Skip to content

👷 chore(types): backport the marketplace face contracts - #426

Open
quentinlebourles-packmind wants to merge 1 commit into
mainfrom
chore/backport-marketplace-face-types
Open

👷 chore(types): backport the marketplace face contracts#426
quentinlebourles-packmind wants to merge 1 commit into
mainfrom
chore/backport-marketplace-face-types

Conversation

@quentinlebourles-packmind

Copy link
Copy Markdown
Contributor

Explanation

Backports the marketplace face contracts so both editions compile against the same shared types and ship the same schema history.

A face is one vendor's projection of a marketplace's shared plugin payload — it owns a descriptor path and its own way of referencing a plugin's source, while the plugins/<slug>/ directories stay shared. This PR names that concept in @packmind/types and adds the column that stores it. Contracts and schema only — no marketplace logic.

Concretely:

  • MarketplaceVendor gains 'copilot'; MarketplaceFaceId ('claude' | 'copilot') names the descriptor-path axis, which is separate from what a descriptor declares itself to be.
  • PluginSource becomes a union: Copilot references a plugin by owner/name slug, where Claude Code uses a clone URL plus a subdirectory.
  • Marketplace carries the set of faces it serves; MarketplaceDescriptor carries the per-face reconciliation outcome and the partially-served slugs.
  • The updateMarketplaceFaces contract, its three errors, and the port method.
  • Migration 1818000000000-AddFacesToMarketplaces, backfilling existing rows to ["claude"].

The OSS marketplaces stub gains the matching updateMarketplaceFaces throw, since it implements the widened port — that is the one file here outside types/migrations.

This is the prerequisite half of a pair: it must land before the proprietary PR's check-oss-sync can pass.

Type of Change

  • New feature

Affected Components

  • Domain packages affected: types, migrations, editions
  • Frontend / Backend / Both: Backend (shared contract layer)
  • Breaking changes (if any): none. MarketplaceVendor and PluginSource are widened rather than changed, and the new column is NOT NULL with a default that backfills existing rows.

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing completed
  • Test coverage maintained or improved

Test Details:

  • nx run-many -t lint test typecheck -p types migrations editions in the oss edition: types 17 suites / 273 tests, migrations 2/22, editions typecheck clean — all green.
  • The migration is covered up, down, and for its backfill against pg-mem.
  • Parity verified with the exact diff -rq -x node_modules -x dist -x '.*' invocation check-oss-sync uses: packages/types and packages/migrations in sync with the proprietary tree.

TODO List

  • CHANGELOG Updated
  • Documentation Updated

Neither applies: this carries no user-facing behaviour on its own. The changelog entries and end-user docs live with the feature, in the proprietary PR.

Reviewer Notes

  • MarketplaceFaceId uses 'claude' while MarketplaceVendor uses 'anthropic'. That asymmetry is intentional and documented on both types: the face is the descriptor path Packmind writes to, the vendor is what a descriptor declares itself to be, and the two need to stay independently extensible.
  • MarketplaceFaceHealth carries the contract that an unreadable face reports an empty missing-slug list rather than "everything is missing". The doc comment states why, because the consuming logic in the proprietary edition depends on it: without that, a transient fetch failure would look like plugins leaving the catalogue.

🤖 Generated with Claude Code

@packmind/types is the contract layer both editions compile against, and
packages/migrations must ship the same schema history in both, so the
multi-assistant marketplace work lands here first.

This is contracts and schema only — no marketplace logic. A face is one
vendor's projection of a marketplace's shared plugin payload: MarketplaceVendor
gains 'copilot', PluginSource becomes a union so a plugin can be referenced by
owner/name slug as well as by clone URL plus subdirectory, and the marketplace
row carries the set of faces it serves.

The OSS marketplaces stub gains the matching updateMarketplaceFaces throw,
since it implements the widened port.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@quentinlebourles-packmind

Copy link
Copy Markdown
Contributor Author

Prerequisite for PackmindHub/packmind-proprietary#739 (multi-assistant marketplaces). check-oss-sync on that PR compares packages/types and packages/migrations against this repo's main, so this one merges first.

@greptile-apps

greptile-apps Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR backports the shared multi-face marketplace contracts and schema history needed for OSS/proprietary edition parity.

  • Adds Claude and Copilot face identifiers, per-face reconciliation health, and Copilot plugin-source contracts.
  • Extends marketplace and descriptor types with served faces and partial-service state.
  • Adds the update-faces use-case and port contracts, corresponding domain errors, and an OSS adapter stub.
  • Adds and tests a migration that backfills existing marketplaces with the Claude face.

Confidence Score: 5/5

The PR appears safe to merge; no concrete changed-code failure remains in the reviewed contracts, migration, or OSS adapter.

The migration is discoverable and ordered, its backfill and rollback are covered, the new descriptor fields are compatibility-preserving, and the OSS edition does not execute marketplace persistence or vendor-specific processing.

Important Files Changed

Filename Overview
packages/migrations/src/migrations/1818000000000-AddFacesToMarketplaces.ts Adds a correctly ordered migration that creates and backfills the non-null JSONB faces column.
packages/migrations/src/lib/migrations.spec.ts Covers migration application, legacy-row backfill, and rollback.
packages/types/src/marketplaces/Marketplace.ts Adds the required served-face collection to the shared Marketplace contract.
packages/types/src/marketplaces/MarketplaceDescriptor.ts Adds optional per-face health and partially served plugin state while preserving compatibility with older descriptors.
packages/types/src/marketplaces/PluginRef.ts Widens plugin source coordinates with a discriminated GitHub source variant.
packages/types/src/marketplaces/contracts/IUpdateMarketplaceFacesUseCase.ts Defines the complete desired-set update command and its applied-delta response.
packages/types/src/marketplaces/ports/IMarketplacePort.ts Exposes the new face-update operation through the marketplace port.
packages/editions/src/oss/marketplaces/MarketplacesAdapter.ts Keeps the OSS adapter aligned with the widened port by rejecting the unavailable operation consistently.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
    DB[(marketplaces.faces JSONB)] --> M[Marketplace.faces]
    M --> U[UpdateMarketplaceFaces contract]
    U --> P[IMarketplacePort]
    P --> OSS[OSS adapter: unavailable]
    M --> D[MarketplaceDescriptor]
    D --> H[Per-face health]
    D --> R[Drift and partial-service results]
    F[MarketplaceFaceId] --> M
    F --> H
    S[PluginSource union] --> D
Loading

Reviews (1): Last reviewed commit: "👷 chore(types): backport the marketplac..." | Re-trigger Greptile

@sonarqubecloud

sonarqubecloud Bot commented Aug 5, 2026

Copy link
Copy Markdown

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.

1 participant