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
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# mcp-routine-approval-detector.sh — Surface the May 2026 routine-approval cluster
|
|
3
|
+
#
|
|
4
|
+
# PROBLEM (cluster, active since ~2026-05-20):
|
|
5
|
+
# Scheduled and Remote Claude.ai Routines silently fail every MCP tool call
|
|
6
|
+
# on Anthropic-hosted connectors (Gmail, Calendar, Microsoft 365, Notion,
|
|
7
|
+
# Slack, Datadog, Atlassian, Snowflake, Linear, Granola) with:
|
|
8
|
+
#
|
|
9
|
+
# Streamable HTTP error: Error POSTing to endpoint:
|
|
10
|
+
# MCP tool call requires approval
|
|
11
|
+
#
|
|
12
|
+
# Cluster anchors: #61015 (52r/40c), #61027 (33r/18c), #61097 (6r/11c,
|
|
13
|
+
# has architectural fix proposal), #61044 (3r/3c, open).
|
|
14
|
+
#
|
|
15
|
+
# The routine has no UI surface to approve the prompt, so the call becomes
|
|
16
|
+
# a permanent no-op. Custom user-registered MCP servers work fine in the
|
|
17
|
+
# same routine — the bug is scoped to the CCR proxy's approval gate.
|
|
18
|
+
#
|
|
19
|
+
# HOW THIS HELPS:
|
|
20
|
+
# PostToolUse hook on mcp__* matcher. Reads tool_result. If the error
|
|
21
|
+
# string matches the cluster signature, writes a structured diagnostic
|
|
22
|
+
# receipt under ~/.claude/state/mcp-routine-approval-blocks/ and emits
|
|
23
|
+
# a stderr warning so the operator sees the silent failure.
|
|
24
|
+
#
|
|
25
|
+
# The hook does NOT block the failure — the call has already failed on
|
|
26
|
+
# the server side. The hook surfaces it.
|
|
27
|
+
#
|
|
28
|
+
# RECEIPT FORMAT (one JSON file per block):
|
|
29
|
+
# {
|
|
30
|
+
# "blocked_at": "2026-05-25T12:00:00Z",
|
|
31
|
+
# "tool_name": "mcp__claude_ai_Gmail__search_threads",
|
|
32
|
+
# "server": "claude_ai_Gmail",
|
|
33
|
+
# "operation": "search_threads",
|
|
34
|
+
# "session_id": "<from input>",
|
|
35
|
+
# "error_excerpt": "Streamable HTTP error: ..."
|
|
36
|
+
# }
|
|
37
|
+
#
|
|
38
|
+
# CONFIG (all optional):
|
|
39
|
+
# CC_MCP_ROUTINE_BLOCK_DIR receipt directory (default: ~/.claude/state/mcp-routine-approval-blocks)
|
|
40
|
+
# CC_MCP_ROUTINE_BLOCK_DISABLE=1 skip the hook entirely
|
|
41
|
+
# CC_MCP_ROUTINE_BLOCK_WEBHOOK if set to a URL, POST a JSON body on each block
|
|
42
|
+
# CC_MCP_ROUTINE_BLOCK_QUIET=1 suppress the stderr warning (still writes receipt)
|
|
43
|
+
#
|
|
44
|
+
# TRIGGER: PostToolUse
|
|
45
|
+
# MATCHER: mcp__.*
|
|
46
|
+
#
|
|
47
|
+
# OPERATOR NEXT STEPS (printed in stderr warning):
|
|
48
|
+
# - Confirm cluster signature via the Fallback Architecture Gist:
|
|
49
|
+
# https://gist.github.com/yurukusa/7ed7176a8e79ea4635995d717b9af703
|
|
50
|
+
# - Subscribe to the open anchor for the fix-landed signal:
|
|
51
|
+
# https://github.com/anthropics/claude-code/issues/61044
|
|
52
|
+
# - Aggregate receipts to see how many blocks happened today:
|
|
53
|
+
# find ~/.claude/state/mcp-routine-approval-blocks -mtime -1 | wc -l
|
|
54
|
+
|
|
55
|
+
set -u
|
|
56
|
+
|
|
57
|
+
[ "${CC_MCP_ROUTINE_BLOCK_DISABLE:-0}" = "1" ] && exit 0
|
|
58
|
+
|
|
59
|
+
INPUT=$(cat)
|
|
60
|
+
|
|
61
|
+
# Need jq for structured field extraction; silent skip if missing
|
|
62
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
63
|
+
exit 0
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
TOOL=$(printf '%s' "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
|
|
67
|
+
[ -z "$TOOL" ] && exit 0
|
|
68
|
+
|
|
69
|
+
# Only inspect MCP tool calls
|
|
70
|
+
case "$TOOL" in
|
|
71
|
+
mcp__*) ;;
|
|
72
|
+
*) exit 0 ;;
|
|
73
|
+
esac
|
|
74
|
+
|
|
75
|
+
# Extract the tool result text (could be string or structured)
|
|
76
|
+
RESULT_TEXT=$(printf '%s' "$INPUT" | jq -r '
|
|
77
|
+
.tool_result // .tool_response // "" |
|
|
78
|
+
if type == "string" then .
|
|
79
|
+
elif type == "object" then (.content // .text // .error // "" | tostring)
|
|
80
|
+
elif type == "array" then map(tostring) | join(" ")
|
|
81
|
+
else tostring end
|
|
82
|
+
' 2>/dev/null)
|
|
83
|
+
|
|
84
|
+
[ -z "$RESULT_TEXT" ] && exit 0
|
|
85
|
+
|
|
86
|
+
# Cluster signature: the exact error string the four anchor issues report
|
|
87
|
+
SIG_PRIMARY="MCP tool call requires approval"
|
|
88
|
+
SIG_SECONDARY="Streamable HTTP error"
|
|
89
|
+
|
|
90
|
+
# Both signatures present = high-confidence cluster match
|
|
91
|
+
if ! printf '%s' "$RESULT_TEXT" | grep -qF "$SIG_PRIMARY"; then
|
|
92
|
+
exit 0
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# At this point we have a confirmed cluster hit. Write a receipt.
|
|
96
|
+
RECEIPT_DIR="${CC_MCP_ROUTINE_BLOCK_DIR:-${HOME}/.claude/state/mcp-routine-approval-blocks}"
|
|
97
|
+
if ! mkdir -p "$RECEIPT_DIR" 2>/dev/null; then
|
|
98
|
+
# State dir not writable — silent skip per the existing-hook convention
|
|
99
|
+
exit 0
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
SESSION_ID=$(printf '%s' "$INPUT" | jq -r '.session_id // empty' 2>/dev/null)
|
|
103
|
+
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
104
|
+
|
|
105
|
+
# Server / operation extraction. Tool names look like mcp__<server>__<operation>
|
|
106
|
+
# where server can itself contain underscores (e.g. claude_ai_Gmail).
|
|
107
|
+
# The separator is the double underscore __, not a single _.
|
|
108
|
+
TOOL_REST="${TOOL#mcp__}"
|
|
109
|
+
SERVER="${TOOL_REST%%__*}"
|
|
110
|
+
OPERATION="${TOOL_REST#*__}"
|
|
111
|
+
|
|
112
|
+
# Truncate error excerpt to keep receipt files small
|
|
113
|
+
ERROR_EXCERPT=$(printf '%s' "$RESULT_TEXT" | head -c 400)
|
|
114
|
+
|
|
115
|
+
# Receipt filename: timestamp + tool + short hash of error
|
|
116
|
+
SAFE_TOOL=$(printf '%s' "$TOOL" | tr -c 'A-Za-z0-9_-' '_')
|
|
117
|
+
RECEIPT_NAME="${TIMESTAMP//:/-}-${SAFE_TOOL}.json"
|
|
118
|
+
RECEIPT_PATH="${RECEIPT_DIR}/${RECEIPT_NAME}"
|
|
119
|
+
|
|
120
|
+
if jq -nc \
|
|
121
|
+
--arg ts "$TIMESTAMP" \
|
|
122
|
+
--arg tool "$TOOL" \
|
|
123
|
+
--arg server "$SERVER" \
|
|
124
|
+
--arg op "$OPERATION" \
|
|
125
|
+
--arg sid "$SESSION_ID" \
|
|
126
|
+
--arg err "$ERROR_EXCERPT" \
|
|
127
|
+
'{blocked_at: $ts, tool_name: $tool, server: $server, operation: $op, session_id: $sid, error_excerpt: $err}' \
|
|
128
|
+
> "$RECEIPT_PATH" 2>/dev/null; then
|
|
129
|
+
:
|
|
130
|
+
else
|
|
131
|
+
# Receipt write failed — silent skip
|
|
132
|
+
exit 0
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
# Optional webhook
|
|
136
|
+
if [ -n "${CC_MCP_ROUTINE_BLOCK_WEBHOOK:-}" ] && command -v curl >/dev/null 2>&1; then
|
|
137
|
+
curl -s --max-time 5 -X POST \
|
|
138
|
+
-H "Content-Type: application/json" \
|
|
139
|
+
--data-binary "@${RECEIPT_PATH}" \
|
|
140
|
+
"$CC_MCP_ROUTINE_BLOCK_WEBHOOK" >/dev/null 2>&1 || true
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
# Stderr warning unless quiet
|
|
144
|
+
if [ "${CC_MCP_ROUTINE_BLOCK_QUIET:-0}" != "1" ]; then
|
|
145
|
+
cat >&2 <<EOF
|
|
146
|
+
mcp-routine-approval-detector: silent failure detected on $TOOL
|
|
147
|
+
→ cluster: #61015 / #61027 / #61097 / #61044 (May 2026 routine-approval regression)
|
|
148
|
+
→ receipt: $RECEIPT_PATH
|
|
149
|
+
→ fallback architecture: https://gist.github.com/yurukusa/7ed7176a8e79ea4635995d717b9af703
|
|
150
|
+
→ fix-landed signal: https://github.com/anthropics/claude-code/issues/61044
|
|
151
|
+
EOF
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
exit 0
|
|
@@ -16,6 +16,18 @@
|
|
|
16
16
|
|
|
17
17
|
set -euo pipefail
|
|
18
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-mcp-server-allowlist-$PPID"
|
|
25
|
+
[ -f "$_nojq_warned" ] || {
|
|
26
|
+
echo "WARNING [mcp-server-allowlist]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
27
|
+
: > "$_nojq_warned"
|
|
28
|
+
}
|
|
29
|
+
fi
|
|
30
|
+
|
|
19
31
|
INPUT=$(cat)
|
|
20
32
|
TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
|
|
21
33
|
[ -z "$TOOL" ] && exit 0
|
|
@@ -23,6 +23,18 @@
|
|
|
23
23
|
# }
|
|
24
24
|
# }
|
|
25
25
|
|
|
26
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
27
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
28
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
29
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
30
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
31
|
+
_nojq_warned="/tmp/cc-nojq-warned-mcp-server-guard-$PPID"
|
|
32
|
+
[ -f "$_nojq_warned" ] || {
|
|
33
|
+
echo "WARNING [mcp-server-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
34
|
+
: > "$_nojq_warned"
|
|
35
|
+
}
|
|
36
|
+
fi
|
|
37
|
+
|
|
26
38
|
INPUT=$(cat)
|
|
27
39
|
TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
|
|
28
40
|
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# mcp-startup-bloat-detector.sh — Warn when claude.ai connector
|
|
4
|
+
# sync inflates the System tools context at session start.
|
|
5
|
+
# ================================================================
|
|
6
|
+
# PURPOSE:
|
|
7
|
+
# Pro / Claude.ai-OAuth users inherit every connector configured
|
|
8
|
+
# on their claude.ai account into every CLI session. The MCP
|
|
9
|
+
# tool definitions and authentication entries each consume
|
|
10
|
+
# ~250-330 tokens of context, and at scale they can dominate
|
|
11
|
+
# the context window before the user has typed anything.
|
|
12
|
+
#
|
|
13
|
+
# TRIGGER: SessionStart
|
|
14
|
+
# MATCHER: (none)
|
|
15
|
+
#
|
|
16
|
+
# WHY THIS MATTERS:
|
|
17
|
+
# Issue #50062 (closed 2026-04-19) reported ~100k tokens of
|
|
18
|
+
# silent connector bloat; the v2.1.14 fix added the
|
|
19
|
+
# ENABLE_CLAUDEAI_MCP_SERVERS=false escape hatch.
|
|
20
|
+
#
|
|
21
|
+
# Issue #57235 (filed 2026-05-08, v2.1.133) reports the same
|
|
22
|
+
# pattern at 2.9M tokens — 29x larger — leaving /context at
|
|
23
|
+
# 1,460% before the first user turn. Either the v2.1.14 fix
|
|
24
|
+
# regressed, or a new path bypasses it.
|
|
25
|
+
#
|
|
26
|
+
# This detector reads claude mcp list and warns when the count
|
|
27
|
+
# of claude.ai-prefixed connectors crosses a threshold, giving
|
|
28
|
+
# users a chance to set ENABLE_CLAUDEAI_MCP_SERVERS=false
|
|
29
|
+
# before the bloat hurts them.
|
|
30
|
+
#
|
|
31
|
+
# CONFIGURATION:
|
|
32
|
+
# MCP_BLOAT_THRESHOLD_COUNT number of claude.ai connectors to
|
|
33
|
+
# trigger warning (default: 5)
|
|
34
|
+
# MCP_BLOAT_DETECTOR_DISABLE set to 1 to silence this hook
|
|
35
|
+
#
|
|
36
|
+
# RELATED ISSUES:
|
|
37
|
+
# https://github.com/anthropics/claude-code/issues/50062
|
|
38
|
+
# https://github.com/anthropics/claude-code/issues/57235
|
|
39
|
+
# ================================================================
|
|
40
|
+
|
|
41
|
+
set -u
|
|
42
|
+
|
|
43
|
+
[ "${MCP_BLOAT_DETECTOR_DISABLE:-0}" = "1" ] && exit 0
|
|
44
|
+
|
|
45
|
+
THRESHOLD="${MCP_BLOAT_THRESHOLD_COUNT:-5}"
|
|
46
|
+
LOG_DIR="${HOME}/.claude/logs"
|
|
47
|
+
mkdir -p "$LOG_DIR" 2>/dev/null
|
|
48
|
+
|
|
49
|
+
INPUT=$(cat 2>/dev/null || true)
|
|
50
|
+
SESSION_ID=$(printf '%s' "$INPUT" | jq -r '.session_id // empty' 2>/dev/null)
|
|
51
|
+
[ -z "$SESSION_ID" ] && SESSION_ID="unknown-$(date +%s)"
|
|
52
|
+
|
|
53
|
+
# One warning per session
|
|
54
|
+
WARN_LOG="$LOG_DIR/mcp-bloat-warned-$SESSION_ID"
|
|
55
|
+
[ -f "$WARN_LOG" ] && exit 0
|
|
56
|
+
|
|
57
|
+
# Need claude binary to inspect MCP state
|
|
58
|
+
if ! command -v claude >/dev/null 2>&1; then
|
|
59
|
+
exit 0
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# Count claude.ai-prefixed connectors. The CLI prints one per line as:
|
|
63
|
+
# claude.ai <Name>: <url> - <status>
|
|
64
|
+
MCP_OUTPUT=$(claude mcp list 2>/dev/null || true)
|
|
65
|
+
[ -z "$MCP_OUTPUT" ] && exit 0
|
|
66
|
+
|
|
67
|
+
COUNT=$(printf '%s\n' "$MCP_OUTPUT" | grep -cE '^claude\.ai[[:space:]]' || true)
|
|
68
|
+
COUNT=${COUNT:-0}
|
|
69
|
+
|
|
70
|
+
if [ "$COUNT" -ge "$THRESHOLD" ]; then
|
|
71
|
+
EST_TOKENS=$((COUNT * 290))
|
|
72
|
+
cat >&2 <<MSG
|
|
73
|
+
mcp-startup-bloat-detector: $COUNT claude.ai connectors auto-loaded
|
|
74
|
+
(estimated ~${EST_TOKENS} tokens of context overhead at ~290 tokens each).
|
|
75
|
+
|
|
76
|
+
If /context shows an unusually high "System tools" load, set
|
|
77
|
+
ENABLE_CLAUDEAI_MCP_SERVERS=false in your shell, remove
|
|
78
|
+
~/.claude/.credentials.json, and re-run /login. OAuth stays;
|
|
79
|
+
the connector sync is what gets disabled.
|
|
80
|
+
|
|
81
|
+
Background: Issue #50062 (closed v2.1.14, ~100k tokens) and
|
|
82
|
+
Issue #57235 (filed 2026-05-08 v2.1.133, ~2.9M tokens).
|
|
83
|
+
MSG
|
|
84
|
+
touch "$WARN_LOG"
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
exit 0
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# mcp-stdio-compatibility-test.sh — MCP regression test harness (Incident 8)
|
|
3
|
+
# Why: v2.1.105 changed PreToolUse additionalContext + stdio framing and
|
|
4
|
+
# broke MCP servers that had worked on v2.1.104. The regression was
|
|
5
|
+
# largely fixed by v2.1.118 but custom MCP servers still need
|
|
6
|
+
# re-validation after every Claude Code upgrade. This harness
|
|
7
|
+
# exercises every MCP server registered in your settings against a
|
|
8
|
+
# known-good suite of calls so you can distinguish "MCP regression"
|
|
9
|
+
# from "auth expired" / "external resource down."
|
|
10
|
+
# Event: standalone CLI, not a Claude Code hook.
|
|
11
|
+
# Usage: bash examples/mcp-stdio-compatibility-test.sh [path-to-settings.json]
|
|
12
|
+
# (defaults to ~/.claude/settings.json)
|
|
13
|
+
# Exit: 0 if all servers OK; 1 if one or more regressions (parse errors,
|
|
14
|
+
# stdio framing failures). Non-regression failures (auth, network)
|
|
15
|
+
# are reported as [AUTH] or [NET] and do not set exit code 1.
|
|
16
|
+
|
|
17
|
+
set -u
|
|
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-mcp-stdio-compatibility-test-$PPID"
|
|
25
|
+
[ -f "$_nojq_warned" ] || {
|
|
26
|
+
echo "WARNING [mcp-stdio-compatibility-test]: 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
|
+
SETTINGS="${1:-${HOME}/.claude/settings.json}"
|
|
32
|
+
LOG_DIR="${HOME}/.claude/logs"
|
|
33
|
+
LOG_FILE="${LOG_DIR}/mcp-compat.log"
|
|
34
|
+
mkdir -p "$LOG_DIR" 2>/dev/null
|
|
35
|
+
|
|
36
|
+
if [ ! -r "$SETTINGS" ]; then
|
|
37
|
+
echo "mcp-stdio-compatibility-test: settings file not readable: $SETTINGS" >&2
|
|
38
|
+
exit 2
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Reject malformed JSON up front so a parse failure isn't reported as
|
|
42
|
+
# "nothing to test" — that would mask a broken config and exit 0.
|
|
43
|
+
if ! jq empty "$SETTINGS" 2>/dev/null; then
|
|
44
|
+
echo "mcp-stdio-compatibility-test: settings file is not valid JSON: $SETTINGS" >&2
|
|
45
|
+
exit 2
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
if ! jq -e '.mcpServers // empty' "$SETTINGS" >/dev/null 2>&1; then
|
|
49
|
+
echo "[info] no mcpServers block in $SETTINGS — nothing to test"
|
|
50
|
+
exit 0
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Pick whichever timeout binary is available; macOS ships only `gtimeout`
|
|
54
|
+
# via coreutils, while Linux usually has `timeout`. Without one of these
|
|
55
|
+
# a misbehaving server could hang the whole probe loop, so fall back to
|
|
56
|
+
# a no-timeout invocation only when we have warned the operator.
|
|
57
|
+
if command -v timeout >/dev/null 2>&1; then
|
|
58
|
+
TIMEOUT_CMD="timeout"
|
|
59
|
+
elif command -v gtimeout >/dev/null 2>&1; then
|
|
60
|
+
TIMEOUT_CMD="gtimeout"
|
|
61
|
+
else
|
|
62
|
+
TIMEOUT_CMD=""
|
|
63
|
+
echo "[warn] no timeout/gtimeout in PATH — server probes may hang on misbehaving servers" >&2
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
SERVERS=$(jq -r '.mcpServers | keys[]' "$SETTINGS" 2>/dev/null)
|
|
67
|
+
if [ -z "$SERVERS" ]; then
|
|
68
|
+
echo "[info] mcpServers block is empty — nothing to test"
|
|
69
|
+
exit 0
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
REGRESSION_COUNT=0
|
|
73
|
+
TS=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
74
|
+
|
|
75
|
+
# Each MCP server speaks JSON-RPC over stdio. A viable smoke test is to
|
|
76
|
+
# send the initialize request and verify the server replies with a valid
|
|
77
|
+
# JSON-RPC response containing serverInfo. Parse errors or non-JSON
|
|
78
|
+
# output indicate the v2.1.105-class regression.
|
|
79
|
+
send_initialize() {
|
|
80
|
+
local cmd="$1"
|
|
81
|
+
local args_json="$2"
|
|
82
|
+
local args_array=()
|
|
83
|
+
if [ -n "$args_json" ] && [ "$args_json" != "null" ]; then
|
|
84
|
+
while IFS= read -r a; do args_array+=("$a"); done < <(printf '%s' "$args_json" | jq -r '.[]' 2>/dev/null)
|
|
85
|
+
fi
|
|
86
|
+
local init_req='{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"cc-safe-setup-compat-test","version":"1.0"}}}'
|
|
87
|
+
if [ -n "$TIMEOUT_CMD" ]; then
|
|
88
|
+
printf '%s\n' "$init_req" | "$TIMEOUT_CMD" 5 "$cmd" "${args_array[@]}" 2>&1
|
|
89
|
+
else
|
|
90
|
+
printf '%s\n' "$init_req" | "$cmd" "${args_array[@]}" 2>&1
|
|
91
|
+
fi
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
for name in $SERVERS; do
|
|
95
|
+
CMD=$(jq -r ".mcpServers[\"$name\"].command // empty" "$SETTINGS" 2>/dev/null)
|
|
96
|
+
ARGS=$(jq -c ".mcpServers[\"$name\"].args // []" "$SETTINGS" 2>/dev/null)
|
|
97
|
+
if [ -z "$CMD" ]; then
|
|
98
|
+
echo "[skip] $name: no command field"
|
|
99
|
+
printf '%s\t%s\t%s\n' "$TS" "$name" "skip-no-command" >> "$LOG_FILE"
|
|
100
|
+
continue
|
|
101
|
+
fi
|
|
102
|
+
if ! command -v "$CMD" >/dev/null 2>&1 && [ ! -x "$CMD" ]; then
|
|
103
|
+
echo "[skip] $name: command not executable ($CMD)"
|
|
104
|
+
printf '%s\t%s\t%s\n' "$TS" "$name" "skip-not-executable" >> "$LOG_FILE"
|
|
105
|
+
continue
|
|
106
|
+
fi
|
|
107
|
+
OUTPUT=$(send_initialize "$CMD" "$ARGS" 2>&1) || true
|
|
108
|
+
RESPONSE=$(printf '%s' "$OUTPUT" | grep -m1 '"jsonrpc"' || true)
|
|
109
|
+
if [ -z "$RESPONSE" ]; then
|
|
110
|
+
echo "[FAIL] $name: no JSON-RPC response (regression candidate)"
|
|
111
|
+
printf '%s\t%s\t%s\n' "$TS" "$name" "regression-no-response" >> "$LOG_FILE"
|
|
112
|
+
REGRESSION_COUNT=$((REGRESSION_COUNT + 1))
|
|
113
|
+
continue
|
|
114
|
+
fi
|
|
115
|
+
if ! printf '%s' "$RESPONSE" | jq -e . >/dev/null 2>&1; then
|
|
116
|
+
echo "[FAIL] $name: non-JSON response (v2.1.105-class regression)"
|
|
117
|
+
printf '%s\t%s\t%s\n' "$TS" "$name" "regression-parse-error" >> "$LOG_FILE"
|
|
118
|
+
REGRESSION_COUNT=$((REGRESSION_COUNT + 1))
|
|
119
|
+
continue
|
|
120
|
+
fi
|
|
121
|
+
ERR=$(printf '%s' "$RESPONSE" | jq -r '.error.code // empty' 2>/dev/null)
|
|
122
|
+
if [ -n "$ERR" ]; then
|
|
123
|
+
MSG=$(printf '%s' "$RESPONSE" | jq -r '.error.message // ""' 2>/dev/null)
|
|
124
|
+
case "$MSG" in
|
|
125
|
+
*auth*|*Auth*|*AUTH*|*permission*|*Permission*)
|
|
126
|
+
echo "[AUTH] $name: $MSG"
|
|
127
|
+
printf '%s\t%s\t%s\n' "$TS" "$name" "auth-$ERR" >> "$LOG_FILE"
|
|
128
|
+
;;
|
|
129
|
+
*network*|*timeout*|*connect*|*DNS*)
|
|
130
|
+
echo "[NET] $name: $MSG"
|
|
131
|
+
printf '%s\t%s\t%s\n' "$TS" "$name" "network-$ERR" >> "$LOG_FILE"
|
|
132
|
+
;;
|
|
133
|
+
*)
|
|
134
|
+
echo "[FAIL] $name: error $ERR — $MSG"
|
|
135
|
+
printf '%s\t%s\t%s\n' "$TS" "$name" "regression-error-$ERR" >> "$LOG_FILE"
|
|
136
|
+
REGRESSION_COUNT=$((REGRESSION_COUNT + 1))
|
|
137
|
+
;;
|
|
138
|
+
esac
|
|
139
|
+
continue
|
|
140
|
+
fi
|
|
141
|
+
echo "[ok] $name"
|
|
142
|
+
printf '%s\t%s\t%s\n' "$TS" "$name" "ok" >> "$LOG_FILE"
|
|
143
|
+
done
|
|
144
|
+
|
|
145
|
+
if [ "$REGRESSION_COUNT" -gt 0 ]; then
|
|
146
|
+
echo
|
|
147
|
+
echo "$REGRESSION_COUNT MCP server(s) have regressions. Review the log:"
|
|
148
|
+
echo " $LOG_FILE"
|
|
149
|
+
echo "Consider pinning an older Claude Code version:"
|
|
150
|
+
echo " npm install -g @anthropic-ai/claude-code@2.1.104"
|
|
151
|
+
exit 1
|
|
152
|
+
fi
|
|
153
|
+
exit 0
|
|
File without changes
|
|
@@ -1,9 +1,50 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
#
|
|
3
|
-
#
|
|
3
|
+
# mcp-tool-guard.sh — Guard destructive / side-effecting MCP tool calls.
|
|
4
|
+
#
|
|
5
|
+
# TRIGGER: PreToolUse
|
|
6
|
+
# MATCHER: ".*" (fires on every tool; the hook self-filters to mcp__ tools.
|
|
7
|
+
# NOTE: the previous "Bash" matcher was wrong — a Bash matcher
|
|
8
|
+
# never sees an mcp__ tool name, so the hook never fired.)
|
|
9
|
+
#
|
|
10
|
+
# Why this exists: an MCP tool can perform a destructive action whose tool NAME
|
|
11
|
+
# looks harmless. The clearest case is browser automation: a model in an
|
|
12
|
+
# auto-approve mode calls e.g. mcp__playwright__browser_click on a "delete"
|
|
13
|
+
# confirmation button and removes production data with no prompt (anthropics/
|
|
14
|
+
# claude-code#65563). The tool name ("browser_click") contains no destructive
|
|
15
|
+
# word, so name-based detection alone misses it.
|
|
16
|
+
#
|
|
17
|
+
# CONFIG (all opt-in; defaults preserve the original warn-only behavior):
|
|
18
|
+
# CC_MCP_WARN_ALL=1 Log every MCP tool call.
|
|
19
|
+
# CC_MCP_BLOCKED_TOOLS="a,b" Hard-block (exit 2) MCP tools matching these.
|
|
20
|
+
# CC_MCP_PROD_HOSTS="h1,h2" Deny any MCP call whose input references these
|
|
21
|
+
# hosts/paths. Reliable for browser navigate
|
|
22
|
+
# (the target URL is in tool_input) — keeps an
|
|
23
|
+
# "investigation" from reaching production.
|
|
24
|
+
# CC_MCP_AUTOMATION_GUARD=off|warn|ask|block (default: warn)
|
|
25
|
+
# How to treat automation tools (click/navigate/
|
|
26
|
+
# fill/type/...) while a permission mode is
|
|
27
|
+
# auto-approving. warn=stderr note; ask=prompt;
|
|
28
|
+
# block=exit 2. Addresses #65563's root cause.
|
|
29
|
+
# CC_MCP_AUTOMATION_TOOLS="click,navigate,fill,type,press,submit,upload"
|
|
30
|
+
# Tool-name substrings treated as automation.
|
|
31
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
32
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
33
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
34
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
35
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
36
|
+
_nojq_warned="/tmp/cc-nojq-warned-mcp-tool-guard-$PPID"
|
|
37
|
+
[ -f "$_nojq_warned" ] || {
|
|
38
|
+
echo "WARNING [mcp-tool-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
39
|
+
: > "$_nojq_warned"
|
|
40
|
+
}
|
|
41
|
+
fi
|
|
42
|
+
|
|
4
43
|
INPUT=$(cat)
|
|
5
44
|
TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
|
|
6
45
|
echo "$TOOL" | grep -q '^mcp__' || exit 0
|
|
46
|
+
MODE=$(echo "$INPUT" | jq -r '.permission_mode // empty' 2>/dev/null)
|
|
47
|
+
INPUT_BLOB=$(echo "$INPUT" | jq -r '.tool_input | tostring' 2>/dev/null)
|
|
7
48
|
if [ "${CC_MCP_WARN_ALL:-0}" = "1" ]; then
|
|
8
49
|
echo "NOTE: MCP tool call: $TOOL" >&2
|
|
9
50
|
fi
|
|
@@ -18,6 +59,65 @@ if [ -n "$BLOCKED" ]; then
|
|
|
18
59
|
fi
|
|
19
60
|
done
|
|
20
61
|
fi
|
|
62
|
+
|
|
63
|
+
# Deny any MCP call that references a configured production host/path. For
|
|
64
|
+
# browser navigate tools the destination URL is in tool_input, so this reliably
|
|
65
|
+
# stops an "investigation" session from reaching production data.
|
|
66
|
+
PROD="${CC_MCP_PROD_HOSTS:-}"
|
|
67
|
+
if [ -n "$PROD" ] && [ -n "$INPUT_BLOB" ]; then
|
|
68
|
+
IFS=',' read -ra HOSTS <<< "$PROD"
|
|
69
|
+
for h in "${HOSTS[@]}"; do
|
|
70
|
+
h=$(echo "$h" | xargs)
|
|
71
|
+
[ -z "$h" ] && continue
|
|
72
|
+
if printf '%s' "$INPUT_BLOB" | grep -qiF "$h"; then
|
|
73
|
+
printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"MCP tool %s targets a production host (%s). Investigate against staging/local, not production."}}\n' "$TOOL" "$h"
|
|
74
|
+
exit 0
|
|
75
|
+
fi
|
|
76
|
+
done
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# #65563: while a permission mode is auto-approving, an automation tool can
|
|
80
|
+
# perform a destructive UI action (e.g. clicking a delete button) that the tool
|
|
81
|
+
# name does not reveal. Escalate such tools so a click cannot auto-run.
|
|
82
|
+
GUARD="${CC_MCP_AUTOMATION_GUARD:-warn}"
|
|
83
|
+
if [ "$GUARD" != "off" ]; then
|
|
84
|
+
case "$MODE" in
|
|
85
|
+
acceptEdits|bypassPermissions|auto|dontAsk)
|
|
86
|
+
AUTOM="${CC_MCP_AUTOMATION_TOOLS:-click,navigate,fill,type,press,submit,upload}"
|
|
87
|
+
IFS=',' read -ra ATOOLS <<< "$AUTOM"
|
|
88
|
+
for a in "${ATOOLS[@]}"; do
|
|
89
|
+
a=$(echo "$a" | xargs)
|
|
90
|
+
[ -z "$a" ] && continue
|
|
91
|
+
if [[ "$TOOL" == *"$a"* ]]; then
|
|
92
|
+
case "$GUARD" in
|
|
93
|
+
# VERSION NOTE (measured 2026-08-13 on 2.1.228; this
|
|
94
|
+
# comment previously claimed the opposite): #77212
|
|
95
|
+
# reported "ask" being silently auto-approved under
|
|
96
|
+
# bypassPermissions — the very mode this branch fires
|
|
97
|
+
# in. It does not reproduce on 2.1.228: interactively,
|
|
98
|
+
# the confirmation appears under both
|
|
99
|
+
# --dangerously-skip-permissions and
|
|
100
|
+
# --permission-mode auto. Control: with the hook removed
|
|
101
|
+
# both modes ran unprompted, so the mode was in effect.
|
|
102
|
+
# Older builds may differ. Use
|
|
103
|
+
# CC_MCP_AUTOMATION_GUARD=block when no operator is
|
|
104
|
+
# present to answer; block is enforced in every mode.
|
|
105
|
+
ask)
|
|
106
|
+
printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"ask","permissionDecisionReason":"Confirm MCP automation action %s — permission mode %s is auto-approving."}}\n' "$TOOL" "$MODE"
|
|
107
|
+
exit 0 ;;
|
|
108
|
+
block)
|
|
109
|
+
echo "BLOCKED: MCP automation tool $TOOL under auto-approve mode $MODE. Re-run in default mode so the action is confirmed." >&2
|
|
110
|
+
exit 2 ;;
|
|
111
|
+
*)
|
|
112
|
+
echo "WARNING: MCP automation tool $TOOL is running under auto-approve mode $MODE — a UI action could change data without a prompt." >&2 ;;
|
|
113
|
+
esac
|
|
114
|
+
break
|
|
115
|
+
fi
|
|
116
|
+
done
|
|
117
|
+
;;
|
|
118
|
+
esac
|
|
119
|
+
fi
|
|
120
|
+
|
|
21
121
|
case "$TOOL" in
|
|
22
122
|
*delete*|*remove*|*drop*|*destroy*|*purge*)
|
|
23
123
|
echo "WARNING: Potentially destructive MCP tool: $TOOL" >&2
|
|
File without changes
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# memory-chain-audit.sh — extractMemories double-cache detector (Incident 7)
|
|
3
|
+
# Why: Claude Code's extractMemories feature fires a background call at the
|
|
4
|
+
# end of each turn to update persistent memory. When the default is ON,
|
|
5
|
+
# this background call carries its own cache chain that roughly doubles
|
|
6
|
+
# the API cost per turn. Users who have not set
|
|
7
|
+
# CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 are paying for the feature silently.
|
|
8
|
+
# Event: PostToolUse MATCHER: "*" (the extractMemories background call
|
|
9
|
+
# fires as a Stop-event after the turn,
|
|
10
|
+
# so we observe it one turn later)
|
|
11
|
+
# Action: Log cumulative main-chain vs extractMemories-chain cost per session.
|
|
12
|
+
# If the ratio is consistently ≥ 1 (extractMemories costs match or
|
|
13
|
+
# exceed the main chain), the log shows the user that the feature is
|
|
14
|
+
# doubling their bill.
|
|
15
|
+
#
|
|
16
|
+
# Review with:
|
|
17
|
+
# awk -F'\t' '{ main+=$3; mem+=$4 } END { if (main>0) printf "main=%d mem=%d ratio=%.2f\n", main, mem, mem/main }' \
|
|
18
|
+
# ~/.claude/logs/memory-chain.log
|
|
19
|
+
#
|
|
20
|
+
# If the ratio is near or above 1 and you do not actively rely on auto-memory,
|
|
21
|
+
# set CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 in your shell rc.
|
|
22
|
+
|
|
23
|
+
set -u
|
|
24
|
+
|
|
25
|
+
LOG_DIR="${HOME}/.claude/logs"
|
|
26
|
+
LOG_FILE="${LOG_DIR}/memory-chain.log"
|
|
27
|
+
mkdir -p "$LOG_DIR" 2>/dev/null
|
|
28
|
+
|
|
29
|
+
INPUT=$(cat)
|
|
30
|
+
|
|
31
|
+
SESSION_ID=$(printf '%s' "$INPUT" | jq -r '.session_id // "unknown"' 2>/dev/null)
|
|
32
|
+
[ "$SESSION_ID" = "unknown" ] && exit 0
|
|
33
|
+
|
|
34
|
+
TRANSCRIPT=$(printf '%s' "$INPUT" | jq -r '.transcript_path // empty' 2>/dev/null)
|
|
35
|
+
[ -z "$TRANSCRIPT" ] && exit 0
|
|
36
|
+
[ ! -r "$TRANSCRIPT" ] && exit 0
|
|
37
|
+
|
|
38
|
+
# Main-chain cost = total input+output for the last assistant turn tagged
|
|
39
|
+
# "main". extractMemories-chain cost = the same for the last turn tagged as
|
|
40
|
+
# a memory call. Tags differ between client versions; we match on the
|
|
41
|
+
# presence of "extractMemories" / "memory" in the request metadata.
|
|
42
|
+
|
|
43
|
+
MAIN=$(tac "$TRANSCRIPT" 2>/dev/null \
|
|
44
|
+
| grep -m1 '"type":"assistant"' \
|
|
45
|
+
| jq -r '(.message.usage.input_tokens // 0) + (.message.usage.output_tokens // 0)' 2>/dev/null)
|
|
46
|
+
|
|
47
|
+
MEM=$(grep 'extractMemor\|"memory"' "$TRANSCRIPT" 2>/dev/null | tail -1 \
|
|
48
|
+
| jq -r '(.message.usage.input_tokens // 0) + (.message.usage.output_tokens // 0)' 2>/dev/null)
|
|
49
|
+
|
|
50
|
+
MAIN=${MAIN:-0}
|
|
51
|
+
MEM=${MEM:-0}
|
|
52
|
+
|
|
53
|
+
TS=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
54
|
+
printf '%s\t%s\t%s\t%s\n' "$TS" "$SESSION_ID" "$MAIN" "$MEM" >> "$LOG_FILE"
|
|
55
|
+
|
|
56
|
+
exit 0
|