# DiskSaver

> Safely free internal disk space by discovering large directories, classifying cleanup and external-disk mapping candidates, clearing rebuildable caches, offloading large bundles to external storage, and recording cleanup or symlink mapping actions with explicit user confirmation.

- Skill: `xue-xiaobao/disksaver` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add xue-xiaobao/disksaver`
- Raw SKILL.md: https://api.skillmd.com/api/skills/xue-xiaobao/disksaver/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: xue-xiaobao (https://skillmd.com/u/xue-xiaobao)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/xue-xiaobao/disksaver

---


# DiskSaver

Use this skill to free internal disk space by clearing rebuildable caches, cleaning temporary leftovers, or offloading space-heavy directories onto an external disk with a symbolic link in place.

Prefer deterministic execution through `scripts/disk_saver.py`. Keep user data safe: never perform a write operation unless the user has explicitly confirmed the exact checklist.

Write operations include: creating config, deleting/clearing cache contents, moving directories, creating symlinks, and replacing directories with mapped locations.

## Workflow

1. Discover large directories and decide whether the user has a writable external disk.
2. Classify each target directory.
3. Dry-run the plan for every target (`plan-clean` for cleanup, `plan` for mapping/migration).
4. Check app/process ownership and ask the user to quit apps when needed.
5. Present a batch checklist of every write operation and wait for explicit user confirmation.
6. Run the confirmed operation with `--confirmed`.
7. Verify cleanup results or symlinks, disk space when relevant, and recorded state.

## External Disk Setup

If config is missing or the user wants to change disks, first list candidates:

```bash
python3 scripts/disk_saver.py discover-targets
```

Ask the user to choose or approve a storage root. Then initialize only after confirmation:

```bash
python3 scripts/disk_saver.py init --storage-root "<external-root>" --create --confirmed
```

The selected storage root is stored for future runs:

- Config: `~/.config/disk-saver/config.json`
- State: `~/.local/state/disk-saver/migrations.json`
- Legacy fallback: reads `external-disk-mapper` config/state if the new paths do not exist.

Before any migration, the script checks that the configured storage root exists, is writable, and has enough free space for preserve-mode migrations.

## Operation Modes

Use the right mode for the data type:

- `clean-cache`: for recreatable caches when no external disk is available or the user wants a one-time cleanup. It deletes directory contents but keeps the directory itself.
- `empty-map`: for recreatable caches and build artifacts. It deletes current cache contents, creates an empty mapped directory, then future cache writes go to the external disk.
- `migrate`: for large assets that may be costly or risky to rebuild. It preserves current contents by moving them to the external disk.
- direct cleanup: for system temp leftovers such as `code_sign_clone` or `ShipIt.*`; these should be deleted after process checks, not mapped.

Rule of thumb:

> No external disk: `clean-cache`; rebuildable cache with external disk: `empty-map`; large model/runtime bundle: `migrate`; profile, container, database, chat history, or system path: do not map by default.

## Commands

Run the script directly:

```bash
python3 scripts/disk_saver.py discover-targets
python3 scripts/disk_saver.py init --storage-root "<external-root>/disk-saver/$USER/data" --create --confirmed
python3 scripts/disk_saver.py plan-clean --source "$HOME/Library/Caches/ms-playwright"
python3 scripts/disk_saver.py clean-cache --source "$HOME/Library/Caches/ms-playwright" --confirmed
python3 scripts/disk_saver.py plan --source "$HOME/Library/Caches/ms-playwright"
python3 scripts/disk_saver.py empty-map --source "$HOME/Library/Caches/ms-playwright" --confirmed
python3 scripts/disk_saver.py migrate --source "$HOME/Library/Application Support/App/large-runtime-bundle" --allow-caution --confirmed
python3 scripts/disk_saver.py status
```

## Confirmation Contract

Never run `init`, `clean-cache`, `empty-map`, `migrate`, `rm`, `mv`, or symlink writes until the user confirms a checklist that includes:

- source path
- destination path
- operation mode (`clean-cache`, `empty-map`, `migrate`, or cleanup)
- estimated size
- classification (`safe`, `caution`, `avoid`)
- apps/processes that should be stopped
- expected data loss, if any

The bundled script enforces this by requiring `--confirmed` for write commands. This flag means the user has already approved the displayed checklist; do not use it as a shortcut.

## Safety Rules

Always run `plan-clean` or `plan` first for a new target.

Use `references/safety-matrix.md` to decide whether a path is:

- `safe`: caches, build outputs, recreatable artifacts
- `caution`: app data that may need the app stopped first
- `avoid`: system paths, containers, message/mail stores, VM areas, broad home directories

If the target is under `Application Support`, browser profiles, IDE indexes, or simulator data, check `references/safety-matrix.md` before migrating and usually stop the corresponding app first. For suspicious active paths, use `ps` and `lsof +D <path>` before writing.

## Operational Notes

The script preserves the relative source path under the configured storage root. Example:

- Source: `<home>/Library/Caches/ms-playwright`
- Storage root: `<external-root>/disk-saver/<user>/data`
- Destination: `<external-root>/disk-saver/<user>/data/<home-without-leading-slash>/Library/Caches/ms-playwright`

The script refuses to overwrite an existing destination unless `--force` is passed and the destination is empty.

The script records each cleanup or migration in the state file with source, category, mode, source size, timestamp, and symlink status when relevant.

## References

- Read `references/safety-matrix.md` when deciding whether a target is safe to migrate.
- Read `references/state-files.md` when updating config or migration records.

