- 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>
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
SessionRegistryen mémoire (map sessionID → SessionInfo) - Poll
/proctoutes 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 sessiontype: "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)
i3.GetTree()— récupère l'arbre des fenêtres i3- Pour chaque fenêtre avec "Claude Code" dans le titre : lit son PID via
_NET_WM_PID(X11) - Remonte la chaîne
/proc/<pid>/fd/0→ PTY → processus parent → PID Claude - 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) |