APM is a dependency manager for AI agent skills, instructions, prompts, and MCP servers. Think of it as npm for agent configuration.
When this skill applies
- "add a skill to this project"
- "install skills globally"
- "create a skill for this repo"
- "set up apm.yml"
- "update agent dependencies"
Core commands
# Install all dependencies from apm.yml
apm install
Install a specific package
apm install owner/repo apm install owner/repo/skills/skill-name # subdirectory skill apm install owner/repo#v1.0.0 # pinned version
Global (user-scope) install → ~/.claude/skills/apm install -g owner/repo/skills/skill-name
Update all to latestapm install --update # project scope apm install -g --update # global scope
Removeapm uninstall owner/repo apm uninstall -g owner/repo
Inspectapm deps list # project deps apm deps list -g # global deps apm deps tree # dependency tree apm deps tree -g
Security scanapm audit
Dry run (preview without changes)apm install --dry-run
## apm.yml manifest
```yaml
name: my-project
version: 1.0.0
dependencies:
apm:
# GitHub shorthand
- owner/repo
- owner/repo#v1.0.0 # pinned tag
- owner/repo/skills/skill-name # subdirectory
# Non-GitHub hosts
- gitlab.com/org/repo
- git: git@gitlab.com:org/repo.git
path: skills/my-skill
ref: main
# Local path (dev only, not for -g)
- ./packages/my-skill
mcp:
- io.github.github/github-mcp-server
scripts: {}
scripts: example
scripts: is a map of name → command.apm install Register post-setup, one-shot processes during development:
scripts:
postinstall: "echo 'skills installed; restart Claude Code to pick them up'"
verify: "ls -1 .claude/skills | sort"
audit: "apm audit"
Invocation: apm run <name>(e.g., apm run verify)。postinstall は apm install is automatically executed on success (hook). One-shot processes (e.g., apm run audit) are called explicitly.
lockfile (apm.lock.yaml) operation
apm install は apm.lock.yaml is generated. To ensure reproducibility:
- project scope:
apm.lock.yamlを commit (to resolve the same skill version across teams).node_modulessame idea as package-lock - global scope:
~/.apm/apm.lock.yamlis synced with chezmoi, the same version will be installed on a new machine - On CI / new machines, use
apm install --frozen-lockfileto prevent drift (fail if the lockfile does not match the manifest) - Only when you intentionally want to update the lockfile,
apm install --update
Coexistence with chezmoi
If you manage dotfiles with chezmoi, the boundary with APM:
| path | chezmoi | APM |
|---|---|---|
~/.apm/apm.yml |
manage (copy to source) | read |
~/.apm/apm.lock.yaml |
manage (for new machine reproducibility) | generate |
~/.apm/apm_modules/ |
ignore (large cache) | manage |
~/.claude/skills/<name>/ |
ignore (APM-managed is excluded from chezmoi) | deploy destination |
On the chezmoi side, add the following to .chezmoiignore :
.apm/apm_modules
.claude/skills/<apm-managed-name>
Be careful not to have name collisions with self-made skills (chezmoi add those copied to source with). On collision, APM overwrites at install time. For details, see the chezmoi-management skill.
Creating skills in a repository
Follow the agentskills.io open standard. Publishing-focused guide (repo layout, tag/release, dependency declaration, verification checklist) is in references/publishing.md.
Directory structure
my-repo/
└── skills/
└── my-skill/
├── SKILL.md # Required
├── scripts/ # Optional: executable code
├── references/ # Optional: detailed docs
└── assets/ # Optional: templates, resources
SKILL.md format
---
name: my-skill
description: One-line description of what this skill does and when to use it.
---
# Skill body
Instructions for the AI agent. Keep under 500 lines.
Move detailed reference material to references/ directory.
Frontmatter fields
| Field | Required | Constraints |
|---|---|---|
name |
Yes | 1-64 chars, lowercase alphanumeric + hyphens, must match directory name |
description |
Yes | 1-1024 chars, describe what + when |
license |
No | SPDX identifier or license file reference |
compatibility |
No | Environment requirements (max 500 chars) |
metadata |
No | Arbitrary key-value pairs |
Name validation rules
- Lowercase letters, numbers, hyphens only
- Cannot start or end with hyphen
- No consecutive hyphens (
--) - Must match the parent directory name
Users install with
apm install owner/my-repo/skills/my-skill
Skill patterns for library authors
Single skill in a library repo
my-library/
├── skills/
│ └── my-library-guide/
│ └── SKILL.md
├── src/
└── package.json
Multiple skills (monorepo)
my-org-skills/
├── skill-a/
│ └── SKILL.md
├── skill-b/
│ └── SKILL.md
└── skill-c/
└── SKILL.md
Users install individually: apm install owner/my-org-skills/skill-a
Target detection
APM auto-detects deployment targets from project structure:
| Directory exists | Target | Skills deployed to |
|---|---|---|
.claude/ |
claude | .claude/skills/ |
.github/ |
copilot | .github/skills/ |
.cursor/ |
cursor | .cursor/skills/ (if supported) |
.codex/ |
codex | .agents/skills/ |
Override with --target claude or set target: in apm.yml.
Global vs project scope
Project (apm install) |
Global (apm install -g) |
|
|---|---|---|
| Manifest | ./apm.yml |
~/.apm/apm.yml |
| Modules | ./apm_modules/ |
~/.apm/apm_modules/ |
| Lockfile | ./apm.lock.yaml |
~/.apm/apm.lock.yaml |
| Deploy to | ./.claude/skills/ |
~/.claude/skills/ |
Local .apm/ content |
Deployed | Skipped |
Authentication
For private repos, APM resolves auth automatically:
gh auth login(GH_TOKEN) — zero-config if already logged ingit credential fill— OS keychain, SSH keysGITHUB_APM_PATenvironment variable — for CI or explicit setup
No extra configuration needed if gh auth login is done.
Priority and conflict resolution
- Local skills always override dependency skills on name collision
- Dependencies processed in declaration order; first wins
apm install --forceoverwrites local files on collision