Run Monitor
The Run Monitor is the “what is happening right now” surface: a read-only, chat-like view of everything in flight — streaming agent text, tool calls resolving in place, shell commands and their output, plan updates, and gate pauses — in near-realtime.
It is non-interactive by design. It observes exactly the same event stream the canvas animates from, so it can never disagree with the canvas about what happened.

One feed for every run in flight, filterable to one.
Opening it
Section titled “Opening it”Click the running indicator in the status bar — it reads idle, ⟳ running <workflow> or
⟳ 3 running, and it is a button. Or ⌘⇧P → Monitor: Live Run Feed. It opens as a tab
like anything else, so you can leave it open beside the code an agent is editing.
What’s in the feed
Section titled “What’s in the feed”Feed items are typed — status changes, streaming model text, tool calls, shell commands, and plans — each rendered with its own affordance rather than flattened into log lines. A tool call appears when it is issued and fills in when its result arrives, so a long-running call is visibly pending rather than absent.
Every item carries its run’s workflow id, the node that produced it, and a timestamp:
| Item | Looks like | Comes from |
|---|---|---|
| Status | ▶ build-pipeline started (cron 0 2 * * *), ✓ … completed, ✕ … failed: <error> |
run.started / run.completed / run.failed |
| Text 🤖 | A bubble that grows token by token, marked streaming… until it closes |
node.delta, closed by node.completed |
| Tool ⚙ | read_file {"path":"src/index.ts"}, marked running…, then → ✓ <preview> |
tool.call patched by tool.result |
Shell $ |
$ npm test then → exit 0 and the head of the output |
shell.exec |
| Plan ▤ | ☑ scaffold ▸ implement ☐ tests |
plan.update, from the set_plan tool |
Publishes and pauses punctuate the feed as statuses too: ▦ morning-brief: 6 widget(s) published, 🗺 latchai-map: 3 view(s) published, ⏸ review waiting for review, ☑ review approved.
A node that fails closes its bubble with ✕ <error> rather than leaving it spinning, so a
run that died has a visible last word.
Two caps keep a long night from eating the tab: 600 items across all runs, and 8,000
characters per streaming bubble (it keeps the tail, prefixed with …). The full text is
always in the run log on disk.
Filtering
Section titled “Filtering”Newest runs come first in the filter, labelled with their workflow id and the tail of the run id when one is known. Selecting a run narrows the feed to it; “all” shows everything the daemon is doing at once — which, with triggers armed, is often more than one thing.
Following
Section titled “Following”The feed auto-follows the stream only while you are pinned to the bottom. Scroll up to read something and it stops fighting you; scroll back down and following resumes.
Everything shows up here
Section titled “Everything shows up here”Because dashboard and atlas
builds drive the same tool loop as workflow runs and emit the same events, they appear in
the Run Monitor too — a briefing being assembled at 7am looks like any other run, under
the workflow id dashboard:<id> or atlas:<id>. Subworkflows appear as runs of their own,
which is what makes a pipeline of pipelines legible.
Two things are deliberately absent. Chat turns are excluded — the
chat panel already renders them, in more detail. And a trigger.skipped event, which has
no run to belong to, goes to the events panel instead.
Opening mid-run
Section titled “Opening mid-run”Open the app while a cron run is halfway through and the feed is not empty. On connect, LatchAI asks the engine what is running, reads those runs’ persisted logs, and replays them through the same reducer the live socket feeds — so the monitor, the canvas and the status bar all catch up to the present. It isn’t a replay mode: this is the current run, with no “(replay)” label, and the live stream takes over from there.
Where else a run is visible
Section titled “Where else a run is visible”| Surface | What it holds |
|---|---|
| Run Monitor | Live, chat-shaped, this browser session. Clearing it empties only this view |
Events panel (⌘J) |
The raw event lines — kind, node, path, arguments — with clickable file paths. Last 200 events, streaming text excluded |
| The canvas | The same events as node status, per node, on the workflow you’re looking at |
<home>/runs/<runId>.jsonl |
The append-only truth. Every event, in order, forever |
Reporting (≣) |
Run history, transcripts and token usage across runs |
Clearing the feed is a view-level action, not a delete: history stays in Reporting and on disk.