| name | airfoil-kit |
| description | Implement a new Airfoil producer connector end-to-end. Use when the user asks to build, add, scaffold, create, or port a connector/producer/integration for any SaaS API (Stripe, Shopify, GitHub, Intercom, HubSpot, Linear, Polar, custom, etc.) in this monorepo. Copies templates/producer-template/, researches the real API, wires Effect v4 Config + HttpClient + Resource.entity/Fetch.page + Webhook.route, and finishes with deterministic replay tests (VCR for REST/GraphQL, fixtures/mocks for gRPC). |
airfoil-kit
You are implementing a new producer connector for the Airfoil Connector Kit (ACK)
inside this monorepo. Work in small, verified steps. Use the template as your
starting point, never guess API shapes, and keep changes aligned with the
existing patterns in templates/producer-template/ and the current producer connectors.
If the task is to diagnose or repair an existing connector from a trace, cassette
failure, webhook payload, provider changelog, or schema/transform error, use the
airfoil-connector-debugger skill instead.
The current repo shape matters more than historical examples. When in doubt,
follow the current source packages and the refreshed reference docs in this
skill.
Hard rules (do not violate)
- Copy the template. Do not invent a new structure. The canonical scaffold
is
templates/producer-template/. Start every new connector with
cp -R templates/producer-template connectors/producer-<name> and adapt from
there. See assets/rename-checklist.md.
- No pre-existing connector for the target service. Before writing any
code, run the pre-flight checks in
references/anti-cheat.md.
If an implementation exists, stop and report it โ do not copy, rename, or
refactor it.
- Use the repo-pinned Effect v4 beta only (
effect@^4.0.0-beta.98 via
catalog). No legacy @effect/platform, @effect/schema, or Effect v2/v3 patterns.
Read references/effect-v4-essentials.md
whenever you reach for a new Effect module. For Effect guidance, consult
effect-smol only. Do not use the older official Effect docs as source of
truth for this repo right now.
- No
process.env reads in connector code. Use Config/ConfigProvider
everywhere. Sandboxes use Effect's default environment provider; hosted
runtimes add RuntimeConfig.layerHosted() for file config beneath environment
overrides. Tests attach ConfigProvider.fromUnknown({ ... }) or equivalent
Effect config providers. Narrow live-VCR credential fallbacks in tests are
acceptable when still routed through ConfigProvider.
- Never edit cassette files by hand.
test/__cassettes__/** is write-only
via record/replay flow. If replay mismatches, re-record or adjust matcher /
redaction config โ never patch cassette JSON directly.
- Schemas must be derived from real, observed API traffic. For REST/GraphQL:
record a VCR cassette against the real (sandbox) API and define
Schema.Struct
fields from the cassette. For gRPC: use deterministic proto fixtures or a mock
server. Never hand-fabricate field names from memory. See
references/vcr-workflow.md and
references/api-research.md.
- You must pass the implementation gate before writing connector code.
Before scaffolding or editing files under
connectors/producer-<name>/,
produce an API-facts artifact with: API mode (rest/graphql/grpc),
source evidence URLs + access date, and a pinned API version rationale.
Default artifact path: connectors/producer-<name>/api-facts.md.
If the user requests non-persistence, keep it ephemeral but include the same
facts in the final report.
- Webhook verification must follow platform docs exactly. If the upstream
service signs events, implement verification using the provider-documented
contract (inputs, canonicalization, algorithm, encoding, tolerance). Use raw
request bytes whenever the platform requires them. See
references/webhooks.md.
- Signed webhook verification must fail closed. If signature verification
is enabled and required verification inputs are missing (for example raw
request bytes or signature headers), fail with a typed connector error.
Never silently skip verification in this state.
test and test:ci must load config equivalently. If tests rely on
env vars, both scripts must provide the same config-loading behavior
(for example both loading .env through script/runtime flags).
- Pagination behavior must come from official platform docs. Do not infer
continuation semantics from memory or examples. Validate your implementation
against recorded traffic and deterministic tests.
- Expected failures must use typed error channels. Do not throw inside
Effect.sync for recoverable connector errors. Map failures to
ConnectorError (or connector-specific tagged errors mapped to it).
- The Definition of Done is a gate. Do not declare complete until every
item in
references/definition-of-done.md
passes (lint, typecheck, build, test:ci, and mode-appropriate deterministic
replay: VCR for REST/GraphQL, fixtures or mock servers for gRPC).
- Use current names. API clients and connectors use
make, layer(config),
and layerConfig(Config.Wrap<...>). Prefer namespace entrypoint exports,
ConnectorApp.check(...), Ingestion.run(...), StateStore.layerMemory,
Publisher.Publisher, and Webhook.route(...).
- Use correct layer semantics.
Layer.mergeAll(...) is for independent
layers. If a layer needs another to build, satisfy that dependency with
Layer.provide(...) before merging.
- Do not hide dependency graph mistakes behind casts. If a runtime or
test entrypoint seems to need
as Effect.Effect<...>, inspect the layer
graph first.
- Keep the production image runnable. Preserve the template Dockerfile,
compile
src/main.ts to dist/main.js, keep effect in production
dependencies, run the final image as a non-root user, and never copy .env
files or secrets into an image.
High-level flow
- Pre-flight โ confirm no existing implementation. โ
references/anti-cheat.md
- Archetype + mode โ classify the target API (sandbox URL? test keys?
OAuth? webhook-only? polling-only?) and choose one implementation mode:
rest, graphql, or grpc. โ
references/connector-archetypes.md
- API research + evidence โ collect real endpoint + auth + pagination +
webhook docs and write an API-facts artifact (required during implementation).
Default path is
connectors/producer-<name>/api-facts.md; if user asks not
to persist it, keep the same facts in ephemeral notes and final report.
Include source URLs, access date, selected version, and why.
โ references/api-research.md
- Mode-specific standards โ read the one mode doc you selected and treat
it as the implementation contract. Keep decisions evidence-based, and adapt
abstractions to the target platform rather than copying one provider's shape.
- Credentials / test data โ ask the user for sandbox credentials and
seed data; set up
.env. โ references/test-data.md
- Scaffold โ
cp -R templates/producer-template connectors/producer-<name>
and run the rename checklist. โ assets/rename-checklist.md
and references/template-walkthrough.md
- Implement API client (mode-specific) โ use your selected mode contract
and validate auth + pagination behavior against real docs and captured
traffic. Also cross-check kit contracts in
references/connector-kit-api.md.
- Define schemas from real traffic โ use mode-appropriate evidence:
- Wire resources + fetches + webhook route โ follow the template's
Resource.entity / Fetch.page / Connector.define / Webhook.route pattern. Add
webhook signature verification if the service signs events. โ
references/patterns.md,
references/webhooks.md
- Update CLI runtimes โ keep
src/main.ts as CLI assembly, wire
production Wings publishing in src/start.ts, and keep the sandbox console
publisher shape in src/sandbox.ts. Rename the Docker image identifiers
and keep src/main.ts in the tsdown entry list.
- Write tests โ
- REST/GraphQL:
api.vcr.test.ts replays the backfill path.
- gRPC: deterministic fixture/mock-server tests cover equivalent paths.
webhook.test.ts exercises webhook endpoint behavior in-memory.
Ensure committed tests replay deterministically without live credentials.
- Run local verification in order โ
pnpm install, then the relevant
build, typecheck, test:ci, format, and lint checks.
Every one must pass. โ references/definition-of-done.md
A detailed, numbered version of this flow lives at
references/playbook.md. Read it on every run.
Files you will almost always need to edit
After cp -R templates/producer-template connectors/producer-<name>:
package.json โ set package name, version, and service SDK / crypto deps.
Dockerfile โ rename package/image identifiers and retain the workspace-root
build context plus pruned non-root runtime stage.
tsdown.config.ts โ retain src/main.ts as a separate build entry.
.env.example โ set env vars and list required sandbox credentials.
src/schemas.ts โ replace PostSchema with real entities.
src/manifest.ts โ define user-facing config with Manifest.defineConfig(...), export <Service>ConfigDef, derived <Service>Config, and the browser-safe manifest.
src/api.ts โ replace /posts endpoint, adjust pagination + auth.
src/connector.ts โ set service tags, wire resources/fetches, implement webhook
signature verification, and set provider-specific env vars.
src/main.ts โ set CLI command name and subcommand imports.
src/start.ts โ set production runtime layers, Wings table env vars, and
provider-specific telemetry redaction.
src/sandbox.ts โ set sandbox runtime layers, port env var, service name,
and provider-specific telemetry redaction.
src/index.ts โ update exports.
test/api.vcr.test.ts โ REST/GraphQL replay test from real recorded cassette.
test/__fixtures__/** and/or gRPC mock-server tests โ gRPC deterministic
replay artifacts.
test/webhook.test.ts โ adjust payload fixtures.
README.md โ describe the connector, required env, and test flow.
AGENTS.md โ add provider-wide source-of-truth, versioning, auth,
pagination, webhook, resource-map, drift-risk, code-map, and verification
guidance for future agents. This file should cover future upgrades, not only
the connector's initial implemented scope.
references/template-walkthrough.md
explains each file line-by-line.
When stuck
If MCP tools are unavailable
Do not block on Context7/DeepWiki availability.
Fallback order:
- Local repo source of truth:
AGENTS.md
packages/connector-kit/src/**
packages/effect-vcr/src/**
connectors/producer-polar/**
connectors/producer-shopify/**
templates/producer-template/**
- Official public docs via normal web fetch/search.
- Ask the user only for missing, material facts (credentials, webhook
signing details, v1 scope).
Output expectations
- Small, additive commits. Minimize edits outside
connectors/producer-<name>/; if cross-package changes are needed, keep them
narrowly scoped and explicitly justify why.
- All generated code must typecheck, lint, and build.
- Final message must summarize: entities delivered, deterministic test evidence
recorded (VCR or fixtures/mocks), commands you ran, and any follow-ups.
- Final message must include an Environment Setup Guide for the user:
where each env var is obtained, required scopes/permissions, exact setup
steps, and a quick "verify config" checklist.
Use this output shape:
ENV_VAR_NAME
- Where to obtain it (dashboard/API flow + link/path)
- Required scope/permission
- Setup step (
cp .env.example .env, paste value)
- Verification command and expected signal