Share Agent Skills Across Repos Without Drift
Stop copying skills into eight repos and watching versions drift. Keep one shared repo, tag releases, pin one version per project, and review every bump.
How to share agent skills across repos
If you wan share agent skills across repos, stop copying the file and start depending on am. Keep one skills repository, tag am, and make each project pin one tag. Then add one smoke test for each skill, and review every bump the same way you review dependency bump.
Na four parts: one shared source of truth, one pinned version for each repository, one smoke test for each skill, and one review path. Everything below explain why each part dey exist, wetin the tools wey release for 2026 dey do about am, and how to build the whole thing for self-hosted git remote without any outside service.
An agent skill na folder wey hold one SKILL.md file, plus any scripts and reference files wey e need. If that unit dey new, read wetin an agent skill be and how SKILL.md dey work first. This page na about the supply chain around that unit.
Where skill dey live, and why sharing am hard
Claude Code dey load skills from three places, and the skills documentation name each path.
~/.claude/skills/<skill-name>/SKILL.mdna personal. E dey load for all your projects, but e no dey load for anybody else..claude/skills/<skill-name>/SKILL.mdna project level. E dey load for anybody wey checkout that repository.<plugin>/skills/<skill-name>/SKILL.mddey inside plugin. E dey load anywhere wey dem enable that plugin.
The middle one na the useful option for team, because dem commit am and everybody wey clone the repo go get am. Na there the wahala start too. Skill wey dey for .claude/skills/ belong to one repository. You get eight repositories. So dem go copy the skill eight times.
The frontmatter no fit help here. Agent Skills spec allow six keys, and the distribution paths wey enforce am go print the list when you use another one:
Unexpected key(s) in SKILL.md frontmatter: argument-hint. Allowed properties are: allowed-tools, compatibility, description, license, metadata, nameNotice wetin no dey there: no version key dey. Nothing inside the file record which copy newer pass. This one reasonable, because skill na document, no be package. But e mean say versioning must come from the layer around the file, and na you go manage that layer.
Problem wan: eight copies wey quietly dey diverge
Copy-paste fit work for day one. E go fail for day sixty. Person fit fix wrong instruction for payments repo but no touch the other seven. Another person fit add rule about pagination for orders. Now the same skill name dey give two different reviews, depending on which directory agent start from, and neither developer know.
The failure dey happen quietly because no error state dey. Skill na prose. Stale instruction fit produce confident but wrong answer, and na this kind error dey cost plenty. Nothing for agent dey compare your copy with another person's own, so the only signal na when person notice say two repos no agree.
Problem two: nothing pin a version
Even when team keep skills for one place, the normal sharing method na copy step: setup script, one curl line for onboarding doc, or shell alias wey dey sync one folder. All of dem install anything wey dey for head of the branch at that time.
This mean say two developers wey dey use the same commit of the same application fit dey run different instructions, because dem run the sync on different days. E also mean say after bad agent run, you no fit answer the important question: which version of the skill produce this? If you no record the revision, you no fit reproduce the run, so the bug report no get enough information to act on.
Problem three: nobody know whether the skill still dey work
Skill no get compiler. Na instruction wey dem aim at model, so e fit stop to work even when the file remain exactly the same byte for byte. Model upgrade fit change how well e dey follow long instruction. Command line tool wey the skill dey call fit rename flag. URL for reference file fit start return 404, and agent go use the error page do work.
For all these cases, nothing go fail loudly. Agent still dey answer. Na only say the answer don worse pass how e be last month. One pull request at a time, this kind change hard to notice.
Wetin di tools wey dey ship for 2026 dey solve
Several answers dey land now, and dem no agree on where di version suppose dey.
Lockfiles. Di skills command line tool from Vercel Labs (vercel-labs/skills, MIT licensed, v1.5.22 as of 5 August 2026) dey install skills from git repository go any directory wey your agent expect, and e sabi di layout for more than seventy agents. npx skills add <repo> dey install, npx skills update dey upgrade, and npx skills list dey show wetin you get. Di record of wetin dem install dey kept once per user instead of once per repository, and one open request for dat project (issue 283) dey ask for skills install command wey go reinstall every tracked skill from di lock file, so second machine go end up with di same set. Take dat request as status report. Di lockfile idea don settle. Di per-project part still dey build.
Specs and tests. SkillSpec dey take di other side. E dey treat a SKILL.md as contract wey you need check, instead of prose wey you trust, with di stated goal to make skills "followable, testable, and provable". skillspec doctor <path> dey report where agent likely go lose di thread. skillspec boundary map <path> dey report wetin di skill fit reach, and skillspec boundary assess <path> dey rank dose findings by risk. Na Rust crate, MIT or Apache 2.0 dual licensed, for version 0.2.2 as of 29 July 2026. Install di pinned version instead of di newest one:
cargo install skillspec --version 0.2.2 --locked
skillspec --version--locked dey build with di dependency versions wey dem publish di crate with, so di build no go drift under you. skillspec --version suppose print 0.2.2. If e print different number, e mean say older binary earlier inside your PATH dey win.
Vendor practice. Google describe how e dey build di skills for google/skills inside one post about how e dey build, test and scale agent skills. If you remove di scale, di method na ordinary continuous integration (CI). Every skill dey pass linters for frontmatter metadata, line count, directory layout, and naming before dem merge am. Link checker dey fail di build for any URL wey return 404, and dis dey catch plausible link wey agent invent. Authors must provide evaluation prompt suite and scoring rubric together with di skill. Scheduled evaluation jobs dey run every week against di whole library to catch regressions, and every skill get named owner wey suppose fix am when quality drop.
The pattern wey dey under all three answers
You no need choose any of dem. Under all of dem, one single structure dey, and plain git give you everything inside am.
- One source of truth. The skill get exactly one home, and every repository refer to that home instead of keeping copy.
- One pinned version for each repository. Every project record the exact revision wey e dey use, so upgrade na commit for that project with author and date.
- One smoke test for each skill. One runnable check wey prove say the skill still dey produce the result wey e promise.
- One review path. Change to shared skill must pass through review, and every consumer go see diff before e accept am.
Na this be the structure of dependency. Skills become shared artifacts faster than tooling grow around dem, so the tooling wey you already trust na the safest thing to use.
A layout for small team wey dey use self-hosted git remote
One repository go hold the skills. Nothing else go dey inside am, so the history go read like changelog for instructions.
agent-skills/
skills/
api-review/
SKILL.md
release-notes/
SKILL.md
tests/
api-review.sh
release-notes.sh
CHANGELOG.mdReleases na tags. Use annotated tags, because dem carry message and date. Write the message as the reason why consumer go want the bump:
git tag -a v1.4.0 -m "api-review: require pagination on list endpoints"
git push origin v1.4.0If your remote na Gitea, Forgejo, GitLab or bare repository over SSH for your own VPS, nothing for wetin follow go change. Everything here na git plus symlink.
Git submodule dey pin
A submodule dey record one exact commit from another repository inside your repository. Na this record be the pin. For each project wey dey use am:
git submodule add https://git.example.com/team/agent-skills.git vendor/agent-skills
git -C vendor/agent-skills fetch --tags
git -C vendor/agent-skills checkout v1.4.0
mkdir -p .claude/skills
ln -s ../../vendor/agent-skills/skills/api-review .claude/skills/api-review
git add .gitmodules vendor/agent-skills .claude/skills/api-review
git commit -m "Pin shared agent skills to v1.4.0"The symlink na the part wey make this work. Skill entry for project level fit be symlink to directory for another place for disk, and Claude Code go follow am and read SKILL.md from the target. So the skill go load like normal project skill, while the bytes dey inside the submodule for commit wey you choose.
Check the pin:
git submodule statusHealthy line dey start with one space, then the commit, then the path, then the nearest tag:
4d1a7c2f0b93e5a1c8d6f2b40e7a95c3d1f8b602 vendor/agent-skills (v1.4.0)If line start with -, e mean say dem never initialise the submodule, so .claude/skills/api-review dey point to nothing and the skill no go load quietly. Use git submodule update --init to fix am. If line start with +, e mean say the checked-out commit different from the one wey dem record, so that developer dey run instructions wey nobody else get. New clones need git clone --recurse-submodules, and that line suppose dey inside the README, because plain clone go leave vendor/agent-skills empty and e no go print error.
Upgrade na deliberate process, and na the main reason for the pin:
git -C vendor/agent-skills fetch --tags
git -C vendor/agent-skills diff v1.4.0 v1.5.0 -- skills/
git -C vendor/agent-skills checkout v1.5.0
git add vendor/agent-skills
git commit -m "Bump shared agent skills to v1.5.0"The diff line na the review path. E show the same change wey every other consuming repo go see, and e fit enter pull request.
Use plugin marketplace instead for pinning
If you no want make every developer learn submodules, Claude Code plugin system fit handle the distribution for you, and e fit work with self-hosted remote. Put catalog for .claude-plugin/marketplace.json inside the skills repository:
{
"name": "acme-agents",
"owner": { "name": "Platform team", "email": "platform@example.com" },
"plugins": [
{
"name": "team-skills",
"description": "Shared review and release skills",
"version": "1.4.0",
"source": {
"source": "url",
"url": "https://git.example.com/team/agent-skills.git",
"ref": "v1.4.0",
"sha": "4d1a7c2f0b93e5a1c8d6f2b40e7a95c3d1f8b602"
}
}
]
}Two different sources dey involved here, and na mixing dem up be the common mistake. Marketplace source, meaning where the catalog itself dey fetched from, accepts ref for branch or tag, but e no accept sha. Plugin source inside the catalog accepts both, and when both dey set, sha na the effective pin. So exact-commit pin suppose dey for the catalog entry.
Each consuming repository then declares the marketplace inside its committed .claude/settings.json:
{
"extraKnownMarketplaces": {
"acme-agents": {
"source": {
"source": "url",
"url": "https://git.example.com/team/agent-skills.git",
"ref": "v1.4.0"
}
}
},
"enabledPlugins": {
"team-skills@acme-agents": true
}
}Teammate wey trust the project folder go see prompt to install the marketplace, and the plugin go enable for dem without wiki page telling dem to do am. The skills then answer to /team-skills:api-review, because plugin skills dey namespaced by plugin name and dem no fit clash with project skill wey get the same name. After you push new tag, consumers refresh with /plugin marketplace update acme-agents, then run /reload-plugins if the install summary ask for am.
Writing a smoke test for one skill
Smoke test na a scripted agent run against fixture wey get known fault, plus one assertion. Claude Code dey run non-interactively with -p, and skill wey user invoke dey work there: put /skill-name for prompt string, and e go expand before run start.
#!/usr/bin/env bash
set -euo pipefail
claude -p "/api-review Read fixtures/orders-api.md and list the rule ids it breaks." \
--allowedTools "Read" \
--output-format json \
--json-schema '{"type":"object","properties":{"rule_ids":{"type":"array","items":{"type":"string"}}},"required":["rule_ids"]}' \
| jq -e '.structured_output.rule_ids | index("pagination-required")' > /dev/nullfixtures/orders-api.md na short file wey get one deliberate fault. Assertion na say the skill go name am. jq -e go exit non-zero when e filter produce null, so any skill wey stop to catch the seeded fault go make the script fail. claude itself go exit non-zero when the run fail, and set -euo pipefail go turn either failure into failed test.
Model fit reword e answers between runs, so never assert on complete sentence. Assert on identifier wey the skill suppose emit, or on field for schema wey you request, and keep fixture small so the run no cost much.
For CI, add --bare. Without am, claude -p go load the same context wey interactive session go use, including hooks, plugins and CLAUDE.md from the machine wey e dey run on, so teammate personal configuration fit change the result. Bare mode dey skip all auto-discovery, so e go also skip the skill wey you dey test; load that one explicitly. Bare mode no dey read your subscription login too, so set ANTHROPIC_API_KEY for environment first:
claude --bare -p "/team-skills:api-review Read fixtures/orders-api.md and list the rule ids it breaks." \
--plugin-dir vendor/agent-skills \
--allowedTools "Read" \
--output-format jsonWith --output-format stream-json, first event for the run go report which plugins load and carry plugin_errors array for the ones wey no load. Make CI job fail when plugin_errors no empty. This one go catch pin wey point to revision wey no dey exist again; otherwise agent fit just ignore your house rules without any clear error.
Skill wey get executable instruction
Two features make that statement literal, and both matter when another team provide the file.
First, a SKILL.md fit run shell commands before model read anything. A line like this inside the body na preprocessing:
- Current branch: !`git rev-parse --abbrev-ref HEAD`The command dey run for the machine wey load the skill, and e output go replace the placeholder for the text wey model receive. Fenced block wey start with three backticks followed by ! go run several commands the same way. Nobody dey approve any of this when e run. To read shared skill mean say you dey read the command substitutions inside am.
Second, frontmatter fit pre-approve tools. allowed-tools go grant the listed tools without permission prompt for the turn wey invoke the skill. For project skill, this grant go take effect after person accept the workspace trust dialog for the folder. Claude Code documentation talk the consequence plainly: review project skills before you trust repository, because skill fit grant itself broad tool access.
So handle skill bump exactly like dependency bump. Pin am to exact commit wherever the mechanism allow am, because tag fit move and branch dey move by definition. For locked-down machine, "disableSkillShellExecution": true for settings go replace every command substitution with literal text [shell command execution disabled by policy] instead of running am, and when managed settings apply am, user no fit override am. Bundled and managed skills no dey affected by that setting.
The same care apply to wetin skill dey read. Skill wey run env or open config file go pull anything wey e find enter model context. Na this failure dem cover for keeping secrets out of the agents you run. Skill wey fetch page or run query na the same exposure wey point outward, because retrieved text go enter context and look exactly like the instructions wey you write. Na boundary wey you suppose read about before you point an agent at your own SearXNG instance for web search.
Wetín to read when version change
- The diff of every
SKILL.mdbody, because na that text your agent go follow. - Every command substitution, because dem dey run for your machine when the skill load.
- Any change to
allowed-tools, because that line dey grant tools without prompt. - The test run behind the tag. If the shared repository dey run im own smoke tests for CI, the tag wey you dey pin to suppose get green run attached.
Reviewer wey no fit read the whole diff within ten minutes dey look at skill wey don too big. Split am. The same thing apply to repository documents wey your agents dey read: keep durable rules for the files wey the AGENTS.md and HUMAN.md split describe, keep architectural reasoning for a DESIGN.md wey agents fit read, and make skills remain narrow procedures.
Wen model or tool change dey break skill
Plenty things fit change underneath skill without anybody edit am. Model upgrade fit change how well e dey follow long instruction, so skill wey depend on model to reach step nine fit stop before e reach there. Command line tool fit rename flag, so agent go run the old flag, read the error, then improvise. Referenced URL fit start return 404. Agent harness fit change how e dey select skills, so a description wey used to win the match fit stop winning. Wen procedure start dey end early like this, no version bump go fix am. The instructions themselves need structure wey go force the final steps. Na this approach dey behind the unlazy skill and e Depth Tree method.
Na why smoke test dey carry the main weight for this setup. Run each skill test on schedule and also on every push. Google dey run evaluation jobs every week against the whole library for this reason. For team wey get ten skills, one weekly cron job for small VPS dey enough. Na only this way you fit hear about the breakage before developer notice am.
Portability still dey help. Agent Skills spec keep frontmatter to six keys, so skill wey follow that spec fit load for tools beyond the one wey you write am for. But every harness-specific key wey you add na bet on one vendor. Writing skills wey go survive model swap na separate discipline. making skill work on any model cover am.
FAQ
How I fit share one agent skill across plenty repositories?
Put the skill for one dedicated git repository, tag releases for there, and make each project wey dey use am reference one tag instead of copying the file. Two methods dey work. A git submodule records one exact commit, and symlink from .claude/skills/<name> enter the submodule make e load like normal project skill. A plugin marketplace dey do the same work through /plugin, with the pin declared for the consuming repository .claude/settings.json. Both methods put the version for git history, so you fit answer which instructions produce one particular agent run.
I fit pin agent skill to one specific version?
No be from inside SKILL.md, because that frontmatter no get version key. The layer around the file must provide the pin. A git submodule pins one exact commit by design. For Claude Code plugin marketplace, plugin source accepts ref for branch or tag and sha for exact commit, and sha get priority when both dey present. The marketplace source itself accepts ref only. Prefer commit pin, because person fit move tag after you don review am.
Wetin smoke test for skill suppose assert?
Assert on something wey stable. Run the skill non-interactively against fixture wey get one known fault, then check say one specific identifier dey for the output, like rule id wey the skill suppose report. Request structured output with --output-format json and --json-schema make the check exact, and jq -e make the script fail when the value no dey. Never assert on complete sentence, because model fit reword the answers between runs.
E safe to install shared skill from another team repository?
Treat am like code dependency, because na executable instruction. One SKILL.md fit run shell commands when e load through ! command substitution form, and frontmatter allowed-tools field fit pre-approve tools without prompt. Read the diff every time you bump am, pin to exact commit instead of branch, and prefer source wey your own team dey control. For managed machines, "disableSkillShellExecution": true for settings stop command substitutions from running at all.
Shared skill go work for agents wey no be Claude Code?
E depend on the frontmatter wey you use. Agent Skills spec define six keys: name, description, license, compatibility, metadata and allowed-tools. Skill wey use only those keys go load across tools wey implement the spec, and e go also load for Claude Code without changes. Harness-specific keys and body features wey dey outside the spec dey ignored or rejected for other tools, so keep dem out of any skill wey you plan to share widely.