Files
orchestra/deploy/hooks/orchestra-stop.sh
T
kami 72f6230b4a feat(harness): dispatch /v1/harness/complete by harness kind (codex/opencode)
Adds an optional "harness" field so codex/opencode completions route to
their own Usage readers instead of always assuming Claude's transcript
format; unblocks the server side named as open in progress.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1rkJ2hBMybnJctPbcy4tT
2026-07-27 23:31:10 +04:00

71 lines
2.2 KiB
Bash
Executable File

#!/bin/sh
# Claude Code Stop hook — fires on every turn boundary, not just completion.
# Convention: the agent signals "this task is done" by writing a report file
# named .orchestra-report.md at the worktree root before stopping. If that
# marker is present, report completion. If it is absent, this is an ordinary
# turn boundary — ask the unified turn-decision endpoint (AUDIT.md B3, Phase
# 2 items 1-2) what to do instead of no-op'ing.
#
# Requires: ORCHESTRA_TASK_ID and ORCHESTRA_URL set in the pane's env.
# Optional: ORCHESTRA_HARNESS_TOKEN if the server requires one.
#
# Reads the Stop hook's JSON payload from stdin (has "transcript_path" and
# "cwd"); needs jq.
set -eu
payload="$(cat)"
transcript_path="$(printf '%s' "$payload" | jq -r '.transcript_path // empty')"
cwd="$(printf '%s' "$payload" | jq -r '.cwd // empty')"
[ -z "$transcript_path" ] && exit 0
[ -z "${ORCHESTRA_TASK_ID:-}" ] && exit 0
[ -z "${ORCHESTRA_URL:-}" ] && exit 0
auth_header=""
if [ -n "${ORCHESTRA_HARNESS_TOKEN:-}" ]; then
auth_header="Authorization: Bearer ${ORCHESTRA_HARNESS_TOKEN}"
fi
report_file="${cwd:-.}/.orchestra-report.md"
if [ -f "$report_file" ]; then
report="$(cat "$report_file")"
body="$(jq -n \
--arg task_id "$ORCHESTRA_TASK_ID" \
--arg transcript_path "$transcript_path" \
--arg report "$report" \
'{task_id: $task_id, harness: "claude", transcript_path: $transcript_path, report: $report}')"
if curl -fsS -X POST "${ORCHESTRA_URL%/}/v1/harness/complete" \
-H "Content-Type: application/json" \
${auth_header:+-H "$auth_header"} \
-d "$body" >/dev/null 2>&1; then
rm -f "$report_file"
else
echo "orchestra-stop: failed to report completion" >&2
exit 2
fi
exit 0
fi
body="$(jq -n --arg task_id "$ORCHESTRA_TASK_ID" '{task_id: $task_id}')"
response="$(curl -fsS -X POST "${ORCHESTRA_URL%/}/v1/harness/turn" \
-H "Content-Type: application/json" \
${auth_header:+-H "$auth_header"} \
-d "$body" 2>/dev/null)" || {
echo "orchestra-stop: failed to reach turn-decision endpoint" >&2
exit 0
}
decision="$(printf '%s' "$response" | jq -r '.decision // empty')"
if [ "$decision" = "refuse" ]; then
echo "orchestra-stop: turn decision is refuse — this turn boundary is not safe to stop at" >&2
exit 2
fi
exit 0