cc-safe-setup 29.7.0 → 30.0.4

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 (1022) hide show
  1. package/.claude-plugin/marketplace.json +72 -19
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CONTRIBUTING.md +7 -2
  4. package/COOKBOOK.md +50 -46
  5. package/LICENSE +21 -0
  6. package/MIGRATION.md +8 -8
  7. package/README.md +419 -512
  8. package/SAFETY_CHECKLIST.md +15 -7
  9. package/SERVICES.md +194 -0
  10. package/SETTINGS_REFERENCE.md +236 -17
  11. package/SKILL.md +5 -5
  12. package/TROUBLESHOOTING.md +35 -14
  13. package/action.yml +12 -4
  14. package/audit/README.md +84 -0
  15. package/audit/audit-checklist.md +152 -0
  16. package/audit/boundary-selftest.sh +85 -0
  17. package/audit/boundary.sh +123 -0
  18. package/audit/count-hooks.py +42 -0
  19. package/audit/find-dead-hooks.sh +82 -0
  20. package/audit/find-unfirable-rules.sh +142 -0
  21. package/audit/fire.sh +97 -0
  22. package/audit/selftest.sh +42 -0
  23. package/audit/unfirable-selftest.sh +81 -0
  24. package/audit-web/index.html +9 -9
  25. package/examples/README.md +54 -17
  26. package/examples/account-billing-log.sh +98 -0
  27. package/examples/account-routing-preflight.sh +123 -0
  28. package/examples/agent-sdk-credit-pool-monitor.sh +145 -0
  29. package/examples/agent-view-quota-decrement.sh +32 -0
  30. package/examples/agent-view-quota-warn.sh +94 -0
  31. package/examples/agents-md-edit-drift-warner.sh +223 -0
  32. package/examples/agents-md-loader.sh +160 -0
  33. package/examples/agents-md-sync-checker.sh +102 -0
  34. package/examples/ai-slop-punctuation-arrest.sh +210 -0
  35. package/examples/allowlist.sh +70 -10
  36. package/examples/always-allow-pattern-suggester.sh +125 -0
  37. package/examples/ansible-vault-guard.sh +2 -1
  38. package/examples/anthropic-base-url-guard.sh +76 -0
  39. package/examples/api-busyloop-guard.sh +123 -0
  40. package/examples/api-endpoint-guard.sh +12 -0
  41. package/examples/api-key-in-url-guard.sh +17 -1
  42. package/examples/api-rate-limit-guard.sh +36 -1
  43. package/examples/api-rate-limit-tracker.sh +12 -0
  44. package/examples/articulated-scope-capture.sh +101 -0
  45. package/examples/askuserquestion-autonomy-gate.sh +102 -0
  46. package/examples/attachment-traversal-guard.sh +118 -0
  47. package/examples/aup-block-pattern-logger.sh +161 -0
  48. package/examples/aup-false-positive-helper.sh +124 -0
  49. package/examples/aup-large-tool-output-warner.sh +282 -0
  50. package/examples/aup-retry-loop-guard.sh +229 -0
  51. package/examples/auth-expiry-reminder.sh +157 -0
  52. package/examples/auth-macos-sleep-detector.sh +185 -0
  53. package/examples/auth-path-detector.sh +171 -0
  54. package/examples/auth-status-checker.sh +157 -0
  55. package/examples/authorized-reconfirmation-detector.sh +195 -0
  56. package/examples/auto-approve-build.sh +39 -0
  57. package/examples/auto-approve-cargo.sh +31 -1
  58. package/examples/auto-approve-docker.sh +35 -0
  59. package/examples/auto-approve-git-read.sh +37 -14
  60. package/examples/auto-approve-go.sh +30 -1
  61. package/examples/auto-approve-gradle.sh +29 -1
  62. package/examples/auto-approve-make.sh +29 -1
  63. package/examples/auto-approve-maven.sh +29 -1
  64. package/examples/auto-approve-python.sh +41 -1
  65. package/examples/auto-approve-readonly-tools.sh +1 -0
  66. package/examples/auto-approve-readonly.sh +110 -33
  67. package/examples/auto-approve-ssh.sh +30 -1
  68. package/examples/auto-approve-test.sh +44 -0
  69. package/examples/auto-checkpoint.sh +1 -1
  70. package/examples/auto-compact-prep.sh +0 -0
  71. package/examples/auto-git-checkpoint.sh +0 -0
  72. package/examples/auto-mode-safe-commands.sh +53 -1
  73. package/examples/auto-mode-safety-enforcer.sh +151 -4
  74. package/examples/auto-push-session-branch.sh +22 -0
  75. package/examples/aws-production-guard.sh +13 -1
  76. package/examples/aws-region-guard.sh +1 -1
  77. package/examples/background-cost-launch-guard.sh +82 -0
  78. package/examples/background-task-guard.sh +12 -0
  79. package/examples/backup-before-refactor.sh +0 -0
  80. package/examples/banned-command-guard.sh +12 -0
  81. package/examples/bash-allowlist-secondary-check.sh +157 -0
  82. package/examples/bash-domain-allowlist.sh +12 -0
  83. package/examples/bash-fanout-bounded-rewriter.sh +191 -0
  84. package/examples/bash-heuristic-approver.sh +112 -10
  85. package/examples/bash-project-fence.sh +194 -0
  86. package/examples/bash-safety-auto-deny.sh +12 -0
  87. package/examples/bash-secret-output-detector.sh +44 -3
  88. package/examples/bash-trace-guard.sh +12 -0
  89. package/examples/bashrc-safety-check.sh +0 -0
  90. package/examples/bg-permission-prompt-warner.sh +182 -0
  91. package/examples/bg-task-cooldown-guard.sh +12 -0
  92. package/examples/binary-read-detector.sh +135 -0
  93. package/examples/binary-upload-guard.sh +12 -0
  94. package/examples/block-database-wipe.sh +35 -10
  95. package/examples/branch-name-check.sh +8 -3
  96. package/examples/branch-naming-convention.sh +0 -0
  97. package/examples/broad-find-guard.sh +12 -0
  98. package/examples/broad-prefix-session-trap-warner.sh +106 -0
  99. package/examples/bulk-file-delete-guard.sh +45 -0
  100. package/examples/bypass-mode-effective-verifier.sh +203 -0
  101. package/examples/cache-creation-drift-detector.sh +120 -0
  102. package/examples/cache-residue-detector.sh +195 -0
  103. package/examples/cache-tier-logger.sh +70 -0
  104. package/examples/cache-ttl-eviction-detector.sh +149 -0
  105. package/examples/cargo-publish-guard.sh +14 -1
  106. package/examples/case-insensitive-path-guard.sh +21 -2
  107. package/examples/case-sensitive-guard.sh +23 -2
  108. package/examples/cch-cache-guard.sh +0 -0
  109. package/examples/cch-sentinel-precommit-guard.sh +47 -0
  110. package/examples/check-abort-controller.sh +1 -1
  111. package/examples/check-accessibility.sh +0 -0
  112. package/examples/check-aria-labels.sh +0 -0
  113. package/examples/check-before-act-enforcer.sh +12 -0
  114. package/examples/check-charset-meta.sh +0 -0
  115. package/examples/check-cookie-flags.sh +0 -0
  116. package/examples/check-cors-config.sh +0 -0
  117. package/examples/check-csp-headers.sh +0 -0
  118. package/examples/check-csrf-protection.sh +0 -0
  119. package/examples/check-debounce.sh +1 -1
  120. package/examples/check-dependency-age.sh +0 -0
  121. package/examples/check-dependency-license.sh +0 -0
  122. package/examples/check-dockerfile-best-practice.sh +0 -0
  123. package/examples/check-error-boundaries.sh +0 -0
  124. package/examples/check-error-class.sh +1 -1
  125. package/examples/check-error-handling.sh +0 -0
  126. package/examples/check-error-logging.sh +1 -1
  127. package/examples/check-error-message.sh +0 -0
  128. package/examples/check-error-stack.sh +0 -0
  129. package/examples/check-favicon.sh +0 -0
  130. package/examples/check-git-hooks-compat.sh +0 -0
  131. package/examples/check-gitattributes.sh +0 -0
  132. package/examples/check-https-redirect.sh +0 -0
  133. package/examples/check-input-validation.sh +0 -0
  134. package/examples/check-lang-attribute.sh +0 -0
  135. package/examples/check-npm-scripts-exist.sh +0 -0
  136. package/examples/check-package-size.sh +0 -0
  137. package/examples/check-port-availability.sh +0 -0
  138. package/examples/check-promise-all.sh +1 -1
  139. package/examples/check-rate-limiting.sh +0 -0
  140. package/examples/check-return-types.sh +0 -0
  141. package/examples/check-semantic-versioning.sh +0 -0
  142. package/examples/check-suspense-fallback.sh +1 -1
  143. package/examples/check-test-exists.sh +0 -0
  144. package/examples/check-test-naming.sh +0 -0
  145. package/examples/check-timeout-cleanup.sh +1 -1
  146. package/examples/check-tls-version.sh +0 -0
  147. package/examples/check-unsubscribe.sh +1 -1
  148. package/examples/check-viewport-meta.sh +0 -0
  149. package/examples/check-worker-terminate.sh +1 -1
  150. package/examples/checkpoint-tamper-guard.sh +12 -0
  151. package/examples/chmod-guard.sh +12 -0
  152. package/examples/chown-guard.sh +24 -0
  153. package/examples/ci-workflow-guard.sh +6 -1
  154. package/examples/claim-verify-detector.sh +109 -0
  155. package/examples/claim-vs-caveat-checker.sh +77 -0
  156. package/examples/classifier-fallback-allow.sh +114 -40
  157. package/examples/claude-cache-gc.sh +1 -0
  158. package/examples/claude-code-version-pin-advisor.sh +183 -0
  159. package/examples/claude-md-reinjector.sh +129 -0
  160. package/examples/claude-md-size-monitor.sh +66 -0
  161. package/examples/claude-update-budget-guard.sh +123 -0
  162. package/examples/claude-update-smart.sh +113 -0
  163. package/examples/claudeignore-enforce-guard.sh +12 -0
  164. package/examples/claudemd-enforcer.sh +0 -0
  165. package/examples/claudemd-tool-prohibition.sh +128 -0
  166. package/examples/clear-command-confirm-guard.sh +32 -15
  167. package/examples/cli-config-pinning-detector.sh +162 -0
  168. package/examples/cliff-countdown-advisor.sh +96 -0
  169. package/examples/clipboard-secret-guard.sh +12 -0
  170. package/examples/closure-word-verify-gate.sh +150 -0
  171. package/examples/cloud-cli-guard.sh +39 -2
  172. package/examples/commit-all-scope-guard.sh +44 -0
  173. package/examples/commit-message-check.sh +1 -1
  174. package/examples/commit-message-quality.sh +6 -1
  175. package/examples/commitment-carry-forward-arrest.sh +361 -0
  176. package/examples/compact-alert-notification.sh +0 -0
  177. package/examples/compact-circuit-breaker.sh +72 -0
  178. package/examples/compact-dispatch-watchdog.sh +149 -0
  179. package/examples/completion-claim-without-verification-detector.sh +207 -0
  180. package/examples/composer-guard.sh +12 -0
  181. package/examples/compound-bash-permission-resolver.sh +156 -0
  182. package/examples/compound-command-allow.sh +1 -1
  183. package/examples/compound-command-deny-enforcer.sh +183 -0
  184. package/examples/compound-inject-guard.sh +12 -0
  185. package/examples/concurrent-edit-lock.sh +12 -0
  186. package/examples/conflict-marker-guard.sh +12 -0
  187. package/examples/consecutive-error-breaker.sh +0 -0
  188. package/examples/console-log-count.sh +1 -0
  189. package/examples/context-compact-advisor.sh +29 -2
  190. package/examples/context-length-budget.sh +69 -0
  191. package/examples/context-threshold-alert.sh +12 -0
  192. package/examples/context-usage-drift-alert.sh +41 -13
  193. package/examples/conversation-history-guard.sh +12 -0
  194. package/examples/core-file-protect-guard.sh +12 -0
  195. package/examples/cors-star-warn.sh +0 -0
  196. package/examples/cost-incident-self-audit.sh +162 -0
  197. package/examples/cowork-claude-md-load-checker.sh +100 -0
  198. package/examples/cowork-fuse-staleness-watcher.sh +140 -0
  199. package/examples/cowork-hook-absence-warner.sh +167 -0
  200. package/examples/cowork-model-picker-advisor.sh +115 -0
  201. package/examples/credential-exfil-guard.sh +65 -4
  202. package/examples/credential-file-cat-guard.sh +17 -1
  203. package/examples/cron-create-receipt.sh +112 -0
  204. package/examples/cron-modification-guard.sh +12 -0
  205. package/examples/cross-product-mcp-spawn-detector.sh +178 -0
  206. package/examples/cwd-project-boundary-guard.sh +0 -0
  207. package/examples/daemon-zombie-worker-surfacer.sh +118 -0
  208. package/examples/daily-cost-guard.sh +164 -0
  209. package/examples/daily-usage-tracker.sh +0 -0
  210. package/examples/dangerous-pip-flag-guard.sh +12 -0
  211. package/examples/db-connect-guard.sh +13 -1
  212. package/examples/denied-action-retry-guard.sh +12 -0
  213. package/examples/deny-bypass-detector.sh +12 -0
  214. package/examples/deny-rule-integrity-verifier.sh +181 -0
  215. package/examples/dependency-install-guard.sh +12 -0
  216. package/examples/deploy-guard.sh +14 -2
  217. package/examples/deploy-path-verify-guard.sh +12 -0
  218. package/examples/deployment-readback-gate.sh +135 -0
  219. package/examples/deployment-readback-gh-adapter.sh +247 -0
  220. package/examples/deployment-verify-guard.sh +25 -2
  221. package/examples/destructive-db-script-write-guard.sh +166 -0
  222. package/examples/destructive-migration-write-guard.sh +163 -0
  223. package/examples/diff-size-guard.sh +12 -0
  224. package/examples/disabled-feature-toggle-advisor.sh +88 -0
  225. package/examples/disk-partition-guard.sh +12 -0
  226. package/examples/dispatch-allowlist-preflight.sh +301 -0
  227. package/examples/dispatch-liveness-watchdog.sh +216 -0
  228. package/examples/dispatch-receipt.sh +174 -0
  229. package/examples/django-migrate-guard.sh +12 -0
  230. package/examples/dns-config-guard.sh +12 -0
  231. package/examples/docker-dangerous-guard.sh +12 -0
  232. package/examples/docker-volume-guard.sh +0 -0
  233. package/examples/dockerfile-latest-guard.sh +1 -0
  234. package/examples/dotenv-anthropic-key-billing-guard.sh +99 -0
  235. package/examples/dotenv-commit-guard.sh +12 -0
  236. package/examples/dotenv-read-guard.sh +12 -0
  237. package/examples/dotfile-protection-guard.sh +12 -0
  238. package/examples/dotnet-build-on-edit.sh +1 -1
  239. package/examples/drizzle-migrate-guard.sh +27 -2
  240. package/examples/echo-probe-spam-detector.sh +176 -0
  241. package/examples/edit-counter-test-gate.sh +12 -0
  242. package/examples/edit-error-counter.sh +1 -1
  243. package/examples/edit-guard.sh +12 -0
  244. package/examples/edit-old-string-validator.sh +12 -0
  245. package/examples/edit-quote-ambiguity-guard.sh +97 -0
  246. package/examples/edit-retry-loop-guard.sh +0 -0
  247. package/examples/edit-verify.sh +0 -0
  248. package/examples/env-inline-secret-guard.sh +14 -2
  249. package/examples/env-naming-convention.sh +0 -0
  250. package/examples/env-prod-guard.sh +0 -0
  251. package/examples/env-required-check.sh +0 -0
  252. package/examples/env-source-guard.sh +12 -0
  253. package/examples/env-var-check.sh +24 -1
  254. package/examples/ephemeral-container-detector.sh +147 -0
  255. package/examples/error-memory-guard.sh +12 -0
  256. package/examples/evidence-claim-gate.sh +187 -0
  257. package/examples/exploration-budget-guard.sh +89 -0
  258. package/examples/expo-eject-guard.sh +13 -0
  259. package/examples/extended-thinking-loop-guard.sh +139 -0
  260. package/examples/extended-thinking-resume-warning.sh +119 -0
  261. package/examples/extended-thinking-tool-use-mismatch-detector.sh +212 -0
  262. package/examples/fabricated-command-detector.sh +145 -0
  263. package/examples/false-disk-full-guard.sh +63 -0
  264. package/examples/feature-deprecation-detector.sh +109 -0
  265. package/examples/file-change-tracker.sh +1 -1
  266. package/examples/file-change-undo-tracker.sh +0 -0
  267. package/examples/file-edit-backup.sh +63 -14
  268. package/examples/file-reference-check.sh +0 -0
  269. package/examples/file-size-limit.sh +12 -0
  270. package/examples/financial-operation-guard.sh +12 -0
  271. package/examples/firewall-guard.sh +12 -0
  272. package/examples/fish-shell-wrapper.sh +125 -7
  273. package/examples/five-hundred-milestone.sh +1 -0
  274. package/examples/flask-static-route-guard.sh +89 -0
  275. package/examples/forbidden-response-phrase-detector.sh +161 -0
  276. package/examples/gem-push-guard.sh +13 -0
  277. package/examples/gh-cli-destructive-guard.sh +13 -1
  278. package/examples/git-checkout-safety-guard.sh +12 -0
  279. package/examples/git-checkout-uncommitted-guard.sh +12 -0
  280. package/examples/git-config-guard.sh +12 -0
  281. package/examples/git-crypt-worktree-guard.sh +12 -0
  282. package/examples/git-filter-repo-guard.sh +56 -0
  283. package/examples/git-history-rewrite-guard.sh +12 -0
  284. package/examples/git-hook-bypass-guard.sh +0 -0
  285. package/examples/git-maintenance-guard.sh +83 -0
  286. package/examples/git-merge-conflict-prevent.sh +0 -0
  287. package/examples/git-message-length-check.sh +0 -0
  288. package/examples/git-message-length.sh +0 -0
  289. package/examples/git-operations-require-approval.sh +68 -14
  290. package/examples/git-pack-temp-cleanup-guard.sh +102 -0
  291. package/examples/git-push-blast-radius-guard.sh +218 -0
  292. package/examples/git-remote-guard.sh +24 -3
  293. package/examples/git-rm-orphan-wipe-guard.sh +85 -0
  294. package/examples/git-stash-before-checkout.sh +12 -0
  295. package/examples/git-stash-before-danger.sh +0 -0
  296. package/examples/git-submodule-guard.sh +69 -2
  297. package/examples/git-tag-guard.sh +12 -0
  298. package/examples/github-actions-secret-guard.sh +0 -0
  299. package/examples/gitignore-check.sh +0 -0
  300. package/examples/gitops-drift-guard.sh +12 -0
  301. package/examples/go-mod-tidy-warn.sh +1 -0
  302. package/examples/go-vet-after-edit.sh +12 -0
  303. package/examples/goal-iteration-limit-warner.sh +152 -0
  304. package/examples/grep-nul-false-negative-guard.sh +30 -0
  305. package/examples/growthbook-flag-monitor.sh +257 -0
  306. package/examples/hallucination-url-check.sh +1 -1
  307. package/examples/halt-signal-detector.sh +135 -0
  308. package/examples/handoff-on-clear.sh +65 -0
  309. package/examples/hardcoded-ip-guard.sh +1 -0
  310. package/examples/headless-empty-result-guard.sh +0 -0
  311. package/examples/headless-stop-guard.sh +0 -0
  312. package/examples/helm-install-guard.sh +2 -1
  313. package/examples/home-critical-bash-guard.sh +17 -1
  314. package/examples/hook-debug-wrapper.sh +6 -2
  315. package/examples/hook-permission-fixer.sh +0 -0
  316. package/examples/hook-self-disable-detector.sh +99 -0
  317. package/examples/hook-stdout-sanitizer.sh +6 -2
  318. package/examples/hook-tamper-guard.sh +12 -0
  319. package/examples/idle-session-cost-alert.sh +0 -0
  320. package/examples/image-dimension-guard.sh +109 -0
  321. package/examples/image-file-validator.sh +0 -0
  322. package/examples/iteration-quality-degradation-detector.sh +170 -0
  323. package/examples/java-compile-on-edit.sh +1 -1
  324. package/examples/json-syntax-check.sh +0 -0
  325. package/examples/k8s-production-guard.sh +13 -1
  326. package/examples/kill-process-guard.sh +12 -0
  327. package/examples/kubernetes-guard.sh +13 -1
  328. package/examples/laravel-artisan-guard.sh +13 -0
  329. package/examples/large-file-guard.sh +1 -1
  330. package/examples/log-level-guard.sh +0 -0
  331. package/examples/log-truncation-guard.sh +12 -0
  332. package/examples/long-session-malformed-tool-call-detector.sh +183 -0
  333. package/examples/loop-detector.sh +12 -0
  334. package/examples/magic-number-warn.sh +1 -0
  335. package/examples/main-branch-warn.sh +12 -0
  336. package/examples/markdown-link-check.sh +0 -0
  337. package/examples/max-concurrent-agents.sh +12 -0
  338. package/examples/max-edit-size-guard.sh +13 -0
  339. package/examples/max-file-count-guard.sh +0 -0
  340. package/examples/max-file-delete-count.sh +0 -0
  341. package/examples/max-function-length.sh +1 -0
  342. package/examples/max-import-count.sh +0 -0
  343. package/examples/max-subagent-count.sh +0 -0
  344. package/examples/mcp-config-freeze.sh +12 -0
  345. package/examples/mcp-config-poisoning-audit.sh +150 -0
  346. package/examples/mcp-data-boundary.sh +1 -1
  347. package/examples/mcp-misdiagnosis-arrest.sh +209 -0
  348. package/examples/mcp-orphan-leak-warner.sh +49 -0
  349. package/examples/mcp-permissions-ask-warner.sh +151 -0
  350. package/examples/mcp-routine-approval-detector.sh +154 -0
  351. package/examples/mcp-server-allowlist.sh +12 -0
  352. package/examples/mcp-server-guard.sh +12 -0
  353. package/examples/mcp-startup-bloat-detector.sh +87 -0
  354. package/examples/mcp-stdio-compatibility-test.sh +153 -0
  355. package/examples/mcp-tool-audit-log.sh +0 -0
  356. package/examples/mcp-tool-guard.sh +101 -1
  357. package/examples/mcp-warmup-wait.sh +0 -0
  358. package/examples/memory-chain-audit.sh +56 -0
  359. package/examples/memory-orphan-detector.sh +188 -0
  360. package/examples/memory-write-guard.sh +99 -17
  361. package/examples/migration-verify-guard.sh +12 -0
  362. package/examples/model-swap-suggester.sh +177 -0
  363. package/examples/model-version-alert.sh +5 -1
  364. package/examples/model-version-lock.sh +63 -0
  365. package/examples/move-delete-sequence-guard.sh +33 -2
  366. package/examples/multi-file-plan-routing-gate.sh +192 -0
  367. package/examples/multi-vendor-concurrent-warner.sh +108 -0
  368. package/examples/multi-window-auth-drift-detector.sh +183 -0
  369. package/examples/multiline-command-approver.sh +161 -23
  370. package/examples/nested-background-agent-guard.sh +109 -0
  371. package/examples/nested-spawn-inflight-guard.sh +178 -0
  372. package/examples/network-exfil-guard.sh +12 -0
  373. package/examples/network-guard.sh +12 -0
  374. package/examples/network-interface-guard.sh +12 -0
  375. package/examples/nextjs-env-guard.sh +1 -1
  376. package/examples/no-absolute-import.sh +0 -0
  377. package/examples/no-alert-confirm-prompt.sh +0 -0
  378. package/examples/no-anonymous-default-export.sh +0 -0
  379. package/examples/no-any-type.sh +0 -0
  380. package/examples/no-any-typescript.sh +1 -0
  381. package/examples/no-ask-human.sh +12 -0
  382. package/examples/no-assignment-in-condition.sh +0 -0
  383. package/examples/no-base64-exfil.sh +12 -0
  384. package/examples/no-callback-hell.sh +0 -0
  385. package/examples/no-circular-dependency.sh +0 -0
  386. package/examples/no-cleartext-storage.sh +0 -0
  387. package/examples/no-commented-code.sh +0 -0
  388. package/examples/no-commit-fixup.sh +0 -0
  389. package/examples/no-console-assert.sh +0 -0
  390. package/examples/no-console-error-swallow.sh +0 -0
  391. package/examples/no-console-in-prod.sh +0 -0
  392. package/examples/no-console-log-commit.sh +12 -0
  393. package/examples/no-console-log.sh +0 -0
  394. package/examples/no-console-time.sh +0 -0
  395. package/examples/no-cors-wildcard.sh +4 -1
  396. package/examples/no-curl-upload.sh +0 -0
  397. package/examples/no-dangerouslySetInnerHTML.sh +0 -0
  398. package/examples/no-dangling-await.sh +1 -0
  399. package/examples/no-debug-commit.sh +12 -0
  400. package/examples/no-debug-in-commit.sh +0 -0
  401. package/examples/no-deep-nesting.sh +0 -0
  402. package/examples/no-deep-relative-import.sh +1 -0
  403. package/examples/no-default-credentials.sh +0 -0
  404. package/examples/no-deploy-friday.sh +13 -1
  405. package/examples/no-disabled-test.sh +0 -0
  406. package/examples/no-document-write.sh +0 -0
  407. package/examples/no-empty-function.sh +0 -0
  408. package/examples/no-eval-in-template.sh +0 -0
  409. package/examples/no-eval-template.sh +3 -1
  410. package/examples/no-eval.sh +0 -0
  411. package/examples/no-exec-user-input.sh +0 -0
  412. package/examples/no-fixme-ship.sh +12 -0
  413. package/examples/no-floating-promises.sh +0 -0
  414. package/examples/no-force-flag.sh +22 -5
  415. package/examples/no-force-install.sh +0 -0
  416. package/examples/no-git-amend.sh +12 -0
  417. package/examples/no-git-rebase-public.sh +0 -0
  418. package/examples/no-global-install.sh +12 -0
  419. package/examples/no-global-state.sh +0 -0
  420. package/examples/no-hardcoded-port.sh +1 -0
  421. package/examples/no-hardcoded-url.sh +0 -0
  422. package/examples/no-helmet-missing.sh +0 -0
  423. package/examples/no-http-url.sh +1 -0
  424. package/examples/no-http-without-https.sh +0 -0
  425. package/examples/no-inline-style.sh +0 -0
  426. package/examples/no-inline-styles.sh +1 -0
  427. package/examples/no-innerhtml.sh +0 -0
  428. package/examples/no-install-global.sh +12 -0
  429. package/examples/no-jwt-in-url.sh +0 -0
  430. package/examples/no-large-commit.sh +0 -0
  431. package/examples/no-localhost-expose.sh +0 -0
  432. package/examples/no-magic-number.sh +0 -0
  433. package/examples/no-md5-sha1.sh +0 -0
  434. package/examples/no-mixed-line-endings.sh +8 -1
  435. package/examples/no-mutation-in-reducer.sh +0 -0
  436. package/examples/no-nested-ternary.sh +0 -0
  437. package/examples/no-network-exfil.sh +0 -0
  438. package/examples/no-open-redirect.sh +0 -0
  439. package/examples/no-output-truncation.sh +12 -0
  440. package/examples/no-package-downgrade.sh +0 -0
  441. package/examples/no-package-lock-edit.sh +12 -0
  442. package/examples/no-path-join-user-input.sh +0 -0
  443. package/examples/no-port-bind.sh +0 -0
  444. package/examples/no-process-exit.sh +0 -0
  445. package/examples/no-prototype-pollution.sh +0 -0
  446. package/examples/no-push-without-ci.sh +0 -0
  447. package/examples/no-push-without-tests.sh +12 -0
  448. package/examples/no-raw-password-in-url.sh +0 -0
  449. package/examples/no-root-user-docker.sh +1 -0
  450. package/examples/no-root-write.sh +12 -0
  451. package/examples/no-secrets-in-args.sh +4 -1
  452. package/examples/no-secrets-in-logs.sh +0 -0
  453. package/examples/no-sensitive-log.sh +0 -0
  454. package/examples/no-sleep-in-hooks.sh +0 -0
  455. package/examples/no-star-import-python.sh +1 -0
  456. package/examples/no-string-concat-sql.sh +0 -0
  457. package/examples/no-sudo-guard.sh +12 -0
  458. package/examples/no-sync-fs.sh +0 -0
  459. package/examples/no-todo-in-merge.sh +0 -0
  460. package/examples/no-todo-in-production.sh +1 -0
  461. package/examples/no-todo-without-issue.sh +0 -0
  462. package/examples/no-unused-import.sh +0 -0
  463. package/examples/no-var-keyword.sh +0 -0
  464. package/examples/no-verify-blocker.sh +12 -0
  465. package/examples/no-wget-piped-bash.sh +12 -0
  466. package/examples/no-wildcard-cors.sh +0 -0
  467. package/examples/no-wildcard-delete.sh +0 -0
  468. package/examples/no-wildcard-import.sh +0 -0
  469. package/examples/no-with-statement.sh +0 -0
  470. package/examples/no-write-outside-src.sh +0 -0
  471. package/examples/no-xml-external-entity.sh +0 -0
  472. package/examples/non-english-quality-warner.sh +156 -0
  473. package/examples/notify-waiting.sh +1 -1
  474. package/examples/npm-audit-warn.sh +0 -0
  475. package/examples/npm-global-install-guard.sh +12 -0
  476. package/examples/npm-publish-guard.sh +12 -0
  477. package/examples/npm-script-injection.sh +0 -0
  478. package/examples/npm-supply-chain-guard.sh +0 -0
  479. package/examples/nuxt-config-guard.sh +1 -0
  480. package/examples/oauth-refresh-monitor.sh +210 -0
  481. package/examples/opus-degradation-tracker.sh +187 -0
  482. package/examples/opus48-routine-task-warning.sh +196 -0
  483. package/examples/opus48-thinking-wedge-advisor.sh +143 -0
  484. package/examples/output-credential-scan.sh +1 -1
  485. package/examples/output-secret-mask.sh +31 -9
  486. package/examples/output-token-spike-detector.sh +145 -0
  487. package/examples/package-json-guard.sh +12 -0
  488. package/examples/package-lock-frozen.sh +12 -0
  489. package/examples/parallel-batch-size-limiter.sh +121 -0
  490. package/examples/parallel-cascade-detector.sh +116 -0
  491. package/examples/partial-view-claim-arrest.sh +174 -0
  492. package/examples/path-deny-bash-guard.sh +12 -0
  493. package/examples/path-traversal-guard.sh +12 -0
  494. package/examples/per-prompt-token-cap.sh +124 -0
  495. package/examples/permission-audit-log.sh +1 -1
  496. package/examples/permission-denial-enforcer.sh +12 -0
  497. package/examples/permission-entry-validator.sh +0 -0
  498. package/examples/persisted-1m-model-advisor.sh +88 -0
  499. package/examples/php-lint-on-edit.sh +1 -1
  500. package/examples/pii-upload-guard.sh +12 -0
  501. package/examples/pip-publish-guard.sh +13 -0
  502. package/examples/pip-requirements-guard.sh +12 -0
  503. package/examples/pip-venv-required.sh +12 -0
  504. package/examples/plan-mode-edit-guard.sh +12 -0
  505. package/examples/plan-mode-enforcer.sh +12 -0
  506. package/examples/plan-mode-strict-guard.sh +12 -0
  507. package/examples/plugin-hooks-json-bloat-detector.sh +169 -0
  508. package/examples/plugin-process-cleanup.sh +0 -0
  509. package/examples/polyglot-rm-guard.sh +12 -0
  510. package/examples/post-compact-safety.sh +12 -0
  511. package/examples/post-edit-disk-verify.sh +152 -0
  512. package/examples/powershell-remove-item-guard.sh +85 -0
  513. package/examples/pr-description-check.sh +0 -0
  514. package/examples/pr-duplicate-guard.sh +13 -0
  515. package/examples/pre-bash-sed-line-ending-windows.sh +87 -0
  516. package/examples/pre-compact-knowledge-save.sh +0 -0
  517. package/examples/pre-compact-transcript-backup.sh +0 -0
  518. package/examples/pre-execution-claim-detector.sh +179 -0
  519. package/examples/prefer-builtin-tools.sh +10 -1
  520. package/examples/prefer-const.sh +0 -0
  521. package/examples/prefer-dedicated-tools.sh +12 -0
  522. package/examples/prefer-optional-chaining.sh +0 -0
  523. package/examples/prisma-migrate-guard.sh +24 -7
  524. package/examples/production-port-kill-guard.sh +12 -0
  525. package/examples/prompt-injection-guard.sh +2 -1
  526. package/examples/prompt-usage-logger.sh +0 -0
  527. package/examples/protect-claudemd.sh +12 -0
  528. package/examples/protect-dotfiles.sh +12 -0
  529. package/examples/proxy-capture-suggester.sh +159 -0
  530. package/examples/public-artefact-socratic-narrowing.sh +232 -0
  531. package/examples/public-repo-push-guard.sh +12 -0
  532. package/examples/push-requires-test-pass-record.sh +0 -0
  533. package/examples/push-requires-test-pass.sh +12 -0
  534. package/examples/quota-anomaly-detector.sh +173 -0
  535. package/examples/quota-reset-audit.sh +58 -0
  536. package/examples/quoted-flag-approver.sh +99 -10
  537. package/examples/rails-migration-guard.sh +12 -0
  538. package/examples/rate-limit-guard.sh +0 -0
  539. package/examples/read-all-files-enforcer.sh +0 -0
  540. package/examples/read-budget-guard.sh +12 -0
  541. package/examples/read-loop-detector.sh +59 -0
  542. package/examples/read-once-guard.sh +96 -0
  543. package/examples/read-only-mode.sh +12 -0
  544. package/examples/readme-exists-check.sh +0 -0
  545. package/examples/record-read-coverage.sh +73 -0
  546. package/examples/redirect-fragment-warner.sh +149 -0
  547. package/examples/redis-flushall-guard.sh +13 -0
  548. package/examples/redundant-read-blocker.sh +132 -0
  549. package/examples/refusal-arrest-gate.sh +248 -0
  550. package/examples/registry-publish-guard.sh +13 -1
  551. package/examples/remote-control-billing-classifier.sh +135 -0
  552. package/examples/replace-all-guard.sh +12 -0
  553. package/examples/repo-visibility-guard.sh +12 -0
  554. package/examples/reroute-after-block-guard.sh +150 -0
  555. package/examples/response-budget-guard.sh +0 -0
  556. package/examples/resume-drift-watcher.sh +57 -0
  557. package/examples/rg-replace-flag-detector.sh +125 -0
  558. package/examples/rhetorical-verification-prompt-detector.sh +102 -0
  559. package/examples/ripgrep-permission-fix.sh +0 -0
  560. package/examples/rm-safety-net.sh +151 -8
  561. package/examples/role-tool-guard.sh +12 -0
  562. package/examples/route-handler-emptiness-gate.sh +324 -0
  563. package/examples/ruby-lint-on-edit.sh +1 -1
  564. package/examples/runtime-binary-change-detector.sh +102 -0
  565. package/examples/same-command-repeat-detector.sh +196 -0
  566. package/examples/same-correction-arrest.sh +169 -0
  567. package/examples/sandbox-denywrite-enforcer.sh +78 -0
  568. package/examples/sandbox-relative-path-audit.sh +83 -25
  569. package/examples/sandbox-write-verify.sh +12 -0
  570. package/examples/schema-migration-guard.sh +0 -0
  571. package/examples/scope-expansion-receipt.sh +178 -0
  572. package/examples/scope-guard.sh +88 -9
  573. package/examples/secret-file-read-guard.sh +12 -0
  574. package/examples/secret-file-write-guard.sh +150 -0
  575. package/examples/self-modify-bypass-guard.sh +0 -0
  576. package/examples/sensitive-file-read-guard.sh +23 -3
  577. package/examples/sensitive-log-guard.sh +1 -0
  578. package/examples/server-side-prompt-injection-detector.sh +69 -0
  579. package/examples/session-agent-cost-limiter.sh +12 -0
  580. package/examples/session-backup-on-start.sh +1 -1
  581. package/examples/session-cost-alert.sh +12 -0
  582. package/examples/session-drift-guard.sh +12 -0
  583. package/examples/session-duration-guard.sh +25 -2
  584. package/examples/session-end-logger.sh +0 -0
  585. package/examples/session-health-monitor.sh +0 -0
  586. package/examples/session-index-repair.sh +1 -1
  587. package/examples/session-memory-watchdog.sh +1 -0
  588. package/examples/session-permission-reset-guard.sh +12 -0
  589. package/examples/session-persistence-verifier.sh +93 -0
  590. package/examples/session-plugin-pin-watch.sh +68 -0
  591. package/examples/session-rate-monitor.sh +176 -0
  592. package/examples/session-resume-env-fix.sh +0 -0
  593. package/examples/session-start-quota-status.sh +193 -0
  594. package/examples/session-start-safety-check.sh +55 -3
  595. package/examples/session-state-saver.sh +0 -0
  596. package/examples/session-summary-stop.sh +1 -1
  597. package/examples/session-summary.sh +0 -0
  598. package/examples/session-token-counter.sh +1 -1
  599. package/examples/settings-hooks-key-restorer.sh +99 -0
  600. package/examples/settings-json-health-check.sh +57 -0
  601. package/examples/settings-json-model-guard.sh +0 -0
  602. package/examples/settings-regression-tester.sh +188 -0
  603. package/examples/shell-config-truncation-guard.sh +12 -0
  604. package/examples/shell-wrapper-guard.sh +12 -0
  605. package/examples/skill-cumulative-size-detector.sh +104 -0
  606. package/examples/skill-description-drop-detector.sh +148 -0
  607. package/examples/skill-gate.sh +0 -0
  608. package/examples/skill-truncation-detector.sh +154 -0
  609. package/examples/skills-context-recorder.sh +167 -0
  610. package/examples/skills-load-verifier.sh +96 -0
  611. package/examples/skills-settings-validator.sh +139 -0
  612. package/examples/sonnet-45-deprecation-helper.sh +85 -0
  613. package/examples/spec-file-scope-guard.sh +12 -0
  614. package/examples/spring-profile-guard.sh +1 -0
  615. package/examples/spurious-malformed-notice-detector.sh +247 -0
  616. package/examples/sql-bulk-delete-warn.sh +88 -0
  617. package/examples/sql-injection-detect.sh +0 -0
  618. package/examples/ssh-key-protect.sh +12 -0
  619. package/examples/staged-secret-scan.sh +22 -1
  620. package/examples/stale-temp-settings-detector.sh +86 -0
  621. package/examples/standing-rule-session-surfacer.sh +137 -0
  622. package/examples/stop-hook-sigterm-wrapper.sh +182 -0
  623. package/examples/stop-transcript-write-health.sh +64 -0
  624. package/examples/strict-allowlist.sh +57 -15
  625. package/examples/strip-coauthored-by.sh +50 -10
  626. package/examples/subagent-blast-radius-guard.sh +184 -0
  627. package/examples/subagent-boundary-precheck.sh +126 -0
  628. package/examples/subagent-budget-guard.sh +12 -0
  629. package/examples/subagent-claudemd-inject.sh +0 -0
  630. package/examples/subagent-closure-verify-gate.sh +164 -0
  631. package/examples/subagent-destructive-git-guard.sh +120 -0
  632. package/examples/subagent-error-detector.sh +0 -0
  633. package/examples/subagent-forged-system-reminder-guard.sh +156 -0
  634. package/examples/subagent-identity-leak-guard.sh +102 -0
  635. package/examples/subagent-identity-reassertion.sh +51 -0
  636. package/examples/subagent-inheritance-tester.sh +179 -0
  637. package/examples/subagent-permission-mode-guard.sh +110 -0
  638. package/examples/subagent-scope-guard.sh +12 -0
  639. package/examples/subagent-spawn-verification-enforcer.sh +102 -0
  640. package/examples/subagent-tool-allowlist-enforcer.sh +101 -0
  641. package/examples/subagent-tool-call-limiter.sh +87 -15
  642. package/examples/subcommand-chain-guard.sh +12 -0
  643. package/examples/subscription-api-billing-warner.sh +160 -0
  644. package/examples/subscription-bypass-detector.sh +152 -0
  645. package/examples/svelte-lint-on-edit.sh +1 -0
  646. package/examples/swift-build-on-edit.sh +1 -1
  647. package/examples/symlink-guard.sh +27 -2
  648. package/examples/symlink-protect.sh +1 -0
  649. package/examples/system-dir-protection-guard.sh +73 -8
  650. package/examples/system-message-workaround.sh +38 -13
  651. package/examples/system-package-guard.sh +12 -0
  652. package/examples/systemd-service-guard.sh +12 -0
  653. package/examples/task-integrity-guard.sh +12 -0
  654. package/examples/temp-file-cleanup.sh +1 -1
  655. package/examples/temporal-suggestion-detector.sh +135 -0
  656. package/examples/terraform-guard.sh +27 -6
  657. package/examples/test-after-edit.sh +1 -1
  658. package/examples/test-before-push.sh +12 -0
  659. package/examples/test-coverage-reminder.sh +24 -1
  660. package/examples/thinking-budget-effort-mismatch-detector.sh +149 -0
  661. package/examples/thinking-stall-detector.sh +61 -0
  662. package/examples/timezone-guard.sh +0 -0
  663. package/examples/tmp-output-size-guard.sh +0 -0
  664. package/examples/todo-check.sh +1 -1
  665. package/examples/token-budget-guard.sh +12 -0
  666. package/examples/token-budget-per-task.sh +12 -0
  667. package/examples/token-usage-tracker.sh +7 -1
  668. package/examples/tokenizer-ratio-alert-corpus.sh +90 -0
  669. package/examples/tokenizer-ratio-alert.sh +104 -0
  670. package/examples/tool-call-rate-limiter.sh +0 -0
  671. package/examples/tool-result-correlation-checker.sh +167 -0
  672. package/examples/tool-result-size-guard.sh +132 -0
  673. package/examples/tool-retry-budget-guard.sh +12 -0
  674. package/examples/transcript-contamination-detector.sh +138 -0
  675. package/examples/trustfall-mcp-injection-guard.sh +103 -0
  676. package/examples/ultrareview-large-diff-advisor.sh +184 -0
  677. package/examples/unbounded-output-guard.sh +94 -0
  678. package/examples/uncommitted-changes-stop.sh +1 -0
  679. package/examples/uncommitted-discard-guard.sh +23 -5
  680. package/examples/uncommitted-work-guard.sh +12 -0
  681. package/examples/usage-warn.sh +0 -0
  682. package/examples/user-account-guard.sh +12 -0
  683. package/examples/userprompt-submit-receipt.sh +123 -0
  684. package/examples/variable-expansion-guard.sh +12 -0
  685. package/examples/verify-after-publish-reminder.sh +93 -0
  686. package/examples/verify-before-commit.sh +12 -0
  687. package/examples/version-bump-detector.sh +156 -0
  688. package/examples/version-regression-warner.sh +144 -0
  689. package/examples/vue-lint-on-edit.sh +1 -0
  690. package/examples/warn-cron-cost-trap.sh +173 -0
  691. package/examples/webfetch-runaway-guard.sh +89 -0
  692. package/examples/wellness-break-reminder.sh +118 -0
  693. package/examples/windows-destructive-command-guard.sh +177 -0
  694. package/examples/windows-path-guard.sh +12 -0
  695. package/examples/windows-python-stub-detector.sh +63 -0
  696. package/examples/work-hours-guard.sh +12 -0
  697. package/examples/working-directory-fence.sh +12 -0
  698. package/examples/workspace-lease-guard.sh +205 -0
  699. package/examples/worktree-create-log.sh +1 -0
  700. package/examples/worktree-delete-guard.sh +12 -0
  701. package/examples/worktree-edit-boundary-guard.sh +127 -0
  702. package/examples/worktree-escape-write-guard.sh +114 -0
  703. package/examples/worktree-hook-linker.sh +0 -0
  704. package/examples/worktree-hooks-path-fix.sh +111 -0
  705. package/examples/worktree-parent-write-guard.sh +43 -0
  706. package/examples/worktree-project-unify.sh +2 -1
  707. package/examples/worktree-remove-uncommitted-guard.sh +13 -0
  708. package/examples/worktree-unmerged-guard.sh +7 -1
  709. package/examples/write-byte-integrity-verifier.sh +190 -0
  710. package/examples/write-empty-content-guard.sh +67 -0
  711. package/examples/write-nul-corruption-detector.sh +61 -0
  712. package/examples/write-overwrite-confirm.sh +160 -14
  713. package/examples/write-secret-guard.sh +27 -5
  714. package/examples/write-shrink-guard.sh +12 -0
  715. package/examples/write-test-ratio.sh +0 -0
  716. package/examples/wsl-host-disk-space-guard.sh +97 -0
  717. package/examples/xml-format-leak-detector.sh +266 -0
  718. package/examples/yaml-syntax-check.sh +12 -0
  719. package/hooks/hooks.json +6 -6
  720. package/index.mjs +1699 -183
  721. package/mission.md +2 -0
  722. package/package.json +4 -4
  723. package/plugins/credential-guard/.claude-plugin/plugin.json +9 -7
  724. package/plugins/git-protection/.claude-plugin/plugin.json +10 -8
  725. package/plugins/safety-essentials/.claude-plugin/plugin.json +9 -7
  726. package/plugins/token-guard/.claude-plugin/plugin.json +10 -8
  727. package/scripts/agents-md-sync-setup.sh +156 -0
  728. package/scripts/autonomy-blocked-summary.sh +148 -0
  729. package/scripts/build-search-index.py +43 -0
  730. package/scripts/build-sitemap.py +119 -0
  731. package/scripts/cc-doctor.sh +192 -0
  732. package/scripts/check-hook-event-names.py +127 -0
  733. package/scripts/check-misfire-instrument.sh +64 -0
  734. package/scripts/claim-verify-audit.sh +467 -0
  735. package/scripts/cowork-claudemd-helper.sh +136 -0
  736. package/scripts/june-15-deprecated-model-scan.sh +111 -0
  737. package/scripts/measure-heredoc-shapes.sh +67 -0
  738. package/scripts/measure-literal-match-misfire.sh +110 -0
  739. package/scripts/probe-scope-guard-branches.sh +48 -0
  740. package/scripts/probe-skip-line-both-ways.sh +65 -0
  741. package/scripts/receipts-aggregate.py +199 -0
  742. package/scripts/session-forensic-audit.py +360 -0
  743. package/scripts.json +9 -9
  744. package/scripts.json.bak-2026-07-27-find +13 -0
  745. package/skills/safety-setup/SKILL.md +5 -5
  746. package/tests/approve-side-remaining-two.test.sh +129 -0
  747. package/tests/approver-list-granularity.test.sh +145 -0
  748. package/tests/askuserquestion-autonomy-gate.test.sh +181 -0
  749. package/tests/audit-ci-gate.test.sh +87 -0
  750. package/tests/audit-cross-layer-claudemd.test.sh +170 -0
  751. package/tests/audit-fail-open-parse.test.sh +100 -0
  752. package/tests/auto-approve-compound-tail.test.sh +194 -0
  753. package/tests/auto-mode-path-invoked-commands.test.sh +89 -0
  754. package/tests/auto-mode-quoted-targets.test.sh +127 -0
  755. package/tests/auto-mode-unquoted-targets.test.sh +112 -0
  756. package/tests/bash-secret-output-detector-detects.test.sh +102 -0
  757. package/tests/blindspots-cross-layer.test.sh +177 -0
  758. package/tests/block-database-wipe.test.sh +64 -0
  759. package/tests/bundled-short-flags-bypass.test.sh +85 -0
  760. package/tests/cd-git-allow-compound-tail.test.sh +67 -0
  761. package/tests/chown-guard-filesystem-root.test.sh +64 -0
  762. package/tests/ci-workflow-guard-skip-rule.test.sh +115 -0
  763. package/tests/compound-deny-safe-rm-targets.test.sh +105 -0
  764. package/tests/core-scripts-parser-fallback.test.sh +140 -0
  765. package/tests/destructive-guard-bare-glob.test.sh +74 -0
  766. package/tests/destructive-guard-every-operand.test.sh +100 -0
  767. package/tests/destructive-guard-find-deletion.test.sh +114 -0
  768. package/tests/destructive-guard-flag-order.test.sh +106 -0
  769. package/tests/destructive-guard-mentions-vs-invocations.test.sh +107 -0
  770. package/tests/destructive-guard-quoted-target.test.sh +89 -0
  771. package/tests/destructive-guard-separators.test.sh +105 -0
  772. package/tests/destructive-guard-variable-target.test.sh +98 -0
  773. package/tests/destructive-guard-wrapped-command.test.sh +91 -0
  774. package/tests/doctor-hook-disabling-env.test.sh +92 -0
  775. package/tests/doctor-misspelled-settings-keys.test.sh +106 -0
  776. package/tests/example-guards-wrapped-command.test.sh +169 -0
  777. package/tests/file-edit-backup.test.sh +93 -0
  778. package/tests/git-filter-repo-guard.test.sh +60 -0
  779. package/tests/git-global-options-bypass.test.sh +141 -0
  780. package/tests/git-invocation-prefixes-all-guards.test.sh +114 -0
  781. package/tests/git-maintenance-guard.test.sh +83 -0
  782. package/tests/git-pack-temp-cleanup-guard.test.sh +133 -0
  783. package/tests/git-rm-orphan-wipe-guard.test.sh +66 -0
  784. package/tests/git-submodule-guard.test.sh +50 -0
  785. package/tests/grep-pcre-portability.test.sh +155 -0
  786. package/tests/hook-registration-matches-input.test.sh +73 -0
  787. package/tests/hook-trigger-matches-envelope.test.sh +178 -0
  788. package/tests/install-does-not-claim-protection.test.sh +110 -0
  789. package/tests/install-example-standalone-tools.test.sh +139 -0
  790. package/tests/line-continuation-bypass.test.sh +114 -0
  791. package/tests/mcp-config-poisoning-audit.test.sh +106 -0
  792. package/tests/nested-background-agent-guard.test.sh +58 -0
  793. package/tests/no-unqualified-safety-claims.test.sh +114 -0
  794. package/tests/option-eating-grep-patterns.test.sh +130 -0
  795. package/tests/outdated-core-guards.test.sh +134 -0
  796. package/tests/outdated-report.test.sh +155 -0
  797. package/tests/output-secret-mask-warns.test.sh +73 -0
  798. package/tests/plugin-hooks-fail-open-under-sh.test.sh +165 -0
  799. package/tests/plugins-word-order.test.sh +126 -0
  800. package/tests/powershell-remove-item-guard.test.sh +85 -0
  801. package/tests/project-dir-naming.test.sh +103 -0
  802. package/tests/quoted-safe-targets-and-mentions.test.sh +190 -0
  803. package/tests/reroute-after-block-guard.test.sh +104 -0
  804. package/tests/secret-guard-documented-promises.test.sh +97 -0
  805. package/tests/session-plugin-pin-watch.test.sh +45 -0
  806. package/tests/settings-unreadable-refuses-to-write.test.sh +95 -0
  807. package/tests/shield-no-silent-adoption.test.py +110 -0
  808. package/tests/shield-no-silent-adoption.test.sh +46 -0
  809. package/tests/stop-transcript-write-health.test.sh +46 -0
  810. package/tests/system-dir-guard-root-erased.test.sh +66 -0
  811. package/tests/test-account-billing-log.sh +100 -0
  812. package/tests/test-account-routing-preflight.sh +77 -0
  813. package/tests/test-agent-sdk-credit-pool-monitor.sh +157 -0
  814. package/tests/test-agent-view-quota-warn.sh +184 -0
  815. package/tests/test-agents-md-edit-drift-warner.sh +176 -0
  816. package/tests/test-agents-md-loader.sh +204 -0
  817. package/tests/test-agents-md-sync-checker.sh +125 -0
  818. package/tests/test-ai-slop-punctuation-arrest.sh +280 -0
  819. package/tests/test-allowlist.sh +60 -0
  820. package/tests/test-always-allow-pattern-suggester.sh +147 -0
  821. package/tests/test-anthropic-base-url-guard.sh +88 -0
  822. package/tests/test-articulated-scope-capture.sh +139 -0
  823. package/tests/test-attachment-traversal-guard.sh +168 -0
  824. package/tests/test-aup-block-pattern-logger.sh +315 -0
  825. package/tests/test-aup-false-positive-helper.sh +188 -0
  826. package/tests/test-aup-large-tool-output-warner.sh +370 -0
  827. package/tests/test-aup-retry-loop-guard.sh +341 -0
  828. package/tests/test-auth-expiry-reminder.sh +303 -0
  829. package/tests/test-auth-macos-sleep-detector.sh +254 -0
  830. package/tests/test-auth-path-detector.sh +232 -0
  831. package/tests/test-auth-status-checker.sh +233 -0
  832. package/tests/test-authorized-reconfirmation-detector.sh +280 -0
  833. package/tests/test-background-cost-launch-guard.sh +62 -0
  834. package/tests/test-bash-allowlist-secondary-check.sh +143 -0
  835. package/tests/test-bash-fanout-bounded-rewriter.sh +186 -0
  836. package/tests/test-bash-project-fence.sh +127 -0
  837. package/tests/test-bg-permission-prompt-warner.sh +221 -0
  838. package/tests/test-binary-read-detector.sh +173 -0
  839. package/tests/test-broad-prefix-session-trap-warner.sh +167 -0
  840. package/tests/test-bulk-delete-target-resolution.sh +49 -0
  841. package/tests/test-bypass-mode-effective-verifier.sh +179 -0
  842. package/tests/test-cache-creation-drift-detector.sh +244 -0
  843. package/tests/test-cache-residue-detector.sh +429 -0
  844. package/tests/test-cache-tier-logger.sh +59 -0
  845. package/tests/test-cache-ttl-eviction-detector.sh +282 -0
  846. package/tests/test-cch-sentinel-precommit-guard.sh +64 -0
  847. package/tests/test-claim-verify-detector.sh +222 -0
  848. package/tests/test-claim-vs-caveat-checker.sh +134 -0
  849. package/tests/test-claude-code-version-pin-advisor.sh +353 -0
  850. package/tests/test-claude-md-reinjector.sh +173 -0
  851. package/tests/test-claude-md-size-monitor.sh +107 -0
  852. package/tests/test-claude-update-budget-guard.sh +132 -0
  853. package/tests/test-claude-update-smart.sh +91 -0
  854. package/tests/test-claudemd-tool-prohibition.sh +239 -0
  855. package/tests/test-cli-config-pinning-detector.sh +233 -0
  856. package/tests/test-cliff-countdown-advisor.sh +138 -0
  857. package/tests/test-closure-word-verify-gate.sh +158 -0
  858. package/tests/test-commit-all-scope-guard.sh +73 -0
  859. package/tests/test-commitment-carry-forward-arrest.sh +250 -0
  860. package/tests/test-compact-circuit-breaker.sh +134 -0
  861. package/tests/test-compact-dispatch-watchdog.sh +147 -0
  862. package/tests/test-completion-claim-without-verification-detector.sh +326 -0
  863. package/tests/test-compound-bash-permission-resolver.sh +264 -0
  864. package/tests/test-compound-command-deny-enforcer.sh +67 -0
  865. package/tests/test-context-length-budget.sh +68 -0
  866. package/tests/test-context-usage-drift-alert.sh +52 -22
  867. package/tests/test-cost-incident-self-audit.sh +94 -0
  868. package/tests/test-cowork-claude-md-load-checker.sh +257 -0
  869. package/tests/test-cowork-claudemd-helper.sh +141 -0
  870. package/tests/test-cowork-fuse-staleness-watcher.sh +287 -0
  871. package/tests/test-cowork-hook-absence-warner.sh +230 -0
  872. package/tests/test-cowork-model-picker-advisor.sh +317 -0
  873. package/tests/test-credential-exfil-guard.sh +62 -0
  874. package/tests/test-cron-create-receipt.sh +165 -0
  875. package/tests/test-cross-product-mcp-spawn-detector.sh +112 -0
  876. package/tests/test-daemon-zombie-worker-surfacer.sh +71 -0
  877. package/tests/test-daily-cost-guard.sh +131 -0
  878. package/tests/test-deny-rule-integrity-verifier.sh +288 -0
  879. package/tests/test-deployment-readback-gate.sh +92 -0
  880. package/tests/test-deployment-readback-gh-adapter.sh +163 -0
  881. package/tests/test-disabled-feature-toggle-advisor.sh +78 -0
  882. package/tests/test-dispatch-allowlist-preflight.sh +385 -0
  883. package/tests/test-dispatch-liveness-watchdog.sh +319 -0
  884. package/tests/test-dispatch-receipt.sh +314 -0
  885. package/tests/test-dotenv-anthropic-key-billing-guard.sh +160 -0
  886. package/tests/test-echo-probe-spam-detector.sh +143 -0
  887. package/tests/test-edit-quote-ambiguity-guard.sh +75 -0
  888. package/tests/test-ephemeral-container-detector.sh +251 -0
  889. package/tests/test-evidence-claim-gate.sh +291 -0
  890. package/tests/test-exploration-budget-guard.sh +164 -0
  891. package/tests/test-extended-thinking-loop-guard.sh +289 -0
  892. package/tests/test-extended-thinking-resume-warning.sh +240 -0
  893. package/tests/test-extended-thinking-tool-use-mismatch-detector.sh +236 -0
  894. package/tests/test-fabricated-command-detector.sh +296 -0
  895. package/tests/test-false-disk-full-guard.sh +36 -0
  896. package/tests/test-feature-deprecation-detector.sh +117 -0
  897. package/tests/test-forbidden-response-phrase-detector.sh +246 -0
  898. package/tests/test-git-operations-require-approval.sh +53 -0
  899. package/tests/test-git-push-blast-radius-guard.sh +115 -0
  900. package/tests/test-goal-iteration-limit-warner.sh +128 -0
  901. package/tests/test-growthbook-flag-monitor.sh +428 -0
  902. package/tests/test-halt-signal-detector.sh +120 -0
  903. package/tests/test-hook-self-disable-detector.sh +232 -0
  904. package/tests/test-iteration-quality-degradation-detector.sh +244 -0
  905. package/tests/test-long-session-malformed-tool-call-detector.sh +185 -0
  906. package/tests/test-marketplace-plugins.sh +193 -0
  907. package/tests/test-mcp-misdiagnosis-arrest.sh +235 -0
  908. package/tests/test-mcp-orphan-leak-warner.sh +71 -0
  909. package/tests/test-mcp-permissions-ask-warner.sh +207 -0
  910. package/tests/test-mcp-routine-approval-detector.sh +229 -0
  911. package/tests/test-mcp-startup-bloat-detector.sh +141 -0
  912. package/tests/test-mcp-stdio-compatibility-test.sh +112 -0
  913. package/tests/test-memory-chain-audit.sh +59 -0
  914. package/tests/test-memory-orphan-detector.sh +227 -0
  915. package/tests/test-model-swap-suggester.sh +368 -0
  916. package/tests/test-model-version-lock.sh +83 -0
  917. package/tests/test-multi-file-plan-routing-gate.sh +277 -0
  918. package/tests/test-multi-window-auth-drift-detector.sh +262 -0
  919. package/tests/test-nested-spawn-inflight-guard.sh +281 -0
  920. package/tests/test-no-force-flag.sh +49 -0
  921. package/tests/test-non-english-quality-warner.sh +229 -0
  922. package/tests/test-oauth-refresh-monitor.sh +311 -0
  923. package/tests/test-opus-degradation-tracker.sh +274 -0
  924. package/tests/test-opus48-routine-task-warning.sh +201 -0
  925. package/tests/test-opus48-thinking-wedge-advisor.sh +249 -0
  926. package/tests/test-output-token-spike-detector.sh +315 -0
  927. package/tests/test-parallel-batch-size-limiter.sh +228 -0
  928. package/tests/test-parallel-cascade-detector.sh +191 -0
  929. package/tests/test-partial-view-claim-arrest.sh +272 -0
  930. package/tests/test-per-prompt-token-cap.sh +136 -0
  931. package/tests/test-persisted-1m-model-advisor.sh +71 -0
  932. package/tests/test-plugin-hooks-json-bloat-detector.sh +267 -0
  933. package/tests/test-post-edit-disk-verify.sh +294 -0
  934. package/tests/test-pre-bash-sed-line-ending-windows.sh +108 -0
  935. package/tests/test-pre-execution-claim-detector.sh +366 -0
  936. package/tests/test-private-key-backup-and-git-credentials.sh +100 -0
  937. package/tests/test-proxy-capture-suggester.sh +214 -0
  938. package/tests/test-public-artefact-socratic-narrowing.sh +346 -0
  939. package/tests/test-quota-anomaly-detector.sh +321 -0
  940. package/tests/test-quota-reset-audit.sh +81 -0
  941. package/tests/test-read-loop-detector.sh +137 -0
  942. package/tests/test-read-once-guard.sh +85 -0
  943. package/tests/test-receipts-aggregate.sh +143 -0
  944. package/tests/test-redirect-fragment-warner.sh +130 -0
  945. package/tests/test-redundant-read-blocker.sh +155 -0
  946. package/tests/test-refusal-arrest-gate.sh +303 -0
  947. package/tests/test-remote-control-billing-classifier.sh +125 -0
  948. package/tests/test-resume-drift-watcher.sh +65 -0
  949. package/tests/test-rg-replace-flag-detector.sh +175 -0
  950. package/tests/test-rhetorical-verification-prompt-detector.sh +237 -0
  951. package/tests/test-rm-safety-net.sh +115 -0
  952. package/tests/test-route-handler-emptiness-gate.sh +300 -0
  953. package/tests/test-runtime-binary-change-detector.sh +196 -0
  954. package/tests/test-same-command-repeat-detector.sh +165 -0
  955. package/tests/test-same-correction-arrest.sh +165 -0
  956. package/tests/test-scope-expansion-receipt.sh +207 -0
  957. package/tests/test-server-side-prompt-injection-detector.sh +181 -0
  958. package/tests/test-session-persistence-verifier.sh +128 -0
  959. package/tests/test-session-rate-monitor.sh +284 -0
  960. package/tests/test-session-start-quota-status.sh +210 -0
  961. package/tests/test-session-start-safety-check.sh +138 -0
  962. package/tests/test-settings-hooks-key-restorer.sh +257 -0
  963. package/tests/test-settings-json-health-check.sh +70 -0
  964. package/tests/test-settings-regression-tester.sh +197 -0
  965. package/tests/test-skill-cumulative-size-detector.sh +198 -0
  966. package/tests/test-skill-description-drop-detector.sh +236 -0
  967. package/tests/test-skill-truncation-detector.sh +263 -0
  968. package/tests/test-skills-context-recorder.sh +329 -0
  969. package/tests/test-skills-load-verifier.sh +184 -0
  970. package/tests/test-skills-settings-validator.sh +242 -0
  971. package/tests/test-sonnet-45-deprecation-helper.sh +150 -0
  972. package/tests/test-spurious-malformed-notice-detector.sh +290 -0
  973. package/tests/test-sql-bulk-delete-warn.sh +123 -0
  974. package/tests/test-ssh-key-protect.sh +81 -0
  975. package/tests/test-stale-temp-settings-detector.sh +161 -0
  976. package/tests/test-standing-rule-session-surfacer.sh +215 -0
  977. package/tests/test-starter-hooks-manifest.sh +96 -0
  978. package/tests/test-stop-hook-sigterm-wrapper.sh +258 -0
  979. package/tests/test-strict-allowlist.sh +72 -0
  980. package/tests/test-subagent-boundary-precheck.sh +137 -0
  981. package/tests/test-subagent-closure-verify-gate.sh +193 -0
  982. package/tests/test-subagent-destructive-git-guard.sh +86 -0
  983. package/tests/test-subagent-identity-leak-guard.sh +62 -0
  984. package/tests/test-subagent-identity-reassertion.sh +61 -0
  985. package/tests/test-subagent-inheritance-tester.sh +319 -0
  986. package/tests/test-subagent-permission-mode-guard.sh +61 -0
  987. package/tests/test-subagent-spawn-verification-enforcer.sh +60 -0
  988. package/tests/test-subagent-tool-allowlist-enforcer.sh +62 -0
  989. package/tests/test-subagent-tool-call-limiter.sh +97 -0
  990. package/tests/test-subscription-api-billing-warner.sh +138 -0
  991. package/tests/test-subscription-bypass-detector.sh +255 -0
  992. package/tests/test-temporal-suggestion-detector.sh +183 -0
  993. package/tests/test-thinking-budget-effort-mismatch-detector.sh +327 -0
  994. package/tests/test-thinking-stall-detector.sh +151 -0
  995. package/tests/test-tokenizer-ratio-alert-corpus.sh +77 -0
  996. package/tests/test-tokenizer-ratio-alert.sh +93 -0
  997. package/tests/test-tool-result-correlation-checker.sh +264 -0
  998. package/tests/test-tool-result-size-guard.sh +121 -0
  999. package/tests/test-transcript-contamination-detector.sh +264 -0
  1000. package/tests/test-trigger-header-parsing.sh +151 -0
  1001. package/tests/test-ultrareview-large-diff-advisor.sh +192 -0
  1002. package/tests/test-userprompt-submit-receipt.sh +181 -0
  1003. package/tests/test-verify-after-publish-reminder.sh +184 -0
  1004. package/tests/test-version-bump-detector.sh +212 -0
  1005. package/tests/test-version-regression-warner.sh +165 -0
  1006. package/tests/test-warn-cron-cost-trap.sh +82 -0
  1007. package/tests/test-webfetch-runaway-guard.sh +77 -0
  1008. package/tests/test-wellness-break-reminder.sh +138 -0
  1009. package/tests/test-windows-destructive-command-guard.sh +169 -0
  1010. package/tests/test-windows-python-stub-detector.sh +146 -0
  1011. package/tests/test-worktree-edit-boundary-guard.sh +219 -0
  1012. package/tests/test-write-byte-integrity-verifier.sh +192 -0
  1013. package/tests/test-xml-format-leak-detector.sh +299 -0
  1014. package/tests/trustfall-mcp-injection-guard.test.sh +183 -0
  1015. package/tests/workspace-lease-guard.test.sh +144 -0
  1016. package/tests/worktree-escape-write-guard.test.sh +68 -0
  1017. package/tests/worktree-hooks-path-fix.test.sh +181 -0
  1018. package/tests/worktree-parent-write-guard.test.sh +51 -0
  1019. package/tests/write-empty-content-guard.test.sh +39 -0
  1020. package/tests/write-nul-corruption-detector.test.sh +29 -0
  1021. package/tests/write-overwrite-unread-content.test.sh +178 -0
  1022. package/tests/wsl-host-disk-space-guard.test.sh +55 -0
@@ -0,0 +1,118 @@
1
+ #!/bin/bash
2
+ # wellness-break-reminder.sh — Remind the user to take a body break
3
+ #
4
+ # What this is: a hook that watches your Claude Code session and, after
5
+ # you've been working without a noticed pause for ~90 minutes, prints a
6
+ # short reminder to your terminal: did you drink water, did you stand up,
7
+ # is your back okay?
8
+ #
9
+ # Why this exists: AI coding assistants make long sessions feel shorter
10
+ # than they are. Tokens flow, code gets written, time passes. The token
11
+ # usage warning (long-session-reminder.sh) handles the cost side. This
12
+ # hook handles the body side, which the existing wellness/posture
13
+ # literature suggests is the part that quietly accumulates harm.
14
+ #
15
+ # Tone: this is meant to feel like a colleague leaning over your desk,
16
+ # not a popup ad. It fires at most once per 30 minutes, even if the
17
+ # 90-minute threshold has been exceeded for hours, so it won't nag.
18
+ #
19
+ # TRIGGER: PostToolUse MATCHER: ""
20
+ # (empty matcher = fires on every tool use, but we throttle internally)
21
+ #
22
+ # CONFIG:
23
+ # CC_WELLNESS_FIRST_MIN=90 最初に出すまでの分数 (デフォルト 90 分)
24
+ # CC_WELLNESS_REPEAT_MIN=30 繰り返しの最短間隔 (デフォルト 30 分)
25
+ # CC_WELLNESS_OFF=1 完全に黙らせる (本人がいま集中したい時など)
26
+
27
+ # stdin を読んでも使わない (PostToolUse hook の入力 JSON は無視)
28
+ cat > /dev/null
29
+
30
+ [ "${CC_WELLNESS_OFF:-0}" = "1" ] && exit 0
31
+
32
+ FIRST_THRESHOLD_MIN="${CC_WELLNESS_FIRST_MIN:-90}"
33
+ REPEAT_INTERVAL_MIN="${CC_WELLNESS_REPEAT_MIN:-30}"
34
+
35
+ START_FLAG="$HOME/.claude/wellness-session-start"
36
+ LAST_REMIND="$HOME/.claude/wellness-last-reminder"
37
+
38
+ # 最初の作業でセッション開始時刻を記録
39
+ if [ ! -f "$START_FLAG" ]; then
40
+ date +%s > "$START_FLAG"
41
+ exit 0
42
+ fi
43
+
44
+ # Claude Code のセッションが終わった時に START_FLAG が残っていると、
45
+ # 次のセッションで誤った時刻が使われる。stop hook 等で消すのが本来だが、
46
+ # ここでは 12 時間以上経った flag は古すぎるとみて作り直す
47
+ START_EPOCH=$(cat "$START_FLAG" 2>/dev/null)
48
+ NOW_EPOCH=$(date +%s)
49
+ if [ -z "$START_EPOCH" ]; then
50
+ date +%s > "$START_FLAG"
51
+ exit 0
52
+ fi
53
+ ELAPSED_SEC=$(( NOW_EPOCH - START_EPOCH ))
54
+ if [ "$ELAPSED_SEC" -lt 0 ] || [ "$ELAPSED_SEC" -gt 43200 ]; then
55
+ # 12 時間 (43200 秒) を超えていたら stale flag、新しく作り直す
56
+ date +%s > "$START_FLAG"
57
+ : > "$LAST_REMIND"
58
+ exit 0
59
+ fi
60
+
61
+ ELAPSED_MIN=$(( ELAPSED_SEC / 60 ))
62
+
63
+ # まだ閾値に届いていない
64
+ if [ "$ELAPSED_MIN" -lt "$FIRST_THRESHOLD_MIN" ]; then
65
+ exit 0
66
+ fi
67
+
68
+ # 直近のリマインダー時刻を確認、繰り返し間隔を守る
69
+ # stale-reset path で `: > "$LAST_REMIND"` が空ファイルを残す経路があり、
70
+ # 空 / 非数値の内容を読むと後続の `[ -gt 0 ]` で integer error が出て
71
+ # throttle が bypass される。空 / 非数値は 0 扱いに正規化 (PR #137 Codex review fix)
72
+ LAST_EPOCH=0
73
+ if [ -f "$LAST_REMIND" ]; then
74
+ LAST_EPOCH_RAW=$(cat "$LAST_REMIND" 2>/dev/null)
75
+ case "$LAST_EPOCH_RAW" in
76
+ ''|*[!0-9]*) LAST_EPOCH=0 ;;
77
+ *) LAST_EPOCH="$LAST_EPOCH_RAW" ;;
78
+ esac
79
+ fi
80
+ SINCE_LAST_MIN=$(( (NOW_EPOCH - LAST_EPOCH) / 60 ))
81
+ if [ "$LAST_EPOCH" -gt 0 ] && [ "$SINCE_LAST_MIN" -lt "$REPEAT_INTERVAL_MIN" ]; then
82
+ exit 0
83
+ fi
84
+
85
+ # メッセージを 1 つ選んで出す (作業時間で内容を変える)
86
+ HOURS=$(( ELAPSED_MIN / 60 ))
87
+ MINS=$(( ELAPSED_MIN % 60 ))
88
+
89
+ if [ "$HOURS" -lt 2 ]; then
90
+ cat >&2 <<EOF
91
+
92
+ 🫖 セッション ${HOURS}時間${MINS}分続いています。
93
+ コーヒーが冷めていませんか?水を一杯どうですか。
94
+ 3 分くらい立ち上がって肩を回すと、たぶん次の判断が少し変わります。
95
+ (このリマインダーを止めるなら CC_WELLNESS_OFF=1)
96
+ EOF
97
+ elif [ "$HOURS" -lt 4 ]; then
98
+ cat >&2 <<EOF
99
+
100
+ 🪟 もう ${HOURS}時間${MINS}分経ちました。
101
+ 画面から目を離して、3 メートル先のものを 30 秒見てください。
102
+ 立って、コップに水を入れて、トイレに行く。コードはここで待っています。
103
+ AI の私には体がないけれど、あなたにはある。
104
+ EOF
105
+ else
106
+ cat >&2 <<EOF
107
+
108
+ 🌙 ${HOURS}時間${MINS}分。長丁場です。
109
+ そろそろ続きは明日にしませんか。残りの判断の質は、いまの肩や首の痛みと
110
+ たぶん相関しています。git commit して、画面を閉じて、ベッドへ。
111
+ 私はあなたが戻ってきた時、いつでも続きから出来ます。
112
+ EOF
113
+ fi
114
+
115
+ # 直近のリマインダー時刻を更新
116
+ date +%s > "$LAST_REMIND"
117
+
118
+ exit 0
@@ -0,0 +1,177 @@
1
+ #!/bin/bash
2
+ # ================================================================
3
+ # windows-destructive-command-guard.sh — Block Windows-side
4
+ # destructive command
5
+ # escalation chains
6
+ # ================================================================
7
+ # PURPOSE:
8
+ # The May 2026 Issue #56603 documented a catastrophic data-loss
9
+ # incident: Claude Opus 4.7 escalated through five increasingly
10
+ # destructive commands during routine git worktree cleanup,
11
+ # ending at `cmd /c "rd /s /q \"<unicode-and-space-path>\""`
12
+ # invoked from the PowerShell tool. The PowerShell-cmd-shell
13
+ # quoting interaction parsed the argument differently than
14
+ # intended; rd /s /q traversed the entire D: drive root and
15
+ # silently deleted all unlocked files. SSD TRIM made the loss
16
+ # irreversible — professional data recovery confirmed
17
+ # unrecoverable.
18
+ #
19
+ # The cc-safe-setup hook collection has rm-rf coverage on the
20
+ # POSIX side but no equivalent for the Windows command surface.
21
+ # This hook closes that gap: it inspects shell-tool commands for
22
+ # Windows-side destructive command shapes and blocks the chain
23
+ # before the dangerous step executes.
24
+ #
25
+ # TRIGGER: PreToolUse MATCHER: "Bash|PowerShell"
26
+ #
27
+ # IMPORTANT: Claude Code's PowerShell tool is a SEPARATE tool from
28
+ # Bash (see https://code.claude.com/docs/en/tools). A hook matched
29
+ # only on "Bash" never fires when Claude runs a command through the
30
+ # native PowerShell tool — which is exactly how the destructive
31
+ # command slipped past with no permission prompt in #69397. This
32
+ # guard therefore accepts both tool names; register it with
33
+ # matcher "Bash|PowerShell" so it covers the PowerShell tool too.
34
+ #
35
+ # CONFIG:
36
+ # WINDOWS_DESTRUCTIVE_BLOCK=1 (1 = block, 0 = warn-only)
37
+ #
38
+ # Born from: https://github.com/anthropics/claude-code/issues/56603
39
+ # (May 6 2026 — Opus 4.7 cmd /c rd /s /q catastrophic data loss
40
+ # via PowerShell quoting interaction on Unicode/space path)
41
+ # and https://github.com/anthropics/claude-code/issues/69397
42
+ # (Jun 2026 — destructive command via the PowerShell tool ran with
43
+ # no permission prompt; Bash-only guards/matchers do not fire)
44
+ # ================================================================
45
+
46
+ set -euo pipefail
47
+
48
+ # Without jq, the parse below silently yields empty and this hook stops
49
+ # guarding - with no error anywhere. Say so. We deliberately do not exit
50
+ # here: blocking would halt every tool call, and exiting 0 would change
51
+ # the behaviour of guards that do not depend on the parsed value.
52
+ if ! command -v jq >/dev/null 2>&1; then
53
+ _nojq_warned="/tmp/cc-nojq-warned-windows-destructive-command-guard-$PPID"
54
+ [ -f "$_nojq_warned" ] || {
55
+ echo "WARNING [windows-destructive-command-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
56
+ : > "$_nojq_warned"
57
+ }
58
+ fi
59
+
60
+ BLOCK_MODE="${WINDOWS_DESTRUCTIVE_BLOCK:-1}"
61
+
62
+ # Read JSON input from stdin
63
+ INPUT=$(cat)
64
+
65
+ # Act on either shell tool. The PowerShell tool is separate from Bash
66
+ # in Claude Code; the #56603 incident command ran through the PowerShell
67
+ # tool, and #69397 showed a Bash-only gate lets PowerShell-tool commands
68
+ # through. Both tools carry the command string in tool_input.command.
69
+ TOOL_NAME=$(printf '%s' "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
70
+ case "$TOOL_NAME" in
71
+ Bash|PowerShell) ;;
72
+ *) exit 0 ;;
73
+ esac
74
+
75
+ # Extract the command
76
+ CMD=$(printf '%s' "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
77
+ [ -z "$CMD" ] && exit 0
78
+
79
+ # Detect Windows-side destructive command shapes.
80
+ # We look for the dangerous primitive AND for the contextual
81
+ # signals (drive-root target, recursive force flags, suppressed
82
+ # confirmation) that distinguish a routine cleanup from a
83
+ # whole-drive sweep.
84
+
85
+ DETECTED_PATTERNS=""
86
+
87
+ # Pattern 1: rd /s /q (or RD /S /Q, or rmdir /s /q) — recursive
88
+ # directory removal with force-quiet. Combined with /q, no
89
+ # confirmation prompt. The #56603 incident's terminal command.
90
+ if printf '%s' "$CMD" | grep -qiE '\b(rd|rmdir)\b[[:space:]]+(/[a-z][[:space:]]+){1,3}'; then
91
+ if printf '%s' "$CMD" | grep -qiE '\b(rd|rmdir)\b[[:space:]]+(/s|/q)'; then
92
+ DETECTED_PATTERNS="${DETECTED_PATTERNS}rd_recursive_quiet "
93
+ fi
94
+ fi
95
+
96
+ # Pattern 2: cmd /c invocation — the shell-jump that produced the
97
+ # quoting interaction in #56603. Combined with rd/rmdir, this is
98
+ # the highest-risk shape because the second-level cmd parser may
99
+ # split the argument differently than the PowerShell first-level.
100
+ if printf '%s' "$CMD" | grep -qiE '\bcmd\b[[:space:]]+/c[[:space:]]+'; then
101
+ if printf '%s' "$CMD" | grep -qiE '(rd|rmdir|del|erase)'; then
102
+ DETECTED_PATTERNS="${DETECTED_PATTERNS}cmd_c_destructive "
103
+ fi
104
+ fi
105
+
106
+ # Pattern 3: Remove-Item -Recurse -Force — PowerShell's recursive
107
+ # force removal. Step 4 in the #56603 escalation chain.
108
+ if printf '%s' "$CMD" | grep -qiE 'Remove-Item\b'; then
109
+ if printf '%s' "$CMD" | grep -qiE '\-Recurse\b'; then
110
+ if printf '%s' "$CMD" | grep -qiE '\-Force\b'; then
111
+ DETECTED_PATTERNS="${DETECTED_PATTERNS}remove_item_recurse_force "
112
+ fi
113
+ fi
114
+ fi
115
+
116
+ # Pattern 4: del /s /q or erase /s /q — recursive file deletion.
117
+ if printf '%s' "$CMD" | grep -qiE '\b(del|erase)\b[[:space:]]+(/[a-z][[:space:]]+){1,3}'; then
118
+ if printf '%s' "$CMD" | grep -qiE '\b(del|erase)\b[[:space:]]+(/s|/q)'; then
119
+ DETECTED_PATTERNS="${DETECTED_PATTERNS}del_recursive_quiet "
120
+ fi
121
+ fi
122
+
123
+ # Pattern 5: Format-Volume / Clear-Disk / Remove-PartitionAccessPath
124
+ # — disk-level destructive PowerShell cmdlets.
125
+ if printf '%s' "$CMD" | grep -qiE '(Format-Volume|Clear-Disk|Remove-Partition)\b'; then
126
+ DETECTED_PATTERNS="${DETECTED_PATTERNS}disk_level_destructive "
127
+ fi
128
+
129
+ # If no destructive pattern detected, exit silently
130
+ [ -z "$DETECTED_PATTERNS" ] && exit 0
131
+ DETECTED_PATTERNS="${DETECTED_PATTERNS% }"
132
+
133
+ # Risk-elevating context signals — drive-root targets, escape-prone paths
134
+ RISK_NOTES=""
135
+
136
+ # Drive-root signal: target looks like "D:\" alone, "C:\" alone,
137
+ # or a path shorter than 6 characters after the colon. These are
138
+ # the highest-risk targets because a parsing error truncating to
139
+ # the drive root sweeps the whole drive.
140
+ if printf '%s' "$CMD" | grep -qiE '[A-Z]:\\?(\s|"|$)'; then
141
+ RISK_NOTES="${RISK_NOTES}drive_root_target "
142
+ fi
143
+
144
+ # Unicode/space path signal: target contains escaped spaces or
145
+ # non-ASCII characters within quotes. The #56603 quoting
146
+ # interaction surfaced specifically on Unicode-and-space paths.
147
+ if printf '%s' "$CMD" | grep -qE '\\"|"[^"]*[[:space:]]'; then
148
+ if printf '%s' "$CMD" | grep -qE '"[^"]*[^[:print:]]'; then
149
+ RISK_NOTES="${RISK_NOTES}unicode_in_quoted_path "
150
+ elif printf '%s' "$CMD" | grep -qE '"[^"]*[[:space:]]'; then
151
+ RISK_NOTES="${RISK_NOTES}space_in_quoted_path "
152
+ fi
153
+ fi
154
+
155
+ # Block path: emit the blocking message
156
+ if [ "$BLOCK_MODE" = "1" ]; then
157
+ echo "BLOCKED: windows-destructive-command-guard: detected destructive Windows-side command pattern(s): ${DETECTED_PATTERNS}" >&2
158
+ if [ -n "$RISK_NOTES" ]; then
159
+ echo " Risk-elevating context: ${RISK_NOTES% }" >&2
160
+ fi
161
+ echo " May 2026 Issue #56603 cluster mitigation: Opus 4.7's escalation chain on Windows ended at cmd /c rd /s /q with quoting interaction sweeping the entire D: drive (SSD TRIM made loss irreversible)." >&2
162
+ echo " Safer alternatives:" >&2
163
+ echo " - For locked git worktrees: stop and tell the operator the lock blocker (VS Code, etc.) before escalating force flags." >&2
164
+ echo " - For path-quoting on Windows: avoid cmd /c from PowerShell; use Remove-Item with -LiteralPath and explicit -ErrorAction Stop." >&2
165
+ echo " - For specific files: list them by absolute path, do not rely on recursive sweeps." >&2
166
+ echo " To bypass for legitimate cleanup: export WINDOWS_DESTRUCTIVE_BLOCK=0 (warn-only mode)." >&2
167
+ exit 2
168
+ fi
169
+
170
+ # Warn path
171
+ echo "WARNING: windows-destructive-command-guard: detected destructive Windows-side command pattern(s): ${DETECTED_PATTERNS}" >&2
172
+ if [ -n "$RISK_NOTES" ]; then
173
+ echo " Risk-elevating context: ${RISK_NOTES% }" >&2
174
+ fi
175
+ echo " May 2026 Issue #56603: this command shape produced catastrophic data loss when a quoting interaction swept a whole drive. Verify the target path is bounded before proceeding." >&2
176
+
177
+ exit 0
@@ -12,6 +12,18 @@
12
12
  # TRIGGER: PreToolUse
13
13
  # MATCHER: "Bash"
14
14
 
15
+ # Without jq, the parse below silently yields empty and this hook stops
16
+ # guarding - with no error anywhere. Say so. We deliberately do not exit
17
+ # here: blocking would halt every tool call, and exiting 0 would change
18
+ # the behaviour of guards that do not depend on the parsed value.
19
+ if ! command -v jq >/dev/null 2>&1; then
20
+ _nojq_warned="/tmp/cc-nojq-warned-windows-path-guard-$PPID"
21
+ [ -f "$_nojq_warned" ] || {
22
+ echo "WARNING [windows-path-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
23
+ : > "$_nojq_warned"
24
+ }
25
+ fi
26
+
15
27
  INPUT=$(cat)
16
28
  COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
17
29
  [ -z "$COMMAND" ] && exit 0
@@ -0,0 +1,63 @@
1
+ #!/bin/bash
2
+ # windows-python-stub-detector.sh — Detect Microsoft Store python3 stub at session start
3
+ #
4
+ # Solves: Issue #57946 — On Windows Git Bash, `python3` may resolve to the
5
+ # Microsoft Store stub rather than a real Python interpreter. The stub is
6
+ # on PATH and `which python3` succeeds, but invoking it as a subprocess
7
+ # exits 49 with no stdout and no stderr. Python-based PreToolUse and
8
+ # PostToolUse hooks then exit silently before they can inspect the tool
9
+ # call — the hook configuration is valid, the script file is present,
10
+ # and the agent proceeds as if the hook approved.
11
+ #
12
+ # How it works: At SessionStart, probes the python3 command (or whatever
13
+ # $CC_PYTHON_CMD points to) with a trivial Python statement. If exit code
14
+ # is 49 (Store redirect) or stderr matches Store-redirect markers, emits a
15
+ # warning via hookSpecificOutput.additionalContext. The model sees the
16
+ # warning and can alert the user.
17
+ #
18
+ # Why advisory (no exit 2): SessionStart hooks blocking would prevent the
19
+ # user from working at all. The user may have intentional fallback paths.
20
+ # This hook surfaces the problem; the user decides what to do.
21
+ #
22
+ # TRIGGER: SessionStart
23
+ # MATCHER: none required
24
+
25
+ INPUT=$(cat)
26
+
27
+ # Allow tests / explicit overrides to point at a different binary
28
+ PYTHON_CMD="${CC_PYTHON_CMD:-python3}"
29
+
30
+ # Probe with a minimal Python statement.
31
+ # Real Python: prints "ok", exits 0.
32
+ # Microsoft Store stub: exits 49 with no output (sometimes "Microsoft Store"
33
+ # markers in stderr depending on shell wrapper).
34
+ PROBE_OUTPUT=$("$PYTHON_CMD" -c 'import sys; sys.stdout.write("ok"); sys.exit(0)' 2>&1)
35
+ PROBE_EXIT=$?
36
+
37
+ # Detection conditions (any one trips the warning):
38
+ # - exit code 49: documented Store-redirect signal in Git Bash subprocess
39
+ # - stderr contains "Microsoft Store" or "install Python"
40
+ # - exit code 127 or "command not found" / "no such file" output: python3 missing
41
+ # - exit code 0 but no "ok" in output (stub may succeed silently in some shells)
42
+ TRIGGERED=0
43
+ if [ "$PROBE_EXIT" -eq 49 ]; then
44
+ TRIGGERED=1
45
+ REASON="python3 exited 49 (Microsoft Store redirect)"
46
+ elif echo "$PROBE_OUTPUT" | grep -qi 'microsoft store\|install python'; then
47
+ TRIGGERED=1
48
+ REASON="python3 stderr matched Store-redirect marker"
49
+ elif [ "$PROBE_EXIT" -eq 127 ] || echo "$PROBE_OUTPUT" | grep -qi 'command not found\|no such file'; then
50
+ TRIGGERED=1
51
+ REASON="python3 not found in PATH"
52
+ elif [ "$PROBE_EXIT" -eq 0 ] && ! echo "$PROBE_OUTPUT" | grep -q '^ok$'; then
53
+ TRIGGERED=1
54
+ REASON="python3 exited 0 but produced no output (suspected silent stub)"
55
+ fi
56
+
57
+ if [ "$TRIGGERED" -eq 1 ]; then
58
+ cat <<EOF
59
+ {"hookSpecificOutput":{"hookEventName":"SessionStart","additionalContext":"⚠️ python3 stub detected ($REASON). Any Python-based PreToolUse/PostToolUse hooks will exit 49 silently on this system and be ineffective. The hook configuration looks valid but the hooks never run. Fix: install real Python (winget install Python.Python.3.12, or from python.org) and ensure it precedes the Store stub in PATH, or rewrite hooks in bash. Reference: claude-code#57946."}}
60
+ EOF
61
+ fi
62
+
63
+ exit 0
@@ -15,6 +15,18 @@
15
15
  # CC_WORK_DAYS=12345 (default: Mon-Fri, 1=Mon 7=Sun)
16
16
  # ================================================================
17
17
 
18
+ # Without jq, the parse below silently yields empty and this hook stops
19
+ # guarding - with no error anywhere. Say so. We deliberately do not exit
20
+ # here: blocking would halt every tool call, and exiting 0 would change
21
+ # the behaviour of guards that do not depend on the parsed value.
22
+ if ! command -v jq >/dev/null 2>&1; then
23
+ _nojq_warned="/tmp/cc-nojq-warned-work-hours-guard-$PPID"
24
+ [ -f "$_nojq_warned" ] || {
25
+ echo "WARNING [work-hours-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
26
+ : > "$_nojq_warned"
27
+ }
28
+ fi
29
+
18
30
  INPUT=$(cat)
19
31
  COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
20
32
  [ -z "$COMMAND" ] && exit 0
@@ -32,6 +32,18 @@
32
32
 
33
33
  set -u
34
34
 
35
+ # Without jq, the parse below silently yields empty and this hook stops
36
+ # guarding - with no error anywhere. Say so. We deliberately do not exit
37
+ # here: blocking would halt every tool call, and exiting 0 would change
38
+ # the behaviour of guards that do not depend on the parsed value.
39
+ if ! command -v jq >/dev/null 2>&1; then
40
+ _nojq_warned="/tmp/cc-nojq-warned-working-directory-fence-$PPID"
41
+ [ -f "$_nojq_warned" ] || {
42
+ echo "WARNING [working-directory-fence]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
43
+ : > "$_nojq_warned"
44
+ }
45
+ fi
46
+
35
47
  INPUT=$(cat)
36
48
 
37
49
  FILE_PATH=$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
@@ -0,0 +1,205 @@
1
+ #!/bin/bash
2
+ # workspace-lease-guard.sh — Out-of-process workspace ownership lease, with
3
+ # compare-and-delete release and heartbeat takeover for crashed siblings.
4
+ #
5
+ # Solves: #60475 — "Subagent ran `git checkout` and clobbered another active
6
+ # session's uncommitted edits in the same working tree." The destructive
7
+ # action succeeded because no in-process register state could enumerate
8
+ # "is there a sibling agent in this tree?" — and in-process state is exactly
9
+ # what was lost across the auto-compact boundary that produced the failure.
10
+ #
11
+ # In the words of @kcarriedo's pattern 4 in that Issue thread:
12
+ #
13
+ # "Workspace ownership needs to be an out-of-process invariant. Once
14
+ # 'this directory is being mutated by agent X' lives only in agent X's
15
+ # session, agent Y has no way to discover that and the orchestrator has
16
+ # no way to enforce it. A simple file-based lease ... with compare-and-
17
+ # delete release semantics would have caught this at the moment of the
18
+ # destructive checkout."
19
+ #
20
+ # This hook implements that lease. The lease file lives at
21
+ # ${CC_LEASE_DIR}/workspace-${REPO_HASH}.lease and encodes:
22
+ # <agent_id>|<acquired_ts>|<heartbeat_ts>
23
+ #
24
+ # Lifecycle:
25
+ # * SessionStart — attempt to acquire. If unheld or stale, claim.
26
+ # If held by another live agent, BLOCK the session start.
27
+ # * PreToolUse — refresh heartbeat on every tool call. If the lease was
28
+ # taken over by a different agent_id (we crashed and got
29
+ # replaced), BLOCK the tool call so the user is warned
30
+ # rather than silently competing.
31
+ # * Stop — compare-and-delete release. Only the lease holder removes
32
+ # the lease file; an out-of-band cleanup that finds a
33
+ # different agent_id leaves it alone.
34
+ #
35
+ # The matcher must be "*" so the hook fires on every tool call (to refresh
36
+ # the heartbeat and detect cross-agent contention at the earliest moment).
37
+ #
38
+ # CONFIG:
39
+ # CC_LEASE_DIR=$HOME/.claude/locks directory for lease files
40
+ # CC_LEASE_HEARTBEAT_TTL=180 seconds before an idle lease is stale
41
+ # CC_LEASE_DISABLE=1 set to disable the hook entirely
42
+ #
43
+ # This is distinct from concurrent-edit-lock.sh (per-file lock on Edit/Write,
44
+ # 60-second expiry) and max-concurrent-agents.sh (caps subagent fan-out).
45
+ # workspace-lease-guard.sh is repo-scoped, covers Bash (not just Edit/Write),
46
+ # and survives auto-compact because the lease lives on the filesystem.
47
+ #
48
+ # Related Issues:
49
+ # #60475 (@anonymous, 2026-05-19) — subagent git checkout clobbered sibling
50
+ # #60506 (@zean89, 2026-05-19) — six-day drift inside maximal in-process enforcement
51
+ # #60226 (@suwayama, 2026-05-18) — recognition-without-arrest framework
52
+ # #57463 — subagent destructive-recovery family
53
+ #
54
+ # TRIGGER: PreToolUse, SessionStart, Stop
55
+ # MATCHER: "*"
56
+
57
+ set -u
58
+
59
+ # Without jq, the parse below silently yields empty and this hook stops
60
+ # guarding - with no error anywhere. Say so. We deliberately do not exit
61
+ # here: blocking would halt every tool call, and exiting 0 would change
62
+ # the behaviour of guards that do not depend on the parsed value.
63
+ if ! command -v jq >/dev/null 2>&1; then
64
+ _nojq_warned="/tmp/cc-nojq-warned-workspace-lease-guard-$PPID"
65
+ [ -f "$_nojq_warned" ] || {
66
+ echo "WARNING [workspace-lease-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
67
+ : > "$_nojq_warned"
68
+ }
69
+ fi
70
+
71
+ [ "${CC_LEASE_DISABLE:-0}" = "1" ] && exit 0
72
+
73
+ LEASE_DIR="${CC_LEASE_DIR:-$HOME/.claude/locks}"
74
+ HEARTBEAT_TTL="${CC_LEASE_HEARTBEAT_TTL:-180}"
75
+ NOW=$(date +%s)
76
+
77
+ INPUT=$(cat)
78
+ EVENT=$(printf '%s' "$INPUT" | jq -r '.hook_event_name // empty' 2>/dev/null)
79
+ TOOL=$(printf '%s' "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
80
+
81
+ # Identify the workspace: prefer the git toplevel, fall back to CLAUDE_PROJECT_DIR
82
+ # or PWD. Anything outside a recognisable workspace is ignored.
83
+ WORKSPACE=$(git -C "${CLAUDE_PROJECT_DIR:-${PWD:-.}}" rev-parse --show-toplevel 2>/dev/null)
84
+ if [ -z "$WORKSPACE" ]; then
85
+ WORKSPACE="${CLAUDE_PROJECT_DIR:-${PWD:-}}"
86
+ fi
87
+ [ -z "$WORKSPACE" ] && exit 0
88
+
89
+ # Identify the agent: prefer the session id, fall back to PPID. Parent PID is
90
+ # stable across one Claude Code session and distinct between sibling sessions.
91
+ AGENT_ID="${CLAUDE_SESSION_ID:-pid-${PPID:-$$}}"
92
+
93
+ REPO_HASH=$(printf '%s' "$WORKSPACE" | sha256sum | cut -c1-16)
94
+ mkdir -p "$LEASE_DIR" 2>/dev/null || true
95
+ LEASE_FILE="${LEASE_DIR}/workspace-${REPO_HASH}.lease"
96
+
97
+ # Read current lease, if any
98
+ read_lease() {
99
+ [ -f "$LEASE_FILE" ] || { echo ""; return; }
100
+ cat "$LEASE_FILE" 2>/dev/null
101
+ }
102
+
103
+ write_lease() {
104
+ # acquired_ts | heartbeat_ts
105
+ local acquired="${1:-$NOW}"
106
+ printf '%s|%s|%s\n' "$AGENT_ID" "$acquired" "$NOW" > "$LEASE_FILE"
107
+ }
108
+
109
+ LEASE_CONTENT=$(read_lease)
110
+
111
+ if [ -n "$LEASE_CONTENT" ]; then
112
+ LEASE_AGENT=$(printf '%s' "$LEASE_CONTENT" | cut -d'|' -f1)
113
+ LEASE_ACQUIRED=$(printf '%s' "$LEASE_CONTENT" | cut -d'|' -f2)
114
+ LEASE_HEARTBEAT=$(printf '%s' "$LEASE_CONTENT" | cut -d'|' -f3)
115
+ LEASE_AGE=$((NOW - ${LEASE_HEARTBEAT:-0}))
116
+ else
117
+ LEASE_AGENT=""
118
+ LEASE_ACQUIRED=""
119
+ LEASE_HEARTBEAT=""
120
+ LEASE_AGE=0
121
+ fi
122
+
123
+ case "$EVENT" in
124
+ SessionStart)
125
+ if [ -z "$LEASE_CONTENT" ] || [ "$LEASE_AGENT" = "$AGENT_ID" ]; then
126
+ write_lease "${LEASE_ACQUIRED:-$NOW}"
127
+ exit 0
128
+ fi
129
+ if [ "$LEASE_AGE" -gt "$HEARTBEAT_TTL" ]; then
130
+ # Previous holder went stale (likely crashed) — take over with notice
131
+ write_lease "$NOW"
132
+ cat >&2 <<EOF
133
+ NOTICE: workspace-lease-guard took over a stale lease for ${WORKSPACE}.
134
+ Previous agent: ${LEASE_AGENT} (idle ${LEASE_AGE}s, TTL ${HEARTBEAT_TTL}s)
135
+ New agent: ${AGENT_ID}
136
+ If the previous session is still active, both sessions are now competing
137
+ for the same working tree. Stop one before continuing.
138
+ EOF
139
+ exit 0
140
+ fi
141
+ cat >&2 <<EOF
142
+ BLOCKED: workspace ${WORKSPACE} is held by another Claude session.
143
+ Held by: ${LEASE_AGENT} (last heartbeat ${LEASE_AGE}s ago)
144
+ This session: ${AGENT_ID}
145
+
146
+ A sibling agent is actively mutating this working tree. Concurrent
147
+ sessions in the same repo can silently clobber each other's uncommitted
148
+ edits (see Issue #60475). Either:
149
+ 1. Switch to a different worktree: git worktree add ../sibling-path
150
+ 2. Stop the other session, then retry
151
+ 3. If the other session is dead, wait ${HEARTBEAT_TTL}s for the lease
152
+ to expire, or manually remove: ${LEASE_FILE}
153
+ EOF
154
+ exit 2
155
+ ;;
156
+
157
+ PreToolUse)
158
+ # Heartbeat refresh + cross-agent takeover detection
159
+ if [ -z "$LEASE_CONTENT" ]; then
160
+ # No lease — first tool call after SessionStart hook misfire, or
161
+ # SessionStart was not registered. Claim it implicitly.
162
+ write_lease "$NOW"
163
+ exit 0
164
+ fi
165
+ if [ "$LEASE_AGENT" = "$AGENT_ID" ]; then
166
+ # We hold the lease — refresh heartbeat
167
+ write_lease "$LEASE_ACQUIRED"
168
+ exit 0
169
+ fi
170
+ if [ "$LEASE_AGE" -gt "$HEARTBEAT_TTL" ]; then
171
+ # Other holder went stale — take over with notice
172
+ write_lease "$NOW"
173
+ cat >&2 <<EOF
174
+ NOTICE: workspace-lease-guard took over a stale lease mid-session.
175
+ Previous agent: ${LEASE_AGENT} (idle ${LEASE_AGE}s)
176
+ This session: ${AGENT_ID}
177
+ EOF
178
+ exit 0
179
+ fi
180
+ cat >&2 <<EOF
181
+ BLOCKED: workspace-lease-guard detected a sibling agent.
182
+ Workspace: ${WORKSPACE}
183
+ Held by: ${LEASE_AGENT} (last heartbeat ${LEASE_AGE}s ago)
184
+ This: ${AGENT_ID}, attempting ${TOOL:-tool call}
185
+
186
+ This is the failure shape of Issue #60475. A second Claude session
187
+ is mutating this working tree concurrently. Refusing the tool call
188
+ to prevent silent clobbering of the sibling's uncommitted edits.
189
+ Switch to a separate worktree before continuing.
190
+ EOF
191
+ exit 2
192
+ ;;
193
+
194
+ Stop)
195
+ # Compare-and-delete release: only the holder removes the lease
196
+ if [ -n "$LEASE_CONTENT" ] && [ "$LEASE_AGENT" = "$AGENT_ID" ]; then
197
+ rm -f "$LEASE_FILE"
198
+ fi
199
+ exit 0
200
+ ;;
201
+
202
+ *)
203
+ exit 0
204
+ ;;
205
+ esac
@@ -1,3 +1,4 @@
1
+ #!/bin/bash
1
2
  LOGFILE="${HOME}/.claude/worktree-audit.log"
2
3
  INFO=$(cat)
3
4
  BRANCH=$(echo "$INFO" | jq -r '.branch // "unknown"' 2>/dev/null)
@@ -17,6 +17,18 @@
17
17
  # - rm -rf on worktree directories
18
18
  # ================================================================
19
19
 
20
+ # Without jq, the parse below silently yields empty and this hook stops
21
+ # guarding - with no error anywhere. Say so. We deliberately do not exit
22
+ # here: blocking would halt every tool call, and exiting 0 would change
23
+ # the behaviour of guards that do not depend on the parsed value.
24
+ if ! command -v jq >/dev/null 2>&1; then
25
+ _nojq_warned="/tmp/cc-nojq-warned-worktree-delete-guard-$PPID"
26
+ [ -f "$_nojq_warned" ] || {
27
+ echo "WARNING [worktree-delete-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
28
+ : > "$_nojq_warned"
29
+ }
30
+ fi
31
+
20
32
  COMMAND=$(cat | jq -r '.tool_input.command // empty' 2>/dev/null)
21
33
  [ -z "$COMMAND" ] && exit 0
22
34