mirror of
https://github.com/bmadcode/BMAD-METHOD.git
synced 2025-12-17 17:55:34 +00:00
installer fixes
This commit is contained in:
parent
aa1cf76f88
commit
0b9290789e
@ -1,7 +1,7 @@
|
||||
---
|
||||
name: create-prd
|
||||
description: Creates a comprehensive PRDs through collaborative step-by-step discovery between two product managers working as peers.
|
||||
main_config: `{project-root}/{bmad_folder}/bmm/config.yaml`
|
||||
main_config: '{project-root}/{bmad_folder}/bmm/config.yaml'
|
||||
web_bundle: true
|
||||
---
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ const fs = require('fs-extra');
|
||||
const { BaseIdeSetup } = require('./_base-ide');
|
||||
const chalk = require('chalk');
|
||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||
|
||||
/**
|
||||
* Auggie CLI setup handler
|
||||
@ -33,10 +34,23 @@ class AuggieSetup extends BaseIdeSetup {
|
||||
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
|
||||
const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
|
||||
|
||||
// Get tasks, tools, and workflows (standalone only)
|
||||
// Get tasks, tools, and workflows (ALL workflows now generate commands)
|
||||
const tasks = await this.getTasks(bmadDir, true);
|
||||
const tools = await this.getTools(bmadDir, true);
|
||||
const workflows = await this.getWorkflows(bmadDir, true);
|
||||
|
||||
// Get ALL workflows using the new workflow command generator
|
||||
const workflowGenerator = new WorkflowCommandGenerator(this.bmadFolderName);
|
||||
const { artifacts: workflowArtifacts, counts: workflowCounts } = await workflowGenerator.collectWorkflowArtifacts(bmadDir);
|
||||
|
||||
// Convert workflow artifacts to expected format
|
||||
const workflows = workflowArtifacts
|
||||
.filter((artifact) => artifact.type === 'workflow-command')
|
||||
.map((artifact) => ({
|
||||
module: artifact.module,
|
||||
name: path.basename(artifact.relativePath, '.md'),
|
||||
path: artifact.sourcePath,
|
||||
content: artifact.content,
|
||||
}));
|
||||
|
||||
const bmadCommandsDir = path.join(location, 'bmad');
|
||||
const agentsDir = path.join(bmadCommandsDir, 'agents');
|
||||
@ -73,13 +87,11 @@ class AuggieSetup extends BaseIdeSetup {
|
||||
await this.writeFile(targetPath, commandContent);
|
||||
}
|
||||
|
||||
// Install workflows
|
||||
// Install workflows (already generated commands)
|
||||
for (const workflow of workflows) {
|
||||
const content = await this.readFile(workflow.path);
|
||||
const commandContent = this.createWorkflowCommand(workflow, content);
|
||||
|
||||
// Use the pre-generated workflow command content
|
||||
const targetPath = path.join(workflowsDir, `${workflow.module}-${workflow.name}.md`);
|
||||
await this.writeFile(targetPath, commandContent);
|
||||
await this.writeFile(targetPath, workflow.content);
|
||||
}
|
||||
|
||||
const totalInstalled = agentArtifacts.length + tasks.length + tools.length + workflows.length;
|
||||
|
||||
@ -3,6 +3,7 @@ const fs = require('fs-extra');
|
||||
const { BaseIdeSetup } = require('./_base-ide');
|
||||
const chalk = require('chalk');
|
||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||
|
||||
/**
|
||||
* Crush IDE setup handler
|
||||
@ -34,10 +35,23 @@ class CrushSetup extends BaseIdeSetup {
|
||||
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
|
||||
const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
|
||||
|
||||
// Get tasks, tools, and workflows (standalone only)
|
||||
// Get tasks, tools, and workflows (ALL workflows now generate commands)
|
||||
const tasks = await this.getTasks(bmadDir, true);
|
||||
const tools = await this.getTools(bmadDir, true);
|
||||
const workflows = await this.getWorkflows(bmadDir, true);
|
||||
|
||||
// Get ALL workflows using the new workflow command generator
|
||||
const workflowGenerator = new WorkflowCommandGenerator(this.bmadFolderName);
|
||||
const { artifacts: workflowArtifacts, counts: workflowCounts } = await workflowGenerator.collectWorkflowArtifacts(bmadDir);
|
||||
|
||||
// Convert workflow artifacts to expected format for organizeByModule
|
||||
const workflows = workflowArtifacts
|
||||
.filter((artifact) => artifact.type === 'workflow-command')
|
||||
.map((artifact) => ({
|
||||
module: artifact.module,
|
||||
name: path.basename(artifact.relativePath, '.md'),
|
||||
path: artifact.sourcePath,
|
||||
content: artifact.content,
|
||||
}));
|
||||
|
||||
// Organize by module
|
||||
const agentCount = await this.organizeByModule(commandsDir, agentArtifacts, tasks, tools, workflows, projectDir);
|
||||
@ -113,13 +127,12 @@ class CrushSetup extends BaseIdeSetup {
|
||||
toolCount++;
|
||||
}
|
||||
|
||||
// Copy module-specific workflows
|
||||
// Copy module-specific workflow commands (already generated)
|
||||
const moduleWorkflows = workflows.filter((w) => w.module === module);
|
||||
for (const workflow of moduleWorkflows) {
|
||||
const content = await this.readFile(workflow.path);
|
||||
const commandContent = this.createWorkflowCommand(workflow, content);
|
||||
// Use the pre-generated workflow command content
|
||||
const targetPath = path.join(moduleWorkflowsDir, `${workflow.name}.md`);
|
||||
await this.writeFile(targetPath, commandContent);
|
||||
await this.writeFile(targetPath, workflow.content);
|
||||
workflowCount++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ const path = require('node:path');
|
||||
const { BaseIdeSetup } = require('./_base-ide');
|
||||
const chalk = require('chalk');
|
||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||
|
||||
/**
|
||||
* Cursor IDE setup handler
|
||||
@ -53,10 +54,22 @@ class CursorSetup extends BaseIdeSetup {
|
||||
// Convert artifacts to agent format for index creation
|
||||
const agents = agentArtifacts.map((a) => ({ module: a.module, name: a.name }));
|
||||
|
||||
// Get tasks, tools, and workflows (standalone only)
|
||||
// Get tasks, tools, and workflows (ALL workflows now generate commands)
|
||||
const tasks = await this.getTasks(bmadDir, true);
|
||||
const tools = await this.getTools(bmadDir, true);
|
||||
const workflows = await this.getWorkflows(bmadDir, true);
|
||||
|
||||
// Get ALL workflows using the new workflow command generator
|
||||
const workflowGenerator = new WorkflowCommandGenerator(this.bmadFolderName);
|
||||
const { artifacts: workflowArtifacts, counts: workflowCounts } = await workflowGenerator.collectWorkflowArtifacts(bmadDir);
|
||||
|
||||
// Convert artifacts to workflow objects for directory creation
|
||||
const workflows = workflowArtifacts
|
||||
.filter((artifact) => artifact.type === 'workflow-command')
|
||||
.map((artifact) => ({
|
||||
module: artifact.module,
|
||||
name: path.basename(artifact.relativePath, '.md'),
|
||||
path: artifact.sourcePath,
|
||||
}));
|
||||
|
||||
// Create directories for each module
|
||||
const modules = new Set();
|
||||
@ -113,19 +126,22 @@ class CursorSetup extends BaseIdeSetup {
|
||||
toolCount++;
|
||||
}
|
||||
|
||||
// Process and copy workflows
|
||||
// Process and copy workflow commands (generated, not raw workflows)
|
||||
let workflowCount = 0;
|
||||
for (const workflow of workflows) {
|
||||
const content = await this.readAndProcess(workflow.path, {
|
||||
module: workflow.module,
|
||||
name: workflow.name,
|
||||
for (const artifact of workflowArtifacts) {
|
||||
if (artifact.type === 'workflow-command') {
|
||||
// Add MDC metadata header to workflow command
|
||||
const content = this.wrapLauncherWithMDC(artifact.content, {
|
||||
module: artifact.module,
|
||||
name: path.basename(artifact.relativePath, '.md'),
|
||||
});
|
||||
|
||||
const targetPath = path.join(bmadRulesDir, workflow.module, 'workflows', `${workflow.name}.mdc`);
|
||||
const targetPath = path.join(bmadRulesDir, artifact.module, 'workflows', `${path.basename(artifact.relativePath, '.md')}.mdc`);
|
||||
|
||||
await this.writeFile(targetPath, content);
|
||||
workflowCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Create BMAD index file (but NOT .cursorrules - user manages that)
|
||||
await this.createBMADIndex(bmadRulesDir, agents, tasks, tools, workflows, modules);
|
||||
|
||||
@ -4,6 +4,7 @@ const yaml = require('js-yaml');
|
||||
const { BaseIdeSetup } = require('./_base-ide');
|
||||
const chalk = require('chalk');
|
||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||
|
||||
/**
|
||||
* Gemini CLI setup handler
|
||||
@ -68,9 +69,13 @@ class GeminiSetup extends BaseIdeSetup {
|
||||
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
|
||||
const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
|
||||
|
||||
// Get tasks
|
||||
// Get tasks and workflows (ALL workflows now generate commands)
|
||||
const tasks = await this.getTasks(bmadDir);
|
||||
|
||||
// Get ALL workflows using the new workflow command generator
|
||||
const workflowGenerator = new WorkflowCommandGenerator(this.bmadFolderName);
|
||||
const { artifacts: workflowArtifacts, counts: workflowCounts } = await workflowGenerator.collectWorkflowArtifacts(bmadDir);
|
||||
|
||||
// Install agents as TOML files with bmad- prefix (flat structure)
|
||||
let agentCount = 0;
|
||||
for (const artifact of agentArtifacts) {
|
||||
@ -98,17 +103,37 @@ class GeminiSetup extends BaseIdeSetup {
|
||||
console.log(chalk.green(` ✓ Added task: /bmad:tasks:${task.module}:${task.name}`));
|
||||
}
|
||||
|
||||
// Install workflows as TOML files with bmad- prefix (flat structure)
|
||||
let workflowCount = 0;
|
||||
for (const artifact of workflowArtifacts) {
|
||||
if (artifact.type === 'workflow-command') {
|
||||
// Create TOML wrapper around workflow command content
|
||||
const tomlContent = await this.createWorkflowToml(artifact);
|
||||
|
||||
// Flat structure: bmad-workflow-{module}-{name}.toml
|
||||
const workflowName = path.basename(artifact.relativePath, '.md');
|
||||
const tomlPath = path.join(commandsDir, `bmad-workflow-${artifact.module}-${workflowName}.toml`);
|
||||
await this.writeFile(tomlPath, tomlContent);
|
||||
workflowCount++;
|
||||
|
||||
console.log(chalk.green(` ✓ Added workflow: /bmad:workflows:${artifact.module}:${workflowName}`));
|
||||
}
|
||||
}
|
||||
|
||||
console.log(chalk.green(`✓ ${this.name} configured:`));
|
||||
console.log(chalk.dim(` - ${agentCount} agents configured`));
|
||||
console.log(chalk.dim(` - ${taskCount} tasks configured`));
|
||||
console.log(chalk.dim(` - ${workflowCount} workflows configured`));
|
||||
console.log(chalk.dim(` - Commands directory: ${path.relative(projectDir, commandsDir)}`));
|
||||
console.log(chalk.dim(` - Agent activation: /bmad:agents:{agent-name}`));
|
||||
console.log(chalk.dim(` - Task activation: /bmad:tasks:{task-name}`));
|
||||
console.log(chalk.dim(` - Workflow activation: /bmad:workflows:{workflow-name}`));
|
||||
|
||||
return {
|
||||
success: true,
|
||||
agents: agentCount,
|
||||
tasks: taskCount,
|
||||
workflows: workflowCount,
|
||||
};
|
||||
}
|
||||
|
||||
@ -179,6 +204,27 @@ ${contentWithoutFrontmatter}
|
||||
return tomlContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create workflow TOML content from artifact
|
||||
*/
|
||||
async createWorkflowToml(artifact) {
|
||||
// Extract description from artifact content
|
||||
const descriptionMatch = artifact.content.match(/description:\s*"([^"]+)"/);
|
||||
const description = descriptionMatch
|
||||
? descriptionMatch[1]
|
||||
: `BMAD ${artifact.module.toUpperCase()} Workflow: ${path.basename(artifact.relativePath, '.md')}`;
|
||||
|
||||
// Strip frontmatter from command content
|
||||
const frontmatterRegex = /^---\s*\n[\s\S]*?\n---\s*\n/;
|
||||
const contentWithoutFrontmatter = artifact.content.replace(frontmatterRegex, '').trim();
|
||||
|
||||
return `description = "${description}"
|
||||
prompt = """
|
||||
${contentWithoutFrontmatter}
|
||||
"""
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup Gemini configuration - surgically remove only BMAD files
|
||||
*/
|
||||
|
||||
@ -3,6 +3,7 @@ const fs = require('fs-extra');
|
||||
const { BaseIdeSetup } = require('./_base-ide');
|
||||
const chalk = require('chalk');
|
||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||
|
||||
/**
|
||||
* iFlow CLI setup handler
|
||||
@ -29,9 +30,11 @@ class IFlowSetup extends BaseIdeSetup {
|
||||
const commandsDir = path.join(iflowDir, this.commandsDir, 'bmad');
|
||||
const agentsDir = path.join(commandsDir, 'agents');
|
||||
const tasksDir = path.join(commandsDir, 'tasks');
|
||||
const workflowsDir = path.join(commandsDir, 'workflows');
|
||||
|
||||
await this.ensureDir(agentsDir);
|
||||
await this.ensureDir(tasksDir);
|
||||
await this.ensureDir(workflowsDir);
|
||||
|
||||
// Generate agent launchers
|
||||
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
|
||||
@ -47,9 +50,13 @@ class IFlowSetup extends BaseIdeSetup {
|
||||
agentCount++;
|
||||
}
|
||||
|
||||
// Get tasks
|
||||
// Get tasks and workflows (ALL workflows now generate commands)
|
||||
const tasks = await this.getTasks(bmadDir);
|
||||
|
||||
// Get ALL workflows using the new workflow command generator
|
||||
const workflowGenerator = new WorkflowCommandGenerator(this.bmadFolderName);
|
||||
const { artifacts: workflowArtifacts, counts: workflowCounts } = await workflowGenerator.collectWorkflowArtifacts(bmadDir);
|
||||
|
||||
// Setup tasks as commands
|
||||
let taskCount = 0;
|
||||
for (const task of tasks) {
|
||||
@ -61,15 +68,27 @@ class IFlowSetup extends BaseIdeSetup {
|
||||
taskCount++;
|
||||
}
|
||||
|
||||
// Setup workflows as commands (already generated)
|
||||
let workflowCount = 0;
|
||||
for (const artifact of workflowArtifacts) {
|
||||
if (artifact.type === 'workflow-command') {
|
||||
const targetPath = path.join(workflowsDir, `${artifact.module}-${path.basename(artifact.relativePath, '.md')}.md`);
|
||||
await this.writeFile(targetPath, artifact.content);
|
||||
workflowCount++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(chalk.green(`✓ ${this.name} configured:`));
|
||||
console.log(chalk.dim(` - ${agentCount} agent commands created`));
|
||||
console.log(chalk.dim(` - ${taskCount} task commands created`));
|
||||
console.log(chalk.dim(` - ${workflowCount} workflow commands created`));
|
||||
console.log(chalk.dim(` - Commands directory: ${path.relative(projectDir, commandsDir)}`));
|
||||
|
||||
return {
|
||||
success: true,
|
||||
agents: agentCount,
|
||||
tasks: taskCount,
|
||||
workflows: workflowCount,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -156,16 +156,41 @@ class KiroCliSetup extends BaseIdeSetup {
|
||||
return;
|
||||
}
|
||||
|
||||
// Extract agent name from ID path (e.g., "{bmad_folder}/bmm/agents/analyst.md" -> "analyst")
|
||||
// Extract module from file path
|
||||
const normalizedPath = path.normalize(agentFile);
|
||||
const pathParts = normalizedPath.split(path.sep);
|
||||
const basename = path.basename(agentFile, '.agent.yaml');
|
||||
|
||||
// Find the module name from path
|
||||
let moduleName = 'unknown';
|
||||
if (pathParts.includes('src')) {
|
||||
const srcIndex = pathParts.indexOf('src');
|
||||
if (srcIndex + 3 < pathParts.length) {
|
||||
const folderAfterSrc = pathParts[srcIndex + 1];
|
||||
// Handle both src/core/agents and src/modules/[module]/agents patterns
|
||||
if (folderAfterSrc === 'core') {
|
||||
moduleName = 'core';
|
||||
} else if (folderAfterSrc === 'modules') {
|
||||
moduleName = pathParts[srcIndex + 2]; // The actual module name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Extract the agent name from the ID path in YAML if available
|
||||
let agentBaseName = basename;
|
||||
if (agentData.agent && agentData.agent.metadata && agentData.agent.metadata.id) {
|
||||
const idPath = agentData.agent.metadata.id;
|
||||
const basename = path.basename(idPath, '.md');
|
||||
const agentName = basename.startsWith('bmad-') ? basename : `bmad-${basename}`;
|
||||
agentBaseName = path.basename(idPath, '.md');
|
||||
}
|
||||
|
||||
const agentName = `bmad-${moduleName}-${agentBaseName}`;
|
||||
const sanitizedAgentName = this.sanitizeAgentName(agentName);
|
||||
|
||||
// Create JSON definition
|
||||
await this.createAgentDefinitionFromYaml(agentsDir, agentName, agentData);
|
||||
await this.createAgentDefinitionFromYaml(agentsDir, sanitizedAgentName, agentData);
|
||||
|
||||
// Create prompt file
|
||||
await this.createAgentPromptFromYaml(agentsDir, agentName, agentData, projectDir);
|
||||
await this.createAgentPromptFromYaml(agentsDir, sanitizedAgentName, agentData, projectDir);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -47,7 +47,7 @@ class OpenCodeSetup extends BaseIdeSetup {
|
||||
agentCount++;
|
||||
}
|
||||
|
||||
// Install workflow commands with flat naming: bmad-workflow-{module}-{name}.md
|
||||
// Install workflow commands with flat naming: bmad-{module}-{workflow-name}
|
||||
const workflowGenerator = new WorkflowCommandGenerator(this.bmadFolderName);
|
||||
const { artifacts: workflowArtifacts, counts: workflowCounts } = await workflowGenerator.collectWorkflowArtifacts(bmadDir);
|
||||
|
||||
@ -55,10 +55,10 @@ class OpenCodeSetup extends BaseIdeSetup {
|
||||
for (const artifact of workflowArtifacts) {
|
||||
if (artifact.type === 'workflow-command') {
|
||||
const commandContent = artifact.content;
|
||||
// Flat structure: bmad-workflow-{module}-{name}.md
|
||||
// Flat structure: bmad-{module}-{workflow-name}.md
|
||||
// artifact.relativePath is like: bmm/workflows/plan-project.md
|
||||
const workflowName = path.basename(artifact.relativePath, '.md');
|
||||
const targetPath = path.join(commandsBaseDir, `bmad-workflow-${artifact.module}-${workflowName}.md`);
|
||||
const targetPath = path.join(commandsBaseDir, `bmad-${artifact.module}-${workflowName}.md`);
|
||||
await this.writeFile(targetPath, commandContent);
|
||||
workflowCommandCount++;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user