| name | clean-cache |
| description | Delete the skill-engine clone cache (`~/.cache/skill-engine/`), with a dry-run preview first. |
Clean cache
Opt-in destructive command. Deletes the persistent local clone cache that DISCOVER and REFRESH populate under ~/.cache/skill-engine/. Always dry-runs first; only deletes after explicit user confirmation.
Usage
/skill-engine:clean-cache [kind]
kind is optional:
- omitted → clean every cache subtree under
~/.cache/skill-engine/,
including old flat-layout entries.
git-managed → clean only ~/.cache/skill-engine/git-managed/.
web-doc → clean only ~/.cache/skill-engine/web-doc/.
Always prompts with a list of directories before deletion. No deletion
happens without confirmation.
What gets deleted
Everything under ${XDG_CACHE_HOME:-$HOME/.cache}/skill-engine/. The cache is partitioned by source kind:
~/.cache/skill-engine/git-managed/<source_id>-<sha>/ — shallow clones of git-backed upstream sources at a specific SHA.
~/.cache/skill-engine/web-doc/<source_id>-<crawl_id>/ — snapshots of crawled web documentation for a specific crawl.
Old flat-layout entries (~/.cache/skill-engine/<source_id>-<sha>/) may still exist if they predate the kind-partitioned layout and have not yet been migrated by REFRESH; this command will clean them too. The cache is regenerable: a subsequent DISCOVER or REFRESH against the same upstream re-creates whatever it needs from gh/git or the web crawler.
Nothing outside the cache root is touched. No contextualizer state (.claude/skills/<slug>-context/, including its research/ and references/ directories) is touched. No user files outside ~/.cache/skill-engine/ are touched.
Workflow
cache_root="${XDG_CACHE_HOME:-$HOME/.cache}/skill-engine"
if [ ! -d "$cache_root" ]; then
printf '%s\n' "Cache root not present at $cache_root — nothing to clean."
exit 0
fi
kind="${1:-}"
case "$kind" in
""|git-managed|web-doc) ;;
*)
printf 'ERROR: invalid kind %q (expected: git-managed, web-doc, or omitted)\n' "$kind" >&2
exit 2
;;
esac
Step 1: Dry-run preview
List the entries that would be deleted, scoped by $kind if set. Default to dry-run only — emit the list without deleting.
total=$(du -sh "$cache_root" 2>/dev/null | awk '{print $1}')
printf '%s\n' "Cache root: $cache_root"
[ -n "$kind" ] && printf '%s\n' "Kind filter: $kind"
printf '%s\n' "Total size: ${total:-0}"
printf '\n%-60s %8s %s\n' "Directory" "Size" "Last accessed"
if [ -z "$kind" ]; then
scan_globs=( "$cache_root"/git-managed/*/ "$cache_root"/web-doc/*/ "$cache_root"/*/ )
else
scan_globs=( "$cache_root/$kind"/*/ )
fi
for d in "${scan_globs[@]}"; do
[ -d "$d" ] || continue
base="$(basename "$d")"
if [ -z "$kind" ]; then
[ "$base" = "git-managed" ] && continue
[ "$base" = "web-doc" ] && continue
fi
sz=$(du -sh "$d" 2>/dev/null | awk '{print $1}')
accessed=$(stat -f '%Sa' -t '%Y-%m-%d' "$d" 2>/dev/null \
|| stat -c '%x' "$d" 2>/dev/null | cut -d' ' -f1)
name="${d#"$cache_root"/}"
name="${name%/}"
printf '%-60s %8s %s\n' "$name" "$sz" "$accessed"
done
Surface the listing and ask the user to confirm. The confirmation phrasing should make the destructive scope explicit and name the kind filter when set:
Delete the listed directories (total: )?
[if kind set:] Filter: only <kind> cache subtree.
Reply yes to proceed, anything else to abort.
If the user does not reply with the literal word yes, abort without deleting.
Worked example. A typical dry-run with no kind filter, surfaced before the confirmation prompt, looks like:
Cache root: /Users/me/.cache/skill-engine
Total size: 135M
Directory Size Last accessed
git-managed/django-django-cccc3333 31M 2026-04-28
git-managed/vitejs-vite-aaaa1111 52M 2026-05-11
git-managed/vitejs-vite-bbbb2222 52M 2026-05-12
web-doc/anthropic-docs-eeee5555 42M 2026-05-15
legacy-flat-dddd4444 18M 2026-03-02
Delete the listed directories (total: 135M)?
A subsequent /skill-engine:discover or /skill-engine:refresh against any of
these sources will re-clone or re-crawl from upstream when run.
Reply `yes` to proceed, anything else to abort.
Two directories with the same <source_id> prefix (here, vitejs-vite-*) indicate REFRESH has not yet GC'd the older SHA — the older directory is stale and safe to remove. Entries directly under the cache root (here, legacy-flat-dddd4444) are pre-migration flat-layout cache; REFRESH's pre-flight step 1.5 normally relocates them on the next run.
When invoked with a [kind] argument, the preview lists only that subtree:
$ /skill-engine:clean-cache web-doc
Cache root: /Users/me/.cache/skill-engine
Kind filter: web-doc
Total size: 42M
Directory Size Last accessed
web-doc/anthropic-docs-eeee5555 42M 2026-05-15
Step 2: Deletion (only after confirmation)
if [ -z "$kind" ]; then
rm -rf -- "$cache_root"/git-managed/*/ "$cache_root"/web-doc/*/
for d in "$cache_root"/*/; do
[ -d "$d" ] || continue
base="$(basename "$d")"
[ "$base" = "git-managed" ] && continue
[ "$base" = "web-doc" ] && continue
rm -rf -- "$d"
done
else
rm -rf -- "$cache_root/$kind"/*/
fi
Notes:
- The
-- guards against any subdirectory name starting with -.
- Do NOT delete the cache root itself, nor the
git-managed/ or web-doc/ kind subdirectories themselves — only their children.
- Do NOT follow symlinks. The
*/ glob expands only to directories, but be conservative: a symlinked directory should be inspected before deletion. If unsure, skip it.
- Do NOT delete anything outside the cache root, ever. The literal string
${XDG_CACHE_HOME:-$HOME/.cache}/skill-engine/ must appear verbatim in the deletion path; never substitute, never accept user-supplied paths beyond the validated kind enum.
Step 3: Post-clean summary
After deletion, emit a one-line summary: "Deleted N directories, freed ." If a subsequent DISCOVER or REFRESH runs, it will re-clone or re-crawl from upstream into a fresh kind-partitioned directory (~/.cache/skill-engine/git-managed/<source_id>-<sha>/ or ~/.cache/skill-engine/web-doc/<source_id>-<crawl_id>/).
When to suggest this command
The user may want to clean the cache when:
- A contextualizer is finished and no REFRESH cycles are planned.
- Disk usage is a concern and
/skill-engine:status shows accumulated cache directories.
- The user has rotated to a different project and the cached sources are no longer relevant.
This command is opt-in: nothing in the engine invokes it automatically.
What this skill does NOT do
- It does not delete contextualizer state (no
.claude/skills/*-context/ directory is touched).
- It does not delete
source-paths.json or any references/ files.
- It does not unregister sources.
- It does not delete
~/.cache/skill-engine/ itself, only its immediate children.
- It does not run DISCOVER or REFRESH afterward — the user runs those separately when ready.
Invariants
- Dry-run is the default; deletion requires explicit
yes.
- Deletion scope is bounded to
${XDG_CACHE_HOME:-$HOME/.cache}/skill-engine/*/.
- No network access. No state writes to any contextualizer. Read-then-delete only.