magi-code 0.97.6

Repository-aware CLI coding agent for terminal work
Documentation
# Mission Control TUI

[Mission Control user guide](../user/mission-control.md) · [Technical reference index](README.md) · [Repository README](../../README.md)

Use Mission Control to edit prompts, follow tools and subagents, inspect captured output, and change settings without leaving the terminal.

```sh
magi-code
magi-code --prompt "Summarize this repository."
```

Mission Control is the conversation interface. Both stdin and stdout must be TTYs. `--prompt` rejects whitespace-only input.

## Startup and readiness

You can edit after the first frame, before execution is ready. Settings, instructions, skills, and session setup load before that frame. Background session cleanup does not block readiness.

Execution waits for the selected primary agent, enabled subagent profiles, and every enabled MCP server. A failure in any required component blocks queued work. Unselected or disabled profile errors only warn. Autocomplete, titles, and Git metadata do not block execution. See [MCP startup](mcp-stdio-tools.md#startup-policy-by-interface).

## Startup prompt queue

During readiness, you can queue one normal prompt. The queued prompt becomes immutable, and the editor clears for a separate draft. A second submission is rejected without replacing either. `Alt-C` cancels the queue and preserves the draft. `/help` and `/quit` work immediately; other slash commands remain blocked until ready.

After readiness, an input fence checks for later queue decisions, then runs the prompt once. An untouched `--prompt` follows the same path. A critical startup failure restores the terminal, exits nonzero, and does not run the queue. Startup queuing is separate from active-run steering.

## Provider connection

`/login` opens Connect Provider at 60% terminal width and 40% height. It lists OpenAI Codex, Anthropic, Claude Subscription, OpenAI, and Custom Provider with current status. Select with `Up`/`Down`, then `Enter`. Enlarge compact terminals when prompted to reveal editable controls.

- Codex OAuth stays in the modal. Click **Open Browser** (`Alt-O`) or **Copy URL** (`Ctrl-Y`) below the URL. `Tab`/`Shift-Tab` moves between these buttons and the redacted redirect field; `Enter` activates the focused control. Copy the final browser redirect URL, paste it into the field, and press `Enter`. `Esc` cancels OAuth.
- Anthropic shows environment/API-key setup guidance. It does not request or store a key.
- Custom Provider accepts a label, base URL, optional API-key environment-variable name (never the key), and optional `models.dev` provider override. The override selects an exact catalog namespace. Blank uses the provider ID and clears an existing override on replacement. `Tab`/`Shift-Tab` moves between fields; compact layouts show the focused field. Reusing an ID requires confirmation: `Enter` replaces it, while `Esc` returns to the form.
- After success, `Enter`/`Esc` closes. After an error, `Enter` retries, `Backspace`/`Left` goes back, and `Esc` closes. Cancellation before Saving preserves settings and credentials. Saving cannot be cancelled after durable custom-provider persistence starts; the modal stays open until completion is reconciled.

## Edit settings

`/settings` opens six tabs (Context, Agent settings, Models, Tools, Internal Tooling, Other) for Global or Project settings. Edits remain drafts until `Ctrl-S`. Saving reloads settings for future actions and refreshes affected Mission Control state. `Tab` switches tabs; `Ctrl-G` switches scope. Models shows cached rows without refreshing. Its **Refresh catalog** button refreshes only when clicked or selected with Up/Down and activated with Enter. See [Configuration](configuration.md#edit-settings-in-mission-control) for all controls and editable groups.

Compaction, Side agent, Summary, Session titles, and View image each use one model picker for paired provider/model settings. It lists enabled cached models, including unsaved availability changes. Enter accepts into the draft; Esc cancels. Tab or Ctrl-G cancels an unaccepted choice before navigating. Opening the picker does not refresh the catalog.

## Side conversation

`/side` opens an independent conversation, including during primary work. It has separate history and display state but uses the same transcript cards, prompt editor, and activity inspection. `Esc` hides it without stopping work; `/side` reopens it. `Alt-C` cancels only side work. Hidden work shows running/unread status at top right.

Inside the modal, only `/reset` is available. Reset preserves old history and waits for worker/MCP cleanup before creating a new UUID session. The live conversation lasts only for this process. Its files live under `sessions/side/`, outside primary session selection. `--no-session` disables it. See [Side agent](side-agent.md) for tools, shared-file risks, settings, and lifetime details.

## Prompt editing and paste

`Enter` submits. `Shift-Enter`, `Ctrl-J`, and `Ctrl-Enter` insert a newline. **Use `Ctrl-J` as the portable fallback.** Some terminals send `Shift-Enter` and `Ctrl-Enter` as plain `Enter`, causing submission. This includes WSL when its host terminal or an intervening multiplexer drops these modifiers.

Autocomplete and modals take precedence over editing. The prompt grows from 1 to 5 visual rows. Use cursor keys for longer prompts; mouse-wheel events over Prompt do nothing.

Paste normalizes CRLF and lone CR to `\n`, keeps tabs/newlines, and strips other C0 controls, `ESC`, and `DEL`. Explicit `Crossterm Event::Paste` and the Windows text-burst fallback share this policy. At least 3 logical lines or more than 800 UTF-8 bytes collapse to `[Pasted #N · X lines]`. Text starting with `/` after optional whitespace or with `!` remains ordinary text so commands still work. Thresholds are fixed.

The expanded normalized prompt, including hidden paste payloads, is capped at 1 MiB. An oversized edit is rejected in full with `Prompt is limited to 1 MiB; edit rejected`; it is not truncated.

Collapsed pastes act as one unit during cursor movement, deletion, selection, mouse hit-testing, and undo/redo. Submission, selected copy, restored history, and provider input use the full normalized payload. Rejected submissions restore label and payload together. Autocomplete sees only visible text and offsets. Labels contain only local IDs and line counts, while debug output excludes payloads. Typed text resembling a paste label remains ordinary text.

`Alt-V` reads the local desktop clipboard while primary or side Prompt is focused: supported image first, otherwise text. Subagent steering editors do not handle this shortcut. Clipboard access and PNG encoding run in one owned background worker per conversation. Ordinary terminal paste stays unchanged. macOS terminals must send Option as Alt/Meta; otherwise Option-V types `√`. Native Linux Wayland requires compositor data-control support; X11/XWayland is also supported. SSH does not forward the client clipboard; WSL needs access to a supported desktop clipboard.

Images are saved under resolved `$MC_HOME/tmp` (default `~/.magi-code/tmp`) as unique `clipboard-image-N-UUID.png` files. Unix directory/file permissions are `0700`/`0600`; symlinked `tmp` directories are rejected. Images must contain valid RGBA data, fit 16 megapixels, and encode within `capabilities.tools.view_image.max_image_bytes`. Labels use the editor's shared paste numbering: `[Pasted Image #N]` expands to `[View the image here: /absolute/path.png]`. Submitted chat and replay project these references back to labels without changing stored/provider text. The model can inspect the file with `view_image`; outside-project access settings still apply.

Submission waits for pending paste, for up to five seconds. Timeout leaves the draft unchanged and allows submission, but another clipboard request must wait for the old worker to finish; side reset also waits for that worker. If the draft, cursor, selection, or session changes before completion, paste is discarded; press `Alt-V` again. Saved files remain after exit, including discarded pastes, so resumed sessions retain their image references. No automatic cleanup runs; remove files manually only when their session references are no longer needed.

### Editor limits

Undo history retains 50 edits. A collapsed paste counts as one edit and restores its full payload. Non-empty selections copy through OSC52.

Movement is character-based, not guaranteed grapheme-safe. Extremely long prompts can exceed the editor's 65,535-row display coordinates, affecting cursor placement and mouse selection even though logical text is retained. Use smaller prompts in that case. Mouse-wheel scrolling is disabled over Prompt; use cursor keys.

## Follow activity

Transcript occupies the body beside the tab rail. `Shift-Tab` or a rail click switches between Transcript and Changes without removing Prompt. The header shows session and branch information plus panel controls.

Header toggles open **Activity Tree** (`Alt-1`), **Session Files** (`Alt-2`), and **Summary** (`Alt-3`). They overlay the right side by default, at one third of transcript width with a 27-column minimum where space permits. Panels stack in opening order and share the available height. Closing one expands the others; reopening puts it last.

**Pin** (`Alt-A`) reserves a column beside Transcript instead of covering it:

- With no panels open, pinning opens all three. Unpinning then closes them.
- With panels already open, unpinning restores their overlays.
- Closing the last panel turns pinning off.
- Pinned panels hide on Changes and return on Transcript. On narrow terminals, at least half the body remains available to Transcript.

`Esc` closes a focused unpinned panel, or the last opened panel when none has focus, after dismissing autocomplete. Pinned panels ignore `Esc`; use their Alt shortcut or close button. Other dialogs take priority.

Panel order, visibility, and pinning survive session switches and application restarts through global `interface.tui.panel_layout`. Focus and scroll are not saved across restarts. These preferences never enter history or provider requests.

Letters, numbers, `/`, or clicking Prompt return focus to it without closing panels. `Tab` cycles Prompt and Transcript; pinned panels join that cycle in opening order. Clicking a panel focuses it without moving it. Navigation keys act on the focused panel; the mouse wheel scrolls the hovered pane.

In Activity Tree, arrows select or expand rows; `Enter` opens detail. `Ctrl-T` also opens the tree. Session Files uses arrows and Page Up/Down to scroll. In Summary, `Enter` starts or stops generation. Hiding Summary does not stop it.

In Changes without overlays, `Tab` cycles Prompt, Files, Original, and Diff; `Shift-Tab` returns to Transcript. See [Diff review](diff-review.md) for line comments, refresh behavior, storage, and provider visibility.

The prompt border shows run status, provider/model, thinking level, and primary-agent selection. Its footer shows active session time, input/output usage, cache share, estimated context, and the compaction threshold.

Usage totals include primary and child activity and survive resume and compaction. Cache share is cached input divided by total input. Missing updates retain the last known percentage; older unrecorded usage cannot be recovered.

Session time includes foreground provider waits, tools, retries, Bash Mode, manual compaction, and cancellation cleanup. Concurrent child time is not added twice. Idle time and background title/summary work are excluded. An abrupt exit may lose the unfinished interval.

The context bar measures the primary agent's estimated input against its window; `|` marks automatic compaction. It is not an exact countdown. Disabled compaction shows `Auto off`; unknown context shows a placeholder. Narrow layouts omit the bar before clipping text.

The prompt border shows Claude and Codex subscription usage whenever their accounts are connected, regardless of the selected provider or model. Both indicators show percentage **used**. Connected accounts without quota data show `usage unavailable` instead of disappearing.

Claude prefers the five-hour window, falling back to the weekly window. Codex Pro prefers the weekly window; other plans prefer five hours. A missing preferred Codex window falls back to an available one. Claude's five-hour window and Codex's windows show a reset countdown when available.

Background refresh runs at most every five minutes during or shortly after agent work. Missing quota data also retries while idle; failed Claude loads retry after 60 seconds. `/usage` requests fresh data. Keyboard and mouse activity alone do not refresh known quota. Failed Codex auth reads hide its indicator; Claude hides its indicator after three consecutive failed status probes.

Tool cards show status and bounded, sanitized summaries. Write/edit cards update in place; a successful `hash_edit` previews at most four changed lines. Use activity detail for captured output and metadata.

Kitty, Ghostty, and Herdr can show [local image previews](terminal-images.md) in `view_image` cards and completed assistant Markdown. Other terminals keep text. Remote URLs and data URLs are never loaded.

### Inspect complete tool output

Click an activity tree row or select it with Up/Down and press `Enter` to open Selected Activity Detail in a modal. `Escape` closes it and returns focus to the tree. Up/Down, Page Up/Down, and the mouse wheel scroll details without scrolling the panes behind it. Background clicks, typing, and pane shortcuts are blocked while it is open. Left/Right in the tree still collapse/expand activities.

Selected Activity Detail has `Status`, `Tool • <actual name> • <label>`, `Metadata / Params`, and `Sanitized Output`. A successful live `hash_edit` may add `Applied Diff`. Click `▸ Metadata / Params` (or other activities' `▸ Metadata`) to expand; click `▾` to collapse. Selecting another activity resets it to collapsed.

Detail retains all submitted parameters and result-metadata fields with recursive credential redaction and terminal-control sanitization. Output is complete up to each tool's native capture limit; expanded metadata retains truncation details. Parent `subagents` output is not compacted here. Applied diffs are display-only and absent after session hydration.

The rail's [Diff page](diff-review.md) reviews current worktree changes against `HEAD`. Tool-specific diffs remain in activity detail; branch status, `#git-status`, and Git-aware autocomplete remain available.

### Follow subagents

Live subagent cards show aggregate settled/running/failed/waiting counts, clickable task chips, selected intent, recent activity, and `[View Subagent ↗]`. `interface.tui.subagent_card_rows` controls recent activity rows: default `16`, range `1` to `50`.

Chips prefer configured agent names, falling back to task identity. The selection also shows identity and resolved provider/model/reasoning when available. The first task is selected initially; selecting a chip keeps that task selected until another chip is chosen. Activity updates do not switch tasks. View Subagent opens a live viewer for that task and its batch siblings, with tabs and bounded timeline scrolling. Closing leaves the underlying selection/scroll unchanged. Stalled tasks suppress late start events after terminal failure. Selection, scrolling, and drafts remain local display state.

The viewer's bottom prompt uses the primary prompt's styling and keyboard editor, including selection, undo/redo, multiline input, and collapsed paste. Each task keeps a separate draft. Autocomplete offers only `$skill` tags; slash commands are rejected, and a leading `!` is literal steering text, never a shell command. Mouse editing is not supported in this prompt.

- `Enter` queues steering for the selected active child, or accepts visible autocomplete; `Shift-Enter`, `Ctrl-J`, and `Ctrl-Enter` insert a newline, with the same terminal compatibility limits as the primary prompt.
- `Alt-C` recalls that child's pending steering before any existing draft. If none is pending, it requests cancellation of that child, not the primary run or sibling tasks. A busy injection or oversized recall leaves the queue and draft intact.
- `Esc` closes the viewer. `Tab` / `Shift-Tab` switch sibling tabs.
- `PgUp` / `PgDn` and the mouse wheel scroll output. While the prompt is editable, arrow keys belong to the editor, not output scrolling or tab switching. Clicking sibling tabs switches tasks.

Completed children are read-only, but `Alt-C` can still recall unconsumed steering. Failed or cancelled children retain pending input for recall during the current application session; a new primary run is blocked until it is recalled. Accepted steering uses the child's existing continuation and persistence path, not a separate run. See [compaction and steering](sessions-context-cache.md#configure-automatic-compaction).

### Show hooks and injected context

`automation.hooks.show_in_tui=true` shows matching before/after hooks under their tool with running/success/failure status and sanitized phase/label/tool metadata. Default `false` keeps successful hooks quiet.

Provider-injection visibility uses separate `automation.hooks.injected_content` settings: `show_in_transcript` adds local/system rows; `show_in_activity_tree` places rows under the related tool/message, or at the root. Both default to `false`. `style` defaults to `content` (redacted/truncated text); `metadata` shows only label, status, item count, and byte count. These settings affect display only and do not enable injection itself.

## Direct shell commands

Submit `!command` with `!` as the first character to run immediately through guarded bash in cwd, without a provider request or authentication. Tool restrictions, hooks, and cancellation still apply. Command and output are local display only, not durable session history. See [direct shell execution](commands-and-interfaces.md#run-a-shell-command-directly).

## Autocomplete

- `/` as the first character suggests slash commands, including `/help`, `/login`, `/logout`, `/fast`, `/model`, `/settings`, `/skills`, `/sessions`, `/system-prompt`, `/new`, `/export`, and `/quit`.
- `@` anywhere suggests regular files under cwd and inserts slash-normalized relative tags such as `@src/lib.rs`.
- `$` anywhere suggests enabled skills and inserts literal tags such as `$rust-dev`. Tags do not auto-load skills or add provider/session metadata.
- `#` anywhere suggests `#tree`, `#git-status`, and `#diff-changes`. Acceptance only inserts text; it does not run commands or submit. After root user submission, `#tree` and `#git-status` expand through guarded bash; `#diff-changes` uses the review backend to add only unresolved comments, without changed code or a file list. See [prompt context](commands-and-interfaces.md#add-prompt-context) and [Diff review](diff-review.md).

## Updates

After the first frame and every four hours, a bounded background check announces newer stable crates.io versions. `/update` requires idle state, leaves the TUI for Cargo's build output, and reopens the exact session only after cleanup and a successful update. It never replays the initial prompt. See [Installation and updates](installation-and-updates.md#update-with-cargo) for platform behavior, supported installations, and recovery.

## Fast mode

`/fast [on|off|status]` and `/ultrafast [on|off|status]` select mutually exclusive global speed modes while idle. A bare command toggles its mode; enabling the other selects it, and either command's `off` restores Standard. Neither switches models. Status and invalid usage work during a run. Writes share the existing worker off the UI loop; memory changes only after disk success. Pending writes block another mutation, new prompt, or compaction and restore input, while status/help/quit stay usable. Accepted writes settle during cleanup. The startup snapshot is authoritative and successful writes update it for later work.

An unacknowledged persistence-worker failure with no event blocks retry until restart. A delivered failure clears when its matching event is handled.

Fast and Ultrafast highlight the provider/model label instead of showing a separate speed marker. Use `/fast status` or `/ultrafast status` to inspect the requested mode. Fast eligibility follows Codex catalog/fallback rules or explicit custom-provider `fast_mode` metadata; Ultrafast requires catalog-advertised Codex support. See [Configuration](configuration.md). Both apply to eligible primary turns, subagents, and blocking compaction, not title requests. Color terminals animate only provider/model text right-to-left in rainbow colors about every 83 ms: Fast advances one color step, Ultrafast two for twice the movement speed without more redraws. Reduced motion disables animation; without color, bold and underline mark the label. Thinking, context, separators, spaces, and hotkeys keep normal styles. `Alt-M` is hidden during a run while animation stays paced.

## Switch or export a session

`/sessions` shows newest-first sessions, marks the current one, and previews the selection in a second column when space allows. Bounded reads find first and most recent conversational user/assistant messages; tool-only, hook, context-cache, title, and diagnostic events are ignored. Preview text is sanitized/redacted.

`Tab`/terminal-delivered `Shift-Tab` switches list/preview focus; arrows move the list or scroll the preview. Wheel scrolls the hovered column, `Enter` switches from either focus, and `Esc` closes without switching.

`/export` requires an idle run and active persisted session. It rejects arguments and duplicates, runs off the UI loop, and writes a private ZIP under `$MC_HOME/exports` without overwriting. Completion appears in normal status and is ignored if it belongs to a session changed during export. The unencrypted archive contains raw session data and a manifest and may be sensitive; see [export contents and safety](sessions-context-cache.md#export-a-session).

## Exit and cleanup limits

The terminal is restored before worker cleanup. Cancellation is requested first; each critical startup/provider worker gets a 2 s join before detach/error. Non-cooperative detached workers may still have side effects. Decoration gets only a short grace before detach. Accepted Fast persistence has no fixed total join bound if filesystem work stalls after lock acquisition. Export workers are cancelled and joined so publication cannot continue after teardown.

In-flight blocking HTTP MCP POST/body operations, including `notifications/initialized`, cannot be interrupted. A worker detached after 2 s may remain in that call until the configured timeout (default 30 s, maximum 300 s). Cancellation before request start and stdio/pending-response paths remain responsive.

## Controls

| Key | Action |
| --- | --- |
| `Enter` | Submit from Prompt, queue during startup, or accept visible autocomplete. |
| `Shift-Enter` / `Ctrl-Enter` | Insert a newline when the terminal preserves modifiers; otherwise use `Ctrl-J`. |
| `Ctrl-J` | Insert a newline (portable fallback). |
| `Left` / `Right` | Move the prompt cursor by character. |
| `Up` / `Down` | Move cursor vertically in Prompt; otherwise move selection/scroll by focused pane or modal. |
| Mouse wheel over Prompt | Ignored; use cursor keys. |
| `Ctrl-Z` / `Ctrl-Y` | Undo/redo in Prompt; OAuth uses `Ctrl-Y` to copy its URL. |
| `Alt-O` | Open the OAuth URL during provider connection. |
| `Ctrl-Left` / `Ctrl-Right` | Move by word. |
| `Ctrl-Backspace` / `Ctrl-Delete` | Delete previous/next word. |
| `Shift-Arrow` | Extend prompt selection. |
| `Ctrl-A` | Select all prompt text. |
| `Ctrl-C` | Copy non-empty selection through OSC52; otherwise clear input, or exit if empty. |
| `Alt-V` | Paste local clipboard image, otherwise text, into focused Prompt. |
| `Ctrl-D` | Exit. |
| `Alt-P` | Cycle primary agent selection. |
| `Esc` | Focus Prompt, close help/unpinned modal, or cancel a modal action; pinned column modals and provider Saving cannot be closed with Esc. |
| `Tab` | Cycle Prompt/Transcript, including open pinned modals; in Changes without overlays, Prompt/Files/Original/Diff; accept autocomplete; move dialog focus. |
| `Alt-1` / `Alt-2` | Show/hide Activity Tree / Session Files. |
| `Alt-3` | Show/hide the right-side Summary modal. |
| `Alt-A` | Pin/unpin all column modals beside Transcript; pinned modals are hidden on Changes. |
| `Shift-Tab` | Switch Transcript/Changes; pinned modals hide on Changes without closing. Other dialogs retain their own controls. |
| `Ctrl-T` | Open Activity Tree. |
| `F1` or `/help` | Toggle/open help. |
| `Alt-E` / `Alt-C` | Expand/collapse activities; during startup `Alt-C` cancels the queue; during a run it restores queued steering for editing, or requests cancellation when none is queued. Never submits editor text. |
| `Alt-F` / `Alt-R` | Select first failed/running activity. |
| Left click / drag | Position/select prompt text; elsewhere select transcript text, disclose metadata, or use subagent controls. Live viewer consumes mouse input: wheel scrolls and clicks switch sibling tabs. |
| Terminal paste | Apply the normalization, collapse, and byte-limit rules above. |

With steering queued, the prompt border shows `[Alt-C] to edit steering`. Alt-C removes all queued messages and restores them to the prompt in queue order, separated by newlines, followed by any existing draft. The run continues. If the combined text exceeds the prompt limit, the queue and draft remain unchanged. With no steering queued, the border shows `[Alt-C] to cancel`. Cancellation settles at safe runtime boundaries; an already-started blocking provider request or tool may finish its call before the next prompt is accepted.