Don't apply the worktree default when resuming a session - #31
Conversation
JeanBaptisteRenard
left a comment
There was a problem hiding this comment.
Thanks @ymajoros! Good diagnosis — resolveDefaultSessionOptions() was indeed designed for new-session creation, and the global worktree: true default leaking into resume is exactly what broke the plain sidebar click. The fix works for that path.
Test suite passes locally on your branch: 101/101 pass.
One gap before merge:
The schedule-creator resume path has the same bug (required)
launchScheduleCreator in public/dialogs.js also calls resolveDefaultSessionOptions(project) (line 33) and then passes the result unstripped to window.api.openTerminal(result.sessionId, project.projectPath, false, options) (line 68) — isNew=false, so it's a resume, and main.js appends the worktree flag without checking isNew (the guard at ~1465 only switches the command form). So "Create scheduled task" still hits the worktree-on-resume bug; your fix in app.js (openSession) is never reached on that path.
Suggestion: rather than deleting the keys at each resume call site, strip them once in a shared helper (e.g. a resolveResumeSessionOptions() next to resolveDefaultSessionOptions()), or have main.js ignore the worktree option when isNew === false — that closes every current and future resume path at the source.
Minor
delete resumeOptions.worktreemutates the caller'scustomOptionsin place. No current caller is harmed, but a shallow copy ({ ...customOptions }) is safer against future reuse.- No test — the jsdom harness under
test/(seetest/dom-setup.js) makes this unit-testable: assert thatopenTerminalis called withoutworktreewhen resuming. Would make a nice regression guard, especially if you go the shared-helper route.
Verdict: request changes — only for the dialogs.js path. Thanks again for the three PRs, much appreciated! 🙏
5d90f28 to
2f56c4e
Compare
--worktree creates a fresh isolated git worktree, which only makes sense when STARTING a session. On resume (isNew === false) it makes claude try to spin up a new worktree and fail to attach — so a plain sidebar click, and equally the "Create scheduled task" flow (launchScheduleCreator also resumes via openTerminal with isNew=false), silently broke. Rather than stripping the option at each renderer call site, gate it in the open-terminal handler: only append --worktree when isNew. That closes every current and future resume path in one place, and avoids mutating the caller's options object.
2f56c4e to
5384778
Compare
|
Thanks! Reworked per your suggestion — force-pushed (also rebased onto current Moved the fix to the source: the On the test: with the logic now in the main-process command-building (not the renderer), the jsdom harness doesn't reach it, and there's no clean unit seam without spawning a PTY — so I left it out. Happy to add one if you'd prefer a specific approach. |
JeanBaptisteRenard
left a comment
There was a problem hiding this comment.
Re-reviewed the rework — fixing it at the source is exactly right, and the execution is clean:
- ✅
isNew && sessionOptions.worktreeguard covers every resume path in one place (sidebar click, schedule creator, fork, future callers) — verified all fouropenTerminalcall sites - ✅ Resume of a session originally created in a worktree is unaffected: the PTY cwd always comes from the stored
projectPath, the flag only ever mattered at creation - ✅ The app.js delete-hack is gone — nice and minimal now
On the no-test question: I checked the fork's conventions — main.js exports nothing and no IPC handler has a runtime unit test (existing tests treat it as static text only), so requiring one here would exceed the local bar. Fine as-is.
Local run: 119/119 tests pass, CI green on Node 20/22.
Merging — thanks for the rework and for PR #30's honest self-close, much appreciated! 🙏
Problem
A plain click on a session in the sidebar does nothing — no terminal appears, the session stays "inactive" — yet Resume with config works. So a session can only be interacted with through the config dialog.
Cause
openSession()resumes withresolveDefaultSessionOptions(), which is shared with new-session creation and includes the globalworktree: truedefault. Resuming an existing session with--worktreetries to spin it up in a fresh git worktree and fails to attach, so the terminal never shows.showResumeSessionDialog()has no worktree control and never sets the flag — which is exactly why "Resume with config" works. Plain click and the dialog should behave the same.Fix
Strip
worktree/worktreeNamefrom the resolved options on the resume path inopenSession():New-session creation is untouched (still honors the worktree default). Worktree is a new-session concept — resuming must reuse the session's existing directory.
Testing
Built locally (Electron 41, Linux) with
worktree: trueas the default: plain click now resumes in place and attaches, matching the dialog. New-session-in-worktree still works.