@@ -15,13 +15,6 @@ function uniqueSortedCommandNames(commands: Iterable<string>): string[] {
1515 ) ;
1616}
1717
18- export function getKnownCliCommandNames ( ) : string [ ] {
19- return uniqueSortedCommandNames ( [
20- ...getCoreCliCommandNames ( ) ,
21- ...getSubCliEntries ( ) . map ( ( entry ) => entry . name ) ,
22- ] ) ;
23- }
24-
2518export function levenshteinDistance ( left : string , right : string ) : number {
2619 if ( left === right ) {
2720 return 0 ;
@@ -52,37 +45,40 @@ export function levenshteinDistance(left: string, right: string): number {
5245 return previous [ right . length ] ?? 0 ;
5346}
5447
55- export function suggestCliCommands (
56- input : string ,
57- candidates : Iterable < string > = getKnownCliCommandNames ( ) ,
58- ) : string [ ] {
48+ export function formatCliCommandSuggestions ( input : string ) : string | undefined {
5949 const normalizedInput = input . trim ( ) . toLowerCase ( ) ;
6050 if ( ! normalizedInput ) {
61- return [ ] ;
51+ return undefined ;
6252 }
6353
64- const knownCommands = uniqueSortedCommandNames ( candidates ) ;
54+ const knownCommands = uniqueSortedCommandNames ( [
55+ ...getCoreCliCommandNames ( ) ,
56+ ...getSubCliEntries ( ) . map ( ( entry ) => entry . name ) ,
57+ ] ) ;
6558 const explicitAlias = EXPLICIT_COMMAND_ALIASES . get ( normalizedInput ) ;
6659 if ( explicitAlias && knownCommands . includes ( explicitAlias ) ) {
67- return [ explicitAlias ] ;
60+ return formatCliSuggestionLines ( [ explicitAlias ] ) ;
6861 }
62+ const suggestions = findCliCommandSuggestions ( normalizedInput , knownCommands ) ;
63+ if ( suggestions . length === 0 ) {
64+ return undefined ;
65+ }
66+ return formatCliSuggestionLines ( suggestions ) ;
67+ }
6968
70- const maxDistance = Math . max ( 1 , Math . floor ( normalizedInput . length * 0.4 ) ) ;
71- return knownCommands
72- . map ( ( command ) => ( { command, distance : levenshteinDistance ( normalizedInput , command ) } ) )
73- . filter ( ( { command, distance } ) => command !== normalizedInput && distance <= maxDistance )
69+ function findCliCommandSuggestions ( input : string , candidates : readonly string [ ] ) : string [ ] {
70+ const maxDistance = Math . max ( 1 , Math . floor ( input . length * 0.4 ) ) ;
71+ return candidates
72+ . map ( ( command ) => ( { command, distance : levenshteinDistance ( input , command ) } ) )
73+ . filter ( ( { command, distance } ) => command !== input && distance <= maxDistance )
7474 . toSorted (
7575 ( left , right ) => left . distance - right . distance || left . command . localeCompare ( right . command ) ,
7676 )
7777 . slice ( 0 , MAX_SUGGESTIONS )
7878 . map ( ( { command } ) => command ) ;
7979}
8080
81- export function formatCliCommandSuggestions ( input : string ) : string | undefined {
82- const suggestions = suggestCliCommands ( input ) ;
83- if ( suggestions . length === 0 ) {
84- return undefined ;
85- }
81+ function formatCliSuggestionLines ( suggestions : readonly string [ ] ) : string {
8682 const commandLines = suggestions
8783 . map ( ( command ) => ` ${ formatCliCommand ( `openclaw ${ command } ` ) } ` )
8884 . join ( "\n" ) ;
0 commit comments