Loading...
Loading...
Develop the Stitch SDK. Covers the generation pipeline, dual modality (agent vs SDK), error handling, and Traffic Light (Red-Green-Yellow) implementation workflow. Use when adding features, fixing bugs, or understanding the architecture.
npx skill4agent add google-labs-code/stitch-sdk stitch-sdk-development@google/stitch-sdkStage 1: Capture Stage 2: Domain Design Stage 3: Generate
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ capture-tools.ts │──────▶│ domain-map.json │───────▶│ generate-sdk.ts │
│ │ │ (the IR) │ │ │
│ Connects to MCP │ │ Classes, bindings│ │ Deterministic │
│ server, calls │ │ arg routing, │ │ codegen into │
│ tools/list │ │ cache, extraction│ │ packages/sdk/generated/ │
└──────────────────┘ └──────────────────┘ └──────────────────┘
│ │ │
▼ ▼ ▼
tools-manifest.json domain-map.json packages/sdk/generated/src/*.ts
(raw MCP tool schemas) (tool→class mapping) (Stitch, Project, Screen)bun scripts/capture-tools.tstools/listtools-manifest.jsondomain-map.jsonselfparamcomputedbun scripts/generate-sdk.tspackages/sdk/generated/src/stitch-sdk.lockbun scripts/validate-generated.tsdomain-map.jsonvalidate-generated.tsdomain-map.json{
"Screen": {
"constructorParams": ["projectId", "screenId"],
"fieldMapping": {
"projectId": { "from": "projectId" },
"screenId": { "from": "id", "fallback": { "field": "name", "splitOn": "/screens/" } }
},
"parentField": "projectId",
"idField": "screenId"
}
}{
"tool": "generate_screen_from_text",
"class": "Project",
"method": "generate",
"args": {
"projectId": { "from": "self" },
"prompt": { "from": "param" },
"name": { "from": "computed", "template": "projects/{projectId}/screens/{screenId}" }
},
"returns": {
"class": "Screen",
"projection": [
{ "prop": "outputComponents", "index": 0 },
{ "prop": "design" },
{ "prop": "screens", "index": 0 }
]
}
}selfthisparamcomputedselfArray[this.field]ProjectionStep[]outputSchemaindexeach[]cacheprojectionthis.data{
"cache": { "projection": [{ "prop": "htmlCode" }, { "prop": "downloadUrl" }], "description": "Use cached download URL from generation response" }
}StitchToolClientconst client = new StitchToolClient();
const tools = await client.listTools();
const result = await client.callTool("generate_screen_from_text", {
projectId: "123", prompt: "A login page"
});callToolStitchErrorconst project = await stitch.createProject("My App");
const screen = await project.generate("A login page");
const html = await screen.getHtml();StitchToolClientcallToolthrow StitchErrorResult<T>// Generated method pattern (inside each method):
try {
const raw = await this.client.callTool<any>("tool_name", args);
return /* extracted result */;
} catch (error) {
throw StitchError.fromUnknown(error);
}StitchError.fromUnknown()StitchErrorStitchToolClientStitchErrorStitchProxysingleton.tsstitch# Unit tests for generated classes
npx vitest run test/unit/sdk.test.ts
# → FAIL (new method doesn't exist yet)
# E2E test for the public API
bun scripts/e2e-test.ts
# → FAIL (method doesn't exist yet)domain-map.jsonbun scripts/generate-sdk.tsnpx vitest run # All tests pass
bun scripts/e2e-test.ts # E2E passesnpx tscbun scripts/validate-generated.tspackages/sdk/src/index.tspackages/sdk/generated/src/packages/sdk/generated/domain-map.jsonpackages/sdk/generated/tools-manifest.jsonpackages/sdk/src/client.tspackages/sdk/src/spec/errors.tspackages/sdk/src/singleton.tspackages/sdk/test/unit/packages/sdk/test/integration/scriptspackage.json.jsimport { StitchError } from '../../src/spec/errors.js'; // ✓
import { StitchError } from '../../src/spec/errors'; // ✗