Skip to content

agents-cleanup

Usage
agents-cleanup [-n | --dry-run] [--drop-extras] [-f | --force] [--marker-file]
[-v | --verbose] [-q | --quiet] [-s | --silent] [-h | --help]

Reverses agents-init in the current project, and marks the project so agents-init – and therefore every claude/agy launch – leaves it alone from then on.

Every symlink that resolves into AGENTS/ is replaced by the real file or directory it points to. When two links share a target (docs/plans and docs/superpowers/plans), the shallower one receives the content and the other is removed; a link to a target holding only .gitkeep, a dangling link, or a link to AGENTS/ itself is removed with nothing put in its place. Inside a git repository, dangling links are removed even when AGENTS/ is already gone; outside git with no AGENTS/ the links are not inventoried at all, because the current directory is only a guess at the project root. An AGENTS.md that is exactly the stub agents-init writes is deleted; any other AGENTS.md loses only the SYSTEM DIRECTIVE blockquote that pointed agents at AGENTS/AGENTS.md. No CLAUDE.md is recreated.

In a public-mode project the public AGENTS.md files are the project’s own and are never touched. Each AGENTS.local.md link is restored like any other (deleted instead when it is exactly agents-init’s local stub, and stripped of its directive otherwise), and because the agents-init .gitignore blocks are removed, a restored AGENTS.local.md is kept ignored by a standalone line: it holds private instructions. The AGENTS/<dir>/AGENTS.md links that point back out at the public files are not counted as unlinked files.

Before anything is moved, pending AGENTS/ changes are committed and the full history is written to a verified git bundle under $XDG_STATE_HOME/agents-cleanup/ (default ~/.local/state). AGENTS/ is then removed, along with docs/superpowers/ and docs/ if left empty, and every “Added by agents-init” block is stripped from .gitignore. Nothing is committed to the outer repository.

A damaged AGENTS/.git (present but not a valid repository, e.g. HEAD gone with the objects left) cannot be bundled, so the cleanup refuses before anything changes: repair it, or pass --force to remove AGENTS/ without an archive. With --force the damaged .git is treated as “not a repository” and removed with AGENTS/, and a warning on stderr says that its history is not archived (suppressed by --silent only). --dry-run refuses the same way, unless --force is also given.

Files inside AGENTS/ that no project symlink points to – other than agents-init’s own .version, .agents-tools/ and .gitkeep files – stop the cleanup before anything changes. They are listed; --drop-extras discards them instead. A nested git repository inside AGENTS/ is always refused, --drop-extras or not: the bundle keeps only a pointer to it, so move it out first. One inside a directory a kept link restores travels out with it, but only if it has a commit: a nested repository with no commits (and not ignored by AGENTS/) cannot be recorded by the final AGENTS/ commit, so it is refused by path too – commit something in it, or remove its .git. --dry-run refuses the same way.

The disabled marker is the per-clone git config key agents-init.disabled, set on every run. --marker-file also writes .agents-disabled in the project root, which agents-init honors too and which may be committed to opt every clone out; it is the only marker available outside a git repository, where the project root is taken to be the current directory – run it from there. In a project with no AGENTS/, the marker is set – a pre-emptive opt-out – and, inside git, any dangling AGENTS/ links and agents-init .gitignore blocks are removed as well; outside git there is no link inventory, so only the marker and any .gitignore blocks are touched. agents-init --enable clears the git key again.

Re-running is safe: an interrupted cleanup resumes where it stopped, and a finished one only confirms the marker.

-n, --dry-run Print the plan and change nothing
--drop-extras Discard unlinked files in AGENTS/ instead of refusing
-f, --force Remove AGENTS/ even though its .git is damaged (no archive)
--marker-file Also write .agents-disabled (required outside git)
-v, --verbose Print all per-step output (default)
-q, --quiet Print one summary line only if changes were made
-s, --silent Suppress all output; errors only
-h, --help Show this help message and exit
0 Cleanup finished, or nothing was left to do
1 Refused (outside git without --marker-file, unresolved rebase in AGENTS/, unlinked files or a nested repository in AGENTS/, a nested repository with no commits inside a restored directory, a damaged AGENTS/.git without --force) or a step failed
2 Unknown option

Restore an archived AGENTS/ from the project root: delete .agents-disabled if present, git clone <bundle> AGENTS, drop the clone’s origin (git -C AGENTS remote remove origin), delete every path the cleanup reported as “Restored” – agents-init will not replace a real file that differs from its AGENTS/ copy, and a restored AGENTS.md always differs – then agents-init --enable. The full write-up – what is kept, what is removed, and how the markers interact – is in docs/manual/17-agent-tooling.md. Update that section in the same change whenever this function’s behavior changes.

Terminal window
agents-cleanup --dry-run
agents-cleanup
agents-cleanup --marker-file

Dependencies: _agents_init_find, _agents_init_stub, _agents_repo_slug, _agents_repo_sync

Classification: destructive, self-limiting(rm,mkdir,grep), bypasses-shadow(mv), manual-section(17-agent-tooling)

See also: 17. AI AGENT TOOLING