Skip to content

Registry roadmap: fill the lexicon-to-UI gap #1026

@ascorbic

Description

@ascorbic

The experimental decentralized plugin registry (#694, #1011) shipped
the install path, but the admin UI displays ~6 of the ~28 fields the
lexicons define, and the CLI takes 6 flat flags with no way to set
keywords, sections, repo, SBOM, icons, or to update an existing
profile. This umbrella tracks the work to close that gap.

Background

The lexicons (packages/registry-lexicons/lexicons/com/emdashcms/experimental/package/)
define:

  • profile.json — name, description, license, keywords, repo,
    authors[] (1–32), security[] (1–8), sections{description,
    installation, faq, changelog, security} (20KB Markdown each),
    lastUpdated.
  • release.json — version, artifacts (package + icon +
    screenshot + banner), provides, requires (env:emdash, env:astro,
    …), suggests, repo, sbom.

The admin currently renders name, description, publisher handle,
verified label, version, indexedAt, capabilities. Everything else
is in the aggregator response but never reaches the screen.

The CLI's ProfileBootstrap interface covers 6 fields (license,
authorName, authorUrl, authorEmail, securityEmail, securityUrl) and
silently drops them on subsequent publishes with a warning telling
publishers to edit the PDS by hand. Release-record fields beyond the
package artifact (provides, requires, suggests, repo, sbom, icon,
screenshot, banner) have no CLI surface at all.

Design decisions

Manifest format: emdash-plugin.jsonc

JSONC matches wrangler.jsonc / tsconfig.json precedent across
the repo, and lets us inline-document each field. CLI loads it from
repo root; --manifest <path> for explicit paths. Files referenced
via { "file": "./path" } resolve relative to the manifest.

A JSON Schema is published alongside the CLI
(@emdash-cms/registry-cli/schemas/emdash-plugin.schema.json) and at
https://emdashcms.com/schemas/emdash-plugin.schema.json. Generated
from the Zod source of truth so there's no drift. The init
scaffolder writes a $schema reference into every new
emdash-plugin.jsonc so VS Code / JetBrains light up completion and
inline validation immediately.

{
  "$schema": "https://emdashcms.com/schemas/emdash-plugin.schema.json",
  "slug": "acme-forms",
  "package": {
    "name": "Acme Forms",
    "description": "...",
    "license": "MIT",
    "keywords": ["forms", "contact"],
    "repo": "https://github.com/acme/emdash-forms",
    "authors": [{ "name": "Acme Co.", "url": "https://acme.example" }],
    "security": [{ "email": "security@acme.example" }],
    "sections": {
      "description":  { "file": "./docs/description.md" },
      "installation": "Drop into `live.config.ts` plugins array.",
      "changelog":    { "file": "./CHANGELOG.md" }
    }
  },
  "release": {
    "requires": { "env:emdash": ">=0.13.0", "env:astro": ">=4.16.0" },
    "repo": "https://github.com/acme/emdash-forms/tree/v1.2.0",
    "sbom": { "format": "cyclonedx", "file": "./build/sbom.cyclonedx.json" },
    "artifacts": {
      "icon": { "file": "./assets/icon.png" },
      "screenshot": [{ "file": "./assets/screen-1.png" }],
      "banner": { "file": "./assets/banner.png" }
    }
  }
}

Fields not in the manifest:

  • version and capabilities — read from the bundle's
    plugin.manifest.json, tied to the bytes, not authoring intent.
  • Artifact URL and checksum — derived from the tarball --url.

Image dimensions: image-size

Pure JS, no native deps, reads header bytes only. PNG / JPEG / WebP /
GIF / SVG. Sharp would be overkill for header extraction and would
add ~30MB of native deps to the CLI install.

emdash-registry init

Scaffolds a complete sandboxed-plugin starter:

  • emdash-plugin.jsonc
  • docs/{description,installation,changelog,security}.md
  • src/index.ts + src/sandbox-entry.ts (minimal: one
    plugin:activate hook + one GET /hello route, no capabilities,
    compiles and publishes clean)
  • package.json, tsconfig.json, tests/index.test.ts, README.md,
    .gitignore

Interactive prompts for slug, name, description, license, repo,
author, security contact. Subsequent runs prompt for overwrite per
file.

Plan

Ordered roughly by foundation-first, then richness. Each child issue
is one PR.

Server-side gaps from #1011 — uninstall handler, update handler, MST
proof verification, Zod schema for experimental.registry config,
test coverage for the install handler / SSRF / checksum — are tracked
in #I. MST proof verification is its own future epic; it's documented
as a known gap in ExperimentalConfig.registry JSDoc.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions