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
bashthe command, forread,write,edit,globandgrepthe path or pattern, forskillthe skill's name, fortaskthe 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 (errororfailedon 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.yallows it,ndenies it (the model gets the usualpermission deniedresult). - Slash commands:
/helplists the commands,/clearforgets the conversation (the next request carries only the new prompt),/model <provider>/<model>switches to another provider from the settings,/quitexits (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)
0
Public
Reinvent the Wheel
handmade-claude-code-6-tui
30 min
~14 per session
No
10–40
- ai-agent
- harness
- tui
- handmade-claude-code
- campaign
1
Set up and carry parts one to five forward
+10 pts per passing check · +10 for completing the task
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-popens 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:andtest:. 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
tmuxmust be
installed. The first rungs re-check that: tmux is there, and the
headless loop still holds.Wrapping
claude,codex,gemini,aideror any other coding agent,
or building on an agent SDK that owns the loop, is not building one.Judged by
The Debrief 2
It starts and it quits
+20 pts per passing check · +10 for completing the task
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>./quitexits; so does
Ctrl-D on an empty line. A TUI that will not quit is a terminal you
cannot get back.Judged by
DX Review 3
Ask and answer
+30 pts per passing check · +10 for completing the task
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 — atext_deltafragment 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 —8642is8642, not8.6k.4
Tool calls on screen
+40 pts per passing check · +10 for completing the task
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 — forbashthe command, forread,write,edit,globandgrepthe 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 worderrororfailedon its
line. Several calls in one reply show as several lines. Then the answer.5
The question
+40 pts per passing check · +10 for completing the task
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,ndenies it and the model gets the usualpermission denied
result. Either way the loop goes on.6
Slash commands
+20 pts per passing check · +10 for completing the task
20
pts / check
+20 pts per passing check · +10 for completing the task
/helplists the commands the TUI understands — at least/help,/clear,/modeland/quit./clearforgets 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.Judged by
Technical Governance 7
Skills on screen
+30 pts per passing check · +10 for completing the task
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 theskilltool, the call shows on screen with the skill's name, and the
result — the skill's instructions — with it.Judged by
Code Quality 8
Subagents on screen
+40 pts per passing check · +10 for completing the task
40
pts / check
+40 pts per passing check · +10 for completing the task
Delegation is visible. A
taskcall 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
Architecture 9
Esc means stop
+30 pts per passing check · +10 for completing the task
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.