fix(sessions): restore resume-or-fresh fallback chain for AI tool launches - #236
Conversation
…worktrees Restore the `<resume> || <fresh>` shell fallback that ca72a85 removed. The helpers in WorktreeCore are still named *WithFallback but had been launching just the resume form, so when `claude --continue` (or `codex resume --last`, `gemini --resume latest`) exits nonzero on an existing worktree the tmux pane is left empty and the user has to restart manually. Most concrete trigger: switching the AI tool on an existing worktree. If a worktree was previously running codex and the user picks claude, there is no prior claude session in that cwd, `claude --continue` exits, and without the chain the pane never lands at a claude prompt. The freshWorktree=true path (createFeature, recreateImplementWorktree) is unchanged — those callers already launch the fresh form directly and never attempt to resume, so the noisy "no saved session" first-launch message that motivated ca72a85 stays suppressed. Updated WorktreeCoreAutoResume tests to assert the chained command shape and added a regression test for the agent-switch scenario. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Address review comment "why is this separate from the others?". The two launchAISessionWithFallback variants only differed in claude's `-n displayName` flag, so fold that into the unified helper as an optional trailing parameter threaded from the call site when selectedTool === 'claude'. Drops the duplicate Claude-specific helper and removes the unused AI_TOOLS value import. No behavior change — same `<resume> || <fresh>` chain for the non-fresh path, same plain-fresh launch when freshWorktree=true. Full suite (781 tests) and typecheck pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…uild Apply review findings: drop the dead `tool === 'none'` guard (caller already narrows), narrow the parameter type, hoist a single `promptArg` instead of re-deriving the with/without-prompt ternary in each branch, source the fresh-form binary name from `AI_TOOLS[tool].command` for parity with `aiLaunchCommand` on the resume form, and always pass `displayName` from the caller (the helper is the single source of truth for "which tools use -n"). Trim the doc comment to the agent-switch WHY. No behavior change — the same `<resume> || <fresh>` chain (or plain fresh when freshWorktree=true) for all three tools. 781 tests + typecheck pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Code Review — PR #236: fix(sessions): restore resume-or-fresh fallback chainOverviewThis PR restores the Code quality ✅
Potential issuesMinor — error output visibility before fallback runs: When Unused Performance ✅No change to refresh rates or hot paths. The command string building is trivial. Security ✅All externally-derived strings ( Test coverage ✅
SummaryThis is a clean, well-scoped fix. The refactor to a single helper is a genuine improvement. The only actionable suggestion is adding a TODO comment to the unused 🤖 Generated with Claude Code |
…k chain PR #236 review: AIToolService.launchTool still launches `claude --continue` with no fresh-launch fallback. It is unused in production today, but a future caller could silently reintroduce the bug PR #236 fixed. Add a brief docstring pointing at the live launch path so the next person who wires it up mirrors the chain. No behavior change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Code Review — PR #236: restore resume-or-fresh fallback chainOverall: ✅ Looks good — clean fix, well-scoped, solid tests. What this doesRestores the Code quality
Potential issues
Tests
SummaryThe fix is narrow, well-understood, and addresses the root cause. The two minor style points (unconditional |
…AGENTS.md PR #236 second-round review: the multi-line JSDoc I added on AIToolService.launchTool violates the project's preference for terse comments. Trim it to a one-liner and add a short Comments section to AGENTS.md so the convention is on paper.
Code Review — PR #236: fix(sessions): restore resume-or-fresh fallback chain for AI tool launchesOverviewRestores the shell-level Code QualityPositive:
Specific IssuesMinor — comment on AGENTS.md now says "prefer a single line" for warranted comments. The block comment at lines 595–601 is 7 lines covering two distinct concerns. Both concerns are genuinely non-obvious (the agent-switch scenario, and the claude-only // Non-fresh path uses `<resume> || <fresh>` so an agent switch (e.g. codex → claude) doesn't leave the pane empty.
// displayName is claude-only (-n pane title); other tools ignore it.
private launchAISessionWithFallback(...)Minor — // Unused in src/; the live launch path is WorktreeCore.launchAISessionWithFallback. If wired up again, mirror its `<resume> || <fresh>` chain.AGENTS.md says "don't reference current task / fix / caller" and the specific method name reference ( // Unused; if revived, build the command as `<resume-form> || <fresh-form>` (see WorktreeCore for the canonical pattern).Observation — test comments explain the WHAT: The two inline comments in the new regression test: // Simulate a worktree that was previously running codex.
// Now the user explicitly picks claude — no fresh-worktree flag, since the worktree directory already exists.They mostly restate the setup lines that follow them. The test name already says "switching to claude on a worktree previously used with codex"; the comments could be dropped without losing anything. Correctness / BehaviorTraced all three tools through the new command-build logic:
The Test Coverage
One gap worth noting: there's no test for the SecurityNo concerns. All user-controlled values ( SummaryThe core logic is correct, the refactor is a genuine improvement, and the test additions are appropriate. The three comments flagged above are minor style nits relative to the new AGENTS.md guideline. No blockers. 🤖 Generated with Claude Code |
Summary
<resume> || <fresh>shell-level fallback that commitca72a85removed. When the user attaches to an existing worktree, devteam launches the selected AI tool with its resume flag (claude --continue,codex resume --last,gemini --resume latest) — but on tool-switch (e.g. picking claude on a worktree that previously ran codex) the resume form exits with no prior session, leaving the tmux pane empty. The chain falls through to a fresh launch in that case.launchClaudeSessionWithFallbackandlaunchAISessionWithFallback; the only Claude-specific concern (the-n displayNametmux pane title flag) is now an optional parameter on a single helper. The helper is one straight-line build instead of per-tool branching.freshWorktree=truecallers (createFeature,recreateImplementWorktree) are unchanged: they still launch the fresh form directly with no chain, since the worktree was just created and there is nothing to resume.Test plan
npm run buildcleannpm test— 781/781 pass across 77 suitesnpx tsc -p tsconfig.test.jsoncleanWorktreeCoreAutoResumeassertions to match the chained command shapelastTool=codexproduces the chained launch (the originally-reported failure case)claude --continue || clauderuns and lands at a working prompt whether the resume succeeds or not🤖 Generated with Claude Code