@@ -113,6 +113,11 @@ class CommandRegistry {
113113 * Defaults to stdout; pass stderr (or a non-TTY stream) to keep stdout
114114 * clean for piped / JSON output.
115115 */
116+ // Color helpers — no-ops when output is not a TTY
117+ private bold = ( s : string , out : NodeJS . WriteStream ) => out . isTTY ? `\x1b[1m${ s } \x1b[0m` : s ;
118+ private accent = ( s : string , out : NodeJS . WriteStream ) => out . isTTY ? `\x1b[38;2;248;103;58m${ s } \x1b[0m` : s ;
119+ private dim = ( s : string , out : NodeJS . WriteStream ) => out . isTTY ? `\x1b[2m${ s } \x1b[0m` : s ;
120+
116121 printHelp ( commandPath : string [ ] , out : NodeJS . WriteStream = process . stdout ) : void {
117122 if ( commandPath . length === 0 ) {
118123 this . printRootHelp ( out ) ;
@@ -134,80 +139,108 @@ class CommandRegistry {
134139 return ;
135140 }
136141
137- // Group help
138- out . write ( `\nUsage: mmx ${ commandPath . join ( ' ' ) } <command> [flags]\n\n` ) ;
139- out . write ( 'Commands:\n' ) ;
140- this . printChildren ( node , commandPath . join ( ' ' ) , out ) ;
142+ // Group help (e.g. `mmx auth --help`)
143+ const prefix = commandPath . join ( ' ' ) ;
144+ out . write ( `\n${ this . bold ( 'Usage:' , out ) } mmx ${ prefix } <command> [flags]\n\n` ) ;
145+ out . write ( `${ this . bold ( 'Commands:' , out ) } \n` ) ;
146+ this . printChildren ( node , prefix , out ) ;
141147 out . write ( '\n' ) ;
142148 }
143149
144150 private printRootHelp ( out : NodeJS . WriteStream ) : void {
151+ // MiniMax brand gradient: #F0177A (pink) → #FA7B2A (orange), one color per row
152+ const LOGO = [
153+ '███╗ ███╗███╗ ███╗██╗ ██╗' ,
154+ '████╗ ████║████╗ ████║╚██╗██╔╝' ,
155+ '██╔████╔██║██╔████╔██║ ╚███╔╝ ' ,
156+ '██║╚██╔╝██║██║╚██╔╝██║ ██╔██╗ ' ,
157+ '██║ ╚═╝ ██║██║ ╚═╝ ██║██╔╝ ██╗' ,
158+ '╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝' ,
159+ ] ;
160+ const GRADIENT : [ number , number , number ] [ ] = [
161+ [ 240 , 23 , 122 ] ,
162+ [ 242 , 43 , 106 ] ,
163+ [ 244 , 63 , 90 ] ,
164+ [ 246 , 83 , 74 ] ,
165+ [ 248 , 103 , 58 ] ,
166+ [ 250 , 123 , 42 ] ,
167+ ] ;
168+
169+ out . write ( '\n' ) ;
170+ for ( let i = 0 ; i < LOGO . length ; i ++ ) {
171+ if ( out . isTTY ) {
172+ const [ r , g , b ] = GRADIENT [ i ] ;
173+ out . write ( `\x1b[1;38;2;${ r } ;${ g } ;${ b } m${ LOGO [ i ] } \x1b[0m\n` ) ;
174+ } else {
175+ out . write ( LOGO [ i ] + '\n' ) ;
176+ }
177+ }
178+
179+ const b = ( s : string ) => this . bold ( s , out ) ;
180+ const a = ( s : string ) => this . accent ( s , out ) ;
181+ const d = ( s : string ) => this . dim ( s , out ) ;
182+
145183 out . write ( `
146- __ __ __ ____ __
147- | \\/ | \\/ \\ \\/ /
148- | |\\/| | |\\/| |\\ /
149- | | | | | | |/ \\
150- |_| |_|_| |_/_/\\_\\
151-
152- Usage: mmx <resource> <command> [flags]
153-
154- Resources:
155- auth Authentication (login, status, refresh, logout)
156- text Text generation (chat)
157- speech Speech synthesis (synthesize, voices)
158- image Image generation (generate)
159- video Video generation (generate, task get, download)
160- music Music generation (generate)
161- search Web search (query)
162- vision Image understanding (describe)
163- quota Usage quotas (show)
164- config CLI configuration (show, set, export-schema)
165- update Update mmx to a newer version
166-
167- Global Flags:
168- --api-key <key> API key (overrides all other auth)
169- --region <region> API region: global (default), cn
170- --base-url <url> API base URL (overrides region)
171- --output <format> Output format: text, json
172- --quiet Suppress non-essential output
173- --verbose Print HTTP request/response details
174- --timeout <seconds> Request timeout (default: 300)
175- --no-color Disable ANSI colors and spinners
176- --dry-run Show what would happen without executing
177- --non-interactive Disable interactive prompts (CI/agent mode)
178- --version Print version and exit
179- --help Show help
180-
181- Getting Help:
182- Add --help after any command to see its full list of options, defaults,
183- and usage examples. For example: mmx text chat --help
184+ ${ b ( 'Usage:' ) } mmx <resource> <command> [flags]
185+
186+ ${ b ( 'Resources:' ) }
187+ ${ a ( 'auth' ) } ${ d ( 'Authentication (login, status, refresh, logout)' ) }
188+ ${ a ( 'text' ) } ${ d ( 'Text generation (chat)' ) }
189+ ${ a ( 'speech' ) } ${ d ( 'Speech synthesis (synthesize, voices)' ) }
190+ ${ a ( 'image' ) } ${ d ( 'Image generation (generate)' ) }
191+ ${ a ( 'video' ) } ${ d ( 'Video generation (generate, task get, download)' ) }
192+ ${ a ( 'music' ) } ${ d ( 'Music generation (generate)' ) }
193+ ${ a ( 'search' ) } ${ d ( 'Web search (query)' ) }
194+ ${ a ( 'vision' ) } ${ d ( 'Image understanding (describe)' ) }
195+ ${ a ( 'quota' ) } ${ d ( 'Usage quotas (show)' ) }
196+ ${ a ( 'config' ) } ${ d ( 'CLI configuration (show, set, export-schema)' ) }
197+ ${ a ( 'update' ) } ${ d ( 'Update mmx to a newer version' ) }
198+
199+ ${ b ( 'Global Flags:' ) }
200+ ${ a ( '--api-key <key>' ) } ${ d ( 'API key (overrides all other auth)' ) }
201+ ${ a ( '--region <region>' ) } ${ d ( 'API region: global (default), cn' ) }
202+ ${ a ( '--base-url <url>' ) } ${ d ( 'API base URL (overrides region)' ) }
203+ ${ a ( '--output <format>' ) } ${ d ( 'Output format: text, json' ) }
204+ ${ a ( '--quiet' ) } ${ d ( 'Suppress non-essential output' ) }
205+ ${ a ( '--verbose' ) } ${ d ( 'Print HTTP request/response details' ) }
206+ ${ a ( '--timeout <seconds>' ) } ${ d ( 'Request timeout (default: 300)' ) }
207+ ${ a ( '--no-color' ) } ${ d ( 'Disable ANSI colors and spinners' ) }
208+ ${ a ( '--dry-run' ) } ${ d ( 'Show what would happen without executing' ) }
209+ ${ a ( '--non-interactive' ) } ${ d ( 'Disable interactive prompts (CI/agent mode)' ) }
210+ ${ a ( '--version' ) } ${ d ( 'Print version and exit' ) }
211+ ${ a ( '--help' ) } ${ d ( 'Show help' ) }
212+
213+ ${ b ( 'Getting Help:' ) }
214+ ${ d ( 'Add --help after any command to see its full list of options, defaults,' ) }
215+ ${ d ( 'and usage examples. For example:' ) } mmx text chat --help
184216` ) ;
185217 }
186218
187219 private printCommandHelp ( cmd : Command , out : NodeJS . WriteStream ) : void {
220+ const b = ( s : string ) => this . bold ( s , out ) ;
221+ const a = ( s : string ) => this . accent ( s , out ) ;
222+ const d = ( s : string ) => this . dim ( s , out ) ;
223+
188224 out . write ( `\n${ cmd . description } \n` ) ;
189- if ( cmd . usage ) out . write ( `Usage: ${ cmd . usage } \n` ) ;
225+ if ( cmd . usage ) out . write ( `${ b ( ' Usage:' ) } ${ cmd . usage } \n` ) ;
190226 if ( cmd . options && cmd . options . length > 0 ) {
191227 const maxLen = Math . max ( ...cmd . options . map ( o => o . flag . length ) ) ;
192- out . write ( 'Options:\n' ) ;
228+ out . write ( `\n ${ b ( 'Options:' ) } \n` ) ;
193229 for ( const opt of cmd . options ) {
194- out . write ( ` ${ opt . flag . padEnd ( maxLen + 2 ) } ${ opt . description } \n` ) ;
230+ out . write ( ` ${ a ( opt . flag . padEnd ( maxLen + 2 ) ) } ${ d ( opt . description ) } \n` ) ;
195231 }
196- out . write ( '\n' ) ;
197232 }
198233 if ( cmd . examples && cmd . examples . length > 0 ) {
199- out . write ( 'Examples:\n' ) ;
234+ out . write ( `\n ${ b ( 'Examples:' ) } \n` ) ;
200235 for ( const ex of cmd . examples ) {
201- out . write ( ` ${ ex } \n` ) ;
236+ out . write ( ` ${ d ( ex ) } \n` ) ;
202237 }
203- out . write ( '\n' ) ;
204238 }
205- out . write ( `Global flags (--api-key, --output, --quiet, etc.) are always available.\n` ) ;
206- out . write ( `Run ' mmx --help' for the full list.\n` ) ;
239+ out . write ( `\n ${ d ( ' Global flags (--api-key, --output, --quiet, etc.) are always available.' ) } \n` ) ;
240+ out . write ( `${ d ( " Run" ) } mmx --help ${ d ( ' for the full list.' ) } \n` ) ;
207241 }
208242
209243 private printChildren ( node : CommandNode , prefix : string , out : NodeJS . WriteStream ) : void {
210- // Collect all leaf entries first so we can align the description column.
211244 const entries : Array < { fullName : string ; description : string } > = [ ] ;
212245 const collect = ( n : CommandNode , p : string ) => {
213246 for ( const [ name , child ] of n . children ) {
@@ -218,7 +251,7 @@ Getting Help:
218251 collect ( node , prefix ) ;
219252 const maxLen = Math . max ( ...entries . map ( e => e . fullName . length ) ) ;
220253 for ( const { fullName, description } of entries ) {
221- out . write ( ` ${ fullName . padEnd ( maxLen ) } ${ description } \n` ) ;
254+ out . write ( ` ${ this . accent ( fullName . padEnd ( maxLen ) , out ) } ${ this . dim ( description , out ) } \n` ) ;
222255 }
223256 }
224257}
0 commit comments