{"_id":"@buckeyestudio/toh-cmdline","name":"@buckeyestudio/toh-cmdline","dist-tags":{"next":"0.1.1-rc.2","latest":"0.1.1-rc.2"},"versions":{"0.1.1-rc.2":{"name":"@buckeyestudio/toh-cmdline","description":"Immutable command-line handoff from a toh launcher to any app plugin that injects cmdlineArgs","version":"0.1.1-rc.2","publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/dustinwloring1988/theopen-harness.git","directory":"packages/boot/cmdline"},"type":"module","main":"lib/index.js","types":"lib/types/index.d.ts","exports":{".":{"types":"./lib/types/index.d.ts","default":"./lib/index.js"},"./invariant":{"types":"./lib/types/invariant.d.ts","default":"./lib/invariant.js"},"./src/*":"./src/*","./package.json":"./package.json"},"license":"MIT","author":{"name":"buckeyestudio"},"peerDependencies":{"@buckeyestudio/cordis-plugin-loader":"^1.0.2","@buckeyestudio/toh-invariants":"^0.1.1-rc.2","@buckeyestudio/cordis":"^4.0.1"},"devDependencies":{"commander":"^15.0.0","@buckeyestudio/cordis-plugin-include":"^1.0.6","@buckeyestudio/toh-invariants":"^0.1.1-rc.2","@buckeyestudio/cordis-plugin-loader":"^1.0.2","@buckeyestudio/cordis":"^4.0.1"},"_id":"@buckeyestudio/toh-cmdline@0.1.1-rc.2","bugs":{"url":"https://github.com/dustinwloring1988/theopen-harness/issues"},"homepage":"https://github.com/dustinwloring1988/theopen-harness#readme","_integrity":"sha512-71/hXPZmeciHIrAYNnkNN3T8AoI/BB+0wD/+a4Ho0E08P30KsVTrFMZEIw4m1JrzyTL6X5zX/XZ02YxrBuLNnA==","_resolved":"/home/runner/work/theopen-harness/theopen-harness/dist/npm/buckeyestudio-toh-cmdline-0.1.1-rc.2.tgz","_from":"file:/home/runner/work/theopen-harness/theopen-harness/dist/npm/buckeyestudio-toh-cmdline-0.1.1-rc.2.tgz","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-71/hXPZmeciHIrAYNnkNN3T8AoI/BB+0wD/+a4Ho0E08P30KsVTrFMZEIw4m1JrzyTL6X5zX/XZ02YxrBuLNnA==","shasum":"97bb5cf845e61f158325639f9c01201278d21e66","tarball":"https://registry.npmjs.org/@buckeyestudio/toh-cmdline/-/toh-cmdline-0.1.1-rc.2.tgz","fileCount":9,"unpackedSize":22939,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFSPaqoM0SB6gNGcdT5rW7s4w9j+x1uaLBsGWrrOUe0tAiAN8hQpV/3jzeyzxaguJts4RQ25sOIV+60Mne4WXJ49HQ=="}]},"_npmUser":{"name":"buckeyestudio","email":"dustinwloring1988@gmail.com"},"directories":{},"maintainers":[{"name":"buckeyestudio","email":"dustinwloring1988@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/toh-cmdline_0.1.1-rc.2_1787489518029_0.26624408138703237"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-23T12:51:57.816Z","0.1.1-rc.2":"2026-08-23T12:51:58.170Z","modified":"2026-08-23T12:51:58.494Z"},"maintainers":[{"name":"buckeyestudio","email":"dustinwloring1988@gmail.com"}],"description":"Immutable command-line handoff from a toh launcher to any app plugin that injects cmdlineArgs","homepage":"https://github.com/dustinwloring1988/theopen-harness#readme","repository":{"type":"git","url":"git+https://github.com/dustinwloring1988/theopen-harness.git","directory":"packages/boot/cmdline"},"author":{"name":"buckeyestudio"},"bugs":{"url":"https://github.com/dustinwloring1988/theopen-harness/issues"},"license":"MIT","readme":"# `@buckeyestudio/toh-cmdline`\n\n[English](README.md) | 中文\n\ntoh 启动器交给它所引导应用的那条命令行。启动器只解析属于自己的 flag（`--profile`、`--patch`、配置 dump），并把**其后的一切**原样交给配置树，因此 flag 家族、`--help` 文本和解析错误都由应用自己持有，启动器不必知道它们。\n\n## 启动器提供的值\n\n启动器在任何配置树条目挂载之前调用 `provideCmdline(ctx, host)`，它提供：\n\n- `ctx.cmdlineArgs`：本次调用的内层参数。`get()` 就是它的全部接口，返回一份快照：`toh --profile tui --resume abc` 得到 `['--resume', 'abc']`。\n- `ctx.appExit`：一个有边界的进程退出请求，接到启动器的关停控制器上。\n\n没有命令行的嵌入宿主提供空列表；这是诚实的答案，而不是缺失的值。\n\n## 普通提供方与注入配置\n\n任何应用插件都可以注入 `cmdlineArgs`、解析它，再发布一个普通的应用自有服务。`parseCmdline(ctx, program)` 只适配 commander；校验与发布的服务都归 program 自己的 action 持有：\n\n```ts ignore\nexport const name = 'web-startup'\nexport const inject = ['cmdlineArgs']\n\nexport function apply(ctx: Context): void {\n  const program = webCommand()\n  program.action(() => ctx.provide('webStartup', webValuesFrom(program)))\n  parseCmdline(ctx, program)\n}\n```\n\n它的 Loader 行不携带启动器标记，也没有特殊类型：\n\n```yaml\n- id: web-startup\n  name: '@buckeyestudio/toh-web-app/startup'\n```\n\n所有由这些取值配置的行都使用普通服务注入，并在惰性配置中直接访问该服务：\n\n```yaml\n- id: webserver\n  name: '@buckeyestudio/toh-host-webserver'\n  inject: [webStartup]\n  config:\n    host: !!js ctx.webStartup.host ?? '127.0.0.1'\n    port: !!js ctx.webStartup.port ?? 3080\n```\n\n`parseCmdline` 在加载时拒绝整棵命令树中没有任何命令声明 action 的 program，把每个命令的退出与输出都接到启动器上（commander 只在注册时把这些设置复制进子命令），再解析不可变参数；解析成功时 commander 运行被调用命令的同步 action。action 用 `program.error(...)` 拒绝无效调用——必须先拒绝后发布，因为写在拒绝之前的语句已经执行。遇到 `--help`、`--version`、解析错误或这种拒绝时，该适配器输出 commander 文本并请求退出；提供方什么也不发布，因此依赖行不会激活。\n\n### 注入如何排列配置求值\n\nLoader 会把一行的 `!!js` 插值推迟到该行声明的注入全部激活之后，再基于该行的插件上下文求值。所以上例可以直接读取 `ctx.webStartup`：Loader 索取 `webserver` 的配置之前，Cordis 已经填入了这个注入服务。Include 树会保留嵌套表达式节点，直到各个目标行到达这一时点。提供方替换与活动 patch 重载都会针对当前注入服务重新插值，因此启动 flag 不会被悄悄重置。\n\n### 共享不可变参数\n\n`get()` 不会消费或修改 argv。多个插件可以解析同一份快照，并分别提供服务。启动器不会检查组合中的命令行所有者；没有读取方的 profile 只会忽略自己的应用参数。\n\n树外插件会带来自己的一份 commander 副本，因此 commander 的控制流错误按结构识别，而不是按类身份识别；按身份判断会把已经打印出来的 help 重新抛成致命的加载失败。\n\n## 模型体验\n\n无。本包在任何会话存在之前解析进程自身的命令行。\n\n#### KV Cache 影响\n\n无；本包既不组装也不发送提供方请求。\n\n## 已知限制与延期工作\n\n- **启动器的 flag 必须写在应用参数之前**：切分按位置进行，启动器不认识的第一个 token 就是内层参数的起点，因此写在某个应用 flag 之后的 `--patch` 属于应用。启动器的解析器会消耗掉一个 `--`，因此必须以字面量 `--` 存活到应用的参数需要写成 `-- --`。\n- **应用自有服务没有静态声明的提供方**：消费行通过普通注入点名它；缺少提供方的组合包会在结算时失败，由待处理条目点名该服务，而不是在加载时失败。\n- **用户 patch 若整体替换某行的 `config`，会连同其中的表达式一起丢掉**：flag 胜过的是表达式旁写着的那个值，而不是用户用字面量替换掉表达式之后的结果；保留表达式才能保留 flag 的优先级。\n","readmeFilename":"README.zh.md","_rev":"1-5c1cc9b898387567c3b9f538d189b0cc"}