Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions scripts/hooks/run-with-flags-shell.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ HOOK_ID="${1:-}"
REL_SCRIPT_PATH="${2:-}"
PROFILES_CSV="${3:-standard,strict}"

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DEFAULT_PLUGIN_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-${DEFAULT_PLUGIN_ROOT}}"
Comment on lines +10 to +12
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n scripts/hooks/run-with-flags-shell.sh

Repository: affaan-m/everything-claude-code

Length of output: 1379


🏁 Script executed:

# Find hook scripts and check if any reference CLAUDE_PLUGIN_ROOT
find scripts/hooks -type f -name "*.sh" -o -name "*.js" | head -20

Repository: affaan-m/everything-claude-code

Length of output: 793


🏁 Script executed:

# Search for references to CLAUDE_PLUGIN_ROOT in the codebase
rg 'CLAUDE_PLUGIN_ROOT' --type sh --type js

Repository: affaan-m/everything-claude-code

Length of output: 1571


🏁 Script executed:

# Check if run-with-flags.js reads CLAUDE_PLUGIN_ROOT from process.env
cat -n scripts/hooks/run-with-flags.js | head -40

Repository: affaan-m/everything-claude-code

Length of output: 1389


🏁 Script executed:

# Search for how hooks are configured/registered to see what gets passed as REL_SCRIPT_PATH
rg "REL_SCRIPT_PATH|run-with-flags" scripts/ -A 2 -B 2 | head -50

Repository: affaan-m/everything-claude-code

Length of output: 1581


Export CLAUDE_PLUGIN_ROOT so child hooks can access it.

Lines 7–12 contain duplicate SCRIPT_DIR computation and set CLAUDE_PLUGIN_ROOT without exporting it. Child hook scripts—particularly Node scripts like run-with-flags.js—that call getPluginRoot() expect CLAUDE_PLUGIN_ROOT to be available in their process environment. Without the export, they cannot access the fallback value set here.

Suggested fix
 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(cd "${SCRIPT_DIR}/../.." && pwd)}"
-
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
 DEFAULT_PLUGIN_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
-CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-${DEFAULT_PLUGIN_ROOT}}"
+export CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-${DEFAULT_PLUGIN_ROOT}}"
+PLUGIN_ROOT="$CLAUDE_PLUGIN_ROOT"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/hooks/run-with-flags-shell.sh` around lines 10 - 12, Remove the
duplicated SCRIPT_DIR computation and ensure CLAUDE_PLUGIN_ROOT is exported so
child processes can read it; specifically, keep a single declaration of
SCRIPT_DIR and DEFAULT_PLUGIN_ROOT, set
CLAUDE_PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-${DEFAULT_PLUGIN_ROOT}}" and add
export CLAUDE_PLUGIN_ROOT (so run-with-flags.js and its getPluginRoot() can
access it from the environment).


# Preserve stdin for passthrough or script execution
INPUT="$(cat)"

Expand Down
20 changes: 15 additions & 5 deletions skills/continuous-learning-v2/hooks/observe.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@

set -e

# Pick an available Python executable (python3 preferred, python fallback)
if command -v python3 >/dev/null 2>&1; then
PYTHON_CMD="python3"
elif command -v python >/dev/null 2>&1; then
PYTHON_CMD="python"
else
echo "[observe] No python found, skipping observation" >&2
exit 0
fi
Comment on lines +15 to +24
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, check if the file exists and explore the repository structure
find . -type f -name "observe.sh" 2>/dev/null | head -20

Repository: affaan-m/everything-claude-code

Length of output: 123


🏁 Script executed:

# List the continuous-learning-v2 directory structure
fd . "skills/continuous-learning-v2" -type f | head -30

Repository: affaan-m/everything-claude-code

Length of output: 245


🏁 Script executed:

# Read the observe.sh file
cat -n ./skills/continuous-learning-v2/hooks/observe.sh

Repository: affaan-m/everything-claude-code

Length of output: 10034


🏁 Script executed:

# Read the detect-project.sh file to understand CLV2_PYTHON_CMD contract
cat -n ./skills/continuous-learning-v2/scripts/detect-project.sh | head -100

Repository: affaan-m/everything-claude-code

Length of output: 3979


🏁 Script executed:

# Read start-observer.sh
cat -n ./skills/continuous-learning-v2/agents/start-observer.sh | head -100

Repository: affaan-m/everything-claude-code

Length of output: 4040


Honor CLV2_PYTHON_CMD before exiting.

The early Python detection on Lines 15–24 skips PATH check for CLV2_PYTHON_CMD and exits at Line 23 before detect-project.sh is sourced at Line 96. This breaks any environment where only CLV2_PYTHON_CMD provides a valid interpreter. The resolve_python_cmd() function on Lines 41–58 correctly checks CLV2_PYTHON_CMD first, but it is never reached if Lines 15–24 exit early.

Remove the early hardcoded check and instead call resolve_python_cmd() before reading stdin, or source detect-project.sh and check CLV2_PYTHON_CMD first at the entry point.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skills/continuous-learning-v2/hooks/observe.sh` around lines 15 - 24, Remove
the early hardcoded Python detection block that exits when no python binary is
found and instead invoke the existing resolve_python_cmd() (which honors
CLV2_PYTHON_CMD) at the script entrypoint before reading stdin; alternatively
source detect-project.sh first so CLV2_PYTHON_CMD is available and then call
resolve_python_cmd() to set PYTHON_CMD (or fail gracefully) — update the top of
observe.sh to rely on resolve_python_cmd() and remove the initial command -v
python* check that causes an early exit.


# Hook phase from CLI argument: "pre" (PreToolUse) or "post" (PostToolUse)
HOOK_PHASE="${1:-post}"

Expand All @@ -33,7 +43,7 @@ fi

# Extract cwd from the hook JSON to use for project detection.
# This avoids spawning a separate git subprocess when cwd is available.
STDIN_CWD=$(echo "$INPUT_JSON" | python3 -c '
STDIN_CWD=$(echo "$INPUT_JSON" | "$PYTHON_CMD" -c '
import json, sys
try:
data = json.load(sys.stdin)
Expand Down Expand Up @@ -74,7 +84,7 @@ fi

# Parse using python via stdin pipe (safe for all JSON payloads)
# 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 '
PARSED=$(echo "$INPUT_JSON" | HOOK_PHASE="$HOOK_PHASE" "$PYTHON_CMD" -c '
import json
import sys
import os
Expand Down Expand Up @@ -122,13 +132,13 @@ except Exception as e:
')

# Check if parsing succeeded
PARSED_OK=$(echo "$PARSED" | python3 -c "import json,sys; print(json.load(sys.stdin).get('parsed', False))" 2>/dev/null || echo "False")
PARSED_OK=$(echo "$PARSED" | "$PYTHON_CMD" -c "import json,sys; print(json.load(sys.stdin).get('parsed', False))" 2>/dev/null || echo "False")

if [ "$PARSED_OK" != "True" ]; then
# Fallback: log raw input for debugging
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
export TIMESTAMP="$timestamp"
echo "$INPUT_JSON" | python3 -c "
echo "$INPUT_JSON" | "$PYTHON_CMD" -c "
import json, sys, os
raw = sys.stdin.read()[:2000]
print(json.dumps({'timestamp': os.environ['TIMESTAMP'], 'event': 'parse_error', 'raw': raw}))
Expand All @@ -153,7 +163,7 @@ export PROJECT_ID_ENV="$PROJECT_ID"
export PROJECT_NAME_ENV="$PROJECT_NAME"
export TIMESTAMP="$timestamp"

echo "$PARSED" | python3 -c "
echo "$PARSED" | "$PYTHON_CMD" -c "
import json, sys, os

parsed = json.load(sys.stdin)
Expand Down