package tui import ( "fmt" "regexp" "strings" "github.com/charmbracelet/lipgloss" ) var versionRegex = regexp.MustCompile(`\d+\.\d+\.\d+`) func extractVersion(s string) string { return versionRegex.FindString(s) } func (m Model) renderConfig() string { colWidth := m.width / 2 if colWidth < 30 { colWidth = 30 } var left, right strings.Builder left.WriteString(renderSectionWithIcon("Profile", "👤")) left.WriteString("\n") if m.config != nil { fields := []struct { label string value string }{ {"Name", m.config.Profile.Name}, {"Pseudo", m.config.Profile.Pseudo}, {"Email", m.config.Profile.Email}, {"Editor", m.config.Profile.Preferences.Editor}, {"Shell", m.config.Profile.Preferences.Shell}, {"Theme", m.config.Profile.Preferences.Theme}, {"Default AI", m.config.Profile.Preferences.DefaultAI}, } for _, f := range fields { left.WriteString(fmt.Sprintf(" %s %s\n", labelStyle.Render(f.label+":"), valueStyle.Render(f.value))) } if len(m.config.Profile.Languages) > 0 { left.WriteString(fmt.Sprintf(" %s %s\n", labelStyle.Render("Languages:"), valueStyle.Render(strings.Join(m.config.Profile.Languages, ", ")))) } } left.WriteString("\n") left.WriteString(renderSectionWithIcon("AI Providers", "◆")) left.WriteString("\n") if m.config != nil { for _, p := range m.config.AI.Providers { active := "" if p.Active { active = lipgloss.NewStyle().Foreground(primaryColor).Bold(true).Render(" ●") } keyStatus := itemMissingStyle.Render("no key") if p.APIKey != "" { keyStatus = itemOKStyle.Render("configured") } nameStyle := lipgloss.NewStyle().Foreground(textColor).Bold(true) left.WriteString(fmt.Sprintf(" %s %s key=%s%s\n", nameStyle.Render(p.Name), lipgloss.NewStyle().Foreground(dimColor).Render("model="+p.Model), keyStatus, active)) } } left.WriteString("\n") right.WriteString(renderSectionWithIcon("Terminal", "▶")) right.WriteString("\n") if m.config != nil { right.WriteString(fmt.Sprintf(" %s %v\n", labelStyle.Render("Custom Prompt:"), valueStyle.Render(fmt.Sprintf("%v", m.config.Terminal.CustomPrompt)))) right.WriteString(fmt.Sprintf(" %s %s\n", labelStyle.Render("Prompt Theme:"), valueStyle.Render(m.config.Terminal.PromptTheme))) right.WriteString(fmt.Sprintf(" %s %v\n", labelStyle.Render("Auto Update:"), valueStyle.Render(fmt.Sprintf("%v", m.config.Profile.Preferences.AutoUpdate)))) right.WriteString(fmt.Sprintf(" %s %v\n", labelStyle.Render("Check on Start:"), valueStyle.Render(fmt.Sprintf("%v", m.config.Profile.Preferences.CheckOnStart)))) } right.WriteString("\n") right.WriteString(renderSectionWithIcon("BMAD Method", "◈")) right.WriteString("\n") if m.config != nil { installed := itemMissingStyle.Render("no") if m.config.BMAD.Installed { installed = itemOKStyle.Render("yes") } right.WriteString(fmt.Sprintf(" %s %s\n", labelStyle.Render("Installed:"), installed)) right.WriteString(fmt.Sprintf(" %s %v\n", labelStyle.Render("Global:"), valueStyle.Render(fmt.Sprintf("%v", m.config.BMAD.Global)))) if m.config.BMAD.Version != "" { right.WriteString(fmt.Sprintf(" %s %s\n", labelStyle.Render("Version:"), valueStyle.Render(m.config.BMAD.Version))) } } right.WriteString("\n") right.WriteString(renderSectionWithIcon(fmt.Sprintf("Skills (%d)", len(m.skillList)), "⚡")) right.WriteString("\n") if len(m.skillList) > 0 { for _, s := range m.skillList { target := s.Target if target == "" { target = "both" } right.WriteString(fmt.Sprintf(" %s %s %s\n", lipgloss.NewStyle().Foreground(textColor).Render(s.Name), lipgloss.NewStyle().Foreground(primaryColor).Render("["+target+"]"), lipgloss.NewStyle().Foreground(dimColor).Render(s.Description))) } } else { right.WriteString(lipgloss.NewStyle().Foreground(mutedColor).Render(" No skills. Run `muyue skills init`.")) right.WriteString("\n") } leftCol := lipgloss.NewStyle().Width(colWidth).Render(left.String()) rightCol := lipgloss.NewStyle().Width(colWidth).Render(right.String()) return lipgloss.JoinHorizontal(lipgloss.Top, leftCol, rightCol) }