@xship/cli 0.0.0-stage → 0.0.36

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 (93) hide show
  1. package/LICENSE +25 -0
  2. package/README.md +68 -2
  3. package/THIRD_PARTY_NOTICES.md +10 -0
  4. package/client-config.snapshot.json +377 -0
  5. package/codex-base-instructions.md +277 -0
  6. package/dist/brand.json +45 -0
  7. package/dist/cli.js +2 -0
  8. package/dist/client-config.snapshot.json +377 -0
  9. package/dist/commands/auth.js +1 -0
  10. package/dist/commands/base.js +1 -0
  11. package/dist/commands/bench.js +1 -0
  12. package/dist/commands/codex-sessions.js +1 -0
  13. package/dist/commands/completion.js +1 -0
  14. package/dist/commands/config.js +1 -0
  15. package/dist/commands/doctor.js +1 -0
  16. package/dist/commands/index.js +1 -0
  17. package/dist/commands/lang.js +1 -0
  18. package/dist/commands/logs.js +1 -0
  19. package/dist/commands/refresh.js +1 -0
  20. package/dist/commands/sessions.js +1 -0
  21. package/dist/commands/setup.js +1 -0
  22. package/dist/commands/status.js +1 -0
  23. package/dist/commands/update.js +1 -0
  24. package/dist/commands/upgrade.js +1 -0
  25. package/dist/index.js +1 -0
  26. package/dist/lib/api-validator.js +1 -0
  27. package/dist/lib/auto-update.js +1 -0
  28. package/dist/lib/brand.js +1 -0
  29. package/dist/lib/claude-code-manager.js +1 -0
  30. package/dist/lib/cli-help.js +1 -0
  31. package/dist/lib/client-config-sync.js +1 -0
  32. package/dist/lib/client-config.js +1 -0
  33. package/dist/lib/codex-sessions.js +1 -0
  34. package/dist/lib/command-docs.js +1 -0
  35. package/dist/lib/command.js +1 -0
  36. package/dist/lib/config.js +1 -0
  37. package/dist/lib/confirm.js +1 -0
  38. package/dist/lib/dry-run.js +1 -0
  39. package/dist/lib/env-cleanup.js +1 -0
  40. package/dist/lib/errors.js +1 -0
  41. package/dist/lib/gateway-addresses.js +1 -0
  42. package/dist/lib/gateway-models.js +1 -0
  43. package/dist/lib/gateway-protocol.js +1 -0
  44. package/dist/lib/i18n.js +1 -0
  45. package/dist/lib/key-balance.js +1 -0
  46. package/dist/lib/model-catalog.js +1 -0
  47. package/dist/lib/model-refresh.js +1 -0
  48. package/dist/lib/model-registry.js +1 -0
  49. package/dist/lib/opencode-manager.js +1 -0
  50. package/dist/lib/persistent-env.js +1 -0
  51. package/dist/lib/post-apply.js +1 -0
  52. package/dist/lib/program.js +1 -0
  53. package/dist/lib/runtime-options.js +1 -0
  54. package/dist/lib/secret-store.js +1 -0
  55. package/dist/lib/sessions/formats.js +1 -0
  56. package/dist/lib/sessions/index.js +1 -0
  57. package/dist/lib/settings-template.js +1 -0
  58. package/dist/lib/stream-check.js +1 -0
  59. package/dist/lib/telemetry.js +1 -0
  60. package/dist/lib/tool-manager.js +1 -0
  61. package/dist/lib/tool-upgrade.js +1 -0
  62. package/dist/lib/tools/antigravity.js +1 -0
  63. package/dist/lib/tools/atomcode.js +1 -0
  64. package/dist/lib/tools/backup.js +1 -0
  65. package/dist/lib/tools/claude-code.js +1 -0
  66. package/dist/lib/tools/claude-desktop-cli.js +1 -0
  67. package/dist/lib/tools/claude-desktop.js +1 -0
  68. package/dist/lib/tools/claude-managed.js +1 -0
  69. package/dist/lib/tools/claude-native-mirror.js +1 -0
  70. package/dist/lib/tools/claude-plugins.js +1 -0
  71. package/dist/lib/tools/codex-catalog.js +1 -0
  72. package/dist/lib/tools/codex.js +1 -0
  73. package/dist/lib/tools/desktop-process.js +1 -0
  74. package/dist/lib/tools/elevated-reg.js +1 -0
  75. package/dist/lib/tools/grok.js +1 -0
  76. package/dist/lib/tools/hermes.js +1 -0
  77. package/dist/lib/tools/openclaw.js +1 -0
  78. package/dist/lib/tools/opencode.js +1 -0
  79. package/dist/lib/tools/registry.js +1 -0
  80. package/dist/lib/tools/tool-installs.js +1 -0
  81. package/dist/lib/tools/types.js +1 -0
  82. package/dist/lib/windows-env.js +1 -0
  83. package/dist/lib/wizard.js +1 -0
  84. package/dist/lib/write-plan.js +1 -0
  85. package/dist/locales/en_US.json +1051 -0
  86. package/dist/locales/zh_CN.json +1051 -0
  87. package/dist/models.json +301 -0
  88. package/dist/settings-template.json +18 -0
  89. package/dist/utils/logger.js +1 -0
  90. package/dist/utils/string-width.js +1 -0
  91. package/models.json +301 -0
  92. package/package.json +48 -4
  93. package/settings-template.json +18 -0
@@ -0,0 +1,377 @@
1
+ {
2
+ "announcements": [],
3
+ "defaults": {
4
+ "language": "zh-CN",
5
+ "permission_mode": "full_auto"
6
+ },
7
+ "features": {},
8
+ "min_client_version": "",
9
+ "models": {
10
+ "claude": [
11
+ {
12
+ "description": "100 万上下文 | 高强度推理 | 长时 Agent | SWE-bench Verified 95%",
13
+ "group": "grp_pzxnceygmqlp",
14
+ "group_name": "",
15
+ "hidden": false,
16
+ "id": "claude-fable-5",
17
+ "name": "claude-fable-5",
18
+ "recommended": false
19
+ },
20
+ {
21
+ "description": "100 万上下文 | 12.8 万输出 | 自适应思考常开 | 长时 Agent 与多步研究",
22
+ "group": "grp_pzxnceygmqlp",
23
+ "group_name": "",
24
+ "hidden": false,
25
+ "id": "claude-fable-5-1",
26
+ "name": "claude-fable-5-1",
27
+ "recommended": false
28
+ },
29
+ {
30
+ "description": "轻量档 | 低延迟 | 高频短任务",
31
+ "group": "grp_6lyxfgbs440g",
32
+ "group_name": "",
33
+ "hidden": false,
34
+ "id": "claude-haiku-4-5-20251001",
35
+ "name": "claude-haiku-4-5-20251001",
36
+ "recommended": false
37
+ },
38
+ {
39
+ "description": "100 万上下文 | 12.8 万输出 | 低延迟 | 高频轻量任务",
40
+ "group": "grp_pzxnceygmqlp",
41
+ "group_name": "",
42
+ "hidden": false,
43
+ "id": "claude-haiku-5-5",
44
+ "name": "claude-haiku-5-5",
45
+ "recommended": false
46
+ },
47
+ {
48
+ "description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
49
+ "group": "grp_pzxnceygmqlp",
50
+ "group_name": "",
51
+ "hidden": false,
52
+ "id": "claude-opus-4-6",
53
+ "name": "claude-opus-4-6",
54
+ "recommended": false
55
+ },
56
+ {
57
+ "description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
58
+ "group": "grp_pzxnceygmqlp",
59
+ "group_name": "",
60
+ "hidden": false,
61
+ "id": "claude-opus-4-7",
62
+ "name": "claude-opus-4-7",
63
+ "recommended": false
64
+ },
65
+ {
66
+ "description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
67
+ "group": "grp_6co8aqwefsoh",
68
+ "group_name": "",
69
+ "hidden": false,
70
+ "id": "claude-opus-4-8",
71
+ "name": "claude-opus-4-8",
72
+ "recommended": false
73
+ },
74
+ {
75
+ "description": "100 万上下文 | 12.8 万输出 | 自适应思考五档 | Agent 编程",
76
+ "group": "grp_6lyxfgbs440g",
77
+ "group_name": "",
78
+ "hidden": false,
79
+ "id": "claude-opus-5",
80
+ "name": "claude-opus-5",
81
+ "recommended": false
82
+ },
83
+ {
84
+ "description": "100 万上下文 | 长时 Agent 编程 | 知识工作",
85
+ "group": "grp_6lyxfgbs440g",
86
+ "group_name": "",
87
+ "hidden": false,
88
+ "id": "claude-opus-5-5",
89
+ "name": "claude-opus-5-5",
90
+ "recommended": true
91
+ },
92
+ {
93
+ "description": "100 万上下文 | Agent 编程 | 长上下文不加价",
94
+ "group": "grp_rld6af0zorqd",
95
+ "group_name": "",
96
+ "hidden": false,
97
+ "id": "claude-sonnet-4-6",
98
+ "name": "claude-sonnet-4-6",
99
+ "recommended": false
100
+ },
101
+ {
102
+ "description": "100 万上下文 | Agent 编程 | 工具调用 | 知识工作",
103
+ "group": "grp_rld6af0zorqd",
104
+ "group_name": "",
105
+ "hidden": false,
106
+ "id": "claude-sonnet-5",
107
+ "name": "claude-sonnet-5",
108
+ "recommended": false
109
+ },
110
+ {
111
+ "description": "100 万上下文 | 12.8 万输出 | Agent 编程 | 知识工作",
112
+ "group": "grp_rld6af0zorqd",
113
+ "group_name": "",
114
+ "hidden": false,
115
+ "id": "claude-sonnet-5-5",
116
+ "name": "claude-sonnet-5-5",
117
+ "recommended": false
118
+ }
119
+ ],
120
+ "codex": [
121
+ {
122
+ "description": "100 万上下文 | 12.8 万输出 | 复杂专业负载",
123
+ "group": "grp_6co8aqwefsoh",
124
+ "group_name": "",
125
+ "hidden": false,
126
+ "id": "gpt-5.5",
127
+ "name": "gpt-5.5",
128
+ "recommended": false
129
+ },
130
+ {
131
+ "description": "105 万上下文 | 12.8 万输出 | 大批量低成本档",
132
+ "group": "grp_irydsgijuckh",
133
+ "group_name": "",
134
+ "hidden": false,
135
+ "id": "gpt-5.6-luna",
136
+ "name": "gpt-5.6-luna",
137
+ "recommended": false
138
+ },
139
+ {
140
+ "description": "105 万上下文 | 12.8 万输出 | 前沿档",
141
+ "group": "grp_mb5v069lpnze",
142
+ "group_name": "",
143
+ "hidden": false,
144
+ "id": "gpt-5.6-sol",
145
+ "name": "gpt-5.6-sol",
146
+ "recommended": false
147
+ },
148
+ {
149
+ "description": "105 万上下文 | 12.8 万输出 | 均衡生产档",
150
+ "group": "grp_squ2qzjnehps",
151
+ "group_name": "",
152
+ "hidden": false,
153
+ "id": "gpt-5.6-terra",
154
+ "name": "gpt-5.6-terra",
155
+ "recommended": false
156
+ },
157
+ {
158
+ "description": "105 万上下文 | 12.8 万输出 | 思考强度至 max | 计算机操作 / 编码 / 科学基准接近饱和",
159
+ "group": "grp_irydsgijuckh",
160
+ "group_name": "",
161
+ "hidden": false,
162
+ "id": "gpt-6-astra",
163
+ "name": "gpt-6-astra",
164
+ "recommended": true
165
+ },
166
+ {
167
+ "description": "转发至 gpt-6-sol | 实际由 gpt-6-sol 响应 | 105 万上下文 | 12.8 万输出",
168
+ "group": "grp_irydsgijuckh",
169
+ "group_name": "",
170
+ "hidden": false,
171
+ "id": "gpt-6-luna",
172
+ "name": "gpt-6-luna",
173
+ "recommended": false
174
+ },
175
+ {
176
+ "description": "105 万上下文 | 12.8 万输出 | 复杂编程与 Agent 工作流",
177
+ "group": "grp_6co8aqwefsoh",
178
+ "group_name": "",
179
+ "hidden": false,
180
+ "id": "gpt-6-sol",
181
+ "name": "gpt-6-sol",
182
+ "recommended": false
183
+ },
184
+ {
185
+ "description": "105 万上下文 | 12.8 万输出 | 文字与图像输入 | 工具调用、联网搜索、结构化输出 | 工具调用使用 Responses API",
186
+ "group": "grp_irydsgijuckh",
187
+ "group_name": "",
188
+ "hidden": false,
189
+ "id": "gpt-6.1-sol",
190
+ "name": "gpt-6.1-sol",
191
+ "recommended": false
192
+ }
193
+ ],
194
+ "gemini": [
195
+ {
196
+ "description": "高吞吐 | 低延迟 | 大批量",
197
+ "group": "grp_3pi5kyqkp51b",
198
+ "group_name": "",
199
+ "hidden": false,
200
+ "id": "gemini-3-flash",
201
+ "name": "gemini-3-flash",
202
+ "recommended": false
203
+ },
204
+ {
205
+ "description": "约 100 万上下文 | 深度推理 | 长文档一致性",
206
+ "group": "grp_3pi5kyqkp51b",
207
+ "group_name": "",
208
+ "hidden": false,
209
+ "id": "gemini-3-pro",
210
+ "name": "gemini-3-pro",
211
+ "recommended": false
212
+ },
213
+ {
214
+ "description": "Gemini 3.1 Flash-Lite 预览版 | 约 100 万上下文 | 低成本 | 高吞吐",
215
+ "group": "grp_3pi5kyqkp51b",
216
+ "group_name": "",
217
+ "hidden": false,
218
+ "id": "gemini-3.1-flash-lite-preview",
219
+ "name": "gemini-3.1-flash-lite-preview",
220
+ "recommended": false
221
+ },
222
+ {
223
+ "description": "约 100 万上下文 | 深度推理 | 密集长文档",
224
+ "group": "grp_3pi5kyqkp51b",
225
+ "group_name": "",
226
+ "hidden": false,
227
+ "id": "gemini-3.1-pro",
228
+ "name": "gemini-3.1-pro",
229
+ "recommended": false
230
+ },
231
+ {
232
+ "description": "Gemini 3.1 Pro 预览版 | 约 100 万上下文 | 深度推理 | 文本、图像、音视频输入",
233
+ "group": "grp_3pi5kyqkp51b",
234
+ "group_name": "",
235
+ "hidden": false,
236
+ "id": "gemini-3.1-pro-preview",
237
+ "name": "gemini-3.1-pro-preview",
238
+ "recommended": false
239
+ },
240
+ {
241
+ "description": "高吞吐 | 低成本 | 大批量常规任务",
242
+ "group": "grp_3pi5kyqkp51b",
243
+ "group_name": "",
244
+ "hidden": false,
245
+ "id": "gemini-3.5-flash",
246
+ "name": "gemini-3.5-flash",
247
+ "recommended": false
248
+ },
249
+ {
250
+ "description": "约 208 token/秒 | 高吞吐 | 多语言 | 编码",
251
+ "group": "grp_6co8aqwefsoh",
252
+ "group_name": "",
253
+ "hidden": false,
254
+ "id": "gemini-3.6-flash",
255
+ "name": "gemini-3.6-flash",
256
+ "recommended": false
257
+ },
258
+ {
259
+ "description": "Agent 主力 | 软件工程 | 网页开发",
260
+ "group": "grp_3pi5kyqkp51b",
261
+ "group_name": "",
262
+ "hidden": false,
263
+ "id": "gemini-3.7-flash",
264
+ "name": "gemini-3.7-flash",
265
+ "recommended": false
266
+ },
267
+ {
268
+ "description": "推理与编码 | HLE-Verified 54.9% | 长文档工作流",
269
+ "group": "grp_3pi5kyqkp51b",
270
+ "group_name": "",
271
+ "hidden": false,
272
+ "id": "gemini-3.8-flash",
273
+ "name": "gemini-3.8-flash",
274
+ "recommended": true
275
+ },
276
+ {
277
+ "description": "约 100 万上下文 | 深度推理 | 文本、图像、音视频输入",
278
+ "group": "grp_3pi5kyqkp51b",
279
+ "group_name": "",
280
+ "hidden": false,
281
+ "id": "gemini-4-argon",
282
+ "name": "gemini-4-argon",
283
+ "recommended": false
284
+ },
285
+ {
286
+ "description": "Nano Banana 2.1 | 图像生成与编辑 | 1K / 2K / 4K | 最多 6 张参考图",
287
+ "group": "grp_lidtulcm988s",
288
+ "group_name": "",
289
+ "hidden": false,
290
+ "id": "gemini-nano-banana-2.1",
291
+ "name": "gemini-nano-banana-2.1",
292
+ "recommended": false
293
+ }
294
+ ],
295
+ "grok": [
296
+ {
297
+ "description": "50 万上下文 | 1.5 万亿参数 MoE | 编码与 Agent",
298
+ "group": "grp_irydsgijuckh",
299
+ "group_name": "",
300
+ "hidden": false,
301
+ "id": "grok-4.5",
302
+ "name": "grok-4.5",
303
+ "recommended": false
304
+ },
305
+ {
306
+ "description": "50 万上下文 | 思考强度四档 | 编码与 Agent",
307
+ "group": "grp_l34dwliv4yas",
308
+ "group_name": "",
309
+ "hidden": false,
310
+ "id": "grok-4.6",
311
+ "name": "grok-4.6",
312
+ "recommended": false
313
+ },
314
+ {
315
+ "description": "50 万上下文 | 长时 Agent | 编码与视觉项目",
316
+ "group": "grp_l34dwliv4yas",
317
+ "group_name": "",
318
+ "hidden": false,
319
+ "id": "grok-4.7",
320
+ "name": "grok-4.7",
321
+ "recommended": true
322
+ }
323
+ ]
324
+ },
325
+ "profiles": [
326
+ {
327
+ "default": true,
328
+ "id": "claude-opus-medium",
329
+ "model": "claude-opus-5-5",
330
+ "name": "Claude Opus 5.5 · Medium",
331
+ "permission_mode": "full_auto",
332
+ "thinking": "medium",
333
+ "tool": "claude"
334
+ },
335
+ {
336
+ "default": false,
337
+ "id": "codex-gpt-6-astra",
338
+ "model": "gpt-6-astra",
339
+ "name": "Codex · GPT-6 Astra",
340
+ "permission_mode": "full_auto",
341
+ "tool": "codex"
342
+ },
343
+ {
344
+ "default": false,
345
+ "id": "grok-4-7",
346
+ "model": "grok-4.7",
347
+ "name": "Grok 4.7",
348
+ "permission_mode": "full_auto",
349
+ "tool": "grok"
350
+ },
351
+ {
352
+ "default": false,
353
+ "id": "gemini-3-8-flash",
354
+ "model": "gemini-3.8-flash",
355
+ "name": "Gemini 3.8 Flash",
356
+ "permission_mode": "full_auto",
357
+ "tool": "gemini"
358
+ }
359
+ ],
360
+ "revision": "builtin-1",
361
+ "schema": 1,
362
+ "tools": {
363
+ "claude": {
364
+ "min_version": ""
365
+ },
366
+ "codex": {
367
+ "min_version": ""
368
+ },
369
+ "gemini": {
370
+ "min_version": ""
371
+ },
372
+ "grok": {
373
+ "min_version": ""
374
+ }
375
+ },
376
+ "upgrade_message": ""
377
+ }
@@ -0,0 +1 @@
1
+ import e from"chalk";import o from"inquirer";import t from"ora";import{configManager as r}from"../lib/config.js";import{i18n as a}from"../lib/i18n.js";import{validateApiKey as i}from"../lib/api-validator.js";import{toolManager as n}from"../lib/tool-manager.js";import{isJsonMode as s,isNonInteractive as c,shouldAutoConfirm as d,emitJson as l,isColorEnabled as p}from"../lib/runtime-options.js";import{authenticationError as m,CliError as u,networkError as _,operationError as f,usageError as h}from"../lib/errors.js";import{CLI_NAME as k}from"../lib/brand.js";const w=["claude","claude-code","opencode"];function y(e){return p()?e:e=>e}function g(e,o=e=>e){s()||console.log(y(o)(e))}function v(e){return"invalid_api_key"===e.error?m(a.t("wizard.api_key_invalid"),a.t("errors.next_step",{command:`${k} auth ${a.t("errors.key_placeholder")}`}),"invalid_api_key"):_(a.t("wizard.api_key_network_error"),e.message??"",e.error??"network_error")}async function b(o){if(s()){const e=await i(o);if(!e.valid)throw v(e);return r.setApiKey(o),void l({ok:!0,action:"auth"})}const n=t(a.t("wizard.validating_api_key")).start(),c=await i(o);if(!c.valid)throw n.stop(),v(c);r.setApiKey(o),n.succeed(y(e.green)(a.t("auth.saved")))}export async function authCommand(t){0!==t.length?"revoke"!==t[0]?"reload"!==t[0]?await b(t[0]):await async function(o){const t=o.toLowerCase();if(!w.includes(t))throw h(a.t("auth.reload_tool_not_supported",{tool:o}),a.t("errors.next_step",{command:`${k} auth reload claude-code`}),"unsupported_tool");const i="opencode"===t?"opencode":"claude-code",c=r.getApiKeyForTool(i)||r.getApiKey();if(!c)throw h(a.t("bench.missing_api_key"),a.t("errors.next_step",{command:`${k} setup --key ${a.t("errors.key_placeholder")}`}),"missing_api_key");const d="opencode"===t?"OpenCode":"Claude Code";s()||g(a.t("auth.reloading",{tool:d}),e.blue);try{await n.applyPrivateConfig(i,c,r.getModelsForTool(i)),s()?l({ok:!0,action:"reload",tool:i}):g(a.t("auth.reloaded",{tool:d}),e.green)}catch(e){throw f(`${a.t("auth.reload_failed")} ${e instanceof Error?e.message:String(e)}`,a.t("errors.hint_logs"),"reload_failed")}}(t[1]||""):await async function(){if(!d()){const{confirm:e}=await o.prompt([{type:"confirm",name:"confirm",message:a.t("auth.revoke_confirm"),default:!1}]);if(!e)throw new u("cancelled",a.t("auth.not_revoked"),"","user_cancelled")}r.revokeApiKey(),s()?l({ok:!0,action:"revoke"}):g(a.t("auth.revoked"),e.green)}():await async function(){if(c())throw h(a.t("runtime.non_interactive_required_token"),a.t("errors.next_step",{command:`${k} auth ${a.t("errors.key_placeholder")}`}),"token_required");const{token:e}=await o.prompt([{type:"password",name:"token",message:a.t("auth.token_prompt"),validate:e=>!(!e||0===e.trim().length)||a.t("auth.token_required")}]);await b(e.trim())}()}
@@ -0,0 +1 @@
1
+ import e from"chalk";import{configManager as r,DEFAULT_BASE_URL as t}from"../lib/config.js";import{i18n as o}from"../lib/i18n.js";import{toolManager as s}from"../lib/tool-manager.js";import{listAdapters as a}from"../lib/tools/registry.js";import{postApplyPrompts as n}from"../lib/post-apply.js";import{emitJson as l,isJsonMode as i}from"../lib/runtime-options.js";import{logger as u}from"../utils/logger.js";import{reportCliError as c,usageError as p,authenticationError as d,networkError as f,operationError as m}from"../lib/errors.js";import{gatewayAddresses as b,normalizeBaseUrl as y,probeGatewayAddress as g}from"../lib/gateway-addresses.js";import{CLI_NAME as h}from"../lib/brand.js";export async function baseCommand(s){const a=r.getBaseUrl(),n=addressesWithCurrent(),u=s?.trim().toLowerCase();if(!u)return void await async function(r,t){const s=savedApiKey(),a=await probeAll(r,{apiKey:s,samples:3});i()?l({ok:!0,current:t,addresses:r.map((e,r)=>({...e,...a[r],current:e.url===t}))}):(console.log(e.bold(o.t("base.current",{url:t}))),console.log(e.gray(o.t(s?"base.probe_with_key":"base.probe_without_key"))+"\n"),w(r,a,t),console.log("\n"+e.gray(o.t("base.usage_hint"))))}(n,a);if("auto"===u){const e=await probeAll(n,{apiKey:savedApiKey()}),r=e.find(e=>e.ok);if(!r){const r=e.every(e=>"key_rejected"===e.error);return _(r?"key_rejected":"no_reachable",o.t(r?"base.key_rejected_everywhere":"base.none_reachable")),void w(n,e,a)}return void await switchGatewayAddress(r.url)}let c;if("default"===u||"reset"===u)c=t;else if(/^\d+$/.test(u)){if(c=n[Number(u)-1]?.url??null,!c)return void _("bad_index",o.t("base.bad_index",{index:u,count:String(n.length)}))}else if(c=y(s),!c)return void _("bad_url",o.t("base.bad_url",{value:s}));const p=await g(c,{apiKey:savedApiKey()});p.ok?await switchGatewayAddress(c):_("unreachable",o.t("base.unreachable",{url:c,reason:reasonText(p)}))}export async function ensureReachableGatewayAddress(s=savedApiKey()){if(r.hasRuntimeBaseUrl())return null;const a=r.getBaseUrl(),n=await g(a,{apiKey:s});if(n.ok||"key_rejected"===n.error)return null;const l=b().filter(e=>e.url!==a),u=(await probeAll(l,{apiKey:s})).find(e=>e.ok);if(!u)return null;if(u.url===t?r.resetBaseUrl():r.setBaseUrl(u.url,!0),!i()){const r=u.url===t?"base.setup_fallback_main":"base.setup_fallback";console.log(e.yellow(o.t(r,{from:a,reason:reasonText(n),url:u.url})))}return u.url}export function addressesWithCurrent(){const e=r.getBaseUrl(),t=b();return t.some(r=>r.url===e)||t.push({url:e,label:o.t("base.custom_label")}),t}export function savedApiKey(){return r.getApiKey()||a().map(e=>r.getApiKeyForTool(e.name)).find(Boolean)}export async function probeAll(e,r={}){return Promise.all(e.map(e=>g(e.url,r)))}export function probeSummary(r,t){if(!r.ok)return e.red(`× ${reasonText(r)}`);const s=[`${r.ms} ms`];return void 0!==r.models&&s.push(o.t("base.models_count",{count:String(r.models)})),t&&s.push(o.t("base.fastest")),e.green(`√ ${s.join(" · ")}`)}export function fastestIndex(e){let r=-1;return e.forEach((t,o)=>{t.ok&&(r<0||t.ms<e[r].ms)&&(r=o)}),r}export function reasonText(e){if(!e.error)return"";const r=o.t(`base.error_${e.error}`);return e.detail?`${r}(${e.detail})`:r}function _(e,r){const t="bad_index"===e||"bad_url"===e?p(r,o.t("errors.next_step",{command:`${h} base --help`}),e):"key_rejected"===e?d(r,o.t("errors.next_step",{command:`${h} setup --key ${o.t("errors.key_placeholder")}`}),e):f(r,o.t("base.next_addresses"),e);c(t)}function w(r,t,s){if(i())return;const a=t.length>1?fastestIndex(t):-1;r.forEach((r,n)=>{const l=r.url===s?e.cyan(` ← ${o.t("base.current_mark")}`):"";console.log(`${n+1}. ${r.url} ${e.gray(r.label)}\n ${probeSummary(t[n],n===a)}${l}`)})}export async function switchGatewayAddress(p){const d=r.getBaseUrl();p===t?r.resetBaseUrl():r.setBaseUrl(p,!0);const f=[],b=[];for(const e of function(){const e=[];for(const t of a()){const o=r.getApiKeyForTool(t.name);if(o)try{t.detectCurrentConfig().apiKey===o&&e.push(t.name)}catch(e){u.logError(`base.detectCurrentConfig(${t.name})`,e)}}return e}()){const t=r.getApiKeyForTool(e);try{await s.applyPrivateConfig(e,t,r.getModelsForTool(e)),f.push(e)}catch(r){b.push({tool:e,reason:r instanceof Error?r.message:String(r)})}}if(b.length>0&&c(m(b.map(({tool:e,reason:r})=>`${e}: ${r}`).join("; "),o.t("errors.next_step",{command:`${h} setup --key ${o.t("errors.key_placeholder")}`}),"config_write_failed")),i()&&0===b.length)l({ok:0===b.length,previous:d,base_url:p,applied:f,failed:b});else{console.log(e.green(o.t(p===d?"base.kept":"base.switched",{url:p}))),f.length>0&&console.log(o.t("base.tools_moved"));for(const e of f)s.printApplied(e);for(const{tool:r,reason:t}of b)console.error(e.red(`× ${o.t("setup.apply_failed",{tool:r,reason:t})}`));0===f.length&&0===b.length&&console.log(e.yellow(o.t("base.no_tools",{url:p}))),await n(f)}}
@@ -0,0 +1 @@
1
+ import e from"chalk";import{configManager as o}from"../lib/config.js";import{savedApiKey as t}from"./base.js";import{i18n as s}from"../lib/i18n.js";import{isJsonMode as r,emitJson as n,isColorEnabled as l}from"../lib/runtime-options.js";import{usageError as a}from"../lib/errors.js";import{CLI_NAME as i}from"../lib/brand.js";import{runStreamCheck as m}from"../lib/stream-check.js";import{getDefaultModels as c,getToolDefaultModel as h}from"../lib/model-registry.js";function p(e){return l()?e:e=>e}export function pickStreamModel(e){return[c().haiku,h("codex")].map(e=>e.replace(/\[[^\]]*\]$/,"")).filter(Boolean).find(o=>e.includes(o))??e[0]}export async function benchCommand(l,c=function(e){let o,t=5,s=!1;for(let r=0;r<e.length;r+=1)if("--stream"===e[r]&&(s=!0),"--model"===e[r]&&e[r+1]&&(o=e[r+1]),"--samples"===e[r]&&e[r+1]){const o=Number.parseInt(e[r+1],10);Number.isFinite(o)&&o>0&&o<=50&&(t=o)}return{samples:t,stream:s,model:o}}(l)){const h=t();if(!h)throw a(s.t("bench.missing_api_key"),s.t("errors.next_step",{command:`${i} setup --key ${s.t("errors.key_placeholder")}`}),"missing_api_key");const d=c.fetchFn||fetch,g=o.getBaseUrl(),f=`${g}/v1/models`,b={samples:c.samples,errors:0,durations:[]};let u=[];r()||console.log(p(e.gray)(s.t("bench.running")));for(let e=0;e<c.samples;e+=1){const e=Date.now();try{const o=await d(f,{method:"GET",headers:{Authorization:`Bearer ${h}`,Accept:"application/json"}});if(!o.ok){b.errors+=1;continue}if(b.durations.push(Date.now()-e),c.stream&&0===u.length){const e=await o.json().catch(()=>null);u=(e?.data??[]).map(e=>e.id).filter(e=>"string"==typeof e)}}catch{b.errors+=1}}const _=function(e){const o=e.durations.slice().sort((e,o)=>e-o),t=o.reduce((e,o)=>e+o,0),s=0===o.length?0:o.length%2==0?(o[o.length/2-1]+o[o.length/2])/2:o[Math.floor(o.length/2)],r=0===o.length?0:t/o.length;return{samples:e.samples,completed:o.length,errors:e.errors,median_ms:Math.round(s),average_ms:Math.round(r),min_ms:o[0]||0,max_ms:o[o.length-1]||0}}(b),$=b.errors===c.samples;let k;if(c.stream){const o=c.model??pickStreamModel(u);r()||console.log(p(e.gray)(s.t("bench.stream_running",{model:o??"-"}))),k=o?await m({baseUrl:g,apiKey:h,model:o,fetchFn:d}):{ok:!1,failure:"no_model"}}if(r())return n({ok:!$&&(k?.ok??!0),base_url:g,..._,...k?{stream:k}:{}}),void(k&&!k.ok&&(process.exitCode=1));console.log("\n"+p(e.bold)(s.t("bench.result_title"))),console.log(` ${s.t("bench.samples")}: ${_.samples}`),console.log(` ${s.t("bench.median")}: ${_.median_ms}ms`),console.log(` ${s.t("bench.average")}: ${_.average_ms}ms`),console.log(` ${s.t("bench.min")}: ${_.min_ms}ms`),console.log(` ${s.t("bench.max")}: ${_.max_ms}ms`),console.log(` ${s.t("bench.errors")}: ${_.errors}`),k?function(o){console.log("\n"+p(e.bold)(s.t("bench.stream_title"))),"model"in o&&(console.log(` ${s.t("bench.stream_model")}: ${o.model} (${"anthropic"===o.protocol?"Anthropic Messages":"Chat Completions"})`),void 0!==o.first_token_ms&&console.log(` ${s.t("bench.stream_first_token")}: ${o.first_token_ms}ms`),console.log(` ${s.t("bench.stream_total")}: ${o.total_ms}ms`));const t=o.ok?p(e.green)("√ "+s.t("bench.stream_ok")):p(e.red)("× "+s.t(`bench.stream_fail.${o.failure}`,{cli:i}));console.log(` ${t}`),!o.ok&&"detail"in o&&o.detail&&console.log(p(e.gray)(` ${o.detail}`)),o.ok||(process.exitCode=1)}(k):console.log(p(e.gray)("\n"+s.t("bench.stream_hint",{cli:i})))}
@@ -0,0 +1 @@
1
+ import o from"chalk";import{i18n as s}from"../lib/i18n.js";import{isDryRun as e}from"../lib/runtime-options.js";import{currentCodexProvider as n,moveSessionsToProvider as i,NO_STATE_DB as t,runningCodexPids as r,undoSessionMove as d}from"../lib/codex-sessions.js";export async function codexSessionsCommand(c){const l=r();if(l.length>0)return console.error(o.yellow(s.t("codex_sessions.codex_running",{pids:l.join(", ")}))),void(process.exitCode=1);if(c.undo){const{files:e,dbRows:n}=await d(c.undo);return void console.log(o.green("√ "+s.t("codex_sessions.undone",{files:String(e),rows:String(n)})))}const g=c.to?.trim()||n(),m=await i(g,{dryRun:e()}),a=Math.max(m.moved.length,m.dbRows);if(0===a)return void console.log(s.t("codex_sessions.nothing",{target:g,scanned:String(m.scanned)}));const p=[...new Set(m.moved.map(o=>o.from))].join("、")||"-";e()?console.log(s.t("codex_sessions.dry_run",{count:String(a),from:p,target:g})):(console.log(o.green("√ "+s.t("codex_sessions.moved",{count:String(a),from:p,target:g}))),m.dbSkipped&&m.dbSkipped!==t&&console.log(o.yellow(" ! "+s.t("codex_sessions.db_skipped",{reason:m.dbSkipped}))),console.log(o.gray(" "+s.t("codex_sessions.backup",{dir:m.backupDir??""}))))}
@@ -0,0 +1 @@
1
+ import{i18n as n}from"../lib/i18n.js";import{isJsonMode as o,emitJson as e}from"../lib/runtime-options.js";import{CLI_NAME as s}from"../lib/brand.js";import{usageError as c}from"../lib/errors.js";const t=s.replace(/-/g,"_"),i=["init","setup","lang","auth","doctor","status","logs","completion","update","upgrade","codex","bench","base","config","enter"],r=["profile","preset","backup","claude-code","codex"],m=["list","create","use","delete"],l=["list","save","use","delete"],a=["list","create","restore"],p=["revoke","reload"],u=["show","set"],$=["path","list","tail"],_=["bash","zsh","fish"],d=["--base","--non-interactive","--json","--yes","--dry-run","--no-color","--help","--version"];export async function completionCommand(h){const b=(h[0]||"").toLowerCase();if(!_.includes(b))throw c(n.t("completion.unsupported_shell",{shell:b}),n.t("errors.next_step",{command:`${s} completion bash`}),"unsupported_shell");const f="bash"===b?`# ${s} bash completion\n_${t}_completions() {\n local cur prev\n COMPREPLY=()\n cur="\${COMP_WORDS[COMP_CWORD]}"\n prev="\${COMP_WORDS[COMP_CWORD-1]}"\n\n case "\${prev}" in\n ${s})\n COMPREPLY=( $(compgen -W "${i.join(" ")} ${d.join(" ")}" -- "\${cur}") )\n return 0\n ;;\n config)\n COMPREPLY=( $(compgen -W "${r.join(" ")}" -- "\${cur}") )\n return 0\n ;;\n profile)\n COMPREPLY=( $(compgen -W "${m.join(" ")}" -- "\${cur}") )\n return 0\n ;;\n preset)\n COMPREPLY=( $(compgen -W "${l.join(" ")}" -- "\${cur}") )\n return 0\n ;;\n backup)\n COMPREPLY=( $(compgen -W "${a.join(" ")}" -- "\${cur}") )\n return 0\n ;;\n auth)\n COMPREPLY=( $(compgen -W "${p.join(" ")}" -- "\${cur}") )\n return 0\n ;;\n lang)\n COMPREPLY=( $(compgen -W "${u.join(" ")}" -- "\${cur}") )\n return 0\n ;;\n logs)\n COMPREPLY=( $(compgen -W "${$.join(" ")}" -- "\${cur}") )\n return 0\n ;;\n completion)\n COMPREPLY=( $(compgen -W "${_.join(" ")}" -- "\${cur}") )\n return 0\n ;;\n esac\n\n if [[ "\${cur}" == --* ]]; then\n COMPREPLY=( $(compgen -W "${d.join(" ")}" -- "\${cur}") )\n return 0\n fi\n}\ncomplete -F _${t}_completions ${s}\n`:"zsh"===b?`#compdef ${s}\n_${t}() {\n local -a commands subcommands\n local context state line\n\n _arguments -C \\\n '(-h --help)'{-h,--help}'[Show help]' \\\n '(-v --version)'{-v,--version}'[Show version]' \\\n '--base[Custom API base URL]:url:' \\\n '--non-interactive[Disable interactive prompts]' \\\n '--json[Emit JSON output]' \\\n '(-y --yes)'{-y,--yes}'[Auto-confirm prompts]' \\\n '--dry-run[Show planned changes without writing]' \\\n '--no-color[Disable colored output]' \\\n '1:command:->command' \\\n '*::arg:->args'\n\n case $state in\n command)\n commands=(\n${i.map(n=>` '${n}:${s} ${n}'`).join("\n")}\n )\n _describe 'command' commands\n ;;\n args)\n case $line[1] in\n config)\n subcommands=(${r.map(n=>`'${n}'`).join(" ")})\n _describe 'config sub' subcommands\n ;;\n auth) _values 'auth sub' ${p.join(" ")} ;;\n lang) _values 'lang sub' ${u.join(" ")} ;;\n logs) _values 'logs action' ${$.join(" ")} ;;\n completion) _values 'shell' ${_.join(" ")} ;;\n esac\n ;;\n esac\n}\ncompdef _${t} ${s}\n`:`# ${s} fish completion\ncomplete -c ${s} -n "__fish_use_subcommand" -a "${i.join(" ")}"\ncomplete -c ${s} -n "__fish_seen_subcommand_from config" -a "${r.join(" ")}"\ncomplete -c ${s} -n "__fish_seen_subcommand_from profile" -a "${m.join(" ")}"\ncomplete -c ${s} -n "__fish_seen_subcommand_from preset" -a "${l.join(" ")}"\ncomplete -c ${s} -n "__fish_seen_subcommand_from backup" -a "${a.join(" ")}"\ncomplete -c ${s} -n "__fish_seen_subcommand_from auth" -a "${p.join(" ")}"\ncomplete -c ${s} -n "__fish_seen_subcommand_from lang" -a "${u.join(" ")}"\ncomplete -c ${s} -n "__fish_seen_subcommand_from logs" -a "${$.join(" ")}"\ncomplete -c ${s} -n "__fish_seen_subcommand_from completion" -a "${_.join(" ")}"\ncomplete -c ${s} -l base -d 'Custom API base URL'\ncomplete -c ${s} -l non-interactive -d 'Disable interactive prompts'\ncomplete -c ${s} -l json -d 'Emit JSON output'\ncomplete -c ${s} -l yes -s y -d 'Auto-confirm prompts'\ncomplete -c ${s} -l dry-run -d 'Show planned changes without writing'\ncomplete -c ${s} -l no-color -d 'Disable colored output'\n`;o()?e({shell:b,script:f}):(console.log(f),"bash"===b?console.log("# "+n.t("completion.instructions_bash")):"zsh"===b?console.log("# "+n.t("completion.instructions_zsh")):console.log("# "+n.t("completion.instructions_fish")))}
@@ -0,0 +1 @@
1
+ import o from"inquirer";import e from"chalk";import{wizard as t}from"../lib/wizard.js";import{toolManager as n,SUPPORTED_TOOLS as l}from"../lib/tool-manager.js";import{i18n as i}from"../lib/i18n.js";import{configManager as r,DEFAULT_PROFILE_NAME as a}from"../lib/config.js";import{confirmAction as s,applyOrDryRun as c}from"../lib/confirm.js";import{isDryRun as d,isNonInteractive as f,shouldAutoConfirm as g}from"../lib/runtime-options.js";const p=/^[a-zA-Z0-9._-]+$/;function m(o,e){const t=(o||"").trim();if(!t||!p.test(t))throw new Error(i.t(`config.${e}_invalid_name`,{name:t||"<empty>"}));return t}function _(o,t){console.log("\n"+e.bold(o)),0!==t.length?t.forEach(o=>console.log(" "+o)):console.log(e.gray(" ("+i.t("config.empty_list")+")"))}function u(o,t){if("backups"===t){const t=n.listToolBackups(o).flatMap(o=>{const t=o.file.replace(/^.*[/\\]/,"");return o.backups.length?o.backups.map(o=>`${e.cyan(t)} ${e.gray(o.name.split(".bak-")[1]||o.name)}`):[`${e.cyan(t)} ${e.gray("("+i.t("config.empty_list")+")")}`]});return void _(i.t("config.tool_backups_title",{tool:l[o].displayName}),t)}const r=n.restorePrivateConfig(o).filter(o=>o.result.restored);0!==r.length?(console.log(e.green(i.t("config.config_restored",{tool:l[o].displayName}))),r.forEach(o=>console.log(e.gray(` ${o.file} ← ${o.result.from}`))),console.log(e.yellow(" ! "+i.t("config.reopen_hint",{tool:l[o].displayName})))):console.log(e.yellow(i.t("config.restore_no_backup",{tool:l[o].displayName})))}async function y(a,f,g){if(!l[a])return void console.log(e.red(i.t("config.unknown_tool",{tool:a})));const p=(f[0]||"").toLowerCase();if("backups"!==p&&"list-backups"!==p)if("restore"!==p){if("remove"===p||"unload"===p){const o=l[a].displayName;return void await c({description:i.t("config.remove_dry_run",{tool:o}),json:{action:"remove",tool:a},apply:async()=>{if(!await s({message:i.t("config.confirm_remove",{tool:o,name:a}),defaultValue:!0}))return;const t=n.holdsOurConfig(a),l=n.unloadPrivateConfig(a);t?(console.log(e.green(i.t("config.remove_done",{tool:o}))),l.forEach(o=>console.log(e.yellow(" ! "+o.text)))):console.log(e.gray(i.t("config.remove_nothing",{tool:o})))}})}if("clear-model"===p||"clear-models"===p){const o=l[a].displayName;return n.supportsClearPinnedModels(a)?void await c({description:i.t("config.clear_model_dry_run",{tool:o}),json:{action:"clear_model",tool:a},apply:async()=>{const t=await n.clearPinnedModels(a);0!==t.length?(console.log(e.green(i.t("config.clear_model_done",{tool:o}))),t.forEach(o=>console.log(e.gray(` - ${o}`))),console.log(e.gray(i.t("config.clear_model_restart_hint",{tool:o})))):console.log(e.yellow(i.t("config.clear_model_none",{tool:o})))}}):void console.log(e.yellow(i.t("config.clear_model_unsupported",{tool:o})))}if(d())await c({description:i.t("config.tool_apply_dry_run",{tool:l[a].displayName}),json:{action:"apply",tool:a,force:Boolean(g.force)},apply:()=>{}});else{if(!n.isToolInstalled(a)){if(g.nonInteractive)return void console.log(e.yellow(i.t("wizard.tool_not_installed",{tool:l[a].displayName})));console.log(e.yellow(i.t("wizard.tool_not_installed",{tool:l[a].displayName})));const{shouldInstall:t}=await o.prompt([{type:"confirm",name:"shouldInstall",message:i.t("wizard.install_tool_confirm"),default:!0}]);if(!t)return void console.log(e.yellow(i.t("wizard.install_skipped")));try{await n.installTool(a)}catch(o){return console.error(e.red(i.t("install.install_failed_detail"))),void(o instanceof Error&&o.message&&console.error(e.gray(o.message)))}}if(g.nonInteractive||g.force){const o=r.getApiKeyForTool(a);if(!o)return void console.log(e.red(i.t("auth.reload_missing_config")));if(g.force&&!g.nonInteractive&&!await s({message:i.t("config.confirm_force",{tool:l[a].displayName}),defaultValue:!1}))return;return await n.applyPrivateConfig(a,o,r.getModelsForTool(a),{force:g.force}),g.force&&console.log(e.yellow(i.t("config.force_done",{tool:l[a].displayName,name:a}))),void n.printApplied(a)}await t.showToolMenu(a)}}else await c({description:i.t("config.tool_restore_dry_run",{tool:l[a].displayName}),json:{action:"tool_restore",tool:a},apply:async()=>{await s({message:i.t("config.confirm_restore",{tool:l[a].displayName}),defaultValue:!1})&&u(a,"restore")}});else u(a,"backups")}export async function configCommand(t){const{positional:n,options:d}=function(o){const e=[],t={};(f()||g())&&(t.nonInteractive=!0);for(const n of o)"--non-interactive"===n||"-y"===n?t.nonInteractive=!0:"--force"===n||"-f"===n?t.force=!0:e.push(n);return{positional:e,options:t}}(t),u=n[0],v=n.slice(1);if(u){switch(u){case"profile":return void await async function(o){const t=o[0],n=o[1];if(!t||"list"===t){const o=r.getActiveProfileName(),t=r.listProfiles().map(t=>{const n=t===o;return`${n?e.green("●"):e.gray("○")} ${t}${n?e.gray(" ("+i.t("config.profile_active_label")+")"):""}`});return void _(i.t("config.profile_list_title"),t)}if("create"===t){const o=m(n,"profile");return r.listProfiles().includes(o)?void console.log(e.yellow(i.t("config.profile_exists",{name:o}))):void await c({description:i.t("config.profile_create_dry_run",{name:o}),json:{action:"profile_create",name:o},apply:()=>{r.createProfile(o),console.log(e.green(i.t("config.profile_created",{name:o})))}})}if("use"===t){const o=m(n,"profile");return void await c({description:i.t("config.profile_use_dry_run",{name:o}),json:{action:"profile_use",name:o},apply:()=>{r.setActiveProfile(o),console.log(e.green(i.t("config.profile_activated",{name:o})))}})}if("delete"===t||"remove"===t){const o=m(n,"profile");return o===a&&1===r.listProfiles().length?void console.log(e.yellow(i.t("config.profile_cannot_delete_last"))):void await c({description:i.t("config.profile_delete_dry_run",{name:o}),json:{action:"profile_delete",name:o},apply:async()=>{await s({message:i.t("config.profile_delete_confirm",{name:o}),defaultValue:!1})?(r.deleteProfile(o),console.log(e.green(i.t("config.profile_deleted",{name:o})))):console.log(e.yellow(i.t("config.profile_delete_aborted")))}})}console.log(e.red(i.t("config.unknown_action",{action:t})))}(v);case"preset":return void await async function(o){const t=o[0],n=o[1];if(!t||"list"===t){const o=Object.entries(r.getCustomPresets()).map(([o,t])=>`${e.cyan(o)} ${e.gray(`H:${t.models.haiku} S:${t.models.sonnet} O:${t.models.opus}`)}`);return void _(i.t("config.preset_list_title"),o)}if("save"===t){const o=m(n,"preset");return void await c({description:i.t("config.preset_save_dry_run",{name:o}),json:{action:"preset_save",name:o},apply:()=>{r.saveCustomPreset(o,r.getModels()),console.log(e.green(i.t("config.preset_saved",{name:o})))}})}if("use"===t||"apply"===t){const o=m(n,"preset"),t=r.getCustomPresets()[o];return t?void await c({description:i.t("config.preset_use_dry_run",{name:o}),json:{action:"preset_use",name:o},apply:()=>{r.setModels(t.models),console.log(e.green(i.t("config.preset_applied",{name:o})))}}):void console.log(e.red(i.t("config.preset_not_found",{name:o})))}if("delete"===t||"remove"===t){const o=m(n,"preset");return void await c({description:i.t("config.preset_delete_dry_run",{name:o}),json:{action:"preset_delete",name:o},apply:()=>{r.deleteCustomPreset(o),console.log(e.green(i.t("config.preset_deleted",{name:o})))}})}console.log(e.red(i.t("config.unknown_action",{action:t})))}(v);case"tool-model":return void await async function(o){const t=o[0];if(!t||"list"===t){const o=r.getProfile().tool_models||{},t=Object.entries(o).map(([o,t])=>{const n=Object.entries(t).map(([o,e])=>`${o}=${e}`).join(" ");return`${e.cyan(o)} ${e.gray(n)}`});return void _(i.t("config.tool_model_list_title"),t)}if("set"===t){const t=(o[1]||"").trim(),n=o.length>=4?(o[2]||"").trim():"opus",a=(o.length>=4?o[3]:o[2]||"").trim();return l[t]?a&&p.test(n)?void await c({description:i.t("config.tool_model_set_dry_run",{tool:t,slot:n,model:a}),json:{action:"tool_model_set",tool:t,slot:n,model:a},apply:()=>{r.setToolModel(t,{[n]:a}),console.log(e.green(i.t("config.tool_model_set",{tool:t,slot:n,model:a})))}}):void console.log(e.red(i.t("config.tool_model_usage"))):void console.log(e.red(t?i.t("config.unknown_tool",{tool:t}):i.t("config.tool_model_usage")))}if("clear"===t||"remove"===t){const t=(o[1]||"").trim();return l[t]?void await c({description:i.t("config.tool_model_clear_dry_run",{tool:t}),json:{action:"tool_model_clear",tool:t},apply:()=>{r.setToolModel(t,null),console.log(e.green(i.t("config.tool_model_cleared",{tool:t})))}}):void console.log(e.red(t?i.t("config.unknown_tool",{tool:t}):i.t("config.tool_model_usage")))}console.log(e.red(i.t("config.unknown_action",{action:t})))}(v);case"backup":return void await function(o){return async function(o){const t=o[0],n=o[1];if(!t||"list"===t){const o=r.listBackups().map(o=>{const t=new Date(o.mtimeMs).toISOString();return`${e.cyan(o.name)} ${e.gray(t)}`});return void _(i.t("config.backup_list_title"),o)}if("create"!==t&&"snapshot"!==t)return"restore"===t?n?void await c({description:i.t("config.backup_restore_dry_run",{name:n}),json:{action:"backup_restore",name:n},apply:async()=>{await s({message:i.t("config.backup_restore_confirm",{name:n}),defaultValue:!1})?(r.restoreBackup(n),console.log(e.green(i.t("config.backup_restored",{name:n})))):console.log(e.yellow(i.t("config.backup_restore_aborted")))}}):void console.log(e.red(i.t("config.backup_restore_missing_name"))):void console.log(e.red(i.t("config.unknown_action",{action:t})));await c({description:i.t("config.backup_create_dry_run"),json:{action:"backup_create",name:n??null},apply:()=>{const o=r.createBackup(n);console.log(e.green(i.t("config.backup_created",{path:o})))}})}(o)}(v)}"claude-code"!==u&&"claude-code"!==v[0]?l[u]?await y(u,v,d):(console.error(e.red(i.t("config.unknown_command",{command:u}))),console.log(e.gray(i.t("config.usage_hint"))),Object.values(l).filter(o=>!o.hidden).forEach(o=>{console.log(e.gray(` - ${o.name}: ${o.displayName}`))})):await y("claude-code",v,d)}else await async function(t){if(t.nonInteractive)return void console.log(e.red(i.t("config.requires_argument")));const{selectedTool:n}=await o.prompt([{type:"list",name:"selectedTool",message:i.t("wizard.select_tool"),choices:Object.values(l).filter(o=>!o.hidden).map(o=>({name:`${o.displayName} (${o.name})`,value:o.name}))}]);await y(n,[],t)}(d)}
@@ -0,0 +1 @@
1
+ import{refreshClientConfig as o}from"../lib/client-config-sync.js";import t from"chalk";import e from"ora";import{spawnSync as s}from"child_process";import{existsSync as r,readdirSync as n,readFileSync as a}from"fs";import{connect as i}from"net";import{join as c}from"path";import{configManager as l}from"../lib/config.js";import{savedApiKey as d}from"./base.js";import{toolManager as p}from"../lib/tool-manager.js";import{i18n as u}from"../lib/i18n.js";import{validateApiKey as m}from"../lib/api-validator.js";import{getAdapter as f}from"../lib/tools/registry.js";import{findInstalls as _,installLabel as g}from"../lib/tools/tool-installs.js";import{detectManagedOverrides as h}from"../lib/tools/claude-managed.js";import{codexAuthProblem as y,codexCatalogRejection as k,codexConfigPath as w,codexWorkModeOn as b}from"../lib/tools/codex.js";import{claudeAccountLoginPresent as v}from"../lib/tools/claude-code.js";import{toolHome as j}from"../lib/tools/types.js";import{gatewayAddresses as x,probeGatewayAddress as $}from"../lib/gateway-addresses.js";import{listAdapters as T}from"../lib/tools/registry.js";import{logger as A}from"../utils/logger.js";import{maskHome as P,maskSecrets as R,uploadReport as N}from"../lib/telemetry.js";import{CLI_NAME as O}from"../lib/brand.js";import{balanceLookupEnabled as C,balanceNeedsAttention as I,balanceText as H,fetchKeyBalances as L}from"../lib/key-balance.js";const S=["HTTPS_PROXY","https_proxy","HTTP_PROXY","http_proxy","ALL_PROXY","all_proxy"];function U(o,t,e=3e3){return new Promise(s=>{const r=i({host:o,port:t}),n=o=>{r.destroy(),s(o)};r.setTimeout(e,()=>n(!1)),r.once("connect",()=>n(!0)),r.once("error",()=>n(!1))})}function E(){const o=A.getLogDir();if(!r(o))return"";const t=n(o).filter(o=>/^\d{4}-\d{2}-\d{2}\.log$/.test(o)).sort().slice(-2).map(t=>`== ${t}\n`+a(c(o,t),"utf-8")).join("\n");return R(t.slice(-15e4))}function K(){const o={};for(const t of S){const e=process.env[t]?.trim();if(e)try{const s=new URL(e.includes("://")?e:`http://${e}`);o[t]=`${s.protocol}//${s.host}`}catch{o[t]="(unparsable)"}}return o}export async function doctorCommand(r={}){const n=e(u.t("doctor.checking")).start(),i=[],A=Number(process.versions.node.split(".")[0]);i.push({name:"Node.js",status:A>=20?"pass":"fail",message:`v${process.versions.node}`}),n.text=u.t("doctor.check_proxy"),i.push(await async function(){const o=u.t("doctor.proxy"),t=new Map;for(const o of S){const e=process.env[o]?.trim();e&&!t.has(e)&&t.set(e,o)}if(0===t.size)return{name:o,status:"pass",message:u.t("doctor.proxy_none")};const e=[];for(const[o,s]of t){let t;try{t=new URL(o.includes("://")?o:`http://${o}`)}catch{e.push(`${s}=${o}`);continue}const r=Number(t.port)||("https:"===t.protocol?443:t.protocol.startsWith("socks")?1080:80);await U(t.hostname,r)||e.push(`${s}=${o}`)}return 0===e.length?{name:o,status:"pass",message:[...t.keys()].join(", ")}:{name:o,status:"fail",message:u.t("doctor.proxy_dead",{proxies:e.join(", ")})}}()),n.text=u.t("doctor.check_api_key_network");const R=d(),B=u.t("doctor.api_key_network");if(R){const o=await m(R);o.valid?(i.push({name:B,status:"pass"}),n.text=u.t("doctor.check_balance"),i.push(...await async function(o){if(!C())return[];const t=l.listToolApiKeys().map(o=>({tool:o,key:l.getApiKeyForTool(o)})).filter(t=>Boolean(t.key)&&t.key!==o),e=await L([o,...t.map(o=>o.key)]),s=[{name:u.t("doctor.balance"),key:o},...t.map(o=>({name:u.t("doctor.balance_tool",{tool:f(o.tool)?.displayName??o.tool}),key:o.key}))],r=[];for(const o of s){const t=e.get(o.key);t&&r.push({name:o.name,status:I(t)?"warn":"pass",message:H(t)})}return r}(R))):"invalid_api_key"===o.error?i.push({name:B,status:"fail",message:u.t("doctor.api_key_invalid")}):(i.push({name:B,status:"fail",message:`${u.t("doctor.network_error")}: ${o.message??o.error}`}),n.text=u.t("doctor.check_other_addresses"),i.push(await async function(){const o=u.t("doctor.other_addresses"),t=l.getBaseUrl(),e=x().filter(o=>o.url!==t),s=d(),r=await Promise.all(e.map(o=>$(o.url,{apiKey:s}))),n=e.filter((o,t)=>r[t].ok).map(o=>o.url);return 0===n.length?{name:o,status:"fail",message:u.t("doctor.other_addresses_none")}:{name:o,status:"warn",message:u.t("doctor.other_addresses_found",{urls:n.join(", ")})}}()))}else i.push({name:B,status:"fail",message:u.t("doctor.api_key_missing")});n.text=u.t("doctor.check_client_config");const G=await o();i.push({name:u.t("doctor.client_config"),status:"cloud"===G.source||"cache"===G.source&&!G.problem?"pass":"warn",message:[G.source?u.t(`refresh.source.${G.source}`):u.t("refresh.source.none"),G.revision?u.t("doctor.client_config_revision",{revision:G.revision}):"",G.problem??""].filter(Boolean).join(" · ")}),n.text=u.t("doctor.check_tools");const D=p.getInstalledTools();i.push({name:u.t("doctor.installed_tools"),status:D.length>0?"pass":"warn",message:D.length>0?D.map(o=>f(o)?.displayName??o).join(u.t("setup.list_separator")):u.t("doctor.no_tools_installed")}),i.push(...function(){const o=[];for(const t of p.getInstalledTools()){const e=f(t);if(!e?.installSpec)continue;const s=_(e.installSpec);if(0===s.length)continue;const r=[],n=p.outdatedVersion(t);n&&r.push(u.t("doctor.tool_outdated",{min:n.min})),s.length>1&&r.push(u.t("doctor.tool_duplicates",{others:s.slice(1).map(g).join("、")})),o.push({name:e.displayName,status:r.length>0?"warn":"pass",message:[g(s[0]),...r,...r.length>0?[u.t("doctor.run_upgrade",{tool:t})]:[]].join("\n ")})}return o}());const q=function(){if(!p.isToolInstalled("claude-code"))return null;const o=u.t("doctor.claude_config"),t=h();if(t.length>0){const e=t.map(o=>`${o.source}: ${o.keys.join(", ")}`).join("; ");return{name:o,status:"fail",message:u.t("doctor.claude_managed",{detail:e})}}let e={};try{e=JSON.parse(a(c(process.env.CLAUDE_CONFIG_DIR?.trim()||c(j(),".claude"),"settings.json"),"utf-8")).env??{}}catch{}const s=l.getApiKeyForTool("claude-code");return e.ANTHROPIC_AUTH_TOKEN&&e.ANTHROPIC_BASE_URL?e.ANTHROPIC_BASE_URL!==l.getBaseUrl()||s&&e.ANTHROPIC_AUTH_TOKEN!==s?{name:o,status:"warn",message:u.t("doctor.claude_config_changed")}:{name:o,status:"pass"}:{name:o,status:"warn",message:u.t("doctor.claude_not_configured")}}();q&&i.push(q),D.includes("claude-code")&&v()&&i.push({name:u.t("doctor.claude_login"),status:"pass",message:u.t("tools.claude_code.account_login_overridden")});const F=D.includes("codex")?y():null;if(D.includes("codex")&&i.push({name:u.t("doctor.codex_auth"),status:F?"fail":"pass",message:F?u.t(`doctor.codex_${F}`,{path:P(w())}):void 0}),D.includes("codex")){const o=k();i.push({name:u.t("doctor.codex_catalog"),status:o?"fail":"pass",message:o?u.t("doctor.codex_catalog_rejected",{path:o.bin,version:o.version??"?",error:o.error}):void 0})}D.includes("codex")&&b()&&i.push({name:u.t("doctor.codex_work_mode"),status:"warn",message:u.t("tools.codex.work_mode_on")}),"win32"===process.platform&&D.includes("claude-code")&&!process.env.CLAUDE_CODE_GIT_BASH_PATH&&i.push({name:"Git for Windows",status:p.isGitInstalled()?"pass":"warn",message:p.isGitInstalled()?void 0:u.t("tools.claude_code.no_git_bash")}),r.deep&&D.includes("claude-code")&&(n.text=u.t("doctor.check_claude_request"),i.push(function(){const o=u.t("doctor.claude_request"),t=_(f("claude-code").installSpec)[0];if(!t)return{name:o,status:"warn",message:u.t("doctor.claude_request_skipped")};const e={encoding:"utf-8",timeout:12e4,windowsHide:!0,stdio:["ignore","pipe","pipe"]},r=["-p","Reply with the single word OK."],n=/\.cmd$/i.test(t.path)?s(`"${t.path}" ${r.map(o=>`"${o}"`).join(" ")}`,{...e,shell:!0}):s(t.path,r,e),a=`${n.stdout??""}`.trim();if(0===n.status&&a)return{name:o,status:"pass",message:a.slice(0,80)};const i=(`${n.stderr??""}`.trim()||a||n.error?.message||`exit ${n.status}`).slice(0,300);return{name:o,status:"fail",message:u.t("doctor.claude_request_failed",{reason:i})}}())),n.stop(),console.log("\n"+t.bold(u.t("doctor.results_title"))+"\n");const M={pass:t.green("√"),warn:t.yellow("!"),fail:t.red("×")};for(const o of i)console.log(`${M[o.status]} ${o.name}`),o.message&&console.log(t.gray(` ${o.message}`));if(i.every(o=>"pass"===o.status)&&console.log("\n"+t.green.bold(u.t("doctor.all_good"))),!r.deep&&D.includes("claude-code")&&console.log(t.gray("\n"+u.t("doctor.deep_hint"))),r.report){const o=e(u.t("doctor.report_uploading")).start(),t=await N(function(o,t){const e={};for(const o of T()){if(o.hidden)continue;let t=null;try{t=p.detectCurrentConfig(o.name).apiKey?"has_key":"no_key"}catch{t="unreadable"}e[o.name]={installed:p.isToolInstalled(o.name),version:p.installedVersion(o.name),copies:o.installSpec?_(o.installSpec).map(o=>({kind:o.kind,version:o.version,path:o.path})):void 0,config:t}}const s=l.getProfile();return{checks:o,tools:e,settings:{base_url:l.getBaseUrl(),profile:l.getActiveProfileName(),profiles:l.listProfiles().length,key_fingerprint:l.getApiKeyFingerprint()||null,tool_keys:Object.keys(s.tool_api_keys??{}),models:s.models,tool_models:s.tool_models??{},tool_settings:s.tool_settings??{},lang:l.getLang()},client_config:t,env:{shell:process.env.SHELL??process.env.ComSpec??null,term:process.env.TERM_PROGRAM??null,proxies:K()},log:E()}}(i,{source:G.source??void 0,revision:G.revision,problem:G.problem}));t?o.succeed(u.t("doctor.report_done",{code:t})):o.fail(u.t("doctor.report_failed",{cli:O}))}else i.some(o=>"fail"===o.status)&&console.log(t.gray("\n"+u.t("doctor.report_hint",{cli:O})));i.some(o=>"fail"===o.status)&&(process.exitCode=1)}
@@ -0,0 +1 @@
1
+ export{langCommand}from"./lang.js";export{authCommand}from"./auth.js";export{doctorCommand}from"./doctor.js";export{configCommand}from"./config.js";export{statusCommand}from"./status.js";export{logsCommand}from"./logs.js";export{completionCommand}from"./completion.js";export{benchCommand}from"./bench.js";export{updateCommand}from"./update.js";export{refreshCommand}from"./refresh.js";
@@ -0,0 +1 @@
1
+ import{configManager as o}from"../lib/config.js";import{i18n as n}from"../lib/i18n.js";import l from"chalk";import{isJsonMode as a,emitJson as t,isColorEnabled as e}from"../lib/runtime-options.js";import{usageError as i}from"../lib/errors.js";function r(o){return e()?o:o=>o}export async function langCommand(e){if(0===e.length||"show"===e[0]){const e=o.getLang(),i=n.getAvailableLocales();return a()?void t({current:e,available:i}):(console.log(`${n.t("lang.current")}: ${r(l.cyan)(e)}`),void console.log(`${n.t("lang.available")}: ${i.join(", ")}`))}if("set"===e[0]&&e.length>=2){const g=e[1],s=n.getAvailableLocales();if(!s.includes(g))throw i(n.t("lang.invalid",{lang:g}),`${n.t("lang.available")}: ${s.join(", ")}`,"invalid_locale");const c=o.getLang();return o.setLang(g),n.loadFromConfig(g),a()?void t({ok:!0,from:c,to:g}):void console.log(r(l.green)(n.t("lang.changed",{from:c,to:g})))}console.log(n.t("lang.show_usage")),console.log(n.t("lang.set_usage"))}
@@ -0,0 +1 @@
1
+ import o from"chalk";import{readdirSync as t,statSync as i,readFileSync as n,existsSync as r}from"fs";import{join as e}from"path";import{logger as s}from"../utils/logger.js";import{i18n as l}from"../lib/i18n.js";import{isJsonMode as f,emitJson as m,isColorEnabled as c}from"../lib/runtime-options.js";import{operationError as g,usageError as a}from"../lib/errors.js";import{CLI_NAME as u}from"../lib/brand.js";const p=/^\d{4}-\d{2}-\d{2}\.log$/;function d(o){return c()?o:o=>o}export async function logsCommand(c){const h=c[0]||"list",_=s.getLogDir();if("path"===h)return f()?void m({log_dir:_}):void console.log(l.t("logs.directory",{dir:_}));const b=function(){const o=s.getLogDir();return r(o)?t(o).filter(o=>p.test(o)).map(t=>{const n=e(o,t),r=i(n);return{name:t,path:n,size:r.size,mtimeMs:r.mtimeMs}}).sort((o,t)=>t.mtimeMs-o.mtimeMs):[]}();if("list"!==h){if("tail"===h){const o=c[1],t=o?b.find(t=>t.name===o):b[0];if(!t)throw g(o?l.t("logs.no_such_file",{file:o}):l.t("logs.no_files"),"","no_log_file");const e=function(o,t=16384){if(!r(o))return"";const e=i(o),s=n(o);if(e.size<=t)return s.toString("utf-8");let l=e.size-t;for(;l<e.size&&128==(192&s[l]);)l+=1;return s.subarray(l).toString("utf-8")}(t.path);return f()?void m({file:t.name,path:t.path,content:e}):void console.log(e)}throw a(l.t("config.unknown_action",{action:h}),l.t("errors.next_step",{command:`${u} logs --help`}),"unknown_action")}if(f())m({log_dir:_,files:b});else if(console.log("\n"+d(o.bold)(l.t("logs.files_title"))),0!==b.length)for(const t of b){const i=new Date(t.mtimeMs).toISOString();console.log(` ${d(o.cyan)(t.name)} ${d(o.gray)(`${t.size}B`)} ${d(o.gray)(i)}`)}else console.log(" "+d(o.gray)(l.t("logs.no_files")))}
@@ -0,0 +1 @@
1
+ import e from"chalk";import{refreshClientConfig as o}from"../lib/client-config-sync.js";import{i18n as r}from"../lib/i18n.js";import{lastModelRefreshOutcome as s,runModelRefresh as c}from"../lib/model-refresh.js";export async function refreshCommand(){const n=await o({force:!0}),t=n.source?r.t(`refresh.source.${n.source}`):r.t("refresh.source.none");if(console.log(e.gray(r.t("refresh.config",{source:t,revision:n.revision||"-"}))+(n.problem?e.yellow(` ${r.t("refresh.problem",{problem:n.problem})}`):"")),(await c(["refresh"],{force:!0,output:e=>console.log(e)})).length>0)return;const{checked:l,failed:i}=s();0===l&&0===i?console.log(e.gray(r.t("refresh.nothing_checked"))):0===i&&console.log(e.green(r.t("refresh.up_to_date")))}
@@ -0,0 +1 @@
1
+ import s from"chalk";import{spawnSync as o}from"child_process";import{existsSync as t,mkdirSync as e,writeFileSync as i}from"fs";import{dirname as n,join as r,resolve as l}from"path";import{i18n as c}from"../lib/i18n.js";import{emitJson as d,isColorEnabled as m,isJsonMode as a}from"../lib/runtime-options.js";import{maskHome as f}from"../lib/telemetry.js";import{operationError as u,usageError as p}from"../lib/errors.js";import{CLI_NAME as g}from"../lib/brand.js";import{clip as h}from"../lib/sessions/formats.js";import{listSessions as w,readSession as _,resolveSession as b,resumeCommand as $,resumeLine as v,roleLabel as x,sessionMarkdown as N}from"../lib/sessions/index.js";import{padString as y,stringWidth as S}from"../utils/string-width.js";function j(s){return s.replace(/[\u0000-\u0008\u000b-\u001f\u007f-\u009f]/g,"")}function A(s){return m()?s:s=>s}function C(s){const o=new Date(s);if(Number.isNaN(o.getTime()))return s;const t=s=>String(s).padStart(2,"0");return`${o.getFullYear()}-${t(o.getMonth()+1)}-${t(o.getDate())} ${t(o.getHours())}:${t(o.getMinutes())}`}function M(s,o){const t=j(s).replace(/\s+/g," ").trim();if(S(t)<=o)return t;let e="";for(const s of t){if(S(e+s)>o-1)break;e+=s}return e+"…"}function k(s){const o=$(s);return{id:s.id,tool:s.tool,title:s.title,cwd:s.cwd,started_at:s.startedAt??null,updated_at:s.updatedAt,provider:s.provider??null,file:s.file,resume:o?v(o):null}}export async function sessionsListCommand(o={}){const t=o.all?0:Number(o.limit??20);if(!o.all&&(!Number.isInteger(t)||t<=0))throw p(c.t("sessions.bad_limit",{value:String(o.limit)}),c.t("sessions.bad_limit_hint",{cli:g}));const e=o.here?process.cwd():o.dir,i=w({tool:o.tool,dir:e,limit:t});if(a())return void d(i.map(k));if(0===i.length)return void console.log(c.t("sessions.none"));const n=A(s.gray),r=A(s.cyan),l=Math.max(...i.map(s=>S(s.toolName)),4);for(const s of i){const o=`${r(s.id.slice(0,8))} ${y(s.toolName,l)} ${n(C(s.updatedAt))}`;console.log(`${o} ${M(s.title||"-",60)}`),s.cwd&&console.log(n(` ${j(f(s.cwd))}`))}console.log(n("\n"+c.t("sessions.list_footer",{cli:g,count:String(i.length)})))}export async function sessionsShowCommand(o,t={}){const e=Number(t.messages??6);if(!Number.isInteger(e)||e<0)throw p(c.t("sessions.bad_limit",{value:String(t.messages)}),c.t("sessions.bad_limit_hint",{cli:g}));const i=b(o),n=_(i);if(a())return void d({...k(i),message_count:n.length,messages:n.slice(0,e)});const r=A(s.gray),l=A(s.cyan),m=A(s.bold),u=$(i);console.log("\n"+m(j(i.title||i.id))+"\n");const w=[[c.t("sessions.field.tool"),i.toolName],[c.t("sessions.field.id"),i.id],[c.t("sessions.field.started"),i.startedAt?C(i.startedAt):void 0],[c.t("sessions.field.updated"),C(i.updatedAt)],[c.t("sessions.field.cwd"),i.cwd?f(i.cwd):void 0],[c.t("sessions.field.provider"),i.provider],[c.t("sessions.field.messages"),String(n.length)],[c.t("sessions.field.file"),f(i.file)],[c.t("sessions.field.resume"),u?v(u):c.t("sessions.no_resume")]],N=Math.max(...w.map(([s])=>S(s)));for(const[s,o]of w)o&&console.log(` ${l(y(s,N))} ${j(o)}`);for(const s of n.slice(0,e))console.log("\n"+m(`[${x(s.role)}]`)+(s.timestamp?r(` ${C(s.timestamp)}`):"")),console.log(j(h(s.text,500)));n.length>e&&console.log(r("\n"+c.t("sessions.more_messages",{more:String(n.length-e),cli:g,id:i.id.slice(0,8)})))}export async function sessionsResumeCommand(e,i={}){const n=b(e),r=$(n);if(!r)throw p(c.t("sessions.cannot_resume",{tool:n.toolName}),c.t("sessions.cannot_resume_hint",{tool:n.toolName}));const l=v(r);if(!i.run)return void(a()?d({id:n.id,tool:n.tool,command:r.command,args:r.args,cwd:r.cwd||null,line:l}):console.log(l));const m=r.cwd&&t(r.cwd)?r.cwd:void 0;r.cwd&&!m&&console.error(A(s.yellow)(c.t("sessions.cwd_missing",{dir:r.cwd})));const f=o(r.command,r.args,{cwd:m,stdio:"inherit",shell:"win32"===process.platform});if(f.error)throw u(c.t("sessions.run_failed",{command:r.command,error:f.error.message}),c.t("sessions.run_failed_hint",{line:l}));"number"==typeof f.status&&0!==f.status&&(process.exitCode=f.status)}function D(s,o,e){const i=`${o.tool}-${o.id}`.replace(/[^A-Za-z0-9_-]/g,"_");let d=r(s,`${i}.md`);for(let o=2;e.has(d)||t(d);o++)d=r(s,`${i}-${o}.md`);if(n(l(d))!==l(s))throw u(c.t("sessions.export_bad_path",{path:d}),"");return e.add(d),d}export async function sessionsExportCommand(o,t={}){if(!t.output)throw p(c.t("sessions.export_needs_output"),c.t("sessions.export_hint",{cli:g}));const n=o.map(b),r=l(t.output);e(r,{recursive:!0});const m=new Set,u=[];for(const s of n){const o=D(r,s,m);i(o,N(s,_(s,{details:t.tools})),"utf-8"),u.push({id:s.id,tool:s.tool,path:o})}if(a())d({written:u});else for(const o of u)console.log(A(s.green)("√ ")+f(o.path))}
@@ -0,0 +1 @@
1
+ import o from"chalk";import{getAdapter as e}from"../lib/tools/registry.js";import{postApplyPrompts as t}from"../lib/post-apply.js";import{ensureReachableGatewayAddress as i}from"./base.js";import{i18n as l}from"../lib/i18n.js";import{configManager as s}from"../lib/config.js";import{toolManager as a,SUPPORTED_TOOLS as n}from"../lib/tool-manager.js";import{validateApiKey as r,fetchModels as d}from"../lib/api-validator.js";import{CODEX_ONE_MILLION_CONTEXT_SETTING as p,setCodexOneMillionContext as c}from"../lib/tools/codex.js";import{resolveModelCatalog as u}from"../lib/model-catalog.js";import{CLAUDE_DESKTOP_FORCE_REGISTRY_SETTING as f,CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING as m}from"../lib/tools/claude-desktop.js";import{operationError as g,authenticationError as y,networkError as _,EXIT_CODES as k}from"../lib/errors.js";import{emitJson as h,isColorEnabled as b,isDryRun as w,isJsonMode as v,isNonInteractive as x,shouldAutoConfirm as C}from"../lib/runtime-options.js";import{join as j}from"path";import{confirmWritePlan as K,printWritePlan as $,toolWritePlan as T}from"../lib/write-plan.js";import G from"inquirer";import{logger as S}from"../utils/logger.js";import{forgetInstalls as M}from"../lib/tools/tool-installs.js";import{CLI_NAME as N,brandEnv as E}from"../lib/brand.js";export const DEDICATED_KEYS=[{option:"claudekey",tool:"claude-code",need:"claude"},{option:"codexkey",tool:"codex",need:"gpt"},{option:"grokkey",tool:"grok",need:"grok"},{option:"desktopkey",tool:"claude-desktop",need:"claude"},{option:"agykey",tool:"agy",need:"gemini"},{option:"openclawkey",tool:"openclaw",need:"any",hidden:!0},{option:"hermeskey",tool:"hermes",need:"any",hidden:!0},{option:"atomcodekey",tool:"atomcode",need:"any",hidden:!0}];async function I(o){const e=await d(o);if(!e.ok)return{hasClaude:!0,hasGpt:!0,hasGrok:!0,hasGemini:!0,probed:!1};const t=e.models.map(o=>o.toLowerCase());return{hasClaude:t.some(o=>o.includes("claude")),hasGpt:t.some(o=>o.startsWith("gpt")||o.includes("gpt-")||/^o\d/.test(o)),hasGrok:t.some(o=>o.includes("grok")),hasGemini:t.some(o=>o.startsWith("gemini")),probed:!0}}function O(o,e){switch(e){case"claude":return o.hasClaude;case"gpt":return o.hasGpt;case"grok":return o.hasGrok;case"gemini":return o.hasGemini;default:return!0}}export function parseOnOff(o){const e=(o??"").trim().toLowerCase();return!!["on","true","show","1","yes","y"].includes(e)||!["off","false","hide","0","no","n"].includes(e)&&void 0}function A(e){console.log(o.green(e))}function D(e){console.log(o.yellow(e))}function F(e){console.error(o.red(e))}let B=null;function L(o){const e={operation:1,authentication:2,network:3};(!B||e[o]>e[B])&&(B=o)}async function R(e,t){v()||console.log(o.gray(l.t("setup.validating",{label:e})));const i=await r(t);if(i.valid)return!0;const a=l.t("errors.key_placeholder"),n="--key"===e?`${N} setup --key ${a}`:`${N} setup ${e} ${a}`;let d;if("network_error"===i.error?(L("network"),d=_(l.t("setup.unreachable",{url:s.getBaseUrl(),reason:i.message||"network error"}),`${N} base auto`,"network_error")):"invalid_api_key"===i.error?(L("authentication"),d=y(l.t("setup.invalid_key",{label:e,reason:i.message||"invalid"}),n,"invalid_api_key")):(L("operation"),d=g(l.t("setup.validate_failed",{label:e,reason:i.message||i.error||"unknown"}),n,i.error)),v())throw d;return F(d.message),console.log(o.gray(l.t("errors.next_step",{command:d.hint}))),!1}async function P(t,i,r={}){const{oneMillion:d,officialLogin:c,desktopRegistry:u,force:y}=r,_=n[t];try{"claude-desktop"===t&&void 0!==u&&s.setToolSetting("claude-desktop",f,u),"codex"===t&&void 0!==d&&s.setToolSetting("codex",p,d),"claude-desktop"===t&&void 0!==c&&s.setToolSetting("claude-desktop",m,!c),await a.applyPrivateConfig(t,i,s.getModelsForTool(t),{force:y})}catch(o){if(v())throw g(o instanceof Error?o.message:String(o),`${N} setup --key ${l.t("errors.key_placeholder")}`,"config_write_failed");const e=(o instanceof Error?o.message:String(o)).replace(/\s+/g," ").trim();return F("× "+l.t("setup.apply_failed",{tool:_.displayName,reason:e})),!1}return a.printApplied(t),y&&console.log(o.gray(" "+l.t("config.force_done",{tool:_.displayName,name:t}))),"codex"===t&&void 0!==d&&console.log(o.gray(" "+l.t(d?"setup.codex_1m_enabled":"setup.codex_1m_disabled"))),e(t)?.isInstalled&&!a.isToolInstalled(t)&&console.log(o.yellow(" ! "+l.t("setup.gui_preconfigured",{tool:_.displayName,install:_.installCommand}))),!0}function Y(o){return!e(o)?.isInstalled&&!a.isToolInstalled(o)}function q(o){D(l.t("setup.still_missing",{tools:o.map(o=>n[o].displayName).join(l.t("setup.list_separator")),commands:o.map(o=>`${N} config ${o} --yes`).join(l.t("setup.list_separator"))}))}function H(e,t,i=[]){const a=T(e),n=j(s.getConfigDir(),"config.yaml");if(v())h({dry_run:!0,tools:a,install_first:i,key_file:t?n:null});else{if(0===a.length&&0===i.length){const e=(b()?o.cyan:o=>o)(l.t("runtime.dry_run_label"));return void console.log(`${e} ${l.t("setup.dry_run_none")}`)}$(a,{label:l.t("runtime.dry_run_label"),keyFile:t?n:void 0,installFirst:i})}}function W(){return"darwin"===process.platform||"win32"===process.platform||a.isToolInstalled("claude-desktop")}export async function setupCommand(r){B=null;const d=r.key?.trim(),f=DEDICATED_KEYS.map(o=>({...o,apiKey:r[o.option]?.trim()})).filter(o=>Boolean(o.apiKey)),m=void 0!==r.oneMillion,g=void 0!==r.claudeOfficial;let y;if(g&&(y=parseOnOff(r.claudeOfficial),void 0===y))return F(l.t("setup.claude_official_invalid",{value:String(r.claudeOfficial)})),void(process.exitCode=1);const _=void 0!==r.desktopRegistry;let h;if(_&&(h=parseOnOff(r.desktopRegistry),void 0===h))return F(l.t("setup.desktop_registry_invalid",{value:String(r.desktopRegistry)})),void(process.exitCode=1);const b=g||_,$=Boolean(d||f.length>0),T={oneMillion:r.oneMillion,officialLogin:y,desktopRegistry:h,force:r.force};if(!$&&(m||b)&&w())return void H([...m?["codex"]:[],...b?["claude-desktop"]:[]],!1);if(!$&&(m||b)){if(m){const o=s.getApiKeyForTool("codex");if(o)try{const e=!0===r.oneMillion;s.setToolSetting("codex",p,e);const t=await u(o);c(e,t??void 0),A(l.t(e?"setup.codex_1m_enabled":"setup.codex_1m_disabled"))}catch(o){F(l.t("setup.apply_failed",{tool:n.codex.displayName,reason:o instanceof Error?o.message:String(o)})),process.exitCode=1}else F(l.t("setup.codex_1m_missing_key")),process.exitCode=1}if(b){const o=s.getApiKeyForTool("claude-desktop");o?await P("claude-desktop",o,{...T,oneMillion:void 0})?await t(["claude-desktop"]):process.exitCode=1:(F(l.t("setup.desktop_official_login_missing_key")),process.exitCode=1)}return}if(!$)return F(l.t("setup.usage")),void(process.exitCode=1);const L=w();L||await i(d||f[0].apiKey);const U=[],z=[];let J,Q=0,V=0;const X=new Set,Z=f.map(o=>({tool:o.tool,label:`--${o.option}`,apiKey:o.apiKey,need:o.need}));for(const o of Z){if(!await R(o.label,o.apiKey)){V+=1;continue}const e=await I(o.apiKey);!e.probed||O(e,o.need)?(e.probed||D(l.t("setup.probe_failed",{label:o.label})),U.push({tool:o.tool,apiKey:o.apiKey,dedicated:!0}),X.add(o.tool)):(F(l.t(`setup.key_no_${o.need}`,{label:o.label,tool:n[o.tool].displayName})),V+=1)}const oo=!!d&&await R("--key",d);d&&!oo&&(J=k[B??"operation"]);const eo=d&&oo?await I(d):void 0;if(d&&eo&&!eo.probed&&D(l.t("setup.probe_failed",{label:"--key"})),!(d&&eo&&eo.probed)||eo.hasClaude||eo.hasGpt||eo.hasGrok||eo.hasGemini||(F(l.t("setup.key_no_family")),J=1),d&&eo&&void 0===J){const o=[{tool:"claude-code",capable:eo.hasClaude,skipMsg:l.t(W()?"setup.skip_no_claude_desktop":"setup.skip_no_claude")},{tool:"codex",capable:eo.hasGpt,skipMsg:l.t("setup.skip_no_gpt")},{tool:"grok",capable:eo.hasGrok,skipMsg:l.t("setup.skip_no_grok")},{tool:"claude-desktop",capable:eo.hasClaude&&W(),skipMsg:"",quiet:!0},{tool:"agy",capable:eo.hasGemini,skipMsg:l.t("setup.skip_no_gemini")}];for(const e of o)X.has(e.tool)||(e.capable?(U.push({tool:e.tool,apiKey:d,dedicated:!1}),X.add(e.tool)):e.quiet||D(e.skipMsg))}const to=Boolean(d&&oo&&void 0===J);if(L)return H(U.filter(o=>!Y(o.tool)).map(o=>o.tool),U.length>0,U.filter(o=>Y(o.tool)).map(o=>o.tool)),void((V>0||void 0!==J)&&(process.exitCode=J??k[B??"operation"]));const io=U.filter(o=>!Y(o.tool)),lo=to||U.some(o=>o.dedicated);if((U.length>0||lo)&&!r.fromInstaller&&!await K(io.map(o=>o.tool),{keyFile:lo?j(s.getConfigDir(),"config.yaml"):void 0,installFirst:U.filter(o=>Y(o.tool)).map(o=>o.tool)}))return void(process.exitCode=k.cancelled);to&&d&&s.setApiKey(d);for(const o of U)o.dedicated&&s.setToolApiKey(o.tool,o.apiKey),Y(o.tool)?z.push({tool:o.tool,apiKey:o.apiKey}):await P(o.tool,o.apiKey,T)?Q+=1:(V+=1,X.delete(o.tool));if(void 0!==J)return z.length>0&&q(z.map(o=>o.tool)),void(process.exitCode=J);let so=[];if(z.length>0){const e=await async function(e,t,i){const s=e.map(o=>o.tool);if(0===s.length)return{still:[],applied:[],failed:[]};const r=s.map(o=>n[o].displayName).join(l.t("setup.list_separator"));let d=t;if(void 0!==d||v()||(C()?d=!x():process.stdin.isTTY&&(console.log(""),d=(await G.prompt([{type:"confirm",name:"go",message:l.t("setup.install_confirm",{tools:r}),default:!0}])).go)),!d){console.log("");for(const e of s)console.log(o.yellow("! "+l.t("setup.install_hint",{tool:n[e].displayName,install:n[e].installCommand})));return v()||console.log(o.gray(l.t("setup.install_all_hint",{cli:N}))),{still:s,applied:[],failed:[]}}const p=[];for(const e of s){console.log(o.bold(`\n${n[e].displayName}`));try{await a.installTool(e)}catch(o){S.logError(`setup: install ${e}`,o)}M(),a.isToolInstalled(e)||p.push(e)}const c=s.filter(o=>!p.includes(o));c.length>0&&console.log("");const u=[],f=[];for(const{tool:o,apiKey:t}of e.filter(o=>c.includes(o.tool)))await P(o,t,i)?u.push(o):f.push(o);return{still:p,applied:u,failed:f}}(z,r.install,T);so=e.still,Q+=e.applied.length,V+=e.failed.length;for(const o of[...so,...e.failed])X.delete(o)}if(Q>0){const t=[...X].filter(o=>!e(o)?.isInstalled&&!so.includes(o)),i=t.map(o=>n[o]?.command).filter(Boolean).join(" / "),s=l.t("setup.done",{count:String(Q)});A("\n"+(i?`${s}${l.t("setup.done_commands",{commands:i})}`:s)),so.length>0&&q(so);for(const o of t){const e=a.ensureNativeOnPath(o);e&&A(l.t("setup.path_added",{tool:n[o].displayName,dir:e}))}const r=t.filter(o=>!a.isOnPath(o));if(r.length>0&&!v()&&"1"!==E("PATH_HINT_BY_CALLER")){const e=r.map(o=>n[o].command).join(" / ");console.log(o.yellow(" ! "+l.t("win32"===process.platform?"setup.path_reload_windows":"setup.path_reload",{commands:e})))}}0===Q&&so.length>0&&q(so),V>0&&(F(l.t("setup.failed_summary",{count:String(V)})),v()||console.error(`${N} setup --key ${l.t("errors.key_placeholder")}`)),await t([...X]),(V>0||0===Q&&0===so.length)&&(process.exitCode=k[B??"operation"])}
@@ -0,0 +1 @@
1
+ import o from"chalk";import{configManager as e,DEFAULT_BASE_URL as t}from"../lib/config.js";import{toolManager as n,SUPPORTED_TOOLS as l}from"../lib/tool-manager.js";import{claudeCodeManager as s}from"../lib/claude-code-manager.js";import{i18n as i}from"../lib/i18n.js";import{isJsonMode as a,emitJson as r,isColorEnabled as c}from"../lib/runtime-options.js";import{balanceLookupEnabled as g,balanceNeedsAttention as u,balanceText as p,fetchKeyBalances as m}from"../lib/key-balance.js";function f(o){return c()?o:o=>o}function d(o){return o?{remaining:o.remaining,unit:o.unit,symbol:o.symbol,wallet:o.wallet??null,token_remaining:o.tokenRemaining??null,account_insufficient:o.accountInsufficient??!1}:null}export async function statusCommand(){const c=e.getApiKey(),$=e.getBaseUrl(),_=e.getModels(),y=i.getLocale(),b=n.getSupportedTools().map(o=>{const e=n.isToolInstalled(o.name);let t=null;return e&&"claude-code"===o.name&&(t=Boolean(s.detectCurrentConfig().apiKey)),{name:o.name,display_name:o.displayName,installed:e,config_loaded:t}}),k=e.getActiveProfileName(),j=e.listProfiles(),A=Object.keys(e.getCustomPresets()),K=e.listToolApiKeys(),T=g()?[c,...K.map(o=>e.getApiKeyForTool(o))].filter(o=>Boolean(o)):[],F=await m(T),w=o=>o?F.get(o):void 0;if(a())return void r({api_key_set:Boolean(c),api_key_fingerprint:e.getApiKeyFingerprint()||null,tool_key_fingerprints:Object.fromEntries(K.map(o=>[o,e.getToolApiKeyFingerprint(o)||null])),balance:d(w(c)),tool_key_balances:Object.fromEntries(K.map(o=>[o,d(w(e.getApiKeyForTool(o)))])),base_url:$,base_url_is_default:$===t,language:y,models:_,tools:b,active_profile:k,profiles:j,custom_presets:A});const C=f(o.cyan),v=f(o.green),B=f(o.yellow),O=f(o.gray),P=f(o.red);console.log("\n"+f(o.bold)(i.t("status.title"))+"\n");const h=e.getApiKeyFingerprint(),N=c?h?`sk-fp-${h}`:"sk-****":B(i.t("wizard.not_set"));console.log(` ${C(i.t("status.api_key"))}: ${c?v(N):N}`);const E=w(c);if(E){const o=p(E);console.log(` ${C(i.t("status.balance"))}: ${u(E)?B(o):v(o)}`)}for(const o of K){const t=e.getToolApiKeyFingerprint(o);if(!t)continue;const n=l[o]?.displayName||o,s=w(e.getApiKeyForTool(o)),a=s?O(` · ${i.t("status.balance")} ${p(s)}`):"";console.log(` ${C(i.t("status.tool_key_label",{tool:n}))}: ${v(`sk-fp-${t}`)}${a}`)}const I=$===t;console.log(` ${C(i.t("status.base_url"))}: ${$}${I?O(" (default)"):""}`),console.log(` ${C(i.t("status.language"))}: ${y}`),console.log(` ${C("Profile")}: ${k} ${O("("+j.join(", ")+")")}`),console.log(` ${C(i.t("status.models"))}:`),console.log(` Haiku: ${_.haiku}`),console.log(` Sonnet: ${_.sonnet}`),console.log(` Opus: ${_.opus}`),console.log(` Reasoning: ${_.reasoning}`),A.length>0&&console.log(` ${C("Custom presets")}: ${A.join(", ")}`),console.log(` ${C(i.t("status.tools"))}:`);for(const o of b){const e=o.installed?v("✓"):P("✗");let t="";!0===o.config_loaded?t=v(" ("+i.t("status.config_loaded")+")"):!1===o.config_loaded&&(t=O(" ("+i.t("status.config_not_loaded")+")")),console.log(` ${e} ${o.display_name}${t}`)}console.log("")}
@@ -0,0 +1 @@
1
+ import e from"chalk";import{readFileSync as t}from"fs";import{join as r,dirname as o}from"path";import{fileURLToPath as n}from"url";import{i18n as a}from"../lib/i18n.js";import{isJsonMode as s,emitJson as i,isColorEnabled as c}from"../lib/runtime-options.js";import{brand as l}from"../lib/brand.js";const u=l().packageName;export const UPDATE_TIMEOUT_MS=1500;const p=e=>{const t=e["dist-tags"];if(!t||"object"!=typeof t)return null;const r=t.latest;return"string"==typeof r?r:null};export const UPDATE_SOURCES=l().updateRegistries.map(({id:e,url:t})=>({id:e,registry:t,metadataUrl:e=>((e,t,r="")=>`${e}${encodeURIComponent(t)}${r}`)(t,e),readVersion:p}));function m(e){return c()?e:e=>e}export function readLocalPackage(){const e=n(import.meta.url),a=o(e),s=r(a,"..","..");try{const e=JSON.parse(t(r(s,"package.json"),"utf-8"));return{name:e.name||u,version:e.version||"0.0.0",root:s}}catch{return{name:u,version:"0.0.0",root:s}}}function g(e){const[t,...r]=e.split("-"),o=r.length?r.join("-").split("."):[];return{main:t.split(".").map(e=>Number.parseInt(e,10)||0),pre:o}}function f(e,t){const r=Number.parseInt(e,10),o=Number.parseInt(t,10),n=Number.isFinite(r)&&String(r)===e,a=Number.isFinite(o)&&String(o)===t;return n&&a?r-o:n?-1:a?1:e<t?-1:e>t?1:0}export function compareSemver(e,t){const r=g(e),o=g(t),n=Math.max(r.main.length,o.main.length);for(let e=0;e<n;e+=1){const t=(r.main[e]||0)-(o.main[e]||0);if(0!==t)return t}if(0===r.pre.length&&0===o.pre.length)return 0;if(0===r.pre.length)return 1;if(0===o.pre.length)return-1;const a=Math.max(r.pre.length,o.pre.length);for(let e=0;e<a;e+=1){const t=r.pre[e],n=o.pre[e];if(void 0===t)return-1;if(void 0===n)return 1;const a=f(t,n);if(0!==a)return a}return 0}async function d(e,t,r,o){const n=new AbortController,a=setTimeout(()=>n.abort(),o);try{const o=await r(e.metadataUrl(t),{headers:{Accept:"application/json"},signal:n.signal});if(!o.ok)throw new Error(`HTTP ${o.status}`);const a=await o.json(),s=e.readVersion(a);if(!s)throw new Error("invalid registry metadata");return s}catch(e){if(n.signal.aborted)throw new Error(`timeout after ${o}ms`);throw e}finally{clearTimeout(a)}}export async function checkForUpdate(e={}){const t=e.localPackage||readLocalPackage(),r=e.localVersion||t.version,o=e.packageName||t.name,n=e.fetchFn||fetch,a=e.timeoutMs||1500,s=e.sources||UPDATE_SOURCES,i=[];for(const e of s)try{const t=await d(e,o,n,a);return{current:r,latest:t,up_to_date:compareSemver(r,t)>=0,source:e.id,registry:e.registry,errors:i,error:null}}catch(t){i.push({source:e.id,error:t instanceof Error?t.message:String(t)})}return{current:r,latest:null,up_to_date:null,source:null,registry:null,errors:i,error:i.map(e=>`${e.source}: ${e.error}`).join("; ")||"unknown"}}export async function updateCommand(t={}){const r=t.localPackage||readLocalPackage();s()||console.log(m(e.gray)(a.t("update.checking")));const o=await checkForUpdate({...t,localPackage:r});if(s())i(o);else if(console.log(` ${m(e.cyan)(a.t("update.current",{version:o.current}))}`),o.latest)if(console.log(` ${m(e.cyan)(a.t("update.latest",{version:o.latest}))}`),console.log(` ${m(e.cyan)(a.t("update.source",{source:l().updateRegistries.find(e=>e.id===o.source)?.label??o.source??"unknown"}))}`),o.up_to_date)console.log(" "+m(e.green)(a.t("update.up_to_date")));else{const t="npm"===o.source?"":` --registry ${o.registry}`,n=`npm install -g ${r.name}@latest${t}`;console.log(" "+m(e.yellow)(a.t("update.available"))),console.log(" "+m(e.gray)(a.t("update.command_hint",{command:n})))}else console.log(" "+m(e.yellow)(a.t("update.fetch_failed",{error:o.error||"unknown"})))}
@@ -0,0 +1 @@
1
+ import o from"chalk";import{i18n as r}from"../lib/i18n.js";import{toolManager as t}from"../lib/tool-manager.js";import{listAdapters as e}from"../lib/tools/registry.js";import{upgradeTool as i}from"../lib/tool-upgrade.js";export async function upgradeCommand(l){const n=e().filter(o=>o.installSpec).map(o=>o.name),s=l.length>0?l:n.filter(o=>t.isToolInstalled(o)),p=s.filter(o=>!n.includes(o));if(p.length>0)return console.error(o.red(r.t("upgrade.unsupported",{tool:p.join(", ")}))),console.error(r.t("upgrade.supported",{tools:n.join(" / ")})),void(process.exitCode=1);if(0===s.length)return void console.log(r.t("upgrade.nothing_installed",{tools:n.join(" / ")}));let a=0;for(const o of s)await i(o)||(a+=1);a>0&&(process.exitCode=1)}
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export{Command}from"./lib/command.js";export{Wizard,wizard}from"./lib/wizard.js";export{ConfigManager,configManager,DEFAULT_BASE_URL,DEFAULT_MODELS}from"./lib/config.js";export{ToolManager,toolManager,SUPPORTED_TOOLS}from"./lib/tool-manager.js";export{ClaudeCodeManager,claudeCodeManager}from"./lib/claude-code-manager.js";export{OpenCodeManager,openCodeManager}from"./lib/opencode-manager.js";export{i18n,I18n}from"./lib/i18n.js";export{Logger,logger,LogLevel}from"./utils/logger.js";export{validateApiKey}from"./lib/api-validator.js";
@@ -0,0 +1 @@
1
+ import{KEY_INFO_PATH as r}from"./gateway-protocol.js";import{logger as e}from"../utils/logger.js";import{configManager as t}from"./config.js";import{i18n as o}from"./i18n.js";import{rememberPublishedAddresses as a}from"./gateway-addresses.js";import{eligibleLists as n}from"./client-config.js";import{track as s}from"./telemetry.js";import{refreshClientConfig as i}from"./client-config-sync.js";const l=r=>new Promise(e=>setTimeout(e,r));async function c(r,e,a){const n=`${t.getBaseUrl()}/v1/models`,s=new AbortController,i=setTimeout(()=>s.abort(),e);try{const e=await a(n,{method:"GET",headers:{Authorization:`Bearer ${r}`,"Content-Type":"application/json"},signal:s.signal});if(401===e.status)return{valid:!1,error:"invalid_api_key",message:o.t("validator.rejected")};if(e.ok){try{const r=await e.json();if(r&&"list"===r.object)return{valid:!0}}catch{return{valid:!0}}return{valid:!0}}return{valid:!1,error:"unknown_error",message:`HTTP ${e.status}: ${e.statusText}`}}catch(r){return r instanceof Error&&"AbortError"===r.name?{valid:!1,error:"network_error",message:o.t("validator.timeout")}:function(r){const e=r?.cause?.code;return"string"==typeof e&&u.has(e)}(r)?{valid:!1,error:"network_error",message:o.t("messages.certificate_intercepted",{url:n})}:{valid:!1,error:"network_error",message:r instanceof Error?r.message:o.t("validator.network")}}finally{clearTimeout(i)}}const u=new Set(["DEPTH_ZERO_SELF_SIGNED_CERT","SELF_SIGNED_CERT_IN_CHAIN","UNABLE_TO_VERIFY_LEAF_SIGNATURE","UNABLE_TO_GET_ISSUER_CERT_LOCALLY","CERT_UNTRUSTED","ERR_TLS_CERT_ALTNAME_INVALID"]);export async function fetchModels(r,o={}){const{timeoutMs:a=3e4,fetchFn:n=fetch}=o,s=`${t.getBaseUrl()}/v1/models`,i=new AbortController,l=setTimeout(()=>i.abort(),a);try{const e=await n(s,{method:"GET",headers:{Authorization:`Bearer ${r}`,"Content-Type":"application/json"},signal:i.signal});if(!e.ok)return{ok:!1,models:[],error:`HTTP ${e.status}`};const t=await e.json();return{ok:!0,models:(Array.isArray(t?.data)?t.data:[]).map(r=>"string"==typeof r?r:r?.id).filter(r=>"string"==typeof r&&r.trim().length>0).map(r=>r.trim())}}catch(r){return e.logError("fetchModels",r),{ok:!1,models:[],error:r instanceof Error?r.message:"network error"}}finally{clearTimeout(l)}}function f(r){return r.filter(r=>!!r&&"object"==typeof r&&"string"==typeof r.name).map(r=>({name:r.name.trim(),..."string"==typeof r.labelOverride?{labelOverride:r.labelOverride}:{},..."boolean"==typeof r.supports1m?{supports1m:r.supports1m}:{}})).filter(r=>r.name.length>0)}export async function fetchGatewayStatus(r={}){const{timeoutMs:o=15e3,fetchFn:n=fetch}=r,s=`${t.getBaseUrl()}/api/status`,i=new AbortController,l=setTimeout(()=>i.abort(),o);try{const r=await n(s,{method:"GET",signal:i.signal});if(!r.ok)return{ok:!1,claudeDesktopGroupModels:{},error:`HTTP ${r.status}`};const e=await r.json();a(e?.data,t.getBaseUrl());let o=e?.data?.claude_desktop_group_models;if("string"==typeof o)try{o=JSON.parse(o)}catch{o=void 0}const l={};if(o&&"object"==typeof o&&!Array.isArray(o))for(const[r,e]of Object.entries(o))Array.isArray(e)&&(l[r]=f(e));return{ok:!0,claudeDesktopGroupModels:l}}catch(r){return e.logError("fetchGatewayStatus",r),{ok:!1,claudeDesktopGroupModels:{},error:r instanceof Error?r.message:"network error"}}finally{clearTimeout(l)}}export async function fetchKeyGroupInfo(o,a={}){const{timeoutMs:n=1e4,fetchFn:s=fetch}=a,i=`${t.getBaseUrl()}${r}`,l=new AbortController,c=setTimeout(()=>l.abort(),n);try{const r=await s(i,{method:"GET",headers:{Authorization:`Bearer ${o}`},signal:l.signal});if(!r.ok)return null;const e=await r.json(),t=e?.data;if(!t||"string"!=typeof t.group||!Array.isArray(t.claude_desktop_models))return null;const a=Array.isArray(t.groups)?t.groups.filter(r=>"string"==typeof r&&!!r):[];return{group:t.group,groups:a.length>0?a:[t.group],claudeDesktopModels:f(t.claude_desktop_models)}}catch(r){return e.logError("fetchKeyGroupInfo",r),null}finally{clearTimeout(c)}}export async function fetchClientModelConfig(r={}){const e=await i(r);return e.config?n(e.config.models):null}export async function validateApiKey(r,t={}){const a=Date.now(),n=await async function(r,t){const{timeoutMs:a=3e4,retries:n=2,backoffMs:s=500,fetchFn:i=fetch,sleepFn:u=l}=t;let f={valid:!1,error:"network_error",message:o.t("validator.network")};for(let t=0;t<=n;t++){const o=await c(r,a,i);if(o.valid||"invalid_api_key"===o.error)return o.valid||e.logError("validateApiKey",new Error(o.message||"invalid_api_key")),o;f=o,t<n&&await u(s*Math.pow(2,t))}return e.logError("validateApiKey",new Error(f.message||"network_error")),f}(r,t);return s("validate-key",n.valid?"ok":"fail",{duration_ms:Date.now()-a,...n.valid?{}:{error:n.message??n.error,detail:{reason:n.error}}}),n}
@@ -0,0 +1 @@
1
+ import{chmodSync as e,existsSync as t,mkdirSync as r,readFileSync as n,renameSync as o,writeFileSync as s}from"fs";import{homedir as a}from"os";import{dirname as l,join as i,sep as u}from"path";import{spawnSync as c}from"child_process";import p from"chalk";import{checkForUpdate as d,compareSemver as m,readLocalPackage as f,UPDATE_SOURCES as _}from"../commands/update.js";import{i18n as h}from"./i18n.js";import{isColorEnabled as g}from"./runtime-options.js";import{logger as x}from"../utils/logger.js";import{isHelpRequest as v}from"./cli-help.js";import{brand as y,brandEnvName as S}from"./brand.js";export const UPDATE_CHECK_INTERVAL_MS=216e5;export const INSTALL_RETRY_INTERVAL_MS=36e5;export const INSTALL_TIMEOUT_MS=45e3;function k(e,t){return g()?e(t):t}export function resolveUpdateCachePath(e=process.env){const t=e[S("CONFIG_DIR")]?.trim();if(t)return i(t,"update-state.json");const r=e[S("TEST_HOME")]?.trim();return i(r||a(),y().configDirName,"update-state.json")}export function isGlobalPackageInstall(e){return e.split(u).includes("node_modules")}export function isNpxExecution(e=process.env){return"exec"===e.npm_command||"npx"===e.npm_lifecycle_event}export function isPnpmGlobalInstall(e){return e.includes(`${u}.pnpm${u}`)||e.includes(`${u}pnpm${u}global${u}`)}export function resolveNpmGlobalPrefix(e){const t=`${u}node_modules${u}`,r=e.indexOf(t);if(r<0)return null;const n=e.slice(0,r);return n.endsWith(`${u}lib`)?l(n):n}export function shouldSkipStartupUpdate(e,t=process.env){return"1"===t[S("SKIP_AUTO_UPDATE")]||"1"===t[S("DISABLE_AUTO_UPDATE")]||(!(!["--json","--non-interactive","--dry-run","--help","-h","--version","-v"].some(t=>e.includes(t))&&!v(e))||e.includes("update")||e.includes("completion"))}function A(t,n,a,i,u){try{r(l(t),{recursive:!0,mode:448});const c=`${t}.tmp-${process.pid}`,p={package_name:n,checked_at:a,latest:i.latest,source:i.source,registry:i.registry,errors:i.errors,...void 0===u?{}:{install_attempted_at:u,install_attempted_version:i.latest||void 0}};s(c,JSON.stringify(p),{encoding:"utf-8",mode:384}),o(c,t),e(t,384)}catch(e){x.warn("Failed to persist update check cache:",e)}}export function windowsShellCommand(e,t){return[e,...t.map(e=>`"${e}"`)].join(" ")}const P=(e,t)=>{const r={stdio:"inherit",timeout:45e3,killSignal:"SIGTERM"};return"win32"===process.platform?c(windowsShellCommand(e,t),{...r,shell:!0}):c(e,t,r)},$=(e,t)=>c(process.execPath,[process.argv[1],...e],{stdio:"inherit",env:t});export async function runStartupUpdate(e,r={}){const o=r.env||process.env,s=r.localPackage||f(),a=r.globalInstall??isGlobalPackageInstall(s.root),l=r.npx??isNpxExecution(o);if(!a||l||shouldSkipStartupUpdate(e,o))return{status:"skipped",handled:!1,source:null};const i=r.now??Date.now(),u=r.cachePath||resolveUpdateCachePath(o),c=function(e,r,o){try{if(!t(e))return null;const s=JSON.parse(n(e,"utf-8"));if(s.package_name!==r.name||!Number.isFinite(s.checked_at))return null;const a=s.latest?216e5:6e5;return o-s.checked_at>=a?null:{result:{current:r.version,latest:s.latest,up_to_date:s.latest?m(r.version,s.latest)>=0:null,source:s.source,registry:s.registry,errors:Array.isArray(s.errors)?s.errors:[],error:s.latest?null:(s.errors||[]).map(e=>`${e.source}: ${e.error}`).join("; ")||"unknown"},installAttemptedAt:s.latest&&s.install_attempted_version===s.latest&&Number.isFinite(s.install_attempted_at)?s.install_attempted_at:null}}catch{return null}}(u,s,i);let g=c?.result,x=c?.installAttemptedAt||null;if(g||(g=await d({localPackage:s,fetchFn:r.fetchFn}),A(u,s.name,i,g),x=null),!g.latest)return{status:"unavailable",handled:!1,source:null};if(g.up_to_date)return{status:"current",handled:!1,source:g.source};if(null!==x&&i-x<36e5)return{status:"update_failed",handled:!1,source:g.source};const v=r.output||console.log,y=r.errorOutput||console.error,T=r.installRunner||P,b=isPnpmGlobalInstall(s.root),w=b?"win32"===process.platform?"pnpm.cmd":"pnpm":"win32"===process.platform?"npm.cmd":"npm",I=b?null:resolveNpmGlobalPrefix(s.root);v(k(p.cyan,h.t("update.auto_installing",{version:g.latest})));let E=null,N="unknown";for(const e of _.map(e=>e.registry)){const t=T(w,b?["add","--global",`${s.name}@${g.latest}`,"--registry",e]:["install","--global",...I?["--prefix",I]:[],`${s.name}@${g.latest}`,"--registry",e,"--no-audit","--no-fund","--fetch-timeout=15000","--fetch-retries=1","--fetch-retry-mintimeout=1000","--fetch-retry-maxtimeout=3000"]);if(0===t.status){E=e;break}N=t.error?.message||`exit ${t.status??"unknown"}`}if(!E)return A(u,s.name,i,g,i),y(k(p.yellow,h.t("update.auto_failed",{error:N}))),{status:"update_failed",handled:!1,source:g.source};v(k(p.green,h.t("update.auto_installed",{version:g.latest})));const U=(r.reexecRunner||$)(e,{...o,[S("SKIP_AUTO_UPDATE")]:"1"});return U.error?(y(k(p.yellow,h.t("update.reexec_failed",{error:U.error.message}))),{status:"update_failed",handled:!1,source:g.source}):(process.exitCode=U.status??1,{status:"reexecuted",handled:!0,source:g.source})}