Conversation
The workspace put a real agent in the content pane, which is the point of it — but a real agent takes the keyboard. Click into claude and every sidebar key stops working, and with tmux's status line off there is nothing on screen that says how to get back out. You are looking at one agent with no visible way to leave it. A status line would have been the small fix: one row of text that never goes away. But a row you can only read answers "how do I get out" and nothing else — you still cannot start a second agent without leaving the first. So the row takes input. It is the same surface as the CLI, which makes the escape hatch and the command line one thing rather than two. mosh ▸ ps · start claude · show <n> · kill <n> · detach · help F12 reaches it from anywhere, including from inside an agent that has taken the keyboard: the binding lives in tmux's root table, so it is claimed before the pane's application ever sees it. It switches the client first, so it is also a way out of a member you attached to directly. Esc goes back to the session; Enter on an empty line does too. Output grows the bar over the content while you read it, then it collapses back to one row. `attach` in the bar means `show`. The real attach would be a tmux client inside the client already drawing the pane, which tmux refuses, and in a workspace the word means "put it in the content pane" anyway. Two things this turned up, both caught by probing a live tmux rather than by reasoning about it: - `join-pane -b -t <bar>` splits the BAR's cell, and the bar is one row: "create pane failed: pane too small". Dropping `select-layout main-vertical` for a plain split of the sidebar fixes it and is better anyway — main-vertical owns every pane in the window, so it dragged the footer into the right-hand column and gave it an equal share. Splitting the sidebar touches only the region above the footer, so the bar spans the full width and needs no correction after a swap. - `bind-key -n F12 cmd1 ";" cmd2` as separate argv elements binds cmd1 and runs cmd2 once, immediately. That produced a key which switched sessions and did nothing else. The chain has to arrive as one string. `contentPane()` excluded only itself, which was fine with two panes and wrong with three — a swap would have parked the bar. It now excludes by title, like everything else here. Also: clicking the member already on screen, or pressing Enter, hands it the keyboard — without that the workspace can only be watched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
| // command itself, so tmux binds the first command and runs the second once, | ||
| // now. That silently produced a key that switched sessions and did nothing | ||
| // else — the binding has to arrive as a single command sequence. | ||
| tmux(["bind-key", "-n", BAR_KEY, `switch-client -t ${WORKSPACE} ; select-pane -t ${paneId}`], { runner }); |
ThreatCrush Security Scan94 finding(s) HIGH/CRITICAL: 2 | MEDIUM: 44 | LOW: 48
…and 44 more. Full results in the Security tab. Snippets are redacted; ThreatCrush never prints matched credential material. |
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Run
/herd start claude --agent, get into it, and you are looking at one agent with no visible way to leave. This adds the row that fixes it — and because it takes input, it is also how you start the second agent without leaving the first.Why a prompt and not a status line
A status line was the small version: one row of text that never goes away, so the way out is always on screen. But a row you can only read answers "how do I get out" and nothing else — you still have to leave to start anything. Making the row take input means the escape hatch and the command line are the same thing, and it is the surface that already exists: every
moshcode herdverb works in it.F12 reaches it from anywhere, including from inside an agent that has taken the keyboard — the binding lives in tmux's root table, so it is claimed before the pane's application ever sees it. It switches the client first, so it is also a way out of a member you attached to directly, not only of the workspace. Esc goes back to the session. Output grows the bar over the content while you read it, then collapses to one row.
attachin the bar meansshow: the real attach would be a tmux client inside the client already drawing the pane, which tmux refuses, and in a workspace the word means "put it in the content pane" anyway.Clicking the member already on screen — or pressing Enter — now hands it the keyboard. Without that the workspace could only be watched.
Two bugs the probe caught
Both from driving a live tmux instead of reasoning about it:
join-pane -b -t <bar>fails: "create pane failed: pane too small."-bsplits the bar's cell, and the bar is one row. The fix dropsselect-layout main-verticalfor a plain split of the sidebar — which is better regardless, because main-vertical owns every pane in the window, so it dragged the footer into the right-hand column and handed it an equal share. Splitting the sidebar touches only the region above the footer.bind-key -n F12 cmd1 ";" cmd2as separate argv elements bindscmd1and runscmd2once, right then. That silently produced a key that switched sessions and did nothing else:Also fixed:
contentPane()excluded only itself, which was fine with two panes and wrong with three — a swap would have parked the bar into a session named after it. It now excludes by title, like everything else here.Verification
Geometry holds across four swaps, footer full width and exactly one row:
Live end-to-end against the real
herd barprocess:1513 tests pass, 0 fail. 15 new for the bar (line editor, command resolution, one-row prompt at narrow widths, role classification) plus the integration test now asserts the footer survives every swap at height 1 and full width, that Enter reaches the session, and that the F12 binding carries both commands — the exact thing that was silently broken.
🤖 Generated with Claude Code