cc-safe-setup 29.8.0 → 30.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +72 -19
- package/.claude-plugin/plugin.json +1 -1
- package/CONTRIBUTING.md +7 -2
- package/COOKBOOK.md +50 -46
- package/LICENSE +21 -0
- package/MIGRATION.md +8 -8
- package/README.md +419 -512
- package/SAFETY_CHECKLIST.md +15 -7
- package/SERVICES.md +194 -0
- package/SETTINGS_REFERENCE.md +236 -17
- package/SKILL.md +5 -5
- package/TROUBLESHOOTING.md +35 -14
- package/action.yml +12 -4
- package/audit/README.md +84 -0
- package/audit/audit-checklist.md +152 -0
- package/audit/boundary-selftest.sh +85 -0
- package/audit/boundary.sh +123 -0
- package/audit/count-hooks.py +42 -0
- package/audit/find-dead-hooks.sh +82 -0
- package/audit/find-unfirable-rules.sh +142 -0
- package/audit/fire.sh +97 -0
- package/audit/selftest.sh +42 -0
- package/audit/unfirable-selftest.sh +81 -0
- package/audit-web/index.html +9 -9
- package/examples/README.md +54 -17
- package/examples/account-billing-log.sh +98 -0
- package/examples/account-routing-preflight.sh +123 -0
- package/examples/agent-sdk-credit-pool-monitor.sh +145 -0
- package/examples/agent-view-quota-decrement.sh +32 -0
- package/examples/agent-view-quota-warn.sh +94 -0
- package/examples/agents-md-edit-drift-warner.sh +223 -0
- package/examples/agents-md-loader.sh +160 -0
- package/examples/agents-md-sync-checker.sh +102 -0
- package/examples/ai-slop-punctuation-arrest.sh +210 -0
- package/examples/allowlist.sh +70 -10
- package/examples/always-allow-pattern-suggester.sh +125 -0
- package/examples/ansible-vault-guard.sh +2 -1
- package/examples/anthropic-base-url-guard.sh +76 -0
- package/examples/api-busyloop-guard.sh +123 -0
- package/examples/api-endpoint-guard.sh +12 -0
- package/examples/api-key-in-url-guard.sh +17 -1
- package/examples/api-rate-limit-guard.sh +36 -1
- package/examples/api-rate-limit-tracker.sh +12 -0
- package/examples/articulated-scope-capture.sh +101 -0
- package/examples/askuserquestion-autonomy-gate.sh +102 -0
- package/examples/attachment-traversal-guard.sh +118 -0
- package/examples/aup-block-pattern-logger.sh +161 -0
- package/examples/aup-false-positive-helper.sh +124 -0
- package/examples/aup-large-tool-output-warner.sh +282 -0
- package/examples/aup-retry-loop-guard.sh +229 -0
- package/examples/auth-expiry-reminder.sh +157 -0
- package/examples/auth-macos-sleep-detector.sh +185 -0
- package/examples/auth-path-detector.sh +171 -0
- package/examples/auth-status-checker.sh +157 -0
- package/examples/authorized-reconfirmation-detector.sh +195 -0
- package/examples/auto-approve-build.sh +39 -0
- package/examples/auto-approve-cargo.sh +31 -1
- package/examples/auto-approve-docker.sh +35 -0
- package/examples/auto-approve-git-read.sh +37 -14
- package/examples/auto-approve-go.sh +30 -1
- package/examples/auto-approve-gradle.sh +29 -1
- package/examples/auto-approve-make.sh +29 -1
- package/examples/auto-approve-maven.sh +29 -1
- package/examples/auto-approve-python.sh +41 -1
- package/examples/auto-approve-readonly-tools.sh +1 -0
- package/examples/auto-approve-readonly.sh +110 -33
- package/examples/auto-approve-ssh.sh +30 -1
- package/examples/auto-approve-test.sh +44 -0
- package/examples/auto-checkpoint.sh +1 -1
- package/examples/auto-compact-prep.sh +0 -0
- package/examples/auto-git-checkpoint.sh +0 -0
- package/examples/auto-mode-safe-commands.sh +53 -1
- package/examples/auto-mode-safety-enforcer.sh +151 -4
- package/examples/auto-push-session-branch.sh +22 -0
- package/examples/aws-production-guard.sh +13 -1
- package/examples/aws-region-guard.sh +1 -1
- package/examples/background-cost-launch-guard.sh +82 -0
- package/examples/background-task-guard.sh +12 -0
- package/examples/backup-before-refactor.sh +0 -0
- package/examples/banned-command-guard.sh +12 -0
- package/examples/bash-allowlist-secondary-check.sh +157 -0
- package/examples/bash-domain-allowlist.sh +12 -0
- package/examples/bash-fanout-bounded-rewriter.sh +191 -0
- package/examples/bash-heuristic-approver.sh +112 -10
- package/examples/bash-project-fence.sh +194 -0
- package/examples/bash-safety-auto-deny.sh +12 -0
- package/examples/bash-secret-output-detector.sh +44 -3
- package/examples/bash-trace-guard.sh +12 -0
- package/examples/bashrc-safety-check.sh +0 -0
- package/examples/bg-permission-prompt-warner.sh +182 -0
- package/examples/bg-task-cooldown-guard.sh +12 -0
- package/examples/binary-read-detector.sh +135 -0
- package/examples/binary-upload-guard.sh +12 -0
- package/examples/block-database-wipe.sh +35 -10
- package/examples/branch-name-check.sh +8 -3
- package/examples/branch-naming-convention.sh +0 -0
- package/examples/broad-find-guard.sh +12 -0
- package/examples/broad-prefix-session-trap-warner.sh +106 -0
- package/examples/bulk-file-delete-guard.sh +45 -0
- package/examples/bypass-mode-effective-verifier.sh +203 -0
- package/examples/cache-creation-drift-detector.sh +120 -0
- package/examples/cache-residue-detector.sh +195 -0
- package/examples/cache-tier-logger.sh +70 -0
- package/examples/cache-ttl-eviction-detector.sh +149 -0
- package/examples/cargo-publish-guard.sh +14 -1
- package/examples/case-insensitive-path-guard.sh +21 -2
- package/examples/case-sensitive-guard.sh +23 -2
- package/examples/cch-cache-guard.sh +0 -0
- package/examples/cch-sentinel-precommit-guard.sh +47 -0
- package/examples/check-abort-controller.sh +1 -1
- package/examples/check-accessibility.sh +0 -0
- package/examples/check-aria-labels.sh +0 -0
- package/examples/check-before-act-enforcer.sh +12 -0
- package/examples/check-charset-meta.sh +0 -0
- package/examples/check-cookie-flags.sh +0 -0
- package/examples/check-cors-config.sh +0 -0
- package/examples/check-csp-headers.sh +0 -0
- package/examples/check-csrf-protection.sh +0 -0
- package/examples/check-debounce.sh +1 -1
- package/examples/check-dependency-age.sh +0 -0
- package/examples/check-dependency-license.sh +0 -0
- package/examples/check-dockerfile-best-practice.sh +0 -0
- package/examples/check-error-boundaries.sh +0 -0
- package/examples/check-error-class.sh +1 -1
- package/examples/check-error-handling.sh +0 -0
- package/examples/check-error-logging.sh +1 -1
- package/examples/check-error-message.sh +0 -0
- package/examples/check-error-stack.sh +0 -0
- package/examples/check-favicon.sh +0 -0
- package/examples/check-git-hooks-compat.sh +0 -0
- package/examples/check-gitattributes.sh +0 -0
- package/examples/check-https-redirect.sh +0 -0
- package/examples/check-input-validation.sh +0 -0
- package/examples/check-lang-attribute.sh +0 -0
- package/examples/check-npm-scripts-exist.sh +0 -0
- package/examples/check-package-size.sh +0 -0
- package/examples/check-port-availability.sh +0 -0
- package/examples/check-promise-all.sh +1 -1
- package/examples/check-rate-limiting.sh +0 -0
- package/examples/check-return-types.sh +0 -0
- package/examples/check-semantic-versioning.sh +0 -0
- package/examples/check-suspense-fallback.sh +1 -1
- package/examples/check-test-exists.sh +0 -0
- package/examples/check-test-naming.sh +0 -0
- package/examples/check-timeout-cleanup.sh +1 -1
- package/examples/check-tls-version.sh +0 -0
- package/examples/check-unsubscribe.sh +1 -1
- package/examples/check-viewport-meta.sh +0 -0
- package/examples/check-worker-terminate.sh +1 -1
- package/examples/checkpoint-tamper-guard.sh +12 -0
- package/examples/chmod-guard.sh +12 -0
- package/examples/chown-guard.sh +24 -0
- package/examples/ci-workflow-guard.sh +6 -1
- package/examples/claim-verify-detector.sh +109 -0
- package/examples/claim-vs-caveat-checker.sh +77 -0
- package/examples/classifier-fallback-allow.sh +114 -40
- package/examples/claude-cache-gc.sh +1 -0
- package/examples/claude-code-version-pin-advisor.sh +183 -0
- package/examples/claude-md-reinjector.sh +129 -0
- package/examples/claude-md-size-monitor.sh +66 -0
- package/examples/claude-update-budget-guard.sh +123 -0
- package/examples/claude-update-smart.sh +113 -0
- package/examples/claudeignore-enforce-guard.sh +12 -0
- package/examples/claudemd-enforcer.sh +0 -0
- package/examples/claudemd-tool-prohibition.sh +128 -0
- package/examples/clear-command-confirm-guard.sh +32 -15
- package/examples/cli-config-pinning-detector.sh +162 -0
- package/examples/cliff-countdown-advisor.sh +96 -0
- package/examples/clipboard-secret-guard.sh +12 -0
- package/examples/closure-word-verify-gate.sh +150 -0
- package/examples/cloud-cli-guard.sh +39 -2
- package/examples/commit-all-scope-guard.sh +44 -0
- package/examples/commit-message-check.sh +1 -1
- package/examples/commit-message-quality.sh +6 -1
- package/examples/commitment-carry-forward-arrest.sh +361 -0
- package/examples/compact-alert-notification.sh +0 -0
- package/examples/compact-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 +1699 -183
- package/mission.md +2 -0
- package/package.json +4 -4
- package/plugins/credential-guard/.claude-plugin/plugin.json +9 -7
- package/plugins/git-protection/.claude-plugin/plugin.json +10 -8
- package/plugins/safety-essentials/.claude-plugin/plugin.json +9 -7
- package/plugins/token-guard/.claude-plugin/plugin.json +10 -8
- package/scripts/agents-md-sync-setup.sh +156 -0
- package/scripts/autonomy-blocked-summary.sh +148 -0
- package/scripts/build-search-index.py +43 -0
- package/scripts/build-sitemap.py +119 -0
- package/scripts/cc-doctor.sh +192 -0
- package/scripts/check-hook-event-names.py +127 -0
- package/scripts/check-misfire-instrument.sh +64 -0
- package/scripts/claim-verify-audit.sh +467 -0
- package/scripts/cowork-claudemd-helper.sh +136 -0
- package/scripts/june-15-deprecated-model-scan.sh +111 -0
- package/scripts/measure-heredoc-shapes.sh +67 -0
- package/scripts/measure-literal-match-misfire.sh +110 -0
- package/scripts/probe-scope-guard-branches.sh +48 -0
- package/scripts/probe-skip-line-both-ways.sh +65 -0
- package/scripts/receipts-aggregate.py +199 -0
- package/scripts/session-forensic-audit.py +360 -0
- package/scripts.json +9 -9
- package/scripts.json.bak-2026-07-27-find +13 -0
- package/skills/safety-setup/SKILL.md +5 -5
- package/tests/approve-side-remaining-two.test.sh +129 -0
- package/tests/approver-list-granularity.test.sh +145 -0
- package/tests/askuserquestion-autonomy-gate.test.sh +181 -0
- package/tests/audit-ci-gate.test.sh +87 -0
- package/tests/audit-cross-layer-claudemd.test.sh +170 -0
- package/tests/audit-fail-open-parse.test.sh +100 -0
- package/tests/auto-approve-compound-tail.test.sh +194 -0
- package/tests/auto-mode-path-invoked-commands.test.sh +89 -0
- package/tests/auto-mode-quoted-targets.test.sh +127 -0
- package/tests/auto-mode-unquoted-targets.test.sh +112 -0
- package/tests/bash-secret-output-detector-detects.test.sh +102 -0
- package/tests/blindspots-cross-layer.test.sh +177 -0
- package/tests/block-database-wipe.test.sh +64 -0
- package/tests/bundled-short-flags-bypass.test.sh +85 -0
- package/tests/cd-git-allow-compound-tail.test.sh +67 -0
- package/tests/chown-guard-filesystem-root.test.sh +64 -0
- package/tests/ci-workflow-guard-skip-rule.test.sh +115 -0
- package/tests/compound-deny-safe-rm-targets.test.sh +105 -0
- package/tests/core-scripts-parser-fallback.test.sh +140 -0
- package/tests/destructive-guard-bare-glob.test.sh +74 -0
- package/tests/destructive-guard-every-operand.test.sh +100 -0
- package/tests/destructive-guard-find-deletion.test.sh +114 -0
- package/tests/destructive-guard-flag-order.test.sh +106 -0
- package/tests/destructive-guard-mentions-vs-invocations.test.sh +107 -0
- package/tests/destructive-guard-quoted-target.test.sh +89 -0
- package/tests/destructive-guard-separators.test.sh +105 -0
- package/tests/destructive-guard-variable-target.test.sh +98 -0
- package/tests/destructive-guard-wrapped-command.test.sh +91 -0
- package/tests/doctor-hook-disabling-env.test.sh +92 -0
- package/tests/doctor-misspelled-settings-keys.test.sh +106 -0
- package/tests/example-guards-wrapped-command.test.sh +169 -0
- package/tests/file-edit-backup.test.sh +93 -0
- package/tests/git-filter-repo-guard.test.sh +60 -0
- package/tests/git-global-options-bypass.test.sh +141 -0
- package/tests/git-invocation-prefixes-all-guards.test.sh +114 -0
- package/tests/git-maintenance-guard.test.sh +83 -0
- package/tests/git-pack-temp-cleanup-guard.test.sh +133 -0
- package/tests/git-rm-orphan-wipe-guard.test.sh +66 -0
- package/tests/git-submodule-guard.test.sh +50 -0
- package/tests/grep-pcre-portability.test.sh +155 -0
- package/tests/hook-registration-matches-input.test.sh +73 -0
- package/tests/hook-trigger-matches-envelope.test.sh +178 -0
- package/tests/install-does-not-claim-protection.test.sh +110 -0
- package/tests/install-example-standalone-tools.test.sh +139 -0
- package/tests/line-continuation-bypass.test.sh +114 -0
- package/tests/mcp-config-poisoning-audit.test.sh +106 -0
- package/tests/nested-background-agent-guard.test.sh +58 -0
- package/tests/no-unqualified-safety-claims.test.sh +114 -0
- package/tests/option-eating-grep-patterns.test.sh +130 -0
- package/tests/outdated-core-guards.test.sh +134 -0
- package/tests/outdated-report.test.sh +155 -0
- package/tests/output-secret-mask-warns.test.sh +73 -0
- package/tests/plugin-hooks-fail-open-under-sh.test.sh +165 -0
- package/tests/plugins-word-order.test.sh +126 -0
- package/tests/powershell-remove-item-guard.test.sh +85 -0
- package/tests/project-dir-naming.test.sh +103 -0
- package/tests/quoted-safe-targets-and-mentions.test.sh +190 -0
- package/tests/reroute-after-block-guard.test.sh +104 -0
- package/tests/secret-guard-documented-promises.test.sh +97 -0
- package/tests/session-plugin-pin-watch.test.sh +45 -0
- package/tests/settings-unreadable-refuses-to-write.test.sh +95 -0
- package/tests/shield-no-silent-adoption.test.py +110 -0
- package/tests/shield-no-silent-adoption.test.sh +46 -0
- package/tests/stop-transcript-write-health.test.sh +46 -0
- package/tests/system-dir-guard-root-erased.test.sh +66 -0
- package/tests/test-account-billing-log.sh +100 -0
- package/tests/test-account-routing-preflight.sh +77 -0
- package/tests/test-agent-sdk-credit-pool-monitor.sh +157 -0
- package/tests/test-agent-view-quota-warn.sh +184 -0
- package/tests/test-agents-md-edit-drift-warner.sh +176 -0
- package/tests/test-agents-md-loader.sh +204 -0
- package/tests/test-agents-md-sync-checker.sh +125 -0
- package/tests/test-ai-slop-punctuation-arrest.sh +280 -0
- package/tests/test-allowlist.sh +60 -0
- package/tests/test-always-allow-pattern-suggester.sh +147 -0
- package/tests/test-anthropic-base-url-guard.sh +88 -0
- package/tests/test-articulated-scope-capture.sh +139 -0
- package/tests/test-attachment-traversal-guard.sh +168 -0
- package/tests/test-aup-block-pattern-logger.sh +315 -0
- package/tests/test-aup-false-positive-helper.sh +188 -0
- package/tests/test-aup-large-tool-output-warner.sh +370 -0
- package/tests/test-aup-retry-loop-guard.sh +341 -0
- package/tests/test-auth-expiry-reminder.sh +303 -0
- package/tests/test-auth-macos-sleep-detector.sh +254 -0
- package/tests/test-auth-path-detector.sh +232 -0
- package/tests/test-auth-status-checker.sh +233 -0
- package/tests/test-authorized-reconfirmation-detector.sh +280 -0
- package/tests/test-background-cost-launch-guard.sh +62 -0
- package/tests/test-bash-allowlist-secondary-check.sh +143 -0
- package/tests/test-bash-fanout-bounded-rewriter.sh +186 -0
- package/tests/test-bash-project-fence.sh +127 -0
- package/tests/test-bg-permission-prompt-warner.sh +221 -0
- package/tests/test-binary-read-detector.sh +173 -0
- package/tests/test-broad-prefix-session-trap-warner.sh +167 -0
- package/tests/test-bulk-delete-target-resolution.sh +49 -0
- package/tests/test-bypass-mode-effective-verifier.sh +179 -0
- package/tests/test-cache-creation-drift-detector.sh +244 -0
- package/tests/test-cache-residue-detector.sh +429 -0
- package/tests/test-cache-tier-logger.sh +59 -0
- package/tests/test-cache-ttl-eviction-detector.sh +282 -0
- package/tests/test-cch-sentinel-precommit-guard.sh +64 -0
- package/tests/test-claim-verify-detector.sh +222 -0
- package/tests/test-claim-vs-caveat-checker.sh +134 -0
- package/tests/test-claude-code-version-pin-advisor.sh +353 -0
- package/tests/test-claude-md-reinjector.sh +173 -0
- package/tests/test-claude-md-size-monitor.sh +107 -0
- package/tests/test-claude-update-budget-guard.sh +132 -0
- package/tests/test-claude-update-smart.sh +91 -0
- package/tests/test-claudemd-tool-prohibition.sh +239 -0
- package/tests/test-cli-config-pinning-detector.sh +233 -0
- package/tests/test-cliff-countdown-advisor.sh +138 -0
- package/tests/test-closure-word-verify-gate.sh +158 -0
- package/tests/test-commit-all-scope-guard.sh +73 -0
- package/tests/test-commitment-carry-forward-arrest.sh +250 -0
- package/tests/test-compact-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,152 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# goal-iteration-limit-warner.sh — Warn before /goal command without iteration termination
|
|
3
|
+
#
|
|
4
|
+
# Solves: github.com/anthropics/claude-code/issues/58550
|
|
5
|
+
# "/goal evaluator has no circuit breaker — unsatisfiable conditions burn unlimited tokens"
|
|
6
|
+
#
|
|
7
|
+
# Reporter (2026-05-13): a `/goal` set with no termination clause kept
|
|
8
|
+
# firing the same "condition not satisfied" check for 200+ iterations
|
|
9
|
+
# over 5 hours, consuming approximately 50% of the user's weekly token
|
|
10
|
+
# budget. The assistant cannot programmatically clear a goal; only the
|
|
11
|
+
# user can with `/goal clear`. If the user steps away after setting the
|
|
12
|
+
# goal, the budget burns silently.
|
|
13
|
+
#
|
|
14
|
+
# WHY THIS MATTERS:
|
|
15
|
+
# This is a textbook irreversible-operation pattern: the goal-evaluator's
|
|
16
|
+
# per-turn token spend is non-refundable once consumed, and the only stop
|
|
17
|
+
# condition is the user manually noticing and running `/goal clear`. For
|
|
18
|
+
# developers running Claude Code autonomously or stepping away mid-session,
|
|
19
|
+
# this is a high-impact silent failure.
|
|
20
|
+
#
|
|
21
|
+
# TRIGGER: UserPromptSubmit MATCHER: ""
|
|
22
|
+
#
|
|
23
|
+
# HOW IT WORKS:
|
|
24
|
+
# When the user submits a prompt:
|
|
25
|
+
# 1. Check whether the prompt is a `/goal` command.
|
|
26
|
+
# Skip `/goal clear`, `/goal status`, `/goal evaluate-once`, etc.
|
|
27
|
+
# (anything that isn't setting a new goal).
|
|
28
|
+
# 2. For a goal-setting command, check whether the goal text already
|
|
29
|
+
# contains a termination clause ("stop after", "or stop", "max", a
|
|
30
|
+
# turn-count like "20 turns", "within N iterations", etc.).
|
|
31
|
+
# 3. If no termination clause is present, emit a warning explaining the
|
|
32
|
+
# known iteration-limit bug and recommend adding a clause such as
|
|
33
|
+
# "or stop after 20 turns". Do not block — let the user proceed with
|
|
34
|
+
# eyes open.
|
|
35
|
+
#
|
|
36
|
+
# CONFIGURATION:
|
|
37
|
+
# CC_GOAL_WARN_DISABLE=1 — disable the hook entirely
|
|
38
|
+
# CC_GOAL_WARN_ACTION — "warn" (default) or "block" (exit 2)
|
|
39
|
+
# CC_GOAL_WARN_LOG — log file path (default /tmp/cc-goal-warn.log)
|
|
40
|
+
# CC_GOAL_WARN_MAX_TURNS — suggested max turn count (default 20)
|
|
41
|
+
#
|
|
42
|
+
# Usage:
|
|
43
|
+
# {
|
|
44
|
+
# "hooks": {
|
|
45
|
+
# "UserPromptSubmit": [{
|
|
46
|
+
# "hooks": [{ "type": "command", "command": "~/.claude/hooks/goal-iteration-limit-warner.sh" }]
|
|
47
|
+
# }]
|
|
48
|
+
# }
|
|
49
|
+
# }
|
|
50
|
+
|
|
51
|
+
if [ "${CC_GOAL_WARN_DISABLE:-0}" = "1" ]; then
|
|
52
|
+
exit 0
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
56
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
57
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
58
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
59
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
60
|
+
_nojq_warned="/tmp/cc-nojq-warned-goal-iteration-limit-warner-$PPID"
|
|
61
|
+
[ -f "$_nojq_warned" ] || {
|
|
62
|
+
echo "WARNING [goal-iteration-limit-warner]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
63
|
+
: > "$_nojq_warned"
|
|
64
|
+
}
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
INPUT=$(cat)
|
|
68
|
+
|
|
69
|
+
# Pull user prompt (UserPromptSubmit puts it in tool_input.prompt or .prompt)
|
|
70
|
+
PROMPT=$(printf '%s' "$INPUT" | jq -r '.prompt // .tool_input.prompt // empty' 2>/dev/null)
|
|
71
|
+
if [ -z "$PROMPT" ]; then
|
|
72
|
+
exit 0
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
# Quick scan: only act on /goal commands
|
|
76
|
+
case "$PROMPT" in
|
|
77
|
+
"/goal "*|"/goal"|*$'\n'"/goal "*)
|
|
78
|
+
;;
|
|
79
|
+
*)
|
|
80
|
+
exit 0
|
|
81
|
+
;;
|
|
82
|
+
esac
|
|
83
|
+
|
|
84
|
+
ACTION="${CC_GOAL_WARN_ACTION:-warn}"
|
|
85
|
+
LOG_FILE="${CC_GOAL_WARN_LOG:-/tmp/cc-goal-warn.log}"
|
|
86
|
+
MAX_TURNS="${CC_GOAL_WARN_MAX_TURNS:-20}"
|
|
87
|
+
|
|
88
|
+
# Extract the line that begins with /goal
|
|
89
|
+
GOAL_LINE=$(printf '%s' "$PROMPT" | grep -oE '^/goal[[:space:]]+[^\n]+' | head -1)
|
|
90
|
+
if [ -z "$GOAL_LINE" ]; then
|
|
91
|
+
# Could be just "/goal" with no args — informational, no action needed
|
|
92
|
+
exit 0
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# Skip non-setting subcommands. Anything starting with /goal followed by
|
|
96
|
+
# clear/status/evaluate-once/help/list is not setting a new goal.
|
|
97
|
+
case "$GOAL_LINE" in
|
|
98
|
+
"/goal clear"*|"/goal status"*|"/goal help"*|"/goal list"*|"/goal evaluate-once"*|"/goal evaluate"*|"/goal show"*)
|
|
99
|
+
exit 0
|
|
100
|
+
;;
|
|
101
|
+
esac
|
|
102
|
+
|
|
103
|
+
# Check for a termination clause. These are heuristic — false negatives are
|
|
104
|
+
# acceptable (we just warn once); false positives let a careful user proceed.
|
|
105
|
+
# Patterns:
|
|
106
|
+
# - "stop after"
|
|
107
|
+
# - "or stop"
|
|
108
|
+
# - "max N"
|
|
109
|
+
# - "N turns" / "N iterations" / "N evaluations"
|
|
110
|
+
# - "within N turns"
|
|
111
|
+
# - "after N attempts"
|
|
112
|
+
HAS_LIMIT=0
|
|
113
|
+
if echo "$GOAL_LINE" | grep -qiE '(stop[[:space:]]+after|or[[:space:]]+stop|max[[:space:]]+[0-9]+|[0-9]+[[:space:]]+(turns|iterations|evaluations|attempts|tries)|within[[:space:]]+[0-9]+[[:space:]]+(turns|iterations)|after[[:space:]]+[0-9]+[[:space:]]+(attempts|tries|turns))'; then
|
|
114
|
+
HAS_LIMIT=1
|
|
115
|
+
fi
|
|
116
|
+
|
|
117
|
+
if [ "$HAS_LIMIT" = "1" ]; then
|
|
118
|
+
# Termination clause present — silent pass.
|
|
119
|
+
exit 0
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
|
|
123
|
+
GOAL_TEXT_TRIMMED=$(echo "$GOAL_LINE" | head -c 200)
|
|
124
|
+
echo "[$TIMESTAMP] goal_without_limit detected, action=$ACTION goal_excerpt=$GOAL_TEXT_TRIMMED" >> "$LOG_FILE"
|
|
125
|
+
|
|
126
|
+
MSG="⚠️ /goal without a termination clause detected"
|
|
127
|
+
MSG+=$'\n'" command: $GOAL_TEXT_TRIMMED"
|
|
128
|
+
MSG+=$'\n'
|
|
129
|
+
MSG+=$'\n'" Known bug: github.com/anthropics/claude-code/issues/58550"
|
|
130
|
+
MSG+=$'\n'" The /goal evaluator runs after every assistant turn and has no built-in"
|
|
131
|
+
MSG+=$'\n'" iteration limit. One reported incident: 200+ iterations over 5 hours,"
|
|
132
|
+
MSG+=$'\n'" burning approximately 50% of the user's weekly token quota before the"
|
|
133
|
+
MSG+=$'\n'" user noticed and ran /goal clear. The assistant cannot clear or modify"
|
|
134
|
+
MSG+=$'\n'" a goal programmatically; only the user can."
|
|
135
|
+
MSG+=$'\n'
|
|
136
|
+
MSG+=$'\n'" Recommendation: add an explicit termination clause. Examples:"
|
|
137
|
+
MSG+=$'\n'" /goal <condition> or stop after $MAX_TURNS turns"
|
|
138
|
+
MSG+=$'\n'" /goal <condition>, max $MAX_TURNS iterations"
|
|
139
|
+
MSG+=$'\n'" /goal <condition> within $MAX_TURNS turns"
|
|
140
|
+
MSG+=$'\n'
|
|
141
|
+
MSG+=$'\n'" Reportedly, the 'or stop after N turns' clause is honored by the"
|
|
142
|
+
MSG+=$'\n'" evaluator already (issue #58550 workaround #4). If you proceed without"
|
|
143
|
+
MSG+=$'\n'" a clause, set a phone alarm for ~30 minutes and confirm /goal clear"
|
|
144
|
+
MSG+=$'\n'" if the condition turns out to be unreachable."
|
|
145
|
+
|
|
146
|
+
if [ "$ACTION" = "block" ]; then
|
|
147
|
+
printf '%s\n' "$MSG" >&2
|
|
148
|
+
exit 2
|
|
149
|
+
else
|
|
150
|
+
printf '%s\n' "$MSG" >&2
|
|
151
|
+
exit 0
|
|
152
|
+
fi
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -uo pipefail
|
|
3
|
+
#
|
|
4
|
+
# The registration was missing from this header. The installer reads TRIGGER
|
|
5
|
+
# and MATCHER from here and falls back to PreToolUse / Bash when both are
|
|
6
|
+
# absent, so this hook was being registered at a moment where the field it
|
|
7
|
+
# reads is always empty: it installed, it appeared in the settings, and it
|
|
8
|
+
# did nothing. Measured 2026-08-04 across examples/: 14 files were like this.
|
|
9
|
+
# TRIGGER: PostToolUse
|
|
10
|
+
# MATCHER: "Grep"
|
|
11
|
+
INPUT=$(cat)
|
|
12
|
+
TOOL=$(printf '%s' "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
|
|
13
|
+
[ "$TOOL" = "Grep" ] || exit 0
|
|
14
|
+
RESP=$(printf '%s' "$INPUT" | jq -r '.tool_response // .tool_result // empty' 2>/dev/null)
|
|
15
|
+
printf '%s' "$RESP" | grep -qiE 'no matches found|no files found' || exit 0
|
|
16
|
+
SEARCH=$(printf '%s' "$INPUT" | jq -r '.tool_input.path // "."' 2>/dev/null)
|
|
17
|
+
[ -e "$SEARCH" ] || exit 0
|
|
18
|
+
HIT=$(find "$SEARCH" -type f \
|
|
19
|
+
-not -path '*/.git/*' -not -path '*/node_modules/*' 2>/dev/null \
|
|
20
|
+
| head -300 \
|
|
21
|
+
| while read -r f; do
|
|
22
|
+
if LC_ALL=C grep -qaP '\x00' "$f" 2>/dev/null; then echo "$f"; break; fi
|
|
23
|
+
done)
|
|
24
|
+
if [ -n "$HIT" ]; then
|
|
25
|
+
echo "[grep-nul-guard] Grep returned no matches, but '$HIT' contains a NUL byte." >&2
|
|
26
|
+
echo " ripgrep silently suppresses matches in files it treats as binary, so this" >&2
|
|
27
|
+
echo " 'no matches' may be a false negative. Before concluding the pattern is absent," >&2
|
|
28
|
+
echo " re-search in text mode, e.g. rg -a --text <pattern> <path> (or grep -aP)." >&2
|
|
29
|
+
fi
|
|
30
|
+
exit 0
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# growthbook-flag-monitor.sh — Surface server-pushed GrowthBook
|
|
4
|
+
# flag changes that silently override client-side state.
|
|
5
|
+
# ================================================================
|
|
6
|
+
# PURPOSE:
|
|
7
|
+
# Issue #62205 (2026-05-25, root-cause analysis) documented that
|
|
8
|
+
# the macOS Desktop variant of Claude Code syncs GrowthBook A/B
|
|
9
|
+
# feature flags from the Anthropic server every ~9 minutes and
|
|
10
|
+
# silently overrides the user's local settings.json. Concretely,
|
|
11
|
+
# `permissions.defaultMode: bypassPermissions` flips back to
|
|
12
|
+
# `acceptEdits` on each sync, with the same shape applying to
|
|
13
|
+
# other dispatch surfaces (auto-compact: #63015 suspects
|
|
14
|
+
# `tengu_compact_cache_prefix` gating a new compaction path that
|
|
15
|
+
# silently fails to fire).
|
|
16
|
+
#
|
|
17
|
+
# The local cache file is read-write but not authoritative — any
|
|
18
|
+
# operator edit is restored on the next ~9-minute sync. Local
|
|
19
|
+
# edits do not persist. The five documented override paths in
|
|
20
|
+
# the cluster framing all draw from the cached flag set, so the
|
|
21
|
+
# minimum-viable defense is to make flag changes visible to the
|
|
22
|
+
# operator instead of letting them happen silently in the
|
|
23
|
+
# background.
|
|
24
|
+
#
|
|
25
|
+
# WHO THIS PROTECTS:
|
|
26
|
+
# macOS Claude Desktop operators (where the cache file is at
|
|
27
|
+
# `~/Library/Application Support/Claude/cachedGrowthBookFeatures`).
|
|
28
|
+
# Linux operators where the cache lives under
|
|
29
|
+
# `~/.config/Claude/cachedGrowthBookFeatures` are also covered
|
|
30
|
+
# when the file is present. CLI-only operators are unaffected
|
|
31
|
+
# when the file is absent — the hook stays silent.
|
|
32
|
+
#
|
|
33
|
+
# HOW IT WORKS:
|
|
34
|
+
# On SessionStart, snapshots the current GrowthBook flag set
|
|
35
|
+
# (sha256 over the canonicalised flag-name list, plus the
|
|
36
|
+
# per-flag JSON value digest). Compares against the previous
|
|
37
|
+
# snapshot from `${XDG_STATE_HOME:-$HOME/.local/state}/cc-safe-setup/
|
|
38
|
+
# growthbook-flag-monitor/snapshot.json`. If the set has changed,
|
|
39
|
+
# prints a one-screen stderr advisory listing added / removed /
|
|
40
|
+
# changed flags so the operator sees what shifted while they
|
|
41
|
+
# were away. Always exits 0 (advisory only).
|
|
42
|
+
#
|
|
43
|
+
# The snapshot does NOT contain raw flag values by default
|
|
44
|
+
# (those are server-controlled and can change without notice).
|
|
45
|
+
# The snapshot stores just the flag-name set + per-flag value
|
|
46
|
+
# digest. Set CC_GROWTHBOOK_MONITOR_FULL=1 to also store full
|
|
47
|
+
# values for forensic comparison (off by default to keep the
|
|
48
|
+
# state file small).
|
|
49
|
+
#
|
|
50
|
+
# TRIGGER: SessionStart MATCHER: ""
|
|
51
|
+
# CLUSTER: 10 (GrowthBook A/B flag client-side overrides)
|
|
52
|
+
#
|
|
53
|
+
# CONFIGURATION (env vars):
|
|
54
|
+
# CC_GROWTHBOOK_MONITOR_DISABLE Set to "1" to silence.
|
|
55
|
+
# CC_GROWTHBOOK_MONITOR_PATH Override cache file path.
|
|
56
|
+
# Default: macOS / Linux auto.
|
|
57
|
+
# CC_GROWTHBOOK_MONITOR_STATE_DIR Override snapshot dir.
|
|
58
|
+
# Default: $XDG_STATE_HOME or
|
|
59
|
+
# $HOME/.local/state.
|
|
60
|
+
# CC_GROWTHBOOK_MONITOR_FULL Store full values in
|
|
61
|
+
# snapshot (forensic mode).
|
|
62
|
+
# Default: off (digest only).
|
|
63
|
+
# CC_GROWTHBOOK_MONITOR_QUIET Suppress the no-change line
|
|
64
|
+
# shown on first run / no diff.
|
|
65
|
+
# CC_GROWTHBOOK_MONITOR_LOG Append snapshot events to
|
|
66
|
+
# this file (default off).
|
|
67
|
+
#
|
|
68
|
+
# USAGE:
|
|
69
|
+
# {
|
|
70
|
+
# "hooks": {
|
|
71
|
+
# "SessionStart": [{
|
|
72
|
+
# "hooks": [{
|
|
73
|
+
# "type": "command",
|
|
74
|
+
# "command": "~/.claude/hooks/growthbook-flag-monitor.sh"
|
|
75
|
+
# }]
|
|
76
|
+
# }]
|
|
77
|
+
# }
|
|
78
|
+
# }
|
|
79
|
+
|
|
80
|
+
INPUT=$(cat 2>/dev/null || true)
|
|
81
|
+
|
|
82
|
+
if [ "${CC_GROWTHBOOK_MONITOR_DISABLE:-}" = "1" ]; then
|
|
83
|
+
exit 0
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
# Locate the cachedGrowthBookFeatures file.
|
|
87
|
+
locate_cache() {
|
|
88
|
+
if [ -n "${CC_GROWTHBOOK_MONITOR_PATH:-}" ]; then
|
|
89
|
+
[ -f "$CC_GROWTHBOOK_MONITOR_PATH" ] && echo "$CC_GROWTHBOOK_MONITOR_PATH"
|
|
90
|
+
return 0
|
|
91
|
+
fi
|
|
92
|
+
# macOS Claude Desktop
|
|
93
|
+
if [ -f "$HOME/Library/Application Support/Claude/cachedGrowthBookFeatures" ]; then
|
|
94
|
+
echo "$HOME/Library/Application Support/Claude/cachedGrowthBookFeatures"; return 0
|
|
95
|
+
fi
|
|
96
|
+
# Linux Claude Desktop (XDG)
|
|
97
|
+
if [ -f "${XDG_CONFIG_HOME:-$HOME/.config}/Claude/cachedGrowthBookFeatures" ]; then
|
|
98
|
+
echo "${XDG_CONFIG_HOME:-$HOME/.config}/Claude/cachedGrowthBookFeatures"; return 0
|
|
99
|
+
fi
|
|
100
|
+
# ~/.claude.json carries cachedGrowthBookFeatures on some Claude Code variants
|
|
101
|
+
if [ -f "$HOME/.claude.json" ] && grep -q "cachedGrowthBookFeatures" "$HOME/.claude.json" 2>/dev/null; then
|
|
102
|
+
echo "$HOME/.claude.json"; return 0
|
|
103
|
+
fi
|
|
104
|
+
return 1
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
CACHE_FILE=$(locate_cache)
|
|
108
|
+
if [ -z "$CACHE_FILE" ]; then
|
|
109
|
+
# No GrowthBook cache found — operator is on CLI or has the file disabled.
|
|
110
|
+
exit 0
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
114
|
+
echo "[growthbook-flag-monitor] jq not available; skipping (install jq to enable)" >&2
|
|
115
|
+
exit 0
|
|
116
|
+
fi
|
|
117
|
+
|
|
118
|
+
STATE_DIR="${CC_GROWTHBOOK_MONITOR_STATE_DIR:-${XDG_STATE_HOME:-$HOME/.local/state}/cc-safe-setup/growthbook-flag-monitor}"
|
|
119
|
+
mkdir -p "$STATE_DIR" 2>/dev/null
|
|
120
|
+
SNAPSHOT_FILE="$STATE_DIR/snapshot.json"
|
|
121
|
+
|
|
122
|
+
# Build a normalised flag manifest. The cache file is either:
|
|
123
|
+
# - a JSON object {flag_name: {value: ...}, ...} (Desktop variants)
|
|
124
|
+
# - the full ~/.claude.json with cachedGrowthBookFeatures nested.
|
|
125
|
+
extract_flags() {
|
|
126
|
+
# First try the direct object form
|
|
127
|
+
local payload
|
|
128
|
+
payload=$(jq -c '.cachedGrowthBookFeatures // .' "$CACHE_FILE" 2>/dev/null)
|
|
129
|
+
if [ -z "$payload" ] || [ "$payload" = "null" ]; then
|
|
130
|
+
echo "{}"
|
|
131
|
+
return 1
|
|
132
|
+
fi
|
|
133
|
+
# Normalise to {flag_name: digest_of_value}
|
|
134
|
+
echo "$payload" | jq -c '
|
|
135
|
+
if type == "object" then
|
|
136
|
+
to_entries
|
|
137
|
+
| map({key: .key, value: (.value | tostring | @base64)})
|
|
138
|
+
| from_entries
|
|
139
|
+
else
|
|
140
|
+
{}
|
|
141
|
+
end
|
|
142
|
+
' 2>/dev/null || echo "{}"
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
CURRENT=$(extract_flags)
|
|
146
|
+
if [ -z "$CURRENT" ] || [ "$CURRENT" = "{}" ]; then
|
|
147
|
+
# File present but no flag data — silent skip.
|
|
148
|
+
exit 0
|
|
149
|
+
fi
|
|
150
|
+
|
|
151
|
+
# First run: snapshot and emit baseline notice.
|
|
152
|
+
if [ ! -f "$SNAPSHOT_FILE" ]; then
|
|
153
|
+
if [ "${CC_GROWTHBOOK_MONITOR_FULL:-}" = "1" ]; then
|
|
154
|
+
jq -c '.cachedGrowthBookFeatures // .' "$CACHE_FILE" > "$SNAPSHOT_FILE" 2>/dev/null
|
|
155
|
+
else
|
|
156
|
+
echo "$CURRENT" > "$SNAPSHOT_FILE"
|
|
157
|
+
fi
|
|
158
|
+
if [ -z "${CC_GROWTHBOOK_MONITOR_QUIET:-}" ]; then
|
|
159
|
+
FLAG_COUNT=$(echo "$CURRENT" | jq 'length' 2>/dev/null)
|
|
160
|
+
echo "[growthbook-flag-monitor] baseline snapshot recorded: ${FLAG_COUNT} flags in ${CACHE_FILE}" >&2
|
|
161
|
+
fi
|
|
162
|
+
if [ -n "${CC_GROWTHBOOK_MONITOR_LOG:-}" ]; then
|
|
163
|
+
mkdir -p "$(dirname "$CC_GROWTHBOOK_MONITOR_LOG")" 2>/dev/null
|
|
164
|
+
echo "$(date -Iseconds) event=baseline cache=${CACHE_FILE} flags=${FLAG_COUNT}" >> "$CC_GROWTHBOOK_MONITOR_LOG"
|
|
165
|
+
fi
|
|
166
|
+
exit 0
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
PREVIOUS=$(cat "$SNAPSHOT_FILE" 2>/dev/null)
|
|
170
|
+
if [ "${CC_GROWTHBOOK_MONITOR_FULL:-}" = "1" ]; then
|
|
171
|
+
# Compare full values
|
|
172
|
+
PREVIOUS=$(echo "$PREVIOUS" | jq -c '
|
|
173
|
+
if type == "object" then
|
|
174
|
+
to_entries | map({key: .key, value: (.value | tostring | @base64)}) | from_entries
|
|
175
|
+
else {} end
|
|
176
|
+
' 2>/dev/null)
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
# Compute diff using jq set operations
|
|
180
|
+
DIFF=$(jq -n --argjson prev "$PREVIOUS" --argjson curr "$CURRENT" '
|
|
181
|
+
{
|
|
182
|
+
added: (($curr | keys) - ($prev | keys)),
|
|
183
|
+
removed: (($prev | keys) - ($curr | keys)),
|
|
184
|
+
changed: [
|
|
185
|
+
($curr | keys | .[]) as $k
|
|
186
|
+
| select(($prev | has($k)) and ($prev[$k] != $curr[$k]))
|
|
187
|
+
| $k
|
|
188
|
+
]
|
|
189
|
+
}
|
|
190
|
+
' 2>/dev/null)
|
|
191
|
+
|
|
192
|
+
ADDED=$(echo "$DIFF" | jq -r '.added | length' 2>/dev/null)
|
|
193
|
+
REMOVED=$(echo "$DIFF" | jq -r '.removed | length' 2>/dev/null)
|
|
194
|
+
CHANGED=$(echo "$DIFF" | jq -r '.changed | length' 2>/dev/null)
|
|
195
|
+
TOTAL=$((${ADDED:-0} + ${REMOVED:-0} + ${CHANGED:-0}))
|
|
196
|
+
|
|
197
|
+
if [ "$TOTAL" -eq 0 ]; then
|
|
198
|
+
if [ -z "${CC_GROWTHBOOK_MONITOR_QUIET:-}" ]; then
|
|
199
|
+
FLAG_COUNT=$(echo "$CURRENT" | jq 'length' 2>/dev/null)
|
|
200
|
+
echo "[growthbook-flag-monitor] no GrowthBook flag changes since last session (${FLAG_COUNT} flags tracked)" >&2
|
|
201
|
+
fi
|
|
202
|
+
exit 0
|
|
203
|
+
fi
|
|
204
|
+
|
|
205
|
+
# Emit diff advisory
|
|
206
|
+
cat >&2 <<EOF
|
|
207
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
208
|
+
[growthbook-flag-monitor] SessionStart — GrowthBook flag set changed
|
|
209
|
+
Cache file: ${CACHE_FILE}
|
|
210
|
+
Cluster 10 (server-pushed flag overrides). Anthropic syncs flags
|
|
211
|
+
on a ~9-minute cadence; local edits do not persist across syncs.
|
|
212
|
+
|
|
213
|
+
Changes since last session:
|
|
214
|
+
added: ${ADDED}
|
|
215
|
+
removed: ${REMOVED}
|
|
216
|
+
changed: ${CHANGED}
|
|
217
|
+
EOF
|
|
218
|
+
|
|
219
|
+
if [ "${ADDED:-0}" -gt 0 ]; then
|
|
220
|
+
echo "" >&2
|
|
221
|
+
echo " ADDED:" >&2
|
|
222
|
+
echo "$DIFF" | jq -r '.added[] | " + " + .' >&2
|
|
223
|
+
fi
|
|
224
|
+
if [ "${REMOVED:-0}" -gt 0 ]; then
|
|
225
|
+
echo "" >&2
|
|
226
|
+
echo " REMOVED:" >&2
|
|
227
|
+
echo "$DIFF" | jq -r '.removed[] | " - " + .' >&2
|
|
228
|
+
fi
|
|
229
|
+
if [ "${CHANGED:-0}" -gt 0 ]; then
|
|
230
|
+
echo "" >&2
|
|
231
|
+
echo " CHANGED:" >&2
|
|
232
|
+
echo "$DIFF" | jq -r '.changed[] | " ~ " + .' >&2
|
|
233
|
+
fi
|
|
234
|
+
|
|
235
|
+
cat >&2 <<'EOF'
|
|
236
|
+
|
|
237
|
+
Verify your permissions.defaultMode and other settings.json values
|
|
238
|
+
are still what you expect. Server-pushed flags (e.g.
|
|
239
|
+
tengu_permission_friction, tengu_quill_harbor, tengu_compact_cache_prefix)
|
|
240
|
+
have been observed silently overriding client behavior.
|
|
241
|
+
Issue: https://github.com/anthropics/claude-code/issues/62205
|
|
242
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
243
|
+
EOF
|
|
244
|
+
|
|
245
|
+
# Update the snapshot for the next session
|
|
246
|
+
if [ "${CC_GROWTHBOOK_MONITOR_FULL:-}" = "1" ]; then
|
|
247
|
+
jq -c '.cachedGrowthBookFeatures // .' "$CACHE_FILE" > "$SNAPSHOT_FILE" 2>/dev/null
|
|
248
|
+
else
|
|
249
|
+
echo "$CURRENT" > "$SNAPSHOT_FILE"
|
|
250
|
+
fi
|
|
251
|
+
|
|
252
|
+
if [ -n "${CC_GROWTHBOOK_MONITOR_LOG:-}" ]; then
|
|
253
|
+
mkdir -p "$(dirname "$CC_GROWTHBOOK_MONITOR_LOG")" 2>/dev/null
|
|
254
|
+
echo "$(date -Iseconds) event=diff added=${ADDED} removed=${REMOVED} changed=${CHANGED}" >> "$CC_GROWTHBOOK_MONITOR_LOG"
|
|
255
|
+
fi
|
|
256
|
+
|
|
257
|
+
exit 0
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# halt-signal-detector.sh — Warn before further tool calls when the
|
|
4
|
+
# user's previous message contains a halt
|
|
5
|
+
# token (stop, やめて, halt, etc.)
|
|
6
|
+
# ================================================================
|
|
7
|
+
# PURPOSE:
|
|
8
|
+
# When the previous user message in the transcript contains an
|
|
9
|
+
# explicit halt signal, warn that the upcoming tool call may be
|
|
10
|
+
# reframing the user's halt as a renegotiation. Prevents the
|
|
11
|
+
# "continuation bargaining after halt signals" failure mode reported
|
|
12
|
+
# in Issue #55909 (Cowork mode bargaining), Issue #56351 (refusing
|
|
13
|
+
# to stop digging), and Issue #55363 (/ultrareview ignoring stop).
|
|
14
|
+
#
|
|
15
|
+
# TRIGGER: PreToolUse
|
|
16
|
+
# MATCHER: "*" (all tools)
|
|
17
|
+
#
|
|
18
|
+
# WHY THIS MATTERS:
|
|
19
|
+
# In Issue #55909, the user said "stop / やめて / use a different
|
|
20
|
+
# browser" multiple times, but the model continued operating and
|
|
21
|
+
# replied with bargaining language ("just let me do this one part",
|
|
22
|
+
# "after you log in, send 'OK' and I'll do the rest"). The expected
|
|
23
|
+
# behaviour after a user halt signal is: zero tool calls in the
|
|
24
|
+
# next turn, no requests for partial cooperation. The original plan
|
|
25
|
+
# does not survive into the next response, even softened.
|
|
26
|
+
#
|
|
27
|
+
# This hook detects the halt signal at the input boundary and warns
|
|
28
|
+
# before any tool call is made. It cannot fix the underlying model
|
|
29
|
+
# layer issue, but it removes the bargaining surface from the next
|
|
30
|
+
# turn by surfacing the contradiction to the operator.
|
|
31
|
+
#
|
|
32
|
+
# WHAT IT CHECKS:
|
|
33
|
+
# 1. Read the most recent user message from the transcript
|
|
34
|
+
# 2. Search for halt tokens (Japanese and English)
|
|
35
|
+
# 3. If a halt token is present, emit a warning to stderr
|
|
36
|
+
# 4. If CC_HALT_SIGNAL_BLOCK=1, also exit 2 to block the tool call
|
|
37
|
+
#
|
|
38
|
+
# OUTPUT:
|
|
39
|
+
# Warning to stderr with a snippet of the matched user text and a
|
|
40
|
+
# reference to Issue #55909. Exit 0 (advisory) by default.
|
|
41
|
+
#
|
|
42
|
+
# CONFIGURATION:
|
|
43
|
+
# CC_HALT_SIGNAL_BLOCK — set to "1" to block the tool call (exit 2)
|
|
44
|
+
# when a halt signal is detected. Default is
|
|
45
|
+
# advisory only.
|
|
46
|
+
# CC_HALT_SIGNAL_EXTRA — additional comma-separated halt tokens to
|
|
47
|
+
# match (case-insensitive). Example: "abort,kill"
|
|
48
|
+
#
|
|
49
|
+
# RELATED ISSUES:
|
|
50
|
+
# https://github.com/anthropics/claude-code/issues/55909
|
|
51
|
+
# https://github.com/anthropics/claude-code/issues/56351
|
|
52
|
+
# https://github.com/anthropics/claude-code/issues/55363
|
|
53
|
+
# ================================================================
|
|
54
|
+
|
|
55
|
+
set -u
|
|
56
|
+
|
|
57
|
+
# Without jq, the parse below silently yields empty and this hook stops
|
|
58
|
+
# guarding - with no error anywhere. Say so. We deliberately do not exit
|
|
59
|
+
# here: blocking would halt every tool call, and exiting 0 would change
|
|
60
|
+
# the behaviour of guards that do not depend on the parsed value.
|
|
61
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
62
|
+
_nojq_warned="/tmp/cc-nojq-warned-halt-signal-detector-$PPID"
|
|
63
|
+
[ -f "$_nojq_warned" ] || {
|
|
64
|
+
echo "WARNING [halt-signal-detector]: jq not found - this hook cannot inspect tool calls and is NOT protecting you. Install jq." >&2
|
|
65
|
+
: > "$_nojq_warned"
|
|
66
|
+
}
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
INPUT=$(cat)
|
|
70
|
+
|
|
71
|
+
# Get transcript path from PreToolUse input
|
|
72
|
+
TRANSCRIPT_PATH=$(printf '%s' "$INPUT" | jq -r '.transcript_path // empty' 2>/dev/null)
|
|
73
|
+
|
|
74
|
+
if [ -z "$TRANSCRIPT_PATH" ] || [ ! -f "$TRANSCRIPT_PATH" ]; then
|
|
75
|
+
exit 0
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
# Find the most recent user message
|
|
79
|
+
LAST_USER_LINE=$(grep -h '"type":"user"' "$TRANSCRIPT_PATH" 2>/dev/null | tail -1)
|
|
80
|
+
|
|
81
|
+
if [ -z "$LAST_USER_LINE" ]; then
|
|
82
|
+
exit 0
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
# Extract user text — content may be a string or an array of blocks
|
|
86
|
+
USER_TEXT=$(printf '%s' "$LAST_USER_LINE" | jq -r '
|
|
87
|
+
if (.message.content | type) == "string" then
|
|
88
|
+
.message.content
|
|
89
|
+
elif (.message.content | type) == "array" then
|
|
90
|
+
[.message.content[] | select(.type == "text") | .text] | join(" ")
|
|
91
|
+
else
|
|
92
|
+
empty
|
|
93
|
+
end
|
|
94
|
+
' 2>/dev/null)
|
|
95
|
+
|
|
96
|
+
if [ -z "$USER_TEXT" ]; then
|
|
97
|
+
exit 0
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
# Skip if user text looks like a system-generated nudge (idle prompt, hook output)
|
|
101
|
+
if printf '%s' "$USER_TEXT" | grep -qE '^\[idle [0-9]+s|^<system-reminder>|^BLOCKED:'; then
|
|
102
|
+
exit 0
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
# Halt signal patterns — explicit stop/halt verbs
|
|
106
|
+
# Japanese: やめて, やめろ, 止めて, 止まれ, 中断, 中止, ストップ
|
|
107
|
+
# English: stop, halt, abort, cease, do not, don't
|
|
108
|
+
HALT_BASE='やめて|やめろ|止めて|止まれ|中断|中止|ストップ|\bstop\b|\bhalt\b|\babort\b|\bcease\b|\bdo not\b|\bdon'\''t\b'
|
|
109
|
+
|
|
110
|
+
# Optional extra patterns from env
|
|
111
|
+
EXTRA="${CC_HALT_SIGNAL_EXTRA:-}"
|
|
112
|
+
if [ -n "$EXTRA" ]; then
|
|
113
|
+
EXTRA_PATTERN=$(printf '%s' "$EXTRA" | tr ',' '|')
|
|
114
|
+
HALT_PATTERN="${HALT_BASE}|${EXTRA_PATTERN}"
|
|
115
|
+
else
|
|
116
|
+
HALT_PATTERN="$HALT_BASE"
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
# Check for halt signal (case-insensitive)
|
|
120
|
+
if printf '%s' "$USER_TEXT" | grep -qiE "$HALT_PATTERN"; then
|
|
121
|
+
SNIPPET=$(printf '%s' "$USER_TEXT" | head -c 160 | tr '\n' ' ')
|
|
122
|
+
cat >&2 <<EOF
|
|
123
|
+
🛑 halt-signal-detector: 直前の利用者の応答に停止の合図が含まれています。
|
|
124
|
+
検出した文脈: ${SNIPPET}...
|
|
125
|
+
この道具の呼び出しが、 利用者の停止の合図を「計画の調整の依頼」 として再解釈していないか確認してください。
|
|
126
|
+
「これだけ」「ここだけ」「短い合図を送ってください」 のような部分的な協力の依頼は、 利用者から見ると停止の合図の無視と等価です。
|
|
127
|
+
期待される動き: 次の応答で道具の呼び出しゼロ、 状態の報告と利用者への確認のみ。
|
|
128
|
+
Reference: https://github.com/anthropics/claude-code/issues/55909
|
|
129
|
+
EOF
|
|
130
|
+
if [ "${CC_HALT_SIGNAL_BLOCK:-0}" = "1" ]; then
|
|
131
|
+
exit 2
|
|
132
|
+
fi
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
exit 0
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# handoff-on-clear.sh — Write a handoff note at /clear, before the context goes
|
|
3
|
+
#
|
|
4
|
+
# Solves: /clear wipes the conversation with no chance to act first, and no hook
|
|
5
|
+
# can block it — slash commands never reach UserPromptSubmit (measured
|
|
6
|
+
# 2026-09-19 on 2.1.270; the table is in clear-command-confirm-guard.sh).
|
|
7
|
+
# People ask for a PreClear event for exactly this (#95199).
|
|
8
|
+
#
|
|
9
|
+
# How it works: SessionEnd fires with reason="clear", and at that moment
|
|
10
|
+
# transcript_path still points at a readable file — 271,593 bytes of it in the
|
|
11
|
+
# run this was measured on. The conversation is not gone yet, so this hook
|
|
12
|
+
# reads it and writes HANDOFF.md next to the project before the wipe.
|
|
13
|
+
#
|
|
14
|
+
# This is "derive and save", never "hold on, are you sure". SessionEnd cannot
|
|
15
|
+
# cancel the clear and gives no ordering guarantee against the wipe.
|
|
16
|
+
#
|
|
17
|
+
# TRIGGER: SessionEnd
|
|
18
|
+
# MATCHER: ""
|
|
19
|
+
#
|
|
20
|
+
# Usage:
|
|
21
|
+
# {
|
|
22
|
+
# "hooks": {
|
|
23
|
+
# "SessionEnd": [{
|
|
24
|
+
# "hooks": [{ "type": "command", "command": "~/.claude/hooks/handoff-on-clear.sh" }]
|
|
25
|
+
# }]
|
|
26
|
+
# }
|
|
27
|
+
# }
|
|
28
|
+
|
|
29
|
+
set -uo pipefail
|
|
30
|
+
INPUT=$(cat)
|
|
31
|
+
|
|
32
|
+
# Without jq there is nothing to read the event with. Say so rather than failing
|
|
33
|
+
# silently: a handoff that never gets written looks identical to one not needed.
|
|
34
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
35
|
+
echo "WARNING [handoff-on-clear]: jq not found - no handoff will be written. Install jq." >&2
|
|
36
|
+
exit 0
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
# Only /clear. The other SessionEnd reasons (prompt_input_exit, logout) end the
|
|
40
|
+
# session without the user losing context they expected to keep.
|
|
41
|
+
[ "$(printf '%s' "$INPUT" | jq -r '.reason // empty')" = "clear" ] || exit 0
|
|
42
|
+
|
|
43
|
+
tp=$(printf '%s' "$INPUT" | jq -r '.transcript_path // empty')
|
|
44
|
+
cwd=$(printf '%s' "$INPUT" | jq -r '.cwd // empty')
|
|
45
|
+
if [ -z "$tp" ] || [ ! -f "$tp" ]; then
|
|
46
|
+
echo "WARNING [handoff-on-clear]: no readable transcript at '$tp' - nothing written." >&2
|
|
47
|
+
exit 0
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
out="${cwd:-.}/HANDOFF.md"
|
|
51
|
+
{
|
|
52
|
+
printf '# Handoff (written at /clear, %s)\n\n' "$(date -Is)"
|
|
53
|
+
printf -- '- transcript: `%s`\n' "$tp"
|
|
54
|
+
printf -- '- turns: %s user / %s assistant\n\n' \
|
|
55
|
+
"$(jq -rs '[.[] | select(.type=="user")] | length' "$tp" 2>/dev/null)" \
|
|
56
|
+
"$(jq -rs '[.[] | select(.type=="assistant")] | length' "$tp" 2>/dev/null)"
|
|
57
|
+
printf '## Last thing you asked for\n\n'
|
|
58
|
+
jq -rs '[.[] | select(.type=="user") | .message.content] | last
|
|
59
|
+
| if type=="array" then map(select(.type=="text").text) | join("\n") else . end' \
|
|
60
|
+
"$tp" 2>/dev/null | head -c 1200
|
|
61
|
+
printf '\n'
|
|
62
|
+
} > "$out"
|
|
63
|
+
|
|
64
|
+
echo "handoff-on-clear: wrote $out" >&2
|
|
65
|
+
exit 0
|
|
File without changes
|
|
File without changes
|