Skip to content

feat(tui): move the activity line while the agent works, and say for how long - #45

Merged
benjipeng merged 3 commits into
mainfrom
feat/activity-line
Sep 23, 2026
Merged

benjipeng merged 3 commits into
mainfrom
feat/activity-line

Conversation

@benjipeng

@benjipeng benjipeng commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

What

Stage 34, slice 4: the activity line moves while the agent works, and says for how long.

The line opened with a static dot, so a thirty-second silent turn read as a hang. It now opens with the mark on the workspace's motion clock: blue for the agent's own work, the server-tool colour while a hosted search runs, standing still in the action-required colour while approval waits. After the label it reads, muted, how long the current work has run, the effort, and after five silent seconds how long it has been quiet; a short row drops effort, then quiet, then elapsed. The user chose the mark in their own terminal over Unicode cycles that shook.

The readings are presentation: events are dated as the workspace applies them, and the motion clock supplies the instant each frame is drawn for, so renderers never read the system clock and tests pass instants explicitly.

After the user's first look in kitty, the line takes its row and a blank one beneath while there is work or a request waiting, and no rows otherwise, so an idle reply sits one blank row from the composer. The rows open and close only with the conversation's own facts: a selection note that opened them lifted the conversation two rows under the reader's drag, which the selection tests caught. While the rows are closed, the selection note rides the status row beside the copy receipt.

Review found the count followed whether the label named any work, so the gap between steps restarted it and an approval ran it unseen into the next tool's reading; and any session event, a child's included, reset quiet. Elapsed now counts the primary's turn, carrying through the gaps between steps and stopping while an approval or a question waits on the user, which the user chose over a count per step and over one that runs through their waits. Quiet hears only the primary's own events. COM-5, SEL-2, SEL-5 and the contract say so.

MOT-2 is now proven by the mark. The plan's last slice (documents, plan deletion, phase row) follows this merge.

Verified

First head: clippy, workspace tests 1624 passed, all 8 TUI smokes locally; CI green. The user reviewed the working and answered states in kitty against an offline scripted provider.

Review fix (2c3cb44), local: fmt, clippy on core and TUI, their tests (547 TUI, 8 core), citations, file length, frames, typos, and the TUI, input-queue and server-tool smokes. Each new test was seen failing with its bug restored. No frame changed. CI not yet observed on this head.

…how long

The activity line opened with a static dot, so a thirty-second silent turn read as a hang. It now
opens with the mark, the Nerd Font's circle, rounded square and square, outline then filled, on the
workspace's motion clock: blue for the agent's own work, the server-tool colour while a hosted
search runs, standing still in the action-required colour while approval waits. After the label it
reads, muted, how long the current work has run, the effort, and after five silent seconds how long
it has been quiet; a short row drops effort, then quiet, then elapsed.

The readings are presentation. Events are dated as the workspace applies them, and the motion
clock supplies the instant each frame is drawn for, so renderers never read the system clock and
tests pass instants explicitly. The user chose the mark in their own terminal over Unicode cycles
that shook. The activity line leaves chrome for its own module, and the workspace's producer
methods leave for theirs, which keeps both files under the line sentinel.
… back when idle

The user's first look in kitty found the row pressed against the composer's rule while working
and a hole under the last reply once done: the row held its place blank while idle. The activity
line now takes its row and a blank one beneath while there is work or a request waiting, and no
rows otherwise, so an idle reply sits one blank row from the composer.

The rows open and close only with the conversation's own facts. A selection note that opened them
lifted the whole bottom-anchored conversation two rows under the reader's drag, which the
selection tests caught; while the rows are closed, the selection note rides the status row's right
end beside the copy receipt instead.
… only the primary for quiet

Review of the activity line found the count followed whether the label named any work: the gap
between steps, while queued tools wait to start, restarted it, and an approval kept it running
unseen, so the next tool read the user's decision time as its own run. The count now belongs to
the primary's turn: it opens and ends with the turn, carries through the gaps between steps, and
stops while an approval or a question holds the turn on the user, resuming where it stopped. The
user chose this over a count per step, which never shows the turn's total, and over one that runs
through the user's waits.

Quiet was restarted by any event in the session, so a child streaming during Thinking kept the
primary's line from ever saying it had been quiet. It now hears only the primary's own events,
and counts from the answer after a wait on the user.

The idle assertion read a row that stopped being the activity line once the idle rows closed, so
it looked at the whole conversation instead. COM-5, SEL-2, SEL-5 and the renderer's comments
described the row before its rows could close; they are rewritten, and a doc comment the first
commit detached from its function is back on it.
@benjipeng
benjipeng merged commit 3a9b610 into main Sep 23, 2026
3 checks passed
@benjipeng
benjipeng deleted the feat/activity-line branch September 23, 2026 15:12
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.

1 participant