Skip to content

Sonny: a click on an agent's name goes to its tab, a right click opens it beside - #533

Merged
lydakis merged 34 commits into
mainfrom
claude/project-thread-qj5sfg
Nov 1, 2026
Merged

lydakis merged 34 commits into
mainfrom
claude/project-thread-qj5sfg

Conversation

@lydakis

@lydakis lydakis commented Oct 31, 2026

Copy link
Copy Markdown
Owner

What

Going to an agent's own tab is the common move when agents are laid out in a multiplexer; the side pane is the quick look. So:

  • Click an agent's name (in the chat, /status, or the side pane's title) goes to the agent's tab when it is laid out in Rex, Herdr or cmux. When it isn't laid out, the click opens it in the side pane as before.
  • Right click a name opens it in the side pane, beside the chat.
  • [sonny] agent_opens = "beside" swaps the two, for people who want the pane on a plain click. Default tab. It's a /config row too.
  • Ctrl+T in the side pane goes to the shown agent's tab; the pane's key hints say so for a laid out agent.
  • The pane's title keeps the agent's name whole on narrow panes: the key hints drop from the end first, as the footer's least urgent ones do.
  • A laid out agent's name in the pane title is blue (a name, never underlined, as Sonny: an agent's name in the conversation opens that agent #435 set), with the ↗ main-view button beside it.

Focus goes through a new Backend::focus: rex focus, herdr tab focus, cmux surface.focus.

The pane's title, laid out and not

Audit follow-up (multiplexer audit, "go to its tab").

Checks

cargo clippy -p sonny -p agent-client --all-targets -D warnings and cargo test -p sonny -p agent-client pass locally. New tests: a_laid_out_agents_name_goes_to_its_tab (title widths at 72, 48 and 32 columns), right click asserts in an_agents_name_opens_it_in_its_color…, and the agent_opens parse test.


Generated by Claude Code

claude added 30 commits October 31, 2026 04:27
…ft is small

Every Rex, Herdr and cmux call Sonny makes waited on its CLI with no
limit, from the lead's screen loop: a host that stopped answering froze
Sonny. They now go through mux::output, which stops the CLI after 10 s.

Herdr's ratio is the first pane's share and a swap keeps the shares in
place, so a small split above or to the left came out at 65%. It now
asks for 0.35 when it swaps.

Usage text and comments name cmux beside Rex and Herdr.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
…e screen

A lead's tasks were laid out by blocking multiplexer CLI calls made inside
the screen loop: about seven per task start, two or three per state change,
and /status re-read places every two seconds. Each Rex call measures about
27 ms, so typing stalled for ~200 ms whenever a task started.

mux::Worker owns the Layout on a thread of its own. Jobs run in order; a
window naming that a later one follows is skipped; places are read in the
background and /status reads the kept copy. What a job has to say comes
back to the screen loop on a channel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
# Conflicts:
#	sonny/FEATURES.md
#	sonny/src/mux.rs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
…then

The layout listed every block before each thing it did: a task start
listed three times, every state change of any task once more, and /status
re-read places every two seconds. Now the home's blocks and places are
kept, and read again only once the host's events say something changed,
or Sonny changed it itself. A host's events say that something changed,
not what: the home is read again whole, as Herdr's and cmux's event docs
ask of a client that keeps their state.

- Rex: `rex events -s SESSION --json`; terminal and focus events move no block.
- Herdr: `events.subscribe` on HERDR_SOCKET_PATH, which Herdr sets in its
  panes; its CLI has no stream. An error (events_lost) ends the watch.
- cmux: `cmux events` for workspace, pane and surface; its heartbeats
  end the command once Sonny is gone.

With no stream, or once it ends, the home is read once per batch of work.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
…ession_destroyed ends the stream

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
…ns off the worker

A read that fails is no longer cached as an empty home while the news
stream is up, and a host slow to take the subscription no longer holds
up the layout worker. Herdr's and cmux's feature rows record the change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
… worked

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
When the project's lead ran out of Rex, Herdr and cmux, an agent's
run_in_pane or show_agent opened a Rex session (or else a Herdr or cmux
workspace) that no one watched, and agents got the Rex skill. Now a call
goes only where the lead laid the project out, where its lead is, or where
the project it was asked from is; otherwise it says nothing opened would be
seen. Out of every multiplexer, agents get no layout skill.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
Another project's Sonny still in its multiplexer keeps the skill it
installed; this one only installs none.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGFK4LP1UZB6mt7eV3i
run_in_pane and show_agent take split "float": for something the person
deals with once and closes (a sign-in, a quick look). Rex floats a block
only in its own window, so it is split beside its anchor, then floated
with session.float_block over the middle of the window, taking neither
focus nor the active window. Where a multiplexer cannot float (Herdr's
popup is plugin-only and modal, cmux's canvas is a whole-workspace mode),
it is split on the right. Only Rex's skill mentions it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
…T does

Where the lead's tasks are laid out in Rex, Herdr or cmux, clicking a
task's name in the side pane's title, or Ctrl+T, brings its own tab into
view there: Rex makes its window the session's active one, Herdr focuses
its tab, cmux its surface. The ↗ beside the name still opens it in the
main view. Out of a multiplexer the name is only a name and the hint
leaves Ctrl+T out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
…de; agent_opens swaps them

An agent laid out in Rex, Herdr or cmux is worked with in its own tab, so
a click on its name, its roster row or its /status row goes there; a
right click opens the look beside the conversation. [sonny] agent_opens
= "beside" swaps the two. An agent with no tab opens beside either way.
The pane's title draws a laid out agent's name in the agents' blue, as
any agent's name that opens it is drawn.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-01T01:09:08.946930Z ff499dd New commits
🔒 Security Review ⚠️ Failed 2026-10-31T16:58:38.978555Z
We couldn’t complete this review. Comment @codex security review to try again.
0a1ef5b New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

The account paying for this security review has reached its Codex usage limits. The payer can check the Codex usage dashboard. For personal accounts, using credits requires enabling “Use credits for security reviews” in Code review settings. If you do not manage the paying account, contact this repository's admins.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2a86234f7a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sonny/src/main.rs Resolved
…ut found off the screen

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
@chatgpt-codex-connector

Copy link
Copy Markdown

The account paying for this security review has reached its Codex usage limits. The payer can check the Codex usage dashboard. For personal accounts, using credits requires enabling “Use credits for security reviews” in Code review settings. If you do not manage the paying account, contact this repository's admins.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 66e011a65e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread sonny/src/main.rs Resolved
… not in its last read

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT
… test's script can take

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEWm1MS4yiwexivszT

lydakis commented Nov 1, 2026

Copy link
Copy Markdown
Owner Author

The macos check failed on 413b2ae, in exec::tests::each_call_that_asks_first_waits_for_the_gate_with_the_script_s_time_stopped, and the cause isn't this PR's change. The test's second, ungated run (exec.rs:1942) ended with "Script terminated: it ran out of time before it started". That script has a 300 ms budget, and the wait for one of the tool host's four script slots (RUNNING, a process-wide semaphore that every exec test running in parallel shares) counts against it. This PR doesn't touch exec.

I couldn't re-run the job: the integration gets a 403. ff499dd makes the test robust instead. The ungated run checks only that every call runs, so it now gets a 30 s budget. The gated run keeps its 300 ms, because that run is what proves the gate's wait doesn't count. In principle it shares the same slot exposure.


Generated by Claude Code

@lydakis
lydakis merged commit e1c7602 into main Nov 1, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants