@@ -557,17 +557,46 @@ const createCliBuilder = <V, P extends readonly unknown[]>(
557557 } ,
558558
559559 // Internal method for nested command support - not part of public API
560+ // Handles HelpError here so nested builders can render their own help
560561 __parseWithParentGlobals (
561562 args : string [ ] ,
562563 parentGlobals : ParseResult < unknown , readonly unknown [ ] > ,
563564 allowAsync : boolean ,
564565 ) :
565- | ( ParseResult < V , P > & { command ?: string } )
566- | Promise < ParseResult < V , P > & { command ?: string } > {
566+ | ( ParseResult < V , P > & { command ?: string ; earlyExit ?: boolean } )
567+ | Promise < ParseResult < V , P > & { command ?: string ; earlyExit ?: boolean } > {
567568 const stateWithGlobals = { ...state , parentGlobals } ;
568- return parseCore ( stateWithGlobals , args , allowAsync ) as
569- | ( ParseResult < V , P > & { command ?: string } )
570- | Promise < ParseResult < V , P > & { command ?: string } > ;
569+ try {
570+ const result = parseCore ( stateWithGlobals , args , allowAsync ) ;
571+ if ( isThenable ( result ) ) {
572+ return result . catch ( ( error : unknown ) => {
573+ if ( error instanceof HelpError ) {
574+ return handleHelpError ( error , stateWithGlobals ) as ParseResult <
575+ V ,
576+ P
577+ > & {
578+ command ?: string ;
579+ earlyExit : true ;
580+ } ;
581+ }
582+ throw error ;
583+ } ) as Promise <
584+ ParseResult < V , P > & { command ?: string ; earlyExit ?: boolean }
585+ > ;
586+ }
587+ return result as ParseResult < V , P > & { command ?: string } ;
588+ } catch ( error ) {
589+ if ( error instanceof HelpError ) {
590+ return handleHelpError ( error , stateWithGlobals ) as ParseResult <
591+ V ,
592+ P
593+ > & {
594+ command ?: string ;
595+ earlyExit : true ;
596+ } ;
597+ }
598+ throw error ;
599+ }
571600 } ,
572601
573602 // Overloaded command(): accepts (name, factory, options?),
@@ -760,7 +789,7 @@ const createCliBuilder = <V, P extends readonly unknown[]>(
760789
761790 parse (
762791 args : string [ ] = process . argv . slice ( 2 ) ,
763- ) : ParseResult < V , P > & { command ?: string ; helpShown ?: boolean } {
792+ ) : ParseResult < V , P > & { command ?: string ; earlyExit ?: boolean } {
764793 try {
765794 const result = parseCore ( state , args , false ) ;
766795 if ( isThenable ( result ) ) {
@@ -773,7 +802,7 @@ const createCliBuilder = <V, P extends readonly unknown[]>(
773802 if ( error instanceof HelpError ) {
774803 return handleHelpError ( error , state ) as ParseResult < V , P > & {
775804 command ?: string ;
776- helpShown : true ;
805+ earlyExit : true ;
777806 } ;
778807 }
779808 throw error ;
@@ -782,7 +811,7 @@ const createCliBuilder = <V, P extends readonly unknown[]>(
782811
783812 async parseAsync (
784813 args : string [ ] = process . argv . slice ( 2 ) ,
785- ) : Promise < ParseResult < V , P > & { command ?: string ; helpShown ?: boolean } > {
814+ ) : Promise < ParseResult < V , P > & { command ?: string ; earlyExit ?: boolean } > {
786815 try {
787816 return ( await parseCore ( state , args , true ) ) as ParseResult < V , P > & {
788817 command ?: string ;
@@ -791,7 +820,7 @@ const createCliBuilder = <V, P extends readonly unknown[]>(
791820 if ( error instanceof HelpError ) {
792821 return handleHelpError ( error , state ) as ParseResult < V , P > & {
793822 command ?: string ;
794- helpShown : true ;
823+ earlyExit : true ;
795824 } ;
796825 }
797826 throw error ;
@@ -821,18 +850,18 @@ const parseCore = (
821850
822851 /**
823852 * Helper to create an early-exit result (for help, version, completions).
824- * Sets process.exitCode and returns a result with helpShown : true.
853+ * Sets process.exitCode and returns a result with earlyExit : true.
825854 *
826855 * @function
827856 */
828- const earlyExit = (
857+ const createEarlyExitResult = (
829858 exitCode : number ,
830859 ) : ParseResult < unknown , readonly unknown [ ] > & {
831860 command ?: string ;
832- helpShown : true ;
861+ earlyExit : true ;
833862 } => {
834863 process . exitCode = exitCode ;
835- return { command : undefined , helpShown : true , positionals : [ ] , values : { } } ;
864+ return { command : undefined , earlyExit : true , positionals : [ ] , values : { } } ;
836865 } ;
837866
838867 // Handle --help
@@ -880,12 +909,12 @@ const parseCore = (
880909
881910 // Regular command help
882911 console . log ( generateCommandHelpNew ( state , commandName , theme ) ) ;
883- return earlyExit ( 0 ) ;
912+ return createEarlyExitResult ( 0 ) ;
884913 }
885914 }
886915
887916 console . log ( generateHelpNew ( state , theme ) ) ;
888- return earlyExit ( 0 ) ;
917+ return createEarlyExitResult ( 0 ) ;
889918 }
890919
891920 // Handle --version
@@ -896,7 +925,7 @@ const parseCore = (
896925 } else {
897926 console . log ( 'Version information not available' ) ;
898927 }
899- return earlyExit ( 0 ) ;
928+ return createEarlyExitResult ( 0 ) ;
900929 }
901930
902931 // Handle shell completion (when enabled)
@@ -909,15 +938,15 @@ const parseCore = (
909938 console . error (
910939 'Error: --completion-script requires a shell argument (bash, zsh, or fish)' ,
911940 ) ;
912- return earlyExit ( 1 ) ;
941+ return createEarlyExitResult ( 1 ) ;
913942 }
914943 try {
915944 const shell = validateShell ( shellArg ) ;
916945 console . log ( generateCompletionScript ( state . name , shell ) ) ;
917- return earlyExit ( 0 ) ;
946+ return createEarlyExitResult ( 0 ) ;
918947 } catch ( err ) {
919948 console . error ( `Error: ${ ( err as Error ) . message } ` ) ;
920- return earlyExit ( 1 ) ;
949+ return createEarlyExitResult ( 1 ) ;
921950 }
922951 }
923952
@@ -927,7 +956,7 @@ const parseCore = (
927956 const shellArg = args [ getCompletionsIndex + 1 ] ;
928957 if ( ! shellArg ) {
929958 // No shell specified, output nothing
930- return earlyExit ( 0 ) ;
959+ return createEarlyExitResult ( 0 ) ;
931960 }
932961 try {
933962 const shell = validateShell ( shellArg ) ;
@@ -937,10 +966,10 @@ const parseCore = (
937966 if ( candidates . length > 0 ) {
938967 console . log ( candidates . join ( '\n' ) ) ;
939968 }
940- return earlyExit ( 0 ) ;
969+ return createEarlyExitResult ( 0 ) ;
941970 } catch {
942971 // Invalid shell, output nothing
943- return earlyExit ( 0 ) ;
972+ return createEarlyExitResult ( 0 ) ;
944973 }
945974 }
946975 }
@@ -965,19 +994,19 @@ const showNestedCommandHelp = (
965994) :
966995 | ( ParseResult < unknown , readonly unknown [ ] > & {
967996 command ?: string ;
968- helpShown ?: boolean ;
997+ earlyExit ?: boolean ;
969998 } )
970999 | Promise <
9711000 ParseResult < unknown , readonly unknown [ ] > & {
9721001 command ?: string ;
973- helpShown ?: boolean ;
1002+ earlyExit ?: boolean ;
9741003 }
9751004 > => {
9761005 const commandEntry = state . commands . get ( commandName ) ;
9771006 if ( ! commandEntry || commandEntry . type !== 'nested' ) {
9781007 console . error ( `Unknown command group: ${ commandName } ` ) ;
9791008 process . exitCode = 1 ;
980- return { command : undefined , helpShown : true , positionals : [ ] , values : { } } ;
1009+ return { command : undefined , earlyExit : true , positionals : [ ] , values : { } } ;
9811010 }
9821011
9831012 // Delegate to nested builder with --help
@@ -1107,7 +1136,7 @@ const handleHelpError = (
11071136 state : InternalCliState ,
11081137) : ParseResult < unknown , readonly unknown [ ] > & {
11091138 command ?: string ;
1110- helpShown : true ;
1139+ earlyExit : true ;
11111140} => {
11121141 const { theme } = state ;
11131142
@@ -1125,7 +1154,7 @@ const handleHelpError = (
11251154 // Return a result indicating help was shown
11261155 return {
11271156 command : error . command ,
1128- helpShown : true ,
1157+ earlyExit : true ,
11291158 positionals : [ ] ,
11301159 values : { } ,
11311160 } ;
0 commit comments