Skip to main content
Fabro provides two interfaces — a CLI for local development and an HTTP API for production use. Both submit runs to the same server, and every run executes on the same engine.

The engine

Every run executes on Petri, the workflow engine. At create time the server hands Petri the workflow bundle and the run’s settings; Petri lowers the Graphviz graph, checks it, pins the models its nodes name, and either admits the graph or refuses the run with its diagnostics. At execution a worker process runs the admitted graph: it walks the nodes, dispatches each stage (agent, command, human, etc.), selects edges, and records every step in the run’s log, from which the run resumes after an interruption. Human-in-the-loop questions reach the server’s questions API; the CLI answers them from the terminal, the web app from the run page.

CLI mode

The CLI builds the run manifest, submits it to the server (starting a local one when none is running), and follows the run: events are printed to stderr, progress is shown with terminal indicators, and human-in-the-loop questions are answered via interactive terminal prompts. When the run finishes, the process exits. CLI mode is ideal for:
  • Local development and iteration on workflows
  • One-off runs and debugging
  • Scripting and CI/CD pipelines

API mode

fabro server start starts an HTTP server, binding to ~/.fabro/fabro.sock by default (or plain TCP when configured), with persistent run storage. Runs are submitted via the REST API and executed asynchronously. Public HTTPS, when needed, is terminated upstream by a reverse proxy or platform ingress.

Configuration

The server reads ~/.fabro/settings.toml for default settings (model, sandbox, variables, authentication). This file is live-reloaded — changes take effect within seconds without restarting the server. Key server config options:

Run lifecycle

  1. Submit — Register immutable workflow content with POST /api/v1/workflow-versions, then submit POST /api/v1/runs with its workflow_version_id and an explicit target. The run is created with status submitted and the response returns immediately with the run ID.
  2. Start request — POST /api/v1/runs/{id}/start moves normal runs to runnable. Parent-generated child runs may move to pending with approval_required.
  3. Approve if needed — POST /api/v1/runs/{id}/approve moves an approval-gated run to runnable; deny fails it with approval_denied.
  4. Schedule — A background scheduler promotes runnable runs to running in FIFO order, up to the concurrency limit.
  5. Execute — A worker runs the admitted graph on Petri, streaming events to all subscribers.
  6. Complete — The run transitions to succeeded, failed, or dead.

Event streaming

The API streams run events via Server-Sent Events (SSE). Every significant action — stage starts, LLM calls, tool invocations, edge selections — is emitted as a structured JSON event. The web UI uses this endpoint for real-time run monitoring. Any HTTP client that supports SSE can subscribe. See the run events endpoint in the API reference.

Human-in-the-loop

In API mode, human-in-the-loop questions are served over HTTP instead of terminal prompts. The engine blocks the current stage until an answer is received, then continues execution. See the list questions and submit answer API reference pages.

Authentication

API mode supports two bootstrap auth methods, configurable in settings.toml:
  • dev-token — Bearer token access for operators and automation
  • github — GitHub OAuth for browser users, resulting in a session cookie

Demo mode

Demo mode is per-request: send the X-Fabro-Demo: 1 HTTP header to get static mock data with authentication disabled. The web UI sends this header automatically when configured with FABRO_DEMO=1. This lets you explore the UI without API keys or real workflow execution.

Web UI

The web UI is a React app (apps/fabro-web) that connects to the API server. Start it alongside fabro server start:
The UI provides:
  • Run board — List and monitor all runs
  • Run detail — Real-time stage progress, event stream, diffs, usage stats
  • Start new run — Submit a Graphviz workflow from the browser
  • Human-in-the-loop — Answer agent questions through the web interface
  • Sessions — Interactive chat interface (coming soon)
  • Insights — SQL-based analysis across runs via DuckDB

Comparison

See Deployment for where the Fabro server runs and the trade-offs between local and self-hosted modes.