Merge branch 'main' into docs/e2s5-e2s6-cn-howto
This commit is contained in:
commit
17d10f3f77
|
|
@ -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,9 +5,9 @@ sidebar:
|
|||
order: 6
|
||||
---
|
||||
|
||||
在现有项目和遗留代码库上工作时,有效使用 BMad Method。
|
||||
当你在现有项目或遗留代码库上工作时,本指南帮助你更稳妥地使用 BMad Method。
|
||||
|
||||
本指南涵盖了使用 BMad Method 接入现有项目的核心工作流程。
|
||||
如果你是从零开始的新项目,建议先看[快速入门](../tutorials/getting-started.md);本文主要面向既有项目接入场景。
|
||||
|
||||
:::note[前置条件]
|
||||
- 已安装 BMad Method(`npx bmad-method install`)
|
||||
|
|
@ -23,16 +23,16 @@ sidebar:
|
|||
- `_bmad-output/planning-artifacts/`
|
||||
- `_bmad-output/implementation-artifacts/`
|
||||
|
||||
## 步骤 2:创建项目上下文
|
||||
## 步骤 2:创建项目上下文(project context)
|
||||
|
||||
:::tip[推荐用于既有项目]
|
||||
生成 `project-context.md` 以捕获你现有代码库的模式和约定。这确保 AI 智能体在实施变更时遵循你既定的实践。
|
||||
生成 `project-context.md`,梳理现有代码库的模式与约定,确保 AI 智能体在实施变更时遵循你既有的工程实践。
|
||||
:::
|
||||
|
||||
运行生成项目上下文工作流程:
|
||||
运行生成项目上下文工作流:
|
||||
|
||||
```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)
|
||||
|
||||
|
|
@ -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 quick-flow 和完整方法有什么区别?
|
||||
bmad-help 显示我有哪些可用的工作流程
|
||||
bmad-help Quick Flow 和完整方法有什么区别?
|
||||
bmad-help 显示我当前有哪些可用工作流
|
||||
```
|
||||
|
||||
BMad-Help 还会在**每个工作流程结束时自动运行**,提供关于下一步该做什么的清晰指导。
|
||||
BMad-Help 还会在**每个工作流结束时自动运行**,明确告诉你下一步该做什么。
|
||||
|
||||
### 选择你的方法
|
||||
|
||||
根据变更范围,你有两个主要选项:
|
||||
|
||||
| 范围 | 推荐方法 |
|
||||
| ------------------------------ | ----------------------------------------------------------------------------------------------------------------- |
|
||||
| **小型更新或添加** | 运行 `bmad-quick-dev` 在单个工作流中澄清意图、规划、实现和审查。完整的四阶段 BMad Method 可能有些过度。 |
|
||||
| **重大变更或添加** | 从 BMad Method 开始,根据需要应用或多或少的严谨性。 |
|
||||
| --- | --- |
|
||||
| **小型更新或新增** | 运行 `bmad-quick-dev`,在单个工作流中完成意图澄清、规划、实现与审查。完整四阶段 BMad Method 往往过重。 |
|
||||
| **重大变更或新增** | 从完整 BMad Method 开始,再按项目风险和协作需求调整流程严谨度。 |
|
||||
|
||||
### 在创建 PRD 期间
|
||||
|
||||
在创建简报或直接进入 PRD 时,确保智能体:
|
||||
|
||||
- 查找并分析你现有的项目文档
|
||||
- 阅读关于你当前系统的适当上下文
|
||||
- 读取与你当前系统匹配的项目上下文(project context)
|
||||
|
||||
你可以明确地指导智能体,但目标是确保新功能与你的现有系统良好集成。
|
||||
你可以显式补充指令,但核心目标是让新功能与现有 architecture 和代码约束自然融合。
|
||||
|
||||
### UX 考量
|
||||
|
||||
UX 工作是可选的。决定不取决于你的项目是否有 UX,而取决于:
|
||||
UX 工作是可选项。是否需要进入 UX 流程,不取决于“项目里有没有 UX”,而取决于:
|
||||
|
||||
- 你是否将处理 UX 变更
|
||||
- 是否需要重要的新 UX 设计或模式
|
||||
- 你是否真的在做 UX 层面的变更
|
||||
- 是否需要新增重要的 UX 设计或交互模式
|
||||
|
||||
如果你的变更只是对你满意的现有屏幕进行简单更新,则不需要完整的 UX 流程。
|
||||
如果本次只是对现有页面做小幅调整,通常不需要完整 UX 流程。
|
||||
|
||||
### 架构考量
|
||||
### 架构考量(architecture)
|
||||
|
||||
在进行架构工作时,确保架构师:
|
||||
|
||||
- 使用适当的已记录文件
|
||||
- 扫描现有代码库
|
||||
- 使用正确且最新的文档输入
|
||||
- 扫描并理解现有代码库
|
||||
|
||||
在此处要密切注意,以防止重新发明轮子或做出与你现有架构不一致的决定。
|
||||
这一点非常关键:可避免“重复造轮子”,也能减少与现有架构冲突的设计决策。
|
||||
|
||||
## 更多信息
|
||||
|
||||
- **[快速修复](./quick-fixes.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**:运行时变体。在程序运行时可选择或切换的不同实现方式或配置。
|
||||
|
|
|
|||
|
|
@ -5,27 +5,30 @@ sidebar:
|
|||
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[前置条件]
|
||||
- 已安装 BMad Method
|
||||
- 了解项目的技术栈和约定
|
||||
- 了解项目的技术栈与团队约定
|
||||
:::
|
||||
|
||||
## 何时使用
|
||||
|
||||
- 在开始架构设计之前有明确的技术偏好
|
||||
- 已完成架构设计并希望为实施捕获决策
|
||||
- 正在处理具有既定模式的现有代码库
|
||||
- 注意到智能体在不同用户故事中做出不一致的决策
|
||||
- 在开始架构(architecture)前,你已有明确的技术偏好
|
||||
- 已完成架构设计,希望把关键决策沉淀到实施阶段
|
||||
- 正在处理具有既定模式的既有代码库
|
||||
- 发现智能体在不同用户故事(story)之间决策不一致
|
||||
|
||||
## 步骤 1:选择方法
|
||||
## 步骤 1:选择路径
|
||||
|
||||
**手动创建** — 当您确切知道要记录哪些规则时最佳
|
||||
**手动创建** — 适合你已经明确知道要沉淀哪些规则
|
||||
|
||||
**架构后生成** — 最适合捕获解决方案制定过程中所做的决策
|
||||
**架构后生成** — 适合把 solutioning 阶段形成的架构决策沉淀下来
|
||||
|
||||
**为现有项目生成** — 最适合在现有代码库中发现模式
|
||||
**为既有项目生成** — 适合从现有代码库中自动发现团队约定与模式
|
||||
|
||||
## 步骤 2:创建文件
|
||||
|
||||
|
|
@ -38,17 +41,17 @@ mkdir -p _bmad-output
|
|||
touch _bmad-output/project-context.md
|
||||
```
|
||||
|
||||
添加技术栈和实现规则:
|
||||
然后补充技术栈与实现规则:
|
||||
|
||||
```markdown
|
||||
---
|
||||
project_name: 'MyProject'
|
||||
user_name: 'YourName'
|
||||
project_name: '我的项目'
|
||||
user_name: '你的名字'
|
||||
date: '2026-02-15'
|
||||
sections_completed: ['technology_stack', 'critical_rules']
|
||||
---
|
||||
|
||||
# AI 智能体的项目上下文
|
||||
# AI 智能体项目上下文
|
||||
|
||||
## 技术栈与版本
|
||||
|
||||
|
|
@ -60,93 +63,70 @@ sections_completed: ['technology_stack', 'critical_rules']
|
|||
## 关键实现规则
|
||||
|
||||
**TypeScript:**
|
||||
- 启用严格模式,不使用 `any` 类型
|
||||
- 公共 API 使用 `interface`,联合类型使用 `type`
|
||||
- 开启严格模式,禁止使用 `any` 类型
|
||||
- 对外 API 使用 `interface`,联合类型使用 `type`
|
||||
|
||||
**代码组织:**
|
||||
- 组件位于 `/src/components/` 并附带同位置测试
|
||||
- API 调用使用 `apiClient` 单例 — 绝不直接使用 fetch
|
||||
- 组件放在 `/src/components/`,并与测试文件同目录(co-located)
|
||||
- API 调用统一使用 `apiClient` 单例,不要直接使用 `fetch`
|
||||
|
||||
**测试:**
|
||||
- 单元测试专注于业务逻辑
|
||||
- 集成测试使用 MSW 进行 API 模拟
|
||||
- 单元测试聚焦业务逻辑
|
||||
- 集成测试使用 MSW 模拟 API
|
||||
```
|
||||
|
||||
### 选项 B:架构后生成
|
||||
|
||||
在新的聊天中运行工作流程:
|
||||
在新的会话中运行:
|
||||
|
||||
```bash
|
||||
/bmad-bmm-generate-project-context
|
||||
bmad-generate-project-context
|
||||
```
|
||||
|
||||
工作流程扫描架构文档和项目文件,生成捕获所做决策的上下文文件。
|
||||
该工作流会扫描架构文档和项目文件,生成能够反映已做决策的上下文文件。
|
||||
|
||||
### 选项 C:为现有项目生成
|
||||
### 选项 C:为既有项目生成
|
||||
|
||||
对于现有项目,运行:
|
||||
对于既有项目,运行:
|
||||
|
||||
```bash
|
||||
/bmad-bmm-generate-project-context
|
||||
bmad-generate-project-context
|
||||
```
|
||||
|
||||
工作流程分析代码库以识别约定,然后生成上下文文件供您审查和完善。
|
||||
该工作流会分析代码库中的约定,然后生成可供你审阅和完善的上下文文件。
|
||||
|
||||
## 步骤 3:验证内容
|
||||
|
||||
审查生成的文件并确保它捕获了:
|
||||
审查生成文件,并确认它覆盖了:
|
||||
|
||||
- 正确的技术版本
|
||||
- 实际约定(而非通用最佳实践)
|
||||
- 防止常见错误的规则
|
||||
- 框架特定的模式
|
||||
- 你的真实约定(不是通用最佳实践)
|
||||
- 能预防常见错误的规则
|
||||
- 框架相关模式
|
||||
|
||||
手动编辑以添加任何缺失内容或删除不准确之处。
|
||||
如果有缺漏或误判,直接手动补充和修正。
|
||||
|
||||
## 您将获得
|
||||
## 你将获得
|
||||
|
||||
一个 `project-context.md` 文件,它:
|
||||
一个 `project-context.md` 文件,它可以:
|
||||
|
||||
- 确保所有智能体遵循相同的约定
|
||||
- 防止在不同用户故事中做出不一致的决策
|
||||
- 为实施捕获架构决策
|
||||
- 作为项目模式和规则的参考
|
||||
- 确保所有智能体遵循相同约定
|
||||
- 避免在不同用户故事(story)中出现不一致决策
|
||||
- 为实施阶段保留架构决策
|
||||
- 作为项目模式与规则的长期参考
|
||||
|
||||
## 提示
|
||||
|
||||
:::tip[关注非显而易见的内容]
|
||||
记录智能体可能遗漏的模式,例如"在每个公共类、函数和变量上使用 JSDoc 风格注释",而不是像"使用有意义的变量名"这样的通用实践,因为 LLM 目前已经知道这些。
|
||||
:::
|
||||
|
||||
:::tip[保持精简]
|
||||
此文件由每个实施工作流程加载。长文件会浪费上下文。不要包含仅适用于狭窄范围或特定用户故事或功能的内容。
|
||||
:::
|
||||
|
||||
:::tip[根据需要更新]
|
||||
当模式发生变化时手动编辑,或在重大架构更改后重新生成。
|
||||
:::
|
||||
|
||||
:::tip[适用于所有项目类型]
|
||||
对于快速流程和完整的 BMad Method 项目同样有用。
|
||||
:::tip[最佳实践]
|
||||
- **聚焦“不明显但重要”的规则**:优先记录智能体容易漏掉的项目约束,而不是
|
||||
“变量要有意义”这类通用建议。
|
||||
- **保持精简**:此文件会被多数实现工作流加载,过长会浪费上下文窗口。避免写入
|
||||
只适用于单一 story 的细节。
|
||||
- **按需更新**:当团队约定变化时手动更新,或在架构发生较大变化后重新生成。
|
||||
- **适用于 Quick Flow 与完整 BMad Method**:两种模式都可共享同一份项目上下文。
|
||||
:::
|
||||
|
||||
## 后续步骤
|
||||
|
||||
- [**项目上下文说明**](../explanation/project-context.md) — 了解其工作原理
|
||||
- [**工作流程图**](../reference/workflow-map.md) — 查看哪些工作流程加载项目上下文
|
||||
|
||||
---
|
||||
## 术语说明
|
||||
|
||||
- **agent**:智能体。在人工智能与编程文档中,指具备自主决策或执行能力的单元。
|
||||
- **workflow**:工作流程。指完成特定任务的一系列步骤或过程。
|
||||
- **codebase**:代码库。指项目的所有源代码和资源的集合。
|
||||
- **implementation**:实施。指将设计或架构转化为实际代码的过程。
|
||||
- **architecture**:架构。指系统的整体结构和设计。
|
||||
- **stack**:技术栈。指项目使用的技术组合,如编程语言、框架、工具等。
|
||||
- **convention**:约定。指团队或项目中遵循的编码规范和最佳实践。
|
||||
- **singleton**:单例。一种设计模式,确保类只有一个实例。
|
||||
- **co-located**:同位置。指相关文件(如测试文件)与主文件放在同一目录中。
|
||||
- **mocking**:模拟。在测试中用模拟对象替代真实对象的行为。
|
||||
- **context**:上下文。指程序运行时的环境信息或背景信息。
|
||||
- **LLM**:大语言模型。Large Language Model 的缩写,指大型语言模型。
|
||||
- [**项目上下文说明**](../explanation/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 |
|
||||
| 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).
|
||||
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 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
|
||||
|
||||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
### 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
|
||||
|
||||
Read fully and follow `./step-04-review.md`
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ YOU MUST ALWAYS SPEAK OUTPUT in your Agent communication style with the config `
|
|||
|
||||
### 2. Paths
|
||||
|
||||
- `wipFile` = `{implementation_artifacts}/tech-spec-wip.md`
|
||||
- `wipFile` = `{implementation_artifacts}/spec-wip.md`
|
||||
|
||||
### 3. First Step Execution
|
||||
|
||||
|
|
|
|||
|
|
@ -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,8 +954,49 @@ class ConfigCollector {
|
|||
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)
|
||||
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
|
||||
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 (!configValue && currentModule && moduleConfig && 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;
|
||||
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