anvilsign in

collin/anvil

1# tmux configuration for anvil agent sessions.
2#
3# The browser terminal is the only client, so the usual interactive niceties
4# (status bar, prefix gymnastics) are noise. What matters is that the pane
5# behaves like a real terminal for a TUI and that scrollback is deep enough to
6# replay on reconnect.
7
8# Status bar at the top. Note: `capture-pane` (the reconnect snapshot) only
9# ever sees pane content, never this bar — it's client chrome — so a browser
10# that reconnects gets a one-row jump versus the live view until the next
11# repaint. Cosmetic, not a correctness issue.
12set -g status on
13set -g status-position top
14
15# Mouse reporting through to the application, so a TUI's click targets and
16# scroll work in the browser.
17set -g mouse on
18
19# Forward focus in/out (DECSET 1004) to the pane. Without it Claude Code warns
20# on startup and can't tell when the browser tab is focused — wterm's input
21# layer already tracks real DOM focus/blur on the terminal element and turns
22# it into the same escape sequences, this is what lets tmux pass them through.
23set -g focus-events on
24
25# Deep scrollback — `capture-pane -S -` replays this on reconnect, and an agent
26# session produces a lot of output before anyone looks at it.
27set -g history-limit 50000
28
29# 256-colour + true-colour advertisement. wterm's core resolves 24-bit SGR, so
30# there is no reason to let tmux downsample.
31set -g default-terminal "tmux-256color"
32set -ga terminal-overrides ",*256col*:Tc"
33
34# The attached client is always anvil's own websocket bridge (see
35# container.rs's `attach`), never a real terminal tmux can query — so rather
36# than rely on tmux's built-in detection for the client's TERM (xterm-256color,
37# set in `attach`'s exec env), say explicitly that it understands OSC 8. wterm
38# already parses OSC 8 (docs/agent-sessions.md); this is what lets those
39# sequences reach it instead of being dropped in tmux.
40set -ga terminal-features ",*:hyperlinks"
41
42# Keep the pane after its command exits, so the browser can still read the last
43# screen; the entrypoint decides when the container is actually done.
44set -g remain-on-exit on
45
46# With remain-on-exit on, a dead pane never actually closes — it just stops
47# accepting input — so tmux never re-selects for it the way it would if the
48# pane were destroyed. `pane-died` is the hook that fires for exactly that
49# case (see tmux.1: "the program running in a pane exits, but remain-on-exit
50# is on so the pane has not closed"). Only matters once something splits the
51# window — a single-pane session has nowhere else to go — which is what a
52# Claude Code teammate spawned with `teammateMode: tmux` would do.
53set-hook -g pane-died 'select-pane -t :.+'
54
55# Do not renumber or rename out from under the supervisor, which addresses the
56# session by name.
57set -g allow-rename off
58
59# With several browsers attached, size the window to the most recently active
60# client rather than the smallest. The default ("smallest") means one phone
61# viewer squeezes everyone else's terminal down to its width for as long as it
62# stays connected.
63set -g window-size latest