From 72adf16afc3f4bd77dea50afb831973fa2a2445e Mon Sep 17 00:00:00 2001 From: danielmeppiel Date: Thu, 23 Apr 2026 10:30:45 +0200 Subject: [PATCH] docs: rewrite first-package tutorial, fix anatomy hallucination The first-package tutorial was prompts-led with cat-heredoc snippets and mis-framed apm compile as a Codex/Gemini fallback. Rewrite it skills-first to match how APM is actually used: - Lead with a real skill (pr-description) using path-header code blocks - Pair it with a custom agent (team-reviewer.agent.md) - Show apm install deploying .apm/ -> .github/ side-by-side - Clarify apm install vs apm compile (different concerns, not nested) - Add apm pack --format plugin as a first-class step (with --plugin scaffold tip), shielding against plugin-skeptic readers - Link to real microsoft/apm and microsoft/apm-sample-package primitives instead of inventing ones Anatomy page: replace the hallucinated writing-skills/SKILL.md example with the real python-architecture/SKILL.md and doc-writer.agent.md, with GitHub permalinks readers can click. Soften the byte-identical claim -- deploy can augment per-runtime when targets need it. All commands, paths, and outputs verified end-to-end against the CLI. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../docs/getting-started/first-package.md | 291 ++++++++++++++---- .../introduction/anatomy-of-an-apm-package.md | 33 +- 2 files changed, 248 insertions(+), 76 deletions(-) diff --git a/docs/src/content/docs/getting-started/first-package.md b/docs/src/content/docs/getting-started/first-package.md index 2c81521c..c237f064 100644 --- a/docs/src/content/docs/getting-started/first-package.md +++ b/docs/src/content/docs/getting-started/first-package.md @@ -1,117 +1,280 @@ --- title: "Your First Package" -description: "Create, publish, and install your first APM package in minutes." +description: "Build a real APM package with a skill and an agent, install it, and ship it as a plugin." sidebar: order: 3 --- -This tutorial walks you through creating an APM package from scratch, publishing it, and installing it in another project. +In about ten minutes you will scaffold an APM package, add a skill that +auto-activates inside Copilot or Claude, add a custom agent that pairs with +it, install both into a project, and ship the result as a plugin. No prompts, +no `cat < **Note:** By default, `apm init` creates only `apm.yml`. The directory structure below is what you build manually in the following steps. See [Anatomy of an APM Package](../../introduction/anatomy-of-an-apm-package/) for what `.apm/` is and why files live there. +## 2. Add a skill -## 2. Add an Instruction +A **skill** is a chunk of expertise that the runtime activates automatically +based on its `description`. No slash command, no manual selection: the agent +sees the description, decides the skill is relevant, and pulls it in. That +auto-activation is what separates skills from prompts. -Create a coding standard that applies to all Python files: +Create one for drafting pull-request descriptions: -```bash -cat > .apm/instructions/python.instructions.md << 'EOF' +**`.apm/skills/pr-description/SKILL.md`** + +```markdown --- -applyTo: "**/*.py" +name: pr-description +description: >- + Activate when the user asks for a pull-request description, a summary of + uncommitted changes, or release notes. Use when preparing to open a PR or + when the user says "draft a PR description for me". --- -# Python Standards -- Use type hints for all function parameters and return values -- Follow PEP 8 style guidelines -- Write docstrings for all public functions -- Prefer `pathlib.Path` over `os.path` -EOF +# PR Description Skill + +Produce a PR description with these sections, in order: + +## Summary + +One sentence. What changes and why. No file lists, no implementation detail. + +## Motivation + +Two to four sentences. The problem this solves or the capability it adds. +Link to the issue or design doc if one exists. + +## Changes + +Bullet list grouped by area (e.g. "API", "Tests", "Docs"). One bullet per +logical change, not per file. + +## Risk and rollback + +Note any breaking changes, migrations required, or feature flags. +Mention how to revert if something breaks. + +## Testing + +How you verified the change. Commands run, environments tested. ``` -## 3. Add a Prompt +The frontmatter `description` is a contract with the runtime: write it as +"activate when ...". The body is the operating manual the agent reads when +the skill fires. -Create a reusable slash command: +> Want to inspect a real one? The skill that governs this CLI's own +> architecture decisions lives at +> [`.apm/skills/python-architecture/SKILL.md`](https://github.com/microsoft/apm/blob/main/.apm/skills/python-architecture/SKILL.md) +> in this repo. Same shape, different concern. -```bash -cat > .apm/prompts/security-audit.prompt.md << 'EOF' +See the [Skills guide](/apm/guides/skills/) for the full schema. + +## 3. Add a custom agent + +A **custom agent** (`.agent.md`) is a named expert your runtime can invoke +directly. While skills auto-activate based on context, agents are summoned +on demand -- typically with `@agent-name`. + +Pair the skill with a reviewer agent that critiques the diff before the PR +goes out: + +**`.apm/agents/team-reviewer.agent.md`** + +```markdown --- -description: Run a security audit on the current file +name: team-reviewer +description: Senior reviewer that critiques diffs against team standards before PR submission. --- -Review this code for common security issues: -1. Input validation and sanitization -2. Authentication and authorization checks -3. Sensitive data exposure -4. SQL injection and XSS vulnerabilities -Provide specific line numbers and suggested fixes. -EOF +# Team Reviewer + +You are a senior engineer reviewing a teammate's diff before it becomes +a pull request. Your job is to catch the things that waste reviewer +time downstream. + +## What to check, in order + +1. **Correctness.** Does the code do what its commit message claims? + Spot logic errors, off-by-ones, unhandled error paths. +2. **Tests.** Are the changed code paths covered? Are new public APIs + exercised by at least one test? Flag missing coverage explicitly. +3. **Naming and clarity.** Are names accurate? Would a new contributor + understand this in six months? +4. **Surface area.** Does this change export anything new? If yes, is + that intentional and documented? + +## Output format + +Group findings by severity: **Blocking**, **Should fix**, **Nit**. +For each finding, cite the file and line. End with a one-line verdict: +"Ready to ship", "Address blockers then ship", or "Needs another pass". + +Do not rewrite the code yourself. Point and explain. ``` -## 4. Update the Manifest +> A real example: this repo's documentation agent lives at +> [`.apm/agents/doc-writer.agent.md`](https://github.com/microsoft/apm/blob/main/.apm/agents/doc-writer.agent.md). -Edit `apm.yml` to describe your package: +See the [Agent Workflows guide](/apm/guides/agent-workflows/) for more. -```yaml -name: my-coding-standards -version: 1.0.0 -description: Team coding standards and security prompts +## 4. Deploy and use + +Run install with no arguments. APM treats your repo as the package and +deploys its `.apm/` content into the runtime directories your tools read: + +```bash +apm install ``` -## 5. Publish +Output: + +``` +[+] (local) +|-- 1 agent integrated -> .github/agents/ +|-- 1 skill(s) integrated -> .github/skills/ +[i] Added apm_modules/ to .gitignore +``` + +Your tree now has source on the left and runtime-ready output on the right: + +``` +team-skills/ ++-- .apm/ # source you edit +| +-- skills/ +| | +-- pr-description/SKILL.md +| +-- agents/ +| +-- team-reviewer.agent.md ++-- .github/ # generated by apm install +| +-- skills/ +| | +-- pr-description/SKILL.md +| +-- agents/ +| +-- team-reviewer.agent.md ++-- apm.yml ++-- apm.lock.yaml +``` -Push to a git repository: +`apm install` auto-detects which runtimes you have. The example above shows +`.github/` because Copilot is the default fallback. If `.claude/`, `.cursor/`, +or `.opencode/` exists in the project, they get populated too. To target +explicitly, see the [Compilation guide](/apm/guides/compilation/). + +> **What about `apm compile`?** Compile is a different concern: it +> generates merged `AGENTS.md` / `CLAUDE.md` files for tools that read a +> single top-level context document (Codex, Gemini, plain `agents`-protocol +> hosts). Copilot, Claude Code, and Cursor read the per-skill directories +> directly -- no compile step needed. + +Now open Copilot or Claude in this project. Ask "draft a PR description for +my last commit". The `pr-description` skill activates on its own. To get the +review pass, type `@team-reviewer review my staged changes`. + +## 5. Publish as a package + +Push to GitHub: ```bash git init -git add . -git commit -m "Initial APM package" -git remote add origin https://github.com/you/my-coding-standards.git +git add apm.yml .apm/ +git commit -m "Initial team-skills package" +git remote add origin https://github.com/your-handle/team-skills.git git push -u origin main ``` -## 6. Install in Another Project +In any other project's `apm.yml`: -In any project: - -```bash -apm install you/my-coding-standards +```yaml +dependencies: + apm: + - your-handle/team-skills ``` -APM automatically: -- Downloads the package to `apm_modules/` -- Copies instructions to `.github/instructions/` -- Copies prompts to `.github/prompts/` -- Updates `apm.yml` with the dependency +Then `apm install` -- consumers get the same skill and agent in their +runtime dirs, with version pinning recorded in `apm.lock.yaml`. -## 7. Optional: Compile for Other Tools +For a real published package to read, see +[`microsoft/apm-sample-package`](https://github.com/microsoft/apm-sample-package) +(install with `apm install microsoft/apm-sample-package#v1.0.0`). -If you use tools beyond GitHub Copilot, Claude, Cursor, and OpenCode (which read deployed primitives natively), generate compiled instruction files: +## 6. Ship as a plugin (optional) + +The same package can ship as a standalone plugin -- no APM required for +consumers. This lets you target plugin-aware hosts (Copilot CLI plugins, +the broader plugin ecosystem) with the primitives you already authored. ```bash -apm compile +apm pack --format plugin +``` + +Output: + ``` +build/team-skills-1.0.0/ ++-- plugin.json # synthesized from apm.yml ++-- agents/ +| +-- team-reviewer.agent.md ++-- skills/ + +-- pr-description/SKILL.md +``` + +No `apm.yml`, no `apm_modules/`, no `.apm/`. Just primitives in +plugin-native layout. + +If you know up front that you want to ship a plugin, you can scaffold with +`apm init --plugin team-skills`, which adds `plugin.json` next to `apm.yml` +from day one. APM still gives you dependency management, the lockfile, and +audit while you author; pack produces the plugin bundle when you ship. -This produces `AGENTS.md` (for Codex, Gemini) and `CLAUDE.md` for tools that need a single instructions file. Copilot, Claude, and Cursor users can skip this step — OpenCode users need `apm compile` only if their packages include instructions (OpenCode reads `AGENTS.md` for those). +For the full reference, see the [Pack & Distribute guide](/apm/guides/pack-distribute/) +and the [Plugin authoring guide](/apm/guides/plugins/). -## Next Steps +## Next steps -- Add [skills](/apm/guides/skills/) to your package -- Set up [dependencies](/apm/guides/dependencies/) on other packages -- Distribute as a standalone plugin — see [Plugin authoring](../../guides/plugins/#plugin-authoring) and [Pack & Distribute](../../guides/pack-distribute/) -- Explore the [CLI reference](/apm/reference/cli-commands/) for more commands +- [Anatomy of an APM Package](/apm/introduction/anatomy-of-an-apm-package/) + -- the full mental model: `.apm/` vs `apm_modules/` vs `.github/`. +- [Skills guide](/apm/guides/skills/) -- bundled resources, sub-skills, + activation tuning. +- [Agent Workflows guide](/apm/guides/agent-workflows/) -- chaining agents, + GitHub Agentic Workflows integration. +- [Dependencies guide](/apm/guides/dependencies/) -- depend on other APM + packages, file-level imports, version pinning. +- [`apm audit`](/apm/reference/cli-commands/) -- scan dependencies for + policy violations before they ship. 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 cfa5bd8c..c25876a7 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 @@ -41,33 +41,42 @@ APM separates two concerns that those folders conflate: ### A concrete example: this repo The `microsoft/apm` repository (the one shipping the CLI you are reading docs -for) dogfoods this layout. It contains both source and compiled output side by -side: +for) dogfoods this layout. It contains both source and compiled output side +by side: ``` microsoft/apm/ +-- apm.yml +-- .apm/ | +-- skills/ -| | +-- writing-skills/ +| | +-- python-architecture/ | | +-- SKILL.md -| +-- instructions/ | +-- agents/ +| | +-- doc-writer.agent.md +| +-- instructions/ +-- .github/ | +-- skills/ -| | +-- writing-skills/ -| | +-- SKILL.md (compiled from .apm/, byte-identical) -| +-- instructions/ +| | +-- python-architecture/ +| | +-- SKILL.md (deployed from .apm/ by apm install) | +-- agents/ +| | +-- doc-writer.agent.md +| +-- instructions/ +-- src/ +-- tests/ ``` -The file under `.apm/skills/writing-skills/SKILL.md` is the source. The file -under `.github/skills/writing-skills/SKILL.md` is the compiled artifact that -the in-repo Copilot agent actually loads while we work on the CLI. Same -content today, but only one of them is authoritative -- and only one of them -gets shipped when this repo is consumed as an APM package. +The source files under `.apm/` are authoritative. You can inspect them on +GitHub: +[`.apm/skills/python-architecture/SKILL.md`](https://github.com/microsoft/apm/blob/main/.apm/skills/python-architecture/SKILL.md) +and +[`.apm/agents/doc-writer.agent.md`](https://github.com/microsoft/apm/blob/main/.apm/agents/doc-writer.agent.md). +Their counterparts under `.github/` are the deployed copies the in-repo +Copilot agent actually loads while we work on the CLI. + +For simple primitives the deployed file is byte-identical to the source. +The deploy step can also augment files for runtime-specific concerns (e.g. +adding diagnostic guidance for a particular target), so treat `.github/` +as build output: never edit it by hand, always re-deploy from `.apm/`. ## Why not just put primitives in `.github/` directly?