Skip to content

web: fold the activity group and the settled approval card to one line - #173

Merged
adityak74 merged 3 commits into
mainfrom
feat/web-collapse-activity-and-approval
Sep 5, 2026
Merged

web: fold the activity group and the settled approval card to one line#173
adityak74 merged 3 commits into
mainfrom
feat/web-collapse-activity-and-approval

Conversation

@adityak74

Copy link
Copy Markdown
Contributor

What

Browser only, no Rust. Two collapses in the transcript, both native details with no toggle code of their own.

Activity group. Consecutive tool, verify and notice lines now sit under one details.activity. Its summary reads "Working on it · " while the turn is still adding to the group, and "N steps" or "N steps, M failed" once it is closed. The lines themselves are built exactly as before by activity-line.ts and are one click away. The phrase is read off the latest line's .activity-brief or .activity-name and written back through textContent after clampPhrase, imported from activity-line.ts rather than written twice. Appending never toggles the group, so a reader who opened it keeps it open. Group state is computed from the lines' activity-ok / activity-fail / activity-running classes with classList.contains and put on the details, which colours the marker; a line with none of the three counts as ok, so nothing depends on those classes existing.

Every place that used to write activityGroup = null now goes through one closeActivityGroup(), and the done event and the replay in openSession call it too, so the summary is finalised in exactly one place. Nothing in appendActivity scrolls; applyEvent still decides that once, after the event, from where the reader was, and a collapsed group does not change height on append, so it cannot steal scroll position.

Approval card. details.card.card-approval with the head as its summary. Open while pending, and a click on the head is refused with preventDefault while the buttons are live, so a person cannot fold away what they are deciding on. settle sets open = false, so the settled card is its head line only: the outcome title, code.tool-name and the outcome tag, with the arguments and the note one click under it. prettyArguments output still goes through textContent only.

Modules. The two pieces of DOM building move out of main.ts into web/src/activity-group.ts and web/src/approval-card.ts, in the shape of activity-line.ts and approval-mode.ts (take a Document, return the element plus small update functions), so they can be tested without a page. tsconfig.json gains allowImportingTsExtensions so activity-group.ts can import ./activity-line.ts with the extension that node --test needs; esbuild resolves it the same way.

Docs. docs/DECISIONS.md entry dated 2026-09-05, and one sentence each in the web/ bullet of CLAUDE.md and AGENTS.md, identical.

Tests

web/test/activity-group.test.ts (8) and web/test/approval-card.test.ts (6): an injection string in a phrase and in a tool name or arguments renders as text; a fresh group reads "Working on it" and follows the latest phrase, clamped; the lines are kept as built; appending never toggles; closing gives "1 step", "3 steps", "3 steps, 2 failed"; the group takes running over failed over ok; a waiting card is open and refuses a head click; a settled card is closed with the tool name in its summary and the arguments and note still underneath; every outcome has its title and note.

From web/: npm run check, npm test (373 pass, 0 fail) and npm run build all pass.

Not changed

What is stored or sent. activityLine, verifyLine, noticeLine and activity-line.ts are untouched.

https://claude.ai/code/session_01PG2vuux5tMsjnZBLWJzMyp

A long run's transcript is the answers, not the plumbing. Consecutive
tool lines now sit under one native details whose summary reads
"Working on it" and the latest line's phrase while the turn is adding
to it, and the count, "3 steps" or "3 steps, 1 failed", once it is
closed. The lines themselves are built exactly as before and are one
click away. Every place that used to null the group now goes through
closeActivityGroup, so the summary is finalised in one place, and a
replayed group is closed as soon as it is drawn.

The approval card is a details too: open and refusing a click on its
head while it waits, folded to its head with the outcome and the tool
name once settled, with the arguments and the note under it.

Both pieces of DOM building move out of main.ts into activity-group.ts
and approval-card.ts so they can be tested without a page. The phrase on
the summary is read off the line and written through textContent after
the same clamp the line used. Nothing about what is stored or sent
changed.

Claude-Session: https://claude.ai/code/session_01PG2vuux5tMsjnZBLWJzMyp
…it reports

The browser's tool line no longer writes its status word beside the phrase. The result is the bullet's colour, from exactly one of activity-ok, activity-fail or activity-running on the line, with the word kept in the line's title and, for a shell call, under the verbatim command in the details. stateForStatus in web/src/activity-line.ts is the one mapping: exit 0 and passed are ok, the tools' failure vocabulary is fail, and the other tools' own success summaries stay ok, the same split the agent loop uses for succeeded. The verify line keeps its word and takes the same classes.

Renderer::tool_starting is a new trait method with an empty default, called from Agent::run_tool after approval and before dispatch, so a denied call never draws as running. WebRenderer sends it as a tool_started frame with the name and phrase the tool frame will carry; the browser appends a running line on the first and settles it in place on the second. A replayed session has every result, so no replayed line is in progress, and a turn that ends with a line pending fails it with the reason in its title.

Claude-Session: https://claude.ai/code/session_01PG2vuux5tMsjnZBLWJzMyp
…y-and-approval

Resolves the overlap in web/src/main.ts: both imports, both pieces of
state, the tool line comment says colour and collapse, and every reset
site closes the group and drops the pending tool line. Both decision
entries are kept.

Claude-Session: https://claude.ai/code/session_01PG2vuux5tMsjnZBLWJzMyp
@adityak74
adityak74 merged commit 58a4397 into main Sep 5, 2026
7 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.

1 participant