feat(kyberforge): add apm-install/apm-workflow/apm-orchestrate, ADR-0015 #91
31
plugins/kyberforge/skills/apm-workflow/README.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# apm-workflow
|
||||
|
||||
Authors, scaffolds, compiles, and audits apm packages and marketplaces.
|
||||
|
||||
## What it does
|
||||
|
||||
Covers the apm.yml lifecycle a session moves through repeatedly: configuring/scaffolding a package manifest, building or registering a marketplace, compiling/packing/publishing a distributable, and validating integrity via apm audit. Dispatches by requested action to one of four reference files, each self-contained for its concern.
|
||||
|
||||
## Before you start
|
||||
|
||||
Requires the `apm` binary and (for runtime-driven scripts) an agent runtime already installed — use `apm-install` first if either is missing.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
/apm-workflow configure
|
||||
/apm-workflow marketplace
|
||||
/apm-workflow compile
|
||||
/apm-workflow audit
|
||||
```
|
||||
|
||||
## Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `SKILL.md` | Dispatch table and cross-cutting gotchas |
|
||||
| `references/configure.md` | apm.yml schema, apm plugin init, dependency forms, MCP secrets, registries |
|
||||
| `references/marketplace.md` | Building/registering a marketplace, package registration, versioning |
|
||||
| `references/compile.md` | apm compile / pack / publish / run |
|
||||
| `references/audit.md` | apm audit, apm audit --ci, apm marketplace check, CI wiring, frozen installs |
|
||||
| `references/sources.md` | Provenance chain — research sources that informed this skill |
|
||||
43
plugins/kyberforge/skills/apm-workflow/SKILL.md
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
name: apm-workflow
|
||||
description: >
|
||||
Use when the user wants to author or edit an apm.yml manifest
|
||||
(dependencies, scripts, compilation, policy, registries), scaffold a new
|
||||
apm package or marketplace (apm plugin init, apm marketplace init/package
|
||||
add), register a marketplace as a consumer, 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", "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:
|
||||
category: apm
|
||||
source_keys:
|
||||
- context7-microsoft-apm
|
||||
---
|
||||
|
||||
## 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.
|
||||
- `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."
|
||||
- `apm marketplace add` (registering a marketplace as a *consumer*, pointing at someone else's catalog) and `apm marketplace package add` (registering a local package *into* a marketplace you're building) are opposite directions of the same command family — don't conflate them.
|
||||
- `apm pack` is the same command that both bundles a distributable artifact *and* emits `.claude-plugin/marketplace.json` as one of its compile targets — regenerating the Claude Code-native manifest isn't a separate step from packing.
|
||||
- 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
|
||||
|
Defame1297 marked this conversation as resolved
|
||||
|
||||
| Invocation | Action | Reference |
|
||||
|---|---|---|
|
||||
| `/apm-workflow configure` | Author/edit `apm.yml`; scaffold a new package (`apm plugin init`) | `references/configure.md` |
|
||||
| `/apm-workflow marketplace` | Build a marketplace, register packages into it, or register a marketplace as a consumer (`apm marketplace init/check/package add/add`) | `references/marketplace.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, wire a CI gate, or check marketplace refs resolve (`apm audit`, `apm audit --ci`, `apm marketplace check`) | `references/audit.md` |
|
||||
|
||||
Read only the reference file matching the requested action — each is self-contained for its concern.
|
||||
|
||||
## Step 2 — Execute
|
||||
|
||||
Follow the matched reference file's instructions. Report back which `apm` command(s) were run (or drafted, if the user asked for a plan rather than execution) and their outcome.
|
||||
49
plugins/kyberforge/skills/apm-workflow/references/audit.md
Normal file
@@ -0,0 +1,49 @@
|
||||
---
|
||||
topic: audit
|
||||
source_keys:
|
||||
- context7-microsoft-apm
|
||||
---
|
||||
|
||||
## `apm audit`
|
||||
|
||||
```bash
|
||||
apm audit # local: scan deployed files for hidden Unicode
|
||||
apm audit --ci # CI gate: lockfile consistency + drift replay + policy
|
||||
apm audit --file <path> # standalone: scan an arbitrary file
|
||||
```
|
||||
|
||||
`apm audit --ci` runs baseline lockfile checks, install-replay drift detection (does a clean `apm install` reproduce what's on disk), and org policy checks. Exit code `0` on success, `1` on any violation — composes as a normal CI gate step. It covers AI agent configuration integrity, hidden-content scanning, lockfile verification, and policy enforcement — it does not replace general lint/test/security-scan CI steps, it sits alongside them.
|
||||
|
||||
## Policy checks
|
||||
|
||||
`apm audit --ci` auto-discovers an org policy from the git remote if `--policy`/`--policy-source` isn't given explicitly; `--no-policy` skips policy discovery for a single invocation.
|
||||
|
||||
## Marketplace ref validation
|
||||
|
||||
Separate from `apm audit`: `apm marketplace check` validates that every package reference declared in a marketplace's `apm.yml` actually resolves (correct path/ref, manifest present) — run before `apm pack`/publish, to catch a typo'd local path or stale pinned tag before it ships.
|
||||
|
||||
## CI integration example (GitHub Actions)
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
apm-audit:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with: { python-version: "3.12" }
|
||||
- run: pip install apm-cli==X.Y.Z # pin to the version standardized on
|
||||
- run: apm install
|
||||
- run: apm audit --ci -f sarif --output apm-audit.sarif
|
||||
- uses: github/codeql-action/upload-sarif@v3
|
||||
with: { sarif_file: apm-audit.sarif }
|
||||
```
|
||||
|
||||
`-f sarif --output <file>` emits SARIF for GitHub Code Scanning's inline PR annotations.
|
||||
|
||||
## Frozen installs
|
||||
|
||||
`apm install --frozen` fails instead of silently re-resolving if the lockfile is out of date — the CI equivalent of `npm ci` vs `npm install`. Use in any CI job that must not be allowed to drift the lockfile.
|
||||
42
plugins/kyberforge/skills/apm-workflow/references/compile.md
Normal file
@@ -0,0 +1,42 @@
|
||||
---
|
||||
topic: compile
|
||||
source_keys:
|
||||
- context7-microsoft-apm
|
||||
---
|
||||
|
||||
## Compile
|
||||
|
||||
```bash
|
||||
apm compile
|
||||
```
|
||||
|
||||
Generates per-target output (Claude, Copilot, etc.) from the vendor-neutral `.apm/` primitive source tree, per the `compilation:` block in `apm.yml`. Run this after any change to `.apm/` content or to `compilation:`/`targets:` in `apm.yml`.
|
||||
|
||||
## Pack
|
||||
|
||||
```bash
|
||||
apm pack --dry-run # resolve and print; do not write
|
||||
|
Defame1297 marked this conversation as resolved
Defame1297
commented
Should this not be part of the audit before we compile? or do we compile first and then audit? Should this not be part of the audit before we compile? or do we compile first and then audit?
|
||||
apm pack --offline # cached refs only
|
||||
apm pack --include-prerelease # allow pre-release tags
|
||||
apm pack -v # per-entry resolution detail
|
||||
apm pack --marketplace=claude --json # JSON output for CI pipelines
|
||||
```
|
||||
|
||||
Bundles a producer package into a distributable artifact. Default to `--dry-run -v` first when packing something for the first time or after a dependency change — resolution errors surface before anything is written.
|
||||
|
||||
## Publish
|
||||
|
||||
```bash
|
||||
apm publish --package acme/my-skill --dry-run -v
|
||||
apm publish --package acme/my-skill
|
||||
```
|
||||
|
||||
Publishes a producer package (root containing `apm.yml`, `.apm/`, and optionally a `registries:` block) to a registry. Always dry-run with `-v` first — publishing is not trivially reversible once a version tag is claimed on a registry.
|
||||
|
||||
## Run
|
||||
|
||||
```bash
|
||||
apm run <script> [--param key=value]
|
||||
```
|
||||
|
||||
Executes a named script defined under `scripts:` in `apm.yml`, with `--param` substituting values into the script's parameters.
|
||||
127
plugins/kyberforge/skills/apm-workflow/references/configure.md
Normal file
@@ -0,0 +1,127 @@
|
||||
---
|
||||
|
Defame1297 marked this conversation as resolved
Claude
commented
This and the other three apm-workflow reference files (compile.md, audit.md, marketplace.md) restate their sibling research docs under docs/research/docs/microsoft-apm/ nearly verbatim (same command lists, same caveats, same CI YAML block in audit.md) — two sources of truth for the same facts. An upstream apm flag/behavior change applied to the research doc (the stated source of truth) can be missed here, leaving the actionable skill guidance silently stale while looking equally authoritative. Consider having these reference files point at the research docs rather than duplicating their content. This and the other three apm-workflow reference files (compile.md, audit.md, marketplace.md) restate their sibling research docs under docs/research/docs/microsoft-apm/ nearly verbatim (same command lists, same caveats, same CI YAML block in audit.md) — two sources of truth for the same facts. An upstream apm flag/behavior change applied to the research doc (the stated source of truth) can be missed here, leaving the actionable skill guidance silently stale while looking equally authoritative. Consider having these reference files point at the research docs rather than duplicating their content.
Defame1297
commented
This is/should be done through the sources.md. Not sure this finding is correct This is/should be done through the sources.md. Not sure this finding is correct
|
||||
topic: configure
|
||||
source_keys:
|
||||
- context7-microsoft-apm
|
||||
---
|
||||
|
||||
## Scaffolding a new package
|
||||
|
||||
```bash
|
||||
apm plugin init <name> --yes
|
||||
```
|
||||
|
||||
Scaffolds `apm.yml` + a `.apm/` skeleton in the current directory. 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:
|
||||
|
||||
```yaml
|
||||
name: my-pkg
|
||||
version: 1.0.0
|
||||
```
|
||||
|
||||
## `apm.yml` — full schema
|
||||
|
||||
```yaml
|
||||
name: my-pkg
|
||||
version: 1.0.0
|
||||
description: Code review skills for Python services
|
||||
author: Jane Doe # plain string, or {name, email?, url?} object
|
||||
license: MIT
|
||||
homepage: https://example.com/my-pkg
|
||||
repository: https://github.com/org/my-pkg
|
||||
keywords: [ai, review, python]
|
||||
|
||||
type: skill # instructions | skill | hybrid | prompts — constrains .apm/ contents
|
||||
|
Defame1297 marked this conversation as resolved
Outdated
Claude
commented
This apm.yml schema block omits the "legacy singular Failure scenario: An agent following only this file — the one its own SKILL.md dispatch table points to — encounters an existing apm.yml using This apm.yml schema block omits the "legacy singular `target:` CSV form is still accepted" caveat that the sibling research doc (`docs/research/docs/microsoft-apm/configuration.md:32`) documents for the same `targets:` field.
**Failure scenario:** An agent following only this file — the one its own SKILL.md dispatch table points to — encounters an existing apm.yml using `target: copilot,claude` and flags or "corrects" it as invalid, when apm actually still accepts that legacy form.
|
||||
|
||||
targets: # which harnesses this package compiles to; prefer plural list form
|
||||
- copilot
|
||||
- claude
|
||||
|
||||
includes: auto # "auto" = publish the authoritative local layout; or list explicit repo paths
|
||||
|
||||
dependencies:
|
||||
apm:
|
||||
- microsoft/apm-sample-package#v1.0.0 # pinned to a tag
|
||||
- github/awesome-copilot/skills/review-and-refactor # single primitive
|
||||
mcp:
|
||||
- microsoft/azure-devops-mcp # MCP server dependency
|
||||
lsp:
|
||||
- name: pyright
|
||||
command: pyright-langserver
|
||||
args: ["--stdio"]
|
||||
extensionToLanguage:
|
||||
".py": python
|
||||
|
||||
devDependencies: # same shape as dependencies, excluded from the shipped artifact
|
||||
apm:
|
||||
- my-org/internal-test-skills
|
||||
|
||||
scripts: # named commands runnable via `apm run <name>`
|
||||
start: "copilot -p 'README.prompt.md'"
|
||||
review: "copilot -p 'code-review.prompt.md'"
|
||||
|
||||
compilation:
|
||||
target: all
|
||||
strategy: distributed
|
||||
exclude:
|
||||
- "apm_modules/**"
|
||||
placement:
|
||||
min_instructions_per_file: 1
|
||||
|
||||
policy:
|
||||
fetch_failure_default: warn
|
||||
|
||||
registries:
|
||||
public-apm:
|
||||
url: https://registry.example.com/api/public-apm
|
||||
default: public-apm
|
||||
|
||||
marketplace: # see references/marketplace.md for the full marketplace workflow
|
||||
owner:
|
||||
name: contoso
|
||||
url: https://github.com/contoso
|
||||
packages:
|
||||
- name: code-review
|
||||
source: contoso/code-review
|
||||
version: "^1.0.0"
|
||||
tags: [review, quality]
|
||||
```
|
||||
|
||||
## 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
|
||||
|
||||
Use `${VAR}` indirection for headers/env vars — never a literal secret value in `apm.yml`:
|
||||
|
||||
```yaml
|
||||
mcp:
|
||||
- name: linear
|
||||
registry: false
|
||||
transport: http
|
||||
url: https://mcp.linear.app/sse
|
||||
headers:
|
||||
Authorization: "Bearer ${LINEAR_TOKEN}"
|
||||
- name: my-internal
|
||||
registry: false
|
||||
transport: stdio
|
||||
command: my-server
|
||||
env:
|
||||
API_TOKEN: "${MY_API_TOKEN}"
|
||||
```
|
||||
|
||||
## 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:
|
||||
|
||||
```bash
|
||||
apm experimental enable registries # required first — see SKILL.md 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.
|
||||
@@ -0,0 +1,61 @@
|
||||
---
|
||||
topic: marketplace
|
||||
source_keys:
|
||||
- context7-microsoft-apm
|
||||
---
|
||||
|
||||
## Building a marketplace from a producer repo
|
||||
|
||||
```bash
|
||||
apm marketplace init # 1. add the marketplace: block to apm.yml
|
||||
$EDITOR apm.yml # 2. describe each package
|
||||
apm marketplace check # 3. validate refs resolve
|
||||
apm pack # 4. build marketplace artifacts
|
||||
git add apm.yml .claude-plugin/marketplace.json
|
||||
|
Defame1297 marked this conversation as resolved
Claude
commented
Documents a raw Documents a raw `git add`/`git commit`/`git tag`/`git push --tags` chain as the literal release step. AGENTS.md's 'Prefer plugin skills over raw shell' section states commits/remotes are owned by `git:git-commits`/`git:git-remotes` and to fall back to raw shell 'only when no skill covers it' — an agent following this reference verbatim shells out directly in a repo that already has dedicated skills for exactly this operation.
|
||||
git commit -m "Release v1.0.0" && git tag v1.0.0 && git push --tags
|
||||
```
|
||||
|
||||
`apm pack` emits `.claude-plugin/marketplace.json` as one of its compile targets — an APM-based marketplace stays consumable by Claude Code's existing marketplace mechanism without a separately hand-maintained file.
|
||||
|
||||
## Registering a package into a marketplace you're building
|
||||
|
||||
```bash
|
||||
apm marketplace package add ./packages/plugin-a --name plugin-a
|
||||
```
|
||||
|
||||
Registers an already-existing local package path into the root marketplace listing without re-scaffolding it — this is the monorepo-hybrid command: point it at each existing `plugins/<name>/` directory once that directory has its own `apm.yml`.
|
||||
|
||||
## Registering a marketplace as a consumer
|
||||
|
||||
`apm marketplace add` accepts many source shapes:
|
||||
|
||||
```bash
|
||||
apm marketplace add my-org/awesome-agents # GitHub shorthand
|
||||
apm marketplace add gitlab.com/my-org/awesome-agents --host gitlab.com # GitLab
|
||||
apm marketplace add https://gitea.example.com/org/repo.git#v1.0.0 --name custom # self-hosted git, pinned
|
||||
apm marketplace add https://catalog.example.com/marketplace.json --name catalog # hosted marketplace.json
|
||||
apm marketplace add git@gitea.example.com:org/repo.git --name custom # SSH
|
||||
apm marketplace add /srv/marketplaces/agent-forge.git --name agent-forge # local bare repo/working dir
|
||||
apm marketplace add ./vendor/marketplace.json --name vendor # local marketplace.json file
|
||||
apm marketplace add file:///srv/marketplaces/agent-forge.git --name agent-forge # file:// form
|
||||
```
|
||||
|
||||
The local-filesystem and `file://` forms need no hosted registry or network access — the fit for an internal/homelab setup.
|
||||
|
||||
## Per-package versioning
|
||||
|
||||
```yaml
|
||||
marketplace:
|
||||
versioning: { strategy: per_package }
|
||||
packages:
|
||||
- { name: plugin-a, source: ./packages/plugin-a, version: 2.0.0 }
|
||||
- { name: plugin-b, source: ./packages/plugin-b, version: 0.1.0 }
|
||||
```
|
||||
|
||||
Without this block, the default versioning strategy ties every listed package to the marketplace/root version.
|
||||
|
||||
## Which mechanism to use
|
||||
|
||||
- **Local packages, no distribution needed yet** — local-path dependencies in `apm.yml` (`./packages/my-shared-skills`); no marketplace or registry involved.
|
||||
- **Internal catalog, still git-based, no server** — `apm marketplace add` against a local path, bare repo, `file://` URI, or a plain git host.
|
||||
- **Package-level hosting at scale / access control** — registries (Artifactory-style REST endpoint); more infrastructure, only worth it once package count or access-control needs outgrow git-based discovery.
|
||||
@@ -0,0 +1,9 @@
|
||||
# Sources
|
||||
|
||||
## context7-microsoft-apm
|
||||
|
||||
- **URL:** context7:/microsoft/apm
|
||||
- **Description:** Microsoft APM (Agent Package Manager) — open-source dependency manager for AI agent configuration (skills, prompts, instructions, agents, hooks, MCP/LSP deps), applying a declare/lock/install/audit workflow.
|
||||
- **Research doc:** plugins/kyberforge/docs/research/docs/microsoft-apm/sources.md
|
||||
- **Contributing files:** SKILL.md, references/configure.md, references/marketplace.md, references/compile.md, references/audit.md
|
||||
- **Status:** `extracted`
|
||||
Neither apm-workflow's dispatch table nor apm-orchestrate's operation list ever routes to plain
apm install [PACKAGE_REF]— the core command that actually resolves/downloads a dependency declared in apm.yml — and apm-install (the skill whose name most resembles it) is explicitly scoped only to installing the apm binary/runtime, not runningapm install.Failure scenario: A caller adds a dependency under
dependencies.apmin apm.yml per configure.md's guidance, then has no documented next step to actually fetch it (apm install) — an agent following only these two skills scaffolds a manifest that's never installed.