feat(ide): add Bob IDE installer support#1786
feat(ide): add Bob IDE installer support#1786timgraepel wants to merge 3 commits intobmad-code-org:mainfrom
Conversation
📝 WalkthroughWalkthroughThis PR adds support for IBM Bob IDE integration to BMAD's installer system. It introduces a new BobSetup class to manage Bob configuration files, updates the IDE manager to load the Bob installer, registers Bob as a platform in configuration files, and adds Bob-related patterns to gitignore. Changes
Sequence Diagram(s)sequenceDiagram
participant Manager as IdeManager
participant BobSetup
participant FS as File System
participant YAML as YAML Parser
Manager->>BobSetup: instantiate BobSetup()
Manager->>BobSetup: setup(projectDir, bmadDir, options)
BobSetup->>FS: read .bob/custom_modes.yaml
FS-->>BobSetup: config file (or empty)
BobSetup->>YAML: parse YAML
YAML-->>BobSetup: parsed config object
BobSetup->>BobSetup: ensure customModes array
BobSetup->>BobSetup: createModeObject(artifact)
BobSetup->>BobSetup: append mode to config
BobSetup->>FS: write updated .bob/custom_modes.yaml
BobSetup->>FS: write workflows to .bob/workflows/
BobSetup->>BobSetup: log summary (modes, workflows, tasks, tools)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (2)
tools/cli/installers/lib/ide/bob.js (2)
276-276: Remove debug/placeholder comment.
// Made with Bobappears to be a leftover joke or debug marker. Remove it before merging.- -// Made with Bob🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tools/cli/installers/lib/ide/bob.js` at line 276, Remove the stray debug/placeholder comment "// Made with Bob" from the bob.js module (the top-level comment in the IDE installer module) so the file no longer contains this leftover joke; simply delete that single-line comment and commit the change.
162-172: Inconsistentfs-extrarequire — inline instead of top-level.
fs-extrais required inline inclearBmadWorkflows()andcleanup()but other methods usethis.pathExists,this.readFile,this.writeFilefrom the base class. Either use base class methods consistently or moverequire('fs-extra')to the top of the file.♻️ Option 1: Use base class methods
async clearBmadWorkflows(workflowsDir) { - const fs = require('fs-extra'); - if (!(await fs.pathExists(workflowsDir))) return; + if (!(await this.pathExists(workflowsDir))) return; - const entries = await fs.readdir(workflowsDir); + const fs = require('fs-extra'); // Only for readdir/remove + const entries = await fs.readdir(workflowsDir); for (const entry of entries) {♻️ Option 2: Move require to top of file
const path = require('node:path'); +const fs = require('fs-extra'); const { BaseIdeSetup } = require('./_base-ide');Then remove inline requires from
clearBmadWorkflows()andcleanup().🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tools/cli/installers/lib/ide/bob.js` around lines 162 - 172, The inline require('fs-extra') in clearBmadWorkflows (and cleanup) is inconsistent with the rest of the class which uses base-class helpers (this.pathExists, this.readFile, this.writeFile); fix by either (A) replacing the inline fs-extra calls in clearBmadWorkflows and cleanup to use the base-class methods (use this.pathExists(workflowsDir), this.readdir/readDir equivalent, this.remove or this.unlink via base helpers) or (B) move const fs = require('fs-extra') to the top of the file and remove inline requires from clearBmadWorkflows and cleanup so all uses import fs the same way; update references to path.join as needed and keep function names clearBmadWorkflows and cleanup to locate the changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.gitignore:
- Around line 57-58: Remove the unused `.bobmodes` entry from .gitignore: delete
the `.bobmodes` line and keep the existing `.bob` ignore (which already covers
the `.bob` directory), and if necessary ensure `.bob/custom_modes.yaml` (the
actual bob.js config path) remains untracked via the `.bob` rule.
In `@tools/cli/installers/lib/ide/bob.js`:
- Line 143: The customInstructions string assigned (customInstructions) is a
run-on sentence and unclear; update the template that combines activationHeader
and relativePath to add proper punctuation and clearer clauses (e.g., separate
sentences or commas) so it reads like distinct steps: instruct to read the full
YAML from ${relativePath}, then start activation, follow the startup section
instructions, and remain in the activated mode until explicitly told to exit;
keep activationHeader and ${relativePath} interpolation intact.
- Line 135: Guard against artifact.sourcePath being undefined before calling
path.relative: update the logic around the assignment to relativePath so it
first checks artifact.sourcePath (the same property read earlier) and only calls
path.relative(projectDir, artifact.sourcePath).replaceAll('\\', '/') when
present; otherwise set relativePath to a safe default (e.g., empty string or
null) and handle that downstream. Modify the code that uses relativePath
accordingly so no TypeError is thrown when artifact.sourcePath is missing.
- Around line 253-260: The custom mode added in installCustomAgentLauncher
(config.customModes.push) is inconsistent with createModeObject: include the
icon prefix in the name (use `${icon} ${title}` like createModeObject) and fix
the malformed customInstructions string by ensuring activationHeader, agentPath
and instructions are concatenated into a single well-formed sentence (no stray
"start activation" fragment) — update the object created in
installCustomAgentLauncher to match createModeObject’s shape (fields: slug, name
(with icon), roleDefinition, whenToUse, customInstructions, groups) and reuse
the same template/variable order (icon, title, agentName, activationHeader,
agentPath) so display and instructions are consistent with createModeObject.
- Line 217: The installCustomAgentLauncher function currently declares an unused
parameter metadata; either remove metadata from the function signature of
installCustomAgentLauncher and update all call sites to stop passing it, or use
metadata inside the function (e.g., read metadata.title, metadata.description,
metadata.icon) when constructing the launcher/manifest so the values are
applied; update any code that builds the launcher (same function) to consume
those fields and ensure linter/tests no longer report an unused variable.
- Around line 65-90: Wrap the sequence of file writes (the call to
this.writeFile(bobModesPath, ...),
workflowGenerator.writeDashArtifacts(workflowsDir, ...), and
taskToolGen.writeDashArtifacts(workflowsDir, ...)) in a try/catch so partial
success doesn't leave inconsistent state; on catch clean up any partial
artifacts by removing the written bobModesPath and clearing workflowsDir (you
can reuse clearBmadWorkflows(workflowsDir)), then rethrow or throw a new error
that includes context (e.g., which write failed) so callers can handle it;
ensure you reference bobModesPath, workflowsDir, writeFile, writeDashArtifacts,
and clearBmadWorkflows when implementing the recovery.
In `@tools/platform-codes.yaml`:
- Around line 52-57: Pick one canonical description for the bob entry and make
both platform-codes.yaml files consistent: update the bob key's description
field (the "description" value under the bob entry) in both the main
platform-codes.yaml and the installer's platform-codes.yaml so they match
exactly (preserve quoting/formatting), e.g., change both to either "IBM's AI
development environment" or "IBM's agentic IDE for AI-powered development".
---
Nitpick comments:
In `@tools/cli/installers/lib/ide/bob.js`:
- Line 276: Remove the stray debug/placeholder comment "// Made with Bob" from
the bob.js module (the top-level comment in the IDE installer module) so the
file no longer contains this leftover joke; simply delete that single-line
comment and commit the change.
- Around line 162-172: The inline require('fs-extra') in clearBmadWorkflows (and
cleanup) is inconsistent with the rest of the class which uses base-class
helpers (this.pathExists, this.readFile, this.writeFile); fix by either (A)
replacing the inline fs-extra calls in clearBmadWorkflows and cleanup to use the
base-class methods (use this.pathExists(workflowsDir), this.readdir/readDir
equivalent, this.remove or this.unlink via base helpers) or (B) move const fs =
require('fs-extra') to the top of the file and remove inline requires from
clearBmadWorkflows and cleanup so all uses import fs the same way; update
references to path.join as needed and keep function names clearBmadWorkflows and
cleanup to locate the changes.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
eslint.config.mjsis excluded by!eslint.config.mjs
📒 Files selected for processing (5)
.gitignoretools/cli/installers/lib/ide/bob.jstools/cli/installers/lib/ide/manager.jstools/cli/installers/lib/ide/platform-codes.yamltools/platform-codes.yaml
.gitignore
Outdated
| .bobmodes | ||
| .bob |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
echo "=== Searching for .bobmodes references ==="
rg -i "bobmodes" --type-add 'all:*' -t all
echo ""
echo "=== Git history of .gitignore around line 57-58 ==="
git log -p --follow -- .gitignore | grep -A 5 -B 5 "bobmodes" | head -30
echo ""
echo "=== Checking .gitignore content around lines 55-60 ==="
sed -n '55,60p' .gitignoreRepository: bmad-code-org/BMAD-METHOD
Length of output: 359
Remove .bobmodes — it has no references in the codebase and doesn't match the actual config file path.
The bob.js installer uses .bob/custom_modes.yaml, not .bobmodes. A search of the entire codebase found zero references to .bobmodes, indicating it's unused or dead code. The .bob entry on line 58 already ignores the entire directory and its contents, making .bobmodes redundant.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.gitignore around lines 57 - 58, Remove the unused `.bobmodes` entry from
.gitignore: delete the `.bobmodes` line and keep the existing `.bob` ignore
(which already covers the `.bob` directory), and if necessary ensure
`.bob/custom_modes.yaml` (the actual bob.js config path) remains untracked via
the `.bob` rule.
tools/cli/installers/lib/ide/bob.js
Outdated
| // Write .bob/custom_modes.yaml file with proper YAML structure | ||
| const finalContent = yaml.stringify(config, { lineWidth: 0 }); | ||
| 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 | ||
| const workflowsDir = path.join(projectDir, '.bob', 'workflows'); | ||
| await this.ensureDir(workflowsDir); | ||
|
|
||
| // Clear old BMAD workflows before writing new ones | ||
| await this.clearBmadWorkflows(workflowsDir); | ||
|
|
||
| // Write workflow files | ||
| const 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); | ||
| const taskCount = taskToolCounts.tasks || 0; | ||
| const toolCount = taskToolCounts.tools || 0; |
There was a problem hiding this comment.
No error recovery for partial write failures.
If writeFile at line 67 succeeds but writeDashArtifacts at line 81 or 88 throws, the user is left with modes but no workflows. Consider wrapping write operations in try/catch with rollback, or at minimum document that failures may leave partial state.
🛡️ Minimal improvement: wrap writes with error context
// Write .bob/custom_modes.yaml file with proper YAML structure
const finalContent = yaml.stringify(config, { lineWidth: 0 });
- await this.writeFile(bobModesPath, finalContent);
+ try {
+ await this.writeFile(bobModesPath, finalContent);
+ } catch (err) {
+ throw new Error(`Failed to write ${this.configFile}: ${err.message}`);
+ }
// Generate workflow commands📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Write .bob/custom_modes.yaml file with proper YAML structure | |
| const finalContent = yaml.stringify(config, { lineWidth: 0 }); | |
| 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 | |
| const workflowsDir = path.join(projectDir, '.bob', 'workflows'); | |
| await this.ensureDir(workflowsDir); | |
| // Clear old BMAD workflows before writing new ones | |
| await this.clearBmadWorkflows(workflowsDir); | |
| // Write workflow files | |
| const 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); | |
| const taskCount = taskToolCounts.tasks || 0; | |
| const toolCount = taskToolCounts.tools || 0; | |
| // Write .bob/custom_modes.yaml file with proper YAML structure | |
| const finalContent = yaml.stringify(config, { lineWidth: 0 }); | |
| try { | |
| await this.writeFile(bobModesPath, finalContent); | |
| } catch (err) { | |
| throw new Error(`Failed to write ${this.configFile}: ${err.message}`); | |
| } | |
| // Generate workflow commands | |
| const workflowGenerator = new WorkflowCommandGenerator(this.bmadFolderName); | |
| const { artifacts: workflowArtifacts } = await workflowGenerator.collectWorkflowArtifacts(bmadDir); | |
| // Write to .bob/workflows/ directory | |
| const workflowsDir = path.join(projectDir, '.bob', 'workflows'); | |
| await this.ensureDir(workflowsDir); | |
| // Clear old BMAD workflows before writing new ones | |
| await this.clearBmadWorkflows(workflowsDir); | |
| // Write workflow files | |
| const 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); | |
| const taskCount = taskToolCounts.tasks || 0; | |
| const toolCount = taskToolCounts.tools || 0; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tools/cli/installers/lib/ide/bob.js` around lines 65 - 90, Wrap the sequence
of file writes (the call to this.writeFile(bobModesPath, ...),
workflowGenerator.writeDashArtifacts(workflowsDir, ...), and
taskToolGen.writeDashArtifacts(workflowsDir, ...)) in a try/catch so partial
success doesn't leave inconsistent state; on catch clean up any partial
artifacts by removing the written bobModesPath and clearing workflowsDir (you
can reuse clearBmadWorkflows(workflowsDir)), then rethrow or throw a new error
that includes context (e.g., which write failed) so callers can handle it;
ensure you reference bobModesPath, workflowsDir, writeFile, writeDashArtifacts,
and clearBmadWorkflows when implementing the recovery.
tools/cli/installers/lib/ide/bob.js
Outdated
| const roleDefinition = `You are a ${title} specializing in ${title.toLowerCase()} tasks.`; | ||
|
|
||
| // Get relative path | ||
| const relativePath = path.relative(projectDir, artifact.sourcePath).replaceAll('\\', '/'); |
There was a problem hiding this comment.
Potential crash if artifact.sourcePath is undefined.
Line 135 uses artifact.sourcePath unconditionally in path.relative(), but lines 119-125 only read from it conditionally. If an artifact lacks sourcePath, this will throw TypeError: Cannot read properties of undefined.
🐛 Proposed fix: guard against missing sourcePath
- // Get relative path
- const relativePath = path.relative(projectDir, artifact.sourcePath).replaceAll('\\', '/');
+ // 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`;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tools/cli/installers/lib/ide/bob.js` at line 135, Guard against
artifact.sourcePath being undefined before calling path.relative: update the
logic around the assignment to relativePath so it first checks
artifact.sourcePath (the same property read earlier) and only calls
path.relative(projectDir, artifact.sourcePath).replaceAll('\\', '/') when
present; otherwise set relativePath to a safe default (e.g., empty string or
null) and handle that downstream. Modify the code that uses relativePath
accordingly so no TypeError is thrown when artifact.sourcePath is missing.
tools/cli/installers/lib/ide/bob.js
Outdated
| name: `${icon} ${title}`, | ||
| roleDefinition: roleDefinition, | ||
| whenToUse: whenToUse, | ||
| customInstructions: `${activationHeader} Read the full YAML from ${relativePath} start activation to alter your state of being follow startup section instructions stay in this being until told to exit this mode\n`, |
There was a problem hiding this comment.
Malformed customInstructions — missing punctuation and unclear phrasing.
The instruction string is a run-on sentence: "Read the full YAML from ${relativePath} start activation to alter your state of being follow startup section instructions stay in this being until told to exit this mode".
This is likely to confuse the AI model. Add periods or commas to separate clauses.
✏️ Suggested fix
- customInstructions: `${activationHeader} Read the full YAML from ${relativePath} start activation to alter your state of being follow startup section instructions stay in this being until told to exit this mode\n`,
+ 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`,📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| customInstructions: `${activationHeader} Read the full YAML from ${relativePath} start activation to alter your state of being follow startup section instructions stay in this being until told to exit this mode\n`, | |
| 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`, |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tools/cli/installers/lib/ide/bob.js` at line 143, The customInstructions
string assigned (customInstructions) is a run-on sentence and unclear; update
the template that combines activationHeader and relativePath to add proper
punctuation and clearer clauses (e.g., separate sentences or commas) so it reads
like distinct steps: instruct to read the full YAML from ${relativePath}, then
start activation, follow the startup section instructions, and remain in the
activated mode until explicitly told to exit; keep activationHeader and
${relativePath} interpolation intact.
| * @param {Object} metadata - Agent metadata | ||
| * @returns {Object} Installation result | ||
| */ | ||
| async installCustomAgentLauncher(projectDir, agentName, agentPath, metadata) { |
There was a problem hiding this comment.
Unused metadata parameter.
The metadata parameter is declared in the function signature but never referenced in the method body. Either use it (e.g., to extract title, description, or icon) or remove it from the signature.
✏️ Example usage
// Add custom mode object
- const title = `BMAD Custom: ${agentName}`;
+ const title = metadata?.title || `BMAD Custom: ${agentName}`;
+ const icon = metadata?.icon || '🤖';
const activationHeader = (await this.getAgentCommandHeader()).trim();
config.customModes.push({
slug: slug,
- name: title,
+ name: `${icon} ${title}`,🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tools/cli/installers/lib/ide/bob.js` at line 217, The
installCustomAgentLauncher function currently declares an unused parameter
metadata; either remove metadata from the function signature of
installCustomAgentLauncher and update all call sites to stop passing it, or use
metadata inside the function (e.g., read metadata.title, metadata.description,
metadata.icon) when constructing the launcher/manifest so the values are
applied; update any code that builds the launcher (same function) to consume
those fields and ensure linter/tests no longer report an unused variable.
| config.customModes.push({ | ||
| slug: slug, | ||
| name: 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 from ${agentPath} start activation to alter your state of being follow startup section instructions stay in this being until told to exit this mode\n`, | ||
| groups: ['read', 'edit', 'browser', 'command', 'mcp'], | ||
| }); |
There was a problem hiding this comment.
Inconsistent mode object format vs createModeObject().
createModeObject() at line 140 includes an icon in the name (${icon} ${title}), but installCustomAgentLauncher() at line 254 does not. This creates inconsistent display in the Bob UI. Also, line 258 has the same malformed customInstructions issue noted earlier.
✏️ Align with createModeObject format
config.customModes.push({
slug: slug,
- name: title,
+ name: `🤖 ${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 from ${agentPath} start activation to alter your state of being follow startup section instructions stay in this being until told to exit this mode\n`,
+ 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'],
});🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tools/cli/installers/lib/ide/bob.js` around lines 253 - 260, The custom mode
added in installCustomAgentLauncher (config.customModes.push) is inconsistent
with createModeObject: include the icon prefix in the name (use `${icon}
${title}` like createModeObject) and fix the malformed customInstructions string
by ensuring activationHeader, agentPath and instructions are concatenated into a
single well-formed sentence (no stray "start activation" fragment) — update the
object created in installCustomAgentLauncher to match createModeObject’s shape
(fields: slug, name (with icon), roleDefinition, whenToUse, customInstructions,
groups) and reuse the same template/variable order (icon, title, agentName,
activationHeader, agentPath) so display and instructions are consistent with
createModeObject.
| bob: | ||
| name: "IBM Bob" | ||
| preferred: false | ||
| category: ide | ||
| description: "IBM's agentic IDE for AI-powered development" | ||
|
|
There was a problem hiding this comment.
Description mismatch with tools/cli/installers/lib/ide/platform-codes.yaml.
This file says "IBM's agentic IDE for AI-powered development" but the installer's platform-codes.yaml (line 39) says "IBM's AI development environment". Pick one and use it consistently across both files.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tools/platform-codes.yaml` around lines 52 - 57, Pick one canonical
description for the bob entry and make both platform-codes.yaml files
consistent: update the bob key's description field (the "description" value
under the bob entry) in both the main platform-codes.yaml and the installer's
platform-codes.yaml so they match exactly (preserve quoting/formatting), e.g.,
change both to either "IBM's AI development environment" or "IBM's agentic IDE
for AI-powered development".
ab1dd6c to
82411fe
Compare
|
We will be doing a transition soon to most workflows being skills - do you know if this tool has skills support? |
|
Yes, structure as per agentskills.io standard. |
Add IBM Bob (agentic IDE) as a supported IDE platform with custom installer: - Create custom Bob installer (tools/cli/installers/lib/ide/bob.js) - Add .bobmodes to .gitignore - Add platform config to tools/platform-codes.yaml - Register Bob in IDE manager's custom installer list Bob uses a custom installer (like Kilo) that creates a .bobmodes file to register custom modes and writes workflows to .bob/workflows/ Fixes bmad-code-org#1768
- bob.js: fix installCustomAgentLauncher using wrong mode schema (description/prompt/always/permissions → roleDefinition/whenToUse/ customInstructions/groups) - bob.js: add detectionPaths for .bob directory - manager.js: update comments to include bob.js in custom installer list - platform-codes.yaml: move bob entry to correct alphabetical position - eslint.config.mjs: add .bob/** to eslint ignores (like .claude, .roo, etc.)
- Remove leftover '// Made with Bob' debug comment - Guard artifact.sourcePath before calling path.relative() to prevent TypeError - Fix run-on customInstructions string with proper punctuation in createModeObject - Move fs-extra require to top of file; remove inline requires from clearBmadWorkflows/cleanup - Wrap write sequence in try/catch with rollback to prevent partial state on failure - Use metadata.title and metadata.icon in installCustomAgentLauncher instead of ignoring param - Align installCustomAgentLauncher mode object with createModeObject (icon in name, fixed instructions) - Remove unused .bobmodes entry from .gitignore (.bob already covers the directory) - Sync bob description in tools/cli/installers/lib/ide/platform-codes.yaml to match tools/platform-codes.yaml
82411fe to
411219e
Compare
What
Adds IBM Bob (agentic IDE) as a supported platform with a custom installer that creates
.bobmodesand writes workflows to.bob/workflows/.Why
Bob is an IBM agentic IDE that requires a custom installation path similar to Kilo. Without this, BMAD users on Bob have no supported install path.
Fixes #1768
How
tools/cli/installers/lib/ide/bob.js— custom installer using correct Bob mode schema (roleDefinition/whenToUse/customInstructions/groups)tools/cli/installers/lib/ide/manager.jsand add platform config totools/platform-codes.yamlandtools/cli/installers/lib/ide/platform-codes.yaml.bobmodesto.gitignoreand.bob/**to eslint ignoresTesting
Manually tested the installer against a Bob workspace;
.bobmodesand.bob/workflows/are created correctly with valid mode schema.