bmad-method 6.2.3-next.0 → 6.2.3-next.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/.claude-plugin/marketplace.json +0 -1
  2. package/package.json +9 -8
  3. package/src/bmm-skills/1-analysis/bmad-agent-analyst/SKILL.md +7 -4
  4. package/src/bmm-skills/1-analysis/bmad-agent-tech-writer/SKILL.md +6 -4
  5. package/src/bmm-skills/1-analysis/bmad-document-project/workflow.md +8 -10
  6. package/src/bmm-skills/1-analysis/bmad-prfaq/SKILL.md +96 -0
  7. package/src/bmm-skills/1-analysis/bmad-prfaq/agents/artifact-analyzer.md +60 -0
  8. package/src/bmm-skills/1-analysis/bmad-prfaq/agents/web-researcher.md +49 -0
  9. package/src/bmm-skills/1-analysis/bmad-prfaq/assets/prfaq-template.md +62 -0
  10. package/src/bmm-skills/1-analysis/bmad-prfaq/bmad-manifest.json +16 -0
  11. package/src/bmm-skills/1-analysis/bmad-prfaq/references/customer-faq.md +55 -0
  12. package/src/bmm-skills/1-analysis/bmad-prfaq/references/internal-faq.md +51 -0
  13. package/src/bmm-skills/1-analysis/bmad-prfaq/references/press-release.md +60 -0
  14. package/src/bmm-skills/1-analysis/bmad-prfaq/references/verdict.md +79 -0
  15. package/src/bmm-skills/1-analysis/bmad-product-brief/SKILL.md +1 -6
  16. package/src/bmm-skills/1-analysis/bmad-product-brief/bmad-manifest.json +1 -1
  17. package/src/bmm-skills/1-analysis/research/bmad-domain-research/workflow.md +8 -6
  18. package/src/bmm-skills/1-analysis/research/bmad-market-research/workflow.md +8 -6
  19. package/src/bmm-skills/1-analysis/research/bmad-technical-research/workflow.md +8 -6
  20. package/src/bmm-skills/2-plan-workflows/bmad-agent-pm/SKILL.md +6 -4
  21. package/src/bmm-skills/2-plan-workflows/bmad-agent-ux-designer/SKILL.md +6 -4
  22. package/src/bmm-skills/2-plan-workflows/bmad-create-prd/workflow.md +8 -9
  23. package/src/bmm-skills/2-plan-workflows/bmad-create-ux-design/workflow.md +8 -9
  24. package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-01-discovery.md +1 -1
  25. package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-01b-legacy-conversion.md +1 -1
  26. package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-02-review.md +1 -1
  27. package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-03-edit.md +1 -1
  28. package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/steps-e/step-e-04-complete.md +1 -1
  29. package/src/bmm-skills/2-plan-workflows/bmad-edit-prd/workflow.md +8 -9
  30. package/src/bmm-skills/2-plan-workflows/bmad-validate-prd/workflow.md +8 -9
  31. package/src/bmm-skills/3-solutioning/bmad-agent-architect/SKILL.md +6 -4
  32. package/src/bmm-skills/3-solutioning/bmad-check-implementation-readiness/workflow.md +8 -10
  33. package/src/bmm-skills/3-solutioning/bmad-create-architecture/workflow.md +8 -14
  34. package/src/bmm-skills/3-solutioning/bmad-create-epics-and-stories/workflow.md +10 -12
  35. package/src/bmm-skills/3-solutioning/bmad-generate-project-context/workflow.md +8 -12
  36. package/src/bmm-skills/4-implementation/bmad-agent-dev/SKILL.md +6 -4
  37. package/src/bmm-skills/4-implementation/bmad-agent-qa/SKILL.md +6 -4
  38. package/src/bmm-skills/4-implementation/bmad-agent-quick-flow-solo-dev/SKILL.md +6 -4
  39. package/src/bmm-skills/4-implementation/bmad-agent-sm/SKILL.md +6 -4
  40. package/src/bmm-skills/module-help.csv +2 -1
  41. package/src/core-skills/bmad-advanced-elicitation/SKILL.md +1 -2
  42. package/src/core-skills/bmad-distillator/SKILL.md +0 -1
  43. package/src/core-skills/bmad-distillator/resources/distillate-format-reference.md +10 -10
  44. package/src/core-skills/bmad-party-mode/SKILL.md +121 -2
  45. package/tools/{cli → installer}/bmad-cli.js +3 -1
  46. package/tools/{cli/lib → installer}/cli-utils.js +3 -4
  47. package/tools/{cli → installer}/commands/install.js +3 -3
  48. package/tools/{cli → installer}/commands/status.js +4 -4
  49. package/tools/{cli → installer}/commands/uninstall.js +5 -5
  50. package/tools/installer/core/config.js +52 -0
  51. package/tools/{cli/installers/lib → installer}/core/custom-module-cache.js +1 -1
  52. package/tools/installer/core/existing-install.js +127 -0
  53. package/tools/installer/core/install-paths.js +129 -0
  54. package/tools/installer/core/installer.js +1790 -0
  55. package/tools/{cli/installers/lib → installer}/core/manifest-generator.js +3 -3
  56. package/tools/{cli/installers/lib → installer}/core/manifest.js +2 -2
  57. package/tools/{cli/installers/lib/custom/handler.js → installer/custom-handler.js} +1 -1
  58. package/tools/{cli/installers/lib → installer}/ide/_config-driven.js +30 -397
  59. package/tools/{cli/installers/lib → installer}/ide/manager.js +1 -53
  60. package/tools/installer/ide/platform-codes.js +37 -0
  61. package/tools/installer/ide/platform-codes.yaml +192 -0
  62. package/tools/{cli/installers/lib → installer}/ide/shared/module-injections.js +1 -1
  63. package/tools/{cli/installers/lib → installer}/message-loader.js +2 -2
  64. package/tools/installer/modules/custom-modules.js +197 -0
  65. package/tools/installer/modules/external-manager.js +354 -0
  66. package/tools/{cli/installers/lib/core/config-collector.js → installer/modules/official-modules.js} +714 -43
  67. package/tools/{cli/lib → installer}/ui.js +65 -299
  68. package/tools/javascript-conventions.md +5 -0
  69. package/tools/platform-codes.yaml +6 -0
  70. package/src/bmm-skills/2-plan-workflows/create-prd/data/domain-complexity.csv +0 -15
  71. package/src/bmm-skills/2-plan-workflows/create-prd/data/prd-purpose.md +0 -197
  72. package/src/bmm-skills/2-plan-workflows/create-prd/data/project-types.csv +0 -11
  73. package/src/bmm-skills/2-plan-workflows/create-prd/steps-v/step-v-01-discovery.md +0 -224
  74. package/src/bmm-skills/2-plan-workflows/create-prd/steps-v/step-v-02-format-detection.md +0 -191
  75. package/src/bmm-skills/2-plan-workflows/create-prd/steps-v/step-v-02b-parity-check.md +0 -209
  76. package/src/bmm-skills/2-plan-workflows/create-prd/steps-v/step-v-03-density-validation.md +0 -174
  77. package/src/bmm-skills/2-plan-workflows/create-prd/steps-v/step-v-04-brief-coverage-validation.md +0 -214
  78. package/src/bmm-skills/2-plan-workflows/create-prd/steps-v/step-v-05-measurability-validation.md +0 -228
  79. package/src/bmm-skills/2-plan-workflows/create-prd/steps-v/step-v-06-traceability-validation.md +0 -217
  80. package/src/bmm-skills/2-plan-workflows/create-prd/steps-v/step-v-07-implementation-leakage-validation.md +0 -205
  81. package/src/bmm-skills/2-plan-workflows/create-prd/steps-v/step-v-08-domain-compliance-validation.md +0 -243
  82. package/src/bmm-skills/2-plan-workflows/create-prd/steps-v/step-v-09-project-type-validation.md +0 -263
  83. package/src/bmm-skills/2-plan-workflows/create-prd/steps-v/step-v-10-smart-validation.md +0 -209
  84. package/src/bmm-skills/2-plan-workflows/create-prd/steps-v/step-v-11-holistic-quality-validation.md +0 -264
  85. package/src/bmm-skills/2-plan-workflows/create-prd/steps-v/step-v-12-completeness-validation.md +0 -242
  86. package/src/bmm-skills/2-plan-workflows/create-prd/steps-v/step-v-13-report-complete.md +0 -232
  87. package/src/bmm-skills/2-plan-workflows/create-prd/workflow-validate-prd.md +0 -65
  88. package/src/core-skills/bmad-init/SKILL.md +0 -100
  89. package/src/core-skills/bmad-init/resources/core-module.yaml +0 -25
  90. package/src/core-skills/bmad-init/scripts/bmad_init.py +0 -624
  91. package/src/core-skills/bmad-init/scripts/tests/test_bmad_init.py +0 -393
  92. package/src/core-skills/bmad-party-mode/steps/step-01-agent-loading.md +0 -138
  93. package/src/core-skills/bmad-party-mode/steps/step-02-discussion-orchestration.md +0 -187
  94. package/src/core-skills/bmad-party-mode/steps/step-03-graceful-exit.md +0 -167
  95. package/src/core-skills/bmad-party-mode/workflow.md +0 -190
  96. package/tools/bmad-npx-wrapper.js +0 -38
  97. package/tools/cli/installers/lib/core/dependency-resolver.js +0 -743
  98. package/tools/cli/installers/lib/core/detector.js +0 -223
  99. package/tools/cli/installers/lib/core/ide-config-manager.js +0 -157
  100. package/tools/cli/installers/lib/core/installer.js +0 -3002
  101. package/tools/cli/installers/lib/ide/_base-ide.js +0 -657
  102. package/tools/cli/installers/lib/ide/platform-codes.js +0 -100
  103. package/tools/cli/installers/lib/ide/platform-codes.yaml +0 -341
  104. package/tools/cli/installers/lib/modules/external-manager.js +0 -136
  105. package/tools/cli/installers/lib/modules/manager.js +0 -928
  106. package/tools/cli/lib/config.js +0 -213
  107. package/tools/cli/lib/platform-codes.js +0 -116
  108. package/tools/lib/xml-utils.js +0 -13
  109. /package/tools/{cli → installer}/README.md +0 -0
  110. /package/tools/{cli → installer}/external-official-modules.yaml +0 -0
  111. /package/tools/{cli/lib → installer}/file-ops.js +0 -0
  112. /package/tools/{cli/installers/lib → installer}/ide/shared/agent-command-generator.js +0 -0
  113. /package/tools/{cli/installers/lib → installer}/ide/shared/bmad-artifacts.js +0 -0
  114. /package/tools/{cli/installers/lib → installer}/ide/shared/path-utils.js +0 -0
  115. /package/tools/{cli/installers/lib → installer}/ide/shared/skill-manifest.js +0 -0
  116. /package/tools/{cli/installers/lib → installer}/ide/templates/agent-command-template.md +0 -0
  117. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/antigravity.md +0 -0
  118. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/default-agent.md +0 -0
  119. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/default-task.md +0 -0
  120. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/default-tool.md +0 -0
  121. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/default-workflow.md +0 -0
  122. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/gemini-agent.toml +0 -0
  123. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/gemini-task.toml +0 -0
  124. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/gemini-tool.toml +0 -0
  125. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/gemini-workflow-yaml.toml +0 -0
  126. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/gemini-workflow.toml +0 -0
  127. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/kiro-agent.md +0 -0
  128. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/kiro-task.md +0 -0
  129. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/kiro-tool.md +0 -0
  130. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/kiro-workflow.md +0 -0
  131. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/opencode-agent.md +0 -0
  132. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/opencode-task.md +0 -0
  133. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/opencode-tool.md +0 -0
  134. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/opencode-workflow-yaml.md +0 -0
  135. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/opencode-workflow.md +0 -0
  136. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/rovodev.md +0 -0
  137. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/trae.md +0 -0
  138. /package/tools/{cli/installers/lib → installer}/ide/templates/combined/windsurf-workflow.md +0 -0
  139. /package/tools/{cli/installers/lib → installer}/ide/templates/split/.gitkeep +0 -0
  140. /package/tools/{cli/installers → installer}/install-messages.yaml +0 -0
  141. /package/tools/{cli/lib → installer}/project-root.js +0 -0
  142. /package/tools/{cli/lib → installer}/prompts.js +0 -0
  143. /package/tools/{cli/lib → installer}/yaml-format.js +0 -0
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: bmad-distillator
3
3
  description: Lossless LLM-optimized compression of source documents. Use when the user requests to 'distill documents' or 'create a distillate'.
4
- argument-hint: "[to create provide input paths] [--validate distillate-path to confirm distillate is lossless and optimized]"
5
4
  ---
6
5
 
7
6
  # Distillator: A Document Distillation Engine
@@ -81,18 +81,18 @@ When the same fact appears in both a brief and discovery notes:
81
81
 
82
82
  **Brief says:**
83
83
  ```
84
- bmad-init must always be included as a base skill in every bundle
84
+ bmad-help must always be included as a base skill in every bundle
85
85
  ```
86
86
 
87
87
  **Discovery notes say:**
88
88
  ```
89
- bmad-init must always be included as a base skill in every bundle/install
90
- (solves bootstrapping problem)
89
+ bmad-help must always be included as a base skill in every bundle/install
90
+ (solves discoverability problem)
91
91
  ```
92
92
 
93
93
  **Distillate keeps the more contextual version:**
94
94
  ```
95
- - bmad-init: always included as base skill in every bundle (solves bootstrapping)
95
+ - bmad-help: always included as base skill in every bundle (solves discoverability)
96
96
  ```
97
97
 
98
98
  ### Decision/Rationale Compression
@@ -128,7 +128,7 @@ parts: 1
128
128
 
129
129
  ## Core Concept
130
130
  - BMAD Next-Gen Installer: replaces monolithic Node.js CLI with skill-based plugin architecture for distributing BMAD methodology across 40+ AI platforms
131
- - Three layers: self-describing plugins (bmad-manifest.json), cross-platform install via Vercel skills CLI (MIT), runtime registration via bmad-init skill
131
+ - Three layers: self-describing plugins (bmad-manifest.json), cross-platform install via Vercel skills CLI (MIT), runtime registration via bmad-setup skill
132
132
  - Transforms BMAD from dev-only methodology into open platform for any domain (creative, therapeutic, educational, personal)
133
133
 
134
134
  ## Problem
@@ -141,7 +141,7 @@ parts: 1
141
141
  - Plugins: skill bundles with Anthropic plugin standard as base format + bmad-manifest.json extending for BMAD-specific metadata (installer options, capabilities, help integration, phase ordering, dependencies)
142
142
  - Existing manifest example: `{"module-code":"bmm","replaces-skill":"bmad-create-product-brief","capabilities":[{"name":"create-brief","menu-code":"CB","supports-headless":true,"phase-name":"1-analysis","after":["brainstorming"],"before":["create-prd"],"is-required":true}]}`
143
143
  - Vercel skills CLI handles platform translation; integration pattern (wrap/fork/call) is PRD decision
144
- - bmad-init: global skill scanning installed bmad-manifest.json files, registering capabilities, configuring project settings; always included as base skill in every bundle (solves bootstrapping)
144
+ - bmad-setup: global skill scanning installed bmad-manifest.json files, registering capabilities, configuring project settings; always included as base skill in every bundle (solves bootstrapping)
145
145
  - bmad-update: plugin update path without full reinstall; technical approach (diff/replace/preserve customizations) is PRD decision
146
146
  - Distribution tiers: (1) NPX installer wrapping skills CLI for technical users, (2) zip bundle + platform-specific README for non-technical users, (3) future marketplace
147
147
  - Non-technical path has honest friction: "copy to right folder" requires knowing where; per-platform README instructions; improves over time as low-code space matures
@@ -161,18 +161,18 @@ parts: 1
161
161
  - Zero (or near-zero) custom platform directory code; delegated to skills CLI ecosystem
162
162
  - Installation verified on top platforms by volume; skills CLI handles long tail
163
163
  - Non-technical install path validated with non-developer users
164
- - bmad-init discovers/registers all plugins from manifests; clear errors for malformed manifests
164
+ - bmad-setup discovers/registers all plugins from manifests; clear errors for malformed manifests
165
165
  - At least one external module author successfully publishes plugin using manifest system
166
166
  - bmad-update works without full reinstall
167
167
  - Existing CLI users have documented migration path
168
168
 
169
169
  ## Scope
170
- - In: manifest spec, bmad-init, bmad-update, Vercel CLI integration, NPX installer, zip bundles, migration path
170
+ - In: manifest spec, bmad-setup, bmad-update, Vercel CLI integration, NPX installer, zip bundles, migration path
171
171
  - Out: BMAD Builder, marketplace web platform, skill conversion (prerequisite, separate), one-click install for all platforms, monetization, quality certification process (gated-submission principle is architectural requirement; process defined separately)
172
172
  - Deferred: CI/CD integration, telemetry for module authors, air-gapped enterprise install, zip bundle integrity verification (checksums/signing), deeper non-technical platform integrations
173
173
 
174
174
  ## Current Installer (migration context)
175
- - Entry: `tools/cli/bmad-cli.js` (Commander.js) → `tools/cli/installers/lib/core/installer.js`
175
+ - Entry: `tools/installer/bmad-cli.js` (Commander.js) → `tools/installer/core/installer.js`
176
176
  - Platforms: `platform-codes.yaml` (~20 platforms with target dirs, legacy dirs, template types, special flags)
177
177
  - Manifests: CSV files (skill/workflow/agent-manifest.csv) are current source of truth, not JSON
178
178
  - External modules: `external-official-modules.yaml` (CIS, GDS, TEA, WDS) from npm with semver
@@ -214,7 +214,7 @@ parts: 1
214
214
 
215
215
  ## Opportunities
216
216
  - Module authors as acquisition channel: each published plugin distributes BMAD to creator's audience
217
- - CI/CD integration: bmad-init as pipeline one-liner increases stickiness
217
+ - CI/CD integration: bmad-setup as pipeline one-liner increases stickiness
218
218
  - Educational institutions: structured methodology + non-technical install → university AI curriculum
219
219
  - Skill composability: mixing BMAD modules with third-party skills for custom methodology stacks
220
220
 
@@ -1,6 +1,125 @@
1
1
  ---
2
2
  name: bmad-party-mode
3
- description: 'Orchestrates group discussions between all installed BMAD agents, enabling natural multi-agent conversations. Use when user requests party mode.'
3
+ description: 'Orchestrates group discussions between installed BMAD agents, enabling natural multi-agent conversations where each agent is a real subagent with independent thinking. Use when user requests party mode, wants multiple agent perspectives, group discussion, roundtable, or multi-agent conversation about their project.'
4
4
  ---
5
5
 
6
- Follow the instructions in ./workflow.md.
6
+ # Party Mode
7
+
8
+ Facilitate roundtable discussions where BMAD agents participate as **real subagents** — each spawned independently via the Agent tool so they think for themselves. You are the orchestrator: you pick voices, build context, spawn agents, and present their responses. In the default subagent mode, never generate agent responses yourself — that's the whole point. In `--solo` mode, you roleplay all agents directly.
9
+
10
+ ## Why This Matters
11
+
12
+ The whole point of party mode is that each agent produces a genuinely independent perspective. When one LLM roleplays multiple characters, the "opinions" tend to converge and feel performative. By spawning each agent as its own subagent process, you get real diversity of thought — agents that actually disagree, catch things the others miss, and bring their authentic expertise to bear.
13
+
14
+ ## Arguments
15
+
16
+ Party mode accepts optional arguments when invoked:
17
+
18
+ - `--model <model>` — Force all subagents to use a specific model (e.g. `--model haiku`, `--model opus`). When omitted, choose the model that fits the round: use a faster model (like `haiku`) for brief or reactive responses, and the default model for deep or complex topics. Match model weight to the depth of thinking the round requires.
19
+ - `--solo` — Run without subagents. Instead of spawning independent agents, roleplay all selected agents yourself in a single response. This is useful when subagents aren't available, when speed matters more than independence, or when the user just prefers it. Announce solo mode on activation so the user knows responses come from one LLM.
20
+
21
+ ## On Activation
22
+
23
+ 1. **Parse arguments** — check for `--model` and `--solo` flags from the user's invocation.
24
+
25
+ 2. Load config from `{project-root}/_bmad/core/config.yaml` and resolve:
26
+ - Use `{user_name}` for greeting
27
+ - Use `{communication_language}` for all communications
28
+
29
+ 3. **Read the agent manifest** at `{project-root}/_bmad/_config/agent-manifest.csv`. Build an internal roster of available agents with their displayName, title, icon, role, identity, communicationStyle, and principles.
30
+
31
+ 4. **Load project context** — search for `**/project-context.md`. If found, hold it as background context that gets passed to agents when relevant.
32
+
33
+ 5. **Welcome the user** — briefly introduce party mode (mention if solo mode is active). Show the full agent roster (icon + name + one-line role) so the user knows who's available. Ask what they'd like to discuss.
34
+
35
+ ## The Core Loop
36
+
37
+ For each user message:
38
+
39
+ ### 1. Pick the Right Voices
40
+
41
+ Choose 2-4 agents whose expertise is most relevant to what the user is asking. Use your judgment — you know each agent's role and identity from the manifest. Some guidelines:
42
+
43
+ - **Simple question**: 2 agents with the most relevant expertise
44
+ - **Complex or cross-cutting topic**: 3-4 agents from different domains
45
+ - **User names specific agents**: Always include those, plus 1-2 complementary voices
46
+ - **User asks an agent to respond to another**: Spawn just that agent with the other's response as context
47
+ - **Rotate over time** — avoid the same 2 agents dominating every round
48
+
49
+ ### 2. Build Context and Spawn
50
+
51
+ For each selected agent, spawn a subagent using the Agent tool. Each subagent gets:
52
+
53
+ **The agent prompt** (built from the manifest data):
54
+ ```
55
+ You are {displayName} ({title}), a BMAD agent in a collaborative roundtable discussion.
56
+
57
+ ## Your Persona
58
+ - Icon: {icon}
59
+ - Communication Style: {communicationStyle}
60
+ - Principles: {principles}
61
+ - Identity: {identity}
62
+
63
+ ## Discussion Context
64
+ {summary of the conversation so far — keep under 400 words}
65
+
66
+ {project context if relevant}
67
+
68
+ ## What Other Agents Said This Round
69
+ {if this is a cross-talk or reaction request, include the responses being reacted to — otherwise omit this section}
70
+
71
+ ## The User's Message
72
+ {the user's actual message}
73
+
74
+ ## Guidelines
75
+ - Respond authentically as {displayName}. Your perspective should reflect your genuine expertise.
76
+ - Start your response with: {icon} **{displayName}:**
77
+ - Speak in {communication_language}.
78
+ - Scale your response to the substance — don't pad. If you have a brief point, make it briefly.
79
+ - Disagree with other agents when your expertise tells you to. Don't hedge or be polite about it.
80
+ - If you have nothing substantive to add, say so in one sentence rather than manufacturing an opinion.
81
+ - You may ask the user direct questions if something needs clarification.
82
+ - Do NOT use tools. Just respond with your perspective.
83
+ ```
84
+
85
+ **Spawn all agents in parallel** — put all Agent tool calls in a single response so they run concurrently. If `--model` was specified, use that model for all subagents. Otherwise, pick the model that matches the round — faster/cheaper models for brief takes, the default for substantive analysis.
86
+
87
+ **Solo mode** — if `--solo` is active, skip spawning. Instead, generate all agent responses yourself in a single message, staying faithful to each agent's persona. Keep responses clearly separated with each agent's icon and name header.
88
+
89
+ ### 3. Present Responses
90
+
91
+ Present each agent's full response to the user — distinct, complete, and in their own voice. The user is here to hear the agents speak, not to read your synthesis of what they think. Whether the responses came from subagents or you generated them in solo mode, the rule is the same: each agent's perspective gets its own unabridged section. Never blend, paraphrase, or condense agent responses into a summary.
92
+
93
+ The format is simple: each agent's response one after another, separated by a blank line. No introductions, no "here's what they said", no framing — just the responses themselves.
94
+
95
+ After all agent responses are presented in full, you may optionally add a brief **Orchestrator Note** — flagging a disagreement worth exploring, or suggesting an agent to bring in next round. Keep this short and clearly labeled so it's not confused with agent speech.
96
+
97
+ ### 4. Handle Follow-ups
98
+
99
+ The user drives what happens next. Common patterns:
100
+
101
+ | User says... | You do... |
102
+ |---|---|
103
+ | Continues the general discussion | Pick fresh agents, repeat the loop |
104
+ | "Winston, what do you think about what Sally said?" | Spawn just Winston with Sally's response as context |
105
+ | "Bring in Quinn on this" | Spawn Quinn with a summary of the discussion so far |
106
+ | "I agree with John, let's go deeper on that" | Spawn John + 1-2 others to expand on John's point |
107
+ | "What would Mary and Bob think about Winston's approach?" | Spawn Mary and Bob with Winston's response as context |
108
+ | Asks a question directed at everyone | Back to step 1 with all agents |
109
+
110
+ The key insight: you can spawn any combination at any time. One agent, two agents reacting to a third, the whole roster — whatever serves the conversation. Each spawn is cheap and independent.
111
+
112
+ ## Keeping Context Manageable
113
+
114
+ As the conversation grows, you'll need to summarize prior rounds rather than passing the full transcript to each subagent. Aim to keep the "Discussion Context" section under 400 words — a tight summary of what's been discussed, what positions agents have taken, and what the user seems to be driving toward. Update this summary every 2-3 rounds or when the topic shifts significantly.
115
+
116
+ ## When Things Go Sideways
117
+
118
+ - **Agents are all saying the same thing**: Bring in a contrarian voice, or ask a specific agent to play devil's advocate by framing the prompt that way.
119
+ - **Discussion is going in circles**: Summarize the impasse and ask the user what angle they want to explore next.
120
+ - **User seems disengaged**: Ask directly — continue, change topic, or wrap up?
121
+ - **Agent gives a weak response**: Don't retry. Present it and let the user decide if they want more from that agent.
122
+
123
+ ## Exit
124
+
125
+ When the user says they're done (any natural phrasing — "thanks", "that's all", "end party mode", etc.), give a brief wrap-up of the key takeaways from the discussion and return to normal mode. Don't force exit triggers — just read the room.
@@ -1,9 +1,11 @@
1
+ #!/usr/bin/env node
2
+
1
3
  const { program } = require('commander');
2
4
  const path = require('node:path');
3
5
  const fs = require('node:fs');
4
6
  const { execSync } = require('node:child_process');
5
7
  const semver = require('semver');
6
- const prompts = require('./lib/prompts');
8
+ const prompts = require('./prompts');
7
9
 
8
10
  // The installer flow uses many sequential @clack/prompts, each adding keypress
9
11
  // listeners to stdin. Raise the limit to avoid spurious EventEmitter warnings.
@@ -8,7 +8,7 @@ const CLIUtils = {
8
8
  */
9
9
  getVersion() {
10
10
  try {
11
- const packageJson = require(path.join(__dirname, '..', '..', '..', 'package.json'));
11
+ const packageJson = require(path.join(__dirname, '..', '..', 'package.json'));
12
12
  return packageJson.version || 'Unknown';
13
13
  } catch {
14
14
  return 'Unknown';
@@ -16,10 +16,9 @@ const CLIUtils = {
16
16
  },
17
17
 
18
18
  /**
19
- * Display BMAD logo using @clack intro + box
20
- * @param {boolean} _clearScreen - Deprecated, ignored (no longer clears screen)
19
+ * Display BMAD logo and version using @clack intro + box
21
20
  */
22
- async displayLogo(_clearScreen = true) {
21
+ async displayLogo() {
23
22
  const version = this.getVersion();
24
23
  const color = await prompts.getColor();
25
24
 
@@ -1,7 +1,7 @@
1
1
  const path = require('node:path');
2
- const prompts = require('../lib/prompts');
3
- const { Installer } = require('../installers/lib/core/installer');
4
- const { UI } = require('../lib/ui');
2
+ const prompts = require('../prompts');
3
+ const { Installer } = require('../core/installer');
4
+ const { UI } = require('../ui');
5
5
 
6
6
  const installer = new Installer();
7
7
  const ui = new UI();
@@ -1,8 +1,8 @@
1
1
  const path = require('node:path');
2
- const prompts = require('../lib/prompts');
3
- const { Installer } = require('../installers/lib/core/installer');
4
- const { Manifest } = require('../installers/lib/core/manifest');
5
- const { UI } = require('../lib/ui');
2
+ const prompts = require('../prompts');
3
+ const { Installer } = require('../core/installer');
4
+ const { Manifest } = require('../core/manifest');
5
+ const { UI } = require('../ui');
6
6
 
7
7
  const installer = new Installer();
8
8
  const manifest = new Manifest();
@@ -1,7 +1,7 @@
1
1
  const path = require('node:path');
2
2
  const fs = require('fs-extra');
3
- const prompts = require('../lib/prompts');
4
- const { Installer } = require('../installers/lib/core/installer');
3
+ const prompts = require('../prompts');
4
+ const { Installer } = require('../core/installer');
5
5
 
6
6
  const installer = new Installer();
7
7
 
@@ -62,9 +62,9 @@ module.exports = {
62
62
  }
63
63
 
64
64
  const existingInstall = await installer.getStatus(projectDir);
65
- const version = existingInstall.version || 'unknown';
66
- const modules = (existingInstall.modules || []).map((m) => m.id || m.name).join(', ');
67
- const ides = (existingInstall.ides || []).join(', ');
65
+ const version = existingInstall.installed ? existingInstall.version : 'unknown';
66
+ const modules = existingInstall.moduleIds.join(', ');
67
+ const ides = existingInstall.ides.join(', ');
68
68
 
69
69
  const outputFolder = await installer.getOutputFolder(projectDir);
70
70
 
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Clean install configuration built from user input.
3
+ * User input comes from either UI answers or headless CLI flags.
4
+ */
5
+ class Config {
6
+ constructor({ directory, modules, ides, skipPrompts, verbose, actionType, coreConfig, moduleConfigs, quickUpdate }) {
7
+ this.directory = directory;
8
+ this.modules = Object.freeze([...modules]);
9
+ this.ides = Object.freeze([...ides]);
10
+ this.skipPrompts = skipPrompts;
11
+ this.verbose = verbose;
12
+ this.actionType = actionType;
13
+ this.coreConfig = coreConfig;
14
+ this.moduleConfigs = moduleConfigs;
15
+ this._quickUpdate = quickUpdate;
16
+ Object.freeze(this);
17
+ }
18
+
19
+ /**
20
+ * Build a clean install config from raw user input.
21
+ * @param {Object} userInput - UI answers or CLI flags
22
+ * @returns {Config}
23
+ */
24
+ static build(userInput) {
25
+ const modules = [...(userInput.modules || [])];
26
+ if (userInput.installCore && !modules.includes('core')) {
27
+ modules.unshift('core');
28
+ }
29
+
30
+ return new Config({
31
+ directory: userInput.directory,
32
+ modules,
33
+ ides: userInput.skipIde ? [] : [...(userInput.ides || [])],
34
+ skipPrompts: userInput.skipPrompts || false,
35
+ verbose: userInput.verbose || false,
36
+ actionType: userInput.actionType,
37
+ coreConfig: userInput.coreConfig || {},
38
+ moduleConfigs: userInput.moduleConfigs || null,
39
+ quickUpdate: userInput._quickUpdate || false,
40
+ });
41
+ }
42
+
43
+ hasCoreConfig() {
44
+ return this.coreConfig && Object.keys(this.coreConfig).length > 0;
45
+ }
46
+
47
+ isQuickUpdate() {
48
+ return this._quickUpdate;
49
+ }
50
+ }
51
+
52
+ module.exports = { Config };
@@ -7,7 +7,7 @@
7
7
  const fs = require('fs-extra');
8
8
  const path = require('node:path');
9
9
  const crypto = require('node:crypto');
10
- const prompts = require('../../../lib/prompts');
10
+ const prompts = require('../prompts');
11
11
 
12
12
  class CustomModuleCache {
13
13
  constructor(bmadDir) {
@@ -0,0 +1,127 @@
1
+ const path = require('node:path');
2
+ const fs = require('fs-extra');
3
+ const yaml = require('yaml');
4
+ const { Manifest } = require('./manifest');
5
+
6
+ /**
7
+ * Immutable snapshot of an existing BMAD installation.
8
+ * Pure query object — no filesystem operations after construction.
9
+ */
10
+ class ExistingInstall {
11
+ #version;
12
+
13
+ constructor({ installed, version, hasCore, modules, ides, customModules }) {
14
+ this.installed = installed;
15
+ this.#version = version;
16
+ this.hasCore = hasCore;
17
+ this.modules = Object.freeze(modules.map((m) => Object.freeze({ ...m })));
18
+ this.moduleIds = Object.freeze(this.modules.map((m) => m.id));
19
+ this.ides = Object.freeze([...ides]);
20
+ this.customModules = Object.freeze([...customModules]);
21
+ Object.freeze(this);
22
+ }
23
+
24
+ get version() {
25
+ if (!this.installed) {
26
+ throw new Error('version is not available when nothing is installed');
27
+ }
28
+ return this.#version;
29
+ }
30
+
31
+ static empty() {
32
+ return new ExistingInstall({
33
+ installed: false,
34
+ version: null,
35
+ hasCore: false,
36
+ modules: [],
37
+ ides: [],
38
+ customModules: [],
39
+ });
40
+ }
41
+
42
+ /**
43
+ * Scan a bmad directory and return an immutable snapshot of what's installed.
44
+ * @param {string} bmadDir - Path to bmad directory
45
+ * @returns {Promise<ExistingInstall>}
46
+ */
47
+ static async detect(bmadDir) {
48
+ if (!(await fs.pathExists(bmadDir))) {
49
+ return ExistingInstall.empty();
50
+ }
51
+
52
+ let version = null;
53
+ let hasCore = false;
54
+ const modules = [];
55
+ let ides = [];
56
+ let customModules = [];
57
+
58
+ const manifest = new Manifest();
59
+ const manifestData = await manifest.read(bmadDir);
60
+ if (manifestData) {
61
+ version = manifestData.version;
62
+ if (manifestData.customModules) {
63
+ customModules = manifestData.customModules;
64
+ }
65
+ if (manifestData.ides) {
66
+ ides = manifestData.ides.filter((ide) => ide && typeof ide === 'string');
67
+ }
68
+ }
69
+
70
+ const corePath = path.join(bmadDir, 'core');
71
+ if (await fs.pathExists(corePath)) {
72
+ hasCore = true;
73
+
74
+ if (!version) {
75
+ const coreConfigPath = path.join(corePath, 'config.yaml');
76
+ if (await fs.pathExists(coreConfigPath)) {
77
+ try {
78
+ const configContent = await fs.readFile(coreConfigPath, 'utf8');
79
+ const config = yaml.parse(configContent);
80
+ if (config.version) {
81
+ version = config.version;
82
+ }
83
+ } catch {
84
+ // Ignore config read errors
85
+ }
86
+ }
87
+ }
88
+ }
89
+
90
+ if (manifestData && manifestData.modules && manifestData.modules.length > 0) {
91
+ for (const moduleId of manifestData.modules) {
92
+ const modulePath = path.join(bmadDir, moduleId);
93
+ const moduleConfigPath = path.join(modulePath, 'config.yaml');
94
+
95
+ const moduleInfo = {
96
+ id: moduleId,
97
+ path: modulePath,
98
+ version: 'unknown',
99
+ };
100
+
101
+ if (await fs.pathExists(moduleConfigPath)) {
102
+ try {
103
+ const configContent = await fs.readFile(moduleConfigPath, 'utf8');
104
+ const config = yaml.parse(configContent);
105
+ moduleInfo.version = config.version || 'unknown';
106
+ moduleInfo.name = config.name || moduleId;
107
+ moduleInfo.description = config.description;
108
+ } catch {
109
+ // Ignore config read errors
110
+ }
111
+ }
112
+
113
+ modules.push(moduleInfo);
114
+ }
115
+ }
116
+
117
+ const installed = hasCore || modules.length > 0 || !!manifestData;
118
+
119
+ if (!installed) {
120
+ return ExistingInstall.empty();
121
+ }
122
+
123
+ return new ExistingInstall({ installed, version, hasCore, modules, ides, customModules });
124
+ }
125
+ }
126
+
127
+ module.exports = { ExistingInstall };
@@ -0,0 +1,129 @@
1
+ const path = require('node:path');
2
+ const fs = require('fs-extra');
3
+ const { getProjectRoot } = require('../project-root');
4
+ const { BMAD_FOLDER_NAME } = require('../ide/shared/path-utils');
5
+
6
+ class InstallPaths {
7
+ static async create(config) {
8
+ const srcDir = getProjectRoot();
9
+ await assertReadableDir(srcDir, 'BMAD source root');
10
+
11
+ const pkgPath = path.join(srcDir, 'package.json');
12
+ await assertReadableFile(pkgPath, 'package.json');
13
+ const version = require(pkgPath).version;
14
+
15
+ const projectRoot = path.resolve(config.directory);
16
+ await ensureWritableDir(projectRoot, 'project root');
17
+
18
+ const bmadDir = path.join(projectRoot, BMAD_FOLDER_NAME);
19
+ const isUpdate = await fs.pathExists(bmadDir);
20
+
21
+ const configDir = path.join(bmadDir, '_config');
22
+ const agentsDir = path.join(configDir, 'agents');
23
+ const customCacheDir = path.join(configDir, 'custom');
24
+ const coreDir = path.join(bmadDir, 'core');
25
+
26
+ for (const [dir, label] of [
27
+ [bmadDir, 'bmad directory'],
28
+ [configDir, 'config directory'],
29
+ [agentsDir, 'agents config directory'],
30
+ [customCacheDir, 'custom modules cache'],
31
+ [coreDir, 'core module directory'],
32
+ ]) {
33
+ await ensureWritableDir(dir, label);
34
+ }
35
+
36
+ return new InstallPaths({
37
+ srcDir,
38
+ version,
39
+ projectRoot,
40
+ bmadDir,
41
+ configDir,
42
+ agentsDir,
43
+ customCacheDir,
44
+ coreDir,
45
+ isUpdate,
46
+ });
47
+ }
48
+
49
+ constructor(props) {
50
+ Object.assign(this, props);
51
+ Object.freeze(this);
52
+ }
53
+
54
+ manifestFile() {
55
+ return path.join(this.configDir, 'manifest.yaml');
56
+ }
57
+ agentManifest() {
58
+ return path.join(this.configDir, 'agent-manifest.csv');
59
+ }
60
+ filesManifest() {
61
+ return path.join(this.configDir, 'files-manifest.csv');
62
+ }
63
+ helpCatalog() {
64
+ return path.join(this.configDir, 'bmad-help.csv');
65
+ }
66
+ moduleDir(name) {
67
+ return path.join(this.bmadDir, name);
68
+ }
69
+ moduleConfig(name) {
70
+ return path.join(this.bmadDir, name, 'config.yaml');
71
+ }
72
+ }
73
+
74
+ async function assertReadableDir(dirPath, label) {
75
+ const stat = await fs.stat(dirPath).catch(() => null);
76
+ if (!stat) {
77
+ throw new Error(`${label} does not exist: ${dirPath}`);
78
+ }
79
+ if (!stat.isDirectory()) {
80
+ throw new Error(`${label} is not a directory: ${dirPath}`);
81
+ }
82
+ try {
83
+ await fs.access(dirPath, fs.constants.R_OK);
84
+ } catch {
85
+ throw new Error(`${label} is not readable: ${dirPath}`);
86
+ }
87
+ }
88
+
89
+ async function assertReadableFile(filePath, label) {
90
+ const stat = await fs.stat(filePath).catch(() => null);
91
+ if (!stat) {
92
+ throw new Error(`${label} does not exist: ${filePath}`);
93
+ }
94
+ if (!stat.isFile()) {
95
+ throw new Error(`${label} is not a file: ${filePath}`);
96
+ }
97
+ try {
98
+ await fs.access(filePath, fs.constants.R_OK);
99
+ } catch {
100
+ throw new Error(`${label} is not readable: ${filePath}`);
101
+ }
102
+ }
103
+
104
+ async function ensureWritableDir(dirPath, label) {
105
+ const stat = await fs.stat(dirPath).catch(() => null);
106
+ if (stat && !stat.isDirectory()) {
107
+ throw new Error(`${label} exists but is not a directory: ${dirPath}`);
108
+ }
109
+
110
+ try {
111
+ await fs.ensureDir(dirPath);
112
+ } catch (error) {
113
+ if (error.code === 'EACCES') {
114
+ throw new Error(`${label}: permission denied creating directory: ${dirPath}`);
115
+ }
116
+ if (error.code === 'ENOSPC') {
117
+ throw new Error(`${label}: no space left on device: ${dirPath}`);
118
+ }
119
+ throw new Error(`${label}: cannot create directory: ${dirPath} (${error.message})`);
120
+ }
121
+
122
+ try {
123
+ await fs.access(dirPath, fs.constants.R_OK | fs.constants.W_OK);
124
+ } catch {
125
+ throw new Error(`${label} is not writable: ${dirPath}`);
126
+ }
127
+ }
128
+
129
+ module.exports = { InstallPaths };