首页
/ Spec Kit 如何编写自定义 Bundle:从 bundle.yml 到 validate 与 build 产出安装制品

Spec Kit 如何编写自定义 Bundle:从 bundle.yml 到 validate 与 build 产出安装制品

2026-09-08 16:37:09作者:裴麒琰

如果你已经用 Spec Kit 的扩展、预设、工作流和步骤搭好了某个团队或角色的组件栈,接下来要做的就是把它们打成一个可版本化、可安装的 bundle:写一份 bundle.yml 清单,用 specify bundle validate 检查清单是否合法、组件引用能否解析,再用 specify bundle build 产出单个 .zip 安装制品。本文以 developer 示例 bundle 为参照,完整走一遍"写清单 → 校验 → 打包"这条路径,并给出文档中有依据的验证方式和常见校验报错。

Bundle 是什么:一份清单加一组可安装引用

Bundles 参考文档 的说法,bundle 把既有的 Spec Kit 组件——extensions、presets、workflows、steps——组合成一个单一、带版本、可安装的单元。它本身不引入新的运行时行为,只是分发放置层:安装时按清单中固定的版本解析各组件,幂等地逐个安装,并记录来源以便后续移除或刷新。

一个 bundle 目录的最低要求由打包逻辑定义:目录下必须有 bundle.yml,且必须有一个面向使用者的 README.md,否则 build 会直接拒绝并提示 No README.md found ... Every bundle must ship a README.md describing it.。清单的完整字段可对照 developer 示例

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"]

写清单时需要遵守的约束如下,全部来自清单校验逻辑与契约测试(test_manifest_schema.py):

  • bundleidnameversionroledescriptionauthorlicense 均为必填;字段值为空(YAML 里写成 author: 这种显式 null)会被按缺失报错。requires.speckit_version 也是必填,且必须是合法的版本约束。
  • schema_version 只接受当前支持的值(示例用的是 "1.0"),写其他值会被拒绝。
  • bundle.version 必须是 semver,如 1.0.0id 必须是可以当作路径片段的 slug(如 team-a.bundle_1 合法,../evil 会被结构性校验标记)。
  • provides 中 extensions、presets、workflows 的每个组件都必须用 version 固定版本,唯独 steps 可以省略版本。
  • presets 额外要求两个字段:priority(必须是整数,写 "high" 这类字符串会直接抛出 priority must be an integer)和 strategy(示例中是 "append",填 "merge" 这类未定义值会被拒绝)。
  • requires.toolsrequires.mcptags 都必须是字符串列表,写成单个字符串(如 tags: "security")会被拒绝,而不是按字符拆分。
  • 清单可选地声明 integration(必须是一个 mapping,不能是裸字符串)。声明后 bundle 就不再是 integration-agnostic 的:它绑定特定集成,而示例中的 agnostic bundle 则继承项目当前活跃的 integration。如果 bundle 目标集成与已初始化项目的活跃集成不同,安装会直接中止且不产生任何改动。

用 validate 检查清单与组件引用

清单写好后,在 bundle 所在目录或任意位置都可以显式指定路径运行校验:

specify bundle validate --path examples/bundles/developer

--path 接受 bundle 目录或 bundle.yml 文件路径,缺省为当前目录;--offline 表示只对照 bundled/已安装组件校验引用。校验做两件事:

  1. 结构性检查:上面列出的必填字段、semver、slug、pin、priority/strategy 等规则,不合法项会逐条以字段名报错,例如缺 license 时报 bundle.license
  2. 引用解析检查:清单里每个组件引用会依次对照 bundled 组件、项目已安装组件,以及在线时的活跃 catalog。只有当某个可达的 catalog 明确确认组件不存在时,校验才以 error 失败;离线校验、或 catalog 不可达导致"无法确认"的引用会降级为 warning,让编写流程可以继续。

所以判断标准是:输出中没有 error 即通过;warning 不阻塞,但如果你依赖非默认 catalog 的组件,需要确认用户侧已添加对应 catalog 源,否则安装时这些引用可能解析不到。

用 build 产出 .zip 安装制品

校验通过后执行构建:

specify bundle build --path examples/bundles/developer --output dist/

--path 指定 bundle 目录(缺省为当前目录),--output 指定制品输出目录。构建行为在 packager 实现 中定义,几个直接影响产物的点:

  • 产物命名为 <bundle id>-<version>.zip,例如 developer-1.0.0.zip,输出到 --output 目录(未指定则输出到 bundle 目录本身)。
  • 构建前会先做清单校验,manifest 非法时拒绝构建,并提示"Run 'specify bundle validate' and fix",同时列出具体错误。
  • 打包内容限于 bundle 目录内的文件;.git__pycache__.DS_Store 以及符号链接一律排除,目录内之前构建过的同 bundle 的 *.zip 制品不会被打进新制品。
  • 构建是可复现的:相同输入得到逐字节一致的制品(固定的 zip 时间戳与归一化权限)。

验证制品可安装

制品产出后的验证路径与安装命令同源:specify bundle install 的参数既可以是 catalog 里的 bundle id,也可以是本地路径——构建好的 .zip 制品、bundle 目录、或 bundle.yml 文件都可以直接作为本地源安装,且本地源安装不查询 catalog 栈:

# 用构建出的制品安装(在目标项目目录内)
specify bundle install dist/developer-1.0.0.zip

如果当前目录还不是 Spec Kit 项目,install 会先初始化项目再安装,所以在一个干净目录里执行这条命令就是对 bundle 的端到端验证。安装是幂等的(已存在的组件会被跳过);失败时不写来源记录,并会尽力回滚本次运行安装的组件。

安装后可以用 specify bundle list 查看项目中已安装的 bundle、版本、组件数与安装时间;specify bundle info <bundle_id> 则展示"完全展开后的组件集合"——每个 extension、preset、step、workflow 及其固定版本,这个预览就是 install 实际应用的计划,可用来核对制品内容与预期一致。

常见校验报错怎么读

契约测试覆盖了 validate 的多数拒绝路径,遇到报错时可以这样对照:

  • bundle.<字段名>:对应必填字段缺失或为 null,按字段名补齐。
  • semverbundle.version 不是合法的语义化版本号。
  • priority / strategy:preset 条目缺字段或 strategy 取值不受支持;priority must be an integer 表示 priority 写了非整数值。
  • must be pinned:extensions/presets/workflows 下的某个组件漏了 version
  • Unresolved reference ...:某个组件引用在所有可检查的来源里都不存在——检查组件 id 拼写,或确认用户环境是否已添加该组件所在的 catalog。
  • 'tags' must be a list of strings / 'provides' must be a mapping when present 这类类型错误:对应字段写成了标量或非 mapping 值。

发布前的收尾

如果 bundle 要交给其他人使用,参考文档给出的路径是:先在本地完成 validate 与 build,然后自行托管生成的制品与 catalog 元数据(catalog 条目指向 bundle 制品,但 bundle.yml 内声明的组件在用户安装时仍然要走 bundled 组件、已安装组件或活跃的 extension/preset/workflow/step catalog 解析)。如果引用了非默认 catalog 的组件,需要把 catalog 地址写进文档,并在添加了这些 catalog 的干净项目里实测安装路径。社区 bundle 的提交要求见 Community Bundles 文档,其中明确要求提交包含由 specify bundle build 产出的版本化制品、说明用途/组件/依赖 catalog 的文档,以及干净项目的测试证据。

对仓库内四个示例 bundle(developer、product-manager、business-analyst、security-researcher)做同样的校验与构建,可以直接沿用 developer 示例 README 给出的命令形式,替换 --path 指向对应目录即可。

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

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
docsdocs
暂无描述
Markdown
899
5.83 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
925
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
601
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.03 K
525
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
395