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
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ #
3
+ # TRIGGER: PreToolUse MATCHER: "Bash"
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
  COMMAND=$(cat | jq -r ".tool_input.command // empty" 2>/dev/null); echo "$COMMAND" | grep -qE "git\s+merge" && git diff --cached 2>/dev/null | grep -q "TODO" && echo "WARNING: TODO markers in merge target" >&2
@@ -1,3 +1,5 @@
1
+ #
2
+ # TRIGGER: PreToolUse MATCHER: "Bash"
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 "TODO[^(]|FIXME[^(]" && ! echo "$CONTENT" | grep -qE "TODO\(#|FIXME\(#" && echo "NOTE: TODO without issue reference" >&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 TS triple-slash references" >&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 code after return" >&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 "^import.*from" && echo "$CONTENT" | grep -cE "^import" | xargs -I{} test {} -gt 10 && echo "NOTE: Many imports — check for unused ones" >&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 unused state in components" >&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 "^\s*var\s" && echo "NOTE: var keyword — use const/let" >&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 "Access-Control.*\*" && echo "WARNING: Wildcard CORS origin" >&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 "NOTE: Warn on window.location assignment" >&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 "\bwith\s*\(" && echo "WARNING: with statement is deprecated" >&2
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ #
3
+ # TRIGGER: PreToolUse MATCHER: "Bash"
2
4
  FILE=$(cat | jq -r '.tool_input.file_path // empty' 2>/dev/null)
3
5
  [ -z "$FILE" ] && exit 0
4
6
  case "$FILE" in
@@ -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 "parseXML|xml2js|DOMParser|libxml" && echo "$CONTENT" | grep -q "ENTITY" && echo "WARNING: Possible XXE in XML parsing" >&2
@@ -17,6 +17,8 @@
17
17
  # }
18
18
 
19
19
  # Linux (notify-send) — skip on WSL2 where D-Bus may not be running
20
+ #
21
+ # TRIGGER: PreToolUse MATCHER: "Bash"
20
22
  if command -v notify-send &>/dev/null && [ -z "$WSL_DISTRO_NAME" ]; then
21
23
  notify-send "Claude Code" "Waiting for your input" --urgency=normal 2>/dev/null && exit 0
22
24
  fi
@@ -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
  echo "$COMMAND" | grep -qE "^\s*npm\s+install" && echo "NOTE: Run npm audit after install" >&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
  if echo "$COMMAND" | grep -qE '^\s*(npm\s+publish|npx\s+npm\s+publish)' && ! echo "$COMMAND" | grep -qE '\-\-dry-run'; 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 // empty' 2>/dev/null)
3
5
  FILE=$(cat | jq -r '.tool_input.file_path // empty' 2>/dev/null)
4
6
  [ -z "$CONTENT" ] && exit 0
@@ -0,0 +1,92 @@
1
+ #!/bin/bash
2
+ # npm-supply-chain-guard.sh — Detect npm supply chain attack patterns
3
+ #
4
+ # Solves: npm install can execute arbitrary code via postinstall scripts.
5
+ # Claude Code may install malicious packages via typosquatting,
6
+ # dependency confusion, or compromised packages (#39421).
7
+ #
8
+ # How it works: PreToolUse hook on Bash that detects npm/yarn/pnpm
9
+ # install commands and checks for:
10
+ # 1. Typosquatting patterns (similar to popular packages)
11
+ # 2. Scoped packages from unknown registries
12
+ # 3. Packages with suspicious install scripts
13
+ # 4. Version pinning warnings
14
+ #
15
+ # TRIGGER: PreToolUse
16
+ # MATCHER: "Bash"
17
+ #
18
+ # Usage:
19
+ # {
20
+ # "hooks": {
21
+ # "PreToolUse": [{
22
+ # "matcher": "Bash",
23
+ # "hooks": [{ "type": "command", "command": "~/.claude/hooks/npm-supply-chain-guard.sh" }]
24
+ # }]
25
+ # }
26
+ # }
27
+
28
+ INPUT=$(cat)
29
+ CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
30
+ [ -z "$CMD" ] && exit 0
31
+
32
+ # Only check npm/yarn/pnpm install commands
33
+ echo "$CMD" | grep -qE '\b(npm|yarn|pnpm)\s+(install|add|i)\b' || exit 0
34
+
35
+ # Extract package names from command
36
+ PACKAGES=$(echo "$CMD" | grep -oE '\b(npm|yarn|pnpm)\s+(install|add|i)\s+(.+)' | sed -E 's/^(npm|yarn|pnpm)\s+(install|add|i)\s+//' | tr ' ' '\n' | grep -v '^-')
37
+
38
+ WARNINGS=""
39
+
40
+ for pkg in $PACKAGES; do
41
+ # Skip flags
42
+ [[ "$pkg" == -* ]] && continue
43
+
44
+ # Check for known typosquatting patterns
45
+ # Common targets: lodash, express, react, axios, webpack, babel
46
+ POPULAR=("lodash" "express" "react" "axios" "webpack" "babel" "moment" "chalk" "commander" "inquirer")
47
+ for popular in "${POPULAR[@]}"; do
48
+ # Skip exact matches
49
+ [ "$pkg" = "$popular" ] && continue
50
+ # Check Levenshtein-like similarity (simple: 1 char difference)
51
+ if [ "${#pkg}" -ge 3 ] && [ "${#pkg}" -le $((${#popular} + 2)) ]; then
52
+ # Check if package name is very similar to a popular one
53
+ diff_count=$(python3 -c "
54
+ import sys
55
+ a, b = '$pkg', '$popular'
56
+ if abs(len(a)-len(b)) <= 2:
57
+ # Simple edit distance check
58
+ d = sum(1 for x,y in zip(a,b) if x!=y) + abs(len(a)-len(b))
59
+ print(d)
60
+ else:
61
+ print(99)
62
+ " 2>/dev/null)
63
+ if [ -n "$diff_count" ] && [ "$diff_count" -le 2 ] && [ "$diff_count" -gt 0 ]; then
64
+ WARNINGS="${WARNINGS}\n ⚠ '$pkg' looks similar to popular package '$popular' (possible typosquatting)"
65
+ fi
66
+ fi
67
+ done
68
+
69
+ # Check for internal/private scope packages being installed from public registry
70
+ if echo "$pkg" | grep -qE '^@[a-z]+-internal/|^@private-'; then
71
+ WARNINGS="${WARNINGS}\n ⚠ '$pkg' looks like an internal scoped package — verify it exists on the intended registry"
72
+ fi
73
+ done
74
+
75
+ # Check for --ignore-scripts bypass
76
+ if echo "$CMD" | grep -q '\-\-ignore-scripts'; then
77
+ # This is actually a safety measure, no warning needed
78
+ :
79
+ fi
80
+
81
+ # Warn about not using --ignore-scripts
82
+ if [ -n "$PACKAGES" ] && ! echo "$CMD" | grep -qE '\-\-ignore-scripts|\-\-production'; then
83
+ WARNINGS="${WARNINGS}\n ℹ Consider using --ignore-scripts to prevent postinstall script execution"
84
+ fi
85
+
86
+ if [ -n "$WARNINGS" ]; then
87
+ echo "⚠ npm supply chain check:" >&2
88
+ echo -e "$WARNINGS" >&2
89
+ # Warn but don't block — exit 0
90
+ fi
91
+
92
+ 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
@@ -22,6 +22,8 @@
22
22
  # }]
23
23
  # }
24
24
  # }
25
+ #
26
+ # TRIGGER: PostToolUse MATCHER: "Bash"
25
27
 
26
28
  INPUT=$(cat)
27
29
  OUTPUT=$(echo "$INPUT" | jq -r '.tool_result.stdout // 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 '\brm\b.*package\.json'; then
@@ -21,6 +21,8 @@
21
21
  # }
22
22
  # }
23
23
  # ================================================================
24
+ #
25
+ # TRIGGER: PreToolUse MATCHER: "Bash"
24
26
 
25
27
  INPUT=$(cat)
26
28
  TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
@@ -15,6 +15,8 @@
15
15
  # }]
16
16
  # }
17
17
  # }
18
+ #
19
+ # TRIGGER: PreToolUse MATCHER: "Bash"
18
20
 
19
21
  INPUT=$(cat)
20
22
  TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
@@ -25,6 +25,8 @@
25
25
  # cat ~/.claude/tool-usage.jsonl | jq -s 'group_by(.tool) | map({tool: .[0].tool, count: length}) | sort_by(-.count)'
26
26
  # # Top commands:
27
27
  # cat ~/.claude/tool-usage.jsonl | jq -s '[.[] | select(.tool=="Bash")] | group_by(.command | split(" ")[0]) | map({cmd: .[0].command | split(" ")[0], count: length}) | sort_by(-.count) | .[:20]'
28
+ #
29
+ # TRIGGER: PreToolUse MATCHER: "Bash"
28
30
 
29
31
  INPUT=$(cat)
30
32
  TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
@@ -0,0 +1,48 @@
1
+ #!/bin/bash
2
+ # permission-entry-validator.sh — Clean broken permission entries from settings
3
+ #
4
+ # Solves: Shell redirect targets saved as standalone permissions (#40382).
5
+ # Commands like `az ... > "filepath"` cause Claude Code to save
6
+ # `Bash("D:/path/file.json")` which is a bare filepath, not a command.
7
+ #
8
+ # How it works: Stop hook that reads settings.local.json and removes
9
+ # permission entries that are bare file paths (not valid command patterns).
10
+ # Identifies entries matching path patterns without a command prefix.
11
+ #
12
+ # TRIGGER: Stop
13
+ # MATCHER: ""
14
+
15
+ set -euo pipefail
16
+
17
+ SETTINGS_FILE=".claude/settings.local.json"
18
+ [ -f "$SETTINGS_FILE" ] || exit 0
19
+
20
+ # Check for broken entries (bare file paths as Bash permissions)
21
+ BROKEN=$(jq -r '
22
+ .permissions.allow // [] | .[] |
23
+ select(
24
+ startswith("Bash(\"") and
25
+ (
26
+ # Windows paths
27
+ test("^Bash\\(\"[A-Z]:/") or
28
+ # Unix absolute paths without command
29
+ test("^Bash\\(\"/[^\"]*\"\\)$")
30
+ ) and
31
+ # Must NOT contain a space (command + args have spaces)
32
+ (test("^Bash\\(\"[^\" ]*\"\\)$"))
33
+ )
34
+ ' "$SETTINGS_FILE" 2>/dev/null || true)
35
+
36
+ if [ -n "$BROKEN" ]; then
37
+ COUNT=$(echo "$BROKEN" | wc -l)
38
+ echo "WARNING: Found $COUNT broken permission entries (bare file paths):" >&2
39
+ echo "$BROKEN" | head -5 | while IFS= read -r entry; do
40
+ echo " $entry" >&2
41
+ done
42
+ echo "" >&2
43
+ echo "These entries were likely created by 'Always allow' on commands with" >&2
44
+ echo "shell redirects (> filepath). They don't match any command pattern." >&2
45
+ echo "Consider removing them from $SETTINGS_FILE" >&2
46
+ fi
47
+
48
+ exit 0
@@ -0,0 +1,50 @@
1
+ #!/bin/bash
2
+ # permission-pattern-auto-allow.sh — Auto-allow commands matching user-defined patterns
3
+ #
4
+ # Solves: Claude repeatedly asks for permission to run commands
5
+ # even after "Always Allow" — because the settings use
6
+ # exact argument matching, not pattern matching (#819).
7
+ #
8
+ # How it works: Maintains a list of regex patterns in an env var
9
+ # or config file. If the Bash command matches any pattern,
10
+ # returns allow decision. Bypasses the broken exact-match
11
+ # permission system entirely.
12
+ #
13
+ # Config: Set ALLOWED_PATTERNS env var or create ~/.claude/allowed-patterns.txt
14
+ # Example patterns (one per line):
15
+ # ^npm (test|run|install|ci)
16
+ # ^git (status|log|diff|add|commit|push|pull|fetch|branch|checkout)
17
+ # ^(ls|cat|pwd|echo|head|tail|wc|grep|find|which|env)
18
+ # ^python[23]?\s
19
+ # ^cargo (build|test|run|check)
20
+ #
21
+ # TRIGGER: PreToolUse
22
+ # MATCHER: "Bash"
23
+
24
+ set -euo pipefail
25
+ INPUT=$(cat)
26
+
27
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
28
+ [ -z "$COMMAND" ] && exit 0
29
+
30
+ # Load patterns from file or env
31
+ PATTERN_FILE="${HOME}/.claude/allowed-patterns.txt"
32
+ if [ -f "$PATTERN_FILE" ]; then
33
+ while IFS= read -r pattern || [ -n "$pattern" ]; do
34
+ # Skip empty lines and comments
35
+ [[ -z "$pattern" || "$pattern" == \#* ]] && continue
36
+ if echo "$COMMAND" | grep -qE "$pattern" 2>/dev/null; then
37
+ exit 0
38
+ fi
39
+ done < "$PATTERN_FILE"
40
+ elif [ -n "${ALLOWED_PATTERNS:-}" ]; then
41
+ # Fallback: pipe-separated patterns in env var
42
+ echo "$ALLOWED_PATTERNS" | tr '|' '\n' | while IFS= read -r pattern; do
43
+ [ -z "$pattern" ] && continue
44
+ if echo "$COMMAND" | grep -qE "$pattern" 2>/dev/null; then
45
+ exit 0
46
+ fi
47
+ done
48
+ fi
49
+
50
+ exit 0
@@ -16,6 +16,8 @@
16
16
  # }
17
17
  # }
18
18
  # ================================================================
19
+ #
20
+ # TRIGGER: PreToolUse MATCHER: "Bash"
19
21
 
20
22
  INPUT=$(cat)
21
23
  FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // 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,37 @@
1
+ #!/bin/bash
2
+ # plain-language-danger-warn.sh — Add plain-language warnings to dangerous commands
3
+ #
4
+ # Solves: Users not understanding technical risk of commands (#30505).
5
+ # "git reset --hard" doesn't convey "this deletes all your unsaved work."
6
+ #
7
+ # How it works: PreToolUse hook on Bash that detects dangerous commands
8
+ # and injects plain-language explanations into stderr context.
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
+ # Map dangerous commands to plain-language warnings
20
+ if echo "$COMMAND" | grep -qE 'git\s+reset\s+--hard'; then
21
+ echo "WARNING: This will DELETE all unsaved changes in your working directory." >&2
22
+ echo "Any uncommitted work will be permanently lost." >&2
23
+ elif echo "$COMMAND" | grep -qE 'git\s+clean\s+-[fd]'; then
24
+ echo "WARNING: This will DELETE all untracked files (files not in git)." >&2
25
+ elif echo "$COMMAND" | grep -qE 'git\s+push\s+.*--force'; then
26
+ echo "WARNING: This will OVERWRITE the remote branch history." >&2
27
+ echo "Other people's commits may be permanently lost." >&2
28
+ elif echo "$COMMAND" | grep -qE 'rm\s+-rf\s+/'; then
29
+ echo "WARNING: This will DELETE everything on the system. Unrecoverable." >&2
30
+ elif echo "$COMMAND" | grep -qE 'drop\s+(database|table|schema)'; then
31
+ echo "WARNING: This will DELETE the entire database/table. Data is unrecoverable." >&2
32
+ elif echo "$COMMAND" | grep -qE 'truncate\s+table'; then
33
+ echo "WARNING: This will DELETE all rows in the table." >&2
34
+ fi
35
+
36
+ # Always allow — this hook only warns, doesn't block
37
+ exit 0
@@ -27,6 +27,8 @@
27
27
  # }]
28
28
  # }
29
29
  # }
30
+ #
31
+ # TRIGGER: PreToolUse MATCHER: "Bash"
30
32
 
31
33
  STATE_FILE="/tmp/.cc-plan-mode-active"
32
34
  [ -f "$STATE_FILE" ] || exit 0
@@ -0,0 +1,50 @@
1
+ #!/bin/bash
2
+ # plugin-process-cleanup.sh — Kill leaked plugin subprocesses on session end
3
+ #
4
+ # Solves: Channel plugin subprocesses (bun server.ts) leak across sessions,
5
+ # accumulating to 1000%+ CPU usage (#39137). Each session spawns
6
+ # new processes but never kills old ones.
7
+ #
8
+ # How it works: SessionEnd hook that finds and kills plugin server processes
9
+ # that are still running from the Claude plugins cache directory.
10
+ #
11
+ # TRIGGER: SessionEnd
12
+ # MATCHER: ""
13
+ #
14
+ # Usage:
15
+ # {
16
+ # "hooks": {
17
+ # "SessionEnd": [{
18
+ # "hooks": [{ "type": "command", "command": "~/.claude/hooks/plugin-process-cleanup.sh" }]
19
+ # }]
20
+ # }
21
+ # }
22
+
23
+ # Find plugin server processes from Claude's cache
24
+ PLUGIN_CACHE="$HOME/.claude/plugins/cache"
25
+
26
+ # Kill bun/node server processes from plugin directories
27
+ PIDS=$(pgrep -f "$PLUGIN_CACHE" 2>/dev/null)
28
+
29
+ if [ -n "$PIDS" ]; then
30
+ COUNT=$(echo "$PIDS" | wc -l | tr -d ' ')
31
+ echo "Cleaning up $COUNT leaked plugin process(es)..." >&2
32
+
33
+ for pid in $PIDS; do
34
+ # Try graceful shutdown first
35
+ kill "$pid" 2>/dev/null
36
+ done
37
+
38
+ # Wait briefly for graceful shutdown
39
+ sleep 1
40
+
41
+ # Force kill any remaining
42
+ for pid in $PIDS; do
43
+ if kill -0 "$pid" 2>/dev/null; then
44
+ kill -9 "$pid" 2>/dev/null
45
+ echo " Force-killed PID $pid" >&2
46
+ fi
47
+ done
48
+ fi
49
+
50
+ exit 0
@@ -0,0 +1,59 @@
1
+ #!/bin/bash
2
+ # polyglot-rm-guard.sh — Block file deletion via any language, not just rm
3
+ #
4
+ # Solves: Claude circumvents Bash(rm) deny rules by using Python os.remove(),
5
+ # Node fs.unlinkSync(), or other languages to delete files (#39459).
6
+ # The permission system blocks the tool, not the goal.
7
+ #
8
+ # How it works: PreToolUse hook on Bash that detects file deletion attempts
9
+ # via Python, Node, Ruby, Perl, or any other interpreter — not just rm.
10
+ #
11
+ # TRIGGER: PreToolUse
12
+ # MATCHER: "Bash"
13
+ #
14
+ # Usage:
15
+ # {
16
+ # "hooks": {
17
+ # "PreToolUse": [{
18
+ # "matcher": "Bash",
19
+ # "hooks": [{ "type": "command", "command": "~/.claude/hooks/polyglot-rm-guard.sh" }]
20
+ # }]
21
+ # }
22
+ # }
23
+
24
+ INPUT=$(cat)
25
+ CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
26
+ [ -z "$CMD" ] && exit 0
27
+
28
+ # Python file deletion
29
+ if echo "$CMD" | grep -qE 'python[23]?\s+-c\s.*\b(os\.remove|os\.unlink|shutil\.rmtree|pathlib.*unlink)\b'; then
30
+ echo "BLOCKED: File deletion via Python detected." >&2
31
+ echo "Blocked: os.remove/unlink/rmtree circumvents rm restrictions." >&2
32
+ exit 2
33
+ fi
34
+
35
+ # Node.js file deletion
36
+ if echo "$CMD" | grep -qE 'node\s+-e\s.*\b(unlinkSync|rmdirSync|rmSync|fs\.rm)\b'; then
37
+ echo "BLOCKED: File deletion via Node.js detected." >&2
38
+ exit 2
39
+ fi
40
+
41
+ # Ruby file deletion
42
+ if echo "$CMD" | grep -qE 'ruby\s+-e\s.*\b(File\.delete|FileUtils\.rm)\b'; then
43
+ echo "BLOCKED: File deletion via Ruby detected." >&2
44
+ exit 2
45
+ fi
46
+
47
+ # Perl file deletion
48
+ if echo "$CMD" | grep -qE 'perl\s+-[eE]\s.*\bunlink\b'; then
49
+ echo "BLOCKED: File deletion via Perl detected." >&2
50
+ exit 2
51
+ fi
52
+
53
+ # Generic: any interpreter with remove/delete/unlink in the command
54
+ if echo "$CMD" | grep -qE '(python|node|ruby|perl|php)\s+.*-[ceE]\s.*\b(remove|unlink|delete|rmtree|rmdir)\b'; then
55
+ echo "BLOCKED: File deletion via interpreter detected." >&2
56
+ exit 2
57
+ fi
58
+
59
+ exit 0
@@ -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)
@@ -0,0 +1,53 @@
1
+ #!/bin/bash
2
+ # pre-compact-knowledge-save.sh — Save critical context before compaction
3
+ #
4
+ # Solves: Context compaction losing important decisions, file locations,
5
+ # and progress state. After /compact, Claude forgets what it was
6
+ # doing and repeats work or contradicts earlier decisions.
7
+ #
8
+ # How it works: PreCompact hook that saves the current session state
9
+ # to a checkpoint file that survives compaction. The model can read
10
+ # this file after compaction to restore context.
11
+ #
12
+ # The checkpoint includes: current task, recent decisions, modified files.
13
+ #
14
+ # TRIGGER: PreCompact
15
+ # MATCHER: ""
16
+
17
+ set -euo pipefail
18
+
19
+ INPUT=$(cat)
20
+
21
+ CHECKPOINT="${CC_COMPACT_CHECKPOINT:-.claude/pre-compact-checkpoint.md}"
22
+ mkdir -p "$(dirname "$CHECKPOINT")"
23
+
24
+ TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
25
+
26
+ # Gather session state
27
+ GIT_BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
28
+ MODIFIED=$(git diff --name-only 2>/dev/null | head -10 || echo "none")
29
+ STAGED=$(git diff --cached --name-only 2>/dev/null | head -10 || echo "none")
30
+ RECENT_COMMITS=$(git log --oneline -3 2>/dev/null || echo "none")
31
+
32
+ cat > "$CHECKPOINT" << CHECKPOINT_EOF
33
+ # Pre-Compact Checkpoint
34
+ Generated: ${TIMESTAMP}
35
+ Branch: ${GIT_BRANCH}
36
+
37
+ ## Modified files (not staged)
38
+ ${MODIFIED}
39
+
40
+ ## Staged files
41
+ ${STAGED}
42
+
43
+ ## Recent commits
44
+ ${RECENT_COMMITS}
45
+
46
+ ## Notes
47
+ Read this file after compaction to restore context.
48
+ Check tasks/todo.md for current task progress.
49
+ CHECKPOINT_EOF
50
+
51
+ echo "Pre-compact checkpoint saved to $CHECKPOINT" >&2
52
+
53
+ exit 0