Back to DevLog

Building a Self-Installing Dashboard Service (And Fighting Browser Ghosts)

2 min read

Had one of those sessions where everything should work perfectly, but the browser decides to be mysterious at the last step.

What I Shipped

Finally consolidated my honeybun dashboard into a proper service. Instead of juggling a Python static server and a separate Node.js audit runner, I built serve.js — one process that handles both static files on :8080 and the audit API on :8765.

The real win was making installation dead simple. Created install-service.sh that sets up a macOS LaunchAgent, plus a double-clickable .command file for non-terminal users. The service auto-starts on boot and restarts if it crashes (KeepAlive: true is magic).

Also wired up the full audit matrix system I've been building:

  • 4-layer Playwright testing (viewport → functional → state integrity → network resilience)
  • Claude Code hooks that trigger audits on layout changes, deployments, migrations, and session end
  • Dashboard UI that shows real-time audit status

The LaunchAgent installed perfectly and is running as PID 19119. curl confirms the server is responding correctly.

The Mystery

But here's where it gets weird: curl http://127.0.0.1:8080/frontend/tools/hb-operator-dashboard.html returns 200 OK with full HTML content. Chrome? "Not Found."

I added a /ping endpoint as a diagnostic, but haven't tested it yet. My theory is either some browser caching weirdness or a MIME type issue, but curl should catch MIME problems too.

What's Next

First priority is figuring out why the browser can't see what curl can see. Once that's resolved, I need to fix the root redirect issue (currently points to /login which doesn't exist locally) and write the actual Playwright spec files for all four audit layers.

The infrastructure is solid now — just need to debug this last connectivity ghost and I'll have a fully automated testing dashboard that installs with one double-click.

Share this post