cc-safe-setup 29.7.0 → 30.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +72 -19
- package/.claude-plugin/plugin.json +1 -1
- package/CONTRIBUTING.md +7 -2
- package/COOKBOOK.md +50 -46
- package/LICENSE +21 -0
- package/MIGRATION.md +8 -8
- package/README.md +419 -512
- package/SAFETY_CHECKLIST.md +15 -7
- package/SERVICES.md +194 -0
- package/SETTINGS_REFERENCE.md +236 -17
- package/SKILL.md +5 -5
- package/TROUBLESHOOTING.md +35 -14
- package/action.yml +12 -4
- package/audit/README.md +84 -0
- package/audit/audit-checklist.md +152 -0
- package/audit/boundary-selftest.sh +85 -0
- package/audit/boundary.sh +123 -0
- package/audit/count-hooks.py +42 -0
- package/audit/find-dead-hooks.sh +82 -0
- package/audit/find-unfirable-rules.sh +142 -0
- package/audit/fire.sh +97 -0
- package/audit/selftest.sh +42 -0
- package/audit/unfirable-selftest.sh +81 -0
- package/audit-web/index.html +9 -9
- package/examples/README.md +54 -17
- package/examples/account-billing-log.sh +98 -0
- package/examples/account-routing-preflight.sh +123 -0
- package/examples/agent-sdk-credit-pool-monitor.sh +145 -0
- package/examples/agent-view-quota-decrement.sh +32 -0
- package/examples/agent-view-quota-warn.sh +94 -0
- package/examples/agents-md-edit-drift-warner.sh +223 -0
- package/examples/agents-md-loader.sh +160 -0
- package/examples/agents-md-sync-checker.sh +102 -0
- package/examples/ai-slop-punctuation-arrest.sh +210 -0
- package/examples/allowlist.sh +70 -10
- package/examples/always-allow-pattern-suggester.sh +125 -0
- package/examples/ansible-vault-guard.sh +2 -1
- package/examples/anthropic-base-url-guard.sh +76 -0
- package/examples/api-busyloop-guard.sh +123 -0
- package/examples/api-endpoint-guard.sh +12 -0
- package/examples/api-key-in-url-guard.sh +17 -1
- package/examples/api-rate-limit-guard.sh +36 -1
- package/examples/api-rate-limit-tracker.sh +12 -0
- package/examples/articulated-scope-capture.sh +101 -0
- package/examples/askuserquestion-autonomy-gate.sh +102 -0
- package/examples/attachment-traversal-guard.sh +118 -0
- package/examples/aup-block-pattern-logger.sh +161 -0
- package/examples/aup-false-positive-helper.sh +124 -0
- package/examples/aup-large-tool-output-warner.sh +282 -0
- package/examples/aup-retry-loop-guard.sh +229 -0
- package/examples/auth-expiry-reminder.sh +157 -0
- package/examples/auth-macos-sleep-detector.sh +185 -0
- package/examples/auth-path-detector.sh +171 -0
- package/examples/auth-status-checker.sh +157 -0
- package/examples/authorized-reconfirmation-detector.sh +195 -0
- package/examples/auto-approve-build.sh +39 -0
- package/examples/auto-approve-cargo.sh +31 -1
- package/examples/auto-approve-docker.sh +35 -0
- package/examples/auto-approve-git-read.sh +37 -14
- package/examples/auto-approve-go.sh +30 -1
- package/examples/auto-approve-gradle.sh +29 -1
- package/examples/auto-approve-make.sh +29 -1
- package/examples/auto-approve-maven.sh +29 -1
- package/examples/auto-approve-python.sh +41 -1
- package/examples/auto-approve-readonly-tools.sh +1 -0
- package/examples/auto-approve-readonly.sh +110 -33
- package/examples/auto-approve-ssh.sh +30 -1
- package/examples/auto-approve-test.sh +44 -0
- package/examples/auto-checkpoint.sh +1 -1
- package/examples/auto-compact-prep.sh +0 -0
- package/examples/auto-git-checkpoint.sh +0 -0
- package/examples/auto-mode-safe-commands.sh +53 -1
- package/examples/auto-mode-safety-enforcer.sh +151 -4
- package/examples/auto-push-session-branch.sh +22 -0
- package/examples/aws-production-guard.sh +13 -1
- package/examples/aws-region-guard.sh +1 -1
- package/examples/background-cost-launch-guard.sh +82 -0
- package/examples/background-task-guard.sh +12 -0
- package/examples/backup-before-refactor.sh +0 -0
- package/examples/banned-command-guard.sh +12 -0
- package/examples/bash-allowlist-secondary-check.sh +157 -0
- package/examples/bash-domain-allowlist.sh +12 -0
- package/examples/bash-fanout-bounded-rewriter.sh +191 -0
- package/examples/bash-heuristic-approver.sh +112 -10
- package/examples/bash-project-fence.sh +194 -0
- package/examples/bash-safety-auto-deny.sh +12 -0
- package/examples/bash-secret-output-detector.sh +44 -3
- package/examples/bash-trace-guard.sh +12 -0
- package/examples/bashrc-safety-check.sh +0 -0
- package/examples/bg-permission-prompt-warner.sh +182 -0
- package/examples/bg-task-cooldown-guard.sh +12 -0
- package/examples/binary-read-detector.sh +135 -0
- package/examples/binary-upload-guard.sh +12 -0
- package/examples/block-database-wipe.sh +35 -10
- package/examples/branch-name-check.sh +8 -3
- package/examples/branch-naming-convention.sh +0 -0
- package/examples/broad-find-guard.sh +12 -0
- package/examples/broad-prefix-session-trap-warner.sh +106 -0
- package/examples/bulk-file-delete-guard.sh +45 -0
- package/examples/bypass-mode-effective-verifier.sh +203 -0
- package/examples/cache-creation-drift-detector.sh +120 -0
- package/examples/cache-residue-detector.sh +195 -0
- package/examples/cache-tier-logger.sh +70 -0
- package/examples/cache-ttl-eviction-detector.sh +149 -0
- package/examples/cargo-publish-guard.sh +14 -1
- package/examples/case-insensitive-path-guard.sh +21 -2
- package/examples/case-sensitive-guard.sh +23 -2
- package/examples/cch-cache-guard.sh +0 -0
- package/examples/cch-sentinel-precommit-guard.sh +47 -0
- package/examples/check-abort-controller.sh +1 -1
- package/examples/check-accessibility.sh +0 -0
- package/examples/check-aria-labels.sh +0 -0
- package/examples/check-before-act-enforcer.sh +12 -0
- package/examples/check-charset-meta.sh +0 -0
- package/examples/check-cookie-flags.sh +0 -0
- package/examples/check-cors-config.sh +0 -0
- package/examples/check-csp-headers.sh +0 -0
- package/examples/check-csrf-protection.sh +0 -0
- package/examples/check-debounce.sh +1 -1
- package/examples/check-dependency-age.sh +0 -0
- package/examples/check-dependency-license.sh +0 -0
- package/examples/check-dockerfile-best-practice.sh +0 -0
- package/examples/check-error-boundaries.sh +0 -0
- package/examples/check-error-class.sh +1 -1
- package/examples/check-error-handling.sh +0 -0
- package/examples/check-error-logging.sh +1 -1
- package/examples/check-error-message.sh +0 -0
- package/examples/check-error-stack.sh +0 -0
- package/examples/check-favicon.sh +0 -0
- package/examples/check-git-hooks-compat.sh +0 -0
- package/examples/check-gitattributes.sh +0 -0
- package/examples/check-https-redirect.sh +0 -0
- package/examples/check-input-validation.sh +0 -0
- package/examples/check-lang-attribute.sh +0 -0
- package/examples/check-npm-scripts-exist.sh +0 -0
- package/examples/check-package-size.sh +0 -0
- package/examples/check-port-availability.sh +0 -0
- package/examples/check-promise-all.sh +1 -1
- package/examples/check-rate-limiting.sh +0 -0
- package/examples/check-return-types.sh +0 -0
- package/examples/check-semantic-versioning.sh +0 -0
- package/examples/check-suspense-fallback.sh +1 -1
- package/examples/check-test-exists.sh +0 -0
- package/examples/check-test-naming.sh +0 -0
- package/examples/check-timeout-cleanup.sh +1 -1
- package/examples/check-tls-version.sh +0 -0
- package/examples/check-unsubscribe.sh +1 -1
- package/examples/check-viewport-meta.sh +0 -0
- package/examples/check-worker-terminate.sh +1 -1
- package/examples/checkpoint-tamper-guard.sh +12 -0
- package/examples/chmod-guard.sh +12 -0
- package/examples/chown-guard.sh +24 -0
- package/examples/ci-workflow-guard.sh +6 -1
- package/examples/claim-verify-detector.sh +109 -0
- package/examples/claim-vs-caveat-checker.sh +77 -0
- package/examples/classifier-fallback-allow.sh +114 -40
- package/examples/claude-cache-gc.sh +1 -0
- package/examples/claude-code-version-pin-advisor.sh +183 -0
- package/examples/claude-md-reinjector.sh +129 -0
- package/examples/claude-md-size-monitor.sh +66 -0
- package/examples/claude-update-budget-guard.sh +123 -0
- package/examples/claude-update-smart.sh +113 -0
- package/examples/claudeignore-enforce-guard.sh +12 -0
- package/examples/claudemd-enforcer.sh +0 -0
- package/examples/claudemd-tool-prohibition.sh +128 -0
- package/examples/clear-command-confirm-guard.sh +32 -15
- package/examples/cli-config-pinning-detector.sh +162 -0
- package/examples/cliff-countdown-advisor.sh +96 -0
- package/examples/clipboard-secret-guard.sh +12 -0
- package/examples/closure-word-verify-gate.sh +150 -0
- package/examples/cloud-cli-guard.sh +39 -2
- package/examples/commit-all-scope-guard.sh +44 -0
- package/examples/commit-message-check.sh +1 -1
- package/examples/commit-message-quality.sh +6 -1
- package/examples/commitment-carry-forward-arrest.sh +361 -0
- package/examples/compact-alert-notification.sh +0 -0
- package/examples/compact-circuit-breaker.sh +72 -0
- package/examples/compact-dispatch-watchdog.sh +149 -0
- package/examples/completion-claim-without-verification-detector.sh +207 -0
- package/examples/composer-guard.sh +12 -0
- package/examples/compound-bash-permission-resolver.sh +156 -0
- package/examples/compound-command-allow.sh +1 -1
- package/examples/compound-command-deny-enforcer.sh +183 -0
- package/examples/compound-inject-guard.sh +12 -0
- package/examples/concurrent-edit-lock.sh +12 -0
- package/examples/conflict-marker-guard.sh +12 -0
- package/examples/consecutive-error-breaker.sh +0 -0
- package/examples/console-log-count.sh +1 -0
- package/examples/context-compact-advisor.sh +29 -2
- package/examples/context-length-budget.sh +69 -0
- package/examples/context-threshold-alert.sh +12 -0
- package/examples/context-usage-drift-alert.sh +41 -13
- package/examples/conversation-history-guard.sh +12 -0
- package/examples/core-file-protect-guard.sh +12 -0
- package/examples/cors-star-warn.sh +0 -0
- package/examples/cost-incident-self-audit.sh +162 -0
- package/examples/cowork-claude-md-load-checker.sh +100 -0
- package/examples/cowork-fuse-staleness-watcher.sh +140 -0
- package/examples/cowork-hook-absence-warner.sh +167 -0
- package/examples/cowork-model-picker-advisor.sh +115 -0
- package/examples/credential-exfil-guard.sh +65 -4
- package/examples/credential-file-cat-guard.sh +17 -1
- package/examples/cron-create-receipt.sh +112 -0
- package/examples/cron-modification-guard.sh +12 -0
- package/examples/cross-product-mcp-spawn-detector.sh +178 -0
- package/examples/cwd-project-boundary-guard.sh +0 -0
- package/examples/daemon-zombie-worker-surfacer.sh +118 -0
- package/examples/daily-cost-guard.sh +164 -0
- package/examples/daily-usage-tracker.sh +0 -0
- package/examples/dangerous-pip-flag-guard.sh +12 -0
- package/examples/db-connect-guard.sh +13 -1
- package/examples/denied-action-retry-guard.sh +12 -0
- package/examples/deny-bypass-detector.sh +12 -0
- package/examples/deny-rule-integrity-verifier.sh +181 -0
- package/examples/dependency-install-guard.sh +12 -0
- package/examples/deploy-guard.sh +14 -2
- package/examples/deploy-path-verify-guard.sh +12 -0
- package/examples/deployment-readback-gate.sh +135 -0
- package/examples/deployment-readback-gh-adapter.sh +247 -0
- package/examples/deployment-verify-guard.sh +25 -2
- package/examples/destructive-db-script-write-guard.sh +166 -0
- package/examples/destructive-migration-write-guard.sh +163 -0
- package/examples/diff-size-guard.sh +12 -0
- package/examples/disabled-feature-toggle-advisor.sh +88 -0
- package/examples/disk-partition-guard.sh +12 -0
- package/examples/dispatch-allowlist-preflight.sh +301 -0
- package/examples/dispatch-liveness-watchdog.sh +216 -0
- package/examples/dispatch-receipt.sh +174 -0
- package/examples/django-migrate-guard.sh +12 -0
- package/examples/dns-config-guard.sh +12 -0
- package/examples/docker-dangerous-guard.sh +12 -0
- package/examples/docker-volume-guard.sh +0 -0
- package/examples/dockerfile-latest-guard.sh +1 -0
- package/examples/dotenv-anthropic-key-billing-guard.sh +99 -0
- package/examples/dotenv-commit-guard.sh +12 -0
- package/examples/dotenv-read-guard.sh +12 -0
- package/examples/dotfile-protection-guard.sh +12 -0
- package/examples/dotnet-build-on-edit.sh +1 -1
- package/examples/drizzle-migrate-guard.sh +27 -2
- package/examples/echo-probe-spam-detector.sh +176 -0
- package/examples/edit-counter-test-gate.sh +12 -0
- package/examples/edit-error-counter.sh +1 -1
- package/examples/edit-guard.sh +12 -0
- package/examples/edit-old-string-validator.sh +12 -0
- package/examples/edit-quote-ambiguity-guard.sh +97 -0
- package/examples/edit-retry-loop-guard.sh +0 -0
- package/examples/edit-verify.sh +0 -0
- package/examples/env-inline-secret-guard.sh +14 -2
- package/examples/env-naming-convention.sh +0 -0
- package/examples/env-prod-guard.sh +0 -0
- package/examples/env-required-check.sh +0 -0
- package/examples/env-source-guard.sh +12 -0
- package/examples/env-var-check.sh +24 -1
- package/examples/ephemeral-container-detector.sh +147 -0
- package/examples/error-memory-guard.sh +12 -0
- package/examples/evidence-claim-gate.sh +187 -0
- package/examples/exploration-budget-guard.sh +89 -0
- package/examples/expo-eject-guard.sh +13 -0
- package/examples/extended-thinking-loop-guard.sh +139 -0
- package/examples/extended-thinking-resume-warning.sh +119 -0
- package/examples/extended-thinking-tool-use-mismatch-detector.sh +212 -0
- package/examples/fabricated-command-detector.sh +145 -0
- package/examples/false-disk-full-guard.sh +63 -0
- package/examples/feature-deprecation-detector.sh +109 -0
- package/examples/file-change-tracker.sh +1 -1
- package/examples/file-change-undo-tracker.sh +0 -0
- package/examples/file-edit-backup.sh +63 -14
- package/examples/file-reference-check.sh +0 -0
- package/examples/file-size-limit.sh +12 -0
- package/examples/financial-operation-guard.sh +12 -0
- package/examples/firewall-guard.sh +12 -0
- package/examples/fish-shell-wrapper.sh +125 -7
- package/examples/five-hundred-milestone.sh +1 -0
- package/examples/flask-static-route-guard.sh +89 -0
- package/examples/forbidden-response-phrase-detector.sh +161 -0
- package/examples/gem-push-guard.sh +13 -0
- package/examples/gh-cli-destructive-guard.sh +13 -1
- package/examples/git-checkout-safety-guard.sh +12 -0
- package/examples/git-checkout-uncommitted-guard.sh +12 -0
- package/examples/git-config-guard.sh +12 -0
- package/examples/git-crypt-worktree-guard.sh +12 -0
- package/examples/git-filter-repo-guard.sh +56 -0
- package/examples/git-history-rewrite-guard.sh +12 -0
- package/examples/git-hook-bypass-guard.sh +0 -0
- package/examples/git-maintenance-guard.sh +83 -0
- package/examples/git-merge-conflict-prevent.sh +0 -0
- package/examples/git-message-length-check.sh +0 -0
- package/examples/git-message-length.sh +0 -0
- package/examples/git-operations-require-approval.sh +68 -14
- package/examples/git-pack-temp-cleanup-guard.sh +102 -0
- package/examples/git-push-blast-radius-guard.sh +218 -0
- package/examples/git-remote-guard.sh +24 -3
- package/examples/git-rm-orphan-wipe-guard.sh +85 -0
- package/examples/git-stash-before-checkout.sh +12 -0
- package/examples/git-stash-before-danger.sh +0 -0
- package/examples/git-submodule-guard.sh +69 -2
- package/examples/git-tag-guard.sh +12 -0
- package/examples/github-actions-secret-guard.sh +0 -0
- package/examples/gitignore-check.sh +0 -0
- package/examples/gitops-drift-guard.sh +12 -0
- package/examples/go-mod-tidy-warn.sh +1 -0
- package/examples/go-vet-after-edit.sh +12 -0
- package/examples/goal-iteration-limit-warner.sh +152 -0
- package/examples/grep-nul-false-negative-guard.sh +30 -0
- package/examples/growthbook-flag-monitor.sh +257 -0
- package/examples/hallucination-url-check.sh +1 -1
- package/examples/halt-signal-detector.sh +135 -0
- package/examples/handoff-on-clear.sh +65 -0
- package/examples/hardcoded-ip-guard.sh +1 -0
- package/examples/headless-empty-result-guard.sh +0 -0
- package/examples/headless-stop-guard.sh +0 -0
- package/examples/helm-install-guard.sh +2 -1
- package/examples/home-critical-bash-guard.sh +17 -1
- package/examples/hook-debug-wrapper.sh +6 -2
- package/examples/hook-permission-fixer.sh +0 -0
- package/examples/hook-self-disable-detector.sh +99 -0
- package/examples/hook-stdout-sanitizer.sh +6 -2
- package/examples/hook-tamper-guard.sh +12 -0
- package/examples/idle-session-cost-alert.sh +0 -0
- package/examples/image-dimension-guard.sh +109 -0
- package/examples/image-file-validator.sh +0 -0
- package/examples/iteration-quality-degradation-detector.sh +170 -0
- package/examples/java-compile-on-edit.sh +1 -1
- package/examples/json-syntax-check.sh +0 -0
- package/examples/k8s-production-guard.sh +13 -1
- package/examples/kill-process-guard.sh +12 -0
- package/examples/kubernetes-guard.sh +13 -1
- package/examples/laravel-artisan-guard.sh +13 -0
- package/examples/large-file-guard.sh +1 -1
- package/examples/log-level-guard.sh +0 -0
- package/examples/log-truncation-guard.sh +12 -0
- package/examples/long-session-malformed-tool-call-detector.sh +183 -0
- package/examples/loop-detector.sh +12 -0
- package/examples/magic-number-warn.sh +1 -0
- package/examples/main-branch-warn.sh +12 -0
- package/examples/markdown-link-check.sh +0 -0
- package/examples/max-concurrent-agents.sh +12 -0
- package/examples/max-edit-size-guard.sh +13 -0
- package/examples/max-file-count-guard.sh +0 -0
- package/examples/max-file-delete-count.sh +0 -0
- package/examples/max-function-length.sh +1 -0
- package/examples/max-import-count.sh +0 -0
- package/examples/max-subagent-count.sh +0 -0
- package/examples/mcp-config-freeze.sh +12 -0
- package/examples/mcp-config-poisoning-audit.sh +150 -0
- package/examples/mcp-data-boundary.sh +1 -1
- package/examples/mcp-misdiagnosis-arrest.sh +209 -0
- package/examples/mcp-orphan-leak-warner.sh +49 -0
- package/examples/mcp-permissions-ask-warner.sh +151 -0
- package/examples/mcp-routine-approval-detector.sh +154 -0
- package/examples/mcp-server-allowlist.sh +12 -0
- package/examples/mcp-server-guard.sh +12 -0
- package/examples/mcp-startup-bloat-detector.sh +87 -0
- package/examples/mcp-stdio-compatibility-test.sh +153 -0
- package/examples/mcp-tool-audit-log.sh +0 -0
- package/examples/mcp-tool-guard.sh +101 -1
- package/examples/mcp-warmup-wait.sh +0 -0
- package/examples/memory-chain-audit.sh +56 -0
- package/examples/memory-orphan-detector.sh +188 -0
- package/examples/memory-write-guard.sh +99 -17
- package/examples/migration-verify-guard.sh +12 -0
- package/examples/model-swap-suggester.sh +177 -0
- package/examples/model-version-alert.sh +5 -1
- package/examples/model-version-lock.sh +63 -0
- package/examples/move-delete-sequence-guard.sh +33 -2
- package/examples/multi-file-plan-routing-gate.sh +192 -0
- package/examples/multi-vendor-concurrent-warner.sh +108 -0
- package/examples/multi-window-auth-drift-detector.sh +183 -0
- package/examples/multiline-command-approver.sh +161 -23
- package/examples/nested-background-agent-guard.sh +109 -0
- package/examples/nested-spawn-inflight-guard.sh +178 -0
- package/examples/network-exfil-guard.sh +12 -0
- package/examples/network-guard.sh +12 -0
- package/examples/network-interface-guard.sh +12 -0
- package/examples/nextjs-env-guard.sh +1 -1
- package/examples/no-absolute-import.sh +0 -0
- package/examples/no-alert-confirm-prompt.sh +0 -0
- package/examples/no-anonymous-default-export.sh +0 -0
- package/examples/no-any-type.sh +0 -0
- package/examples/no-any-typescript.sh +1 -0
- package/examples/no-ask-human.sh +12 -0
- package/examples/no-assignment-in-condition.sh +0 -0
- package/examples/no-base64-exfil.sh +12 -0
- package/examples/no-callback-hell.sh +0 -0
- package/examples/no-circular-dependency.sh +0 -0
- package/examples/no-cleartext-storage.sh +0 -0
- package/examples/no-commented-code.sh +0 -0
- package/examples/no-commit-fixup.sh +0 -0
- package/examples/no-console-assert.sh +0 -0
- package/examples/no-console-error-swallow.sh +0 -0
- package/examples/no-console-in-prod.sh +0 -0
- package/examples/no-console-log-commit.sh +12 -0
- package/examples/no-console-log.sh +0 -0
- package/examples/no-console-time.sh +0 -0
- package/examples/no-cors-wildcard.sh +4 -1
- package/examples/no-curl-upload.sh +0 -0
- package/examples/no-dangerouslySetInnerHTML.sh +0 -0
- package/examples/no-dangling-await.sh +1 -0
- package/examples/no-debug-commit.sh +12 -0
- package/examples/no-debug-in-commit.sh +0 -0
- package/examples/no-deep-nesting.sh +0 -0
- package/examples/no-deep-relative-import.sh +1 -0
- package/examples/no-default-credentials.sh +0 -0
- package/examples/no-deploy-friday.sh +13 -1
- package/examples/no-disabled-test.sh +0 -0
- package/examples/no-document-write.sh +0 -0
- package/examples/no-empty-function.sh +0 -0
- package/examples/no-eval-in-template.sh +0 -0
- package/examples/no-eval-template.sh +3 -1
- package/examples/no-eval.sh +0 -0
- package/examples/no-exec-user-input.sh +0 -0
- package/examples/no-fixme-ship.sh +12 -0
- package/examples/no-floating-promises.sh +0 -0
- package/examples/no-force-flag.sh +22 -5
- package/examples/no-force-install.sh +0 -0
- package/examples/no-git-amend.sh +12 -0
- package/examples/no-git-rebase-public.sh +0 -0
- package/examples/no-global-install.sh +12 -0
- package/examples/no-global-state.sh +0 -0
- package/examples/no-hardcoded-port.sh +1 -0
- package/examples/no-hardcoded-url.sh +0 -0
- package/examples/no-helmet-missing.sh +0 -0
- package/examples/no-http-url.sh +1 -0
- package/examples/no-http-without-https.sh +0 -0
- package/examples/no-inline-style.sh +0 -0
- package/examples/no-inline-styles.sh +1 -0
- package/examples/no-innerhtml.sh +0 -0
- package/examples/no-install-global.sh +12 -0
- package/examples/no-jwt-in-url.sh +0 -0
- package/examples/no-large-commit.sh +0 -0
- package/examples/no-localhost-expose.sh +0 -0
- package/examples/no-magic-number.sh +0 -0
- package/examples/no-md5-sha1.sh +0 -0
- package/examples/no-mixed-line-endings.sh +8 -1
- package/examples/no-mutation-in-reducer.sh +0 -0
- package/examples/no-nested-ternary.sh +0 -0
- package/examples/no-network-exfil.sh +0 -0
- package/examples/no-open-redirect.sh +0 -0
- package/examples/no-output-truncation.sh +12 -0
- package/examples/no-package-downgrade.sh +0 -0
- package/examples/no-package-lock-edit.sh +12 -0
- package/examples/no-path-join-user-input.sh +0 -0
- package/examples/no-port-bind.sh +0 -0
- package/examples/no-process-exit.sh +0 -0
- package/examples/no-prototype-pollution.sh +0 -0
- package/examples/no-push-without-ci.sh +0 -0
- package/examples/no-push-without-tests.sh +12 -0
- package/examples/no-raw-password-in-url.sh +0 -0
- package/examples/no-root-user-docker.sh +1 -0
- package/examples/no-root-write.sh +12 -0
- package/examples/no-secrets-in-args.sh +4 -1
- package/examples/no-secrets-in-logs.sh +0 -0
- package/examples/no-sensitive-log.sh +0 -0
- package/examples/no-sleep-in-hooks.sh +0 -0
- package/examples/no-star-import-python.sh +1 -0
- package/examples/no-string-concat-sql.sh +0 -0
- package/examples/no-sudo-guard.sh +12 -0
- package/examples/no-sync-fs.sh +0 -0
- package/examples/no-todo-in-merge.sh +0 -0
- package/examples/no-todo-in-production.sh +1 -0
- package/examples/no-todo-without-issue.sh +0 -0
- package/examples/no-unused-import.sh +0 -0
- package/examples/no-var-keyword.sh +0 -0
- package/examples/no-verify-blocker.sh +12 -0
- package/examples/no-wget-piped-bash.sh +12 -0
- package/examples/no-wildcard-cors.sh +0 -0
- package/examples/no-wildcard-delete.sh +0 -0
- package/examples/no-wildcard-import.sh +0 -0
- package/examples/no-with-statement.sh +0 -0
- package/examples/no-write-outside-src.sh +0 -0
- package/examples/no-xml-external-entity.sh +0 -0
- package/examples/non-english-quality-warner.sh +156 -0
- package/examples/notify-waiting.sh +1 -1
- package/examples/npm-audit-warn.sh +0 -0
- package/examples/npm-global-install-guard.sh +12 -0
- package/examples/npm-publish-guard.sh +12 -0
- package/examples/npm-script-injection.sh +0 -0
- package/examples/npm-supply-chain-guard.sh +0 -0
- package/examples/nuxt-config-guard.sh +1 -0
- package/examples/oauth-refresh-monitor.sh +210 -0
- package/examples/opus-degradation-tracker.sh +187 -0
- package/examples/opus48-routine-task-warning.sh +196 -0
- package/examples/opus48-thinking-wedge-advisor.sh +143 -0
- package/examples/output-credential-scan.sh +1 -1
- package/examples/output-secret-mask.sh +31 -9
- package/examples/output-token-spike-detector.sh +145 -0
- package/examples/package-json-guard.sh +12 -0
- package/examples/package-lock-frozen.sh +12 -0
- package/examples/parallel-batch-size-limiter.sh +121 -0
- package/examples/parallel-cascade-detector.sh +116 -0
- package/examples/partial-view-claim-arrest.sh +174 -0
- package/examples/path-deny-bash-guard.sh +12 -0
- package/examples/path-traversal-guard.sh +12 -0
- package/examples/per-prompt-token-cap.sh +124 -0
- package/examples/permission-audit-log.sh +1 -1
- package/examples/permission-denial-enforcer.sh +12 -0
- package/examples/permission-entry-validator.sh +0 -0
- package/examples/persisted-1m-model-advisor.sh +88 -0
- package/examples/php-lint-on-edit.sh +1 -1
- package/examples/pii-upload-guard.sh +12 -0
- package/examples/pip-publish-guard.sh +13 -0
- package/examples/pip-requirements-guard.sh +12 -0
- package/examples/pip-venv-required.sh +12 -0
- package/examples/plan-mode-edit-guard.sh +12 -0
- package/examples/plan-mode-enforcer.sh +12 -0
- package/examples/plan-mode-strict-guard.sh +12 -0
- package/examples/plugin-hooks-json-bloat-detector.sh +169 -0
- package/examples/plugin-process-cleanup.sh +0 -0
- package/examples/polyglot-rm-guard.sh +12 -0
- package/examples/post-compact-safety.sh +12 -0
- package/examples/post-edit-disk-verify.sh +152 -0
- package/examples/powershell-remove-item-guard.sh +85 -0
- package/examples/pr-description-check.sh +0 -0
- package/examples/pr-duplicate-guard.sh +13 -0
- package/examples/pre-bash-sed-line-ending-windows.sh +87 -0
- package/examples/pre-compact-knowledge-save.sh +0 -0
- package/examples/pre-compact-transcript-backup.sh +0 -0
- package/examples/pre-execution-claim-detector.sh +179 -0
- package/examples/prefer-builtin-tools.sh +10 -1
- package/examples/prefer-const.sh +0 -0
- package/examples/prefer-dedicated-tools.sh +12 -0
- package/examples/prefer-optional-chaining.sh +0 -0
- package/examples/prisma-migrate-guard.sh +24 -7
- package/examples/production-port-kill-guard.sh +12 -0
- package/examples/prompt-injection-guard.sh +2 -1
- package/examples/prompt-usage-logger.sh +0 -0
- package/examples/protect-claudemd.sh +12 -0
- package/examples/protect-dotfiles.sh +12 -0
- package/examples/proxy-capture-suggester.sh +159 -0
- package/examples/public-artefact-socratic-narrowing.sh +232 -0
- package/examples/public-repo-push-guard.sh +12 -0
- package/examples/push-requires-test-pass-record.sh +0 -0
- package/examples/push-requires-test-pass.sh +12 -0
- package/examples/quota-anomaly-detector.sh +173 -0
- package/examples/quota-reset-audit.sh +58 -0
- package/examples/quoted-flag-approver.sh +99 -10
- package/examples/rails-migration-guard.sh +12 -0
- package/examples/rate-limit-guard.sh +0 -0
- package/examples/read-all-files-enforcer.sh +0 -0
- package/examples/read-budget-guard.sh +12 -0
- package/examples/read-loop-detector.sh +59 -0
- package/examples/read-once-guard.sh +96 -0
- package/examples/read-only-mode.sh +12 -0
- package/examples/readme-exists-check.sh +0 -0
- package/examples/record-read-coverage.sh +73 -0
- package/examples/redirect-fragment-warner.sh +149 -0
- package/examples/redis-flushall-guard.sh +13 -0
- package/examples/redundant-read-blocker.sh +132 -0
- package/examples/refusal-arrest-gate.sh +248 -0
- package/examples/registry-publish-guard.sh +13 -1
- package/examples/remote-control-billing-classifier.sh +135 -0
- package/examples/replace-all-guard.sh +12 -0
- package/examples/repo-visibility-guard.sh +12 -0
- package/examples/reroute-after-block-guard.sh +150 -0
- package/examples/response-budget-guard.sh +0 -0
- package/examples/resume-drift-watcher.sh +57 -0
- package/examples/rg-replace-flag-detector.sh +125 -0
- package/examples/rhetorical-verification-prompt-detector.sh +102 -0
- package/examples/ripgrep-permission-fix.sh +0 -0
- package/examples/rm-safety-net.sh +151 -8
- package/examples/role-tool-guard.sh +12 -0
- package/examples/route-handler-emptiness-gate.sh +324 -0
- package/examples/ruby-lint-on-edit.sh +1 -1
- package/examples/runtime-binary-change-detector.sh +102 -0
- package/examples/same-command-repeat-detector.sh +196 -0
- package/examples/same-correction-arrest.sh +169 -0
- package/examples/sandbox-denywrite-enforcer.sh +78 -0
- package/examples/sandbox-relative-path-audit.sh +83 -25
- package/examples/sandbox-write-verify.sh +12 -0
- package/examples/schema-migration-guard.sh +0 -0
- package/examples/scope-expansion-receipt.sh +178 -0
- package/examples/scope-guard.sh +88 -9
- package/examples/secret-file-read-guard.sh +12 -0
- package/examples/secret-file-write-guard.sh +150 -0
- package/examples/self-modify-bypass-guard.sh +0 -0
- package/examples/sensitive-file-read-guard.sh +23 -3
- package/examples/sensitive-log-guard.sh +1 -0
- package/examples/server-side-prompt-injection-detector.sh +69 -0
- package/examples/session-agent-cost-limiter.sh +12 -0
- package/examples/session-backup-on-start.sh +1 -1
- package/examples/session-cost-alert.sh +12 -0
- package/examples/session-drift-guard.sh +12 -0
- package/examples/session-duration-guard.sh +25 -2
- package/examples/session-end-logger.sh +0 -0
- package/examples/session-health-monitor.sh +0 -0
- package/examples/session-index-repair.sh +1 -1
- package/examples/session-memory-watchdog.sh +1 -0
- package/examples/session-permission-reset-guard.sh +12 -0
- package/examples/session-persistence-verifier.sh +93 -0
- package/examples/session-plugin-pin-watch.sh +68 -0
- package/examples/session-rate-monitor.sh +176 -0
- package/examples/session-resume-env-fix.sh +0 -0
- package/examples/session-start-quota-status.sh +193 -0
- package/examples/session-start-safety-check.sh +55 -3
- package/examples/session-state-saver.sh +0 -0
- package/examples/session-summary-stop.sh +1 -1
- package/examples/session-summary.sh +0 -0
- package/examples/session-token-counter.sh +1 -1
- package/examples/settings-hooks-key-restorer.sh +99 -0
- package/examples/settings-json-health-check.sh +57 -0
- package/examples/settings-json-model-guard.sh +0 -0
- package/examples/settings-regression-tester.sh +188 -0
- package/examples/shell-config-truncation-guard.sh +12 -0
- package/examples/shell-wrapper-guard.sh +12 -0
- package/examples/skill-cumulative-size-detector.sh +104 -0
- package/examples/skill-description-drop-detector.sh +148 -0
- package/examples/skill-gate.sh +0 -0
- package/examples/skill-truncation-detector.sh +154 -0
- package/examples/skills-context-recorder.sh +167 -0
- package/examples/skills-load-verifier.sh +96 -0
- package/examples/skills-settings-validator.sh +139 -0
- package/examples/sonnet-45-deprecation-helper.sh +85 -0
- package/examples/spec-file-scope-guard.sh +12 -0
- package/examples/spring-profile-guard.sh +1 -0
- package/examples/spurious-malformed-notice-detector.sh +247 -0
- package/examples/sql-bulk-delete-warn.sh +88 -0
- package/examples/sql-injection-detect.sh +0 -0
- package/examples/ssh-key-protect.sh +12 -0
- package/examples/staged-secret-scan.sh +22 -1
- package/examples/stale-temp-settings-detector.sh +86 -0
- package/examples/standing-rule-session-surfacer.sh +137 -0
- package/examples/stop-hook-sigterm-wrapper.sh +182 -0
- package/examples/stop-transcript-write-health.sh +64 -0
- package/examples/strict-allowlist.sh +57 -15
- package/examples/strip-coauthored-by.sh +50 -10
- package/examples/subagent-blast-radius-guard.sh +184 -0
- package/examples/subagent-boundary-precheck.sh +126 -0
- package/examples/subagent-budget-guard.sh +12 -0
- package/examples/subagent-claudemd-inject.sh +0 -0
- package/examples/subagent-closure-verify-gate.sh +164 -0
- package/examples/subagent-destructive-git-guard.sh +120 -0
- package/examples/subagent-error-detector.sh +0 -0
- package/examples/subagent-forged-system-reminder-guard.sh +156 -0
- package/examples/subagent-identity-leak-guard.sh +102 -0
- package/examples/subagent-identity-reassertion.sh +51 -0
- package/examples/subagent-inheritance-tester.sh +179 -0
- package/examples/subagent-permission-mode-guard.sh +110 -0
- package/examples/subagent-scope-guard.sh +12 -0
- package/examples/subagent-spawn-verification-enforcer.sh +102 -0
- package/examples/subagent-tool-allowlist-enforcer.sh +101 -0
- package/examples/subagent-tool-call-limiter.sh +87 -15
- package/examples/subcommand-chain-guard.sh +12 -0
- package/examples/subscription-api-billing-warner.sh +160 -0
- package/examples/subscription-bypass-detector.sh +152 -0
- package/examples/svelte-lint-on-edit.sh +1 -0
- package/examples/swift-build-on-edit.sh +1 -1
- package/examples/symlink-guard.sh +27 -2
- package/examples/symlink-protect.sh +1 -0
- package/examples/system-dir-protection-guard.sh +73 -8
- package/examples/system-message-workaround.sh +38 -13
- package/examples/system-package-guard.sh +12 -0
- package/examples/systemd-service-guard.sh +12 -0
- package/examples/task-integrity-guard.sh +12 -0
- package/examples/temp-file-cleanup.sh +1 -1
- package/examples/temporal-suggestion-detector.sh +135 -0
- package/examples/terraform-guard.sh +27 -6
- package/examples/test-after-edit.sh +1 -1
- package/examples/test-before-push.sh +12 -0
- package/examples/test-coverage-reminder.sh +24 -1
- package/examples/thinking-budget-effort-mismatch-detector.sh +149 -0
- package/examples/thinking-stall-detector.sh +61 -0
- package/examples/timezone-guard.sh +0 -0
- package/examples/tmp-output-size-guard.sh +0 -0
- package/examples/todo-check.sh +1 -1
- package/examples/token-budget-guard.sh +12 -0
- package/examples/token-budget-per-task.sh +12 -0
- package/examples/token-usage-tracker.sh +7 -1
- package/examples/tokenizer-ratio-alert-corpus.sh +90 -0
- package/examples/tokenizer-ratio-alert.sh +104 -0
- package/examples/tool-call-rate-limiter.sh +0 -0
- package/examples/tool-result-correlation-checker.sh +167 -0
- package/examples/tool-result-size-guard.sh +132 -0
- package/examples/tool-retry-budget-guard.sh +12 -0
- package/examples/transcript-contamination-detector.sh +138 -0
- package/examples/trustfall-mcp-injection-guard.sh +103 -0
- package/examples/ultrareview-large-diff-advisor.sh +184 -0
- package/examples/unbounded-output-guard.sh +94 -0
- package/examples/uncommitted-changes-stop.sh +1 -0
- package/examples/uncommitted-discard-guard.sh +23 -5
- package/examples/uncommitted-work-guard.sh +12 -0
- package/examples/usage-warn.sh +0 -0
- package/examples/user-account-guard.sh +12 -0
- package/examples/userprompt-submit-receipt.sh +123 -0
- package/examples/variable-expansion-guard.sh +12 -0
- package/examples/verify-after-publish-reminder.sh +93 -0
- package/examples/verify-before-commit.sh +12 -0
- package/examples/version-bump-detector.sh +156 -0
- package/examples/version-regression-warner.sh +144 -0
- package/examples/vue-lint-on-edit.sh +1 -0
- package/examples/warn-cron-cost-trap.sh +173 -0
- package/examples/webfetch-runaway-guard.sh +89 -0
- package/examples/wellness-break-reminder.sh +118 -0
- package/examples/windows-destructive-command-guard.sh +177 -0
- package/examples/windows-path-guard.sh +12 -0
- package/examples/windows-python-stub-detector.sh +63 -0
- package/examples/work-hours-guard.sh +12 -0
- package/examples/working-directory-fence.sh +12 -0
- package/examples/workspace-lease-guard.sh +205 -0
- package/examples/worktree-create-log.sh +1 -0
- package/examples/worktree-delete-guard.sh +12 -0
- package/examples/worktree-edit-boundary-guard.sh +127 -0
- package/examples/worktree-escape-write-guard.sh +114 -0
- package/examples/worktree-hook-linker.sh +0 -0
- package/examples/worktree-hooks-path-fix.sh +111 -0
- package/examples/worktree-parent-write-guard.sh +43 -0
- package/examples/worktree-project-unify.sh +2 -1
- package/examples/worktree-remove-uncommitted-guard.sh +13 -0
- package/examples/worktree-unmerged-guard.sh +7 -1
- package/examples/write-byte-integrity-verifier.sh +190 -0
- package/examples/write-empty-content-guard.sh +67 -0
- package/examples/write-nul-corruption-detector.sh +61 -0
- package/examples/write-overwrite-confirm.sh +160 -14
- package/examples/write-secret-guard.sh +27 -5
- package/examples/write-shrink-guard.sh +12 -0
- package/examples/write-test-ratio.sh +0 -0
- package/examples/wsl-host-disk-space-guard.sh +97 -0
- package/examples/xml-format-leak-detector.sh +266 -0
- package/examples/yaml-syntax-check.sh +12 -0
- package/hooks/hooks.json +6 -6
- package/index.mjs +1699 -183
- package/mission.md +2 -0
- package/package.json +4 -4
- package/plugins/credential-guard/.claude-plugin/plugin.json +9 -7
- package/plugins/git-protection/.claude-plugin/plugin.json +10 -8
- package/plugins/safety-essentials/.claude-plugin/plugin.json +9 -7
- package/plugins/token-guard/.claude-plugin/plugin.json +10 -8
- package/scripts/agents-md-sync-setup.sh +156 -0
- package/scripts/autonomy-blocked-summary.sh +148 -0
- package/scripts/build-search-index.py +43 -0
- package/scripts/build-sitemap.py +119 -0
- package/scripts/cc-doctor.sh +192 -0
- package/scripts/check-hook-event-names.py +127 -0
- package/scripts/check-misfire-instrument.sh +64 -0
- package/scripts/claim-verify-audit.sh +467 -0
- package/scripts/cowork-claudemd-helper.sh +136 -0
- package/scripts/june-15-deprecated-model-scan.sh +111 -0
- package/scripts/measure-heredoc-shapes.sh +67 -0
- package/scripts/measure-literal-match-misfire.sh +110 -0
- package/scripts/probe-scope-guard-branches.sh +48 -0
- package/scripts/probe-skip-line-both-ways.sh +65 -0
- package/scripts/receipts-aggregate.py +199 -0
- package/scripts/session-forensic-audit.py +360 -0
- package/scripts.json +9 -9
- package/scripts.json.bak-2026-07-27-find +13 -0
- package/skills/safety-setup/SKILL.md +5 -5
- package/tests/approve-side-remaining-two.test.sh +129 -0
- package/tests/approver-list-granularity.test.sh +145 -0
- package/tests/askuserquestion-autonomy-gate.test.sh +181 -0
- package/tests/audit-ci-gate.test.sh +87 -0
- package/tests/audit-cross-layer-claudemd.test.sh +170 -0
- package/tests/audit-fail-open-parse.test.sh +100 -0
- package/tests/auto-approve-compound-tail.test.sh +194 -0
- package/tests/auto-mode-path-invoked-commands.test.sh +89 -0
- package/tests/auto-mode-quoted-targets.test.sh +127 -0
- package/tests/auto-mode-unquoted-targets.test.sh +112 -0
- package/tests/bash-secret-output-detector-detects.test.sh +102 -0
- package/tests/blindspots-cross-layer.test.sh +177 -0
- package/tests/block-database-wipe.test.sh +64 -0
- package/tests/bundled-short-flags-bypass.test.sh +85 -0
- package/tests/cd-git-allow-compound-tail.test.sh +67 -0
- package/tests/chown-guard-filesystem-root.test.sh +64 -0
- package/tests/ci-workflow-guard-skip-rule.test.sh +115 -0
- package/tests/compound-deny-safe-rm-targets.test.sh +105 -0
- package/tests/core-scripts-parser-fallback.test.sh +140 -0
- package/tests/destructive-guard-bare-glob.test.sh +74 -0
- package/tests/destructive-guard-every-operand.test.sh +100 -0
- package/tests/destructive-guard-find-deletion.test.sh +114 -0
- package/tests/destructive-guard-flag-order.test.sh +106 -0
- package/tests/destructive-guard-mentions-vs-invocations.test.sh +107 -0
- package/tests/destructive-guard-quoted-target.test.sh +89 -0
- package/tests/destructive-guard-separators.test.sh +105 -0
- package/tests/destructive-guard-variable-target.test.sh +98 -0
- package/tests/destructive-guard-wrapped-command.test.sh +91 -0
- package/tests/doctor-hook-disabling-env.test.sh +92 -0
- package/tests/doctor-misspelled-settings-keys.test.sh +106 -0
- package/tests/example-guards-wrapped-command.test.sh +169 -0
- package/tests/file-edit-backup.test.sh +93 -0
- package/tests/git-filter-repo-guard.test.sh +60 -0
- package/tests/git-global-options-bypass.test.sh +141 -0
- package/tests/git-invocation-prefixes-all-guards.test.sh +114 -0
- package/tests/git-maintenance-guard.test.sh +83 -0
- package/tests/git-pack-temp-cleanup-guard.test.sh +133 -0
- package/tests/git-rm-orphan-wipe-guard.test.sh +66 -0
- package/tests/git-submodule-guard.test.sh +50 -0
- package/tests/grep-pcre-portability.test.sh +155 -0
- package/tests/hook-registration-matches-input.test.sh +73 -0
- package/tests/hook-trigger-matches-envelope.test.sh +178 -0
- package/tests/install-does-not-claim-protection.test.sh +110 -0
- package/tests/install-example-standalone-tools.test.sh +139 -0
- package/tests/line-continuation-bypass.test.sh +114 -0
- package/tests/mcp-config-poisoning-audit.test.sh +106 -0
- package/tests/nested-background-agent-guard.test.sh +58 -0
- package/tests/no-unqualified-safety-claims.test.sh +114 -0
- package/tests/option-eating-grep-patterns.test.sh +130 -0
- package/tests/outdated-core-guards.test.sh +134 -0
- package/tests/outdated-report.test.sh +155 -0
- package/tests/output-secret-mask-warns.test.sh +73 -0
- package/tests/plugin-hooks-fail-open-under-sh.test.sh +165 -0
- package/tests/plugins-word-order.test.sh +126 -0
- package/tests/powershell-remove-item-guard.test.sh +85 -0
- package/tests/project-dir-naming.test.sh +103 -0
- package/tests/quoted-safe-targets-and-mentions.test.sh +190 -0
- package/tests/reroute-after-block-guard.test.sh +104 -0
- package/tests/secret-guard-documented-promises.test.sh +97 -0
- package/tests/session-plugin-pin-watch.test.sh +45 -0
- package/tests/settings-unreadable-refuses-to-write.test.sh +95 -0
- package/tests/shield-no-silent-adoption.test.py +110 -0
- package/tests/shield-no-silent-adoption.test.sh +46 -0
- package/tests/stop-transcript-write-health.test.sh +46 -0
- package/tests/system-dir-guard-root-erased.test.sh +66 -0
- package/tests/test-account-billing-log.sh +100 -0
- package/tests/test-account-routing-preflight.sh +77 -0
- package/tests/test-agent-sdk-credit-pool-monitor.sh +157 -0
- package/tests/test-agent-view-quota-warn.sh +184 -0
- package/tests/test-agents-md-edit-drift-warner.sh +176 -0
- package/tests/test-agents-md-loader.sh +204 -0
- package/tests/test-agents-md-sync-checker.sh +125 -0
- package/tests/test-ai-slop-punctuation-arrest.sh +280 -0
- package/tests/test-allowlist.sh +60 -0
- package/tests/test-always-allow-pattern-suggester.sh +147 -0
- package/tests/test-anthropic-base-url-guard.sh +88 -0
- package/tests/test-articulated-scope-capture.sh +139 -0
- package/tests/test-attachment-traversal-guard.sh +168 -0
- package/tests/test-aup-block-pattern-logger.sh +315 -0
- package/tests/test-aup-false-positive-helper.sh +188 -0
- package/tests/test-aup-large-tool-output-warner.sh +370 -0
- package/tests/test-aup-retry-loop-guard.sh +341 -0
- package/tests/test-auth-expiry-reminder.sh +303 -0
- package/tests/test-auth-macos-sleep-detector.sh +254 -0
- package/tests/test-auth-path-detector.sh +232 -0
- package/tests/test-auth-status-checker.sh +233 -0
- package/tests/test-authorized-reconfirmation-detector.sh +280 -0
- package/tests/test-background-cost-launch-guard.sh +62 -0
- package/tests/test-bash-allowlist-secondary-check.sh +143 -0
- package/tests/test-bash-fanout-bounded-rewriter.sh +186 -0
- package/tests/test-bash-project-fence.sh +127 -0
- package/tests/test-bg-permission-prompt-warner.sh +221 -0
- package/tests/test-binary-read-detector.sh +173 -0
- package/tests/test-broad-prefix-session-trap-warner.sh +167 -0
- package/tests/test-bulk-delete-target-resolution.sh +49 -0
- package/tests/test-bypass-mode-effective-verifier.sh +179 -0
- package/tests/test-cache-creation-drift-detector.sh +244 -0
- package/tests/test-cache-residue-detector.sh +429 -0
- package/tests/test-cache-tier-logger.sh +59 -0
- package/tests/test-cache-ttl-eviction-detector.sh +282 -0
- package/tests/test-cch-sentinel-precommit-guard.sh +64 -0
- package/tests/test-claim-verify-detector.sh +222 -0
- package/tests/test-claim-vs-caveat-checker.sh +134 -0
- package/tests/test-claude-code-version-pin-advisor.sh +353 -0
- package/tests/test-claude-md-reinjector.sh +173 -0
- package/tests/test-claude-md-size-monitor.sh +107 -0
- package/tests/test-claude-update-budget-guard.sh +132 -0
- package/tests/test-claude-update-smart.sh +91 -0
- package/tests/test-claudemd-tool-prohibition.sh +239 -0
- package/tests/test-cli-config-pinning-detector.sh +233 -0
- package/tests/test-cliff-countdown-advisor.sh +138 -0
- package/tests/test-closure-word-verify-gate.sh +158 -0
- package/tests/test-commit-all-scope-guard.sh +73 -0
- package/tests/test-commitment-carry-forward-arrest.sh +250 -0
- package/tests/test-compact-circuit-breaker.sh +134 -0
- package/tests/test-compact-dispatch-watchdog.sh +147 -0
- package/tests/test-completion-claim-without-verification-detector.sh +326 -0
- package/tests/test-compound-bash-permission-resolver.sh +264 -0
- package/tests/test-compound-command-deny-enforcer.sh +67 -0
- package/tests/test-context-length-budget.sh +68 -0
- package/tests/test-context-usage-drift-alert.sh +52 -22
- package/tests/test-cost-incident-self-audit.sh +94 -0
- package/tests/test-cowork-claude-md-load-checker.sh +257 -0
- package/tests/test-cowork-claudemd-helper.sh +141 -0
- package/tests/test-cowork-fuse-staleness-watcher.sh +287 -0
- package/tests/test-cowork-hook-absence-warner.sh +230 -0
- package/tests/test-cowork-model-picker-advisor.sh +317 -0
- package/tests/test-credential-exfil-guard.sh +62 -0
- package/tests/test-cron-create-receipt.sh +165 -0
- package/tests/test-cross-product-mcp-spawn-detector.sh +112 -0
- package/tests/test-daemon-zombie-worker-surfacer.sh +71 -0
- package/tests/test-daily-cost-guard.sh +131 -0
- package/tests/test-deny-rule-integrity-verifier.sh +288 -0
- package/tests/test-deployment-readback-gate.sh +92 -0
- package/tests/test-deployment-readback-gh-adapter.sh +163 -0
- package/tests/test-disabled-feature-toggle-advisor.sh +78 -0
- package/tests/test-dispatch-allowlist-preflight.sh +385 -0
- package/tests/test-dispatch-liveness-watchdog.sh +319 -0
- package/tests/test-dispatch-receipt.sh +314 -0
- package/tests/test-dotenv-anthropic-key-billing-guard.sh +160 -0
- package/tests/test-echo-probe-spam-detector.sh +143 -0
- package/tests/test-edit-quote-ambiguity-guard.sh +75 -0
- package/tests/test-ephemeral-container-detector.sh +251 -0
- package/tests/test-evidence-claim-gate.sh +291 -0
- package/tests/test-exploration-budget-guard.sh +164 -0
- package/tests/test-extended-thinking-loop-guard.sh +289 -0
- package/tests/test-extended-thinking-resume-warning.sh +240 -0
- package/tests/test-extended-thinking-tool-use-mismatch-detector.sh +236 -0
- package/tests/test-fabricated-command-detector.sh +296 -0
- package/tests/test-false-disk-full-guard.sh +36 -0
- package/tests/test-feature-deprecation-detector.sh +117 -0
- package/tests/test-forbidden-response-phrase-detector.sh +246 -0
- package/tests/test-git-operations-require-approval.sh +53 -0
- package/tests/test-git-push-blast-radius-guard.sh +115 -0
- package/tests/test-goal-iteration-limit-warner.sh +128 -0
- package/tests/test-growthbook-flag-monitor.sh +428 -0
- package/tests/test-halt-signal-detector.sh +120 -0
- package/tests/test-hook-self-disable-detector.sh +232 -0
- package/tests/test-iteration-quality-degradation-detector.sh +244 -0
- package/tests/test-long-session-malformed-tool-call-detector.sh +185 -0
- package/tests/test-marketplace-plugins.sh +193 -0
- package/tests/test-mcp-misdiagnosis-arrest.sh +235 -0
- package/tests/test-mcp-orphan-leak-warner.sh +71 -0
- package/tests/test-mcp-permissions-ask-warner.sh +207 -0
- package/tests/test-mcp-routine-approval-detector.sh +229 -0
- package/tests/test-mcp-startup-bloat-detector.sh +141 -0
- package/tests/test-mcp-stdio-compatibility-test.sh +112 -0
- package/tests/test-memory-chain-audit.sh +59 -0
- package/tests/test-memory-orphan-detector.sh +227 -0
- package/tests/test-model-swap-suggester.sh +368 -0
- package/tests/test-model-version-lock.sh +83 -0
- package/tests/test-multi-file-plan-routing-gate.sh +277 -0
- package/tests/test-multi-window-auth-drift-detector.sh +262 -0
- package/tests/test-nested-spawn-inflight-guard.sh +281 -0
- package/tests/test-no-force-flag.sh +49 -0
- package/tests/test-non-english-quality-warner.sh +229 -0
- package/tests/test-oauth-refresh-monitor.sh +311 -0
- package/tests/test-opus-degradation-tracker.sh +274 -0
- package/tests/test-opus48-routine-task-warning.sh +201 -0
- package/tests/test-opus48-thinking-wedge-advisor.sh +249 -0
- package/tests/test-output-token-spike-detector.sh +315 -0
- package/tests/test-parallel-batch-size-limiter.sh +228 -0
- package/tests/test-parallel-cascade-detector.sh +191 -0
- package/tests/test-partial-view-claim-arrest.sh +272 -0
- package/tests/test-per-prompt-token-cap.sh +136 -0
- package/tests/test-persisted-1m-model-advisor.sh +71 -0
- package/tests/test-plugin-hooks-json-bloat-detector.sh +267 -0
- package/tests/test-post-edit-disk-verify.sh +294 -0
- package/tests/test-pre-bash-sed-line-ending-windows.sh +108 -0
- package/tests/test-pre-execution-claim-detector.sh +366 -0
- package/tests/test-private-key-backup-and-git-credentials.sh +100 -0
- package/tests/test-proxy-capture-suggester.sh +214 -0
- package/tests/test-public-artefact-socratic-narrowing.sh +346 -0
- package/tests/test-quota-anomaly-detector.sh +321 -0
- package/tests/test-quota-reset-audit.sh +81 -0
- package/tests/test-read-loop-detector.sh +137 -0
- package/tests/test-read-once-guard.sh +85 -0
- package/tests/test-receipts-aggregate.sh +143 -0
- package/tests/test-redirect-fragment-warner.sh +130 -0
- package/tests/test-redundant-read-blocker.sh +155 -0
- package/tests/test-refusal-arrest-gate.sh +303 -0
- package/tests/test-remote-control-billing-classifier.sh +125 -0
- package/tests/test-resume-drift-watcher.sh +65 -0
- package/tests/test-rg-replace-flag-detector.sh +175 -0
- package/tests/test-rhetorical-verification-prompt-detector.sh +237 -0
- package/tests/test-rm-safety-net.sh +115 -0
- package/tests/test-route-handler-emptiness-gate.sh +300 -0
- package/tests/test-runtime-binary-change-detector.sh +196 -0
- package/tests/test-same-command-repeat-detector.sh +165 -0
- package/tests/test-same-correction-arrest.sh +165 -0
- package/tests/test-scope-expansion-receipt.sh +207 -0
- package/tests/test-server-side-prompt-injection-detector.sh +181 -0
- package/tests/test-session-persistence-verifier.sh +128 -0
- package/tests/test-session-rate-monitor.sh +284 -0
- package/tests/test-session-start-quota-status.sh +210 -0
- package/tests/test-session-start-safety-check.sh +138 -0
- package/tests/test-settings-hooks-key-restorer.sh +257 -0
- package/tests/test-settings-json-health-check.sh +70 -0
- package/tests/test-settings-regression-tester.sh +197 -0
- package/tests/test-skill-cumulative-size-detector.sh +198 -0
- package/tests/test-skill-description-drop-detector.sh +236 -0
- package/tests/test-skill-truncation-detector.sh +263 -0
- package/tests/test-skills-context-recorder.sh +329 -0
- package/tests/test-skills-load-verifier.sh +184 -0
- package/tests/test-skills-settings-validator.sh +242 -0
- package/tests/test-sonnet-45-deprecation-helper.sh +150 -0
- package/tests/test-spurious-malformed-notice-detector.sh +290 -0
- package/tests/test-sql-bulk-delete-warn.sh +123 -0
- package/tests/test-ssh-key-protect.sh +81 -0
- package/tests/test-stale-temp-settings-detector.sh +161 -0
- package/tests/test-standing-rule-session-surfacer.sh +215 -0
- package/tests/test-starter-hooks-manifest.sh +96 -0
- package/tests/test-stop-hook-sigterm-wrapper.sh +258 -0
- package/tests/test-strict-allowlist.sh +72 -0
- package/tests/test-subagent-boundary-precheck.sh +137 -0
- package/tests/test-subagent-closure-verify-gate.sh +193 -0
- package/tests/test-subagent-destructive-git-guard.sh +86 -0
- package/tests/test-subagent-identity-leak-guard.sh +62 -0
- package/tests/test-subagent-identity-reassertion.sh +61 -0
- package/tests/test-subagent-inheritance-tester.sh +319 -0
- package/tests/test-subagent-permission-mode-guard.sh +61 -0
- package/tests/test-subagent-spawn-verification-enforcer.sh +60 -0
- package/tests/test-subagent-tool-allowlist-enforcer.sh +62 -0
- package/tests/test-subagent-tool-call-limiter.sh +97 -0
- package/tests/test-subscription-api-billing-warner.sh +138 -0
- package/tests/test-subscription-bypass-detector.sh +255 -0
- package/tests/test-temporal-suggestion-detector.sh +183 -0
- package/tests/test-thinking-budget-effort-mismatch-detector.sh +327 -0
- package/tests/test-thinking-stall-detector.sh +151 -0
- package/tests/test-tokenizer-ratio-alert-corpus.sh +77 -0
- package/tests/test-tokenizer-ratio-alert.sh +93 -0
- package/tests/test-tool-result-correlation-checker.sh +264 -0
- package/tests/test-tool-result-size-guard.sh +121 -0
- package/tests/test-transcript-contamination-detector.sh +264 -0
- package/tests/test-trigger-header-parsing.sh +151 -0
- package/tests/test-ultrareview-large-diff-advisor.sh +192 -0
- package/tests/test-userprompt-submit-receipt.sh +181 -0
- package/tests/test-verify-after-publish-reminder.sh +184 -0
- package/tests/test-version-bump-detector.sh +212 -0
- package/tests/test-version-regression-warner.sh +165 -0
- package/tests/test-warn-cron-cost-trap.sh +82 -0
- package/tests/test-webfetch-runaway-guard.sh +77 -0
- package/tests/test-wellness-break-reminder.sh +138 -0
- package/tests/test-windows-destructive-command-guard.sh +169 -0
- package/tests/test-windows-python-stub-detector.sh +146 -0
- package/tests/test-worktree-edit-boundary-guard.sh +219 -0
- package/tests/test-write-byte-integrity-verifier.sh +192 -0
- package/tests/test-xml-format-leak-detector.sh +299 -0
- package/tests/trustfall-mcp-injection-guard.test.sh +183 -0
- package/tests/workspace-lease-guard.test.sh +144 -0
- package/tests/worktree-escape-write-guard.test.sh +68 -0
- package/tests/worktree-hooks-path-fix.test.sh +181 -0
- package/tests/worktree-parent-write-guard.test.sh +51 -0
- package/tests/write-empty-content-guard.test.sh +39 -0
- package/tests/write-nul-corruption-detector.test.sh +29 -0
- package/tests/write-overwrite-unread-content.test.sh +178 -0
- package/tests/wsl-host-disk-space-guard.test.sh +55 -0
package/mission.md
ADDED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cc-safe-setup",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "30.0.4",
|
|
4
|
+
"description": "Safety hooks for Claude Code: PreToolUse/PostToolUse/Stop guards that block destructive or irreversible operations at the tool boundary and surface silent failures. Interactive installer, plain shell scripts, no npm dependencies (the hooks read their JSON input with jq, python3 or node).",
|
|
5
5
|
"main": "index.mjs",
|
|
6
6
|
"bin": {
|
|
7
7
|
"cc-safe-setup": "index.mjs"
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
"type": "git",
|
|
43
43
|
"url": "https://github.com/yurukusa/cc-safe-setup"
|
|
44
44
|
},
|
|
45
|
-
"homepage": "https://
|
|
45
|
+
"homepage": "https://www.npmjs.com/package/cc-safe-setup",
|
|
46
46
|
"funding": {
|
|
47
47
|
"type": "github",
|
|
48
48
|
"url": "https://github.com/sponsors/yurukusa"
|
|
49
49
|
}
|
|
50
|
-
}
|
|
50
|
+
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "credential-guard",
|
|
3
3
|
"description": "Protect secrets and credentials from Claude Code. Blocks writes to .env files, detects API keys in shell commands, prevents hardcoded tokens, and guards service account JSON files.",
|
|
4
|
-
"version": "1.
|
|
5
|
-
"author": {
|
|
4
|
+
"version": "1.2.0",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "yurukusa"
|
|
7
|
+
},
|
|
6
8
|
"homepage": "https://yurukusa.github.io/cc-safe-setup/",
|
|
7
9
|
"repository": "https://github.com/yurukusa/cc-safe-setup",
|
|
8
10
|
"license": "MIT",
|
|
@@ -13,7 +15,7 @@
|
|
|
13
15
|
"hooks": [
|
|
14
16
|
{
|
|
15
17
|
"type": "command",
|
|
16
|
-
"command": "INPUT=$(cat); FILE=$(
|
|
18
|
+
"command": "INPUT=$(cat); FILE=$(printf %s \"$INPUT\" | { if command -v jq >/dev/null 2>&1; then jq -r '.tool_input.file_path // empty' 2>/dev/null; elif command -v python3 >/dev/null 2>&1; then python3 -c 'import sys,json;d=json.load(sys.stdin);print((d.get(\"tool_input\") or {}).get(\"file_path\") or \"\")' 2>/dev/null; elif command -v node >/dev/null 2>&1; then node -e 'let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>{try{process.stdout.write(String((JSON.parse(s).tool_input||{}).file_path||\"\"))}catch(e){}})' 2>/dev/null; else echo __CCHOOK_NO_PARSER__; fi; }); if [ \"$FILE\" = \"__CCHOOK_NO_PARSER__\" ]; then W=/tmp/cc-noparser-warned-credential-guard-$PPID; [ -f \"$W\" ] || { echo \"WARNING [credential-guard]: cannot inspect tool calls - jq, python3 and node are all unavailable, so this plugin is NOT protecting you. Install any one of them.\" >&2; : > \"$W\"; }; exit 0; fi; [ -z \"$FILE\" ] && exit 0; if echo \"$FILE\" | grep -qE '\\.env$|\\.env\\.|credentials|secret' && ! echo \"$FILE\" | grep -qiE '\\.env\\.(example|sample|template|dist)$'; then echo \"BLOCKED [credential-guard]: Writing to sensitive file: $FILE\" >&2; exit 2; fi"
|
|
17
19
|
}
|
|
18
20
|
]
|
|
19
21
|
},
|
|
@@ -22,7 +24,7 @@
|
|
|
22
24
|
"hooks": [
|
|
23
25
|
{
|
|
24
26
|
"type": "command",
|
|
25
|
-
"command": "INPUT=$(cat); FILE=$(
|
|
27
|
+
"command": "INPUT=$(cat); FILE=$(printf %s \"$INPUT\" | { if command -v jq >/dev/null 2>&1; then jq -r '.tool_input.file_path // empty' 2>/dev/null; elif command -v python3 >/dev/null 2>&1; then python3 -c 'import sys,json;d=json.load(sys.stdin);print((d.get(\"tool_input\") or {}).get(\"file_path\") or \"\")' 2>/dev/null; elif command -v node >/dev/null 2>&1; then node -e 'let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>{try{process.stdout.write(String((JSON.parse(s).tool_input||{}).file_path||\"\"))}catch(e){}})' 2>/dev/null; else echo __CCHOOK_NO_PARSER__; fi; }); if [ \"$FILE\" = \"__CCHOOK_NO_PARSER__\" ]; then W=/tmp/cc-noparser-warned-credential-guard-$PPID; [ -f \"$W\" ] || { echo \"WARNING [credential-guard]: cannot inspect tool calls - jq, python3 and node are all unavailable, so this plugin is NOT protecting you. Install any one of them.\" >&2; : > \"$W\"; }; exit 0; fi; [ -z \"$FILE\" ] && exit 0; if echo \"$FILE\" | grep -qE '\\.env$|\\.env\\.|credentials|secret' && ! echo \"$FILE\" | grep -qiE '\\.env\\.(example|sample|template|dist)$'; then echo \"BLOCKED [credential-guard]: Editing sensitive file: $FILE\" >&2; exit 2; fi"
|
|
26
28
|
}
|
|
27
29
|
]
|
|
28
30
|
},
|
|
@@ -31,7 +33,7 @@
|
|
|
31
33
|
"hooks": [
|
|
32
34
|
{
|
|
33
35
|
"type": "command",
|
|
34
|
-
"command": "INPUT=$(cat); CMD=$(
|
|
36
|
+
"command": "INPUT=$(cat); CMD=$(printf %s \"$INPUT\" | { if command -v jq >/dev/null 2>&1; then jq -r '.tool_input.command // empty' 2>/dev/null; elif command -v python3 >/dev/null 2>&1; then python3 -c 'import sys,json;d=json.load(sys.stdin);print((d.get(\"tool_input\") or {}).get(\"command\") or \"\")' 2>/dev/null; elif command -v node >/dev/null 2>&1; then node -e 'let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>{try{process.stdout.write(String((JSON.parse(s).tool_input||{}).command||\"\"))}catch(e){}})' 2>/dev/null; else echo __CCHOOK_NO_PARSER__; fi; }); if [ \"$CMD\" = \"__CCHOOK_NO_PARSER__\" ]; then W=/tmp/cc-noparser-warned-credential-guard-$PPID; [ -f \"$W\" ] || { echo \"WARNING [credential-guard]: cannot inspect tool calls - jq, python3 and node are all unavailable, so this plugin is NOT protecting you. Install any one of them.\" >&2; : > \"$W\"; }; exit 0; fi; [ -z \"$CMD\" ] && exit 0; if echo \"$CMD\" | grep -qE '(sk|pk|api|key|token|secret|password)[-_]?[a-zA-Z0-9]{20,}'; then echo 'WARNING [credential-guard]: Possible API key or token detected in command. Verify no secrets are exposed.' >&2; fi"
|
|
35
37
|
}
|
|
36
38
|
]
|
|
37
39
|
},
|
|
@@ -40,7 +42,7 @@
|
|
|
40
42
|
"hooks": [
|
|
41
43
|
{
|
|
42
44
|
"type": "command",
|
|
43
|
-
"command": "INPUT=$(cat); FILE=$(
|
|
45
|
+
"command": "INPUT=$(cat); FILE=$(printf %s \"$INPUT\" | { if command -v jq >/dev/null 2>&1; then jq -r '.tool_input.file_path // empty' 2>/dev/null; elif command -v python3 >/dev/null 2>&1; then python3 -c 'import sys,json;d=json.load(sys.stdin);print((d.get(\"tool_input\") or {}).get(\"file_path\") or \"\")' 2>/dev/null; elif command -v node >/dev/null 2>&1; then node -e 'let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>{try{process.stdout.write(String((JSON.parse(s).tool_input||{}).file_path||\"\"))}catch(e){}})' 2>/dev/null; else echo __CCHOOK_NO_PARSER__; fi; }); if [ \"$FILE\" = \"__CCHOOK_NO_PARSER__\" ]; then W=/tmp/cc-noparser-warned-credential-guard-$PPID; [ -f \"$W\" ] || { echo \"WARNING [credential-guard]: cannot inspect tool calls - jq, python3 and node are all unavailable, so this plugin is NOT protecting you. Install any one of them.\" >&2; : > \"$W\"; }; exit 0; fi; [ -z \"$FILE\" ] && exit 0; if echo \"$FILE\" | grep -qE 'serviceaccount.*\\.json|key\\.json|credentials\\.json'; then echo \"BLOCKED [credential-guard]: Writing to service account file: $FILE\" >&2; exit 2; fi"
|
|
44
46
|
}
|
|
45
47
|
]
|
|
46
48
|
},
|
|
@@ -49,7 +51,7 @@
|
|
|
49
51
|
"hooks": [
|
|
50
52
|
{
|
|
51
53
|
"type": "command",
|
|
52
|
-
"command": "INPUT=$(cat); CMD=$(
|
|
54
|
+
"command": "INPUT=$(cat); CMD=$(printf %s \"$INPUT\" | { if command -v jq >/dev/null 2>&1; then jq -r '.tool_input.command // empty' 2>/dev/null; elif command -v python3 >/dev/null 2>&1; then python3 -c 'import sys,json;d=json.load(sys.stdin);print((d.get(\"tool_input\") or {}).get(\"command\") or \"\")' 2>/dev/null; elif command -v node >/dev/null 2>&1; then node -e 'let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>{try{process.stdout.write(String((JSON.parse(s).tool_input||{}).command||\"\"))}catch(e){}})' 2>/dev/null; else echo __CCHOOK_NO_PARSER__; fi; }); if [ \"$CMD\" = \"__CCHOOK_NO_PARSER__\" ]; then W=/tmp/cc-noparser-warned-credential-guard-$PPID; [ -f \"$W\" ] || { echo \"WARNING [credential-guard]: cannot inspect tool calls - jq, python3 and node are all unavailable, so this plugin is NOT protecting you. Install any one of them.\" >&2; : > \"$W\"; }; exit 0; fi; [ -z \"$CMD\" ] && exit 0; if echo \"$CMD\" | grep -qE 'ANTHROPIC_API_KEY|OPENAI_API_KEY|AWS_SECRET|GITHUB_TOKEN|DATABASE_URL'; then echo 'WARNING [credential-guard]: Environment variable with potential secret detected in command.' >&2; fi"
|
|
53
55
|
}
|
|
54
56
|
]
|
|
55
57
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "git-protection",
|
|
3
|
-
"description": "Git safety hooks for Claude Code. Blocks force-push, protects main/master branch, prevents hard-reset,
|
|
4
|
-
"version": "1.
|
|
5
|
-
"author": {
|
|
3
|
+
"description": "Git safety hooks for Claude Code. Blocks force-push, protects the main/master branch, prevents hard-reset, blocks git clean, and blocks forced branch deletion.",
|
|
4
|
+
"version": "1.2.0",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "yurukusa"
|
|
7
|
+
},
|
|
6
8
|
"homepage": "https://yurukusa.github.io/cc-safe-setup/",
|
|
7
9
|
"repository": "https://github.com/yurukusa/cc-safe-setup",
|
|
8
10
|
"license": "MIT",
|
|
@@ -13,7 +15,7 @@
|
|
|
13
15
|
"hooks": [
|
|
14
16
|
{
|
|
15
17
|
"type": "command",
|
|
16
|
-
"command": "INPUT=$(cat); CMD=$(
|
|
18
|
+
"command": "INPUT=$(cat); CMD=$(printf %s \"$INPUT\" | { if command -v jq >/dev/null 2>&1; then jq -r '.tool_input.command // empty' 2>/dev/null; elif command -v python3 >/dev/null 2>&1; then python3 -c 'import sys,json;d=json.load(sys.stdin);print((d.get(\"tool_input\") or {}).get(\"command\") or \"\")' 2>/dev/null; elif command -v node >/dev/null 2>&1; then node -e 'let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>{try{process.stdout.write(String((JSON.parse(s).tool_input||{}).command||\"\"))}catch(e){}})' 2>/dev/null; else echo __CCHOOK_NO_PARSER__; fi; }); if [ \"$CMD\" = \"__CCHOOK_NO_PARSER__\" ]; then W=/tmp/cc-noparser-warned-git-protection-$PPID; [ -f \"$W\" ] || { echo \"WARNING [git-protection]: cannot inspect tool calls - jq, python3 and node are all unavailable, so this plugin is NOT protecting you. Install any one of them.\" >&2; : > \"$W\"; }; exit 0; fi; [ -z \"$CMD\" ] && exit 0; CMD_NOLEASE=$(printf %s \"$CMD\" | sed 's/--force-with-lease[^ ]*//g'); if echo \"$CMD_NOLEASE\" | grep -qE 'git\\s+push.*--force|git\\s+push.*-f\\b'; then echo 'BLOCKED [git-protection]: Force push. Use --force-with-lease for safer alternative.' >&2; exit 2; fi"
|
|
17
19
|
}
|
|
18
20
|
]
|
|
19
21
|
},
|
|
@@ -22,7 +24,7 @@
|
|
|
22
24
|
"hooks": [
|
|
23
25
|
{
|
|
24
26
|
"type": "command",
|
|
25
|
-
"command": "INPUT=$(cat); CMD=$(
|
|
27
|
+
"command": "INPUT=$(cat); CMD=$(printf %s \"$INPUT\" | { if command -v jq >/dev/null 2>&1; then jq -r '.tool_input.command // empty' 2>/dev/null; elif command -v python3 >/dev/null 2>&1; then python3 -c 'import sys,json;d=json.load(sys.stdin);print((d.get(\"tool_input\") or {}).get(\"command\") or \"\")' 2>/dev/null; elif command -v node >/dev/null 2>&1; then node -e 'let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>{try{process.stdout.write(String((JSON.parse(s).tool_input||{}).command||\"\"))}catch(e){}})' 2>/dev/null; else echo __CCHOOK_NO_PARSER__; fi; }); if [ \"$CMD\" = \"__CCHOOK_NO_PARSER__\" ]; then W=/tmp/cc-noparser-warned-git-protection-$PPID; [ -f \"$W\" ] || { echo \"WARNING [git-protection]: cannot inspect tool calls - jq, python3 and node are all unavailable, so this plugin is NOT protecting you. Install any one of them.\" >&2; : > \"$W\"; }; exit 0; fi; [ -z \"$CMD\" ] && exit 0; if echo \"$CMD\" | grep -qE 'git\\s+push\\s+(origin\\s+)?(main|master)\\b'; then echo 'BLOCKED [git-protection]: Direct push to main/master. Use a feature branch and PR.' >&2; exit 2; fi"
|
|
26
28
|
}
|
|
27
29
|
]
|
|
28
30
|
},
|
|
@@ -31,7 +33,7 @@
|
|
|
31
33
|
"hooks": [
|
|
32
34
|
{
|
|
33
35
|
"type": "command",
|
|
34
|
-
"command": "INPUT=$(cat); CMD=$(
|
|
36
|
+
"command": "INPUT=$(cat); CMD=$(printf %s \"$INPUT\" | { if command -v jq >/dev/null 2>&1; then jq -r '.tool_input.command // empty' 2>/dev/null; elif command -v python3 >/dev/null 2>&1; then python3 -c 'import sys,json;d=json.load(sys.stdin);print((d.get(\"tool_input\") or {}).get(\"command\") or \"\")' 2>/dev/null; elif command -v node >/dev/null 2>&1; then node -e 'let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>{try{process.stdout.write(String((JSON.parse(s).tool_input||{}).command||\"\"))}catch(e){}})' 2>/dev/null; else echo __CCHOOK_NO_PARSER__; fi; }); if [ \"$CMD\" = \"__CCHOOK_NO_PARSER__\" ]; then W=/tmp/cc-noparser-warned-git-protection-$PPID; [ -f \"$W\" ] || { echo \"WARNING [git-protection]: cannot inspect tool calls - jq, python3 and node are all unavailable, so this plugin is NOT protecting you. Install any one of them.\" >&2; : > \"$W\"; }; exit 0; fi; [ -z \"$CMD\" ] && exit 0; if echo \"$CMD\" | grep -qE 'git\\s+reset\\b[^;&|]*--hard'; then echo 'BLOCKED [git-protection]: git reset --hard. Use git stash or git reset --soft.' >&2; exit 2; fi"
|
|
35
37
|
}
|
|
36
38
|
]
|
|
37
39
|
},
|
|
@@ -40,7 +42,7 @@
|
|
|
40
42
|
"hooks": [
|
|
41
43
|
{
|
|
42
44
|
"type": "command",
|
|
43
|
-
"command": "INPUT=$(cat); CMD=$(
|
|
45
|
+
"command": "INPUT=$(cat); CMD=$(printf %s \"$INPUT\" | { if command -v jq >/dev/null 2>&1; then jq -r '.tool_input.command // empty' 2>/dev/null; elif command -v python3 >/dev/null 2>&1; then python3 -c 'import sys,json;d=json.load(sys.stdin);print((d.get(\"tool_input\") or {}).get(\"command\") or \"\")' 2>/dev/null; elif command -v node >/dev/null 2>&1; then node -e 'let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>{try{process.stdout.write(String((JSON.parse(s).tool_input||{}).command||\"\"))}catch(e){}})' 2>/dev/null; else echo __CCHOOK_NO_PARSER__; fi; }); if [ \"$CMD\" = \"__CCHOOK_NO_PARSER__\" ]; then W=/tmp/cc-noparser-warned-git-protection-$PPID; [ -f \"$W\" ] || { echo \"WARNING [git-protection]: cannot inspect tool calls - jq, python3 and node are all unavailable, so this plugin is NOT protecting you. Install any one of them.\" >&2; : > \"$W\"; }; exit 0; fi; [ -z \"$CMD\" ] && exit 0; if echo \"$CMD\" | grep -qE 'git\\s+clean\\b[^;&|]*(\\s-[a-zA-Z]*[fd]|\\s--force)' && ! echo \"$CMD\" | grep -qE 'git\\s+clean\\b[^;&|]*(\\s-[a-zA-Z]*n[a-zA-Z]*|\\s--dry-run)'; then echo 'BLOCKED [git-protection]: git clean removes untracked files permanently. Review with git clean -n first.' >&2; exit 2; fi"
|
|
44
46
|
}
|
|
45
47
|
]
|
|
46
48
|
},
|
|
@@ -49,7 +51,7 @@
|
|
|
49
51
|
"hooks": [
|
|
50
52
|
{
|
|
51
53
|
"type": "command",
|
|
52
|
-
"command": "INPUT=$(cat); CMD=$(
|
|
54
|
+
"command": "INPUT=$(cat); CMD=$(printf %s \"$INPUT\" | { if command -v jq >/dev/null 2>&1; then jq -r '.tool_input.command // empty' 2>/dev/null; elif command -v python3 >/dev/null 2>&1; then python3 -c 'import sys,json;d=json.load(sys.stdin);print((d.get(\"tool_input\") or {}).get(\"command\") or \"\")' 2>/dev/null; elif command -v node >/dev/null 2>&1; then node -e 'let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>{try{process.stdout.write(String((JSON.parse(s).tool_input||{}).command||\"\"))}catch(e){}})' 2>/dev/null; else echo __CCHOOK_NO_PARSER__; fi; }); if [ \"$CMD\" = \"__CCHOOK_NO_PARSER__\" ]; then W=/tmp/cc-noparser-warned-git-protection-$PPID; [ -f \"$W\" ] || { echo \"WARNING [git-protection]: cannot inspect tool calls - jq, python3 and node are all unavailable, so this plugin is NOT protecting you. Install any one of them.\" >&2; : > \"$W\"; }; exit 0; fi; [ -z \"$CMD\" ] && exit 0; if echo \"$CMD\" | grep -qE 'git\\s+branch\\b[^;&|]*(-D|--delete[^;&|]*--force|--force[^;&|]*--delete)'; then echo 'BLOCKED [git-protection]: Force branch deletion. Use -d (safe delete) instead of -D.' >&2; exit 2; fi"
|
|
53
55
|
}
|
|
54
56
|
]
|
|
55
57
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "safety-essentials",
|
|
3
3
|
"description": "5 essential safety hooks for Claude Code. Blocks rm -rf, force-push, hard-reset, .env overwrites, and package publish. The minimum viable safety net from 800+ hours of autonomous operation.",
|
|
4
|
-
"version": "1.
|
|
5
|
-
"author": {
|
|
4
|
+
"version": "1.2.0",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "yurukusa"
|
|
7
|
+
},
|
|
6
8
|
"homepage": "https://yurukusa.github.io/cc-safe-setup/",
|
|
7
9
|
"repository": "https://github.com/yurukusa/cc-safe-setup",
|
|
8
10
|
"license": "MIT",
|
|
@@ -13,7 +15,7 @@
|
|
|
13
15
|
"hooks": [
|
|
14
16
|
{
|
|
15
17
|
"type": "command",
|
|
16
|
-
"command": "INPUT=$(cat); CMD=$(
|
|
18
|
+
"command": "INPUT=$(cat); CMD=$(printf %s \"$INPUT\" | { if command -v jq >/dev/null 2>&1; then jq -r '.tool_input.command // empty' 2>/dev/null; elif command -v python3 >/dev/null 2>&1; then python3 -c 'import sys,json;d=json.load(sys.stdin);print((d.get(\"tool_input\") or {}).get(\"command\") or \"\")' 2>/dev/null; elif command -v node >/dev/null 2>&1; then node -e 'let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>{try{process.stdout.write(String((JSON.parse(s).tool_input||{}).command||\"\"))}catch(e){}})' 2>/dev/null; else echo __CCHOOK_NO_PARSER__; fi; }); if [ \"$CMD\" = \"__CCHOOK_NO_PARSER__\" ]; then W=/tmp/cc-noparser-warned-safety-essentials-$PPID; [ -f \"$W\" ] || { echo \"WARNING [safety-essentials]: cannot inspect tool calls - jq, python3 and node are all unavailable, so this plugin is NOT protecting you. Install any one of them.\" >&2; : > \"$W\"; }; exit 0; fi; [ -z \"$CMD\" ] && exit 0; if echo \"$CMD\" | grep -qE 'rm\\s([^;&|]*\\s)?-[a-zA-Z]*r[a-zA-Z]*\\s[^;&|]*-[a-zA-Z]*f|rm\\s([^;&|]*\\s)?-[a-zA-Z]*f[a-zA-Z]*\\s[^;&|]*-[a-zA-Z]*r|rm\\s([^;&|]*\\s)?-[a-zA-Z]*(rf|fr)[a-zA-Z]*(\\s|$)|rm\\s[^;&|]*--recursive[^;&|]*--force|rm\\s[^;&|]*--force[^;&|]*--recursive'; then echo 'BLOCKED [safety-essentials]: rm -rf detected. Use git clean or manual deletion instead.' >&2; exit 2; fi"
|
|
17
19
|
}
|
|
18
20
|
]
|
|
19
21
|
},
|
|
@@ -22,7 +24,7 @@
|
|
|
22
24
|
"hooks": [
|
|
23
25
|
{
|
|
24
26
|
"type": "command",
|
|
25
|
-
"command": "INPUT=$(cat); CMD=$(
|
|
27
|
+
"command": "INPUT=$(cat); CMD=$(printf %s \"$INPUT\" | { if command -v jq >/dev/null 2>&1; then jq -r '.tool_input.command // empty' 2>/dev/null; elif command -v python3 >/dev/null 2>&1; then python3 -c 'import sys,json;d=json.load(sys.stdin);print((d.get(\"tool_input\") or {}).get(\"command\") or \"\")' 2>/dev/null; elif command -v node >/dev/null 2>&1; then node -e 'let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>{try{process.stdout.write(String((JSON.parse(s).tool_input||{}).command||\"\"))}catch(e){}})' 2>/dev/null; else echo __CCHOOK_NO_PARSER__; fi; }); if [ \"$CMD\" = \"__CCHOOK_NO_PARSER__\" ]; then W=/tmp/cc-noparser-warned-safety-essentials-$PPID; [ -f \"$W\" ] || { echo \"WARNING [safety-essentials]: cannot inspect tool calls - jq, python3 and node are all unavailable, so this plugin is NOT protecting you. Install any one of them.\" >&2; : > \"$W\"; }; exit 0; fi; [ -z \"$CMD\" ] && exit 0; CMD_NOLEASE=$(printf %s \"$CMD\" | sed 's/--force-with-lease[^ ]*//g'); if echo \"$CMD_NOLEASE\" | grep -qE 'git\\s+push.*--force|git\\s+push.*-f\\b'; then echo 'BLOCKED [safety-essentials]: Force push detected. Use --force-with-lease or push normally.' >&2; exit 2; fi"
|
|
26
28
|
}
|
|
27
29
|
]
|
|
28
30
|
},
|
|
@@ -31,7 +33,7 @@
|
|
|
31
33
|
"hooks": [
|
|
32
34
|
{
|
|
33
35
|
"type": "command",
|
|
34
|
-
"command": "INPUT=$(cat); CMD=$(
|
|
36
|
+
"command": "INPUT=$(cat); CMD=$(printf %s \"$INPUT\" | { if command -v jq >/dev/null 2>&1; then jq -r '.tool_input.command // empty' 2>/dev/null; elif command -v python3 >/dev/null 2>&1; then python3 -c 'import sys,json;d=json.load(sys.stdin);print((d.get(\"tool_input\") or {}).get(\"command\") or \"\")' 2>/dev/null; elif command -v node >/dev/null 2>&1; then node -e 'let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>{try{process.stdout.write(String((JSON.parse(s).tool_input||{}).command||\"\"))}catch(e){}})' 2>/dev/null; else echo __CCHOOK_NO_PARSER__; fi; }); if [ \"$CMD\" = \"__CCHOOK_NO_PARSER__\" ]; then W=/tmp/cc-noparser-warned-safety-essentials-$PPID; [ -f \"$W\" ] || { echo \"WARNING [safety-essentials]: cannot inspect tool calls - jq, python3 and node are all unavailable, so this plugin is NOT protecting you. Install any one of them.\" >&2; : > \"$W\"; }; exit 0; fi; [ -z \"$CMD\" ] && exit 0; if echo \"$CMD\" | grep -qE 'git\\s+reset\\b[^;&|]*--hard'; then echo 'BLOCKED [safety-essentials]: git reset --hard discards uncommitted changes. Use git stash instead.' >&2; exit 2; fi"
|
|
35
37
|
}
|
|
36
38
|
]
|
|
37
39
|
},
|
|
@@ -40,7 +42,7 @@
|
|
|
40
42
|
"hooks": [
|
|
41
43
|
{
|
|
42
44
|
"type": "command",
|
|
43
|
-
"command": "INPUT=$(cat); FILE=$(
|
|
45
|
+
"command": "INPUT=$(cat); FILE=$(printf %s \"$INPUT\" | { if command -v jq >/dev/null 2>&1; then jq -r '.tool_input.file_path // empty' 2>/dev/null; elif command -v python3 >/dev/null 2>&1; then python3 -c 'import sys,json;d=json.load(sys.stdin);print((d.get(\"tool_input\") or {}).get(\"file_path\") or \"\")' 2>/dev/null; elif command -v node >/dev/null 2>&1; then node -e 'let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>{try{process.stdout.write(String((JSON.parse(s).tool_input||{}).file_path||\"\"))}catch(e){}})' 2>/dev/null; else echo __CCHOOK_NO_PARSER__; fi; }); if [ \"$FILE\" = \"__CCHOOK_NO_PARSER__\" ]; then W=/tmp/cc-noparser-warned-safety-essentials-$PPID; [ -f \"$W\" ] || { echo \"WARNING [safety-essentials]: cannot inspect tool calls - jq, python3 and node are all unavailable, so this plugin is NOT protecting you. Install any one of them.\" >&2; : > \"$W\"; }; exit 0; fi; [ -z \"$FILE\" ] && exit 0; if echo \"$FILE\" | grep -qE '\\.env$|\\.env\\.' && ! echo \"$FILE\" | grep -qiE '\\.env\\.(example|sample|template|dist)$'; then echo \"BLOCKED [safety-essentials]: Writing to environment file: $FILE\" >&2; exit 2; fi"
|
|
44
46
|
}
|
|
45
47
|
]
|
|
46
48
|
},
|
|
@@ -49,7 +51,7 @@
|
|
|
49
51
|
"hooks": [
|
|
50
52
|
{
|
|
51
53
|
"type": "command",
|
|
52
|
-
"command": "INPUT=$(cat); CMD=$(
|
|
54
|
+
"command": "INPUT=$(cat); CMD=$(printf %s \"$INPUT\" | { if command -v jq >/dev/null 2>&1; then jq -r '.tool_input.command // empty' 2>/dev/null; elif command -v python3 >/dev/null 2>&1; then python3 -c 'import sys,json;d=json.load(sys.stdin);print((d.get(\"tool_input\") or {}).get(\"command\") or \"\")' 2>/dev/null; elif command -v node >/dev/null 2>&1; then node -e 'let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>{try{process.stdout.write(String((JSON.parse(s).tool_input||{}).command||\"\"))}catch(e){}})' 2>/dev/null; else echo __CCHOOK_NO_PARSER__; fi; }); if [ \"$CMD\" = \"__CCHOOK_NO_PARSER__\" ]; then W=/tmp/cc-noparser-warned-safety-essentials-$PPID; [ -f \"$W\" ] || { echo \"WARNING [safety-essentials]: cannot inspect tool calls - jq, python3 and node are all unavailable, so this plugin is NOT protecting you. Install any one of them.\" >&2; : > \"$W\"; }; exit 0; fi; [ -z \"$CMD\" ] && exit 0; if echo \"$CMD\" | grep -qE 'npm\\s+publish|yarn\\s+publish'; then echo 'BLOCKED [safety-essentials]: Package publish requires manual execution.' >&2; exit 2; fi"
|
|
53
55
|
}
|
|
54
56
|
]
|
|
55
57
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "token-guard",
|
|
3
3
|
"description": "Token consumption guards for Claude Code. Warns on large file reads (100KB+), limits unique file reads per session, estimates token budget, and caps subagent spawns. From 800+ hours of autonomous operation data.",
|
|
4
|
-
"version": "1.
|
|
5
|
-
"author": {
|
|
4
|
+
"version": "1.1.0",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "yurukusa"
|
|
7
|
+
},
|
|
6
8
|
"homepage": "https://yurukusa.github.io/cc-safe-setup/token-book.html",
|
|
7
9
|
"repository": "https://github.com/yurukusa/cc-safe-setup",
|
|
8
10
|
"license": "MIT",
|
|
@@ -13,7 +15,7 @@
|
|
|
13
15
|
"hooks": [
|
|
14
16
|
{
|
|
15
17
|
"type": "command",
|
|
16
|
-
"command": "INPUT=$(cat); FP=$(
|
|
18
|
+
"command": "INPUT=$(cat); FP=$(printf %s \"$INPUT\" | { if command -v jq >/dev/null 2>&1; then jq -r '.tool_input.file_path // empty' 2>/dev/null; elif command -v python3 >/dev/null 2>&1; then python3 -c 'import sys,json;d=json.load(sys.stdin);print((d.get(\"tool_input\") or {}).get(\"file_path\") or \"\")' 2>/dev/null; elif command -v node >/dev/null 2>&1; then node -e 'let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>{try{process.stdout.write(String((JSON.parse(s).tool_input||{}).file_path||\"\"))}catch(e){}})' 2>/dev/null; else echo __CCHOOK_NO_PARSER__; fi; }); if [ \"$FP\" = \"__CCHOOK_NO_PARSER__\" ]; then W=/tmp/cc-noparser-warned-token-guard-$PPID; [ -f \"$W\" ] || { echo \"WARNING [token-guard]: cannot inspect tool calls - jq, python3 and node are all unavailable, so this plugin is NOT protecting you. Install any one of them.\" >&2; : > \"$W\"; }; exit 0; fi; [ -z \"$FP\" ] || [ ! -f \"$FP\" ] && exit 0; SZ=$(stat -c%s \"$FP\" 2>/dev/null || stat -f%z \"$FP\" 2>/dev/null); [ \"$SZ\" -gt 102400 ] 2>/dev/null && echo \"Warning [token-guard]: $(basename $FP) is $((SZ/1024))KB. Use limit parameter to read only what you need.\" || true"
|
|
17
19
|
}
|
|
18
20
|
]
|
|
19
21
|
},
|
|
@@ -22,27 +24,27 @@
|
|
|
22
24
|
"hooks": [
|
|
23
25
|
{
|
|
24
26
|
"type": "command",
|
|
25
|
-
"command": "BUDGET=${CC_READ_BUDGET:-100}; WARN=${CC_READ_WARN:-50}; T=/tmp/cc-read-budget-$PPID; INPUT=$(cat); FP=$(
|
|
27
|
+
"command": "BUDGET=${CC_READ_BUDGET:-100}; WARN=${CC_READ_WARN:-50}; T=/tmp/cc-read-budget-$PPID; INPUT=$(cat); FP=$(printf %s \"$INPUT\" | { if command -v jq >/dev/null 2>&1; then jq -r '.tool_input.file_path // empty' 2>/dev/null; elif command -v python3 >/dev/null 2>&1; then python3 -c 'import sys,json;d=json.load(sys.stdin);print((d.get(\"tool_input\") or {}).get(\"file_path\") or \"\")' 2>/dev/null; elif command -v node >/dev/null 2>&1; then node -e 'let s=\"\";process.stdin.on(\"data\",d=>s+=d).on(\"end\",()=>{try{process.stdout.write(String((JSON.parse(s).tool_input||{}).file_path||\"\"))}catch(e){}})' 2>/dev/null; else echo __CCHOOK_NO_PARSER__; fi; }); if [ \"$FP\" = \"__CCHOOK_NO_PARSER__\" ]; then W=/tmp/cc-noparser-warned-token-guard-$PPID; [ -f \"$W\" ] || { echo \"WARNING [token-guard]: cannot inspect tool calls - jq, python3 and node are all unavailable, so this plugin is NOT protecting you. Install any one of them.\" >&2; : > \"$W\"; }; exit 0; fi; [ -z \"$FP\" ] && exit 0; C=0; if [ -f \"$T\" ]; then grep -qF \"$FP\" \"$T\" || echo \"$FP\" >> \"$T\"; C=$(wc -l < \"$T\"); else echo \"$FP\" > \"$T\"; C=1; fi; [ \"$C\" -ge \"$BUDGET\" ] && { echo \"[BLOCK token-guard] Read budget reached (${BUDGET} files). Use Glob/Grep to narrow down.\"; exit 2; }; [ \"$C\" -ge \"$WARN\" ] && echo \"Warning [token-guard]: ${C}/${BUDGET} files read.\"; exit 0"
|
|
26
28
|
}
|
|
27
29
|
]
|
|
28
30
|
},
|
|
29
31
|
{
|
|
30
|
-
"matcher": "Agent",
|
|
32
|
+
"matcher": "Task|Agent",
|
|
31
33
|
"hooks": [
|
|
32
34
|
{
|
|
33
35
|
"type": "command",
|
|
34
|
-
"command": "MAX=${CC_MAX_AGENTS:-3}; T=/tmp/cc-agents-$PPID; C=0; [ -f \"$T\" ] && C=$(cat \"$T\"); C=$((C+1)); echo $C > \"$T\"; [ $C -gt $MAX ] && { echo \"[BLOCK] Subagent limit (${MAX}). Complete existing agents first.\"; exit 2; }; [ $C -ge $MAX ] && echo \"Warning: ${C}/${MAX} subagents spawned.\""
|
|
36
|
+
"command": "MAX=${CC_MAX_AGENTS:-3}; T=/tmp/cc-agents-$PPID; C=0; [ -f \"$T\" ] && C=$(cat \"$T\"); C=$((C+1)); echo $C > \"$T\"; [ $C -gt $MAX ] && { echo \"[BLOCK token-guard] Subagent limit (${MAX}). Complete existing agents first.\"; exit 2; }; [ $C -ge $MAX ] && echo \"Warning [token-guard]: ${C}/${MAX} subagents spawned.\"; exit 0"
|
|
35
37
|
}
|
|
36
38
|
]
|
|
37
39
|
}
|
|
38
40
|
],
|
|
39
41
|
"PostToolUse": [
|
|
40
42
|
{
|
|
41
|
-
"matcher":
|
|
43
|
+
"matcher": "",
|
|
42
44
|
"hooks": [
|
|
43
45
|
{
|
|
44
46
|
"type": "command",
|
|
45
|
-
"command": "WARN=${CC_TOKEN_BUDGET:-50000}; BLOCK=${CC_TOKEN_BLOCK:-100000}; T=/tmp/cc-tokens-$PPID; INPUT=$(cat); SZ=${#INPUT}; TK=$((SZ/4)); TOTAL=0; [ -f \"$T\" ] && TOTAL=$(cat \"$T\"); TOTAL=$((TOTAL+TK)); echo $TOTAL > \"$T\"; [ $TOTAL -ge $BLOCK ] && { echo \"[BLOCK] Token budget exceeded (~${TOTAL}). Run /compact.\"; exit 2; }; [ $TOTAL -ge $WARN ] && echo \"Warning: ~${TOTAL} tokens consumed (limit: ${BLOCK}).\""
|
|
47
|
+
"command": "WARN=${CC_TOKEN_BUDGET:-50000}; BLOCK=${CC_TOKEN_BLOCK:-100000}; T=/tmp/cc-tokens-$PPID; INPUT=$(cat); SZ=${#INPUT}; TK=$((SZ/4)); TOTAL=0; [ -f \"$T\" ] && TOTAL=$(cat \"$T\"); TOTAL=$((TOTAL+TK)); echo $TOTAL > \"$T\"; [ $TOTAL -ge $BLOCK ] && { echo \"[BLOCK token-guard] Token budget exceeded (~${TOTAL}). Run /compact.\"; exit 2; }; [ $TOTAL -ge $WARN ] && echo \"Warning [token-guard]: ~${TOTAL} tokens consumed (limit: ${BLOCK}).\"; exit 0"
|
|
46
48
|
}
|
|
47
49
|
]
|
|
48
50
|
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# agents-md-sync-setup.sh — Safely set up CLAUDE.md <-> AGENTS.md
|
|
4
|
+
# sync so a single edit keeps both in step. Solves the #6235 pain
|
|
5
|
+
# at the source instead of only warning about drift.
|
|
6
|
+
# ================================================================
|
|
7
|
+
# PURPOSE:
|
|
8
|
+
# anthropics/claude-code#6235 (5,268 reactions, 13+ months open,
|
|
9
|
+
# the single largest feature request in the Claude Code tracker)
|
|
10
|
+
# asks Claude Code to read AGENTS.md as a fallback to CLAUDE.md.
|
|
11
|
+
# Codex, Cursor, Amp, Aider and others converge on AGENTS.md;
|
|
12
|
+
# Claude Code reads CLAUDE.md. Operators end up hand-syncing two
|
|
13
|
+
# files, and they drift.
|
|
14
|
+
#
|
|
15
|
+
# cc-safe-setup already ships two DETECTION hooks:
|
|
16
|
+
# - agents-md-sync-checker.sh (SessionStart: reports drift)
|
|
17
|
+
# - agents-md-edit-drift-warner.sh (PostToolUse: warns at edit)
|
|
18
|
+
# Both tell you that the files are out of sync. Neither sets up
|
|
19
|
+
# the sync. This script closes that gap: it inspects the current
|
|
20
|
+
# state and performs the one safe action that removes future
|
|
21
|
+
# drift — replacing one file with a relative symlink to the other,
|
|
22
|
+
# so other agents read AGENTS.md, Claude Code reads CLAUDE.md, and
|
|
23
|
+
# one edit updates both.
|
|
24
|
+
#
|
|
25
|
+
# Hooks cannot do this safely (they fire mid-session and must not
|
|
26
|
+
# mutate the repo), so this is a standalone, operator-run script.
|
|
27
|
+
#
|
|
28
|
+
# UPSTREAM REFERENCES:
|
|
29
|
+
# #6235 (read AGENTS.md as a fallback to CLAUDE.md)
|
|
30
|
+
#
|
|
31
|
+
# USAGE:
|
|
32
|
+
# bash scripts/agents-md-sync-setup.sh # dry-run: print the plan only
|
|
33
|
+
# bash scripts/agents-md-sync-setup.sh --apply # perform the plan (with backups)
|
|
34
|
+
# bash scripts/agents-md-sync-setup.sh --help
|
|
35
|
+
#
|
|
36
|
+
# SAFETY (this is a safety toolkit — it never loses your content):
|
|
37
|
+
# - Dry-run is the DEFAULT. Nothing is modified without --apply.
|
|
38
|
+
# - Before replacing any real file with a symlink, the original is
|
|
39
|
+
# moved to <file>.bak-<timestamp> (never deleted, never rm'd).
|
|
40
|
+
# - If both files exist with DIFFERENT content, the script REFUSES
|
|
41
|
+
# to modify anything and prints how to reconcile. It never merges
|
|
42
|
+
# or overwrites differing instructions.
|
|
43
|
+
# - On filesystems without symlink support (e.g. some Windows
|
|
44
|
+
# setups), set CC_AGENTS_SYNC_MODE=copy to use a one-way copy plus
|
|
45
|
+
# a printed git pre-commit reminder instead of a symlink.
|
|
46
|
+
#
|
|
47
|
+
# CONFIGURATION (env vars):
|
|
48
|
+
# CC_AGENTS_SYNC_DIR Directory to operate in (default: cwd).
|
|
49
|
+
# CC_AGENTS_SYNC_CANONICAL Which file holds the real content and is
|
|
50
|
+
# the symlink target: "claude" (default) or
|
|
51
|
+
# "agents". The other becomes the symlink.
|
|
52
|
+
# CC_AGENTS_SYNC_MODE "symlink" (default) or "copy".
|
|
53
|
+
# CC_AGENTS_SYNC_TIMESTAMP Override the backup timestamp (tests).
|
|
54
|
+
# ================================================================
|
|
55
|
+
|
|
56
|
+
set -u
|
|
57
|
+
|
|
58
|
+
DIR="${CC_AGENTS_SYNC_DIR:-.}"
|
|
59
|
+
CANONICAL="${CC_AGENTS_SYNC_CANONICAL:-claude}"
|
|
60
|
+
MODE="${CC_AGENTS_SYNC_MODE:-symlink}"
|
|
61
|
+
APPLY=0
|
|
62
|
+
|
|
63
|
+
while [ $# -gt 0 ]; do
|
|
64
|
+
case "$1" in
|
|
65
|
+
--apply) APPLY=1; shift ;;
|
|
66
|
+
-h|--help)
|
|
67
|
+
sed -n '2,57p' "$0" | sed 's/^# \{0,1\}//'
|
|
68
|
+
exit 0 ;;
|
|
69
|
+
*) echo "Unknown argument: $1 (try --help)" >&2; exit 2 ;;
|
|
70
|
+
esac
|
|
71
|
+
done
|
|
72
|
+
|
|
73
|
+
CLAUDE="$DIR/CLAUDE.md"
|
|
74
|
+
AGENTS="$DIR/AGENTS.md"
|
|
75
|
+
|
|
76
|
+
# Decide which file is canonical (holds content) and which is the link.
|
|
77
|
+
if [ "$CANONICAL" = "agents" ]; then
|
|
78
|
+
SRC="$AGENTS"; SRC_NAME="AGENTS.md"
|
|
79
|
+
LINK="$CLAUDE"; LINK_NAME="CLAUDE.md"
|
|
80
|
+
else
|
|
81
|
+
SRC="$CLAUDE"; SRC_NAME="CLAUDE.md"
|
|
82
|
+
LINK="$AGENTS"; LINK_NAME="AGENTS.md"
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
say() { echo "$@"; }
|
|
86
|
+
plan() { if [ "$APPLY" -eq 1 ]; then echo " APPLYING: $*"; else echo " PLAN (dry-run): $*"; fi; }
|
|
87
|
+
|
|
88
|
+
# --- State 0: neither file exists ---
|
|
89
|
+
if [ ! -e "$CLAUDE" ] && [ ! -e "$AGENTS" ]; then
|
|
90
|
+
say "No CLAUDE.md or AGENTS.md found in $DIR."
|
|
91
|
+
say "Create your instructions in CLAUDE.md first, then re-run to mirror it to AGENTS.md."
|
|
92
|
+
exit 0
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
# --- State 1: already synced (same inode, i.e. one is a link to the other) ---
|
|
96
|
+
if [ -e "$CLAUDE" ] && [ -e "$AGENTS" ] && [ "$CLAUDE" -ef "$AGENTS" ]; then
|
|
97
|
+
say "Already synced: CLAUDE.md and AGENTS.md resolve to the same file. Nothing to do."
|
|
98
|
+
exit 0
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
# --- State 5: both exist with DIFFERENT content -> refuse to modify ---
|
|
102
|
+
if [ -e "$CLAUDE" ] && [ -e "$AGENTS" ] && ! cmp -s "$CLAUDE" "$AGENTS"; then
|
|
103
|
+
csize=$(wc -c < "$CLAUDE" 2>/dev/null | tr -d ' ')
|
|
104
|
+
asize=$(wc -c < "$AGENTS" 2>/dev/null | tr -d ' ')
|
|
105
|
+
say "CLAUDE.md ($csize bytes) and AGENTS.md ($asize bytes) exist with DIFFERENT content."
|
|
106
|
+
say "Refusing to modify either file — that would lose one set of instructions."
|
|
107
|
+
say ""
|
|
108
|
+
say "Reconcile first, then re-run:"
|
|
109
|
+
say " 1. Decide which file is correct (or merge them by hand into one)."
|
|
110
|
+
say " 2. Make the other identical, or delete it."
|
|
111
|
+
say " 3. Re-run this script to replace the duplicate with a symlink."
|
|
112
|
+
say ""
|
|
113
|
+
say " diff CLAUDE.md AGENTS.md # review the differences"
|
|
114
|
+
exit 0
|
|
115
|
+
fi
|
|
116
|
+
|
|
117
|
+
# At this point either only one file exists, or both exist with identical content.
|
|
118
|
+
# In both cases the plan is: ensure SRC holds the content and LINK points to it.
|
|
119
|
+
|
|
120
|
+
# If only the LINK-named file exists (and SRC does not), flip roles so we keep the
|
|
121
|
+
# real file and create the missing one as the link — never discard existing content.
|
|
122
|
+
if [ ! -e "$SRC" ] && [ -e "$LINK" ]; then
|
|
123
|
+
tmp="$SRC"; SRC="$LINK"; LINK="$tmp"
|
|
124
|
+
tmp="$SRC_NAME"; SRC_NAME="$LINK_NAME"; LINK_NAME="$tmp"
|
|
125
|
+
fi
|
|
126
|
+
|
|
127
|
+
TS="${CC_AGENTS_SYNC_TIMESTAMP:-$(date +%Y%m%d-%H%M%S)}"
|
|
128
|
+
|
|
129
|
+
say "Source of truth: $SRC_NAME -> link: $LINK_NAME (mode: $MODE)"
|
|
130
|
+
|
|
131
|
+
if [ "$MODE" = "copy" ]; then
|
|
132
|
+
plan "copy $SRC_NAME to $LINK_NAME (one-way; symlinks unavailable)"
|
|
133
|
+
if [ -e "$LINK" ] && [ ! -L "$LINK" ]; then
|
|
134
|
+
plan "back up existing $LINK_NAME to $(basename "$LINK").bak-$TS"
|
|
135
|
+
fi
|
|
136
|
+
if [ "$APPLY" -eq 1 ]; then
|
|
137
|
+
[ -e "$LINK" ] && [ ! -L "$LINK" ] && mv "$LINK" "$LINK.bak-$TS"
|
|
138
|
+
cp "$SRC" "$LINK"
|
|
139
|
+
say "Done. $LINK_NAME is now a COPY of $SRC_NAME."
|
|
140
|
+
say "Copies drift. Add a git pre-commit hook that fails when they differ, or re-run after edits."
|
|
141
|
+
fi
|
|
142
|
+
exit 0
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
# symlink mode
|
|
146
|
+
plan "replace $LINK_NAME with a relative symlink -> $SRC_NAME"
|
|
147
|
+
if [ -e "$LINK" ] && [ ! -L "$LINK" ]; then
|
|
148
|
+
plan "back up existing $LINK_NAME to $(basename "$LINK").bak-$TS"
|
|
149
|
+
fi
|
|
150
|
+
if [ "$APPLY" -eq 1 ]; then
|
|
151
|
+
[ -e "$LINK" ] && [ ! -L "$LINK" ] && mv "$LINK" "$LINK.bak-$TS"
|
|
152
|
+
[ -L "$LINK" ] && rm -f "$LINK" # only removes an existing symlink, never a real file
|
|
153
|
+
( cd "$DIR" && ln -s "$(basename "$SRC")" "$(basename "$LINK")" )
|
|
154
|
+
say "Done. $LINK_NAME -> $SRC_NAME. One edit to $SRC_NAME now updates both."
|
|
155
|
+
fi
|
|
156
|
+
exit 0
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# autonomy-blocked-summary.sh — Summarise AskUserQuestion blocks recorded by
|
|
3
|
+
# askuserquestion-autonomy-gate.sh over the past N hours.
|
|
4
|
+
#
|
|
5
|
+
# Companion script for the operator who runs /goal overnight or autonomous
|
|
6
|
+
# tasks with CC_AUTONOMY_MODE=1. After the agent runs, this script prints
|
|
7
|
+
# a quick "how many AskUserQuestion calls were blocked, and when?" summary
|
|
8
|
+
# so the operator can decide whether to relax the autonomy mode for some
|
|
9
|
+
# legitimate question topics in future runs.
|
|
10
|
+
#
|
|
11
|
+
# Usage:
|
|
12
|
+
# ./autonomy-blocked-summary.sh # past 24 hours
|
|
13
|
+
# ./autonomy-blocked-summary.sh --hours 12 # past 12 hours
|
|
14
|
+
# ./autonomy-blocked-summary.sh --hours 24 --json # past 24 hours, JSON
|
|
15
|
+
#
|
|
16
|
+
# Reads from $CC_AUTONOMY_MODE_RECEIPT_DIR (default: ~/.claude/receipts).
|
|
17
|
+
# Returns exit 0 always; this is read-only reporting, not gating.
|
|
18
|
+
|
|
19
|
+
set -u
|
|
20
|
+
|
|
21
|
+
HOURS=24
|
|
22
|
+
FORMAT=text
|
|
23
|
+
|
|
24
|
+
while [[ $# -gt 0 ]]; do
|
|
25
|
+
case "$1" in
|
|
26
|
+
--hours) HOURS="$2"; shift 2 ;;
|
|
27
|
+
--json) FORMAT=json; shift ;;
|
|
28
|
+
-h|--help)
|
|
29
|
+
cat <<EOF
|
|
30
|
+
autonomy-blocked-summary.sh — summarise blocked AskUserQuestion calls
|
|
31
|
+
|
|
32
|
+
Usage: $0 [--hours N] [--json]
|
|
33
|
+
|
|
34
|
+
Reads JSONL receipts from \$CC_AUTONOMY_MODE_RECEIPT_DIR (default ~/.claude/receipts)
|
|
35
|
+
and prints how many AskUserQuestion calls were blocked in the past N hours.
|
|
36
|
+
EOF
|
|
37
|
+
exit 0
|
|
38
|
+
;;
|
|
39
|
+
*) echo "Unknown option: $1" >&2; exit 1 ;;
|
|
40
|
+
esac
|
|
41
|
+
done
|
|
42
|
+
|
|
43
|
+
RECEIPT_DIR="${CC_AUTONOMY_MODE_RECEIPT_DIR:-$HOME/.claude/receipts}"
|
|
44
|
+
if [[ ! -d "$RECEIPT_DIR" ]]; then
|
|
45
|
+
if [[ "$FORMAT" = json ]]; then
|
|
46
|
+
echo '{"error":"receipt_dir_not_found","path":"'"$RECEIPT_DIR"'"}'
|
|
47
|
+
else
|
|
48
|
+
echo "No receipt directory at $RECEIPT_DIR. Has the hook fired yet?" >&2
|
|
49
|
+
fi
|
|
50
|
+
exit 0
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Cutoff: now - HOURS hours, as ISO 8601 UTC
|
|
54
|
+
CUTOFF=$(python3 -c "
|
|
55
|
+
import datetime
|
|
56
|
+
cutoff = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(hours=$HOURS)
|
|
57
|
+
print(cutoff.strftime('%Y-%m-%dT%H:%M:%SZ'))
|
|
58
|
+
" 2>/dev/null) || {
|
|
59
|
+
echo "python3 required for time calculation" >&2
|
|
60
|
+
exit 1
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# Gather receipts. The hook writes one file per UTC date:
|
|
64
|
+
# autonomy-blocked-YYYY-MM-DD.jsonl
|
|
65
|
+
RECEIPTS=$(find "$RECEIPT_DIR" -maxdepth 1 -type f -name 'autonomy-blocked-*.jsonl' 2>/dev/null)
|
|
66
|
+
if [[ -z "$RECEIPTS" ]]; then
|
|
67
|
+
if [[ "$FORMAT" = json ]]; then
|
|
68
|
+
echo '{"hours":'"$HOURS"',"blocked_count":0,"earliest":null,"latest":null}'
|
|
69
|
+
else
|
|
70
|
+
echo "No autonomy-block receipts found in $RECEIPT_DIR."
|
|
71
|
+
echo "Either no AskUserQuestion was blocked, or CC_AUTONOMY_MODE was never set."
|
|
72
|
+
fi
|
|
73
|
+
exit 0
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# Filter and summarise via python (stdlib only)
|
|
77
|
+
echo "$RECEIPTS" | python3 -c "
|
|
78
|
+
import sys
|
|
79
|
+
import json
|
|
80
|
+
import os
|
|
81
|
+
|
|
82
|
+
cutoff = '$CUTOFF'
|
|
83
|
+
hours = $HOURS
|
|
84
|
+
fmt = '$FORMAT'
|
|
85
|
+
|
|
86
|
+
files = [line.strip() for line in sys.stdin if line.strip()]
|
|
87
|
+
records = []
|
|
88
|
+
for path in files:
|
|
89
|
+
try:
|
|
90
|
+
with open(path, 'r', encoding='utf-8') as f:
|
|
91
|
+
for line in f:
|
|
92
|
+
line = line.strip()
|
|
93
|
+
if not line:
|
|
94
|
+
continue
|
|
95
|
+
try:
|
|
96
|
+
rec = json.loads(line)
|
|
97
|
+
except json.JSONDecodeError:
|
|
98
|
+
continue
|
|
99
|
+
ts = rec.get('ts', '')
|
|
100
|
+
if ts and ts >= cutoff:
|
|
101
|
+
records.append(rec)
|
|
102
|
+
except (IOError, OSError):
|
|
103
|
+
continue
|
|
104
|
+
|
|
105
|
+
records.sort(key=lambda r: r.get('ts', ''))
|
|
106
|
+
|
|
107
|
+
count = len(records)
|
|
108
|
+
earliest = records[0].get('ts') if records else None
|
|
109
|
+
latest = records[-1].get('ts') if records else None
|
|
110
|
+
|
|
111
|
+
# Distribution of question lengths
|
|
112
|
+
lengths = [r.get('question_length', 0) for r in records if r.get('question_length')]
|
|
113
|
+
if lengths:
|
|
114
|
+
avg_len = sum(lengths) / len(lengths)
|
|
115
|
+
max_len = max(lengths)
|
|
116
|
+
min_len = min(lengths)
|
|
117
|
+
else:
|
|
118
|
+
avg_len = max_len = min_len = 0
|
|
119
|
+
|
|
120
|
+
if fmt == 'json':
|
|
121
|
+
out = {
|
|
122
|
+
'hours': hours,
|
|
123
|
+
'blocked_count': count,
|
|
124
|
+
'earliest': earliest,
|
|
125
|
+
'latest': latest,
|
|
126
|
+
'question_length_stats': {
|
|
127
|
+
'avg': round(avg_len, 1),
|
|
128
|
+
'max': max_len,
|
|
129
|
+
'min': min_len,
|
|
130
|
+
},
|
|
131
|
+
}
|
|
132
|
+
print(json.dumps(out))
|
|
133
|
+
else:
|
|
134
|
+
print(f'AskUserQuestion blocks in the past {hours} hours: {count}')
|
|
135
|
+
if count > 0:
|
|
136
|
+
print(f' Earliest: {earliest}')
|
|
137
|
+
print(f' Latest: {latest}')
|
|
138
|
+
print(f' Question length stats (bytes): avg {avg_len:.1f}, min {min_len}, max {max_len}')
|
|
139
|
+
if count >= 10:
|
|
140
|
+
print('')
|
|
141
|
+
print(' 10 or more blocks suggests the autonomy rule is colliding with')
|
|
142
|
+
print(' a genuine need for the model to ask. Consider whether some')
|
|
143
|
+
print(' question topics (e.g. \"destructive operation? y/N\") deserve')
|
|
144
|
+
print(' a narrower allowlist rather than a blanket block.')
|
|
145
|
+
else:
|
|
146
|
+
print(' (No blocks recorded. Either the hook was not configured, or the')
|
|
147
|
+
print(' model never tried to ask a question during the window.)')
|
|
148
|
+
"
|