用途
scaffold-cli 用于从零引导一个全新的 TypeScript CLI 或 npm 包(Node 24、TypeScript 7),使用 references/ 中固定的模板,直到首次 CI 运行变绿、并且包可以通过 OIDC 发布到 npm。
它不适用于:Next.js 网页应用(应使用 scaffold-nextjs)、现有代码库的目录结构或模块契约(应使用 codebase-architecture)、审计现有 CLI 的人机工程学(应使用 dx-audit),或发布现有包(应使用 autoship)。
主要能力
模板固化了整套工具链。需要替换项目值,并对照已安装的包版本验证模板 API;对于已证实的不兼容应进行修复,而不是盲目复现。工具链本身就是其主张:使用 tsdown 而非 tsup,使用 vitest 而非 jest,通过 ultracite 使用 oxlint 与 oxfmt 而非 eslint 或 prettier,使用 node:util 的 styleText 而非 chalk,使用 @clack/prompts 而非 ora。替换其中任何一项或重构目录布局,都会产生模板注释不再描述的仓库。
参考文件及其读取时机:
- references/scaffold-configs.md:第 3 步,package.json、tsconfig、tsdown、gitignore、license、changeset 配置、GitHub Actions。
- references/scaffold-source.md:第 4-5 步,src/cli.ts、src/index.ts、src/types.ts、AGENTS.md、README.md、skills/SKILL.md。
- references/agent-friendly-cli.md:第 4 步,仅当某个命令接受标识符、路径或 URL,或会改变状态时使用:输入验证、dry-run、确认、schema。
- references/post-scaffold.md:第 6-8 步,脚手架后命令、lefthook.yml 替换、验证清单、GitHub 与 npm 引导、故障排查。
使用方式
脚手架工作流包含以下步骤,可复制清单跟踪进度:
- 收集项目信息
- 创建目录结构
- 生成配置文件
- 生成源码文件
- 生成文档与技能
- 运行脚手架后命令
- 验证脚手架
- 引导 GitHub 与 npm(需用户同意)
第 1 步:收集项目信息。只询问用户未提供的内容。变量包括:{{name}}(示例 md-tools,必填,用于 package.json name、README 标题、npm 包)、{{description}}(示例“CLI tool to convert content to markdown”,必填,用于 package.json、README、SKILL.md)、{{bin}}(示例 md,默认与 {{name}} 相同,用于 package.json bin 字段、CLI 示例、skills 文件夹)、{{repo}}(示例 acme/md-tools,必填,用于 package.json repository、GitHub 仓库、npm trusted publisher)、{{author}}(示例 Your Name,必填,用于 package.json、LICENSE)、{{year}}(示例 2026,默认当前年份,用于 LICENSE)。{{repo}} 必须是精确的 GitHub owner/name:npm provenance 会拒绝 repository.url 与其来源仓库不一致的发布。
第 2 步:创建目录结构:{{name}}/ 下包含 .changeset/、.github/workflows/、src/、skills/{{bin}}/。
第 3 步:生成配置文件。加载 references/scaffold-configs.md,生成其中每个文件并替换每个 {{placeholder}}:package.json、tsconfig.json、tsdown.config.ts、.gitignore、LICENSE.md、.changeset/config.json、.changeset/README.md、.github/workflows/ci.yml、.github/workflows/npm-publish.yml。
第 4 步:生成源码文件。加载 references/scaffold-source.md,生成:src/cli.ts(Commander 入口点,带 agent 友好默认值:--output text|json、--no-input、stdout 数据 / stderr 日志分离、JSON 错误信封)、src/index.ts(公共 API 导出)、src/types.ts(共享类型定义)。当某个命令接受标识符、路径或 URL,或会改变状态时,还要加载 references/agent-friendly-cli.md 并复制匹配的固定模式。对于没有此类命令的 CLI 则跳过。
第 5 步:生成文档与技能。从同一 references/scaffold-source.md 生成:AGENTS.md(命令、架构、注意事项、agent 不变量)、README.md(安装、用法、API、agent 技能安装、许可证)、skills/{{bin}}/SKILL.md(agent 技能定义)。直接使用 AGENTS.md;不要创建 CLAUDE.md 包装或符号链接。
第 6 步:运行脚手架后命令。加载 references/post-scaffold.md,按给定顺序运行命令序列,包括在 ultracite init 与首次提交之间覆盖 lefthook.yml。
第 7 步:验证脚手架。运行 references/post-scaffold.md 中的验证清单。每一项都是一个命令,其输出即为证据;清单包括 publint、arethetypeswrong、针对真实文件演练 hook,以及占位符清扫。
第 8 步:引导 GitHub 与 npm。对于本地脚手架,在第 7 步后停止。如果用户已请求远程设置或发布,则执行该授权范围。否则在请求创建或发布之前,先展示准备好的仓库/包身份。否则遵循 references/post-scaffold.md 中的“Bootstrap GitHub and npm”:创建并推送仓库,启用 Actions 创建的 PR,手动发布一次 0.0.1 使包存在,然后将工作流注册为 trusted publisher。终端证据是推送提交上 CI 运行变绿,以及 npm view {{name}} version 打印 0.0.1。此后每次发布都归 autoship 负责。
依赖
运行时:@clack/prompts、commander。
开发依赖(在 package.json 模板中):@changesets/cli、@types/node、tsdown、typescript、vitest。
由 ultracite init 添加,绝不手动列出:ultracite(由 init 固定精确版本)、oxlint、oxfmt、lefthook,以及 check、fix、prepare 脚本。手动添加会产生重复脚本以及与 init 安装版本之间的版本偏差。
注意事项
- tsdown 默认输出 .mjs。在 platform: node(默认)下 fixedExtension 开启,因此没有 outputOptions.entryFileNames: "[name].js" 的配置会构建出 dist/cli.mjs、dist/index.mjs 和 dist/index.d.mts,而 bin 和 exports 指向不存在的文件。模板中的 outputOptions 块正是让它们保持 .js 的原因;不要把它当作噪音删掉。
- src/cli.ts 中没有 shebang。tsdown 的 banner 会注入 #!/usr/bin/env node;源码中的 shebang 会在 dist/cli.js 中重复。两个构建入口保持分离:CLI 入口有 banner 且 dts: false,库入口有 dts: true 且无 banner。
- "test": "vitest run" 不带 --passWithNoTests 时,在零测试文件的仓库上会以 1 退出,因此首次 CI 运行会变红。
- @changesets/cli@3 与 changesets/action@v2 及 publish-script: 输入配对。@v1 无法驱动 changesets v3,而 @v2 若给定 v1 的 publish: 输入,会为包打版本号然后变绿完成却不发布。模板携带匹配的一对;不要降级其中一侧。
- npm 无法为一个尚不存在的包注册 trusted publisher。首次发布运行会失败并报 E404 或 ENEEDAUTH,直到第 8 步的一次性手动 pnpm publish 创建了包并注册了工作流。那次发布发生在任何 changeset 存在之前,因此它是 autoship 规则不禁止的唯一一次手动发布。
- Node 22 附带 npm 10.9.x;OIDC 发布需要 npm 11.5.1 或更高版本。Node 24 附带 npm 11.19,这就是两个工作流都固定 node-version: 24 的原因。将其降低到 22 会因 ENEEDAUTH 破坏发布。发布工作流会升级 npm,即使项目使用 pnpm:pnpm publish 可以把上传交给 PATH 上的 npm CLI,而那里较旧的 npm 会导致 OIDC 失败。
- 面向 agent 的输出是一种格式契约。数据在 stdout,日志和进度在 stderr;一个多余的 console.log 会破坏解析 --output json 的消费者。当 stdin 不是 TTY 时绝不提示:遵守 --no-input 并将每个值作为标志传入,否则进程会在管道下挂起。
相关技能
autoship:引导发布之后的每次发布:changeset、CI 监视、Version Packages PR、发布验证,以及诊断未发布的发布。
dx-audit:一旦真实命令存在,审计 CLI 的标志、错误和类型。
agents-md:随着代码库获得结构,扩展生成的 AGENTS.md。
ghostwriter:一旦有真实的使用故事可讲,重写 README。
仅维护用:evals/evals.json 包含针对此技能变更的回归场景;它不会在用户任务期间加载。