Skip to content

Primitives and Targets

A primitive is a unit of agent context APM can manage: instructions, prompts, agents, skills, hooks, commands, plugins, and MCP servers. A target is a harness APM compiles primitives for: Copilot, Claude, Cursor, Codex, Gemini, Antigravity, OpenCode, and Windsurf. The matrix below is the full reach map. For any primitive X and harness Y, it tells you whether Y receives X natively, receives it after APM transforms it, or does not receive it at all.

This page is the canonical reference. Tutorials and how-tos link here; do not duplicate.

APM authors place primitives under .apm/ in their package. APM discovers, validates, and routes them at apm install (per-target) and apm compile (aggregated context files).

Coding standards and guidelines, scoped by file glob.

  • Source: .apm/instructions/*.instructions.md
  • Frontmatter: description (required), applyTo (optional glob)
  • Deep dive: see Anatomy of an APM Package

Executable, parameterized AI workflows. Equivalent to a callable program for an LLM.

  • Source: .apm/prompts/*.prompt.md
  • Also surfaced as commands for harnesses that read slash-commands (see commands row below).
  • Deep dive: Prompts guide

Specialized AI personalities with tool boundaries and expertise scope.

  • Source: .apm/agents/*.agent.md (legacy: .chatmode.md)
  • Deep dive: Agent workflows

Cross-tool meta-guides authored in the agent-skills SKILL.md format. Bundled resources live alongside the skill.

  • Source: .apm/skills/<name>/SKILL.md or root SKILL.md
  • Deep dive: Skills guide

Lifecycle event handlers (e.g. PreToolUse, PostToolUse, Stop) that invoke scripts.

Slash-commands for harnesses that expose a command palette. Sourced from .apm/prompts/ — there is no separate .apm/commands/ directory. The same .prompt.md file becomes Copilot’s prompt and Claude’s /command.

A packaging format. A plugin is a self-contained bundle (plugin.json or .claude-plugin/) that ships a set of primitives. APM normalizes plugins at install time into the same primitives the rest of this page describes.

Model Context Protocol servers declared as dependencies. APM writes the per-harness MCP config file at install time.

  • Source: apm.yml -> dependencies.mcp:
  • Deep dive: MCP servers

GitHub Copilot CLI canvas extensions: a directory bundle whose entry file is extension.mjs (executable Node.js). Copilot-only. Behind the canvas experimental flag; dependency-provided canvases are blocked unless --trust-canvas-extensions is passed, because they are arbitrary executable code. Project scope deploys to .github/extensions/; --global deploys a dependency canvas to ~/.copilot/extensions/ (always requiring the trust flag).

  • Source: .apm/extensions/<name>/extension.mjs
  • Deploys to: .github/extensions/<name>/ (project) or ~/.copilot/extensions/<name>/ (--global)
  • Deep dive: Canvas extensions

Each target is identified by a slug used in apm.yml’s targets: field and on the --target flag. The output directory is where APM writes deployed primitives. The “agent-skills” and “copilot-cowork” targets exist in the registry but are not end-user runtimes; they are covered separately in the experimental reference.

SlugOutput directoryCompile family
copilot.github/ (project), ~/.copilot/ (user scope)vscode
claude.claude/claude
cursor.cursor/agents
codex.codex/ plus .agents/ for skillsagents
gemini.gemini/gemini
antigravity.agents/ (project), ~/.gemini/ (user)agents
opencode.opencode/ (project), ~/.config/opencode/ (user)agents
windsurf.windsurf/ (project), ~/.codeium/windsurf/ (user)agents
kiro.kiro/ (project and user)agents

Notes per target:

  • copilot — GitHub Copilot (CLI + IDE). User-scope partial: prompts and instructions are project-scope only.
  • claude — Claude Code. Full user-scope support. Hooks merge into .claude/settings.json rather than living as separate files.
  • cursor — Cursor IDE. Rules use the .mdc extension. Instructions are not deployable at user scope (Cursor exposes them via the Settings UI only).
  • codex — Codex CLI. Agents and hooks use TOML; skills use the cross-tool .agents/ directory.
  • gemini — Gemini CLI. Commands are TOML. Hooks merge into .gemini/settings.json. No native agents or instructions primitives — both arrive via compiled context files.
  • antigravity — Google Antigravity CLI (agy), successor to Gemini CLI. Explicit-only target (--target antigravity); the .agents/ root is shared, so it is never auto-detected and is not part of --target all. Instructions deploy as rules under .agents/rules/. Skills use .agents/skills/. Hooks use Antigravity’s native .agents/hooks.json schema. MCP servers write to a dedicated .agents/mcp_config.json. No commands primitive (legacy Gemini commands convert to skills upstream).
  • opencode — OpenCode. No hooks support.
  • windsurf — Windsurf / Cascade. No native agents primitive — Cascade auto-invokes any SKILL.md by its description: frontmatter, so personas ship as skills. Workflows are the harness’s name for commands.
  • kiro — Kiro IDE. Instructions become steering files, skills stay as SKILL.md folders, hooks are individual JSON files, and MCP lands in .kiro/settings/mcp.json.

Rows are primitives, columns are harnesses. Cell legend:

  • native — the harness reads this primitive directly from its own format and directory; APM writes the file as-is or in the harness’s documented format.
  • compiled — APM transforms the primitive into a different format the harness understands (e.g. a prompt becomes a TOML command, an instruction is folded into AGENTS.md).
  • unsupported — APM does not deliver this primitive to this harness.
  • gated — delivered behind an explicit declaration or trust flag.
PrimitiveCopilotClaudeCursorCodexGeminiAntigravityOpenCodeWindsurfKiro
instructionsnativenativenativecompiledcompilednativecompilednativenative
promptsnativecompiledcompiledunsupportedcompiledcompiledcompiledcompiledunsupported
agentsnativenativecompiledcompiledunsupportedunsupportednativeunsupportedunsupported
skillsnativenativenativenativenativenativenativenativenative
hooksnativenativenativenativenativenativeunsupportednativenative
commandsunsupportednativecompiledunsupportedcompiledunsupportedcompiledcompiledunsupported
pluginscompiledcompiledcompiledcompiledcompiledcompiledcompiledcompiledcompiled
MCP serversnativenativenativenativenativenativenativenativenative
canvas (experimental)gatedunsupportedunsupportedunsupportedunsupportedunsupportedunsupportedunsupportedunsupported

How to read a cell:

  • instructions / claude = native — APM writes .claude/rules/<name>.md; Claude Code reads it directly.
  • prompts / claude = compiled — APM transforms .apm/prompts/<n>.prompt.md into .claude/commands/<n>.md. The prompt becomes a /command.
  • agents / gemini = unsupported — Gemini CLI has no agents primitive; APM does not deliver .agent.md files to it. Their content still reaches Gemini through the compiled GEMINI.md if referenced from instructions.
  • agents / antigravity = unsupported — Antigravity CLI has no agents primitive; their content reaches Antigravity through the compiled AGENTS.md.
  • instructions / antigravity = native — APM deploys instructions as plain-markdown rules under .agents/rules/.
  • commands / copilot = unsupported — Copilot has no commands primitive; the same source .prompt.md reaches Copilot as a native prompt instead.
  • plugins / * — APM unpacks the plugin at install time into the primitives in the rows above; routing then follows those rows.
  • MCP servers / * — APM writes the harness’s standard MCP config. Transitive MCP servers brought in by deep dependencies must be explicitly declared or trusted with --trust-transitive-mcp — effectively gated for those, native for direct dependencies.
  • canvas / copilot = gated — requires the canvas experimental flag; a canvas shipped by a dependency is executable code, so it stays blocked until you pass --trust-canvas-extensions. First-party canvases in your own package deploy at project scope once the flag is on. With --global, a dependency canvas deploys to ~/.copilot/extensions/ and always requires the trust flag (first-party global install is not supported). Every other harness is unsupported: a canvas is a Copilot CLI construct only.

apm compile defaults to distributed placement: instead of one monolithic AGENTS.md / CLAUDE.md at the repo root, APM writes a focused target file next to each directory that has matching instructions. The placement is driven by each instruction’s applyTo: glob in its frontmatter. For example, an instruction with applyTo: "scripts/**" lands in scripts/AGENTS.md rather than the root file.

This means a fresh apm compile may create new AGENTS.md / CLAUDE.md files in subdirectories you did not previously touch. That is intentional — it follows the Minimal Context Principle so each agent only loads instructions relevant to the directory it is working in. If you prefer one combined file at the project root, run apm compile --single-agents (or set compilation.single_file: true in apm.yml).

To remove distributed files that are no longer produced (e.g. after deleting or rescoping an instruction), run apm compile --clean.

For the full strategy reference and flag semantics, see apm compile and manifest schema: compilation.strategy.

Mark a primitive as dev-only when it is useful to the package author but should not ship to consumers: release checklists, internal debugging agents, test-fixture skills, anything tied to your own infrastructure. Author such primitives outside .apm/ (typically dev/) and reference them under devDependencies in apm.yml. apm pack excludes them; apm install --dev deploys them locally.

Full pattern, the three pack-time gotchas, and verification steps: Dev-only primitives.

apm install and apm compile resolve active targets in this order:

  1. Explicit --target <slug> flag, when passed.
  2. The targets: field in apm.yml, when present.
  3. Auto-detection: any harness whose root directory (.github/, .claude/, .cursor/, .codex/, .gemini/, .opencode/, .windsurf/, .kiro/) already exists in the workspace is selected.
  4. Fallback: minimal — APM writes AGENTS.md only and skips folder integration. Create one of the harness folders above (or set targets: explicitly) for full integration.

Unknown target slugs are rejected upstream by the manifest parser; they never silently fall through to the default.

For flag reference and exact resolution semantics, see apm compile and apm install. For policy controls that further restrict which primitives a target may deploy, see Governance guide.