Skip to content
Back to skills

Clean Cache

ASecurity

Use when the local `~/.cache/skill-engine/` clone cache should be cleared — to free disk, drop stale git-managed clones or web-doc snapshots, or force a clean re-fetch on the next DISCOVER/REFRESH. Always dry-runs first.

  • 2 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added May 28, 2026
ai-agentsgobashdjangogitdocumentation

Security analysis

A93/100
  • highPerforms destructive filesystem operations

Pro shows the line behind each finding and how to fix it

Scanned September 22, 2026

npx -y skills add nick-railsback/skill-engine --skill clean-cache --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Clean Cache?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Clean Cache
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/nick-railsback-clean-cache/badge)](https://www.skillsdirectory.com/skills/nick-railsback-clean-cache)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: clean-cache
description: Use when the local `~/.cache/skill-engine/` clone cache should be cleared — to free disk, drop stale git-managed clones or web-doc snapshots, or force a clean re-fetch on the next DISCOVER/REFRESH. Always dry-runs 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. <!-- doctrine:legacy-cache-layout --> 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

```bash
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

# Parse optional [kind] argument.
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.

```bash
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"

# Build the list of directories in scope.
if [ -z "$kind" ]; then
  # All kinds + any legacy flat-layout entries at the cache root.
  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")"
  # Skip the kind subdirectories themselves when caught by the bare */ glob.
  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: <size>)?
> [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)

```bash
if [ -z "$kind" ]; then
  # All kinds + legacy flat-layout entries.
  rm -rf -- "$cache_root"/git-managed/*/ "$cache_root"/web-doc/*/
  # Legacy flat entries (anything else directly under cache_root that is
  # a directory but not 'git-managed' or '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
  # ${var:?} on both: an unset or empty cache_root would make this
  # `rm -rf -- //*/`, and this block runs with a user's real HOME.
  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 <size>." 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.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.