Repository navigation
fix(web): focus the primary action when confirmation dialogs open - #18187
Conversation
Dialogs focused Cancel on open, so pressing Enter cancelled even though Confirm is the highlighted action. Popups now focus the AlertDialogAction or DialogAction when they open, so Enter and Space confirm and Tab reaches Cancel, with native button semantics. Destructive actions aren't marked, so those dialogs keep focus on Cancel. Touch opens still focus the popup. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ApprovabilityVerdict: Needs Human Approval Macroscope's review found this PR requires human approval — Existing update, installation, and import dialogs now initially focus their primary action, changing the default keyboard interaction. Human review is required to accept that default change, including for update confirmations that close and relaunch applications. You can add or adjust custom eligibility rules. Learn more. |
Dismissing prior approval to re-evaluate 894463f
|
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
ConfirmDialogHost serves every requestConfirmDialog and dialogs.confirm caller, so focusing Confirm there also made Enter approve MCP tool requests, roll back checkpoints and sign out providers. The host now keeps Cancel focused unless the caller passes initialFocus: "confirm", and only the desktop and server update prompts do. DialogAction now rejects destructive Button variants at compile time instead of matching the variant name, which missed ghost-destructive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dismissing prior approval to re-evaluate 6f46e56
|
Re CodeRabbit's security note: good catch. |
|
@coderabbitai run pre-merge checks |
✅ Actions performedRunning Pre-merge checks. Results will be posted in the summary comment once complete. |
|
Taking over this one. I’ll rebuild on current main, trim the tests to meaningful focus behavior, and push to this branch while keeping generic and destructive confirmations Cancel-first. |
# Conflicts: # apps/web/src/components/ServerUpdateAction.browser.test.tsx
# Conflicts: # apps/web/src/components/LegacySidebar.tsx # apps/web/src/components/ServerUpdateAction.browser.test.tsx # apps/web/src/components/ui/alert-dialog.tsx # apps/web/src/components/ui/dialog.tsx # apps/web/src/confirmDialog.test.ts
AI-assisted; verified with the tests and tools listed above.
EvidenceLinux Electron, light theme, 1280×900, fresh isolated state on each commit. Settings → About → Install, opened by mouse and keyboard; press Enter or Space without changing dialog focus. Then Settings → General → change In-app notifications → Restore device defaults → Enter. The update action resides under About on both commits, rather than General as stated in the supplied reproduction. A synthetic downloaded update was supplied through Electron IPC. Install requests were counted; the fixture then reported Up to Date. No release was downloaded or installed.
The destructive control canceled and preserved the changed setting on both commits. Driver and IPC seed · Before observations · After observations · Redacted diagnostics AI-assisted; verified with the tests and tools listed above. Not shown:
|
**v0.1.10-nightly.20261111.4529** · 54 changes from 29 contributors - **Find in browser.** Search pages in the desktop integrated browser with Cmd+F or Ctrl+F. - **GitLab overview threads.** Resolve merge request overview threads from Summary and Timeline. - **Faster worktree updates.** Checkpoint captures and status refreshes avoid rereading every file in newly created worktrees. - **Imported session history.** Imported agent sessions now show their existing history instead of opening as empty threads. - **SSH reconnect prompts.** Expired SSH verification prompts no longer stack up and force an app restart. - **Large reasoning traces.** Opening a thread with a large collapsed reasoning trace no longer freezes the app. - **Terminal scrollback.** Terminal history retains substantially more output instead of silently discarding older lines. ### Plus 45 more bug fixes and performance improvements. <details> <summary>Full changelog</summary> ## What's Changed * fix(server): new worktrees refresh their index once, so captures and status stop re-hashing every file by @josephv123 in pingdotgg/t3code#21341 * fix(usage): Grok and Cursor usage limits show pace and the even-spend line by @wookiist in pingdotgg/t3code#21897 * fix(web): retain diff selection across navigation by @aleo113 in pingdotgg/t3code#22347 * fix(mobile): subscription widget no longer expires on a window that already reset by @juliusmarminge in pingdotgg/t3code#22993 * fix(opencode): verify CLI updates when loopback server is still running by @intrepid37 in pingdotgg/t3code#22839 * fix(usage): Claude subagent output is no longer undercounted by @rfrost-xyz in pingdotgg/t3code#20276 * fix(server): a remote update points the service unit at the runtime it committed by @Marve10s in pingdotgg/t3code#19652 * fix(server): a limited provider's queue stays held after another provider's turn succeeds by @Marve10s in pingdotgg/t3code#22425 * fix(shared): keep spreadsheet shorthand as inline code by @juliusmarminge in pingdotgg/t3code#23203 * fix(web): offer retry while an environment reconnects by @juliusmarminge in pingdotgg/t3code#23194 * fix(server): custom Codex providers no longer report native quota by @fixfon in pingdotgg/t3code#18622 * fix(desktop): Cmd+F now searches the page in the integrated browser by @armanarutiunov in pingdotgg/t3code#22960 * fix(desktop): an SSH password prompt that ended leaves the dialog instead of stacking by @Umais-Adeed in pingdotgg/t3code#34192 * fix(web): render Claude insight blocks as a callout by @macodev00 in pingdotgg/t3code#22239 * fix(scheduler): show short server timezone on fixed-time labels by @shawk08033 in pingdotgg/t3code#23111 * fix(web): focus the primary action when confirmation dialogs open by @rgrvlsk in pingdotgg/t3code#18187 * fix(web): Changes row matches the diff comparison by @whoisaldo in pingdotgg/t3code#19553 * fix(server): imported ACP sessions show their native history by @only21mil in pingdotgg/t3code#22155 * fix(preview): always return evaluated results by value by @juliusmarminge in pingdotgg/t3code#22948 * fix(provider-core): a model reply of "title" no longer replaces the thread title by @juliusmarminge in pingdotgg/t3code#25743 * fix(desktop,web): Open in runs locally for a background service sharing the desktop's T3 home by @KinanLak in pingdotgg/t3code#21661 * fix(web): question answers submit while normal sends are blocked by @t3dotgg in pingdotgg/t3code#22874 * fix(server): cancelling a background-only delegated task reports it interrupted by @only21mil in pingdotgg/t3code#21676 * fix(web): fall back to a readable server for shared repositories by @sanjaibalajee in pingdotgg/t3code#21530 * fix(web): composer follows an optionless thread instead of the settings default by @f4llenz in pingdotgg/t3code#16546 * fix(web): don't save retention age until committed by @macodev00 in pingdotgg/t3code#22208 * fix(server): one dropped probe no longer lists a live linked peer as unreachable by @juliusmarminge in pingdotgg/t3code#34208 * fix(server): preview automation reports ambiguous selectors instead of calling them invalid by @juliusmarminge in pingdotgg/t3code#34205 * fix(opencode): a context overflow that OpenCode compacts no longer fails the turn by @juliusmarminge in pingdotgg/t3code#26743 * fix(web): Ctrl + "+" zooms on keyboard layouts with a dedicated plus key by @juliusmarminge in pingdotgg/t3code#26408 * fix(ci): release version bump push retries when main moves by @t3dotgg in pingdotgg/t3code#34326 * fix(server): CLI commands no longer migrate the database of a running server by @juliusmarminge in pingdotgg/t3code#26763 * fix(web): keep saved default model when changing effort by @macodev00 in pingdotgg/t3code#22193 * fix(web): reveal expanded work rows hidden behind the composer by @ln-bodicherla in pingdotgg/t3code#21968 * fix(composer): steer instead of queueing during automatic compaction by @NikitaMGrimm in pingdotgg/t3code#24138 * feat(gitlab): resolve overview threads from Summary and Timeline by @TonybynMp4 in pingdotgg/t3code#30575 * fix(web): pull request search keeps partial-word matches after GitHub answers by @juliusmarminge in pingdotgg/t3code#26992 * fix(server): Claude subagents no longer show the parent's effort by @juansuaya17 in pingdotgg/t3code#17042 * fix(server): runs cancelled by a server restart say why in the thread by @juliusmarminge in pingdotgg/t3code#27192 * fix(client-runtime): server updates stop waiting 32 minutes when the host returns without this update's outcome by @juliusmarminge in pingdotgg/t3code#27275 * fix(web): Stop shows a pending state and repeat clicks no longer resume by @voida6 in pingdotgg/t3code#20809 * fix(web): collapsed reasoning previews no longer process the whole block by @juliusmarminge in pingdotgg/t3code#23001 * fix(server): storage cleanup skips stale worktree paths under a regular file by @juliusmarminge in pingdotgg/t3code#26594 * fix(terminal): use a byte budget for Ghostty scrollback by @zero-two-rafaeltab in pingdotgg/t3code#8766 * fix(server): storage cleanup keeps worktrees whose file listing exceeds the inspection limit by @juliusmarminge in pingdotgg/t3code#26593 * fix(server): delete temporary ACP health probe sessions by @juliusmarminge in pingdotgg/t3code#25397 * perf(client): streamed text no longer republishes thread queue and checkpoints by @juliusmarminge in pingdotgg/t3code#27425 * fix(web): convert composer list markers completed later by @juliusmarminge in pingdotgg/t3code#22997 * test: remove tests that repeat another case or restate the source by @shivamhwp in pingdotgg/t3code#34170 * fix(server): drop stale queued pull-request watch wakes by @Sinan53x in pingdotgg/t3code#21239 * fix(web): preview recordings stay decodable after a viewport resize by @MansTomb in pingdotgg/t3code#10495 * fix(server): only offer claude update for native Claude installs by @AI091 in pingdotgg/t3code#14170 * fix(server): tell outside agents which MCP tools need a thread and that t3_thread_list takes allProjects by @juliusmarminge in pingdotgg/t3code#26525 ## New Contributors * @wookiist made their first contribution in pingdotgg/t3code#21897 * @aleo113 made their first contribution in pingdotgg/t3code#22347 * @intrepid37 made their first contribution in pingdotgg/t3code#22839 * @rfrost-xyz made their first contribution in pingdotgg/t3code#20276 * @armanarutiunov made their first contribution in pingdotgg/t3code#22960 * @KinanLak made their first contribution in pingdotgg/t3code#21661 * @sanjaibalajee made their first contribution in pingdotgg/t3code#21530 * @ln-bodicherla made their first contribution in pingdotgg/t3code#21968 * @juansuaya17 made their first contribution in pingdotgg/t3code#17042 * @zero-two-rafaeltab made their first contribution in pingdotgg/t3code#8766 * @MansTomb made their first contribution in pingdotgg/t3code#10495 * @AI091 made their first contribution in pingdotgg/t3code#14170 **Full Changelog**: pingdotgg/t3code@v0.1.9-nightly.20261111.4515...v0.1.10-nightly.20261111.4529 </details> Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.1.10-nightly.20261111.4529
…ngdotgg#18187) Co-authored-by: Roger Vilaseca <roger@tres65.es> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Julius Marminge <julius0216@outlook.com> (cherry picked from commit 4382138)




Selected update and install confirmation dialogs focus Cancel even though the primary action is visually emphasized. Pressing Enter therefore cancels. This change lets those prompts opt into primary-action focus while keeping generic and destructive confirmations Cancel-first.
A shared DialogAction marker selects the enabled primary button on popup open. Explicit caller focus wins, caller refs remain composed, and touch opening retains popup focus. Desktop update prompts in Settings, current and legacy sidebars, and remote single/batch update actions opt in. Relay install and browser-import quit/retry screens use the same marker. The broad Update everything dialog keeps its existing behavior.
Based on @rgrvlsk’s original contribution. Contributor history is preserved; main was merged and the implementation rebuilt against current primitives. The rebuild fixes caller refs overriding the internal focus ref and removes redundant comments and runtime variant bookkeeping.
Verification for rebuilt head 0c37cce149:
The screenshots use the same synthetic app data, 1280×800 viewport, dialog text, and Liberation Sans fallback font. Baseline web focus code matches main ab6be13d43; head is 0c37cce149. The live coordinator was invoked with the real update message/options; no real updates, relay installation, cookie import, or tool approval ran.
Head recording: Enter confirms the opted-in update, cancels generic approval, and cancels destructive confirmation
Not verified: packaged Electron desktop, actual update execution from Settings/sidebar or remote batch, macOS, Windows, physical touch/soft keyboards, screen readers, iOS, or Android. Mobile uses its separate native dialogs. Synthetic Chromium touch tests verify popup focus; they do not verify OS keyboard behavior.
Implementation: Codex GPT-6.1 Sol; tests: Codex GPT-6 Astra; reviews: Claude Opus 5.5 and Codex GPT-6 Sol. Harness: T3 Code through Codex.
Fixes #18167