Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .changeset/30904-marketplace-taxonomy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
'@objectstack/spec': minor
'@objectstack/cli': minor
'create-objectstack': patch
---

feat(spec)!: one marketplace taxonomy — business functions, industries, a solution type and a maturity flag replace the single `category` (#30904)

Clause-②: yes (narrowing) — new facet keys and `maturity` widen; `category` retired and refused by name narrows; a contract review runs before the queue
Metadata-protocol: narrowed

<!-- adr-0087: registered marketplace-category-retired -->

**BREAKING** for a package source, publish request or listing that still writes `category`.

- **`@objectstack/spec`.** The marketplace taxonomy is defined once, in `@objectstack/spec/marketplace` (`taxonomy.zod.ts`): `businessFunctions` (1-3 distinct values, the primary one first: `sales`, `marketing`, `customer-service`, `finance`, `hr`, `supply-chain`, `administration`, `project`, `legal`, `it`, `collaboration`), `industries` (up to 3, optional; absent means cross-industry), `solutionType` (`app` | `template` | `connector`; absent means `app`) and `maturity` (`beta` | `stable`; absent means `stable`), on `PackageSchema`, `CreatePackageRequestSchema`, `UpdatePackageRequestSchema`, `TemplateManifestSchema` (`objectstack.manifest.json`) and `MarketplaceListingSchema`, where `businessFunctions` is required. A search filters by `businessFunctions` / `industries` / `solutionTypes` / `maturity` and reads one facet count list per facet. `explainSolutionTypeContradiction` is the publish cross-check (a `template` needs the `unmanaged` install mode, a `connector` a declared connector) and `LEGACY_CATEGORY_MAPPING` says what every old category value becomes.
- **Retired.** `category` on all six schemas, and `MarketplaceSearchResponse.facets.categories`, are `retiredKey()` tombstones: `tsc` refuses them and a parse refuses them with the prescription. `MarketplaceCategorySchema` / `MarketplaceCategory` and `PackageCategorySchema` / `PackageCategory` are removed. `RETIRED_KEYS_BY_MAJOR[18]` lists the six keys, `RETIRED_DEFS_BY_MAJOR[18]` both defs, and the upgrade guide carries the semantic entry `marketplace-category-retired`. No ADR-0087 conversion: none of these shapes is a stack collection member, so `os migrate meta` has nothing to rewrite; a runtime boot never reads them.
- **`@objectstack/cli`.** `os package publish` refuses a `category` in `objectstack.manifest.json`, or the now-hidden `--category` flag, before any network call, naming the facets for the value it held. It judges each facet with the spec's schema, checks a declared `solutionType` against the built artifact, and sends the facets as `business_functions`, `industries`, `solution_type` and `maturity`; an absent facet is not sent.
- **`create-objectstack`.** The blank template no longer ships `category: "starter"`, which every project scaffolded from it inherited and which the hosted publish route refused.

**The remedy.** FROM `"category": "<value>"` TO the facets: delete `category` and declare `businessFunctions` (and, where they apply, `industries` and `solutionType`) in `objectstack.manifest.json`. `os package publish` prints the mapping for the value you had — for example `"finance"` → `"businessFunctions": ["finance"], "solutionType": "app"` — and `LEGACY_CATEGORY_MAPPING` lists them all. A `"starter"` copied from the blank template is simply deleted. A TypeScript caller that imported `MarketplaceCategorySchema` or `PackageCategorySchema` uses `MarketplaceBusinessFunctionSchema` and `MarketplaceSolutionTypeSchema` instead.
13 changes: 9 additions & 4 deletions content/docs/deployment/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3264,7 +3264,6 @@ candidates with how to pass `--env`.
| `-v, --version <semver>` | — | Version to publish. Default: `artifact.manifest.version`, else `0.0.0-dev.` + a timestamp |
| `--display-name <name>` | — | Name shown in the Marketplace (default `artifact.manifest.name`) |
| `--description <text>` | — | Short package description |
| `--category <slug>` | — | Marketplace category slug (`crm`, `hr`, `devtools`, …) |
| `--visibility <level>` | — | `org` (installable across your organization) · `private` (explicit grants only) · `marketplace` (public after review). Omitted: not sent, so the control plane decides — an existing package keeps its visibility, a new one gets the control plane's default (`org` on ObjectOS Cloud) |
| `--org <id>` | `OS_ORG_ID` | `owner_org_id`. Required with a bearer key in service mode; ignored in user mode |
| `--env <id>` | `OS_ENVIRONMENT_ID` | Environment to install the new version into. Defaults to the environment [`os environments switch`](#cloud-environments) — or `os environments create --activate` — recorded **for this control plane** in `~/.objectstack/cloud.json`, then to your organization's only environment |
Expand Down Expand Up @@ -3300,9 +3299,15 @@ and rebuild.

**`objectstack.manifest.json` supplies the listing fields.** When that file is
present in the working directory, publish reads `manifestId`, `displayName`,
`description`, `category`, `tags`, `iconUrl`, `homepageUrl`, `license`,
`readmePath` and a `translations` map from it, so a listing need not be retyped
as flags on every publish. **CLI flags always win.** `tags` has no flag and is
`description`, `tags`, `iconUrl`, `homepageUrl`, `license`, `readmePath`, a
`translations` map and the marketplace facets — `businessFunctions`,
`industries`, `solutionType` and `maturity` — from it, so a listing need not be
retyped as flags on every publish. **CLI flags always win.** Each facet is
checked against the spec's schema before anything is sent, and a declared
`solutionType` against the built artifact: a `template` needs the `unmanaged`
install mode, a `connector` a declared connector. The retired `category` — in
the file, or as `--category` — is refused before any network call, with the
facets that replace the value it held. `tags` has no flag and is
sent as written: the control plane judges the list, and a refusal is its 400,
printed as it is. A top-level `tagline` is used only as the description, when
neither `--description` nor the file's `description` gives one; otherwise it is
Expand Down
16 changes: 11 additions & 5 deletions content/docs/deployment/marketplace-handbook.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ D1/D2). Modules, plugins and other contributions ship **inside** that App — se
[Extras](#extras-dependencies-and-modules) below.

The listing is a package row in the catalog plus its versions: the row carries
the name, description, category, icon, README and translations, and each
the name, description, business functions and other taxonomy facets, icon, README and translations, and each
version is a snapshot of your compiled artifact.

## The listing file: `objectstack.manifest.json`
Expand All @@ -34,24 +34,30 @@ the declared keys below are the ones publish actually sends.
| `manifestId` | The package id (reverse-domain, immutable once published) | `--manifest-id` |
| `displayName` | The name on the card | `--display-name` |
| `description` | The short description | `--description` |
| `category` | The catalog category slug (`crm`, `hr`, `finance`, …) | `--category` |
| `businessFunctions` | The business functions the app serves: 1-3 values, the primary one first (the values: [Marketplace Taxonomy reference](/docs/references/marketplace/taxonomy)) | — |
| `industries` | Up to 3 industries the app is built for; leave it out for a cross-industry app | — |
| `solutionType` | `app` (you keep upgrading it), `template` (the customer's to change — needs the `unmanaged` install mode) or `connector` (needs a declared connector); publish checks it against your built package. Left out: `app` | — |
| `maturity` | `beta` or `stable`; left out: `stable` | — |
| `tags` | The listing tags, sent as written. The catalog validates and stores them and refuses a bad list with a 400, which publish prints as it is; `[]` clears the stored tags, and leaving the key out keeps them | — |
| `iconUrl` | A public http(s) icon URL | `--icon-url`, or `--icon-file` to upload one |
| `homepageUrl` | Your project or docs URL | `--homepage-url` |
| `license` | An SPDX identifier | `--license` |
| `readmePath` | A markdown file, relative to the manifest, read at publish time | `--readme-file`, `--readme` |
| `translations` | Per-locale `displayName`, `description`, `tagline`, `readme` and `screenshotCaptions` | — |

The four taxonomy keys are defined once, in `@objectstack/spec/marketplace`. Publish validates them and sends them; the hosted catalog's facet filters, its submission rule (at least one business function) and the console's facet chips and Beta badge arrive as each side adopts the taxonomy, so until then a value you declare is accepted and not yet shown.

An official ObjectStack listing's `manifestId` is `app.objectstack.<app>` (`app.objectstack.hotcrm`, `app.objectstack.connector-github`); a partner listing uses its own reverse domain, `app.<partner>.<app>`.

[HotCRM](https://github.com/objectstack-ai/hotcrm/blob/main/objectstack.manifest.json)
is a worked example for the keys it carries:
is a worked example for the keys it carries (shown with the business functions
that replace its retired `category`):

```json
{
"manifestId": "app.objectstack.hotcrm",
"displayName": "HotCRM",
"category": "crm",
"businessFunctions": ["sales", "customer-service", "marketing"],
"license": "Apache-2.0",
"iconUrl": "https://raw.githubusercontent.com/objectstack-ai/hotcrm/main/assets/icon.svg",
"homepageUrl": "https://github.com/objectstack-ai/hotcrm",
Expand Down Expand Up @@ -189,7 +195,7 @@ the detail.

1. **Finding the app.** In the Console, **Setup → Browse Marketplace** opens the
**App Marketplace** page, which lists the approved apps; clicking one opens
its page with the README, version, category and license. A runtime started
its page with the README, version, business functions and license. A runtime started
with `OS_CLOUD_URL=off` shows **App Marketplace is turned off** instead —
[Cloud connection](/docs/deployment/cloud-connection) covers connecting one.
2. **Installing.** Into a cloud environment, **Install to cloud…** opens a
Expand Down
5 changes: 3 additions & 2 deletions content/docs/protocol/kernel/plugin-spec.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,9 @@ export default definePlugin({

// MARKETPLACE METADATA
marketplace: {
// Category for marketplace listing
category: 'crm',
// Business functions for the marketplace listing (the taxonomy in
// @objectstack/spec/marketplace; the first is primary)
businessFunctions: ['sales'],

// Screenshots
screenshots: [
Expand Down
13 changes: 7 additions & 6 deletions content/docs/references/index.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Protocol reference — every schema by module
navTitle: Protocol Reference
description: Every schema published by @objectstack/spec — 1631 schemas across 14 protocol modules
description: Every schema published by @objectstack/spec — 1635 schemas across 14 protocol modules
---

{/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */}
Expand All @@ -27,14 +27,14 @@ counts are sums of the rows they head. Regenerate with
| [Identity Protocol](/docs/references/identity) | 5 | 27 | Users and accounts, organizations, positions, SCIM provisioning. |
| [Integration Protocol](/docs/references/integration) | 1 | 23 | The single connector protocol (ADR-0097) — catalog descriptors and provider-bound instances. |
| [Kernel Protocol](/docs/references/kernel) | 30 | 152 | Plugin lifecycle and manifests, capabilities and security, metadata loading, service registry. |
| [Marketplace Protocol](/docs/references/marketplace) | 4 | 30 | The package & marketplace format — package identity and versions, listing, publish, review, search, install, template manifests. |
| [Marketplace Protocol](/docs/references/marketplace) | 5 | 34 | The package & marketplace format — package identity and versions, listing, publish, review, search, install, template manifests. |
| [QA Protocol](/docs/references/qa) | 1 | 8 | Declarative test suites — scenarios, steps, actions and assertions. |
| [Security Protocol](/docs/references/security) | 6 | 37 | Permission sets, row-level security, sharing rules, tenancy posture. |
| [Shared Protocol](/docs/references/shared) | 10 | 31 | Primitives used across every protocol — identifiers, HTTP, expressions, error maps, enums. |
| [Studio Protocol](/docs/references/studio) | 3 | 35 | Studio designer metadata — the authoring surfaces for the protocols above. |
| [System Protocol](/docs/references/system) | 39 | 295 | The runtime environment — logging, jobs, cache, metrics, notifications, i18n and compliance. |
| [UI Protocol](/docs/references/ui) | 16 | 175 | Apps, pages, views, dashboards, reports, actions and themes — the ObjectUI layer. |
| **Total** | **211** | **1631** | 14 protocol modules |
| **Total** | **212** | **1635** | 14 protocol modules |

---

Expand Down Expand Up @@ -249,15 +249,16 @@ Plugin lifecycle and manifests, capabilities and security, metadata loading, ser

## Marketplace Protocol

**Source:** `packages/spec/src/marketplace/` · **Import:** `@objectstack/spec/marketplace` · **4 pages, 30 schemas**
**Source:** `packages/spec/src/marketplace/` · **Import:** `@objectstack/spec/marketplace` · **5 pages, 34 schemas**

The package & marketplace format — package identity and versions, listing, publish, review, search, install, template manifests.

| File | Schemas |
| :--- | :--- |
| [`marketplace.zod.ts`](/docs/references/marketplace/marketplace) | `ArtifactDownloadResponse`, `ArtifactReference`, `ListingStatus`, `MarketplaceCategory`, `MarketplaceInstallRequest`, `MarketplaceInstallResponse`, `MarketplaceListing`, `MarketplaceSearchRequest`, `MarketplaceSearchResponse`, `PackageSubmission`, `PricingModel`, `Publisher`, `PublisherVerification` |
| [`package.zod.ts`](/docs/references/marketplace/package) | `CreatePackageRequest`, `Package`, `PackageCategory`, `PackageLocale`, `PackagePublisher`, `PackageTranslation`, `PackageTranslations`, `PackageVisibility`, `UpdatePackageRequest` |
| [`marketplace.zod.ts`](/docs/references/marketplace/marketplace) | `ArtifactDownloadResponse`, `ArtifactReference`, `ListingStatus`, `MarketplaceInstallRequest`, `MarketplaceInstallResponse`, `MarketplaceListing`, `MarketplaceSearchRequest`, `MarketplaceSearchResponse`, `PackageSubmission`, `PricingModel`, `Publisher`, `PublisherVerification` |
| [`package.zod.ts`](/docs/references/marketplace/package) | `CreatePackageRequest`, `Package`, `PackageLocale`, `PackagePublisher`, `PackageTranslation`, `PackageTranslations`, `PackageVisibility`, `UpdatePackageRequest` |
| [`package-version.zod.ts`](/docs/references/marketplace/package-version) | `CreatePackageVersionRequest`, `PackageDependency`, `PackageManifest`, `PackageVersion`, `PackageVersionStatus`, `PublishPackageVersionRequest`, `UpdatePackageVersionRequest` |
| [`taxonomy.zod.ts`](/docs/references/marketplace/taxonomy) | `MarketplaceBusinessFunction`, `MarketplaceBusinessFunctions`, `MarketplaceIndustries`, `MarketplaceIndustry`, `MarketplaceSolutionType`, `PackageMaturity` |
| [`template-manifest.zod.ts`](/docs/references/marketplace/template-manifest) | `TemplateManifest` |

---
Expand Down
3 changes: 2 additions & 1 deletion content/docs/references/marketplace/index.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Marketplace Protocol — schema reference
navTitle: Marketplace Protocol
description: "The ObjectStack Marketplace Protocol in 4 reference pages: every schema in @objectstack/spec with its properties, types, defaults and a TypeScript example."
description: "The ObjectStack Marketplace Protocol in 5 reference pages: every schema in @objectstack/spec with its properties, types, defaults and a TypeScript example."
---

{/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */}
Expand All @@ -12,5 +12,6 @@ This section contains all protocol schemas for the marketplace layer of ObjectSt
<Card href="/docs/references/marketplace/marketplace" title="Marketplace" description="Source: packages/spec/src/marketplace/marketplace.zod.ts" />
<Card href="/docs/references/marketplace/package" title="Package" description="Source: packages/spec/src/marketplace/package.zod.ts" />
<Card href="/docs/references/marketplace/package-version" title="Package Version" description="Source: packages/spec/src/marketplace/package-version.zod.ts" />
<Card href="/docs/references/marketplace/taxonomy" title="Taxonomy" description="Source: packages/spec/src/marketplace/taxonomy.zod.ts" />
<Card href="/docs/references/marketplace/template-manifest" title="Template Manifest" description="Source: packages/spec/src/marketplace/template-manifest.zod.ts" />
</Cards>
Loading
Loading