Skip to content

Transcript: one live line that holds the latest step and keeps its clock - #29938

Merged
teamleaderleo merged 10 commits into
feat-cmux-nextfrom
lane/transcript-live-line-keeps-going
Nov 1, 2026
Merged

teamleaderleo merged 10 commits into
feat-cmux-nextfrom
lane/transcript-live-line-keeps-going

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Nov 1, 2026 •

Copy link
Copy Markdown
Collaborator

Leo, 2026-11-01, on a screenshot of "Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' …" with "Thinking 15s · ↓ 284 out ↑ 342.6K in" on its own line under it:

this should be replacing the thinking area and its shimmer across things

like the thinking or whatever it should just keep going

and shouldn't flicker

What changed

A running turn now has one live line at the bottom, and that line is the current activity:

moment before after
before any output Thinking 15s Thinking 15s
a call runs Running grep … 0s (the clock started again at the call) Running grep … 15s · tokens
the call is done row "Ran grep …", then "Thinking 18s · tokens" under it Ran grep … 18s · tokens (one line, shimmering)
the agent thinks after it as above Ran grep … 21s · tokens
the next call runs Running sed … 0s Running sed … 24s · tokens, and "Ran grep" moves into the run above
  • conversation/turns.ts codexLiveTurn / liftedStep: between calls the line names the latest finished step instead of going back to "Thinking". That step leaves its run so it reads once. Failed, backgrounded, message, sub-session, render and edit calls keep their own rows and do not go on the line.
  • conversation/Thinking.tsx: one clock, the turn's time from the prompt, for every step, so the time no longer starts again at each call. The turn's tokens now show beside a call too. A finished step reads "Ran …" and offers no ⌃B.
  • The line keeps its one id (thinking-live) and the same element tree for every state. Only its text changes, so React never remounts it and the CSS shimmer never starts again.

Spec: leo-workspace design/chat-transcript.md, "The live line" (added alongside this PR).

Proof: per-frame trace

webviews/test/transcript-live-line-continuous-browser.test.ts (real Chromium, cmuxAfterPaint reads every painted frame). A turn steps through Thinking → grep running → grep done → a thought → sed running → sed done, 12 frames each. Across every frame it asserts:

  • one line element and one shimmer band element;
  • the band's animation time only moves forward (no restart);
  • words and a time on the line in every frame (no blank frame);
  • the turn's clock (never under the 15s already elapsed, never going back);
  • "Ran grep" and "Ran sed" between calls, never "Thinking".

The trace it prints is below.

Head (green), every painted frame:

72 frames
frame | step | line el | band el | band t (ms) | text | time
0 | thinking | #1 | #2 | 0.0 | Thinking | 15s
1 | thinking | #1 | #2 | 0.0 | Thinking | 15s
2 | thinking | #1 | #2 | 16.6 | Thinking | 15s
3 | thinking | #1 | #2 | 33.4 | Thinking | 15s
4 | thinking | #1 | #2 | 50.0 | Thinking | 15s
5 | thinking | #1 | #2 | 66.7 | Thinking | 15s
6 | thinking | #1 | #2 | 83.3 | Thinking | 15s
7 | thinking | #1 | #2 | 100.0 | Thinking | 15s
8 | thinking | #1 | #2 | 116.7 | Thinking | 15s
9 | thinking | #1 | #2 | 133.3 | Thinking | 15s
10 | thinking | #1 | #2 | 150.0 | Thinking | 15s
11 | thinking | #1 | #2 | 166.7 | Thinking | 15s
12 | grep running | #1 | #2 | 183.3 | Running grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
13 | grep running | #1 | #2 | 200.0 | Running grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
14 | grep running | #1 | #2 | 216.7 | Running grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
15 | grep running | #1 | #2 | 233.3 | Running grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
16 | grep running | #1 | #2 | 250.0 | Running grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
17 | grep running | #1 | #2 | 266.7 | Running grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
18 | grep running | #1 | #2 | 283.3 | Running grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
19 | grep running | #1 | #2 | 300.0 | Running grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
20 | grep running | #1 | #2 | 316.7 | Running grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
21 | grep running | #1 | #2 | 333.4 | Running grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
22 | grep running | #1 | #2 | 350.0 | Running grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
23 | grep running | #1 | #2 | 366.6 | Running grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
24 | grep done | #1 | #2 | 383.3 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
25 | grep done | #1 | #2 | 400.0 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
26 | grep done | #1 | #2 | 416.6 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
27 | grep done | #1 | #2 | 433.3 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
28 | grep done | #1 | #2 | 450.0 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
29 | grep done | #1 | #2 | 466.7 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
30 | grep done | #1 | #2 | 483.3 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
31 | grep done | #1 | #2 | 500.0 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
32 | grep done | #1 | #2 | 516.7 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
33 | grep done | #1 | #2 | 533.4 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
34 | grep done | #1 | #2 | 550.0 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
35 | grep done | #1 | #2 | 566.6 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
36 | thought | #1 | #2 | 583.3 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
37 | thought | #1 | #2 | 600.0 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
38 | thought | #1 | #2 | 616.6 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
39 | thought | #1 | #2 | 633.3 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
40 | thought | #1 | #2 | 650.0 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
41 | thought | #1 | #2 | 666.6 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
42 | thought | #1 | #2 | 683.3 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
43 | thought | #1 | #2 | 700.0 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
44 | thought | #1 | #2 | 716.6 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
45 | thought | #1 | #2 | 733.4 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
46 | thought | #1 | #2 | 750.0 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
47 | thought | #1 | #2 | 766.7 | Ran grep -n -E 'environ|GH_QUOTA_[A-Z_]+|low_water' ~/.local/bi… | 15s
48 | sed running | #1 | #2 | 783.3 | Running sed -n 1,40p ~/.local/bin/gh-quota | 15s
49 | sed running | #1 | #2 | 800.0 | Running sed -n 1,40p ~/.local/bin/gh-quota | 15s
50 | sed running | #1 | #2 | 816.7 | Running sed -n 1,40p ~/.local/bin/gh-quota | 15s
51 | sed running | #1 | #2 | 833.3 | Running sed -n 1,40p ~/.local/bin/gh-quota | 15s
52 | sed running | #1 | #2 | 850.0 | Running sed -n 1,40p ~/.local/bin/gh-quota | 15s
53 | sed running | #1 | #2 | 866.6 | Running sed -n 1,40p ~/.local/bin/gh-quota | 15s
54 | sed running | #1 | #2 | 883.3 | Running sed -n 1,40p ~/.local/bin/gh-quota | 15s
55 | sed running | #1 | #2 | 900.0 | Running sed -n 1,40p ~/.local/bin/gh-quota | 15s
56 | sed running | #1 | #2 | 916.6 | Running sed -n 1,40p ~/.local/bin/gh-quota | 15s
57 | sed running | #1 | #2 | 933.3 | Running sed -n 1,40p ~/.local/bin/gh-quota | 15s
58 | sed running | #1 | #2 | 950.0 | Running sed -n 1,40p ~/.local/bin/gh-quota | 15s
59 | sed running | #1 | #2 | 966.6 | Running sed -n 1,40p ~/.local/bin/gh-quota | 15s
60 | sed done | #1 | #2 | 983.3 | Ran sed -n 1,40p ~/.local/bin/gh-quota | 15s
61 | sed done | #1 | #2 | 1000.0 | Ran sed -n 1,40p ~/.local/bin/gh-quota | 16s
62 | sed done | #1 | #2 | 1016.6 | Ran sed -n 1,40p ~/.local/bin/gh-quota | 16s
63 | sed done | #1 | #2 | 1033.3 | Ran sed -n 1,40p ~/.local/bin/gh-quota | 16s
64 | sed done | #1 | #2 | 1049.9 | Ran sed -n 1,40p ~/.local/bin/gh-quota | 16s
65 | sed done | #1 | #2 | 1066.6 | Ran sed -n 1,40p ~/.local/bin/gh-quota | 16s
66 | sed done | #1 | #2 | 1083.3 | Ran sed -n 1,40p ~/.local/bin/gh-quota | 16s
67 | sed done | #1 | #2 | 1099.9 | Ran sed -n 1,40p ~/.local/bin/gh-quota | 16s
68 | sed done | #1 | #2 | 1116.6 | Ran sed -n 1,40p ~/.local/bin/gh-quota | 16s
69 | sed done | #1 | #2 | 1133.3 | Ran sed -n 1,40p ~/.local/bin/gh-quota | 16s
70 | sed done | #1 | #2 | 1150.0 | Ran sed -n 1,40p ~/.local/bin/gh-quota | 16s
71 | sed done | #1 | #2 | 1166.6 | Ran sed -n 1,40p ~/.local/bin/gh-quota | 16s

Base source (red), first and last frame of each step:

49 | sed running | #1 | #2 | 800.0 | Running sed -n 1,40p ~/.local/bin/gh-quota | 0s
59 | sed running | #1 | #2 | 966.6 | Running sed -n 1,40p ~/.local/bin/gh-quota | 0s
60 | sed done | #1 | #2 | 983.3 | Thinking | 15s
71 | sed done | #1 | #2 | 1166.6 | Thinking | 16s

Tests

Base fails and head passes:

  • the trace test, red on base (the clock reads "0s" at the call, the line reads "Thinking" after a call);
  • bun test test/transcript-codex-live-line.test.tsx test/transcript-running-live-line.test.tsx test/transcript-working-line.test.tsx: 46 pass on head. These tests encoded the 2026-10-20 spec ("Thinking -> Running -> Thinking", a clock per call) and now encode Leo's new one.

Observed / Not run

  • Observed: every unit test file that touches the live line or the Thinking component passes when run on its own (32 files). vp fmt and vp lint (with type checks) are clean on the changed files.
  • The browser trace runs through cmux-ci, because this VM skips browser lanes. Result: 1 pass at head (run 41264916394). With the source reverted to base it fails, 0 pass and 1 fail (run 41265476768): the clock reads 0s at each call and the line reads "Thinking" after a call.
  • Not run: a DEV build. That is the next step after this lands.

Follow-ups (from review)

  • The lifted run's version (10v+3) can equal the ended open fold's (5v'+3) if one snapshot ends the turn and doubles that run's version. It needs a run state of its own, and the minimap test's pinned versions have to move in the same PR.
  • Find counts a match on the call the line names but cannot reveal it until the next step. Range copy has the same gap.
  • When a run held only the lifted call, its row leaves and comes back at the next call.
  • The no-plan and merged-run fixes from review are in (joined, no lift with a todo list).

Changelog

  • Changed: A running turn shows one live line that names the latest step (Running/Ran …) with the turn's time and tokens, instead of a separate Thinking line.

risk:normal

Agent session: agent session

🤖 Generated with Claude Code

teamleaderleo and others added 2 commits November 1, 2026 01:36
…, no blank frame

A per-frame Chromium trace of a running turn (Thinking, a call running, done,
a thought, the next call, done): one line element and one shimmer band whose
animation never restarts, words and the turn's clock on every frame, and the
finished step named on the line between calls. Unit tests move to the new
line: Ran between calls, the turn's time and tokens beside a call.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-20208ae4fb1bb2a05468
…lock

Leo (2026-11-01), on "Ran grep …" over a separate "Thinking 15s · ↓ out ↑ in":
"this should be replacing the thinking area and its shimmer across things",
"like the thinking or whatever it should just keep going", "and shouldn't
flicker".

- turns.ts codexLiveTurn: between calls the one live line names the latest
  finished step ("Ran grep …", liftedStep) instead of going back to
  "Thinking"; that step leaves its run so it reads once. Failed,
  backgrounded, message, sub-session, render and edit calls keep their rows.
- Thinking.tsx: one clock for every step, the turn's from the prompt (it no
  longer starts again at each call), and the turn's tokens beside a call too.
  A done step reads "Ran …" and offers no ⌃B.
- The line stays one element with one shimmer band from send to end.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-20208ae4fb1bb2a05468
@github-actions

github-actions Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review ff392ce: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr29938 -f ref=lane/transcript-live-line-keeps-going -f platform=macos -f backend_mode=local

Gallery before/after for fbfd657: 16 states rendered, 0 images differ, 2730 more touched states not rendered. Images are in the run's artifact, not on this public PR; the independent review of this head reads them on its own, so the PR needs no hand-made screenshots of these states.

gh run download 41286287698 -R manaflow-ai/cmux -n gallery-advisory-29938-fbfd657bbde674271143c1e5ccf5c761a10b6927 (then read gallery-review.json)

States
State Theme Status Diff Picked by
agent-pane.chat-width/standard Apple System Colors Light unchanged 0% own App.tsx
agent-pane.chat-width/standard Apple System Colors unchanged 0% own App.tsx
agent-pane.chat-width/wide Apple System Colors Light unchanged 0% own App.tsx
agent-pane.chat-width/wide Apple System Colors unchanged 0% own App.tsx
agent-pane.chat-width/wide-blocks Apple System Colors Light unchanged 0% own App.tsx
agent-pane.chat-width/wide-blocks Apple System Colors unchanged 0% own App.tsx
agent-pane.composer-edge/short-edge Apple System Colors Light unchanged 0% own App.tsx
agent-pane.composer-edge/short-edge Apple System Colors unchanged 0% own App.tsx
agent-pane.composer-edge/wide-edge Apple System Colors Light unchanged 0% own App.tsx
agent-pane.composer-edge/wide-edge Apple System Colors unchanged 0% own App.tsx
agent-pane.composer-edge/no-edge Apple System Colors Light unchanged 0% own App.tsx
agent-pane.composer-edge/no-edge Apple System Colors unchanged 0% own App.tsx
agent-pane.composer-floats/scrolled-to-end Apple System Colors Light unchanged 0% own App.tsx
agent-pane.composer-floats/scrolled-to-end Apple System Colors unchanged 0% own App.tsx
agent-pane.composer-floats/composer-grown Apple System Colors Light unchanged 0% own App.tsx
agent-pane.composer-floats/composer-grown Apple System Colors unchanged 0% own App.tsx
agent-pane.continuation-spacing/shipped Apple System Colors Light unchanged 0% own App.tsx
agent-pane.continuation-spacing/shipped Apple System Colors unchanged 0% own App.tsx
agent-pane.continuation-spacing/two-thirds Apple System Colors Light unchanged 0% own App.tsx
agent-pane.continuation-spacing/two-thirds Apple System Colors unchanged 0% own App.tsx
agent-pane.continuation-spacing/half-tucked Apple System Colors Light unchanged 0% own App.tsx
agent-pane.continuation-spacing/half-tucked Apple System Colors unchanged 0% own App.tsx
agent-pane.continuation-spacing/before Apple System Colors Light unchanged 0% own App.tsx
agent-pane.continuation-spacing/before Apple System Colors unchanged 0% own App.tsx
agent-pane.copy-controls/output Apple System Colors Light unchanged 0% own App.tsx
agent-pane.copy-controls/output Apple System Colors unchanged 0% own App.tsx
agent-pane.docked-chat/new-chat Apple System Colors Light unchanged 0% own App.tsx
agent-pane.docked-chat/new-chat Apple System Colors unchanged 0% own App.tsx
agent-pane.docked-chat/after-turn Apple System Colors Light unchanged 0% own App.tsx
agent-pane.docked-chat/after-turn Apple System Colors unchanged 0% own App.tsx
agent-pane.docked-chat/working Apple System Colors Light unchanged 0% own App.tsx
agent-pane.docked-chat/working Apple System Colors unchanged 0% own App.tsx

Pick other states with a Gallery: entry.id, entry.id/variant line in the PR body.

Passes: CI passes on fbfd657bbd.

CI passes on fbfd657bbd (run 41286287711 attempt 1).

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

red: cmux-next checks (god files, concurrency, crash safety, l10n); NEW: red check: Daemon capabilities export is fresh (+4 more) is not red on the base f818cf7; do not merge until green; see lane-rules

Shipped in:

@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Nov 1, 2026
@cursor

cursor Bot commented Nov 1, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@cubic-dev-ai cubic-dev-ai 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.

4 issues found across 9 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="webviews/test/transcript-live-line-continuous-browser.test.ts">

<violation number="1" location="webviews/test/transcript-live-line-continuous-browser.test.ts:164">
P2: This assertion does not prove that a shimmer band exists; a missing `.cv-shimmer__band` produces the same `-1` ID on every frame and passes. Assert the first band ID is positive (and its animation time is nonnegative) before checking continuity.</violation>

<violation number="2" location="webviews/test/transcript-live-line-continuous-browser.test.ts:176">
P2: The clock assertions allow a frozen clock to pass because they require only a lower bound and monotonicity. Require the trace to advance by at least one displayed second so a missing ticker is caught.</violation>
</file>

<file name="webviews/src/agent-session/acpmux/conversation/turns.ts">

<violation number="1" location="webviews/src/agent-session/acpmux/conversation/turns.ts:998">
P2: A completed latest step disappears when a todo list is present: `liftedStep` removes it, but the plan branch discards the populated `line` and renders a new `activityLine`. Preserve the lifted line's label and completion state in this branch, so the live line still says the completed step.</violation>

<violation number="2" location="webviews/src/agent-session/acpmux/conversation/turns.ts:1049">
P2: Completed `delete` and `move` calls are lifted out of the run even though they are file-change rows that must remain visible. Extend this exclusion to `delete` and `move` so their own rows are retained like other edit calls.</violation>
</file>

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

expect(trace.length).toBeGreaterThan(60);
// One line element and one shimmer band from the first frame to the last: never remounted.
expect(new Set(trace.map((row) => row.line))).toEqual(new Set([trace[0]!.line]));
expect(new Set(trace.map((row) => row.band))).toEqual(new Set([trace[0]!.band]));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: This assertion does not prove that a shimmer band exists; a missing .cv-shimmer__band produces the same -1 ID on every frame and passes. Assert the first band ID is positive (and its animation time is nonnegative) before checking continuity.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/test/transcript-live-line-continuous-browser.test.ts, line 164:

<comment>This assertion does not prove that a shimmer band exists; a missing `.cv-shimmer__band` produces the same `-1` ID on every frame and passes. Assert the first band ID is positive (and its animation time is nonnegative) before checking continuity.</comment>

<file context>
@@ -0,0 +1,188 @@
+    expect(trace.length).toBeGreaterThan(60);
+    // One line element and one shimmer band from the first frame to the last: never remounted.
+    expect(new Set(trace.map((row) => row.line))).toEqual(new Set([trace[0]!.line]));
+    expect(new Set(trace.map((row) => row.band))).toEqual(new Set([trace[0]!.band]));
+    expect(trace[0]!.line).toBeGreaterThan(0);
+    // The shimmer never starts again: its animation's time only moves forward.
</file context>
Suggested change
expect(new Set(trace.map((row) => row.band))).toEqual(new Set([trace[0]!.band]));
expect(trace[0]!.band).toBeGreaterThan(0);
expect(new Set(trace.map((row) => row.band))).toEqual(new Set([trace[0]!.band]));

}
// The turn's clock, never the call's: it never reads under the 15 s the turn has run, nor goes back.
const seconds = trace.map((row) => Number.parseInt(row.time, 10));
expect(Math.min(...seconds)).toBeGreaterThanOrEqual(15);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: The clock assertions allow a frozen clock to pass because they require only a lower bound and monotonicity. Require the trace to advance by at least one displayed second so a missing ticker is caught.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/test/transcript-live-line-continuous-browser.test.ts, line 176:

<comment>The clock assertions allow a frozen clock to pass because they require only a lower bound and monotonicity. Require the trace to advance by at least one displayed second so a missing ticker is caught.</comment>

<file context>
@@ -0,0 +1,188 @@
+    }
+    // The turn's clock, never the call's: it never reads under the 15 s the turn has run, nor goes back.
+    const seconds = trace.map((row) => Number.parseInt(row.time, 10));
+    expect(Math.min(...seconds)).toBeGreaterThanOrEqual(15);
+    for (let index = 1; index < seconds.length; index += 1)
+      expect(seconds[index]!).toBeGreaterThanOrEqual(seconds[index - 1]!);
</file context>
Suggested change
expect(Math.min(...seconds)).toBeGreaterThanOrEqual(15);
expect(Math.min(...seconds)).toBeGreaterThanOrEqual(15);
expect(Math.max(...seconds) - Math.min(...seconds)).toBeGreaterThanOrEqual(1);

isRunning(call) ||
call.background !== undefined ||
callFailed(call) ||
isEditTool(call) ||

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Completed delete and move calls are lifted out of the run even though they are file-change rows that must remain visible. Extend this exclusion to delete and move so their own rows are retained like other edit calls.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/src/agent-session/acpmux/conversation/turns.ts, line 1049:

<comment>Completed `delete` and `move` calls are lifted out of the run even though they are file-change rows that must remain visible. Extend this exclusion to `delete` and `move` so their own rows are retained like other edit calls.</comment>

<file context>
@@ -1008,6 +1023,49 @@ function codexLiveTurn(
+    isRunning(call) ||
+    call.background !== undefined ||
+    callFailed(call) ||
+    isEditTool(call) ||
+    renderCall(call) ||
+    subsessionCall(call) ||
</file context>
Suggested change
isEditTool(call) ||
(isEditTool(call) || call.kind === "delete" || call.kind === "move") ||

// just keep going"). The step leaves its run while the line names it, so it reads once.
const lifted = liftedStep(rows, last);
if (lifted) {
rows = lifted.rows;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: A completed latest step disappears when a todo list is present: liftedStep removes it, but the plan branch discards the populated line and renders a new activityLine. Preserve the lifted line's label and completion state in this branch, so the live line still says the completed step.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/src/agent-session/acpmux/conversation/turns.ts, line 998:

<comment>A completed latest step disappears when a todo list is present: `liftedStep` removes it, but the plan branch discards the populated `line` and renders a new `activityLine`. Preserve the lifted line's label and completion state in this branch, so the live line still says the completed step.</comment>

<file context>
@@ -986,6 +987,20 @@ function codexLiveTurn(
+    // just keep going"). The step leaves its run while the line names it, so it reads once.
+    const lifted = liftedStep(rows, last);
+    if (lifted) {
+      rows = lifted.rows;
+      line.doing = lifted.doing;
+      line.doingShell = lifted.shell;
</file context>

… list keeps its calls

Review follow-ups on #29938: a run joined to an earlier one by a short note
keeps that one's id, so the line looked it up by `joined` too; with a todo
list the activity line is the live line, so no call leaves its run; the
lifted run's version is a run state of its own (RUN_STATES 6, LIFTED 5).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-20208ae4fb1bb2a05468

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="webviews/test/transcript-codex-live-line.test.tsx">

<violation number="1" location="webviews/test/transcript-codex-live-line.test.tsx:423">
P2: This test never verifies the behavior named in its title: the activity line could have the wrong kind or label and still pass. Assert that the final row is an `activityLine` with `text: "Step one"` (and `below: true`) before checking the calls remain in the run.</violation>
</file>

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

new Set(),
{ working: true, liveRuns: true, lineBelow: true, sessionStatus: true },
);
expect(callIds(shaped)).toEqual(["a", "b"]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: This test never verifies the behavior named in its title: the activity line could have the wrong kind or label and still pass. Assert that the final row is an activityLine with text: "Step one" (and below: true) before checking the calls remain in the run.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/test/transcript-codex-live-line.test.tsx, line 423:

<comment>This test never verifies the behavior named in its title: the activity line could have the wrong kind or label and still pass. Assert that the final row is an `activityLine` with `text: "Step one"` (and `below: true`) before checking the calls remain in the run.</comment>

<file context>
@@ -398,3 +398,27 @@ test("a call that takes no input keeps its row in an ended turn", () => {
+    new Set(),
+    { working: true, liveRuns: true, lineBelow: true, sessionStatus: true },
+  );
+  expect(callIds(shaped)).toEqual(["a", "b"]);
+});
</file context>
Suggested change
expect(callIds(shaped)).toEqual(["a", "b"]);
expect(shaped.at(-1)).toMatchObject({ kind: "activityLine", text: "Step one", below: true });
expect(callIds(shaped)).toEqual(["a", "b"]);

…on its own

RUN_STATES 6 broke minimap-card-metadata's pinned edit-card version (review
BLOCK at 58cefe8). The lifted run keeps version*2+1 as at 427e775.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-20208ae4fb1bb2a05468

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="webviews/src/agent-session/acpmux/conversation/turns.ts">

<violation number="1" location="webviews/src/agent-session/acpmux/conversation/turns.ts:1065">
P2: This encoding can reuse a prior version on the live-to-ended transition, so React may skip the completed run when its activity version changes from 1 to 2 in the same snapshot. Use a distinct state offset for lifted runs.</violation>
</file>

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

const doing = shell ? (call.command ? shortCommand(call.command) : "") : runningLabel(call, item!.text);
const kept = items.filter((_, position) => position !== index);
const next = rows.slice();
if (kept.length) next[at] = { ...run, items: kept, version: run.version * LIFTED_STATES + 1 };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: This encoding can reuse a prior version on the live-to-ended transition, so React may skip the completed run when its activity version changes from 1 to 2 in the same snapshot. Use a distinct state offset for lifted runs.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/src/agent-session/acpmux/conversation/turns.ts, line 1065:

<comment>This encoding can reuse a prior version on the live-to-ended transition, so React may skip the completed run when its activity version changes from 1 to 2 in the same snapshot. Use a distinct state offset for lifted runs.</comment>

<file context>
@@ -1062,13 +1062,13 @@ function liftedStep(
   const kept = items.filter((_, position) => position !== index);
   const next = rows.slice();
-  if (kept.length) next[at] = { ...run, items: kept, version: run.version * RUN_STATES + LIFTED };
+  if (kept.length) next[at] = { ...run, items: kept, version: run.version * LIFTED_STATES + 1 };
   else next.splice(at, 1);
   return { rows: next, doing, shell };
</file context>
Suggested change
if (kept.length) next[at] = { ...run, items: kept, version: run.version * LIFTED_STATES + 1 };
if (kept.length) next[at] = { ...run, items: kept, version: run.version * RUN_STATES + RUN_STATES };

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent claude-opus-5-5 medium): SHIP at b1294f6

Three rounds:

  • 427e775: SHIP with follow-ups.
  • 58cefe8: BLOCK. RUN_STATES 6 broke minimap-card-metadata's pinned versions.
  • b1294f6: SHIP. The revert brings back RUN_STATES 5 and the lifted run's v*2+1. The no-lift-with-a-todo-list fix and the merged-run (joined) fix stay.

At b1294f6, six focused files pass (67 tests): minimap-card-metadata, transcript-codex-live-line, transcript-running-live-line, transcript-live-runs, transcript-working-line and transcript-consolidated-runs.

Follow-ups (non-blocking, in the PR body):

  • The lifted run's version can collide with the ended open fold's in a narrow case.
  • Find can count the lifted call but not reveal it.
  • A one-call run leaves and comes back.

@blacksmith-sh

blacksmith-sh Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

Found 5 test failures on Blacksmith runners:

Failures

Test View Logs
nightly must build and hand off the macOS 26 helper and Xcode 26.5 app before publishin
g/
nightly must build and hand off the macOS 26 helper and Xcode 26.5 app before publishin
g
View Logs
test_helper_never_takes_a_hosted_mac_and_skips_compile_on_hit (main.WorkflowTests.t
est_helper_never_takes_a_hosted_mac_and_skips_compile_on_hit)/
test_helper_never_takes_a_hosted_mac_and_skips_compile_on_hit (main.WorkflowTests.t
est_helper_never_takes_a_hosted_mac_and_skips_compile_on_hit)
View Logs
test_the_nightly_is_covered (main.NightlyStepCoverageTests.test_the_nightly_is_cove
red)/
test_the_nightly_is_covered (main.NightlyStepCoverageTests.test_the_nightly_is_cove
red)
View Logs
test_the_repository_highlights_validate (main.DigestTests.test_the_repository_highl
ights_validate)/
test_the_repository_highlights_validate (main.DigestTests.test_the_repository_highl
ights_validate)
View Logs
test_under_githubs_limit_with_headroom (main.NightlyWorkflowSize.test_under_githubs
_limit_with_headroom)/
test_under_githubs_limit_with_headroom (main.NightlyWorkflowSize.test_under_githubs
_limit_with_headroom)
View Logs

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Base reds, not this PR's own. All three are reproduced on the base tip.

cmux-next checks fails on two items, and neither touches a file this PR changes (it changes only webviews TS and its tests):

  • tests/test_cmux_next_checks_workflow.py test_every_part_of_bun_run_check_runs_in_the_warn_branch: "bun run check:session-info-names ... does not run when CMUX_NEXT_STYLE_GUARDS=warn". At feat-cmux-next 08c0011 it fails the same way: FAILED (failures=1), 165 tests.
  • scripts/lint-ios-package-conventions.sh: namespace-type in Packages/macOS/CmuxNext/Sources/CmuxNextAgentPane/AgentPaneHandoffPrompt.swift:11. At 08c0011 the same ERROR line appears.

health (2) and health (3) report "1 red state(s) render or are red another way on base 94a9a59: agent-pane.transcript#tool-result-envelopes", which is a base red by the job's own wording.

release-notary and Guard status are guard-status base reds.

…inished step

The webview verdict on #29938 named three: the peer chat's line still names
its call once done, the question record's read becomes a row when the next
call runs, and the compositor shimmer test times its line from the turn.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-20208ae4fb1bb2a05468
teamleaderleo and others added 2 commits November 1, 2026 05:47
…may be under the reply

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-20208ae4fb1bb2a05468
…e live line now

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-20208ae4fb1bb2a05468
@cursor

cursor Bot commented Nov 1, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@cubic-dev-ai cubic-dev-ai 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.

2 issues found across 5 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="webviews/test/agent-pane-peer-chat.test.ts">

<violation number="1" location="webviews/test/agent-pane-peer-chat.test.ts:394">
P2: This no longer waits for any post-completion state: `.cv-worked__time` already exists while `Run make` is running, so the assertion can read the pre-completion DOM and miss a continuity regression. Wait for an observable completed state (for example, make the fixture render distinct `Running`/`Ran` labels and await `Ran`, or send a next call and assert the completed call becomes its row).</violation>
</file>

<file name="webviews/test/agent-pane-stream-jitter.test.ts">

<violation number="1" location="webviews/test/agent-pane-stream-jitter.test.ts:563">
P2: This allowance removes the only assertion that the tool-ending fixture actually contributes a tool row. A regression that omits or fails to fold that row can still satisfy the remaining geometry equality; assert the live/finished row content separately while allowing zero height change.</violation>
</file>

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

// The call ends: the live line holds it until the next step and times the turn from the
// prompt ("Run make 5s"), moved onto this computer's clock, as it did while the call ran.
send(3, "tool_call_update", { toolCallId: "t1", status: "completed" });
await row.first().waitFor({ state: "detached" });

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: This no longer waits for any post-completion state: .cv-worked__time already exists while Run make is running, so the assertion can read the pre-completion DOM and miss a continuity regression. Wait for an observable completed state (for example, make the fixture render distinct Running/Ran labels and await Ran, or send a next call and assert the completed call becomes its row).

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/test/agent-pane-peer-chat.test.ts, line 394:

<comment>This no longer waits for any post-completion state: `.cv-worked__time` already exists while `Run make` is running, so the assertion can read the pre-completion DOM and miss a continuity regression. Wait for an observable completed state (for example, make the fixture render distinct `Running`/`Ran` labels and await `Ran`, or send a next call and assert the completed call becomes its row).</comment>

<file context>
@@ -388,10 +388,9 @@ await requireBrowserLane("agent-pane-peer-chat.test.ts", async () => {
+      // prompt ("Run make 5s"), moved onto this computer's clock, as it did while the call ran.
       send(3, "tool_call_update", { toolCallId: "t1", status: "completed" });
-      await row.first().waitFor({ state: "detached" });
       const time = page.locator(".cv-worked.is-below .cv-worked__time");
       await time.waitFor();
       const label = (await time.textContent()) ?? "";
</file context>

// drops by what went from under it, once, in the settle's frame, and rests there.
// on purpose): whatever ran after the reply leaves from under it, so the reply drops by
// what went from under it, once, in the settle's frame, and rests there. The live line
// holds the finished call until the turn ends (Leo, 2026-11-01: "it should just keep

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: This allowance removes the only assertion that the tool-ending fixture actually contributes a tool row. A regression that omits or fails to fold that row can still satisfy the remaining geometry equality; assert the live/finished row content separately while allowing zero height change.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At webviews/test/agent-pane-stream-jitter.test.ts, line 563:

<comment>This allowance removes the only assertion that the tool-ending fixture actually contributes a tool row. A regression that omits or fails to fold that row can still satisfy the remaining geometry equality; assert the live/finished row content separately while allowing zero height change.</comment>

<file context>
@@ -558,10 +558,11 @@ await requireBrowserLane("agent-pane-stream-jitter.test.ts", async () => {
-          // drops by what went from under it, once, in the settle's frame, and rests there.
+          // on purpose): whatever ran after the reply leaves from under it, so the reply drops by
+          // what went from under it, once, in the settle's frame, and rests there. The live line
+          // holds the finished call until the turn ends (Leo, 2026-11-01: "it should just keep
+          // going"), and the footer takes the line's place at its height, so that may be nothing.
           const left = before!.under! - after!.under!;
</file context>

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent claude-opus-5-5 medium): SHIP at bd1ce43

Source unchanged since the SHIP at b1294f6; the delta b1294f6..bd1ce43 touches only five webview tests, each adapted to the intended behaviour (a finished last call stays on the live line instead of a row). No assertion weaker than the change requires.

Follow-ups:

  • peer-chat: after completed, assert the line still reads "Run make" with the time.
  • stream-jitter: expect(left).toBeGreaterThanOrEqual(-1) in the tool-ending branch.
  • subagent-groups-open: STALE test also waits on "Read tests.ts" before the no-groups check.

Verdict-named tests at bd1ce43 (cmux-ci run 41278616620): subagent-groups-open green; stream-jitter's only fail, "the reply only moves up as a tool call, the working line and the queue card come and go", fails the same way with base source (run of job 124762770402, reverse-patched), so it is a base red.

@cmux-bot
cmux-bot Bot temporarily deployed to ci-routing-agent November 1, 2026 06:10 Inactive
@cmux-bot
cmux-bot Bot temporarily deployed to ci-routing-agent November 1, 2026 06:12 Inactive
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent claude-opus-5-5 medium): SHIP at fbfd657

Delta since the SHIP at bd1ce43 (and cmux-bot's base merge ff392ce): one gallery fixture. agent-pane.transcript#tool-result-envelopes is a working turn whose calls all finished, so the live line took its last call and the play found one row fewer; a reply under the calls keeps every call a row. Its play and checks are unchanged.

Gallery health, agent-pane.transcript and agent-pane.transcript-view at fbfd657 vs the same tree with this PR's src reverse-applied (cmux-ci, this lane): tool-result-envelopes renders at head; transcript-view#verbose ("Verbose did not draw .cv-command[aria-expanded=true]") is broken identically on base source, so it is a base red.

Follow-ups:

  • mcp-calls (no play): its last finished call MCP_READ now sits on the live line instead of a row; check the render and add a reply if the read should stay a row.

@teamleaderleo
teamleaderleo merged commit 5f1acf7 into feat-cmux-next Nov 1, 2026
144 of 153 checks passed
@teamleaderleo
teamleaderleo deleted the lane/transcript-live-line-keeps-going branch November 1, 2026 09:43
teamleaderleo added a commit that referenced this pull request Nov 1, 2026
…t step draws on the live line

#29938 draws a running turn's latest step on its own live line, outside
.cv-tool-run, so the fixture's last command left the run and the second
note had no row below it. One more call keeps it between two run rows.
transcript-interim-prose-gap.test.ts: red after the base merge (3 of 4
note gaps found), green with this (4 of 4 at 12px, light and dark).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-92fa78a91e29868c5eaa
teamleaderleo added a commit that referenced this pull request Nov 1, 2026
* test(transcript): measure the room around a note between tool rows

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-92fa78a91e29868c5eaa

* fix(transcript): give a note between tool rows the plain gap above and below

Leo, 2026-11-01: "the thoughts in between tool calls probably want a bit more padding"

A short interim note folded into a run of calls (turns.ts mergeShortNotes)
had 3px to the tool rows around it. It now has --cv-note-gap, the 12px
plain status gap a longer reply between two runs has; model.ts estimates
the note with the same numbers. Gallery variants compare 3, 8, 12 and 16px.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-92fa78a91e29868c5eaa

* test(transcript): open only the run in the note-gap gallery entry

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-92fa78a91e29868c5eaa

* test(transcript): keep the second note between run rows now the latest step draws on the live line

#29938 draws a running turn's latest step on its own live line, outside
.cv-tool-run, so the fixture's last command left the run and the second
note had no row below it. One more call keeps it between two run rows.
transcript-interim-prose-gap.test.ts: red after the base merge (3 of 4
note gaps found), green with this (4 of 4 at 12px, light and dark).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-92fa78a91e29868c5eaa

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: cmux-bot[bot] <348531757+cmux-bot[bot]@users.noreply.github.com>
cmux-bot Bot pushed a commit that referenced this pull request Nov 3, 2026
…29938's live line (#33614)

* base red: the spacing table finds the live line across its lead span (#33241)

#33241 draws the live line's verb in its own span ("Sending" | " message to …"),
so no single text node holds "Sending message to" and step-to-live / live-to-step
measured nothing. The test now finds the live line by its row's text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-2f629b93d5a20c58e6f8

* base red: the codex live line test reads the live line's column class (#33157)

#33157 gives the live line `cv-worked--live` (its words on the status rows' text
column), so its quiet box renders "cv-worked cv-worked--live is-quiet".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-2f629b93d5a20c58e6f8

* base red: the working-counts tray lists its subagents newest first (#33364)

#33364 orders the open running tray newest first: Tester (spawned after Reviewer)
now leads.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-2f629b93d5a20c58e6f8

* base red: the live permission tests move the turn past the approved call (#33408, #33439)

In a running turn with nothing after it, the latest finished call is lifted onto the
live line (turns.ts liftedStep, #29938), so its row and its Approved mark are not drawn.
#33439 pushed only the call's completion; the tests now push the reply's first words
after it, the state the passing resync test already reaches.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-2f629b93d5a20c58e6f8

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

This branch was previously deployed

1 inactive deployment
ci-routing-agent — fbfd657b Deployed Nov 1, 2026 by teamleaderleo via cmux-tui tree preflight #94739
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant