👷 chore(types): backport the marketplace face contracts - #426
👷 chore(types): backport the marketplace face contracts#426quentinlebourles-packmind wants to merge 1 commit into
Conversation
@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>
|
Prerequisite for PackmindHub/packmind-proprietary#739 (multi-assistant marketplaces). |
Greptile SummaryThis PR backports the shared multi-face marketplace contracts and schema history needed for OSS/proprietary edition parity.
Confidence Score: 5/5The 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
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
Reviews (1): Last reviewed commit: "👷 chore(types): backport the marketplac..." | Re-trigger Greptile |
|



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/typesand adds the column that stores it. Contracts and schema only — no marketplace logic.Concretely:
MarketplaceVendorgains'copilot';MarketplaceFaceId('claude' | 'copilot') names the descriptor-path axis, which is separate from what a descriptor declares itself to be.PluginSourcebecomes a union: Copilot references a plugin byowner/nameslug, where Claude Code uses a clone URL plus a subdirectory.Marketplacecarries the set of faces it serves;MarketplaceDescriptorcarries the per-face reconciliation outcome and the partially-served slugs.updateMarketplaceFacescontract, its three errors, and the port method.1818000000000-AddFacesToMarketplaces, backfilling existing rows to["claude"].The OSS marketplaces stub gains the matching
updateMarketplaceFacesthrow, since it implements the widened port — that is the one file here outsidetypes/migrations.This is the prerequisite half of a pair: it must land before the proprietary PR's
check-oss-synccan pass.Type of Change
Affected Components
types,migrations,editionsMarketplaceVendorandPluginSourceare widened rather than changed, and the new column isNOT NULLwith a default that backfills existing rows.Testing
Test Details:
nx run-many -t lint test typecheck -p types migrations editionsin theossedition:types17 suites / 273 tests,migrations2/22,editionstypecheck clean — all green.diff -rq -x node_modules -x dist -x '.*'invocationcheck-oss-syncuses:packages/typesandpackages/migrationsin sync with the proprietary tree.TODO List
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
MarketplaceFaceIduses'claude'whileMarketplaceVendoruses'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.MarketplaceFaceHealthcarries 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