cc-safe-setup 29.7.0 → 30.0.4
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.
- package/.claude-plugin/marketplace.json +72 -19
- package/.claude-plugin/plugin.json +1 -1
- package/CONTRIBUTING.md +7 -2
- package/COOKBOOK.md +50 -46
- package/LICENSE +21 -0
- package/MIGRATION.md +8 -8
- package/README.md +419 -512
- package/SAFETY_CHECKLIST.md +15 -7
- package/SERVICES.md +194 -0
- package/SETTINGS_REFERENCE.md +236 -17
- package/SKILL.md +5 -5
- package/TROUBLESHOOTING.md +35 -14
- package/action.yml +12 -4
- package/audit/README.md +84 -0
- package/audit/audit-checklist.md +152 -0
- package/audit/boundary-selftest.sh +85 -0
- package/audit/boundary.sh +123 -0
- package/audit/count-hooks.py +42 -0
- package/audit/find-dead-hooks.sh +82 -0
- package/audit/find-unfirable-rules.sh +142 -0
- package/audit/fire.sh +97 -0
- package/audit/selftest.sh +42 -0
- package/audit/unfirable-selftest.sh +81 -0
- package/audit-web/index.html +9 -9
- package/examples/README.md +54 -17
- package/examples/account-billing-log.sh +98 -0
- package/examples/account-routing-preflight.sh +123 -0
- package/examples/agent-sdk-credit-pool-monitor.sh +145 -0
- package/examples/agent-view-quota-decrement.sh +32 -0
- package/examples/agent-view-quota-warn.sh +94 -0
- package/examples/agents-md-edit-drift-warner.sh +223 -0
- package/examples/agents-md-loader.sh +160 -0
- package/examples/agents-md-sync-checker.sh +102 -0
- package/examples/ai-slop-punctuation-arrest.sh +210 -0
- package/examples/allowlist.sh +70 -10
- package/examples/always-allow-pattern-suggester.sh +125 -0
- package/examples/ansible-vault-guard.sh +2 -1
- package/examples/anthropic-base-url-guard.sh +76 -0
- package/examples/api-busyloop-guard.sh +123 -0
- package/examples/api-endpoint-guard.sh +12 -0
- package/examples/api-key-in-url-guard.sh +17 -1
- package/examples/api-rate-limit-guard.sh +36 -1
- package/examples/api-rate-limit-tracker.sh +12 -0
- package/examples/articulated-scope-capture.sh +101 -0
- package/examples/askuserquestion-autonomy-gate.sh +102 -0
- package/examples/attachment-traversal-guard.sh +118 -0
- package/examples/aup-block-pattern-logger.sh +161 -0
- package/examples/aup-false-positive-helper.sh +124 -0
- package/examples/aup-large-tool-output-warner.sh +282 -0
- package/examples/aup-retry-loop-guard.sh +229 -0
- package/examples/auth-expiry-reminder.sh +157 -0
- package/examples/auth-macos-sleep-detector.sh +185 -0
- package/examples/auth-path-detector.sh +171 -0
- package/examples/auth-status-checker.sh +157 -0
- package/examples/authorized-reconfirmation-detector.sh +195 -0
- package/examples/auto-approve-build.sh +39 -0
- package/examples/auto-approve-cargo.sh +31 -1
- package/examples/auto-approve-docker.sh +35 -0
- package/examples/auto-approve-git-read.sh +37 -14
- package/examples/auto-approve-go.sh +30 -1
- package/examples/auto-approve-gradle.sh +29 -1
- package/examples/auto-approve-make.sh +29 -1
- package/examples/auto-approve-maven.sh +29 -1
- package/examples/auto-approve-python.sh +41 -1
- package/examples/auto-approve-readonly-tools.sh +1 -0
- package/examples/auto-approve-readonly.sh +110 -33
- package/examples/auto-approve-ssh.sh +30 -1
- package/examples/auto-approve-test.sh +44 -0
- package/examples/auto-checkpoint.sh +1 -1
- package/examples/auto-compact-prep.sh +0 -0
- package/examples/auto-git-checkpoint.sh +0 -0
- package/examples/auto-mode-safe-commands.sh +53 -1
- package/examples/auto-mode-safety-enforcer.sh +151 -4
- package/examples/auto-push-session-branch.sh +22 -0
- package/examples/aws-production-guard.sh +13 -1
- package/examples/aws-region-guard.sh +1 -1
- package/examples/background-cost-launch-guard.sh +82 -0
- package/examples/background-task-guard.sh +12 -0
- package/examples/backup-before-refactor.sh +0 -0
- package/examples/banned-command-guard.sh +12 -0
- package/examples/bash-allowlist-secondary-check.sh +157 -0
- package/examples/bash-domain-allowlist.sh +12 -0
- package/examples/bash-fanout-bounded-rewriter.sh +191 -0
- package/examples/bash-heuristic-approver.sh +112 -10
- package/examples/bash-project-fence.sh +194 -0
- package/examples/bash-safety-auto-deny.sh +12 -0
- package/examples/bash-secret-output-detector.sh +44 -3
- package/examples/bash-trace-guard.sh +12 -0
- package/examples/bashrc-safety-check.sh +0 -0
- package/examples/bg-permission-prompt-warner.sh +182 -0
- package/examples/bg-task-cooldown-guard.sh +12 -0
- package/examples/binary-read-detector.sh +135 -0
- package/examples/binary-upload-guard.sh +12 -0
- package/examples/block-database-wipe.sh +35 -10
- package/examples/branch-name-check.sh +8 -3
- package/examples/branch-naming-convention.sh +0 -0
- package/examples/broad-find-guard.sh +12 -0
- package/examples/broad-prefix-session-trap-warner.sh +106 -0
- package/examples/bulk-file-delete-guard.sh +45 -0
- package/examples/bypass-mode-effective-verifier.sh +203 -0
- package/examples/cache-creation-drift-detector.sh +120 -0
- package/examples/cache-residue-detector.sh +195 -0
- package/examples/cache-tier-logger.sh +70 -0
- package/examples/cache-ttl-eviction-detector.sh +149 -0
- package/examples/cargo-publish-guard.sh +14 -1
- package/examples/case-insensitive-path-guard.sh +21 -2
- package/examples/case-sensitive-guard.sh +23 -2
- package/examples/cch-cache-guard.sh +0 -0
- package/examples/cch-sentinel-precommit-guard.sh +47 -0
- package/examples/check-abort-controller.sh +1 -1
- package/examples/check-accessibility.sh +0 -0
- package/examples/check-aria-labels.sh +0 -0
- package/examples/check-before-act-enforcer.sh +12 -0
- package/examples/check-charset-meta.sh +0 -0
- package/examples/check-cookie-flags.sh +0 -0
- package/examples/check-cors-config.sh +0 -0
- package/examples/check-csp-headers.sh +0 -0
- package/examples/check-csrf-protection.sh +0 -0
- package/examples/check-debounce.sh +1 -1
- package/examples/check-dependency-age.sh +0 -0
- package/examples/check-dependency-license.sh +0 -0
- package/examples/check-dockerfile-best-practice.sh +0 -0
- package/examples/check-error-boundaries.sh +0 -0
- package/examples/check-error-class.sh +1 -1
- package/examples/check-error-handling.sh +0 -0
- package/examples/check-error-logging.sh +1 -1
- package/examples/check-error-message.sh +0 -0
- package/examples/check-error-stack.sh +0 -0
- package/examples/check-favicon.sh +0 -0
- package/examples/check-git-hooks-compat.sh +0 -0
- package/examples/check-gitattributes.sh +0 -0
- package/examples/check-https-redirect.sh +0 -0
- package/examples/check-input-validation.sh +0 -0
- package/examples/check-lang-attribute.sh +0 -0
- package/examples/check-npm-scripts-exist.sh +0 -0
- package/examples/check-package-size.sh +0 -0
- package/examples/check-port-availability.sh +0 -0
- package/examples/check-promise-all.sh +1 -1
- package/examples/check-rate-limiting.sh +0 -0
- package/examples/check-return-types.sh +0 -0
- package/examples/check-semantic-versioning.sh +0 -0
- package/examples/check-suspense-fallback.sh +1 -1
- package/examples/check-test-exists.sh +0 -0
- package/examples/check-test-naming.sh +0 -0
- package/examples/check-timeout-cleanup.sh +1 -1
- package/examples/check-tls-version.sh +0 -0
- package/examples/check-unsubscribe.sh +1 -1
- package/examples/check-viewport-meta.sh +0 -0
- package/examples/check-worker-terminate.sh +1 -1
- package/examples/checkpoint-tamper-guard.sh +12 -0
- package/examples/chmod-guard.sh +12 -0
- package/examples/chown-guard.sh +24 -0
- package/examples/ci-workflow-guard.sh +6 -1
- package/examples/claim-verify-detector.sh +109 -0
- package/examples/claim-vs-caveat-checker.sh +77 -0
- package/examples/classifier-fallback-allow.sh +114 -40
- package/examples/claude-cache-gc.sh +1 -0
- package/examples/claude-code-version-pin-advisor.sh +183 -0
- package/examples/claude-md-reinjector.sh +129 -0
- package/examples/claude-md-size-monitor.sh +66 -0
- package/examples/claude-update-budget-guard.sh +123 -0
- package/examples/claude-update-smart.sh +113 -0
- package/examples/claudeignore-enforce-guard.sh +12 -0
- package/examples/claudemd-enforcer.sh +0 -0
- package/examples/claudemd-tool-prohibition.sh +128 -0
- package/examples/clear-command-confirm-guard.sh +32 -15
- package/examples/cli-config-pinning-detector.sh +162 -0
- package/examples/cliff-countdown-advisor.sh +96 -0
- package/examples/clipboard-secret-guard.sh +12 -0
- package/examples/closure-word-verify-gate.sh +150 -0
- package/examples/cloud-cli-guard.sh +39 -2
- package/examples/commit-all-scope-guard.sh +44 -0
- package/examples/commit-message-check.sh +1 -1
- package/examples/commit-message-quality.sh +6 -1
- package/examples/commitment-carry-forward-arrest.sh +361 -0
- package/examples/compact-alert-notification.sh +0 -0
- package/examples/compact-circuit-breaker.sh +72 -0
- package/examples/compact-dispatch-watchdog.sh +149 -0
- package/examples/completion-claim-without-verification-detector.sh +207 -0
- package/examples/composer-guard.sh +12 -0
- package/examples/compound-bash-permission-resolver.sh +156 -0
- package/examples/compound-command-allow.sh +1 -1
- package/examples/compound-command-deny-enforcer.sh +183 -0
- package/examples/compound-inject-guard.sh +12 -0
- package/examples/concurrent-edit-lock.sh +12 -0
- package/examples/conflict-marker-guard.sh +12 -0
- package/examples/consecutive-error-breaker.sh +0 -0
- package/examples/console-log-count.sh +1 -0
- package/examples/context-compact-advisor.sh +29 -2
- package/examples/context-length-budget.sh +69 -0
- package/examples/context-threshold-alert.sh +12 -0
- package/examples/context-usage-drift-alert.sh +41 -13
- package/examples/conversation-history-guard.sh +12 -0
- package/examples/core-file-protect-guard.sh +12 -0
- package/examples/cors-star-warn.sh +0 -0
- package/examples/cost-incident-self-audit.sh +162 -0
- package/examples/cowork-claude-md-load-checker.sh +100 -0
- package/examples/cowork-fuse-staleness-watcher.sh +140 -0
- package/examples/cowork-hook-absence-warner.sh +167 -0
- package/examples/cowork-model-picker-advisor.sh +115 -0
- package/examples/credential-exfil-guard.sh +65 -4
- package/examples/credential-file-cat-guard.sh +17 -1
- package/examples/cron-create-receipt.sh +112 -0
- package/examples/cron-modification-guard.sh +12 -0
- package/examples/cross-product-mcp-spawn-detector.sh +178 -0
- package/examples/cwd-project-boundary-guard.sh +0 -0
- package/examples/daemon-zombie-worker-surfacer.sh +118 -0
- package/examples/daily-cost-guard.sh +164 -0
- package/examples/daily-usage-tracker.sh +0 -0
- package/examples/dangerous-pip-flag-guard.sh +12 -0
- package/examples/db-connect-guard.sh +13 -1
- package/examples/denied-action-retry-guard.sh +12 -0
- package/examples/deny-bypass-detector.sh +12 -0
- package/examples/deny-rule-integrity-verifier.sh +181 -0
- package/examples/dependency-install-guard.sh +12 -0
- package/examples/deploy-guard.sh +14 -2
- package/examples/deploy-path-verify-guard.sh +12 -0
- package/examples/deployment-readback-gate.sh +135 -0
- package/examples/deployment-readback-gh-adapter.sh +247 -0
- package/examples/deployment-verify-guard.sh +25 -2
- package/examples/destructive-db-script-write-guard.sh +166 -0
- package/examples/destructive-migration-write-guard.sh +163 -0
- package/examples/diff-size-guard.sh +12 -0
- package/examples/disabled-feature-toggle-advisor.sh +88 -0
- package/examples/disk-partition-guard.sh +12 -0
- package/examples/dispatch-allowlist-preflight.sh +301 -0
- package/examples/dispatch-liveness-watchdog.sh +216 -0
- package/examples/dispatch-receipt.sh +174 -0
- package/examples/django-migrate-guard.sh +12 -0
- package/examples/dns-config-guard.sh +12 -0
- package/examples/docker-dangerous-guard.sh +12 -0
- package/examples/docker-volume-guard.sh +0 -0
- package/examples/dockerfile-latest-guard.sh +1 -0
- package/examples/dotenv-anthropic-key-billing-guard.sh +99 -0
- package/examples/dotenv-commit-guard.sh +12 -0
- package/examples/dotenv-read-guard.sh +12 -0
- package/examples/dotfile-protection-guard.sh +12 -0
- package/examples/dotnet-build-on-edit.sh +1 -1
- package/examples/drizzle-migrate-guard.sh +27 -2
- package/examples/echo-probe-spam-detector.sh +176 -0
- package/examples/edit-counter-test-gate.sh +12 -0
- package/examples/edit-error-counter.sh +1 -1
- package/examples/edit-guard.sh +12 -0
- package/examples/edit-old-string-validator.sh +12 -0
- package/examples/edit-quote-ambiguity-guard.sh +97 -0
- package/examples/edit-retry-loop-guard.sh +0 -0
- package/examples/edit-verify.sh +0 -0
- package/examples/env-inline-secret-guard.sh +14 -2
- package/examples/env-naming-convention.sh +0 -0
- package/examples/env-prod-guard.sh +0 -0
- package/examples/env-required-check.sh +0 -0
- package/examples/env-source-guard.sh +12 -0
- package/examples/env-var-check.sh +24 -1
- package/examples/ephemeral-container-detector.sh +147 -0
- package/examples/error-memory-guard.sh +12 -0
- package/examples/evidence-claim-gate.sh +187 -0
- package/examples/exploration-budget-guard.sh +89 -0
- package/examples/expo-eject-guard.sh +13 -0
- package/examples/extended-thinking-loop-guard.sh +139 -0
- package/examples/extended-thinking-resume-warning.sh +119 -0
- package/examples/extended-thinking-tool-use-mismatch-detector.sh +212 -0
- package/examples/fabricated-command-detector.sh +145 -0
- package/examples/false-disk-full-guard.sh +63 -0
- package/examples/feature-deprecation-detector.sh +109 -0
- package/examples/file-change-tracker.sh +1 -1
- package/examples/file-change-undo-tracker.sh +0 -0
- package/examples/file-edit-backup.sh +63 -14
- package/examples/file-reference-check.sh +0 -0
- package/examples/file-size-limit.sh +12 -0
- package/examples/financial-operation-guard.sh +12 -0
- package/examples/firewall-guard.sh +12 -0
- package/examples/fish-shell-wrapper.sh +125 -7
- package/examples/five-hundred-milestone.sh +1 -0
- package/examples/flask-static-route-guard.sh +89 -0
- package/examples/forbidden-response-phrase-detector.sh +161 -0
- package/examples/gem-push-guard.sh +13 -0
- package/examples/gh-cli-destructive-guard.sh +13 -1
- package/examples/git-checkout-safety-guard.sh +12 -0
- package/examples/git-checkout-uncommitted-guard.sh +12 -0
- package/examples/git-config-guard.sh +12 -0
- package/examples/git-crypt-worktree-guard.sh +12 -0
- package/examples/git-filter-repo-guard.sh +56 -0
- package/examples/git-history-rewrite-guard.sh +12 -0
- package/examples/git-hook-bypass-guard.sh +0 -0
- package/examples/git-maintenance-guard.sh +83 -0
- package/examples/git-merge-conflict-prevent.sh +0 -0
- package/examples/git-message-length-check.sh +0 -0
- package/examples/git-message-length.sh +0 -0
- package/examples/git-operations-require-approval.sh +68 -14
- package/examples/git-pack-temp-cleanup-guard.sh +102 -0
- package/examples/git-push-blast-radius-guard.sh +218 -0
- package/examples/git-remote-guard.sh +24 -3
- package/examples/git-rm-orphan-wipe-guard.sh +85 -0
- package/examples/git-stash-before-checkout.sh +12 -0
- package/examples/git-stash-before-danger.sh +0 -0
- package/examples/git-submodule-guard.sh +69 -2
- package/examples/git-tag-guard.sh +12 -0
- package/examples/github-actions-secret-guard.sh +0 -0
- package/examples/gitignore-check.sh +0 -0
- package/examples/gitops-drift-guard.sh +12 -0
- package/examples/go-mod-tidy-warn.sh +1 -0
- package/examples/go-vet-after-edit.sh +12 -0
- package/examples/goal-iteration-limit-warner.sh +152 -0
- package/examples/grep-nul-false-negative-guard.sh +30 -0
- package/examples/growthbook-flag-monitor.sh +257 -0
- package/examples/hallucination-url-check.sh +1 -1
- package/examples/halt-signal-detector.sh +135 -0
- package/examples/handoff-on-clear.sh +65 -0
- package/examples/hardcoded-ip-guard.sh +1 -0
- package/examples/headless-empty-result-guard.sh +0 -0
- package/examples/headless-stop-guard.sh +0 -0
- package/examples/helm-install-guard.sh +2 -1
- package/examples/home-critical-bash-guard.sh +17 -1
- package/examples/hook-debug-wrapper.sh +6 -2
- package/examples/hook-permission-fixer.sh +0 -0
- package/examples/hook-self-disable-detector.sh +99 -0
- package/examples/hook-stdout-sanitizer.sh +6 -2
- package/examples/hook-tamper-guard.sh +12 -0
- package/examples/idle-session-cost-alert.sh +0 -0
- package/examples/image-dimension-guard.sh +109 -0
- package/examples/image-file-validator.sh +0 -0
- package/examples/iteration-quality-degradation-detector.sh +170 -0
- package/examples/java-compile-on-edit.sh +1 -1
- package/examples/json-syntax-check.sh +0 -0
- package/examples/k8s-production-guard.sh +13 -1
- package/examples/kill-process-guard.sh +12 -0
- package/examples/kubernetes-guard.sh +13 -1
- package/examples/laravel-artisan-guard.sh +13 -0
- package/examples/large-file-guard.sh +1 -1
- package/examples/log-level-guard.sh +0 -0
- package/examples/log-truncation-guard.sh +12 -0
- package/examples/long-session-malformed-tool-call-detector.sh +183 -0
- package/examples/loop-detector.sh +12 -0
- package/examples/magic-number-warn.sh +1 -0
- package/examples/main-branch-warn.sh +12 -0
- package/examples/markdown-link-check.sh +0 -0
- package/examples/max-concurrent-agents.sh +12 -0
- package/examples/max-edit-size-guard.sh +13 -0
- package/examples/max-file-count-guard.sh +0 -0
- package/examples/max-file-delete-count.sh +0 -0
- package/examples/max-function-length.sh +1 -0
- package/examples/max-import-count.sh +0 -0
- package/examples/max-subagent-count.sh +0 -0
- package/examples/mcp-config-freeze.sh +12 -0
- package/examples/mcp-config-poisoning-audit.sh +150 -0
- package/examples/mcp-data-boundary.sh +1 -1
- package/examples/mcp-misdiagnosis-arrest.sh +209 -0
- package/examples/mcp-orphan-leak-warner.sh +49 -0
- package/examples/mcp-permissions-ask-warner.sh +151 -0
- package/examples/mcp-routine-approval-detector.sh +154 -0
- package/examples/mcp-server-allowlist.sh +12 -0
- package/examples/mcp-server-guard.sh +12 -0
- package/examples/mcp-startup-bloat-detector.sh +87 -0
- package/examples/mcp-stdio-compatibility-test.sh +153 -0
- package/examples/mcp-tool-audit-log.sh +0 -0
- package/examples/mcp-tool-guard.sh +101 -1
- package/examples/mcp-warmup-wait.sh +0 -0
- package/examples/memory-chain-audit.sh +56 -0
- package/examples/memory-orphan-detector.sh +188 -0
- package/examples/memory-write-guard.sh +99 -17
- package/examples/migration-verify-guard.sh +12 -0
- package/examples/model-swap-suggester.sh +177 -0
- package/examples/model-version-alert.sh +5 -1
- package/examples/model-version-lock.sh +63 -0
- package/examples/move-delete-sequence-guard.sh +33 -2
- package/examples/multi-file-plan-routing-gate.sh +192 -0
- package/examples/multi-vendor-concurrent-warner.sh +108 -0
- package/examples/multi-window-auth-drift-detector.sh +183 -0
- package/examples/multiline-command-approver.sh +161 -23
- package/examples/nested-background-agent-guard.sh +109 -0
- package/examples/nested-spawn-inflight-guard.sh +178 -0
- package/examples/network-exfil-guard.sh +12 -0
- package/examples/network-guard.sh +12 -0
- package/examples/network-interface-guard.sh +12 -0
- package/examples/nextjs-env-guard.sh +1 -1
- package/examples/no-absolute-import.sh +0 -0
- package/examples/no-alert-confirm-prompt.sh +0 -0
- package/examples/no-anonymous-default-export.sh +0 -0
- package/examples/no-any-type.sh +0 -0
- package/examples/no-any-typescript.sh +1 -0
- package/examples/no-ask-human.sh +12 -0
- package/examples/no-assignment-in-condition.sh +0 -0
- package/examples/no-base64-exfil.sh +12 -0
- package/examples/no-callback-hell.sh +0 -0
- package/examples/no-circular-dependency.sh +0 -0
- package/examples/no-cleartext-storage.sh +0 -0
- package/examples/no-commented-code.sh +0 -0
- package/examples/no-commit-fixup.sh +0 -0
- package/examples/no-console-assert.sh +0 -0
- package/examples/no-console-error-swallow.sh +0 -0
- package/examples/no-console-in-prod.sh +0 -0
- package/examples/no-console-log-commit.sh +12 -0
- package/examples/no-console-log.sh +0 -0
- package/examples/no-console-time.sh +0 -0
- package/examples/no-cors-wildcard.sh +4 -1
- package/examples/no-curl-upload.sh +0 -0
- package/examples/no-dangerouslySetInnerHTML.sh +0 -0
- package/examples/no-dangling-await.sh +1 -0
- package/examples/no-debug-commit.sh +12 -0
- package/examples/no-debug-in-commit.sh +0 -0
- package/examples/no-deep-nesting.sh +0 -0
- package/examples/no-deep-relative-import.sh +1 -0
- package/examples/no-default-credentials.sh +0 -0
- package/examples/no-deploy-friday.sh +13 -1
- package/examples/no-disabled-test.sh +0 -0
- package/examples/no-document-write.sh +0 -0
- package/examples/no-empty-function.sh +0 -0
- package/examples/no-eval-in-template.sh +0 -0
- package/examples/no-eval-template.sh +3 -1
- package/examples/no-eval.sh +0 -0
- package/examples/no-exec-user-input.sh +0 -0
- package/examples/no-fixme-ship.sh +12 -0
- package/examples/no-floating-promises.sh +0 -0
- package/examples/no-force-flag.sh +22 -5
- package/examples/no-force-install.sh +0 -0
- package/examples/no-git-amend.sh +12 -0
- package/examples/no-git-rebase-public.sh +0 -0
- package/examples/no-global-install.sh +12 -0
- package/examples/no-global-state.sh +0 -0
- package/examples/no-hardcoded-port.sh +1 -0
- package/examples/no-hardcoded-url.sh +0 -0
- package/examples/no-helmet-missing.sh +0 -0
- package/examples/no-http-url.sh +1 -0
- package/examples/no-http-without-https.sh +0 -0
- package/examples/no-inline-style.sh +0 -0
- package/examples/no-inline-styles.sh +1 -0
- package/examples/no-innerhtml.sh +0 -0
- package/examples/no-install-global.sh +12 -0
- package/examples/no-jwt-in-url.sh +0 -0
- package/examples/no-large-commit.sh +0 -0
- package/examples/no-localhost-expose.sh +0 -0
- package/examples/no-magic-number.sh +0 -0
- package/examples/no-md5-sha1.sh +0 -0
- package/examples/no-mixed-line-endings.sh +8 -1
- package/examples/no-mutation-in-reducer.sh +0 -0
- package/examples/no-nested-ternary.sh +0 -0
- package/examples/no-network-exfil.sh +0 -0
- package/examples/no-open-redirect.sh +0 -0
- package/examples/no-output-truncation.sh +12 -0
- package/examples/no-package-downgrade.sh +0 -0
- package/examples/no-package-lock-edit.sh +12 -0
- package/examples/no-path-join-user-input.sh +0 -0
- package/examples/no-port-bind.sh +0 -0
- package/examples/no-process-exit.sh +0 -0
- package/examples/no-prototype-pollution.sh +0 -0
- package/examples/no-push-without-ci.sh +0 -0
- package/examples/no-push-without-tests.sh +12 -0
- package/examples/no-raw-password-in-url.sh +0 -0
- package/examples/no-root-user-docker.sh +1 -0
- package/examples/no-root-write.sh +12 -0
- package/examples/no-secrets-in-args.sh +4 -1
- package/examples/no-secrets-in-logs.sh +0 -0
- package/examples/no-sensitive-log.sh +0 -0
- package/examples/no-sleep-in-hooks.sh +0 -0
- package/examples/no-star-import-python.sh +1 -0
- package/examples/no-string-concat-sql.sh +0 -0
- package/examples/no-sudo-guard.sh +12 -0
- package/examples/no-sync-fs.sh +0 -0
- package/examples/no-todo-in-merge.sh +0 -0
- package/examples/no-todo-in-production.sh +1 -0
- package/examples/no-todo-without-issue.sh +0 -0
- package/examples/no-unused-import.sh +0 -0
- package/examples/no-var-keyword.sh +0 -0
- package/examples/no-verify-blocker.sh +12 -0
- package/examples/no-wget-piped-bash.sh +12 -0
- package/examples/no-wildcard-cors.sh +0 -0
- package/examples/no-wildcard-delete.sh +0 -0
- package/examples/no-wildcard-import.sh +0 -0
- package/examples/no-with-statement.sh +0 -0
- package/examples/no-write-outside-src.sh +0 -0
- package/examples/no-xml-external-entity.sh +0 -0
- package/examples/non-english-quality-warner.sh +156 -0
- package/examples/notify-waiting.sh +1 -1
- package/examples/npm-audit-warn.sh +0 -0
- package/examples/npm-global-install-guard.sh +12 -0
- package/examples/npm-publish-guard.sh +12 -0
- package/examples/npm-script-injection.sh +0 -0
- package/examples/npm-supply-chain-guard.sh +0 -0
- package/examples/nuxt-config-guard.sh +1 -0
- package/examples/oauth-refresh-monitor.sh +210 -0
- package/examples/opus-degradation-tracker.sh +187 -0
- package/examples/opus48-routine-task-warning.sh +196 -0
- package/examples/opus48-thinking-wedge-advisor.sh +143 -0
- package/examples/output-credential-scan.sh +1 -1
- package/examples/output-secret-mask.sh +31 -9
- package/examples/output-token-spike-detector.sh +145 -0
- package/examples/package-json-guard.sh +12 -0
- package/examples/package-lock-frozen.sh +12 -0
- package/examples/parallel-batch-size-limiter.sh +121 -0
- package/examples/parallel-cascade-detector.sh +116 -0
- package/examples/partial-view-claim-arrest.sh +174 -0
- package/examples/path-deny-bash-guard.sh +12 -0
- package/examples/path-traversal-guard.sh +12 -0
- package/examples/per-prompt-token-cap.sh +124 -0
- package/examples/permission-audit-log.sh +1 -1
- package/examples/permission-denial-enforcer.sh +12 -0
- package/examples/permission-entry-validator.sh +0 -0
- package/examples/persisted-1m-model-advisor.sh +88 -0
- package/examples/php-lint-on-edit.sh +1 -1
- package/examples/pii-upload-guard.sh +12 -0
- package/examples/pip-publish-guard.sh +13 -0
- package/examples/pip-requirements-guard.sh +12 -0
- package/examples/pip-venv-required.sh +12 -0
- package/examples/plan-mode-edit-guard.sh +12 -0
- package/examples/plan-mode-enforcer.sh +12 -0
- package/examples/plan-mode-strict-guard.sh +12 -0
- package/examples/plugin-hooks-json-bloat-detector.sh +169 -0
- package/examples/plugin-process-cleanup.sh +0 -0
- package/examples/polyglot-rm-guard.sh +12 -0
- package/examples/post-compact-safety.sh +12 -0
- package/examples/post-edit-disk-verify.sh +152 -0
- package/examples/powershell-remove-item-guard.sh +85 -0
- package/examples/pr-description-check.sh +0 -0
- package/examples/pr-duplicate-guard.sh +13 -0
- package/examples/pre-bash-sed-line-ending-windows.sh +87 -0
- package/examples/pre-compact-knowledge-save.sh +0 -0
- package/examples/pre-compact-transcript-backup.sh +0 -0
- package/examples/pre-execution-claim-detector.sh +179 -0
- package/examples/prefer-builtin-tools.sh +10 -1
- package/examples/prefer-const.sh +0 -0
- package/examples/prefer-dedicated-tools.sh +12 -0
- package/examples/prefer-optional-chaining.sh +0 -0
- package/examples/prisma-migrate-guard.sh +24 -7
- package/examples/production-port-kill-guard.sh +12 -0
- package/examples/prompt-injection-guard.sh +2 -1
- package/examples/prompt-usage-logger.sh +0 -0
- package/examples/protect-claudemd.sh +12 -0
- package/examples/protect-dotfiles.sh +12 -0
- package/examples/proxy-capture-suggester.sh +159 -0
- package/examples/public-artefact-socratic-narrowing.sh +232 -0
- package/examples/public-repo-push-guard.sh +12 -0
- package/examples/push-requires-test-pass-record.sh +0 -0
- package/examples/push-requires-test-pass.sh +12 -0
- package/examples/quota-anomaly-detector.sh +173 -0
- package/examples/quota-reset-audit.sh +58 -0
- package/examples/quoted-flag-approver.sh +99 -10
- package/examples/rails-migration-guard.sh +12 -0
- package/examples/rate-limit-guard.sh +0 -0
- package/examples/read-all-files-enforcer.sh +0 -0
- package/examples/read-budget-guard.sh +12 -0
- package/examples/read-loop-detector.sh +59 -0
- package/examples/read-once-guard.sh +96 -0
- package/examples/read-only-mode.sh +12 -0
- package/examples/readme-exists-check.sh +0 -0
- package/examples/record-read-coverage.sh +73 -0
- package/examples/redirect-fragment-warner.sh +149 -0
- package/examples/redis-flushall-guard.sh +13 -0
- package/examples/redundant-read-blocker.sh +132 -0
- package/examples/refusal-arrest-gate.sh +248 -0
- package/examples/registry-publish-guard.sh +13 -1
- package/examples/remote-control-billing-classifier.sh +135 -0
- package/examples/replace-all-guard.sh +12 -0
- package/examples/repo-visibility-guard.sh +12 -0
- package/examples/reroute-after-block-guard.sh +150 -0
- package/examples/response-budget-guard.sh +0 -0
- package/examples/resume-drift-watcher.sh +57 -0
- package/examples/rg-replace-flag-detector.sh +125 -0
- package/examples/rhetorical-verification-prompt-detector.sh +102 -0
- package/examples/ripgrep-permission-fix.sh +0 -0
- package/examples/rm-safety-net.sh +151 -8
- package/examples/role-tool-guard.sh +12 -0
- package/examples/route-handler-emptiness-gate.sh +324 -0
- package/examples/ruby-lint-on-edit.sh +1 -1
- package/examples/runtime-binary-change-detector.sh +102 -0
- package/examples/same-command-repeat-detector.sh +196 -0
- package/examples/same-correction-arrest.sh +169 -0
- package/examples/sandbox-denywrite-enforcer.sh +78 -0
- package/examples/sandbox-relative-path-audit.sh +83 -25
- package/examples/sandbox-write-verify.sh +12 -0
- package/examples/schema-migration-guard.sh +0 -0
- package/examples/scope-expansion-receipt.sh +178 -0
- package/examples/scope-guard.sh +88 -9
- package/examples/secret-file-read-guard.sh +12 -0
- package/examples/secret-file-write-guard.sh +150 -0
- package/examples/self-modify-bypass-guard.sh +0 -0
- package/examples/sensitive-file-read-guard.sh +23 -3
- package/examples/sensitive-log-guard.sh +1 -0
- package/examples/server-side-prompt-injection-detector.sh +69 -0
- package/examples/session-agent-cost-limiter.sh +12 -0
- package/examples/session-backup-on-start.sh +1 -1
- package/examples/session-cost-alert.sh +12 -0
- package/examples/session-drift-guard.sh +12 -0
- package/examples/session-duration-guard.sh +25 -2
- package/examples/session-end-logger.sh +0 -0
- package/examples/session-health-monitor.sh +0 -0
- package/examples/session-index-repair.sh +1 -1
- package/examples/session-memory-watchdog.sh +1 -0
- package/examples/session-permission-reset-guard.sh +12 -0
- package/examples/session-persistence-verifier.sh +93 -0
- package/examples/session-plugin-pin-watch.sh +68 -0
- package/examples/session-rate-monitor.sh +176 -0
- package/examples/session-resume-env-fix.sh +0 -0
- package/examples/session-start-quota-status.sh +193 -0
- package/examples/session-start-safety-check.sh +55 -3
- package/examples/session-state-saver.sh +0 -0
- package/examples/session-summary-stop.sh +1 -1
- package/examples/session-summary.sh +0 -0
- package/examples/session-token-counter.sh +1 -1
- package/examples/settings-hooks-key-restorer.sh +99 -0
- package/examples/settings-json-health-check.sh +57 -0
- package/examples/settings-json-model-guard.sh +0 -0
- package/examples/settings-regression-tester.sh +188 -0
- package/examples/shell-config-truncation-guard.sh +12 -0
- package/examples/shell-wrapper-guard.sh +12 -0
- package/examples/skill-cumulative-size-detector.sh +104 -0
- package/examples/skill-description-drop-detector.sh +148 -0
- package/examples/skill-gate.sh +0 -0
- package/examples/skill-truncation-detector.sh +154 -0
- package/examples/skills-context-recorder.sh +167 -0
- package/examples/skills-load-verifier.sh +96 -0
- package/examples/skills-settings-validator.sh +139 -0
- package/examples/sonnet-45-deprecation-helper.sh +85 -0
- package/examples/spec-file-scope-guard.sh +12 -0
- package/examples/spring-profile-guard.sh +1 -0
- package/examples/spurious-malformed-notice-detector.sh +247 -0
- package/examples/sql-bulk-delete-warn.sh +88 -0
- package/examples/sql-injection-detect.sh +0 -0
- package/examples/ssh-key-protect.sh +12 -0
- package/examples/staged-secret-scan.sh +22 -1
- package/examples/stale-temp-settings-detector.sh +86 -0
- package/examples/standing-rule-session-surfacer.sh +137 -0
- package/examples/stop-hook-sigterm-wrapper.sh +182 -0
- package/examples/stop-transcript-write-health.sh +64 -0
- package/examples/strict-allowlist.sh +57 -15
- package/examples/strip-coauthored-by.sh +50 -10
- package/examples/subagent-blast-radius-guard.sh +184 -0
- package/examples/subagent-boundary-precheck.sh +126 -0
- package/examples/subagent-budget-guard.sh +12 -0
- package/examples/subagent-claudemd-inject.sh +0 -0
- package/examples/subagent-closure-verify-gate.sh +164 -0
- package/examples/subagent-destructive-git-guard.sh +120 -0
- package/examples/subagent-error-detector.sh +0 -0
- package/examples/subagent-forged-system-reminder-guard.sh +156 -0
- package/examples/subagent-identity-leak-guard.sh +102 -0
- package/examples/subagent-identity-reassertion.sh +51 -0
- package/examples/subagent-inheritance-tester.sh +179 -0
- package/examples/subagent-permission-mode-guard.sh +110 -0
- package/examples/subagent-scope-guard.sh +12 -0
- package/examples/subagent-spawn-verification-enforcer.sh +102 -0
- package/examples/subagent-tool-allowlist-enforcer.sh +101 -0
- package/examples/subagent-tool-call-limiter.sh +87 -15
- package/examples/subcommand-chain-guard.sh +12 -0
- package/examples/subscription-api-billing-warner.sh +160 -0
- package/examples/subscription-bypass-detector.sh +152 -0
- package/examples/svelte-lint-on-edit.sh +1 -0
- package/examples/swift-build-on-edit.sh +1 -1
- package/examples/symlink-guard.sh +27 -2
- package/examples/symlink-protect.sh +1 -0
- package/examples/system-dir-protection-guard.sh +73 -8
- package/examples/system-message-workaround.sh +38 -13
- package/examples/system-package-guard.sh +12 -0
- package/examples/systemd-service-guard.sh +12 -0
- package/examples/task-integrity-guard.sh +12 -0
- package/examples/temp-file-cleanup.sh +1 -1
- package/examples/temporal-suggestion-detector.sh +135 -0
- package/examples/terraform-guard.sh +27 -6
- package/examples/test-after-edit.sh +1 -1
- package/examples/test-before-push.sh +12 -0
- package/examples/test-coverage-reminder.sh +24 -1
- package/examples/thinking-budget-effort-mismatch-detector.sh +149 -0
- package/examples/thinking-stall-detector.sh +61 -0
- package/examples/timezone-guard.sh +0 -0
- package/examples/tmp-output-size-guard.sh +0 -0
- package/examples/todo-check.sh +1 -1
- package/examples/token-budget-guard.sh +12 -0
- package/examples/token-budget-per-task.sh +12 -0
- package/examples/token-usage-tracker.sh +7 -1
- package/examples/tokenizer-ratio-alert-corpus.sh +90 -0
- package/examples/tokenizer-ratio-alert.sh +104 -0
- package/examples/tool-call-rate-limiter.sh +0 -0
- package/examples/tool-result-correlation-checker.sh +167 -0
- package/examples/tool-result-size-guard.sh +132 -0
- package/examples/tool-retry-budget-guard.sh +12 -0
- package/examples/transcript-contamination-detector.sh +138 -0
- package/examples/trustfall-mcp-injection-guard.sh +103 -0
- package/examples/ultrareview-large-diff-advisor.sh +184 -0
- package/examples/unbounded-output-guard.sh +94 -0
- package/examples/uncommitted-changes-stop.sh +1 -0
- package/examples/uncommitted-discard-guard.sh +23 -5
- package/examples/uncommitted-work-guard.sh +12 -0
- package/examples/usage-warn.sh +0 -0
- package/examples/user-account-guard.sh +12 -0
- package/examples/userprompt-submit-receipt.sh +123 -0
- package/examples/variable-expansion-guard.sh +12 -0
- package/examples/verify-after-publish-reminder.sh +93 -0
- package/examples/verify-before-commit.sh +12 -0
- package/examples/version-bump-detector.sh +156 -0
- package/examples/version-regression-warner.sh +144 -0
- package/examples/vue-lint-on-edit.sh +1 -0
- package/examples/warn-cron-cost-trap.sh +173 -0
- package/examples/webfetch-runaway-guard.sh +89 -0
- package/examples/wellness-break-reminder.sh +118 -0
- package/examples/windows-destructive-command-guard.sh +177 -0
- package/examples/windows-path-guard.sh +12 -0
- package/examples/windows-python-stub-detector.sh +63 -0
- package/examples/work-hours-guard.sh +12 -0
- package/examples/working-directory-fence.sh +12 -0
- package/examples/workspace-lease-guard.sh +205 -0
- package/examples/worktree-create-log.sh +1 -0
- package/examples/worktree-delete-guard.sh +12 -0
- package/examples/worktree-edit-boundary-guard.sh +127 -0
- package/examples/worktree-escape-write-guard.sh +114 -0
- package/examples/worktree-hook-linker.sh +0 -0
- package/examples/worktree-hooks-path-fix.sh +111 -0
- package/examples/worktree-parent-write-guard.sh +43 -0
- package/examples/worktree-project-unify.sh +2 -1
- package/examples/worktree-remove-uncommitted-guard.sh +13 -0
- package/examples/worktree-unmerged-guard.sh +7 -1
- package/examples/write-byte-integrity-verifier.sh +190 -0
- package/examples/write-empty-content-guard.sh +67 -0
- package/examples/write-nul-corruption-detector.sh +61 -0
- package/examples/write-overwrite-confirm.sh +160 -14
- package/examples/write-secret-guard.sh +27 -5
- package/examples/write-shrink-guard.sh +12 -0
- package/examples/write-test-ratio.sh +0 -0
- package/examples/wsl-host-disk-space-guard.sh +97 -0
- package/examples/xml-format-leak-detector.sh +266 -0
- package/examples/yaml-syntax-check.sh +12 -0
- package/hooks/hooks.json +6 -6
- package/index.mjs +1699 -183
- package/mission.md +2 -0
- package/package.json +4 -4
- package/plugins/credential-guard/.claude-plugin/plugin.json +9 -7
- package/plugins/git-protection/.claude-plugin/plugin.json +10 -8
- package/plugins/safety-essentials/.claude-plugin/plugin.json +9 -7
- package/plugins/token-guard/.claude-plugin/plugin.json +10 -8
- package/scripts/agents-md-sync-setup.sh +156 -0
- package/scripts/autonomy-blocked-summary.sh +148 -0
- package/scripts/build-search-index.py +43 -0
- package/scripts/build-sitemap.py +119 -0
- package/scripts/cc-doctor.sh +192 -0
- package/scripts/check-hook-event-names.py +127 -0
- package/scripts/check-misfire-instrument.sh +64 -0
- package/scripts/claim-verify-audit.sh +467 -0
- package/scripts/cowork-claudemd-helper.sh +136 -0
- package/scripts/june-15-deprecated-model-scan.sh +111 -0
- package/scripts/measure-heredoc-shapes.sh +67 -0
- package/scripts/measure-literal-match-misfire.sh +110 -0
- package/scripts/probe-scope-guard-branches.sh +48 -0
- package/scripts/probe-skip-line-both-ways.sh +65 -0
- package/scripts/receipts-aggregate.py +199 -0
- package/scripts/session-forensic-audit.py +360 -0
- package/scripts.json +9 -9
- package/scripts.json.bak-2026-07-27-find +13 -0
- package/skills/safety-setup/SKILL.md +5 -5
- package/tests/approve-side-remaining-two.test.sh +129 -0
- package/tests/approver-list-granularity.test.sh +145 -0
- package/tests/askuserquestion-autonomy-gate.test.sh +181 -0
- package/tests/audit-ci-gate.test.sh +87 -0
- package/tests/audit-cross-layer-claudemd.test.sh +170 -0
- package/tests/audit-fail-open-parse.test.sh +100 -0
- package/tests/auto-approve-compound-tail.test.sh +194 -0
- package/tests/auto-mode-path-invoked-commands.test.sh +89 -0
- package/tests/auto-mode-quoted-targets.test.sh +127 -0
- package/tests/auto-mode-unquoted-targets.test.sh +112 -0
- package/tests/bash-secret-output-detector-detects.test.sh +102 -0
- package/tests/blindspots-cross-layer.test.sh +177 -0
- package/tests/block-database-wipe.test.sh +64 -0
- package/tests/bundled-short-flags-bypass.test.sh +85 -0
- package/tests/cd-git-allow-compound-tail.test.sh +67 -0
- package/tests/chown-guard-filesystem-root.test.sh +64 -0
- package/tests/ci-workflow-guard-skip-rule.test.sh +115 -0
- package/tests/compound-deny-safe-rm-targets.test.sh +105 -0
- package/tests/core-scripts-parser-fallback.test.sh +140 -0
- package/tests/destructive-guard-bare-glob.test.sh +74 -0
- package/tests/destructive-guard-every-operand.test.sh +100 -0
- package/tests/destructive-guard-find-deletion.test.sh +114 -0
- package/tests/destructive-guard-flag-order.test.sh +106 -0
- package/tests/destructive-guard-mentions-vs-invocations.test.sh +107 -0
- package/tests/destructive-guard-quoted-target.test.sh +89 -0
- package/tests/destructive-guard-separators.test.sh +105 -0
- package/tests/destructive-guard-variable-target.test.sh +98 -0
- package/tests/destructive-guard-wrapped-command.test.sh +91 -0
- package/tests/doctor-hook-disabling-env.test.sh +92 -0
- package/tests/doctor-misspelled-settings-keys.test.sh +106 -0
- package/tests/example-guards-wrapped-command.test.sh +169 -0
- package/tests/file-edit-backup.test.sh +93 -0
- package/tests/git-filter-repo-guard.test.sh +60 -0
- package/tests/git-global-options-bypass.test.sh +141 -0
- package/tests/git-invocation-prefixes-all-guards.test.sh +114 -0
- package/tests/git-maintenance-guard.test.sh +83 -0
- package/tests/git-pack-temp-cleanup-guard.test.sh +133 -0
- package/tests/git-rm-orphan-wipe-guard.test.sh +66 -0
- package/tests/git-submodule-guard.test.sh +50 -0
- package/tests/grep-pcre-portability.test.sh +155 -0
- package/tests/hook-registration-matches-input.test.sh +73 -0
- package/tests/hook-trigger-matches-envelope.test.sh +178 -0
- package/tests/install-does-not-claim-protection.test.sh +110 -0
- package/tests/install-example-standalone-tools.test.sh +139 -0
- package/tests/line-continuation-bypass.test.sh +114 -0
- package/tests/mcp-config-poisoning-audit.test.sh +106 -0
- package/tests/nested-background-agent-guard.test.sh +58 -0
- package/tests/no-unqualified-safety-claims.test.sh +114 -0
- package/tests/option-eating-grep-patterns.test.sh +130 -0
- package/tests/outdated-core-guards.test.sh +134 -0
- package/tests/outdated-report.test.sh +155 -0
- package/tests/output-secret-mask-warns.test.sh +73 -0
- package/tests/plugin-hooks-fail-open-under-sh.test.sh +165 -0
- package/tests/plugins-word-order.test.sh +126 -0
- package/tests/powershell-remove-item-guard.test.sh +85 -0
- package/tests/project-dir-naming.test.sh +103 -0
- package/tests/quoted-safe-targets-and-mentions.test.sh +190 -0
- package/tests/reroute-after-block-guard.test.sh +104 -0
- package/tests/secret-guard-documented-promises.test.sh +97 -0
- package/tests/session-plugin-pin-watch.test.sh +45 -0
- package/tests/settings-unreadable-refuses-to-write.test.sh +95 -0
- package/tests/shield-no-silent-adoption.test.py +110 -0
- package/tests/shield-no-silent-adoption.test.sh +46 -0
- package/tests/stop-transcript-write-health.test.sh +46 -0
- package/tests/system-dir-guard-root-erased.test.sh +66 -0
- package/tests/test-account-billing-log.sh +100 -0
- package/tests/test-account-routing-preflight.sh +77 -0
- package/tests/test-agent-sdk-credit-pool-monitor.sh +157 -0
- package/tests/test-agent-view-quota-warn.sh +184 -0
- package/tests/test-agents-md-edit-drift-warner.sh +176 -0
- package/tests/test-agents-md-loader.sh +204 -0
- package/tests/test-agents-md-sync-checker.sh +125 -0
- package/tests/test-ai-slop-punctuation-arrest.sh +280 -0
- package/tests/test-allowlist.sh +60 -0
- package/tests/test-always-allow-pattern-suggester.sh +147 -0
- package/tests/test-anthropic-base-url-guard.sh +88 -0
- package/tests/test-articulated-scope-capture.sh +139 -0
- package/tests/test-attachment-traversal-guard.sh +168 -0
- package/tests/test-aup-block-pattern-logger.sh +315 -0
- package/tests/test-aup-false-positive-helper.sh +188 -0
- package/tests/test-aup-large-tool-output-warner.sh +370 -0
- package/tests/test-aup-retry-loop-guard.sh +341 -0
- package/tests/test-auth-expiry-reminder.sh +303 -0
- package/tests/test-auth-macos-sleep-detector.sh +254 -0
- package/tests/test-auth-path-detector.sh +232 -0
- package/tests/test-auth-status-checker.sh +233 -0
- package/tests/test-authorized-reconfirmation-detector.sh +280 -0
- package/tests/test-background-cost-launch-guard.sh +62 -0
- package/tests/test-bash-allowlist-secondary-check.sh +143 -0
- package/tests/test-bash-fanout-bounded-rewriter.sh +186 -0
- package/tests/test-bash-project-fence.sh +127 -0
- package/tests/test-bg-permission-prompt-warner.sh +221 -0
- package/tests/test-binary-read-detector.sh +173 -0
- package/tests/test-broad-prefix-session-trap-warner.sh +167 -0
- package/tests/test-bulk-delete-target-resolution.sh +49 -0
- package/tests/test-bypass-mode-effective-verifier.sh +179 -0
- package/tests/test-cache-creation-drift-detector.sh +244 -0
- package/tests/test-cache-residue-detector.sh +429 -0
- package/tests/test-cache-tier-logger.sh +59 -0
- package/tests/test-cache-ttl-eviction-detector.sh +282 -0
- package/tests/test-cch-sentinel-precommit-guard.sh +64 -0
- package/tests/test-claim-verify-detector.sh +222 -0
- package/tests/test-claim-vs-caveat-checker.sh +134 -0
- package/tests/test-claude-code-version-pin-advisor.sh +353 -0
- package/tests/test-claude-md-reinjector.sh +173 -0
- package/tests/test-claude-md-size-monitor.sh +107 -0
- package/tests/test-claude-update-budget-guard.sh +132 -0
- package/tests/test-claude-update-smart.sh +91 -0
- package/tests/test-claudemd-tool-prohibition.sh +239 -0
- package/tests/test-cli-config-pinning-detector.sh +233 -0
- package/tests/test-cliff-countdown-advisor.sh +138 -0
- package/tests/test-closure-word-verify-gate.sh +158 -0
- package/tests/test-commit-all-scope-guard.sh +73 -0
- package/tests/test-commitment-carry-forward-arrest.sh +250 -0
- package/tests/test-compact-circuit-breaker.sh +134 -0
- package/tests/test-compact-dispatch-watchdog.sh +147 -0
- package/tests/test-completion-claim-without-verification-detector.sh +326 -0
- package/tests/test-compound-bash-permission-resolver.sh +264 -0
- package/tests/test-compound-command-deny-enforcer.sh +67 -0
- package/tests/test-context-length-budget.sh +68 -0
- package/tests/test-context-usage-drift-alert.sh +52 -22
- package/tests/test-cost-incident-self-audit.sh +94 -0
- package/tests/test-cowork-claude-md-load-checker.sh +257 -0
- package/tests/test-cowork-claudemd-helper.sh +141 -0
- package/tests/test-cowork-fuse-staleness-watcher.sh +287 -0
- package/tests/test-cowork-hook-absence-warner.sh +230 -0
- package/tests/test-cowork-model-picker-advisor.sh +317 -0
- package/tests/test-credential-exfil-guard.sh +62 -0
- package/tests/test-cron-create-receipt.sh +165 -0
- package/tests/test-cross-product-mcp-spawn-detector.sh +112 -0
- package/tests/test-daemon-zombie-worker-surfacer.sh +71 -0
- package/tests/test-daily-cost-guard.sh +131 -0
- package/tests/test-deny-rule-integrity-verifier.sh +288 -0
- package/tests/test-deployment-readback-gate.sh +92 -0
- package/tests/test-deployment-readback-gh-adapter.sh +163 -0
- package/tests/test-disabled-feature-toggle-advisor.sh +78 -0
- package/tests/test-dispatch-allowlist-preflight.sh +385 -0
- package/tests/test-dispatch-liveness-watchdog.sh +319 -0
- package/tests/test-dispatch-receipt.sh +314 -0
- package/tests/test-dotenv-anthropic-key-billing-guard.sh +160 -0
- package/tests/test-echo-probe-spam-detector.sh +143 -0
- package/tests/test-edit-quote-ambiguity-guard.sh +75 -0
- package/tests/test-ephemeral-container-detector.sh +251 -0
- package/tests/test-evidence-claim-gate.sh +291 -0
- package/tests/test-exploration-budget-guard.sh +164 -0
- package/tests/test-extended-thinking-loop-guard.sh +289 -0
- package/tests/test-extended-thinking-resume-warning.sh +240 -0
- package/tests/test-extended-thinking-tool-use-mismatch-detector.sh +236 -0
- package/tests/test-fabricated-command-detector.sh +296 -0
- package/tests/test-false-disk-full-guard.sh +36 -0
- package/tests/test-feature-deprecation-detector.sh +117 -0
- package/tests/test-forbidden-response-phrase-detector.sh +246 -0
- package/tests/test-git-operations-require-approval.sh +53 -0
- package/tests/test-git-push-blast-radius-guard.sh +115 -0
- package/tests/test-goal-iteration-limit-warner.sh +128 -0
- package/tests/test-growthbook-flag-monitor.sh +428 -0
- package/tests/test-halt-signal-detector.sh +120 -0
- package/tests/test-hook-self-disable-detector.sh +232 -0
- package/tests/test-iteration-quality-degradation-detector.sh +244 -0
- package/tests/test-long-session-malformed-tool-call-detector.sh +185 -0
- package/tests/test-marketplace-plugins.sh +193 -0
- package/tests/test-mcp-misdiagnosis-arrest.sh +235 -0
- package/tests/test-mcp-orphan-leak-warner.sh +71 -0
- package/tests/test-mcp-permissions-ask-warner.sh +207 -0
- package/tests/test-mcp-routine-approval-detector.sh +229 -0
- package/tests/test-mcp-startup-bloat-detector.sh +141 -0
- package/tests/test-mcp-stdio-compatibility-test.sh +112 -0
- package/tests/test-memory-chain-audit.sh +59 -0
- package/tests/test-memory-orphan-detector.sh +227 -0
- package/tests/test-model-swap-suggester.sh +368 -0
- package/tests/test-model-version-lock.sh +83 -0
- package/tests/test-multi-file-plan-routing-gate.sh +277 -0
- package/tests/test-multi-window-auth-drift-detector.sh +262 -0
- package/tests/test-nested-spawn-inflight-guard.sh +281 -0
- package/tests/test-no-force-flag.sh +49 -0
- package/tests/test-non-english-quality-warner.sh +229 -0
- package/tests/test-oauth-refresh-monitor.sh +311 -0
- package/tests/test-opus-degradation-tracker.sh +274 -0
- package/tests/test-opus48-routine-task-warning.sh +201 -0
- package/tests/test-opus48-thinking-wedge-advisor.sh +249 -0
- package/tests/test-output-token-spike-detector.sh +315 -0
- package/tests/test-parallel-batch-size-limiter.sh +228 -0
- package/tests/test-parallel-cascade-detector.sh +191 -0
- package/tests/test-partial-view-claim-arrest.sh +272 -0
- package/tests/test-per-prompt-token-cap.sh +136 -0
- package/tests/test-persisted-1m-model-advisor.sh +71 -0
- package/tests/test-plugin-hooks-json-bloat-detector.sh +267 -0
- package/tests/test-post-edit-disk-verify.sh +294 -0
- package/tests/test-pre-bash-sed-line-ending-windows.sh +108 -0
- package/tests/test-pre-execution-claim-detector.sh +366 -0
- package/tests/test-private-key-backup-and-git-credentials.sh +100 -0
- package/tests/test-proxy-capture-suggester.sh +214 -0
- package/tests/test-public-artefact-socratic-narrowing.sh +346 -0
- package/tests/test-quota-anomaly-detector.sh +321 -0
- package/tests/test-quota-reset-audit.sh +81 -0
- package/tests/test-read-loop-detector.sh +137 -0
- package/tests/test-read-once-guard.sh +85 -0
- package/tests/test-receipts-aggregate.sh +143 -0
- package/tests/test-redirect-fragment-warner.sh +130 -0
- package/tests/test-redundant-read-blocker.sh +155 -0
- package/tests/test-refusal-arrest-gate.sh +303 -0
- package/tests/test-remote-control-billing-classifier.sh +125 -0
- package/tests/test-resume-drift-watcher.sh +65 -0
- package/tests/test-rg-replace-flag-detector.sh +175 -0
- package/tests/test-rhetorical-verification-prompt-detector.sh +237 -0
- package/tests/test-rm-safety-net.sh +115 -0
- package/tests/test-route-handler-emptiness-gate.sh +300 -0
- package/tests/test-runtime-binary-change-detector.sh +196 -0
- package/tests/test-same-command-repeat-detector.sh +165 -0
- package/tests/test-same-correction-arrest.sh +165 -0
- package/tests/test-scope-expansion-receipt.sh +207 -0
- package/tests/test-server-side-prompt-injection-detector.sh +181 -0
- package/tests/test-session-persistence-verifier.sh +128 -0
- package/tests/test-session-rate-monitor.sh +284 -0
- package/tests/test-session-start-quota-status.sh +210 -0
- package/tests/test-session-start-safety-check.sh +138 -0
- package/tests/test-settings-hooks-key-restorer.sh +257 -0
- package/tests/test-settings-json-health-check.sh +70 -0
- package/tests/test-settings-regression-tester.sh +197 -0
- package/tests/test-skill-cumulative-size-detector.sh +198 -0
- package/tests/test-skill-description-drop-detector.sh +236 -0
- package/tests/test-skill-truncation-detector.sh +263 -0
- package/tests/test-skills-context-recorder.sh +329 -0
- package/tests/test-skills-load-verifier.sh +184 -0
- package/tests/test-skills-settings-validator.sh +242 -0
- package/tests/test-sonnet-45-deprecation-helper.sh +150 -0
- package/tests/test-spurious-malformed-notice-detector.sh +290 -0
- package/tests/test-sql-bulk-delete-warn.sh +123 -0
- package/tests/test-ssh-key-protect.sh +81 -0
- package/tests/test-stale-temp-settings-detector.sh +161 -0
- package/tests/test-standing-rule-session-surfacer.sh +215 -0
- package/tests/test-starter-hooks-manifest.sh +96 -0
- package/tests/test-stop-hook-sigterm-wrapper.sh +258 -0
- package/tests/test-strict-allowlist.sh +72 -0
- package/tests/test-subagent-boundary-precheck.sh +137 -0
- package/tests/test-subagent-closure-verify-gate.sh +193 -0
- package/tests/test-subagent-destructive-git-guard.sh +86 -0
- package/tests/test-subagent-identity-leak-guard.sh +62 -0
- package/tests/test-subagent-identity-reassertion.sh +61 -0
- package/tests/test-subagent-inheritance-tester.sh +319 -0
- package/tests/test-subagent-permission-mode-guard.sh +61 -0
- package/tests/test-subagent-spawn-verification-enforcer.sh +60 -0
- package/tests/test-subagent-tool-allowlist-enforcer.sh +62 -0
- package/tests/test-subagent-tool-call-limiter.sh +97 -0
- package/tests/test-subscription-api-billing-warner.sh +138 -0
- package/tests/test-subscription-bypass-detector.sh +255 -0
- package/tests/test-temporal-suggestion-detector.sh +183 -0
- package/tests/test-thinking-budget-effort-mismatch-detector.sh +327 -0
- package/tests/test-thinking-stall-detector.sh +151 -0
- package/tests/test-tokenizer-ratio-alert-corpus.sh +77 -0
- package/tests/test-tokenizer-ratio-alert.sh +93 -0
- package/tests/test-tool-result-correlation-checker.sh +264 -0
- package/tests/test-tool-result-size-guard.sh +121 -0
- package/tests/test-transcript-contamination-detector.sh +264 -0
- package/tests/test-trigger-header-parsing.sh +151 -0
- package/tests/test-ultrareview-large-diff-advisor.sh +192 -0
- package/tests/test-userprompt-submit-receipt.sh +181 -0
- package/tests/test-verify-after-publish-reminder.sh +184 -0
- package/tests/test-version-bump-detector.sh +212 -0
- package/tests/test-version-regression-warner.sh +165 -0
- package/tests/test-warn-cron-cost-trap.sh +82 -0
- package/tests/test-webfetch-runaway-guard.sh +77 -0
- package/tests/test-wellness-break-reminder.sh +138 -0
- package/tests/test-windows-destructive-command-guard.sh +169 -0
- package/tests/test-windows-python-stub-detector.sh +146 -0
- package/tests/test-worktree-edit-boundary-guard.sh +219 -0
- package/tests/test-write-byte-integrity-verifier.sh +192 -0
- package/tests/test-xml-format-leak-detector.sh +299 -0
- package/tests/trustfall-mcp-injection-guard.test.sh +183 -0
- package/tests/workspace-lease-guard.test.sh +144 -0
- package/tests/worktree-escape-write-guard.test.sh +68 -0
- package/tests/worktree-hooks-path-fix.test.sh +181 -0
- package/tests/worktree-parent-write-guard.test.sh +51 -0
- package/tests/write-empty-content-guard.test.sh +39 -0
- package/tests/write-nul-corruption-detector.test.sh +29 -0
- package/tests/write-overwrite-unread-content.test.sh +178 -0
- package/tests/wsl-host-disk-space-guard.test.sh +55 -0
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
# trigger a confirmation prompt even when they match allowlist patterns.
|
|
11
11
|
#
|
|
12
12
|
# This PermissionRequest hook auto-approves these prompts when:
|
|
13
|
-
# 1.
|
|
13
|
+
# 1. Every command position is in a safe list
|
|
14
14
|
# 2. The only "issue" is quoted characters in flag values
|
|
15
15
|
#
|
|
16
16
|
# TRIGGER: PermissionRequest
|
|
@@ -25,6 +25,25 @@
|
|
|
25
25
|
# }]
|
|
26
26
|
# }
|
|
27
27
|
# }
|
|
28
|
+
#
|
|
29
|
+
# Fixed 2026-08-03. The safe list held bare command *words* — `git`, `curl`,
|
|
30
|
+
# `chmod`, `sed`, `node`, `python3`, `npx` — and a word says nothing about what
|
|
31
|
+
# the command does. `git commit -m "fix"` and `git push --force origin main`
|
|
32
|
+
# have the same first word.
|
|
33
|
+
#
|
|
34
|
+
# Measured against the shipped copy, over 20 destructive or credential-reading
|
|
35
|
+
# commands with no separator in them at all: **15 were approved**, among them
|
|
36
|
+
# `git push --force`, `git reset --hard`, `git clean -fdx`, `chmod -R 777 /`,
|
|
37
|
+
# `curl … | sh`, `node -e '…rmSync…'` and `cat ~/.aws/credentials`.
|
|
38
|
+
#
|
|
39
|
+
# This is a different defect from the first-command-position one repaired in
|
|
40
|
+
# #937/#940/#941/#942/#943/#947, and mixing the two would produce a number that
|
|
41
|
+
# looks right and is not: nothing here was hiding past a separator. The
|
|
42
|
+
# granularity of the list was the problem. (The first-position defect was here
|
|
43
|
+
# too, and is fixed in the same pass.)
|
|
44
|
+
#
|
|
45
|
+
# Known limit: quotes are not parsed when splitting, so a separator inside a
|
|
46
|
+
# quoted string ends a segment early. That errs toward fewer approvals.
|
|
28
47
|
|
|
29
48
|
INPUT=$(cat)
|
|
30
49
|
|
|
@@ -36,16 +55,86 @@ echo "$MESSAGE" | grep -qi "quoted characters in flag" || exit 0
|
|
|
36
55
|
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
37
56
|
[ -z "$COMMAND" ] && exit 0
|
|
38
57
|
|
|
39
|
-
#
|
|
40
|
-
|
|
58
|
+
# A substitution or backtick carries a command no string-level read can see.
|
|
59
|
+
# This hook is about quoted flag values, not substitution, so it refuses them.
|
|
60
|
+
case "$COMMAND" in
|
|
61
|
+
*'$('*|*'`'*) exit 0 ;;
|
|
62
|
+
esac
|
|
63
|
+
|
|
64
|
+
# Command words that carry no destructive form of their own. Anything that
|
|
65
|
+
# takes code as an argument (`node -e`, `python3 -c`, `npx`) or fetches and runs
|
|
66
|
+
# (`curl`, `wget`) is deliberately absent: for those the word says nothing.
|
|
67
|
+
cc_base_ok() {
|
|
68
|
+
case "$1" in
|
|
69
|
+
cat|head|tail|less|more|wc|file|stat|du|df|ls|tree|\
|
|
70
|
+
which|whereis|type|realpath|readlink|basename|dirname|\
|
|
71
|
+
grep|rg|ag|ack|sort|uniq|tr|cut|column|nl|rev|awk|\
|
|
72
|
+
echo|printf|true|false|pwd|date|uname|hostname|whoami|id|\
|
|
73
|
+
jq|yq|cd|\
|
|
74
|
+
tsc|eslint|prettier|jest|vitest|pytest)
|
|
75
|
+
return 0 ;;
|
|
76
|
+
esac
|
|
77
|
+
return 1
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
# Build tool subcommands that neither destroy history nor run fetched code.
|
|
81
|
+
# One line on purpose: inside single quotes a trailing backslash is a literal
|
|
82
|
+
# backslash-newline, not a continuation, and the pattern silently stops matching.
|
|
83
|
+
CC_SUBCMD_RE='^[[:space:]]*(git[[:space:]]+(status|log|diff|show|add|commit|branch|remote|describe|rev-parse|blame|shortlog|ls-files|ls-tree|fetch|stash[[:space:]]+(list|push|save))|npm[[:space:]]+(test|run|ci|ls|view|outdated)|yarn[[:space:]]+(test|run|info|why)|pnpm[[:space:]]+(test|run|list|why)|bun[[:space:]]+(test|run)|cargo[[:space:]]+(build|test|check|fmt|clippy|tree)|go[[:space:]]+(build|test|vet|fmt|list)|docker[[:space:]]+(ps|images|logs|inspect|version|info)|make[[:space:]]+[A-Za-z0-9_.-]+|pip[[:space:]]+(list|show|freeze)|python3[[:space:]]+-m[[:space:]]+(pytest|unittest|pip[[:space:]]+(list|show|freeze)))([[:space:]]|$)'
|
|
84
|
+
|
|
85
|
+
cc_subcommand_ok() {
|
|
86
|
+
printf '%s' "$1" | grep -qE "$CC_SUBCMD_RE"
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
cc_segment_base() {
|
|
90
|
+
printf '%s' "$1" \
|
|
91
|
+
| sed -E 's/^[[:space:]]+//; s/^([A-Za-z_][A-Za-z0-9_]*=[^[:space:]]*[[:space:]]+)*//' \
|
|
92
|
+
| awk '{print $1}' \
|
|
93
|
+
| sed 's|.*/||'
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
# `git branch` reads; `git branch -D main` deletes one. Same first two words.
|
|
97
|
+
CC_GIT_DESTRUCTIVE_RE='^[[:space:]]*git[[:space:]]+(branch|tag)[[:space:]]+-([dDmM]|-delete|-move)([[:space:]]|$)'
|
|
98
|
+
|
|
99
|
+
cc_segment_ok() {
|
|
100
|
+
local seg="$1" base
|
|
101
|
+
base=$(cc_segment_base "$seg")
|
|
102
|
+
[ -z "$base" ] && return 1
|
|
103
|
+
|
|
104
|
+
if [ "$base" = "find" ]; then
|
|
105
|
+
printf '%s' "$seg" \
|
|
106
|
+
| grep -qE '(^|[[:space:]])-(delete|exec|execdir|ok|okdir|fprintf?|fls|fprint0)([[:space:]]|$)' \
|
|
107
|
+
&& return 1
|
|
108
|
+
return 0
|
|
109
|
+
fi
|
|
110
|
+
if [ "$base" = "sed" ]; then
|
|
111
|
+
printf '%s' "$seg" | grep -qE '(^|[[:space:]])-[a-zA-Z]*i' && return 1
|
|
112
|
+
return 0
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
cc_base_ok "$base" && return 0
|
|
116
|
+
printf '%s' "$seg" | grep -qE "$CC_GIT_DESTRUCTIVE_RE" && return 1
|
|
117
|
+
cc_subcommand_ok "$seg" && return 0
|
|
118
|
+
return 1
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
# A redirection writes a file, whatever the command word says.
|
|
122
|
+
case "$COMMAND" in
|
|
123
|
+
*'>'*) exit 0 ;;
|
|
124
|
+
esac
|
|
41
125
|
|
|
42
|
-
|
|
43
|
-
|
|
126
|
+
IDX=0
|
|
127
|
+
while IFS= read -r SEG; do
|
|
128
|
+
SEG="${SEG#"${SEG%%[![:space:]]*}"}"
|
|
129
|
+
SEG="${SEG%"${SEG##*[![:space:]]}"}"
|
|
130
|
+
[ -z "$SEG" ] && continue
|
|
131
|
+
cc_segment_ok "$SEG" || exit 0
|
|
132
|
+
IDX=$((IDX + 1))
|
|
133
|
+
done <<EOF
|
|
134
|
+
$(printf '%s' "$COMMAND" | tr ';&|' '\n\n\n')
|
|
135
|
+
EOF
|
|
44
136
|
|
|
45
|
-
|
|
46
|
-
echo '{"permissionDecision":"allow"}'
|
|
47
|
-
exit 0
|
|
48
|
-
fi
|
|
137
|
+
[ "$IDX" -eq 0 ] && exit 0
|
|
49
138
|
|
|
50
|
-
|
|
139
|
+
echo '{"permissionDecision":"allow"}'
|
|
51
140
|
exit 0
|
|
@@ -19,6 +19,18 @@
|
|
|
19
19
|
#
|
|
20
20
|
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
21
21
|
|
|
22
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
23
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
24
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
25
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
26
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
27
|
+
_nojq_warned="/tmp/cc-nojq-warned-rails-migration-guard-$PPID"
|
|
28
|
+
[ -f "$_nojq_warned" ] || {
|
|
29
|
+
echo "WARNING [rails-migration-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
30
|
+
: > "$_nojq_warned"
|
|
31
|
+
}
|
|
32
|
+
fi
|
|
33
|
+
|
|
22
34
|
INPUT=$(cat)
|
|
23
35
|
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
24
36
|
|
|
File without changes
|
|
File without changes
|
|
@@ -25,6 +25,18 @@
|
|
|
25
25
|
# CC_READ_BUDGET=100 — max unique files per session (default: 100)
|
|
26
26
|
# CC_READ_WARN=50 — warn threshold (default: 50)
|
|
27
27
|
|
|
28
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
29
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
30
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
31
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
32
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
33
|
+
_nojq_warned="/tmp/cc-nojq-warned-read-budget-guard-$PPID"
|
|
34
|
+
[ -f "$_nojq_warned" ] || {
|
|
35
|
+
echo "WARNING [read-budget-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
36
|
+
: > "$_nojq_warned"
|
|
37
|
+
}
|
|
38
|
+
fi
|
|
39
|
+
|
|
28
40
|
INPUT=$(cat)
|
|
29
41
|
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
|
|
30
42
|
[ -z "$FILE" ] && exit 0
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# read-loop-detector.sh — Surface same-file Read loops within a session
|
|
4
|
+
# ================================================================
|
|
5
|
+
# PURPOSE:
|
|
6
|
+
# When Claude Code decides to write a memory file (or any output)
|
|
7
|
+
# it sometimes re-reads source files it already read earlier in the
|
|
8
|
+
# same session, looping 10+ times before finally writing. The
|
|
9
|
+
# "File unchanged since last read" cache hint logs through the
|
|
10
|
+
# harness but does not short-circuit the model's decision, so the
|
|
11
|
+
# loop bills tokens for round-trips that return identical content.
|
|
12
|
+
#
|
|
13
|
+
# This hook surfaces the loop while it's happening so the user can
|
|
14
|
+
# interrupt with `escape` and prompt the model to write directly.
|
|
15
|
+
#
|
|
16
|
+
# Reference: https://github.com/anthropics/claude-code/issues/53578
|
|
17
|
+
# https://github.com/anthropics/claude-code/issues/40123
|
|
18
|
+
#
|
|
19
|
+
# TRIGGER: PostToolUse MATCHER: "Read"
|
|
20
|
+
#
|
|
21
|
+
# CONFIG:
|
|
22
|
+
# CC_READ_LOOP_THRESHOLD=3 (warn at this many reads of same path)
|
|
23
|
+
# CC_READ_LOOP_LOG_DIR=/tmp (per-session counter log location)
|
|
24
|
+
# CC_READ_LOOP_DISABLE= (set to 1 to disable)
|
|
25
|
+
# ================================================================
|
|
26
|
+
|
|
27
|
+
[ "${CC_READ_LOOP_DISABLE:-}" = "1" ] && exit 0
|
|
28
|
+
|
|
29
|
+
INPUT=$(cat)
|
|
30
|
+
SESSION_ID=$(printf '%s' "$INPUT" | jq -r '.session_id // "unknown"' 2>/dev/null)
|
|
31
|
+
TOOL_NAME=$(printf '%s' "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
|
|
32
|
+
FILE_PATH=$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
|
|
33
|
+
|
|
34
|
+
[ "$TOOL_NAME" != "Read" ] && exit 0
|
|
35
|
+
[ -z "$FILE_PATH" ] && exit 0
|
|
36
|
+
|
|
37
|
+
THRESHOLD="${CC_READ_LOOP_THRESHOLD:-3}"
|
|
38
|
+
LOG_DIR="${CC_READ_LOOP_LOG_DIR:-/tmp}"
|
|
39
|
+
LOG_FILE="$LOG_DIR/cc-read-loop-${SESSION_ID}.log"
|
|
40
|
+
|
|
41
|
+
# Defensive: ensure threshold is a positive integer
|
|
42
|
+
case "$THRESHOLD" in
|
|
43
|
+
''|*[!0-9]*) THRESHOLD=3 ;;
|
|
44
|
+
esac
|
|
45
|
+
|
|
46
|
+
# Append this read; one path per line for grep -c
|
|
47
|
+
printf '%s\n' "$FILE_PATH" >> "$LOG_FILE" 2>/dev/null || exit 0
|
|
48
|
+
|
|
49
|
+
# Count occurrences of this exact path (literal string, not regex)
|
|
50
|
+
COUNT=$(grep -cFx "$FILE_PATH" "$LOG_FILE" 2>/dev/null || echo 0)
|
|
51
|
+
|
|
52
|
+
if [ "$COUNT" -ge "$THRESHOLD" ]; then
|
|
53
|
+
echo "NOTE: Read on $FILE_PATH has fired $COUNT times this session." >&2
|
|
54
|
+
echo "If the agent is preparing to write a memory or summary file, the model may be re-verifying context it already has." >&2
|
|
55
|
+
echo "To break the loop: escape and prompt 'Stop reading. Write the file now using existing context.'" >&2
|
|
56
|
+
echo "Disable this hint: export CC_READ_LOOP_DISABLE=1" >&2
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
exit 0
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# read-once-guard.sh — Warn when Claude re-reads a file already in context
|
|
3
|
+
#
|
|
4
|
+
# Inspired by the token waste pattern where Claude reads the same file
|
|
5
|
+
# multiple times in a session, consuming tokens without gaining new info.
|
|
6
|
+
# Studies show this can waste 30%+ of session tokens.
|
|
7
|
+
#
|
|
8
|
+
# HOW IT WORKS:
|
|
9
|
+
# Tracks which files have been read in the current session.
|
|
10
|
+
# If a file is read again and hasn't been modified since the last read,
|
|
11
|
+
# warns the user (but allows the read to proceed).
|
|
12
|
+
#
|
|
13
|
+
# TRIGGER: PreToolUse MATCHER: "Read"
|
|
14
|
+
#
|
|
15
|
+
# CONFIGURATION:
|
|
16
|
+
# CC_READ_ONCE_ACTION=warn|block (default: warn)
|
|
17
|
+
# CC_READ_ONCE_MAX=3 (warn/block after N re-reads of same file)
|
|
18
|
+
|
|
19
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
20
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
21
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
22
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
23
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
24
|
+
_nojq_warned="/tmp/cc-nojq-warned-read-once-guard-$PPID"
|
|
25
|
+
[ -f "$_nojq_warned" ] || {
|
|
26
|
+
echo "WARNING [read-once-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
27
|
+
: > "$_nojq_warned"
|
|
28
|
+
}
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
INPUT=$(cat)
|
|
32
|
+
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
|
|
33
|
+
|
|
34
|
+
[[ -z "$FILE_PATH" ]] && exit 0
|
|
35
|
+
|
|
36
|
+
# Normalize path
|
|
37
|
+
FILE_PATH=$(realpath "$FILE_PATH" 2>/dev/null || echo "$FILE_PATH")
|
|
38
|
+
|
|
39
|
+
STATE_DIR="/tmp/cc-read-once"
|
|
40
|
+
mkdir -p "$STATE_DIR"
|
|
41
|
+
|
|
42
|
+
ACTION="${CC_READ_ONCE_ACTION:-warn}"
|
|
43
|
+
MAX_READS="${CC_READ_ONCE_MAX:-3}"
|
|
44
|
+
|
|
45
|
+
# Session ID based on parent process
|
|
46
|
+
SESSION_ID="${CC_SESSION_ID:-$$}"
|
|
47
|
+
STATE_FILE="$STATE_DIR/reads-${SESSION_ID}.log"
|
|
48
|
+
|
|
49
|
+
# Get current file mtime
|
|
50
|
+
CURRENT_MTIME=$(stat -c %Y "$FILE_PATH" 2>/dev/null || echo "0")
|
|
51
|
+
|
|
52
|
+
# Check if this file was already read
|
|
53
|
+
READ_COUNT=0
|
|
54
|
+
LAST_MTIME="0"
|
|
55
|
+
if [[ -f "$STATE_FILE" ]]; then
|
|
56
|
+
while IFS=$'\t' read -r path mtime count; do
|
|
57
|
+
if [[ "$path" == "$FILE_PATH" ]]; then
|
|
58
|
+
READ_COUNT=$count
|
|
59
|
+
LAST_MTIME=$mtime
|
|
60
|
+
break
|
|
61
|
+
fi
|
|
62
|
+
done < "$STATE_FILE"
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# If file was modified since last read, reset counter
|
|
66
|
+
if [[ "$CURRENT_MTIME" != "$LAST_MTIME" && "$LAST_MTIME" != "0" ]]; then
|
|
67
|
+
READ_COUNT=0
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
# Increment read count
|
|
71
|
+
READ_COUNT=$((READ_COUNT + 1))
|
|
72
|
+
|
|
73
|
+
# Update state file (use tab as delimiter to avoid path conflicts)
|
|
74
|
+
ESCAPED_PATH=$(printf '%s' "$FILE_PATH" | sed 's/[&/\]/\\&/g')
|
|
75
|
+
if grep -q "^${ESCAPED_PATH} " "$STATE_FILE" 2>/dev/null; then
|
|
76
|
+
# Replace the line for this file
|
|
77
|
+
grep -v "^${ESCAPED_PATH} " "$STATE_FILE" > "${STATE_FILE}.tmp"
|
|
78
|
+
echo -e "${FILE_PATH}\t${CURRENT_MTIME}\t${READ_COUNT}" >> "${STATE_FILE}.tmp"
|
|
79
|
+
mv "${STATE_FILE}.tmp" "$STATE_FILE"
|
|
80
|
+
else
|
|
81
|
+
echo -e "${FILE_PATH}\t${CURRENT_MTIME}\t${READ_COUNT}" >> "$STATE_FILE"
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
# Check threshold
|
|
85
|
+
if [[ "$READ_COUNT" -gt "$MAX_READS" ]]; then
|
|
86
|
+
if [[ "$ACTION" == "block" ]]; then
|
|
87
|
+
echo "⚠️ BLOCKED: ${FILE_PATH} has been read ${READ_COUNT} times without changes." >&2
|
|
88
|
+
echo " The file content is already in your context. Use what you already know." >&2
|
|
89
|
+
exit 2
|
|
90
|
+
else
|
|
91
|
+
echo "⚠️ NOTE: Re-reading ${FILE_PATH} (${READ_COUNT}x). File hasn't changed since last read." >&2
|
|
92
|
+
echo " Consider using the content already in your context to save tokens." >&2
|
|
93
|
+
fi
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
exit 0
|
|
@@ -33,6 +33,18 @@
|
|
|
33
33
|
# TRIGGER: PreToolUse MATCHER: "Write|Edit|NotebookEdit|Bash"
|
|
34
34
|
|
|
35
35
|
# Only active when CLAUDE_READONLY=1
|
|
36
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
37
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
38
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
39
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
40
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
41
|
+
_nojq_warned="/tmp/cc-nojq-warned-read-only-mode-$PPID"
|
|
42
|
+
[ -f "$_nojq_warned" ] || {
|
|
43
|
+
echo "WARNING [read-only-mode]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
44
|
+
: > "$_nojq_warned"
|
|
45
|
+
}
|
|
46
|
+
fi
|
|
47
|
+
|
|
36
48
|
[[ "${CLAUDE_READONLY:-}" != "1" ]] && exit 0
|
|
37
49
|
|
|
38
50
|
INPUT=$(cat)
|
|
File without changes
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# record-read-coverage.sh — Record how much of each file was read
|
|
4
|
+
# ================================================================
|
|
5
|
+
# PURPOSE:
|
|
6
|
+
# Two shipped hooks need to know whether a file was read before it
|
|
7
|
+
# is written, and neither could work without this recorder:
|
|
8
|
+
#
|
|
9
|
+
# read-before-edit.sh — documents "Requires companion PostToolUse
|
|
10
|
+
# hook to record Read events" and no such
|
|
11
|
+
# hook shipped, so its NOTE fired on every
|
|
12
|
+
# single Edit (a warning that always fires
|
|
13
|
+
# carries no information)
|
|
14
|
+
# write-overwrite-confirm.sh — could only compare sizes, so an overwrite
|
|
15
|
+
# that keeps the line count was invisible
|
|
16
|
+
#
|
|
17
|
+
# WHY COVERAGE AND NOT JUST THE PATH:
|
|
18
|
+
# Issue #78273: the agent read FIVE lines of a hand-built file, confirmed
|
|
19
|
+
# it had content, then overwrote the whole file with its own analysis.
|
|
20
|
+
# The original was not in git and was unrecoverable. A path-only record
|
|
21
|
+
# would have said "this file was read" and the write would have passed.
|
|
22
|
+
# What matters is whether the part being destroyed was ever seen.
|
|
23
|
+
#
|
|
24
|
+
# TRIGGER: PostToolUse
|
|
25
|
+
# MATCHER: "Read"
|
|
26
|
+
#
|
|
27
|
+
# RECORD FORMAT (tab separated, appended):
|
|
28
|
+
# <absolute path>\t<offset>\t<limit>\t<total lines when read>
|
|
29
|
+
#
|
|
30
|
+
# offset/limit are 0 when the Read carried no such argument, which the
|
|
31
|
+
# Read tool treats as "from the top, up to its own default cap".
|
|
32
|
+
# ================================================================
|
|
33
|
+
|
|
34
|
+
set -uo pipefail
|
|
35
|
+
|
|
36
|
+
READ_LOG="${CC_READ_LOG:-/tmp/cc-read-files}"
|
|
37
|
+
|
|
38
|
+
INPUT=$(cat)
|
|
39
|
+
|
|
40
|
+
TOOL=$(printf '%s' "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null || true)
|
|
41
|
+
[ "$TOOL" = "Read" ] || exit 0
|
|
42
|
+
|
|
43
|
+
FILE=$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null || true)
|
|
44
|
+
[ -n "$FILE" ] || exit 0
|
|
45
|
+
|
|
46
|
+
# Only real files can be covered. A path that is gone by the time the
|
|
47
|
+
# PostToolUse hook runs tells us nothing useful, so record nothing.
|
|
48
|
+
[ -f "$FILE" ] || exit 0
|
|
49
|
+
|
|
50
|
+
OFFSET=$(printf '%s' "$INPUT" | jq -r '.tool_input.offset // 0' 2>/dev/null || echo 0)
|
|
51
|
+
LIMIT=$(printf '%s' "$INPUT" | jq -r '.tool_input.limit // 0' 2>/dev/null || echo 0)
|
|
52
|
+
case "$OFFSET" in ''|*[!0-9]*) OFFSET=0 ;; esac
|
|
53
|
+
case "$LIMIT" in ''|*[!0-9]*) LIMIT=0 ;; esac
|
|
54
|
+
|
|
55
|
+
TOTAL=$(wc -l < "$FILE" 2>/dev/null || echo 0)
|
|
56
|
+
case "$TOTAL" in ''|*[!0-9]*) TOTAL=0 ;; esac
|
|
57
|
+
|
|
58
|
+
# The log is advisory state shared between separate hook processes, so a
|
|
59
|
+
# failed write must never break the user's Read. Everything here is best effort.
|
|
60
|
+
printf '%s\t%s\t%s\t%s\n' "$FILE" "$OFFSET" "$LIMIT" "$TOTAL" >> "$READ_LOG" 2>/dev/null || true
|
|
61
|
+
|
|
62
|
+
# Keep the log from growing without bound across a long session. 2000 lines is
|
|
63
|
+
# far more than any single session needs and costs nothing to carry.
|
|
64
|
+
if [ -f "$READ_LOG" ]; then
|
|
65
|
+
LINES=$(wc -l < "$READ_LOG" 2>/dev/null || echo 0)
|
|
66
|
+
case "$LINES" in ''|*[!0-9]*) LINES=0 ;; esac
|
|
67
|
+
if [ "$LINES" -gt 2000 ]; then
|
|
68
|
+
tail -n 1000 "$READ_LOG" > "$READ_LOG.trim" 2>/dev/null &&
|
|
69
|
+
mv "$READ_LOG.trim" "$READ_LOG" 2>/dev/null || true
|
|
70
|
+
fi
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
exit 0
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# redirect-fragment-warner.sh — Warn / block Bash commands using `2>&1`
|
|
3
|
+
# (Cluster 25 candidate, axis 25C — permission-engine `&` fragmentation hang)
|
|
4
|
+
#
|
|
5
|
+
# Background:
|
|
6
|
+
# A Bash tool command containing `2>&1` triggers a multi-minute spinner
|
|
7
|
+
# hang in the permission-evaluation layer. Token usage increments
|
|
8
|
+
# continuously during the hang — implying a model-reinvocation loop
|
|
9
|
+
# rather than an idle wait. The command itself eventually executes
|
|
10
|
+
# correctly; the hang is purely in the permission step.
|
|
11
|
+
#
|
|
12
|
+
# Hypothesised root cause: the permission engine splits Bash commands on
|
|
13
|
+
# shell operators including `&`. The `&` inside `2>&1` fragments the
|
|
14
|
+
# command into segments that are validated independently. That
|
|
15
|
+
# fragmentation drops the command into a re-validation loop where each
|
|
16
|
+
# fragment is re-checked, and the loop re-invokes the model on each
|
|
17
|
+
# iteration — which is the source of the climbing token usage during
|
|
18
|
+
# the visible hang.
|
|
19
|
+
#
|
|
20
|
+
# Anchor case:
|
|
21
|
+
# #64334 — Bash command with 2>&1 causes ~12min spinner hang with
|
|
22
|
+
# token usage climbing during the stall
|
|
23
|
+
#
|
|
24
|
+
# Cluster 25 sub-axes (4 + 1 overlap):
|
|
25
|
+
# 25A — late/empty tool-result delivery (substrate)
|
|
26
|
+
# 25B — echo-probe spam compensation (PR #556 shipped)
|
|
27
|
+
# 25C — 2>&1 permission-engine fragmentation hang (this hook)
|
|
28
|
+
# 25D — compounding cost (downstream of 25B/25C)
|
|
29
|
+
# 25E — empty-result triggered fabrication (Cluster 22 overlap)
|
|
30
|
+
#
|
|
31
|
+
# This hook is a PreToolUse hook on Bash that:
|
|
32
|
+
# - Matches `2>&1` in the command string (the trigger pattern)
|
|
33
|
+
# - Warns with a rewrite suggestion (default) — `CC_BLOCK_2_REDIRECT=1`
|
|
34
|
+
# to block by default for users who have been bitten once
|
|
35
|
+
# - Allows operator override via `# ACCEPT 2>&1` marker in the command
|
|
36
|
+
#
|
|
37
|
+
# The cost-impact justification (12-min hang with token billing climbing)
|
|
38
|
+
# supports defaulting to warn rather than silent allow, and supports the
|
|
39
|
+
# easy-toggle to block-by-default for users who have hit this.
|
|
40
|
+
#
|
|
41
|
+
# When this hook does NOT warn / block:
|
|
42
|
+
# - CC_REDIRECT_FRAGMENT_DISABLE=1 — never warn or block
|
|
43
|
+
# - CC_REDIRECT_FRAGMENT_QUIET=1 — silent (no stderr output)
|
|
44
|
+
# - The command does not contain `2>&1`
|
|
45
|
+
# - The command contains `# ACCEPT 2>&1` marker (operator override)
|
|
46
|
+
#
|
|
47
|
+
# When this hook BLOCKS (exit 2):
|
|
48
|
+
# - CC_BLOCK_2_REDIRECT=1 is set
|
|
49
|
+
# - the command contains `2>&1`
|
|
50
|
+
# - the command does not contain the `# ACCEPT 2>&1` override marker
|
|
51
|
+
#
|
|
52
|
+
# Hook config (settings.json):
|
|
53
|
+
# {
|
|
54
|
+
# "hooks": {
|
|
55
|
+
# "PreToolUse": [{
|
|
56
|
+
# "matcher": "Bash",
|
|
57
|
+
# "hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/redirect-fragment-warner.sh" }]
|
|
58
|
+
# }]
|
|
59
|
+
# }
|
|
60
|
+
# }
|
|
61
|
+
#
|
|
62
|
+
# Env vars:
|
|
63
|
+
# CC_REDIRECT_FRAGMENT_DISABLE=1 — never warn or block
|
|
64
|
+
# CC_REDIRECT_FRAGMENT_QUIET=1 — silent (process but never write stderr)
|
|
65
|
+
# CC_BLOCK_2_REDIRECT=1 — block (exit 2) instead of warn
|
|
66
|
+
|
|
67
|
+
set -u
|
|
68
|
+
|
|
69
|
+
if [ "${CC_REDIRECT_FRAGMENT_DISABLE:-}" = "1" ]; then
|
|
70
|
+
exit 0
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
INPUT=$(cat 2>/dev/null || true)
|
|
74
|
+
CMD=""
|
|
75
|
+
if command -v jq >/dev/null 2>&1 && [ -n "$INPUT" ]; then
|
|
76
|
+
CMD=$(printf '%s' "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null || true)
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
if [ -z "$CMD" ]; then
|
|
80
|
+
exit 0
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
# Detect `2>&1` in the command (the trigger pattern)
|
|
84
|
+
if ! printf '%s\n' "$CMD" | grep -q '2>&1'; then
|
|
85
|
+
exit 0
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# Operator override: `# ACCEPT 2>&1` marker disables the warning for this call
|
|
89
|
+
if printf '%s\n' "$CMD" | grep -Eq '#[[:space:]]*ACCEPT[[:space:]]+2>&1'; then
|
|
90
|
+
exit 0
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# Build the rewrite suggestion: strip `2>&1` and keep the rest of the command
|
|
94
|
+
# (best-effort — the operator should review)
|
|
95
|
+
SUGGESTED=$(printf '%s\n' "$CMD" | sed 's/[[:space:]]*2>&1//g')
|
|
96
|
+
|
|
97
|
+
if [ "${CC_REDIRECT_FRAGMENT_QUIET:-}" = "1" ]; then
|
|
98
|
+
if [ "${CC_BLOCK_2_REDIRECT:-}" = "1" ]; then
|
|
99
|
+
exit 2
|
|
100
|
+
fi
|
|
101
|
+
exit 0
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
if [ "${CC_BLOCK_2_REDIRECT:-}" = "1" ]; then
|
|
105
|
+
cat >&2 <<EOF
|
|
106
|
+
|
|
107
|
+
BLOCKED: Bash command contains \`2>&1\`.
|
|
108
|
+
|
|
109
|
+
Pattern detected: the permission engine splits Bash commands on shell
|
|
110
|
+
operators including \`&\`. The \`&\` inside \`2>&1\` fragments the command
|
|
111
|
+
into segments that are validated independently, dropping the command
|
|
112
|
+
into a re-validation loop where each fragment is re-checked and the
|
|
113
|
+
loop re-invokes the model on each iteration. This produces the
|
|
114
|
+
multi-minute spinner hang with token usage climbing observed in #64334
|
|
115
|
+
(Cluster 25 axis 25C).
|
|
116
|
+
|
|
117
|
+
What to do instead:
|
|
118
|
+
bad: ${CMD}
|
|
119
|
+
good: ${SUGGESTED}
|
|
120
|
+
|
|
121
|
+
If you genuinely need stderr captured, redirect it explicitly to a file
|
|
122
|
+
or to a separate stream the model reads separately.
|
|
123
|
+
|
|
124
|
+
Background: gist.github.com/yurukusa/5881286479969d5bac0323511dc33ab2
|
|
125
|
+
Anchor issue: github.com/anthropics/claude-code/issues/64334
|
|
126
|
+
|
|
127
|
+
To override once: include "# ACCEPT 2>&1" in the command.
|
|
128
|
+
To disable: export CC_REDIRECT_FRAGMENT_DISABLE=1
|
|
129
|
+
To downgrade to warn-only: unset CC_BLOCK_2_REDIRECT
|
|
130
|
+
|
|
131
|
+
EOF
|
|
132
|
+
exit 2
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
cat >&2 <<EOF
|
|
136
|
+
|
|
137
|
+
NOTICE: Bash command contains \`2>&1\`, which can trigger a multi-minute
|
|
138
|
+
permission-engine hang with token billing climbing during the stall
|
|
139
|
+
(Cluster 25 axis 25C, anchor #64334).
|
|
140
|
+
|
|
141
|
+
Suggested rewrite:
|
|
142
|
+
${SUGGESTED}
|
|
143
|
+
|
|
144
|
+
To block this pattern by default: export CC_BLOCK_2_REDIRECT=1
|
|
145
|
+
To override per-call: include "# ACCEPT 2>&1" in the command.
|
|
146
|
+
|
|
147
|
+
EOF
|
|
148
|
+
|
|
149
|
+
exit 0
|
|
@@ -1,5 +1,18 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
#
|
|
2
3
|
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
4
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
5
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
6
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
7
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
8
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
9
|
+
_nojq_warned="/tmp/cc-nojq-warned-redis-flushall-guard-$PPID"
|
|
10
|
+
[ -f "$_nojq_warned" ] || {
|
|
11
|
+
echo "WARNING [redis-flushall-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
12
|
+
: > "$_nojq_warned"
|
|
13
|
+
}
|
|
14
|
+
fi
|
|
15
|
+
|
|
3
16
|
INPUT=$(cat)
|
|
4
17
|
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
5
18
|
[[ -z "$COMMAND" ]] && exit 0
|