Monitor App
The Monitor App is a built-in web interface for interacting with the workflow engine during development. It provides a real-time view of workflow definitions, executions, jobs, and registered workers.
Integration roadmap
The Monitor App runs on the Neops Web Client’s session and has no sign-in of its own.
Set WEBCLIENT_ORIGIN on the container to the web client’s exact origin; with it unset the
app reports that it has no session. The app calls the engine from the browser, so its own
origin has to be listed in the engine’s NEOPS_CORS_ORIGINS. Its functionality will be
integrated into the web client in a future release. For now, it is the primary UI for
workflow management and execution monitoring.
Deployment
The container image serves the static build with nginx and reads three environment variables at
start (rest/monitor-app/docker-entrypoint.d/40-runtime-config.sh). All three are rendered into
/config.js, which the page loads before the app bundle, so no rebuild is needed to change them.
| Variable | Meaning |
|---|---|
ENGINE_BASE_URL |
Browser-facing base URL of the engine, e.g. https://engine.example.com. Unset: the compile-time default. |
WEBCLIENT_ORIGIN |
Exact origin of the Neops Web Client the app takes its session from. Unset: no session. |
MONITOR_BASE_PATH |
Path prefix the app is published under, e.g. /workflows. Unset: the origin root. |
Session modes
How the app obtains an access token depends on where it is served relative to WEBCLIENT_ORIGIN.
The two are compared as origins, and the mode is chosen once per page load
(rest/monitor-app/src/lib/auth/token-provider.ts).
- Another origin (host relay). The app is opened from the web client, in an iframe or a popup,
and asks the host window for a token over
postMessage. The host answers with the bare JWT and its expiry, the app asks again ahead of expiry and on a401, and a logout in the web client is relayed as a message. Opened directly, with no host window, the app has no session. - The web client’s own origin (shared session). Served from the same origin, for instance under
https://neops.example.com/workflows, the app reads the web SDK’s access token straight from the sharedlocalStoragekeytokenand follows thestorageevent for that key, so a refresh or a logout in any web client tab reaches it. The refresh token is never read, and the key is never written: the SDK’s cross-tab logout listens on it. Without a token the app asks the user to sign in to the web client and picks the session up as soon as that happens.
Base path
SvelteKit fixes its base path at build time, and the image is built once. MONITOR_BASE_PATH
therefore works on the served HTML instead: the reverse proxy in front strips the prefix, nginx
keeps serving from /, and at container start the entrypoint rewrites every .html file of the
build so the browser requests <prefix>/_app/..., <prefix>/config.js and <prefix>/favicon.svg
and the SvelteKit runtime base carries the prefix. The rewrite always starts from pristine copies
taken at image build (/html.template/), so a restart with a different value cannot stack
prefixes, and the value is validated as one or more /segment parts from [A-Za-z0-9._~-] with
no trailing slash and no . or .. segment.
The rewrite is tied to SvelteKit’s HTML output
The entrypoint uses sed with a fixed set of patterns: href="/_app/, import("/_app/,
href="/favicon.svg", src="/config.js" and a line that is exactly base: "" inside the
inline __sveltekit_<hash> script. The client bundle reads base from that global at
runtime, which is what makes the rewrite reach $app/paths and the router. Nothing in CI
checks this, so after a SvelteKit or adapter upgrade compare a built build/index.html with
those patterns and run the image with MONITOR_BASE_PATH=/workflows before releasing.
What You Can Do
- Browse workflow definitions – See all registered workflows with their versions, steps, and schemas
- Trigger executions – Execute workflows with custom parameters and entity scopes
- Monitor executions – Watch execution state transitions in real time (NEW → RUNNING → COMPLETED)
- Inspect jobs – See which jobs are pending, polled, or completed, and which worker handled each job
- View workers – See online workers and their registered function blocks
Quick Start
Follow the Quick Start to start PostgreSQL, the Monitor App, and the engine. Then open http://localhost:5173 in your browser.
- Ensure the workflow engine is running (see Setup)
-
Start the Monitor App:
Or directly:
-
Open http://localhost:5173 in your browser
Key Screens
Workflow Definitions
Lists all registered workflow definitions. From here you can:
- View the full YAML definition of each workflow
- See the version history
- Deploy new workflow definitions
- Trigger an execution directly
Executions
The execution view shows all workflow executions with their current state. Click an execution to see:
- The current state in the lifecycle (with color coding)
- Individual jobs and their status per device
- Step-by-step progress
- Error details for failed steps
- DB updates that will be applied
Workers
Shows all registered workers with their status (online, unreachable, offline) and which function blocks each worker provides. Useful for debugging when jobs are not being picked up.
Importing Workflows
The Monitor App accepts workflow definitions in JSON format. Since we recommend authoring workflows in YAML for readability, convert before importing:
Paste the raw workflow JSON into the Monitor App’s definition editor — the app handles the API wrapping automatically.
Quick conversion alternatives
yq(recommended):yq -o=json < workflow.yaml– install viabrew install yqor see github.com/mikefarah/yq- Online: json2yaml.com converts both directions
- Python:
python -c "import yaml, json, sys; json.dump(yaml.safe_load(sys.stdin), sys.stdout, indent=2)" < workflow.yaml
Technology
The Monitor App is built with Svelte and communicates with the engine
via browser-side HTTP requests to the REST API (defaulting to http://localhost:3030,
configurable in the app’s Settings page). When started via Docker Compose, it runs as a static
production build served by nginx. For local development (make run-monitor), it runs as a Vite
dev server with hot-reload.
Next: Your First Workflow – deploy and execute a workflow end to end.

