# Slash commands

Type in the TUI input. Tab-completion is available for all commands.

## `/help`

Shows the quick-reference keybinding card inside the TUI.
This docs site is the full reference; `/help` is the in-session reminder.

## `/model [<alias-or-id>]`

Without an argument: opens an interactive picker listing all model aliases
and any locally running models detected via LM Studio or Ollama.

With an argument: switches immediately.

```text
/model gemini-flash        ← switch by alias
/model claude-opus         ← switch by alias
/model local               ← auto-detect from LM Studio
/model gpt-4o              ← literal model ID (no alias needed)
/model llama3.2            ← any model name your provider understands
```

The new model is persisted to the keystore and used for all future
sessions until changed again. See [Providers & model aliases](./providers.md).

## `/provider [<name>]`

Without an argument: opens a two-step picker — choose provider, then
browse and pick one of its available models.

With an argument: jumps straight to that provider's model list.

```text
/provider                  ← open the picker
/provider anthropic        ← go straight to Anthropic models
/provider ollama           ← browse locally running Ollama models
```

## `/key`

Opens the API key manager. Select a provider, then type or paste your key.
Keys are stored in the local SQLite keystore (file mode 0600) and injected
as environment variables at every startup.

As of v0.2.27 (#1185), the input is rendered with each character masked
as `•` while you type, so a peer glancing at your terminal won't see the
key itself — useful for screen-sharing or pair-coding sessions. The
composer still tracks the real characters under the hood; backspace and
paste behave normally.

Shell env vars always win over stored keys — so `export ANTHROPIC_API_KEY=…`
in your shell or `.envrc` is always a clean override.

## `/compact`

Summarises old conversation history to free context tokens. Koda
auto-compacts when the context window hits **85%** full, but you can
trigger it manually at any time:

- All but the **last 4 messages** are summarised by the model
- The summary replaces the old messages in the DB
- The compressed session continues normally
- Use `/purge` later to clean up the archived messages

## `/purge [<age>]`

Deletes compacted (archived) message history. Does not touch the live messages
in your current session.

```text
/purge        ← delete all archived messages (prompts for confirmation)
/purge 90d    ← only messages archived more than 90 days ago
/purge 30d    ← only messages archived more than 30 days ago
```

Requires `y` to confirm. Deleted messages are gone permanently.

## `/undo`

Reverts all file mutations from the **previous inference turn** — Write,
Edit, and Delete tool calls. One `/undo` per turn; call again to go back
another turn. Bash commands (e.g. `cargo build`) are **not** undoable.

```text
# Koda wrote bad code in the last turn
/undo    ← all file changes from that turn are reverted
/undo    ← undo the turn before that
```

## `/diff`

Shows a summary of uncommitted `git diff` in the project root. Then offers:

- **Review** — sends the diff to the model for code review comments
- **Commit** — asks the model to write a conventional commit message and
  runs `git commit -m "…"`

## `/sessions [<sub-command>]`

```text
/sessions              ← open the session picker (shows last 100 sessions)
/sessions resume abc   ← resume the session whose ID starts with "abc"
/sessions delete abc   ← permanently delete that session
```

Session IDs are UUIDs; you only need 6–8 characters to be unambiguous.
On resume, Koda shows an away-summary: idle time, message count, token
usage, and a banner if the previous turn was interrupted mid-inference.

## `/memory [save]`

```text
/memory        ← show the paths to project and global memory files
/memory save   ← ask the model to summarise the session and append to MEMORY.md
```

See [Memory](./memory.md) for the full memory system.

## `/skills [<query>]`

```text
/skills              ← list all built-in and custom skills
/skills security     ← filter by name or description
```

## `/agent <name>`

Switches to a named sub-agent for the current session. The agent's
system prompt, model, and allowed tools replace the current defaults.

```text
/agent testgen     ← use the "testgen" agent definition
```

## `/agents`

Removed in #1210. The flat-text `/agents` dump (and its short-lived
interactive replacement from #1191) was superseded by the always-on
**bg-activity overlay** rendered just above the status bar. The
overlay shows every running background sub-agent and shell process
in real time — id, name, the last tool call each one fired, and
elapsed age — with no slash-command needed.

```text
  🤖 agent:1  explore    Read('src/lib.rs')         2m
  🤖 agent:2  verify     Bash('cargo test')         45s
  ⚙️ process:5821  cargo test --workspace          1m
  + 2 more
```

The LLM-facing equivalent is still the `ListBackgroundTasks` tool —
the model sees the same task ids when it asks about its own
background work.

## `/cancel <id>`

Requests cancellation of a background task by id (visible in the
bg-activity overlay above the status bar). Accepts three forms:

- `agent:N` — fires the per-task `CancellationToken`, which the
  inference loop checks between iterations. A cancelled sub-agent
  may run for one more iteration before noticing. The result still
  injects on the next user turn (with status `Cancelled` instead
  of `Completed`), so you don't lose any partial work the agent
  already did.
- `process:N` — sends SIGTERM to the shell process. The reaper
  transitions the entry to `Killed` immediately and to
  `Exited` once the OS confirms the process is gone.
- `N` (bare numeric) — back-compat with the original single-
  registry `/cancel` UX; treated as `agent:N`.

```text
/cancel agent:1       ← cancel background sub-agent #1
/cancel process:5821  ← SIGTERM background shell process pid 5821
/cancel 1             ← back-compat: same as `/cancel agent:1`
```

Idempotent: re-running `/cancel agent:1` on an already-cancelled
task is a no-op; `/cancel process:N` on an already-dead pid is also
a no-op (the kernel just rejects the SIGTERM). Unknown ids report a
helpful error rather than silently no-oping.

The LLM-facing equivalent is the `CancelTask` tool, which uses the
same parser and accepts the same prefixed forms.

## `/expand [<n>]`

Shows the full, untruncated output of a recent tool call. Useful when Koda
collapsed a long `cargo build` or `grep` result during streaming.

```text
/expand      ← show full output of the most recent tool call
/expand 3    ← show full output of the 3rd most recent tool call
```

## `/copy [<n>]`

Copies the Nth-most-recent **assistant response** to the system clipboard.
Defaults to the most recent response (`n=1`).

```text
/copy      ← copy the last response
/copy 2    ← copy the second-to-last response
/copy 5    ← copy the fifth-to-last response
```

Reads from the full session DB, so compacted (summarised) responses are
included in the count. A one-line preview is shown in the confirmation.

## `/debug-bundle`

Writes a self-contained `.zip` artifact capturing everything a debugger
(human or LLM) needs to reason about the current session. Replaces the
`/export` command removed in v0.2.26 (RFC #1167).

```text
/debug-bundle
```

The bundle is written to:

```text
~/.config/koda/debug-bundles/koda-debug-{timestamp}-{slug}.zip
```

where `{slug}` is derived from the first user message. The success
message prints the full path and a hint to the raw log directory:

```text
Wrote debug bundle → /Users/you/.config/koda/debug-bundles/koda-debug-20260429-082303-fix-the-auth-bug.zip
  raw logs: /Users/you/.config/koda/logs/latest
```

### Bundle layout

| File | What's in it |
|---|---|
| `README.md` | Human-orientation: what each file is, when to share, the env-var redaction caveat |
| `conversation.md` | Full session rendered via the same `history_render` pipeline as the live TUI — byte-for-byte identical to what you saw on screen |
| `messages.json` | Raw per-message DB rows (role, content, tool calls, tool results) |
| `metadata.json` | Session ID, title, started-at, model, provider, current PID, capture timestamp |
| `env.txt` | Allowlist-filtered environment variables (see below) |
| `logs/koda-{PID}.log` | Full per-process tracing log captured by the active session |
| `logs/panic.log` | Present only if the session encountered a panic; mirrors `~/.config/koda/logs/panic.log` |

The `.zip` format was chosen for **random-access reads** — LLM debugging
workflows that poke at one file at a time pay O(file) instead of
O(bundle), and the artifact opens cleanly in Finder Quick Look,
Windows Explorer, and any unzip CLI.

### Environment-variable redaction

`env.txt` is filtered through an **allowlist by default** in
`koda-cli/src/debug_bundle/env_filter.rs`. The filter has three
categories:

- **Pass through verbatim**: `KODA_*`, `RUST_*`, `LC_*`, `LANG`,
  `TERM`, `SHELL`, `PATH`, proxy vars (`HTTP_PROXY` / `HTTPS_PROXY` /
  `NO_PROXY`).
- **Length-redact**: known credential vars (`OPENAI_API_KEY`,
  `ANTHROPIC_API_KEY`, `GITHUB_TOKEN`, `GEMINI_API_KEY`, etc.) appear
  as `<redacted, N bytes>` so their *presence* is visible to the
  debugger but the *value* never leaks.
- **Drop entirely**: PII (`HOME`, `USER`, `PWD`, `LOGNAME`) and any
  unknown variable. Defaulting unknown to *drop* protects against
  unanticipated future credential names.

There is **no runtime opt-in to disable this filter**. Embedding raw
`std::env::vars()` in a sharable artifact is a foot-gun even with
opt-in flags; the bundle README also reminds you to re-check `env.txt`
before sharing externally.

### When to use it

- Reporting a bug to the koda issue tracker — attach the `.zip` so
  maintainers see your exact session, panic context, and runtime
  environment.
- Asking another LLM (Claude, ChatGPT, Gemini) to help debug a koda
  session — the model can `unzip` and read `conversation.md` directly.
- Capturing a known-bad state for later analysis (the timestamped
  filename + slug make bundles trivially sortable).

### Self-correlating logs (v0.2.26)

When a panic occurs, the panic hook now emits a `tracing::error!`
breadcrumb in rustc's default format (`thread '<name>' panicked at
<location>: <message>`) **before** writing `panic.log`. The breadcrumb
lands in the per-process tracing log, so within a `/debug-bundle` the
`logs/panic.log` and `logs/koda-{PID}.log` are correlatable by
wall-clock timestamp — no more orphan panic files disconnected from
the events that led up to them.


## `/verbose [on|off]`

Toggles verbose tool output. By default Koda collapses long outputs
during streaming. Verbose mode shows every line in real time.

```text
/verbose      ← toggle
/verbose on   ← enable explicitly
/verbose off  ← disable explicitly
```

## `/vim`

Toggles vim-mode editing in the input composer. When enabled, the
composer behaves like a single-buffer vi: `Esc` enters Normal mode,
`i`/`a`/`o` re-enter Insert mode, and the usual `h j k l`, `w b e`,
`0 $`, `gg G`, `dd yy p`, `x`, `cc`, `ci<delim>`, `ca<delim>`, etc.
bindings are honored. Useful when you're already living in vim and
want the same muscle memory in koda's chat input.

Added in v0.2.27 (#1182). The setting is per-session only; relaunching
koda starts back in plain insert mode.

See also: [Keybindings → Vim mode](./keybindings.md#vim-mode).

## `/exit`

Quit Koda. Equivalent to `Ctrl+D`.

## `/mcp <sub-command>`

Manage external MCP (Model Context Protocol) servers. See [MCP servers](./mcp.md)
for the full reference.

```text
/mcp list                                  ← list configured servers + status
/mcp add <name> <command> [args...]        ← add a stdio server
/mcp add-http <name> <url> [--token <tok>] ← add an HTTP server
/mcp reconnect <name>                      ← reconnect without restart
/mcp remove <name>                         ← permanently delete a server
```
