Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/command-invocation-parity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@fission-ai/openspec': patch
---

Reference slash commands by the name each tool actually registers. Command bodies, generated `SKILL.md` cross-references, and the `init`/`update`/migration hints all advertised `/opsx:<id>`, but only 7 of the 28 tools with a command adapter register that name — the ones whose files sit in an `opsx/` directory. The other 21 write `.../opsx-<id>.md`, where the filename is the command, so tools such as Cursor, GitHub Copilot, Windsurf and Kilo Code were told to type a command their palette never had; a single generated Cursor file named itself `/opsx-apply` in frontmatter and then told the reader to run `/opsx:apply`. The command *name* is now derived from the command file each adapter writes rather than a hand-maintained tool list, so a newly added adapter cannot drift, and the *wrapper* around it is adapter metadata: Amazon Q loads its files into a prompt library invoked with `@`, so it now gets `@opsx-<id>` in command bodies, skills, and the onboarding hint instead of a slash command it never registers. Codex, which generates no command files at all, now gets `$openspec-<skill>` — the syntax its CLI actually accepts — everywhere it previously advertised `/opsx:*`, superseding the syntax-neutral hint described in the pending `adapterless-skill-references` note. Command filenames and paths are unchanged, and Claude Code output is byte-identical.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ Now talk to your AI:

Both are in the default profile. If you want the expanded workflow (`/opsx:new`, `/opsx:continue`, `/opsx:ff`, `/opsx:verify`, `/opsx:bulk-archive`, `/opsx:onboard`), select it with `openspec config profile` and apply with `openspec update`.

`/opsx:propose` is the canonical name; your tool may spell it `/opsx-propose` (Cursor, GitHub Copilot), `@opsx-propose` (Amazon Q) or `$openspec-propose` (Codex). `openspec init` prints the right form for the tools you picked — see [How To Invoke](docs/supported-tools.md#how-to-invoke).

> [!NOTE]
> Not sure if your tool is supported? [View the full list](docs/supported-tools.md) – we support 30+ tools and growing.
>
Expand Down
27 changes: 14 additions & 13 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ This is the reference for OpenSpec's slash commands. These commands are invoked

For workflow patterns and when to use each command, see [Workflows](workflows.md). For CLI commands, see [CLI](cli.md).

These pages use `/opsx:<command>` as the canonical name. Some tools spell it
differently — Cursor and GitHub Copilot register `/opsx-propose`, Codex uses
`$openspec-propose` — so check [How To Invoke](supported-tools.md#how-to-invoke)
for your tool. The files OpenSpec generates already use the right form.

## Quick Reference

### Default Quick Path (`core` profile)
Expand Down Expand Up @@ -664,19 +669,15 @@ AI: Welcome to OpenSpec!

Different AI tools use slightly different command syntax. Use the format that matches your tool:

| Tool | Syntax Example |
|------|----------------|
| Claude Code | `/opsx:propose`, `/opsx:apply` |
| Cursor | `/opsx-propose`, `/opsx-apply` |
| Windsurf | `/opsx-propose`, `/opsx-apply` |
| Copilot (IDE) | `/opsx-propose`, `/opsx-apply` |
| CodeArts | Skill-based invocations such as `/openspec-propose`, `/openspec-apply-change` (no generated `opsx-*` command files) |
| Codex | Skill-based invocations from `.codex/skills/openspec-*` (no generated `opsx-*` prompt files) |
| Oh My Pi | `/opsx-propose`, `/opsx-apply` |
| Kimi Code | Skill-based invocations such as `/skill:openspec-propose`, `/skill:openspec-apply-change` (no generated `opsx-*` command files) |
| Trae | `/opsx-propose`, `/opsx-apply` |

The intent is the same across tools, but how commands are surfaced can differ by integration.
| Your tool's command file | Syntax example | Example tools |
|--------------------------|----------------|---------------|
| `.../commands/opsx/<id>.*` | `/opsx:propose`, `/opsx:apply` | Claude Code, Gemini CLI, Crush |
| `.../opsx-<id>.*` | `/opsx-propose`, `/opsx-apply` | Cursor, Windsurf, Copilot (IDE), Trae, Oh My Pi |
| none — skills only | `/openspec-propose`, `/openspec-apply-change` | CodeArts, ForgeCode, Hermes, Mistral Vibe |
| none — Kimi Code | `/skill:openspec-propose` | Kimi Code |
| none — Codex CLI | `$openspec-propose` | Codex |

The intent is the same across tools, but how commands are surfaced can differ by integration. [How To Invoke](supported-tools.md#how-to-invoke) lists every supported tool; this table shows only examples of each shape.

> **Note:** GitHub Copilot commands (`.github/prompts/*.prompt.md`) are only available in IDE extensions (VS Code, JetBrains, Visual Studio). GitHub Copilot CLI does not currently support custom prompt files — see [Supported Tools](supported-tools.md) for details and workarounds.

Expand Down
4 changes: 2 additions & 2 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ There isn't a separate mode to start. You open your AI assistant like normal and

### I typed a slash command and nothing happened. Why?

Most likely you typed it in the terminal instead of your AI chat, or the commands aren't installed yet. Run `openspec update` in your project, restart your assistant, then try typing `/opsx` in chat and watch for autocomplete. [Troubleshooting](troubleshooting.md#commands-dont-show-up) has the full checklist.
Most likely you typed it in the terminal instead of your AI chat, you used a spelling your tool doesn't register, or the commands aren't installed yet. If the files are missing — or you never set the tool up — run `openspec init`; `openspec update` only refreshes files that already exist. Then restart your assistant and use the form printed under "Getting started" — see [How To Invoke](supported-tools.md#how-to-invoke). [Troubleshooting](troubleshooting.md#commands-dont-show-up) has the full checklist.

### Why is the syntax `/opsx:propose` in one tool and `/opsx-propose` in another?

Each AI tool surfaces custom commands a little differently. The intent is identical; only the punctuation changes. Type a slash in your chat and the autocomplete shows you the form your tool expects. The per-tool table is in [How Commands Work](how-commands-work.md#slash-command-syntax-by-tool).
Each AI tool surfaces custom commands a little differently, and OpenSpec spells them the way your tool loads the file it wrote. A command file named `opsx-propose.md` is typed `/opsx-propose`; one filed under `commands/opsx/` is typed `/opsx:propose`. Tools that take skills instead of commands use the skill name — Codex needs `$openspec-propose`, Kimi Code `/skill:openspec-propose`. The `openspec init` "Getting started" line already prints the right form for the tools you picked; the full table is in [How To Invoke](supported-tools.md#how-to-invoke).

### What's the difference between a skill and a command?

Expand Down
41 changes: 22 additions & 19 deletions docs/how-commands-work.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,30 +71,33 @@ The strength of this design: you learn the workflow once and carry it across too

## Slash command syntax by tool

The intent is identical everywhere. The punctuation differs. Use the form that matches your assistant.

| Tool | How you type it |
|------|-----------------|
| Claude Code | `/opsx:propose`, `/opsx:apply` |
| Cursor | `/opsx-propose`, `/opsx-apply` |
| Windsurf | `/opsx-propose`, `/opsx-apply` |
| GitHub Copilot (IDE) | `/opsx-propose`, `/opsx-apply` |
| CodeArts | skill-style, e.g. `/openspec-propose` |
| Codex | skill-style via `.codex/skills/openspec-*` |
| Oh My Pi | `/opsx-propose`, `/opsx-apply` |
| Kimi CLI | skill-style, e.g. `/skill:openspec-propose` |
| Trae | `/opsx-propose`, `/opsx-apply` |

Most tools use either the colon form (`/opsx:propose`) or the dash form (`/opsx-propose`). A few tools surface OpenSpec as named skills instead of slash commands; for those you invoke the skill by name. The full per-tool list, including exactly which files get written where, lives in [Supported Tools](supported-tools.md).

When in doubt, type a slash in your AI chat and look at the autocomplete. Your tool will show you the form it expects.
The intent is identical everywhere. The spelling follows the file your tool loads.

| Your tool's command file | How you type it | Example tools |
|--------------------------|-----------------|---------------|
| `.../commands/opsx/<id>.*` | `/opsx:propose` | Claude Code, Gemini CLI, Crush |
| `.../opsx-<id>.*` | `/opsx-propose` | Cursor, GitHub Copilot (IDE), Windsurf, Trae, Oh My Pi |
| `.amazonq/prompts/opsx-<id>.md` | `@opsx-propose` | Amazon Q Developer |
| none — skills only | `/openspec-propose` | CodeArts, ForgeCode, Hermes, Mistral Vibe |
| none — Kimi Code | `/skill:openspec-propose` | Kimi Code |
| none — Codex CLI | `$openspec-propose` | Codex |

Every tool is listed in [How To Invoke](supported-tools.md#how-to-invoke) — that
table is the authoritative one. Two rows are not slash commands at all: Amazon Q
loads its files into a prompt library invoked with `@`, and the last three rows
use the *skill* name, which is not the command id (`/opsx:apply` is the
`openspec-apply-change` skill).

When in doubt, read the "Getting started" line `openspec init` printed: it already
uses the form your tools registered. Typing a slash and watching the autocomplete
works too, for the tools that surface slash commands at all.

## How the commands got there: skills and commands

When you run `openspec init` (or `openspec update`), OpenSpec writes small files into your project so your AI tool can find the workflow. Depending on your tool and settings, these are **skills**, **commands**, or both.

- **Skills** live in places like `.claude/skills/openspec-*/SKILL.md`. They're the emerging cross-tool standard: a folder of instructions your assistant auto-detects.
- **Commands** live in places like `.claude/commands/opsx/<id>.md`. They're the older per-tool slash command files. Codex does not get generated command files; use `.codex/skills/openspec-*`.
- **Commands** live in places like `.cursor/commands/opsx-<id>.md` or `.claude/commands/opsx/<id>.md` — the layout is the tool's, and it decides how you type the command. They're the older per-tool slash command files. Codex does not get generated command files; use `.codex/skills/openspec-*`.

You don't have to care which one your tool uses. You just type the slash command and it works. But knowing these files exist helps when something goes wrong: if your commands vanish, it usually means these files are missing or stale, and `openspec update` regenerates them.

Expand All @@ -104,7 +107,7 @@ See [Supported Tools](supported-tools.md) for the exact paths per tool, and [Mig

Quick checks, fastest first:

1. **Type a slash in your AI chat.** Start typing `/opsx` and watch for autocomplete suggestions. If they appear, you're set.
1. **Type a slash in your AI chat.** Start typing `/opsx` and watch for autocomplete suggestions. If they appear, you're set. On a skills-only tool (Codex, Kimi Code, CodeArts, ForgeCode, Hermes, Mistral Vibe) `/opsx` never completes even on a healthy install — try the skill name from the table above instead.
2. **Look for the files.** For Claude Code, check that `.claude/skills/` contains `openspec-*` folders. Other tools use their own directories ([Supported Tools](supported-tools.md) lists them).
3. **Re-run setup.** From your project root, run `openspec update`. This regenerates the skill and command files for whatever tools you configured.
4. **Restart your assistant.** Many tools scan for skills and commands at startup, so a fresh window can be the missing step.
Expand Down
5 changes: 3 additions & 2 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ order, and stop where a step tells you to stop.
it suggested instead of retrying. Finish by telling me how to invoke OpenSpec
in my tool, and take the exact spelling from the files init created rather
than from its summary line: the punctuation differs per tool (/opsx:propose
in some, /opsx-propose in others), and skills-only tools have no slash
command at all.
in some, /opsx-propose in others, @opsx-propose in Amazon Q), and tools that
get skills instead of commands are invoked by skill name (/openspec-propose,
or $openspec-propose in Codex, or /skill:openspec-propose in Kimi Code).
```

Nothing in the prompt is vendor-specific: it's plain instructions plus the same commands documented on this page. It works on macOS, Linux, and Windows, and it deliberately stops rather than improvising when a step needs your permission. Your assistant does need to be able to run shell commands — a few IDE integrations can't.
Expand Down
38 changes: 38 additions & 0 deletions docs/supported-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,44 @@ By default, OpenSpec uses the `core` profile, which includes:

You can enable expanded workflows (`new`, `continue`, `ff`, `verify`, `bulk-archive`, `onboard`) via `openspec config profile`, then run `openspec update`.

## How To Invoke

These docs use `/opsx:propose` as the canonical name, but each tool spells it the
way it loads the file OpenSpec wrote. Find your tool's command path in the
[Tool Directory Reference](#tool-directory-reference) below, then match its shape here.

| Command file OpenSpec writes | You type | Tools |
|------------------------------|----------|-------|
| `.../commands/opsx/<id>.*` — an `opsx/` folder namespaces it | `/opsx:<id>` | Claude Code, CodeBuddy, Crush, Gemini CLI, Lingma, Qoder, ZCode |
| `.../opsx-<id>.*` — the filename is the command | `/opsx-<id>` | Every other tool with generated command files, except Amazon Q |
| `.amazonq/prompts/opsx-<id>.md` — a prompt, not a command | `@opsx-<id>` | Amazon Q Developer |
| none — skills only | `/openspec-<skill>` | CodeArts, ForgeCode, Hermes, Mistral Vibe |
| none — Kimi Code | `/skill:openspec-<skill>` | Kimi Code |
| none — Codex CLI | `$openspec-<skill>` | Codex ([`/openspec-<skill>` is not recognized](https://github.com/openai/codex/issues/11817)) |

So `/opsx:propose` is `/opsx-propose` in Cursor, `@opsx-propose` in Amazon Q, and
`$openspec-propose` in Codex.

Two things vary independently, which is why the rows do not collapse:

- **The name.** Rows 1–2 differ only in how the file names the command, and the
`opsx-<id>` / `opsx:<id>` stem is the same for every tool with generated
command files.
- **The wrapper.** Amazon Q loads its files into a prompt library invoked with
`@`. Skills-only tools generate no command files at all, so their last three
rows use *skill* names — listed under
[Generated Skill Names](#generated-skill-names) — which do not map one-to-one
onto command ids (`/opsx:apply` is the `openspec-apply-change` skill).

The command path patterns above are extension-neutral (`.*`) on purpose: the
extension is the tool's (`.toml` for Gemini CLI, `.prompt` for Continue,
`.prompt.md` for Kiro and GitHub Copilot), and a few tools show the name with
its extension in the picker. Match the directory shape, not the extension.

The files OpenSpec generates, and the "Getting started" hint printed after setup,
already use the right form for the tools you selected — so the fastest answer is
to read the hint.

## Tool Directory Reference

| Tool (ID) | Skills path pattern | Command path pattern |
Expand Down
2 changes: 1 addition & 1 deletion docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ If `/opsx:propose` (or your tool's equivalent) doesn't appear or doesn't do anyt

5. **Check you initialized this project.** Skills are written per project. If you cloned a repo or switched folders, run `openspec init` (or `openspec update`) there.

6. **Confirm your tool supports command files.** Codex and a few other tools (CodeArts, Kimi CLI, ForgeCode, Mistral Vibe) don't get generated `opsx-*` command files; they use skill-based invocations instead. For Codex, check `.codex/skills/openspec-*`. The forms differ per tool: see [Supported Tools](supported-tools.md) and [How Commands Work](how-commands-work.md#slash-command-syntax-by-tool).
6. **Confirm your tool supports command files.** Codex, CodeArts, ForgeCode, Hermes, Kimi Code and Mistral Vibe don't get generated `opsx-*` command files; they use skill-based invocations instead, so `/opsx` will never autocomplete for them. Type `$openspec-propose` in Codex, `/skill:openspec-propose` in Kimi Code, and `/openspec-propose` in the rest. Amazon Q does get command files, but loads them into its prompt library rather than its slash menu — type `@opsx-propose` there, not `/opsx`. Every tool's form is listed in [How To Invoke](supported-tools.md#how-to-invoke).

## Working with changes

Expand Down
9 changes: 4 additions & 5 deletions openspec/specs/cli-init/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ The command SHALL configure AI coding assistants with skills and slash commands

- **WHEN** user selects tools and confirms
- **THEN** generate skills in `.<tool>/skills/` directory for each selected tool
- **AND** generate slash commands in `.<tool>/commands/opsx/` directory for each selected tool
- **AND** generate slash commands for each selected tool with a command adapter, at that adapter's own path (for example `.claude/commands/opsx/<id>.md` or `.cursor/commands/opsx-<id>.md`)
- **AND** create `openspec/config.yaml` with default schema setting

### Requirement: Interactive Mode
Expand Down Expand Up @@ -85,10 +85,9 @@ The command SHALL provide clear, actionable next steps upon successful initializ
- "Created: <tools>" for newly configured tools
- "Refreshed: <tools>" for already-configured tools that were updated
- Count of skills and commands generated
- **AND** display getting started section with:
- `/opsx:new` - Start a new change
- `/opsx:continue` - Create the next artifact
- `/opsx:apply` - Implement tasks
- **AND** display a getting started section naming an installed onboarding workflow (for example `/opsx:propose` - Start a change)
- **AND** spell each command the way the configured tool registers it: `/opsx-<id>` for tools whose command files are named `opsx-<id>`, and the tool's skill invocation (`$openspec-<skill>` for Codex, `/skill:openspec-<skill>` for Kimi Code, `/openspec-<skill>` otherwise) for tools that receive no command files
- **AND** print one labeled line per distinct form when the selected tools disagree
- **AND** display links to documentation and feedback

#### Scenario: Displaying restart instruction
Expand Down
2 changes: 1 addition & 1 deletion openspec/specs/cli-update/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ The update command SHALL refresh existing slash command files for configured too
#### Scenario: Updating slash commands for OpenCode
- **WHEN** `.opencode/commands/` contains OpenSpec-managed `opsx-*.md` command files for the configured profile (for example `opsx-propose.md`, `opsx-apply.md`, and `opsx-archive.md`)
- **THEN** refresh each file using shared templates
- **AND** transform command references to hyphen form (for example `/opsx-propose`) for OpenCode compatibility
- **AND** transform command references to hyphen form (for example `/opsx-propose`), as for every tool whose command files are named `opsx-<id>`
- **AND** ensure templates include instructions for the relevant workflow stage
- **AND** ensure the archive command includes `$ARGUMENTS` placeholder in frontmatter for accepting change ID arguments

Expand Down
Loading
Loading