Agent Skillsluongnv89/asm › refresh-index

refresh-index

GitHub

批量重新索引已启用的技能仓库,同步代码、重建目录并生成PR。用于维护现有索引数据一致性,区别于新增仓库或单个技能优化。

skills/refresh-index/SKILL.md luongnv89/asm

Trigger Scenarios

刷新索引 重新摄入已索引仓库 批量维护已索引技能源

Install

npx skills add luongnv89/asm --skill refresh-index -g -y
More Options

Use without installing

npx skills use luongnv89/asm@refresh-index

指定 Agent (Claude Code)

npx skills add luongnv89/asm --skill refresh-index -a claude-code -g -y

安装 repo 全部 skill

npx skills add luongnv89/asm --all -g -y

预览 repo 内 skill

npx skills add luongnv89/asm --list

SKILL.md

Frontmatter
{
    "name": "refresh-index",
    "effort": "high",
    "license": "MIT",
    "metadata": {
        "author": "luongnv89",
        "version": "1.0.0"
    },
    "description": "Re-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, re-ingest indexed repos, or batch-maintain already-indexed skill sources. Don't use for adding new repos (use skill-index-updater), improving a single skill (use skill-auto-improver), or installing\/updating skills on the local machine (use asm install or asm update).",
    "allowed-tools": "Bash Read Write Edit Grep Glob",
    "compatibility": "Claude Code"
}

Refresh Index

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.

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.

Repo Sync Before Edits (mandatory)

Before re-ingesting anything, pull the latest remote branch:

branch="$(git rev-parse --abbrev-ref HEAD)"
dirty=0
if [ -n "$(git status --porcelain)" ]; then
  git stash push -u -m "pre-refresh-index: ${branch}"
  dirty=1
fi
git fetch origin
git pull --rebase origin "$branch"
if [ "$dirty" -eq 1 ]; then
  git stash pop || {
    echo "✗ Stash pop failed — recover with: git stash list && git stash show -p stash@{0}"
    exit 1
  }
fi

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.

Prerequisites

Verify each before any ingest. Stop and tell the user if any fails.

  • node and npm on PATH (command -v node, command -v npm) — required by npm run preindex
  • asm on PATH (command -v asm) — invoked transitively by the ingester for asm eval
  • gh on PATH and authenticated (gh auth status) — required for PR creation
  • git on PATH and inside the ASM repo working tree (git rev-parse --show-toplevel)
  • Network access to github.com (each ingest clones the upstream repo)

Pipeline

Follow these steps in order. Each step has a verification check — do not proceed if the check fails.

Step 1: Enumerate the index

Read data/skill-index-resources.json and split entries into two lists:

ROOT="$(git rev-parse --show-toplevel)"
RES="$ROOT/data/skill-index-resources.json"

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:

  • enabled[] — every repo with "enabled": true. These will be refreshed.
  • disabled[] — every repo with "enabled": false. These land in the skipped bucket up front with reason "disabled in skill-index-resources.json".
jq -r '.repos[] | select(.enabled == true)  | .source' "$RES"   # e.g. github:anthropics/skills
jq -r '.repos[] | select(.enabled == false) | .source' "$RES"

Also derive the on-disk file key ({owner}_{repo}) for each enabled repo — this is what data/skill-index/{owner}_{repo}.json is named:

jq -r '.repos[] | select(.enabled == true) | "\(.source)\t\(.owner)_\(.repo)"' "$RES"

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:

jq empty data/skill-index/*.json   # exits non-zero if any file is invalid

If enabled[] is empty or pre-validation fails, stop — there is nothing safe to refresh.

Step 2: Snapshot pre-run skill counts

Before re-ingesting, record the current skillCount for each enabled repo. This lets Step 7 report skill-count deltas.

mkdir -p /tmp/refresh-index
SNAPSHOT="/tmp/refresh-index/pre-snapshot.json"
echo "{}" > "$SNAPSHOT"
for entry in $(jq -r '.repos[] | select(.enabled == true) | "\(.owner)_\(.repo)"' "$RES"); do
  file="$ROOT/data/skill-index/${entry}.json"
  if [ -f "$file" ]; then
    count=$(jq -r '.skillCount // 0' "$file")
    jq --arg k "$entry" --argjson v "$count" '. + {($k): $v}' "$SNAPSHOT" > "$SNAPSHOT.tmp" && mv "$SNAPSHOT.tmp" "$SNAPSHOT"
  fi
done

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.

Step 3: Run npm run preindex

Re-ingest every enabled repo via the project's preindex script. Capture both stdout and the exit code — preindex exits 1 if any repo fails, but do not abort the run. We still want partial results so the summary can show what succeeded.

LOG="/tmp/refresh-index/preindex.log"
cd "$ROOT"
set +e
npm run preindex 2>&1 | tee "$LOG"
PREINDEX_EXIT=$?
set -e

Verification: the log file exists and contains one line per enabled repo formatted as either {source} ... {N} skills (success) or {source} ... FAILED: {error} (failure), where {source} matches the github:owner/repo strings from Step 1. If the log is empty or no line matches, stop and surface the error.

Step 4: Classify each repo

Build per-repo status from three signals — the preindex log, git diff on data/skill-index/, and the disabled[] list from Step 1.

DIFF_FILES=$(git diff --name-only -- data/skill-index/ | sort -u)

For each enabled repo, match the preindex log line by its {source} string (github:owner/repo) and look up the on-disk file by {owner}_{repo}:

Signal in preindex.log (per {source} line) data/skill-index/{owner}_{repo}.json in git diff Bucket
{source} ... N skills yes updated
{source} ... N skills no unchanged
{source} ... FAILED: ... (either) failed (capture error message)
(no line for this {source}) (either) failed (capture as "no output from preindex")

For each disabled[] repo: skipped with the disabled reason.

Capture each repo's post-run skillCount by reading the (possibly updated) data/skill-index/{owner}_{repo}.json. For failed repos, post-count = pre-count (no change on disk).

Step 5: Rebuild the website catalog (verification only)

Run the catalog build to confirm the refreshed index is structurally valid. website/catalog.json is gitignored — never stage it. A failure here means the data files are internally inconsistent and the PR must not land.

cd "$ROOT"
npx tsx scripts/build-catalog.ts

Verification: the script exits 0 and website/catalog.json is valid JSON (jq empty website/catalog.json). If it fails, stop the pipeline — investigate the data issue before committing anything.

Step 6: Detect unexpected diff scope

Confirm the only files that changed are the ones we expect — per-repo data under data/skill-index/ and, only if the user explicitly bumped the top-level updatedAt, data/skill-index-resources.json:

UNEXPECTED=$(git diff --name-only \
  | grep -v -E '^data/skill-index/' \
  | grep -v -E '^data/skill-index-resources\.json$' \
  || true)
if [ -n "$UNEXPECTED" ]; then
  echo "⚠ Unexpected files in diff:"
  printf '%s\n' "$UNEXPECTED"
  # stop and surface to user
fi

Note: npm run preindex does not modify data/skill-index-resources.json — it only writes per-repo files under data/skill-index/. The resources file should only appear in the diff if the user is also refreshing the top-level updatedAt timestamp (optional — leave it alone unless asked).

If unexpected files appear (e.g. someone left edits in src/ or skills/), stop and tell the user. Do not commit a mixed change.

Step 7: Print the four-bucket summary

Render a markdown table grouped by bucket, with skill-count deltas. This is what the user reads to decide whether to confirm the PR.

## Refresh summary — N repos processed

### ✓ Updated (X)
| Repo | Before | After | Δ |
|------|--------|-------|---|
| anthropics/skills | 14 | 15 | +1 |
| obra/superpowers  | 22 | 22 |  0 |

### · Unchanged (Y)
| Repo | Skills |
|------|--------|
| owner1/repo1 | 7 |

### ✗ Failed (Z)
| Repo | Error |
|------|-------|
| owner2/repo2 | clone failed: 404 Not Found |

### ○ Skipped (W)
| Repo | Reason |
|------|--------|
| luongnv89/asm | disabled in skill-index-resources.json |

If X + Y + Z + W does not equal len(enabled) + len(disabled), the classification is inconsistent — stop and re-check Step 4 before moving on.

Step 8: Confirmation gate, commit, and PR

Do not proceed without explicit user confirmation. Print the diff stat and ask:

git diff --stat -- data/skill-index/ data/skill-index-resources.json
echo
echo "Ready to commit the files above and open a PR."
echo "Type 'yes' to continue, anything else to abort."

On yes (and only yes), stage only the index data files — never website/catalog.json, never anything outside data/skill-index/ — commit with the conventional-commit message below, push, and open the PR:

git add data/skill-index/
# Only add the resources file if it was intentionally modified (e.g., updatedAt bump):
if git diff --name-only | grep -q '^data/skill-index-resources\.json$'; then
  git add data/skill-index-resources.json
fi

git commit -m "$(cat <<'EOF'
chore(index): refresh indexed skill sources

Re-ingested all enabled repos in data/skill-index-resources.json.

Updated: <X> repo(s)
Unchanged: <Y> repo(s)
Failed: <Z> repo(s)
Skipped: <W> repo(s)
EOF
)"

branch="$(git rev-parse --abbrev-ref HEAD)"
git push -u origin "$branch"

gh pr create --title "chore(index): refresh indexed skill sources" --body "$(cat <<'EOF'
## Summary
Re-ingested all enabled repos in `data/skill-index-resources.json` to bring the catalog up to date with upstream.

## Results
- **Updated:** <X> repo(s)
- **Unchanged:** <Y> repo(s)
- **Failed:** <Z> repo(s) (see body for details)
- **Skipped:** <W> repo(s) (disabled in resources file)

### Updated repos
| Repo | Before | After | Δ |
|------|--------|-------|---|
| ... | ... | ... | ... |

### Failed repos
| Repo | Error |
|------|-------|
| ... | ... |

## Test Plan
- [ ] `data/skill-index/*.json` files are valid JSON
- [ ] `npx tsx scripts/build-catalog.ts` rebuilds `website/catalog.json` without errors
- [ ] No files outside `data/skill-index/` and `data/skill-index-resources.json` are staged
- [ ] CI passes
EOF
)"

Fill the <X> / <Y> / <Z> / <W> placeholders and the per-bucket tables with the actual numbers from Step 7 before running gh pr create.

Verification: gh pr view --json url returns the new PR URL. Print it back to the user.

Edge Cases & Error Handling

Each row names a condition, the step that owns it, and the required response. When two rows touch the same guardrail (never stage website/catalog.json; yes-only gate), honor it at every point of action — the cost of forgetting mid-run is a bad push.

Condition Response
No enabled repos (enabled[] empty) Stop in Step 1 — nothing to refresh.
Pre-existing corrupt data/skill-index/*.json Step 1 jq empty catches it — stop before the refresh masks it.
Existing local edits to data/skill-index/ The mandatory pre-edit stash captures them; if the post-run pop conflicts, follow the recovery hint in the stash block and stop.
A single upstream repo unreachable (404, network blip) preindex marks it FAILED and continues; it lands in failed. The PR still ships the rest.
All upstream repos fail (no network, outage) Every repo lands in failed; the diff is empty; stop before Step 8 — nothing to commit.
Ingest produces zero skillCount (upstream removed every SKILL.md) Treat as updated with a negative delta — a real change worth shipping.
preindex errors before any log line Stop in Step 3 — environmental, not per-repo. Prompt npm install and retry.
preindex exits 1 with a partial log Continue to Step 4 — partial results are still useful.
build-catalog fails after preindex Stop in Step 5 — the index is internally inconsistent. Investigate before committing.
website/catalog.json in git status It is gitignored; if .gitignore broke, fix it. Never git add website/catalog.json.
Unexpected files in the diff (WIP in src/, skills/) Stop in Step 6 — do not commit a mixed change. Ask the user to revert or run on a clean branch.
User declines the Step 8 gate Stop cleanly. Leave the refreshed files in the working tree for inspection. Do not git checkout -- anything.
gh not authenticated Prompt gh auth login before retrying Step 8.
gh pr create fails (auth, network, missing remote) Print the committed SHA so the user can push and open the PR manually.

Cleanup

After the PR is opened (or the pipeline aborts), remove temporary artifacts:

rm -rf /tmp/refresh-index

Leave the working tree as the user left it. Do not git checkout anything they did not stage.

Version History

  • 286ea95 Current 2026-07-25 05:01

Dependencies

  • optional github:owner/repo
  • optional github:anthropics/skills

Same Skill Collection

skills/find-me-skills/SKILL.md
skills/skill-creator/SKILL.md
tests/fixtures/skills/well-formed/SKILL.md
skills/skill-auto-improver/SKILL.md
skills/skill-index-updater/SKILL.md
skills/skill-install-improved/SKILL.md
skills/skill-upstream-pr/SKILL.md
skills/hello-world/SKILL.md

Metadata

Files
0
Version
94065fd
Hash
3f63711d
Indexed
2026-07-25 05:01

Главная - Вики-сайт
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-21 22:36
浙ICP备14020137号-1 $Гость$