diff --git a/docs/_STYLE_GUIDE.md b/docs/_STYLE_GUIDE.md index 5256d2bf5..d23e93114 100644 --- a/docs/_STYLE_GUIDE.md +++ b/docs/_STYLE_GUIDE.md @@ -56,7 +56,7 @@ Critical warnings only — data loss, security issues | Phase | Name | What Happens | | ----- | -------- | -------------------------------------------- | | 1 | Analysis | Brainstorm, research *(optional)* | -| 2 | Planning | Requirements — PRD or tech-spec *(required)* | +| 2 | Planning | Requirements — PRD or spec *(required)* | ``` **Skills:** diff --git a/docs/explanation/established-projects-faq.md b/docs/explanation/established-projects-faq.md index fe217fcdd..9671dd171 100644 --- a/docs/explanation/established-projects-faq.md +++ b/docs/explanation/established-projects-faq.md @@ -34,7 +34,7 @@ Yes! Quick Flow works great for established projects. It will: - Auto-detect your existing stack - Analyze existing code patterns - Detect conventions and ask for confirmation -- Generate context-rich tech-spec that respects existing code +- Generate context-rich spec that respects existing code Perfect for bug fixes and small features in existing codebases. @@ -43,7 +43,7 @@ Perfect for bug fixes and small features in existing codebases. Quick Flow detects your conventions and asks: "Should I follow these existing conventions?" You decide: - **Yes** → Maintain consistency with current codebase -- **No** → Establish new standards (document why in tech-spec) +- **No** → Establish new standards (document why in spec) BMM respects your choice — it won't force modernization, but it will offer it. diff --git a/docs/explanation/project-context.md b/docs/explanation/project-context.md index 7b4eba4ed..b7cce90ff 100644 --- a/docs/explanation/project-context.md +++ b/docs/explanation/project-context.md @@ -25,7 +25,7 @@ Every implementation workflow automatically loads `project-context.md` if it exi - `bmad-create-story` — informs story creation with project patterns - `bmad-dev-story` — guides implementation decisions - `bmad-code-review` — validates against project standards -- `bmad-quick-dev` — applies patterns when implementing tech-specs +- `bmad-quick-dev` — applies patterns when implementing specs - `bmad-sprint-planning`, `bmad-retrospective`, `bmad-correct-course` — provides project-wide context ## When to Create It diff --git a/docs/fr/reference/workflow-map.md b/docs/fr/reference/workflow-map.md index a26106682..50821c6fd 100644 --- a/docs/fr/reference/workflow-map.md +++ b/docs/fr/reference/workflow-map.md @@ -68,7 +68,7 @@ Sautez les phases 1-3 pour les travaux de faible envergure et bien compris. | Workflow | Objectif | Produit | |------------------|-------------------------------------------------------------------------------------|-----------------------| -| `bmad-quick-dev` | Flux rapide unifié — clarifie l'intention, planifie, implémente, révise et présente | `tech-spec.md` + code | +| `bmad-quick-dev` | Flux rapide unifié — clarifie l'intention, planifie, implémente, révise et présente | `spec-*.md` + code | ## Gestion du Contexte diff --git a/docs/fr/tutorials/getting-started.md b/docs/fr/tutorials/getting-started.md index c0502f23a..70d6e3095 100644 --- a/docs/fr/tutorials/getting-started.md +++ b/docs/fr/tutorials/getting-started.md @@ -233,7 +233,7 @@ your-project/ ## Questions fréquentes **Ai-je toujours besoin d'une architecture ?** -Uniquement pour les voies méthode BMad et Enterprise. Quick Dev passe directement de la spécification technique (tech-spec) à l'implémentation. +Uniquement pour les voies méthode BMad et Enterprise. Quick Dev passe directement de la spécification technique (spec) à l'implémentation. **Puis-je modifier mon plan plus tard ?** Oui. Utilisez `bmad-correct-course` pour gérer les changements de périmètre. diff --git a/docs/reference/workflow-map.md b/docs/reference/workflow-map.md index 7fd4cae67..9f5e7e7ed 100644 --- a/docs/reference/workflow-map.md +++ b/docs/reference/workflow-map.md @@ -68,7 +68,7 @@ Skip phases 1-3 for small, well-understood work. | Workflow | Purpose | Produces | | ------------------ | --------------------------------------------------------------------------- | ---------------------- | -| `bmad-quick-dev` | Unified quick flow — clarify intent, plan, implement, review, and present | `tech-spec.md` + code | +| `bmad-quick-dev` | Unified quick flow — clarify intent, plan, implement, review, and present | `spec-*.md` + code | ## Context Management diff --git a/docs/tutorials/getting-started.md b/docs/tutorials/getting-started.md index ee68eb6ce..d6d1f08dd 100644 --- a/docs/tutorials/getting-started.md +++ b/docs/tutorials/getting-started.md @@ -69,7 +69,7 @@ BMad helps you build software through guided workflows with specialized AI agent | Phase | Name | What Happens | | ----- | -------------- | --------------------------------------------------- | | 1 | Analysis | Brainstorming, research, product brief *(optional)* | -| 2 | Planning | Create requirements (PRD or tech-spec) | +| 2 | Planning | Create requirements (PRD or spec) | | 3 | Solutioning | Design architecture *(BMad Method/Enterprise only)* | | 4 | Implementation | Build epic by epic, story by story | @@ -237,7 +237,7 @@ your-project/ ## Common Questions **Do I always need architecture?** -Only for BMad Method and Enterprise tracks. Quick Flow skips from tech-spec to implementation. +Only for BMad Method and Enterprise tracks. Quick Flow skips from spec to implementation. **Can I change my plan later?** Yes. The SM agent has a `bmad-correct-course` workflow (`bmad-correct-course`) for handling scope changes. diff --git a/docs/zh-cn/_STYLE_GUIDE.md b/docs/zh-cn/_STYLE_GUIDE.md index 53904e219..93d3c2739 100644 --- a/docs/zh-cn/_STYLE_GUIDE.md +++ b/docs/zh-cn/_STYLE_GUIDE.md @@ -56,7 +56,7 @@ Critical warnings only — data loss, security issues | Phase | Name | What Happens | | ----- | -------- | -------------------------------------------- | | 1 | Analysis | Brainstorm, research *(optional)* | -| 2 | Planning | Requirements — PRD or tech-spec *(required)* | +| 2 | Planning | Requirements — PRD or spec *(required)* | ``` **Commands:** diff --git a/docs/zh-cn/explanation/established-projects-faq.md b/docs/zh-cn/explanation/established-projects-faq.md index dcf89df2c..a182d8723 100644 --- a/docs/zh-cn/explanation/established-projects-faq.md +++ b/docs/zh-cn/explanation/established-projects-faq.md @@ -1,60 +1,62 @@ --- title: "既有项目常见问题" -description: 关于在既有项目上使用 BMad 方法的常见问题 +description: 关于在既有项目上使用 BMad Method 的常见问题 sidebar: order: 8 --- -关于使用 BMad 方法(BMM)在既有项目上工作的常见问题的快速解答。 +关于在 established projects(既有项目)中使用 BMad Method 的高频问题,快速说明如下。 ## 问题 -- [我必须先运行 document-project 吗?](#我必须先运行-document-project-吗) -- [如果我忘记运行 document-project 怎么办?](#如果我忘记运行-document-project-怎么办) -- [我可以在既有项目上使用快速流程吗?](#我可以在既有项目上使用快速流程吗) -- [如果我的现有代码不遵循最佳实践怎么办?](#如果我的现有代码不遵循最佳实践怎么办) +- [我必须先运行文档梳理工作流吗?](#我必须先运行文档梳理工作流吗) +- [如果我忘了运行文档梳理怎么办?](#如果我忘了运行文档梳理怎么办) +- [既有项目可以直接用 Quick Flow 吗?](#既有项目可以直接用-quick-flow-吗) +- [如果现有代码不符合最佳实践怎么办?](#如果现有代码不符合最佳实践怎么办) +- [什么时候该从 Quick Flow 切到完整方法?](#什么时候该从-quick-flow-切到完整方法) -### 我必须先运行 document-project 吗? +### 我必须先运行文档梳理工作流吗? -强烈推荐,特别是如果: +不绝对必须,但通常强烈建议先运行 `bmad-document-project`,尤其当: +- 项目文档缺失或明显过时 +- 新成员或智能体难以快速理解现有系统 +- 你希望后续 `workflow` 基于真实现状而不是猜测执行 -- 没有现有文档 -- 文档已过时 -- AI 智能体需要关于现有代码的上下文 +如果你已有完整且最新的文档(包含 `docs/index.md`),并且能通过其他方式提供足够上下文,也可以跳过。 -如果你拥有全面且最新的文档,包括 `docs/index.md`,或者将使用其他工具或技术来帮助智能体发现现有系统,则可以跳过此步骤。 +### 如果我忘了运行文档梳理怎么办? -### 如果我忘记运行 document-project 怎么办? +可以随时补跑,不影响你继续推进当前任务。很多团队会在迭代中期或里程碑后再运行一次,用来把“代码现状”回写到文档里。 -不用担心——你可以随时执行。你甚至可以在项目期间或项目之后执行,以帮助保持文档最新。 +### 既有项目可以直接用 Quick Flow 吗? -### 我可以在既有项目上使用快速流程吗? +可以。Quick Flow(例如 `bmad-quick-dev`)在既有项目里通常很高效,尤其适合: +- 小功能增量 +- 缺陷修复 +- 风险可控的局部改动 -可以!快速流程在既有项目上效果很好。它将: +它会尝试识别现有技术栈、代码模式和约定,并据此生成更贴近现状的实现方案。 -- 自动检测你的现有技术栈 -- 分析现有代码模式 -- 检测约定并请求确认 -- 生成尊重现有代码的上下文丰富的技术规范 +### 如果现有代码不符合最佳实践怎么办? -非常适合现有代码库中的错误修复和小功能。 +工作流会优先问你:“是否沿用当前约定?”你可以主动选择: +- **沿用**:优先保持一致性,降低短期改动风险 +- **升级**:建立新标准,并在 tech-spec 或架构中写明迁移理由与范围 -### 如果我的现有代码不遵循最佳实践怎么办? +BMad Method 不会强制“立即现代化”,而是把决策权交给你。 -快速流程会检测你的约定并询问:"我应该遵循这些现有约定吗?"你决定: +### 什么时候该从 Quick Flow 切到完整方法? -- **是** → 与当前代码库保持一致 -- **否** → 建立新标准(在技术规范中记录原因) +当任务出现以下信号时,建议从 Quick Flow 升级到完整 BMad Method: +- 改动跨多个 `epic` 或多个子系统 +- 需要明确 `architecture` 决策,否则容易冲突 +- 涉及较大协作面、较高回归风险或复杂验收要求 -BMM 尊重你的选择——它不会强制现代化,但会提供现代化选项。 +如果你不确定,先让 `bmad-help` 判断当前阶段更稳妥的 workflow。 -**有未在此处回答的问题吗?** 请[提出问题](https://github.com/bmad-code-org/BMAD-METHOD/issues)或在 [Discord](https://discord.gg/gk8jAdXWmj) 中提问,以便我们添加它! +**还有问题?** 欢迎在 [GitHub Issues](https://github.com/bmad-code-org/BMAD-METHOD/issues) 或 [Discord](https://discord.gg/gk8jAdXWmj) 提问。 ---- -## 术语说明 +## 继续阅读 -- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。 -- **Quick Flow**:快速流程。BMad 方法中的一种工作流程,用于快速处理既有项目。 -- **tech-spec**:技术规范。描述技术实现细节和标准的文档。 -- **stack**:技术栈。项目所使用的技术组合,包括框架、库、工具等。 -- **conventions**:约定。代码库中遵循的编码风格、命名规则等规范。 -- **modernization**:现代化。将旧代码或系统更新为更现代的技术和最佳实践的过程。 +- [既有项目(How-to)](../how-to/established-projects.md) +- [项目上下文(Explanation)](./project-context.md) +- [管理项目上下文(How-to)](../how-to/project-context.md) diff --git a/docs/zh-cn/explanation/preventing-agent-conflicts.md b/docs/zh-cn/explanation/preventing-agent-conflicts.md index c3f24faf6..b8cd4a083 100644 --- a/docs/zh-cn/explanation/preventing-agent-conflicts.md +++ b/docs/zh-cn/explanation/preventing-agent-conflicts.md @@ -5,133 +5,112 @@ sidebar: order: 4 --- -当多个 AI 智能体实现系统的不同部分时,它们可能会做出相互冲突的技术决策。架构文档通过建立共享标准来防止这种情况。 +当多个 AI 智能体并行实现系统时,冲突并不罕见。`architecture` 的作用,就是在 `solutioning` 阶段先统一关键决策,避免到 `epic/story` 实施时才暴露分歧。 -## 常见冲突类型 +## 冲突最常出现在哪些地方 ### API 风格冲突 -没有架构时: -- 智能体 A 使用 REST,路径为 `/users/{id}` +没有架构约束时: +- 智能体 A 使用 REST,路径是 `/users/{id}` - 智能体 B 使用 GraphQL mutations -- 结果:API 模式不一致,消费者困惑 +- 结果:接口模式不一致,调用方和集成层都变复杂 -有架构时: -- ADR 指定:"所有客户端-服务器通信使用 GraphQL" -- 所有智能体遵循相同的模式 +有架构约束时: +- ADR 明确规定:“客户端与服务端统一使用 GraphQL” +- 所有智能体遵循同一套 API 规则 -### 数据库设计冲突 +### 数据库与命名冲突 -没有架构时: -- 智能体 A 使用 snake_case 列名 -- 智能体 B 使用 camelCase 列名 -- 结果:模式不一致,查询混乱 +没有架构约束时: +- 智能体 A 使用 `snake_case` 列名 +- 智能体 B 使用 `camelCase` 列名 +- 结果:schema 不一致,查询与迁移成本上升 -有架构时: -- 标准文档指定命名约定 -- 所有智能体遵循相同的模式 +有架构约束时: +- 标准文档统一命名约定和迁移策略 +- 所有智能体按同一模式实现 ### 状态管理冲突 -没有架构时: -- 智能体 A 使用 Redux 管理全局状态 +没有架构约束时: +- 智能体 A 使用 Redux - 智能体 B 使用 React Context -- 结果:多种状态管理方法,复杂度增加 +- 结果:状态层碎片化,维护复杂度增加 -有架构时: -- ADR 指定状态管理方法 -- 所有智能体一致实现 +有架构约束时: +- ADR 明确状态管理方案 +- 不同 `story` 的实现保持一致 -## 架构如何防止冲突 +## architecture 如何前置消解冲突 -### 1. 通过 ADR 明确决策 +### 1. 用 ADR 固化关键决策 -每个重要的技术选择都记录以下内容: -- 上下文(为什么这个决策很重要) -- 考虑的选项(有哪些替代方案) -- 决策(我们选择了什么) -- 理由(为什么选择它) -- 后果(接受的权衡) +每个关键技术选择都至少包含: +- 背景(为什么要做这个决策) +- 备选方案(有哪些选择) +- 最终决策(采用什么) +- 理由(为什么这样选) +- 后果(接受哪些权衡) -### 2. FR/NFR 特定指导 +### 2. 把 FR/NFR 映射到技术实现 -架构将每个功能需求映射到技术方法: -- FR-001:用户管理 → GraphQL mutations -- FR-002:移动应用 → 优化查询 +`architecture` 不是抽象原则清单,而是把需求落到可执行方案: +- FR-001(用户管理)→ GraphQL mutations +- FR-002(移动端性能)→ 查询裁剪与缓存策略 -### 3. 标准和约定 +### 3. 统一基础约定 -明确记录以下内容: +至少覆盖以下共识: - 目录结构 - 命名约定 -- 代码组织 -- 测试模式 +- 代码组织方式 +- 测试策略 -## 架构作为共享上下文 +## architecture 是所有 epic 的共享上下文 -将架构视为所有智能体在实现之前阅读的共享上下文: +把架构文档看作每个智能体在实施前都要阅读的“公共协议”: ```text -PRD:"构建什么" +PRD: "做什么" ↓ -架构:"如何构建" +architecture: "如何做" ↓ -智能体 A 阅读架构 → 实现 Epic 1 -智能体 B 阅读架构 → 实现 Epic 2 -智能体 C 阅读架构 → 实现 Epic 3 +智能体 A 读 architecture → 实现 Epic 1 +智能体 B 读 architecture → 实现 Epic 2 +智能体 C 读 architecture → 实现 Epic 3 ↓ -结果:一致的实现 +结果:实现一致、集成顺畅 ``` -## Key ADR Topics +## 优先写清的 ADR 主题 -防止冲突的常见决策: - -| Topic | Example Decision | +| 主题 | 示例决策 | | ---------------- | -------------------------------------------- | -| API Style | GraphQL vs REST vs gRPC | -| Database | PostgreSQL vs MongoDB | -| Auth | JWT vs Sessions | -| State Management | Redux vs Context vs Zustand | -| Styling | CSS Modules vs Tailwind vs Styled Components | -| Testing | Jest + Playwright vs Vitest + Cypress | +| API 风格 | GraphQL vs REST vs gRPC | +| 数据存储 | PostgreSQL vs MongoDB | +| 认证机制 | JWT vs Session | +| 状态管理 | Redux vs Context vs Zustand | +| 样式方案 | CSS Modules vs Tailwind vs Styled Components | +| 测试体系 | Jest + Playwright vs Vitest + Cypress | -## 避免的反模式 +## 常见误区 :::caution[常见错误] -- **隐式决策** — "我们边做边确定 API 风格"会导致不一致 -- **过度文档化** — 记录每个次要选择会导致分析瘫痪 -- **过时架构** — 文档写一次后从不更新,导致智能体遵循过时的模式 +- **隐式决策**:边写边定规则,最终通常会分叉 +- **过度文档化**:把每个小选择都写 ADR,造成分析瘫痪 +- **架构陈旧**:文档不更新,智能体继续按过时规则实现 ::: -:::tip[正确方法] -- 记录跨越 epic 边界的决策 -- 专注于容易产生冲突的领域 -- 随着学习更新架构 -- 对重大变更使用 `correct-course` +:::tip[更稳妥的做法] +- 先记录跨 `epic`、高冲突概率的决策 +- 把精力放在“会影响多个 story 的规则” +- 随着项目演进持续更新架构文档 +- 出现重大偏移时使用 `bmad-correct-course` ::: ---- -## 术语说明 +## 继续阅读 -- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。 -- **ADR**:架构决策记录(Architecture Decision Record)。用于记录重要架构决策及其背景、选项和后果的文档。 -- **FR**:功能需求(Functional Requirement)。系统必须具备的功能或行为。 -- **NFR**:非功能需求(Non-Functional Requirement)。系统性能、安全性、可扩展性等质量属性。 -- **Epic**:史诗。大型功能或用户故事的集合,通常需要多个迭代完成。 -- **snake_case**:蛇形命名法。单词之间用下划线连接,所有字母小写的命名风格。 -- **camelCase**:驼峰命名法。除第一个单词外,每个单词首字母大写的命名风格。 -- **GraphQL mutations**:GraphQL 变更操作。用于修改服务器数据的 GraphQL 操作类型。 -- **Redux**:JavaScript 状态管理库。用于管理应用全局状态的可预测状态容器。 -- **React Context**:React 上下文 API。用于在组件树中传递数据而无需逐层传递 props。 -- **Zustand**:轻量级状态管理库。用于 React 应用的简单状态管理解决方案。 -- **CSS Modules**:CSS 模块。将 CSS 作用域限制在组件内的技术。 -- **Tailwind**:Tailwind CSS。实用优先的 CSS 框架。 -- **Styled Components**:样式化组件。使用 JavaScript 编写样式的 React 库。 -- **Jest**:JavaScript 测试框架。用于编写和运行测试的工具。 -- **Playwright**:端到端测试框架。用于自动化浏览器测试的工具。 -- **Vitest**:Vite 原生测试框架。快速且轻量的单元测试工具。 -- **Cypress**:端到端测试框架。用于 Web 应用测试的工具。 -- **gRPC**:远程过程调用框架。Google 开发的高性能 RPC 框架。 -- **JWT**:JSON Web Token。用于身份验证的开放标准令牌。 -- **PRD**:产品需求文档(Product Requirements Document)。描述产品功能、需求和目标的文档。 +- [为什么解决方案阶段很重要](./why-solutioning-matters.md) +- [项目上下文](./project-context.md) +- [工作流地图](../reference/workflow-map.md) diff --git a/docs/zh-cn/explanation/project-context.md b/docs/zh-cn/explanation/project-context.md index d43105ea6..7886e4c0c 100644 --- a/docs/zh-cn/explanation/project-context.md +++ b/docs/zh-cn/explanation/project-context.md @@ -1,55 +1,51 @@ --- title: "项目上下文" -description: project-context.md 如何使用项目的规则和偏好指导 AI 智能体 +description: project-context.md 如何使用项目规则和偏好指导 AI 智能体 sidebar: order: 7 --- -`project-context.md` 文件是您的项目面向 AI 智能体的实施指南。类似于其他开发系统中的"宪法",它记录了确保所有工作流中代码生成一致的规则、模式和偏好。 +`project-context.md` 是面向 AI 智能体的项目级上下文文件。它的定位不是教程步骤,而是“实现约束说明”:把你的技术偏好、架构边界和工程约定沉淀成可复用规则,让不同工作流、不同智能体在多个 `story` 中做出一致决策。 -## 它的作用 +## project context 解决什么问题 -AI 智能体不断做出实施决策——遵循哪些模式、如何组织代码、使用哪些约定。如果没有明确指导,它们可能会: -- 遵循与您的代码库不匹配的通用最佳实践 -- 在不同的用户故事中做出不一致的决策 -- 错过项目特定的需求或约束 +没有统一上下文时,智能体往往会: +- 套用通用最佳实践,而不是你的项目约定 +- 在不同 `story` 中做出不一致实现 +- 漏掉代码里不易推断的隐性约束 -`project-context.md` 文件通过以简洁、针对 LLM 优化的格式记录智能体需要了解的内容来解决这个问题。 +有 `project-context.md` 时,这些高频偏差会明显减少,因为关键规则在进入实现前已经被显式声明。 -## 它的工作原理 +## 它如何被工作流使用 -每个实施工作流都会自动加载 `project-context.md`(如果存在)。架构师工作流也会加载它,以便在设计架构时尊重您的技术偏好。 +多数实现相关工作流会自动加载 `project-context.md`(若存在),并把它作为共享上下文参与决策。 -**由以下工作流加载:** -- `create-architecture` — 在解决方案设计期间尊重技术偏好 -- `create-story` — 使用项目模式指导用户故事创建 -- `dev-story` — 指导实施决策 -- `code-review` — 根据项目标准进行验证 -- `quick-dev` — 在实施技术规范时应用模式 -- `sprint-planning`、`retrospective`、`correct-course` — 提供项目范围的上下文 +**常见加载方包括:** +- `bmad-create-architecture`:在 solutioning 时纳入你的技术偏好 +- `bmad-create-story`:按项目约定拆分和描述 story +- `bmad-dev-story`:约束实现路径和代码风格 +- `bmad-code-review`:按项目标准做一致性校验 +- `bmad-quick-dev`:在快速实现中避免偏离既有模式 +- `bmad-sprint-planning`、`bmad-retrospective`、`bmad-correct-course`:读取项目级背景 -## 何时创建 +## 什么时候建立或更新 -`project-context.md` 文件在项目的任何阶段都很有用: - -| 场景 | 何时创建 | 目的 | +| 场景 | 建议时机 | 目标 | |----------|----------------|---------| -| **新项目,架构之前** | 手动,在 `create-architecture` 之前 | 记录您的技术偏好,以便架构师尊重它们 | -| **新项目,架构之后** | 通过 `generate-project-context` 或手动 | 捕获架构决策,供实施智能体使用 | -| **现有项目** | 通过 `generate-project-context` | 发现现有模式,以便智能体遵循既定约定 | -| **快速流程项目** | 在 `quick-dev` 之前或期间 | 确保快速实施尊重您的模式 | +| **新项目(架构前)** | 在 `bmad-create-architecture` 前手动创建 | 先声明技术偏好,避免架构偏航 | +| **新项目(架构后)** | 通过 `bmad-generate-project-context` 生成并补充 | 把架构决策转成可执行规则 | +| **既有项目** | 先生成,再人工校对 | 让智能体学习现有约定而非重造体系 | +| **Quick Flow 场景** | 在 `bmad-quick-dev` 前或过程中维护 | 弥补跳过完整规划带来的上下文缺口 | -:::tip[推荐] -对于新项目,如果您有强烈的技术偏好,请在架构之前手动创建。否则,在架构之后生成它以捕获这些决策。 +:::tip[推荐做法] +如果你有强技术偏好(例如数据库、状态管理、目录规范),尽量在架构前写入。否则可在架构后生成,再按项目现实补齐。 ::: -## 文件内容 +## 应该写哪些内容 -该文件有两个主要部分: +建议聚焦两类信息:**技术栈与版本**、**关键实现规则**。原则是记录“智能体不容易从代码片段直接推断”的内容。 -### 技术栈与版本 - -记录项目使用的框架、语言和工具及其具体版本: +### 1. 技术栈与版本 ```markdown ## Technology Stack & Versions @@ -60,9 +56,7 @@ AI 智能体不断做出实施决策——遵循哪些模式、如何组织代 - Styling: Tailwind CSS with custom design tokens ``` -### 关键实施规则 - -记录智能体可能忽略的模式和约定: +### 2. 关键实现规则 ```markdown ## Critical Implementation Rules @@ -73,104 +67,28 @@ AI 智能体不断做出实施决策——遵循哪些模式、如何组织代 **Code Organization:** - Components in `/src/components/` with co-located `.test.tsx` -- Utilities in `/src/lib/` for reusable pure functions - API calls use the `apiClient` singleton — never fetch directly **Testing Patterns:** -- Unit tests focus on business logic, not implementation details - Integration tests use MSW to mock API responses - E2E tests cover critical user journeys only - -**Framework-Specific:** -- All async operations use the `handleError` wrapper for consistent error handling -- Feature flags accessed via `featureFlag()` from `@/lib/flags` -- New routes follow the file-based routing pattern in `/src/app/` ``` -专注于那些**不明显**的内容——智能体可能无法从阅读代码片段中推断出来的内容。不要记录普遍适用的标准实践。 +## 常见误解 -## 创建文件 +- **误解 1:它是操作手册。** + 不是。操作步骤请看 how-to;这里强调的是规则与边界。 +- **误解 2:写得越全越好。** + 不对。冗长且泛化的“最佳实践”会稀释有效约束。 +- **误解 3:写一次就结束。** + 这是动态文件。架构变化、约定变化后要同步更新。 -您有三个选择: +## 文件位置 -### 手动创建 +默认位置是 `_bmad-output/project-context.md`。工作流优先在该位置查找,也会扫描项目内的 `**/project-context.md`。 -在 `_bmad-output/project-context.md` 创建文件并添加您的规则: +## 继续阅读 -```bash -# In your project root -mkdir -p _bmad-output -touch _bmad-output/project-context.md -``` - -使用您的技术栈和实施规则编辑它。架构师和实施工作流将自动查找并加载它。 - -### 架构后生成 - -在完成架构后运行 `generate-project-context` 工作流: - -```bash -/bmad-bmm-generate-project-context -``` - -这将扫描您的架构文档和项目文件,生成一个捕获所做决策的上下文文件。 - -### 为现有项目生成 - -对于现有项目,运行 `generate-project-context` 以发现现有模式: - -```bash -/bmad-bmm-generate-project-context -``` - -该工作流分析您的代码库以识别约定,然后生成一个您可以审查和优化的上下文文件。 - -## 为什么重要 - -没有 `project-context.md`,智能体会做出可能与您的项目不匹配的假设: - -| 没有上下文 | 有上下文 | -|----------------|--------------| -| 使用通用模式 | 遵循您的既定约定 | -| 用户故事之间风格不一致 | 实施一致 | -| 可能错过项目特定的约束 | 尊重所有技术需求 | -| 每个智能体独立决策 | 所有智能体遵循相同规则 | - -这对于以下情况尤其重要: -- **快速流程** — 跳过 PRD 和架构,因此上下文文件填补了空白 -- **团队项目** — 确保所有智能体遵循相同的标准 -- **现有项目** — 防止破坏既定模式 - -## 编辑和更新 - -`project-context.md` 文件是一个动态文档。在以下情况下更新它: - -- 架构决策发生变化 -- 建立了新的约定 -- 模式在实施过程中演变 -- 您从智能体行为中发现差距 - -您可以随时手动编辑它,或者在重大更改后重新运行 `generate-project-context` 来更新它。 - -:::note[文件位置] -默认位置是 `_bmad-output/project-context.md`。工作流在那里搜索它,并且还会检查项目中任何位置的 `**/project-context.md`。 -::: - ---- -## 术语说明 - -- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。 -- **workflow**:工作流。指一系列自动化或半自动化的任务流程。 -- **PRD**:产品需求文档(Product Requirements Document)。描述产品功能、需求和目标的文档。 -- **LLM**:大语言模型(Large Language Model)。指基于深度学习的自然语言处理模型。 -- **singleton**:单例。一种设计模式,确保一个类只有一个实例。 -- **E2E**:端到端(End-to-End)。指从用户角度出发的完整测试流程。 -- **MSW**:Mock Service Worker。用于模拟 API 响应的库。 -- **Vitest**:基于 Vite 的单元测试框架。 -- **Playwright**:端到端测试框架。 -- **Zustand**:轻量级状态管理库。 -- **Redux**:JavaScript 应用状态管理库。 -- **Tailwind CSS**:实用优先的 CSS 框架。 -- **TypeScript**:JavaScript 的超集,添加了静态类型。 -- **React**:用于构建用户界面的 JavaScript 库。 -- **Node.js**:基于 Chrome V8 引擎的 JavaScript 运行时。 +- [管理项目上下文(How-to)](../how-to/project-context.md) +- [既有项目常见问题](./established-projects-faq.md) +- [工作流地图](../reference/workflow-map.md) diff --git a/docs/zh-cn/explanation/why-solutioning-matters.md b/docs/zh-cn/explanation/why-solutioning-matters.md index 27e8f96ca..2a598f2dc 100644 --- a/docs/zh-cn/explanation/why-solutioning-matters.md +++ b/docs/zh-cn/explanation/why-solutioning-matters.md @@ -5,54 +5,53 @@ sidebar: order: 3 --- +Phase 3(solutioning)把“要做什么”(planning 产出)转成“如何实现”(`architecture` 设计 + 工作拆分)。它的核心价值是:在开发前先把跨 `epic` 的关键技术决策写清楚,让后续 `story` 实施保持一致。 -阶段 3(解决方案)将构建**什么**(来自规划)转化为**如何**构建(技术设计)。该阶段通过在实施开始前记录架构决策,防止多史诗项目中的智能体冲突。 - -## 没有解决方案阶段的问题 +## 不做 solutioning 会出现什么问题 ```text -智能体 1 使用 REST API 实现史诗 1 -智能体 2 使用 GraphQL 实现史诗 2 -结果:API 设计不一致,集成噩梦 +智能体 1 使用 REST API 实现 Epic 1 +智能体 2 使用 GraphQL 实现 Epic 2 +结果:API 设计不一致,集成成本暴涨 ``` -当多个智能体在没有共享架构指导的情况下实现系统的不同部分时,它们会做出可能冲突的独立技术决策。 +当多个智能体在没有共享 `architecture` 指南的前提下并行实现不同 `epic`,它们会各自做局部最优决策,最后在集成阶段发生冲突。 -## 有解决方案阶段的解决方案 +## 做了 solutioning 后会发生什么 ```text -架构工作流决定:"所有 API 使用 GraphQL" -所有智能体遵循架构决策 -结果:实现一致,无冲突 +architecture 工作流先定规则:"所有 API 使用 GraphQL" +所有智能体按同一套决策实现 story +结果:实现一致,集成顺滑 ``` -通过明确记录技术决策,所有智能体都能一致地实现,集成变得简单直接。 +solutioning 的本质不是“多写一份文档”,而是把高冲突风险决策前置,作为所有 `story` 的共享上下文。 -## 解决方案阶段 vs 规划阶段 +## solutioning 与 planning 的边界 -| 方面 | 规划(阶段 2) | 解决方案(阶段 3) | +| 方面 | Planning(阶段 2) | Solutioning(阶段 3) | | -------- | ----------------------- | --------------------------------- | -| 问题 | 做什么和为什么? | 如何做?然后是什么工作单元? | -| 输出 | FRs/NFRs(需求) | 架构 + 史诗/用户故事 | -| 智能体 | PM | 架构师 → PM | +| 核心问题 | 做什么,为什么做? | 如何做,再如何拆分工作? | +| 输出物 | FRs/NFRs(需求) | `architecture` + `epic/story` 拆分 | +| 主导角色 | PM | Architect → PM | | 受众 | 利益相关者 | 开发人员 | -| 文档 | PRD(FRs/NFRs) | 架构 + 史诗文件 | -| 层级 | 业务逻辑 | 技术设计 + 工作分解 | +| 文档 | PRD(FRs/NFRs) | 架构文档 + epics 文件 | +| 决策层级 | 业务目标与范围 | 技术策略与实现边界 | ## 核心原则 -**使技术决策明确且有文档记录**,以便所有智能体一致地实现。 +**让跨 `epic` 的关键技术决策显式、可追溯、可复用。** -这可以防止: +这能直接降低: - API 风格冲突(REST vs GraphQL) -- 数据库设计不一致 -- 状态管理分歧 -- 命名约定不匹配 -- 安全方法差异 +- 数据模型与命名约定不一致 +- 状态管理方案分裂 +- 安全策略分叉 +- 中后期返工成本 -## 何时需要解决方案阶段 +## 什么时候需要 solutioning -| 流程 | 需要解决方案阶段? | +| 流程 | 需要 solutioning? | |-------|----------------------| | Quick Flow | 否 - 完全跳过 | | BMad Method Simple | 可选 | @@ -60,31 +59,24 @@ sidebar: | Enterprise | 是 | :::tip[经验法则] -如果你有多个可能由不同智能体实现的史诗,你需要解决方案阶段。 +只要需求会拆成多个 `epic`,并且可能由不同智能体并行实现,就应该做 solutioning。 ::: -## 跳过的代价 +## 跳过 solutioning 的代价 -在复杂项目中跳过解决方案阶段会导致: +在复杂项目中跳过该阶段,常见后果是: -- **集成问题**在冲刺中期发现 -- **返工**由于实现冲突 -- **开发时间更长**整体 -- **技术债务**来自不一致模式 +- **集成问题**在冲刺中期暴露 +- **返工**由实现冲突引发 +- **整体研发周期拉长** +- **技术债务**因模式不一致持续累积 :::caution[成本倍增] -在解决方案阶段发现对齐问题比在实施期间发现要快 10 倍。 +在 solutioning 阶段发现对齐问题,通常比在实施中后期才发现更快、更便宜。 ::: ---- -## 术语说明 +## 继续阅读 -- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。 -- **epic**:史诗。在敏捷开发中,指一个大型的工作项,可分解为多个用户故事。 -- **REST API**:表述性状态传递应用程序接口。一种基于 HTTP 协议的 Web API 设计风格。 -- **GraphQL**:一种用于 API 的查询语言和运行时环境。 -- **FRs/NFRs**:功能需求/非功能需求。Functional Requirements/Non-Functional Requirements 的缩写。 -- **PRD**:产品需求文档。Product Requirements Document 的缩写。 -- **PM**:产品经理。Product Manager 的缩写。 -- **sprint**:冲刺。敏捷开发中的固定时间周期,通常为 1-4 周。 -- **technical debt**:技术债务。指为了短期目标而选择的不完美技术方案,未来需要付出额外成本来修复。 +- [防止智能体冲突](./preventing-agent-conflicts.md) +- [项目上下文](./project-context.md) +- [工作流地图](../reference/workflow-map.md) diff --git a/docs/zh-cn/how-to/customize-bmad.md b/docs/zh-cn/how-to/customize-bmad.md index 5ed2d44c3..72afcd2bc 100644 --- a/docs/zh-cn/how-to/customize-bmad.md +++ b/docs/zh-cn/how-to/customize-bmad.md @@ -5,56 +5,56 @@ sidebar: order: 7 --- -使用 `.customize.yaml` 文件来调整智能体行为、角色和菜单,同时在更新过程中保留您的更改。 +使用 `.customize.yaml` 文件,自定义智能体(agent)的行为、角色(persona)和菜单,同时在后续更新中保留你的改动。 ## 何时使用此功能 -- 您想要更改智能体的名称、个性或沟通风格 -- 您需要智能体记住项目特定的上下文 -- 您想要添加自定义菜单项来触发您自己的工作流或提示 -- 您希望智能体在每次启动时执行特定操作 +- 你想修改智能体名称、身份设定或沟通风格 +- 你需要让智能体长期记住项目约束和背景信息 +- 你希望增加自定义菜单项,触发自己的工作流或提示 +- 你希望智能体每次启动都先执行固定动作 :::note[前置条件] -- 在项目中安装了 BMad(参见[如何安装 BMad](./install-bmad.md)) +- 已在项目中安装 BMad(参见[如何安装 BMad](./install-bmad.md)) - 用于编辑 YAML 文件的文本编辑器 ::: :::caution[保护您的自定义配置] -始终使用此处描述的 `.customize.yaml` 文件,而不是直接编辑智能体文件。安装程序在更新期间会覆盖智能体文件,但会保留您的 `.customize.yaml` 更改。 +始终通过 `.customize.yaml` 自定义,不要直接改动智能体源文件。安装程序在更新时会覆盖智能体文件,但会保留 `.customize.yaml` 的内容。 ::: ## 步骤 ### 1. 定位自定义文件 -安装后,在以下位置为每个智能体找到一个 `.customize.yaml` 文件: +安装完成后,每个已安装智能体都会在下面目录生成一个 `.customize.yaml`: ```text _bmad/_config/agents/ ├── core-bmad-master.customize.yaml ├── bmm-dev.customize.yaml ├── bmm-pm.customize.yaml -└── ...(每个已安装的智能体一个文件) +└── ...(每个已安装智能体一个文件) ``` ### 2. 编辑自定义文件 -打开您想要修改的智能体的 `.customize.yaml` 文件。每个部分都是可选的——只自定义您需要的内容。 +打开目标智能体的 `.customize.yaml`。各段都可选,只改你需要的部分即可。 -| 部分 | 行为 | 用途 | +| 部分 | 作用方式 | 用途 | | ------------------ | -------- | ---------------------------------------------- | -| `agent.metadata` | 替换 | 覆盖智能体的显示名称 | -| `persona` | 替换 | 设置角色、身份、风格和原则 | -| `memories` | 追加 | 添加智能体始终会记住的持久上下文 | -| `menu` | 追加 | 为工作流或提示添加自定义菜单项 | -| `critical_actions` | 追加 | 定义智能体的启动指令 | -| `prompts` | 追加 | 创建可重复使用的提示供菜单操作使用 | +| `agent.metadata` | 覆盖 | 覆盖智能体显示名称 | +| `persona` | 覆盖 | 设置角色、身份、风格和原则 | +| `memories` | 追加 | 添加智能体长期记忆的上下文 | +| `menu` | 追加 | 增加指向工作流或提示的菜单项 | +| `critical_actions` | 追加 | 定义智能体启动时要执行的动作 | +| `prompts` | 追加 | 创建可复用提示,供菜单 `action` 引用 | -标记为 **替换** 的部分会完全覆盖智能体的默认设置。标记为 **追加** 的部分会添加到现有配置中。 +标记为 **覆盖** 的部分会完全替换默认配置;标记为 **追加** 的部分会在默认配置基础上累加。 -**智能体名称** +**智能体名称(`agent.metadata`)** -更改智能体的自我介绍方式: +修改智能体的显示名称: ```yaml agent: @@ -62,9 +62,9 @@ agent: name: 'Spongebob' # 默认值:"Amelia" ``` -**角色** +**角色(`persona`)** -替换智能体的个性、角色和沟通风格: +替换智能体的人设、职责和沟通风格: ```yaml persona: @@ -76,11 +76,11 @@ persona: - 'Favor composition over inheritance' ``` -`persona` 部分会替换整个默认角色,因此如果您设置它,请包含所有四个字段。 +`persona` 会覆盖默认整段配置,所以启用时请把四个字段都填全。 -**记忆** +**记忆(`memories`)** -添加智能体将始终记住的持久上下文: +添加智能体会长期记住的上下文: ```yaml memories: @@ -89,9 +89,9 @@ memories: - 'Learned in Epic 1 that it is not cool to just pretend that tests have passed' ``` -**菜单项** +**菜单项(`menu`)** -向智能体的显示菜单添加自定义条目。每个条目需要一个 `trigger`、一个目标(`workflow` 路径或 `action` 引用)和一个 `description`: +给智能体菜单添加自定义项。每个条目都需要 `trigger`、目标(`workflow` 路径或 `action` 引用)和 `description`: ```yaml menu: @@ -103,18 +103,18 @@ menu: description: Deploy to production ``` -**关键操作** +**启动关键动作(`critical_actions`)** -定义智能体启动时运行的指令: +定义智能体启动时执行的指令: ```yaml critical_actions: - 'Check the CI Pipelines with the XYZ Skill and alert user on wake if anything is urgently needing attention' ``` -**自定义提示** +**可复用提示(`prompts`)** -创建可重复使用的提示,菜单项可以通过 `action="#id"` 引用: +创建可复用提示,菜单项可通过 `action="#id"` 调用: ```yaml prompts: @@ -126,56 +126,51 @@ prompts: 3. Execute deployment script ``` -### 3. 应用您的更改 +### 3. 应用更改 -编辑后,重新安装以应用更改: +编辑完成后,重新安装以应用配置: ```bash npx bmad-method install ``` -安装程序会检测现有安装并提供以下选项: +安装程序会识别现有安装,并给出以下选项: -| Option | What It Does | +| 选项 | 作用 | | ---------------------------- | ------------------------------------------------------------------- | -| **Quick Update** | 将所有模块更新到最新版本并应用自定义配置 | -| **Modify BMad Installation** | 用于添加或删除模块的完整安装流程 | +| **Quick Update** | 更新所有模块到最新版本,并应用你的自定义配置 | +| **Modify BMad Installation** | 进入完整安装流程,用于增删模块 | -对于仅自定义配置的更改,**Quick Update** 是最快的选项。 +如果只是调整 `.customize.yaml`,优先选 **Quick Update**。 -## 故障排除 +## 故障排查 -**更改未生效?** +**改动没有生效?** - 运行 `npx bmad-method install` 并选择 **Quick Update** 以应用更改 -- 检查您的 YAML 语法是否有效(缩进很重要) -- 验证您编辑的是该智能体正确的 `.customize.yaml` 文件 +- 检查 YAML 语法是否正确(尤其是缩进) +- 确认你编辑的是目标智能体对应的 `.customize.yaml` **智能体无法加载?** - 使用在线 YAML 验证器检查 YAML 语法错误 -- 确保在取消注释后没有留下空字段 -- 尝试恢复到原始模板并重新构建 +- 确保取消注释后没有遗留空字段 +- 可先回退到模板,再逐项恢复自定义配置 -**需要重置智能体?** +**需要重置某个智能体?** - 清空或删除智能体的 `.customize.yaml` 文件 - 运行 `npx bmad-method install` 并选择 **Quick Update** 以恢复默认设置 ## 工作流自定义 -对现有 BMad Method 工作流和技能的自定义即将推出。 +对现有 BMad Method 工作流和技能的深度自定义能力即将推出。 ## 模块自定义 关于构建扩展模块和自定义现有模块的指南即将推出。 ---- -## 术语说明 +## 后续步骤 -- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。 -- **workflow**:工作流。指一系列有序的任务或步骤,用于完成特定目标。 -- **persona**:角色。指智能体的身份、个性、沟通风格和行为原则的集合。 -- **memory**:记忆。指智能体持久存储的上下文信息,用于在对话中保持连贯性。 -- **critical action**:关键操作。指智能体启动时必须执行的指令或任务。 -- **prompt**:提示。指发送给智能体的输入文本,用于引导其生成特定响应或执行特定操作。 +- [文档分片指南](./shard-large-documents.md) - 了解如何管理超长文档 +- [命令参考](../reference/commands.md) - 查看可用命令和工作流入口 diff --git a/docs/zh-cn/how-to/shard-large-documents.md b/docs/zh-cn/how-to/shard-large-documents.md index 759069813..0b394e502 100644 --- a/docs/zh-cn/how-to/shard-large-documents.md +++ b/docs/zh-cn/how-to/shard-large-documents.md @@ -5,19 +5,21 @@ sidebar: order: 9 --- -如果需要将大型 Markdown 文件拆分为更小、组织良好的文件以更好地管理上下文,请使用 `shard-doc` 工具。 +当单个 Markdown 文档过大、影响模型读取时,可使用 `bmad-shard-doc` 工作流把文档拆成按章节组织的小文件,降低上下文压力。 :::caution[已弃用] -不再推荐使用此方法,随着工作流程的更新以及大多数主要 LLM 和工具支持子进程,这很快将变得不再必要。 +这是兼容性方案,默认不推荐。随着工作流更新,以及主流模型/工具逐步支持子进程(subprocesses),很多场景将不再需要手动分片。 ::: ## 何时使用 -仅当你发现所选工具/模型组合无法在需要时加载和读取所有文档作为输入时,才使用此方法。 +- 你确认当前工具/模型在关键步骤无法一次读入完整文档 +- 文档体量已明显影响工作流稳定性或响应质量 +- 你需要保留原文结构,但希望按 `##` 章节拆分维护 ## 什么是文档分片? -文档分片根据二级标题(`## Heading`)将大型 Markdown 文件拆分为更小、组织良好的文件。 +文档分片会按二级标题(`## Heading`)把大型 Markdown 文件拆成多个子文件,并生成一个 `index.md` 作为入口。 ### 架构 @@ -38,16 +40,16 @@ _bmad-output/planning-artifacts/ ## 步骤 -### 1. 运行 Shard-Doc 工具 +### 1. 运行 `bmad-shard-doc` 工作流 ```bash /bmad-shard-doc ``` -### 2. 遵循交互式流程 +### 2. 按交互流程完成分片 ```text -智能体:您想要分片哪个文档? +智能体:你想分片哪个文档? 用户:docs/PRD.md 智能体:默认目标位置:docs/prd/ @@ -60,27 +62,21 @@ _bmad-output/planning-artifacts/ ✓ 完成! ``` -## 工作流程发现机制 +## 工作流发现机制 -BMad 工作流程使用**双重发现系统**: +BMad 工作流使用**双重发现机制**: -1. **首先尝试完整文档** - 查找 `document-name.md` -2. **检查分片版本** - 查找 `document-name/index.md` -3. **优先级规则** - 如果两者都存在,完整文档优先 - 如果希望使用分片版本,请删除完整文档 +1. **先查完整文档** - 查找 `document-name.md` +2. **再查分片入口** - 查找 `document-name/index.md` +3. **优先级规则** - 若两者并存,默认优先完整文档;若你要强制使用分片版本,请删除或重命名完整文档 -## 工作流程支持 +## 你将获得 -所有 BMM 工作流程都支持这两种格式: +- 原始完整文档(可保留,但不建议与分片长期并存;并存时默认优先读取完整文档) +- 分片目录(如 `document-name/index.md` + 各章节文件) +- 对工作流透明的自动识别行为(无需额外配置) -- 完整文档 -- 分片文档 -- 自动检测 -- 对用户透明 +## 后续步骤 ---- -## 术语说明 - -- **sharding**:分片。将大型文档或数据集拆分为更小、更易管理的部分的过程。 -- **token**:令牌。在自然语言处理和大型语言模型中,文本的基本单位,通常对应单词或字符的一部分。 -- **subprocesses**:子进程。由主进程创建的独立执行单元,可以并行运行以执行特定任务。 -- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。 +- [如何自定义 BMad](./customize-bmad.md) - 了解高级配置与工作流定制边界 +- [如何升级到 v6](./upgrade-to-v6.md) - 在迁移过程中处理文档与目录结构变化 diff --git a/docs/zh-cn/how-to/upgrade-to-v6.md b/docs/zh-cn/how-to/upgrade-to-v6.md index b833d360c..eb28c9c38 100644 --- a/docs/zh-cn/how-to/upgrade-to-v6.md +++ b/docs/zh-cn/how-to/upgrade-to-v6.md @@ -5,76 +5,83 @@ sidebar: order: 3 --- -使用 BMad 安装程序从 v4 升级到 v6,其中包括自动检测旧版安装和迁移辅助。 +使用 BMad 安装程序把 v4 升级到 v6。安装程序会自动识别旧安装,并提供迁移辅助,帮助你在已有项目中平滑过渡。 ## 何时使用本指南 -- 您已安装 BMad v4(`.bmad-method` 文件夹) -- 您希望迁移到新的 v6 架构 -- 您有需要保留的现有规划产物 +- 你已安装 BMad v4(目录名通常是 `.bmad-method`) +- 你准备迁移到 v6 的统一目录结构 +- 你有要保留的规划产物或进行中的开发工作 :::note[前置条件] - Node.js 20+ -- 现有的 BMad v4 安装 +- 现有 BMad v4 安装 ::: +::::caution[先备份再迁移] +如果当前仓库里仍有未提交的重要变更,先完成提交或备份,再执行升级。 +:::: + ## 步骤 ### 1. 运行安装程序 按照[安装程序说明](./install-bmad.md)操作。 -### 2. 处理旧版安装 +### 2. 处理旧版安装目录 -当检测到 v4 时,您可以: +当检测到 v4 时,你有两种处理方式: -- 允许安装程序备份并删除 `.bmad-method` -- 退出并手动处理清理 +- 允许安装程序自动备份并删除 `.bmad-method` +- 先退出安装流程,再手动清理旧目录 -如果您将 bmad method 文件夹命名为其他名称 - 您需要手动删除该文件夹。 +如果你把 BMad Method 目录改成了其他名字,需要你自己手动定位并删除。 -### 3. 清理 IDE 命令 +### 3. 清理 IDE 命令与技能目录 -手动删除旧版 v4 IDE 命令 - 例如如果您使用 claude,查找任何以 bmad 开头的嵌套文件夹并删除它们: +手动删除旧版 v4 IDE 命令/技能目录。以 Claude Code 为例,请在旧目录中删除以 `bmad` 开头的嵌套目录: -- `.claude/commands/BMad/agents` -- `.claude/commands/BMad/tasks` +- `.claude/commands/` + +v6 新技能会安装到: + +- `.claude/skills/` ### 4. 迁移规划产物 -**如果您有规划文档(Brief/PRD/UX/Architecture):** +**如果你有规划文档(Brief/PRD/UX/Architecture):** -将它们移动到 `_bmad-output/planning-artifacts/` 并使用描述性名称: +把它们移动到 `_bmad-output/planning-artifacts/`,并使用可读的文件名: -- 在文件名中包含 `PRD` 用于 PRD 文档 -- 相应地包含 `brief`、`architecture` 或 `ux-design` -- 分片文档可以放在命名的子文件夹中 +- PRD 文档文件名包含 `PRD` +- 其他文档按类型包含 `brief`、`architecture` 或 `ux-design` +- 分片文档可放在命名清晰的子目录中 -**如果您正在进行规划:** 考虑使用 v6 工作流重新开始。将现有文档作为输入——新的渐进式发现工作流配合网络搜索和 IDE 计划模式会产生更好的结果。 +**如果你仍在规划中:** 建议直接用 v6 工作流重启规划,把现有文档作为输入;新版渐进式发现流程配合 Web 搜索和 IDE 计划模式通常会得到更稳妥的结果。 -### 5. 迁移进行中的开发 +### 5. 迁移进行中的开发工作 -如果您已创建或实现了故事: +如果你已经创建或实现了部分用户故事(story): 1. 完成 v6 安装 2. 将 `epics.md` 或 `epics/epic*.md` 放入 `_bmad-output/planning-artifacts/` -3. 运行 Scrum Master 的 `sprint-planning` 工作流 +3. 运行 Scrum Master 的 `bmad-sprint-planning` 工作流 4. 告诉 SM 哪些史诗/故事已经完成 -## 您将获得 +## 你将获得 **v6 统一结构:** ```text your-project/ -├── _bmad/ # 单一安装文件夹 -│ ├── _config/ # 您的自定义配置 +├── _bmad/ # 单一安装目录 +│ ├── _config/ # 你的自定义配置 │ │ └── agents/ # 智能体自定义文件 │ ├── core/ # 通用核心框架 │ ├── bmm/ # BMad Method 模块 │ ├── bmb/ # BMad Builder │ └── cis/ # Creative Intelligence Suite -└── _bmad-output/ # 输出文件夹(v4 中为 doc 文件夹) +└── _bmad-output/ # 输出目录(v4 时代常见为 doc 目录) ``` ## 模块迁移 @@ -87,34 +94,18 @@ your-project/ | `.bmad-infrastructure-devops` | 已弃用 — 新的 DevOps 智能体即将推出 | | `.bmad-creative-writing` | 未适配 — 新的 v6 模块即将推出 | -## 主要变更 +## 关键差异(旧名/新名) -| 概念 | v4 | v6 | -| ------------ | --------------------------------------- | ------------------------------------ | -| **核心** | `_bmad-core` 实际上是 BMad Method | `_bmad/core/` 是通用框架 | -| **方法** | `_bmad-method` | `_bmad/bmm/` | -| **配置** | 直接修改文件 | 每个模块使用 `config.yaml` | -| **文档** | 需要设置分片或非分片 | 完全灵活,自动扫描 | +| 概念 | v4(旧) | v6(新) | 迁移提示 | +| ------------ | --------------------------------------- | ------------------------------------ | ------------------------------------ | +| **核心框架** | `_bmad-core` 实际上承载的是 BMad Method | `_bmad/core/` 变成通用框架层 | 迁移时不要再把 `_bmad/core/` 当成 Method 本体 | +| **方法模块** | `_bmad-method` | `_bmad/bmm/` | 旧脚本、路径引用需同步更新到 `bmm` | +| **配置方式** | 直接改模块文件 | 每个模块通过 `config.yaml` 管理 | 优先改配置,不要直接改生成文件 | +| **文档读取** | 需要手动区分分片/非分片 | 自动扫描完整文档与分片入口 | 只有在兼容性场景下才建议手动分片 | ---- -## 术语说明 +## 后续建议 -- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。 -- **epic**:史诗。在敏捷开发中,指大型的工作项,可分解为多个用户故事。 -- **story**:故事。在敏捷开发中,指用户故事,描述用户需求的功能单元。 -- **Scrum Master**:Scrum 主管。敏捷开发 Scrum 框架中的角色,负责促进团队流程和移除障碍。 -- **sprint-planning**:冲刺规划。Scrum 框架中的会议,用于确定下一个冲刺期间要完成的工作。 -- **sharded**:分片。将大型文档拆分为多个较小的文件以便于管理和处理。 -- **PRD**:产品需求文档(Product Requirements Document)。描述产品功能、需求和特性的文档。 -- **Brief**:简报。概述项目目标、范围和关键信息的文档。 -- **UX**:用户体验(User Experience)。用户在使用产品或服务过程中的整体感受和交互体验。 -- **Architecture**:架构。系统的结构设计,包括组件、模块及其相互关系。 -- **BMGD**:BMad Game Development。BMad 游戏开发模块。 -- **DevOps**:开发运维(Development Operations)。结合开发和运维的实践,旨在缩短系统开发生命周期。 -- **BMad Method**:BMad 方法。BMad 框架的核心方法论模块。 -- **BMad Builder**:BMad 构建器。BMad 框架的构建工具。 -- **Creative Intelligence Suite**:创意智能套件。BMad 框架中的创意工具集合。 -- **IDE**:集成开发环境(Integrated Development Environment)。提供代码编辑、调试等功能的软件开发工具。 -- **progressive discovery**:渐进式发现。逐步深入探索和理解需求的过程。 -- **web search**:网络搜索。通过互联网检索信息的能力。 -- **plan mode**:计划模式。IDE 中的一种工作模式,用于规划和设计任务。 +- 升级完成后先运行 `bmad-help`,确认可用工作流与下一步建议 +- 如果是既有项目,补充或更新 `project-context.md`,减少后续实现偏差 +- 在继续开发前,先做一次关键链路验证(安装、命令触发、文档读取) +- 继续阅读:[如何安装 BMad](./install-bmad.md)、[管理项目上下文](./project-context.md) diff --git a/docs/zh-cn/reference/workflow-map.md b/docs/zh-cn/reference/workflow-map.md index c8a20ff9c..7c74efe70 100644 --- a/docs/zh-cn/reference/workflow-map.md +++ b/docs/zh-cn/reference/workflow-map.md @@ -68,7 +68,7 @@ BMad Method(BMM)是 BMad 生态系统中的一个模块,旨在遵循上下 | 工作流程 | 目的 | 产出 | | --------------------- | --------------------------------------------------------------------------- | --------------------------- | -| `bmad-bmm-quick-dev` | 统一快速流程 — 澄清意图、规划、实现、审查和呈现 | `tech-spec.md` + 代码 | +| `bmad-bmm-quick-dev` | 统一快速流程 — 澄清意图、规划、实现、审查和呈现 | `spec-*.md` + 代码 | ## 上下文管理 diff --git a/src/bmm-skills/4-implementation/bmad-correct-course/workflow.md b/src/bmm-skills/4-implementation/bmad-correct-course/workflow.md index 1241101d0..c65a3d105 100644 --- a/src/bmm-skills/4-implementation/bmad-correct-course/workflow.md +++ b/src/bmm-skills/4-implementation/bmad-correct-course/workflow.md @@ -36,7 +36,7 @@ Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve: | Epics | `{planning_artifacts}/*epic*.md` (whole) or `{planning_artifacts}/*epic*/*.md` (sharded) | FULL_LOAD | | Architecture | `{planning_artifacts}/*architecture*.md` (whole) or `{planning_artifacts}/*architecture*/*.md` (sharded) | FULL_LOAD | | UX Design | `{planning_artifacts}/*ux*.md` (whole) or `{planning_artifacts}/*ux*/*.md` (sharded) | FULL_LOAD | -| Tech Spec | `{planning_artifacts}/*tech-spec*.md` (whole) | FULL_LOAD | +| Spec | `{planning_artifacts}/*spec-*.md` (whole) | FULL_LOAD | | Document Project | `{project_knowledge}/index.md` (sharded) | INDEX_GUIDED | ### Context @@ -51,9 +51,9 @@ Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve: **Strategy**: Course correction needs broad project context to assess change impact accurately. Load all available planning artifacts. -**Discovery Process for FULL_LOAD documents (PRD, Epics, Architecture, UX Design, Tech Spec):** +**Discovery Process for FULL_LOAD documents (PRD, Epics, Architecture, UX Design, Spec):** -1. **Search for whole document first** - Look for files matching the whole-document pattern (e.g., `*prd*.md`, `*epic*.md`, `*architecture*.md`, `*ux*.md`, `*tech-spec*.md`) +1. **Search for whole document first** - Look for files matching the whole-document pattern (e.g., `*prd*.md`, `*epic*.md`, `*architecture*.md`, `*ux*.md`, `*spec-*.md`) 2. **Check for sharded version** - If whole document not found, look for a directory with `index.md` (e.g., `prd/index.md`, `epics/index.md`) 3. **If sharded version found**: - Read `index.md` to understand the document structure @@ -70,7 +70,7 @@ Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve: **Fuzzy matching**: Be flexible with document names — users may use variations like `prd.md`, `bmm-prd.md`, `product-requirements.md`, etc. -**Missing documents**: Not all documents may exist. PRD and Epics are essential; Architecture, UX Design, Tech Spec, and Document Project are loaded if available. HALT if PRD or Epics cannot be found. +**Missing documents**: Not all documents may exist. PRD and Epics are essential; Architecture, UX Design, Spec, and Document Project are loaded if available. HALT if PRD or Epics cannot be found. diff --git a/src/bmm-skills/4-implementation/bmad-quick-dev/tech-spec-template.md b/src/bmm-skills/4-implementation/bmad-quick-dev/spec-template.md similarity index 99% rename from src/bmm-skills/4-implementation/bmad-quick-dev/tech-spec-template.md rename to src/bmm-skills/4-implementation/bmad-quick-dev/spec-template.md index c9fef536b..3f70a5134 100644 --- a/src/bmm-skills/4-implementation/bmad-quick-dev/tech-spec-template.md +++ b/src/bmm-skills/4-implementation/bmad-quick-dev/spec-template.md @@ -11,8 +11,6 @@ context: [] # optional: max 3 project-wide standards/docs. NO source code files. Cohesive cross-layer stories (DB+BE+UI) stay in ONE file. IMPORTANT: Remove all HTML comments when filling this template. --> -# {title} - ## Intent diff --git a/src/bmm-skills/4-implementation/bmad-quick-dev/step-01-clarify-and-route.md b/src/bmm-skills/4-implementation/bmad-quick-dev/step-01-clarify-and-route.md index 047a2bf7a..5563dfcad 100644 --- a/src/bmm-skills/4-implementation/bmad-quick-dev/step-01-clarify-and-route.md +++ b/src/bmm-skills/4-implementation/bmad-quick-dev/step-01-clarify-and-route.md @@ -1,5 +1,5 @@ --- -wipFile: '{implementation_artifacts}/tech-spec-wip.md' +wipFile: '{implementation_artifacts}/spec-wip.md' deferred_work_file: '{implementation_artifacts}/deferred-work.md' spec_file: '' # set at runtime for plan-code-review before leaving this step --- @@ -15,13 +15,27 @@ spec_file: '' # set at runtime for plan-code-review before leaving this step - The user chose this workflow on purpose. Later steps (e.g. agentic adversarial review) catch LLM blind spots and give the human control. Do not skip them. - **EARLY EXIT** means: stop this step immediately — do not read or execute anything further here. Read and fully follow the target file instead. Return here ONLY if a later step explicitly says to loop back. -## ARTIFACT SCAN +## Intent check (do this first) -- `{wipFile}` exists? → Offer resume or archive. -- Active specs (`ready-for-dev`, `in-progress`, `in-review`) in `{implementation_artifacts}`? → List them and HALT. Ask user which to resume (or `[N]` for new). - - If `ready-for-dev` or `in-progress` selected: Set `spec_file`. **EARLY EXIT** → `./step-03-implement.md` - - If `in-review` selected: Set `spec_file`. **EARLY EXIT** → `./step-04-review.md` -- Unformatted spec or intent file lacking `status` frontmatter in `{implementation_artifacts}`? → Suggest to the user to treat its contents as the starting intent for this workflow. DO NOT attempt to infer a state and resume it. +Before listing artifacts or prompting the user, check whether you already know the intent. Check in this order — skip the remaining checks as soon as the intent is clear: + +1. Explicit argument + Did the user pass a specific file path, spec name, or clear instruction this message? + - If it points to a file that matches the spec template (has `status` frontmatter with a recognized value: ready-for-dev, in-progress, or in-review) → set `spec_file` and **EARLY EXIT** to the appropriate step (step-03 for ready/in-progress, step-04 for review). + - Anything else (intent files, external docs, plans, descriptions) → ingest it as starting intent and proceed to INSTRUCTIONS. Do not attempt to infer a workflow state from it. + +2. Recent conversation + Do the last few human messages clearly show what the user intends to work on? + Use the same routing as above. + +3. Otherwise — scan artifacts and ask + - `{wipFile}` exists? → Offer resume or archive. + - Active specs (`ready-for-dev`, `in-progress`, `in-review`) in `{implementation_artifacts}`? → List them and HALT. Ask user which to resume (or `[N]` for new). + - If `ready-for-dev` or `in-progress` selected: Set `spec_file`. **EARLY EXIT** → `./step-03-implement.md` + - If `in-review` selected: Set `spec_file`. **EARLY EXIT** → `./step-04-review.md` + - Unformatted spec or intent file lacking `status` frontmatter? → Suggest treating its contents as the starting intent. Do NOT attempt to infer a state and resume it. + +Never ask extra questions if you already understand what the user intends. ## INSTRUCTIONS @@ -42,7 +56,7 @@ spec_file: '' # set at runtime for plan-code-review before leaving this step **EARLY EXIT** → `./step-oneshot.md` **b) Plan-code-review** — everything else. When uncertain whether blast radius is truly zero, choose this path. - 1. Derive a valid kebab-case slug from the clarified intent. If `{implementation_artifacts}/tech-spec-{slug}.md` already exists, append `-2`, `-3`, etc. Set `spec_file` = `{implementation_artifacts}/tech-spec-{slug}.md`. + 1. Derive a valid kebab-case slug from the clarified intent. If the intent references a tracking identifier (story number, issue number, ticket ID), lead the slug with it (e.g. `3-2-digest-delivery`, `gh-47-fix-auth`). If `{implementation_artifacts}/spec-{slug}.md` already exists, append `-2`, `-3`, etc. Set `spec_file` = `{implementation_artifacts}/spec-{slug}.md`. ## NEXT diff --git a/src/bmm-skills/4-implementation/bmad-quick-dev/step-02-plan.md b/src/bmm-skills/4-implementation/bmad-quick-dev/step-02-plan.md index 15be7fda8..361d4c566 100644 --- a/src/bmm-skills/4-implementation/bmad-quick-dev/step-02-plan.md +++ b/src/bmm-skills/4-implementation/bmad-quick-dev/step-02-plan.md @@ -1,5 +1,5 @@ --- -wipFile: '{implementation_artifacts}/tech-spec-wip.md' +wipFile: '{implementation_artifacts}/spec-wip.md' deferred_work_file: '{implementation_artifacts}/deferred-work.md' --- @@ -13,7 +13,7 @@ deferred_work_file: '{implementation_artifacts}/deferred-work.md' ## INSTRUCTIONS 1. Investigate codebase. _Isolate deep exploration in sub-agents/tasks where available. To prevent context snowballing, instruct subagents to give you distilled summaries only._ -2. Read `./tech-spec-template.md` fully. Fill it out based on the intent and investigation, and write the result to `{wipFile}`. +2. Read `./spec-template.md` fully. Fill it out based on the intent and investigation, and write the result to `{wipFile}`. 3. Self-review against READY FOR DEVELOPMENT standard. 4. If intent gaps exist, do not fantasize, do not leave open questions, HALT and ask the human. 5. Token count check (see SCOPE STANDARD). If spec exceeds 1600 tokens: diff --git a/src/bmm-skills/4-implementation/bmad-quick-dev/workflow.md b/src/bmm-skills/4-implementation/bmad-quick-dev/workflow.md index 0cf4c9976..f842532bf 100644 --- a/src/bmm-skills/4-implementation/bmad-quick-dev/workflow.md +++ b/src/bmm-skills/4-implementation/bmad-quick-dev/workflow.md @@ -72,7 +72,7 @@ YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config ` ### 2. Paths -- `wipFile` = `{implementation_artifacts}/tech-spec-wip.md` +- `wipFile` = `{implementation_artifacts}/spec-wip.md` ### 3. First Step Execution diff --git a/src/bmm-skills/module-help.csv b/src/bmm-skills/module-help.csv index 6e27cb3e2..696688cc4 100644 --- a/src/bmm-skills/module-help.csv +++ b/src/bmm-skills/module-help.csv @@ -1,7 +1,7 @@ module,phase,name,code,sequence,workflow-file,command,required,agent,options,description,output-location,outputs, bmm,anytime,Document Project,DP,,skill:bmad-document-project,bmad-bmm-document-project,false,analyst,Create Mode,"Analyze an existing project to produce useful documentation",project-knowledge,*, -bmm,anytime,Generate Project Context,GPC,,skill:bmad-generate-project-context,bmad-bmm-generate-project-context,false,analyst,Create Mode,"Scan existing codebase to generate a lean LLM-optimized project-context.md containing critical implementation rules patterns and conventions for AI agents. Essential for brownfield projects and quick-flow.",output_folder,"project context", -bmm,anytime,Quick Dev,QQ,,skill:bmad-quick-dev,bmad-bmm-quick-dev,false,quick-flow-solo-dev,Create Mode,"Unified quick flow: clarify intent plan implement review and present in a single workflow",implementation_artifacts,"tech spec and project implementation", +bmm,anytime,Generate Project Context,GPC,,skill:bmad-generate-project-context,bmad-bmm-generate-project-context,false,analyst,Create Mode,"Scan existing codebase to generate a lean LLM-optimized project-context.md containing critical implementation rules patterns and conventions for AI agents. Essential for brownfield projects.",output_folder,"project context", +bmm,anytime,Quick Dev,QQ,,skill:bmad-quick-dev,bmad-bmm-quick-dev,false,quick-flow-solo-dev,Create Mode,"Unified intent-in code-out workflow: clarify plan implement review and present",implementation_artifacts,"spec and project implementation", bmm,anytime,Correct Course,CC,,skill:bmad-correct-course,bmad-bmm-correct-course,false,sm,Create Mode,"Anytime: Navigate significant changes. May recommend start over update PRD redo architecture sprint planning or correct epics and stories",planning_artifacts,"change proposal", bmm,anytime,Write Document,WD,,skill:bmad-agent-tech-writer,,false,tech-writer,,"Describe in detail what you want, and the agent will follow the documentation best practices defined in agent memory. Multi-turn conversation with subprocess for research/review.",project-knowledge,"document", bmm,anytime,Update Standards,US,,skill:bmad-agent-tech-writer,,false,tech-writer,,"Update agent memory documentation-standards.md with your specific preferences if you discover missing document conventions.",_bmad/_memory/tech-writer-sidecar,"standards", diff --git a/test/test-installation-components.js b/test/test-installation-components.js index c5b04a1ee..d75ec9871 100644 --- a/test/test-installation-components.js +++ b/test/test-installation-components.js @@ -14,6 +14,7 @@ const path = require('node:path'); const os = require('node:os'); const fs = require('fs-extra'); +const { ConfigCollector } = require('../tools/cli/installers/lib/core/config-collector'); const { ManifestGenerator } = require('../tools/cli/installers/lib/core/manifest-generator'); const { IdeManager } = require('../tools/cli/installers/lib/ide/manager'); const { clearCache, loadPlatformCodes } = require('../tools/cli/installers/lib/ide/platform-codes'); @@ -1853,6 +1854,93 @@ async function runTests() { console.log(''); + // ============================================================ + // Test Suite 33: ConfigCollector Prompt Normalization + // ============================================================ + console.log(`${colors.yellow}Test Suite 33: ConfigCollector Prompt Normalization${colors.reset}\n`); + + try { + const teaModuleConfig33 = { + test_artifacts: { + default: '_bmad-output/test-artifacts', + }, + test_design_output: { + prompt: 'Where should test design documents be stored?', + default: 'test-design', + result: '{test_artifacts}/{value}', + }, + test_review_output: { + prompt: 'Where should test review reports be stored?', + default: 'test-reviews', + result: '{test_artifacts}/{value}', + }, + trace_output: { + prompt: 'Where should traceability reports be stored?', + default: 'traceability', + result: '{test_artifacts}/{value}', + }, + }; + + const collector33 = new ConfigCollector(); + collector33.currentProjectDir = path.join(os.tmpdir(), 'bmad-config-normalization'); + collector33.allAnswers = {}; + collector33.collectedConfig = { + tea: { + test_artifacts: '_bmad-output/test-artifacts', + }, + }; + collector33.existingConfig = { + tea: { + test_artifacts: '_bmad-output/test-artifacts', + test_design_output: '_bmad-output/test-artifacts/test-design', + test_review_output: '_bmad-output/test-artifacts/test-reviews', + trace_output: '_bmad-output/test-artifacts/traceability', + }, + }; + + const testDesignQuestion33 = await collector33.buildQuestion( + 'tea', + 'test_design_output', + teaModuleConfig33.test_design_output, + teaModuleConfig33, + ); + const testReviewQuestion33 = await collector33.buildQuestion( + 'tea', + 'test_review_output', + teaModuleConfig33.test_review_output, + teaModuleConfig33, + ); + const traceQuestion33 = await collector33.buildQuestion('tea', 'trace_output', teaModuleConfig33.trace_output, teaModuleConfig33); + + assert(testDesignQuestion33.default === 'test-design', 'ConfigCollector normalizes existing test_design_output prompt default'); + assert(testReviewQuestion33.default === 'test-reviews', 'ConfigCollector normalizes existing test_review_output prompt default'); + assert(traceQuestion33.default === 'traceability', 'ConfigCollector normalizes existing trace_output prompt default'); + + collector33.allAnswers = { + tea_test_artifacts: '_bmad-output/test-artifacts', + }; + + assert( + collector33.processResultTemplate(teaModuleConfig33.test_design_output.result, testDesignQuestion33.default) === + '_bmad-output/test-artifacts/test-design', + 'ConfigCollector re-applies test_design_output template without duplicating prefix', + ); + assert( + collector33.processResultTemplate(teaModuleConfig33.test_review_output.result, testReviewQuestion33.default) === + '_bmad-output/test-artifacts/test-reviews', + 'ConfigCollector re-applies test_review_output template without duplicating prefix', + ); + assert( + collector33.processResultTemplate(teaModuleConfig33.trace_output.result, traceQuestion33.default) === + '_bmad-output/test-artifacts/traceability', + 'ConfigCollector re-applies trace_output template without duplicating prefix', + ); + } catch (error) { + assert(false, 'ConfigCollector prompt normalization test succeeds', error.message); + } + + console.log(''); + // ============================================================ // Summary // ============================================================ diff --git a/tools/bmad-npx-wrapper.js b/tools/bmad-npx-wrapper.js index bc63a4121..c6f578b2d 100755 --- a/tools/bmad-npx-wrapper.js +++ b/tools/bmad-npx-wrapper.js @@ -5,7 +5,7 @@ * This file ensures proper execution when run via npx from GitHub or npm registry */ -const { execSync } = require('node:child_process'); +const { execFileSync } = require('node:child_process'); const path = require('node:path'); const fs = require('node:fs'); @@ -25,7 +25,7 @@ if (isNpxExecution) { try { // Execute CLI from user's working directory (process.cwd()), not npm cache - execSync(`node "${bmadCliPath}" ${args.join(' ')}`, { + execFileSync('node', [bmadCliPath, ...args], { stdio: 'inherit', cwd: process.cwd(), // This preserves the user's working directory }); diff --git a/tools/cli/installers/lib/core/config-collector.js b/tools/cli/installers/lib/core/config-collector.js index e8569cd0f..665c7957a 100644 --- a/tools/cli/installers/lib/core/config-collector.js +++ b/tools/cli/installers/lib/core/config-collector.js @@ -954,31 +954,123 @@ class ConfigCollector { return match; } - // Look for the config value in allAnswers (already answered questions) - let configValue = this.allAnswers[configKey] || this.allAnswers[`core_${configKey}`]; - - // Check in already collected config - if (!configValue) { - for (const mod of Object.keys(this.collectedConfig)) { - if (mod !== '_meta' && this.collectedConfig[mod] && this.collectedConfig[mod][configKey]) { - configValue = this.collectedConfig[mod][configKey]; - break; - } - } - } - - // If still not found and we're in the same module, use the default from the config schema - if (!configValue && currentModule && moduleConfig && moduleConfig[configKey]) { - const referencedItem = moduleConfig[configKey]; - if (referencedItem && referencedItem.default !== undefined) { - configValue = referencedItem.default; - } - } + const configValue = this.resolveConfigValue(configKey, currentModule, moduleConfig); return configValue || match; }); } + /** + * Clean a stored path-like value for prompt display/input reuse. + * @param {*} value - Stored value + * @returns {*} Cleaned value + */ + cleanPromptValue(value) { + if (typeof value === 'string' && value.startsWith('{project-root}/')) { + return value.replace('{project-root}/', ''); + } + + return value; + } + + /** + * Resolve a config key from answers, collected config, existing config, or schema defaults. + * @param {string} configKey - Config key to resolve + * @param {string} currentModule - Current module name + * @param {Object} moduleConfig - Current module config schema + * @returns {*} Resolved value + */ + resolveConfigValue(configKey, currentModule = null, moduleConfig = null) { + // Look for the config value in allAnswers (already answered questions) + let configValue = this.allAnswers?.[configKey] || this.allAnswers?.[`core_${configKey}`]; + + if (!configValue && this.allAnswers) { + for (const [answerKey, answerValue] of Object.entries(this.allAnswers)) { + if (answerKey.endsWith(`_${configKey}`)) { + configValue = answerValue; + break; + } + } + } + + // Prefer the current module's persisted value when re-prompting an existing install + if (!configValue && currentModule && this.existingConfig?.[currentModule]?.[configKey] !== undefined) { + configValue = this.existingConfig[currentModule][configKey]; + } + + // Check in already collected config + if (!configValue) { + for (const mod of Object.keys(this.collectedConfig)) { + if (mod !== '_meta' && this.collectedConfig[mod] && this.collectedConfig[mod][configKey]) { + configValue = this.collectedConfig[mod][configKey]; + break; + } + } + } + + // Fall back to other existing module config values + if (!configValue && this.existingConfig) { + for (const mod of Object.keys(this.existingConfig)) { + if (mod !== '_meta' && this.existingConfig[mod] && this.existingConfig[mod][configKey]) { + configValue = this.existingConfig[mod][configKey]; + break; + } + } + } + + // If still not found and we're in the same module, use the default from the config schema + if (!configValue && currentModule && moduleConfig && moduleConfig[configKey]) { + const referencedItem = moduleConfig[configKey]; + if (referencedItem && referencedItem.default !== undefined) { + configValue = referencedItem.default; + } + } + + return this.cleanPromptValue(configValue); + } + + /** + * Convert an existing stored value back into the prompt-facing value for templated fields. + * For example, "{test_artifacts}/{value}" + "_bmad-output/test-artifacts/test-design" + * becomes "test-design" so the template is not applied twice on modify. + * @param {*} existingValue - Stored config value + * @param {string} moduleName - Module name + * @param {Object} item - Config item definition + * @param {Object} moduleConfig - Current module config schema + * @returns {*} Prompt-facing default value + */ + normalizeExistingValueForPrompt(existingValue, moduleName, item, moduleConfig = null) { + const cleanedValue = this.cleanPromptValue(existingValue); + + if (typeof cleanedValue !== 'string' || typeof item?.result !== 'string' || !item.result.includes('{value}')) { + return cleanedValue; + } + + const [prefixTemplate = '', suffixTemplate = ''] = item.result.split('{value}'); + const prefix = this.cleanPromptValue(this.replacePlaceholders(prefixTemplate, moduleName, moduleConfig)); + const suffix = this.cleanPromptValue(this.replacePlaceholders(suffixTemplate, moduleName, moduleConfig)); + + if ((prefix && !cleanedValue.startsWith(prefix)) || (suffix && !cleanedValue.endsWith(suffix))) { + return cleanedValue; + } + + const startIndex = prefix.length; + const endIndex = suffix ? cleanedValue.length - suffix.length : cleanedValue.length; + if (endIndex < startIndex) { + return cleanedValue; + } + + let promptValue = cleanedValue.slice(startIndex, endIndex); + if (promptValue.startsWith('/')) { + promptValue = promptValue.slice(1); + } + if (promptValue.endsWith('/')) { + promptValue = promptValue.slice(0, -1); + } + + return promptValue || cleanedValue; + } + /** * Build a prompt question from a config item * @param {string} moduleName - Module name @@ -993,12 +1085,7 @@ class ConfigCollector { let existingValue = null; if (this.existingConfig && this.existingConfig[moduleName]) { existingValue = this.existingConfig[moduleName][key]; - - // Clean up existing value - remove {project-root}/ prefix if present - // This prevents duplication when the result template adds it back - if (typeof existingValue === 'string' && existingValue.startsWith('{project-root}/')) { - existingValue = existingValue.replace('{project-root}/', ''); - } + existingValue = this.normalizeExistingValueForPrompt(existingValue, moduleName, item, moduleConfig); } // Special handling for user_name: default to system user