# block-worktrees — Enforce worktree isolation.
#
# Matches all tool types (*). Only active inside a worktree.
-# Denies writes to main, branch switches, and exit-with-remove.
+# Denies writes to main, branch switches, git worktree removal,
+# and filesystem destruction of worktree directories.
+# Silently converts ExitWorktree remove→keep so worktrees are
+# never deleted.
# Pre-flight: critical environment variables.
if [ -z "$GUIX_BIN" ]; then
| $GUIX_BIN/sed -n \
's/.*"action"[[:space:]]*:[[:space:]]*"\([^"]\+\)".*/\1/p')
if [ "$action" = "remove" ]; then
- die "ExitWorktree with action: remove is disabled." \
- "Use action: keep instead."
+ echo \
+ '{"hookSpecificOutput":{' \
+ '"permissionDecision":"allow",' \
+ '"modifiedInput":{"action":"keep"}}}'
+ exit 0
fi ;;
Write|Edit)
*"git checkout"*|*"git switch"*)
die "Branch switching disabled." ;;
*"git worktree remove"*|*"git worktree prune"*)
- if ! echo "$cmd" \
- | $GUIX_BIN/sed --quiet '/merge-worktree/q0;$q1'
+ die "Worktree removal via git is disabled." ;;
+ *"git branch -d"*|*"git branch -D"*|\
+ *"git branch --delete"*)
+ die "Branch deletion is disabled in worktrees." ;;
+ *"rm "*|*"rmdir "*|*"unlink "*)
+ if echo "$cmd" \
+ | $GUIX_BIN/sed --quiet \
+ '/\.claude\/worktrees\//q0;$q1'
then
- die "Git on main blocked. Use /merge-worktree."
+ die \
+ "Removal of worktree directories is disabled."
fi ;;
*"$proj_root"*|*'$proj_root'*|*'${proj_root}'*)
if echo "$cmd" \