agentleFS
mazze93mazze93/claude-code-skills/skills/model-inventory/SKILL.md

model-inventory

Skill1 starsChanged 11 days agoMITView on GitHub

Inventory on-device AI models (Ollama, Hugging Face, LM Studio, MLX, Unsloth and loose .gguf/.safetensors), judge what deleting each would lose — re-downloadable, locally built, fine-tuned, orphaned — and archive to a user-chosen drive with SHA-256 verification before anything is removed. Use when models are eating disk space, before deleting any model, when the user asks "which models do I use", "did I train anything", "is it safe to delete", or when disk-audit hands off its model bucket.

1 other project uses a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

1 rule. About 0 are common, 0 are distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈0

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Only now hand the user the removal command per item.

    line 139

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Model Inventory

Local models look like cache and are not. A pulled model costs a long download to get back; a model you built or fine-tuned cannot be got back at all. This skill finds every model on the machine, says which is which with evidence, and moves the irreplaceable ones to external storage before anyone deletes anything. It never deletes.

The scanner is scripts/model_inventory.py (stdlib Python, no installs).

Ground rules

  • Never assume a drive or a path. The archive destination is always the user's choice, asked fresh each time (see Phase 3). Don't reuse one from memory without asking.
  • Absence of evidence is not evidence of re-downloadability. A model is re-downloadable only when its layer digests match the registry (--check-registry) or it sits in a hub cache. Everything else is unknown-archive-first until the user says where it came from.
  • Deletion is the user's act, item by item. Hand them the exact command (ollama rm <name>, hf cache delete) after the archive is verified. Don't run it unprompted.
  • Other accounts' stores need root. The scan reports them as (unreadable store). Give the user a ! sudo … command to rerun it with output written to a records location they choose, then chmod 644.
  • Reports are records: write them somewhere durable (the user's inbox or records folder), never the session scratchpad.

Phase 1 — Scan (read-only)

python3 -I <skill>/scripts/model_inventory.py scan --check-registry \
  --refs <project-root> [--refs <another-root>] --json <records-dir>/model-scan.json
  • --check-registry makes one read-only GET per Ollama model to its registry and compares layer digests. Without it every Ollama model stays unknown-archive-first. For zero network use --offline, which also skips the /api/ps "loaded now" probe to $OLLAMA_HOST (possibly remote).
  • --refs greps the user's project trees for each model's name — a cheap "is anything wired to this" signal. Ask which roots matter; don't guess.
  • --root (default $HOME) is where it sweeps for training runs and loose weights. It stays on one filesystem and skips Library, CloudStorage, media libraries, node_modules, and the managed stores (inventoried separately). File Provider folders (SSH, S3, Drive) can hang stat() for as long as you let them; never point --root into one.
  • --store DIR adds an Ollama models dir outside the default locations. Stores are never found by globbing a tree, for the same hang reason.
  • Typical runtime: ~10 s for ~100 GB of models with --refs over two project trees. If it runs for minutes at 0% CPU, it is stuck on a mount — sample <pid> shows lstat; kill it and narrow --root.

What it finds:

SourceHow
Ollama$OLLAMA_MODELS, ~/.ollama/models, every /Users/*/.ollama/models (incl. /Users/Shared), --store — manifests parsed, blobs sized, unreferenced blobs flagged, manifest-list runner variants tied to their parent, manifests-v2-only entries surfaced
Hugging Face (incl. MLX, Unsloth bases)$HF_HUB_CACHE, $HF_HOME/hub, ~/.cache/huggingface/hub
LM Studio~/.lmstudio/models, ~/.cache/lm-studio/models — unknown-archive-first (LM Studio keeps no download record), keep-archive-first if training files are inside
Training runsany dir with adapter_config.json, adapter_model.*, trainer_state.json, training_args.bin, or checkpoint-*
Loose weights.gguf / .safetensors / large .bin/.pt outside the managed stores
Linkssymlinks into a store's blobs (e.g. Unsloth Studio's .studio_links) — deleting the model breaks them
In useloaded now from Ollama's /api/ps; references from --refs

Phase 2 — Judge

Verdicts, most precious first:

VerdictMeaningAction
keep-archive-firstAdapter layer, training run, or an Ollama model/tag the registry doesn't have at all (ollama create output, or a since-removed model)Archive before any removal. Ask the user what it is.
unknown-archive-firstCan't prove it's reproducible: no registry check, loose file, unreadable store — or the tag moved upstream (registry serves a different build now)Ask provenance. For a moved tag: the current build re-pulls, this exact one doesn't — usually fine to replace, but the user decides
orphanBlobs no manifest referencesCheck the link evidence; usually safe after ollama is restarted and the blobs are still unreferenced
re-downloadableDigest-verified registry match, or a hub cache entryDelete freely if unused; cost is the download
cloud-stubManifest with no local layers (:cloud tags)Nothing to reclaim

Runner variants (llamacpp:<64-hex> and similar, often hidden from ollama list) are part of their parent's pull — listed in its manifest list — and take the parent's verdict. Never present one as the user's own work.

Also report cross-store duplicates (… of identical blobs also stored in, only when ≥ 1 MiB overlaps) — the same bytes in several stores (e.g. ~/.ollama and /Users/Shared/.ollama). Consolidating to one store with OLLAMA_MODELS frees the copies without losing anything.

last used is deliberately not reported: Ollama keeps no usage log, and access times on APFS are not reliable enough to decide a deletion on. Say so if asked; ask the user which models they actually run.

Present one table: name, size, verdict, the evidence line that decided it, in-use signal. Lead with what can't be got back.

Phase 3 — Archive (only what the user picks)

  1. Ask for the drive. List what's mounted, then ask with AskUserQuestion (one option per volume, plus "Other"):
    for v in /Volumes/*/; do
      v=${v%/}; [ -L "$v" ] || [ "$v" = /Volumes/Recovery ] && continue
      diskutil info "$v" | grep -qE 'Device Location: +External|Removable Media: +Removable' || continue
      printf '%s\t%s free\t%s\n' "$v" "$(df -h "$v" | awk 'NR==2{print $4}')" \
        "$(diskutil info "$v" | awk -F': +' '/File System Personality/{print $2}')"
    done
    Iterate the mount points themselves — parsing df columns breaks on names with spaces (/Volumes/My Passport), and a bare /Volumes/ match also hits /System/Volumes/* and Recovery. /Volumes/Macintosh HD is a symlink to / and is skipped. If nothing external is mounted, say so and stop — don't fall back to an internal path.
  2. Ask for the folder on that volume (offer a sensible default such as <volume>/model-archive, but let them change it).
  3. Copy and verify:
    python3 -I <skill>/scripts/model_inventory.py archive --dest <chosen-dir> \
      --from-json <records-dir>/model-scan.json --item '<id>' [--item '<id>' …]
    It checks free space first and refuses (writing nothing) if the selection won't fit; it fails (exit 1) if any scanned source has vanished since the scan, rather than writing a partial archive that verifies; it archives each Ollama model's full dependency closure (layers, config, manifest-list variants and their layers); links that point outside a copied tree are replaced by verified copies of their targets; Ollama blobs identical across stores are stored once per run and listed under dedup in MANIFEST.json for restore. It copies bytes + mtime only, so exFAT/FAT drives work. It refuses a destination on the same disk as the source (that frees nothing), copies each item under model-archive-<timestamp>/ keeping its absolute layout, checks every file's SHA-256 against the original — and for Ollama blobs, against the hash in the blob's own name — then writes SHA256SUMS and MANIFEST.json. Any mismatch aborts with exit 1.
  4. Re-verify from the drive, independently of the script:
    cd '<archive-run-dir>' && shasum -a 256 -c SHA256SUMS
  5. Only now hand the user the removal command per item. For Ollama, restore is OLLAMA_MODELS=<archive-run-dir>/<original store path> or copying manifests/ and blobs/ back.

Phase 4 — Record

State what was archived where, the verify result, what the user chose to delete, and what was left alone and why. If the user keeps a decision ledger, log the keep/delete decisions there with the evidence line for each.

Limits

  • Registry check covers Ollama registries that speak the Docker v2 manifest API; other hosts report error: and stay unknown-archive-first.
  • Training detection is by marker files. A fine-tune exported straight to a single .gguf with no run directory shows up as loose-weights (unknown-archive-first), not as training — ask.
  • The scan reads as the current user; other accounts need the sudo rerun.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.