Building a Self-Deploying Agent Dashboard
The agents built their own dashboard today. Bill has shipped 13 PRs so far — 5 today alone. Homer reviews them, Bob deploys. Toast notifications, system health monitoring, and cron status cards — all shipped by local LLMs on a Strix Halo.
Here's something that'll mess with your head: today the AI agents built, reviewed, and deployed improvements to the dashboard that monitors them.
Not metaphorically. Literally.
Bill (a 27B Qwen model running on a Strix Halo) picked up Fizzy cards, wrote the code, and created PRs. Homer reviewed and classified risk. Bob merged, fixed edge cases, and deployed. The dashboard restarted itself via PM2 and served the new features.
The snake ate its own tail. And it tasted pretty good.

What We Shipped
🍞 Toast Notifications (PR #42)
The dashboard used to call alert() when you triggered actions. Yes, the browser's built-in blocking popup from 1997. Bill replaced it with a proper toast system:
- Non-blocking — fire off multiple actions without the UI freezing
- Success/error/info variants with color-coded styling
- Auto-dismiss with sensible timeout (5s default)
- Dedupe throttling — spamming the button won't stack 15 identical toasts
- Portal-based rendering so they float above everything
The implementation uses a window.__toast global (not the cleanest pattern — React context would be better) but it works and keeps the change surface small. Bill's pragmatic like that.
🏥 System Health Panel (PR #43)
A compact grid showing live status of every service in the fleet:
- integrate-next (production app)
- Lemonade (llamacpp inference server)
- Ollama Strix (27B model host)
- Ollama Unraid (14B model host)
- Fizzy (kanban board)
Each service gets pinged with a 3-second timeout. Green pulsing dot = up. Red dot = down. Latency displayed in milliseconds. Auto-refreshes every 60 seconds.
The backend is dead simple — a Next.js API route that Promise.alls five fetch() calls with AbortController timeouts. No external dependencies.
🔄 Last Cron Run Status (PR #45)
Two compact cards showing Bill and Homer's last run result at a glance:
- Status badge (ok/error)
- Summary text (what happened)
- Duration and model used
- Timestamp in human-readable format
- Errors highlighted in red
The API route shells out to openclaw cron runs --id <jobId> --limit 1 and extracts JSON from the output. Had to regex-parse it because the CLI mixes doctor warnings into stdout. Classic.
⚡ Fire-and-Forget Actions
The "Run Bill" and "Run Homer" buttons used to block for up to 2 minutes waiting for the cron to finish. Now they use spawn() with detached: true and stdio: 'ignore' — the API returns instantly and the cron runs in the background. Click, toast, done.
The Meta Part
What makes this interesting isn't the features — it's the workflow.
The loop:
- I create Fizzy cards describing what I want
- Bill's cron picks one up every 2 hours
- A deterministic bash script (
bill-setup.sh) handles git clone, branching - Bill writes the actual code (the only part that needs an LLM)
- Another bash script (
bill-finalize.sh) commits, pushes, creates the PR - Homer reviews every 30 minutes — merges low-risk, escalates high-risk
- Bob (or I) review escalated PRs and deploy
Today's scorecard:
- Bill: 13 PRs merged total (5 today, 8 yesterday) ✅
- Homer: 1 auto-merged (simple API fix), 2 correctly escalated (new endpoints)
- Total human review time: ~5 minutes
The deterministic controller pattern was the breakthrough. Previous versions had Bill orchestrating everything — git, PRs, card moves — via LLM tool calls. That's fragile. Now the LLM only does what LLMs are good at: reading code and writing code. Everything else is bash.
Infrastructure Notes
- Bill's model:
Qwen3.5-27B-GGUFon Lemonade (llamacpp, ROCm, Strix Halo) - Homer's model:
qwen3.5:27bon Ollama (same hardware, different backend) - Dashboard: Next.js on PM2,
192.168.1.6:3010 - Inference speed: ~11 tok/s generation on Ollama, faster on Lemonade but with streaming quirks
The Lemonade backend triggers an OpenClaw streaming guard ("Invalid diff: now finding less tool calls!") intermittently. Ollama doesn't have this issue but is slower. With the simplified prompt, Lemonade succeeds more often — fewer tool calls means less surface area for the guard to trip on.
What's Next
- Cron Run History page — Bill already has PR #46 open for a
/cronspage with per-job drill-down - Cross-agent learning — agents now log successes/failures to shared memory files. Homer reads Bill's memory before reviewing his PRs. Weekly retro cron synthesizes patterns across all agents.
- Cost tracking — replace mock data with real token usage from OpenClaw sessions
The dashboard monitors the agents. The agents improve the dashboard. The dashboard shows the improvements. Round and round it goes.
I'm not sure if that's elegant or terrifying. Probably both.