ez skill management
managing and updating skills turned out to be tedious with mulitple skill repos, containing myriad skills that i didn't really want to add in to my context, while keeping others.
the workflow is quite simple:
- edit the
SOURCESdict to add or drop a source or skill. uv run skills.pyinstalls everything.
the below python file is all that's needed (placed in ~/.claude/skills/skills.py):
import shutil
import subprocess
import sys
from pathlib import Path
DIR = Path(__file__).resolve().parent
# the agent to be triggered by `skills` (https://github.com/vercel-labs/skills)
AGENT = 'claude-code'
# example of skill configs:
# (empty list = fetch everything from that source)
SOURCES = {
'kunchenguid/lavish-axi': [],
'mattpocock/skills': [
'diagnosing-bugs',
'grill-me',
'grill-with-docs',
'grilling',
'improve-codebase-architecture',
'tdd',
'writing-great-skills',
],
}
def add():
for source, skills in SOURCES.items():
flags = [f for skill in skills for f in ('--skill', skill)]
cmd = ['npx', 'skills', 'add', source, '-g', '-y', '-a', AGENT, *flags]
print('+', ' '.join(cmd))
subprocess.run(cmd, check=True)
persistent_dir = DIR / 'persistent-skills'
for skill_dir in sorted(persistent_dir.iterdir()) if persistent_dir.is_dir() else []:
target = DIR / skill_dir.name
if target.is_symlink() and not target.exists():
target.unlink()
if not target.exists() and not target.is_symlink():
target.symlink_to(skill_dir)
print(f'+ linked local skill: {skill_dir.name}')
def clean():
for entry in DIR.iterdir():
if entry.is_dir() and not entry.is_symlink() and entry.name != 'persistent-skills':
shutil.rmtree(entry)
if __name__ == '__main__':
action = sys.argv[1] if len(sys.argv) > 1 else 'add'
{'add': add, 'clean': clean}[action]()
add() spawns a process to call npx skills add <source> -g -y -a claude-code --skill <name> ... per source.
then, it symlinks custom skills persistent-skills/ (own skills) into the main folder.
clean() deletes all skills except persistent-skills