Files
vmux/docs/architecture.md
Pierre Martin f6881c1619 docs: add README, licence WTFPL et documentation
- README.md : vision, installation, commandes, aperçu fonctionnement
- LICENSE : WTFPL v2
- docs/architecture.md : composants, flux de données, index des fichiers
- docs/i3-integration.md : config i3bar, switch, focus, dépannage
- .gitignore : exclure .direnv/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 17:57:51 +02:00

4.3 KiB

Architecture

Vue d'ensemble

vmux suit une architecture daemon + CLI classique. Un daemon unique tourne en arrière-plan ; toutes les commandes vmux communiquent avec lui via une Unix socket.

Claude Code session
      │ hooks (HTTP localhost:3119)
      ▼
┌─────────────┐
│   Daemon    │◄── /proc scan (5s)
│             │◄── JSONL reader (~/.claude/projects/)
│  registry   │◄── i3 IPC + X11 (workspace resolution)
└──────┬──────┘
       │ Unix socket (~/.vmux/vmux.sock)
       ▼
  vmux list / switch / label / focus / i3bar

Composants

Daemon (daemon.go)

  • Écoute sur ~/.vmux/vmux.sock (Unix socket)
  • Lance un hook server HTTP sur localhost:3119
  • Maintient un SessionRegistry en mémoire (map sessionID → SessionInfo)
  • Poll /proc toutes les 5s (ou 20s si des hooks arrivent activement)

Détection des processus (proc.go)

Scrute /proc/*/cmdline pour trouver les processus dont la commande contient claude. Pour chaque processus trouvé, lit :

  • /proc/<pid>/cwd — répertoire de travail courant
  • /proc/<pid>/fd/0 — PTY associé (pour la résolution workspace)

Lecture JSONL (session.go)

Claude Code écrit un fichier JSONL par session dans ~/.claude/projects/<encoded-cwd>/<uuid>.jsonl. vmux associe un PID au bon fichier par correspondance du cwd, puis lit les messages pour extraire :

  • sessionId, gitBranch — identité de la session
  • type: "assistant" — dernier message Claude (pour le state et le preview)

Détection d'état (state.go)

État Critère
Working Dernier event hook = PreToolUse ou PostToolUse
Needs Input Dernier event hook = Notification ou Stop
Idle Aucun event récent, dernier message JSONL vieux de plus de 30s

Les hooks Claude Code sont prioritaires sur la détection JSONL : ils arrivent en temps réel.

Hooks Claude Code (hook.go)

Claude Code appelle vmux hook à chaque événement (via la config ~/.claude/settings.json). Le binaire lit le JSON sur stdin et le transmet au daemon via la socket. Le daemon met à jour le registry et déclenche une notification si la session passe de Working à Needs Input.

Résolution workspace i3 (workspace.go, i3bridge.go, x11_resolver.go)

  1. i3.GetTree() — récupère l'arbre des fenêtres i3
  2. Pour chaque fenêtre avec "Claude Code" dans le titre : lit son PID via _NET_WM_PID (X11)
  3. Remonte la chaîne /proc/<pid>/fd/0 → PTY → processus parent → PID Claude
  4. Associe le PID Claude au numéro de workspace i3

Dégradation gracieuse : si i3 ou X11 est indisponible, les workspaces restent vides (pas de crash).

i3bar (i3bar.go)

Implémente le protocole i3bar. Tourne en boucle infinie, interroge le daemon toutes les 2s, écrit du JSON sur stdout.

Notifications (notify.go)

Appelle notify-send avec --urgency=critical quand une session passe de Working à Needs Input. Le mode focus (vmux focus <minutes>) supprime les notifications pendant la durée donnée.

Fichiers

Fichier Rôle
main.go Entrypoint, routing des commandes CLI
daemon.go Daemon, registry, label store
proc.go Scan /proc pour les processus claude
session.go Lecture des fichiers JSONL Claude Code
state.go Détection d'état (Working/NeedsInput/Idle)
hook.go Réception et traitement des hooks Claude Code
workspace.go Résolution workspace via i3 tree
i3bridge.go Abstraction i3 IPC (testable)
x11_resolver.go Lecture _NET_WM_PID via XGB
i3bar.go Protocole i3bar
notify.go Notifications desktop (notify-send)
focus.go Timer de mode focus
display.go Affichage vmux list
client.go Client Unix socket
protocol.go Types Request/Response partagés
setup.go Injection des hooks dans settings.json
types.go Types de données (Session, SessionState…)

Données persistées

Chemin Contenu
~/.vmux/vmux.sock Unix socket du daemon
~/.vmux/labels.json Labels assignés par l'utilisateur
~/.claude/settings.json Hooks Claude Code (modifié par vmux setup)