@@ -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}
4344func 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)
46100var 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