@oneie/claude 0.3.1 → 0.3.2
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/hooks/hooks.json +14 -0
- package/hooks/scripts/compact-hint.sh +36 -0
- package/hooks/scripts/config-protect.sh +56 -0
- package/package.json +1 -1
package/hooks/hooks.json
CHANGED
|
@@ -9,6 +9,20 @@
|
|
|
9
9
|
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/gate-guard.sh\"",
|
|
10
10
|
"timeout": 5000,
|
|
11
11
|
"blocking": true
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"id": "hook:config-protect",
|
|
15
|
+
"type": "command",
|
|
16
|
+
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/config-protect.sh\"",
|
|
17
|
+
"timeout": 5000,
|
|
18
|
+
"blocking": true
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "hook:compact-hint",
|
|
22
|
+
"type": "command",
|
|
23
|
+
"command": "bash \"$CLAUDE_PLUGIN_ROOT/hooks/scripts/compact-hint.sh\"",
|
|
24
|
+
"timeout": 3000,
|
|
25
|
+
"blocking": false
|
|
12
26
|
}
|
|
13
27
|
]
|
|
14
28
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# COMPACT-HINT — PreToolUse: suggest /compact when context is large.
|
|
3
|
+
#
|
|
4
|
+
# Non-blocking — writes one line to stderr, fires at most once per session.
|
|
5
|
+
# Threshold: 400KB transcript (~80-120k tokens depending on content density).
|
|
6
|
+
#
|
|
7
|
+
# Disable: ECC_DISABLED_HOOKS=hook:compact-hint
|
|
8
|
+
|
|
9
|
+
# shellcheck source=lib/hook.sh
|
|
10
|
+
_HOOK_LIB="${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR/.claude}/hooks/lib"
|
|
11
|
+
source "$_HOOK_LIB/hook.sh"
|
|
12
|
+
is_hook_disabled "hook:compact-hint" && exit 0
|
|
13
|
+
|
|
14
|
+
PAYLOAD="${1:-}"
|
|
15
|
+
[[ -z "$PAYLOAD" ]] && exit 0
|
|
16
|
+
|
|
17
|
+
# Locate the transcript — from hook JSON or env var (Claude Code sets both)
|
|
18
|
+
TRANSCRIPT=$(printf '%s' "$PAYLOAD" | jq -r '.transcript_path // .transcriptPath // empty' 2>/dev/null)
|
|
19
|
+
[[ -z "$TRANSCRIPT" ]] && TRANSCRIPT="${CLAUDE_TRANSCRIPT_PATH:-}"
|
|
20
|
+
[[ -z "$TRANSCRIPT" || ! -f "$TRANSCRIPT" ]] && exit 0
|
|
21
|
+
|
|
22
|
+
SIZE=$(wc -c < "$TRANSCRIPT" 2>/dev/null | tr -d ' ')
|
|
23
|
+
[[ -z "$SIZE" || "$SIZE" -lt 400000 ]] && exit 0
|
|
24
|
+
|
|
25
|
+
# Fire at most once per session
|
|
26
|
+
SESSION_KEY=$(hook_session_key "$PAYLOAD")
|
|
27
|
+
FLAG="/tmp/oneie-compact-hint-${SESSION_KEY}"
|
|
28
|
+
[[ -f "$FLAG" ]] && exit 0
|
|
29
|
+
touch "$FLAG"
|
|
30
|
+
|
|
31
|
+
SIZE_KB=$(( SIZE / 1024 ))
|
|
32
|
+
echo "" >&2
|
|
33
|
+
echo "⚡ Context is ~${SIZE_KB}KB — run /compact before the next big edit to keep responses fast and cheap." >&2
|
|
34
|
+
echo "" >&2
|
|
35
|
+
|
|
36
|
+
exit 0
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# CONFIG-PROTECT — PreToolUse(Edit|Write): block lint/type config weakening.
|
|
3
|
+
#
|
|
4
|
+
# Prevents introducing "off"/"warn" rules or disabling strict flags in
|
|
5
|
+
# biome.json, tsconfig*.json, or .eslintrc* files.
|
|
6
|
+
#
|
|
7
|
+
# Why: W4 verify uses biome + tsc as hard gates. Weakening the config
|
|
8
|
+
# is equivalent to deleting the gate. Fix the code — not the rules.
|
|
9
|
+
# If a rule genuinely needs changing, explain it in the PR description.
|
|
10
|
+
#
|
|
11
|
+
# Disable: ECC_DISABLED_HOOKS=hook:config-protect
|
|
12
|
+
|
|
13
|
+
# shellcheck source=lib/hook.sh
|
|
14
|
+
_HOOK_LIB="${CLAUDE_PLUGIN_ROOT:-$CLAUDE_PROJECT_DIR/.claude}/hooks/lib"
|
|
15
|
+
source "$_HOOK_LIB/hook.sh"
|
|
16
|
+
is_hook_disabled "hook:config-protect" && exit 0
|
|
17
|
+
|
|
18
|
+
PAYLOAD="${1:-}"
|
|
19
|
+
[[ -z "$PAYLOAD" ]] && exit 0
|
|
20
|
+
|
|
21
|
+
TOOL=$(printf '%s' "$PAYLOAD" | jq -r '.tool_name // empty' 2>/dev/null)
|
|
22
|
+
case "$TOOL" in Edit|Write) ;; *) exit 0 ;; esac
|
|
23
|
+
|
|
24
|
+
FILE=$(printf '%s' "$PAYLOAD" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
|
|
25
|
+
[[ -z "$FILE" ]] && exit 0
|
|
26
|
+
|
|
27
|
+
# Only gate known config files
|
|
28
|
+
case "$(basename "$FILE")" in
|
|
29
|
+
biome.json|biome.*.json|\
|
|
30
|
+
tsconfig.json|tsconfig.*.json|\
|
|
31
|
+
.eslintrc|.eslintrc.json|.eslintrc.js|.eslintrc.cjs|.eslintrc.mjs) ;;
|
|
32
|
+
*) exit 0 ;;
|
|
33
|
+
esac
|
|
34
|
+
|
|
35
|
+
# For Edit: compare old_string vs new_string — block only if weakening is NEW.
|
|
36
|
+
# For Write: check the whole content.
|
|
37
|
+
if [[ "$TOOL" == "Edit" ]]; then
|
|
38
|
+
OLD=$(printf '%s' "$PAYLOAD" | jq -r '.tool_input.old_string // empty' 2>/dev/null)
|
|
39
|
+
NEW=$(printf '%s' "$PAYLOAD" | jq -r '.tool_input.new_string // empty' 2>/dev/null)
|
|
40
|
+
[[ -z "$NEW" ]] && exit 0
|
|
41
|
+
# Only block if the weakening pattern appears in NEW but not in OLD
|
|
42
|
+
_has_weakening() { printf '%s' "$1" | grep -qE '"(off|warn)"|"noErrors":\s*true|"strict":\s*false|"skipLibCheck":\s*true|"noUnusedLocals":\s*false|"noImplicitAny":\s*false|"allowJs":\s*true'; }
|
|
43
|
+
_has_weakening "$OLD" && exit 0 # already present — not introducing it
|
|
44
|
+
_has_weakening "$NEW" || exit 0 # not in new content — safe
|
|
45
|
+
else
|
|
46
|
+
# Write: check full content
|
|
47
|
+
CONTENT=$(printf '%s' "$PAYLOAD" | jq -r '.tool_input.content // empty' 2>/dev/null)
|
|
48
|
+
[[ -z "$CONTENT" ]] && exit 0
|
|
49
|
+
printf '%s' "$CONTENT" | grep -qE '"(off|warn)"|"noErrors":\s*true|"strict":\s*false|"skipLibCheck":\s*true|"noUnusedLocals":\s*false|"noImplicitAny":\s*false|"allowJs":\s*true' || exit 0
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
FNAME=$(basename "$FILE")
|
|
53
|
+
printf '%s' "$(jq -nc --arg f "$FNAME" --arg path "$FILE" \
|
|
54
|
+
'{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":
|
|
55
|
+
("[Config-Guard] Weakening \($f) is not allowed.\n\nW4 verify uses biome + tsc as hard gates — disabling rules deletes the gate.\nFix the code, not the config.\n\nIf this change is genuinely intentional, explain it in the PR description, then\ndisable for this session: ECC_DISABLED_HOOKS=hook:config-protect")}}')"
|
|
56
|
+
exit 0
|