Files
holocron/plugins/kyberforge/.apm/skills/apm-workflow/references/configure.md
Defame1297 c07ca0767e docs(kyberforge): stop apm-workflow assuming root package versions
The root apm.yml packages[] entries no longer carry version:, and a
version there is a silent override that --check-versions does not
catch. configure.md and marketplace.md now name the package's own
apm.yml as the single source and drop version: from the examples.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 10:33:35 +00:00

6.4 KiB

topic, source_keys
topic source_keys
configure
context7-microsoft-apm

Scaffolding a new package

apm plugin init --yes --target claude,copilot

Run from inside the target package directory, with no positional name argument (see Gotchas). Creates apm.yml + plugin.json in the current directory — it does NOT scaffold a .apm/ skeleton. Primitive subdirectories (.apm/skills/, .apm/agents/, .apm/hooks/) must be created manually as content is migrated into them. Run this once per package (e.g. once per plugins/<name>/ directory in a monorepo-hybrid layout), not once for the whole repo.

apm.yml — required fields

Only name and version (SemVer) are required:

name: my-pkg
version: 1.0.0

apm.yml — top-level keys

  • name, version — required (see above)
  • description, author, license, homepage, repository, keywords — standard package metadata
  • type — instructions | skill | hybrid | prompts; selects how the package is processed at install/compile time. It is a routing selector, not a constraint on what .apm/ may contain (see Gotchas)
  • targets — which harnesses this package compiles to (plural list form preferred; legacy singular target: copilot,claude CSV form still accepted)
  • includes — auto publishes the authoritative local layout as-is; it is not scoped down to what's relevant, so anything narrower needs an explicit repo-path list. Note: auto also does not sweep generic root-level passthrough files (README.md, docs/, sources.md, config files) into the apm pack distribution bundle — see references/compile.md
  • dependencies/devDependencies — apm/mcp/lsp entries; devDependencies share the same shape but are excluded from the shipped artifact
  • scripts — named commands runnable via apm run <name>
  • compilation — target/strategy/exclude/placement controls for apm compile/apm pack
  • policy — e.g. fetch_failure_default
  • registries — named registry endpoints for shorthand dependency resolution
  • marketplace — owner + packages list; see references/marketplace.md for the full marketplace workflow

Bumping a package's own version (repo policy)

apm ships no version-bump command, so version: in a package's own apm.yml is a hand edit. Policy: bump a package's own apm.yml version: whenever anything that reaches its compiled output changes. Two triggers, not one:

  • Its .apm/ content — a new or removed skill/agent/hook, or a substantive edit to an existing one.
  • Its own apm.yml manifest metadata — description, keywords, author, license, homepage, repository. These are compiled verbatim into .claude-plugin/plugin.json and .github/plugin/plugin.json, so editing them republishes the package's public description under an unchanged version number, which is the same defect as shipping changed content silently. Purely local edits that reach no compiled output — a README.md, a docs/ page — do not require a bump on their own.

The version belongs to the package, not to the repo: editing plugins/foo/.apm/ never bumps plugins/bar/apm.yml.

Under a per_package strategy this version: is the single source: when a catalog's marketplace.packages[] entry omits version:, apm pack reads it from the package's apm.yml. Do not restate it there. A version: on the entry is an override, not a copy — it silently wins in the compiled marketplace.json, and apm pack --check-versions still reports [matches] when it disagrees with the package's own number, so drift between the two is never caught. Set one only when an override is the intent. A skipped bump is not caught either: nothing infers intent from a content diff. The catalog's own version follows a separate rule — see references/marketplace.md.

Dependency reference forms

dependencies.apm entries accept: a pinned tag (owner/repo#tag), a plain repo (uses default branch), a single primitive path within a repo, a raw git URL, a git:/path:/ref: object for finer control, or a local relative path (./packages/my-shared-skills).

MCP server secrets

${VAR} indirection is required for MCP server secrets (headers, env vars) in apm.yml, never literal values — see SKILL.md Gotchas.

Registries (config-level, not apm.yml)

Any git repo is a valid package source by default — no registry required. To declare named registries for shorthand dependency resolution:

apm experimental enable registries   # required first — see Gotchas
apm config set registry.corp-main.url https://artifactory.corp.example.com/apm
apm config set registry.corp-main.token eyJ...
apm config set registry.corp-main.default true

apm config get/apm config unset manage individual keys the same way.

Gotchas

  • apm.yml's type: field validates nothing about .apm/. It selects processing: instructions compiles to AGENTS.md only, skill installs a native skill only, prompts emits commands only, hybrid does both (see apm_cli/models/validation.py, PackageContentType). apm checks only that the value parses to one of those four strings; no check anywhere compares it against the primitives actually on disk, and no mismatch diagnostic exists. A package declaring type: instructions while shipping .apm/skills/ therefore raises no error — the mismatch resolves silently, either by omitting that primitive from the install/compile output or, in apm 0.28.0 where get_effective_type() routes off the on-disk layout and never reads the declared field, by ignoring the declared value outright. Both directions are silent: apm install and apm compile can exit 0 having shipped none of the primitives you expected. Set type: to cover every primitive the package ships, and confirm the deployed output rather than the exit code.
  • apm experimental enable registries must run before any registry.* config takes effect. Declaring a registries: block or running apm config set registry.* without it silently does nothing — no error, no warning.
  • apm plugin init <name> run with a positional name argument, from inside a directory already named <name>, creates a wrongly-nested <name>/<name>/ subdirectory — it treats the positional arg as "create a new project directory named X," not "confirm the current directory is X." Fix: omit the positional argument entirely when already cd'd into the target package directory — run apm plugin init --yes --target claude,copilot instead.