Hook system: token-aware input and quiet injection channel
Context
I use a Stop hook (claudemd-reinject.sh) that periodically re-injects CLAUDE.md rules into context to combat instruction decay in long sessions. Two limitations in the current hook architecture prevent better implementations.
Feature Request 1: Add context token count to hook input JSON
Current behavior: Stop hook JSON input contains session_id, cwd, stop_hook_active, and hook_event_name. No information about context size.
Requested: Include a context_tokens (or similar) field in the hook input JSON, representing the current context window usage.
Why this matters: Counter-based reinjection (every N turns) is a blunt instrument. A 20-turn session where each turn uses 200 tokens is very different from one where each turn uses 5,000 tokens. Token-aware hooks could reinject based on actual context growth — e.g., "reinject every 20K tokens" — which better targets the "lost in the middle" decay that reinjection is designed to combat.
Current workaround: Fixed-interval counting with a tunable env var. Works but can't adapt to varying turn sizes.
Feature Request 2: Separate injection channel from display output
Current behavior: Hook stderr serves dual purpose — it's both (1) the mechanism for injecting content into Claude's context and (2) what the user sees in the terminal. There's no way to inject content silently.
Requested: A mechanism to inject content into Claude's context without displaying it verbatim to the user. For example, a structured output format:
{"display": "Reinforcing CLAUDE.md rules...", "inject": "<full CLAUDE.md contents>"}
Or a separate file descriptor, or a flag in the hook output that marks content as "inject but minimize display."
Why this matters: Reinjecting a full CLAUDE.md (1,000+ tokens) prints a wall of text the user has already read. This is disruptive, especially at higher injection frequencies. Users want to know reinjection happened (short status line) without re-reading the entire document every time.
Current workaround: None. The only options are (a) show everything or (b) don't inject it.
Likely Affected Modules
- Hook input JSON construction (for token count)
- Hook output/stderr processing (for display vs. inject separation)
- Stop hook execution pipeline
Acceptance Criteria
- [ ] Stop hook JSON input includes a field representing current context token usage
- [ ] Hooks can specify content to inject into context without displaying it verbatim
- [ ] Existing hooks that use plain stderr continue to work unchanged (backward compatible)
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗