How Slash Commands Work in Kimi CLI at the Soul and Shell Levels

Kimi CLI routes user slash commands through a shared parser into two distinct registries—soul-level commands that manipulate the agent runtime in src/kimi_cli/soul/slash.py and shell-level commands that control the interactive UI in src/kimi_cli/ui/shell/slash.py—allowing both layers to expose a unified /command interface.

The MoonshotAI/kimi-cli repository implements a dual-layer slash command architecture that separates agent runtime logic from terminal UI interactions. When a user types a command beginning with /, the system handles it through shared parsing utilities but dispatches to one of two specialized registries depending on whether the operation affects the core agent or the shell interface. Understanding how slash commands work in Kimi CLI reveals a clean boundary between the conversational engine and the user-facing terminal.

Shared Parsing Foundation in utils/slashcmd.py

All slash commands, regardless of layer, pass through the same low-level parser in src/kimi_cli/utils/slashcmd.py. The parse_slash_command_call function extracts the command name and raw arguments using a strict regular expression.


# src/kimi_cli/utils/slashcmd.py

def parse_slash_command_call(user_input: str) -> SlashCommandCall | None:
    ...
    name_match = re.match(r"^\/([a-zA-Z0-9_-]+(?::[a-zA-Z0-9_-]+)*)", user_input)
    ...
    return SlashCommandCall(name=command_name, args=raw_args, raw_input=user_input)

The parser returns None if the input does not match the slash command pattern, causing the UI to treat the line as ordinary chat text. When parsing succeeds, the resulting SlashCommandCall object carries the command name, raw argument string, and original input for downstream dispatch.

Soul-Level Slash Commands in Kimi CLI

Soul-level commands operate on the core agent runtime. Defined in src/kimi_cli/soul/slash.py, these handlers receive a KimiSoul instance and directly manipulate context, planning state, and session data.

The Soul Registry

The soul layer instantiates a dedicated registry for typed command functions:


# src/kimi_cli/soul/slash.py (lines 34-35)

registry = SlashCommandRegistry[SoulSlashCmdFunc]()

Developers register commands with the @registry.command decorator. Each decorated function accepts soul: KimiSoul and args: str:

@registry.command
async def clear(soul: KimiSoul, args: str):
    """Clear the context"""
    ...

Runtime Control Examples

  • /clear wipes the conversation context and rewrites the system prompt. The implementation lives in src/kimi_cli/soul/slash.py around lines 80-86.
  • /plan on enables plan mode, writes a persistent plan.md file, and disables tool calls. This is implemented around lines 60-99 of the same file.

These commands never concern themselves with terminal rendering. They modify the agent's internal state and rely on the soul's event system to propagate changes.

Shell-Level Slash Commands in Kimi CLI

Shell-level commands manage the interactive UI experience. Located in src/kimi_cli/ui/shell/slash.py, they interact with the terminal, launch editors, and handle model selection.

Dual Registry System

The shell maintains two registries to support both normal and agent-shell modes:


# src/kimi_cli/ui/shell/slash.py (lines 35-36)

registry = SlashCommandRegistry[ShellSlashCmdFunc]()
shell_mode_registry = SlashCommandRegistry[ShellSlashCmdFunc]()

Commands available in every mode attach to registry, while commands needed only when the UI acts as a raw shell attach to shell_mode_registry. Some commands, such as version, register to both:

@registry.command
@shell_mode_registry.command
def version(app: Shell, args: str):
    """Show version information"""
    ...

Handlers at this layer receive app: Shell and perform console I/O or external process launches. They do not mutate the agent runtime directly.

UI-Focused Operations

Notable shell-level slash commands in Kimi CLI include:

  • /model opens an interactive selector to switch the LLM model and thinking mode, implemented in src/kimi_cli/ui/shell/slash.py around lines 84-129.
  • /help renders a rich help screen with shortcuts and skill listings, found around lines 91-119.
  • /new starts a fresh session by calling _do_new_session, defined around lines 64-68. It acts as a shell alias for clearing state.
  • /btw sends a side-question without interrupting the main conversation. This shell command requires soul cooperation and is implemented around lines 60-73.

Execution Flow from Input to Handler

The dispatch pipeline follows a strict precedence that prioritizes shell-level UI actions before forwarding to the soul agent.

  1. User input enters the UI loop managed in src/kimi_cli/ui/shell/__init__.py. The input string is passed to parse_slash_command_call.
  2. At the parsing gate, if the parser returns None, the text is submitted as normal chat. Otherwise, a SlashCommandCall proceeds to registry lookup.
  3. The shell queries registry.find_command(name) and shell_mode_registry if applicable. If a match exists, the shell invokes the handler with the current Shell instance.
  4. When the shell cannot resolve the command, or when the command is explicitly intended for the runtime layer, the input reaches KimiSoul.run in src/kimi_cli/soul/kimisoul.py. The soul repeats the lookup against its own registry.
  5. The matched soul handler receives the KimiSoul instance and may update Context, emit messages via wire_send, or write session state. Shell handlers may redraw the terminal or spawn subprocesses.

This ordered resolution ensures UI concerns like /help or /model never pollute the agent's reasoning loop, while still allowing the shell to surface agent operations such as /clear when appropriate.

Summary

  • Kimi CLI slash commands share a unified parser in src/kimi_cli/utils/slashcmd.py that produces a SlashCommandCall object.
  • Soul-level commands live in src/kimi_cli/soul/slash.py and affect the agent runtime through a SlashCommandRegistry[SoulSlashCmdFunc].
  • Shell-level commands live in src/kimi_cli/ui/shell/slash.py and manage the terminal UI through one or both of registry and shell_mode_registry.
  • The execution flow checks the shell registry first, then falls back to the soul registry, maintaining a clean separation between interface logic and core agent behavior.

Frequently Asked Questions

What is the difference between soul and shell slash commands in Kimi CLI?

Soul-level commands manipulate the core agent runtime, such as clearing conversation context or toggling plan mode, and are defined in src/kimi_cli/soul/slash.py. Shell-level commands control the interactive terminal experience, such as displaying help or switching models, and are defined in src/kimi_cli/ui/shell/slash.py. The soul registry receives KimiSoul instances, while the shell registry receives Shell instances.

How does Kimi CLI parse a slash command from user input?

All slash commands are parsed by parse_slash_command_call in src/kimi_cli/utils/slashcmd.py. This function applies a regex starting with / followed by alphanumeric names and optional colon-namespaced segments. It returns a SlashCommandCall containing the command name, raw arguments, and original input string. If parsing fails, the line is treated as normal chat text.

Can a shell-level command modify the agent's internal state?

Shell-level commands do not mutate the agent runtime directly. However, commands like /new trigger UI-side routines that may start a fresh session, and /btw sends side-questions by interacting with the soul layer. Direct context changes remain the responsibility of soul-level handlers.

What happens if a command is not found in either registry?

If the parser identifies a slash command but neither the shell nor the soul registry contains a matching handler, the input does not enter the chat context as a user message. Instead, the system typically notifies the user that the command is unknown. The unified parsing layer guarantees that malformed or unrecognized commands are handled distinctly from ordinary conversational text.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →