cc-safe-setup 28.4.8 → 28.5.0
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 +143 -0
- package/README.md +1 -0
- package/examples/auto-approve-docker.sh +1 -0
- package/examples/auto-approve-test.sh +1 -0
- package/examples/auto-compact-prep.sh +19 -8
- package/examples/auto-git-checkpoint.sh +1 -0
- package/examples/backup-before-refactor.sh +1 -0
- package/examples/branch-naming-convention.sh +1 -0
- package/examples/check-accessibility.sh +1 -0
- package/examples/check-aria-labels.sh +1 -0
- package/examples/check-charset-meta.sh +1 -0
- package/examples/check-cookie-flags.sh +1 -0
- package/examples/check-cors-config.sh +1 -0
- package/examples/check-csp-headers.sh +1 -0
- package/examples/check-csrf-protection.sh +1 -0
- package/examples/check-dependency-age.sh +1 -0
- package/examples/check-dependency-license.sh +1 -0
- package/examples/check-dockerfile-best-practice.sh +1 -0
- package/examples/check-error-boundaries.sh +1 -0
- package/examples/check-error-handling.sh +1 -0
- package/examples/check-error-message.sh +1 -0
- package/examples/check-error-stack.sh +1 -0
- package/examples/check-favicon.sh +1 -0
- package/examples/check-git-hooks-compat.sh +1 -0
- package/examples/check-gitattributes.sh +1 -0
- package/examples/check-https-redirect.sh +1 -0
- package/examples/check-input-validation.sh +1 -0
- package/examples/check-lang-attribute.sh +1 -0
- package/examples/check-npm-scripts-exist.sh +1 -0
- package/examples/check-package-size.sh +1 -0
- package/examples/check-port-availability.sh +1 -0
- package/examples/check-rate-limiting.sh +1 -0
- package/examples/check-return-types.sh +1 -0
- package/examples/check-semantic-versioning.sh +1 -0
- package/examples/check-test-naming.sh +1 -0
- package/examples/check-tls-version.sh +1 -0
- package/examples/check-viewport-meta.sh +1 -0
- package/examples/claudemd-enforcer.sh +1 -0
- package/examples/cors-star-warn.sh +1 -0
- package/examples/docker-volume-guard.sh +1 -0
- package/examples/edit-verify.sh +1 -0
- package/examples/env-naming-convention.sh +1 -0
- package/examples/env-prod-guard.sh +1 -0
- package/examples/env-required-check.sh +1 -0
- package/examples/file-size-limit.sh +1 -0
- package/examples/git-hook-bypass-guard.sh +1 -0
- package/examples/git-merge-conflict-prevent.sh +1 -0
- package/examples/git-message-length.sh +1 -0
- package/examples/git-submodule-guard.sh +1 -0
- package/examples/git-tag-guard.sh +1 -0
- package/examples/gitignore-check.sh +1 -0
- package/examples/log-level-guard.sh +1 -0
- package/examples/max-file-count-guard.sh +1 -0
- package/examples/max-file-delete-count.sh +1 -0
- package/examples/max-function-length.sh +1 -0
- package/examples/max-import-count.sh +1 -0
- package/examples/max-subagent-count.sh +1 -0
- package/examples/mcp-tool-guard.sh +1 -0
- package/examples/no-absolute-import.sh +1 -0
- package/examples/no-alert-confirm-prompt.sh +1 -0
- package/examples/no-anonymous-default-export.sh +1 -0
- package/examples/no-any-type.sh +1 -0
- package/examples/no-assignment-in-condition.sh +1 -0
- package/examples/no-callback-hell.sh +1 -0
- package/examples/no-circular-dependency.sh +1 -0
- package/examples/no-cleartext-storage.sh +1 -0
- package/examples/no-commented-code.sh +1 -0
- package/examples/no-commit-fixup.sh +1 -0
- package/examples/no-console-assert.sh +1 -0
- package/examples/no-console-error-swallow.sh +1 -0
- package/examples/no-console-in-prod.sh +1 -0
- package/examples/no-console-log.sh +1 -0
- package/examples/no-console-time.sh +1 -0
- package/examples/no-curl-upload.sh +1 -0
- package/examples/no-dangerouslySetInnerHTML.sh +1 -0
- package/examples/no-debug-in-commit.sh +1 -0
- package/examples/no-deep-nesting.sh +1 -0
- package/examples/no-default-credentials.sh +1 -0
- package/examples/no-disabled-test.sh +1 -0
- package/examples/no-document-write.sh +1 -0
- package/examples/no-empty-function.sh +1 -0
- package/examples/no-eval-in-template.sh +1 -0
- package/examples/no-eval.sh +1 -0
- package/examples/no-exec-user-input.sh +1 -0
- package/examples/no-floating-promises.sh +1 -0
- package/examples/no-force-install.sh +1 -0
- package/examples/no-git-rebase-public.sh +1 -0
- package/examples/no-global-state.sh +1 -0
- package/examples/no-hardcoded-port.sh +1 -0
- package/examples/no-hardcoded-url.sh +1 -0
- package/examples/no-helmet-missing.sh +1 -0
- package/examples/no-http-without-https.sh +1 -0
- package/examples/no-inline-style.sh +1 -0
- package/examples/no-innerhtml.sh +1 -0
- package/examples/no-install-global.sh +1 -0
- package/examples/no-jwt-in-url.sh +1 -0
- package/examples/no-large-commit.sh +1 -0
- package/examples/no-localhost-expose.sh +1 -0
- package/examples/no-magic-number.sh +1 -0
- package/examples/no-md5-sha1.sh +1 -0
- package/examples/no-mixed-line-endings.sh +1 -0
- package/examples/no-mutation-in-reducer.sh +1 -0
- package/examples/no-nested-ternary.sh +1 -0
- package/examples/no-network-exfil.sh +1 -0
- package/examples/no-open-redirect.sh +1 -0
- package/examples/no-package-downgrade.sh +1 -0
- package/examples/no-package-lock-edit.sh +1 -0
- package/examples/no-path-join-user-input.sh +1 -0
- package/examples/no-port-bind.sh +1 -0
- package/examples/no-process-exit.sh +1 -0
- package/examples/no-prototype-pollution.sh +1 -0
- package/examples/no-push-without-ci.sh +1 -0
- package/examples/no-raw-password-in-url.sh +1 -0
- package/examples/no-root-write.sh +1 -0
- package/examples/no-secrets-in-logs.sh +1 -0
- package/examples/no-sensitive-log.sh +1 -0
- package/examples/no-sleep-in-hooks.sh +1 -0
- package/examples/no-string-concat-sql.sh +1 -0
- package/examples/no-sudo-guard.sh +1 -0
- package/examples/no-sync-fs.sh +1 -0
- package/examples/no-todo-in-merge.sh +1 -0
- package/examples/no-todo-without-issue.sh +1 -0
- package/examples/no-unused-import.sh +1 -0
- package/examples/no-var-keyword.sh +1 -0
- package/examples/no-wildcard-cors.sh +1 -0
- package/examples/no-wildcard-delete.sh +1 -0
- package/examples/no-wildcard-import.sh +1 -0
- package/examples/no-with-statement.sh +1 -0
- package/examples/no-write-outside-src.sh +1 -0
- package/examples/no-xml-external-entity.sh +1 -0
- package/examples/npm-audit-warn.sh +1 -0
- package/examples/npm-publish-guard.sh +1 -0
- package/examples/npm-script-injection.sh +1 -0
- package/examples/package-json-guard.sh +1 -0
- package/examples/pr-description-check.sh +1 -0
- package/examples/prefer-const.sh +1 -0
- package/examples/prefer-optional-chaining.sh +1 -0
- package/examples/rate-limit-guard.sh +1 -0
- package/examples/readme-exists-check.sh +1 -0
- package/examples/session-state-saver.sh +1 -0
- package/examples/session-summary.sh +1 -0
- package/examples/skill-gate.sh +1 -0
- package/examples/sql-injection-detect.sh +1 -0
- package/examples/subagent-budget-guard.sh +1 -0
- package/examples/test-before-commit.sh +1 -0
- package/examples/timezone-guard.sh +1 -0
- package/examples/usage-warn.sh +1 -0
- package/examples/write-test-ratio.sh +1 -0
- package/index.mjs +1 -1
- package/package.json +1 -1
package/COOKBOOK.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Cookbook — cc-safe-setup Recipes
|
|
2
|
+
|
|
3
|
+
Real-world recipes for common safety scenarios. Each recipe is a single command.
|
|
4
|
+
|
|
5
|
+
## Getting Started
|
|
6
|
+
|
|
7
|
+
| I want to... | Command |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Install basic safety | `npx cc-safe-setup` |
|
|
10
|
+
| Maximum protection | `npx cc-safe-setup --shield` |
|
|
11
|
+
| Check my setup | `npx cc-safe-setup --doctor` |
|
|
12
|
+
| See my safety score | `npx cc-safe-setup --audit` |
|
|
13
|
+
|
|
14
|
+
## Blocking Dangerous Commands
|
|
15
|
+
|
|
16
|
+
### Block rm -rf on home/root
|
|
17
|
+
Already included in the default install. To verify:
|
|
18
|
+
```bash
|
|
19
|
+
npx cc-safe-setup --simulate "rm -rf ~"
|
|
20
|
+
# Expected: BLOCKED
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Block database wipes
|
|
24
|
+
```bash
|
|
25
|
+
npx cc-safe-setup --install-example block-database-wipe
|
|
26
|
+
```
|
|
27
|
+
Blocks: `prisma migrate reset`, `rails db:drop`, `DROP TABLE`, etc.
|
|
28
|
+
|
|
29
|
+
### Block npm publish accidents
|
|
30
|
+
```bash
|
|
31
|
+
npx cc-safe-setup --install-example npm-publish-guard
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Auto-Approving Safe Commands
|
|
35
|
+
|
|
36
|
+
### Approve read-only commands (cat, ls, grep)
|
|
37
|
+
```bash
|
|
38
|
+
npx cc-safe-setup --install-example auto-approve-readonly
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Approve test runners
|
|
42
|
+
```bash
|
|
43
|
+
npx cc-safe-setup --install-example auto-approve-test
|
|
44
|
+
```
|
|
45
|
+
Covers: `npm test`, `pytest`, `go test`, `cargo test`, `jest`, `vitest`
|
|
46
|
+
|
|
47
|
+
### Approve git read commands (status, log, diff)
|
|
48
|
+
```bash
|
|
49
|
+
npx cc-safe-setup --install-example auto-approve-git-read
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## File Protection
|
|
53
|
+
|
|
54
|
+
### Protect .env files from edits
|
|
55
|
+
```bash
|
|
56
|
+
npx cc-safe-setup --protect .env
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Protect CLAUDE.md from unauthorized changes
|
|
60
|
+
```bash
|
|
61
|
+
npx cc-safe-setup --install-example protect-claudemd
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Protect dotfiles (~/.bashrc, ~/.aws/)
|
|
65
|
+
```bash
|
|
66
|
+
npx cc-safe-setup --install-example protect-dotfiles
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## YAML Rules (No Coding)
|
|
70
|
+
|
|
71
|
+
Write rules in YAML, compile to hooks:
|
|
72
|
+
|
|
73
|
+
```yaml
|
|
74
|
+
# rules.yaml
|
|
75
|
+
- block: "rm -rf on root"
|
|
76
|
+
pattern: "rm\s+-rf\s+(\/$|~)"
|
|
77
|
+
|
|
78
|
+
- approve: "read-only commands"
|
|
79
|
+
commands: [cat, ls, grep, head, tail]
|
|
80
|
+
|
|
81
|
+
- protect: ".env"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npx cc-safe-setup --rules rules.yaml
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Monitoring & Recovery
|
|
89
|
+
|
|
90
|
+
### Auto-save checkpoint before compaction
|
|
91
|
+
```bash
|
|
92
|
+
npx cc-safe-setup --install-example auto-compact-prep
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Track context window usage
|
|
96
|
+
```bash
|
|
97
|
+
npx cc-safe-setup --install-example compact-reminder
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Fix hook permissions on Windows/plugins
|
|
101
|
+
```bash
|
|
102
|
+
npx cc-safe-setup --install-example hook-permission-fixer
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Prevent tool call loops
|
|
106
|
+
```bash
|
|
107
|
+
npx cc-safe-setup --install-example response-budget-guard
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Diagnosing Problems
|
|
111
|
+
|
|
112
|
+
### Why isn't my hook working?
|
|
113
|
+
```bash
|
|
114
|
+
npx cc-safe-setup --doctor
|
|
115
|
+
```
|
|
116
|
+
Checks: jq, settings.json, file existence, permissions, shebangs, exit codes.
|
|
117
|
+
|
|
118
|
+
### Test a specific hook
|
|
119
|
+
```bash
|
|
120
|
+
npx cc-safe-setup --test-hook destructive-guard
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Preview how hooks react to a command
|
|
124
|
+
```bash
|
|
125
|
+
npx cc-safe-setup --simulate "git push --force origin main"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Web Tools
|
|
129
|
+
|
|
130
|
+
All browser-based, nothing leaves your machine:
|
|
131
|
+
|
|
132
|
+
- [Safety Hub](https://yurukusa.github.io/cc-safe-setup/hub.html) — All 23 tools
|
|
133
|
+
- [Validator](https://yurukusa.github.io/cc-safe-setup/validator.html) — Paste settings.json, get score
|
|
134
|
+
- [Permission Checker](https://yurukusa.github.io/cc-safe-setup/permission-checker.html) — Find broken paths
|
|
135
|
+
- [Playground](https://yurukusa.github.io/cc-safe-setup/playground.html) — Write and test hooks
|
|
136
|
+
- [Hook Builder](https://yurukusa.github.io/cc-safe-setup/builder.html) — Generate hooks from English
|
|
137
|
+
|
|
138
|
+
## Further Reading
|
|
139
|
+
|
|
140
|
+
- [Getting Started](https://yurukusa.github.io/cc-safe-setup/getting-started.html)
|
|
141
|
+
- [Common Mistakes](https://yurukusa.github.io/cc-safe-setup/common-mistakes.html)
|
|
142
|
+
- [Troubleshooting](TROUBLESHOOTING.md)
|
|
143
|
+
- [Settings Reference](SETTINGS_REFERENCE.md)
|
package/README.md
CHANGED
|
@@ -356,6 +356,7 @@ See [Issue #1](https://github.com/yurukusa/cc-safe-setup/issues/1) for details.
|
|
|
356
356
|
|
|
357
357
|
## Learn More
|
|
358
358
|
|
|
359
|
+
- [Cookbook](COOKBOOK.md) — 26 practical recipes (block, approve, protect, monitor, diagnose)
|
|
359
360
|
- [Official Hooks Reference](https://docs.anthropic.com/en/docs/claude-code/hooks) — Claude Code hooks documentation
|
|
360
361
|
- [Hooks Cookbook](https://github.com/yurukusa/claude-code-hooks/blob/main/COOKBOOK.md) — 25 recipes from real GitHub Issues ([interactive version](https://yurukusa.github.io/claude-code-hooks/))
|
|
361
362
|
- [Japanese guide (Qiita)](https://qiita.com/yurukusa/items/a9714b33f5d974e8f1e8) — この記事の日本語解説
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
COMMAND=$(cat | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$COMMAND" ] && exit 0
|
|
3
4
|
if echo "$COMMAND" | grep -qE '^\s*(npm\s+test|npm\s+run\s+test|npx\s+(jest|vitest|mocha|ava|tap|playwright\s+test|cypress\s+run)|yarn\s+test|pnpm\s+test|bun\s+test)\b'; then
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ================================================================
|
|
3
|
+
# auto-compact-prep.sh — Save checkpoint before context compaction
|
|
4
|
+
# ================================================================
|
|
5
|
+
# PURPOSE:
|
|
6
|
+
# Tracks tool call count per session. When threshold is reached,
|
|
7
|
+
# saves a checkpoint file with git state so Claude can recover
|
|
8
|
+
# context after automatic compaction.
|
|
9
|
+
#
|
|
10
|
+
# TRIGGER: PreToolUse MATCHER: ""
|
|
11
|
+
#
|
|
12
|
+
# CONFIG:
|
|
13
|
+
# CC_COMPACT_PREP_THRESHOLD=200 (save checkpoint after N tool calls)
|
|
14
|
+
# ================================================================
|
|
15
|
+
|
|
1
16
|
INPUT=$(cat)
|
|
2
17
|
STATE_DIR="${HOME}/.claude"
|
|
3
18
|
COUNTER_FILE="${STATE_DIR}/session-call-count"
|
|
@@ -5,15 +20,11 @@ PREP_FLAG="${STATE_DIR}/compact-prep-done"
|
|
|
5
20
|
CHECKPOINT=".claude/pre-compact-checkpoint.md"
|
|
6
21
|
COUNT=0
|
|
7
22
|
[ -f "$COUNTER_FILE" ] && COUNT=$(cat "$COUNTER_FILE" 2>/dev/null || echo 0)
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
else
|
|
12
|
-
COUNT=$((COUNT + 1))
|
|
13
|
-
echo "$COUNT" > "$COUNTER_FILE"
|
|
14
|
-
fi
|
|
23
|
+
COUNT=$((COUNT + 1))
|
|
24
|
+
echo "$COUNT" > "$COUNTER_FILE"
|
|
25
|
+
|
|
15
26
|
THRESHOLD=${CC_COMPACT_PREP_THRESHOLD:-200}
|
|
16
|
-
if
|
|
27
|
+
if [ "$COUNT" -ge "$THRESHOLD" ] && [ ! -f "$PREP_FLAG" ]; then
|
|
17
28
|
mkdir -p "$(dirname "$CHECKPOINT")" 2>/dev/null
|
|
18
29
|
BRANCH=$(git branch --show-current 2>/dev/null || echo "?")
|
|
19
30
|
DIRTY=$(git status --porcelain 2>/dev/null | wc -l)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$CONTENT" ] && exit 0
|
|
3
4
|
echo "$CONTENT" | grep -qE "<(button|a|input)[^>]*>" && ! echo "$CONTENT" | grep -q "aria-" && echo "NOTE: Interactive element without ARIA" >&2
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$CONTENT" ] && exit 0
|
|
3
4
|
echo "$CONTENT" | grep -qE "setCookie|res\.cookie" && ! echo "$CONTENT" | grep -q "secure" && echo "NOTE: Cookie without secure flag" >&2
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$CONTENT" ] && exit 0
|
|
3
4
|
echo "$CONTENT" | grep -qE "Content-Security-Policy" || (echo "$CONTENT" | grep -q "helmet" && echo "NOTE: Consider adding CSP headers" >&2)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$CONTENT" ] && exit 0
|
|
3
4
|
echo "$CONTENT" | grep -qE "<form.*method.*POST" && ! echo "$CONTENT" | grep -qE "csrf|_token|csrfmiddleware" && echo "NOTE: Form without CSRF protection" >&2
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$CONTENT" ] && exit 0
|
|
3
4
|
COMMAND=$(cat | jq -r ".tool_input.command // empty" 2>/dev/null); echo "$COMMAND" | grep -qE "npm\s+install\s+\w" && echo "NOTE: Check dependency license before adding" >&2
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$CONTENT" ] && exit 0
|
|
3
4
|
echo "$CONTENT" | grep -qE "class.*extends.*Component|function.*\(\)" && echo "$CONTENT" | grep -q "render" && ! echo "$CONTENT" | grep -q "ErrorBoundary" && echo "NOTE: Consider adding ErrorBoundary" >&2
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$CONTENT" ] && exit 0
|
|
3
4
|
echo "$CONTENT" | grep -qE "throw new Error\(['\"](error|Error|something went wrong)" && echo "NOTE: Generic error message — be specific" >&2
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
# TRIGGER: PreToolUse MATCHER: "Bash"
|
|
2
3
|
COMMAND=$(cat | jq -r ".tool_input.command // empty" 2>/dev/null)
|
|
3
4
|
echo "$COMMAND" | grep -qE "git\s+add.*\.(zip|tar|bin|exe)" && [ ! -f ".gitattributes" ] && echo "NOTE: Binary file without .gitattributes LFS config" >&2
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$CONTENT" ] && exit 0
|
|
3
4
|
echo "$CONTENT" | grep -qE "http://" && echo "$CONTENT" | grep -q "redirect" && ! echo "$CONTENT" | grep -q "https" && echo "NOTE: HTTP redirect without HTTPS" >&2
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$CONTENT" ] && exit 0
|
|
3
4
|
echo "$CONTENT" | grep -qE "req\.(body|query|params)\.\w+" && ! echo "$CONTENT" | grep -qE "validate|sanitize|Joi|zod|yup" && echo "NOTE: User input without validation" >&2
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$CONTENT" ] && exit 0
|
|
3
4
|
FILE=$(cat | jq -r ".tool_input.file_path // empty" 2>/dev/null); case "$FILE" in *package.json) ;; *) exit 0;; esac; echo "$CONTENT" | grep -qE "npm run [a-z]+" && echo "NOTE: Verify referenced npm scripts exist" >&2
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$CONTENT" ] && exit 0
|
|
3
4
|
COMMAND=$(cat | jq -r ".tool_input.command // empty" 2>/dev/null); echo "$COMMAND" | grep -qE "listen\(|--port|:3000|:8080" && echo "NOTE: Check port availability before starting server" >&2
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$CONTENT" ] && exit 0
|
|
3
4
|
echo "$CONTENT" | grep -qE "app\.(get|post|put|delete)\(" && ! echo "$CONTENT" | grep -q "rateLimit" && echo "NOTE: API endpoint without rate limiting" >&2
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$CONTENT" ] && exit 0
|
|
3
4
|
echo "$CONTENT" | grep -qE "function\s+\w+\([^)]*\)\s*{" && ! echo "$CONTENT" | grep -q ": " && echo "NOTE: Missing return type annotation" >&2
|
package/examples/edit-verify.sh
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$CONTENT" ] && exit 0
|
|
3
4
|
echo "$CONTENT" | grep -qE "process\.env\.\w+\s*\|\|" || echo "$CONTENT" | grep -qE "process\.env\.\w+!" && echo "NOTE: Env var without default — add fallback" >&2
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
COMMAND=$(cat | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$COMMAND" ] && exit 0
|
|
3
4
|
echo "$COMMAND" | grep -qE "git\s+commit\s+-m" || exit 0; MSG=$(echo "$COMMAND" | grep -oP "(?<=-m\s[\x27\x22])[^\x27\x22]+"); [ ${#MSG} -lt 10 ] && echo "WARNING: Commit message too short (${#MSG} chars)" >&2
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
COMMAND=$(cat | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$COMMAND" ] && exit 0
|
|
3
4
|
if echo "$COMMAND" | grep -qE "^\s*rm\b"; then COUNT=$(echo "$COMMAND" | tr " " "\n" | grep -cvE "^-" | head -1); [ "$COUNT" -gt 5 ] && echo "WARNING: Deleting $COUNT files at once" >&2; fi
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$CONTENT" ] && exit 0
|
|
3
4
|
IMPORTS=$(echo "$CONTENT" | grep -cE "^(import|from|require)" || echo 0); [ "$IMPORTS" -gt 20 ] && echo "NOTE: $IMPORTS imports — consider splitting module" >&2
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
COMMAND=$(cat | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$COMMAND" ] && exit 0
|
|
3
4
|
STATE="/tmp/cc-subagent-count"; C=$(cat "$STATE" 2>/dev/null || echo 0); echo $((C+1)) > "$STATE"; [ "$C" -gt 5 ] && echo "WARNING: $C subagents spawned this session" >&2
|
package/examples/no-any-type.sh
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$CONTENT" ] && exit 0
|
|
3
4
|
echo "$CONTENT" | grep -qE "localStorage\.setItem.*password|sessionStorage.*token" && echo "WARNING: Storing secrets in browser storage" >&2
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$CONTENT" ] && exit 0
|
|
3
4
|
COMMENTED=$(echo "$CONTENT" | grep -cE "^\s*(//|#)\s*(if|for|while|function|const|let|var|import|class)" || echo 0); [ "$COMMENTED" -gt 5 ] && echo "NOTE: Large block of commented code — delete or uncomment" >&2
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/bin/bash
|
|
1
2
|
CONTENT=$(cat | jq -r '.tool_input.new_string // .tool_input.content // empty' 2>/dev/null)
|
|
2
3
|
[ -z "$CONTENT" ] && exit 0
|
|
3
4
|
if echo "$CONTENT" | grep -qE "catch\s*\([^)]*\)\s*\{[\s\n]*\}|except:[\s\n]*pass"; then echo "WARNING: Empty catch/except block swallows errors" >&2; fi
|