Skip to content

Architecture

Flowbun’s distributed topology has three layers:

  • Coordinator — the long-lived parent. Light-touch: process supervision only (spawn, restart with exponential backoff, crash-loop detection), the typecheck gate, the file watcher, and the websocket control API. It holds no Home Assistant connection.
  • Flow-host — one OS process per flow. Each opens exactly one Home Assistant connection, lazily, shared by every Worker in that flow. A crash in one flow never touches another.
  • Workers — one persistent Bun Worker per block instance, spawned once per flow-host lifetime. Workers hold no connection of their own; readEntityState()/performHassAction() calls relay to the flow-host’s single connection over a small postMessage protocol.

@hass/trigger nodes skip the Worker entirely — the flow-host subscribes them directly off the flow’s connection, like @core/scheduler’s timer.

The Router never calls block.process() directly — it delegates to a swappable NodeExecutor. The single-process demo uses an in-process executor; the real topology uses a distributed one. Same wiring format, same typecheck gate, same block code, unmodified in both.

Every hop between blocks clones the payload (structuredClone), so a block mutating its own inputs can never corrupt a sibling branch’s copy. This also meant moving to real Worker/IPC boundaries — where serialization is unavoidable — changed nothing about block-visible behavior.

The coordinator restarts a crashed flow-host with exponential backoff (500ms base, 30s cap) and flags a flow as crash-looped after more than 5 unexpected exits in a rolling 5-minute window. kill -9 a flow-host and it self-heals with state intact — state lives in SQLite, not process memory.

The editor’s chat panel talks to a Claude Agent SDK loop in a dedicated ai-host process. Its only capability surface is an MCP server whose tools relay back to the coordinator and call the same mutation functions the browser’s websocket handlers call — so an agent edit is typechecked, git-committed, and undo-tracked exactly like a human edit. Every built-in SDK tool (Bash, Read, Write, …) is disabled.