Repository navigation
Output GC
This page describes how the core plugin claudetto records the files that a session makes outside the project, and how it removes the files that nothing uses.
It is for a user who wants to know what the sweep removes and for a contributor who edits the gc slice.
Claude and its agents make folders and files outside the project: mktemp folders, worktrees, repository copies, sandbox config folders, and scratch files.
Nobody removes them, so they fill the disk.
The gc slice records each one when a session makes it, and a sweep removes the ones that nothing uses.
A tool.call hook watches the Bash and Write tools.
It records these outputs:
| Kind | Source |
|---|---|
temp |
The path that mktemp prints. |
worktree |
The path of git worktree add. |
copy |
The target of git clone and cp -r. |
config |
The value of CLAUDE_CONFIG_DIR= in a command. |
scratch |
The file of a Write call inside a temp folder. |
A path that starts with ~ or $ is not recorded, because the hook cannot expand it.
Each record holds the path, the kind, the session id, the time, and the working folder.
The records of one session are in ~/.claudetto/gc/<session id>.json.
The sweep removes a path only when all these rules are true:
- The path is in a record.
- The path is strictly inside an allowed root.
The roots are the temp folder of the user and the
.claude/worktrees/folder of the project where the session ran. - The path is not a symlink, and no part of its real path leaves the root.
- No live session needs it.
A session is live when its file in
sessions/of the config folder names a running process. A path stays when it belongs to a live session, or when the folder of a live session is inside it. - The path is older than 7 days. After that, the sweep removes the oldest unused paths until the unused paths take at most 5 GiB.
The sweep never removes a path by a name pattern.
A path that is outside each root, or that is a symlink, stays.
The report names it with the status skip, and its record is dropped.
After a removed worktree, the sweep runs git worktree prune in the project.
The two bounds are in Bounds.
- At session start, in the
session.starthook. - At session end, in the
session.endhook. The ending session does not count as live, so its own outputs can go when they are old enough. The sweep stays under the time budget that Claude Code leaves at the end of a session. - On request, with the bin
claudetto-gcor the command/claudetto:gc.
The hooks write the report to the debug log. A report names each path with its size, the count of removed paths, and the space that the sweep freed.
claudetto-gc --dry-runThe dry run lists each path with its size and the total. It removes nothing and changes no record. Run it before the first sweep to see what the sweep removes.
- Bounds: the age bound and the size bound.
- Architecture: the slices of the core plugin.
- Start
- How claudetto Works
- Add-On Plugins
- How Claude Code Works
- Reference
- Rationale
- Evidence
- Development
- Archive