Feature request: ephemeral/transient hook output that doesn't accumulate in conversation history
Problem
Hooks that inject dynamic per-turn context (e.g., UserPromptSubmit for memory systems) accumulate in conversation history. Every turn adds another block of injected context, consuming context window over long sessions.
Both stdout and additionalContext persist identically — there's no mechanism for "show this to the model on this turn only."
Use Case
Memory systems (like Roampal) inject relevant memories into each turn via UserPromptSubmit hooks. This works great functionally, but over a 100+ turn session, the accumulated injection blocks consume significant context.
OpenCode solves this with system.transform — the plugin rewrites the system prompt fresh each turn, zero accumulation. Claude Code has no equivalent.
Proposed Solutions (any of these would work)
- Ephemeral hook output: A flag or field (e.g.,
ephemeral: trueor a dedicatedtransientContextfield) where hook output is visible to the model on the current turn but not persisted in conversation history for future turns.
- System prompt access: Allow hooks to modify or append to the system prompt (similar to OpenCode's
system.transform). System prompt content is assembled per-turn and doesn't accumulate.
- Hook output replacement: Allow a hook to mark its output as "replaces previous injection from this hook" rather than appending a new block each turn.
What We Investigated
UserPromptSubmitstdout → accumulatesadditionalContextJSON field → accumulates identically- MCP resources/prompts → accumulate in conversation
- Skills DCI (
!command``) → doesn't accumulate but requires explicit invocation, not automatic per-turn - CLAUDE.md → system-level but static, not dynamic per-turn
suppressOutput→ only hides from UI, still persists in context
Environment
- Claude Code CLI (Windows, macOS, Linux)
- Use case: persistent memory systems that inject context every turn
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗