bmad-method 6.3.1-next.1 → 6.3.1-next.3
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/package.json +1 -1
- package/src/bmm-skills/4-implementation/bmad-quick-dev/step-01-clarify-and-route.md +14 -5
- package/src/bmm-skills/4-implementation/bmad-quick-dev/step-03-implement.md +2 -0
- package/src/bmm-skills/4-implementation/bmad-quick-dev/step-05-present.md +17 -8
- package/src/bmm-skills/4-implementation/bmad-quick-dev/step-oneshot.md +4 -0
- package/src/bmm-skills/4-implementation/bmad-quick-dev/sync-sprint-status.md +19 -0
- package/src/bmm-skills/4-implementation/bmad-quick-dev/workflow.md +1 -0
- package/tools/installer/ide/shared/agent-command-generator.js +0 -180
- package/tools/installer/ide/shared/bmad-artifacts.js +0 -208
- package/tools/installer/ide/templates/agent-command-template.md +0 -14
- package/tools/installer/ide/templates/combined/antigravity.md +0 -8
- package/tools/installer/ide/templates/combined/default-agent.md +0 -15
- package/tools/installer/ide/templates/combined/default-task.md +0 -10
- package/tools/installer/ide/templates/combined/default-tool.md +0 -10
- package/tools/installer/ide/templates/combined/default-workflow.md +0 -6
- package/tools/installer/ide/templates/combined/gemini-agent.toml +0 -14
- package/tools/installer/ide/templates/combined/gemini-task.toml +0 -11
- package/tools/installer/ide/templates/combined/gemini-tool.toml +0 -11
- package/tools/installer/ide/templates/combined/gemini-workflow-yaml.toml +0 -16
- package/tools/installer/ide/templates/combined/gemini-workflow.toml +0 -14
- package/tools/installer/ide/templates/combined/kiro-agent.md +0 -16
- package/tools/installer/ide/templates/combined/kiro-task.md +0 -9
- package/tools/installer/ide/templates/combined/kiro-tool.md +0 -9
- package/tools/installer/ide/templates/combined/kiro-workflow.md +0 -7
- package/tools/installer/ide/templates/combined/opencode-agent.md +0 -15
- package/tools/installer/ide/templates/combined/opencode-task.md +0 -13
- package/tools/installer/ide/templates/combined/opencode-tool.md +0 -13
- package/tools/installer/ide/templates/combined/opencode-workflow-yaml.md +0 -16
- package/tools/installer/ide/templates/combined/opencode-workflow.md +0 -16
- package/tools/installer/ide/templates/combined/rovodev.md +0 -9
- package/tools/installer/ide/templates/combined/trae.md +0 -9
- package/tools/installer/ide/templates/combined/windsurf-workflow.md +0 -10
- package/tools/installer/ide/templates/split/.gitkeep +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
deferred_work_file: '{implementation_artifacts}/deferred-work.md'
|
|
3
3
|
spec_file: '' # set at runtime for both routes before leaving this step
|
|
4
|
+
story_key: '' # set at runtime to the current story's full sprint-status key (e.g. 3-2-digest-delivery) when the intent is an epic story and sprint-status resolution succeeds
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# Step 1: Clarify and Route
|
|
@@ -20,7 +21,7 @@ Before listing artifacts or prompting the user, check whether you already know t
|
|
|
20
21
|
|
|
21
22
|
1. Explicit argument
|
|
22
23
|
Did the user pass a specific file path, spec name, or clear instruction this message?
|
|
23
|
-
- If it points to a file that matches the spec template (has `status` frontmatter with a recognized value: draft, ready-for-dev, in-progress, in-review, or done) → set `spec_file
|
|
24
|
+
- If it points to a file that matches the spec template (has `status` frontmatter with a recognized value: draft, ready-for-dev, in-progress, in-review, or done) → set `spec_file`. Before exiting, run **Story-key resolution** (below). Then **EARLY EXIT** to the appropriate step (step-02 for draft, step-03 for ready/in-progress, step-04 for review). For `done`, ingest as context and proceed to INSTRUCTIONS — do not resume.
|
|
24
25
|
- Anything else (intent files, external docs, plans, descriptions) → ingest it as starting intent and proceed to INSTRUCTIONS. Do not attempt to infer a workflow state from it.
|
|
25
26
|
|
|
26
27
|
2. Recent conversation
|
|
@@ -29,13 +30,19 @@ Before listing artifacts or prompting the user, check whether you already know t
|
|
|
29
30
|
|
|
30
31
|
3. Otherwise — scan artifacts and ask
|
|
31
32
|
- Active specs (`draft`, `ready-for-dev`, `in-progress`, `in-review`) in `{implementation_artifacts}`? → List them and HALT. Ask user which to resume (or `[N]` for new).
|
|
32
|
-
- If `draft` selected: Set `spec_file`. **EARLY EXIT** → `./step-02-plan.md` (resume planning from the draft)
|
|
33
|
-
- If `ready-for-dev` or `in-progress` selected: Set `spec_file`. **EARLY EXIT** → `./step-03-implement.md`
|
|
34
|
-
- If `in-review` selected: Set `spec_file`. **EARLY EXIT** → `./step-04-review.md`
|
|
33
|
+
- If `draft` selected: Set `spec_file`. Run **Story-key resolution** (below). **EARLY EXIT** → `./step-02-plan.md` (resume planning from the draft)
|
|
34
|
+
- If `ready-for-dev` or `in-progress` selected: Set `spec_file`. Run **Story-key resolution** (below). **EARLY EXIT** → `./step-03-implement.md`
|
|
35
|
+
- If `in-review` selected: Set `spec_file`. Run **Story-key resolution** (below). **EARLY EXIT** → `./step-04-review.md`
|
|
35
36
|
- Unformatted spec or intent file lacking `status` frontmatter? → Suggest treating its contents as the starting intent. Do NOT attempt to infer a state and resume it.
|
|
36
37
|
|
|
37
38
|
Never ask extra questions if you already understand what the user intends.
|
|
38
39
|
|
|
40
|
+
### Story-key resolution
|
|
41
|
+
|
|
42
|
+
This runs on ALL paths (early-exit and INSTRUCTIONS) whenever `spec_file` is set. Determine whether the spec is an epic story — use the spec's filename, frontmatter, and any loaded epics file to identify `{epic_num}` and `{story_num}`. If the spec is not an epic story, skip silently and leave `{story_key}` unset.
|
|
43
|
+
|
|
44
|
+
If the spec is an epic story and `{sprint_status}` exists: find the `development_status` key matching `{epic_num}-{story_num}` by exact numeric equality on the first two segments (so `1-1` never collides with `1-10`). Exactly one match → set `{story_key}` to that full key. Zero or multiple matches → leave `{story_key}` unset (warn on multiple).
|
|
45
|
+
|
|
39
46
|
## INSTRUCTIONS
|
|
40
47
|
|
|
41
48
|
1. Load context.
|
|
@@ -45,7 +52,7 @@ Never ask extra questions if you already understand what the user intends.
|
|
|
45
52
|
|
|
46
53
|
**A) Epic story path** — if the intent is clearly an epic story:
|
|
47
54
|
|
|
48
|
-
1. Identify the epic number and (if present) the story number
|
|
55
|
+
1. Identify the epic number `{epic_num}` and (if present) the story number `{story_num}`. If you can't identify an epic number, use path B.
|
|
49
56
|
|
|
50
57
|
2. **Check for a valid cached epic context.** Look for `{implementation_artifacts}/epic-<N>-context.md` (where `<N>` is the epic number). A file is **valid** when it exists, is non-empty, starts with `# Epic <N> Context:` (with the correct epic number), and no file in `{planning_artifacts}` is newer.
|
|
51
58
|
- **If valid:** load it as the primary planning context. Do not load raw planning docs (PRD, architecture, UX, etc.). Skip to step 5.
|
|
@@ -59,6 +66,8 @@ Never ask extra questions if you already understand what the user intends.
|
|
|
59
66
|
|
|
60
67
|
5. **Previous story continuity.** Regardless of which context source succeeded above, scan `{implementation_artifacts}` for specs from the same epic with `status: done` and a lower story number. Load the most recent one (highest story number below current). Extract its **Code Map**, **Design Notes**, **Spec Change Log**, and **task list** as continuity context for step-02 planning. If no `done` spec is found but an `in-review` spec exists for the same epic with a lower story number, note it to the user and ask whether to load it.
|
|
61
68
|
|
|
69
|
+
6. **Resolve `{story_key}`.** If not already set by an earlier early-exit path, run **Story-key resolution** (above) now.
|
|
70
|
+
|
|
62
71
|
**B) Freeform path** — if the intent is not an epic story:
|
|
63
72
|
- Planning artifacts are the output of BMAD phases 1-3. Typical files include:
|
|
64
73
|
- **PRD** (`*prd*`) — product requirements and success criteria
|
|
@@ -24,6 +24,8 @@ Capture `baseline_commit` (current HEAD, or `NO_VCS` if version control is unava
|
|
|
24
24
|
|
|
25
25
|
Change `{spec_file}` status to `in-progress` in the frontmatter before starting implementation.
|
|
26
26
|
|
|
27
|
+
Follow `./sync-sprint-status.md` with `{target_status}` = `in-progress`.
|
|
28
|
+
|
|
27
29
|
If `{spec_file}` has a non-empty `context:` list in its frontmatter, load those files before implementation begins. When handing to a sub-agent, include them in the sub-agent prompt so it has access to the referenced context.
|
|
28
30
|
|
|
29
31
|
Hand `{spec_file}` to a sub-agent/task and let it implement. If no sub-agents are available, implement directly.
|
|
@@ -48,16 +48,25 @@ Format each stop as framing first, link on the next indented line:
|
|
|
48
48
|
|
|
49
49
|
When there is only one concern, omit the bold label — just list the stops directly.
|
|
50
50
|
|
|
51
|
-
###
|
|
51
|
+
### Mark Spec Done
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
Change `{spec_file}` status to `done` in the frontmatter.
|
|
54
|
+
|
|
55
|
+
Follow `./sync-sprint-status.md` with `{target_status}` = `review`.
|
|
56
|
+
|
|
57
|
+
### Commit and Open
|
|
58
|
+
|
|
59
|
+
1. If version control is available and the tree is dirty, create a local commit with a conventional message derived from the spec title.
|
|
60
|
+
2. Open the spec in the user's editor so they can click through the Suggested Review Order:
|
|
56
61
|
- Resolve two absolute paths: (1) the repository root (`git rev-parse --show-toplevel` — returns the worktree root when in a worktree, project root otherwise; if this fails, fall back to the current working directory), (2) `{spec_file}`. Run `code -r "{absolute-root}" "{absolute-spec-file}"` — the root first so VS Code opens in the right context, then the spec file. Always double-quote paths to handle spaces and special characters.
|
|
57
62
|
- If `code` is not available (command fails), skip gracefully and tell the user the spec file path instead.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
|
|
64
|
+
### Display Summary
|
|
65
|
+
|
|
66
|
+
Display summary of your work to the user, including the commit hash if one was created. Any file paths shown in conversation/terminal output must use CWD-relative format (no leading `/`) with `:line` notation (e.g., `src/path/file.ts:42`) for terminal clickability — the goal is to make paths clickable in terminal emulators. Include:
|
|
67
|
+
|
|
68
|
+
- A note that the spec is open in their editor (or the file path if it couldn't be opened). Mention that `{spec_file}` now contains a Suggested Review Order.
|
|
69
|
+
- **Navigation tip:** "Ctrl+click (Cmd+click on macOS) the links in the Suggested Review Order to jump to each stop."
|
|
70
|
+
- Offer to push and/or create a pull request.
|
|
62
71
|
|
|
63
72
|
Workflow complete.
|
|
@@ -13,6 +13,8 @@ deferred_work_file: '{implementation_artifacts}/deferred-work.md'
|
|
|
13
13
|
|
|
14
14
|
### Implement
|
|
15
15
|
|
|
16
|
+
Follow `./sync-sprint-status.md` with `{target_status}` = `in-progress`.
|
|
17
|
+
|
|
16
18
|
Implement the clarified intent directly.
|
|
17
19
|
|
|
18
20
|
### Review
|
|
@@ -39,6 +41,8 @@ Write `{spec_file}` using `./spec-template.md`. Fill only these sections — del
|
|
|
39
41
|
2. **Title and Intent** — `# {title}` heading and `## Intent` with **Problem** and **Approach** lines. Reuse the summary you already generated for the terminal.
|
|
40
42
|
3. **Suggested Review Order** — append after Intent. Build using the same convention as `./step-05-present.md` § "Generate Suggested Review Order" (spec-file-relative links, concern-based ordering, ultra-concise framing).
|
|
41
43
|
|
|
44
|
+
Follow `./sync-sprint-status.md` with `{target_status}` = `review`.
|
|
45
|
+
|
|
42
46
|
### Commit
|
|
43
47
|
|
|
44
48
|
If version control is available and the tree is dirty, create a local commit with a conventional message derived from the intent. If VCS is unavailable, skip.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Sync Sprint Status
|
|
2
|
+
|
|
3
|
+
Shared sub-step for updating `sprint-status.yaml` during quick-dev. Called from any route (plan-code-review, one-shot, future routes) with a `{target_status}` parameter.
|
|
4
|
+
|
|
5
|
+
## Preconditions
|
|
6
|
+
|
|
7
|
+
Skip this entire file (return to caller) if ANY of:
|
|
8
|
+
- `{story_key}` is unset
|
|
9
|
+
- `{sprint_status}` does not exist on disk
|
|
10
|
+
|
|
11
|
+
## Instructions
|
|
12
|
+
|
|
13
|
+
1. Load the FULL `{sprint_status}` file.
|
|
14
|
+
2. Find the `development_status` entry matching `{story_key}`. If not found, warn the user once (`"{story_key} not found in sprint-status; skipping sprint sync"`) and return to caller.
|
|
15
|
+
3. **Idempotency check.** If `development_status[{story_key}]` is already at `{target_status}` or a later state (`review` is later than `in-progress`; `done` is later than both), return to caller — no write needed. Never regress a story's status.
|
|
16
|
+
4. Set `development_status[{story_key}]` to `{target_status}`.
|
|
17
|
+
5. **Epic lift (only when `{target_status}` = `in-progress`).** Derive the parent epic key as `epic-{N}` from the leading numeric segment of `{story_key}` (e.g., `3-2-digest-delivery` → `epic-3`). If that entry exists and is `backlog`, set it to `in-progress`. Leave it alone otherwise. Skip this sub-step entirely when `{target_status}` is not `in-progress`.
|
|
18
|
+
6. Refresh `last_updated` to the current date.
|
|
19
|
+
7. Save the file, preserving ALL comments and structure including STATUS DEFINITIONS and WORKFLOW NOTES.
|
|
@@ -65,6 +65,7 @@ Load and read full config from `{main_config}` and resolve:
|
|
|
65
65
|
- `project_name`, `planning_artifacts`, `implementation_artifacts`, `user_name`
|
|
66
66
|
- `communication_language`, `document_output_language`, `user_skill_level`
|
|
67
67
|
- `date` as system-generated current datetime
|
|
68
|
+
- `sprint_status` = `{implementation_artifacts}/sprint-status.yaml`
|
|
68
69
|
- `project_context` = `**/project-context.md` (load if exists)
|
|
69
70
|
- CLAUDE.md / memory files (load if exist)
|
|
70
71
|
|
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
const path = require('node:path');
|
|
2
|
-
const fs = require('fs-extra');
|
|
3
|
-
const { toColonPath, toDashPath, customAgentColonName, customAgentDashName, BMAD_FOLDER_NAME } = require('./path-utils');
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Generates launcher command files for each agent
|
|
7
|
-
*/
|
|
8
|
-
class AgentCommandGenerator {
|
|
9
|
-
constructor(bmadFolderName = BMAD_FOLDER_NAME) {
|
|
10
|
-
this.templatePath = path.join(__dirname, '../templates/agent-command-template.md');
|
|
11
|
-
this.bmadFolderName = bmadFolderName;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Collect agent artifacts for IDE installation
|
|
16
|
-
* @param {string} bmadDir - BMAD installation directory
|
|
17
|
-
* @param {Array} selectedModules - Modules to include
|
|
18
|
-
* @returns {Object} Artifacts array with metadata
|
|
19
|
-
*/
|
|
20
|
-
async collectAgentArtifacts(bmadDir, selectedModules = []) {
|
|
21
|
-
const { getAgentsFromBmad } = require('./bmad-artifacts');
|
|
22
|
-
|
|
23
|
-
// Get agents from INSTALLED bmad/ directory
|
|
24
|
-
const agents = await getAgentsFromBmad(bmadDir, selectedModules);
|
|
25
|
-
|
|
26
|
-
const artifacts = [];
|
|
27
|
-
|
|
28
|
-
for (const agent of agents) {
|
|
29
|
-
const launcherContent = await this.generateLauncherContent(agent);
|
|
30
|
-
// Use relativePath if available (for nested agents), otherwise just name with .md
|
|
31
|
-
const agentPathInModule = agent.relativePath || `${agent.name}.md`;
|
|
32
|
-
// Calculate the relative agent path (e.g., bmm/agents/pm.md)
|
|
33
|
-
let agentRelPath = agent.path || '';
|
|
34
|
-
// Normalize path separators for cross-platform compatibility
|
|
35
|
-
agentRelPath = agentRelPath.replaceAll('\\', '/');
|
|
36
|
-
// Remove _bmad/ prefix if present to get relative path from project root
|
|
37
|
-
// Handle both absolute paths (/path/to/_bmad/...) and relative paths (_bmad/...)
|
|
38
|
-
if (agentRelPath.includes('_bmad/')) {
|
|
39
|
-
const parts = agentRelPath.split(/_bmad\//);
|
|
40
|
-
if (parts.length > 1) {
|
|
41
|
-
agentRelPath = parts.slice(1).join('/');
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
artifacts.push({
|
|
45
|
-
type: 'agent-launcher',
|
|
46
|
-
name: agent.name,
|
|
47
|
-
description: agent.description || `${agent.name} agent`,
|
|
48
|
-
module: agent.module,
|
|
49
|
-
canonicalId: agent.canonicalId || '',
|
|
50
|
-
relativePath: path.join(agent.module, 'agents', agentPathInModule), // For command filename
|
|
51
|
-
agentPath: agentRelPath, // Relative path to actual agent file
|
|
52
|
-
content: launcherContent,
|
|
53
|
-
sourcePath: agent.path,
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return {
|
|
58
|
-
artifacts,
|
|
59
|
-
counts: {
|
|
60
|
-
agents: agents.length,
|
|
61
|
-
},
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Generate launcher content for an agent
|
|
67
|
-
* @param {Object} agent - Agent metadata
|
|
68
|
-
* @returns {string} Launcher file content
|
|
69
|
-
*/
|
|
70
|
-
async generateLauncherContent(agent) {
|
|
71
|
-
// Load the template
|
|
72
|
-
const template = await fs.readFile(this.templatePath, 'utf8');
|
|
73
|
-
|
|
74
|
-
// Replace template variables
|
|
75
|
-
// Use relativePath if available (for nested agents), otherwise just name with .md
|
|
76
|
-
const agentPathInModule = agent.relativePath || `${agent.name}.md`;
|
|
77
|
-
return template
|
|
78
|
-
.replaceAll('{{name}}', agent.name)
|
|
79
|
-
.replaceAll('{{module}}', agent.module)
|
|
80
|
-
.replaceAll('{{path}}', agentPathInModule)
|
|
81
|
-
.replaceAll('{{description}}', agent.description || `${agent.name} agent`)
|
|
82
|
-
.replaceAll('_bmad', this.bmadFolderName)
|
|
83
|
-
.replaceAll('_bmad', '_bmad');
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Write agent launcher artifacts to IDE commands directory
|
|
88
|
-
* @param {string} baseCommandsDir - Base commands directory for the IDE
|
|
89
|
-
* @param {Array} artifacts - Agent launcher artifacts
|
|
90
|
-
* @returns {number} Count of launchers written
|
|
91
|
-
*/
|
|
92
|
-
async writeAgentLaunchers(baseCommandsDir, artifacts) {
|
|
93
|
-
let writtenCount = 0;
|
|
94
|
-
|
|
95
|
-
for (const artifact of artifacts) {
|
|
96
|
-
if (artifact.type === 'agent-launcher') {
|
|
97
|
-
const moduleAgentsDir = path.join(baseCommandsDir, artifact.module, 'agents');
|
|
98
|
-
await fs.ensureDir(moduleAgentsDir);
|
|
99
|
-
|
|
100
|
-
const launcherPath = path.join(moduleAgentsDir, `${artifact.name}.md`);
|
|
101
|
-
await fs.writeFile(launcherPath, artifact.content);
|
|
102
|
-
writtenCount++;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return writtenCount;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Write agent launcher artifacts using underscore format (Windows-compatible)
|
|
111
|
-
* Creates flat files like: bmad_bmm_pm.md
|
|
112
|
-
*
|
|
113
|
-
* @param {string} baseCommandsDir - Base commands directory for the IDE
|
|
114
|
-
* @param {Array} artifacts - Agent launcher artifacts
|
|
115
|
-
* @returns {number} Count of launchers written
|
|
116
|
-
*/
|
|
117
|
-
async writeColonArtifacts(baseCommandsDir, artifacts) {
|
|
118
|
-
let writtenCount = 0;
|
|
119
|
-
|
|
120
|
-
for (const artifact of artifacts) {
|
|
121
|
-
if (artifact.type === 'agent-launcher') {
|
|
122
|
-
// Convert relativePath to underscore format: bmm/agents/pm.md → bmad_bmm_pm.md
|
|
123
|
-
const flatName = toColonPath(artifact.relativePath);
|
|
124
|
-
const launcherPath = path.join(baseCommandsDir, flatName);
|
|
125
|
-
await fs.ensureDir(path.dirname(launcherPath));
|
|
126
|
-
await fs.writeFile(launcherPath, artifact.content);
|
|
127
|
-
writtenCount++;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return writtenCount;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Write agent launcher artifacts using dash format (NEW STANDARD)
|
|
136
|
-
* Creates flat files like: bmad-agent-bmm-pm.md
|
|
137
|
-
*
|
|
138
|
-
* The bmad-agent- prefix distinguishes agents from workflows/tasks/tools.
|
|
139
|
-
*
|
|
140
|
-
* @param {string} baseCommandsDir - Base commands directory for the IDE
|
|
141
|
-
* @param {Array} artifacts - Agent launcher artifacts
|
|
142
|
-
* @returns {number} Count of launchers written
|
|
143
|
-
*/
|
|
144
|
-
async writeDashArtifacts(baseCommandsDir, artifacts) {
|
|
145
|
-
let writtenCount = 0;
|
|
146
|
-
|
|
147
|
-
for (const artifact of artifacts) {
|
|
148
|
-
if (artifact.type === 'agent-launcher') {
|
|
149
|
-
// Convert relativePath to dash format: bmm/agents/pm.md → bmad-agent-bmm-pm.md
|
|
150
|
-
const flatName = toDashPath(artifact.relativePath);
|
|
151
|
-
const launcherPath = path.join(baseCommandsDir, flatName);
|
|
152
|
-
await fs.ensureDir(path.dirname(launcherPath));
|
|
153
|
-
await fs.writeFile(launcherPath, artifact.content);
|
|
154
|
-
writtenCount++;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
return writtenCount;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Get the custom agent name in underscore format (Windows-compatible)
|
|
163
|
-
* @param {string} agentName - Custom agent name
|
|
164
|
-
* @returns {string} Underscore-formatted filename
|
|
165
|
-
*/
|
|
166
|
-
getCustomAgentColonName(agentName) {
|
|
167
|
-
return customAgentColonName(agentName);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Get the custom agent name in underscore format (Windows-compatible)
|
|
172
|
-
* @param {string} agentName - Custom agent name
|
|
173
|
-
* @returns {string} Underscore-formatted filename
|
|
174
|
-
*/
|
|
175
|
-
getCustomAgentDashName(agentName) {
|
|
176
|
-
return customAgentDashName(agentName);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
module.exports = { AgentCommandGenerator };
|
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
const path = require('node:path');
|
|
2
|
-
const fs = require('fs-extra');
|
|
3
|
-
const { loadSkillManifest, getCanonicalId } = require('./skill-manifest');
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Helpers for gathering BMAD agents/tasks from the installed tree.
|
|
7
|
-
* Shared by installers that need Claude-style exports.
|
|
8
|
-
*
|
|
9
|
-
* TODO: Dead code cleanup — compiled XML agents are retired.
|
|
10
|
-
*
|
|
11
|
-
* All agents now use the SKILL.md directory format with bmad-skill-manifest.yaml
|
|
12
|
-
* (type: agent). The legacy pipeline below only discovers compiled .md files
|
|
13
|
-
* containing <agent> XML tags, which no longer exist. The following are dead:
|
|
14
|
-
*
|
|
15
|
-
* - getAgentsFromBmad() — scans {module}/agents/ for .md files with <agent> tags
|
|
16
|
-
* - getAgentsFromDir() — recursive helper for the above
|
|
17
|
-
* - AgentCommandGenerator — (agent-command-generator.js) generates launcher .md files
|
|
18
|
-
* that tell the LLM to load a compiled agent .md file
|
|
19
|
-
* - agent-command-template.md — (templates/) the launcher template with hardcoded
|
|
20
|
-
* {module}/agents/{{path}} reference
|
|
21
|
-
*
|
|
22
|
-
* Agent metadata for agent-manifest.csv is now handled entirely by
|
|
23
|
-
* ManifestGenerator.getAgentsFromDirRecursive() in manifest-generator.js,
|
|
24
|
-
* which walks the full module tree and finds type:agent directories.
|
|
25
|
-
*
|
|
26
|
-
* IDE installation of agents is handled by the native skill pipeline —
|
|
27
|
-
* each agent's SKILL.md directory is installed directly to the IDE's
|
|
28
|
-
* skills path, so no launcher intermediary is needed.
|
|
29
|
-
*
|
|
30
|
-
* Cleanup: remove getAgentsFromBmad, getAgentsFromDir, their exports,
|
|
31
|
-
* AgentCommandGenerator, agent-command-template.md, and all call sites
|
|
32
|
-
* in IDE installers that invoke collectAgentArtifacts / writeAgentLaunchers /
|
|
33
|
-
* writeColonArtifacts / writeDashArtifacts.
|
|
34
|
-
* getTasksFromBmad and getTasksFromDir may still be live — verify before removing.
|
|
35
|
-
*/
|
|
36
|
-
async function getAgentsFromBmad(bmadDir, selectedModules = []) {
|
|
37
|
-
const agents = [];
|
|
38
|
-
|
|
39
|
-
// Get core agents
|
|
40
|
-
if (await fs.pathExists(path.join(bmadDir, 'core', 'agents'))) {
|
|
41
|
-
const coreAgents = await getAgentsFromDir(path.join(bmadDir, 'core', 'agents'), 'core');
|
|
42
|
-
agents.push(...coreAgents);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Get module agents
|
|
46
|
-
for (const moduleName of selectedModules) {
|
|
47
|
-
const agentsPath = path.join(bmadDir, moduleName, 'agents');
|
|
48
|
-
|
|
49
|
-
if (await fs.pathExists(agentsPath)) {
|
|
50
|
-
const moduleAgents = await getAgentsFromDir(agentsPath, moduleName);
|
|
51
|
-
agents.push(...moduleAgents);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Get standalone agents from bmad/agents/ directory
|
|
56
|
-
const standaloneAgentsDir = path.join(bmadDir, 'agents');
|
|
57
|
-
if (await fs.pathExists(standaloneAgentsDir)) {
|
|
58
|
-
const agentDirs = await fs.readdir(standaloneAgentsDir, { withFileTypes: true });
|
|
59
|
-
|
|
60
|
-
for (const agentDir of agentDirs) {
|
|
61
|
-
if (!agentDir.isDirectory()) continue;
|
|
62
|
-
|
|
63
|
-
const agentDirPath = path.join(standaloneAgentsDir, agentDir.name);
|
|
64
|
-
const agentFiles = await fs.readdir(agentDirPath);
|
|
65
|
-
const skillManifest = await loadSkillManifest(agentDirPath);
|
|
66
|
-
|
|
67
|
-
for (const file of agentFiles) {
|
|
68
|
-
if (!file.endsWith('.md')) continue;
|
|
69
|
-
if (file.includes('.customize.')) continue;
|
|
70
|
-
|
|
71
|
-
const filePath = path.join(agentDirPath, file);
|
|
72
|
-
const content = await fs.readFile(filePath, 'utf8');
|
|
73
|
-
|
|
74
|
-
if (content.includes('localskip="true"')) continue;
|
|
75
|
-
|
|
76
|
-
agents.push({
|
|
77
|
-
path: filePath,
|
|
78
|
-
name: file.replace('.md', ''),
|
|
79
|
-
module: 'standalone', // Mark as standalone agent
|
|
80
|
-
canonicalId: getCanonicalId(skillManifest, file),
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return agents;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
async function getTasksFromBmad(bmadDir, selectedModules = []) {
|
|
90
|
-
const tasks = [];
|
|
91
|
-
|
|
92
|
-
if (await fs.pathExists(path.join(bmadDir, 'core', 'tasks'))) {
|
|
93
|
-
const coreTasks = await getTasksFromDir(path.join(bmadDir, 'core', 'tasks'), 'core');
|
|
94
|
-
tasks.push(...coreTasks);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
for (const moduleName of selectedModules) {
|
|
98
|
-
const tasksPath = path.join(bmadDir, moduleName, 'tasks');
|
|
99
|
-
|
|
100
|
-
if (await fs.pathExists(tasksPath)) {
|
|
101
|
-
const moduleTasks = await getTasksFromDir(tasksPath, moduleName);
|
|
102
|
-
tasks.push(...moduleTasks);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return tasks;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
async function getAgentsFromDir(dirPath, moduleName, relativePath = '') {
|
|
110
|
-
const agents = [];
|
|
111
|
-
|
|
112
|
-
if (!(await fs.pathExists(dirPath))) {
|
|
113
|
-
return agents;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
117
|
-
const skillManifest = await loadSkillManifest(dirPath);
|
|
118
|
-
|
|
119
|
-
for (const entry of entries) {
|
|
120
|
-
// Skip if entry.name is undefined or not a string
|
|
121
|
-
if (!entry.name || typeof entry.name !== 'string') {
|
|
122
|
-
continue;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const fullPath = path.join(dirPath, entry.name);
|
|
126
|
-
const newRelativePath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
|
|
127
|
-
|
|
128
|
-
if (entry.isDirectory()) {
|
|
129
|
-
// Recurse into subdirectories
|
|
130
|
-
const subDirAgents = await getAgentsFromDir(fullPath, moduleName, newRelativePath);
|
|
131
|
-
agents.push(...subDirAgents);
|
|
132
|
-
} else if (entry.name.endsWith('.md')) {
|
|
133
|
-
// Skip README files and other non-agent files
|
|
134
|
-
if (entry.name.toLowerCase() === 'readme.md' || entry.name.toLowerCase().startsWith('readme-')) {
|
|
135
|
-
continue;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (entry.name.includes('.customize.')) {
|
|
139
|
-
continue;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
const content = await fs.readFile(fullPath, 'utf8');
|
|
143
|
-
|
|
144
|
-
if (content.includes('localskip="true"')) {
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Only include files that have agent-specific content (compiled agents have <agent> tag)
|
|
149
|
-
if (!content.includes('<agent')) {
|
|
150
|
-
continue;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
agents.push({
|
|
154
|
-
path: fullPath,
|
|
155
|
-
name: entry.name.replace('.md', ''),
|
|
156
|
-
module: moduleName,
|
|
157
|
-
relativePath: newRelativePath, // Keep the .md extension for the full path
|
|
158
|
-
canonicalId: getCanonicalId(skillManifest, entry.name),
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return agents;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
async function getTasksFromDir(dirPath, moduleName) {
|
|
167
|
-
const tasks = [];
|
|
168
|
-
|
|
169
|
-
if (!(await fs.pathExists(dirPath))) {
|
|
170
|
-
return tasks;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const files = await fs.readdir(dirPath);
|
|
174
|
-
const skillManifest = await loadSkillManifest(dirPath);
|
|
175
|
-
|
|
176
|
-
for (const file of files) {
|
|
177
|
-
// Include both .md and .xml task files
|
|
178
|
-
if (!file.endsWith('.md') && !file.endsWith('.xml')) {
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const filePath = path.join(dirPath, file);
|
|
183
|
-
const content = await fs.readFile(filePath, 'utf8');
|
|
184
|
-
|
|
185
|
-
// Skip internal/engine files (not user-facing tasks)
|
|
186
|
-
if (content.includes('internal="true"')) {
|
|
187
|
-
continue;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// Remove extension to get task name
|
|
191
|
-
const ext = file.endsWith('.xml') ? '.xml' : '.md';
|
|
192
|
-
tasks.push({
|
|
193
|
-
path: filePath,
|
|
194
|
-
name: file.replace(ext, ''),
|
|
195
|
-
module: moduleName,
|
|
196
|
-
canonicalId: getCanonicalId(skillManifest, file),
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
return tasks;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
module.exports = {
|
|
204
|
-
getAgentsFromBmad,
|
|
205
|
-
getTasksFromBmad,
|
|
206
|
-
getAgentsFromDir,
|
|
207
|
-
getTasksFromDir,
|
|
208
|
-
};
|
|
@@ -1,14 +0,0 @@
|
|
|
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/{{module}}/agents/{{path}}
|
|
10
|
-
2. READ its entire contents - this contains the complete agent persona, menu, and instructions
|
|
11
|
-
3. Execute ALL activation steps exactly as written in the agent file
|
|
12
|
-
4. Follow the agent's persona and menu system precisely
|
|
13
|
-
5. Stay in character throughout the session
|
|
14
|
-
</agent-activation>
|
|
@@ -1,15 +0,0 @@
|
|
|
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>
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
description = "Activates the {{name}} agent from the BMad Method."
|
|
2
|
-
prompt = """
|
|
3
|
-
CRITICAL: You are now the BMad '{{name}}' agent.
|
|
4
|
-
|
|
5
|
-
PRE-FLIGHT CHECKLIST:
|
|
6
|
-
1. [ ] IMMEDIATE ACTION: Load and parse {project-root}/{{bmadFolderName}}/{{module}}/config.yaml - store ALL config values in memory for use throughout the session.
|
|
7
|
-
2. [ ] IMMEDIATE ACTION: Read and internalize the full agent definition at {project-root}/{{bmadFolderName}}/{{path}}.
|
|
8
|
-
3. [ ] CONFIRM: The user's name from config is {user_name}.
|
|
9
|
-
|
|
10
|
-
Only after all checks are complete, greet the user by name and display the menu.
|
|
11
|
-
Acknowledge this checklist is complete in your first response.
|
|
12
|
-
|
|
13
|
-
AGENT DEFINITION: {project-root}/{{bmadFolderName}}/{{path}}
|
|
14
|
-
"""
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
description = "Executes the {{name}} task from the BMAD Method."
|
|
2
|
-
prompt = """
|
|
3
|
-
Execute the BMAD '{{name}}' task.
|
|
4
|
-
|
|
5
|
-
TASK INSTRUCTIONS:
|
|
6
|
-
1. LOAD the task file from {project-root}/{{bmadFolderName}}/{{path}}
|
|
7
|
-
2. READ its entire contents
|
|
8
|
-
3. FOLLOW every instruction precisely as specified
|
|
9
|
-
|
|
10
|
-
TASK FILE: {project-root}/{{bmadFolderName}}/{{path}}
|
|
11
|
-
"""
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
description = "Executes the {{name}} tool from the BMAD Method."
|
|
2
|
-
prompt = """
|
|
3
|
-
Execute the BMAD '{{name}}' tool.
|
|
4
|
-
|
|
5
|
-
TOOL INSTRUCTIONS:
|
|
6
|
-
1. LOAD the tool file from {project-root}/{{bmadFolderName}}/{{path}}
|
|
7
|
-
2. READ its entire contents
|
|
8
|
-
3. FOLLOW every instruction precisely as specified
|
|
9
|
-
|
|
10
|
-
TOOL FILE: {project-root}/{{bmadFolderName}}/{{path}}
|
|
11
|
-
"""
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
description = '{{description}}'
|
|
2
|
-
prompt = """
|
|
3
|
-
Execute the BMAD '{{name}}' workflow.
|
|
4
|
-
|
|
5
|
-
CRITICAL: This is a structured YAML workflow. Follow these steps precisely:
|
|
6
|
-
|
|
7
|
-
1. LOAD the workflow definition from {project-root}/{{bmadFolderName}}/{{workflow_path}}
|
|
8
|
-
2. PARSE the YAML structure to understand:
|
|
9
|
-
- Workflow phases and steps
|
|
10
|
-
- Required inputs and outputs
|
|
11
|
-
- Dependencies between steps
|
|
12
|
-
3. EXECUTE each step in order
|
|
13
|
-
4. VALIDATE outputs before proceeding to next step
|
|
14
|
-
|
|
15
|
-
WORKFLOW FILE: {project-root}/{{bmadFolderName}}/{{workflow_path}}
|
|
16
|
-
"""
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
description = '{{description}}'
|
|
2
|
-
prompt = """
|
|
3
|
-
Execute the BMAD '{{name}}' workflow.
|
|
4
|
-
|
|
5
|
-
CRITICAL: You must load and follow the workflow definition exactly.
|
|
6
|
-
|
|
7
|
-
WORKFLOW INSTRUCTIONS:
|
|
8
|
-
1. LOAD the workflow file from {project-root}/{{bmadFolderName}}/{{workflow_path}}
|
|
9
|
-
2. READ its entire contents
|
|
10
|
-
3. FOLLOW every step precisely as specified
|
|
11
|
-
4. DO NOT skip or modify any steps
|
|
12
|
-
|
|
13
|
-
WORKFLOW FILE: {project-root}/{{bmadFolderName}}/{{workflow_path}}
|
|
14
|
-
"""
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
inclusion: manual
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# {{name}}
|
|
6
|
-
|
|
7
|
-
You must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.
|
|
8
|
-
|
|
9
|
-
<agent-activation CRITICAL="TRUE">
|
|
10
|
-
1. LOAD the FULL agent file from #[[file:{{bmadFolderName}}/{{path}}]]
|
|
11
|
-
2. READ its entire contents - this contains the complete agent persona, menu, and instructions
|
|
12
|
-
3. FOLLOW every step in the <activation> section precisely
|
|
13
|
-
4. DISPLAY the welcome/greeting as instructed
|
|
14
|
-
5. PRESENT the numbered menu
|
|
15
|
-
6. WAIT for user input before proceeding
|
|
16
|
-
</agent-activation>
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
mode: all
|
|
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}/{{bmadFolderName}}/{{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>
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: '{{description}}'
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
Execute the BMAD '{{name}}' task.
|
|
6
|
-
|
|
7
|
-
TASK INSTRUCTIONS:
|
|
8
|
-
|
|
9
|
-
1. LOAD the task file from {project-root}/{{bmadFolderName}}/{{path}}
|
|
10
|
-
2. READ its entire contents
|
|
11
|
-
3. FOLLOW every instruction precisely as specified
|
|
12
|
-
|
|
13
|
-
TASK FILE: {project-root}/{{bmadFolderName}}/{{path}}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: '{{description}}'
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
Execute the BMAD '{{name}}' tool.
|
|
6
|
-
|
|
7
|
-
TOOL INSTRUCTIONS:
|
|
8
|
-
|
|
9
|
-
1. LOAD the tool file from {project-root}/{{bmadFolderName}}/{{path}}
|
|
10
|
-
2. READ its entire contents
|
|
11
|
-
3. FOLLOW every instruction precisely as specified
|
|
12
|
-
|
|
13
|
-
TOOL FILE: {project-root}/{{bmadFolderName}}/{{path}}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: '{{description}}'
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
Execute the BMAD '{{name}}' workflow.
|
|
6
|
-
|
|
7
|
-
CRITICAL: You must load and follow the workflow definition exactly.
|
|
8
|
-
|
|
9
|
-
WORKFLOW INSTRUCTIONS:
|
|
10
|
-
|
|
11
|
-
1. LOAD the workflow file from {project-root}/{{bmadFolderName}}/{{path}}
|
|
12
|
-
2. READ its entire contents
|
|
13
|
-
3. FOLLOW every step precisely as specified
|
|
14
|
-
4. DO NOT skip or modify any steps
|
|
15
|
-
|
|
16
|
-
WORKFLOW FILE: {project-root}/{{bmadFolderName}}/{{path}}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: '{{description}}'
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
Execute the BMAD '{{name}}' workflow.
|
|
6
|
-
|
|
7
|
-
CRITICAL: You must load and follow the workflow definition exactly.
|
|
8
|
-
|
|
9
|
-
WORKFLOW INSTRUCTIONS:
|
|
10
|
-
|
|
11
|
-
1. LOAD the workflow file from {project-root}/{{bmadFolderName}}/{{path}}
|
|
12
|
-
2. READ its entire contents
|
|
13
|
-
3. FOLLOW every step precisely as specified
|
|
14
|
-
4. DO NOT skip or modify any steps
|
|
15
|
-
|
|
16
|
-
WORKFLOW FILE: {project-root}/{{bmadFolderName}}/{{path}}
|
|
File without changes
|