Remote pane · built and measured

State above the input, receipts under their message

Two placements. The connection state moves out of the bottom row to sit between the log and the line you type on, drawn with the same braille mark the terminal traces use — the spinner while it is working, that motion's completed path for everything else. And a message's delivery receipt moves from the right of its text to the bottom of the message's own block.

The built pane

Screenshots of the real component, driven against a real server: the states are produced the way the product produces them, not by setting classes.

the pane's lower edge showing the braille spinner and the word working above the input
working — the braille spinner, animating. The newest word in the log is the operator's and the agent has not answered yet.
the pane's lower edge showing a small hollow rectangle and the word listening
listening — the spinner's completed path, still, in the same accent. The agent has answered and is polling.
the pane's lower edge showing a muted hollow rectangle and the words not connected
not connected — the same path, muted. Disconnected, or nothing has polled recently.
the same row at 150 percent, everything larger including the mark
the pane's zoom — the mark grows with the row, 12.5px to 18.7px at 150%. It is sized as a ratio of the pane, not from the contract's absolute pixels.
two messages in the log, one with a delivered tick beneath it and one with pending beneath it
The receipts, under the messages they belong to: a tick and delivered for a message a poll has collected, pending for one it has not. The second message wraps to two lines and its receipt still starts on the text's left edge.

The app's own words for the three states are working, listening and not connected (REMOTE_STATE_LABEL) — a remote agent has no process here to be "stopped", only a connection that is or is not there.

The same three, live

A screenshot cannot show the spinner moving, and the braille is the point. These are drawn from the app's own stylesheet, in this page.

working
laptop-carver ⇪ ⏹ ✕
❯
rerun the eval with the rebuilt tokenizer and report perplexity delivered
Starting the run…
working
❯message this agent
claude·~/work/video-cuts ·on carver-mbp last seen 2s ago↵ send · ⇧↵ newline
listening
laptop-carver ⇪ ⏹ ✕
❯
can you check the tokenizer on the 7B run? delivered
Checked — the merges file is stale. Rebuilt it and the eval matches now.
listening
❯message this agent
claude·~/work/video-cuts ·on carver-mbp last seen 8s ago↵ send · ⇧↵ newline
not connected
laptop-carver ⇪ ⏹ ✕
❯
when you are back: pull the new cuts and re-render scene 4 at 60fps, then tell me the render time and whether the audio drifted on the long takepending
not connected
❯disconnected — a message will wait in the log
claude·~/work/video-cuts ·on carver-mbp ↵ send · ⇧↵ newline

The mark is the app's state vocabulary — one measured contract for the spinner's type, cell and ink, and the still path derived from it. Nothing new to keep in sync, and no second thing that also means busy.

What moved, and what stayed

FactWasNowWhy
state (working / listening / not connected)bottom rowabove the inputit changes second to second and it is what you check before typing
harness · working directory · hostbottom rowbottom rowidentity, not state — CLI bottom-row furniture
last seenbottom rowbottom rowkeeps one place that narrates time; on the state row it would say when in two voices
↵ send · ⇧↵ newlinebottom rowbottom rowa keyboard legend, not a state
the state word in the bottom rowled the rowgoneit moved; a copy left behind would say the same word twice, forty pixels apart

Two indicators on one pane?

The header keeps its StateLogo — the CLI tile whose frame carries the state, which every pane in the app has and the sidebar matches. The new row is the one with a word. Different shapes at opposite ends of the pane: which agent this is, and what it is doing right now. Terminal panes already pair a header mark with a working line in the body; this is that pairing. If it still reads as one too many, the header logo is the one to drop, because the new row says more.

The two things that could have gone wrong

a long message at 260px, pending
laptop-carver ⇪ ⏹ ✕
❯
when you are back: pull the new cuts and re-render scene 4 at 60fps, then tell me the render time and whether the audio drifted on the long takepending
listening
❯message this agent
claude·~/work/video-cuts ·on carver-mbp last seen 12m ago↵ send · ⇧↵ newline
the same block, collected
laptop-carver ⇪ ⏹ ✕
❯
when you are back: pull the new cuts and re-render scene 4 at 60fps, then tell me the render time and whether the audio drifted on the long take delivered
working
❯message this agent
claude·~/work/video-cuts ·on carver-mbp last seen 1s ago↵ send · ⇧↵ newline

A receipt landing must not move the log

pending → delivered happens live, under a log pinned to the bottom. Both receipts are one element at one line height, so the swap changes the words and the colour and never the block's height. Measured in the running app: 727px into a 1351px log, the scroll position is identical before and after. Give the two receipts different heights and the log shifts by 2px — which is how that check was proved to work.

The meaning does not change

Both states still come only from the highest sequence number a poll actually returned: the agent either has this message or has not collected it yet. Nothing claims the agent read it, and moving the mark below the text does not make it claim more. delivered is the word for what the field records.