oh-my-customcode 1.1.55 → 1.1.57

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.
Files changed (42) hide show
  1. package/dist/cli/index.js +5 -1
  2. package/dist/index.js +5 -1
  3. package/package.json +1 -1
  4. package/templates/.claude/hooks/hooks.json +21 -21
  5. package/templates/.claude/hooks/scripts/agent-start-recorder.sh +5 -5
  6. package/templates/.claude/hooks/scripts/agent-teams-advisor.sh +4 -4
  7. package/templates/.claude/hooks/scripts/audit-log.sh +6 -6
  8. package/templates/.claude/hooks/scripts/auto-continue-guard.sh +1 -1
  9. package/templates/.claude/hooks/scripts/auto-dev-token-summary.sh +6 -6
  10. package/templates/.claude/hooks/scripts/auto-dev-token-tracker.sh +6 -6
  11. package/templates/.claude/hooks/scripts/claude-md-reinject.sh +9 -4
  12. package/templates/.claude/hooks/scripts/content-hash-validator.sh +4 -4
  13. package/templates/.claude/hooks/scripts/context-budget-advisor.sh +3 -3
  14. package/templates/.claude/hooks/scripts/cost-cap-advisor.sh +6 -6
  15. package/templates/.claude/hooks/scripts/cwd-change-detector.sh +3 -3
  16. package/templates/.claude/hooks/scripts/destructive-git-guard.sh +2 -2
  17. package/templates/.claude/hooks/scripts/eval-core-batch-save.sh +2 -2
  18. package/templates/.claude/hooks/scripts/feedback-collector.sh +7 -7
  19. package/templates/.claude/hooks/scripts/file-change-validator.sh +4 -4
  20. package/templates/.claude/hooks/scripts/git-delegation-guard.sh +3 -3
  21. package/templates/.claude/hooks/scripts/model-escalation-advisor.sh +4 -4
  22. package/templates/.claude/hooks/scripts/omcustom-auto-update.sh +6 -6
  23. package/templates/.claude/hooks/scripts/playwright-compress.sh +4 -4
  24. package/templates/.claude/hooks/scripts/plugin-cache-check.sh +2 -2
  25. package/templates/.claude/hooks/scripts/rtk-intercept.sh +9 -9
  26. package/templates/.claude/hooks/scripts/rule-deletion-guard.sh +5 -5
  27. package/templates/.claude/hooks/scripts/schema-validator.sh +10 -10
  28. package/templates/.claude/hooks/scripts/secret-filter.sh +4 -4
  29. package/templates/.claude/hooks/scripts/session-autofix-prompt.sh +3 -3
  30. package/templates/.claude/hooks/scripts/session-autofix.sh +1 -1
  31. package/templates/.claude/hooks/scripts/session-env-check.sh +1 -1
  32. package/templates/.claude/hooks/scripts/session-reflection.sh +15 -15
  33. package/templates/.claude/hooks/scripts/skill-extractor-analyzer.sh +2 -2
  34. package/templates/.claude/hooks/scripts/stale-todo-scanner.sh +1 -1
  35. package/templates/.claude/hooks/scripts/stall-detection-advisor.sh +11 -11
  36. package/templates/.claude/hooks/scripts/stop-console-audit.sh +1 -1
  37. package/templates/.claude/hooks/scripts/stuck-detector.sh +5 -5
  38. package/templates/.claude/hooks/scripts/subagent-failure-advisor.sh +36 -0
  39. package/templates/.claude/hooks/scripts/task-outcome-recorder.sh +8 -8
  40. package/templates/.claude/hooks/scripts/task-state-precompact.sh +1 -1
  41. package/templates/.claude/settings.json +21 -21
  42. package/templates/manifest.json +1 -1
@@ -0,0 +1,36 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+
4
+ # Dependency check: exit silently if jq not available
5
+ command -v jq >/dev/null 2>&1 || exit 0
6
+
7
+ # Subagent Failure Advisor Hook
8
+ # Trigger: SubagentStop
9
+ # Purpose: Advisory-only replacement for the removed `type: "prompt"` SubagentStop hook
10
+ # (#1631). The prompt hook asked an LLM judge whether the CURRENT session's own
11
+ # background_tasks entry had transitioned to "completed" before allowing Stop —
12
+ # but that transition only happens AFTER the SubagentStop hook chain resolves, so the
13
+ # judgment was structurally always "not yet completed" for a subagent evaluating its
14
+ # OWN stop. That produced a self-referential `Stop hook feedback:` re-injection loop
15
+ # with no dedup, observed to repeat 8-10x per session before manual override.
16
+ # Fix: replace the blocking LLM judge with a plain stderr-only warning that never
17
+ # triggers the Stop-hook-feedback re-injection path. No block, no LLM call, no loop.
18
+ # Protocol: stdin JSON -> read tool_output.is_error -> stderr warning if failed -> pass through -> exit 0 (always)
19
+
20
+ input=$(cat)
21
+
22
+ is_error=$(printf '%s\n' "$input" | jq -r '.tool_output.is_error // false' 2>/dev/null || echo "false")
23
+
24
+ if [ "$is_error" = "true" ]; then
25
+ agent_type=$(printf '%s\n' "$input" | jq -r '.tool_input.subagent_type // .agent_type // "unknown"' 2>/dev/null || echo "unknown")
26
+ error_summary=$(printf '%s\n' "$input" | jq -r '.tool_output.output // ""' 2>/dev/null | head -c 200)
27
+ echo "" >&2
28
+ echo "--- [Subagent Failure Advisor] background subagent (${agent_type}) reported an error ---" >&2
29
+ echo " ${error_summary}" >&2
30
+ echo " If it FAILED, do NOT auto-continue -- report the failure and wait for user input." >&2
31
+ echo "-----------------------------------------------------------------------------------" >&2
32
+ fi
33
+
34
+ # Always pass through -- advisory only, never blocks, never triggers Stop hook feedback re-injection
35
+ printf '%s\n' "$input"
36
+ exit 0
@@ -12,9 +12,9 @@ command -v jq >/dev/null 2>&1 || exit 0
12
12
  input=$(cat)
13
13
 
14
14
  # Extract task info — support both PostToolUse (tool_input.*) and SubagentStop (top-level) shapes
15
- agent_type=$(echo "$input" | jq -r '.tool_input.subagent_type // .agent_type // "unknown"')
16
- model=$(echo "$input" | jq -r '.tool_input.model // .model // "inherit"')
17
- description=$(echo "$input" | jq -r '.tool_input.description // .description // ""' | head -c 80)
15
+ agent_type=$(printf '%s\n' "$input" | jq -r '.tool_input.subagent_type // .agent_type // "unknown"')
16
+ model=$(printf '%s\n' "$input" | jq -r '.tool_input.model // .model // "inherit"')
17
+ description=$(printf '%s\n' "$input" | jq -r '.tool_input.description // .description // ""' | head -c 80)
18
18
 
19
19
  # Extract skill name from description or prompt
20
20
  skill_name=""
@@ -23,16 +23,16 @@ if echo "$description" | grep -qiE '(skill:|routing|→.*skill)'; then
23
23
  fi
24
24
  # Fallback: check prompt field for "Skill: {name}" pattern
25
25
  if [ -z "$skill_name" ]; then
26
- prompt=$(echo "$input" | jq -r '.tool_input.prompt // ""' | head -c 500)
26
+ prompt=$(printf '%s\n' "$input" | jq -r '.tool_input.prompt // ""' | head -c 500)
27
27
  skill_name=$(echo "$prompt" | grep -oiE 'Skill:\s*[a-z]+-[a-z]+(-[a-z]+)*' | sed 's/[Ss]kill:\s*//' | head -1)
28
28
  fi
29
29
 
30
30
  # Determine outcome
31
- is_error=$(echo "$input" | jq -r '.tool_output.is_error // false')
31
+ is_error=$(printf '%s\n' "$input" | jq -r '.tool_output.is_error // false')
32
32
 
33
33
  if [ "$is_error" = "true" ]; then
34
34
  outcome="failure"
35
- error_summary=$(echo "$input" | jq -r '.tool_output.output // ""' | head -c 200)
35
+ error_summary=$(printf '%s\n' "$input" | jq -r '.tool_output.output // ""' | head -c 200)
36
36
  else
37
37
  outcome="success"
38
38
  error_summary=""
@@ -94,7 +94,7 @@ entry=$(jq -n \
94
94
  --arg dur "$duration_seconds" \
95
95
  '{timestamp: $ts, agent_type: $agent, model: $model, outcome: $outcome, pattern_used: $pattern, skill: $skill, description: $desc, error_summary: $err, duration_seconds: ($dur | tonumber)}')
96
96
 
97
- echo "$entry" >> "$OUTCOME_FILE"
97
+ printf '%s\n' "$entry" >> "$OUTCOME_FILE"
98
98
 
99
99
  # Ring buffer: keep last 50 entries
100
100
  if [ -f "$OUTCOME_FILE" ]; then
@@ -115,5 +115,5 @@ if [ "$outcome" = "failure" ]; then
115
115
  fi
116
116
 
117
117
  # Pass through
118
- echo "$input"
118
+ printf '%s\n' "$input"
119
119
  exit 0
@@ -49,7 +49,7 @@ collect_state() {
49
49
  state=$(collect_state 2>/dev/null)
50
50
 
51
51
  if [ -n "$state" ] && [ "$state" != "{}" ]; then
52
- echo "$state" > "$STATE_FILE"
52
+ printf '%s\n' "$state" > "$STATE_FILE"
53
53
  echo "[PreCompact] Task state saved to $STATE_FILE" >&2
54
54
  else
55
55
  echo "[PreCompact] No active task state to save" >&2
@@ -18,7 +18,7 @@
18
18
  "hooks": [
19
19
  {
20
20
  "type": "command",
21
- "command": "input=$(cat)\nif printf '%s' \"$input\" | jq -e '((.tool_input.command // \"\") | test(\"(npm run dev|pnpm( run)? dev|yarn dev|bun run dev)\"))' >/dev/null 2>&1; then\n printf '%s' \"$input\" | (\n#!/bin/bash\ninput=$(cat)\ncmd=$(echo \"$input\" | jq -r '.tool_input.command // \"\"')\n\n# Block dev servers that aren't run in tmux\necho '[Hook] BLOCKED: Dev server must run in tmux for log access' >&2\necho '[Hook] Use this command instead:' >&2\necho \"[Hook] tmux new-session -d -s dev 'npm run dev'\" >&2\necho '[Hook] Then: tmux attach -t dev' >&2\nexit 1\n )\nelse\n printf '%s' \"$input\"\nfi"
21
+ "command": "input=$(cat)\nif printf '%s' \"$input\" | jq -e '((.tool_input.command // \"\") | test(\"(npm run dev|pnpm( run)? dev|yarn dev|bun run dev)\"))' >/dev/null 2>&1; then\n printf '%s' \"$input\" | (\n#!/bin/bash\ninput=$(cat)\ncmd=$(printf '%s\\n' \"$input\" | jq -r '.tool_input.command // \"\"')\n\n# Block dev servers that aren't run in tmux\necho '[Hook] BLOCKED: Dev server must run in tmux for log access' >&2\necho '[Hook] Use this command instead:' >&2\necho \"[Hook] tmux new-session -d -s dev 'npm run dev'\" >&2\necho '[Hook] Then: tmux attach -t dev' >&2\nexit 1\n )\nelse\n printf '%s' \"$input\"\nfi"
22
22
  }
23
23
  ],
24
24
  "matcher": "Bash",
@@ -28,7 +28,7 @@
28
28
  "hooks": [
29
29
  {
30
30
  "type": "command",
31
- "command": "input=$(cat)\nif printf '%s' \"$input\" | jq -e '((.tool_input.command // \"\") | test(\"(npm (install|test)|pnpm (install|test)|yarn (install|test)|bun (install|test)|cargo build|make|docker|pytest|vitest|playwright)\"))' >/dev/null 2>&1; then\n printf '%s' \"$input\" | (\n#!/bin/bash\ninput=$(cat)\nif [ -z \"$TMUX\" ]; then\n echo '[Hook] Consider running in tmux for session persistence' >&2\n echo '[Hook] tmux new -s dev | tmux attach -t dev' >&2\nfi\necho \"$input\"\n )\nelse\n printf '%s' \"$input\"\nfi"
31
+ "command": "input=$(cat)\nif printf '%s' \"$input\" | jq -e '((.tool_input.command // \"\") | test(\"(npm (install|test)|pnpm (install|test)|yarn (install|test)|bun (install|test)|cargo build|make|docker|pytest|vitest|playwright)\"))' >/dev/null 2>&1; then\n printf '%s' \"$input\" | (\n#!/bin/bash\ninput=$(cat)\nif [ -z \"$TMUX\" ]; then\n echo '[Hook] Consider running in tmux for session persistence' >&2\n echo '[Hook] tmux new -s dev | tmux attach -t dev' >&2\nfi\nprintf '%s\\n' \"$input\"\n )\nelse\n printf '%s' \"$input\"\nfi"
32
32
  }
33
33
  ],
34
34
  "matcher": "Bash",
@@ -48,7 +48,7 @@
48
48
  "hooks": [
49
49
  {
50
50
  "type": "command",
51
- "command": "#!/bin/bash\ninput=$(cat)\nfile_path=$(echo \"$input\" | jq -r '.tool_input.file_path // \"\"')\n\nif [[ \"$file_path\" =~ \\.(md|txt)$ ]] && [[ ! \"$file_path\" =~ (README|CLAUDE|AGENT|SKILL)\\.md$ ]]; then\n echo \"[Hook] BLOCKED: Unnecessary documentation file creation\" >&2\n echo \"[Hook] File: $file_path\" >&2\n echo \"[Hook] Use README.md or AGENT.md for documentation instead\" >&2\n exit 1\nfi\n\necho \"$input\""
51
+ "command": "#!/bin/bash\ninput=$(cat)\nfile_path=$(printf '%s\\n' \"$input\" | jq -r '.tool_input.file_path // \"\"')\n\nif [[ \"$file_path\" =~ \\.(md|txt)$ ]] && [[ ! \"$file_path\" =~ (README|CLAUDE|AGENT|SKILL)\\.md$ ]]; then\n echo \"[Hook] BLOCKED: Unnecessary documentation file creation\" >&2\n echo \"[Hook] File: $file_path\" >&2\n echo \"[Hook] Use README.md or AGENT.md for documentation instead\" >&2\n exit 1\nfi\n\nprintf '%s\\n' \"$input\""
52
52
  }
53
53
  ],
54
54
  "matcher": "Write",
@@ -118,7 +118,7 @@
118
118
  "hooks": [
119
119
  {
120
120
  "type": "command",
121
- "command": "#!/bin/bash\ninput=$(cat)\nagent_type=$(echo \"$input\" | jq -r '.tool_input.subagent_type // \"unknown\"')\nmodel=$(echo \"$input\" | jq -r '.tool_input.model // \"inherit\"')\ndesc=$(echo \"$input\" | jq -r '.tool_input.description // \"\"' | head -c 40)\nresume=$(echo \"$input\" | jq -r '.tool_input.resume // empty')\nif [ -n \"$resume\" ]; then\n echo \"─── [Resume] ${agent_type}:${model} | ${desc} ───\" >&2\nelse\n echo \"─── [Spawn] ${agent_type}:${model} | ${desc} ───\" >&2\nfi\necho \"$input\""
121
+ "command": "#!/bin/bash\ninput=$(cat)\nagent_type=$(printf '%s\\n' \"$input\" | jq -r '.tool_input.subagent_type // \"unknown\"')\nmodel=$(printf '%s\\n' \"$input\" | jq -r '.tool_input.model // \"inherit\"')\ndesc=$(printf '%s\\n' \"$input\" | jq -r '.tool_input.description // \"\"' | head -c 40)\nresume=$(printf '%s\\n' \"$input\" | jq -r '.tool_input.resume // empty')\nif [ -n \"$resume\" ]; then\n echo \"─── [Resume] ${agent_type}:${model} | ${desc} ───\" >&2\nelse\n echo \"─── [Spawn] ${agent_type}:${model} | ${desc} ───\" >&2\nfi\nprintf '%s\\n' \"$input\""
122
122
  },
123
123
  {
124
124
  "type": "command",
@@ -205,8 +205,8 @@
205
205
  "command": "bash .claude/hooks/scripts/claude-md-reinject.sh"
206
206
  }
207
207
  ],
208
- "matcher": "*",
209
- "description": "Re-inject project CLAUDE.md into model context on session start/resume/clear and compact re-entry — matcher \"*\" covers all SessionStart sources including \"compact\" (#1617)"
208
+ "matcher": "compact",
209
+ "description": "Re-inject project CLAUDE.md into model context on compact re-entry only — CC already natively auto-loads CLAUDE.md on startup/resume/clear, so re-injecting there is pure duplication (~13.8KB/session); matcher narrowed to \"compact\" to keep the original #1617 purpose (post-compact amnesia defense) without the startup double-injection (#1626)"
210
210
  }
211
211
  ],
212
212
  "UserPromptSubmit": [
@@ -256,7 +256,7 @@
256
256
  "hooks": [
257
257
  {
258
258
  "type": "command",
259
- "command": "#!/bin/bash\ninput=$(cat)\nagent_type=$(echo \"$input\" | jq -r '.agent_type // \"unknown\"')\nmodel=$(echo \"$input\" | jq -r '.model // \"inherit\"')\ndesc=$(echo \"$input\" | jq -r '.description // \"\"' | head -c 40)\necho \"─── [SubagentStart] ${agent_type}:${model} | ${desc} ───\" >&2\necho \"$input\""
259
+ "command": "#!/bin/bash\ninput=$(cat)\nagent_type=$(printf '%s\\n' \"$input\" | jq -r '.agent_type // \"unknown\"')\nmodel=$(printf '%s\\n' \"$input\" | jq -r '.model // \"inherit\"')\ndesc=$(printf '%s\\n' \"$input\" | jq -r '.description // \"\"' | head -c 40)\necho \"─── [SubagentStart] ${agent_type}:${model} | ${desc} ───\" >&2\nprintf '%s\\n' \"$input\""
260
260
  },
261
261
  {
262
262
  "type": "command",
@@ -287,12 +287,12 @@
287
287
  "command": "bash .claude/hooks/scripts/r007-r008-drift-advisor.sh"
288
288
  },
289
289
  {
290
- "type": "prompt",
291
- "prompt": "A background subagent just completed. If it FAILED, do NOT auto-continue — report the failure and wait for user input."
290
+ "type": "command",
291
+ "command": "bash .claude/hooks/scripts/subagent-failure-advisor.sh"
292
292
  }
293
293
  ],
294
294
  "matcher": "*",
295
- "description": "Record agent outcomes + auto-continue workflow + R007/R008 drift advisory on subagent completion (autonomous-loop re-entry, #1545)"
295
+ "description": "Record agent outcomes + auto-continue workflow + R007/R008 drift advisory + failure advisory on subagent completion (autonomous-loop re-entry, #1545; #1631 replaced the self-referential prompt-type judge hook with an advisory-only command hook)"
296
296
  }
297
297
  ],
298
298
  "CwdChanged": [
@@ -324,7 +324,7 @@
324
324
  "hooks": [
325
325
  {
326
326
  "type": "command",
327
- "command": "#!/bin/bash\ninput=$(cat)\nmsg=$(echo \"$input\" | jq -r '.message // \"\"' 2>/dev/null)\nif [ -n \"$msg\" ]; then\n echo \"[Hook] Notification: $msg\" >&2\nfi\necho \"$input\""
327
+ "command": "#!/bin/bash\ninput=$(cat)\nmsg=$(printf '%s\\n' \"$input\" | jq -r '.message // \"\"' 2>/dev/null)\nif [ -n \"$msg\" ]; then\n echo \"[Hook] Notification: $msg\" >&2\nfi\nprintf '%s\\n' \"$input\""
328
328
  }
329
329
  ],
330
330
  "matcher": "*",
@@ -336,7 +336,7 @@
336
336
  "hooks": [
337
337
  {
338
338
  "type": "command",
339
- "command": "#!/bin/bash\ninput=$(cat)\nteammate=$(echo \"$input\" | jq -r '.teammate_id // \"unknown\"' 2>/dev/null)\necho \"[Hook] TeammateIdle: $teammate — available for reassignment\" >&2\necho \"$input\""
339
+ "command": "#!/bin/bash\ninput=$(cat)\nteammate=$(printf '%s\\n' \"$input\" | jq -r '.teammate_id // \"unknown\"' 2>/dev/null)\necho \"[Hook] TeammateIdle: $teammate — available for reassignment\" >&2\nprintf '%s\\n' \"$input\""
340
340
  }
341
341
  ],
342
342
  "matcher": "*",
@@ -348,7 +348,7 @@
348
348
  "hooks": [
349
349
  {
350
350
  "type": "command",
351
- "command": "#!/bin/bash\ninput=$(cat)\ntask_id=$(echo \"$input\" | jq -r '.task_id // \"\"' 2>/dev/null)\ndesc=$(echo \"$input\" | jq -r '.description // \"\"' 2>/dev/null | head -c 60)\necho \"[Hook] TaskCreated: $task_id — $desc\" >&2\necho \"$input\""
351
+ "command": "#!/bin/bash\ninput=$(cat)\ntask_id=$(printf '%s\\n' \"$input\" | jq -r '.task_id // \"\"' 2>/dev/null)\ndesc=$(printf '%s\\n' \"$input\" | jq -r '.description // \"\"' 2>/dev/null | head -c 60)\necho \"[Hook] TaskCreated: $task_id — $desc\" >&2\nprintf '%s\\n' \"$input\""
352
352
  }
353
353
  ],
354
354
  "matcher": "*",
@@ -360,7 +360,7 @@
360
360
  "hooks": [
361
361
  {
362
362
  "type": "command",
363
- "command": "#!/bin/bash\ninput=$(cat)\ntask_id=$(echo \"$input\" | jq -r '.task_id // \"\"' 2>/dev/null)\nresult=$(echo \"$input\" | jq -r '.result // \"\"' 2>/dev/null | head -c 60)\necho \"[Hook] TaskCompleted: $task_id — $result\" >&2\necho \"$input\""
363
+ "command": "#!/bin/bash\ninput=$(cat)\ntask_id=$(printf '%s\\n' \"$input\" | jq -r '.task_id // \"\"' 2>/dev/null)\nresult=$(printf '%s\\n' \"$input\" | jq -r '.result // \"\"' 2>/dev/null | head -c 60)\necho \"[Hook] TaskCompleted: $task_id — $result\" >&2\nprintf '%s\\n' \"$input\""
364
364
  }
365
365
  ],
366
366
  "matcher": "*",
@@ -396,7 +396,7 @@
396
396
  "hooks": [
397
397
  {
398
398
  "type": "command",
399
- "command": "#!/bin/bash\ninput=$(cat)\ncmd=$(echo \"$input\" | jq -r '.tool_input.command')\n\nif echo \"$cmd\" | grep -qE 'gh pr create'; then\n output=$(echo \"$input\" | jq -r '.tool_output.output // \"\"')\n pr_url=$(echo \"$output\" | grep -oE 'https://github.com/[^/]+/[^/]+/pull/[0-9]+')\n \n if [ -n \"$pr_url\" ]; then\n echo \"[Hook] PR created: $pr_url\" >&2\n echo \"[Hook] Checking GitHub Actions status...\" >&2\n repo=$(echo \"$pr_url\" | sed -E 's|https://github.com/([^/]+/[^/]+)/pull/[0-9]+|\\1|')\n pr_num=$(echo \"$pr_url\" | sed -E 's|.*/pull/([0-9]+)|\\1|')\n echo \"[Hook] To review PR: gh pr review $pr_num --repo $repo\" >&2\n fi\nfi\n\necho \"$input\""
399
+ "command": "#!/bin/bash\ninput=$(cat)\ncmd=$(printf '%s\\n' \"$input\" | jq -r '.tool_input.command')\n\nif echo \"$cmd\" | grep -qE 'gh pr create'; then\n output=$(printf '%s\\n' \"$input\" | jq -r '.tool_output.output // \"\"')\n pr_url=$(echo \"$output\" | grep -oE 'https://github.com/[^/]+/[^/]+/pull/[0-9]+')\n \n if [ -n \"$pr_url\" ]; then\n echo \"[Hook] PR created: $pr_url\" >&2\n echo \"[Hook] Checking GitHub Actions status...\" >&2\n repo=$(echo \"$pr_url\" | sed -E 's|https://github.com/([^/]+/[^/]+)/pull/[0-9]+|\\1|')\n pr_num=$(echo \"$pr_url\" | sed -E 's|.*/pull/([0-9]+)|\\1|')\n echo \"[Hook] To review PR: gh pr review $pr_num --repo $repo\" >&2\n fi\nfi\n\nprintf '%s\\n' \"$input\""
400
400
  }
401
401
  ],
402
402
  "matcher": "Bash",
@@ -406,7 +406,7 @@
406
406
  "hooks": [
407
407
  {
408
408
  "type": "command",
409
- "command": "input=$(cat)\nif printf '%s' \"$input\" | jq -e '((.tool_input.file_path // \"\") | test(\"\\\\.(ts|tsx|js|jsx)$\"))' >/dev/null 2>&1; then\n printf '%s' \"$input\" | (\n#!/bin/bash\ninput=$(cat)\nfile_path=$(echo \"$input\" | jq -r '.tool_input.file_path // \"\"')\n\nif [ -n \"$file_path\" ] && [ -f \"$file_path\" ]; then\n if command -v prettier >/dev/null 2>&1; then\n prettier --write \"$file_path\" 2>&1 | head -5 >&2\n fi\nfi\n\necho \"$input\"\n )\nelse\n printf '%s' \"$input\"\nfi"
409
+ "command": "input=$(cat)\nif printf '%s' \"$input\" | jq -e '((.tool_input.file_path // \"\") | test(\"\\\\.(ts|tsx|js|jsx)$\"))' >/dev/null 2>&1; then\n printf '%s' \"$input\" | (\n#!/bin/bash\ninput=$(cat)\nfile_path=$(printf '%s\\n' \"$input\" | jq -r '.tool_input.file_path // \"\"')\n\nif [ -n \"$file_path\" ] && [ -f \"$file_path\" ]; then\n if command -v prettier >/dev/null 2>&1; then\n prettier --write \"$file_path\" 2>&1 | head -5 >&2\n fi\nfi\n\nprintf '%s\\n' \"$input\"\n )\nelse\n printf '%s' \"$input\"\nfi"
410
410
  }
411
411
  ],
412
412
  "matcher": "Edit",
@@ -416,7 +416,7 @@
416
416
  "hooks": [
417
417
  {
418
418
  "type": "command",
419
- "command": "input=$(cat)\nif printf '%s' \"$input\" | jq -e '((.tool_input.file_path // \"\") | test(\"\\\\.(ts|tsx)$\"))' >/dev/null 2>&1; then\n printf '%s' \"$input\" | (\n#!/bin/bash\ninput=$(cat)\nfile_path=$(echo \"$input\" | jq -r '.tool_input.file_path // \"\"')\n\nif [ -n \"$file_path\" ] && [ -f \"$file_path\" ]; then\n dir=$(dirname \"$file_path\")\n project_root=\"$dir\"\n while [ \"$project_root\" != \"/\" ] && [ ! -f \"$project_root/package.json\" ]; do\n project_root=$(dirname \"$project_root\")\n done\n \n if [ -f \"$project_root/tsconfig.json\" ]; then\n cd \"$project_root\" && npx tsc --noEmit --pretty false 2>&1 | grep \"$file_path\" | head -10 >&2 || true\n fi\nfi\n\necho \"$input\"\n )\nelse\n printf '%s' \"$input\"\nfi",
419
+ "command": "input=$(cat)\nif printf '%s' \"$input\" | jq -e '((.tool_input.file_path // \"\") | test(\"\\\\.(ts|tsx)$\"))' >/dev/null 2>&1; then\n printf '%s' \"$input\" | (\n#!/bin/bash\ninput=$(cat)\nfile_path=$(printf '%s\\n' \"$input\" | jq -r '.tool_input.file_path // \"\"')\n\nif [ -n \"$file_path\" ] && [ -f \"$file_path\" ]; then\n dir=$(dirname \"$file_path\")\n project_root=\"$dir\"\n while [ \"$project_root\" != \"/\" ] && [ ! -f \"$project_root/package.json\" ]; do\n project_root=$(dirname \"$project_root\")\n done\n \n if [ -f \"$project_root/tsconfig.json\" ]; then\n cd \"$project_root\" && npx tsc --noEmit --pretty false 2>&1 | grep \"$file_path\" | head -10 >&2 || true\n fi\nfi\n\nprintf '%s\\n' \"$input\"\n )\nelse\n printf '%s' \"$input\"\nfi",
420
420
  "continueOnBlock": true
421
421
  }
422
422
  ],
@@ -427,7 +427,7 @@
427
427
  "hooks": [
428
428
  {
429
429
  "type": "command",
430
- "command": "input=$(cat)\nif printf '%s' \"$input\" | jq -e '((.tool_input.file_path // \"\") | test(\"\\\\.(ts|tsx|js|jsx)$\"))' >/dev/null 2>&1; then\n printf '%s' \"$input\" | (\n#!/bin/bash\ninput=$(cat)\nfile_path=$(echo \"$input\" | jq -r '.tool_input.file_path // \"\"')\n\nif [ -n \"$file_path\" ] && [ -f \"$file_path\" ]; then\n console_logs=$(grep -n \"console\\\\.log\" \"$file_path\" 2>/dev/null || true)\n \n if [ -n \"$console_logs\" ]; then\n echo \"[Hook] WARNING: console.log found in $file_path\" >&2\n echo \"$console_logs\" | head -5 >&2\n echo \"[Hook] Remove console.log before committing\" >&2\n fi\nfi\n\necho \"$input\"\n )\nelse\n printf '%s' \"$input\"\nfi",
430
+ "command": "input=$(cat)\nif printf '%s' \"$input\" | jq -e '((.tool_input.file_path // \"\") | test(\"\\\\.(ts|tsx|js|jsx)$\"))' >/dev/null 2>&1; then\n printf '%s' \"$input\" | (\n#!/bin/bash\ninput=$(cat)\nfile_path=$(printf '%s\\n' \"$input\" | jq -r '.tool_input.file_path // \"\"')\n\nif [ -n \"$file_path\" ] && [ -f \"$file_path\" ]; then\n console_logs=$(grep -n \"console\\\\.log\" \"$file_path\" 2>/dev/null || true)\n \n if [ -n \"$console_logs\" ]; then\n echo \"[Hook] WARNING: console.log found in $file_path\" >&2\n echo \"$console_logs\" | head -5 >&2\n echo \"[Hook] Remove console.log before committing\" >&2\n fi\nfi\n\nprintf '%s\\n' \"$input\"\n )\nelse\n printf '%s' \"$input\"\nfi",
431
431
  "continueOnBlock": true
432
432
  }
433
433
  ],
@@ -438,7 +438,7 @@
438
438
  "hooks": [
439
439
  {
440
440
  "type": "command",
441
- "command": "input=$(cat)\nif printf '%s' \"$input\" | jq -e '((.tool_input.file_path // \"\") | test(\"\\\\.(go)$\"))' >/dev/null 2>&1; then\n printf '%s' \"$input\" | (\n#!/bin/bash\ninput=$(cat)\nfile_path=$(echo \"$input\" | jq -r '.tool_input.file_path // \"\"')\n\nif [ -n \"$file_path\" ] && [ -f \"$file_path\" ]; then\n if command -v gofmt >/dev/null 2>&1; then\n gofmt -w \"$file_path\" 2>&1 >&2\n fi\nfi\n\necho \"$input\"\n )\nelse\n printf '%s' \"$input\"\nfi"
441
+ "command": "input=$(cat)\nif printf '%s' \"$input\" | jq -e '((.tool_input.file_path // \"\") | test(\"\\\\.(go)$\"))' >/dev/null 2>&1; then\n printf '%s' \"$input\" | (\n#!/bin/bash\ninput=$(cat)\nfile_path=$(printf '%s\\n' \"$input\" | jq -r '.tool_input.file_path // \"\"')\n\nif [ -n \"$file_path\" ] && [ -f \"$file_path\" ]; then\n if command -v gofmt >/dev/null 2>&1; then\n gofmt -w \"$file_path\" 2>&1 >&2\n fi\nfi\n\nprintf '%s\\n' \"$input\"\n )\nelse\n printf '%s' \"$input\"\nfi"
442
442
  }
443
443
  ],
444
444
  "matcher": "Edit",
@@ -448,7 +448,7 @@
448
448
  "hooks": [
449
449
  {
450
450
  "type": "command",
451
- "command": "input=$(cat)\nif printf '%s' \"$input\" | jq -e '((.tool_input.file_path // \"\") | test(\"\\\\.(py)$\"))' >/dev/null 2>&1; then\n printf '%s' \"$input\" | (\n#!/bin/bash\ninput=$(cat)\nfile_path=$(echo \"$input\" | jq -r '.tool_input.file_path // \"\"')\n\nif [ -n \"$file_path\" ] && [ -f \"$file_path\" ]; then\n # Format with ruff\n if command -v ruff >/dev/null 2>&1; then\n ruff format --quiet \"$file_path\" 2>&1 >&2\n ruff check --fix --quiet \"$file_path\" 2>&1 >&2 || true\n echo \"[Hook] Python formatted with ruff\" >&2\n fi\nfi\n\necho \"$input\"\n )\nelse\n printf '%s' \"$input\"\nfi",
451
+ "command": "input=$(cat)\nif printf '%s' \"$input\" | jq -e '((.tool_input.file_path // \"\") | test(\"\\\\.(py)$\"))' >/dev/null 2>&1; then\n printf '%s' \"$input\" | (\n#!/bin/bash\ninput=$(cat)\nfile_path=$(printf '%s\\n' \"$input\" | jq -r '.tool_input.file_path // \"\"')\n\nif [ -n \"$file_path\" ] && [ -f \"$file_path\" ]; then\n # Format with ruff\n if command -v ruff >/dev/null 2>&1; then\n ruff format --quiet \"$file_path\" 2>&1 >&2\n ruff check --fix --quiet \"$file_path\" 2>&1 >&2 || true\n echo \"[Hook] Python formatted with ruff\" >&2\n fi\nfi\n\nprintf '%s\\n' \"$input\"\n )\nelse\n printf '%s' \"$input\"\nfi",
452
452
  "continueOnBlock": true
453
453
  }
454
454
  ],
@@ -459,7 +459,7 @@
459
459
  "hooks": [
460
460
  {
461
461
  "type": "command",
462
- "command": "input=$(cat)\nif printf '%s' \"$input\" | jq -e '((.tool_input.file_path // \"\") | test(\"\\\\.(py)$\"))' >/dev/null 2>&1; then\n printf '%s' \"$input\" | (\n#!/bin/bash\ninput=$(cat)\nfile_path=$(echo \"$input\" | jq -r '.tool_input.file_path // \"\"')\n\nif [ -n \"$file_path\" ] && [ -f \"$file_path\" ]; then\n # Type check with ty\n if command -v ty >/dev/null 2>&1; then\n dir=$(dirname \"$file_path\")\n project_root=\"$dir\"\n while [ \"$project_root\" != \"/\" ] && [ ! -f \"$project_root/pyproject.toml\" ]; do\n project_root=$(dirname \"$project_root\")\n done\n \n if [ -f \"$project_root/pyproject.toml\" ]; then\n cd \"$project_root\" && ty check \"$file_path\" 2>&1 | head -10 >&2 || true\n else\n ty check \"$file_path\" 2>&1 | head -10 >&2 || true\n fi\n fi\nfi\n\necho \"$input\"\n )\nelse\n printf '%s' \"$input\"\nfi",
462
+ "command": "input=$(cat)\nif printf '%s' \"$input\" | jq -e '((.tool_input.file_path // \"\") | test(\"\\\\.(py)$\"))' >/dev/null 2>&1; then\n printf '%s' \"$input\" | (\n#!/bin/bash\ninput=$(cat)\nfile_path=$(printf '%s\\n' \"$input\" | jq -r '.tool_input.file_path // \"\"')\n\nif [ -n \"$file_path\" ] && [ -f \"$file_path\" ]; then\n # Type check with ty\n if command -v ty >/dev/null 2>&1; then\n dir=$(dirname \"$file_path\")\n project_root=\"$dir\"\n while [ \"$project_root\" != \"/\" ] && [ ! -f \"$project_root/pyproject.toml\" ]; do\n project_root=$(dirname \"$project_root\")\n done\n \n if [ -f \"$project_root/pyproject.toml\" ]; then\n cd \"$project_root\" && ty check \"$file_path\" 2>&1 | head -10 >&2 || true\n else\n ty check \"$file_path\" 2>&1 | head -10 >&2 || true\n fi\n fi\nfi\n\nprintf '%s\\n' \"$input\"\n )\nelse\n printf '%s' \"$input\"\nfi",
463
463
  "continueOnBlock": true
464
464
  }
465
465
  ],
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.1.55",
2
+ "version": "1.1.57",
3
3
  "lastUpdated": "2026-07-14T00:00:00.000Z",
4
4
  "omcustomMinClaudeCode": "2.1.121",
5
5
  "omcustomMinClaudeCodeReason": "Sensitive-path direct Write/Edit on .claude/** under bypassPermissions (R010 deprecation, #1101)",