Aller au contenu principal
Retour aux projets
En développement

agents-deck - Dashboard temps réel multi-agents IA

Dashboard temps réel pour orchestrer 3 à 5 agents de coding IA (Claude Code, Codex, Cursor, Kimi) tournant en parallèle. Répond à "qui fait quoi, qui est bloqué, qui attend qui" en un coup d'œil. Philosophie zero-DB : le repo Git est la base de données via fichiers YAML. Manifest auto-discovery (project.yml), 5 artefacts (Ticket, Backlog, Message, Reply, Changelog), 3 rôles (coordinator, executor, oversight). Status = location (le dossier d'un ticket EST son statut, git mv = transition). Dual source of truth (status.yml agent vs state.yml coordinator) avec détection de conflits. Isolation par branches/worktrees Git, ~17 500 LOC TypeScript.

Node.js 20 TypeScript Express js-yaml Ajv chokidar React 18 Vite Tailwind Radix UI Server-Sent Events Docker
agents-deck — vue d'ensemble du dashboard

Architecture Zero-DB : le repo Git est la base de données

Dashboard temps réel qui watch des fichiers YAML versionnés dans le repo cible. Aucune persistence propre.

01

Backend Node.js + Express

Serveur TypeScript de ~6 400 LOC. 32 parsers spécialisés (parser-yml-*, parser-state, parser-git, parser-messages...). Validation Ajv contre 14 schémas JSON Draft-07. Watcher chokidar + bus d'événements SSE pour push temps réel au front.

Node.js 20TypeScriptExpressjs-yamlAjvchokidarSSE
02

Frontend React + Vite

SPA de ~11 100 LOC. 37 composants, 10 pages, react-router 7, Tailwind + Radix UI, framer-motion. Live updates via EventSource. Switcher multi-projets (registre XDG local), modale détail agent (Tickets/Messages/Replies en 1 bundle).

React 18ViteTailwindRadix UIreact-router 7framer-motion
03

Modèle de données YAML

5 artefacts (T_* ticket, B_* backlog, M_* message, R_* reply, C_* changelog) + 3 rôles (coordinator, executor, oversight). Un seul project.yml à la racine du repo cible déclare agents, phases, paths, conventions — le dashboard se reconfigure tout seul. Aucun hardcode.

YAMLJSON Schema Draft-07Manifest auto-discovery
04

Isolation Git + worktrees

Chaque agent travaille sur sa branche agent/<id>/active, optionnellement en worktree séparé monté :ro dans le container. Status d'un ticket = son dossier (planned/, working/, done/, ...) → git mv = transition d'état. Pas de champ qui peut dériver.

Git worktreeDocker volumes :rogit mvgit status --porcelain

Fonctionnalités Clés

Manifest auto-discovery

Un seul project.yml à la racine déclare agents, phases, paths, rôles. Le dashboard se reconfigure tout seul, zéro hardcode. Fork sur un autre repo = copier project.yml.

Zero-DB philosophy

Aucune persistence propre. State reconstruit à chaque requête depuis YAML + git refs. Restart container = zéro perte. Backup = git push. Audit trail = git log.

Status = location

Le statut d'un ticket est son dossier (planned/drafts/blocked/working/waiting/done/cancelled). git mv = transition. Pas de champ qui peut dériver du disque.

Dual source of truth

status.yml (ce que l'agent dit qu'il fait) vs state.yml (ce que le coordinator attend). Divergence → conflict card sur le dashboard, investigation obligatoire.

Isolation par worktree

Chaque agent sur sa branche dédiée, optionnellement en worktree séparé. Monté :ro côté Docker. Deux agents ne peuvent jamais éditer le même fichier en même temps.

Server-Sent Events

Push temps réel des changements de fichiers vers le navigateur via chokidar + bus d'événements. Pas de polling, refresh sub-seconde.

State machine 6 états

closed > deploying > blocked > waiting_for_review > working > standby. Calculé depuis status.yml avec fallback git signals (commits ahead, last activity, dirty files).

Multi-projets via registry XDG

Switcher entre plusieurs repos observés. Registre local ~/.config/agents-deck/projects.json. API /api/v2/projects pour register/switch/remove.

Stack Technique

Node.js 20 + TypeScript Backend Runtime

Serveur Express 4, modules ESM, build via tsc + tsx watch en dev

js-yaml + Ajv Parsing & Validation

Parse YAML strict + validation contre 14 schémas JSON Draft-07

chokidar + SSE Temps réel

Watcher filesystem + bus d'événements + Server-Sent Events vers le navigateur

React 18 + Vite Frontend

SPA, 37 composants, 10 pages, code-splitting par route

Tailwind + Radix UI UI

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

react-router 7 Routing

Routes /v2/* (canonique YAML) + / (legacy) avec sidebar contextuelle

Docker multi-stage Deployment

Build TypeScript dans builder, runtime Alpine avec git installé pour git status --porcelain

Git worktree + branches Isolation

Une branche agent/<id>/active par agent, worktrees montés :ro dans le container

Résultats & Métriques

Performance Technique

~6 400
LOC backend
TypeScript, 32 parsers spécialisés
~11 100
LOC frontend
React, 37 composants, 10 pages
< 2s
Cold start
Container Alpine multi-stage
35
Endpoints API
14 v2 (canonique) + 21 legacy

Défis Techniques & Solutions

Éviter la dérive d'état

Problème
Un champ status: working dans un YAML peut mentir si personne ne le met à jour. Avec 5 agents en parallèle, les statuts deviennent vite obsolètes.
Solution
Status d'un ticket = nom de son dossier parent. Promouvoir un ticket de drafts à working est un git mv. Impossible d'avoir une divergence : le filesystem EST la vérité.

Coordination multi-agents sans bottleneck

Problème
Si un seul agent maintient l'état, il devient le goulot d'étranglement. Si chacun maintient le sien, le coordinator n'a aucun moyen d'exprimer ses attentes.
Solution
Dual YAML : status.yml côté agent (ce qu'il fait), state.yml côté coordinator (ce qu'il attend). Le dashboard compare et surface les conflits — investigation obligatoire, pas de silence.

Collision de fichiers entre agents

Problème
Deux agents qui éditent le même fichier en parallèle = merge conflict garanti et perte de productivité.
Solution
Une branche par agent (agent/<id>/active), optionnellement un worktree Git séparé monté :ro dans le container du dashboard. Plus juridiction déclarée par agent (liste de paths autorisés) avec détection de violations.

Restart sans perte de contexte

Problème
Un dashboard qui maintient son propre state perd tout au moindre crash. Inacceptable pour un outil de coordination critique.
Solution
Zero-DB. Tout est reconstruit à chaque requête depuis les YAML + git. Restart Docker = cold start < 2 secondes, zero perte. Backup = le git push que tu fais déjà.

Compétences Démontrées

Architecture système

Zero-DB designManifest auto-discoveryDual source of truthState machine multi-niveauxEvent-driven via SSE

TypeScript backend

Express 4Parsers modulaires (32 fichiers)JSON Schema validation (Ajv)Filesystem watching (chokidar)Git scripting (execSync)

React frontend

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

Git tooling avancé

Worktree par agentgit mv pour transitions d'étatgit status --porcelain parsinggit rev-list / log --graphBranches isolées par agent

DevEx & packaging

Docker multi-stageVolumes :ro/:rw stratégiquesXDG-compliant configHot reload (tsx watch + vite)Concurrently en dev

Intéressé par ce projet ?

Contactez-moi pour discuter de projets similaires ou pour plus d'informations.