@xship/cli 0.0.146 → 0.0.148
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 +19 -19
- package/dist/client-config.snapshot.json +19 -19
- 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/codex-sessions.js +1 -1
- package/dist/lib/i18n.js +1 -1
- package/dist/lib/post-apply.js +1 -1
- package/dist/lib/powershell-env.js +1 -0
- package/dist/lib/program.js +1 -1
- package/dist/lib/tool-manager.js +1 -1
- package/dist/lib/tool-upgrade.js +1 -1
- package/dist/lib/tools/chatgpt-desktop.js +1 -0
- package/dist/lib/tools/claude-desktop-app.js +1 -0
- package/dist/lib/tools/claude-desktop-cli.js +1 -1
- package/dist/lib/tools/claude-desktop.js +1 -1
- package/dist/lib/tools/codex.js +1 -1
- package/dist/lib/tools/desktop-app-installer.js +1 -0
- package/dist/lib/tools/desktop-process.js +1 -1
- package/dist/lib/tools/elevated-reg.js +1 -1
- package/dist/lib/windows-env.js +1 -1
- package/dist/lib/wizard.js +1 -1
- package/dist/locales/en_US.json +69 -7
- package/dist/locales/zh_CN.json +69 -7
- package/package.json +1 -1
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
"description": "100 万上下文 | 12.8 万输出 | 自适应思考常开 | 长时 Agent 与多步研究",
|
|
22
|
-
"group": "
|
|
22
|
+
"group": "grp_pzxnceygmqlp",
|
|
23
23
|
"group_name": "",
|
|
24
24
|
"hidden": false,
|
|
25
25
|
"id": "claude-fable-5-1",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
{
|
|
30
30
|
"description": "轻量档 | 低延迟 | 高频短任务",
|
|
31
|
-
"group": "
|
|
31
|
+
"group": "grp_pzxnceygmqlp",
|
|
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_6co8aqwefsoh",
|
|
41
41
|
"group_name": "",
|
|
42
42
|
"hidden": false,
|
|
43
43
|
"id": "claude-haiku-5-5",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
"description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
|
|
49
|
-
"group": "
|
|
49
|
+
"group": "grp_6eg2dq9ywgrg",
|
|
50
50
|
"group_name": "",
|
|
51
51
|
"hidden": false,
|
|
52
52
|
"id": "claude-opus-4-6",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
66
|
"description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
|
|
67
|
-
"group": "
|
|
67
|
+
"group": "grp_pzxnceygmqlp",
|
|
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_6eg2dq9ywgrg",
|
|
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_rld6af0zorqd",
|
|
95
95
|
"group_name": "",
|
|
96
96
|
"hidden": false,
|
|
97
97
|
"id": "claude-sonnet-4-6",
|
|
@@ -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_mb5v069lpnze",
|
|
124
124
|
"group_name": "",
|
|
125
125
|
"hidden": false,
|
|
126
126
|
"id": "gpt-5.6-luna",
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
},
|
|
130
130
|
{
|
|
131
131
|
"description": "105 万上下文 | 12.8 万输出 | 前沿档",
|
|
132
|
-
"group": "
|
|
132
|
+
"group": "grp_bsbtt432saoq",
|
|
133
133
|
"group_name": "",
|
|
134
134
|
"hidden": false,
|
|
135
135
|
"id": "gpt-5.6-sol",
|
|
@@ -147,7 +147,7 @@
|
|
|
147
147
|
},
|
|
148
148
|
{
|
|
149
149
|
"description": "105 万上下文 | 12.8 万输出 | 思考强度至 max | 计算机操作 / 编码 / 科学基准接近饱和",
|
|
150
|
-
"group": "
|
|
150
|
+
"group": "grp_squ2qzjnehps",
|
|
151
151
|
"group_name": "",
|
|
152
152
|
"hidden": false,
|
|
153
153
|
"id": "gpt-6-astra",
|
|
@@ -165,7 +165,7 @@
|
|
|
165
165
|
},
|
|
166
166
|
{
|
|
167
167
|
"description": "105 万上下文 | 12.8 万输出 | 复杂编程与 Agent 工作流",
|
|
168
|
-
"group": "
|
|
168
|
+
"group": "grp_6co8aqwefsoh",
|
|
169
169
|
"group_name": "",
|
|
170
170
|
"hidden": false,
|
|
171
171
|
"id": "gpt-6-sol",
|
|
@@ -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",
|
|
@@ -203,7 +203,7 @@
|
|
|
203
203
|
},
|
|
204
204
|
{
|
|
205
205
|
"description": "约 100 万上下文 | 深度推理 | 长文档一致性",
|
|
206
|
-
"group": "
|
|
206
|
+
"group": "grp_z5khwusxuh2j",
|
|
207
207
|
"group_name": "",
|
|
208
208
|
"hidden": false,
|
|
209
209
|
"id": "gemini-3-pro",
|
|
@@ -230,7 +230,7 @@
|
|
|
230
230
|
},
|
|
231
231
|
{
|
|
232
232
|
"description": "Gemini 3.1 Pro 预览版 | 约 100 万上下文 | 深度推理 | 文本、图像、音视频输入",
|
|
233
|
-
"group": "
|
|
233
|
+
"group": "grp_z5khwusxuh2j",
|
|
234
234
|
"group_name": "",
|
|
235
235
|
"hidden": false,
|
|
236
236
|
"id": "gemini-3.1-pro-preview",
|
|
@@ -248,7 +248,7 @@
|
|
|
248
248
|
},
|
|
249
249
|
{
|
|
250
250
|
"description": "约 208 token/秒 | 高吞吐 | 多语言 | 编码",
|
|
251
|
-
"group": "
|
|
251
|
+
"group": "grp_3pi5kyqkp51b",
|
|
252
252
|
"group_name": "",
|
|
253
253
|
"hidden": false,
|
|
254
254
|
"id": "gemini-3.6-flash",
|
|
@@ -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",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
"description": "100 万上下文 | 12.8 万输出 | 自适应思考常开 | 长时 Agent 与多步研究",
|
|
22
|
-
"group": "
|
|
22
|
+
"group": "grp_pzxnceygmqlp",
|
|
23
23
|
"group_name": "",
|
|
24
24
|
"hidden": false,
|
|
25
25
|
"id": "claude-fable-5-1",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
{
|
|
30
30
|
"description": "轻量档 | 低延迟 | 高频短任务",
|
|
31
|
-
"group": "
|
|
31
|
+
"group": "grp_pzxnceygmqlp",
|
|
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_6co8aqwefsoh",
|
|
41
41
|
"group_name": "",
|
|
42
42
|
"hidden": false,
|
|
43
43
|
"id": "claude-haiku-5-5",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
"description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
|
|
49
|
-
"group": "
|
|
49
|
+
"group": "grp_6eg2dq9ywgrg",
|
|
50
50
|
"group_name": "",
|
|
51
51
|
"hidden": false,
|
|
52
52
|
"id": "claude-opus-4-6",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
66
|
"description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
|
|
67
|
-
"group": "
|
|
67
|
+
"group": "grp_pzxnceygmqlp",
|
|
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_6eg2dq9ywgrg",
|
|
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_rld6af0zorqd",
|
|
95
95
|
"group_name": "",
|
|
96
96
|
"hidden": false,
|
|
97
97
|
"id": "claude-sonnet-4-6",
|
|
@@ -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_mb5v069lpnze",
|
|
124
124
|
"group_name": "",
|
|
125
125
|
"hidden": false,
|
|
126
126
|
"id": "gpt-5.6-luna",
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
},
|
|
130
130
|
{
|
|
131
131
|
"description": "105 万上下文 | 12.8 万输出 | 前沿档",
|
|
132
|
-
"group": "
|
|
132
|
+
"group": "grp_bsbtt432saoq",
|
|
133
133
|
"group_name": "",
|
|
134
134
|
"hidden": false,
|
|
135
135
|
"id": "gpt-5.6-sol",
|
|
@@ -147,7 +147,7 @@
|
|
|
147
147
|
},
|
|
148
148
|
{
|
|
149
149
|
"description": "105 万上下文 | 12.8 万输出 | 思考强度至 max | 计算机操作 / 编码 / 科学基准接近饱和",
|
|
150
|
-
"group": "
|
|
150
|
+
"group": "grp_squ2qzjnehps",
|
|
151
151
|
"group_name": "",
|
|
152
152
|
"hidden": false,
|
|
153
153
|
"id": "gpt-6-astra",
|
|
@@ -165,7 +165,7 @@
|
|
|
165
165
|
},
|
|
166
166
|
{
|
|
167
167
|
"description": "105 万上下文 | 12.8 万输出 | 复杂编程与 Agent 工作流",
|
|
168
|
-
"group": "
|
|
168
|
+
"group": "grp_6co8aqwefsoh",
|
|
169
169
|
"group_name": "",
|
|
170
170
|
"hidden": false,
|
|
171
171
|
"id": "gpt-6-sol",
|
|
@@ -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",
|
|
@@ -203,7 +203,7 @@
|
|
|
203
203
|
},
|
|
204
204
|
{
|
|
205
205
|
"description": "约 100 万上下文 | 深度推理 | 长文档一致性",
|
|
206
|
-
"group": "
|
|
206
|
+
"group": "grp_z5khwusxuh2j",
|
|
207
207
|
"group_name": "",
|
|
208
208
|
"hidden": false,
|
|
209
209
|
"id": "gemini-3-pro",
|
|
@@ -230,7 +230,7 @@
|
|
|
230
230
|
},
|
|
231
231
|
{
|
|
232
232
|
"description": "Gemini 3.1 Pro 预览版 | 约 100 万上下文 | 深度推理 | 文本、图像、音视频输入",
|
|
233
|
-
"group": "
|
|
233
|
+
"group": "grp_z5khwusxuh2j",
|
|
234
234
|
"group_name": "",
|
|
235
235
|
"hidden": false,
|
|
236
236
|
"id": "gemini-3.1-pro-preview",
|
|
@@ -248,7 +248,7 @@
|
|
|
248
248
|
},
|
|
249
249
|
{
|
|
250
250
|
"description": "约 208 token/秒 | 高吞吐 | 多语言 | 编码",
|
|
251
|
-
"group": "
|
|
251
|
+
"group": "grp_3pi5kyqkp51b",
|
|
252
252
|
"group_name": "",
|
|
253
253
|
"hidden": false,
|
|
254
254
|
"id": "gemini-3.6-flash",
|
|
@@ -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",
|
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 i}from"net";import{join as c}from"path";import{configManager as l}from"../lib/config.js";import{savedApiKey as d}from"./base.js";import{toolManager as p}from"../lib/tool-manager.js";import{i18n as u}from"../lib/i18n.js";import{validateApiKey as m}from"../lib/api-validator.js";import{getAdapter as f}from"../lib/tools/registry.js";import{findInstalls as _,installLabel as g}from"../lib/tools/tool-installs.js";import{detectManagedOverrides as h}from"../lib/tools/claude-managed.js";import{codexAuthProblem as y,codexCatalogRejection as k,codexConfigPath as w,codexWorkModeOn as b}from"../lib/tools/codex.js";import{claudeAccountLoginPresent as v}from"../lib/tools/claude-code.js";import{toolHome as j}from"../lib/tools/types.js";import{gatewayAddresses as x,probeGatewayAddress as $}from"../lib/gateway-addresses.js";import{listAdapters as T}from"../lib/tools/registry.js";import{logger as A}from"../utils/logger.js";import{maskHome as P,maskSecrets as R,uploadReport as N}from"../lib/telemetry.js";import{CLI_NAME as O}from"../lib/brand.js";import{balanceLookupEnabled as C,balanceNeedsAttention as I,balanceText as H,fetchKeyBalances as L}from"../lib/key-balance.js";const S=["HTTPS_PROXY","https_proxy","HTTP_PROXY","http_proxy","ALL_PROXY","all_proxy"];function U(o,t,e=3e3){return new Promise(s=>{const r=i({host:o,port:t}),n=o=>{r.destroy(),s(o)};r.setTimeout(e,()=>n(!1)),r.once("connect",()=>n(!0)),r.once("error",()=>n(!1))})}function E(){const o=A.getLogDir();if(!r(o))return"";const t=n(o).filter(o=>/^\d{4}-\d{2}-\d{2}\.log$/.test(o)).sort().slice(-2).map(t=>`== ${t}\n`+a(c(o,t),"utf-8")).join("\n");return R(t.slice(-15e4))}function K(){const o={};for(const t of S){const e=process.env[t]?.trim();if(e)try{const s=new URL(e.includes("://")?e:`http://${e}`);o[t]=`${s.protocol}//${s.host}`}catch{o[t]="(unparsable)"}}return o}export async function doctorCommand(r={}){const n=e(u.t("doctor.checking")).start(),i=[],A=Number(process.versions.node.split(".")[0]);i.push({name:"Node.js",status:A>=20?"pass":"fail",message:`v${process.versions.node}`}),n.text=u.t("doctor.check_proxy"),i.push(await async function(){const o=u.t("doctor.proxy"),t=new Map;for(const o of S){const e=process.env[o]?.trim();e&&!t.has(e)&&t.set(e,o)}if(0===t.size)return{name:o,status:"pass",message:u.t("doctor.proxy_none")};const e=[];for(const[o,s]of t){let t;try{t=new URL(o.includes("://")?o:`http://${o}`)}catch{e.push(`${s}=${o}`);continue}const r=Number(t.port)||("https:"===t.protocol?443:t.protocol.startsWith("socks")?1080:80);await U(t.hostname,r)||e.push(`${s}=${o}`)}return 0===e.length?{name:o,status:"pass",message:[...t.keys()].join(", ")}:{name:o,status:"fail",message:u.t("doctor.proxy_dead",{proxies:e.join(", ")})}}()),n.text=u.t("doctor.check_api_key_network");const R=d(),B=u.t("doctor.api_key_network");if(R){const o=await m(R);o.valid?(i.push({name:B,status:"pass"}),n.text=u.t("doctor.check_balance"),i.push(...await async function(o){if(!C())return[];const t=l.listToolApiKeys().map(o=>({tool:o,key:l.getApiKeyForTool(o)})).filter(t=>Boolean(t.key)&&t.key!==o),e=await L([o,...t.map(o=>o.key)]),s=[{name:u.t("doctor.balance"),key:o},...t.map(o=>({name:u.t("doctor.balance_tool",{tool:f(o.tool)?.displayName??o.tool}),key:o.key}))],r=[];for(const o of s){const t=e.get(o.key);t&&r.push({name:o.name,status:I(t)?"warn":"pass",message:H(t)})}return r}(R))):"invalid_api_key"===o.error?i.push({name:B,status:"fail",message:u.t("doctor.api_key_invalid")}):(i.push({name:B,status:"fail",message:`${u.t("doctor.network_error")}: ${o.message??o.error}`}),n.text=u.t("doctor.check_other_addresses"),i.push(await async function(){const o=u.t("doctor.other_addresses"),t=l.getBaseUrl(),e=x().filter(o=>o.url!==t),s=d(),r=await Promise.all(e.map(o=>$(o.url,{apiKey:s}))),n=e.filter((o,t)=>r[t].ok).map(o=>o.url);return 0===n.length?{name:o,status:"fail",message:u.t("doctor.other_addresses_none")}:{name:o,status:"warn",message:u.t("doctor.other_addresses_found",{urls:n.join(", ")})}}()))}else i.push({name:B,status:"fail",message:u.t("doctor.api_key_missing")});n.text=u.t("doctor.check_client_config");const G=await o();i.push({name:u.t("doctor.client_config"),status:"cloud"===G.source||"cache"===G.source&&!G.problem?"pass":"warn",message:[G.source?u.t(`refresh.source.${G.source}`):u.t("refresh.source.none"),G.revision?u.t("doctor.client_config_revision",{revision:G.revision}):"",G.problem??""].filter(Boolean).join(" · ")}),n.text=u.t("doctor.check_tools");const D=p.getInstalledTools();i.push({name:u.t("doctor.installed_tools"),status:D.length>0?"pass":"warn",message:D.length>0?D.map(o=>f(o)?.displayName??o).join(u.t("setup.list_separator")):u.t("doctor.no_tools_installed")}),i.push(...function(){const o=[];for(const t of p.getInstalledTools()){const e=f(t);if(!e?.installSpec)continue;const s=_(e.installSpec);if(0===s.length)continue;const r=[],n=p.outdatedVersion(t);n&&r.push(u.t("doctor.tool_outdated",{min:n.min})),s.length>1&&r.push(u.t("doctor.tool_duplicates",{others:s.slice(1).map(g).join("、")})),o.push({name:e.displayName,status:r.length>0?"warn":"pass",message:[g(s[0]),...r,...r.length>0?[u.t("doctor.run_upgrade",{tool:t})]:[]].join("\n ")})}return o}());const q=function(){if(!p.isToolInstalled("claude-code"))return null;const o=u.t("doctor.claude_config"),t=h();if(t.length>0){const e=t.map(o=>`${o.source}: ${o.keys.join(", ")}`).join("; ");return{name:o,status:"fail",message:u.t("doctor.claude_managed",{detail:e})}}let e={};try{e=JSON.parse(a(c(process.env.CLAUDE_CONFIG_DIR?.trim()||c(j(),".claude"),"settings.json"),"utf-8")).env??{}}catch{}const s=l.getApiKeyForTool("claude-code");return e.ANTHROPIC_AUTH_TOKEN&&e.ANTHROPIC_BASE_URL?e.ANTHROPIC_BASE_URL!==l.getBaseUrl()||s&&e.ANTHROPIC_AUTH_TOKEN!==s?{name:o,status:"warn",message:u.t("doctor.claude_config_changed")}:{name:o,status:"pass"}:{name:o,status:"warn",message:u.t("doctor.claude_not_configured")}}();q&&i.push(q),D.includes("claude-code")&&v()&&i.push({name:u.t("doctor.claude_login"),status:"pass",message:u.t("tools.claude_code.account_login_overridden")});const F=D.includes("codex")?y():null;if(D.includes("codex")&&i.push({name:u.t("doctor.codex_auth"),status:F?"fail":"pass",message:F?u.t(`doctor.codex_${F}`,{path:P(w())}):void 0}),D.includes("codex")){const o=k();i.push({name:u.t("doctor.codex_catalog"),status:o?"fail":"pass",message:o?u.t("doctor.codex_catalog_rejected",{path:o.bin,version:o.version??"?",error:o.error}):void 0})}D.includes("codex")&&b()&&i.push({name:u.t("doctor.codex_work_mode"),status:"warn",message:u.t("tools.codex.work_mode_on")}),"win32"===process.platform&&D.includes("claude-code")&&!process.env.CLAUDE_CODE_GIT_BASH_PATH&&i.push({name:"Git for Windows",status:p.isGitInstalled()?"pass":"warn",message:p.isGitInstalled()?void 0:u.t("tools.claude_code.no_git_bash")}),r.deep&&D.includes("claude-code")&&(n.text=u.t("doctor.check_claude_request"),i.push(function(){const o=u.t("doctor.claude_request"),t=_(f("claude-code").installSpec)[0];if(!t)return{name:o,status:"warn",message:u.t("doctor.claude_request_skipped")};const e={encoding:"utf-8",timeout:12e4,windowsHide:!0,stdio:["ignore","pipe","pipe"]},r=["-p","Reply with the single word OK."],n=/\.cmd$/i.test(t.path)?s(`"${t.path}" ${r.map(o=>`"${o}"`).join(" ")}`,{...e,shell:!0}):s(t.path,r,e),a=`${n.stdout??""}`.trim();if(0===n.status&&a)return{name:o,status:"pass",message:a.slice(0,80)};const i=(`${n.stderr??""}`.trim()||a||n.error?.message||`exit ${n.status}`).slice(0,300);return{name:o,status:"fail",message:u.t("doctor.claude_request_failed",{reason:i})}}())),n.stop(),console.log("\n"+t.bold(u.t("doctor.results_title"))+"\n");const M={pass:t.green("√"),warn:t.yellow("!"),fail:t.red("×")};for(const o of i)console.log(`${M[o.status]} ${o.name}`),o.message&&console.log(t.gray(` ${o.message}`));if(i.every(o=>"pass"===o.status)&&console.log("\n"+t.green.bold(u.t("doctor.all_good"))),!r.deep&&D.includes("claude-code")&&console.log(t.gray("\n"+u.t("doctor.deep_hint"))),r.report){const o=e(u.t("doctor.report_uploading")).start(),t=await N(function(o,t){const e={};for(const o of T()){if(o.hidden)continue;let t=null;try{t=p.detectCurrentConfig(o.name).apiKey?"has_key":"no_key"}catch{t="unreadable"}e[o.name]={installed:p.isToolInstalled(o.name),version:p.installedVersion(o.name),copies:o.installSpec?_(o.installSpec).map(o=>({kind:o.kind,version:o.version,path:o.path})):void 0,config:t}}const s=l.getProfile();return{checks:o,tools:e,settings:{base_url:l.getBaseUrl(),profile:l.getActiveProfileName(),profiles:l.listProfiles().length,key_fingerprint:l.getApiKeyFingerprint()||null,tool_keys:Object.keys(s.tool_api_keys??{}),models:s.models,tool_models:s.tool_models??{},tool_settings:s.tool_settings??{},lang:l.getLang()},client_config:t,env:{shell:process.env.SHELL??process.env.ComSpec??null,term:process.env.TERM_PROGRAM??null,proxies:K()},log:E()}}(i,{source:G.source??void 0,revision:G.revision,problem:G.problem}));t?o.succeed(u.t("doctor.report_done",{code:t})):o.fail(u.t("doctor.report_failed",{cli:O}))}else i.some(o=>"fail"===o.status)&&console.log(t.gray("\n"+u.t("doctor.report_hint",{cli:O})));i.some(o=>"fail"===o.status)&&(process.exitCode=1)}
|
|
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 w,codexWorkModeOn as b}from"../lib/tools/codex.js";import{claudeAccountLoginPresent as v}from"../lib/tools/claude-code.js";import{toolHome as j}from"../lib/tools/types.js";import{gatewayAddresses as x,probeGatewayAddress as $}from"../lib/gateway-addresses.js";import{listAdapters as T}from"../lib/tools/registry.js";import{logger as A}from"../utils/logger.js";import{maskHome as P,maskSecrets as R,uploadReport as N}from"../lib/telemetry.js";import{CLI_NAME as O}from"../lib/brand.js";import{appStatus as I,appStatusText as C,appTools as H,appUpgradeCommand as L,getApp as S}from"../lib/app-update.js";import{balanceLookupEnabled as U,balanceNeedsAttention as E,balanceText as K,fetchKeyBalances as B}from"../lib/key-balance.js";const G=["HTTPS_PROXY","https_proxy","HTTP_PROXY","http_proxy","ALL_PROXY","all_proxy"];function D(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 q(){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 F(){const o={};for(const t of G){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 G){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 D(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(),M=u.t("doctor.api_key_network");if(R){const o=await m(R);o.valid?(c.push({name:M,status:"pass"}),n.text=u.t("doctor.check_balance"),c.push(...await async function(o){if(!U())return[];const t=l.listToolApiKeys().map(o=>({tool:o,key:l.getApiKeyForTool(o)})).filter(t=>Boolean(t.key)&&t.key!==o),e=await B([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:E(t)?"warn":"pass",message:K(t)})}return r}(R))):"invalid_api_key"===o.error?c.push({name:M,status:"fail",message:u.t("doctor.api_key_invalid")}):(c.push({name:M,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:M,status:"fail",message:u.t("doctor.api_key_missing")});n.text=u.t("doctor.check_client_config");const X=await o();c.push({name:u.t("doctor.client_config"),status:"cloud"===X.source||"cache"===X.source&&!X.problem?"pass":"warn",message:[X.source?u.t(`refresh.source.${X.source}`):u.t("refresh.source.none"),X.revision?u.t("doctor.client_config_revision",{revision:X.revision}):"",X.problem??""].filter(Boolean).join(" · ")}),n.text=u.t("doctor.check_tools");const Y=p.getInstalledTools();c.push({name:u.t("doctor.installed_tools"),status:Y.length>0?"pass":"warn",message:Y.length>0?Y.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 I(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,url:S(t)?.appInstaller.downloadPage??"",command:L(t)}):u.t("doctor.run_app_upgrade",{command:L(t)});o.push({name:s,status:"warn",message:`${C(e)}\n ${r}`})}else o.push({name:s,status:"pass",message:C(e)})}return o}());const V=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")}}();V&&c.push(V),Y.includes("claude-code")&&v()&&c.push({name:u.t("doctor.claude_login"),status:"pass",message:u.t("tools.claude_code.account_login_overridden")});const W=Y.includes("codex")?y():null;if(Y.includes("codex")&&c.push({name:u.t("doctor.codex_auth"),status:W?"fail":"pass",message:W?u.t(`doctor.codex_${W}`,{path:P(w())}):void 0}),Y.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})}Y.includes("codex")&&b()&&c.push({name:u.t("doctor.codex_work_mode"),status:"warn",message:u.t("tools.codex.work_mode_on")}),"win32"===process.platform&&Y.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&&Y.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 z={pass:t.green("√"),warn:t.yellow("!"),fail:t.red("×")};for(const o of c)console.log(`${z[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&&Y.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:F()},log:q()}}(c,{source:X.source??void 0,revision:X.revision,problem:X.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{appsForTools as K,appUpgradeCommand as $,getApp as T}from"../lib/app-update.js";import{join as M}from"path";import{confirmWritePlan as G,printWritePlan as S,toolWritePlan as I}from"../lib/write-plan.js";import N from"inquirer";import{logger as E}from"../utils/logger.js";import{forgetInstalls as A}from"../lib/tools/tool-installs.js";import{CLI_NAME as O,brandEnv as B}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 D(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 F(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 L(e){console.log(o.green(e))}function R(e){console.log(o.yellow(e))}function P(e){console.error(o.red(e))}let Y=null;function q(o){const e={operation:1,authentication:2,network:3};(!Y||e[o]>e[Y])&&(Y=o)}async function z(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?`${O} setup --key ${a}`:`${O} setup ${e} ${a}`;let p;if("network_error"===i.error?(q("network"),p=_(l.t("setup.unreachable",{url:s.getBaseUrl(),reason:i.message||"network error"}),`${O} base auto`,"network_error")):"invalid_api_key"===i.error?(q("authentication"),p=y(l.t("setup.invalid_key",{label:e,reason:i.message||"invalid"}),n,"invalid_api_key")):(q("operation"),p=g(l.t("setup.validate_failed",{label:e,reason:i.message||i.error||"unknown"}),n,i.error)),x())throw p;return P(p.message),console.log(o.gray(l.t("errors.next_step",{command:p.hint}))),!1}async function H(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),`${O} setup --key ${l.t("errors.key_placeholder")}`,"config_write_failed");const e=(o instanceof Error?o.message:String(o)).replace(/\s+/g," ").trim();return P("× "+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 W(o){return!e(o)?.isInstalled&&!a.isToolInstalled(o)}export async function installMissingApps(e,t){const i=K(e).filter(o=>{const e=T(o)?.appInstaller;try{return Boolean(e&&!e.blocker()&&!e.installedPath())}catch(e){return E.logError(`setup: app installed? ${o}`,e),!1}});if(0===i.length)return!1;const s=o=>T(o)?.displayName??o;let a=t;if(void 0===a&&!x())if(j())a=!C();else if(h()){const o=i.map(s).join(l.t("setup.list_separator")),e=i.reduce((o,e)=>o+(T(e)?.appInstaller.sizeMb()??0),0);console.log(""),a=(await N.prompt([{type:"confirm",name:"go",message:l.t("setup.install_app_confirm",{tools:o,size:String(e)}),default:!0}])).go}if(!a&&!x())for(const e of i)console.log(o.gray(l.t("setup.install_app_hint",{tool:s(e),command:$(e)})));return Boolean(a)}function U(o){R(l.t("setup.still_missing",{tools:o.map(o=>n[o].displayName).join(l.t("setup.list_separator")),commands:o.map(o=>`${O} config ${o} --yes`).join(l.t("setup.list_separator"))}))}function J(e,t,i=[]){const a=I(e),n=M(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")}`)}S(a,{label:l.t("runtime.dry_run_label"),keyFile:t?n:void 0,installFirst:i})}}function Q(){return"darwin"===process.platform||"win32"===process.platform||a.isToolInstalled("claude-desktop")}export async function setupCommand(r){Y=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 P(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 P(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 J([...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),L(l.t(e?"setup.codex_1m_enabled":"setup.codex_1m_disabled"))}catch(o){P(l.t("setup.apply_failed",{tool:n.codex.displayName,reason:o instanceof Error?o.message:String(o)})),process.exitCode=1}else P(l.t("setup.codex_1m_missing_key")),process.exitCode=1}if(b){const o=s.getApiKeyForTool("claude-desktop");o?await H("claude-desktop",o,{...K,oneMillion:void 0})?await t(["claude-desktop"],{apps:{install:!1}}):process.exitCode=1:(P(l.t("setup.desktop_official_login_missing_key")),process.exitCode=1)}return}if(!w)return P(l.t("setup.usage")),void(process.exitCode=1);const $=v();$||await i(p||f[0].apiKey);const T=[],S=[];let I,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 z(o.label,o.apiKey)){V+=1;continue}const e=await D(o.apiKey);!e.probed||F(e,o.need)?(e.probed||R(l.t("setup.probe_failed",{label:o.label})),T.push({tool:o.tool,apiKey:o.apiKey,dedicated:!0}),X.add(o.tool)):(P(l.t(`setup.key_no_${o.need}`,{label:o.label,tool:n[o.tool].displayName})),V+=1)}const oo=!!p&&await z("--key",p);p&&!oo&&(I=k[Y??"operation"]);const eo=p&&oo?await D(p):void 0;if(p&&eo&&!eo.probed&&R(l.t("setup.probe_failed",{label:"--key"})),!(p&&eo&&eo.probed)||eo.hasClaude||eo.hasGpt||eo.hasGrok||eo.hasGemini||(P(l.t("setup.key_no_family")),I=1),p&&eo&&void 0===I){const o=[{tool:"claude-code",capable:eo.hasClaude,skipMsg:l.t(Q()?"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&&Q(),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?(T.push({tool:e.tool,apiKey:p,dedicated:!1}),X.add(e.tool)):e.quiet||R(e.skipMsg))}const to=Boolean(p&&oo&&void 0===I);if($)return J(T.filter(o=>!W(o.tool)).map(o=>o.tool),T.length>0,T.filter(o=>W(o.tool)).map(o=>o.tool)),void((V>0||void 0!==I)&&(process.exitCode=I??k[Y??"operation"]));const io=T.filter(o=>!W(o.tool)),lo=to||T.some(o=>o.dedicated);if((T.length>0||lo)&&!r.fromInstaller&&!await G(io.map(o=>o.tool),{keyFile:lo?M(s.getConfigDir(),"config.yaml"):void 0,installFirst:T.filter(o=>W(o.tool)).map(o=>o.tool)}))return void(process.exitCode=k.cancelled);to&&p&&s.setApiKey(p);for(const o of T)o.dedicated&&s.setToolApiKey(o.tool,o.apiKey),W(o.tool)?S.push({tool:o.tool,apiKey:o.apiKey}):await H(o.tool,o.apiKey,K)?q+=1:(V+=1,X.delete(o.tool));if(void 0!==I)return S.length>0&&U(S.map(o=>o.tool)),void(process.exitCode=I);let so=[];if(S.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:O}))),{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){E.logError(`setup: install ${e}`,o)}A(),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 H(o,t,i)?u.push(o):f.push(o);return{still:d,applied:u,failed:f}}(S,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)});L("\n"+(i?`${s}${l.t("setup.done_commands",{commands:i})}`:s)),so.length>0&&U(so);for(const o of t){const e=a.ensureNativeOnPath(o);e&&L(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"!==B("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&&U(so),V>0&&(P(l.t("setup.failed_summary",{count:String(V)})),x()||console.error(`${O} 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[Y??"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 r}from"../lib/i18n.js";import{toolManager as
|
|
1
|
+
import o from"chalk";import{appTools as t,getApp as e,upgradeApp as l}from"../lib/app-update.js";import{i18n as r}from"../lib/i18n.js";import{emitJson as n,isJsonMode as i}from"../lib/runtime-options.js";import{toolManager as s}from"../lib/tool-manager.js";import{listAdapters as a}from"../lib/tools/registry.js";import{upgradeTool as p}from"../lib/tool-upgrade.js";export async function upgradeCommand(d,c={}){const u=t(),m=[...a().filter(o=>o.installSpec).map(o=>o.name),...u],f=d.length>0?d:m.filter(o=>u.includes(o)?(o=>{const t=e(o)?.appInstaller;return Boolean(t&&!t.blocker()&&t.installedPath())})(o):s.isToolInstalled(o)),g=f.filter(o=>!m.includes(o));if(g.length>0)return console.error(o.red(r.t("upgrade.unsupported",{tool:g.join(", ")}))),console.error(r.t("upgrade.supported",{tools:m.join(" / ")})),void(process.exitCode=1);if(0===f.length)return void(i()?n({tools:[]}):console.log(r.t("upgrade.nothing_installed",{tools:m.join(" / ")})));let j=0;const b=[];for(const t of f){if(u.includes(t)){const r=e(t)?.displayName??t;i()||console.log(o.bold(`\n${r}`));const n=await l(t,{install:!0,force:c.force}),s=["installed","upgraded","up_to_date","declined"].includes(n.result);s||(j+=1),b.push({...n,ok:s});continue}const r=await p(t);r||(j+=1),b.push({tool:t,ok:r})}i()&&n({tools:b}),j>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{listAdapters as g}from"./tools/registry.js";import{logger as _}from"../utils/logger.js";function y(){return l(i.getConfigDir(),"app-releases.json")}function w(){try{if(!r(y()))return{};const t=JSON.parse(a(y(),"utf-8"));return t&&"object"==typeof t?t:{}}catch{return{}}}function h(t,e){try{n(i.getConfigDir(),{recursive:!0}),o(y(),JSON.stringify({...w(),[t]:e},null,2))}catch(t){_.logError("app-update.writeCache",t)}}function k(){return g().flatMap(t=>[...t.appInstaller?[{name:t.name,displayName:t.displayName,appInstaller:t.appInstaller,installedVersion:t.installedVersion,runningApp:t.runningApp,tool:t.name}]:[],...(t.companionApps??[]).map(e=>({...e,tool:t.name}))])}export function appTools(){return k().map(t=>t.name)}export function getApp(t){return k().find(e=>e.name===t)}export function appsForTools(t){return k().filter(e=>t.includes(e.tool)).map(t=>t.name)}function v(t){const e=getApp(t);if(!e)throw new Error(`no app installer for ${t}`);return e}function b(t,e,r){try{return e()}catch(e){return _.logError(`app-update.${t}`,e),r}}function C(t){const e=v(t),r=e.appInstaller,n=b("installedPath",()=>null!==r.installedPath(),!1);return{tool:t,name:e.displayName,installed:n,current:n?b("installedVersion",()=>e.installedVersion?.()??null,null):null,running:!!n&&b("isRunning",()=>e.runningApp?.isRunning()??!1,!1),blocker:b("blocker",()=>r.blocker(),"unsupported_platform")}}function U(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=C(t);if(r.blocker&&"classic_install"!==r.blocker)return U(r,null);const n=w()[t],a=n&&Date.now()-n.checked_at<(n.version?36e5:6e5);if(n&&a&&!e.refresh)return U(r,n.version??null,n.error);try{const e=await v(t).appInstaller.latestVersion();return h(t,{version:e,checked_at:Date.now()}),U(r,e)}catch(e){const a=e instanceof Error?e.message:String(e);return _.logError(`app-update.latest(${t})`,e),h(t,{error:a,checked_at:Date.now()}),U(r,n?.version??null,a)}}export function cachedAppStatus(t){const e=C(t);return U(e,e.blocker&&"classic_install"!==e.blocker?null:w()[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 A(t){c()?process.stderr.write(t+"\n"):console.log(t)}async function j(t,r=!0){const{ok:n}=await e.prompt([{type:"confirm",name:"ok",message:t,default:r}]);return n}export async function upgradeApp(e,r={}){const n=Date.now(),a=await appStatus(e,{refresh:r.refresh??!0}),o=a.name,l=(t,r={})=>{const o={...a,result:t,upgraded:"upgraded"===t||"installed"===t,version_after:null,...r};return["up_to_date","unavailable","not_installed","offered"].includes(t)||f(`app-upgrade:${e}`,"failed"===t?"fail":"ok",{duration_ms:Date.now()-n,detail:{result:t,current:a.current,latest:a.latest,...r.reason?{reason:r.reason}:{}}}),o};if(a.blocker)return!r.quiet&&a.installed&&a.outdated&&A(t.yellow(" ! "+s.t("app_update.outdated",{current:a.current,latest:a.latest}))),r.quiet||A(t.yellow(" ! "+s.t(`app_update.blocked_${a.blocker}`,{tool:o,url:v(e).appInstaller.downloadPage,command:appUpgradeCommand(e)}))),l("unavailable",{reason:a.blocker});if(!a.latest)return r.quiet||A(t.yellow(" ! "+s.t("app_update.latest_unknown",{tool:o,reason:a.error??""}))),l("unavailable",{reason:a.error});if(!a.installed&&!r.install)return l("not_installed");const p=Boolean(r.force&&a.installed&&!a.outdated);if(a.installed&&!a.outdated&&!p)return r.quiet||(A(t.green(" √ "+s.t("app_update.already_latest",{tool:o,current:a.current??a.latest}))),A(t.gray(" "+s.t("app_update.force_hint",{command:appUpgradeCommand(e)})))),l("up_to_date");if(p?A(t.yellow(" ! "+s.t("app_update.reinstalling",{tool:o,latest:a.latest,current:a.current??"?"}))):!a.installed||r.askBeforeUpgrade&&!a.running||A(t.yellow(` ! ${o} `+appStatusText(a))),a.installed&&r.askBeforeUpgrade&&!a.running){if(!u()||d())return A(t.gray(" "+s.t("app_update.upgrade_hint",{tool:o,current:a.current??"?",latest:a.latest,command:appUpgradeCommand(e)}))),l("offered");if(!await j(s.t("app_update.upgrade_offer",{tool:o,current:a.current??"?",latest:a.latest})))return A(t.gray(" "+s.t("app_update.declined_hint",{command:appUpgradeCommand(e)}))),l("declined")}let i=!1;if(a.running){if(!u()||d())return A(t.yellow(" ! "+s.t("app_update.running_hint",{tool:o,command:appUpgradeCommand(e)}))),l("left_running");if(!await j(s.t("app_update.offer_quit",{tool:o,latest:a.latest})))return A(t.gray(" "+s.t("app_update.declined_hint",{command:appUpgradeCommand(e)}))),l("declined");const r=v(e).runningApp;if(!r?.quit?.())return A(t.yellow(" ! "+s.t("app_update.quit_failed",{tool:o,command:appUpgradeCommand(e)}))),l("failed",{reason:"quit_failed"});i=!0}try{const{version:r}=await async function(e){const r=v(e).appInstaller,n=!c()&&Boolean(process.stdout.isTTY);let a=-1;try{return await r.install({downloading:n=>A(t.gray(" "+s.t("app_update.downloading",{tool:v(e).displayName,version:n,size:String(r.sizeMb())}))),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,A(t.gray(" "+s.t("app_update.verifying",{vendor:r.vendor})))},installing:()=>A(t.gray(" "+s.t("app_update.installing")))})}finally{n&&a>=0&&a<100&&process.stdout.write("\n")}}(e);return A(t.green(" √ "+(p?s.t("app_update.reinstalled",{tool:o,version:r}):a.installed?s.t("app_update.upgraded",{tool:o,from:a.current??"?",to:r}):s.t("app_update.installed",{tool:o,version:r})))),i&&!v(e).runningApp?.launch?.()&&A(t.yellow(" ! "+s.t("setup.reopen_hint",{tool:o}))),l(a.installed?"upgraded":"installed",{version_after:r,current:a.current})}catch(r){const n=r instanceof Error?r.message:String(r);return _.logError(`app-update.install(${e})`,r),A(t.yellow(" ! "+(a.installed?s.t("app_update.upgrade_failed",{tool:o,reason:n,current:a.current??"?",command:appUpgradeCommand(e)}):s.t("app_update.install_failed",{tool:o,reason:n,command:appUpgradeCommand(e)})))),i&&v(e).runningApp?.launch?.(),l("failed",{reason:n})}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawnSync as t}from"child_process";import{closeSync as e,copyFileSync as o,createReadStream as r,createWriteStream as n,existsSync as s,mkdirSync as i,openSync as a,readFileSync as c,readSync as
|
|
1
|
+
import{spawnSync as t}from"child_process";import{closeSync as e,copyFileSync as o,createReadStream as r,createWriteStream as n,existsSync as s,mkdirSync as i,openSync as a,readFileSync as c,readSync as l,readdirSync as f,realpathSync as d,renameSync as p,statSync as u,utimesSync as m,writeFileSync as h}from"fs";import{basename as g,join as b,resolve as y}from"path";import{pipeline as S}from"stream/promises";import*as _ from"@iarna/toml";import{codexHome as v,toolHome as w}from"./tools/types.js";import{CLI_NAME as E}from"./brand.js";import{powerShellEnv as x}from"./powershell-env.js";export{v as codexHome};export function currentCodexProvider(){try{const t=_.parse(c(b(v(),"config.toml"),"utf-8"));return"string"==typeof t.model_provider&&t.model_provider.trim()?t.model_provider.trim():"openai"}catch{return"openai"}}let N=()=>{if("win32"===process.platform)return`${t("powershell.exe",["-NoProfile","-NonInteractive","-Command","(Get-Process -Name codex -ErrorAction SilentlyContinue).Id"],{encoding:"utf-8",windowsHide:!0,env:x()}).stdout??""}`.split(/\s+/).filter(Boolean).map(Number);const e=process.getuid?.(),o=`${t("pgrep",["-x","-i",...void 0===e?[]:["-u",String(e)],"codex"],{encoding:"utf-8"}).stdout??""}`.split(/\s+/).filter(Boolean).map(Number);if("linux"!==process.platform)return o;const r=O(v());return o.filter(t=>{let e;try{e=c(`/proc/${t}/environ`,"utf-8")}catch{return!0}const o=new Map(e.split("\0").map(t=>[t.slice(0,t.indexOf("=")),t.slice(t.indexOf("=")+1)])),n=o.get("CODEX_HOME")?.trim()||(o.get("HOME")?b(o.get("HOME"),".codex"):null);return null===n||O(n)===r})};function O(t){try{return d(t)}catch{return t}}export function setCodexProcessCheckForTests(t){N=t}export function runningCodexPids(){try{return N()}catch{return[]}}function $(t){const o=a(t,"r");try{const t=[],e=Buffer.alloc(65536);for(;;){const r=l(o,e,0,e.length,null);if(r<=0)break;const n=e.subarray(0,r).indexOf(10);if(n>=0){t.push(Buffer.from(e.subarray(0,n)));break}t.push(Buffer.from(e.subarray(0,r)))}return Buffer.concat(t).toString("utf-8")}finally{e(o)}}async function D(t,e,o){const{atime:s,mtime:i}=u(t),a=`${t}.${E}-tmp`,c=n(a);c.write(e),await S(r(t,{start:o}),c),p(a,t),m(t,s,i)}export function codexSqliteHome(){const t=v();try{const e=_.parse(c(b(t,"config.toml"),"utf-8")),o="string"==typeof e.sqlite_home?e.sqlite_home.trim():"";if(o)return"~"===o||o.startsWith("~/")?b(w(),o.slice(1)):y(t,o)}catch{}const e=process.env.CODEX_SQLITE_HOME?.trim();return e?y(e):t}function T(){const t=codexSqliteHome();if(!s(t))return null;const e=f(t).map(t=>/^state_(\d+)\.sqlite$/.exec(t)).filter(t=>!!t).sort((t,e)=>Number(e[1])-Number(t[1]));return e.length>0?b(t,e[0][0]):null}const A={threads:"id",local_thread_catalog:"thread_id"};function B(){const t=b(codexSqliteHome(),"sqlite");return s(t)?f(t).filter(t=>/\.(db|sqlite3?)$/.test(t)).map(e=>b(t,e)).sort():[]}function C(t,e,o){const r=function(t,e){return new Set(t.prepare(`PRAGMA table_info(${e})`).all().map(t=>String(t.name)))}(t,e),n=A[e];if(!r.has(n)||!r.has("model_provider"))return null;const s=r.has("host_id")?" AND host_id = 'local'":"";return t.prepare(`SELECT ${n} AS id, model_provider AS "from" FROM ${e} WHERE COALESCE(model_provider, '') NOT IN ('', ?)${s}`).all(o).map(t=>({id:String(t.id),from:String(t.from)}))}async function H(t){try{return new((await import("node:sqlite")).DatabaseSync)(t)}catch(t){return`node:sqlite unavailable (Node ${process.versions.node}; needs 22.13+): ${t instanceof Error?t.message:String(t)}`}}export const NO_STATE_DB="no state DB";export async function moveSessionsToProvider(t,e={}){const r=function(){const t=[],e=o=>{if(s(o))for(const r of f(o,{withFileTypes:!0})){const n=b(o,r.name);r.isDirectory()?e(n):r.isFile()&&r.name.endsWith(".jsonl")&&t.push(n)}};return e(b(v(),"sessions")),e(b(v(),"archived_sessions")),t}(),n=[];for(const e of r){let o,r;try{o=$(e)}catch{continue}try{r=JSON.parse(o)}catch{continue}const s=r.payload?.model_provider;"session_meta"===r.type&&"string"==typeof s&&s!==t&&(r.payload.model_provider=t,n.push({file:e,from:s,line:JSON.stringify(r),length:Buffer.byteLength(o,"utf-8")}))}const a=[T(),...B()].filter(t=>!!t);let c=a.length>0?null:NO_STATE_DB;const l=[];for(const e of a){const o=await H(e);if("string"==typeof o){c=o;break}const r=[];try{for(const n of Object.keys(A)){const s=C(o,n,t);s&&s.length>0&&r.push({db:e,table:n,rows:s})}}catch{}l.push({path:e,db:o,tables:r})}const d=l.flatMap(t=>t.tables),p=new Set(d.flatMap(t=>t.rows.map(t=>t.id))),u={target:t,scanned:r.length,moved:n.map(({file:t,from:e})=>({file:t,from:e})),dbRows:p.size,dbSkipped:c,backupDir:null},m=()=>l.forEach(t=>t.db.close());if(e.dryRun||0===n.length&&0===d.length)return m(),u;const y=b(v(),"backups",`${E}-sessions-${(new Date).toISOString().replace(/[:.]/g,"-")}`);i(y,{recursive:!0}),l.forEach(({path:t,tables:e},r)=>{if(0!==e.length)for(const e of["","-wal","-shm"])s(t+e)&&o(t+e,b(y,`${r}-${g(t)}${e}`))});const S={target:t,moved:u.moved,tables:d};h(b(y,"manifest.json"),JSON.stringify(S,null,2)+"\n");for(const t of n)await D(t.file,t.line,t.length);for(const{db:e,tables:o}of l)for(const{table:r,rows:n}of o){const o=e.prepare(`UPDATE ${r} SET model_provider = ? WHERE ${A[r]} = ? AND model_provider = ?`);for(const{id:e,from:r}of n)o.run(t,e,r)}return m(),u.backupDir=y,u}export async function undoSessionMove(t){const e=JSON.parse(c(b(t,"manifest.json"),"utf-8"));let o=0;for(const{file:t,from:r}of e.moved){if(!s(t))continue;const e=$(t),n=JSON.parse(e);n.payload&&(n.payload.model_provider=r,await D(t,JSON.stringify(n),Buffer.byteLength(e,"utf-8")),o+=1)}const r=e.tables??(e.db&&e.threads?[{db:e.db,table:"threads",rows:e.threads}]:[]),n=new Set;for(const{db:t,table:o,rows:i}of r){if(!s(t)||0===i.length||!A[o])continue;const r=await H(t);if("string"==typeof r)continue;const a=r.prepare(`UPDATE ${o} SET model_provider = ? WHERE ${A[o]} = ? AND model_provider = ?`);for(const{id:t,from:o}of i)Number(a.run(o,t,e.target).changes)>0&&n.add(t);r.close()}return{files:o,dbRows:n.size}}
|
package/dist/lib/i18n.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readFileSync as t,existsSync as e,readdirSync as s}from"fs";import{join as o,dirname as r}from"path";import{fileURLToPath as a}from"url";import{logger as n}from"../utils/logger.js";import{brandTokens as l}from"./brand.js";class c{static instance;currentLocale="en_US";translations=new Map;fallbackLocale="en_US";localesDir;constructor(){const t=a(import.meta.url),e=r(t);this.localesDir=o(e,"..","locales"),this.loadTranslations(),this.loadSavedLocale()}static getInstance(){return c.instance||(c.instance=new c),c.instance}loadTranslations(){try{if(!e(this.localesDir))return void n.warn(`Locales directory not found at ${this.localesDir}`);const r=s(this.localesDir).filter(t=>t.endsWith(".json"));if(0===r.length)return void n.warn("No locale files found in locales directory");for(const e of r){const s=e.replace(".json",""),r=o(this.localesDir,e);try{const e=t(r,"utf-8"),o=JSON.parse(e);this.translations.set(s,o)}catch(t){n.warn(`Failed to load locale file ${e}:`,t)}}const a=process.env.LANG||process.env.LC_ALL||process.env.LC_MESSAGES;if(a){const t=a.split(".")[0].replace("_","-");if(this.translations.has(t))this.currentLocale=t;else{const e=t.split("-")[0],s=Array.from(this.translations.keys()).find(t=>t.startsWith(e+"_"));s?this.currentLocale=s:"zh"===e?this.currentLocale="zh_CN":"en"===e&&(this.currentLocale="en_US")}}}catch(t){n.warn("Failed to load translations:",t)}}setLocale(t){this.translations.has(t)?(this.currentLocale=t,this.saveLocale()):n.warn(`Locale '${t}' not supported, falling back to '${this.currentLocale}'`)}getLocale(){return this.currentLocale}getAvailableLocales(){return Array.from(this.translations.keys())}translate(t,e){const s=t.split(".");let o=this.translations.get(this.currentLocale);for(const e of s){if(!o||"object"!=typeof o||!(e in o)){o=this.translations.get(this.fallbackLocale);for(const e of s){if(!o||"object"!=typeof o||!(e in o))return t;o=o[e]}break}o=o[e]}if("string"!=typeof o)return t;const r=l(this.currentLocale);return o=o.replace(/\{\{(\w+)\}\}/g,(t,e)=>r[e]??t),e?o.replace(/\{\{(\w+)\}\}/g,(t,s)=>e[s]
|
|
1
|
+
import{readFileSync as t,existsSync as e,readdirSync as s}from"fs";import{join as o,dirname as r}from"path";import{fileURLToPath as a}from"url";import{logger as n}from"../utils/logger.js";import{brandTokens as l}from"./brand.js";class c{static instance;currentLocale="en_US";translations=new Map;fallbackLocale="en_US";localesDir;constructor(){const t=a(import.meta.url),e=r(t);this.localesDir=o(e,"..","locales"),this.loadTranslations(),this.loadSavedLocale()}static getInstance(){return c.instance||(c.instance=new c),c.instance}loadTranslations(){try{if(!e(this.localesDir))return void n.warn(`Locales directory not found at ${this.localesDir}`);const r=s(this.localesDir).filter(t=>t.endsWith(".json"));if(0===r.length)return void n.warn("No locale files found in locales directory");for(const e of r){const s=e.replace(".json",""),r=o(this.localesDir,e);try{const e=t(r,"utf-8"),o=JSON.parse(e);this.translations.set(s,o)}catch(t){n.warn(`Failed to load locale file ${e}:`,t)}}const a=process.env.LANG||process.env.LC_ALL||process.env.LC_MESSAGES;if(a){const t=a.split(".")[0].replace("_","-");if(this.translations.has(t))this.currentLocale=t;else{const e=t.split("-")[0],s=Array.from(this.translations.keys()).find(t=>t.startsWith(e+"_"));s?this.currentLocale=s:"zh"===e?this.currentLocale="zh_CN":"en"===e&&(this.currentLocale="en_US")}}}catch(t){n.warn("Failed to load translations:",t)}}setLocale(t){this.translations.has(t)?(this.currentLocale=t,this.saveLocale()):n.warn(`Locale '${t}' not supported, falling back to '${this.currentLocale}'`)}getLocale(){return this.currentLocale}getAvailableLocales(){return Array.from(this.translations.keys())}translate(t,e){const s=t.split(".");let o=this.translations.get(this.currentLocale);for(const e of s){if(!o||"object"!=typeof o||!(e in o)){o=this.translations.get(this.fallbackLocale);for(const e of s){if(!o||"object"!=typeof o||!(e in o))return t;o=o[e]}break}o=o[e]}if("string"!=typeof o)return t;const r=l(this.currentLocale);return o=o.replace(/\{\{(\w+)\}\}/g,(t,e)=>r[e]??t),e?o.replace(/\{\{(\w+)\}\}/g,(t,s)=>e[s]??t):o}t(t,e){return this.translate(t,e)}saveLocale(){}loadSavedLocale(){}loadFromConfig(t){this.translations.has(t)&&(this.currentLocale=t)}}export function detectSystemLang(){const t=process.env.LC_ALL||process.env.LC_MESSAGES||process.env.LANG||process.env.LANGUAGE||"";let e="";try{e=Intl.DateTimeFormat().resolvedOptions().locale||""}catch{}return`${t} ${e}`.toLowerCase().split(/[\s:;,]+/).some(t=>"zh"===t||t.startsWith("zh-")||t.startsWith("zh_"))?"zh_CN":"en_US"}export{c as I18n};export const i18n=c.getInstance();
|
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
|
|
1
|
+
import o from"chalk";import t from"inquirer";import{i18n as n}from"./i18n.js";import{canPrompt as e,hasExplicitYes as r,shouldAutoConfirm as i}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{appsForTools as p,upgradeApp as f}from"./app-update.js";import{logger as c}from"../utils/logger.js";async function u(o){const{ok:n}=await t.prompt([{type:"confirm",name:"ok",message:o,default:!0}]);return n}export async function runPendingElevations(t){const r=e();for(const e of t){const t=a(e)?.pendingElevation?.();if(!t)continue;if(!(i()||r&&await u(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,i={}){const m=new Set;for(const o of i.apps?p(t):[])try{const t=await f(o,{install:i.apps.install,quiet:!0,askBeforeUpgrade:!0});t.upgraded&&t.running&&m.add(o)}catch(t){c.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 g=e();for(const n of t){let t;try{t=await(a(n)?.followUp?.())}catch(o){c.logError(`postApplyPrompts.followUp(${n})`,o);continue}if(t)if("run"in t&&(r()||g))if(r()||await u(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 d=r(),y=g||d?t.filter(o=>a(o)?.installSpec&&s.outdatedVersion(o)):[];if(y.length>0){const o=y.map(o=>a(o)?.displayName??o).join("、");if(d||await u(n.t("setup.offer_upgrade",{tools:o})))for(const o of y)await l(o)}for(const e of t){const t=a(e);if(m.has(e)||!t?.runningApp?.isRunning())continue;if(d||!g){console.log(o.yellow(" ! "+n.t("setup.reopen_hint",{tool:t.displayName})));continue}if(!await u(n.t("setup.offer_restart",{tool:t.displayName})))continue;const r=t.runningApp.restart();console.log(r?o.green(" √ "+n.t("setup.restarted",{tool:t.displayName})):o.yellow(" ! "+n.t("setup.restart_failed",{tool:t.displayName})))}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function powerShellEnv(e=process.env){const o={};for(const[t,r]of Object.entries(e))"psmodulepath"!==t.toLowerCase()&&(o[t]=r);return o}export function isWindowsPowerShell(e){return/(^|[\\/])powershell(\.exe)?$/i.test(e.trim())}
|