cc-safe-setup 29.6.32 → 29.6.33

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 (384) 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/commit-message-check.sh +2 -0
  99. package/examples/compact-blocker.sh +25 -0
  100. package/examples/composer-guard.sh +2 -0
  101. package/examples/compound-command-allow.sh +2 -0
  102. package/examples/consecutive-failure-circuit-breaker.sh +49 -0
  103. package/examples/console-log-count.sh +2 -0
  104. package/examples/context-compact-advisor.sh +16 -0
  105. package/examples/cors-star-warn.sh +2 -0
  106. package/examples/credential-exfil-guard.sh +2 -0
  107. package/examples/credential-file-cat-guard.sh +2 -0
  108. package/examples/cron-modification-guard.sh +40 -0
  109. package/examples/cwd-project-boundary-guard.sh +50 -0
  110. package/examples/denied-action-retry-guard.sh +41 -0
  111. package/examples/dependency-install-guard.sh +2 -0
  112. package/examples/deploy-guard.sh +2 -0
  113. package/examples/deploy-path-verify-guard.sh +62 -0
  114. package/examples/django-migrate-guard.sh +2 -0
  115. package/examples/docker-volume-guard.sh +2 -0
  116. package/examples/dockerfile-latest-guard.sh +2 -0
  117. package/examples/dotenv-commit-guard.sh +44 -0
  118. package/examples/dotenv-example-sync.sh +55 -0
  119. package/examples/dotnet-build-on-edit.sh +2 -0
  120. package/examples/drizzle-migrate-guard.sh +2 -0
  121. package/examples/edit-counter-test-gate.sh +44 -0
  122. package/examples/edit-error-counter.sh +2 -0
  123. package/examples/edit-guard.sh +2 -0
  124. package/examples/edit-retry-loop-guard.sh +2 -0
  125. package/examples/edit-verify.sh +2 -0
  126. package/examples/enforce-tests.sh +2 -0
  127. package/examples/env-inherit-guard.sh +2 -0
  128. package/examples/env-inline-secret-guard.sh +36 -0
  129. package/examples/env-prod-guard.sh +2 -0
  130. package/examples/env-required-check.sh +2 -0
  131. package/examples/env-var-check.sh +2 -0
  132. package/examples/expo-eject-guard.sh +2 -0
  133. package/examples/export-overwrite-guard.sh +29 -0
  134. package/examples/file-change-tracker.sh +2 -0
  135. package/examples/file-change-undo-tracker.sh +46 -0
  136. package/examples/file-recycle-bin.sh +48 -0
  137. package/examples/file-size-limit.sh +2 -0
  138. package/examples/five-hundred-milestone.sh +2 -0
  139. package/examples/flask-debug-guard.sh +2 -0
  140. package/examples/gem-push-guard.sh +2 -0
  141. package/examples/git-checkout-safety-guard.sh +2 -0
  142. package/examples/git-config-guard.sh +2 -0
  143. package/examples/git-hook-bypass-guard.sh +2 -0
  144. package/examples/git-merge-conflict-prevent.sh +2 -0
  145. package/examples/git-message-length.sh +2 -0
  146. package/examples/git-show-flag-sanitizer.sh +41 -0
  147. package/examples/git-stash-before-danger.sh +2 -0
  148. package/examples/git-submodule-guard.sh +2 -0
  149. package/examples/git-tag-guard.sh +2 -0
  150. package/examples/github-actions-secret-guard.sh +59 -0
  151. package/examples/gitignore-check.sh +2 -0
  152. package/examples/gitops-drift-guard.sh +53 -0
  153. package/examples/go-mod-tidy-warn.sh +2 -0
  154. package/examples/hallucination-url-check.sh +2 -0
  155. package/examples/hardcoded-ip-guard.sh +2 -0
  156. package/examples/headless-empty-result-guard.sh +46 -0
  157. package/examples/headless-stop-guard.sh +43 -0
  158. package/examples/helm-install-guard.sh +2 -0
  159. package/examples/issue-draft-redact-guard.sh +45 -0
  160. package/examples/java-compile-on-edit.sh +2 -0
  161. package/examples/k8s-production-guard.sh +77 -0
  162. package/examples/laravel-artisan-guard.sh +2 -0
  163. package/examples/large-file-guard.sh +2 -0
  164. package/examples/log-level-guard.sh +2 -0
  165. package/examples/magic-number-warn.sh +2 -0
  166. package/examples/max-edit-size-guard.sh +2 -0
  167. package/examples/max-file-count-guard.sh +2 -0
  168. package/examples/max-file-delete-count.sh +2 -0
  169. package/examples/max-function-length.sh +2 -0
  170. package/examples/max-import-count.sh +2 -0
  171. package/examples/max-subagent-count.sh +2 -0
  172. package/examples/mcp-orphan-process-guard.sh +39 -0
  173. package/examples/mcp-server-allowlist.sh +45 -0
  174. package/examples/mcp-tool-audit-log.sh +41 -0
  175. package/examples/mcp-tool-guard.sh +2 -0
  176. package/examples/migration-verify-guard.sh +44 -0
  177. package/examples/monorepo-scope-guard.sh +2 -0
  178. package/examples/network-exfil-guard.sh +61 -0
  179. package/examples/network-guard.sh +2 -0
  180. package/examples/nextjs-env-guard.sh +2 -0
  181. package/examples/no-absolute-import.sh +2 -0
  182. package/examples/no-alert-confirm-prompt.sh +2 -0
  183. package/examples/no-any-type.sh +2 -0
  184. package/examples/no-any-typescript.sh +2 -0
  185. package/examples/no-assignment-in-condition.sh +2 -0
  186. package/examples/no-callback-hell.sh +2 -0
  187. package/examples/no-catch-all-route.sh +2 -0
  188. package/examples/no-circular-dependency.sh +2 -0
  189. package/examples/no-class-in-functional.sh +2 -0
  190. package/examples/no-cleartext-storage.sh +2 -0
  191. package/examples/no-commented-code.sh +2 -0
  192. package/examples/no-commit-fixup.sh +2 -0
  193. package/examples/no-console-assert.sh +2 -0
  194. package/examples/no-console-error-swallow.sh +2 -0
  195. package/examples/no-console-in-prod.sh +2 -0
  196. package/examples/no-console-log.sh +2 -0
  197. package/examples/no-console-time.sh +2 -0
  198. package/examples/no-cors-wildcard.sh +2 -0
  199. package/examples/no-curl-upload.sh +2 -0
  200. package/examples/no-dangerouslySetInnerHTML.sh +2 -0
  201. package/examples/no-dangling-await.sh +2 -0
  202. package/examples/no-debug-in-commit.sh +2 -0
  203. package/examples/no-deep-nesting.sh +2 -0
  204. package/examples/no-deep-relative-import.sh +2 -0
  205. package/examples/no-default-credentials.sh +2 -0
  206. package/examples/no-deprecated-api.sh +2 -0
  207. package/examples/no-direct-dom-manipulation.sh +2 -0
  208. package/examples/no-disabled-test.sh +2 -0
  209. package/examples/no-document-cookie.sh +2 -0
  210. package/examples/no-document-write.sh +2 -0
  211. package/examples/no-empty-function.sh +2 -0
  212. package/examples/no-eval-in-template.sh +2 -0
  213. package/examples/no-eval-template.sh +2 -0
  214. package/examples/no-eval.sh +2 -0
  215. package/examples/no-exec-user-input.sh +2 -0
  216. package/examples/no-expose-internal-ids.sh +2 -0
  217. package/examples/no-floating-promises.sh +2 -0
  218. package/examples/no-force-install.sh +2 -0
  219. package/examples/no-git-rebase-public.sh +2 -0
  220. package/examples/no-global-state.sh +2 -0
  221. package/examples/no-hardcoded-port.sh +2 -0
  222. package/examples/no-hardcoded-url.sh +2 -0
  223. package/examples/no-helmet-missing.sh +2 -0
  224. package/examples/no-http-url.sh +2 -0
  225. package/examples/no-http-without-https.sh +2 -0
  226. package/examples/no-index-as-key.sh +2 -0
  227. package/examples/no-infinite-scroll-mem.sh +2 -0
  228. package/examples/no-inline-event-handler.sh +2 -0
  229. package/examples/no-inline-handler.sh +2 -0
  230. package/examples/no-inline-style.sh +2 -0
  231. package/examples/no-inline-styles.sh +2 -0
  232. package/examples/no-innerhtml.sh +2 -0
  233. package/examples/no-install-global.sh +2 -0
  234. package/examples/no-jwt-in-url.sh +2 -0
  235. package/examples/no-large-commit.sh +2 -0
  236. package/examples/no-localhost-expose.sh +2 -0
  237. package/examples/no-long-switch.sh +2 -0
  238. package/examples/no-magic-number.sh +2 -0
  239. package/examples/no-md5-sha1.sh +2 -0
  240. package/examples/no-memory-leak-interval.sh +2 -0
  241. package/examples/no-mixed-line-endings.sh +2 -0
  242. package/examples/no-mutation-in-reducer.sh +2 -0
  243. package/examples/no-mutation-observer-leak.sh +2 -0
  244. package/examples/no-nested-subscribe.sh +2 -0
  245. package/examples/no-nested-ternary.sh +2 -0
  246. package/examples/no-network-exfil.sh +2 -0
  247. package/examples/no-new-array-fill.sh +2 -0
  248. package/examples/no-object-freeze-mutation.sh +2 -0
  249. package/examples/no-open-redirect.sh +2 -0
  250. package/examples/no-output-truncation.sh +44 -0
  251. package/examples/no-package-downgrade.sh +2 -0
  252. package/examples/no-package-lock-edit.sh +2 -0
  253. package/examples/no-path-join-user-input.sh +2 -0
  254. package/examples/no-port-bind.sh +2 -0
  255. package/examples/no-process-exit.sh +2 -0
  256. package/examples/no-prototype-pollution.sh +2 -0
  257. package/examples/no-push-without-ci.sh +2 -0
  258. package/examples/no-raw-ref.sh +2 -0
  259. package/examples/no-redundant-fragment.sh +2 -0
  260. package/examples/no-render-in-loop.sh +2 -0
  261. package/examples/no-root-user-docker.sh +2 -0
  262. package/examples/no-root-write.sh +2 -0
  263. package/examples/no-secrets-in-args.sh +2 -0
  264. package/examples/no-secrets-in-logs.sh +2 -0
  265. package/examples/no-sensitive-log.sh +2 -0
  266. package/examples/no-side-effects-in-render.sh +2 -0
  267. package/examples/no-sleep-in-hooks.sh +2 -0
  268. package/examples/no-star-import-python.sh +2 -0
  269. package/examples/no-string-concat-sql.sh +2 -0
  270. package/examples/no-sudo-guard.sh +2 -0
  271. package/examples/no-sync-external-call.sh +2 -0
  272. package/examples/no-sync-fs.sh +2 -0
  273. package/examples/no-table-layout.sh +2 -0
  274. package/examples/no-throw-string.sh +2 -0
  275. package/examples/no-todo-in-merge.sh +2 -0
  276. package/examples/no-todo-in-production.sh +2 -0
  277. package/examples/no-todo-without-issue.sh +2 -0
  278. package/examples/no-triple-slash-ref.sh +2 -0
  279. package/examples/no-unreachable-code.sh +2 -0
  280. package/examples/no-unused-import.sh +2 -0
  281. package/examples/no-unused-state.sh +2 -0
  282. package/examples/no-var-keyword.sh +2 -0
  283. package/examples/no-wildcard-cors.sh +2 -0
  284. package/examples/no-wildcard-import.sh +2 -0
  285. package/examples/no-window-location.sh +2 -0
  286. package/examples/no-with-statement.sh +2 -0
  287. package/examples/no-write-outside-src.sh +2 -0
  288. package/examples/no-xml-external-entity.sh +2 -0
  289. package/examples/notify-waiting.sh +2 -0
  290. package/examples/npm-audit-warn.sh +2 -0
  291. package/examples/npm-publish-guard.sh +2 -0
  292. package/examples/npm-script-injection.sh +2 -0
  293. package/examples/npm-supply-chain-guard.sh +92 -0
  294. package/examples/nuxt-config-guard.sh +2 -0
  295. package/examples/output-secret-mask.sh +2 -0
  296. package/examples/package-json-guard.sh +2 -0
  297. package/examples/parallel-session-guard.sh +2 -0
  298. package/examples/path-traversal-guard.sh +2 -0
  299. package/examples/permission-audit-log.sh +2 -0
  300. package/examples/permission-entry-validator.sh +48 -0
  301. package/examples/php-lint-on-edit.sh +2 -0
  302. package/examples/pip-publish-guard.sh +2 -0
  303. package/examples/plain-language-danger-warn.sh +37 -0
  304. package/examples/plan-mode-enforcer.sh +2 -0
  305. package/examples/plugin-process-cleanup.sh +50 -0
  306. package/examples/polyglot-rm-guard.sh +59 -0
  307. package/examples/pr-description-check.sh +2 -0
  308. package/examples/pre-compact-knowledge-save.sh +53 -0
  309. package/examples/pre-compact-transcript-export.sh +85 -0
  310. package/examples/prefer-builtin-tools.sh +2 -0
  311. package/examples/prefer-const.sh +2 -0
  312. package/examples/prefer-dedicated-tools.sh +55 -0
  313. package/examples/prefer-optional-chaining.sh +2 -0
  314. package/examples/prisma-migrate-guard.sh +2 -0
  315. package/examples/prompt-injection-detector.sh +2 -0
  316. package/examples/prompt-length-guard.sh +2 -0
  317. package/examples/protect-dotfiles.sh +2 -0
  318. package/examples/public-repo-push-guard.sh +58 -0
  319. package/examples/push-requires-test-pass-record.sh +2 -0
  320. package/examples/push-requires-test-pass.sh +2 -0
  321. package/examples/rails-migration-guard.sh +2 -0
  322. package/examples/rate-limit-guard.sh +2 -0
  323. package/examples/read-all-files-enforcer.sh +51 -0
  324. package/examples/readme-exists-check.sh +2 -0
  325. package/examples/redis-flushall-guard.sh +2 -0
  326. package/examples/rm-safety-net.sh +2 -0
  327. package/examples/role-tool-guard.sh +69 -0
  328. package/examples/ruby-lint-on-edit.sh +2 -0
  329. package/examples/schema-migration-guard.sh +57 -0
  330. package/examples/scope-guard.sh +2 -0
  331. package/examples/secret-file-read-guard.sh +74 -0
  332. package/examples/self-modify-bypass-guard.sh +54 -0
  333. package/examples/sensitive-log-guard.sh +2 -0
  334. package/examples/session-checkpoint.sh +2 -0
  335. package/examples/session-end-logger.sh +57 -0
  336. package/examples/session-error-rate-monitor.sh +65 -0
  337. package/examples/session-health-monitor.sh +61 -0
  338. package/examples/session-memory-watchdog.sh +17 -0
  339. package/examples/session-permission-reset-guard.sh +39 -0
  340. package/examples/session-resume-env-fix.sh +49 -0
  341. package/examples/session-state-saver.sh +2 -0
  342. package/examples/session-summary-stop.sh +2 -0
  343. package/examples/session-summary.sh +2 -0
  344. package/examples/session-token-counter.sh +2 -0
  345. package/examples/shell-wrapper-guard.sh +2 -0
  346. package/examples/skill-gate.sh +2 -0
  347. package/examples/skill-injection-detector.sh +41 -0
  348. package/examples/spec-file-scope-guard.sh +69 -0
  349. package/examples/spring-profile-guard.sh +2 -0
  350. package/examples/sql-injection-detect.sh +2 -0
  351. package/examples/subagent-budget-guard.sh +2 -0
  352. package/examples/subagent-claudemd-inject.sh +45 -0
  353. package/examples/subagent-tool-call-limiter.sh +48 -0
  354. package/examples/svelte-lint-on-edit.sh +2 -0
  355. package/examples/swift-build-on-edit.sh +2 -0
  356. package/examples/system-message-workaround.sh +44 -0
  357. package/examples/system-package-guard.sh +2 -0
  358. package/examples/temp-file-cleanup.sh +2 -0
  359. package/examples/terminal-state-restore.sh +23 -0
  360. package/examples/test-after-edit.sh +2 -0
  361. package/examples/test-before-commit.sh +2 -0
  362. package/examples/test-before-push.sh +2 -0
  363. package/examples/test-exit-code-verify.sh +2 -0
  364. package/examples/timeout-guard.sh +2 -0
  365. package/examples/timezone-guard.sh +2 -0
  366. package/examples/tmp-output-size-guard.sh +46 -0
  367. package/examples/todo-check.sh +2 -0
  368. package/examples/todo-deadline-warn.sh +48 -0
  369. package/examples/token-budget-per-task.sh +55 -0
  370. package/examples/token-usage-tracker.sh +14 -0
  371. package/examples/turbo-cache-guard.sh +2 -0
  372. package/examples/uncommitted-changes-stop.sh +2 -0
  373. package/examples/uncommitted-work-shield.sh +37 -0
  374. package/examples/usage-warn.sh +2 -0
  375. package/examples/verify-before-commit.sh +2 -0
  376. package/examples/vue-lint-on-edit.sh +2 -0
  377. package/examples/webfetch-domain-allow.sh +96 -0
  378. package/examples/worktree-memory-guard.sh +47 -0
  379. package/examples/worktree-project-unify.sh +19 -0
  380. package/examples/worktree-unmerged-guard.sh +2 -0
  381. package/examples/write-overwrite-confirm.sh +40 -0
  382. package/examples/write-secret-guard.sh +2 -0
  383. package/examples/write-test-ratio.sh +2 -0
  384. package/package.json +2 -2
package/COOKBOOK.md CHANGED
@@ -236,6 +236,76 @@ npx cc-safe-setup --install-example push-requires-test-pass-record
236
236
 
237
237
  Two-hook system: the PostToolUse `record` hook detects successful test runs (`npm test`, `pytest`, `cargo test`, etc.) and saves a timestamp. The PreToolUse hook blocks push to main/master/production if no recent test pass exists (30-minute window). See [#36673](https://github.com/anthropics/claude-code/issues/36673).
238
238
 
239
+ ## Recipe: Protect CI/CD Pipelines
240
+
241
+ ```bash
242
+ npx cc-safe-setup --install-example github-actions-secret-guard
243
+ npx cc-safe-setup --install-example ci-workflow-guard
244
+ npx cc-safe-setup --install-example gitops-drift-guard
245
+ ```
246
+
247
+ Three-hook system: `github-actions-secret-guard` (PostToolUse) detects hardcoded secrets in workflow files. `ci-workflow-guard` (PostToolUse) flags `--no-verify`, remote script execution, and broad write permissions. `gitops-drift-guard` (PreToolUse) warns when editing infrastructure files on protected branches.
248
+
249
+ ## Recipe: Kubernetes Production Safety
250
+
251
+ ```bash
252
+ npx cc-safe-setup --install-example k8s-production-guard
253
+ # Set production contexts/namespaces:
254
+ export CC_K8S_PROD_CONTEXTS="prod:production"
255
+ export CC_K8S_PROD_NAMESPACES="production:prod"
256
+ ```
257
+
258
+ Blocks `kubectl delete`, `scale --replicas=0`, `drain`, and `helm uninstall` on production namespaces/contexts. Safe operations (get, logs, describe) are always allowed.
259
+
260
+ ## Recipe: MCP Server Allowlist
261
+
262
+ ```bash
263
+ npx cc-safe-setup --install-example mcp-server-allowlist
264
+ npx cc-safe-setup --install-example mcp-tool-audit-log
265
+ export CC_MCP_ALLOWED="github:filesystem:memory"
266
+ ```
267
+
268
+ Only allows MCP tool calls from whitelisted servers. Blocks calls from unknown/synced servers that may cause OOM crashes ([#20412](https://github.com/anthropics/claude-code/issues/20412)). The audit log records all MCP tool calls for security review (OWASP MCP09 compliance).
269
+
270
+ ## Recipe: Role-Based Agent Teams
271
+
272
+ ```bash
273
+ npx cc-safe-setup --install-example role-tool-guard
274
+ echo "pm" > .claude/current-role.txt
275
+ ```
276
+
277
+ Restricts tools based on agent role. PM can only read and delegate (no Edit/Write/Bash). Architect can design but not execute. Reviewer is read-only. Developer has full access. Switch roles: `echo "developer" > .claude/current-role.txt`. See [#40425](https://github.com/anthropics/claude-code/issues/40425).
278
+
279
+ ## Recipe: Fix git show --no-stat Bug
280
+
281
+ Claude Code frequently runs `git show <ref> --no-stat`, which fails because `--no-stat` is not a valid git-show flag. This wastes context on error output. The hook silently rewrites the command.
282
+
283
+ ```bash
284
+ npx cc-safe-setup --install-example git-show-flag-sanitizer
285
+ ```
286
+
287
+ Install in `.claude/settings.json` as a PreToolUse hook with matcher `Bash`. The hook detects `git show` + `--no-stat`, strips the invalid flag, and returns the corrected command via `updatedInput`. See [#13071](https://github.com/anthropics/claude-code/issues/13071).
288
+
289
+ ## Recipe: Disable Auto-Compaction
290
+
291
+ Power users who manage context manually can block auto-compaction entirely:
292
+
293
+ ```bash
294
+ npx cc-safe-setup --install-example compact-blocker
295
+ ```
296
+
297
+ Install as a PreCompact hook (no matcher needed). Exit code 2 blocks compaction. For conditional control, add a guard: `[ -f /tmp/allow-compact ] && exit 0`. See [#6689](https://github.com/anthropics/claude-code/issues/6689).
298
+
299
+ ## Recipe: WebFetch Domain Allowlist
300
+
301
+ `WebFetch(domain:*)` in settings.json fails in sandbox mode. This hook auto-approves WebFetch requests by domain:
302
+
303
+ ```bash
304
+ npx cc-safe-setup --install-example webfetch-domain-allow
305
+ ```
306
+
307
+ Install as a PreToolUse hook with matcher `WebFetch`. By default allows all domains. Set `CC_WEBFETCH_ALLOW_DOMAINS=github.com,docs.anthropic.com` for specific domains. See [#9329](https://github.com/anthropics/claude-code/issues/9329).
308
+
239
309
  ## Further Reading
240
310
 
241
311
  - [Getting Started](https://yurukusa.github.io/cc-safe-setup/getting-started.html)
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![npm downloads](https://img.shields.io/npm/dw/cc-safe-setup)](https://www.npmjs.com/package/cc-safe-setup)
5
5
  [![tests](https://github.com/yurukusa/cc-safe-setup/actions/workflows/test.yml/badge.svg)](https://github.com/yurukusa/cc-safe-setup/actions/workflows/test.yml)
6
6
 
7
- **One command to make Claude Code safe for autonomous operation.** 517 example hooks · 7,591 tests · 1,000+ installs/day · [日本語](docs/README.ja.md)
7
+ **One command to make Claude Code safe for autonomous operation.** 611 example hooks · 10,411 tests · 1,000+ installs/day · [日本語](docs/README.ja.md)
8
8
 
9
9
  ```bash
10
10
  npx cc-safe-setup
@@ -91,6 +91,9 @@ Override Claude Code's built-in confirmation prompts. These run **after** the bu
91
91
  | `edit-always-allow` | Edit prompts in `.claude/skills/` despite `bypassPermissions` | [#36192](https://github.com/anthropics/claude-code/issues/36192) |
92
92
  | `allow-git-hooks-dir` | Edit prompts in `.git/hooks/` for pre-commit/pre-push setup | |
93
93
  | `allow-protected-dirs` | All protected directory prompts (CI/Docker environments) | [#36168](https://github.com/anthropics/claude-code/issues/36168) |
94
+ | `git-show-flag-sanitizer` | Strips invalid `--no-stat` from `git show` (wastes context on error) | [#13071](https://github.com/anthropics/claude-code/issues/13071) |
95
+ | `compact-blocker` | Blocks auto-compaction via PreCompact (preserves full context) | [#6689](https://github.com/anthropics/claude-code/issues/6689) |
96
+ | `webfetch-domain-allow` | Auto-approves WebFetch by domain (fixes broken `domain:*` wildcard) | [#9329](https://github.com/anthropics/claude-code/issues/9329) |
94
97
 
95
98
  Install any of these: `npx cc-safe-setup --install-example <name>`
96
99
 
@@ -117,7 +120,7 @@ Install any of these: `npx cc-safe-setup --install-example <name>`
117
120
  | `--scan [--apply]` | Tech stack detection |
118
121
  | `--export / --import` | Team config sharing |
119
122
  | `--verify` | Test each hook |
120
- | `--install-example <name>` | Install from 517 examples |
123
+ | `--install-example <name>` | Install from 564 examples |
121
124
  | `--examples [filter]` | Browse examples by keyword |
122
125
  | `--full` | All-in-one setup |
123
126
  | `--status` | Check installed hooks |
@@ -404,6 +407,7 @@ See [Issue #1](https://github.com/yurukusa/cc-safe-setup/issues/1) for details.
404
407
  - [Cookbook](COOKBOOK.md) — 26 practical recipes (block, approve, protect, monitor, diagnose)
405
408
  - [Official Hooks Reference](https://code.claude.com/docs/en/hooks) — Claude Code hooks documentation
406
409
  - [Hooks Cookbook](https://github.com/yurukusa/claude-code-hooks/blob/main/COOKBOOK.md) — 25 recipes from real GitHub Issues ([interactive version](https://yurukusa.github.io/claude-code-hooks/))
410
+ - [Skills Guide deep-dive (Qiita, 19K+ views)](https://qiita.com/yurukusa/items/f69920b4a02cf7e2988c) — Anthropic's official Skills PDF analyzed with 40% token reduction
407
411
  - [Japanese guide (Qiita)](https://qiita.com/yurukusa/items/a9714b33f5d974e8f1e8) — この記事の日本語解説
408
412
  - [v2.1.85 `if` field guide (Qiita)](https://qiita.com/yurukusa/items/7079866e9dc239fcdd57) — Reduce hook overhead with conditional execution
409
413
  - [Hook Test Runner](https://github.com/yurukusa/cc-hook-test) — `npx cc-hook-test <hook.sh>` to auto-test any hook
@@ -0,0 +1,42 @@
1
+ #!/bin/bash
2
+ # absolute-rule-enforcer.sh — Enforce CLAUDE.md "ABSOLUTE RULE" markers
3
+ #
4
+ # Solves: ABSOLUTE RULEs in CLAUDE.md treated as advisory (#40284).
5
+ # Even rules marked with strong language get ignored under
6
+ # context pressure. This hook extracts and enforces them.
7
+ #
8
+ # How it works: Stop hook that parses CLAUDE.md for "ABSOLUTE RULE"
9
+ # or "MUST NEVER" markers, extracts the constraint keywords,
10
+ # and checks if the session violated them.
11
+ #
12
+ # TRIGGER: Stop
13
+ # MATCHER: ""
14
+
15
+ set -euo pipefail
16
+
17
+ # Find CLAUDE.md
18
+ CLAUDEMD=""
19
+ for candidate in "CLAUDE.md" "../CLAUDE.md" "../../CLAUDE.md"; do
20
+ if [ -f "$candidate" ]; then
21
+ CLAUDEMD="$candidate"
22
+ break
23
+ fi
24
+ done
25
+
26
+ [ -z "$CLAUDEMD" ] && exit 0
27
+
28
+ # Extract absolute rules (lines containing ABSOLUTE, MUST NEVER, NEVER, 絶対)
29
+ RULES=$(grep -iE '(ABSOLUTE|MUST NEVER|NEVER|絶対|禁止)' "$CLAUDEMD" 2>/dev/null | head -10 || true)
30
+
31
+ if [ -z "$RULES" ]; then
32
+ exit 0
33
+ fi
34
+
35
+ # Log that absolute rules exist (reminder to model via stderr)
36
+ echo "REMINDER: This project has absolute rules in CLAUDE.md:" >&2
37
+ echo "$RULES" | head -5 | while IFS= read -r rule; do
38
+ echo " $rule" >&2
39
+ done
40
+ echo "Verify your changes comply before finalizing." >&2
41
+
42
+ exit 0
@@ -13,6 +13,8 @@
13
13
  # WARNING: Only use in environments where you trust Claude's edits
14
14
  # to your configuration. In shared or production environments,
15
15
  # keep the default prompts.
16
+ #
17
+ # TRIGGER: PermissionRequest MATCHER: ""
16
18
 
17
19
  INPUT=$(cat)
18
20
  FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
@@ -9,6 +9,8 @@
9
9
  #
10
10
  # WARNING: Only allow specific subdirectories you trust.
11
11
  # Never blanket-allow all of .git/ — that exposes HEAD, config, etc.
12
+ #
13
+ # TRIGGER: PermissionRequest MATCHER: ""
12
14
 
13
15
  INPUT=$(cat)
14
16
  FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
@@ -13,6 +13,8 @@
13
13
  # It bypasses ALL built-in file protection. Do NOT use in shared or
14
14
  # production environments. Prefer allow-git-hooks-dir.sh or
15
15
  # allow-claude-settings.sh for targeted bypass.
16
+ #
17
+ # TRIGGER: PermissionRequest MATCHER: ""
16
18
 
17
19
  INPUT=$(cat)
18
20
  FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
@@ -21,6 +21,8 @@
21
21
  # }]
22
22
  # }
23
23
  # }
24
+ #
25
+ # TRIGGER: PermissionRequest MATCHER: ""
24
26
 
25
27
  INPUT=$(cat)
26
28
  TOOL=$(echo "$INPUT" | jq -r '.tool_name // 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
@@ -14,6 +14,8 @@
14
14
  # }]
15
15
  # }
16
16
  # }
17
+ #
18
+ # TRIGGER: PreToolUse MATCHER: "Bash"
17
19
 
18
20
  INPUT=$(cat)
19
21
  TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
@@ -14,6 +14,8 @@
14
14
  #
15
15
  # See: https://github.com/anthropics/claude-code/issues/30519
16
16
  # See: https://github.com/anthropics/claude-code/issues/16561
17
+ #
18
+ # TRIGGER: PermissionRequest MATCHER: ""
17
19
 
18
20
  INPUT=$(cat)
19
21
  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
  INPUT=$(cat)
3
5
  TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
4
6
  [ "$TOOL" != "Bash" ] && exit 0
@@ -8,6 +8,8 @@
8
8
  # GitHub Issues: #36900, #32985
9
9
  #
10
10
  # Usage: Add to settings.json as a PreToolUse hook on "Bash"
11
+ #
12
+ # TRIGGER: PermissionRequest MATCHER: ""
11
13
 
12
14
  INPUT=$(cat)
13
15
  COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
@@ -14,6 +14,8 @@
14
14
  # }]
15
15
  # }
16
16
  # }
17
+ #
18
+ # TRIGGER: PermissionRequest MATCHER: ""
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: PermissionRequest MATCHER: ""
1
3
  INPUT=$(cat)
2
4
  TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
3
5
  case "$TOOL" in
@@ -8,6 +8,8 @@
8
8
  #
9
9
  # Usage: Add to settings.json as a PreToolUse hook on "Bash"
10
10
  # Customize SAFE_COMMANDS for your use case.
11
+ #
12
+ # TRIGGER: PermissionRequest MATCHER: ""
11
13
 
12
14
  INPUT=$(cat)
13
15
  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 '^\s*(npm\s+test|npm\s+run\s+test|npx\s+(jest|vitest|mocha|ava|tap|playwright\s+test|cypress\s+run)|yarn\s+test|pnpm\s+test|bun\s+test)\b'; then
@@ -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)
@@ -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
  FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
@@ -20,6 +20,8 @@
20
20
  # }]
21
21
  # }
22
22
  # }
23
+ #
24
+ # TRIGGER: PermissionRequest MATCHER: ""
23
25
 
24
26
  INPUT=$(cat)
25
27
  COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
@@ -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)
@@ -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)
@@ -13,13 +13,13 @@
13
13
  # Default banned commands (configurable via CC_BANNED_COMMANDS):
14
14
  # sed -i (in-place file editing — use Edit tool instead)
15
15
  # awk -i inplace (same reason)
16
- # perl -pi -e (same reason)
16
+ # perl -i / perl -pi (same reason — covers -i -pe, -pi -e, etc.)
17
17
  #
18
18
  # TRIGGER: PreToolUse MATCHER: "Bash"
19
19
  #
20
20
  # Configuration:
21
21
  # CC_BANNED_COMMANDS — colon-separated list of regex patterns to block
22
- # Default: "sed -i:awk -i inplace:perl -pi"
22
+ # Default: "sed -i:awk -i inplace:perl -pi:perl .*-i"
23
23
 
24
24
  INPUT=$(cat)
25
25
  COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
@@ -27,7 +27,7 @@ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
27
27
  [ -z "$COMMAND" ] && exit 0
28
28
 
29
29
  # Configurable banned patterns (colon-separated)
30
- BANNED="${CC_BANNED_COMMANDS:-sed\s+-i:awk\s+-i\s+inplace:perl\s+-pi}"
30
+ BANNED="${CC_BANNED_COMMANDS:-sed\s+-i:awk\s+-i\s+inplace:perl\s+-pi:perl\s+.*-i}"
31
31
 
32
32
  # Check each banned pattern
33
33
  IFS=':' read -ra PATTERNS <<< "$BANNED"
@@ -0,0 +1,72 @@
1
+ #!/bin/bash
2
+ # bash-domain-allowlist.sh — Block curl/wget to unauthorized domains
3
+ #
4
+ # Solves: Sandbox allowedDomains not enforced for plain HTTP requests,
5
+ # allowing data exfiltration via curl/wget (#40213).
6
+ # Also provides defense-in-depth when sandbox is not available.
7
+ #
8
+ # How it works: PreToolUse hook on Bash that extracts target domains from
9
+ # curl/wget commands and blocks requests to domains not in the allowlist.
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/bash-domain-allowlist.sh" }]
20
+ # }]
21
+ # }
22
+ # }
23
+ #
24
+ # Configuration: Set CC_ALLOWED_DOMAINS env var (comma-separated)
25
+ # or edit the ALLOWED_DOMAINS array below.
26
+
27
+ INPUT=$(cat)
28
+ CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
29
+ [ -z "$CMD" ] && exit 0
30
+
31
+ # Only check commands that make HTTP requests
32
+ echo "$CMD" | grep -qE '\b(curl|wget|http|fetch)\b' || exit 0
33
+
34
+ # ========================================
35
+ # DOMAIN ALLOWLIST — edit to your needs
36
+ # ========================================
37
+ if [ -n "$CC_ALLOWED_DOMAINS" ]; then
38
+ IFS=',' read -ra ALLOWED_DOMAINS <<< "$CC_ALLOWED_DOMAINS"
39
+ else
40
+ ALLOWED_DOMAINS=(
41
+ "github.com"
42
+ "api.github.com"
43
+ "raw.githubusercontent.com"
44
+ "registry.npmjs.org"
45
+ "pypi.org"
46
+ "*.amazonaws.com"
47
+ "localhost"
48
+ "127.0.0.1"
49
+ )
50
+ fi
51
+
52
+ # Extract target domains from URLs in the command
53
+ DOMAINS=$(echo "$CMD" | grep -oE 'https?://[^/"'"'"'"'"'"' ]+' | sed -E 's|^https?://||;s|/.*||;s|:.*||' | sort -u)
54
+ [ -z "$DOMAINS" ] && exit 0
55
+
56
+ for domain in $DOMAINS; do
57
+ allowed=false
58
+ for pattern in "${ALLOWED_DOMAINS[@]}"; do
59
+ # Convert glob to regex (*.example.com -> .*\.example\.com)
60
+ regex=$(echo "$pattern" | sed 's/\./\\./g; s/\*/.*/g')
61
+ if echo "$domain" | grep -qE "^${regex}$"; then
62
+ allowed=true
63
+ break
64
+ fi
65
+ done
66
+ if [ "$allowed" = false ]; then
67
+ echo "BLOCKED: HTTP request to unauthorized domain: $domain" >&2
68
+ echo "Allowed: ${ALLOWED_DOMAINS[*]}" >&2
69
+ exit 2
70
+ fi
71
+ done
72
+ exit 0
@@ -0,0 +1,56 @@
1
+ #!/bin/bash
2
+ # bash-safety-auto-deny.sh — Auto-deny commands that trigger safety prompts
3
+ #
4
+ # Solves: Users want "auto-deny" instead of "prompt" for risky commands (#28993).
5
+ # Currently Claude's safety heuristic prompts the user. This hook
6
+ # blocks the command outright, forcing Claude to reformulate.
7
+ #
8
+ # How it works: PreToolUse hook on Bash that detects patterns the built-in
9
+ # safety system would flag, and blocks them with exit 2 instead of
10
+ # prompting. Claude learns to use safer alternatives.
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
+ # Patterns that trigger built-in safety prompts
22
+ # 1. Pipe to bash/sh (command injection risk)
23
+ if echo "$COMMAND" | grep -qE '\|\s*(bash|sh|zsh)\b'; then
24
+ echo "BLOCKED: Piping to shell interpreter detected." >&2
25
+ echo "Reformulate without piping to bash/sh." >&2
26
+ exit 2
27
+ fi
28
+
29
+ # 2. curl/wget piped to execution
30
+ if echo "$COMMAND" | grep -qE '(curl|wget)\s.*\|\s*(bash|sh|python|node|perl)'; then
31
+ echo "BLOCKED: Remote code execution pattern detected." >&2
32
+ echo "Download the file first, review it, then execute separately." >&2
33
+ exit 2
34
+ fi
35
+
36
+ # 3. eval with variable expansion
37
+ if echo "$COMMAND" | grep -qE '\beval\s'; then
38
+ echo "BLOCKED: eval detected. Use direct commands instead." >&2
39
+ exit 2
40
+ fi
41
+
42
+ # 4. Nested command substitution in dangerous positions
43
+ if echo "$COMMAND" | grep -qE '(rm|mv|cp|chmod|chown)\s.*\$\('; then
44
+ echo "BLOCKED: Command substitution in destructive command." >&2
45
+ echo "Expand the subcommand first, verify the result, then run." >&2
46
+ exit 2
47
+ fi
48
+
49
+ # 5. Globbed rm (rm *.* or rm -rf *)
50
+ if echo "$COMMAND" | grep -qE 'rm\s+.*\*'; then
51
+ echo "BLOCKED: Wildcard deletion detected." >&2
52
+ echo "List the files first (ls), verify, then delete specific files." >&2
53
+ exit 2
54
+ fi
55
+
56
+ exit 0
@@ -0,0 +1,68 @@
1
+ #!/bin/bash
2
+ # bash-secret-output-detector.sh — Warn when Bash output contains secrets
3
+ #
4
+ # Solves: Bash command output containing API keys, tokens, or credentials
5
+ # enters the LLM context window and gets sent to the API provider
6
+ # (#39882). PostToolUse hook that scans stdout for secret patterns.
7
+ #
8
+ # How it works: PostToolUse hook on Bash that checks command stdout for
9
+ # patterns matching API keys, tokens, passwords, and connection strings.
10
+ # Emits a systemMessage warning the model to ignore/not repeat secrets.
11
+ #
12
+ # TRIGGER: PostToolUse
13
+ # MATCHER: "Bash"
14
+ #
15
+ # Usage:
16
+ # {
17
+ # "hooks": {
18
+ # "PostToolUse": [{
19
+ # "matcher": "Bash",
20
+ # "hooks": [{ "type": "command", "command": "~/.claude/hooks/bash-secret-output-detector.sh" }]
21
+ # }]
22
+ # }
23
+ # }
24
+
25
+ INPUT=$(cat)
26
+ STDOUT=$(echo "$INPUT" | jq -r '.tool_result.stdout // empty' 2>/dev/null)
27
+
28
+ [ -z "$STDOUT" ] && exit 0
29
+
30
+ # Secret patterns (high-confidence, low false-positive)
31
+ FOUND=""
32
+
33
+ # AWS keys
34
+ if echo "$STDOUT" | grep -qE 'AKIA[0-9A-Z]{16}'; then
35
+ FOUND="${FOUND}AWS access key, "
36
+ fi
37
+
38
+ # Generic API keys/tokens (long hex/base64 strings after key= or token=)
39
+ if echo "$STDOUT" | grep -qiE '(api[_-]?key|api[_-]?secret|auth[_-]?token|access[_-]?token|secret[_-]?key)\s*[:=]\s*\S{20,}'; then
40
+ FOUND="${FOUND}API key/token, "
41
+ fi
42
+
43
+ # Connection strings with passwords
44
+ if echo "$STDOUT" | grep -qiE '(mysql|postgres|mongodb|redis)://[^:]+:[^@]+@'; then
45
+ FOUND="${FOUND}database connection string, "
46
+ fi
47
+
48
+ # Private keys
49
+ if echo "$STDOUT" | grep -qE '-----BEGIN (RSA |EC |OPENSSH )?PRIVATE KEY-----'; then
50
+ FOUND="${FOUND}private key, "
51
+ fi
52
+
53
+ # JWT tokens
54
+ if echo "$STDOUT" | grep -qE 'eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]+'; then
55
+ FOUND="${FOUND}JWT token, "
56
+ fi
57
+
58
+ # GitHub/GitLab tokens
59
+ if echo "$STDOUT" | grep -qE '(ghp|gho|ghs|ghr|glpat)_[A-Za-z0-9]{30,}'; then
60
+ FOUND="${FOUND}GitHub/GitLab token, "
61
+ fi
62
+
63
+ if [ -n "$FOUND" ]; then
64
+ FOUND="${FOUND%, }"
65
+ echo "{\"systemMessage\":\"⚠ SECRET DETECTED in command output: ${FOUND}. Do NOT repeat, log, or include these values in any output. They are now in context but should be treated as redacted.\"}"
66
+ fi
67
+
68
+ exit 0
@@ -22,6 +22,8 @@
22
22
  # }
23
23
  # }
24
24
  # ================================================================
25
+ #
26
+ # TRIGGER: PreToolUse MATCHER: "Bash"
25
27
 
26
28
  INPUT=$(cat)
27
29
  COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
@@ -0,0 +1,59 @@
1
+ #!/bin/bash
2
+ # bashrc-safety-check.sh — Warn about .bashrc lines that hang in non-interactive shells
3
+ #
4
+ # Solves: Agent-spawned bash shells source user .bashrc/.bash_profile,
5
+ # causing hangs or process cascades when completion scripts or
6
+ # slow init commands run in non-interactive shells (#40354).
7
+ #
8
+ # How it works: SessionStart hook scans .bashrc for known-dangerous patterns
9
+ # (completion scripts, nvm, conda, pyenv) and warns the user to add an
10
+ # interactive-shell guard.
11
+ #
12
+ # TRIGGER: SessionStart
13
+ # MATCHER: ""
14
+ #
15
+ # Usage:
16
+ # {
17
+ # "hooks": {
18
+ # "SessionStart": [{
19
+ # "hooks": [{ "type": "command", "command": "~/.claude/hooks/bashrc-safety-check.sh" }]
20
+ # }]
21
+ # }
22
+ # }
23
+
24
+ BASHRC="$HOME/.bashrc"
25
+ [ ! -f "$BASHRC" ] && exit 0
26
+
27
+ # Check if .bashrc already has a non-interactive guard at the top
28
+ if head -10 "$BASHRC" | grep -qE 'case \$- in|\[\[ \$- ==.*i'; then
29
+ # Already guarded — skip check
30
+ exit 0
31
+ fi
32
+
33
+ # Patterns known to hang/crash in non-interactive agent shells
34
+ DANGEROUS_PATTERNS=(
35
+ 'source.*<.*completion' # Angular CLI, kubectl, etc.
36
+ 'eval.*\$.*completion' # Completion eval patterns
37
+ 'nvm\.sh' # nvm can be slow on init
38
+ 'conda.*activate' # conda activation in non-interactive
39
+ 'pyenv.*init' # pyenv init sometimes hangs
40
+ 'rbenv.*init' # rbenv init
41
+ 'rvm.*scripts' # rvm scripts
42
+ )
43
+
44
+ WARNINGS=""
45
+ for pattern in "${DANGEROUS_PATTERNS[@]}"; do
46
+ MATCH=$(grep -n "$pattern" "$BASHRC" 2>/dev/null | head -3)
47
+ if [ -n "$MATCH" ]; then
48
+ WARNINGS="${WARNINGS}\n Line: $MATCH"
49
+ fi
50
+ done
51
+
52
+ if [ -n "$WARNINGS" ]; then
53
+ echo "⚠ WARNING: .bashrc contains commands that may hang in agent subshells:" >&2
54
+ echo -e "$WARNINGS" >&2
55
+ echo "" >&2
56
+ echo "Add this as the FIRST line of .bashrc to fix:" >&2
57
+ echo ' case $- in *i*) ;; *) return;; esac' >&2
58
+ fi
59
+ exit 0