Repository navigation
Description
Problem
When a Claude session moves into a git worktree partway through, the Files panel keeps showing the main checkout. To reproduce:
- Create a Codeman session on a repository, for example
~/src/myapp. - Ask Claude to work in a worktree. Claude Code's worktree feature creates
~/src/myapp/.claude/worktrees/<name>and moves theclaudeprocess there. - Click the Files button.
The panel lists ~/src/myapp, not the worktree Claude is editing. Files that Claude creates or changes in the worktree are missing from the tree, and the preview shows the main checkout's version of every file the two share.
Cause
Session.workingDir is readonly (src/session.ts) and only the constructor assigns it, from the case or path chosen at creation. GET /api/sessions/:id/files walks session.workingDir (src/web/routes/file-routes.ts), and the preview and edit routes use it for their confinement check. Nothing updates it when the agent's own working directory changes.
Codeman already detects worktrees elsewhere. Past-session rows read the transcript's cwd and worktree-state records and show a worktree badge (#265, #266). The Files panel doesn't use that information.
Proposal
Track the agent's current working directory on the live session, and root the Files panel there when it differs from workingDir.
- Every Claude Code hook payload carries
cwd, and/api/hook-eventalready receives it. The transcript'sworktree-staterecord is a second source that also covers sessions without workspace hooks. - Keep
workingDiras the session's identity. It decides the case, the tmux attach cwd and persistence, so the live directory should be a separate field onSessionState. - The panel header should show which directory it lists, and offer a way back to the session root.
Security
The live directory comes from hook payloads and transcripts, which an agent can influence. A worktree under <workingDir>/.claude/worktrees/ is already inside the confinement root, so following it widens nothing. A worktree outside the root, such as one made with git worktree add ../myapp-feature, would need the file routes to accept a second root. The design should decide whether to allow that. If it does, it should accept only a directory that git worktree list in workingDir reports as a worktree of the same repository. It should never accept an arbitrary path from a hook.
Workarounds
- Turn on hidden files in the panel and open
.claude/worktrees/<name>. - Create a separate session on the worktree directory with Add Case → Link Existing.
Activity
Ark0N commentedon Nov 6, 2026
Thanks, this was a clear report. I have a fix on a branch,
fix/files-panel-worktree, tested with a real Claude Code session moving in and out of a worktree in a browser.Your proposal mostly held, with two differences worth knowing:
cwd, and it follows everycdin a Bash call, so.../probe/subrather than the worktree root. The pane directory is the better signal for this. It does follow acdin a plain shell session though, so the panel only moves when that directory is inside a linked worktree, recognised by its.gitfile. Acd srcmoves nothing.<workingDir>/.claude/worktrees/is already inside the confinement root, so following it widens nothing, and the file routes are unchanged: paths stay relative toworkingDir. Allowing../myapp-featurewould need a second root, which is a bigger decision than this bug, so for those Add Case → Link Existing stays the way in.The panel gets a strip naming the worktree, with a button to switch to the session folder and back, and it follows the agent in and out while it's open.
Ark0N commentedon Nov 6, 2026
The fix is up as #772.
fix(files): list the git worktree an agent moved into (Ark0N#765)