Files
openclaw/.claude/settings.json
Peter Steinberger 9e8bcd1134 chore(claude): auto-install deps on new Claude Code worktree startup
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.
2026-07-22 13:47:40 -07:00

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
}
]
}
]
}
}