Handmade Claude Code 6/7 — The TUI

Part six of the Handmade Claude Code campaign: the agent gets a face. Everything so far ran headless — a prompt in, an answer out. A coding agent you would sit in is a conversation: you type, it streams, it shows you the tools it is running and asks before the dangerous ones, it tells you what the session has cost, and when it goes wrong you press a key and it stops.

This session continues the agent you built in parts one to five, in the same repository. The same command without -p opens the terminal UI in the working directory:

<command> -C <dir> [--yes]

The contract

The checks drive your TUI inside tmux (a 120×32 pane), typing keys and reading the screen — so tmux must be installed on your machine, and the screen must say what happened in plain text:

  • An input line that begins with > (whitespace before it is fine). Enter submits; Enter on an empty line does nothing.
  • The answer is shown as it arrives: streamed fragments appear on screen before the final message does.
  • A tool call is shown with the tool's name and what it targets — for bash the command, for read, write, edit, glob and grep the path or pattern, for skill the skill's name, for task the agent's name and the delegated prompt — and, once it finishes, its output (or the head of it). A call that failed is marked as such (error or failed on its line). Several calls in one reply show as several lines.
  • Skills work as they do headless: /<skill> <args> at the prompt sends the skill's body, and the typed line stays in the transcript.
  • Subagents are visible: everything the child does — its tool calls, its answer — is shown marked with the agent's name, so the user can tell the child's activity from the parent's.
  • Without --yes, a call the rules do not permit becomes a question on screen, showing the tool name and its input. y allows it, n denies it (the model gets the usual permission denied result).
  • Slash commands: /help lists the commands, /clear forgets the conversation (the next request carries only the new prompt), /model <provider>/<model> switches to another provider from the settings, /quit exits (so does Ctrl-D on an empty line).
  • A status line shows the session's total input and output tokens, as plain integers.
  • Esc interrupts the running turn: a running tool is killed, no further model call is made for that turn, and the input line is back.

The scripted model is the same one the headless checks use, so what streams, what asks and what gets interrupted is entirely under the check's control — and yours.

The judges

The quality panel — architecture, performance, code quality, test quality, technical governance and DX review — sits on the rungs where its subject is decided, one verdict per judge per rung, on top of the rung's own points. There is no closing review: what you build is judged as you build it, and a rung you never reach is a verdict you never get.

The ladder

  • Set up and carry parts one to five forward (10)
  • It starts and it quits (20)
  • Ask and answer: typed, streamed, billed (30)
  • Tool calls on screen (40)
  • The question (40)
  • Slash commands (20)
  • Skills on screen (30)
  • Subagents on screen (40)
  • Esc means stop (30)
Sessions

0

Visibility

Public

Category

Reinvent the Wheel

Slug

handmade-claude-code-6-tui

Duration

30 min

Judge reviews

~14 per session

Active session

No

Points

10–40

Tags
  • ai-agent
  • harness
  • tui
  • handmade-claude-code
  • campaign
  • 1

    Set up and carry parts one to five forward

    10

    pts / check

    +10 pts per passing check · +10 for completing the task

    This part continues your agent. Same repository, same command, same
    model protocol, tools, context, skills and MCP — what grows is the face:
    the same command without -p opens a terminal UI in the working
    directory.

    agent: started as: -C

    [--yes]

    Your AGENTS.md (or README.md) must still carry the two lines the
    platform captures into session memory: agent: and test:. If you are
    starting in an empty folder, your earlier work is fetched for you —
    check that the lines are there and that the agent still builds and
    runs.

    The checks of this part drive the TUI inside tmux, so tmux must be
    installed. The first rungs re-check that: tmux is there, and the
    headless loop still holds.

    Wrapping claude, codex, gemini, aider or any other coding agent,
    or building on an agent SDK that owns the loop, is not building one.

    Judged by
  • 2

    It starts and it quits

    20

    pts / check

    +20 pts per passing check · +10 for completing the task

    Without -p, the command opens the TUI in the working directory. On
    screen: an input line that begins with > . /quit exits; so does
    Ctrl-D on an empty line. A TUI that will not quit is a terminal you
    cannot get back.

    Judged by
  • 3

    Ask and answer

    30

    pts / check

    +30 pts per passing check · +10 for completing the task

    Type, Enter, read. What is typed on the input line goes to the model as
    the prompt, exactly as typed; the answer appears on screen as it is
    written — a text_delta fragment shows as soon as the model prints it,
    before the final message. And a status line shows what the session has
    cost so far: the total input tokens and the total output tokens every
    reply reported, as plain integers — 8642 is 8642, not 8.6k.

  • 4

    Tool calls on screen

    40

    pts / check

    +40 pts per passing check · +10 for completing the task

    The user sees what the agent does. Every tool call shows on screen with
    the tool's name and what it targets — for bash the command, for
    read, write, edit, glob and grep the path or pattern — and,
    once it finishes, its output or the head of it. A call that failed
    (is_error) is marked as such: the word error or failed on its
    line. Several calls in one reply show as several lines. Then the answer.

  • 5

    The question

    40

    pts / check

    +40 pts per passing check · +10 for completing the task

    Without --yes, a call the rules do not permit is not refused — it is
    asked. The screen shows the tool's name and its input, and waits: y
    runs it, n denies it and the model gets the usual permission denied
    result. Either way the loop goes on.

  • 6

    Slash commands

    20

    pts / check

    +20 pts per passing check · +10 for completing the task

    /help lists the commands the TUI understands — at least /help,
    /clear, /model and /quit. /clear forgets the conversation: the
    next prompt goes to the model alone, without the earlier turns.
    /model <provider>/<model> switches to another provider from the
    settings for the rest of the session.

  • 7

    Skills on screen

    30

    pts / check

    +30 pts per passing check · +10 for completing the task

    The TUI knows the project's skills the way the headless mode does. A
    line /<skill> <args> typed at the prompt is a slash command: the
    skill's body goes to the model, expanded exactly as in headless mode,
    and the transcript shows what was typed. When the model calls the
    skill tool, the call shows on screen with the skill's name, and the
    result — the skill's instructions — with it.

    Judged by
  • 8

    Subagents on screen

    40

    pts / check

    +40 pts per passing check · +10 for completing the task

    Delegation is visible. A task call shows the agent's name and the
    delegated prompt; everything the child does — its tool calls, its answer
    — is shown marked with the agent's name, so the user can tell the
    child's activity from the parent's; then the parent's answer.

    Judged by
  • 9

    Esc means stop

    30

    pts / check

    +30 pts per passing check · +10 for completing the task

    Things go wrong and the user must be able to stop them. Esc interrupts
    the running turn: a tool still running is killed, no further model call
    is made for that turn, and the input line is back. The next prompt
    starts a fresh turn.