Imported from arghhhhh/claude-skills (
shared/skills/skill-repo-maintenance/SKILL.md). Install upstream withnpx skills add arghhhhh/claude-skills --skill skill-repo-maintenance. Copyright stays with the author.
Skill Repo Maintenance
This skill governs how to keep the claude-skills repo (arghhhhh/claude-skills) synchronized when skills are added, updated, or modified.
Repo Location
The repo lives at ~/.claude/.skill-repos/claude-skills/. All skill edits should happen in this directory, not directly in ~/.claude/skills/ (those are symlinks).
Group Types
Each skill-groups/<group>/manifest.json declares a type:. Missing/empty defaults to "authored" for backwards compatibility.
| Type | What lives in this repo | Where to edit | Install behavior |
|---|---|---|---|
authored (default) |
Full SKILL.md + agent files |
skill-groups/<group>/skills/<name>/SKILL.md directly |
Symlinks straight into ~/.claude/skills/ |
vendored |
manifest.json (pinned source.ref SHA) + optional overlays/ |
Overlays at skill-groups/<group>/overlays/{skills,agents}/... mirroring upstream paths |
Installer clones source.repo at the pinned SHA into ~/.claude/.skill-repos/<owner>-<repo>/, then symlinks overlay files first and upstream files for the rest |
tool-only |
manifest.json only — no skills:, no agents: |
n/a | Installer runs install + test only; no symlinks under ~/.claude/skills/ |
Today: unity-cli and officecli are vendored. claude-notifications is tool-only. Everything else is authored.
Before Any Skill Edit
Always pull first to avoid conflicts with changes made from other machines:
cd ~/.claude/.skill-repos/claude-skills && git pull origin main
If the pull has changes, re-run the installer to update local symlinks:
cd ~/.claude/.skill-repos/claude-skills && bash install.sh --skills <affected-group> --skip-software
For vendored groups, never edit upstream files in ~/.claude/.skill-repos/<owner>-<repo>/ — those are read-only mirrors. Customize via overlays (see below).
Updating an Existing Skill
1. Edit the source file
For authored groups: edit skill-groups/<group>/skills/<skill-name>/SKILL.md directly. Never edit the symlink in ~/.claude/skills/.
For vendored groups: never edit upstream files in ~/.claude/.skill-repos/<owner>-<repo>/. Instead, create an overlay at skill-groups/<group>/overlays/skills/<skill-name>/SKILL.md (mirroring the upstream path). The installer symlinks the overlay in place of the upstream file. Don't restyle unmodified upstream files just to match your conventions — every overlay is a permanent fork delta to re-reconcile on every re-vendor. Send style PRs upstream instead.
For tool-only groups: no skill files to edit; only the manifest.
2. Bump the version
Update the version: field in the skill's frontmatter. Use semver:
- Patch (1.0.0 → 1.0.1): Typo fixes, clarifications, minor wording changes
- Minor (1.0.0 → 1.1.0): New commands, new sections, expanded guidance
- Major (1.0.0 → 2.0.0): Restructured skill, changed tool names, breaking workflow changes
---
version: 1.1.0
name: my-skill
description: ...
---
3. Commit and push
cd ~/.claude/.skill-repos/claude-skills
git add skill-groups/<group>/skills/<skill-name>/ # or overlays/skills/... for vendored
git commit -m "Update <skill-name> to v1.1.0 — <what changed>"
git push origin main
For vendored groups, if you want the change in upstream too: send a PR to source.repo so the next --bump-vendor brings it in and you can delete the overlay.
4. Verify
cd ~/.claude/.skill-repos/claude-skills && bash install.sh --status
Adding a New Skill to an Existing Group
1. Create the skill file
mkdir -p ~/.claude/.skill-repos/claude-skills/skill-groups/<group>/skills/<new-skill>/
Write SKILL.md with frontmatter:
---
version: 1.0.0
name: new-skill
description: What this skill does and when to use it.
---
2. Add to manifest
Edit skill-groups/<group>/manifest.json and add the skill name to the "skills" array.
3. Add CLAUDE.md snippet (if needed)
If the skill has unique trigger phrases not covered by the group's existing snippet, update shared/claude-md/<group>.md.
4. Commit, push, reinstall
cd ~/.claude/.skill-repos/claude-skills
git add skill-groups/<group>/ shared/claude-md/<group>.md
git commit -m "Add <new-skill> to <group>"
git push origin main
bash install.sh --skills <group> --skip-software
Keeping MCP-backed Skills in Sync
For groups whose manifest declares mcp_servers (blender, comfyui, houdini, notch, claude-mermaid), the documented tool list can silently drift from the server's actual tools after an upstream package update. Detect it mechanically instead of eyeballing:
bash install.sh --check-drift # all mcp-backed groups
bash install.sh --check-drift --skills blender # one group
# or call the script directly:
bash scripts/check-mcp-drift.sh blender comfyui
It runs npx mcporter list <server> and diffs the live tool set against the tool names referenced in the group's skill + agent docs, reporting:
- UNDOCUMENTED — tool exists on the server but is absent from the docs (add it).
- STALE — docs reference
<server>.Xbut X is no longer a live tool (renamed/removed).
Notes:
- The MCP server's host app must be running for that server to be inspected (Blender/Houdini/ComfyUI open; mermaid/notch are standalone). Unreachable servers are SKIPPED, not failed.
- Advisory only — it never edits files. After reconciling, bump the skill version like any other edit.
mcporter list <server> --all-parametersprints full signatures — use it to copy exact params when adding a newly-surfaced tool.- Run it whenever you bump an MCP server/package (e.g. a new
blender-mcprelease), as part of the same change.
Adding a New Skill Group
1. Create directory structure
mkdir -p skill-groups/<name>/skills/<skill-name>/
mkdir -p skill-groups/<name>/agents/ # if the group has an agent
2. Create manifest.json
First decide the group's type: — see the Group Types table above. Pick one of:
authored(or omittype:entirely) — you own the SKILL.md files. Must include:name,description,version,prerequisites,install,test,skills,agents. See any existing authored manifest for the template.vendored— wrapping an upstream repo. Must include:type: "vendored",name,version,source: { repo, ref, ref_name, paths: { skills, agents } },skills:(explicit allow-list),agents:, optionaloverlays:,install,test. Seeskill-groups/unity-cli/manifest.jsonorskill-groups/officecli/manifest.jsonfor templates.tool-only— installs software, ships no skills. Must include:type: "tool-only",name,version,install,test,post_install_hints. Seeskill-groups/claude-notifications/manifest.jsonfor the template.
Optional fields:
mcp_servers: Object mapping server names to{ "command": "...", "args": [...] }. The installer auto-generates~/.mcporter/mcporter.jsonand~/.claude/.mcp.jsonentries. Use{{PLACEHOLDER}}for machine-specific paths (resolved fromskills-config.sh). Commands are auto-resolved to full paths on Windows.post_install_hints: Array of strings printed after install. Use for optional setup steps the installer can't automate (e.g., API keys, browser auth, manual addon installation).agent_renames: Object mapping source filenames to agent names when they differ.
3. Create CLAUDE.md snippet
# shared/claude-md/<name>.md
## Group Name - Description
When [trigger conditions], read `~/.claude/skills/<skill-name>/SKILL.md`.
Trigger phrases: "keyword1", "keyword2", ...
4. Commit, push, install
git add skill-groups/<name>/ shared/claude-md/<name>.md
git commit -m "Add <name> skill group"
git push origin main
bash install.sh --skills <name>
Adding an MCP-backed Skill
A skill driven by an MCP server (Blender, ComfyUI, Houdini, Mermaid, Notch…) is a normal skill group — it is not special-cased by location. Follow "Adding a New Skill Group" above, with these MCP-specific points:
- Locate by domain, not mechanism. The group and skill are named for the tool (
blender,comfy-pilot), never for the transport. Do not create askills/mcp/directory and do not append-mcpto the skill name — that was an early mistake (only legacy blender/houdini used it; comfy-pilot/td got it right). The skill lives atskill-groups/<tool>/skills/<tool>/SKILL.md. - Declare the server in the manifest, not in the path — add an
mcp_serversblock (see the optional fields above). The installer wires~/.mcporter/mcporter.json+~/.claude/.mcp.json. This field is also what--check-driftkeys off. - Discover the real tool surface before writing. With the server running:
Watch for: required params that aren't obvious (e.g. Blender'snpx mcporter list <server> --all-parameters # authoritative tool + param list npx mcporter call <server>.<simple_tool> … # test 2-3 tools — MCPs have undocumented requirementsuser_prompt), param names that differ from any docs, and auth errors. - Write the SKILL.md from the tested surface — command tables, an "Always Start Here" connection check, workflows, and a Quirks/Gotchas section for what you hit during testing. Put dense scripting traps in
references/. - Add the CLAUDE.md snippet pointing at
~/.claude/skills/<tool>/SKILL.mdwith trigger phrases. - Verify tool/doc parity after install with
bash install.sh --check-drift --skills <tool>(see "Keeping MCP-backed Skills in Sync"), then commit + push.
This supersedes the old standalone mcp-setup skill, which predated this repo workflow and wrote directly into ~/.claude/ (bypassing the repo, versioning, and snippets).
Maintaining Vendored Groups
Vendored groups (type: "vendored") pin a specific upstream commit. The installer clones source.repo into ~/.claude/.skill-repos/<owner>-<repo>/ and checks out the pinned source.ref (detached HEAD).
Check what's new upstream
cd ~/.claude/.skill-repos/claude-skills && bash install.sh --vendor-status
Lists every vendored group with: pinned SHA, upstream HEAD, commit delta, and whether the local clone is currently on the pinned ref.
Bump a vendored group to a newer upstream
bash install.sh --bump-vendor <group>
Fetches source.repo, shows git log <pinned>..origin/main so you can review what changed, then prompts to update the manifest's source.ref to the new HEAD SHA. After accepting, re-reconcile any overlays:
- For each file in
skill-groups/<group>/overlays/, diff against the new upstream version at the new SHA. - If upstream now incorporates your customization → delete the overlay.
- If upstream changed adjacent content → merge: take upstream as the base, re-apply your changes on top.
- If the file was renamed or deleted upstream → either rename your overlay to match or remove it.
Then bump the manifest version: (minor for new upstream, patch for overlay-only edits) and commit.
Adding a new vendored skill from upstream
When upstream adds skills, the installer does not auto-pick them up — the manifest skills: array is an explicit allow-list. After bumping, list the new upstream skills:
ls ~/.claude/.skill-repos/<owner>-<repo>/<source.paths.skills>/
Add new entries to manifest.json's skills: array. Same for agents:.
Rules for vendored groups
source.refmust be a full commit SHA or an immutable tag. Branch names (main,develop) are rejected by the installer — they re-introduce silent drift.- Overlays are replace-only — an overlay at
overlays/skills/<name>/SKILL.mdwhose path matches an upstream file overrides it. No additive siblings; author wholly new skills in their own group. - Overlay agent renames live in
manifest.json'soverlays.agentsas{"upstream-name.md": "rename:new-name.md"}. - CLAUDE.md snippet: if
shared/claude-md/<group>.mdexists, the installer uses it. Otherwise it auto-generates one from the manifest description. Author your own only when you want to override.
Maintaining Tool-only Groups
Tool-only groups (type: "tool-only") ship no skills or agents — they exist only to run install and test for a piece of external software (e.g., claude-notifications installs a Claude Code plugin). Manifest shape is minimal: type, version, install, test, post_install_hints.
To update, edit install / test / post_install_hints, bump version, commit, push. No symlinks are created, so there's nothing to re-sync on other machines beyond rerunning the installer.
Update Policy — Tracking My Own Tool Repos at HEAD
Any group (tool-only or otherwise) whose install command builds software from a git clone can declare how --update treats that software:
"update_policy": "latest"
| Policy | Meaning | Use for |
|---|---|---|
pinned (default, field omitted) |
--update never touches installed software; it only refreshes skills/agents/commands. Software updates happen only when the install check fails or a human bumps something deliberately. |
Third-party tools where an unreviewed upstream change is a risk (claude-notifications, winget/brew packages) |
latest |
Every --update re-runs the group's install command even though the binary already exists — the command must be idempotent (pull-or-clone + rebuild, like git pull --ff-only … && go build), and run_test verifies afterwards. --skip-software suppresses this. |
My own repos (arghhhhh/*) where HEAD is always wanted: claude-code-sessions, claude-conversation-transfer |
Rule: any group that clones one of my own repos must set update_policy: "latest" — otherwise fixes pushed from one machine silently never reach the installed binaries on others (the install check sees an existing binary and short-circuits). Third-party sources stay pinned/default unless there's a specific reason to track them.
Same rule for groups whose "software" lives in THIS repo — a tool-only group that installs by copying/wiring files out of skill-groups/<group>/ (e.g. context-rotation's hook scripts via install/wire.sh). A repo edit is a software change there, so without update_policy: "latest" the group's --update path short-circuits at "tool-only — nothing to update" and machines keep running stale copies while the summary reports success. Such install commands must be idempotent (wire-style copy + dedupe), which is what makes re-running them on every update safe.
install.check vs test.command — they answer different questions
| Field | Question | Used by |
|---|---|---|
install.check |
"May I skip the install step?" | install_software only |
test.command |
"Is this correctly installed?" | run_test, group_is_installed (tool-only), --verify (tool-only) |
Don't conflate them. A group whose install is a cheap idempotent re-wire deliberately sets check: "false" so install always runs — and that must NOT make the group read as "not installed". group_is_installed and --verify therefore probe tool-only groups with test.command, falling back to install.check only when no test is declared. Every tool-only group must declare a real test.command that inspects the installed footprint (a path, a settings entry), not a tautology.
Symptoms of getting this wrong: --update silently skips the group forever, and every --sync re-offers it as a "new" group.
Propagating a group into WSL (wsl_propagate)
A WSL distro is a separate Claude Code store (/home/<user>/.claude) that a Windows install.sh run otherwise never touches — so anything wired there goes stale silently and indefinitely. A group whose install is an idempotent re-wire can opt in:
"wsl_propagate": {
"check": "test -d $HOME/.claude/hooks/<group>",
"command": "bash {{REPO}}/skill-groups/<group>/install/wire.sh"
}
{{REPO}}→ this repo's/mnt/c/...path, so the distro reuses the Windows clone. Never re-clone into WSL.checkruns inside the distro and gates everything: it must test that the group is already set up there. Nocheck→ fail closed, never propagates. This is what keeps a distro the user never configured from being silently installed into.- Fires only from Windows Git Bash with a reachable distro, and never when the installer is itself running inside WSL (that would recurse).
--skip-wslopts out; failureswarnwith the manual command rather than failing the update.
Only for files this repo owns. Per-environment state — settings.json, hook command paths, anything holding an absolute OS path — must NOT be propagated; it's per-environment precisely because the two can't share it.
Syncing Another Machine
On any other machine, just pull and reinstall:
cd ~/.claude/.skill-repos/claude-skills
git pull origin main
bash install.sh --update --sync
--update only refreshes groups already installed on that machine — it never silently installs groups the user didn't pick. If the pull brought in groups that machine doesn't have, they're listed and the user is prompted whether to install them (skipped with a notice under -y). A ledger at ~/.claude/.skills-meta/known-groups records what's already been offered, so a declined group isn't re-prompted on every sync. Net effect: syncing a Mac won't drag in a Windows-only group unless the user says yes.
Or for a fresh machine:
git clone https://github.com/arghhhhh/claude-skills.git ~/.claude/.skill-repos/claude-skills
cd ~/.claude/.skill-repos/claude-skills
bash install.sh
First-Time Setup on a New Machine
When the user asks to "set up my skills", "install claude-skills", or "set up Claude on this machine", follow this workflow:
1. Clone the repo (if not already present)
if [ -d ~/.claude/.skill-repos/claude-skills ]; then
cd ~/.claude/.skill-repos/claude-skills && git pull origin main
else
mkdir -p ~/.claude/.skill-repos
git clone https://github.com/arghhhhh/claude-skills.git ~/.claude/.skill-repos/claude-skills
fi
2. Run the installer
cd ~/.claude/.skill-repos/claude-skills && bash install.sh -y
The -y flag runs non-interactively (installs all groups, skips manual-install prompts).
3. Resolve {{PLACEHOLDER}} variables
After install, run bash install.sh --verify and check for {{PLACEHOLDER}} warnings. If any exist, you (the agent) should resolve them by searching the machine for the correct paths:
Strategy for finding paths:
which <binary>orcommand -v <binary>— finds executables on PATHfind / -name "<binary>" -type f 2>/dev/null | head -5— broader search (use sparingly)- On Windows Git Bash:
where.exe <binary>or search common locations - Check common install locations:
- Miniconda:
~/miniconda3/Scripts/,~/miniconda3/bin/ - Homebrew:
/opt/homebrew/bin/,/usr/local/bin/ - Cargo:
~/.cargo/bin/ - Go:
~/go/bin/ - npm global: check
npm root -g - Windows tools:
C:/Users/*/tools/,C:/Program Files/
- Miniconda:
Once you find the paths, write ~/.claude/skills-config.sh:
# Example — fill in paths you actually found on this machine
COMFY_CLI="/path/to/comfy"
COMFYUI_WORKSPACE="/path/to/ComfyUI"
COMFYUI_PYTHON="" # leave empty if not using Windows standalone
GOBS_CLI="/path/to/gobs-cli"
OBS_CONFIG_DIR="$HOME/.config/obs-studio" # or AppData/Roaming on Windows
Then re-run the installer to apply the config:
cd ~/.claude/.skill-repos/claude-skills && bash install.sh --update
4. Verify and report
cd ~/.claude/.skill-repos/claude-skills && bash install.sh --verify
Report the results to the user. If any software smoke tests failed, let them know what needs manual attention (e.g., "OBS Studio needs to be installed from obsproject.com").
5. Register MCP servers (if applicable)
Some skills require MCP server registration. Check post-install hints in the installer output. Common ones:
officecli mcp claude— registers OfficeCLI MCP server
Running Tests
The tests/ directory contains a static test suite that validates repo correctness without running the installer.
node tests/smoke-check.js # fast — Node.js, no bash required (438 checks)
bash tests/run-tests.sh # full bash suite (Git Bash / Linux / macOS)
bash tests/run-tests.sh test-manifest-contracts # one suite
Run the smoke check whenever you add or modify a group to catch manifest schema errors, duplicate skill names, orphaned files, or vendored ref issues early.
Key Rules
- Always pull before editing — other machines may have pushed changes
- Always bump the version — even for small changes;
--statusdepends on it - Edit source files, not symlinks —
~/.claude/skills/contains symlinks pointing to the repo - Push after every change — unpushed changes won't sync to other machines
- For vendored groups, never edit upstream files — customize via overlays in
skill-groups/<group>/overlays/; upstream clones are read-only - Run
--verifyafter changes — catches broken symlinks, missing files, version mismatches. For vendored groups it also confirms the pinned SHA is checked out and overlay paths still match real upstream files - For MCP-backed skills, run
--check-driftafter a server/package bump — confirms the documented tool list still matches the live server (see "Keeping MCP-backed Skills in Sync")
Skill Style Guide
Follow these conventions when writing or editing any skill:
Before writing, read 1-2 existing skills as style templates
Start with skill-groups/comfyui/skills/comfy-cli.md (flat single-file) or the notch skill (multi-reference structure). Match the density and formatting of what's already there.
File roles — one fact in one place
| File | Contains |
|---|---|
SKILL.md |
Entry point: critical rules, capability table, workflow, globals, cross-references. Must be self-contained enough to guide the first action. |
references/*.md |
Topic-scoped deep dives. node-catalog.md / similar = quick-lookup tables. gotchas.md = "this doesn't work as expected because…" narratives. patterns.md = reusable code. |
Do not duplicate facts across files. If something belongs in gotchas, don't also put it in the catalog.
Write terse and dense
- No preamble: don't open with "In this section we'll discuss…" or "Read this reference when you need to…" (one-line subtitle is fine).
- No narrative recap: don't restate what was just said in prose after a table or code block.
- Prefer tables and code over paragraphs.
- Mark uncertainty explicitly (
⚠ Untested,❌ Dead end,✅ Verified) — don't soften with hedging prose. - Say what doesn't work and why. "X silently no-ops because Y" is more useful than "X may not work in all cases".
Agent Style Guide
Agents live at skill-groups/<group>/agents/<agent-name>.md. They are picked up by the installer and symlinked into ~/.claude/agents/. Agents are optional — a group may ship skills only.
Frontmatter contract
Required fields, in this order:
---
version: 1.0.0
name: <agent-name>
description: <one sentence capability statement>. Use when <trigger criteria>.
tools: <comma-separated tool list>
model: <sonnet|haiku|opus>
---
The version: field is leading so it matches the skill frontmatter contract. Claude Code itself ignores it, but install.sh --status and the maintenance workflow depend on it.
Optional fields, appended after model: in this order:
skills:— YAML list of skill names this agent should reach for. Use when the group ships skills the agent depends on, or when the agent borrows shared skills (e.g.find-docs).color:— UI hint (green,blue, etc.). Only set if there's a reason; otherwise omit.
Do not use allowed-tools in agents — that field is for skills. Agents use tools.
Field conventions
name— kebab-case, matches the filename (without.md). If they must differ, useagent_renamesin the manifest.description— default to a single line. Lead with what the agent is ("X expert for Y") then a "Use when …" clause listing trigger surfaces. A block-scalar description (description: |) with<example>blocks is permitted only when trigger surfaces overlap with other agents and the selector needs disambiguation hints — Claude Code reads those examples for agent-selection heuristics. Default is still single-line; reach for examples only when ambiguity is observed in practice.tools— comma-separated, no brackets. Standard set for a full-featured agent:Read, Glob, Grep, Bash, Edit, Write, Agent, WebFetch, WebSearch. Trim to what's actually needed (e.g.imagemagickagent omitsWriteand the web tools).model—haikufor narrow CLI wrappers (imagemagick, obs-studio),sonnetfor most domain experts,opusonly if explicitly needed.skills— list every skill the agent should consult, including shared ones likefind-docs. The installer does not enforce this; it documents intent.
Body structure
Match the density of existing agents (see skill-groups/blender/agents/blender.md or skill-groups/ghidra/agents/ghidra.md as templates). Typical sections:
| Section | Purpose |
|---|---|
# Your Tools |
What the agent has access to (CLI, MCP, skills) and how to invoke each. |
# Operational Rules |
Hard rules the agent must follow — what to never do, what to always check first. |
# Workflow |
Step-by-step pattern for common requests. Optional. |
# Connection Diagnostics / # Troubleshooting |
If the agent depends on external software, how to detect and report it missing. |
Same rules as skills: terse, dense, tables over paragraphs, no preamble, mark uncertainty explicitly.
Versioning
Agents carry their own version: field in frontmatter, using the same semver rules as skills:
- Patch (1.0.0 → 1.0.1): Typo fixes, clarifications, minor wording changes.
- Minor (1.0.0 → 1.1.0): New sections, expanded guidance, added tool to
tools:, added skill toskills:. - Major (1.0.0 → 2.0.0): Restructured agent, changed
model:, removed a tool, breaking workflow changes.
Bump the agent's version: for any content change. Also bump the group manifest's version: so install.sh --status flags the group as updated and downstream machines re-sync.