Skip to main content
Back to projects
In Development

agents-deck - Real-Time Multi-Agent AI Dashboard

Real-time dashboard to orchestrate 3 to 5 AI coding agents (Claude Code, Codex, Cursor, Kimi) running in parallel. Answers "who's doing what, who's blocked, who's waiting on whom" at a glance. Zero-DB philosophy: the Git repo IS the database via YAML files. Manifest auto-discovery (project.yml), 5 artifacts (Ticket, Backlog, Message, Reply, Changelog), 3 roles (coordinator, executor, oversight). Status = location (a ticket's folder IS its status, git mv = transition). Dual source of truth (agent status.yml vs coordinator state.yml) with conflict detection. Isolation via Git branches/worktrees, ~17,500 LOC TypeScript.

Node.js 20TypeScriptExpressjs-yamlAjvchokidarReact 18ViteTailwindRadix UIServer-Sent EventsDocker
agents-deck — dashboard overview

Zero-DB Architecture: the Git repo IS the database

Real-time dashboard watching versioned YAML files in the target repo. No self-managed persistence.

01

Node.js + Express Backend

TypeScript server, ~6,400 LOC. 32 specialized parsers (parser-yml-*, parser-state, parser-git, parser-messages...). Ajv validation against 14 JSON Schema Draft-07 files. chokidar watcher + SSE event bus for real-time push to the frontend.

Node.js 20TypeScriptExpressjs-yamlAjvchokidarSSE
02

React + Vite Frontend

SPA, ~11,100 LOC. 37 components, 10 pages, react-router 7, Tailwind + Radix UI, framer-motion. Live updates via EventSource. Multi-project switcher (XDG local registry), agent detail modal (Tickets/Messages/Replies in one bundle).

React 18ViteTailwindRadix UIreact-router 7framer-motion
03

YAML Data Model

5 artifacts (T_* ticket, B_* backlog, M_* message, R_* reply, C_* changelog) + 3 roles (coordinator, executor, oversight). A single project.yml at the target repo root declares agents, phases, paths, conventions — the dashboard reconfigures itself. Zero hardcode.

YAMLJSON Schema Draft-07Manifest auto-discovery
04

Git Isolation + Worktrees

Each agent works on its own agent/<id>/active branch, optionally in a separate worktree mounted :ro into the container. A ticket's status = its folder (planned/, working/, done/, ...) → git mv = state transition. No field can drift.

Git worktreeDocker :ro volumesgit mvgit status --porcelain

Key Features

Manifest auto-discovery

A single project.yml at the root declares agents, phases, paths, roles. The dashboard reconfigures itself, zero hardcode. Forking onto another repo = copy project.yml.

Zero-DB philosophy

No self-managed persistence. State is reconstructed at every request from YAML + git refs. Container restart = zero loss. Backup = git push. Audit trail = git log.

Status = location

A ticket's status is its folder (planned/drafts/blocked/working/waiting/done/cancelled). git mv = transition. No field can drift from disk truth.

Dual source of truth

status.yml (what the agent says it does) vs state.yml (what the coordinator expects). Divergence → conflict card on the dashboard, mandatory investigation.

Worktree isolation

Each agent on its own dedicated branch, optionally a separate worktree. Mounted :ro Docker-side. Two agents can never edit the same file at the same time.

Server-Sent Events

Real-time push of file changes to the browser via chokidar + event bus. No polling, sub-second refresh.

6-state machine

closed > deploying > blocked > waiting_for_review > working > standby. Computed from status.yml with git-signal fallback (commits ahead, last activity, dirty files).

Multi-project via XDG registry

Switch between several observed repos. Local registry at ~/.config/agents-deck/projects.json. API /api/v2/projects to register/switch/remove.

Tech Stack

Node.js 20 + TypeScript Backend Runtime

Express 4, ESM modules, built via tsc + tsx watch in dev

js-yaml + Ajv Parsing & Validation

Strict YAML parsing + validation against 14 JSON Schema Draft-07 files

chokidar + SSE Real-time

Filesystem watcher + event bus + Server-Sent Events to the browser

React 18 + Vite Frontend

SPA, 37 components, 10 pages, route-based code-splitting

Tailwind + Radix UI UI

Design system, accessible primitives (scroll-area, select, switch, tabs, tooltip)

react-router 7 Routing

/v2/* routes (canonical YAML) + / (legacy) with contextual sidebar

Docker multi-stage Deployment

TypeScript built in the builder stage, Alpine runtime with git installed for git status --porcelain

Git worktree + branches Isolation

One agent/<id>/active branch per agent, worktrees mounted :ro into the container

Results & Metrics

Technical Performance

~6,400
Backend LOC
TypeScript, 32 specialized parsers
~11,100
Frontend LOC
React, 37 components, 10 pages
< 2s
Cold start
Alpine multi-stage container
35
API endpoints
14 v2 (canonical) + 21 legacy

Technical Challenges & Solutions

Avoiding state drift

Problem
A status: working field in a YAML can lie if nobody updates it. With 5 agents running in parallel, statuses go stale fast.
Solution
A ticket's status = its parent folder name. Promoting a ticket from drafts to working is a git mv. Divergence becomes impossible: the filesystem IS the truth.

Multi-agent coordination without bottleneck

Problem
If a single agent maintains state, they become a bottleneck. If each maintains their own, the coordinator has no way to express what they expect.
Solution
Dual YAML: status.yml on the agent side (what they do), state.yml on the coordinator side (what they expect). The dashboard compares them and surfaces conflicts — mandatory investigation, no silence.

File collisions between agents

Problem
Two agents editing the same file in parallel = guaranteed merge conflict and lost productivity.
Solution
One branch per agent (agent/<id>/active), optionally a separate Git worktree mounted :ro into the dashboard's container. Plus declared jurisdiction per agent (list of allowed paths) with violation detection.

Restart without losing context

Problem
A dashboard that keeps its own state loses everything on the slightest crash. Unacceptable for a critical coordination tool.
Solution
Zero-DB. Everything is reconstructed at every request from YAML + git. Docker restart = cold start < 2 seconds, zero loss. Backup = the git push you already do.

Demonstrated Skills

System architecture

Zero-DB designManifest auto-discoveryDual source of truthMulti-level state machineEvent-driven via SSE

TypeScript backend

Express 4Modular parsers (32 files)JSON Schema validation (Ajv)Filesystem watching (chokidar)Git scripting (execSync)

React frontend

React 18Vite + HMRreact-router 7Radix UI primitivesEventSource (SSE client)

Advanced Git tooling

Per-agent worktreegit mv for state transitionsgit status --porcelain parsinggit rev-list / log --graphIsolated branches per agent

DevEx & packaging

Docker multi-stageStrategic :ro/:rw volumesXDG-compliant configHot reload (tsx watch + vite)concurrently in dev

Interested in this project?

Contact me to discuss similar projects or for more information.