Commands/Slash Commands/ — Parsing & Dispatch
Slash command parsing, routing, and dispatch infrastructure
The Slash Commands sub-module implements the core command processing pipeline for OpenClaw. It parses user input into structured command objects, resolves them against a registry of handlers, manages command aliases, and dispatches execution through the agent binding system with support for channel-specific routing and peer-level targeting.
📚 What is this & why does it exist?
Slash Commands is the front door of OpenClaw’s CLI. Every time a user types a command like openclaw agents add or openclaw models set gpt-4o, this sub-module is responsible for figuring out what the user wants, finding the right handler function, and routing the request to it. Without it, the system would have no way to interpret user intent.
💡 Real-world analogy
Think of Slash Commands like the reception desk at a large office building. When a visitor (user input) arrives, the receptionist (command parser) reads the visitor’s badge, checks their name against the directory (command registry), handles any name aliases (“go to Bob” actually means “go to Robert in Suite 401”), and then routes them to the correct office (command handler). The receptionist also checks if the visitor has an appointment with a specific person (agent binding) on a specific floor (channel routing).
Contents
Architecture
flowchart TD Input["User Input
CLI args"] --> Parser["Command Parser
parse args & flags"] Parser --> Registry["Command Registry
resolve handler"] Registry --> AliasCheck{"Alias?"} AliasCheck -->|Yes| AliasResolve["Alias Resolution
models/aliases.ts"] AliasCheck -->|No| BindingCheck["Binding Resolution
agents.bindings.ts"] AliasResolve --> BindingCheck BindingCheck --> ConfigLoad["Config Snapshot
requireValidConfigFileSnapshot()"] ConfigLoad --> Handler["Command Handler
domain-specific function"] Handler --> Output["Runtime Output
JSON or formatted text"]
Key Classes
| Class / Function | File | Purpose |
|---|---|---|
agentsAddCommand() | agents.commands.add.ts | Wizard-driven agent creation with model selection and binding |
agentsBindCommand() | agents.commands.bind.ts | Bind agent to ACP provider/platform with auth flow |
agentsUnbindCommand() | agents.commands.bind.ts | Remove agent route bindings |
agentsListCommand() | agents.commands.list.ts | Display agent summaries with binding details |
applyAgentBindings() | agents.bindings.ts | Merge bindings into config with conflict detection |
describeBinding() | agents.bindings.ts | Human-readable binding description |
buildAgentSummaries() | agents.config.ts | Construct display-ready agent info from config |
requireValidConfigFileSnapshot() | agents.command-shared.ts | Load and validate config with content hash |
channelsAddCommand() | channels/add.ts | Interactive channel configuration wizard |
Data Structures
| Type | Name | Description |
|---|---|---|
| interface | AgentsAddOptions | Options bag for agent add: name, workspace, model, agentDir, bind[], nonInteractive, json |
| interface | AgentRouteBinding | Binding model with agentId and match criteria (channel, accountId, peer, guildId, teamId, roles) |
| interface | AgentSummary | Display model with id, name, identityName, workspace, model, bindings count, isDefault |
| interface | AgentsBindOptions | Options for bind command: agent, bind[], json |
| interface | ChannelAddResult | Result of channel add: channelId, configured boolean, optional error |
| type | ChannelsAddOptions | Options for channel add: token, channel, nonInteractive |
Interactions
| Direction | Partner | Interface | Description |
|---|---|---|---|
| → | config/ | requireValidConfigFileSnapshot() | Load config snapshot with hash for conflict detection |
| → | config/ | replaceConfigFile() | Atomically write updated config |
| → | wizard/ | createClackPrompter() | Interactive user prompting for wizards |
| → | routing/ | parseSessionKey() | Agent/session key parsing for binding resolution |
| → | channels/ | resolveChannelAdapter() | Channel adapter loading for capability detection |
| ← | terminal/ | RuntimeEnv | Output abstraction for log/warn/error/exit |
Configuration
| Knob / Parameter | Default | Description |
|---|---|---|
--name | prompted | Agent display name for creation |
--workspace | current dir | Agent workspace directory path |
--model | default model | Primary model for the agent |
--bind | none | Binding spec in provider:value format (repeatable) |
--non-interactive | false | Skip all prompts, require all flags |
--json | false | Output structured JSON instead of formatted text |
--agent-dir | auto | Override agent directory path |
Directory Map
Source tree for Slash Commands
src/commands/
├── agents.commands.add.ts ← Wizard-driven agent creation
├── agents.commands.bind.ts ← Route bind/unbind operations
├── agents.commands.delete.ts ← Agent removal with cleanup
├── agents.commands.list.ts ← Agent listing & display
├── agents.commands.identity.ts ← Agent identity management
├── agents.bindings.ts ← Binding model & conflict detection
├── agents.config.ts ← Agent configuration & summaries
├── agents.providers.ts ← Provider resolution for agents
├── agents.command-shared.ts ← Shared utilities (config load)
├── channels/
│ ├── add.ts ← Interactive channel add wizard
│ ├── remove.ts ← Channel removal
│ ├── list.ts ← Channel listing
│ ├── status.ts ← Channel status & probing
│ ├── capabilities.ts ← Feature detection
│ ├── resolve.ts ← Adapter resolution
│ ├── shared.ts ← Shared channel utilities
│ ├── logs.ts ← Channel log display
│ └── add-mutators.ts ← Account config helpers
└── models/
├── aliases.ts ← Alias CRUD commands
├── set.ts ← Default model selection
└── list.ts ← Model listing
Deep-Dive Highlights
Core mechanisms from this sub-module have been extracted into dedicated focus pages for in-depth exploration. Each page covers one algorithm, protocol, or subsystem with diagrams, code walks, and configuration details.
Deep-Dive Pages
Command Parsing Focus
How user input is tokenized, validated, and transformed into structured command objects with typed options. Covers the full parse pipeline from raw string to handler invocation.
Command Registry Focus
The handler registration and lookup system. How commands are registered, matched by name, and dispatched to their corresponding async handler functions with dependency injection.
Command Aliases Focus
Model alias management system allowing users to create shorthand names for models. Covers alias normalization, storage in config, and resolution during command dispatch.
Code Examples
Example: Agent Route Binding
export function describeBinding(binding: AgentRouteBinding): string {
const match = binding.match;
const parts = [match.channel];
if (match.accountId) parts.push(`accountId=${match.accountId}`);
if (match.peer) parts.push(`peer=${match.peer.kind}:${match.peer.id}`);
if (match.guildId) parts.push(`guild=${match.guildId}`);
if (match.teamId) parts.push(`team=${match.teamId}`);
return parts.join(" ");
}
Example: Agent Add Command Signature
type AgentsAddOptions = {
name?: string;
workspace?: string;
model?: string;
agentDir?: string;
bind?: string[];
nonInteractive?: boolean;
json?: boolean;
};
export async function agentsAddCommand(
opts: AgentsAddOptions,
runtime: RuntimeEnv = defaultRuntime,
params?: { hasFlags?: boolean }
): Promise<void>