1实现原理 · 为什么它能做到
技能包不自带 Stitch 客户端,而是在运行时用宿主的 list_tools 动态发现 MCP 前缀,再以 [prefix]:工具名 调用——因此同一份指令能适配不同宿主。
1. **Namespace discovery**: Run `list_tools` to find the Stitch MCP prefix. Use this prefix (e.g., `stitch:`) for all subsequent calls.
设计稿由 MCP 返回签名 URL 后,强制用随包 curl 脚本下载,而不是用模型内置抓取——为了绕开 Google Cloud Storage 域上的抓取失败。
4. **High-reliability download**: Internal AI fetch tools can fail on Google Cloud Storage domains. You MUST use the provided script.
下载到的 HTML 里的 tailwind.config 被抽成设计 token 并**覆盖写回技能自带的** resources/style-guide.json,使该文件成为本轮组件的唯一配色来源。
2. **Sync `resources/style-guide.json`**: Overwrite the file with the extracted tokens from THIS project. The style guide MUST match the Stitch project being converted.
生成结果用 AST 校验而不是正则:必须有以 Props 结尾的接口,且 className 中不得出现硬编码十六进制色值。
if (node.type === 'TsInterfaceDeclaration' && node.id.value.endsWith('Props')) hasInterface = true;
上传刻意绕开 MCP 工具:base64 会把模型输出 token 撑爆,于是改由 Python 脚本在进程内编码后直接 HTTP POST 到 Stitch REST。
a 53KB PNG becomes ~71K chars of base64). The output gets truncated
code-to-design 是纯编排型 skill:自身不做转换,只按序把活派给三个兄弟技能。
This skill orchestrates three other skills in sequence:
stitch-loop 用 .stitch/next-prompt.md 作接力棒文件实现无人值守的多页站点循环,且每轮必须更新接力棒。
1. Reads the current task from a baton file (`.stitch/next-prompt.md`)
静态 HTML 抽取的主力是一个 Puppeteer 脚本:起 headless Chrome 抓渲染后的 DOM,再把 CSS 与图片内联成单文件。
* snapshot.ts — Production-grade Puppeteer-based full-page HTML snapshot
设计系统的单一事实源是 DESIGN.md:上传后由项目级持有 token,因此生成提示被要求不要再写颜色与字体。
After generating `.stitch/DESIGN.md`, make sure to also create or update the
2核心能力
3外部依赖
| 类型 | 依赖 |
|---|---|
| api | Stitch API 默认 base URL |
| api | BatchCreateScreens 端点 |
| cli | curl 下载 MCP 返回的签名资产 |
| network | 远程 Stitch MCP(URL 由用户填) |
| cli | npx tsx 运行 TypeScript 脚本 |
| cli | python3 运行上传脚本 |
| package | puppeteer(未在任何 package.json 声明,由 npx tsx 运行时解析) |
| package | @swc/core(已声明依赖,用于 AST 解析) |
| cli | npx shadcn CLI 拉取组件源码 |
| package | @google/design.md linter |
| cli | npm 安装 Remotion 依赖 |
| cli | npx remotion render 出片 |
4风险提醒 风险提醒:红色 · 谨慎使用
- 任意本地模块执行入口(--auth-script) — snapshot.ts 会 `await import()` 由参数指定的任意 JS/TS 模块并在 Node 进程执行,路径只做 resolve,无白名单、无沙箱;参数由 agent 填写,一旦指令被误导或参数被注入,等价于在开发者机器上执行任意代码。
- API key 从宿主配置里被读出并以明文命令行传递 — SKILL.md 要求到 ~/.claude.json、~/.gemini/settings.json、.gemini/antigravity/mcp_config.json 等位置抠 X-Goog-Api-Key,再以 `--api-key <API_KEY>` 传给 Python 子进程;密钥因此出现在进程参数里,可能被 ps、shell 历史或 agent 日志留存。
- 外部内容未做数据/指令隔离 — MCP 返回的 Stitch HTML、DESIGN.md,以及抓取的本地页面 DOM,都被原样交给模型解析并据此写代码或改配置;全包没有『页面文本视为数据』的限定,只有动作层的人工确认兜底。
- 依赖解析不锁定 — snapshot.ts 依赖 puppeteer,但该依赖未出现在任何 package.json 中,由 npx tsx 在运行时解析;@google/design.md、shadcn、Remotion 等也走 npx/npm 最新版,版本可漂移。
- 文档与仓库实际不一致 — README 的 utilities 表与结构图漏列 site-md,且宣称每个 skill 都含 scripts/resources/examples 与实测不符;插件级 description 在 plugin.json 与 .codex-plugin/plugin.json 两处文案不同;命名空间 stitch::xxx 非 kebab-case,README 自承在 OpenCode 下需改名。
- 存在未接线资产 — shadcn-ui/scripts/verify-setup.sh 随包发货但 SKILL.md 无调用点,只被 README 目录树提及。
5第二遍独立确认
- [ok] skill.path 的选取 — 重读 .agents/plugins/marketplace.json 与三个 plugin.json:仓库根与 plugins/ 直属层都没有 SKILL.md 或 manifest,故条目只能落在插件级或插件内的具体技能上。根 README 与 marketplace 都把它当『库』对待(displayName=Stitch Skills、三条 source.path),而 brief 要求 official_desc 取 SKILL.md frontmatter 原文——plugins/stitch-design 本身没有 SKILL.md,故选其中承载设计主流程的入口技能目录 plugins/stitch-design/skills/generate-design(name: stitch::generate-design,frontmatter 有完整 description)。
- [ok] official_desc 逐字与折行 — 重读 generate-design/SKILL.md L1-9:description 用 YAML 折叠符 `>-`,跨 5 行;已按折叠后单行逐字收录,未改动用词。另注意 plugins/stitch-design/plugin.json 的插件级 description 与 .codex-plugin/plugin.json 的文案不同(前者用破折号、后者更短),属两处清单不一致,非本 skill 的 description。
- [ok] external_deps:Stitch REST 端点与请求头 — 重读 upload_to_stitch.py:默认 base 为 https://stitch.googleapis.com,URL 拼接为 `{api_url}/v1/projects/{project_id}/screens:batchCreate`,请求头 `X-Goog-Api-Key` 与 `--api-key required=True` 均在位;三处行号与首遍一致。
- [ok] external_deps:curl 调用点与两处重复脚本 — 对 plugins 全量二次检索 curl:react-components 与 react-native 的 fetch-stitch.sh 是同一语句的两个副本,remotion 的 download-stitch-asset.sh 额外做 mkdir -p 与失败 rm -f。三处均为极简包装,不读凭证。
- [ok] security.credential_reads 的三条配置路径 — 重读 upload-to-stitch/SKILL.md 的『Get the API Key』段:Antigravity / Gemini CLI / Claude Code 三条配置路径、X-Goog-Api-Key 取值说明、找不到时必须向用户索要的强约束,以及脚本调用处的 `--api-key <API_KEY>`,逐字与首遍一致。
- [ok] security:任意模块执行分支 — 重读 snapshot.ts 的 auth-script 分支:打印 Running authentication script from 后 `path.resolve(process.cwd(), opts.authScript)` 再 `await import(authPath)`,若导出为函数则以 page 调用。确认这是无校验的本地模块执行入口,参数由调用方(agent)填入。
- [ok] security:SSL 处理是否属安全降级 — 重读 upload_to_stitch.py 的 ssl 相关行与 SKILL.md 的 Troubleshooting 段:脚本用 certifi 提供的 CA 建默认上下文,SKILL.md 建议通过 SSL_CERT_FILE 指定 CA——是修正缺失根证书,不是 disable verification;故未把它计入降级行为。
- [ok] security.file_writes 的路径清单 — 重读 react-components/SKILL.md 与 stitch-loop/SKILL.md 的写入段:.stitch/designs、.stitch/metadata.json、resources/style-guide.json 覆盖写、site/public 迁移、.stitch/next-prompt.md 强制更新均有原文;另补 post_process.ts 与 snapshot.ts 的脚本级写入。写入目标全部位于当前项目或技能自身目录。
6结论
88df56fdbec37bb5…0337446dad