Skip to content

Sonny: a lead shows its tasks' margin notes, and the footer counts agents at work - #367

Merged
lydakis merged 77 commits into
mainfrom
claude/project-thread-om42p0
Oct 29, 2026
Merged

lydakis merged 77 commits into
mainfrom
claude/project-thread-om42p0

Conversation

@lydakis

@lydakis lydakis commented Oct 29, 2026 •

Copy link
Copy Markdown
Owner

Requested by George · project thread

Follow-up to the margin (#308), from George's asks in the thread: lookout raising tasks' notes to the lead, a small counter near the composer for the agents at work, and a margin that is there only while it holds something.

A lead's margin showing both tasks' tables, the conversation's markers titled as the tasks titled them, and ● 2 under the composer

What changes

  • Lookout tells a lead about its tasks' notes. When a task posts or removes a note in its own margin, the lead's task updates say so:
    • - calc.quick: turn:calc.quick/1, put the note "results" in its own margin; the margin tool with from "calc.quick/results" shows it in yours.
    • Only the note's id is given, never its title or text, because lookout's note reaches the approver as the person's words.
    • The note lines count toward the update's size limit (Sonny: the lookout forwards everything and judges nothing #310), and wait for the next note when they don't fit.
  • The margin tool takes from: "task/id". It shows that task's note in the lead's margin, so the person sees it.
    • Sonny reads the task's history every 3 seconds while the task exists. The first read pages back until it finds where the note starts, and calls are read in the order each node holds them.
    • Only calls the task's own margin would take are read.
    • A file note is read from the task's folder the way margin files are (regular files only, bounded) and kept as text.
    • Once the task is removed, the last thing read stays.
    • When the lead gives no title of its own, the note follows the task's title.
  • The margin opens with its first note and goes once it holds none. A margin the person closed with Esc stays closed as notes come; they show inline as before. /margin still opens an empty one.
  • A counter under the composer.
    • A cyan ● with a number counts the agents at work, and a yellow ● counts what needs you. These are the roster's colors.
    • It shows only when there is something to count, whether the margin is open or not.
    • A click opens /status.
    • Without a multiplexer, it counts the tasks this lead started, as their rosters read them.
    • The margin's glance line no longer repeats these counts.
  • A note taken away leaves the conversation too. This applies to a ×'d note and to one the agent removes: its marker or inline copy goes, which matches what a redraw already showed.
  • A note's marker says the note's current title.

After a click on the counter, /status lists the two working tasks

Both tasks done and then deleted: the counter is gone and their notes stay in the margin

Both notes taken away with ×: the margin goes and the conversation has the window back

Testing

  • cargo test --workspace passes (sonny: 435). cargo clippy --workspace --all-targets -D warnings and cargo fmt --check are clean.
  • New tests cover:
    • a task's notes as lookout news, by id, with failed calls and grandchildren left out;
    • from read as the task changes the note, a file note kept as text, and the note kept once the task is gone;
    • a note found far back in a task's history, two calls in one response read in order, a call the margin turns down skipped, and the title followed until the lead gives its own;
    • the margin opening with a note, going once emptied, and staying closed once the person closed it;
    • the counter's text, colors and click;
    • a marker following its note's title;
    • a removed note leaving the conversation whether or not the margin is shown.
  • Driven in real Kitty on Xvfb with a real daemon and a scripted lead, two tasks and a judge (the screenshots above). No margin showed before the first note. The notes showed while the tasks worked, the counter opened /status, and the notes stayed after agent rm removed both tasks. With both notes ×'d, the margin went.

🤖 Generated with Claude Code

https://claude.ai/code/session_013jkdGEPcebFosL2vrxNNYx

claude added 30 commits October 28, 2026 23:30
/fullscreen and the settings' fullscreen key go, with the inline
viewport, the /status and /background screens of their own, and the
side chat that took over the terminal: /status, /background and /side
always open in the pane beside the conversation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGFoe3qjfmPo7oQpb2d
…on shows no failure

A message attached to the bot's next call was a yellow notice that read
as something to act on: it is now a dim 📎 in the footer (with a count
past one) until a call takes it in. A turn that ends because the model's
last round came back empty ends as one that completed: no red line, no
error, no failure chime.

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

WIP: two reaction tests still read the old placement.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGFoe3qjfmPo7oQpb2d
Rows of the conversation can now carry a tag (where a message ends, the
reactions under it) and a link, and be changed in place. The person's
reaction to any reply goes on a row right under that reply, joining the
emoji already there, and taking one back takes it off that row; the
bot's reactions go under the person's message as it makes them, not
once the turn ends. A message no longer in the conversation keeps the
old fallback: a row of its own that says which message.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGFoe3qjfmPo7oQpb2d
Tasks started one after another (or messaged, removed, scheduled...)
with nothing drawn between now read as one row, "Started a, b and c ▸",
and a click opens it to show each call and folds it again. A row can
carry a button, a sonny: link that is never underlined or handed to the
terminal: the fold's row, and each option of a question the agent asks,
which a click answers with.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGFoe3qjfmPo7oQpb2d
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGFoe3qjfmPo7oQpb2d
A message another bot sent, or the lead's task updates, lands as one dim
row: who sent it and its first words, or the news it brings. A click opens
the whole message under it and shuts it again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGFoe3qjfmPo7oQpb2d
…of Shift+Tab

The lead's start_task calls draw as a roster of the tasks started together,
each with what it is doing now, read every few seconds; a click on a task
opens its own Sonny in the pane, to watch it and talk to it, as a side chat
is. SONNY_TASKS=cards draws each as a box instead, for comparing the two.

Shift+Tab switches tabs in multiplexers, so Ctrl+] moves the keys between
the conversation and the pane.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGFoe3qjfmPo7oQpb2d
… pane's width; docs and screenshots

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGFoe3qjfmPo7oQpb2d
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGFoe3qjfmPo7oQpb2d
George picked the roster over the cards prototype.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGFoe3qjfmPo7oQpb2d
…b alone; quiet messages keep no payload

- A task opened in the pane runs with --embedded: it announces nothing to
  Herdr or cmux, which hold the lead's tab, and takes no --model from the
  lead's window; only a side chat does.
- Ended tasks are read again every 30 seconds, so one given more work
  shows it; a task the daemon could not read keeps its state, and only
  bot_not_found makes it removed.
- A quiet message keeps only its shut row's words; opening it reads it
  again from the history. A task keeps its brief's first line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGFoe3qjfmPo7oQpb2d
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGFoe3qjfmPo7oQpb2d
…opening it at the ends; Ctrl+\ moves the keys

Esc stays the way to close the pane. Ctrl+] opens again the pane
closed last, with its /status or /background.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGFoe3qjfmPo7oQpb2d
…s let go of calls the conversation let go; history buttons stay on their rows under the welcome

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGFoe3qjfmPo7oQpb2d
A note's body moved right for the margin kept its rows' marks only in
the first span, which the indent hid: wrapped text copied with breaks
and the indent, and an address cut over rows lost its CUT. The new
transcript::indent puts the mark first and widens its lead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEPcebFosL2vrxNNYx
Following a file link took the margin out of the pane before opening the
file, so the file had no ← back and Esc made a new margin. The margin is
put back first, and open_pane lays the file over it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEPcebFosL2vrxNNYx
…n at most 600 rows

Codex review on #308:
- × takes a note away only once the close message is submitted, so a
  refused or lost submit leaves the note to close again.
- Each note is cut at 600 rows with a count of the rest, so 20 long
  notes stay under what the pane's screen keeps and none is dropped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEPcebFosL2vrxNNYx
A note's Markdown, and a Markdown file a note shows, now go through
transcript::markdown with the margin's five-column lead, as replies,
the pane and cards do; its relead keeps the wrap marks, so the margin's
own indent helper goes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEPcebFosL2vrxNNYx
…ersation let go are no longer kept or read

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGFoe3qjfmPo7oQpb2d
…ote can draw

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEPcebFosL2vrxNNYx
Task names, who sent a message and the lead in the footer are blue; a
call that worked and the git branch are green. Only the terminal's 16
colors, so themes set the shades.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGFoe3qjfmPo7oQpb2d
… red; a shut agent message never slices its cut arrow

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGFoe3qjfmPo7oQpb2d
… and tells a lead its tasks' notes don't reach the person

On GPT-6.1 Sol the earlier text got no margin calls in 18 sessions:
diagrams and tables went inline. Saying when to post (a part the person
will look at more than once) got a note in 9 of 10 runs that called for
one and none for a short answer. Added from what that round still
missed: update or remove a note in the turn its subject changes, no file
notes into a task's copy, steps go in the plan, and on a lead, carry a
task's result into its own margin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEPcebFosL2vrxNNYx
Older pages drawn above carry their tags and buttons, so reactions,
folds, rosters and relayed messages work on them too.

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

A bot a lead makes takes the lead's declared tools as they stand, so every
task heard the lead-only sentence about its margin. The sentence now sits
in lead.md, and the margin tool has one description for every bot. It also
asks for a note to be reposted while a change waits on a task's branch, and
for a walkthrough to keep in the note only what the walkthrough does not hold.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEPcebFosL2vrxNNYx
A group of calls or tasks drawn again while an older page is written
is found among that page's rows, not flushed under the newer ones.

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

@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: 78f030612a

ℹ️ 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/margin.rs Resolved
Comment thread sonny/src/margin.rs Resolved
Comment thread sonny/src/main.rs Resolved
Comment thread sonny/src/margin.rs Resolved

@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: 20b5885975

ℹ️ 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
Comment thread sonny/src/main.rs Resolved
Comment thread sonny/src/main.rs Resolved
… pictures from the task's folder

A title-only update to a task's note retitles the lead's copy, and the
read back stops only at a post that sets both. A read cut short leaves
where it was read from. What a task's note shows is drawn with the
task's folder, so its relative pictures are the task's. Lookout reads a
long margin call whole when its started event cut the arguments before
the note's id.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013jkdGEPcebFosL2vrxNNYx
…note stays with the bot first read

Without a multiplexer, the tasks at work are the lead's tasks with a
turn running, as the daemon lists them, whether or not their rosters
are still drawn; what needs the person still comes from the rosters.
A note shown from a task is read from that bot only: another given its
name later leaves what was read as it was.

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

@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: 51bee947a4

ℹ️ 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
Comment thread sonny/src/margin.rs Resolved
…tied margin under a pane is let go

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

@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: 3824801bbb

ℹ️ 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
Comment thread sonny/src/main.rs Resolved
… of running bots is counted

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

@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: c089b9679a

ℹ️ 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/lookout/updates.rs Resolved
Comment thread sonny/src/main.rs Resolved
Comment thread sonny/src/margin.rs Resolved
…is news, and one taken away stops reading through

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

@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: 6150ab9b7c

ℹ️ 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/margin.rs Resolved
Comment thread sonny/src/margin.rs Resolved

@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: 7905d1cc96

ℹ️ 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

@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: d8dab30787

ℹ️ 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
…margin's notes are known

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

@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: fd0c477129

ℹ️ 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/margin.rs Resolved
Comment thread sonny/src/margin.rs Resolved
Comment thread sonny/src/margin.rs Resolved
…ad, and few gone notes are kept

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

@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: d3f2596ecb

ℹ️ 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/margin.rs Resolved
Comment thread sonny/src/main.rs Resolved
…ide chats are no tasks at work

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

@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: af320c0158

ℹ️ 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/margin.rs Resolved
@lydakis
lydakis merged commit 18ba40b into main Oct 29, 2026
4 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