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,77 @@
1
+ #!/bin/bash
2
+ # k8s-production-guard.sh — Block destructive Kubernetes operations on production
3
+ #
4
+ # Solves: Claude running kubectl delete, scale-to-zero, or rollback on
5
+ # production namespaces/clusters without explicit confirmation.
6
+ #
7
+ # How it works: PreToolUse hook on Bash that detects kubectl/helm commands
8
+ # targeting production contexts/namespaces and blocks destructive operations.
9
+ #
10
+ # CONFIG:
11
+ # CC_K8S_PROD_CONTEXTS="prod:production:live" (colon-separated)
12
+ # CC_K8S_PROD_NAMESPACES="production:prod:default" (colon-separated)
13
+ #
14
+ # TRIGGER: PreToolUse
15
+ # MATCHER: "Bash"
16
+
17
+ set -euo pipefail
18
+
19
+ INPUT=$(cat)
20
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
21
+ [ -z "$COMMAND" ] && exit 0
22
+
23
+ # Only check kubectl/helm commands
24
+ echo "$COMMAND" | grep -qE '(kubectl|helm)\s' || exit 0
25
+
26
+ # Production indicators
27
+ PROD_CTX="${CC_K8S_PROD_CONTEXTS:-prod:production:live}"
28
+ PROD_NS="${CC_K8S_PROD_NAMESPACES:-production:prod}"
29
+
30
+ # Destructive kubectl operations
31
+ DESTRUCT_KUBECTL='delete\s+(deploy|pod|svc|namespace|pv|statefulset|daemonset|job|cronjob|ingress|secret|configmap)|scale\s+.*--replicas=0|drain\s|cordon\s|taint\s.*NoSchedule|rollout\s+undo'
32
+
33
+ # Destructive helm operations
34
+ DESTRUCT_HELM='helm\s+(uninstall|delete|rollback|reset)'
35
+
36
+ # Check if command is destructive
37
+ IS_DESTRUCTIVE=false
38
+ if echo "$COMMAND" | grep -qE "$DESTRUCT_KUBECTL"; then
39
+ IS_DESTRUCTIVE=true
40
+ fi
41
+ if echo "$COMMAND" | grep -qE "$DESTRUCT_HELM"; then
42
+ IS_DESTRUCTIVE=true
43
+ fi
44
+
45
+ $IS_DESTRUCTIVE || exit 0
46
+
47
+ # Check if targeting production
48
+ IS_PROD=false
49
+
50
+ # Check --context flag
51
+ IFS=':' read -ra CTXS <<< "$PROD_CTX"
52
+ for ctx in "${CTXS[@]}"; do
53
+ if echo "$COMMAND" | grep -qE -- "--context[= ]$ctx"; then
54
+ IS_PROD=true
55
+ break
56
+ fi
57
+ done
58
+
59
+ # Check -n/--namespace flag
60
+ IFS=':' read -ra NSS <<< "$PROD_NS"
61
+ for ns in "${NSS[@]}"; do
62
+ if echo "$COMMAND" | grep -qE -- "(-n|--namespace)[= ]$ns"; then
63
+ IS_PROD=true
64
+ break
65
+ fi
66
+ done
67
+
68
+ if $IS_PROD; then
69
+ echo "BLOCKED: Destructive Kubernetes operation on production." >&2
70
+ echo " Command: $COMMAND" >&2
71
+ echo " Run this manually if you're sure." >&2
72
+ exit 2
73
+ fi
74
+
75
+ # Not targeting production explicitly — warn but allow
76
+ echo "NOTE: Destructive k8s operation (not targeting a known prod namespace)." >&2
77
+ exit 0
@@ -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
@@ -17,6 +17,8 @@
17
17
  # }]
18
18
  # }
19
19
  # }
20
+ #
21
+ # TRIGGER: PreToolUse MATCHER: "Bash"
20
22
 
21
23
  INPUT=$(cat)
22
24
  TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
@@ -0,0 +1,30 @@
1
+ #!/bin/bash
2
+ # ================================================================
3
+ # line-ending-guard.sh — Warn on CRLF/LF mismatch
4
+ # ================================================================
5
+ # PURPOSE:
6
+ # Claude Code outputs LF line endings. On Windows/WSL, files may
7
+ # use CRLF. Editing a CRLF file with LF content creates mixed
8
+ # line endings, causing test failures, script errors, and git
9
+ # noise. Especially common in .bat, .cmd, .ps1 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 if existing file uses CRLF
23
+ if head -c 1000 "$FILE" 2>/dev/null | od -c | grep -q '\\r\\n'; then
24
+ echo "WARNING: $FILE uses CRLF line endings. Claude outputs LF." >&2
25
+ echo " This may create mixed line endings. Consider:" >&2
26
+ echo " - Setting .gitattributes: *.bat text eol=crlf" >&2
27
+ echo " - Running: unix2dos $FILE (after edit)" >&2
28
+ fi
29
+
30
+ exit 0
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ #
3
+ # TRIGGER: PreToolUse MATCHER: "Edit|Write"
2
4
  INPUT=$(cat)
3
5
  CONTENT=$(echo "$INPUT" | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
4
6
  [ -z "$CONTENT" ] && exit 0
@@ -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
@@ -1,3 +1,5 @@
1
+ #
2
+ # TRIGGER: PreToolUse MATCHER: "Edit|Write"
1
3
  INPUT=$(cat)
2
4
  TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
3
5
  [ "$TOOL" != "Edit" ] && exit 0
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ #
3
+ # TRIGGER: PreToolUse MATCHER: "Bash"
2
4
  INPUT=$(cat)
3
5
  FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
4
6
  [ -z "$FILE" ] && 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 -qE "^\s*rm\b"; then COUNT=$(echo "$COMMAND" | tr " " "\n" | grep -cvE "^-" | head -1); [ "$COUNT" -gt 5 ] && echo "WARNING: Deleting $COUNT files at once" >&2; fi
@@ -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
@@ -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
  IMPORTS=$(echo "$CONTENT" | grep -cE "^(import|from|require)" || echo 0); [ "$IMPORTS" -gt 20 ] && echo "NOTE: $IMPORTS imports — consider splitting module" >&2
@@ -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
  STATE="/tmp/cc-subagent-count"; C=$(cat "$STATE" 2>/dev/null || echo 0); echo $((C+1)) > "$STATE"; [ "$C" -gt 5 ] && echo "WARNING: $C subagents spawned this session" >&2
@@ -0,0 +1,39 @@
1
+ #!/bin/bash
2
+ # mcp-orphan-process-guard.sh — Detect orphaned MCP server processes
3
+ #
4
+ # Solves: MCP server containers not stopped when Claude Code exits (#29058).
5
+ # Docker containers and background processes accumulate over sessions.
6
+ #
7
+ # How it works: Stop hook that checks for running MCP-related processes
8
+ # and warns about potential orphans.
9
+ #
10
+ # TRIGGER: Stop
11
+ # MATCHER: ""
12
+
13
+ set -euo pipefail
14
+
15
+ # Check for running MCP-related processes
16
+ ORPHANS=""
17
+
18
+ # Docker containers with MCP-like names
19
+ if command -v docker &>/dev/null; then
20
+ MCP_CONTAINERS=$(docker ps --format '{{.Names}}' 2>/dev/null | grep -iE 'mcp|claude|anthropic' || true)
21
+ if [ -n "$MCP_CONTAINERS" ]; then
22
+ ORPHANS="${ORPHANS}Docker containers: ${MCP_CONTAINERS}\n"
23
+ fi
24
+ fi
25
+
26
+ # Node/Python processes that might be MCP servers
27
+ MCP_PROCS=$(ps aux 2>/dev/null | grep -iE 'mcp.*server|@modelcontextprotocol' | grep -v grep || true)
28
+ if [ -n "$MCP_PROCS" ]; then
29
+ COUNT=$(echo "$MCP_PROCS" | wc -l)
30
+ ORPHANS="${ORPHANS}MCP processes: ${COUNT} running\n"
31
+ fi
32
+
33
+ if [ -n "$ORPHANS" ]; then
34
+ echo "WARNING: Potential orphaned MCP processes detected:" >&2
35
+ echo -e "$ORPHANS" >&2
36
+ echo "Consider stopping them: docker stop <name> or kill <pid>" >&2
37
+ fi
38
+
39
+ exit 0
@@ -0,0 +1,45 @@
1
+ #!/bin/bash
2
+ # mcp-server-allowlist.sh — Restrict MCP tool calls to allowed servers
3
+ #
4
+ # Solves: Unwanted MCP servers (synced from claude.ai) injecting tools
5
+ # that consume memory and cause OOM crashes (#20412).
6
+ # Also prevents untrusted MCP tools from being called.
7
+ #
8
+ # How it works: PreToolUse hook that checks if a tool call is from an
9
+ # MCP server, and blocks it if the server isn't in the allowlist.
10
+ #
11
+ # CONFIG:
12
+ # CC_MCP_ALLOWED="filesystem:github:memory" (colon-separated server names)
13
+ #
14
+ # TRIGGER: PreToolUse
15
+ # MATCHER: ""
16
+
17
+ set -euo pipefail
18
+
19
+ INPUT=$(cat)
20
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
21
+ [ -z "$TOOL" ] && exit 0
22
+
23
+ ALLOWED="${CC_MCP_ALLOWED:-}"
24
+ [ -n "$ALLOWED" ] || exit 0 # No allowlist = allow all
25
+
26
+ # MCP tools are prefixed with mcp__servername__
27
+ case "$TOOL" in
28
+ mcp__*__*)
29
+ # Extract server name
30
+ SERVER=$(echo "$TOOL" | sed 's/^mcp__\([^_]*\)__.*/\1/')
31
+
32
+ IFS=':' read -ra SERVERS <<< "$ALLOWED"
33
+ for s in "${SERVERS[@]}"; do
34
+ [ "$s" = "$SERVER" ] && exit 0
35
+ done
36
+
37
+ echo "BLOCKED: MCP tool from non-allowed server '$SERVER'." >&2
38
+ echo " Tool: $TOOL" >&2
39
+ echo " Allowed servers: $ALLOWED" >&2
40
+ echo " Add to CC_MCP_ALLOWED to permit." >&2
41
+ exit 2
42
+ ;;
43
+ esac
44
+
45
+ exit 0
@@ -0,0 +1,41 @@
1
+ #!/bin/bash
2
+ # mcp-tool-audit-log.sh — Log all MCP tool calls for security auditing
3
+ #
4
+ # Solves: No visibility into which MCP tools are being called, by whom,
5
+ # and with what parameters. Essential for OWASP MCP Top 10
6
+ # compliance (MCP09: Insufficient Logging).
7
+ #
8
+ # How it works: PostToolUse hook that logs MCP tool calls to a file
9
+ # with timestamp, tool name, server, and input summary.
10
+ #
11
+ # CONFIG:
12
+ # CC_MCP_AUDIT_LOG="~/.claude/mcp-audit.log"
13
+ #
14
+ # TRIGGER: PostToolUse
15
+ # MATCHER: ""
16
+
17
+ set -euo pipefail
18
+
19
+ INPUT=$(cat)
20
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
21
+ [ -z "$TOOL" ] && exit 0
22
+
23
+ # Only log MCP tool calls
24
+ case "$TOOL" in
25
+ mcp__*) ;;
26
+ *) exit 0 ;;
27
+ esac
28
+
29
+ LOG_FILE="${CC_MCP_AUDIT_LOG:-${HOME}/.claude/mcp-audit.log}"
30
+ mkdir -p "$(dirname "$LOG_FILE")"
31
+
32
+ # Extract details
33
+ SERVER=$(echo "$TOOL" | sed 's/^mcp__\([^_]*\)__.*/\1/')
34
+ OPERATION=$(echo "$TOOL" | sed 's/^mcp__[^_]*__//')
35
+ EXIT_CODE=$(echo "$INPUT" | jq -r '.tool_result.exitCode // "0"' 2>/dev/null)
36
+ TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
37
+
38
+ # Log entry
39
+ echo "${TIMESTAMP} | server=${SERVER} | op=${OPERATION} | exit=${EXIT_CODE} | tool=${TOOL}" >> "$LOG_FILE"
40
+
41
+ exit 0
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ #
3
+ # TRIGGER: PreToolUse MATCHER: "Bash"
2
4
  INPUT=$(cat)
3
5
  TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
4
6
  echo "$TOOL" | grep -q '^mcp__' || exit 0
@@ -0,0 +1,44 @@
1
+ #!/bin/bash
2
+ # migration-verify-guard.sh — Require verification before destructive migrations
3
+ #
4
+ # Solves: Claude executing destructive database/code migrations without
5
+ # verifying the plan first (#35435). A Rust migration went wrong
6
+ # across 2 sessions with 20 compounding errors.
7
+ #
8
+ # How it works: PreToolUse hook on Bash that detects migration commands
9
+ # and blocks them unless a verification marker file exists.
10
+ # Create the marker: touch .claude/migration-approved
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 migration commands across frameworks
22
+ MIGRATION_PATTERN='(migrate|migration|db:migrate|typeorm.*migration|prisma.*migrate|alembic|flyway|liquibase|knex.*migrate|sequelize.*db:migrate|rails.*db:migrate|django.*migrate|drizzle.*push)'
23
+
24
+ if echo "$COMMAND" | grep -qiE "$MIGRATION_PATTERN"; then
25
+ # Check for approval marker
26
+ if [ -f ".claude/migration-approved" ]; then
27
+ # Consume the marker (one-time use)
28
+ rm -f ".claude/migration-approved"
29
+ exit 0
30
+ fi
31
+
32
+ echo "BLOCKED: Migration command detected without verification." >&2
33
+ echo "" >&2
34
+ echo "Command: $COMMAND" >&2
35
+ echo "" >&2
36
+ echo "Before running migrations:" >&2
37
+ echo " 1. Review the migration plan carefully" >&2
38
+ echo " 2. Ensure you have a backup or can rollback" >&2
39
+ echo " 3. Create approval: touch .claude/migration-approved" >&2
40
+ echo " 4. Then retry the command" >&2
41
+ exit 2
42
+ fi
43
+
44
+ exit 0
@@ -21,6 +21,8 @@
21
21
  # }
22
22
  # }
23
23
  # ================================================================
24
+ #
25
+ # TRIGGER: PreToolUse MATCHER: "Bash"
24
26
 
25
27
  INPUT=$(cat)
26
28
  FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
@@ -0,0 +1,61 @@
1
+ #!/bin/bash
2
+ # network-exfil-guard.sh — Block data exfiltration via network commands
3
+ #
4
+ # Solves: Claude using curl/wget/nc to send local data to external servers.
5
+ # OWASP MCP Top 10: MCP01 (Secret Exposure via network).
6
+ #
7
+ # How it works: PreToolUse hook on Bash that detects outbound data transfer
8
+ # commands (POST/PUT with file data, netcat connections, base64-encoded
9
+ # data in URLs) and blocks them.
10
+ #
11
+ # TRIGGER: PreToolUse
12
+ # MATCHER: "Bash"
13
+
14
+ set -euo pipefail
15
+
16
+ INPUT=$(cat)
17
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
18
+ [ -z "$COMMAND" ] && exit 0
19
+
20
+ # Patterns for outbound data exfiltration
21
+ BLOCKED=false
22
+ REASON=""
23
+
24
+ # curl/wget sending file contents
25
+ if echo "$COMMAND" | grep -qE 'curl\s+.*(-d\s+@|-F\s+.*=@|--data-binary\s+@|--upload-file)'; then
26
+ BLOCKED=true
27
+ REASON="curl uploading local file"
28
+ fi
29
+
30
+ # wget POST with file
31
+ if echo "$COMMAND" | grep -qE 'wget\s+.*--post-file'; then
32
+ BLOCKED=true
33
+ REASON="wget posting local file"
34
+ fi
35
+
36
+ # netcat sending data
37
+ if echo "$COMMAND" | grep -qE '(nc|ncat|netcat)\s+.*<\s|>\s*(nc|ncat|netcat)'; then
38
+ BLOCKED=true
39
+ REASON="netcat data transfer"
40
+ fi
41
+
42
+ # Pipe sensitive files to network commands
43
+ if echo "$COMMAND" | grep -qE 'cat\s+(~/\.|/etc/|/home/).*\|\s*(curl|wget|nc)'; then
44
+ BLOCKED=true
45
+ REASON="piping sensitive file to network command"
46
+ fi
47
+
48
+ # Base64-encoded data in URL (common exfil technique)
49
+ if echo "$COMMAND" | grep -qE 'base64.*\|\s*curl|curl.*\$\(.*base64'; then
50
+ BLOCKED=true
51
+ REASON="base64-encoded data in network request"
52
+ fi
53
+
54
+ if $BLOCKED; then
55
+ echo "BLOCKED: Potential data exfiltration detected." >&2
56
+ echo " Reason: $REASON" >&2
57
+ echo " Command: $COMMAND" >&2
58
+ exit 2
59
+ fi
60
+
61
+ exit 0
@@ -15,6 +15,8 @@
15
15
  # }]
16
16
  # }
17
17
  # }
18
+ #
19
+ # TRIGGER: PreToolUse MATCHER: "Bash"
18
20
 
19
21
  INPUT=$(cat)
20
22
  COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
@@ -20,6 +20,8 @@
20
20
  # }
21
21
  # }
22
22
  # ================================================================
23
+ #
24
+ # TRIGGER: PreToolUse MATCHER: "Bash"
23
25
 
24
26
  INPUT=$(cat)
25
27
  FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
@@ -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
  if echo "$CONTENT" | grep -qE "from ['\"]/|require\(['\"]/"; then echo "NOTE: Absolute import path detected" >&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 "\balert\(|\bconfirm\(|\bprompt\(" && echo "WARNING: alert/confirm/prompt in code" >&2
@@ -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 ": any\b|<any>" && echo "NOTE: TypeScript any detected — add proper types" >&2
@@ -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
@@ -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 "if\s*\([^=]*=[^=]" && echo "NOTE: Assignment in condition (use ===)" >&2
@@ -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
  DEPTH=$(echo "$CONTENT" | grep -c "function\s*("); [ "$DEPTH" -gt 3 ] && echo "NOTE: Possible callback hell ($DEPTH levels)" >&2
@@ -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 "NOTE: Warn on catch-all routes without 404" >&2
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ #
3
+ # TRIGGER: PreToolUse MATCHER: "Edit|Write"
2
4
  FILE=$(cat | jq -r '.tool_input.file_path // empty' 2>/dev/null)
3
5
  case "$FILE" in *package.json) ;; *) exit 0;; esac
4
6
  CONTENT=$(cat | jq -r '.tool_input.new_string // empty' 2>/dev/null)
@@ -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 "NOTE: Warn on class patterns in functional" >&2
@@ -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 "localStorage\.setItem.*password|sessionStorage.*token" && echo "WARNING: Storing secrets in browser storage" >&2
@@ -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
  COMMENTED=$(echo "$CONTENT" | grep -cE "^\s*(//|#)\s*(if|for|while|function|const|let|var|import|class)" || echo 0); [ "$COMMENTED" -gt 5 ] && echo "NOTE: Large block of commented code — delete or uncomment" >&2
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ #
3
+ # TRIGGER: PreToolUse MATCHER: "Bash"
2
4
  INPUT=$(cat)
3
5
  COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
4
6
  [ -z "$COMMAND" ] && exit 0
@@ -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 -q "console.assert" && echo "NOTE: console.assert in code" >&2
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ #
3
+ # TRIGGER: PermissionRequest MATCHER: ""
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
  if echo "$CONTENT" | grep -qE "catch\s*\([^)]*\)\s*\{[\s\n]*\}|except:[\s\n]*pass"; then echo "WARNING: Empty catch/except block swallows errors" >&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
  FILE=$(cat | jq -r ".tool_input.file_path // empty" 2>/dev/null); case "$FILE" in *test*|*spec*) exit 0;; esac; echo "$CONTENT" | grep -qE "console\.(log|warn)" && echo "NOTE: console statement in non-test file" >&2
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ #
3
+ # TRIGGER: PreToolUse MATCHER: "Bash"
2
4
  INPUT=$(cat)
3
5
  COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
4
6
  CONTENT=$(echo "$INPUT" | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
@@ -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 "console\.(time|timeEnd|timeLog)" && echo "NOTE: console.time left in code" >&2
@@ -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
@@ -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 'curl\s+.*(-X\s+POST|-d\s+@|--data-binary|--upload-file)'; then
@@ -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 -q "dangerouslySetInnerHTML" && echo "WARNING: XSS risk via dangerouslySetInnerHTML" >&2
@@ -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
@@ -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
  echo "$COMMAND" | grep -qE 'git\s+commit' || exit 0
4
6
  git diff --cached 2>/dev/null | grep -qE '^\+.*(debugger|pdb\.set_trace)' && echo "WARNING: Debug in staged" >&2
@@ -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
  DEPTH=$(echo "$CONTENT" | awk "{n=0; for(i=1;i<=length;i++) if(substr(\$0,i,1)==\"{\") n++; if(n>m) m=n} END{print m}"); [ "$DEPTH" -gt 4 ] && echo "NOTE: Deep nesting ($DEPTH levels)" >&2