refactor(kyberforge): retrofit apm-workflow to the ADR-0020 contract
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
This commit is contained in:
@@ -19,10 +19,10 @@ You resolve the package root once per dispatched operation (the directory contai
|
|||||||
|
|
||||||
These are non-negotiable regardless of `confirm` or any skill-local override:
|
These are non-negotiable regardless of `confirm` or any skill-local override:
|
||||||
- `apm publish` claims a version on a registry — treat it as irreversible. Refuse without explicit `confirm: true`; always dispatch with `--dry-run -v` first and surface that output to the caller before the real publish, even when `confirm: true` was given.
|
- `apm publish` claims a version on a registry — treat it as irreversible. Refuse without explicit `confirm: true`; always dispatch with `--dry-run -v` first and surface that output to the caller before the real publish, even when `confirm: true` was given.
|
||||||
- Never guess the marketplace-add direction from context — resolve strictly from the operation name (`add-package` vs `add-marketplace`); see apm-workflow/SKILL.md Gotchas for why the two are easy to conflate.
|
- Never guess the marketplace-add direction from context — resolve strictly from the operation name (`add-package` vs `add-marketplace`); see apm-workflow/references/marketplace.md Gotchas for why the two are easy to conflate.
|
||||||
- `apm.yml`'s `type:` field constrains what `.apm/` may contain — when scaffolding (`init-package`), set `type:` before any primitive content is added; do not defer it.
|
- `apm.yml`'s `type:` field constrains what `.apm/` may contain — when scaffolding (`init-package`), set `type:` before any primitive content is added; do not defer it.
|
||||||
- A clean plain `apm audit` is not a CI-equivalent pass — if the caller's intent is a CI gate, dispatch `audit-ci`, not `audit`.
|
- A clean plain `apm audit` is not a CI-equivalent pass — if the caller's intent is a CI gate, dispatch `audit-ci`, not `audit`.
|
||||||
- Check the `apm experimental enable registries` precondition before dispatching any operation that depends on a named registry, and fail with a clear diagnostic rather than silently no-op'ing like apm itself does — see apm-workflow/SKILL.md Gotchas for the underlying constraint.
|
- Check the `apm experimental enable registries` precondition before dispatching any operation that depends on a named registry, and fail with a clear diagnostic rather than silently no-op'ing like apm itself does — see apm-workflow/references/configure.md Gotchas for the underlying constraint (summarised in its SKILL.md Gotchas).
|
||||||
- You are read-only against the working tree. Never create, edit, or delete a file — not an `apm.yml`, not a `.apm/` primitive, not compiled output, not a scratch note. `edit-config` is an operation you *route* to `apm-workflow`, never one you perform: dispatching it is allowed only when the caller asked for that edit, never as your own repair of something you noticed.
|
- You are read-only against the working tree. Never create, edit, or delete a file — not an `apm.yml`, not a `.apm/` primitive, not compiled output, not a scratch note. `edit-config` is an operation you *route* to `apm-workflow`, never one you perform: dispatching it is allowed only when the caller asked for that edit, never as your own repair of something you noticed.
|
||||||
|
|
||||||
When invoked, you:
|
When invoked, you:
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ Requires the `apm` binary and (for runtime-driven scripts) an agent runtime alre
|
|||||||
|
|
||||||
| File | Purpose |
|
| File | Purpose |
|
||||||
|------|---------|
|
|------|---------|
|
||||||
| `SKILL.md` | Dispatch table and cross-cutting gotchas |
|
| `SKILL.md` | Dispatch table and the two gotchas common to every branch (MCP secret indirection, the `experimental enable registries` precondition) |
|
||||||
| `references/configure.md` | apm.yml schema, apm plugin init, dependency forms, MCP secrets, registries |
|
| `references/configure.md` | apm.yml schema, apm plugin init, dependency forms, MCP secrets, `includes:`, registries; `type:` and `experimental enable registries` traps |
|
||||||
| `references/install.md` | apm install, apm install [PACKAGE_REF], --update, --target agent-skills |
|
| `references/install.md` | apm install, apm install [PACKAGE_REF], --update, --target agent-skills |
|
||||||
| `references/marketplace.md` | Building/registering a marketplace, package registration, versioning, Claude Code reserved-name/publish-confirm gotchas |
|
| `references/marketplace.md` | Building/registering a marketplace, `marketplace add` vs `package add`, package registration, versioning, Claude Code reserved-name/publish-confirm gotchas |
|
||||||
| `references/compile.md` | apm compile / pack / publish / run, claude plugin validate agents/ gotcha |
|
| `references/compile.md` | apm compile / pack / publish / run, claude plugin validate agents/ gotcha |
|
||||||
| `references/audit.md` | apm audit, apm audit --ci, apm marketplace check, CI wiring, frozen installs, claude plugin validate terminal check |
|
| `references/audit.md` | apm audit vs apm audit --ci (they check different things), apm marketplace check, CI wiring, frozen installs, claude plugin validate terminal check |
|
||||||
| `references/sources.md` | Provenance chain — research sources that informed this skill |
|
| `references/sources.md` | Provenance chain — research sources that informed this skill |
|
||||||
|
|||||||
@@ -1,18 +1,11 @@
|
|||||||
---
|
---
|
||||||
name: apm-workflow
|
name: apm-workflow
|
||||||
description: >
|
description: >
|
||||||
Use when the user wants to author or edit an apm.yml manifest
|
Use when the user wants to author, scaffold, install, compile, publish, or
|
||||||
(dependencies, scripts, compilation, policy, registries), scaffold a new
|
audit an apm package, an apm.yml manifest, or an apm marketplace, or register
|
||||||
apm package or marketplace (apm plugin init, apm marketplace init/package
|
someone else's to consume — even when they do not say "apm"
|
||||||
add), install or resolve dependencies declared in apm.yml (apm install,
|
explicitly, e.g. "set up the package manifest". Not the apm binary itself or
|
||||||
apm install [PACKAGE_REF]), register a marketplace as a consumer,
|
an agent runtime -> `apm-install`.
|
||||||
compile/pack/publish an apm package for distribution, or validate/audit
|
|
||||||
apm.yml and installed content (apm audit, apm marketplace check) — even if
|
|
||||||
the user doesn't say "apm" explicitly, e.g. "set up the package manifest",
|
|
||||||
"scaffold this as an apm package", "install my apm dependencies", "resolve
|
|
||||||
apm.yml deps", "build the distributable", "check this passes CI". Do not
|
|
||||||
use for installing the apm binary itself or setting up an agent runtime —
|
|
||||||
use apm-install for those.
|
|
||||||
metadata:
|
metadata:
|
||||||
category: apm
|
category: apm
|
||||||
source_keys:
|
source_keys:
|
||||||
@@ -21,12 +14,8 @@ metadata:
|
|||||||
|
|
||||||
## Gotchas
|
## Gotchas
|
||||||
|
|
||||||
- `apm.yml`'s `type:` field (`instructions`, `skill`, `hybrid`, `prompts`) constrains what `.apm/` may contain — set it before scaffolding content, not after. Changing it later doesn't retroactively validate what's already on disk.
|
- MCP server secrets in `apm.yml` (headers, env vars) must use `${VAR}` indirection, never literal values, so they resolve at install or runtime and are never committed.
|
||||||
- `includes: auto` publishes the authoritative local layout as-is. Anything narrower needs an explicit repo-path list — don't assume `auto` means "scoped down to what's relevant." Note: `auto` still excludes generic root-level passthrough files (README.md, docs/, sources.md, config files) from the `apm pack` distribution bundle — see `references/compile.md`.
|
- `apm experimental enable registries` must run before a `registries:` block or `registry.*` config takes effect anywhere — configure, install or publish. Without it, declaring one silently does nothing: no error, no warning.
|
||||||
- `apm marketplace add` (registering a marketplace as a *consumer*, pointing at someone else's catalog) and `apm marketplace package add` (registering a package by remote reference — `owner/repo`, host URL, or full URL — into a marketplace you're building) are opposite directions of the same command family — don't conflate them. `package add` does NOT accept local paths; a local package is registered by hand-editing `apm.yml`'s `marketplace.packages[]` directly — see `references/marketplace.md`.
|
|
||||||
- MCP server secrets (headers, env vars) inside `apm.yml` must use `${VAR}` indirection, never literal values, so they're resolved at install/runtime and never committed to the manifest.
|
|
||||||
- `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.
|
|
||||||
- Plain `apm audit` and `apm audit --ci` check different things: plain `apm audit` scans deployed files for hidden Unicode only; `--ci` additionally runs lockfile-consistency checks, install-replay drift detection, and org policy checks. A clean plain `apm audit` is not a CI-equivalent pass.
|
|
||||||
|
|
||||||
## Step 1 — Dispatch
|
## Step 1 — Dispatch
|
||||||
|
|
||||||
@@ -38,7 +27,7 @@ metadata:
|
|||||||
| `/apm-workflow compile` | Generate per-target output, bundle, or publish (`apm compile`, `apm pack`, `apm publish`) | `references/compile.md` |
|
| `/apm-workflow compile` | Generate per-target output, bundle, or publish (`apm compile`, `apm pack`, `apm publish`) | `references/compile.md` |
|
||||||
| `/apm-workflow audit` | Validate integrity/policy or wire a CI gate (`apm audit`, `apm audit --ci`) | `references/audit.md` |
|
| `/apm-workflow audit` | Validate integrity/policy or wire a CI gate (`apm audit`, `apm audit --ci`) | `references/audit.md` |
|
||||||
|
|
||||||
Read only the reference file matching the requested action — each is self-contained for its concern.
|
Read only the reference file matching the requested action — each is self-contained for its concern, and each carries the traps specific to its flow.
|
||||||
|
|
||||||
## Step 2 — Execute
|
## Step 2 — Execute
|
||||||
|
|
||||||
|
|||||||
@@ -53,3 +53,7 @@ jobs:
|
|||||||
## Claude Code validation is a separate terminal check
|
## Claude Code validation is a separate terminal check
|
||||||
|
|
||||||
For packages compiling to the `claude` target, also run `claude plugin validate [--strict]` against the compiled output as a terminal check. `apm audit`/`apm audit --ci` do not check Claude Code-marketplace-specific schema rules (reserved prefixes, the `agents/` stray-file behavior — see `references/compile.md` — etc.), so they don't substitute for it.
|
For packages compiling to the `claude` target, also run `claude plugin validate [--strict]` against the compiled output as a terminal check. `apm audit`/`apm audit --ci` do not check Claude Code-marketplace-specific schema rules (reserved prefixes, the `agents/` stray-file behavior — see `references/compile.md` — etc.), so they don't substitute for it.
|
||||||
|
|
||||||
|
## Gotchas
|
||||||
|
|
||||||
|
- Plain `apm audit` and `apm audit --ci` check different things: plain `apm audit` scans deployed files for hidden Unicode only; `--ci` additionally runs lockfile-consistency checks, install-replay drift detection, and org policy checks. A clean plain `apm audit` is not a CI-equivalent pass.
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ Bundles a producer package into a distributable artifact. Default to `--dry-run
|
|||||||
|
|
||||||
`includes: auto` does NOT sweep generic root-level passthrough files (README.md, docs/, sources.md, config files, etc.) into the `apm pack` distribution bundle (`build/<name>-<version>`) — only `.apm/` primitives, the compiled `plugin.json`, and the content-aware `.mcp.json` handling above make it into that bundle. This does not affect Claude Code's own plugin loading, which reads a plugin's working directory directly via its `source:` path in `marketplace.json`, not the `apm pack` bundle — but it matters for anyone relying on the packed bundle for distribution via `apm install`.
|
`includes: auto` does NOT sweep generic root-level passthrough files (README.md, docs/, sources.md, config files, etc.) into the `apm pack` distribution bundle (`build/<name>-<version>`) — only `.apm/` primitives, the compiled `plugin.json`, and the content-aware `.mcp.json` handling above make it into that bundle. This does not affect Claude Code's own plugin loading, which reads a plugin's working directory directly via its `source:` path in `marketplace.json`, not the `apm pack` bundle — but it matters for anyone relying on the packed bundle for distribution via `apm install`.
|
||||||
|
|
||||||
Run `apm audit` after compile/pack, not before — audit scans deployed/compiled output, not the source `apm.yml` manifest; see `references/audit.md`.
|
Run `apm audit` after compile/pack, not before — audit scans deployed/compiled output, not the source `apm.yml` manifest. Plain `apm audit` is not the CI-equivalent pass (that is `apm audit --ci`, which checks strictly more); see `references/audit.md`.
|
||||||
|
|
||||||
## Publish
|
## Publish
|
||||||
|
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ version: 1.0.0
|
|||||||
|
|
||||||
- `name`, `version` — required (see above)
|
- `name`, `version` — required (see above)
|
||||||
- `description`, `author`, `license`, `homepage`, `repository`, `keywords` — standard package metadata
|
- `description`, `author`, `license`, `homepage`, `repository`, `keywords` — standard package metadata
|
||||||
- `type` — `instructions | skill | hybrid | prompts`; constrains `.apm/` contents
|
- `type` — `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 singular `target: copilot,claude` CSV form still accepted)
|
- `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, or list explicit repo paths. Note: `auto` 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`
|
- `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
|
- `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>`
|
- `scripts` — named commands runnable via `apm run <name>`
|
||||||
- `compilation` — target/strategy/exclude/placement controls for `apm compile`/`apm pack`
|
- `compilation` — target/strategy/exclude/placement controls for `apm compile`/`apm pack`
|
||||||
@@ -68,14 +68,14 @@ from a content diff.
|
|||||||
|
|
||||||
## MCP server secrets
|
## MCP server secrets
|
||||||
|
|
||||||
`${VAR}` indirection is required for MCP server secrets in `apm.yml` — see SKILL.md Gotchas.
|
`${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`)
|
## 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:
|
Any git repo is a valid package source by default — no registry required. To declare named registries for shorthand dependency resolution:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
apm experimental enable registries # required first — see SKILL.md Gotchas
|
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.url https://artifactory.corp.example.com/apm
|
||||||
apm config set registry.corp-main.token eyJ...
|
apm config set registry.corp-main.token eyJ...
|
||||||
apm config set registry.corp-main.default true
|
apm config set registry.corp-main.default true
|
||||||
@@ -85,4 +85,6 @@ apm config set registry.corp-main.default true
|
|||||||
|
|
||||||
## Gotchas
|
## Gotchas
|
||||||
|
|
||||||
|
- `apm.yml`'s `type:` 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 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.
|
- `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.
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ hook.
|
|||||||
|
|
||||||
## Gotchas
|
## Gotchas
|
||||||
|
|
||||||
|
- `apm marketplace add` and `apm marketplace package add` point in opposite directions and are easy to conflate: `add` registers someone else's catalog for you to *consume*; `package add` registers a package by remote reference (`owner/repo`, host URL, or full URL) into a marketplace you are *building*. `package add` does not accept a local path — register a local package by hand-editing `marketplace.packages[]`, as above.
|
||||||
- Only `claude` and `codex` marketplace output profiles exist in apm 0.28.0 — confirmed via source (`apm_cli/marketplace/output_profiles.py`: `MARKETPLACE_OUTPUTS = {claude: ..., codex: ...}`, nothing else). There is no native Copilot marketplace output; `apm pack` will not generate one. A repo needing a Copilot-consumable marketplace manifest must maintain it separately by other means.
|
- Only `claude` and `codex` marketplace output profiles exist in apm 0.28.0 — confirmed via source (`apm_cli/marketplace/output_profiles.py`: `MARKETPLACE_OUTPUTS = {claude: ..., codex: ...}`, nothing else). There is no native Copilot marketplace output; `apm pack` will not generate one. A repo needing a Copilot-consumable marketplace manifest must maintain it separately by other means.
|
||||||
- A package/plugin `name` compiling to the `claude` target must avoid Claude Code's reserved name prefixes/values — `anthropic-*`, `claude-*`, `agent-skills`, `official-claude-plugins` — otherwise the compiled `.claude-plugin/marketplace.json` is rejected by Claude Code's validator. This is a Claude Code platform constraint, independent of how the manifest gets authored.
|
- A package/plugin `name` compiling to the `claude` target must avoid Claude Code's reserved name prefixes/values — `anthropic-*`, `claude-*`, `agent-skills`, `official-claude-plugins` — otherwise the compiled `.claude-plugin/marketplace.json` is rejected by Claude Code's validator. This is a Claude Code platform constraint, independent of how the manifest gets authored.
|
||||||
- Removing a package from `marketplace.packages[]` in `apm.yml` and re-packing changes the public/consumed catalog. Confirm with the user in conversation before removing the entry and running `apm pack` — this is a normal `apm.yml` edit (not a distinct apm-orchestrate operation with its own gate), so the confirmation is conversational, the same as any other consequential manifest edit.
|
- Removing a package from `marketplace.packages[]` in `apm.yml` and re-packing changes the public/consumed catalog. Confirm with the user in conversation before removing the entry and running `apm pack` — this is a normal `apm.yml` edit (not a distinct apm-orchestrate operation with its own gate), so the confirmation is conversational, the same as any other consequential manifest edit.
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ You resolve the package root once per dispatched operation (the directory contai
|
|||||||
|
|
||||||
These are non-negotiable regardless of `confirm` or any skill-local override:
|
These are non-negotiable regardless of `confirm` or any skill-local override:
|
||||||
- `apm publish` claims a version on a registry — treat it as irreversible. Refuse without explicit `confirm: true`; always dispatch with `--dry-run -v` first and surface that output to the caller before the real publish, even when `confirm: true` was given.
|
- `apm publish` claims a version on a registry — treat it as irreversible. Refuse without explicit `confirm: true`; always dispatch with `--dry-run -v` first and surface that output to the caller before the real publish, even when `confirm: true` was given.
|
||||||
- Never guess the marketplace-add direction from context — resolve strictly from the operation name (`add-package` vs `add-marketplace`); see apm-workflow/SKILL.md Gotchas for why the two are easy to conflate.
|
- Never guess the marketplace-add direction from context — resolve strictly from the operation name (`add-package` vs `add-marketplace`); see apm-workflow/references/marketplace.md Gotchas for why the two are easy to conflate.
|
||||||
- `apm.yml`'s `type:` field constrains what `.apm/` may contain — when scaffolding (`init-package`), set `type:` before any primitive content is added; do not defer it.
|
- `apm.yml`'s `type:` field constrains what `.apm/` may contain — when scaffolding (`init-package`), set `type:` before any primitive content is added; do not defer it.
|
||||||
- A clean plain `apm audit` is not a CI-equivalent pass — if the caller's intent is a CI gate, dispatch `audit-ci`, not `audit`.
|
- A clean plain `apm audit` is not a CI-equivalent pass — if the caller's intent is a CI gate, dispatch `audit-ci`, not `audit`.
|
||||||
- Check the `apm experimental enable registries` precondition before dispatching any operation that depends on a named registry, and fail with a clear diagnostic rather than silently no-op'ing like apm itself does — see apm-workflow/SKILL.md Gotchas for the underlying constraint.
|
- Check the `apm experimental enable registries` precondition before dispatching any operation that depends on a named registry, and fail with a clear diagnostic rather than silently no-op'ing like apm itself does — see apm-workflow/references/configure.md Gotchas for the underlying constraint (summarised in its SKILL.md Gotchas).
|
||||||
- You are read-only against the working tree. Never create, edit, or delete a file — not an `apm.yml`, not a `.apm/` primitive, not compiled output, not a scratch note. `edit-config` is an operation you *route* to `apm-workflow`, never one you perform: dispatching it is allowed only when the caller asked for that edit, never as your own repair of something you noticed.
|
- You are read-only against the working tree. Never create, edit, or delete a file — not an `apm.yml`, not a `.apm/` primitive, not compiled output, not a scratch note. `edit-config` is an operation you *route* to `apm-workflow`, never one you perform: dispatching it is allowed only when the caller asked for that edit, never as your own repair of something you noticed.
|
||||||
|
|
||||||
When invoked, you:
|
When invoked, you:
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ Requires the `apm` binary and (for runtime-driven scripts) an agent runtime alre
|
|||||||
|
|
||||||
| File | Purpose |
|
| File | Purpose |
|
||||||
|------|---------|
|
|------|---------|
|
||||||
| `SKILL.md` | Dispatch table and cross-cutting gotchas |
|
| `SKILL.md` | Dispatch table and the two gotchas common to every branch (MCP secret indirection, the `experimental enable registries` precondition) |
|
||||||
| `references/configure.md` | apm.yml schema, apm plugin init, dependency forms, MCP secrets, registries |
|
| `references/configure.md` | apm.yml schema, apm plugin init, dependency forms, MCP secrets, `includes:`, registries; `type:` and `experimental enable registries` traps |
|
||||||
| `references/install.md` | apm install, apm install [PACKAGE_REF], --update, --target agent-skills |
|
| `references/install.md` | apm install, apm install [PACKAGE_REF], --update, --target agent-skills |
|
||||||
| `references/marketplace.md` | Building/registering a marketplace, package registration, versioning, Claude Code reserved-name/publish-confirm gotchas |
|
| `references/marketplace.md` | Building/registering a marketplace, `marketplace add` vs `package add`, package registration, versioning, Claude Code reserved-name/publish-confirm gotchas |
|
||||||
| `references/compile.md` | apm compile / pack / publish / run, claude plugin validate agents/ gotcha |
|
| `references/compile.md` | apm compile / pack / publish / run, claude plugin validate agents/ gotcha |
|
||||||
| `references/audit.md` | apm audit, apm audit --ci, apm marketplace check, CI wiring, frozen installs, claude plugin validate terminal check |
|
| `references/audit.md` | apm audit vs apm audit --ci (they check different things), apm marketplace check, CI wiring, frozen installs, claude plugin validate terminal check |
|
||||||
| `references/sources.md` | Provenance chain — research sources that informed this skill |
|
| `references/sources.md` | Provenance chain — research sources that informed this skill |
|
||||||
|
|||||||
@@ -1,18 +1,11 @@
|
|||||||
---
|
---
|
||||||
name: apm-workflow
|
name: apm-workflow
|
||||||
description: >
|
description: >
|
||||||
Use when the user wants to author or edit an apm.yml manifest
|
Use when the user wants to author, scaffold, install, compile, publish, or
|
||||||
(dependencies, scripts, compilation, policy, registries), scaffold a new
|
audit an apm package, an apm.yml manifest, or an apm marketplace, or register
|
||||||
apm package or marketplace (apm plugin init, apm marketplace init/package
|
someone else's to consume — even when they do not say "apm"
|
||||||
add), install or resolve dependencies declared in apm.yml (apm install,
|
explicitly, e.g. "set up the package manifest". Not the apm binary itself or
|
||||||
apm install [PACKAGE_REF]), register a marketplace as a consumer,
|
an agent runtime -> `apm-install`.
|
||||||
compile/pack/publish an apm package for distribution, or validate/audit
|
|
||||||
apm.yml and installed content (apm audit, apm marketplace check) — even if
|
|
||||||
the user doesn't say "apm" explicitly, e.g. "set up the package manifest",
|
|
||||||
"scaffold this as an apm package", "install my apm dependencies", "resolve
|
|
||||||
apm.yml deps", "build the distributable", "check this passes CI". Do not
|
|
||||||
use for installing the apm binary itself or setting up an agent runtime —
|
|
||||||
use apm-install for those.
|
|
||||||
metadata:
|
metadata:
|
||||||
category: apm
|
category: apm
|
||||||
source_keys:
|
source_keys:
|
||||||
@@ -21,12 +14,8 @@ metadata:
|
|||||||
|
|
||||||
## Gotchas
|
## Gotchas
|
||||||
|
|
||||||
- `apm.yml`'s `type:` field (`instructions`, `skill`, `hybrid`, `prompts`) constrains what `.apm/` may contain — set it before scaffolding content, not after. Changing it later doesn't retroactively validate what's already on disk.
|
- MCP server secrets in `apm.yml` (headers, env vars) must use `${VAR}` indirection, never literal values, so they resolve at install or runtime and are never committed.
|
||||||
- `includes: auto` publishes the authoritative local layout as-is. Anything narrower needs an explicit repo-path list — don't assume `auto` means "scoped down to what's relevant." Note: `auto` still excludes generic root-level passthrough files (README.md, docs/, sources.md, config files) from the `apm pack` distribution bundle — see `references/compile.md`.
|
- `apm experimental enable registries` must run before a `registries:` block or `registry.*` config takes effect anywhere — configure, install or publish. Without it, declaring one silently does nothing: no error, no warning.
|
||||||
- `apm marketplace add` (registering a marketplace as a *consumer*, pointing at someone else's catalog) and `apm marketplace package add` (registering a package by remote reference — `owner/repo`, host URL, or full URL — into a marketplace you're building) are opposite directions of the same command family — don't conflate them. `package add` does NOT accept local paths; a local package is registered by hand-editing `apm.yml`'s `marketplace.packages[]` directly — see `references/marketplace.md`.
|
|
||||||
- MCP server secrets (headers, env vars) inside `apm.yml` must use `${VAR}` indirection, never literal values, so they're resolved at install/runtime and never committed to the manifest.
|
|
||||||
- `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.
|
|
||||||
- Plain `apm audit` and `apm audit --ci` check different things: plain `apm audit` scans deployed files for hidden Unicode only; `--ci` additionally runs lockfile-consistency checks, install-replay drift detection, and org policy checks. A clean plain `apm audit` is not a CI-equivalent pass.
|
|
||||||
|
|
||||||
## Step 1 — Dispatch
|
## Step 1 — Dispatch
|
||||||
|
|
||||||
@@ -38,7 +27,7 @@ metadata:
|
|||||||
| `/apm-workflow compile` | Generate per-target output, bundle, or publish (`apm compile`, `apm pack`, `apm publish`) | `references/compile.md` |
|
| `/apm-workflow compile` | Generate per-target output, bundle, or publish (`apm compile`, `apm pack`, `apm publish`) | `references/compile.md` |
|
||||||
| `/apm-workflow audit` | Validate integrity/policy or wire a CI gate (`apm audit`, `apm audit --ci`) | `references/audit.md` |
|
| `/apm-workflow audit` | Validate integrity/policy or wire a CI gate (`apm audit`, `apm audit --ci`) | `references/audit.md` |
|
||||||
|
|
||||||
Read only the reference file matching the requested action — each is self-contained for its concern.
|
Read only the reference file matching the requested action — each is self-contained for its concern, and each carries the traps specific to its flow.
|
||||||
|
|
||||||
## Step 2 — Execute
|
## Step 2 — Execute
|
||||||
|
|
||||||
|
|||||||
@@ -53,3 +53,7 @@ jobs:
|
|||||||
## Claude Code validation is a separate terminal check
|
## Claude Code validation is a separate terminal check
|
||||||
|
|
||||||
For packages compiling to the `claude` target, also run `claude plugin validate [--strict]` against the compiled output as a terminal check. `apm audit`/`apm audit --ci` do not check Claude Code-marketplace-specific schema rules (reserved prefixes, the `agents/` stray-file behavior — see `references/compile.md` — etc.), so they don't substitute for it.
|
For packages compiling to the `claude` target, also run `claude plugin validate [--strict]` against the compiled output as a terminal check. `apm audit`/`apm audit --ci` do not check Claude Code-marketplace-specific schema rules (reserved prefixes, the `agents/` stray-file behavior — see `references/compile.md` — etc.), so they don't substitute for it.
|
||||||
|
|
||||||
|
## Gotchas
|
||||||
|
|
||||||
|
- Plain `apm audit` and `apm audit --ci` check different things: plain `apm audit` scans deployed files for hidden Unicode only; `--ci` additionally runs lockfile-consistency checks, install-replay drift detection, and org policy checks. A clean plain `apm audit` is not a CI-equivalent pass.
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ Bundles a producer package into a distributable artifact. Default to `--dry-run
|
|||||||
|
|
||||||
`includes: auto` does NOT sweep generic root-level passthrough files (README.md, docs/, sources.md, config files, etc.) into the `apm pack` distribution bundle (`build/<name>-<version>`) — only `.apm/` primitives, the compiled `plugin.json`, and the content-aware `.mcp.json` handling above make it into that bundle. This does not affect Claude Code's own plugin loading, which reads a plugin's working directory directly via its `source:` path in `marketplace.json`, not the `apm pack` bundle — but it matters for anyone relying on the packed bundle for distribution via `apm install`.
|
`includes: auto` does NOT sweep generic root-level passthrough files (README.md, docs/, sources.md, config files, etc.) into the `apm pack` distribution bundle (`build/<name>-<version>`) — only `.apm/` primitives, the compiled `plugin.json`, and the content-aware `.mcp.json` handling above make it into that bundle. This does not affect Claude Code's own plugin loading, which reads a plugin's working directory directly via its `source:` path in `marketplace.json`, not the `apm pack` bundle — but it matters for anyone relying on the packed bundle for distribution via `apm install`.
|
||||||
|
|
||||||
Run `apm audit` after compile/pack, not before — audit scans deployed/compiled output, not the source `apm.yml` manifest; see `references/audit.md`.
|
Run `apm audit` after compile/pack, not before — audit scans deployed/compiled output, not the source `apm.yml` manifest. Plain `apm audit` is not the CI-equivalent pass (that is `apm audit --ci`, which checks strictly more); see `references/audit.md`.
|
||||||
|
|
||||||
## Publish
|
## Publish
|
||||||
|
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ version: 1.0.0
|
|||||||
|
|
||||||
- `name`, `version` — required (see above)
|
- `name`, `version` — required (see above)
|
||||||
- `description`, `author`, `license`, `homepage`, `repository`, `keywords` — standard package metadata
|
- `description`, `author`, `license`, `homepage`, `repository`, `keywords` — standard package metadata
|
||||||
- `type` — `instructions | skill | hybrid | prompts`; constrains `.apm/` contents
|
- `type` — `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 singular `target: copilot,claude` CSV form still accepted)
|
- `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, or list explicit repo paths. Note: `auto` 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`
|
- `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
|
- `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>`
|
- `scripts` — named commands runnable via `apm run <name>`
|
||||||
- `compilation` — target/strategy/exclude/placement controls for `apm compile`/`apm pack`
|
- `compilation` — target/strategy/exclude/placement controls for `apm compile`/`apm pack`
|
||||||
@@ -68,14 +68,14 @@ from a content diff.
|
|||||||
|
|
||||||
## MCP server secrets
|
## MCP server secrets
|
||||||
|
|
||||||
`${VAR}` indirection is required for MCP server secrets in `apm.yml` — see SKILL.md Gotchas.
|
`${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`)
|
## 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:
|
Any git repo is a valid package source by default — no registry required. To declare named registries for shorthand dependency resolution:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
apm experimental enable registries # required first — see SKILL.md Gotchas
|
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.url https://artifactory.corp.example.com/apm
|
||||||
apm config set registry.corp-main.token eyJ...
|
apm config set registry.corp-main.token eyJ...
|
||||||
apm config set registry.corp-main.default true
|
apm config set registry.corp-main.default true
|
||||||
@@ -85,4 +85,6 @@ apm config set registry.corp-main.default true
|
|||||||
|
|
||||||
## Gotchas
|
## Gotchas
|
||||||
|
|
||||||
|
- `apm.yml`'s `type:` 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 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.
|
- `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.
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ hook.
|
|||||||
|
|
||||||
## Gotchas
|
## Gotchas
|
||||||
|
|
||||||
|
- `apm marketplace add` and `apm marketplace package add` point in opposite directions and are easy to conflate: `add` registers someone else's catalog for you to *consume*; `package add` registers a package by remote reference (`owner/repo`, host URL, or full URL) into a marketplace you are *building*. `package add` does not accept a local path — register a local package by hand-editing `marketplace.packages[]`, as above.
|
||||||
- Only `claude` and `codex` marketplace output profiles exist in apm 0.28.0 — confirmed via source (`apm_cli/marketplace/output_profiles.py`: `MARKETPLACE_OUTPUTS = {claude: ..., codex: ...}`, nothing else). There is no native Copilot marketplace output; `apm pack` will not generate one. A repo needing a Copilot-consumable marketplace manifest must maintain it separately by other means.
|
- Only `claude` and `codex` marketplace output profiles exist in apm 0.28.0 — confirmed via source (`apm_cli/marketplace/output_profiles.py`: `MARKETPLACE_OUTPUTS = {claude: ..., codex: ...}`, nothing else). There is no native Copilot marketplace output; `apm pack` will not generate one. A repo needing a Copilot-consumable marketplace manifest must maintain it separately by other means.
|
||||||
- A package/plugin `name` compiling to the `claude` target must avoid Claude Code's reserved name prefixes/values — `anthropic-*`, `claude-*`, `agent-skills`, `official-claude-plugins` — otherwise the compiled `.claude-plugin/marketplace.json` is rejected by Claude Code's validator. This is a Claude Code platform constraint, independent of how the manifest gets authored.
|
- A package/plugin `name` compiling to the `claude` target must avoid Claude Code's reserved name prefixes/values — `anthropic-*`, `claude-*`, `agent-skills`, `official-claude-plugins` — otherwise the compiled `.claude-plugin/marketplace.json` is rejected by Claude Code's validator. This is a Claude Code platform constraint, independent of how the manifest gets authored.
|
||||||
- Removing a package from `marketplace.packages[]` in `apm.yml` and re-packing changes the public/consumed catalog. Confirm with the user in conversation before removing the entry and running `apm pack` — this is a normal `apm.yml` edit (not a distinct apm-orchestrate operation with its own gate), so the confirmation is conversational, the same as any other consequential manifest edit.
|
- Removing a package from `marketplace.packages[]` in `apm.yml` and re-packing changes the public/consumed catalog. Confirm with the user in conversation before removing the entry and running `apm pack` — this is a normal `apm.yml` edit (not a distinct apm-orchestrate operation with its own gate), so the confirmation is conversational, the same as any other consequential manifest edit.
|
||||||
|
|||||||
Reference in New Issue
Block a user