Skip to content

feat(marketplace): support multi-profile marketplace outputs#1281

Open
henrydennis wants to merge 1 commit into
microsoft:mainfrom
henrydennis:feature/multi-marketplace-outputs
Open

feat(marketplace): support multi-profile marketplace outputs#1281
henrydennis wants to merge 1 commit into
microsoft:mainfrom
henrydennis:feature/multi-marketplace-outputs

Conversation

@henrydennis
Copy link
Copy Markdown

@henrydennis henrydennis commented May 11, 2026

TL;DR

apm pack can now build more than one marketplace artifact from the same marketplace: block. Claude/Anthropic output remains the default and keeps the existing .claude-plugin/marketplace.json behavior, while maintainers can opt into Codex repo marketplace output with marketplace.outputs: [claude, codex].

Problem

Marketplace authoring was effectively single-output: the schema and builder assumed one Claude-compatible marketplace.json path. That made it awkward to support another repo marketplace shape without either duplicating resolution logic or letting Codex-specific fields leak into the Claude artifact.

There was also an ambiguous boundary around --marketplace-output: once multiple artifacts exist, the CLI override needs to target the Claude/Anthropic compatibility artifact only, not whichever configured path happens to compare equal to a legacy field.

Approach

Change What
Output profiles Add MarketplaceOutputProfile entries for claude and codex, including profile-specific config namespace, mapper name, required package fields, and whether the CLI output override applies.
Output mappers Move format-specific JSON composition into ClaudeMarketplaceMapper and CodexMarketplaceMapper; keep resolution and writing in MarketplaceBuilder.
Multi-output producer Update MarketplaceProducer to resolve packages once, then write every selected profile and return a BuildReport containing all per-profile output reports.
Schema extensions Add marketplace.outputs, marketplace.claude.output, marketplace.codex.output, and package-level category required only when Codex output is selected.
Docs and init flow Document the multi-output selector, Claude-only override behavior, Codex category requirement, and generated artifact tracking.

Implementation

  • src/apm_cli/marketplace/yml_schema.py parses outputs, output-specific config blocks, and category, while preserving legacy output: as shorthand for claude.output.
  • src/apm_cli/marketplace/output_profiles.py centralizes output capabilities; supports_cli_output_override is true only for the Claude profile.
  • src/apm_cli/marketplace/output_mappers.py owns format-specific JSON shape, so builder no longer contains both Claude and Codex field-mapping logic.
  • src/apm_cli/marketplace/builder.py now writes one profile at a time and returns BuildReport(outputs=(...)); compatibility accessors such as report.output_path and report.resolved continue to work for single-output callers.
  • src/apm_cli/core/build_orchestrator.py loops over selected profiles, applies --marketplace-output only to profiles that support it, and keeps all profile reports in the marketplace producer payload.
  • src/apm_cli/commands/pack.py renders each marketplace output line separately, including the profile name.

Behavior

flowchart TD
    A["apm.yml marketplace block"] --> B["MarketplaceConfig"]
    B --> C["MarketplaceProducer"]
    C --> D["MarketplaceBuilder.resolve()"]
    D --> E["ResolvedPackage tuple"]
    B --> F["MarketplaceOutputProfile registry"]
    F --> G["claude profile"]
    F --> H["codex profile"]
    E --> I["ClaudeMarketplaceMapper"]
    E --> J["CodexMarketplaceMapper"]
    I --> K[".claude-plugin/marketplace.json"]
    J --> L[".agents/plugins/marketplace.json"]
Loading

Example authoring config:

marketplace:
  outputs: [claude, codex]

  claude:
    output: .claude-plugin/marketplace.json

  codex:
    output: .agents/plugins/marketplace.json

  packages:
    - name: local-tool
      source: ./plugins/local-tool
      category: Productivity

Trade-offs

  • BuildReport is now multi-output internally, but keeps single-output compatibility properties to avoid forcing unrelated marketplace callers to change immediately.
  • Codex category is validated at schema load time when codex is selected, so maintainers get an early error instead of a partially written artifact.
  • --marketplace-output remains Claude-only by design. Codex output path is configured declaratively through marketplace.codex.output, which avoids one CLI flag having two different meanings.

Validation

uv run pytest tests/unit tests/test_console.py -x
# 8318 passed, 1 warning in 29.08s

uv run --extra dev ruff check src/ tests/
# All checks passed!

uv run --extra dev ruff format --check src/ tests/
# 752 files already formatted

How to test

  1. Create an apm.yml with marketplace.outputs: [claude, codex] and local package entries that include category.
  2. Run apm pack --offline.
  3. Confirm both .claude-plugin/marketplace.json and .agents/plugins/marketplace.json are written.
  4. Run apm pack --marketplace-output ./build/marketplace.json and confirm only the Claude artifact path is overridden.

@henrydennis
Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

@henrydennis henrydennis marked this pull request as ready for review May 11, 2026 17:26
Copilot AI review requested due to automatic review settings May 11, 2026 17:26
@henrydennis henrydennis force-pushed the feature/multi-marketplace-outputs branch from 74a3a20 to 7778108 Compare May 11, 2026 17:31
@henrydennis henrydennis marked this pull request as draft May 11, 2026 17:32
@henrydennis henrydennis marked this pull request as ready for review May 11, 2026 17:32
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

Note

Copilot was unable to run its full agentic suite in this review.

Adds multi-profile marketplace builds so apm pack can emit multiple marketplace artifacts (Claude + optional Codex) from a single marketplace: block, while keeping backwards compatibility with the existing Claude .claude-plugin/marketplace.json behavior.

Changes:

  • Introduces marketplace output profiles (claude, codex) and output-specific mappers, moving format composition out of the builder.
  • Extends the marketplace YAML schema to support marketplace.outputs, marketplace.claude, marketplace.codex, plus conditional package.category for Codex.
  • Updates pack/orchestrator rendering and init/docs/tests to support and validate multi-output behavior and Claude-only CLI override.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/unit/marketplace/test_local_path_compose.py Adds Codex composition/write tests and verifies Claude output omits Codex-only fields.
tests/unit/marketplace/test_builder.py Updates tests for renamed --marketplace-output plumbing in build options.
tests/unit/marketplace/test_apm_yml_marketplace_loader.py Adds schema/output-profile parsing + validation coverage for multi-output and Codex category requirement.
tests/unit/core/test_build_orchestrator.py Validates orchestrator/producer writes multiple outputs and applies CLI override only to Claude.
tests/unit/commands/test_marketplace_init.py Confirms init template and warnings mention Codex output + gitignore patterns.
tests/integration/test_pack_unified.py Integration coverage for pack writing Codex output when selected.
src/apm_cli/marketplace/yml_schema.py Implements outputs, per-output blocks, and conditional package validation (category for Codex).
src/apm_cli/marketplace/output_profiles.py Adds centralized profile registry for output capabilities and defaults.
src/apm_cli/marketplace/output_mappers.py Introduces Claude/Codex mappers and shared mapping helpers.
src/apm_cli/marketplace/init_template.py Documents multi-output config in the scaffolded marketplace block.
src/apm_cli/marketplace/diagnostics.py Extracts shared build diagnostics type used by mappers/reports.
src/apm_cli/marketplace/builder.py Refactors builder to map/write per-profile and returns multi-output BuildReport.
src/apm_cli/core/build_orchestrator.py Orchestrates resolving once and writing each selected marketplace profile; applies CLI override only to Claude.
src/apm_cli/commands/pack.py Renders per-profile marketplace output lines; clarifies CLI override scope.
src/apm_cli/commands/marketplace/init.py Updates next-steps messaging for optional Codex output and multiple generated artifacts.
src/apm_cli/commands/marketplace/init.py Expands .gitignore checks to cover both Claude and Codex default output paths.
docs/src/content/docs/reference/cli-commands.md Documents multi-output behavior and Claude-only --marketplace-output semantics.
docs/src/content/docs/guides/pack-distribute.md Updates pack guide to describe selectable marketplace outputs.
docs/src/content/docs/guides/marketplace-authoring.md Documents marketplace.outputs, Codex output shape/requirements, and updated examples.

Comment thread src/apm_cli/core/build_orchestrator.py
Comment thread src/apm_cli/marketplace/builder.py
Comment thread src/apm_cli/marketplace/yml_schema.py Outdated
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