ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

BMad 安装生命周期管理:setup / doctor / update 三命令的完整运维指南

2026/9/19 7:48:59 拓冰建站 浏览量
BMad 安装生命周期管理:setup / doctor / update 三命令的完整运维指南 BMad 安装生命周期管理setup / doctor / update 三命令的完整运维指南【免费下载链接】BMAD-METHODBreakthrough Method for Agile Ai Driven Development项目地址: https://gitcode.com/gh_mirrors/bm/BMAD-METHODBMadBreakthrough Method for Agile AI-Driven Development把「安装、体检、升级」拆成三条互不越界的命令流bmad setup负责物化_bmad运行时bmad doctor只修复已存在的运行时bmad update仅做只读的版本检查。本文以 skills/bmad/references/setup.md 为骨架结合 skills/bmad/scripts/setup.py 的源码实现完整讲解三条命令的调用方式、JSON 报告语义、模块配置问题的问答流程以及底层物化与合并机制读完即可独立完成 BMad 的安装、修复与版本核对。命令分发三条流互不串线BMad 的安装运维入口由 hub skill 负责路由。当用户以命令名或自然语言表达「setup、update、doctor」意图时Agent 必须加载 skills/bmad/references/setup.md 并严格按对应流程执行见 skills/bmad/SKILL.md 的分发规则。三条命令的定位差异是本文全部内容的前提bmad update—— 纯检查inspection only只报告安装状态不做任何修改bmad doctor—— 修复repairs an existing runtime只针对已经存在的_bmad运行时bmad setup—— 安装performs setup负责从零物化或整体重建运行时。三条流绝不互相代跑update 请求不会触发 setupdoctor 请求也不会被路由到 setup。此外所有脚本调用都依赖uv如果环境中缺少uv或无法运行Agent 必须明确告知用户先安装uv并停止执行绝不使用其他方式绕行编写_bmad。bmad update只读的版本体检调用命令update 是纯检查命令运行时不允许创建任何答案文件或临时文件直接执行 skill 内的脚本uv run --no-cache {skill-root}/scripts/setup.py --project-root {project-root} --skill {skill-root} --update其中{skill-root}是 bmad skill 在宿主环境中的实际路径{project-root}是目标项目根目录。在源码层面--update分支会拒绝与--list-config-questions或--module-answers组合使用见 setup.py保证检查路径纯粹只读。JSON 报告与状态语义脚本以 JSON 形式输出报告每个 module 一个状态并列出该 module 的每一份已安装副本按 skill id 与版本标识。顶层current字段为true仅当所有 module 都处于current状态。报告中的状态取值必须原样转述共七种状态含义current已安装版本与源版本一致无需更新newer-available源版本比已安装版本更新存在可升级版本ahead已安装版本领先于源版本differing-unordered两版本无法按 SemVer 排序比较如含-dev或非 SemVer 版本could-not-check无法读取源清单如网络失败必须附上 source 特定的失败原因version-spread同一 module 的多份副本版本不一致source-disagreement多份副本各自可检查但状态结论不一致模块级的汇总逻辑可在 setup.py 的 update_report 中看到先判断是否version-spread多版本其次是否could-not-check再检查状态是否单一否则归为source-disagreement。单副本的版本判定由version_state完成可比较且相等为current低于源为newer-available高于源为ahead不可比较为differing-unorderedsetup.py。报告纪律出现version-spread时必须逐一列出每一份副本could-not-check必须包含该次检查失败的原因必须说明本次使用的 bmad 副本及其版本bmad_copy字段顶层current不为true时严禁宣称安装已是最新。update 的边界update 只做两件事重新扫描已安装的 skills以及读取每个源的module-manifest.toml。它不会安装、移动、修复或删除任何 skill不会写项目或写 lockfile也不会执行npx skills update。如果报告显示有可用更新正确做法是把「更新已安装 skill 文件夹」这件事交给npx skills update负责——这正是 update 分支在源码中刻意保持只读 的设计意图。update 的版本比较基于严格的 SemVer 解析SEMVER正则覆盖 major.minor.patch、预发布与构建元数据且显式排除含-dev的版本setup.py预发布比较遵循「无预发布 有预发布、数字段按数值、字母段按字典序」的规则compare_prerelease。源清单的读取支持四种update_source前缀——github:、https://、file:、plugin:——其中github:会被展开为 raw 源地址plugin:直接标记为plugin-managed并提示通过插件市场更新file:则解析为相对或绝对本地路径update_copy_report。bmad doctor对既有运行时做精准修复前置条件与状态机doctor 要求{project-root}/_bmad已存在。当该目录缺失时两条 doctor 子命令都会返回顶层status: setup-requiredAgent 必须转告用户先运行bmad setup并停止不得自行创建 staging 目录或任何项目输出对应源码中的missing_bmad_report见 setup.py。若_bmad存在但不是普通目录同样报错终止若_bmad是符号链接脚本会提示用链接指向的真实目录作为--project-root重新执行reject_symlinked_bmad。第一步列出新声明的配置问题只读uv run --no-cache {skill-root}/scripts/setup.py --project-root {project-root} --skill {skill-root} --doctor --list-config-questions该命令输出一个 JSON 数组每个元素形如{module: ..., key: ..., prompt: ..., default: ...}。问答纪律数组中的每个问题只问一次且严格按数组顺序必须展示其default已有答案的问题不会出现在数组中不得重问更不得覆盖用户接受默认值时必须原样使用脚本输出的默认值。第二步写入临时答案文件当数组非空时仅将返回的模块答案写入一个新的临时 TOML 文件路径记录为{module-answers-path}。写入时必须遵循与 setup 完全一致的引用、转义、避撞规则和[modules....]结构详见下文「已安装模块问题」一节例如[modules.example] simple_key selected answer nested.key selected answer第三步执行修复# 无新声明的配置问题 uv run --no-cache {skill-root}/scripts/setup.py --project-root {project-root} --skill {skill-root} --doctor # 带新声明的答案 uv run --no-cache {skill-root}/scripts/setup.py --project-root {project-root} --skill {skill-root} --doctor --module-answers {module-answers-path}成功结束后只删除本次 doctor 运行创建的临时答案文件。doctor 报告字段doctor 报告顶层status有三种取值current—— 无需任何修复repaired—— 完成了修复reconciled-with-warnings—— 仍有 module 处于版本分散spread或被阻塞blocked状态。报告中还必须包含共享脚本的修复结果shared_scripts、新增的答案answers_added、每个 module 的选中或阻塞状态modules[].state、module 脚本修复的精确结果scripts: repaired/current/unchanged、剩余的版本分散version_spreads与过期remaining_staleness以及本次使用的 bmad 副本/版本bmad_copy。顶层current字段为false当且仅当存在阻塞或版本分散见 doctor 函数。doctor 的修复边界当legacy_leftovers非空时必须说明「经典 BMad 安装器遗留的文件仍然存在且未被触碰」这些文件定义在源码的LEGACY_LEFTOVERS常量中setup.py包括_config/manifest.yaml、_config/bmad-help.csv、core/config.yaml等旧安装器产物本地修复成功不等于项目级 skill 副本已更新只要version_spreads或remaining_staleness非空就不得宣称整个安装为最新并应告知用户协调被阻塞或分散 module 的已安装副本是npx skills update的职责doctor保留既有配置答案、custom/、用户层以及非脚本的 module 文件它只把共享脚本树与选中的 module 脚本树修到与源完全一致byte 级因此可能删除这些脚本目录下过期的文件遇到畸形配置、非法 manifest 或答案、不可读脚本、来源歧义时必须指名出错来源并停止绝不尝试第二条修复路径。doctor 的 module 选择逻辑select_doctor_modules值得单独说明单副本直接选中多副本时先剔除不可排序的 dev/非 SemVer 版本——若剩余副本内容完全一致则仍可选中否则标记blocked在可排序副本中选取最高 release若并列最高版本的多个副本 manifest 或脚本负载不一致同样标记blocked。这保证了 doctor 只会从「可信的最高版本副本」物化脚本杜绝在冲突状态下盲目修复。bmad setup物化与重建_bmad运行时行为契约setup 自身不提出任何问题——唯一的问题来源是已安装 module 的 manifest。其契约要点重复运行幂等且保留团队答案第二次运行会保留既有团队答案包括非字符串值只询问新声明的 module 问题经典安装器文件永不触碰经典 BMad 安装器在_bmad下遗留的文件LEGACY_LEFTOVERS所列不会被修改或删除修复_bmad/scripts当该路径是符号链接、或是一份与打包 bmad skill 的scripts/并非 byte 完全一致的拷贝时setup 会将其修复——每个符号链接都被替换为普通拷贝byte 一致的拷贝原样保留成功完成的 setup 永远不会创建符号链接对应 stage_bmad / ensure_scripts 的实现tree_matches先做整树逐字节比对不匹配才重建永不触碰custom/与既有*.user.toml。setup 的物化流程源码视角setup()setup.py的执行链如下拒绝符号链接形式的_bmad从 skill 取scripts/与assets/config.template.toml作为负载payload()并校验resolve_config.py等关键文件存在用项目目录名填充模板中的{directory_name}占位符fill_team_config解析出团队配置模板读取既有_bmad/config.toml通过fill_keep做「模板为骨架、既有值为优先」的递归合并——既有的键全部保留且覆盖模板默认值模板新增的键才保留模板值fill_keep发现已安装 modules找出尚未回答的配置问题find_pending_questions按modules.module.key路径探测是否已存在校验答案文件与待答问题集合完全一致不多不少validate_module_answers在_bmad的兄弟 staging 目录_bmad.setup-*中物化先拷贝现有_bmad保留custom/、额外的*.user.toml与遗留物再写入scripts/、config.toml、每个 module 的scripts/与custom/最后通过replace_dir原子替换materialize_bmad依据配置中的output_folder确保输出目录存在默认_bmad-output见 output_folder。replace_dir的三步换位dest 改名备份 → staging 改名就位 → 删备份保证了即便中途失败也能回滚是「setup 永不破坏既有运行时」的底层保障setup.py。已安装模块问题配置问答与 TOML 答案文件这是 setup 与 doctor 共用的核心交互协议。发现待答问题只读uv run --no-cache {skill-root}/scripts/setup.py --project-root {project-root} --skill {skill-root} --list-config-questions输出 JSON 数组元素含module、key、prompt、default四个字段。规则数组中的每个问题只问一次、按数组顺序、展示default数组里没有的问题不问接受默认值时原样使用脚本输出——脚本已经将{directory_name}展开为项目目录名同时保留{project-root}与未知占位符的字面量见 find_pending_questions 中的 default 替换。答案文件的写法当数组非空时用 Write 工具而不是 shell把选定的答案写入{project-root}/.bmad-help-setup-modules.toml若该路径已存在另选一个临时路径以避免覆盖任何既有文件并把实际路径记录为{module-answers-path}。不要把这些答案放进config.user.toml或其他*.user.toml。写入要点只把答案放在其所属 module 之下每个返回的 key 都作为一个 TOML key 加引号写入使点分 key 保持无歧义[modules.example] simple_key selected answer nested.key selected answer所有值必须是 TOML 基础字符串basic strings反斜杠、双引号、换行、回车、制表符及其他控制字符必须正确转义。源码中的toml_string/toml_control函数setup.py正是这套转义规则的实现\、、\b、\t、\n、\f、\r显式映射其余0x20以下与0x7F的控制符转成\uXXXXload_module_answers会校验答案文件只含modules表扁平化后逐值必须是字符串且同一(module, key)不得重复定义setup.pyvalidate_module_answers进一步要求答案与待答问题严格一一对应多了报is not a pending question少了提示先运行--list-config-questionssetup.py。执行 setup# 无模块答案 uv run --no-cache {skill-root}/scripts/setup.py --project-root {project-root} --skill {skill-root} # 带模块答案 uv run --no-cache {skill-root}/scripts/setup.py --project-root {project-root} --skill {skill-root} --module-answers {module-answers-path}出错即停不留残余若发现或安装过程报告团队 TOML 畸形、manifest 冲突或无效、答案无效、声明的脚本不可读——必须指名出错来源并停止不尝试其他物化路径。setup 成功后只删除本次 setup 期间创建的实际临时答案路径包括写了模块答案时的{module-answers-path}。底层支撑manifest 解析与安全问题setup/doctor/update 三条命令共享同一套 manifest 解析管线parse_packaged_manifest见 setup.py其对输入的安全校验值得关注module 名称必须匹配[A-Za-z0-9][A-Za-z0-9_-]*且不能落入保留目录集{_config, custom, modules, scripts}大小写不敏感防止路径穿越与保留名冲突update_source必须是github:、https://、file:、plugin:前缀之一且前缀后非空github:要求 owner/repo/path 三段齐全https://不允许含空白config_questions每个问题必须且只能含key、prompt、default三个字符串字段key必须是非空点分 key 且不能以 module 名为前缀同一清单内互不冲突含前缀冲突见conflicting_question_keyscripts每个条目必须是相对路径、首段为scripts、至少两段、不含..、.或反斜杠且最终解析结果必须落在 skill 根目录之内read_declared_script用resolve(strictTrue)后做relative_to校验防符号链接逃逸多副本一致性discover_installed_modules要求同一 module 的多份 manifest 字节完全一致否则直接报冲突module id 仅大小写不同的情况也会被group_installed_copies拒绝。与配置模板及 manifest 的对应关系setup 物化的_bmad/config.toml源自 skills/bmad/assets/config.template.toml其结构展示了「模块配置 Agent 角色」的双层组织[core] project_name {directory_name} output_folder {project-root}/_bmad-output [modules.bmm] planning_artifacts {project-root}/_bmad-output/planning-artifacts implementation_artifacts {project-root}/_bmad-output/implementation-artifacts project_knowledge {project-root}/docs [agents.bmad-agent-analyst] module bmm team software-development name Mary title Business Analyst icon {directory_name}由 setup 在写盘前替换为项目目录名{project-root}作为字面量保留由后续的resolve_config.py解析。配置的合并层级可参考 skills/bmad/scripts/tests/test_config_utils.py 的验证_bmad/config.toml→_bmad/custom/config.toml→_bmad/custom/*.user.toml层层覆盖而_bmad/config.user.toml被明确视为经典安装器遗留物LEGACY_LEFTOVERS之一既不被写入也不参与合并——测试断言其中的stray键永远不会出现在最终配置里。而 bmad skill 自身的 skills/bmad/module-manifest.toml 正是被上述管线解析的典型 manifestmodule toolbox version 6.13.0-next update_source github:bmad-code-org/BMAD-METHOD/skills knowledge references/help.md in the bmad skill其module值为toolbox版本号为6.13.0-next含-next后缀属于不可排序的 dev 形态update_source采用github:前缀knowledge指向 skills/bmad/references/help.md 作为该模块的路由文档。常见故障与处置速查现象处置环境无uv停止执行告知用户安装uv不得改用其他方式写_bmaddoctor 报告setup-required先运行bmad setupdoctor 不自行补建运行时update 报告newer-available/version-spread按报告列出每份副本交由npx skills update更新已安装 skill 文件夹_bmad是符号链接用--project-root指向链接的真实目标目录执行 setup/doctor团队 TOML 畸形、manifest 冲突或答案无效指名出错来源并停止不尝试第二条修复路径doctor 的legacy_leftovers非空说明经典安装器遗留文件存在且未被触碰需要临时答案文件写入.bmad-help-setup-modules.toml冲突则换名结束后只删自己创建的临时文件三条命令的设计哲学一以贯之update 只观察、doctor 只修运行时、setup 才物化且每一步都通过 staging 目录、byte 级比对、严格 manifest 校验和「出错即停」来保证_bmad的可恢复性与安全性。理解这套生命周期管理是团队稳定运行 BMad 工作流、平滑升级 v6 及后续版本的基础。【免费下载链接】BMAD-METHODBreakthrough Method for Agile Ai Driven Development项目地址: https://gitcode.com/gh_mirrors/bm/BMAD-METHOD创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考