Build @netscript/plugin-ai — the thin manifest, connector, and scaffold layer that wires @netscript/ai into a NetScript project with an in-process default topology.
Context
Part of epic #238 · cluster plugin-ai · wave v1-min · depends-on P1, E1, E2, E3, E4, E5, FA0, FA1, FA2, FB0.
This is the terminal integration slice for the v1-min wave: every core primitive (E1-E5), the streams proxy fix (FA0-FA2), and the fresh-ui ai collection (FB0) must exist before the plugin can scaffold a working chat route against them. It sits at the bottom of the DAG on purpose — it is the slice a user actually runs (plugin add ai).
Problem / motivation
Today there is no plugins/ai manifest at all; eis-chat wires @netscript/ai-shaped functionality by hand-rolling provider calls, token counting, and a chat route directly in userland, with no typed scaffold and no contract version negotiation. This repeats the exact anti-pattern the auth plugin split was built to eliminate: business logic and provider wiring living in the app instead of behind a thin, versioned manifest. Per the plugin-thinness law, plugins/ai must stay a manifest + connector + scaffolder — no runtime AI logic — with @netscript/ai and its subpath adapters (P1) doing the actual work.
Scope
Ships
plugins/ai/mod.ts — manifest built via
definePlugin('ai', ...).withRuntimeConfigTopics(['ai']).withContractVersions(...).build()
(no default service, matching the workers reference — the plugin exposes scaffolders and
runtime-config wiring, not a running service).
plugins/ai/deno.json, scaffold.plugin.json, scaffold.runtime.json following the
plugins/workers / plugins/sagas shape.
plugins/ai/src/scaffolding/ — ItemScaffolders (mirroring
plugins/workers/src/scaffolding/*-scaffolders.ts):
- typed barrel (
ai.ts re-exporting the configured @netscript/ai client/ports)
models.ts starter (provider + model id constants)
- chat route stub (TanStack-consuming, matching the fresh-ui
ai collection primitives from
FB0)
- stream-proxy stub (in-process call into
@netscript/ai, not a network gateway hop)
- tool stub and agent stub (thin wrappers over the E-series ports)
- Conditional scaffolders gated by scaffold flags:
--mcp (emits an SkillLoaderPort-consuming
MCP tool stub) and --persist-threads (emits thread-persistence wiring, app-owned per the
MemoryPort-deferred decision — no bundled store).
- Default topology: in-process (direct
@netscript/ai calls from the scaffolded route); no
network hop, no gateway config emitted by default.
Out of scope
- Gateway topology /
--gateway flag and any network-hop proxy config — deferred to a later
gateway-focused slice (post v1-min, per the ratified in-process-default decision).
- A registry/marketplace target for
plugin-ai scaffolds — owned by the marketplace
plugin-install slice, not this issue.
- The core provider adapters, ports, and contracts themselves (
@netscript/ai,
@netscript/ai/anthropic, usage/OTel/skill-loader ports) — owned by P1 and E1-E5.
- The streams gzip/proxy fix and fresh-ui
ai collection registration — owned by FA0-FA2 and FB0
respectively; this slice only consumes their shipped surface.
Public surface
plugins/ai/mod.ts exports: aiPlugin (the built manifest) and an AiPluginInspection /
AiPluginManifest-style type set, matching the workersPlugin / WorkersPluginManifest
naming convention in plugins/workers/mod.ts.
plugins/ai/src/scaffolding/mod.ts re-exporting the ItemScaffolder set (barrel, models,
chat-route, stream-proxy, tool, agent, and the conditional mcp/persist-threads scaffolders).
plugins/ai/scaffold.plugin.json declaring the scaffold flags (--mcp,
--persist-threads) and the emitted item list.
Acceptance & fitness gates
Dependencies
Depends on P1, E1, E2, E3, E4, E5, FA0, FA1, FA2, FB0 (GitHub numbers tracked in the #238 DAG
checklist). Blocked by #239 (FA0/FA2 anchor bug) via the FA0/FA2 dependency chain.
Size
L
Build
@netscript/plugin-ai— the thin manifest, connector, and scaffold layer that wires@netscript/aiinto a NetScript project with an in-process default topology.Context
Part of epic #238 · cluster plugin-ai · wave v1-min · depends-on P1, E1, E2, E3, E4, E5, FA0, FA1, FA2, FB0.
This is the terminal integration slice for the v1-min wave: every core primitive (E1-E5), the streams proxy fix (FA0-FA2), and the fresh-ui
aicollection (FB0) must exist before the plugin can scaffold a working chat route against them. It sits at the bottom of the DAG on purpose — it is the slice a user actually runs (plugin add ai).Problem / motivation
Today there is no
plugins/aimanifest at all; eis-chat wires@netscript/ai-shaped functionality by hand-rolling provider calls, token counting, and a chat route directly in userland, with no typed scaffold and no contract version negotiation. This repeats the exact anti-pattern the auth plugin split was built to eliminate: business logic and provider wiring living in the app instead of behind a thin, versioned manifest. Per the plugin-thinness law,plugins/aimust stay a manifest + connector + scaffolder — no runtime AI logic — with@netscript/aiand its subpath adapters (P1) doing the actual work.Scope
Ships
plugins/ai/mod.ts— manifest built viadefinePlugin('ai', ...).withRuntimeConfigTopics(['ai']).withContractVersions(...).build()(no default
service, matching the workers reference — the plugin exposes scaffolders andruntime-config wiring, not a running service).
plugins/ai/deno.json,scaffold.plugin.json,scaffold.runtime.jsonfollowing theplugins/workers/plugins/sagasshape.plugins/ai/src/scaffolding/—ItemScaffolders (mirroringplugins/workers/src/scaffolding/*-scaffolders.ts):ai.tsre-exporting the configured@netscript/aiclient/ports)models.tsstarter (provider + model id constants)aicollection primitives fromFB0)
@netscript/ai, not a network gateway hop)--mcp(emits anSkillLoaderPort-consumingMCP tool stub) and
--persist-threads(emits thread-persistence wiring, app-owned per theMemoryPort-deferred decision — no bundled store).
@netscript/aicalls from the scaffolded route); nonetwork hop, no gateway config emitted by default.
Out of scope
--gatewayflag and any network-hop proxy config — deferred to a latergateway-focused slice (post v1-min, per the ratified in-process-default decision).
plugin-aiscaffolds — owned by the marketplaceplugin-install slice, not this issue.
@netscript/ai,@netscript/ai/anthropic, usage/OTel/skill-loader ports) — owned by P1 and E1-E5.aicollection registration — owned by FA0-FA2 and FB0respectively; this slice only consumes their shipped surface.
Public surface
plugins/ai/mod.tsexports:aiPlugin(the built manifest) and anAiPluginInspection/AiPluginManifest-style type set, matching theworkersPlugin/WorkersPluginManifestnaming convention in
plugins/workers/mod.ts.plugins/ai/src/scaffolding/mod.tsre-exporting theItemScaffolderset (barrel, models,chat-route, stream-proxy, tool, agent, and the conditional mcp/persist-threads scaffolders).
plugins/ai/scaffold.plugin.jsondeclaring the scaffold flags (--mcp,--persist-threads) and the emitted item list.Acceptance & fitness gates
plugins/aidepends only on@netscript/plugin,@netscript/ai(and its subpaths), and
@netscript/runtime-config; no reverse dependency from core intothe plugin (
deno task arch:check).plugins/ai/mod.tscarries@moduleJSDoc and stays within the <=20-export cap.deno task publish:dry-runWITHOUT--allow-slow-types.AbortSignal/stop()per the runtime-declaration gate.
deno task check(with--unstable-kvwhere workspace code is touched) is green forplugins/ai.scaffold.runtimecase that adds theaiplugin to a scaffolded project,runs its scaffolders (default topology plus
--mcpand--persist-threadsvariants), andtype-checks the generated workspace end to end.
netscript plugin add airesolves against local-source, and the generated chat routecompiles against the fresh-ui
aicollection primitives shipped in FB0.this slice.
Dependencies
Depends on P1, E1, E2, E3, E4, E5, FA0, FA1, FA2, FB0 (GitHub numbers tracked in the #238 DAG
checklist). Blocked by #239 (FA0/FA2 anchor bug) via the FA0/FA2 dependency chain.
Size
L