@@ -125,6 +125,9 @@ export async function runCdxgen(argvObj: ArgvObject): Promise<ShadowBinResult> {
125125 const cdxgenPackageSpec = `@cyclonedx/cdxgen@${ cdxgenVersion } `
126126 const cdxgenArgs = argvObjectToArray ( argvMutable )
127127
128+ // Check if this is a help/version request.
129+ const isHelpRequest = argvMutable [ 'help' ] || argvMutable [ 'version' ]
130+
128131 const result = await runShadowCommand ( cdxgenPackageSpec , cdxgenArgs , {
129132 agent,
130133 ipc : {
@@ -137,17 +140,31 @@ export async function runCdxgen(argvObj: ArgvObject): Promise<ShadowBinResult> {
137140 } )
138141
139142 // Create fake ShadowBinResult for backward compatibility.
143+ // Note: Help/version requests should always exit with code 0.
144+ const exitCode = result . ok || isHelpRequest ? 0 : ( result . code ?? 1 )
140145 const stdioResult = {
141146 cmd : 'cdxgen' ,
142147 args : [ ] as const ,
143- code : result . ok ? 0 : ( result . code ?? 1 ) ,
148+ code : exitCode ,
144149 signal : null ,
145150 stderr : Buffer . from ( '' ) ,
146151 stdout : Buffer . from ( result . ok ? result . data : '' ) ,
147152 }
153+
154+ // Create a mock ChildProcess with event emitter methods for backward compatibility.
155+ // The ShadowBinResult interface expects a ChildProcess, but runShadowCommand doesn't
156+ // return one. This mock provides the minimum EventEmitter interface needed by callers
157+ // while maintaining API compatibility. Each method returns 'this' to support chaining.
158+ const mockProcess = {
159+ on : ( ) => mockProcess ,
160+ once : ( ) => mockProcess ,
161+ off : ( ) => mockProcess ,
162+ removeListener : ( ) => mockProcess ,
163+ } as unknown as ChildProcess
164+
148165 const shadowResult : ShadowBinResult = {
149166 spawnPromise : Object . assign ( Promise . resolve ( stdioResult ) , {
150- process : { } as ChildProcess ,
167+ process : mockProcess ,
151168 stdin : null ,
152169 } ) ,
153170 }
0 commit comments