Skip to content

fix(web): flush terminal dimensions when panel resizing ends - #15619

Open
maria-rcks wants to merge 1 commit into
pingdotgg:mainfrom
maria-rcks:fix/round2-wide-12058
Open

maria-rcks wants to merge 1 commit into
pingdotgg:mainfrom
maria-rcks:fix/round2-wide-12058

Conversation

@maria-rcks

@maria-rcks maria-rcks commented Oct 4, 2026 •

Copy link
Copy Markdown
Collaborator

problem

Narrowing the right-panel terminal reflows Ghostty immediately, while Bash keeps the previous column count until the 150 ms resize debounce expires. Typing immediately after releasing the divider can overwrite the prompt.

change

Publish a drag-end resize epoch through the existing shared panel sizing path. Visible nested terminals fit the committed width and flush pending PTY dimensions before paint, including split terminals and interrupted drags. Keep the existing observer and mid-drag debounce.

scope and approval

Closes #12058. Follows the accepted panel-width fix scope and adapts the focused implementation from #12068 to V2's shared usePreviewPanelInlineSize path, as requested in the V2 refile comment. #12830 addresses the separate attach/replay sizing path.

verification

  • Blacksmith: 83 focused tests pass across the existing width-hook, Ghostty surface, panel shell, and terminal drawer suites. Coverage includes shrinking/widening, immediate pending-size flush, observer ordering, retained debounce, duplicate suppression, disposal, release/cancellation/lost capture/blur, and thread switches.
  • The changed regression cases fail against the baseline implementation: 11 failures across the two changed existing suites, with real Ghostty WASM loaded.
  • Blacksmith: web typecheck and formatting of all seven changed files pass. Targeted lint has zero errors and the same eight warnings as the baseline. Worker stopped after checks.
  • Unverified: the real Bash/client interaction, local/remote PTY sizing, packaged desktop, and before/after screenshots and recording. Shared-runtime evidence is being coordinated by the parent; native T3 preview currently times out. All eight required CI checks passed at ccfe9049e43e1d2da1c5d151418cc083aa6218eb; Macroscope approved that head. CodeRabbit completed successfully; final independent reviews remain pending.

Implemented by gpt-6.1-sol (xhigh) through the Codex harness in T3 Code, on behalf of Maria.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Oct 4, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at ccfe904

Macroscope's review found this PR approvable — This is a contained web bug fix that flushes existing terminal resize notifications at panel drag completion without changing panel defaults or introducing a new capability. The implementation preserves debouncing and includes focused regression coverage for drag, observer, cancellation, and disposal paths.

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

@coderabbitai

coderabbitai Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

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

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: c0b1b893-5923-4726-b8d5-20dde4f3f9d2
📥 Commits

Reviewing files that changed from the base of the PR and between 4ee6bfd and ccfe904.

📒 Files selected for processing (7)
  • apps/web/src/components/ThreadTerminalDrawer.tsx
  • apps/web/src/components/preview/PreviewPanelShell.tsx
  • apps/web/src/hooks/usePreviewPanelInlineSize.ts
  • apps/web/src/hooks/useResizableWidth.test.tsx
  • apps/web/src/hooks/useResizableWidth.ts
  • apps/web/src/terminal/ghostty/surface.test.ts
  • apps/web/src/terminal/ghostty/surface.ts

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


📝 Walkthrough

Walkthrough

The preview panel now exposes resize completion epochs to its children. The terminal uses these epochs to refit when visible. GhosttyTerminalSurface now supports immediate flushing of pending resize notifications and debounces observer-driven notifications.

Changes

Right-panel terminal resize

Layer / File(s) Summary
Debounced terminal resize reporting
apps/web/src/terminal/ghostty/surface.ts, apps/web/src/terminal/ghostty/surface.test.ts
GhosttyTerminalSurface now debounces resize notifications for 150 ms and provides flushResize() to report pending dimensions immediately. Tests cover drag-end flushing, observer notifications, and disposal.
Propagate panel resize completion
apps/web/src/hooks/useResizableWidth.ts, apps/web/src/hooks/useResizableWidth.test.tsx, apps/web/src/hooks/usePreviewPanelInlineSize.ts, apps/web/src/components/preview/PreviewPanelShell.tsx, apps/web/src/components/ThreadTerminalDrawer.tsx
useResizableWidth exposes a resize epoch that advances when resizing finishes. PreviewPanelShell provides the epoch to its children. When the epoch is nonzero and the terminal is visible, TerminalViewport calls fit() and flushes if fitting reports a change. Tests check epoch values for completed and canceled resizes.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Low

Sequence Diagram(s)

sequenceDiagram
  participant useResizableWidth
  participant PreviewPanelShell
  participant TerminalViewport
  participant GhosttyTerminalSurface
  useResizableWidth->>PreviewPanelShell: resizeEpoch
  PreviewPanelShell->>TerminalViewport: provide resizeEpoch
  TerminalViewport->>GhosttyTerminalSurface: fit and flushResize
  GhosttyTerminalSurface->>TerminalViewport: report current grid dimensions
Loading

Possibly related PRs

  • pingdotgg/t3code#12068: The PR summary describes the same resize-epoch propagation and terminal resize-flush behavior.

Suggested labels: size:M

Suggested reviewers: juliusmarminge, t3dotgg

Merge Risk: ⚪ Minimal · up to ccfe9

The change flushes terminal dimensions when panel resizing ends. No concrete merge-blocking risk was found in the reviewed changes.

Security Architecture Review

Security architecture risk: 🔵 Low · up to ccfe9

The change preserves the existing session-scoped terminal resize path, with no demonstrated increase in privileges or data access. Remaining uncertainty concerns failure recovery and real shell behavior, especially for remote terminals.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The changed trigger can affect visible terminals nested beneath the panel, including split terminals. The inspected flow adds no arbitrary environment or terminal selector; this bounds the demonstrated client-side exposure, without establishing server-side authorization.

Trust Boundaries and Controls

  • observed — The new completion consumer requires a nonzero epoch, an existing surface, and current visibility. Surface fitting additionally rejects hidden, disposed, or zero-sized mounts; flushing rejects disposed surfaces and absent pending notifications.

Hardening Proposals

  • proposed — As separate ownership hardening, bind resize callbacks to the immutable session that created each surface and reject callbacks from retired surfaces. Disposal-time notification through a current-render callback already exists in the base; this is not an established PR-introduced vulnerability.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning [#12058] The drag-end epoch reaches visible terminals, and the surface can flush pending dimensions. However, ThreadTerminalDrawer calls flushResize() only when terminal.fit() reports a change. … After fitting on a visible panel resize epoch, call flushResize() even when fit() reports no grid change. flushResize() already no-ops when there is no pending resize. Add a regression test where the resize observer fits the final gri…
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 7 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Out of Scope Changes check ✅ Passed The shared resize epoch, terminal fit and flush behavior, and related tests support the right-panel terminal resize fix in [#12058]. The reviewed changes show no unrelated behavior.
Title check ✅ Passed The title clearly and concisely describes the primary change: flushing terminal dimensions when panel resizing ends.
Description check ✅ Passed The description covers the problem, change, scope and approval, and verification. It reports specific test results and identifies unverified behavior. It does not include the before-and-after screensh…
Full details: Linked Issues check

Explanation

[#12058] The drag-end epoch reaches visible terminals, and the surface can flush pending dimensions. However, ThreadTerminalDrawer calls flushResize() only when terminal.fit() reports a change. If the resize observer already fitted the final grid during the drag, fit() reports no change and the pending PTY resize remains on the 150 ms debounce. The surface tests call flushResize() directly and do not cover this component-level ordering. This leaves the reported post-drag delay in place for that case.

Resolution

After fitting on a visible panel resize epoch, call flushResize() even when fit() reports no grid change. flushResize() already no-ops when there is no pending resize. Add a regression test where the resize observer fits the final grid before the panel drag-end epoch, and verify that the PTY receives the dimensions before paint.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@maria-rcks

Copy link
Copy Markdown
Collaborator Author

Note

Written by gpt-6.1-sol on behalf of Maria

the linked-issue warning misreads the return value of fit(). it returns true for every successful visible fit, including when the grid is unchanged; it returns false only for disposed, hidden, or zero-sized surfaces. see surface.ts at the reviewed head. therefore the component guard still flushes when the observer has already fitted the final grid, while retaining the zero-size guard.

the existing observer-ordering regression exercises observer fit, same-grid refit, and immediate pending-size flush without advancing the debounce timer. no code change is needed for this warning. the new flush method, epoch, and context already have explanatory comments; broader docstring additions would be outside this focused fix.

This branch has not been deployed

No deployments
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:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Right-panel terminal does not re-fit on resize - cursor lands in the wrong column and typed text draws over the prompt

1 participant