DEV Community

Cover image for How I Set Up Shared Agent Config for Our Team with APM
Dante De Ruwe
Dante De Ruwe

Posted on • Originally published at dantederuwe.com on

How I Set Up Shared Agent Config for Our Team with APM

I set up a shared Git repo for our team to maintain reusable AI agent packages: skills, instructions, coding standards, custom agents. We use APM (Agent Package Manager) to distribute them to every project in one command. Think npm, but for agent config.


Four problems I kept running into

If you've been working with AI coding agents (Copilot, Claude, Cursor, Codex), you've run into a few of these.

Configuration drift

You spend time crafting instructions, coding standards, and skills for your project. It works well. Then you start a new project, and you copy-paste it all over. And again. A few months later, you've got a bunch of repos with their own subtly different versions of the same agent configuration. You improve the frontend guidelines in repo A, but repos B through N never get the update. Nobody notices until something breaks.

Tool lock-in

Each AI tool wants its config in a different place. Copilot reads from .github/, .copilot/, or .agents/ depending on where you put your config, Claude wants .claude/, Cursor has .cursor/ and so on. If you want to support multiple tools, or keep your options open, you end up maintaining the same knowledge in multiple formats and keeping all of those in sync.

No source of truth in the repo

One way to avoid tool lock-in is to not commit those tool-specific folders at all. But then a new team member clones a repo and gets zero agent setup. They build their own from scratch, copy files from a colleague, or grab what they can from a shared location. Everyone ends up with a different setup, and nobody knows which one is "right" for that project.

Shared and project-specific config blur together

Skills that apply to every repo live next to skills that only make sense for one project. If you store agent config in your user directory, it follows you to every repo whether it belongs there or not. If you try to share a setup with a teammate, you're handing over a flat pile of files with no indication of what's generic and what's project-specific. Copying setups between repos drags along things that don't belong.

I was dealing with all of these. It was getting out of hand.

Finding the right tool

I wanted a way to manage agent configuration as dependencies: declarative, versioned, and shareable across repos. Two tools stood out.

skills.sh

If you've looked into sharing agent capabilities before, you may have come across skills.sh (or its npx skills add CLI), built by Vercel. It's a solid tool for installing community skills into your project with a single command.

I started there, but ran into its limits. skills.sh focuses on skills1, which are only one of the primitives you might want to share. I also needed to distribute instructions (coding standards, conventions), custom agent definitions, hooks, and prompt templates.

skills.sh is a good fit if you want to grab a few community skills. I needed something that manages a full stack of agent configuration across teams and projects.

APM: a package manager for agent configuration

APM, or Agent Package Manager , is a tool by Microsoft that does for AI agent setup what npm does for JavaScript dependencies. You declare what agent packages you need in an apm.yml file, run apm install, and it pulls everything in, lockfile included.

APM supports instructions, skills, hooks, agents, prompts, and MCP server configuration as first-class primitives2. It also handles transitive dependencies, lockfiles, and deploying to multiple tools at once.

APM is tool-agnostic. It detects what tools your project uses and deploys the right files to the right places. Write your agent config once, deploy it to Copilot, Claude, Cursor, or any other supported tool.

There's no central registry. Packages are Git repos, resolved over SSH or HTTPS. That means private repos work out of the box if you have Git access to them (APM reuses your existing Git credentials3). If you stop using APM, your deployed files still work in their native format. The APM creator's HN post explains the reasoning: each tool vendor governs its own ecosystem, so a cross-tool dependency manager shouldn't introduce yet another walled garden4.

Dependencies can point to an entire repo, a subfolder inside a repo, or a single file. You can reference GitHub repos with shorthand (owner/repo), use full HTTPS or SSH URLs for any Git host (GitLab, Bitbucket, Azure DevOps, self-hosted), or point to local paths for monorepo setups2. This flexibility is what makes the shared repo pattern work: one Git repo, multiple installable packages as subfolders.

One shared repo, many consuming projects

I took this further. Instead of maintaining agent config per project, I created a central Git repository that acts as a catalog of reusable APM packages.

APM's org packages guide suggests creating separate repos per concern: one for security baselines, one for coding standards. I tried a different approach: one repo with multiple packages as subfolders, connected through internal dependencies. Same composability, less overhead. One repo to manage, one place to review changes. Packages still stay independent and focused.

The structure organizes packages by concern, and each project pulls in what it needs:

agents-repo/
├─ general/ → guidance for ALL projects
├─ development/
│ ├─ _shared/ → shared building blocks (internal dependency)
│ ├─ backend-dotnet/ → .NET-specific guidance
│ └─ frontend-angular/ → Angular-specific guidance

Enter fullscreen mode Exit fullscreen mode

Each folder is its own installable package with its own apm.yml. An Angular frontend project pulls in general and development/frontend-angular. A .NET API project grabs general and development/backend-dotnet.

Why this modularity matters

The packages form a dependency graph.

Both backend-dotnet and frontend-angular declare _shared as a dependency in their own apm.yml. _shared contains things that apply to all development work but not to non-development uses of the agent. Think instructions on how to write commit messages, a skill for addressing PR review comments, conventions around branching and code review. The stack-specific packages build on top of it. backend-dotnet adds .NET conventions like solution structure, API design patterns, unit and integration testing practices, validation steps for builds and formatting. frontend-angular adds things like component architecture guidelines, styling conventions, and its own validation flow for linting and builds.

The underscore-prefixed _shared folder is an internal dependency by convention. Other packages in the repo depend on it, but consuming projects don't reference it. They get it transitively.

The general package sits outside the development/ tree. It holds things that apply to any project, no matter the tech stack: community skills like skill-creator5 and grill-me6, and connections to tools the whole organization uses. Non-developers like functional analysts can pull in general on its own, without any of the development packages.

For an Angular project, the dependency graph could look like this:

consuming project's apm.yml
├─ general (non-technical guidance, community skills)
└─ development/frontend-angular (or backend-dotnet)
   └─ development/_shared (transitive: shared dev tooling and skills)

Enter fullscreen mode Exit fullscreen mode

A consuming project needs two lines in its apm.yml. APM resolves the rest, and _shared comes along because frontend-angular depends on it.

I update the PR review skill in _shared, and every frontend and backend project picks up the change. I tighten the Angular coding standards, and only Angular projects are affected.

How a project consumes shared packages

In any project repo, you reference the shared packages in your apm.yml. In this example, the shared config lives in a repo called agents:

dependencies:
  apm:
    - git: your-git-host.com/your-org/agents
      path: development/frontend-angular
      ref: main

    - git: your-git-host.com/your-org/agents
      path: general
      ref: main

Enter fullscreen mode Exit fullscreen mode

Then run:

apm install

Enter fullscreen mode Exit fullscreen mode

APM resolves all dependencies, including transitive ones, and deploys the instructions, skills, and hooks into the right tool-specific folders (.github/, .claude/, etc.). You don't need to commit these generated files to source control, because apm install can regenerate them at any time.

Add --target <tool> (e.g. --target claude) to deploy for a specific tool only. Add --update to pull the latest versions of all dependencies before installing. You can combine both:

apm install --target claude --update

Enter fullscreen mode Exit fullscreen mode

Pulling in community-built skills

APM also supports pulling in packages from public GitHub repos:

dependencies:
  apm:
    - anthropics/skills/skills/skill-creator
    - mattpocock/skills/productivity/grill-me

Enter fullscreen mode Exit fullscreen mode

The community around shared skills is growing. You can mix community-built skills with your own organization's standards. Found a good skill on GitHub? Add it as a dependency!

Side note: these two specific skills are fantastic. Anthropic's skill-creator5 helps you build, test, and iterate on new skills with evals baked in. Matt Pocock's grill-me6 interviews you about a plan or design until the gaps surface. I added both to my default setup and I can't imagine working without them now.

Local overrides with .apm/

Some projects have quirks that don't belong in a shared package. For these, you can place project-specific instructions, skills, or hooks in a local .apm/ folder right inside your project repo:

my-project/
├─ apm.yml
├─ apm.lock.yaml
└─ .apm/
   ├─ instructions/
   │ └─ local-conventions.instructions.md
   └─ skills/
       └─ my-project-skill/
           └─ SKILL.md

Enter fullscreen mode Exit fullscreen mode

When you run apm install, APM picks up this local content and deploys it alongside your shared dependencies. No extra config in apm.yml needed.

I'm a bit proud of this one, because this feature started as a feature request I filed on the APM repo. Before v0.8.12, the .apm/ folder in your own project wasn't treated the same way as content from installed packages. You had to use workarounds like apm install ./.apm/skills/skill-name to get local skills deployed. That felt inconsistent. The .apm/ folder is the natural place for project-local APM content, so it should work out of the box.

I filed the issue, another user independently confirmed the gap, and the APM team shipped the fix within two days. That kind of responsiveness from an open-source project is refreshing, and it shows APM is still in active development with a team that listens.

What you get from this setup

DRY, for real. Write your coding standards once. Share them across projects. When you improve a skill or update an instruction, consuming projects get the update on their next apm install --update.

Tool independence. I don't want to commit to a single AI tool while this space evolves this fast. APM lets the same package of instructions and skills target Copilot, Claude, Cursor, or any other supported tool. If you switch tools next month, your agent knowledge comes with you.

Different team members can even prefer different tools. Each person runs apm install, and they get the config deployed for their tool of choice.

Easy updates. Updating is a one-liner: apm install --update. You can also pin to specific branches, tags, or commits for stability. Pin to v1.2 for a production project, or follow main if you want the latest.

Smooth team sharing. A new team member runs apm install and has the same agent setup as the rest of the team. The config lives in a repo, versioned and reviewable in pull requests.

Composability. A consuming project picks the packages it needs. No Angular project inherits .NET conventions. No .NET project pulls in frontend linting instructions.

Supply-chain security. Agent instructions have direct access to your codebase and terminal. That makes them a vector worth scanning. APM ships with apm audit, which checks installed packages for hidden Unicode characters, bidi marks, and prompt-injection payloads. It outputs SARIF, so you can plug it into your existing code scanning pipeline7.

CI/CD integration. The lockfile (apm.lock.yaml) pins every dependency to an exact commit SHA, so apm install in a CI pipeline produces the same agent setup as on your local machine. There's also an official GitHub Action if you want to automate installs and audits on every PR.

Offline support. apm pack bundles your resolved dependencies into a portable archive. apm unpack restores them on a machine without Git access. Useful if you work in environments with restricted internet connectivity, or if you want to ship a self-contained agent setup to someone who can't reach your Git host.

Local overrides. Projects with specific quirks can add instructions, skills, or hooks in a local .apm/ folder without touching the shared packages.

Advice if you're doing this too

Keep packages narrow

It's tempting to create one mega-package with all your standards, skills, and hooks bundled together. Resist that. Smaller, composable packages are easier to maintain. They let consuming projects pick up frontend guidance without also inheriting backend conventions they don't need. If two packages share common ground, extract that into a _shared dependency rather than duplicating it.

Only share what's reusable

If guidance applies to one project, keep it local in that project's .apm/ folder. The shared repo is for patterns that apply across projects and teams. Putting single-project quirks in a shared package adds noise for consumers who don't need them, and creates maintenance burden when that project's needs change.

Treat it like code

Use pull requests, reviews, and meaningful commit messages. Your agent configuration shapes how AI tools behave across your entire organization. A bad instruction can propagate to dozens of repos on the next update. Give changes the same review rigor you'd give production code.

Consider not committing generated files

APM's own docs suggest committing the tool-specific folders (.github/, .claude/, .cursor/, etc.)8, and there are valid reasons to do so: cloud agents may need config present in the repo, and committed files give contributors instant context before they run apm install.

I chose not to, for now. My reasoning: these files can be regenerated from apm install at any time, committing them repeats content that already lives in the shared packages, and I don't want the repo to prescribe which AI tool developers should use. If the generated config lives in .gitignore, each developer runs apm install and gets the output for their tool.

I'm not 100% sure this is the right call long-term, but it follows a principle I like: if code is generated from source, don't commit the output.

Try it yourself

If you're managing AI agents across multiple projects and you're still copy-pasting instructions between repos, this setup is worth an afternoon of your time.

  1. Install APM: irm https://aka.ms/apm-windows | iex (Windows) or curl -sSL https://aka.ms/apm-unix | sh (Mac/Linux)
  2. Run apm init in a project
  3. Add a dependency and run apm install

The APM docs walk through each step. The org packages guide covers the shared repo pattern in detail.

If you do set this up, I'd be curious to hear how it works for your team.



  1. skills.sh focuses on installing skills (folders with a SKILL.md) from GitHub repos. 

  2. APM supports instructions, prompts, agents, skills, hooks, chat modes, and MCP server configuration as first-class primitives. Dependencies can be entire repos, subfolders, or single files from any Git host. See the APM dependencies guide

  3. APM resolves authentication through environment variables, gh auth login, or your system's Git credential helper. Private repos on GitHub, GitLab, Bitbucket, and Azure DevOps all work. See the APM authentication guide

  4. From the APM creator's Show HN post: "Why this won't come from plugin vendors: each tool governs its own ecosystem. [...] Nobody governs across tools, resolves cross-plugin dependencies, or gives consumers a lock file for what they actually installed." 

  5. skill-creator by Anthropic. Helps you create, test, and optimize skills with built-in evals. 

  6. grill-me by Matt Pocock. Stress-tests your plans and designs through relentless questioning. 

  7. Marcel Lupo wrote a good DevOps-focused walkthrough of APM that covers the security and CI angles in more detail. 

  8. See the "What to commit" section in the APM quick start guide

Top comments (0)