Merge branch 'main' into docs/e2s5-e2s6-cn-howto

This commit is contained in:
Alex Verkhovsky 2026-03-23 19:19:44 -06:00 committed by GitHub
commit 17d10f3f77
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 332 additions and 177 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

@ -54,7 +54,7 @@ BMM 尊重你的选择——它不会强制现代化,但会提供现代化选
- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。 - **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。
- **Quick Flow**快速流程。BMad 方法中的一种工作流程,用于快速处理既有项目。 - **Quick Flow**快速流程。BMad 方法中的一种工作流程,用于快速处理既有项目。
- **tech-spec**技术规范。描述技术实现细节和标准的文档。 - **spec**:规范。描述技术实现细节和标准的文档。
- **stack**:技术栈。项目所使用的技术组合,包括框架、库、工具等。 - **stack**:技术栈。项目所使用的技术组合,包括框架、库、工具等。
- **conventions**:约定。代码库中遵循的编码风格、命名规则等规范。 - **conventions**:约定。代码库中遵循的编码风格、命名规则等规范。
- **modernization**:现代化。将旧代码或系统更新为更现代的技术和最佳实践的过程。 - **modernization**:现代化。将旧代码或系统更新为更现代的技术和最佳实践的过程。

View File

@ -5,9 +5,9 @@ sidebar:
order: 6 order: 6
--- ---
在现有项目和遗留代码库上工作时,有效使用 BMad Method。 当你在现有项目或遗留代码库上工作时,本指南帮助你更稳妥地使用 BMad Method。
本指南涵盖了使用 BMad Method 接入现有项目的核心工作流程 如果你是从零开始的新项目,建议先看[快速入门](../tutorials/getting-started.md);本文主要面向既有项目接入场景
:::note[前置条件] :::note[前置条件]
- 已安装 BMad Method`npx bmad-method install` - 已安装 BMad Method`npx bmad-method install`
@ -23,16 +23,16 @@ sidebar:
- `_bmad-output/planning-artifacts/` - `_bmad-output/planning-artifacts/`
- `_bmad-output/implementation-artifacts/` - `_bmad-output/implementation-artifacts/`
## 步骤 2创建项目上下文 ## 步骤 2创建项目上下文project context
:::tip[推荐用于既有项目] :::tip[推荐用于既有项目]
生成 `project-context.md` 以捕获你现有代码库的模式和约定。这确保 AI 智能体在实施变更时遵循你既定的实践。 生成 `project-context.md`,梳理现有代码库的模式与约定,确保 AI 智能体在实施变更时遵循你既有的工程实践。
::: :::
运行生成项目上下文工作流 运行生成项目上下文工作流:
```bash ```bash
/bmad-bmm-generate-project-context bmad-generate-project-context
``` ```
这将扫描你的代码库以识别: 这将扫描你的代码库以识别:
@ -40,9 +40,10 @@ sidebar:
- 代码组织模式 - 代码组织模式
- 命名约定 - 命名约定
- 测试方法 - 测试方法
- 框架特定模式 - 框架相关模式
你可以查看和完善生成的文件,或者如果你更喜欢,可以在 `_bmad-output/project-context.md` 手动创建它。 你可以先审阅并完善生成内容;如果更希望手动维护,也可以直接在
`_bmad-output/project-context.md` 创建并编辑。
[了解更多关于项目上下文](../explanation/project-context.md) [了解更多关于项目上下文](../explanation/project-context.md)
@ -55,80 +56,63 @@ sidebar:
- 架构 - 架构
- 任何其他相关的项目信息 - 任何其他相关的项目信息
对于复杂项目,考虑使用 `document-project` 工作流程。它提供运行时变体,将扫描你的整个项目并记录其实际当前状态。 对于复杂项目,可考虑使用 `bmad-document-project` 工作流。它会扫描整个项目并记录当前真实状态。
## 步骤 3:获取帮助 ## 步骤 4:获取帮助
### BMad-Help你的起点 ### BMad-Help默认起点
**随时运行 `bmad-help`,当你不确定下一步该做什么时。** 这个智能指南: **当你不确定下一步做什么时,随时运行 `bmad-help`。** 这个智能指南
- 检查你的项目以查看已经完成了什么 - 检查项目当前状态,识别哪些工作已经完成
- 根据你安装的模块显示选项 - 根据你安装的模块给出可行选项
- 理解自然语言查询 - 理解自然语言查询
``` ```
bmad-help 我有一个现有的 Rails 应用,我应该从哪里开始? bmad-help 我有一个现有的 Rails 应用,我应该从哪里开始?
bmad-help quick-flow 和完整方法有什么区别? bmad-help Quick Flow 和完整方法有什么区别?
bmad-help 显示我有哪些可用工作流 bmad-help 显示我当前有哪些可用工作流
``` ```
BMad-Help 还会在**每个工作流程结束时自动运行**,提供关于下一步该做什么的清晰指导 BMad-Help 还会在**每个工作流结束时自动运行**,明确告诉你下一步该做什么
### 选择你的方法 ### 选择你的方法
根据变更范围,你有两个主要选项: 根据变更范围,你有两个主要选项:
| 范围 | 推荐方法 | | 范围 | 推荐方法 |
| ------------------------------ | ----------------------------------------------------------------------------------------------------------------- | | --- | --- |
| **小型更新或添加** | 运行 `bmad-quick-dev` 在单个工作流中澄清意图、规划、实现和审查。完整的四阶段 BMad Method 可能有些过度。 | | **小型更新或新增** | 运行 `bmad-quick-dev`,在单个工作流中完成意图澄清、规划、实现与审查。完整四阶段 BMad Method 往往过重。 |
| **重大变更或添加** | 从 BMad Method 开始,根据需要应用或多或少的严谨性。 | | **重大变更或新增** | 从完整 BMad Method 开始,再按项目风险和协作需求调整流程严谨度。 |
### 在创建 PRD 期间 ### 在创建 PRD 期间
在创建简报或直接进入 PRD 时,确保智能体: 在创建简报或直接进入 PRD 时,确保智能体:
- 查找并分析你现有的项目文档 - 查找并分析你现有的项目文档
- 阅读关于你当前系统的适当上下文 - 读取与你当前系统匹配的项目上下文project context
你可以明确地指导智能体,但目标是确保新功能与你的现有系统良好集成 你可以显式补充指令,但核心目标是让新功能与现有 architecture 和代码约束自然融合
### UX 考量 ### UX 考量
UX 工作是可选的。决定不取决于你的项目是否有 UX,而取决于: UX 工作是可选项。是否需要进入 UX 流程,不取决于“项目里有没有 UX”,而取决于:
- 你是否将处理 UX 变更 - 你是否真的在做 UX 层面的变更
- 是否需要重要的 UX 设计或模式 - 是否需要新增重要的 UX 设计或交互模式
如果你的变更只是对你满意的现有屏幕进行简单更新,则不需要完整的 UX 流程。 如果本次只是对现有页面做小幅调整,通常不需要完整 UX 流程。
### 架构考量 ### 架构考量architecture
在进行架构工作时,确保架构师: 在进行架构工作时,确保架构师:
- 使用适当的已记录文件 - 使用正确且最新的文档输入
- 扫描现有代码库 - 扫描并理解现有代码库
在此处要密切注意,以防止重新发明轮子或做出与你现有架构不一致的决定 这一点非常关键:可避免“重复造轮子”,也能减少与现有架构冲突的设计决策
## 更多信息 ## 更多信息
- **[快速修复](./quick-fixes.md)** - 错误修复和临时变更 - **[快速修复](./quick-fixes.md)** - 错误修复和临时变更
- **[既有项目 FAQ](../explanation/established-projects-faq.md)** - 关于在既有项目上工作的常见问题 - **[既有项目 FAQ](../explanation/established-projects-faq.md)** - 关于在既有项目上工作的常见问题
---
## 术语说明
- **BMad Method**BMad 方法。一种结构化的软件开发方法论,用于指导从分析到实施的完整流程。
- **PRD**产品需求文档Product Requirements Document。描述产品功能、需求和目标的文档。
- **epic**:史诗。大型功能或用户故事的集合,通常需要较长时间完成。
- **story**:用户故事。描述用户需求的简短陈述,通常遵循"作为...我想要...以便于..."的格式。
- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。
- **IDE**集成开发环境Integrated Development Environment。提供代码编辑、调试、构建等功能的软件工具。
- **UX**用户体验User Experience。用户在使用产品或服务过程中的整体感受和交互体验。
- **tech-spec**技术规范Technical Specification。描述技术实现细节、架构设计和开发标准的文档。
- **quick-flow**快速流程。BMad Method 中的一种简化工作流程,适用于小型变更或快速迭代。
- **legacy codebase**:遗留代码库。指历史遗留的、可能缺乏文档或使用过时技术的代码集合。
- **project context**:项目上下文。描述项目技术栈、约定、模式等背景信息的文档。
- **artifact**:产物。在开发过程中生成的文档、代码或其他输出物。
- **runtime variant**:运行时变体。在程序运行时可选择或切换的不同实现方式或配置。

View File

@ -5,27 +5,30 @@ sidebar:
order: 8 order: 8
--- ---
使用 `project-context.md` 文件确保 AI 智能体在所有工作流程中遵循项目的技术偏好和实现规则。 使用 `project-context.md`,确保 AI 智能体在各类工作流中遵循项目的技术偏好与实现规则。
为了保证这份上下文始终可见,你也可以在工具上下文或 always-rules 文件(如 `AGENTS.md`
中加入这句:
`Important project context and conventions are located in [path to project context]/project-context.md`
:::note[前置条件] :::note[前置条件]
- 已安装 BMad Method - 已安装 BMad Method
- 了解项目的技术栈约定 - 了解项目的技术栈与团队约定
::: :::
## 何时使用 ## 何时使用
- 在开始架构设计之前有明确的技术偏好 - 在开始架构architecture你已有明确的技术偏好
- 已完成架构设计并希望为实施捕获决策 - 已完成架构设计,希望把关键决策沉淀到实施阶段
- 正在处理具有既定模式的有代码库 - 正在处理具有既定模式的有代码库
- 注意到智能体在不同用户故事中做出不一致的决策 - 发现智能体在不同用户故事story之间决策不一致
## 步骤 1选择方法 ## 步骤 1选择路径
**手动创建** — 当您确切知道要记录哪些规则时最佳 **手动创建** — 适合你已经明确知道要沉淀哪些规则
**架构后生成** — 最适合捕获解决方案制定过程中所做的决策 **架构后生成** — 适合把 solutioning 阶段形成的架构决策沉淀下来
**为现有项目生成** — 最适合在现有代码库中发现模式 **为既有项目生成** — 适合从现有代码库中自动发现团队约定与模式
## 步骤 2创建文件 ## 步骤 2创建文件
@ -38,17 +41,17 @@ mkdir -p _bmad-output
touch _bmad-output/project-context.md touch _bmad-output/project-context.md
``` ```
添加技术栈和实现规则: 然后补充技术栈与实现规则:
```markdown ```markdown
--- ---
project_name: 'MyProject' project_name: '我的项目'
user_name: 'YourName' user_name: '你的名字'
date: '2026-02-15' date: '2026-02-15'
sections_completed: ['technology_stack', 'critical_rules'] sections_completed: ['technology_stack', 'critical_rules']
--- ---
# AI 智能体项目上下文 # AI 智能体项目上下文
## 技术栈与版本 ## 技术栈与版本
@ -60,93 +63,70 @@ sections_completed: ['technology_stack', 'critical_rules']
## 关键实现规则 ## 关键实现规则
**TypeScript** **TypeScript**
- 启用严格模式,不使用 `any` 类型 - 开启严格模式,禁止使用 `any` 类型
- 公共 API 使用 `interface`,联合类型使用 `type` - 对外 API 使用 `interface`,联合类型使用 `type`
**代码组织:** **代码组织:**
- 组件位于 `/src/components/` 并附带同位置测试 - 组件放在 `/src/components/`并与测试文件同目录co-located
- API 调用使用 `apiClient` 单例 — 绝不直接使用 fetch - API 调用统一使用 `apiClient` 单例,不要直接使用 `fetch`
**测试:** **测试:**
- 单元测试专注于业务逻辑 - 单元测试聚焦业务逻辑
- 集成测试使用 MSW 进行 API 模拟 - 集成测试使用 MSW 模拟 API
``` ```
### 选项 B架构后生成 ### 选项 B架构后生成
在新的聊天中运行工作流程 在新的会话中运行
```bash ```bash
/bmad-bmm-generate-project-context bmad-generate-project-context
``` ```
工作流程扫描架构文档和项目文件,生成捕获所做决策的上下文文件。 该工作流会扫描架构文档和项目文件,生成能够反映已做决策的上下文文件。
### 选项 C有项目生成 ### 选项 C有项目生成
对于有项目,运行: 对于有项目,运行:
```bash ```bash
/bmad-bmm-generate-project-context bmad-generate-project-context
``` ```
工作流程分析代码库以识别约定,然后生成上下文文件供您审查和完善 该工作流会分析代码库中的约定,然后生成可供你审阅和完善的上下文文件
## 步骤 3验证内容 ## 步骤 3验证内容
审查生成的文件并确保它捕获了: 审查生成文件,并确认它覆盖了:
- 正确的技术版本 - 正确的技术版本
- 实际约定(而非通用最佳实践) - 你的真实约定(不是通用最佳实践)
- 防常见错误的规则 - 能预防常见错误的规则
- 框架特定的模式 - 框架相关模式
手动编辑以添加任何缺失内容或删除不准确之处 如果有缺漏或误判,直接手动补充和修正
## 将获得 ## 将获得
一个 `project-context.md` 文件,它: 一个 `project-context.md` 文件,它可以
- 确保所有智能体遵循相同约定 - 确保所有智能体遵循相同约定
- 防止在不同用户故事中做出不一致的决策 - 避免在不同用户故事story中出现不一致决策
- 为实施捕获架构决策 - 为实施阶段保留架构决策
- 作为项目模式和规则的参考 - 作为项目模式与规则的长期参考
## 提示 ## 提示
:::tip[关注非显而易见的内容] :::tip[最佳实践]
记录智能体可能遗漏的模式,例如"在每个公共类、函数和变量上使用 JSDoc 风格注释",而不是像"使用有意义的变量名"这样的通用实践,因为 LLM 目前已经知道这些。 - **聚焦“不明显但重要”的规则**:优先记录智能体容易漏掉的项目约束,而不是
::: “变量要有意义”这类通用建议。
- **保持精简**:此文件会被多数实现工作流加载,过长会浪费上下文窗口。避免写入
:::tip[保持精简] 只适用于单一 story 的细节。
此文件由每个实施工作流程加载。长文件会浪费上下文。不要包含仅适用于狭窄范围或特定用户故事或功能的内容。 - **按需更新**:当团队约定变化时手动更新,或在架构发生较大变化后重新生成。
::: - **适用于 Quick Flow 与完整 BMad Method**:两种模式都可共享同一份项目上下文。
:::tip[根据需要更新]
当模式发生变化时手动编辑,或在重大架构更改后重新生成。
:::
:::tip[适用于所有项目类型]
对于快速流程和完整的 BMad Method 项目同样有用。
::: :::
## 后续步骤 ## 后续步骤
- [**项目上下文说明**](../explanation/project-context.md) — 了解其工作原理 - [**项目上下文说明**](../explanation/project-context.md) - 了解其工作原理
- [**工作流程图**](../reference/workflow-map.md) — 查看哪些工作流程加载项目上下文 - [**工作流程图**](../reference/workflow-map.md) - 查看哪些工作流会加载项目上下文
---
## 术语说明
- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。
- **workflow**:工作流程。指完成特定任务的一系列步骤或过程。
- **codebase**:代码库。指项目的所有源代码和资源的集合。
- **implementation**:实施。指将设计或架构转化为实际代码的过程。
- **architecture**:架构。指系统的整体结构和设计。
- **stack**:技术栈。指项目使用的技术组合,如编程语言、框架、工具等。
- **convention**:约定。指团队或项目中遵循的编码规范和最佳实践。
- **singleton**:单例。一种设计模式,确保类只有一个实例。
- **co-located**:同位置。指相关文件(如测试文件)与主文件放在同一目录中。
- **mocking**:模拟。在测试中用模拟对象替代真实对象的行为。
- **context**:上下文。指程序运行时的环境信息或背景信息。
- **LLM**大语言模型。Large Language Model 的缩写,指大型语言模型。

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)
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. - `{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). - 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

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

@ -28,6 +28,10 @@ Hand `{spec_file}` to a sub-agent/task and let it implement. If no sub-agents ar
**Path formatting rule:** Any markdown links written into `{spec_file}` must use paths relative to `{spec_file}`'s directory so they are clickable in VS Code. Any file paths displayed in terminal/conversation output must use CWD-relative format with `:line` notation (e.g., `src/path/file.ts:42`) for terminal clickability. No leading `/` in either case. **Path formatting rule:** Any markdown links written into `{spec_file}` must use paths relative to `{spec_file}`'s directory so they are clickable in VS Code. Any file paths displayed in terminal/conversation output must use CWD-relative format with `:line` notation (e.g., `src/path/file.ts:42`) for terminal clickability. No leading `/` in either case.
### Self-Check
Before leaving this step, verify every task in the `## Tasks & Acceptance` section of `{spec_file}` is complete. Mark each finished task `[x]`. If any task is not done, finish it before proceeding.
## NEXT ## NEXT
Read fully and follow `./step-04-review.md` Read fully and follow `./step-04-review.md`

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,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