Install
openclaw skills install @voronindenis5/last-login-janitorUse when you have developer debt - stacks of repos, venvs, node_modules, Docker images, caches, model files - and need to know what is safe to delete. Scans last-access and last-commit times, sizes every artifact, flags stale-vs-protected, and produces size-sorted deletion candidates with one-command cleanup.
openclaw skills install @voronindenis5/last-login-janitorDeveloper machines fill with gigabytes of things nobody has touched in a year: 38 cloned repos (7 abandoned), 22 virtualenvs (14 orphaned - their repos are gone), node_modules directories from failed experiments, 12 versions of the same Docker image, caches that no longer serve any project, and LLM model files from an interest that passed.
The danger of cleanup is deleting the WRONG thing: the venv a cron job uses, the image a stopped-but-important container references, the repo with uncommitted work, the cache that would take 40 minutes to rebuild before tomorrow's demo. That's why people don't clean up - and why disks hit 100%.
This skill makes cleanup decision-safe:
Don't use for: system-package cleanup (apt autoremove territory),
photo/video library organization, or deleting anything you can't rebuild or
re-clone. Always run --dry-run semantics: this skill reports, YOU decide.
| Artifact | Truth signal | Protected when |
|---|---|---|
| Git repo | last commit date (git log -1) | dirty worktree, unpushed branches, stashes, recent commit < stale threshold |
| Python venv | last access (atime) OR mtime of newest .py | referenced by a sibling/parent project modified after venv creation |
| node_modules | mtime of newest file inside | sibling package.json modified recently; sibling node_modules newer than repo staleness |
| Docker image | last container run from it (events/ctimes) | ANY container (running OR stopped) uses it; < N days since pull in active project |
| Docker volume | last mount/write | attached to any container |
| pip cache | dir mtime | modified within cache-warm window (default 14d) |
| npm/pnpm cache | dir mtime | same |
| uv cache | dir mtime | same |
| HF model dir | dir mtime | modified within 30d, or referenced by active config/compose file |
| Build dirs (dist/, target/, build/, .next) | mtime | parent project active |
| IDE indexes (.idea, .vscode+bin) | mtime | project active |
| File | Purpose |
|---|---|
scripts/dev_janitor.py | The scanner/classifier: finds artifacts, dates them, flags stale/protected, emits ranked report + cleanup manifest |
references/cleanup-playbook.md | Safe-deletion rules per artifact type, restore-cost table, command cookbook |
README.md | The problem, in dollars and gigabytes |
# Audit a whole home dir (read-only, always)
python3 scripts/dev_janitor.py scan ~/dev ~/projects --stale-days 180
# Include Docker (requires docker group membership), exclude model dirs
python3 scripts/dev_janitor.py scan ~/ --docker --skip ~/.cache/huggingface
# Emit a ready-to-review cleanup manifest (NOT auto-executed)
python3 scripts/dev_janitor.py scan ~/dev --stale-days 365 --manifest cleanup.json
Output sections: SIZING (bytes per category), STALE candidates (size-sorted, with reason + restore cost), PROTECTED (with why), then a conservative cleanup script printed for human review.
~), narrow later.git checkout/pull touches every file.
Date repos by last COMMIT, not file mtime - the script does this.grep -r venv /etc/systemd).
The script can't see systemd; you must.noatime/relatime;
venv dating falls back to ctime/mtime - treat as "older than reported".tar czf ~/archive/$(basename $r).tgz $r).