AI AgentAI CodingSecurity & Supply Chain

How to Manage Dependencies and Automated Upgrades for Agent Skills

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.

Why Managing a Few Text Files Is Harder Than It Looks

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.

Three Places Where Copying npm + Dependabot Breaks Down

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.

Workflow difference between npm and APM during a Dependabot upgrade

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.

Why Microsoft and GitHub Built Two Different Tools at the Same Time

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.

A Skill Maintenance Workflow That Actually Works

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.

Layered governance workflow for continuous Agent skill synchronization

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.