Deployment architecture for running AgentFlow across a multi-host Proxmox testlab with cross-user instrumentation, systemd persistence, and Open WebUI embedding.
AgentFlow is an open-source real-time visualizer for Claude Code agent sessions, created by patoles. This repo contains only the deployment configs, systemd services, hook scripts, and supporting glue written on top of it — not the AgentFlow application itself.
| Component | Description |
|---|---|
| systemd services | Boot-persistent AgentFlow relay + socat bridge, per workspace |
| Cross-user hooks | Root and hermes user instrumentation, with the EPERM liveness fix |
| Discovery writer | Auto-syncs the hermes discovery file to the live ingest port on every restart |
| Multi-workspace | Separate dashboard instances per user workspace |
AgentFlow binds an internal port and picks a fresh ephemeral ingest
port on each start. Each user workspace gets its own relay instance,
and a socat unit bridges the internal port to a stable external port.
Proxmox LXC container
┌───────────────────────────────────────────────────────────┐
│ root workspace │
│ agent-flow.service npx agent-flow-app :3001 │
│ agent-flow-bridge.service socat :3002 -> 127.0.0.1:3001│
│ │
│ hermes workspace │
│ agent-flow-hermes.service npx ... :3003 │
│ agent-flow-hermes-bridge.service socat :3004 -> :3003 │
│ │
│ ExecStartPost: agentflow-hermes-discovery │
│ - reinstalls the patched cross-user hook.js for hermes │
│ - mirrors the live root ingest port into a discovery │
│ file the hermes hook can read │
└───────────────────────────────────────────────────────────┘
:3002 (root dashboard) :3004 (hermes dashboard)
Claude Code invokes hook.js on each session/tool event. The hook
reads the discovery directory, finds live instances whose workspace
matches the current cwd, and forwards the event over HTTP to the
matching relay.
The hermes discovery file points at the root-owned AgentFlow app.
From the hermes user, process.kill(pid, 0) returns EPERM (the
process exists but isn't ours). The stock forwarder treats that as
"dead" and deletes its own discovery file, so hermes events never
forward. hooks/hook-hermes.js treats EPERM as alive and only
ESRCH (no such process) as dead. See the comment header in that file.
| Path | Purpose |
|---|---|
agent-flow.service |
root-workspace relay (port 3001) |
agent-flow-bridge.service |
socat bridge 3002 → 3001 |
agent-flow-hermes.service |
hermes-workspace relay (port 3003) |
agent-flow-hermes-bridge.service |
socat bridge 3004 → 3003 |
agentflow-hermes-discovery.sh |
ExecStartPost discovery/hook writer |
hooks/hook-root.js |
root event forwarder |
hooks/hook-hermes.js |
hermes event forwarder (EPERM-aware) |
claude-settings/settings-root.json |
Claude Code hook wiring (root) |
claude-settings/settings-hermes.json |
Claude Code hook wiring (hermes) |
- Copy
.env.exampleto.envand fill in your values. - Install the discovery writer:
install -m 0755 agentflow-hermes-discovery.sh /usr/local/bin/agentflow-hermes-discovery - Place the canonical hermes hook at
/usr/local/share/agentflow/hermes-hook.js(used by the discovery writer). - Copy the
.servicefiles to/etc/systemd/system/, thensystemctl daemon-reload && systemctl enable --now agent-flow.service agent-flow-bridge.service(and the hermes units). - Merge the
claude-settings/*.jsonhook blocks into each user's~/.claude/settings.json.
Ports, IPs, and hostnames in these files are placeholders — adjust to your environment.
- The AgentFlow app — install from patoles/agent-flow.
- The Open WebUI filter — the live-agent-panel filter runs inside a
separate, network-isolated Open WebUI container in the source
environment and is not part of this deployment bundle. If you want to
embed the dashboard in Open WebUI, point an
iframe/filter at the external bridge port (:3002/:3004).
Built on AgentFlow by patoles. Deployment glue in this repo is independent and provided as-is.