Spec Kit 扩展模板深度解析:基于 extensions/template 构建、调试并发布你的第一个扩展
本文以 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 步:发布(可选)
- 创建仓库(如 GitHub 仓库);
- 创建 Release 并打版本标签(如
v1.0.0); - 提交到社区目录(见 发布指南)。
开发指南 中列出了三条分发渠道:仓库直接安装(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.json 与 extensions/catalog.json。
四、extension.yml 逐字段讲解与源码级校验规则
extension.yml 是模板的核心,其每个字段都带有 CUSTOMIZE 或 REVIEW 注释。下面按清单结构逐段讲解,并对照 ExtensionManifest 源码 说明真实约束。
4.1 顶层结构
清单必须包含四个顶层字段,源码中 ExtensionManifest 的 REQUIRED_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(可选):自由字符串,描述扩展操作对象,模板注释建议的常见取值为docs、code、process、integration、visibility,源码中category属性也沿用了这一说明(见 L685-L688);effect(可选):声明扩展是否修改项目文件,只允许read-only或read-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),每项含name、version、required;无外部依赖时应删除该节。
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.example或my-extension.example这类两段式旧格式,源码会尝试自动纠正为speckit.{ext-id}.{command}并输出警告(见_try_correct_command_name,L643-L663),但模板建议一开始就写规范格式;file:命令文件相对扩展根目录的路径(如commands/example.md),不允许绝对路径或../上跳路径,源码通过relative_extension_path_violation()在清单加载阶段即拒绝违规路径(见 L467-L471);aliases:可选别名数组,同样采用命名空间格式。从源码注释看,别名有意不做模式强制以兼容社区扩展(见 L490-L492);- 模板中"ADD MORE COMMANDS"注释块提示:为每个新命令复制该块并修改
name与file。
config 条目声明用户侧配置文件:name 是安装后生成的文件名(约定与扩展 ID 对应,如 my-extension-config.yml),template 指向模板内的 config-template.yml,required: true 表示安装时必须生成该配置(可选时置 false)。
4.5 hooks 生命周期钩子
模板示例注册了一个 after_tasks 钩子——在核心命令 /speckit.tasks 执行后触发。钩子对象的字段语义(结合 开发指南 的 Hook 章节):
command:要执行的命令,必填(源码在 L424-L427 强制校验);optional: true表示执行前向用户征求确认,配合prompt文案;optional: false则自动执行;priority:同一事件下多个钩子的执行顺序,整数且>= 1,默认 10,数值越小越先执行(源码常量DEFAULT_HOOK_PRIORITY = 10见 L73,非法取值校验见 L428-L439);condition:模板中为null,注释标注 "Future: conditional execution",属于预留字段。
可用的钩子点覆盖核心命令前后两个时机:before/after_specify、before/after_plan、before/after_tasks、before/after_implement、before/after_analyze、before/after_checklist、before/after_clarify、before/after_constitution、before/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: true与feature.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 注释:
- Purpose:命令做什么、何时使用;
- Prerequisites:执行前置条件(如 "MCP server configured"、"Configuration file exists"、"Valid API credentials");
- User Input:占位符
$ARGUMENTS,运行时由用户提供的参数替换; - 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;
- Step 1 读取配置:从
- Configuration Reference:以 "Setting / Type / Required / Default / Example" 的条目形式逐一文档化配置项;
- Environment Variables:列出环境变量覆盖映射及
export示例; - Troubleshooting:覆盖三类典型故障——"Configuration not found"(重新安装并从模板复制配置文件)、"MCP tool not available"(检查 Agent 侧 MCP 配置)、"Permission denied"(检查外部服务凭据);
- 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: true、auto_sync: false、verbose: false |
功能开关 |
defaults |
labels: []、priority: "medium"、assignee: "" |
默认行为参数,priority 取值限定 low/medium/high |
field_mappings |
internal_field: "external_field_id" |
内部字段到外部字段 ID 的映射(示例态) |
advanced |
timeout: 30、retry_count: 3、cache_duration: 3600 |
超时、重试、缓存等高级参数 |
该模板最重要的两块注释知识是环境变量覆盖与本地覆盖文件:
- 环境变量覆盖:任何配置项都可按
SPECKIT_MY_EXTENSION_{SECTION}_{KEY}模式用环境变量覆盖,例如SPECKIT_MY_EXTENSION_CONNECTION_API_KEY覆盖connection.api_key、SPECKIT_MY_EXTENSION_PROJECT_ID覆盖project.id;约定是全大写、用下划线替代点号。模板同时示范了敏感值(api_key)应留空、交由环境变量注入,避免凭据入库; - 本地覆盖文件:开发期可创建
my-extension-config.local.yml进行个人化覆盖,模板的 .gitignore 首行即*-config.local.yml,确保本地覆盖不会被提交。
结合 开发指南 的 "Config Loading" 章节,完整的加载优先级为四层:
- 扩展默认值(
extension.yml的defaults); - 项目配置(
.specify/extensions/my-ext/my-ext-config.yml); - 本地覆盖(
.specify/extensions/my-ext/my-ext-config.local.yml,已 gitignore); - 环境变量(
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 → 重装扩展),以及版本落款; - CHANGELOG:CHANGELOG.md 采用 Keep a Changelog 结构(
[Unreleased]下的 Planned 区块 + 已发布版本区块),版本区块按Added/Features/Requirements分组,并预留了比较链接锚点; - LICENSE:LICENSE 为标准 MIT,发布前替换版权行占位符。
这些文件共同构成 开发指南 "Best Practices" 中 Documentation 一节的推荐形态:README 管概览与用法,CHANGELOG 管版本史,命令文件管单命令细节。
八、本地测试与自动化验证
8.1 手动测试循环
开发指南 的 "Testing Extensions" 章节给出了五步手动测试循环,与模板 README 第 6 步衔接:
- 在目标项目中
specify extension add --dev /path/to/extension; specify extension list确认条目出现(名称、版本、命令数、钩子数、状态);- 在 AI Agent 中执行命令(如 Claude 中
> /speckit.my-extension.example world); - 检查注册产物,例如
ls .claude/commands/speckit.my-extension.*; - 卸载验证:
specify extension remove my-ext。
安装后的扩展会注册进项目内 .specify/extensions/ 目录,注册表文件 .specify/extensions/.registry 由 ExtensionRegistry 管理——它持久化每个扩展的元数据与 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.ymlwith 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.commands 的 name 必须为 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 参考 中进一步查证。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00