fix(files): list the git worktree an agent moved into (#765)

Claude Code's EnterWorktree moves the running process into
<repo>/.claude/worktrees/<name>, while Session.workingDir stays on the main
checkout. The Files panel kept walking workingDir, so it listed a tree the
agent had left.

paneCwd already follows the move, measured on Claude Code 2.1.318 in both
directions, so nothing new has to track the agent. It also follows every cd
in a shell, so a new SessionState.liveWorktree narrows it to a linked
worktree, read from the .git file without starting git.

Only a folder strictly below workingDir is ever an answer, and the listing
only starts there: returned paths stay relative to workingDir, so the
preview, raw and edit routes are unchanged and confinement does not widen.
A worktree outside the session folder stays unfollowed.

The panel asks with root=live, shows a strip naming the worktree with a
switch to the session folder, and follows the agent in and out while open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer committed 2026-11-05 23:47:38 +01:00
1 parent 46b85fa6d0
commit 89a93c871f
19 files changed
+853 -32

No files matched your search

+10
View File
@@ -34,6 +34,7 @@
import type { RespawnConfig } from './respawn.js';
import type { AttachmentDetectedType } from './tools.js';
import type { GitFetchStatus } from '../git-fetch.js';
import type { LiveWorktree } from '../live-worktree.js';
/** Status of a Claude session */
export type SessionStatus = 'idle' | 'busy' | 'stopped' | 'error';
@@ -847,6 +848,15 @@ export interface SessionState {
* routes like any other out-of-workspace path.
*/
paneCwd?: string;
/**
* The linked git worktree inside `workingDir` that the pane is in NOW, when there is one:
* Claude Code's `.claude/worktrees/<name>`, or any other worktree of the repository under
* the session's folder. Derived from {@link paneCwd} by `live-worktree.ts`, so it is
* runtime-only and absent wherever `paneCwd` is, and absent for a worktree outside
* `workingDir`: the file routes never serve those. NOT a confinement root; the Files panel
* only starts its listing here.
*/
liveWorktree?: LiveWorktree;
/** Remote execution metadata, present when this session runs over SSH through local tmux */
remote?: SessionRemote;
/** Docker execution metadata, present when this session runs inside a container via local tmux + docker exec */