/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) orB(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 forpackage.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
--targetto integrate into the live SDK and--api-surfaceto 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:
# After /generate-emitter — design doc, entry point, and tests
ls {project}/docs/sdk-architecture/{language}.md
ls {project}/src/{language}/index.ts
cd {project} && npx vitest run test/{language}/ 2>&1 | tail -5
# After /generate-extractor — extractor registered with hints
grep -l "{language}Extractor\|{language}_extractor" {project}/src/plugin.ts {project}/src/index.ts
grep -l "hints" {project}/src/compat/extractors/{language}.ts
# After /verify-compat — handled by the skill itself
# After /generate-smoke-test — script exists
ls {project}/smoke/sdk-{language}.ts
# After /verify-smoke-test — handled by the skill itself
# After /integrate — changes visible in live SDK
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 # emitter project
npx tsc --noEmit # oagen core type check
npx tsup # oagen core build
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)