478c7529a7
The stats layer reads usage/duration only from run.end, but neither framework populated them, so tokens/cost/avg-duration were always 0. - hermes: accumulate token usage across each run's api-result calls in session state and attach the summed usage plus a computed duration_ms (from a stored runStartedAt) onto run.end. metric.snapshot emission is unchanged, so there is no double counting. - claude-code: store runStartedAt and use it as a duration_ms fallback at all run.end sites. Usage is unavailable from CC hook inputs. Live verification: a real hermes run now reports duration_ms and total_tokens on run.end; dashboard tokens_today/avg_duration_ms, both previously 0, now populate. cost_today stays 0 (no provider emits cost through the hooks). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>