This page covers the slash command framework. Individual commands should be documented on separate reference pages once the command inventory is written.
What counts as a command
Claude Code uses slash commands as a second control plane beside natural-language prompts. Natural language goes through the model first. Slash commands go through the command registry first. That distinction matters because commands can:- Open local UI
- Mutate session settings
- Expand into prompt text
- Execute entirely without the model
src/commands.ts.
Command types
The codebase uses three main command shapes:prompt: expands into text that is sent to the modellocal: runs locally and returns textlocal-jsx: renders Ink UI components in the terminal
local-jsx. If it needs the model, it is prompt.
Registry architecture
src/commands.ts is the aggregator for built-in commands and external sources. It imports built-ins directly, then merges additional command sources at runtime:
- Built-in commands
- Skill directory commands
- Bundled skills
- Plugin commands
- Plugin skills
- Workflow commands
- Dynamic skills discovered during execution
Loading flow
Availability and enablement
A command can be filtered out in two separate ways. Availability:- Provider or account requirements such as
claude-aiorconsole - Evaluated on every
getCommands()call because auth state can change mid-session
- Feature gating and command-specific runtime checks
- Evaluated after availability
meetsAvailabilityRequirement() and getCommands().
Commands versus skills
The codebase intentionally blurs the boundary between commands and skills.- Some prompt commands are model-invocable through the skill tool path
- Some slash commands exist mainly as user-facing wrappers around skills
- Skills from directories, plugins, bundled assets, and MCP can all become command-like entries
src/commands.ts make the split explicit:
getSkillToolCommands(): prompt-based commands the model may invokegetSlashCommandToolSkills(): the subset treated as slash-command-style skills
Remote and bridge safety
Not every slash command is safe in every transport. The registry defines explicit allowlists for:- Remote mode
- Remote-control bridge mode
local-jsxcommands cannot safely render UI on remote clients- Some local commands depend on local filesystem or terminal context
- Prompt commands are usually safer because they expand into model text instead of executing local UI
REMOTE_SAFE_COMMANDS, BRIDGE_SAFE_COMMANDS, and isBridgeSafeCommand().
Execution path
Once a user enters/something, the input path differs from normal prompt handling:
- Parse the slash command token.
- Resolve the command from the active registry.
- Dispatch based on command type.
- Return local output, render UI, or synthesize prompt text.
- If prompt-based, continue into the normal model loop.
Feature-flagged commands
The registry usesbun:bundle feature gates heavily.
Examples in src/commands.ts include:
- Voice mode
- Bridge mode
- Ultraplan
- Forked subagent flows
- Internal Anthropic-only command surfaces
Naming and source annotation
Commands carry origin metadata used in UI and discovery surfaces. For prompt commands, the source can be:- Built-in
- Plugin
- Bundled
- Skills directory
- Legacy commands directory
- MCP
formatDescriptionWithSource() uses that metadata to explain provenance in user-facing interfaces.
Why the system is structured this way
The command layer solves three different problems at once:- Power-user shortcuts for the terminal UI
- Capability discovery for the model
- Extensibility for plugins, workflows, skills, and MCP
src/commands.ts looks more like a routing and policy module than a simple command list.