Merge branch 'main' into main

This commit is contained in:
miendinh 2026-03-24 10:03:39 +07:00 committed by GitHub
commit d476db0f86
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 545 additions and 485 deletions

View File

@ -56,7 +56,7 @@ Critical warnings only — data loss, security issues
| Phase | Name | What Happens | | Phase | Name | What Happens |
| ----- | -------- | -------------------------------------------- | | ----- | -------- | -------------------------------------------- |
| 1 | Analysis | Brainstorm, research *(optional)* | | 1 | Analysis | Brainstorm, research *(optional)* |
| 2 | Planning | Requirements — PRD or tech-spec *(required)* | | 2 | Planning | Requirements — PRD or spec *(required)* |
``` ```
**Skills:** **Skills:**

View File

@ -34,7 +34,7 @@ Yes! Quick Flow works great for established projects. It will:
- Auto-detect your existing stack - Auto-detect your existing stack
- Analyze existing code patterns - Analyze existing code patterns
- Detect conventions and ask for confirmation - 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. 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: Quick Flow detects your conventions and asks: "Should I follow these existing conventions?" You decide:
- **Yes** → Maintain consistency with current codebase - **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. BMM respects your choice — it won't force modernization, but it will offer it.

View File

@ -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-create-story` — informs story creation with project patterns
- `bmad-dev-story` — guides implementation decisions - `bmad-dev-story` — guides implementation decisions
- `bmad-code-review` — validates against project standards - `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 - `bmad-sprint-planning`, `bmad-retrospective`, `bmad-correct-course` — provides project-wide context
## When to Create It ## When to Create It

View File

@ -68,7 +68,7 @@ Sautez les phases 1-3 pour les travaux de faible envergure et bien compris.
| Workflow | Objectif | Produit | | 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 ## Gestion du Contexte

View File

@ -233,7 +233,7 @@ your-project/
## Questions fréquentes ## Questions fréquentes
**Ai-je toujours besoin d'une architecture ?** **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 ?** **Puis-je modifier mon plan plus tard ?**
Oui. Utilisez `bmad-correct-course` pour gérer les changements de périmètre. Oui. Utilisez `bmad-correct-course` pour gérer les changements de périmètre.

View File

@ -68,7 +68,7 @@ Skip phases 1-3 for small, well-understood work.
| Workflow | Purpose | Produces | | 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 ## Context Management

View File

@ -69,7 +69,7 @@ BMad helps you build software through guided workflows with specialized AI agent
| Phase | Name | What Happens | | Phase | Name | What Happens |
| ----- | -------------- | --------------------------------------------------- | | ----- | -------------- | --------------------------------------------------- |
| 1 | Analysis | Brainstorming, research, product brief *(optional)* | | 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)* | | 3 | Solutioning | Design architecture *(BMad Method/Enterprise only)* |
| 4 | Implementation | Build epic by epic, story by story | | 4 | Implementation | Build epic by epic, story by story |
@ -237,7 +237,7 @@ your-project/
## Common Questions ## Common Questions
**Do I always need architecture?** **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?** **Can I change my plan later?**
Yes. The SM agent has a `bmad-correct-course` workflow (`bmad-correct-course`) for handling scope changes. Yes. The SM agent has a `bmad-correct-course` workflow (`bmad-correct-course`) for handling scope changes.

View File

@ -56,7 +56,7 @@ Critical warnings only — data loss, security issues
| Phase | Name | What Happens | | Phase | Name | What Happens |
| ----- | -------- | -------------------------------------------- | | ----- | -------- | -------------------------------------------- |
| 1 | Analysis | Brainstorm, research *(optional)* | | 1 | Analysis | Brainstorm, research *(optional)* |
| 2 | Planning | Requirements — PRD or tech-spec *(required)* | | 2 | Planning | Requirements — PRD or spec *(required)* |
``` ```
**Commands:** **Commands:**

View File

@ -1,60 +1,62 @@
--- ---
title: "既有项目常见问题" title: "既有项目常见问题"
description: 关于在既有项目上使用 BMad 方法的常见问题 description: 关于在既有项目上使用 BMad Method 的常见问题
sidebar: sidebar:
order: 8 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` 基于真实现状而不是猜测执行
- 没有现有文档 如果你已有完整且最新的文档(包含 `docs/index.md`),并且能通过其他方式提供足够上下文,也可以跳过。
- 文档已过时
- AI 智能体需要关于现有代码的上下文
如果你拥有全面且最新的文档,包括 `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**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。 - [既有项目How-to](../how-to/established-projects.md)
- **Quick Flow**快速流程。BMad 方法中的一种工作流程,用于快速处理既有项目。 - [项目上下文Explanation](./project-context.md)
- **tech-spec**:技术规范。描述技术实现细节和标准的文档。 - [管理项目上下文How-to](../how-to/project-context.md)
- **stack**:技术栈。项目所使用的技术组合,包括框架、库、工具等。
- **conventions**:约定。代码库中遵循的编码风格、命名规则等规范。
- **modernization**:现代化。将旧代码或系统更新为更现代的技术和最佳实践的过程。

View File

@ -5,133 +5,112 @@ sidebar:
order: 4 order: 4
--- ---
当多个 AI 智能体实现系统的不同部分时,它们可能会做出相互冲突的技术决策。架构文档通过建立共享标准来防止这种情况 当多个 AI 智能体并行实现系统时,冲突并不罕见。`architecture` 的作用,就是在 `solutioning` 阶段先统一关键决策,避免到 `epic/story` 实施时才暴露分歧
## 常见冲突类型 ## 冲突最常出现在哪些地方
### API 风格冲突 ### API 风格冲突
没有架构时: 没有架构约束时:
- 智能体 A 使用 REST路径 `/users/{id}` - 智能体 A 使用 REST路径 `/users/{id}`
- 智能体 B 使用 GraphQL mutations - 智能体 B 使用 GraphQL mutations
- 结果:API 模式不一致,消费者困惑 - 结果:接口模式不一致,调用方和集成层都变复杂
有架构时: 有架构约束时:
- ADR 指定:"所有客户端-服务器通信使用 GraphQL" - ADR 明确规定:“客户端与服务端统一使用 GraphQL”
- 所有智能体遵循相同的模式 - 所有智能体遵循同一套 API 规则
### 数据库设计冲突 ### 数据库与命名冲突
没有架构时: 没有架构约束时:
- 智能体 A 使用 snake_case 列名 - 智能体 A 使用 `snake_case` 列名
- 智能体 B 使用 camelCase 列名 - 智能体 B 使用 `camelCase` 列名
- 结果:模式不一致,查询混乱 - 结果:schema 不一致,查询与迁移成本上升
有架构时: 有架构约束时:
- 标准文档指定命名约定 - 标准文档统一命名约定和迁移策略
- 所有智能体遵循相同的模式 - 所有智能体按同一模式实现
### 状态管理冲突 ### 状态管理冲突
没有架构时: 没有架构约束时:
- 智能体 A 使用 Redux 管理全局状态 - 智能体 A 使用 Redux
- 智能体 B 使用 React Context - 智能体 B 使用 React Context
- 结果:多种状态管理方法,复杂度增加 - 结果:状态层碎片化,维护复杂度增加
有架构时: 有架构约束时:
- ADR 指定状态管理方法 - ADR 明确状态管理方案
- 所有智能体一致实现 - 不同 `story` 的实现保持一致
## 架构如何防止冲突 ## architecture 如何前置消解冲突
### 1. 通过 ADR 明确决策 ### 1. 用 ADR 固化关键决策
每个重要的技术选择都记录以下内容 每个关键技术选择都至少包含
- 上下文(为什么这个决策很重要 - 背景(为什么要做这个决策
- 考虑的选项(有哪些替代方案 - 备选方案(有哪些选择
- 决策(我们选择了什么) - 最终决策(采用什么)
- 理由(为什么选择它 - 理由(为什么这样选)
- 后果(接受权衡) - 后果(接受哪些权衡)
### 2. FR/NFR 特定指导 ### 2. 把 FR/NFR 映射到技术实现
架构将每个功能需求映射到技术方法 `architecture` 不是抽象原则清单,而是把需求落到可执行方案
- FR-001:用户管理 → GraphQL mutations - FR-001(用户管理)→ GraphQL mutations
- FR-002:移动应用 → 优化查询 - FR-002(移动端性能)→ 查询裁剪与缓存策略
### 3. 标准和约定 ### 3. 统一基础约定
明确记录以下内容 至少覆盖以下共识
- 目录结构 - 目录结构
- 命名约定 - 命名约定
- 代码组织 - 代码组织方式
- 测试模式 - 测试策略
## 架构作为共享上下文 ## architecture 是所有 epic 的共享上下文
将架构视为所有智能体在实现之前阅读的共享上下文 把架构文档看作每个智能体在实施前都要阅读的“公共协议”
```text ```text
PRD"构建什么" PRD: "做什么"
架构:"如何构建" architecture: "如何做"
智能体 A 阅读架构 → 实现 Epic 1 智能体 A 读 architecture → 实现 Epic 1
智能体 B 阅读架构 → 实现 Epic 2 智能体 B 读 architecture → 实现 Epic 2
智能体 C 阅读架构 → 实现 Epic 3 智能体 C 读 architecture → 实现 Epic 3
结果:一致的实现 结果:实现一致、集成顺畅
``` ```
## Key ADR Topics ## 优先写清的 ADR 主题
防止冲突的常见决策: | 主题 | 示例决策 |
| Topic | Example Decision |
| ---------------- | -------------------------------------------- | | ---------------- | -------------------------------------------- |
| API Style | GraphQL vs REST vs gRPC | | API 风格 | GraphQL vs REST vs gRPC |
| Database | PostgreSQL vs MongoDB | | 数据存储 | PostgreSQL vs MongoDB |
| Auth | JWT vs Sessions | | 认证机制 | JWT vs Session |
| State Management | Redux vs Context vs Zustand | | 状态管理 | Redux vs Context vs Zustand |
| Styling | CSS Modules vs Tailwind vs Styled Components | | 样式方案 | CSS Modules vs Tailwind vs Styled Components |
| Testing | Jest + Playwright vs Vitest + Cypress | | 测试体系 | Jest + Playwright vs Vitest + Cypress |
## 避免的反模式 ## 常见误区
:::caution[常见错误] :::caution[常见错误]
- **隐式决策** — "我们边做边确定 API 风格"会导致不一致 - **隐式决策**:边写边定规则,最终通常会分叉
- **过度文档化** — 记录每个次要选择会导致分析瘫痪 - **过度文档化**:把每个小选择都写 ADR造成分析瘫痪
- **过时架构** — 文档写一次后从不更新,导致智能体遵循过时的模式 - **架构陈旧**:文档不更新,智能体继续按过时规则实现
::: :::
:::tip[正确方法] :::tip[更稳妥的做法]
- 记录跨越 epic 边界的决策 - 先记录跨 `epic`、高冲突概率的决策
- 专注于容易产生冲突的领域 - 把精力放在“会影响多个 story 的规则”
- 随着学习更新架构 - 随着项目演进持续更新架构文档
- 对重大变更使用 `correct-course` - 出现重大偏移时使用 `bmad-correct-course`
::: :::
--- ## 继续阅读
## 术语说明
- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。 - [为什么解决方案阶段很重要](./why-solutioning-matters.md)
- **ADR**架构决策记录Architecture Decision Record。用于记录重要架构决策及其背景、选项和后果的文档。 - [项目上下文](./project-context.md)
- **FR**功能需求Functional Requirement。系统必须具备的功能或行为。 - [工作流地图](../reference/workflow-map.md)
- **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。描述产品功能、需求和目标的文档。

View File

@ -1,55 +1,51 @@
--- ---
title: "项目上下文" title: "项目上下文"
description: project-context.md 如何使用项目规则和偏好指导 AI 智能体 description: project-context.md 如何使用项目规则和偏好指导 AI 智能体
sidebar: sidebar:
order: 7 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` — 在解决方案设计期间尊重技术偏好 - `bmad-create-architecture`:在 solutioning 时纳入你的技术偏好
- `create-story` — 使用项目模式指导用户故事创建 - `bmad-create-story`:按项目约定拆分和描述 story
- `dev-story` — 指导实施决策 - `bmad-dev-story`:约束实现路径和代码风格
- `code-review` — 根据项目标准进行验证 - `bmad-code-review`:按项目标准做一致性校验
- `quick-dev` — 在实施技术规范时应用模式 - `bmad-quick-dev`:在快速实现中避免偏离既有模式
- `sprint-planning`、`retrospective`、`correct-course` — 提供项目范围的上下文 - `bmad-sprint-planning`、`bmad-retrospective`、`bmad-correct-course`:读取项目级背景
## 何时创建 ## 什么时候建立或更新
`project-context.md` 文件在项目的任何阶段都很有用: | 场景 | 建议时机 | 目标 |
| 场景 | 何时创建 | 目的 |
|----------|----------------|---------| |----------|----------------|---------|
| **新项目,架构之前** | 手动,在 `create-architecture` 之前 | 记录您的技术偏好,以便架构师尊重它们 | | **新项目(架构前)** | 在 `bmad-create-architecture` 前手动创建 | 先声明技术偏好,避免架构偏航 |
| **新项目,架构之后** | 通过 `generate-project-context` 或手动 | 捕获架构决策,供实施智能体使用 | | **新项目(架构后)** | 通过 `bmad-generate-project-context` 生成并补充 | 把架构决策转成可执行规则 |
| **现有项目** | 通过 `generate-project-context` | 发现现有模式,以便智能体遵循既定约定 | | **既有项目** | 先生成,再人工校对 | 让智能体学习现有约定而非重造体系 |
| **快速流程项目** | 在 `quick-dev` 之前或期间 | 确保快速实施尊重您的模式 | | **Quick Flow 场景** | 在 `bmad-quick-dev` 前或过程中维护 | 弥补跳过完整规划带来的上下文缺口 |
:::tip[推荐] :::tip[推荐做法]
对于新项目,如果您有强烈的技术偏好,请在架构之前手动创建。否则,在架构之后生成它以捕获这些决策 如果你有强技术偏好(例如数据库、状态管理、目录规范),尽量在架构前写入。否则可在架构后生成,再按项目现实补齐
::: :::
## 文件内容 ## 应该写哪些内容
该文件有两个主要部分: 建议聚焦两类信息:**技术栈与版本**、**关键实现规则**。原则是记录“智能体不容易从代码片段直接推断”的内容。
### 技术栈与版本 ### 1. 技术栈与版本
记录项目使用的框架、语言和工具及其具体版本:
```markdown ```markdown
## Technology Stack & Versions ## Technology Stack & Versions
@ -60,9 +56,7 @@ AI 智能体不断做出实施决策——遵循哪些模式、如何组织代
- Styling: Tailwind CSS with custom design tokens - Styling: Tailwind CSS with custom design tokens
``` ```
### 关键实施规则 ### 2. 关键实现规则
记录智能体可能忽略的模式和约定:
```markdown ```markdown
## Critical Implementation Rules ## Critical Implementation Rules
@ -73,104 +67,28 @@ AI 智能体不断做出实施决策——遵循哪些模式、如何组织代
**Code Organization:** **Code Organization:**
- Components in `/src/components/` with co-located `.test.tsx` - 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 - API calls use the `apiClient` singleton — never fetch directly
**Testing Patterns:** **Testing Patterns:**
- Unit tests focus on business logic, not implementation details
- Integration tests use MSW to mock API responses - Integration tests use MSW to mock API responses
- E2E tests cover critical user journeys only - 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 - [管理项目上下文How-to](../how-to/project-context.md)
# In your project root - [既有项目常见问题](./established-projects-faq.md)
mkdir -p _bmad-output - [工作流地图](../reference/workflow-map.md)
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 运行时。

View File

@ -5,54 +5,53 @@ sidebar:
order: 3 order: 3
--- ---
Phase 3solutioning把“要做什么”planning 产出)转成“如何实现”(`architecture` 设计 + 工作拆分)。它的核心价值是:在开发前先把跨 `epic` 的关键技术决策写清楚,让后续 `story` 实施保持一致。
阶段 3解决方案将构建**什么**(来自规划)转化为**如何**构建(技术设计)。该阶段通过在实施开始前记录架构决策,防止多史诗项目中的智能体冲突。 ## 不做 solutioning 会出现什么问题
## 没有解决方案阶段的问题
```text ```text
智能体 1 使用 REST API 实现史诗 1 智能体 1 使用 REST API 实现 Epic 1
智能体 2 使用 GraphQL 实现史诗 2 智能体 2 使用 GraphQL 实现 Epic 2
结果API 设计不一致,集成噩梦 结果API 设计不一致,集成成本暴涨
``` ```
当多个智能体在没有共享架构指导的情况下实现系统的不同部分时,它们会做出可能冲突的独立技术决策 当多个智能体在没有共享 `architecture` 指南的前提下并行实现不同 `epic`,它们会各自做局部最优决策,最后在集成阶段发生冲突
## 有解决方案阶段的解决方案 ## 做了 solutioning 后会发生什么
```text ```text
架构工作流决定"所有 API 使用 GraphQL" architecture 工作流先定规则"所有 API 使用 GraphQL"
所有智能体遵循架构决策 所有智能体按同一套决策实现 story
结果:实现一致,无冲突 结果:实现一致,集成顺滑
``` ```
通过明确记录技术决策,所有智能体都能一致地实现,集成变得简单直接 solutioning 的本质不是“多写一份文档”,而是把高冲突风险决策前置,作为所有 `story` 的共享上下文
## 解决方案阶段 vs 规划阶段 ## solutioning 与 planning 的边界
| 方面 | 规划(阶段 2 | 解决方案(阶段 3 | | 方面 | Planning阶段 2 | Solutioning(阶段 3 |
| -------- | ----------------------- | --------------------------------- | | -------- | ----------------------- | --------------------------------- |
| 问题 | 做什么和为什么? | 如何做?然后是什么工作单元 | | 核心问题 | 做什么,为什么做? | 如何做,再如何拆分工作 |
| 输出 | FRs/NFRs需求 | 架构 + 史诗/用户故事 | | 输出物 | FRs/NFRs需求 | `architecture` + `epic/story` 拆分 |
| 智能体 | PM | 架构师 → PM | | 主导角色 | PM | Architect → PM |
| 受众 | 利益相关者 | 开发人员 | | 受众 | 利益相关者 | 开发人员 |
| 文档 | PRDFRs/NFRs | 架构 + 史诗文件 | | 文档 | PRDFRs/NFRs | 架构文档 + epics 文件 |
| 层级 | 业务逻辑 | 技术设计 + 工作分解 | | 决策层级 | 业务目标与范围 | 技术策略与实现边界 |
## 核心原则 ## 核心原则
**使技术决策明确且有文档记录**,以便所有智能体一致地实现。 **让跨 `epic` 的关键技术决策显式、可追溯、可复用。**
可以防止 能直接降低
- API 风格冲突REST vs GraphQL - API 风格冲突REST vs GraphQL
- 数据库设计不一致 - 数据模型与命名约定不一致
- 状态管理分歧 - 状态管理方案分裂
- 命名约定不匹配 - 安全策略分叉
- 安全方法差异 - 中后期返工成本
## 何时需要解决方案阶段 ## 什么时候需要 solutioning
| 流程 | 需要解决方案阶段 | | 流程 | 需要 solutioning |
|-------|----------------------| |-------|----------------------|
| Quick Flow | 否 - 完全跳过 | | Quick Flow | 否 - 完全跳过 |
| BMad Method Simple | 可选 | | BMad Method Simple | 可选 |
@ -60,31 +59,24 @@ sidebar:
| Enterprise | 是 | | Enterprise | 是 |
:::tip[经验法则] :::tip[经验法则]
如果你有多个可能由不同智能体实现的史诗,你需要解决方案阶段 只要需求会拆成多个 `epic`,并且可能由不同智能体并行实现,就应该做 solutioning
::: :::
## 跳过的代价 ## 跳过 solutioning 的代价
在复杂项目中跳过解决方案阶段会导致 在复杂项目中跳过该阶段,常见后果是
- **集成问题**在冲刺中期发现 - **集成问题**在冲刺中期暴露
- **返工**由实现冲突 - **返工**由实现冲突引发
- **开发时间更长**整体 - **整体研发周期拉长**
- **技术债务**来自不一致模式 - **技术债务**因模式不一致持续累积
:::caution[成本倍增] :::caution[成本倍增]
解决方案阶段发现对齐问题比在实施期间发现要快 10 倍 solutioning 阶段发现对齐问题,通常比在实施中后期才发现更快、更便宜
::: :::
--- ## 继续阅读
## 术语说明
- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。 - [防止智能体冲突](./preventing-agent-conflicts.md)
- **epic**:史诗。在敏捷开发中,指一个大型的工作项,可分解为多个用户故事。 - [项目上下文](./project-context.md)
- **REST API**:表述性状态传递应用程序接口。一种基于 HTTP 协议的 Web API 设计风格。 - [工作流地图](../reference/workflow-map.md)
- **GraphQL**:一种用于 API 的查询语言和运行时环境。
- **FRs/NFRs**:功能需求/非功能需求。Functional Requirements/Non-Functional Requirements 的缩写。
- **PRD**产品需求文档。Product Requirements Document 的缩写。
- **PM**产品经理。Product Manager 的缩写。
- **sprint**:冲刺。敏捷开发中的固定时间周期,通常为 1-4 周。
- **technical debt**:技术债务。指为了短期目标而选择的不完美技术方案,未来需要付出额外成本来修复。

View File

@ -5,56 +5,56 @@ sidebar:
order: 7 order: 7
--- ---
使用 `.customize.yaml` 文件来调整智能体行为、角色和菜单,同时在更新过程中保留您的更改 使用 `.customize.yaml` 文件自定义智能体agent的行为、角色persona和菜单同时在后续更新中保留你的改动
## 何时使用此功能 ## 何时使用此功能
- 您想要更改智能体的名称、个性或沟通风格 - 你想修改智能体名称、身份设定或沟通风格
- 您需要智能体记住项目特定的上下文 - 你需要让智能体长期记住项目约束和背景信息
- 您想要添加自定义菜单项来触发您自己的工作流或提示 - 你希望增加自定义菜单项,触发自己的工作流或提示
- 您希望智能体在每次启动时执行特定操 - 你希望智能体每次启动都先执行固定动
:::note[前置条件] :::note[前置条件]
- 在项目中安装 BMad参见[如何安装 BMad](./install-bmad.md) - 在项目中安装 BMad参见[如何安装 BMad](./install-bmad.md)
- 用于编辑 YAML 文件的文本编辑器 - 用于编辑 YAML 文件的文本编辑器
::: :::
:::caution[保护您的自定义配置] :::caution[保护您的自定义配置]
始终使用此处描述的 `.customize.yaml` 文件,而不是直接编辑智能体文件。安装程序在更新期间会覆盖智能体文件,但会保留您的 `.customize.yaml` 更改 始终通过 `.customize.yaml` 自定义,不要直接改动智能体源文件。安装程序在更新时会覆盖智能体文件,但会保留 `.customize.yaml` 的内容
::: :::
## 步骤 ## 步骤
### 1. 定位自定义文件 ### 1. 定位自定义文件
安装后,在以下位置为每个智能体找到一个 `.customize.yaml` 文件 安装完成后,每个已安装智能体都会在下面目录生成一个 `.customize.yaml`
```text ```text
_bmad/_config/agents/ _bmad/_config/agents/
├── core-bmad-master.customize.yaml ├── core-bmad-master.customize.yaml
├── bmm-dev.customize.yaml ├── bmm-dev.customize.yaml
├── bmm-pm.customize.yaml ├── bmm-pm.customize.yaml
└── ...(每个已安装智能体一个文件) └── ...(每个已安装智能体一个文件)
``` ```
### 2. 编辑自定义文件 ### 2. 编辑自定义文件
打开您想要修改的智能体的 `.customize.yaml` 文件。每个部分都是可选的——只自定义您需要的内容 打开目标智能体的 `.customize.yaml`。各段都可选,只改你需要的部分即可
| 部分 | 行为 | 用途 | | 部分 | 作用方式 | 用途 |
| ------------------ | -------- | ---------------------------------------------- | | ------------------ | -------- | ---------------------------------------------- |
| `agent.metadata` | 替换 | 覆盖智能体的显示名称 | | `agent.metadata` | 覆盖 | 覆盖智能体显示名称 |
| `persona` | 替换 | 设置角色、身份、风格和原则 | | `persona` | 覆盖 | 设置角色、身份、风格和原则 |
| `memories` | 追加 | 添加智能体始终会记住的持久上下文 | | `memories` | 追加 | 添加智能体长期记忆的上下文 |
| `menu` | 追加 | 为工作流或提示添加自定义菜单项 | | `menu` | 追加 | 增加指向工作流或提示的菜单项 |
| `critical_actions` | 追加 | 定义智能体的启动指令 | | `critical_actions` | 追加 | 定义智能体启动时要执行的动作 |
| `prompts` | 追加 | 创建可重复使用的提示供菜单操作使用 | | `prompts` | 追加 | 创建可复用提示,供菜单 `action` 引用 |
标记为 **替换** 的部分会完全覆盖智能体的默认设置。标记为 **追加** 的部分会添加到现有配置中 标记为 **覆盖** 的部分会完全替换默认配置;标记为 **追加** 的部分会在默认配置基础上累加
**智能体名称** **智能体名称`agent.metadata`**
更改智能体的自我介绍方式 修改智能体的显示名称
```yaml ```yaml
agent: agent:
@ -62,9 +62,9 @@ agent:
name: 'Spongebob' # 默认值:"Amelia" name: 'Spongebob' # 默认值:"Amelia"
``` ```
**角色** **角色`persona`**
替换智能体的个性、角色和沟通风格: 替换智能体的人设、职责和沟通风格:
```yaml ```yaml
persona: persona:
@ -76,11 +76,11 @@ persona:
- 'Favor composition over inheritance' - 'Favor composition over inheritance'
``` ```
`persona` 部分会替换整个默认角色,因此如果您设置它,请包含所有四个字段 `persona` 会覆盖默认整段配置,所以启用时请把四个字段都填全
**记忆** **记忆`memories`**
添加智能体将始终记住的持久上下文: 添加智能体会长期记住的上下文:
```yaml ```yaml
memories: memories:
@ -89,9 +89,9 @@ memories:
- 'Learned in Epic 1 that it is not cool to just pretend that tests have passed' - '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 ```yaml
menu: menu:
@ -103,18 +103,18 @@ menu:
description: Deploy to production description: Deploy to production
``` ```
**关键操作** **启动关键动作(`critical_actions`**
定义智能体启动时行的指令: 定义智能体启动时行的指令:
```yaml ```yaml
critical_actions: critical_actions:
- 'Check the CI Pipelines with the XYZ Skill and alert user on wake if anything is urgently needing attention' - '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 ```yaml
prompts: prompts:
@ -126,56 +126,51 @@ prompts:
3. Execute deployment script 3. Execute deployment script
``` ```
### 3. 应用您的更改 ### 3. 应用更改
编辑后,重新安装以应用更改 编辑完成后,重新安装以应用配置
```bash ```bash
npx bmad-method install npx bmad-method install
``` ```
安装程序会检测现有安装并提供以下选项: 安装程序会识别现有安装,并给出以下选项:
| Option | What It Does | | 选项 | 作用 |
| ---------------------------- | ------------------------------------------------------------------- | | ---------------------------- | ------------------------------------------------------------------- |
| **Quick Update** | 将所有模块更新到最新版本并应用自定义配置 | | **Quick Update** | 更新所有模块到最新版本,并应用你的自定义配置 |
| **Modify BMad Installation** | 用于添加或删除模块的完整安装流程 | | **Modify BMad Installation** | 进入完整安装流程,用于增删模块 |
对于仅自定义配置的更改,**Quick Update** 是最快的选项 如果只是调整 `.customize.yaml`,优先选 **Quick Update**
## 故障排 ## 故障排
**更改未生效?** **改动没有生效?**
- 运行 `npx bmad-method install` 并选择 **Quick Update** 以应用更改 - 运行 `npx bmad-method install` 并选择 **Quick Update** 以应用更改
- 检查您的 YAML 语法是否有效(缩进很重要 - 检查 YAML 语法是否正确(尤其是缩进
- 验证您编辑的是该智能体正确的 `.customize.yaml` 文件 - 确认你编辑的是目标智能体对应的 `.customize.yaml`
**智能体无法加载?** **智能体无法加载?**
- 使用在线 YAML 验证器检查 YAML 语法错误 - 使用在线 YAML 验证器检查 YAML 语法错误
- 确保取消注释后没有留空字段 - 确保取消注释后没有留空字段
- 尝试恢复到原始模板并重新构建 - 可先回退到模板,再逐项恢复自定义配置
**需要重置智能体?** **需要重置某个智能体?**
- 清空或删除智能体的 `.customize.yaml` 文件 - 清空或删除智能体的 `.customize.yaml` 文件
- 运行 `npx bmad-method install` 并选择 **Quick Update** 以恢复默认设置 - 运行 `npx bmad-method install` 并选择 **Quick Update** 以恢复默认设置
## 工作流自定义 ## 工作流自定义
对现有 BMad Method 工作流和技能的自定义即将推出。 对现有 BMad Method 工作流和技能的深度自定义能力即将推出。
## 模块自定义 ## 模块自定义
关于构建扩展模块和自定义现有模块的指南即将推出。 关于构建扩展模块和自定义现有模块的指南即将推出。
--- ## 后续步骤
## 术语说明
- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。 - [文档分片指南](./shard-large-documents.md) - 了解如何管理超长文档
- **workflow**:工作流。指一系列有序的任务或步骤,用于完成特定目标。 - [命令参考](../reference/commands.md) - 查看可用命令和工作流入口
- **persona**:角色。指智能体的身份、个性、沟通风格和行为原则的集合。
- **memory**:记忆。指智能体持久存储的上下文信息,用于在对话中保持连贯性。
- **critical action**:关键操作。指智能体启动时必须执行的指令或任务。
- **prompt**:提示。指发送给智能体的输入文本,用于引导其生成特定响应或执行特定操作。

View File

@ -5,19 +5,21 @@ sidebar:
order: 9 order: 9
--- ---
如果需要将大型 Markdown 文件拆分为更小、组织良好的文件以更好地管理上下文,请使用 `shard-doc` 工具 当单个 Markdown 文档过大、影响模型读取时,可使用 `bmad-shard-doc` 工作流把文档拆成按章节组织的小文件,降低上下文压力
:::caution[已弃用] :::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 ```bash
/bmad-shard-doc /bmad-shard-doc
``` ```
### 2. 遵循交互式流程 ### 2. 按交互流程完成分片
```text ```text
智能体:您想要分片哪个文档? 智能体:你想分片哪个文档?
用户docs/PRD.md 用户docs/PRD.md
智能体默认目标位置docs/prd/ 智能体默认目标位置docs/prd/
@ -60,27 +62,21 @@ _bmad-output/planning-artifacts/
✓ 完成! ✓ 完成!
``` ```
## 工作流发现机制 ## 工作流发现机制
BMad 工作流程使用**双重发现系统** BMad 工作流使用**双重发现机制**
1. **首先尝试完整文档** - 查找 `document-name.md` 1. **先查完整文档** - 查找 `document-name.md`
2. **检查分片版本** - 查找 `document-name/index.md` 2. **再查分片入口** - 查找 `document-name/index.md`
3. **优先级规则** - 如果两者都存在,完整文档优先 - 如果希望使用分片版本,请删除完整文档 3. **优先级规则** - 若两者并存,默认优先完整文档;若你要强制使用分片版本,请删除或重命名完整文档
## 工作流程支持 ## 你将获得
所有 BMM 工作流程都支持这两种格式: - 原始完整文档(可保留,但不建议与分片长期并存;并存时默认优先读取完整文档)
- 分片目录(如 `document-name/index.md` + 各章节文件)
- 对工作流透明的自动识别行为(无需额外配置)
- 完整文档 ## 后续步骤
- 分片文档
- 自动检测
- 对用户透明
--- - [如何自定义 BMad](./customize-bmad.md) - 了解高级配置与工作流定制边界
## 术语说明 - [如何升级到 v6](./upgrade-to-v6.md) - 在迁移过程中处理文档与目录结构变化
- **sharding**:分片。将大型文档或数据集拆分为更小、更易管理的部分的过程。
- **token**:令牌。在自然语言处理和大型语言模型中,文本的基本单位,通常对应单词或字符的一部分。
- **subprocesses**:子进程。由主进程创建的独立执行单元,可以并行运行以执行特定任务。
- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。

View File

@ -5,76 +5,83 @@ sidebar:
order: 3 order: 3
--- ---
使用 BMad 安装程序从 v4 升级到 v6其中包括自动检测旧版安装和迁移辅助 使用 BMad 安装程序把 v4 升级到 v6。安装程序会自动识别旧安装并提供迁移辅助帮助你在已有项目中平滑过渡
## 何时使用本指南 ## 何时使用本指南
- 您已安装 BMad v4`.bmad-method` 文件夹 - 你已安装 BMad v4目录名通常是 `.bmad-method`
- 您希望迁移到新的 v6 架 - 你准备迁移到 v6 的统一目录结
- 您有需要保留的现有规划产物 - 你有要保留的规划产物或进行中的开发工作
:::note[前置条件] :::note[前置条件]
- Node.js 20+ - Node.js 20+
- 现有 BMad v4 安装 - 现有 BMad v4 安装
::: :::
::::caution[先备份再迁移]
如果当前仓库里仍有未提交的重要变更,先完成提交或备份,再执行升级。
::::
## 步骤 ## 步骤
### 1. 运行安装程序 ### 1. 运行安装程序
按照[安装程序说明](./install-bmad.md)操作。 按照[安装程序说明](./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/`
- `.claude/commands/BMad/tasks`
v6 新技能会安装到:
- `.claude/skills/`
### 4. 迁移规划产物 ### 4. 迁移规划产物
**如果有规划文档Brief/PRD/UX/Architecture** **如果有规划文档Brief/PRD/UX/Architecture**
将它们移动到 `_bmad-output/planning-artifacts/` 并使用描述性名称 把它们移动到 `_bmad-output/planning-artifacts/`,并使用可读的文件名
- 在文件名中包含 `PRD` 用于 PRD 文档 - PRD 文档文件名包含 `PRD`
- 相应地包含 `brief`、`architecture` 或 `ux-design` - 其他文档按类型包含 `brief`、`architecture` 或 `ux-design`
- 分片文档可以放在命名的子文件夹 - 分片文档可放在命名清晰的子目录
**如果您正在进行规划:** 考虑使用 v6 工作流重新开始。将现有文档作为输入——新的渐进式发现工作流配合网络搜索和 IDE 计划模式会产生更好的结果。 **如果你仍在规划中:** 建议直接用 v6 工作流重启规划,把现有文档作为输入;新版渐进式发现流程配合 Web 搜索和 IDE 计划模式通常会得到更稳妥的结果。
### 5. 迁移进行中的开发 ### 5. 迁移进行中的开发工作
如果您已创建或实现了故事 如果你已经创建或实现了部分用户故事story
1. 完成 v6 安装 1. 完成 v6 安装
2. 将 `epics.md``epics/epic*.md` 放入 `_bmad-output/planning-artifacts/` 2. 将 `epics.md``epics/epic*.md` 放入 `_bmad-output/planning-artifacts/`
3. 运行 Scrum Master 的 `sprint-planning` 工作流 3. 运行 Scrum Master 的 `bmad-sprint-planning` 工作流
4. 告诉 SM 哪些史诗/故事已经完成 4. 告诉 SM 哪些史诗/故事已经完成
## 将获得 ## 将获得
**v6 统一结构:** **v6 统一结构:**
```text ```text
your-project/ your-project/
├── _bmad/ # 单一安装文件夹 ├── _bmad/ # 单一安装目录
│ ├── _config/ # 的自定义配置 │ ├── _config/ # 的自定义配置
│ │ └── agents/ # 智能体自定义文件 │ │ └── agents/ # 智能体自定义文件
│ ├── core/ # 通用核心框架 │ ├── core/ # 通用核心框架
│ ├── bmm/ # BMad Method 模块 │ ├── bmm/ # BMad Method 模块
│ ├── bmb/ # BMad Builder │ ├── bmb/ # BMad Builder
│ └── cis/ # Creative Intelligence Suite │ └── cis/ # Creative Intelligence Suite
└── _bmad-output/ # 输出文件夹v4 中为 doc 文件夹 └── _bmad-output/ # 输出目录v4 时代常见为 doc 目录
``` ```
## 模块迁移 ## 模块迁移
@ -87,34 +94,18 @@ your-project/
| `.bmad-infrastructure-devops` | 已弃用 — 新的 DevOps 智能体即将推出 | | `.bmad-infrastructure-devops` | 已弃用 — 新的 DevOps 智能体即将推出 |
| `.bmad-creative-writing` | 未适配 — 新的 v6 模块即将推出 | | `.bmad-creative-writing` | 未适配 — 新的 v6 模块即将推出 |
## 主要变更 ## 关键差异(旧名/新名)
| 概念 | v4 | v6 | | 概念 | v4 | v6 | 迁移提示 |
| ------------ | --------------------------------------- | ------------------------------------ | | ------------ | --------------------------------------- | ------------------------------------ | ------------------------------------ |
| **核心** | `_bmad-core` 实际上是 BMad Method | `_bmad/core/` 是通用框架 | | **核心框架** | `_bmad-core` 实际上承载的是 BMad Method | `_bmad/core/` 变成通用框架层 | 迁移时不要再把 `_bmad/core/` 当成 Method 本体 |
| **方法** | `_bmad-method` | `_bmad/bmm/` | | **方法模块** | `_bmad-method` | `_bmad/bmm/` | 旧脚本、路径引用需同步更新到 `bmm` |
| **配置** | 直接修改文件 | 每个模块使用 `config.yaml` | | **配置方式** | 直接改模块文件 | 每个模块通过 `config.yaml` 管理 | 优先改配置,不要直接改生成文件 |
| **文档** | 需要设置分片或非分片 | 完全灵活,自动扫描 | | **文档读取** | 需要手动区分分片/非分片 | 自动扫描完整文档与分片入口 | 只有在兼容性场景下才建议手动分片 |
--- ## 后续建议
## 术语说明
- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。 - 升级完成后先运行 `bmad-help`,确认可用工作流与下一步建议
- **epic**:史诗。在敏捷开发中,指大型的工作项,可分解为多个用户故事。 - 如果是既有项目,补充或更新 `project-context.md`,减少后续实现偏差
- **story**:故事。在敏捷开发中,指用户故事,描述用户需求的功能单元。 - 在继续开发前,先做一次关键链路验证(安装、命令触发、文档读取)
- **Scrum Master**Scrum 主管。敏捷开发 Scrum 框架中的角色,负责促进团队流程和移除障碍。 - 继续阅读:[如何安装 BMad](./install-bmad.md)、[管理项目上下文](./project-context.md)
- **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 中的一种工作模式,用于规划和设计任务。

View File

@ -68,7 +68,7 @@ BMad MethodBMM是 BMad 生态系统中的一个模块,旨在遵循上下
| 工作流程 | 目的 | 产出 | | 工作流程 | 目的 | 产出 |
| --------------------- | --------------------------------------------------------------------------- | --------------------------- | | --------------------- | --------------------------------------------------------------------------- | --------------------------- |
| `bmad-bmm-quick-dev` | 统一快速流程 — 澄清意图、规划、实现、审查和呈现 | `tech-spec.md` + 代码 | | `bmad-bmm-quick-dev` | 统一快速流程 — 澄清意图、规划、实现、审查和呈现 | `spec-*.md` + 代码 |
## 上下文管理 ## 上下文管理

View File

@ -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 | | 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 | | 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 | | 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 | | Document Project | `{project_knowledge}/index.md` (sharded) | INDEX_GUIDED |
### Context ### 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. **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`) 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**: 3. **If sharded version found**:
- Read `index.md` to understand the document structure - 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. **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.
<workflow> <workflow>

View File

@ -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. Cohesive cross-layer stories (DB+BE+UI) stay in ONE file.
IMPORTANT: Remove all HTML comments when filling this template. --> IMPORTANT: Remove all HTML comments when filling this template. -->
# {title}
<frozen-after-approval reason="human-owned intent — do not modify unless human renegotiates"> <frozen-after-approval reason="human-owned intent — do not modify unless human renegotiates">
## Intent ## Intent

View File

@ -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' deferred_work_file: '{implementation_artifacts}/deferred-work.md'
spec_file: '' # set at runtime for plan-code-review before leaving this step 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. - 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. - **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. 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:
- 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` 1. Explicit argument
- If `in-review` selected: Set `spec_file`. **EARLY EXIT**`./step-04-review.md` Did the user pass a specific file path, spec name, or clear instruction this message?
- 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. - 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 ## INSTRUCTIONS
@ -42,7 +56,7 @@ spec_file: '' # set at runtime for plan-code-review before leaving this step
**EARLY EXIT**`./step-oneshot.md` **EARLY EXIT**`./step-oneshot.md`
**b) Plan-code-review** — everything else. When uncertain whether blast radius is truly zero, choose this path. **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 ## NEXT

View File

@ -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' deferred_work_file: '{implementation_artifacts}/deferred-work.md'
--- ---
@ -13,7 +13,7 @@ deferred_work_file: '{implementation_artifacts}/deferred-work.md'
## INSTRUCTIONS ## 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._ 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. 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. 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: 5. Token count check (see SCOPE STANDARD). If spec exceeds 1600 tokens:

View File

@ -72,7 +72,7 @@ YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `
### 2. Paths ### 2. Paths
- `wipFile` = `{implementation_artifacts}/tech-spec-wip.md` - `wipFile` = `{implementation_artifacts}/spec-wip.md`
### 3. First Step Execution ### 3. First Step Execution

View File

@ -1,7 +1,7 @@
module,phase,name,code,sequence,workflow-file,command,required,agent,options,description,output-location,outputs, 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,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,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 quick flow: clarify intent plan implement review and present in a single workflow",implementation_artifacts,"tech spec and project implementation", 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,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,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", 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",

1 module phase name code sequence workflow-file command required agent options description output-location outputs
2 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 *
3 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. 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
4 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 Unified intent-in code-out workflow: clarify plan implement review and present implementation_artifacts tech spec and project implementation spec and project implementation
5 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
6 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
7 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

View File

@ -14,6 +14,7 @@
const path = require('node:path'); const path = require('node:path');
const os = require('node:os'); const os = require('node:os');
const fs = require('fs-extra'); 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 { ManifestGenerator } = require('../tools/cli/installers/lib/core/manifest-generator');
const { IdeManager } = require('../tools/cli/installers/lib/ide/manager'); const { IdeManager } = require('../tools/cli/installers/lib/ide/manager');
const { clearCache, loadPlatformCodes } = require('../tools/cli/installers/lib/ide/platform-codes'); const { clearCache, loadPlatformCodes } = require('../tools/cli/installers/lib/ide/platform-codes');
@ -1853,6 +1854,93 @@ async function runTests() {
console.log(''); 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 // Summary
// ============================================================ // ============================================================

View File

@ -5,7 +5,7 @@
* This file ensures proper execution when run via npx from GitHub or npm registry * 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 path = require('node:path');
const fs = require('node:fs'); const fs = require('node:fs');
@ -25,7 +25,7 @@ if (isNpxExecution) {
try { try {
// Execute CLI from user's working directory (process.cwd()), not npm cache // Execute CLI from user's working directory (process.cwd()), not npm cache
execSync(`node "${bmadCliPath}" ${args.join(' ')}`, { execFileSync('node', [bmadCliPath, ...args], {
stdio: 'inherit', stdio: 'inherit',
cwd: process.cwd(), // This preserves the user's working directory cwd: process.cwd(), // This preserves the user's working directory
}); });

View File

@ -954,31 +954,123 @@ class ConfigCollector {
return match; return match;
} }
// Look for the config value in allAnswers (already answered questions) const configValue = this.resolveConfigValue(configKey, currentModule, moduleConfig);
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;
}
}
return configValue || match; 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 * Build a prompt question from a config item
* @param {string} moduleName - Module name * @param {string} moduleName - Module name
@ -993,12 +1085,7 @@ class ConfigCollector {
let existingValue = null; let existingValue = null;
if (this.existingConfig && this.existingConfig[moduleName]) { if (this.existingConfig && this.existingConfig[moduleName]) {
existingValue = this.existingConfig[moduleName][key]; existingValue = this.existingConfig[moduleName][key];
existingValue = this.normalizeExistingValueForPrompt(existingValue, moduleName, item, moduleConfig);
// 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}/', '');
}
} }
// Special handling for user_name: default to system user // Special handling for user_name: default to system user