Skip to content

feat(hooks): expose run cost, tokens and duration to post-hooks - #113

Open
dagoaie wants to merge 2 commits into
Inakitajes:mainfrom
dagoaie:feat/hook-run-usage-pr
Open

dagoaie wants to merge 2 commits into
Inakitajes:mainfrom
dagoaie:feat/hook-run-usage-pr

Conversation

@dagoaie

@dagoaie dagoaie commented Sep 11, 2026

Copy link
Copy Markdown

Why

Post-hooks are the place to notify, gate or comment on a run, but they only got the run's status and ID — not what the run cost. A hook that wants to leave the cost on a PR or refuse to continue past a budget had to re-parse metadata.json itself. The runner already holds every phase's usage; this exposes the aggregate.

Summary

  • src/usage.ts: sumRunUsage folds the recorded phases into a RunUsage — cost (executor plus advisor), advisor cost on its own, summed executor tokens and summed phase durations. Each field is present only when a phase recorded that fact; absent facts are never reported as zero.
  • src/metadata.ts: runUsage() on the metadata store, built from the in-memory phases so the hook sees the same numbers convoy runs will show.
  • src/hooks.ts: post-hooks receive CONVOY_RUN_COST, CONVOY_RUN_ADVISOR_COST (4 decimals, USD), CONVOY_RUN_TOKENS_{INPUT,OUTPUT,CACHE_READ,CACHE_WRITE,REASONING,TOTAL} and CONVOY_RUN_DURATION_MS, on success and on failure. Inherited CONVOY_RUN_* usage variables are stripped from the hook's environment so a stale parent value can't leak in.
  • src/runner.ts: passes the usage snapshot to the post-hooks on both exit paths (+4 lines).
  • README.md: documents the variables with a PR-comment hook and an awk budget guard.
  • OpenSpec change hook-run-usage archived with its spec.

Verification

  • bun run typecheck, bun test (3203 pass), coverage 92.4 % lines / 93.0 % functions.
  • openspec validate hook-run-usage --strict.
  • Headless smoke on a scratch repo with a post-hook dumping env | grep '^CONVOY_RUN_': cost and token counts match the run's metadata.json, duration equals the recorded phase durations, CONVOY_RUN_ADVISOR_COST absent when no advisor ran.
  • Review-pipeline finding (advisor-only spend was omitted from CONVOY_RUN_COST) fixed and covered by a unit test.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BG8wiaLWbUzGXBm3rtzN41

dagoaie and others added 2 commits September 11, 2026 21:14
Post-hooks receive the run's aggregated usage in their environment:
CONVOY_RUN_COST (executor plus advisor), CONVOY_RUN_ADVISOR_COST,
CONVOY_RUN_TOKENS_* and CONVOY_RUN_DURATION_MS, summed from the metadata
the runner already holds, on success and on failure. Each variable appears
only when a phase recorded that fact; nothing is reported as zero. The
README documents the formats with a PR-comment hook and an awk budget
guard.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BG8wiaLWbUzGXBm3rtzN41
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FUdVGWR9FvgD11kEsuS1U4
@dagoaie
dagoaie force-pushed the feat/hook-run-usage-pr branch 2 times, most recently from 852d3f5 to 5bad914 Compare September 14, 2026 11:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant