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

> Explore how Kimi CLI's slash commands function at soul and shell levels. Discover the unified interface for agent runtime and interactive UI control, leveraging a shared parser for seamless command execution.

- Repository: [Moonshot AI/kimi-cli](https://github.com/MoonshotAI/kimi-cli)
- Tags: internals
- Published: 2026-07-21

---

**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`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/soul/slash.py) and shell-level commands that control the interactive UI in [`src/kimi_cli/ui/shell/slash.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/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`](https://github.com/MoonshotAI/kimi-cli/blob/main/utils/slashcmd.py)

All slash commands, regardless of layer, pass through the same low-level parser in [`src/kimi_cli/utils/slashcmd.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/utils/slashcmd.py). The `parse_slash_command_call` function extracts the command name and raw arguments using a strict regular expression.

```python

# 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`](https://github.com/MoonshotAI/kimi-cli/blob/main/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:

```python

# 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`:

```python
@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`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/soul/slash.py) around lines 80-86.
- **`/plan on`** enables plan mode, writes a persistent [`plan.md`](https://github.com/MoonshotAI/kimi-cli/blob/main/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`](https://github.com/MoonshotAI/kimi-cli/blob/main/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:

```python

# 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:

```python
@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`](https://github.com/MoonshotAI/kimi-cli/blob/main/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`](https://github.com/MoonshotAI/kimi-cli/blob/main/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`](https://github.com/MoonshotAI/kimi-cli/blob/main/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`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/utils/slashcmd.py) that produces a `SlashCommandCall` object.
- **Soul-level** commands live in [`src/kimi_cli/soul/slash.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/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`](https://github.com/MoonshotAI/kimi-cli/blob/main/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`](https://github.com/MoonshotAI/kimi-cli/blob/main/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`](https://github.com/MoonshotAI/kimi-cli/blob/main/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`](https://github.com/MoonshotAI/kimi-cli/blob/main/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.