@lumenkey/cli 0.2.3 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/README.md +43 -7
  2. package/dist/cli/copied.d.ts +19 -36
  3. package/dist/cli/copied.d.ts.map +1 -1
  4. package/dist/cli/copied.js +159 -283
  5. package/dist/cli/copied.js.map +1 -1
  6. package/dist/cli/index.d.ts.map +1 -1
  7. package/dist/cli/index.js +86 -136
  8. package/dist/cli/index.js.map +1 -1
  9. package/dist/cli/render.d.ts +11 -0
  10. package/dist/cli/render.d.ts.map +1 -0
  11. package/dist/cli/render.js +38 -0
  12. package/dist/cli/render.js.map +1 -0
  13. package/dist/core/atomic-config-file.d.ts +21 -2
  14. package/dist/core/atomic-config-file.d.ts.map +1 -1
  15. package/dist/core/atomic-config-file.js +66 -10
  16. package/dist/core/atomic-config-file.js.map +1 -1
  17. package/dist/core/chat.d.ts +13 -0
  18. package/dist/core/chat.d.ts.map +1 -0
  19. package/dist/core/chat.js +31 -0
  20. package/dist/core/chat.js.map +1 -0
  21. package/dist/core/client.d.ts +19 -1
  22. package/dist/core/client.d.ts.map +1 -1
  23. package/dist/core/client.js +50 -11
  24. package/dist/core/client.js.map +1 -1
  25. package/dist/core/config-dir.d.ts.map +1 -1
  26. package/dist/core/config-dir.js +3 -4
  27. package/dist/core/config-dir.js.map +1 -1
  28. package/dist/core/config-error.d.ts +14 -0
  29. package/dist/core/config-error.d.ts.map +1 -0
  30. package/dist/core/config-error.js +20 -0
  31. package/dist/core/config-error.js.map +1 -0
  32. package/dist/core/config.d.ts +1 -5
  33. package/dist/core/config.d.ts.map +1 -1
  34. package/dist/core/config.js +8 -39
  35. package/dist/core/config.js.map +1 -1
  36. package/dist/core/credit-cap.d.ts +5 -0
  37. package/dist/core/credit-cap.d.ts.map +1 -0
  38. package/dist/core/credit-cap.js +15 -0
  39. package/dist/core/credit-cap.js.map +1 -0
  40. package/dist/core/download.d.ts.map +1 -1
  41. package/dist/core/download.js +105 -16
  42. package/dist/core/download.js.map +1 -1
  43. package/dist/core/error-result.d.ts +4 -13
  44. package/dist/core/error-result.d.ts.map +1 -1
  45. package/dist/core/error-result.js +4 -24
  46. package/dist/core/error-result.js.map +1 -1
  47. package/dist/core/generation-input.d.ts +33 -0
  48. package/dist/core/generation-input.d.ts.map +1 -0
  49. package/dist/core/generation-input.js +145 -0
  50. package/dist/core/generation-input.js.map +1 -0
  51. package/dist/core/generation-result.d.ts +17 -14
  52. package/dist/core/generation-result.d.ts.map +1 -1
  53. package/dist/core/generation-result.js +3 -4
  54. package/dist/core/generation-result.js.map +1 -1
  55. package/dist/core/generation.d.ts +124 -0
  56. package/dist/core/generation.d.ts.map +1 -0
  57. package/dist/core/generation.js +316 -0
  58. package/dist/core/generation.js.map +1 -0
  59. package/dist/core/locale.d.ts +21 -0
  60. package/dist/core/locale.d.ts.map +1 -1
  61. package/dist/core/locale.js +84 -4
  62. package/dist/core/locale.js.map +1 -1
  63. package/dist/core/outcome.d.ts +134 -0
  64. package/dist/core/outcome.d.ts.map +1 -0
  65. package/dist/core/outcome.js +112 -0
  66. package/dist/core/outcome.js.map +1 -0
  67. package/dist/core/output-path.d.ts +10 -0
  68. package/dist/core/output-path.d.ts.map +1 -0
  69. package/dist/core/output-path.js +15 -0
  70. package/dist/core/output-path.js.map +1 -0
  71. package/dist/core/params.d.ts +68 -0
  72. package/dist/core/params.d.ts.map +1 -0
  73. package/dist/core/params.js +227 -0
  74. package/dist/core/params.js.map +1 -0
  75. package/dist/core/poller.d.ts +6 -1
  76. package/dist/core/poller.d.ts.map +1 -1
  77. package/dist/core/poller.js +17 -8
  78. package/dist/core/poller.js.map +1 -1
  79. package/dist/core/profiles.d.ts +4 -2
  80. package/dist/core/profiles.d.ts.map +1 -1
  81. package/dist/core/profiles.js +20 -9
  82. package/dist/core/profiles.js.map +1 -1
  83. package/dist/core/submission-journal.d.ts +106 -0
  84. package/dist/core/submission-journal.d.ts.map +1 -0
  85. package/dist/core/submission-journal.js +340 -0
  86. package/dist/core/submission-journal.js.map +1 -0
  87. package/dist/index.d.ts +3 -0
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/index.js +3 -0
  90. package/dist/index.js.map +1 -1
  91. package/dist/mcp/render.d.ts +11 -0
  92. package/dist/mcp/render.d.ts.map +1 -0
  93. package/dist/mcp/render.js +17 -0
  94. package/dist/mcp/render.js.map +1 -0
  95. package/dist/mcp/server.d.ts.map +1 -1
  96. package/dist/mcp/server.js +95 -337
  97. package/dist/mcp/server.js.map +1 -1
  98. package/package.json +2 -1
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # @lumenkey/cli
2
2
 
3
+ 本版:**0.3.0**(CLI/MCP);下文 0.2.3 均为已发布旧版的行为对照。
4
+
3
5
  > **光钥 (LumenKey) 官方 CLI 命令行工具 & 智能体 MCP (Model Context Protocol) 统一服务包**
4
6
  > 一套代码同构支持:**人类终端命令行 (CLI)** 与 **AI Agent (Cursor / Claude Code / Codex / Antigravity) 原生工具挂载 (MCP Server)**。
5
7
 
@@ -53,6 +55,12 @@ npx @lumenkey/cli models --type video
53
55
  ### 2. 视频先报价,确认后生成
54
56
  不加 `--confirm` 只报价,不提交生成任务。参数与默认值由所选模型目录决定;不要把某个模型的规格套用到其他模型。
55
57
 
58
+ **目录默认值会显式发送。** CLI 与 MCP 的图片/视频生成共用 `buildGenerationInput`:未提供的字段如果在目录参数表中有非空字符串、有限数字或布尔默认值,会写入实际 `input`,报价与建任务使用同一份输入。目录 `null` 与空字符串默认值不发送;调用方显式给 `null` 在任何请求前返回 `MODEL_PARAM_INVALID`,要用默认值就省略该字段。明确给出的 `0`、`false`、空字符串仍优先;对象/数组默认值不自动展开。`--dry-run` 返回最终 `input` 与 `defaultsApplied:true`;`schemaDefaults` 只是目录标量默认值参考,不是另一份待发送字段。没有目录或参数表则失败,不静默降级。显式默认值不改变目录价格,但上游现在会收到以前省略的时长、宽高比,尤其图生视频成片可能与以前不同。
59
+
60
+ 同一参数不能同时使用两个不同字段名(例如 `--duration 5 --set duration_ms=5000`、`--resolution 2k --set size=2k`),即使值相同也返回 `MODEL_PARAM_ALIAS_CONFLICT`,不会发送目录/报价/任务请求。不换算别名的单位。显式字段优先于它的其他别名默认值;目录同时为同组两个字段提供默认值且调用方未选择时,返回 `MODEL_INPUT_SCHEMA_INVALID`,不猜选哪一个。
61
+
62
+ **升级后的待确认提交。** 确认提交时,如果默认值补全/目录变更使同一生成意图的输入不同于本机未确认记录,在记录的 23 小时窗口内返回 `SUBMISSION_INPUT_POLICY_CHANGED`(`submission:"none"`),附 `pendingIdempotencyKey`、`pendingQuoteId` 等定位字段,不新报价、建单或改写旧记录;新显式键也不能绕过。补写当前或记录时的默认值仍视为同一意图。请用 `lumenkey tasks resume <记录键>` / MCP `lumenkey_resume_submission` 原样恢复;恢复不读目录、不补默认值,仍遵守账号/网关绑定和 23 小时窗口。23–48 小时的旧记录不再永久阻塞新提交:先提示「有一条未确认的旧请求已过可续传时限,请先查任务历史」,再允许不带键或使用新键提交;原记录键与恢复动词仍返回 `SUBMISSION_RECORD_EXPIRED`,不危险重放。48 小时后忽略并清理旧记录。新记录保存本地 `callerInput`,它不进入网关请求;未知结果或死属主 in-flight 的不同输入在放行时也有提示。普通新记录输入未变时仍原样自动续传。已发布 0.2.3 没有提交记录功能;这里的旧格式记录只来自未发布构建,不要求 0.2.3 用户迁移。仅报价和 dry-run 不提交任务,仍可检查当前目录输入。
63
+
56
64
  ```bash
57
65
  npx @lumenkey/cli video \
58
66
  --model doubao-seedance-2.0 \
@@ -74,9 +82,34 @@ npx @lumenkey/cli status <jobId>
74
82
  npx @lumenkey/cli --json status <jobId>
75
83
  ```
76
84
 
77
- `status` 和 `tasks progress` 默认显示可读的任务/模型/状态;脚本应显式加 `--json`。失败任务仍返回原始任务详情和 `error.code`,同时以退出码 1 结束。网关请求失败等命令错误统一返回 `error`、`code`、`type`,有 HTTP 状态时另带 `httpStatus`。任务错误码可能为小写(例如 `provider_error`),请原样处理。
85
+ `status` 和 `tasks progress` 默认显示可读的任务/模型/状态;脚本应显式加 `--json`。任务错误码可能为小写(例如 `provider_error`),请原样处理。
86
+
87
+ CLI `--json` 与 MCP 工具结果使用**同一个结果对象**(MCP 的 `content[0].text` 就是这个对象的 JSON,`isError` 等于 `ok:false`;`lumenkey_chat` 成功时第一段是回答正文,最后一段才是该对象)。成功为 `ok:true`,失败为 `ok:false` 加 `code`(供脚本判断)、`message`(不含码、路径和 HTTP 后缀的说明)、`type`。任务相关结果带 `jobId`、`jobStatus`(网关任务状态)和 `job`(完整任务记录,网关原始 `error` 对象在 `job.error` 下);本机等待状态用 `waitStatus:"TIMEOUT"|"INTERRUPTED"`,不凭空推断任务失败。配置类错误带 `path` 与 `detail`。顶层 `error` 永远是字符串。
88
+
89
+ 为兼容 0.2.x 脚本,`error`、`status`、`failureCode`、`failureMessage`、`timedOut` 继续输出,但已标记弃用:`status` 在任务失败时是任务状态、在等待超时时是 `"TIMEOUT"`,新脚本请改用 `jobStatus` / `waitStatus`。图片/视频非法 `--max-credits` 返回 `CREDIT_LIMIT_INVALID`,聊天保持 `CHAT_CREDIT_LIMIT_INVALID`;MCP 参数校验失败也返回同一结果对象(例如 `INPUT_INVALID`、`IDEMPOTENCY_KEY_REQUIRED`),不再是 SDK 的 `-32602` 文本。
90
+
91
+ | 兼容字段 | 含义 | 新消费者 |
92
+ | --- | --- | --- |
93
+ | `success` | 生成成功结果上的旧布尔字段,与 `ok` 同义;已弃用,并非每种结果均有此字段。 | 一律读 `ok`。 |
78
94
 
79
- 从 0.2.3 起,CLI `--json` 失败输出统一提供 `ok:false`、`code`、`message`;任务失败另带实际 `jobStatus`。`message` 是便于展示的原因,`code` 供脚本判断;旧 `error`、`status`、`failureCode`、`failureMessage` 字段保留。等待超时使用 `waitStatus:"TIMEOUT"`,兼容旧 `status:"TIMEOUT"`,不凭空推断任务失败。图片/视频非法 `--max-credits` 返回 `CREDIT_LIMIT_INVALID`,聊天保持 `CHAT_CREDIT_LIMIT_INVALID`。MCP 工具既有文本/任务结果结构不因此更换。
95
+ `submission:"unknown"` 的 `message` 是简短安全提示;完整的旧版 `error` 字符串保持兼容,不应再用它解析恢复信息。新消费者读下列字段:
96
+
97
+ | 字段 | 内容 |
98
+ | --- | --- |
99
+ | `idempotencyKey`、`quoteId` | 原提交的幂等键及报价 ID,不得为了重试而换键或参数。 |
100
+ | `recovery` | `rerun`(可续传)、`resume-command`(需显式恢复)、`expired`(已过期)、`ledger`(核对任务与余额,不在此重发)。 |
101
+ | `recoveryCommand` | 只有可安全续传时才有的 **argv 数组**,例如 `["lumenkey","tasks","resume","--key=<原幂等键>"]`。第一项是程序,其余是参数;不拼成 shell 字符串、不用 `eval`。MCP 可改调用 `lumenkey_resume_submission` 并传同一 `idempotencyKey`。 |
102
+ | `resumeDeadline` | 本机记录仍存在时的 23 小时截止时间,ISO UTC;不是新报价有效期,也不是延长服务端幂等期限。 |
103
+
104
+ 供人阅读的短 `message` 及 CLI 错误显示使用**执行机本机时区**,附 `±HH:MM` 偏移;例如 `2026-10-16 17:47 (-07:00)`。机器字段 `resumeDeadline` 保持 UTC。已过期、记录丢失或幂等冲突时不提供 `recoveryCommand`;先核对任务列表与余额,不能靠换键重提来解决 unknown。
105
+
106
+ **提交后的真金字段。** 只要请求了 `--confirm`,无论成功失败,结果都带 `submission`;一旦拿到报价就带 `quoteId`,一旦决定了幂等键就带 `idempotencyKey`(报价之前的失败——参数错误、没有密钥、目录不可写——只带 `submission:"none"`,没有键和报价)。`submission`:`"created"` 已创建任务(带 `jobId`)、`"none"` 什么都没创建(请求没发出,或网关返回了格式正确的 4xx)、`"unknown"` 请求已发出但没有拿到格式正确的回答(连接中断、客户端超时、任何 5xx、2xx 但响应不合约)。旧的布尔 `submitted` 只在成功结果上保留(报价 `false`、已建单 `true`),已标记弃用,不会出现在失败结果里。`"unknown"` 时网关可能已受理并冻结算力点:**不要换键重提**。客户端在 POST 前把这次提交(幂等键、quoteId、projectId、模型与输入、状态、网关地址与密钥的 SHA-256 指纹,不含密钥本身)原子写入 `~/.lumenkey/pending-submissions/`;记录只对创建它的账号和网关有效:换档案后不会自动接续别人的记录,显式带别人的键会本地返回 `SUBMISSION_CREDENTIALS_MISMATCH` 且不发请求、不动记录;同一账号换了密钥也不再匹配(记录保留并在 24 小时后过期)。观察到 `"unknown"` 后记录改为 unknown 状态。之后**用相同参数再次运行同一命令/同一工具调用**(不带键也可以):客户端找到模型与输入完全相同、状态为 unknown 的最早记录,原样重发它的请求体而不是重新报价,结果带 `resumed: true`;显式带 `--idempotency-key <同一个键>`(MCP `idempotencyKey`)则直接重发该键的记录,参数不同返回 `SUBMISSION_RETRY_MISMATCH`,不发任何请求。仍在运行的进程的 in-flight 记录不会被自动接续(stderr 会提示它的键),所以并行提交多个相同生成仍会得到多个任务;被杀死进程留下的本机记录会被接续。**恢复动词**:`lumenkey tasks resume <幂等键>`(MCP `lumenkey_resume_submission`)把记录的请求体原样重发——不读目录、不重新报价、不接受任何生成参数——遵守同样的账号绑定、23 小时窗口和重放分类,返回同样的结果对象并带 `resumed: true`;模型下架或目录变更后仍可用它找回已有任务。显式带一个新键而本机已有相同输入的未确认记录时,不会用新键发送任何内容,而是返回 `SUBMISSION_PENDING_IDENTICAL`(`submission:"none"`):结果里 `idempotencyKey` 仍是你提供的键,`pendingIdempotencyKey`、`pendingQuoteId`、`pendingRecordedAt`、`pendingAgeSeconds` 指出阻塞的那条记录,文案指引先运行 `tasks resume <那个键>`。在那条记录处理完或记录后 23 小时过期之前,无法创建第二个相同的任务(显式键的语义不会被覆盖)。`tasks` 的各子命令只接受自己的选项(`progress` 无,`wait` 为 `--interval/--timeout`,`cancel` 为 `--yes`,`resume` 为 `-o/--interval/--timeout/--key`),其他选项返回 `INPUT_INVALID`;以 `-` 开头的键用 `tasks resume --key=<键>` 或 `tasks resume -- <键>` 传入。同模型但输入不同的未确认记录、其他主机的记录、过期的记录都会在 stderr 和 `detail` 里点名,不会被静默跳过。重发时只有网关在建单步骤内给出的明确拒绝(如 `QUOTE_NOT_AVAILABLE`、`INSUFFICIENT_CREDITS`)才算 `"none"` 并删除记录;鉴权、限流等其他 4xx 不能说明第一次有没有建单,结果保持 `"unknown"`、记录保留。首次提交时也只有带业务码的 4xx 才算 `"none"`;没有业务码的 4xx(例如代理返回的 HTML)同样是 `"unknown"`。记录可接续的窗口是 23 小时(比网关的 24 小时幂等记录短一小时):过期记录不再自动接续,显式带它的键会本地返回 `SUBMISSION_RECORD_EXPIRED` 且不发请求;过期记录保留到 48 小时以便报告,之后清理。`"unknown"` 结果里的恢复建议按磁盘上的真实状态给出:记录已标记为 unknown → 直接重跑即接续;记录仍是 in-flight(标记失败)→ 需显式带键;记录已不存在 → 核对任务列表与余额。被杀死的进程留下的 in-flight 记录(本机、进程已不存在)会被相同的重跑接续;仍在运行的进程的记录不会;其他主机的记录会在 stderr 和 `detail` 中提示但不接续。
107
+
108
+ **写不进记录时不提交任务。** 在报价之前就会探测记录目录是否可写,失败返回 `SUBMISSION_JOURNAL_UNWRITABLE`(带目录与原因),不会买下报价。这意味着 0.2.3 在只读 HOME(容器、CI、`HOME=/nonexistent`)下仍可 `--confirm`,而本版本会拒绝;请设置 `LUMENKEY_JOURNAL_DIR=<可写目录>` 把待确认记录放到别处(目录以 0700 创建),记录不可关闭。任务创建成功后记录删不掉只会写进 `detail`,不会改变结果。`--json --confirm` 下任务一创建就向 stderr 写一行 `{"event":"job_created","jobId":…,"idempotencyKey":…,"quoteId":…}`,stdout 仍是单个 JSON 文档;人类模式在任务号旁打印幂等键。
109
+
110
+ `chat --json` 成功结果为 `ok:true`、`idempotencyKey`、`modelId`、`text`(回答正文)、`usage`、`billing`,完整网关响应体在 `response` 下;为兼容 0.2.x 脚本,响应体字段(如 `choices`)本版本仍同时铺在顶层,0.3 起只保留 `response`。
111
+
112
+ CLI 的选项和 MCP 工具的字段由 core 里同一张参数表生成,参数值也由同一段 core 代码校验:同一个问题在两个入口返回同一个码(例如空白提示词 `INPUT_INVALID`、未知选项/字段 `INPUT_INVALID`、等待参数非法 `WAIT_OPTIONS_INVALID`、花费上限非法 `CREDIT_LIMIT_INVALID`/`CHAT_CREDIT_LIMIT_INVALID`、缺密钥 `API_KEY_NOT_CONFIGURED`),文案只提自己入口的选项名。同一意图两个入口发出的请求体一致:宽高比只落到目录声明的一个字段(优先 `aspect_ratio`),空白的系统提示都不发送。`count` 两边都按目录类型校验(`MODEL_PARAM_INVALID`),`set` 在 MCP 上也接受单个字符串,显式给空的聊天模型在两边都是 `MODEL_REQUIRED`,`--interval -1` 与 `intervalMs: -1000` 同为 `WAIT_OPTIONS_INVALID`。MCP `tools/list` 保留必填项(`modelId`、`prompt`;聊天 `prompt`)并标注数值约束(`maxCredits` 非负整数、`intervalMs` 正数、`timeoutMs` 非负)。唯一无法对齐的是 `--max-credits 1e3`:CLI 收到的是字符串并拒绝,MCP 通过 JSON 收到的是数字 1000,无法区分。
80
113
 
81
114
  图片、视频、`tasks wait` 共用轮询逻辑,默认间隔 5 秒、等待 1800 秒。间隔必须大于 0,指定 25 秒不会被缩短到 10 秒。等待时长是两次请求之间检查的预算,不会中断已发出的单次查询;单次网关请求另受 `LUMENKEY_TIMEOUT_MS` 控制。超时带 `WAIT_TIMEOUT`、`timedOut: true` 和任务号;不取消任务、不代表退款。
82
115
 
@@ -84,9 +117,11 @@ CLI 的 `--interval` / `--timeout` 单位都是**秒**,MCP 的 `intervalMs` /
84
117
 
85
118
  Ctrl+C / SIGTERM 只停止本机等待或下载,不调用取消接口;分别以 130 / 143 退出并保留恢复查询信息。取消任务必须显式运行 `tasks cancel <jobId> --yes`(MCP 使用 `yes: true`)。
86
119
 
87
- `--output` 下载不覆盖已有文件,单次限 120 秒、128 MiB。生成成功但保存失败时,仍返回 `status: "succeeded"`、`jobId`、`idempotencyKey` 和全部 `urls`,另带 `download: {ok:false,code,error}`;CLI 以 1 退出表示本机保存失败,MCP 保留生成成功和下载警告。请用结果地址另存,不要为下载失败重新提交付费生成。下载中断时也保留这些结果。
120
+ `--output` 下载不覆盖已有文件,单次限 120 秒、128 MiB;目标目录里超过 1 小时的残留 `.part` 文件会被清理。生成成功但保存失败时,仍返回 `status: "succeeded"`、`jobId`、`idempotencyKey` 和全部 `urls`,另带 `download: {ok:false,code,error}`;CLI 以 1 退出表示本机保存失败,MCP 保留生成成功和下载警告。请用结果地址另存,不要为下载失败重新提交付费生成。下载中断时也保留这些结果。
121
+
122
+ `--output` 必须是包含文件名的路径;目标为目录(包括指向目录的符号链接/junction)时返回 `DOWNLOAD_IS_DIRECTORY`,已有普通文件(或指向文件的链接)则返回 `DOWNLOAD_EXISTS`,不会覆盖、删除或穿过链接写入。目标目录链只在结果开始落盘时创建,保存失败会删掉本次创建的空目录;不支持硬链接的文件系统(exFAT、部分 SMB)自动改用独占复制,仍不覆盖。两个入口都把开头的 `~/` 展开为主目录(不展开 `~user`);CLI 的相对路径按当前目录解析,MCP 的 `downloadPath` 必须是绝对路径或 `~/` 开头,否则在报价前返回 `DOWNLOAD_PATH_NOT_ABSOLUTE`(MCP 服务的工作目录不属于调用方)。下载目录白名单留待后续版本。
88
123
 
89
- `--output` 必须是包含文件名的路径;目标为目录时返回 `DOWNLOAD_IS_DIRECTORY`,已有普通文件则返回 `DOWNLOAD_EXISTS`,不会覆盖或删除它们。
124
+ `~/.lumenkey` 在首次写入时以 0700 创建,已存在但权限更宽时会被收紧(config.json、profiles.json、待确认提交记录共用同一写入路径;Windows 不应用权限位)。配置路径为符号链接或硬链接时,`config.json` 与 `profiles.json` 都返回 `CONFIG_UNSAFE_PATH`(0.2.3 对 profiles 返回 `PROFILE_UNREADABLE`,这是有意的契约变更);路径存在但不是普通文件(目录、FIFO、套接字、设备)或 `.lumenkey` 不是目录时返回 `CONFIG_NOT_A_FILE`,带 `path` 与 `detail`。
90
125
 
91
126
  ### 4. 查看账户算力余额
92
127
  ```bash
@@ -101,7 +136,7 @@ npx @lumenkey/cli balance
101
136
 
102
137
  代理地址只能包含源地址(可带代理认证信息),不能附加 `/gw` 等路径、查询或片段;无效时返回 `PROXY_URL_INVALID`。`NO_PROXY` 明确旁路的请求不使用该代理。
103
138
 
104
- 聊天返回 HTTP 5xx 且没有 `billing` 时,客户端会明确提示结算状态未知、算力点可能仍被冻结;不会承诺已释放、扣费为零或自动重试。服务端带回的 `SETTLED` / `RELEASED` / `PENDING` 仍是结算依据。目录查询失败不会被误写成聊天冻结。
139
+ 聊天返回 HTTP 5xx 且没有 `billing`、或在客户端超时(`REQUEST_TIMEOUT`)/连接中断时,客户端会明确提示结算状态未知、算力点可能仍被冻结;不会承诺已释放、扣费为零或自动重试。聊天成功与失败结果都带实际发送的 `idempotencyKey`(CLI `--idempotency-key`、MCP `idempotencyKey` 可显式指定);安全重试方法是用同一个键再次发送完全相同的请求,网关会回放结果而不会重复扣费。同键请求仍在运行返回 `REQUEST_IN_PROGRESS`,已完成但不能再回放返回 `IDEMPOTENCY_RESULT_EXPIRED`,两者都未重复扣费,请核对余额。服务端带回的 `SETTLED` / `RELEASED` / `PENDING` 仍是结算依据。目录查询失败不会被误写成聊天冻结。
105
140
 
106
141
  ---
107
142
 
@@ -159,13 +194,14 @@ claude mcp add lumenkey npx -y @lumenkey/cli mcp
159
194
  | `lumenkey_generate_image` | 调度商业级图像模型生成图片 |
160
195
  | `lumenkey_query_job` | 根据任务 ID 异步查询进度与生成产物 URL |
161
196
  | `lumenkey_check_balance` | 查询可用/冻结算力点及余额更新时间 |
162
- | `lumenkey_chat` | 发起计费文本对话,返回服务器用量与结算信息 |
197
+ | `lumenkey_chat` | 发起计费文本对话,返回回答正文及含用量、结算与幂等键的结果对象 |
163
198
  | `lumenkey_explain_model` | 说明模型参数、必填项和允许值 |
164
199
  | `lumenkey_tasks_progress` | 查询已有任务进度 |
165
200
  | `lumenkey_tasks_wait` | 等待已有任务,不新建任务 |
166
201
  | `lumenkey_tasks_cancel` | 传 `yes: true` 请求取消;不承诺退款 |
202
+ | `lumenkey_resume_submission` | 按幂等键原样重发一次已记录的提交(结果未知后的恢复);不重新报价,不读目录,不接受生成参数 |
167
203
 
168
- `lumenkey_generate_image` / `lumenkey_generate_video` 支持可选 `intervalMs`、`timeoutMs`,与 CLI 共用默认 5000 / 1800000 毫秒;省略 `confirm` 仍然只报价。等待超时后可用 `lumenkey_query_job` 或 `lumenkey_tasks_progress` 继续查询。IDE 自身也可能有工具调用时限,需独立设置;客户端不会因此承诺服务端任务已取消。
204
+ `lumenkey_generate_image` / `lumenkey_generate_video` 支持可选 `intervalMs`、`timeoutMs`,与 CLI 共用默认 5000 / 1800000 毫秒;省略 `confirm` 仍然只报价。等待超时后可用 `lumenkey_query_job` 或 `lumenkey_tasks_progress` 继续查询。IDE 自身也可能有工具调用时限,需独立设置;客户端不会因此承诺服务端任务已取消。所有工具的结果对象与 CLI `--json` 相同(见上文);配置在第一次需要它的工具调用时读取并缓存,修改 `config.json` 后请重启服务。
169
205
 
170
206
  ---
171
207
 
@@ -1,45 +1,28 @@
1
1
  import type { CAC } from 'cac';
2
- import { LumenKeyClient } from '../core/client.js';
3
- import type { GenerationJobDetail, ModelItem } from '../core/types.js';
4
- export declare function wantsJson(argv?: string[]): boolean;
2
+ import { type DryRunPreview } from '../core/generation-input.js';
3
+ import { type ParamSpec } from '../core/params.js';
4
+ import { type GenerationCompleted, type GenerationEvent } from '../core/generation.js';
5
+ import type { QuoteSuccess, Success } from '../core/outcome.js';
6
+ export { wantsJson } from './render.js';
5
7
  export declare function rawOption(names: string[], argv?: string[]): string | undefined;
6
8
  export declare function applyRaw(options: Record<string, unknown>, key: string, names: string[]): void;
9
+ /** Plain data commands (catalog, balance, profiles) print their payload; outcomes go through renderOutcome. */
7
10
  export declare function emit(data: unknown, human: () => void, argv?: string[]): void;
8
11
  export declare function rejectEmptyIdempotencyKey(): void;
9
- export declare function parseMaxCredits(value: unknown, label?: string, code?: string): number | undefined;
10
- export declare function quoteCreditLimitError(label?: string): Error;
11
- export declare function dryRunPreview(modelId: string, input: Record<string, unknown>, model: ModelItem, confirm?: unknown): Record<string, unknown>;
12
- export declare function submitQuote(modelId: string, input: Record<string, unknown>, options: Record<string, unknown>): Promise<{
13
- jobId: string;
14
- idempotencyKey: string;
15
- } | undefined>;
16
- export declare function buildGenerationInput(modelId: string, fields: Record<string, unknown>, pairs: string[], known?: ModelItem): Promise<{
17
- input: Record<string, unknown>;
18
- properties: Record<string, unknown>;
19
- model: ModelItem;
20
- }>;
12
+ /** Install SIGINT/SIGTERM handling around a wait: abort the core operation and keep the conventional exit code. */
13
+ export declare function withCliSignals<T>(run: (signal: AbortSignal) => Promise<T>): Promise<T>;
14
+ /** CLI view of generation progress. In --json mode the job identity goes to stderr the moment it exists. */
15
+ export declare function cliGenerationEvents(): (event: GenerationEvent) => void;
16
+ export declare function printGeneration(result: Success<DryRunPreview | QuoteSuccess | GenerationCompleted>): void;
17
+ /** Shared by `video` and `image generate`: options come from the core spec, values go through the core normalizer, one use case, one renderer. */
18
+ export declare function runCliGeneration(kind: 'video' | 'image', spec: readonly ParamSpec[], options: Record<string, unknown>): Promise<void>;
19
+ /** Register every CLI option of a spec on a command. */
20
+ export declare function registerOptions<T extends {
21
+ option: (flags: string, description: string, config?: {
22
+ default?: string | number;
23
+ }) => T;
24
+ }>(command: T, spec: readonly ParamSpec[]): T;
21
25
  export declare function registerCopied(cli: CAC): void;
22
- export declare function outputUrls(detail: {
23
- outputs?: Array<{
24
- url?: string;
25
- }>;
26
- }): string[];
27
- export declare function parsePollOptions(options: {
28
- interval?: unknown;
29
- timeout?: unknown;
30
- }, warnShort?: boolean): {
31
- initialIntervalMs: number;
32
- timeoutMs: number;
33
- };
34
- export declare function pollConfirmed(api: LumenKeyClient, jobId: string, options: {
35
- interval?: unknown;
36
- timeout?: unknown;
37
- }): Promise<GenerationJobDetail>;
38
- export declare function finishGeneration(api: LumenKeyClient, created: {
39
- jobId: string;
40
- idempotencyKey: string;
41
- }, options: Record<string, unknown>): Promise<void>;
42
- export declare function emitJobDetail(detail: GenerationJobDetail): void;
43
26
  export declare function promptForKey(): Promise<string | undefined>;
44
27
  export declare function readSecret(input?: NodeJS.ReadStream, output?: NodeJS.WritableStream): Promise<string>;
45
28
  //# sourceMappingURL=copied.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"copied.d.ts","sourceRoot":"","sources":["../../src/cli/copied.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"copied.d.ts","sourceRoot":"","sources":["../../src/cli/copied.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAW/B,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAA8H,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC/K,OAAO,EAAqD,KAAK,mBAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC1I,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAIhE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAcxC,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,WAAe,GAAG,MAAM,GAAG,SAAS,CAYlF;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAS7F;AAED,+GAA+G;AAC/G,wBAAgB,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,IAAI,EAAE,IAAI,WAAe,GAAG,IAAI,CAMhF;AAMD,wBAAgB,yBAAyB,IAAI,IAAI,CAGhD;AAED,mHAAmH;AACnH,wBAAsB,cAAc,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAa5F;AAMD,4GAA4G;AAC5G,wBAAgB,mBAAmB,IAAI,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CA0BtE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,GAAG,YAAY,GAAG,mBAAmB,CAAC,GAAG,IAAI,CAazG;AAED,kJAAkJ;AAClJ,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,EAAE,IAAI,EAAE,SAAS,SAAS,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB3I;AAED,wDAAwD;AACxD,wBAAgB,eAAe,CAAC,CAAC,SAAS;IAAE,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,KAAK,CAAC,CAAA;CAAE,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,SAAS,EAAE,GAAG,CAAC,CAGlL;AAsBD,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAqQ7C;AAwCD,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAIhE;AAED,wBAAsB,UAAU,CAC9B,KAAK,GAAE,MAAM,CAAC,UAA0B,EACxC,MAAM,GAAE,MAAM,CAAC,cAA+B,GAC7C,OAAO,CAAC,MAAM,CAAC,CA6DjB"}