#!/usr/bin/env bash
# gpt-advisor: reconstruct this session's conversation from the on-disk transcript
# and put it to Codex as a reviewer. Fail-closed: never advise on an unverified
# transcript, never guess a session.
#
#   gpt-advisor.sh <MARKER> <QUESTION> [--effort E] [--full] [--budget-tokens N]
#
#   MARKER    distinctive ASCII substring of a recent user turn; disambiguates
#             this session from others sharing ~/.claude/projects/<slug>/
#   QUESTION  what to advise on, including the approach under review
#   --full    send the whole transcript instead of the unread delta
set -euo pipefail

RESOLVE="${HOME}/.claude/skills/dead-advisor/resolve.sh"
ASK_GPT="${HOME}/.local/bin/ask-gpt"
BUDGET="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/transcript-budget.py"
STATE_DIR="${HOME}/.claude/gpt-advisor-state"
EFFORT="xhigh"
FULL=0
BUDGET_TOKENS=900000

die() { echo "gpt-advisor: $*" >&2; exit 1; }

[ -x "$RESOLVE" ] || die "transcript resolver not found: $RESOLVE"
[ -x "$ASK_GPT" ] || die "ask-gpt not installed: $ASK_GPT"
[ -f "$BUDGET" ] || die "budget filter not found: $BUDGET"

marker="${1:-}"; shift || true
question="${1:-}"; shift || true
[ -n "$marker" ] || die "usage: gpt-advisor.sh <MARKER> <QUESTION> [--effort E] [--full] [--budget-tokens N]"
[ -n "$question" ] || die "QUESTION is required"

while [ $# -gt 0 ]; do
  case "$1" in
    --effort) EFFORT="${2:-}"; [ -n "$EFFORT" ] || die "--effort requires a value"; shift 2 ;;
    --full)   FULL=1; shift ;;
    --budget-tokens)
              BUDGET_TOKENS="${2:-}"
              case "$BUDGET_TOKENS" in (''|*[!0-9]*) die "--budget-tokens requires a positive integer" ;; esac
              shift 2 ;;
    *)        die "unknown argument: $1" ;;
  esac
done

resolved=$("$RESOLVE" lookup "$marker") || exit $?
eval "$resolved"
[ -n "${TRANSCRIPT:-}" ] || die "resolver returned no transcript"

# gpt-advisor keeps its OWN read cursor: dead-advisor's cursor tracks what its
# subagent consumed, and the two advisors are used independently.
cursor_file="${STATE_DIR}/${SESSION}.read"
lastread=0
[ -f "$cursor_file" ] && lastread=$(head -1 "$cursor_file" 2>/dev/null || echo 0)
case "$lastread" in (*[!0-9]*|'') lastread=0 ;; esac
[ "$FULL" = 1 ] && lastread=0
if [ "$lastread" -eq 0 ]; then
  coverage="the whole session so far"
else
  coverage="the turns since your last review"
fi

start=$((lastread + 1))
[ "$start" -le "$NOW" ] || die "nothing new since line ${lastread}; pass --full to resend the whole transcript"

workdir=$(mktemp -d -t gpt-advisor-XXXXXX)
trap 'rm -rf "$workdir"' EXIT
raw="${workdir}/raw.jsonl"
slice="${workdir}/transcript-${start}-${NOW}.jsonl"
sed -n "${start},${NOW}p" "$TRANSCRIPT" > "$raw"
[ -s "$raw" ] || die "transcript slice ${start}..${NOW} is empty"

# fail-closed: an over-budget attachment is rejected by ask-gpt, so shrink here
# and refuse rather than send one
elision=$(python3 "$BUDGET" "$raw" "$slice" --budget-tokens "$BUDGET_TOKENS" 2>&1 >/dev/null) \
  || die "${elision:-could not fit the transcript into ${BUDGET_TOKENS} tokens}"
[ -s "$slice" ] || die "budget filter produced an empty slice"
echo "$elision" >&2

prompt="You are a stronger reviewer advising a coding agent mid-task.

The attached file is that agent's raw Claude Code session transcript in JSONL — one
record per line, covering lines ${start}..${NOW} of the session (${coverage}).
Reconstruct what happened from it: the task, the tool calls, what they returned.

To fit a ${BUDGET_TOKENS}-token cap the slice was shrunk — ${elision#transcript-budget: }.
Bulky tool output is clipped head+tail with an explicit elided-chars marker; harness
plumbing records were removed. Say so if a verdict depends on something elided.

Then advise on this, treating the stated approach as the decision under review:

${question}

Be critical and specific. Name the concrete risk, the file, the line, the failure
case. If the approach is sound, say so plainly and say what would falsify it. Do
not summarize the transcript back — the agent already lived it."

# a failed run leaves the cursor untouched, so the next call re-sends the same
# turns rather than silently skipping the range nobody reviewed
"$ASK_GPT" --effort "$EFFORT" -a "$slice" "$prompt"

mkdir -p "$STATE_DIR"
printf '%s\n' "$NOW" > "$cursor_file"
