From 87d82b1cf86497317046f349f0ee368537a6e307 Mon Sep 17 00:00:00 2001 From: Rodney Russ <367748+rdruss@users.noreply.github.com> Date: Fri, 27 Mar 2026 13:13:34 -0600 Subject: [PATCH 1/8] test: add comprehensive tests for Bob Shell adapter - 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 --- test/core/command-generation/adapters.test.ts | 55 ++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/test/core/command-generation/adapters.test.ts b/test/core/command-generation/adapters.test.ts index dab19bf3d..ff89cb2f0 100644 --- a/test/core/command-generation/adapters.test.ts +++ b/test/core/command-generation/adapters.test.ts @@ -4,6 +4,7 @@ import path from 'path'; import { amazonQAdapter } from '../../../src/core/command-generation/adapters/amazon-q.js'; import { antigravityAdapter } from '../../../src/core/command-generation/adapters/antigravity.js'; import { auggieAdapter } from '../../../src/core/command-generation/adapters/auggie.js'; +import { bobAdapter } from '../../../src/core/command-generation/adapters/bob.js'; import { claudeAdapter } from '../../../src/core/command-generation/adapters/claude.js'; import { clineAdapter } from '../../../src/core/command-generation/adapters/cline.js'; import { codexAdapter } from '../../../src/core/command-generation/adapters/codex.js'; @@ -183,6 +184,58 @@ describe('command-generation/adapters', () => { }); }); + + describe('bobAdapter', () => { + it('should have correct toolId', () => { + expect(bobAdapter.toolId).toBe('bob'); + }); + + it('should generate correct file path', () => { + const filePath = bobAdapter.getFilePath('explore'); + expect(filePath).toBe(path.join('.bob', 'commands', 'opsx-explore.md')); + }); + + it('should generate correct file paths for different commands', () => { + expect(bobAdapter.getFilePath('new')).toBe(path.join('.bob', 'commands', 'opsx-new.md')); + expect(bobAdapter.getFilePath('bulk-archive')).toBe(path.join('.bob', 'commands', 'opsx-bulk-archive.md')); + }); + + it('should format file with description frontmatter', () => { + const output = bobAdapter.formatFile(sampleContent); + expect(output).toContain('---\n'); + expect(output).toContain('description: Enter explore mode for thinking'); + expect(output).toContain('---\n\n'); + expect(output).toContain('This is the command body.\n\nWith multiple lines.'); + }); + + it('should escape YAML special characters in description', () => { + const contentWithSpecialChars: CommandContent = { + ...sampleContent, + description: 'Fix: regression in "auth" feature', + }; + const output = bobAdapter.formatFile(contentWithSpecialChars); + expect(output).toContain('description: "Fix: regression in \\"auth\\" feature"'); + }); + + it('should escape newlines in description', () => { + const contentWithNewline: CommandContent = { + ...sampleContent, + description: 'Line 1\nLine 2', + }; + const output = bobAdapter.formatFile(contentWithNewline); + expect(output).toContain('description: "Line 1\\nLine 2"'); + }); + + it('should handle empty description', () => { + const contentEmptyDesc: CommandContent = { + ...sampleContent, + description: '', + }; + const output = bobAdapter.formatFile(contentEmptyDesc); + expect(output).toContain('description: \n'); + }); + }); + describe('clineAdapter', () => { it('should have correct toolId', () => { expect(clineAdapter.toolId).toBe('cline'); @@ -606,7 +659,7 @@ describe('command-generation/adapters', () => { it('All adapters use path.join for paths', () => { // Verify all adapters produce valid paths const adapters = [ - amazonQAdapter, antigravityAdapter, auggieAdapter, clineAdapter, + amazonQAdapter, antigravityAdapter, auggieAdapter, bobAdapter, clineAdapter, codexAdapter, codebuddyAdapter, continueAdapter, costrictAdapter, crushAdapter, factoryAdapter, geminiAdapter, githubCopilotAdapter, iflowAdapter, kilocodeAdapter, opencodeAdapter, piAdapter, qoderAdapter, From 2779a53034e92fa24d1e49c01d36b80cbb243744 Mon Sep 17 00:00:00 2001 From: Rodney Russ <367748+rdruss@users.noreply.github.com> Date: Fri, 27 Mar 2026 13:13:47 -0600 Subject: [PATCH 2/8] feat: add Bob Shell adapter support - 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-.md format - Supports all 11 workflows via custom profile system --- src/core/command-generation/adapters/bob.ts | 47 +++++++++++++++++++ src/core/command-generation/adapters/index.ts | 1 + src/core/command-generation/registry.ts | 2 + src/core/config.ts | 1 + 4 files changed, 51 insertions(+) create mode 100644 src/core/command-generation/adapters/bob.ts diff --git a/src/core/command-generation/adapters/bob.ts b/src/core/command-generation/adapters/bob.ts new file mode 100644 index 000000000..164e21923 --- /dev/null +++ b/src/core/command-generation/adapters/bob.ts @@ -0,0 +1,47 @@ +/** + * Bob Shell Command Adapter + * + * Formats commands for Bob Shell following its markdown specification. + * Commands are stored in .bob/commands/ directory. + */ + +import path from 'path'; +import type { CommandContent, ToolCommandAdapter } from '../types.js'; + +/** + * Escapes a string value for safe YAML output. + * Quotes the string if it contains special YAML characters. + */ +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}"`; + } + return value; +} + +/** + * Bob Shell adapter for command generation. + * File path: .bob/commands/opsx-.md + * Frontmatter: description (optional) + */ +export const bobAdapter: ToolCommandAdapter = { + toolId: 'bob', + + getFilePath(commandId: string): string { + return path.join('.bob', 'commands', `opsx-${commandId}.md`); + }, + + formatFile(content: CommandContent): string { + // Bob Shell supports optional YAML frontmatter with description field + return `--- +description: ${escapeYamlValue(content.description)} +--- + +${content.body} +`; + }, +}; diff --git a/src/core/command-generation/adapters/index.ts b/src/core/command-generation/adapters/index.ts index 06f7a7ae7..18b4f1f25 100644 --- a/src/core/command-generation/adapters/index.ts +++ b/src/core/command-generation/adapters/index.ts @@ -7,6 +7,7 @@ export { amazonQAdapter } from './amazon-q.js'; export { antigravityAdapter } from './antigravity.js'; export { auggieAdapter } from './auggie.js'; +export { bobAdapter } from './bob.js'; export { claudeAdapter } from './claude.js'; export { clineAdapter } from './cline.js'; export { codexAdapter } from './codex.js'; diff --git a/src/core/command-generation/registry.ts b/src/core/command-generation/registry.ts index a69a98adc..a55c3030f 100644 --- a/src/core/command-generation/registry.ts +++ b/src/core/command-generation/registry.ts @@ -9,6 +9,7 @@ import type { ToolCommandAdapter } from './types.js'; import { amazonQAdapter } from './adapters/amazon-q.js'; import { antigravityAdapter } from './adapters/antigravity.js'; import { auggieAdapter } from './adapters/auggie.js'; +import { bobAdapter } from './adapters/bob.js'; import { claudeAdapter } from './adapters/claude.js'; import { clineAdapter } from './adapters/cline.js'; import { codexAdapter } from './adapters/codex.js'; @@ -41,6 +42,7 @@ export class CommandAdapterRegistry { CommandAdapterRegistry.register(amazonQAdapter); CommandAdapterRegistry.register(antigravityAdapter); CommandAdapterRegistry.register(auggieAdapter); + CommandAdapterRegistry.register(bobAdapter); CommandAdapterRegistry.register(claudeAdapter); CommandAdapterRegistry.register(clineAdapter); CommandAdapterRegistry.register(codexAdapter); diff --git a/src/core/config.ts b/src/core/config.ts index f35f92861..af9c3cd7c 100644 --- a/src/core/config.ts +++ b/src/core/config.ts @@ -21,6 +21,7 @@ export const AI_TOOLS: AIToolOption[] = [ { name: 'Amazon Q Developer', value: 'amazon-q', available: true, successLabel: 'Amazon Q Developer', skillsDir: '.amazonq' }, { name: 'Antigravity', value: 'antigravity', available: true, successLabel: 'Antigravity', skillsDir: '.agent' }, { name: 'Auggie (Augment CLI)', value: 'auggie', available: true, successLabel: 'Auggie', skillsDir: '.augment' }, + { name: 'Bob Shell', value: 'bob', available: true, successLabel: 'Bob Shell', skillsDir: '.bob' }, { name: 'Claude Code', value: 'claude', available: true, successLabel: 'Claude Code', skillsDir: '.claude' }, { name: 'Cline', value: 'cline', available: true, successLabel: 'Cline', skillsDir: '.cline' }, { name: 'Codex', value: 'codex', available: true, successLabel: 'Codex', skillsDir: '.codex' }, From b92ab60affb3a56e7e063b8ce6ee19ab5036e0b9 Mon Sep 17 00:00:00 2001 From: Rodney Russ <367748+rdruss@users.noreply.github.com> Date: Fri, 27 Mar 2026 13:13:52 -0600 Subject: [PATCH 3/8] docs: add Bob Shell to supported tools documentation - Add Bob Shell to README.md supported tools list - Update docs/supported-tools.md with Bob Shell entry - Document .bob/commands/opsx-.md command path pattern - Note that Bob Shell uses commands, not Agent Skills spec --- README.md | 2 +- docs/supported-tools.md | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b8af8ca15..45c18bd7e 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ Now tell your AI: `/opsx:propose ` If you want the expanded workflow (`/opsx:new`, `/opsx:continue`, `/opsx:ff`, `/opsx:verify`, `/opsx:sync`, `/opsx:bulk-archive`, `/opsx:onboard`), select it with `openspec config profile` and apply with `openspec update`. > [!NOTE] -> Not sure if your tool is supported? [View the full list](docs/supported-tools.md) – we support 20+ tools and growing. +> Not sure if your tool is supported? [View the full list](docs/supported-tools.md) – we support 25+ tools and growing. > > Also works with pnpm, yarn, bun, and nix. [See installation options](docs/installation.md). diff --git a/docs/supported-tools.md b/docs/supported-tools.md index 524e597f2..7fcf40620 100644 --- a/docs/supported-tools.md +++ b/docs/supported-tools.md @@ -24,6 +24,7 @@ You can enable expanded workflows (`new`, `continue`, `ff`, `verify`, `sync`, `b | Amazon Q Developer (`amazon-q`) | `.amazonq/skills/openspec-*/SKILL.md` | `.amazonq/prompts/opsx-.md` | | Antigravity (`antigravity`) | `.agent/skills/openspec-*/SKILL.md` | `.agent/workflows/opsx-.md` | | Auggie (`auggie`) | `.augment/skills/openspec-*/SKILL.md` | `.augment/commands/opsx-.md` | +| Bob Shell (`bob`) | `.bob/skills/openspec-*/SKILL.md` | `.bob/commands/opsx-.md` | | Claude Code (`claude`) | `.claude/skills/openspec-*/SKILL.md` | `.claude/commands/opsx/.md` | | Cline (`cline`) | `.cline/skills/openspec-*/SKILL.md` | `.clinerules/workflows/opsx-.md` | | CodeBuddy (`codebuddy`) | `.codebuddy/skills/openspec-*/SKILL.md` | `.codebuddy/commands/opsx/.md` | @@ -68,7 +69,7 @@ openspec init --tools none openspec init --profile core ``` -**Available tool IDs (`--tools`):** `amazon-q`, `antigravity`, `auggie`, `claude`, `cline`, `codex`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `gemini`, `github-copilot`, `iflow`, `kilocode`, `kiro`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `windsurf` +**Available tool IDs (`--tools`):** `amazon-q`, `antigravity`, `auggie`, `bob`, `claude`, `cline`, `codex`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `gemini`, `github-copilot`, `iflow`, `kilocode`, `kiro`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `windsurf` ## Workflow-Dependent Installation From ddff3943d98558fe01d20678b9814eef75d514e6 Mon Sep 17 00:00:00 2001 From: Rodney Russ <367748+rdruss@users.noreply.github.com> Date: Fri, 27 Mar 2026 13:13:58 -0600 Subject: [PATCH 4/8] docs: add Bob Shell support proposal and design documentation - 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 --- .../changes/add-bob-shell-support/proposal.md | 225 ++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 openspec/changes/add-bob-shell-support/proposal.md diff --git a/openspec/changes/add-bob-shell-support/proposal.md b/openspec/changes/add-bob-shell-support/proposal.md new file mode 100644 index 000000000..557dad9bb --- /dev/null +++ b/openspec/changes/add-bob-shell-support/proposal.md @@ -0,0 +1,225 @@ +# Add Bob Shell Support to OpenSpec + +## Overview + +Add support for IBM Bob Shell to OpenSpec's multi-tool integration system, enabling Bob Shell users to leverage OpenSpec's workflow commands (`/opsx:propose`, `/opsx:apply`, `/opsx:archive`, etc.) directly within their Bob Shell environment. + +## Motivation + +Bob Shell is IBM's AI coding assistant that supports custom slash commands through markdown files. By integrating Bob Shell into OpenSpec's supported tools list, we enable Bob Shell users to: + +- Use OpenSpec's proven workflow patterns for spec-driven development +- Maintain consistency with teams using other AI tools (Claude Code, Cursor, etc.) +- Leverage OpenSpec's change management and artifact generation capabilities +- Access the full suite of OpenSpec workflows (propose, explore, apply, archive, etc.) + +## Current State + +OpenSpec currently supports 24+ AI coding tools but does not include Bob Shell. The existing architecture uses: +- Tool definitions in `src/core/config.ts` (AI_TOOLS array) +- Command adapters in `src/core/command-generation/adapters/` +- A registry system for adapter lookup +- Tool-specific file path and format generation + +## Proposed Changes + +### 1. Bob Shell Command Structure + +Based on Bob Shell documentation: + +**Directory Structure:** +- Project commands: `.bob/commands/` +- Global commands: `~/.bob/commands/` (not used by OpenSpec) + +**File Format:** +- Extension: `.md` (Markdown) +- Naming: `command-name.md` → `/command-name` slash command +- Optional YAML frontmatter for metadata + +**Frontmatter Fields:** +```yaml +--- +description: Brief description shown in command menu +argument-hint: # Optional, for commands with arguments +--- +``` + +**Example Command File:** +```markdown +--- +description: Create a new OpenSpec change proposal +argument-hint: +--- + +Create a new OpenSpec change proposal for: $1 + +Follow the OpenSpec workflow to: +1. Create the change directory structure +2. Generate proposal.md with problem statement and goals +3. Create specs/ directory for requirements +4. Generate design.md for technical approach +5. Create tasks.md with implementation checklist +``` + +### 2. Integration Approach + +**Add Bob Shell to AI_TOOLS** (`src/core/config.ts`): +```typescript +{ + name: 'Bob Shell', + value: 'bob', + available: true, + successLabel: 'Bob Shell', + skillsDir: '.bob' +} +``` + +**Create Bob Shell Adapter** (`src/core/command-generation/adapters/bob.ts`): +```typescript +export const bobAdapter: ToolCommandAdapter = { + toolId: 'bob', + + getFilePath(commandId: string): string { + return path.join('.bob', 'commands', `${commandId}.md`); + }, + + formatFile(content: CommandContent): string { + // Generate frontmatter + body + return `--- +description: ${content.description} +--- + +${content.body} +`; + }, +}; +``` + +**Register Adapter** (update `src/core/command-generation/registry.ts`): +- Import bobAdapter +- Add to registry map + +**Export Adapter** (update `src/core/command-generation/adapters/index.ts`): +- Export bobAdapter + +### 3. Command Generation + +OpenSpec will generate Bob Shell command files for each workflow: + +**Core Profile Commands:** +- `.bob/commands/opsx-propose.md` → `/opsx-propose` +- `.bob/commands/opsx-explore.md` → `/opsx-explore` +- `.bob/commands/opsx-apply.md` → `/opsx-apply` +- `.bob/commands/opsx-archive.md` → `/opsx-archive` + +**Expanded Profile Commands (when enabled):** +- `.bob/commands/opsx-new.md` → `/opsx-new` +- `.bob/commands/opsx-continue.md` → `/opsx-continue` +- `.bob/commands/opsx-ff.md` → `/opsx-ff` +- `.bob/commands/opsx-verify.md` → `/opsx-verify` +- `.bob/commands/opsx-sync.md` → `/opsx-sync` +- `.bob/commands/opsx-bulk-archive.md` → `/opsx-bulk-archive` +- `.bob/commands/opsx-onboard.md` → `/opsx-onboard` + +### 4. Documentation Updates + +**Update `docs/supported-tools.md`:** +- Add Bob Shell to the tools table +- Document directory structure: `.bob/commands/opsx-.md` +- Note: Bob Shell does not use the Agent Skills spec, only custom commands +- Explain that commands appear as `/opsx-propose`, `/opsx-apply`, etc. + +**Update `README.md`:** +- Add Bob Shell to the list of supported tools +- Update tool count (24+ → 25+) + +### 5. Skills Directory Consideration + +Bob Shell supports custom modes in `.bob/modes/` with XML rule files (as seen in the mode.yaml example). However, OpenSpec's current skill generation follows the Agent Skills specification which may not align with Bob Shell's mode system. + +**Decision:** +- **Phase 1**: Only generate command files (`.bob/commands/`) +- **Phase 2** (future): Evaluate if OpenSpec skills should be converted to Bob Shell modes + +**Rationale:** +- Commands provide immediate value and are simpler to implement +- Bob Shell's mode system is more complex (XML rules, custom structure) +- Commands are sufficient for OpenSpec's workflow invocation needs +- Can revisit mode integration based on user feedback + +## Implementation Plan + +### Phase 1: Core Integration +1. Add Bob Shell to AI_TOOLS array +2. Create Bob Shell command adapter +3. Register and export adapter +4. Test command generation with `openspec init --tools bob` +5. Verify generated command files work in Bob Shell + +### Phase 2: Documentation +1. Update supported-tools.md with Bob Shell details +2. Update README.md to include Bob Shell +3. Add Bob Shell examples to getting-started.md (if applicable) + +### Phase 3: Testing +1. Manual testing with Bob Shell installation +2. Verify all workflow commands generate correctly +3. Test command invocation in Bob Shell +4. Validate frontmatter parsing +5. Test profile switching (core → expanded) + +## Success Criteria + +- [ ] Bob Shell appears in `openspec init` tool selection +- [ ] Running `openspec init --tools bob` generates `.bob/commands/` directory +- [ ] All core workflow commands generate with correct format +- [ ] Generated commands work when invoked in Bob Shell (e.g., `/opsx-propose`) +- [ ] Documentation accurately describes Bob Shell integration +- [ ] `openspec update` regenerates Bob Shell commands correctly +- [ ] Profile switching updates Bob Shell commands appropriately + +## Testing Strategy + +### Manual Testing +1. Install OpenSpec in a test project +2. Run `openspec init --tools bob` +3. Verify `.bob/commands/` directory created +4. Check generated command files for correct format +5. Open project in Bob Shell +6. Type `/` and verify OpenSpec commands appear +7. Invoke `/opsx-propose test-feature` and verify behavior +8. Test other workflow commands + +### Automated Testing +- Add unit tests for Bob Shell adapter +- Test command file generation +- Verify frontmatter formatting +- Test file path generation + +## Risks and Mitigations + +**Risk**: Bob Shell command format changes +**Mitigation**: Monitor Bob Shell documentation, version adapter if needed + +**Risk**: Frontmatter parsing issues in Bob Shell +**Mitigation**: Test with various frontmatter configurations, keep format simple + +**Risk**: Command naming conflicts with existing Bob Shell commands +**Mitigation**: Use `opsx-` prefix consistently, document in supported-tools.md + +**Risk**: Skills vs. Commands confusion +**Mitigation**: Clearly document that OpenSpec uses commands, not modes (Phase 1) + +## Future Enhancements + +1. **Bob Shell Mode Integration**: Convert OpenSpec skills to Bob Shell modes with XML rules +2. **Argument Support**: Add argument hints for commands that accept parameters +3. **Global Commands**: Option to install commands globally in `~/.bob/commands/` +4. **Mode-Aware Commands**: Commands that switch Bob Shell to appropriate mode before execution + +## References + +- Bob Shell Documentation: https://bob.ibm.com/docs/shell +- Bob Shell Slash Commands: https://bob.ibm.com/docs/shell/features/slash-commands +- OpenSpec Command Generation: `src/core/command-generation/` +- OpenSpec Tool Configuration: `src/core/config.ts` From 46ecebc18b3a84703eb9919c499bb887209990c9 Mon Sep 17 00:00:00 2001 From: Rodney Russ <367748+rdruss@users.noreply.github.com> Date: Fri, 27 Mar 2026 13:15:53 -0600 Subject: [PATCH 5/8] chore: update dependencies and gitignore - Update package-lock.json with latest dependencies - Add .bob/ to gitignore (test output directory) --- .gitignore | 1 + package-lock.json | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 3a952f090..3484450ac 100644 --- a/.gitignore +++ b/.gitignore @@ -156,3 +156,4 @@ opencode.json # Codex .codex/ +.bob/ diff --git a/package-lock.json b/package-lock.json index e1daf932f..03dad207d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@fission-ai/openspec", - "version": "1.1.1", + "version": "1.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@fission-ai/openspec", - "version": "1.1.1", + "version": "1.2.0", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -1803,6 +1803,7 @@ "integrity": "sha512-oH72nZRfDv9lADUBSo104Aq7gPHpQZc4BTx38r9xf9pg5LfP6EzSyH2n7qFmmxRQXh7YlUXODcYsg6PuTDSxGg==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -1852,6 +1853,7 @@ "integrity": "sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.56.0", "@typescript-eslint/types": "8.56.0", @@ -2182,6 +2184,7 @@ "integrity": "sha512-hGISOaP18plkzbWEcP/QvtRW1xDXF2+96HbEX6byqQhAUbiS5oH6/9JwW+QsQCIYON2bI6QZBF+2PvOmrRZ9wA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@vitest/utils": "3.2.4", "fflate": "^0.8.2", @@ -2219,6 +2222,7 @@ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2685,6 +2689,7 @@ "integrity": "sha512-VmQ+sifHUbI/IcSopBCF/HO3YiHQx/AVd3UVyYL6weuwW+HvON9VYn5l6Zl1WZzPWXPNZrSQpxwkkZ/VuvJZzg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -4448,6 +4453,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -4546,6 +4552,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -4611,6 +4618,7 @@ "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -4727,6 +4735,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -4740,6 +4749,7 @@ "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.4", @@ -4919,6 +4929,7 @@ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", "license": "ISC", + "peer": true, "bin": { "yaml": "bin.mjs" }, From a6d45832c107a8459e312cdeceecd1edc12d73cc Mon Sep 17 00:00:00 2001 From: Rodney Russ <367748+rdruss@users.noreply.github.com> Date: Fri, 27 Mar 2026 13:46:46 -0600 Subject: [PATCH 6/8] chore: update gitignore to exclude .bob directory --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 3484450ac..3ed26016a 100644 --- a/.gitignore +++ b/.gitignore @@ -156,4 +156,6 @@ opencode.json # Codex .codex/ + +# Bob .bob/ From e99889d7cc8c245d67f79b8594970ce01292191d Mon Sep 17 00:00:00 2001 From: Rodney Russ <367748+rdruss@users.noreply.github.com> Date: Fri, 27 Mar 2026 13:53:16 -0600 Subject: [PATCH 7/8] openspec change not needed for project, should be kept local --- .../changes/add-bob-shell-support/proposal.md | 225 ------------------ 1 file changed, 225 deletions(-) delete mode 100644 openspec/changes/add-bob-shell-support/proposal.md diff --git a/openspec/changes/add-bob-shell-support/proposal.md b/openspec/changes/add-bob-shell-support/proposal.md deleted file mode 100644 index 557dad9bb..000000000 --- a/openspec/changes/add-bob-shell-support/proposal.md +++ /dev/null @@ -1,225 +0,0 @@ -# Add Bob Shell Support to OpenSpec - -## Overview - -Add support for IBM Bob Shell to OpenSpec's multi-tool integration system, enabling Bob Shell users to leverage OpenSpec's workflow commands (`/opsx:propose`, `/opsx:apply`, `/opsx:archive`, etc.) directly within their Bob Shell environment. - -## Motivation - -Bob Shell is IBM's AI coding assistant that supports custom slash commands through markdown files. By integrating Bob Shell into OpenSpec's supported tools list, we enable Bob Shell users to: - -- Use OpenSpec's proven workflow patterns for spec-driven development -- Maintain consistency with teams using other AI tools (Claude Code, Cursor, etc.) -- Leverage OpenSpec's change management and artifact generation capabilities -- Access the full suite of OpenSpec workflows (propose, explore, apply, archive, etc.) - -## Current State - -OpenSpec currently supports 24+ AI coding tools but does not include Bob Shell. The existing architecture uses: -- Tool definitions in `src/core/config.ts` (AI_TOOLS array) -- Command adapters in `src/core/command-generation/adapters/` -- A registry system for adapter lookup -- Tool-specific file path and format generation - -## Proposed Changes - -### 1. Bob Shell Command Structure - -Based on Bob Shell documentation: - -**Directory Structure:** -- Project commands: `.bob/commands/` -- Global commands: `~/.bob/commands/` (not used by OpenSpec) - -**File Format:** -- Extension: `.md` (Markdown) -- Naming: `command-name.md` → `/command-name` slash command -- Optional YAML frontmatter for metadata - -**Frontmatter Fields:** -```yaml ---- -description: Brief description shown in command menu -argument-hint: # Optional, for commands with arguments ---- -``` - -**Example Command File:** -```markdown ---- -description: Create a new OpenSpec change proposal -argument-hint: ---- - -Create a new OpenSpec change proposal for: $1 - -Follow the OpenSpec workflow to: -1. Create the change directory structure -2. Generate proposal.md with problem statement and goals -3. Create specs/ directory for requirements -4. Generate design.md for technical approach -5. Create tasks.md with implementation checklist -``` - -### 2. Integration Approach - -**Add Bob Shell to AI_TOOLS** (`src/core/config.ts`): -```typescript -{ - name: 'Bob Shell', - value: 'bob', - available: true, - successLabel: 'Bob Shell', - skillsDir: '.bob' -} -``` - -**Create Bob Shell Adapter** (`src/core/command-generation/adapters/bob.ts`): -```typescript -export const bobAdapter: ToolCommandAdapter = { - toolId: 'bob', - - getFilePath(commandId: string): string { - return path.join('.bob', 'commands', `${commandId}.md`); - }, - - formatFile(content: CommandContent): string { - // Generate frontmatter + body - return `--- -description: ${content.description} ---- - -${content.body} -`; - }, -}; -``` - -**Register Adapter** (update `src/core/command-generation/registry.ts`): -- Import bobAdapter -- Add to registry map - -**Export Adapter** (update `src/core/command-generation/adapters/index.ts`): -- Export bobAdapter - -### 3. Command Generation - -OpenSpec will generate Bob Shell command files for each workflow: - -**Core Profile Commands:** -- `.bob/commands/opsx-propose.md` → `/opsx-propose` -- `.bob/commands/opsx-explore.md` → `/opsx-explore` -- `.bob/commands/opsx-apply.md` → `/opsx-apply` -- `.bob/commands/opsx-archive.md` → `/opsx-archive` - -**Expanded Profile Commands (when enabled):** -- `.bob/commands/opsx-new.md` → `/opsx-new` -- `.bob/commands/opsx-continue.md` → `/opsx-continue` -- `.bob/commands/opsx-ff.md` → `/opsx-ff` -- `.bob/commands/opsx-verify.md` → `/opsx-verify` -- `.bob/commands/opsx-sync.md` → `/opsx-sync` -- `.bob/commands/opsx-bulk-archive.md` → `/opsx-bulk-archive` -- `.bob/commands/opsx-onboard.md` → `/opsx-onboard` - -### 4. Documentation Updates - -**Update `docs/supported-tools.md`:** -- Add Bob Shell to the tools table -- Document directory structure: `.bob/commands/opsx-.md` -- Note: Bob Shell does not use the Agent Skills spec, only custom commands -- Explain that commands appear as `/opsx-propose`, `/opsx-apply`, etc. - -**Update `README.md`:** -- Add Bob Shell to the list of supported tools -- Update tool count (24+ → 25+) - -### 5. Skills Directory Consideration - -Bob Shell supports custom modes in `.bob/modes/` with XML rule files (as seen in the mode.yaml example). However, OpenSpec's current skill generation follows the Agent Skills specification which may not align with Bob Shell's mode system. - -**Decision:** -- **Phase 1**: Only generate command files (`.bob/commands/`) -- **Phase 2** (future): Evaluate if OpenSpec skills should be converted to Bob Shell modes - -**Rationale:** -- Commands provide immediate value and are simpler to implement -- Bob Shell's mode system is more complex (XML rules, custom structure) -- Commands are sufficient for OpenSpec's workflow invocation needs -- Can revisit mode integration based on user feedback - -## Implementation Plan - -### Phase 1: Core Integration -1. Add Bob Shell to AI_TOOLS array -2. Create Bob Shell command adapter -3. Register and export adapter -4. Test command generation with `openspec init --tools bob` -5. Verify generated command files work in Bob Shell - -### Phase 2: Documentation -1. Update supported-tools.md with Bob Shell details -2. Update README.md to include Bob Shell -3. Add Bob Shell examples to getting-started.md (if applicable) - -### Phase 3: Testing -1. Manual testing with Bob Shell installation -2. Verify all workflow commands generate correctly -3. Test command invocation in Bob Shell -4. Validate frontmatter parsing -5. Test profile switching (core → expanded) - -## Success Criteria - -- [ ] Bob Shell appears in `openspec init` tool selection -- [ ] Running `openspec init --tools bob` generates `.bob/commands/` directory -- [ ] All core workflow commands generate with correct format -- [ ] Generated commands work when invoked in Bob Shell (e.g., `/opsx-propose`) -- [ ] Documentation accurately describes Bob Shell integration -- [ ] `openspec update` regenerates Bob Shell commands correctly -- [ ] Profile switching updates Bob Shell commands appropriately - -## Testing Strategy - -### Manual Testing -1. Install OpenSpec in a test project -2. Run `openspec init --tools bob` -3. Verify `.bob/commands/` directory created -4. Check generated command files for correct format -5. Open project in Bob Shell -6. Type `/` and verify OpenSpec commands appear -7. Invoke `/opsx-propose test-feature` and verify behavior -8. Test other workflow commands - -### Automated Testing -- Add unit tests for Bob Shell adapter -- Test command file generation -- Verify frontmatter formatting -- Test file path generation - -## Risks and Mitigations - -**Risk**: Bob Shell command format changes -**Mitigation**: Monitor Bob Shell documentation, version adapter if needed - -**Risk**: Frontmatter parsing issues in Bob Shell -**Mitigation**: Test with various frontmatter configurations, keep format simple - -**Risk**: Command naming conflicts with existing Bob Shell commands -**Mitigation**: Use `opsx-` prefix consistently, document in supported-tools.md - -**Risk**: Skills vs. Commands confusion -**Mitigation**: Clearly document that OpenSpec uses commands, not modes (Phase 1) - -## Future Enhancements - -1. **Bob Shell Mode Integration**: Convert OpenSpec skills to Bob Shell modes with XML rules -2. **Argument Support**: Add argument hints for commands that accept parameters -3. **Global Commands**: Option to install commands globally in `~/.bob/commands/` -4. **Mode-Aware Commands**: Commands that switch Bob Shell to appropriate mode before execution - -## References - -- Bob Shell Documentation: https://bob.ibm.com/docs/shell -- Bob Shell Slash Commands: https://bob.ibm.com/docs/shell/features/slash-commands -- OpenSpec Command Generation: `src/core/command-generation/` -- OpenSpec Tool Configuration: `src/core/config.ts` From 0da36ff2bfb5e01481d30c0fa4cdfa9cb2cc1957 Mon Sep 17 00:00:00 2001 From: Rodney Russ <367748+rdruss@users.noreply.github.com> Date: Fri, 27 Mar 2026 14:31:28 -0600 Subject: [PATCH 8/8] Update reference from Bob Shell to IBM Bob Shell --- docs/supported-tools.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/supported-tools.md b/docs/supported-tools.md index 7fcf40620..888b513dd 100644 --- a/docs/supported-tools.md +++ b/docs/supported-tools.md @@ -24,7 +24,7 @@ You can enable expanded workflows (`new`, `continue`, `ff`, `verify`, `sync`, `b | Amazon Q Developer (`amazon-q`) | `.amazonq/skills/openspec-*/SKILL.md` | `.amazonq/prompts/opsx-.md` | | Antigravity (`antigravity`) | `.agent/skills/openspec-*/SKILL.md` | `.agent/workflows/opsx-.md` | | Auggie (`auggie`) | `.augment/skills/openspec-*/SKILL.md` | `.augment/commands/opsx-.md` | -| Bob Shell (`bob`) | `.bob/skills/openspec-*/SKILL.md` | `.bob/commands/opsx-.md` | +| IBM Bob Shell (`bob`) | `.bob/skills/openspec-*/SKILL.md` | `.bob/commands/opsx-.md` | | Claude Code (`claude`) | `.claude/skills/openspec-*/SKILL.md` | `.claude/commands/opsx/.md` | | Cline (`cline`) | `.cline/skills/openspec-*/SKILL.md` | `.clinerules/workflows/opsx-.md` | | CodeBuddy (`codebuddy`) | `.codebuddy/skills/openspec-*/SKILL.md` | `.codebuddy/commands/opsx/.md` |