Skip to content

Commit f04c1d8

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 923833d commit f04c1d8

1 file changed

Lines changed: 54 additions & 17 deletions

File tree

cmd/lk/console_tui.go

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/charmbracelet/bubbles/textinput"
2828
tea "github.com/charmbracelet/bubbletea"
2929
"github.com/charmbracelet/lipgloss"
30+
"github.com/charmbracelet/x/ansi"
3031

3132
agent "github.com/livekit/protocol/livekit/agent"
3233

@@ -39,12 +40,13 @@ var (
3940
lkCyan = lipgloss.Color("#1fd5f9")
4041
lkPurple = lipgloss.Color("#8f83ff")
4142
lkGreen = lipgloss.Color("#6BCB77")
42-
lkRed = lipgloss.Color("#EF4444")
43+
lkRed = lipgloss.Color("#EF4444")
4344

44-
labelStyle = lipgloss.NewStyle().Foreground(lkPurple)
45-
cyanBoldStyle = lipgloss.NewStyle().Foreground(lkCyan).Bold(true)
46-
greenBoldStyle = lipgloss.NewStyle().Foreground(lkGreen).Bold(true)
47-
redBoldStyle = lipgloss.NewStyle().Foreground(lkRed).Bold(true)
45+
labelStyle = lipgloss.NewStyle().Foreground(lkPurple)
46+
cyanBoldStyle = lipgloss.NewStyle().Foreground(lkCyan).Bold(true)
47+
greenBoldStyle = lipgloss.NewStyle().Foreground(lkGreen).Bold(true)
48+
redBoldStyle = lipgloss.NewStyle().Foreground(lkRed).Bold(true)
49+
textModeBoxStyle = lipgloss.NewStyle().Background(lkPurple).Foreground(lipgloss.Color("#E6F7FF"))
4850
)
4951

5052
// Unicode block characters for frequency visualizer (matching Python console)
@@ -286,6 +288,51 @@ func (m consoleModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
286288
return m, nil
287289
}
288290

291+
func renderTextModeBox(width int, input string) string {
292+
if width <= 0 {
293+
width = 80
294+
}
295+
296+
var b strings.Builder
297+
b.WriteString(renderTextModeBoxLine(width, strings.Repeat("─", width)))
298+
b.WriteString("\n")
299+
b.WriteString(renderTextModeInputLine(width, input))
300+
b.WriteString("\n")
301+
b.WriteString(renderTextModeBoxLine(width, textModeStatusLine(width)))
302+
return b.String()
303+
}
304+
305+
// renderTextModeInputLine keeps the input on the normal terminal background
306+
// but paints the first and last column with the bar color so it reads as a
307+
// framed prompt bar.
308+
func renderTextModeInputLine(width int, input string) string {
309+
if width <= 2 {
310+
return renderTextModeBoxLine(width, input)
311+
}
312+
inner := width - 2
313+
input = ansi.Truncate(input, inner, "")
314+
pad := inner - lipgloss.Width(input)
315+
if pad < 0 {
316+
pad = 0
317+
}
318+
edge := textModeBoxStyle.Render(" ")
319+
return edge + input + strings.Repeat(" ", pad) + edge
320+
}
321+
322+
func renderTextModeBoxLine(width int, line string) string {
323+
line = ansi.Truncate(line, width, "")
324+
return textModeBoxStyle.Width(width).MaxWidth(width).Render(line)
325+
}
326+
327+
func textModeStatusLine(width int) string {
328+
label := "in text mode (-t)"
329+
labelWidth := lipgloss.Width(label)
330+
if width <= labelWidth {
331+
return label[:min(width, len(label))]
332+
}
333+
return strings.Repeat("─", width-labelWidth-1) + " " + label
334+
}
335+
289336
func (m *consoleModel) switchToAudio() tea.Cmd {
290337
if m.pipeline.HasAudio() {
291338
m.textMode = false
@@ -445,7 +492,7 @@ func (m *consoleModel) handleSessionEvent(ev *agent.AgentSessionEvent) []tea.Cmd
445492
if text := formatMetrics(msg.Metrics); text != "" {
446493
m.metricsText = text
447494
}
448-
}
495+
}
449496
cmds = append(cmds, tea.Println(formatChatItem(item)))
450497
}
451498

@@ -553,17 +600,7 @@ func (m consoleModel) View() string {
553600
frame := spinnerFrames[int(time.Now().UnixMilli()/80)%len(spinnerFrames)]
554601
b.WriteString(" " + dimStyle.Render(frame+" thinking"))
555602
} else {
556-
// ── Text input ──
557-
w := m.width
558-
if w <= 0 {
559-
w = 80
560-
}
561-
sep := dimStyle.Render(strings.Repeat("─", min(w, 80)))
562-
b.WriteString(sep)
563-
b.WriteString("\n")
564-
b.WriteString(m.textInput.View())
565-
b.WriteString("\n")
566-
b.WriteString(sep)
603+
b.WriteString(renderTextModeBox(m.width, m.textInput.View()))
567604
}
568605

569606
if m.audioError != "" {

0 commit comments

Comments
 (0)