diff --git a/.opencode/command/ponytail-audit.md b/.opencode/commands/ponytail-audit.md similarity index 100% rename from .opencode/command/ponytail-audit.md rename to .opencode/commands/ponytail-audit.md diff --git a/.opencode/command/ponytail-debt.md b/.opencode/commands/ponytail-debt.md similarity index 100% rename from .opencode/command/ponytail-debt.md rename to .opencode/commands/ponytail-debt.md diff --git a/.opencode/command/ponytail-help.md b/.opencode/commands/ponytail-help.md similarity index 100% rename from .opencode/command/ponytail-help.md rename to .opencode/commands/ponytail-help.md diff --git a/.opencode/command/ponytail-review.md b/.opencode/commands/ponytail-review.md similarity index 100% rename from .opencode/command/ponytail-review.md rename to .opencode/commands/ponytail-review.md diff --git a/.opencode/command/ponytail.md b/.opencode/commands/ponytail.md similarity index 100% rename from .opencode/command/ponytail.md rename to .opencode/commands/ponytail.md diff --git a/README.md b/README.md index d003bfa..b887f8c 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,15 @@ Injects the ruleset every turn at the active level; adds the `/ponytail` command The `./` path resolves against your project's `opencode.json`; to share one checkout across projects, point it at the absolute path of the `.mjs` instead (it finds its `hooks/` and `skills/` relative to its own file). +The slash commands ship in `.opencode/commands/` and are auto-discovered when you run OpenCode from this repo's root. To use them in every project without copying, link them into OpenCode's global commands directory: + +```bash +mkdir -p ~/.config/opencode/commands +ln -s "$PWD"/.opencode/commands/*.md ~/.config/opencode/commands/ +``` + +Run that once from this repo's root; rerun if a new command is added. Restart OpenCode to pick up the changes. + ### Gemini CLI ```bash diff --git a/docs/agent-portability.md b/docs/agent-portability.md index 40b4af8..34daa3c 100644 --- a/docs/agent-portability.md +++ b/docs/agent-portability.md @@ -10,7 +10,7 @@ to load in a given agent. |------|-------|-------| | Claude Code | `.claude-plugin/`, `commands/`, `hooks/` | Full plugin install with session activation, mode tracking, commands, and statusline support. | | Codex | `.codex-plugin/plugin.json`, `hooks/hooks.json`, `hooks/`, `skills/` | Plugin install with the same skills plus lifecycle hooks for activation and mode tracking. | -| OpenCode | `.opencode/plugins/ponytail.mjs`, `.opencode/command/`, `hooks/`, `skills/` | Server plugin injects the ruleset each turn via `experimental.chat.system.transform` and persists `/ponytail` switches; reuses the shared instruction builder. | +| OpenCode | `.opencode/plugins/ponytail.mjs`, `.opencode/commands/`, `hooks/`, `skills/` | Server plugin injects the ruleset each turn via `experimental.chat.system.transform` and persists `/ponytail` switches; reuses the shared instruction builder. | | pi | `pi-extension/`, `skills/`, `hooks/` | Package extension: injects the ruleset each turn through the shared instruction builder and registers the `/ponytail` commands. | | Gemini CLI | `gemini-extension.json`, `AGENTS.md`, `commands/`, `skills/` | Extension manifest points `contextFileName` at `AGENTS.md` for always-on rules, and reuses the existing `commands/*.toml` and `skills/`, which Gemini CLI auto-discovers. | | Cursor | `.cursor/rules/ponytail.mdc` | Always-on project rule. | diff --git a/tests/commands.test.js b/tests/commands.test.js index ef47a86..bc1dbff 100644 --- a/tests/commands.test.js +++ b/tests/commands.test.js @@ -1,7 +1,7 @@ #!/usr/bin/env node // Every ponytail command the pi extension registers must also ship as a // file-based command for the hosts that need one: Claude Code (commands/*.toml, -// which Gemini CLI reuses) and OpenCode (.opencode/command/*.md). /ponytail-help +// which Gemini CLI reuses) and OpenCode (.opencode/commands/*.md). /ponytail-help // was advertised in the README and the help card but missing both files; this // guards that drift -- a registered command with no adapter file fails here. @@ -29,11 +29,11 @@ test('every registered command ships a Claude commands/*.toml', () => { } }); -test('every registered command ships an OpenCode .opencode/command/*.md', () => { +test('every registered command ships an OpenCode .opencode/commands/*.md', () => { for (const name of commands) { assert.ok( - fs.existsSync(path.join(root, '.opencode', 'command', `${name}.md`)), - `missing .opencode/command/${name}.md`, + fs.existsSync(path.join(root, '.opencode', 'commands', `${name}.md`)), + `missing .opencode/commands/${name}.md`, ); } });