Skip to content

feat: add support for IBM Bob coding assistant#886

Merged
TabishB merged 11 commits intoFission-AI:mainfrom
rdruss:feat/bob-support
Apr 11, 2026
Merged

feat: add support for IBM Bob coding assistant#886
TabishB merged 11 commits intoFission-AI:mainfrom
rdruss:feat/bob-support

Conversation

@rdruss
Copy link
Copy Markdown
Contributor

@rdruss rdruss commented Mar 27, 2026

Add support for IBM's AI coding assistant, Bob, to OpenSpec

Summary by CodeRabbit

  • New Features

    • Bob Shell is now supported for generating commands and installing skills.
  • Chores

    • Added Bob Shell config directory to ignore rules.
    • Updated docs to include Bob Shell and increased supported-tools count from 20+ to 25+.
  • Tests

    • Added tests for Bob Shell command formatting, file paths, and YAML escaping.

rdruss added 7 commits March 27, 2026 13:13
- Add 7 tests covering toolId, file paths, formatting, and edge cases
- Include Bob Shell adapter in cross-platform path handling tests
- All 89 adapter tests now passing
- Ensures Bob Shell adapter works correctly with all 11 workflows
- Implement Bob Shell command adapter with YAML frontmatter
- Register adapter in CommandAdapterRegistry
- Export adapter from adapters/index.ts
- Add Bob Shell to AI_TOOLS configuration
- Generates commands in .bob/commands/opsx-<id>.md format
- Supports all 11 workflows via custom profile system
- Add Bob Shell to README.md supported tools list
- Update docs/supported-tools.md with Bob Shell entry
- Document .bob/commands/opsx-<id>.md command path pattern
- Note that Bob Shell uses commands, not Agent Skills spec
- Add comprehensive proposal for Bob Shell integration
- Document command structure and file format
- Include implementation plan and success criteria
- Preserve change documentation for future reference
- Update package-lock.json with latest dependencies
- Add .bob/ to gitignore (test output directory)
@rdruss rdruss requested a review from TabishB as a code owner March 27, 2026 20:15
Copy link
Copy Markdown

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 27, 2026

📝 Walkthrough

Walkthrough

Adds Bob Shell as a supported command-generation tool: new adapter implementation, re-export and registry registration, config and docs updates, tests, and .bob/ ignored in .gitignore.

Changes

Cohort / File(s) Summary
Ignore & Docs
\.gitignore, README.md, docs/supported-tools.md
Added .bob/ to .gitignore, updated README tool count to "25+ tools", and documented bob in supported tools with skills/commands install path patterns and tool ID.
Configuration
src/core/config.ts
Added Bob Shell entry to AI_TOOLS (value: 'bob', skillsDir: '.bob', available: true).
Adapter Implementation
src/core/command-generation/adapters/bob.ts
New bobAdapter exporting toolId: 'bob', getFilePath(commandId).bob/commands/opsx-${commandId}.md, formatFile(content) that YAML-escapes description, includes argument-hint, and transforms command references to hyphenated form.
Adapter Exports & Registry
src/core/command-generation/adapters/index.ts, src/core/command-generation/registry.ts
Re-exported bobAdapter and registered it with CommandAdapterRegistry.
Tests
test/core/command-generation/adapters.test.ts
Added tests for bobAdapter verifying toolId, path format, YAML frontmatter escaping (quotes, newlines, empty), command reference transformation, and inclusion in shared path assertions.

Sequence Diagram(s)

sequenceDiagram
  participant CLI as "CLI/Invoker"
  participant Gen as "CommandGenerator"
  participant Reg as "AdapterRegistry"
  participant Adapter as "bobAdapter"
  participant FS as "Filesystem"

  CLI->>Gen: request generate command (toolId:'bob', id, content)
  Gen->>Reg: resolve adapter for 'bob'
  Reg-->>Gen: returns bobAdapter
  Gen->>Adapter: getFilePath(commandId)
  Adapter-->>Gen: ".bob/commands/opsx-<id>.md"
  Gen->>Adapter: formatFile(content)
  Adapter-->>Gen: formatted Markdown (YAML frontmatter + body)
  Gen->>FS: write file at ".bob/commands/opsx-<id>.md"
  FS-->>Gen: write success
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Poem

🐰 I found a burrow called .bob/ bright,
New adapter hops in, YAML tucked tight,
Commands turn hyphens, paths sleep at night,
Tests nod approval, docs glow with light,
Twenty-five tools now leap in delight.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add support for IBM Bob coding assistant' directly and clearly summarizes the main change: adding support for a new tool (IBM Bob) to the codebase.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
README.md (1)

106-106: Prefer count-agnostic wording to avoid future drift.

Line 106 hardcodes “25+ tools,” which can get out of sync with other README sections and docs. Consider wording that doesn’t require manual recounts.

📝 Suggested edit
-> Not sure if your tool is supported? [View the full list](docs/supported-tools.md) – we support 25+ tools and growing.
+> Not sure if your tool is supported? [View the full list](docs/supported-tools.md) – we support many tools and growing.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` at line 106, Replace the hardcoded phrase "25+ tools" in the
README line that reads "Not sure if your tool is supported? [View the full
list](docs/supported-tools.md) – we support 25+ tools and growing." with
count-agnostic wording such as "many tools," "a growing list of tools," or
"dozens of tools" to avoid drift; update the text surrounding the link so it
reads e.g. "Not sure if your tool is supported? View the full list — we support
a growing roster of tools." and ensure the link target (docs/supported-tools.md)
remains unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/core/command-generation/adapters/bob.ts`:
- Around line 15-21: The escapeYamlValue function currently replaces
backslashes, double quotes, and newlines but omits carriage returns; update
escapeYamlValue so it also escapes '\r' when serializing YAML (e.g., add a
replacement for /\r/g to produce '\\r' in the same escape chain used for
value.replace(...)). Ensure the function still wraps the escaped string in
double quotes and preserves the existing escapes for backslashes, quotes, and
newlines.

---

Nitpick comments:
In `@README.md`:
- Line 106: Replace the hardcoded phrase "25+ tools" in the README line that
reads "Not sure if your tool is supported? [View the full
list](docs/supported-tools.md) – we support 25+ tools and growing." with
count-agnostic wording such as "many tools," "a growing list of tools," or
"dozens of tools" to avoid drift; update the text surrounding the link so it
reads e.g. "Not sure if your tool is supported? View the full list — we support
a growing roster of tools." and ensure the link target (docs/supported-tools.md)
remains unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a0738528-ec68-436f-96bb-9f5c7832c974

📥 Commits

Reviewing files that changed from the base of the PR and between afdca0d and e99889d.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (8)
  • .gitignore
  • README.md
  • docs/supported-tools.md
  • src/core/command-generation/adapters/bob.ts
  • src/core/command-generation/adapters/index.ts
  • src/core/command-generation/registry.ts
  • src/core/config.ts
  • test/core/command-generation/adapters.test.ts

Comment on lines +15 to +21
function escapeYamlValue(value: string): string {
// Check if value needs quoting (contains special YAML characters or starts/ends with whitespace)
const needsQuoting = /[:\n\r#{}[\],&*!|>'"%@`]|^\s|\s$/.test(value);
if (needsQuoting) {
// Use double quotes and escape internal double quotes and backslashes
const escaped = value.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n');
return `"${escaped}"`;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Escape \r as well when serializing YAML description.

escapeYamlValue flags carriage returns at Line 17, but Line 20 doesn’t escape them. That can produce malformed or parser-dependent frontmatter on CRLF input.

🔧 Suggested fix
-    const escaped = value.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n');
+    const escaped = value
+      .replace(/\\/g, '\\\\')
+      .replace(/"/g, '\\"')
+      .replace(/\r/g, '\\r')
+      .replace(/\n/g, '\\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.

Suggested change
function escapeYamlValue(value: string): string {
// Check if value needs quoting (contains special YAML characters or starts/ends with whitespace)
const needsQuoting = /[:\n\r#{}[\],&*!|>'"%@`]|^\s|\s$/.test(value);
if (needsQuoting) {
// Use double quotes and escape internal double quotes and backslashes
const escaped = value.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n');
return `"${escaped}"`;
function escapeYamlValue(value: string): string {
// Check if value needs quoting (contains special YAML characters or starts/ends with whitespace)
const needsQuoting = /[:\n\r#{}[\],&*!|>'"%@`]|^\s|\s$/.test(value);
if (needsQuoting) {
// Use double quotes and escape internal double quotes and backslashes
const escaped = value
.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"')
.replace(/\r/g, '\\r')
.replace(/\n/g, '\\n');
return `"${escaped}"`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/core/command-generation/adapters/bob.ts` around lines 15 - 21, The
escapeYamlValue function currently replaces backslashes, double quotes, and
newlines but omits carriage returns; update escapeYamlValue so it also escapes
'\r' when serializing YAML (e.g., add a replacement for /\r/g to produce '\\r'
in the same escape chain used for value.replace(...)). Ensure the function still
wraps the escaped string in double quotes and preserves the existing escapes for
backslashes, quotes, and newlines.

@rdruss rdruss changed the title Bob coding assistant support feat: add support for IBM Bob coding assistant Mar 31, 2026
TabishB added 2 commits April 12, 2026 01:18
Bob derives command names from filenames (opsx-apply.md → /opsx-apply),
so body text referencing /opsx:apply is incorrect. Apply the same
transformToHyphenCommands rewrite that opencode.ts uses. Also add
argument-hint frontmatter to match peer adapters (auggie, codebuddy, etc).
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
src/core/command-generation/adapters/bob.ts (1)

16-24: ⚠️ Potential issue | 🟡 Minor

Escape \r and preserve empty-string YAML semantics.

At Line 21, \r is not escaped, and at Line 24 an empty description serializes as description: (YAML null), not an empty string.

🔧 Proposed fix
 function escapeYamlValue(value: string): string {
+  if (value.length === 0) {
+    return '""';
+  }
   // Check if value needs quoting (contains special YAML characters or starts/ends with whitespace)
   const needsQuoting = /[:\n\r#{}[\],&*!|>'"%@`]|^\s|\s$/.test(value);
   if (needsQuoting) {
     // Use double quotes and escape internal double quotes and backslashes
-    const escaped = value.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n');
+    const escaped = value
+      .replace(/\\/g, '\\\\')
+      .replace(/"/g, '\\"')
+      .replace(/\r/g, '\\r')
+      .replace(/\n/g, '\\n');
     return `"${escaped}"`;
   }
   return value;
 }
#!/bin/bash
# Verify current escape chain and empty-description expectation
rg -n -C2 'function escapeYamlValue|replace\(/\\\\/g|replace\(/\\"/g|replace\(/\\n/g|replace\(/\\r/g|return value;' src/core/command-generation/adapters/bob.ts
rg -n -C2 'empty description|description: \\n|description: ""|\\r' test/core/command-generation/adapters.test.ts
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/core/command-generation/adapters/bob.ts` around lines 16 - 24, The
escapeYamlValue function currently doesn't escape carriage returns and allows
empty strings to serialize as YAML null; update escapeYamlValue to include '\r'
in the needsQuoting regex (add \r to /[:\n\r#{}[\],&*!|>'"%@`]|^\s|\s$/) and add
a replace for /\r/g to the escape chain (e.g., .replace(/\r/g, '\\r')) and
ensure that when value === '' you return '""' (an explicit empty-string YAML
value) instead of value so empty descriptions serialize as description: "".
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/core/command-generation/adapters/bob.ts`:
- Around line 16-24: The escapeYamlValue function currently doesn't escape
carriage returns and allows empty strings to serialize as YAML null; update
escapeYamlValue to include '\r' in the needsQuoting regex (add \r to
/[:\n\r#{}[\],&*!|>'"%@`]|^\s|\s$/) and add a replace for /\r/g to the escape
chain (e.g., .replace(/\r/g, '\\r')) and ensure that when value === '' you
return '""' (an explicit empty-string YAML value) instead of value so empty
descriptions serialize as description: "".

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 04351423-41e4-493e-8847-2fda3a4ce665

📥 Commits

Reviewing files that changed from the base of the PR and between 0da36ff and 30348d5.

📒 Files selected for processing (6)
  • docs/supported-tools.md
  • src/core/command-generation/adapters/bob.ts
  • src/core/command-generation/adapters/index.ts
  • src/core/command-generation/registry.ts
  • src/core/config.ts
  • test/core/command-generation/adapters.test.ts
✅ Files skipped from review due to trivial changes (2)
  • src/core/command-generation/registry.ts
  • docs/supported-tools.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/core/command-generation/adapters/index.ts
  • src/core/config.ts

@TabishB TabishB enabled auto-merge April 11, 2026 15:26
@TabishB TabishB added this pull request to the merge queue Apr 11, 2026
Merged via the queue into Fission-AI:main with commit 94d651d Apr 11, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants