vac
🧹 Vacuum up cruft from your AI coding-agent sessions. A small, standalone Python CLI that cleans, analyzes, and repairs local session logs for Kiro CLI and Claude Code.
Long screenshot-heavy sessions accumulate embedded base64 images. Because these agents replay the full conversation every turn, one oversized image (>2000px) can wedge the whole session with:
image dimensions exceed max allowed size for many-image requests: 2000 pixels
vac fixes and prevents that.
Install
Pick whichever you have — the installed command is always vac.
pip (universal — works anywhere Python + pip exist):
pip install vac-cli
pipx / uv (isolated global tool):
pipx install vac-cli
uv tool install vac-cli
From source, no pipx/uv needed (one-liner):
curl -fsSL https://raw.githubusercontent.com/homeo26/vac/main/install.sh | bash
This creates an isolated venv under ~/.vac and links vac into ~/.local/bin
(uses uv automatically if present). Make sure ~/.local/bin is on your PATH.
From a git checkout (for development):
git clone https://github.com/homeo26/vac.git && cd vac
pip install -e . # or: uv tool install .
Requires Python 3.9+.
pip install vac-clibecomes available once the package is published to PyPI; theinstall.shand git methods work today.
Commands
| Command | What it does |
|---|---|
vac list |
Inventory sessions (size, image count, age, live?, at-risk?). Flags: --older-than 60d, --tool kiro|claude, --sort size|images|updated|age, --json |
vac analyze <id> |
Show what's consuming one session: size, image count, largest entry, active state |
vac clean <id> |
GC image blocks (fixes file-size/payload crashes & the 2000px many-image error). --keep N retains the newest N images. Dry-run unless --apply |
vac prune <id> |
Free ~N% of context tokens from the oldest side (the "compact the first N%" Kiro can't do). --oldest N, --mode outputs|hard, --max-field <chars>. Dry-run unless --apply |
vac doctor |
Flag sessions likely wedged: many images, oversized single entry (context bomb), or oversized session |
vac archive |
tar.gz + remove sessions older than a threshold (by real last-used time). --older-than 60d, --tool, --include-active. Reversible; dry-run unless --apply |
Global safety: clean/prune/archive are dry-run by default, write a .bak, refuse to edit active/locked sessions (use --force), and JSON-validate before writing. Works across Kiro CLI and Claude Code.
Usage examples
vac list # inventory sessions: size, image count, live?, at-risk?
vac analyze <id|path> # what's consuming space in one session
vac clean <id> --keep 3 # GC images, keep the last 3 (dry-run by default)
vac clean <id> --keep 3 --apply # actually write (creates a .bak)
vac prune <id> --oldest 30 # clean ONLY the oldest 30% of the session (dry-run)
vac prune <id> --oldest 30 --apply
vac doctor # find sessions likely wedged (many/oversized images)
vac list --older-than 60d # sessions not used in 60+ days (by real last-used time)
vac archive --older-than 60d # preview archiving old sessions (dry-run)
vac archive --older-than 60d --apply # tar.gz + remove them (reversible)
vac list --json # machine-readable everywhere
Age filtering & archiving
--older-than accepts 60d, 2w, 12h, 30m. Age is computed from each
session's real last-used time (updated_at in metadata), not the file
mtime — so sessions that vac itself rewrote are not misflagged as recent.
vac archive --older-than N tar.gz's every matching session (log + metadata +
history) into ~/.kiro/sessions/vac-archive-<timestamp>.tar.gz and removes the
originals. It's reversible — tar -xzf <archive> -C <dir> restores any
session. Dry-run by default; active/locked sessions are skipped unless
--include-active.
vac prune — free a percentage of the context (by tokens)
Neither Kiro's /compact nor /rewind can free a chosen slice of context from
the start. vac prune --oldest N does: it frees ~N% of the context tokens
(what the context % actually counts — not file bytes) from the oldest side,
walking oldest→newest and cleaning entries until the token target is met.
Modes:
--mode outputs(default) — drop old tool-output bodies / strip images / truncate old tool text, keeping prompts and assistant text. Non-lossy for the dialogue, but frees less if the old region is mostly text (it tells you and suggestshard).--mode hard— also collapse old assistant/prompt text to stubs, guaranteeing it reaches the target. Loses old detail, but genuinely frees the requested %.
It reports tokens freed and % of context; user prompts are kept as anchors; the
result is JSON-validated before writing. Dry-run + .bak by default.
Note: vac clean (image GC) shrinks file bytes — great for payload-size crashes
and disk — but images are cheap in tokens, so use prune (especially --mode hard)
to actually lower the context % and delay auto-compaction.
Safety
- Dry-run by default —
cleannever writes unless you pass--apply. - Automatic backup — writes a
.bakbeside the log (disable with--no-backup). - Won't touch live sessions — refuses to edit a locked/recently-active session unless
--force. - Keeps source paths — cleared images become a text placeholder, and file-based images can simply be re-read.
- Local only — never makes network calls.
Supported tools
| Tool | Store | Image forms handled |
|---|---|---|
| Kiro CLI | ~/.kiro/sessions/cli/*.jsonl |
inline {"kind":"image",...} and tool-result {"Image":{"source":{...}}} (base64 or raw-bytes array) |
| Claude Code | ~/.claude/projects/**/*.jsonl |
{"type":"image","source":{"type":"base64",...}} |
Adapters are pluggable — more tools can be added.
doctor checks
vac doctor flags sessions likely to be wedged:
- Many-image risk — more than ~20 images (Anthropic's stricter 2000px cap).
- Context-bomb entry — any single log entry over ~1 MB (a runaway tool output or embedded image re-sent every turn).
- Oversized session — total size likely to exceed the model's context window.
Each finding prints the exact vac clean … --apply command to fix it.
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file vac_cli-0.1.0.tar.gz.
File metadata
- Download URL: vac_cli-0.1.0.tar.gz
- Upload date:
- Size: 16.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ecdd82217680fa5907a07c3aa74adf7a85d5357445ffdf00ca51be8b5f9b847d
|
|
| MD5 |
e8ad3e0a20ac09599dc7dd4170550e94
|
|
| BLAKE2b-256 |
7a93631ce434d52142160ecc6bb68d9e222aee664755fe7b8129fa6f925ace9c
|
Provenance
The following attestation bundles were made for vac_cli-0.1.0.tar.gz:
Publisher:
publish.yml on homeo26/vac
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vac_cli-0.1.0.tar.gz -
Subject digest:
ecdd82217680fa5907a07c3aa74adf7a85d5357445ffdf00ca51be8b5f9b847d - Sigstore transparency entry: 2592513251
- Sigstore integration time:
-
Permalink:
homeo26/vac@fb483fade6fda3ece2eb0b931d568502f6251bb5 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/homeo26
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fb483fade6fda3ece2eb0b931d568502f6251bb5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file vac_cli-0.1.0-py3-none-any.whl.
File metadata
- Download URL: vac_cli-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d456ab121603a46e4f57ae6919a720e9f8d3585b1033dde74905b16b97fd699c
|
|
| MD5 |
b5c7807f22e1330d9a5a63407aa8c713
|
|
| BLAKE2b-256 |
19613177ce97c8ae7bb5db4176def8823a28eaa96c36600b5198f80a3ba91e6e
|
Provenance
The following attestation bundles were made for vac_cli-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on homeo26/vac
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vac_cli-0.1.0-py3-none-any.whl -
Subject digest:
d456ab121603a46e4f57ae6919a720e9f8d3585b1033dde74905b16b97fd699c - Sigstore transparency entry: 2592513656
- Sigstore integration time:
-
Permalink:
homeo26/vac@fb483fade6fda3ece2eb0b931d568502f6251bb5 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/homeo26
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fb483fade6fda3ece2eb0b931d568502f6251bb5 -
Trigger Event:
push
-
Statement type: