Integrating a third-party Agent skill into your project for the first
time feels effortless. Whether you copy and paste a
SKILL.md file directly from GitHub or run a quick terminal
command, you can drop a file into .claude/skills/ or
.github/skills/ in fifteen seconds and use it immediately
inside your editor. If a skill never needed to change after day one, we
would not need any package manager at all.
The real headache starts two months later with ongoing maintenance.
Suppose an upstream vendor updates its SDK interface guidelines, or your
infrastructure team patches a false negative in an internal security
review skill, after you have already copied that skill across a dozen
business repositories. Some repos store it under .claude/,
others under .github/, and others under
.cursor/. A few months in, those repositories are running
several different versions from different eras, teammates have casually
edited a couple of lines in some copies, nobody knows which repo is on
which version, and nobody wants to sync them all by hand.
Day-one distribution was solved long ago. The real challenge is
keeping dozens of repositories aligned with upstream changes after
installation without creating chaos or manual toil. For cross-repository
dependency syncing, the standard software engineering answer over the
past decade has been a package manager paired with an automated upgrade
bot. On November 3, 2026, GitHub announced that its automated dependency
update tool Dependabot
now supports Microsoft’s Agent Package Manager (APM). In the
official workflow, you declare dependencies in a root
apm.yml file, lock versions in apm.lock.yaml,
and let Dependabot periodically scan upstream repositories and open pull
requests to bump your skill versions. On paper this looks identical to
npm, but if you copy the traditional code-package workflow verbatim to
manage Agent skills, you will quickly run into trouble at several
critical steps.
At first glance, this might sound puzzling: aren’t Agent skills just a handful of Markdown text files? JavaScript and Python source files are text files too, so why does the workflow built for code packages break down when applied to skill files? Looking closely at how skills are actually used in a repository reveals four concrete differences between Agent skills and traditional code libraries.
First, host editors lack a runtime module import system for skills,
so installed files usually have to be committed directly to your Git
repository. In a frontend project, the runtime knows how to resolve
modules from node_modules/, so you never commit downloaded
third-party code to Git—you only commit the two ledger files,
package.json and the lockfile. By contrast, Claude Code,
Cursor, and cloud coding assistants do not read from a package manager
cache directory, nor do they automatically run an install command when
you open an editor; they simply scan fixed directories such as
.claude/ or .github/. Teammates also
frequently invoke cloud coding assistants directly in the browser for
code review, or clone a repository and immediately open their IDE
without running a terminal setup command first. To guarantee that
everyone gets identical Agent context right after pulling the repo,
Microsoft officially recommends committing the unpacked target
directories directly into version control.
Second, what we install is no longer just passive text, and files
take effect the moment they land on disk. Modern skill packages often
bundle executable scripts under scripts/, MCP server
declarations that rewrite client configurations, and lifecycle hooks
injected into .claude/settings.json. When a traditional
code package is downloaded to disk, unused functions sit there as dead
code, giving teams a wide buffer for security audits. As noted in APM’s
security model documentation, the prompt supply chain behaves very
differently: as soon as skill files, instructions, or hooks land in
their target directories, an editor Agent watching the filesystem
immediately loads them into context or triggers the hooks. Presence on
disk is execution.
Third, natural language has no function parameters, which constantly
pushes users to edit upstream source files directly. When we use code
libraries like axios or lodash, we customize
timeouts or behavior by passing arguments to functions; nobody opens
node_modules/ to edit library source code. A
SKILL.md file, however, is a natural-language manual
written for a large language model and offers no parameter interface.
When a team installs a generic code review or database query skill from
outside and notices after two days that it keeps generating queries that
violate internal conventions, the most natural fix is to open the file
under .claude/skills/ and add two lines specifying internal
table naming rules or banned framework patterns. Once those two lines of
local customization are mixed in, the file combines external public
dependencies with internal private rules and can no longer be replaced
as a black-box package.
Fourth, natural language has no compiler or unit tests to catch
regressions. When a code dependency bumps a minor version, GitHub
Actions runs type checks and unit tests; if CI is green, the interface
is generally intact. If an upstream author rewrites three paragraphs of
instructions in SKILL.md, its Markdown syntax is always
valid, and your application unit tests never touch the text inside
.claude/skills/. Even when CI passes without a single
warning, merging the update can interact with your existing system
prompts and alter the Agent’s output behavior across the entire team the
next morning.
Once you understand those four differences, it becomes clear why transplanting the traditional code package manager workflow onto Agent skills fails in three specific places. Code package managers assume that only ledger files live in Git and that runtime behavior can be verified by compilers and tests—neither of which holds for skill files.
The first and most common pitfall is that clicking Merge on a
Dependabot PR upgrades the ledger while leaving the actual skill files
in your repository untouched. Traditional dependency bots only need to
modify the manifest and lockfile when opening a PR. According to the
implementation record in dependabot-core, when Dependabot opens an
upgrade PR for APM skills, it runs APM’s
lock command in the background. As the official
documentation explains, apm lock only fetches the new
upstream version and updates the version numbers and verification hashes
inside apm.lock.yaml; it explicitly skips security scanning
and does not copy the updated skill files into host directories such as
.github/ or .claude/.
This creates a split between the ledger and the actual files. Because
teams typically commit the unpacked .github/skills/ or
.claude/skills/ directories to Git, the PR opened by
Dependabot only touches apm.yml and
apm.lock.yaml without updating the skill text in the
repository. If you click Merge the way you would for a frontend library
bump, main shows the latest version in the lockfile while
your coding assistant continues reading the old skill text every
day.
To prevent this file desynchronization, the official practice is to configure an apm audit drift-detection gate in your CI pipeline. This check performs a fresh install from the new lockfile in a temporary directory and compares the result file-by-file against your repository’s working tree. Consequently, because Dependabot’s PR only updates the lockfile and leaves the committed skill files unchanged, every single upgrade PR opened by the bot fails CI with a red X until someone runs an extra install pass to update the working tree. And if you skip the drift check for convenience, even Microsoft’s own official repository fell into this trap during routine maintenance in June 2026: because its pipeline skipped drift detection, the skill files committed on the main branch stayed on a stale version that was missing an entire performance reviewer role present in upstream source, while CI continued reporting green.
The second pitfall is that automated upgrades silently stop working
as soon as you use advanced configuration features like picking a subset
of skills, aliasing names, or declaring MCP tool servers. Many
open-source skill repositories are large bundles packing twenty or
thirty skills into one repo. Often you only want to install two or three
of them into your project, or you need to rename an imported skill so it
does not collide with an existing local skill of the same name, or you
also declare the project’s MCP tool servers inside apm.yml.
In all of these cases, you cannot just write a simple one-line
repository path; you have to expand the entry into a multi-line
configuration block specifying which subdirectories to pick or what
alias to assign. Yet a look at GitHub’s
official Dependabot ecosystem support documentation reveals a long
list of limitations: the updater currently only parses the simplest
single-line repository string format. As soon as a dependency is written
as a multi-line configuration block with options, declares an MCP
server, or points to a private enterprise registry for compliance, the
parser silently skips those entries—raising no error and opening no PR.
The more you rely on the package manager’s advanced composition
features, the less you can rely on automated upgrades.
The third pitfall is that both the vulnerability advisory database and the content security scan are effectively empty during automated updates. Many teams rely on Dependabot because it immediately pushes a fix PR when an open-source library discloses a security vulnerability. However, if you inspect the commit that merged APM support into dependabot-core, you will notice a revealing change: the author had originally implemented version range parsing and downgrade protection for security advisories during earlier review rounds, then deleted all of that code right before merging. As the commit message notes plainly, the GitHub Advisory Database does not index APM packages at all, making the security update check dead code that always evaluates to false.
Meanwhile, the more realistic and insidious threat lies in the text
itself. In 2026, an attack pattern known as Glassworm emerged in which
attackers hide malicious instructions inside shared rule files using
invisible Unicode variation selectors and bidirectional control
characters. To a human reviewer looking at a GitHub PR diff in the
browser, the change looks like a harmless formatting tweak, but the
language model’s tokenizer reads and executes the hidden instructions
verbatim. APM actually includes a pre-deployment scan during
apm install to catch these invisible characters—yet
apm lock, the command Dependabot runs when updating
lockfiles, skips this scan entirely. If you merge a Dependabot PR simply
because its checks look green, that defense never runs.
At this point you might wonder: if maintaining a central
apm.yml and apm.lock.yaml alongside committed
files creates so much friction, is there a lighter-weight approach?
Interestingly, two tools representing distinct design philosophies
emerged across Microsoft and GitHub in 2026.
In April 2026, the GitHub CLI team released a native subcommand
called gh
skill. Instead of introducing separate manifest and lockfiles, it
uses a single-file self-contained design: when you install a skill and
pin a version, it writes the upstream repository URL, the pinned version
tag, and the Git tree hash of the skill directory directly into the YAML
frontmatter at the top of the downloaded SKILL.md file.
Putting the two tools side by side makes their bookkeeping trade-offs
immediately clear:
| Dimension | Single-File Embedded Lock
(gh skill) |
Build-Time Dependency Compiler
(apm + Dependabot) |
|---|---|---|
| Primary Ledger Location | Embedded directly in the YAML frontmatter
of each SKILL.md |
Separate apm.yml and
apm.lock.yaml in the repo root |
| Risk of Ledger-to-File Drift | None; the file carries its own lock, so updating the file and the lock is a single atomic step | High; Dependabot only updates the lockfile without updating committed skill files |
| Cross-Repo Copy-Paste Provenance | Copying a single file to another repo preserves its upstream source and tree hash | Copying generated .claude/
files alone loses apm.lock.yaml provenance |
| Multi-Host Compilation & Transitive Dependencies | Installs individual skills only; no transitive dependency resolution | Supports cross-repo subpath assembly, transitive resolution, and multi-editor output |
| Ideal Team Scale | Individual developers or small-to-medium projects importing a few standalone skills | Large engineering organizations using multiple editors, internal rule libraries, and CI policy gates |
Seeing them side by side clarifies how the two tools divide the
problem space. gh skill treats each skill file as a
self-contained artifact whose lock metadata travels inside the file
itself. Even if a teammate copies that SKILL.md file into
another repository, running the update command still checks the upstream
repository against the hash in the file header—eliminating the
split-brain state where a lockfile advances while the actual skill file
stays behind. Conversely, in a community discussion on
strategic positioning, APM creator Daniel Meppiel describes APM as
an orchestration and governance layer for AI agents: its core value is
helping large organizations pull rule fragments across code hosts,
resolve multi-layer transitive dependencies, and compile them uniformly
into multiple editor directories.
Returning to our original question: if your team wants to use external and cross-team Agent skills across multiple repositories today and keep up with upstream improvements without falling into these traps, how should you set up your workflow? Given the real-world constraints of current tooling, three practical engineering rules make automated maintenance work reliably.
First, route tools by project scale—not every repository needs a
heavy package manager. If your project only needs a handful of external
skills (such as official skills for a frontend framework or cloud
provider) and your team works in one or two editors, simply install them
into the repository with gh skill install --pin. Because
the lock metadata lives directly in the SKILL.md header,
running the update command updates the text in place, code reviewers see
the exact prompt changes in the PR diff, and nobody has to maintain
separate lockfiles or working-tree sync pipelines.
Second, if your organization genuinely operates in a multi-editor,
cross-repository environment and chooses APM + Dependabot, complete the
last mile inside your CI pipeline. Do not expect the dependency bot to
finish the job after editing apm.lock.yaml. Configure a
companion workflow in your repository: whenever it detects a pull
request from Dependabot modifying the manifest or lockfile, the pipeline
should automatically run apm install on that branch,
materialize the new skill files into .github/ and
.claude/, commit the updated files back to the PR branch,
and immediately enforce apm audit --ci. That way, every
upgrade PR triggers the built-in hidden-character security scan and
shows human reviewers the exact natural-language prompt diff instead of
just a commit hash bump.
Third, enforce strict physical separation between public and private
context by treating external skills as read-only black boxes. As we saw
earlier, one of the main reasons skills become impossible to upgrade is
that developers open installed SKILL.md files and splice in
team-specific business rules. To make automated upgrades viable,
establish a clear rule: every external skill file installed by a tool is
a read-only build artifact and must never be edited by hand. Delegate
stateless public capabilities—such as third-party framework docs and
generic coding standards—to apm.yml or
gh skill so they can track upstream automatically. Place
your team’s private database table conventions, approval workflows, and
architectural exceptions in your project’s own CLAUDE.md or
a separate local rule file, letting the host editor combine them through
its layered context loading. Once upstream public mechanisms and local
private rules live in separate files, upstream updates will never
overwrite your local customizations, and automated skill upgrades can
finally run end to end.