anthropics / anthropics/claude-code

[FEATURE] Add model, stop_reason, token usage and tool timing to hook payloads

Offen
#91,767 3 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
area:hooks enhancement
Vorherrschende Sprache
Python
Sterne
145k
Forks
23.1k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

### Preflight Checklist

- [x] I have searched [existing requests](https://github.com/anthropics/claude-code/issues?q=is%3Aissue%20label%3Aenhancement) and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)

### Problem Statement

I maintain an open-source desk device + plugin family ([Rubato_Plugins](https://github.com/lovaxi/Rubato_Plugins)) that mirrors agent state on physical hardware for several hosts (opencode, Cursor, OpenClaw, Codex). For Claude Code I use the official hooks — seven of them, from SessionStart to StopFailure.

The problem: **hook payloads carry almost no data** (session_id, transcript_path, cwd). To know the model, stop_reason, token usage, or tool names, my plugin must tail the session transcript JSONL in parallel — a second file-watcher per session, racing with Claude's own writes, parsing a format that is not documented as a stable contract.

Consequences:

- every hook consumer duplicates the same transcript-parsing layer (fragile, version-sensitive);
- extra latency between what Claude is doing and what external surfaces can display;
- streaming metrics (TTFT, tokens/sec) are simply unavailable at any latency — so honest duration estimation ("how long will this run take?") is impossible for external hardware and status surfaces, while the data itself exists inside the session.

### Proposed Solution

Keep the hooks exactly as they are — just make the payload self-sufficient, additively:

- on **all hooks**: include `model`
- on **Stop / StopFailure**: include `stop_reason`, `duration_ms`, and `token_usage { input, output, cache_read, cache_creation }`
- on **PostToolUse**: include `tool_duration_ms`
- (stretch) a turn-level metrics field with TTFT / output tokens-per-second — I understand streaming metrics may not be feasible; the usage fields alone are the high-value part.

Ideal UX: a hook consumer can mirror the full session — state, model, cost, honest durations — from hook events alone, without opening a single transcript file. All new fields are additive: existing consumers that ignore them are unaffected.

### Alternative Solutions

- Current workaround: tail `~/.claude/projects/.../*.jsonl` from a parallel daemon — works, but it parses an internal format, races with Claude's own writes, and still cannot see TTFT or streaming rate.
- The statusline input carries some session context, but it is a render surface, not an event stream an external device can subscribe to.
- An MCP server is the wrong layer for this: MCP servers serve the model; they do not observe the session.

### Priority

High - Significant impact on productivity

### Feature Category

Developer tools/SDK

### Use Case Example

1. I kick off a long refactor with Claude Code; my desk device shows Thinking → Generating so I stop alt-tabbing into the terminal.
2. On Stop, I want the device to show "took 4m 12s, 18k tokens" — so the user can honestly decide whether the next run justifies staying at the desk, and whether a break is due.
3. Today the Stop hook hands me a transcript path; a parallel daemon tails the JSONL, parses internal message shapes, and still cannot compute TTFT or per-request usage cleanly.
4. With structured hook payloads, the same integration shrinks to ~100 lines of version-stable code — and every status bar, dashboard, and device in the hooks ecosystem gets it for free.

### Additional Context

- The integration is shipped and verified end-to-end: [Rubato_Plugins](https://github.com/lovaxi/Rubato_Plugins) (seven hooks in use, including StopFailure and idle_prompt recovery).
- Cross-host parity: opencode events already carry per-call token usage, and OpenAI Codex exposes usage in its session data — Claude Code hooks are the gap.
- My device wire contract reserves `estSec` (estimated seconds); structured usage in hooks is the missing input for an honest estimate. Strictly additive proposal — no breaking changes.

Beitragsleitfaden

Für dieses Repository ist kein Beitragsleitfaden indexiert

Rechercherichtung

Start by finding where Claude Code builds official hook payloads for SessionStart through StopFailure, especially Stop, StopFailure, and PostToolUse. Compare those payloads with the transcript JSONL data under ~/.claude/projects/.../*.jsonl to see where model, stop_reason, token_usage, duration_ms, and tool_duration_ms are already available. Done means the listed fields are added additively to hook events without requiring consumers to read the transcript.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
api, cli, developer-experience, tooling
Issue-Typ
Feature
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Aktiv
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
45/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.