harb/onchain/.claude/hooks/supervisor/lib.sh
openhands b7260b2eaf chore: analysis tooling, research artifacts, and code quality
- Analysis: parameter sweep scripts, adversarial testing, 2D frontier maps
- Research: KRAIKEN_RESEARCH_REPORT, SECURITY_REVIEW, STORAGE_LAYOUT
- FuzzingBase: consolidated fuzzing helper, BackgroundLP simulation
- Sweep results: CSV data for full 4D sweep (1050 combos), bull-bear,
  AS sweep, VWAP fix validation
- Code quality: .gitignore for fuzz CSVs, gas snapshot, updated docs
- Remove dead analysis helpers (CSVHelper, CSVManager, ScenarioRecorder)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 18:22:03 +00:00

139 lines
4.8 KiB
Bash
Executable file
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# Shared functions for claude-code-supervisor hooks and scripts.
set -euo pipefail
# Find config file: project .claude-code-supervisor.yml → ~/.config/ → defaults
ccs_find_config() {
local cwd="${1:-.}"
if [ -f "$cwd/.claude-code-supervisor.yml" ]; then
echo "$cwd/.claude-code-supervisor.yml"
elif [ -f "${HOME}/.config/claude-code-supervisor/config.yml" ]; then
echo "${HOME}/.config/claude-code-supervisor/config.yml"
else
echo ""
fi
}
# Read a yaml value (simple key.subkey extraction, no yq dependency).
# Falls back to default if not found.
ccs_config_get() {
local config_file="$1"
local key="$2"
local default="${3:-}"
if [ -z "$config_file" ] || [ ! -f "$config_file" ]; then
echo "$default"
return
fi
# Simple grep-based yaml extraction (handles key: value on one line)
local value
case "$key" in
triage.command) value=$(grep -A0 '^\s*command:' "$config_file" | head -1 | sed 's/.*command:\s*["]*//;s/["]*$//' | xargs) ;;
triage.model) value=$(awk '/^triage:/,/^[a-z]/' "$config_file" | grep 'model:' | head -1 | sed 's/.*model:\s*["]*//;s/["]*$//' | xargs) ;;
triage.max_tokens) value=$(awk '/^triage:/,/^[a-z]/' "$config_file" | grep 'max_tokens:' | head -1 | sed 's/.*max_tokens:\s*//' | xargs) ;;
notify.command) value=$(awk '/^notify:/,/^[a-z]/' "$config_file" | grep 'command:' | head -1 | sed 's/.*command:\s*["]*//;s/["]*$//' | xargs) ;;
idle.timeout) value=$(awk '/^idle:/,/^[a-z]/' "$config_file" | grep 'timeout_seconds:' | head -1 | sed 's/.*timeout_seconds:\s*//' | xargs) ;;
idle.nudge_message) value=$(awk '/^idle:/,/^[a-z]/' "$config_file" | grep 'nudge_message:' | head -1 | sed 's/.*nudge_message:\s*["]*//;s/["]*$//' | xargs) ;;
*) value="" ;;
esac
echo "${value:-$default}"
}
# Send a notification via the configured notify command.
ccs_notify() {
local config_file="$1"
local message="$2"
local notify_cmd
notify_cmd=$(ccs_config_get "$config_file" "notify.command" "openclaw gateway call wake --params")
# Build JSON payload
local payload
payload=$(jq -n --arg text "$message" --arg mode "now" '{text: $text, mode: $mode}')
$notify_cmd "$payload" 2>/dev/null || true
}
# Run LLM triage via configured command.
# Accepts prompt on stdin, returns verdict on stdout.
ccs_triage() {
local config_file="$1"
local prompt="$2"
local triage_cmd model max_tokens
triage_cmd=$(ccs_config_get "$config_file" "triage.command" "claude -p --no-session-persistence")
model=$(ccs_config_get "$config_file" "triage.model" "claude-haiku-4-20250414")
max_tokens=$(ccs_config_get "$config_file" "triage.max_tokens" "150")
echo "$prompt" | $triage_cmd --model "$model" --max-tokens "$max_tokens" 2>/dev/null
}
# Generate a notify wrapper script the agent can call on completion.
# Usage: ccs_generate_notify_script "$config_file" ["/tmp/supervisor-notify.sh"]
ccs_generate_notify_script() {
local config_file="$1"
local script_path="${2:-/tmp/supervisor-notify.sh}"
local notify_cmd
notify_cmd=$(ccs_config_get "$config_file" "notify.command" "openclaw gateway call wake --params")
cat > "$script_path" <<SCRIPT
#!/bin/bash
# Auto-generated by claude-code-supervisor
# Usage: $script_path "your summary here"
MESSAGE="\${*:-done}"
PAYLOAD=\$(jq -n --arg text "cc-supervisor: DONE | agent-reported | \$MESSAGE" --arg mode "now" '{text: \$text, mode: \$mode}')
$notify_cmd "\$PAYLOAD" 2>/dev/null || echo "Notify failed (command: $notify_cmd)" >&2
SCRIPT
chmod +x "$script_path"
}
# Extract environment_hints from config as newline-separated list.
# Usage: hints=$(ccs_environment_hints "$config_file")
ccs_environment_hints() {
local config_file="$1"
if [ -z "$config_file" ] || [ ! -f "$config_file" ]; then
return
fi
awk '/^environment_hints:/,/^[a-z]/' "$config_file" \
| grep '^\s*-' \
| sed 's/^\s*-\s*["]*//;s/["]*$//'
}
# Parse capture-pane output and return session status.
# Returns: WORKING | IDLE | DONE | ERROR
# Usage: status=$(ccs_parse_status "$pane_output")
ccs_parse_status() {
local output="$1"
local last_lines
last_lines=$(echo "$output" | tail -15)
# DONE: completed task indicators (cost summary line)
if echo "$last_lines" | grep -qE '(Brewed for|Churned for) [0-9]+'; then
echo "DONE"
return
fi
# WORKING: active tool call or thinking
if echo "$last_lines" | grep -qE 'esc to interrupt|Running…|Waiting…'; then
echo "WORKING"
return
fi
# ERROR: tool failures or API errors
if echo "$last_lines" | grep -qiE 'API Error:|Exit code [1-9]|^Error:'; then
echo "ERROR"
return
fi
# IDLE: prompt back with no activity indicator
if echo "$last_lines" | tail -3 | grep -qE '^\$ |^ |^% |^[a-z]+@.*\$ '; then
echo "IDLE"
return
fi
# Default: assume working (mid-output, streaming, etc.)
echo "WORKING"
}