@webpieces/ai-hook-rules 0.4.508 → 0.4.510

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/package.json +2 -2
  2. package/src/bin/shim.d.ts +2 -0
  3. package/src/bin/shim.js +46 -19
  4. package/src/bin/shim.js.map +1 -1
  5. package/src/core/build-context.d.ts +2 -1
  6. package/src/core/build-context.js +5 -2
  7. package/src/core/build-context.js.map +1 -1
  8. package/src/core/effective-tree.d.ts +75 -0
  9. package/src/core/effective-tree.js +136 -0
  10. package/src/core/effective-tree.js.map +1 -0
  11. package/src/core/rules/branch-creation-guard.d.ts +20 -47
  12. package/src/core/rules/branch-creation-guard.js +58 -150
  13. package/src/core/rules/branch-creation-guard.js.map +1 -1
  14. package/src/core/rules/cap-remedies.d.ts +79 -0
  15. package/src/core/rules/cap-remedies.js +175 -0
  16. package/src/core/rules/cap-remedies.js.map +1 -0
  17. package/src/core/rules/content-read-scan.d.ts +29 -4
  18. package/src/core/rules/content-read-scan.js +54 -9
  19. package/src/core/rules/content-read-scan.js.map +1 -1
  20. package/src/core/rules/feature-branch-guard.js +1 -1
  21. package/src/core/rules/feature-branch-guard.js.map +1 -1
  22. package/src/core/rules/merged-branch-bash-guard.js +8 -2
  23. package/src/core/rules/merged-branch-bash-guard.js.map +1 -1
  24. package/src/core/rules/merged-branch-message.d.ts +8 -0
  25. package/src/core/rules/merged-branch-message.js +17 -1
  26. package/src/core/rules/merged-branch-message.js.map +1 -1
  27. package/src/core/rules/read-stale-guard.js +2 -2
  28. package/src/core/rules/read-stale-guard.js.map +1 -1
  29. package/src/core/rules/stale-main-bash-guard.js +2 -2
  30. package/src/core/rules/stale-main-bash-guard.js.map +1 -1
  31. package/src/core/rules/stale-main-message.d.ts +12 -0
  32. package/src/core/rules/stale-main-message.js +17 -1
  33. package/src/core/rules/stale-main-message.js.map +1 -1
  34. package/src/core/rules/tree-recovery.d.ts +16 -0
  35. package/src/core/rules/tree-recovery.js +28 -7
  36. package/src/core/rules/tree-recovery.js.map +1 -1
  37. package/src/core/runner.js +56 -77
  38. package/src/core/runner.js.map +1 -1
  39. package/src/core/types.d.ts +12 -1
  40. package/src/core/types.js +14 -1
  41. package/src/core/types.js.map +1 -1
  42. package/templates/ai-hook.sh +5 -5
@@ -121,14 +121,14 @@ wp_log() { # $1 = decision label (ALLOW-INSTALL | DENY | DENY-
121
121
  DENY_LABEL="DENY"
122
122
  [ -n "$DRIFT_PKG" ] && DENY_LABEL="DENY-STALE" # version drift, not a missing bin
123
123
  [ -n "$BROKEN_BIN" ] && DENY_LABEL="DENY-BROKEN" # bin present but CRASHED (corrupt node_modules)
124
- if printf '%s' "$CMD" | grep -Eq '^(pnpm|npm)[[:space:]]+(install|i)([[:space:]]+--[A-Za-z][A-Za-z0-9=._/@:-]*)*([[:space:]]+2>(&1|/dev/null))?([[:space:]]*\|[[:space:]]*(tail|head)([[:space:]]+-(n[[:space:]]+)?[0-9]+)?)?[[:space:]]*$' || printf '%s' "$CMD" | grep -Eq '^rm[[:space:]]+-rf[[:space:]]+(\./)?node_modules/?([[:space:]]*&&[[:space:]]*(pnpm|npm)[[:space:]]+(install|i)([[:space:]]+--[A-Za-z][A-Za-z0-9=._/@:-]*)*)?([[:space:]]+2>(&1|/dev/null))?([[:space:]]*\|[[:space:]]*(tail|head)([[:space:]]+-(n[[:space:]]+)?[0-9]+)?)?[[:space:]]*$'; then
124
+ if printf '%s' "$CMD" | grep -Eq '^(cd[[:space:]]+[A-Za-z0-9._/@~+-]+[[:space:]]*&&[[:space:]]*)?(pnpm|npm)[[:space:]]+(install|i)([[:space:]]+--[A-Za-z][A-Za-z0-9=._/@:-]*)*([[:space:]]+2>(&1|/dev/null))?([[:space:]]*\|[[:space:]]*(tail|head)([[:space:]]+-(n[[:space:]]+)?[0-9]+)?)?[[:space:]]*$' || printf '%s' "$CMD" | grep -Eq '^(cd[[:space:]]+[A-Za-z0-9._/@~+-]+[[:space:]]*&&[[:space:]]*)?rm[[:space:]]+-rf[[:space:]]+(\./)?node_modules/?([[:space:]]*&&[[:space:]]*(pnpm|npm)[[:space:]]+(install|i)([[:space:]]+--[A-Za-z][A-Za-z0-9=._/@:-]*)*)?([[:space:]]+2>(&1|/dev/null))?([[:space:]]*\|[[:space:]]*(tail|head)([[:space:]]+-(n[[:space:]]+)?[0-9]+)?)?[[:space:]]*$'; then
125
125
  wp_log ALLOW-INSTALL # record the self-heal we let through (re-enables the guards)
126
126
  exit 0 # allow the installer/recovery so the assistant can break the deadlock
127
127
  fi
128
128
  # DRIFT ONLY: let the git sync commands through. When the PIN is the stale side (a checkout behind
129
129
  # origin), 'pnpm install' DOWNGRADES and 'git pull' is the only cure — denying it deadlocks the
130
130
  # assistant against its own fix. Pointless for a missing/broken bin, so it stays gated on drift.
131
- if [ -n "$DRIFT_PKG" ] && printf '%s' "$CMD" | grep -Eq '^git[[:space:]]+(pull|fetch|merge)([[:space:]]+(--)?[A-Za-z0-9][A-Za-z0-9=._/@:-]*)*([[:space:]]+2>(&1|/dev/null))?([[:space:]]*\|[[:space:]]*(tail|head)([[:space:]]+-(n[[:space:]]+)?[0-9]+)?)?[[:space:]]*$'; then
131
+ if [ -n "$DRIFT_PKG" ] && printf '%s' "$CMD" | grep -Eq '^(cd[[:space:]]+[A-Za-z0-9._/@~+-]+[[:space:]]*&&[[:space:]]*)?git[[:space:]]+(pull|fetch|merge)([[:space:]]+(--)?[A-Za-z0-9][A-Za-z0-9=._/@:-]*)*([[:space:]]+2>(&1|/dev/null))?([[:space:]]*\|[[:space:]]*(tail|head)([[:space:]]+-(n[[:space:]]+)?[0-9]+)?)?[[:space:]]*$'; then
132
132
  wp_log ALLOW-SYNC # record the git sync we let through (may be what re-syncs the pin)
133
133
  exit 0
134
134
  fi
@@ -142,7 +142,7 @@ if [ -n "$BROKEN_BIN" ]; then
142
142
  if [ "${STAGING_N:-0}" -gt 0 ] 2>/dev/null; then
143
143
  STAGING_NOTE=" Also found $STAGING_N orphaned pnpm staging dirs (name_pid_hash) under node_modules - the fingerprint of an install that was killed mid-write."
144
144
  fi
145
- REASON="❌ webpieces guards are DOWN and every OTHER tool call is BLOCKED: ${BIN_NAME} is installed but CRASHED ($CRASH_MSG). Your node_modules is corrupt or partially written, so the guards cannot run - and they must NOT be silently skipped. NOTE: a plain 'pnpm install' will NOT fix this; pnpm sees the correct version on disk and skips the broken package. THIS IS NOT A DEADLOCK: the option below is explicitly ALLOWED through while this guard is up, so run it YOURSELF rather than handing it to the human. OPTION 1 - run EXACTLY this command, then retry: 'rm -rf node_modules && pnpm install'. Type the option you pick EXACTLY as written, character for character, and run NOTHING else on that line. Seriously: do NOT append && anything (not even a harmless && git status), do NOT put a cd in front of it, do NOT wrap it in a subshell. The allowlist is anchored to the ENTIRE command, so anything you bolt on makes it a DIFFERENT command and it WILL be rejected again - which is not the guard refusing its own cure. If an option already contains &&, that && is part of the command: keep it, and still add nothing beyond it. The ONLY additions that are tolerated are a trailing 2>&1 or a pipe into tail/head (e.g. 2>&1 | tail -20).${STAGING_NOTE}"
145
+ REASON="❌ webpieces guards are DOWN and every OTHER tool call is BLOCKED: ${BIN_NAME} is installed but CRASHED ($CRASH_MSG). Your node_modules is corrupt or partially written, so the guards cannot run - and they must NOT be silently skipped. NOTE: a plain 'pnpm install' will NOT fix this; pnpm sees the correct version on disk and skips the broken package. THIS IS NOT A DEADLOCK: the option below is explicitly ALLOWED through while this guard is up, so run it YOURSELF rather than handing it to the human. OPTION 1 - run EXACTLY this command, then retry: 'rm -rf node_modules && pnpm install'. Type the option you pick EXACTLY as written, character for character, and run NOTHING else on that line. Seriously: do NOT append && anything (not even a harmless && git status), do NOT wrap it in a subshell. The allowlist is anchored to the ENTIRE command, so anything you bolt on makes it a DIFFERENT command and it WILL be rejected again - which is not the guard refusing its own cure. If an option already contains &&, that && is part of the command: keep it, and still add nothing beyond it. The only additions tolerated are a LEADING cd <dir> && (needed to run the cure in a linked worktree, since cd does not persist between tool calls - that one IS accepted), a trailing 2>&1, and a pipe into tail/head (e.g. cd /path/to/worktree && pnpm install 2>&1 | tail -20).${STAGING_NOTE}"
146
146
  elif [ -n "$DRIFT_PKG" ]; then
147
147
  # The 'how do I get current' half comes from SyncFlowGuidance so it cannot contradict the guards.
148
148
  # It used to name 'git merge --ff-only origin/main' and assert that merge is allowed while this guard
@@ -155,7 +155,7 @@ elif [ -n "$DRIFT_PKG" ]; then
155
155
  # check is a plain !=, so it fires BOTH ways, and the old text always claimed node_modules was the
156
156
  # older side. When it is actually the NEWER side (a checkout behind origin), that text sent people
157
157
  # to 'pnpm install', which DOWNGRADES them further from correct.
158
- REASON="❌ webpieces version drift: package.json pins $DRIFT_PKG@$DRIFT_DECLARED but node_modules has $DRIFT_INSTALLED. Every OTHER call is blocked until they agree. WHICH ONE IS STALE decides which option is yours - compare the two versions above. OPTION 1 (the pin is NEWER than node_modules - you just pulled or switched to a branch pinning a newer webpieces) - run EXACTLY this command to catch node_modules up: 'pnpm install'. OPTION 2 (the pin is OLDER than node_modules - your checkout is behind origin, so the PIN is the stale side, and 'pnpm install' on its own would DOWNGRADE you) - get the checkout current FIRST, THEN run 'pnpm install'. To get main itself current: ON main, run 'git pull origin main'. In a linked worktree (main is checked out in the primary clone, so checkout main fatals there), run 'git fetch origin main' and branch off origin/main. Do NOT reach for git merge --ff-only / git reset --hard / git checkout -B main: merge and rebase are blocked in EVERY form by redirect-how-to-merge-main, and the reset/-B forms silently throw away commits. To sync a FEATURE branch from main use pnpm wp-start-update (no PR open) or pnpm wp-start-upsert-pr (a PR is open). git pull and git fetch are allowed while this guard is up and are the cure here. Do not reach for git merge: this guard lets it through only because the guards are DOWN, and the moment they come back redirect-how-to-merge-main blocks it in every form. Type the option you pick EXACTLY as written, character for character, and run NOTHING else on that line. Seriously: do NOT append && anything (not even a harmless && git status), do NOT put a cd in front of it, do NOT wrap it in a subshell. The allowlist is anchored to the ENTIRE command, so anything you bolt on makes it a DIFFERENT command and it WILL be rejected again - which is not the guard refusing its own cure. If an option already contains &&, that && is part of the command: keep it, and still add nothing beyond it. The ONLY additions that are tolerated are a trailing 2>&1 or a pipe into tail/head (e.g. 2>&1 | tail -20)."
158
+ REASON="❌ webpieces version drift: package.json pins $DRIFT_PKG@$DRIFT_DECLARED but node_modules has $DRIFT_INSTALLED. Every OTHER call is blocked until they agree. WHICH ONE IS STALE decides which option is yours - compare the two versions above. OPTION 1 (the pin is NEWER than node_modules - you just pulled or switched to a branch pinning a newer webpieces) - run EXACTLY this command to catch node_modules up: 'pnpm install'. OPTION 2 (the pin is OLDER than node_modules - your checkout is behind origin, so the PIN is the stale side, and 'pnpm install' on its own would DOWNGRADE you) - get the checkout current FIRST, THEN run 'pnpm install'. To get main itself current: ON main, run 'git pull origin main'. In a linked worktree (main is checked out in the primary clone, so checkout main fatals there), run 'git fetch origin main' and branch off origin/main. Do NOT reach for git merge --ff-only / git reset --hard / git checkout -B main: merge and rebase are blocked in EVERY form by redirect-how-to-merge-main, and the reset/-B forms silently throw away commits. To sync a FEATURE branch from main use pnpm wp-start-update (no PR open) or pnpm wp-start-upsert-pr (a PR is open). git pull and git fetch are allowed while this guard is up and are the cure here. Do not reach for git merge: this guard lets it through only because the guards are DOWN, and the moment they come back redirect-how-to-merge-main blocks it in every form. Type the option you pick EXACTLY as written, character for character, and run NOTHING else on that line. Seriously: do NOT append && anything (not even a harmless && git status), do NOT wrap it in a subshell. The allowlist is anchored to the ENTIRE command, so anything you bolt on makes it a DIFFERENT command and it WILL be rejected again - which is not the guard refusing its own cure. If an option already contains &&, that && is part of the command: keep it, and still add nothing beyond it. The only additions tolerated are a LEADING cd <dir> && (needed to run the cure in a linked worktree, since cd does not persist between tool calls - that one IS accepted), a trailing 2>&1, and a pipe into tail/head (e.g. cd /path/to/worktree && pnpm install 2>&1 | tail -20)."
159
159
  else
160
160
  # A LINKED WORKTREE is the overwhelmingly common way to land here with a perfectly healthy repo:
161
161
  # git gives the new worktree a .git FILE (the primary clone has a .git directory) and copies no
@@ -166,7 +166,7 @@ else
166
166
  if [ -f "$ROOT/.git" ]; then
167
167
  WORKTREE_NOTE=" NOTE: $ROOT is a LINKED WORKTREE - git does not copy node_modules into a new worktree, so this is expected on a fresh one. Run 'pnpm install' HERE (in this worktree), not in the primary clone."
168
168
  fi
169
- REASON="❌ @webpieces/ai-hook-rules is declared in package.json but is not installed (${BIN_NAME} not found). OPTION 1 - run EXACTLY this command to enable the webpieces AI guards, then retry: 'pnpm install'. Type the option you pick EXACTLY as written, character for character, and run NOTHING else on that line. Seriously: do NOT append && anything (not even a harmless && git status), do NOT put a cd in front of it, do NOT wrap it in a subshell. The allowlist is anchored to the ENTIRE command, so anything you bolt on makes it a DIFFERENT command and it WILL be rejected again - which is not the guard refusing its own cure. If an option already contains &&, that && is part of the command: keep it, and still add nothing beyond it. The ONLY additions that are tolerated are a trailing 2>&1 or a pipe into tail/head (e.g. 2>&1 | tail -20).${WORKTREE_NOTE} (If you removed @webpieces/ai-hook-rules on purpose, delete its hooks from .claude/settings.json.)"
169
+ REASON="❌ @webpieces/ai-hook-rules is declared in package.json but is not installed (${BIN_NAME} not found). OPTION 1 - run EXACTLY this command to enable the webpieces AI guards, then retry: 'pnpm install'. Type the option you pick EXACTLY as written, character for character, and run NOTHING else on that line. Seriously: do NOT append && anything (not even a harmless && git status), do NOT wrap it in a subshell. The allowlist is anchored to the ENTIRE command, so anything you bolt on makes it a DIFFERENT command and it WILL be rejected again - which is not the guard refusing its own cure. If an option already contains &&, that && is part of the command: keep it, and still add nothing beyond it. The only additions tolerated are a LEADING cd <dir> && (needed to run the cure in a linked worktree, since cd does not persist between tool calls - that one IS accepted), a trailing 2>&1, and a pipe into tail/head (e.g. cd /path/to/worktree && pnpm install 2>&1 | tail -20).${WORKTREE_NOTE} (If you removed @webpieces/ai-hook-rules on purpose, delete its hooks from .claude/settings.json.)"
170
170
  fi
171
171
  if [ "$TOOL" = "Bash" ]; then
172
172
  BS='\' # one literal backslash, so the \u001b escape never sits in this source