Resume worktree sessions in their real recorded cwd - #85
Conversation
…e-parent JBR collapses a worktree session's projectPath to the parent repo for sidebar grouping. But `claude --resume` is project/cwd-scoped, so launching from the parent makes claude report 'No conversation found with session ID' for every worktree session. Recover the session's original cwd from its .jsonl transcript and launch the resume there; new sessions and plain terminals are unaffected.
The `windows-latest` label rolled over to Windows Server 2025, whose image no longer ships the Visual Studio C++ toolchain node-gyp needs, so every Windows build failed in electron-builder's install-app-deps while rebuilding node-pty. Pinning to windows-2022 restores an image that still carries the toolchain. Same fix @Flaykz independently included in #72; split out so it lands on its own.
devsuitup
left a comment
There was a problem hiding this comment.
Thanks — the intent is right (worktree sessions resumed under their parent repo do break claude --resume), and the guard is well scoped (attached sessions, new sessions and plain terminals are untouched). But three things need fixing before merge:
Blocking — unbounded read of the session JSONL. resolveSessionRealCwd does fs.readFileSync(jsonl, 'utf8').slice(0, 8000), which reads the whole file into memory before truncating. This repo already hit that exact failure mode: see derive-project-path.js — the header comment documents a 338 MB live-session JSONL pegging the main thread (2026-06-11 incident), and extractCwdFromJsonl there does a bounded 256 KB openSync/readSync scan, with tests. Worktree sessions with long transcripts are precisely the population this PR targets. Please reuse extractCwdFromJsonl from derive-project-path.js instead of reimplementing the read.
Major — settings-key divergence. The guard mutates projectPath before effectiveProfileId is computed (getSetting('project:' + projectPath)), while the renderer header (public/app.js, showTerminalHeader) still resolves the shell profile from the collapsed session.projectPath. With a project-level shell profile configured, the header shows one profile and the PTY spawns another. Resolve project settings from the original (collapsed) path, and use the real cwd only for the spawn cwd / encodeProjectPath / MCP dirs.
Major — no tests. resolveSessionRealCwd and the guard are untested; the twin logic in derive-project-path.js has 8 tests covering exactly the traps here (file larger than the scan window, line cut at the boundary, missing cwd). Please follow that pattern.
Minor: the branch also needs a rebase — open-terminal gained an initialSize parameter on main, the first hunk conflicts.
Resuming a worktree session was failing with "No conversation found with session ID".
The sidebar collapses a worktree session's projectPath to the parent repo for grouping, which is great for the tree. But
claude --resumeis scoped to the cwd it was started in, so launching it from the parent repo means claude looks in the wrong project dir and can't find the conversation.This reads the session's original cwd back from the first
cwdentry in its .jsonl transcript and starts the resume there. New sessions and plain terminals are untouched (they keep the requested projectPath).Small and self-contained: one helper plus a guard in the open-terminal handler.