Feature request: Surgical context compaction (/shrink command)
Problem
When large files, tool outputs, or MCP responses are read into a conversation, they consume significant context budget even when the full content is no longer needed. Currently, the only option is /compact which summarizes the entire conversation - a blunt instrument when you only need to shrink specific blocks.
Example: Accidentally reading a 2500-line file consumes ~50KB of context. That content might be 30% of the context budget, but is no longer relevant after initial analysis.
Proposed Solution
A /shrink command that performs surgical compaction - targeting specific large blocks while preserving the rest of the conversation verbatim.
How it would work
- Identify large content blocks in the session JSONL:
thinkingblocks over N bytestoolUseResult.file.contentover N KBtoolUseResult.stdoutover N KBtool_resultcontent blocks over N KB
- Replace each with a compact summary:
- File reads →
[COMPACTED] File: /path/to/file.ts (1109 lines). Summary: {brief description} - Tool output →
[COMPACTED] Command output (500 lines). Preview: {first 150 chars}... - Thinking →
[COMPACTED] Thinking block removed.
- Write back the modified JSONL, preserving all message metadata
- User runs
/resumeto reload the lighter conversation
Key benefits
- Targeted: Only shrinks what you specify, preserving full fidelity elsewhere
- Recoverable: Original content exists in backups
- User-controlled:
--dry-runto preview,--threshold-kb=Nto tune - Context-efficient: The compaction work happens in a subagent's separate context
Proof of Concept
We built a working prototype during a conversation about this exact problem:
- Script:
~/.claude/scripts/shrink.mjs- handles all mechanical compaction - Command:
~/.claude/commands/shrink.md- slash command wrapper
Tested successfully - reduced a 218KB conversation to 207KB by compacting 5 blocks (thinking + file content + tool results).
Additional context
The conversation JSONL structure already supports this well:
- One JSON object per line
- Clear content type markers (
thinking,tool_result,toolUseResult) - UUIDs for message identity
- Modifying the file and running
/resumepicks up changes
This could be a native Claude Code feature with tighter integration (e.g., inline prompts: "This file is 2500 lines. Compact after reading?").
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗