Stop losing track of where your Claude Code skills came from.
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."
- 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.
git clone https://github.com/pcx-wave/update-skills ~/.claude/skills/update-skillsTell 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.
# 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 vibeCompares local skill content against upstream (with GITHUB_TOKEN: SHA-by-SHA precision; without: content comparison via SKILL.md).
# 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 geopython ~/.claude/skills/update-skills/scripts/update_skill.py --revert vibe
python ~/.claude/skills/update-skills/scripts/update_skill.py --revert allPrevious versions are backed up automatically before each update.
- 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
Each resolved skill directory gets a hidden JSON file:
{
"repo": "owner/repo",
"path": "skills/vibe",
"confidence": "unique",
"last_sha": "a1b2c3d4e5f6789abcdef1234567890abcdef12",
"previous_sha": "9f8e7d6c5b4a3210fedcba9876543210fedcba98"
}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
- Python 3.10+ — no pip dependencies, no virtualenv, no node_modules