lazyagent compact shrinks session files in place without deleting them. Tool outputs, embedded images, terminal logs, and long thinking blocks are truncated above a threshold; the message graph, prompts, and tool call metadata are preserved so compacted sessions stay usable with the originating agent.
For deleting entire sessions, see Prune instead.
Synopsis
lazyagent compact [--days N] [--agent LIST]
[--threshold-kb N] [--min-size-kb N]
[--dry-run | --dry-run-verbose]
[--no-backup] [--yes]
All flags are optional. With no flags, compact opens the interactive agent picker, scans every supported agent, and prompts for confirmation before rewriting anything.
Flags
| Flag | Type | Default | Summary |
|---|---|---|---|
--days N | int | 0 (unset) | Only compact sessions idle more than N days |
--agent LIST | string | unset | Comma-separated subset: claude,pi,codex,grok,kimi. Empty opens the picker |
--threshold-kb N | int | 10 | Truncate JSON string values larger than N KiB |
--min-size-kb N | int | 512 | Skip files smaller than N KiB |
--dry-run | bool | false | Print a grouped summary, rewrite nothing |
--dry-run-verbose | bool | false | Print one row per file, rewrite nothing |
--no-backup | bool | false | Do not write .bak sidecars before rewriting |
--yes | bool | false | Skip the destructive-op disclaimer |
Quick reference
lazyagent compact # interactive picker + dry-run summary
lazyagent compact --agent claude --dry-run # preview group totals before/after
lazyagent compact --agent claude --dry-run-verbose # one row per file
lazyagent compact --agent claude --days 14 # only sessions idle ≥14 days
lazyagent compact --threshold-kb 20 # looser cut (default 10 KiB)
lazyagent compact --min-size-kb 2048 # only files ≥2 MiB (default 512 KiB)
lazyagent compact --no-backup # skip the .bak sidecar
lazyagent compact --yes # skip the destructive-op disclaimer
How it works
For JSONL transcripts, each line is parsed, walked, and re-serialized. Where a string value exceeds the threshold, lazyagent keeps a prefix (minimum 256 bytes, typically threshold / 10) and appends a marker:
[truncated by lazyagent compact — was 47123 bytes, kept first 4096]
The full JSONL rewrite is validated: the line count before and after must match, otherwise the rewrite is aborted and the original file is left untouched. Grok terminal logs and Kimi subagent outputs are truncated as plain text files. For extra safety a .bak sidecar is written by default; pass --no-backup to skip it.
Files where the rewrite wouldn’t actually shrink the file (usually because JSON map-key re-ordering added a handful of bytes but nothing was truncated) are silently left alone — no needless .bak, no wasted I/O.
Thresholds
--threshold-kb N (default 10) sets the maximum size for a single JSON string value. Beyond that, the value is truncated. Thinking blocks get a 2× budget because they carry genuine model reasoning that’s more expensive to lose than a tool output snapshot.
--min-size-kb N (default 512) skips files smaller than that many KiB — compacting a 40 KB transcript saves nothing meaningful.
Tuning guide:
| Goal | Recommended |
|---|---|
| Free up the most space, lose verbose tool output | --threshold-kb 5 |
| Conservative cut, keep short tool results readable | --threshold-kb 20 |
| Only hit whales (>2 MiB transcripts) | --min-size-kb 2048 |
| Aggressive sweep of everything >100 KiB | --min-size-kb 100 --threshold-kb 10 |
Agent selection
Same interactive picker as prune when --agent is omitted — see Prune: agent selection for the keybindings. Pass --agent claude,codex,pi,grok,kimi to skip the picker.
What gets truncated
Each agent has its own set of field paths. Only oversized values are touched; short strings (UUIDs, timestamps, tool names, signatures under threshold) are left alone.
Claude Code
toolUseResult.stdout,toolUseResult.stderr— bash outputtoolUseResult.originalFile— pre-edit file snapshotstoolUseResult.file.content— Read tool resultstoolUseResult.content[].text— structured tool payloadsmessage.content[].thinking— extended-thinking blocks (2× threshold)message.content[].text,message.content[].content— rare large assistant/user contentmessage.content[].source.data— base64-encoded images (replaced with a short marker rather than truncated)- Same fields under
data.message.message.content[]for progress-type entries
pi
message.content[].text— text blocksmessage.content[].thinking(2× threshold) — thinking blocksmessage.content[].thinkingSignature— cryptographic attestationmessage.content[].arguments— tool call arguments JSONmessage.details.truncation.content— post-compaction snapshotssummary— compaction summaries, only when they grow beyond 4× threshold (normally small and semantically useful)
Codex
payload.output— function_call_output bodiespayload.result— alternative result payload variantpayload.message— long agent_message payloadspayload.arguments— function call argumentspayload.content[].text/input_text/output_text— message content blocks
Grok CLI
updates.jsonl— the ACP update streamchat_history.jsonl— oversizedtool_resultpayloadsrewind_points.jsonl— checkpoint snapshotsterminal/*.log— raw terminal capture logs
Truncating rewind_points.jsonl disables Grok’s rewind feature for that session.
Kimi Code
agents/main/wire.jsonl— oversized user input blocks, thinking/text parts, tool-call arguments, and tool-result payloadsagents/*/wire.jsonl— the same fields for Kimi subagents embedded in a parent sessionagents/*/output— raw subagent output files
state.json, prompt.txt, and subagent metadata are left untouched.
Dry runs
Same two flags as prune — --dry-run for grouped totals, --dry-run-verbose for per-file rows. Both show the before/after size and the exact reclaimable bytes based on a simulated rewrite:
AGENT PROJECT FILES BEFORE AFTER SAVED
claude /Users/me/projects/big-app 6 142.1 MiB 86.7 MiB 55.3 MiB
claude /Users/me/projects/mid-app 3 10.4 MiB 5.9 MiB 4.5 MiB
pi /Users/me/projects/pi-exp 2 2.1 MiB 1.0 MiB 1.1 MiB
…
Total: 41 file(s) — 307.5 MiB → 220.9 MiB (86.6 MiB reclaimed).
Confirmation
Real runs print the summary (with a numbered # column next to every project group), then the disclaimer box, then a prompt that accepts three forms:
Compact N file(s)? Enter y for all, a row # to target a single project, or N to abort [y/N/#]:
| Input | Effect |
|---|---|
y / yes | Compact every candidate in the table |
Row number (1-based, from the # column) | Compact only the files in that group |
n / empty / anything else / EOF | Abort without rewriting anything |
Out-of-range numbers abort. When you pick a row, lazyagent prints a one-line confirmation (Selected row 3: claude /path/to/project (4 file(s))) before the rewrite starts.
The disclaimer and prompt are both skipped with --yes, which always acts on every candidate — the per-row picker is interactive only.
Safety
- Line-count validation — the rewrite is aborted if the line count changes, leaving the original file untouched.
.baksidecar — written by default before each rewrite. Pass--no-backupto skip.- File mode preserved — a 0600 transcript stays 0600 after compaction; no quiet permission widening.
- Active sessions (touched in the last 5 minutes) are skipped.
- Discovered sub-agent sessions are skipped to avoid breaking the parent’s file. Kimi’s nested subagent payload/output files are compacted as part of their parent session.
- Path guard refuses to rewrite anything outside the known agent roots.
- No-op guard — if a simulated rewrite wouldn’t actually shrink the file, it’s left alone.
Restoring from a backup
Every rewrite (unless --no-backup) produces a <filename>.bak sibling. To undo a compaction:
mv session.jsonl.bak session.jsonl
Supported agents
- claude (Claude Code CLI and Desktop share the same JSONL format)
- pi
- codex
- grok
- kimi
Not supported:
- Amp — local files are re-synced from the remote; rewriting them gets overwritten on the next sync.
- Cursor, OpenCode, and Kilo — sessions live inside third-party SQLite databases. Rewriting their internals is deferred to a future version.
Examples
# Default sweep with an interactive picker
lazyagent compact
# Preview what would happen for Claude only — no writes
lazyagent compact --agent claude --dry-run-verbose
# Aggressive cut: everything ≥100 KiB, with a tight 5 KiB threshold
lazyagent compact --min-size-kb 100 --threshold-kb 5 --agent claude
# Conservative cut: only old, only big, keep everything resumable
lazyagent compact --days 14 --min-size-kb 2048 --threshold-kb 20
# Script-friendly run: no prompt, no .bak, log the summary
lazyagent compact --agent claude --days 7 --yes --no-backup > ~/.local/state/la-compact.log 2>&1
# Undo a specific compaction
mv path/to/session.jsonl.bak path/to/session.jsonl
See Recipes for the full “weekly tidy-up” and “reclaim disk space aggressively” walkthroughs.
Exit codes
| Code | Meaning |
|---|---|
0 | Success (including “nothing to compact”) |
1 | At least one rewrite failed |
2 | Invalid flags or combinations |