Skip to content

Marketplace foundation: Deno-native JSR-URL plugin add (dx scaffolder protocol) #167

Description

@rickylabs

Marketplace foundation — Deno-native JSR-URL plugin add (dx scaffolder protocol)

Why (motivation / evidence)

Run-2 fresh-user eye-tests of all four published tutorials on jsr:@netscript/cli@0.0.1-alpha.12
found 0 of 4 completable. Every tutorial walls at its first official-plugin step:

Unsupported plugin kind … Supported kinds: api (exit 246)

Grounding (origin/main @ alpha.12) showed the published netscript plugin add <official-kind> path
does not exist for a real userland install. Official kinds (auth/workers/sagas/triggers/
streams) are registered only when the CLI discovers a NetScript monorepo checkout above the
project
(add-plugin.ts:88-92resolveOfficialPluginSourceRootofficial-plugin-source.ts
requires packages/cli/bin/netscript.ts + plugins/*/scaffold.plugin.json). A jsr:@netscript/cli
userland install has no such checkout, so DEFAULT_PLUGIN_KIND_PROVIDERS ships only ['api'] and
every official kind is rejected. The scaffold.runtime e2e "passes" because it scaffolds inside the
monorepo
, so the walk-up finds the real checkout — the true userland-JSR install path is untested
and unbuilt
. (Supersedes the false "prod/JSR plugin add is already correct, thin stubs" assumption.)

What — the design

plugin add becomes a Deno-native, JSR-URL-scheme installer that is identical for first-party and
third-party plugins, and is the foundation of the NetScript marketplace.

Resolution (kind → JSR URL):

  • Bare name → NetScript-scoped JSR package, e.g. netscript plugin add workersjsr:@netscript/…workers.
    (Lock the exact convention in PLAN — published names are currently @netscript/plugin-<kind>; decide
    whether workers maps to @netscript/plugin-workers or we adopt @netscript/<kind>.)
  • Scoped name → that JSR package as-is, e.g. netscript plugin add @acme/cool-pluginjsr:@acme/cool-plugin.

Install pipeline (identical for native + external):

  1. Validate the URL is a real JSR package (JSR registry/meta API via fetch; deno info/deno add
    semantics).
  2. Validate it is a real NetScript plugin — the package must satisfy a published plugin protocol
    (exported manifest / declared scaffolder bin export). Define this contract.
  3. External-package confirmation — for non-netscript-native packages, extract JSR metadata
    (name, version, author, description, links) and ask the user to confirm it's the intended package.
    Skippable with --skip-confirmation and --ci.
  4. Run the plugin's own scaffolder via deno x / dx jsr:… — the plugin itself emits the
    scaffold artifacts it needs (e.g. auth → database/auth.prisma + auth-api service + /api/v1/auth/*
    routes; sagas/streams → runtime resource). No CLI-embedded templates, no static descriptors — the
    plugin owns its scaffolding. (This makes ANY third-party plugin installable the same way.)
  5. Integrity + verification — verify the produced output (expected artifacts / checksums) and run
    any declared post-install scripts from the plugin manifest.

Maintainer ↔ prod symmetry:

  • Maintainer mode defaults to --local-path (local plugin source/bin), accepts --jsr-url to
    exercise the JSR path.
  • Prod CLI defaults to JSR, accepts --local-path to extend a project with locally-built plugins.

Enterprise-grade / Deno-native requirements (to harden in PLAN)

  • Permission model for running an external plugin's scaffolder binary — do NOT blanket -A; scope
    Deno permissions (e.g. --allow-write=<projectRoot> and minimal read/net) and rely on the step-3
    confirmation gate for untrusted packages. This is the key security surface.
  • Plugin protocol/manifest contract — the published, versioned shape that makes a JSR package "a
    valid NetScript plugin" (scaffolder bin export, declared artifacts, post-scripts, peer/runtime deps).
  • Integrity — verify scaffolder output is what the manifest promised before declaring success;
    fail closed.
  • Runtime vs scaffold split — userland depends on the plugin's runtime off JSR (thin import, no
    source copy / no source leak into userland); scaffolding is produced by the dx scaffolder run.
  • e2e-cli-prod must exercise a TRUE userland install (outside any monorepo checkout) of at least
    one official kind, so this entire class can never regress (the current e2e blind spot).

Scope / blast radius

  • packages/cli — new resolver + install pipeline + permission/confirmation/integrity layers; flag
    surface (--jsr-url, --local-path, --skip-confirmation, --ci); kind→URL convention.
  • The five @netscript/plugin-* packages — each must ship a dx-runnable scaffolder bin + manifest
    (framework-source change → WSL Codex per doctrine).
  • e2e-cli-prod — add true-userland official-plugin install coverage.

Relationships

Process

Harness-gated: research → plan → PLAN-EVAL (OpenHands minimax-M3, separate session) → WSL Codex
daemon-attached implementation slices → adversarial review → IMPL-EVAL (OpenHands qwen3.7-max)
merge → cut alpha.13 → re-run the 4 eye-tests. Then this becomes the spine the marketplace builds on.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions