authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-02-11 15:33:01-08:00
committergravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-02-11 15:33:01-08:00
log5b7af7b9f641b8e8f1bdffabcdd423d3f09e9d80
treeb97b3f84878aac084e8d9d40a518e5f3ffd59b16
parent8324949b54c9aadc5d5db1b6cebbd10325a0ea79

Fix session not restarting when switching to a worktree branch

When selecting a branch that lives in a different worktree, the store updated the thread's worktreePath but the running session kept its original cwd. The agent continued operating in the old directory. - SET_THREAD_BRANCH now clears the session when worktreePath changes - BranchToolbar stops the server-side session before dispatching the branch change, so the next message creates a fresh session with the correct cwd Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

2 files changed, 20 insertions(+), 6 deletions(-)

apps/web/src/components/BranchToolbar.tsx+6
...@@ -108,6 +108,12 @@ export default function BranchToolbar({ envMode, onEnvModeChange, envLocked }: B...@@ -108,6 +108,12 @@ export default function BranchToolbar({ envMode, onEnvModeChange, envLocked }: B
108108
109 const setThreadBranch = (branch: string | null, worktreePath: string | null) => {109 const setThreadBranch = (branch: string | null, worktreePath: string | null) => {
110 if (!activeThreadId) return;110 if (!activeThreadId) return;
111 // If the effective cwd is about to change, stop the running session so the
112 // next message creates a new one with the correct cwd.
113 const sessionId = activeThread?.session?.sessionId;
114 if (sessionId && worktreePath !== activeWorktreePath) {
115 void api?.providers.stopSession({ sessionId }).catch(() => undefined);
116 }
111 dispatch({ type: "SET_THREAD_BRANCH", threadId: activeThreadId, branch, worktreePath });117 dispatch({ type: "SET_THREAD_BRANCH", threadId: activeThreadId, branch, worktreePath });
112 };118 };
113119
apps/web/src/store.ts+14-6
...@@ -376,15 +376,23 @@ export function reducer(state: AppState, action: Action): AppState {...@@ -376,15 +376,23 @@ export function reducer(state: AppState, action: Action): AppState {
376 })),376 })),
377 };377 };
378378
379 case "SET_THREAD_BRANCH":379 case "SET_THREAD_BRANCH": {
380 return {380 return {
381 ...state,381 ...state,
382 threads: updateThread(state.threads, action.threadId, (t) => ({382 threads: updateThread(state.threads, action.threadId, (t) => {
383 ...t,383 // When the effective cwd changes (worktreePath differs), the old
384 branch: action.branch,384 // session is no longer valid — clear it so ensureSession creates a
385 worktreePath: action.worktreePath,385 // new one with the correct cwd on the next message.
386 })),386 const cwdChanged = t.worktreePath !== action.worktreePath;
387 return {
388 ...t,
389 branch: action.branch,
390 worktreePath: action.worktreePath,
391 ...(cwdChanged ? { session: null } : {}),
392 };
393 }),
387 };394 };
395 }
388396
389 case "SET_RUNTIME_MODE":397 case "SET_RUNTIME_MODE":
390 return {398 return {