$npx -y skills add luongnv89/asm --skill refresh-indexRe-ingest every already-enabled repo in data/skill-index-resources.json: sync the working tree, run preindex, rebuild the catalog for verification, summarize updated/unchanged/failed/skipped, then gate commit + PR behind explicit confirmation. Use when asked to refresh the index,
| 1 | # Refresh Index |
| 2 | |
| 3 | You are refreshing every enabled repository in the ASM curated skill index. The goal is to re-ingest each source so `data/skill-index/{owner}_{repo}.json` reflects the latest upstream state, classify each repo as **updated / unchanged / failed / skipped**, verify the catalog still rebuilds cleanly, and open a single PR that ships only the data changes — with explicit user confirmation before any commit or push. |
| 4 | |
| 5 | This is the inverse of `skill-index-updater`. That skill **adds new repos** from URLs the user supplies. This skill **refreshes the repos that are already enabled** in `data/skill-index-resources.json`. |
| 6 | |
| 7 | ## Repo Sync Before Edits (mandatory) |
| 8 | |
| 9 | Before re-ingesting anything, pull the latest remote branch: |
| 10 | |
| 11 | ```bash |
| 12 | branch="$(git rev-parse --abbrev-ref HEAD)" |
| 13 | dirty=0 |
| 14 | if [ -n "$(git status --porcelain)" ]; then |
| 15 | git stash push -u -m "pre-refresh-index: ${branch}" |
| 16 | dirty=1 |
| 17 | fi |
| 18 | git fetch origin |
| 19 | git pull --rebase origin "$branch" |
| 20 | if [ "$dirty" -eq 1 ]; then |
| 21 | git stash pop || { |
| 22 | echo "✗ Stash pop failed — recover with: git stash list && git stash show -p stash@{0}" |
| 23 | exit 1 |
| 24 | } |
| 25 | fi |
| 26 | ``` |
| 27 | |
| 28 | If `origin` is missing or rebase conflicts occur, **stop and ask the user** before continuing. Never silently overwrite local edits to `data/skill-index/` or `data/skill-index-resources.json`. |
| 29 | |
| 30 | ## Prerequisites |
| 31 | |
| 32 | Verify each before any ingest. Stop and tell the user if any fails. |
| 33 | |
| 34 | - `node` and `npm` on PATH (`command -v node`, `command -v npm`) — required by `npm run preindex` |
| 35 | - `asm` on PATH (`command -v asm`) — invoked transitively by the ingester for `asm eval` |
| 36 | - `gh` on PATH and authenticated (`gh auth status`) — required for PR creation |
| 37 | - `git` on PATH and inside the ASM repo working tree (`git rev-parse --show-toplevel`) |
| 38 | - Network access to `github.com` (each ingest clones the upstream repo) |
| 39 | |
| 40 | ## Pipeline |
| 41 | |
| 42 | Follow these steps in order. Each step has a verification check — do not proceed if the check fails. |
| 43 | |
| 44 | ### Step 1: Enumerate the index |
| 45 | |
| 46 | Read `data/skill-index-resources.json` and split entries into two lists: |
| 47 | |
| 48 | ```bash |
| 49 | ROOT="$(git rev-parse --show-toplevel)" |
| 50 | RES="$ROOT/data/skill-index-resources.json" |
| 51 | ``` |
| 52 | |
| 53 | Use `jq` (or your equivalent JSON reader) to build two lists, keyed on the `source` string (`github:owner/repo`) because that is the identifier `preindex` echoes in its log lines: |
| 54 | |
| 55 | - `enabled[]` — every repo with `"enabled": true`. These will be refreshed. |
| 56 | - `disabled[]` — every repo with `"enabled": false`. These land in the **skipped** bucket up front with reason `"disabled in skill-index-resources.json"`. |
| 57 | |
| 58 | ```bash |
| 59 | jq -r '.repos[] | select(.enabled == true) | .source' "$RES" # e.g. github:anthropics/skills |
| 60 | jq -r '.repos[] | select(.enabled == false) | .source' "$RES" |
| 61 | ``` |
| 62 | |
| 63 | Also derive the on-disk file key (`{owner}_{repo}`) for each enabled repo — this is what `data/skill-index/{owner}_{repo}.json` is named: |
| 64 | |
| 65 | ```bash |
| 66 | jq -r '.repos[] | select(.enabled == true) | "\(.source)\t\(.owner)_\(.repo)"' "$RES" |
| 67 | ``` |
| 68 | |
| 69 | Verification: both lists are non-empty (the index always contains at least one enabled repo and one disabled self-reference). Also validate the existing per-repo JSON is parseable before re-ingesting — a pre-existing corruption otherwise gets masked by the refresh: |
| 70 | |
| 71 | ```bash |
| 72 | jq empty data/skill-index/*.json # exits non-zero if any file is invalid |
| 73 | ``` |
| 74 | |
| 75 | If `enabled[]` is empty or pre-validation fails, stop — there is nothing safe to refresh. |
| 76 | |
| 77 | ### Step 2: Snapshot pre-run skill counts |
| 78 | |
| 79 | Before re-ingesting, record the current `skillCount` for each enabled repo. This lets Step 7 report skill-count deltas. |
| 80 | |
| 81 | ```bash |
| 82 | mkdir -p /tmp/refresh-index |
| 83 | SNAPSHOT="/tmp/refresh-index/pre-snapshot.json" |
| 84 | echo "{}" > "$SNAPSHOT" |
| 85 | for entry in $(jq -r '.repos[] | select(.enabled == true) | "\(.owner)_\(.repo)"' "$RES"); do |
| 86 | file="$ROOT/data/skill-index/${entry}.json" |
| 87 | if [ -f "$file" ]; then |
| 88 | count=$(jq -r '.skillCount // 0' "$file") |
| 89 | jq --arg k "$entry" --argjson v "$count" '. + {($k): $v}' "$SNAPSHOT" > "$SNAPSHOT.tmp" && mv "$SNAPSHOT.tmp" "$SNAPSHOT" |
| 90 | fi |
| 91 | done |
| 92 | ``` |
| 93 | |
| 94 | If a repo is enabled but has no existing index file, treat the pre-count as `0`. The repo will then show up in **updated** with a positive delta in Step 7. |
| 95 | |
| 96 | ### Step 3: Run `npm run preindex` |
| 97 | |
| 98 | Re-ingest every enabled |