feat(01-02): add CLI display and main.go for vmux list

- DisplaySessions: colored output with state, cwd, branch, preview
- display_test.go: 5 tests covering color, noColor, empty, worktree, noBranch
- main.go: full pipeline FindClaudeProcesses -> FindSession -> DetectState -> Display
- Supports --no-color flag and NO_COLOR env var
- resolveWorktree via git rev-parse --show-toplevel

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Pierre Martin
2026-03-23 13:30:55 +01:00
parent e7ced9c3a3
commit f1dcee0ae2
3 changed files with 283 additions and 1 deletions

74
display.go Normal file
View File

@@ -0,0 +1,74 @@
package main
import (
"fmt"
"io"
"strings"
)
const (
colorReset = "\033[0m"
colorGreen = "\033[32m"
colorYellow = "\033[33m"
colorRed = "\033[31m"
colorGray = "\033[90m"
colorBold = "\033[1m"
)
// DisplaySessions writes a formatted list of sessions to w.
func DisplaySessions(w io.Writer, sessions []Session, noColor bool) {
if len(sessions) == 0 {
fmt.Fprintln(w, "No active Claude Code sessions found.")
return
}
for i, s := range sessions {
if i > 0 {
fmt.Fprintln(w)
}
stateLabel := stateColor(s.State, noColor) + s.State.String() + resetIfColor(noColor)
branch := ""
if s.GitBranch != "" {
branch = " (" + s.GitBranch + ")"
}
worktreeInfo := ""
if s.Worktree != "" && s.Worktree != s.CwdPath {
worktreeInfo = " [worktree: " + s.Worktree + "]"
}
fmt.Fprintf(w, "[%s] %s%s%s\n", stateLabel, s.CwdPath, branch, worktreeInfo)
if s.Preview != "" {
lines := strings.Split(s.Preview, "\n")
for _, line := range lines {
fmt.Fprintf(w, " %s\n", line)
}
}
}
}
func stateColor(state SessionState, noColor bool) string {
if noColor {
return ""
}
switch state {
case Working:
return colorGreen
case NeedsInput:
return colorYellow
case Idle:
return colorGray
default:
return colorGray
}
}
func resetIfColor(noColor bool) string {
if noColor {
return ""
}
return colorReset
}