Compare commits

..

1 Commits

Author SHA1 Message Date
Nikolas Hor 8c131d663e
Merge f7d432abd3 into 861716fbe3 2026-03-12 09:10:46 -03:00
26 changed files with 31 additions and 153 deletions

View File

@ -37,7 +37,7 @@ permissions:
jobs: jobs:
publish: publish:
if: github.repository == 'bmad-code-org/BMAD-METHOD' && (github.event_name != 'workflow_dispatch' || github.ref == 'refs/heads/main') if: github.event_name != 'workflow_dispatch' || github.ref == 'refs/heads/main'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout

4
.gitignore vendored
View File

@ -20,10 +20,6 @@ build/*.txt
# Environment variables # Environment variables
.env .env
# Python
__pycache__/
.pytest_cache/
# System files # System files
.DS_Store .DS_Store
Thumbs.db Thumbs.db

View File

@ -18,7 +18,7 @@ agent:
menu: menu:
- trigger: BP or fuzzy match on brainstorm-project - trigger: BP or fuzzy match on brainstorm-project
exec: "skill:bmad-brainstorming" exec: "{project-root}/_bmad/core/workflows/brainstorming/workflow.md"
data: "{project-root}/_bmad/bmm/data/project-context-template.md" data: "{project-root}/_bmad/bmm/data/project-context-template.md"
description: "[BP] Brainstorm Project: Expert Guided Facilitation through a single or multiple techniques with a final report" description: "[BP] Brainstorm Project: Expert Guided Facilitation through a single or multiple techniques with a final report"

View File

@ -10,7 +10,7 @@ bmm,anytime,Update Standards,US,,_bmad/bmm/agents/tech-writer/tech-writer.agent.
bmm,anytime,Mermaid Generate,MG,,_bmad/bmm/agents/tech-writer/tech-writer.agent.yaml,,false,tech-writer,,"Create a Mermaid diagram based on user description. Will suggest diagram types if not specified.",planning_artifacts,"mermaid diagram", bmm,anytime,Mermaid Generate,MG,,_bmad/bmm/agents/tech-writer/tech-writer.agent.yaml,,false,tech-writer,,"Create a Mermaid diagram based on user description. Will suggest diagram types if not specified.",planning_artifacts,"mermaid diagram",
bmm,anytime,Validate Document,VD,,_bmad/bmm/agents/tech-writer/tech-writer.agent.yaml,,false,tech-writer,,"Review the specified document against documentation standards and best practices. Returns specific actionable improvement suggestions organized by priority.",planning_artifacts,"validation report", bmm,anytime,Validate Document,VD,,_bmad/bmm/agents/tech-writer/tech-writer.agent.yaml,,false,tech-writer,,"Review the specified document against documentation standards and best practices. Returns specific actionable improvement suggestions organized by priority.",planning_artifacts,"validation report",
bmm,anytime,Explain Concept,EC,,_bmad/bmm/agents/tech-writer/tech-writer.agent.yaml,,false,tech-writer,,"Create clear technical explanations with examples and diagrams for complex concepts. Breaks down into digestible sections using task-oriented approach.",project_knowledge,"explanation", bmm,anytime,Explain Concept,EC,,_bmad/bmm/agents/tech-writer/tech-writer.agent.yaml,,false,tech-writer,,"Create clear technical explanations with examples and diagrams for complex concepts. Breaks down into digestible sections using task-oriented approach.",project_knowledge,"explanation",
bmm,1-analysis,Brainstorm Project,BP,10,skill:bmad-brainstorming,bmad-brainstorming,false,analyst,data=_bmad/bmm/data/project-context-template.md,"Expert Guided Facilitation through a single or multiple techniques",planning_artifacts,"brainstorming session", bmm,1-analysis,Brainstorm Project,BP,10,_bmad/core/workflows/brainstorming/workflow.md,bmad-brainstorming,false,analyst,data=_bmad/bmm/data/project-context-template.md,"Expert Guided Facilitation through a single or multiple techniques",planning_artifacts,"brainstorming session",
bmm,1-analysis,Market Research,MR,20,_bmad/bmm/workflows/1-analysis/research/workflow-market-research.md,bmad-bmm-market-research,false,analyst,Create Mode,"Market analysis competitive landscape customer needs and trends","planning_artifacts|project-knowledge","research documents", bmm,1-analysis,Market Research,MR,20,_bmad/bmm/workflows/1-analysis/research/workflow-market-research.md,bmad-bmm-market-research,false,analyst,Create Mode,"Market analysis competitive landscape customer needs and trends","planning_artifacts|project-knowledge","research documents",
bmm,1-analysis,Domain Research,DR,21,_bmad/bmm/workflows/1-analysis/research/workflow-domain-research.md,bmad-bmm-domain-research,false,analyst,Create Mode,"Industry domain deep dive subject matter expertise and terminology","planning_artifacts|project_knowledge","research documents", bmm,1-analysis,Domain Research,DR,21,_bmad/bmm/workflows/1-analysis/research/workflow-domain-research.md,bmad-bmm-domain-research,false,analyst,Create Mode,"Industry domain deep dive subject matter expertise and terminology","planning_artifacts|project_knowledge","research documents",
bmm,1-analysis,Technical Research,TR,22,_bmad/bmm/workflows/1-analysis/research/workflow-technical-research.md,bmad-bmm-technical-research,false,analyst,Create Mode,"Technical feasibility architecture options and implementation approaches","planning_artifacts|project_knowledge","research documents", bmm,1-analysis,Technical Research,TR,22,_bmad/bmm/workflows/1-analysis/research/workflow-technical-research.md,bmad-bmm-technical-research,false,analyst,Create Mode,"Technical feasibility architecture options and implementation approaches","planning_artifacts|project_knowledge","research documents",

1 module phase name code sequence workflow-file command required agent options description output-location outputs
10 bmm anytime Mermaid Generate MG _bmad/bmm/agents/tech-writer/tech-writer.agent.yaml false tech-writer Create a Mermaid diagram based on user description. Will suggest diagram types if not specified. planning_artifacts mermaid diagram
11 bmm anytime Validate Document VD _bmad/bmm/agents/tech-writer/tech-writer.agent.yaml false tech-writer Review the specified document against documentation standards and best practices. Returns specific actionable improvement suggestions organized by priority. planning_artifacts validation report
12 bmm anytime Explain Concept EC _bmad/bmm/agents/tech-writer/tech-writer.agent.yaml false tech-writer Create clear technical explanations with examples and diagrams for complex concepts. Breaks down into digestible sections using task-oriented approach. project_knowledge explanation
13 bmm 1-analysis Brainstorm Project BP 10 skill:bmad-brainstorming _bmad/core/workflows/brainstorming/workflow.md bmad-brainstorming false analyst data=_bmad/bmm/data/project-context-template.md Expert Guided Facilitation through a single or multiple techniques planning_artifacts brainstorming session
14 bmm 1-analysis Market Research MR 20 _bmad/bmm/workflows/1-analysis/research/workflow-market-research.md bmad-bmm-market-research false analyst Create Mode Market analysis competitive landscape customer needs and trends planning_artifacts|project-knowledge research documents
15 bmm 1-analysis Domain Research DR 21 _bmad/bmm/workflows/1-analysis/research/workflow-domain-research.md bmad-bmm-domain-research false analyst Create Mode Industry domain deep dive subject matter expertise and terminology planning_artifacts|project_knowledge research documents
16 bmm 1-analysis Technical Research TR 22 _bmad/bmm/workflows/1-analysis/research/workflow-technical-research.md bmad-bmm-technical-research false analyst Create Mode Technical feasibility architecture options and implementation approaches planning_artifacts|project_knowledge research documents

View File

@ -1,5 +1,5 @@
module,phase,name,code,sequence,workflow-file,command,required,agent,options,description,output-location,outputs module,phase,name,code,sequence,workflow-file,command,required,agent,options,description,output-location,outputs
core,anytime,Brainstorming,BSP,,skill:bmad-brainstorming,bmad-brainstorming,false,analyst,,"Generate diverse ideas through interactive techniques. Use early in ideation phase or when stuck generating ideas.",{output_folder}/brainstorming/brainstorming-session-{{date}}.md,, core,anytime,Brainstorming,BSP,,_bmad/core/workflows/brainstorming/workflow.md,bmad-brainstorming,false,analyst,,"Generate diverse ideas through interactive techniques. Use early in ideation phase or when stuck generating ideas.",{output_folder}/brainstorming/brainstorming-session-{{date}}.md,,
core,anytime,Party Mode,PM,,skill:bmad-party-mode,bmad-party-mode,false,party-mode facilitator,,"Orchestrate multi-agent discussions. Use when you need multiple agent perspectives or want agents to collaborate.",, core,anytime,Party Mode,PM,,skill:bmad-party-mode,bmad-party-mode,false,party-mode facilitator,,"Orchestrate multi-agent discussions. Use when you need multiple agent perspectives or want agents to collaborate.",,
core,anytime,bmad-help,BH,,skill:bmad-help,bmad-help,false,,,"Get unstuck by showing what workflow steps come next or answering BMad Method questions.",, core,anytime,bmad-help,BH,,skill:bmad-help,bmad-help,false,,,"Get unstuck by showing what workflow steps come next or answering BMad Method questions.",,
core,anytime,Index Docs,ID,,skill:bmad-index-docs,bmad-index-docs,false,,,"Create lightweight index for quick LLM scanning. Use when LLM needs to understand available docs without loading everything.",, core,anytime,Index Docs,ID,,skill:bmad-index-docs,bmad-index-docs,false,,,"Create lightweight index for quick LLM scanning. Use when LLM needs to understand available docs without loading everything.",,

Can't render this file because it has a wrong number of fields in line 2.

View File

@ -1,6 +0,0 @@
---
name: bmad-brainstorming
description: 'Facilitate interactive brainstorming sessions using diverse creative techniques and ideation methods. Use when the user says help me brainstorm or help me ideate.'
---
Follow the instructions in [workflow.md](workflow.md).

View File

@ -1,4 +1,6 @@
--- ---
name: bmad-party-mode
description: 'Orchestrates group discussions between all installed BMAD agents, enabling natural multi-agent conversations. Use when user requests party mode.'
--- ---
# Party Mode Workflow # Party Mode Workflow

View File

@ -0,0 +1,3 @@
canonicalId: bmad-brainstorming
type: workflow
description: "Facilitate interactive brainstorming sessions using diverse creative techniques and ideation methods"

View File

@ -1,4 +1,6 @@
--- ---
name: brainstorming
description: 'Facilitate interactive brainstorming sessions using diverse creative techniques and ideation methods. Use when the user says help me brainstorm or help me ideate.'
context_file: '' # Optional context file path for project-specific guidance context_file: '' # Optional context file path for project-specific guidance
--- ---
@ -40,8 +42,9 @@ Load config from `{project-root}/_bmad/core/config.yaml` and resolve:
### Paths ### Paths
- `template_path` = `./template.md` - `installed_path` = `{project-root}/_bmad/core/workflows/brainstorming`
- `brain_techniques_path` = `./brain-methods.csv` - `template_path` = `{installed_path}/template.md`
- `brain_techniques_path` = `{installed_path}/brain-methods.csv`
- `brainstorming_session_output_file` = `{output_folder}/brainstorming/brainstorming-session-{{date}}-{{time}}.md` (evaluated once at workflow start) - `brainstorming_session_output_file` = `{output_folder}/brainstorming/brainstorming-session-{{date}}-{{time}}.md` (evaluated once at workflow start)
All steps MUST reference `{brainstorming_session_output_file}` instead of the full path pattern. All steps MUST reference `{brainstorming_session_output_file}` instead of the full path pattern.

View File

@ -81,60 +81,6 @@ async function createTestBmadFixture() {
return fixtureDir; return fixtureDir;
} }
async function createSkillCollisionFixture() {
const fixtureRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'bmad-skill-collision-'));
const fixtureDir = path.join(fixtureRoot, '_bmad');
const configDir = path.join(fixtureDir, '_config');
await fs.ensureDir(configDir);
await fs.writeFile(
path.join(configDir, 'agent-manifest.csv'),
[
'name,displayName,title,icon,capabilities,role,identity,communicationStyle,principles,module,path,canonicalId',
'"bmad-master","BMAD Master","","","","","","","","core","_bmad/core/agents/bmad-master.md","bmad-master"',
'',
].join('\n'),
);
await fs.writeFile(
path.join(configDir, 'workflow-manifest.csv'),
[
'name,description,module,path,canonicalId',
'"help","Workflow help","core","_bmad/core/workflows/help/workflow.md","bmad-help"',
'',
].join('\n'),
);
await fs.writeFile(path.join(configDir, 'task-manifest.csv'), 'name,displayName,description,module,path,standalone,canonicalId\n');
await fs.writeFile(path.join(configDir, 'tool-manifest.csv'), 'name,displayName,description,module,path,standalone,canonicalId\n');
await fs.writeFile(
path.join(configDir, 'skill-manifest.csv'),
[
'canonicalId,name,description,module,path,install_to_bmad',
'"bmad-help","bmad-help","Native help skill","core","_bmad/core/tasks/bmad-help/SKILL.md","true"',
'',
].join('\n'),
);
const skillDir = path.join(fixtureDir, 'core', 'tasks', 'bmad-help');
await fs.ensureDir(skillDir);
await fs.writeFile(
path.join(skillDir, 'SKILL.md'),
['---', 'name: bmad-help', 'description: Native help skill', '---', '', 'Use this skill directly.'].join('\n'),
);
const agentDir = path.join(fixtureDir, 'core', 'agents');
await fs.ensureDir(agentDir);
await fs.writeFile(
path.join(agentDir, 'bmad-master.md'),
['---', 'name: BMAD Master', 'description: Master agent', '---', '', '<agent name="BMAD Master" title="Master">', '</agent>'].join(
'\n',
),
);
return { root: fixtureRoot, bmadDir: fixtureDir };
}
/** /**
* Test Suite * Test Suite
*/ */
@ -1824,50 +1770,6 @@ async function runTests() {
console.log(''); console.log('');
// ============================================================
// Test 31: Skill-format installs report unique skill directories
// ============================================================
console.log(`${colors.yellow}Test Suite 31: Skill Count Reporting${colors.reset}\n`);
let collisionFixtureRoot = null;
let collisionProjectDir = null;
try {
clearCache();
const collisionFixture = await createSkillCollisionFixture();
collisionFixtureRoot = collisionFixture.root;
collisionProjectDir = await fs.mkdtemp(path.join(os.tmpdir(), 'bmad-antigravity-test-'));
const ideManager = new IdeManager();
await ideManager.ensureInitialized();
const result = await ideManager.setup('antigravity', collisionProjectDir, collisionFixture.bmadDir, {
silent: true,
selectedModules: ['core'],
});
assert(result.success === true, 'Antigravity setup succeeds with overlapping skill names');
assert(result.detail === '2 agents', 'Installer detail reports agents separately from skills');
assert(result.handlerResult.results.skillDirectories === 2, 'Result exposes unique skill directory count');
assert(result.handlerResult.results.agents === 2, 'Result retains generated agent write count');
assert(result.handlerResult.results.workflows === 1, 'Result retains generated workflow count');
assert(result.handlerResult.results.skills === 1, 'Result retains verbatim skill count');
assert(
await fs.pathExists(path.join(collisionProjectDir, '.agent', 'skills', 'bmad-agent-bmad-master', 'SKILL.md')),
'Agent skill directory is created',
);
assert(
await fs.pathExists(path.join(collisionProjectDir, '.agent', 'skills', 'bmad-help', 'SKILL.md')),
'Overlapping skill directory is created once',
);
} catch (error) {
assert(false, 'Skill-format unique count test succeeds', error.message);
} finally {
if (collisionProjectDir) await fs.remove(collisionProjectDir).catch(() => {});
if (collisionFixtureRoot) await fs.remove(collisionFixtureRoot).catch(() => {});
}
console.log('');
// ============================================================ // ============================================================
// Summary // Summary
// ============================================================ // ============================================================

View File

@ -1153,6 +1153,12 @@ class Installer {
preservedModules: modulesForCsvPreserve, preservedModules: modulesForCsvPreserve,
}); });
addResult(
'Manifests',
'ok',
`${manifestStats.workflows} workflows, ${manifestStats.agents} agents, ${manifestStats.tasks} tasks, ${manifestStats.tools} tools`,
);
// Merge help catalogs // Merge help catalogs
message('Generating help catalog...'); message('Generating help catalog...');
await this.mergeModuleHelpCatalogs(bmadDir); await this.mergeModuleHelpCatalogs(bmadDir);
@ -1373,27 +1379,10 @@ class Installer {
*/ */
async renderInstallSummary(results, context = {}) { async renderInstallSummary(results, context = {}) {
const color = await prompts.getColor(); const color = await prompts.getColor();
const selectedIdes = new Set((context.ides || []).map((ide) => String(ide).toLowerCase()));
// Build step lines with status indicators // Build step lines with status indicators
const lines = []; const lines = [];
for (const r of results) { for (const r of results) {
let stepLabel = null;
if (r.status !== 'ok') {
stepLabel = r.step;
} else if (r.step === 'Core') {
stepLabel = 'BMAD';
} else if (r.step.startsWith('Module: ')) {
stepLabel = r.step;
} else if (selectedIdes.has(String(r.step).toLowerCase())) {
stepLabel = r.step;
}
if (!stepLabel) {
continue;
}
let icon; let icon;
if (r.status === 'ok') { if (r.status === 'ok') {
icon = color.green('\u2713'); icon = color.green('\u2713');
@ -1403,11 +1392,7 @@ class Installer {
icon = color.red('\u2717'); icon = color.red('\u2717');
} }
const detail = r.detail ? color.dim(` (${r.detail})`) : ''; const detail = r.detail ? color.dim(` (${r.detail})`) : '';
lines.push(` ${icon} ${stepLabel}${detail}`); lines.push(` ${icon} ${r.step}${detail}`);
}
if ((context.ides || []).length === 0) {
lines.push(` ${color.green('\u2713')} No IDE selected ${color.dim('(installed in _bmad only)')}`);
} }
// Context and warnings // Context and warnings
@ -1430,10 +1415,8 @@ class Installer {
` Join our Discord: ${color.dim('https://discord.gg/gk8jAdXWmj')}`, ` Join our Discord: ${color.dim('https://discord.gg/gk8jAdXWmj')}`,
` Star us on GitHub: ${color.dim('https://github.com/bmad-code-org/BMAD-METHOD/')}`, ` Star us on GitHub: ${color.dim('https://github.com/bmad-code-org/BMAD-METHOD/')}`,
` Subscribe on YouTube: ${color.dim('https://www.youtube.com/@BMadCode')}`, ` Subscribe on YouTube: ${color.dim('https://www.youtube.com/@BMadCode')}`,
` Invoke the ${color.cyan('bmad-help')} skill in your IDE Agent to get started`,
); );
if (context.ides && context.ides.length > 0) {
lines.push(` Invoke the ${color.cyan('bmad-help')} skill in your IDE Agent to get started`);
}
await prompts.note(lines.join('\n'), 'BMAD is ready to use!'); await prompts.note(lines.join('\n'), 'BMAD is ready to use!');
} }

View File

@ -349,6 +349,7 @@ class BaseIdeSetup {
} else if (entry.isFile() && entry.name === 'workflow.md') { } else if (entry.isFile() && entry.name === 'workflow.md') {
// Read workflow.md frontmatter to get name and standalone property // Read workflow.md frontmatter to get name and standalone property
try { try {
const yaml = require('yaml');
const content = await fs.readFile(fullPath, 'utf8'); const content = await fs.readFile(fullPath, 'utf8');
const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/); const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
if (!frontmatterMatch) continue; if (!frontmatterMatch) continue;

View File

@ -129,7 +129,6 @@ class ConfigDrivenIdeSetup extends BaseIdeSetup {
const selectedModules = options.selectedModules || []; const selectedModules = options.selectedModules || [];
const results = { agents: 0, workflows: 0, tasks: 0, tools: 0, skills: 0 }; const results = { agents: 0, workflows: 0, tasks: 0, tools: 0, skills: 0 };
this.skillWriteTracker = config.skill_format ? new Set() : null;
// Install standard artifacts (agents, workflows, tasks, tools) // Install standard artifacts (agents, workflows, tasks, tools)
if (!skipStandardArtifacts) { if (!skipStandardArtifacts) {
@ -160,11 +159,9 @@ class ConfigDrivenIdeSetup extends BaseIdeSetup {
// Install verbatim skills (type: skill) // Install verbatim skills (type: skill)
if (config.skill_format) { if (config.skill_format) {
results.skills = await this.installVerbatimSkills(projectDir, bmadDir, targetPath, config); results.skills = await this.installVerbatimSkills(projectDir, bmadDir, targetPath, config);
results.skillDirectories = this.skillWriteTracker ? this.skillWriteTracker.size : 0;
} }
await this.printSummary(results, target_dir, options); await this.printSummary(results, target_dir, options);
this.skillWriteTracker = null;
return { success: true, results }; return { success: true, results };
} }
@ -498,7 +495,6 @@ LOAD and execute from: {project-root}/{{bmadFolderName}}/{{path}}
// Create skill directory // Create skill directory
const skillDir = path.join(targetPath, skillName); const skillDir = path.join(targetPath, skillName);
await this.ensureDir(skillDir); await this.ensureDir(skillDir);
this.skillWriteTracker?.add(skillName);
// Transform content: rewrite frontmatter for skills format // Transform content: rewrite frontmatter for skills format
const skillContent = this.transformToSkillFormat(content, skillName); const skillContent = this.transformToSkillFormat(content, skillName);
@ -671,7 +667,6 @@ LOAD and execute from: {project-root}/{{bmadFolderName}}/{{path}}
const skillDir = path.join(targetPath, canonicalId); const skillDir = path.join(targetPath, canonicalId);
await fs.remove(skillDir); await fs.remove(skillDir);
await fs.ensureDir(skillDir); await fs.ensureDir(skillDir);
this.skillWriteTracker?.add(canonicalId);
// Copy all skill files, filtering OS/editor artifacts recursively // Copy all skill files, filtering OS/editor artifacts recursively
const skipPatterns = new Set(['.DS_Store', 'Thumbs.db', 'desktop.ini']); const skipPatterns = new Set(['.DS_Store', 'Thumbs.db', 'desktop.ini']);
@ -712,11 +707,11 @@ LOAD and execute from: {project-root}/{{bmadFolderName}}/{{path}}
async printSummary(results, targetDir, options = {}) { async printSummary(results, targetDir, options = {}) {
if (options.silent) return; if (options.silent) return;
const parts = []; const parts = [];
const totalDirs =
results.skillDirectories || (results.workflows || 0) + (results.tasks || 0) + (results.tools || 0) + (results.skills || 0);
const skillCount = totalDirs - (results.agents || 0);
if (skillCount > 0) parts.push(`${skillCount} skills`);
if (results.agents > 0) parts.push(`${results.agents} agents`); if (results.agents > 0) parts.push(`${results.agents} agents`);
if (results.workflows > 0) parts.push(`${results.workflows} workflows`);
if (results.tasks > 0) parts.push(`${results.tasks} tasks`);
if (results.tools > 0) parts.push(`${results.tools} tools`);
if (results.skills > 0) parts.push(`${results.skills} skills`);
await prompts.log.success(`${this.name} configured: ${parts.join(', ')}${targetDir}`); await prompts.log.success(`${this.name} configured: ${parts.join(', ')}${targetDir}`);
} }

View File

@ -162,10 +162,10 @@ class IdeManager {
// Config-driven handlers return { success, results: { agents, workflows, tasks, tools } } // Config-driven handlers return { success, results: { agents, workflows, tasks, tools } }
const r = handlerResult.results; const r = handlerResult.results;
const parts = []; const parts = [];
const totalDirs = r.skillDirectories || (r.workflows || 0) + (r.tasks || 0) + (r.tools || 0) + (r.skills || 0);
const skillCount = totalDirs - (r.agents || 0);
if (skillCount > 0) parts.push(`${skillCount} skills`);
if (r.agents > 0) parts.push(`${r.agents} agents`); if (r.agents > 0) parts.push(`${r.agents} agents`);
if (r.workflows > 0) parts.push(`${r.workflows} workflows`);
if (r.tasks > 0) parts.push(`${r.tasks} tasks`);
if (r.tools > 0) parts.push(`${r.tools} tools`);
detail = parts.join(', '); detail = parts.join(', ');
} }
// Propagate handler's success status (default true for backward compat) // Propagate handler's success status (default true for backward compat)

View File

@ -157,7 +157,7 @@ function buildMenuXml(menuItems) {
} }
} }
xml += ` <item cmd="PM or fuzzy match on party-mode" exec="skill:bmad-party-mode">[PM] Start Party Mode</item>\n`; xml += ` <item cmd="PM or fuzzy match on party-mode" exec="{project-root}/_bmad/core/workflows/bmad-party-mode/workflow.md">[PM] Start Party Mode</item>\n`;
xml += ` <item cmd="DA or fuzzy match on exit, leave, goodbye or dismiss agent">[DA] Dismiss Agent</item>\n`; xml += ` <item cmd="DA or fuzzy match on exit, leave, goodbye or dismiss agent">[DA] Dismiss Agent</item>\n`;
xml += ' </menu>\n'; xml += ' </menu>\n';