docs: complete project research
This commit is contained in:
175
.planning/research/STACK.md
Normal file
175
.planning/research/STACK.md
Normal file
@@ -0,0 +1,175 @@
|
||||
# Stack Research
|
||||
|
||||
**Domain:** CLI/TUI session monitor for Claude Code on Linux (NixOS, i3 WM)
|
||||
**Researched:** 2026-03-23
|
||||
**Confidence:** HIGH
|
||||
|
||||
## Recommended Stack
|
||||
|
||||
### Core Technologies
|
||||
|
||||
| Technology | Version | Purpose | Why Recommended |
|
||||
|------------|---------|---------|-----------------|
|
||||
| Go | 1.25.x | Language | Deja utilise par piaire, coherence stack. Single binary, bon pour les outils CLI. Disponible via `nix-shell -p go`. |
|
||||
| Bubble Tea v2 | v2.x (charm.land/bubbletea/v2) | TUI framework | Standard de facto pour les TUI en Go (18k+ apps). Architecture Elm (Init/Update/View) qui structure bien le code. Le v2 apporte le renderer Cursed (base ncurses) et le mode 2026 (anti-tearing). |
|
||||
| go.i3wm.org/i3/v4 | v4.21+ | i3 IPC | Lib officielle du projet i3. Couvre 100% de l'API IPC. Gere automatiquement les reconnexions si i3 redemarre. Supporte les subscriptions (workspace events). |
|
||||
| fsnotify | v1.8+ | File watching | Surveiller les fichiers JSONL de `~/.claude/projects/` pour detecter l'activite des sessions. 13k+ importers, stable. |
|
||||
|
||||
### Supporting Libraries
|
||||
|
||||
| Library | Version | Purpose | When to Use |
|
||||
|---------|---------|---------|-------------|
|
||||
| Lip Gloss v2 | v2.x (charm.land/lipgloss/v2) | Styling TUI | Mise en forme du dashboard (couleurs, bordures, layout). Compose naturellement avec Bubble Tea v2. |
|
||||
| Bubbles v2 | v2.x (charm.land/bubbles/v2) | TUI components | Composants pre-faits (list, table, spinner) pour le dashboard. Evite de tout coder from scratch. |
|
||||
| esiqveland/notify | v0.11+ | Desktop notifications | Envoyer des notifs D-Bus quand une session passe de "travaille" a "attend input". Alternative legere a libnotify. |
|
||||
| encoding/json (stdlib) | - | JSON parsing | Parser les JSONL des sessions Claude Code. Pas besoin de lib externe, le format est simple. |
|
||||
| os (stdlib) | - | Process inspection | Lire `/proc/<pid>/status`, `/proc/<pid>/cmdline` pour detecter les processus Claude. Pas besoin de prometheus/procfs pour ce cas simple. |
|
||||
| hpcloud/tail | v1.0+ | File tailing | Follow les fichiers JSONL en temps reel (comme `tail -f`). Alternative a fsnotify pour le cas specifique du suivi de fichiers qui grandissent. |
|
||||
|
||||
### Development Tools
|
||||
|
||||
| Tool | Purpose | Notes |
|
||||
|------|---------|-------|
|
||||
| nix-shell | Environment dev | `nix-shell -p go gopls` pour avoir Go + LSP sans pollution globale |
|
||||
| goreleaser | Build & release | Single binary, cross-compile. Standard pour les outils Go distribues |
|
||||
| golangci-lint | Linting | Aggregateur de linters, couvre les erreurs courantes |
|
||||
|
||||
## Architecture Decision: Pas de lib pour /proc
|
||||
|
||||
Pour vmux, on a besoin de :
|
||||
1. Lister les processus `claude` (= `pgrep claude` ou scan de `/proc/*/cmdline`)
|
||||
2. Lire le PID parent pour trouver le terminal
|
||||
3. Lire le PTY associe (`/proc/<pid>/fd/0` -> `/dev/pts/X`)
|
||||
|
||||
C'est 50 lignes de Go stdlib (`os.ReadDir("/proc")` + `os.ReadFile`). Importer `prometheus/procfs` (poids lourd, API instable) ou `mitchellh/go-ps` (pas maintenu activement) n'a pas de sens.
|
||||
|
||||
## Architecture Decision: JSONL comme source primaire d'etat
|
||||
|
||||
L'analyse du systeme de fichiers revele que Claude Code stocke ses sessions dans `~/.claude/projects/<encoded-cwd>/<session-id>.jsonl`. Chaque ligne est un evenement JSON avec :
|
||||
- `type` : "user", "assistant", "file-history-snapshot"
|
||||
- `timestamp` : ISO 8601
|
||||
- `sessionId` : UUID
|
||||
- `cwd` : repertoire de travail
|
||||
- `gitBranch` : branche git courante
|
||||
- `version` : version de Claude Code
|
||||
- `message.content` : contenu du message
|
||||
|
||||
**Strategie de detection d'etat :**
|
||||
- "Travaille" = le dernier evenement est de type "assistant" et recent (< 30s), ou le processus est actif CPU
|
||||
- "Attend input" = le dernier evenement est de type "assistant" (reponse terminee) et le processus idle
|
||||
- "Idle" = pas d'activite recente
|
||||
|
||||
Le fichier `/proc/<pid>/status` confirme : `State: S (sleeping)` quand Claude attend.
|
||||
|
||||
## Architecture Decision: i3 tree comme source de mapping
|
||||
|
||||
L'i3 tree (via `get_tree`) fournit toutes les fenetres avec leur nom. Les terminaux Claude Code ont des titres distinctifs (verifies sur le poste) :
|
||||
- `Claude Code` dans le titre de la fenetre
|
||||
- Le workspace numerote est directement accessible
|
||||
|
||||
Combinaison PID process Claude -> PTY (`/proc/pid/fd/0`) -> fenetre i3 (via window properties ou titre) -> workspace.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
# Nix shell pour le dev
|
||||
nix-shell -p go gopls goreleaser golangci-lint
|
||||
|
||||
# Init module
|
||||
go mod init github.com/pieMusic/vmux
|
||||
|
||||
# Core
|
||||
go get charm.land/bubbletea/v2
|
||||
go get charm.land/lipgloss/v2
|
||||
go get charm.land/bubbles/v2
|
||||
|
||||
# i3 IPC
|
||||
go get go.i3wm.org/i3/v4
|
||||
|
||||
# File watching
|
||||
go get github.com/fsnotify/fsnotify
|
||||
|
||||
# Notifications
|
||||
go get github.com/esiqveland/notify
|
||||
go get github.com/godbus/dbus/v5
|
||||
```
|
||||
|
||||
## Alternatives Considered
|
||||
|
||||
| Recommended | Alternative | When to Use Alternative |
|
||||
|-------------|-------------|-------------------------|
|
||||
| Bubble Tea v2 | tview (rivo/tview) | Si on veut un style "formulaire terminal" classique (menus, tables, formulaires). Mais vmux est un dashboard de monitoring, l'archi Elm de Bubble Tea convient mieux. |
|
||||
| Bubble Tea v2 | Pas de TUI (CLI simple) | Si la v1 se limite a un `vmux status` one-shot. Commencer en CLI pure, migrer vers TUI quand le dashboard prend forme. **Recommande pour le MVP.** |
|
||||
| go.i3wm.org/i3/v4 | mdirkse/i3ipc-go | Si la lib officielle manque une feature. Mais elle couvre 100% de l'API IPC, pas de raison d'utiliser un fork. |
|
||||
| go.i3wm.org/i3/v4 | Executer `i3-msg` via os/exec | Si on veut eviter la dependance. Viable pour un prototype rapide, mais la lib Go gere les reconnexions et le parsing. |
|
||||
| fsnotify | Polling periodique | Si fsnotify pose des problemes avec NixOS/inotify limits. Le polling toutes les 2s est acceptable pour le use case. |
|
||||
| stdlib /proc | prometheus/procfs | Si on a besoin de metriques systeme avancees. Pas le cas pour vmux. |
|
||||
| esiqveland/notify | os/exec + notify-send | Plus simple, zero dependance. Viable si les notifs restent basiques (pas d'actions, pas d'icones). |
|
||||
|
||||
## What NOT to Use
|
||||
|
||||
| Avoid | Why | Use Instead |
|
||||
|-------|-----|-------------|
|
||||
| Rust / Ratatui | Briserait la coherence avec piaire (Go). Le gain de perf n'a aucun interet pour un dashboard. | Go + Bubble Tea |
|
||||
| Python / Rich | Pas de single binary, runtime dependency, lent au demarrage. | Go |
|
||||
| prometheus/procfs | Trop lourd pour lire 3 champs dans /proc. API instable (WARNING dans leur doc). | Go stdlib (os.ReadFile) |
|
||||
| mitchellh/go-ps | Derniere release 2021. API minimaliste qui ne donne pas les FDs. | Go stdlib /proc scan |
|
||||
| Bubble Tea v1 | v2 est sorti, le renderer Cursed est meilleur. Pas de raison de partir sur l'ancienne version. | Bubble Tea v2 |
|
||||
| gRPC / API HTTP interne | Over-engineering pour un outil local single-user. | Channels Go internes |
|
||||
|
||||
## Stack Patterns by Variant
|
||||
|
||||
**Si standalone (recommande pour commencer) :**
|
||||
- Binary unique `vmux`
|
||||
- Config dans `~/.config/vmux/` ou flags CLI
|
||||
- Pas de serveur, pas de port
|
||||
|
||||
**Si integration piaire plus tard :**
|
||||
- vmux comme package Go importe par piaire
|
||||
- Partage du module Go, meme conventions
|
||||
- piaire expose le dashboard vmux dans son interface HTMX
|
||||
|
||||
**Si MVP CLI-first (recommande) :**
|
||||
- Phase 1 : `vmux` en one-shot, affiche l'etat des sessions en tableau
|
||||
- Phase 2 : Mode watch (`vmux -w`) avec refresh periodique
|
||||
- Phase 3 : TUI interactive avec Bubble Tea
|
||||
- Cela permet de valider la detection avant d'investir dans la TUI
|
||||
|
||||
## Version Compatibility
|
||||
|
||||
| Package | Compatible With | Notes |
|
||||
|---------|-----------------|-------|
|
||||
| Bubble Tea v2 | Go 1.22+ | Import path: `charm.land/bubbletea/v2` (pas `github.com/...`) |
|
||||
| Lip Gloss v2 | Bubble Tea v2 | Doivent etre upgrades ensemble |
|
||||
| Bubbles v2 | Bubble Tea v2, Lip Gloss v2 | Trio indissociable |
|
||||
| go.i3wm.org/i3/v4 | i3 4.x | Tags alignes sur les versions i3. v4.21+ pour i3 4.24 |
|
||||
| fsnotify v1.8 | Go 1.17+ | Utilise inotify sur Linux |
|
||||
| Go 1.25.x | NixOS current | Disponible dans nixpkgs stable |
|
||||
|
||||
## Verified on This Machine
|
||||
|
||||
| Element | Value | Source |
|
||||
|---------|-------|--------|
|
||||
| Go version (nix) | 1.25.7 | `nix-shell -p go --run "go version"` |
|
||||
| i3 version | 4.24 | `i3-msg -t get_version` |
|
||||
| Claude processes | 4 actifs (PID 6938, 10466, 13736, 16030) | `ps aux` |
|
||||
| Session storage | `~/.claude/projects/<encoded-cwd>/<uuid>.jsonl` | Verifie sur le poste |
|
||||
| JSONL fields cles | type, timestamp, sessionId, cwd, gitBranch, message | Verifie par lecture directe |
|
||||
| i3 window names | Contiennent "Claude Code" | `i3-msg -t get_tree` |
|
||||
| PTY mapping | `/proc/<pid>/fd/0` -> `/dev/pts/X` | Verifie sur PID 6938 |
|
||||
|
||||
## Sources
|
||||
|
||||
- [Bubble Tea GitHub](https://github.com/charmbracelet/bubbletea) - v2 release, 18k+ apps
|
||||
- [Bubble Tea v2 release notes](https://github.com/charmbracelet/bubbletea/releases/tag/v2.0.0) - Cursed renderer, mode 2026
|
||||
- [go.i3wm.org/i3/v4](https://pkg.go.dev/go.i3wm.org/i3/v4) - Official i3 Go package, published Mar 2025
|
||||
- [i3 IPC docs](https://i3wm.org/docs/ipc.html) - Protocol reference
|
||||
- [fsnotify](https://github.com/fsnotify/fsnotify) - Cross-platform file watcher, 13k+ importers
|
||||
- [esiqveland/notify](https://github.com/esiqveland/notify) - D-Bus notification Go library
|
||||
- [Claude Code CLI reference](https://code.claude.com/docs/en/cli-reference) - Session management docs
|
||||
- [claude-code-log](https://github.com/daaain/claude-code-log) - Confirms JSONL format structure
|
||||
- Machine locale (NixOS, i3 4.24, Go 1.25.7) - Verified by direct inspection
|
||||
|
||||
---
|
||||
*Stack research for: vmux (Claude Code session monitor)*
|
||||
*Researched: 2026-03-23*
|
||||
Reference in New Issue
Block a user