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-92 → resolveOfficialPluginSourceRoot → official-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 workers → jsr:@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-plugin → jsr:@acme/cool-plugin.
Install pipeline (identical for native + external):
- Validate the URL is a real JSR package (JSR registry/meta API via
fetch; deno info/deno add
semantics).
- Validate it is a real NetScript plugin — the package must satisfy a published plugin protocol
(exported manifest / declared scaffolder bin export). Define this contract.
- 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.
- 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.)
- 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.
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.12found 0 of 4 completable. Every tutorial walls at its first official-plugin step:
Grounding (origin/main @ alpha.12) showed the published
netscript plugin add <official-kind>pathdoes 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 theproject (
add-plugin.ts:88-92→resolveOfficialPluginSourceRoot→official-plugin-source.tsrequires
packages/cli/bin/netscript.ts+plugins/*/scaffold.plugin.json). Ajsr:@netscript/cliuserland install has no such checkout, so
DEFAULT_PLUGIN_KIND_PROVIDERSships only['api']andevery official kind is rejected. The
scaffold.runtimee2e "passes" because it scaffolds inside themonorepo, 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 addbecomes a Deno-native, JSR-URL-scheme installer that is identical for first-party andthird-party plugins, and is the foundation of the NetScript marketplace.
Resolution (kind → JSR URL):
netscript plugin add workers→jsr:@netscript/…workers.(Lock the exact convention in PLAN — published names are currently
@netscript/plugin-<kind>; decidewhether
workersmaps to@netscript/plugin-workersor we adopt@netscript/<kind>.)netscript plugin add @acme/cool-plugin→jsr:@acme/cool-plugin.Install pipeline (identical for native + external):
fetch;deno info/deno addsemantics).
(exported manifest / declared scaffolder bin export). Define this contract.
(name, version, author, description, links) and ask the user to confirm it's the intended package.
Skippable with
--skip-confirmationand--ci.deno x/dx jsr:…— the plugin itself emits thescaffold 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.)
any declared post-install scripts from the plugin manifest.
Maintainer ↔ prod symmetry:
--local-path(local plugin source/bin), accepts--jsr-urltoexercise the JSR path.
--local-pathto extend a project with locally-built plugins.Enterprise-grade / Deno-native requirements (to harden in PLAN)
-A; scopeDeno permissions (e.g.
--allow-write=<projectRoot>and minimal read/net) and rely on the step-3confirmation gate for untrusted packages. This is the key security surface.
valid NetScript plugin" (scaffolder bin export, declared artifacts, post-scripts, peer/runtime deps).
fail closed.
source copy / no source leak into userland); scaffolding is produced by the dx scaffolder run.
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; flagsurface (
--jsr-url,--local-path,--skip-confirmation,--ci); kind→URL convention.@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
convention + the plugin protocol.
plugin addmechanism.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.