Spec Kit 社区 Bundle 详解:角色化组件栈的发布、发现与安装策略
在 Spec-Driven Development 工作流中,单个 extension、preset 或 workflow 只能解决局部问题;当团队希望“一次装好某个角色所需的全部组件”时,就需要 Bundle 这一分发与组合层。本篇以社区 Bundle 目录(docs/community/bundles.md)为核心,讲清楚三件事:社区 Bundle 的信任边界与当前已收录条目、bundle.yml 组件引用如何跨目录解析,以及一个 Bundle 从提交、审核到更新的完整生命周期。读完后,你将能够评估一个社区 Bundle 是否可信可装、为自己的团队制作并上架 Bundle,并理解内置社区源的 discovery-only 策略在源码层面的实现。
一、Bundle 是什么:组件的“组合层”而非新运行时
Spec Kit 的原语是 extension(命令扩展)、preset(命令/模板预设)、workflow 和 step。Bundle 本身不引入新的运行时行为,而是把这些既有原语组合成一个按角色或团队划分的“技术栈”,并通过每个组件自身的机制一次性安装——文档原话是:bundle 是“distribution and composition layer over the primitives you already use”(分发与组合层)。
社区 Bundle(Community Bundles)由各自作者独立创建与维护。文档在开头用一段 NOTE 明确了信任边界:
Maintainers only verify that submission metadata is complete and correctly formatted — they do not review, audit, endorse, or support the bundle code or the components it installs.
也就是说,官方维护者只校验提交元数据是否完整、格式是否正确,不审查、不审计、不背书、不维护 Bundle 代码及其安装的组件。因此安装前必须自行审阅 bundle manifest、组件目录(catalog)和源码仓库,风险自负。这是使用任何社区 Bundle 前必须建立的预期。
二、当前社区目录:两个已收录条目
获批的社区 Bundle 条目发布在 bundles/catalog.community.json 中。当前该文件(schema_version: "1.0")收录了两个条目,其完整元数据可以直接从仓库中核实:
| Bundle | 角色 | 当前版本 | 提供的组件 | 要求的 Spec Kit 版本 | 标签 |
|---|---|---|---|---|---|
| SicarioSpec Security & Governance Bundle | security-engineer |
0.5.1 | 1 extension + 11 presets | >=0.9.0 |
security, governance, compliance, appsec, threat-modeling |
| SpecAssay | developer |
0.4.12 | 1 extension + 1 preset | >=0.14.0 |
traceability, governance, durable-ids, gate, sdd |
两个条目的共同点(均可在 bundles/catalog.community.json 中逐字段核对):
- 均声明了
download_url(指向各自发布仓库的版本化 zip 产物)与repository字段,verified均为false——社区条目默认不标记为组织级策展的 verified 条目; provides对象给出四类组件的计数,与文档中表格的 “Provides” 列一一对应;requires.speckit_version声明了对宿主 Spec Kit 的最低版本约束。
条目解析时的健壮性由 src/specify_cli/bundler/models/catalog.py 中的 load_catalog_payload 保障:目录 JSON 必须包含顶层 bundles 对象,且每个条目的 id 字段必须与其外层键完全一致,否则抛出 BundlerError——这防止了恶意或损坏的目录把某个 id 解析到不同的 bundle 上。
三、发现与安装的分权:内置社区源是 discovery-only
文档给出了一个关键机制:内置社区源是“仅发现”(discovery-only)的——specify bundle search 和 specify bundle info 可以查看条目,但按 ID 安装必须显式添加一个 install-allowed 的目录;显式添加的目录默认优先级高于内置社区源。
从源码结构看,这一行为由两处代码共同实现:
- 内置默认目录栈定义在 src/specify_cli/bundler/models/catalog.py:
BUILTIN_DEFAULT_STACK: tuple[dict[str, Any], ...] = (
{"id": "default", "url": "builtin://default", "priority": 1,
"install_policy": InstallPolicy.INSTALL_ALLOWED.value},
{"id": "community", "url": "builtin://community", "priority": 20,
"install_policy": InstallPolicy.DISCOVERY_ONLY.value},
)
内置 community 源的 install_policy 硬编码为 discovery-only,优先级 20;而用户通过 specify bundle catalog add 添加的显式源默认优先级为 10(数字越小优先级越高),因此天然覆盖社区源。
- 解析逻辑在 src/specify_cli/bundler/services/catalog_stack.py 的
CatalogStack.resolve中:按优先级遍历各源,第一个命中的条目即生效,并携带其来源的install_policy作为安装许可判断依据(ResolvedBundle.install_allowed)。search方法同样遵循“每个 bundle id 只在其最高优先级来源处解析一次”的语义,避免低优先级的影子条目被展示出来却无法安装。
项目级目录配置持久化在 .specify/bundle-catalogs.yml 中,写入路径与字段校验见 src/specify_cli/bundler/commands_impl/catalog_config.py:id、url、priority、install_policy 四字段必填,URL 支持 http(s)://(远程强制 HTTPS,仅 localhost 允许 HTTP)、file://、builtin:// 或本地路径,重复 id/url 会直接报错。
对应的命令速查(完整参数说明见 Bundles 参考文档):
# 发现(任何目录可运行,无需项目初始化)
specify bundle search [query] # 支持 --offline / --json
specify bundle info <bundle_id> # 展示完整展开的组件集合与信任标记
# 显式目录管理(需要已 specify init 的项目)
specify bundle catalog list
specify bundle catalog add <url> --policy install-allowed --priority 10 --id <id>
specify bundle catalog remove <id_or_url>
# 安装/卸载(install 会在未初始化目录中先自动初始化项目)
specify bundle install <bundle_id | path>
specify bundle remove <bundle_id>
specify bundle list
四、组件解析:目录条目只指路,组件还要能“落地”
这是社区 Bundle 使用中最容易踩坑的环节。文档 “Component Resolution” 一节指出:Bundle 目录条目描述的是从哪里下载 bundle 产物,但 bundle.yml 里声明的组件引用(extension、preset、step、workflow 的 id + 版本)在用户安装时仍需要独立解析。引用可以来自三个位置:
- bundled components——随 bundle 产物一起携带的组件;
- 已安装组件——项目中已经装好的同名组件;
- 活跃的 extension / preset / workflow / step 目录——用户显式添加的各类组件 catalog。
因此文档的要求很直接:如果你的 bundle 依赖默认 Spec Kit 目录中不存在的组件,必须在提交材料和 README 中给出这些目录 URL,并在添加了这些目录的干净项目中完整测试安装路径后再提交。
文档给出的标准安装序列是:
specify preset catalog add https://example.com/presets.json --name example-bundle --install-allowed
specify extension catalog add https://example.com/extensions.json --name example-bundle --install-allowed
curl -L -o example-bundle-1.0.0.zip https://example.com/example-bundle-1.0.0.zip
specify bundle install ./example-bundle-1.0.0.zip
# Or install by id from an install-allowed bundle catalog.
specify bundle catalog add https://example.com/bundles.json --id example-bundle-catalog --policy install-allowed
specify bundle install example-bundle
注意两条安装路径的差异:本地路径安装(.zip 产物、bundle 目录或 bundle.yml 文件)不查询目录栈,直接安装;按 id 安装则依赖目录栈解析,且只有 install-allowed 来源才允许安装。specify bundle validate 命令会对这一解析过程做预检——引用在“可检查的所有位置”都确定缺失时才失败,离线或目录不可达导致的不可验证引用会降级为警告,而不是阻断(详见 docs/reference/bundles.md 的 Validate 一节)。
作为对照,仓库内置的示例 bundle 展示了一个完整 bundle.yml 的形状(四类组件引用、requires、preset 的 priority/strategy 字段):examples/bundles/developer/bundle.yml,其 README 还演示了 specify bundle validate --path ... 与 specify bundle build --path ... --output dist/ 的本地验证与打包流程。
五、提交一个社区 Bundle
5.1 提交清单
按文档 “What to Submit” 一节,一个合格的 Bundle 提交应包含:
- 一个包含有效
bundle.ymlmanifest 的公开仓库; - 一个版本化的 GitHub Release,其中包含由
specify bundle build生成的 bundle 产物; - 说明目标角色、安装组件、所需目录与预期工作流的文档;
- 一个包含 bundle 元数据与组件计数的目录条目提案;
- 来自干净 Spec Kit 项目的测试证据。
5.2 提交模板的完整字段
提交通过 Bundle Submission issue 模板进行,模板文件就在仓库内:.github/ISSUE_TEMPLATE/bundle_submission.yml。其必填字段与上述清单一一对应,并可据此精确准备材料:
| 字段 | 说明 | 约束/示例 |
|---|---|---|
| Bundle ID | 唯一标识 | 以字母或数字开头结尾,中间可含小写字母、数字、点、下划线、连字符,如 security-governance-stack |
| Version | 语义化版本号 | 如 1.0.0 |
| Role or Team | 目标角色 | 如 security-engineer、product-manager |
| Repository URL | 源码仓库 | GitHub 仓库地址 |
| Download URL | 版本化产物地址 | 必须是 specify bundle build 生成的产物链接 |
| Documentation URL | 说明文档 | 解释 bundle 安装内容与用法 |
| License | 开源协议 | 如 MIT、Apache-2.0 |
| Required Spec Kit Version | 最低版本约束 | 如 >=0.9.0 |
| Integration Target(可选) | 固定的集成 id | 如 claude、copilot;留空表示 integration-agnostic |
| Components Provided | 提供的组件清单 | 按 extensions/presets/workflows/steps 分类列出,含版本 |
| Required Component Catalogs | 依赖的非默认目录 | 无则填 “None” |
| Proposed Catalog Entry | 目录条目 JSON | 见下文 |
| Testing Checklist | 六项必勾测试项 | validate、build、产物安装、端到端分发路径、干净项目、目录依赖 |
| Submission Requirements | 六项必勾要求项 | 含 README、LICENSE、版本 tag、id 一致性、版本 pin |
其中“Proposed Catalog Entry”要求直接给出顶层 bundles 对象下的 JSON 条目,其形状与 bundles/catalog.community.json 中现网条目一致:
{
"your-bundle": {
"name": "Your Bundle",
"id": "your-bundle",
"version": "1.0.0",
"role": "security-engineer",
"description": "Brief description of the stack",
"author": "Your Name",
"license": "MIT",
"download_url": "https://example.com/releases/download/v1.0.0/your-bundle-1.0.0.zip",
"repository": "https://example.com/your-org/your-bundle",
"requires": { "speckit_version": ">=0.9.0" },
"provides": { "extensions": 1, "presets": 2, "steps": 0, "workflows": 1 },
"tags": ["security", "governance"],
"verified": false
}
}
模板中的测试清单还明确要求:验证命令、构建命令、从产物安装、(若提案含目录条目)从 install-allowed 目录按 bundle-id 安装的端到端路径、干净项目安装、目录依赖文档化——共 6 项均为必勾。
六、审核范围:检查什么,不检查什么
文档 “Review Scope” 将维护者的职责压缩成五件事,并明确划出不做的部分:
检查项:
- 提交字段完整且格式正确;
- Release 产物与文档 URL 可达;
- 仓库包含
bundle.ymlmanifest; - 提交材料清晰标识了所需的组件目录;
- 目录条目使用了预期的 bundle catalog 条目形状。
不检查项: 维护者不审计所安装 extension、preset、workflow、step 或脚本的行为。这一声明与开头 NOTE 呼应,也解释了为什么 verified 字段在社区条目中始终为 false,以及为什么 specify bundle search / info 的输出会携带信任标记(verified 对应组织策展条目,否则为 community)供用户在安装前自行判断。
提交后的流程:维护者在 issue triage 阶段打上 bundle-submission 标签,即可触发自动化的目录校验(模板中说明了这一点,无需用户自行申请标签)。
七、更新已提交的 Bundle
更新走与首发相同的通道:再提交一个 Bundle Submission issue,包含新版本号、新下载 URL、变更后的组件清单和更新后的测试证据,并在 issue 中说明这是对既有目录条目的更新。由于审核只校验元数据与可达性,更新的主要成本在于:重新执行干净项目中的端到端安装测试,尤其是组件目录有变动时。
八、实践要点小结
结合 docs/community/bundles.md 与 Bundles 命令参考,使用与制作社区 Bundle 的完整闭环是:
- 用户侧:
specify bundle search/info发现并预览(含信任标记与完整组件展开)→ 若依赖非默认组件,先catalog add所需目录 → 本地产物或按 idspecify bundle install→specify bundle list/remove管理生命周期; - 作者侧:编写
bundle.yml→specify bundle validate本地预检 →specify bundle build产出 zip → 在干净项目中带目录依赖完整走一遍安装 → 按模板提交 issue → 获批后条目进入bundles/catalog.community.json; - 机制侧:内置社区源永远 discovery-only(priority 20),install-allowed 源靠显式添加且默认 priority 10 压过它;安装是幂等的、按组件溯源记录,失败不写溯源记录并尽力回滚已装组件。
理解这套“发现与安装分权”的设计,就能解释社区目录为何既能自由增长,又不会让未经显式授权的来源污染项目的安装面。
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