feat(ui): see and reach the agent's terminal - #44
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
57e7f0f to
8636260
Compare
fcb2b70 to
7db7eba
Compare
8636260 to
13e71a4
Compare
7db7eba to
f893416
Compare
13e71a4 to
caaaaf8
Compare
f893416 to
934f2a5
Compare
caaaaf8 to
d679934
Compare
934f2a5 to
e2c2202
Compare
d679934 to
6e93a80
Compare
e2c2202 to
bca13d6
Compare
6e93a80 to
853edf6
Compare
bca13d6 to
ba723b4
Compare
853edf6 to
d90c5f3
Compare
ba723b4 to
2ebb732
Compare
67ad575 to
6f718b9
Compare
c462779 to
420f655
Compare
6f718b9 to
1db148c
Compare
A tmux pane id like `%9` is a server handle: it names no window a reader can place, and two agents in one worktree are told apart by their window rather than their pane. One `tmux list-panes` per sample now resolves every lane at once into `session:window.pane`, however many lanes there are. That address is a column of its own and a field on the detail; the raw `%N` stays on the lane as the handle every action addresses, and never enters a name. `laneNameParts` listing `pane` selects that column. It composed nothing into a name and could not simply be dropped, because `validate` rejects an unknown part and every stored config naming it would stop vsys from starting. Giving it work again settles that without breaking a single stored file. The agent detail gains a Terminal section holding the last lines its pane drew, read only while the section is open and again on each sample so it keeps moving. That text is the agent's own output, so it is treated as hostile: complete escape sequences are dropped and every remaining control byte is removed, which is what stops a captured line moving the cursor, repainting the screen or writing the clipboard. Go to terminal moves the reader's own tmux view when vsys is a client of the server holding that pane. Outside it there is no view to move, so the row hands over `tmux switch-client` through the clipboard and says why. Neither reading a pane nor moving a view touches a process, so neither waits on write mode, and no terminal emulator is ever launched: the program that would open one differs on every desktop and does not exist on macOS. No tmux, or no server answering, and the column is absent, the section says so and nothing else on any screen changes. Also corrects three references in the verdict document to a test file deleted in abca412, whose cases now live in `src/ui/attention.test.ts`. Claude-Session: https://claude.ai/code/session_01B4rKWUEy6WF5MRxtBEwFdB
1db148c to
ade7d51
Compare
|
Closing in favour of a fresh pull request on the same branch, with the same head This pull request was opened against So the review this work needs can only come from a pull request that is new. |
Phase 7 of #24: see and reach the agent's terminal. Stacked on #43.
The address, not the pane id
TMUX_PANEis a server-global pane id like%9. A tmux session holds windows and a window holds panes, so the pane id alone throws that structure away. On the machine this was built against,%9resolves tovsys:1.1and%13tovsys:2.1— two agents in the same worktree, separated by the window, not the pane.%17and%21are two panes in one window.src/collect/tmux.tsis the one place that talks to a tmux server. A capability probe decides whether one answers, and the probe is taken as an argument so no test spawns tmux. Onetmux list-panes -aper sample resolves every lane; the collector calls it once and hands the map to the lane builder.The lane keeps the raw
%Nas the handle every action addresses. The resolvedsession:window.paneis a column of its own and a field on the detail — identity a name should not carry, beside the process id for the same reason.The format string uses tabs, not spaces. A tmux session or window may be named with a space, and a space-separated line cannot then be split back into the values it carried. A test covers a session named
my work.laneNamePartslistingpanenow selects that column. It had no work and could not be dropped:validaterejects an unknown part, so every stored config naming it would stop vsys starting.Seeing the pane
A
Terminalsection on the agent detail holds the last lines that pane drew, read only while the section is open and again on each sample. A pane that has gone away says why rather than showing an empty box.Captured text is treated as hostile. Complete escape sequences are dropped first for legibility, then every remaining control byte is removed. That order is the guarantee: anything the sequence patterns miss still loses its control bytes, so the safety does not rest on a regex being complete. Tested at both levels — on the parsed lines, and on the rendered frame plus the clipboard stream.
Reaching the pane
Go to terminalrunstmux switch-clientwhen vsys is a client of that same server. It moves the reader's view and does not touch the agent's processes, so it does not sit behindwriteMode. When vsys is not in that server, the row copies the command through the phase 1 clipboard path and says why it cannot switch.No terminal emulator is ever launched.
$TERMINAL -e …names a program that differs on every desktop and does not exist on macOS, whileswitch-clientbehaves the same everywhere tmux runs.Checked against a live server, not only stubs
19 panes resolved with their window names. A capture returned 52 readable lines with its escapes gone. A missing pane answered
can't find pane: %99999, which is the wording the section shows a reader. The unit tests stub tmux, so this is the part they could not tell.One trade-off, chosen and pinned
At 180 columns beside the side pane, the address column and the trend column cannot both fit under the name floor. The trend goes: the address is identity nothing else on the row carries, and the trend's own number is already in the CPU column beside it. Both widths are pinned by a test, so the priority cannot flip silently.
Proof
376 tests, 0 fail. Ten plants, each reddening its own test.
This line read 362 while the branch sat under #43. Two things moved it. The stack was replayed onto the merged phase-5, which carries four tests the review rounds added there. And 362 was itself one too high: a duplicate test entered during the test-file split, so every suite figure from that commit onward overstated by one until it was found. #43 records how — a by-name body comparison collapses two identical tests to one key and reads as no loss, so only the count carries that evidence.
Also fixed here: three references in
docs/architecture/verdict.mdnaming a test file deleted in the redesign. Each bullet's cited phrase was confirmed present in the successor rather than assumed.Part of #24.
https://claude.ai/code/session_01B4rKWUEy6WF5MRxtBEwFdB