| name | generate-sdk |
| description | Orchestrate generating an SDK for a target language end-to-end. Determines the right scenario (backwards-compatible or fresh) and guides through the correct sequence of sub-skills. Use when the user wants to generate an SDK, add a new language, create SDK bindings, start a new language target, or asks "how do I add X support". Also triggers for "new SDK", "language support", or "scaffold SDK". |
/generate-sdk
Overview
Orchestrate the end-to-end workflow for generating an SDK for a target language. This skill does not implement anything itself — it determines the right scenario, sequences the correct skills, and tracks progress across steps.
Inputs
- language — target language (e.g.,
ruby, python, node, go)
- scenario —
A (backwards-compatible with existing SDK) or B (fresh, no existing SDK)
- project — path to the emitter project
- spec — path to the OpenAPI spec
- sdk_path — path to the live SDK (Scenario A only)
Reference Docs
- Workflows — Phase 1 setup vs. Phase 2 ongoing spec updates
- Pipeline — three-stage parse/emit/write flow
Architecture
Emitters, extractors, smoke tests, and their unit tests all live in the emitter project, not in the oagen core repo. The emitter project depends on @workos/oagen for types and shared utilities.
Context Management
Sub-skills use subagents (via the built-in Explore agent type) to keep the main context lean. Read-heavy exploration — studying existing SDKs, reading reference implementations — is delegated to isolated agents that return only structured summaries. This prevents context rot during the write-heavy generation steps that follow.
Each sub-skill documents where it uses subagents:
/generate-emitter — Step 1a (SDK exploration) and Steps 3-5 (reference emitter reading)
/generate-extractor — Prerequisites (SDK exploration)
/generate-smoke-test — Prerequisites (reference smoke script reading) and Step 2 (SDK SERVICE_MAP)
/verify-compat — Step 1 (baseline extraction spot-check)
Step 1: Gather Inputs
Collect these values via AskUserQuestion. If any were provided as arguments, skip the corresponding question.
language — target language (e.g., ruby, python, php, node)
scenario — which workflow to use:
A. Backwards compatible — There's a published SDK with consumers who depend on its public API. The generated SDK must match the existing surface.
B. Fresh — No existing SDK to preserve, or you're intentionally replacing one. No compat constraints.
sdk_path (Scenario A only) — path to the existing SDK. Validate the path exists (look for package.json, Gemfile, go.mod, pyproject.toml, or similar).
project — emitter project path (e.g., ../oagen-emitters/node). Create if needed:
mkdir -p {project}/src/{language} && mkdir -p {project}/test/{language}
spec — path to the OpenAPI spec (e.g., ../openapi.yaml)
Store all values and pass them to all sub-skill invocations.
Step 2: Present the Plan
Scenario A — Backwards compatible
Step 1: /generate-emitter {language} {project} sdk_path={sdk_path} — study existing SDK, scaffold emitter
Step 2: /generate-extractor {language} sdk_path={sdk_path} — scaffold extractor
Step 3: /verify-compat {language} sdk_path={sdk_path} — extract baseline, verify
Step 4: /generate-smoke-test {language} — smoke tests against output dir
Step 5: /verify-smoke-test {language} — iterate until clean
Step 6: /integrate {language} sdk_path={sdk_path} — merge into live SDK
Scenario B — Fresh
Step 1: /generate-emitter {project} {language} — scaffold emitter
Step 2: /generate-smoke-test {language} — wire-level HTTP parity tests
Step 3: /verify-smoke-test {language} — run smoke tests
Lifecycle note: Scenario B is a one-time bootstrap. Once the generated SDK ships, it becomes the live SDK. All future spec updates follow Scenario A — use --target to integrate into the live SDK and --api-surface to preserve backwards compatibility.
Confirm with the user, then invoke the first skill.
Step 3: Run Skills in Sequence
Invoke each skill in order using the Skill tool, passing project through. After each skill, validate:
ls {project}/docs/sdk-architecture/{language}.md
ls {project}/src/{language}/index.ts
cd {project} && npx vitest run test/{language}/ 2>&1 | tail -5
grep -l "{language}Extractor\|{language}_extractor" {project}/src/plugin.ts {project}/src/index.ts
grep -l "hints" {project}/src/compat/extractors/{language}.ts
ls {project}/smoke/sdk-{language}.ts
cd {sdk_path} && git diff --stat
For Scenario A: After /generate-emitter, also verify the design doc references real SDK patterns:
grep -c "existing SDK\|from src/" {project}/docs/sdk-architecture/{language}.md
If a skill fails or the user wants to pause, note where they stopped. They can resume by running the remaining skills individually.
Step 4: Final Checklist
Run the full validation suite:
cd {project} && npx vitest run
npx tsc --noEmit
npx tsup
Then present the summary:
=== {language} SDK support: COMPLETE ===
Scenario: {A/B}
Skills completed:
[x] /generate-emitter {language}
[x] /generate-extractor {language} (Scenario A only)
[x] /verify-compat {language} (Scenario A only)
[x] /integrate {language} (Scenario A only)
[x] /generate-smoke-test {language}
Validation:
Emitter tests: {N} passed, {N} failed
Type check: PASS/FAIL
Build: PASS/FAIL
Only include this next section in the output if this is Scenario A:
Output
This skill produces, via its sub-skills:
- A complete language emitter registered in the plugin bundle (
src/plugin.ts)
- An API surface extractor (Scenario A only)
- A smoke test script at
smoke/sdk-{language}.ts
- Generated SDK code at
{project}/sdk/
- Integration into the live SDK (Scenario A only)