Keep all your custom skills up-to-date
update-skills
Stop losing track of where your Claude Code skills came from.
The problem
You've installed 30+ Claude Code skills. Some from GitHub. Some from gists. Some from that blog post you bookmarked but can't find again.
There's no pip list equivalent. No plugin marketplace. No update manager. Just a pile of SKILL.md files with no connection to their source. When a skill ships a bugfix, you won't know. Neither will Claude.
This is the gap between "it works" and "I can maintain it."
What this skill does
- Discovers the canonical GitHub repo for each of your manually installed skills
- Tracks the exact commit SHA of what you have installed vs what's upstream
- Updates any skill โ or all of them โ with one command
- Rolls back if an update breaks something
- Zero pip dependencies. No API keys needed for source resolution. You're not locked into anything.
Install
git clone https://github.com/pcx-wave/update-skills ~/.claude/skills/update-skills
Usage
Step 1 โ Resolve sources (first time only)
Tell Claude to find where each skill originally came from:
"find the source repos for my skills"
Claude reads each SKILL.md, searches verbatim phrases on DuckDuckGo, and writes a .skill-source file per skill. No script, no token. Done once.
Step 2 โ Check for updates
# Check all skills
python ~/.claude/skills/update-skills/scripts/check_updates.py
Check a specific skill
python ~/.claude/skills/update-skills/scripts/check_updates.py --skill vibe
Compares local skill content against upstream (with GITHUB_TOKEN: SHA-by-SHA precision; without: content comparison via SKILL.md).
Step 3 โ Update
# Update every outdated skill at once
python ~/.claude/skills/update-skills/scripts/update_skill.py all
Update specific skills
python ~/.claude/skills/update-skills/scripts/update_skill.py vibe geo
Revert if something breaks
python ~/.claude/skills/update-skills/scripts/update_skill.py --revert vibe
python ~/.claude/skills/update-skills/scripts/update_skill.py --revert all
Previous versions are backed up automatically before each update.
How source resolution works
- Reads verbatim phrases from the first 10 lines of each local
SKILL.md - Searches DuckDuckGo:
github <skill-name> <verbatim phrase> - For each candidate repo found, fetches the first 10 lines of the remote
SKILL.md - Rejects candidates where no sentence matches verbatim โ eliminates forks and similarly-named but different skills
- Writes a
.skill-sourcefile so this is a one-time cost per skill
.skill-source format
Each resolved skill directory gets a hidden JSON file:
{
"repo": "owner/repo",
"path": "skills/vibe",
"confidence": "unique",
"last_sha": "a1b2c3d4e5f6789abcdef1234567890abcdef12",
"previous_sha": "9f8e7d6c5b4a3210fedcba9876543210fedcba98"
}
GITHUB_TOKEN โ optional
Both modes work out of the box. The difference is precision and rate limits.
| | Without token | With GITHUB_TOKEN | |---|---|---| | Detection | SKILL.md content comparison | Exact commit SHA comparison | | Misses | Updates that don't touch SKILL.md | Nothing | | Rate limit | 60 GitHub API req/hour โ inconsistent if run repeatedly | 5000/hour โ no practical limit |
To add a token permanently: echo 'export GITHUB_TOKEN=<token>' >> ~/.bashrc
Requirements
- Python 3.10+ โ no pip dependencies, no virtualenv, no node_modules