Compare commits
9 Commits
f646450ad8
...
bc0215d849
| Author | SHA1 | Date |
|---|---|---|
|
|
bc0215d849 | |
|
|
44972d62b9 | |
|
|
deedf18fc5 | |
|
|
17fe438452 | |
|
|
d036d34892 | |
|
|
bc7c7f0757 | |
|
|
82411feef3 | |
|
|
740662350a | |
|
|
ab41b23751 |
|
|
@ -54,6 +54,7 @@ _bmad-output
|
|||
.opencode
|
||||
.qwen
|
||||
.rovodev
|
||||
.bob
|
||||
.kilocodemodes
|
||||
.claude/commands
|
||||
.codex
|
||||
|
|
|
|||
15
CHANGELOG.md
15
CHANGELOG.md
|
|
@ -1,5 +1,20 @@
|
|||
# Changelog
|
||||
|
||||
## [6.0.4]
|
||||
|
||||
### 🎁 Features
|
||||
|
||||
* Add edge case hunter review task - new reusable review task that exhaustively traces branching paths and boundary conditions in code, reporting only unhandled gaps. Method-driven analysis complementary to adversarial review (#1790)
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
* Fix brainstorming to not overwrite previous sessions; now prompts to continue existing brainstorming or start a new one when older brainstorming sessions are found
|
||||
* Fix installer templates - replace legacy `@` path prefixes with explicit `{project-root}` syntax for consistency (#1769)
|
||||
* Fix edge case hunter - remove zero-findings halt condition that was pressuring the LLM to hallucinate findings when none legitimately exist (#1797)
|
||||
* Fix broken docs domain references in README and GitHub issue templates (#1777)
|
||||
|
||||
---
|
||||
|
||||
## [6.0.3]
|
||||
|
||||
### 🎁 Features
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ export default [
|
|||
'website/**',
|
||||
// Gitignored patterns
|
||||
'z*/**', // z-samples, z1, z2, etc.
|
||||
'.bob/**',
|
||||
'.claude/**',
|
||||
'.codex/**',
|
||||
'.github/chatmodes/**',
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "bmad-method",
|
||||
"version": "6.0.3",
|
||||
"version": "6.0.4",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "bmad-method",
|
||||
"version": "6.0.3",
|
||||
"version": "6.0.4",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@clack/core": "^1.0.0",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "bmad-method",
|
||||
"version": "6.0.3",
|
||||
"version": "6.0.4",
|
||||
"description": "Breakthrough Method of Agile AI-driven Development",
|
||||
"keywords": [
|
||||
"agile",
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ No extra text, no explanations, no markdown wrapping.</output-format>
|
|||
</flow>
|
||||
|
||||
<halt-conditions>
|
||||
<condition>HALT if zero findings - this is suspicious, re-analyze or ask for guidance</condition>
|
||||
<condition>HALT if content is empty or unreadable</condition>
|
||||
</halt-conditions>
|
||||
|
||||
|
|
|
|||
|
|
@ -29,23 +29,30 @@ Initialize the brainstorming workflow by detecting continuation state and settin
|
|||
|
||||
## INITIALIZATION SEQUENCE:
|
||||
|
||||
### 1. Check for Existing Workflow
|
||||
### 1. Check for Existing Sessions
|
||||
|
||||
First, check if the output document already exists:
|
||||
First, check the brainstorming sessions folder for existing sessions:
|
||||
|
||||
- Look for file at `{output_folder}/brainstorming/brainstorming-session-{{date}}.md`
|
||||
- If exists, read the complete file including frontmatter
|
||||
- If not exists, this is a fresh workflow
|
||||
- List all files in `{output_folder}/brainstorming/`
|
||||
- **DO NOT read any file contents** - only list filenames
|
||||
- If files exist, identify the most recent by date/time in the filename
|
||||
- If no files exist, this is a fresh workflow
|
||||
|
||||
### 2. Handle Continuation (If Document Exists)
|
||||
### 2. Handle Existing Sessions (If Files Found)
|
||||
|
||||
If the document exists and has frontmatter with `stepsCompleted`:
|
||||
If existing session files are found:
|
||||
|
||||
- **STOP here** and load `./step-01b-continue.md` immediately
|
||||
- Do not proceed with any initialization tasks
|
||||
- Let step-01b handle the continuation logic
|
||||
- Display the most recent session filename (do NOT read its content)
|
||||
- Ask the user: "Found existing session: `[filename]`. Would you like to:
|
||||
**[1]** Continue this session
|
||||
**[2]** Start a new session
|
||||
**[3]** See all existing sessions"
|
||||
|
||||
### 3. Fresh Workflow Setup (If No Document)
|
||||
- If user selects **[1]** (continue): Set `{brainstorming_session_output_file}` to that file path and load `./step-01b-continue.md`
|
||||
- If user selects **[2]** (new): Generate new filename with current date/time and proceed to step 3
|
||||
- If user selects **[3]** (see all): List all session filenames and ask which to continue or if new
|
||||
|
||||
### 3. Fresh Workflow Setup (If No Files or User Chooses New)
|
||||
|
||||
If no document exists or no `stepsCompleted` in frontmatter:
|
||||
|
||||
|
|
@ -55,10 +62,10 @@ Create the brainstorming session document:
|
|||
|
||||
```bash
|
||||
# Create directory if needed
|
||||
mkdir -p "$(dirname "{output_folder}/brainstorming/brainstorming-session-{{date}}.md")"
|
||||
mkdir -p "$(dirname "{brainstorming_session_output_file}")"
|
||||
|
||||
# Initialize from template
|
||||
cp "{template_path}" "{output_folder}/brainstorming/brainstorming-session-{{date}}.md"
|
||||
cp "{template_path}" "{brainstorming_session_output_file}"
|
||||
```
|
||||
|
||||
#### B. Context File Check and Loading
|
||||
|
|
@ -134,7 +141,7 @@ _[Content based on conversation about session parameters and facilitator approac
|
|||
|
||||
## APPEND TO DOCUMENT:
|
||||
|
||||
When user selects approach, append the session overview content directly to `{output_folder}/brainstorming/brainstorming-session-{{date}}.md` using the structure from above.
|
||||
When user selects approach, append the session overview content directly to `{brainstorming_session_output_file}` using the structure from above.
|
||||
|
||||
### E. Continue to Technique Selection
|
||||
|
||||
|
|
@ -152,7 +159,7 @@ Which approach appeals to you most? (Enter 1-4)"
|
|||
|
||||
#### When user selects approach number:
|
||||
|
||||
- **Append initial session overview to `{output_folder}/brainstorming/brainstorming-session-{{date}}.md`**
|
||||
- **Append initial session overview to `{brainstorming_session_output_file}`**
|
||||
- **Update frontmatter:** `stepsCompleted: [1]`, `selected_approach: '[selected approach]'`
|
||||
- **Load the appropriate step-02 file** based on selection
|
||||
|
||||
|
|
@ -167,7 +174,9 @@ After user selects approach number:
|
|||
|
||||
## SUCCESS METRICS:
|
||||
|
||||
✅ Existing workflow detected and continuation handled properly
|
||||
✅ Existing sessions detected without reading file contents
|
||||
✅ User prompted to continue existing session or start new
|
||||
✅ Correct session file selected for continuation
|
||||
✅ Fresh workflow initialized with correct document structure
|
||||
✅ Session context gathered and understood clearly
|
||||
✅ User's approach selection captured and routed correctly
|
||||
|
|
@ -176,7 +185,9 @@ After user selects approach number:
|
|||
|
||||
## FAILURE MODES:
|
||||
|
||||
❌ Not checking for existing document before creating new one
|
||||
❌ Reading file contents during session detection (wastes context)
|
||||
❌ Not asking user before continuing existing session
|
||||
❌ Not properly routing user's continue/new session selection
|
||||
❌ Missing continuation detection leading to duplicate work
|
||||
❌ Insufficient session context gathering
|
||||
❌ Not properly routing user's approach selection
|
||||
|
|
@ -184,7 +195,9 @@ After user selects approach number:
|
|||
|
||||
## SESSION SETUP PROTOCOLS:
|
||||
|
||||
- Always verify document existence before initialization
|
||||
- Always list sessions folder WITHOUT reading file contents
|
||||
- Ask user before continuing any existing session
|
||||
- Only load continue step after user confirms
|
||||
- Load brain techniques CSV only when needed for technique presentation
|
||||
- Use collaborative facilitation language throughout
|
||||
- Maintain psychological safety for creative exploration
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ Load existing document and analyze current state:
|
|||
|
||||
**Document Analysis:**
|
||||
|
||||
- Read existing `{output_folder}/brainstorming/brainstorming-session-{{date}}.md`
|
||||
- Read existing `{brainstorming_session_output_file}`
|
||||
- Examine frontmatter for `stepsCompleted`, `session_topic`, `session_goals`
|
||||
- Review content to understand session progress and outcomes
|
||||
- Identify current stage and next logical steps
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ After final technique element:
|
|||
|
||||
#### If 'C' (Move to organization):
|
||||
|
||||
- **Append the technique execution content to `{output_folder}/brainstorming/brainstorming-session-{{date}}.md`**
|
||||
- **Append the technique execution content to `{brainstorming_session_output_file}`**
|
||||
- **Update frontmatter:** `stepsCompleted: [1, 2, 3]`
|
||||
- **Load:** `./step-04-idea-organization.md`
|
||||
|
||||
|
|
@ -356,7 +356,7 @@ _[Short narrative describing the user and AI collaboration journey - what made t
|
|||
|
||||
## APPEND TO DOCUMENT:
|
||||
|
||||
When user selects 'C', append the content directly to `{output_folder}/brainstorming/brainstorming-session-{{date}}.md` using the structure from above.
|
||||
When user selects 'C', append the content directly to `{brainstorming_session_output_file}` using the structure from above.
|
||||
|
||||
## SUCCESS METRICS:
|
||||
|
||||
|
|
|
|||
|
|
@ -253,14 +253,14 @@ Provide final session wrap-up and forward guidance:
|
|||
|
||||
#### If [C] Complete:
|
||||
|
||||
- **Append the final session content to `{output_folder}/brainstorming/brainstorming-session-{{date}}.md`**
|
||||
- **Append the final session content to `{brainstorming_session_output_file}`**
|
||||
- Update frontmatter: `stepsCompleted: [1, 2, 3, 4]`
|
||||
- Set `session_active: false` and `workflow_completed: true`
|
||||
- Complete workflow with positive closure message
|
||||
|
||||
## APPEND TO DOCUMENT:
|
||||
|
||||
When user selects 'C', append the content directly to `{output_folder}/brainstorming/brainstorming-session-{{date}}.md` using the structure from step 7.
|
||||
When user selects 'C', append the content directly to `{brainstorming_session_output_file}` using the structure from step 7.
|
||||
|
||||
## SUCCESS METRICS:
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,9 @@ Load config from `{project-root}/_bmad/core/config.yaml` and resolve:
|
|||
- `installed_path` = `{project-root}/_bmad/core/workflows/brainstorming`
|
||||
- `template_path` = `{installed_path}/template.md`
|
||||
- `brain_techniques_path` = `{installed_path}/brain-methods.csv`
|
||||
- `default_output_file` = `{output_folder}/brainstorming/brainstorming-session-{{date}}.md`
|
||||
- `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.
|
||||
- `context_file` = Optional context file path from workflow invocation for project-specific guidance
|
||||
- `advancedElicitationTask` = `{project-root}/_bmad/core/workflows/advanced-elicitation/workflow.xml`
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,294 @@
|
|||
const path = require('node:path');
|
||||
const fs = require('fs-extra');
|
||||
const { BaseIdeSetup } = require('./_base-ide');
|
||||
const yaml = require('yaml');
|
||||
const prompts = require('../../../lib/prompts');
|
||||
const { AgentCommandGenerator } = require('./shared/agent-command-generator');
|
||||
const { WorkflowCommandGenerator } = require('./shared/workflow-command-generator');
|
||||
const { TaskToolCommandGenerator } = require('./shared/task-tool-command-generator');
|
||||
|
||||
/**
|
||||
* IBM Bob IDE setup handler
|
||||
* Creates custom modes in .bob/custom_modes.yaml file
|
||||
*/
|
||||
class BobSetup extends BaseIdeSetup {
|
||||
constructor() {
|
||||
super('bob', 'IBM Bob');
|
||||
this.configFile = '.bob/custom_modes.yaml';
|
||||
this.detectionPaths = ['.bob'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup IBM Bob IDE configuration
|
||||
* @param {string} projectDir - Project directory
|
||||
* @param {string} bmadDir - BMAD installation directory
|
||||
* @param {Object} options - Setup options
|
||||
*/
|
||||
async setup(projectDir, bmadDir, options = {}) {
|
||||
if (!options.silent) await prompts.log.info(`Setting up ${this.name}...`);
|
||||
|
||||
// Clean up any old BMAD installation first
|
||||
await this.cleanup(projectDir, options);
|
||||
|
||||
// Load existing config (may contain non-BMAD modes and other settings)
|
||||
const bobModesPath = path.join(projectDir, this.configFile);
|
||||
let config = {};
|
||||
|
||||
if (await this.pathExists(bobModesPath)) {
|
||||
const existingContent = await this.readFile(bobModesPath);
|
||||
try {
|
||||
config = yaml.parse(existingContent) || {};
|
||||
} catch {
|
||||
// If parsing fails, start fresh but warn user
|
||||
await prompts.log.warn('Warning: Could not parse existing .bob/custom_modes.yaml, starting fresh');
|
||||
config = {};
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure customModes array exists
|
||||
if (!Array.isArray(config.customModes)) {
|
||||
config.customModes = [];
|
||||
}
|
||||
|
||||
// Generate agent launchers
|
||||
const agentGen = new AgentCommandGenerator(this.bmadFolderName);
|
||||
const { artifacts: agentArtifacts } = await agentGen.collectAgentArtifacts(bmadDir, options.selectedModules || []);
|
||||
|
||||
// Create mode objects and add to config
|
||||
let addedCount = 0;
|
||||
|
||||
for (const artifact of agentArtifacts) {
|
||||
const modeObject = await this.createModeObject(artifact, projectDir);
|
||||
config.customModes.push(modeObject);
|
||||
addedCount++;
|
||||
}
|
||||
|
||||
// Write .bob/custom_modes.yaml file with proper YAML structure
|
||||
const finalContent = yaml.stringify(config, { lineWidth: 0 });
|
||||
const workflowsDir = path.join(projectDir, '.bob', 'workflows');
|
||||
|
||||
let workflowCount = 0;
|
||||
let taskCount = 0;
|
||||
let toolCount = 0;
|
||||
|
||||
try {
|
||||
await this.writeFile(bobModesPath, finalContent);
|
||||
|
||||
// Generate workflow commands
|
||||
const workflowGenerator = new WorkflowCommandGenerator(this.bmadFolderName);
|
||||
const { artifacts: workflowArtifacts } = await workflowGenerator.collectWorkflowArtifacts(bmadDir);
|
||||
|
||||
// Write to .bob/workflows/ directory
|
||||
await this.ensureDir(workflowsDir);
|
||||
|
||||
// Clear old BMAD workflows before writing new ones
|
||||
await this.clearBmadWorkflows(workflowsDir);
|
||||
|
||||
// Write workflow files
|
||||
workflowCount = await workflowGenerator.writeDashArtifacts(workflowsDir, workflowArtifacts);
|
||||
|
||||
// Generate task and tool commands
|
||||
const taskToolGen = new TaskToolCommandGenerator(this.bmadFolderName);
|
||||
const { artifacts: taskToolArtifacts, counts: taskToolCounts } = await taskToolGen.collectTaskToolArtifacts(bmadDir);
|
||||
|
||||
// Write task/tool files to workflows directory (same location as workflows)
|
||||
await taskToolGen.writeDashArtifacts(workflowsDir, taskToolArtifacts);
|
||||
taskCount = taskToolCounts.tasks || 0;
|
||||
toolCount = taskToolCounts.tools || 0;
|
||||
} catch (error) {
|
||||
// Roll back partial writes to avoid inconsistent state
|
||||
try {
|
||||
await fs.remove(bobModesPath);
|
||||
} catch {
|
||||
// Ignore cleanup errors
|
||||
}
|
||||
await this.clearBmadWorkflows(workflowsDir);
|
||||
throw new Error(`Failed to write Bob configuration: ${error.message}`);
|
||||
}
|
||||
|
||||
if (!options.silent) {
|
||||
await prompts.log.success(
|
||||
`${this.name} configured: ${addedCount} modes, ${workflowCount} workflows, ${taskCount} tasks, ${toolCount} tools → ${this.configFile}`,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
modes: addedCount,
|
||||
workflows: workflowCount,
|
||||
tasks: taskCount,
|
||||
tools: toolCount,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mode object for an agent
|
||||
* @param {Object} artifact - Agent artifact
|
||||
* @param {string} projectDir - Project directory
|
||||
* @returns {Object} Mode object for YAML serialization
|
||||
*/
|
||||
async createModeObject(artifact, projectDir) {
|
||||
// Extract title and icon from the compiled agent file's <agent> XML tag
|
||||
// artifact.content is the launcher template which does NOT contain these attributes
|
||||
let title = this.formatTitle(artifact.name);
|
||||
let icon = '🤖';
|
||||
|
||||
if (artifact.sourcePath && (await this.pathExists(artifact.sourcePath))) {
|
||||
const agentContent = await this.readFile(artifact.sourcePath);
|
||||
const titleMatch = agentContent.match(/<agent[^>]*\stitle="([^"]+)"/);
|
||||
if (titleMatch) title = titleMatch[1];
|
||||
const iconMatch = agentContent.match(/<agent[^>]*\sicon="([^"]+)"/);
|
||||
if (iconMatch) icon = iconMatch[1];
|
||||
}
|
||||
|
||||
const whenToUse = `Use for ${title} tasks`;
|
||||
|
||||
// Get the activation header from central template (trim to avoid YAML formatting issues)
|
||||
const activationHeader = (await this.getAgentCommandHeader()).trim();
|
||||
|
||||
const roleDefinition = `You are a ${title} specializing in ${title.toLowerCase()} tasks.`;
|
||||
|
||||
// Get relative path (fall back to artifact name if sourcePath unavailable)
|
||||
const relativePath = artifact.sourcePath
|
||||
? path.relative(projectDir, artifact.sourcePath).replaceAll('\\', '/')
|
||||
: `${this.bmadFolderName}/agents/${artifact.name}.md`;
|
||||
|
||||
// Build mode object (Bob uses same schema as Kilo/Roo)
|
||||
return {
|
||||
slug: `bmad-${artifact.module}-${artifact.name}`,
|
||||
name: `${icon} ${title}`,
|
||||
roleDefinition: roleDefinition,
|
||||
whenToUse: whenToUse,
|
||||
customInstructions: `${activationHeader} Read the full agent definition from ${relativePath}. Start activation to assume this persona. Follow the startup section instructions. Stay in this mode until told to exit.\n`,
|
||||
groups: ['read', 'edit', 'browser', 'command', 'mcp'],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Format name as title
|
||||
*/
|
||||
formatTitle(name) {
|
||||
return name
|
||||
.split('-')
|
||||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
||||
.join(' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear old BMAD workflow files from workflows directory
|
||||
* @param {string} workflowsDir - Workflows directory path
|
||||
*/
|
||||
async clearBmadWorkflows(workflowsDir) {
|
||||
if (!(await this.pathExists(workflowsDir))) return;
|
||||
|
||||
const entries = await fs.readdir(workflowsDir);
|
||||
for (const entry of entries) {
|
||||
if (entry.startsWith('bmad-') && entry.endsWith('.md')) {
|
||||
await fs.remove(path.join(workflowsDir, entry));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup IBM Bob configuration
|
||||
*/
|
||||
async cleanup(projectDir, options = {}) {
|
||||
const bobModesPath = path.join(projectDir, this.configFile);
|
||||
|
||||
if (await this.pathExists(bobModesPath)) {
|
||||
const content = await this.readFile(bobModesPath);
|
||||
|
||||
try {
|
||||
const config = yaml.parse(content) || {};
|
||||
|
||||
if (Array.isArray(config.customModes)) {
|
||||
const originalCount = config.customModes.length;
|
||||
// Remove BMAD modes only (keep non-BMAD modes)
|
||||
config.customModes = config.customModes.filter((mode) => !mode.slug || !mode.slug.startsWith('bmad-'));
|
||||
const removedCount = originalCount - config.customModes.length;
|
||||
|
||||
if (removedCount > 0) {
|
||||
await this.writeFile(bobModesPath, yaml.stringify(config, { lineWidth: 0 }));
|
||||
if (!options.silent) await prompts.log.message(`Removed ${removedCount} BMAD modes from .bob/custom_modes.yaml`);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// If parsing fails, leave file as-is
|
||||
if (!options.silent) await prompts.log.warn('Warning: Could not parse .bob/custom_modes.yaml for cleanup');
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up workflow files
|
||||
const workflowsDir = path.join(projectDir, '.bob', 'workflows');
|
||||
await this.clearBmadWorkflows(workflowsDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Install a custom agent launcher for Bob
|
||||
* @param {string} projectDir - Project directory
|
||||
* @param {string} agentName - Agent name (e.g., "fred-commit-poet")
|
||||
* @param {string} agentPath - Path to compiled agent (relative to project root)
|
||||
* @param {Object} metadata - Agent metadata
|
||||
* @returns {Object} Installation result
|
||||
*/
|
||||
async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) {
|
||||
const bobmodesPath = path.join(projectDir, this.configFile);
|
||||
let config = {};
|
||||
|
||||
// Read existing .bob/custom_modes.yaml file
|
||||
if (await this.pathExists(bobmodesPath)) {
|
||||
const existingContent = await this.readFile(bobmodesPath);
|
||||
try {
|
||||
config = yaml.parse(existingContent) || {};
|
||||
} catch {
|
||||
config = {};
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure customModes array exists
|
||||
if (!Array.isArray(config.customModes)) {
|
||||
config.customModes = [];
|
||||
}
|
||||
|
||||
// Create custom agent mode object
|
||||
const slug = `bmad-custom-${agentName.toLowerCase()}`;
|
||||
|
||||
// Check if mode already exists
|
||||
if (config.customModes.some((mode) => mode.slug === slug)) {
|
||||
return {
|
||||
ide: 'bob',
|
||||
path: this.configFile,
|
||||
command: agentName,
|
||||
type: 'custom-agent-launcher',
|
||||
alreadyExists: true,
|
||||
};
|
||||
}
|
||||
|
||||
// Add custom mode object
|
||||
const title = metadata?.title || `BMAD Custom: ${agentName}`;
|
||||
const icon = metadata?.icon || '🤖';
|
||||
const activationHeader = (await this.getAgentCommandHeader()).trim();
|
||||
config.customModes.push({
|
||||
slug: slug,
|
||||
name: `${icon} ${title}`,
|
||||
roleDefinition: `You are a custom BMAD agent "${agentName}". Follow the persona and instructions from the agent file.`,
|
||||
whenToUse: `Use for custom BMAD agent "${agentName}" tasks`,
|
||||
customInstructions: `${activationHeader} Read the full agent definition from ${agentPath}. Start activation to assume this persona. Follow the startup section instructions. Stay in this mode until told to exit.\n`,
|
||||
groups: ['read', 'edit', 'browser', 'command', 'mcp'],
|
||||
});
|
||||
|
||||
// Write .bob/custom_modes.yaml file with proper YAML structure
|
||||
await this.writeFile(bobmodesPath, yaml.stringify(config, { lineWidth: 0 }));
|
||||
|
||||
return {
|
||||
ide: 'bob',
|
||||
path: this.configFile,
|
||||
command: slug,
|
||||
type: 'custom-agent-launcher',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { BobSetup };
|
||||
|
||||
// Made with Bob
|
||||
|
|
@ -8,7 +8,7 @@ const prompts = require('../../../lib/prompts');
|
|||
* Dynamically discovers and loads IDE handlers
|
||||
*
|
||||
* Loading strategy:
|
||||
* 1. Custom installer files (codex.js, github-copilot.js, kilo.js, rovodev.js) - for platforms with unique installation logic
|
||||
* 1. Custom installer files (bob.js, codex.js, github-copilot.js, kilo.js, rovodev.js) - for platforms with unique installation logic
|
||||
* 2. Config-driven handlers (from platform-codes.yaml) - for standard IDE installation patterns
|
||||
*/
|
||||
class IdeManager {
|
||||
|
|
@ -44,7 +44,7 @@ class IdeManager {
|
|||
|
||||
/**
|
||||
* Dynamically load all IDE handlers
|
||||
* 1. Load custom installer files first (codex.js, github-copilot.js, kilo.js, rovodev.js)
|
||||
* 1. Load custom installer files first (bob.js, codex.js, github-copilot.js, kilo.js, rovodev.js)
|
||||
* 2. Load config-driven handlers from platform-codes.yaml
|
||||
*/
|
||||
async loadHandlers() {
|
||||
|
|
@ -61,7 +61,7 @@ class IdeManager {
|
|||
*/
|
||||
async loadCustomInstallerFiles() {
|
||||
const ideDir = __dirname;
|
||||
const customFiles = ['codex.js', 'github-copilot.js', 'kilo.js', 'rovodev.js'];
|
||||
const customFiles = ['bob.js', 'codex.js', 'github-copilot.js', 'kilo.js', 'rovodev.js'];
|
||||
|
||||
for (const file of customFiles) {
|
||||
const filePath = path.join(ideDir, file);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,13 @@ platforms:
|
|||
target_dir: .augment/commands
|
||||
template_type: default
|
||||
|
||||
bob:
|
||||
name: "IBM Bob"
|
||||
preferred: false
|
||||
category: ide
|
||||
description: "IBM's agentic IDE for AI-powered development"
|
||||
# No installer config - uses custom bob.js (creates .bob/custom_modes.yaml)
|
||||
|
||||
claude-code:
|
||||
name: "Claude Code"
|
||||
preferred: true
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ description: '{{description}}'
|
|||
You must fully embody this agent's persona and follow all activation instructions exactly as specified. NEVER break character until given an exit command.
|
||||
|
||||
<agent-activation CRITICAL="TRUE">
|
||||
1. LOAD the FULL agent file from @_bmad/{{module}}/agents/{{path}}
|
||||
1. LOAD the FULL agent file from {project-root}/_bmad/{{module}}/agents/{{path}}
|
||||
2. READ its entire contents - this contains the complete agent persona, menu, and instructions
|
||||
3. Execute ALL activation steps exactly as written in the agent file
|
||||
4. Follow the agent's persona and menu system precisely
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ description: '{{description}}'
|
|||
IT IS CRITICAL THAT YOU FOLLOW THESE STEPS - while staying in character as the current agent persona you may have loaded:
|
||||
|
||||
<steps CRITICAL="TRUE">
|
||||
1. Always LOAD the FULL @{project-root}/{{bmadFolderName}}/core/tasks/workflow.xml
|
||||
2. READ its entire contents - this is the CORE OS for EXECUTING the specific workflow-config @{project-root}/{{bmadFolderName}}/{{path}}
|
||||
3. Pass the yaml path @{project-root}/{{bmadFolderName}}/{{path}} as 'workflow-config' parameter to the workflow.xml instructions
|
||||
1. Always LOAD the FULL {project-root}/{{bmadFolderName}}/core/tasks/workflow.xml
|
||||
2. READ its entire contents - this is the CORE OS for EXECUTING the specific workflow-config {project-root}/{{bmadFolderName}}/{{path}}
|
||||
3. Pass the yaml path {project-root}/{{bmadFolderName}}/{{path}} as 'workflow-config' parameter to the workflow.xml instructions
|
||||
4. Follow workflow.xml instructions EXACTLY as written to process and follow the specific workflow config and its instructions
|
||||
5. Save outputs after EACH section when generating any documents from templates
|
||||
</steps>
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@ name: '{{name}}'
|
|||
description: '{{description}}'
|
||||
---
|
||||
|
||||
IT IS CRITICAL THAT YOU FOLLOW THIS COMMAND: LOAD the FULL @{project-root}/{{bmadFolderName}}/{{path}}, READ its entire contents and follow its directions exactly!
|
||||
IT IS CRITICAL THAT YOU FOLLOW THIS COMMAND: LOAD the FULL {project-root}/{{bmadFolderName}}/{{path}}, READ its entire contents and follow its directions exactly!
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ description: '{{description}}'
|
|||
IT IS CRITICAL THAT YOU FOLLOW THESE STEPS - while staying in character as the current agent persona you may have loaded:
|
||||
|
||||
<steps CRITICAL="TRUE">
|
||||
1. Always LOAD the FULL @_bmad/core/tasks/workflow.xml
|
||||
2. READ its entire contents - this is the CORE OS for EXECUTING the specific workflow-config @{{workflow_path}}
|
||||
1. Always LOAD the FULL {project-root}/_bmad/core/tasks/workflow.xml
|
||||
2. READ its entire contents - this is the CORE OS for EXECUTING the specific workflow-config {project-root}/{{workflow_path}}
|
||||
3. Pass the yaml path {{workflow_path}} as 'workflow-config' parameter to the workflow.xml instructions
|
||||
4. Follow workflow.xml instructions EXACTLY as written to process and follow the specific workflow config and its instructions
|
||||
5. Save outputs after EACH section when generating any documents from templates
|
||||
|
|
|
|||
|
|
@ -2,4 +2,4 @@
|
|||
description: '{{description}}'
|
||||
---
|
||||
|
||||
IT IS CRITICAL THAT YOU FOLLOW THIS COMMAND: LOAD the FULL @{{workflow_path}}, READ its entire contents and follow its directions exactly!
|
||||
IT IS CRITICAL THAT YOU FOLLOW THIS COMMAND: LOAD the FULL {project-root}/{{workflow_path}}, READ its entire contents and follow its directions exactly!
|
||||
|
|
|
|||
|
|
@ -49,6 +49,12 @@ platforms:
|
|||
category: cli
|
||||
description: "AI development tool"
|
||||
|
||||
bob:
|
||||
name: "IBM Bob"
|
||||
preferred: false
|
||||
category: ide
|
||||
description: "IBM's agentic IDE for AI-powered development"
|
||||
|
||||
roo:
|
||||
name: "Roo Cline"
|
||||
preferred: false
|
||||
|
|
|
|||
Loading…
Reference in New Issue