Compile your package
apm compile reads your instructions primitives from .apm/
(plus any unpacked under apm_modules/) and writes the per-harness
root context files each agent harness reads at startup. It does not
fetch packages, does not resolve dependencies, does not write the
lockfile, and does not deploy other primitive types.
apm compileConcretely, that command rolls your instructions/*.instructions.md
(see Instructions)
into the native rules surface each target expects:
AGENTS.md— the cross-harness root context file (Copilot, Codex, OpenCode, Windsurf all read this).CLAUDE.md— Claude Code’s root context file.GEMINI.md— Gemini CLI’s root context file.- per-harness rules trees that mirror each instruction’s
applyTo:glob:.github/instructions/,.claude/rules/,.cursor/rules/*.mdc,.windsurf/rules/.
Other primitive types — prompts, skills, agents, chatmodes, hooks,
commands — are NOT compiled by this command. They are deployed by
apm install directly into the harness directories that consume them
(.github/prompts/, .agents/skills/, .claude/commands/, etc.).
For the full reach map, see
Primitives and targets. For
the place compile takes in the broader flow, see
Lifecycle.
The authoring loop
Section titled “The authoring loop”edit .apm/instructions/ -> apm compile -> inspect AGENTS.md -> repeatYou will run this loop while writing or refining instructions. Three flags speed it up:
apm compile --watch # re-run on every changeapm compile --validate # check frontmatter and structure; emit nothingapm compile --dry-run # print placement decisions without writing files--validate is the fastest signal that an instruction parses.
--dry-run shows you exactly which AGENTS.md tree would be written
where. --watch is the tight inner loop while you edit prose.
To preview a script that wraps a .prompt.md file, use
apm preview instead. apm compile builds
the root context files; apm preview shows the rewritten command line
your script will execute.
Pick a target
Section titled “Pick a target”By default apm compile detects targets from your workspace (see
detection cascade below). Override it with
--target (-t):
apm compile --target claudeapm compile --target copilot,cursor # comma-separatedapm compile --all # every canonical targetAccepted values: copilot, claude, cursor, opencode, codex,
gemini, windsurf, agent-skills, all. The agent-skills slug
is a no-op for compile (skills are deployed by apm install); it is
accepted in target lists for symmetry only. Unknown slugs are
rejected before any work runs.
Detection cascade
Section titled “Detection cascade”When you omit --target, APM resolves which targets to build in this
order:
- Explicit
--target <slug>flag. - The
targets:field in yourapm.yml. - Auto-detect: any harness root directory (
.github/,.claude/,.cursor/,.codex/,.gemini/,.opencode/,.windsurf/) that already exists. - Fallback:
minimal— writes a singleAGENTS.mdand skips per- harness rules folders.
Pin targets: in apm.yml if you want the same compile output on
every machine. Full rules and the per-target output map live in
Primitives and targets.
Where instructions land
Section titled “Where instructions land”Per target, with the rules shape on disk after compile:
| Target | Root context file | Per-rule output | Compile required? |
|---|---|---|---|
copilot | AGENTS.md | .github/instructions/<name>.instructions.md (preserves applyTo) | No — Copilot reads the per-rule files natively |
claude | CLAUDE.md | .claude/rules/<name>.md | Yes — CLAUDE.md is the entry point |
cursor | — | .cursor/rules/<name>.mdc | Yes — .mdc is Cursor’s rules format |
codex | AGENTS.md (folded) | none — compile-only, no per-file deploy | Yes — folded into AGENTS.md |
gemini | GEMINI.md (folded) | none — compile-only, no per-file deploy | Yes — folded into GEMINI.md |
opencode | AGENTS.md (folded) | none — compile-only, no per-file deploy | Yes — folded into AGENTS.md |
windsurf | — | .windsurf/rules/<name>.md | Yes — compiled to Windsurf rules |
compile vs install
Section titled “compile vs install”| You want to… | Run |
|---|---|
Iterate on instructions in .apm/instructions/ | apm compile |
| Deploy prompts, skills, agents, hooks, commands, MCP | apm install (see Install packages) |
Add a dependency or refresh apm_modules/ | apm install |
| Verify deployed bytes match the lockfile | apm audit |
apm install runs compile internally as part of its integrate phase,
so a normal apm install on a clean checkout already produces
correct AGENTS.md / CLAUDE.md / GEMINI.md output. Reach for
apm compile directly when you are iterating on instructions and
do not want install’s side effects.
Pitfalls
Section titled “Pitfalls”- Confusing compile’s scope. Compile only handles instructions
(and optionally a single chatmode to prepend). If you edit a prompt,
skill, agent, hook, or command,
apm compilewill not redeploy it — runapm installfor that. - Forgetting
--targeton a clean workspace. With no harness folder present and notargets:inapm.yml, the cascade falls back tominimaland writes onlyAGENTS.md. The CLI prints a hint, but the easy fix is to either create the harness folder or pintargets:in your manifest. - Stale
AGENTS.mdafter deleting an instruction. Compile leaves previous output in place by default. Pass--cleanto remove orphaned files generated by earlier runs. - Hand-edited primitives skip the security scan.
apm compiledoes not run the install-time hidden-Unicode scan. After hand-edits, runapm auditbefore publishing. See drift and secure-by-default. - Zero-output success. If compile reports success but writes no
files, your project either has no instructions, or every requested
target was rejected. The CLI surfaces this as a warning — check
targets:and the contents of.apm/instructions/.
Once your instructions compile cleanly into the harnesses you care
about, package the result with apm pack and
share it via a marketplace.