首页
/ Spec Kit 扩展模板深度解析:基于 extensions/template 构建、调试并发布你的第一个扩展

Spec Kit 扩展模板深度解析:基于 extensions/template 构建、调试并发布你的第一个扩展

2026-09-04 21:10:47作者:何举烈Damon

本文以 Spec Kit 仓库中的扩展启动模板(extensions/template)为主体,完整讲解扩展模板的目录结构、extension.yml 清单的每个字段、命令文件与配置模板的写法、本地调试流程以及发布路径,并结合 扩展管理器源码 中的校验逻辑,说明每个字段的真实约束与常见踩坑点。读完后你可以基于该模板从零搭建一个结构完整、可通过 Spec Kit 校验的扩展,并用 specify extension add --dev 完成本地安装验证。

一、模板定位与适用场景

Spec Kit 的扩展(Extension)是模块化功能包,为 Spec Kit 项目注入自定义命令(speckit.{ext-id}.{command})、配置模板与生命周期钩子,而无需改动核心框架。extensions/template 就是官方提供的"起步模板":它本身是一个可运行的最小扩展(扩展 ID 为 my-extension,命令为 speckit.my-extension.example),所有文件都带有 CUSTOMIZE 注释,指导你把每个占位内容替换为自己的实现。

模板当前版本信息(见 模板 README 末尾):

  • Template Version: 1.0.0
  • Last Updated: 2026-01-28
  • Compatible with Spec Kit: >=0.1.0

配套的四份指南文档位于同一目录的上一级:扩展开发指南API 参考发布指南用户指南,本模板的 README 末尾专门列出了这四份文档作为求助入口。

二、模板文件清单:七个文件的职责划分

模板 README 中的 "Files in This Template" 一节给出了七个文件的完整清单,每个文件都有明确的处置标注:

文件 职责 处置标注
extension.yml 扩展清单(manifest):ID、版本、命令、钩子、标签 CUSTOMIZE THIS(必须定制)
config-template.yml 用户侧配置文件的模板 CUSTOMIZE THIS(必须定制)
commands/example.md 示例命令文件 REPLACE THIS(必须替换)
README.md 扩展文档 REPLACE THIS(必须替换)
LICENSE MIT 许可证 REVIEW THIS(审阅后保留或更换)
CHANGELOG.md 版本历史(Keep a Changelog 风格 + SemVer) UPDATE THIS(随版本更新)
.gitignore Git 忽略规则 直接可用

其中 LICENSE 是标准 MIT 许可证,版权行留了 [Your Name or Organization] 占位符,发布前需要替换;CHANGELOG.md 已预置 [Unreleased][1.0.0] 两个区块,并预写了首个命令 /speckit.my-extension.example、"Configuration system with template" 等条目,提醒你在发布时填写真实日期与特性描述。

另外 模板目录 中还有一个 EXAMPLE-README.md,它示范了定制完成后 README 应有的完整形态:Features、Installation(catalog 安装与 --dev 本地安装两种方式)、Configuration(从模板拷贝并编辑配置文件)、Usage、Configuration Reference 表格、Environment Variables、Troubleshooting 等章节一应俱全。README 中明确提示"Delete this file and replace README.md with content similar to this"。

三、七步 Quick Start:从拷贝模板到发布

模板 README 的 Quick Start 给出了完整的七步流程,下面逐步展开,并补充每一步的验证要点。

第 1 步:拷贝模板

cp -r extensions/template my-extension
cd my-extension

第 2 步:定制 extension.yml

  • 修改扩展 ID、名称、描述;
  • 更新作者与仓库地址;
  • 定义你的命令列表。

第 3 步:创建命令文件

  • commands/ 目录中添加命令文件;
  • 使用带 YAML frontmatter 的 Markdown 格式。

第 4 步:创建配置模板

  • 定义配置项;
  • 为所有设置项写注释文档。

第 5 步:编写文档

  • 用使用说明替换 README.md;
  • 补充使用示例。

第 6 步:本地测试

cd /path/to/spec-kit-project
specify extension add --dev /path/to/my-extension

--dev 参数表示从本地目录安装,是开发阶段的调试入口。安装后可用 specify extension list 验证,输出应包含类似 ✓ My Extension (v1.0.0) 的条目,并显示命令数、钩子数与启用状态;命令文件会按目标 Agent 注册到对应目录(如 Claude 场景下的 .claude/commands/)。

第 7 步:发布(可选)

  1. 创建仓库(如 GitHub 仓库);
  2. 创建 Release 并打版本标签(如 v1.0.0);
  3. 提交到社区目录(见 发布指南)。

开发指南 中列出了三条分发渠道:仓库直接安装(specify extension add --dev <path>)、ZIP 归档(标记为 Future,配合 specify extension add <name> --from <url>)、以及社区参考目录(用户可浏览 catalog.community.json 发现扩展,把条目复制进自己的 catalog.json 后用 specify extension add my-ext 安装)。本仓库中社区目录文件实际位于 extensions/catalog.community.jsonextensions/catalog.json

四、extension.yml 逐字段讲解与源码级校验规则

extension.yml 是模板的核心,其每个字段都带有 CUSTOMIZEREVIEW 注释。下面按清单结构逐段讲解,并对照 ExtensionManifest 源码 说明真实约束。

4.1 顶层结构

清单必须包含四个顶层字段,源码中 ExtensionManifestREQUIRED_FIELDS 明确定义为 ["schema_version", "extension", "requires", "provides"](见 源码 L221-L225),缺失任意一项都会触发 ValidationError。模板给出的是:

schema_version: "1.0"

extension:
  id: "my-extension"
  name: "My Extension"
  version: "1.0.0"
  description: "Brief description of what your extension does"
  # category: "process"
  # effect: "read-write"
  author: "Your Name"
  repository: "https://github.com/your-org/spec-kit-my-extension"
  license: "MIT"
  homepage: "https://github.com/your-org/spec-kit-my-extension"

requires:
  speckit_version: ">=0.1.0"
  tools:
    - name: "example-mcp-server"
      version: ">=1.0.0"
      required: true

provides:
  commands:
    - name: "speckit.my-extension.example"
      file: "commands/example.md"
      description: "Example command that demonstrates functionality"
      aliases: ["speckit.my-extension.example-short"]
  config:
    - name: "my-extension-config.yml"
      template: "config-template.yml"
      description: "Extension configuration"
      required: true

hooks:
  after_tasks:
    command: "speckit.my-extension.example"
    optional: true
    prompt: "Run example command?"
    description: "Demonstrates hook functionality"
    condition: null

tags:
  - "example"
  - "template"

defaults:
  feature:
    enabled: true
    auto_sync: false

4.2 extension 元数据块

  • id:扩展标识符,必须小写字母、数字与连字符。源码校验正则为 ^[a-z0-9-]+$(见 L316-L320),MyExt(大写)、my_ext(下划线)、my ext(空格)均非法;
  • name / version / description:均为必填字符串。注意 version 必须是合法语义化版本号,模板注释也强调"Update version when releasing (semantic versioning: X.Y.Z)"。从源码的防御性检查(L295-L313)可以看到,YAML 中不加引号的 version: 1.0 会被解析为浮点数而直接触发 ValidationError,因此版本值务必加引号
  • category(可选):自由字符串,描述扩展操作对象,模板注释建议的常见取值为 docscodeprocessintegrationvisibility,源码中 category 属性也沿用了这一说明(见 L685-L688);
  • effect(可选):声明扩展是否修改项目文件,只允许 read-onlyread-write 两个取值,源码中以 VALID_EFFECTS 常量校验(见 L71);
  • author / repository / license / homepage:可选元信息,license 推荐 SPDX 标识符(如 MIT)。

4.3 requires 依赖声明

  • speckit_version:必填,语义化版本说明符。模板注释给出两种写法——>=X.Y.Z 声明最低版本,>=X.Y.Z,<Y.0.0 声明版本区间;源码要求它必须是非空字符串(见 L362-L369),并在兼容性检查中交给 SpecifierSet 解析;
  • tools:可选,声明扩展依赖的外部工具(如 MCP server),每项含 nameversionrequired;无外部依赖时应删除该节。

4.4 provides 提供物声明

provides 是模板中最需要动手的部分。一个硬性约束来自源码:扩展必须提供至少一个命令、钩子、事件、模板或脚本,否则抛出 "Extension must provide at least one command, hook, or event (or a declared template/script)"(见 L395-L405)。

命令条目的关键字段:

  • name:必须严格匹配 speckit.{ext-id}.{command-name} 三段式命名。源码正则 ^speckit\.([a-z0-9-]+)\.([a-z0-9-]+)$ 定义于 L62。若你写出 speckit.examplemy-extension.example 这类两段式旧格式,源码会尝试自动纠正为 speckit.{ext-id}.{command} 并输出警告(见 _try_correct_command_nameL643-L663),但模板建议一开始就写规范格式;
  • file:命令文件相对扩展根目录的路径(如 commands/example.md),不允许绝对路径或 ../ 上跳路径,源码通过 relative_extension_path_violation() 在清单加载阶段即拒绝违规路径(见 L467-L471);
  • aliases:可选别名数组,同样采用命名空间格式。从源码注释看,别名有意不做模式强制以兼容社区扩展(见 L490-L492);
  • 模板中"ADD MORE COMMANDS"注释块提示:为每个新命令复制该块并修改 namefile

config 条目声明用户侧配置文件:name 是安装后生成的文件名(约定与扩展 ID 对应,如 my-extension-config.yml),template 指向模板内的 config-template.ymlrequired: true 表示安装时必须生成该配置(可选时置 false)。

4.5 hooks 生命周期钩子

模板示例注册了一个 after_tasks 钩子——在核心命令 /speckit.tasks 执行后触发。钩子对象的字段语义(结合 开发指南 的 Hook 章节):

  • command:要执行的命令,必填(源码在 L424-L427 强制校验);
  • optional: true 表示执行前向用户征求确认,配合 prompt 文案;optional: false 则自动执行;
  • priority:同一事件下多个钩子的执行顺序,整数且 >= 1,默认 10,数值越小越先执行(源码常量 DEFAULT_HOOK_PRIORITY = 10L73,非法取值校验见 L428-L439);
  • condition:模板中为 null,注释标注 "Future: conditional execution",属于预留字段。

可用的钩子点覆盖核心命令前后两个时机:before/after_specifybefore/after_planbefore/after_tasksbefore/after_implementbefore/after_analyzebefore/after_checklistbefore/after_clarifybefore/after_constitutionbefore/after_taskstoissues(见 开发指南 Hooks 章节)。

模板注释还给出"同一事件挂多个命令"的写法:把钩子值写成列表,并用 priority 排序:

hooks:
  after_plan:
    - command: "speckit.my-ext.verify"
      priority: 5
    - command: "speckit.my-ext.report"
      priority: 10

源码的 coerce_hook_entries()(见 L207-L213)会把单条映射或列表统一归一化为列表处理,两种形态均合法;同时若某个钩子引用了被自动纠正过的命令名,源码会自动改写引用并警告(见 L513-L540),保证钩子不会因为命名笔误而静默失效。

4.6 tags 与 defaults

  • tags:目录发现用的标签数组,模板注释建议 2~5 个;
  • defaults:默认配置值(可选),会与用户配置合并。模板示例给出了 feature.enabled: truefeature.auto_sync: false 两个默认项。

五、命令文件 commands/example.md 的结构规范

commands/example.md 是一个 210 行的完整范例,展示了命令文件应有的全部骨架:frontmatter、步骤、配置参考、环境变量、故障排查与示例。

5.1 YAML frontmatter

---
description: "Example command that demonstrates extension functionality"
tools:
  - 'example-mcp-server/example_tool'
---
  • description:必填,命令描述;
  • tools:可选,声明该命令会用到的 MCP 工具(格式为 'server/tool'),模板中同时提示"List MCP tools this command uses";
  • 开发指南 中还提到可选的 scripts 字段(sh: / ps: 指向帮助脚本),其中的相对路径会在注册时被重写(例如 ../../scripts/bash/helper.sh 变为 .specify/scripts/bash/helper.sh),便于扩展命令引用核心 Spec Kit 脚本。

5.2 正文骨架

模板命令文件的正文分七段,全部带有 CUSTOMIZE 注释:

  1. Purpose:命令做什么、何时使用;
  2. Prerequisites:执行前置条件(如 "MCP server configured"、"Configuration file exists"、"Valid API credentials");
  3. User Input:占位符 $ARGUMENTS,运行时由用户提供的参数替换;
  4. Steps:模板给出四步范例——
    • Step 1 读取配置:从 .specify/extensions/my-extension/my-extension-config.yml 加载,缺失时打印错误并提示 specify extension add my-extension,读取后叠加环境变量覆盖 setting_value="${SPECKIT_MY_EXTENSION_KEY:-$setting_value}"
    • Step 2 主操作:通过 MCP 工具执行动作,参数引用上一步的配置值;
    • Step 3 结果处理:格式化输出;
    • Step 4(可选)保存输出:把带 UTC 时间戳的 JSON 写入 .specify/my-extension-output.json
  5. Configuration Reference:以 "Setting / Type / Required / Default / Example" 的条目形式逐一文档化配置项;
  6. Environment Variables:列出环境变量覆盖映射及 export 示例;
  7. Troubleshooting:覆盖三类典型故障——"Configuration not found"(重新安装并从模板复制配置文件)、"MCP tool not available"(检查 Agent 侧 MCP 配置)、"Permission denied"(检查外部服务凭据);
  8. Examples:三个用法示例——默认配置执行 > /speckit.my-extension.example、环境变量覆盖后执行、以及接在 > /speckit.tasks 之后的工作流串联。

正文末尾的落款约定是 *For more information, see the extension README or run specify extension info my-extension*

补充一点来自 开发指南 的可移植性约定:当命令需要引用其他命令时,不要硬编码 /speckit.xxx 字面量,而应使用 __SPECKIT_COMMAND_<NAME>__ 令牌(如 __SPECKIT_COMMAND_BUG_FIX__),由 Spec Kit 按当前 Agent 的调用风格(斜杠点号 / 斜杠连字符 / skills 前缀)渲染,保证一次编写、多 Agent 可用。

六、config-template.yml:配置分层与环境变量覆盖

config-template.yml 示范了一个面向外部服务集成的完整配置结构,按语义分为六段:

配置段 字段示例 说明
connection url(必填)、api_key(必填) 外部服务连接信息
project id(必填)、workspace(可选) 项目标识与所属组织
features enabled: trueauto_sync: falseverbose: false 功能开关
defaults labels: []priority: "medium"assignee: "" 默认行为参数,priority 取值限定 low/medium/high
field_mappings internal_field: "external_field_id" 内部字段到外部字段 ID 的映射(示例态)
advanced timeout: 30retry_count: 3cache_duration: 3600 超时、重试、缓存等高级参数

该模板最重要的两块注释知识是环境变量覆盖本地覆盖文件

  1. 环境变量覆盖:任何配置项都可按 SPECKIT_MY_EXTENSION_{SECTION}_{KEY} 模式用环境变量覆盖,例如 SPECKIT_MY_EXTENSION_CONNECTION_API_KEY 覆盖 connection.api_keySPECKIT_MY_EXTENSION_PROJECT_ID 覆盖 project.id;约定是全大写、用下划线替代点号。模板同时示范了敏感值(api_key)应留空、交由环境变量注入,避免凭据入库;
  2. 本地覆盖文件:开发期可创建 my-extension-config.local.yml 进行个人化覆盖,模板的 .gitignore 首行即 *-config.local.yml,确保本地覆盖不会被提交。

结合 开发指南 的 "Config Loading" 章节,完整的加载优先级为四层:

  1. 扩展默认值(extension.ymldefaults);
  2. 项目配置(.specify/extensions/my-ext/my-ext-config.yml);
  3. 本地覆盖(.specify/extensions/my-ext/my-ext-config.local.yml,已 gitignore);
  4. 环境变量(SPECKIT_MY_EXT_*)。

命令文件中的 Step 1 示例正是这一优先级的运行时体现:先用 yq 读取配置文件,再用 ${ENV:-$value} 语法让环境变量胜出。

七、README、CHANGELOG 与 LICENSE 的配套写法

模板对三份"门面文件"各有示范:

  • README:以 EXAMPLE-README.md 为蓝本。它展示了定制后 README 的完整章节结构:特性列表、安装方式(catalog 安装 specify extension add my-extension 与本地 --dev 安装并列)、配置初始化三步(cp 模板为正式配置文件 → 编辑器修改 → 填入必填值)、每个命令的 Usage 说明(前置条件与输出物)、配置参考表格(含 Type / Required 列)、环境变量覆盖示例、故障排查(含 "Command not available" 的三连排查:specify extension list → 重启 Agent → 重装扩展),以及版本落款;
  • CHANGELOGCHANGELOG.md 采用 Keep a Changelog 结构([Unreleased] 下的 Planned 区块 + 已发布版本区块),版本区块按 Added / Features / Requirements 分组,并预留了比较链接锚点;
  • LICENSELICENSE 为标准 MIT,发布前替换版权行占位符。

这些文件共同构成 开发指南 "Best Practices" 中 Documentation 一节的推荐形态:README 管概览与用法,CHANGELOG 管版本史,命令文件管单命令细节。

八、本地测试与自动化验证

8.1 手动测试循环

开发指南 的 "Testing Extensions" 章节给出了五步手动测试循环,与模板 README 第 6 步衔接:

  1. 在目标项目中 specify extension add --dev /path/to/extension
  2. specify extension list 确认条目出现(名称、版本、命令数、钩子数、状态);
  3. 在 AI Agent 中执行命令(如 Claude 中 > /speckit.my-extension.example world);
  4. 检查注册产物,例如 ls .claude/commands/speckit.my-extension.*
  5. 卸载验证:specify extension remove my-ext

安装后的扩展会注册进项目内 .specify/extensions/ 目录,注册表文件 .specify/extensions/.registryExtensionRegistry 管理——它持久化每个扩展的元数据与 installed_at 时间戳,list / get 方法均返回深拷贝且会过滤损坏条目,因此一条坏清单不会拖垮 specify extension list 的整体输出。

8.2 自动化测试建议

开发指南 给出了一段 pytest 骨架:用 ExtensionManifest 加载 extension.yml,断言 ID 正确、命令数至少为 1,并遍历所有命令条目断言 cmd["file"] 文件真实存在。这段测试恰好覆盖了最常见的两类发布事故——清单声明了不存在的命令文件、以及 ID 与预期不符。本仓库自身的第一方扩展测试(如 git 扩展测试bug 扩展测试)也可以作为编写此类测试的参考。

九、定制检查清单(Customization Checklist)

模板 README 末尾的 12 项检查清单是发布前的自查标准,完整保留如下:

  • [ ] Update extension.yml with your extension details
  • [ ] Change extension ID to your extension name
  • [ ] Update author information
  • [ ] Define your commands
  • [ ] Create command files in commands/
  • [ ] Update config template
  • [ ] Write README with usage instructions
  • [ ] Add examples
  • [ ] Update LICENSE if needed
  • [ ] Test extension locally
  • [ ] Create git repository
  • [ ] Create first release

对照前文的源码校验规则,这份清单中隐藏的两个高频失手点值得强调:extension.yml 中 ID 与版本号必须加引号且符合 ^[a-z0-9-]+$ / SemVer 约束;provides.commandsname 必须为 speckit.{ext-id}.{command}file 为扩展根目录内的相对路径。只要这两点过关,specify extension add --dev 的清单校验阶段就不会再报 ValidationError

十、总结

extensions/template 的价值在于它把"一个能被 Spec Kit 正确识别、安装、注册命令并挂接钩子"的最小完整形态固化成了七个开箱即用的文件:extension.yml 声明身份与提供物(受 ExtensionManifest 严格校验)、commands/example.md 示范命令文件的 frontmatter 与正文骨架、config-template.yml 示范四层配置优先级与环境变量覆盖约定,三份门面文件则固化了文档规范。开发新扩展时,最稳妥的路径就是:拷贝模板 → 按 CUSTOMIZE 注释逐项替换 → 用 specify extension add --dev 在真实项目里跑通"安装、执行、卸载"循环 → 按 12 项清单自查后发布。所有字段约束、钩子事件点与故障排查细节,均可在 扩展开发指南API 参考 中进一步查证。

登录后查看全文
热门项目推荐
相关项目推荐