mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-07 01:33:31 +08:00
fix: use CLI argument for hook phase detection in observe.sh
The observe.sh script receives "pre" or "post" as $1 from the hook config, but the Python code was looking for a "hook_type" field in the stdin JSON. Claude Code does NOT include "hook_type" in the JSON payload passed to hooks, so it always defaulted to "unknown", causing all observations to be recorded as "tool_complete" — PreToolUse events were never distinguished from PostToolUse. Fix: capture $1 as HOOK_PHASE and pass it to Python via env var. This also fixes TIMESTAMP export in the .cursor copy where inline `VAR=val cmd` syntax didn't propagate to the python subprocess.
This commit is contained in:
@@ -36,6 +36,9 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
# Hook phase from CLI argument: "pre" (PreToolUse) or "post" (PostToolUse)
|
||||||
|
HOOK_PHASE="${1:-post}"
|
||||||
|
|
||||||
CONFIG_DIR="${HOME}/.claude/homunculus"
|
CONFIG_DIR="${HOME}/.claude/homunculus"
|
||||||
OBSERVATIONS_FILE="${CONFIG_DIR}/observations.jsonl"
|
OBSERVATIONS_FILE="${CONFIG_DIR}/observations.jsonl"
|
||||||
MAX_FILE_SIZE_MB=10
|
MAX_FILE_SIZE_MB=10
|
||||||
@@ -57,15 +60,22 @@ if [ -z "$INPUT_JSON" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Parse using python via stdin pipe (safe for all JSON payloads)
|
# Parse using python via stdin pipe (safe for all JSON payloads)
|
||||||
PARSED=$(echo "$INPUT_JSON" | python3 -c '
|
# Pass HOOK_PHASE via env var since Claude Code does not include hook type in stdin JSON
|
||||||
|
PARSED=$(echo "$INPUT_JSON" | HOOK_PHASE="$HOOK_PHASE" python3 -c '
|
||||||
import json
|
import json
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
try:
|
try:
|
||||||
data = json.load(sys.stdin)
|
data = json.load(sys.stdin)
|
||||||
|
|
||||||
|
# Determine event type from CLI argument passed via env var.
|
||||||
|
# Claude Code does NOT include a "hook_type" field in the stdin JSON,
|
||||||
|
# so we rely on the shell argument ("pre" or "post") instead.
|
||||||
|
hook_phase = os.environ.get("HOOK_PHASE", "post")
|
||||||
|
event = "tool_start" if hook_phase == "pre" else "tool_complete"
|
||||||
|
|
||||||
# Extract fields - Claude Code hook format
|
# Extract fields - Claude Code hook format
|
||||||
hook_type = data.get("hook_type", "unknown") # PreToolUse or PostToolUse
|
|
||||||
tool_name = data.get("tool_name", data.get("tool", "unknown"))
|
tool_name = data.get("tool_name", data.get("tool", "unknown"))
|
||||||
tool_input = data.get("tool_input", data.get("input", {}))
|
tool_input = data.get("tool_input", data.get("input", {}))
|
||||||
tool_output = data.get("tool_output", data.get("output", ""))
|
tool_output = data.get("tool_output", data.get("output", ""))
|
||||||
@@ -82,9 +92,6 @@ try:
|
|||||||
else:
|
else:
|
||||||
tool_output_str = str(tool_output)[:5000]
|
tool_output_str = str(tool_output)[:5000]
|
||||||
|
|
||||||
# Determine event type
|
|
||||||
event = "tool_start" if "Pre" in hook_type else "tool_complete"
|
|
||||||
|
|
||||||
print(json.dumps({
|
print(json.dumps({
|
||||||
"parsed": True,
|
"parsed": True,
|
||||||
"event": event,
|
"event": event,
|
||||||
@@ -103,7 +110,8 @@ PARSED_OK=$(echo "$PARSED" | python3 -c "import json,sys; print(json.load(sys.st
|
|||||||
if [ "$PARSED_OK" != "True" ]; then
|
if [ "$PARSED_OK" != "True" ]; then
|
||||||
# Fallback: log raw input for debugging
|
# Fallback: log raw input for debugging
|
||||||
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||||
TIMESTAMP="$timestamp" echo "$INPUT_JSON" | python3 -c "
|
export TIMESTAMP="$timestamp"
|
||||||
|
echo "$INPUT_JSON" | python3 -c "
|
||||||
import json, sys, os
|
import json, sys, os
|
||||||
raw = sys.stdin.read()[:2000]
|
raw = sys.stdin.read()[:2000]
|
||||||
print(json.dumps({'timestamp': os.environ['TIMESTAMP'], 'event': 'parse_error', 'raw': raw}))
|
print(json.dumps({'timestamp': os.environ['TIMESTAMP'], 'event': 'parse_error', 'raw': raw}))
|
||||||
@@ -124,7 +132,8 @@ fi
|
|||||||
# Build and write observation
|
# Build and write observation
|
||||||
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||||
|
|
||||||
TIMESTAMP="$timestamp" echo "$PARSED" | python3 -c "
|
export TIMESTAMP="$timestamp"
|
||||||
|
echo "$PARSED" | python3 -c "
|
||||||
import json, sys, os
|
import json, sys, os
|
||||||
|
|
||||||
parsed = json.load(sys.stdin)
|
parsed = json.load(sys.stdin)
|
||||||
|
|||||||
@@ -36,6 +36,9 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
# Hook phase from CLI argument: "pre" (PreToolUse) or "post" (PostToolUse)
|
||||||
|
HOOK_PHASE="${1:-post}"
|
||||||
|
|
||||||
CONFIG_DIR="${HOME}/.claude/homunculus"
|
CONFIG_DIR="${HOME}/.claude/homunculus"
|
||||||
OBSERVATIONS_FILE="${CONFIG_DIR}/observations.jsonl"
|
OBSERVATIONS_FILE="${CONFIG_DIR}/observations.jsonl"
|
||||||
MAX_FILE_SIZE_MB=10
|
MAX_FILE_SIZE_MB=10
|
||||||
@@ -57,15 +60,22 @@ if [ -z "$INPUT_JSON" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Parse using python via stdin pipe (safe for all JSON payloads)
|
# Parse using python via stdin pipe (safe for all JSON payloads)
|
||||||
PARSED=$(echo "$INPUT_JSON" | python3 -c '
|
# Pass HOOK_PHASE via env var since Claude Code does not include hook type in stdin JSON
|
||||||
|
PARSED=$(echo "$INPUT_JSON" | HOOK_PHASE="$HOOK_PHASE" python3 -c '
|
||||||
import json
|
import json
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
try:
|
try:
|
||||||
data = json.load(sys.stdin)
|
data = json.load(sys.stdin)
|
||||||
|
|
||||||
|
# Determine event type from CLI argument passed via env var.
|
||||||
|
# Claude Code does NOT include a "hook_type" field in the stdin JSON,
|
||||||
|
# so we rely on the shell argument ("pre" or "post") instead.
|
||||||
|
hook_phase = os.environ.get("HOOK_PHASE", "post")
|
||||||
|
event = "tool_start" if hook_phase == "pre" else "tool_complete"
|
||||||
|
|
||||||
# Extract fields - Claude Code hook format
|
# Extract fields - Claude Code hook format
|
||||||
hook_type = data.get("hook_type", "unknown") # PreToolUse or PostToolUse
|
|
||||||
tool_name = data.get("tool_name", data.get("tool", "unknown"))
|
tool_name = data.get("tool_name", data.get("tool", "unknown"))
|
||||||
tool_input = data.get("tool_input", data.get("input", {}))
|
tool_input = data.get("tool_input", data.get("input", {}))
|
||||||
tool_output = data.get("tool_output", data.get("output", ""))
|
tool_output = data.get("tool_output", data.get("output", ""))
|
||||||
@@ -82,9 +92,6 @@ try:
|
|||||||
else:
|
else:
|
||||||
tool_output_str = str(tool_output)[:5000]
|
tool_output_str = str(tool_output)[:5000]
|
||||||
|
|
||||||
# Determine event type
|
|
||||||
event = "tool_start" if "Pre" in hook_type else "tool_complete"
|
|
||||||
|
|
||||||
print(json.dumps({
|
print(json.dumps({
|
||||||
"parsed": True,
|
"parsed": True,
|
||||||
"event": event,
|
"event": event,
|
||||||
|
|||||||
Reference in New Issue
Block a user