Cleanup
A dry-run-first storage cleanup planner — inspectable plans and reports before any destructive command or path deletion runs.
Problem
Disk cleanup scripts are dangerous by default. rm -rf with a typo, shell-string command injection, and silent partial failures turn maintenance into incident response. Most tools optimize for speed, not reversibility.
Cleanup separates planning from application. cleanup plan never mutates the filesystem. cleanup apply consumes an immutable plan artifact and executes argv arrays through a central path executor.
Safety model
- Plan and doctor commands that scan targets without writing deletes
- Immutable plan JSON artifacts stored under
.cleanup/planswith matching reports - argv-array command execution — no shell-string interpolation
- Built-in storage targets for duplicates, empty directories, bad extensions, and container volumes
- Explicit
--yesgate on apply plus--dry-runfor mutation rehearsal
export const defaultPlanDirectory = (cwd: string): string =>
path.join(cwd, DEFAULT_ARTIFACT_DIRECTORY, PLAN_DIRECTORY_NAME);
export const writeCleanupPlan = async (plan: CleanupPlan, filePath: string): Promise<string> => {
await mkdir(path.dirname(filePath), { recursive: true });
await writeArtifactFile(filePath, plan);
return filePath;
};
export const readCleanupPlan = async (filePath: string): Promise<CleanupPlan> => {
const parsed = await readJsonObject(filePath);
assertCleanupPlanArtifact(parsed, filePath);
return parsed as unknown as CleanupPlan;
};