Skip to content

fix(web): default-branch confirmation keeps its copy while closing - #13921

Closed
otavio wants to merge 2 commits into
pingdotgg:mainfrom
OSSystems:fix/reproduce-issue-13831
Closed

otavio wants to merge 2 commits into
pingdotgg:mainfrom
OSSystems:fix/reproduce-issue-13831

Conversation

@otavio

@otavio otavio commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

What Changed

The default-branch confirmation ("Commit & push to default ref?") now tracks its open state separately from the pending action. The pending action is cleared in onOpenChangeComplete(false), after the exit transition, instead of in the same render that closes the dialog.

A preceding refactor commit merges the "Continue" and "Check out feature branch & continue" handlers, which differed only by the featureBranch flag, so the dialog has a single close path. That handler now checks the open flag, so a click during the exit transition cannot run the action twice.

Why

Fixes #13831. open was derived from pendingDefaultBranchAction !== null, so Abort, the close button, Escape, and both continue buttons nulled the payload while the popup was still mounted for its 200ms exit transition. The title, description, and primary label fell back to "Run action on default branch?", nothing, and "Continue", and the dialog visibly shrank before it faded.

This matches the pattern RelayClientInstallDialog and ConfirmDialogHost already use. Base UI aborts the pending completion callback when open flips back, so reopening mid-exit cannot clear a fresh payload.

Reproduced in a throwaway jsdom harness with the real Dialog and a held exit animation: before the fix the mounted popup showed the fallback title during exit; after it, the original copy stays until unmount. Web and desktop share this UI; the mobile confirm sheet is a separate route and is unaffected.

UI Changes

Recorded in the web client against current main (5cc99e1); the fix rebases onto it cleanly. Synthetic repo on main with a remote. Each video shows Abort at real speed, then Abort, "Commit & push to main", and "Check out feature branch & continue" with animations slowed to 10% through DevTools (Animation.setPlaybackRate) so the 200ms exit is visible.

Before: every close path swaps the copy to "Run action on default branch?" with no description and a "Continue" label, and the dialog shrinks while it fades.

before

After: the title, description, and both continue labels stay until the dialog is gone.

after

Real-speed Abort, 33ms per frame from the click:

Before After
before frames after frames

MP4: before · after

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Made with Claude Opus 5.5 in Claude Code (via T3 Code).

Summary by CodeRabbit

  • Bug Fixes
    • Improved default-branch confirmation behavior so pending actions continue correctly after the dialog closes, whether staying on the current branch or switching to a feature branch.
    • Aborting the confirmation now closes the dialog and clears the pending action after the exit transition.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Sep 27, 2026
@coderabbitai

coderabbitai Bot commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

⚙️ Run configuration

Configuration used: Repository: pingdotgg/t3code/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 434748d2-2b42-4961-94e7-4bfb47a86320

📥 Commits

Reviewing files that changed from the base of the PR and between 43c9a8a and b35127f.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: pingdotgg/t3code/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 677c40b0-4e6b-4ab8-ac56-84bf1911b262

📥 Commits

Reviewing files that changed from the base of the PR and between ab09917 and afa266d.

📒 Files selected for processing (1)
  • apps/web/src/components/GitActionsControl.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.


📝 Walkthrough

Walkthrough

The default-branch confirmation dialog now tracks its open state separately from its pending action. Abort and continuation close the dialog without immediately clearing pending data. The pending action is cleared when the exit transition completes.

Changes

Default-branch confirmation

Layer / File(s) Summary
Dialog state and actions
apps/web/src/components/GitActionsControl.tsx
The dialog uses separate open and pending-action state. Both continuation choices use one handler, and the pending action remains available until the dialog’s close transition completes.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Low

Suggested reviewers: juliusmarminge

Merge Risk: ⚪ Minimal · up to afa26

No actionable merge-blocking issue remains in the changed confirmation flow.

Security Architecture Review

Security architecture risk: 🔵 Low · up to afa26

The confirmation remains required before the affected Git actions proceed, and no new action path or authority was identified. Some confidence depends on how the dialog handles reopening during its close transition.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The inspected change affects the local UI confirmation for Git actions, not a demonstrated new service, tenant, credential, or deployment boundary. Backend authorization was outside the available evidence.

Trust Boundaries and Controls

  • observed — Closing or aborting does not invoke the Git action. The confirmed dispatch is restricted to the continuation handler while both dialog-open state and a pending payload are present.

Resilience and Maintainability Implications

  • inferred — A stale close-completion callback could clear a newer pending payload if the dialog primitive did not cancel it on reopening. Available documentation reported in prior inspection supports cancellation, and no dispatch from cleanup was found; dependency implementation and re-entrant event timing remain unverified.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 1 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the primary change: preserving the default-branch confirmation dialog copy during its closing transition.
Description check ✅ Passed The description clearly explains what changed, why it changed, the affected behavior, and the linked issue. The UI evidence is incomplete because the promised recording and required interaction video …
Linked Issues check ✅ Passed Issue [#13831] requires the default-branch confirmation content to remain unchanged until the dialog closes. The PR separates isDefaultBranchDialogOpen from pendingDefaultBranchAction, keeps the p…
Out of Scope Changes check ✅ Passed The reviewed diff changes only GitActionsControl.tsx. Each change supports issue [#13831]: it preserves dialog state during dismissal, consolidates the continuation handlers, and prevents duplicate …
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Comment @coderabbitai help to get the list of available commands.

@otavio

otavio commented Sep 27, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai Two notes on the review:

  • Reopen during close: verified in @base-ui/react@1.5.0 (esm/internals/useOpenChangeComplete.js). The completion wait runs in an effect keyed on open and is aborted in its cleanup, so flipping open back to true cancels the pending onOpenChangeComplete(false) and cannot clear a newer payload.
  • Docstring coverage: not applicable. The touched function is a component-local event handler, and this codebase doesn't document those with docstrings.

@macroscopeapp

macroscopeapp Bot commented Sep 27, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at afa266d

Macroscope's review found this PR approvable — This is a small, self-contained UI bug fix that preserves the pending Git action and its copy through the dialog exit animation while retaining existing continuation behavior. It touches no sensitive, schema, deployment, or static-analysis configuration areas.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Sep 27, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
ast-grep outline apps/web/src/components/GitActionsControl.tsx --match 'GitActionsControl|defaultBranch|continue' --view expanded | head -140
rg -n -C4 'onOpenChangeComplete|defaultBranch|featureBranch|handleContinue|@base-ui/react' apps/web/src/components/GitActionsControl.tsx | tail -220
rg -n -C2 '"@base-ui/react"|@base-ui/react@1\.5\.0' -g 'package.json' -g '*lock*' | head -90
gh api repos/pingdotgg/t3code/pulls/13921/comments --jq '.[] | select(.user.login=="coderabbitai" or (.body|test("docstring|reopen|Reopen|close|completion";"i"))) | {id,body,path,line,html_url}' | head -180

Length of output: 5677


🏁 Script executed:

#!/bin/bash
set -euo pipefail
fd -i 'dialog*' apps/web/src/components | head -35
rg -n -C5 'onOpenChangeComplete|DialogRoot|Root as Dialog' apps/web/src/components/ui -g '*.tsx' | head -130
sed -n '1170,1195p;1240,1265p;1455,1480p;2010,2045p' apps/web/src/components/GitActionsControl.tsx
printf '\nUpstream Base UI source:\n'
curl -fsSL --max-time 15 'https://unpkg.com/@base-ui/react@1.5.0/esm/internals/useOpenChangeComplete.js' | head -160

Length of output: 2351


🏁 Script executed:

#!/bin/bash
ast-grep outline apps/web/src/components/ui/dialog.tsx --view expanded | head -100
sed -n '1170,1195p;1240,1265p;1455,1480p;2010,2045p' apps/web/src/components/GitActionsControl.tsx
sed -n '1,130p' apps/web/src/components/ui/dialog.tsx
printf '\nUpstream Base UI source:\n'
curl -fsSL --max-time 15 'https://unpkg.com/@base-ui/react@1.5.0/esm/internals/useOpenChangeComplete.js' | head -160

Length of output: 9904


@otavio, thanks for the details. I checked the resolved @base-ui/react@1.5.0 version and its useOpenChangeComplete source. When open changes, the effect cleanup aborts the pending completion wait. The dialog also uses DialogPrimitive.Root directly. I withdraw the reopen-during-close concern.

I also withdraw the docstring request. The changed function is a component-local event handler, and your clarification about this codebase’s docstring convention applies here.


✏️ Learnings added
Learnt from: otavio
URL: https://github.com/pingdotgg/t3code/pull/13921

Timestamp: 2026-09-27T05:37:59.548Z
Learning: In `pingdotgg/t3code`, `apps/web/src/components/GitActionsControl.tsx` uses `base-ui/react1.5.0` for the default-branch confirmation dialog. Base UI's `useOpenChangeComplete` effect aborts its pending animation-completion wait during cleanup when `open` changes, so reopening cancels the pending close-completion callback.

Learnt from: otavio
URL: https://github.com/pingdotgg/t3code/pull/13921

Timestamp: 2026-09-27T05:37:59.548Z
Learning: In `pingdotgg/t3code`, component-local event handlers such as `continuePendingDefaultBranchAction` in `apps/web/src/components/GitActionsControl.tsx` do not require docstrings under the codebase's convention.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

@otavio
otavio force-pushed the fix/reproduce-issue-13831 branch from afa266d to 58a93f2 Compare September 30, 2026 18:08
"Continue" and "Check out feature branch & continue" duplicated the same
body and differed only in the featureBranch flag. Fold them into one
handler that takes the flag, so the confirmation has a single exit path
for running the pending action.
@otavio
otavio force-pushed the fix/reproduce-issue-13831 branch from 58a93f2 to 43c9a8a Compare September 30, 2026 18:20
The dialog's open state was derived from the pending action payload, so
dismissing it nulled the payload in the same render. The popup stayed
mounted for its 200ms exit transition with fallback copy ("Run action on
default branch?", no description, "Continue"), visibly shrinking before
it faded.

Track the open flag separately and clear the payload in
onOpenChangeComplete(false), matching RelayClientInstallDialog and
ConfirmDialogHost. The continue handler now checks the open flag so a
click during the exit transition cannot run the action twice.

Fixes pingdotgg#13831
@otavio
otavio force-pushed the fix/reproduce-issue-13831 branch from 43c9a8a to b35127f Compare September 30, 2026 18:27

Copy link
Copy Markdown
Member

Note

This comment is posted by Julius' dot

The PR still promises a before/after recording, but none is supplied. A jsdom check doesn't demonstrate the visible 200ms closing transition. Closing under the verification rule. Add current-client before/after evidence showing dismissal and both continue actions keeping their copy until the dialog disappears, then request reconsideration.

@otavio

otavio commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

@juliusmarminge Thanks. I added current-client before/after evidence to the description.

It was recorded in the web client against current main (5cc99e1), with the fix applied on top (it rebases cleanly). It covers Abort at real speed, then Abort, "Commit & push to main", and "Check out feature branch & continue" with animations slowed to 10% via DevTools so the 200ms exit is easy to see.

Before After
before after

Before, all three paths drop to "Run action on default branch?" with no description and a "Continue" label, and the dialog shrinks as it fades. After, the original title, description, and labels stay until the dialog is gone. The real-speed frame strips (33ms apart) in the description show the same thing without the slowdown.

MP4: before · after

Could you take another look and reopen if it holds up?

@otavio

otavio commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #16907: the same fix rebased onto current main (f570bd2), with fresh before/after evidence for all five exit paths and per-frame measurements of the dialog content during the exit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Default-ref confirmation changes content while closing

2 participants