
spec-kit Preset 预设系统详解模板解析栈、组合策略与specify preset命令全景【免费下载链接】spec-kit Toolkit to help you get started with Spec-Driven Development项目地址: https://gitcode.com/GitHub_Trending/sp/spec-kit在 Spec-Driven Development 工作流中Spec Kit 的 Preset预设机制允许你在不修改任何核心文件的前提下替换模板、重写命令、统一团队术语甚至对整个工作流做本地化改造。本文基于仓库内的官方参考文档与src/specify_cli/presets/源码系统讲解specify preset的完整命令族search / add / remove / list / info / resolve / enable / disable / set-priority / catalog深入剖析优先级解析栈 replace/prepend/append/wrap 组合策略的底层实现并给出可直接复现的实操示例帮助你在团队中落地组织级规范、审计模板来源、调试多预设叠加时的文件胜出规则。Preset 是什么不改工具只换内容Preset 是对 Spec Kit 工作行为进行定制的最小单元——它以模板、命令、脚本三类文件为载体覆盖 Spec Kit 生成的 artifactsspecs、plans、tasks、checklists、constitutions以及指导 LLM 生成这些产物的命令。多个 Preset 可以同时安装并按优先级叠加stacking互不冲突。两类被覆盖对象的作用不同见 presets/README.mdTemplates模板定义生成什么——spec、plan、constitution 等 artifact 的骨架结构Commands命令定义LLM 如何生成——逐步指导 AI 编码代理执行 SDD 流程的指令。一个关键设计是模板解析发生在运行时。安装时预设文件只是被拷贝进.specify/presets/id/Spec Kit 每次需要模板时都会重新遍历解析栈而不是把模板合并到某个单一位置。未安装任何预设时行为与没有 Preset 系统时完全一致——始终回落到核心模板。Preset 全生命周期命令所有specify preset子命令都要求项目已经通过specify init初始化。命令实现位于 src/specify_cli/presets/_commands.py业务逻辑集中在 src/specify_cli/presets/init.py约 5900 行包含PresetManifest、PresetRegistry、PresetManager、PresetCatalog、PresetResolver五大类。搜索可用预设specify preset searchspecify preset search [query]选项说明--tag按标签过滤--author按作者过滤不带 query 时列出所有可用预设。搜索会在所有激活的 catalog中进行——因此 catalog 的管理直接决定了你能看见和装到什么后文会展开。安装预设specify preset addspecify preset add [preset_id]选项说明--dev path从本地目录安装开发调试用--from url从自定义 URL 安装而不是从 catalog--priority N解析优先级默认 10数字越小优先级越高安装行为由PresetManager执行要点有三兼容性检查check_compatibility()读取preset.yml的requires.speckit_version用packaging.SpecifierSet与当前版本比对不满足时抛出PresetCompatibilityError并提示升级命令见 presets/init.py。命令自动注册若预设含type: command条目命令会被注册到当前激活的AI 编码代理集成目录中如.claude/commands/、.gemini/commands/并按代理类型渲染为 Markdown 或 TOML。安装后调和reconciliation安装与移除之后系统会基于当前解析栈重新计算受影响命令名下的有效内容并写回移除时甚至可能更新该预设曾写入的非活跃代理目录以恢复幸存的命令/skill 层。非活跃集成不会收到这些命令文件直到你通过specify integration use key或switch key切换——切换时会为新的激活集成重新 scaffold 所有已启用预设。官方 catalog 中的内置预设示例presets/catalog.json包含lean精简核心工作流命令与constitution-sync为把物化模板当作受审产物的团队恢复安装期 constitution 物化。以lean的清单 presets/lean/preset.yml 为例它通过 5 个type: command条目覆盖speckit.specify、speckit.plan、speckit.tasks、speckit.implement、speckit.constitution五个核心命令要求speckit_version: 0.6.0。移除、列出、查询# 移除删除文件、注销其命令、清理注册表条目 specify preset remove preset_id # 列出显示版本、描述、模板数量与当前状态 specify preset list # 详细信息模板、元数据、标签 specify preset info preset_id # 追踪某个名字最终解析到哪个文件 specify preset resolve namespecify preset list的输出按解析/胜出顺序打印优先级最高的预设priority 数字最小排在最前priority 相同时按预设 id 字母序决胜——这与命令组合、模板解析使用的顺序完全一致因此列表第一项就是重叠文件的最终胜者。这一语义在源码中由PresetRegistry.list_by_priority()实现默认跳过enabled: false的预设默认 priority 归一化为 10排序键为(priority, pack_id)见 presets/init.py。启用 / 禁用enable与disablespecify preset enable preset_id specify preset disable preset_id禁用不等于移除。两者的差别是排查行为问题时最常踩的坑操作文件解析已注册命令文件/注册表disable该预设被跳过模板/脚本不再命中保留在 AI 代理中直到移除保留remove彻底消失从所有代理目录注销并删除文件全部清除因此如果只想临时对比有/没有该预设的模板输出用disable如果希望命令层面的改动立即失效必须remove。随时可用enable重新启用。调整优先级set-priorityspecify preset set-priority preset_id priority数字越小越优先。当多个预设提供同名文件时priority 数字最小者胜出。Catalog预设的发现与安装来源Catalog 控制search和add到哪里寻找预设。多个 catalog 按优先级顺序数字小者先查生效解析顺序为首个命中即停止环境变量—SPECKIT_PRESET_CATALOG_URL覆盖所有 catalog等价于只用这一个 catalog项目配置—.specify/preset-catalogs.yml用户配置—~/.specify/preset-catalogs.yml内置默认— 官方 catalog 社区 catalog。源码印证PresetCatalog.get_active_catalogs()见 presets/init.py环境变量路径返回单个priority1, install_allowedTrue的自定义条目且对非默认 URL 打印一次性警告Only use catalogs from sources you trust.项目配置整体替换默认栈注意不是与默认栈合并无配置时的内置栈为defaultpriority 1允许安装communitypriority 2仅发现、不允许安装。Catalog 管理命令# 列出所有激活 catalog含优先级与安装权限 specify preset catalog list # 添加 catalog specify preset catalog add url # 按名称移除 specify preset catalog remove namecatalog add的完整参数选项说明--name name必填catalog 唯一名称--priority N优先级默认 10数字小者优先--install-allowed / --no-install-allowed是否允许从该 catalog 安装预设默认仅发现--description text可选描述添加操作会写入项目的.specify/preset-catalogs.yml示例catalogs: - name: my-org-presets url: https://example.com/preset-catalog.json priority: 5 install_allowed: true description: Our approved presets从源码结构看每个 catalog 条目是PresetCatalogEntry(url, name, priority, install_allowed, description)数据类presets/init.pycatalog JSON 按 URL 做 SHA256 哈希生成独立缓存文件presets/init.py缓存有效期为 1 小时。此外对 GitHub 域名的请求会自动附带GH_TOKEN/GITHUB_TOKEN适用于私有仓库托管的 catalog 或预设 ZIP非 GitHub URL 一律不带凭据。文件解析优先级栈与组合策略四层解析栈Preset 可以提供三类文件command 文件、template 文件如plan-template.md、script 文件。每个文件名字在栈中独立求值所以不同文件完全可以来自不同层。模板与脚本在 Spec Kit 需要时实时查栈命令则用同一栈做替换与组合但只在激活集成目录中物化一次——代理每次执行命令时不会重新解析栈。从最高到最低优先级解析栈为Project-local overrides—.specify/templates/overrides/Installed presets— 按 priority 排序数字小者先查位于.specify/presets/‹id›/Installed extensions— 按 priority 排序位于.specify/extensions/‹id›/Spec Kit core—.specify/templates/各层内文件按类型组织在子目录中类型子目录覆盖路径Templatestemplates/.specify/templates/overrides/Commandscommands/.specify/templates/overrides/Scriptsscripts/.specify/templates/overrides/scripts/一次典型的运行时解析请求plan-template.md实操示例specify preset add compliance --priority 5 specify preset add team-workflow --priority 10对于两者都提供的文件compliance5 10胜出只有一方提供的文件用那一方的都没有的用 core 默认。四种组合策略默认策略是replace栈中第一个命中的文件整体生效。模板与命令还支持组合策略让预设增强而非替换低优先级内容策略行为模板命令脚本replace默认完全替换低优先级内容✓✓✓prepend放在低优先级内容之前空行分隔✓✓—append放在低优先级内容之后空行分隔✓✓—wrap内容中的占位符{CORE_TEMPLATE}模板/命令或$CORE_SCRIPT脚本被低优先级内容替换✓✓✓脚本只支持replace与wrap——在 presets/init.py 中定义VALID_PRESET_TEMPLATE_TYPES {template, command, script} VALID_PRESET_STRATEGIES {replace, prepend, append, wrap} # Scripts only support replace and wrap (prepend/append dont make semantic sense for executable code) VALID_SCRIPT_STRATEGIES {replace, wrap}在preset.yml中按条目声明strategyname指定组合目标file指向实际内容文件二者可以不同provides: templates: - type: template name: spec-template file: templates/spec-addendum.md strategy: append # 在 core 模板之后追加内容组合是递归链式的例如一个prepend的 security 预设加一个append的 compliance 预设最终产物是security 头 core 内容 compliance 尾。源码透视resolve_content()如何组合多层PresetResolver.resolve_content()presets/init.py是组合的执行者其算法值得细读顶层是 replace 就直接返回——低层内容完全无关否则自高优先级向下找到最近的 replace 层作为有效基座basebase 之下的层被忽略从 base 向上一层层应用策略prepend为content layer \n\n contentappend为content content \n\n layerwrap则把占位符替换进基座内容对命令类型逐层剥离 frontmatter防止 YAML 元数据泄漏进正文最终把最高优先级层的 frontmatter重新装回若其缺少scripts/agent_scripts/argument-hint键会从 base 层继承内部的strategy键一律剥除不会出现在写给代理的命令文件里wrap层若缺少占位符会抛出PresetValidationError错误信息明确指出缺失的是{CORE_TEMPLATE}还是$CORE_SCRIPT。而resolve()presets/init.py在栈内查找单个文件时还有两个容易忽略的细节manifest 优先于约定路径只要预设的preset.yml声明了某(name, type)条目就必须解析其file:字段声明了但文件缺失时不回落到约定路径templates/name.md以免掩盖拼写错误或捡到未声明的散落文件第 5 层兜底项目.specify/templates/未命中时还会查 wheel 安装内的 core_pack 或源码检出仓库根下的templates/保证wrap策略总能定位到真正的{CORE_TEMPLATE}来源。resolve_core()则是跳过预设层tier 2的特化变体防止 wrap 时误把另一个预设的 wrap 产物当成 core。调试利器specify preset resolvespecify preset resolve spec-template specify preset resolve speckit.specify该命令调用collect_all_layers()打印完整解析栈presets/_commands.py显示最高优先级层的路径与来源top layer from: ...检测到组合时额外输出Composition chain——从有效 base 层向上逐层列出[base]、[prepend]、[append]、[wrap]标签与各层来源路径若组合无法产出结果没有任何 replace 基座给出黄色警告名字中不含点的按 template 解析含点的按 command 解析如speckit.git.feature。多个预设提供同名文件时这条命令就是判断到底谁赢的唯一权威手段。命令注册与集成目录模板是运行时解析的命令则不同命令覆盖在安装时物化。PresetManager._register_commands()presets/init.py的处理流程只处理type: command条目若策略非 replace先检查该预设是否是组合栈的顶层——是则预组合后写入.composed/再注册不是则先注册原始文件随后立即执行 reconciliation 修正为正确内容若没有可组合的基座如要 wrap 的扩展未安装警告并跳过该命令而不中止整个安装通过resolve_active_agent_for_registration()解析当前激活集成项目没有init-options.json旧布局时回退到检测全部代理的注册模式文件存在但损坏时失败关闭不注册任何内容避免静默扩散注册时按代理格式渲染——Claude 系写 Markdown.md$ARGUMENTS占位Gemini/Qwen/Tabnine 写 TOML{{args}}Copilot 写.agent.md 伴生.prompt.md。更完整的架构图含注册流程图、agent 格式表、constitution 生命周期见 presets/ARCHITECTURE.md。Preset 清单规范preset.yml的硬性校验创建预设时可复制 presets/scaffold/ 脚手架起步PresetManifestpresets/init.py会对清单做严格校验常见报错都源于此校验项规则schema_version必须等于1.0字符串必备顶层字段schema_version、preset、requires、providespreset.id小写字母/数字/连字符正则^[a-z0-9-]$preset.version合法语义化版本且必须是带引号的字符串version: 1.0会被 YAML 解析成 float 而报错requires.speckit_version非空字符串作为 PEP 440 specifier 使用provides.templates至少一条每条必须含type/name/filetype取值template/command/scriptstrategy取值replace/prepend/append/wrap脚本仅replace/wrap自动转小写持久化命令名点分小写^[a-z0-9.-]$如speckit.specify其他类型不含点file路径必须是预设目录内的相对路径禁止..上跳重复声明同一(name, type)不得重复否则后续条目将永远不可达安装本地开发版验证# 1. 复制 scaffold 并编辑 preset.yml # 2. 本地安装 specify preset add --dev ./my-preset # 3. 验证解析结果 specify preset resolve spec-template常见疑问FAQ可以同时使用多个预设吗可以。预设按 priority 叠加——每个文件独立地从提供它且优先级最高的来源解析。用specify preset set-priority控制顺序。如何确认某个名字实际生效的是哪个文件运行specify preset resolve name追踪解析栈查看胜出文件组合场景下还会打印完整的 Composition chain。disable 和 remove 到底差在哪disable保留安装、仅将其排除在模板/脚本解析之外之前注册的命令仍留在 AI 代理中直到你真正移除该预设——所以命令层面的变更需要remove才会失效。disable适合临时对照有/无预设的模板或脚本输出差异随时enable恢复。remove则是完全卸载删除文件、注销命令、清除注册表条目。预设由谁维护绝大多数预设由其作者独立创建和维护。Spec Kit 维护者不审查、不审计、不背书、不支持预设代码本身对 community catalog 仅验证条目完整性与格式正确。安装前请自行审查预设源码风险自担具体问题请联系其作者或在对应仓库提 issue。相关文档用户指南与快速上手presets/README.md内部架构解析/注册/catalog 流程图、模块结构presets/ARCHITECTURE.md预设上架指南presets/PUBLISHING.md参考文档本文主体来源docs/reference/presets.md核心实现src/specify_cli/presets/init.pyPresetResolver/PresetManager/PresetCatalog与 src/specify_cli/presets/_commands.py【免费下载链接】spec-kit Toolkit to help you get started with Spec-Driven Development项目地址: https://gitcode.com/GitHub_Trending/sp/spec-kit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考