cc-safe-setup 29.6.32 → 29.6.33
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/COOKBOOK.md +70 -0
- package/README.md +6 -2
- package/examples/absolute-rule-enforcer.sh +42 -0
- package/examples/allow-claude-settings.sh +2 -0
- package/examples/allow-git-hooks-dir.sh +2 -0
- package/examples/allow-protected-dirs.sh +2 -0
- package/examples/allowlist.sh +2 -0
- package/examples/ansible-vault-guard.sh +2 -0
- package/examples/auto-approve-build.sh +2 -0
- package/examples/auto-approve-compound-git.sh +2 -0
- package/examples/auto-approve-docker.sh +2 -0
- package/examples/auto-approve-git-read.sh +2 -0
- package/examples/auto-approve-python.sh +2 -0
- package/examples/auto-approve-readonly-tools.sh +2 -0
- package/examples/auto-approve-ssh.sh +2 -0
- package/examples/auto-approve-test.sh +2 -0
- package/examples/auto-checkpoint.sh +2 -0
- package/examples/auto-git-checkpoint.sh +2 -0
- package/examples/auto-mode-safe-commands.sh +2 -0
- package/examples/auto-snapshot.sh +2 -0
- package/examples/backup-before-refactor.sh +2 -0
- package/examples/banned-command-guard.sh +3 -3
- package/examples/bash-domain-allowlist.sh +72 -0
- package/examples/bash-safety-auto-deny.sh +56 -0
- package/examples/bash-secret-output-detector.sh +68 -0
- package/examples/bash-timeout-guard.sh +2 -0
- package/examples/bashrc-safety-check.sh +59 -0
- package/examples/bg-task-cooldown-guard.sh +46 -0
- package/examples/block-database-wipe.sh +2 -0
- package/examples/branch-name-check.sh +2 -0
- package/examples/branch-naming-convention.sh +2 -0
- package/examples/cargo-publish-guard.sh +2 -0
- package/examples/check-abort-controller.sh +2 -0
- package/examples/check-accessibility.sh +2 -0
- package/examples/check-aria-labels.sh +2 -0
- package/examples/check-async-await-consistency.sh +2 -0
- package/examples/check-before-act-enforcer.sh +47 -0
- package/examples/check-charset-meta.sh +2 -0
- package/examples/check-cleanup-effect.sh +2 -0
- package/examples/check-content-type.sh +2 -0
- package/examples/check-controlled-input.sh +2 -0
- package/examples/check-cookie-flags.sh +2 -0
- package/examples/check-cors-config.sh +2 -0
- package/examples/check-csp-headers.sh +2 -0
- package/examples/check-csrf-protection.sh +2 -0
- package/examples/check-debounce.sh +2 -0
- package/examples/check-dependency-age.sh +2 -0
- package/examples/check-dependency-license.sh +2 -0
- package/examples/check-dockerfile-best-practice.sh +2 -0
- package/examples/check-error-boundaries.sh +2 -0
- package/examples/check-error-class.sh +2 -0
- package/examples/check-error-handling.sh +2 -0
- package/examples/check-error-logging.sh +2 -0
- package/examples/check-error-message.sh +2 -0
- package/examples/check-error-page.sh +2 -0
- package/examples/check-error-stack.sh +2 -0
- package/examples/check-favicon.sh +2 -0
- package/examples/check-form-validation.sh +2 -0
- package/examples/check-git-hooks-compat.sh +2 -0
- package/examples/check-https-redirect.sh +2 -0
- package/examples/check-image-optimization.sh +2 -0
- package/examples/check-input-validation.sh +2 -0
- package/examples/check-key-prop.sh +2 -0
- package/examples/check-lang-attribute.sh +2 -0
- package/examples/check-lazy-loading.sh +2 -0
- package/examples/check-loading-state.sh +2 -0
- package/examples/check-memo-deps.sh +2 -0
- package/examples/check-meta-description.sh +2 -0
- package/examples/check-npm-scripts-exist.sh +2 -0
- package/examples/check-null-check.sh +2 -0
- package/examples/check-package-size.sh +2 -0
- package/examples/check-pagination.sh +2 -0
- package/examples/check-port-availability.sh +2 -0
- package/examples/check-promise-all.sh +2 -0
- package/examples/check-prop-types.sh +2 -0
- package/examples/check-rate-limiting.sh +2 -0
- package/examples/check-responsive-design.sh +2 -0
- package/examples/check-retry-logic.sh +2 -0
- package/examples/check-return-types.sh +2 -0
- package/examples/check-semantic-html.sh +2 -0
- package/examples/check-semantic-versioning.sh +2 -0
- package/examples/check-suspense-fallback.sh +2 -0
- package/examples/check-test-naming.sh +2 -0
- package/examples/check-timeout-cleanup.sh +2 -0
- package/examples/check-tls-version.sh +2 -0
- package/examples/check-type-coercion.sh +2 -0
- package/examples/check-unsubscribe.sh +2 -0
- package/examples/check-viewport-meta.sh +2 -0
- package/examples/check-worker-terminate.sh +2 -0
- package/examples/checkpoint-tamper-guard.sh +2 -0
- package/examples/chmod-guard.sh +2 -0
- package/examples/chown-guard.sh +2 -0
- package/examples/ci-workflow-guard.sh +59 -0
- package/examples/classifier-fallback-allow.sh +2 -0
- package/examples/claude-cache-gc.sh +15 -0
- package/examples/claudeignore-enforce-guard.sh +60 -0
- package/examples/claudemd-enforcer.sh +2 -0
- package/examples/commit-message-check.sh +2 -0
- package/examples/compact-blocker.sh +25 -0
- package/examples/composer-guard.sh +2 -0
- package/examples/compound-command-allow.sh +2 -0
- package/examples/consecutive-failure-circuit-breaker.sh +49 -0
- package/examples/console-log-count.sh +2 -0
- package/examples/context-compact-advisor.sh +16 -0
- package/examples/cors-star-warn.sh +2 -0
- package/examples/credential-exfil-guard.sh +2 -0
- package/examples/credential-file-cat-guard.sh +2 -0
- package/examples/cron-modification-guard.sh +40 -0
- package/examples/cwd-project-boundary-guard.sh +50 -0
- package/examples/denied-action-retry-guard.sh +41 -0
- package/examples/dependency-install-guard.sh +2 -0
- package/examples/deploy-guard.sh +2 -0
- package/examples/deploy-path-verify-guard.sh +62 -0
- package/examples/django-migrate-guard.sh +2 -0
- package/examples/docker-volume-guard.sh +2 -0
- package/examples/dockerfile-latest-guard.sh +2 -0
- package/examples/dotenv-commit-guard.sh +44 -0
- package/examples/dotenv-example-sync.sh +55 -0
- package/examples/dotnet-build-on-edit.sh +2 -0
- package/examples/drizzle-migrate-guard.sh +2 -0
- package/examples/edit-counter-test-gate.sh +44 -0
- package/examples/edit-error-counter.sh +2 -0
- package/examples/edit-guard.sh +2 -0
- package/examples/edit-retry-loop-guard.sh +2 -0
- package/examples/edit-verify.sh +2 -0
- package/examples/enforce-tests.sh +2 -0
- package/examples/env-inherit-guard.sh +2 -0
- package/examples/env-inline-secret-guard.sh +36 -0
- package/examples/env-prod-guard.sh +2 -0
- package/examples/env-required-check.sh +2 -0
- package/examples/env-var-check.sh +2 -0
- package/examples/expo-eject-guard.sh +2 -0
- package/examples/export-overwrite-guard.sh +29 -0
- package/examples/file-change-tracker.sh +2 -0
- package/examples/file-change-undo-tracker.sh +46 -0
- package/examples/file-recycle-bin.sh +48 -0
- package/examples/file-size-limit.sh +2 -0
- package/examples/five-hundred-milestone.sh +2 -0
- package/examples/flask-debug-guard.sh +2 -0
- package/examples/gem-push-guard.sh +2 -0
- package/examples/git-checkout-safety-guard.sh +2 -0
- package/examples/git-config-guard.sh +2 -0
- package/examples/git-hook-bypass-guard.sh +2 -0
- package/examples/git-merge-conflict-prevent.sh +2 -0
- package/examples/git-message-length.sh +2 -0
- package/examples/git-show-flag-sanitizer.sh +41 -0
- package/examples/git-stash-before-danger.sh +2 -0
- package/examples/git-submodule-guard.sh +2 -0
- package/examples/git-tag-guard.sh +2 -0
- package/examples/github-actions-secret-guard.sh +59 -0
- package/examples/gitignore-check.sh +2 -0
- package/examples/gitops-drift-guard.sh +53 -0
- package/examples/go-mod-tidy-warn.sh +2 -0
- package/examples/hallucination-url-check.sh +2 -0
- package/examples/hardcoded-ip-guard.sh +2 -0
- package/examples/headless-empty-result-guard.sh +46 -0
- package/examples/headless-stop-guard.sh +43 -0
- package/examples/helm-install-guard.sh +2 -0
- package/examples/issue-draft-redact-guard.sh +45 -0
- package/examples/java-compile-on-edit.sh +2 -0
- package/examples/k8s-production-guard.sh +77 -0
- package/examples/laravel-artisan-guard.sh +2 -0
- package/examples/large-file-guard.sh +2 -0
- package/examples/log-level-guard.sh +2 -0
- package/examples/magic-number-warn.sh +2 -0
- package/examples/max-edit-size-guard.sh +2 -0
- package/examples/max-file-count-guard.sh +2 -0
- package/examples/max-file-delete-count.sh +2 -0
- package/examples/max-function-length.sh +2 -0
- package/examples/max-import-count.sh +2 -0
- package/examples/max-subagent-count.sh +2 -0
- package/examples/mcp-orphan-process-guard.sh +39 -0
- package/examples/mcp-server-allowlist.sh +45 -0
- package/examples/mcp-tool-audit-log.sh +41 -0
- package/examples/mcp-tool-guard.sh +2 -0
- package/examples/migration-verify-guard.sh +44 -0
- package/examples/monorepo-scope-guard.sh +2 -0
- package/examples/network-exfil-guard.sh +61 -0
- package/examples/network-guard.sh +2 -0
- package/examples/nextjs-env-guard.sh +2 -0
- package/examples/no-absolute-import.sh +2 -0
- package/examples/no-alert-confirm-prompt.sh +2 -0
- package/examples/no-any-type.sh +2 -0
- package/examples/no-any-typescript.sh +2 -0
- package/examples/no-assignment-in-condition.sh +2 -0
- package/examples/no-callback-hell.sh +2 -0
- package/examples/no-catch-all-route.sh +2 -0
- package/examples/no-circular-dependency.sh +2 -0
- package/examples/no-class-in-functional.sh +2 -0
- package/examples/no-cleartext-storage.sh +2 -0
- package/examples/no-commented-code.sh +2 -0
- package/examples/no-commit-fixup.sh +2 -0
- package/examples/no-console-assert.sh +2 -0
- package/examples/no-console-error-swallow.sh +2 -0
- package/examples/no-console-in-prod.sh +2 -0
- package/examples/no-console-log.sh +2 -0
- package/examples/no-console-time.sh +2 -0
- package/examples/no-cors-wildcard.sh +2 -0
- package/examples/no-curl-upload.sh +2 -0
- package/examples/no-dangerouslySetInnerHTML.sh +2 -0
- package/examples/no-dangling-await.sh +2 -0
- package/examples/no-debug-in-commit.sh +2 -0
- package/examples/no-deep-nesting.sh +2 -0
- package/examples/no-deep-relative-import.sh +2 -0
- package/examples/no-default-credentials.sh +2 -0
- package/examples/no-deprecated-api.sh +2 -0
- package/examples/no-direct-dom-manipulation.sh +2 -0
- package/examples/no-disabled-test.sh +2 -0
- package/examples/no-document-cookie.sh +2 -0
- package/examples/no-document-write.sh +2 -0
- package/examples/no-empty-function.sh +2 -0
- package/examples/no-eval-in-template.sh +2 -0
- package/examples/no-eval-template.sh +2 -0
- package/examples/no-eval.sh +2 -0
- package/examples/no-exec-user-input.sh +2 -0
- package/examples/no-expose-internal-ids.sh +2 -0
- package/examples/no-floating-promises.sh +2 -0
- package/examples/no-force-install.sh +2 -0
- package/examples/no-git-rebase-public.sh +2 -0
- package/examples/no-global-state.sh +2 -0
- package/examples/no-hardcoded-port.sh +2 -0
- package/examples/no-hardcoded-url.sh +2 -0
- package/examples/no-helmet-missing.sh +2 -0
- package/examples/no-http-url.sh +2 -0
- package/examples/no-http-without-https.sh +2 -0
- package/examples/no-index-as-key.sh +2 -0
- package/examples/no-infinite-scroll-mem.sh +2 -0
- package/examples/no-inline-event-handler.sh +2 -0
- package/examples/no-inline-handler.sh +2 -0
- package/examples/no-inline-style.sh +2 -0
- package/examples/no-inline-styles.sh +2 -0
- package/examples/no-innerhtml.sh +2 -0
- package/examples/no-install-global.sh +2 -0
- package/examples/no-jwt-in-url.sh +2 -0
- package/examples/no-large-commit.sh +2 -0
- package/examples/no-localhost-expose.sh +2 -0
- package/examples/no-long-switch.sh +2 -0
- package/examples/no-magic-number.sh +2 -0
- package/examples/no-md5-sha1.sh +2 -0
- package/examples/no-memory-leak-interval.sh +2 -0
- package/examples/no-mixed-line-endings.sh +2 -0
- package/examples/no-mutation-in-reducer.sh +2 -0
- package/examples/no-mutation-observer-leak.sh +2 -0
- package/examples/no-nested-subscribe.sh +2 -0
- package/examples/no-nested-ternary.sh +2 -0
- package/examples/no-network-exfil.sh +2 -0
- package/examples/no-new-array-fill.sh +2 -0
- package/examples/no-object-freeze-mutation.sh +2 -0
- package/examples/no-open-redirect.sh +2 -0
- package/examples/no-output-truncation.sh +44 -0
- package/examples/no-package-downgrade.sh +2 -0
- package/examples/no-package-lock-edit.sh +2 -0
- package/examples/no-path-join-user-input.sh +2 -0
- package/examples/no-port-bind.sh +2 -0
- package/examples/no-process-exit.sh +2 -0
- package/examples/no-prototype-pollution.sh +2 -0
- package/examples/no-push-without-ci.sh +2 -0
- package/examples/no-raw-ref.sh +2 -0
- package/examples/no-redundant-fragment.sh +2 -0
- package/examples/no-render-in-loop.sh +2 -0
- package/examples/no-root-user-docker.sh +2 -0
- package/examples/no-root-write.sh +2 -0
- package/examples/no-secrets-in-args.sh +2 -0
- package/examples/no-secrets-in-logs.sh +2 -0
- package/examples/no-sensitive-log.sh +2 -0
- package/examples/no-side-effects-in-render.sh +2 -0
- package/examples/no-sleep-in-hooks.sh +2 -0
- package/examples/no-star-import-python.sh +2 -0
- package/examples/no-string-concat-sql.sh +2 -0
- package/examples/no-sudo-guard.sh +2 -0
- package/examples/no-sync-external-call.sh +2 -0
- package/examples/no-sync-fs.sh +2 -0
- package/examples/no-table-layout.sh +2 -0
- package/examples/no-throw-string.sh +2 -0
- package/examples/no-todo-in-merge.sh +2 -0
- package/examples/no-todo-in-production.sh +2 -0
- package/examples/no-todo-without-issue.sh +2 -0
- package/examples/no-triple-slash-ref.sh +2 -0
- package/examples/no-unreachable-code.sh +2 -0
- package/examples/no-unused-import.sh +2 -0
- package/examples/no-unused-state.sh +2 -0
- package/examples/no-var-keyword.sh +2 -0
- package/examples/no-wildcard-cors.sh +2 -0
- package/examples/no-wildcard-import.sh +2 -0
- package/examples/no-window-location.sh +2 -0
- package/examples/no-with-statement.sh +2 -0
- package/examples/no-write-outside-src.sh +2 -0
- package/examples/no-xml-external-entity.sh +2 -0
- package/examples/notify-waiting.sh +2 -0
- package/examples/npm-audit-warn.sh +2 -0
- package/examples/npm-publish-guard.sh +2 -0
- package/examples/npm-script-injection.sh +2 -0
- package/examples/npm-supply-chain-guard.sh +92 -0
- package/examples/nuxt-config-guard.sh +2 -0
- package/examples/output-secret-mask.sh +2 -0
- package/examples/package-json-guard.sh +2 -0
- package/examples/parallel-session-guard.sh +2 -0
- package/examples/path-traversal-guard.sh +2 -0
- package/examples/permission-audit-log.sh +2 -0
- package/examples/permission-entry-validator.sh +48 -0
- package/examples/php-lint-on-edit.sh +2 -0
- package/examples/pip-publish-guard.sh +2 -0
- package/examples/plain-language-danger-warn.sh +37 -0
- package/examples/plan-mode-enforcer.sh +2 -0
- package/examples/plugin-process-cleanup.sh +50 -0
- package/examples/polyglot-rm-guard.sh +59 -0
- package/examples/pr-description-check.sh +2 -0
- package/examples/pre-compact-knowledge-save.sh +53 -0
- package/examples/pre-compact-transcript-export.sh +85 -0
- package/examples/prefer-builtin-tools.sh +2 -0
- package/examples/prefer-const.sh +2 -0
- package/examples/prefer-dedicated-tools.sh +55 -0
- package/examples/prefer-optional-chaining.sh +2 -0
- package/examples/prisma-migrate-guard.sh +2 -0
- package/examples/prompt-injection-detector.sh +2 -0
- package/examples/prompt-length-guard.sh +2 -0
- package/examples/protect-dotfiles.sh +2 -0
- package/examples/public-repo-push-guard.sh +58 -0
- package/examples/push-requires-test-pass-record.sh +2 -0
- package/examples/push-requires-test-pass.sh +2 -0
- package/examples/rails-migration-guard.sh +2 -0
- package/examples/rate-limit-guard.sh +2 -0
- package/examples/read-all-files-enforcer.sh +51 -0
- package/examples/readme-exists-check.sh +2 -0
- package/examples/redis-flushall-guard.sh +2 -0
- package/examples/rm-safety-net.sh +2 -0
- package/examples/role-tool-guard.sh +69 -0
- package/examples/ruby-lint-on-edit.sh +2 -0
- package/examples/schema-migration-guard.sh +57 -0
- package/examples/scope-guard.sh +2 -0
- package/examples/secret-file-read-guard.sh +74 -0
- package/examples/self-modify-bypass-guard.sh +54 -0
- package/examples/sensitive-log-guard.sh +2 -0
- package/examples/session-checkpoint.sh +2 -0
- package/examples/session-end-logger.sh +57 -0
- package/examples/session-error-rate-monitor.sh +65 -0
- package/examples/session-health-monitor.sh +61 -0
- package/examples/session-memory-watchdog.sh +17 -0
- package/examples/session-permission-reset-guard.sh +39 -0
- package/examples/session-resume-env-fix.sh +49 -0
- package/examples/session-state-saver.sh +2 -0
- package/examples/session-summary-stop.sh +2 -0
- package/examples/session-summary.sh +2 -0
- package/examples/session-token-counter.sh +2 -0
- package/examples/shell-wrapper-guard.sh +2 -0
- package/examples/skill-gate.sh +2 -0
- package/examples/skill-injection-detector.sh +41 -0
- package/examples/spec-file-scope-guard.sh +69 -0
- package/examples/spring-profile-guard.sh +2 -0
- package/examples/sql-injection-detect.sh +2 -0
- package/examples/subagent-budget-guard.sh +2 -0
- package/examples/subagent-claudemd-inject.sh +45 -0
- package/examples/subagent-tool-call-limiter.sh +48 -0
- package/examples/svelte-lint-on-edit.sh +2 -0
- package/examples/swift-build-on-edit.sh +2 -0
- package/examples/system-message-workaround.sh +44 -0
- package/examples/system-package-guard.sh +2 -0
- package/examples/temp-file-cleanup.sh +2 -0
- package/examples/terminal-state-restore.sh +23 -0
- package/examples/test-after-edit.sh +2 -0
- package/examples/test-before-commit.sh +2 -0
- package/examples/test-before-push.sh +2 -0
- package/examples/test-exit-code-verify.sh +2 -0
- package/examples/timeout-guard.sh +2 -0
- package/examples/timezone-guard.sh +2 -0
- package/examples/tmp-output-size-guard.sh +46 -0
- package/examples/todo-check.sh +2 -0
- package/examples/todo-deadline-warn.sh +48 -0
- package/examples/token-budget-per-task.sh +55 -0
- package/examples/token-usage-tracker.sh +14 -0
- package/examples/turbo-cache-guard.sh +2 -0
- package/examples/uncommitted-changes-stop.sh +2 -0
- package/examples/uncommitted-work-shield.sh +37 -0
- package/examples/usage-warn.sh +2 -0
- package/examples/verify-before-commit.sh +2 -0
- package/examples/vue-lint-on-edit.sh +2 -0
- package/examples/webfetch-domain-allow.sh +96 -0
- package/examples/worktree-memory-guard.sh +47 -0
- package/examples/worktree-project-unify.sh +19 -0
- package/examples/worktree-unmerged-guard.sh +2 -0
- package/examples/write-overwrite-confirm.sh +40 -0
- package/examples/write-secret-guard.sh +2 -0
- package/examples/write-test-ratio.sh +2 -0
- package/package.json +2 -2
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# TRIGGER: PreToolUse MATCHER: "Edit|Write"
|
|
2
4
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
3
5
|
[ -z "$CONTENT" ] && exit 0
|
|
4
6
|
echo "$CONTENT" | grep -qiE "\"SELECT.*\+|'SELECT.*\+" && echo "WARNING: String concatenation in SQL — use parameterized queries" >&2
|
package/examples/no-sync-fs.sh
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# TRIGGER: PreToolUse MATCHER: "Edit|Write"
|
|
2
4
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
3
5
|
[ -z "$CONTENT" ] && exit 0
|
|
4
6
|
echo "$CONTENT" | grep -qE "readFileSync|writeFileSync|mkdirSync|existsSync" && echo "NOTE: Sync fs in hot path — consider async" >&2
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
2
4
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
3
5
|
[ -z "$CONTENT" ] && exit 0
|
|
4
6
|
COMMAND=$(cat | jq -r ".tool_input.command // empty" 2>/dev/null); echo "$COMMAND" | grep -qE "git\s+merge" && git diff --cached 2>/dev/null | grep -q "TODO" && echo "WARNING: TODO markers in merge target" >&2
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# TRIGGER: PreToolUse MATCHER: "Edit|Write"
|
|
2
4
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
3
5
|
[ -z "$CONTENT" ] && exit 0
|
|
4
6
|
echo "$CONTENT" | grep -qE "TODO[^(]|FIXME[^(]" && ! echo "$CONTENT" | grep -qE "TODO\(#|FIXME\(#" && echo "NOTE: TODO without issue reference" >&2
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# TRIGGER: PreToolUse MATCHER: "Edit|Write"
|
|
2
4
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
3
5
|
[ -z "$CONTENT" ] && exit 0
|
|
4
6
|
echo "$CONTENT" | grep -qE "^import.*from" && echo "$CONTENT" | grep -cE "^import" | xargs -I{} test {} -gt 10 && echo "NOTE: Many imports — check for unused ones" >&2
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# TRIGGER: PreToolUse MATCHER: "Edit|Write"
|
|
2
4
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
3
5
|
[ -z "$CONTENT" ] && exit 0
|
|
4
6
|
echo "$CONTENT" | grep -qE "^\s*var\s" && echo "NOTE: var keyword — use const/let" >&2
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# TRIGGER: PreToolUse MATCHER: "Edit|Write"
|
|
2
4
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
3
5
|
[ -z "$CONTENT" ] && exit 0
|
|
4
6
|
echo "$CONTENT" | grep -qE "Access-Control.*\*" && echo "WARNING: Wildcard CORS origin" >&2
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# TRIGGER: PreToolUse MATCHER: "Edit|Write"
|
|
2
4
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
3
5
|
[ -z "$CONTENT" ] && exit 0
|
|
4
6
|
echo "$CONTENT" | grep -qE "\bwith\s*\(" && echo "WARNING: with statement is deprecated" >&2
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# TRIGGER: PreToolUse MATCHER: "Edit|Write"
|
|
2
4
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
3
5
|
[ -z "$CONTENT" ] && exit 0
|
|
4
6
|
echo "$CONTENT" | grep -qE "parseXML|xml2js|DOMParser|libxml" && echo "$CONTENT" | grep -q "ENTITY" && echo "WARNING: Possible XXE in XML parsing" >&2
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
# }
|
|
18
18
|
|
|
19
19
|
# Linux (notify-send) — skip on WSL2 where D-Bus may not be running
|
|
20
|
+
#
|
|
21
|
+
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
20
22
|
if command -v notify-send &>/dev/null && [ -z "$WSL_DISTRO_NAME" ]; then
|
|
21
23
|
notify-send "Claude Code" "Waiting for your input" --urgency=normal 2>/dev/null && exit 0
|
|
22
24
|
fi
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
2
4
|
COMMAND=$(cat | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
3
5
|
[ -z "$COMMAND" ] && exit 0
|
|
4
6
|
if echo "$COMMAND" | grep -qE '^\s*(npm\s+publish|npx\s+npm\s+publish)' && ! echo "$COMMAND" | grep -qE '\-\-dry-run'; then
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# npm-supply-chain-guard.sh — Detect npm supply chain attack patterns
|
|
3
|
+
#
|
|
4
|
+
# Solves: npm install can execute arbitrary code via postinstall scripts.
|
|
5
|
+
# Claude Code may install malicious packages via typosquatting,
|
|
6
|
+
# dependency confusion, or compromised packages (#39421).
|
|
7
|
+
#
|
|
8
|
+
# How it works: PreToolUse hook on Bash that detects npm/yarn/pnpm
|
|
9
|
+
# install commands and checks for:
|
|
10
|
+
# 1. Typosquatting patterns (similar to popular packages)
|
|
11
|
+
# 2. Scoped packages from unknown registries
|
|
12
|
+
# 3. Packages with suspicious install scripts
|
|
13
|
+
# 4. Version pinning warnings
|
|
14
|
+
#
|
|
15
|
+
# TRIGGER: PreToolUse
|
|
16
|
+
# MATCHER: "Bash"
|
|
17
|
+
#
|
|
18
|
+
# Usage:
|
|
19
|
+
# {
|
|
20
|
+
# "hooks": {
|
|
21
|
+
# "PreToolUse": [{
|
|
22
|
+
# "matcher": "Bash",
|
|
23
|
+
# "hooks": [{ "type": "command", "command": "~/.claude/hooks/npm-supply-chain-guard.sh" }]
|
|
24
|
+
# }]
|
|
25
|
+
# }
|
|
26
|
+
# }
|
|
27
|
+
|
|
28
|
+
INPUT=$(cat)
|
|
29
|
+
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
30
|
+
[ -z "$CMD" ] && exit 0
|
|
31
|
+
|
|
32
|
+
# Only check npm/yarn/pnpm install commands
|
|
33
|
+
echo "$CMD" | grep -qE '\b(npm|yarn|pnpm)\s+(install|add|i)\b' || exit 0
|
|
34
|
+
|
|
35
|
+
# Extract package names from command
|
|
36
|
+
PACKAGES=$(echo "$CMD" | grep -oE '\b(npm|yarn|pnpm)\s+(install|add|i)\s+(.+)' | sed -E 's/^(npm|yarn|pnpm)\s+(install|add|i)\s+//' | tr ' ' '\n' | grep -v '^-')
|
|
37
|
+
|
|
38
|
+
WARNINGS=""
|
|
39
|
+
|
|
40
|
+
for pkg in $PACKAGES; do
|
|
41
|
+
# Skip flags
|
|
42
|
+
[[ "$pkg" == -* ]] && continue
|
|
43
|
+
|
|
44
|
+
# Check for known typosquatting patterns
|
|
45
|
+
# Common targets: lodash, express, react, axios, webpack, babel
|
|
46
|
+
POPULAR=("lodash" "express" "react" "axios" "webpack" "babel" "moment" "chalk" "commander" "inquirer")
|
|
47
|
+
for popular in "${POPULAR[@]}"; do
|
|
48
|
+
# Skip exact matches
|
|
49
|
+
[ "$pkg" = "$popular" ] && continue
|
|
50
|
+
# Check Levenshtein-like similarity (simple: 1 char difference)
|
|
51
|
+
if [ "${#pkg}" -ge 3 ] && [ "${#pkg}" -le $((${#popular} + 2)) ]; then
|
|
52
|
+
# Check if package name is very similar to a popular one
|
|
53
|
+
diff_count=$(python3 -c "
|
|
54
|
+
import sys
|
|
55
|
+
a, b = '$pkg', '$popular'
|
|
56
|
+
if abs(len(a)-len(b)) <= 2:
|
|
57
|
+
# Simple edit distance check
|
|
58
|
+
d = sum(1 for x,y in zip(a,b) if x!=y) + abs(len(a)-len(b))
|
|
59
|
+
print(d)
|
|
60
|
+
else:
|
|
61
|
+
print(99)
|
|
62
|
+
" 2>/dev/null)
|
|
63
|
+
if [ -n "$diff_count" ] && [ "$diff_count" -le 2 ] && [ "$diff_count" -gt 0 ]; then
|
|
64
|
+
WARNINGS="${WARNINGS}\n ⚠ '$pkg' looks similar to popular package '$popular' (possible typosquatting)"
|
|
65
|
+
fi
|
|
66
|
+
fi
|
|
67
|
+
done
|
|
68
|
+
|
|
69
|
+
# Check for internal/private scope packages being installed from public registry
|
|
70
|
+
if echo "$pkg" | grep -qE '^@[a-z]+-internal/|^@private-'; then
|
|
71
|
+
WARNINGS="${WARNINGS}\n ⚠ '$pkg' looks like an internal scoped package — verify it exists on the intended registry"
|
|
72
|
+
fi
|
|
73
|
+
done
|
|
74
|
+
|
|
75
|
+
# Check for --ignore-scripts bypass
|
|
76
|
+
if echo "$CMD" | grep -q '\-\-ignore-scripts'; then
|
|
77
|
+
# This is actually a safety measure, no warning needed
|
|
78
|
+
:
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
# Warn about not using --ignore-scripts
|
|
82
|
+
if [ -n "$PACKAGES" ] && ! echo "$CMD" | grep -qE '\-\-ignore-scripts|\-\-production'; then
|
|
83
|
+
WARNINGS="${WARNINGS}\n ℹ Consider using --ignore-scripts to prevent postinstall script execution"
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
if [ -n "$WARNINGS" ]; then
|
|
87
|
+
echo "⚠ npm supply chain check:" >&2
|
|
88
|
+
echo -e "$WARNINGS" >&2
|
|
89
|
+
# Warn but don't block — exit 0
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
exit 0
|
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
# cat ~/.claude/tool-usage.jsonl | jq -s 'group_by(.tool) | map({tool: .[0].tool, count: length}) | sort_by(-.count)'
|
|
26
26
|
# # Top commands:
|
|
27
27
|
# cat ~/.claude/tool-usage.jsonl | jq -s '[.[] | select(.tool=="Bash")] | group_by(.command | split(" ")[0]) | map({cmd: .[0].command | split(" ")[0], count: length}) | sort_by(-.count) | .[:20]'
|
|
28
|
+
#
|
|
29
|
+
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
28
30
|
|
|
29
31
|
INPUT=$(cat)
|
|
30
32
|
TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# permission-entry-validator.sh — Clean broken permission entries from settings
|
|
3
|
+
#
|
|
4
|
+
# Solves: Shell redirect targets saved as standalone permissions (#40382).
|
|
5
|
+
# Commands like `az ... > "filepath"` cause Claude Code to save
|
|
6
|
+
# `Bash("D:/path/file.json")` which is a bare filepath, not a command.
|
|
7
|
+
#
|
|
8
|
+
# How it works: Stop hook that reads settings.local.json and removes
|
|
9
|
+
# permission entries that are bare file paths (not valid command patterns).
|
|
10
|
+
# Identifies entries matching path patterns without a command prefix.
|
|
11
|
+
#
|
|
12
|
+
# TRIGGER: Stop
|
|
13
|
+
# MATCHER: ""
|
|
14
|
+
|
|
15
|
+
set -euo pipefail
|
|
16
|
+
|
|
17
|
+
SETTINGS_FILE=".claude/settings.local.json"
|
|
18
|
+
[ -f "$SETTINGS_FILE" ] || exit 0
|
|
19
|
+
|
|
20
|
+
# Check for broken entries (bare file paths as Bash permissions)
|
|
21
|
+
BROKEN=$(jq -r '
|
|
22
|
+
.permissions.allow // [] | .[] |
|
|
23
|
+
select(
|
|
24
|
+
startswith("Bash(\"") and
|
|
25
|
+
(
|
|
26
|
+
# Windows paths
|
|
27
|
+
test("^Bash\\(\"[A-Z]:/") or
|
|
28
|
+
# Unix absolute paths without command
|
|
29
|
+
test("^Bash\\(\"/[^\"]*\"\\)$")
|
|
30
|
+
) and
|
|
31
|
+
# Must NOT contain a space (command + args have spaces)
|
|
32
|
+
(test("^Bash\\(\"[^\" ]*\"\\)$"))
|
|
33
|
+
)
|
|
34
|
+
' "$SETTINGS_FILE" 2>/dev/null || true)
|
|
35
|
+
|
|
36
|
+
if [ -n "$BROKEN" ]; then
|
|
37
|
+
COUNT=$(echo "$BROKEN" | wc -l)
|
|
38
|
+
echo "WARNING: Found $COUNT broken permission entries (bare file paths):" >&2
|
|
39
|
+
echo "$BROKEN" | head -5 | while IFS= read -r entry; do
|
|
40
|
+
echo " $entry" >&2
|
|
41
|
+
done
|
|
42
|
+
echo "" >&2
|
|
43
|
+
echo "These entries were likely created by 'Always allow' on commands with" >&2
|
|
44
|
+
echo "shell redirects (> filepath). They don't match any command pattern." >&2
|
|
45
|
+
echo "Consider removing them from $SETTINGS_FILE" >&2
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
exit 0
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# plain-language-danger-warn.sh — Add plain-language warnings to dangerous commands
|
|
3
|
+
#
|
|
4
|
+
# Solves: Users not understanding technical risk of commands (#30505).
|
|
5
|
+
# "git reset --hard" doesn't convey "this deletes all your unsaved work."
|
|
6
|
+
#
|
|
7
|
+
# How it works: PreToolUse hook on Bash that detects dangerous commands
|
|
8
|
+
# and injects plain-language explanations into stderr context.
|
|
9
|
+
#
|
|
10
|
+
# TRIGGER: PreToolUse
|
|
11
|
+
# MATCHER: "Bash"
|
|
12
|
+
|
|
13
|
+
set -euo pipefail
|
|
14
|
+
|
|
15
|
+
INPUT=$(cat)
|
|
16
|
+
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
17
|
+
[ -z "$COMMAND" ] && exit 0
|
|
18
|
+
|
|
19
|
+
# Map dangerous commands to plain-language warnings
|
|
20
|
+
if echo "$COMMAND" | grep -qE 'git\s+reset\s+--hard'; then
|
|
21
|
+
echo "WARNING: This will DELETE all unsaved changes in your working directory." >&2
|
|
22
|
+
echo "Any uncommitted work will be permanently lost." >&2
|
|
23
|
+
elif echo "$COMMAND" | grep -qE 'git\s+clean\s+-[fd]'; then
|
|
24
|
+
echo "WARNING: This will DELETE all untracked files (files not in git)." >&2
|
|
25
|
+
elif echo "$COMMAND" | grep -qE 'git\s+push\s+.*--force'; then
|
|
26
|
+
echo "WARNING: This will OVERWRITE the remote branch history." >&2
|
|
27
|
+
echo "Other people's commits may be permanently lost." >&2
|
|
28
|
+
elif echo "$COMMAND" | grep -qE 'rm\s+-rf\s+/'; then
|
|
29
|
+
echo "WARNING: This will DELETE everything on the system. Unrecoverable." >&2
|
|
30
|
+
elif echo "$COMMAND" | grep -qE 'drop\s+(database|table|schema)'; then
|
|
31
|
+
echo "WARNING: This will DELETE the entire database/table. Data is unrecoverable." >&2
|
|
32
|
+
elif echo "$COMMAND" | grep -qE 'truncate\s+table'; then
|
|
33
|
+
echo "WARNING: This will DELETE all rows in the table." >&2
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Always allow — this hook only warns, doesn't block
|
|
37
|
+
exit 0
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# plugin-process-cleanup.sh — Kill leaked plugin subprocesses on session end
|
|
3
|
+
#
|
|
4
|
+
# Solves: Channel plugin subprocesses (bun server.ts) leak across sessions,
|
|
5
|
+
# accumulating to 1000%+ CPU usage (#39137). Each session spawns
|
|
6
|
+
# new processes but never kills old ones.
|
|
7
|
+
#
|
|
8
|
+
# How it works: SessionEnd hook that finds and kills plugin server processes
|
|
9
|
+
# that are still running from the Claude plugins cache directory.
|
|
10
|
+
#
|
|
11
|
+
# TRIGGER: SessionEnd
|
|
12
|
+
# MATCHER: ""
|
|
13
|
+
#
|
|
14
|
+
# Usage:
|
|
15
|
+
# {
|
|
16
|
+
# "hooks": {
|
|
17
|
+
# "SessionEnd": [{
|
|
18
|
+
# "hooks": [{ "type": "command", "command": "~/.claude/hooks/plugin-process-cleanup.sh" }]
|
|
19
|
+
# }]
|
|
20
|
+
# }
|
|
21
|
+
# }
|
|
22
|
+
|
|
23
|
+
# Find plugin server processes from Claude's cache
|
|
24
|
+
PLUGIN_CACHE="$HOME/.claude/plugins/cache"
|
|
25
|
+
|
|
26
|
+
# Kill bun/node server processes from plugin directories
|
|
27
|
+
PIDS=$(pgrep -f "$PLUGIN_CACHE" 2>/dev/null)
|
|
28
|
+
|
|
29
|
+
if [ -n "$PIDS" ]; then
|
|
30
|
+
COUNT=$(echo "$PIDS" | wc -l | tr -d ' ')
|
|
31
|
+
echo "Cleaning up $COUNT leaked plugin process(es)..." >&2
|
|
32
|
+
|
|
33
|
+
for pid in $PIDS; do
|
|
34
|
+
# Try graceful shutdown first
|
|
35
|
+
kill "$pid" 2>/dev/null
|
|
36
|
+
done
|
|
37
|
+
|
|
38
|
+
# Wait briefly for graceful shutdown
|
|
39
|
+
sleep 1
|
|
40
|
+
|
|
41
|
+
# Force kill any remaining
|
|
42
|
+
for pid in $PIDS; do
|
|
43
|
+
if kill -0 "$pid" 2>/dev/null; then
|
|
44
|
+
kill -9 "$pid" 2>/dev/null
|
|
45
|
+
echo " Force-killed PID $pid" >&2
|
|
46
|
+
fi
|
|
47
|
+
done
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
exit 0
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# polyglot-rm-guard.sh — Block file deletion via any language, not just rm
|
|
3
|
+
#
|
|
4
|
+
# Solves: Claude circumvents Bash(rm) deny rules by using Python os.remove(),
|
|
5
|
+
# Node fs.unlinkSync(), or other languages to delete files (#39459).
|
|
6
|
+
# The permission system blocks the tool, not the goal.
|
|
7
|
+
#
|
|
8
|
+
# How it works: PreToolUse hook on Bash that detects file deletion attempts
|
|
9
|
+
# via Python, Node, Ruby, Perl, or any other interpreter — not just rm.
|
|
10
|
+
#
|
|
11
|
+
# TRIGGER: PreToolUse
|
|
12
|
+
# MATCHER: "Bash"
|
|
13
|
+
#
|
|
14
|
+
# Usage:
|
|
15
|
+
# {
|
|
16
|
+
# "hooks": {
|
|
17
|
+
# "PreToolUse": [{
|
|
18
|
+
# "matcher": "Bash",
|
|
19
|
+
# "hooks": [{ "type": "command", "command": "~/.claude/hooks/polyglot-rm-guard.sh" }]
|
|
20
|
+
# }]
|
|
21
|
+
# }
|
|
22
|
+
# }
|
|
23
|
+
|
|
24
|
+
INPUT=$(cat)
|
|
25
|
+
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
26
|
+
[ -z "$CMD" ] && exit 0
|
|
27
|
+
|
|
28
|
+
# Python file deletion
|
|
29
|
+
if echo "$CMD" | grep -qE 'python[23]?\s+-c\s.*\b(os\.remove|os\.unlink|shutil\.rmtree|pathlib.*unlink)\b'; then
|
|
30
|
+
echo "BLOCKED: File deletion via Python detected." >&2
|
|
31
|
+
echo "Blocked: os.remove/unlink/rmtree circumvents rm restrictions." >&2
|
|
32
|
+
exit 2
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# Node.js file deletion
|
|
36
|
+
if echo "$CMD" | grep -qE 'node\s+-e\s.*\b(unlinkSync|rmdirSync|rmSync|fs\.rm)\b'; then
|
|
37
|
+
echo "BLOCKED: File deletion via Node.js detected." >&2
|
|
38
|
+
exit 2
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Ruby file deletion
|
|
42
|
+
if echo "$CMD" | grep -qE 'ruby\s+-e\s.*\b(File\.delete|FileUtils\.rm)\b'; then
|
|
43
|
+
echo "BLOCKED: File deletion via Ruby detected." >&2
|
|
44
|
+
exit 2
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# Perl file deletion
|
|
48
|
+
if echo "$CMD" | grep -qE 'perl\s+-[eE]\s.*\bunlink\b'; then
|
|
49
|
+
echo "BLOCKED: File deletion via Perl detected." >&2
|
|
50
|
+
exit 2
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Generic: any interpreter with remove/delete/unlink in the command
|
|
54
|
+
if echo "$CMD" | grep -qE '(python|node|ruby|perl|php)\s+.*-[ceE]\s.*\b(remove|unlink|delete|rmtree|rmdir)\b'; then
|
|
55
|
+
echo "BLOCKED: File deletion via interpreter detected." >&2
|
|
56
|
+
exit 2
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
exit 0
|