1- import { createMemo } from "solid-js"
1+ import { createMemo , createResource } from "solid-js"
22import { DialogSelect , type DialogSelectRef } from "@tui/ui/dialog-select"
33import { type DialogContext } from "@tui/ui/dialog"
44import {
@@ -10,6 +10,11 @@ import {
1010} from "../keymap"
1111import { useTuiConfig } from "../context/tui-config"
1212import { useFrecency } from "./prompt/frecency"
13+ import { useLocal } from "@tui/context/local"
14+ import { useSync } from "@tui/context/sync"
15+ import { useRoute } from "@tui/context/route"
16+ import { useSDK } from "@tui/context/sdk"
17+ import { Locale } from "@/util/locale"
1318
1419type PaletteCommandEntry = ReturnType < OpenTuiKeymap [ "getCommandEntries" ] > [ number ]
1520
@@ -28,6 +33,11 @@ export function CommandPaletteDialog() {
2833 const config = useTuiConfig ( )
2934 const keymap = useTinycodeKeymap ( )
3035 const frecency = useFrecency ( )
36+ const local = useLocal ( )
37+ const sync = useSync ( )
38+ const route = useRoute ( )
39+ const sdk = useSDK ( )
40+
3141 const entries = useKeymapSelector ( ( keymap : OpenTuiKeymap ) => {
3242 const query = {
3343 namespace : "palette" ,
@@ -47,11 +57,12 @@ export function CommandPaletteDialog() {
4757 bindings : registeredBindings . get ( entry . command . name ) ?? entry . bindings ,
4858 } ) )
4959 } )
50- const options = createMemo ( ( ) =>
60+
61+ const commandOptions = createMemo ( ( ) =>
5162 entries ( ) . map ( ( entry ) => ( {
5263 title : typeof entry . command . title === "string" ? entry . command . title : entry . command . name ,
5364 description : typeof entry . command . desc === "string" ? entry . command . desc : undefined ,
54- category : typeof entry . command . category === "string" ? entry . command . category : undefined ,
65+ category : typeof entry . command . category === "string" ? entry . command . category : "Commands" ,
5566 footer : formatKeyBindings ( entry . bindings , config ) ,
5667 value : entry . command . name ,
5768 suggested : isSuggestedPaletteCommand ( entry ) ,
@@ -64,19 +75,88 @@ export function CommandPaletteDialog() {
6475 } ) ) ,
6576 )
6677
78+ const currentAgent = createMemo ( ( ) => local . agent . current ( ) ?. name )
79+ const agentOptions = createMemo ( ( ) =>
80+ local . agent
81+ . list ( )
82+ . filter ( ( a ) => ! a . hidden && a . name !== currentAgent ( ) )
83+ . map ( ( agent ) => ( {
84+ title : agent . name ,
85+ description : agent . description ? Locale . truncate ( agent . description , 60 ) : undefined ,
86+ category : "Agents" ,
87+ footer : agent . name === currentAgent ( ) ? "current" : "" ,
88+ value : `agent:${ agent . name } ` ,
89+ suggested : false ,
90+ frecencyScore : frecency . getFrecency ( "agents" , agent . name ) ,
91+ onSelect : ( dialog : DialogContext ) => {
92+ dialog . clear ( )
93+ frecency . updateFrecency ( "agents" , agent . name )
94+ local . agent . set ( agent . name )
95+ } ,
96+ } ) ) ,
97+ )
98+
99+ const currentSessionID = createMemo ( ( ) => ( route . data . type === "session" ? route . data . sessionID : undefined ) )
100+ const sessionOptions = createMemo ( ( ) =>
101+ sync . data . session
102+ . filter ( ( s ) => ! s . parentID && s . id !== currentSessionID ( ) )
103+ . toSorted ( ( a , b ) => b . time . updated - a . time . updated )
104+ . slice ( 0 , 8 )
105+ . map ( ( session ) => ( {
106+ title : session . title ,
107+ description : Locale . time ( session . time . updated ) ,
108+ category : "Sessions" ,
109+ footer : "" ,
110+ value : `session:${ session . id } ` ,
111+ suggested : false ,
112+ frecencyScore : frecency . getFrecency ( "sessions" , session . id ) ,
113+ onSelect : ( dialog : DialogContext ) => {
114+ dialog . clear ( )
115+ frecency . updateFrecency ( "sessions" , session . id )
116+ route . navigate ( { type : "session" , sessionID : session . id } )
117+ } ,
118+ } ) ) ,
119+ )
120+
121+ const [ skills ] = createResource ( async ( ) => {
122+ const result = await sdk . client . app . skills ( )
123+ return result . data ?? [ ]
124+ } )
125+ const skillOptions = createMemo ( ( ) =>
126+ ( skills ( ) ?? [ ] ) . map ( ( skill ) => ( {
127+ title : `/${ skill . name } ` ,
128+ description : skill . description ?. replace ( / \s + / g, " " ) . trim ( ) ,
129+ category : "Skills" ,
130+ footer : "" ,
131+ value : `skill:${ skill . name } ` ,
132+ suggested : false ,
133+ frecencyScore : frecency . getFrecency ( "skills" , skill . name ) ,
134+ onSelect : ( dialog : DialogContext ) => {
135+ dialog . clear ( )
136+ frecency . updateFrecency ( "skills" , skill . name )
137+ keymap . dispatchCommand ( "prompt.skills" )
138+ } ,
139+ } ) ) ,
140+ )
141+
67142 let ref : DialogSelectRef < string >
68143 const list = ( ) => {
69- if ( ref ?. filter ) return options ( )
70- const suggested = options ( )
144+ if ( ref ?. filter ) {
145+ return [ ...commandOptions ( ) , ...agentOptions ( ) , ...sessionOptions ( ) , ...skillOptions ( ) ]
146+ }
147+ const suggested = commandOptions ( )
71148 . filter ( ( option ) => option . suggested )
72149 . map ( ( option ) => ( {
73150 ...option ,
74151 value : `suggested:${ option . value } ` ,
75152 category : "Suggested" ,
76153 } ) )
77- const rest = [ ...options ( ) ] . sort ( ( a , b ) => b . frecencyScore - a . frecencyScore )
78- return [ ...suggested , ...rest ]
154+ const commands = [ ...commandOptions ( ) ] . sort ( ( a , b ) => b . frecencyScore - a . frecencyScore )
155+ const agents = [ ...agentOptions ( ) ] . sort ( ( a , b ) => b . frecencyScore - a . frecencyScore )
156+ const sessions = [ ...sessionOptions ( ) ]
157+ const skillsList = [ ...skillOptions ( ) ] . sort ( ( a , b ) => b . frecencyScore - a . frecencyScore )
158+ return [ ...suggested , ...commands , ...agents , ...sessions , ...skillsList ]
79159 }
80160
81- return < DialogSelect ref = { ( value ) => ( ref = value ) } title = "Commands " options = { list ( ) } />
161+ return < DialogSelect ref = { ( value ) => ( ref = value ) } title = "Command Palette " options = { list ( ) } flat />
82162}
0 commit comments