- 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>
99 lines
2.0 KiB
Go
99 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func main() {
|
|
noColor := flag.Bool("no-color", false, "Disable colored output")
|
|
flag.Parse()
|
|
|
|
if os.Getenv("NO_COLOR") != "" {
|
|
*noColor = true
|
|
}
|
|
|
|
args := flag.Args()
|
|
// Also check for --no-color after subcommand (flag stops at first non-flag)
|
|
var filteredArgs []string
|
|
for _, arg := range args {
|
|
if arg == "--no-color" {
|
|
*noColor = true
|
|
} else {
|
|
filteredArgs = append(filteredArgs, arg)
|
|
}
|
|
}
|
|
|
|
if len(filteredArgs) == 0 || filteredArgs[0] != "list" {
|
|
fmt.Fprintf(os.Stderr, "Usage: vmux list [--no-color]\n")
|
|
os.Exit(1)
|
|
}
|
|
|
|
processes, err := FindClaudeProcesses("/proc")
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error scanning processes: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
claudeDir := filepath.Join(os.Getenv("HOME"), ".claude", "projects")
|
|
now := time.Now()
|
|
var sessions []Session
|
|
|
|
for _, proc := range processes {
|
|
jsonlPath, messages, err := FindSessionForProcess(claudeDir, proc)
|
|
if err != nil {
|
|
sessions = append(sessions, Session{
|
|
Process: proc,
|
|
State: Unknown,
|
|
CwdPath: proc.Cwd,
|
|
})
|
|
continue
|
|
}
|
|
|
|
state := DetectState(messages, now)
|
|
preview := ExtractPreview(messages)
|
|
|
|
var sessionID, gitBranch string
|
|
for _, msg := range messages {
|
|
if msg.SessionID != "" {
|
|
sessionID = msg.SessionID
|
|
}
|
|
if msg.GitBranch != "" {
|
|
gitBranch = msg.GitBranch
|
|
}
|
|
}
|
|
|
|
worktree := resolveWorktree(proc.Cwd)
|
|
|
|
_ = jsonlPath
|
|
|
|
sessions = append(sessions, Session{
|
|
Process: proc,
|
|
SessionID: sessionID,
|
|
GitBranch: gitBranch,
|
|
State: state,
|
|
Preview: preview,
|
|
CwdPath: proc.Cwd,
|
|
Worktree: worktree,
|
|
})
|
|
}
|
|
|
|
DisplaySessions(os.Stdout, sessions, *noColor)
|
|
}
|
|
|
|
// resolveWorktree uses git to find the worktree root.
|
|
// Falls back to cwd if git fails (not a git repo).
|
|
func resolveWorktree(cwd string) string {
|
|
cmd := exec.Command("git", "-C", cwd, "rev-parse", "--show-toplevel")
|
|
out, err := cmd.Output()
|
|
if err != nil {
|
|
return cwd
|
|
}
|
|
return strings.TrimSpace(string(out))
|
|
}
|