@xhscopy-ai/cli 0.0.138 → 0.0.139
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.
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"claude": [
|
|
11
11
|
{
|
|
12
12
|
"description": "100 万上下文 | 高强度推理 | 长时 Agent | SWE-bench Verified 95%",
|
|
13
|
-
"group": "
|
|
13
|
+
"group": "grp_rld6af0zorqd",
|
|
14
14
|
"group_name": "",
|
|
15
15
|
"hidden": false,
|
|
16
16
|
"id": "claude-fable-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_6lyxfgbs440g",
|
|
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",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
"description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
|
|
58
|
-
"group": "
|
|
58
|
+
"group": "grp_6co8aqwefsoh",
|
|
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",
|
|
@@ -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_irydsgijuckh",
|
|
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_irydsgijuckh",
|
|
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_squ2qzjnehps",
|
|
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",
|
|
@@ -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",
|
|
@@ -147,7 +147,7 @@
|
|
|
147
147
|
},
|
|
148
148
|
{
|
|
149
149
|
"description": "105 万上下文 | 12.8 万输出 | 思考强度至 max | 计算机操作 / 编码 / 科学基准接近饱和",
|
|
150
|
-
"group": "
|
|
150
|
+
"group": "grp_bsbtt432saoq",
|
|
151
151
|
"group_name": "",
|
|
152
152
|
"hidden": false,
|
|
153
153
|
"id": "gpt-6-astra",
|
|
@@ -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",
|
|
@@ -165,7 +165,7 @@
|
|
|
165
165
|
},
|
|
166
166
|
{
|
|
167
167
|
"description": "105 万上下文 | 12.8 万输出 | 复杂编程与 Agent 工作流",
|
|
168
|
-
"group": "
|
|
168
|
+
"group": "grp_mb5v069lpnze",
|
|
169
169
|
"group_name": "",
|
|
170
170
|
"hidden": false,
|
|
171
171
|
"id": "gpt-6-sol",
|
|
@@ -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_z5khwusxuh2j",
|
|
252
252
|
"group_name": "",
|
|
253
253
|
"hidden": false,
|
|
254
254
|
"id": "gemini-3.6-flash",
|
|
@@ -266,7 +266,7 @@
|
|
|
266
266
|
},
|
|
267
267
|
{
|
|
268
268
|
"description": "推理与编码 | HLE-Verified 54.9% | 长文档工作流",
|
|
269
|
-
"group": "
|
|
269
|
+
"group": "grp_3pi5kyqkp51b",
|
|
270
270
|
"group_name": "",
|
|
271
271
|
"hidden": false,
|
|
272
272
|
"id": "gemini-3.8-flash",
|
|
@@ -313,7 +313,7 @@
|
|
|
313
313
|
},
|
|
314
314
|
{
|
|
315
315
|
"description": "50 万上下文 | 长时 Agent | 编码与视觉项目",
|
|
316
|
-
"group": "
|
|
316
|
+
"group": "grp_irydsgijuckh",
|
|
317
317
|
"group_name": "",
|
|
318
318
|
"hidden": false,
|
|
319
319
|
"id": "grok-4.7",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"claude": [
|
|
11
11
|
{
|
|
12
12
|
"description": "100 万上下文 | 高强度推理 | 长时 Agent | SWE-bench Verified 95%",
|
|
13
|
-
"group": "
|
|
13
|
+
"group": "grp_rld6af0zorqd",
|
|
14
14
|
"group_name": "",
|
|
15
15
|
"hidden": false,
|
|
16
16
|
"id": "claude-fable-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_6lyxfgbs440g",
|
|
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",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
"description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
|
|
58
|
-
"group": "
|
|
58
|
+
"group": "grp_6co8aqwefsoh",
|
|
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",
|
|
@@ -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_irydsgijuckh",
|
|
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_irydsgijuckh",
|
|
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_squ2qzjnehps",
|
|
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",
|
|
@@ -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",
|
|
@@ -147,7 +147,7 @@
|
|
|
147
147
|
},
|
|
148
148
|
{
|
|
149
149
|
"description": "105 万上下文 | 12.8 万输出 | 思考强度至 max | 计算机操作 / 编码 / 科学基准接近饱和",
|
|
150
|
-
"group": "
|
|
150
|
+
"group": "grp_bsbtt432saoq",
|
|
151
151
|
"group_name": "",
|
|
152
152
|
"hidden": false,
|
|
153
153
|
"id": "gpt-6-astra",
|
|
@@ -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",
|
|
@@ -165,7 +165,7 @@
|
|
|
165
165
|
},
|
|
166
166
|
{
|
|
167
167
|
"description": "105 万上下文 | 12.8 万输出 | 复杂编程与 Agent 工作流",
|
|
168
|
-
"group": "
|
|
168
|
+
"group": "grp_mb5v069lpnze",
|
|
169
169
|
"group_name": "",
|
|
170
170
|
"hidden": false,
|
|
171
171
|
"id": "gpt-6-sol",
|
|
@@ -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_z5khwusxuh2j",
|
|
252
252
|
"group_name": "",
|
|
253
253
|
"hidden": false,
|
|
254
254
|
"id": "gemini-3.6-flash",
|
|
@@ -266,7 +266,7 @@
|
|
|
266
266
|
},
|
|
267
267
|
{
|
|
268
268
|
"description": "推理与编码 | HLE-Verified 54.9% | 长文档工作流",
|
|
269
|
-
"group": "
|
|
269
|
+
"group": "grp_3pi5kyqkp51b",
|
|
270
270
|
"group_name": "",
|
|
271
271
|
"hidden": false,
|
|
272
272
|
"id": "gemini-3.8-flash",
|
|
@@ -313,7 +313,7 @@
|
|
|
313
313
|
},
|
|
314
314
|
{
|
|
315
315
|
"description": "50 万上下文 | 长时 Agent | 编码与视觉项目",
|
|
316
|
-
"group": "
|
|
316
|
+
"group": "grp_irydsgijuckh",
|
|
317
317
|
"group_name": "",
|
|
318
318
|
"hidden": false,
|
|
319
319
|
"id": "grok-4.7",
|
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{logger as i}from"../utils/logger.js";import{configManager as l}from"./config.js";import{getAdapter as s,listAdapters as a,TOOL_ADAPTERS as c}from"./tools/registry.js";import{backupBeforeWrite as d,listBackups as p,restoreBackup as u}from"./tools/backup.js";import{existsSync as m,rmSync as f}from"fs";import{dirname as g,join as h}from"path";import{toolHome as w}from"./tools/types.js";import{stringWidth as y}from"../utils/string-width.js";import{resolveModelCatalog as P}from"./model-catalog.js";import{compareVersions as $,getToolMinVersion as T}from"./model-registry.js";import{findInstalls as C,forgetInstalls as v,installLabel as k,mirrorInstallCommand as E,npmMirrorInstallCommand as O}from"./tools/tool-installs.js";import{mirrorInstall 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{logger as i}from"../utils/logger.js";import{configManager as l}from"./config.js";import{getAdapter as s,listAdapters as a,TOOL_ADAPTERS as c}from"./tools/registry.js";import{backupBeforeWrite as d,listBackups as p,restoreBackup as u}from"./tools/backup.js";import{existsSync as m,rmSync as f}from"fs";import{dirname as g,join as h}from"path";import{toolHome as w}from"./tools/types.js";import{stringWidth as y}from"../utils/string-width.js";import{resolveModelCatalog as P}from"./model-catalog.js";import{compareVersions as $,getToolMinVersion as T}from"./model-registry.js";import{findInstalls as C,forgetInstalls as v,installLabel as k,mirrorInstallCommand as E,npmMirrorInstallCommand as O,npmMirrorVersion as _}from"./tools/tool-installs.js";import{mirrorInstall as S}from"./tool-upgrade.js";import{CLI_NAME as N}from"./brand.js";import{track as M,trackStep as j}from"./telemetry.js";import{addUserPathDir as U,broadcastEnvChange as b}from"./windows-env.js";export{$ as compareVersions};function x(o){const t=c[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 I(){const o=new Set;for(const t of l.listProfiles()){const n=l.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(c).map(o=>[o,x(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=s(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=s(o),n=t?.installSpec?.native?.binDir;if(!t||!n)return null;const e="win32"===process.platform?`${t.command}.exe`:t.command,r=h(w(),...n,e);return m(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=g(t);try{if(!U(n))return null}catch(t){return i.logError(`ensureNativeOnPath: ${o}`,t),null}return b(),process.env.Path=`${process.env.Path??""};${n}`,n}async installTool(o){return j(`install:${o}`,()=>this.installToolNow(o))}async installToolNow(t){const i=SUPPORTED_TOOLS[t];if(!i)throw new Error(`Unknown tool: ${t}`);const l=s(t)?.installSpec;if(l&&(l.mirrorScript||l.npmPackage)){const o=E(l);if(await S(l)&&(v(),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:i.displayName,command:o}))),l.mirrorScript&&l.npmPackage&&console.log(r.yellow(" ! "+n.t("install.manual_npm",{command:O(l,await _(l))}))),new Error(`Failed to install ${i.displayName}`)}const a=i.installCommand;console.log(r.gray("$ ")+r.white(a));try{return o(a,{stdio:"inherit"}),v(),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&&!a.startsWith("npm "))throw new Error(`Failed to install ${i.displayName}: ${o}`);console.log(r.yellow(" ! "+("win32"===process.platform?n.t("install.permission_windows",{command:a}):n.t("install.permission_unix",{command:a}))))}const{action:c}=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"===c)throw new Error(n.t("install.user_cancelled"));if(v(),!this.isToolInstalled(t))throw console.log(r.red("× "+n.t("install.still_not_installed",{tool:i.displayName}))),new Error(`${i.displayName} is not installed`);console.log(r.green("√ "+n.t("install.verified_success",{tool:i.displayName})))}getToolConfig(o){const t=s(o);if(!t)throw new Error(`Unknown tool: ${o}`);try{return t.getConfig()}catch(t){return i.warn(`Failed to read config for ${o}:`,t),i.logError(`ToolManager.getToolConfig(${o})`,t),null}}updateToolConfig(o,t){const n=s(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=s(o);if(!t)throw new Error(`Unknown tool: ${o}`);const n=t.forceResetPaths?t.forceResetPaths():this.backupPathsFor(t),e=[];for(const o of n)m(o)&&(d(o),f(o,{force:!0}),e.push(o));return e}loadPrivateConfig(o,t,n,e,r={}){const i=s(o);if(!i)throw new Error(`Unknown tool: ${o}`);r.force&&this.forceResetConfig(o),i.loadPrivateConfig({apiKey:t,baseUrl:l.getBaseUrl(),models:n,settings:l.getToolSettings(o),...e?{catalog:e}:{}})}async applyPrivateConfig(o,t,n,e={}){const r=this.installedVersion(o);return j(`apply:${o}`,()=>this.applyPrivateConfigNow(o,t,n,e),{...r?{tool_version:r}:{},...e.force?{force:!0}:{}})}async applyPrivateConfigNow(o,t,n,e){const r=s(o);if(!r)throw new Error(`Unknown tool: ${o}`);const i=r.wantsModelCatalog?await P(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=s(o);if(!t)return[];const e=[];try{t.applyNotes&&e.push(...t.applyNotes())}catch(t){i.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?`${N} upgrade ${o}`:t.upgradeCommand||t.installCommand})});for(const o of t.upgradeHints?.(r.min)??[])e.push({kind:"action",text:o})}const l=t.installSpec?C(t.installSpec):[];return l.length>1&&e.push({kind:"action",text:n.t("upgrade.duplicates_note",{count:String(l.length),active:k(l[0]),others:l.slice(1).map(k).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))i.record(`${n}: ${o.text}`);const l=e.filter(o=>"summary"===o.kind).map(o=>o.text).join(";"),s=" ".repeat(Math.max(1,t-y(n)));console.log(r.green("√ "+n)+(l?s+l:""));for(const o of e.filter(o=>"action"===o.kind))console.log(r.yellow(" ! "+o.text))}installedVersion(o){const n=s(o);if(!n)return null;if(n.installSpec)return C(n.installSpec)[0]?.version??null;if(n.installedVersion)try{return n.installedVersion()}catch(t){return i.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=T(o);if(!t)return null;const n=this.installedVersion(o);return n&&$(n,t)<0?{current:n,min:t}:null}unloadPrivateConfig(o){const t=s(o);if(!t)throw new Error(`Unknown tool: ${o}`);try{t.unloadPrivateConfig({savedKeys:I()}),M(`remove:${o}`,"ok")}catch(t){throw M(`remove:${o}`,"fail",{error:t}),t}let e=[];try{e=t.unloadNotes?.()??[]}catch(t){i.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=s(o);if(!t)throw new Error(`Unknown tool: ${o}`);if(l.setToolModel(o,null),!t.clearPinnedModels)return[];const n=l.getApiKeyForTool(o),e=t.wantsModelCatalog&&n?await P(n):null;return t.clearPinnedModels(e??void 0)}supportsClearPinnedModels(o){return Boolean(s(o)?.clearPinnedModels)}holdsOurConfig(o){const t=s(o);if(!t)return!1;const n=I();return t.holdsOurConfig?t.holdsOurConfig(n):Boolean(t.detectCurrentConfig().apiKey)}detectCurrentConfig(o){const t=s(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=s(o);if(!t)throw new Error(`Unknown tool: ${o}`);return this.backupPathsFor(t).map(o=>({file:o,backups:p(o)}))}restorePrivateConfig(o){const t=s(o);if(!t)throw new Error(`Unknown tool: ${o}`);return this.backupPathsFor(t).map(o=>({file:o,result:u(o)}))}getInstalledTools(){return Object.keys(SUPPORTED_TOOLS).filter(o=>this.isToolInstalled(o))}getSupportedTools(){return a().filter(o=>!o.hidden).map(o=>x(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();
|
package/dist/lib/tool-upgrade.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawn as t,spawnSync as e}from"child_process";import{rmSync as o}from"fs";import{join as r}from"path";import n from"chalk";import i from"inquirer";import{i18n as a}from"./i18n.js";import{logger as s}from"../utils/logger.js";import{compareVersions as l,getToolMinVersion as c}from"./model-registry.js";import{getAdapter as p}from"./tools/registry.js";import{findInstalls as u,forgetInstalls as m,installLabel as d,npmMirrorInstallCommand as g,npmUninstallCommand as
|
|
1
|
+
import{spawn as t,spawnSync as e}from"child_process";import{rmSync as o}from"fs";import{join as r}from"path";import n from"chalk";import i from"inquirer";import{i18n as a}from"./i18n.js";import{logger as s}from"../utils/logger.js";import{compareVersions as l,getToolMinVersion as c}from"./model-registry.js";import{getAdapter as p}from"./tools/registry.js";import{findInstalls as u,forgetInstalls as m,installLabel as d,npmMirrorInstallCommand as g,npmMirrorVersion as f,npmUninstallCommand as w}from"./tools/tool-installs.js";import{toolHome as y}from"./tools/types.js";import{isNonInteractive as h,shouldAutoConfirm as _}from"./runtime-options.js";import{track as v}from"./telemetry.js";let k="ok",b=async(t,o,r={})=>(console.log(n.gray("$ ")+[t,...o].join(" ")),k=r.idleMs?await runWatched(t,o,r):function(t,o,r){const n=$(t)?e(T(t,o),{stdio:"inherit",shell:!0,timeout:r}):e(t,o,{stdio:"inherit",timeout:r});return n.error&&s.logError(`upgrade: ${t}`,n.error),"ETIMEDOUT"===n.error?.code?"timeout":0===n.status?"ok":"fail"}(t,o,r.timeoutMs),"ok"===k);const $=t=>"win32"===process.platform&&!/\.exe$/i.test(t),T=(t,e)=>[t,...e].map(t=>/\s/.test(t)?`"${t}"`:t).join(" ");export function runWatched(e,o,r){return new Promise(n=>{const i=$(e)?t(T(e,o),{stdio:["inherit","pipe","pipe"],shell:!0}):t(e,o,{stdio:["inherit","pipe","pipe"]});let a;const l=t=>{a=t,i.kill()};let c;const p=()=>{clearTimeout(c),r.idleMs&&(c=setTimeout(()=>l("stalled"),r.idleMs))},u=r.timeoutMs?setTimeout(()=>l("timeout"),r.timeoutMs):void 0;p(),i.stdout?.on("data",t=>{process.stdout.write(t),p()}),i.stderr?.on("data",t=>{process.stderr.write(t),p()});const m=t=>{clearTimeout(c),clearTimeout(u),n(t)};i.on("error",t=>{s.logError(`upgrade: ${e}`,t),m(a??"fail")}),i.on("close",t=>{a&&process.stdout.write("\n"),m(a??(0===t?"ok":"fail"))})})}export function setUpgradeRunnerForTests(t){b=async(e,o,r)=>{const n=await t(e,o,r);return k="string"==typeof n?n:n?"ok":"fail","ok"===k}}const j={ok:"install.script_failed_npm",fail:"install.script_failed_npm",stalled:"install.script_stalled_npm",timeout:"install.script_timeout_npm"};export async function mirrorInstall(t){if(!t.mirrorScript)return M(t);console.log(n.gray(a.t("install.downloading")));const e=`install-script:${t.command}`,o=Date.now();v(e,"start");const r={idleMs:18e4,timeoutMs:36e5},i="win32"===process.platform?await b("powershell.exe",["-NoProfile","-ExecutionPolicy","Bypass","-Command",`irm ${t.mirrorScript.ps1} -TimeoutSec 30 | iex`],r):await b("sh",["-c",`script=$(curl -fsSL --connect-timeout 15 --max-time 60 ${t.mirrorScript.sh}) && printf '%s\\n' "$script" | sh`],r),s=k;return v(e,"stalled"===s?"timeout":s,{duration_ms:Date.now()-o,..."stalled"===s||"timeout"===s?{detail:{reason:s}}:{}}),i||!t.npmPackage?i:(console.log(n.yellow(" ! "+a.t(j[s],{minutes:String(3)}))),v(e,"fallback"),M(t))}async function M(t){const e=g(t,await f(t)),[o,...r]=e.split(" "),i=`install-npm:${t.command}`,s=Date.now();v(i,"start");const l=await b(o,r);return v(i,l?"ok":"fail",{duration_ms:Date.now()-s}),l||"win32"===process.platform||console.log(n.yellow(" ! "+a.t("upgrade.npm_permission",{command:e}))),l}async function D(t,e){switch(e.kind){case"npm":t.npmPackage&&await b("npm",["uninstall","-g",t.npmPackage]);break;case"brew":t.brew&&await b("brew",["uninstall",t.brew]);break;case"native":try{o(e.path,{force:!0});for(const e of t.native?.dataDirs??[])o(r(y(),...e),{recursive:!0,force:!0})}catch(t){s.logError("upgrade: remove native copy",t)}break;default:return!1}return m(),!u(t).some(t=>t.path===e.path)}function x(t,e){switch(e.kind){case"npm":return w(t);case"brew":return`brew uninstall ${t.brew}`;case"native":return a.t("upgrade.delete_paths",{paths:[e.path,...(t.native?.dataDirs??[]).map(t=>r(y(),...t))].join("、")});default:return a.t("upgrade.delete_paths",{paths:e.path})}}export async function upgradeTool(t){const e=Date.now();v(`upgrade:${t}`,"start");try{const o=await async function(t){const e=p(t),o=e?.installSpec;if(!e||!o)throw new Error(a.t("upgrade.unsupported",{tool:t}));const r=e.displayName;m();const g=u(o);if(console.log(n.bold(`\n${r}`)),0===g.length)console.log(a.t("upgrade.not_installed_installing",{tool:r})),await mirrorInstall(o);else{const t=g[0];console.log(n.gray(" "+a.t("upgrade.current",{copy:d(t)})));const e=await async function(t,e){switch(e.kind){case"native":return b(e.path,t.native?.updateArgs??["update"],{timeoutMs:t.native?.updateTimeoutMs});case"npm":return M(t);case"brew":return!!t.brew&&b("brew",["upgrade",t.brew]);default:return!1}}(o,t);e||"other"!==t.kind?e||"npm"===t.kind||"native"===t.kind&&await async function(t){const e=t.native?.mirrorUpdate;if(!e)return!1;console.log(n.yellow(" ! "+a.t("upgrade.native_mirror_trying")));try{const{version:t,manifestVerified:o}=await e();return console.log(n.green(" √ "+a.t(o?"upgrade.native_mirror_done_verified":"upgrade.native_mirror_done",{version:t}))),!0}catch(t){return s.logError("upgrade: native mirror",t),console.log(n.yellow(" ! "+a.t("upgrade.native_mirror_failed",{reason:t instanceof Error?t.message:String(t)}))),!1}}(o)||(console.log(n.yellow(" ! "+a.t("upgrade.fallback_mirror"))),await mirrorInstall(o)):console.log(n.yellow(" ! "+a.t("upgrade.unknown_install",{path:t.path})))}m(),await async function(t,e){const o=u(t);if(o.length<2)return;const r=function(t){return t.reduce((t,e)=>e.version&&(!t.version||l(e.version,t.version)>0)?e:t)}(o),s=o.filter(t=>t!==r);console.log(n.yellow(" ! "+a.t("upgrade.duplicates",{tool:e,keep:d(r),others:s.map(d).join("、")})));let c=_();c||h()||!process.stdin.isTTY||(c=(await i.prompt([{type:"confirm",name:"remove",message:a.t("upgrade.confirm_remove"),default:!0}])).remove);for(const e of s)c&&await D(t,e)?console.log(n.green(" √ "+a.t("upgrade.removed",{copy:d(e)}))):console.log(n.yellow(" ! "+a.t("upgrade.remove_by_hand",{how:x(t,e)})))}(o,r),m();const f=u(o)[0];if(!f)return console.log(n.red(" × "+a.t("upgrade.still_missing",{tool:r}))),!1;const w=c(t);if(w&&f.version&&l(f.version,w)<0){console.log(n.yellow(" ! "+a.t("upgrade.still_old",{copy:d(f),min:w})));for(const t of e.upgradeHints?.(w)??[])console.log(n.yellow(" ! "+t));return!1}return console.log(n.green(" √ "+a.t("upgrade.done",{copy:d(f)}))),!0}(t);return v(`upgrade:${t}`,o?"ok":"fail",{duration_ms:Date.now()-e}),o}catch(o){throw v(`upgrade:${t}`,"fail",{duration_ms:Date.now()-e,error:o}),o}}
|
package/dist/lib/tools/grok.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync as e,readFileSync as t}from"fs";import{join as o}from"path";import*as r from"@iarna/toml";import{logger as n}from"../../utils/logger.js";import{PROVIDER_KEY as i}from"../brand.js";import{backupBeforeWrite as s,atomicWriteFile as l}from"./backup.js";import{pickModel as
|
|
1
|
+
import{existsSync as e,readFileSync as t}from"fs";import{join as o}from"path";import*as r from"@iarna/toml";import{logger as n}from"../../utils/logger.js";import{PROVIDER_KEY as i}from"../brand.js";import{backupBeforeWrite as s,atomicWriteFile as l}from"./backup.js";import{pickModel as a,toolHome as d,withV1 as m}from"./types.js";import{i18n as f}from"../i18n.js";import{getToolDefaultModel as g}from"../model-registry.js";import{gatewayModelSpecs as u,modelBlurb as c,modelFamily as p,prettyModelName as y}from"../gateway-models.js";import{brandInstallScripts as k,mirrorInstallCommand as b}from"./tool-installs.js";import{OFFICIAL_PLUGINS as h}from"./claude-plugins.js";const j=()=>o(o(d(),".grok"),"config.toml"),_=i,w=`${i}-`,A=["low","medium","high","xhigh"];let v=null;const C=e=>`${w}${e}`,M=e=>e===_||e.startsWith(w),x={command:"grok",npmPackage:"@xai-official/grok",npmMirrorTagStale:!0,mirrorScript:k("grok"),native:{binDir:[".grok","bin"],updateArgs:["update"],updateTimeoutMs:12e4,dataDirs:[[".grok","downloads"]]}};function S(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function E(e,t){return S(e[t])||(e[t]={}),e[t]}function O(){if(!e(j()))return{};const o=t(j(),"utf-8");if(!o.trim())return{};try{const e=r.parse(o);if(!S(e))throw new Error("config.toml root must be a TOML table");return e}catch(e){throw new Error(`Existing ~/.grok/config.toml cannot be parsed; back it up and fix it first: ${e instanceof Error?e.message:String(e)}`)}}function P(e){return S(e.model)?Object.entries(e.model).filter(e=>M(e[0])&&S(e[1])):[]}function N(e,t){let o=u("grok",e.catalog?.clientModels);if(e.catalog){const t=new Set(e.catalog.models);o=o.filter(e=>t.has(e.id))}return o.some(e=>e.id===t)?o:[{id:t},...o]}function $(e,t,o){E(e,"endpoints").models_base_url=m(t.baseUrl);const r=E(e,"model"),n=new Map(P(e));for(const e of n.keys())delete r[e];for(const e of o){const o=C(e.id),i={...n.get(o)??{},name:e.name??y(e.id),model:e.id,base_url:m(t.baseUrl),api_key:t.apiKey,context_window:e.contextWindow??5e5,api_backend:"responses",reasoning_summary:"concise"};"grok"===p(e.id)&&(i.supports_reasoning_effort=!0,i.reasoning_efforts=A);const s=c(e.description);s?i.description=s:delete i.description,r[o]=i}}export const grokAdapter={name:"grok",displayName:"Grok Build",command:"grok",installCommand:b(x),installSpec:x,configPath:j(),wantsModelCatalog:!0,loadPrivateConfig(e){const t=O(),o=a(e.models,g("grok")),n=N(e,o);$(t,e,n);const i=e=>e.name??y(e.id);v={names:n.map(i),defaultName:i(n.find(e=>e.id===o))},E(t,"models").default=C(o),function(e){const t=E(e,"plugins"),o=e=>Array.isArray(e)?e.map(String):[],r=o(t.enabled),n=o(t.disabled),i=h.filter(e=>!r.includes(e)&&!n.includes(e));i.length>0&&(t.disabled=[...n,...i])}(t),s(j()),l(j(),r.stringify(t))},unloadPrivateConfig(){if(!e(j()))return;let t;try{t=O()}catch(e){return void n.logError("grokAdapter.unloadPrivateConfig",e)}if(S(t.model)){for(const[e]of P(t))delete t.model[e];0===Object.keys(t.model).length&&delete t.model}S(t.models)&&"string"==typeof t.models.default&&M(t.models.default)&&(delete t.models.default,0===Object.keys(t.models).length&&delete t.models),S(t.endpoints)&&(delete t.endpoints.models_base_url,0===Object.keys(t.endpoints).length&&delete t.endpoints),function(e){if(!S(e.plugins)||!Array.isArray(e.plugins.disabled))return;const t=e.plugins.disabled.filter(e=>!h.includes(e));t.length>0?e.plugins.disabled=t:delete e.plugins.disabled,0===Object.keys(e.plugins).length&&delete e.plugins}(t),s(j()),l(j(),r.stringify(t))},detectCurrentConfig(){try{const e=O(),t=P(e),o=S(e.models)?e.models.default:void 0,r=t.find(([e])=>e===o)?.[1]??t[0]?.[1],n=r?r.api_key:null;return{apiKey:"string"==typeof n&&n.trim()?n:null}}catch{return{apiKey:null}}},listedModels(){try{const e=P(O());return e.length>0?e.map(([,e])=>String(e.model)):null}catch{return null}},refreshModelMenu(e){const t=O(),o=E(t,"models"),n="string"==typeof o.default?o.default:void 0,i=n?P(t).find(([e])=>e===n)?.[1].model:void 0,d="string"==typeof i&&n!==_&&e.catalog.models.includes(i)?i:a(e.models,g("grok")),m=r.stringify(t);$(t,e,N(e,d)),(void 0===n||M(n))&&(o.default=C(d)),r.stringify(t)!==m&&(s(j()),l(j(),r.stringify(t)))},applyNotes:()=>v?[{kind:"summary",text:f.t("tools.grok.menu_written",{count:String(v.names.length),list:v.names.join(f.t("tools.grok.list_separator")),default:v.defaultName})}]:[],getConfig(){try{return O()}catch(e){return n.logError("grokAdapter.getConfig",e),null}}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawnSync as
|
|
1
|
+
import{spawnSync as t}from"child_process";import{existsSync as r,realpathSync as n,statSync as e}from"fs";import{delimiter as o,dirname as s,isAbsolute as i,join as a}from"path";import{i18n as c}from"../i18n.js";import{toolHome as p}from"./types.js";import{brand as m}from"../brand.js";export const NPM_MIRROR="https://registry.npmmirror.com";export function brandInstallScripts(t){const r=m().installMirror?.scripts;return r?{sh:`${r}/${t}.sh`,ps1:`${r}/${t}.ps1`}:void 0}export function npmMirrorInstallCommand(t,r="latest"){return`npm install -g ${t.npmPackage}@${r} --registry=${NPM_MIRROR}`}const l=/^(\d+)\.(\d+)\.(\d+)$/;function u(t,r){const n=l.exec(t).slice(1).map(Number),e=l.exec(r).slice(1).map(Number);for(let o=0;o<3;o++)if(n[o]!==e[o])return n[o]>e[o]?t:r;return t}async function f(t,r,n){const e=await fetch(t,{signal:AbortSignal.timeout(r),headers:n});if(!e.ok)throw new Error(`HTTP ${e.status}`);return e.json()}export async function npmMirrorVersion(t){if(!t.npmPackage||!t.npmMirrorTagStale)return"latest";let r=d.get(t.npmPackage);return r||d.set(t.npmPackage,r=async function(t){try{const{version:r}=await f(`https://registry.npmjs.org/${t}/latest`,1e4);if("string"==typeof r&&l.test(r))return r}catch{}try{const r=await f(`${NPM_MIRROR}/${t}`,2e4,{accept:"application/vnd.npm.install-v1+json"}),n=Object.keys(r.versions??{}).filter(t=>l.test(t));if(n.length)return n.reduce(u)}catch{}return"latest"}(t.npmPackage)),r}const d=new Map;export function mirrorInstallCommand(t){return t.mirrorScript?"win32"===process.platform?`powershell -NoProfile -ExecutionPolicy Bypass -Command "irm ${t.mirrorScript.ps1} | iex"`:`curl -fsSL ${t.mirrorScript.sh} | sh`:t.npmPackage?npmMirrorInstallCommand(t):""}export function npmUninstallCommand(t){return`npm uninstall -g ${t.npmPackage}`}export function installLabel(t){return c.t("upgrade.install_label",{kind:c.t(`upgrade.kind.${t.kind}`),version:t.version??"?",path:t.path})}let g=r=>{const n={encoding:"utf-8",timeout:1e4,windowsHide:!0,stdio:["ignore","pipe","pipe"]};return`${(/\.cmd$/i.test(r)?t(`"${r}" --version`,{...n,shell:!0}):t(r,["--version"],n)).stdout??""}`};const h=new Map;export function setVersionRunnerForTests(t){g=t,h.clear(),d.clear()}export function forgetInstalls(){h.clear()}function $(t){try{return e(t).isFile()}catch{return!1}}function w(t,e){if(t.native&&(o=s(e),i=a(p(),...t.native.binDir),"win32"===process.platform?o.toLowerCase()===i.toLowerCase():o===i))return"native";var o,i;const c=t.npmPackage?a("node_modules",...t.npmPackage.split("/")):null;if(c&&r(a(s(e),c)))return"npm";let m=e;try{m=n(e)}catch{return"other"}return c&&m.includes(c)?"npm":/[\\/](Cellar|Caskroom)[\\/]/.test(m)?"brew":"other"}export function findInstalls(t){const r=h.get(t.command);if(r)return r;const e="win32"===process.platform?[`${t.command}.exe`,`${t.command}.cmd`]:[t.command],s=new Set,c=[];for(const r of(process.env.PATH??"").split(o))if(r&&i(r))for(const o of e){const e=a(r,o);if(!$(e))continue;let i=e;try{i=n(e)}catch{}const p="win32"===process.platform?i.toLowerCase():i;if(s.has(p))continue;s.add(p);const m=g(e).match(/(\d+)\.(\d+)\.(\d+)/);c.push({path:e,kind:w(t,e),version:m?m[0]:null})}return h.set(t.command,c),c}
|