Skip to content

Publishing

Publishing turns a package directory into a tarball and pushes it somewhere a Host can install from. The default publish target is Gitea, the Matrix-native registry; Gitea serves the npm-compatible HTTP API so existing npm/pnpm tooling Just Works against it. Local registry directories are also supported for tests and air-gapped builds.

Pages

Where Gitea fits

The registry-side description (where bytes end up, how the index is updated, channels and revocation) lives in the docs-registry Publishing section. This page is the author-facing pipeline: how mx publish runs.

ConcernThis docs packagedocs-registry
mx publish flow, dry-run, errorsyesno
Versioning, package.json disciplineyesno
Where the tarball landsnoyes
How the catalog index is updatednoyes
Revocation, promotion, dist-tagspartial (author actions)full

What mx publish does, in order

  1. Resolves cwd and registry options (packages/mx-cli/src/commands/publish.ts:88-105).
  2. Reads stored credentials. If no credential is found, throws MX_AUTH_REQUIRED. Run mx login first.
  3. Runs ensurePublishPreflight:
    • Re-validates matrix.json against the CLI validator.
    • Checks runtime.entry exists on disk.
    • Checks webapp.distDir/webapp.entry exists if a webapp block is declared.
    • Checks the package declares at least one of: root actor, a component, a webapp, or a matrix.service.json factory.
  4. Reads the version from package.json.
  5. Extracts discovery metadata (packages/mx-cli/src/utils/discovery-extractor.ts).
  6. Packs the tarball:
    • For npm-compatible registries (Gitea is one), uses packNpmPublishTarball (npm's own pack logic).
    • For local registries, uses the in-tree packCommand.
  7. If --dry-run, returns the tarball path and exits.
  8. Otherwise:
    • For npm-compatible registries, calls publishNpmTarball which shells out to npm publish against the configured registry URL.
    • For local registries, calls publishRegistryVersion to record the tarball under <registryRoot>/<packageName>/<version>/ and updates the local discovery index.

Status: target state — single manifest (P1.41). Today the publish-preflight checks honor either a matrix.service.json factory reference or a matrix.json-declared instance factory. P1.41 absorbs matrix.service.json into matrix.json. After P1.41 the preflight only checks matrix.json. See P1.41.

The two registry surfaces

Default — npm-compatible HTTP registry (Gitea behind the API)

bash
mx publish --registry https://registry.hivecast.ai/api/packages/open-matrix/npm/

Used when --registry is set or when no --registry-dir is set. Default URL is https://registry.hivecast.ai/api/packages/open-matrix/npm/ (packages/mx-cli/src/utils/config-store.ts:DEFAULT_PACKAGE_REGISTRY).

Gitea serves the npm-compatible API; from mx publish's point of view it is just an npm registry that happens to be reversible (operators can delete versions on Gitea). This is the v1 path.

Local — directory-backed registry

bash
mx publish --registry-dir /tmp/my-registry

Writes the tarball into <registry-dir>/<packageName>/<version>/ and updates <registry-dir>/index.json. No HTTP server involved. Useful for tests, air-gapped environments, and CI fixtures.

The two are mutually exclusive: --registry and --registry-dir together throw MX_REGISTRY_INVALID.

Public — npmjs.com (target state, vertical-specific)

Status: target state — vertical-specific, post-v1. The npm publish safety audit at projects/matrix-3/packages/docs/content/security/npm-publish-safety.md is mandatory prerequisite reading. Once published to npmjs.com, a version is permanent — npm does not allow deletion. The substrate's launch wedge is hivecast install gitea://... and the MCP bridge, not npmjs.com publication.

See also

Source: projects/matrix-3/packages/mx-cli/src/commands/publish.ts orchestrates the publish flow; packages/mx-cli/src/utils/npm-registry-client.ts and packages/mx-cli/src/utils/registry-store.ts implement the two registry surfaces.