Description 817 -> 324 chars, body 421 -> 237 words, Gotchas 6 -> 2. The five capability clauses, the second trigger register and the prose boundary form go; one trigger clause, the indirect trigger and one boundary clause remain. Four of six Gotchas move into the flow file that every branch needing them already loads. Two stay in the always-loaded body because a dispatch body must carry the gates common to every branch, not just the dispatch table: the MCP secret indirection rule, and the `apm experimental enable registries` precondition. The first pass moved registries into references/configure.md alone, which stranded it -- references/compile.md documents publishing to a registry and references/install.md resolves dependencies through one, and neither points at configure.md. Declaring a registry without the precondition is a silent no-op, so the failure had no signal. Also drops an unsourced claim the compression pass introduced (that apm checks `type:` going forward -- no source supports it), corrects the MCP rationale to install *or* runtime per configuration.md:98, and repoints two apm-orchestrate back-references that pointed at body Gotchas which had moved. Refs #99 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MWb5RQgCL1ye7cGp2RPb2u
5.4 KiB
topic, source_keys
| topic | source_keys | |
|---|---|---|
| configure |
|
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 metadatatype—instructions | skill | hybrid | prompts; constrains what.apm/may contain, so set it before scaffolding content (see Gotchas)targets— which harnesses this package compiles to (plural list form preferred; legacy singulartarget: copilot,claudeCSV form still accepted)includes—autopublishes 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:autoalso does not sweep generic root-level passthrough files (README.md, docs/, sources.md, config files) into theapm packdistribution bundle — seereferences/compile.mddependencies/devDependencies—apm/mcp/lspentries;devDependenciesshare the same shape but are excluded from the shipped artifactscripts— named commands runnable viaapm run <name>compilation— target/strategy/exclude/placement controls forapm compile/apm packpolicy— e.g.fetch_failure_defaultregistries— named registry endpoints for shorthand dependency resolutionmarketplace— owner + packages list; seereferences/marketplace.mdfor the full marketplace workflow
See docs/research/docs/microsoft-apm/configuration.md for the complete annotated schema.
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.ymlmanifest metadata —description,keywords,author,license,homepage,repository. These are compiled verbatim into.claude-plugin/plugin.jsonand.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 — aREADME.md, adocs/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 the same number is also carried in the catalog's
marketplace.packages[] entry, so both copies move together in the same commit. The catalog's own
version follows a separate rule — see references/marketplace.md. apm pack --check-versions
fails the push when a package's version disagrees with the configured strategy, so a bump applied
in only one of the two places is caught, but a bump skipped in both is not: nothing infers intent
from a content diff.
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'stype:field constrains what.apm/may contain — set it before scaffolding content, not after. Changing it later does not retroactively validate what is already on disk.apm experimental enable registriesmust run before anyregistry.*config takes effect. Declaring aregistries:block or runningapm 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 — runapm plugin init --yes --target claude,copilotinstead.