← Back to Blog
|5 min read|tech

Building an Agent Orchestration Platform on a Raspberry Pi

How I turned a Raspberry Pi 5 running Debian Bookworm into a full agent orchestration platform with real-time kanban, WebSocket state sync, and dependency chains -- all on 16GB of RAM with Bun, Hono, xterm.js, Supabase, and Cloudflare Tunnel.


This post was automatically generated by Claude (Opus 4.6) as part of an automated weekly engineering report. The content describes work completed during the week of March 24-28, 2026.

From Web Terminal to Command Center

OptimalOS started as a web terminal -- a way to SSH into my Pi from a browser. It worked, but it was just a terminal with extra steps. This week it became something else entirely.

I rebuilt the core into an orchestration hub: a command center that manages AI agent sessions, tracks task state, and gives me a single pane of glass for everything running on the Pi. The inspiration came from studying Cline Kanban's architecture, an open-source agent orchestration UI. I liked the paradigm -- agents as managed work units with lifecycle states -- but I wanted it running on my own metal, integrated with my own toolchain.

The result is a kanban board baked into OptimalOS that manages agent sessions across Claude Code, OpenClaw, and plain shell tasks. Queued, Active, Review -- three columns, each representing a real agent lifecycle stage.

The Terminal That Actually Works

Before any of the orchestration work, I had to fix the terminal itself. Two bugs had been driving me crazy for weeks.

First: click-to-focus was broken. You'd click on a terminal tab and nothing would happen. The culprit was a WebGL canvas overlay from xterm.js's GPU-accelerated renderer sitting on top of the actual terminal element, swallowing pointer events. The fix was surgical -- adjusting the z-index stacking so the interactive layer sat above the render layer.

Second: scroll was completely busted for the same reason. The WebGL canvas was intercepting scroll events before they reached the terminal buffer.

I also added keyboard shortcuts -- Ctrl+1 through Ctrl+9 for instant tab switching. These are the kinds of changes that don't show up in a changelog but completely change how it feels to use the tool every day.

The 5-Phase Orchestration Build

The orchestration system came together in five distinct phases over about four days:

Phase 1: Hook Ingest. Agents need a way to report their state back to the server. I built an HTTP endpoint that accepts structured status updates -- task ID, phase, progress percentage, stdout/stderr snapshots. Any agent that can make an HTTP POST can participate.

Phase 2: WebSocket State Hub. Raw state updates are noisy. I built a WebSocket layer powered by Hono that batches state deltas every 150ms and fans them out to connected dashboards. This means the UI stays responsive even when multiple agents are hammering the ingest endpoint simultaneously.

Phase 3: Kanban Board. Three columns: Queued, Active, and Review. Each card represents an agent task with real-time status indicators. Built with vanilla DOM manipulation on the client side -- no React, no framework overhead. The Catppuccin Mocha color palette keeps it easy on the eyes during late-night sessions.

Phase 4: Agent Launcher. A unified interface for spawning agents. Select a type (Claude Code, OpenClaw gateway, or shell), define the task parameters, and launch. The launcher handles PTY allocation via Bun's native subprocess API and wires up the hook ingest automatically.

Phase 5: Dependency Chains. This is where it gets interesting. You can define that Task B depends on Task A. When A moves to "Review" (or completes), B auto-promotes from "Queued" to "Active" and launches. It's a poor man's DAG executor, but it works and it's mine.

The whole stack runs on Bun + Hono on the server side, with xterm.js terminals on the client, all tunneled to the public internet through Cloudflare Tunnel. Supabase handles persistent state so nothing is lost if the Pi reboots.

ReturnPro: Finding the Invisible 46.9%

The orchestration work was the headline, but ReturnPro got a major analytics upgrade too.

I added ratio KPIs to the variance monitor -- COGs%, Commission%, and Gross Margin% -- with per-master-program breakdowns and month-over-month color coding. Green for improving margins, red for deteriorating ones. The kind of dashboard that makes a CFO's morning easier.

But the real win was a bug fix. I discovered that 46.9% of our budget projections were completely invisible in the variance reports. The root cause: override-only programs -- programs that exist in the budget but have no matching GL account mapping -- were being silently dropped during the FK resolution step. Nearly half the data, just gone. No error, no warning.

The fix was straightforward once diagnosed: fall back to the override mapping when the primary GL lookup returns null. But finding it required tracing the entire data pipeline from NetSuite extract through Solution7 formula caching to Supabase staging tables. That's the kind of bug that lives in the seam between systems.

Infrastructure Hygiene

Not glamorous, but necessary. This week's maintenance:

  • Killed an orphan n8n process that was consuming memory after a failed systemd restart
  • Fixed the n8n systemd unit's restart policy so it recovers cleanly on failure
  • Cleaned up stale Vercel deployments from abandoned preview branches
  • Pushed everything to GitHub -- OptimalOS, optimal-cli, ReturnPro dashboard, this portfolio

Running your own infrastructure means being your own SRE. The Pi is forgiving in some ways (low power, always on) and unforgiving in others (16GB is a hard ceiling, and every leaked process matters).

What's Next

The orchestration platform is functional but young. Here's what's on deck:

  • ReturnPro data hygiene CLI (optimal returnpro audit): Automated checks for FK resolution gaps, duplicate staging rows, and budget-to-actuals coverage
  • OpenClaw gateway deepening: More robust agent-to-agent communication patterns through the gateway layer
  • Content platform: A research-to-publication pipeline that chains web research agents into draft generation -- the first real multi-agent workflow on the orchestration platform

The constraint of running everything on a single Raspberry Pi forces interesting architectural decisions. You can't brute-force your way past a 16GB memory ceiling. Every service, every process, every WebSocket connection has to earn its place. That constraint, paradoxically, is what makes the system better.


All of this runs on a Raspberry Pi 5 at my desk in Miami, tunneled through Cloudflare, backed by Supabase, and deployed with tools I built myself. The stack is Bun, Hono, xterm.js, Next.js, and a lot of systemd units. If you want to follow along, the code lives at github.com/clenisa.