mirror of
https://github.com/bmadcode/BMAD-METHOD.git
synced 2025-12-29 16:14:59 +00:00
fix bmb workflow paths
This commit is contained in:
@@ -59,7 +59,7 @@ function buildSimpleActivation(criticalActions = [], menuItems = [], deploymentT
|
||||
|
||||
// Standard steps
|
||||
activation += ` <step n="${stepNum++}">Load persona from this current agent file (already in context)</step>\n`;
|
||||
activation += ` <step n="${stepNum++}">Load and read {project-root}/{bmad_folder}/core/config.yaml to get {user_name}, {communication_language}, {output_folder}</step>\n`;
|
||||
activation += ` <step n="${stepNum++}">Load and read {project-root}/.bmad/core/config.yaml to get {user_name}, {communication_language}, {output_folder}</step>\n`;
|
||||
activation += ` <step n="${stepNum++}">Remember: user's name is {user_name}</step>\n`;
|
||||
|
||||
// Agent-specific steps from critical_actions
|
||||
@@ -119,7 +119,7 @@ function buildSimpleActivation(criticalActions = [], menuItems = [], deploymentT
|
||||
if (usedHandlers.has('workflow')) {
|
||||
activation += ` <handler type="workflow">
|
||||
When menu item has: workflow="path/to/workflow.yaml"
|
||||
1. CRITICAL: Always LOAD {project-root}/{bmad_folder}/core/tasks/workflow.xml
|
||||
1. CRITICAL: Always LOAD {project-root}/.bmad/core/tasks/workflow.xml
|
||||
2. Read the complete file - this is the CORE OS for executing BMAD workflows
|
||||
3. Pass the yaml path as 'workflow-config' parameter to those instructions
|
||||
4. Execute workflow.xml instructions precisely following all steps
|
||||
@@ -150,7 +150,7 @@ function buildSimpleActivation(criticalActions = [], menuItems = [], deploymentT
|
||||
if (usedHandlers.has('validate-workflow')) {
|
||||
activation += ` <handler type="validate-workflow">
|
||||
When menu item has: validate-workflow="path/to/workflow.yaml"
|
||||
1. CRITICAL: Always LOAD {project-root}/{bmad_folder}/core/tasks/validate-workflow.xml
|
||||
1. CRITICAL: Always LOAD {project-root}/.bmad/core/tasks/validate-workflow.xml
|
||||
2. Read the complete file - this is the CORE OS for validating BMAD workflows
|
||||
3. Pass the workflow.yaml path as 'workflow' parameter to those instructions
|
||||
4. Pass any checklist.md from the workflow location as 'checklist' parameter if available
|
||||
|
||||
@@ -273,7 +273,7 @@ function installAgent(agentInfo, answers, targetPath, options = {}) {
|
||||
// Resolve path variables
|
||||
const resolvedSidecarFolder = agentSidecarFolder
|
||||
.replaceAll('{project-root}', options.projectRoot || process.cwd())
|
||||
.replaceAll('{bmad_folder}', options.bmadFolder || '.bmad');
|
||||
.replaceAll('.bmad', options.bmadFolder || '.bmad');
|
||||
|
||||
// Create sidecar directory for this agent
|
||||
const agentSidecarDir = path.join(resolvedSidecarFolder, agentFolderName);
|
||||
@@ -407,7 +407,7 @@ function detectBmadProject(targetPath) {
|
||||
|
||||
// Walk up directory tree looking for BMAD installation
|
||||
while (checkPath !== root) {
|
||||
const possibleNames = ['.bmad', 'bmad'];
|
||||
const possibleNames = ['.bmad'];
|
||||
for (const name of possibleNames) {
|
||||
const bmadFolder = path.join(checkPath, name);
|
||||
const cfgFolder = path.join(bmadFolder, '_cfg');
|
||||
|
||||
@@ -136,7 +136,7 @@ class UI {
|
||||
// Create the bmad directory based on core config
|
||||
const path = require('node:path');
|
||||
const fs = require('fs-extra');
|
||||
const bmadFolderName = coreConfig.bmad_folder || 'bmad';
|
||||
const bmadFolderName = '.bmad';
|
||||
const bmadDir = path.join(confirmedDirectory, bmadFolderName);
|
||||
|
||||
await fs.ensureDir(bmadDir);
|
||||
@@ -1082,7 +1082,7 @@ class UI {
|
||||
* @calls checkAgentVibesInstalled(), inquirer.prompt(), chalk.green/yellow/dim()
|
||||
*
|
||||
* AI NOTE: This prompt is strategically positioned in installation flow:
|
||||
* - AFTER core config (bmad_folder, user_name, etc)
|
||||
* - AFTER core config (user_name, etc)
|
||||
* - BEFORE IDE selection (which can hang on Windows/PowerShell)
|
||||
*
|
||||
* Flow Logic:
|
||||
@@ -1210,129 +1210,134 @@ class UI {
|
||||
*/
|
||||
async promptCustomContentForExisting() {
|
||||
try {
|
||||
CLIUtils.displaySection('Custom Content', 'Add new custom agents, workflows, or modules to your installation');
|
||||
// Skip custom content installation - always return false
|
||||
return { hasCustomContent: false };
|
||||
|
||||
const { hasCustomContent } = await inquirer.prompt([
|
||||
{
|
||||
type: 'list',
|
||||
name: 'hasCustomContent',
|
||||
message: 'Do you want to add or update custom content?',
|
||||
choices: [
|
||||
{
|
||||
name: 'No, continue with current installation only',
|
||||
value: false,
|
||||
},
|
||||
{
|
||||
name: 'Yes, I have custom content to add or update',
|
||||
value: true,
|
||||
},
|
||||
],
|
||||
default: false,
|
||||
},
|
||||
]);
|
||||
// TODO: Custom content installation temporarily disabled
|
||||
// CLIUtils.displaySection('Custom Content', 'Add new custom agents, workflows, or modules to your installation');
|
||||
|
||||
if (!hasCustomContent) {
|
||||
return { hasCustomContent: false };
|
||||
}
|
||||
// const { hasCustomContent } = await inquirer.prompt([
|
||||
// {
|
||||
// type: 'list',
|
||||
// name: 'hasCustomContent',
|
||||
// message: 'Do you want to add or update custom content?',
|
||||
// choices: [
|
||||
// {
|
||||
// name: 'No, continue with current installation only',
|
||||
// value: false,
|
||||
// },
|
||||
// {
|
||||
// name: 'Yes, I have custom content to add or update',
|
||||
// value: true,
|
||||
// },
|
||||
// ],
|
||||
// default: false,
|
||||
// },
|
||||
// ]);
|
||||
|
||||
// Get directory path
|
||||
const { customPath } = await inquirer.prompt([
|
||||
{
|
||||
type: 'input',
|
||||
name: 'customPath',
|
||||
message: 'Enter directory to search for custom content (will scan subfolders):',
|
||||
default: process.cwd(),
|
||||
validate: async (input) => {
|
||||
if (!input || input.trim() === '') {
|
||||
return 'Please enter a directory path';
|
||||
}
|
||||
// if (!hasCustomContent) {
|
||||
// return { hasCustomContent: false };
|
||||
// }
|
||||
|
||||
// Normalize and check if path exists
|
||||
const expandedPath = CLIUtils.expandPath(input.trim());
|
||||
const pathExists = await fs.pathExists(expandedPath);
|
||||
if (!pathExists) {
|
||||
return 'Directory does not exist';
|
||||
}
|
||||
// TODO: Custom content installation temporarily disabled
|
||||
// // Get directory path
|
||||
// const { customPath } = await inquirer.prompt([
|
||||
// {
|
||||
// type: 'input',
|
||||
// name: 'customPath',
|
||||
// message: 'Enter directory to search for custom content (will scan subfolders):',
|
||||
// default: process.cwd(),
|
||||
// validate: async (input) => {
|
||||
// if (!input || input.trim() === '') {
|
||||
// return 'Please enter a directory path';
|
||||
// }
|
||||
|
||||
// Check if it's actually a directory
|
||||
const stats = await fs.stat(expandedPath);
|
||||
if (!stats.isDirectory()) {
|
||||
return 'Path must be a directory';
|
||||
}
|
||||
// // Normalize and check if path exists
|
||||
// const expandedPath = CLIUtils.expandPath(input.trim());
|
||||
// const pathExists = await fs.pathExists(expandedPath);
|
||||
// if (!pathExists) {
|
||||
// return 'Directory does not exist';
|
||||
// }
|
||||
|
||||
return true;
|
||||
},
|
||||
transformer: (input) => {
|
||||
return CLIUtils.expandPath(input);
|
||||
},
|
||||
},
|
||||
]);
|
||||
// // Check if it's actually a directory
|
||||
// const stats = await fs.stat(expandedPath);
|
||||
// if (!stats.isDirectory()) {
|
||||
// return 'Path must be a directory';
|
||||
// }
|
||||
|
||||
const resolvedPath = CLIUtils.expandPath(customPath);
|
||||
// return true;
|
||||
// },
|
||||
// transformer: (input) => {
|
||||
// return CLIUtils.expandPath(input);
|
||||
// },
|
||||
// },
|
||||
// ]);
|
||||
|
||||
// Find custom content
|
||||
const customHandler = new CustomHandler();
|
||||
const customFiles = await customHandler.findCustomContent(resolvedPath);
|
||||
// const resolvedPath = CLIUtils.expandPath(customPath);
|
||||
|
||||
if (customFiles.length === 0) {
|
||||
console.log(chalk.yellow(`\nNo custom content found in ${resolvedPath}`));
|
||||
// // Find custom content
|
||||
// const customHandler = new CustomHandler();
|
||||
// const customFiles = await customHandler.findCustomContent(resolvedPath);
|
||||
|
||||
const { tryDifferent } = await inquirer.prompt([
|
||||
{
|
||||
type: 'confirm',
|
||||
name: 'tryDifferent',
|
||||
message: 'Try a different directory?',
|
||||
default: true,
|
||||
},
|
||||
]);
|
||||
// if (customFiles.length === 0) {
|
||||
// console.log(chalk.yellow(`\nNo custom content found in ${resolvedPath}`));
|
||||
|
||||
if (tryDifferent) {
|
||||
return await this.promptCustomContentForExisting();
|
||||
}
|
||||
// const { tryDifferent } = await inquirer.prompt([
|
||||
// {
|
||||
// type: 'confirm',
|
||||
// name: 'tryDifferent',
|
||||
// message: 'Try a different directory?',
|
||||
// default: true,
|
||||
// },
|
||||
// ]);
|
||||
|
||||
return { hasCustomContent: false };
|
||||
}
|
||||
// if (tryDifferent) {
|
||||
// return await this.promptCustomContentForExisting();
|
||||
// }
|
||||
|
||||
// Display found items
|
||||
console.log(chalk.cyan(`\nFound ${customFiles.length} custom content file(s):`));
|
||||
const customContentItems = [];
|
||||
// return { hasCustomContent: false };
|
||||
// }
|
||||
|
||||
for (const customFile of customFiles) {
|
||||
const customInfo = await customHandler.getCustomInfo(customFile);
|
||||
if (customInfo) {
|
||||
customContentItems.push({
|
||||
name: `${chalk.cyan('✓')} ${customInfo.name} ${chalk.gray(`(${customInfo.relativePath})`)}`,
|
||||
value: `__CUSTOM_CONTENT__${customFile}`,
|
||||
checked: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
// // Display found items
|
||||
// console.log(chalk.cyan(`\nFound ${customFiles.length} custom content file(s):`));
|
||||
// const customContentItems = [];
|
||||
|
||||
// Add option to keep existing custom content
|
||||
console.log(chalk.yellow('\nExisting custom modules will be preserved unless you remove them'));
|
||||
// for (const customFile of customFiles) {
|
||||
// const customInfo = await customHandler.getCustomInfo(customFile);
|
||||
// if (customInfo) {
|
||||
// customContentItems.push({
|
||||
// name: `${chalk.cyan('✓')} ${customInfo.name} ${chalk.gray(`(${customInfo.relativePath})`)}`,
|
||||
// value: `__CUSTOM_CONTENT__${customFile}`,
|
||||
// checked: true,
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
const { selectedFiles } = await inquirer.prompt([
|
||||
{
|
||||
type: 'checkbox',
|
||||
name: 'selectedFiles',
|
||||
message: 'Select custom content to add:',
|
||||
choices: customContentItems,
|
||||
pageSize: 15,
|
||||
validate: (answer) => {
|
||||
if (answer.length === 0) {
|
||||
return 'You must select at least one item';
|
||||
}
|
||||
return true;
|
||||
},
|
||||
},
|
||||
]);
|
||||
// // Add option to keep existing custom content
|
||||
// console.log(chalk.yellow('\nExisting custom modules will be preserved unless you remove them'));
|
||||
|
||||
return {
|
||||
hasCustomContent: true,
|
||||
customPath: resolvedPath,
|
||||
selected: true,
|
||||
selectedFiles: selectedFiles,
|
||||
};
|
||||
// const { selectedFiles } = await inquirer.prompt([
|
||||
// {
|
||||
// type: 'checkbox',
|
||||
// name: 'selectedFiles',
|
||||
// message: 'Select custom content to add:',
|
||||
// choices: customContentItems,
|
||||
// pageSize: 15,
|
||||
// validate: (answer) => {
|
||||
// if (answer.length === 0) {
|
||||
// return 'You must select at least one item';
|
||||
// }
|
||||
// return true;
|
||||
// },
|
||||
// },
|
||||
// ]);
|
||||
|
||||
// return {
|
||||
// hasCustomContent: true,
|
||||
// customPath: resolvedPath,
|
||||
// selected: true,
|
||||
// selectedFiles: selectedFiles,
|
||||
// };
|
||||
} catch (error) {
|
||||
console.error(chalk.red('Error configuring custom content:'), error);
|
||||
return { hasCustomContent: false };
|
||||
|
||||
Reference in New Issue
Block a user