fix(desktop): a server restart no longer reopens a closed window on macOS#24102
Problem
On macOS, T3 Code keeps running in the Dock after you close its window with Cmd+W. If the local server then exits unexpectedly (crash, OOM, kill), it restarts automatically. When it becomes ready again, a new main window opens and takes focus from whatever app is in front. The cause is that backend readiness is reported after every restart, not only at launch, and handleBackendReady creates a main window whenever none exists. Expected: a window the user closed stays closed until they ask for it.
Reproduction steps and the code path are in #24101.
Change
DesktopWindow now tracks whether the main window was closed:
- The main window's
closedhandler sets the flag. activateclears it. This covers Dock clicks, launching the app again, and the menu paths that callactivate.handleBackendReadystill marks the backend ready, but skips window creation while the flag is set.
Effects:
- First launch: the first readiness still opens the window. The flag starts false.
- Startup retries: if the server fails before it is ever ready and then retries, it still opens the window when it finally becomes ready.
- Local environment disabled: this boot path never goes through
handleBackendReady, so it is unchanged. - Dock click during a restart: the click clears the flag, so the window opens as soon as the server is back. Before this change that worked only because every readiness opened a window.
- Windows and Linux: closing the last window quits the app there, so nothing changes in practice.
Scope and approval
Fixes #24101
This is one bug in one module, apps/desktop/src/window/DesktopWindow.ts, plus focused tests. It restores the behavior the suite already expects for closed windows: see does not reopen a closed main window for a completed capture.
Verification
New tests in the existing apps/desktop/src/window/DesktopWindow.test.ts, using its layerTest harness and it.effect:
keeps a closed main window closed when the backend restarts. The test drives backend ready (one window, checking that the first launch still opens it), then fires the window'sclosedevent, thenhandleBackendNotReadyandhandleBackendReadyagain. It asserts that no second window is created and nothing is revealed. A finalactivate(Dock click) must then open a window.opens the main window when the backend returns after activation during a restart. The test drives ready, closed, not-ready, thenactivatewhile the server is down (no window yet), then ready. It asserts that the window opens.
Fail before, pass after:
| 1 | # DesktopWindow.ts from upstream/main, new tests in place |
| 2 | $ cd apps/desktop && vp test run src/window/DesktopWindow.test.ts |
| 3 | FAIL src/window/DesktopWindow.test.ts > DesktopWindow > keeps a closed main window closed when the backend restarts |
| 4 | AssertionError: expected 2 to equal 1 |
| 5 | Tests 1 failed | 21 passed (22) |
| 6 | |
| 7 | # with this change |
| 8 | $ cd apps/desktop && vp test run src/window/DesktopWindow.test.ts |
| 9 | Tests 22 passed (22) |
The second test also passes on main. It guards the Dock-click-during-restart case so the fix doesn't regress it.
vp run check:changed upstream/main: format, lint, knip, typecheck (2 packages), and test (1 file) all pass.
Not checked: I did not run a packaged macOS build or kill a real server process to see the window stay closed. The behavior is verified only through the unit tests above.
Implemented with Claude Opus 5.5 via Claude Code (running in T3 Code).
🤖 Generated with Claude Code
Fixes pingdotgg/t3code#24101
Checks
Added 1 commit
- fix(desktop): a server restart no longer reopens a closed window on macOSca6ce99
Approvability
Verdict: Approved at ca6ce99
Macroscope's review found this PR approvable — This is a localized macOS window-lifecycle bug fix that prevents backend readiness from recreating a window the user explicitly closed, while preserving reopening through activation. It includes focused tests for both the closed-window and explicit-activation paths.
You can add or adjust custom eligibility rules. Learn more.
No actionable comments were generated in the recent review.
Walkthrough
-
DesktopWindowrecords when the main window closes. Backend readiness does not recreate it while that state remains set. Activation clears the state, and tests cover backend restarts and activation while the backend is unavailable.Changes: Main window lifecycle
Layer / File(s) Summary Track closed state across activation and backend readiness
apps/desktop/src/window/DesktopWindow.ts,apps/desktop/src/window/DesktopWindow.test.tsDesktopWindowrecords window closure, skips creation on backend readiness while closed, and clears the closed state on activation. Tests cover backend restart after closure and activation while the backend is unavailable.Estimated code review effort: 2 (Simple) | ~10 minutes
Change: Bug fix · Severity of issue fixed: Low
Suggested reviewers:
juliusmarminge
Merge Risk: External image Minimal · up to ca6ce
-
The reviewed lifecycle paths preserve reopening after an explicit action. No actionable issue remains before merge.
Pre-merge checks: Passed 4
-
Check name Status Explanation Title check Passed The title clearly and concisely describes the primary fix: preventing a server restart from reopening a closed desktop window on macOS. Linked Issues check Passed Issue [ #24101] requires a closed macOS main window to remain closed when backend readiness fires after a restart, and to reopen after explicit activation. The supplied PR evidence shows `mainWindowClo…Out of Scope Changes check Passed The supplied change summary shows changes only in apps/desktop/src/window/DesktopWindow.tsand its focused test file. The production change directly implements [#24101]. The tests verify the require…Description check Passed The description covers the problem, change, scope and approval, and verification. It links the reported issue, explains the focused scope, lists test results, and states what was not checked. Full details: Linked Issues check
-
Explanation
Issue [
#24101] requires a closed macOS main window to remain closed when backend readiness fires after a restart, and to reopen after explicit activation. The supplied PR evidence showsmainWindowClosedRef, aclosedhandler, activation clearing, and readiness skipping creation while the flag is set. The two focused tests cover restart suppression and activation during restart. The reported test run passes 22 tests.
Full details: Out of Scope Changes check
-
Explanation
The supplied change summary shows changes only in
apps/desktop/src/window/DesktopWindow.tsand its focused test file. The production change directly implements [#24101]. The tests verify the required behavior and regression cases. No unrelated change is demonstrated.
-
Finishing Touches
-
🧪 Generate unit tests (beta)
-
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
ℹ️ Recent review info
-
⚙️ Run configuration
-
- Source mode: Auto
- Repository: pingdotgg/t3code
- Branch: main
- File: .coderabbit.config.ts
- Commit: c58d558
- Layers: Repository TS config
- Review profile: CHILL
- Plan: Advanced
- Run ID:
5a26abd4-1bb6-4662-bed2-beab038aede7
📥 Commits
-
Reviewing files that changed from the base of the PR and between c58d558e10e3fb238afc62746a857c6bfa764296 and ca6ce99c5378bc13621b7dcdc08e4a5cc0568f5a.
📒 Files selected for processing: 2
-
apps/desktop/src/window/DesktopWindow.test.tsapps/desktop/src/window/DesktopWindow.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.
ℹ️ Recent review info
-
⚙️ Run configuration
-
- Source mode: Auto
- Repository: pingdotgg/t3code
- Branch: main
- File: .coderabbit.config.ts
- Commit: c58d558
- Layers: Repository TS config
- Review profile: CHILL
- Plan: Advanced
- Run ID:
5a26abd4-1bb6-4662-bed2-beab038aede7
📥 Commits
-
Reviewing files that changed from the base of the PR and between c58d558e10e3fb238afc62746a857c6bfa764296 and ca6ce99c5378bc13621b7dcdc08e4a5cc0568f5a.
📒 Files selected for processing: 2
-
apps/desktop/src/window/DesktopWindow.test.tsapps/desktop/src/window/DesktopWindow.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.
-
This PR conflicts with main. Rebase it or merge main into it. If it still conflicts after 7 days with no activity, it will be closed automatically.
See the conflict window.