|
| 1 | +## Context |
| 2 | + |
| 3 | +OpenCode is one of many supported AI tools. Each tool has: |
| 4 | +- A **command adapter** (in `src/core/command-generation/adapters/`) for generating tool-specific command files |
| 5 | +- **Skills** generated via `generateSkillContent()` in `src/core/shared/skill-generation.ts` |
| 6 | + |
| 7 | +Currently: |
| 8 | +- Commands go through the adapter system which can transform content per-tool |
| 9 | +- Skills use a single shared function with no tool-specific transformation |
| 10 | + |
| 11 | +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. |
| 12 | + |
| 13 | +## Goals / Non-Goals |
| 14 | + |
| 15 | +**Goals:** |
| 16 | +- Transform all `/opsx:` command references to `/opsx-` for OpenCode in both commands and skills |
| 17 | +- Create a shared, reusable transformation utility |
| 18 | +- Keep the transformation opt-in via a callback parameter (not hard-coded tool detection) |
| 19 | + |
| 20 | +**Non-Goals:** |
| 21 | +- Modifying the canonical template format (templates stay with `/opsx:`) |
| 22 | +- Applying transformation to other tools (only OpenCode for now) |
| 23 | +- Creating a full adapter system for skills (overkill for current needs) |
| 24 | + |
| 25 | +## Decisions |
| 26 | + |
| 27 | +### Decision 1: Shared Utility Function |
| 28 | + |
| 29 | +**Choice**: Create `transformToHyphenCommands()` in `src/utils/command-references.ts` |
| 30 | + |
| 31 | +**Rationale**: |
| 32 | +- Single source of truth for the transformation logic |
| 33 | +- Can be used by both command adapter and skill generation |
| 34 | +- Easy to test in isolation |
| 35 | +- Follows existing utils pattern in the codebase |
| 36 | + |
| 37 | +**Alternatives considered**: |
| 38 | +- Inline the transformation in each location - Duplicates logic, harder to maintain |
| 39 | + |
| 40 | +### Decision 2: Callback Parameter for Skill Generation |
| 41 | + |
| 42 | +**Choice**: Add optional `transformInstructions?: (instructions: string) => string` parameter to `generateSkillContent()` |
| 43 | + |
| 44 | +**Rationale**: |
| 45 | +- Flexible - callers define the transformation, not the generation function |
| 46 | +- No coupling - `generateSkillContent()` doesn't need to know about tool formats |
| 47 | +- Extensible - could support other transformations in the future |
| 48 | +- Follows inversion of control principle |
| 49 | + |
| 50 | +**Alternatives considered**: |
| 51 | +- Add tool ID parameter and switch on it - Creates coupling, harder to extend |
| 52 | +- Create skill adapter system parallel to commands - Over-engineering for current needs |
| 53 | +- Transform in templates directly - Breaks single-source-of-truth principle |
| 54 | + |
| 55 | +### Decision 3: Apply at Generation Sites |
| 56 | + |
| 57 | +**Choice**: Pass transformer in `init.ts` and `update.ts` when `tool.value === 'opencode'` |
| 58 | + |
| 59 | +**Rationale**: |
| 60 | +- These are the only two places that generate skills |
| 61 | +- Simple conditional check, no new abstractions needed |
| 62 | +- Easy to extend to other tools if needed later |
| 63 | + |
| 64 | +## Risks / Trade-offs |
| 65 | + |
| 66 | +| Risk | Mitigation | |
| 67 | +|------|------------| |
| 68 | +| Other `/opsx:` patterns exist that shouldn't be transformed | All occurrences in templates are command invocations - verified by inspection | |
| 69 | +| Future tools may need same transformation | Utility is shared and easy to reuse; can add to other tools' generation | |
| 70 | +| Callback adds complexity to function signature | Optional parameter with sensible default (no transformation) | |
0 commit comments