feat(workflows): add VS Code workflow prompt recommendations
- Add workflow-prompt-generator.js for dynamic prompt generation from path files - Add workflow-prompts-config.js for static workflow prompt configuration - Update github-copilot.js to use WorkflowPromptGenerator - Include model frontmatter and new-chat notes in prompts - Deep-merge prompt recommendations to preserve existing settings
This commit is contained in:
parent
73135bee8e
commit
d0e80e7508
|
|
@ -2,6 +2,7 @@ const path = require('node:path');
|
||||||
const { BaseIdeSetup } = require('./_base-ide');
|
const { BaseIdeSetup } = require('./_base-ide');
|
||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||||
|
const { WorkflowPromptGenerator } = require('./shared/workflow-prompt-generator');
|
||||||
const prompts = require('../../../lib/prompts');
|
const prompts = require('../../../lib/prompts');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -13,6 +14,7 @@ class GitHubCopilotSetup extends BaseIdeSetup {
|
||||||
super('github-copilot', 'GitHub Copilot', true); // preferred IDE
|
super('github-copilot', 'GitHub Copilot', true); // preferred IDE
|
||||||
this.configDir = '.github';
|
this.configDir = '.github';
|
||||||
this.agentsDir = 'agents';
|
this.agentsDir = 'agents';
|
||||||
|
this.promptsDir = 'prompts';
|
||||||
this.vscodeDir = '.vscode';
|
this.vscodeDir = '.vscode';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,14 +92,12 @@ class GitHubCopilotSetup extends BaseIdeSetup {
|
||||||
async setup(projectDir, bmadDir, options = {}) {
|
async setup(projectDir, bmadDir, options = {}) {
|
||||||
console.log(chalk.cyan(`Setting up ${this.name}...`));
|
console.log(chalk.cyan(`Setting up ${this.name}...`));
|
||||||
|
|
||||||
// Configure VS Code settings using pre-collected config if available
|
|
||||||
const config = options.preCollectedConfig || {};
|
|
||||||
await this.configureVsCodeSettings(projectDir, { ...options, ...config });
|
|
||||||
|
|
||||||
// Create .github/agents directory
|
// Create .github/agents directory
|
||||||
const githubDir = path.join(projectDir, this.configDir);
|
const githubDir = path.join(projectDir, this.configDir);
|
||||||
const agentsDir = path.join(githubDir, this.agentsDir);
|
const agentsDir = path.join(githubDir, this.agentsDir);
|
||||||
|
const promptsDir = path.join(githubDir, this.promptsDir);
|
||||||
await this.ensureDir(agentsDir);
|
await this.ensureDir(agentsDir);
|
||||||
|
await this.ensureDir(promptsDir);
|
||||||
|
|
||||||
// Clean up any existing BMAD files before reinstalling
|
// Clean up any existing BMAD files before reinstalling
|
||||||
await this.cleanup(projectDir);
|
await this.cleanup(projectDir);
|
||||||
|
|
@ -113,22 +113,40 @@ class GitHubCopilotSetup extends BaseIdeSetup {
|
||||||
const agentContent = await this.createAgentContent({ module: artifact.module, name: artifact.name }, content);
|
const agentContent = await this.createAgentContent({ module: artifact.module, name: artifact.name }, content);
|
||||||
|
|
||||||
// Use bmd- prefix: bmd-custom-{module}-{name}.agent.md
|
// Use bmd- prefix: bmd-custom-{module}-{name}.agent.md
|
||||||
const targetPath = path.join(agentsDir, `bmd-custom-${artifact.module}-${artifact.name}.agent.md`);
|
const agentFileName = `bmd-custom-${artifact.module}-${artifact.name}`;
|
||||||
|
const targetPath = path.join(agentsDir, `${agentFileName}.agent.md`);
|
||||||
await this.writeFile(targetPath, agentContent);
|
await this.writeFile(targetPath, agentContent);
|
||||||
agentCount++;
|
agentCount++;
|
||||||
|
|
||||||
console.log(chalk.green(` ✓ Created agent: bmd-custom-${artifact.module}-${artifact.name}`));
|
console.log(chalk.green(` ✓ Created agent: ${agentFileName}`));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate workflow prompts from config (shared logic)
|
||||||
|
// Each prompt includes nextSteps guidance for the agent to suggest next workflows
|
||||||
|
const promptGen = new WorkflowPromptGenerator();
|
||||||
|
const promptRecommendations = await promptGen.generatePromptFiles(promptsDir, options.selectedModules || [], {
|
||||||
|
projectDir,
|
||||||
|
bmadDir,
|
||||||
|
});
|
||||||
|
const promptCount = Object.keys(promptRecommendations).length;
|
||||||
|
|
||||||
|
// Configure VS Code settings using pre-collected config if available
|
||||||
|
const config = options.preCollectedConfig || {};
|
||||||
|
await this.configureVsCodeSettings(projectDir, { ...options, ...config, promptRecommendations });
|
||||||
|
|
||||||
console.log(chalk.green(`✓ ${this.name} configured:`));
|
console.log(chalk.green(`✓ ${this.name} configured:`));
|
||||||
console.log(chalk.dim(` - ${agentCount} agents created`));
|
console.log(chalk.dim(` - ${agentCount} agents created`));
|
||||||
|
console.log(chalk.dim(` - ${promptCount} workflow prompts configured`));
|
||||||
console.log(chalk.dim(` - Agents directory: ${path.relative(projectDir, agentsDir)}`));
|
console.log(chalk.dim(` - Agents directory: ${path.relative(projectDir, agentsDir)}`));
|
||||||
|
console.log(chalk.dim(` - Prompts directory: ${path.relative(projectDir, promptsDir)}`));
|
||||||
console.log(chalk.dim(` - VS Code settings configured`));
|
console.log(chalk.dim(` - VS Code settings configured`));
|
||||||
console.log(chalk.dim('\n Agents available in VS Code Chat view'));
|
console.log(chalk.dim('\n Agents available in VS Code Chat view'));
|
||||||
|
console.log(chalk.dim(' Workflow prompts show as new chat starters'));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
agents: agentCount,
|
agents: agentCount,
|
||||||
|
prompts: promptCount,
|
||||||
settings: true,
|
settings: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -195,9 +213,22 @@ class GitHubCopilotSetup extends BaseIdeSetup {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge settings (existing take precedence)
|
// Add prompt file recommendations for new chat starters
|
||||||
|
if (options.promptRecommendations && Object.keys(options.promptRecommendations).length > 0) {
|
||||||
|
bmadSettings['chat.promptFilesRecommendations'] = options.promptRecommendations;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge settings (existing take precedence, except for prompt recommendations)
|
||||||
const mergedSettings = { ...bmadSettings, ...existingSettings };
|
const mergedSettings = { ...bmadSettings, ...existingSettings };
|
||||||
|
|
||||||
|
// Deep-merge prompt recommendations (new prompts added, existing preserved)
|
||||||
|
if (options.promptRecommendations && Object.keys(options.promptRecommendations).length > 0) {
|
||||||
|
mergedSettings['chat.promptFilesRecommendations'] = {
|
||||||
|
...existingSettings['chat.promptFilesRecommendations'],
|
||||||
|
...options.promptRecommendations,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Write settings
|
// Write settings
|
||||||
await fs.writeFile(settingsPath, JSON.stringify(mergedSettings, null, 2));
|
await fs.writeFile(settingsPath, JSON.stringify(mergedSettings, null, 2));
|
||||||
console.log(chalk.green(' ✓ VS Code settings configured'));
|
console.log(chalk.green(' ✓ VS Code settings configured'));
|
||||||
|
|
@ -303,6 +334,24 @@ ${cleanContent}
|
||||||
console.log(chalk.dim(` Cleaned up ${removed} existing BMAD agents`));
|
console.log(chalk.dim(` Cleaned up ${removed} existing BMAD agents`));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clean up prompts directory
|
||||||
|
const promptsDir = path.join(projectDir, this.configDir, this.promptsDir);
|
||||||
|
if (await fs.pathExists(promptsDir)) {
|
||||||
|
const files = await fs.readdir(promptsDir);
|
||||||
|
let removed = 0;
|
||||||
|
|
||||||
|
for (const file of files) {
|
||||||
|
if (file.startsWith('bmd-') && file.endsWith('.prompt.md')) {
|
||||||
|
await fs.remove(path.join(promptsDir, file));
|
||||||
|
removed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removed > 0) {
|
||||||
|
console.log(chalk.dim(` Cleaned up ${removed} existing BMAD prompt files`));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,297 @@
|
||||||
|
const path = require('node:path');
|
||||||
|
const fs = require('fs-extra');
|
||||||
|
const yaml = require('yaml');
|
||||||
|
const { workflowPromptsConfig } = require('./workflow-prompts-config');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate workflow prompt recommendations for IDE new chat starters
|
||||||
|
* Uses static configuration from workflow-prompts-config.js which mirrors
|
||||||
|
* the workflows documented in quick-start.md
|
||||||
|
*
|
||||||
|
* The implementation-readiness and sprint-planning workflows update
|
||||||
|
* VS Code settings to toggle which prompts are shown based on project phase.
|
||||||
|
*/
|
||||||
|
class WorkflowPromptGenerator {
|
||||||
|
/**
|
||||||
|
* Get workflow prompts for selected modules
|
||||||
|
* @param {Array<string>} selectedModules - Modules to include (e.g., ['bmm', 'bmgd'])
|
||||||
|
* @returns {Array<Object>} Array of workflow prompt configurations
|
||||||
|
*/
|
||||||
|
getWorkflowPrompts(selectedModules = []) {
|
||||||
|
const allPrompts = [];
|
||||||
|
|
||||||
|
// Always include core prompts
|
||||||
|
if (workflowPromptsConfig.core) {
|
||||||
|
allPrompts.push(...workflowPromptsConfig.core);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add prompts for each selected module
|
||||||
|
for (const moduleName of selectedModules) {
|
||||||
|
if (workflowPromptsConfig[moduleName]) {
|
||||||
|
allPrompts.push(...workflowPromptsConfig[moduleName]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return allPrompts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate prompt files for an IDE
|
||||||
|
* @param {string} promptsDir - Directory to write prompt files
|
||||||
|
* @param {Array<string>} selectedModules - Modules to include
|
||||||
|
* @returns {Object} Map of prompt names to true for VS Code settings
|
||||||
|
*/
|
||||||
|
async generatePromptFiles(promptsDir, selectedModules = [], options = {}) {
|
||||||
|
const prompts = this.getWorkflowPrompts(selectedModules);
|
||||||
|
const pathPrompts = await this.getWorkflowPathPrompts({
|
||||||
|
bmadDir: options.bmadDir,
|
||||||
|
projectDir: options.projectDir,
|
||||||
|
selectedModules,
|
||||||
|
});
|
||||||
|
const mergedPrompts = this.mergePrompts(prompts, pathPrompts);
|
||||||
|
const recommendations = {};
|
||||||
|
|
||||||
|
for (const prompt of mergedPrompts) {
|
||||||
|
const frontmatter = ['---', `agent: ${prompt.agent}`, `description: "${prompt.description}"`];
|
||||||
|
|
||||||
|
if (prompt.model) {
|
||||||
|
frontmatter.push(`model: ${prompt.model}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const promptContent = [...frontmatter, '---', '', prompt.prompt, ''].join('\n');
|
||||||
|
|
||||||
|
const promptFilePath = path.join(promptsDir, `bmd-${prompt.name}.prompt.md`);
|
||||||
|
await fs.writeFile(promptFilePath, promptContent);
|
||||||
|
recommendations[`bmd-${prompt.name}`] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return recommendations;
|
||||||
|
}
|
||||||
|
|
||||||
|
mergePrompts(staticPrompts, dynamicPrompts) {
|
||||||
|
const merged = [];
|
||||||
|
const seen = new Set();
|
||||||
|
|
||||||
|
for (const prompt of [...staticPrompts, ...dynamicPrompts]) {
|
||||||
|
if (seen.has(prompt.name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
seen.add(prompt.name);
|
||||||
|
merged.push(prompt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return merged;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getWorkflowPathPrompts({ bmadDir, projectDir, selectedModules = [] }) {
|
||||||
|
if (!bmadDir) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const prompts = [];
|
||||||
|
const promptKeys = new Map();
|
||||||
|
|
||||||
|
for (const moduleName of selectedModules) {
|
||||||
|
const pathFilesDir = await this.resolvePathFilesDir({ moduleName, bmadDir, projectDir });
|
||||||
|
if (!pathFilesDir) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let pathFiles = [];
|
||||||
|
try {
|
||||||
|
pathFiles = await fs.readdir(pathFilesDir);
|
||||||
|
} catch {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const yamlFiles = pathFiles.filter((file) => file.endsWith('.yaml') || file.endsWith('.yml'));
|
||||||
|
|
||||||
|
for (const file of yamlFiles) {
|
||||||
|
const filePath = path.join(pathFilesDir, file);
|
||||||
|
let pathData;
|
||||||
|
|
||||||
|
try {
|
||||||
|
pathData = yaml.parse(await fs.readFile(filePath, 'utf8'));
|
||||||
|
} catch {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const phases = Array.isArray(pathData?.phases) ? pathData.phases : [];
|
||||||
|
let lastAgent = null;
|
||||||
|
|
||||||
|
for (const phase of phases) {
|
||||||
|
const phaseName = phase?.name || '';
|
||||||
|
const workflows = Array.isArray(phase?.workflows) ? phase.workflows : [];
|
||||||
|
|
||||||
|
for (const workflow of workflows) {
|
||||||
|
const agentKey = workflow?.agent || '';
|
||||||
|
const command = workflow?.command || '';
|
||||||
|
const workflowId = workflow?.id || '';
|
||||||
|
|
||||||
|
if (!command && !workflowId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const promptName = this.buildPromptName({ moduleName, workflowId, command });
|
||||||
|
const prompt = this.buildPromptText({ moduleName, workflowId, command });
|
||||||
|
const agent = this.buildAgentName({ moduleName, agentKey });
|
||||||
|
const requiresNewChat = !!lastAgent && !!agentKey && agentKey !== lastAgent;
|
||||||
|
const description = this.buildPromptDescription({
|
||||||
|
workflow,
|
||||||
|
promptName,
|
||||||
|
requiresNewChat,
|
||||||
|
});
|
||||||
|
const model = this.resolveModel({ phaseName, workflow, agentKey });
|
||||||
|
|
||||||
|
lastAgent = agentKey || lastAgent;
|
||||||
|
|
||||||
|
const promptKey = `${moduleName}:${promptName}`;
|
||||||
|
const existing = promptKeys.get(promptKey);
|
||||||
|
|
||||||
|
if (!existing) {
|
||||||
|
const promptEntry = {
|
||||||
|
name: promptName,
|
||||||
|
agent,
|
||||||
|
description,
|
||||||
|
model,
|
||||||
|
prompt,
|
||||||
|
};
|
||||||
|
|
||||||
|
promptKeys.set(promptKey, promptEntry);
|
||||||
|
prompts.push(promptEntry);
|
||||||
|
} else if (requiresNewChat && !existing.description.includes('Ctrl+Shift+Enter')) {
|
||||||
|
existing.description = this.appendNewChatHint(existing.description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return prompts;
|
||||||
|
}
|
||||||
|
|
||||||
|
async resolvePathFilesDir({ moduleName, bmadDir, projectDir }) {
|
||||||
|
const workflowStatusPath = path.join(bmadDir, moduleName, 'workflows', 'workflow-status', 'workflow.yaml');
|
||||||
|
|
||||||
|
if (!(await fs.pathExists(workflowStatusPath))) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let workflowStatus;
|
||||||
|
try {
|
||||||
|
workflowStatus = yaml.parse(await fs.readFile(workflowStatusPath, 'utf8'));
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pathFilesRaw = workflowStatus?.path_files;
|
||||||
|
if (!pathFilesRaw || typeof pathFilesRaw !== 'string') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const workflowDir = path.dirname(workflowStatusPath).replaceAll('\\', '/');
|
||||||
|
let resolved = pathFilesRaw.replace('{installed_path}', workflowDir);
|
||||||
|
|
||||||
|
if (projectDir) {
|
||||||
|
const normalizedProjectDir = projectDir.replaceAll('\\', '/');
|
||||||
|
resolved = resolved.replace('{project-root}', normalizedProjectDir);
|
||||||
|
|
||||||
|
const relativeBmadDir = path.relative(projectDir, bmadDir).replaceAll('\\', '/');
|
||||||
|
if (relativeBmadDir && relativeBmadDir !== '_bmad') {
|
||||||
|
resolved = resolved.replace('/_bmad/', `/${relativeBmadDir}/`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resolved = resolved.replaceAll('\\', '/');
|
||||||
|
|
||||||
|
return path.resolve(resolved);
|
||||||
|
}
|
||||||
|
|
||||||
|
buildPromptName({ moduleName, workflowId, command }) {
|
||||||
|
let baseName = workflowId || command || 'workflow';
|
||||||
|
|
||||||
|
if (command && command.startsWith('/')) {
|
||||||
|
baseName = command.split(':').pop() || baseName;
|
||||||
|
} else if (command) {
|
||||||
|
baseName = command;
|
||||||
|
}
|
||||||
|
|
||||||
|
baseName = baseName.replace(/^\/+/, '');
|
||||||
|
|
||||||
|
return `${moduleName}-${baseName}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
buildPromptText({ moduleName, workflowId, command }) {
|
||||||
|
if (command) {
|
||||||
|
if (command.startsWith('/')) {
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `/bmad:${moduleName}:workflows:${command}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (workflowId) {
|
||||||
|
return `/bmad:${moduleName}:workflows:${workflowId}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return '*workflow-status';
|
||||||
|
}
|
||||||
|
|
||||||
|
buildAgentName({ moduleName, agentKey }) {
|
||||||
|
if (!agentKey) {
|
||||||
|
return `bmd-custom-${moduleName}-pm`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `bmd-custom-${moduleName}-${agentKey}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
buildPromptDescription({ workflow, promptName, requiresNewChat }) {
|
||||||
|
const title = this.toTitle(promptName.replace(/^[^-]+-/, ''));
|
||||||
|
const detail = workflow?.note || workflow?.output || workflow?.description || '';
|
||||||
|
const baseDescription = detail ? `${title} — ${detail}` : title;
|
||||||
|
|
||||||
|
return requiresNewChat ? this.appendNewChatHint(baseDescription) : baseDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
appendNewChatHint(description) {
|
||||||
|
return `${description} (open a new chat with Ctrl+Shift+Enter)`;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolveModel({ phaseName, workflow, agentKey }) {
|
||||||
|
const phase = (phaseName || '').toLowerCase();
|
||||||
|
const id = (workflow?.id || '').toLowerCase();
|
||||||
|
const command = (workflow?.command || '').toLowerCase();
|
||||||
|
const agent = (agentKey || '').toLowerCase();
|
||||||
|
|
||||||
|
if (id.includes('code-review') || command.includes('code-review') || agent.endsWith('dev') || agent.includes('game-dev')) {
|
||||||
|
return 'gpt-5.2-codex';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id.includes('dev-story') || command.includes('dev-story') || id.includes('implement') || command.includes('implement')) {
|
||||||
|
return 'gpt-5.2-codex';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id.includes('sprint-planning') || command.includes('sprint-planning')) {
|
||||||
|
return 'claude-opus-4.5';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
phase.includes('analysis') ||
|
||||||
|
phase.includes('planning') ||
|
||||||
|
phase.includes('solution') ||
|
||||||
|
phase.includes('design') ||
|
||||||
|
phase.includes('technical') ||
|
||||||
|
phase.includes('pre-production')
|
||||||
|
) {
|
||||||
|
return 'claude-opus-4.5';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'gpt-5.2';
|
||||||
|
}
|
||||||
|
|
||||||
|
toTitle(value) {
|
||||||
|
return value.replaceAll(/[-_]/g, ' ').replaceAll(/\b\w/g, (match) => match.toUpperCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { WorkflowPromptGenerator };
|
||||||
|
|
@ -0,0 +1,115 @@
|
||||||
|
/**
|
||||||
|
* Workflow prompt configuration for IDE new chat starters
|
||||||
|
*
|
||||||
|
* This configuration defines the workflow prompts that appear as suggestions
|
||||||
|
* when starting a new chat in VS Code (via chat.promptFilesRecommendations).
|
||||||
|
*
|
||||||
|
* The implementation-readiness and sprint-planning workflows update the
|
||||||
|
* VS Code settings to toggle which prompts are shown based on project phase.
|
||||||
|
*
|
||||||
|
* Reference: docs/modules/bmm-bmad-method/quick-start.md
|
||||||
|
*/
|
||||||
|
|
||||||
|
const workflowPromptsConfig = {
|
||||||
|
// BMad Method Module (bmm) - Static prompts not covered by path files
|
||||||
|
bmm: [
|
||||||
|
{
|
||||||
|
name: 'workflow-init',
|
||||||
|
agent: 'bmd-custom-bmm-analyst',
|
||||||
|
shortcut: 'WI',
|
||||||
|
description: '[WI] Initialize workflow and choose planning track',
|
||||||
|
model: 'claude-opus-4.5',
|
||||||
|
prompt: '*workflow-init',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'workflow-status',
|
||||||
|
agent: 'bmd-custom-bmm-pm',
|
||||||
|
shortcut: 'WS',
|
||||||
|
description: '[WS] Check current workflow status and next steps (open a new chat with Ctrl+Shift+Enter)',
|
||||||
|
model: 'claude-opus-4.5',
|
||||||
|
prompt: '*workflow-status',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'create-story',
|
||||||
|
agent: 'bmd-custom-bmm-sm',
|
||||||
|
shortcut: 'CS',
|
||||||
|
description: '[CS] Create developer-ready story from epic',
|
||||||
|
model: 'gpt-5.2-codex',
|
||||||
|
prompt: '*create-story',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'dev-story',
|
||||||
|
agent: 'bmd-custom-bmm-dev',
|
||||||
|
shortcut: 'DS',
|
||||||
|
description: '[DS] Implement the current story (open a new chat with Ctrl+Shift+Enter)',
|
||||||
|
model: 'gpt-5.2-codex',
|
||||||
|
prompt: '*dev-story',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'code-review',
|
||||||
|
agent: 'bmd-custom-bmm-dev',
|
||||||
|
shortcut: 'CR',
|
||||||
|
description: '[CR] Perform code review on implementation',
|
||||||
|
model: 'gpt-5.2-codex',
|
||||||
|
prompt: '*code-review',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'retrospective',
|
||||||
|
agent: 'bmd-custom-bmm-sm',
|
||||||
|
shortcut: 'ER',
|
||||||
|
description: '[ER] Run epic retrospective after completion (open a new chat with Ctrl+Shift+Enter)',
|
||||||
|
model: 'claude-opus-4.5',
|
||||||
|
prompt: '*epic-retrospective',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'correct-course',
|
||||||
|
agent: 'bmd-custom-bmm-sm',
|
||||||
|
shortcut: 'CC',
|
||||||
|
description: '[CC] Course correction when things go off track',
|
||||||
|
model: 'claude-opus-4.5',
|
||||||
|
prompt: '*correct-course',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
// BMad Game Development Module (bmgd) - Static prompts not covered by path files
|
||||||
|
bmgd: [
|
||||||
|
{
|
||||||
|
name: 'game-implement',
|
||||||
|
agent: 'bmd-custom-bmgd-game-dev',
|
||||||
|
shortcut: 'GI',
|
||||||
|
description: '[GI] Implement game feature',
|
||||||
|
model: 'gpt-5.2-codex',
|
||||||
|
prompt: '*game-implement',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'game-qa',
|
||||||
|
agent: 'bmd-custom-bmgd-game-qa',
|
||||||
|
shortcut: 'GQ',
|
||||||
|
description: '[GQ] Test and QA game feature (open a new chat with Ctrl+Shift+Enter)',
|
||||||
|
model: 'gpt-5.2',
|
||||||
|
prompt: '*game-qa',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
// Core agents (always available)
|
||||||
|
core: [
|
||||||
|
{
|
||||||
|
name: 'list-tasks',
|
||||||
|
agent: 'bmd-custom-core-bmad-master',
|
||||||
|
shortcut: 'LT',
|
||||||
|
description: '[LT] List available tasks',
|
||||||
|
model: 'gpt-5-mini',
|
||||||
|
prompt: '*list-tasks',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'list-workflows',
|
||||||
|
agent: 'bmd-custom-core-bmad-master',
|
||||||
|
shortcut: 'LW',
|
||||||
|
description: '[LW] List available workflows',
|
||||||
|
model: 'gpt-5-mini',
|
||||||
|
prompt: '*list-workflows',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = { workflowPromptsConfig };
|
||||||
Loading…
Reference in New Issue