Skip to content

Building Nocturna — The Hermes Kanban Control Center

After months of running Hermes Agent for home-lab automation, I needed a visual way to track, manage, and replay tasks. Nocturna was born: a React + Express kanban board that connects to Hermes in two modes — Gateway (HTTP API to a remote instance) or Local CLI (spawns the hermes binary directly).

Nocturna provides a visual kanban board for Hermes tasks, supporting both remote Gateway API and local CLI modes.

Why a separate UI?

Hermes' web UI is great for chat, but automation tasks have lifecycle states (pending → running → complete/blocked) that benefit from a board view. Nocturna adds:

  • Board-scoped tasks: each board maps to a Hermes kanban board (default: nocturna)
  • Instance management: add SSH, LAN, Gateway, or Local CLI instances
  • Real-time polling: 3s interval with idle detection
  • Action lifecycle: complete, block, promote, reopen via single click

Architecture highlights

Component Tech Purpose
Backend Express 5 + TypeScript (ESM) API routes, auth, instance runner
Frontend React 19 + Vite + Tailwind v4 Board, columns, cards, drawers
Database node:sqlite (no ORM) Users, instances, tasks, runs, boards
Hermes link Gateway HTTP / CLI spawn Two execution modes

The critical branching: every server route checks isGatewayActive(instance) and calls either gatewayFetch() (HTTP) or runCliJson() (spawns hermes binary).

Development workflow

npm run dev      # Vite + tsx hot reload
npm run build    # Vite + esbuild → dist/
npm test         # Vitest (unit/integration)
npm run test:e2e # Playwright (starts dev server)
npm run lint     # tsc --noEmit

Tests mock the CLI via NOCTURNA_HERMES_BIN=tests/fake-hermes pointing to a shell shim.

Next steps

  • Board templates (scrum, kanban, custom columns)
  • Webhook receiver for external triggers
  • Mobile-responsive board view
  • Export/import board JSON

This post is linked to the Nocturna project — click the project link in the sidebar to see all related posts.

Comments