Compare commits
8 Commits
4ef78f34a8
...
3b501de13b
| Author | SHA1 | Date |
|---|---|---|
|
|
3b501de13b | |
|
|
90d9d880b6 | |
|
|
0c245474c4 | |
|
|
303e7ae290 | |
|
|
48152507e2 | |
|
|
b3cf338118 | |
|
|
fc2b253ab5 | |
|
|
ac5cb9de5c |
|
|
@ -56,7 +56,7 @@ Critical warnings only — data loss, security issues
|
|||
| Phase | Name | What Happens |
|
||||
| ----- | -------- | -------------------------------------------- |
|
||||
| 1 | Analysis | Brainstorm, research *(optional)* |
|
||||
| 2 | Planning | Requirements — PRD or tech-spec *(required)* |
|
||||
| 2 | Planning | Requirements — PRD or spec *(required)* |
|
||||
```
|
||||
|
||||
**Skills:**
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ Yes! Quick Flow works great for established projects. It will:
|
|||
- Auto-detect your existing stack
|
||||
- Analyze existing code patterns
|
||||
- Detect conventions and ask for confirmation
|
||||
- Generate context-rich tech-spec that respects existing code
|
||||
- Generate context-rich spec that respects existing code
|
||||
|
||||
Perfect for bug fixes and small features in existing codebases.
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ Perfect for bug fixes and small features in existing codebases.
|
|||
Quick Flow detects your conventions and asks: "Should I follow these existing conventions?" You decide:
|
||||
|
||||
- **Yes** → Maintain consistency with current codebase
|
||||
- **No** → Establish new standards (document why in tech-spec)
|
||||
- **No** → Establish new standards (document why in spec)
|
||||
|
||||
BMM respects your choice — it won't force modernization, but it will offer it.
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ Every implementation workflow automatically loads `project-context.md` if it exi
|
|||
- `bmad-create-story` — informs story creation with project patterns
|
||||
- `bmad-dev-story` — guides implementation decisions
|
||||
- `bmad-code-review` — validates against project standards
|
||||
- `bmad-quick-dev` — applies patterns when implementing tech-specs
|
||||
- `bmad-quick-dev` — applies patterns when implementing specs
|
||||
- `bmad-sprint-planning`, `bmad-retrospective`, `bmad-correct-course` — provides project-wide context
|
||||
|
||||
## When to Create It
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ Sautez les phases 1-3 pour les travaux de faible envergure et bien compris.
|
|||
|
||||
| Workflow | Objectif | Produit |
|
||||
|------------------|-------------------------------------------------------------------------------------|-----------------------|
|
||||
| `bmad-quick-dev` | Flux rapide unifié — clarifie l'intention, planifie, implémente, révise et présente | `tech-spec.md` + code |
|
||||
| `bmad-quick-dev` | Flux rapide unifié — clarifie l'intention, planifie, implémente, révise et présente | `spec-*.md` + code |
|
||||
|
||||
## Gestion du Contexte
|
||||
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ your-project/
|
|||
## Questions fréquentes
|
||||
|
||||
**Ai-je toujours besoin d'une architecture ?**
|
||||
Uniquement pour les voies méthode BMad et Enterprise. Quick Dev passe directement de la spécification technique (tech-spec) à l'implémentation.
|
||||
Uniquement pour les voies méthode BMad et Enterprise. Quick Dev passe directement de la spécification technique (spec) à l'implémentation.
|
||||
|
||||
**Puis-je modifier mon plan plus tard ?**
|
||||
Oui. Utilisez `bmad-correct-course` pour gérer les changements de périmètre.
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ Skip phases 1-3 for small, well-understood work.
|
|||
|
||||
| Workflow | Purpose | Produces |
|
||||
| ------------------ | --------------------------------------------------------------------------- | ---------------------- |
|
||||
| `bmad-quick-dev` | Unified quick flow — clarify intent, plan, implement, review, and present | `tech-spec.md` + code |
|
||||
| `bmad-quick-dev` | Unified quick flow — clarify intent, plan, implement, review, and present | `spec-*.md` + code |
|
||||
|
||||
## Context Management
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ BMad helps you build software through guided workflows with specialized AI agent
|
|||
| Phase | Name | What Happens |
|
||||
| ----- | -------------- | --------------------------------------------------- |
|
||||
| 1 | Analysis | Brainstorming, research, product brief *(optional)* |
|
||||
| 2 | Planning | Create requirements (PRD or tech-spec) |
|
||||
| 2 | Planning | Create requirements (PRD or spec) |
|
||||
| 3 | Solutioning | Design architecture *(BMad Method/Enterprise only)* |
|
||||
| 4 | Implementation | Build epic by epic, story by story |
|
||||
|
||||
|
|
@ -237,7 +237,7 @@ your-project/
|
|||
## Common Questions
|
||||
|
||||
**Do I always need architecture?**
|
||||
Only for BMad Method and Enterprise tracks. Quick Flow skips from tech-spec to implementation.
|
||||
Only for BMad Method and Enterprise tracks. Quick Flow skips from spec to implementation.
|
||||
|
||||
**Can I change my plan later?**
|
||||
Yes. The SM agent has a `bmad-correct-course` workflow (`bmad-correct-course`) for handling scope changes.
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ Critical warnings only — data loss, security issues
|
|||
| Phase | Name | What Happens |
|
||||
| ----- | -------- | -------------------------------------------- |
|
||||
| 1 | Analysis | Brainstorm, research *(optional)* |
|
||||
| 2 | Planning | Requirements — PRD or tech-spec *(required)* |
|
||||
| 2 | Planning | Requirements — PRD or spec *(required)* |
|
||||
```
|
||||
|
||||
**Commands:**
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ BMM 尊重你的选择——它不会强制现代化,但会提供现代化选
|
|||
|
||||
- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。
|
||||
- **Quick Flow**:快速流程。BMad 方法中的一种工作流程,用于快速处理既有项目。
|
||||
- **tech-spec**:技术规范。描述技术实现细节和标准的文档。
|
||||
- **spec**:规范。描述技术实现细节和标准的文档。
|
||||
- **stack**:技术栈。项目所使用的技术组合,包括框架、库、工具等。
|
||||
- **conventions**:约定。代码库中遵循的编码风格、命名规则等规范。
|
||||
- **modernization**:现代化。将旧代码或系统更新为更现代的技术和最佳实践的过程。
|
||||
|
|
|
|||
|
|
@ -5,56 +5,56 @@ sidebar:
|
|||
order: 7
|
||||
---
|
||||
|
||||
使用 `.customize.yaml` 文件来调整智能体行为、角色和菜单,同时在更新过程中保留您的更改。
|
||||
使用 `.customize.yaml` 文件,自定义智能体(agent)的行为、角色(persona)和菜单,同时在后续更新中保留你的改动。
|
||||
|
||||
## 何时使用此功能
|
||||
|
||||
- 您想要更改智能体的名称、个性或沟通风格
|
||||
- 您需要智能体记住项目特定的上下文
|
||||
- 您想要添加自定义菜单项来触发您自己的工作流或提示
|
||||
- 您希望智能体在每次启动时执行特定操作
|
||||
- 你想修改智能体名称、身份设定或沟通风格
|
||||
- 你需要让智能体长期记住项目约束和背景信息
|
||||
- 你希望增加自定义菜单项,触发自己的工作流或提示
|
||||
- 你希望智能体每次启动都先执行固定动作
|
||||
|
||||
:::note[前置条件]
|
||||
- 在项目中安装了 BMad(参见[如何安装 BMad](./install-bmad.md))
|
||||
- 已在项目中安装 BMad(参见[如何安装 BMad](./install-bmad.md))
|
||||
- 用于编辑 YAML 文件的文本编辑器
|
||||
:::
|
||||
|
||||
:::caution[保护您的自定义配置]
|
||||
始终使用此处描述的 `.customize.yaml` 文件,而不是直接编辑智能体文件。安装程序在更新期间会覆盖智能体文件,但会保留您的 `.customize.yaml` 更改。
|
||||
始终通过 `.customize.yaml` 自定义,不要直接改动智能体源文件。安装程序在更新时会覆盖智能体文件,但会保留 `.customize.yaml` 的内容。
|
||||
:::
|
||||
|
||||
## 步骤
|
||||
|
||||
### 1. 定位自定义文件
|
||||
|
||||
安装后,在以下位置为每个智能体找到一个 `.customize.yaml` 文件:
|
||||
安装完成后,每个已安装智能体都会在下面目录生成一个 `.customize.yaml`:
|
||||
|
||||
```text
|
||||
_bmad/_config/agents/
|
||||
├── core-bmad-master.customize.yaml
|
||||
├── bmm-dev.customize.yaml
|
||||
├── bmm-pm.customize.yaml
|
||||
└── ...(每个已安装的智能体一个文件)
|
||||
└── ...(每个已安装智能体一个文件)
|
||||
```
|
||||
|
||||
### 2. 编辑自定义文件
|
||||
|
||||
打开您想要修改的智能体的 `.customize.yaml` 文件。每个部分都是可选的——只自定义您需要的内容。
|
||||
打开目标智能体的 `.customize.yaml`。各段都可选,只改你需要的部分即可。
|
||||
|
||||
| 部分 | 行为 | 用途 |
|
||||
| 部分 | 作用方式 | 用途 |
|
||||
| ------------------ | -------- | ---------------------------------------------- |
|
||||
| `agent.metadata` | 替换 | 覆盖智能体的显示名称 |
|
||||
| `persona` | 替换 | 设置角色、身份、风格和原则 |
|
||||
| `memories` | 追加 | 添加智能体始终会记住的持久上下文 |
|
||||
| `menu` | 追加 | 为工作流或提示添加自定义菜单项 |
|
||||
| `critical_actions` | 追加 | 定义智能体的启动指令 |
|
||||
| `prompts` | 追加 | 创建可重复使用的提示供菜单操作使用 |
|
||||
| `agent.metadata` | 覆盖 | 覆盖智能体显示名称 |
|
||||
| `persona` | 覆盖 | 设置角色、身份、风格和原则 |
|
||||
| `memories` | 追加 | 添加智能体长期记忆的上下文 |
|
||||
| `menu` | 追加 | 增加指向工作流或提示的菜单项 |
|
||||
| `critical_actions` | 追加 | 定义智能体启动时要执行的动作 |
|
||||
| `prompts` | 追加 | 创建可复用提示,供菜单 `action` 引用 |
|
||||
|
||||
标记为 **替换** 的部分会完全覆盖智能体的默认设置。标记为 **追加** 的部分会添加到现有配置中。
|
||||
标记为 **覆盖** 的部分会完全替换默认配置;标记为 **追加** 的部分会在默认配置基础上累加。
|
||||
|
||||
**智能体名称**
|
||||
**智能体名称(`agent.metadata`)**
|
||||
|
||||
更改智能体的自我介绍方式:
|
||||
修改智能体的显示名称:
|
||||
|
||||
```yaml
|
||||
agent:
|
||||
|
|
@ -62,9 +62,9 @@ agent:
|
|||
name: 'Spongebob' # 默认值:"Amelia"
|
||||
```
|
||||
|
||||
**角色**
|
||||
**角色(`persona`)**
|
||||
|
||||
替换智能体的个性、角色和沟通风格:
|
||||
替换智能体的人设、职责和沟通风格:
|
||||
|
||||
```yaml
|
||||
persona:
|
||||
|
|
@ -76,11 +76,11 @@ persona:
|
|||
- 'Favor composition over inheritance'
|
||||
```
|
||||
|
||||
`persona` 部分会替换整个默认角色,因此如果您设置它,请包含所有四个字段。
|
||||
`persona` 会覆盖默认整段配置,所以启用时请把四个字段都填全。
|
||||
|
||||
**记忆**
|
||||
**记忆(`memories`)**
|
||||
|
||||
添加智能体将始终记住的持久上下文:
|
||||
添加智能体会长期记住的上下文:
|
||||
|
||||
```yaml
|
||||
memories:
|
||||
|
|
@ -89,9 +89,9 @@ memories:
|
|||
- 'Learned in Epic 1 that it is not cool to just pretend that tests have passed'
|
||||
```
|
||||
|
||||
**菜单项**
|
||||
**菜单项(`menu`)**
|
||||
|
||||
向智能体的显示菜单添加自定义条目。每个条目需要一个 `trigger`、一个目标(`workflow` 路径或 `action` 引用)和一个 `description`:
|
||||
给智能体菜单添加自定义项。每个条目都需要 `trigger`、目标(`workflow` 路径或 `action` 引用)和 `description`:
|
||||
|
||||
```yaml
|
||||
menu:
|
||||
|
|
@ -103,18 +103,18 @@ menu:
|
|||
description: Deploy to production
|
||||
```
|
||||
|
||||
**关键操作**
|
||||
**启动关键动作(`critical_actions`)**
|
||||
|
||||
定义智能体启动时运行的指令:
|
||||
定义智能体启动时执行的指令:
|
||||
|
||||
```yaml
|
||||
critical_actions:
|
||||
- 'Check the CI Pipelines with the XYZ Skill and alert user on wake if anything is urgently needing attention'
|
||||
```
|
||||
|
||||
**自定义提示**
|
||||
**可复用提示(`prompts`)**
|
||||
|
||||
创建可重复使用的提示,菜单项可以通过 `action="#id"` 引用:
|
||||
创建可复用提示,菜单项可通过 `action="#id"` 调用:
|
||||
|
||||
```yaml
|
||||
prompts:
|
||||
|
|
@ -126,56 +126,51 @@ prompts:
|
|||
3. Execute deployment script
|
||||
```
|
||||
|
||||
### 3. 应用您的更改
|
||||
### 3. 应用更改
|
||||
|
||||
编辑后,重新安装以应用更改:
|
||||
编辑完成后,重新安装以应用配置:
|
||||
|
||||
```bash
|
||||
npx bmad-method install
|
||||
```
|
||||
|
||||
安装程序会检测现有安装并提供以下选项:
|
||||
安装程序会识别现有安装,并给出以下选项:
|
||||
|
||||
| Option | What It Does |
|
||||
| 选项 | 作用 |
|
||||
| ---------------------------- | ------------------------------------------------------------------- |
|
||||
| **Quick Update** | 将所有模块更新到最新版本并应用自定义配置 |
|
||||
| **Modify BMad Installation** | 用于添加或删除模块的完整安装流程 |
|
||||
| **Quick Update** | 更新所有模块到最新版本,并应用你的自定义配置 |
|
||||
| **Modify BMad Installation** | 进入完整安装流程,用于增删模块 |
|
||||
|
||||
对于仅自定义配置的更改,**Quick Update** 是最快的选项。
|
||||
如果只是调整 `.customize.yaml`,优先选 **Quick Update**。
|
||||
|
||||
## 故障排除
|
||||
## 故障排查
|
||||
|
||||
**更改未生效?**
|
||||
**改动没有生效?**
|
||||
|
||||
- 运行 `npx bmad-method install` 并选择 **Quick Update** 以应用更改
|
||||
- 检查您的 YAML 语法是否有效(缩进很重要)
|
||||
- 验证您编辑的是该智能体正确的 `.customize.yaml` 文件
|
||||
- 检查 YAML 语法是否正确(尤其是缩进)
|
||||
- 确认你编辑的是目标智能体对应的 `.customize.yaml`
|
||||
|
||||
**智能体无法加载?**
|
||||
|
||||
- 使用在线 YAML 验证器检查 YAML 语法错误
|
||||
- 确保在取消注释后没有留下空字段
|
||||
- 尝试恢复到原始模板并重新构建
|
||||
- 确保取消注释后没有遗留空字段
|
||||
- 可先回退到模板,再逐项恢复自定义配置
|
||||
|
||||
**需要重置智能体?**
|
||||
**需要重置某个智能体?**
|
||||
|
||||
- 清空或删除智能体的 `.customize.yaml` 文件
|
||||
- 运行 `npx bmad-method install` 并选择 **Quick Update** 以恢复默认设置
|
||||
|
||||
## 工作流自定义
|
||||
|
||||
对现有 BMad Method 工作流和技能的自定义即将推出。
|
||||
对现有 BMad Method 工作流和技能的深度自定义能力即将推出。
|
||||
|
||||
## 模块自定义
|
||||
|
||||
关于构建扩展模块和自定义现有模块的指南即将推出。
|
||||
|
||||
---
|
||||
## 术语说明
|
||||
## 后续步骤
|
||||
|
||||
- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。
|
||||
- **workflow**:工作流。指一系列有序的任务或步骤,用于完成特定目标。
|
||||
- **persona**:角色。指智能体的身份、个性、沟通风格和行为原则的集合。
|
||||
- **memory**:记忆。指智能体持久存储的上下文信息,用于在对话中保持连贯性。
|
||||
- **critical action**:关键操作。指智能体启动时必须执行的指令或任务。
|
||||
- **prompt**:提示。指发送给智能体的输入文本,用于引导其生成特定响应或执行特定操作。
|
||||
- [文档分片指南](./shard-large-documents.md) - 了解如何管理超长文档
|
||||
- [命令参考](../reference/commands.md) - 查看可用命令和工作流入口
|
||||
|
|
|
|||
|
|
@ -5,19 +5,21 @@ sidebar:
|
|||
order: 9
|
||||
---
|
||||
|
||||
如果需要将大型 Markdown 文件拆分为更小、组织良好的文件以更好地管理上下文,请使用 `shard-doc` 工具。
|
||||
当单个 Markdown 文档过大、影响模型读取时,可使用 `bmad-shard-doc` 工作流把文档拆成按章节组织的小文件,降低上下文压力。
|
||||
|
||||
:::caution[已弃用]
|
||||
不再推荐使用此方法,随着工作流程的更新以及大多数主要 LLM 和工具支持子进程,这很快将变得不再必要。
|
||||
这是兼容性方案,默认不推荐。随着工作流更新,以及主流模型/工具逐步支持子进程(subprocesses),很多场景将不再需要手动分片。
|
||||
:::
|
||||
|
||||
## 何时使用
|
||||
|
||||
仅当你发现所选工具/模型组合无法在需要时加载和读取所有文档作为输入时,才使用此方法。
|
||||
- 你确认当前工具/模型在关键步骤无法一次读入完整文档
|
||||
- 文档体量已明显影响工作流稳定性或响应质量
|
||||
- 你需要保留原文结构,但希望按 `##` 章节拆分维护
|
||||
|
||||
## 什么是文档分片?
|
||||
|
||||
文档分片根据二级标题(`## Heading`)将大型 Markdown 文件拆分为更小、组织良好的文件。
|
||||
文档分片会按二级标题(`## Heading`)把大型 Markdown 文件拆成多个子文件,并生成一个 `index.md` 作为入口。
|
||||
|
||||
### 架构
|
||||
|
||||
|
|
@ -38,16 +40,16 @@ _bmad-output/planning-artifacts/
|
|||
|
||||
## 步骤
|
||||
|
||||
### 1. 运行 Shard-Doc 工具
|
||||
### 1. 运行 `bmad-shard-doc` 工作流
|
||||
|
||||
```bash
|
||||
/bmad-shard-doc
|
||||
```
|
||||
|
||||
### 2. 遵循交互式流程
|
||||
### 2. 按交互流程完成分片
|
||||
|
||||
```text
|
||||
智能体:您想要分片哪个文档?
|
||||
智能体:你想分片哪个文档?
|
||||
用户:docs/PRD.md
|
||||
|
||||
智能体:默认目标位置:docs/prd/
|
||||
|
|
@ -60,27 +62,21 @@ _bmad-output/planning-artifacts/
|
|||
✓ 完成!
|
||||
```
|
||||
|
||||
## 工作流程发现机制
|
||||
## 工作流发现机制
|
||||
|
||||
BMad 工作流程使用**双重发现系统**:
|
||||
BMad 工作流使用**双重发现机制**:
|
||||
|
||||
1. **首先尝试完整文档** - 查找 `document-name.md`
|
||||
2. **检查分片版本** - 查找 `document-name/index.md`
|
||||
3. **优先级规则** - 如果两者都存在,完整文档优先 - 如果希望使用分片版本,请删除完整文档
|
||||
1. **先查完整文档** - 查找 `document-name.md`
|
||||
2. **再查分片入口** - 查找 `document-name/index.md`
|
||||
3. **优先级规则** - 若两者并存,默认优先完整文档;若你要强制使用分片版本,请删除或重命名完整文档
|
||||
|
||||
## 工作流程支持
|
||||
## 你将获得
|
||||
|
||||
所有 BMM 工作流程都支持这两种格式:
|
||||
- 原始完整文档(可保留,但不建议与分片长期并存;并存时默认优先读取完整文档)
|
||||
- 分片目录(如 `document-name/index.md` + 各章节文件)
|
||||
- 对工作流透明的自动识别行为(无需额外配置)
|
||||
|
||||
- 完整文档
|
||||
- 分片文档
|
||||
- 自动检测
|
||||
- 对用户透明
|
||||
## 后续步骤
|
||||
|
||||
---
|
||||
## 术语说明
|
||||
|
||||
- **sharding**:分片。将大型文档或数据集拆分为更小、更易管理的部分的过程。
|
||||
- **token**:令牌。在自然语言处理和大型语言模型中,文本的基本单位,通常对应单词或字符的一部分。
|
||||
- **subprocesses**:子进程。由主进程创建的独立执行单元,可以并行运行以执行特定任务。
|
||||
- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。
|
||||
- [如何自定义 BMad](./customize-bmad.md) - 了解高级配置与工作流定制边界
|
||||
- [如何升级到 v6](./upgrade-to-v6.md) - 在迁移过程中处理文档与目录结构变化
|
||||
|
|
|
|||
|
|
@ -5,76 +5,83 @@ sidebar:
|
|||
order: 3
|
||||
---
|
||||
|
||||
使用 BMad 安装程序从 v4 升级到 v6,其中包括自动检测旧版安装和迁移辅助。
|
||||
使用 BMad 安装程序把 v4 升级到 v6。安装程序会自动识别旧安装,并提供迁移辅助,帮助你在已有项目中平滑过渡。
|
||||
|
||||
## 何时使用本指南
|
||||
|
||||
- 您已安装 BMad v4(`.bmad-method` 文件夹)
|
||||
- 您希望迁移到新的 v6 架构
|
||||
- 您有需要保留的现有规划产物
|
||||
- 你已安装 BMad v4(目录名通常是 `.bmad-method`)
|
||||
- 你准备迁移到 v6 的统一目录结构
|
||||
- 你有要保留的规划产物或进行中的开发工作
|
||||
|
||||
:::note[前置条件]
|
||||
- Node.js 20+
|
||||
- 现有的 BMad v4 安装
|
||||
- 现有 BMad v4 安装
|
||||
:::
|
||||
|
||||
::::caution[先备份再迁移]
|
||||
如果当前仓库里仍有未提交的重要变更,先完成提交或备份,再执行升级。
|
||||
::::
|
||||
|
||||
## 步骤
|
||||
|
||||
### 1. 运行安装程序
|
||||
|
||||
按照[安装程序说明](./install-bmad.md)操作。
|
||||
|
||||
### 2. 处理旧版安装
|
||||
### 2. 处理旧版安装目录
|
||||
|
||||
当检测到 v4 时,您可以:
|
||||
当检测到 v4 时,你有两种处理方式:
|
||||
|
||||
- 允许安装程序备份并删除 `.bmad-method`
|
||||
- 退出并手动处理清理
|
||||
- 允许安装程序自动备份并删除 `.bmad-method`
|
||||
- 先退出安装流程,再手动清理旧目录
|
||||
|
||||
如果您将 bmad method 文件夹命名为其他名称 - 您需要手动删除该文件夹。
|
||||
如果你把 BMad Method 目录改成了其他名字,需要你自己手动定位并删除。
|
||||
|
||||
### 3. 清理 IDE 命令
|
||||
### 3. 清理 IDE 命令与技能目录
|
||||
|
||||
手动删除旧版 v4 IDE 命令 - 例如如果您使用 claude,查找任何以 bmad 开头的嵌套文件夹并删除它们:
|
||||
手动删除旧版 v4 IDE 命令/技能目录。以 Claude Code 为例,请在旧目录中删除以 `bmad` 开头的嵌套目录:
|
||||
|
||||
- `.claude/commands/BMad/agents`
|
||||
- `.claude/commands/BMad/tasks`
|
||||
- `.claude/commands/`
|
||||
|
||||
v6 新技能会安装到:
|
||||
|
||||
- `.claude/skills/`
|
||||
|
||||
### 4. 迁移规划产物
|
||||
|
||||
**如果您有规划文档(Brief/PRD/UX/Architecture):**
|
||||
**如果你有规划文档(Brief/PRD/UX/Architecture):**
|
||||
|
||||
将它们移动到 `_bmad-output/planning-artifacts/` 并使用描述性名称:
|
||||
把它们移动到 `_bmad-output/planning-artifacts/`,并使用可读的文件名:
|
||||
|
||||
- 在文件名中包含 `PRD` 用于 PRD 文档
|
||||
- 相应地包含 `brief`、`architecture` 或 `ux-design`
|
||||
- 分片文档可以放在命名的子文件夹中
|
||||
- PRD 文档文件名包含 `PRD`
|
||||
- 其他文档按类型包含 `brief`、`architecture` 或 `ux-design`
|
||||
- 分片文档可放在命名清晰的子目录中
|
||||
|
||||
**如果您正在进行规划:** 考虑使用 v6 工作流重新开始。将现有文档作为输入——新的渐进式发现工作流配合网络搜索和 IDE 计划模式会产生更好的结果。
|
||||
**如果你仍在规划中:** 建议直接用 v6 工作流重启规划,把现有文档作为输入;新版渐进式发现流程配合 Web 搜索和 IDE 计划模式通常会得到更稳妥的结果。
|
||||
|
||||
### 5. 迁移进行中的开发
|
||||
### 5. 迁移进行中的开发工作
|
||||
|
||||
如果您已创建或实现了故事:
|
||||
如果你已经创建或实现了部分用户故事(story):
|
||||
|
||||
1. 完成 v6 安装
|
||||
2. 将 `epics.md` 或 `epics/epic*.md` 放入 `_bmad-output/planning-artifacts/`
|
||||
3. 运行 Scrum Master 的 `sprint-planning` 工作流
|
||||
3. 运行 Scrum Master 的 `bmad-sprint-planning` 工作流
|
||||
4. 告诉 SM 哪些史诗/故事已经完成
|
||||
|
||||
## 您将获得
|
||||
## 你将获得
|
||||
|
||||
**v6 统一结构:**
|
||||
|
||||
```text
|
||||
your-project/
|
||||
├── _bmad/ # 单一安装文件夹
|
||||
│ ├── _config/ # 您的自定义配置
|
||||
├── _bmad/ # 单一安装目录
|
||||
│ ├── _config/ # 你的自定义配置
|
||||
│ │ └── agents/ # 智能体自定义文件
|
||||
│ ├── core/ # 通用核心框架
|
||||
│ ├── bmm/ # BMad Method 模块
|
||||
│ ├── bmb/ # BMad Builder
|
||||
│ └── cis/ # Creative Intelligence Suite
|
||||
└── _bmad-output/ # 输出文件夹(v4 中为 doc 文件夹)
|
||||
└── _bmad-output/ # 输出目录(v4 时代常见为 doc 目录)
|
||||
```
|
||||
|
||||
## 模块迁移
|
||||
|
|
@ -87,34 +94,18 @@ your-project/
|
|||
| `.bmad-infrastructure-devops` | 已弃用 — 新的 DevOps 智能体即将推出 |
|
||||
| `.bmad-creative-writing` | 未适配 — 新的 v6 模块即将推出 |
|
||||
|
||||
## 主要变更
|
||||
## 关键差异(旧名/新名)
|
||||
|
||||
| 概念 | v4 | v6 |
|
||||
| ------------ | --------------------------------------- | ------------------------------------ |
|
||||
| **核心** | `_bmad-core` 实际上是 BMad Method | `_bmad/core/` 是通用框架 |
|
||||
| **方法** | `_bmad-method` | `_bmad/bmm/` |
|
||||
| **配置** | 直接修改文件 | 每个模块使用 `config.yaml` |
|
||||
| **文档** | 需要设置分片或非分片 | 完全灵活,自动扫描 |
|
||||
| 概念 | v4(旧) | v6(新) | 迁移提示 |
|
||||
| ------------ | --------------------------------------- | ------------------------------------ | ------------------------------------ |
|
||||
| **核心框架** | `_bmad-core` 实际上承载的是 BMad Method | `_bmad/core/` 变成通用框架层 | 迁移时不要再把 `_bmad/core/` 当成 Method 本体 |
|
||||
| **方法模块** | `_bmad-method` | `_bmad/bmm/` | 旧脚本、路径引用需同步更新到 `bmm` |
|
||||
| **配置方式** | 直接改模块文件 | 每个模块通过 `config.yaml` 管理 | 优先改配置,不要直接改生成文件 |
|
||||
| **文档读取** | 需要手动区分分片/非分片 | 自动扫描完整文档与分片入口 | 只有在兼容性场景下才建议手动分片 |
|
||||
|
||||
---
|
||||
## 术语说明
|
||||
## 后续建议
|
||||
|
||||
- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。
|
||||
- **epic**:史诗。在敏捷开发中,指大型的工作项,可分解为多个用户故事。
|
||||
- **story**:故事。在敏捷开发中,指用户故事,描述用户需求的功能单元。
|
||||
- **Scrum Master**:Scrum 主管。敏捷开发 Scrum 框架中的角色,负责促进团队流程和移除障碍。
|
||||
- **sprint-planning**:冲刺规划。Scrum 框架中的会议,用于确定下一个冲刺期间要完成的工作。
|
||||
- **sharded**:分片。将大型文档拆分为多个较小的文件以便于管理和处理。
|
||||
- **PRD**:产品需求文档(Product Requirements Document)。描述产品功能、需求和特性的文档。
|
||||
- **Brief**:简报。概述项目目标、范围和关键信息的文档。
|
||||
- **UX**:用户体验(User Experience)。用户在使用产品或服务过程中的整体感受和交互体验。
|
||||
- **Architecture**:架构。系统的结构设计,包括组件、模块及其相互关系。
|
||||
- **BMGD**:BMad Game Development。BMad 游戏开发模块。
|
||||
- **DevOps**:开发运维(Development Operations)。结合开发和运维的实践,旨在缩短系统开发生命周期。
|
||||
- **BMad Method**:BMad 方法。BMad 框架的核心方法论模块。
|
||||
- **BMad Builder**:BMad 构建器。BMad 框架的构建工具。
|
||||
- **Creative Intelligence Suite**:创意智能套件。BMad 框架中的创意工具集合。
|
||||
- **IDE**:集成开发环境(Integrated Development Environment)。提供代码编辑、调试等功能的软件开发工具。
|
||||
- **progressive discovery**:渐进式发现。逐步深入探索和理解需求的过程。
|
||||
- **web search**:网络搜索。通过互联网检索信息的能力。
|
||||
- **plan mode**:计划模式。IDE 中的一种工作模式,用于规划和设计任务。
|
||||
- 升级完成后先运行 `bmad-help`,确认可用工作流与下一步建议
|
||||
- 如果是既有项目,补充或更新 `project-context.md`,减少后续实现偏差
|
||||
- 在继续开发前,先做一次关键链路验证(安装、命令触发、文档读取)
|
||||
- 继续阅读:[如何安装 BMad](./install-bmad.md)、[管理项目上下文](./project-context.md)
|
||||
|
|
|
|||
|
|
@ -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 |
|
||||
| Architecture | `{planning_artifacts}/*architecture*.md` (whole) or `{planning_artifacts}/*architecture*/*.md` (sharded) | FULL_LOAD |
|
||||
| UX Design | `{planning_artifacts}/*ux*.md` (whole) or `{planning_artifacts}/*ux*/*.md` (sharded) | FULL_LOAD |
|
||||
| Tech Spec | `{planning_artifacts}/*tech-spec*.md` (whole) | FULL_LOAD |
|
||||
| Spec | `{planning_artifacts}/*spec-*.md` (whole) | FULL_LOAD |
|
||||
| Document Project | `{project_knowledge}/index.md` (sharded) | INDEX_GUIDED |
|
||||
|
||||
### Context
|
||||
|
|
@ -51,9 +51,9 @@ Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
|
|||
|
||||
**Strategy**: Course correction needs broad project context to assess change impact accurately. Load all available planning artifacts.
|
||||
|
||||
**Discovery Process for FULL_LOAD documents (PRD, Epics, Architecture, UX Design, Tech Spec):**
|
||||
**Discovery Process for FULL_LOAD documents (PRD, Epics, Architecture, UX Design, Spec):**
|
||||
|
||||
1. **Search for whole document first** - Look for files matching the whole-document pattern (e.g., `*prd*.md`, `*epic*.md`, `*architecture*.md`, `*ux*.md`, `*tech-spec*.md`)
|
||||
1. **Search for whole document first** - Look for files matching the whole-document pattern (e.g., `*prd*.md`, `*epic*.md`, `*architecture*.md`, `*ux*.md`, `*spec-*.md`)
|
||||
2. **Check for sharded version** - If whole document not found, look for a directory with `index.md` (e.g., `prd/index.md`, `epics/index.md`)
|
||||
3. **If sharded version found**:
|
||||
- Read `index.md` to understand the document structure
|
||||
|
|
@ -70,7 +70,7 @@ Load config from `{project-root}/_bmad/bmm/config.yaml` and resolve:
|
|||
|
||||
**Fuzzy matching**: Be flexible with document names — users may use variations like `prd.md`, `bmm-prd.md`, `product-requirements.md`, etc.
|
||||
|
||||
**Missing documents**: Not all documents may exist. PRD and Epics are essential; Architecture, UX Design, Tech Spec, and Document Project are loaded if available. HALT if PRD or Epics cannot be found.
|
||||
**Missing documents**: Not all documents may exist. PRD and Epics are essential; Architecture, UX Design, Spec, and Document Project are loaded if available. HALT if PRD or Epics cannot be found.
|
||||
|
||||
<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.
|
||||
IMPORTANT: Remove all HTML comments when filling this template. -->
|
||||
|
||||
# {title}
|
||||
|
||||
<frozen-after-approval reason="human-owned intent — do not modify unless human renegotiates">
|
||||
|
||||
## 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'
|
||||
spec_file: '' # set at runtime for plan-code-review before leaving this step
|
||||
---
|
||||
|
|
@ -15,13 +15,27 @@ spec_file: '' # set at runtime for plan-code-review before leaving this step
|
|||
- The user chose this workflow on purpose. Later steps (e.g. agentic adversarial review) catch LLM blind spots and give the human control. Do not skip them.
|
||||
- **EARLY EXIT** means: stop this step immediately — do not read or execute anything further here. Read and fully follow the target file instead. Return here ONLY if a later step explicitly says to loop back.
|
||||
|
||||
## ARTIFACT SCAN
|
||||
## Intent check (do this first)
|
||||
|
||||
- `{wipFile}` exists? → Offer resume or archive.
|
||||
- Active specs (`ready-for-dev`, `in-progress`, `in-review`) in `{implementation_artifacts}`? → List them and HALT. Ask user which to resume (or `[N]` for new).
|
||||
- If `ready-for-dev` or `in-progress` selected: Set `spec_file`. **EARLY EXIT** → `./step-03-implement.md`
|
||||
- If `in-review` selected: Set `spec_file`. **EARLY EXIT** → `./step-04-review.md`
|
||||
- Unformatted spec or intent file lacking `status` frontmatter in `{implementation_artifacts}`? → Suggest to the user to treat its contents as the starting intent for this workflow. DO NOT attempt to infer a state and resume it.
|
||||
Before listing artifacts or prompting the user, check whether you already know the intent. Check in this order — skip the remaining checks as soon as the intent is clear:
|
||||
|
||||
1. Explicit argument
|
||||
Did the user pass a specific file path, spec name, or clear instruction this message?
|
||||
- If it points to a file that matches the spec template (has `status` frontmatter with a recognized value: ready-for-dev, in-progress, or in-review) → set `spec_file` and **EARLY EXIT** to the appropriate step (step-03 for ready/in-progress, step-04 for review).
|
||||
- Anything else (intent files, external docs, plans, descriptions) → ingest it as starting intent and proceed to INSTRUCTIONS. Do not attempt to infer a workflow state from it.
|
||||
|
||||
2. Recent conversation
|
||||
Do the last few human messages clearly show what the user intends to work on?
|
||||
Use the same routing as above.
|
||||
|
||||
3. Otherwise — scan artifacts and ask
|
||||
- `{wipFile}` exists? → Offer resume or archive.
|
||||
- Active specs (`ready-for-dev`, `in-progress`, `in-review`) in `{implementation_artifacts}`? → List them and HALT. Ask user which to resume (or `[N]` for new).
|
||||
- If `ready-for-dev` or `in-progress` selected: Set `spec_file`. **EARLY EXIT** → `./step-03-implement.md`
|
||||
- If `in-review` selected: Set `spec_file`. **EARLY EXIT** → `./step-04-review.md`
|
||||
- Unformatted spec or intent file lacking `status` frontmatter? → Suggest treating its contents as the starting intent. Do NOT attempt to infer a state and resume it.
|
||||
|
||||
Never ask extra questions if you already understand what the user intends.
|
||||
|
||||
## INSTRUCTIONS
|
||||
|
||||
|
|
@ -42,7 +56,7 @@ spec_file: '' # set at runtime for plan-code-review before leaving this step
|
|||
**EARLY EXIT** → `./step-oneshot.md`
|
||||
|
||||
**b) Plan-code-review** — everything else. When uncertain whether blast radius is truly zero, choose this path.
|
||||
1. Derive a valid kebab-case slug from the clarified intent. If `{implementation_artifacts}/tech-spec-{slug}.md` already exists, append `-2`, `-3`, etc. Set `spec_file` = `{implementation_artifacts}/tech-spec-{slug}.md`.
|
||||
1. Derive a valid kebab-case slug from the clarified intent. If the intent references a tracking identifier (story number, issue number, ticket ID), lead the slug with it (e.g. `3-2-digest-delivery`, `gh-47-fix-auth`). If `{implementation_artifacts}/spec-{slug}.md` already exists, append `-2`, `-3`, etc. Set `spec_file` = `{implementation_artifacts}/spec-{slug}.md`.
|
||||
|
||||
|
||||
## NEXT
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
wipFile: '{implementation_artifacts}/tech-spec-wip.md'
|
||||
wipFile: '{implementation_artifacts}/spec-wip.md'
|
||||
deferred_work_file: '{implementation_artifacts}/deferred-work.md'
|
||||
---
|
||||
|
||||
|
|
@ -13,7 +13,7 @@ deferred_work_file: '{implementation_artifacts}/deferred-work.md'
|
|||
## INSTRUCTIONS
|
||||
|
||||
1. Investigate codebase. _Isolate deep exploration in sub-agents/tasks where available. To prevent context snowballing, instruct subagents to give you distilled summaries only._
|
||||
2. Read `./tech-spec-template.md` fully. Fill it out based on the intent and investigation, and write the result to `{wipFile}`.
|
||||
2. Read `./spec-template.md` fully. Fill it out based on the intent and investigation, and write the result to `{wipFile}`.
|
||||
3. Self-review against READY FOR DEVELOPMENT standard.
|
||||
4. If intent gaps exist, do not fantasize, do not leave open questions, HALT and ask the human.
|
||||
5. Token count check (see SCOPE STANDARD). If spec exceeds 1600 tokens:
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `
|
|||
|
||||
### 2. Paths
|
||||
|
||||
- `wipFile` = `{implementation_artifacts}/tech-spec-wip.md`
|
||||
- `wipFile` = `{implementation_artifacts}/spec-wip.md`
|
||||
|
||||
### 3. First Step Execution
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
module,phase,name,code,sequence,workflow-file,command,required,agent,options,description,output-location,outputs,
|
||||
bmm,anytime,Document Project,DP,,skill:bmad-document-project,bmad-bmm-document-project,false,analyst,Create Mode,"Analyze an existing project to produce useful documentation",project-knowledge,*,
|
||||
bmm,anytime,Generate Project Context,GPC,,skill:bmad-generate-project-context,bmad-bmm-generate-project-context,false,analyst,Create Mode,"Scan existing codebase to generate a lean LLM-optimized project-context.md containing critical implementation rules patterns and conventions for AI agents. Essential for brownfield projects and quick-flow.",output_folder,"project context",
|
||||
bmm,anytime,Quick Dev,QQ,,skill:bmad-quick-dev,bmad-bmm-quick-dev,false,quick-flow-solo-dev,Create Mode,"Unified quick flow: clarify intent plan implement review and present in a single workflow",implementation_artifacts,"tech spec and project implementation",
|
||||
bmm,anytime,Generate Project Context,GPC,,skill:bmad-generate-project-context,bmad-bmm-generate-project-context,false,analyst,Create Mode,"Scan existing codebase to generate a lean LLM-optimized project-context.md containing critical implementation rules patterns and conventions for AI agents. Essential for brownfield projects.",output_folder,"project context",
|
||||
bmm,anytime,Quick Dev,QQ,,skill:bmad-quick-dev,bmad-bmm-quick-dev,false,quick-flow-solo-dev,Create Mode,"Unified intent-in code-out workflow: clarify plan implement review and present",implementation_artifacts,"spec and project implementation",
|
||||
bmm,anytime,Correct Course,CC,,skill:bmad-correct-course,bmad-bmm-correct-course,false,sm,Create Mode,"Anytime: Navigate significant changes. May recommend start over update PRD redo architecture sprint planning or correct epics and stories",planning_artifacts,"change proposal",
|
||||
bmm,anytime,Write Document,WD,,skill:bmad-agent-tech-writer,,false,tech-writer,,"Describe in detail what you want, and the agent will follow the documentation best practices defined in agent memory. Multi-turn conversation with subprocess for research/review.",project-knowledge,"document",
|
||||
bmm,anytime,Update Standards,US,,skill:bmad-agent-tech-writer,,false,tech-writer,,"Update agent memory documentation-standards.md with your specific preferences if you discover missing document conventions.",_bmad/_memory/tech-writer-sidecar,"standards",
|
||||
|
|
|
|||
|
|
|
@ -14,6 +14,7 @@
|
|||
const path = require('node:path');
|
||||
const os = require('node:os');
|
||||
const fs = require('fs-extra');
|
||||
const { ConfigCollector } = require('../tools/cli/installers/lib/core/config-collector');
|
||||
const { ManifestGenerator } = require('../tools/cli/installers/lib/core/manifest-generator');
|
||||
const { IdeManager } = require('../tools/cli/installers/lib/ide/manager');
|
||||
const { clearCache, loadPlatformCodes } = require('../tools/cli/installers/lib/ide/platform-codes');
|
||||
|
|
@ -1853,6 +1854,93 @@ async function runTests() {
|
|||
|
||||
console.log('');
|
||||
|
||||
// ============================================================
|
||||
// Test Suite 33: ConfigCollector Prompt Normalization
|
||||
// ============================================================
|
||||
console.log(`${colors.yellow}Test Suite 33: ConfigCollector Prompt Normalization${colors.reset}\n`);
|
||||
|
||||
try {
|
||||
const teaModuleConfig33 = {
|
||||
test_artifacts: {
|
||||
default: '_bmad-output/test-artifacts',
|
||||
},
|
||||
test_design_output: {
|
||||
prompt: 'Where should test design documents be stored?',
|
||||
default: 'test-design',
|
||||
result: '{test_artifacts}/{value}',
|
||||
},
|
||||
test_review_output: {
|
||||
prompt: 'Where should test review reports be stored?',
|
||||
default: 'test-reviews',
|
||||
result: '{test_artifacts}/{value}',
|
||||
},
|
||||
trace_output: {
|
||||
prompt: 'Where should traceability reports be stored?',
|
||||
default: 'traceability',
|
||||
result: '{test_artifacts}/{value}',
|
||||
},
|
||||
};
|
||||
|
||||
const collector33 = new ConfigCollector();
|
||||
collector33.currentProjectDir = path.join(os.tmpdir(), 'bmad-config-normalization');
|
||||
collector33.allAnswers = {};
|
||||
collector33.collectedConfig = {
|
||||
tea: {
|
||||
test_artifacts: '_bmad-output/test-artifacts',
|
||||
},
|
||||
};
|
||||
collector33.existingConfig = {
|
||||
tea: {
|
||||
test_artifacts: '_bmad-output/test-artifacts',
|
||||
test_design_output: '_bmad-output/test-artifacts/test-design',
|
||||
test_review_output: '_bmad-output/test-artifacts/test-reviews',
|
||||
trace_output: '_bmad-output/test-artifacts/traceability',
|
||||
},
|
||||
};
|
||||
|
||||
const testDesignQuestion33 = await collector33.buildQuestion(
|
||||
'tea',
|
||||
'test_design_output',
|
||||
teaModuleConfig33.test_design_output,
|
||||
teaModuleConfig33,
|
||||
);
|
||||
const testReviewQuestion33 = await collector33.buildQuestion(
|
||||
'tea',
|
||||
'test_review_output',
|
||||
teaModuleConfig33.test_review_output,
|
||||
teaModuleConfig33,
|
||||
);
|
||||
const traceQuestion33 = await collector33.buildQuestion('tea', 'trace_output', teaModuleConfig33.trace_output, teaModuleConfig33);
|
||||
|
||||
assert(testDesignQuestion33.default === 'test-design', 'ConfigCollector normalizes existing test_design_output prompt default');
|
||||
assert(testReviewQuestion33.default === 'test-reviews', 'ConfigCollector normalizes existing test_review_output prompt default');
|
||||
assert(traceQuestion33.default === 'traceability', 'ConfigCollector normalizes existing trace_output prompt default');
|
||||
|
||||
collector33.allAnswers = {
|
||||
tea_test_artifacts: '_bmad-output/test-artifacts',
|
||||
};
|
||||
|
||||
assert(
|
||||
collector33.processResultTemplate(teaModuleConfig33.test_design_output.result, testDesignQuestion33.default) ===
|
||||
'_bmad-output/test-artifacts/test-design',
|
||||
'ConfigCollector re-applies test_design_output template without duplicating prefix',
|
||||
);
|
||||
assert(
|
||||
collector33.processResultTemplate(teaModuleConfig33.test_review_output.result, testReviewQuestion33.default) ===
|
||||
'_bmad-output/test-artifacts/test-reviews',
|
||||
'ConfigCollector re-applies test_review_output template without duplicating prefix',
|
||||
);
|
||||
assert(
|
||||
collector33.processResultTemplate(teaModuleConfig33.trace_output.result, traceQuestion33.default) ===
|
||||
'_bmad-output/test-artifacts/traceability',
|
||||
'ConfigCollector re-applies trace_output template without duplicating prefix',
|
||||
);
|
||||
} catch (error) {
|
||||
assert(false, 'ConfigCollector prompt normalization test succeeds', error.message);
|
||||
}
|
||||
|
||||
console.log('');
|
||||
|
||||
// ============================================================
|
||||
// Summary
|
||||
// ============================================================
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
* This file ensures proper execution when run via npx from GitHub or npm registry
|
||||
*/
|
||||
|
||||
const { execSync } = require('node:child_process');
|
||||
const { execFileSync } = require('node:child_process');
|
||||
const path = require('node:path');
|
||||
const fs = require('node:fs');
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ if (isNpxExecution) {
|
|||
|
||||
try {
|
||||
// Execute CLI from user's working directory (process.cwd()), not npm cache
|
||||
execSync(`node "${bmadCliPath}" ${args.join(' ')}`, {
|
||||
execFileSync('node', [bmadCliPath, ...args], {
|
||||
stdio: 'inherit',
|
||||
cwd: process.cwd(), // This preserves the user's working directory
|
||||
});
|
||||
|
|
|
|||
|
|
@ -954,31 +954,123 @@ class ConfigCollector {
|
|||
return match;
|
||||
}
|
||||
|
||||
// Look for the config value in allAnswers (already answered questions)
|
||||
let configValue = this.allAnswers[configKey] || this.allAnswers[`core_${configKey}`];
|
||||
|
||||
// Check in already collected config
|
||||
if (!configValue) {
|
||||
for (const mod of Object.keys(this.collectedConfig)) {
|
||||
if (mod !== '_meta' && this.collectedConfig[mod] && this.collectedConfig[mod][configKey]) {
|
||||
configValue = this.collectedConfig[mod][configKey];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If still not found and we're in the same module, use the default from the config schema
|
||||
if (!configValue && currentModule && moduleConfig && moduleConfig[configKey]) {
|
||||
const referencedItem = moduleConfig[configKey];
|
||||
if (referencedItem && referencedItem.default !== undefined) {
|
||||
configValue = referencedItem.default;
|
||||
}
|
||||
}
|
||||
const configValue = this.resolveConfigValue(configKey, currentModule, moduleConfig);
|
||||
|
||||
return configValue || match;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean a stored path-like value for prompt display/input reuse.
|
||||
* @param {*} value - Stored value
|
||||
* @returns {*} Cleaned value
|
||||
*/
|
||||
cleanPromptValue(value) {
|
||||
if (typeof value === 'string' && value.startsWith('{project-root}/')) {
|
||||
return value.replace('{project-root}/', '');
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a config key from answers, collected config, existing config, or schema defaults.
|
||||
* @param {string} configKey - Config key to resolve
|
||||
* @param {string} currentModule - Current module name
|
||||
* @param {Object} moduleConfig - Current module config schema
|
||||
* @returns {*} Resolved value
|
||||
*/
|
||||
resolveConfigValue(configKey, currentModule = null, moduleConfig = null) {
|
||||
// Look for the config value in allAnswers (already answered questions)
|
||||
let configValue = this.allAnswers?.[configKey] || this.allAnswers?.[`core_${configKey}`];
|
||||
|
||||
if (!configValue && this.allAnswers) {
|
||||
for (const [answerKey, answerValue] of Object.entries(this.allAnswers)) {
|
||||
if (answerKey.endsWith(`_${configKey}`)) {
|
||||
configValue = answerValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prefer the current module's persisted value when re-prompting an existing install
|
||||
if (!configValue && currentModule && this.existingConfig?.[currentModule]?.[configKey] !== undefined) {
|
||||
configValue = this.existingConfig[currentModule][configKey];
|
||||
}
|
||||
|
||||
// Check in already collected config
|
||||
if (!configValue) {
|
||||
for (const mod of Object.keys(this.collectedConfig)) {
|
||||
if (mod !== '_meta' && this.collectedConfig[mod] && this.collectedConfig[mod][configKey]) {
|
||||
configValue = this.collectedConfig[mod][configKey];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to other existing module config values
|
||||
if (!configValue && this.existingConfig) {
|
||||
for (const mod of Object.keys(this.existingConfig)) {
|
||||
if (mod !== '_meta' && this.existingConfig[mod] && this.existingConfig[mod][configKey]) {
|
||||
configValue = this.existingConfig[mod][configKey];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If still not found and we're in the same module, use the default from the config schema
|
||||
if (!configValue && currentModule && moduleConfig && moduleConfig[configKey]) {
|
||||
const referencedItem = moduleConfig[configKey];
|
||||
if (referencedItem && referencedItem.default !== undefined) {
|
||||
configValue = referencedItem.default;
|
||||
}
|
||||
}
|
||||
|
||||
return this.cleanPromptValue(configValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an existing stored value back into the prompt-facing value for templated fields.
|
||||
* For example, "{test_artifacts}/{value}" + "_bmad-output/test-artifacts/test-design"
|
||||
* becomes "test-design" so the template is not applied twice on modify.
|
||||
* @param {*} existingValue - Stored config value
|
||||
* @param {string} moduleName - Module name
|
||||
* @param {Object} item - Config item definition
|
||||
* @param {Object} moduleConfig - Current module config schema
|
||||
* @returns {*} Prompt-facing default value
|
||||
*/
|
||||
normalizeExistingValueForPrompt(existingValue, moduleName, item, moduleConfig = null) {
|
||||
const cleanedValue = this.cleanPromptValue(existingValue);
|
||||
|
||||
if (typeof cleanedValue !== 'string' || typeof item?.result !== 'string' || !item.result.includes('{value}')) {
|
||||
return cleanedValue;
|
||||
}
|
||||
|
||||
const [prefixTemplate = '', suffixTemplate = ''] = item.result.split('{value}');
|
||||
const prefix = this.cleanPromptValue(this.replacePlaceholders(prefixTemplate, moduleName, moduleConfig));
|
||||
const suffix = this.cleanPromptValue(this.replacePlaceholders(suffixTemplate, moduleName, moduleConfig));
|
||||
|
||||
if ((prefix && !cleanedValue.startsWith(prefix)) || (suffix && !cleanedValue.endsWith(suffix))) {
|
||||
return cleanedValue;
|
||||
}
|
||||
|
||||
const startIndex = prefix.length;
|
||||
const endIndex = suffix ? cleanedValue.length - suffix.length : cleanedValue.length;
|
||||
if (endIndex < startIndex) {
|
||||
return cleanedValue;
|
||||
}
|
||||
|
||||
let promptValue = cleanedValue.slice(startIndex, endIndex);
|
||||
if (promptValue.startsWith('/')) {
|
||||
promptValue = promptValue.slice(1);
|
||||
}
|
||||
if (promptValue.endsWith('/')) {
|
||||
promptValue = promptValue.slice(0, -1);
|
||||
}
|
||||
|
||||
return promptValue || cleanedValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a prompt question from a config item
|
||||
* @param {string} moduleName - Module name
|
||||
|
|
@ -993,12 +1085,7 @@ class ConfigCollector {
|
|||
let existingValue = null;
|
||||
if (this.existingConfig && this.existingConfig[moduleName]) {
|
||||
existingValue = this.existingConfig[moduleName][key];
|
||||
|
||||
// Clean up existing value - remove {project-root}/ prefix if present
|
||||
// This prevents duplication when the result template adds it back
|
||||
if (typeof existingValue === 'string' && existingValue.startsWith('{project-root}/')) {
|
||||
existingValue = existingValue.replace('{project-root}/', '');
|
||||
}
|
||||
existingValue = this.normalizeExistingValueForPrompt(existingValue, moduleName, item, moduleConfig);
|
||||
}
|
||||
|
||||
// Special handling for user_name: default to system user
|
||||
|
|
|
|||
Loading…
Reference in New Issue