@@ -132,7 +132,7 @@ func (a *App) syncBrowserView() {
132132 // Ensure miller has current dimensions so scroll calculations in
133133 // Update() work correctly (Render operates on a value copy).
134134 if a .height > 0 {
135- contentH := max (5 , a .height - chromeHeight )
135+ contentH := max (5 , a .height - chromeHeight - 1 ) // -1 for LLM anchor line
136136 bv .miller .SetSize (a .width , contentH )
137137 }
138138 a .views .SetBase (bv )
@@ -170,6 +170,13 @@ func (a App) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
170170 a .views .Pop ()
171171 return a , nil
172172
173+ case PaletteExecMsg :
174+ a .views .Pop ()
175+ if msg .Key != "" {
176+ return a , a .dispatchPaletteKey (msg .Key )
177+ }
178+ return a , nil
179+
173180 // --- View creation messages ---
174181 case OpenOverlayMsg :
175182 ov := NewOverlayView (msg .Title , msg .Content , a .width , a .height , msg .Opts )
@@ -452,7 +459,7 @@ func (a App) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
452459 // scroll calculations (Render operates on a copy and cannot
453460 // persist dimensions back).
454461 if bv , ok := a .views .Active ().(BrowserView ); ok {
455- contentH := a .height - chromeHeight
462+ contentH := a .height - chromeHeight - 1 // -1 for LLM anchor line
456463 if contentH < 5 {
457464 contentH = 5
458465 }
@@ -474,7 +481,7 @@ func (a App) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
474481 bv .allNodes = msg .Nodes
475482 bv .miller = tab .Miller
476483 if a .height > 0 {
477- contentH := max (5 , a .height - chromeHeight )
484+ contentH := max (5 , a .height - chromeHeight - 1 ) // -1 for LLM anchor line
478485 bv .miller .SetSize (a .width , contentH )
479486 }
480487 a .views .SetBase (bv )
@@ -727,6 +734,11 @@ func (a *App) handleBrowserAppKeys(msg tea.KeyMsg) tea.Cmd {
727734 a .views .Push (ov )
728735 return handledCmd
729736
737+ case ":" :
738+ cp := NewCommandPaletteView (a .width , a .height )
739+ a .views .Push (cp )
740+ return handledCmd
741+
730742 case "c" :
731743 cv := NewCompareView ()
732744 cv .mxcliPath = a .mxcliPath
@@ -820,8 +832,8 @@ func (a App) View() string {
820832 }
821833 }
822834
823- // Content area
824- contentH := a .height - chromeHeight
835+ // Content area (chromeHeight + 1 for the LLM anchor line)
836+ contentH := a .height - chromeHeight - 1
825837 if contentH < 5 {
826838 contentH = 5
827839 }
@@ -849,7 +861,11 @@ func (a App) View() string {
849861 a .statusBar .SetViewDepth (a .views .Depth (), viewModeNames )
850862 statusLine := StatusBarStyle .Width (a .width ).Render (a .statusBar .View (a .width ))
851863
852- rendered := tabLine + "\n " + content + "\n " + hintLine + "\n " + statusLine
864+ // LLM anchor: machine-readable command list (Faint, not visible to users in practice)
865+ anchorStyle := lipgloss .NewStyle ().Foreground (MutedColor ).Faint (true )
866+ anchorLine := anchorStyle .Render ("[mxcli:commands] h:back l:open Space:jump /:filter b:bson c:compare d:diagram z:zen Tab:toggle x:exec r:refresh y:copy !:check ]e:next-error [e:prev-error t:tab T:new-tab W:close-tab 1-9:switch ?:help ::palette" )
867+
868+ rendered := anchorLine + "\n " + tabLine + "\n " + content + "\n " + hintLine + "\n " + statusLine
853869
854870 if a .showHelp {
855871 helpView := renderHelp (a .width , a .height )
@@ -939,6 +955,21 @@ func (a App) collectViewModeNames() []string {
939955 return a .views .ModeNames ()
940956}
941957
958+ // dispatchPaletteKey converts a palette command key string into a synthetic
959+ // tea.KeyMsg and re-dispatches it through Update.
960+ func (a App ) dispatchPaletteKey (key string ) tea.Cmd {
961+ var keyMsg tea.KeyMsg
962+ switch key {
963+ case " " :
964+ keyMsg = tea.KeyMsg {Type : tea .KeySpace }
965+ case "Tab" :
966+ keyMsg = tea.KeyMsg {Type : tea .KeyTab }
967+ default :
968+ keyMsg = tea.KeyMsg {Type : tea .KeyRunes , Runes : []rune (key )}
969+ }
970+ return func () tea.Msg { return keyMsg }
971+ }
972+
942973// inferBsonType maps tree node types to valid bson object types.
943974func inferBsonType (nodeType string ) string {
944975 switch strings .ToLower (nodeType ) {
0 commit comments