Type to search the docs and updates.

Browse documentation

Commands

commands/ holds slash commands: saved prompts a person starts by name, such as /deploy. The body is the prompt the tool sends.

Use a skill instead when the model should pick the workflow itself, or when it needs bundled files. Set outputs.<target>.emit-skills-as-commands: true to get both from one skill.

Write one

agnostic-ai new command review-changes

It creates .agnostic-ai/commands/review-changes.md. Write the prompt, run agnostic-ai sync, then type /review-changes in a supported tool.

---
name: review-changes
description: Review the current branch against main.
x-claude:
  allowed-tools: [Bash(git diff:*), Read, Grep]
---

Diff the branch against `main` and report bugs with `file:line`, most severe first.

Fields

FieldRequiredDefaultDescription
namenofilenameCommand identifier and slash name, such as /deploy.
descriptionnoemptyShort description shown in slash-command pickers.
argument-hintnoemptyHint shown after the command in Claude Code, Augment, and Factory.

Other frontmatter is kept. Put keys for one tool under x-<target>, like x-claude.allowed-tools above.

Output

Each target page lists the exact directory. Gemini writes each command as a .toml file named after name. Codex without outputs.codex.commands-dir, Copilot, Zed, Windsurf, and Crush get each command as a skill (below). Other tools without command support skip it with a note.

Tools without commands

Tools with skills but no commands can receive commands as skills. The tool must support preventing the model from starting them: Codex, Copilot, Zed, Windsurf, and Crush. All but Codex qualify only while no other tool writes their skills folder, since a shared SKILL.md cannot keep the field. Cline, Amp, Warp, Antigravity, Continue, Goose, and OpenHands document no such switch, so they skip commands. The skill:

  • is written at the top level of the skills folder, whatever folder the command sits in under commands/;
  • sets disable-model-invocation: true, which Codex reads as allow_implicit_invocation: false in agents/openai.yaml, Copilot and Zed keep in SKILL.md, Windsurf writes as triggers: [user], and Crush writes with user-invocable: true;
  • keeps name, description, the target fields, and argument-hint where the tool reads it, and notes any other field it leaves out. A target field that decides who starts the skill, disable-model-invocation, triggers, or user-invocable, is left out, so the skill stays user-run;
  • opens with one line asking the model to run it only when called, and to treat the text typed after its name as its arguments, since these tools do not fill in $ARGUMENTS in a skill. Sync notes each $ARGUMENTS or $1 line, and on-unsupported: error does not fail on them.

A skill spec with the same name (ignoring case), or a hand-written skill folder of that name the tool reads, wins, and sync notes the skipped command. A tool that reads the same skills folder, such as Gemini CLI reading the copy Codex writes to .agents/skills, also sees the skill, even with target-exclude; sync notes that it lists the command twice, or that its model can start it.

Claude Code body syntax

A Claude Code command body can use !`command` lines, ```! blocks, $ARGUMENTS, and $1, $2, ... (skill syntax). Sync copies the body as written. Support follows each tool's docs:

Target!`command`$ARGUMENTS$1, $2, ...
Claude Codeyesyesyes
OpenCodeyesyesyes
Codexnoyesyes
Augment, Factorynoyesno
Kiro CLI V3noyesno
Cursor, Gemini, Junie, Kilo, Qoder, Traenonono

A tool that reads the syntax as plain text gets a note naming each line; on-unsupported: error fails the sync, and lint reports LINT019. Write a tool's own placeholders in a ::target fence: Gemini's argument and shell forms (custom commands), or Kiro's ${1} through ${10} and ${@}, which sync keeps as written (it does not map a bare $1).