Skip to content

feat(cli): introduce apm plugin init noun-verb surface#1370

Merged
danielmeppiel merged 8 commits into
mainfrom
danielmeppiel/wave-3-portable-release-pipeline
May 18, 2026
Merged

feat(cli): introduce apm plugin init noun-verb surface#1370
danielmeppiel merged 8 commits into
mainfrom
danielmeppiel/wave-3-portable-release-pipeline

Conversation

@danielmeppiel
Copy link
Copy Markdown
Collaborator

@danielmeppiel danielmeppiel commented May 18, 2026

feat(cli): introduce apm plugin init noun-verb surface

TL;DR

Adds apm plugin init as the canonical scaffolding command for plugin authors, completing the noun-verb namespace already established by apm marketplace <verb>. Soft-deprecates apm init --plugin and apm init --marketplace (warning + replacement; legacy keeps working through v0.15; removal in v0.16). Ships three new vendor-neutral producer docs and an 11-test end-to-end matrix covering all four supported repo shapes. Closes the "init landscape confusion" UX gap surfaced in discussion #1322 and the producer-journey verification gap surfaced by the adversarial DevX review.

Problem (WHY)

  • The producer surface is asymmetric. apm marketplace is a full noun-verb namespace (add, remove, init, doctor), but plugin scaffolding lives on a --plugin flag of the consumer command. The shape of the surface tells producers "plugins are a side mode of init" -- they are not.
  • Three adversarial Opus DevX reviews flagged the surface as failing well-known package-manager mental models. Agent B (kubectl/gh lens) was unambiguous: "verb namespaces beat flag combinations every single time."
  • The previous Wave 3 v2 design (a release.sh scaffolder) failed two principles: no package manager generates CI pipelines, and it would have cannibalized apm-action. Both were correctly rejected by the user.
  • Issue Producer experience: close the gap from "I built a plugin" to "every assistant can install it" #1348 acceptance criteria require a producer journey that survives CI. We had unit coverage for each piece but no test that exercises init -> author -> pack across all four shapes. A regression in pack's plugin emission path could break aggregator without breaking single-plugin, and CI would not notice.

Approach (WHAT)

Decision Choice Rejected
Scaffolding surface Add apm plugin init; deprecate --plugin/--marketplace flags apm init --shape=... (rejected: vendor-neutrality + mental model debt)
Migration cost Soft-deprecate; legacy flags keep working 2 minors Hard-remove (rejected: breaks every existing user)
Discoverability "Next steps" panel after apm init teaches both verbs Add a --help epilog only (rejected: invisible to new users)
CI guidance Documentation-only: one portable shell recipe, four CI wrappers Generate release.yml per CI (rejected: not vendor-neutral; cannibalizes apm-action)
Test coverage New tests/integration/test_producer_journey.py, 11 tests across 4 shapes + parity + deprecation Wait for first regression (rejected: G2 already broke this surface once)

Implementation (HOW)

File Change
src/apm_cli/commands/plugin/__init__.py (new) Click group hosting the plugin-author noun namespace
src/apm_cli/commands/plugin/init.py (new) apm plugin init -- thin wrapper delegating to _perform_init(plugin=True, source="plugin")
src/apm_cli/commands/init.py Extracted body into _perform_init(); added stderr deprecation echoes for --plugin/--marketplace; branched "Next steps" on source so consumer init teaches the noun-verb namespace
src/apm_cli/cli.py Registers the new plugin group
tests/unit/commands/test_plugin_init_command.py (new) 7 unit tests: surface parity, deprecation message shape, consumer next-steps
tests/integration/test_producer_journey.py (new) 11 e2e journey tests across single-plugin / aggregator / monorepo / hybrid + cross-flow byte equivalence + deprecation contract
docs/src/content/docs/producer/repo-shapes.md (new) The four supported shapes, decision matrix, migration paths
docs/src/content/docs/producer/releasing-from-any-ci.md (new) One portable shell recipe wrapped for GH Actions, GitLab CI, Jenkins, Azure DevOps
docs/src/content/docs/producer/versioning-strategies.md (new) Lockstep vs per-package; how --check-versions enforces alignment
docs/src/content/docs/consumer/installing-from-marketplaces.md (new) Native runtime install table (consumer ramp companion)
docs/src/content/docs/producer/publish-to-a-marketplace.md Refreshed -- trims duplication, delegates to the new pages
.apm/docs-index.yml 4 new corpus entries for the docs-sync skill
CHANGELOG.md Added + Deprecated sections under Unreleased

Diagrams

The producer-surface command graph. Boxed nodes are NEW.

flowchart LR
    user((Producer))
    user --> initc[apm init<br/>consumer]
    user --> pinit[apm plugin init]:::new
    user --> minit[apm marketplace init]
    initc -.deprecated.-> legacy_p[apm init --plugin]:::deprecated
    initc -.deprecated.-> legacy_m[apm init --marketplace]
    legacy_p -.redirects.-> pinit
    legacy_m -.redirects.-> minit
    pinit --> plugin_json[plugin.json + apm.yml]
    minit --> mkt_block[marketplace block in apm.yml]
    classDef new fill:#d4edda,stroke:#28a745,stroke-width:2px
    classDef deprecated fill:#fff3cd,stroke:#856404,stroke-dasharray:5
Loading

The four repo shapes that emerge from composing the two verbs. None require a --shape flag.

flowchart TB
    subgraph Shapes
        s1[single-plugin<br/>apm plugin init]
        s2[aggregator<br/>apm init + apm marketplace init]
        s3[monorepo<br/>aggregator + per-package apm plugin init]
        s4[hybrid<br/>apm plugin init + apm marketplace init]
    end
    s1 --> pack[apm pack]
    s2 --> pack
    s3 --> pack
    s4 --> pack
    pack --> bundle[build/]
Loading

The e2e matrix and what each test proves.

flowchart LR
    A[Wave 7 matrix] --> B[single-plugin<br/>3 tests]
    A --> C[aggregator<br/>2 tests incl. legacy flag]
    A --> D[monorepo<br/>1 test: 2 packages]
    A --> E[hybrid<br/>1 test]
    A --> F[parity<br/>byte-equivalence new vs legacy]
    A --> G[deprecation contract<br/>2 tests: --plugin / --marketplace]
Loading

Trade-offs

  • Two ways to scaffold a plugin for one release cycle. Both apm plugin init and apm init --plugin work. The deprecation echo nudges migration; legacy removal is locked to v0.16. The alternative -- hard-removing in this PR -- would break every existing user.
  • CI guidance is docs, not codegen. We could ship a release.yml generator and reduce producer effort to zero on day one. Rejected because (a) no canonical package manager generates CI pipelines, (b) it would compete with apm-action, and (c) it locks us to one vendor's syntax. The portable shell recipe wins on neutrality and longevity.
  • No apm init --lib --workspace (npm/cargo-style). Tempting because it matches a familiar mental model, but it would force a breaking rename of the existing marketplace noun namespace and force every monorepo user to migrate. The noun-verb composition reaches the same destination at zero migration cost.

Benefits

  1. Mental model parity -- apm <noun> <verb> works the same way for plugin and marketplace, so the two halves of the producer surface no longer disagree about their own shape.
  2. Zero migration cost -- 100% of existing --plugin/--marketplace invocations keep working through v0.15.
  3. Discoverability gain -- the post-init "Next steps" panel teaches both noun verbs in 3 lines.
  4. Regression net -- 11-test e2e matrix means any future change to init or pack that breaks one shape fails CI in <5 seconds.
  5. Vendor-neutral CI story -- four CI wrappers, one shell recipe, no codegen lock-in.

Companion PRs

  • apm-action#43 -- adds mode: release to the action, the GitHub-Actions-flavoured convenience wrapper that the new releasing-from-any-ci.md page documents alongside equally-weighted GitLab / Jenkins / Azure DevOps recipes.

Validation

Local validation transcript (lint + targeted tests + journey matrix)
$ uv run --extra dev ruff check src/ tests/
All checks passed!

$ uv run --extra dev ruff format --check src/ tests/
778 files already formatted

$ uv run --extra dev pytest tests/unit/commands/test_plugin_init_command.py \
                              tests/unit/test_init_command.py \
                              tests/integration/test_producer_journey.py -q
....................................................................     [100%]
68 passed in 3.88s

$ uv run --extra dev pytest tests/unit/ -q -n auto --dist worksteal
... 8613 passed ...

Scenario Evidence

User-promise scenario Test Principle
"I can scaffold a plugin without learning a flag" test_init_produces_plugin_json_and_apm_yml Discoverability
"Monorepo authors compose verbs; no special mode" test_init_two_packages_under_monorepo Composability
"My existing --plugin script keeps working" test_new_surface_matches_legacy_flag_byte_for_byte Backward compatibility
"Consumer init tells me where the producer surface lives" test_apm_init_consumer_surfaces_namespace_hints Discoverability
"Deprecation warnings name the replacement and the removal milestone" test_init_plugin_flag_warning_shape, test_init_marketplace_flag_warning_shape Honest migration

How to test

  • git fetch && git checkout danielmeppiel/wave-3-portable-release-pipeline
  • uv run --extra dev pytest tests/integration/test_producer_journey.py -v -- 11 green
  • In a tmp dir: apm plugin init demo --yes then inspect demo/plugin.json and demo/apm.yml
  • In a tmp dir: apm init demo --plugin --yes and confirm the stderr deprecation message names apm plugin init and v0.16
  • Run apm init demo --yes and confirm the "Next steps" panel surfaces both apm plugin init and apm marketplace init
  • Visit the new docs pages (producer/repo-shapes, producer/releasing-from-any-ci, producer/versioning-strategies, consumer/installing-from-marketplaces) and confirm the refreshed producer/publish-to-a-marketplace no longer duplicates their content

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

Daniel Meppiel and others added 2 commits May 18, 2026 17:32
Adds 'apm plugin init' as the canonical scaffolding command for plugin
authors, completing the noun-verb namespace already established by
'apm marketplace <verb>'. The four supported repo shapes -- single-plugin,
aggregator, monorepo, hybrid -- emerge from composing these two verbs;
APM does not gate shapes behind a --shape flag.

Soft-deprecates 'apm init --plugin' and 'apm init --marketplace' (stderr
warning naming the replacement; legacy flags keep working through v0.15;
removal in v0.16). 'apm init' becomes consumer-first and prints a
'Next steps' panel teaching the noun-verb taxonomy.

Adds three producer docs pages (repo-shapes, releasing-from-any-ci,
versioning-strategies). The CI guidance is vendor-neutral: one portable
shell recipe wrapped in GitHub Actions, GitLab CI, Jenkins, and Azure
DevOps -- APM does not generate CI pipelines.

Verification:
  * tests/integration/test_producer_journey.py -- 11 new tests covering
    all four shapes + parity + deprecation contracts
  * tests/unit/commands/test_plugin_init_command.py -- 7 new tests
  * Full unit suite: 8613 passed
  * Lint silent

Closes-part-of: #1348

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The docs added in the prior commit were authored directly from the design
artifact, bypassing the doc-sync skill contract. Reverting so docs land
through the proper orchestration.

Code + tests + CHANGELOG kept; only docs/src/ pages reverted.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@danielmeppiel
Copy link
Copy Markdown
Collaborator Author

Docs sync advisory

Verdict: structural * Pages affected: 4 (1 new + 3 edits) * LLM calls: 11/15 * Took: ~6 min

Important

Docs land the PRODUCE promise cleanly with one redraft pass -- verb-first lede, no speculative future-verbs, no legacy in the teaching ramp. The technical substrate is solid (verifier confirms 6/7 claims, writer self-corrected the 1 refutation against the architect outline); the redraft below is editorial discipline at the lede plus one teaching-narrative leak. No companion docs PR will be opened automatically -- the docs-sync-confirm label is not present. Apply the patches manually or add the label and re-run with the docs-sync label to trigger automated commit.

Classifier verdict

Structural (high confidence). The PR introduces a brand-new top-level CLI verb namespace (apm plugin). That cannot be served by an in-place edit to init.md alone; it needs a dedicated reference page mirroring the existing marketplace.md noun-verb home.

Architect TOC delta

Action Path Rationale
NEW docs/src/content/docs/reference/cli/plugin.md (sidebar.order=21) Noun page hosting all apm plugin <verb> (today: init). Mirrors marketplace.md@22 for symmetry under PRODUCE.
EDIT docs/src/content/docs/reference/cli/init.md Deprecate --plugin and --marketplace flag rows; add Deprecations subsection; cross-link to new noun pages.
EDIT docs/src/content/docs/getting-started/first-package.md Swap apm init --plugin team-skills -> apm plugin init team-skills.
EDIT docs/src/content/docs/reference/manifest-schema.md Update devDependencies callout cross-link.

S7 verifier evidence

# Claim Verdict Evidence
1 apm plugin init command exists verified apm plugin --help shows init subcommand
2 Flag set: --force --name --owner (per architect outline) refuted Actual flags: -y/--yes, --target, -v/--verbose, plus positional PROJECT_NAME. Writer self-corrected against the outline.
3 apm init --plugin prints deprecation stderr citing v0.16 verified src/apm_cli/commands/init.py:82-85
4 apm init --marketplace prints deprecation stderr citing v0.16 verified src/apm_cli/commands/init.py:88-91
5 CHANGELOG documents v0.16 removal verified CHANGELOG.md:42
6 Next steps panel after apm init exists verified src/apm_cli/commands/init.py:264-282
7 Byte-for-byte parity between apm plugin init and apm init --plugin is test-enforced verified tests/integration/test_producer_journey.py:186-198 + shared _perform_init(plugin=True) helper

Patch 1 of 4 -- NEW page docs/src/content/docs/reference/cli/plugin.md

Click to expand full file body (~85 lines)
---
title: apm plugin
description: Scaffold a publishable plugin project. The noun-verb home for `apm plugin init` and future plugin-scoped verbs.
sidebar:
  order: 21
---

## Synopsis

```bash
apm plugin init [PROJECT_NAME] [-y] [--target TARGETS] [-v]

# Example
apm plugin init my-skill --yes

Description

apm plugin init scaffolds a publishable plugin in the current directory: a plugin.json manifest plus an apm.yml carrying a devDependencies block. The result is a working tree you can commit, tag, and reference from a marketplace.

apm plugin is the noun-verb home for plugin-author workflows, mirroring apm marketplace for marketplace-author verbs. Today it ships a single verb -- apm plugin init. Sibling verbs live under the same namespace as they ship.

The two common repo shapes for plugin authors -- single-plugin (one plugin per repo) and aggregator (one repo that ships a marketplace plus the plugins it indexes) -- are not gated by flags. They emerge from composing apm plugin init and apm marketplace init in the same working tree.

Subcommands

apm plugin init

Scaffold a plugin authoring project. Writes plugin.json and an apm.yml with a devDependencies block in the current directory (or under PROJECT_NAME/ if provided).

apm plugin init
apm plugin init my-skill --yes
apm plugin init my-skill --target copilot,claude --yes
Flag Description
PROJECT_NAME Optional positional. If provided, scaffolds into a new subdirectory of that name; otherwise writes into the current directory.
--yes, -y Skip interactive prompts and use auto-detected defaults.
--target Comma-separated target list (e.g. copilot,claude,codex). Skips the target prompt and writes selections directly.
--verbose, -v Show detailed output.

Migration from apm init --plugin

If you've used apm init --plugin before, here's the move: run apm plugin init instead. The generated files are byte-for-byte identical.

The legacy apm init --plugin flag still works and still produces the same output, but prints a deprecation warning on stderr:

[!] Deprecation: 'apm init --plugin' is deprecated. Use 'apm plugin init' instead.
    Legacy flag will be removed in v0.16.

Migrate at your convenience before v0.16.

Examples

Single-plugin repo

One repo, one plugin. Author publishes a git tag; consumers reference it as owner/repo@version.

mkdir my-skill && cd my-skill
apm plugin init --yes
git init && git add . && git commit -m "init"
git tag v0.1.0

Aggregator repo

One repo that ships a marketplace and the plugins it indexes side-by-side. Useful when you want one place to govern a small fleet of related plugins.

mkdir agents-hub && cd agents-hub
apm marketplace init --yes
apm plugin init review-bot --yes
apm plugin init lint-bot --yes

The top-level apm.yml carries the marketplace authoring config; each plugin lives in its own subdirectory with its own plugin.json and apm.yml.

See also

  • apm marketplace -- author and publish marketplaces that index your plugins.

</details>

### Patch 2 of 4 -- IN-PLACE `docs/src/content/docs/reference/cli/init.md`

**Edit A: Description paragraph**

```diff
- Use `--plugin` to also scaffold `plugin.json` for a publishable
- plugin, or `--marketplace` to seed an authoring block for a
- marketplace.
+ The legacy `--plugin` and `--marketplace` flags (which scaffolded a
+ plugin or marketplace authoring block alongside `apm.yml`) are
+ deprecated and will be removed in v0.16; use [`apm plugin init`](../plugin/)
+ and [`apm marketplace init`](../marketplace/) instead.

Edit B: Options table --plugin row (prefix with **Deprecated (removed in v0.16).** Use [\apm plugin init`](../plugin/) instead.`)

Edit C: Options table --marketplace row (prefix with **Deprecated (removed in v0.16).** Use [\apm marketplace init`](../marketplace/) instead.`)

Edit D: NEW ## Deprecations subsection (insert between ## Behavior and ## Related)

## Deprecations

The `--plugin` and `--marketplace` flags are deprecated and will be
removed in **v0.16**. They remain functional during the deprecation
window; each invocation prints a one-line warning to stderr pointing
at the replacement command (`apm plugin init` or `apm marketplace
init`). Migrate to:

- [`apm plugin init`](../plugin/) -- replaces `apm init --plugin`.
- [`apm marketplace init`](../marketplace/) -- replaces
  `apm init --marketplace`.

Edit E: ## Related list + :::note[Next steps] aside (add apm plugin init and apm marketplace init bullets; describe the new Next steps panel printed after apm init succeeds)

Patch 3 of 4 -- IN-PLACE docs/src/content/docs/getting-started/first-package.md

- 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.
+ If you know up front that you want to ship a plugin, you can scaffold with
+ `apm plugin init 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.

Patch 4 of 4 -- IN-PLACE docs/src/content/docs/reference/manifest-schema.md

- Created automatically by `apm init --plugin`. Use [`apm install --dev`](../cli/install/) to add packages:
+ Created automatically by [`apm plugin init`](../cli/plugin/). Use [`apm install --dev`](../cli/install/) to add packages:

Panel disagreement notes

  • Editorial verdict: revise (9 tone findings, mostly about lede taxonomy and one legacy-flag leak into a teaching narrative). All findings folded into the redraft above.
  • Growth verdict: ship. Flagged forward-link risk -- CDO decided trim_to_repo_shapes (see "Open scope decisions" below).
  • CDO synthesis: revise-then-ship. Redraft is the patch set above; no second loop needed.

Open scope decisions for the maintainer

  1. Forward links trimmed. The architect's original See also block referenced 3 producer pages that don't exist in main yet (producer/repo-shapes, producer/releasing-from-any-ci, producer/versioning-strategies). CDO trimmed all 3 from the new page to avoid shipping broken links. Re-add them when those pages land via a follow-up doc-sync run.
  2. Repo-shape vocabulary scoped down. monorepo and hybrid are removed from the new page until producer/repo-shapes exists to define them. The page documents only single-plugin and aggregator today.
  3. Companion PR not opened. Per the docs-sync skill contract, the companion docs PR fires only when this PR carries the docs-sync-confirm label. Apply that label and re-run the workflow (or apply the patches manually) to land the docs.

Growth release-note angle (out of scope, for CEO triage)

This PR is a quiet positioning unlock disguised as a CLI ergonomics fix. One-line elevator pitch worth surfacing in the v0.15 release notes:

apm plugin init scaffolds a publishable AI plugin in one command -- the same way npm init scaffolds a Node package.

Recommend the maintainer pass this to oss-growth for the release-note draft. Keep it out of the docs PR scope.


Generated by the docs-sync skill (advisory; does not gate merge). Re-run by re-applying the docs-sync label.

…l guides

Wave 6 of #1348 producer-experience refresh. Four new pages and one
refresh, drafted through the doc-sync persona panel (doc-writer +
python-architect verification + editorial-owner + oss-growth-hacker)
and synthesized by CDO.

New pages:
- producer/repo-shapes.md: single-plugin, aggregator, monorepo-hybrid
- producer/releasing-from-any-ci.md: vendor-neutral release sequence
  (GitHub Actions, GitLab, Jenkins, Azure DevOps), with apm-action@v1
  as a documented convenience wrapper
- producer/versioning-strategies.md: lockstep / tag_pattern / per_package
- consumer/installing-from-marketplaces.md: native runtime install table

Refresh:
- producer/publish-to-a-marketplace.md: trims duplicated CI prose,
  delegates to the new pages, keeps registry schema as the canonical
  reference

Updates .apm/docs-index.yml with the four new entries.

All CLI claims verified against the local apm binary (apm pack
--check-versions / --check-clean / --json; apm plugin init; apm
marketplace init; apm marketplace package add). ASCII-only.

Refs #1348

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@danielmeppiel danielmeppiel marked this pull request as ready for review May 18, 2026 18:39
Copilot AI review requested due to automatic review settings May 18, 2026 18:39
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces apm plugin init as a first-class noun-verb CLI surface for plugin author scaffolding, while keeping apm init --plugin/--marketplace working via a soft deprecation path. It also expands producer/consumer documentation and adds unit + integration coverage for the end-to-end producer journey across multiple repo layouts.

Changes:

  • Added a new apm plugin command group with apm plugin init, delegating to shared init logic for parity with legacy flags.
  • Updated apm init to emit deprecation warnings for --plugin/--marketplace and to print consumer “Next steps” hints that point to the new noun namespaces.
  • Added unit + integration tests and new docs pages to document repo shapes, versioning/release gates, and marketplace installation paths.
Show a summary per file
File Description
src/apm_cli/cli.py Registers the new plugin command group at the top-level CLI.
src/apm_cli/commands/init.py Extracts shared init logic into _perform_init(), adds deprecation stderr warnings, and updates “Next steps” hints.
src/apm_cli/commands/plugin/__init__.py New apm plugin noun namespace (Click group).
src/apm_cli/commands/plugin/init.py New apm plugin init command delegating to _perform_init(plugin=True, source="plugin").
tests/unit/test_init_command.py Updates expectations for consumer init “Next steps” content.
tests/unit/commands/test_plugin_init_command.py Adds unit tests for apm plugin init behavior and legacy-flag deprecation warnings.
tests/integration/test_producer_journey.py Adds an end-to-end journey matrix covering multiple producer repo shapes and legacy/new parity.
docs/src/content/docs/producer/repo-shapes.md New producer doc explaining supported repo layouts and the noun-verb composition.
docs/src/content/docs/producer/releasing-from-any-ci.md New producer doc describing a portable CI release sequence using apm pack release gates.
docs/src/content/docs/producer/versioning-strategies.md New producer doc describing marketplace.versioning.strategy and apm pack --check-versions.
docs/src/content/docs/producer/publish-to-a-marketplace.md Refreshes and de-duplicates marketplace authoring docs; links out to the new pages.
docs/src/content/docs/consumer/installing-from-marketplaces.md New consumer doc mapping install commands/auth/cache per runtime.
.apm/docs-index.yml Adds new docs pages to the docs index/symbol map.
CHANGELOG.md Adds Unreleased entries for the new CLI surface + docs and the deprecation notice.

Copilot's findings

  • Files reviewed: 14/14 changed files
  • Comments generated: 3

Comment thread CHANGELOG.md Outdated
- `apm init --plugin` and `apm init --marketplace` are deprecated in favor of `apm plugin init` and `apm marketplace init`. The legacy flags still work; they print a one-line stderr warning naming the replacement and **will be removed in v0.16**. Existing scripts continue to function unchanged during the deprecation window. (#1348)

- Refactored duplicate code blocks across MCP client adapters and marketplace modules: extracted shared helpers `_apply_pypi_homebrew_generic_config`, `_apply_auth_and_headers_impl`, and `_resolve_env_vars_with_prompting` into `MCPClientAdapter` base class; extracted `iter_semver_tags` into `marketplace._shared`; fixed homebrew formula slash-stripping, `Authorization` header skip-only-when-injected logic, and CI-aware prompting guard (`CI`/`APM_E2E_TESTS` env vars now suppress interactive prompts). (#1360)
### Changed: extracted shared helpers `_apply_pypi_homebrew_generic_config`, `_apply_auth_and_headers_impl`, and `_resolve_env_vars_with_prompting` into `MCPClientAdapter` base class; extracted `iter_semver_tags` into `marketplace._shared`; fixed homebrew formula slash-stripping, `Authorization` header skip-only-when-injected logic, and CI-aware prompting guard (`CI`/`APM_E2E_TESTS` env vars now suppress interactive prompts). (#1360)
@@ -0,0 +1,72 @@
---
title: Installing from marketplaces
description: Five ways consumers install APM-published plugins -- through APM, VS Code, Cursor, Copilot CLI, Claude Code, and Codex -- and the auth and cache layout of each.
Comment on lines +1 to +22
---
title: Repo shapes for marketplace producers
description: Three layouts for shipping APM plugins -- single-plugin, aggregator, and monorepo-hybrid -- and the noun-verb commands that scaffold each.
sidebar:
order: 5
---

A marketplace producer repo is just an `apm.yml` (or several) plus a
`marketplace:` block. There is no `--shape` flag and no scaffold
mode: every layout below emerges from the same two commands,
`apm plugin init` and `apm marketplace init`, composed differently.

Pick the shape that matches how the source code is already
organised. You can migrate later by moving directories and re-running
the same commands.

| Shape | Source files | When |
|------------------|---------------------------------------------------|-----------------------------------------------------|
| Single-plugin | One `apm.yml` at the repo root | One plugin per repo. Smallest surface, fewest gotchas. |
| Aggregator | One `apm.yml` at the root, N remote `packages:` | You curate other repos into a marketplace. |
| Monorepo-hybrid | Root `apm.yml` plus per-plugin `apm.yml` subdirs | Many plugins live alongside the marketplace in one repo. |

Daniel Meppiel and others added 4 commits May 18, 2026 20:59
Applies the four patches recommended by the docs-sync workflow advisory
on PR #1370 (comment 4479394909):

- NEW: docs/src/content/docs/reference/cli/plugin.md (sidebar.order=21)
  Noun page mirroring marketplace.md, hosting all apm plugin <verb>
  subcommands. Documents single-plugin and aggregator repo shapes by
  composing apm plugin init + apm marketplace init.

- EDIT: docs/src/content/docs/reference/cli/init.md
  Deprecate --plugin and --marketplace flag rows; add Deprecations
  subsection; cross-link to new noun pages in Related.

- EDIT: docs/src/content/docs/getting-started/first-package.md
  Swap 'apm init --plugin team-skills' -> 'apm plugin init team-skills'.

- EDIT: docs/src/content/docs/reference/manifest-schema.md
  Update devDependencies callout cross-link to apm plugin init.

- EDIT: .apm/docs-index.yml
  Add reference/cli/plugin.md to apm plugin init symbol_index.

Patches verified by the doc-sync persona panel (S7 evidence: 6/7
claims verified, 1 self-corrected against the architect outline).
ASCII-only.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- producer/index.md: name apm plugin init as scaffold entry; add
  'two primitive postures + composition' framing; insert
  'Production-grade releases' sidebar table linking the three
  Wave 6 operational pages; fix dead 'apm publish via a marketplace
  adapter' vocabulary to marketplace.outputs-aware wording.
- producer/repo-shapes.md: reframe lead from 'three layouts' to
  'two primitive postures plus a hybrid composition'; mark
  monorepo-hybrid section as advanced with zava-agent-configs
  as the canonical example.
- getting-started/first-package.md: cross-link 'apm plugin init'
  to reference/cli/plugin and producer/repo-shapes so first-time
  authors discover the noun-verb command and pick a layout.

Joint CDO + CEO recommendation: keep all three documented shapes
(hybrid is real and tested), but frame as 2 primitives + 1
composition so cold-visitor cognitive load stays at 2 and the
5-rung happy path stays uncluttered. No README/MANIFESTO touch in
this PR per CEO scope boundary.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- CHANGELOG.md: fix malformed '### Changed: extracted helpers...'
  heading. Split into standalone '### Changed' heading + bullet
  underneath so Keep a Changelog auto-parsing works.
- CHANGELOG.md: drop 'four supported repo shapes' claim that
  contradicts the just-shipped CDO+CEO framing. Replace with
  'two primitive postures (single-plugin, aggregator) plus the
  hybrid composition' matching producer/index.md and repo-shapes.md.
- installing-from-marketplaces.md: frontmatter description said
  'Five ways' but the table lists six (APM, VS Code, Cursor,
  Copilot CLI, Claude Code, Codex). Fix to 'Six ways'.

Closes inline review comments 3261253412, 3261253469, 3261253496.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@danielmeppiel danielmeppiel merged commit 21c48b7 into main May 18, 2026
8 checks passed
@danielmeppiel danielmeppiel deleted the danielmeppiel/wave-3-portable-release-pipeline branch May 18, 2026 19:50
danielmeppiel added a commit that referenced this pull request May 18, 2026
* chore: cut 0.14.0

Renames the [Unreleased] block in CHANGELOG.md to [0.14.0] - 2026-05-18
and bumps the package version from 0.13.0 to 0.14.0 in pyproject.toml
(and uv.lock by regeneration).

0.14.0 ships the producer-experience epic (#1348) on the CLI side --
notably:

- apm pack --check-versions / --check-clean (#1365), the release gates
  consumed by apm-action mode: release.
- apm plugin init (#1370), the noun-verb successor to apm init --plugin.
- apm pack multi-format outputs (--marketplace, --marketplace-path,
  --json, marketplace.outputs map form) (#1317).
- New producer docs corpus (repo-shapes / releasing-from-any-ci /
  versioning-strategies) (#1370).
- Breaking: MCP registry client adopts the official v0.1 spec; self-
  hosted registries must serve /v0.1/ paths (#1337).

Plus the deprecations and fixes already listed in the moved block.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs(changelog): tighten v0.14.0 entries; add post-cut PRs

- One concise line per PR answering 'so what?' for end users
- Add 5 missing entries: #1376 (perf resolver), #1373 (shared/apm.md
  matrix secret-stripping), #1246 (install.ps1 GHES env vars), #1255
  (warn missing apm.yml), #1248 (extends:org unmanaged_files)
- Drop internal/CI/test-infra entries (#1270, #1271, #1272, #1274,
  #1276, #1291, #1360 refactor)
- Consolidate three #605 lines and four #1317 lines into one entry
  per PR where appropriate
- Promote MCP Registry v0.1 to a dedicated Breaking section

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* docs(changelog): add #1377 Bitbucket DC tilde fix

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Daniel Meppiel <copilot-rework@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants