@@ -32,32 +32,40 @@ export interface Cli {
3232}
3333
3434/**
35- * Build a CLI from an injected command set — each product (bl / rag / …) passes
36- * its own commands + identity. `run` resolves argv into a {@link Resolution},
37- * then dispatches it.
35+ * 进程级一次性设置:代理初始化、Ctrl+C、stdout EPIPE。
36+ * 属进程生命周期行为,装一次即可,不进 per-command 中间件。
3837 */
39- export function createCli ( commands : Record < string , AnyCommand > , opts : CliOptions ) : Cli {
40- const registry = new CommandRegistry ( commands , opts . binName ) ;
41- const clientName = opts . clientName ?? opts . binName ;
42- const { binName, version, npmPackage } = opts ;
43-
38+ function installProcessHandlers ( binName : string ) : void {
4439 try {
4540 setupProxyFromEnv ( ) ;
4641 } catch ( err ) {
4742 handleError ( err , binName ) ;
4843 }
4944
50- // 优雅处理 Ctrl+C
45+ // 处理 Ctrl+C
5146 process . on ( "SIGINT" , ( ) => {
5247 process . stderr . write ( "\nInterrupted. Exiting.\n" ) ;
5348 void flushTelemetry ( 500 ) . finally ( ( ) => process . exit ( 130 ) ) ;
5449 } ) ;
5550
56- // 优雅处理 stdout EPIPE(例如管道到提前退出的 `mpv`)
51+ // 处理 stdout EPIPE(例如管道到提前退出的 `mpv`)
5752 process . stdout . on ( "error" , ( e : NodeJS . ErrnoException ) => {
5853 if ( e . code === "EPIPE" ) process . exit ( 0 ) ;
5954 else throw e ;
6055 } ) ;
56+ }
57+
58+ /**
59+ * Build a CLI from an injected command set — each product (bl / rag / …) passes
60+ * its own commands + identity. `run` resolves argv into a {@link Resolution},
61+ * then dispatches it.
62+ */
63+ export function createCli ( commands : Record < string , AnyCommand > , opts : CliOptions ) : Cli {
64+ const registry = new CommandRegistry ( commands , opts . binName ) ;
65+ const clientName = opts . clientName ?? opts . binName ;
66+ const { binName, version, npmPackage } = opts ;
67+
68+ installProcessHandlers ( binName ) ;
6169
6270 const runMiddleware = compose ( [ versionCheckStage , telemetryStage , authStage , runCommandStage ] ) ;
6371
0 commit comments