2026-03-16 09:46:49 +00:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
#
|
|
|
|
|
# show-impact.sh — Display accumulated impact metrics from the log.
|
|
|
|
|
#
|
|
|
|
|
# Usage: ./show-impact.sh [session_id]
|
|
|
|
|
# Without arguments: shows summary across all sessions.
|
|
|
|
|
# With session_id: shows entries for that session only.
|
|
|
|
|
|
|
|
|
|
set -euo pipefail
|
|
|
|
|
|
|
|
|
|
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(cd "$(dirname "$0")/../.." && pwd)}"
|
|
|
|
|
LOG_FILE="$PROJECT_DIR/.claude/impact/impact-log.jsonl"
|
|
|
|
|
|
|
|
|
|
if [ ! -f "$LOG_FILE" ]; then
|
|
|
|
|
echo "No impact log found at $LOG_FILE"
|
|
|
|
|
echo "The PreCompact hook will create it on first context compaction."
|
|
|
|
|
exit 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
FILTER="${1:-.}"
|
|
|
|
|
|
|
|
|
|
echo "=== Impact Log ==="
|
|
|
|
|
echo ""
|
|
|
|
|
|
|
|
|
|
while IFS= read -r line; do
|
|
|
|
|
sid=$(echo "$line" | jq -r '.session_id')
|
|
|
|
|
if ! echo "$sid" | grep -q "$FILTER"; then
|
|
|
|
|
continue
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
ts=$(echo "$line" | jq -r '.timestamp')
|
|
|
|
|
trigger=$(echo "$line" | jq -r '.trigger')
|
|
|
|
|
turns=$(echo "$line" | jq -r '.assistant_turns')
|
|
|
|
|
tools=$(echo "$line" | jq -r '.tool_uses')
|
|
|
|
|
source=$(echo "$line" | jq -r '.token_source // "heuristic"')
|
|
|
|
|
cum_input=$(echo "$line" | jq -r '.cumulative_input_tokens')
|
|
|
|
|
# Support both old field name and new field name
|
|
|
|
|
output=$(echo "$line" | jq -r '.output_tokens // .estimated_output_tokens')
|
|
|
|
|
cache_create=$(echo "$line" | jq -r '.cache_creation_tokens // 0')
|
|
|
|
|
cache_read=$(echo "$line" | jq -r '.cache_read_tokens // 0')
|
|
|
|
|
energy=$(echo "$line" | jq -r '.energy_wh')
|
|
|
|
|
co2=$(echo "$line" | jq -r '.co2_g')
|
|
|
|
|
cost=$(echo "$line" | jq -r '.cost_cents')
|
|
|
|
|
|
|
|
|
|
printf "%s [%s] session=%s\n" "$ts" "$trigger" "${sid:0:12}..."
|
|
|
|
|
printf " Turns: %s Tool uses: %s Token source: %s\n" "$turns" "$tools" "$source"
|
|
|
|
|
printf " Input tokens (cache-weighted): %s Output tokens: %s\n" "$cum_input" "$output"
|
|
|
|
|
if [ "$cache_create" != "0" ] || [ "$cache_read" != "0" ]; then
|
|
|
|
|
printf " Cache: %s created, %s read\n" "$cache_create" "$cache_read"
|
|
|
|
|
fi
|
|
|
|
|
LC_NUMERIC=C printf " Energy: ~%s Wh CO2: ~%sg Cost: ~\$%.2f\n" "$energy" "$co2" "$(echo "$cost / 100" | bc -l 2>/dev/null || echo "$cost cents")"
|
2026-03-16 15:05:53 +00:00
|
|
|
|
|
|
|
|
# Social cost proxies (if present in log entry)
|
|
|
|
|
model=$(echo "$line" | jq -r '.model_id // empty')
|
|
|
|
|
auto_pm=$(echo "$line" | jq -r '.automation_ratio_pm // empty')
|
|
|
|
|
user_tok=$(echo "$line" | jq -r '.user_tokens_est // empty')
|
|
|
|
|
files_ed=$(echo "$line" | jq -r '.unique_files_edited // empty')
|
|
|
|
|
total_ed=$(echo "$line" | jq -r '.total_file_edits // empty')
|
|
|
|
|
t_pass=$(echo "$line" | jq -r '.test_passes // empty')
|
|
|
|
|
t_fail=$(echo "$line" | jq -r '.test_failures // empty')
|
|
|
|
|
pub_push=$(echo "$line" | jq -r '.has_public_push // empty')
|
|
|
|
|
|
|
|
|
|
if [ -n "$model" ]; then
|
|
|
|
|
printf " Model: %s\n" "$model"
|
|
|
|
|
fi
|
|
|
|
|
if [ -n "$auto_pm" ] && [ "$auto_pm" != "0" ]; then
|
|
|
|
|
auto_pct=$(( auto_pm / 10 ))
|
|
|
|
|
auto_dec=$(( auto_pm % 10 ))
|
|
|
|
|
printf " Automation ratio: %d.%d%% (user ~%s tokens, AI ~%s tokens)\n" \
|
|
|
|
|
"$auto_pct" "$auto_dec" "$user_tok" "$output"
|
|
|
|
|
fi
|
|
|
|
|
if [ -n "$files_ed" ] && [ "$files_ed" != "0" ]; then
|
|
|
|
|
printf " File churn: %s edits across %s files\n" "$total_ed" "$files_ed"
|
|
|
|
|
fi
|
|
|
|
|
if [ -n "$t_pass" ] && [ -n "$t_fail" ] && { [ "$t_pass" != "0" ] || [ "$t_fail" != "0" ]; }; then
|
|
|
|
|
printf " Tests: %s passed, %s failed\n" "$t_pass" "$t_fail"
|
|
|
|
|
fi
|
|
|
|
|
if [ "$pub_push" = "1" ]; then
|
|
|
|
|
printf " Public push: yes (data pollution risk)\n"
|
|
|
|
|
fi
|
2026-03-16 09:46:49 +00:00
|
|
|
echo ""
|
|
|
|
|
done < "$LOG_FILE"
|
|
|
|
|
|
|
|
|
|
# Totals
|
|
|
|
|
TOTAL_ENERGY=$(jq -s '[.[].energy_wh] | add' "$LOG_FILE")
|
|
|
|
|
TOTAL_CO2=$(jq -s '[.[].co2_g] | add' "$LOG_FILE")
|
|
|
|
|
TOTAL_COST=$(jq -s '[.[].cost_cents] | add' "$LOG_FILE")
|
|
|
|
|
TOTAL_ENTRIES=$(wc -l < "$LOG_FILE")
|
|
|
|
|
|
|
|
|
|
echo "=== Totals ($TOTAL_ENTRIES snapshots) ==="
|
|
|
|
|
LC_NUMERIC=C printf " Energy: ~%s Wh CO2: ~%sg Cost: ~\$%.2f\n" \
|
|
|
|
|
"$TOTAL_ENERGY" "$TOTAL_CO2" \
|
|
|
|
|
"$(echo "$TOTAL_COST / 100" | bc -l 2>/dev/null || echo "$TOTAL_COST cents")"
|
|
|
|
|
|
|
|
|
|
# Show annotations if they exist
|
|
|
|
|
ANNOT_FILE="$PROJECT_DIR/.claude/impact/annotations.jsonl"
|
|
|
|
|
if [ -f "$ANNOT_FILE" ] && [ -s "$ANNOT_FILE" ]; then
|
|
|
|
|
echo ""
|
|
|
|
|
echo "=== Value Annotations ==="
|
|
|
|
|
echo ""
|
|
|
|
|
while IFS= read -r line; do
|
|
|
|
|
sid=$(echo "$line" | jq -r '.session_id')
|
|
|
|
|
if ! echo "$sid" | grep -q "$FILTER"; then
|
|
|
|
|
continue
|
|
|
|
|
fi
|
|
|
|
|
ts=$(echo "$line" | jq -r '.timestamp')
|
|
|
|
|
summary=$(echo "$line" | jq -r '.value_summary')
|
|
|
|
|
reach=$(echo "$line" | jq -r '.estimated_reach')
|
|
|
|
|
cf=$(echo "$line" | jq -r '.counterfactual')
|
|
|
|
|
net=$(echo "$line" | jq -r '.net_assessment')
|
|
|
|
|
printf "%s session=%s\n" "$ts" "${sid:0:12}..."
|
|
|
|
|
printf " Value: %s\n" "$summary"
|
|
|
|
|
printf " Reach: %s Counterfactual: %s Net: %s\n" "$reach" "$cf" "$net"
|
|
|
|
|
echo ""
|
|
|
|
|
done < "$ANNOT_FILE"
|
|
|
|
|
fi
|