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,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
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# memory-orphan-detector.sh — Detect Claude Code memory that may have been
|
|
3
|
+
# orphaned when the working directory was renamed.
|
|
4
|
+
#
|
|
5
|
+
# Solves: #61349 — "[BUG] Memory orphaned when working directory is renamed"
|
|
6
|
+
# Filed 2026-05-22 by adamcopley.
|
|
7
|
+
#
|
|
8
|
+
# Claude Code stores per-project memory at
|
|
9
|
+
# ~/.claude/projects/<encoded-working-dir>/memory/
|
|
10
|
+
# where <encoded-working-dir> is the absolute working directory path with
|
|
11
|
+
# every `/` and `.` rewritten as `-`.
|
|
12
|
+
#
|
|
13
|
+
# When the operator renames or moves a working directory, Claude Code does
|
|
14
|
+
# not migrate the memory. Instead, on next session start it silently creates
|
|
15
|
+
# a fresh empty memory directory at the new encoded path. The old memory
|
|
16
|
+
# directory remains on disk forever — orphaned, not loaded by any session,
|
|
17
|
+
# with no notification to the operator. The accumulated investment (user
|
|
18
|
+
# role, project conventions, validated feedback, references to external
|
|
19
|
+
# systems) is effectively lost.
|
|
20
|
+
#
|
|
21
|
+
# This hook runs on SessionStart and emits a warning when:
|
|
22
|
+
# (a) the CURRENT working directory's memory is empty (≤ N entries), AND
|
|
23
|
+
# (b) the current working directory has substantive git history (suggesting
|
|
24
|
+
# prior work in the project that would have accumulated memory), AND
|
|
25
|
+
# (c) one or more OTHER memory directories on disk have substantive content
|
|
26
|
+
# (≥ M entries or ≥ K bytes), making them candidate orphans
|
|
27
|
+
#
|
|
28
|
+
# All three signals together: high likelihood of an orphaning event. The hook
|
|
29
|
+
# does not block session start. It surfaces the candidate orphan directories
|
|
30
|
+
# so the operator can decide whether to migrate them manually.
|
|
31
|
+
#
|
|
32
|
+
# Path decoding is LOSSY (a `-` in the encoded path could have originated as
|
|
33
|
+
# either a `/` or a literal `-` in the working directory name). This hook
|
|
34
|
+
# does NOT attempt to decode and verify path existence; it uses encoded-form
|
|
35
|
+
# similarity heuristics instead.
|
|
36
|
+
#
|
|
37
|
+
# TRIGGER: SessionStart
|
|
38
|
+
# MATCHER: ""
|
|
39
|
+
#
|
|
40
|
+
# CONFIGURATION (environment variables):
|
|
41
|
+
# CC_PROJECTS_DIR default ~/.claude/projects
|
|
42
|
+
# CC_MEMORY_ORPHAN_DISABLE set to "1" to disable
|
|
43
|
+
# CC_MEMORY_EMPTY_THRESHOLD max entries to consider "empty" (default 1)
|
|
44
|
+
# CC_MEMORY_ORPHAN_THRESHOLD min entries for candidate orphan (default 5)
|
|
45
|
+
# CC_MEMORY_ORPHAN_MIN_BYTES min bytes for candidate orphan (default 2048)
|
|
46
|
+
#
|
|
47
|
+
# USAGE (settings.json):
|
|
48
|
+
# {
|
|
49
|
+
# "hooks": {
|
|
50
|
+
# "SessionStart": [{
|
|
51
|
+
# "matcher": "",
|
|
52
|
+
# "hooks": [{
|
|
53
|
+
# "type": "command",
|
|
54
|
+
# "command": "~/.claude/hooks/memory-orphan-detector.sh"
|
|
55
|
+
# }]
|
|
56
|
+
# }]
|
|
57
|
+
# }
|
|
58
|
+
# }
|
|
59
|
+
|
|
60
|
+
set -uo pipefail
|
|
61
|
+
|
|
62
|
+
[ "${CC_MEMORY_ORPHAN_DISABLE:-0}" = "1" ] && exit 0
|
|
63
|
+
|
|
64
|
+
PROJECTS_DIR="${CC_PROJECTS_DIR:-$HOME/.claude/projects}"
|
|
65
|
+
EMPTY_THRESHOLD="${CC_MEMORY_EMPTY_THRESHOLD:-1}"
|
|
66
|
+
ORPHAN_THRESHOLD="${CC_MEMORY_ORPHAN_THRESHOLD:-5}"
|
|
67
|
+
ORPHAN_MIN_BYTES="${CC_MEMORY_ORPHAN_MIN_BYTES:-2048}"
|
|
68
|
+
|
|
69
|
+
[ ! -d "$PROJECTS_DIR" ] && exit 0
|
|
70
|
+
|
|
71
|
+
CWD="$(pwd)"
|
|
72
|
+
|
|
73
|
+
# Compute the encoded form of the current working directory.
|
|
74
|
+
encode_path() {
|
|
75
|
+
# / → -, . → -
|
|
76
|
+
printf '%s' "$1" | tr '/.' '--'
|
|
77
|
+
}
|
|
78
|
+
CWD_ENCODED="$(encode_path "$CWD")"
|
|
79
|
+
CURRENT_MEMORY_DIR="$PROJECTS_DIR/${CWD_ENCODED}/memory"
|
|
80
|
+
|
|
81
|
+
# (a) Is current memory empty?
|
|
82
|
+
CURRENT_COUNT=0
|
|
83
|
+
if [ -d "$CURRENT_MEMORY_DIR" ]; then
|
|
84
|
+
CURRENT_COUNT=$(find "$CURRENT_MEMORY_DIR" -maxdepth 1 -type f 2>/dev/null | wc -l)
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# Not empty → likely fine. Exit silently.
|
|
88
|
+
if [ "$CURRENT_COUNT" -gt "$EMPTY_THRESHOLD" ]; then
|
|
89
|
+
exit 0
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
# (b) Does current working directory have git history?
|
|
93
|
+
HAS_GIT_HISTORY=0
|
|
94
|
+
if [ -d "$CWD/.git" ] || git -C "$CWD" rev-parse --git-dir > /dev/null 2>&1; then
|
|
95
|
+
COMMITS=$(git -C "$CWD" rev-list --count HEAD 2>/dev/null || echo 0)
|
|
96
|
+
if [ "$COMMITS" -gt 5 ]; then
|
|
97
|
+
HAS_GIT_HISTORY=1
|
|
98
|
+
fi
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
# No git history → not a strong signal of prior work. Exit silently.
|
|
102
|
+
if [ "$HAS_GIT_HISTORY" -eq 0 ]; then
|
|
103
|
+
exit 0
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
# (c) Find candidate orphans: other memory directories with content.
|
|
107
|
+
ORPHAN_CANDIDATES=()
|
|
108
|
+
for d in "$PROJECTS_DIR"/*/; do
|
|
109
|
+
[ -d "$d" ] || continue
|
|
110
|
+
base="${d%/}"
|
|
111
|
+
base="${base##*/}"
|
|
112
|
+
# Skip current
|
|
113
|
+
if [ "$base" = "$CWD_ENCODED" ]; then continue; fi
|
|
114
|
+
mem_dir="$d/memory"
|
|
115
|
+
[ ! -d "$mem_dir" ] && continue
|
|
116
|
+
cnt=$(find "$mem_dir" -maxdepth 1 -type f 2>/dev/null | wc -l)
|
|
117
|
+
bytes=$(du -sb "$mem_dir" 2>/dev/null | awk '{print $1}')
|
|
118
|
+
bytes="${bytes:-0}"
|
|
119
|
+
if [ "$cnt" -ge "$ORPHAN_THRESHOLD" ] && [ "$bytes" -ge "$ORPHAN_MIN_BYTES" ]; then
|
|
120
|
+
# Compute encoded-form similarity: shared prefix length / longer length
|
|
121
|
+
# (very rough — but better than nothing without lossless decode)
|
|
122
|
+
ORPHAN_CANDIDATES+=("$base|$cnt|$bytes")
|
|
123
|
+
fi
|
|
124
|
+
done
|
|
125
|
+
|
|
126
|
+
# No candidate orphans → nothing to report.
|
|
127
|
+
if [ "${#ORPHAN_CANDIDATES[@]}" -eq 0 ]; then
|
|
128
|
+
exit 0
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
# Limit output to top 5 candidates, sorted by byte size descending.
|
|
132
|
+
TOP=()
|
|
133
|
+
while IFS= read -r line; do
|
|
134
|
+
TOP+=("$line")
|
|
135
|
+
done < <(printf '%s\n' "${ORPHAN_CANDIDATES[@]}" | sort -t'|' -k3 -rn | head -5)
|
|
136
|
+
|
|
137
|
+
EXTRA=$(( ${#ORPHAN_CANDIDATES[@]} - ${#TOP[@]} ))
|
|
138
|
+
|
|
139
|
+
cat >&2 <<EOF
|
|
140
|
+
<system-reminder>
|
|
141
|
+
POSSIBLE MEMORY ORPHANING DETECTED — the current working directory's memory
|
|
142
|
+
is empty, but this project has substantive git history AND there are other
|
|
143
|
+
memory directories on disk with non-trivial content. One of them may be the
|
|
144
|
+
prior version of this project's memory that was orphaned by a directory
|
|
145
|
+
rename, move, or symlink change.
|
|
146
|
+
|
|
147
|
+
This is the failure mode documented in anthropics/claude-code#61349. Claude
|
|
148
|
+
Code derives memory location from the encoded working-directory path
|
|
149
|
+
(everything in / and . becomes -). Renaming the directory produces a
|
|
150
|
+
different encoded form, so a fresh empty memory directory is created at
|
|
151
|
+
the new path while the old memory stays on disk, unreferenced.
|
|
152
|
+
|
|
153
|
+
Current working directory: $CWD
|
|
154
|
+
Encoded form: $CWD_ENCODED
|
|
155
|
+
Current memory: $CURRENT_COUNT file(s) at $CURRENT_MEMORY_DIR
|
|
156
|
+
|
|
157
|
+
Candidate orphan memory directories (top 5 by size):
|
|
158
|
+
EOF
|
|
159
|
+
for entry in "${TOP[@]}"; do
|
|
160
|
+
IFS='|' read -r b c bytes <<< "$entry"
|
|
161
|
+
# Print bytes in KB for readability
|
|
162
|
+
kb=$(( bytes / 1024 ))
|
|
163
|
+
echo " $PROJECTS_DIR/$b/memory/ ($c files, ${kb}KB)" >&2
|
|
164
|
+
done
|
|
165
|
+
if [ "$EXTRA" -gt 0 ]; then
|
|
166
|
+
echo " ... and $EXTRA more" >&2
|
|
167
|
+
fi
|
|
168
|
+
cat >&2 <<EOF
|
|
169
|
+
|
|
170
|
+
Recommended next actions for the operator (NOT for the model to perform
|
|
171
|
+
automatically):
|
|
172
|
+
1. Inspect the candidate directories. The encoded path is the original
|
|
173
|
+
working directory's absolute path with every / and . replaced by -.
|
|
174
|
+
Note that this encoding is LOSSY — a - in the encoded form could be a
|
|
175
|
+
literal - or a / in the original path. Decode by trying both.
|
|
176
|
+
2. If you recognize an orphan that corresponds to a previous location of
|
|
177
|
+
this project (before a rename/move), copy its memory files into the
|
|
178
|
+
current memory directory: cp -r <orphan>/memory/* $CURRENT_MEMORY_DIR/
|
|
179
|
+
3. To prevent future orphaning, version-control the memory directory:
|
|
180
|
+
store memory in the project's git tree (e.g., .claude-memory/) and
|
|
181
|
+
symlink the system memory directory to it. Renames preserve the link.
|
|
182
|
+
|
|
183
|
+
To disable this detector, set CC_MEMORY_ORPHAN_DISABLE=1.
|
|
184
|
+
</system-reminder>
|
|
185
|
+
EOF
|
|
186
|
+
|
|
187
|
+
# Exit 0 — detection-only.
|
|
188
|
+
exit 0
|