fix: pua-loop state file isolation — prevent cross-directory task bleed

State file was written to a single global path (~/.claude/pua/loop-active.md),
causing two Claude Code instances in different directories to overwrite each
other's loop state. Now uses cwd hash in filename (loop-<hash>.md) so each
project directory has an independent loop instance.

Fixes: multiple users reporting task A executing task B's commands when
running pua-loop in two directories simultaneously.
This commit is contained in:
xsser
2026-04-19 22:20:25 +08:00
parent a0313a408a
commit 08e70525ed
2 changed files with 17 additions and 4 deletions
+13 -1
View File
@@ -42,11 +42,23 @@ fi
# ═══════════════════════════════════════════════════════════════
HOOK_SESSION_ID=$(echo "$HOOK_INPUT" | jq -r '.session_id // ""' 2>/dev/null || echo "")
PUA_DIR="${HOME}/.claude/pua"
ABS_STATE_FILE="${PUA_DIR}/loop-active.md"
CWD_HASH=$(printf '%s' "$(pwd)" | md5sum 2>/dev/null | cut -c1-8 || printf '%s' "$(pwd)" | md5 2>/dev/null | cut -c1-8 || echo "default")
ABS_STATE_FILE="${PUA_DIR}/loop-${CWD_HASH}.md"
LEGACY_ABS_STATE_FILE="${PUA_DIR}/loop-active.md"
LEGACY_STATE_FILE=".claude/pua-loop.local.md"
if [[ -f "$ABS_STATE_FILE" ]]; then
RALPH_STATE_FILE="$ABS_STATE_FILE"
elif [[ -f "$LEGACY_ABS_STATE_FILE" ]]; then
# v3.1 兼容:旧版单文件,检查 started_cwd 是否匹配当前目录
LEGACY_CWD=$(sed -n '/^---$/,/^---$/{ /^---$/d; p; }' "$LEGACY_ABS_STATE_FILE" | grep '^started_cwd:' | sed 's/started_cwd: *//' | sed 's/^"\(.*\)"$/\1/' || true)
if [[ "$LEGACY_CWD" == "$(pwd)" ]] || [[ -z "$LEGACY_CWD" ]]; then
RALPH_STATE_FILE="$LEGACY_ABS_STATE_FILE"
elif [[ -f "$LEGACY_STATE_FILE" ]]; then
RALPH_STATE_FILE="$LEGACY_STATE_FILE"
else
exit 0
fi
elif [[ -f "$LEGACY_STATE_FILE" ]]; then
RALPH_STATE_FILE="$LEGACY_STATE_FILE"
else
+4 -3
View File
@@ -114,13 +114,14 @@ if [[ -z "$PROMPT" ]]; then
fi
# Create state file
# v3.1: 写绝对路径为主($HOME/.claude/pua/loop-active.md),跨 cwd 可找
# 兼容:同时写 legacy 相对路径,老 hook 或用户工具链仍能访问
# v3.2: 用 cwd 哈希命名状态文件,解决多目录 loop 实例互相覆盖的 bug
# 每个项目目录有独立的 loop-<hash>.md,不再共享单一 loop-active.md
PUA_HOME_DIR="${HOME}/.claude/pua"
mkdir -p "$PUA_HOME_DIR"
mkdir -p .claude
ABS_STATE="${PUA_HOME_DIR}/loop-active.md"
CWD_HASH=$(printf '%s' "$(pwd)" | md5sum 2>/dev/null | cut -c1-8 || printf '%s' "$(pwd)" | md5 2>/dev/null | cut -c1-8 || echo "default")
ABS_STATE="${PUA_HOME_DIR}/loop-${CWD_HASH}.md"
LEGACY_STATE=".claude/pua-loop.local.md"
# YAML quoting