bmad-method 6.0.1 → 6.0.2

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 (156) hide show
  1. package/.claude/skills/bmad-os-audit-file-refs/SKILL.md +6 -0
  2. package/.claude/skills/bmad-os-audit-file-refs/prompts/instructions.md +59 -0
  3. package/.claude/skills/bmad-os-changelog-social/SKILL.md +1 -2
  4. package/.claude/skills/bmad-os-diataxis-style-fix/SKILL.md +1 -2
  5. package/.claude/skills/bmad-os-draft-changelog/SKILL.md +1 -2
  6. package/.claude/skills/bmad-os-gh-triage/SKILL.md +1 -7
  7. package/.claude/skills/bmad-os-release-module/SKILL.md +1 -2
  8. package/.claude/skills/bmad-os-review-pr/SKILL.md +6 -0
  9. package/{tools/maintainer/review-pr.md → .claude/skills/bmad-os-review-pr/prompts/instructions.md} +5 -16
  10. package/.prettierignore +3 -0
  11. package/CHANGELOG.md +37 -0
  12. package/README.md +13 -1
  13. package/docs/how-to/customize-bmad.md +14 -14
  14. package/docs/how-to/established-projects.md +15 -3
  15. package/docs/how-to/get-answers-about-bmad.md +39 -8
  16. package/docs/how-to/install-bmad.md +13 -4
  17. package/docs/how-to/non-interactive-installation.md +1 -1
  18. package/docs/how-to/quick-fixes.md +1 -1
  19. package/docs/index.md +10 -4
  20. package/docs/reference/commands.md +21 -1
  21. package/docs/reference/workflow-map.md +29 -62
  22. package/docs/roadmap.mdx +136 -0
  23. package/docs/tutorials/getting-started.md +69 -15
  24. package/package.json +2 -2
  25. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-01-init.md +2 -2
  26. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-01b-continue.md +3 -3
  27. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-02-vision.md +1 -1
  28. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-03-users.md +1 -1
  29. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-04-metrics.md +1 -1
  30. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-05-scope.md +1 -1
  31. package/src/bmm/workflows/1-analysis/create-product-brief/steps/step-06-complete.md +1 -1
  32. package/src/bmm/workflows/1-analysis/create-product-brief/workflow.md +1 -1
  33. package/src/bmm/workflows/1-analysis/research/domain-steps/step-01-init.md +2 -2
  34. package/src/bmm/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +2 -2
  35. package/src/bmm/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +2 -2
  36. package/src/bmm/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +2 -2
  37. package/src/bmm/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +1 -1
  38. package/src/bmm/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +2 -1
  39. package/src/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +2 -2
  40. package/src/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +2 -2
  41. package/src/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +2 -2
  42. package/src/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +2 -2
  43. package/src/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +2 -1
  44. package/src/bmm/workflows/1-analysis/research/technical-steps/step-01-init.md +2 -2
  45. package/src/bmm/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +2 -2
  46. package/src/bmm/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +2 -2
  47. package/src/bmm/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +2 -2
  48. package/src/bmm/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +2 -2
  49. package/src/bmm/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +2 -1
  50. package/src/bmm/workflows/1-analysis/research/workflow-domain-research.md +1 -1
  51. package/src/bmm/workflows/1-analysis/research/workflow-market-research.md +1 -1
  52. package/src/bmm/workflows/1-analysis/research/workflow-technical-research.md +1 -1
  53. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-01b-continue.md +2 -3
  54. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02-discovery.md +1 -1
  55. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02b-vision.md +1 -1
  56. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02c-executive-summary.md +1 -1
  57. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-03-success.md +2 -2
  58. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-04-journeys.md +2 -2
  59. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-05-domain.md +2 -2
  60. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-06-innovation.md +2 -2
  61. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-07-project-type.md +1 -1
  62. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-08-scoping.md +1 -1
  63. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-09-functional.md +1 -1
  64. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-10-nonfunctional.md +1 -1
  65. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-11-polish.md +3 -3
  66. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-12-complete.md +1 -1
  67. package/src/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-13-report-complete.md +1 -1
  68. package/src/bmm/workflows/2-plan-workflows/create-prd/workflow-create-prd.md +1 -1
  69. package/src/bmm/workflows/2-plan-workflows/create-prd/workflow-edit-prd.md +1 -1
  70. package/src/bmm/workflows/2-plan-workflows/create-prd/workflow-validate-prd.md +1 -1
  71. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01-init.md +2 -2
  72. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01b-continue.md +3 -3
  73. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +2 -2
  74. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +2 -2
  75. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +2 -2
  76. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +2 -2
  77. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +2 -2
  78. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +2 -2
  79. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +2 -2
  80. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +2 -2
  81. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +2 -2
  82. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +2 -2
  83. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +2 -2
  84. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +2 -2
  85. package/src/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-14-complete.md +1 -1
  86. package/src/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +2 -2
  87. package/src/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-06-final-assessment.md +1 -1
  88. package/src/bmm/workflows/3-solutioning/check-implementation-readiness/workflow.md +2 -2
  89. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-01-init.md +2 -2
  90. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-01b-continue.md +11 -2
  91. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-02-context.md +2 -2
  92. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md +3 -5
  93. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md +2 -2
  94. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md +2 -2
  95. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md +2 -2
  96. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md +2 -2
  97. package/src/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md +1 -1
  98. package/src/bmm/workflows/3-solutioning/create-architecture/workflow.md +3 -3
  99. package/src/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +1 -1
  100. package/src/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +1 -1
  101. package/src/bmm/workflows/4-implementation/code-review/workflow.yaml +1 -2
  102. package/src/bmm/workflows/4-implementation/correct-course/workflow.yaml +1 -2
  103. package/src/bmm/workflows/4-implementation/create-story/checklist.md +2 -2
  104. package/src/bmm/workflows/4-implementation/create-story/workflow.yaml +1 -2
  105. package/src/bmm/workflows/4-implementation/dev-story/workflow.yaml +1 -2
  106. package/src/bmm/workflows/4-implementation/retrospective/workflow.yaml +1 -2
  107. package/src/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +1 -1
  108. package/src/bmm/workflows/4-implementation/sprint-status/workflow.yaml +1 -1
  109. package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-01-mode-detection.md +6 -6
  110. package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-02-context-gathering.md +1 -1
  111. package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-03-execute.md +1 -1
  112. package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-04-self-check.md +1 -1
  113. package/src/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-05-adversarial-review.md +1 -1
  114. package/src/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md +2 -2
  115. package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-01-understand.md +4 -6
  116. package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-02-investigate.md +1 -2
  117. package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-03-generate.md +1 -2
  118. package/src/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md +2 -2
  119. package/src/bmm/workflows/document-project/workflow.yaml +1 -1
  120. package/src/bmm/workflows/generate-project-context/steps/step-01-discover.md +1 -1
  121. package/src/bmm/workflows/generate-project-context/steps/step-02-generate.md +1 -1
  122. package/src/bmm/workflows/generate-project-context/workflow.md +2 -2
  123. package/src/bmm/workflows/{qa/automate → qa-generate-e2e-tests}/workflow.yaml +2 -4
  124. package/src/core/tasks/editorial-review-prose.xml +1 -1
  125. package/src/core/tasks/editorial-review-structure.xml +1 -2
  126. package/src/core/tasks/help.md +3 -2
  127. package/src/core/tasks/index-docs.xml +1 -1
  128. package/src/core/tasks/review-adversarial-general.xml +2 -1
  129. package/src/core/tasks/shard-doc.xml +1 -1
  130. package/src/core/workflows/advanced-elicitation/workflow.xml +1 -0
  131. package/src/core/workflows/brainstorming/workflow.md +1 -1
  132. package/src/core/workflows/party-mode/workflow.md +1 -1
  133. package/tools/cli/installers/lib/ide/_config-driven.js +0 -1
  134. package/tools/cli/installers/lib/ide/codex.js +195 -181
  135. package/tools/cli/installers/lib/ide/github-copilot.js +0 -1
  136. package/tools/cli/installers/lib/ide/manager.js +3 -3
  137. package/tools/cli/installers/lib/ide/platform-codes.yaml +11 -4
  138. package/tools/cli/installers/lib/ide/rovodev.js +257 -0
  139. package/tools/cli/installers/lib/ide/shared/task-tool-command-generator.js +0 -1
  140. package/tools/cli/installers/lib/ide/templates/agent-command-template.md +0 -1
  141. package/tools/cli/installers/lib/ide/templates/combined/default-agent.md +0 -1
  142. package/tools/cli/installers/lib/ide/templates/combined/default-workflow-yaml.md +0 -1
  143. package/tools/cli/installers/lib/ide/templates/combined/default-workflow.md +0 -1
  144. package/tools/cli/installers/lib/ide/templates/workflow-command-template.md +0 -1
  145. package/tools/cli/installers/lib/ide/templates/workflow-commander.md +0 -1
  146. package/tools/cli/lib/ui.js +1 -1
  147. package/tools/platform-codes.yaml +12 -12
  148. package/tools/validate-doc-links.js +20 -6
  149. package/website/astro.config.mjs +1 -0
  150. package/website/src/rehype-markdown-links.js +9 -1
  151. package/website/src/styles/custom.css +296 -0
  152. package/.claude/skills/bmad-os-gh-triage/README.md +0 -14
  153. package/.claude/skills/bmad-os-release-module/README.md +0 -24
  154. package/tools/maintainer/review-pr-README.md +0 -55
  155. /package/src/bmm/workflows/{qa/automate → qa-generate-e2e-tests}/checklist.md +0 -0
  156. /package/src/bmm/workflows/{qa/automate → qa-generate-e2e-tests}/instructions.md +0 -0
@@ -0,0 +1,257 @@
1
+ const path = require('node:path');
2
+ const fs = require('fs-extra');
3
+ const yaml = require('yaml');
4
+ const { BaseIdeSetup } = require('./_base-ide');
5
+ const prompts = require('../../../lib/prompts');
6
+ const { AgentCommandGenerator } = require('./shared/agent-command-generator');
7
+ const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
8
+ const { TaskToolCommandGenerator } = require('./shared/task-tool-command-generator');
9
+ const { toDashPath } = require('./shared/path-utils');
10
+
11
+ /**
12
+ * Rovo Dev IDE setup handler
13
+ *
14
+ * Custom installer that writes .md workflow files to .rovodev/workflows/
15
+ * and generates .rovodev/prompts.yml to register them with Rovo Dev's /prompts feature.
16
+ *
17
+ * prompts.yml format (per Rovo Dev docs):
18
+ * prompts:
19
+ * - name: bmad-bmm-create-prd
20
+ * description: "PRD workflow..."
21
+ * content_file: workflows/bmad-bmm-create-prd.md
22
+ */
23
+ class RovoDevSetup extends BaseIdeSetup {
24
+ constructor() {
25
+ super('rovo-dev', 'Rovo Dev', false);
26
+ this.rovoDir = '.rovodev';
27
+ this.workflowsDir = 'workflows';
28
+ this.promptsFile = 'prompts.yml';
29
+ }
30
+
31
+ /**
32
+ * Setup Rovo Dev configuration
33
+ * @param {string} projectDir - Project directory
34
+ * @param {string} bmadDir - BMAD installation directory
35
+ * @param {Object} options - Setup options
36
+ * @returns {Promise<Object>} Setup result with { success, results: { agents, workflows, tasks, tools } }
37
+ */
38
+ async setup(projectDir, bmadDir, options = {}) {
39
+ if (!options.silent) await prompts.log.info(`Setting up ${this.name}...`);
40
+
41
+ // Clean up any old BMAD installation first
42
+ await this.cleanup(projectDir, options);
43
+
44
+ const workflowsPath = path.join(projectDir, this.rovoDir, this.workflowsDir);
45
+ await this.ensureDir(workflowsPath);
46
+
47
+ const selectedModules = options.selectedModules || [];
48
+ const writtenFiles = [];
49
+
50
+ // Generate and write agent launchers
51
+ const agentGen = new AgentCommandGenerator(this.bmadFolderName);
52
+ const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, selectedModules);
53
+ const agentCount = await agentGen.writeDashArtifacts(workflowsPath, agentArtifacts);
54
+ this._collectPromptEntries(writtenFiles, agentArtifacts, ['agent-launcher'], 'agent');
55
+
56
+ // Generate and write workflow commands
57
+ const workflowGen = new WorkflowCommandGenerator(this.bmadFolderName);
58
+ const { artifacts: workflowArtifacts } = await workflowGen.collectWorkflowArtifacts(bmadDir);
59
+ const workflowCount = await workflowGen.writeDashArtifacts(workflowsPath, workflowArtifacts);
60
+ this._collectPromptEntries(writtenFiles, workflowArtifacts, ['workflow-command'], 'workflow');
61
+
62
+ // Generate and write task/tool commands
63
+ const taskToolGen = new TaskToolCommandGenerator(this.bmadFolderName);
64
+ const { artifacts: taskToolArtifacts, counts: taskToolCounts } = await taskToolGen.collectTaskToolArtifacts(bmadDir);
65
+ await taskToolGen.writeDashArtifacts(workflowsPath, taskToolArtifacts);
66
+ const taskCount = taskToolCounts.tasks || 0;
67
+ const toolCount = taskToolCounts.tools || 0;
68
+ this._collectPromptEntries(writtenFiles, taskToolArtifacts, ['task', 'tool']);
69
+
70
+ // Generate prompts.yml manifest (only if we have entries to write)
71
+ if (writtenFiles.length > 0) {
72
+ await this.generatePromptsYml(projectDir, writtenFiles);
73
+ }
74
+
75
+ if (!options.silent) {
76
+ await prompts.log.success(
77
+ `${this.name} configured: ${agentCount} agents, ${workflowCount} workflows, ${taskCount} tasks, ${toolCount} tools`,
78
+ );
79
+ }
80
+
81
+ return {
82
+ success: true,
83
+ results: {
84
+ agents: agentCount,
85
+ workflows: workflowCount,
86
+ tasks: taskCount,
87
+ tools: toolCount,
88
+ },
89
+ };
90
+ }
91
+
92
+ /**
93
+ * Collect prompt entries from artifacts into writtenFiles array
94
+ * @param {Array} writtenFiles - Target array to push entries into
95
+ * @param {Array} artifacts - Artifacts from a generator's collect method
96
+ * @param {string[]} acceptedTypes - Artifact types to include (e.g., ['agent-launcher'])
97
+ * @param {string} [fallbackSuffix] - Suffix for fallback description; defaults to artifact.type
98
+ */
99
+ _collectPromptEntries(writtenFiles, artifacts, acceptedTypes, fallbackSuffix) {
100
+ for (const artifact of artifacts) {
101
+ if (!acceptedTypes.includes(artifact.type)) continue;
102
+ const flatName = toDashPath(artifact.relativePath);
103
+ writtenFiles.push({
104
+ name: path.basename(flatName, '.md'),
105
+ description: artifact.description || `${artifact.name} ${fallbackSuffix || artifact.type}`,
106
+ contentFile: `${this.workflowsDir}/${flatName}`,
107
+ });
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Generate .rovodev/prompts.yml manifest
113
+ * Merges with existing user entries -- strips entries with names starting 'bmad-',
114
+ * appends new BMAD entries, and writes back.
115
+ *
116
+ * @param {string} projectDir - Project directory
117
+ * @param {Array<Object>} writtenFiles - Array of { name, description, contentFile }
118
+ */
119
+ async generatePromptsYml(projectDir, writtenFiles) {
120
+ const promptsPath = path.join(projectDir, this.rovoDir, this.promptsFile);
121
+ let existingPrompts = [];
122
+
123
+ // Read existing prompts.yml and preserve non-BMAD entries
124
+ if (await this.pathExists(promptsPath)) {
125
+ try {
126
+ const content = await this.readFile(promptsPath);
127
+ const parsed = yaml.parse(content);
128
+ if (parsed && Array.isArray(parsed.prompts)) {
129
+ // Keep only non-BMAD entries (entries whose name does NOT start with bmad-)
130
+ existingPrompts = parsed.prompts.filter((entry) => !entry.name || !entry.name.startsWith('bmad-'));
131
+ }
132
+ } catch {
133
+ // If parsing fails, start fresh but preserve file safety
134
+ existingPrompts = [];
135
+ }
136
+ }
137
+
138
+ // Build new BMAD entries (prefix description with name so /prompts list is scannable)
139
+ const bmadEntries = writtenFiles.map((file) => ({
140
+ name: file.name,
141
+ description: `${file.name} - ${file.description}`,
142
+ content_file: file.contentFile,
143
+ }));
144
+
145
+ // Merge: user entries first, then BMAD entries
146
+ const allPrompts = [...existingPrompts, ...bmadEntries];
147
+
148
+ const config = { prompts: allPrompts };
149
+ const yamlContent = yaml.stringify(config, { lineWidth: 0 });
150
+ await this.writeFile(promptsPath, yamlContent);
151
+ }
152
+
153
+ /**
154
+ * Cleanup Rovo Dev configuration
155
+ * Removes bmad-* files from .rovodev/workflows/ and strips BMAD entries from prompts.yml
156
+ * @param {string} projectDir - Project directory
157
+ * @param {Object} options - Cleanup options
158
+ */
159
+ async cleanup(projectDir, options = {}) {
160
+ const workflowsPath = path.join(projectDir, this.rovoDir, this.workflowsDir);
161
+
162
+ // Remove all bmad-* entries from workflows dir (aligned with detect() predicate)
163
+ if (await this.pathExists(workflowsPath)) {
164
+ const entries = await fs.readdir(workflowsPath);
165
+ for (const entry of entries) {
166
+ if (entry.startsWith('bmad-')) {
167
+ await fs.remove(path.join(workflowsPath, entry));
168
+ }
169
+ }
170
+ }
171
+
172
+ // Clean BMAD entries from prompts.yml (preserve user entries)
173
+ const promptsPath = path.join(projectDir, this.rovoDir, this.promptsFile);
174
+ if (await this.pathExists(promptsPath)) {
175
+ try {
176
+ const content = await this.readFile(promptsPath);
177
+ const parsed = yaml.parse(content) || {};
178
+
179
+ if (Array.isArray(parsed.prompts)) {
180
+ const originalCount = parsed.prompts.length;
181
+ parsed.prompts = parsed.prompts.filter((entry) => !entry.name || !entry.name.startsWith('bmad-'));
182
+ const removedCount = originalCount - parsed.prompts.length;
183
+
184
+ if (removedCount > 0) {
185
+ if (parsed.prompts.length === 0) {
186
+ // If no entries remain, remove the file entirely
187
+ await fs.remove(promptsPath);
188
+ } else {
189
+ await this.writeFile(promptsPath, yaml.stringify(parsed, { lineWidth: 0 }));
190
+ }
191
+ if (!options.silent) {
192
+ await prompts.log.message(`Removed ${removedCount} BMAD entries from ${this.promptsFile}`);
193
+ }
194
+ }
195
+ }
196
+ } catch {
197
+ // If parsing fails, leave file as-is
198
+ if (!options.silent) {
199
+ await prompts.log.warn(`Warning: Could not parse ${this.promptsFile} for cleanup`);
200
+ }
201
+ }
202
+ }
203
+
204
+ // Remove empty .rovodev directories
205
+ if (await this.pathExists(workflowsPath)) {
206
+ const remaining = await fs.readdir(workflowsPath);
207
+ if (remaining.length === 0) {
208
+ await fs.remove(workflowsPath);
209
+ }
210
+ }
211
+
212
+ const rovoDirPath = path.join(projectDir, this.rovoDir);
213
+ if (await this.pathExists(rovoDirPath)) {
214
+ const remaining = await fs.readdir(rovoDirPath);
215
+ if (remaining.length === 0) {
216
+ await fs.remove(rovoDirPath);
217
+ }
218
+ }
219
+ }
220
+
221
+ /**
222
+ * Detect whether Rovo Dev configuration exists in the project
223
+ * Checks for .rovodev/ dir with bmad files or bmad entries in prompts.yml
224
+ * @param {string} projectDir - Project directory
225
+ * @returns {boolean}
226
+ */
227
+ async detect(projectDir) {
228
+ const workflowsPath = path.join(projectDir, this.rovoDir, this.workflowsDir);
229
+
230
+ // Check for bmad files in workflows dir
231
+ if (await fs.pathExists(workflowsPath)) {
232
+ const entries = await fs.readdir(workflowsPath);
233
+ if (entries.some((entry) => entry.startsWith('bmad-'))) {
234
+ return true;
235
+ }
236
+ }
237
+
238
+ // Check for bmad entries in prompts.yml
239
+ const promptsPath = path.join(projectDir, this.rovoDir, this.promptsFile);
240
+ if (await fs.pathExists(promptsPath)) {
241
+ try {
242
+ const content = await fs.readFile(promptsPath, 'utf8');
243
+ const parsed = yaml.parse(content);
244
+ if (parsed && Array.isArray(parsed.prompts)) {
245
+ return parsed.prompts.some((entry) => entry.name && entry.name.startsWith('bmad-'));
246
+ }
247
+ } catch {
248
+ // If parsing fails, check raw content
249
+ return false;
250
+ }
251
+ }
252
+
253
+ return false;
254
+ }
255
+ }
256
+
257
+ module.exports = { RovoDevSetup };
@@ -176,7 +176,6 @@ class TaskToolCommandGenerator {
176
176
 
177
177
  return `---
178
178
  description: '${description.replaceAll("'", "''")}'
179
- disable-model-invocation: true
180
179
  ---
181
180
 
182
181
  # ${item.displayName || item.name}
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: '{{name}}'
3
3
  description: '{{description}}'
4
- disable-model-invocation: true
5
4
  ---
6
5
 
7
6
  You must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: '{{name}}'
3
3
  description: '{{description}}'
4
- disable-model-invocation: true
5
4
  ---
6
5
 
7
6
  You must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: '{{name}}'
3
3
  description: '{{description}}'
4
- disable-model-invocation: true
5
4
  ---
6
5
 
7
6
  IT IS CRITICAL THAT YOU FOLLOW THESE STEPS - while staying in character as the current agent persona you may have loaded:
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  name: '{{name}}'
3
3
  description: '{{description}}'
4
- disable-model-invocation: true
5
4
  ---
6
5
 
7
6
  IT IS CRITICAL THAT YOU FOLLOW THIS COMMAND: LOAD the FULL @{project-root}/{{bmadFolderName}}/{{path}}, READ its entire contents and follow its directions exactly!
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  description: '{{description}}'
3
- disable-model-invocation: true
4
3
  ---
5
4
 
6
5
  IT IS CRITICAL THAT YOU FOLLOW THESE STEPS - while staying in character as the current agent persona you may have loaded:
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  description: '{{description}}'
3
- disable-model-invocation: true
4
3
  ---
5
4
 
6
5
  IT IS CRITICAL THAT YOU FOLLOW THIS COMMAND: LOAD the FULL @{{workflow_path}}, READ its entire contents and follow its directions exactly!
@@ -582,7 +582,7 @@ class UI {
582
582
  /**
583
583
  * Prompt for tool/IDE selection (called after module configuration)
584
584
  * Uses a split prompt approach:
585
- * 1. Recommended tools - standard multiselect for 3 preferred tools
585
+ * 1. Recommended tools - standard multiselect for preferred tools
586
586
  * 2. Additional tools - autocompleteMultiselect with search capability
587
587
  * @param {string} projectDir - Project directory to check for existing IDEs
588
588
  * @param {Object} options - Command-line options
@@ -18,12 +18,6 @@ platforms:
18
18
  category: cli
19
19
  description: "Anthropic's official CLI for Claude"
20
20
 
21
- windsurf:
22
- name: "Windsurf"
23
- preferred: true
24
- category: ide
25
- description: "AI-powered IDE with cascade flows"
26
-
27
21
  cursor:
28
22
  name: "Cursor"
29
23
  preferred: true
@@ -43,6 +37,12 @@ platforms:
43
37
  category: ide
44
38
  description: "OpenCode terminal coding assistant"
45
39
 
40
+ codebuddy:
41
+ name: "CodeBuddy"
42
+ preferred: false
43
+ category: ide
44
+ description: "Tencent Cloud Code Assistant - AI-powered coding companion"
45
+
46
46
  auggie:
47
47
  name: "Auggie"
48
48
  preferred: false
@@ -55,12 +55,6 @@ platforms:
55
55
  category: ide
56
56
  description: "Enhanced Cline fork"
57
57
 
58
- rovo:
59
- name: "Rovo"
60
- preferred: false
61
- category: ide
62
- description: "Atlassian's AI coding assistant"
63
-
64
58
  rovo-dev:
65
59
  name: "Rovo Dev"
66
60
  preferred: false
@@ -127,6 +121,12 @@ platforms:
127
121
  category: ide
128
122
  description: "AI coding tool"
129
123
 
124
+ windsurf:
125
+ name: "Windsurf"
126
+ preferred: false
127
+ category: ide
128
+ description: "AI-powered IDE with cascade flows"
129
+
130
130
  # Platform categories
131
131
  categories:
132
132
  ide:
@@ -51,7 +51,7 @@ function getMarkdownFiles(dir) {
51
51
 
52
52
  if (entry.isDirectory()) {
53
53
  walk(fullPath);
54
- } else if (entry.isFile() && entry.name.endsWith('.md')) {
54
+ } else if (entry.isFile() && (entry.name.endsWith('.md') || entry.name.endsWith('.mdx'))) {
55
55
  files.push(fullPath);
56
56
  }
57
57
  }
@@ -120,10 +120,13 @@ function resolveLink(siteRelativePath, sourceFile) {
120
120
  if (!resolved.startsWith(DOCS_ROOT + path.sep) && resolved !== DOCS_ROOT) return null;
121
121
  if (fs.existsSync(resolved) && fs.statSync(resolved).isFile()) return resolved;
122
122
  if (fs.existsSync(resolved + '.md')) return resolved + '.md';
123
- // Directory: check for index.md
123
+ if (fs.existsSync(resolved + '.mdx')) return resolved + '.mdx';
124
+ // Directory: check for index.md or index.mdx
124
125
  if (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {
125
126
  const indexFile = path.join(resolved, 'index.md');
127
+ const indexMdxFile = path.join(resolved, 'index.mdx');
126
128
  if (fs.existsSync(indexFile)) return indexFile;
129
+ if (fs.existsSync(indexMdxFile)) return indexMdxFile;
127
130
  }
128
131
  return null;
129
132
  }
@@ -134,12 +137,17 @@ function resolveLink(siteRelativePath, sourceFile) {
134
137
  }
135
138
 
136
139
  if (checkPath.endsWith('/')) {
137
- // Could be file.md or directory/index.md
138
- const asFile = path.join(DOCS_ROOT, checkPath.slice(0, -1) + '.md');
140
+ // Could be file.md, file.mdx, or directory/index.md/mdx
141
+ const baseName = checkPath.slice(0, -1);
142
+ const asMd = path.join(DOCS_ROOT, baseName + '.md');
143
+ const asMdx = path.join(DOCS_ROOT, baseName + '.mdx');
139
144
  const asIndex = path.join(DOCS_ROOT, checkPath, 'index.md');
145
+ const asIndexMdx = path.join(DOCS_ROOT, checkPath, 'index.mdx');
140
146
 
141
- if (fs.existsSync(asFile)) return asFile;
147
+ if (fs.existsSync(asMd)) return asMd;
148
+ if (fs.existsSync(asMdx)) return asMdx;
142
149
  if (fs.existsSync(asIndex)) return asIndex;
150
+ if (fs.existsSync(asIndexMdx)) return asIndexMdx;
143
151
  return null;
144
152
  }
145
153
 
@@ -151,10 +159,16 @@ function resolveLink(siteRelativePath, sourceFile) {
151
159
  const withMd = direct + '.md';
152
160
  if (fs.existsSync(withMd)) return withMd;
153
161
 
154
- // Directory without trailing slash: check for index.md
162
+ // Try with .mdx extension
163
+ const withMdx = direct + '.mdx';
164
+ if (fs.existsSync(withMdx)) return withMdx;
165
+
166
+ // Directory without trailing slash: check for index.md or index.mdx
155
167
  if (fs.existsSync(direct) && fs.statSync(direct).isDirectory()) {
156
168
  const indexFile = path.join(direct, 'index.md');
169
+ const indexMdxFile = path.join(direct, 'index.mdx');
157
170
  if (fs.existsSync(indexFile)) return indexFile;
171
+ if (fs.existsSync(indexMdxFile)) return indexMdxFile;
158
172
  }
159
173
 
160
174
  return null;
@@ -90,6 +90,7 @@ export default defineConfig({
90
90
  // Sidebar configuration (Diataxis structure)
91
91
  sidebar: [
92
92
  { label: 'Welcome', slug: 'index' },
93
+ { label: 'Roadmap', slug: 'roadmap' },
93
94
  {
94
95
  label: 'Tutorials',
95
96
  collapsed: false,
@@ -101,11 +101,19 @@ export function findFirstDelimiter(str) {
101
101
  /** Walk up from a file path to find the content docs directory. */
102
102
  export function detectContentDir(filePath) {
103
103
  const segments = filePath.split(path.sep);
104
- // Look for src/content/docs in the path
104
+ // Look for src/content/docs in the path (standard Astro)
105
105
  for (let i = segments.length - 1; i >= 2; i--) {
106
106
  if (segments[i - 2] === 'src' && segments[i - 1] === 'content' && segments[i] === 'docs') {
107
107
  return segments.slice(0, i + 1).join(path.sep);
108
108
  }
109
109
  }
110
+ // Also check for a standalone 'docs' directory (BMAD project structure)
111
+ // Path format: .../bmm/docs/file.mdx or .../bmm/website/...
112
+ for (let i = segments.length - 1; i >= 0; i--) {
113
+ if (segments[i] === 'docs') {
114
+ // Found docs directory - use its parent as the content root
115
+ return segments.slice(0, i + 1).join(path.sep);
116
+ }
117
+ }
110
118
  return null;
111
119
  }