vac
🧹 Vacuum up cruft from your AI coding-agent sessions. A small, standalone Python CLI that cleans, prunes, analyzes, archives, and repairs local session logs for Kiro CLI and Claude Code.
Long agent sessions rot over time — embedded screenshots, giant tool outputs, and ever-growing history. Because these agents replay the whole conversation every turn, that bloat causes real failures:
- Oversized images (>2000px) wedge a session:
image dimensions exceed max allowed size for many-image requests: 2000 pixels - Huge embedded payloads crash the load:
Agent connection closed/the selected model cannot continue this conversation - Runaway context triggers premature, quality-killing auto-compaction
- Hundreds of stale sessions quietly eat disk
vac fixes wedged sessions and keeps them lean:
clean— strip embedded images (both Kiro forms + Claude), fixing the 2000px / payload-size crashesprune— free a chosen % of context tokens from the oldest turns (the "compact the first N%" Kiro's/compactand/rewindcan't do)analyze/doctor— see what's eating a session and triage the ones about to breaklist/archive— inventory by age and archive old sessions (reversible)
Everything backs up before writing, refuses to touch live sessions, and JSON-validates the result (and offers --dry-run to preview) — so it never corrupts a session.
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
Homebrew (macOS/Linux):
brew tap homeo26/vac
brew install vac # short form after tapping
# or one-shot without tapping first:
brew install homeo26/vac/vac
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 ".[test]" # or: uv tool install .
Requires Python 3.9+.
Commands
| Command | Options | What it does |
|---|---|---|
vac list |
--older-than <dur> · --tool kiro|claude · --sort size|images|updated|age · --json |
Inventory sessions: size, images, age, live?, at-risk? |
vac analyze <id> |
— | Break down one session: size, image count, largest entry, active? |
vac clean <id> |
--keep N · --dry-run · --force · --no-backup |
Strip embedded images (fixes the 2000px / 100-image / payload crashes). Keeps the newest N (default 3); cleared file-read images keep a re-readable path |
vac prune <id> |
--oldest N · --mode outputs|hard · --max-field <n> · --dry-run · --force · --no-backup |
Free ~N% of context tokens from the oldest turns (hard guarantees the target; outputs keeps text) |
vac prune <id> (Kiro v3) |
--keep-recent N · --cap · --dry-run · --force · --no-backup |
Shorten what the agent already used (tool output, tool/skill definition dumps, inline images) in the part after the last compaction, keeping the newest N% whole; messages and replies are never changed. --cap also turns off auto-compaction for that session |
vac doctor |
--json |
Flag sessions likely wedged: many images, context-bomb entry, or oversized session |
vac name [<id>] |
--include-generic · --llm-cmd "claude -p" · --tool · --limit N · --dry-run |
AI-name untitled sessions from their content (ChatGPT/Claude-style). Uses a local LLM CLI — no API key. Kiro only (writable title store) |
vac archive |
--older-than <dur> · --tool · --include-active · --dry-run |
Archive (tar.gz) + remove sessions older than a threshold — reversible |
<id> = a session id or a path to a .jsonl. <dur> = 60d 2w 12h 30m. Commands that write (clean, prune, name, archive) apply by default — add --dry-run (-n) to preview. They create a .bak, refuse to edit active/locked sessions (--force overrides), and JSON-validate before writing. Works on both Kiro CLI and Claude Code.
vac doctor # triage everything
vac clean <id> --keep 1 # drop old images (add --dry-run to preview)
vac prune <id> --oldest 20 --mode hard # free ~20% of context tokens
vac prune <v3-id> --cap # Kiro v3: trim used tool output, run to 100%
vac archive --older-than 60d # reclaim disk (reversible)
Key concepts
Tokens vs. bytes — which command to use. Kiro's context % counts tokens, not file size. An embedded image is megabytes on disk but only ~1–2K tokens.
- Fixing a file-size problem (2000px image error, "connection closed", disk)?
→
vac clean(removes image bytes). - Lowering the context % / delaying auto-compaction? →
vac prune(removes text tokens).--mode hardguarantees the target;--mode outputsis non-lossy for the dialogue but frees less.
Age is real last-used time. --older-than and the age column use each session's
updated_at metadata, not the file mtime — so sessions that vac itself rewrote
aren't misflagged as recently used. Durations: 60d, 2w, 12h, 30m.
Archiving is reversible. vac archive tar.gz's each session (log + metadata +
history) to ~/.kiro/sessions/vac-archive-<timestamp>.tar.gz; restore with
tar -xzf <archive> -C <dir>.
Images are "lazy", not lost. After the first read, an image's content is
already captured in the model's text reply, so keeping it re-sent every turn
mostly just burns tokens and hits the image caps. vac clean strips them
aggressively (keeps the newest 3 by default) and, for images read from a file,
leaves a placeholder with the source path (re-read /tmp/shot.png …) so the
model can pull the image back on demand if it ever needs the pixels again.
Safety
- Preview with
--dry-run— commands apply by default;-n/--dry-runshows what would change without writing. - 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) |
| Kiro CLI v3 | ~/.kiro/sessions/<workspace>/<id>/messages.jsonl |
file-read stubs (Image: <path>), and base64 images on tool results and pasted prompts |
| 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 … command to fix it.
Development
git clone https://github.com/homeo26/vac.git && cd vac
pip install -e ".[test]"
pytest -q # run the test suite
CI runs the tests on every push/PR (Python 3.9 and 3.12). Releases publish to
PyPI automatically via OIDC Trusted Publishing when a v* tag is pushed — no
tokens stored (see .github/workflows/publish.yml).
License
MIT
Metadata
Release files for vac-cli 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| vac_cli-0.2.0.tar.gz | 28.3 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| vac_cli-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 57.1 kB
Release files / vac_cli-0.2.0.tar.gz
| Download URL | vac_cli-0.2.0.tar.gz |
|---|---|
| Size | 28.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b9cac7def39b5418584c4ab7cc20a9695599976ea0abf97d27f0ce2fccaa7484
|
|
BLAKE2b-256 checksum How to use checksums |
027e2571883bdac5b1c9a704a86ad50b774ddb63b9db289b81b4f09d59a6d694
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logRelease files / vac_cli-0.2.0-py3-none-any.whl
| Download URL | vac_cli-0.2.0-py3-none-any.whl |
|---|---|
| Size | 28.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8731f7ab2b0b84f3f5a7b9cad6b0caca4232b08c83b75c8cb79e165782f0940f
|
|
BLAKE2b-256 checksum How to use checksums |
9ced71b1a9af12813ebaf8fd97ccac37180d3a562aa0b18ff883bcb165c1d9e3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logSecurity for vac-cli 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for vac_cli-0.2.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.