From c8d7817180224db7029be47d810ef15eba395798 Mon Sep 17 00:00:00 2001 From: Daniel Meppiel Date: Mon, 4 May 2026 12:05:36 +0200 Subject: [PATCH 1/5] docs: clarify APM's role for skills, unify plugins-as-packages, add ADO sub-path examples, state stability Customer feedback audit: - guides/skills.md: defer SKILL.md authoring to agentskills.io as the canonical source; APM owns distribution and governance, not the spec. Replace marketing copy with concrete responsibilities. Fix the apm init tree (only writes apm.yml; never scaffolds .apm/). Replace emoji checkmarks/x with ASCII bracket form per encoding rule. - guides/plugins.md: drop the misleading 'Three modes' framing. A plugin is a package, a package is a plugin. apm pack now emits plugin-compatible bundles by default. The only authoring choice is whether to keep an apm.yml. - guides/pack-distribute.md: add 'Without APM: what you give up' section. Frame as a value tradeoff (npx vs npm), not a doc gap. Cover the consumer install path for Claude Code and other hosts. - guides/dependencies.md, getting-started/authentication.md: add ADO sub-path + ref examples in shorthand and object form. Note the failing https://...repo/sub-path URL form (parser bug, tracked separately). - introduction/what-is-apm.md: explicit Stability section. State apm run / apm runtime as experimental, vendor-neutral (npx-for-npm analog), not currently prioritized. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../docs/getting-started/authentication.md | 3 ++ docs/src/content/docs/guides/dependencies.md | 14 +++++++ .../content/docs/guides/pack-distribute.md | 26 ++++++++++++ docs/src/content/docs/guides/plugins.md | 31 +++++--------- docs/src/content/docs/guides/skills.md | 41 ++++++++++--------- .../content/docs/introduction/what-is-apm.md | 16 ++++++++ 6 files changed, 91 insertions(+), 40 deletions(-) diff --git a/docs/src/content/docs/getting-started/authentication.md b/docs/src/content/docs/getting-started/authentication.md index eaad9ff64..cd7714815 100644 --- a/docs/src/content/docs/getting-started/authentication.md +++ b/docs/src/content/docs/getting-started/authentication.md @@ -147,6 +147,9 @@ ADO is always auth-required. Uses 3-segment paths (`org/project/repo`). No `ADO_ ```bash apm install dev.azure.com/myorg/myproject/myrepo#main apm install mycompany.visualstudio.com/org/project/repo # legacy URL + +# Sub-path inside an ADO repo, pinned to a tag (use the _git form for sub-paths): +apm install dev.azure.com/myorg/myproject/_git/myrepo/instructions/security#v2.0 ``` If your ADO project or repository name contains spaces, URL-encode them as `%20`: diff --git a/docs/src/content/docs/guides/dependencies.md b/docs/src/content/docs/guides/dependencies.md index 525634e27..87f25c45c 100644 --- a/docs/src/content/docs/guides/dependencies.md +++ b/docs/src/content/docs/guides/dependencies.md @@ -143,10 +143,24 @@ dependencies: alias: review # local alias (controls install directory name) - git: ssh://git@bitbucket.example.com:7999/project/repo.git # Bitbucket Datacenter (custom SSH port) ref: v1.0 + # Azure DevOps with sub-path and ref pin + - git: https://dev.azure.com/myorg/myproject/_git/myrepo + path: instructions/security + ref: v2.0 ``` Fields: `git` (required), `path`, `ref`, `alias` (all optional). The `git` value is any HTTPS, HTTP or SSH clone URL. +:::note[Azure DevOps + sub-path + ref] +The shorthand form for the same ADO entry is: + +```yaml +- dev.azure.com/myorg/myproject/_git/myrepo/instructions/security#v2.0 +``` + +Use the **shorthand** or the **object form** for ADO sub-paths. The full `https://dev.azure.com///_git//` URL form is not yet accepted by the parser ([tracking issue](https://github.com/microsoft/apm/issues)) - if you copy the URL straight from your ADO browser tab, switch to one of the two forms above. Spaces in project / repo names must be URL-encoded as `%20`. +::: + Explicit URL schemes are honored exactly -- see [Transport selection](#transport-selection-ssh-vs-https) for the full contract. Custom ports are preserved across every attempt (including any cross-protocol fallback enabled with `--allow-protocol-fallback`), so `ssh://host:7999/...` retried over HTTPS becomes `https://host:7999/...`. :::caution diff --git a/docs/src/content/docs/guides/pack-distribute.md b/docs/src/content/docs/guides/pack-distribute.md index 93a7d4d81..aad9a31cb 100644 --- a/docs/src/content/docs/guides/pack-distribute.md +++ b/docs/src/content/docs/guides/pack-distribute.md @@ -132,6 +132,32 @@ This is informational -- the files still extract. The warning helps users unders Pick `--format apm` when a downstream consumer expects the enriched lockfile and the install-shape directory tree -- in particular `microsoft/apm-action@v1` with `bundle:` (its restore mode reads the bundle's `apm.lock.yaml`). The action exposes `--format apm` end-to-end so existing pack/restore workflows continue unchanged. Otherwise leave the default in place. +## Without APM: what you give up + +A plugin bundle works two ways: with APM, or without it. Both are supported. Pick the one that matches the consumer. + +| Concern | With APM (`apm install`) | Without APM (host's native plugin loader) | +|---|---|---| +| Dependency declaration | `apm.yml` | None - copy the bundle directly | +| Version locking | `apm.lock.yaml` pins exact commits | None - whatever bytes you copied | +| Transitive dependencies | Resolved automatically | Not resolved - bundle whatever the author shipped | +| Governance hooks | `apm install` runs policy + security scans | Trust the source | +| Security scanning | Built-in: install / compile / unpack block critical findings; `apm audit` for reports | None at install time | +| Cross-runtime deploy | One install, all detected runtimes | One bundle per host, manually placed | +| Reproducibility | Same `apm.lock.yaml` -> identical bytes everywhere | Copy-and-pray | + +The parallel: `apm install ` is to `npx skills add ` what `npm install` is to `npx`. Both work. The first is reproducible and governed; the second is convenient. + +### Where the bundle goes without APM + +`apm pack` writes a directory shaped like a standard plugin. The consumer side depends on the host: + +- **Claude Code** loads plugins from `~/.claude/plugins//` (or via a Claude marketplace entry and `/plugin install`). Convention dirs (`agents/`, `skills/`, `commands/`, `instructions/`, `hooks/`) are picked up automatically. +- **Other Claude-plugin-compatible hosts** follow their own install steps. The bundle conforms to the [official Claude Code plugin manifest schema](https://json.schemastore.org/claude-code-plugin.json); consult your host's plugin documentation for the install path. +- **Archive output (`apm pack --archive`)** must be extracted first (`tar xzf -.tar.gz`), then copied into the host's plugin directory. + +If your consumer runs APM, none of this applies - declare the package in `apm.yml`, run `apm install`, and APM handles discovery, deployment, locking, and scanning. + ## Bundle structure (plugin format, default) `apm pack` writes to `./build/-/` by default. Convention directories (`agents/`, `skills/`, `commands/`, `instructions/`, `hooks/`) are auto-discovered by Claude Code, so the synthesized `plugin.json` does NOT emit `agents`/`skills`/`commands`/`instructions` keys for them. Per the [official schema](https://json.schemastore.org/claude-code-plugin.json), those array entries are reserved for `./*.md` paths to *additional* files outside the convention directories. diff --git a/docs/src/content/docs/guides/plugins.md b/docs/src/content/docs/guides/plugins.md index 31b1d878c..9e636f0a4 100644 --- a/docs/src/content/docs/guides/plugins.md +++ b/docs/src/content/docs/guides/plugins.md @@ -4,36 +4,27 @@ sidebar: order: 4 --- -APM supports plugins through the `plugin.json` format. Plugins are automatically detected and integrated into your project as standard APM dependencies. +APM treats plugins and packages as the same artifact. Every APM package is plugin-compatible by default: `apm pack` writes a `plugin.json` at the root of the bundle so any plugin host (Claude Code and other Claude-plugin-compatible runtimes) can load it natively. ## Plugin authoring -For where plugins fit relative to APM's source layout, see [Anatomy -- Why not just ship a `plugin.json`?](../../introduction/anatomy-of-an-apm-package/#why-not-just-ship-a-pluginjson). +The only authoring decision is whether you also keep an `apm.yml`: -Plugin ecosystems handle distribution but lack dependency management, security scanning, version locking, and dev/prod separation. As plugins depend on shared primitives, these gaps compound. +- **With `apm.yml` (recommended).** You get dependency management, lockfile pinning, [security scanning](../../enterprise/security/), [`devDependencies`](../../reference/manifest-schema/#5-devdependencies), and multi-runtime deploy during development. `apm pack` still emits a plugin-compatible bundle for non-APM consumers. This is what `apm init --plugin` produces. +- **From an existing `plugin.json`.** APM consumes it natively - `apm install owner/repo` works against any plugin repo without migration. Metadata is synthesized from `plugin.json`. Add an `apm.yml` later if you want APM tooling during development. -APM is the supply-chain layer. Author packages with full tooling — transitive dependencies, lockfile pinning, [security scanning](../../enterprise/security/), [`devDependencies`](../../reference/manifest-schema/#5-devdependencies) — then export as standard plugins. Consumers never need APM installed. +For why `apm.yml` adds value on top of `plugin.json`, see [Anatomy -- Why not just ship a `plugin.json`?](../../introduction/anatomy-of-an-apm-package/#why-not-just-ship-a-pluginjson). -### Three modes - -| Mode | Manifests | Use when | -|------|-----------|----------| -| **APM-only** | `apm.yml` | Full APM workflow — deploy to `.github/`, `.claude/`, `.cursor/`, `.opencode/` | -| **Plugin-only** | `plugin.json` | Standard plugin consumed by APM via `apm install` — metadata synthesized automatically | -| **Hybrid** | `apm.yml` + `plugin.json` | Author with dependency management + security, export as standalone plugins | - -**APM-only** is the default for teams using APM end-to-end. **Plugin-only** requires no changes to existing plugins — APM consumes them as-is. **Hybrid** is for plugin authors who want APM's supply-chain features during development while distributing standard plugins. - -### Hybrid authoring workflow +### Authoring workflow ```bash -apm init my-plugin --plugin # Creates both apm.yml and plugin.json -apm install --dev owner/helpers # Dev-only dependency (excluded from export) -apm install owner/core-rules # Production dependency -apm pack # Export -- plugin format is the default; dev deps excluded, security scanned +apm init my-plugin --plugin # apm.yml + plugin.json +apm install --dev owner/helpers # dev-only dependency (excluded from pack) +apm install owner/core-rules # production dependency +apm pack # plugin-compatible bundle by default ``` -The exported plugin directory contains no APM-specific files. See [Pack & Distribute -- Plugin format](../../guides/pack-distribute/#plugin-format-vs-apm-format) for the output mapping. +The packed directory contains no APM-specific files. See [Pack & Distribute -- Plugin format](../../guides/pack-distribute/#plugin-format-vs-apm-format) for the output mapping and [Without APM: what you give up](../../guides/pack-distribute/#without-apm-what-you-give-up) for the consumer-side trade-off. ## Overview diff --git a/docs/src/content/docs/guides/skills.md b/docs/src/content/docs/guides/skills.md index b27f848ec..a87ff6b8e 100644 --- a/docs/src/content/docs/guides/skills.md +++ b/docs/src/content/docs/guides/skills.md @@ -4,21 +4,23 @@ sidebar: order: 2 --- -Skills (`SKILL.md`) are package meta-guides that help AI agents quickly understand what an APM package does and how to leverage its content. They provide a concise summary optimized for AI consumption. +APM installs, locks, audits, and deploys skills across runtimes (GitHub Copilot, Claude Code, Cursor, OpenCode, Codex, Gemini). It is the package manager for skills, not the spec. -## What are Skills? +:::note[Authoring a SKILL.md?] +The `SKILL.md` format - frontmatter rules, body conventions, when to prefer a skill over an instruction or prompt - is defined by the agent-skills spec at . Treat that as the canonical source. This page covers what APM does *with* skills: distribution, version locking, governance, security scanning, and cross-runtime deployment. +::: -Skills describe an APM package in a format AI agents can quickly parse: -- **What** the package provides (name, description) -- **How** to use it (body content with guidelines) -- **Resources** available (bundled scripts, references, examples) +## What APM does with skills -### Skills Can Be Used Two Ways +- **Install** from any git host (`apm install owner/repo/skill-name`). +- **Lock** the resolved commit in `apm.lock.yaml` so every machine and CI job gets identical bytes. +- **Audit** for hidden-character and prompt-injection findings on every install / compile / unpack (zero config); use `apm audit` for SARIF / JSON / markdown reports. +- **Deploy** to the right convention directory for each detected runtime (`.claude/skills/`, `.agents/skills/`, `.cursor/`, ...) - see [Routing](#what-happens-during-install) below. -1. **Package meta-guides for your own package**: Add a `SKILL.md` to your APM package to help AI agents understand what your package does -2. **Installed from Claude skill repositories**: Install skills from monorepos like `ComposioHQ/awesome-claude-skills` to gain new capabilities +### Two ways to consume a skill -When you install a package with a SKILL.md, AI agents can quickly understand how to use it. +1. **As a dependency of your APM package** - declare it in `apm.yml`, `apm install` resolves and deploys it. +2. **Bundled inside your own package** - ship a `SKILL.md` (root, single-skill repo) or `.apm/skills//SKILL.md` (multi-skill layout); APM treats it like any other primitive. ## Installing Skills @@ -155,14 +157,13 @@ my-skill/ apm init my-skill && cd my-skill ``` -This creates: +This creates a single file: ``` my-skill/ -├── apm.yml # Package manifest -└── .apm/ # Primitives folder +└── apm.yml # Package manifest (the only file `apm init` writes) ``` -Add a `SKILL.md` at root to make it a publishable skill (see below). +`apm init` does not scaffold `.apm/` for you. Author the skill yourself: drop a `SKILL.md` at the root for a single-skill repo (Option 1 below), or create `.apm/skills//SKILL.md` for a multi-skill layout (Options 2-4 below). See [Anatomy of an APM Package](../../introduction/anatomy-of-an-apm-package/) for the full source layout. ### Option 1: Standalone Skill @@ -378,15 +379,15 @@ The migration is automatic and idempotent. Files not tracked in the lockfile are ### 1. Clear Naming Use descriptive, lowercase-hyphenated names: -- ✅ `brand-guidelines` -- ✅ `code-review-expert` -- ❌ `mySkill` -- ❌ `Skill_1` +- `[+]` `brand-guidelines` +- `[+]` `code-review-expert` +- `[x]` `mySkill` +- `[x]` `Skill_1` ### 2. Focused Description Keep the description to one line: -- ✅ `Applies corporate brand colors and typography` -- ❌ `This skill helps you with branding and it can also do typography and it uses the company colors...` +- `[+]` `Applies corporate brand colors and typography` +- `[x]` `This skill helps you with branding and it can also do typography and it uses the company colors...` ### 3. Structured Body Organize with clear sections: diff --git a/docs/src/content/docs/introduction/what-is-apm.md b/docs/src/content/docs/introduction/what-is-apm.md index 378219736..cee5a1491 100644 --- a/docs/src/content/docs/introduction/what-is-apm.md +++ b/docs/src/content/docs/introduction/what-is-apm.md @@ -250,6 +250,22 @@ change. **Multi-tool output.** Write your configuration once. APM compiles it for every supported AI tool. +## Stability + +These surfaces are stable and recommended for production use: + +- `apm install`, `apm.lock.yaml`, `apm audit` - dependency resolution, version locking, security scanning. +- `apm compile`, `apm pack`, `apm unpack` - multi-tool output, bundle distribution, plugin export. +- Authoring layout (`apm.yml`, `.apm/`) and consumption from GitHub, Azure DevOps, GitLab, Bitbucket, and self-hosted Git hosts. +- Cross-tool deployment to GitHub Copilot, Claude Code, Cursor, OpenCode, Codex, and Gemini. + +These surfaces are **experimental** and may change between releases: + +- `apm run` and `apm runtime setup` - local execution of agent workflows. Vendor-neutral by design and modeled on what `npx` is to `npm`. Not a current priority for the project; treat as a preview. +- Microsoft 365 Copilot Cowork target. See [Copilot Cowork](../../integrations/copilot-cowork/). + +The dependency-management core does not depend on the experimental runtime surface. If `apm run` is not in your workflow, the stable surface above stands on its own. + ## What's next - [Installation](../../getting-started/installation/) — get APM running in under a minute From fe8f5541f6916e11995d3e198360ec16cbcfa83e Mon Sep 17 00:00:00 2001 From: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com> Date: Mon, 4 May 2026 12:09:29 +0200 Subject: [PATCH 2/5] docs: fix stale #hybrid-authoring-workflow anchors Section was renamed to 'Authoring workflow' in this PR; update the self-link in plugins.md and the cross-link from anatomy-of-an-apm-package.md to the new slug. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/src/content/docs/guides/plugins.md | 2 +- docs/src/content/docs/introduction/anatomy-of-an-apm-package.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/content/docs/guides/plugins.md b/docs/src/content/docs/guides/plugins.md index 9e636f0a4..c58b98499 100644 --- a/docs/src/content/docs/guides/plugins.md +++ b/docs/src/content/docs/guides/plugins.md @@ -353,7 +353,7 @@ This: ## Exporting APM packages as plugins -Use the [hybrid authoring workflow](#hybrid-authoring-workflow) to develop plugins with APM's full tooling and export them as standalone plugin directories. See [Pack & Distribute -- Plugin format](../../guides/pack-distribute/#plugin-format-vs-apm-format) for the output mapping and structure. +Use the [authoring workflow](#authoring-workflow) to develop plugins with APM's full tooling and export them as standalone plugin directories. See [Pack & Distribute -- Plugin format](../../guides/pack-distribute/#plugin-format-vs-apm-format) for the output mapping and structure. ## Finding Plugins diff --git a/docs/src/content/docs/introduction/anatomy-of-an-apm-package.md b/docs/src/content/docs/introduction/anatomy-of-an-apm-package.md index 38ca01f69..b6497e1d6 100644 --- a/docs/src/content/docs/introduction/anatomy-of-an-apm-package.md +++ b/docs/src/content/docs/introduction/anatomy-of-an-apm-package.md @@ -302,7 +302,7 @@ install as first-class dependencies) and exports to plugin format you dependency management, lockfiles, and security scanning during authoring; `plugin.json` is the runtime distribution format. Use both -- see [Why not just ship a `plugin.json`?](#why-not-just-ship-a-pluginjson) -above and the [hybrid authoring workflow](../../guides/plugins/#hybrid-authoring-workflow). +above and the [authoring workflow](../../guides/plugins/#authoring-workflow). ## See also From 358d58a29cc2f99174e5b2c7b72fbadeec16e81d Mon Sep 17 00:00:00 2001 From: Daniel Meppiel <51440732+danielmeppiel@users.noreply.github.com> Date: Mon, 4 May 2026 12:17:10 +0200 Subject: [PATCH 3/5] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/src/content/docs/guides/dependencies.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/docs/guides/dependencies.md b/docs/src/content/docs/guides/dependencies.md index 87f25c45c..cb6a1109b 100644 --- a/docs/src/content/docs/guides/dependencies.md +++ b/docs/src/content/docs/guides/dependencies.md @@ -158,7 +158,7 @@ The shorthand form for the same ADO entry is: - dev.azure.com/myorg/myproject/_git/myrepo/instructions/security#v2.0 ``` -Use the **shorthand** or the **object form** for ADO sub-paths. The full `https://dev.azure.com///_git//` URL form is not yet accepted by the parser ([tracking issue](https://github.com/microsoft/apm/issues)) - if you copy the URL straight from your ADO browser tab, switch to one of the two forms above. Spaces in project / repo names must be URL-encoded as `%20`. +Use the **shorthand** or the **object form** for ADO sub-paths. The full `https://dev.azure.com///_git//` URL form is not yet accepted by the parser. If you copy the URL straight from your ADO browser tab, switch to one of the two forms above. Spaces in project / repo names must be URL-encoded as `%20`. ::: Explicit URL schemes are honored exactly -- see [Transport selection](#transport-selection-ssh-vs-https) for the full contract. Custom ports are preserved across every attempt (including any cross-protocol fallback enabled with `--allow-protocol-fallback`), so `ssh://host:7999/...` retried over HTTPS becomes `https://host:7999/...`. From c072ac16f0323cdc60e265b6c40030a7692850e7 Mon Sep 17 00:00:00 2001 From: Daniel Meppiel <51440732+danielmeppiel@users.noreply.github.com> Date: Mon, 4 May 2026 12:17:37 +0200 Subject: [PATCH 4/5] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/src/content/docs/guides/skills.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/docs/guides/skills.md b/docs/src/content/docs/guides/skills.md index a87ff6b8e..dc1ad037d 100644 --- a/docs/src/content/docs/guides/skills.md +++ b/docs/src/content/docs/guides/skills.md @@ -14,7 +14,7 @@ The `SKILL.md` format - frontmatter rules, body conventions, when to prefer a sk - **Install** from any git host (`apm install owner/repo/skill-name`). - **Lock** the resolved commit in `apm.lock.yaml` so every machine and CI job gets identical bytes. -- **Audit** for hidden-character and prompt-injection findings on every install / compile / unpack (zero config); use `apm audit` for SARIF / JSON / markdown reports. +- **Audit** for hidden Unicode character findings on every install / compile / unpack (zero config); use `apm audit` for SARIF / JSON / markdown reports. - **Deploy** to the right convention directory for each detected runtime (`.claude/skills/`, `.agents/skills/`, `.cursor/`, ...) - see [Routing](#what-happens-during-install) below. ### Two ways to consume a skill From 4d8d5dbe6afb9e7d3233f9ac71b0def84bf07814 Mon Sep 17 00:00:00 2001 From: Daniel Meppiel <51440732+danielmeppiel@users.noreply.github.com> Date: Mon, 4 May 2026 12:17:52 +0200 Subject: [PATCH 5/5] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/src/content/docs/introduction/what-is-apm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/content/docs/introduction/what-is-apm.md b/docs/src/content/docs/introduction/what-is-apm.md index cee5a1491..5fe26c25d 100644 --- a/docs/src/content/docs/introduction/what-is-apm.md +++ b/docs/src/content/docs/introduction/what-is-apm.md @@ -255,7 +255,7 @@ every supported AI tool. These surfaces are stable and recommended for production use: - `apm install`, `apm.lock.yaml`, `apm audit` - dependency resolution, version locking, security scanning. -- `apm compile`, `apm pack`, `apm unpack` - multi-tool output, bundle distribution, plugin export. +- `apm compile`, `apm pack`, `apm install ` - multi-tool output, bundle distribution, and supported local-bundle installation. - Authoring layout (`apm.yml`, `.apm/`) and consumption from GitHub, Azure DevOps, GitLab, Bitbucket, and self-hosted Git hosts. - Cross-tool deployment to GitHub Copilot, Claude Code, Cursor, OpenCode, Codex, and Gemini.