bmad-method 6.0.0-Beta.0 → 6.0.0-Beta.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.
- package/CHANGELOG.md +8 -1
- package/package.json +1 -1
- package/src/bmm/module-help.csv +31 -31
- package/src/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-04-review.md +1 -1
- package/src/core/module-help.csv +8 -8
- package/tools/cli/installers/install-messages.yaml +11 -10
- package/tools/cli/installers/lib/core/installer.js +26 -40
- package/tools/cli/installers/lib/ide/_config-driven.js +423 -0
- package/tools/cli/installers/lib/ide/codex.js +40 -12
- package/tools/cli/installers/lib/ide/manager.js +65 -38
- package/tools/cli/installers/lib/ide/platform-codes.js +100 -0
- package/tools/cli/installers/lib/ide/platform-codes.yaml +241 -0
- package/tools/cli/installers/lib/ide/shared/agent-command-generator.js +19 -5
- package/tools/cli/installers/lib/ide/shared/bmad-artifacts.js +5 -0
- package/tools/cli/installers/lib/ide/shared/path-utils.js +166 -50
- package/tools/cli/installers/lib/ide/shared/task-tool-command-generator.js +7 -5
- package/tools/cli/installers/lib/ide/shared/workflow-command-generator.js +21 -3
- package/tools/cli/installers/lib/ide/templates/combined/antigravity.md +8 -0
- package/tools/cli/installers/lib/ide/templates/combined/default-agent.md +15 -0
- package/tools/cli/installers/lib/ide/templates/combined/default-workflow-yaml.md +14 -0
- package/tools/cli/installers/lib/ide/templates/combined/default-workflow.md +6 -0
- package/tools/cli/installers/lib/ide/templates/combined/rovodev.md +9 -0
- package/tools/cli/installers/lib/ide/templates/combined/trae.md +9 -0
- package/tools/cli/installers/lib/ide/templates/combined/windsurf-workflow.md +10 -0
- package/tools/cli/installers/lib/ide/templates/split/gemini/body.md +10 -0
- package/tools/cli/installers/lib/ide/templates/split/gemini/header.toml +2 -0
- package/tools/cli/installers/lib/ide/templates/split/opencode/body.md +10 -0
- package/tools/cli/installers/lib/ide/templates/split/opencode/header.md +4 -0
- package/tools/cli/lib/ui.js +19 -75
- package/tools/cli/installers/lib/ide/STANDARDIZATION_PLAN.md +0 -208
- package/tools/cli/installers/lib/ide/antigravity.js +0 -474
- package/tools/cli/installers/lib/ide/auggie.js +0 -244
- package/tools/cli/installers/lib/ide/claude-code.js +0 -506
- package/tools/cli/installers/lib/ide/cline.js +0 -272
- package/tools/cli/installers/lib/ide/crush.js +0 -149
- package/tools/cli/installers/lib/ide/cursor.js +0 -160
- package/tools/cli/installers/lib/ide/gemini.js +0 -301
- package/tools/cli/installers/lib/ide/github-copilot.js +0 -383
- package/tools/cli/installers/lib/ide/iflow.js +0 -191
- package/tools/cli/installers/lib/ide/opencode.js +0 -257
- package/tools/cli/installers/lib/ide/qwen.js +0 -372
- package/tools/cli/installers/lib/ide/roo.js +0 -273
- package/tools/cli/installers/lib/ide/rovo-dev.js +0 -290
- package/tools/cli/installers/lib/ide/trae.js +0 -313
- package/tools/cli/installers/lib/ide/windsurf.js +0 -258
|
@@ -2,7 +2,16 @@
|
|
|
2
2
|
* Path transformation utilities for IDE installer standardization
|
|
3
3
|
*
|
|
4
4
|
* Provides utilities to convert hierarchical paths to flat naming conventions.
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
|
+
* DASH-BASED NAMING (new standard):
|
|
7
|
+
* - Agents: bmad-module-name.agent.md (with .agent.md suffix)
|
|
8
|
+
* - Workflows/Tasks/Tools: bmad-module-name.md
|
|
9
|
+
*
|
|
10
|
+
* Example outputs:
|
|
11
|
+
* - cis/agents/storymaster.md → bmad-cis-storymaster.agent.md
|
|
12
|
+
* - bmm/workflows/plan-project.md → bmad-bmm-plan-project.md
|
|
13
|
+
* - bmm/tasks/create-story.md → bmad-bmm-create-story.md
|
|
14
|
+
* - core/agents/brainstorming.md → bmad-brainstorming.agent.md
|
|
6
15
|
*/
|
|
7
16
|
|
|
8
17
|
// Type segments - agents are included in naming, others are filtered out
|
|
@@ -10,19 +19,148 @@ const TYPE_SEGMENTS = ['workflows', 'tasks', 'tools'];
|
|
|
10
19
|
const AGENT_SEGMENT = 'agents';
|
|
11
20
|
|
|
12
21
|
/**
|
|
13
|
-
* Convert hierarchical path to flat
|
|
14
|
-
* Converts: 'bmm', 'agents', 'pm' → '
|
|
15
|
-
* Converts: 'bmm', 'workflows', 'correct-course' → '
|
|
16
|
-
* Converts: 'core', 'agents', 'brainstorming' → '
|
|
22
|
+
* Convert hierarchical path to flat dash-separated name (NEW STANDARD)
|
|
23
|
+
* Converts: 'bmm', 'agents', 'pm' → 'bmad-bmm-pm.agent.md'
|
|
24
|
+
* Converts: 'bmm', 'workflows', 'correct-course' → 'bmad-bmm-correct-course.md'
|
|
25
|
+
* Converts: 'core', 'agents', 'brainstorming' → 'bmad-brainstorming.agent.md' (core items skip module prefix)
|
|
17
26
|
*
|
|
18
27
|
* @param {string} module - Module name (e.g., 'bmm', 'core')
|
|
19
28
|
* @param {string} type - Artifact type ('agents', 'workflows', 'tasks', 'tools')
|
|
20
29
|
* @param {string} name - Artifact name (e.g., 'pm', 'brainstorming')
|
|
21
|
-
* @returns {string} Flat filename like '
|
|
30
|
+
* @returns {string} Flat filename like 'bmad-bmm-pm.agent.md' or 'bmad-bmm-correct-course.md'
|
|
31
|
+
*/
|
|
32
|
+
function toDashName(module, type, name) {
|
|
33
|
+
const isAgent = type === AGENT_SEGMENT;
|
|
34
|
+
|
|
35
|
+
// For core module, skip the module prefix: use 'bmad-name.md' instead of 'bmad-core-name.md'
|
|
36
|
+
if (module === 'core') {
|
|
37
|
+
return isAgent ? `bmad-${name}.agent.md` : `bmad-${name}.md`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Module artifacts: bmad-module-name.md or bmad-module-name.agent.md
|
|
41
|
+
// eslint-disable-next-line unicorn/prefer-string-replace-all -- regex replace is intentional here
|
|
42
|
+
const dashName = name.replace(/\//g, '-'); // Flatten nested paths
|
|
43
|
+
return isAgent ? `bmad-${module}-${dashName}.agent.md` : `bmad-${module}-${dashName}.md`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Convert relative path to flat dash-separated name
|
|
48
|
+
* Converts: 'bmm/agents/pm.md' → 'bmad-bmm-pm.agent.md'
|
|
49
|
+
* Converts: 'bmm/workflows/correct-course.md' → 'bmad-bmm-correct-course.md'
|
|
50
|
+
* Converts: 'core/agents/brainstorming.md' → 'bmad-brainstorming.agent.md' (core items skip module prefix)
|
|
51
|
+
*
|
|
52
|
+
* @param {string} relativePath - Path like 'bmm/agents/pm.md'
|
|
53
|
+
* @returns {string} Flat filename like 'bmad-bmm-pm.agent.md' or 'bmad-brainstorming.md'
|
|
54
|
+
*/
|
|
55
|
+
function toDashPath(relativePath) {
|
|
56
|
+
if (!relativePath || typeof relativePath !== 'string') {
|
|
57
|
+
// Return a safe default for invalid input
|
|
58
|
+
return 'bmad-unknown.md';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const withoutExt = relativePath.replace('.md', '');
|
|
62
|
+
const parts = withoutExt.split(/[/\\]/);
|
|
63
|
+
|
|
64
|
+
const module = parts[0];
|
|
65
|
+
const type = parts[1];
|
|
66
|
+
const name = parts.slice(2).join('-');
|
|
67
|
+
|
|
68
|
+
return toDashName(module, type, name);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Create custom agent dash name
|
|
73
|
+
* Creates: 'bmad-custom-fred-commit-poet.agent.md'
|
|
74
|
+
*
|
|
75
|
+
* @param {string} agentName - Custom agent name
|
|
76
|
+
* @returns {string} Flat filename like 'bmad-custom-fred-commit-poet.agent.md'
|
|
77
|
+
*/
|
|
78
|
+
function customAgentDashName(agentName) {
|
|
79
|
+
return `bmad-custom-${agentName}.agent.md`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Check if a filename uses dash format
|
|
84
|
+
* @param {string} filename - Filename to check
|
|
85
|
+
* @returns {boolean} True if filename uses dash format
|
|
86
|
+
*/
|
|
87
|
+
function isDashFormat(filename) {
|
|
88
|
+
return filename.startsWith('bmad-') && filename.includes('-');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Extract parts from a dash-formatted filename
|
|
93
|
+
* Parses: 'bmad-bmm-pm.agent.md' → { prefix: 'bmad', module: 'bmm', type: 'agents', name: 'pm' }
|
|
94
|
+
* Parses: 'bmad-bmm-correct-course.md' → { prefix: 'bmad', module: 'bmm', type: 'workflows', name: 'correct-course' }
|
|
95
|
+
* Parses: 'bmad-brainstorming.agent.md' → { prefix: 'bmad', module: 'core', type: 'agents', name: 'brainstorming' } (core agents)
|
|
96
|
+
* Parses: 'bmad-brainstorming.md' → { prefix: 'bmad', module: 'core', type: 'workflows', name: 'brainstorming' } (core workflows)
|
|
97
|
+
*
|
|
98
|
+
* @param {string} filename - Dash-formatted filename
|
|
99
|
+
* @returns {Object|null} Parsed parts or null if invalid format
|
|
100
|
+
*/
|
|
101
|
+
function parseDashName(filename) {
|
|
102
|
+
const withoutExt = filename.replace('.md', '');
|
|
103
|
+
const parts = withoutExt.split('-');
|
|
104
|
+
|
|
105
|
+
if (parts.length < 2 || parts[0] !== 'bmad') {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Check if this is an agent file (has .agent suffix)
|
|
110
|
+
const isAgent = withoutExt.endsWith('.agent');
|
|
111
|
+
|
|
112
|
+
if (isAgent) {
|
|
113
|
+
// This is an agent file
|
|
114
|
+
// Format: bmad-name.agent (core) or bmad-module-name.agent
|
|
115
|
+
if (parts.length === 3) {
|
|
116
|
+
// Core agent: bmad-name.agent
|
|
117
|
+
return {
|
|
118
|
+
prefix: parts[0],
|
|
119
|
+
module: 'core',
|
|
120
|
+
type: 'agents',
|
|
121
|
+
name: parts[1],
|
|
122
|
+
};
|
|
123
|
+
} else {
|
|
124
|
+
// Module agent: bmad-module-name.agent
|
|
125
|
+
return {
|
|
126
|
+
prefix: parts[0],
|
|
127
|
+
module: parts[1],
|
|
128
|
+
type: 'agents',
|
|
129
|
+
name: parts.slice(2).join('-'),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Not an agent file - must be a workflow/tool/task
|
|
135
|
+
// If only 2 parts (bmad-name), it's a core workflow/tool/task
|
|
136
|
+
if (parts.length === 2) {
|
|
137
|
+
return {
|
|
138
|
+
prefix: parts[0],
|
|
139
|
+
module: 'core',
|
|
140
|
+
type: 'workflows', // Default to workflows for non-agent core items
|
|
141
|
+
name: parts[1],
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Otherwise, it's a module workflow/tool/task (bmad-module-name)
|
|
146
|
+
return {
|
|
147
|
+
prefix: parts[0],
|
|
148
|
+
module: parts[1],
|
|
149
|
+
type: 'workflows', // Default to workflows for non-agent module items
|
|
150
|
+
name: parts.slice(2).join('-'),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// ============================================================================
|
|
155
|
+
// LEGACY FUNCTIONS (underscore format) - kept for backward compatibility
|
|
156
|
+
// ============================================================================
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Convert hierarchical path to flat underscore-separated name (LEGACY)
|
|
160
|
+
* @deprecated Use toDashName instead
|
|
22
161
|
*/
|
|
23
162
|
function toUnderscoreName(module, type, name) {
|
|
24
163
|
const isAgent = type === AGENT_SEGMENT;
|
|
25
|
-
// For core module, skip the module prefix: use 'bmad_name.md' instead of 'bmad_core_name.md'
|
|
26
164
|
if (module === 'core') {
|
|
27
165
|
return isAgent ? `bmad_agent_${name}.md` : `bmad_${name}.md`;
|
|
28
166
|
}
|
|
@@ -30,13 +168,8 @@ function toUnderscoreName(module, type, name) {
|
|
|
30
168
|
}
|
|
31
169
|
|
|
32
170
|
/**
|
|
33
|
-
* Convert relative path to flat underscore-separated name
|
|
34
|
-
*
|
|
35
|
-
* Converts: 'bmm/workflows/correct-course.md' → 'bmad_bmm_correct-course.md'
|
|
36
|
-
* Converts: 'core/agents/brainstorming.md' → 'bmad_agent_brainstorming.md' (core items skip module prefix)
|
|
37
|
-
*
|
|
38
|
-
* @param {string} relativePath - Path like 'bmm/agents/pm.md'
|
|
39
|
-
* @returns {string} Flat filename like 'bmad_bmm_agent_pm.md' or 'bmad_brainstorming.md'
|
|
171
|
+
* Convert relative path to flat underscore-separated name (LEGACY)
|
|
172
|
+
* @deprecated Use toDashPath instead
|
|
40
173
|
*/
|
|
41
174
|
function toUnderscorePath(relativePath) {
|
|
42
175
|
const withoutExt = relativePath.replace('.md', '');
|
|
@@ -46,39 +179,28 @@ function toUnderscorePath(relativePath) {
|
|
|
46
179
|
const type = parts[1];
|
|
47
180
|
const name = parts.slice(2).join('_');
|
|
48
181
|
|
|
49
|
-
// Use toUnderscoreName for consistency
|
|
50
182
|
return toUnderscoreName(module, type, name);
|
|
51
183
|
}
|
|
52
184
|
|
|
53
185
|
/**
|
|
54
|
-
* Create custom agent underscore name
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* @param {string} agentName - Custom agent name
|
|
58
|
-
* @returns {string} Flat filename like 'bmad_custom_fred-commit-poet.md'
|
|
186
|
+
* Create custom agent underscore name (LEGACY)
|
|
187
|
+
* @deprecated Use customAgentDashName instead
|
|
59
188
|
*/
|
|
60
189
|
function customAgentUnderscoreName(agentName) {
|
|
61
190
|
return `bmad_custom_${agentName}.md`;
|
|
62
191
|
}
|
|
63
192
|
|
|
64
193
|
/**
|
|
65
|
-
* Check if a filename uses underscore format
|
|
66
|
-
* @
|
|
67
|
-
* @returns {boolean} True if filename uses underscore format
|
|
194
|
+
* Check if a filename uses underscore format (LEGACY)
|
|
195
|
+
* @deprecated Use isDashFormat instead
|
|
68
196
|
*/
|
|
69
197
|
function isUnderscoreFormat(filename) {
|
|
70
198
|
return filename.startsWith('bmad_') && filename.includes('_');
|
|
71
199
|
}
|
|
72
200
|
|
|
73
201
|
/**
|
|
74
|
-
* Extract parts from an underscore-formatted filename
|
|
75
|
-
*
|
|
76
|
-
* Parses: 'bmad_bmm_correct-course.md' → { prefix: 'bmad', module: 'bmm', type: 'workflows', name: 'correct-course' }
|
|
77
|
-
* Parses: 'bmad_agent_brainstorming.md' → { prefix: 'bmad', module: 'core', type: 'agents', name: 'brainstorming' } (core agents)
|
|
78
|
-
* Parses: 'bmad_brainstorming.md' → { prefix: 'bmad', module: 'core', type: 'workflows', name: 'brainstorming' } (core workflows)
|
|
79
|
-
*
|
|
80
|
-
* @param {string} filename - Underscore-formatted filename
|
|
81
|
-
* @returns {Object|null} Parsed parts or null if invalid format
|
|
202
|
+
* Extract parts from an underscore-formatted filename (LEGACY)
|
|
203
|
+
* @deprecated Use parseDashName instead
|
|
82
204
|
*/
|
|
83
205
|
function parseUnderscoreName(filename) {
|
|
84
206
|
const withoutExt = filename.replace('.md', '');
|
|
@@ -88,14 +210,10 @@ function parseUnderscoreName(filename) {
|
|
|
88
210
|
return null;
|
|
89
211
|
}
|
|
90
212
|
|
|
91
|
-
// Check if this is an agent file (has 'agent' as one of the parts)
|
|
92
213
|
const agentIndex = parts.indexOf('agent');
|
|
93
214
|
|
|
94
215
|
if (agentIndex !== -1) {
|
|
95
|
-
// This is an agent file
|
|
96
|
-
// Format: bmad_agent_name (core) or bmad_module_agent_name
|
|
97
216
|
if (agentIndex === 1) {
|
|
98
|
-
// Core agent: bmad_agent_name
|
|
99
217
|
return {
|
|
100
218
|
prefix: parts[0],
|
|
101
219
|
module: 'core',
|
|
@@ -103,7 +221,6 @@ function parseUnderscoreName(filename) {
|
|
|
103
221
|
name: parts.slice(agentIndex + 1).join('_'),
|
|
104
222
|
};
|
|
105
223
|
} else {
|
|
106
|
-
// Module agent: bmad_module_agent_name
|
|
107
224
|
return {
|
|
108
225
|
prefix: parts[0],
|
|
109
226
|
module: parts[1],
|
|
@@ -113,53 +230,52 @@ function parseUnderscoreName(filename) {
|
|
|
113
230
|
}
|
|
114
231
|
}
|
|
115
232
|
|
|
116
|
-
// Not an agent file - must be a workflow/tool/task
|
|
117
|
-
// If only 2 parts (bmad_name), it's a core workflow/tool/task
|
|
118
233
|
if (parts.length === 2) {
|
|
119
234
|
return {
|
|
120
235
|
prefix: parts[0],
|
|
121
236
|
module: 'core',
|
|
122
|
-
type: 'workflows',
|
|
237
|
+
type: 'workflows',
|
|
123
238
|
name: parts[1],
|
|
124
239
|
};
|
|
125
240
|
}
|
|
126
241
|
|
|
127
|
-
// Otherwise, it's a module workflow/tool/task (bmad_module_name)
|
|
128
242
|
return {
|
|
129
243
|
prefix: parts[0],
|
|
130
244
|
module: parts[1],
|
|
131
|
-
type: 'workflows',
|
|
245
|
+
type: 'workflows',
|
|
132
246
|
name: parts.slice(2).join('_'),
|
|
133
247
|
};
|
|
134
248
|
}
|
|
135
249
|
|
|
136
|
-
// Backward compatibility aliases (
|
|
250
|
+
// Backward compatibility aliases (colon format was same as underscore)
|
|
137
251
|
const toColonName = toUnderscoreName;
|
|
138
252
|
const toColonPath = toUnderscorePath;
|
|
139
|
-
const toDashPath = toUnderscorePath;
|
|
140
253
|
const customAgentColonName = customAgentUnderscoreName;
|
|
141
|
-
const customAgentDashName = customAgentUnderscoreName;
|
|
142
254
|
const isColonFormat = isUnderscoreFormat;
|
|
143
|
-
const isDashFormat = isUnderscoreFormat;
|
|
144
255
|
const parseColonName = parseUnderscoreName;
|
|
145
|
-
const parseDashName = parseUnderscoreName;
|
|
146
256
|
|
|
147
257
|
module.exports = {
|
|
258
|
+
// New standard (dash-based)
|
|
259
|
+
toDashName,
|
|
260
|
+
toDashPath,
|
|
261
|
+
customAgentDashName,
|
|
262
|
+
isDashFormat,
|
|
263
|
+
parseDashName,
|
|
264
|
+
|
|
265
|
+
// Legacy (underscore-based) - kept for backward compatibility
|
|
148
266
|
toUnderscoreName,
|
|
149
267
|
toUnderscorePath,
|
|
150
268
|
customAgentUnderscoreName,
|
|
151
269
|
isUnderscoreFormat,
|
|
152
270
|
parseUnderscoreName,
|
|
271
|
+
|
|
153
272
|
// Backward compatibility aliases
|
|
154
273
|
toColonName,
|
|
155
274
|
toColonPath,
|
|
156
|
-
toDashPath,
|
|
157
275
|
customAgentColonName,
|
|
158
|
-
customAgentDashName,
|
|
159
276
|
isColonFormat,
|
|
160
|
-
isDashFormat,
|
|
161
277
|
parseColonName,
|
|
162
|
-
|
|
278
|
+
|
|
163
279
|
TYPE_SEGMENTS,
|
|
164
280
|
AGENT_SEGMENT,
|
|
165
281
|
};
|
|
@@ -66,7 +66,7 @@ class TaskToolCommandGenerator {
|
|
|
66
66
|
|
|
67
67
|
// Convert path to use {project-root} placeholder
|
|
68
68
|
let itemPath = item.path;
|
|
69
|
-
if (itemPath.startsWith('bmad/')) {
|
|
69
|
+
if (itemPath && typeof itemPath === 'string' && itemPath.startsWith('bmad/')) {
|
|
70
70
|
itemPath = `{project-root}/${itemPath}`;
|
|
71
71
|
}
|
|
72
72
|
|
|
@@ -76,7 +76,7 @@ description: '${description.replaceAll("'", "''")}'
|
|
|
76
76
|
|
|
77
77
|
# ${item.displayName || item.name}
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
Read the entire ${type} file at: ${itemPath}
|
|
80
80
|
|
|
81
81
|
Follow all instructions in the ${type} file exactly as written.
|
|
82
82
|
`;
|
|
@@ -239,8 +239,10 @@ Follow all instructions in the ${type} file exactly as written.
|
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
/**
|
|
242
|
-
* Write task/tool artifacts using
|
|
243
|
-
* Creates flat files like:
|
|
242
|
+
* Write task/tool artifacts using dash format (NEW STANDARD)
|
|
243
|
+
* Creates flat files like: bmad-bmm-bmad-help.md
|
|
244
|
+
*
|
|
245
|
+
* Note: Tasks/tools do NOT have .agent.md suffix - only agents do.
|
|
244
246
|
*
|
|
245
247
|
* @param {string} baseCommandsDir - Base commands directory for the IDE
|
|
246
248
|
* @param {Array} artifacts - Task/tool artifacts with relativePath
|
|
@@ -252,7 +254,7 @@ Follow all instructions in the ${type} file exactly as written.
|
|
|
252
254
|
for (const artifact of artifacts) {
|
|
253
255
|
if (artifact.type === 'task' || artifact.type === 'tool') {
|
|
254
256
|
const commandContent = this.generateCommandContent(artifact, artifact.type);
|
|
255
|
-
// Use
|
|
257
|
+
// Use dash format: bmad-module-name.md
|
|
256
258
|
const flatName = toDashPath(artifact.relativePath);
|
|
257
259
|
const commandPath = path.join(baseCommandsDir, flatName);
|
|
258
260
|
await fs.ensureDir(path.dirname(commandPath));
|
|
@@ -67,10 +67,26 @@ class WorkflowCommandGenerator {
|
|
|
67
67
|
|
|
68
68
|
for (const workflow of allWorkflows) {
|
|
69
69
|
const commandContent = await this.generateCommandContent(workflow, bmadDir);
|
|
70
|
+
// Calculate the relative workflow path (e.g., bmm/workflows/4-implementation/sprint-planning/workflow.yaml)
|
|
71
|
+
let workflowRelPath = workflow.path;
|
|
72
|
+
// Remove _bmad/ prefix if present to get relative path from project root
|
|
73
|
+
// Handle both absolute paths (/path/to/_bmad/...) and relative paths (_bmad/...)
|
|
74
|
+
if (workflowRelPath.includes('_bmad/')) {
|
|
75
|
+
const parts = workflowRelPath.split(/_bmad\//);
|
|
76
|
+
if (parts.length > 1) {
|
|
77
|
+
workflowRelPath = parts.slice(1).join('/');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Determine if this is a YAML workflow
|
|
81
|
+
const isYamlWorkflow = workflow.path.endsWith('.yaml') || workflow.path.endsWith('.yml');
|
|
70
82
|
artifacts.push({
|
|
71
83
|
type: 'workflow-command',
|
|
84
|
+
isYamlWorkflow: isYamlWorkflow, // For template selection
|
|
85
|
+
name: workflow.name,
|
|
86
|
+
description: workflow.description || `${workflow.name} workflow`,
|
|
72
87
|
module: workflow.module,
|
|
73
88
|
relativePath: path.join(workflow.module, 'workflows', `${workflow.name}.md`),
|
|
89
|
+
workflowPath: workflowRelPath, // Relative path to actual workflow file
|
|
74
90
|
content: commandContent,
|
|
75
91
|
sourcePath: workflow.path,
|
|
76
92
|
});
|
|
@@ -265,8 +281,10 @@ When running any workflow:
|
|
|
265
281
|
}
|
|
266
282
|
|
|
267
283
|
/**
|
|
268
|
-
* Write workflow command artifacts using
|
|
269
|
-
* Creates flat files like:
|
|
284
|
+
* Write workflow command artifacts using dash format (NEW STANDARD)
|
|
285
|
+
* Creates flat files like: bmad-bmm-correct-course.md
|
|
286
|
+
*
|
|
287
|
+
* Note: Workflows do NOT have .agent.md suffix - only agents do.
|
|
270
288
|
*
|
|
271
289
|
* @param {string} baseCommandsDir - Base commands directory for the IDE
|
|
272
290
|
* @param {Array} artifacts - Workflow artifacts
|
|
@@ -277,7 +295,7 @@ When running any workflow:
|
|
|
277
295
|
|
|
278
296
|
for (const artifact of artifacts) {
|
|
279
297
|
if (artifact.type === 'workflow-command') {
|
|
280
|
-
// Convert relativePath to
|
|
298
|
+
// Convert relativePath to dash format: bmm/workflows/correct-course.md → bmad-bmm-correct-course.md
|
|
281
299
|
const flatName = toDashPath(artifact.relativePath);
|
|
282
300
|
const commandPath = path.join(baseCommandsDir, flatName);
|
|
283
301
|
await fs.ensureDir(path.dirname(commandPath));
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: '{{name}}'
|
|
3
|
+
description: '{{description}}'
|
|
4
|
+
---
|
|
5
|
+
|
|
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.
|
|
7
|
+
|
|
8
|
+
<agent-activation CRITICAL="TRUE">
|
|
9
|
+
1. LOAD the FULL agent file from {project-root}/_bmad/{{path}}
|
|
10
|
+
2. READ its entire contents - this contains the complete agent persona, menu, and instructions
|
|
11
|
+
3. FOLLOW every step in the <activation> section precisely
|
|
12
|
+
4. DISPLAY the welcome/greeting as instructed
|
|
13
|
+
5. PRESENT the numbered menu
|
|
14
|
+
6. WAIT for user input before proceeding
|
|
15
|
+
</agent-activation>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: '{{name}}'
|
|
3
|
+
description: '{{description}}'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
IT IS CRITICAL THAT YOU FOLLOW THESE STEPS - while staying in character as the current agent persona you may have loaded:
|
|
7
|
+
|
|
8
|
+
<steps CRITICAL="TRUE">
|
|
9
|
+
1. Always LOAD the FULL @{project-root}/{{bmadFolderName}}/core/tasks/workflow.xml
|
|
10
|
+
2. READ its entire contents - this is the CORE OS for EXECUTING the specific workflow-config @{project-root}/{{bmadFolderName}}/{{path}}
|
|
11
|
+
3. Pass the yaml path @{project-root}/{{bmadFolderName}}/{{path}} as 'workflow-config' parameter to the workflow.xml instructions
|
|
12
|
+
4. Follow workflow.xml instructions EXACTLY as written to process and follow the specific workflow config and its instructions
|
|
13
|
+
5. Save outputs after EACH section when generating any documents from templates
|
|
14
|
+
</steps>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
You must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.
|
|
2
|
+
|
|
3
|
+
<agent-activation CRITICAL="TRUE">
|
|
4
|
+
1. LOAD the FULL agent file from {project-root}/_bmad/{{path}}
|
|
5
|
+
2. READ its entire contents - this contains the complete agent persona, menu, and instructions
|
|
6
|
+
3. FOLLOW every step in the <activation> section precisely
|
|
7
|
+
4. DISPLAY the welcome/greeting as instructed
|
|
8
|
+
5. PRESENT the numbered menu
|
|
9
|
+
6. WAIT for user input before proceeding
|
|
10
|
+
</agent-activation>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
You must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.
|
|
2
|
+
|
|
3
|
+
<agent-activation CRITICAL="TRUE">
|
|
4
|
+
1. LOAD the FULL agent file from {project-root}/_bmad/{{path}}
|
|
5
|
+
2. READ its entire contents - this contains the complete agent persona, menu, and instructions
|
|
6
|
+
3. FOLLOW every step in the <activation> section precisely
|
|
7
|
+
4. DISPLAY the welcome/greeting as instructed
|
|
8
|
+
5. PRESENT the numbered menu
|
|
9
|
+
6. WAIT for user input before proceeding
|
|
10
|
+
</agent-activation>
|