review-pr.md into .chatcli/commands/ and /review-pr 1326 security becomes a full, expanded prompt — in the REPL, inside a running /coder session, in one-shot -p scripts, through the messaging gateway, and over ACP and MCP. Expansion happens before the request is built, so commands work identically with every provider ChatCLI supports. And if your team already keeps commands for Claude Code, Devin, Windsurf, Cursor, opencode, Codex, Gemini CLI, Qwen Code or GitHub Copilot, those files work here unchanged — zero migration.
Commands vs. skills
Both appear in the completer and in the
/menu palette.
Where commands live
Scanned in precedence order — first hit for a name wins. Native ChatCLI dirs come first, then the interop matrix: if your team already uses any of these agent CLIs, their command files work in ChatCLI unchanged.
Subdirectories become namespaces:
frontend/deploy.md → /frontend:deploy (Gemini’s git/commit.toml → /git:commit). Foreign frontmatter keys (agent, subtask, mode, auto_execute_steps) are tolerated; opencode’s model maps to ChatCLI’s model hint. Frontmatter that isn’t even valid YAML — like Codex’s own documented argument-hint: [FILES=<paths>] shape — falls back to a line-wise read instead of dropping the file. A command can never shadow a built-in command — files named session.md, config.md etc. are refused and reported in /config commands.
Anatomy of a command
Placeholders (every dialect’s syntax works in every file):
Unknown
$WORDS pass through untouched.
Pre-execution lines (!)
A line starting with ! runs a shell command and embeds its output into the expanded prompt. The inline dialects work too — Gemini’s !{cmd} and opencode’s !`cmd` substitute in place mid-sentence. Every occurrence, whole-line or inline, goes through the same security gate as coder tools:
- Safety-immune commands (
rm -rf,sudo, …) always require interactive approval — never auto-approved, not even by automode. - Your
/policyrules apply (allow / ask / deny), and approval decisions can persist new rules (allow-always / deny-forever). - On unattended surfaces (gateway, MCP, ACP, scheduler) an “ask” resolves through
/policy automode— or fails safe to deny. A denied line is replaced by an explicit marker so the model knows the output is missing, never silently empty.
allowed-tools
When set, the run initiated by the command gets an ephemeral overlay on the security gate: a tool outside the list escalates from allow to ask — the human (or policy automode) arbitrates the exception. It never silently widens permissions and never silently denies.
Surfaces
Managing
✓/– existence marker:
Example: team standup
@commands) now has /standup 2.