Compare commits
7 Commits
957c53f7d0
...
42e6dac9a4
| Author | SHA1 | Date |
|---|---|---|
|
|
42e6dac9a4 | |
|
|
303e7ae290 | |
|
|
48152507e2 | |
|
|
b3cf338118 | |
|
|
fc2b253ab5 | |
|
|
ac5cb9de5c | |
|
|
51b6d0896a |
|
|
@ -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:**
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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:**
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,8 @@ sidebar:
|
||||||
对于任何规范或计划,事前复盘都是一个很好的首选。它始终能找到标准审查会遗漏的空白。
|
对于任何规范或计划,事前复盘都是一个很好的首选。它始终能找到标准审查会遗漏的空白。
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
如果你还处在方向发散阶段,可先用 [头脑风暴](./brainstorming.md);如果你需要多角色权衡讨论,可用 [派对模式](./party-mode.md)。在进入实现前做问题发现时,可结合 [对抗性评审](./adversarial-review.md)。
|
||||||
|
|
||||||
---
|
---
|
||||||
## 术语说明
|
## 术语说明
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ sidebar:
|
||||||
对抗性评审产生:
|
对抗性评审产生:
|
||||||
|
|
||||||
> 1. **高** - `login.ts:47` - 失败尝试没有速率限制
|
> 1. **高** - `login.ts:47` - 失败尝试没有速率限制
|
||||||
> 2. **高** - 会话令牌存储在 localStorage 中(易受 XSS 攻击)
|
> 2. **高** - 会话令牌存储在 `localStorage` 中(易受 XSS 攻击)
|
||||||
> 3. **中** - 密码验证仅在客户端进行
|
> 3. **中** - 密码验证仅在客户端进行
|
||||||
> 4. **中** - 失败登录尝试没有审计日志
|
> 4. **中** - 失败登录尝试没有审计日志
|
||||||
> 5. **低** - 魔法数字 `3600` 应该是 `SESSION_TIMEOUT_SECONDS`
|
> 5. **低** - 魔法数字 `3600` 应该是 `SESSION_TIMEOUT_SECONDS`
|
||||||
|
|
@ -58,6 +58,8 @@ sidebar:
|
||||||
假设问题存在。寻找缺失的内容,而不仅仅是错误的内容。
|
假设问题存在。寻找缺失的内容,而不仅仅是错误的内容。
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
如果你想把该策略放进快速实现节奏中,可参见 [快速开发](./quick-dev.md);若要做多轮推理补强,可参见 [高级启发](./advanced-elicitation.md)。整体流程位置请见 [工作流地图](../reference/workflow-map.md)。
|
||||||
|
|
||||||
---
|
---
|
||||||
## 术语说明
|
## 术语说明
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ sidebar:
|
||||||
|
|
||||||
## 什么是头脑风暴?
|
## 什么是头脑风暴?
|
||||||
|
|
||||||
运行 `brainstorming`,你就拥有了一位创意引导者,帮助你从自身挖掘想法——而不是替你生成想法。AI 充当教练和向导,使用经过验证的技术,创造让你最佳思维涌现的条件。
|
运行 `bmad-brainstorming`,你就拥有了一位创意引导者,帮助你从自身挖掘想法——而不是替你生成想法。AI 充当教练和向导,使用经过验证的技术,创造让你最佳思维涌现的条件。
|
||||||
|
|
||||||
**适用于:**
|
**适用于:**
|
||||||
|
|
||||||
|
|
@ -32,6 +32,8 @@ sidebar:
|
||||||
每个想法都来自你。工作流程创造洞察的条件——你是源头。
|
每个想法都来自你。工作流程创造洞察的条件——你是源头。
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
想继续深化现有输出,可参考 [高级启发](./advanced-elicitation.md);需要多角色协同讨论,可参考 [派对模式](./party-mode.md)。若要查看它在整体流程中的位置,请参见 [工作流地图](../reference/workflow-map.md)。
|
||||||
|
|
||||||
---
|
---
|
||||||
## 术语说明
|
## 术语说明
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,12 @@ sidebar:
|
||||||
|
|
||||||
## 问题
|
## 问题
|
||||||
|
|
||||||
- [我必须先运行 document-project 吗?](#我必须先运行-document-project-吗)
|
- [我必须先运行 bmad-document-project 吗?](#我必须先运行-bmad-document-project-吗)
|
||||||
- [如果我忘记运行 document-project 怎么办?](#如果我忘记运行-document-project-怎么办)
|
- [如果我忘记运行 bmad-document-project 怎么办?](#如果我忘记运行-bmad-document-project-怎么办)
|
||||||
- [我可以在既有项目上使用快速流程吗?](#我可以在既有项目上使用快速流程吗)
|
- [我可以在既有项目上使用 bmad-quick-dev 吗?](#我可以在既有项目上使用-bmad-quick-dev-吗)
|
||||||
- [如果我的现有代码不遵循最佳实践怎么办?](#如果我的现有代码不遵循最佳实践怎么办)
|
- [如果我的现有代码不遵循最佳实践怎么办?](#如果我的现有代码不遵循最佳实践怎么办)
|
||||||
|
|
||||||
### 我必须先运行 document-project 吗?
|
### 我必须先运行 bmad-document-project 吗?
|
||||||
|
|
||||||
强烈推荐,特别是如果:
|
强烈推荐,特别是如果:
|
||||||
|
|
||||||
|
|
@ -23,11 +23,11 @@ sidebar:
|
||||||
|
|
||||||
如果你拥有全面且最新的文档,包括 `docs/index.md`,或者将使用其他工具或技术来帮助智能体发现现有系统,则可以跳过此步骤。
|
如果你拥有全面且最新的文档,包括 `docs/index.md`,或者将使用其他工具或技术来帮助智能体发现现有系统,则可以跳过此步骤。
|
||||||
|
|
||||||
### 如果我忘记运行 document-project 怎么办?
|
### 如果我忘记运行 bmad-document-project 怎么办?
|
||||||
|
|
||||||
不用担心——你可以随时执行。你甚至可以在项目期间或项目之后执行,以帮助保持文档最新。
|
不用担心——你可以随时执行。你甚至可以在项目期间或项目之后执行,以帮助保持文档最新。
|
||||||
|
|
||||||
### 我可以在既有项目上使用快速流程吗?
|
### 我可以在既有项目上使用 bmad-quick-dev 吗?
|
||||||
|
|
||||||
可以!快速流程在既有项目上效果很好。它将:
|
可以!快速流程在既有项目上效果很好。它将:
|
||||||
|
|
||||||
|
|
@ -49,12 +49,14 @@ BMM 尊重你的选择——它不会强制现代化,但会提供现代化选
|
||||||
|
|
||||||
**有未在此处回答的问题吗?** 请[提出问题](https://github.com/bmad-code-org/BMAD-METHOD/issues)或在 [Discord](https://discord.gg/gk8jAdXWmj) 中提问,以便我们添加它!
|
**有未在此处回答的问题吗?** 请[提出问题](https://github.com/bmad-code-org/BMAD-METHOD/issues)或在 [Discord](https://discord.gg/gk8jAdXWmj) 中提问,以便我们添加它!
|
||||||
|
|
||||||
|
如果你想了解这套接入方式的操作步骤,可继续阅读 [How-to:既有项目](../how-to/established-projects.md) 与 [How-to:项目上下文](../how-to/project-context.md)。想理解快速流程在方法论中的定位,可参见 [快速开发](./quick-dev.md)。
|
||||||
|
|
||||||
---
|
---
|
||||||
## 术语说明
|
## 术语说明
|
||||||
|
|
||||||
- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。
|
- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。
|
||||||
- **Quick Flow**:快速流程。BMad 方法中的一种工作流程,用于快速处理既有项目。
|
- **Quick Flow**:快速流程。BMad 方法中的一种工作流程,用于快速处理既有项目。
|
||||||
- **tech-spec**:技术规范。描述技术实现细节和标准的文档。
|
- **spec**:规范。描述技术实现细节和标准的文档。
|
||||||
- **stack**:技术栈。项目所使用的技术组合,包括框架、库、工具等。
|
- **stack**:技术栈。项目所使用的技术组合,包括框架、库、工具等。
|
||||||
- **conventions**:约定。代码库中遵循的编码风格、命名规则等规范。
|
- **conventions**:约定。代码库中遵循的编码风格、命名规则等规范。
|
||||||
- **modernization**:现代化。将旧代码或系统更新为更现代的技术和最佳实践的过程。
|
- **modernization**:现代化。将旧代码或系统更新为更现代的技术和最佳实践的过程。
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@ sidebar:
|
||||||
|
|
||||||
将所有 AI 智能体汇聚到一次对话中。
|
将所有 AI 智能体汇聚到一次对话中。
|
||||||
|
|
||||||
## 什么是 Party Mode?
|
## 什么是派对模式(Party Mode)?
|
||||||
|
|
||||||
运行 `party-mode`,你的整个 AI 团队就齐聚一堂——PM、架构师、开发者、UX 设计师,任何你需要的人。BMad Master 负责编排,根据每条消息选择相关的智能体。智能体以角色身份回应,彼此同意、反对,并在彼此的想法基础上继续构建。
|
运行 `bmad-party-mode`,你的整个 AI 团队就齐聚一堂——PM、架构师、开发者、UX 设计师,任何你需要的人。BMad Master 负责编排,根据每条消息选择相关的智能体。智能体以角色身份回应,彼此同意、反对,并在彼此的想法基础上继续构建。
|
||||||
|
|
||||||
对话可以持续到你想要的时间。提出追问、对答案提出质疑、引导讨论方向——这是与智能体之间真正的来回交流,直到你完成目标。
|
对话可以持续到你想要的时间。提出追问、对答案提出质疑、引导讨论方向——这是与智能体之间真正的来回交流,直到你完成目标。
|
||||||
|
|
||||||
|
|
@ -24,40 +24,42 @@ sidebar:
|
||||||
|
|
||||||
### 指出糟糕的架构
|
### 指出糟糕的架构
|
||||||
|
|
||||||
**You:** "好了团队,我们上个冲刺是一场灾难。认证服务宕机了三次。谁搞砸了这件事?"
|
**你:** "好了团队,我们上个冲刺是一场灾难。认证服务宕机了三次。谁搞砸了这件事?"
|
||||||
|
|
||||||
**Architect:** "设计本身是合理的——分布式认证,有适当的回退机制。如果实现偏离了规范……"
|
**架构师:** "设计本身是合理的——分布式认证,有适当的回退机制。如果实现偏离了规范……"
|
||||||
|
|
||||||
**Dev:** "我完全按照架构文档执行的。规范没有考虑到并发会话失效的竞态条件。"
|
**开发者:** "我完全按照架构文档执行的。规范没有考虑到并发会话失效的竞态条件。"
|
||||||
|
|
||||||
**PM:** "你们两个都忽略了更大的问题——我们没有在 PRD 中验证会话管理需求。这是我的错,没有发现这一点。"
|
**产品经理:** "你们两个都忽略了更大的问题——我们没有在 PRD 中验证会话管理需求。这是我的错,没有发现这一点。"
|
||||||
|
|
||||||
**TEA:** "我也应该在集成测试中发现这一点。测试场景没有覆盖并发失效。"
|
**TEA 测试架构师:** "我也应该在集成测试中发现这一点。测试场景没有覆盖并发失效。"
|
||||||
|
|
||||||
### 创意头脑风暴
|
### 创意头脑风暴
|
||||||
|
|
||||||
**You:** "我们如何让入职体验变得神奇,而不是无聊?"
|
**你:** "我们如何让入职体验变得神奇,而不是无聊?"
|
||||||
|
|
||||||
**UX Designer:** "从渐进式披露开始——在用户需要时揭示功能,而不是在教程中一次性展示所有内容。"
|
**UX 设计师:** "从渐进式披露开始——在用户需要时揭示功能,而不是在教程中一次性展示所有内容。"
|
||||||
|
|
||||||
**Storyteller:** "如果入职是一个故事会怎样?每一步都揭示一个角色的旅程——用户就是英雄。"
|
**叙事设计师:** "如果入职是一个故事会怎样?每一步都揭示一个角色的旅程——用户就是英雄。"
|
||||||
|
|
||||||
**Game Designer:** "在此基础上——如果第一个'任务'实际上是解决一个真实的用户问题会怎样?他们通过做有价值的事情来学习。"
|
**游戏设计师:** "在此基础上——如果第一个'任务'实际上是解决一个真实的用户问题会怎样?他们通过做有价值的事情来学习。"
|
||||||
|
|
||||||
### 技术决策
|
### 技术决策
|
||||||
|
|
||||||
**You:** "MVP 用单体还是微服务?"
|
**你:** "MVP 用单体还是微服务?"
|
||||||
|
|
||||||
**Architect:** "从单体开始。微服务会增加你在 1000 用户时不需要的复杂性。"
|
**架构师:** "从单体开始。微服务会增加你在 1000 用户时不需要的复杂性。"
|
||||||
|
|
||||||
**PM:** "同意。上市时间比理论上的可扩展性更重要。"
|
**产品经理:** "同意。上市时间比理论上的可扩展性更重要。"
|
||||||
|
|
||||||
**Dev:** "单体,但要有清晰的模块边界。如果需要,我们以后可以提取服务。"
|
**开发者:** "单体,但要有清晰的模块边界。如果需要,我们以后可以提取服务。"
|
||||||
|
|
||||||
:::tip[Better Decisions]
|
:::tip[更好的决策]
|
||||||
通过多元视角做出更好的决策。欢迎来到 party mode。
|
通过多元视角做出更好的决策。欢迎使用派对模式。
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
若你的目标是结构化发散创意,可先参考 [头脑风暴](./brainstorming.md);若你已经有初稿并想做二次推理补强,可参考 [高级启发](./advanced-elicitation.md)。完整阶段位置见 [工作流地图](../reference/workflow-map.md)。
|
||||||
|
|
||||||
---
|
---
|
||||||
## 术语说明
|
## 术语说明
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,9 +108,11 @@ PRD:"构建什么"
|
||||||
- 记录跨越 epic 边界的决策
|
- 记录跨越 epic 边界的决策
|
||||||
- 专注于容易产生冲突的领域
|
- 专注于容易产生冲突的领域
|
||||||
- 随着学习更新架构
|
- 随着学习更新架构
|
||||||
- 对重大变更使用 `correct-course`
|
- 对重大变更使用 `bmad-correct-course`
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
如需先理解为什么要在实施前做 solutioning,可阅读 [为什么解决方案设计很重要](./why-solutioning-matters.md);如果你想把这些约束落地到项目执行,可继续看 [项目上下文](./project-context.md)。流程全景见 [工作流地图](../reference/workflow-map.md)。
|
||||||
|
|
||||||
---
|
---
|
||||||
## 术语说明
|
## 术语说明
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,12 @@ AI 智能体不断做出实施决策——遵循哪些模式、如何组织代
|
||||||
每个实施工作流都会自动加载 `project-context.md`(如果存在)。架构师工作流也会加载它,以便在设计架构时尊重您的技术偏好。
|
每个实施工作流都会自动加载 `project-context.md`(如果存在)。架构师工作流也会加载它,以便在设计架构时尊重您的技术偏好。
|
||||||
|
|
||||||
**由以下工作流加载:**
|
**由以下工作流加载:**
|
||||||
- `create-architecture` — 在解决方案设计期间尊重技术偏好
|
- `bmad-create-architecture` — 在解决方案设计期间尊重技术偏好
|
||||||
- `create-story` — 使用项目模式指导用户故事创建
|
- `bmad-create-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` — 提供项目范围的上下文
|
||||||
|
|
||||||
## 何时创建
|
## 何时创建
|
||||||
|
|
||||||
|
|
@ -34,10 +34,10 @@ AI 智能体不断做出实施决策——遵循哪些模式、如何组织代
|
||||||
|
|
||||||
| 场景 | 何时创建 | 目的 |
|
| 场景 | 何时创建 | 目的 |
|
||||||
|----------|----------------|---------|
|
|----------|----------------|---------|
|
||||||
| **新项目,架构之前** | 手动,在 `create-architecture` 之前 | 记录您的技术偏好,以便架构师尊重它们 |
|
| **新项目,架构之前** | 手动,在 `bmad-create-architecture` 之前 | 记录您的技术偏好,以便架构师尊重它们 |
|
||||||
| **新项目,架构之后** | 通过 `generate-project-context` 或手动 | 捕获架构决策,供实施智能体使用 |
|
| **新项目,架构之后** | 通过 `bmad-generate-project-context` 或手动 | 捕获架构决策,供实施智能体使用 |
|
||||||
| **现有项目** | 通过 `generate-project-context` | 发现现有模式,以便智能体遵循既定约定 |
|
| **现有项目** | 通过 `bmad-generate-project-context` | 发现现有模式,以便智能体遵循既定约定 |
|
||||||
| **快速流程项目** | 在 `quick-dev` 之前或期间 | 确保快速实施尊重您的模式 |
|
| **快速流程项目** | 在 `bmad-quick-dev` 之前或期间 | 确保快速实施尊重您的模式 |
|
||||||
|
|
||||||
:::tip[推荐]
|
:::tip[推荐]
|
||||||
对于新项目,如果您有强烈的技术偏好,请在架构之前手动创建。否则,在架构之后生成它以捕获这些决策。
|
对于新项目,如果您有强烈的技术偏好,请在架构之前手动创建。否则,在架构之后生成它以捕获这些决策。
|
||||||
|
|
@ -107,20 +107,20 @@ touch _bmad-output/project-context.md
|
||||||
|
|
||||||
### 架构后生成
|
### 架构后生成
|
||||||
|
|
||||||
在完成架构后运行 `generate-project-context` 工作流:
|
在完成架构后运行 `bmad-generate-project-context` 工作流:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/bmad-bmm-generate-project-context
|
/bmad-generate-project-context
|
||||||
```
|
```
|
||||||
|
|
||||||
这将扫描您的架构文档和项目文件,生成一个捕获所做决策的上下文文件。
|
这将扫描您的架构文档和项目文件,生成一个捕获所做决策的上下文文件。
|
||||||
|
|
||||||
### 为现有项目生成
|
### 为现有项目生成
|
||||||
|
|
||||||
对于现有项目,运行 `generate-project-context` 以发现现有模式:
|
对于现有项目,运行 `bmad-generate-project-context` 以发现现有模式:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/bmad-bmm-generate-project-context
|
/bmad-generate-project-context
|
||||||
```
|
```
|
||||||
|
|
||||||
该工作流分析您的代码库以识别约定,然后生成一个您可以审查和优化的上下文文件。
|
该工作流分析您的代码库以识别约定,然后生成一个您可以审查和优化的上下文文件。
|
||||||
|
|
@ -150,12 +150,14 @@ touch _bmad-output/project-context.md
|
||||||
- 模式在实施过程中演变
|
- 模式在实施过程中演变
|
||||||
- 您从智能体行为中发现差距
|
- 您从智能体行为中发现差距
|
||||||
|
|
||||||
您可以随时手动编辑它,或者在重大更改后重新运行 `generate-project-context` 来更新它。
|
您可以随时手动编辑它,或者在重大更改后重新运行 `bmad-generate-project-context` 来更新它。
|
||||||
|
|
||||||
:::note[文件位置]
|
:::note[文件位置]
|
||||||
默认位置是 `_bmad-output/project-context.md`。工作流在那里搜索它,并且还会检查项目中任何位置的 `**/project-context.md`。
|
默认位置是 `_bmad-output/project-context.md`。工作流在那里搜索它,并且还会检查项目中任何位置的 `**/project-context.md`。
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
如需可执行步骤说明,请阅读 [How-to:项目上下文](../how-to/project-context.md);如果你在既有项目落地这套机制,可参考 [既有项目常见问题](./established-projects-faq.md)。整体流程定位见 [工作流地图](../reference/workflow-map.md)。
|
||||||
|
|
||||||
---
|
---
|
||||||
## 术语说明
|
## 术语说明
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,3 +71,5 @@ sidebar:
|
||||||
一些发现属于当前变更。一些不属于。如果一个发现是附带的而不是与当前工作有因果关系,工作流可以推迟它,而不是强迫人类立即处理它。这使运行保持专注,并防止随机的分支话题消耗注意力的预算。
|
一些发现属于当前变更。一些不属于。如果一个发现是附带的而不是与当前工作有因果关系,工作流可以推迟它,而不是强迫人类立即处理它。这使运行保持专注,并防止随机的分支话题消耗注意力的预算。
|
||||||
|
|
||||||
那个分诊有时会不完美。这是可以接受的。通常,误判一些发现比用成千上万个低价值的审查评论淹没人类要好。系统正在优化信号质量,而不是详尽的召回率。
|
那个分诊有时会不完美。这是可以接受的。通常,误判一些发现比用成千上万个低价值的审查评论淹没人类要好。系统正在优化信号质量,而不是详尽的召回率。
|
||||||
|
|
||||||
|
想进一步理解审查策略,可继续阅读 [对抗性评审](./adversarial-review.md);需要对已有输出进行第二轮推理时,可参考 [高级启发](./advanced-elicitation.md)。若要查看它在完整流程中的位置,请参见 [工作流地图](../reference/workflow-map.md)。
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,8 @@ sidebar:
|
||||||
在解决方案阶段发现对齐问题比在实施期间发现要快 10 倍。
|
在解决方案阶段发现对齐问题比在实施期间发现要快 10 倍。
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
想进一步理解冲突是如何发生并被架构约束消除的,可继续阅读 [防止智能体冲突](./preventing-agent-conflicts.md)。如果你要把这些约束落到执行层,请结合 [项目上下文](./project-context.md) 与 [工作流地图](../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` + 代码 |
|
||||||
|
|
||||||
## 上下文管理
|
## 上下文管理
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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).
|
|
||||||
|
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 `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`
|
- 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.
|
- 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
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
|
@ -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
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
|
||||||
|
|
@ -954,8 +954,49 @@ class ConfigCollector {
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
// Look for the config value in allAnswers (already answered questions)
|
||||||
let configValue = this.allAnswers[configKey] || this.allAnswers[`core_${configKey}`];
|
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
|
// Check in already collected config
|
||||||
if (!configValue) {
|
if (!configValue) {
|
||||||
|
|
@ -967,6 +1008,16 @@ class ConfigCollector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 still not found and we're in the same module, use the default from the config schema
|
||||||
if (!configValue && currentModule && moduleConfig && moduleConfig[configKey]) {
|
if (!configValue && currentModule && moduleConfig && moduleConfig[configKey]) {
|
||||||
const referencedItem = moduleConfig[configKey];
|
const referencedItem = moduleConfig[configKey];
|
||||||
|
|
@ -975,8 +1026,49 @@ class ConfigCollector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return configValue || match;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue