Claude Code grabs no mouse and stays off the alternate screen, so a plain terminal answers the wheel with its own scrollback and the child never hears about it. The fullscreen pane is that terminal, so it does the same job: the view is a stable row index into wezterm-term's scrollback, which pins the rows you scrolled to while the child keeps writing. The ctrl-l transcript wipe is cancelled while fullscreen — there the pane is not prompt-only, and its transcript is the thing being scrolled.
claude-cloak
A TUI that displays Claude Code's streams token-by-token — thinking, text, and tool calls — by sitting as a pass-through proxy between Claude Code and the Anthropic API.
No extra usage: it never issues requests of its own; it observes the SSE stream of requests Claude Code was already making, forwarding bytes verbatim and unbuffered.
claude ──ANTHROPIC_BASE_URL──▶ claude-cloak (127.0.0.1:8484) ──▶ api.anthropic.com
│
▼
TUI: live token feed
Usage
cargo build --release
./target/release/claude-cloak
Then point Claude Code at the proxy, either per-shell:
export ANTHROPIC_BASE_URL=http://127.0.0.1:8484
claude
or globally in ~/.claude/settings.json:
{ "env": { "ANTHROPIC_BASE_URL": "http://127.0.0.1:8484" } }
Note: with the global setting, Claude Code can't reach the API while the proxy isn't running.
Keys
| key | action |
|---|---|
q / Esc |
quit |
Tab / Shift-Tab |
switch session |
j/k, arrows, PgUp/PgDn |
scroll (disables follow) |
f / G / End |
follow live tail |
g / Home |
jump to top |
Display
- ✻ thinking — dim italic, streamed token-by-token
- text — rendered as markdown (
tui-markdown) - ⚙ tool calls — input JSON pretty-printed on completion, raw fragments while streaming
- meta — message boundaries with model, context size, stop reason, token counts
- errors — API/stream errors in red
Sessions are keyed by the Claude Code session ID found in request metadata; concurrent requests (subagents) tap independently.
--headless runs the proxy without the TUI. CT_PORT overrides the port (default 8484).
Hot reload
Swap a running instance onto a newly built binary with ctrl-r — without
losing the proxy port, the embedded claude pane, or the live feed.
cargo build # in any terminal, whenever you like
# then press ctrl-r in each running instance
claude-cloak never builds anything itself and watches no files. You rebuild the way you always would; ctrl-r says "run that one now".
ctrl-r execs the same path the instance was started from, so a debug instance reloads onto a rebuilt debug binary and a release instance onto a rebuilt release one. It does not cross profiles.
How it survives
The app execves the new binary into its own process, so the pid, the open
file descriptors and the child processes all stay. Before the exec the proxy
drains: it stops accepting and lets in-flight responses finish, while the
listening socket stays open so requests made during the swap wait in the kernel
backlog and are served by the new code. Nothing is refused and nothing is
truncated.
The footer shows ⟳ reloading… while it drains, then · reload #1 once the new
code is running. A failed exec — ctrl-r pressed while the linker still had the
file open — reports ⚠ reload failed: … and changes nothing; press it again.
A state snapshot the new types no longer fit costs the feed only — never the port and never the pane.