Sharing Agent Skills with APM Profiles, Inheritance, and Private Repos

Get Site as Markdown

The more I work with agents — alone or in a team — the more I want to share skills across projects instead of copying them. In a team this matters more: you want quality-assured skills everyone uses, not five variants drifting apart.

That quickly creates one requirement: profiles, ideally with inheritance. A Go developer environment needs the base developer conventions plus Go extras; a docs repo needs base plus writing extras.

Microsoft’s APM implements exactly this model: skills live in a shared package, profiles compose them via dependencies.

One line, like apm install dhcgn/personal-dev-skills/profiles/dev-go, adds a whole agent profile to a folder. That really simplifies the setup for new projects and ensures consistency across different environments.

I published my starting point at dhcgn/personal-dev-skills. The second requirement came from enterprise work: the same mechanism had to work with non-public repos, without a second toolchain. See the documentation for the various ways to add APM packages.

Below I show what I built, how profiles work as an implicit feature — a folder with an apm.yml that depends on other packages — and how to consume those skill packages. I am still at the beginning with this setup; the repo will evolve fast, so check back there for the current state.

Prerequisites

  • apm CLI (install)
  • My Repo: dhcgn/personal-dev-skills
  • Targets in this repo: opencode (see targets: in profile manifests), because this is a good generic AI-agent target approach for various projects.

How my repo is organized

Two levels, details with the consumer story below:

  • .apm/skills/ — the actual primitives (rtk, gh, wsl, go-1-27-features, go-linq, glossary-*, etc.).
  • profiles/<name>/apm.yml — thin compositions that depend on skills or on other profiles (dev-go and dev-web inherit dev-base and add only their delta).
  • Root apm.yml — umbrella package, currently only upstream deps.

Consumer first: one install per project

I use profiles from the consumer side. Producer details (how I compile them) come later — daily work is install and update.

1. I start a Go solution — one command

Empty folder, Go project, agents with no conventions. I run:

apm install dhcgn/personal-dev-skills/profiles/dev-go

That is the whole setup. I get all skills of dev-go and my baseline developer profile, because dev-go depends on dev-base:

# profiles/dev-go/apm.yml (v1.2.0, excerpt)
name: dev-go
targets:
  - opencode
dependencies:
  apm:
    - dhcgn/personal-dev-skills/profiles/dev-base
    - dhcgn/personal-dev-skills/.apm/skills/go-1-27-features
    - dhcgn/personal-dev-skills/.apm/skills/go-linq
    - dhcgn/personal-dev-skills/.apm/skills/go-newest-version
    - dhcgn/personal-dev-skills/.apm/skills/github-markdown-images
    - spf13/go-skills

No extra flag for the baseline. APM resolves transitively: dev-go pulls dev-base, dev-base pulls ponytail and my small helpers:

# profiles/dev-base/apm.yml (v1.2.0, excerpt)
name: dev-base
targets:
  - opencode
dependencies:
  apm:
    - dhcgn/personal-dev-skills/.apm/skills/gh
    - dhcgn/personal-dev-skills/.apm/skills/rtk
    - dhcgn/personal-dev-skills/.apm/skills/wsl
    - dhcgn/personal-dev-skills/.apm/skills/glossary-init
    - dhcgn/personal-dev-skills/.apm/skills/glossary-create
    - dhcgn/personal-dev-skills/.apm/skills/glossary-search
    - DietrichGebert/ponytail

Other stacks are the same pattern:

apm install dhcgn/personal-dev-skills/profiles/dev-base  # baseline only
apm install dhcgn/personal-dev-skills/profiles/dev-web   # baseline + web delta

dev-web is currently just dev-base plus its own delta — inheritance keeps it one line:

# profiles/dev-web/apm.yml (v1.2.0)
dependencies:
  apm:
    - dhcgn/personal-dev-skills/profiles/dev-base

There is no separate “profile” primitive. A profile is an implicit feature: a folder with an apm.yml that depends on other packages.

2. What landed on disk

apm list
cat AGENTS.md
ls .agents/skills
  • apm.yml now lists the profile under dependencies.apm.
  • apm.lock.yaml pins exact commits and content hashes — teammates get the identical tree on apm install.
  • AGENTS.md starts with <!-- Generated by APM CLI ... --> and contains the merged instructions (e.g. rtk go test prints failures only).
  • .agents/skills/ holds the harness-neutral skills; apm_modules/ is cache only (gitignored, rebuilt from the lockfile).

3. Staying current

Skills evolve. From the consumer side I only need two verbs (Update and refresh):

apm outdated          # what moved upstream?
apm update            # refresh to latest matching refs (asks first)

To pin a known-good state I add a ref:

dependencies:
  apm:
    - dhcgn/personal-dev-skills/profiles/dev-go#v1.2.0

Then apm install reproduces it, apm update moves it forward. I commit apm.yml, apm.lock.yaml, and the deployed files (.agents/, AGENTS.md) together.

Skill inventory

I referenced the same third-party skills in my profiles as needed and added some of my own.

My skills are listed at https://github.com/dhcgn/personal-dev-skills/tree/main/.apm/skills.

My skills

  • devcontainer-debug-windows — Debug DevContainer startup failures on Windows with trace logging to devcontainer-up.log.
  • devsecops-subdomain-finder — Enumerate subdomains of an apex domain via Certificate Transparency log search.
  • encryption-and-cybersecurity-in-development — Encryption overview: use established libs, age format, KDFs, PoW, OWASP practices.
  • gh — GitHub CLI patterns: structured --json output, pagination, search vs. list.
  • gh-skill — Manage agent skills with gh skill (discover, preview, install, update, publish).
  • github-markdown-images — README images must use HTML <img> tags, not Markdown, for github.com rendering.
  • glossary-create — Add a term to a generated glossary: define once in code, ref: everywhere else.
  • glossary-create-issue — Draft GitHub issues reusing glossary keys with repo-scoped code-search links.
  • glossary-init — Bootstrap a source-comment glossary (go:generate, topics, stale/broken-ref gates) from zero.
  • glossary-search — Search glossary key definitions and usages from bash/PowerShell (read-only).
  • go-1-27-features — Safe-to-use Go 1.25–1.27 language, runtime, and stdlib features.
  • go-linq — LINQ-style queries via ahmetb/go-linq/v5 (Go 1.27+, type-safe).
  • go-newest-version — Check latest Go version with curl https://go.dev/VERSION?m=text.
  • image-analysis — Check images for corruption/metadata with local tools (jpegtran, ffprobe, exiftool).
  • lsp-setup — Install and configure an LSP server for Copilot CLI (vendored from github/awesome-copilot).
  • markdown-from-website — Fetch clean AI-ready Markdown via markdown.new instead of raw HTML.
  • rtk — Prefix shell commands with rtk to filter output before LLM context (rtk-ai/rtk).
  • wsl — Run Linux on Windows via WSL, incl. path translation with wslpath.