Skip to content

🤖 feat: immersive review assisted-mode badge + agent status bar#3432

Merged
ammario merged 7 commits into
mainfrom
immersive-review-7f99
Jun 2, 2026
Merged

🤖 feat: immersive review assisted-mode badge + agent status bar#3432
ammario merged 7 commits into
mainfrom
immersive-review-7f99

Conversation

@ammar-agent

@ammar-agent ammar-agent commented May 31, 2026

Copy link
Copy Markdown
Collaborator

Summary

Two gaps in full-screen Immersive Review are fixed: there's now a clear indicator when the Assisted filter is active, and a top status bar that surfaces the agent's TODO plan (a compact horizontal strip) alongside live chat/streaming status so reviewers waiting on the agent keep their signal without leaving review.

Background

Immersive review renders into an opaque overlay (#review-immersive-root, absolute inset-0 z-50) that covers the normal review panel.

  1. No Assisted-mode indication. The Assisted toggle/badge lives in ReviewControls, which is hidden behind that overlay. Once immersive, the diff could be filtered to agent-flagged hunks with zero on-screen indication. (The existing per-hunk assisted banner only means "this hunk was flagged" — not "the worklist filter is on".)
  2. No chat status. A common workflow is reviewing code while waiting for the agent to respond. In immersive mode the transcript, composer streaming barrier, and pinned TODO list are all hidden, so the user had no view of plan progress or streaming state.

Implementation

Issue 1 — Assisted-mode badge

  • ReviewPanel now threads assistedOnly + assistedCount + assistedUnreadCount into the immersive portal (previously only the per-hunk assistedHunkIds/comments were passed).
  • ImmersiveReviewView renders a header badge (Sparkles + --color-review-accent + unread/total via counter-nums) only while assistedOnly is on. Kept visually/semantically distinct from the per-hunk assisted banner.

Issue 2 — Agent status bar (ImmersiveReviewAgentStatusBar.tsx, mounted between header and the per-hunk banner)

  • TODO plan rendered as a single horizontal strip via the shared <TodoList layout="horizontal"> (one row tall, scrolls sideways — minimal review height), collapsible with per-workspace persisted expand state (new getImmersiveReviewAgentBarExpandedKey), plus a summary line ("TODO · 2 in progress · 3 pending").
  • Compact streaming chip: Starting… / Streaming… / a prominent "Mux has a question".
  • Flash-free & graceful:
    • Chip is gated on the held phase from useWorkspaceStreamingStatusPhase (150ms), so starting↔streaming handoffs don't blink.
    • Because plans persist across turns, the bar stays mounted between streams and only unmounts once the held phase clears and there are no todos — no mid-review flicker.
    • Data is synchronous from WorkspaceStore (no skeleton needed); subscriptions live in this leaf so todo/stream churn doesn't re-render the large diff tree.
    • Crash-safe: falls back to empty/idle when the workspace isn't registered (renders null in tests/stories rather than throwing).

Banner scoping — the per-hunk assisted comment banner now lives inside the diff column wrapper (not above the whole body), so it spans only the diff width and lines up with the code it refers to instead of stretching across the minimap + notes sidebar.

Validation

  • New behavioral tests: ImmersiveReviewAgentStatusBar.test.tsx (plan render, idle→null, streaming/starting chips, awaiting-question precedence, collapse persistence) and an assisted-badge gating test in ImmersiveReviewView.test.tsx.
  • New Storybook stories for Chromatic coverage: ImmersiveWithAssistedMode (header badge), ImmersiveWithAgentStatusBar (horizontal TODO strip + live streaming chip), and ImmersiveWithStreamingNoTodo (chip-only state when streaming before any plan is written). The status-bar stories seed the WorkspaceStore so the bar has real state. Snapshot budget stays within limit (250/250, no bump).
  • Snapshot budget: rebased on main (current limit 250); the two new immersive stories fit within budget (249/250), so no budget change or story compression was needed.

Risks

Low. The status bar is an additive, self-subscribed leaf that returns null when there's nothing to show, so it can't reserve review height or cascade re-renders into the diff. The only change to existing render paths is the new header badge (gated on assistedOnly), three new optional props threaded from ReviewPanel, and moving the assisted banner inside the diff column.


Generated with mux • Model: anthropic:claude-opus-4-8 • Thinking: xhigh • Cost: $47.63

@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@codex review

@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: 74833a4075

ℹ️ 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 src/common/constants/storage.ts
@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@codex review

Addressed: added getImmersiveReviewAgentBarExpandedKey to EPHEMERAL_WORKSPACE_KEY_FUNCTIONS so the key is deleted on workspace removal (and still not copied on fork), matching the documented intent. Please take another look.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

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

@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@codex review

Pushed two follow-ups:

  1. The new review-immersive-agentbar-expanded localStorage key is now in EPHEMERAL_WORKSPACE_KEY_FUNCTIONS so it's cleaned up on workspace removal (still not copied on fork).
  2. Fixed the CI-only unit test failures: the status bar now reads todos + streaming flags from a single getWorkspaceState subscription (matching PinnedTodoList) instead of a separate sidebar hook that other test files globally mock.module. The test now uses installDom + spyOn and asserts collapse persistence behaviorally via remount, and passes under all file-ordering permutations.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

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

@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@codex review

Addressed review feedback:

  1. Assisted comment scoped to the diff column. The immersive assisted-review comment banner now renders inside the diff column (a flex-col wrapper around the scroll area) instead of above the whole body, so it spans only the diff width and lines up with the code it refers to — no longer stretching across the minimap and notes sidebar.
  2. TODO status bar is now visible in Storybook. Added the ImmersiveWithAgentStatusBar story, which seeds the WorkspaceStore (registers a workspace + replays a todo_write through the aggregator) so the new top status bar renders a real vertical TODO plan + live "Streaming…" chip. Seeding runs during render before the child subscribes, so it paints populated on the first frame (flash-free for Chromatic).

Note: bumped the storybook snapshot budget 303 → 307 to cover the two new immersive stories. origin/main was already computing 305 against the stale 303 limit, so this also clears that pre-existing overage.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

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

@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@codex review

Reverted the snapshot-budget bump (kept MAX_ESTIMATED_SNAPSHOTS=303). Made room for the two new immersive stories by consolidating four redundant AgentListItem single-state stories (Selected/ErrorState/Question/Draft) into the existing FigmaStates matrix story — no unique visual coverage lost. This also clears a pre-existing overage (origin/main was at 305 > 303).

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

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

Surface assisted-filter mode and chat status inside full-screen immersive review.
Read todos + streaming flags from a single getWorkspaceState subscription
(matching PinnedTodoList) instead of a separate useOptionalWorkspaceSidebarState
hook, which other test files globally mock.module and which caused CI-only
failures. Rewrite the test to use installDom + spyOn and assert collapse
persistence behaviorally via remount.
- Move the immersive assisted-review comment banner inside the diff column so
  it spans only the diff width, not across the minimap + notes sidebar.
- Add ImmersiveWithAgentStatusBar story that seeds the WorkspaceStore so the
  top TODO + streaming status bar renders with real state (flash-free).
@ammar-agent ammar-agent force-pushed the immersive-review-7f99 branch from 568061b to df29340 Compare June 1, 2026 20:13
@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@codex review

Rebased onto latest main and dropped the story-compression work entirely. main lowered the snapshot budget to 250 and brought its own count down to 247, so the two new immersive stories now fit within budget (249/250) with no budget bump and no changes to AgentListItem.stories.tsx — both budget.test.ts and AgentListItem.stories.tsx are now identical to main. Only the immersive-review feature changes remain.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

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

Render the immersive review agent status bar's TODO plan as a single
horizontally-scrolling row of compact chips instead of a tall vertical list,
so the plan reserves minimal vertical space in the review viewport.

- TodoList gains an optional `layout` prop ("vertical" default | "horizontal").
  Horizontal mode lays chips in one scrollable row; the pinned list and tool
  history keep the default vertical layout untouched.
- The bar drops its 240px-tall vertical scroll wrapper and renders the
  horizontal strip, keeping the collapse/persist toggle and streaming chip.
@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@codex review

Changed the immersive review TODO plan from a tall vertical list to a single horizontal strip so it reserves minimal vertical space in the review viewport. Implemented by adding an optional layout prop to the shared <TodoList> ("vertical" default | "horizontal"); the pinned list and tool-history consumers keep the default vertical layout untouched. The bar drops its 240px vertical scroll wrapper and keeps the collapse/persist toggle + streaming chip.

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

ℹ️ 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 src/browser/features/RightSidebar/CodeReview/ImmersiveReviewAgentStatusBar.tsx Outdated
When the agent is streaming but hasn't written a TODO plan, the status bar
previously pushed the "Streaming…" chip to the far right (ml-auto), leaving it
floating alone on an otherwise-empty bar. Left-align the chip in the no-plan
case so it reads as a status label; the TODO case keeps ml-auto so the chip +
chevron stay right of the plan summary.

Add an ImmersiveWithStreamingNoTodo Storybook story that seeds an open stream
with no todo_write so Chromatic covers this chip-only state. The story seeding
helper (seedAgentStatus) now skips the todo_write push when no todos are given;
budget stays within limit (250/250, no bump).
@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@codex review

Two follow-ups for the streaming indicator when there's no TODO plan:

  1. Looks-good fix: in the no-plan case the "Streaming…" chip used ml-auto, leaving it floating alone on the far right of an empty bar. It's now left-aligned so it reads as a status label. The TODO case keeps ml-auto so the chip + chevron stay right of the plan summary.
  2. Coverage: added an ImmersiveWithStreamingNoTodo Storybook story (seeds an open stream with no todo_write) so Chromatic captures this chip-only state. The seeding helper now skips the todo_write push when no todos are provided. Snapshot budget stays within limit (250/250, no bump).

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

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

Codex P2: the bar's useSyncExternalStore returned the whole getWorkspaceState()
object as its snapshot. Because that object is version-cached, its reference
changes on every WorkspaceState bump (e.g. each streamed message), re-rendering
the bar on every token while the user reviews code.

Read each field the bar uses (todos, canInterrupt, isStreamStarting,
awaitingUserQuestion) as its own snapshot instead. Primitives compare by value
and todos keeps a stable aggregator reference (same basis as PinnedTodoList),
so the bar only re-renders when a field it actually uses changes.

Add a regression test asserting the bar ignores unrelated state bumps and
re-renders only on a watched-field change.
@ammar-agent

Copy link
Copy Markdown
Collaborator Author

Addressed the P2 on the immersive status bar's useSyncExternalStore:

  • The bar no longer returns the whole getWorkspaceState() object as its snapshot (which version-bumps its reference on every unrelated WorkspaceState change, e.g. each streamed message). It now reads each field it usestodos, canInterrupt, isStreamStarting, awaitingUserQuestion — as its own useSyncExternalStore snapshot. Primitives compare by value and todos keeps a stable aggregator reference (same basis as PinnedTodoList reading only .todos), so the bar re-renders only when a field it actually uses changes.
  • Added a regression test that asserts the bar ignores unrelated state bumps (new WorkspaceState ref, same watched fields) and re-renders only on a watched-field change.

Fixed in ea9cea88a7.

@ammar-agent

Copy link
Copy Markdown
Collaborator Author

@codex review

Addressed the P2: the immersive status bar now subscribes to each workspace field it uses (todos / canInterrupt / isStreamStarting / awaitingUserQuestion) as its own useSyncExternalStore snapshot instead of returning the whole version-cached WorkspaceState object, so it no longer re-renders on unrelated state bumps (e.g. streamed messages). Added a regression test for the leaf-subscription invariant. Thread resolved.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

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

@ammario ammario merged commit 995d97f into main Jun 2, 2026
24 checks passed
@ammario ammario deleted the immersive-review-7f99 branch June 2, 2026 02:00
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