package main import ( "flag" "fmt" "io" "log" "os" "time" tea "github.com/charmbracelet/bubbletea" ) // debugLog writes to a debug file var debugFile *os.File func debugLog(format string, args ...any) { if debugFile != nil { fmt.Fprintf(debugFile, format+"\n", args...) debugFile.Sync() } } func main() { serverAddr := flag.String("server", "127.0.0.1:9987", "TeamSpeak 3 Server Address") nickname := flag.String("nickname", "TUI-User", "Your nickname") debug := flag.Bool("debug", true, "Enable debug logging to file (default true)") flag.Parse() // Disable log output completely to prevent TUI corruption log.SetOutput(io.Discard) // Enable debug file logging if requested if *debug { var err error timestamp := time.Now().Format("20060102-150405") filename := fmt.Sprintf("tui-%s.log", timestamp) debugFile, err = os.Create(filename) if err == nil { defer debugFile.Close() debugLog("TUI Debug started at %s", timestamp) } } // Create the TUI model m := NewModel(*serverAddr, *nickname) // Create Bubble Tea program p := tea.NewProgram(m, tea.WithAltScreen()) // Set up log capture r, w, _ := os.Pipe() if debugFile != nil { log.SetOutput(io.MultiWriter(w, debugFile)) } else { log.SetOutput(w) } // Make sure logs have timestamp removed (TUI adds it if needed, or we keep it) log.SetFlags(log.Ltime) // Just time go func() { buf := make([]byte, 1024) for { n, err := r.Read(buf) if err != nil { break } if n > 0 { lines := string(buf[:n]) // Split by newline and send each line // Simple split, might need better buffering for partial lines but OK for debug p.Send(logMsg(lines)) } } }() // Run if _, err := p.Run(); err != nil { fmt.Fprintf(os.Stderr, "Error: %v\n", err) os.Exit(1) } }