Command System

Description

The command system handles user-invoked slash commands (/compact, /cost, /clear, /commit, etc.) — 70+ operations a user can trigger directly, as opposed to tools which the model invokes during reasoning. Commands are defined as a discriminated union of three types (prompt, local, local-jsx), registered in a layered registry, and dispatched through a type-switch pipeline.

Registry: src/commands.ts (759 lines). Dispatch: src/utils/processUserInput/processSlashCommand.tsx

Command types

Prompt commands (skills)

Inject structured instructions into the conversation. The model follows these to execute multi-step tasks. Can run inline or forked into a sub-agent (context: 'fork'). Exposed to the model via SkillTool.

Local commands (synchronous)

Execute immediately, return a result without querying the model. Implementation lazy-loaded. Returns text, compact (special compaction result), or skip. Examples: /compact, /cost, /clear, /exit.

Local-JSX commands (React UI)

Render an interactive Ink component for settings panels, selection dialogs, etc. Examples: /help, /config, /model, /mcp.

Registration

Three-tier loading via loadAllCommands(cwd): 1. Bundled skills (highest precedence) + built-in plugin skills 2. Skill directory commands (.claude/skills/, ~/.claude/skills/) + workflow commands + plugin commands 3. Built-in commands (70+, lowest precedence) — defined in COMMANDS(), conditionally included via feature flags

getCommands(cwd) filters by auth (availability field) and feature flags (isEnabled()).

Dispatch

processSlashCommand(): Parse → Lookup → Type-switch → Execute → Return messages. All results become conversation history entries. Only prompt commands with shouldQuery: true trigger a model query.

Built-in commands (selected)

/compact (summarize conversation), /cost (session cost), /clear (clear history), /help (command list), /config (settings), /commit (git commit), /review (code review), /model (select model), /effort (effort level), /doctor (diagnostics), /mcp (MCP management), /vim (vim mode).

Bridge between commands and tools

Prompt commands are exposed to the model via SkillTool. getSkillToolCommands() filters type === 'prompt' commands where !disableModelInvocation, allowing the model to invoke skills programmatically.

Remote/bridge safety

Commands filtered for remote execution. All prompt commands are bridge-safe (expand to text). Local-JSX commands blocked (no Ink UI in bridge). Explicit allowlists for remote-safe and bridge-safe local commands.

Key claims

Relations

Sources

Source code at src/commands.ts, src/types/command.ts, src/utils/processUserInput/processSlashCommand.tsx