-
Notifications
You must be signed in to change notification settings - Fork 1.4k
fix(opencode): transform command references from colon to hyphen format #626
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
TabishB
merged 3 commits into
Fission-AI:main
from
webrgp:fix/opencode-command-references
Jan 30, 2026
+342
−7
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -149,3 +149,7 @@ CLAUDE.md | |
| # Pnpm | ||
| .pnpm-store/ | ||
| result | ||
|
|
||
| # OpenCode | ||
| .opencode/ | ||
| opencode.json | ||
2 changes: 2 additions & 0 deletions
2
openspec/changes/archive/2026-01-30-opencode-command-references/.openspec.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| schema: spec-driven | ||
| created: 2026-01-30 |
3 changes: 3 additions & 0 deletions
3
openspec/changes/archive/2026-01-30-opencode-command-references/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| # opencode-command-references | ||
|
|
||
| Transform /opsx: to /opsx- in both commands and skills for OpenCode |
70 changes: 70 additions & 0 deletions
70
openspec/changes/archive/2026-01-30-opencode-command-references/design.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| ## Context | ||
|
|
||
| OpenCode is one of many supported AI tools. Each tool has: | ||
| - A **command adapter** (in `src/core/command-generation/adapters/`) for generating tool-specific command files | ||
| - **Skills** generated via `generateSkillContent()` in `src/core/shared/skill-generation.ts` | ||
|
|
||
| Currently: | ||
| - Commands go through the adapter system which can transform content per-tool | ||
| - Skills use a single shared function with no tool-specific transformation | ||
|
|
||
| The templates in `src/core/templates/skill-templates.ts` use Claude's colon-based format (`/opsx:new`) as the canonical format. Tools that use different formats need transformation at generation time. | ||
|
|
||
| ## Goals / Non-Goals | ||
|
|
||
| **Goals:** | ||
| - Transform all `/opsx:` command references to `/opsx-` for OpenCode in both commands and skills | ||
| - Create a shared, reusable transformation utility | ||
| - Keep the transformation opt-in via a callback parameter (not hard-coded tool detection) | ||
|
|
||
| **Non-Goals:** | ||
| - Modifying the canonical template format (templates stay with `/opsx:`) | ||
| - Applying transformation to other tools (only OpenCode for now) | ||
| - Creating a full adapter system for skills (overkill for current needs) | ||
|
|
||
| ## Decisions | ||
|
|
||
| ### Decision 1: Shared Utility Function | ||
|
|
||
| **Choice**: Create `transformToHyphenCommands()` in `src/utils/command-references.ts` | ||
|
|
||
| **Rationale**: | ||
| - Single source of truth for the transformation logic | ||
| - Can be used by both command adapter and skill generation | ||
| - Easy to test in isolation | ||
| - Follows existing utils pattern in the codebase | ||
|
|
||
| **Alternatives considered**: | ||
| - Inline the transformation in each location - Duplicates logic, harder to maintain | ||
|
|
||
| ### Decision 2: Callback Parameter for Skill Generation | ||
|
|
||
| **Choice**: Add optional `transformInstructions?: (instructions: string) => string` parameter to `generateSkillContent()` | ||
|
|
||
| **Rationale**: | ||
| - Flexible - callers define the transformation, not the generation function | ||
| - No coupling - `generateSkillContent()` doesn't need to know about tool formats | ||
| - Extensible - could support other transformations in the future | ||
| - Follows inversion of control principle | ||
|
|
||
| **Alternatives considered**: | ||
| - Add tool ID parameter and switch on it - Creates coupling, harder to extend | ||
| - Create skill adapter system parallel to commands - Over-engineering for current needs | ||
| - Transform in templates directly - Breaks single-source-of-truth principle | ||
|
|
||
| ### Decision 3: Apply at Generation Sites | ||
|
|
||
| **Choice**: Pass transformer in `init.ts` and `update.ts` when `tool.value === 'opencode'` | ||
|
|
||
| **Rationale**: | ||
| - These are the only two places that generate skills | ||
| - Simple conditional check, no new abstractions needed | ||
| - Easy to extend to other tools if needed later | ||
|
|
||
| ## Risks / Trade-offs | ||
|
|
||
| | Risk | Mitigation | | ||
| |------|------------| | ||
| | Other `/opsx:` patterns exist that shouldn't be transformed | All occurrences in templates are command invocations - verified by inspection | | ||
| | Future tools may need same transformation | Utility is shared and easy to reuse; can add to other tools' generation | | ||
| | Callback adds complexity to function signature | Optional parameter with sensible default (no transformation) | |
32 changes: 32 additions & 0 deletions
32
openspec/changes/archive/2026-01-30-opencode-command-references/proposal.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| ## Why | ||
|
|
||
| OpenCode uses hyphen-based command syntax (`/opsx-new`) but our templates contain colon-based references (`/opsx:new`). This creates inconsistency where generated command files and skill files contain references that don't match the actual command invocation syntax, confusing both the AI and users. | ||
|
|
||
| ## What Changes | ||
|
|
||
| - Create a shared transformation utility (`transformToHyphenCommands`) for converting `/opsx:` to `/opsx-` | ||
| - Update the OpenCode command adapter to transform body text using this utility | ||
| - Add an optional `transformInstructions` callback parameter to `generateSkillContent()` | ||
| - Update `init.ts` and `update.ts` to pass the transformer when generating skills for OpenCode | ||
|
|
||
| ## Capabilities | ||
|
|
||
| ### New Capabilities | ||
|
|
||
| None - this is a bug fix, not a new capability. | ||
|
|
||
| ### Modified Capabilities | ||
|
|
||
| None - no spec-level behavior changes. This is an implementation fix in the OpenCode adapter and skill generation that doesn't change any external requirements or contracts. | ||
|
|
||
| ## Impact | ||
|
|
||
| - **Code**: | ||
| - `src/utils/command-references.ts` (new file) | ||
| - `src/utils/index.ts` (export) | ||
| - `src/core/shared/skill-generation.ts` (add callback parameter) | ||
| - `src/core/command-generation/adapters/opencode.ts` (use transformer) | ||
| - `src/core/init.ts` (pass transformer for OpenCode) | ||
| - `src/core/update.ts` (pass transformer for OpenCode) | ||
| - **Users**: OpenCode users will see correct `/opsx-` command references in both generated command files AND skill files | ||
| - **Other tools**: No impact - transformation only applies to OpenCode |
9 changes: 9 additions & 0 deletions
9
...spec/changes/archive/2026-01-30-opencode-command-references/specs/no-changes.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # No Spec Changes | ||
|
|
||
| This is a bug fix that doesn't modify any external requirements or contracts. | ||
|
|
||
| The proposal's Capabilities section indicates: | ||
| - **New Capabilities**: None | ||
| - **Modified Capabilities**: None | ||
|
|
||
| No spec files are needed for this implementation-only fix. |
22 changes: 22 additions & 0 deletions
22
openspec/changes/archive/2026-01-30-opencode-command-references/tasks.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| ## 1. Implementation | ||
|
|
||
| - [x] 1.1 Create `src/utils/command-references.ts` with `transformToHyphenCommands()` function | ||
| - [x] 1.2 Export `transformToHyphenCommands` from `src/utils/index.ts` | ||
| - [x] 1.3 Update `generateSkillContent()` in `src/core/shared/skill-generation.ts` to accept optional `transformInstructions` callback | ||
| - [x] 1.4 Update OpenCode adapter in `src/core/command-generation/adapters/opencode.ts` to use `transformToHyphenCommands()` for body text | ||
| - [x] 1.5 Update `init.ts` to pass transformer when generating skills for OpenCode | ||
| - [x] 1.6 Update `update.ts` to pass transformer when generating skills for OpenCode | ||
|
|
||
| ## 2. Testing | ||
|
|
||
| - [x] 2.1 Create `test/utils/command-references.test.ts` with unit tests for `transformToHyphenCommands()` | ||
| - [x] 2.2 Add test to `test/core/command-generation/adapters.test.ts` for OpenCode body transformation | ||
| - [x] 2.3 Add test to `test/core/shared/skill-generation.test.ts` for transformer callback | ||
|
|
||
| ## 3. Verification | ||
|
|
||
| - [x] 3.1 Run `npx vitest run test/utils/command-references.test.ts test/core/command-generation/adapters.test.ts test/core/shared/skill-generation.test.ts` to ensure tests pass | ||
| - [x] 3.2 Run `pnpm run build` to ensure no TypeScript errors | ||
| - [x] 3.3 Run `openspec init --tools opencode` in a temp directory and verify: | ||
| - Command files in `.opencode/command/` contain `/opsx-` references (not `/opsx:`) | ||
| - Skill files in `.opencode/skills/` contain `/opsx-` references (not `/opsx:`) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| /** | ||
| * Command Reference Utilities | ||
| * | ||
| * Utilities for transforming command references to tool-specific formats. | ||
| */ | ||
|
|
||
| /** | ||
| * Transforms colon-based command references to hyphen-based format. | ||
| * Converts `/opsx:` patterns to `/opsx-` for tools that use hyphen syntax. | ||
| * | ||
| * @param text - The text containing command references | ||
| * @returns Text with command references transformed to hyphen format | ||
| * | ||
| * @example | ||
| * transformToHyphenCommands('/opsx:new') // returns '/opsx-new' | ||
| * transformToHyphenCommands('Use /opsx:apply to implement') // returns 'Use /opsx-apply to implement' | ||
| */ | ||
| export function transformToHyphenCommands(text: string): string { | ||
| return text.replace(/\/opsx:/g, '/opsx-'); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This approach works for the immediate fix, but we should look into a more robust way to handle tool-specific transformations as we add support for more tools, similar to how it's handled in
src/core/command-generation/.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@webrgp Yeah you're right, it's something I mentioned here as well: #603 (comment)
Didn't think this would bite us back so soon. The way you've done it makes sense, but yes we need to find a better way to handle these transformations between different coding agents.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, totally agree! This was a quick fix to unblock things, but it's definitely not the long-term solution.
I like the idea of mirroring what we already have for commands - basically a skill adapter system that sits alongside the command adapters. Each tool could have its own adapter that knows how to transform content if needed. That way we keep all the tool-specific quirks in one place instead of sprinkling
if (tool === 'opencode')checks everywhere.Happy to open an issue or start a change for this if you want!