First session — a 10-minute TUI tour¶
A scripted walk through the TUI for someone who has task run on
their screen for the first time. Each step names the keystroke, what
you should see, and the why (the design rationale lives in the
linked pages; this page is the muscle-memory guide).
If you haven't installed yet, start at Install. If you haven't pointed kin at a model, start at First run. This page assumes both are done and you have the welcome banner on screen.
What you're looking at¶
Before you type anything, identify the four regions of the screen:
┌──────────────────────────────────────────────────────────────┐
│ ⭘ kin qwen3.6-35b-A3B · 1.2k/262k · ⎇ main 14:32 │ ← top bar
├──────────────────────────────────────────────────────────────┤
│ │
│ (transcript — empty until you send your first message) │
│ │
├──────────────────────────────────────────────────────────────┤
│ ▌ ask me anything… │ ← composer
├──────────────────────────────────────────────────────────────┤
│ · · · · · thinking ⓐ │ ← status bar
└──────────────────────────────────────────────────────────────┘
- Top bar — model name (left), context usage (right). Updates as the turn progresses.
- Transcript — where everything lands: your messages (rounded
titled boxes from POLISH r3), the model's replies (flat with
▌ KINaccent), reasoning (collapsed by default, italic dim periwinkle from r5), tool calls (rounded with a▌running marker), and tool results. - Composer — multi-line
TextArea.entersends,shift+enterinserts a newline. - Status bar — left cell shows what kin is doing (a cosine-swept
cyan shimmer over a phase word from r6); right cell shows the
current mode (
auto/strict) as a glyph.
The colors: cyan = the live signal (your model speaking), periwinkle = the private thinking channel (collapsed reasoning), graphite ground. See The Graphite+ identity for the why.
Exercise 1 — your first message¶
Type a question and press Enter.
What you should see:
- The composer border thickens briefly while the turn runs.
- The status bar's left cell animates a phase word (a
thinking/mulling/tracingflavor rotates every ~4s when there's no specific label). Reduced-motion:TEXTUAL_ANIMATIONS=nonecollapses the shimmer to a solid cyan label — see REFERENCE.md § UI widgets & theme for the frame-0 invariant. - The model's reply streams in cyan as markdown. Tool calls (if any)
render as rounded rows with their
name(args_summary)title and a live tail while the tool runs. - When the turn ends, the status bar returns to idle (
·glyph, no label), and the composer is focused again.
Exercise 2 — reasoning (collapsed thinking)¶
If the model thinks before replying, you'll see the reasoning render
as a periwinkle italic block with the two-tone title (thinking…
streaming, then thought · 4s when finished).
- The reasoning is collapsed by default (the
▸toggle on the left edge of the block). - Press Ctrl+N to expand ALL reasoning blocks in the transcript.
- Press Ctrl+N again to collapse them back.
- Press Esc first to dismiss any open modal — the toggle is a binding, not a command.
Exercise 3 — interrupting a turn mid-flight¶
Start a long-ish prompt and interrupt it.
About halfway through, press Esc. What you should see:
- The status bar's busy animation stops.
- The partial assistant text stays in the transcript with a
· interruptedmarker. - The composer is focused again, ready for your next message.
Why Esc always works: the turn runs as a Textual @work
worker (group agent_turn); Esc cancels the worker, the
in-flight tool's finally runs, the UI returns to idle. No
subprocess signal-juggling, no "did the child see the SIGINT" race.
See Architecture.
Exercise 4 — queueing a follow-up¶
The composer holds one queued message (latest-wins, shown as its border title while a turn is busy).
Start a turn, then while it's running, type a second prompt and press Enter. You'll see:
- The composer's border title shows the queued message.
- When the first turn finishes, the queued message flushes automatically — no need to press Enter again.
- If you type a THIRD message while the queued one is still queued, the queue replaces it (latest-wins).
The harness drops a mid-turn user message if you manage to send two before the first flushes — see src/kin/tui/CLAUDE.md § "Inbound / outbound / interrupt".
Exercise 5 — slash history¶
Type / and the slash menu opens. Type mo and the menu filters
to /mode. Press Tab to fill, then Enter to run. The status
bar's right cell toggles between auto and strict.
Press Up / Down in the composer to recall slash-command history. Press Left / Right to recall your message history.
Exercise 6 — cursor mode¶
Press Ctrl+B to enter cursor / browse / copy mode. The transcript
becomes navigable with Up / Down / ++page+up++ / ++page+down++.
Press a row's o or Enter to open the buffered output of a tool
call in a read-only modal. Esc exits cursor mode.
Try Ctrl+B while the composer has unsent text — the mode will refuse to enter (cursor mode requires the composer be empty). The fix: send or clear the composer, then re-enter cursor mode.
Exercise 7 — mode toggle¶
The mode badge lives in the right cell of the status bar (ⓐ = auto,
ⓢ = strict). Press Shift+Tab to toggle. What changes:
- auto (default) — edits + shell run without per-call prompts. Shell runs under the OS sandbox (macOS Seatbelt / Linux bubblewrap). The status bar shows the posture line ("auto · shell sandboxed (Seatbelt)" or similar).
- strict — every edit / MCP / non-allowlisted shell command asks before running. Provably-read-only shell commands still auto-allow via the shell allowlist.
Mode persists across turns; /mode <name> swaps at runtime;
session approvals ("always allow this") are stored per-call-signature
and survive mode toggles. See Modes & permissions.
Exercise 8 — a planning freeze¶
Type a question that triggers planning:
If the model decides to use the planner subagent (or calls
write_plan directly), the session enters a read-only planning
freeze:
- The status bar shows a planning badge on the left.
- All editing tools (
write_file/edit_file/shell) are denied for the duration of the freeze. - The
present_planmodal lands with three options: keep (the plan is your new plan; clear and re-inject just the plan), accept & execute (the plan becomes the next user turn, the freeze lifts), or send to critic (the adversarial plan-reviewer runs first). - The freeze has no other exit — you can't toggle out of it with
/modeorshift+tab. Press the modal's button (or Esc to cancel — the modal closes, the freeze stays).
See Modes & permissions § Planning for the full lifecycle.
Exercise 9 — sessions and /resume¶
Press Ctrl+R (no — wait, that's history search now). The
session picker is /resume. Type /resume and the modal lists
recent sessions (newest first) with a cur_<b64url(ts:id)> cursor.
Pick one — the journal replays into the transcript, the loop
rehydrates the session state, the conversation continues from where
you left it.
Type /sessions to see the full list (read-only). The journal files
are JSONL append-logs at ~/.kin/projects/<project>/<session>.jsonl
— cat one to see the event shape, or tail -f it while a turn
runs to watch events land in real time.
Exercise 10 — quitting cleanly¶
Press Ctrl+C. The session closes, the journal is sealed, and
the bg subsystems (run_code kernel, browser, MCP sessions) tear
down via Session.aclose. The next launch with kin --resume <id>
rehydrates from disk.
If you don't want a journal at all, launch with --no-save
(KIN_NO_SAVE=1). The session can't be resumed — useful for
throwaway questions. See Sessions for the
full lifecycle.
Where to next¶
- Configuration — make your model setup permanent (settings.toml layering, env vars).
- Modes & permissions — the full mode × tool matrix, the planning freeze, the shell allowlist.
- Keybindings & cursor mode — the complete key map (every binding, every modal, the cursor-mode surface).
- Slash commands — every
/-command (built-in + custom.mddiscovery). - Outpost — the same kin in a browser tab, with scheduled jobs and a workspace-centric Run surface.