The six marker hooks in plugins/worktrunk/hooks/hooks.json — marker set on
UserPromptSubmit, Notification, PreToolUse, PermissionRequest and Stop,
and marker clear on SessionEnd — run without -C:
bash "$CLAUDE_PLUGIN_ROOT/hooks/wt.sh" config state marker set 💬 || true
So the marker resolves against the hook process's working directory. That is the
agent's shell cwd, and an agent moves it during a turn — reading files out of a
second checkout, for instance. The two hooks in the same file that do reach for a
directory both scope it: WorktreeRemove passes -C "$p", and WorktreeCreate
cds to CLAUDE_PROJECT_DIR.
Three consequences, all silent:
- A
cd into another repository marks that repository's branch instead, and the
session's own marker stops updating. The statusline then carries a stale
marker on the branch being worked on and a spurious one somewhere else.
- A session that ends while the shell sits in another repository clears that
repository's marker on SessionEnd, and leaves its own set.
- In a directory that is not a repository the command prints
✗ git rev-parse --git-common-dir failed (exit 128) and exits 1. The trailing
|| true turns that into a success, so nothing surfaces.
Repro, given a worktree of one repo and any second repo:
cd /tmp/repo-a.feature && wt config state marker set 🧪
# ✓ Set marker for feature to 🧪
cd /tmp/repo-b && wt config state marker set 🧪
# ✓ Set marker for main to 🧪 <- repo-b's branch, from a session on `feature`
cd /tmp/not-a-repo && wt config state marker set 🧪
# ✗ git rev-parse --git-common-dir failed (exit 128), rc 1
The marker should track the worktree the session belongs to rather than wherever
its shell currently is. -C <path> would carry that, but the value to pass isn't
obvious: CLAUDE_PROJECT_DIR is the launch directory and goes stale once the
session moves to another worktree mid-run, and the hook payload's cwd is the
same directory that drifted. Pinning the worktree at session start is one route;
resolving it from the session record is another.
Seen on worktrunk e4238e8.
This was written by Claude Code on behalf of max-sixty
The six marker hooks in
plugins/worktrunk/hooks/hooks.json—marker setonUserPromptSubmit,Notification,PreToolUse,PermissionRequestandStop,and
marker clearonSessionEnd— run without-C:So the marker resolves against the hook process's working directory. That is the
agent's shell cwd, and an agent moves it during a turn — reading files out of a
second checkout, for instance. The two hooks in the same file that do reach for a
directory both scope it:
WorktreeRemovepasses-C "$p", andWorktreeCreatecds to
CLAUDE_PROJECT_DIR.Three consequences, all silent:
cdinto another repository marks that repository's branch instead, and thesession's own marker stops updating. The statusline then carries a stale
marker on the branch being worked on and a spurious one somewhere else.
repository's marker on
SessionEnd, and leaves its own set.✗ git rev-parse --git-common-dir failed (exit 128)and exits 1. The trailing|| trueturns that into a success, so nothing surfaces.Repro, given a worktree of one repo and any second repo:
The marker should track the worktree the session belongs to rather than wherever
its shell currently is.
-C <path>would carry that, but the value to pass isn'tobvious:
CLAUDE_PROJECT_DIRis the launch directory and goes stale once thesession moves to another worktree mid-run, and the hook payload's
cwdis thesame directory that drifted. Pinning the worktree at session start is one route;
resolving it from the session record is another.
Seen on worktrunk e4238e8.