@@ -397,10 +397,17 @@ export class CLI {
397397 const slashCommands = getSlashCommands ( )
398398 const currentInput = line . substring ( 1 ) // Text after '/'
399399
400- const matches = slashCommands
401- . map ( ( cmd ) => cmd . baseCommand ) // Get base command strings
402- . filter ( ( cmdName ) => cmdName && cmdName . startsWith ( currentInput ) )
403- . map ( ( cmdName ) => `/${ cmdName } ` ) // Add back the slash for display
400+ // Get all command names (base commands + aliases) that match the input
401+ const allCommandNames = slashCommands . flatMap ( ( cmd ) => [
402+ cmd . baseCommand ,
403+ ...( cmd . aliases || [ ] ) ,
404+ ] )
405+ const matches = allCommandNames
406+ . filter (
407+ ( cmdName ) : cmdName is string =>
408+ ! ! cmdName && cmdName . startsWith ( currentInput ) ,
409+ )
410+ . map ( ( cmdName ) => `/${ cmdName } ` )
404411
405412 if ( matches . length > 0 ) {
406413 return [ matches , line ] // Return all matches and the full line typed so far
@@ -704,7 +711,23 @@ export class CLI {
704711 * @param command The command to check (without leading slash)
705712 */
706713 private isKnownSlashCommand ( command : string ) : boolean {
707- return getSlashCommands ( ) . some ( ( cmd ) => cmd . baseCommand === command )
714+ return getSlashCommands ( ) . some (
715+ ( cmd ) => cmd . baseCommand === command || cmd . aliases ?. includes ( command ) ,
716+ )
717+ }
718+
719+ /**
720+ * Checks if input matches a command (base command or any of its aliases)
721+ * @param input The input to check
722+ * @param baseCommand The base command to look for
723+ */
724+ private isCommandOrAlias ( input : string , baseCommand : string ) : boolean {
725+ const commandInfo = interactiveCommandDetails . find (
726+ ( cmd ) => cmd . baseCommand === baseCommand ,
727+ )
728+ return (
729+ input === baseCommand || ( commandInfo ?. aliases ?. includes ( input ) ?? false )
730+ )
708731 }
709732
710733 /**
@@ -741,15 +764,14 @@ export class CLI {
741764 const message = costModeMatch [ 2 ] ?. trim ( ) || ''
742765 const hasSlash = userInput . startsWith ( '/' )
743766
744- // Check if this command requires a slash for local processing
745767 const commandInfo = interactiveCommandDetails . find (
746768 ( cmd ) => cmd . baseCommand === mode ,
747769 )
748770 const requiresSlash = commandInfo ?. requireSlash ?? false
749771
750772 // If command requires slash but no slash provided, forward to backend
751773 if ( requiresSlash && ! hasSlash ) {
752- return userInput // Forward to backend
774+ return userInput
753775 }
754776
755777 // Track the cost mode command usage
@@ -789,16 +811,14 @@ export class CLI {
789811
790812 if ( ! message ) {
791813 this . freshPrompt ( )
792- return null // Fully handled, no message to forward
814+ return null
793815 }
794816
795- // Return the message part to be processed as user input
796817 return message
797818 }
798819
799- // Handle empty slash command
800820 if ( userInput === '/' ) {
801- return userInput // Let it be processed as a prompt
821+ return userInput
802822 }
803823
804824 // Track slash command usage if it starts with '/'
@@ -819,17 +839,17 @@ export class CLI {
819839 } )
820840 }
821841
822- if ( cleanInput === 'help' || cleanInput === 'h' ) {
842+ if ( this . isCommandOrAlias ( cleanInput , 'help' ) ) {
823843 displayMenu ( )
824844 this . freshPrompt ( )
825845 return null
826846 }
827- if ( cleanInput === 'login' || cleanInput === 'signin' ) {
847+ if ( this . isCommandOrAlias ( cleanInput , 'login' ) ) {
828848 await Client . getInstance ( ) . login ( )
829849 checkpointManager . clearCheckpoints ( )
830850 return null
831851 }
832- if ( cleanInput === 'logout' || cleanInput === 'signout' ) {
852+ if ( this . isCommandOrAlias ( cleanInput , 'logout' ) ) {
833853 await Client . getInstance ( ) . logout ( )
834854 this . freshPrompt ( )
835855 return null
@@ -854,11 +874,11 @@ export class CLI {
854874 return null
855875 }
856876
857- if ( cleanInput === 'usage' || cleanInput === 'credits' ) {
877+ if ( this . isCommandOrAlias ( cleanInput , 'usage' ) ) {
858878 await Client . getInstance ( ) . getUsage ( )
859879 return null
860880 }
861- if ( cleanInput === 'quit' || cleanInput === ' exit' || cleanInput === 'q' ) {
881+ if ( this . isCommandOrAlias ( cleanInput , ' exit') ) {
862882 await this . handleExit ( )
863883 return null
864884 }
@@ -886,74 +906,74 @@ export class CLI {
886906 this . freshPrompt ( )
887907 return null
888908 }
889- if ( [ 'diff' , 'doff' , 'dif' , 'iff' , 'd' ] . includes ( cleanInput ) ) {
909+ if ( this . isCommandOrAlias ( cleanInput , 'diff' ) ) {
890910 handleDiff ( )
891911 this . freshPrompt ( )
892912 return null
893913 }
894- if (
895- cleanInput === 'uuddlrlrba' ||
896- cleanInput === 'konami' ||
897- cleanInput === 'codebuffy'
898- ) {
914+ if ( this . isCommandOrAlias ( cleanInput , 'konami' ) ) {
899915 showEasterEgg ( this . freshPrompt . bind ( this ) )
900916 return null
901917 }
902918
903- // Handle subagent command
904- if ( cleanInput . startsWith ( 'subagent ' ) ) {
905- const agentId = cleanInput . substring ( 'subagent ' . length ) . trim ( )
919+ // Handle trace command (with alternate words support)
920+ const [ commandBase ] = cleanInput . split ( ' ' )
921+ if ( this . isCommandOrAlias ( commandBase , 'trace' ) ) {
922+ const spaceIndex = cleanInput . indexOf ( ' ' )
923+ if ( spaceIndex > 0 ) {
924+ // Handle trace with ID
925+ const agentId = cleanInput . substring ( spaceIndex + 1 ) . trim ( )
926+
927+ if ( ! agentId ) {
928+ console . log (
929+ yellow (
930+ `Please provide a trace ID. Usage: ${ commandBase } <trace-id>` ,
931+ ) ,
932+ )
933+ const recentSubagents = getRecentSubagents ( 10 )
934+ displaySubagentList ( recentSubagents )
935+ if ( recentSubagents . length === 0 ) {
936+ // Give control back to user when no subagents exist
937+ this . freshPrompt ( )
938+ } else {
939+ // Pre-fill the prompt with the command for easy completion
940+ this . freshPrompt ( `/${ commandBase } ` )
941+ }
942+ return null
943+ }
906944
907- if ( ! agentId ) {
908- console . log (
909- yellow ( 'Please provide a subagent ID. Usage: subagent <agent-id>' ) ,
910- )
911- const recentSubagents = getRecentSubagents ( 10 )
912- displaySubagentList ( recentSubagents )
913- if ( recentSubagents . length === 0 ) {
914- // Give control back to user when no subagents exist
945+ if ( isInSubagentBufferMode ( ) ) {
946+ console . log (
947+ yellow ( 'Already in trace buffer mode! Press ESC to exit.' ) ,
948+ )
915949 this . freshPrompt ( )
916- } else {
917- // Pre-fill the prompt with '/subagent ' for easy completion
918- this . freshPrompt ( '/subagent ' )
950+ return null
919951 }
920- return null
921- }
922952
923- if ( isInSubagentBufferMode ( ) ) {
924- console . log (
925- yellow ( 'Already in subagent buffer mode! Press ESC to exit.' ) ,
926- )
927- this . freshPrompt ( )
953+ enterSubagentBuffer ( this . rl , agentId , ( ) => {
954+ // Callback when exiting subagent buffer
955+ console . log ( green ( '\nExited trace buffer mode!' ) )
956+ this . freshPrompt ( )
957+ } )
928958 return null
929- }
930-
931- enterSubagentBuffer ( this . rl , agentId , ( ) => {
932- // Callback when exiting subagent buffer
933- console . log ( green ( '\nExited subagent buffer mode!' ) )
934- this . freshPrompt ( )
935- } )
936- return null
937- }
959+ } else {
960+ // Handle bare trace command - show trace list
961+ if ( isInSubagentListMode ( ) ) {
962+ console . log ( yellow ( 'Already in trace list mode! Press ESC to exit.' ) )
963+ this . freshPrompt ( )
964+ return null
965+ }
938966
939- // Handle bare 'subagent' command (without space) - show subagent list
940- if ( cleanInput === 'subagent' ) {
941- if ( isInSubagentListMode ( ) ) {
942- console . log ( yellow ( 'Already in subagent list mode! Press ESC to exit.' ) )
943- this . freshPrompt ( )
967+ // Reset selection to last item when entering from main screen
968+ resetSubagentSelectionToLast ( )
969+ enterSubagentListBuffer ( this . rl , ( ) => {
970+ this . freshPrompt ( )
971+ } )
944972 return null
945973 }
946-
947- // Reset selection to last item when entering from main screen
948- resetSubagentSelectionToLast ( )
949- enterSubagentListBuffer ( this . rl , ( ) => {
950- this . freshPrompt ( )
951- } )
952- return null
953974 }
954975
955- // Handle 'agents' command - show agent management interface
956- if ( cleanInput === 'agents' ) {
976+ if ( this . isCommandOrAlias ( cleanInput , 'agents' ) ) {
957977 if ( isInAgentsMode ( ) ) {
958978 console . log ( yellow ( 'Already in agents mode! Press ESC to exit.' ) )
959979 this . freshPrompt ( )
0 commit comments