spoilheap
free on / 3.1 GBof 494 GB under the 10 GB guard floor: the agent's next tool call is blocked

SPOILHEAPwhat your coding agents left on this disk

Worktrees, crash dumps, half-written git packs, chat history, SQLite files that never shrink. spoilheap digs a section through all of it, tags every layer SAFE REVIEW or KEEP with the reason, and shovels out only the safe ones.

Read the docs
curl -fsSL https://blackman99.github.io/spoilheap/install.sh | sh

    Section drawn from real spoilheap --json output on the demo home in scripts/demohome.sh: real git worktrees and a real SQLite file; the big files are sparse and the 3.1 GB free is simulated. Layer thickness is to scale; newest on top.

    201context

    What is in the section

    Each agent keeps its own pile in its own place. None of them tells you the total, and the one-click cleaners count the worktree folder as one number and stop there.

    Codex
    ~/.codex/worktrees sessions archived_sessions log .tmp logs_*.sqlite, Crashpad dumps from the desktop app
    Claude Code
    ~/.claude/projects file-history shell-snapshots debug, and .claude/worktrees inside your repos
    OpenCode
    opencode.db (free pages measured from the SQLite header), snapshot/<project> undo repos, log
    Gemini CLI · Cline
    ~/.gemini/tmp; Cline tasks and checkpoint repos in VS Code, Cursor, Windsurf, VSCodium and ~/.cline/data
    Your repos
    tmp_pack_* left by a git that died mid-write, stale worktree registrations, .aider.tags.cache.v4, git-ignored build output inside agent worktrees

    Every path is taken from the agent's own source or docs, and spoilheap paths prints which ones exist on your machine. Hard links count once, symlinks are never followed, and sizes are blocks on disk, not file lengths.

    202context

    Three flags, and why each one is planted

    • SAFE

      Garbage, or rebuildable in one command: crash dumps, a worktree that is clean and whose commits are all on another branch, tag or remote, git-ignored target/ and node_modules/ inside it, tmp_pack_* untouched for an hour, logs older than a day.

    • REVIEW

      Yours to judge: chats older than --older 30d, a worktree with commits that exist nowhere else (it says how many), a worktree touched in the last hour, a worktree git no longer knows about, a SQLite file with hundreds of MB of free pages.

    • KEEP

      Never touched, even if you name it: uncommitted changes, a worktree a running process is sitting in, recent history, a database that is not worth a VACUUM.

    The worktree verdict comes from git itself: status --porcelain, then rev-list HEAD --not --branches --tags --remotes, with optional locks off so it never fights a running agent for index.lock.

    203context

    Shovel only what is safe

    clean prints the plan and stops. Add --yes to do it.

    $ spoilheap clean --safe
    plan (dry run)
      [102] SAFE   Codex crash dumps                              28.5 GB
            → delete 100 entries under ~/Library/Application Support/Codex/Crashpad
            note Codex is crash-looping right now; quit it first or the dumps come straight back
      [107] SAFE   build output target/                            5.0 GB
            → delete ~/.codex/worktrees/c903/payments/target
      [109] SAFE   worktree payments (detached)                      4 KB
            → git -C ~/code/payments worktree remove ~/.codex/worktrees/a41f/payments
      [127] SAFE   payments: 6 half-written git packs             12.0 GB
            → delete 6 entries under ~/code/payments/.git/objects/pack
      … 8 more
    
    dry run: would free 56.5 GB. Nothing was deleted. Run the same command with --yes to do it.
    • Worktrees go through git worktree remove without --force, after a fresh re-check. If git refuses, that item fails with git's reason, the rest go on, and the exit code is 1.
    • Databases are never edited. spoilheap clean 122 prints the VACUUM command and how much free space it needs while it runs.
    • A KEEP item named on the command line is skipped, with its reason.
    • It deletes only inside the folder the item came from, then measures free space again and tells you if the disk got back less than planned (open files, snapshots).
    • Numbers like 104 come from your last spoilheap run, so they always point at what you just read.

    204context

    Catch the layer while it is still growing

    One reported Codex run wrote 263.7 GB of tmp_pack garbage before the disk filled (openai/codex#54955). watch names the folder, the newest file and the process chain writing it.

    $ spoilheap watch --rate 500MB
    watching 6 locations every 10 s · alarm at 500.0 MB/min or under 10.0 GB free · Ctrl-C to stop
    10:36:42  + 240.0 MB      7.2 GB/min  ~/code/payments/.git/objects/pack  RUNAWAY
              newest file: ~/code/payments/.git/objects/pack/tmp_pack_live9f
              writer: python3[1610135] ← bash[1609933] ← node[1525768]
    10:36:44  + 180.0 MB      5.3 GB/min  ~/code/payments/.git/objects/pack  RUNAWAY

    Recorded on the demo home while a script appended to a pack file. Writers come from /proc/*/fd on Linux and lsof on macOS.

    205context

    Stop digging at the datum line

    A full disk does more than stop the build: it has corrupted OpenCode's session database (anomalyco/opencode#56829) and kept even cleanup commands from starting (openai/codex#55038). spoilheap guard runs as a PreToolUse hook and blocks the agent's next tool call when free space falls under your floor.

    $ spoilheap hook claude   # paste into ~/.claude/settings.json
    {
      "hooks": {
        "PreToolUse": [
          {
            "matcher": "Bash|Write|Edit|MultiEdit|NotebookEdit",
            "hooks": [{ "type": "command", "command": "spoilheap guard --floor 10GB", "timeout": 30 }]
          }
        ]
      }
    }

    What the agent sees when it trips (exit code 2, message on stderr):

    spoilheap guard: only 3.1 GB free on the disk holding ~/code/payments (floor 10.0 GB). Stop and
    tell the user before writing anything else: a full disk corrupts agent databases (anomalyco/opencode#56829) and can
    stop even cleanup commands from starting (openai/codex#55038).
    Agent leftovers that are SAFE to delete (56.5 GB in total):
      [102] Codex crash dumps · 28.5 GB · ~/Library/Application Support/Codex/Crashpad
      [127] payments: 6 half-written git packs · 12.0 GB · ~/code/payments/.git/objects/pack
      [110] build output target/ · 6.5 GB · ~/.codex/worktrees/a41f/payments/target
    Ask the user to run: spoilheap clean --safe --yes

    spoilheap hook codex prints the same thing for ~/.codex/config.toml; the exit-code-2 contract was checked against codex-rs/hooks/src/events/pre_tool_use.rs.

    206context

    Let the agent look, not dig

    spoilheap mcp is a read-only MCP server with two tools, disk_status and disk_leftovers. There is no delete tool: the shovel stays with you.

    $ claude mcp add spoilheap -- spoilheap mcp
    # or, any client:  { "mcpServers": { "spoilheap": { "command": "spoilheap", "args": ["mcp"] } } }

    207context

    Install

    $ curl -fsSL https://blackman99.github.io/spoilheap/install.sh | sh   # Linux, macOS; checks SHA-256
    $ cargo install --git https://github.com/Blackman99/spoilheap
    # Windows: spoilheap-v0.1.0-x86_64-pc-windows-msvc.zip (or aarch64-…) from the release page
    $ spoilheap   # look first. It deletes nothing.

    One static binary, no runtime. Linux x86_64 and aarch64 (musl), macOS arm64 and x86_64, Windows x86_64 and arm64. Every archive is listed in checksums.txt. Releases · Docs · Roadmap · MIT.