Files
platform/docs/marketplace-todo.md
T
pastilhasandClaude Opus 5 23f2ecb950 todo: the marketplace's deferred work, ranked
Split out of docs/marketplace.md so the design document stays about how it works.
Ranked by what blocks something rather than by size: submissions first (until a
stranger's manifest can be read without executing it, the catalogue is ours only
and everything below is cosmetic), then plugin upgrades not migrating, then
staleness, then scale.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-16 11:13:00 +00:00

3.9 KiB

Marketplace — deferred work

What marketplace.officer.dev and the plugin install path do not do yet, as of 2026-08-16. Design and rationale live in docs/marketplace.md; this is the list.

Ranked by what actually blocks something.

Blocks other people using it

  • Third-party submissions cannot use the sync. scripts/marketplace-sync.ts reads a manifest by IMPORTING it, which is code execution. Fine for our own repositories, not a mechanism a stranger's plugin can go through. Needs either a sandbox or a published manifest.json alongside the TypeScript one. Until this exists the catalogue is ours only, and everything below is cosmetic.

  • No write API and no submission flow. Registering a plugin means running the sync by hand against the database. Deliberate while nobody can submit; the first outside contributor makes it the gap.

Blocks a plugin evolving

  • Plugin installs CREATE, they do not MIGRATE. pushPluginSchema generates the SQL that builds a schema from nothing and applies it, skipping objects that already exist. A new version that adds a column will not get it — the CREATE is skipped as "already exists" and the column is silently absent. Plugin upgrades need real migrations. The old global db:push appeared to handle this, at the price of being able to drop half the database, so this is a known trade rather than a regression.

  • No versions table. plugin_metadata is one row per plugin — a snapshot, not a history. A store that can offer "install 1.2 instead of 1.3", or show a changelog, needs a different shape.

Staleness

  • Nothing refreshes the catalogue automatically. Publishing a plugin update changes nothing until somebody runs bun --env-file=.env scripts/marketplace-sync.ts. A Gitea webhook or a cron is the obvious next step.

  • The sync reads local clones, not the remotes. The machine running it must have every plugin checked out, so the catalogue describes that machine's copies. The version that clones each repo into a temp directory is a small change.

  • rawUrl() assumes Gitea and a main branch. A GitHub-hosted plugin, or one whose default branch is master, gets a 404 for its icon. The forge belongs in the registry rather than inferred from a URL shape.

Scale

  • fetchCatalogue() fetches everything, every time. ~737 bytes per entry, so 100 plugins ≈ 72KB and 1,000 ≈ 720KB. Correct at three; the fix at that size is search rather than pagination, and search is a server-side query that changes the shape anyway — so this is deliberately not built early. The seam is fetchCatalogue() itself, which already returns a promise with three fallback paths behind it.

  • The platform fetches the whole catalogue to answer "what can I install", then discards everything already on disk. Fine at three, wasteful at 300. Moving that filter server-side means the platform telling the store what it has, which would be the first data sent TO the marketplace — worth doing deliberately rather than by accident.

  • No search, no categories, no install counts. Three plugins do not need them.

Smaller

  • A plugin's own icon is invisible before install. assets/ is published to public/plugins/<app>/ on mount, which only happens once it is installed; the catalogue's iconUrl works around it by pointing at the repository, and a plugin author has to know to add one.

  • git, pm2 and sudo are still PATH lookups in the install path. They work on both machines we have, and bunx did not — see dc420ba5. Anything new should follow pushPluginSchema's pattern of resolving a path rather than trusting $PATH.

  • Uninstall leaves the ecosystem file's PM2 entry removed but the process's logs behind. Harmless, unexamined.