Skip to content

Commit 51133e6

Browse files
committed
Sort command palette actions alphabetically within each group
Reorder all built-in command groups (Session, Settings, Feedback) so items appear alphabetically by label. Dynamic groups (Agent Commands, MCP Prompts, Skills) are now sorted at runtime via a sortByLabel helper. Assisted-By: cagent
1 parent 6b9afc7 commit 51133e6

1 file changed

Lines changed: 116 additions & 107 deletions

File tree

pkg/tui/commands/commands.go

Lines changed: 116 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package commands
33
import (
44
"context"
55
"fmt"
6+
"slices"
67
"strings"
78

89
tea "charm.land/bubbletea/v2"
@@ -37,69 +38,13 @@ type Item struct {
3738
func builtInSessionCommands() []Item {
3839
cmds := []Item{
3940
{
40-
ID: "session.exit",
41-
Label: "Exit",
42-
SlashCommand: "/exit",
43-
Description: "Exit the application",
44-
Category: "Session",
45-
Execute: func(string) tea.Cmd {
46-
return core.CmdHandler(messages.ExitSessionMsg{})
47-
},
48-
},
49-
{
50-
ID: "session.new",
51-
Label: "New",
52-
SlashCommand: "/new",
53-
Description: "Start a new conversation",
54-
Category: "Session",
55-
Execute: func(string) tea.Cmd {
56-
return core.CmdHandler(messages.NewSessionMsg{})
57-
},
58-
},
59-
{
60-
ID: "session.history",
61-
Label: "Sessions",
62-
SlashCommand: "/sessions",
63-
Description: "Browse and load past sessions",
64-
Category: "Session",
65-
Execute: func(string) tea.Cmd {
66-
return core.CmdHandler(messages.OpenSessionBrowserMsg{})
67-
},
68-
},
69-
{
70-
ID: "session.star",
71-
Label: "Star",
72-
SlashCommand: "/star",
73-
Description: "Toggle star on current session",
74-
Category: "Session",
75-
Execute: func(string) tea.Cmd {
76-
return core.CmdHandler(messages.ToggleSessionStarMsg{})
77-
},
78-
},
79-
{
80-
ID: "session.title",
81-
Label: "Title",
82-
SlashCommand: "/title",
83-
Description: "Set or regenerate session title (usage: /title [new title])",
41+
ID: "session.attach",
42+
Label: "Attach",
43+
SlashCommand: "/attach",
44+
Description: "Attach a file to your message (usage: /attach [path])",
8445
Category: "Session",
8546
Execute: func(arg string) tea.Cmd {
86-
arg = strings.TrimSpace(arg)
87-
if arg == "" {
88-
// No argument: regenerate title
89-
return core.CmdHandler(messages.RegenerateTitleMsg{})
90-
}
91-
// With argument: set title
92-
return core.CmdHandler(messages.SetSessionTitleMsg{Title: arg})
93-
},
94-
},
95-
{
96-
ID: "session.model",
97-
Label: "Model",
98-
SlashCommand: "/model",
99-
Description: "Change the model for the current agent",
100-
Category: "Session",
101-
Execute: func(string) tea.Cmd {
102-
return core.CmdHandler(messages.OpenModelPickerMsg{})
47+
return core.CmdHandler(messages.AttachFileMsg{FilePath: arg})
10348
},
10449
},
10550
{
@@ -132,6 +77,16 @@ func builtInSessionCommands() []Item {
13277
return core.CmdHandler(messages.CopyLastResponseToClipboardMsg{})
13378
},
13479
},
80+
{
81+
ID: "session.cost",
82+
Label: "Cost",
83+
SlashCommand: "/cost",
84+
Description: "Show detailed cost breakdown for this session",
85+
Category: "Session",
86+
Execute: func(string) tea.Cmd {
87+
return core.CmdHandler(messages.ShowCostDialogMsg{})
88+
},
89+
},
13590
{
13691
ID: "session.eval",
13792
Label: "Eval",
@@ -142,6 +97,16 @@ func builtInSessionCommands() []Item {
14297
return core.CmdHandler(messages.EvalSessionMsg{Filename: arg})
14398
},
14499
},
100+
{
101+
ID: "session.exit",
102+
Label: "Exit",
103+
SlashCommand: "/exit",
104+
Description: "Exit the application",
105+
Category: "Session",
106+
Execute: func(string) tea.Cmd {
107+
return core.CmdHandler(messages.ExitSessionMsg{})
108+
},
109+
},
145110
{
146111
ID: "session.export",
147112
Label: "Export",
@@ -153,23 +118,43 @@ func builtInSessionCommands() []Item {
153118
},
154119
},
155120
{
156-
ID: "session.yolo",
157-
Label: "Yolo",
158-
SlashCommand: "/yolo",
159-
Description: "Toggle automatic approval of tool calls",
121+
ID: "session.model",
122+
Label: "Model",
123+
SlashCommand: "/model",
124+
Description: "Change the model for the current agent",
160125
Category: "Session",
161126
Execute: func(string) tea.Cmd {
162-
return core.CmdHandler(messages.ToggleYoloMsg{})
127+
return core.CmdHandler(messages.OpenModelPickerMsg{})
163128
},
164129
},
165130
{
166-
ID: "session.think",
167-
Label: "Think",
168-
SlashCommand: "/think",
169-
Description: "Toggle thinking/reasoning mode",
131+
ID: "session.new",
132+
Label: "New",
133+
SlashCommand: "/new",
134+
Description: "Start a new conversation",
170135
Category: "Session",
171136
Execute: func(string) tea.Cmd {
172-
return core.CmdHandler(messages.ToggleThinkingMsg{})
137+
return core.CmdHandler(messages.NewSessionMsg{})
138+
},
139+
},
140+
{
141+
ID: "session.permissions",
142+
Label: "Permissions",
143+
SlashCommand: "/permissions",
144+
Description: "Show tool permission rules for this session",
145+
Category: "Session",
146+
Execute: func(string) tea.Cmd {
147+
return core.CmdHandler(messages.ShowPermissionsDialogMsg{})
148+
},
149+
},
150+
{
151+
ID: "session.history",
152+
Label: "Sessions",
153+
SlashCommand: "/sessions",
154+
Description: "Browse and load past sessions",
155+
Category: "Session",
156+
Execute: func(string) tea.Cmd {
157+
return core.CmdHandler(messages.OpenSessionBrowserMsg{})
173158
},
174159
},
175160
{
@@ -183,33 +168,49 @@ func builtInSessionCommands() []Item {
183168
},
184169
},
185170
{
186-
ID: "session.cost",
187-
Label: "Cost",
188-
SlashCommand: "/cost",
189-
Description: "Show detailed cost breakdown for this session",
171+
ID: "session.star",
172+
Label: "Star",
173+
SlashCommand: "/star",
174+
Description: "Toggle star on current session",
190175
Category: "Session",
191176
Execute: func(string) tea.Cmd {
192-
return core.CmdHandler(messages.ShowCostDialogMsg{})
177+
return core.CmdHandler(messages.ToggleSessionStarMsg{})
193178
},
194179
},
195180
{
196-
ID: "session.permissions",
197-
Label: "Permissions",
198-
SlashCommand: "/permissions",
199-
Description: "Show tool permission rules for this session",
181+
ID: "session.think",
182+
Label: "Think",
183+
SlashCommand: "/think",
184+
Description: "Toggle thinking/reasoning mode",
200185
Category: "Session",
201186
Execute: func(string) tea.Cmd {
202-
return core.CmdHandler(messages.ShowPermissionsDialogMsg{})
187+
return core.CmdHandler(messages.ToggleThinkingMsg{})
203188
},
204189
},
205190
{
206-
ID: "session.attach",
207-
Label: "Attach",
208-
SlashCommand: "/attach",
209-
Description: "Attach a file to your message (usage: /attach [path])",
191+
ID: "session.title",
192+
Label: "Title",
193+
SlashCommand: "/title",
194+
Description: "Set or regenerate session title (usage: /title [new title])",
210195
Category: "Session",
211196
Execute: func(arg string) tea.Cmd {
212-
return core.CmdHandler(messages.AttachFileMsg{FilePath: arg})
197+
arg = strings.TrimSpace(arg)
198+
if arg == "" {
199+
// No argument: regenerate title
200+
return core.CmdHandler(messages.RegenerateTitleMsg{})
201+
}
202+
// With argument: set title
203+
return core.CmdHandler(messages.SetSessionTitleMsg{Title: arg})
204+
},
205+
},
206+
{
207+
ID: "session.yolo",
208+
Label: "Yolo",
209+
SlashCommand: "/yolo",
210+
Description: "Toggle automatic approval of tool calls",
211+
Category: "Session",
212+
Execute: func(string) tea.Cmd {
213+
return core.CmdHandler(messages.ToggleYoloMsg{})
213214
},
214215
},
215216
}
@@ -224,16 +225,6 @@ func builtInSessionCommands() []Item {
224225

225226
func builtInSettingsCommands() []Item {
226227
return []Item{
227-
{
228-
ID: "settings.theme",
229-
Label: "Theme",
230-
SlashCommand: "/theme",
231-
Description: "Change the color theme",
232-
Category: "Settings",
233-
Execute: func(string) tea.Cmd {
234-
return core.CmdHandler(messages.OpenThemePickerMsg{})
235-
},
236-
},
237228
{
238229
ID: "settings.split-diff",
239230
Label: "Split Diff",
@@ -244,32 +235,50 @@ func builtInSettingsCommands() []Item {
244235
return core.CmdHandler(messages.ToggleSplitDiffMsg{})
245236
},
246237
},
238+
{
239+
ID: "settings.theme",
240+
Label: "Theme",
241+
SlashCommand: "/theme",
242+
Description: "Change the color theme",
243+
Category: "Settings",
244+
Execute: func(string) tea.Cmd {
245+
return core.CmdHandler(messages.OpenThemePickerMsg{})
246+
},
247+
},
247248
}
248249
}
249250

250251
func builtInFeedbackCommands() []Item {
251252
return []Item{
252253
{
253-
ID: "feedback.bug",
254-
Label: "Report Bug",
255-
Description: "Report a bug or issue",
254+
ID: "feedback.feedback",
255+
Label: "Give Feedback",
256+
Description: "Provide feedback about cagent",
256257
Category: "Feedback",
257258
Execute: func(string) tea.Cmd {
258-
return core.CmdHandler(messages.OpenURLMsg{URL: "https://github.com/docker/cagent/issues/new/choose"})
259+
return core.CmdHandler(messages.OpenURLMsg{URL: feedback.Link})
259260
},
260261
},
261262
{
262-
ID: "feedback.feedback",
263-
Label: "Give Feedback",
264-
Description: "Provide feedback about cagent",
263+
ID: "feedback.bug",
264+
Label: "Report Bug",
265+
Description: "Report a bug or issue",
265266
Category: "Feedback",
266267
Execute: func(string) tea.Cmd {
267-
return core.CmdHandler(messages.OpenURLMsg{URL: feedback.Link})
268+
return core.CmdHandler(messages.OpenURLMsg{URL: "https://github.com/docker/cagent/issues/new/choose"})
268269
},
269270
},
270271
}
271272
}
272273

274+
// sortByLabel returns items sorted alphabetically by label.
275+
func sortByLabel(items []Item) []Item {
276+
slices.SortFunc(items, func(a, b Item) int {
277+
return strings.Compare(strings.ToLower(a.Label), strings.ToLower(b.Label))
278+
})
279+
return items
280+
}
281+
273282
// BuildCommandCategories builds the list of command categories for the command palette
274283
func BuildCommandCategories(ctx context.Context, application *app.App) []Category {
275284
// Get session commands and filter based on model capabilities
@@ -323,7 +332,7 @@ func BuildCommandCategories(ctx context.Context, application *app.App) []Categor
323332

324333
categories = append(categories, Category{
325334
Name: "Agent Commands",
326-
Commands: commands,
335+
Commands: sortByLabel(commands),
327336
})
328337
}
329338

@@ -395,7 +404,7 @@ func BuildCommandCategories(ctx context.Context, application *app.App) []Categor
395404

396405
categories = append(categories, Category{
397406
Name: "MCP Prompts",
398-
Commands: mcpCommands,
407+
Commands: sortByLabel(mcpCommands),
399408
})
400409
}
401410

@@ -425,7 +434,7 @@ func BuildCommandCategories(ctx context.Context, application *app.App) []Categor
425434

426435
categories = append(categories, Category{
427436
Name: "Skills",
428-
Commands: skillCommands,
437+
Commands: sortByLabel(skillCommands),
429438
})
430439
}
431440

0 commit comments

Comments
 (0)