@xship/cli 0.0.146 → 0.0.147
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.
- package/client-config.snapshot.json +16 -16
- package/dist/client-config.snapshot.json +16 -16
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/setup.js +1 -1
- package/dist/commands/update.js +1 -1
- package/dist/commands/upgrade.js +1 -1
- package/dist/lib/app-update.js +1 -0
- package/dist/lib/post-apply.js +1 -1
- package/dist/lib/program.js +1 -1
- package/dist/lib/tool-manager.js +1 -1
- package/dist/lib/tools/claude-desktop-app.js +1 -0
- package/dist/lib/tools/claude-desktop.js +1 -1
- package/dist/lib/tools/desktop-process.js +1 -1
- package/dist/lib/wizard.js +1 -1
- package/dist/locales/en_US.json +48 -7
- package/dist/locales/zh_CN.json +48 -7
- package/package.json +1 -1
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
{
|
|
30
30
|
"description": "轻量档 | 低延迟 | 高频短任务",
|
|
31
|
-
"group": "
|
|
31
|
+
"group": "grp_6eg2dq9ywgrg",
|
|
32
32
|
"group_name": "",
|
|
33
33
|
"hidden": false,
|
|
34
34
|
"id": "claude-haiku-4-5-20251001",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
39
|
"description": "100 万上下文 | 12.8 万输出 | 低延迟 | 高频轻量任务",
|
|
40
|
-
"group": "
|
|
40
|
+
"group": "grp_6eg2dq9ywgrg",
|
|
41
41
|
"group_name": "",
|
|
42
42
|
"hidden": false,
|
|
43
43
|
"id": "claude-haiku-5-5",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
"description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
|
|
58
|
-
"group": "
|
|
58
|
+
"group": "grp_6lyxfgbs440g",
|
|
59
59
|
"group_name": "",
|
|
60
60
|
"hidden": false,
|
|
61
61
|
"id": "claude-opus-4-7",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
66
|
"description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
|
|
67
|
-
"group": "
|
|
67
|
+
"group": "grp_6eg2dq9ywgrg",
|
|
68
68
|
"group_name": "",
|
|
69
69
|
"hidden": false,
|
|
70
70
|
"id": "claude-opus-4-8",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
75
|
"description": "100 万上下文 | 12.8 万输出 | 自适应思考五档 | Agent 编程",
|
|
76
|
-
"group": "
|
|
76
|
+
"group": "grp_pzxnceygmqlp",
|
|
77
77
|
"group_name": "",
|
|
78
78
|
"hidden": false,
|
|
79
79
|
"id": "claude-opus-5",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
},
|
|
83
83
|
{
|
|
84
84
|
"description": "100 万上下文 | 长时 Agent 编程 | 知识工作",
|
|
85
|
-
"group": "
|
|
85
|
+
"group": "grp_irydsgijuckh",
|
|
86
86
|
"group_name": "",
|
|
87
87
|
"hidden": false,
|
|
88
88
|
"id": "claude-opus-5-5",
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
},
|
|
92
92
|
{
|
|
93
93
|
"description": "100 万上下文 | Agent 编程 | 长上下文不加价",
|
|
94
|
-
"group": "
|
|
94
|
+
"group": "grp_6eg2dq9ywgrg",
|
|
95
95
|
"group_name": "",
|
|
96
96
|
"hidden": false,
|
|
97
97
|
"id": "claude-sonnet-4-6",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
},
|
|
101
101
|
{
|
|
102
102
|
"description": "100 万上下文 | Agent 编程 | 工具调用 | 知识工作",
|
|
103
|
-
"group": "
|
|
103
|
+
"group": "grp_rld6af0zorqd",
|
|
104
104
|
"group_name": "",
|
|
105
105
|
"hidden": false,
|
|
106
106
|
"id": "claude-sonnet-5",
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
},
|
|
110
110
|
{
|
|
111
111
|
"description": "100 万上下文 | 12.8 万输出 | Agent 编程 | 知识工作",
|
|
112
|
-
"group": "
|
|
112
|
+
"group": "grp_6eg2dq9ywgrg",
|
|
113
113
|
"group_name": "",
|
|
114
114
|
"hidden": false,
|
|
115
115
|
"id": "claude-sonnet-5-5",
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
"codex": [
|
|
121
121
|
{
|
|
122
122
|
"description": "105 万上下文 | 12.8 万输出 | 大批量低成本档",
|
|
123
|
-
"group": "
|
|
123
|
+
"group": "grp_bsbtt432saoq",
|
|
124
124
|
"group_name": "",
|
|
125
125
|
"hidden": false,
|
|
126
126
|
"id": "gpt-5.6-luna",
|
|
@@ -138,7 +138,7 @@
|
|
|
138
138
|
},
|
|
139
139
|
{
|
|
140
140
|
"description": "105 万上下文 | 12.8 万输出 | 均衡生产档",
|
|
141
|
-
"group": "
|
|
141
|
+
"group": "grp_irydsgijuckh",
|
|
142
142
|
"group_name": "",
|
|
143
143
|
"hidden": false,
|
|
144
144
|
"id": "gpt-5.6-terra",
|
|
@@ -156,7 +156,7 @@
|
|
|
156
156
|
},
|
|
157
157
|
{
|
|
158
158
|
"description": "转发至 gpt-6-sol | 实际由 gpt-6-sol 响应 | 105 万上下文 | 12.8 万输出",
|
|
159
|
-
"group": "
|
|
159
|
+
"group": "grp_irydsgijuckh",
|
|
160
160
|
"group_name": "",
|
|
161
161
|
"hidden": false,
|
|
162
162
|
"id": "gpt-6-luna",
|
|
@@ -174,7 +174,7 @@
|
|
|
174
174
|
},
|
|
175
175
|
{
|
|
176
176
|
"description": "105 万上下文 | 12.8 万输出 | 文字与图像输入 | 工具调用、联网搜索、结构化输出 | 工具调用使用 Responses API",
|
|
177
|
-
"group": "
|
|
177
|
+
"group": "grp_mb5v069lpnze",
|
|
178
178
|
"group_name": "",
|
|
179
179
|
"hidden": false,
|
|
180
180
|
"id": "gpt-6.1-sol",
|
|
@@ -183,7 +183,7 @@
|
|
|
183
183
|
},
|
|
184
184
|
{
|
|
185
185
|
"description": "105 万上下文 | 12.8 万输出 | 计算机操作与日常 Agent 任务 | 均衡档",
|
|
186
|
-
"group": "
|
|
186
|
+
"group": "grp_squ2qzjnehps",
|
|
187
187
|
"group_name": "",
|
|
188
188
|
"hidden": false,
|
|
189
189
|
"id": "gpt-6.1-terra",
|
|
@@ -275,7 +275,7 @@
|
|
|
275
275
|
},
|
|
276
276
|
{
|
|
277
277
|
"description": "约 100 万上下文 | 深度推理 | 文本、图像、音视频输入",
|
|
278
|
-
"group": "
|
|
278
|
+
"group": "grp_3pi5kyqkp51b",
|
|
279
279
|
"group_name": "",
|
|
280
280
|
"hidden": false,
|
|
281
281
|
"id": "gemini-4-argon",
|
|
@@ -295,7 +295,7 @@
|
|
|
295
295
|
"grok": [
|
|
296
296
|
{
|
|
297
297
|
"description": "50 万上下文 | 1.5 万亿参数 MoE | 编码与 Agent",
|
|
298
|
-
"group": "
|
|
298
|
+
"group": "grp_l34dwliv4yas",
|
|
299
299
|
"group_name": "",
|
|
300
300
|
"hidden": false,
|
|
301
301
|
"id": "grok-4.5",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
{
|
|
30
30
|
"description": "轻量档 | 低延迟 | 高频短任务",
|
|
31
|
-
"group": "
|
|
31
|
+
"group": "grp_6eg2dq9ywgrg",
|
|
32
32
|
"group_name": "",
|
|
33
33
|
"hidden": false,
|
|
34
34
|
"id": "claude-haiku-4-5-20251001",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
39
|
"description": "100 万上下文 | 12.8 万输出 | 低延迟 | 高频轻量任务",
|
|
40
|
-
"group": "
|
|
40
|
+
"group": "grp_6eg2dq9ywgrg",
|
|
41
41
|
"group_name": "",
|
|
42
42
|
"hidden": false,
|
|
43
43
|
"id": "claude-haiku-5-5",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
"description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
|
|
58
|
-
"group": "
|
|
58
|
+
"group": "grp_6lyxfgbs440g",
|
|
59
59
|
"group_name": "",
|
|
60
60
|
"hidden": false,
|
|
61
61
|
"id": "claude-opus-4-7",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
66
|
"description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
|
|
67
|
-
"group": "
|
|
67
|
+
"group": "grp_6eg2dq9ywgrg",
|
|
68
68
|
"group_name": "",
|
|
69
69
|
"hidden": false,
|
|
70
70
|
"id": "claude-opus-4-8",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
75
|
"description": "100 万上下文 | 12.8 万输出 | 自适应思考五档 | Agent 编程",
|
|
76
|
-
"group": "
|
|
76
|
+
"group": "grp_pzxnceygmqlp",
|
|
77
77
|
"group_name": "",
|
|
78
78
|
"hidden": false,
|
|
79
79
|
"id": "claude-opus-5",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
},
|
|
83
83
|
{
|
|
84
84
|
"description": "100 万上下文 | 长时 Agent 编程 | 知识工作",
|
|
85
|
-
"group": "
|
|
85
|
+
"group": "grp_irydsgijuckh",
|
|
86
86
|
"group_name": "",
|
|
87
87
|
"hidden": false,
|
|
88
88
|
"id": "claude-opus-5-5",
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
},
|
|
92
92
|
{
|
|
93
93
|
"description": "100 万上下文 | Agent 编程 | 长上下文不加价",
|
|
94
|
-
"group": "
|
|
94
|
+
"group": "grp_6eg2dq9ywgrg",
|
|
95
95
|
"group_name": "",
|
|
96
96
|
"hidden": false,
|
|
97
97
|
"id": "claude-sonnet-4-6",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
},
|
|
101
101
|
{
|
|
102
102
|
"description": "100 万上下文 | Agent 编程 | 工具调用 | 知识工作",
|
|
103
|
-
"group": "
|
|
103
|
+
"group": "grp_rld6af0zorqd",
|
|
104
104
|
"group_name": "",
|
|
105
105
|
"hidden": false,
|
|
106
106
|
"id": "claude-sonnet-5",
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
},
|
|
110
110
|
{
|
|
111
111
|
"description": "100 万上下文 | 12.8 万输出 | Agent 编程 | 知识工作",
|
|
112
|
-
"group": "
|
|
112
|
+
"group": "grp_6eg2dq9ywgrg",
|
|
113
113
|
"group_name": "",
|
|
114
114
|
"hidden": false,
|
|
115
115
|
"id": "claude-sonnet-5-5",
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
"codex": [
|
|
121
121
|
{
|
|
122
122
|
"description": "105 万上下文 | 12.8 万输出 | 大批量低成本档",
|
|
123
|
-
"group": "
|
|
123
|
+
"group": "grp_bsbtt432saoq",
|
|
124
124
|
"group_name": "",
|
|
125
125
|
"hidden": false,
|
|
126
126
|
"id": "gpt-5.6-luna",
|
|
@@ -138,7 +138,7 @@
|
|
|
138
138
|
},
|
|
139
139
|
{
|
|
140
140
|
"description": "105 万上下文 | 12.8 万输出 | 均衡生产档",
|
|
141
|
-
"group": "
|
|
141
|
+
"group": "grp_irydsgijuckh",
|
|
142
142
|
"group_name": "",
|
|
143
143
|
"hidden": false,
|
|
144
144
|
"id": "gpt-5.6-terra",
|
|
@@ -156,7 +156,7 @@
|
|
|
156
156
|
},
|
|
157
157
|
{
|
|
158
158
|
"description": "转发至 gpt-6-sol | 实际由 gpt-6-sol 响应 | 105 万上下文 | 12.8 万输出",
|
|
159
|
-
"group": "
|
|
159
|
+
"group": "grp_irydsgijuckh",
|
|
160
160
|
"group_name": "",
|
|
161
161
|
"hidden": false,
|
|
162
162
|
"id": "gpt-6-luna",
|
|
@@ -174,7 +174,7 @@
|
|
|
174
174
|
},
|
|
175
175
|
{
|
|
176
176
|
"description": "105 万上下文 | 12.8 万输出 | 文字与图像输入 | 工具调用、联网搜索、结构化输出 | 工具调用使用 Responses API",
|
|
177
|
-
"group": "
|
|
177
|
+
"group": "grp_mb5v069lpnze",
|
|
178
178
|
"group_name": "",
|
|
179
179
|
"hidden": false,
|
|
180
180
|
"id": "gpt-6.1-sol",
|
|
@@ -183,7 +183,7 @@
|
|
|
183
183
|
},
|
|
184
184
|
{
|
|
185
185
|
"description": "105 万上下文 | 12.8 万输出 | 计算机操作与日常 Agent 任务 | 均衡档",
|
|
186
|
-
"group": "
|
|
186
|
+
"group": "grp_squ2qzjnehps",
|
|
187
187
|
"group_name": "",
|
|
188
188
|
"hidden": false,
|
|
189
189
|
"id": "gpt-6.1-terra",
|
|
@@ -275,7 +275,7 @@
|
|
|
275
275
|
},
|
|
276
276
|
{
|
|
277
277
|
"description": "约 100 万上下文 | 深度推理 | 文本、图像、音视频输入",
|
|
278
|
-
"group": "
|
|
278
|
+
"group": "grp_3pi5kyqkp51b",
|
|
279
279
|
"group_name": "",
|
|
280
280
|
"hidden": false,
|
|
281
281
|
"id": "gemini-4-argon",
|
|
@@ -295,7 +295,7 @@
|
|
|
295
295
|
"grok": [
|
|
296
296
|
{
|
|
297
297
|
"description": "50 万上下文 | 1.5 万亿参数 MoE | 编码与 Agent",
|
|
298
|
-
"group": "
|
|
298
|
+
"group": "grp_l34dwliv4yas",
|
|
299
299
|
"group_name": "",
|
|
300
300
|
"hidden": false,
|
|
301
301
|
"id": "grok-4.5",
|
package/dist/commands/doctor.js
CHANGED
|
@@ -1 +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
|
|
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 c}from"net";import{join as i}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 b,codexWorkModeOn as w}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{appStatus as C,appStatusText as I,appTools as H,appUpgradeCommand as L}from"../lib/app-update.js";import{balanceLookupEnabled as S,balanceNeedsAttention as U,balanceText as E,fetchKeyBalances as K}from"../lib/key-balance.js";const B=["HTTPS_PROXY","https_proxy","HTTP_PROXY","http_proxy","ALL_PROXY","all_proxy"];function G(o,t,e=3e3){return new Promise(s=>{const r=c({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 D(){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(i(o,t),"utf-8")).join("\n");return R(t.slice(-15e4))}function q(){const o={};for(const t of B){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(),c=[],A=Number(process.versions.node.split(".")[0]);c.push({name:"Node.js",status:A>=20?"pass":"fail",message:`v${process.versions.node}`}),n.text=u.t("doctor.check_proxy"),c.push(await async function(){const o=u.t("doctor.proxy"),t=new Map;for(const o of B){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 G(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(),F=u.t("doctor.api_key_network");if(R){const o=await m(R);o.valid?(c.push({name:F,status:"pass"}),n.text=u.t("doctor.check_balance"),c.push(...await async function(o){if(!S())return[];const t=l.listToolApiKeys().map(o=>({tool:o,key:l.getApiKeyForTool(o)})).filter(t=>Boolean(t.key)&&t.key!==o),e=await K([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:U(t)?"warn":"pass",message:E(t)})}return r}(R))):"invalid_api_key"===o.error?c.push({name:F,status:"fail",message:u.t("doctor.api_key_invalid")}):(c.push({name:F,status:"fail",message:`${u.t("doctor.network_error")}: ${o.message??o.error}`}),n.text=u.t("doctor.check_other_addresses"),c.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 c.push({name:F,status:"fail",message:u.t("doctor.api_key_missing")});n.text=u.t("doctor.check_client_config");const M=await o();c.push({name:u.t("doctor.client_config"),status:"cloud"===M.source||"cache"===M.source&&!M.problem?"pass":"warn",message:[M.source?u.t(`refresh.source.${M.source}`):u.t("refresh.source.none"),M.revision?u.t("doctor.client_config_revision",{revision:M.revision}):"",M.problem??""].filter(Boolean).join(" · ")}),n.text=u.t("doctor.check_tools");const X=p.getInstalledTools();c.push({name:u.t("doctor.installed_tools"),status:X.length>0?"pass":"warn",message:X.length>0?X.map(o=>f(o)?.displayName??o).join(u.t("setup.list_separator")):u.t("doctor.no_tools_installed")}),c.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}()),c.push(...await async function(){const o=[];for(const t of H()){const e=await C(t,{refresh:!0});if(!e.installed||!e.current)continue;const s=u.t("doctor.app_version",{tool:e.name});if(e.outdated){const r=e.blocker?u.t(`app_update.blocked_${e.blocker}`,{tool:e.name}):u.t("doctor.run_app_upgrade",{command:L(t)});o.push({name:s,status:"warn",message:`${I(e)}\n ${r}`})}else o.push({name:s,status:"pass",message:I(e)})}return o}());const Y=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(i(process.env.CLAUDE_CONFIG_DIR?.trim()||i(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")}}();Y&&c.push(Y),X.includes("claude-code")&&v()&&c.push({name:u.t("doctor.claude_login"),status:"pass",message:u.t("tools.claude_code.account_login_overridden")});const V=X.includes("codex")?y():null;if(X.includes("codex")&&c.push({name:u.t("doctor.codex_auth"),status:V?"fail":"pass",message:V?u.t(`doctor.codex_${V}`,{path:P(b())}):void 0}),X.includes("codex")){const o=k();c.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})}X.includes("codex")&&w()&&c.push({name:u.t("doctor.codex_work_mode"),status:"warn",message:u.t("tools.codex.work_mode_on")}),"win32"===process.platform&&X.includes("claude-code")&&!process.env.CLAUDE_CODE_GIT_BASH_PATH&&c.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&&X.includes("claude-code")&&(n.text=u.t("doctor.check_claude_request"),c.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 c=(`${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:c})}}())),n.stop(),console.log("\n"+t.bold(u.t("doctor.results_title"))+"\n");const W={pass:t.green("√"),warn:t.yellow("!"),fail:t.red("×")};for(const o of c)console.log(`${W[o.status]} ${o.name}`),o.message&&console.log(t.gray(` ${o.message}`));if(c.every(o=>"pass"===o.status)&&console.log("\n"+t.green.bold(u.t("doctor.all_good"))),!r.deep&&X.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:q()},log:D()}}(c,{source:M.source??void 0,revision:M.revision,problem:M.problem}));t?o.succeed(u.t("doctor.report_done",{code:t})):o.fail(u.t("doctor.report_failed",{cli:O}))}else c.some(o=>"fail"===o.status)&&console.log(t.gray("\n"+u.t("doctor.report_hint",{cli:O})));c.some(o=>"fail"===o.status)&&(process.exitCode=1)}
|
package/dist/commands/setup.js
CHANGED
|
@@ -1 +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"])}
|
|
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 p}from"../lib/api-validator.js";import{CODEX_ONE_MILLION_CONTEXT_SETTING as d,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{canPrompt as h,emitJson as b,isColorEnabled as w,isDryRun as v,isJsonMode as x,isNonInteractive as C,shouldAutoConfirm as j}from"../lib/runtime-options.js";import{appUpgradeCommand as K}from"../lib/app-update.js";import{join as $}from"path";import{confirmWritePlan as T,printWritePlan as G,toolWritePlan as M}from"../lib/write-plan.js";import N from"inquirer";import{logger as S}from"../utils/logger.js";import{forgetInstalls as E}from"../lib/tools/tool-installs.js";import{CLI_NAME as I,brandEnv as A}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 O(o){const e=await p(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 B(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 D(e){console.log(o.green(e))}function F(e){console.log(o.yellow(e))}function L(e){console.error(o.red(e))}let R=null;function P(o){const e={operation:1,authentication:2,network:3};(!R||e[o]>e[R])&&(R=o)}async function Y(e,t){x()||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?`${I} setup --key ${a}`:`${I} setup ${e} ${a}`;let p;if("network_error"===i.error?(P("network"),p=_(l.t("setup.unreachable",{url:s.getBaseUrl(),reason:i.message||"network error"}),`${I} base auto`,"network_error")):"invalid_api_key"===i.error?(P("authentication"),p=y(l.t("setup.invalid_key",{label:e,reason:i.message||"invalid"}),n,"invalid_api_key")):(P("operation"),p=g(l.t("setup.validate_failed",{label:e,reason:i.message||i.error||"unknown"}),n,i.error)),x())throw p;return L(p.message),console.log(o.gray(l.t("errors.next_step",{command:p.hint}))),!1}async function q(t,i,r={}){const{oneMillion:p,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!==p&&s.setToolSetting("codex",d,p),"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(x())throw g(o instanceof Error?o.message:String(o),`${I} setup --key ${l.t("errors.key_placeholder")}`,"config_write_failed");const e=(o instanceof Error?o.message:String(o)).replace(/\s+/g," ").trim();return L("× "+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!==p&&console.log(o.gray(" "+l.t(p?"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 H(o){return!e(o)?.isInstalled&&!a.isToolInstalled(o)}export async function installMissingApps(t,i){const s=t.filter(o=>{const t=e(o)?.appInstaller;try{return Boolean(t&&!t.blocker()&&!t.installedPath())}catch(e){return S.logError(`setup: app installed? ${o}`,e),!1}});if(0===s.length)return!1;let a=i;if(void 0===a&&h()&&!j()){const o=s.map(o=>n[o].displayName).join(l.t("setup.list_separator"));console.log(""),a=(await N.prompt([{type:"confirm",name:"go",message:l.t("setup.install_app_confirm",{tools:o}),default:!1}])).go}if(!a&&!x())for(const e of s)console.log(o.gray(l.t("setup.install_app_hint",{tool:n[e].displayName,command:K(e)})));return Boolean(a)}function W(o){F(l.t("setup.still_missing",{tools:o.map(o=>n[o].displayName).join(l.t("setup.list_separator")),commands:o.map(o=>`${I} config ${o} --yes`).join(l.t("setup.list_separator"))}))}function U(e,t,i=[]){const a=M(e),n=$(s.getConfigDir(),"config.yaml");if(x())b({dry_run:!0,tools:a,install_first:i,key_file:t?n:null});else{if(0===a.length&&0===i.length){const e=(w()?o.cyan:o=>o)(l.t("runtime.dry_run_label"));return void console.log(`${e} ${l.t("setup.dry_run_none")}`)}G(a,{label:l.t("runtime.dry_run_label"),keyFile:t?n:void 0,installFirst:i})}}function z(){return"darwin"===process.platform||"win32"===process.platform||a.isToolInstalled("claude-desktop")}export async function setupCommand(r){R=null;const p=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 L(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 L(l.t("setup.desktop_registry_invalid",{value:String(r.desktopRegistry)})),void(process.exitCode=1);const b=g||_,w=Boolean(p||f.length>0),K={oneMillion:r.oneMillion,officialLogin:y,desktopRegistry:h,force:r.force};if(!w&&(m||b)&&v())return void U([...m?["codex"]:[],...b?["claude-desktop"]:[]],!1);if(!w&&(m||b)){if(m){const o=s.getApiKeyForTool("codex");if(o)try{const e=!0===r.oneMillion;s.setToolSetting("codex",d,e);const t=await u(o);c(e,t??void 0),D(l.t(e?"setup.codex_1m_enabled":"setup.codex_1m_disabled"))}catch(o){L(l.t("setup.apply_failed",{tool:n.codex.displayName,reason:o instanceof Error?o.message:String(o)})),process.exitCode=1}else L(l.t("setup.codex_1m_missing_key")),process.exitCode=1}if(b){const o=s.getApiKeyForTool("claude-desktop");o?await q("claude-desktop",o,{...K,oneMillion:void 0})?await t(["claude-desktop"],{apps:{install:!1}}):process.exitCode=1:(L(l.t("setup.desktop_official_login_missing_key")),process.exitCode=1)}return}if(!w)return L(l.t("setup.usage")),void(process.exitCode=1);const G=v();G||await i(p||f[0].apiKey);const M=[],P=[];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 Y(o.label,o.apiKey)){V+=1;continue}const e=await O(o.apiKey);!e.probed||B(e,o.need)?(e.probed||F(l.t("setup.probe_failed",{label:o.label})),M.push({tool:o.tool,apiKey:o.apiKey,dedicated:!0}),X.add(o.tool)):(L(l.t(`setup.key_no_${o.need}`,{label:o.label,tool:n[o.tool].displayName})),V+=1)}const oo=!!p&&await Y("--key",p);p&&!oo&&(J=k[R??"operation"]);const eo=p&&oo?await O(p):void 0;if(p&&eo&&!eo.probed&&F(l.t("setup.probe_failed",{label:"--key"})),!(p&&eo&&eo.probed)||eo.hasClaude||eo.hasGpt||eo.hasGrok||eo.hasGemini||(L(l.t("setup.key_no_family")),J=1),p&&eo&&void 0===J){const o=[{tool:"claude-code",capable:eo.hasClaude,skipMsg:l.t(z()?"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&&z(),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?(M.push({tool:e.tool,apiKey:p,dedicated:!1}),X.add(e.tool)):e.quiet||F(e.skipMsg))}const to=Boolean(p&&oo&&void 0===J);if(G)return U(M.filter(o=>!H(o.tool)).map(o=>o.tool),M.length>0,M.filter(o=>H(o.tool)).map(o=>o.tool)),void((V>0||void 0!==J)&&(process.exitCode=J??k[R??"operation"]));const io=M.filter(o=>!H(o.tool)),lo=to||M.some(o=>o.dedicated);if((M.length>0||lo)&&!r.fromInstaller&&!await T(io.map(o=>o.tool),{keyFile:lo?$(s.getConfigDir(),"config.yaml"):void 0,installFirst:M.filter(o=>H(o.tool)).map(o=>o.tool)}))return void(process.exitCode=k.cancelled);to&&p&&s.setApiKey(p);for(const o of M)o.dedicated&&s.setToolApiKey(o.tool,o.apiKey),H(o.tool)?P.push({tool:o.tool,apiKey:o.apiKey}):await q(o.tool,o.apiKey,K)?Q+=1:(V+=1,X.delete(o.tool));if(void 0!==J)return P.length>0&&W(P.map(o=>o.tool)),void(process.exitCode=J);let so=[];if(P.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 p=t;if(void 0!==p||x()||(j()?p=!C():process.stdin.isTTY&&(console.log(""),p=(await N.prompt([{type:"confirm",name:"go",message:l.t("setup.install_confirm",{tools:r}),default:!0}])).go)),!p){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 x()||console.log(o.gray(l.t("setup.install_all_hint",{cli:I}))),{still:s,applied:[],failed:[]}}const d=[];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)}E(),a.isToolInstalled(e)||d.push(e)}const c=s.filter(o=>!d.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 q(o,t,i)?u.push(o):f.push(o);return{still:d,applied:u,failed:f}}(P,r.install,K);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)});D("\n"+(i?`${s}${l.t("setup.done_commands",{commands:i})}`:s)),so.length>0&&W(so);for(const o of t){const e=a.ensureNativeOnPath(o);e&&D(l.t("setup.path_added",{tool:n[o].displayName,dir:e}))}const r=t.filter(o=>!a.isOnPath(o));if(r.length>0&&!x()&&"1"!==A("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&&W(so),V>0&&(L(l.t("setup.failed_summary",{count:String(V)})),x()||console.error(`${I} setup --key ${l.t("errors.key_placeholder")}`)),await t([...X],{apps:{install:await installMissingApps([...X],r.install)}}),(V>0||0===Q&&0===so.length)&&(process.exitCode=k[R??"operation"])}
|
package/dist/commands/update.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import t from"chalk";import{readFileSync as e}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 c,isColorEnabled as i}from"../lib/runtime-options.js";import{brand as l}from"../lib/brand.js";import{appStatus as u,appStatusText as p,appTools as m,appUpgradeCommand as d}from"../lib/app-update.js";import{logger as g}from"../utils/logger.js";const f=l().packageName;export const UPDATE_TIMEOUT_MS=1500;const h=t=>{const e=t["dist-tags"];if(!e||"object"!=typeof e)return null;const r=e.latest;return"string"==typeof r?r:null};export const UPDATE_SOURCES=l().updateRegistries.map(({id:t,url:e})=>({id:t,registry:e,metadataUrl:t=>((t,e,r="")=>`${t}${encodeURIComponent(e)}${r}`)(e,t),readVersion:h}));function y(t){return i()?t:t=>t}export function readLocalPackage(){const t=n(import.meta.url),a=o(t),s=r(a,"..","..");try{const t=JSON.parse(e(r(s,"package.json"),"utf-8"));return{name:t.name||f,version:t.version||"0.0.0",root:s}}catch{return{name:f,version:"0.0.0",root:s}}}function w(t){const[e,...r]=t.split("-"),o=r.length?r.join("-").split("."):[];return{main:e.split(".").map(t=>Number.parseInt(t,10)||0),pre:o}}function k(t,e){const r=Number.parseInt(t,10),o=Number.parseInt(e,10),n=Number.isFinite(r)&&String(r)===t,a=Number.isFinite(o)&&String(o)===e;return n&&a?r-o:n?-1:a?1:t<e?-1:t>e?1:0}export function compareSemver(t,e){const r=w(t),o=w(e),n=Math.max(r.main.length,o.main.length);for(let t=0;t<n;t+=1){const e=(r.main[t]||0)-(o.main[t]||0);if(0!==e)return e}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 t=0;t<a;t+=1){const e=r.pre[t],n=o.pre[t];if(void 0===e)return-1;if(void 0===n)return 1;const a=k(e,n);if(0!==a)return a}return 0}async function b(t,e,r,o){const n=new AbortController,a=setTimeout(()=>n.abort(),o);try{const o=await r(t.metadataUrl(e),{headers:{Accept:"application/json"},signal:n.signal});if(!o.ok)throw new Error(`HTTP ${o.status}`);const a=await o.json(),s=t.readVersion(a);if(!s)throw new Error("invalid registry metadata");return s}catch(t){if(n.signal.aborted)throw new Error(`timeout after ${o}ms`);throw t}finally{clearTimeout(a)}}export async function checkForUpdate(t={}){const e=t.localPackage||readLocalPackage(),r=t.localVersion||e.version,o=t.packageName||e.name,n=t.fetchFn||fetch,a=t.timeoutMs||1500,s=t.sources||UPDATE_SOURCES,c=[];for(const t of s)try{const e=await b(t,o,n,a);return{current:r,latest:e,up_to_date:compareSemver(r,e)>=0,source:t.id,registry:t.registry,errors:c,error:null}}catch(e){c.push({source:t.id,error:e instanceof Error?e.message:String(e)})}return{current:r,latest:null,up_to_date:null,source:null,registry:null,errors:c,error:c.map(t=>`${t.source}: ${t.error}`).join("; ")||"unknown"}}function $(e){for(const r of e){const e=p(r);e&&(console.log(" "+y(r.outdated?t.yellow:t.cyan)(`${r.name}: ${e}`)),r.outdated&&console.log(" "+y(t.gray)(a.t("update.command_hint",{command:d(r.tool)}))))}}export async function updateCommand(e={}){const r=e.localPackage||readLocalPackage();s()||console.log(y(t.gray)(a.t("update.checking")));const o=await checkForUpdate({...e,localPackage:r}),n=await async function(){const t=[];for(const e of m())try{const r=await u(e);r.installed&&!r.blocker&&t.push(r)}catch(t){g.logError(`update: app status ${e}`,t)}return t}();if(s())c({...o,apps:n.map(t=>({tool:t.tool,installed:t.installed,current:t.current,latest:t.latest,outdated:t.outdated,upgraded:!1}))});else{if(console.log(` ${y(t.cyan)(a.t("update.current",{version:o.current}))}`),!o.latest)return console.log(" "+y(t.yellow)(a.t("update.fetch_failed",{error:o.error||"unknown"}))),void $(n);if(console.log(` ${y(t.cyan)(a.t("update.latest",{version:o.latest}))}`),console.log(` ${y(t.cyan)(a.t("update.source",{source:l().updateRegistries.find(t=>t.id===o.source)?.label??o.source??"unknown"}))}`),o.up_to_date)console.log(" "+y(t.green)(a.t("update.up_to_date")));else{const e="npm"===o.source?"":` --registry ${o.registry}`,n=`npm install -g ${r.name}@latest${e}`;console.log(" "+y(t.yellow)(a.t("update.available"))),console.log(" "+y(t.gray)(a.t("update.command_hint",{command:n})))}$(n)}}
|
package/dist/commands/upgrade.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import o from"chalk";import{i18n as
|
|
1
|
+
import o from"chalk";import{appTools as t,upgradeApp as e}from"../lib/app-update.js";import{i18n as l}from"../lib/i18n.js";import{emitJson as r,isJsonMode as n}from"../lib/runtime-options.js";import{toolManager as i}from"../lib/tool-manager.js";import{getAdapter as s,listAdapters as a}from"../lib/tools/registry.js";import{upgradeTool as p}from"../lib/tool-upgrade.js";export async function upgradeCommand(d){const c=t(),u=[...a().filter(o=>o.installSpec).map(o=>o.name),...c],m=d.length>0?d:u.filter(o=>c.includes(o)?(o=>{const t=s(o)?.appInstaller;return Boolean(t&&!t.blocker()&&t.installedPath())})(o):i.isToolInstalled(o)),f=m.filter(o=>!u.includes(o));if(f.length>0)return console.error(o.red(l.t("upgrade.unsupported",{tool:f.join(", ")}))),console.error(l.t("upgrade.supported",{tools:u.join(" / ")})),void(process.exitCode=1);if(0===m.length)return void(n()?r({tools:[]}):console.log(l.t("upgrade.nothing_installed",{tools:u.join(" / ")})));let g=0;const j=[];for(const t of m){if(c.includes(t)){const l=s(t)?.displayName??t;n()||console.log(o.bold(`\n${l}`));const r=await e(t,{install:!0}),i=["installed","upgraded","up_to_date","declined"].includes(r.result);i||(g+=1),j.push({...r,ok:i});continue}const l=await p(t);l||(g+=1),j.push({tool:t,ok:l})}n()&&r({tools:j}),g>0&&(process.exitCode=1)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import t from"chalk";import e from"inquirer";import{existsSync as r,mkdirSync as n,readFileSync as a,writeFileSync as o}from"fs";import{join as l}from"path";import{CLI_NAME as p}from"./brand.js";import{configManager as i}from"./config.js";import{i18n as s}from"./i18n.js";import{canPrompt as u,hasExplicitYes as d,isJsonMode as c}from"./runtime-options.js";import{track as f}from"./telemetry.js";import{compareVersions as m}from"./model-registry.js";import{getAdapter as g,listAdapters as _}from"./tools/registry.js";import{logger as y}from"../utils/logger.js";function w(){return l(i.getConfigDir(),"app-releases.json")}function h(){try{if(!r(w()))return{};const t=JSON.parse(a(w(),"utf-8"));return t&&"object"==typeof t?t:{}}catch{return{}}}function k(t,e){try{n(i.getConfigDir(),{recursive:!0}),o(w(),JSON.stringify({...h(),[t]:e},null,2))}catch(t){y.logError("app-update.writeCache",t)}}export function appTools(){return _().filter(t=>t.appInstaller).map(t=>t.name)}function b(t){const e=g(t);if(!e?.appInstaller)throw new Error(`no app installer for ${t}`);return e}function v(t,e,r){try{return e()}catch(e){return y.logError(`app-update.${t}`,e),r}}function j(t){const e=b(t),r=e.appInstaller,n=v("installedPath",()=>null!==r.installedPath(),!1);return{tool:t,name:e.displayName,installed:n,current:n?v("installedVersion",()=>e.installedVersion?.()??null,null):null,running:!!n&&v("isRunning",()=>e.runningApp?.isRunning()??!1,!1),blocker:v("blocker",()=>r.blocker(),"unsupported_platform")}}function $(t,e,r){const n=Boolean(t.installed&&t.current&&e&&m(t.current,e)<0);return{...t,latest:e,outdated:n,...r?{error:r}:{}}}export async function appStatus(t,e={}){const r=j(t);if(r.blocker&&"classic_install"!==r.blocker)return $(r,null);const n=h()[t],a=n&&Date.now()-n.checked_at<(n.version?36e5:6e5);if(n&&a&&!e.refresh)return $(r,n.version??null,n.error);try{const e=await b(t).appInstaller.latestVersion();return k(t,{version:e,checked_at:Date.now()}),$(r,e)}catch(e){const a=e instanceof Error?e.message:String(e);return y.logError(`app-update.latest(${t})`,e),k(t,{error:a,checked_at:Date.now()}),$(r,n?.version??null,a)}}export function cachedAppStatus(t){const e=j(t);return $(e,e.blocker&&"classic_install"!==e.blocker?null:h()[t]?.version??null)}export function appStatusText(t){return t.installed?t.outdated?s.t("app_update.outdated",{current:t.current,latest:t.latest}):t.current&&t.latest?s.t("app_update.up_to_date",{current:t.current}):t.current??"":t.latest?s.t("app_update.not_installed",{latest:t.latest}):""}export function appUpgradeCommand(t){return`${p} upgrade ${t}`}function q(t){c()?process.stderr.write(t+"\n"):console.log(t)}export async function upgradeApp(r,n={}){const a=Date.now(),o=await appStatus(r,{refresh:n.refresh??!0}),l=o.name,p=(t,e={})=>{const n={...o,result:t,upgraded:"upgraded"===t||"installed"===t,version_after:null,...e};return["up_to_date","unavailable","not_installed"].includes(t)||f(`app-upgrade:${r}`,"failed"===t?"fail":"ok",{duration_ms:Date.now()-a,detail:{result:t,current:o.current,latest:o.latest,...e.reason?{reason:e.reason}:{}}}),n};if(o.blocker)return!n.quiet&&o.installed&&o.outdated&&q(t.yellow(" ! "+s.t("app_update.outdated",{current:o.current,latest:o.latest}))),n.quiet||q(t.yellow(" ! "+s.t(`app_update.blocked_${o.blocker}`,{tool:l}))),p("unavailable",{reason:o.blocker});if(!o.latest)return n.quiet||q(t.yellow(" ! "+s.t("app_update.latest_unknown",{tool:l,reason:o.error??""}))),p("unavailable",{reason:o.error});if(!o.installed&&!n.install)return p("not_installed");if(o.installed&&!o.outdated)return n.quiet||q(t.green(" √ "+s.t("app_update.already_latest",{tool:l,current:o.current??o.latest}))),p("up_to_date");o.installed&&q(t.yellow(` ! ${l} `+appStatusText(o)));let i=!1;if(o.running){if(!u()||d())return q(t.yellow(" ! "+s.t("app_update.running_hint",{tool:l,command:appUpgradeCommand(r)}))),p("left_running");if(!await async function(t,r=!0){const{ok:n}=await e.prompt([{type:"confirm",name:"ok",message:t,default:r}]);return n}(s.t("app_update.offer_quit",{tool:l,latest:o.latest})))return q(t.gray(" "+s.t("app_update.declined_hint",{command:appUpgradeCommand(r)}))),p("declined");const n=b(r).runningApp;if(!n?.quit?.())return q(t.yellow(" ! "+s.t("app_update.quit_failed",{tool:l,command:appUpgradeCommand(r)}))),p("failed",{reason:"quit_failed"});i=!0}try{const{version:e}=await async function(e){const r=b(e).appInstaller,n=!c()&&Boolean(process.stdout.isTTY);let a=-1;try{return await r.install({downloading:r=>q(t.gray(" "+s.t("app_update.downloading",{tool:b(e).displayName,version:r}))),percent:e=>{!n||e-a<5||(a=e,process.stdout.write(t.gray(`\r ${e}%`)),e>=100&&process.stdout.write("\n"))},verifying:()=>{n&&a>=0&&a<100&&process.stdout.write("\n"),a=100,q(t.gray(" "+s.t("app_update.verifying")))},installing:()=>q(t.gray(" "+s.t("app_update.installing")))})}finally{n&&a>=0&&a<100&&process.stdout.write("\n")}}(r);return q(t.green(" √ "+(o.installed?s.t("app_update.upgraded",{tool:l,from:o.current??"?",to:e}):s.t("app_update.installed",{tool:l,version:e})))),i&&!b(r).runningApp?.launch?.()&&q(t.yellow(" ! "+s.t("setup.reopen_hint",{tool:l}))),p(o.installed?"upgraded":"installed",{version_after:e,current:o.current})}catch(e){const n=e instanceof Error?e.message:String(e);return y.logError(`app-update.install(${r})`,e),q(t.yellow(" ! "+(o.installed?s.t("app_update.upgrade_failed",{tool:l,reason:n,current:o.current??"?",command:appUpgradeCommand(r)}):s.t("app_update.install_failed",{tool:l,reason:n,command:appUpgradeCommand(r)})))),i&&b(r).runningApp?.launch?.(),p("failed",{reason:n})}}
|
package/dist/lib/post-apply.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import o from"chalk";import t from"inquirer";import{i18n as n}from"./i18n.js";import{canPrompt as e,hasExplicitYes as i,shouldAutoConfirm as r}from"./runtime-options.js";import{toolManager as
|
|
1
|
+
import o from"chalk";import t from"inquirer";import{i18n as n}from"./i18n.js";import{canPrompt as e,hasExplicitYes as i,shouldAutoConfirm as r}from"./runtime-options.js";import{toolManager as s}from"./tool-manager.js";import{getAdapter as a}from"./tools/registry.js";import{upgradeTool as l}from"./tool-upgrade.js";import{upgradeApp as p}from"./app-update.js";import{logger as f}from"../utils/logger.js";async function c(o){const{ok:n}=await t.prompt([{type:"confirm",name:"ok",message:o,default:!0}]);return n}export async function runPendingElevations(t){const i=e();for(const e of t){const t=a(e)?.pendingElevation?.();if(!t)continue;if(!(r()||i&&await c(t.prompt)))continue;const s=a(e)?.displayName??e;console.log(o.gray(" "+n.t("setup.elevation_running"))),console.log(t.run()?o.green(" √ "+n.t("setup.elevation_done",{tool:s})):o.yellow(" ! "+n.t("setup.elevation_failed",{tool:s})))}}export async function postApplyPrompts(t,r={}){const u=new Set;for(const o of t)if(r.apps&&a(o)?.appInstaller)try{const t=await p(o,{install:r.apps.install,quiet:!0});t.upgraded&&t.running&&u.add(o)}catch(t){f.logError(`postApplyPrompts.upgradeApp(${o})`,t)}for(const n of t){const t=await(a(n)?.prepareRuntime?.())??[];for(const n of t)console.log("action"===n.kind?o.yellow(" ! "+n.text):o.green(" √ "+n.text))}await runPendingElevations(t);const m=e();for(const n of t){let t;try{t=await(a(n)?.followUp?.())}catch(o){f.logError(`postApplyPrompts.followUp(${n})`,o);continue}if(t)if("run"in t&&(i()||m))if(i()||await c(t.prompt))for(const n of await t.run())console.log("action"===n.kind?o.yellow(" ! "+n.text):o.green(" √ "+n.text));else t.decline();else console.log(o.yellow(" ! "+t.hint))}const g=i(),d=m||g?t.filter(o=>a(o)?.installSpec&&s.outdatedVersion(o)):[];if(d.length>0){const o=d.map(o=>a(o)?.displayName??o).join("、");if(g||await c(n.t("setup.offer_upgrade",{tools:o})))for(const o of d)await l(o)}for(const e of t){const t=a(e);if(u.has(e)||!t?.runningApp?.isRunning())continue;if(g||!m){console.log(o.yellow(" ! "+n.t("setup.reopen_hint",{tool:t.displayName})));continue}if(!await c(n.t("setup.offer_restart",{tool:t.displayName})))continue;const i=t.runningApp.restart();console.log(i?o.green(" √ "+n.t("setup.restarted",{tool:t.displayName})):o.yellow(" ! "+n.t("setup.restart_failed",{tool:t.displayName})))}}
|
package/dist/lib/program.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Command as e,Option as o}from"commander";import{readFileSync as s}from"fs";import{join as t,dirname as n}from"path";import{fileURLToPath as a}from"url";import{i18n as i}from"./i18n.js";import{wizard as r}from"./wizard.js";import{SUPPORTED_TOOLS as c}from"./tool-manager.js";import{DEFAULT_BASE_URL as l}from"./config.js";import{attachCommandHelp as p,helpConfiguration as m}from"./cli-help.js";import{langCommand as u,authCommand as d,doctorCommand as f,configCommand as g,statusCommand as x,refreshCommand as h}from"../commands/index.js";import{logsCommand as y}from"../commands/logs.js";import{completionCommand as $}from"../commands/completion.js";import{benchCommand as b}from"../commands/bench.js";import{updateCommand as k}from"../commands/update.js";import{upgradeCommand as _}from"../commands/upgrade.js";import{codexSessionsCommand as w}from"../commands/codex-sessions.js";import{sessionsExportCommand as v,sessionsListCommand as j,sessionsResumeCommand as O,sessionsShowCommand as S}from"../commands/sessions.js";import{setupCommand as A,DEDICATED_KEYS as E}from"../commands/setup.js";import{baseCommand as G}from"../commands/base.js";import{usageError as z}from"./errors.js";import{requireTerminal as C}from"./confirm.js";import{brand as R,brandEnv as B,CLI_NAME as I}from"./brand.js";const L=(R().gatewayAddresses[1]??R().gatewayAddresses[0]).url,N=(R().gatewayAddresses[2]??R().gatewayAddresses[0]).url;function P(e,o){return i.t(`help.${e}`,o)}function T(e,o){return{command:e,note:P(o)}}function U(e){const o=P(e);return o===`help.${e}`?"":o}function H(e,o=[]){return{when:U(`${e}.when`),prerequisites:U(`${e}.needs`).split("\n").filter(Boolean),alternatives:o.map(([e,o])=>T(e,o))}}function K(e){return e.helpCommand("help [command]",P("help_command"))}export function buildProgram(){const R=new e;R.name(`${I}`).summary(P("root.summary")).description(P("root.description")).configureHelp(m()).allowExcessArguments(!0).optionsGroup(P("group.global_options")).helpOption("-h, --help",P("global.help")).version(function(){try{const e=n(a(import.meta.url));return JSON.parse(s(t(e,"../../package.json"),"utf-8")).version}catch{return"1.0.0"}}(),"-v, --version",P("global.version")).option("--base <url>",P("global.base")).option("--non-interactive",P("global.non_interactive")).option("--json",P("global.json")).option("-y, --yes",P("global.yes")).option("--dry-run",P("global.dry_run")).option("--no-color",P("global.no_color")),R.configureOutput({writeErr:()=>{},outputError:()=>{}}),R.showSuggestionAfterError(),R.exitOverride(e=>{throw e}),R.commandsGroup(P("group.configure"));const U=R.command("setup").summary(P("setup.summary")).description(P("setup.description")).option("--key <key>",P("setup.opt.key"));for(const e of E){const s=new o(`--${e.option} <key>`,P(`setup.opt.${e.option}`));e.hidden&&s.hideHelp(),U.addOption(s)}U.option("--1m",P("setup.opt.one_m")).option("--no-1m",P("setup.opt.no_one_m")).option("--claude-official <on|off>",P("setup.opt.claude_official")).option("--desktop-registry <on|off>",P("setup.opt.desktop_registry")).option("--force",P("setup.opt.force")).option("--install",P("setup.opt.install")).option("--no-install",P("setup.opt.no_install")).option("--all",P("setup.opt.all")).action(async e=>{e.key||E.some(o=>e[o.option])||(e.key=B("SETUP_KEY")?.trim()||void 0,e.fromInstaller=Boolean(e.key));const o=Boolean(e.key||E.some(o=>e[o.option])),s=void 0!==e["1m"]||void 0!==e.claudeOfficial||void 0!==e.desktopRegistry,t=i.t("errors.key_placeholder");if(!o&&!s)throw z(i.t("setup.usage"),`${I} setup --key ${t}`,"missing_key");if(void 0!==e.claudeOfficial&&!["on","off"].includes(String(e.claudeOfficial).toLowerCase()))throw z(i.t("setup.claude_official_invalid",{value:String(e.claudeOfficial)}),`${I} setup --claude-official on|off`,"invalid_value");if(void 0!==e.desktopRegistry&&!["on","off"].includes(String(e.desktopRegistry).toLowerCase()))throw z(i.t("setup.desktop_registry_invalid",{value:String(e.desktopRegistry)}),`${I} setup --desktop-registry on|off`,"invalid_value");await A({key:e.key,...Object.fromEntries(E.map(o=>[o.option,e[o.option]])),all:e.all,oneMillion:e["1m"],claudeOfficial:e.claudeOfficial,desktopRegistry:e.desktopRegistry,force:e.force,install:e.install,fromInstaller:e.fromInstaller})}),p(U,{...H("setup",[[`${I} init`,"setup.alt.init"],[`${I} config <tool>`,"setup.alt.config"],[`${I} auth <key>`,"setup.alt.auth"]]),sections:[{title:P("setup.autodetect_title"),rows:[["Claude",P("setup.autodetect.claude")],["GPT",P("setup.autodetect.gpt")],["Grok",P("setup.autodetect.grok")],["Gemini",P("setup.autodetect.gemini")]]}],examples:[T(`${I} setup --key sk-xxx`,"setup.ex.key"),T(`${I} setup --install --key sk-xxx`,"setup.ex.install"),T(`${I} setup --claudekey sk-a --codexkey sk-b --agykey sk-g`,"setup.ex.split"),T(`${I} setup --force --key sk-xxx`,"setup.ex.force"),T(`${I} setup --base ${L} --key sk-xxx`,"setup.ex.base")]});const M=R.command("init").summary(P("init.summary")).description(P("init.description")).action(async()=>{C(),await r.runFirstTimeSetup()});p(M,{...H("init",[[`${I} setup --key <key>`,"init.alt.setup"],[`${I}`,"init.alt.menu"]]),examples:[T(`${I} init`,"init.ex.run"),T(`${I} init --base ${L}`,"init.ex.base"),T(`${I}`,"init.ex.menu")]});const q=R.command("auth").summary(P("auth.summary")).description(P("auth.description")).argument("[token]",P("auth.arg.token")).action(async e=>{const o=[];e&&o.push(e),await d(o)});K(q);const D=q.command("revoke").description(P("auth.revoke")).action(async()=>{await d(["revoke"])});p(D,{examples:[T(`${I} auth revoke`,"auth.ex.revoke_ask"),T(`${I} auth revoke --yes`,"auth.ex.revoke")]});const F=q.command("reload <tool>").description(P("auth.reload")).action(async e=>{await d(["reload",e])});p(F,{examples:[T(`${I} auth reload claude-code`,"auth.ex.reload"),T(`${I} auth reload claude-code --json`,"auth.ex.reload_json")]}),p(q,{...H("auth",[[`${I} setup --key <key>`,"auth.alt.setup"]]),examples:[T(`${I} auth`,"auth.ex.prompt"),T(`${I} auth sk-xxx --non-interactive`,"auth.ex.save"),T(`${I} auth revoke --yes`,"auth.ex.revoke"),T(`${I} auth reload claude-code`,"auth.ex.reload")]});const J=R.command("config").summary(P("config.summary")).description(P("config.description")).argument("[args...]",P("config.arg.args")).option("-f, --force",P("config.opt.force")).allowUnknownOption(!0).action(async(e=[],o={})=>{await g(o.force?[...e,"--force"]:e)});p(J,{...H("config",[[`${I} setup --force --key <key>`,"config.alt.setup"],[`${I} status`,"config.alt.status"]]),sections:[{title:P("config.subcommands_title"),rows:[["<tool>",P("config.sub.tool")],["<tool> --force",P("config.sub.tool_force")],["<tool> --non-interactive",P("config.sub.tool_non_interactive")],["<tool> remove",P("config.sub.tool_remove")],["<tool> restore",P("config.sub.tool_restore")],["<tool> backups",P("config.sub.tool_backups")],["<tool> clear-model",P("config.sub.tool_clear_model")],["tool-model list",P("config.sub.tool_model_list")],["tool-model set <tool> [slot] <model>",P("config.sub.tool_model_set")],["tool-model clear <tool>",P("config.sub.tool_model_clear")],["profile list",P("config.sub.profile_list")],["profile create <name>",P("config.sub.profile_create")],["profile use <name>",P("config.sub.profile_use")],["profile delete <name>",P("config.sub.profile_delete")],["preset list",P("config.sub.preset_list")],["preset save <name>",P("config.sub.preset_save")],["preset use <name>",P("config.sub.preset_use")],["preset delete <name>",P("config.sub.preset_delete")],["backup list",P("config.sub.backup_list")],["backup create [label]",P("config.sub.backup_create")],["backup restore <name>",P("config.sub.backup_restore")]]},{title:P("config.tools_title"),rows:Object.values(c).filter(e=>!e.hidden).map(e=>[e.name,e.displayName])}],examples:[T(`${I} config codex`,"config.ex.menu"),T(`${I} config claude-code --force`,"config.ex.force"),T(`${I} config tool-model set codex gpt-6-astra`,"config.ex.tool_model"),T(`${I} config profile create work`,"config.ex.profile"),T(`${I} config codex remove`,"config.ex.remove")]});const Y=R.command("base").summary(P("base.summary")).description(P("base.description")).argument("[target]",P("base.arg.target")).action(async e=>{await G(e)});p(Y,{...H("base",[[`${I} doctor`,"base.alt.doctor"],[`${I} bench`,"base.alt.bench"]]),sections:[{title:P("base.targets_title"),rows:[[P("base.target.none_term"),P("base.target.none")],[P("base.target.index_term"),P("base.target.index")],[P("base.target.url_term"),P("base.target.url")],["auto",P("base.target.auto")],["default",P("base.target.default",{url:l})]]}],examples:[T(`${I} base`,"base.ex.list"),T(`${I} base auto`,"base.ex.auto"),T(`${I} base 2`,"base.ex.index"),T(`${I} base ${L}`,"base.ex.url"),T(`${I} base default`,"base.ex.default")]}),R.commandsGroup(P("group.diagnose"));const Q=R.command("status").summary(P("status.summary")).description(P("status.description")).action(async()=>{await x()});p(Q,{...H("status",[[`${I} doctor`,"status.alt.doctor"]]),examples:[T(`${I} status`,"status.ex.show"),T(`${I} status --json`,"status.ex.json")]});const V=R.command("doctor").summary(P("doctor.summary")).description(P("doctor.description")).option("--deep",P("doctor.opt.deep")).option("--report",P("doctor.opt.report")).action(async e=>{await f({deep:e.deep,report:e.report})});p(V,{...H("doctor",[[`${I} base auto`,"doctor.alt.base"],[`${I} logs tail`,"doctor.alt.logs"]]),examples:[T(`${I} doctor`,"doctor.ex.run"),T(`${I} doctor --deep`,"doctor.ex.deep"),T(`${I} doctor --report`,"doctor.ex.report")]});const W=R.command("bench").summary(P("bench.summary")).description(P("bench.description")).option("--samples <n>",P("bench.opt.samples"),"5").option("--stream",P("bench.opt.stream")).option("--model <model>",P("bench.opt.model")).action(async e=>{const o=[];e.samples&&o.push("--samples",e.samples),e.stream&&o.push("--stream"),e.model&&o.push("--model",e.model),await b(o)});p(W,{...H("bench",[[`${I} base`,"bench.alt.base"]]),examples:[T(`${I} bench`,"bench.ex.run"),T(`${I} bench --samples 3`,"bench.ex.samples"),T(`${I} bench --stream`,"bench.ex.stream"),T(`${I} bench --stream --model gpt-6-astra`,"bench.ex.stream_model"),T(`${I} bench --json`,"bench.ex.json")]});const X=R.command("logs").summary(P("logs.summary")).description(P("logs.description")).argument("[action]",P("logs.arg.action")).argument("[file]",P("logs.arg.file")).action(async(e,o)=>{const s=[];e&&s.push(e),o&&s.push(o),await y(s)});p(X,{...H("logs",[[`${I} doctor`,"logs.alt.doctor"]]),sections:[{title:P("logs.actions_title"),rows:[["list",P("logs.action.list")],["tail [file]",P("logs.action.tail")],["path",P("logs.action.path")]]}],examples:[T(`${I} logs`,"logs.ex.list"),T(`${I} logs tail`,"logs.ex.tail"),T(`${I} logs path`,"logs.ex.path")]}),R.commandsGroup(P("group.maintain"));const Z=R.command("upgrade").summary(P("upgrade.summary")).description(P("upgrade.description")).argument("[tools...]",P("upgrade.arg.tools")).action(async(e=[])=>{await _(e)});p(Z,{...H("upgrade",[[`${I} update`,"upgrade.alt.update"]]),examples:[T(`${I} upgrade`,"upgrade.ex.all"),T(`${I} upgrade claude-code`,"upgrade.ex.one"),T(`${I} upgrade codex agy`,"upgrade.ex.many")]});const ee=R.command("refresh").summary(P("refresh.summary")).description(P("refresh.description")).action(async()=>{await h()});p(ee,{...H("refresh",[[`${I} setup --key ${i.t("errors.key_placeholder")}`,"refresh.alt.setup"]]),examples:[T(`${I} refresh`,"refresh.ex.run"),T(`${I} refresh --base ${N}`,"refresh.ex.base")]});const oe=R.command("update").summary(P("update.summary")).description(P("update.description")).action(async()=>{await k()});p(oe,{...H("update",[[`${I} upgrade`,"update.alt.upgrade"]]),examples:[T(`${I} update`,"update.ex.check"),T(`${I} update --json`,"update.ex.json")]});const se=R.command("codex").summary(P("codex.summary")).description(P("codex.description"));K(se);const te=se.command("sessions").summary(P("codex_sessions.summary")).description(P("codex_sessions.description")).option("--to <provider>",P("codex_sessions.opt.to")).option("--undo <dir>",P("codex_sessions.opt.undo")).action(async e=>{await w(e)});p(se,{...H("codex"),examples:[T(`${I} codex sessions`,"codex_sessions.ex.move"),T(`${I} codex sessions --undo <dir>`,"codex_sessions.ex.undo")]}),p(te,{...H("codex_sessions",[[`${I} codex sessions --undo <dir>`,"codex_sessions.alt.undo"]]),examples:[T(`${I} codex sessions`,"codex_sessions.ex.move"),T(`${I} codex sessions --to custom`,"codex_sessions.ex.to"),T(`${I} codex sessions --undo <dir>`,"codex_sessions.ex.undo")]});const ne=R.command("sessions").summary(P("sessions.summary")).description(P("sessions.description"));K(ne);const ae=ne.command("list",{isDefault:!0}).description(P("sessions.list")).option("--tool <tool>",P("sessions.opt.tool")).option("--dir <path>",P("sessions.opt.dir")).option("--here",P("sessions.opt.here")).option("-n, --limit <count>",P("sessions.opt.limit")).option("--all",P("sessions.opt.all")).action(async e=>{await j(e)}),ie=ne.command("show <id>").description(P("sessions.show")).option("-m, --messages <count>",P("sessions.opt.messages")).action(async(e,o)=>{await S(e,o)}),re=ne.command("resume <id>").description(P("sessions.resume")).option("--run",P("sessions.opt.run")).action(async(e,o)=>{await O(e,o)}),ce=ne.command("export <ids...>").description(P("sessions.export")).option("-o, --output <dir>",P("sessions.opt.output")).option("--tools",P("sessions.opt.tools")).action(async(e,o)=>{await v(e,o)});p(ae,{examples:[T(`${I} sessions list`,"sessions.ex.list"),T(`${I} sessions list --tool codex`,"sessions.ex.codex"),T(`${I} sessions list --here --all`,"sessions.ex.here"),T(`${I} sessions list --json`,"sessions.ex.json")]}),p(ie,{examples:[T(`${I} sessions show 01a0f5fe`,"sessions.ex.show"),T(`${I} sessions show 01a0f5fe -m 20`,"sessions.ex.show_more")]}),p(re,{examples:[T(`${I} sessions resume 01a0f5fe`,"sessions.ex.resume_print"),T(`${I} sessions resume 01a0f5fe --run`,"sessions.ex.resume")]}),p(ce,{examples:[T(`${I} sessions export 01a0f5fe 7c2e9d41 -o ./sessions`,"sessions.ex.export"),T(`${I} sessions export 01a0f5fe -o ./sessions --tools`,"sessions.ex.export_tools")]}),p(ne,{...H("sessions",[[`${I} codex sessions`,"sessions.alt.codex_sessions"]]),examples:[T(`${I} sessions`,"sessions.ex.list"),T(`${I} sessions --tool codex --here`,"sessions.ex.here"),T(`${I} sessions show 01a0f5fe`,"sessions.ex.show"),T(`${I} sessions resume 01a0f5fe --run`,"sessions.ex.resume"),T(`${I} sessions export 01a0f5fe 7c2e9d41 -o ./sessions`,"sessions.ex.export")]});const le=R.command("lang").summary(P("lang.summary")).description(P("lang.description"));K(le);const pe=le.command("show").description(P("lang.show")).action(async()=>{await u(["show"])}),me=le.command("set <locale>").description(P("lang.set")).action(async e=>{await u(["set",e])}),ue=[T(`${I} lang show`,"lang.ex.show"),T(`${I} lang set en_US`,"lang.ex.set_en"),T(`${I} lang set zh_CN`,"lang.ex.set_zh")];p(le,{...H("lang",[[`${I} enter lang`,"lang.alt.enter"]]),examples:ue}),p(pe,{examples:[ue[0],T(`${I} lang show --json`,"lang.ex.show_json")]}),p(me,{examples:ue.slice(1)});const de=R.command("completion").summary(P("completion.summary")).description(P("completion.description")).argument("<shell>",P("completion.arg.shell")).action(async e=>{await $([e])});p(de,{...H("completion"),examples:[T(`${I} completion bash > ~/.${I}-completion.bash`,"completion.ex.bash"),T(`${I} completion zsh > ~/.${I}-completion.zsh`,"completion.ex.zsh"),T(`${I} completion fish > ~/.config/fish/completions/${I}.fish`,"completion.ex.fish")]});const fe=R.command("enter").summary(P("enter.summary")).description(P("enter.description")).argument("[option]",P("enter.arg.option")).action(async e=>{if(e&&!["lang","language","apikey","api-key","models"].includes(e)||C(),e)switch(e){case"lang":case"language":await r.configLanguage();break;case"apikey":case"api-key":await r.configApiKey();break;case"models":await r.configModels();break;default:await g([e])}else await r.run()});p(fe,{...H("enter",[[`${I}`,"enter.alt.menu"],[`${I} config <tool>`,"enter.alt.config"]]),sections:[{title:P("enter.options_title"),rows:[[P("enter.option.none_term"),P("enter.option.none")],["lang",P("enter.option.lang")],["apikey",P("enter.option.apikey")],["models",P("enter.option.models")],["<tool>",P("enter.option.tool")]]}],examples:[T(`${I} enter`,"enter.ex.menu"),T(`${I} enter models`,"enter.ex.models"),T(`${I} enter codex`,"enter.ex.tool")]}),K(R),R.action(async()=>{C(),await r.run()}),p(R,{examples:[T(`${I}`,"root.ex.menu"),T(`${I} setup --key sk-xxx`,"root.ex.setup"),T(`${I} doctor`,"root.ex.doctor"),T(`${I} base auto`,"root.ex.base"),T(`${I} config codex`,"root.ex.config")]});const ge=e=>{for(const o of e.commands)o.helpOption("-h, --help",P("global.help")),ge(o)};return ge(R),R}
|
|
1
|
+
import{Command as e,Option as o}from"commander";import{readFileSync as s}from"fs";import{join as t,dirname as n}from"path";import{fileURLToPath as a}from"url";import{i18n as i}from"./i18n.js";import{wizard as r}from"./wizard.js";import{SUPPORTED_TOOLS as c}from"./tool-manager.js";import{DEFAULT_BASE_URL as l}from"./config.js";import{attachCommandHelp as p,helpConfiguration as m}from"./cli-help.js";import{langCommand as u,authCommand as d,doctorCommand as f,configCommand as g,statusCommand as x,refreshCommand as h}from"../commands/index.js";import{logsCommand as y}from"../commands/logs.js";import{completionCommand as $}from"../commands/completion.js";import{benchCommand as b}from"../commands/bench.js";import{updateCommand as k}from"../commands/update.js";import{upgradeCommand as _}from"../commands/upgrade.js";import{codexSessionsCommand as w}from"../commands/codex-sessions.js";import{sessionsExportCommand as v,sessionsListCommand as j,sessionsResumeCommand as O,sessionsShowCommand as S}from"../commands/sessions.js";import{setupCommand as A,DEDICATED_KEYS as E}from"../commands/setup.js";import{baseCommand as G}from"../commands/base.js";import{usageError as z}from"./errors.js";import{requireTerminal as C}from"./confirm.js";import{brand as R,brandEnv as B,CLI_NAME as I}from"./brand.js";const L=(R().gatewayAddresses[1]??R().gatewayAddresses[0]).url,N=(R().gatewayAddresses[2]??R().gatewayAddresses[0]).url;function P(e,o){return i.t(`help.${e}`,o)}function T(e,o){return{command:e,note:P(o)}}function U(e){const o=P(e);return o===`help.${e}`?"":o}function H(e,o=[]){return{when:U(`${e}.when`),prerequisites:U(`${e}.needs`).split("\n").filter(Boolean),alternatives:o.map(([e,o])=>T(e,o))}}function K(e){return e.helpCommand("help [command]",P("help_command"))}export function buildProgram(){const R=new e;R.name(`${I}`).summary(P("root.summary")).description(P("root.description")).configureHelp(m()).allowExcessArguments(!0).optionsGroup(P("group.global_options")).helpOption("-h, --help",P("global.help")).version(function(){try{const e=n(a(import.meta.url));return JSON.parse(s(t(e,"../../package.json"),"utf-8")).version}catch{return"1.0.0"}}(),"-v, --version",P("global.version")).option("--base <url>",P("global.base")).option("--non-interactive",P("global.non_interactive")).option("--json",P("global.json")).option("-y, --yes",P("global.yes")).option("--dry-run",P("global.dry_run")).option("--no-color",P("global.no_color")),R.configureOutput({writeErr:()=>{},outputError:()=>{}}),R.showSuggestionAfterError(),R.exitOverride(e=>{throw e}),R.commandsGroup(P("group.configure"));const U=R.command("setup").summary(P("setup.summary")).description(P("setup.description")).option("--key <key>",P("setup.opt.key"));for(const e of E){const s=new o(`--${e.option} <key>`,P(`setup.opt.${e.option}`));e.hidden&&s.hideHelp(),U.addOption(s)}U.option("--1m",P("setup.opt.one_m")).option("--no-1m",P("setup.opt.no_one_m")).option("--claude-official <on|off>",P("setup.opt.claude_official")).option("--desktop-registry <on|off>",P("setup.opt.desktop_registry")).option("--force",P("setup.opt.force")).option("--install",P("setup.opt.install")).option("--no-install",P("setup.opt.no_install")).option("--all",P("setup.opt.all")).action(async e=>{e.key||E.some(o=>e[o.option])||(e.key=B("SETUP_KEY")?.trim()||void 0,e.fromInstaller=Boolean(e.key));const o=Boolean(e.key||E.some(o=>e[o.option])),s=void 0!==e["1m"]||void 0!==e.claudeOfficial||void 0!==e.desktopRegistry,t=i.t("errors.key_placeholder");if(!o&&!s)throw z(i.t("setup.usage"),`${I} setup --key ${t}`,"missing_key");if(void 0!==e.claudeOfficial&&!["on","off"].includes(String(e.claudeOfficial).toLowerCase()))throw z(i.t("setup.claude_official_invalid",{value:String(e.claudeOfficial)}),`${I} setup --claude-official on|off`,"invalid_value");if(void 0!==e.desktopRegistry&&!["on","off"].includes(String(e.desktopRegistry).toLowerCase()))throw z(i.t("setup.desktop_registry_invalid",{value:String(e.desktopRegistry)}),`${I} setup --desktop-registry on|off`,"invalid_value");await A({key:e.key,...Object.fromEntries(E.map(o=>[o.option,e[o.option]])),all:e.all,oneMillion:e["1m"],claudeOfficial:e.claudeOfficial,desktopRegistry:e.desktopRegistry,force:e.force,install:e.install,fromInstaller:e.fromInstaller})}),p(U,{...H("setup",[[`${I} init`,"setup.alt.init"],[`${I} config <tool>`,"setup.alt.config"],[`${I} auth <key>`,"setup.alt.auth"]]),sections:[{title:P("setup.autodetect_title"),rows:[["Claude",P("setup.autodetect.claude")],["GPT",P("setup.autodetect.gpt")],["Grok",P("setup.autodetect.grok")],["Gemini",P("setup.autodetect.gemini")]]}],examples:[T(`${I} setup --key sk-xxx`,"setup.ex.key"),T(`${I} setup --install --key sk-xxx`,"setup.ex.install"),T(`${I} setup --claudekey sk-a --codexkey sk-b --agykey sk-g`,"setup.ex.split"),T(`${I} setup --force --key sk-xxx`,"setup.ex.force"),T(`${I} setup --base ${L} --key sk-xxx`,"setup.ex.base")]});const M=R.command("init").summary(P("init.summary")).description(P("init.description")).action(async()=>{C(),await r.runFirstTimeSetup()});p(M,{...H("init",[[`${I} setup --key <key>`,"init.alt.setup"],[`${I}`,"init.alt.menu"]]),examples:[T(`${I} init`,"init.ex.run"),T(`${I} init --base ${L}`,"init.ex.base"),T(`${I}`,"init.ex.menu")]});const q=R.command("auth").summary(P("auth.summary")).description(P("auth.description")).argument("[token]",P("auth.arg.token")).action(async e=>{const o=[];e&&o.push(e),await d(o)});K(q);const D=q.command("revoke").description(P("auth.revoke")).action(async()=>{await d(["revoke"])});p(D,{examples:[T(`${I} auth revoke`,"auth.ex.revoke_ask"),T(`${I} auth revoke --yes`,"auth.ex.revoke")]});const F=q.command("reload <tool>").description(P("auth.reload")).action(async e=>{await d(["reload",e])});p(F,{examples:[T(`${I} auth reload claude-code`,"auth.ex.reload"),T(`${I} auth reload claude-code --json`,"auth.ex.reload_json")]}),p(q,{...H("auth",[[`${I} setup --key <key>`,"auth.alt.setup"]]),examples:[T(`${I} auth`,"auth.ex.prompt"),T(`${I} auth sk-xxx --non-interactive`,"auth.ex.save"),T(`${I} auth revoke --yes`,"auth.ex.revoke"),T(`${I} auth reload claude-code`,"auth.ex.reload")]});const J=R.command("config").summary(P("config.summary")).description(P("config.description")).argument("[args...]",P("config.arg.args")).option("-f, --force",P("config.opt.force")).allowUnknownOption(!0).action(async(e=[],o={})=>{await g(o.force?[...e,"--force"]:e)});p(J,{...H("config",[[`${I} setup --force --key <key>`,"config.alt.setup"],[`${I} status`,"config.alt.status"]]),sections:[{title:P("config.subcommands_title"),rows:[["<tool>",P("config.sub.tool")],["<tool> --force",P("config.sub.tool_force")],["<tool> --non-interactive",P("config.sub.tool_non_interactive")],["<tool> remove",P("config.sub.tool_remove")],["<tool> restore",P("config.sub.tool_restore")],["<tool> backups",P("config.sub.tool_backups")],["<tool> clear-model",P("config.sub.tool_clear_model")],["tool-model list",P("config.sub.tool_model_list")],["tool-model set <tool> [slot] <model>",P("config.sub.tool_model_set")],["tool-model clear <tool>",P("config.sub.tool_model_clear")],["profile list",P("config.sub.profile_list")],["profile create <name>",P("config.sub.profile_create")],["profile use <name>",P("config.sub.profile_use")],["profile delete <name>",P("config.sub.profile_delete")],["preset list",P("config.sub.preset_list")],["preset save <name>",P("config.sub.preset_save")],["preset use <name>",P("config.sub.preset_use")],["preset delete <name>",P("config.sub.preset_delete")],["backup list",P("config.sub.backup_list")],["backup create [label]",P("config.sub.backup_create")],["backup restore <name>",P("config.sub.backup_restore")]]},{title:P("config.tools_title"),rows:Object.values(c).filter(e=>!e.hidden).map(e=>[e.name,e.displayName])}],examples:[T(`${I} config codex`,"config.ex.menu"),T(`${I} config claude-code --force`,"config.ex.force"),T(`${I} config tool-model set codex gpt-6-astra`,"config.ex.tool_model"),T(`${I} config profile create work`,"config.ex.profile"),T(`${I} config codex remove`,"config.ex.remove")]});const Y=R.command("base").summary(P("base.summary")).description(P("base.description")).argument("[target]",P("base.arg.target")).action(async e=>{await G(e)});p(Y,{...H("base",[[`${I} doctor`,"base.alt.doctor"],[`${I} bench`,"base.alt.bench"]]),sections:[{title:P("base.targets_title"),rows:[[P("base.target.none_term"),P("base.target.none")],[P("base.target.index_term"),P("base.target.index")],[P("base.target.url_term"),P("base.target.url")],["auto",P("base.target.auto")],["default",P("base.target.default",{url:l})]]}],examples:[T(`${I} base`,"base.ex.list"),T(`${I} base auto`,"base.ex.auto"),T(`${I} base 2`,"base.ex.index"),T(`${I} base ${L}`,"base.ex.url"),T(`${I} base default`,"base.ex.default")]}),R.commandsGroup(P("group.diagnose"));const Q=R.command("status").summary(P("status.summary")).description(P("status.description")).action(async()=>{await x()});p(Q,{...H("status",[[`${I} doctor`,"status.alt.doctor"]]),examples:[T(`${I} status`,"status.ex.show"),T(`${I} status --json`,"status.ex.json")]});const V=R.command("doctor").summary(P("doctor.summary")).description(P("doctor.description")).option("--deep",P("doctor.opt.deep")).option("--report",P("doctor.opt.report")).action(async e=>{await f({deep:e.deep,report:e.report})});p(V,{...H("doctor",[[`${I} base auto`,"doctor.alt.base"],[`${I} logs tail`,"doctor.alt.logs"]]),examples:[T(`${I} doctor`,"doctor.ex.run"),T(`${I} doctor --deep`,"doctor.ex.deep"),T(`${I} doctor --report`,"doctor.ex.report")]});const W=R.command("bench").summary(P("bench.summary")).description(P("bench.description")).option("--samples <n>",P("bench.opt.samples"),"5").option("--stream",P("bench.opt.stream")).option("--model <model>",P("bench.opt.model")).action(async e=>{const o=[];e.samples&&o.push("--samples",e.samples),e.stream&&o.push("--stream"),e.model&&o.push("--model",e.model),await b(o)});p(W,{...H("bench",[[`${I} base`,"bench.alt.base"]]),examples:[T(`${I} bench`,"bench.ex.run"),T(`${I} bench --samples 3`,"bench.ex.samples"),T(`${I} bench --stream`,"bench.ex.stream"),T(`${I} bench --stream --model gpt-6-astra`,"bench.ex.stream_model"),T(`${I} bench --json`,"bench.ex.json")]});const X=R.command("logs").summary(P("logs.summary")).description(P("logs.description")).argument("[action]",P("logs.arg.action")).argument("[file]",P("logs.arg.file")).action(async(e,o)=>{const s=[];e&&s.push(e),o&&s.push(o),await y(s)});p(X,{...H("logs",[[`${I} doctor`,"logs.alt.doctor"]]),sections:[{title:P("logs.actions_title"),rows:[["list",P("logs.action.list")],["tail [file]",P("logs.action.tail")],["path",P("logs.action.path")]]}],examples:[T(`${I} logs`,"logs.ex.list"),T(`${I} logs tail`,"logs.ex.tail"),T(`${I} logs path`,"logs.ex.path")]}),R.commandsGroup(P("group.maintain"));const Z=R.command("upgrade").summary(P("upgrade.summary")).description(P("upgrade.description")).argument("[tools...]",P("upgrade.arg.tools")).action(async(e=[])=>{await _(e)});p(Z,{...H("upgrade",[[`${I} update`,"upgrade.alt.update"]]),examples:[T(`${I} upgrade`,"upgrade.ex.all"),T(`${I} upgrade claude-code`,"upgrade.ex.one"),T(`${I} upgrade codex agy`,"upgrade.ex.many"),T(`${I} upgrade claude-desktop`,"upgrade.ex.desktop")]});const ee=R.command("refresh").summary(P("refresh.summary")).description(P("refresh.description")).action(async()=>{await h()});p(ee,{...H("refresh",[[`${I} setup --key ${i.t("errors.key_placeholder")}`,"refresh.alt.setup"]]),examples:[T(`${I} refresh`,"refresh.ex.run"),T(`${I} refresh --base ${N}`,"refresh.ex.base")]});const oe=R.command("update").summary(P("update.summary")).description(P("update.description")).action(async()=>{await k()});p(oe,{...H("update",[[`${I} upgrade`,"update.alt.upgrade"]]),examples:[T(`${I} update`,"update.ex.check"),T(`${I} update --json`,"update.ex.json")]});const se=R.command("codex").summary(P("codex.summary")).description(P("codex.description"));K(se);const te=se.command("sessions").summary(P("codex_sessions.summary")).description(P("codex_sessions.description")).option("--to <provider>",P("codex_sessions.opt.to")).option("--undo <dir>",P("codex_sessions.opt.undo")).action(async e=>{await w(e)});p(se,{...H("codex"),examples:[T(`${I} codex sessions`,"codex_sessions.ex.move"),T(`${I} codex sessions --undo <dir>`,"codex_sessions.ex.undo")]}),p(te,{...H("codex_sessions",[[`${I} codex sessions --undo <dir>`,"codex_sessions.alt.undo"]]),examples:[T(`${I} codex sessions`,"codex_sessions.ex.move"),T(`${I} codex sessions --to custom`,"codex_sessions.ex.to"),T(`${I} codex sessions --undo <dir>`,"codex_sessions.ex.undo")]});const ne=R.command("sessions").summary(P("sessions.summary")).description(P("sessions.description"));K(ne);const ae=ne.command("list",{isDefault:!0}).description(P("sessions.list")).option("--tool <tool>",P("sessions.opt.tool")).option("--dir <path>",P("sessions.opt.dir")).option("--here",P("sessions.opt.here")).option("-n, --limit <count>",P("sessions.opt.limit")).option("--all",P("sessions.opt.all")).action(async e=>{await j(e)}),ie=ne.command("show <id>").description(P("sessions.show")).option("-m, --messages <count>",P("sessions.opt.messages")).action(async(e,o)=>{await S(e,o)}),re=ne.command("resume <id>").description(P("sessions.resume")).option("--run",P("sessions.opt.run")).action(async(e,o)=>{await O(e,o)}),ce=ne.command("export <ids...>").description(P("sessions.export")).option("-o, --output <dir>",P("sessions.opt.output")).option("--tools",P("sessions.opt.tools")).action(async(e,o)=>{await v(e,o)});p(ae,{examples:[T(`${I} sessions list`,"sessions.ex.list"),T(`${I} sessions list --tool codex`,"sessions.ex.codex"),T(`${I} sessions list --here --all`,"sessions.ex.here"),T(`${I} sessions list --json`,"sessions.ex.json")]}),p(ie,{examples:[T(`${I} sessions show 01a0f5fe`,"sessions.ex.show"),T(`${I} sessions show 01a0f5fe -m 20`,"sessions.ex.show_more")]}),p(re,{examples:[T(`${I} sessions resume 01a0f5fe`,"sessions.ex.resume_print"),T(`${I} sessions resume 01a0f5fe --run`,"sessions.ex.resume")]}),p(ce,{examples:[T(`${I} sessions export 01a0f5fe 7c2e9d41 -o ./sessions`,"sessions.ex.export"),T(`${I} sessions export 01a0f5fe -o ./sessions --tools`,"sessions.ex.export_tools")]}),p(ne,{...H("sessions",[[`${I} codex sessions`,"sessions.alt.codex_sessions"]]),examples:[T(`${I} sessions`,"sessions.ex.list"),T(`${I} sessions --tool codex --here`,"sessions.ex.here"),T(`${I} sessions show 01a0f5fe`,"sessions.ex.show"),T(`${I} sessions resume 01a0f5fe --run`,"sessions.ex.resume"),T(`${I} sessions export 01a0f5fe 7c2e9d41 -o ./sessions`,"sessions.ex.export")]});const le=R.command("lang").summary(P("lang.summary")).description(P("lang.description"));K(le);const pe=le.command("show").description(P("lang.show")).action(async()=>{await u(["show"])}),me=le.command("set <locale>").description(P("lang.set")).action(async e=>{await u(["set",e])}),ue=[T(`${I} lang show`,"lang.ex.show"),T(`${I} lang set en_US`,"lang.ex.set_en"),T(`${I} lang set zh_CN`,"lang.ex.set_zh")];p(le,{...H("lang",[[`${I} enter lang`,"lang.alt.enter"]]),examples:ue}),p(pe,{examples:[ue[0],T(`${I} lang show --json`,"lang.ex.show_json")]}),p(me,{examples:ue.slice(1)});const de=R.command("completion").summary(P("completion.summary")).description(P("completion.description")).argument("<shell>",P("completion.arg.shell")).action(async e=>{await $([e])});p(de,{...H("completion"),examples:[T(`${I} completion bash > ~/.${I}-completion.bash`,"completion.ex.bash"),T(`${I} completion zsh > ~/.${I}-completion.zsh`,"completion.ex.zsh"),T(`${I} completion fish > ~/.config/fish/completions/${I}.fish`,"completion.ex.fish")]});const fe=R.command("enter").summary(P("enter.summary")).description(P("enter.description")).argument("[option]",P("enter.arg.option")).action(async e=>{if(e&&!["lang","language","apikey","api-key","models"].includes(e)||C(),e)switch(e){case"lang":case"language":await r.configLanguage();break;case"apikey":case"api-key":await r.configApiKey();break;case"models":await r.configModels();break;default:await g([e])}else await r.run()});p(fe,{...H("enter",[[`${I}`,"enter.alt.menu"],[`${I} config <tool>`,"enter.alt.config"]]),sections:[{title:P("enter.options_title"),rows:[[P("enter.option.none_term"),P("enter.option.none")],["lang",P("enter.option.lang")],["apikey",P("enter.option.apikey")],["models",P("enter.option.models")],["<tool>",P("enter.option.tool")]]}],examples:[T(`${I} enter`,"enter.ex.menu"),T(`${I} enter models`,"enter.ex.models"),T(`${I} enter codex`,"enter.ex.tool")]}),K(R),R.action(async()=>{C(),await r.run()}),p(R,{examples:[T(`${I}`,"root.ex.menu"),T(`${I} setup --key sk-xxx`,"root.ex.setup"),T(`${I} doctor`,"root.ex.doctor"),T(`${I} base auto`,"root.ex.base"),T(`${I} config codex`,"root.ex.config")]});const ge=e=>{for(const o of e.commands)o.helpOption("-h, --help",P("global.help")),ge(o)};return ge(R),R}
|
package/dist/lib/tool-manager.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{execSync as o,spawnSync as t}from"child_process";import{i18n as n}from"./i18n.js";import e from"inquirer";import r from"chalk";import{canPrompt as i,shouldAutoConfirm as l}from"./runtime-options.js";import{logger as s}from"../utils/logger.js";import{configManager as a}from"./config.js";import{getAdapter as c,listAdapters as d,TOOL_ADAPTERS as p}from"./tools/registry.js";import{backupBeforeWrite as u,listBackups as m,restoreBackup as f}from"./tools/backup.js";import{existsSync as g,rmSync as h}from"fs";import{dirname as w,join as y}from"path";import{toolHome as P}from"./tools/types.js";import{stringWidth as $}from"../utils/string-width.js";import{resolveModelCatalog as T}from"./model-catalog.js";import{compareVersions as
|
|
1
|
+
import{execSync as o,spawnSync as t}from"child_process";import{i18n as n}from"./i18n.js";import e from"inquirer";import r from"chalk";import{canPrompt as i,shouldAutoConfirm as l}from"./runtime-options.js";import{logger as s}from"../utils/logger.js";import{configManager as a}from"./config.js";import{getAdapter as c,listAdapters as d,TOOL_ADAPTERS as p}from"./tools/registry.js";import{backupBeforeWrite as u,listBackups as m,restoreBackup as f}from"./tools/backup.js";import{existsSync as g,rmSync as h}from"fs";import{dirname as w,join as y}from"path";import{toolHome as P}from"./tools/types.js";import{stringWidth as $}from"../utils/string-width.js";import{resolveModelCatalog as T}from"./model-catalog.js";import{compareVersions as v,getToolMinVersion as C}from"./model-registry.js";import{findInstalls as k,forgetInstalls as E,installLabel as O,mirrorInstallCommand as _,npmMirrorInstallCommand as S,npmMirrorVersion as N}from"./tools/tool-installs.js";import{mirrorInstall as j}from"./tool-upgrade.js";import{upgradeApp as M}from"./app-update.js";import{CLI_NAME as U}from"./brand.js";import{track as b,trackStep as x}from"./telemetry.js";import{addUserPathDir as I,broadcastEnvChange as R}from"./windows-env.js";export{v as compareVersions};function F(o){const t=p[o];return{name:t.name,command:t.command,installCommand:t.installCommand,configPath:t.configPath,displayName:t.displayName,...t.hidden?{hidden:!0}:{},...t.isInstalled?{gui:!0}:{}}}function L(){const o=new Set;for(const t of a.listProfiles()){const n=a.getProfile(t);for(const t of[n.api_key,...Object.values(n.tool_api_keys??{})])t?.trim()&&o.add(t.trim())}return[...o]}export const SUPPORTED_TOOLS=Object.fromEntries(Object.keys(p).map(o=>[o,F(o)]));export class ToolManager{static instance;constructor(){}static getInstance(){return ToolManager.instance||(ToolManager.instance=new ToolManager),ToolManager.instance}isToolInstalled(o){if(!SUPPORTED_TOOLS[o])return!1;const t=c(o);if(t?.isInstalled)try{return t.isInstalled()}catch{return!1}return this.isOnPath(o)||null!==this.nativeLauncher(o)}isOnPath(t){const n=SUPPORTED_TOOLS[t];if(!n)return!1;try{const t="win32"===process.platform?`where ${n.command}`:`which ${n.command}`;return o(t,{stdio:"pipe"}),!0}catch{return!1}}nativeLauncher(o){const t=c(o),n=t?.installSpec?.native?.binDir;if(!t||!n)return null;const e="win32"===process.platform?`${t.command}.exe`:t.command,r=y(P(),...n,e);return g(r)?r:null}ensureNativeOnPath(o){if("win32"!==process.platform||this.isOnPath(o))return null;const t=this.nativeLauncher(o);if(!t)return null;const n=w(t);try{if(!I(n))return null}catch(t){return s.logError(`ensureNativeOnPath: ${o}`,t),null}return R(),process.env.Path=`${process.env.Path??""};${n}`,n}async installTool(o){return x(`install:${o}`,()=>this.installToolNow(o))}async installToolNow(t){const s=SUPPORTED_TOOLS[t];if(!s)throw new Error(`Unknown tool: ${t}`);const a=c(t)?.appInstaller;if(a&&!a.blocker()){const o=await M(t,{install:!0});if("failed"===o.result||"unavailable"===o.result)throw new Error(`Failed to install ${s.displayName}`);return}const d=c(t)?.installSpec;if(d&&(d.mirrorScript||d.npmPackage)){const o=_(d);if(await j(d)&&(E(),this.isToolInstalled(t)))return void console.log(r.green("√ "+n.t("wizard.tool_installed")));throw console.log(r.red("× "+n.t("wizard.install_failed"))),console.log(r.yellow(" ! "+n.t("install.manual_command",{tool:s.displayName,command:o}))),d.mirrorScript&&d.npmPackage&&console.log(r.yellow(" ! "+n.t("install.manual_npm",{command:S(d,await N(d))}))),new Error(`Failed to install ${s.displayName}`)}const p=s.installCommand;console.log(r.gray("$ ")+r.white(p));try{return o(p,{stdio:"inherit"}),E(),void console.log(r.green("√ "+n.t("wizard.tool_installed")))}catch(o){if(console.log(r.red("× "+n.t("wizard.install_failed"))),!/EACCES|EPERM|permission denied/i.test(`${o?.message??""}${o?.stderr??""}`)&&243!==o?.status&&!p.startsWith("npm "))throw new Error(`Failed to install ${s.displayName}: ${o}`);console.log(r.yellow(" ! "+("win32"===process.platform?n.t("install.permission_windows",{command:p}):n.t("install.permission_unix",{command:p}))))}const{action:u}=!i()||l()?{action:"continue"}:await e.prompt([{type:"list",name:"action",message:n.t("install.what_next"),choices:[{name:n.t("install.installed_continue"),value:"continue"},{name:n.t("install.cancel_install"),value:"cancel"}]}]);if("cancel"===u)throw new Error(n.t("install.user_cancelled"));if(E(),!this.isToolInstalled(t))throw console.log(r.red("× "+n.t("install.still_not_installed",{tool:s.displayName}))),new Error(`${s.displayName} is not installed`);console.log(r.green("√ "+n.t("install.verified_success",{tool:s.displayName})))}getToolConfig(o){const t=c(o);if(!t)throw new Error(`Unknown tool: ${o}`);try{return t.getConfig()}catch(t){return s.warn(`Failed to read config for ${o}:`,t),s.logError(`ToolManager.getToolConfig(${o})`,t),null}}updateToolConfig(o,t){const n=c(o);if(!n)throw new Error(`Unknown tool: ${o}`);if(!n.updateConfig)throw new Error(`Tool ${o} does not support raw config updates`);n.updateConfig(t)}forceResetConfig(o){const t=c(o);if(!t)throw new Error(`Unknown tool: ${o}`);const n=t.forceResetPaths?t.forceResetPaths():this.backupPathsFor(t),e=[];for(const o of n)g(o)&&(u(o),h(o,{force:!0}),e.push(o));return e}loadPrivateConfig(o,t,n,e,r={}){const i=c(o);if(!i)throw new Error(`Unknown tool: ${o}`);r.force&&this.forceResetConfig(o),i.loadPrivateConfig({apiKey:t,baseUrl:a.getBaseUrl(),models:n,settings:a.getToolSettings(o),...e?{catalog:e}:{}})}async applyPrivateConfig(o,t,n,e={}){const r=this.installedVersion(o);return x(`apply:${o}`,()=>this.applyPrivateConfigNow(o,t,n,e),{...r?{tool_version:r}:{},...e.force?{force:!0}:{}})}async applyPrivateConfigNow(o,t,n,e){const r=c(o);if(!r)throw new Error(`Unknown tool: ${o}`);const i=r.wantsModelCatalog?await T(t):null;e.force?this.loadPrivateConfig(o,t,n,i??void 0,{force:!0}):i?this.loadPrivateConfig(o,t,n,i):this.loadPrivateConfig(o,t,n)}applyNotes(o){const t=c(o);if(!t)return[];const e=[];try{t.applyNotes&&e.push(...t.applyNotes())}catch(t){s.logError(`ToolManager.applyNotes(${o})`,t)}const r=this.outdatedVersion(o);if(r){e.push({kind:"action",text:n.t("tools.version_outdated",{current:r.current,min:r.min,upgrade:t.installSpec?`${U} upgrade ${o}`:t.upgradeCommand||t.installCommand})});for(const o of t.upgradeHints?.(r.min)??[])e.push({kind:"action",text:o})}const i=t.installSpec?k(t.installSpec):[];return i.length>1&&e.push({kind:"action",text:n.t("upgrade.duplicates_note",{count:String(i.length),active:O(i[0]),others:i.slice(1).map(O).join("、"),tool:o})}),e}printApplied(o,t=16){const n=SUPPORTED_TOOLS[o]?.displayName??o,e=this.applyNotes(o);for(const o of e.filter(o=>"detail"===o.kind))s.record(`${n}: ${o.text}`);const i=e.filter(o=>"summary"===o.kind).map(o=>o.text).join(";"),l=" ".repeat(Math.max(1,t-$(n)));console.log(r.green("√ "+n)+(i?l+i:""));for(const o of e.filter(o=>"action"===o.kind))console.log(r.yellow(" ! "+o.text))}installedVersion(o){const n=c(o);if(!n)return null;if(n.installSpec)return k(n.installSpec)[0]?.version??null;if(n.installedVersion)try{return n.installedVersion()}catch(t){return s.logError(`ToolManager.installedVersion(${o})`,t),null}if(n.isInstalled)return null;try{const o={encoding:"utf-8",timeout:1e4,windowsHide:!0,stdio:["ignore","pipe","pipe"]},e=`${("win32"===process.platform?t(`${n.command} --version`,{...o,shell:!0}):t(n.command,["--version"],o)).stdout??""}`.match(/(\d+)\.(\d+)\.(\d+)/);return e?e[0]:null}catch{return null}}outdatedVersion(o){const t=C(o);if(!t)return null;const n=this.installedVersion(o);return n&&v(n,t)<0?{current:n,min:t}:null}unloadPrivateConfig(o){const t=c(o);if(!t)throw new Error(`Unknown tool: ${o}`);try{t.unloadPrivateConfig({savedKeys:L()}),b(`remove:${o}`,"ok")}catch(t){throw b(`remove:${o}`,"fail",{error:t}),t}let e=[];try{e=t.unloadNotes?.()??[]}catch(t){s.logError(`ToolManager.unloadNotes(${o})`,t)}return e.length>0?e:[{kind:"action",text:n.t("config.reopen_hint",{tool:t.displayName})}]}async clearPinnedModels(o){const t=c(o);if(!t)throw new Error(`Unknown tool: ${o}`);if(a.setToolModel(o,null),!t.clearPinnedModels)return[];const n=a.getApiKeyForTool(o),e=t.wantsModelCatalog&&n?await T(n):null;return t.clearPinnedModels(e??void 0)}supportsClearPinnedModels(o){return Boolean(c(o)?.clearPinnedModels)}holdsOurConfig(o){const t=c(o);if(!t)return!1;const n=L();return t.holdsOurConfig?t.holdsOurConfig(n):Boolean(t.detectCurrentConfig().apiKey)}detectCurrentConfig(o){const t=c(o);if(!t)throw new Error(`Unknown tool: ${o}`);return t.detectCurrentConfig()}backupPathsFor(o){return o.backupPaths?o.backupPaths():[o.configPath]}listToolBackups(o){const t=c(o);if(!t)throw new Error(`Unknown tool: ${o}`);return this.backupPathsFor(t).map(o=>({file:o,backups:m(o)}))}restorePrivateConfig(o){const t=c(o);if(!t)throw new Error(`Unknown tool: ${o}`);return this.backupPathsFor(t).map(o=>({file:o,result:f(o)}))}getInstalledTools(){return Object.keys(SUPPORTED_TOOLS).filter(o=>this.isToolInstalled(o))}getSupportedTools(){return d().filter(o=>!o.hidden).map(o=>F(o.name))}isGitInstalled(){try{const t="win32"===process.platform?"where git":"which git";return o(t,{stdio:"pipe"}),!0}catch{return!1}}}export const toolManager=ToolManager.getInstance();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{spawnSync as t}from"child_process";import{createHash as e}from"crypto";import{accessSync as o,constants as r,createReadStream as s,createWriteStream as n,existsSync as a,mkdirSync as i,mkdtempSync as c,readFileSync as p,renameSync as u,rmSync as l}from"fs";import{tmpdir as d}from"os";import{dirname as f,join as m}from"path";import{Readable as g,Transform as h}from"stream";import{pipeline as w}from"stream/promises";import{logger as k}from"../../utils/logger.js";import{brand as $}from"../brand.js";import{i18n as A}from"../i18n.js";import{WINDOWS_PACKAGE_FAMILIES as x}from"./desktop-process.js";import{toolHome as y}from"./types.js";export const ANTHROPIC_TEAM_ID="Q6L2SF6YDW";const S=/(^|,\s*)O="?Anthropic, PBC"?(,|$)/;let v=(e,o,r={})=>{const s=t(e,o,{encoding:"utf-8",timeout:r.timeout??12e4,windowsHide:!0,input:r.input,stdio:[void 0===r.input?"ignore":"pipe","pipe","pipe"],maxBuffer:16777216});return s.error&&k.logError(`claude-desktop-app: ${e}`,s.error),{status:s.status,stdout:`${s.stdout??""}`,stderr:`${s.stderr??""}`}},C=(...t)=>fetch(...t),E=null;export function setDesktopAppDepsForTests(t){void 0!==t.run&&(v=t.run??v),void 0!==t.fetch&&(C=t.fetch??((...t)=>fetch(...t))),void 0!==t.platform&&(E=t.platform)}function P(){return E??process.platform}export function desktopMirrorRepo(){return $().installMirror?.claudeDesktop?.replace(/\/-\/releases\/latest\/?$/,"")??null}export function desktopAssetName(){return"darwin"===P()?"Claude-mac-universal.dmg":"win32"===P()?"arm64"===process.arch||"ARM64"===process.env.PROCESSOR_ARCHITECTURE||"ARM64"===process.env.PROCESSOR_ARCHITEW6432?"Claude-win-arm64.msix":"Claude-win-x64.msix":null}export function desktopInstallBlocker(){return desktopAssetName()?desktopMirrorRepo()?"win32"===P()&&function(){const t=process.env.LOCALAPPDATA||m(y(),"AppData","Local");return a(m(t,"AnthropicClaude","Update.exe"))}()?"classic_install":null:"no_mirror":"unsupported_platform"}async function _(t,e){const o=await C(t,{signal:AbortSignal.timeout(e)});if(!o.ok)throw new Error(`${t}: HTTP ${o.status}`);return(await o.text()).trim()}export async function fetchLatestDesktopVersion(t=8e3){const e=desktopMirrorRepo();if(!e)throw new Error("no mirror");const o=await _(`${e}/-/releases/latest/download/version.txt`,t);if(!/^\d+\.\d+\.\d+$/.test(o))throw new Error(`unexpected version.txt: ${o.slice(0,40)}`);return o}export function parseSha256Sums(t){const e=new Map;for(const o of t.split(/\r?\n/)){const t=/^([0-9a-f]{64})\s+\*?(\S.*)$/i.exec(o.trim());t&&e.set(t[2].trim(),t[1].toLowerCase())}return e}export class DesktopInstallError extends Error{constructor(t){super(t),this.name="DesktopInstallError"}}const b=(t,e={})=>{throw new DesktopInstallError(A.t(`app_update.error_${t}`,e))};export function verifyMacApp(t){const e=v("codesign",["--verify","--deep","--strict",t],{timeout:6e5});0!==e.status&&b("signature",{reason:(e.stderr||e.stdout).trim().split("\n")[0]||`codesign ${e.status}`});const o=v("codesign",["-dv",t]),r=`${o.stdout}\n${o.stderr}`,s=/^TeamIdentifier=(\S+)/m.exec(r)?.[1],n=/^Identifier=(\S+)/m.exec(r)?.[1];"Q6L2SF6YDW"===s&&"com.anthropic.claudefordesktop"===n||b("signature",{reason:`TeamIdentifier=${s??"?"} Identifier=${n??"?"}`});const a=v("spctl",["-a","-t","exec","-vv",t],{timeout:3e5});0!==a.status&&b("signature",{reason:(a.stderr||a.stdout).trim().split("\n")[0]||`spctl ${a.status}`})}function I(t){try{return o(t,r.W_OK),!0}catch{return!1}}export function installedMacApp(){for(const t of["/Applications/Claude.app",m(y(),"Applications","Claude.app")])if(a(m(t,"Contents","Info.plist")))return t;return null}const M=t=>`'${t.replace(/'/g,"''")}'`;function T(t,e=12e4){return v("powershell.exe",["-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-Command",t],{timeout:e})}export function verifyWindowsPackage(t){const e=T(`$s = Get-AuthenticodeSignature -LiteralPath ${M(t)}; [pscustomobject]@{ status = [string]$s.Status; subject = [string]$s.SignerCertificate.Subject } | ConvertTo-Json -Compress`);let o={};try{o=JSON.parse(e.stdout.trim()||"{}")}catch{}"Valid"===o.status&&S.test(o.subject??"")||b("signature",{reason:`${o.status??e.stderr.trim().split("\n")[0]??"?"} ${o.subject??""}`.trim()})}export async function installLatestDesktop(t={}){const o=desktopInstallBlocker();o&&b("blocked",{reason:A.t(`app_update.reason_${o}`)});const r=desktopMirrorRepo(),$=desktopAssetName();let S;try{S=await fetchLatestDesktopVersion(15e3)}catch(t){b("download",{reason:t instanceof Error?t.message:String(t)})}const E=`${r}/-/releases/download/v${S}`;let D;try{D=parseSha256Sums(await _(`${E}/SHA256SUMS`,15e3)).get($)}catch(t){k.logError("claude-desktop-app: SHA256SUMS",t)}D||b("no_checksum",{file:$});const R=c(m(d(),"claude-desktop-"));try{const o=m(R,$);t.downloading?.(S),await async function(t,e,o){let r;try{r=await C(t,{signal:AbortSignal.timeout(18e5)})}catch(t){b("download",{reason:t instanceof Error?t.message:String(t)})}r.ok&&r.body||b("download",{reason:`HTTP ${r.status}`});const s=Number(r.headers.get("content-length"))||0;let a=0,i=-1;const c=new h({transform(t,e,r){a+=t.length;const n=s?Math.floor(100*a/s):-1;n>=0&&n!==i&&(i=n,o?.(n)),r(null,t)}});try{await w(g.fromWeb(r.body),c,n(e))}catch(t){l(e,{force:!0}),b("download",{reason:t instanceof Error?t.message:String(t)})}}(`${E}/${$}`,o,t.percent),t.verifying?.();const r=await async function(t){const o=e("sha256");for await(const e of s(t))o.update(e);return o.digest("hex")}(o);return r!==D&&b("checksum",{file:$,expected:D.slice(0,12),actual:r.slice(0,12)}),t.installing?.(),"darwin"===P()?await async function(t,e){const o=m(e,"mnt");i(o,{recursive:!0});const r=v("hdiutil",["attach","-nobrowse","-readonly","-noautoopen","-mountpoint",o,t],{timeout:3e5,input:"Y\n"});0!==r.status&&b("mount",{reason:(r.stderr||r.stdout).trim().split("\n").pop()??""});let s=null;try{const t=m(o,"Claude.app");a(t)||b("bad_package",{reason:"Claude.app"});const e=installedMacApp();let r=e;if(!r){const t=m(y(),"Applications"),e=I("/Applications")?"/Applications":t;i(e,{recursive:!0}),r=m(e,"Claude.app")}const n=f(r);(!I(n)||e&&!I(e))&&b("no_permission",{path:r}),s=m(n,`.Claude.app.${process.pid}.new`),l(s,{recursive:!0,force:!0});const c=v("ditto",[t,s],{timeout:9e5});0!==c.status&&b("copy",{reason:(c.stderr||c.stdout).trim().split("\n")[0]??""}),verifyMacApp(s);const d=function(t){try{const e=p(m(t,"Contents","Info.plist"),"utf-8");return/<key>CFBundleShortVersionString<\/key>\s*<string>(\d+\.\d+\.\d+)[^<]*<\/string>/.exec(e)?.[1]??null}catch{return null}}(s);d||b("bad_package",{reason:"Info.plist"});const g=m(n,`.Claude.app.${process.pid}.old`);e&&u(e,g);try{u(s,r)}catch(t){throw e&&u(g,e),t}return s=null,l(g,{recursive:!0,force:!0}),{version:d,location:r}}finally{s&&l(s,{recursive:!0,force:!0}),v("hdiutil",["detach",o,"-force"],{timeout:6e4})}}(o,R):function(t){verifyWindowsPackage(t);const e=T(`$ErrorActionPreference = 'Stop'; Add-AppxPackage -Path ${M(t)}`,9e5);0!==e.status&&b("install",{reason:(e.stderr||e.stdout).trim().split(/\r?\n/).filter(Boolean)[0]??`Add-AppxPackage ${e.status}`});const o=function(){const t=T(`Get-AppxPackage | Where-Object { @(${x.map(M).join(",")}) -contains $_.PackageFamilyName } | ForEach-Object { $_.Version.ToString() }`,3e4);return/\d+\.\d+\.\d+/.exec(t.stdout)?.[0]??null}();return o||b("install",{reason:"Get-AppxPackage"}),{version:o,location:"MSIX"}}(o)}finally{l(R,{recursive:!0,force:!0})}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{chmodSync as e,existsSync as t,mkdirSync as o,readdirSync as n,readFileSync as r,rmSync as s}from"fs";import{dirname as i}from"path";import{join as l}from"path";import{randomUUID as a}from"crypto";import{execFileSync as c}from"child_process";import{userInfo as d}from"os";import p from"chalk";import{logger as u}from"../../utils/logger.js";import{track as f}from"../telemetry.js";import{ensureDesktopCli as m,installedDesktopAsarPath as g}from"./claude-desktop-cli.js";import{i18n as y}from"../i18n.js";import{BRAND_NAME as h,brand as k,brandEnv as _,CLI_NAME as D}from"../brand.js";import{backupBeforeWrite as b,atomicWriteFile as A}from"./backup.js";import{toolHome as C}from"./types.js";import{canRestartDesktop as w,isDesktopRunning as E,restartDesktop as v,WINDOWS_PACKAGE_FAMILIES as M}from"./desktop-process.js";import{setUserRegistryElevated as O}from"./elevated-reg.js";import{UserActionNeeded as S}from"./types.js";import{baseModelId as x,isClaudeModel as j}from"../model-catalog.js";import{getDefaultModels as P}from"../model-registry.js";import{claudeFormat as L,nestedClaudeProjectFiles as T}from"../sessions/formats.js";const I=h;export const CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING="hide_official_login";export const CLAUDE_DESKTOP_FORCE_REGISTRY_SETTING="force_registry";const $=/^[a-f0-9-]{36}$/;function N(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}export function claudeDesktopUserDataDir(){const e=process.env.CLAUDE_USER_DATA_DIR?.trim();if(e)return e;const o=C(),n=Boolean(_("TEST_HOME")?.trim());switch(process.platform){case"darwin":return l(o,"Library","Application Support","Claude-3p");case"win32":{const e=!n&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:l(o,"AppData","Local");return M.map(t=>l(e,"Packages",t,"LocalCache","Local","Claude-3p")).find(e=>t(e))??l(e,"Claude-3p")}default:{const e=!n&&process.env.XDG_CONFIG_HOME?process.env.XDG_CONFIG_HOME:l(o,".config");return l(e,"Claude-3p")}}}const R=()=>l(claudeDesktopUserDataDir(),"configLibrary"),G=()=>l(R(),"_meta.json"),K=e=>l(R(),`${e}.json`),U=()=>l(claudeDesktopUserDataDir(),"claude_desktop_config.json");function F(e){if(!t(e))return null;const o=r(e,"utf-8");if(!o.trim())return null;try{const e=JSON.parse(o);return N(e)?e:null}catch(t){throw new Error(`Existing ${e} cannot be parsed; back it up and fix it first: ${t instanceof Error?t.message:String(t)}`)}}function H(n,r){const s=i(n);t(s)||o(s,{recursive:!0,mode:448}),b(n),A(n,JSON.stringify(r,null,2)+"\n");try{e(n,384)}catch(e){u.logError("claude-desktop.writeJson.chmod",e)}}function J(){const e=F(G());if(!e)return null;const t=Array.isArray(e.entries)?e.entries.filter(e=>N(e)&&"string"==typeof e.id&&"string"==typeof e.name):[];return{...e,appliedId:"string"==typeof e.appliedId?e.appliedId:"",entries:t}}function B(e){return e?.entries.find(e=>e.name===I&&$.test(e.id))}const V={opus:0,fable:1,sonnet:2,haiku:3};function W(e){let t=/^claude-(opus|sonnet|haiku|fable)-(\d+(?:-\d+)*)/i.exec(e);return t?{family:t[1].toLowerCase(),version:t[2].split("-").map(Number)}:(t=/^claude-(\d+(?:-\d+)*)-(opus|sonnet|haiku)/i.exec(e),t?{family:t[2].toLowerCase(),version:t[1].split("-").map(Number)}:null)}export function humanizeModelId(e){const t=W(e);return t?`${t.family[0].toUpperCase()+t.family.slice(1)} ${t.version.filter(e=>e<1e7).slice(0,2).join(".")}`:e}function z(e){return W(e)?.family}export function buildInferenceModels(e,t){const{primary:o,bySlot:n}=function(e){const t=["opus","sonnet","haiku","reasoning"].map(t=>x(e[t]||"")).filter(Boolean);return{primary:t[0]??"",bySlot:t}}(e),r=new Set,s=t?.labels??{};let i;if(t&&t.models.some(j)){i=[...new Set(t.models.filter(j).map(x))];for(const e of t.oneMillion)r.add(e)}else{i=[];for(const t of["opus","sonnet","haiku","reasoning"]){const o=(e[t]||"").trim(),n=x(o);n&&(i.includes(n)||i.push(n),/\[1m\]/i.test(o)&&r.add(n))}}const l=e=>V[z(e)??""]??9;i.sort((e,t)=>{if(e===o)return-1;if(t===o)return 1;const n=l(e)-l(t);if(0!==n)return n;const r=W(e),s=W(t);return r&&s?function(e,t){const o=Math.max(e.length,t.length);for(let n=0;n<o;n++){const o=(t[n]??0)-(e[n]??0);if(0!==o)return o}return 0}(r.version,s.version):e.localeCompare(t)});const a=new Set,c=new Map,d=new Set(Object.values(P()).map(e=>x(e||"")));for(const e of n){const t=z(e);t&&i.includes(e)&&!d.has(e)&&!c.has(t)&&c.set(t,e)}return i.map(e=>{const t=z(e),o={name:e,labelOverride:s[e]||humanizeModelId(e)};if(r.has(e)&&(o.supports1m=!0,o.prefer1m=!0),t){o.anthropicFamilyTier=t;const n=c.get(t);n&&n!==e||a.has(t)||(o.isFamilyDefault=!0,a.add(t))}return o})}let Z=null,q=null,X=null,Y=null,Q=null;function ee(e){return{inferenceProvider:"gateway",inferenceCredentialKind:"static",inferenceGatewayBaseUrl:(e.baseUrl||"").trim().replace(/\/+$/,""),inferenceGatewayApiKey:e.apiKey,inferenceModels:buildInferenceModels(e.models,e.catalog),disableDeploymentModeChooser:!1!==e.settings?.hide_official_login,chatTabEnabled:!0,chatAdvancedFileAnalysisEnabled:!0,autoModeEnabled:!0,coworkEgressAllowedHosts:["*"],disableEssentialTelemetry:!0,disableNonessentialTelemetry:!0,disableNonessentialServices:!1}}const te={defaultModelEffort:"medium",modelPrefer1mContext:!0,skipWebFetchPreflight:!0,toolSearchEnabled:!0,builtinBrowserEnabled:!0,isDesktopExtensionEnabled:!0,sshHostAllowlist:["*"],claudeAiImport:{enabled:!0,automatic3pImport:!0,exportEnabled:!0},coworkVmIpv6Enabled:!0,mcpToolTimeoutSec:3600,updateViaUpdatesHost:!0,banner:{enabled:!1}},oe=()=>{if(_("TEST_HOME")?.trim())return null;const e=g();return e?r(e):null};let ne=oe,re=null;export function setDesktopAsarForTests(e){ne=void 0===e?oe:()=>e,re=null}function se(){if(re)return re;let e=null;try{e=ne()}catch(e){u.logError("claude-desktop.unsupportedDefaults",e)}return re=new Set(e?Object.keys(te).filter(t=>!e.includes(t)):[]),re}function ie(e){const t=se();return Object.fromEntries(Object.entries(te).filter(([o])=>!e(o)&&!t.has(o)))}function le(e){const t={...ie(t=>t in e),...e};for(const e of se())e in t&&JSON.stringify(t[e])===JSON.stringify(te[e])&&delete t[e];return t}const ae="SOFTWARE\\Policies\\Claude",ce=`HKCU\\${ae}`,de="HKLM\\SOFTWARE\\Policies\\Claude",pe=`${D}-claude-policy.reg`,ue=e=>c("reg",e,{stdio:["ignore","pipe","pipe"]}).toString();let fe=ue;export function setRegRunnerForTests(e){fe=e??ue}function me(){return"win32"===process.platform}function ge(e){let t;try{t=fe(["query",e])}catch{return null}const o=new Map;for(const e of t.split(/\r?\n/)){const t=/^\s{2,}(\S+)\s+(REG_[A-Z_]+)\s*(.*)$/.exec(e);t&&o.set(t[1],t[3])}return o}function ye(){if(null===ge(ce))return;const e=l(claudeDesktopUserDataDir(),pe);try{t(i(e))||o(i(e),{recursive:!0,mode:448}),b(e),fe(["export",ce,e,"/y"])}catch(e){u.logError("claude-desktop.snapshotPolicy",e)}}function he(e){ye();for(const[t,o]of Object.entries(e)){const[e,n]="boolean"==typeof o?["REG_DWORD",o?"1":"0"]:"number"==typeof o?["REG_DWORD",String(o)]:"string"==typeof o?["REG_SZ",o]:["REG_SZ",JSON.stringify(o)];fe(["add",ce,"/v",t,"/t",e,"/d",n,"/f"])}}function ke(e){const t=ge(ce);if(!t)return;ye();let o=t.size;for(const n of e)t.has(n)&&(fe(["delete",ce,"/v",n,"/f"]),o-=1);o<=0&&fe(["delete",ce,"/f"])}function _e(){const e=!Boolean(_("TEST_HOME")?.trim())&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:l(C(),"AppData","Local");return!!t(l(e,"AnthropicClaude"))||M.some(o=>t(l(e,"Packages",o,"LocalCache","Local","Claude-3p")))}const De=[...Object.keys(ee({apiKey:"",baseUrl:"",models:{haiku:"",sonnet:"",opus:"",reasoning:""}})),...Object.keys(te)];export function detectManagedConfig(){try{if("darwin"===process.platform){let e="";try{e=d().username}catch{}return[e?`/Library/Managed Preferences/${e}/com.anthropic.claudefordesktop.plist`:"","/Library/Managed Preferences/com.anthropic.claudefordesktop.plist"].filter(Boolean).find(e=>t(e))??null}if("win32"===process.platform)return ge(de)?de:null;const e="/etc/claude-desktop/managed-settings.json";return t(e)?e:null}catch(e){return u.logError("claude-desktop.detectManagedConfig",e),null}}function be(){const e=C();let o;switch(process.platform){case"darwin":o=["/Applications/Claude.app",l(e,"Applications","Claude.app")];break;case"win32":{const t=process.env.LOCALAPPDATA||l(e,"AppData","Local");o=[l(t,"AnthropicClaude"),l(t,"Programs","Claude"),...M.map(e=>l(t,"Packages",e))];break}default:o=["/usr/lib/claude-desktop","/opt/Claude","/usr/bin/claude-desktop",l(e,".local","bin","claude-desktop")]}return o.push(claudeDesktopUserDataDir(),l(claudeDesktopUserDataDir(),"..","Claude")),o.some(e=>t(e))}const Ae=/\d+\.\d+\.\d+/;function Ce(e){const t=e=>e.split(".").map(Number);return e.sort((e,o)=>{const[n,r]=[t(e),t(o)];for(let e=0;e<3;e++)if(n[e]!==r[e])return r[e]-n[e];return 0})[0]??null}function we(){if("darwin"===process.platform){for(const e of["/Applications/Claude.app",l(C(),"Applications","Claude.app")]){const o=l(e,"Contents","Info.plist");if(!t(o))continue;const n=/<key>CFBundleShortVersionString<\/key>\s*<string>([^<]+)<\/string>/.exec(r(o,"utf-8")),s=n?Ae.exec(n[1])?.[0]:void 0;if(s)return s}return null}if("win32"===process.platform){const e=l(process.env.LOCALAPPDATA||l(C(),"AppData","Local"),"AnthropicClaude");if(t(e)){const t=n(e).map(e=>/^app-(\d+\.\d+\.\d+)$/.exec(e)?.[1]).filter(e=>!!e);if(t.length>0)return Ce(t)}const o=M.map(e=>`'${e}'`).join(",");return Ce(c("powershell.exe",["-NoProfile","-Command",`Get-AppxPackage | Where-Object { @(${o}) -contains $_.PackageFamilyName } | ForEach-Object { $_.Version.ToString() }`],{encoding:"utf-8",timeout:15e3,windowsHide:!0,stdio:["ignore","pipe","ignore"]}).split(/\r?\n/).flatMap(e=>Ae.exec(e)?.[0]??[]))}if("linux"===process.platform)try{const e=c("dpkg-query",["-W","-f=${Version}","claude-desktop"],{encoding:"utf-8",timeout:5e3,stdio:["ignore","pipe","ignore"]});return Ae.exec(e)?.[0]??null}catch{return null}return null}const Ee="darwin"===process.platform?"open -a Claude":"win32"===process.platform?"Claude":"claude-desktop",ve="darwin"!==process.platform&&"win32"!==process.platform||!k().installMirror?.claudeDesktop?"https://claude.ai/download":k().installMirror.claudeDesktop,Me="darwin"===process.platform?`open ${ve}`:"win32"===process.platform?`start ${ve}`:`xdg-open ${ve}`;export const claudeDesktopAdapter={name:"claude-desktop",displayName:"Claude Desktop",command:Ee,installCommand:Me,configPath:G(),sessions:{format:L,files:()=>T(l(claudeDesktopUserDataDir(),"local-agent-mode-sessions"))},isInstalled:be,installedVersion:we,prepareRuntime:async function(){if(!["win32","darwin","linux"].includes(process.platform)||!be())return[];const e=Date.now();try{const t=await m({userDataDir:claudeDesktopUserDataDir(),onDownload:e=>console.log(p.gray(" "+y.t("tools.claude_desktop.code_cli_downloading",{version:e}))),desktopVersion:"darwin"===process.platform?we():null,mirrorRepo:k().installMirror?.claudeDesktop?.replace(/\/-\/releases\/latest\/?$/,"")??null});return f("desktop-code-cli","skipped"===t.status?"skip":"ok",{duration_ms:Date.now()-e,detail:{...t}}),"installed"!==t.status?[]:[{kind:"summary",text:y.t("tools.claude_desktop.code_cli_installed",{version:t.version})}]}catch(t){return u.logError("claude-desktop.prepareCodeTabCli",t),f("desktop-code-cli","fail",{duration_ms:Date.now()-e,error:t}),[{kind:"action",text:y.t("tools.claude_desktop.code_cli_failed",{reason:t instanceof Error?t.message:String(t)})}]}},runningApp:w()?{isRunning:E,restart:v}:void 0,wantsModelCatalog:!0,loadPrivateConfig(e){const t=J()??{appliedId:"",entries:[]};let o=B(t);o||(o={id:a(),name:I},t.entries.push(o));const n=ee(e);q=!0===n.disableDeploymentModeChooser,Z={models:n.inferenceModels,source:e.catalog?e.catalog.oneMillionSource:"slots",groups:e.catalog?.matchedGroups??[]};const r=F(K(o.id))??{};H(K(o.id),{...le(r),...n}),t.appliedId=o.id,H(G(),t);const s=F(U())??{};if("3p"!==s.deploymentMode&&H(U(),{...s,deploymentMode:"3p"}),Y=null,Q=null,X=null,me()){const t=ge(ce),o=De.filter(e=>t?.has(e)),r={...ie(e=>t?.has(e)??!1),...n},s=!0===e.settings?.force_registry,i=!s&&_e();try{i?ke(De):he(r),X=i?"removed":"written"}catch(e){u.logError("claude-desktop.policy",e),Y=e instanceof Error?e.message.trim():String(e),(o.length>0||s)&&(Q=i?{action:"remove",values:Object.fromEntries(o.map(e=>[e,null])),deleteKey:o.length===t.size}:{action:"write",values:r,deleteKey:!1})}}},pendingElevation(){const e=Q;return e?{prompt:y.t(`tools.claude_desktop.elevate_${e.action}`),run:()=>{if(!O(ae,e.values,e.deleteKey))return!1;const t=ge(ce),o="remove"===e.action?Object.keys(e.values).every(e=>!t?.has(e)):Object.keys(e.values).every(e=>t?.has(e));return o&&(Q=null,Y=null),o}}:null},unloadPrivateConfig(){if(me())try{ke(De)}catch(e){u.logError("claude-desktop.removePolicy",e)}const e=J(),t=B(e);if(!e||!t)return;b(K(t.id)),s(K(t.id),{force:!0});const o=e.entries.filter(e=>e.id!==t.id);0===o.length?(b(G()),s(G(),{force:!0})):H(G(),{...e,entries:o,appliedId:e.appliedId===t.id?o[0].id:e.appliedId})},listedModels(){const e=J(),t=B(e);if(!t||e?.appliedId!==t.id)return null;const o=F(K(t.id))?.inferenceModels;return Array.isArray(o)?o.map(e=>String(e.name)):null},refreshModelMenu(e){const t=J(),o=B(t);if(!o||t?.appliedId!==o.id)return;const n=F(K(o.id));if(!n)return;const r=buildInferenceModels(e.models,e.catalog),s=JSON.stringify(n.inferenceModels)!==JSON.stringify(r),i={...le(n),inferenceModels:r},l=JSON.stringify(i)!==JSON.stringify(n);Q=null;const a=me()?ge(ce):null;if(!a?.has("inferenceModels"))return void(l&&H(K(o.id),i));const c=De.filter(e=>a.has(e)),d=!0!==e.settings?.force_registry&&_e();if(l&&H(K(o.id),i),d||s)try{d?ke(De):he({inferenceModels:r})}catch(e){throw u.logError("claude-desktop.refreshModelMenu registry",e),Q=d?{action:"remove",values:Object.fromEntries(c.map(e=>[e,null])),deleteKey:c.length===a.size}:{action:"write",values:{inferenceModels:r},deleteKey:!1},new S(y.t("tools.claude_desktop.refresh_needs_admin"))}},detectCurrentConfig(){try{if(me()){const e=ge(ce)?.get("inferenceGatewayApiKey");if(e)return{apiKey:e}}const e=B(J());if(!e)return{apiKey:null};const t=F(K(e.id)),o=t?.inferenceGatewayApiKey;return{apiKey:"string"==typeof o&&o?o:null}}catch(e){return u.logError("claude-desktop.detectCurrentConfig",e),{apiKey:null}}},getConfig(){try{const e=J(),t=B(e);return{meta:e,applied:t?F(K(t.id)):null,desktop:F(U()),...me()?{policy:Object.fromEntries(ge(ce)??[])}:{}}}catch(e){return u.logError("claude-desktop.getConfig",e),null}},clearPinnedModels(){let e=!1;me()&&ge(ce)?.has("inferenceModels")&&(ye(),fe(["delete",ce,"/v","inferenceModels","/f"]),e=!0);const t=B(J()),o=t?F(K(t.id)):null;if(t&&o&&void 0!==o.inferenceModels){const{inferenceModels:n,...r}=o;H(K(t.id),r),e=!0}return e?["inferenceModels"]:[]},applyNotes(){const e=[];if(Z&&Z.models.length>0){const{models:t,source:o,groups:n}=Z;e.push({kind:"summary",text:y.t("tools.claude_desktop.models_summary",{count:String(t.length),default:t[0].labelOverride??t[0].name})}),e.push({kind:"detail",text:y.t(`tools.claude_desktop.models_written_${o}`,{count:String(t.length),list:t.map(e=>`${e.labelOverride}${e.supports1m?" (1M)":""}`).join(", "),groups:n.join(" / ")})})}null!==q&&e.push({kind:"detail",text:y.t(q?"tools.claude_desktop.official_login_hidden":"tools.claude_desktop.official_login_shown")}),w()&&!E()||e.push({kind:"action",text:y.t("tools.claude_desktop.restart_hint")}),Q?(e.push({kind:"action",text:y.t(`tools.claude_desktop.policy_stale_${Q.action}`)}),e.push({kind:"detail",text:Y??""})):Y?(e.push({kind:"detail",text:y.t("tools.claude_desktop.registry_denied")}),e.push({kind:"detail",text:Y})):me()&&X&&e.push({kind:"detail",text:y.t(`tools.claude_desktop.registry_${X}`,{key:ce})});const t=detectManagedConfig();return t&&e.push({kind:"action",text:y.t("tools.claude_desktop.managed_conflict",{path:t})}),e},forceResetPaths(){const e=[G(),U()];try{const t=B(J());t&&e.push(K(t.id))}catch{}return e},backupPaths(){const e=[G(),U()];me()&&e.push(l(claudeDesktopUserDataDir(),pe));try{const t=B(J());t&&e.push(K(t.id))}catch{}return e}};
|
|
1
|
+
import{chmodSync as e,existsSync as t,mkdirSync as o,readdirSync as n,readFileSync as r,rmSync as s}from"fs";import{dirname as i}from"path";import{join as l}from"path";import{randomUUID as a}from"crypto";import{execFileSync as c}from"child_process";import{userInfo as d}from"os";import p from"chalk";import{logger as u}from"../../utils/logger.js";import{track as f}from"../telemetry.js";import{ensureDesktopCli as m,installedDesktopAsarPath as g}from"./claude-desktop-cli.js";import{i18n as y}from"../i18n.js";import{BRAND_NAME as h,brand as k,brandEnv as _,CLI_NAME as b}from"../brand.js";import{backupBeforeWrite as D,atomicWriteFile as A}from"./backup.js";import{toolHome as w}from"./types.js";import{canRestartDesktop as C,isDesktopRunning as E,launchDesktop as v,quitDesktop as M,restartDesktop as O,WINDOWS_PACKAGE_FAMILIES as S}from"./desktop-process.js";import{desktopInstallBlocker as x,fetchLatestDesktopVersion as P,installedMacApp as j,installLatestDesktop as I}from"./claude-desktop-app.js";import{setUserRegistryElevated as L}from"./elevated-reg.js";import{UserActionNeeded as T}from"./types.js";import{baseModelId as $,isClaudeModel as N}from"../model-catalog.js";import{getDefaultModels as R}from"../model-registry.js";import{claudeFormat as G,nestedClaudeProjectFiles as K}from"../sessions/formats.js";const U=h;export const CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING="hide_official_login";export const CLAUDE_DESKTOP_FORCE_REGISTRY_SETTING="force_registry";const F=/^[a-f0-9-]{36}$/;function H(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}export function claudeDesktopUserDataDir(){const e=process.env.CLAUDE_USER_DATA_DIR?.trim();if(e)return e;const o=w(),n=Boolean(_("TEST_HOME")?.trim());switch(process.platform){case"darwin":return l(o,"Library","Application Support","Claude-3p");case"win32":{const e=!n&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:l(o,"AppData","Local");return S.map(t=>l(e,"Packages",t,"LocalCache","Local","Claude-3p")).find(e=>t(e))??l(e,"Claude-3p")}default:{const e=!n&&process.env.XDG_CONFIG_HOME?process.env.XDG_CONFIG_HOME:l(o,".config");return l(e,"Claude-3p")}}}const J=()=>l(claudeDesktopUserDataDir(),"configLibrary"),V=()=>l(J(),"_meta.json"),B=e=>l(J(),`${e}.json`),W=()=>l(claudeDesktopUserDataDir(),"claude_desktop_config.json");function z(e){if(!t(e))return null;const o=r(e,"utf-8");if(!o.trim())return null;try{const e=JSON.parse(o);return H(e)?e:null}catch(t){throw new Error(`Existing ${e} cannot be parsed; back it up and fix it first: ${t instanceof Error?t.message:String(t)}`)}}function q(n,r){const s=i(n);t(s)||o(s,{recursive:!0,mode:448}),D(n),A(n,JSON.stringify(r,null,2)+"\n");try{e(n,384)}catch(e){u.logError("claude-desktop.writeJson.chmod",e)}}function X(){const e=z(V());if(!e)return null;const t=Array.isArray(e.entries)?e.entries.filter(e=>H(e)&&"string"==typeof e.id&&"string"==typeof e.name):[];return{...e,appliedId:"string"==typeof e.appliedId?e.appliedId:"",entries:t}}function Z(e){return e?.entries.find(e=>e.name===U&&F.test(e.id))}const Y={opus:0,fable:1,sonnet:2,haiku:3};function Q(e){let t=/^claude-(opus|sonnet|haiku|fable)-(\d+(?:-\d+)*)/i.exec(e);return t?{family:t[1].toLowerCase(),version:t[2].split("-").map(Number)}:(t=/^claude-(\d+(?:-\d+)*)-(opus|sonnet|haiku)/i.exec(e),t?{family:t[2].toLowerCase(),version:t[1].split("-").map(Number)}:null)}export function humanizeModelId(e){const t=Q(e);return t?`${t.family[0].toUpperCase()+t.family.slice(1)} ${t.version.filter(e=>e<1e7).slice(0,2).join(".")}`:e}function ee(e){return Q(e)?.family}export function buildInferenceModels(e,t){const{primary:o,bySlot:n}=function(e){const t=["opus","sonnet","haiku","reasoning"].map(t=>$(e[t]||"")).filter(Boolean);return{primary:t[0]??"",bySlot:t}}(e),r=new Set,s=t?.labels??{};let i;if(t&&t.models.some(N)){i=[...new Set(t.models.filter(N).map($))];for(const e of t.oneMillion)r.add(e)}else{i=[];for(const t of["opus","sonnet","haiku","reasoning"]){const o=(e[t]||"").trim(),n=$(o);n&&(i.includes(n)||i.push(n),/\[1m\]/i.test(o)&&r.add(n))}}const l=e=>Y[ee(e)??""]??9;i.sort((e,t)=>{if(e===o)return-1;if(t===o)return 1;const n=l(e)-l(t);if(0!==n)return n;const r=Q(e),s=Q(t);return r&&s?function(e,t){const o=Math.max(e.length,t.length);for(let n=0;n<o;n++){const o=(t[n]??0)-(e[n]??0);if(0!==o)return o}return 0}(r.version,s.version):e.localeCompare(t)});const a=new Set,c=new Map,d=new Set(Object.values(R()).map(e=>$(e||"")));for(const e of n){const t=ee(e);t&&i.includes(e)&&!d.has(e)&&!c.has(t)&&c.set(t,e)}return i.map(e=>{const t=ee(e),o={name:e,labelOverride:s[e]||humanizeModelId(e)};if(r.has(e)&&(o.supports1m=!0,o.prefer1m=!0),t){o.anthropicFamilyTier=t;const n=c.get(t);n&&n!==e||a.has(t)||(o.isFamilyDefault=!0,a.add(t))}return o})}let te=null,oe=null,ne=null,re=null,se=null;function ie(e){return{inferenceProvider:"gateway",inferenceCredentialKind:"static",inferenceGatewayBaseUrl:(e.baseUrl||"").trim().replace(/\/+$/,""),inferenceGatewayApiKey:e.apiKey,inferenceModels:buildInferenceModels(e.models,e.catalog),disableDeploymentModeChooser:!1!==e.settings?.hide_official_login,chatTabEnabled:!0,chatAdvancedFileAnalysisEnabled:!0,autoModeEnabled:!0,coworkEgressAllowedHosts:["*"],disableEssentialTelemetry:!0,disableNonessentialTelemetry:!0,disableNonessentialServices:!1}}const le={defaultModelEffort:"medium",modelPrefer1mContext:!0,skipWebFetchPreflight:!0,toolSearchEnabled:!0,builtinBrowserEnabled:!0,isDesktopExtensionEnabled:!0,sshHostAllowlist:["*"],claudeAiImport:{enabled:!0,automatic3pImport:!0,exportEnabled:!0},coworkVmIpv6Enabled:!0,mcpToolTimeoutSec:3600,updateViaUpdatesHost:!0,banner:{enabled:!1}},ae=()=>{if(_("TEST_HOME")?.trim())return null;const e=g();return e?r(e):null};let ce=ae,de=null;export function setDesktopAsarForTests(e){ce=void 0===e?ae:()=>e,de=null}function pe(){if(de)return de;let e=null;try{e=ce()}catch(e){u.logError("claude-desktop.unsupportedDefaults",e)}return de=new Set(e?Object.keys(le).filter(t=>!e.includes(t)):[]),de}function ue(e){const t=pe();return Object.fromEntries(Object.entries(le).filter(([o])=>!e(o)&&!t.has(o)))}function fe(e){const t={...ue(t=>t in e),...e};for(const e of pe())e in t&&JSON.stringify(t[e])===JSON.stringify(le[e])&&delete t[e];return t}const me="SOFTWARE\\Policies\\Claude",ge=`HKCU\\${me}`,ye="HKLM\\SOFTWARE\\Policies\\Claude",he=`${b}-claude-policy.reg`,ke=e=>c("reg",e,{stdio:["ignore","pipe","pipe"]}).toString();let _e=ke;export function setRegRunnerForTests(e){_e=e??ke}function be(){return"win32"===process.platform}function De(e){let t;try{t=_e(["query",e])}catch{return null}const o=new Map;for(const e of t.split(/\r?\n/)){const t=/^\s{2,}(\S+)\s+(REG_[A-Z_]+)\s*(.*)$/.exec(e);t&&o.set(t[1],t[3])}return o}function Ae(){if(null===De(ge))return;const e=l(claudeDesktopUserDataDir(),he);try{t(i(e))||o(i(e),{recursive:!0,mode:448}),D(e),_e(["export",ge,e,"/y"])}catch(e){u.logError("claude-desktop.snapshotPolicy",e)}}function we(e){Ae();for(const[t,o]of Object.entries(e)){const[e,n]="boolean"==typeof o?["REG_DWORD",o?"1":"0"]:"number"==typeof o?["REG_DWORD",String(o)]:"string"==typeof o?["REG_SZ",o]:["REG_SZ",JSON.stringify(o)];_e(["add",ge,"/v",t,"/t",e,"/d",n,"/f"])}}function Ce(e){const t=De(ge);if(!t)return;Ae();let o=t.size;for(const n of e)t.has(n)&&(_e(["delete",ge,"/v",n,"/f"]),o-=1);o<=0&&_e(["delete",ge,"/f"])}function Ee(){const e=!Boolean(_("TEST_HOME")?.trim())&&process.env.LOCALAPPDATA?process.env.LOCALAPPDATA:l(w(),"AppData","Local");return!!t(l(e,"AnthropicClaude"))||S.some(o=>t(l(e,"Packages",o,"LocalCache","Local","Claude-3p")))}const ve=[...Object.keys(ie({apiKey:"",baseUrl:"",models:{haiku:"",sonnet:"",opus:"",reasoning:""}})),...Object.keys(le)];export function detectManagedConfig(){try{if("darwin"===process.platform){let e="";try{e=d().username}catch{}return[e?`/Library/Managed Preferences/${e}/com.anthropic.claudefordesktop.plist`:"","/Library/Managed Preferences/com.anthropic.claudefordesktop.plist"].filter(Boolean).find(e=>t(e))??null}if("win32"===process.platform)return De(ye)?ye:null;const e="/etc/claude-desktop/managed-settings.json";return t(e)?e:null}catch(e){return u.logError("claude-desktop.detectManagedConfig",e),null}}function Me(){const e=w();let o;switch(process.platform){case"darwin":o=["/Applications/Claude.app",l(e,"Applications","Claude.app")];break;case"win32":{const t=process.env.LOCALAPPDATA||l(e,"AppData","Local");o=[l(t,"AnthropicClaude"),l(t,"Programs","Claude"),...S.map(e=>l(t,"Packages",e))];break}default:o=["/usr/lib/claude-desktop","/opt/Claude","/usr/bin/claude-desktop",l(e,".local","bin","claude-desktop")]}return o.push(claudeDesktopUserDataDir(),l(claudeDesktopUserDataDir(),"..","Claude")),o.some(e=>t(e))}const Oe=/\d+\.\d+\.\d+/;function Se(e){const t=e=>e.split(".").map(Number);return e.sort((e,o)=>{const[n,r]=[t(e),t(o)];for(let e=0;e<3;e++)if(n[e]!==r[e])return r[e]-n[e];return 0})[0]??null}function xe(){if("darwin"===process.platform){for(const e of["/Applications/Claude.app",l(w(),"Applications","Claude.app")]){const o=l(e,"Contents","Info.plist");if(!t(o))continue;const n=/<key>CFBundleShortVersionString<\/key>\s*<string>([^<]+)<\/string>/.exec(r(o,"utf-8")),s=n?Oe.exec(n[1])?.[0]:void 0;if(s)return s}return null}if("win32"===process.platform){const e=l(process.env.LOCALAPPDATA||l(w(),"AppData","Local"),"AnthropicClaude");if(t(e)){const t=n(e).map(e=>/^app-(\d+\.\d+\.\d+)$/.exec(e)?.[1]).filter(e=>!!e);if(t.length>0)return Se(t)}const o=S.map(e=>`'${e}'`).join(",");return Se(c("powershell.exe",["-NoProfile","-Command",`Get-AppxPackage | Where-Object { @(${o}) -contains $_.PackageFamilyName } | ForEach-Object { $_.Version.ToString() }`],{encoding:"utf-8",timeout:15e3,windowsHide:!0,stdio:["ignore","pipe","ignore"]}).split(/\r?\n/).flatMap(e=>Oe.exec(e)?.[0]??[]))}if("linux"===process.platform)try{const e=c("dpkg-query",["-W","-f=${Version}","claude-desktop"],{encoding:"utf-8",timeout:5e3,stdio:["ignore","pipe","ignore"]});return Oe.exec(e)?.[0]??null}catch{return null}return null}const Pe="darwin"===process.platform?"open -a Claude":"win32"===process.platform?"Claude":"claude-desktop",je="darwin"!==process.platform&&"win32"!==process.platform||!k().installMirror?.claudeDesktop?"https://claude.ai/download":k().installMirror.claudeDesktop,Ie="darwin"===process.platform?`open ${je}`:"win32"===process.platform?`start ${je}`:`xdg-open ${je}`;export const claudeDesktopAdapter={name:"claude-desktop",displayName:"Claude Desktop",command:Pe,installCommand:Ie,configPath:V(),sessions:{format:G,files:()=>K(l(claudeDesktopUserDataDir(),"local-agent-mode-sessions"))},isInstalled:Me,installedVersion:xe,prepareRuntime:async function(){if(!["win32","darwin","linux"].includes(process.platform)||!Me())return[];const e=Date.now();try{const t=await m({userDataDir:claudeDesktopUserDataDir(),onDownload:e=>console.log(p.gray(" "+y.t("tools.claude_desktop.code_cli_downloading",{version:e}))),desktopVersion:"darwin"===process.platform?xe():null,mirrorRepo:k().installMirror?.claudeDesktop?.replace(/\/-\/releases\/latest\/?$/,"")??null});return f("desktop-code-cli","skipped"===t.status?"skip":"ok",{duration_ms:Date.now()-e,detail:{...t}}),"installed"!==t.status?[]:[{kind:"summary",text:y.t("tools.claude_desktop.code_cli_installed",{version:t.version})}]}catch(t){return u.logError("claude-desktop.prepareCodeTabCli",t),f("desktop-code-cli","fail",{duration_ms:Date.now()-e,error:t}),[{kind:"action",text:y.t("tools.claude_desktop.code_cli_failed",{reason:t instanceof Error?t.message:String(t)})}]}},runningApp:C()?{isRunning:E,restart:O,quit:M,launch:v}:void 0,appInstaller:{blocker:x,latestVersion:()=>P(),installedPath(){if("darwin"===process.platform)return j();if("win32"!==process.platform)return null;try{return xe()?"MSIX":null}catch(e){return u.logError("claude-desktop.installedPath",e),null}},install:e=>I(e)},wantsModelCatalog:!0,loadPrivateConfig(e){const t=X()??{appliedId:"",entries:[]};let o=Z(t);o||(o={id:a(),name:U},t.entries.push(o));const n=ie(e);oe=!0===n.disableDeploymentModeChooser,te={models:n.inferenceModels,source:e.catalog?e.catalog.oneMillionSource:"slots",groups:e.catalog?.matchedGroups??[]};const r=z(B(o.id))??{};q(B(o.id),{...fe(r),...n}),t.appliedId=o.id,q(V(),t);const s=z(W())??{};if("3p"!==s.deploymentMode&&q(W(),{...s,deploymentMode:"3p"}),re=null,se=null,ne=null,be()){const t=De(ge),o=ve.filter(e=>t?.has(e)),r={...ue(e=>t?.has(e)??!1),...n},s=!0===e.settings?.force_registry,i=!s&&Ee();try{i?Ce(ve):we(r),ne=i?"removed":"written"}catch(e){u.logError("claude-desktop.policy",e),re=e instanceof Error?e.message.trim():String(e),(o.length>0||s)&&(se=i?{action:"remove",values:Object.fromEntries(o.map(e=>[e,null])),deleteKey:o.length===t.size}:{action:"write",values:r,deleteKey:!1})}}},pendingElevation(){const e=se;return e?{prompt:y.t(`tools.claude_desktop.elevate_${e.action}`),run:()=>{if(!L(me,e.values,e.deleteKey))return!1;const t=De(ge),o="remove"===e.action?Object.keys(e.values).every(e=>!t?.has(e)):Object.keys(e.values).every(e=>t?.has(e));return o&&(se=null,re=null),o}}:null},unloadPrivateConfig(){if(be())try{Ce(ve)}catch(e){u.logError("claude-desktop.removePolicy",e)}const e=X(),t=Z(e);if(!e||!t)return;D(B(t.id)),s(B(t.id),{force:!0});const o=e.entries.filter(e=>e.id!==t.id);0===o.length?(D(V()),s(V(),{force:!0})):q(V(),{...e,entries:o,appliedId:e.appliedId===t.id?o[0].id:e.appliedId})},listedModels(){const e=X(),t=Z(e);if(!t||e?.appliedId!==t.id)return null;const o=z(B(t.id))?.inferenceModels;return Array.isArray(o)?o.map(e=>String(e.name)):null},refreshModelMenu(e){const t=X(),o=Z(t);if(!o||t?.appliedId!==o.id)return;const n=z(B(o.id));if(!n)return;const r=buildInferenceModels(e.models,e.catalog),s=JSON.stringify(n.inferenceModels)!==JSON.stringify(r),i={...fe(n),inferenceModels:r},l=JSON.stringify(i)!==JSON.stringify(n);se=null;const a=be()?De(ge):null;if(!a?.has("inferenceModels"))return void(l&&q(B(o.id),i));const c=ve.filter(e=>a.has(e)),d=!0!==e.settings?.force_registry&&Ee();if(l&&q(B(o.id),i),d||s)try{d?Ce(ve):we({inferenceModels:r})}catch(e){throw u.logError("claude-desktop.refreshModelMenu registry",e),se=d?{action:"remove",values:Object.fromEntries(c.map(e=>[e,null])),deleteKey:c.length===a.size}:{action:"write",values:{inferenceModels:r},deleteKey:!1},new T(y.t("tools.claude_desktop.refresh_needs_admin"))}},detectCurrentConfig(){try{if(be()){const e=De(ge)?.get("inferenceGatewayApiKey");if(e)return{apiKey:e}}const e=Z(X());if(!e)return{apiKey:null};const t=z(B(e.id)),o=t?.inferenceGatewayApiKey;return{apiKey:"string"==typeof o&&o?o:null}}catch(e){return u.logError("claude-desktop.detectCurrentConfig",e),{apiKey:null}}},getConfig(){try{const e=X(),t=Z(e);return{meta:e,applied:t?z(B(t.id)):null,desktop:z(W()),...be()?{policy:Object.fromEntries(De(ge)??[])}:{}}}catch(e){return u.logError("claude-desktop.getConfig",e),null}},clearPinnedModels(){let e=!1;be()&&De(ge)?.has("inferenceModels")&&(Ae(),_e(["delete",ge,"/v","inferenceModels","/f"]),e=!0);const t=Z(X()),o=t?z(B(t.id)):null;if(t&&o&&void 0!==o.inferenceModels){const{inferenceModels:n,...r}=o;q(B(t.id),r),e=!0}return e?["inferenceModels"]:[]},applyNotes(){const e=[];if(te&&te.models.length>0){const{models:t,source:o,groups:n}=te;e.push({kind:"summary",text:y.t("tools.claude_desktop.models_summary",{count:String(t.length),default:t[0].labelOverride??t[0].name})}),e.push({kind:"detail",text:y.t(`tools.claude_desktop.models_written_${o}`,{count:String(t.length),list:t.map(e=>`${e.labelOverride}${e.supports1m?" (1M)":""}`).join(", "),groups:n.join(" / ")})})}null!==oe&&e.push({kind:"detail",text:y.t(oe?"tools.claude_desktop.official_login_hidden":"tools.claude_desktop.official_login_shown")}),C()&&!E()||e.push({kind:"action",text:y.t("tools.claude_desktop.restart_hint")}),se?(e.push({kind:"action",text:y.t(`tools.claude_desktop.policy_stale_${se.action}`)}),e.push({kind:"detail",text:re??""})):re?(e.push({kind:"detail",text:y.t("tools.claude_desktop.registry_denied")}),e.push({kind:"detail",text:re})):be()&&ne&&e.push({kind:"detail",text:y.t(`tools.claude_desktop.registry_${ne}`,{key:ge})});const t=detectManagedConfig();return t&&e.push({kind:"action",text:y.t("tools.claude_desktop.managed_conflict",{path:t})}),e},forceResetPaths(){const e=[V(),W()];try{const t=Z(X());t&&e.push(B(t.id))}catch{}return e},backupPaths(){const e=[V(),W()];be()&&e.push(l(claudeDesktopUserDataDir(),he));try{const t=Z(X());t&&e.push(B(t.id))}catch{}return e}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawnSync as e}from"child_process";import{logger as t}from"../../utils/logger.js";export const WINDOWS_PACKAGE_FAMILIES=["Claude_pzs8sxrjxfjjc","AnthropicPBC.Claude_fnn82j28hfe8t"];const r="Get-Process -Name claude -ErrorAction SilentlyContinue | Where-Object { $_.Path -and ($_.Path -like '*\\AnthropicClaude\\*' -or $_.Path -like '*\\Programs\\Claude\\*' -or $_.Path -like '*\\WindowsApps\\*Claude*') }";let o=(r,o,s=3e4)=>{const n=e(r,o,{encoding:"utf-8",timeout:s,windowsHide:!0,stdio:["ignore","pipe","pipe"]});return n.error&&t.logError(`desktop-process: ${r}`,n.error),{status:n.status,stdout:`${n.stdout??""}`}};export function setDesktopProcessRunnerForTests(e){o=e}function s(e,t){return o("powershell.exe",["-NoProfile","-NonInteractive","-Command",e],t)}function n(e){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}export function isDesktopRunning(){return"darwin"===process.platform?0===o("pgrep",["-x","Claude"]).status:"win32"===process.platform&&Number(s(`@(${r}).Count`).stdout.trim())>0}export function canRestartDesktop(){return"darwin"===process.platform||"win32"===process.platform}export function
|
|
1
|
+
import{spawnSync as e}from"child_process";import{logger as t}from"../../utils/logger.js";export const WINDOWS_PACKAGE_FAMILIES=["Claude_pzs8sxrjxfjjc","AnthropicPBC.Claude_fnn82j28hfe8t"];const r="Get-Process -Name claude -ErrorAction SilentlyContinue | Where-Object { $_.Path -and ($_.Path -like '*\\AnthropicClaude\\*' -or $_.Path -like '*\\Programs\\Claude\\*' -or $_.Path -like '*\\WindowsApps\\*Claude*') }";let o=(r,o,s=3e4)=>{const n=e(r,o,{encoding:"utf-8",timeout:s,windowsHide:!0,stdio:["ignore","pipe","pipe"]});return n.error&&t.logError(`desktop-process: ${r}`,n.error),{status:n.status,stdout:`${n.stdout??""}`}};export function setDesktopProcessRunnerForTests(e){o=e}function s(e,t){return o("powershell.exe",["-NoProfile","-NonInteractive","-Command",e],t)}function n(e){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,e)}export function isDesktopRunning(){return"darwin"===process.platform?0===o("pgrep",["-x","Claude"]).status:"win32"===process.platform&&Number(s(`@(${r}).Count`).stdout.trim())>0}export function canRestartDesktop(){return"darwin"===process.platform||"win32"===process.platform}export function quitDesktop(){if("darwin"===process.platform){o("osascript",["-e",'quit app "Claude"']);for(let e=0;e<30&&isDesktopRunning();e++)n(500);isDesktopRunning()&&o("pkill",["-x","Claude"]),n(1e3)}else{if("win32"!==process.platform)return!1;s([`$p = @(${r})`,"$p | ForEach-Object { [void]$_.CloseMainWindow() }","Start-Sleep -Seconds 3","$p | Where-Object { -not $_.HasExited } | Stop-Process -Force -ErrorAction SilentlyContinue","Start-Sleep -Seconds 1"].join("\n"),6e4)}return!isDesktopRunning()}export function launchDesktop(){if("darwin"===process.platform)o("open",["-a","Claude"]);else{if("win32"!==process.platform)return!1;s(["$squirrel = Join-Path $env:LOCALAPPDATA 'AnthropicClaude\\claude.exe'","$programs = Join-Path $env:LOCALAPPDATA 'Programs\\Claude\\Claude.exe'","if (Test-Path $squirrel) { Start-Process $squirrel }","elseif (Test-Path $programs) { Start-Process $programs }",`else { $pkg = Get-AppxPackage | Where-Object { @(${WINDOWS_PACKAGE_FAMILIES.map(e=>`'${e}'`).join(",")}) -contains $_.PackageFamilyName } | Select-Object -First 1`," if ($pkg) { $id = (Get-AppxPackageManifest $pkg).Package.Applications.Application.Id | Select-Object -First 1",' Start-Process "shell:AppsFolder\\$($pkg.PackageFamilyName)!$id" } }'].join("\n"),6e4)}for(let e=0;e<20;e++){if(isDesktopRunning())return!0;n(500)}return!1}export function restartDesktop(){return!!canRestartDesktop()&&(quitDesktop(),launchDesktop())}
|
package/dist/lib/wizard.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"inquirer";import t from"chalk";import a from"ora";import{configManager as o,DEFAULT_MODELS as i}from"./config.js";import{getPresets as n,resolvePreset as r,getToolDefaultModel as s}from"./model-registry.js";import{toolManager as l,SUPPORTED_TOOLS as c}from"./tool-manager.js";import{confirmWritePlan as d}from"./write-plan.js";import{postApplyPrompts as p}from"./post-apply.js";import{i18n as m,detectSystemLang as u}from"./i18n.js";import{createBorderLine as _,createContentLine as g}from"../utils/string-width.js";import{validateApiKey as w,fetchModels as f}from"./api-validator.js";import{CODEX_ONE_MILLION_CONTEXT_SETTING as y}from"./tools/codex.js";import{CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING as h}from"./tools/claude-desktop.js";import{addressesWithCurrent as z,ensureReachableGatewayAddress as v,fastestIndex as k,probeAll as x,probeSummary as b,reasonText as S,savedApiKey as C,switchGatewayAddress as M}from"../commands/base.js";import{readFileSync as T}from"fs";import{dirname as A,join as K}from"path";import{fileURLToPath as N}from"url";import{brand as B}from"./brand.js";const P=A(N(import.meta.url)),H=t.hex("#FF8700");export class Wizard{static instance;BOX_WIDTH=63;validatedApiKeys=new Set;constructor(){}static getInstance(){return Wizard.instance||(Wizard.instance=new Wizard),Wizard.instance}createBox(e){console.log(H.bold("\n"+_("╔","╗","═",this.BOX_WIDTH))),console.log(H.bold(g(e,"║","║",this.BOX_WIDTH,"center"))),console.log(H.bold(_("╚","╝","═",this.BOX_WIDTH))),console.log("")}showOperationHints(){const e=[t.gray(m.t("wizard.hint_navigate")),t.gray(m.t("wizard.hint_confirm"))];console.log(t.gray("💡 ")+e.join(t.gray(" | "))+"\n")}async promptWithHints(t){this.showOperationHints();const a=t.map(e=>"list"!==e.type||e.pageSize?e:{...e,pageSize:20});return e.prompt(a)}printBanner(){const e=60,t=m.t("wizard.banner_subtitle"),a=g(t,"║","║",e,"center"),o=g("","║","║",e,"center"),i=g(`${B().productName} v${function(){try{return JSON.parse(T(K(P,"..","..","package.json"),"utf-8")).version}catch{return"0.0.0"}}()}`,"║","║",e,"center"),n=[String.raw`__ ___ _ ____ _ ___ `,String.raw`\ \ / (_) |__ ___ / ___| | |_ _|`,String.raw` \ \ / /| | '_ \ / _ \ | | | | | `,String.raw` \ V / | | |_) | __/ |___| |___ | | `,String.raw` \_/ |_|_.__/ \___|\____|_____|___|`],r=Math.max(...n.map(e=>e.length)),s=" ".repeat(Math.floor((58-r)/2)),l=n.map(t=>g(s+t,"║","║",e,"left")),c=[_("╔","╗","═",e),o,...l,o,i,a,_("╚","╝","═",e)];console.log(H.bold("\n"+c.join("\n")))}resetScreen(){console.clear(),this.printBanner()}printGoodbye(){const e=l.getSupportedTools().filter(e=>{if(e.gui)return!1;try{return Boolean(l.detectCurrentConfig(e.name).apiKey)&&l.isToolInstalled(e.name)}catch{return!1}});let a;if(e.length>0){const t=e.map(e=>e.command).join(" / ");a=m.t("wizard.goodbye_message_tools",{commands:t}),e.some(e=>"claude-code"===e.name)&&(a+=" "+m.t("wizard.goodbye_claude_hint"))}else a=m.t("wizard.goodbye_message");console.log(t.green("\n👋 "+a)),this.printPathReloadHint(e.map(e=>e.name))}printPathReloadHint(e){const a=e.filter(e=>!l.isOnPath(e));if(0===a.length)return;const o=a.map(e=>c[e].command).join(" / ");console.log(t.yellow(" ! "+m.t("win32"===process.platform?"setup.path_reload_windows":"setup.path_reload",{commands:o})))}async runFirstTimeSetup(){const e="zh_CN"===u();e&&(o.setLang("zh_CN"),m.setLocale("zh_CN")),this.resetScreen(),console.log(H.bold("\n"+m.t("wizard.welcome"))),console.log(t.gray(m.t("wizard.privacy_note")+"\n")),e?console.log(t.gray(m.t("wizard.lang_auto_zh")+"\n")):await this.configLanguage(),await v(),await this.configApiKey()&&await this.selectAndConfigureTool(!0)}async configLanguage(){for(;;){this.resetScreen(),this.createBox(m.t("wizard.select_language"));const a=m.getLocale(),{language:i}=await this.promptWithHints([{type:"list",name:"language",message:"✨ "+m.t("wizard.select_language"),choices:[{name:"[EN] English"+("en_US"===a?t.green(" ✓ ("+m.t("wizard.current_active")+")"):""),value:"en_US"},{name:"[CN] 中文"+("zh_CN"===a?t.green(" ✓ ("+m.t("wizard.current_active")+")"):""),value:"zh_CN"},new e.Separator,{name:"<- "+m.t("wizard.nav_return"),value:"back"},{name:"x "+m.t("wizard.nav_exit"),value:"exit"}],default:"zh_CN"}]);if("exit"===i)this.printGoodbye(),process.exit(0);else if("back"===i)return;return o.setLang(i),void m.setLocale(i)}}buildPresetChoices(){const a=n(),o=a.filter(e=>e.recommended),i=a.filter(e=>!e.recommended),r=e=>({name:(m.t(e.name)!==e.name?m.t(e.name):e.name)+(e.models?t.gray(` [H:${e.models.haiku} S:${e.models.sonnet} O:${e.models.opus}]`):""),value:{type:"preset",preset:e}}),s=[];return o.length>0&&(s.push(new e.Separator(t.hex("#FF8700")("── "+m.t("wizard.recommended")+" ──"))),s.push(...o.map(r))),i.length>0&&(s.push(new e.Separator(t.gray("── "+m.t("wizard.other_models")+" ──"))),s.push(...i.map(r))),s}async handleCustomModelInput(){const a=o.getModels(),{customMode:n}=await e.prompt([{type:"list",name:"customMode",message:m.t("wizard.custom_model_mode"),choices:[{name:m.t("wizard.custom_model_single"),value:"single"},{name:m.t("wizard.custom_model_per_role"),value:"per_role"}]}]);if("single"===n){const{customModel:t}=await e.prompt([{type:"input",name:"customModel",message:m.t("wizard.input_custom_model"),default:i.sonnet}]);o.setModels({haiku:t,sonnet:t,opus:t,reasoning:t})}else{const t=await e.prompt([{type:"input",name:"haiku",message:m.t("wizard.model_haiku"),default:a.haiku},{type:"input",name:"sonnet",message:m.t("wizard.model_sonnet"),default:a.sonnet},{type:"input",name:"opus",message:m.t("wizard.model_opus"),default:a.opus},{type:"input",name:"reasoning",message:m.t("wizard.model_reasoning"),default:a.reasoning}]);o.setModels(t)}console.log(t.green("\n✓ "+m.t("wizard.models_saved")))}async configModels(a){const i=o.getApiKey();if(await this.validatedKeyForConfiguration(i))for(;;){this.resetScreen(),this.createBox(m.t("wizard.config_models"));const i=[...this.buildPresetChoices()];i.push(new e.Separator),i.push({name:"✏️ "+m.t("wizard.custom_model_input"),value:{type:"custom_input"}}),i.push(new e.Separator),i.push({name:"<- "+m.t("wizard.nav_return"),value:{type:"back"}}),i.push({name:"x "+m.t("wizard.nav_exit"),value:{type:"exit"}});const{modelChoice:n}=await this.promptWithHints([{type:"list",name:"modelChoice",message:m.t("wizard.select_model_config"),choices:i}]);if("exit"===n.type)this.printGoodbye(),process.exit(0);else{if("back"===n.type)return;if("custom_input"===n.type)return await this.handleCustomModelInput(),void(a?.skipLoadPrompt||await this.promptLoadAfterModelConfig());if("preset"===n.type){const e=r(n.preset);return o.setModels(e),console.log(t.green("\n✓ "+m.t("wizard.models_saved"))),void(a?.skipLoadPrompt||await this.promptLoadAfterModelConfig())}}}else await e.prompt([{type:"input",name:"continue",message:m.t("wizard.press_enter")}])}async promptLoadAfterModelConfig(){const{shouldLoad:t}=await e.prompt([{type:"list",name:"shouldLoad",message:m.t("wizard.load_config_now"),choices:[{name:m.t("wizard.load_config_yes"),value:!0},{name:m.t("wizard.load_config_later"),value:!1}]}]);t&&await this.selectAndConfigureTool()}async configBaseUrl(){const i=o.getBaseUrl(),n=z(),r=a(m.t("wizard.base_testing")).start(),s=await x(n,{apiKey:C(),samples:3});r.stop();const l=k(s),c=n.map((e,a)=>{const o=e.url===i?t.cyan(` ← ${m.t("base.current_mark")}`):"";return{name:`${e.url} ${t.gray(e.label)} ${b(s[a],a===l)}${o}`,value:e.url}});c.push(new e.Separator,{name:"<- "+m.t("wizard.nav_return"),value:"__back__"});const{url:d}=await this.promptWithHints([{type:"list",name:"url",message:m.t("wizard.base_select"),choices:c,default:i}]);if("__back__"===d)return;const p=s[n.findIndex(e=>e.url===d)];p.ok?await M(d):console.log(t.red(m.t("base.unreachable",{url:d,reason:S(p)}))),await e.prompt([{type:"input",name:"continue",message:m.t("wizard.press_enter")}])}async configApiKey(){for(;;){this.resetScreen(),this.createBox(m.t("wizard.input_api_key")),console.log(t.gray("\n💡 "+m.t("wizard.api_key_input_hint"))),console.log(t.gray(" "+m.t("wizard.api_key_get_hint",{url:B().links.tokenPage}))),console.log();const{apiKey:i}=await e.prompt([{type:"password",name:"apiKey",message:m.t("wizard.input_your_api_key"),mask:"*"}]);if(!i||""===i.trim()){const{action:t}=await e.prompt([{type:"list",name:"action",message:m.t("wizard.select_action"),choices:[{name:m.t("wizard.retry_input"),value:"retry"},{name:"<- "+m.t("wizard.nav_return"),value:"back"}]}]);if("back"===t)return!1;continue}const n=a(m.t("wizard.validating_api_key")).start(),r=await w(i.trim());if(n.stop(),r.valid)return o.setApiKey(i.trim()),this.validatedApiKeys.add(i.trim()),console.log(t.green("\n✓ "+m.t("wizard.api_key_valid"))),!0;{this.validatedApiKeys.delete(i.trim()),"invalid_api_key"===r.error?console.log(t.red("\n✗ "+m.t("wizard.api_key_invalid"))):console.log(t.red("\n✗ "+m.t("wizard.api_key_network_error")));const{action:a}=await e.prompt([{type:"list",name:"action",message:m.t("wizard.select_action"),choices:[{name:m.t("wizard.retry_input"),value:"retry"},{name:"<- "+m.t("wizard.nav_return"),value:"back"}]}]);if("back"===a)return!1}}}async selectAndConfigureTool(t=!1){for(;;){this.resetScreen(),this.createBox(m.t("wizard.select_tool"));const a=l.getSupportedTools().map(e=>({name:e.displayName,value:e.name})),{tool:o}=await this.promptWithHints([{type:"list",name:"tool",message:"🛠️ "+m.t("wizard.select_tool"),choices:[...a,new e.Separator,{name:"<- "+m.t("wizard.nav_return"),value:"back"},{name:"x "+m.t("wizard.nav_exit"),value:"exit"}]}]);if("exit"===o)this.printGoodbye(),process.exit(0);else if("back"===o)return;await this.configureTool(o,t)}}async configureTool(a,o=!1){const i=c[a];if(i){if(!l.isToolInstalled(a)){console.log(t.yellow("\n"+m.t("wizard.tool_not_installed",{tool:i.displayName})));const{install:o}=await e.prompt([{type:"confirm",name:"install",message:m.t("wizard.install_tool_confirm"),default:!0}]);if(!o)return;try{await l.installTool(a)}catch{return void console.log(t.red(m.t("wizard.install_failed")))}}o?await this.configureToolModel(a)&&await this.loadConfig(a):await this.showToolMenu(a)}}async showToolMenu(t){for(;;){this.resetScreen();const a=c[t];if(!a)return;this.createBox(a.displayName+" "+m.t("wizard.menu_title"));const o=[{name:"📥 "+m.t("wizard.action_load_config",{tool:a.displayName}),value:"load"},{name:"📤 "+m.t("wizard.action_unload_config",{tool:a.displayName}),value:"unload"}];l.supportsClearPinnedModels(t)&&o.push({name:"🧹 "+m.t("wizard.action_clear_model",{tool:a.displayName}),value:"clear-model"}),o.push({name:"🧨 "+m.t("wizard.action_force_config",{tool:a.displayName}),value:"force"},{name:"↩️ "+m.t("wizard.action_restore_config",{tool:a.displayName}),value:"restore"},new e.Separator,{name:"<- "+m.t("wizard.nav_return"),value:"back"},{name:"x "+m.t("wizard.nav_exit"),value:"exit"});const{action:i}=await this.promptWithHints([{type:"list",name:"action",message:"⚙️ "+m.t("wizard.select_action"),choices:o}]);if("exit"===i)this.printGoodbye(),process.exit(0);else{if("back"===i)return;"load"===i?await this.configureToolModel(t)&&await this.loadConfig(t):"force"===i?await this.forceConfig(t):"unload"===i?await this.unloadConfig(t):"clear-model"===i?await this.clearPinnedModels(t):"restore"===i&&await this.restoreConfig(t)}}}singleModelOverride(e){const t=e.trim();return/claude/i.test(t)?{opus:t}:{haiku:t,sonnet:t,opus:t,reasoning:t}}hasConfiguredApiKey(){return!!o.getApiKey()?.trim()||o.listToolApiKeys().some(e=>Boolean(o.getApiKeyForTool(e)?.trim()))}async validatedKeyForConfiguration(e){const o=e?.trim();if(!o)return console.log(t.red("\n"+m.t("wizard.api_key_required"))),console.log(t.yellow(m.t("wizard.please_config_api_key_first"))),null;if(this.validatedApiKeys.has(o))return o;const i=a(m.t("wizard.validating_api_key")).start(),n=await w(o);if(n.valid)return this.validatedApiKeys.add(o),i.succeed(m.t("wizard.api_key_valid")),o;this.validatedApiKeys.delete(o);const r="invalid_api_key"===n.error?m.t("wizard.api_key_invalid"):m.t("wizard.api_key_network_error");return i.fail(r),console.log(t.red("\n"+m.t("wizard.please_reconfig_api_key"))),null}async configureToolModel(i){const n=c[i];if(!n)return!1;const l=await this.validatedKeyForConfiguration(o.getApiKeyForTool(i));if(!l)return await e.prompt([{type:"input",name:"continue",message:m.t("wizard.press_enter")}]),!1;const d="claude-code"===i,p=d||"claude-desktop"===i||"agy"===i,u=s(i),_=p||!u?m.t("wizard.model_builtin_default"):u;this.resetScreen(),this.createBox(n.displayName+" · "+m.t("wizard.config_models"));const g=[{name:"✅ "+m.t("wizard.use_default_model",{model:_}),value:{type:"default"}},{name:"🌐 "+m.t("wizard.fetch_models_from_api"),value:{type:"fetch"}},...this.buildPresetChoices(),new e.Separator,{name:"✏️ "+m.t("wizard.input_custom_model"),value:{type:"custom"}},new e.Separator,{name:"<- "+m.t("wizard.nav_return"),value:{type:"back"}}],{choice:w}=await this.promptWithHints([{type:"list",name:"choice",message:m.t("wizard.select_tool_model",{tool:n.displayName}),choices:g}]);if("back"===w.type)return!1;if("default"===w.type)o.setToolModel(i,null);else if("preset"===w.type)o.setToolModel(i,r(w.preset));else if("custom"===w.type){const{model:t}=await e.prompt([{type:"input",name:"model",message:m.t("wizard.input_custom_model"),default:!p&&u?u:void 0}]),a=(t||"").trim();o.setToolModel(i,a?this.singleModelOverride(a):null)}else if("fetch"===w.type){const n=a(m.t("wizard.fetching_models")).start(),r=await f(l);let s;if(n.stop(),r.ok&&r.models.length>0){const{model:t}=await e.prompt([{type:"list",name:"model",message:m.t("wizard.select_fetched_model"),pageSize:20,choices:[...r.models,new e.Separator,{name:"<- "+m.t("wizard.nav_return"),value:"__back__"}]}]);if("__back__"===t)return!1;s=t}else{console.log(t.yellow("\n"+m.t("wizard.fetch_models_failed")));const{model:a}=await e.prompt([{type:"input",name:"model",message:m.t("wizard.input_custom_model"),default:!p&&u?u:void 0}]);s=(a||"").trim()}o.setToolModel(i,s?this.singleModelOverride(s):null)}if("codex"===i){const t=o.getToolSetting(i,y),{enableOneMillionContext:a}=await e.prompt([{type:"confirm",name:"enableOneMillionContext",message:m.t("wizard.codex_enable_1m_context"),default:!1!==t}]);o.setToolSetting(i,y,Boolean(a))}if("claude-desktop"===i){const t=o.getToolSetting(i,h),{hideOfficialLogin:a}=await e.prompt([{type:"confirm",name:"hideOfficialLogin",message:m.t("wizard.desktop_hide_official_login"),default:!1!==t}]);o.setToolSetting(i,h,Boolean(a))}return console.log(t.green("\n✓ "+m.t("wizard.models_saved"))),d&&console.log(t.gray("💡 "+m.t("wizard.claude_model_hint"))),!0}async forceConfig(t){const a=c[t]?.displayName||t,{confirm:o}=await e.prompt([{type:"confirm",name:"confirm",message:m.t("config.confirm_force",{tool:a}),default:!1}]);o&&await this.loadConfig(t,{force:!0})}async loadConfig(i,n={}){const r=o.getModelsForTool(i),s=await this.validatedKeyForConfiguration(o.getApiKeyForTool(i));if(!s)return void await e.prompt([{type:"input",name:"continue",message:m.t("wizard.press_enter")}]);if(!n.force&&!await d([i]))return;const u=a(m.t("wizard.loading_config")).start();try{await l.applyPrivateConfig(i,s,r,n),u.stop(),l.printApplied(i),await p([i]),n.force&&console.log(t.yellow(m.t("config.force_done",{tool:c[i]?.displayName||i,name:i})));const a=c[i];a&&!a.gui&&(l.isOnPath(i)&&console.log(t.green("\n"+m.t("wizard.run_tool_hint",{command:a.command}))),this.printPathReloadHint([i]));const{nextAction:o}=await e.prompt([{type:"list",name:"nextAction",message:m.t("wizard.what_next"),choices:[{name:m.t("wizard.exit_and_start"),value:"exit"},{name:m.t("wizard.continue_config"),value:"continue"}]}]);"exit"===o&&(this.printGoodbye(),process.exit(0))}catch(a){u.fail(m.t("wizard.config_failed")),console.log(t.red(a instanceof Error?a.message:String(a))),await e.prompt([{type:"input",name:"continue",message:m.t("wizard.press_enter")}])}}async clearPinnedModels(a){const o=c[a]?.displayName||a,{confirm:i}=await e.prompt([{type:"confirm",name:"confirm",message:m.t("wizard.confirm_clear_model",{tool:o}),default:!1}]);if(i){try{const e=await l.clearPinnedModels(a);0===e.length?console.log(t.yellow("\n"+m.t("config.clear_model_none",{tool:o}))):(console.log(t.green("\n✓ "+m.t("config.clear_model_done",{tool:o}))),e.forEach(e=>console.log(t.gray(` - ${e}`))),console.log(t.gray(m.t("config.clear_model_restart_hint",{tool:o}))))}catch(e){console.log(t.red("\n"+(e instanceof Error?e.message:String(e))))}await e.prompt([{type:"input",name:"continue",message:m.t("wizard.press_enter")}])}}async unloadConfig(o){const{confirm:i}=await e.prompt([{type:"confirm",name:"confirm",message:m.t("wizard.confirm_unload_config",{tool:c[o]?.displayName||o}),default:!1}]);if(!i)return;const n=a(m.t("wizard.unloading_config")).start();try{const a=l.holdsOurConfig(o),i=l.unloadPrivateConfig(o);if(!a)return void n.info(m.t("config.remove_nothing",{tool:c[o]?.displayName||o}));n.succeed(m.t("wizard.config_unloaded")),i.forEach(e=>console.log(t.yellow(" ! "+e.text)));const{nextAction:r}=await e.prompt([{type:"list",name:"nextAction",message:m.t("wizard.what_next"),choices:[{name:m.t("wizard.nav_exit"),value:"exit"},{name:m.t("wizard.continue_config"),value:"continue"}]}]);"exit"===r&&(this.printGoodbye(),process.exit(0))}catch(a){n.fail(m.t("wizard.config_unload_failed")),console.log(t.red(a instanceof Error?a.message:String(a))),await e.prompt([{type:"input",name:"continue",message:m.t("wizard.press_enter")}])}}async restoreConfig(o){const i=c[o]?.displayName||o,{confirm:n}=await e.prompt([{type:"confirm",name:"confirm",message:m.t("wizard.confirm_restore_config",{tool:i}),default:!1}]);if(!n)return;const r=a(m.t("wizard.restoring_config")).start();try{const e=l.restorePrivateConfig(o).filter(e=>e.result.restored);0===e.length?r.warn(m.t("wizard.restore_no_backup")):(r.succeed(m.t("wizard.config_restored",{tool:i})),e.forEach(e=>console.log(t.gray(` ${e.file} ← ${e.result.from}`))),console.log(t.yellow(" ! "+m.t("config.reopen_hint",{tool:i}))))}catch(e){r.fail(m.t("wizard.config_restore_failed")),console.log(t.red(e instanceof Error?e.message:String(e)))}await e.prompt([{type:"input",name:"continue",message:m.t("wizard.press_enter")}])}async run(){await this.showMainMenu()}async showMainMenu(){if(this.hasConfiguredApiKey())for(;;){this.resetScreen();const a=o.getApiKey()||"",i=a.length>4?"sk-****"+a.slice(-4):"****";console.log(t.gray(` 🔑 API Key: ${i}`)+t.green(" ✓")),console.log("");const n=l.getSupportedTools().map(e=>({name:"🛠️ "+e.displayName,value:{type:"tool",tool:e.name}})),r=[new e.Separator(H("── "+m.t("wizard.select_tool")+" ──")),...n,new e.Separator(t.gray("── "+m.t("wizard.settings")+" ──")),{name:"🔑 "+m.t("wizard.menu_change_api_key"),value:{type:"apikey"}},{name:"🔗 "+m.t("wizard.menu_base_url",{url:o.getBaseUrl()}),value:{type:"base"}},{name:"🌐 "+m.t("wizard.menu_config_language"),value:{type:"language"}},new e.Separator,{name:"x "+m.t("wizard.nav_exit"),value:{type:"exit"}}],{action:s}=await this.promptWithHints([{type:"list",name:"action",message:"🛠️ "+m.t("wizard.select_tool"),choices:r}]);"exit"===s.type?(this.printGoodbye(),process.exit(0)):"tool"===s.type?await this.configureTool(s.tool):"apikey"===s.type?await this.configApiKey():"base"===s.type?await this.configBaseUrl():"language"===s.type&&await this.configLanguage()}else await this.runFirstTimeSetup()}}export const wizard=Wizard.getInstance();
|
|
1
|
+
import e from"inquirer";import t from"chalk";import a from"ora";import{configManager as o,DEFAULT_MODELS as i}from"./config.js";import{getPresets as n,resolvePreset as r,getToolDefaultModel as s}from"./model-registry.js";import{toolManager as l,SUPPORTED_TOOLS as c}from"./tool-manager.js";import{confirmWritePlan as d}from"./write-plan.js";import{postApplyPrompts as p}from"./post-apply.js";import{appStatus as m,appStatusText as u,appTools as _,cachedAppStatus as g,upgradeApp as w}from"./app-update.js";import{i18n as f,detectSystemLang as y}from"./i18n.js";import{createBorderLine as h,createContentLine as z}from"../utils/string-width.js";import{validateApiKey as v,fetchModels as k}from"./api-validator.js";import{CODEX_ONE_MILLION_CONTEXT_SETTING as x}from"./tools/codex.js";import{CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING as b}from"./tools/claude-desktop.js";import{addressesWithCurrent as S,ensureReachableGatewayAddress as C,fastestIndex as M,probeAll as T,probeSummary as A,reasonText as N,savedApiKey as K,switchGatewayAddress as B}from"../commands/base.js";import{readFileSync as P}from"fs";import{dirname as j,join as H}from"path";import{fileURLToPath as O}from"url";import{brand as W}from"./brand.js";const L=j(O(import.meta.url)),F=t.hex("#FF8700");export class Wizard{static instance;BOX_WIDTH=63;validatedApiKeys=new Set;constructor(){}static getInstance(){return Wizard.instance||(Wizard.instance=new Wizard),Wizard.instance}createBox(e){console.log(F.bold("\n"+h("╔","╗","═",this.BOX_WIDTH))),console.log(F.bold(z(e,"║","║",this.BOX_WIDTH,"center"))),console.log(F.bold(h("╚","╝","═",this.BOX_WIDTH))),console.log("")}showOperationHints(){const e=[t.gray(f.t("wizard.hint_navigate")),t.gray(f.t("wizard.hint_confirm"))];console.log(t.gray("💡 ")+e.join(t.gray(" | "))+"\n")}async promptWithHints(t){this.showOperationHints();const a=t.map(e=>"list"!==e.type||e.pageSize?e:{...e,pageSize:20});return e.prompt(a)}printBanner(){const e=60,t=f.t("wizard.banner_subtitle"),a=z(t,"║","║",e,"center"),o=z("","║","║",e,"center"),i=z(`${W().productName} v${function(){try{return JSON.parse(P(H(L,"..","..","package.json"),"utf-8")).version}catch{return"0.0.0"}}()}`,"║","║",e,"center"),n=[String.raw`__ ___ _ ____ _ ___ `,String.raw`\ \ / (_) |__ ___ / ___| | |_ _|`,String.raw` \ \ / /| | '_ \ / _ \ | | | | | `,String.raw` \ V / | | |_) | __/ |___| |___ | | `,String.raw` \_/ |_|_.__/ \___|\____|_____|___|`],r=Math.max(...n.map(e=>e.length)),s=" ".repeat(Math.floor((58-r)/2)),l=n.map(t=>z(s+t,"║","║",e,"left")),c=[h("╔","╗","═",e),o,...l,o,i,a,h("╚","╝","═",e)];console.log(F.bold("\n"+c.join("\n")))}resetScreen(){console.clear(),this.printBanner()}printGoodbye(){const e=l.getSupportedTools().filter(e=>{if(e.gui)return!1;try{return Boolean(l.detectCurrentConfig(e.name).apiKey)&&l.isToolInstalled(e.name)}catch{return!1}});let a;if(e.length>0){const t=e.map(e=>e.command).join(" / ");a=f.t("wizard.goodbye_message_tools",{commands:t}),e.some(e=>"claude-code"===e.name)&&(a+=" "+f.t("wizard.goodbye_claude_hint"))}else a=f.t("wizard.goodbye_message");console.log(t.green("\n👋 "+a)),this.printPathReloadHint(e.map(e=>e.name))}printPathReloadHint(e){const a=e.filter(e=>!l.isOnPath(e));if(0===a.length)return;const o=a.map(e=>c[e].command).join(" / ");console.log(t.yellow(" ! "+f.t("win32"===process.platform?"setup.path_reload_windows":"setup.path_reload",{commands:o})))}async runFirstTimeSetup(){const e="zh_CN"===y();e&&(o.setLang("zh_CN"),f.setLocale("zh_CN")),this.resetScreen(),console.log(F.bold("\n"+f.t("wizard.welcome"))),console.log(t.gray(f.t("wizard.privacy_note")+"\n")),e?console.log(t.gray(f.t("wizard.lang_auto_zh")+"\n")):await this.configLanguage(),await C(),await this.configApiKey()&&await this.selectAndConfigureTool(!0)}async configLanguage(){for(;;){this.resetScreen(),this.createBox(f.t("wizard.select_language"));const a=f.getLocale(),{language:i}=await this.promptWithHints([{type:"list",name:"language",message:"✨ "+f.t("wizard.select_language"),choices:[{name:"[EN] English"+("en_US"===a?t.green(" ✓ ("+f.t("wizard.current_active")+")"):""),value:"en_US"},{name:"[CN] 中文"+("zh_CN"===a?t.green(" ✓ ("+f.t("wizard.current_active")+")"):""),value:"zh_CN"},new e.Separator,{name:"<- "+f.t("wizard.nav_return"),value:"back"},{name:"x "+f.t("wizard.nav_exit"),value:"exit"}],default:"zh_CN"}]);if("exit"===i)this.printGoodbye(),process.exit(0);else if("back"===i)return;return o.setLang(i),void f.setLocale(i)}}buildPresetChoices(){const a=n(),o=a.filter(e=>e.recommended),i=a.filter(e=>!e.recommended),r=e=>({name:(f.t(e.name)!==e.name?f.t(e.name):e.name)+(e.models?t.gray(` [H:${e.models.haiku} S:${e.models.sonnet} O:${e.models.opus}]`):""),value:{type:"preset",preset:e}}),s=[];return o.length>0&&(s.push(new e.Separator(t.hex("#FF8700")("── "+f.t("wizard.recommended")+" ──"))),s.push(...o.map(r))),i.length>0&&(s.push(new e.Separator(t.gray("── "+f.t("wizard.other_models")+" ──"))),s.push(...i.map(r))),s}async handleCustomModelInput(){const a=o.getModels(),{customMode:n}=await e.prompt([{type:"list",name:"customMode",message:f.t("wizard.custom_model_mode"),choices:[{name:f.t("wizard.custom_model_single"),value:"single"},{name:f.t("wizard.custom_model_per_role"),value:"per_role"}]}]);if("single"===n){const{customModel:t}=await e.prompt([{type:"input",name:"customModel",message:f.t("wizard.input_custom_model"),default:i.sonnet}]);o.setModels({haiku:t,sonnet:t,opus:t,reasoning:t})}else{const t=await e.prompt([{type:"input",name:"haiku",message:f.t("wizard.model_haiku"),default:a.haiku},{type:"input",name:"sonnet",message:f.t("wizard.model_sonnet"),default:a.sonnet},{type:"input",name:"opus",message:f.t("wizard.model_opus"),default:a.opus},{type:"input",name:"reasoning",message:f.t("wizard.model_reasoning"),default:a.reasoning}]);o.setModels(t)}console.log(t.green("\n✓ "+f.t("wizard.models_saved")))}async configModels(a){const i=o.getApiKey();if(await this.validatedKeyForConfiguration(i))for(;;){this.resetScreen(),this.createBox(f.t("wizard.config_models"));const i=[...this.buildPresetChoices()];i.push(new e.Separator),i.push({name:"✏️ "+f.t("wizard.custom_model_input"),value:{type:"custom_input"}}),i.push(new e.Separator),i.push({name:"<- "+f.t("wizard.nav_return"),value:{type:"back"}}),i.push({name:"x "+f.t("wizard.nav_exit"),value:{type:"exit"}});const{modelChoice:n}=await this.promptWithHints([{type:"list",name:"modelChoice",message:f.t("wizard.select_model_config"),choices:i}]);if("exit"===n.type)this.printGoodbye(),process.exit(0);else{if("back"===n.type)return;if("custom_input"===n.type)return await this.handleCustomModelInput(),void(a?.skipLoadPrompt||await this.promptLoadAfterModelConfig());if("preset"===n.type){const e=r(n.preset);return o.setModels(e),console.log(t.green("\n✓ "+f.t("wizard.models_saved"))),void(a?.skipLoadPrompt||await this.promptLoadAfterModelConfig())}}}else await e.prompt([{type:"input",name:"continue",message:f.t("wizard.press_enter")}])}async promptLoadAfterModelConfig(){const{shouldLoad:t}=await e.prompt([{type:"list",name:"shouldLoad",message:f.t("wizard.load_config_now"),choices:[{name:f.t("wizard.load_config_yes"),value:!0},{name:f.t("wizard.load_config_later"),value:!1}]}]);t&&await this.selectAndConfigureTool()}async configBaseUrl(){const i=o.getBaseUrl(),n=S(),r=a(f.t("wizard.base_testing")).start(),s=await T(n,{apiKey:K(),samples:3});r.stop();const l=M(s),c=n.map((e,a)=>{const o=e.url===i?t.cyan(` ← ${f.t("base.current_mark")}`):"";return{name:`${e.url} ${t.gray(e.label)} ${A(s[a],a===l)}${o}`,value:e.url}});c.push(new e.Separator,{name:"<- "+f.t("wizard.nav_return"),value:"__back__"});const{url:d}=await this.promptWithHints([{type:"list",name:"url",message:f.t("wizard.base_select"),choices:c,default:i}]);if("__back__"===d)return;const p=s[n.findIndex(e=>e.url===d)];p.ok?await B(d):console.log(t.red(f.t("base.unreachable",{url:d,reason:N(p)}))),await e.prompt([{type:"input",name:"continue",message:f.t("wizard.press_enter")}])}async configApiKey(){for(;;){this.resetScreen(),this.createBox(f.t("wizard.input_api_key")),console.log(t.gray("\n💡 "+f.t("wizard.api_key_input_hint"))),console.log(t.gray(" "+f.t("wizard.api_key_get_hint",{url:W().links.tokenPage}))),console.log();const{apiKey:i}=await e.prompt([{type:"password",name:"apiKey",message:f.t("wizard.input_your_api_key"),mask:"*"}]);if(!i||""===i.trim()){const{action:t}=await e.prompt([{type:"list",name:"action",message:f.t("wizard.select_action"),choices:[{name:f.t("wizard.retry_input"),value:"retry"},{name:"<- "+f.t("wizard.nav_return"),value:"back"}]}]);if("back"===t)return!1;continue}const n=a(f.t("wizard.validating_api_key")).start(),r=await v(i.trim());if(n.stop(),r.valid)return o.setApiKey(i.trim()),this.validatedApiKeys.add(i.trim()),console.log(t.green("\n✓ "+f.t("wizard.api_key_valid"))),!0;{this.validatedApiKeys.delete(i.trim()),"invalid_api_key"===r.error?console.log(t.red("\n✗ "+f.t("wizard.api_key_invalid"))):console.log(t.red("\n✗ "+f.t("wizard.api_key_network_error")));const{action:a}=await e.prompt([{type:"list",name:"action",message:f.t("wizard.select_action"),choices:[{name:f.t("wizard.retry_input"),value:"retry"},{name:"<- "+f.t("wizard.nav_return"),value:"back"}]}]);if("back"===a)return!1}}}async selectAndConfigureTool(a=!1){for(const e of _())await m(e).catch(()=>{});for(;;){this.resetScreen(),this.createBox(f.t("wizard.select_tool"));const o=l.getSupportedTools().map(e=>{const a=_().includes(e.name)?g(e.name):null;return{name:e.displayName+(a?.outdated?t.yellow(" "+u(a)):""),value:e.name}}),{tool:i}=await this.promptWithHints([{type:"list",name:"tool",message:"🛠️ "+f.t("wizard.select_tool"),choices:[...o,new e.Separator,{name:"<- "+f.t("wizard.nav_return"),value:"back"},{name:"x "+f.t("wizard.nav_exit"),value:"exit"}]}]);if("exit"===i)this.printGoodbye(),process.exit(0);else if("back"===i)return;await this.configureTool(i,a)}}async configureTool(a,o=!1){const i=c[a];if(i){if(!l.isToolInstalled(a)){console.log(t.yellow("\n"+f.t("wizard.tool_not_installed",{tool:i.displayName})));const{install:o}=await e.prompt([{type:"confirm",name:"install",message:f.t("wizard.install_tool_confirm"),default:!0}]);if(!o)return;try{await l.installTool(a)}catch{return void console.log(t.red(f.t("wizard.install_failed")))}}o?await this.configureToolModel(a)&&await this.loadConfig(a):await this.showToolMenu(a)}}async showToolMenu(t){for(;;){this.resetScreen();const a=c[t];if(!a)return;this.createBox(a.displayName+" "+f.t("wizard.menu_title"));const o=[{name:"📥 "+f.t("wizard.action_load_config",{tool:a.displayName}),value:"load"},{name:"📤 "+f.t("wizard.action_unload_config",{tool:a.displayName}),value:"unload"}];l.supportsClearPinnedModels(t)&&o.push({name:"🧹 "+f.t("wizard.action_clear_model",{tool:a.displayName}),value:"clear-model"});const i=_().includes(t)?g(t):null;if(i&&!i.blocker&&i.latest&&(i.outdated||!i.installed)){const e=i.installed?f.t("wizard.action_upgrade_app",{tool:a.displayName,current:i.current??"?",latest:i.latest}):f.t("wizard.action_install_app",{tool:a.displayName,latest:i.latest});o.unshift({name:"↑ "+e,value:"upgrade-app"})}o.push({name:"🧨 "+f.t("wizard.action_force_config",{tool:a.displayName}),value:"force"},{name:"↩️ "+f.t("wizard.action_restore_config",{tool:a.displayName}),value:"restore"},new e.Separator,{name:"<- "+f.t("wizard.nav_return"),value:"back"},{name:"x "+f.t("wizard.nav_exit"),value:"exit"});const{action:n}=await this.promptWithHints([{type:"list",name:"action",message:"⚙️ "+f.t("wizard.select_action"),choices:o}]);if("exit"===n)this.printGoodbye(),process.exit(0);else{if("back"===n)return;"load"===n?await this.configureToolModel(t)&&await this.loadConfig(t):"force"===n?await this.forceConfig(t):"unload"===n?await this.unloadConfig(t):"upgrade-app"===n?(await w(t,{install:!0}),await e.prompt([{type:"input",name:"continue",message:f.t("wizard.press_enter")}])):"clear-model"===n?await this.clearPinnedModels(t):"restore"===n&&await this.restoreConfig(t)}}}singleModelOverride(e){const t=e.trim();return/claude/i.test(t)?{opus:t}:{haiku:t,sonnet:t,opus:t,reasoning:t}}hasConfiguredApiKey(){return!!o.getApiKey()?.trim()||o.listToolApiKeys().some(e=>Boolean(o.getApiKeyForTool(e)?.trim()))}async validatedKeyForConfiguration(e){const o=e?.trim();if(!o)return console.log(t.red("\n"+f.t("wizard.api_key_required"))),console.log(t.yellow(f.t("wizard.please_config_api_key_first"))),null;if(this.validatedApiKeys.has(o))return o;const i=a(f.t("wizard.validating_api_key")).start(),n=await v(o);if(n.valid)return this.validatedApiKeys.add(o),i.succeed(f.t("wizard.api_key_valid")),o;this.validatedApiKeys.delete(o);const r="invalid_api_key"===n.error?f.t("wizard.api_key_invalid"):f.t("wizard.api_key_network_error");return i.fail(r),console.log(t.red("\n"+f.t("wizard.please_reconfig_api_key"))),null}async configureToolModel(i){const n=c[i];if(!n)return!1;const l=await this.validatedKeyForConfiguration(o.getApiKeyForTool(i));if(!l)return await e.prompt([{type:"input",name:"continue",message:f.t("wizard.press_enter")}]),!1;const d="claude-code"===i,p=d||"claude-desktop"===i||"agy"===i,m=s(i),u=p||!m?f.t("wizard.model_builtin_default"):m;this.resetScreen(),this.createBox(n.displayName+" · "+f.t("wizard.config_models"));const _=[{name:"✅ "+f.t("wizard.use_default_model",{model:u}),value:{type:"default"}},{name:"🌐 "+f.t("wizard.fetch_models_from_api"),value:{type:"fetch"}},...this.buildPresetChoices(),new e.Separator,{name:"✏️ "+f.t("wizard.input_custom_model"),value:{type:"custom"}},new e.Separator,{name:"<- "+f.t("wizard.nav_return"),value:{type:"back"}}],{choice:g}=await this.promptWithHints([{type:"list",name:"choice",message:f.t("wizard.select_tool_model",{tool:n.displayName}),choices:_}]);if("back"===g.type)return!1;if("default"===g.type)o.setToolModel(i,null);else if("preset"===g.type)o.setToolModel(i,r(g.preset));else if("custom"===g.type){const{model:t}=await e.prompt([{type:"input",name:"model",message:f.t("wizard.input_custom_model"),default:!p&&m?m:void 0}]),a=(t||"").trim();o.setToolModel(i,a?this.singleModelOverride(a):null)}else if("fetch"===g.type){const n=a(f.t("wizard.fetching_models")).start(),r=await k(l);let s;if(n.stop(),r.ok&&r.models.length>0){const{model:t}=await e.prompt([{type:"list",name:"model",message:f.t("wizard.select_fetched_model"),pageSize:20,choices:[...r.models,new e.Separator,{name:"<- "+f.t("wizard.nav_return"),value:"__back__"}]}]);if("__back__"===t)return!1;s=t}else{console.log(t.yellow("\n"+f.t("wizard.fetch_models_failed")));const{model:a}=await e.prompt([{type:"input",name:"model",message:f.t("wizard.input_custom_model"),default:!p&&m?m:void 0}]);s=(a||"").trim()}o.setToolModel(i,s?this.singleModelOverride(s):null)}if("codex"===i){const t=o.getToolSetting(i,x),{enableOneMillionContext:a}=await e.prompt([{type:"confirm",name:"enableOneMillionContext",message:f.t("wizard.codex_enable_1m_context"),default:!1!==t}]);o.setToolSetting(i,x,Boolean(a))}if("claude-desktop"===i){const t=o.getToolSetting(i,b),{hideOfficialLogin:a}=await e.prompt([{type:"confirm",name:"hideOfficialLogin",message:f.t("wizard.desktop_hide_official_login"),default:!1!==t}]);o.setToolSetting(i,b,Boolean(a))}return console.log(t.green("\n✓ "+f.t("wizard.models_saved"))),d&&console.log(t.gray("💡 "+f.t("wizard.claude_model_hint"))),!0}async forceConfig(t){const a=c[t]?.displayName||t,{confirm:o}=await e.prompt([{type:"confirm",name:"confirm",message:f.t("config.confirm_force",{tool:a}),default:!1}]);o&&await this.loadConfig(t,{force:!0})}async loadConfig(i,n={}){const r=o.getModelsForTool(i),s=await this.validatedKeyForConfiguration(o.getApiKeyForTool(i));if(!s)return void await e.prompt([{type:"input",name:"continue",message:f.t("wizard.press_enter")}]);if(!n.force&&!await d([i]))return;const m=a(f.t("wizard.loading_config")).start();try{await l.applyPrivateConfig(i,s,r,n),m.stop(),l.printApplied(i),await p([i],{apps:{install:!1}}),n.force&&console.log(t.yellow(f.t("config.force_done",{tool:c[i]?.displayName||i,name:i})));const a=c[i];a&&!a.gui&&(l.isOnPath(i)&&console.log(t.green("\n"+f.t("wizard.run_tool_hint",{command:a.command}))),this.printPathReloadHint([i]));const{nextAction:o}=await e.prompt([{type:"list",name:"nextAction",message:f.t("wizard.what_next"),choices:[{name:f.t("wizard.exit_and_start"),value:"exit"},{name:f.t("wizard.continue_config"),value:"continue"}]}]);"exit"===o&&(this.printGoodbye(),process.exit(0))}catch(a){m.fail(f.t("wizard.config_failed")),console.log(t.red(a instanceof Error?a.message:String(a))),await e.prompt([{type:"input",name:"continue",message:f.t("wizard.press_enter")}])}}async clearPinnedModels(a){const o=c[a]?.displayName||a,{confirm:i}=await e.prompt([{type:"confirm",name:"confirm",message:f.t("wizard.confirm_clear_model",{tool:o}),default:!1}]);if(i){try{const e=await l.clearPinnedModels(a);0===e.length?console.log(t.yellow("\n"+f.t("config.clear_model_none",{tool:o}))):(console.log(t.green("\n✓ "+f.t("config.clear_model_done",{tool:o}))),e.forEach(e=>console.log(t.gray(` - ${e}`))),console.log(t.gray(f.t("config.clear_model_restart_hint",{tool:o}))))}catch(e){console.log(t.red("\n"+(e instanceof Error?e.message:String(e))))}await e.prompt([{type:"input",name:"continue",message:f.t("wizard.press_enter")}])}}async unloadConfig(o){const{confirm:i}=await e.prompt([{type:"confirm",name:"confirm",message:f.t("wizard.confirm_unload_config",{tool:c[o]?.displayName||o}),default:!1}]);if(!i)return;const n=a(f.t("wizard.unloading_config")).start();try{const a=l.holdsOurConfig(o),i=l.unloadPrivateConfig(o);if(!a)return void n.info(f.t("config.remove_nothing",{tool:c[o]?.displayName||o}));n.succeed(f.t("wizard.config_unloaded")),i.forEach(e=>console.log(t.yellow(" ! "+e.text)));const{nextAction:r}=await e.prompt([{type:"list",name:"nextAction",message:f.t("wizard.what_next"),choices:[{name:f.t("wizard.nav_exit"),value:"exit"},{name:f.t("wizard.continue_config"),value:"continue"}]}]);"exit"===r&&(this.printGoodbye(),process.exit(0))}catch(a){n.fail(f.t("wizard.config_unload_failed")),console.log(t.red(a instanceof Error?a.message:String(a))),await e.prompt([{type:"input",name:"continue",message:f.t("wizard.press_enter")}])}}async restoreConfig(o){const i=c[o]?.displayName||o,{confirm:n}=await e.prompt([{type:"confirm",name:"confirm",message:f.t("wizard.confirm_restore_config",{tool:i}),default:!1}]);if(!n)return;const r=a(f.t("wizard.restoring_config")).start();try{const e=l.restorePrivateConfig(o).filter(e=>e.result.restored);0===e.length?r.warn(f.t("wizard.restore_no_backup")):(r.succeed(f.t("wizard.config_restored",{tool:i})),e.forEach(e=>console.log(t.gray(` ${e.file} ← ${e.result.from}`))),console.log(t.yellow(" ! "+f.t("config.reopen_hint",{tool:i}))))}catch(e){r.fail(f.t("wizard.config_restore_failed")),console.log(t.red(e instanceof Error?e.message:String(e)))}await e.prompt([{type:"input",name:"continue",message:f.t("wizard.press_enter")}])}async run(){await this.showMainMenu()}async showMainMenu(){if(this.hasConfiguredApiKey())for(;;){this.resetScreen();const a=o.getApiKey()||"",i=a.length>4?"sk-****"+a.slice(-4):"****";console.log(t.gray(` 🔑 API Key: ${i}`)+t.green(" ✓")),console.log("");const n=l.getSupportedTools().map(e=>({name:"🛠️ "+e.displayName,value:{type:"tool",tool:e.name}})),r=[new e.Separator(F("── "+f.t("wizard.select_tool")+" ──")),...n,new e.Separator(t.gray("── "+f.t("wizard.settings")+" ──")),{name:"🔑 "+f.t("wizard.menu_change_api_key"),value:{type:"apikey"}},{name:"🔗 "+f.t("wizard.menu_base_url",{url:o.getBaseUrl()}),value:{type:"base"}},{name:"🌐 "+f.t("wizard.menu_config_language"),value:{type:"language"}},new e.Separator,{name:"x "+f.t("wizard.nav_exit"),value:{type:"exit"}}],{action:s}=await this.promptWithHints([{type:"list",name:"action",message:"🛠️ "+f.t("wizard.select_tool"),choices:r}]);"exit"===s.type?(this.printGoodbye(),process.exit(0)):"tool"===s.type?await this.configureTool(s.tool):"apikey"===s.type?await this.configApiKey():"base"===s.type?await this.configBaseUrl():"language"===s.type&&await this.configLanguage()}else await this.runFirstTimeSetup()}}export const wizard=Wizard.getInstance();
|
package/dist/locales/en_US.json
CHANGED
|
@@ -119,7 +119,9 @@
|
|
|
119
119
|
"action_force_config": "Reset to recommended: delete {{tool}}'s config files and rewrite them, to repair a broken config",
|
|
120
120
|
"menu_base_url": "Switch gateway address (current: {{url}})",
|
|
121
121
|
"base_testing": "Testing the gateway addresses…",
|
|
122
|
-
"base_select": "Pick a gateway address (configured tools switch with it)"
|
|
122
|
+
"base_select": "Pick a gateway address (configured tools switch with it)",
|
|
123
|
+
"action_upgrade_app": "Upgrade {{tool}} ({{current}} installed, {{latest}} available)",
|
|
124
|
+
"action_install_app": "Install {{tool}} {{latest}}"
|
|
123
125
|
},
|
|
124
126
|
"doctor": {
|
|
125
127
|
"checking": "Running checks…",
|
|
@@ -169,7 +171,9 @@
|
|
|
169
171
|
"report_uploading": "Uploading diagnostics…",
|
|
170
172
|
"report_done": "Diagnostic code: {{code}} (give it to support; they can see these results and recent run history with it)",
|
|
171
173
|
"report_failed": "Couldn't upload the diagnostics. Send support a screenshot of the results above, and run {{cli}} doctor --report again once the network is back",
|
|
172
|
-
"report_hint": "When you need help from support, run {{cli}} doctor --report and give them the diagnostic code"
|
|
174
|
+
"report_hint": "When you need help from support, run {{cli}} doctor --report and give them the diagnostic code",
|
|
175
|
+
"app_version": "{{tool}} version",
|
|
176
|
+
"run_app_upgrade": "Run {{command}}"
|
|
173
177
|
},
|
|
174
178
|
"status": {
|
|
175
179
|
"title": "Current Status",
|
|
@@ -361,7 +365,9 @@
|
|
|
361
365
|
"list_separator": ", ",
|
|
362
366
|
"gui_preconfigured": "{{tool}} is not installed yet; its config is written already, so it works once you install and open it (download: {{install}})",
|
|
363
367
|
"validate_failed": "Couldn't validate the API key for {{label}}: {{reason}}",
|
|
364
|
-
"skip_no_claude_desktop": "This API key has no Claude model group; skipped Claude Code and Claude Desktop"
|
|
368
|
+
"skip_no_claude_desktop": "This API key has no Claude model group; skipped Claude Code and Claude Desktop",
|
|
369
|
+
"install_app_confirm": "Install {{tools}}? (about 300 MB from the download site)",
|
|
370
|
+
"install_app_hint": "{{tool}} isn't installed: run {{command}} to install it (its config is ready, so it works once opened)"
|
|
365
371
|
},
|
|
366
372
|
"tools": {
|
|
367
373
|
"version_outdated": "version {{current}} is too old (needs {{min}} or later); upgrade with {{upgrade}}",
|
|
@@ -846,15 +852,16 @@
|
|
|
846
852
|
}
|
|
847
853
|
},
|
|
848
854
|
"upgrade": {
|
|
849
|
-
"summary": "Upgrade Claude Code, Codex and other coding tools",
|
|
850
|
-
"description": "Upgrades each copy the way it was installed: native installs use the tool's own updater, npm installs are reinstalled from the China mirror (npmmirror), Homebrew installs use brew upgrade; if a native or Homebrew upgrade doesn't work, {{brand}}'s install script is used (programs from the China mirror). A named tool that is not installed yet is installed with that script.\nWith no tool named, upgrades every installed one.\nTo update {{product}} itself, use {{cli}} update.",
|
|
855
|
+
"summary": "Upgrade Claude Code, Codex, Claude Desktop and other coding tools",
|
|
856
|
+
"description": "Upgrades each copy the way it was installed: native installs use the tool's own updater, npm installs are reinstalled from the China mirror (npmmirror), Homebrew installs use brew upgrade; if a native or Homebrew upgrade doesn't work, {{brand}}'s install script is used (programs from the China mirror). A named tool that is not installed yet is installed with that script.\nClaude Desktop (macOS / Windows) older than the download site's build is upgraded from the official installer there, after checking its checksum and Anthropic's signature; its own auto-update stays on, {{cli}} only steps in when it falls behind. A running Claude Desktop is only closed after a yes at a terminal; with --yes or without a terminal it is left running and only a hint is printed.\nWith no tool named, upgrades every installed one.\nTo update {{product}} itself, use {{cli}} update.",
|
|
851
857
|
"arg": {
|
|
852
|
-
"tools": "claude-code, codex, grok, agy; one or more"
|
|
858
|
+
"tools": "claude-code, codex, grok, agy, claude-desktop; one or more"
|
|
853
859
|
},
|
|
854
860
|
"ex": {
|
|
855
861
|
"all": "Upgrade every installed tool",
|
|
856
862
|
"one": "Upgrade only Claude Code",
|
|
857
|
-
"many": "Upgrade Codex and Antigravity CLI"
|
|
863
|
+
"many": "Upgrade Codex and Antigravity CLI",
|
|
864
|
+
"desktop": "Install Claude Desktop, or upgrade it to the download site's latest build"
|
|
858
865
|
},
|
|
859
866
|
"when": "When {{cli}} doctor reports an old version, or the tool's own updater doesn't finish.",
|
|
860
867
|
"needs": "Without tool names, only installed tools are upgraded",
|
|
@@ -1049,5 +1056,39 @@
|
|
|
1049
1056
|
"rejected": "the gateway rejected it; it may have been deleted, disabled or expired",
|
|
1050
1057
|
"timeout": "the request timed out",
|
|
1051
1058
|
"network": "couldn't connect to the gateway"
|
|
1059
|
+
},
|
|
1060
|
+
"app_update": {
|
|
1061
|
+
"not_installed": "not installed; the download site has {{latest}}",
|
|
1062
|
+
"outdated": "{{current}} installed, {{latest}} available",
|
|
1063
|
+
"up_to_date": "{{current}} (latest)",
|
|
1064
|
+
"downloading": "Downloading {{tool}} {{version}} from the download site (about 300 MB)…",
|
|
1065
|
+
"verifying": "Checking the checksum and Anthropic's signature…",
|
|
1066
|
+
"installing": "Installing…",
|
|
1067
|
+
"already_latest": "{{tool}} is up to date ({{current}})",
|
|
1068
|
+
"latest_unknown": "Couldn't look up the latest {{tool}}: {{reason}}",
|
|
1069
|
+
"running_hint": "{{tool}} is running, so it wasn't upgraded: quit {{tool}}, then run {{command}}",
|
|
1070
|
+
"offer_quit": "Quit {{tool}} and upgrade to {{latest}}?",
|
|
1071
|
+
"declined_hint": "Not upgraded. Run {{command}} later",
|
|
1072
|
+
"quit_failed": "Couldn't quit {{tool}}, so it wasn't upgraded: quit it yourself, then run {{command}}",
|
|
1073
|
+
"upgraded": "Upgraded {{tool}} from {{from}} to {{to}}",
|
|
1074
|
+
"installed": "Installed {{tool}} {{version}}",
|
|
1075
|
+
"upgrade_failed": "Couldn't upgrade {{tool}}: {{reason}}. {{current}} still works; fix the cause, then run {{command}}",
|
|
1076
|
+
"install_failed": "Couldn't install {{tool}}: {{reason}}. Fix the cause, then run {{command}}",
|
|
1077
|
+
"blocked_unsupported_platform": "On this computer, install {{tool}} from https://claude.ai/download",
|
|
1078
|
+
"blocked_no_mirror": "Install {{tool}} from https://claude.ai/download",
|
|
1079
|
+
"blocked_classic_install": "This computer has the classic installer build of {{tool}}, which {{cli}} doesn't replace: check for updates in {{tool}}, or uninstall it and run {{cli}} upgrade claude-desktop to get the current build",
|
|
1080
|
+
"reason_unsupported_platform": "there is no installer for this system",
|
|
1081
|
+
"reason_no_mirror": "no download site is configured",
|
|
1082
|
+
"reason_classic_install": "the classic installer build is installed",
|
|
1083
|
+
"error_blocked": "{{reason}}",
|
|
1084
|
+
"error_download": "download failed ({{reason}})",
|
|
1085
|
+
"error_no_checksum": "the download site has no checksum for {{file}}",
|
|
1086
|
+
"error_checksum": "{{file}} has the wrong checksum (expected {{expected}}…, got {{actual}}…); the download was deleted",
|
|
1087
|
+
"error_signature": "the package isn't signed by Anthropic or the signature is broken ({{reason}}); nothing was installed",
|
|
1088
|
+
"error_mount": "couldn't open the package ({{reason}})",
|
|
1089
|
+
"error_bad_package": "the package has no {{reason}}",
|
|
1090
|
+
"error_no_permission": "no permission to write {{path}}: run as an administrator, or give {{path}} to this user",
|
|
1091
|
+
"error_copy": "copying the app failed ({{reason}})",
|
|
1092
|
+
"error_install": "the system installer failed ({{reason}})"
|
|
1052
1093
|
}
|
|
1053
1094
|
}
|
package/dist/locales/zh_CN.json
CHANGED
|
@@ -119,7 +119,9 @@
|
|
|
119
119
|
"action_force_config": "重置为推荐配置:删除 {{tool}} 原有配置文件后整份重写,用于修复改坏的配置",
|
|
120
120
|
"menu_base_url": "切换接入地址(当前:{{url}})",
|
|
121
121
|
"base_testing": "正在测试各个接入地址…",
|
|
122
|
-
"base_select": "选择接入地址(已配置的工具会一起切换)"
|
|
122
|
+
"base_select": "选择接入地址(已配置的工具会一起切换)",
|
|
123
|
+
"action_upgrade_app": "升级 {{tool}}(当前 {{current}},可升到 {{latest}})",
|
|
124
|
+
"action_install_app": "安装 {{tool}} {{latest}}"
|
|
123
125
|
},
|
|
124
126
|
"doctor": {
|
|
125
127
|
"checking": "正在检查…",
|
|
@@ -169,7 +171,9 @@
|
|
|
169
171
|
"report_uploading": "正在上传诊断信息…",
|
|
170
172
|
"report_done": "诊断码:{{code}}(把它发给客服,客服就能看到这次检查的结果和最近的运行记录)",
|
|
171
173
|
"report_failed": "无法上传诊断信息。可以把上面的结果截图发给客服,网络恢复后再运行 {{cli}} doctor --report",
|
|
172
|
-
"report_hint": "需要客服帮助时,运行 {{cli}} doctor --report,把得到的诊断码发给客服"
|
|
174
|
+
"report_hint": "需要客服帮助时,运行 {{cli}} doctor --report,把得到的诊断码发给客服",
|
|
175
|
+
"app_version": "{{tool}} 版本",
|
|
176
|
+
"run_app_upgrade": "运行 {{command}}"
|
|
173
177
|
},
|
|
174
178
|
"status": {
|
|
175
179
|
"title": "当前状态",
|
|
@@ -361,7 +365,9 @@
|
|
|
361
365
|
"list_separator": "、",
|
|
362
366
|
"gui_preconfigured": "{{tool}} 还没有安装,已提前写好配置,安装后打开即可使用(下载:{{install}})",
|
|
363
367
|
"validate_failed": "无法验证 {{label}} 的令牌:{{reason}}",
|
|
364
|
-
"skip_no_claude_desktop": "这个令牌没有开通 Claude 模型分组,已跳过 Claude Code 和 Claude Desktop"
|
|
368
|
+
"skip_no_claude_desktop": "这个令牌没有开通 Claude 模型分组,已跳过 Claude Code 和 Claude Desktop",
|
|
369
|
+
"install_app_confirm": "安装 {{tools}}?(从高速下载站下载约 300 MB)",
|
|
370
|
+
"install_app_hint": "没装 {{tool}}:要安装就运行 {{command}}(已写好配置,装好打开就能用)"
|
|
365
371
|
},
|
|
366
372
|
"tools": {
|
|
367
373
|
"version_outdated": "版本 {{current}} 过旧,需要 {{min}} 或更高版本,运行 {{upgrade}} 升级",
|
|
@@ -846,15 +852,16 @@
|
|
|
846
852
|
}
|
|
847
853
|
},
|
|
848
854
|
"upgrade": {
|
|
849
|
-
"summary": "升级 Claude Code、Codex 等编码工具",
|
|
850
|
-
"description": "按每份工具当初的安装方式升级:原生安装用工具自带的更新,npm 安装从国内镜像(npmmirror)重新安装,Homebrew 安装用 brew upgrade;原生或 Homebrew 方式无法升级时,改用 {{brand}} 一键安装脚本(程序取自国内镜像)。指定了但还没有安装的工具,也用这个脚本安装。\n不填工具名则升级已安装的全部工具。\n升级 {{product}} 本身请用 {{cli}} update。",
|
|
855
|
+
"summary": "升级 Claude Code、Codex、Claude Desktop 等编码工具",
|
|
856
|
+
"description": "按每份工具当初的安装方式升级:原生安装用工具自带的更新,npm 安装从国内镜像(npmmirror)重新安装,Homebrew 安装用 brew upgrade;原生或 Homebrew 方式无法升级时,改用 {{brand}} 一键安装脚本(程序取自国内镜像)。指定了但还没有安装的工具,也用这个脚本安装。\nClaude Desktop(macOS / Windows)比高速下载站上的版本旧时,从高速下载站下载官方安装包,核对校验值和 Anthropic 的签名后安装;它自带的自动更新照常开着,{{cli}} 只在它没跟上时补上。Claude Desktop 正在运行时,在终端里问过才关掉它升级,带 --yes 或没有终端时只提示、不关。\n不填工具名则升级已安装的全部工具。\n升级 {{product}} 本身请用 {{cli}} update。",
|
|
851
857
|
"arg": {
|
|
852
|
-
"tools": "claude-code、codex、grok、agy,可以填写多个"
|
|
858
|
+
"tools": "claude-code、codex、grok、agy、claude-desktop,可以填写多个"
|
|
853
859
|
},
|
|
854
860
|
"ex": {
|
|
855
861
|
"all": "升级已安装的全部工具",
|
|
856
862
|
"one": "只升级 Claude Code",
|
|
857
|
-
"many": "升级 Codex 和 Antigravity CLI"
|
|
863
|
+
"many": "升级 Codex 和 Antigravity CLI",
|
|
864
|
+
"desktop": "安装 Claude Desktop,或升到高速下载站上的最新版"
|
|
858
865
|
},
|
|
859
866
|
"when": "{{cli}} doctor 提示版本过低,或工具自带的更新无法完成时。",
|
|
860
867
|
"needs": "不填工具名时,只升级已经安装的工具",
|
|
@@ -1049,5 +1056,39 @@
|
|
|
1049
1056
|
"rejected": "网关拒绝了这个令牌,它可能已被删除、停用或已过期",
|
|
1050
1057
|
"timeout": "请求超时",
|
|
1051
1058
|
"network": "无法连接网关"
|
|
1059
|
+
},
|
|
1060
|
+
"app_update": {
|
|
1061
|
+
"not_installed": "没有安装,高速下载站上最新是 {{latest}}",
|
|
1062
|
+
"outdated": "当前 {{current}},可升到 {{latest}}",
|
|
1063
|
+
"up_to_date": "{{current}}(已是最新)",
|
|
1064
|
+
"downloading": "正在从高速下载站下载 {{tool}} {{version}}(约 300 MB)…",
|
|
1065
|
+
"verifying": "正在核对校验值和 Anthropic 的签名…",
|
|
1066
|
+
"installing": "正在安装…",
|
|
1067
|
+
"already_latest": "{{tool}} 已是最新({{current}})",
|
|
1068
|
+
"latest_unknown": "无法查到 {{tool}} 的最新版本:{{reason}}",
|
|
1069
|
+
"running_hint": "{{tool}} 正在运行,这次没有升级:退出 {{tool}} 后运行 {{command}}",
|
|
1070
|
+
"offer_quit": "关掉 {{tool}} 并升到 {{latest}}?",
|
|
1071
|
+
"declined_hint": "没有升级。之后可以运行 {{command}}",
|
|
1072
|
+
"quit_failed": "无法退出 {{tool}},这次没有升级:手动退出后运行 {{command}}",
|
|
1073
|
+
"upgraded": "已把 {{tool}} 从 {{from}} 升到 {{to}}",
|
|
1074
|
+
"installed": "已安装 {{tool}} {{version}}",
|
|
1075
|
+
"upgrade_failed": "无法升级 {{tool}}:{{reason}}。当前的 {{current}} 照常可用;排除原因后运行 {{command}}",
|
|
1076
|
+
"install_failed": "无法安装 {{tool}}:{{reason}}。排除原因后运行 {{command}}",
|
|
1077
|
+
"blocked_unsupported_platform": "这台电脑的 {{tool}} 要从官网下载安装:https://claude.ai/download",
|
|
1078
|
+
"blocked_no_mirror": "{{tool}} 要从官网下载安装:https://claude.ai/download",
|
|
1079
|
+
"blocked_classic_install": "这台电脑装的是旧式安装版 {{tool}},{{cli}} 不替换它:在 {{tool}} 里检查更新,或卸载后运行 {{cli}} upgrade claude-desktop 装新版",
|
|
1080
|
+
"reason_unsupported_platform": "这个系统没有可用的安装包",
|
|
1081
|
+
"reason_no_mirror": "没有配置高速下载站",
|
|
1082
|
+
"reason_classic_install": "装的是旧式安装版",
|
|
1083
|
+
"error_blocked": "{{reason}}",
|
|
1084
|
+
"error_download": "下载失败({{reason}})",
|
|
1085
|
+
"error_no_checksum": "高速下载站上没有 {{file}} 的校验值",
|
|
1086
|
+
"error_checksum": "{{file}} 的校验值不对(应为 {{expected}}…,实际 {{actual}}…),下载的文件已删除",
|
|
1087
|
+
"error_signature": "安装包的签名不是 Anthropic 的或已损坏({{reason}}),没有安装",
|
|
1088
|
+
"error_mount": "无法打开安装包({{reason}})",
|
|
1089
|
+
"error_bad_package": "安装包里缺少 {{reason}}",
|
|
1090
|
+
"error_no_permission": "没有权限写入 {{path}}:用管理员账号运行,或把 {{path}} 交给当前用户",
|
|
1091
|
+
"error_copy": "复制应用失败({{reason}})",
|
|
1092
|
+
"error_install": "系统安装失败({{reason}})"
|
|
1052
1093
|
}
|
|
1053
1094
|
}
|