spec-kit Developer Bundle 实战解析:用一个 bundle.yml 打包「规格驱动开发」的完整开发侧能力
spec-kit 的 bundle(捆绑包)机制可以把扩展(extension)、预设(preset)、工作流步骤(steps)和工作流(workflow)四类组件组合成一个带版本的可安装单元。本文以仓库自带的示例 developer bundle 为主体,完整拆解它的 manifest 结构、每个字段的取值约束与校验规则,并结合源码说明 specify bundle validate 与 specify bundle build 两条命令的底层行为,让你既能读懂这个面向开发者的角色包,也能照此模式编写自己的角色 bundle。
一、Developer bundle 定位:开发者视角的 SDD 组件集
Developer bundle 是 spec-kit 仓库 examples/bundles/ 目录下四个角色示例包之一(其余为 product-manager、business-analyst、security-researcher),面向「践行规格驱动开发(Spec-Driven Development)的开发者」,覆盖实现规划、任务拆解与代码评审场景。按其 README 声明,安装后向项目中引入四类组件:
| 组件类型 | id | 说明 |
|---|---|---|
| Extension | agent-context |
保持 agent 上下文文件(.specify 下的上下文记录)与项目同步 |
| Preset | implementation-planning(priority 10,strategy append) |
实现规划命令集,以追加方式并入现有命令 |
| Steps | plan-implementation、break-down-tasks |
实现规划、任务拆解两个工作流步骤 |
| Workflow | spec-to-implementation |
驱动一份 spec 一路走向可运行代码的完整工作流 |
一个关键属性是 integration-agnostic(集成无关):它不绑定任何 AI 编码集成(如 copilot、claude、codex 等),安装时自动继承项目当前激活的集成。这一点在 manifest 中体现为「不声明 integration 字段」——源码中 BundleManifest.is_agnostic() 的判定逻辑就是 self.integration is None。
二、bundle.yml 逐字段解析
Developer bundle 的完整 manifest 见 examples/bundles/developer/bundle.yml,全文如下:
schema_version: "1.0"
bundle:
id: "developer"
name: "Developer"
version: "1.0.0"
role: "developer"
description: "Spec-Driven Development setup for developers: implementation planning, task breakdown, and code review."
author: "spec-kit-examples"
license: "MIT"
requires:
speckit_version: ">=0.9.0"
tools: []
mcp: []
provides:
extensions:
- id: "agent-context"
version: "1.0.0"
presets:
- id: "implementation-planning"
version: "1.0.0"
priority: 10
strategy: "append"
steps:
- id: "plan-implementation"
- id: "break-down-tasks"
workflows:
- id: "spec-to-implementation"
version: "1.0.0"
tags: ["development", "implementation", "code-review"]
结合 BundleManifest 模型 的解析与结构校验代码,各字段的约束规则如下:
2.1 schema_version
当前仅支持 "1.0",对应源码常量 SUPPORTED_SCHEMA_VERSIONS = {"1.0"}(manifest.py#L18)。取其他值会被 structural_errors() 判为错误。
2.2 bundle 元数据
bundle 块下七个字段全部必填:id、name、version、role、description、author、license,缺失任意一项都会报 Missing required field: bundle.xxx(manifest.py#L172-L184)。另有两条隐藏规则:
version必须是合法 semver:如本例的1.0.0,由is_semver校验;id必须是文件系统安全的 slug:正则^a-z0-9?$,即小写字母、数字、.、_、-,且不能以分隔符结尾(manifest.py#L26)。之所以如此严格,是因为 id 会直接拼进产物文件名<id>-<version>.zip,路径分隔符会造成逃逸风险。
另外注意一个解析细节:源码中的 _text() 辅助函数会把 YAML 中显式的 null(例如 author: 后无值)归一为空字符串,避免 str(None) 把字面量 "None" 当作合法作者发布出去(manifest.py#L223-L236)。
2.3 requires:兼容性约束
speckit_version: ">=0.9.0"是一个版本约束表达式,validate 阶段会调用parse_constraint验证其合法性(validator.py#L43-L50),安装阶段则由安装计划的解析器用它做硬性版本门禁;tools与mcp声明本 bundle 依赖的外部工具与 MCP 服务器,Developer bundle 均为空数组,表示无额外依赖。
2.4 provides:四类组件的引用规则
provides 下的 extensions、presets、workflows 每类组件必须钉住 version(合法 semver),而 steps 允许省略版本——这条不对称规则直接体现在 Developer bundle 的写法中:三个非 step 组件都带了 version: "1.0.0",两个 step 只有 id(校验代码见 manifest.py#L195-L205)。
preset 组件额外强制两个字段:
priority:整数,决定该 preset 命令集在命令优先级排序中的位置;strategy:取值必须是replace/prepend/append/wrap之一(PRESET_STRATEGIES,manifest.py#L19)。Developer bundle 选用append,意味着implementation-planning预设的命令追加到已有命令之后、不覆盖项目原有命令。
bundle 顶层的 integration 字段(Developer bundle 未声明,故为 integration-agnostic)若存在则必须是 mapping 且带 id;非 mapping 的裸字符串会被显式拒绝,避免 bundle 被误判为集成无关(manifest.py#L125-L133)。
顶层 tags(如 ["development", "implementation", "code-review"])用于目录搜索与展示,必须是字符串列表。
三、validate:校验命令做了什么
Developer bundle README 给出的第一条使用命令:
specify bundle validate --path examples/bundles/developer
对应实现在 bundle validate 命令,其执行链路是「读 manifest → 结构校验 → 约束校验 → 参考解析」,由 validate_manifest 汇总成 ValidationReport(errors + warnings):
- 结构校验:即第二节的必填项、semver、slug、priority/strategy 规则,任一违反进入 errors,最终
report.ok为 False 时命令以非零码退出并列出全部错误; - speckit_version 约束校验:
>=0.9.0会被解析为合法约束,写错(如>=0.9之外的畸形表达式)会报not a valid constraint; - 组件参考解析:每个
provides条目会经由 reference checker 在「项目已捆绑/已安装组件 + 在线目录」中解析。解析不到且能被目录确认不存在时记为错误;离线(--offline)或目录不可达导致的「无法验证」则降级为 warning,不阻断编写流程——这正是官方 bundles 参考文档 中 validate 一节描述的语义。
--path 可以传 bundle 目录(内部定位 bundle.yml)或直接指向 bundle.yml 文件,路径解析逻辑见 _resolve_manifest_path。
四、build:如何产出一个可分发的 zip 工件
第二条命令:
specify bundle build --path examples/bundles/developer --output dist/
它调用 build_bundle,产出一个以 <id>-<version>.zip 命名的工件(本例为 developer-1.0.0.zip),其中的构建细节值得逐条了解:
- README 强制存在:bundle 目录必须同时携带
bundle.yml和README.md,缺少 README 会直接拒绝构建(packager.py#L43-L49)——这解释了 Developer bundle 目录里两个文件缺一不可; - 先校验后打包:构建前会跑一遍
validate_manifest,manifest 不合法时拒绝构建并提示先执行specify bundle validate; - 可复现构建:zip 成员时间戳固定为 1980-01-01(zip 纪元),文件权限归一为 0755/0644 两档(保留可执行位使脚本解包后仍可运行),成员按 POSIX 路径名排序——相同输入在任何机器上产出字节级一致的工件(packager.py#L82-L100);
- 内容安全收敛:排除
.git、__pycache__、.DS_Store,跳过符号链接文件与目录、跳过历史构建产物(匹配<id>-x.y.z.zip的旧工件),并保证每个打包文件都位于 bundle 目录之内(ensure_within); - 路径逃逸防护:产物路径会用
ensure_within(out_dir, artifact_path)做纵深校验,即使 id 校验被绕过也无法把 zip 写到--output之外。
构建完成后,该 zip 可直接通过 specify bundle install <path>/developer-1.0.0.zip 安装,安装器会从 zip 中读取 bundle.yml(带大小限制与 UTF-8 严格解码,见 _local_manifest_source)。
五、在项目中使用 Developer bundle
Developer bundle 的 README 聚焦于「编写侧」两条命令,而消费侧走的是通用 bundle 命令(完整参数表见 docs/reference/bundles.md):
# 在 Spec Kit 项目内,从本地目录安装(不经过 catalog 解析)
specify bundle install examples/bundles/developer
# 查看已安装 bundle(含组件数与安装时间)
specify bundle list
# 刷新到 manifest 钉住的版本
specify bundle update developer
# 卸载仅本 bundle 贡献的组件
specify bundle remove developer
安装流程(bundle install)有几个行为要点,与 Developer bundle 的 integration-agnostic 属性直接相关:
- 按需初始化:若当前目录还不是 Spec Kit 项目,
install会先以默认/指定集成跑specify init,一条命令达到可用状态; - 集成冲突门禁:已初始化项目的「激活集成」是权威——若 bundle 钉死了某个集成且与项目不一致,安装直接中止、不留状态。Developer bundle 不钉集成,因此可以装进任意集成的项目;
- 幂等与溯源:已存在的组件按 id 跳过(幂等),安装记录写入溯源记录,
remove时只卸载本 bundle 贡献的组件,不产生附带删除;安装失败则不写任何记录; - 版本钉住的适用边界:幂等检查按 id 而非版本,
install不会比对磁盘版本与 manifest 钉住版本;需要重新应用钉住版本时用specify bundle update。
六、横向对照:四个角色 bundle 的差异
examples/bundles/ 下四个示例包结构同构,差异全在 provides 的组件选择与 preset 策略上,对照可以看清「同一机制、不同角色配方」的设计意图(各 bundle 的 bundle.yml 见 examples/bundles/product-manager/bundle.yml、examples/bundles/business-analyst/bundle.yml、examples/bundles/security-researcher/bundle.yml):
| 维度 | developer(本文主角) | product-manager | business-analyst | security-researcher |
|---|---|---|---|---|
| 角色 | developer | product-manager | business-analyst | security-researcher |
| Preset | implementation-planning(priority 10 / append) |
product-discovery(priority 10 / append) |
requirements-elicitation(priority 10 / append) |
security-compliance(priority 5 / append) |
| Steps | plan-implementation、break-down-tasks |
draft-spec、review-spec |
capture-requirements、trace-acceptance-criteria |
threat-model、security-review |
| Workflow | spec-to-implementation |
spec-to-roadmap |
requirements-to-spec |
secure-sdd |
| 共同点 | 均带 agent-context 扩展;requires.speckit_version: ">=0.9.0";均 integration-agnostic |
可以注意 security-researcher 的 preset priority 为 5(其余为 10),说明优先级数值是角色包调校命令排序的旋钮。
七、完整实操流程小结
以 Developer bundle 为例,从编写侧到消费侧的完整命令序列:
# 1. 校验 manifest 结构与组件引用(在 spec-kit 仓库根目录)
specify bundle validate --path examples/bundles/developer
# 2. 打包为可分发工件
specify bundle build --path examples/bundles/developer --output dist/
# 产出 dist/developer-1.0.0.zip
# 3. 在目标 Spec Kit 项目中安装(本地路径 / zip / catalog id 三选一)
specify bundle install dist/developer-1.0.0.zip
# 4. 验证安装结果
specify bundle list
适用前提:spec-kit 版本满足 >=0.9.0;validate/build 不要求当前目录是 Spec Kit 项目,而 list/update/remove 要求项目已用 specify init 初始化(install 与 bundle init 会在未初始化目录中按需创建项目)。
八、小结
Developer bundle 的价值有两层:作为使用者,它把「实现规划 + 任务拆解 + spec 到代码」这条开发侧链路以一条 install 命令引入任意集成环境,且 preset 采用 append 策略保证不覆盖项目既有命令;作为参考实现,它的 bundle.yml 恰好展示了四类组件的完整写法——带版本的 extension/preset/workflow、不带版本的 step、preset 的 priority 与 strategy、空 tools/mcp 依赖——配合 manifest 模型、校验器 与打包器 的源码,是编写自定义角色 bundle 时最贴近实际约束的一份活文档。
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