1010 * 对照 Claude Code: entrypoints/cli.tsx
1111 */
1212
13+ // Commander.js — Node.js 最流行的 CLI 框架,用来定义命令、解析参数、生成 --help
1314import { Command } from "commander" ;
15+ // createRequire 让 ESM 模块也能用 CommonJS 的 require(),这里用来读取 JSON 文件
1416import { createRequire } from "node:module" ;
1517import { startChat } from "./main.js" ;
1618
19+ // ESM 中没有 require(),createRequire 基于当前文件路径创建一个兼容的 require 函数
1720const require = createRequire ( import . meta. url ) ;
21+ // 读取 package.json 获取 version,这样 --version 会自动显示包的版本号,不用硬编码
1822const pkg = require ( "../package.json" ) ;
1923
24+ // ?? 是空值合并运算符:只有 null/undefined 时才取默认值,比 || 更安全(0、"" 不会被覆盖)
2025const DEFAULT_MODEL = process . env . MODEL_NAME ?? "claude-sonnet-4-20250514" ;
2126
2227const program = new Command ( ) ;
2328
29+ // 全局配置:name 会出现在 --help 的首行,version 支持 --version / -V 参数
2430program
2531 . name ( "mycli" )
2632 . description ( "AI Agent CLI — 从零构建" )
2733 . version ( pkg . version ) ;
2834
35+ // 注册子命令:mycli chat
36+ // .option() 定义可选参数,第三个参数是默认值
37+ // .action() 在参数解析完成后执行,options 是解析结果对象
2938program
3039 . command ( "chat" )
3140 . description ( "启动交互式对话" )
3241 . option ( "-m, --model <model>" , "模型名称" , DEFAULT_MODEL )
3342 . option ( "-s, --system <prompt>" , "系统提示词" )
3443 . action ( async ( options ) => {
44+ // CLI 入口只负责解析参数,业务逻辑全部在 main.ts 中(关注点分离)
3545 await startChat ( {
3646 model : options . model ,
3747 systemPrompt : options . system ,
3848 } ) ;
3949 } ) ;
4050
51+ // 注册子命令:mycli ask <question>
52+ // <question> 是必选参数(不带尖括号的是可选参数)
4153program
4254 . command ( "ask <question>" )
4355 . description ( "单次提问" )
@@ -47,4 +59,6 @@ program
4759 await ask ( question , { model : options . model } ) ;
4860 } ) ;
4961
50- program . parse ( ) ;
62+ // parse() 解析 process.argv,匹配到命令后执行对应的 .action()
63+ // 没有 .parse() 的话,上面定义的命令都不会生效
64+ program . parse ( ) ;
0 commit comments