cmux NEXT: scope session Changes and add Sources

Merged
TE
7d ago
+772-106

What changed

This is the Inspector UI/state half, built on #26325 (merged at 86250fb2cc9154a17d0b2d51a4ce5faab42df75c). It applies the Session Info content contract in teamleaderleo/leo-workspace#1068 (merged at 33357663).

  • Changes lists only pull requests opened or mutated by this session, with open changes first and five rows before Show more / Show less. Read-only references cannot keep an empty Changes header visible, even while folded and uncached. The composer count and Changes status requests use the same visibleChanges selector. Read-only PRs and issues in Sources trigger neither status inspections nor polling, including with Changes open by default.
  • Sources lists read-only PRs/issues, settled URLs, files read, and MCP tools. Five rows show before View all N / Show fewer; expansion is stored per pane and survives streamed updates. PR, issue and URL rows navigate beside the chat. File rows normalize paths and stay inside the session folder or the subagent’s own worktree; escaped paths and other roots remain plain text. Supported files open beside the chat. HTML, SVG and extensionless files retry the existing native editor route when tab opening is refused, and a failed open displays its error on the row.
  • Outputs and summaries use the scoped session folder supplied by #26325. Run Board callers without a folder remain intentionally unscoped.

Leo's words: “where are the sources part of the stuff?” and “there's a show more button, show less”.

Known gap versus lw#1068: git push/revert attribution is deferred to a follow-up. Explicit refspecs, chained commands, quoted git -C paths, HEAD:refs/heads/..., unrelated pushes and branch observations need reliable attribution before those actions can enter Changes. #26325 handles unambiguous gh PR/issue mutations and brokered comments; this UI PR does not claim push/revert support.

Validation

129 focused tests pass (689 assertions across 12 files), covering Inspector, per-pane state, Sources/Outputs, PR dock, Run Board, parser and producer revisions after merging #26325 at ad185a9a9289db04deb39126c7fac5d9fbc96986. New regressions exercise mixed PR/issue/URL/file targets through ChatInspector, relative and absolute file opens, the full subagent hook resolving its own worktree, Show fewer, expansion during streaming, and folded read-only references without an empty Changes header. Regression coverage also exercises path normalization and worktree escape rejection, native tab-to-editor requests for HTML/SVG/Dockerfile, missing-file errors and transient-error expiry. The reported UI bugs reproduced before their fixes. The latest regression proves that read-only Sources make no link.inspect/pr.inspect calls and start no Changes polling; existing mutation-fetch tests continue to pass.

  • Fixed waits, layers and design-token checks pass.
  • Changed-file vp formatting/lint and TypeScript pass (2,880 files).
  • scripts/web-lint.sh, prepush-gate.py, fixed waits, layers, design tokens and diff checks pass. The UI diff is 806 changed lines over #26325.

Size: about 880 UI-only changed lines, including the integrated regressions proving remote-child file scoping and Sources ordering after reopening. Parser and producer changes land separately in #26325.

  • The existing before/after and real app captures below document the UI; this delta preserves the row appearance while making file rows actionable.

Before: https://raw.githubusercontent.com/manaflow-ai/cmux/pr-media/25208/before.png

After: https://raw.githubusercontent.com/manaflow-ai/cmux/pr-media/25208/after.png

Real app captures

Capture steps-1b43a191ff at 707592be90e2 (fleet build, Blacksmith macOS capture; text checked for private data)

cap 707592be session info light

cap 707592be session info dark

Integration verification

#26325 is merged. Final integration head 368478394cd7474e8fa27eef1a41465d8265c508 merges base 86250fb2cc9154a17d0b2d51a4ce5faab42df75c and preserves the reorderable Inspector groups, with Sources registered in the made group.

Observed / Not run

Final integrated verification passes all eleven focused test files and the full web check: formatting, lint, type, protocol, layers and token checks. The verified snapshot tree exactly matches this head. Coverage includes the original conditional-mutation and steer reproductions, Sources visibility and saved order after reopening, child-session file routing and expansion state. All checks ran remotely. No native code changed and no new native compile was requested; real app captures are linked above.

Command: cmux-ci test --setup webviews --timeout 900 -- bash -lc 'set -eu; cd webviews; bun run test test/transcript-pull-requests.test.ts src/agent-session/acpmux/subagents/subagentFold.test.ts test/agent-pane-background-on-call.test.ts test/sources-files-once.test.tsx test/pr-dock-stale-state.test.tsx test/chat-inspector.test.tsx test/inspector-per-pane-state.test.ts test/inspector-section-order.test.tsx test/chat-inspector-subagent.test.tsx test/chat-inspector-outputs.test.tsx test/chat-inspector-changes.test.tsx; bun run check'.

Prior integration head 27d16fddaa93b37558f0c6f110ab444f87a5a7b3 received independent Astra SHIP. Independent Astra review: SHIP at 368478394cd7474e8fa27eef1a41465d8265c508, with no actionable correctness findings in the complete UI delta or integration. The unchanged HomeChatColors SwiftUI imports were reproduced identically on the parser and base in comparison run 40850823642.

Takes back #25206: Changes and Sources render their fold buttons explicitly with the same button type, classes, aria-expanded state and toggle handler as InspectorFold. The shared full-width hit target, no-hover-fill styling and keyboard focus policy from #25206 remain intact; this replaces the wrapper without reversing its behavior.

Exact head/base release-note comparison reproduces the same DigestTests.test_the_repository_highlights_validate failure for unchanged tool-audio-discovery.md on head and base; the missing try-it/docs metadata is existing base debt.

Risk

File Sources use native file.open: tab refusal occurs before its gesture is consumed, permitting the validated editor fallback. Native roots and file-existence checks still apply; remote/cloud sessions do not receive a local callback. A row error clears after four seconds; its timeout is cancelled on error change or row unmount. No new observer or animation loop. Parser and producer revision behavior belongs to dependency #26325.

Agent session: agent session