Files
vmux/.planning/phases/01-session-discovery/01-01-PLAN.md
2026-03-23 13:09:19 +01:00

8.0 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
01-session-discovery 01 execute 1
shell.nix
go.mod
types.go
proc.go
proc_test.go
true
DISC-01
DISC-02
truths artifacts key_links
vmux detecte les processus Claude Code actifs via /proc
vmux lit le cwd de chaque processus via /proc/PID/cwd
vmux encode le cwd en nom de dossier ~/.claude/projects/
path provides contains
shell.nix Environnement de dev NixOS avec Go go
path provides contains
go.mod Module Go module github.com/pieMusic/vmux
path provides exports
types.go Types partages (Process, Session, SessionState)
Process
Session
SessionState
Working
NeedsInput
Idle
path provides exports
proc.go Scan /proc pour les processus Claude
FindClaudeProcesses
EncodePath
path provides contains
proc_test.go Tests unitaires pour proc.go TestFindClaudeProcesses
from to via pattern
proc.go /proc/*/cmdline os.ReadFile + strings.Split sur null bytes ReadFile.*cmdline
from to via pattern
proc.go /proc/*/cwd os.Readlink Readlink.*cwd
Scaffolding du projet Go et detection des processus Claude Code via /proc.

Purpose: Poser les fondations (module Go, types, environnement NixOS) et implementer la brique de base : trouver les processus Claude actifs avec leur cwd. Output: Un module Go fonctionnel avec FindClaudeProcesses() teste qui retourne les PID + cwd des processus Claude.

<execution_context> @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/01-session-discovery/01-CONTEXT.md @.planning/phases/01-session-discovery/01-RESEARCH.md Task 1: Scaffolding projet + types partages shell.nix, go.mod, types.go .planning/phases/01-session-discovery/01-RESEARCH.md Creer 3 fichiers a la racine du projet :

shell.nix : environnement NixOS avec go et gopls :

{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  buildInputs = with pkgs; [ go gopls ];
}

go.mod : initialiser le module Go :

module github.com/pieMusic/vmux

go 1.25

types.go (package main) : definir les types partages utilises par tous les autres fichiers :

package main

type SessionState int

const (
    Working    SessionState = iota
    NeedsInput
    Idle
    Unknown
)

func (s SessionState) String() string // "Working", "Needs Input", "Idle", "Unknown"

type Process struct {
    PID int
    Cmd []string // arguments cmdline
    Cwd string   // readlink /proc/PID/cwd
}

type Session struct {
    Process   Process
    SessionID string
    GitBranch string
    State     SessionState
    Preview   string // dernieres lignes de sortie
    CwdPath   string // cwd du processus
    Worktree  string // git worktree (peut differer du cwd)
}

Le SessionState a 4 valeurs : Working, NeedsInput, Idle, Unknown. Unknown est utilise quand aucun JSONL n'est trouve pour un processus (per D-04, pitfall 4 de la recherche). cd /home/pierre/Code/vibe/vmux && nix-shell --run "go build ./..." <acceptance_criteria> - shell.nix contient go et gopls dans buildInputs - go.mod contient module github.com/pieMusic/vmux - types.go contient type SessionState int - types.go contient Working SessionState = iota - types.go contient NeedsInput - types.go contient Idle - types.go contient Unknown - types.go contient type Process struct - types.go contient type Session struct - go build ./... compile sans erreur </acceptance_criteria> Le projet compile. Les types Process, Session et SessionState sont definis et exportes.

Task 2: Scan /proc + encoding chemin + tests proc.go, proc_test.go types.go .planning/phases/01-session-discovery/01-RESEARCH.md - TestFindClaudeProcesses: avec un faux /proc contenant 3 repertoires (2 processus "claude", 1 processus "bash"), retourne exactement 2 Process avec les bons PID, Cmd et Cwd. - TestFindClaudeProcesses_PermissionDenied: un /proc/PID/cmdline illisible (permission denied) est ignore silencieusement, pas de crash. - TestFindClaudeProcesses_EmptyProc: un /proc vide retourne un slice vide sans erreur. - TestEncodePath: "/home/pierre/Code/vibe/vmux" -> "-home-pierre-Code-vibe-vmux" - TestEncodePath_DotDir: "/home/pierre/.config/app" -> "-home-pierre--config-app" (les `.` sont remplaces par `-`, d'ou le double dash) **proc.go** (package main) :

FindClaudeProcesses(procDir string) ([]Process, error) :

  • Accepte le chemin vers /proc en parametre (permet le test avec un faux /proc). En production, passer "/proc".
  • Lire os.ReadDir(procDir), filtrer les entrees dont le nom est numerique (PID).
  • Pour chaque PID, lire procDir/PID/cmdline via os.ReadFile. Le contenu est separe par des null bytes (\x00). Splitter avec strings.Split(strings.TrimRight(data, "\x00"), "\x00").
  • Si le premier argument (index 0) se termine par claude ou est exactement claude, c'est un processus Claude Code (per D-01).
  • Lire le cwd via os.Readlink(procDir/PID/cwd) (per D-01).
  • Ignorer silencieusement les erreurs de lecture (permission denied, processus disparu) : continue dans la boucle.
  • Retourner un []Process avec PID (int parse du nom de dossier), Cmd ([]string des arguments) et Cwd (string du readlink).

EncodePath(path string) string :

  • Remplacer tous les / par - et tous les . par - (per RESEARCH Pattern 2, pitfall 6).
  • Utiliser strings.NewReplacer("/", "-", ".", "-").Replace(path).

proc_test.go (package main) :

Utiliser des fixtures temporaires pour simuler /proc (per strategie TDD de la recherche) :

  • createFakeProc(t *testing.T, entries map[int]fakeProcEntry) string : cree un repertoire temporaire avec la structure /proc simulee.
  • fakeProcEntry : struct avec cmdline string (contenu brut avec \x00) et cwd string (chemin cible du symlink).
  • Creer des symlinks pour cwd (os.Symlink).
  • Creer des fichiers pour cmdline (os.WriteFile).

5 tests decrits dans la section behavior. cd /home/pierre/Code/vibe/vmux && nix-shell --run "go test -v -run 'TestFindClaudeProcesses|TestEncodePath' ./..." <acceptance_criteria> - proc.go contient func FindClaudeProcesses(procDir string) ([]Process, error) - proc.go contient func EncodePath(path string) string - proc_test.go contient TestFindClaudeProcesses qui cree un faux /proc - proc_test.go contient TestEncodePath - proc_test.go contient TestEncodePath_DotDir - Tous les tests passent avec go test -v -run 'TestFindClaudeProcesses|TestEncodePath' ./... - FindClaudeProcesses accepte un parametre procDir (pas de /proc en dur) </acceptance_criteria> FindClaudeProcesses detecte les processus Claude dans un faux /proc. EncodePath convertit correctement les chemins. Tous les tests passent.

- `go build ./...` compile sans erreur - `go test -v ./...` : tous les tests passent - `go vet ./...` : pas de warning

<success_criteria>

  • Le projet Go est initialise avec shell.nix et go.mod
  • Les types Process, Session, SessionState sont definis
  • FindClaudeProcesses retourne les processus Claude depuis /proc
  • EncodePath encode les chemins en noms de dossiers ~/.claude/projects/
  • Tests unitaires couvrent les cas normaux et les cas limites </success_criteria>
After completion, create `.planning/phases/01-session-discovery/01-01-SUMMARY.md`