mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-02 10:21:34 +00:00
Claude Code worktrees under .claude/worktrees/ are created without their own node_modules (git worktrees don't materialize gitignored dirs), so tooling silently resolves up to the parent checkout's node_modules. That breaks when the parent sits on a divergent branch missing a newer dependency (observed: tsgo failing on libphonenumber-js in a fresh worktree). Track a minimal .claude/settings.json with a SessionStart(startup) hook that runs an idempotent `pnpm install --frozen-lockfile --ignore-scripts` in the worktree root on first entry, so each worktree is self-contained. Hardening: - resolves the worktree root via `git rev-parse --show-toplevel` (not cwd), so it works when Claude launches from a subdirectory; - --ignore-scripts: a branch-controlled package lifecycle script cannot gain code execution merely because Claude starts a session in that worktree; - --frozen-lockfile: no lockfile mutation; skips cleanly when pnpm or the lockfile is absent; warns instead of blocking the session on failure. Only .claude/settings.json is un-ignored; .claude/worktrees, skills, and settings.local.json stay ignored. Claude Code only — CI and Codex worktrees do not read this file.
17 lines
549 B
JSON
17 lines
549 B
JSON
{
|
|
"hooks": {
|
|
"SessionStart": [
|
|
{
|
|
"matcher": "startup",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "bash -c 'r=\"$(git rev-parse --show-toplevel 2>/dev/null)\"; [ -n \"$r\" ] && cd \"$r\" || exit 0; command -v pnpm >/dev/null 2>&1 && [ -f pnpm-lock.yaml ] || exit 0; CI=true pnpm install --frozen-lockfile --ignore-scripts || echo \"[worktree-setup] pnpm install failed; run pnpm install manually in this worktree\"'",
|
|
"timeout": 600
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|