Skip to content

Commit aa12e80

Browse files
committed
feat(console): style the text-mode prompt bar
Render the text-mode input as a framed prompt bar: a top rule and a bottom status line showing "in text mode (-t)" in the corner, colored to match the agent status text. The input line keeps the normal terminal background.
1 parent deb98ff commit aa12e80

1 file changed

Lines changed: 55 additions & 11 deletions

File tree

cmd/lk/console_tui.go

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/charmbracelet/bubbles/textinput"
2626
tea "github.com/charmbracelet/bubbletea"
2727
"github.com/charmbracelet/lipgloss"
28+
"github.com/charmbracelet/x/ansi"
2829

2930
agent "github.com/livekit/protocol/livekit/agent"
3031

@@ -42,6 +43,59 @@ func greenBoldStyle() lipgloss.Style {
4243
}
4344
func redBoldStyle() lipgloss.Style { return lipgloss.NewStyle().Foreground(util.Error()).Bold(true) }
4445

46+
// textModeBoxStyle is the prompt-bar color, matched to the agent status text
47+
// (labelStyle / "Shutting down agent...").
48+
func textModeBoxStyle() lipgloss.Style {
49+
return lipgloss.NewStyle().Background(util.Accent()).Foreground(lipgloss.Color("#E6F7FF"))
50+
}
51+
52+
// renderTextModeBox draws the framed prompt bar: a top rule, the input line,
53+
// and a bottom status line with "in text mode (-t)" in the corner.
54+
func renderTextModeBox(width int, input string) string {
55+
if width <= 0 {
56+
width = 80
57+
}
58+
59+
var b strings.Builder
60+
b.WriteString(renderTextModeBoxLine(width, strings.Repeat("─", width)))
61+
b.WriteString("\n")
62+
b.WriteString(renderTextModeInputLine(width, input))
63+
b.WriteString("\n")
64+
b.WriteString(renderTextModeBoxLine(width, textModeStatusLine(width)))
65+
return b.String()
66+
}
67+
68+
func renderTextModeBoxLine(width int, line string) string {
69+
line = ansi.Truncate(line, width, "")
70+
return textModeBoxStyle().Width(width).MaxWidth(width).Render(line)
71+
}
72+
73+
// renderTextModeInputLine keeps the input on the normal terminal background
74+
// but paints the first and last column with the bar color so it reads as a
75+
// framed prompt bar.
76+
func renderTextModeInputLine(width int, input string) string {
77+
if width <= 2 {
78+
return renderTextModeBoxLine(width, input)
79+
}
80+
inner := width - 2
81+
input = ansi.Truncate(input, inner, "")
82+
pad := inner - lipgloss.Width(input)
83+
if pad < 0 {
84+
pad = 0
85+
}
86+
edge := textModeBoxStyle().Render(" ")
87+
return edge + input + strings.Repeat(" ", pad) + edge
88+
}
89+
90+
func textModeStatusLine(width int) string {
91+
label := "in text mode (-t)"
92+
labelWidth := lipgloss.Width(label)
93+
if width <= labelWidth {
94+
return label[:min(width, len(label))]
95+
}
96+
return strings.Repeat("─", width-labelWidth-1) + " " + label
97+
}
98+
4599
// Unicode block characters for frequency visualizer (matching Python console)
46100
var blocks = []string{"▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"}
47101

@@ -549,17 +603,7 @@ func (m consoleModel) View() string {
549603
b.WriteString(" ")
550604
b.WriteString(dimStyle.Render(frame + " thinking"))
551605
} else {
552-
// ── Text input ──
553-
w := m.width
554-
if w <= 0 {
555-
w = 80
556-
}
557-
sep := dimStyle.Render(strings.Repeat("─", min(w, 80)))
558-
b.WriteString(sep)
559-
b.WriteString("\n")
560-
b.WriteString(m.textInput.View())
561-
b.WriteString("\n")
562-
b.WriteString(sep)
606+
b.WriteString(renderTextModeBox(m.width, m.textInput.View()))
563607
}
564608

565609
if m.audioError != "" {

0 commit comments

Comments
 (0)