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
@@ -1,6 +1,7 @@
1
1
  const path = require('node:path');
2
- const fs = require('fs-extra');
3
2
  const os = require('node:os');
3
+ const fs = require('fs-extra');
4
+ const yaml = require('yaml');
4
5
  const { BaseIdeSetup } = require('./_base-ide');
5
6
  const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
6
7
  const { AgentCommandGenerator } = require('./shared/agent-command-generator');
@@ -14,58 +15,7 @@ const prompts = require('../../../lib/prompts');
14
15
  */
15
16
  class CodexSetup extends BaseIdeSetup {
16
17
  constructor() {
17
- super('codex', 'Codex', true); // preferred IDE
18
- }
19
-
20
- /**
21
- * Collect configuration choices before installation
22
- * @param {Object} options - Configuration options
23
- * @returns {Object} Collected configuration
24
- */
25
- async collectConfiguration(options = {}) {
26
- // Non-interactive mode: use default (global)
27
- if (options.skipPrompts) {
28
- return { installLocation: 'global' };
29
- }
30
-
31
- let confirmed = false;
32
- let installLocation = 'global';
33
-
34
- while (!confirmed) {
35
- installLocation = await prompts.select({
36
- message: 'Where would you like to install Codex CLI prompts?',
37
- choices: [
38
- {
39
- name: 'Global - Simple for single project ' + '(~/.codex/prompts, but references THIS project only)',
40
- value: 'global',
41
- },
42
- {
43
- name: `Project-specific - Recommended for real work (requires CODEX_HOME=<project-dir>${path.sep}.codex)`,
44
- value: 'project',
45
- },
46
- ],
47
- default: 'global',
48
- });
49
-
50
- // Show brief confirmation hint (detailed instructions available via verbose)
51
- if (installLocation === 'project') {
52
- await prompts.log.info('Prompts installed to: <project>/.codex/prompts (requires CODEX_HOME)');
53
- } else {
54
- await prompts.log.info('Prompts installed to: ~/.codex/prompts');
55
- }
56
-
57
- // Confirm the choice
58
- confirmed = await prompts.confirm({
59
- message: 'Proceed with this installation option?',
60
- default: true,
61
- });
62
-
63
- if (!confirmed) {
64
- await prompts.log.warn("Let's choose a different installation option.");
65
- }
66
- }
67
-
68
- return { installLocation };
18
+ super('codex', 'Codex', false);
69
19
  }
70
20
 
71
21
  /**
@@ -80,20 +30,25 @@ class CodexSetup extends BaseIdeSetup {
80
30
  // Always use CLI mode
81
31
  const mode = 'cli';
82
32
 
83
- // Get installation location from pre-collected config or default to global
84
- const installLocation = options.preCollectedConfig?.installLocation || 'global';
85
-
86
33
  const { artifacts, counts } = await this.collectClaudeArtifacts(projectDir, bmadDir, options);
87
34
 
88
- const destDir = this.getCodexPromptDir(projectDir, installLocation);
35
+ // Clean up old .codex/prompts locations (both global and project)
36
+ const oldGlobalDir = this.getOldCodexPromptDir(null, 'global');
37
+ await this.clearOldBmadFiles(oldGlobalDir, options);
38
+ const oldProjectDir = this.getOldCodexPromptDir(projectDir, 'project');
39
+ await this.clearOldBmadFiles(oldProjectDir, options);
40
+
41
+ // Install to .agents/skills
42
+ const destDir = this.getCodexSkillsDir(projectDir);
89
43
  await fs.ensureDir(destDir);
90
- await this.clearOldBmadFiles(destDir, options);
44
+ await this.clearOldBmadSkills(destDir, options);
91
45
 
92
- // Collect artifacts and write using underscore format
46
+ // Collect and write agent skills
93
47
  const agentGen = new AgentCommandGenerator(this.bmadFolderName);
94
48
  const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
95
- const agentCount = await agentGen.writeDashArtifacts(destDir, agentArtifacts);
49
+ const agentCount = await this.writeSkillArtifacts(destDir, agentArtifacts, 'agent-launcher');
96
50
 
51
+ // Collect and write task skills
97
52
  const tasks = await getTasksFromBmad(bmadDir, options.selectedModules || []);
98
53
  const taskArtifacts = [];
99
54
  for (const task of tasks) {
@@ -117,19 +72,23 @@ class CodexSetup extends BaseIdeSetup {
117
72
  });
118
73
  }
119
74
 
75
+ const ttGen = new TaskToolCommandGenerator(this.bmadFolderName);
76
+ const taskSkillArtifacts = taskArtifacts.map((artifact) => ({
77
+ ...artifact,
78
+ content: ttGen.generateCommandContent(artifact, artifact.type),
79
+ }));
80
+ const tasksWritten = await this.writeSkillArtifacts(destDir, taskSkillArtifacts, 'task');
81
+
82
+ // Collect and write workflow skills
120
83
  const workflowGenerator = new WorkflowCommandGenerator(this.bmadFolderName);
121
84
  const { artifacts: workflowArtifacts } = await workflowGenerator.collectWorkflowArtifacts(bmadDir);
122
- const workflowCount = await workflowGenerator.writeDashArtifacts(destDir, workflowArtifacts);
123
-
124
- // Also write tasks using underscore format
125
- const ttGen = new TaskToolCommandGenerator(this.bmadFolderName);
126
- const tasksWritten = await ttGen.writeDashArtifacts(destDir, taskArtifacts);
85
+ const workflowCount = await this.writeSkillArtifacts(destDir, workflowArtifacts, 'workflow-command');
127
86
 
128
87
  const written = agentCount + workflowCount + tasksWritten;
129
88
 
130
89
  if (!options.silent) {
131
90
  await prompts.log.success(
132
- `${this.name} configured: ${counts.agents} agents, ${counts.workflows} workflows, ${counts.tasks} tasks, ${written} files → ${destDir}`,
91
+ `${this.name} configured: ${counts.agents} agents, ${counts.workflows} workflows, ${counts.tasks} tasks, ${written} skills → ${destDir}`,
133
92
  );
134
93
  }
135
94
 
@@ -140,35 +99,18 @@ class CodexSetup extends BaseIdeSetup {
140
99
  counts,
141
100
  destination: destDir,
142
101
  written,
143
- installLocation,
144
102
  };
145
103
  }
146
104
 
147
105
  /**
148
- * Detect Codex installation by checking for BMAD prompt exports
106
+ * Detect Codex installation by checking for BMAD skills
149
107
  */
150
108
  async detect(projectDir) {
151
- // Check both global and project-specific locations
152
- const globalDir = this.getCodexPromptDir(null, 'global');
153
- const projectDir_local = projectDir || process.cwd();
154
- const projectSpecificDir = this.getCodexPromptDir(projectDir_local, 'project');
109
+ const dir = this.getCodexSkillsDir(projectDir || process.cwd());
155
110
 
156
- // Check global location
157
- if (await fs.pathExists(globalDir)) {
111
+ if (await fs.pathExists(dir)) {
158
112
  try {
159
- const entries = await fs.readdir(globalDir);
160
- if (entries && entries.some((entry) => entry && typeof entry === 'string' && entry.startsWith('bmad'))) {
161
- return true;
162
- }
163
- } catch {
164
- // Ignore errors
165
- }
166
- }
167
-
168
- // Check project-specific location
169
- if (await fs.pathExists(projectSpecificDir)) {
170
- try {
171
- const entries = await fs.readdir(projectSpecificDir);
113
+ const entries = await fs.readdir(dir);
172
114
  if (entries && entries.some((entry) => entry && typeof entry === 'string' && entry.startsWith('bmad'))) {
173
115
  return true;
174
116
  }
@@ -240,26 +182,138 @@ class CodexSetup extends BaseIdeSetup {
240
182
  };
241
183
  }
242
184
 
243
- getCodexPromptDir(projectDir = null, location = 'global') {
185
+ getCodexSkillsDir(projectDir) {
186
+ if (!projectDir) {
187
+ throw new Error('projectDir is required for project-scoped skill installation');
188
+ }
189
+ return path.join(projectDir, '.agents', 'skills');
190
+ }
191
+
192
+ /**
193
+ * Get the old .codex/prompts directory for cleanup purposes
194
+ */
195
+ getOldCodexPromptDir(projectDir = null, location = 'global') {
244
196
  if (location === 'project' && projectDir) {
245
197
  return path.join(projectDir, '.codex', 'prompts');
246
198
  }
247
199
  return path.join(os.homedir(), '.codex', 'prompts');
248
200
  }
249
201
 
250
- async flattenAndWriteArtifacts(artifacts, destDir) {
251
- let written = 0;
202
+ /**
203
+ * Write artifacts as Agent Skills (agentskills.io format).
204
+ * Each artifact becomes a directory containing SKILL.md.
205
+ * @param {string} destDir - Base skills directory
206
+ * @param {Array} artifacts - Artifacts to write
207
+ * @param {string} artifactType - Type filter (e.g., 'agent-launcher', 'workflow-command', 'task')
208
+ * @returns {number} Number of skills written
209
+ */
210
+ async writeSkillArtifacts(destDir, artifacts, artifactType) {
211
+ let writtenCount = 0;
252
212
 
253
213
  for (const artifact of artifacts) {
254
- const flattenedName = this.flattenFilename(artifact.relativePath);
255
- const targetPath = path.join(destDir, flattenedName);
256
- await fs.writeFile(targetPath, artifact.content);
257
- written++;
214
+ // Filter by type if the artifact has a type field
215
+ if (artifact.type && artifact.type !== artifactType) {
216
+ continue;
217
+ }
218
+
219
+ // Get the dash-format name (e.g., bmad-bmm-create-prd.md) and remove .md
220
+ const flatName = toDashPath(artifact.relativePath);
221
+ const skillName = flatName.replace(/\.md$/, '');
222
+
223
+ // Create skill directory
224
+ const skillDir = path.join(destDir, skillName);
225
+ await fs.ensureDir(skillDir);
226
+
227
+ // Transform content: rewrite frontmatter for skills format
228
+ const skillContent = this.transformToSkillFormat(artifact.content, skillName);
229
+
230
+ // Write SKILL.md with platform-native line endings
231
+ const platformContent = skillContent.replaceAll('\n', os.EOL);
232
+ await fs.writeFile(path.join(skillDir, 'SKILL.md'), platformContent, 'utf8');
233
+ writtenCount++;
234
+ }
235
+
236
+ return writtenCount;
237
+ }
238
+
239
+ /**
240
+ * Transform artifact content from Codex prompt format to Agent Skills format.
241
+ * Removes disable-model-invocation, ensures name matches directory.
242
+ * @param {string} content - Original content with YAML frontmatter
243
+ * @param {string} skillName - Skill name (must match directory name)
244
+ * @returns {string} Transformed content
245
+ */
246
+ transformToSkillFormat(content, skillName) {
247
+ // Normalize line endings so body matches rebuilt frontmatter (both LF)
248
+ content = content.replaceAll('\r\n', '\n').replaceAll('\r', '\n');
249
+
250
+ // Parse frontmatter
251
+ const fmMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/);
252
+ if (!fmMatch) {
253
+ // No frontmatter -- wrap with minimal frontmatter
254
+ const fm = yaml.stringify({ name: skillName, description: skillName }).trimEnd();
255
+ return `---\n${fm}\n---\n\n${content}`;
258
256
  }
259
257
 
260
- return written;
258
+ const frontmatter = fmMatch[1];
259
+ const body = fmMatch[2];
260
+
261
+ // Parse frontmatter with yaml library to handle all quoting variants
262
+ let description;
263
+ try {
264
+ const parsed = yaml.parse(frontmatter);
265
+ description = parsed?.description || `${skillName} skill`;
266
+ } catch {
267
+ description = `${skillName} skill`;
268
+ }
269
+
270
+ // Build new frontmatter with only skills-spec fields, let yaml handle quoting
271
+ const newFrontmatter = yaml.stringify({ name: skillName, description }, { lineWidth: 0 }).trimEnd();
272
+ return `---\n${newFrontmatter}\n---\n${body}`;
261
273
  }
262
274
 
275
+ /**
276
+ * Remove existing BMAD skill directories from the skills directory.
277
+ */
278
+ async clearOldBmadSkills(destDir, options = {}) {
279
+ if (!(await fs.pathExists(destDir))) {
280
+ return;
281
+ }
282
+
283
+ let entries;
284
+ try {
285
+ entries = await fs.readdir(destDir);
286
+ } catch (error) {
287
+ if (!options.silent) await prompts.log.warn(`Warning: Could not read directory ${destDir}: ${error.message}`);
288
+ return;
289
+ }
290
+
291
+ if (!entries || !Array.isArray(entries)) {
292
+ return;
293
+ }
294
+
295
+ for (const entry of entries) {
296
+ if (!entry || typeof entry !== 'string') {
297
+ continue;
298
+ }
299
+ if (!entry.startsWith('bmad')) {
300
+ continue;
301
+ }
302
+
303
+ const entryPath = path.join(destDir, entry);
304
+ try {
305
+ await fs.remove(entryPath);
306
+ } catch (error) {
307
+ if (!options.silent) {
308
+ await prompts.log.message(` Skipping ${entry}: ${error.message}`);
309
+ }
310
+ }
311
+ }
312
+ }
313
+
314
+ /**
315
+ * Clean old BMAD files from legacy .codex/prompts directories.
316
+ */
263
317
  async clearOldBmadFiles(destDir, options = {}) {
264
318
  if (!(await fs.pathExists(destDir))) {
265
319
  return;
@@ -299,30 +353,11 @@ class CodexSetup extends BaseIdeSetup {
299
353
  }
300
354
 
301
355
  async readAndProcessWithProject(filePath, metadata, projectDir) {
302
- const content = await fs.readFile(filePath, 'utf8');
356
+ const rawContent = await fs.readFile(filePath, 'utf8');
357
+ const content = rawContent.replaceAll('\r\n', '\n').replaceAll('\r', '\n');
303
358
  return super.processContent(content, metadata, projectDir);
304
359
  }
305
360
 
306
- /**
307
- * Get instructions for global installation
308
- * @returns {string} Instructions text
309
- */
310
- getGlobalInstructions(destDir) {
311
- const lines = [
312
- 'IMPORTANT: Codex Configuration',
313
- '',
314
- '/prompts installed globally to your HOME DIRECTORY.',
315
- '',
316
- 'These prompts reference a specific _bmad path.',
317
- "To use with other projects, you'd need to copy the _bmad dir.",
318
- '',
319
- 'You can now use /commands in Codex CLI',
320
- ' Example: /bmad_bmm_pm',
321
- ' Type / to see all available commands',
322
- ];
323
- return lines.join('\n');
324
- }
325
-
326
361
  /**
327
362
  * Get instructions for project-specific installation
328
363
  * @param {string} projectDir - Optional project directory
@@ -330,95 +365,74 @@ class CodexSetup extends BaseIdeSetup {
330
365
  * @returns {string} Instructions text
331
366
  */
332
367
  getProjectSpecificInstructions(projectDir = null, destDir = null) {
333
- const isWindows = os.platform() === 'win32';
334
-
335
- const commonLines = [
368
+ const lines = [
336
369
  'Project-Specific Codex Configuration',
337
370
  '',
338
- `Prompts will be installed to: ${destDir || '<project>/.codex/prompts'}`,
339
- '',
340
- 'REQUIRED: You must set CODEX_HOME to use these prompts',
341
- '',
342
- ];
343
-
344
- const windowsLines = [
345
- 'Create a codex.cmd file in your project root:',
346
- '',
347
- ' @echo off',
348
- ' set CODEX_HOME=%~dp0.codex',
349
- ' codex %*',
371
+ `Skills installed to: ${destDir || '<project>/.agents/skills'}`,
350
372
  '',
351
- String.raw`Then run: .\codex instead of codex`,
352
- '(The %~dp0 gets the directory of the .cmd file)',
373
+ 'Codex automatically discovers skills in .agents/skills/ at and above the current directory and in your home directory.',
374
+ 'No additional configuration is needed.',
353
375
  ];
354
376
 
355
- const unixLines = [
356
- 'Add this alias to your ~/.bashrc or ~/.zshrc:',
357
- '',
358
- ' alias codex=\'CODEX_HOME="$PWD/.codex" codex\'',
359
- '',
360
- 'After adding, run: source ~/.bashrc (or source ~/.zshrc)',
361
- '(The $PWD uses your current working directory)',
362
- ];
363
- const closingLines = ['', 'This tells Codex CLI to use prompts from this project instead of ~/.codex'];
364
-
365
- const lines = [...commonLines, ...(isWindows ? windowsLines : unixLines), ...closingLines];
366
-
367
377
  return lines.join('\n');
368
378
  }
369
379
 
370
380
  /**
371
- * Cleanup Codex configuration
381
+ * Cleanup Codex configuration - cleans both new .agents/skills and old .codex/prompts
372
382
  */
373
383
  async cleanup(projectDir = null) {
374
- // Clean both global and project-specific locations
375
- const globalDir = this.getCodexPromptDir(null, 'global');
376
- await this.clearOldBmadFiles(globalDir);
384
+ // Clean old .codex/prompts locations
385
+ const oldGlobalDir = this.getOldCodexPromptDir(null, 'global');
386
+ await this.clearOldBmadFiles(oldGlobalDir);
377
387
 
378
388
  if (projectDir) {
379
- const projectSpecificDir = this.getCodexPromptDir(projectDir, 'project');
380
- await this.clearOldBmadFiles(projectSpecificDir);
389
+ const oldProjectDir = this.getOldCodexPromptDir(projectDir, 'project');
390
+ await this.clearOldBmadFiles(oldProjectDir);
391
+
392
+ // Clean new .agents/skills location
393
+ const destDir = this.getCodexSkillsDir(projectDir);
394
+ await this.clearOldBmadSkills(destDir);
381
395
  }
382
396
  }
383
397
 
384
398
  /**
385
- * Install a custom agent launcher for Codex
386
- * @param {string} projectDir - Project directory (not used, Codex installs to home)
399
+ * Install a custom agent launcher for Codex as an Agent Skill
400
+ * @param {string} projectDir - Project directory
387
401
  * @param {string} agentName - Agent name (e.g., "fred-commit-poet")
388
402
  * @param {string} agentPath - Path to compiled agent (relative to project root)
389
403
  * @param {Object} metadata - Agent metadata
390
- * @returns {Object|null} Info about created command
404
+ * @returns {Object|null} Info about created skill
391
405
  */
392
406
  async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
393
- const destDir = this.getCodexPromptDir(projectDir, 'project');
394
- await fs.ensureDir(destDir);
395
-
396
- const launcherContent = `---
397
- name: '${agentName}'
398
- description: '${agentName} agent'
399
- disable-model-invocation: true
400
- ---
401
-
402
- You must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.
403
-
404
- <agent-activation CRITICAL="TRUE">
405
- 1. LOAD the FULL agent file from @${agentPath}
406
- 2. READ its entire contents - this contains the complete agent persona, menu, and instructions
407
- 3. FOLLOW every step in the <activation> section precisely
408
- 4. DISPLAY the welcome/greeting as instructed
409
- 5. PRESENT the numbered menu
410
- 6. WAIT for user input before proceeding
411
- </agent-activation>
412
- `;
413
-
414
- // Use underscore format: bmad_custom_fred-commit-poet.md
415
- const fileName = customAgentDashName(agentName);
416
- const launcherPath = path.join(destDir, fileName);
417
- await fs.writeFile(launcherPath, launcherContent, 'utf8');
407
+ const destDir = this.getCodexSkillsDir(projectDir);
408
+
409
+ // Skill name from the dash name (without .md)
410
+ const skillName = customAgentDashName(agentName).replace(/\.md$/, '');
411
+ const skillDir = path.join(destDir, skillName);
412
+ await fs.ensureDir(skillDir);
413
+
414
+ const description = metadata?.description || `${agentName} agent`;
415
+ const fm = yaml.stringify({ name: skillName, description }).trimEnd();
416
+ const skillContent =
417
+ `---\n${fm}\n---\n` +
418
+ "\nYou must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.\n" +
419
+ '\n<agent-activation CRITICAL="TRUE">\n' +
420
+ `1. LOAD the FULL agent file from @${agentPath}\n` +
421
+ '2. READ its entire contents - this contains the complete agent persona, menu, and instructions\n' +
422
+ '3. FOLLOW every step in the <activation> section precisely\n' +
423
+ '4. DISPLAY the welcome/greeting as instructed\n' +
424
+ '5. PRESENT the numbered menu\n' +
425
+ '6. WAIT for user input before proceeding\n' +
426
+ '</agent-activation>\n';
427
+
428
+ // Write with platform-native line endings
429
+ const platformContent = skillContent.replaceAll('\n', os.EOL);
430
+ const skillPath = path.join(skillDir, 'SKILL.md');
431
+ await fs.writeFile(skillPath, platformContent, 'utf8');
418
432
 
419
433
  return {
420
- path: path.relative(projectDir, launcherPath),
421
- command: `/${fileName.replace('.md', '')}`,
434
+ path: path.relative(projectDir, skillPath),
435
+ command: `$${skillName}`,
422
436
  };
423
437
  }
424
438
  }
@@ -166,7 +166,6 @@ class GitHubCopilotSetup extends BaseIdeSetup {
166
166
  return `---
167
167
  description: '${description.replaceAll("'", "''")}'
168
168
  tools: ${toolsStr}
169
- disable-model-invocation: true
170
169
  ---
171
170
 
172
171
  You must fully embody this agent's persona and follow all activation instructions exactly as specified.
@@ -8,7 +8,7 @@ const prompts = require('../../../lib/prompts');
8
8
  * Dynamically discovers and loads IDE handlers
9
9
  *
10
10
  * Loading strategy:
11
- * 1. Custom installer files (codex.js, github-copilot.js, kilo.js) - for platforms with unique installation logic
11
+ * 1. Custom installer files (codex.js, github-copilot.js, kilo.js, rovodev.js) - for platforms with unique installation logic
12
12
  * 2. Config-driven handlers (from platform-codes.yaml) - for standard IDE installation patterns
13
13
  */
14
14
  class IdeManager {
@@ -44,7 +44,7 @@ class IdeManager {
44
44
 
45
45
  /**
46
46
  * Dynamically load all IDE handlers
47
- * 1. Load custom installer files first (codex.js, github-copilot.js, kilo.js)
47
+ * 1. Load custom installer files first (codex.js, github-copilot.js, kilo.js, rovodev.js)
48
48
  * 2. Load config-driven handlers from platform-codes.yaml
49
49
  */
50
50
  async loadHandlers() {
@@ -61,7 +61,7 @@ class IdeManager {
61
61
  */
62
62
  async loadCustomInstallerFiles() {
63
63
  const ideDir = __dirname;
64
- const customFiles = ['codex.js', 'github-copilot.js', 'kilo.js'];
64
+ const customFiles = ['codex.js', 'github-copilot.js', 'kilo.js', 'rovodev.js'];
65
65
 
66
66
  for (const file of customFiles) {
67
67
  const filePath = path.join(ideDir, file);
@@ -57,6 +57,15 @@ platforms:
57
57
  description: "OpenAI Codex integration"
58
58
  # No installer config - uses custom codex.js
59
59
 
60
+ codebuddy:
61
+ name: "CodeBuddy"
62
+ preferred: false
63
+ category: ide
64
+ description: "Tencent Cloud Code Assistant - AI-powered coding companion"
65
+ installer:
66
+ target_dir: .codebuddy/commands
67
+ template_type: default
68
+
60
69
  crush:
61
70
  name: "Crush"
62
71
  preferred: false
@@ -153,9 +162,7 @@ platforms:
153
162
  preferred: false
154
163
  category: ide
155
164
  description: "Atlassian's Rovo development environment"
156
- installer:
157
- target_dir: .rovodev/workflows
158
- template_type: rovodev
165
+ # No installer config - uses custom rovodev.js (generates prompts.yml manifest)
159
166
 
160
167
  trae:
161
168
  name: "Trae"
@@ -168,7 +175,7 @@ platforms:
168
175
 
169
176
  windsurf:
170
177
  name: "Windsurf"
171
- preferred: true
178
+ preferred: false
172
179
  category: ide
173
180
  description: "AI-powered IDE with cascade flows"
174
181
  installer: