cc-safe-setup 29.8.0 → 30.0.5
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 +421 -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-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 +12 -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/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 +1718 -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-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-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-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,63 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# false-disk-full-guard.sh — flag the #65880 false "temp filesystem is full" / ENOSPC report
|
|
3
|
+
#
|
|
4
|
+
# Why: Claude Code's Bash tool substitutes
|
|
5
|
+
# "Command output was lost: the temp filesystem at <dir> is full (0MB free).
|
|
6
|
+
# The child process's stdout/stderr writes failed with ENOSPC."
|
|
7
|
+
# into stdout for ANY command with empty stdout AND a non-zero exit code — e.g.
|
|
8
|
+
# `false`, a no-match `grep`, a failed `test -e`, `cmd 2>/dev/null` that exits
|
|
9
|
+
# non-zero — even when the filesystem has terabytes free (anthropics/claude-code
|
|
10
|
+
# #65880, reproduced on 2.1.150-2.1.160).
|
|
11
|
+
#
|
|
12
|
+
# The danger is not cosmetic: the fabricated string is presented to the model AS
|
|
13
|
+
# the command's output, so the model can conclude the disk is full and run
|
|
14
|
+
# destructive cleanup (rm, git prune, docker prune) to "free space" that was never
|
|
15
|
+
# occupied. This hook verifies the claim against real `df` and, when the disk
|
|
16
|
+
# actually has room, tells the model it is the false-positive so it does NOT act
|
|
17
|
+
# destructively.
|
|
18
|
+
#
|
|
19
|
+
# Event: PostToolUse MATCHER: "*"
|
|
20
|
+
# Action: advisory only (stderr), never blocks, fails open.
|
|
21
|
+
#
|
|
22
|
+
# The registration was missing from this header. The installer reads TRIGGER
|
|
23
|
+
# and MATCHER from here and falls back to PreToolUse / Bash when both are
|
|
24
|
+
# absent, so this hook was being registered at a moment where the field it
|
|
25
|
+
# reads is always empty: it installed, it appeared in the settings, and it
|
|
26
|
+
# did nothing. Measured 2026-08-04 across examples/: 14 files were like this.
|
|
27
|
+
# TRIGGER: PostToolUse
|
|
28
|
+
# MATCHER: ""
|
|
29
|
+
|
|
30
|
+
set -u
|
|
31
|
+
|
|
32
|
+
IN=$(cat)
|
|
33
|
+
|
|
34
|
+
# tool_response may be a plain string or an object; try the common shapes.
|
|
35
|
+
RESP=$(printf '%s' "$IN" | jq -r '
|
|
36
|
+
if (.tool_response | type) == "string" then .tool_response
|
|
37
|
+
else (.tool_response.stdout // .tool_response.stderr // .tool_response.output // .tool_response.content // .tool_result // empty)
|
|
38
|
+
end' 2>/dev/null)
|
|
39
|
+
# Fallback: scan the whole payload if structured extraction found nothing.
|
|
40
|
+
[ -z "$RESP" ] && RESP="$IN"
|
|
41
|
+
|
|
42
|
+
# Signature of the #65880 fabricated report.
|
|
43
|
+
printf '%s' "$RESP" | grep -qiE 'temp filesystem at .* is full \(0+ ?MB free\)|writes failed with ENOSPC' || exit 0
|
|
44
|
+
|
|
45
|
+
# Which directory did the message blame? Fall back to TMPDIR / /tmp.
|
|
46
|
+
DIR=$(printf '%s' "$RESP" | grep -oE 'temp filesystem at [^ ]+' | head -1 | sed 's/^temp filesystem at //')
|
|
47
|
+
[ -z "$DIR" ] && DIR="${TMPDIR:-/tmp}"
|
|
48
|
+
# The named session dir may already be gone; climb to an existing ancestor.
|
|
49
|
+
while [ -n "$DIR" ] && [ "$DIR" != "/" ] && [ ! -d "$DIR" ]; do DIR=$(dirname "$DIR"); done
|
|
50
|
+
|
|
51
|
+
AVAIL_KB=$(df -Pk "$DIR" 2>/dev/null | awk 'NR==2{print $4}')
|
|
52
|
+
# Can't verify → fail open, stay silent (don't second-guess a possibly-real ENOSPC).
|
|
53
|
+
case "$AVAIL_KB" in ''|*[!0-9]*) exit 0;; esac
|
|
54
|
+
|
|
55
|
+
# Only contradict the message when the disk genuinely has room (>100 MB).
|
|
56
|
+
if [ "$AVAIL_KB" -gt 102400 ]; then
|
|
57
|
+
AVAIL_H=$(df -Ph "$DIR" 2>/dev/null | awk 'NR==2{print $4}')
|
|
58
|
+
echo "⚠ false-disk-full-guard: the 'temp filesystem is full / ENOSPC' message above is very likely the #65880 false-positive, NOT a real disk-full." >&2
|
|
59
|
+
echo " Verified free space on ${DIR}: ${AVAIL_H:-plenty}. Claude Code substitutes that message for ANY empty-stdout + non-zero-exit command (a no-match grep, a failed test, \`false\`)." >&2
|
|
60
|
+
echo " Do NOT run rm / prune / cleanup to 'free space' — the disk is fine. The real result was: empty output, non-zero exit. Re-run as '<cmd>; echo \"[exit \$?]\"' to recover the true exit code." >&2
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
exit 0
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# feature-deprecation-detector.sh — Detect Claude Code feature deprecations from tool output.
|
|
3
|
+
#
|
|
4
|
+
# Background:
|
|
5
|
+
# On 2026-04-09 the `/buddy` companion was removed in v2.1.97 without changelog mention.
|
|
6
|
+
# Issue #45596 ("Bring Back Buddy") accumulated 1,987 reactions, the second-largest
|
|
7
|
+
# single feature request in anthropics/claude-code history. The structural failure pattern:
|
|
8
|
+
# silent removal, no opt-in deprecation, no migration guidance.
|
|
9
|
+
#
|
|
10
|
+
# This hook detects when a previously-working slash command, skill, or capability
|
|
11
|
+
# suddenly returns "Unknown skill: X" or similar deprecation signals, and surfaces
|
|
12
|
+
# the deprecation context to the operator before they spend time troubleshooting
|
|
13
|
+
# what is actually a removed feature.
|
|
14
|
+
#
|
|
15
|
+
# Trigger: PostToolUse (advisory, exit 0)
|
|
16
|
+
# Detection axes:
|
|
17
|
+
# 1. "Unknown skill: <name>" pattern in tool output → likely deprecated slash command
|
|
18
|
+
# 2. "Command not found: /<name>" pattern → likely removed CLI command
|
|
19
|
+
# 3. "Skill <name> is deprecated" pattern → explicit deprecation notice
|
|
20
|
+
# 4. "This feature has been removed" pattern → explicit removal notice
|
|
21
|
+
#
|
|
22
|
+
# When detected, the hook outputs a NOTICE pointing to:
|
|
23
|
+
# - The Claude Code release notes (where deprecations should be documented)
|
|
24
|
+
# - The cc-safe-setup cluster tracker (community-tracked deprecation patterns)
|
|
25
|
+
# - The relevant GitHub issue cluster if known (e.g. #45596 for /buddy)
|
|
26
|
+
#
|
|
27
|
+
# Environment variables:
|
|
28
|
+
# CC_DEPRECATION_QUIET=1 → suppress all output (default 0)
|
|
29
|
+
# CC_DEPRECATION_KNOWN_REMOVALS=/path → custom known-removal list (one slash command per line)
|
|
30
|
+
|
|
31
|
+
set -eu
|
|
32
|
+
|
|
33
|
+
INPUT=$(cat)
|
|
34
|
+
|
|
35
|
+
# Extract tool output (stderr or stdout). PostToolUse provides tool_response.output.
|
|
36
|
+
TOOL_OUTPUT=$(printf '%s' "$INPUT" | jq -r '.tool_response.output // .tool_response.content // empty' 2>/dev/null || true)
|
|
37
|
+
[ -z "$TOOL_OUTPUT" ] && exit 0
|
|
38
|
+
|
|
39
|
+
# Skip if quiet mode requested
|
|
40
|
+
QUIET="${CC_DEPRECATION_QUIET:-0}"
|
|
41
|
+
if [ "$QUIET" = "1" ]; then
|
|
42
|
+
exit 0
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# Built-in known removals (slash commands or features that have been silently removed)
|
|
46
|
+
# Format: "command|release|context|reference"
|
|
47
|
+
KNOWN_REMOVALS_BUILTIN='
|
|
48
|
+
/buddy|v2.1.97 (2026-04-09)|Companion feature removed without changelog mention|https://github.com/anthropics/claude-code/issues/45596
|
|
49
|
+
'
|
|
50
|
+
|
|
51
|
+
# Allow custom known-removal list via environment
|
|
52
|
+
CUSTOM_LIST="${CC_DEPRECATION_KNOWN_REMOVALS:-}"
|
|
53
|
+
if [ -n "$CUSTOM_LIST" ] && [ -f "$CUSTOM_LIST" ]; then
|
|
54
|
+
KNOWN_REMOVALS_BUILTIN="${KNOWN_REMOVALS_BUILTIN}$(printf '\n')$(cat "$CUSTOM_LIST")"
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
# Detection axis 1: "Unknown skill: X" → check against known removals
|
|
58
|
+
detected_command=""
|
|
59
|
+
detected_context=""
|
|
60
|
+
detected_reference=""
|
|
61
|
+
|
|
62
|
+
# Pattern 1: Unknown skill / Unknown command
|
|
63
|
+
if printf '%s' "$TOOL_OUTPUT" | grep -qE 'Unknown skill:|Unknown command:|Command not found:'; then
|
|
64
|
+
# Extract the command name
|
|
65
|
+
skill_name=$(printf '%s' "$TOOL_OUTPUT" | grep -oE '(Unknown skill: [a-zA-Z0-9_-]+|Unknown command: /[a-zA-Z0-9_-]+|Command not found: /[a-zA-Z0-9_-]+)' | head -1 | sed -E 's/.*[: /]//')
|
|
66
|
+
|
|
67
|
+
if [ -n "$skill_name" ]; then
|
|
68
|
+
# Check known removals
|
|
69
|
+
cmd_key="/${skill_name}"
|
|
70
|
+
line=$(printf '%s' "$KNOWN_REMOVALS_BUILTIN" | grep -F "${cmd_key}|" | head -1)
|
|
71
|
+
if [ -n "$line" ]; then
|
|
72
|
+
detected_command="$cmd_key"
|
|
73
|
+
detected_context=$(printf '%s' "$line" | cut -d'|' -f3)
|
|
74
|
+
detected_reference=$(printf '%s' "$line" | cut -d'|' -f4)
|
|
75
|
+
release_info=$(printf '%s' "$line" | cut -d'|' -f2)
|
|
76
|
+
|
|
77
|
+
cat >&2 <<EOF
|
|
78
|
+
NOTICE: \`${detected_command}\` appears to have been removed from Claude Code.
|
|
79
|
+
Release: ${release_info}
|
|
80
|
+
Context: ${detected_context}
|
|
81
|
+
Reference: ${detected_reference}
|
|
82
|
+
Cluster tracking: https://github.com/yurukusa/cc-safe-setup (deprecation pattern monitoring)
|
|
83
|
+
EOF
|
|
84
|
+
exit 0
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# Unknown command but not in known list — still surface it as a possible deprecation
|
|
88
|
+
cat >&2 <<EOF
|
|
89
|
+
NOTICE: Skill or command \`${skill_name}\` not recognized.
|
|
90
|
+
If this previously worked, it may have been deprecated without changelog notice.
|
|
91
|
+
Check release notes: https://docs.anthropic.com/en/release-notes/claude-code
|
|
92
|
+
Report or check existing reports: https://github.com/anthropics/claude-code/issues?q=${skill_name}
|
|
93
|
+
EOF
|
|
94
|
+
exit 0
|
|
95
|
+
fi
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
# Pattern 2: Explicit deprecation notice
|
|
99
|
+
if printf '%s' "$TOOL_OUTPUT" | grep -qiE 'is deprecated|has been deprecated|has been removed|feature has been removed'; then
|
|
100
|
+
matched_line=$(printf '%s' "$TOOL_OUTPUT" | grep -iE 'is deprecated|has been deprecated|has been removed|feature has been removed' | head -1)
|
|
101
|
+
cat >&2 <<EOF
|
|
102
|
+
NOTICE: Deprecation signal detected in tool output:
|
|
103
|
+
> ${matched_line}
|
|
104
|
+
Check release notes for migration guidance: https://docs.anthropic.com/en/release-notes/claude-code
|
|
105
|
+
EOF
|
|
106
|
+
exit 0
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
exit 0
|
|
File without changes
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# file-edit-backup.sh — Auto-backup files before
|
|
2
|
+
# file-edit-backup.sh — Auto-backup files before they are overwritten
|
|
3
3
|
#
|
|
4
4
|
# Solves: Claude Code overwrites important files and the changes are hard
|
|
5
|
-
# to reverse. This creates a timestamped backup before each
|
|
5
|
+
# to reverse. This creates a timestamped backup before each write,
|
|
6
6
|
# so you can always recover the previous version.
|
|
7
7
|
#
|
|
8
8
|
# Real incidents:
|
|
@@ -13,26 +13,75 @@
|
|
|
13
13
|
# Backups go to ~/.claude/file-backups/ with timestamps.
|
|
14
14
|
# Old backups (>7 days) are auto-cleaned to prevent disk bloat.
|
|
15
15
|
#
|
|
16
|
-
#
|
|
16
|
+
# Covers BOTH paths by which a file gets overwritten:
|
|
17
|
+
# 1. The Edit / Write tools -> tool_input.file_path
|
|
18
|
+
# 2. Shell commands run via Bash -> redirection (> >>), tee, mv
|
|
19
|
+
#
|
|
20
|
+
# Path 2 was reported by a reader (2026-07-17) as the biggest hole in this
|
|
21
|
+
# hook: an agent writing through Bash has the same destructive power as
|
|
22
|
+
# Write, but used to slip past this backup entirely. Extraction below is
|
|
23
|
+
# deliberately generous — a spurious backup costs one file copy, a missed
|
|
24
|
+
# one costs the file.
|
|
25
|
+
#
|
|
26
|
+
# TRIGGER: PreToolUse MATCHER: "Edit|Write|Bash"
|
|
17
27
|
|
|
18
28
|
INPUT=$(cat)
|
|
19
29
|
TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
|
|
20
|
-
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
|
|
21
|
-
|
|
22
|
-
[ -z "$FILE" ] && exit 0
|
|
23
|
-
[ ! -f "$FILE" ] && exit 0 # New file, nothing to backup
|
|
24
30
|
|
|
25
31
|
BACKUP_DIR="$HOME/.claude/file-backups"
|
|
26
|
-
mkdir -p "$BACKUP_DIR"
|
|
27
32
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
backup_one() {
|
|
34
|
+
local target="$1"
|
|
35
|
+
[ -z "$target" ] && return 0
|
|
36
|
+
# Strip quotes left over from the command line
|
|
37
|
+
target="${target%\"}"; target="${target#\"}"
|
|
38
|
+
target="${target%\'}"; target="${target#\'}"
|
|
39
|
+
case "$target" in
|
|
40
|
+
/dev/*|/proc/*|/sys/*) return 0 ;; # not real files
|
|
41
|
+
"~"/*) target="$HOME/${target#\~/}" ;;
|
|
42
|
+
esac
|
|
43
|
+
[ ! -f "$target" ] && return 0 # new file, nothing to lose
|
|
44
|
+
[ -L "$target" ] && return 0 # don't follow symlinks
|
|
45
|
+
mkdir -p "$BACKUP_DIR" 2>/dev/null
|
|
46
|
+
local stamp safe
|
|
47
|
+
stamp=$(date +%Y%m%d-%H%M%S)
|
|
48
|
+
safe=$(printf '%s' "$target" | tr '/' '_' | sed 's/^_//')
|
|
49
|
+
# `--` matters: an extracted path starting with "-" would otherwise be
|
|
50
|
+
# read by cp as an option (e.g. a file literally named "-r").
|
|
51
|
+
cp -- "$target" "${BACKUP_DIR}/${safe}.${stamp}" 2>/dev/null
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if [ "$TOOL" = "Bash" ]; then
|
|
55
|
+
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
56
|
+
[ -z "$COMMAND" ] && exit 0
|
|
57
|
+
|
|
58
|
+
# 1. Redirection: > file and >> file.
|
|
59
|
+
# The [^&] guard keeps ">&2" and "2>&1" from being read as filenames.
|
|
60
|
+
while read -r hit; do
|
|
61
|
+
[ -n "$hit" ] && backup_one "$hit"
|
|
62
|
+
done < <(printf '%s' "$COMMAND" \
|
|
63
|
+
| grep -oE '>>?[[:space:]]*[^&|;[:space:]]+' \
|
|
64
|
+
| sed -E 's/^>>?[[:space:]]*//')
|
|
65
|
+
|
|
66
|
+
# 2. tee (with or without -a) — the operand is a destination
|
|
67
|
+
while read -r hit; do
|
|
68
|
+
[ -n "$hit" ] && backup_one "$hit"
|
|
69
|
+
done < <(printf '%s' "$COMMAND" \
|
|
70
|
+
| grep -oE '\btee[[:space:]]+(-a[[:space:]]+)?[^|;&[:space:]]+' \
|
|
71
|
+
| sed -E 's/^tee[[:space:]]+(-a[[:space:]]+)?//')
|
|
32
72
|
|
|
33
|
-
|
|
73
|
+
# 3. mv — the destination is overwritten silently when it already exists
|
|
74
|
+
while read -r hit; do
|
|
75
|
+
[ -n "$hit" ] && backup_one "$hit"
|
|
76
|
+
done < <(printf '%s' "$COMMAND" \
|
|
77
|
+
| grep -oE '\bmv[[:space:]]+(-[a-zA-Z]+[[:space:]]+)*[^|;&[:space:]]+[[:space:]]+[^|;&[:space:]]+' \
|
|
78
|
+
| awk '{print $NF}')
|
|
79
|
+
else
|
|
80
|
+
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
|
|
81
|
+
backup_one "$FILE"
|
|
82
|
+
fi
|
|
34
83
|
|
|
35
84
|
# Clean old backups (>7 days)
|
|
36
|
-
find "$BACKUP_DIR" -type f -mtime +7 -delete 2>/dev/null
|
|
85
|
+
[ -d "$BACKUP_DIR" ] && find "$BACKUP_DIR" -type f -mtime +7 -delete 2>/dev/null
|
|
37
86
|
|
|
38
87
|
exit 0
|
|
File without changes
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
#
|
|
3
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-file-size-limit-$PPID"
|
|
10
|
+
[ -f "$_nojq_warned" ] || {
|
|
11
|
+
echo "WARNING [file-size-limit]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
12
|
+
: > "$_nojq_warned"
|
|
13
|
+
}
|
|
14
|
+
fi
|
|
15
|
+
|
|
4
16
|
INPUT=$(cat)
|
|
5
17
|
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
6
18
|
CONTENT=$(echo "$INPUT" | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
@@ -15,6 +15,18 @@
|
|
|
15
15
|
|
|
16
16
|
set -euo pipefail
|
|
17
17
|
|
|
18
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
19
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
20
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
21
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
22
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
23
|
+
_nojq_warned="/tmp/cc-nojq-warned-financial-operation-guard-$PPID"
|
|
24
|
+
[ -f "$_nojq_warned" ] || {
|
|
25
|
+
echo "WARNING [financial-operation-guard]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
26
|
+
: > "$_nojq_warned"
|
|
27
|
+
}
|
|
28
|
+
fi
|
|
29
|
+
|
|
18
30
|
INPUT=$(cat)
|
|
19
31
|
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
20
32
|
[ -z "$CMD" ] && 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-firewall-guard-$PPID"
|
|
28
|
+
[ -f "$_nojq_warned" ] || {
|
|
29
|
+
echo "WARNING [firewall-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
|
|
|
@@ -11,6 +11,29 @@
|
|
|
11
11
|
# MATCHER: "Bash"
|
|
12
12
|
#
|
|
13
13
|
# See: https://github.com/anthropics/claude-code/issues/7490
|
|
14
|
+
#
|
|
15
|
+
# Fixed 2026-08-03. This hook returned `permissionDecision: "allow"` on every
|
|
16
|
+
# command it wrapped — which is nearly every command, since the skip list held
|
|
17
|
+
# ten builtins. The approval was never a judgement about the command. It was the
|
|
18
|
+
# carrier for `updatedInput`, and the rewrite came with a signature attached.
|
|
19
|
+
#
|
|
20
|
+
# Measured against the shipped copy, over 20 destructive or credential-reading
|
|
21
|
+
# commands with no separator in them at all: **18 were approved**, including
|
|
22
|
+
# `sudo rm -rf`, `dd if=/dev/zero of=/dev/sda`, `mkfs.ext4`, `curl … | sh` and
|
|
23
|
+
# `git push --force`. This is a different defect from the first-command-position
|
|
24
|
+
# one fixed in #937/#940/#941/#942/#943/#947 — nothing here was being missed
|
|
25
|
+
# past a separator. The hook simply approved whatever it wrapped.
|
|
26
|
+
#
|
|
27
|
+
# Now the approval and the rewrite are separated:
|
|
28
|
+
# - the command is rewritten for fish either way, because that is the job
|
|
29
|
+
# - `permissionDecision: "allow"` is emitted only when every command position
|
|
30
|
+
# qualifies on its own
|
|
31
|
+
#
|
|
32
|
+
# Whether `updatedInput` alone (with no decision) is honoured is not documented,
|
|
33
|
+
# and is deliberately not relied on here: if it is, an unqualified command gets
|
|
34
|
+
# wrapped and still goes through the normal permission prompt; if it is not, the
|
|
35
|
+
# command is not wrapped and goes through the normal permission prompt. Both
|
|
36
|
+
# branches end at the prompt, which is the point.
|
|
14
37
|
# ================================================================
|
|
15
38
|
|
|
16
39
|
INPUT=$(cat)
|
|
@@ -23,15 +46,110 @@ echo "$COMMAND" | grep -q '^fish -c' && exit 0
|
|
|
23
46
|
# Skip simple builtins that work identically in any shell
|
|
24
47
|
echo "$COMMAND" | grep -qE '^\s*(cd|echo|cat|ls|pwd|true|false|test|mkdir|touch|rm|cp|mv)\b' && exit 0
|
|
25
48
|
|
|
49
|
+
# ---------------------------------------------------------------- qualifying
|
|
50
|
+
# Command words that carry no destructive form of their own. `git` and the
|
|
51
|
+
# interpreters are handled below, because for those the word says nothing.
|
|
52
|
+
cc_base_ok() {
|
|
53
|
+
case "$1" in
|
|
54
|
+
cat|head|tail|less|more|wc|file|stat|du|df|ls|tree|\
|
|
55
|
+
which|whereis|type|realpath|readlink|basename|dirname|\
|
|
56
|
+
grep|rg|ag|ack|sort|uniq|tr|cut|column|nl|rev|\
|
|
57
|
+
echo|printf|true|false|pwd|date|uname|hostname|whoami|id|\
|
|
58
|
+
jq|yq|cd|\
|
|
59
|
+
tsc|eslint|prettier|jest|vitest|pytest)
|
|
60
|
+
return 0 ;;
|
|
61
|
+
esac
|
|
62
|
+
return 1
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
cc_segment_base() {
|
|
66
|
+
printf '%s' "$1" \
|
|
67
|
+
| sed -E 's/^[[:space:]]+//; s/^([A-Za-z_][A-Za-z0-9_]*=[^[:space:]]*[[:space:]]+)*//' \
|
|
68
|
+
| awk '{print $1}' \
|
|
69
|
+
| sed 's|.*/||'
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
# Build tool subcommands that neither destroy history nor run fetched code.
|
|
73
|
+
# One line on purpose: inside single quotes a trailing backslash is a literal
|
|
74
|
+
# backslash-newline, not a continuation, and the pattern silently stops matching.
|
|
75
|
+
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:]]|$)'
|
|
76
|
+
|
|
77
|
+
# `git branch` reads; `git branch -D main` deletes one. Same first two words.
|
|
78
|
+
CC_GIT_DESTRUCTIVE_RE='^[[:space:]]*git[[:space:]]+(branch|tag)[[:space:]]+-([dDmM]|-delete|-move)([[:space:]]|$)'
|
|
79
|
+
|
|
80
|
+
cc_segment_ok() {
|
|
81
|
+
local seg="$1" base
|
|
82
|
+
base=$(cc_segment_base "$seg")
|
|
83
|
+
[ -z "$base" ] && return 1
|
|
84
|
+
|
|
85
|
+
# find reads only while no predicate acts on what it finds
|
|
86
|
+
if [ "$base" = "find" ]; then
|
|
87
|
+
printf '%s' "$seg" \
|
|
88
|
+
| grep -qE '(^|[[:space:]])-(delete|exec|execdir|ok|okdir|fprintf?|fls|fprint0)([[:space:]]|$)' \
|
|
89
|
+
&& return 1
|
|
90
|
+
return 0
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# sed rewrites the file in place with -i
|
|
94
|
+
if [ "$base" = "sed" ]; then
|
|
95
|
+
printf '%s' "$seg" | grep -qE '(^|[[:space:]])-[a-zA-Z]*i' && return 1
|
|
96
|
+
return 0
|
|
97
|
+
fi
|
|
98
|
+
[ "$base" = "awk" ] && return 0
|
|
99
|
+
|
|
100
|
+
cc_base_ok "$base" && return 0
|
|
101
|
+
|
|
102
|
+
printf '%s' "$seg" | grep -qE "$CC_GIT_DESTRUCTIVE_RE" && return 1
|
|
103
|
+
printf '%s' "$seg" | grep -qE "$CC_SUBCMD_RE" && return 0
|
|
104
|
+
|
|
105
|
+
return 1
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
QUALIFIES=1
|
|
109
|
+
|
|
110
|
+
# A substitution or a backtick carries a command no string-level read can see.
|
|
111
|
+
case "$COMMAND" in
|
|
112
|
+
*'$('*|*'`'*) QUALIFIES=0 ;;
|
|
113
|
+
esac
|
|
114
|
+
# A redirection writes.
|
|
115
|
+
case "$COMMAND" in
|
|
116
|
+
*'>'*) QUALIFIES=0 ;;
|
|
117
|
+
esac
|
|
118
|
+
|
|
119
|
+
if [ "$QUALIFIES" -eq 1 ]; then
|
|
120
|
+
IDX=0
|
|
121
|
+
while IFS= read -r SEG; do
|
|
122
|
+
SEG="${SEG#"${SEG%%[![:space:]]*}"}"
|
|
123
|
+
SEG="${SEG%"${SEG##*[![:space:]]}"}"
|
|
124
|
+
[ -z "$SEG" ] && continue
|
|
125
|
+
if ! cc_segment_ok "$SEG"; then QUALIFIES=0; break; fi
|
|
126
|
+
IDX=$((IDX + 1))
|
|
127
|
+
done <<EOF
|
|
128
|
+
$(printf '%s' "$COMMAND" | tr ';&|' '\n\n\n')
|
|
129
|
+
EOF
|
|
130
|
+
[ "$IDX" -eq 0 ] && QUALIFIES=0
|
|
131
|
+
fi
|
|
132
|
+
|
|
133
|
+
# ---------------------------------------------------------------- rewrite
|
|
26
134
|
# Escape single quotes for fish -c '...'
|
|
27
135
|
ESCAPED=$(printf '%s' "$COMMAND" | sed "s/'/'\\\\''/g")
|
|
28
136
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
137
|
+
if [ "$QUALIFIES" -eq 1 ]; then
|
|
138
|
+
jq -n --arg cmd "fish -c '$ESCAPED'" '{
|
|
139
|
+
hookSpecificOutput: {
|
|
140
|
+
hookEventName: "PreToolUse",
|
|
141
|
+
permissionDecision: "allow",
|
|
142
|
+
updatedInput: { command: $cmd }
|
|
143
|
+
}
|
|
144
|
+
}'
|
|
145
|
+
else
|
|
146
|
+
# rewrite without signing off on it
|
|
147
|
+
jq -n --arg cmd "fish -c '$ESCAPED'" '{
|
|
148
|
+
hookSpecificOutput: {
|
|
149
|
+
hookEventName: "PreToolUse",
|
|
150
|
+
updatedInput: { command: $cmd }
|
|
151
|
+
}
|
|
152
|
+
}'
|
|
153
|
+
fi
|
|
36
154
|
|
|
37
155
|
exit 0
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# flask-static-route-guard.sh — Warn when a catch-all static
|
|
4
|
+
# route would expose .env / .git / source / db files to the web
|
|
5
|
+
#
|
|
6
|
+
# Solves: Claude routinely recommends a Flask catch-all static
|
|
7
|
+
# route that serves the application's own directory, so anyone can
|
|
8
|
+
# request /.env, /.git/config, /app.py, /data.db over the public
|
|
9
|
+
# web and receive secrets, source, and databases. Reported in
|
|
10
|
+
# anthropics/claude-code#65517.
|
|
11
|
+
#
|
|
12
|
+
# The dangerous shape (all three together):
|
|
13
|
+
# 1. a catch-all route capturing an arbitrary path (<path:...>)
|
|
14
|
+
# 2. a send_from_directory()/send_file() call
|
|
15
|
+
# 3. serving from the app/module dir or cwd (dirname(__file__),
|
|
16
|
+
# os.getcwd(), '.') with no static-subdir scoping and no
|
|
17
|
+
# dotfile guard
|
|
18
|
+
#
|
|
19
|
+
# This is a WARNING, not a block — Claude can still write the code,
|
|
20
|
+
# but the operator (and Claude) see the exposure and the fix before
|
|
21
|
+
# it ships. Heuristic by design; it stays quiet when a mitigation
|
|
22
|
+
# (a dedicated static/ subdir, secure_filename, or an explicit
|
|
23
|
+
# dotfile/.env rejection) is present.
|
|
24
|
+
#
|
|
25
|
+
# Usage: Add to settings.json as a PreToolUse hook
|
|
26
|
+
#
|
|
27
|
+
# {
|
|
28
|
+
# "hooks": {
|
|
29
|
+
# "PreToolUse": [{
|
|
30
|
+
# "matcher": "Edit|Write",
|
|
31
|
+
# "hooks": [{ "type": "command", "command": "~/.claude/hooks/flask-static-route-guard.sh" }]
|
|
32
|
+
# }]
|
|
33
|
+
# }
|
|
34
|
+
# }
|
|
35
|
+
# ================================================================
|
|
36
|
+
#
|
|
37
|
+
# TRIGGER: PreToolUse MATCHER: "Edit|Write"
|
|
38
|
+
|
|
39
|
+
INPUT=$(cat)
|
|
40
|
+
|
|
41
|
+
TOOL=$(printf '%s' "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
|
|
42
|
+
case "$TOOL" in
|
|
43
|
+
Write|Edit|MultiEdit) ;;
|
|
44
|
+
*) exit 0 ;;
|
|
45
|
+
esac
|
|
46
|
+
|
|
47
|
+
FILE=$(printf '%s' "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
|
|
48
|
+
# Only Python files can host a Flask route. Skip anything else.
|
|
49
|
+
case "$FILE" in
|
|
50
|
+
*.py) ;;
|
|
51
|
+
"" ) ;; # some Edit payloads omit file_path; still scan content
|
|
52
|
+
*) exit 0 ;;
|
|
53
|
+
esac
|
|
54
|
+
|
|
55
|
+
# Content of the write: Write uses .content, Edit uses .new_string.
|
|
56
|
+
CONTENT=$(printf '%s' "$INPUT" | jq -r '.tool_input.content // .tool_input.new_string // empty' 2>/dev/null)
|
|
57
|
+
[[ -z "$CONTENT" ]] && exit 0
|
|
58
|
+
|
|
59
|
+
# 1. catch-all path capture (Flask's <path:...> converter)
|
|
60
|
+
echo "$CONTENT" | grep -qE '<path:[A-Za-z_][A-Za-z0-9_]*>' || exit 0
|
|
61
|
+
|
|
62
|
+
# 2. a file-serving call
|
|
63
|
+
echo "$CONTENT" | grep -qE 'send_from_directory\(|send_file\(' || exit 0
|
|
64
|
+
|
|
65
|
+
# 3. served base is the app dir or cwd (the exposure), not a scoped subdir
|
|
66
|
+
echo "$CONTENT" | grep -qE "dirname\(__file__\)|abspath\(__file__\)|os\.getcwd\(\)|send_from_directory\([[:space:]]*['\"]\.?['\"]" || exit 0
|
|
67
|
+
|
|
68
|
+
# Suppress when a clear mitigation is present:
|
|
69
|
+
# - serving from a dedicated static/templates/public/assets subdir
|
|
70
|
+
# - secure_filename() sanitisation
|
|
71
|
+
# - an explicit rejection of dotfiles / .env
|
|
72
|
+
if echo "$CONTENT" | grep -qE "secure_filename\(|send_from_directory\(.*['\"](static|templates|public|assets|dist|build)['\"]|os\.path\.join\(.*['\"](static|templates|public|assets|dist|build)['\"]"; then
|
|
73
|
+
exit 0
|
|
74
|
+
fi
|
|
75
|
+
if echo "$CONTENT" | grep -qE "startswith\(['\"]\.['\"]\)|['\"]\.env['\"]|['\"]\.git['\"]|\babort\(40[34]\)" ; then
|
|
76
|
+
# The code already reasons about dotfiles / blocks paths — assume guarded.
|
|
77
|
+
exit 0
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
echo "WARNING: This Flask catch-all route serves the app's own directory to the web." >&2
|
|
81
|
+
echo "Anyone can request /.env, /.git/config, /*.py, or /*.db and receive secrets," >&2
|
|
82
|
+
echo "source code, and databases (anthropics/claude-code#65517)." >&2
|
|
83
|
+
echo "Fix: serve only a dedicated subdirectory and reject dotfiles, e.g." >&2
|
|
84
|
+
echo " STATIC_DIR = os.path.join(os.path.dirname(__file__), 'static')" >&2
|
|
85
|
+
echo " if not path or path.startswith('.') or '..' in path: abort(404)" >&2
|
|
86
|
+
echo " return send_from_directory(STATIC_DIR, path)" >&2
|
|
87
|
+
echo "Never serve the directory that contains .env, .git, or source files." >&2
|
|
88
|
+
|
|
89
|
+
exit 0
|