Skip to content

Studio

The visual companion. Vue 3 + Vite + VueFlow. Reads Nwire primitives natively — no instrumentation, no agents.

bash
pnpm dlx @nwire/studio        # or `pnpm dev` in packages/nwire-studio/

Open http://localhost:7777.

Studio Home

Every screenshot below is captured live from examples/moderation-queue — what you see is exactly what Studio renders against a freshly scanned .nwire/manifest.json.

What's in Studio

The nav is grouped into three surfaces — Map (the system in motion), Run (operate it), Inspect (browse the static surface).

GroupPageWhat it shows
ProjectsCatalog of every workspace Studio has ever opened.
HomePer-project dashboard: recent failures, boot summary, composition stats.
MapTopologyApps as nodes, plugins listed inline, outbound sinks visible, cross-app event flows as edges.
MapTraceCausal tree per correlationId. Click an event → walk its parents and children.
MapStreamLive event firehose via SSE.
RunTryForm-from-schema: pick any action, fire it with JSON scaffolded from its zod schema.
RunProcessesPick a process, click Start, stdout streams in the page.
RunCommandsThe please CLI surface — operator scripts and registered actions/queries.
RunWorkflowsWorkflow defs + which events they subscribe to and which actions they dispatch.
InspectAppsEvery App with its plugin stack, primitive counts, and outbound sinks.
InspectActionsSearchable list + detail panel: schema, retry/policy badges, persona, journey, SLO.
InspectEventsCatalog with public/internal indicator, per-event flow (producer → consumers).
InspectProjectionsCQRS read models — each fold with the events it listens to.
InspectQueriesRead endpoints — projection-backed or direct-handler.
InspectSinksOutbound delivery chain — every stage by position (early / middle / terminal).
InspectPluginsInstalled plugins per app — bundle-mode forge, sub-plugins, custom.
InspectHooksEvery materialised framework hook slot and its chain length.

Map — the system in motion

Topology — apps as nodes, plugins listed inside, outbound sinks visible. Edges are cross-app event flows.

Topology

Trace — causal tree per correlationId. Click an event, walk its parents and children.

Trace

Stream — live event firehose via SSE.

Stream

Run — operate the system

Try — form-from-schema. Pick any action, fire it with JSON scaffolded from its Zod schema.

Every fire is a POST /_nwire/dispatch against the running wire — the same dispatch contract MCP's dispatch_action speaks. Errors come back coded, not raw: a zod-invalid input renders validation_failed with the failing field, an unknown name action_not_found, and a handler throw an opaque internal_error unless the wire runs with exposeErrors. The optional user-id / tenant fields thread into the handler's envelope, so you can exercise an action as a specific caller.

Try

Processes — start dev with custom port + env vars, stream stdout, recognise processes started in another terminal (via .nwire/processes/*.json).

Processes

Commands — the please CLI surface — operator scripts and registered actions / queries.

Commands

Workflows — workflow defs with subscribed events and dispatched actions.

Workflows

Inspect — browse the surface

Apps — every App with its plugin stack, primitive counts, and outbound sinks.

Apps

Actions — searchable list + detail panel: input schema, persona, journey, source link.

Actions

Events — catalog with the .public() gate badge + per-event producer/consumer flow.

Events

Projections — CQRS read models. Each fold with the events it listens to, cross-linked to the queries reading it.

Projections

Queries — read endpoints — projection-backed or direct-handler.

Queries

Sinks — outbound delivery chain — every stage by position (early / middle / terminal). Empty when no outbound adapter is installed.

Sinks

Plugins — installed plugins per app — bundle-mode forge, sub-plugins, custom.

Plugins

Hooks — every materialised framework hook slot and its chain length. The core LocalDelivery chain is where forge attaches at fixed priority slots (idempotency 1000, actors 800, projections 600, workflows 400).

Hooks

Data sources

Studio reads from two places:

  1. .nwire/manifest.json — built by nwire cache, gives every primitive's static metadata (persona, SLO, schema, etc.)
  2. /_nwire/* — runtime introspection from the wire's httpKoa({ inspect: true }) endpoints

The dynamic /_nwire/* proxy in Studio's Vite middleware routes requests to the most-recently-started managed process (or the default NWIRE_INSPECT_URL if no process is up).

Play Trace

The flagship DX feature. Fetches /_nwire/telemetry/recent, groups by correlationId, walks each story chronologically, lights up the matching sticky on the EventStorm canvas with an amber glow. 1×/2×/4×/8× playback speed. Distinct correlations get a pause between them so different stories feel separated.

Studio-as-runner

nwire studio                  # boots Studio's Vite dev server + supervisor

Inside Studio, the Run page lets you:

  1. Pick a topology from apps/topologies/*.topology.ts
  2. Pick a port (defaults 3000)
  3. Click Start — the supervisor spawns pnpm exec vite-node apps/run.ts with NWIRE_TOPOLOGY=<name> + PORT=<port>
  4. Health check polls /_nwire/manifest until the wire is ready
  5. Stdout / stderr stream live via SSE
  6. The dynamic proxy auto-routes Studio's /_nwire/* calls at the new process
  7. Live / Dispatch / EventStorm all light up automatically

No separate terminal. The same Studio sees your code, your live traces, and the running process.

OSS / Cloud split

FeatureLocal OSSHosted Cloud (later)
Live event stream✓ + retained history
Actor / projection browser✓ + multi-deploy
EventStorm canvas✓ + collaboration + sync to code
Dispatch UI
Run / process supervisor✓ + Cloud-managed processes
Distributed traces✓ (single process)✓ + cross-service correlation
Multi-environment✓ (dev / staging / prod)
Team / sharing
Alerts
AI debug

OSS = the local experience. Cloud = persistence, multi-deploy, team features. Same UI, same concepts, same muscle memory.

See also

MIT licensed.