#!/bin/bash # Triage a Claude Code event using a fast LLM. # Called by hook scripts when bash pre-filtering can't decide. # # Usage: triage.sh # event-type: stopped | error | notification # cwd: project directory (used to find config + state) # context: the relevant context (tmux output, error message, etc.) # # Reads supervisor-state.json to find the goal for this session. # Returns one of: FINE | NEEDS_NUDGE | STUCK | DONE | ESCALATE set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "$SCRIPT_DIR/lib.sh" EVENT_TYPE="${1:-unknown}" CWD="${2:-.}" CONTEXT="${3:-}" CONFIG=$(ccs_find_config "$CWD") # Try to find the goal from supervisor state STATE_FILE="${CCS_STATE_FILE:-${HOME}/.openclaw/workspace/supervisor-state.json}" GOAL="unknown" if [ -f "$STATE_FILE" ]; then # Match by cwd/projectDir GOAL=$(jq -r --arg cwd "$CWD" ' .sessions | to_entries[] | select(.value.projectDir == $cwd) | .value.goal ' "$STATE_FILE" 2>/dev/null || echo "unknown") fi PROMPT="You are a coding agent supervisor. A Claude Code session just triggered an event. Event: ${EVENT_TYPE} Project: ${CWD} Goal: ${GOAL} Recent terminal output: ${CONTEXT} Classify this situation with exactly one word on the first line: FINE - Agent is working normally, no intervention needed NEEDS_NUDGE - Agent hit a transient error or stopped prematurely, should be told to continue STUCK - Agent is looping or not making progress, needs different approach DONE - Agent completed the task successfully ESCALATE - Situation needs human judgment Then a one-line explanation." VERDICT=$(ccs_triage "$CONFIG" "$PROMPT") echo "$VERDICT" # Extract the classification (first word of first line) CLASSIFICATION=$(echo "$VERDICT" | head -1 | awk '{print $1}') # Only notify if action is needed case "$CLASSIFICATION" in FINE) # Log silently, don't wake anyone echo "[$(date -u +%FT%TZ)] FINE | $EVENT_TYPE | $CWD" >> "${CCS_LOG_FILE:-/tmp/ccs-triage.log}" ;; NEEDS_NUDGE|STUCK|DONE|ESCALATE) ccs_notify "$CONFIG" "cc-supervisor: $CLASSIFICATION | $EVENT_TYPE | cwd=$CWD | $VERDICT" ;; *) # Couldn't parse — notify to be safe ccs_notify "$CONFIG" "cc-supervisor: UNKNOWN | $EVENT_TYPE | cwd=$CWD | verdict=$VERDICT" ;; esac