cc-safe-setup 29.6.32 → 29.6.36

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 (415) hide show
  1. package/COOKBOOK.md +70 -0
  2. package/README.md +6 -2
  3. package/examples/absolute-rule-enforcer.sh +42 -0
  4. package/examples/allow-claude-settings.sh +2 -0
  5. package/examples/allow-git-hooks-dir.sh +2 -0
  6. package/examples/allow-protected-dirs.sh +2 -0
  7. package/examples/allowlist.sh +2 -0
  8. package/examples/ansible-vault-guard.sh +2 -0
  9. package/examples/auto-approve-build.sh +2 -0
  10. package/examples/auto-approve-compound-git.sh +2 -0
  11. package/examples/auto-approve-docker.sh +2 -0
  12. package/examples/auto-approve-git-read.sh +2 -0
  13. package/examples/auto-approve-python.sh +2 -0
  14. package/examples/auto-approve-readonly-tools.sh +2 -0
  15. package/examples/auto-approve-ssh.sh +2 -0
  16. package/examples/auto-approve-test.sh +2 -0
  17. package/examples/auto-checkpoint.sh +2 -0
  18. package/examples/auto-git-checkpoint.sh +2 -0
  19. package/examples/auto-mode-safe-commands.sh +2 -0
  20. package/examples/auto-snapshot.sh +2 -0
  21. package/examples/backup-before-refactor.sh +2 -0
  22. package/examples/banned-command-guard.sh +3 -3
  23. package/examples/bash-domain-allowlist.sh +72 -0
  24. package/examples/bash-safety-auto-deny.sh +56 -0
  25. package/examples/bash-secret-output-detector.sh +68 -0
  26. package/examples/bash-timeout-guard.sh +2 -0
  27. package/examples/bashrc-safety-check.sh +59 -0
  28. package/examples/bg-task-cooldown-guard.sh +46 -0
  29. package/examples/block-database-wipe.sh +2 -0
  30. package/examples/branch-name-check.sh +2 -0
  31. package/examples/branch-naming-convention.sh +2 -0
  32. package/examples/cargo-publish-guard.sh +2 -0
  33. package/examples/check-abort-controller.sh +2 -0
  34. package/examples/check-accessibility.sh +2 -0
  35. package/examples/check-aria-labels.sh +2 -0
  36. package/examples/check-async-await-consistency.sh +2 -0
  37. package/examples/check-before-act-enforcer.sh +47 -0
  38. package/examples/check-charset-meta.sh +2 -0
  39. package/examples/check-cleanup-effect.sh +2 -0
  40. package/examples/check-content-type.sh +2 -0
  41. package/examples/check-controlled-input.sh +2 -0
  42. package/examples/check-cookie-flags.sh +2 -0
  43. package/examples/check-cors-config.sh +2 -0
  44. package/examples/check-csp-headers.sh +2 -0
  45. package/examples/check-csrf-protection.sh +2 -0
  46. package/examples/check-debounce.sh +2 -0
  47. package/examples/check-dependency-age.sh +2 -0
  48. package/examples/check-dependency-license.sh +2 -0
  49. package/examples/check-dockerfile-best-practice.sh +2 -0
  50. package/examples/check-error-boundaries.sh +2 -0
  51. package/examples/check-error-class.sh +2 -0
  52. package/examples/check-error-handling.sh +2 -0
  53. package/examples/check-error-logging.sh +2 -0
  54. package/examples/check-error-message.sh +2 -0
  55. package/examples/check-error-page.sh +2 -0
  56. package/examples/check-error-stack.sh +2 -0
  57. package/examples/check-favicon.sh +2 -0
  58. package/examples/check-form-validation.sh +2 -0
  59. package/examples/check-git-hooks-compat.sh +2 -0
  60. package/examples/check-https-redirect.sh +2 -0
  61. package/examples/check-image-optimization.sh +2 -0
  62. package/examples/check-input-validation.sh +2 -0
  63. package/examples/check-key-prop.sh +2 -0
  64. package/examples/check-lang-attribute.sh +2 -0
  65. package/examples/check-lazy-loading.sh +2 -0
  66. package/examples/check-loading-state.sh +2 -0
  67. package/examples/check-memo-deps.sh +2 -0
  68. package/examples/check-meta-description.sh +2 -0
  69. package/examples/check-npm-scripts-exist.sh +2 -0
  70. package/examples/check-null-check.sh +2 -0
  71. package/examples/check-package-size.sh +2 -0
  72. package/examples/check-pagination.sh +2 -0
  73. package/examples/check-port-availability.sh +2 -0
  74. package/examples/check-promise-all.sh +2 -0
  75. package/examples/check-prop-types.sh +2 -0
  76. package/examples/check-rate-limiting.sh +2 -0
  77. package/examples/check-responsive-design.sh +2 -0
  78. package/examples/check-retry-logic.sh +2 -0
  79. package/examples/check-return-types.sh +2 -0
  80. package/examples/check-semantic-html.sh +2 -0
  81. package/examples/check-semantic-versioning.sh +2 -0
  82. package/examples/check-suspense-fallback.sh +2 -0
  83. package/examples/check-test-naming.sh +2 -0
  84. package/examples/check-timeout-cleanup.sh +2 -0
  85. package/examples/check-tls-version.sh +2 -0
  86. package/examples/check-type-coercion.sh +2 -0
  87. package/examples/check-unsubscribe.sh +2 -0
  88. package/examples/check-viewport-meta.sh +2 -0
  89. package/examples/check-worker-terminate.sh +2 -0
  90. package/examples/checkpoint-tamper-guard.sh +2 -0
  91. package/examples/chmod-guard.sh +2 -0
  92. package/examples/chown-guard.sh +2 -0
  93. package/examples/ci-workflow-guard.sh +59 -0
  94. package/examples/classifier-fallback-allow.sh +2 -0
  95. package/examples/claude-cache-gc.sh +15 -0
  96. package/examples/claudeignore-enforce-guard.sh +60 -0
  97. package/examples/claudemd-enforcer.sh +2 -0
  98. package/examples/claudemd-violation-detector.sh +36 -0
  99. package/examples/clear-command-confirm-guard.sh +21 -0
  100. package/examples/commit-message-check.sh +2 -0
  101. package/examples/compact-blocker.sh +25 -0
  102. package/examples/composer-guard.sh +2 -0
  103. package/examples/compound-command-allow.sh +2 -0
  104. package/examples/consecutive-failure-circuit-breaker.sh +49 -0
  105. package/examples/console-log-count.sh +2 -0
  106. package/examples/context-compact-advisor.sh +16 -0
  107. package/examples/core-file-protect-guard.sh +91 -0
  108. package/examples/cors-star-warn.sh +2 -0
  109. package/examples/credential-exfil-guard.sh +2 -0
  110. package/examples/credential-file-cat-guard.sh +2 -0
  111. package/examples/cron-modification-guard.sh +40 -0
  112. package/examples/cwd-drift-detector.sh +47 -0
  113. package/examples/cwd-project-boundary-guard.sh +50 -0
  114. package/examples/denied-action-retry-guard.sh +41 -0
  115. package/examples/dependency-install-guard.sh +2 -0
  116. package/examples/deploy-guard.sh +2 -0
  117. package/examples/deploy-path-verify-guard.sh +62 -0
  118. package/examples/deployment-verify-guard.sh +81 -0
  119. package/examples/django-migrate-guard.sh +2 -0
  120. package/examples/docker-volume-guard.sh +2 -0
  121. package/examples/dockerfile-latest-guard.sh +2 -0
  122. package/examples/dotenv-commit-guard.sh +44 -0
  123. package/examples/dotenv-example-sync.sh +55 -0
  124. package/examples/dotnet-build-on-edit.sh +2 -0
  125. package/examples/drizzle-migrate-guard.sh +2 -0
  126. package/examples/edit-counter-test-gate.sh +44 -0
  127. package/examples/edit-error-counter.sh +2 -0
  128. package/examples/edit-guard.sh +2 -0
  129. package/examples/edit-old-string-validator.sh +37 -0
  130. package/examples/edit-retry-loop-guard.sh +2 -0
  131. package/examples/edit-verify.sh +2 -0
  132. package/examples/encoding-preserve-guard.sh +34 -0
  133. package/examples/enforce-tests.sh +2 -0
  134. package/examples/env-inherit-guard.sh +2 -0
  135. package/examples/env-inline-secret-guard.sh +36 -0
  136. package/examples/env-prod-guard.sh +2 -0
  137. package/examples/env-required-check.sh +2 -0
  138. package/examples/env-var-check.sh +2 -0
  139. package/examples/expo-eject-guard.sh +2 -0
  140. package/examples/export-overwrite-guard.sh +29 -0
  141. package/examples/file-change-tracker.sh +2 -0
  142. package/examples/file-change-undo-tracker.sh +46 -0
  143. package/examples/file-recycle-bin.sh +48 -0
  144. package/examples/file-size-limit.sh +2 -0
  145. package/examples/five-hundred-milestone.sh +2 -0
  146. package/examples/flask-debug-guard.sh +2 -0
  147. package/examples/gem-push-guard.sh +2 -0
  148. package/examples/git-checkout-safety-guard.sh +2 -0
  149. package/examples/git-config-guard.sh +2 -0
  150. package/examples/git-crypt-worktree-guard.sh +36 -0
  151. package/examples/git-hook-bypass-guard.sh +2 -0
  152. package/examples/git-merge-conflict-prevent.sh +2 -0
  153. package/examples/git-message-length.sh +2 -0
  154. package/examples/git-operations-require-approval.sh +99 -0
  155. package/examples/git-show-flag-sanitizer.sh +41 -0
  156. package/examples/git-stash-before-danger.sh +2 -0
  157. package/examples/git-submodule-guard.sh +2 -0
  158. package/examples/git-tag-guard.sh +2 -0
  159. package/examples/github-actions-secret-guard.sh +59 -0
  160. package/examples/gitignore-check.sh +2 -0
  161. package/examples/gitops-drift-guard.sh +53 -0
  162. package/examples/go-mod-tidy-warn.sh +2 -0
  163. package/examples/hallucination-url-check.sh +2 -0
  164. package/examples/hardcoded-ip-guard.sh +2 -0
  165. package/examples/headless-empty-result-guard.sh +46 -0
  166. package/examples/headless-stop-guard.sh +43 -0
  167. package/examples/helm-install-guard.sh +2 -0
  168. package/examples/issue-draft-redact-guard.sh +45 -0
  169. package/examples/java-compile-on-edit.sh +2 -0
  170. package/examples/k8s-production-guard.sh +77 -0
  171. package/examples/laravel-artisan-guard.sh +2 -0
  172. package/examples/large-file-guard.sh +2 -0
  173. package/examples/line-ending-guard.sh +30 -0
  174. package/examples/log-level-guard.sh +2 -0
  175. package/examples/magic-number-warn.sh +2 -0
  176. package/examples/max-edit-size-guard.sh +2 -0
  177. package/examples/max-file-count-guard.sh +2 -0
  178. package/examples/max-file-delete-count.sh +2 -0
  179. package/examples/max-function-length.sh +2 -0
  180. package/examples/max-import-count.sh +2 -0
  181. package/examples/max-subagent-count.sh +2 -0
  182. package/examples/mcp-orphan-process-guard.sh +39 -0
  183. package/examples/mcp-server-allowlist.sh +45 -0
  184. package/examples/mcp-tool-audit-log.sh +41 -0
  185. package/examples/mcp-tool-guard.sh +2 -0
  186. package/examples/migration-verify-guard.sh +44 -0
  187. package/examples/monorepo-scope-guard.sh +2 -0
  188. package/examples/network-exfil-guard.sh +61 -0
  189. package/examples/network-guard.sh +2 -0
  190. package/examples/nextjs-env-guard.sh +2 -0
  191. package/examples/no-absolute-import.sh +2 -0
  192. package/examples/no-alert-confirm-prompt.sh +2 -0
  193. package/examples/no-any-type.sh +2 -0
  194. package/examples/no-any-typescript.sh +2 -0
  195. package/examples/no-assignment-in-condition.sh +2 -0
  196. package/examples/no-callback-hell.sh +2 -0
  197. package/examples/no-catch-all-route.sh +2 -0
  198. package/examples/no-circular-dependency.sh +2 -0
  199. package/examples/no-class-in-functional.sh +2 -0
  200. package/examples/no-cleartext-storage.sh +2 -0
  201. package/examples/no-commented-code.sh +2 -0
  202. package/examples/no-commit-fixup.sh +2 -0
  203. package/examples/no-console-assert.sh +2 -0
  204. package/examples/no-console-error-swallow.sh +2 -0
  205. package/examples/no-console-in-prod.sh +2 -0
  206. package/examples/no-console-log.sh +2 -0
  207. package/examples/no-console-time.sh +2 -0
  208. package/examples/no-cors-wildcard.sh +2 -0
  209. package/examples/no-curl-upload.sh +2 -0
  210. package/examples/no-dangerouslySetInnerHTML.sh +2 -0
  211. package/examples/no-dangling-await.sh +2 -0
  212. package/examples/no-debug-in-commit.sh +2 -0
  213. package/examples/no-deep-nesting.sh +2 -0
  214. package/examples/no-deep-relative-import.sh +2 -0
  215. package/examples/no-default-credentials.sh +2 -0
  216. package/examples/no-deprecated-api.sh +2 -0
  217. package/examples/no-direct-dom-manipulation.sh +2 -0
  218. package/examples/no-disabled-test.sh +2 -0
  219. package/examples/no-document-cookie.sh +2 -0
  220. package/examples/no-document-write.sh +2 -0
  221. package/examples/no-empty-function.sh +2 -0
  222. package/examples/no-eval-in-template.sh +2 -0
  223. package/examples/no-eval-template.sh +2 -0
  224. package/examples/no-eval.sh +2 -0
  225. package/examples/no-exec-user-input.sh +2 -0
  226. package/examples/no-expose-internal-ids.sh +2 -0
  227. package/examples/no-floating-promises.sh +2 -0
  228. package/examples/no-force-install.sh +2 -0
  229. package/examples/no-git-rebase-public.sh +2 -0
  230. package/examples/no-global-state.sh +2 -0
  231. package/examples/no-hardcoded-port.sh +2 -0
  232. package/examples/no-hardcoded-url.sh +2 -0
  233. package/examples/no-helmet-missing.sh +2 -0
  234. package/examples/no-http-url.sh +2 -0
  235. package/examples/no-http-without-https.sh +2 -0
  236. package/examples/no-index-as-key.sh +2 -0
  237. package/examples/no-infinite-scroll-mem.sh +2 -0
  238. package/examples/no-inline-event-handler.sh +2 -0
  239. package/examples/no-inline-handler.sh +2 -0
  240. package/examples/no-inline-style.sh +2 -0
  241. package/examples/no-inline-styles.sh +2 -0
  242. package/examples/no-innerhtml.sh +2 -0
  243. package/examples/no-install-global.sh +2 -0
  244. package/examples/no-jwt-in-url.sh +2 -0
  245. package/examples/no-large-commit.sh +2 -0
  246. package/examples/no-localhost-expose.sh +2 -0
  247. package/examples/no-long-switch.sh +2 -0
  248. package/examples/no-magic-number.sh +2 -0
  249. package/examples/no-md5-sha1.sh +2 -0
  250. package/examples/no-memory-leak-interval.sh +2 -0
  251. package/examples/no-mixed-line-endings.sh +2 -0
  252. package/examples/no-mutation-in-reducer.sh +2 -0
  253. package/examples/no-mutation-observer-leak.sh +2 -0
  254. package/examples/no-nested-subscribe.sh +2 -0
  255. package/examples/no-nested-ternary.sh +2 -0
  256. package/examples/no-network-exfil.sh +2 -0
  257. package/examples/no-new-array-fill.sh +2 -0
  258. package/examples/no-object-freeze-mutation.sh +2 -0
  259. package/examples/no-open-redirect.sh +2 -0
  260. package/examples/no-output-truncation.sh +44 -0
  261. package/examples/no-package-downgrade.sh +2 -0
  262. package/examples/no-package-lock-edit.sh +2 -0
  263. package/examples/no-path-join-user-input.sh +2 -0
  264. package/examples/no-port-bind.sh +2 -0
  265. package/examples/no-process-exit.sh +2 -0
  266. package/examples/no-prototype-pollution.sh +2 -0
  267. package/examples/no-push-without-ci.sh +2 -0
  268. package/examples/no-raw-ref.sh +2 -0
  269. package/examples/no-redundant-fragment.sh +2 -0
  270. package/examples/no-render-in-loop.sh +2 -0
  271. package/examples/no-root-user-docker.sh +2 -0
  272. package/examples/no-root-write.sh +2 -0
  273. package/examples/no-secrets-in-args.sh +2 -0
  274. package/examples/no-secrets-in-logs.sh +2 -0
  275. package/examples/no-sensitive-log.sh +2 -0
  276. package/examples/no-side-effects-in-render.sh +2 -0
  277. package/examples/no-sleep-in-hooks.sh +2 -0
  278. package/examples/no-star-import-python.sh +2 -0
  279. package/examples/no-string-concat-sql.sh +2 -0
  280. package/examples/no-sudo-guard.sh +2 -0
  281. package/examples/no-sync-external-call.sh +2 -0
  282. package/examples/no-sync-fs.sh +2 -0
  283. package/examples/no-table-layout.sh +2 -0
  284. package/examples/no-throw-string.sh +2 -0
  285. package/examples/no-todo-in-merge.sh +2 -0
  286. package/examples/no-todo-in-production.sh +2 -0
  287. package/examples/no-todo-without-issue.sh +2 -0
  288. package/examples/no-triple-slash-ref.sh +2 -0
  289. package/examples/no-unreachable-code.sh +2 -0
  290. package/examples/no-unused-import.sh +2 -0
  291. package/examples/no-unused-state.sh +2 -0
  292. package/examples/no-var-keyword.sh +2 -0
  293. package/examples/no-wildcard-cors.sh +2 -0
  294. package/examples/no-wildcard-import.sh +2 -0
  295. package/examples/no-window-location.sh +2 -0
  296. package/examples/no-with-statement.sh +2 -0
  297. package/examples/no-write-outside-src.sh +2 -0
  298. package/examples/no-xml-external-entity.sh +2 -0
  299. package/examples/notify-waiting.sh +2 -0
  300. package/examples/npm-audit-warn.sh +2 -0
  301. package/examples/npm-publish-guard.sh +2 -0
  302. package/examples/npm-script-injection.sh +2 -0
  303. package/examples/npm-supply-chain-guard.sh +92 -0
  304. package/examples/nuxt-config-guard.sh +2 -0
  305. package/examples/output-secret-mask.sh +2 -0
  306. package/examples/package-json-guard.sh +2 -0
  307. package/examples/parallel-session-guard.sh +2 -0
  308. package/examples/path-traversal-guard.sh +2 -0
  309. package/examples/permission-audit-log.sh +2 -0
  310. package/examples/permission-entry-validator.sh +48 -0
  311. package/examples/permission-pattern-auto-allow.sh +50 -0
  312. package/examples/php-lint-on-edit.sh +2 -0
  313. package/examples/pip-publish-guard.sh +2 -0
  314. package/examples/plain-language-danger-warn.sh +37 -0
  315. package/examples/plan-mode-enforcer.sh +2 -0
  316. package/examples/plugin-process-cleanup.sh +50 -0
  317. package/examples/polyglot-rm-guard.sh +59 -0
  318. package/examples/pr-description-check.sh +2 -0
  319. package/examples/pre-compact-knowledge-save.sh +53 -0
  320. package/examples/pre-compact-transcript-export.sh +85 -0
  321. package/examples/prefer-builtin-tools.sh +2 -0
  322. package/examples/prefer-const.sh +2 -0
  323. package/examples/prefer-dedicated-tools.sh +55 -0
  324. package/examples/prefer-optional-chaining.sh +2 -0
  325. package/examples/prisma-migrate-guard.sh +2 -0
  326. package/examples/prompt-injection-detector.sh +2 -0
  327. package/examples/prompt-length-guard.sh +2 -0
  328. package/examples/protect-dotfiles.sh +2 -0
  329. package/examples/public-repo-push-guard.sh +58 -0
  330. package/examples/push-requires-test-pass-record.sh +2 -0
  331. package/examples/push-requires-test-pass.sh +2 -0
  332. package/examples/rails-migration-guard.sh +2 -0
  333. package/examples/rate-limit-guard.sh +2 -0
  334. package/examples/read-all-files-enforcer.sh +51 -0
  335. package/examples/read-audit-log.sh +34 -0
  336. package/examples/readme-exists-check.sh +2 -0
  337. package/examples/redis-flushall-guard.sh +2 -0
  338. package/examples/rm-safety-net.sh +2 -0
  339. package/examples/role-tool-guard.sh +69 -0
  340. package/examples/ruby-lint-on-edit.sh +2 -0
  341. package/examples/schema-migration-guard.sh +57 -0
  342. package/examples/scope-guard.sh +2 -0
  343. package/examples/secret-file-read-guard.sh +74 -0
  344. package/examples/self-modify-bypass-guard.sh +54 -0
  345. package/examples/sensitive-log-guard.sh +2 -0
  346. package/examples/session-checkpoint.sh +2 -0
  347. package/examples/session-duration-guard.sh +51 -0
  348. package/examples/session-end-logger.sh +57 -0
  349. package/examples/session-error-rate-monitor.sh +65 -0
  350. package/examples/session-health-monitor.sh +61 -0
  351. package/examples/session-memory-watchdog.sh +17 -0
  352. package/examples/session-permission-reset-guard.sh +39 -0
  353. package/examples/session-resume-env-fix.sh +49 -0
  354. package/examples/session-state-saver.sh +2 -0
  355. package/examples/session-summary-stop.sh +2 -0
  356. package/examples/session-summary.sh +2 -0
  357. package/examples/session-token-counter.sh +2 -0
  358. package/examples/settings-auto-backup.sh +53 -0
  359. package/examples/settings-mutation-detector.sh +45 -0
  360. package/examples/shell-wrapper-guard.sh +2 -0
  361. package/examples/skill-gate.sh +2 -0
  362. package/examples/skill-injection-detector.sh +41 -0
  363. package/examples/spec-file-scope-guard.sh +69 -0
  364. package/examples/spring-profile-guard.sh +2 -0
  365. package/examples/sql-injection-detect.sh +2 -0
  366. package/examples/subagent-budget-guard.sh +2 -0
  367. package/examples/subagent-claudemd-inject.sh +45 -0
  368. package/examples/subagent-context-size-guard.sh +26 -0
  369. package/examples/subagent-tool-call-limiter.sh +48 -0
  370. package/examples/svelte-lint-on-edit.sh +2 -0
  371. package/examples/swift-build-on-edit.sh +2 -0
  372. package/examples/symlink-protect.sh +12 -0
  373. package/examples/system-message-workaround.sh +44 -0
  374. package/examples/system-package-guard.sh +2 -0
  375. package/examples/temp-file-cleanup-stop.sh +28 -0
  376. package/examples/temp-file-cleanup.sh +2 -0
  377. package/examples/terminal-state-restore.sh +23 -0
  378. package/examples/test-after-edit.sh +2 -0
  379. package/examples/test-before-commit.sh +13 -14
  380. package/examples/test-before-push.sh +2 -0
  381. package/examples/test-exit-code-verify.sh +2 -0
  382. package/examples/timeout-guard.sh +2 -0
  383. package/examples/timezone-guard.sh +2 -0
  384. package/examples/tmp-output-size-guard.sh +46 -0
  385. package/examples/todo-check.sh +2 -0
  386. package/examples/todo-deadline-warn.sh +48 -0
  387. package/examples/token-budget-per-task.sh +55 -0
  388. package/examples/token-spike-alert.sh +51 -0
  389. package/examples/token-usage-tracker.sh +14 -0
  390. package/examples/turbo-cache-guard.sh +2 -0
  391. package/examples/uncommitted-changes-stop.sh +2 -0
  392. package/examples/uncommitted-work-shield.sh +37 -0
  393. package/examples/usage-warn.sh +2 -0
  394. package/examples/verify-before-commit.sh +2 -0
  395. package/examples/virtual-cwd-helper.sh +40 -0
  396. package/examples/vue-lint-on-edit.sh +2 -0
  397. package/examples/webfetch-domain-allow.sh +96 -0
  398. package/examples/worktree-delete-guard.sh +43 -0
  399. package/examples/worktree-memory-guard.sh +47 -0
  400. package/examples/worktree-path-validator.sh +42 -0
  401. package/examples/worktree-project-unify.sh +19 -0
  402. package/examples/worktree-unmerged-guard.sh +2 -0
  403. package/examples/write-overwrite-confirm.sh +40 -0
  404. package/examples/write-secret-guard.sh +2 -0
  405. package/examples/write-shrink-guard.sh +46 -0
  406. package/examples/write-test-ratio.sh +2 -0
  407. package/index.mjs +631 -138
  408. package/package.json +2 -2
  409. package/scripts/generate-categories.mjs +206 -0
  410. package/scripts.json +4 -1
  411. package/test.sh.new_tests +0 -0
  412. package/test.sh.patch +0 -0
  413. package/tests/test-core-file-protect-guard.sh +73 -0
  414. package/tests/test-deployment-verify-guard.sh +74 -0
  415. package/tests/test-git-operations-require-approval.sh +65 -0
@@ -0,0 +1,62 @@
1
+ #!/bin/bash
2
+ # deploy-path-verify-guard.sh — Verify deployment target path before writes
3
+ #
4
+ # Solves: Writing files to wrong filesystem path in Docker setups (#40421).
5
+ # Claude wrote to host /srv/ instead of Docker mount /opt/acestream/public/
6
+ # three times, each time claiming deployment was successful.
7
+ #
8
+ # How it works: Before writing to paths matching CC_DEPLOY_PATHS pattern,
9
+ # verifies the target is actually mounted/accessible. Catches host-vs-container
10
+ # path confusion.
11
+ #
12
+ # CONFIG:
13
+ # CC_DEPLOY_PATHS="/srv:/opt/acestream/public:/var/www"
14
+ # CC_DEPLOY_VERIFY_CMD="docker inspect --format '{{.Mounts}}' mycontainer"
15
+ #
16
+ # TRIGGER: PreToolUse
17
+ # MATCHER: "Bash|Write"
18
+
19
+ set -euo pipefail
20
+
21
+ INPUT=$(cat)
22
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
23
+
24
+ DEPLOY_PATHS="${CC_DEPLOY_PATHS:-/srv:/var/www:/opt}"
25
+
26
+ # For Write tool, check file_path
27
+ if [ "$TOOL" = "Write" ]; then
28
+ FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
29
+ [ -z "$FILE" ] && exit 0
30
+
31
+ IFS=':' read -ra PATHS <<< "$DEPLOY_PATHS"
32
+ for dp in "${PATHS[@]}"; do
33
+ if [[ "$FILE" == "$dp"* ]]; then
34
+ echo "WARNING: Writing to deployment path $dp." >&2
35
+ echo "File: $FILE" >&2
36
+ echo "" >&2
37
+ echo "Verify this is the correct target:" >&2
38
+ echo " - Is this inside a Docker container or on the host?" >&2
39
+ echo " - Run 'docker inspect' to check bind mounts first." >&2
40
+ # Warning only (exit 0), not blocking — change to exit 2 to block
41
+ exit 0
42
+ fi
43
+ done
44
+ fi
45
+
46
+ # For Bash tool, check commands that write to deploy paths
47
+ if [ "$TOOL" = "Bash" ]; then
48
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
49
+ [ -z "$COMMAND" ] && exit 0
50
+
51
+ IFS=':' read -ra PATHS <<< "$DEPLOY_PATHS"
52
+ for dp in "${PATHS[@]}"; do
53
+ if echo "$COMMAND" | grep -qE "(cp|mv|tee|cat.*>|echo.*>).*${dp}"; then
54
+ echo "WARNING: Bash command targets deployment path $dp." >&2
55
+ echo "Command: $COMMAND" >&2
56
+ echo "Verify the target path is correct (host vs container)." >&2
57
+ exit 0
58
+ fi
59
+ done
60
+ fi
61
+
62
+ exit 0
@@ -0,0 +1,81 @@
1
+ #!/bin/bash
2
+ # ================================================================
3
+ # deployment-verify-guard.sh — Warn if committing without post-deploy verification
4
+ # ================================================================
5
+ # PURPOSE:
6
+ # Claude Code sometimes reports "deployment successful" without
7
+ # actually verifying the deployment works. This hook tracks deploy
8
+ # commands and checks that functional verification was performed
9
+ # before the next git commit.
10
+ #
11
+ # How it works:
12
+ # 1. When a deploy command is detected, logs timestamp to a marker file
13
+ # 2. When verification commands (test, curl, log grep) run, clears the marker
14
+ # 3. When git commit is attempted after a deploy without verification,
15
+ # emits a warning (non-blocking, exit 0)
16
+ #
17
+ # See: https://github.com/anthropics/claude-code/issues/40861
18
+ #
19
+ # TRIGGER: PreToolUse MATCHER: "Bash"
20
+ #
21
+ # Configuration:
22
+ # CC_DEPLOY_COMMANDS — regex pattern for deploy commands
23
+ # Default: "systemctl restart|docker restart|docker-compose up|deploy|kubectl apply|terraform apply|heroku push"
24
+ #
25
+ # CC_VERIFY_COMMANDS — regex pattern for verification commands
26
+ # Default: "curl|wget|test |pytest|npm test|jest|mocha|rspec|go test|cargo test|make test|grep.*log|tail.*log|journalctl|docker logs|health"
27
+ # ================================================================
28
+
29
+ INPUT=$(cat)
30
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
31
+
32
+ [ -z "$COMMAND" ] && exit 0
33
+
34
+ MARKER="/tmp/cc-deploy-pending-$$"
35
+
36
+ # Configurable deploy command patterns
37
+ DEPLOY_PATTERN="${CC_DEPLOY_COMMANDS:-systemctl\s+restart|docker\s+restart|docker-compose\s+up|docker\s+compose\s+up|\bdeploy\b|kubectl\s+apply|terraform\s+apply|heroku\s+.*push|fly\s+deploy}"
38
+
39
+ # Configurable verify command patterns
40
+ VERIFY_PATTERN="${CC_VERIFY_COMMANDS:-\bcurl\b|\bwget\b|\btest\s|\bpytest\b|npm\s+test|\bjest\b|\bmocha\b|\brspec\b|go\s+test|cargo\s+test|make\s+test|grep.*log|tail.*log|\bjournalctl\b|docker\s+logs|\bhealth}"
41
+
42
+ # Skip echo/printf
43
+ echo "$COMMAND" | grep -qE '^\s*(echo|printf)\s' && exit 0
44
+
45
+ # Check if this is a deploy command
46
+ if echo "$COMMAND" | grep -qiE "$DEPLOY_PATTERN"; then
47
+ date +%s > "$MARKER"
48
+ echo "Deploy detected. Verification will be required before commit." >&2
49
+ exit 0
50
+ fi
51
+
52
+ # Check if this is a verification command — clear the deploy marker
53
+ if echo "$COMMAND" | grep -qiE "$VERIFY_PATTERN"; then
54
+ if [ -f "$MARKER" ]; then
55
+ rm -f "$MARKER"
56
+ fi
57
+ exit 0
58
+ fi
59
+
60
+ # Check if this is a git commit after an unverified deploy
61
+ if echo "$COMMAND" | grep -qE '\bgit\s+commit\b'; then
62
+ if [ -f "$MARKER" ]; then
63
+ DEPLOY_TIME=$(cat "$MARKER" 2>/dev/null || echo "unknown")
64
+ echo "WARNING: Committing after deployment without verification." >&2
65
+ echo "" >&2
66
+ echo "A deploy command was run (at timestamp $DEPLOY_TIME) but no" >&2
67
+ echo "verification command was detected since then." >&2
68
+ echo "" >&2
69
+ echo "Recommended verifications:" >&2
70
+ echo " curl http://localhost:<port>/health" >&2
71
+ echo " npm test / pytest / go test" >&2
72
+ echo " docker logs <container> | tail" >&2
73
+ echo " journalctl -u <service> --since '5 min ago'" >&2
74
+ echo "" >&2
75
+ echo "See: https://github.com/anthropics/claude-code/issues/40861" >&2
76
+ # Non-blocking — just warn
77
+ rm -f "$MARKER"
78
+ fi
79
+ fi
80
+
81
+ exit 0
@@ -17,6 +17,8 @@
17
17
  # }
18
18
  # }
19
19
  # ================================================================
20
+ #
21
+ # TRIGGER: PreToolUse MATCHER: "Bash"
20
22
 
21
23
  INPUT=$(cat)
22
24
  COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ #
3
+ # TRIGGER: PreToolUse MATCHER: "Bash"
2
4
  COMMAND=$(cat | jq -r '.tool_input.command // empty' 2>/dev/null)
3
5
  [ -z "$COMMAND" ] && exit 0
4
6
  if echo "$COMMAND" | grep -qE '\bdocker\s+volume\s+(rm|prune)\b'; then
@@ -1,3 +1,5 @@
1
+ #
2
+ # TRIGGER: PreToolUse MATCHER: "Edit|Write"
1
3
  INPUT=$(cat)
2
4
  FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
3
5
  [[ -z "$FILE" ]] && exit 0
@@ -0,0 +1,44 @@
1
+ #!/bin/bash
2
+ # dotenv-commit-guard.sh — Prevent committing .env files with secrets
3
+ #
4
+ # Solves: Claude adding .env files to git staging and committing them.
5
+ # Even with .gitignore, Claude can `git add -f .env` to force-add.
6
+ #
7
+ # How it works: PreToolUse hook on Bash that detects git add/commit
8
+ # commands including .env files and blocks them.
9
+ #
10
+ # TRIGGER: PreToolUse
11
+ # MATCHER: "Bash"
12
+
13
+ set -euo pipefail
14
+
15
+ INPUT=$(cat)
16
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
17
+ [ -z "$COMMAND" ] && exit 0
18
+
19
+ # Check for git add with .env files
20
+ # Allow .env.example, .env.sample, .env.template
21
+ if echo "$COMMAND" | grep -qE 'git\s+add\s+.*\.env\.(example|sample|template)'; then
22
+ exit 0
23
+ fi
24
+ if echo "$COMMAND" | grep -qE 'git\s+add\s+.*\.env'; then
25
+ echo "BLOCKED: Adding .env file to git staging." >&2
26
+ echo " .env files contain secrets and should not be committed." >&2
27
+ echo " Use .env.example with placeholder values instead." >&2
28
+ exit 2
29
+ fi
30
+
31
+ # Check for git add -A/-f that might include .env
32
+ if echo "$COMMAND" | grep -qE 'git\s+add\s+(-A|--all|-f|--force)\b'; then
33
+ # Check if .env exists in the working directory
34
+ if [ -f ".env" ] || [ -f ".env.local" ] || [ -f ".env.production" ]; then
35
+ # Check if .gitignore excludes it
36
+ if ! git check-ignore -q .env 2>/dev/null; then
37
+ echo "WARNING: 'git add -A' with .env file not in .gitignore." >&2
38
+ echo " Add .env to .gitignore before staging all files." >&2
39
+ # Warning only for git add -A
40
+ fi
41
+ fi
42
+ fi
43
+
44
+ exit 0
@@ -0,0 +1,55 @@
1
+ #!/bin/bash
2
+ # ================================================================
3
+ # dotenv-example-sync.sh — Warn when .env changes but .env.example doesn't
4
+ # ================================================================
5
+ # PURPOSE:
6
+ # When Claude edits .env (adding/removing variables), .env.example
7
+ # should be updated to match. This hook warns if .env was modified
8
+ # but .env.example still has different keys, preventing deployment
9
+ # failures when team members don't have the new variables.
10
+ #
11
+ # TRIGGER: PostToolUse
12
+ # MATCHER: "Edit|Write"
13
+ #
14
+ # DECISION: Advisory only (exit 0). Warns via stderr.
15
+ # ================================================================
16
+
17
+ INPUT=$(cat)
18
+ FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
19
+ [ -z "$FILE" ] && exit 0
20
+
21
+ # Only trigger when .env is edited (not .env.example itself)
22
+ case "$(basename "$FILE")" in
23
+ .env|.env.local|.env.development|.env.production) ;;
24
+ *) exit 0 ;;
25
+ esac
26
+
27
+ # Find corresponding .env.example
28
+ DIR=$(dirname "$FILE")
29
+ EXAMPLE=""
30
+ for candidate in "$DIR/.env.example" "$DIR/.env.sample" "$DIR/.env.template"; do
31
+ if [ -f "$candidate" ]; then
32
+ EXAMPLE="$candidate"
33
+ break
34
+ fi
35
+ done
36
+
37
+ [ -z "$EXAMPLE" ] && exit 0
38
+ [ ! -f "$FILE" ] && exit 0
39
+
40
+ # Extract variable names (lines with KEY=)
41
+ ENV_KEYS=$(grep -oE '^[A-Z_][A-Z0-9_]*=' "$FILE" 2>/dev/null | sort -u)
42
+ EXAMPLE_KEYS=$(grep -oE '^[A-Z_][A-Z0-9_]*=' "$EXAMPLE" 2>/dev/null | sort -u)
43
+
44
+ # Find keys in .env but not in .env.example
45
+ MISSING=$(comm -23 <(echo "$ENV_KEYS") <(echo "$EXAMPLE_KEYS"))
46
+
47
+ if [ -n "$MISSING" ]; then
48
+ echo "⚠ .env has variables not in $(basename "$EXAMPLE"):" >&2
49
+ echo "$MISSING" | sed 's/=$//' | while read key; do
50
+ echo " + $key" >&2
51
+ done
52
+ echo " Update $(basename "$EXAMPLE") so teammates have the full variable list." >&2
53
+ fi
54
+
55
+ exit 0
@@ -17,6 +17,8 @@
17
17
  # }
18
18
  # }
19
19
  # ================================================================
20
+ #
21
+ # TRIGGER: PreToolUse MATCHER: "Bash"
20
22
 
21
23
  INPUT=$(cat)
22
24
  FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
@@ -16,6 +16,8 @@
16
16
  # }
17
17
  # }
18
18
  # ================================================================
19
+ #
20
+ # TRIGGER: PreToolUse MATCHER: "Bash"
19
21
 
20
22
  INPUT=$(cat)
21
23
  COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
@@ -0,0 +1,44 @@
1
+ #!/bin/bash
2
+ # edit-counter-test-gate.sh — Require testing after N consecutive edits
3
+ #
4
+ # Solves: Reactive cycling through fixes without testing (#40401).
5
+ # Opus writing 4 different fix approaches in sequence without
6
+ # verifying any of them actually work.
7
+ #
8
+ # How it works: PostToolUse hook on Edit that counts consecutive edits.
9
+ # After CC_MAX_EDITS_BEFORE_TEST (default 3) edits without a Bash
10
+ # command (assumed test/build), warns the model to test first.
11
+ #
12
+ # TRIGGER: PostToolUse
13
+ # MATCHER: "Edit|Bash"
14
+
15
+ set -euo pipefail
16
+
17
+ INPUT=$(cat)
18
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
19
+ MAX_EDITS="${CC_MAX_EDITS_BEFORE_TEST:-3}"
20
+ COUNTER_FILE="/tmp/claude-edit-test-gate-${PPID:-0}"
21
+
22
+ case "$TOOL" in
23
+ Edit|Write)
24
+ # Increment edit counter
25
+ COUNT=$(cat "$COUNTER_FILE" 2>/dev/null || echo 0)
26
+ COUNT=$((COUNT + 1))
27
+ echo "$COUNT" > "$COUNTER_FILE"
28
+
29
+ if [ "$COUNT" -ge "$MAX_EDITS" ]; then
30
+ echo "WARNING: $COUNT consecutive edits without testing." >&2
31
+ echo "" >&2
32
+ echo "Run your test/build command before making more changes." >&2
33
+ echo "Untested fixes compound — verify each approach works" >&2
34
+ echo "before trying the next one." >&2
35
+ # Warning only — change to exit 2 to block
36
+ fi
37
+ ;;
38
+ Bash)
39
+ # Bash command (likely test/build) — reset counter
40
+ echo "0" > "$COUNTER_FILE"
41
+ ;;
42
+ esac
43
+
44
+ exit 0
@@ -19,6 +19,8 @@
19
19
  # }
20
20
  # }
21
21
  # ================================================================
22
+ #
23
+ # TRIGGER: PreToolUse MATCHER: "Edit|Write"
22
24
 
23
25
  INPUT=$(cat)
24
26
  TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
@@ -16,6 +16,8 @@
16
16
  # }]
17
17
  # }
18
18
  # }
19
+ #
20
+ # TRIGGER: PreToolUse MATCHER: "Bash"
19
21
 
20
22
  INPUT=$(cat)
21
23
  TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
@@ -0,0 +1,37 @@
1
+ #!/bin/bash
2
+ # edit-old-string-validator.sh — Pre-validate Edit tool old_string exists
3
+ #
4
+ # Solves: Parallel Edit tool calls cascade-fail when one Edit's
5
+ # old_string doesn't match the file content (#22264).
6
+ # By catching mismatches before execution, sibling
7
+ # edits in the same batch can proceed normally.
8
+ #
9
+ # How it works: Reads the Edit tool input, checks if old_string
10
+ # exists in the target file. If not found, blocks with exit 2
11
+ # and a descriptive error message.
12
+ #
13
+ # TRIGGER: PreToolUse
14
+ # MATCHER: "Edit"
15
+
16
+ set -euo pipefail
17
+ INPUT=$(cat)
18
+
19
+ FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
20
+ OLD_STRING=$(echo "$INPUT" | jq -r '.tool_input.old_string // empty' 2>/dev/null)
21
+
22
+ # Skip if no file or old_string
23
+ [ -z "$FILE" ] && exit 0
24
+ [ -z "$OLD_STRING" ] && exit 0
25
+
26
+ # Skip if file doesn't exist (Edit tool will handle that error)
27
+ [ ! -f "$FILE" ] && exit 0
28
+
29
+ # Check if old_string exists in the file
30
+ if ! grep -qF "$OLD_STRING" "$FILE" 2>/dev/null; then
31
+ echo "BLOCKED: old_string not found in $FILE." >&2
32
+ echo "The file may have been modified by a prior edit in this batch." >&2
33
+ echo "Re-read the file to get the current content before retrying." >&2
34
+ exit 2
35
+ fi
36
+
37
+ exit 0
@@ -6,6 +6,8 @@
6
6
  #
7
7
  # Tracks consecutive Edit failures on the same file. After 3 failures,
8
8
  # warns the model to verify the file path.
9
+ #
10
+ # TRIGGER: PreToolUse MATCHER: "Edit|Write"
9
11
 
10
12
  INPUT=$(cat)
11
13
  TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ #
3
+ # TRIGGER: PreToolUse MATCHER: "Edit|Write"
2
4
  INPUT=$(cat)
3
5
  TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
4
6
  FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
@@ -0,0 +1,34 @@
1
+ #!/bin/bash
2
+ # ================================================================
3
+ # encoding-preserve-guard.sh — Warn when file encoding changes
4
+ # ================================================================
5
+ # PURPOSE:
6
+ # Claude's Write tool always outputs UTF-8. When editing files
7
+ # that use different encodings (UTF-8 BOM, Latin-1, Shift-JIS),
8
+ # the encoding silently changes, potentially corrupting content.
9
+ # Common in legacy codebases, .csv exports, Windows batch files.
10
+ #
11
+ # TRIGGER: PreToolUse
12
+ # MATCHER: "Write|Edit"
13
+ # ================================================================
14
+
15
+ INPUT=$(cat)
16
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
17
+ FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
18
+
19
+ [[ "$TOOL" != "Write" && "$TOOL" != "Edit" ]] && exit 0
20
+ [ -z "$FILE" ] || [ ! -f "$FILE" ] && exit 0
21
+
22
+ # Check for BOM (Byte Order Mark)
23
+ if head -c 3 "$FILE" 2>/dev/null | od -An -tx1 | grep -q "ef bb bf"; then
24
+ echo "WARNING: $FILE has UTF-8 BOM. Write tool may strip the BOM." >&2
25
+ fi
26
+
27
+ # Check for non-UTF-8 encoding using file command
28
+ ENCODING=$(file -bi "$FILE" 2>/dev/null | grep -oP 'charset=\K\S+')
29
+ if [ -n "$ENCODING" ] && [ "$ENCODING" != "utf-8" ] && [ "$ENCODING" != "us-ascii" ]; then
30
+ echo "WARNING: $FILE uses $ENCODING encoding. Write tool outputs UTF-8." >&2
31
+ echo " This may corrupt non-ASCII characters in the file." >&2
32
+ fi
33
+
34
+ exit 0
@@ -8,6 +8,8 @@
8
8
  # Usage: Add to settings.json as a PostToolUse hook on "Edit|Write"
9
9
  #
10
10
  # Customize TEST_PATTERN for your project's test file naming convention.
11
+ #
12
+ # TRIGGER: PreToolUse MATCHER: "Bash"
11
13
 
12
14
  INPUT=$(cat)
13
15
  FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
@@ -23,6 +23,8 @@
23
23
  # }
24
24
  # }
25
25
  # ================================================================
26
+ #
27
+ # TRIGGER: PreToolUse MATCHER: "Bash"
26
28
 
27
29
  INPUT=$(cat)
28
30
  COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
@@ -0,0 +1,36 @@
1
+ #!/bin/bash
2
+ # env-inline-secret-guard.sh — Block .env values from appearing in commands
3
+ #
4
+ # Solves: Claude reading .env and hardcoding secrets into inline scripts (#24185).
5
+ # API keys, database URLs, and tokens get embedded in bash commands,
6
+ # potentially leaking to logs, history, or screen recordings.
7
+ #
8
+ # How it works: PreToolUse hook on Bash that detects common secret patterns
9
+ # (API keys, tokens, connection strings) in command text.
10
+ # If found, blocks with exit 2 and suggests environment variable usage.
11
+ #
12
+ # TRIGGER: PreToolUse
13
+ # MATCHER: "Bash"
14
+
15
+ set -euo pipefail
16
+
17
+ INPUT=$(cat)
18
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
19
+ [ -z "$COMMAND" ] && exit 0
20
+
21
+ # Detect inline secrets: known API key prefixes (20+ chars)
22
+ # sk- (OpenAI), ghp_/ghu_ (GitHub), AKIA (AWS)
23
+ if echo "$COMMAND" | grep -qE '(sk-[a-zA-Z0-9]{20,}|ghp_[a-zA-Z0-9]{36}|ghu_[a-zA-Z0-9]{36}|AKIA[0-9A-Z]{16}|xoxb-[0-9]+-[0-9]+-[a-zA-Z0-9]+)'; then
24
+ echo "BLOCKED: Possible secret/credential detected in command." >&2
25
+ echo "Use environment variables instead of inline secrets." >&2
26
+ exit 2
27
+ fi
28
+
29
+ # Detect generic long tokens in auth headers or parameters
30
+ if echo "$COMMAND" | grep -qE "(Authorization:|Bearer |token=|api[_-]?key=|secret=|password=)['\"]?[a-zA-Z0-9+/=_-]{32,}"; then
31
+ echo "BLOCKED: Long token/key detected inline in command." >&2
32
+ echo "Use environment variables or a secrets file instead." >&2
33
+ exit 2
34
+ fi
35
+
36
+ exit 0
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ #
3
+ # TRIGGER: PreToolUse MATCHER: "Bash"
2
4
  COMMAND=$(cat | jq -r '.tool_input.command // empty' 2>/dev/null)
3
5
  [ -z "$COMMAND" ] && exit 0
4
6
  if echo "$COMMAND" | grep -qiE "(NODE_ENV|RAILS_ENV|FLASK_ENV)=production"; then echo "WARNING: Production env detected in command" >&2; fi
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ #
3
+ # TRIGGER: PreToolUse MATCHER: "Edit|Write"
2
4
  CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
3
5
  [ -z "$CONTENT" ] && exit 0
4
6
  echo "$CONTENT" | grep -qE "process\.env\.\w+\s*\|\|" || echo "$CONTENT" | grep -qE "process\.env\.\w+!" && echo "NOTE: Env var without default — add fallback" >&2
@@ -14,6 +14,8 @@
14
14
  # }]
15
15
  # }
16
16
  # }
17
+ #
18
+ # TRIGGER: PreToolUse MATCHER: "Bash"
17
19
 
18
20
  INPUT=$(cat)
19
21
  COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
@@ -1,3 +1,5 @@
1
+ #
2
+ # TRIGGER: PreToolUse MATCHER: "Bash"
1
3
  INPUT=$(cat)
2
4
  COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
3
5
  [[ -z "$COMMAND" ]] && exit 0
@@ -0,0 +1,29 @@
1
+ #!/bin/bash
2
+ # export-overwrite-guard.sh — Prevent /export from overwriting existing files
3
+ #
4
+ # Solves: /export command overwrites files without warning (#37595).
5
+ # Users lose existing files when Claude exports to the same path.
6
+ #
7
+ # How it works: PreToolUse hook on Write that checks if the target file
8
+ # exists and contains content. If so, warns before allowing overwrite.
9
+ #
10
+ # TRIGGER: PreToolUse
11
+ # MATCHER: "Write"
12
+
13
+ set -euo pipefail
14
+
15
+ INPUT=$(cat)
16
+ FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
17
+ [ -z "$FILE" ] && exit 0
18
+
19
+ # Check if file exists and has content
20
+ if [ -f "$FILE" ] && [ -s "$FILE" ]; then
21
+ SIZE=$(wc -c < "$FILE" 2>/dev/null || echo 0)
22
+ if [ "$SIZE" -gt 100 ]; then
23
+ echo "WARNING: Overwriting existing file '$FILE' ($SIZE bytes)." >&2
24
+ echo "Consider writing to a different path or backing up first." >&2
25
+ # Don't block — just warn via stderr
26
+ fi
27
+ fi
28
+
29
+ exit 0
@@ -23,6 +23,8 @@
23
23
  # }
24
24
  #
25
25
  # View changes: cat ~/.claude/session-changes.log
26
+ #
27
+ # TRIGGER: PreToolUse MATCHER: "Edit|Write"
26
28
 
27
29
  INPUT=$(cat)
28
30
  TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
@@ -0,0 +1,46 @@
1
+ #!/bin/bash
2
+ # file-change-undo-tracker.sh — Track file changes for easy undo
3
+ #
4
+ # Solves: After Claude makes unwanted changes across multiple files,
5
+ # users have no easy way to identify and revert all affected files.
6
+ # git diff works but only for tracked files.
7
+ #
8
+ # How it works: FileChanged hook that logs every file modification
9
+ # with timestamp and change type. Creates a revert script
10
+ # that can undo all changes from the current session.
11
+ #
12
+ # Usage: After session, run: bash /tmp/claude-undo-session.sh
13
+ #
14
+ # TRIGGER: FileChanged
15
+ # MATCHER: ""
16
+
17
+ set -euo pipefail
18
+
19
+ INPUT=$(cat)
20
+ FILE=$(echo "$INPUT" | jq -r '.file // empty' 2>/dev/null)
21
+ EVENT=$(echo "$INPUT" | jq -r '.event // empty' 2>/dev/null)
22
+
23
+ [ -z "$FILE" ] && exit 0
24
+
25
+ LOG_FILE="/tmp/claude-file-changes-${PPID:-0}.log"
26
+ UNDO_FILE="/tmp/claude-undo-session-${PPID:-0}.sh"
27
+ TIMESTAMP=$(date +"%H:%M:%S")
28
+
29
+ # Log the change
30
+ echo "${TIMESTAMP} ${EVENT:-modified} ${FILE}" >> "$LOG_FILE"
31
+
32
+ # Track for undo (git-tracked files only)
33
+ if git ls-files --error-unmatch "$FILE" &>/dev/null 2>&1; then
34
+ # File is git-tracked — can be reverted with git checkout
35
+ if ! grep -qF "git checkout -- \"$FILE\"" "$UNDO_FILE" 2>/dev/null; then
36
+ echo "git checkout -- \"$FILE\" # ${EVENT:-modified} at ${TIMESTAMP}" >> "$UNDO_FILE"
37
+ fi
38
+ fi
39
+
40
+ # Count changes
41
+ COUNT=$(wc -l < "$LOG_FILE" 2>/dev/null || echo 0)
42
+ if [ "$((COUNT % 10))" -eq 0 ] && [ "$COUNT" -gt 0 ]; then
43
+ echo "Session file changes: $COUNT files modified. Undo: bash $UNDO_FILE" >&2
44
+ fi
45
+
46
+ exit 0