首页
/ spec-kit Developer Bundle 实战解析:用一个 bundle.yml 打包「规格驱动开发」的完整开发侧能力

spec-kit Developer Bundle 实战解析:用一个 bundle.yml 打包「规格驱动开发」的完整开发侧能力

2026-09-04 15:31:30作者:傅爽业Veleda

spec-kit 的 bundle(捆绑包)机制可以把扩展(extension)、预设(preset)、工作流步骤(steps)和工作流(workflow)四类组件组合成一个带版本的可安装单元。本文以仓库自带的示例 developer bundle 为主体,完整拆解它的 manifest 结构、每个字段的取值约束与校验规则,并结合源码说明 specify bundle validatespecify 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-implementationbreak-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 块下七个字段全部必填:idnameversionroledescriptionauthorlicense,缺失任意一项都会报 Missing required field: bundle.xxxmanifest.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),安装阶段则由安装计划的解析器用它做硬性版本门禁;
  • toolsmcp 声明本 bundle 依赖的外部工具与 MCP 服务器,Developer bundle 均为空数组,表示无额外依赖。

2.4 provides:四类组件的引用规则

provides 下的 extensionspresetsworkflows 每类组件必须钉住 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_STRATEGIESmanifest.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):

  1. 结构校验:即第二节的必填项、semver、slug、priority/strategy 规则,任一违反进入 errors,最终 report.ok 为 False 时命令以非零码退出并列出全部错误;
  2. speckit_version 约束校验>=0.9.0 会被解析为合法约束,写错(如 >=0.9 之外的畸形表达式)会报 not a valid constraint
  3. 组件参考解析:每个 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.ymlREADME.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 属性直接相关:

  1. 按需初始化:若当前目录还不是 Spec Kit 项目,install 会先以默认/指定集成跑 specify init,一条命令达到可用状态;
  2. 集成冲突门禁:已初始化项目的「激活集成」是权威——若 bundle 钉死了某个集成且与项目不一致,安装直接中止、不留状态。Developer bundle 不钉集成,因此可以装进任意集成的项目;
  3. 幂等与溯源:已存在的组件按 id 跳过(幂等),安装记录写入溯源记录,remove 时只卸载本 bundle 贡献的组件,不产生附带删除;安装失败则不写任何记录;
  4. 版本钉住的适用边界:幂等检查按 id 而非版本,install 不会比对磁盘版本与 manifest 钉住版本;需要重新应用钉住版本时用 specify bundle update

六、横向对照:四个角色 bundle 的差异

examples/bundles/ 下四个示例包结构同构,差异全在 provides 的组件选择与 preset 策略上,对照可以看清「同一机制、不同角色配方」的设计意图(各 bundle 的 bundle.ymlexamples/bundles/product-manager/bundle.ymlexamples/bundles/business-analyst/bundle.ymlexamples/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-implementationbreak-down-tasks draft-specreview-spec capture-requirementstrace-acceptance-criteria threat-modelsecurity-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.0validate/build 不要求当前目录是 Spec Kit 项目,而 list/update/remove 要求项目已用 specify init 初始化(installbundle init 会在未初始化目录中按需创建项目)。

八、小结

Developer bundle 的价值有两层:作为使用者,它把「实现规划 + 任务拆解 + spec 到代码」这条开发侧链路以一条 install 命令引入任意集成环境,且 preset 采用 append 策略保证不覆盖项目既有命令;作为参考实现,它的 bundle.yml 恰好展示了四类组件的完整写法——带版本的 extension/preset/workflow、不带版本的 step、preset 的 priority 与 strategy、空 tools/mcp 依赖——配合 manifest 模型校验器打包器 的源码,是编写自定义角色 bundle 时最贴近实际约束的一份活文档。

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