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,108 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# multi-vendor-concurrent-warner.sh — Warn when another AI coding
|
|
4
|
+
# CLI (Codex, Gemini, Cursor, Aider, Amp, ...) is running at the
|
|
5
|
+
# same time as Claude Code, so concurrent edits to the same repo
|
|
6
|
+
# do not silently collide.
|
|
7
|
+
# ================================================================
|
|
8
|
+
# PURPOSE:
|
|
9
|
+
# A growing number of operators run several AI coding tools in
|
|
10
|
+
# parallel — Claude Code plus Codex, Gemini CLI, Cursor's agent,
|
|
11
|
+
# Aider, Amp, and others — pointed at the same repository. Two
|
|
12
|
+
# failure modes follow, and neither tool can see the other:
|
|
13
|
+
# 1. Conflicting edits. Two agents edit the same file; one
|
|
14
|
+
# overwrites the other, or the repo lands in a broken state
|
|
15
|
+
# (reported: dozens of type errors after a parallel run).
|
|
16
|
+
# 2. Cost is invisible. Each vendor bills separately; the
|
|
17
|
+
# combined spend across tools is not shown in any one tool,
|
|
18
|
+
# and parallel runs multiply it (operators report 3-5x).
|
|
19
|
+
#
|
|
20
|
+
# Every other concurrency hook in cc-safe-setup bounds Claude
|
|
21
|
+
# Code's OWN subagents (max-concurrent-agents, parallel-edit-guard,
|
|
22
|
+
# subagent-budget-guard, ...). None of them can see a SEPARATE
|
|
23
|
+
# vendor's process. This hook fills that gap: at session start it
|
|
24
|
+
# checks the process table for other AI CLIs and, if it finds one,
|
|
25
|
+
# prints a one-time advisory so the operator coordinates scope and
|
|
26
|
+
# watches combined cost.
|
|
27
|
+
#
|
|
28
|
+
# UPSTREAM / CONTEXT:
|
|
29
|
+
# The multi-vendor parallel-operation pattern (Claude Code + Codex
|
|
30
|
+
# + Gemini + Grok) is a real and growing operator workflow. This
|
|
31
|
+
# hook is advisory only — it never blocks and never inspects the
|
|
32
|
+
# other tool; it only notes that it is running.
|
|
33
|
+
#
|
|
34
|
+
# TRIGGER: SessionStart (also safe as PreToolUse)
|
|
35
|
+
#
|
|
36
|
+
# CONFIGURATION (env vars):
|
|
37
|
+
# CC_MULTI_VENDOR_PROCS Space-separated process names to treat
|
|
38
|
+
# as other AI CLIs. Default covers the
|
|
39
|
+
# common ones. Claude's own process is
|
|
40
|
+
# never matched.
|
|
41
|
+
# CC_MULTI_VENDOR_PS Override the command used to list
|
|
42
|
+
# process names (default: ps -eo comm=).
|
|
43
|
+
# CC_MULTI_VENDOR_PS_OUTPUT Pre-supplied process listing (tests).
|
|
44
|
+
# ================================================================
|
|
45
|
+
|
|
46
|
+
set -u
|
|
47
|
+
|
|
48
|
+
# Read and discard stdin (hook protocol); this hook does not use it.
|
|
49
|
+
cat > /dev/null 2>&1 || true
|
|
50
|
+
|
|
51
|
+
DEFAULT_PROCS="codex gemini cursor-agent cursor-agent-cli aider amp ampcode grok cline continue goose qwen"
|
|
52
|
+
PROCS="${CC_MULTI_VENDOR_PROCS:-$DEFAULT_PROCS}"
|
|
53
|
+
|
|
54
|
+
# Obtain the list of running process names.
|
|
55
|
+
if [ -n "${CC_MULTI_VENDOR_PS_OUTPUT:-}" ]; then
|
|
56
|
+
PS_LIST="$CC_MULTI_VENDOR_PS_OUTPUT"
|
|
57
|
+
else
|
|
58
|
+
PS_CMD="${CC_MULTI_VENDOR_PS:-ps -eo comm=}"
|
|
59
|
+
PS_LIST="$($PS_CMD 2>/dev/null)"
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
[ -z "$PS_LIST" ] && exit 0
|
|
63
|
+
|
|
64
|
+
# Match each candidate as a whole basename token so "cursor-agent"
|
|
65
|
+
# does not match unrelated names. We compare against the basename of
|
|
66
|
+
# each process entry to tolerate full paths in some ps formats.
|
|
67
|
+
FOUND=""
|
|
68
|
+
while IFS= read -r raw; do
|
|
69
|
+
[ -z "$raw" ] && continue
|
|
70
|
+
name="${raw##*/}" # basename
|
|
71
|
+
name="${name%% *}" # strip args if present
|
|
72
|
+
for p in $PROCS; do
|
|
73
|
+
if [ "$name" = "$p" ]; then
|
|
74
|
+
case " $FOUND " in
|
|
75
|
+
*" $p "*) : ;; # already recorded
|
|
76
|
+
*) FOUND="$FOUND $p" ;;
|
|
77
|
+
esac
|
|
78
|
+
fi
|
|
79
|
+
done
|
|
80
|
+
done <<EOF
|
|
81
|
+
$PS_LIST
|
|
82
|
+
EOF
|
|
83
|
+
|
|
84
|
+
FOUND="${FOUND# }"
|
|
85
|
+
[ -z "$FOUND" ] && exit 0
|
|
86
|
+
|
|
87
|
+
MSG="DETECTED: another AI coding CLI appears to be running alongside Claude Code: ${FOUND}.
|
|
88
|
+
Running multiple AI tools against the same repository at once has two failure modes that neither tool can see on its own:
|
|
89
|
+
- Conflicting edits: two agents change the same file; one silently overwrites the other, or the repo lands half-edited.
|
|
90
|
+
- Combined cost is invisible: each vendor bills separately, so no single tool shows your total spend, and parallel runs multiply it.
|
|
91
|
+
Operator-side mitigations:
|
|
92
|
+
1. Give each tool a disjoint scope (different directories or files) and commit frequently so collisions surface in git, not at runtime.
|
|
93
|
+
2. Track spend per vendor separately; assume the combined monthly cost, not any single tool's number.
|
|
94
|
+
3. Prefer a clear lead tool for edits and use the others for read-only review while both are live.
|
|
95
|
+
This hook is advisory only — it does not read or stop the other tool. The session continues normally."
|
|
96
|
+
|
|
97
|
+
if command -v jq > /dev/null 2>&1; then
|
|
98
|
+
jq -n --arg msg "$MSG" '
|
|
99
|
+
{
|
|
100
|
+
"hookSpecificOutput": {
|
|
101
|
+
"hookEventName": "SessionStart",
|
|
102
|
+
"additionalContext": $msg
|
|
103
|
+
}
|
|
104
|
+
}'
|
|
105
|
+
else
|
|
106
|
+
echo "$MSG" >&2
|
|
107
|
+
fi
|
|
108
|
+
exit 0
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# multi-window-auth-drift-detector.sh — Detect on-disk credentials drift mid-session
|
|
3
|
+
# (Cluster 19 candidate, axis 19E — multi-window /account state inconsistency)
|
|
4
|
+
#
|
|
5
|
+
# Background:
|
|
6
|
+
# Cluster 19 axis 19E documents a class of authentication failures unique to
|
|
7
|
+
# operators running multiple Claude Code windows in parallel. The structural
|
|
8
|
+
# shape: Window A authenticates with Account X and starts a long session.
|
|
9
|
+
# While Window A is mid-session, Window B either (a) logs in with Account Y,
|
|
10
|
+
# (b) logs out, or (c) re-authenticates — any action that rewrites the
|
|
11
|
+
# on-disk credential store. Window A keeps working from the cached in-memory
|
|
12
|
+
# token, but `/account` in Window A now reports "Not authenticated" while
|
|
13
|
+
# the same dialog's USAGE panel still shows real quota consumption.
|
|
14
|
+
#
|
|
15
|
+
# Anchor case: #62790 — "/account shows 'Not authenticated' in older windows
|
|
16
|
+
# after another window logs in/out, while Usage bars still populate".
|
|
17
|
+
#
|
|
18
|
+
# The contradiction is observable: same dialog, "Not authenticated" + live
|
|
19
|
+
# session quota bars. The operator does not know if their next substantive
|
|
20
|
+
# tool call will succeed or fail.
|
|
21
|
+
#
|
|
22
|
+
# This hook is a PostToolUse advisory that fires when:
|
|
23
|
+
# - the credentials file has been modified since the session start, AND
|
|
24
|
+
# - the operator has not already seen the advisory in this session
|
|
25
|
+
#
|
|
26
|
+
# The advisory does not block the tool call. It surfaces the drift so the
|
|
27
|
+
# operator can run /account, decide whether the in-memory auth is still the
|
|
28
|
+
# intended account, and re-auth deliberately if needed.
|
|
29
|
+
#
|
|
30
|
+
# Reference:
|
|
31
|
+
# https://gist.github.com/yurukusa/58cb17bfda4d5ab31bd804809809d22f (auth cluster field guide)
|
|
32
|
+
#
|
|
33
|
+
# Why a hook helps:
|
|
34
|
+
# Without the advisory, the failure mode is: Window A operator continues
|
|
35
|
+
# working, hits a 401 mid-task hours later, loses the in-flight work. With
|
|
36
|
+
# the advisory, the operator learns at the next tool call that the on-disk
|
|
37
|
+
# credentials have drifted, and can verify deliberately rather than discover
|
|
38
|
+
# the lapse during a costly task.
|
|
39
|
+
#
|
|
40
|
+
# When this hook does NOT emit anything:
|
|
41
|
+
# - CC_AUTH_DRIFT_DISABLE=1
|
|
42
|
+
# - CC_AUTH_DRIFT_QUIET=1
|
|
43
|
+
# - no credentials file exists at any known path
|
|
44
|
+
# - the credentials file mtime is older than the session start
|
|
45
|
+
# - the advisory has already fired in this session
|
|
46
|
+
#
|
|
47
|
+
# Hook config (settings.json):
|
|
48
|
+
# {
|
|
49
|
+
# "hooks": {
|
|
50
|
+
# "PostToolUse": [{
|
|
51
|
+
# "matcher": "",
|
|
52
|
+
# "hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/multi-window-auth-drift-detector.sh" }]
|
|
53
|
+
# }]
|
|
54
|
+
# }
|
|
55
|
+
# }
|
|
56
|
+
#
|
|
57
|
+
# Env vars:
|
|
58
|
+
# CC_AUTH_DRIFT_DISABLE=1 — never emit
|
|
59
|
+
# CC_AUTH_DRIFT_QUIET=1 — silent (process but never write to stderr)
|
|
60
|
+
# CC_AUTH_DRIFT_CRED_FILE=<path> — credentials file path override (tests)
|
|
61
|
+
# CC_AUTH_DRIFT_SESSION_START=<ep> — session start epoch override (tests)
|
|
62
|
+
# CC_AUTH_DRIFT_STATE_DIR=<path> — one-shot state dir override (default ~/.claude/state)
|
|
63
|
+
# CC_AUTH_DRIFT_SESSION_ID=<id> — session id override (tests)
|
|
64
|
+
#
|
|
65
|
+
# Design notes:
|
|
66
|
+
# - Opt-out. The advisory is specific (credentials file changed since
|
|
67
|
+
# session start) and the cost of a missed advisory (silent 401 mid-task)
|
|
68
|
+
# exceeds the cost of a false positive (one stderr advisory the operator
|
|
69
|
+
# dismisses).
|
|
70
|
+
# - One-shot per session. The advisory fires once. Further drifts in the
|
|
71
|
+
# same session do not re-fire — the operator already knows.
|
|
72
|
+
# - Never blocks. Exit always 0. The auth recovery is operator-action.
|
|
73
|
+
# - Looks at multiple known credential file paths. The exact path varies
|
|
74
|
+
# across Claude Code versions and platforms; the hook checks each in
|
|
75
|
+
# order and uses the first that exists.
|
|
76
|
+
|
|
77
|
+
set -u
|
|
78
|
+
|
|
79
|
+
if [[ "${CC_AUTH_DRIFT_DISABLE:-0}" = "1" ]]; then
|
|
80
|
+
exit 0
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
CRED_FILE="${CC_AUTH_DRIFT_CRED_FILE:-}"
|
|
84
|
+
if [[ -z "$CRED_FILE" ]]; then
|
|
85
|
+
for candidate in \
|
|
86
|
+
"$HOME/.config/claude/auth.json" \
|
|
87
|
+
"$HOME/.config/anthropic/configs/default.json" \
|
|
88
|
+
"$HOME/.claude/credentials.json" \
|
|
89
|
+
"$HOME/.claude/.credentials.json"; do
|
|
90
|
+
if [[ -f "$candidate" ]]; then
|
|
91
|
+
CRED_FILE="$candidate"
|
|
92
|
+
break
|
|
93
|
+
fi
|
|
94
|
+
done
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
if [[ -z "$CRED_FILE" ]] || [[ ! -f "$CRED_FILE" ]]; then
|
|
98
|
+
exit 0
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
STATE_DIR="${CC_AUTH_DRIFT_STATE_DIR:-$HOME/.claude/state}"
|
|
102
|
+
mkdir -p "$STATE_DIR" 2>/dev/null
|
|
103
|
+
|
|
104
|
+
SESSION_ID="${CC_AUTH_DRIFT_SESSION_ID:-${CLAUDE_SESSION_ID:-default}}"
|
|
105
|
+
GUARD_FILE="$STATE_DIR/auth-drift-${SESSION_ID}.fired"
|
|
106
|
+
START_FILE="$STATE_DIR/auth-drift-${SESSION_ID}.start"
|
|
107
|
+
|
|
108
|
+
if [[ -f "$GUARD_FILE" ]]; then
|
|
109
|
+
exit 0
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
# Read or record session start epoch. The first hook firing of a session
|
|
113
|
+
# records the start time; subsequent firings compare the credentials mtime
|
|
114
|
+
# against it.
|
|
115
|
+
SESSION_START="${CC_AUTH_DRIFT_SESSION_START:-}"
|
|
116
|
+
if [[ -z "$SESSION_START" ]]; then
|
|
117
|
+
if [[ -f "$START_FILE" ]]; then
|
|
118
|
+
SESSION_START=$(cat "$START_FILE" 2>/dev/null)
|
|
119
|
+
fi
|
|
120
|
+
if [[ -z "$SESSION_START" ]] || ! [[ "$SESSION_START" =~ ^[0-9]+$ ]]; then
|
|
121
|
+
date +%s > "$START_FILE" 2>/dev/null
|
|
122
|
+
exit 0
|
|
123
|
+
fi
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
# Get credentials file mtime in epoch seconds. Linux uses stat -c %Y;
|
|
127
|
+
# macOS uses stat -f %m. Try both for portability.
|
|
128
|
+
CRED_MTIME=$(stat -c %Y "$CRED_FILE" 2>/dev/null)
|
|
129
|
+
if [[ -z "$CRED_MTIME" ]] || ! [[ "$CRED_MTIME" =~ ^[0-9]+$ ]]; then
|
|
130
|
+
CRED_MTIME=$(stat -f %m "$CRED_FILE" 2>/dev/null)
|
|
131
|
+
fi
|
|
132
|
+
if [[ -z "$CRED_MTIME" ]] || ! [[ "$CRED_MTIME" =~ ^[0-9]+$ ]]; then
|
|
133
|
+
exit 0
|
|
134
|
+
fi
|
|
135
|
+
|
|
136
|
+
# If credentials were not modified since the session started, no drift.
|
|
137
|
+
if (( CRED_MTIME <= SESSION_START )); then
|
|
138
|
+
exit 0
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
# Drift detected. Mark one-shot guard.
|
|
142
|
+
touch "$GUARD_FILE" 2>/dev/null
|
|
143
|
+
|
|
144
|
+
if [[ "${CC_AUTH_DRIFT_QUIET:-0}" = "1" ]]; then
|
|
145
|
+
exit 0
|
|
146
|
+
fi
|
|
147
|
+
|
|
148
|
+
GAP=$(( CRED_MTIME - SESSION_START ))
|
|
149
|
+
|
|
150
|
+
cat >&2 <<EOF
|
|
151
|
+
|
|
152
|
+
────────────────────────────────────────────────────────────────────
|
|
153
|
+
Auth advisory — Cluster 19 axis 19E (multi-window drift)
|
|
154
|
+
────────────────────────────────────────────────────────────────────
|
|
155
|
+
Credentials file modified ${GAP}s after this session started:
|
|
156
|
+
${CRED_FILE}
|
|
157
|
+
|
|
158
|
+
The Cluster 19 axis 19E pattern: when another Claude Code window
|
|
159
|
+
logs in/out or re-authenticates, this window's in-memory token may
|
|
160
|
+
silently diverge from on-disk state. /account in this window can
|
|
161
|
+
report "Not authenticated" while the USAGE quota bars still show
|
|
162
|
+
live consumption. The next substantive tool call may 401 mid-task.
|
|
163
|
+
|
|
164
|
+
Anchor case: #62790.
|
|
165
|
+
|
|
166
|
+
Recommended check before the next costly tool call:
|
|
167
|
+
|
|
168
|
+
/account
|
|
169
|
+
|
|
170
|
+
If "Auth method" reports "Not authenticated" but USAGE bars are
|
|
171
|
+
populated, the in-memory token is stale. Close all Claude Code
|
|
172
|
+
windows, then re-authenticate in a single window and start fresh
|
|
173
|
+
sessions — re-using the existing window will re-surface the drift.
|
|
174
|
+
|
|
175
|
+
Field guide: https://gist.github.com/yurukusa/58cb17bfda4d5ab31bd804809809d22f
|
|
176
|
+
|
|
177
|
+
(This advisory fires once per session. To disable:
|
|
178
|
+
export CC_AUTH_DRIFT_DISABLE=1)
|
|
179
|
+
────────────────────────────────────────────────────────────────────
|
|
180
|
+
|
|
181
|
+
EOF
|
|
182
|
+
|
|
183
|
+
exit 0
|
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# multiline-command-approver.sh — Auto-approve multiline commands
|
|
2
|
+
# multiline-command-approver.sh — Auto-approve multiline commands safely
|
|
3
3
|
#
|
|
4
4
|
# Solves: Auto-approve patterns fail on heredocs and multiline commands
|
|
5
5
|
# (#11932 — 47 reactions, 29 comments)
|
|
6
6
|
#
|
|
7
|
-
# How it works:
|
|
8
|
-
# 1. Extracts the first line of the command
|
|
9
|
-
# 2. Matches against a whitelist of safe command prefixes
|
|
10
|
-
# 3. If the first line is a safe command, auto-approves the entire command
|
|
11
|
-
#
|
|
12
7
|
# This is needed because Claude Code's built-in pattern matching
|
|
13
8
|
# evaluates the entire multiline string, which breaks on heredocs:
|
|
14
9
|
# echo 'commit message\n\nCo-Authored-By: ...' > file
|
|
@@ -26,15 +21,47 @@
|
|
|
26
21
|
# }]
|
|
27
22
|
# }
|
|
28
23
|
# }
|
|
24
|
+
#
|
|
25
|
+
# Rewritten 2026-08-03. The old version took `head -1` of the command and
|
|
26
|
+
# approved the whole thing when that one line matched a safe prefix. It had two
|
|
27
|
+
# holes, and the second one was the hook's own subject matter:
|
|
28
|
+
#
|
|
29
|
+
# separators : over the 32 commands it approved bare, appending
|
|
30
|
+
# `&& sudo rm -rf /var/app`, `; curl http://… | sh` or
|
|
31
|
+
# `&& git push --force` kept the approval 288/288 times.
|
|
32
|
+
# newlines : `cat <<'EOF' > note.txt` on line 1 with a destructive command
|
|
33
|
+
# on line 2 kept the approval 18/18 times. A hook whose entire
|
|
34
|
+
# purpose is multiline input was reading one line of it.
|
|
35
|
+
#
|
|
36
|
+
# The control says which repair this needs: the same dangerous commands on
|
|
37
|
+
# their own were approved 0/5 and 0/3 times. It never approved anything — it
|
|
38
|
+
# just never looked past the first line's first command.
|
|
39
|
+
#
|
|
40
|
+
# Reading further is not as simple as splitting on separators here, because the
|
|
41
|
+
# forms this hook exists to rescue put separators and newlines *inside* data:
|
|
42
|
+
# a commit message spanning lines, a heredoc body. So the command is scanned
|
|
43
|
+
# with the quoting state carried across lines, and heredoc bodies are skipped
|
|
44
|
+
# between their opener and their terminator. What is left is the actual command
|
|
45
|
+
# positions, and every one of them has to match a safe prefix.
|
|
46
|
+
#
|
|
47
|
+
# A line that does not qualify gets no decision, which leaves it to the normal
|
|
48
|
+
# permission flow. This hook only ever adds approval; it never blocks.
|
|
49
|
+
#
|
|
50
|
+
# Known limits:
|
|
51
|
+
# - Command substitution and backticks are refused outright. Their contents
|
|
52
|
+
# cannot be judged by reading the string.
|
|
53
|
+
# - Some prefixes below hand execution to an interpreter (`python3 -c`,
|
|
54
|
+
# `node -e`, `npx`, `curl -s`). Those are a separate problem from the one
|
|
55
|
+
# fixed here — the granularity of the safe list, not where it looks — and
|
|
56
|
+
# are measured separately.
|
|
57
|
+
# - More than one heredoc opened on the same line is refused rather than
|
|
58
|
+
# guessed at.
|
|
29
59
|
|
|
30
60
|
INPUT=$(cat)
|
|
31
61
|
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
32
62
|
[ -z "$COMMAND" ] && exit 0
|
|
33
63
|
|
|
34
|
-
#
|
|
35
|
-
FIRST_LINE=$(echo "$COMMAND" | head -1 | sed 's/^[[:space:]]*//')
|
|
36
|
-
|
|
37
|
-
# Safe command prefixes (first line only)
|
|
64
|
+
# Safe command prefixes. Each command position must match one of these.
|
|
38
65
|
SAFE_PREFIXES=(
|
|
39
66
|
"echo "
|
|
40
67
|
"printf "
|
|
@@ -71,19 +98,130 @@ SAFE_PREFIXES=(
|
|
|
71
98
|
"curl -s"
|
|
72
99
|
)
|
|
73
100
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
101
|
+
POSITIONS=()
|
|
102
|
+
|
|
103
|
+
cc_flush() {
|
|
104
|
+
local t="$1"
|
|
105
|
+
t="${t#"${t%%[![:space:]]*}"}"
|
|
106
|
+
t="${t%"${t##*[![:space:]]}"}"
|
|
107
|
+
[ -z "$t" ] && return 0
|
|
108
|
+
case "$t" in '#'*) return 0 ;; esac # a comment is not a command position
|
|
109
|
+
POSITIONS+=("$t")
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
# Split the command into command positions, carrying quoting state across lines
|
|
113
|
+
# and skipping heredoc bodies. Returns 1 for anything it will not vouch for.
|
|
114
|
+
cc_scan() {
|
|
115
|
+
local sq=0 dq=0 seg="" hd_active=0 hd_delim="" hd_dash=0
|
|
116
|
+
local line i n c nx j d q ch pending_delim="" pending_dash=0 pending_count=0
|
|
117
|
+
|
|
118
|
+
while IFS= read -r line; do
|
|
119
|
+
if [ "$hd_active" -eq 1 ]; then
|
|
120
|
+
local cand="$line"
|
|
121
|
+
[ "$hd_dash" -eq 1 ] && cand="${cand#"${cand%%[![:space:]]*}"}"
|
|
122
|
+
[ "$cand" = "$hd_delim" ] && hd_active=0
|
|
123
|
+
continue
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
pending_delim=""; pending_count=0
|
|
127
|
+
i=0; n=${#line}
|
|
128
|
+
while [ "$i" -lt "$n" ]; do
|
|
129
|
+
c="${line:i:1}"
|
|
130
|
+
|
|
131
|
+
if [ "$sq" -eq 1 ]; then
|
|
132
|
+
[ "$c" = "'" ] && sq=0
|
|
133
|
+
seg+="$c"; i=$((i + 1)); continue
|
|
134
|
+
fi
|
|
135
|
+
if [ "$dq" -eq 1 ]; then
|
|
136
|
+
if [ "$c" = '\' ]; then seg+="${line:i:2}"; i=$((i + 2)); continue; fi
|
|
137
|
+
[ "$c" = '"' ] && dq=0
|
|
138
|
+
seg+="$c"; i=$((i + 1)); continue
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
case "$c" in
|
|
142
|
+
"'") sq=1; seg+="$c"; i=$((i + 1)) ;;
|
|
143
|
+
'"') dq=1; seg+="$c"; i=$((i + 1)) ;;
|
|
144
|
+
'\') seg+="${line:i:2}"; i=$((i + 2)) ;;
|
|
145
|
+
'`') return 1 ;;
|
|
146
|
+
'$')
|
|
147
|
+
[ "${line:i+1:1}" = "(" ] && return 1
|
|
148
|
+
seg+="$c"; i=$((i + 1)) ;;
|
|
149
|
+
';'|'&'|'|')
|
|
150
|
+
cc_flush "$seg"; seg=""; i=$((i + 1)) ;;
|
|
151
|
+
'#')
|
|
152
|
+
# `#` opens a comment only at the start of a word
|
|
153
|
+
if [ -z "${seg//[[:space:]]/}" ] || [ "${line:i-1:1}" = " " ] || [ "${line:i-1:1}" = $'\t' ]; then
|
|
154
|
+
i="$n"
|
|
155
|
+
else
|
|
156
|
+
seg+="$c"; i=$((i + 1))
|
|
157
|
+
fi ;;
|
|
158
|
+
'<')
|
|
159
|
+
if [ "${line:i+1:1}" = "<" ]; then
|
|
160
|
+
j=$((i + 2)); d=""; q=""
|
|
161
|
+
if [ "${line:j:1}" = "-" ]; then pending_dash=1; j=$((j + 1)); else pending_dash=0; fi
|
|
162
|
+
while [ "${line:j:1}" = " " ] || [ "${line:j:1}" = $'\t' ]; do j=$((j + 1)); done
|
|
163
|
+
ch="${line:j:1}"
|
|
164
|
+
if [ "$ch" = "'" ] || [ "$ch" = '"' ]; then q="$ch"; j=$((j + 1)); fi
|
|
165
|
+
while [ "$j" -lt "$n" ]; do
|
|
166
|
+
ch="${line:j:1}"
|
|
167
|
+
if [ -n "$q" ]; then
|
|
168
|
+
if [ "$ch" = "$q" ]; then j=$((j + 1)); break; fi
|
|
169
|
+
else
|
|
170
|
+
case "$ch" in ' '|$'\t'|';'|'&'|'|'|'>'|'<') break ;; esac
|
|
171
|
+
fi
|
|
172
|
+
d+="$ch"; j=$((j + 1))
|
|
173
|
+
done
|
|
174
|
+
[ -z "$d" ] && return 1
|
|
175
|
+
pending_count=$((pending_count + 1))
|
|
176
|
+
[ "$pending_count" -gt 1 ] && return 1
|
|
177
|
+
pending_delim="$d"
|
|
178
|
+
seg+="<<"; i="$j"
|
|
179
|
+
else
|
|
180
|
+
seg+="$c"; i=$((i + 1))
|
|
181
|
+
fi ;;
|
|
182
|
+
*) seg+="$c"; i=$((i + 1)) ;;
|
|
183
|
+
esac
|
|
184
|
+
done
|
|
185
|
+
|
|
186
|
+
if [ "$sq" -eq 1 ] || [ "$dq" -eq 1 ]; then
|
|
187
|
+
# the newline is part of the string, not the end of a command
|
|
188
|
+
seg+=$'\n'
|
|
189
|
+
else
|
|
190
|
+
cc_flush "$seg"; seg=""
|
|
191
|
+
if [ -n "$pending_delim" ]; then
|
|
192
|
+
hd_delim="$pending_delim"; hd_dash="$pending_dash"; hd_active=1
|
|
193
|
+
fi
|
|
194
|
+
fi
|
|
195
|
+
done <<EOF
|
|
196
|
+
$COMMAND
|
|
197
|
+
EOF
|
|
198
|
+
|
|
199
|
+
# an unterminated quote means the string was not what it looked like
|
|
200
|
+
{ [ "$sq" -eq 1 ] || [ "$dq" -eq 1 ]; } && return 1
|
|
201
|
+
# an unterminated heredoc swallows the rest of the input as body. bash does
|
|
202
|
+
# treat it as data, so approving would not actually be wrong — but that
|
|
203
|
+
# rests on a subtlety, and refusing costs nothing.
|
|
204
|
+
[ "$hd_active" -eq 1 ] && return 1
|
|
205
|
+
cc_flush "$seg"
|
|
206
|
+
return 0
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
cc_scan || exit 0
|
|
210
|
+
[ "${#POSITIONS[@]}" -eq 0 ] && exit 0
|
|
211
|
+
|
|
212
|
+
for seg in "${POSITIONS[@]}"; do
|
|
213
|
+
matched=0
|
|
214
|
+
for prefix in "${SAFE_PREFIXES[@]}"; do
|
|
215
|
+
if [[ "$seg" == "$prefix"* ]]; then matched=1; break; fi
|
|
216
|
+
done
|
|
217
|
+
[ "$matched" -eq 1 ] || exit 0
|
|
86
218
|
done
|
|
87
219
|
|
|
88
|
-
|
|
220
|
+
jq -n '{
|
|
221
|
+
"hookSpecificOutput": {
|
|
222
|
+
"hookEventName": "PreToolUse",
|
|
223
|
+
"permissionDecision": "allow",
|
|
224
|
+
"permissionDecisionReason": "multiline-command-approver: every command position matches a safe prefix"
|
|
225
|
+
}
|
|
226
|
+
}'
|
|
89
227
|
exit 0
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# nested-background-agent-guard.sh — Refuse background agent spawns from inside a sub-agent
|
|
3
|
+
#
|
|
4
|
+
# Why: Issue #73829 (2026-07-04, desktop app, 0 comments when filed) is the canonical
|
|
5
|
+
# report. An intermediate background agent spawned *further* background agents
|
|
6
|
+
# instead of doing the sub-topics inline. A grandchild then re-invoked itself with
|
|
7
|
+
# filler no-ops ("checked current time", "Monitor timed out", "no-op while waiting")
|
|
8
|
+
# for 6.5 hours instead of quiescing. Once the intermediate agent's session ended,
|
|
9
|
+
# the top-level session had no handle on its descendants: TaskStop/TaskOutput
|
|
10
|
+
# returned "No task found" while the panel still showed them running. Several
|
|
11
|
+
# hundred USD burned, and restarting the app was the only way to clear it.
|
|
12
|
+
#
|
|
13
|
+
# The recursion only compounds because a *sub*-agent is allowed to spawn
|
|
14
|
+
# *background* agents at all. That is the one layer a client-side hook can gate
|
|
15
|
+
# deterministically, so that is what this hook does.
|
|
16
|
+
#
|
|
17
|
+
# ★2026-08-01: this got worse by default. Claude Code 2.1.219 changed nested subagent
|
|
18
|
+
# spawning from depth 1 to **depth 3 by default**:
|
|
19
|
+
#
|
|
20
|
+
# "Subagents can now spawn nested subagents up to depth 3 by default (was 1);
|
|
21
|
+
# set CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1 to disable nesting"
|
|
22
|
+
#
|
|
23
|
+
# Two consequences for anyone running unattended:
|
|
24
|
+
# - The blast radius of the #73829 shape tripled without anyone changing a setting.
|
|
25
|
+
# - Guards that cap the *number* of concurrent subagents do not see this at all.
|
|
26
|
+
# If each level spawns only a few, the count stays under the threshold while the
|
|
27
|
+
# depth keeps growing. Depth and width are different axes; this hook is the depth one.
|
|
28
|
+
#
|
|
29
|
+
# Why existing cc-safe-setup hooks miss this exact shape:
|
|
30
|
+
# - nested-spawn-inflight-guard.sh / max-subagent-count.sh / subagent-budget-guard.sh
|
|
31
|
+
# all bound how many subagents are in flight. None of them read whether the *current*
|
|
32
|
+
# run is itself a sub-agent, so none of them can tell depth 1 from depth 3.
|
|
33
|
+
# - background-cost-launch-guard.sh reads the Bash tool's run_in_background parameter.
|
|
34
|
+
# It never sees Agent/Task dispatches.
|
|
35
|
+
#
|
|
36
|
+
# What this does: on PreToolUse for Agent/Task/SendMessage, if run_in_background is true
|
|
37
|
+
# AND the current session is already a sub-agent (CLAUDE_CODE_CHILD_SESSION is set),
|
|
38
|
+
# it BLOCKS (exit 2). Foreground agents inside a sub-agent pass. Background agents from
|
|
39
|
+
# the top-level session pass. Only the nesting case is refused.
|
|
40
|
+
#
|
|
41
|
+
# Verified on 2026-07-04 against three inputs, and re-verified 2026-08-01 with the
|
|
42
|
+
# regression tests in tests/:
|
|
43
|
+
# (a) run_in_background:true + CLAUDE_CODE_CHILD_SESSION set -> exit 2 (blocked)
|
|
44
|
+
# (b) run_in_background:true + variable unset (top level) -> exit 0 (allowed)
|
|
45
|
+
# (c) foreground agent inside a sub-agent -> exit 0 (allowed)
|
|
46
|
+
#
|
|
47
|
+
# ★Limitation, stated plainly: CLAUDE_CODE_CHILD_SESSION is set inside spawned agent
|
|
48
|
+
# sessions on the CLI (confirmed while examining transcript inheritance in #73848).
|
|
49
|
+
# The desktop app was NOT confirmed to set it identically. Verify on your build first
|
|
50
|
+
# with a trivial printenv hook before relying on this.
|
|
51
|
+
#
|
|
52
|
+
# ★This does not recover already-orphaned tasks. They are app-managed tasks, not OS
|
|
53
|
+
# processes you can kill, and the spawning session is gone. The real fixes are
|
|
54
|
+
# provider-side: descendants should stay inspectable/stoppable from the root, and an
|
|
55
|
+
# agent awaiting children should quiesce rather than emit filler tool calls.
|
|
56
|
+
#
|
|
57
|
+
# Opt out: CC_NESTED_BG_AGENT_GUARD_DISABLE=1
|
|
58
|
+
#
|
|
59
|
+
# TRIGGER: PreToolUse MATCHER: "Agent|Task|SendMessage"
|
|
60
|
+
# settings.json:
|
|
61
|
+
# { "hooks": { "PreToolUse": [{ "matcher": "Agent|Task|SendMessage",
|
|
62
|
+
# "hooks": [{ "type": "command",
|
|
63
|
+
# "command": "~/.claude/hooks/nested-background-agent-guard.sh" }] }] } }
|
|
64
|
+
|
|
65
|
+
set -uo pipefail
|
|
66
|
+
|
|
67
|
+
[ "${CC_NESTED_BG_AGENT_GUARD_DISABLE:-0}" = "1" ] && exit 0
|
|
68
|
+
|
|
69
|
+
INPUT="$(cat)"
|
|
70
|
+
|
|
71
|
+
# jq が無い環境で黙って素通りしないこと。2026-07-27 に、配っていた17本が
|
|
72
|
+
# jq 不在で沈黙して素通りしていた(遮断すべき14通りが3環境すべてで0/14)。
|
|
73
|
+
# 「検査する対象が無かった」と「検査する道具が無かった」を混同しないため、
|
|
74
|
+
# ここでは通すが必ず声を出す。どれも無い環境で遮断を選ぶと全ツール呼び出しが
|
|
75
|
+
# 止まって Claude Code が使えなくなるので、fail-open + 警告にする。
|
|
76
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
77
|
+
echo "nested-background-agent-guard: jq not found — cannot inspect this dispatch, passing through unchecked." >&2
|
|
78
|
+
exit 0
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
TOOL="$(printf '%s\n' "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)"
|
|
82
|
+
case "$TOOL" in
|
|
83
|
+
Agent|Task|SendMessage) ;;
|
|
84
|
+
*) exit 0 ;;
|
|
85
|
+
esac
|
|
86
|
+
|
|
87
|
+
BG="$(printf '%s\n' "$INPUT" | jq -r '.tool_input.run_in_background // false' 2>/dev/null)"
|
|
88
|
+
[ "$BG" = "true" ] || exit 0
|
|
89
|
+
|
|
90
|
+
# 親(top-level)からの背景の生成は通す。止めたいのは入れ子の側だけ。
|
|
91
|
+
[ -n "${CLAUDE_CODE_CHILD_SESSION:-}" ] || exit 0
|
|
92
|
+
|
|
93
|
+
cat >&2 <<'MSG'
|
|
94
|
+
Blocked: a sub-agent tried to spawn a background agent.
|
|
95
|
+
|
|
96
|
+
Issue #73829: nested background agents orphan and loop. Once the intermediate
|
|
97
|
+
agent's session ends, TaskStop/TaskOutput return "No task found" while the tasks
|
|
98
|
+
keep running and burning tokens — 6.5 hours and several hundred USD in the
|
|
99
|
+
original report.
|
|
100
|
+
|
|
101
|
+
Since Claude Code 2.1.219 the default nesting depth is 3 (was 1), so this shape
|
|
102
|
+
now has three levels to compound through instead of one.
|
|
103
|
+
|
|
104
|
+
Do one of these instead:
|
|
105
|
+
- Do the sub-topics inline in this sub-agent (no further dispatch).
|
|
106
|
+
- Spawn background agents only from the top-level session, where TaskStop works.
|
|
107
|
+
- If you genuinely need nesting, cap it first: CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=1
|
|
108
|
+
MSG
|
|
109
|
+
exit 2
|