cc-safe-setup 29.8.0 → 30.0.5

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 (1017) 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 +421 -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-dispatch-watchdog.sh +149 -0
  178. package/examples/completion-claim-without-verification-detector.sh +207 -0
  179. package/examples/composer-guard.sh +12 -0
  180. package/examples/compound-bash-permission-resolver.sh +156 -0
  181. package/examples/compound-command-allow.sh +1 -1
  182. package/examples/compound-command-deny-enforcer.sh +183 -0
  183. package/examples/compound-inject-guard.sh +12 -0
  184. package/examples/concurrent-edit-lock.sh +12 -0
  185. package/examples/conflict-marker-guard.sh +12 -0
  186. package/examples/consecutive-error-breaker.sh +0 -0
  187. package/examples/console-log-count.sh +1 -0
  188. package/examples/context-compact-advisor.sh +29 -2
  189. package/examples/context-length-budget.sh +69 -0
  190. package/examples/context-threshold-alert.sh +12 -0
  191. package/examples/context-usage-drift-alert.sh +41 -13
  192. package/examples/conversation-history-guard.sh +12 -0
  193. package/examples/core-file-protect-guard.sh +12 -0
  194. package/examples/cors-star-warn.sh +0 -0
  195. package/examples/cost-incident-self-audit.sh +162 -0
  196. package/examples/cowork-claude-md-load-checker.sh +100 -0
  197. package/examples/cowork-fuse-staleness-watcher.sh +140 -0
  198. package/examples/cowork-hook-absence-warner.sh +167 -0
  199. package/examples/cowork-model-picker-advisor.sh +115 -0
  200. package/examples/credential-exfil-guard.sh +65 -4
  201. package/examples/credential-file-cat-guard.sh +17 -1
  202. package/examples/cron-create-receipt.sh +112 -0
  203. package/examples/cron-modification-guard.sh +12 -0
  204. package/examples/cross-product-mcp-spawn-detector.sh +178 -0
  205. package/examples/cwd-project-boundary-guard.sh +0 -0
  206. package/examples/daemon-zombie-worker-surfacer.sh +118 -0
  207. package/examples/daily-cost-guard.sh +164 -0
  208. package/examples/daily-usage-tracker.sh +0 -0
  209. package/examples/dangerous-pip-flag-guard.sh +12 -0
  210. package/examples/db-connect-guard.sh +13 -1
  211. package/examples/denied-action-retry-guard.sh +12 -0
  212. package/examples/deny-bypass-detector.sh +12 -0
  213. package/examples/deny-rule-integrity-verifier.sh +181 -0
  214. package/examples/dependency-install-guard.sh +12 -0
  215. package/examples/deploy-guard.sh +14 -2
  216. package/examples/deploy-path-verify-guard.sh +12 -0
  217. package/examples/deployment-readback-gate.sh +135 -0
  218. package/examples/deployment-readback-gh-adapter.sh +247 -0
  219. package/examples/deployment-verify-guard.sh +25 -2
  220. package/examples/destructive-db-script-write-guard.sh +166 -0
  221. package/examples/destructive-migration-write-guard.sh +163 -0
  222. package/examples/diff-size-guard.sh +12 -0
  223. package/examples/disabled-feature-toggle-advisor.sh +88 -0
  224. package/examples/disk-partition-guard.sh +12 -0
  225. package/examples/dispatch-allowlist-preflight.sh +301 -0
  226. package/examples/dispatch-liveness-watchdog.sh +216 -0
  227. package/examples/dispatch-receipt.sh +174 -0
  228. package/examples/django-migrate-guard.sh +12 -0
  229. package/examples/dns-config-guard.sh +12 -0
  230. package/examples/docker-dangerous-guard.sh +12 -0
  231. package/examples/docker-volume-guard.sh +0 -0
  232. package/examples/dockerfile-latest-guard.sh +1 -0
  233. package/examples/dotenv-anthropic-key-billing-guard.sh +99 -0
  234. package/examples/dotenv-commit-guard.sh +12 -0
  235. package/examples/dotenv-read-guard.sh +12 -0
  236. package/examples/dotfile-protection-guard.sh +12 -0
  237. package/examples/dotnet-build-on-edit.sh +1 -1
  238. package/examples/drizzle-migrate-guard.sh +27 -2
  239. package/examples/echo-probe-spam-detector.sh +176 -0
  240. package/examples/edit-counter-test-gate.sh +12 -0
  241. package/examples/edit-error-counter.sh +1 -1
  242. package/examples/edit-guard.sh +12 -0
  243. package/examples/edit-old-string-validator.sh +12 -0
  244. package/examples/edit-quote-ambiguity-guard.sh +97 -0
  245. package/examples/edit-retry-loop-guard.sh +0 -0
  246. package/examples/edit-verify.sh +0 -0
  247. package/examples/env-inline-secret-guard.sh +14 -2
  248. package/examples/env-naming-convention.sh +0 -0
  249. package/examples/env-prod-guard.sh +0 -0
  250. package/examples/env-required-check.sh +0 -0
  251. package/examples/env-source-guard.sh +12 -0
  252. package/examples/env-var-check.sh +24 -1
  253. package/examples/ephemeral-container-detector.sh +147 -0
  254. package/examples/error-memory-guard.sh +12 -0
  255. package/examples/evidence-claim-gate.sh +187 -0
  256. package/examples/exploration-budget-guard.sh +12 -0
  257. package/examples/expo-eject-guard.sh +13 -0
  258. package/examples/extended-thinking-loop-guard.sh +139 -0
  259. package/examples/extended-thinking-resume-warning.sh +119 -0
  260. package/examples/extended-thinking-tool-use-mismatch-detector.sh +212 -0
  261. package/examples/fabricated-command-detector.sh +145 -0
  262. package/examples/false-disk-full-guard.sh +63 -0
  263. package/examples/feature-deprecation-detector.sh +109 -0
  264. package/examples/file-change-tracker.sh +1 -1
  265. package/examples/file-change-undo-tracker.sh +0 -0
  266. package/examples/file-edit-backup.sh +63 -14
  267. package/examples/file-reference-check.sh +0 -0
  268. package/examples/file-size-limit.sh +12 -0
  269. package/examples/financial-operation-guard.sh +12 -0
  270. package/examples/firewall-guard.sh +12 -0
  271. package/examples/fish-shell-wrapper.sh +125 -7
  272. package/examples/five-hundred-milestone.sh +1 -0
  273. package/examples/flask-static-route-guard.sh +89 -0
  274. package/examples/forbidden-response-phrase-detector.sh +161 -0
  275. package/examples/gem-push-guard.sh +13 -0
  276. package/examples/gh-cli-destructive-guard.sh +13 -1
  277. package/examples/git-checkout-safety-guard.sh +12 -0
  278. package/examples/git-checkout-uncommitted-guard.sh +12 -0
  279. package/examples/git-config-guard.sh +12 -0
  280. package/examples/git-crypt-worktree-guard.sh +12 -0
  281. package/examples/git-filter-repo-guard.sh +56 -0
  282. package/examples/git-history-rewrite-guard.sh +12 -0
  283. package/examples/git-hook-bypass-guard.sh +0 -0
  284. package/examples/git-maintenance-guard.sh +83 -0
  285. package/examples/git-merge-conflict-prevent.sh +0 -0
  286. package/examples/git-message-length-check.sh +0 -0
  287. package/examples/git-message-length.sh +0 -0
  288. package/examples/git-operations-require-approval.sh +68 -14
  289. package/examples/git-pack-temp-cleanup-guard.sh +102 -0
  290. package/examples/git-push-blast-radius-guard.sh +218 -0
  291. package/examples/git-remote-guard.sh +24 -3
  292. package/examples/git-rm-orphan-wipe-guard.sh +85 -0
  293. package/examples/git-stash-before-checkout.sh +12 -0
  294. package/examples/git-stash-before-danger.sh +0 -0
  295. package/examples/git-submodule-guard.sh +69 -2
  296. package/examples/git-tag-guard.sh +12 -0
  297. package/examples/github-actions-secret-guard.sh +0 -0
  298. package/examples/gitignore-check.sh +0 -0
  299. package/examples/gitops-drift-guard.sh +12 -0
  300. package/examples/go-mod-tidy-warn.sh +1 -0
  301. package/examples/go-vet-after-edit.sh +12 -0
  302. package/examples/goal-iteration-limit-warner.sh +152 -0
  303. package/examples/grep-nul-false-negative-guard.sh +30 -0
  304. package/examples/growthbook-flag-monitor.sh +257 -0
  305. package/examples/hallucination-url-check.sh +1 -1
  306. package/examples/halt-signal-detector.sh +135 -0
  307. package/examples/handoff-on-clear.sh +65 -0
  308. package/examples/hardcoded-ip-guard.sh +1 -0
  309. package/examples/headless-empty-result-guard.sh +0 -0
  310. package/examples/headless-stop-guard.sh +0 -0
  311. package/examples/helm-install-guard.sh +2 -1
  312. package/examples/home-critical-bash-guard.sh +17 -1
  313. package/examples/hook-debug-wrapper.sh +6 -2
  314. package/examples/hook-permission-fixer.sh +0 -0
  315. package/examples/hook-self-disable-detector.sh +99 -0
  316. package/examples/hook-stdout-sanitizer.sh +6 -2
  317. package/examples/hook-tamper-guard.sh +12 -0
  318. package/examples/idle-session-cost-alert.sh +0 -0
  319. package/examples/image-dimension-guard.sh +109 -0
  320. package/examples/image-file-validator.sh +0 -0
  321. package/examples/iteration-quality-degradation-detector.sh +170 -0
  322. package/examples/java-compile-on-edit.sh +1 -1
  323. package/examples/json-syntax-check.sh +0 -0
  324. package/examples/k8s-production-guard.sh +13 -1
  325. package/examples/kill-process-guard.sh +12 -0
  326. package/examples/kubernetes-guard.sh +13 -1
  327. package/examples/laravel-artisan-guard.sh +13 -0
  328. package/examples/large-file-guard.sh +1 -1
  329. package/examples/log-level-guard.sh +0 -0
  330. package/examples/log-truncation-guard.sh +12 -0
  331. package/examples/long-session-malformed-tool-call-detector.sh +183 -0
  332. package/examples/loop-detector.sh +12 -0
  333. package/examples/magic-number-warn.sh +1 -0
  334. package/examples/main-branch-warn.sh +12 -0
  335. package/examples/markdown-link-check.sh +0 -0
  336. package/examples/max-concurrent-agents.sh +12 -0
  337. package/examples/max-edit-size-guard.sh +13 -0
  338. package/examples/max-file-count-guard.sh +0 -0
  339. package/examples/max-file-delete-count.sh +0 -0
  340. package/examples/max-function-length.sh +1 -0
  341. package/examples/max-import-count.sh +0 -0
  342. package/examples/max-subagent-count.sh +0 -0
  343. package/examples/mcp-config-freeze.sh +12 -0
  344. package/examples/mcp-config-poisoning-audit.sh +150 -0
  345. package/examples/mcp-data-boundary.sh +1 -1
  346. package/examples/mcp-misdiagnosis-arrest.sh +209 -0
  347. package/examples/mcp-orphan-leak-warner.sh +49 -0
  348. package/examples/mcp-permissions-ask-warner.sh +151 -0
  349. package/examples/mcp-routine-approval-detector.sh +154 -0
  350. package/examples/mcp-server-allowlist.sh +12 -0
  351. package/examples/mcp-server-guard.sh +12 -0
  352. package/examples/mcp-startup-bloat-detector.sh +87 -0
  353. package/examples/mcp-stdio-compatibility-test.sh +153 -0
  354. package/examples/mcp-tool-audit-log.sh +0 -0
  355. package/examples/mcp-tool-guard.sh +101 -1
  356. package/examples/mcp-warmup-wait.sh +0 -0
  357. package/examples/memory-chain-audit.sh +56 -0
  358. package/examples/memory-orphan-detector.sh +188 -0
  359. package/examples/memory-write-guard.sh +99 -17
  360. package/examples/migration-verify-guard.sh +12 -0
  361. package/examples/model-swap-suggester.sh +177 -0
  362. package/examples/model-version-alert.sh +5 -1
  363. package/examples/model-version-lock.sh +63 -0
  364. package/examples/move-delete-sequence-guard.sh +33 -2
  365. package/examples/multi-file-plan-routing-gate.sh +192 -0
  366. package/examples/multi-vendor-concurrent-warner.sh +108 -0
  367. package/examples/multi-window-auth-drift-detector.sh +183 -0
  368. package/examples/multiline-command-approver.sh +161 -23
  369. package/examples/nested-background-agent-guard.sh +109 -0
  370. package/examples/nested-spawn-inflight-guard.sh +178 -0
  371. package/examples/network-exfil-guard.sh +12 -0
  372. package/examples/network-guard.sh +12 -0
  373. package/examples/network-interface-guard.sh +12 -0
  374. package/examples/nextjs-env-guard.sh +1 -1
  375. package/examples/no-absolute-import.sh +0 -0
  376. package/examples/no-alert-confirm-prompt.sh +0 -0
  377. package/examples/no-anonymous-default-export.sh +0 -0
  378. package/examples/no-any-type.sh +0 -0
  379. package/examples/no-any-typescript.sh +1 -0
  380. package/examples/no-ask-human.sh +12 -0
  381. package/examples/no-assignment-in-condition.sh +0 -0
  382. package/examples/no-base64-exfil.sh +12 -0
  383. package/examples/no-callback-hell.sh +0 -0
  384. package/examples/no-circular-dependency.sh +0 -0
  385. package/examples/no-cleartext-storage.sh +0 -0
  386. package/examples/no-commented-code.sh +0 -0
  387. package/examples/no-commit-fixup.sh +0 -0
  388. package/examples/no-console-assert.sh +0 -0
  389. package/examples/no-console-error-swallow.sh +0 -0
  390. package/examples/no-console-in-prod.sh +0 -0
  391. package/examples/no-console-log-commit.sh +12 -0
  392. package/examples/no-console-log.sh +0 -0
  393. package/examples/no-console-time.sh +0 -0
  394. package/examples/no-cors-wildcard.sh +4 -1
  395. package/examples/no-curl-upload.sh +0 -0
  396. package/examples/no-dangerouslySetInnerHTML.sh +0 -0
  397. package/examples/no-dangling-await.sh +1 -0
  398. package/examples/no-debug-commit.sh +12 -0
  399. package/examples/no-debug-in-commit.sh +0 -0
  400. package/examples/no-deep-nesting.sh +0 -0
  401. package/examples/no-deep-relative-import.sh +1 -0
  402. package/examples/no-default-credentials.sh +0 -0
  403. package/examples/no-deploy-friday.sh +13 -1
  404. package/examples/no-disabled-test.sh +0 -0
  405. package/examples/no-document-write.sh +0 -0
  406. package/examples/no-empty-function.sh +0 -0
  407. package/examples/no-eval-in-template.sh +0 -0
  408. package/examples/no-eval-template.sh +3 -1
  409. package/examples/no-eval.sh +0 -0
  410. package/examples/no-exec-user-input.sh +0 -0
  411. package/examples/no-fixme-ship.sh +12 -0
  412. package/examples/no-floating-promises.sh +0 -0
  413. package/examples/no-force-flag.sh +22 -5
  414. package/examples/no-force-install.sh +0 -0
  415. package/examples/no-git-amend.sh +12 -0
  416. package/examples/no-git-rebase-public.sh +0 -0
  417. package/examples/no-global-install.sh +12 -0
  418. package/examples/no-global-state.sh +0 -0
  419. package/examples/no-hardcoded-port.sh +1 -0
  420. package/examples/no-hardcoded-url.sh +0 -0
  421. package/examples/no-helmet-missing.sh +0 -0
  422. package/examples/no-http-url.sh +1 -0
  423. package/examples/no-http-without-https.sh +0 -0
  424. package/examples/no-inline-style.sh +0 -0
  425. package/examples/no-inline-styles.sh +1 -0
  426. package/examples/no-innerhtml.sh +0 -0
  427. package/examples/no-install-global.sh +12 -0
  428. package/examples/no-jwt-in-url.sh +0 -0
  429. package/examples/no-large-commit.sh +0 -0
  430. package/examples/no-localhost-expose.sh +0 -0
  431. package/examples/no-magic-number.sh +0 -0
  432. package/examples/no-md5-sha1.sh +0 -0
  433. package/examples/no-mixed-line-endings.sh +8 -1
  434. package/examples/no-mutation-in-reducer.sh +0 -0
  435. package/examples/no-nested-ternary.sh +0 -0
  436. package/examples/no-network-exfil.sh +0 -0
  437. package/examples/no-open-redirect.sh +0 -0
  438. package/examples/no-output-truncation.sh +12 -0
  439. package/examples/no-package-downgrade.sh +0 -0
  440. package/examples/no-package-lock-edit.sh +12 -0
  441. package/examples/no-path-join-user-input.sh +0 -0
  442. package/examples/no-port-bind.sh +0 -0
  443. package/examples/no-process-exit.sh +0 -0
  444. package/examples/no-prototype-pollution.sh +0 -0
  445. package/examples/no-push-without-ci.sh +0 -0
  446. package/examples/no-push-without-tests.sh +12 -0
  447. package/examples/no-raw-password-in-url.sh +0 -0
  448. package/examples/no-root-user-docker.sh +1 -0
  449. package/examples/no-root-write.sh +12 -0
  450. package/examples/no-secrets-in-args.sh +4 -1
  451. package/examples/no-secrets-in-logs.sh +0 -0
  452. package/examples/no-sensitive-log.sh +0 -0
  453. package/examples/no-sleep-in-hooks.sh +0 -0
  454. package/examples/no-star-import-python.sh +1 -0
  455. package/examples/no-string-concat-sql.sh +0 -0
  456. package/examples/no-sudo-guard.sh +12 -0
  457. package/examples/no-sync-fs.sh +0 -0
  458. package/examples/no-todo-in-merge.sh +0 -0
  459. package/examples/no-todo-in-production.sh +1 -0
  460. package/examples/no-todo-without-issue.sh +0 -0
  461. package/examples/no-unused-import.sh +0 -0
  462. package/examples/no-var-keyword.sh +0 -0
  463. package/examples/no-verify-blocker.sh +12 -0
  464. package/examples/no-wget-piped-bash.sh +12 -0
  465. package/examples/no-wildcard-cors.sh +0 -0
  466. package/examples/no-wildcard-delete.sh +0 -0
  467. package/examples/no-wildcard-import.sh +0 -0
  468. package/examples/no-with-statement.sh +0 -0
  469. package/examples/no-write-outside-src.sh +0 -0
  470. package/examples/no-xml-external-entity.sh +0 -0
  471. package/examples/non-english-quality-warner.sh +156 -0
  472. package/examples/notify-waiting.sh +1 -1
  473. package/examples/npm-audit-warn.sh +0 -0
  474. package/examples/npm-global-install-guard.sh +12 -0
  475. package/examples/npm-publish-guard.sh +12 -0
  476. package/examples/npm-script-injection.sh +0 -0
  477. package/examples/npm-supply-chain-guard.sh +0 -0
  478. package/examples/nuxt-config-guard.sh +1 -0
  479. package/examples/oauth-refresh-monitor.sh +210 -0
  480. package/examples/opus-degradation-tracker.sh +187 -0
  481. package/examples/opus48-routine-task-warning.sh +196 -0
  482. package/examples/opus48-thinking-wedge-advisor.sh +143 -0
  483. package/examples/output-credential-scan.sh +1 -1
  484. package/examples/output-secret-mask.sh +31 -9
  485. package/examples/output-token-spike-detector.sh +145 -0
  486. package/examples/package-json-guard.sh +12 -0
  487. package/examples/package-lock-frozen.sh +12 -0
  488. package/examples/parallel-batch-size-limiter.sh +121 -0
  489. package/examples/parallel-cascade-detector.sh +116 -0
  490. package/examples/partial-view-claim-arrest.sh +174 -0
  491. package/examples/path-deny-bash-guard.sh +12 -0
  492. package/examples/path-traversal-guard.sh +12 -0
  493. package/examples/per-prompt-token-cap.sh +124 -0
  494. package/examples/permission-audit-log.sh +1 -1
  495. package/examples/permission-denial-enforcer.sh +12 -0
  496. package/examples/permission-entry-validator.sh +0 -0
  497. package/examples/persisted-1m-model-advisor.sh +88 -0
  498. package/examples/php-lint-on-edit.sh +1 -1
  499. package/examples/pii-upload-guard.sh +12 -0
  500. package/examples/pip-publish-guard.sh +13 -0
  501. package/examples/pip-requirements-guard.sh +12 -0
  502. package/examples/pip-venv-required.sh +12 -0
  503. package/examples/plan-mode-edit-guard.sh +12 -0
  504. package/examples/plan-mode-enforcer.sh +12 -0
  505. package/examples/plan-mode-strict-guard.sh +12 -0
  506. package/examples/plugin-hooks-json-bloat-detector.sh +169 -0
  507. package/examples/plugin-process-cleanup.sh +0 -0
  508. package/examples/polyglot-rm-guard.sh +12 -0
  509. package/examples/post-compact-safety.sh +12 -0
  510. package/examples/post-edit-disk-verify.sh +152 -0
  511. package/examples/powershell-remove-item-guard.sh +85 -0
  512. package/examples/pr-description-check.sh +0 -0
  513. package/examples/pr-duplicate-guard.sh +13 -0
  514. package/examples/pre-bash-sed-line-ending-windows.sh +87 -0
  515. package/examples/pre-compact-knowledge-save.sh +0 -0
  516. package/examples/pre-compact-transcript-backup.sh +0 -0
  517. package/examples/pre-execution-claim-detector.sh +179 -0
  518. package/examples/prefer-builtin-tools.sh +10 -1
  519. package/examples/prefer-const.sh +0 -0
  520. package/examples/prefer-dedicated-tools.sh +12 -0
  521. package/examples/prefer-optional-chaining.sh +0 -0
  522. package/examples/prisma-migrate-guard.sh +24 -7
  523. package/examples/production-port-kill-guard.sh +12 -0
  524. package/examples/prompt-injection-guard.sh +2 -1
  525. package/examples/prompt-usage-logger.sh +0 -0
  526. package/examples/protect-claudemd.sh +12 -0
  527. package/examples/protect-dotfiles.sh +12 -0
  528. package/examples/proxy-capture-suggester.sh +159 -0
  529. package/examples/public-artefact-socratic-narrowing.sh +232 -0
  530. package/examples/public-repo-push-guard.sh +12 -0
  531. package/examples/push-requires-test-pass-record.sh +0 -0
  532. package/examples/push-requires-test-pass.sh +12 -0
  533. package/examples/quota-anomaly-detector.sh +173 -0
  534. package/examples/quota-reset-audit.sh +58 -0
  535. package/examples/quoted-flag-approver.sh +99 -10
  536. package/examples/rails-migration-guard.sh +12 -0
  537. package/examples/rate-limit-guard.sh +0 -0
  538. package/examples/read-all-files-enforcer.sh +0 -0
  539. package/examples/read-budget-guard.sh +12 -0
  540. package/examples/read-loop-detector.sh +59 -0
  541. package/examples/read-once-guard.sh +96 -0
  542. package/examples/read-only-mode.sh +12 -0
  543. package/examples/readme-exists-check.sh +0 -0
  544. package/examples/record-read-coverage.sh +73 -0
  545. package/examples/redirect-fragment-warner.sh +149 -0
  546. package/examples/redis-flushall-guard.sh +13 -0
  547. package/examples/redundant-read-blocker.sh +132 -0
  548. package/examples/refusal-arrest-gate.sh +248 -0
  549. package/examples/registry-publish-guard.sh +13 -1
  550. package/examples/remote-control-billing-classifier.sh +135 -0
  551. package/examples/replace-all-guard.sh +12 -0
  552. package/examples/repo-visibility-guard.sh +12 -0
  553. package/examples/reroute-after-block-guard.sh +150 -0
  554. package/examples/response-budget-guard.sh +0 -0
  555. package/examples/resume-drift-watcher.sh +57 -0
  556. package/examples/rg-replace-flag-detector.sh +125 -0
  557. package/examples/rhetorical-verification-prompt-detector.sh +102 -0
  558. package/examples/ripgrep-permission-fix.sh +0 -0
  559. package/examples/rm-safety-net.sh +151 -8
  560. package/examples/role-tool-guard.sh +12 -0
  561. package/examples/route-handler-emptiness-gate.sh +324 -0
  562. package/examples/ruby-lint-on-edit.sh +1 -1
  563. package/examples/runtime-binary-change-detector.sh +102 -0
  564. package/examples/same-command-repeat-detector.sh +196 -0
  565. package/examples/same-correction-arrest.sh +169 -0
  566. package/examples/sandbox-denywrite-enforcer.sh +78 -0
  567. package/examples/sandbox-relative-path-audit.sh +83 -25
  568. package/examples/sandbox-write-verify.sh +12 -0
  569. package/examples/schema-migration-guard.sh +0 -0
  570. package/examples/scope-expansion-receipt.sh +178 -0
  571. package/examples/scope-guard.sh +88 -9
  572. package/examples/secret-file-read-guard.sh +12 -0
  573. package/examples/secret-file-write-guard.sh +150 -0
  574. package/examples/self-modify-bypass-guard.sh +0 -0
  575. package/examples/sensitive-file-read-guard.sh +23 -3
  576. package/examples/sensitive-log-guard.sh +1 -0
  577. package/examples/server-side-prompt-injection-detector.sh +69 -0
  578. package/examples/session-agent-cost-limiter.sh +12 -0
  579. package/examples/session-backup-on-start.sh +1 -1
  580. package/examples/session-cost-alert.sh +12 -0
  581. package/examples/session-drift-guard.sh +12 -0
  582. package/examples/session-duration-guard.sh +25 -2
  583. package/examples/session-end-logger.sh +0 -0
  584. package/examples/session-health-monitor.sh +0 -0
  585. package/examples/session-index-repair.sh +1 -1
  586. package/examples/session-memory-watchdog.sh +1 -0
  587. package/examples/session-permission-reset-guard.sh +12 -0
  588. package/examples/session-persistence-verifier.sh +93 -0
  589. package/examples/session-plugin-pin-watch.sh +68 -0
  590. package/examples/session-rate-monitor.sh +176 -0
  591. package/examples/session-resume-env-fix.sh +0 -0
  592. package/examples/session-start-quota-status.sh +193 -0
  593. package/examples/session-start-safety-check.sh +55 -3
  594. package/examples/session-state-saver.sh +0 -0
  595. package/examples/session-summary-stop.sh +1 -1
  596. package/examples/session-summary.sh +0 -0
  597. package/examples/session-token-counter.sh +1 -1
  598. package/examples/settings-hooks-key-restorer.sh +99 -0
  599. package/examples/settings-json-health-check.sh +57 -0
  600. package/examples/settings-json-model-guard.sh +0 -0
  601. package/examples/settings-regression-tester.sh +188 -0
  602. package/examples/shell-config-truncation-guard.sh +12 -0
  603. package/examples/shell-wrapper-guard.sh +12 -0
  604. package/examples/skill-cumulative-size-detector.sh +104 -0
  605. package/examples/skill-description-drop-detector.sh +148 -0
  606. package/examples/skill-gate.sh +0 -0
  607. package/examples/skill-truncation-detector.sh +154 -0
  608. package/examples/skills-context-recorder.sh +167 -0
  609. package/examples/skills-load-verifier.sh +96 -0
  610. package/examples/skills-settings-validator.sh +139 -0
  611. package/examples/sonnet-45-deprecation-helper.sh +85 -0
  612. package/examples/spec-file-scope-guard.sh +12 -0
  613. package/examples/spring-profile-guard.sh +1 -0
  614. package/examples/spurious-malformed-notice-detector.sh +247 -0
  615. package/examples/sql-bulk-delete-warn.sh +88 -0
  616. package/examples/sql-injection-detect.sh +0 -0
  617. package/examples/ssh-key-protect.sh +12 -0
  618. package/examples/staged-secret-scan.sh +22 -1
  619. package/examples/stale-temp-settings-detector.sh +86 -0
  620. package/examples/standing-rule-session-surfacer.sh +137 -0
  621. package/examples/stop-hook-sigterm-wrapper.sh +182 -0
  622. package/examples/stop-transcript-write-health.sh +64 -0
  623. package/examples/strict-allowlist.sh +57 -15
  624. package/examples/strip-coauthored-by.sh +50 -10
  625. package/examples/subagent-blast-radius-guard.sh +184 -0
  626. package/examples/subagent-boundary-precheck.sh +126 -0
  627. package/examples/subagent-budget-guard.sh +12 -0
  628. package/examples/subagent-claudemd-inject.sh +0 -0
  629. package/examples/subagent-closure-verify-gate.sh +164 -0
  630. package/examples/subagent-destructive-git-guard.sh +120 -0
  631. package/examples/subagent-error-detector.sh +0 -0
  632. package/examples/subagent-forged-system-reminder-guard.sh +156 -0
  633. package/examples/subagent-identity-leak-guard.sh +102 -0
  634. package/examples/subagent-identity-reassertion.sh +51 -0
  635. package/examples/subagent-inheritance-tester.sh +179 -0
  636. package/examples/subagent-permission-mode-guard.sh +110 -0
  637. package/examples/subagent-scope-guard.sh +12 -0
  638. package/examples/subagent-spawn-verification-enforcer.sh +102 -0
  639. package/examples/subagent-tool-allowlist-enforcer.sh +101 -0
  640. package/examples/subagent-tool-call-limiter.sh +87 -15
  641. package/examples/subcommand-chain-guard.sh +12 -0
  642. package/examples/subscription-api-billing-warner.sh +160 -0
  643. package/examples/subscription-bypass-detector.sh +152 -0
  644. package/examples/svelte-lint-on-edit.sh +1 -0
  645. package/examples/swift-build-on-edit.sh +1 -1
  646. package/examples/symlink-guard.sh +27 -2
  647. package/examples/symlink-protect.sh +1 -0
  648. package/examples/system-dir-protection-guard.sh +73 -8
  649. package/examples/system-message-workaround.sh +38 -13
  650. package/examples/system-package-guard.sh +12 -0
  651. package/examples/systemd-service-guard.sh +12 -0
  652. package/examples/task-integrity-guard.sh +12 -0
  653. package/examples/temp-file-cleanup.sh +1 -1
  654. package/examples/temporal-suggestion-detector.sh +135 -0
  655. package/examples/terraform-guard.sh +27 -6
  656. package/examples/test-after-edit.sh +1 -1
  657. package/examples/test-before-push.sh +12 -0
  658. package/examples/test-coverage-reminder.sh +24 -1
  659. package/examples/thinking-budget-effort-mismatch-detector.sh +149 -0
  660. package/examples/timezone-guard.sh +0 -0
  661. package/examples/tmp-output-size-guard.sh +0 -0
  662. package/examples/todo-check.sh +1 -1
  663. package/examples/token-budget-guard.sh +12 -0
  664. package/examples/token-budget-per-task.sh +12 -0
  665. package/examples/token-usage-tracker.sh +7 -1
  666. package/examples/tokenizer-ratio-alert-corpus.sh +90 -0
  667. package/examples/tokenizer-ratio-alert.sh +104 -0
  668. package/examples/tool-call-rate-limiter.sh +0 -0
  669. package/examples/tool-result-correlation-checker.sh +167 -0
  670. package/examples/tool-result-size-guard.sh +132 -0
  671. package/examples/tool-retry-budget-guard.sh +12 -0
  672. package/examples/transcript-contamination-detector.sh +138 -0
  673. package/examples/trustfall-mcp-injection-guard.sh +103 -0
  674. package/examples/ultrareview-large-diff-advisor.sh +184 -0
  675. package/examples/unbounded-output-guard.sh +94 -0
  676. package/examples/uncommitted-changes-stop.sh +1 -0
  677. package/examples/uncommitted-discard-guard.sh +23 -5
  678. package/examples/uncommitted-work-guard.sh +12 -0
  679. package/examples/usage-warn.sh +0 -0
  680. package/examples/user-account-guard.sh +12 -0
  681. package/examples/userprompt-submit-receipt.sh +123 -0
  682. package/examples/variable-expansion-guard.sh +12 -0
  683. package/examples/verify-after-publish-reminder.sh +93 -0
  684. package/examples/verify-before-commit.sh +12 -0
  685. package/examples/version-bump-detector.sh +156 -0
  686. package/examples/version-regression-warner.sh +144 -0
  687. package/examples/vue-lint-on-edit.sh +1 -0
  688. package/examples/warn-cron-cost-trap.sh +173 -0
  689. package/examples/webfetch-runaway-guard.sh +89 -0
  690. package/examples/wellness-break-reminder.sh +118 -0
  691. package/examples/windows-destructive-command-guard.sh +177 -0
  692. package/examples/windows-path-guard.sh +12 -0
  693. package/examples/windows-python-stub-detector.sh +63 -0
  694. package/examples/work-hours-guard.sh +12 -0
  695. package/examples/working-directory-fence.sh +12 -0
  696. package/examples/workspace-lease-guard.sh +205 -0
  697. package/examples/worktree-create-log.sh +1 -0
  698. package/examples/worktree-delete-guard.sh +12 -0
  699. package/examples/worktree-edit-boundary-guard.sh +127 -0
  700. package/examples/worktree-escape-write-guard.sh +114 -0
  701. package/examples/worktree-hook-linker.sh +0 -0
  702. package/examples/worktree-hooks-path-fix.sh +111 -0
  703. package/examples/worktree-parent-write-guard.sh +43 -0
  704. package/examples/worktree-project-unify.sh +2 -1
  705. package/examples/worktree-remove-uncommitted-guard.sh +13 -0
  706. package/examples/worktree-unmerged-guard.sh +7 -1
  707. package/examples/write-byte-integrity-verifier.sh +190 -0
  708. package/examples/write-empty-content-guard.sh +67 -0
  709. package/examples/write-nul-corruption-detector.sh +61 -0
  710. package/examples/write-overwrite-confirm.sh +160 -14
  711. package/examples/write-secret-guard.sh +27 -5
  712. package/examples/write-shrink-guard.sh +12 -0
  713. package/examples/write-test-ratio.sh +0 -0
  714. package/examples/wsl-host-disk-space-guard.sh +97 -0
  715. package/examples/xml-format-leak-detector.sh +266 -0
  716. package/examples/yaml-syntax-check.sh +12 -0
  717. package/hooks/hooks.json +6 -6
  718. package/index.mjs +1718 -183
  719. package/mission.md +2 -0
  720. package/package.json +4 -4
  721. package/plugins/credential-guard/.claude-plugin/plugin.json +9 -7
  722. package/plugins/git-protection/.claude-plugin/plugin.json +10 -8
  723. package/plugins/safety-essentials/.claude-plugin/plugin.json +9 -7
  724. package/plugins/token-guard/.claude-plugin/plugin.json +10 -8
  725. package/scripts/agents-md-sync-setup.sh +156 -0
  726. package/scripts/autonomy-blocked-summary.sh +148 -0
  727. package/scripts/build-search-index.py +43 -0
  728. package/scripts/build-sitemap.py +119 -0
  729. package/scripts/cc-doctor.sh +192 -0
  730. package/scripts/check-hook-event-names.py +127 -0
  731. package/scripts/check-misfire-instrument.sh +64 -0
  732. package/scripts/claim-verify-audit.sh +467 -0
  733. package/scripts/cowork-claudemd-helper.sh +136 -0
  734. package/scripts/june-15-deprecated-model-scan.sh +111 -0
  735. package/scripts/measure-heredoc-shapes.sh +67 -0
  736. package/scripts/measure-literal-match-misfire.sh +110 -0
  737. package/scripts/probe-scope-guard-branches.sh +48 -0
  738. package/scripts/probe-skip-line-both-ways.sh +65 -0
  739. package/scripts/receipts-aggregate.py +199 -0
  740. package/scripts/session-forensic-audit.py +360 -0
  741. package/scripts.json +9 -9
  742. package/scripts.json.bak-2026-07-27-find +13 -0
  743. package/skills/safety-setup/SKILL.md +5 -5
  744. package/tests/approve-side-remaining-two.test.sh +129 -0
  745. package/tests/approver-list-granularity.test.sh +145 -0
  746. package/tests/askuserquestion-autonomy-gate.test.sh +181 -0
  747. package/tests/audit-ci-gate.test.sh +87 -0
  748. package/tests/audit-cross-layer-claudemd.test.sh +170 -0
  749. package/tests/audit-fail-open-parse.test.sh +100 -0
  750. package/tests/auto-approve-compound-tail.test.sh +194 -0
  751. package/tests/auto-mode-path-invoked-commands.test.sh +89 -0
  752. package/tests/auto-mode-quoted-targets.test.sh +127 -0
  753. package/tests/auto-mode-unquoted-targets.test.sh +112 -0
  754. package/tests/bash-secret-output-detector-detects.test.sh +102 -0
  755. package/tests/blindspots-cross-layer.test.sh +177 -0
  756. package/tests/block-database-wipe.test.sh +64 -0
  757. package/tests/bundled-short-flags-bypass.test.sh +85 -0
  758. package/tests/cd-git-allow-compound-tail.test.sh +67 -0
  759. package/tests/chown-guard-filesystem-root.test.sh +64 -0
  760. package/tests/ci-workflow-guard-skip-rule.test.sh +115 -0
  761. package/tests/compound-deny-safe-rm-targets.test.sh +105 -0
  762. package/tests/core-scripts-parser-fallback.test.sh +140 -0
  763. package/tests/destructive-guard-bare-glob.test.sh +74 -0
  764. package/tests/destructive-guard-every-operand.test.sh +100 -0
  765. package/tests/destructive-guard-find-deletion.test.sh +114 -0
  766. package/tests/destructive-guard-flag-order.test.sh +106 -0
  767. package/tests/destructive-guard-mentions-vs-invocations.test.sh +107 -0
  768. package/tests/destructive-guard-quoted-target.test.sh +89 -0
  769. package/tests/destructive-guard-separators.test.sh +105 -0
  770. package/tests/destructive-guard-variable-target.test.sh +98 -0
  771. package/tests/destructive-guard-wrapped-command.test.sh +91 -0
  772. package/tests/doctor-hook-disabling-env.test.sh +92 -0
  773. package/tests/doctor-misspelled-settings-keys.test.sh +106 -0
  774. package/tests/example-guards-wrapped-command.test.sh +169 -0
  775. package/tests/file-edit-backup.test.sh +93 -0
  776. package/tests/git-filter-repo-guard.test.sh +60 -0
  777. package/tests/git-global-options-bypass.test.sh +141 -0
  778. package/tests/git-invocation-prefixes-all-guards.test.sh +114 -0
  779. package/tests/git-maintenance-guard.test.sh +83 -0
  780. package/tests/git-pack-temp-cleanup-guard.test.sh +133 -0
  781. package/tests/git-rm-orphan-wipe-guard.test.sh +66 -0
  782. package/tests/git-submodule-guard.test.sh +50 -0
  783. package/tests/grep-pcre-portability.test.sh +155 -0
  784. package/tests/hook-registration-matches-input.test.sh +73 -0
  785. package/tests/hook-trigger-matches-envelope.test.sh +178 -0
  786. package/tests/install-does-not-claim-protection.test.sh +110 -0
  787. package/tests/install-example-standalone-tools.test.sh +139 -0
  788. package/tests/line-continuation-bypass.test.sh +114 -0
  789. package/tests/mcp-config-poisoning-audit.test.sh +106 -0
  790. package/tests/nested-background-agent-guard.test.sh +58 -0
  791. package/tests/no-unqualified-safety-claims.test.sh +114 -0
  792. package/tests/option-eating-grep-patterns.test.sh +130 -0
  793. package/tests/outdated-core-guards.test.sh +134 -0
  794. package/tests/outdated-report.test.sh +155 -0
  795. package/tests/output-secret-mask-warns.test.sh +73 -0
  796. package/tests/plugin-hooks-fail-open-under-sh.test.sh +165 -0
  797. package/tests/plugins-word-order.test.sh +126 -0
  798. package/tests/powershell-remove-item-guard.test.sh +85 -0
  799. package/tests/project-dir-naming.test.sh +103 -0
  800. package/tests/quoted-safe-targets-and-mentions.test.sh +190 -0
  801. package/tests/reroute-after-block-guard.test.sh +104 -0
  802. package/tests/secret-guard-documented-promises.test.sh +97 -0
  803. package/tests/session-plugin-pin-watch.test.sh +45 -0
  804. package/tests/settings-unreadable-refuses-to-write.test.sh +95 -0
  805. package/tests/shield-no-silent-adoption.test.py +110 -0
  806. package/tests/shield-no-silent-adoption.test.sh +46 -0
  807. package/tests/stop-transcript-write-health.test.sh +46 -0
  808. package/tests/system-dir-guard-root-erased.test.sh +66 -0
  809. package/tests/test-account-billing-log.sh +100 -0
  810. package/tests/test-account-routing-preflight.sh +77 -0
  811. package/tests/test-agent-sdk-credit-pool-monitor.sh +157 -0
  812. package/tests/test-agent-view-quota-warn.sh +184 -0
  813. package/tests/test-agents-md-edit-drift-warner.sh +176 -0
  814. package/tests/test-agents-md-loader.sh +204 -0
  815. package/tests/test-agents-md-sync-checker.sh +125 -0
  816. package/tests/test-ai-slop-punctuation-arrest.sh +280 -0
  817. package/tests/test-allowlist.sh +60 -0
  818. package/tests/test-always-allow-pattern-suggester.sh +147 -0
  819. package/tests/test-anthropic-base-url-guard.sh +88 -0
  820. package/tests/test-articulated-scope-capture.sh +139 -0
  821. package/tests/test-attachment-traversal-guard.sh +168 -0
  822. package/tests/test-aup-block-pattern-logger.sh +315 -0
  823. package/tests/test-aup-false-positive-helper.sh +188 -0
  824. package/tests/test-aup-large-tool-output-warner.sh +370 -0
  825. package/tests/test-aup-retry-loop-guard.sh +341 -0
  826. package/tests/test-auth-expiry-reminder.sh +303 -0
  827. package/tests/test-auth-macos-sleep-detector.sh +254 -0
  828. package/tests/test-auth-path-detector.sh +232 -0
  829. package/tests/test-auth-status-checker.sh +233 -0
  830. package/tests/test-authorized-reconfirmation-detector.sh +280 -0
  831. package/tests/test-background-cost-launch-guard.sh +62 -0
  832. package/tests/test-bash-allowlist-secondary-check.sh +143 -0
  833. package/tests/test-bash-fanout-bounded-rewriter.sh +186 -0
  834. package/tests/test-bash-project-fence.sh +127 -0
  835. package/tests/test-bg-permission-prompt-warner.sh +221 -0
  836. package/tests/test-binary-read-detector.sh +173 -0
  837. package/tests/test-broad-prefix-session-trap-warner.sh +167 -0
  838. package/tests/test-bulk-delete-target-resolution.sh +49 -0
  839. package/tests/test-bypass-mode-effective-verifier.sh +179 -0
  840. package/tests/test-cache-creation-drift-detector.sh +244 -0
  841. package/tests/test-cache-residue-detector.sh +429 -0
  842. package/tests/test-cache-tier-logger.sh +59 -0
  843. package/tests/test-cache-ttl-eviction-detector.sh +282 -0
  844. package/tests/test-cch-sentinel-precommit-guard.sh +64 -0
  845. package/tests/test-claim-verify-detector.sh +222 -0
  846. package/tests/test-claim-vs-caveat-checker.sh +134 -0
  847. package/tests/test-claude-code-version-pin-advisor.sh +353 -0
  848. package/tests/test-claude-md-reinjector.sh +173 -0
  849. package/tests/test-claude-md-size-monitor.sh +107 -0
  850. package/tests/test-claude-update-budget-guard.sh +132 -0
  851. package/tests/test-claude-update-smart.sh +91 -0
  852. package/tests/test-claudemd-tool-prohibition.sh +239 -0
  853. package/tests/test-cli-config-pinning-detector.sh +233 -0
  854. package/tests/test-cliff-countdown-advisor.sh +138 -0
  855. package/tests/test-closure-word-verify-gate.sh +158 -0
  856. package/tests/test-commit-all-scope-guard.sh +73 -0
  857. package/tests/test-commitment-carry-forward-arrest.sh +250 -0
  858. package/tests/test-compact-dispatch-watchdog.sh +147 -0
  859. package/tests/test-completion-claim-without-verification-detector.sh +326 -0
  860. package/tests/test-compound-bash-permission-resolver.sh +264 -0
  861. package/tests/test-compound-command-deny-enforcer.sh +67 -0
  862. package/tests/test-context-length-budget.sh +68 -0
  863. package/tests/test-context-usage-drift-alert.sh +52 -22
  864. package/tests/test-cost-incident-self-audit.sh +94 -0
  865. package/tests/test-cowork-claude-md-load-checker.sh +257 -0
  866. package/tests/test-cowork-claudemd-helper.sh +141 -0
  867. package/tests/test-cowork-fuse-staleness-watcher.sh +287 -0
  868. package/tests/test-cowork-hook-absence-warner.sh +230 -0
  869. package/tests/test-cowork-model-picker-advisor.sh +317 -0
  870. package/tests/test-credential-exfil-guard.sh +62 -0
  871. package/tests/test-cron-create-receipt.sh +165 -0
  872. package/tests/test-cross-product-mcp-spawn-detector.sh +112 -0
  873. package/tests/test-daemon-zombie-worker-surfacer.sh +71 -0
  874. package/tests/test-daily-cost-guard.sh +131 -0
  875. package/tests/test-deny-rule-integrity-verifier.sh +288 -0
  876. package/tests/test-deployment-readback-gate.sh +92 -0
  877. package/tests/test-deployment-readback-gh-adapter.sh +163 -0
  878. package/tests/test-disabled-feature-toggle-advisor.sh +78 -0
  879. package/tests/test-dispatch-allowlist-preflight.sh +385 -0
  880. package/tests/test-dispatch-liveness-watchdog.sh +319 -0
  881. package/tests/test-dispatch-receipt.sh +314 -0
  882. package/tests/test-dotenv-anthropic-key-billing-guard.sh +160 -0
  883. package/tests/test-echo-probe-spam-detector.sh +143 -0
  884. package/tests/test-edit-quote-ambiguity-guard.sh +75 -0
  885. package/tests/test-ephemeral-container-detector.sh +251 -0
  886. package/tests/test-evidence-claim-gate.sh +291 -0
  887. package/tests/test-extended-thinking-loop-guard.sh +289 -0
  888. package/tests/test-extended-thinking-resume-warning.sh +240 -0
  889. package/tests/test-extended-thinking-tool-use-mismatch-detector.sh +236 -0
  890. package/tests/test-fabricated-command-detector.sh +296 -0
  891. package/tests/test-false-disk-full-guard.sh +36 -0
  892. package/tests/test-feature-deprecation-detector.sh +117 -0
  893. package/tests/test-forbidden-response-phrase-detector.sh +246 -0
  894. package/tests/test-git-operations-require-approval.sh +53 -0
  895. package/tests/test-git-push-blast-radius-guard.sh +115 -0
  896. package/tests/test-goal-iteration-limit-warner.sh +128 -0
  897. package/tests/test-growthbook-flag-monitor.sh +428 -0
  898. package/tests/test-halt-signal-detector.sh +120 -0
  899. package/tests/test-hook-self-disable-detector.sh +232 -0
  900. package/tests/test-iteration-quality-degradation-detector.sh +244 -0
  901. package/tests/test-long-session-malformed-tool-call-detector.sh +185 -0
  902. package/tests/test-marketplace-plugins.sh +193 -0
  903. package/tests/test-mcp-misdiagnosis-arrest.sh +235 -0
  904. package/tests/test-mcp-orphan-leak-warner.sh +71 -0
  905. package/tests/test-mcp-permissions-ask-warner.sh +207 -0
  906. package/tests/test-mcp-routine-approval-detector.sh +229 -0
  907. package/tests/test-mcp-startup-bloat-detector.sh +141 -0
  908. package/tests/test-mcp-stdio-compatibility-test.sh +112 -0
  909. package/tests/test-memory-chain-audit.sh +59 -0
  910. package/tests/test-memory-orphan-detector.sh +227 -0
  911. package/tests/test-model-swap-suggester.sh +368 -0
  912. package/tests/test-model-version-lock.sh +83 -0
  913. package/tests/test-multi-file-plan-routing-gate.sh +277 -0
  914. package/tests/test-multi-window-auth-drift-detector.sh +262 -0
  915. package/tests/test-nested-spawn-inflight-guard.sh +281 -0
  916. package/tests/test-no-force-flag.sh +49 -0
  917. package/tests/test-non-english-quality-warner.sh +229 -0
  918. package/tests/test-oauth-refresh-monitor.sh +311 -0
  919. package/tests/test-opus-degradation-tracker.sh +274 -0
  920. package/tests/test-opus48-routine-task-warning.sh +201 -0
  921. package/tests/test-opus48-thinking-wedge-advisor.sh +249 -0
  922. package/tests/test-output-token-spike-detector.sh +315 -0
  923. package/tests/test-parallel-batch-size-limiter.sh +228 -0
  924. package/tests/test-parallel-cascade-detector.sh +191 -0
  925. package/tests/test-partial-view-claim-arrest.sh +272 -0
  926. package/tests/test-per-prompt-token-cap.sh +136 -0
  927. package/tests/test-persisted-1m-model-advisor.sh +71 -0
  928. package/tests/test-plugin-hooks-json-bloat-detector.sh +267 -0
  929. package/tests/test-post-edit-disk-verify.sh +294 -0
  930. package/tests/test-pre-bash-sed-line-ending-windows.sh +108 -0
  931. package/tests/test-pre-execution-claim-detector.sh +366 -0
  932. package/tests/test-private-key-backup-and-git-credentials.sh +100 -0
  933. package/tests/test-proxy-capture-suggester.sh +214 -0
  934. package/tests/test-public-artefact-socratic-narrowing.sh +346 -0
  935. package/tests/test-quota-anomaly-detector.sh +321 -0
  936. package/tests/test-quota-reset-audit.sh +81 -0
  937. package/tests/test-read-loop-detector.sh +137 -0
  938. package/tests/test-read-once-guard.sh +85 -0
  939. package/tests/test-receipts-aggregate.sh +143 -0
  940. package/tests/test-redirect-fragment-warner.sh +130 -0
  941. package/tests/test-redundant-read-blocker.sh +155 -0
  942. package/tests/test-refusal-arrest-gate.sh +303 -0
  943. package/tests/test-remote-control-billing-classifier.sh +125 -0
  944. package/tests/test-resume-drift-watcher.sh +65 -0
  945. package/tests/test-rg-replace-flag-detector.sh +175 -0
  946. package/tests/test-rhetorical-verification-prompt-detector.sh +237 -0
  947. package/tests/test-rm-safety-net.sh +115 -0
  948. package/tests/test-route-handler-emptiness-gate.sh +300 -0
  949. package/tests/test-runtime-binary-change-detector.sh +196 -0
  950. package/tests/test-same-command-repeat-detector.sh +165 -0
  951. package/tests/test-same-correction-arrest.sh +165 -0
  952. package/tests/test-scope-expansion-receipt.sh +207 -0
  953. package/tests/test-server-side-prompt-injection-detector.sh +181 -0
  954. package/tests/test-session-persistence-verifier.sh +128 -0
  955. package/tests/test-session-rate-monitor.sh +284 -0
  956. package/tests/test-session-start-quota-status.sh +210 -0
  957. package/tests/test-session-start-safety-check.sh +138 -0
  958. package/tests/test-settings-hooks-key-restorer.sh +257 -0
  959. package/tests/test-settings-json-health-check.sh +70 -0
  960. package/tests/test-settings-regression-tester.sh +197 -0
  961. package/tests/test-skill-cumulative-size-detector.sh +198 -0
  962. package/tests/test-skill-description-drop-detector.sh +236 -0
  963. package/tests/test-skill-truncation-detector.sh +263 -0
  964. package/tests/test-skills-context-recorder.sh +329 -0
  965. package/tests/test-skills-load-verifier.sh +184 -0
  966. package/tests/test-skills-settings-validator.sh +242 -0
  967. package/tests/test-sonnet-45-deprecation-helper.sh +150 -0
  968. package/tests/test-spurious-malformed-notice-detector.sh +290 -0
  969. package/tests/test-sql-bulk-delete-warn.sh +123 -0
  970. package/tests/test-ssh-key-protect.sh +81 -0
  971. package/tests/test-stale-temp-settings-detector.sh +161 -0
  972. package/tests/test-standing-rule-session-surfacer.sh +215 -0
  973. package/tests/test-starter-hooks-manifest.sh +96 -0
  974. package/tests/test-stop-hook-sigterm-wrapper.sh +258 -0
  975. package/tests/test-strict-allowlist.sh +72 -0
  976. package/tests/test-subagent-boundary-precheck.sh +137 -0
  977. package/tests/test-subagent-closure-verify-gate.sh +193 -0
  978. package/tests/test-subagent-destructive-git-guard.sh +86 -0
  979. package/tests/test-subagent-identity-leak-guard.sh +62 -0
  980. package/tests/test-subagent-identity-reassertion.sh +61 -0
  981. package/tests/test-subagent-inheritance-tester.sh +319 -0
  982. package/tests/test-subagent-permission-mode-guard.sh +61 -0
  983. package/tests/test-subagent-spawn-verification-enforcer.sh +60 -0
  984. package/tests/test-subagent-tool-allowlist-enforcer.sh +62 -0
  985. package/tests/test-subagent-tool-call-limiter.sh +97 -0
  986. package/tests/test-subscription-api-billing-warner.sh +138 -0
  987. package/tests/test-subscription-bypass-detector.sh +255 -0
  988. package/tests/test-temporal-suggestion-detector.sh +183 -0
  989. package/tests/test-thinking-budget-effort-mismatch-detector.sh +327 -0
  990. package/tests/test-tokenizer-ratio-alert-corpus.sh +77 -0
  991. package/tests/test-tokenizer-ratio-alert.sh +93 -0
  992. package/tests/test-tool-result-correlation-checker.sh +264 -0
  993. package/tests/test-tool-result-size-guard.sh +121 -0
  994. package/tests/test-transcript-contamination-detector.sh +264 -0
  995. package/tests/test-trigger-header-parsing.sh +151 -0
  996. package/tests/test-ultrareview-large-diff-advisor.sh +192 -0
  997. package/tests/test-userprompt-submit-receipt.sh +181 -0
  998. package/tests/test-verify-after-publish-reminder.sh +184 -0
  999. package/tests/test-version-bump-detector.sh +212 -0
  1000. package/tests/test-version-regression-warner.sh +165 -0
  1001. package/tests/test-warn-cron-cost-trap.sh +82 -0
  1002. package/tests/test-webfetch-runaway-guard.sh +77 -0
  1003. package/tests/test-wellness-break-reminder.sh +138 -0
  1004. package/tests/test-windows-destructive-command-guard.sh +169 -0
  1005. package/tests/test-windows-python-stub-detector.sh +146 -0
  1006. package/tests/test-worktree-edit-boundary-guard.sh +219 -0
  1007. package/tests/test-write-byte-integrity-verifier.sh +192 -0
  1008. package/tests/test-xml-format-leak-detector.sh +299 -0
  1009. package/tests/trustfall-mcp-injection-guard.test.sh +183 -0
  1010. package/tests/workspace-lease-guard.test.sh +144 -0
  1011. package/tests/worktree-escape-write-guard.test.sh +68 -0
  1012. package/tests/worktree-hooks-path-fix.test.sh +181 -0
  1013. package/tests/worktree-parent-write-guard.test.sh +51 -0
  1014. package/tests/write-empty-content-guard.test.sh +39 -0
  1015. package/tests/write-nul-corruption-detector.test.sh +29 -0
  1016. package/tests/write-overwrite-unread-content.test.sh +178 -0
  1017. package/tests/wsl-host-disk-space-guard.test.sh +55 -0
@@ -0,0 +1,62 @@
1
+ #!/bin/bash
2
+ # Tests for subagent-tool-allowlist-enforcer.sh (Issue #55653 prevention)
3
+ HOOK="examples/subagent-tool-allowlist-enforcer.sh"
4
+ PASS=0 FAIL=0
5
+
6
+ assert_contains() { if echo "$2" | grep -q "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected '$3')"; fi; }
7
+ assert_not_contains() { if ! echo "$2" | grep -q "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (unexpected '$3')"; fi; }
8
+ assert_exit() { if [ "$2" = "$3" ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected exit $3, got $2)"; fi; }
9
+
10
+ # Test 1: Empty prompt should silently pass
11
+ OUT=$(echo '{"tool_input":{"prompt":""}}' | bash "$HOOK" 2>&1)
12
+ RC=$?
13
+ assert_not_contains "empty prompt no warning" "$OUT" "Subagent tool boundary"
14
+ assert_exit "empty prompt exit 0" "$RC" "0"
15
+
16
+ # Test 2: Vague prompt should warn on all 3 checks
17
+ OUT=$(echo '{"tool_input":{"prompt":"please investigate the auth flow"}}' | bash "$HOOK" 2>&1)
18
+ RC=$?
19
+ assert_contains "vague warns allowed tools" "$OUT" "No allowed tool set"
20
+ assert_contains "vague warns forbidden tools" "$OUT" "No forbidden tools"
21
+ assert_contains "vague warns verification" "$OUT" "No parent verification"
22
+ assert_contains "vague references issue" "$OUT" "#55653"
23
+ assert_exit "vague exit 0 advisory" "$RC" "0"
24
+
25
+ # Test 3: Allowed tools named, other 2 missing
26
+ OUT=$(echo '{"tool_input":{"prompt":"You can use Read and Grep. Investigate src/auth/login.ts."}}' | bash "$HOOK" 2>&1)
27
+ assert_not_contains "allowed only no allowed warning" "$OUT" "No allowed tool set"
28
+ assert_contains "allowed only warns forbidden" "$OUT" "No forbidden tools"
29
+ assert_contains "allowed only warns verification" "$OUT" "No parent verification"
30
+
31
+ # Test 4: Read-only constraint named, other 2 missing
32
+ OUT=$(echo '{"tool_input":{"prompt":"This is read-only. Run a task."}}' | bash "$HOOK" 2>&1)
33
+ assert_contains "read-only only warns allowed" "$OUT" "No allowed tool set"
34
+ assert_not_contains "read-only only no forbidden warning" "$OUT" "No forbidden tools"
35
+ assert_contains "read-only only warns verification" "$OUT" "No parent verification"
36
+
37
+ # Test 5: Verification step named, other 2 missing
38
+ OUT=$(echo '{"tool_input":{"prompt":"Investigate something. I will verify with stat."}}' | bash "$HOOK" 2>&1)
39
+ assert_contains "verify only warns allowed" "$OUT" "No allowed tool set"
40
+ assert_contains "verify only warns forbidden" "$OUT" "No forbidden tools"
41
+ assert_not_contains "verify only no verification warning" "$OUT" "No parent verification"
42
+
43
+ # Test 6: All 3 boundary instructions present, no warning
44
+ OUT=$(echo '{"tool_input":{"prompt":"You can use Read and Grep. Do not write or edit any file. I will verify the result with file stat. Investigate src/auth/login.ts."}}' | bash "$HOOK" 2>&1)
45
+ RC=$?
46
+ assert_not_contains "well-formed no warning" "$OUT" "Subagent tool boundary"
47
+ assert_exit "well-formed exit 0" "$RC" "0"
48
+
49
+ # Test 7: Strict mode blocks vague prompts
50
+ OUT=$(echo '{"tool_input":{"prompt":"investigate something"}}' | CC_SUBAGENT_TOOL_REQUIRE_ALL=1 bash "$HOOK" 2>&1)
51
+ RC=$?
52
+ assert_contains "strict mode warns" "$OUT" "Subagent tool boundary"
53
+ assert_exit "strict mode blocks (exit 2)" "$RC" "2"
54
+
55
+ # Test 8: Missing prompt field should silently pass
56
+ OUT=$(echo '{}' | bash "$HOOK" 2>&1)
57
+ RC=$?
58
+ assert_not_contains "missing prompt no warning" "$OUT" "Subagent tool boundary"
59
+ assert_exit "missing prompt exit 0" "$RC" "0"
60
+
61
+ echo "Results: $PASS passed, $FAIL failed"
62
+ [ "$FAIL" -eq 0 ]
@@ -0,0 +1,97 @@
1
+ #!/bin/bash
2
+ # Tests for subagent-tool-call-limiter.sh
3
+ #
4
+ # 2026-08-09 新規。このhookには**テストが1本も無かった**。
5
+ #
6
+ # 旧実装は $PPID(親プロセスのID)をセッションの識別子として使っていた。
7
+ # 遮断そのものは動く(親が安定していれば $PPID は持続する)。
8
+ # 残る欠陥は「$PPID はセッションの識別子ではない」こと:
9
+ # 同じ親から複数のセッションが走るとカウンターが混ざる。
10
+ # 実測(修正前) = 同じ親から session_id が sX と sY の呼び出しを6回ずつ交互に流すと、
11
+ # カウンターファイルは1個だけで値は12(=6+6)。片方が上限を使い切ると、
12
+ # もう片方は何もしていなくても遮断される。
13
+ # 修正後は session_id ごとに分ける。
14
+ #
15
+ # ★このテストを書く過程で自分の測定を1つ取り下げた。最初「200回叩いて遮断0回=
16
+ # この制限は一度も働いていない」と測ったが、それはこちらが $( ) の中で hook を
17
+ # 呼んだせいで呼び出しごとに別のサブシェルが親になっていたためで、
18
+ # 仕掛けが作った結果だった。親を固定して測り直すと5回ちゃんと遮断する。
19
+ # だからこのテストは「遮断が動くこと」と「セッションが独立すること」の両方を見る。
20
+
21
+ HOOK="examples/subagent-tool-call-limiter.sh"
22
+ PASS=0 FAIL=0
23
+ ok() { PASS=$((PASS+1)); }
24
+ ng() { FAIL=$((FAIL+1)); echo "FAIL: $1"; }
25
+ assert_eq() { if [ "$2" = "$3" ]; then ok; else ng "$1 (expected '$3', got '$2')"; fi; }
26
+
27
+ SID="test-limiter-$$-$RANDOM"
28
+ J="{\"session_id\":\"$SID\",\"tool_name\":\"Task\",\"tool_input\":{}}"
29
+ CF="/tmp/claude-tool-call-counter-$SID"
30
+ rm -f "$CF"
31
+
32
+ # 上限を10にして15回叩く
33
+ blocked=0
34
+ for i in $(seq 1 15); do
35
+ printf '%s' "$J" | CC_MAX_TOOL_CALLS=10 bash "$HOOK" >/dev/null 2>&1
36
+ [ $? -eq 2 ] && blocked=$((blocked+1))
37
+ done
38
+
39
+ # 回帰1: 上限を超えたら遮断する(修正前は0回だった)
40
+ assert_eq "上限10で15回叩くと11..15回目の5回が遮断される" "$blocked" "5"
41
+
42
+ # 回帰2: カウンターが呼び出しをまたいで貯まる(修正前は毎回1にリセットされていた)
43
+ # ★2026-08-27に期待値を 15 → 10 へ変えた。挙動の変更が意図的なため。
44
+ # 記録を遮断の判定より後ろへ移したので、遮断された呼び出しはカウンターを進めない。
45
+ # 前は遮断されるたびに 11,12,…15 と増え、案内を読んで再試行するほど数字が悪化した。
46
+ # この試験が守りたい「呼び出しをまたいで貯まる」(修正前は毎回1)は 10 でも守られている。
47
+ assert_eq "カウンターが上限で止まる(遮断された5回は加算されない)" "$(cat "$CF" 2>/dev/null)" "10"
48
+
49
+ # 回帰2b: 遮断された状態で何度叩いてもカウンターが動かない(再試行で待ちが延びない)
50
+ before2b=$(cat "$CF" 2>/dev/null)
51
+ for i in 1 2 3; do printf '%s' "$J" | CC_MAX_TOOL_CALLS=10 bash "$HOOK" >/dev/null 2>&1; done
52
+ assert_eq "遮断中の再試行はカウンターを動かさない" "$(cat "$CF" 2>/dev/null)" "$before2b"
53
+
54
+ # 回帰3: カウンターのファイルはセッションにつき1個(修正前は呼び出しごとに1個increaseしていた)
55
+ assert_eq "ファイルはセッションにつき1個" "$(ls /tmp/claude-tool-call-counter-$SID 2>/dev/null | wc -l)" "1"
56
+
57
+ # 回帰4: 別セッションは独立して数える
58
+ SID2="test-limiter2-$$-$RANDOM"
59
+ J2="{\"session_id\":\"$SID2\",\"tool_name\":\"Task\",\"tool_input\":{}}"
60
+ CF2="/tmp/claude-tool-call-counter-$SID2"
61
+ rm -f "$CF2"
62
+ printf '%s' "$J2" | CC_MAX_TOOL_CALLS=10 bash "$HOOK" >/dev/null 2>&1
63
+ rc2=$?
64
+ assert_eq "別セッションの1回目は遮断されない" "$rc2" "0"
65
+ assert_eq "別セッションのカウンターは1" "$(cat "$CF2" 2>/dev/null)" "1"
66
+
67
+ # 上限内は素通しする
68
+ SID3="test-limiter3-$$-$RANDOM"
69
+ J3="{\"session_id\":\"$SID3\",\"tool_name\":\"Task\",\"tool_input\":{}}"
70
+ CF3="/tmp/claude-tool-call-counter-$SID3"
71
+ rm -f "$CF3"
72
+ printf '%s' "$J3" | CC_MAX_TOOL_CALLS=100 bash "$HOOK" >/dev/null 2>&1
73
+ assert_eq "上限内は exit 0" "$?" "0"
74
+
75
+ # 遮断のメッセージが理由を述べる
76
+ echo "10" > "$CF3"
77
+ MSG=$(printf '%s' "$J3" | CC_MAX_TOOL_CALLS=10 bash "$HOOK" 2>&1 >/dev/null)
78
+ if echo "$MSG" | grep -q "limit"; then ok; else ng "遮断のメッセージが上限に触れる"; fi
79
+
80
+ # 回帰5 (本命): 同じ親プロセスから2つのセッションを交互に流してもカウンターが混ざらない。
81
+ # これが旧実装($PPID をセッション識別子にしていた)で壊れていた点。
82
+ # 修正前の実測 = ファイル1個・値12(=6+6)。片方が上限を使い切るともう片方も遮断された。
83
+ SX="test-mix-x-$$-$RANDOM"; SY="test-mix-y-$$-$RANDOM"
84
+ JX="{\"session_id\":\"$SX\",\"tool_name\":\"Task\",\"tool_input\":{}}"
85
+ JY="{\"session_id\":\"$SY\",\"tool_name\":\"Task\",\"tool_input\":{}}"
86
+ rm -f "/tmp/claude-tool-call-counter-$SX" "/tmp/claude-tool-call-counter-$SY"
87
+ for i in $(seq 1 6); do
88
+ printf '%s' "$JX" | CC_MAX_TOOL_CALLS=10 bash "$HOOK" >/dev/null 2>&1
89
+ printf '%s' "$JY" | CC_MAX_TOOL_CALLS=10 bash "$HOOK" >/dev/null 2>&1
90
+ done
91
+ assert_eq "同じ親でもセッションXは6" "$(cat "/tmp/claude-tool-call-counter-$SX" 2>/dev/null)" "6"
92
+ assert_eq "同じ親でもセッションYは6" "$(cat "/tmp/claude-tool-call-counter-$SY" 2>/dev/null)" "6"
93
+ rm -f "/tmp/claude-tool-call-counter-$SX" "/tmp/claude-tool-call-counter-$SY"
94
+
95
+ rm -f "$CF" "$CF2" "$CF3"
96
+ echo "Results: $PASS passed, $FAIL failed"
97
+ [ "$FAIL" -eq 0 ]
@@ -0,0 +1,138 @@
1
+ #!/bin/bash
2
+ # Tests for subscription-api-billing-warner.sh
3
+ HOOK="examples/subscription-api-billing-warner.sh"
4
+ PASS=0 FAIL=0
5
+
6
+ assert_contains() { if echo "$2" | grep -q "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected '$3')"; fi; }
7
+ assert_not_contains() { if ! echo "$2" | grep -q "$3"; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (unexpected '$3')"; fi; }
8
+ assert_exit() { if [ "$2" = "$3" ]; then PASS=$((PASS+1)); else FAIL=$((FAIL+1)); echo "FAIL: $1 (expected exit $3, got $2)"; fi; }
9
+
10
+ HOOK_ABS="$PWD/$HOOK"
11
+
12
+ # Controlled temp settings files
13
+ TMP=$(mktemp -d)
14
+ trap 'rm -rf "$TMP"' EXIT
15
+ EMPTY_SETTINGS="$TMP/empty-settings.json"
16
+ printf '{"hooks":{}}' > "$EMPTY_SETTINGS"
17
+ HELPER_SETTINGS="$TMP/helper-settings.json"
18
+ printf '{"apiKeyHelper":"/usr/local/bin/get-key.sh","permissions":{}}' > "$HELPER_SETTINGS"
19
+ NOFILE="$TMP/does-not-exist.json"
20
+
21
+ # Base env wrapper: clears the three signals so "absent" is deterministic
22
+ # even though this test may run inside a Claude Code session that sets them.
23
+ run_clean() { env -u ANTHROPIC_API_KEY -u ANTHROPIC_AUTH_TOKEN -u ANTHROPIC_ACCOUNT_LABEL "$@"; }
24
+
25
+ # Test 1: nothing set, empty settings → silent pass
26
+ OUT=$(run_clean CC_SUB_BILLING_SETTINGS_OVERRIDE="$EMPTY_SETTINGS" \
27
+ bash "$HOOK_ABS" </dev/null 2>&1); RC=$?
28
+ assert_not_contains "clean env no advisory" "$OUT" "API / purchased credits"
29
+ assert_exit "clean env exit 0" "$RC" "0"
30
+
31
+ # Test 2: ANTHROPIC_API_KEY set → advisory + exit 0
32
+ # (placeholder value deliberately NOT in Anthropic key format to avoid
33
+ # secret-scanning false positives; the hook never reads the value anyway)
34
+ OUT=$(run_clean ANTHROPIC_API_KEY="dummy-placeholder-LEAKCANARY42" \
35
+ CC_SUB_BILLING_SETTINGS_OVERRIDE="$NOFILE" \
36
+ bash "$HOOK_ABS" </dev/null 2>&1); RC=$?
37
+ assert_contains "api key triggers advisory" "$OUT" "API / purchased credits"
38
+ assert_contains "advisory names the env var" "$OUT" "ANTHROPIC_API_KEY is set"
39
+ assert_contains "advisory cites #64613" "$OUT" "#64613"
40
+ assert_exit "api key advisory exit 0" "$RC" "0"
41
+
42
+ # Test 3: hook never prints the key value (the canary must not leak)
43
+ assert_not_contains "key value never printed" "$OUT" "LEAKCANARY42"
44
+
45
+ # Test 4: ANTHROPIC_AUTH_TOKEN set → advisory
46
+ OUT=$(run_clean ANTHROPIC_AUTH_TOKEN="tok-abc" \
47
+ CC_SUB_BILLING_SETTINGS_OVERRIDE="$NOFILE" \
48
+ bash "$HOOK_ABS" </dev/null 2>&1); RC=$?
49
+ assert_contains "auth token triggers advisory" "$OUT" "ANTHROPIC_AUTH_TOKEN is set"
50
+ assert_exit "auth token exit 0" "$RC" "0"
51
+
52
+ # Test 5: apiKeyHelper in settings → advisory naming the file
53
+ OUT=$(run_clean CC_SUB_BILLING_SETTINGS_OVERRIDE="$HELPER_SETTINGS" \
54
+ bash "$HOOK_ABS" </dev/null 2>&1); RC=$?
55
+ assert_contains "apiKeyHelper triggers advisory" "$OUT" "apiKeyHelper is configured"
56
+ assert_contains "apiKeyHelper names the file" "$OUT" "helper-settings.json"
57
+ assert_exit "apiKeyHelper exit 0" "$RC" "0"
58
+
59
+ # Test 6: settings without apiKeyHelper → no advisory from that source
60
+ OUT=$(run_clean CC_SUB_BILLING_SETTINGS_OVERRIDE="$EMPTY_SETTINGS" \
61
+ bash "$HOOK_ABS" </dev/null 2>&1); RC=$?
62
+ assert_not_contains "empty settings no advisory" "$OUT" "apiKeyHelper is configured"
63
+
64
+ # Test 7: CC_SUB_BILLING_DISABLE=1 silences even with key set
65
+ OUT=$(run_clean ANTHROPIC_API_KEY="sk-x" CC_SUB_BILLING_DISABLE=1 \
66
+ CC_SUB_BILLING_SETTINGS_OVERRIDE="$HELPER_SETTINGS" \
67
+ bash "$HOOK_ABS" </dev/null 2>&1); RC=$?
68
+ assert_not_contains "disable suppresses advisory" "$OUT" "API / purchased credits"
69
+ assert_exit "disable exit 0" "$RC" "0"
70
+
71
+ # Test 8: ANTHROPIC_ACCOUNT_LABEL set → silent (deliberate API use)
72
+ OUT=$(env -u ANTHROPIC_API_KEY -u ANTHROPIC_AUTH_TOKEN \
73
+ ANTHROPIC_API_KEY="sk-x" ANTHROPIC_ACCOUNT_LABEL="work" \
74
+ CC_SUB_BILLING_SETTINGS_OVERRIDE="$HELPER_SETTINGS" \
75
+ bash "$HOOK_ABS" </dev/null 2>&1); RC=$?
76
+ assert_not_contains "account label suppresses advisory" "$OUT" "API / purchased credits"
77
+ assert_exit "account label exit 0" "$RC" "0"
78
+
79
+ # Test 9: advisory points to /status and the refund path
80
+ OUT=$(run_clean ANTHROPIC_API_KEY="sk-x" \
81
+ CC_SUB_BILLING_SETTINGS_OVERRIDE="$NOFILE" \
82
+ bash "$HOOK_ABS" </dev/null 2>&1); RC=$?
83
+ assert_contains "advisory points to /status" "$OUT" "/status"
84
+ assert_contains "advisory points to refund path" "$OUT" "support.claude.com"
85
+ assert_contains "advisory names silence path" "$OUT" "CC_SUB_BILLING_DISABLE"
86
+
87
+ # Test 10: stdin payload consumed without hanging
88
+ PAYLOAD='{"hook_event_name":"SessionStart","session_id":"abc"}'
89
+ OUT=$(echo "$PAYLOAD" | run_clean ANTHROPIC_API_KEY="sk-x" \
90
+ CC_SUB_BILLING_SETTINGS_OVERRIDE="$NOFILE" \
91
+ bash "$HOOK_ABS" 2>&1); RC=$?
92
+ assert_contains "stdin consumed, advisory still fires" "$OUT" "API / purchased credits"
93
+ assert_exit "stdin path exit 0" "$RC" "0"
94
+
95
+ # Test 11: both env var and apiKeyHelper → advisory lists both reasons
96
+ OUT=$(run_clean ANTHROPIC_API_KEY="sk-x" \
97
+ CC_SUB_BILLING_SETTINGS_OVERRIDE="$HELPER_SETTINGS" \
98
+ bash "$HOOK_ABS" </dev/null 2>&1); RC=$?
99
+ assert_contains "both sources: env var listed" "$OUT" "ANTHROPIC_API_KEY is set"
100
+ assert_contains "both sources: helper listed" "$OUT" "apiKeyHelper is configured"
101
+ assert_exit "both sources exit 0" "$RC" "0"
102
+
103
+ # Test 12: empty-string env var is treated as not set
104
+ OUT=$(run_clean ANTHROPIC_API_KEY="" \
105
+ CC_SUB_BILLING_SETTINGS_OVERRIDE="$EMPTY_SETTINGS" \
106
+ bash "$HOOK_ABS" </dev/null 2>&1); RC=$?
107
+ assert_not_contains "empty api key no advisory" "$OUT" "API / purchased credits"
108
+ assert_exit "empty api key exit 0" "$RC" "0"
109
+
110
+ # Test 13: multiple settings paths (colon-separated), one has helper
111
+ OUT=$(run_clean CC_SUB_BILLING_SETTINGS_OVERRIDE="$EMPTY_SETTINGS:$HELPER_SETTINGS" \
112
+ bash "$HOOK_ABS" </dev/null 2>&1); RC=$?
113
+ assert_contains "multi-path finds helper" "$OUT" "apiKeyHelper is configured"
114
+ assert_exit "multi-path exit 0" "$RC" "0"
115
+
116
+ # Test 14: disable wins even with stdin payload
117
+ OUT=$(echo "$PAYLOAD" | run_clean ANTHROPIC_API_KEY="sk-x" CC_SUB_BILLING_DISABLE=1 \
118
+ CC_SUB_BILLING_SETTINGS_OVERRIDE="$HELPER_SETTINGS" \
119
+ bash "$HOOK_ABS" 2>&1); RC=$?
120
+ assert_not_contains "disable with stdin silent" "$OUT" "API / purchased credits"
121
+ assert_exit "disable with stdin exit 0" "$RC" "0"
122
+
123
+ # Test 15: apiKeyHelper present but empty string value → not triggered
124
+ EMPTYHELPER="$TMP/empty-helper.json"
125
+ printf '{"apiKeyHelper":""}' > "$EMPTYHELPER"
126
+ OUT=$(run_clean CC_SUB_BILLING_SETTINGS_OVERRIDE="$EMPTYHELPER" \
127
+ bash "$HOOK_ABS" </dev/null 2>&1); RC=$?
128
+ assert_not_contains "empty apiKeyHelper value no advisory" "$OUT" "apiKeyHelper is configured"
129
+ assert_exit "empty apiKeyHelper exit 0" "$RC" "0"
130
+
131
+ # Test 16: unreadable/missing settings path is skipped silently (no error)
132
+ OUT=$(run_clean CC_SUB_BILLING_SETTINGS_OVERRIDE="$NOFILE" \
133
+ bash "$HOOK_ABS" </dev/null 2>&1); RC=$?
134
+ assert_not_contains "missing settings no advisory" "$OUT" "apiKeyHelper is configured"
135
+ assert_exit "missing settings exit 0" "$RC" "0"
136
+
137
+ echo "Results: $PASS passed, $FAIL failed"
138
+ [ "$FAIL" -eq 0 ]
@@ -0,0 +1,255 @@
1
+ #!/bin/bash
2
+ # Tests for subscription-bypass-detector.sh
3
+ # Run: bash tests/test-subscription-bypass-detector.sh
4
+ set -uo pipefail
5
+
6
+ PASS=0
7
+ FAIL=0
8
+ HOOK="$(cd "$(dirname "$0")/.." && pwd)/examples/subscription-bypass-detector.sh"
9
+ WORK_DIR=$(mktemp -d)
10
+ trap 'rm -rf "$WORK_DIR"' EXIT
11
+
12
+ run_hook() {
13
+ local home_dir="$1"
14
+ local cwd_dir="$2"
15
+ local extra_env="${3:-}"
16
+ if [ -n "$extra_env" ]; then
17
+ echo '{}' | env -i HOME="$home_dir" PATH="$PATH" $extra_env bash -c "cd \"$cwd_dir\" && \"$HOOK\"" 2>&1
18
+ else
19
+ echo '{}' | env -i HOME="$home_dir" PATH="$PATH" bash -c "cd \"$cwd_dir\" && \"$HOOK\"" 2>&1
20
+ fi
21
+ }
22
+
23
+ assert_silent() {
24
+ local label="$1"
25
+ local output="$2"
26
+ if [ -z "$output" ]; then
27
+ PASS=$((PASS + 1))
28
+ echo " ✓ $label"
29
+ else
30
+ FAIL=$((FAIL + 1))
31
+ echo " ✗ $label"
32
+ echo " expected silent, got: ${output:0:200}"
33
+ fi
34
+ }
35
+
36
+ assert_emits_warning() {
37
+ local label="$1"
38
+ local output="$2"
39
+ if echo "$output" | jq -e '.hookSpecificOutput.additionalContext' >/dev/null 2>&1; then
40
+ local ctx
41
+ ctx=$(echo "$output" | jq -r '.hookSpecificOutput.additionalContext')
42
+ if echo "$ctx" | grep -q "ANTHROPIC_API_KEY detected"; then
43
+ PASS=$((PASS + 1))
44
+ echo " ✓ $label"
45
+ else
46
+ FAIL=$((FAIL + 1))
47
+ echo " ✗ $label (warning text not as expected)"
48
+ echo " got context start: ${ctx:0:200}"
49
+ fi
50
+ else
51
+ FAIL=$((FAIL + 1))
52
+ echo " ✗ $label (no hookSpecificOutput)"
53
+ echo " got: ${output:0:200}"
54
+ fi
55
+ }
56
+
57
+ assert_source_in_warning() {
58
+ local label="$1"
59
+ local output="$2"
60
+ local expected_substr="$3"
61
+ if echo "$output" | jq -e '.hookSpecificOutput.additionalContext' >/dev/null 2>&1; then
62
+ local ctx
63
+ ctx=$(echo "$output" | jq -r '.hookSpecificOutput.additionalContext')
64
+ if echo "$ctx" | grep -qF "$expected_substr"; then
65
+ PASS=$((PASS + 1))
66
+ echo " ✓ $label"
67
+ else
68
+ FAIL=$((FAIL + 1))
69
+ echo " ✗ $label (source not surfaced)"
70
+ echo " expected substring: $expected_substr"
71
+ echo " got: ${ctx:0:400}"
72
+ fi
73
+ else
74
+ FAIL=$((FAIL + 1))
75
+ echo " ✗ $label (no output)"
76
+ fi
77
+ }
78
+
79
+ echo "=== Silent cases (no API key in env, no dotenv) ==="
80
+
81
+ H1="$WORK_DIR/home1"
82
+ mkdir -p "$H1" "$H1/.claude"
83
+ OUT=$(run_hook "$H1" "$H1")
84
+ assert_silent "no env, no dotenv files" "$OUT"
85
+
86
+ # Empty dotenv files
87
+ touch "$H1/.env"
88
+ touch "$H1/.claude/.env"
89
+ OUT=$(run_hook "$H1" "$H1")
90
+ assert_silent "empty dotenv files" "$OUT"
91
+
92
+ # Dotenv has other keys but not ANTHROPIC_API_KEY
93
+ echo "OTHER_KEY=value" > "$H1/.env"
94
+ echo "FOO=bar" > "$H1/.claude/.env"
95
+ OUT=$(run_hook "$H1" "$H1")
96
+ assert_silent "dotenv with unrelated keys only" "$OUT"
97
+
98
+ echo ""
99
+ echo "=== Detection cases ==="
100
+
101
+ # Process env has ANTHROPIC_API_KEY
102
+ H2="$WORK_DIR/home2"
103
+ mkdir -p "$H2"
104
+ OUT=$(run_hook "$H2" "$H2" "ANTHROPIC_API_KEY=sk-test-123")
105
+ assert_emits_warning "ANTHROPIC_API_KEY in process env" "$OUT"
106
+ assert_source_in_warning "process env source surfaced" "$OUT" "process environment"
107
+
108
+ # ~/.claude/.env has ANTHROPIC_API_KEY
109
+ H3="$WORK_DIR/home3"
110
+ mkdir -p "$H3/.claude"
111
+ echo "ANTHROPIC_API_KEY=sk-test-456" > "$H3/.claude/.env"
112
+ OUT=$(run_hook "$H3" "$H3")
113
+ assert_emits_warning "ANTHROPIC_API_KEY in ~/.claude/.env" "$OUT"
114
+ assert_source_in_warning "Claude dotenv source surfaced" "$OUT" "Claude per-user dotenv"
115
+
116
+ # $HOME/.env has ANTHROPIC_API_KEY
117
+ H4="$WORK_DIR/home4"
118
+ mkdir -p "$H4"
119
+ echo "ANTHROPIC_API_KEY=sk-test-789" > "$H4/.env"
120
+ OUT=$(run_hook "$H4" "$H4")
121
+ assert_emits_warning "ANTHROPIC_API_KEY in ~/.env" "$OUT"
122
+ assert_source_in_warning "home dotenv source surfaced" "$OUT" "user home dotenv"
123
+
124
+ # project .env (PWD) has ANTHROPIC_API_KEY
125
+ H5="$WORK_DIR/home5"
126
+ P5="$WORK_DIR/proj5"
127
+ mkdir -p "$H5" "$P5"
128
+ echo "ANTHROPIC_API_KEY=sk-test-pwd" > "$P5/.env"
129
+ OUT=$(run_hook "$H5" "$P5")
130
+ assert_emits_warning "ANTHROPIC_API_KEY in project .env" "$OUT"
131
+ assert_source_in_warning "project dotenv source surfaced" "$OUT" "project working-directory dotenv"
132
+
133
+ echo ""
134
+ echo "=== Whitespace handling ==="
135
+
136
+ # With leading whitespace and quoted value
137
+ H6="$WORK_DIR/home6"
138
+ mkdir -p "$H6/.claude"
139
+ cat > "$H6/.claude/.env" <<EOF
140
+ ANTHROPIC_API_KEY = "sk-quoted"
141
+ OTHER=ignored
142
+ EOF
143
+ OUT=$(run_hook "$H6" "$H6")
144
+ assert_emits_warning "ANTHROPIC_API_KEY with whitespace and quotes" "$OUT"
145
+
146
+ # Commented out line should be silent
147
+ H7="$WORK_DIR/home7"
148
+ mkdir -p "$H7/.claude"
149
+ cat > "$H7/.claude/.env" <<EOF
150
+ # ANTHROPIC_API_KEY=sk-commented-out
151
+ OTHER=value
152
+ EOF
153
+ OUT=$(run_hook "$H7" "$H7")
154
+ assert_silent "commented-out ANTHROPIC_API_KEY (silent)" "$OUT"
155
+
156
+ echo ""
157
+ echo "=== Multiple source detection ==="
158
+
159
+ H8="$WORK_DIR/home8"
160
+ P8="$WORK_DIR/proj8"
161
+ mkdir -p "$H8/.claude" "$P8"
162
+ echo "ANTHROPIC_API_KEY=sk-from-claude-env" > "$H8/.claude/.env"
163
+ echo "ANTHROPIC_API_KEY=sk-from-pwd-env" > "$P8/.env"
164
+ OUT=$(run_hook "$H8" "$P8" "ANTHROPIC_API_KEY=sk-from-process")
165
+ assert_emits_warning "multiple sources detected" "$OUT"
166
+ # Should mention all three
167
+ assert_source_in_warning "process env in multi" "$OUT" "process environment"
168
+ assert_source_in_warning "Claude dotenv in multi" "$OUT" "Claude per-user dotenv"
169
+ assert_source_in_warning "project dotenv in multi" "$OUT" "project working-directory dotenv"
170
+
171
+ echo ""
172
+ echo "=== Configuration: disable and acknowledge ==="
173
+
174
+ H9="$WORK_DIR/home9"
175
+ mkdir -p "$H9"
176
+ OUT=$(run_hook "$H9" "$H9" "ANTHROPIC_API_KEY=sk-test CC_SUBSCRIPTION_BYPASS_DISABLE=1")
177
+ assert_silent "CC_SUBSCRIPTION_BYPASS_DISABLE=1 silences output" "$OUT"
178
+
179
+ OUT=$(run_hook "$H9" "$H9" "ANTHROPIC_API_KEY=sk-test CC_SUBSCRIPTION_BYPASS_ACK=1")
180
+ assert_silent "CC_SUBSCRIPTION_BYPASS_ACK=1 suppresses warning (intended use)" "$OUT"
181
+
182
+ # Logging
183
+ LOG_FILE="$WORK_DIR/log.txt"
184
+ OUT=$(run_hook "$H9" "$H9" "ANTHROPIC_API_KEY=sk-test CC_SUBSCRIPTION_BYPASS_LOG=$LOG_FILE")
185
+ assert_emits_warning "logging enabled still emits warning" "$OUT"
186
+ if grep -q "subscription-bypass-detected" "$LOG_FILE" 2>/dev/null; then
187
+ PASS=$((PASS + 1))
188
+ echo " ✓ log file contains detection event"
189
+ else
190
+ FAIL=$((FAIL + 1))
191
+ echo " ✗ log file missing detection event"
192
+ fi
193
+
194
+ # ACK + LOG together: silent warning but log entry recorded
195
+ LOG_FILE2="$WORK_DIR/log2.txt"
196
+ OUT=$(run_hook "$H9" "$H9" "ANTHROPIC_API_KEY=sk-test CC_SUBSCRIPTION_BYPASS_ACK=1 CC_SUBSCRIPTION_BYPASS_LOG=$LOG_FILE2")
197
+ assert_silent "ACK suppresses warning" "$OUT"
198
+ if grep -q "subscription-bypass-detected" "$LOG_FILE2" 2>/dev/null; then
199
+ PASS=$((PASS + 1))
200
+ echo " ✓ ACK still produces log entry (as documented)"
201
+ else
202
+ FAIL=$((FAIL + 1))
203
+ echo " ✗ ACK did not log entry"
204
+ fi
205
+
206
+ echo ""
207
+ echo "=== JSON structure ==="
208
+
209
+ H10="$WORK_DIR/home10"
210
+ mkdir -p "$H10"
211
+ OUT=$(run_hook "$H10" "$H10" "ANTHROPIC_API_KEY=sk-test")
212
+ if echo "$OUT" | jq -e '.' >/dev/null 2>&1; then
213
+ PASS=$((PASS + 1))
214
+ echo " ✓ output is valid JSON"
215
+ else
216
+ FAIL=$((FAIL + 1))
217
+ echo " ✗ output is not valid JSON: ${OUT:0:200}"
218
+ fi
219
+
220
+ HOOK_NAME=$(echo "$OUT" | jq -r '.hookSpecificOutput.hookEventName // empty' 2>/dev/null)
221
+ if [ "$HOOK_NAME" = "SessionStart" ]; then
222
+ PASS=$((PASS + 1))
223
+ echo " ✓ hookEventName is SessionStart"
224
+ else
225
+ FAIL=$((FAIL + 1))
226
+ echo " ✗ hookEventName missing or wrong: $HOOK_NAME"
227
+ fi
228
+
229
+ # Check Issue #60093 reference appears in context
230
+ CTX=$(echo "$OUT" | jq -r '.hookSpecificOutput.additionalContext // empty')
231
+ if echo "$CTX" | grep -q "60093"; then
232
+ PASS=$((PASS + 1))
233
+ echo " ✓ context references Issue #60093"
234
+ else
235
+ FAIL=$((FAIL + 1))
236
+ echo " ✗ context missing Issue #60093 reference"
237
+ fi
238
+
239
+ if echo "$CTX" | grep -q "1,050"; then
240
+ PASS=$((PASS + 1))
241
+ echo " ✓ context references the USD 1,050 case"
242
+ else
243
+ FAIL=$((FAIL + 1))
244
+ echo " ✗ context missing 1,050 reference"
245
+ fi
246
+
247
+ echo ""
248
+ echo "==============================="
249
+ echo "Total: $((PASS + FAIL)) PASS: $PASS FAIL: $FAIL"
250
+ echo "==============================="
251
+
252
+ if [ "$FAIL" -gt 0 ]; then
253
+ exit 1
254
+ fi
255
+ exit 0