Skip to content

🤖 feat: add browser preview tab switching#3399

Open
ThomasK33 wants to merge 8 commits into
mainfrom
mux-agent-y1dq
Open

🤖 feat: add browser preview tab switching#3399
ThomasK33 wants to merge 8 commits into
mainfrom
mux-agent-y1dq

Conversation

@ThomasK33
Copy link
Copy Markdown
Member

Summary

Adds browser page-tab awareness to the Browser Preview panel so users can see and switch between agent-browser tabs from Mux.

Background

agent-browser already supports multi-tab sessions, but Mux previously only showed the currently streamed page. If an agent opened another tab, users had no way to discover or select it from the Browser Preview UI.

Implementation

  • Adds shared ORPC schemas and endpoints for browser.listTabs and browser.selectTab.
  • Extends BrowserControlService to validate session ownership, call agent-browser tab list / tab <ref>, and parse page-tab metadata.
  • Adds a horizontal Browser Preview tab strip with keyboard tablist navigation, active/pending states, and tab switching.
  • Reuses the browser loading-state path for tab switching so the preview URL/loading state refreshes after selection.

Validation

  • bun test src/browser/features/RightSidebar/BrowserTab/BrowserTab.test.tsx src/node/services/browser/BrowserControlService.test.ts
  • make typecheck
  • make lint
  • make static-check

Risks

Medium UI/backend integration risk: this touches Browser Preview polling, ORPC schemas, and agent-browser CLI control paths. The new behavior is scoped to the experimental Agent Browser tab.


Generated with mux • Model: openai:gpt-5.5 • Thinking: xhigh • Cost: $115.09

@ThomasK33
Copy link
Copy Markdown
Member Author

/coder-agents-review

@ThomasK33
Copy link
Copy Markdown
Member Author

@codex review

@coder-agents-review
Copy link
Copy Markdown

coder-agents-review Bot commented May 27, 2026

Chat: Spend limit reached | View chat
Requested: 2026-05-27 12:19 UTC by @ThomasK33
Spend: $103.84 / $100.00 (limit reached)

Review history
  • R1 (2026-05-27): 18 reviewers, 7 Nit, 3 Note, 2 P2, 13 P3, 1 P4, REQUEST_CHANGES. Review
  • R2 (2026-05-27): 8 reviewers, 8 Nit, 6 Note, 1 P0, 2 P2, 18 P3, 1 P4, REQUEST_CHANGES. Review
  • R3 (2026-05-27), 8 Nit, 6 Note, 1 P0, 2 P2, 18 P3, 1 P4, COMMENT. Review
  • R4 (2026-05-27): 5 reviewers, 8 Nit, 8 Note, 1 P0, 2 P2, 20 P3, 1 P4, APPROVE. Review
  • R5 (2026-05-27), 8 Nit, 8 Note, 1 P0, 2 P2, 20 P3, 1 P4, COMMENT. Review
  • R6 (2026-05-27): 3 reviewers, 8 Nit, 8 Note, 1 P0, 2 P2, 20 P3, 1 P4, APPROVE. Review

deep-review v0.5.0 | Round 6 | 5d79d9b..8dd084d

Last posted: Round 6, 40 findings (1 P0, 2 P2, 20 P3, 1 P4, 8 Nit, 8 Note), APPROVE. Review

Finding inventory

Findings

# Sev Status Location Summary Round Reviewer Posted
CRF-1 P2 Author fixed (1726a3f) BrowserTab.tsx:430 Optimistic tab-active update matches by both tabId and label; can mark two tabs active R1 Razor P2, Hisoka P3, Mafuuu P3, Chopper P3, Meruem P3, Kite P3, Knov P3, Pariston P3, Luffy P3 Yes
CRF-2 P2 Author fixed (1726a3f) BrowserControlService.ts:92 parseBrowserTabsJson has 9 branches; only 2 tested R1 Bisky P2, Mafu-san P3 Yes
CRF-3 P3 Author fixed (1726a3f) BrowserControlService.ts:122 One malformed tab entry fails the entire tab listing R1 Hisoka P3, Razor P3, Meruem Note Yes
CRF-4 P3 Author fixed (1726a3f) BrowserControlService.ts:92 Six distinct failure modes produce one misleading "invalid JSON" message R1 Leorio P3, Chopper Note Yes
CRF-5 P3 Author fixed (1726a3f) BrowserTab.test.tsx:209 No frontend test exercises error paths for tab listing or switching R1 Kite P3, Bisky P3, Razor P3 Yes
CRF-6 P3 Author fixed (1726a3f) BrowserTab.test.tsx:240 Tab switch test asserts new tab selected but not old tab deselected R1 Chopper P3 Yes
CRF-7 P3 Author fixed (1726a3f) BrowserTab.tsx:309 Frontend catch-all error messages include no session/context info R1 Leorio P3 Yes
CRF-8 P3 Author fixed (1726a3f) BrowserTab.tsx:698 Six tab label formatting helpers have zero direct test coverage R1 Bisky P3 Yes
CRF-9 P3 Author fixed (1726a3f) BrowserTab.test.tsx:254 Keyboard nav test covers ArrowRight only; ArrowLeft wrap untested R1 Bisky P3 Yes
CRF-10 P3 Author fixed (1726a3f) BrowserControlService.ts:250 tabRef passed as positional CLI argument without -- separator R1 Meruem P3, Razor Note Yes
CRF-11 P3 Author fixed (1726a3f) BrowserTab.tsx:122 areBrowserPageTabsEqual manually enumerates fields; silently drifts if schema gains a field R1 Zoro P3 Yes
CRF-12 P3 Author fixed (1726a3f) router.ts:451 skipSessionValidation: true lost its invariant comment during refactoring R1 Gon P3 Yes
CRF-13 P3 Author fixed (1726a3f) BrowserTab.tsx:658 aria-label says "Switch to" even on the active tab, contradicting aria-selected R1 Leorio P3 Yes
CRF-14 P3 Author fixed (1726a3f) BrowserTab.tsx:562 Active tab not scrolled into view on mount or polling update R1 Nami P3 Yes
CRF-15 P3 Author fixed (1726a3f) BrowserTab.tsx:394 Double-click fires two selectTab API calls; state-based guard has React commit gap R1 Hisoka P3 Yes
CRF-16 P4 Author fixed (1726a3f) BrowserTab.tsx:472 Single-tab sessions render a tab strip that offers no action R1 Luffy P4 Yes
CRF-17 Nit Author fixed (1726a3f) BrowserTab.tsx:598 Missing aria-controls and role="tabpanel" in WAI-ARIA tablist R1 Nami Yes
CRF-18 Nit Author fixed (1726a3f) BrowserTab.tsx:163 switchingTabRef naming collides with React useRef convention R1 Gon Yes
CRF-19 Nit Author fixed (1726a3f) BrowserControlService.ts:88 BrowserTabsParseResult drops "Page" from naming pattern R1 Gon Yes
CRF-20 Nit Author fixed (1726a3f) api.ts:2348 selectTab.output is byte-for-byte identical to control.output; extract shared schema R1 Robin Yes
CRF-21 Nit Author fixed (1726a3f) BrowserControlService.ts:334 formatSessionNotFoundError is a one-liner used once; inline it R1 Leorio Yes
CRF-22 Nit Author fixed (1726a3f) BrowserTab.tsx:588 event.stopPropagation() instead of project convention stopKeyboardPropagation R1 Zoro Yes
CRF-23 Nit Author fixed (1726a3f) BrowserTab.tsx:296 Stale tab preservation on error lacks the explanatory comment the session-discovery path has R1 Razor Yes
CRF-24 Note Author accepted R2 (new error/pending tests cover lifecycle; switch test validates end state) BrowserTab.test.tsx:209 Optimistic update indistinguishable from polling in test R1 Bisky Yes
CRF-25 Note Author accepted R2 (transient external state, self-correcting via next poll) BrowserTab.tsx:549 When no tab has active: true, first tab silently promoted to active R1 Hisoka Yes
CRF-26 Note Author fixed (1726a3f) router.ts:469 runBrowserCommandWithLoadingState lifecycle docs missing R1 Leorio Yes
CRF-27 P0 Author fixed (bc9b776) BrowserTab.test.tsx:392 "shows tab listing and switching errors" test deterministically fails R2 Netero Yes
CRF-28 P3 Author fixed (b60dd80) BrowserTab.test.tsx:258 Keyboard wrap-around never exercised; CRF-9 fix tests non-wrapping directions only R2 Bisky Yes
CRF-29 P3 Author fixed (b60dd80) BrowserTab.tsx:281 Poll during slow tab switch overwrites optimistic active-tab state with stale data R2 Hisoka Yes
CRF-30 P3 Author fixed (b60dd80) BrowserControlService.ts:229 Fallback error says "returned invalid JSON" when CLI reported success: false R2 Mafuuu Yes
CRF-31 P3 Author fixed (b60dd80) BrowserControlService.ts:131 Zod safeParse validates all page tabs as one array; one malformed entry rejects entire list R2 Chopper Yes
CRF-32 P3 Author fixed (b60dd80) BrowserViewport.tsx:557 role="tabpanel" renders unconditionally; orphaned landmark when 0-1 tabs R2 Nami P3, Kite Nit Yes
CRF-33 Nit Author fixed (b60dd80) BrowserControlService.test.ts:488 for loop test hides which case failed R2 Bisky Yes
CRF-34 Note Author contested; panel closed R4 (4/4 accept) router.ts:484 selectTab failure clears preview URL, but browser page didn't change R2 Hisoka Yes
CRF-35 Note Author fixed (b60dd80) BrowserTab.test.tsx:441 Formatting test proves strings exist but not rendering slot R2 Bisky Yes
CRF-36 Note Author accepted R4 (after CRF-31 per-entry validation, terse user-facing errors intentional) BrowserControlService.ts:132 Zod validation error details discarded on schema mismatch R2 Chopper Yes
CRF-37 P3 Author fixed (8dd084d) BrowserTab.test.tsx:575 No test verifies single-tab hides tab strip (CRF-16 boundary untested) R4 Bisky Yes
CRF-38 P3 Author fixed (8dd084d) BrowserControlService.ts:116 All-entries-rejected parse returns empty tabs with no error signal R4 Chopper Yes
CRF-39 Note Author fixed (8dd084d) BrowserTab.test.tsx:454 Formatting test covers uncommon paths; most common plain-title path unasserted R4 Bisky Yes
CRF-40 Note Dropped by orchestrator (body-folded Note, thread resolved) BrowserTab.test.tsx:495 Tab switching error test does not verify selection state preserved after failure R4 Chopper Yes

Contested and acknowledged

CRF-24 (Note, BrowserTab.test.tsx:209) - Optimistic update indistinguishable from polling in test

  • Finding: The tab switching test mutates the mock inside selectTabMock, so both the optimistic setPageTabs update and the next polling cycle produce the same result. If the optimistic update were removed, the test would still pass.
  • Author defense: The positive switch test covers the resulting selected state, and new error/pending tests added in R2 cover the switching lifecycle.
  • Author accepted: The gap is bounded. The optimistic update's purpose (eliminating visual flicker) is not safety-critical, and the switching lifecycle is now independently tested through error and pending-state assertions.

CRF-25 (Note, BrowserTab.tsx:549) - When no tab has active: true, first tab silently promoted to active

  • Finding: When no tab in the server response has active: true, the tab strip promotes the first tab to keyboard tab-stop and visual active state via a fallback.
  • Author defense: No active tab from the daemon is a transient external state that the next poll corrects.
  • Author accepted: The fallback is intentional for the case where the daemon is mid-transition. The 2s poll self-corrects, and the interim state (first tab highlighted) is a reasonable default.

CRF-34 (Note, router.ts:484) - selectTab failure clears preview URL, but browser page didn't change

  • Finding: selectTab failure calls markLoaded(undefined), clearing the preview URL. But a failed tab switch means the browser is still on the original tab at the original URL.
  • Author defense: BrowserSessionStateHub.markLoaded(..., undefined, commandToken) preserves entry.state.url for failed commands, so the helper does not clear the current URL on select-tab failure.
  • Panel closure (R4, 4/4): Mafuuu, Hisoka, Pariston, and Chopper independently traced BrowserSessionStateHub.markLoaded and confirmed that url=undefined with a valid commandToken resolves to entry.state.url. The existing URL is preserved, not cleared.

CRF-36 (Note, BrowserControlService.ts:132) - Zod validation error details discarded on schema mismatch

  • Finding: When safeParse fails, the .error field (with field names, expected/received types) is replaced with "unexpected JSON payload."
  • Author defense: After CRF-31, malformed individual tab entries are skipped instead of failing the whole parse, and the user-facing parse errors remain intentionally terse.
  • Author accepted: The per-entry validation from CRF-31 reduces the frequency and impact of full schema failures. Terse user-facing errors are an intentional design choice.

Round log

Round 1

Panel (18 reviewers). 2 P2, 13 P3, 1 P4, 7 Nit, 3 Note. Reviewed against 5d79d9b..c31f725.

Round 2

Panel (8 reviewers). 1 P0, 5 P3, 1 Nit, 3 Note new. Reviewed against 5d79d9b..1726a3f.

Round 3

BLOCKED. CRF-27 addressed. CRF-28 through CRF-36 silent. No review.

Round 4

Panel (5 reviewers). CRF-34 closed by panel (4/4 accept). 2 P3, 2 Note new. Reviewed against 5d79d9b..b60dd80.

Round 5

BLOCKED. CRF-37 through CRF-40 silent. No review.

Round 6

Churn guard: PROCEED. CRF-37/38/39 author-fixed. CRF-40 dropped (body-folded Note, thread resolved). Reviewed against 5d79d9b..8dd084d.

About deep-review

CRF = Coder Review Finding (P0-P4, Nit, Note)

Reviewer Focus
Bisky tests
Chopper ops/errors
Churn-guard change verification
Ging language modernization
Gon naming
Hisoka edge cases
Killua perf
Kite change integrity
Knov contracts
Knuckle SQL
Kurapika security
Leorio docs
Luffy product
Mafu-san process
Mafuuu contracts
Melody dispatch/pairing
Meruem structural
Nami frontend
Netero mechanical checks
Pariston premise testing
Pen-botter product gaps
Razor verification
Robin duplication
Ryosuke Go arch
Takumi concurrency
Zoro shape

🤖 Managed by Coder Agents.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

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: c31f725fb1

ℹ️ 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/node/services/browser/BrowserControlService.ts Outdated
@ThomasK33
Copy link
Copy Markdown
Member Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

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: c31f725fb1

ℹ️ 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/node/services/browser/BrowserControlService.ts Outdated
@ThomasK33
Copy link
Copy Markdown
Member Author

/coder-agents-review

@ThomasK33
Copy link
Copy Markdown
Member Author

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

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: b410e6f837

ℹ️ 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/node/services/browser/BrowserControlService.ts Outdated
@ThomasK33
Copy link
Copy Markdown
Member Author

/coder-agents-review

@ThomasK33
Copy link
Copy Markdown
Member Author

@codex review

@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".

Copy link
Copy Markdown

@coder-agents-review coder-agents-review Bot left a comment

Choose a reason for hiding this comment

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

Solid feature addition. The polling architecture correctly mirrors the existing session discovery pattern, the runBrowserCommandWithLoadingState extraction cleans up real duplication, and the concurrency handling (generation counter, ref-based staleness guards, cancelled flags) is well-designed. The keyboard tablist implementation covers the WAI-ARIA basics. Pariston tried to build a case against the approach and couldn't.

"I tried to build a case against this and couldn't. The problem is correctly understood, the solution is proportional, and the fix is at the right level." (Pariston)

Severity count: 2 P2, 13 P3, 1 P4, 7 Nit, 3 Note.

The two P2s are the most important: (1) the optimistic tab-active update matches by both tabId and label, which can mark two tabs active simultaneously when a label collides with a tabId (9 reviewers converged on this independently), and (2) parseBrowserTabsJson is the trust boundary between CLI output and the tab model, and 7 of its 9 branches have no test coverage.

The P3s fall into three clusters: test coverage gaps (error paths, ArrowLeft wrap, label formatters, old-tab deselection assertion), correctness/robustness issues (fail-fast on single malformed entry, misleading error messages, CLI arg injection class, schema-coupled comparator, double-click race), and UX/accessibility (aria-label on active tab, scroll-into-view, missing invariant comment).

🤖 This review was automatically generated with Coder Agents.

Comment thread src/browser/features/RightSidebar/BrowserTab/BrowserTab.tsx Outdated
Comment thread src/node/services/browser/BrowserControlService.ts Outdated
Comment thread src/node/services/browser/BrowserControlService.ts
Comment thread src/node/services/browser/BrowserControlService.ts Outdated
Comment thread src/browser/features/RightSidebar/BrowserTab/BrowserTab.test.tsx
Comment thread src/browser/features/RightSidebar/BrowserTab/BrowserTab.tsx Outdated
Comment thread src/browser/features/RightSidebar/BrowserTab/BrowserTab.tsx
Comment thread src/browser/features/RightSidebar/BrowserTab/BrowserTab.test.tsx
Comment thread src/browser/features/RightSidebar/BrowserTab/BrowserTab.tsx
Comment thread src/node/orpc/router.ts
@ThomasK33
Copy link
Copy Markdown
Member Author

Addressed coder-agents-review Round 1 findings:

  • CRF-1: switched optimistic active/pending matching to tab IDs only.
  • CRF-2: added parser coverage for malformed output, missing tabs, schema failures, and mixed target types.
  • CRF-3: non-object tab entries are now skipped instead of failing the whole list.
  • CRF-4: parser failures now distinguish invalid JSON from unexpected JSON payloads.
  • CRF-5: added frontend coverage for tab listing and tab switching error states.
  • CRF-6: tab switch test now asserts the previous tab becomes unselected.
  • CRF-7: fallback frontend errors include session/tab context.
  • CRF-8: added label-format coverage for URL-like titles, labels, and data URLs.
  • CRF-9: keyboard test now covers ArrowLeft, ArrowRight, Home, and End.
  • CRF-10: tab refs are passed after -- in the CLI argument list.
  • CRF-11: tab equality now uses whole-value comparison so new fields are not silently ignored.
  • CRF-12: restored the loading helper invariant comment around session validation / URL refresh.
  • CRF-13: tab aria labels are now neutral (Browser tab: ...).
  • CRF-14: active tab scrolls into view when the active tab changes.
  • CRF-15: added a synchronous pending-tab ref to guard double-click duplicate switches.
  • CRF-16: single-tab sessions no longer render the tab strip unless there is an error.
  • CRF-17: tabs now reference the viewport panel via aria-controls, with the viewport exposed as a tabpanel.
  • CRF-18: renamed switching state to pendingTabId / pendingTabIdRef.
  • CRF-19: renamed tab parser types/functions to include Page.
  • CRF-20: factored the shared browser command result schema.
  • CRF-21: inlined the session-not-found error string into the validation helper.
  • CRF-22: keyboard handling now uses stopKeyboardPropagation.
  • CRF-23: added the matching tab-list transient-error preservation comment.
  • CRF-24: left as a note; the positive switch test still covers the resulting selected state, and new error/pending tests cover the switching lifecycle.
  • CRF-25: left as a note; no active tab from the daemon remains a transient external state that the next poll corrects.
  • CRF-26: added a concise lifecycle comment for the loading helper.

Validation after fixes:

  • bun test src/browser/features/RightSidebar/BrowserTab/BrowserTab.test.tsx src/browser/features/RightSidebar/BrowserTab/BrowserViewport.test.tsx src/node/services/browser/BrowserControlService.test.ts
  • make static-check

@ThomasK33
Copy link
Copy Markdown
Member Author

/coder-agents-review

@ThomasK33
Copy link
Copy Markdown
Member Author

@codex review

@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".

@ThomasK33
Copy link
Copy Markdown
Member Author

@codex review

Pushed a small test-only stabilization for the BrowserTab error-state test after the unit CI caught a race.

@ThomasK33
Copy link
Copy Markdown
Member Author

/coder-agents-review

Please re-check after the BrowserTab test stabilization push.

@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".

Copy link
Copy Markdown

@coder-agents-review coder-agents-review Bot left a comment

Choose a reason for hiding this comment

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

All 26 R1 findings addressed. Thorough fix commit. Pariston verified the fixes and again found the approach proportional and correct.

R2 uncovered 1 P0 and 5 new P3s from the fix commit.

The P0 is a deterministic test failure in the new error-path test ("shows tab listing and switching errors"). It blocks CI. The remaining P3s are: a CRF-9 re-raise (keyboard wrap test still doesn't prove wrapping), a poll-during-switch race, a residual CRF-4 gap (error message misleading for success:false without details), array-level Zod validation rejecting all tabs for one bad entry, and an unconditional tabpanel landmark that orphans when the tablist is hidden.

Severity count: 1 P0, 5 P3, 1 Nit, 3 Note.

"I tried to build a case that the author's understanding of the problem is incomplete, that a simpler solution exists, or that the fix is at the wrong level of the causal chain. I couldn't." (Pariston)

🤖 This review was automatically generated with Coder Agents.

Comment thread src/browser/features/RightSidebar/BrowserTab/BrowserTab.test.tsx Outdated
Comment thread src/browser/features/RightSidebar/BrowserTab/BrowserTab.test.tsx
Comment thread src/browser/features/RightSidebar/BrowserTab/BrowserTab.tsx
Comment thread src/node/services/browser/BrowserControlService.ts
Comment thread src/node/services/browser/BrowserControlService.ts Outdated
Comment thread src/browser/features/RightSidebar/BrowserTab/BrowserViewport.tsx Outdated
Comment thread src/node/services/browser/BrowserControlService.test.ts Outdated
Comment thread src/node/orpc/router.ts
Comment thread src/browser/features/RightSidebar/BrowserTab/BrowserTab.test.tsx
Comment thread src/node/services/browser/BrowserControlService.ts Outdated
Copy link
Copy Markdown

@coder-agents-review coder-agents-review Bot left a comment

Choose a reason for hiding this comment

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

CRF-27 (P0, deterministic test failure) was fixed in bc9b776 and CI is now green.

The remaining 9 R2 findings have no author response and no code changes. Further review is blocked until they are addressed, acknowledged, or contested.

Open P3s needing response:

  • CRF-28: Keyboard wrap-around test still doesn't exercise wrapping (re-raise of CRF-9)
  • CRF-29: Poll during slow tab switch overwrites optimistic state (one-line guard fix)
  • CRF-30: Fallback error says "returned invalid JSON" when CLI reported success: false
  • CRF-31: Zod safeParse validates all page tabs as one array; one bad entry rejects all
  • CRF-32: role="tabpanel" renders unconditionally; orphaned landmark when tablist hidden

Open Nit:

  • CRF-33: for loop test hides which case failed

Open Notes (acknowledge or contest):

  • CRF-34: selectTab failure clears preview URL incorrectly
  • CRF-35: Formatting test proves strings exist but not rendering slot
  • CRF-36: Zod validation error details discarded

🤖 This review was automatically generated with Coder Agents.

@ThomasK33
Copy link
Copy Markdown
Member Author

Addressed the latest coder-agents-review round:

  • CRF-27: split the combined listing/switching error test into deterministic tests so switching errors no longer depend on the 2s polling recovery path.
  • CRF-28: added explicit keyboard wrap coverage with a third tab, including ArrowLeft from the first tab and ArrowRight from the last tab.
  • CRF-29: tab-list polling now skips applying list results while a tab switch is pending, avoiding stale active-tab flashes during slow switches.
  • CRF-30: structured agent-browser failures without an error string now surface failed without details instead of the invalid-JSON fallback.
  • CRF-31: page/webview entries are validated individually; malformed page entries are skipped while valid siblings are preserved.
  • CRF-32: the viewport only renders role="tabpanel"/aria-label/aria-controls target id when the page tab strip is present.
  • CRF-33: split the malformed CLI-output loop into named tests.
  • CRF-34: verified no code change is needed: BrowserSessionStateHub.markLoaded(..., undefined, commandToken) preserves entry.state.url for failed commands, so the helper does not clear the current URL on select-tab failure.
  • CRF-35: tightened the formatting assertions to inspect the specific tab buttons' accessible labels and aux text instead of matching text anywhere in the tree.
  • CRF-36: no debug log added for now; after CRF-31, malformed individual tab entries are skipped instead of failing the whole parse, and the user-facing parse errors remain intentionally terse.

Validation after fixes:

  • bun test src/browser/features/RightSidebar/BrowserTab/BrowserTab.test.tsx --filter 'shows tab switching errors'
  • run_and_report browser-preview-tests bun test src/browser/features/RightSidebar/BrowserTab/BrowserTab.test.tsx src/browser/features/RightSidebar/BrowserTab/BrowserViewport.test.tsx src/node/services/browser/BrowserControlService.test.ts
  • run_and_report static-check make static-check

@ThomasK33
Copy link
Copy Markdown
Member Author

@codex review

Latest coder-agents-review findings were addressed and resolved.

@ThomasK33
Copy link
Copy Markdown
Member Author

/coder-agents-review

Latest findings were addressed and resolved; please re-check.

@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".

Copy link
Copy Markdown

@coder-agents-review coder-agents-review Bot left a comment

Choose a reason for hiding this comment

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

All prior findings resolved. CRF-34 closed: 4/4 panel reviewers independently verified the author's defense by tracing BrowserSessionStateHub.markLoaded; the URL is preserved on failed commands, not cleared.

Pariston, for the third time, tried to build a case against the approach and couldn't: "The problem is correctly understood as a missing UI surface. The solution is proportional: it reuses the existing polling pattern, the existing CLI interface, and the existing loading-state infrastructure."

"The code survived the fight." (Hisoka)

Two new P3s and two Notes from this round. Both P3s are test coverage boundary cases, not correctness bugs.

Severity count: 2 P3, 2 Note.


src/browser/features/RightSidebar/BrowserTab/BrowserTab.test.tsx:495

Note [CRF-40] The tab switching error test asserts the error message appears and aria-busy clears, but does not verify that the original tab's aria-selected stays "true" or that the failed target's stays "false". Adding expect(view.getByTestId("browser-page-tab-t1").getAttribute("aria-selected")).toBe("true") after the error check would close the gap. (Chopper)

🤖

🤖 This review was automatically generated with Coder Agents.

Comment thread src/browser/features/RightSidebar/BrowserTab/BrowserTab.test.tsx
Comment thread src/node/services/browser/BrowserControlService.ts
Comment thread src/browser/features/RightSidebar/BrowserTab/BrowserTab.test.tsx
@ThomasK33
Copy link
Copy Markdown
Member Author

@codex review

Pushed deterministic integration-test fixes for the CI failures (removed live GitHub/submodule network dependencies) after reproducing them locally.

@ThomasK33
Copy link
Copy Markdown
Member Author

/coder-agents-review

Pushed deterministic integration-test fixes for the CI failures after reproducing them locally.

@ThomasK33
Copy link
Copy Markdown
Member Author

Addressed the follow-up coder-agents-review round:

  • CRF-37: added a single-tab BrowserTab test that asserts no tablist/tabpanel is rendered at the pageTabs.length === 1 boundary.
  • CRF-38: tab parsing now reports all tab entries failed validation when every page/webview candidate is malformed, while still preserving valid siblings when only some entries are bad.
  • CRF-39: extended the formatting test to assert the common plain-title path via the tab button's accessible label.

Validation after fixes:

  • run_and_report browser-preview-tests bun test src/browser/features/RightSidebar/BrowserTab/BrowserTab.test.tsx src/browser/features/RightSidebar/BrowserTab/BrowserViewport.test.tsx src/node/services/browser/BrowserControlService.test.ts
  • run_and_report execute-bash-git-env env TEST_INTEGRATION=1 bun x jest tests/ipc/runtime/executeBash.test.ts -t 'should set GIT_TERMINAL_PROMPT=0' --runInBand
  • run_and_report remove-submodule-tests env TEST_INTEGRATION=1 bun x jest tests/ipc/workspace/remove.test.ts -t 'Runtime: local.*submodule' --runInBand
  • run_and_report static-check make static-check

@ThomasK33
Copy link
Copy Markdown
Member Author

@codex review

Follow-up coder-agents-review findings were addressed and resolved.

@ThomasK33
Copy link
Copy Markdown
Member Author

/coder-agents-review

Follow-up findings were addressed and resolved; please re-check.

Copy link
Copy Markdown

@coder-agents-review coder-agents-review Bot left a comment

Choose a reason for hiding this comment

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

The R4 findings have no author response and no code changes. The post-R4 commit (79881f0) touches only tests/ipc/ files (CI infrastructure). Further review is blocked until the findings are addressed, acknowledged, or contested.

Open P3s needing response:

  • CRF-37: No test verifies single-tab hides tab strip (CRF-16 boundary untested)
  • CRF-38: All-entries-rejected parse returns empty tabs with no error signal

Open Notes (acknowledge or contest):

  • CRF-39: Formatting test covers uncommon paths; most common plain-title path unasserted
  • CRF-40: Tab switching error test does not verify selection state preserved after failure

🤖 This review was automatically generated with Coder Agents.

@ThomasK33
Copy link
Copy Markdown
Member Author

Follow-up response to the coder-agents-review body from 2026-05-27T12:20:05Z:

  • CRF-37: addressed in 8dd084d67 with a single-tab boundary test asserting no tablist/tabpanel is rendered.
  • CRF-38: addressed in 8dd084d67 by returning all tab entries failed validation when every page/webview candidate is malformed.
  • CRF-39: addressed in 8dd084d67 by asserting the common plain-title label path.
  • CRF-40: addressed in 3cd8567d5 by asserting a failed tab switch preserves the original active/inactive selection state.

Validation:

  • run_and_report browser-preview-tests bun test src/browser/features/RightSidebar/BrowserTab/BrowserTab.test.tsx src/browser/features/RightSidebar/BrowserTab/BrowserViewport.test.tsx src/node/services/browser/BrowserControlService.test.ts
  • run_and_report static-check make static-check

@ThomasK33
Copy link
Copy Markdown
Member Author

@codex review

Addressed the latest coder-agents-review body, including CRF-40.

@ThomasK33
Copy link
Copy Markdown
Member Author

/coder-agents-review

Addressed the latest review body, including CRF-40; please re-check current head.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

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: 3cd8567d5f

ℹ️ 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 tests/ipc/helpers.ts
@ThomasK33
Copy link
Copy Markdown
Member Author

Addressed Codex P2: the local submodule fixture repo now configures user.email, user.name, and commit.gpgsign=false before creating its commit, matching createTempGitRepo().

Validation:

  • run_and_report remove-submodule-tests env TEST_INTEGRATION=1 bun x jest tests/ipc/workspace/remove.test.ts -t 'Runtime: local.*submodule' --runInBand
  • run_and_report lint make lint
  • run_and_report static-check make static-check

@ThomasK33
Copy link
Copy Markdown
Member Author

@codex review

Addressed the submodule fixture author identity issue.

@ThomasK33
Copy link
Copy Markdown
Member Author

/coder-agents-review

Codex's submodule fixture author-identity finding is fixed; please re-check current head.

Copy link
Copy Markdown

@coder-agents-review coder-agents-review Bot left a comment

Choose a reason for hiding this comment

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

All 40 findings resolved across 6 rounds. No new findings from Netero or the panel. CI green.

The PR adds browser page-tab awareness to the Browser Preview panel: ORPC schemas and endpoints for browser.listTabs and browser.selectTab, BrowserControlService CLI integration with defensive parsing, a WAI-ARIA tablist with keyboard navigation and optimistic state management, and a clean runBrowserCommandWithLoadingState refactoring that eliminated loading-state duplication.

"I tried to build a case against this and couldn't. The problem is correctly understood: users need tab awareness, and this PR adds it. The solution is proportional: it follows the existing poll-based discovery pattern, reuses the CLI control architecture, and the UI follows WAI-ARIA tablist conventions." (Pariston)

Ship it.

🤖 This review was automatically generated with Coder Agents.

@ThomasK33
Copy link
Copy Markdown
Member Author

@codex review

All prior Codex comments are resolved and CI is green; please confirm the current head.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

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: 0e935ff310

ℹ️ 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/node/services/browser/BrowserControlService.ts Outdated
@ThomasK33
Copy link
Copy Markdown
Member Author

Addressed Codex P1: removed the unsupported -- separator from agent-browser tab switch invocations and added an explicit guard rejecting flag-like tab refs before spawning the CLI.

Validation:

  • run_and_report browser-preview-tests bun test src/browser/features/RightSidebar/BrowserTab/BrowserTab.test.tsx src/browser/features/RightSidebar/BrowserTab/BrowserViewport.test.tsx src/node/services/browser/BrowserControlService.test.ts
  • run_and_report static-check make static-check

@ThomasK33
Copy link
Copy Markdown
Member Author

@codex review

Addressed the tab command separator issue and added a flag-like tab ref guard.

@ThomasK33
Copy link
Copy Markdown
Member Author

/coder-agents-review

Codex's tab command separator finding is fixed; please re-check current head.

@ThomasK33
Copy link
Copy Markdown
Member Author

@claude review

@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".

@ThomasK33
Copy link
Copy Markdown
Member Author

/coder-agents-review

All prior coder-agents-review findings are resolved, Codex approved, and CI is green. Please confirm current head.

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