Mission Control TUI
Mission Control user guide · Technical reference index · Repository README
Purpose
Use Mission Control to edit prompts, follow tools and subagents, inspect captured output, and change settings without leaving the terminal.
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.
Details
Startup and readiness
You can edit the prompt as soon as Mission Control draws its first frame, before execution is ready. Settings/config, instructions, skill discovery, and session setup/discovery happen earlier. Background session pruning starts on an unjoined thread before TUI entry. It may overlap startup but does not block readiness.
Execution waits for the current settings/policy snapshot, selected primary agent (or explicit None), enabled subagent profiles, and all enabled MCP servers to connect, initialize, and complete tools/list. Failures in the selected profile, an enabled subagent, or strict MCP startup block execution. Diagnostics from unselected or disabled profiles only warn. Autocomplete, titles, Git/branch data, and other decoration are best effort and do not block. This MCP gate is stricter than magi-code mcp list; see MCP tools.
The controlled TestBackend responsiveness gate requires <50 ms> from receipt of a process-side edit through bounded event draining and state projection to a completed Ratatui draw. It excludes whole-process startup and physical terminal write/flush. The <16 ms> physical-terminal target is non-gating and unverified; no physical TTY test has run.
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 Codex, Anthropic, 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-Tabmoves between these buttons and the redacted redirect field;Enteractivates the focused control. Copy the final browser redirect URL, paste it into the field, and pressEnter.Esccancels 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.devprovider override. The override selects an exact catalog namespace. Blank uses the provider ID and clears an existing override on replacement.Tab/Shift-Tabmoves between fields; compact layouts show the focused field. Reusing an ID requires confirmation:Enterreplaces it, whileEscreturns to the form. - After success,
Enter/Esccloses. After an error,Enterretries,Backspace/Leftgoes back, andEsccloses. 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 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 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.
Editor implementation limits
One PromptEditor wraps the canonical TextArea, which owns visible text, cursor, selection, viewport mapping, and native edit state. Paste payloads live in a private sidecar. The dependency is pinned:
tui-textarea = { package = "tui-textarea-2", version = "=0.13.2", default-features = false, features = ["no-backend", "search"] }
Ordinary drafts use its bounded 50-entry native history. With a collapsed paste, semantic history uses the same 50-edit limit and restores each payload as one edit, without an application-level mirrored history index. Startup queuing, the paint fence, active steering, and rejected-submit restoration remain application behavior. Rendering uses the visible projection, preserves focus/blink behavior, and uses the rendered textarea mapping for mouse selection. Selected non-empty text copies through OSC52.
Movement is character-based, not guaranteed grapheme-safe. Logical text, cursor, selection, and history are lossless, but measured screen rows/private viewport coordinates use u16. Beyond u16::MAX rendered rows, the visible window, native cursor, or mouse hit-testing may be wrong. The internal search fallback handles logical zero-width scalar positions and clears its temporary pattern after movement; it does not fix viewport limits or grapheme handling. The exact pin stays until a reviewed upstream lossless viewport-row fix permits enabling the ignored real-render diagnostic. Wheel scrolling is disabled because the public scroll API changes cursor/selection and exposes no independent viewport control.
Follow activity
The right column is visible by default. Its far-right rail, when space allows, selects Activity, Summary, or Diff. Activity contains the tree and Session files; Summary contains only the summary log and controls. Diff replaces the body with worktree review while retaining Prompt and the rail. Alt-1 selects Activity without moving focus, unless Summary is focused; then it restores the last Activity pane's focus because Summary is now hidden. Alt-2 selects Summary and returns focus to the prompt when visible. Clicking a rail label selects that view. Alt-A hides/shows the conversation's column and rail without persisting the choice. The hidden column's show action appears in the transcript title.
Normal Tab cycles Prompt, Transcript, Activity Tree, and Session files, or Prompt, Transcript, and Summary when Summary is selected, revealing the right column when needed. Modals/autocomplete use their own Tab behavior. Ctrl-T focuses the Activity Tree.
In Diff, Tab cycles Prompt, Files, Original, and Diff; Shift-Tab reverses the order. See Diff review for line comments, refresh behavior, storage, and provider visibility.
The prompt border shows running/cancel status and Bash Mode upper-left, with provider/model/thinking controls and agent selection upper-right. Lower-left shows Session: 14m18s • 123k(in)│ 18k(out)│ 76%(cache) • Current Ctx: 62% [######..|.] 200k • Compact at 80%. Session usage fields have fixed widths and theme colors; unknown context shows —% [..........] —. Session totals include primary and subagent activity and persist across resume and compaction. Cache share is total cached input divided by total input. While usage is incomplete, the display retains this session's last known cache percentage; — appears only before a known value. There is no partial indicator. Older history cannot recover usage that was never recorded.
Session time counts foreground Mission Control prompt workers, Bash Mode, and manual compaction, including provider waits, tools, retries, and cancellation cleanup. Concurrent children share the parent's interval; their times are not added. Idle time, time with the app closed, and background title/summary work are excluded. The footer ticks while work is active, including with reduced motion. Completed worker intervals are saved as local-only session records and survive resume and history rotation. Older sessions start from zero for unrecorded work; an abrupt process exit can lose the unfinished interval.
The bar shows the primary agent's current context against its full window; | marks the configured auto-compaction threshold. This is not an exact countdown: compaction checks projected next-request input. Disabled compaction shows Auto off. Provider controls show idle [Alt-M], or a login fallback. Narrow layouts omit the bar before clipping text. Context refreshes with estimates; model/session switches hide it until recalculated. The prompt's lower-right border shows MAGI-CODE vX.Y.Z. The transcript header shows Cwd: <cwd> • Branch: <branch> when available.
When magi-code has a Codex login, the top-right prompt border starts with Codex 72/100%(w) • before the model controls, even if another provider is selected. This is percentage used, rounded to a whole number: Pro shows the weekly window (w); other or unknown plans show five hours (5h). A missing matching window hides the indicator. One background worker serves this indicator and /usage. It fetches on connection, then at most once every five minutes while a prompt is running or real agent/subagent events occurred within the preceding five minutes. Idle keyboard/mouse input does not trigger quota refreshes. /usage explicitly requests fresh data and shares an in-flight fetch. Local auth checks run off the UI thread every five seconds; disconnects and failed reads hide the indicator. Account changes during a fetch discard that snapshot; same-account token refreshes preserve it.
Transcript cards have single-row, full-width role headers and status marks, with no blank header rows. Body padding and user-card spacing are unchanged. A visual scrollbar replaces textual position labels. Tool cards show bounded, sanitized summaries tailored to browser, bash, read, grep/AST grep, web/code search, find, list-files, write, hash_edit, and view_image. Write/edit cards update in place from running to success/cancelled/failed. Successful hash_edit shows at most four changed diff lines, marked as a limited preview.
Kitty and Ghostty can show local image previews 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 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.
Enterqueues steering for the selected active child, or accepts visible autocomplete;Shift-Enter,Ctrl-J, andCtrl-Enterinsert a newline, with the same terminal compatibility limits as the primary prompt.Alt-Crecalls 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.Esccloses the viewer.Tab/Shift-Tabswitch sibling tabs.PgUp/PgDnand 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.
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.
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,#treeand#git-statusexpand through guarded bash;#diff-changesuses the review backend to add only unresolved comments, without changed code or a file list. See prompt context and Diff review.
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 for platform behavior, supported installations, and recovery.
Fast mode
/fast, /fast on, and /fast off change the global setting while idle; /fast status and invalid usage work during a run. Writes run 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 mode highlights the provider/model label instead of showing a separate Fast: marker. Use /fast status to inspect its state. Eligibility follows Codex catalog/fallback rules or explicit custom-provider fast_mode metadata; see Configuration. It applies to eligible primary turns, subagents, and blocking compaction, not title requests. Color terminals may animate only provider/model text right-to-left in rainbow colors about every 83 ms. 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.
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. |
Ctrl-D | Exit. |
Alt-A | Hide/show right column and rail; hiding moves its focus to Transcript, showing keeps focus. Not persisted. |
Alt-P | Cycle primary agent selection. |
Esc | Focus Prompt, close help/modal, or cancel a modal action; provider Saving cannot be cancelled. |
Tab | Cycle Prompt/Transcript/Activity Tree/Session files or Prompt/Transcript/Summary; in Diff, Prompt/Files/Original/Diff; accept autocomplete; move modal focus. |
Alt-1 / Alt-2 | Select Activity/Summary; Activity preserves focus unless leaving focused Summary, Summary returns focus to Prompt. |
Shift-Tab | Cycle panes backwards, reversing Tab's pane order and revealing the column if hidden; previous custom-provider field or session-list focus in modals (requires terminal BackTab). |
Ctrl-T | Focus Activity Tree. |
Ctrl-Shift-Right / Ctrl-Shift-Left | Activity-focused/transcript-focused columns; Alt-Right/Alt-Left are terminal-dependent aliases. |
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.