DromioWorkflow SDK
Workflow SDKAuthoringAPIWorkflow Apps & Harnesses

Expose and operate

Workflow AppsGUI, CLI, TUI, and SVGExecution and durabilityEvents and traces

External harnesses

Architecture and setup
Expose and operate
Workflow Apps
GUI, CLI, TUI, and SVG
Execution and durability
Events and traces
External harnesses
Architecture and setup

Workflow App surfaces

All packaged surfaces accept the same workflowApp() and execute the same workflow semantics. The adapters differ in interaction and projection, not in orchestration.

Surface overview​

SurfaceEntry pointUse
CLIrunWorkflowCli()Compact execution for commands and scripts
Verbose CLIrunWorkflowCli() with --verboseFull terminal event log
TUIrunWorkflowTui()Interactive terminal application
GUIrunWorkflowGui()Executable browser canvas and inspector
SVGrunWorkflowSvg()Lighter executable graph surface
ServerrunWorkflowServer()HTTP control plane, persistence, and signal delivery
MCPcreateWorkflowControlPlaneMcpProvider()Harness discovery, triggering, inspection, and hook resume

The TUI, GUI, SVG, and bundled server currently require Bun. Bind network surfaces to loopback during development. runWorkflowServer() refuses a non-loopback bind without an auth verifier.

CLI​

await runWorkflowCli(reviewApp);
bun run cli.ts --list-workflows
bun run cli.ts "Review this response"
bun run cli.ts --workflow response-review "Review this response"
bun run cli.ts --interactive "Review and clarify this response"
bun run cli.ts --verbose "Review this response"

--interactive resolves human questions in the terminal. Without it, a run that needs input cannot be driven to completion automatically. The result uses the authored workflow's output keys. Positional arguments are joined into one prompt; --workflow overrides the app's default workflow. A non-interactive run that remains waiting returns exit code 1. Call runWorkflowCli(app, {exit: false}) when the caller needs to inspect the returned result instead of setting process.exitCode.

TUI​

import { runWorkflowTui } from "@dromio/workflow";

await runWorkflowTui(reviewApp);

The TUI selects workflows, starts runs, renders nested graph state, shows events and artifacts, and resolves pending input. If the app declares signals, it starts a loopback signal server by default; pass {signals: {listen: false}} to disable that ingress.

GUI and SVG​

const gui = await runWorkflowGui(reviewApp, {
defaultInput: "Explain workflow traces.",
hostname: "127.0.0.1",
port: 3210,
signals: {storage: {kind: "sqlite", path: "./runs.sqlite"}},
});

console.log(gui.url);
const svg = runWorkflowSvg(reviewApp, {
hostname: "127.0.0.1",
port: 3211,
});

console.log(svg.url);

Both return a server with url, hostname, port, and stop(). The GUI adds artifact inspection and signal integration; the SVG surface is a lighter graph projection. Use an OS signal handler or application shutdown hook to call stop(). runWorkflowSvg() returns synchronously after binding its Bun server; runWorkflowGui() is async because it may create a durable signal host first. GUI SQLite persistence is activated through signals.storage when the app declares signals; without signals, the GUI uses its process-local runtime.

Durable server​

const server = await runWorkflowServer(reviewApp, {
hostname: "127.0.0.1",
port: 4323,
storage: {kind: "sqlite", path: "./runs.sqlite"},
});

console.log(server.url);

The returned server also exposes controlPlane, runtime, runtimeStore, fetch(), deliverSignals(), and stop().

HTTP route map​

The server publishes the authoritative OpenAPI document at GET /api/openapi.json. Core run routes are:

Method and pathPurpose
POST /api/runsStart with {workflowId, input, runId?}
GET /api/runs/{runId}Read a run snapshot
GET /api/runs/{runId}/eventsStream server-sent events
POST /api/runs/{runId}/questions/{questionId}/answerSubmit {value}
POST /api/runs/{runId}/resumeResume after an accepted answer
POST /api/hooks/{token}/resumeDeliver a hook {value}
POST /api/signals/{signalId}/occurrencesPublish a correlated signal occurrence

Send Authorization: Bearer <token> when auth is configured. Capabilities are route-specific, such as runs.read, runs.write, and signal.publish:<signalId>.

The server exposes the Workflow App host's Fetch adapter and runs signal delivery passes. For a non-loopback host, supply auth implementing the exported token-verifier contract and place normal transport security in front of the process.

Choose a surface​

Use direct workflow.start() for libraries and tests, CLI for the smallest operator contract, TUI for terminal interaction, GUI for detailed inspection, SVG for a lighter graph UI, and the host/server APIs for durable integration. Do not put business decisions in a renderer or command parser.

GUI, TUI, CLI, and SVG are user-facing projections of a Workflow App. SDK, HTTP, and MCP are control and integration paths. They share app semantics, but they do not automatically share one live run unless they connect to the same durable host and run ID.

On this page

  • Surface overview
  • CLI
  • TUI
  • GUI
  • Choose a surface
  • Product surfaces