stitch-sdk-development
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseStitch SDK Development
Stitch SDK 开发
This skill encodes the expertise needed to develop — the core systems, patterns, and philosophies. It does not enumerate every method (the codebase is the source of truth for that). It teaches you how to think about the system.
@google/stitch-sdk本指南涵盖了开发所需的核心系统、模式与理念相关知识。它不会罗列每一个方法(代码库才是这方面的权威来源),而是教你如何理解整个系统的设计思路。
@google/stitch-sdkThe Generation Pipeline
生成流水线
The domain layer is fully generated. No handwritten domain classes. The pipeline has 3 stages:
Stage 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)Stage 1 (): Connects to the live Stitch MCP server, calls , writes . Source of truth for what tools exist.
bun scripts/capture-tools.tstools/listtools-manifest.jsonStage 2 (agent/human): Reads the manifest and produces — the intermediate representation. This is where judgment lives: which tool maps to which class, what args come from vs vs , how to extract the return value, and what data to cache.
domain-map.jsonselfparamcomputedStage 3 (): Deterministic codegen. Reads manifest + domain-map, emits TypeScript classes in . No LLM involved — pure template expansion.
bun scripts/generate-sdk.tspackages/sdk/generated/src/Integrity: records SHA-256 hashes of all inputs and outputs. verifies consistency. Run in CI to prevent publishing stale code.
stitch-sdk.lockbun scripts/validate-generated.ts领域层是完全自动生成的,无需手动编写领域类。该流水线包含3个阶段:
Stage 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)阶段1():连接到Stitch MCP实时服务器,调用接口,生成文件。这是确认现有工具的权威来源。
bun scripts/capture-tools.tstools/listtools-manifest.json阶段2(Agent/人工操作):读取清单文件并生成——即中间表示(IR)。这一步需要人工判断:将哪个工具映射到哪个类,参数来自、还是,如何提取返回值,以及需要缓存哪些数据。
domain-map.jsonselfparamcomputed阶段3():确定性代码生成。读取清单文件和domain-map,在目录下生成TypeScript类。此过程不涉及LLM,仅为纯模板展开。
bun scripts/generate-sdk.tspackages/sdk/generated/src/完整性校验:记录了所有输入和输出的SHA-256哈希值。用于验证一致性。需在CI流程中运行该命令,防止发布过期代码。
stitch-sdk.lockbun scripts/validate-generated.tsSupporting a New Tool
支持新工具
When the Stitch MCP server adds a new tool:
- Run Stage 1 to capture the updated manifest
- Run Stage 2: add a binding in for the new tool
domain-map.json - Run Stage 3 to regenerate the SDK classes
- Run to confirm consistency
validate-generated.ts - Update tests as needed
当Stitch MCP服务器新增工具时,执行以下步骤:
- 运行阶段1,捕获更新后的清单文件
- 运行阶段2:在中为新工具添加绑定配置
domain-map.json - 运行阶段3,重新生成SDK类
- 运行确认一致性
validate-generated.ts - 根据需要更新测试用例
The Domain Map IR
领域映射中间表示(IR)
domain-map.jsonClasses: What domain objects exist and how they're constructed.
json
{
"Screen": {
"constructorParams": ["projectId", "screenId"],
"fieldMapping": {
"projectId": { "from": "projectId" },
"screenId": { "from": "id", "fallback": { "field": "name", "splitOn": "/screens/" } }
},
"parentField": "projectId",
"idField": "screenId"
}
}Bindings: How MCP tools map to class methods.
json
{
"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 }
]
}
}Arg routing: = injected from , = passed by the caller, = built from a template at call time, = wrapped as array.
selfthisparamcomputedselfArray[this.field]Response projections: Structured arrays validated against . Use for single items, for arrays. Empty = direct return.
ProjectionStep[]outputSchemaindexeach[]Cache: Methods can specify a with a structured to check before calling the API:
cacheprojectionthis.datajson
{
"cache": { "projection": [{ "prop": "htmlCode" }, { "prop": "downloadUrl" }], "description": "Use cached download URL from generation response" }
}domain-map.json类定义:定义存在哪些领域对象及其构造方式。
json
{
"Screen": {
"constructorParams": ["projectId", "screenId"],
"fieldMapping": {
"projectId": { "from": "projectId" },
"screenId": { "from": "id", "fallback": { "field": "name", "splitOn": "/screens/" } }
},
"parentField": "projectId",
"idField": "screenId"
}
}绑定配置:定义MCP工具如何映射到类方法。
json
{
"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[]缓存配置:方法可指定带有结构化的配置,调用API前会先检查:
projectioncachethis.datajson
{
"cache": { "projection": [{ "prop": "htmlCode" }, { "prop": "downloadUrl" }], "description": "Use cached download URL from generation response" }
}Dual Modality
双模式架构
The SDK serves two distinct consumers with different needs:
SDK服务于两类需求截然不同的使用者:
Agent Modality — StitchToolClient
StitchToolClientAgent模式 —— StitchToolClient
StitchToolClientFor AI agents and orchestration scripts. Raw tool pipe. The agent receives tool schemas, constructs JSON, sends it, gets JSON back. No domain knowledge required.
typescript
const client = new StitchToolClient();
const tools = await client.listTools();
const result = await client.callTool("generate_screen_from_text", {
projectId: "123", prompt: "A login page"
});适用于AI Agent和编排脚本。为原生工具管道,Agent接收工具 schema,构造JSON请求,发送后获取JSON响应。无需具备领域知识。
typescript
const client = new StitchToolClient();
const tools = await client.listTools();
const result = await client.callTool("generate_screen_from_text", {
projectId: "123", prompt: "A login page"
});SDK Modality — Generated Domain Classes
SDK模式 —— 生成的领域类
For humans writing precise, programmatic scripts. Generated domain facade over . Typed parameters, domain objects returned, thrown on failure.
callToolStitchErrortypescript
const project = await stitch.createProject("My App");
const screen = await project.generate("A login page");
const html = await screen.getHtml();Both modalities share underneath. The domain classes are a typed layer over .
StitchToolClientcallTool适用于编写精确、程序化脚本的开发人员。在之上封装了生成的领域外观层,提供类型化参数,返回领域对象,失败时抛出。
callToolStitchErrortypescript
const project = await stitch.createProject("My App");
const screen = await project.generate("A login page");
const html = await screen.getHtml();两种模式底层均基于。领域类是之上的类型化封装层。
StitchToolClientcallToolError Handling — Throws at the Boundary
错误处理 —— 在边界处抛出异常
All generated methods use for error handling. No pattern.
throw StitchErrorResult<T>typescript
// 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()StitchError所有生成的方法均使用进行错误处理,不采用模式。
throw StitchErrorResult<T>typescript
// 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()StitchErrorInfrastructure (Handwritten)
基础设施代码(手动编写)
These components remain handwritten as they provide foundational plumbing:
- — MCP transport, auth, tool invocation
StitchToolClient - — typed error class with codes, messages, recovery hints
StitchError - — MCP proxy server for re-exposing Stitch to other agents
StitchProxy - — lazy proxy for
singleton.tsexport with env var configstitch
以下组件需手动编写,因为它们提供基础的底层能力:
- —— MCP传输、认证、工具调用
StitchToolClient - —— 带错误码、错误信息和恢复提示的类型化错误类
StitchError - —— MCP代理服务器,用于向其他Agent暴露Stitch服务
StitchProxy - ——
singleton.ts导出的懒加载代理,支持环境变量配置stitch
Traffic Light Implementation (Red → Green → Yellow)
红绿灯实现流程(红→绿→黄)
When implementing a new feature or fixing a bug, follow the Traffic Light pattern:
新增功能或修复Bug时,请遵循红绿灯模式:
🔴 Red — Write Breaking Tests
🔴 红色阶段 —— 编写失败的测试用例
Write the test first. It must fail. This defines the contract before any implementation exists.
bash
undefined先编写测试用例,确保测试失败。这会在实现前先定义好契约。
bash
undefinedUnit tests for generated classes
生成类的单元测试
npx vitest run test/unit/sdk.test.ts
npx vitest run test/unit/sdk.test.ts
→ FAIL (new method doesn't exist yet)
→ 失败(新方法尚未实现)
E2E test for the public API
公开API的端到端测试
bun scripts/e2e-test.ts
bun scripts/e2e-test.ts
→ FAIL (method doesn't exist yet)
→ 失败(方法尚未实现)
undefinedundefined🟢 Green — Implement
🟢 绿色阶段 —— 实现功能
- Add a binding to (Stage 2)
domain-map.json - Run (Stage 3)
bun scripts/generate-sdk.ts - Update tests to verify correct behavior
bash
npx vitest run # All tests pass
bun scripts/e2e-test.ts # E2E passes- 在中添加绑定配置(阶段2)
domain-map.json - 运行(阶段3)
bun scripts/generate-sdk.ts - 更新测试用例以验证功能正确性
bash
npx vitest run # 所有测试通过
bun scripts/e2e-test.ts # 端到端测试通过🟡 Yellow — Refactor / Refine / Revisit
🟡 黄色阶段 —— 重构/优化/复查
With passing tests as your safety net:
- Refactor for clarity (extract helpers, simplify args)
- Add edge case tests
- Run to verify type safety
npx tsc - Run to verify pipeline integrity
bun scripts/validate-generated.ts
在测试通过的安全前提下:
- 重构代码以提升可读性(提取辅助函数、简化参数)
- 添加边缘场景测试用例
- 运行验证类型安全性
npx tsc - 运行验证流水线完整性
bun scripts/validate-generated.ts
Orienting in the Codebase
代码库导航
Discover the current state by reading the codebase directly. The key entry points:
- Public surface: Start at — every public export is listed here
packages/sdk/src/index.ts - Generated classes: — Stitch, Project, Screen
packages/sdk/generated/src/ - Pipeline artifacts: ,
packages/sdk/generated/domain-map.jsonpackages/sdk/generated/tools-manifest.json - Infrastructure: ,
packages/sdk/src/client.ts,packages/sdk/src/spec/errors.tspackages/sdk/src/singleton.ts - Test structure: for unit tests,
packages/sdk/test/unit/for live testspackages/sdk/test/integration/ - Available commands: Read the field in
scriptspackage.json
Do not rely on cached descriptions of files or directory trees. Read the source.
直接阅读代码库以了解当前状态,关键入口点如下:
- 公开接口:从开始——所有公开导出均在此列出
packages/sdk/src/index.ts - 生成的类:—— Stitch、Project、Screen等类
packages/sdk/generated/src/ - 流水线产物:、
packages/sdk/generated/domain-map.jsonpackages/sdk/generated/tools-manifest.json - 基础设施代码:、
packages/sdk/src/client.ts、packages/sdk/src/spec/errors.tspackages/sdk/src/singleton.ts - 测试结构:存放单元测试,
packages/sdk/test/unit/存放集成测试packages/sdk/test/integration/ - 可用命令:查看中的
package.json字段scripts
请勿依赖缓存的文件描述或目录结构,直接阅读源代码。
Import Convention
导入约定
Use extensions for ESM compatibility:
.jstypescript
import { StitchError } from '../../src/spec/errors.js'; // ✓
import { StitchError } from '../../src/spec/errors'; // ✗为了兼容ESM,请使用扩展名:
.jstypescript
import { StitchError } from '../../src/spec/errors.js'; // ✓
import { StitchError } from '../../src/spec/errors'; // ✗