@marsapi/cli 0.0.147 → 0.0.151
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 +12 -12
- package/components.json +157 -0
- package/dist/client-config.snapshot.json +12 -12
- package/dist/commands/components.js +1 -0
- package/dist/commands/config.js +1 -1
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/setup.js +1 -1
- package/dist/commands/upgrade.js +1 -1
- package/dist/components.json +157 -0
- package/dist/lib/app-update.js +1 -1
- package/dist/lib/brand.js +1 -1
- package/dist/lib/claude-code-manager.js +1 -1
- package/dist/lib/codex-sessions.js +1 -1
- package/dist/lib/command.js +1 -1
- package/dist/lib/components.js +1 -0
- package/dist/lib/config.js +1 -1
- package/dist/lib/dry-run.js +1 -1
- package/dist/lib/env-cleanup.js +1 -1
- package/dist/lib/gateway-addresses.js +1 -1
- package/dist/lib/i18n.js +1 -1
- package/dist/lib/model-registry.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/runtime-options.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-code.js +1 -1
- package/dist/lib/tools/claude-desktop-app.js +1 -1
- 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/tools/tool-installs.js +1 -1
- package/dist/lib/windows-env.js +1 -1
- package/dist/lib/wizard.js +1 -1
- package/dist/lib/write-plan.js +1 -1
- package/dist/lib/written-values.js +1 -0
- package/dist/locales/en_US.json +175 -12
- package/dist/locales/zh_CN.json +175 -12
- package/package.json +2 -1
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
{
|
|
30
30
|
"description": "轻量档 | 低延迟 | 高频短任务",
|
|
31
|
-
"group": "
|
|
31
|
+
"group": "grp_irydsgijuckh",
|
|
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",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
"description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
|
|
58
|
-
"group": "
|
|
58
|
+
"group": "grp_irydsgijuckh",
|
|
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_rld6af0zorqd",
|
|
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_6lyxfgbs440g",
|
|
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_6lyxfgbs440g",
|
|
95
95
|
"group_name": "",
|
|
96
96
|
"hidden": false,
|
|
97
97
|
"id": "claude-sonnet-4-6",
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
},
|
|
130
130
|
{
|
|
131
131
|
"description": "105 万上下文 | 12.8 万输出 | 前沿档",
|
|
132
|
-
"group": "
|
|
132
|
+
"group": "grp_irydsgijuckh",
|
|
133
133
|
"group_name": "",
|
|
134
134
|
"hidden": false,
|
|
135
135
|
"id": "gpt-5.6-sol",
|
|
@@ -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_bsbtt432saoq",
|
|
169
169
|
"group_name": "",
|
|
170
170
|
"hidden": false,
|
|
171
171
|
"id": "gpt-6-sol",
|
|
@@ -221,7 +221,7 @@
|
|
|
221
221
|
},
|
|
222
222
|
{
|
|
223
223
|
"description": "约 100 万上下文 | 深度推理 | 密集长文档",
|
|
224
|
-
"group": "
|
|
224
|
+
"group": "grp_z5khwusxuh2j",
|
|
225
225
|
"group_name": "",
|
|
226
226
|
"hidden": false,
|
|
227
227
|
"id": "gemini-3.1-pro",
|
|
@@ -239,7 +239,7 @@
|
|
|
239
239
|
},
|
|
240
240
|
{
|
|
241
241
|
"description": "高吞吐 | 低成本 | 大批量常规任务",
|
|
242
|
-
"group": "
|
|
242
|
+
"group": "grp_3pi5kyqkp51b",
|
|
243
243
|
"group_name": "",
|
|
244
244
|
"hidden": false,
|
|
245
245
|
"id": "gemini-3.5-flash",
|
package/components.json
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": 1,
|
|
3
|
+
"about": "Components the CLI installs and upgrades (its list / install / upgrade commands). Read by src/lib/components.ts and by scripts/gen-components-doc.mjs (docs, the install scripts' README). {scripts} = the brand's installMirror.scripts, {agy} = installMirror.agy, {devtools} = the neutral CNB mirror of fnm / uv / Git for Windows.",
|
|
4
|
+
"devtools": "https://cnb.cool/lib/devtools/-/releases/latest/download",
|
|
5
|
+
"components": [
|
|
6
|
+
{
|
|
7
|
+
"id": "node",
|
|
8
|
+
"name": "Node.js",
|
|
9
|
+
"category": "runtime",
|
|
10
|
+
"aliases": ["nodejs"],
|
|
11
|
+
"platforms": ["darwin", "linux", "win32"],
|
|
12
|
+
"detect": { "command": "node", "pattern": "v(\\d+\\.\\d+\\.\\d+)" },
|
|
13
|
+
"latest": { "type": "node-lts", "url": "https://registry.npmmirror.com/-/binary/node/index.json" },
|
|
14
|
+
"sources": {
|
|
15
|
+
"all": "fnm({devtools})+ Node 镜像 https://npmmirror.com/mirrors/node"
|
|
16
|
+
},
|
|
17
|
+
"verify": { "checksum": "fnm:SHA256SUMS;Node:fnm 下载时核对官方 SHASUMS256.txt", "signature": "—" },
|
|
18
|
+
"install": { "type": "script", "script": "node", "forceEnv": { "NODE_INSTALL_FORCE": "1" } },
|
|
19
|
+
"upgrade": { "managedBy": "fnm", "migrateGlobalPackages": true },
|
|
20
|
+
"check": ["node", "--version"],
|
|
21
|
+
"requires": []
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "git",
|
|
25
|
+
"name": "Git",
|
|
26
|
+
"category": "runtime",
|
|
27
|
+
"platforms": ["darwin", "linux", "win32"],
|
|
28
|
+
"detect": { "command": "git", "pattern": "git version (\\d+\\.\\d+\\.\\d+)" },
|
|
29
|
+
"latest": { "type": "devtools", "key": "git", "platforms": ["win32"] },
|
|
30
|
+
"sources": {
|
|
31
|
+
"darwin": "苹果命令行工具(xcode-select)",
|
|
32
|
+
"linux": "系统包管理器(apt、dnf、yum、zypper、pacman、apk)",
|
|
33
|
+
"win32": "Git for Windows({devtools})"
|
|
34
|
+
},
|
|
35
|
+
"verify": {
|
|
36
|
+
"checksum": "Windows:SHA256SUMS(取自 GitHub 公布的 digest)",
|
|
37
|
+
"signature": "macOS / Linux:系统包管理器自己的签名"
|
|
38
|
+
},
|
|
39
|
+
"install": { "type": "script", "script": "git", "forceEnv": { "GIT_INSTALL_FORCE": "1" } },
|
|
40
|
+
"upgrade": { "managedBy": "git-for-windows-user" },
|
|
41
|
+
"check": ["git", "--version"],
|
|
42
|
+
"requires": []
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"id": "uv",
|
|
46
|
+
"name": "uv",
|
|
47
|
+
"category": "runtime",
|
|
48
|
+
"aliases": ["python-uv"],
|
|
49
|
+
"platforms": ["darwin", "linux", "win32"],
|
|
50
|
+
"detect": { "command": "uv", "pattern": "uv (\\d+\\.\\d+\\.\\d+)" },
|
|
51
|
+
"latest": { "type": "devtools", "key": "uv" },
|
|
52
|
+
"sources": {
|
|
53
|
+
"all": "uv 官方程序({devtools});Python 从 npmmirror 的 python-build-standalone 镜像、包从阿里云 PyPI 镜像"
|
|
54
|
+
},
|
|
55
|
+
"verify": { "checksum": "SHA256SUMS", "signature": "—" },
|
|
56
|
+
"install": { "type": "script", "script": "uv", "forceEnv": { "UV_INSTALL_FORCE": "1" } },
|
|
57
|
+
"upgrade": { "managedBy": "uv-standalone" },
|
|
58
|
+
"check": ["uv", "--version"],
|
|
59
|
+
"requires": []
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"id": "claude-code",
|
|
63
|
+
"name": "Claude Code",
|
|
64
|
+
"category": "cli",
|
|
65
|
+
"aliases": ["claude"],
|
|
66
|
+
"platforms": ["darwin", "linux", "win32"],
|
|
67
|
+
"adapter": "claude-code",
|
|
68
|
+
"latest": { "type": "npm", "package": "@anthropic-ai/claude-code" },
|
|
69
|
+
"sources": {
|
|
70
|
+
"all": "npmmirror 的 @anthropic-ai/claude-code-<平台>(与 downloads.claude.ai 同一文件),按官方原生布局安装({scripts}/claude-code.sh / .ps1)"
|
|
71
|
+
},
|
|
72
|
+
"verify": { "checksum": "npm sha512;连得上时再核对 Anthropic 发布清单的 sha256", "signature": "—" },
|
|
73
|
+
"install": { "type": "adapter" },
|
|
74
|
+
"check": ["claude", "--version"],
|
|
75
|
+
"requires": []
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"id": "codex",
|
|
79
|
+
"name": "Codex",
|
|
80
|
+
"category": "cli",
|
|
81
|
+
"platforms": ["darwin", "linux", "win32"],
|
|
82
|
+
"adapter": "codex",
|
|
83
|
+
"latest": { "type": "npm", "package": "@openai/codex" },
|
|
84
|
+
"sources": {
|
|
85
|
+
"all": "npmmirror 的 @openai/codex(vendor 目录与官方 codex-package 逐文件相同),按官方原生布局安装({scripts}/codex.sh / .ps1)"
|
|
86
|
+
},
|
|
87
|
+
"verify": { "checksum": "npm sha512", "signature": "—" },
|
|
88
|
+
"install": { "type": "adapter" },
|
|
89
|
+
"check": ["codex", "--version"],
|
|
90
|
+
"requires": []
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"id": "grok",
|
|
94
|
+
"name": "Grok Build",
|
|
95
|
+
"category": "cli",
|
|
96
|
+
"platforms": ["darwin", "linux", "win32"],
|
|
97
|
+
"adapter": "grok",
|
|
98
|
+
"latest": { "type": "npm", "package": "@xai-official/grok", "staleTag": true },
|
|
99
|
+
"sources": { "all": "npmmirror 的 @xai-official/grok-<平台>({scripts}/grok.sh / .ps1)" },
|
|
100
|
+
"verify": { "checksum": "npm sha512", "signature": "—" },
|
|
101
|
+
"install": { "type": "adapter" },
|
|
102
|
+
"check": ["grok", "--version"],
|
|
103
|
+
"requires": []
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"id": "agy",
|
|
107
|
+
"name": "Antigravity CLI",
|
|
108
|
+
"category": "cli",
|
|
109
|
+
"aliases": ["antigravity"],
|
|
110
|
+
"platforms": ["darwin", "linux", "win32"],
|
|
111
|
+
"adapter": "agy",
|
|
112
|
+
"latest": { "type": "version-file", "url": "{agy}/version.txt" },
|
|
113
|
+
"sources": { "all": "高速下载站 {agy}(每小时同步官方)" },
|
|
114
|
+
"verify": { "checksum": "官方清单的 sha512", "signature": "—" },
|
|
115
|
+
"install": { "type": "adapter" },
|
|
116
|
+
"check": ["agy", "--version"],
|
|
117
|
+
"requires": []
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"id": "claude-desktop",
|
|
121
|
+
"name": "Claude Desktop",
|
|
122
|
+
"category": "app",
|
|
123
|
+
"platforms": ["darwin", "win32"],
|
|
124
|
+
"app": "claude-desktop",
|
|
125
|
+
"latest": { "type": "app" },
|
|
126
|
+
"sources": {
|
|
127
|
+
"darwin": "高速下载站 lib/claude-desktop(官方 dmg)",
|
|
128
|
+
"win32": "高速下载站 lib/claude-desktop(官方 MSIX)"
|
|
129
|
+
},
|
|
130
|
+
"verify": {
|
|
131
|
+
"checksum": "SHA256SUMS",
|
|
132
|
+
"signature": "macOS:Team ID Q6L2SF6YDW + 公证;Windows:Authenticode O=Anthropic, PBC"
|
|
133
|
+
},
|
|
134
|
+
"install": { "type": "app" },
|
|
135
|
+
"requires": []
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"id": "chatgpt",
|
|
139
|
+
"name": "ChatGPT",
|
|
140
|
+
"category": "app",
|
|
141
|
+
"aliases": ["chatgpt-desktop", "codex-desktop", "codex-app"],
|
|
142
|
+
"platforms": ["darwin", "win32"],
|
|
143
|
+
"app": "chatgpt",
|
|
144
|
+
"latest": { "type": "app" },
|
|
145
|
+
"sources": {
|
|
146
|
+
"darwin": "高速下载站 lib/chatgpt-desktop(官方 dmg,只有 Apple 芯片版)",
|
|
147
|
+
"win32": "高速下载站 lib/chatgpt-desktop(Microsoft Store 同一个 MSIX)"
|
|
148
|
+
},
|
|
149
|
+
"verify": {
|
|
150
|
+
"checksum": "SHA256SUMS",
|
|
151
|
+
"signature": "macOS:Team ID 2DC432GLL2 + 公证;Windows:Microsoft Store 签名(OpenAI 发布者)"
|
|
152
|
+
},
|
|
153
|
+
"install": { "type": "app" },
|
|
154
|
+
"requires": []
|
|
155
|
+
}
|
|
156
|
+
]
|
|
157
|
+
}
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
{
|
|
30
30
|
"description": "轻量档 | 低延迟 | 高频短任务",
|
|
31
|
-
"group": "
|
|
31
|
+
"group": "grp_irydsgijuckh",
|
|
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",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
"description": "100 万上下文 | 推理 | 编程 | 长上下文不加价",
|
|
58
|
-
"group": "
|
|
58
|
+
"group": "grp_irydsgijuckh",
|
|
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_rld6af0zorqd",
|
|
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_6lyxfgbs440g",
|
|
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_6lyxfgbs440g",
|
|
95
95
|
"group_name": "",
|
|
96
96
|
"hidden": false,
|
|
97
97
|
"id": "claude-sonnet-4-6",
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
},
|
|
130
130
|
{
|
|
131
131
|
"description": "105 万上下文 | 12.8 万输出 | 前沿档",
|
|
132
|
-
"group": "
|
|
132
|
+
"group": "grp_irydsgijuckh",
|
|
133
133
|
"group_name": "",
|
|
134
134
|
"hidden": false,
|
|
135
135
|
"id": "gpt-5.6-sol",
|
|
@@ -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_bsbtt432saoq",
|
|
169
169
|
"group_name": "",
|
|
170
170
|
"hidden": false,
|
|
171
171
|
"id": "gpt-6-sol",
|
|
@@ -221,7 +221,7 @@
|
|
|
221
221
|
},
|
|
222
222
|
{
|
|
223
223
|
"description": "约 100 万上下文 | 深度推理 | 密集长文档",
|
|
224
|
-
"group": "
|
|
224
|
+
"group": "grp_z5khwusxuh2j",
|
|
225
225
|
"group_name": "",
|
|
226
226
|
"hidden": false,
|
|
227
227
|
"id": "gemini-3.1-pro",
|
|
@@ -239,7 +239,7 @@
|
|
|
239
239
|
},
|
|
240
240
|
{
|
|
241
241
|
"description": "高吞吐 | 低成本 | 大批量常规任务",
|
|
242
|
-
"group": "
|
|
242
|
+
"group": "grp_3pi5kyqkp51b",
|
|
243
243
|
"group_name": "",
|
|
244
244
|
"hidden": false,
|
|
245
245
|
"id": "gemini-3.5-flash",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import t from"chalk";import{appUpgradeCommand as e,upgradeApp as n}from"../lib/app-update.js";import{CLI_NAME as o}from"../lib/brand.js";import{componentStatus as r,listComponents as a,prefetchLatest as l,resolveComponent as s,runRuntime as i,upgradeAdvice as c}from"../lib/components.js";import{i18n as u}from"../lib/i18n.js";import{emitJson as d,isJsonMode as p,progressToStderr as m}from"../lib/runtime-options.js";import{mirrorInstall as f,upgradeTool as g}from"../lib/tool-upgrade.js";import{getAdapter as _}from"../lib/tools/registry.js";import{findInstallsIncludingNative as y,forgetInstalls as b}from"../lib/tools/tool-installs.js";function h(t){p()?process.stderr.write(t+"\n"):console.log(t)}function w(t){let e=0;for(const n of t)e+=/[ᄀ-ᅟ⺀-가-힣豈-︰-﹏-⦆¢-₩]/.test(n)?2:1;return e}function k(t,e){return t+" ".repeat(Math.max(0,e-w(t)))}export function resolveTargets(t){const e=[],n=[],o=(t,e)=>{if(!n.includes(t)&&!e.includes(t.id)){for(const n of t.requires){const r=s(n);r&&o(r,[...e,t.id])}n.push(t)}};for(const n of t){const t=s(n);t?o(t,[]):e.push(n)}return{specs:n,unknown:e}}function v(e){return e.supported?!e.installed&&e.blocker?t.gray(function(t){for(const e of[`components.reason_${t}`,`app_update.reason_${t}`]){const t=u.t(e);if(t!==e)return t}return t}(e.blocker)):e.installed?e.outdated?t.yellow(e.auto_upgrade?u.t("components.state.outdated_auto",{command:`${o} upgrade ${e.id}`}):u.t("components.state.outdated_manual",{how:e.hint??u.t(`components.how_${e.managed_by??"other"}`,{tool:e.name})})):e.latest?t.green(u.t("components.state.latest")):t.gray(u.t("components.state.unknown_latest")):t.gray(u.t("components.state.missing",{command:`${o} install ${e.id}`})):t.gray(u.t("components.state.unsupported"))}export async function listCommand(e={}){const n=a(),o=await l(n,{refresh:e.refresh}),s=[];for(const t of n)s.push(await r(t,{latest:o.get(t.id)}));if(p())return void d({components:s});const i=s.map(t=>({s:t,cells:[t.name,t.installed?t.current??"?":"—",t.latest??"—",t.installed?u.t(`components.by.${t.managed_by??"other"}`):"—"]})),c=[u.t("components.col.name"),u.t("components.col.current"),u.t("components.col.latest"),u.t("components.col.managed")],m=c.map((t,e)=>Math.max(w(t),...i.map(t=>w(t.cells[e])))+2);for(const e of["runtime","cli","app"]){const n=i.filter(t=>t.s.category===e);if(n.length){console.log(t.bold(`\n${u.t(`components.category.${e}`)}`)),console.log(t.gray(" "+c.map((t,e)=>k(t,m[e])).join("")+u.t("components.col.state")));for(const{s:e,cells:o}of n)console.log(" "+o.map((t,e)=>k(t,m[e])).join("")+v(e)),e.source&&e.supported&&console.log(t.gray(" "+u.t("components.source",{source:e.source})))}}const f=s.filter(t=>t.error&&!t.latest);f.length&&console.log(t.yellow("\n ! "+u.t("components.latest_unknown",{tools:f.map(t=>t.name).join("、")})))}export async function installComponent(o,a){return p()||console.log(t.bold(`\n${o.name}`)),"runtime"===o.category?i(o,"install",{force:a}):"cli"===o.category?async function(e,n){const o=_(e.adapter),a=await r(e,{refresh:!0}),l={tool:e.id,category:"cli",current:a.current,latest:a.latest,version_after:null};if(!o?.installSpec)return{...l,result:"unavailable",ok:!1,reason:"no_install_spec"};if(a.blocker)return h(t.yellow(" ! "+u.t(`components.blocked_${a.blocker}`,{tool:e.name}))),{...l,result:"unavailable",ok:!1,reason:a.blocker};if(a.installed&&!n){const n=t.gray(`(${a.path})`);return a.outdated?(h(t.green(" √ "+u.t("components.already_installed",{tool:e.name,current:a.current??"?"}))+n),h(t.yellow(" ! "+c(a))),{...l,result:"already_installed",ok:!0,hint:c(a)}):(h(t.green(" √ "+u.t(a.latest?"components.up_to_date":"components.already_installed",{tool:e.name,current:a.current??"?"}))+n),{...l,result:"already_installed",ok:!0})}let s;a.installed?(h(t.yellow(" ! "+u.t("components.reinstalling",{tool:e.name,current:a.current??"?"}))),s=await f(o.installSpec)):s=await g(o.name),b();const i=y(o.installSpec)[0];a.installed&&s&&h(t.green(" √ "+u.t("components.reinstalled",{tool:e.name,version:i?.version??"?"})));const d=s&&i?a.installed?"reinstalled":"installed":"failed";return{...l,result:d,ok:"failed"!==d,version_after:i?.version??null}}(o,a):async function(o,a){const l=await r(o,{refresh:!0});if(l.installed&&!a){const n={tool:o.id,category:"app",current:l.current,latest:l.latest,version_after:null};if(l.outdated){h(t.green(" √ "+u.t("components.already_installed",{tool:o.name,current:l.current??"?"})));const r=u.t("app_update.upgrade_hint",{tool:o.name,current:l.current??"?",latest:l.latest??"?",command:e(o.app)});return h(t.yellow(" ! "+r)),{...n,result:"already_installed",ok:!0,hint:r}}return h(t.green(" √ "+u.t(l.latest?"components.up_to_date":"components.already_installed",{tool:o.name,current:l.current??"?"}))),{...n,result:"already_installed",ok:!0}}return function(t,e){const n={installed:"installed",upgraded:e.current&&e.latest&&e.current===e.version_after?"reinstalled":"upgraded",up_to_date:"up_to_date",declined:"manual",offered:"already_installed",left_running:"manual",not_installed:"unavailable",unavailable:"unavailable",failed:"failed"}[e.result]??"failed";return{tool:t.id,category:"app",current:e.current,latest:e.latest,result:n,version_after:e.version_after,ok:["installed","upgraded","reinstalled","up_to_date","already_installed"].includes(n),...e.reason?{reason:e.reason}:{}}}(o,await n(o.app,{install:!0,force:a}))}(o,a)}export async function installCommand(e,n={}){const{specs:o,unknown:r}=resolveTargets(e);if(r.length||!o.length)return console.error(t.red(u.t("components.unknown",{names:r.join(", ")||"—"}))),console.error(u.t("components.known",{ids:a().map(t=>t.id).join(" / ")})),void(process.exitCode=1);const l=[];for(const t of o)l.push(await m(()=>installComponent(t,Boolean(n.force))));p()&&d({components:l}),l.some(t=>!t.ok)&&(process.exitCode=1)}export async function outdatedRuntimeHints(){const t=a().filter(t=>"runtime"===t.category);return(await Promise.all(t.map(t=>r(t,{offline:!0})))).filter(t=>t.installed&&t.outdated).map(t=>c(t))}
|
package/dist/commands/config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import o from"inquirer";import e from"chalk";import{wizard as t}from"../lib/wizard.js";import{toolManager as n,SUPPORTED_TOOLS as l}from"../lib/tool-manager.js";import{i18n as i}from"../lib/i18n.js";import{configManager as r,DEFAULT_PROFILE_NAME as a}from"../lib/config.js";import{confirmAction as s,applyOrDryRun as c,requireTerminal as d}from"../lib/confirm.js";import{canPrompt as f,isDryRun as g,isNonInteractive as p,shouldAutoConfirm as m}from"../lib/runtime-options.js";const _=/^[a-zA-Z0-9._-]+$/;function u(o,e){const t=(o||"").trim();if(!t||!_.test(t))throw new Error(i.t(`config.${e}_invalid_name`,{name:t||"<empty>"}));return t}function y(o,t){console.log("\n"+e.bold(o)),0!==t.length?t.forEach(o=>console.log(" "+o)):console.log(e.gray(" ("+i.t("config.empty_list")+")"))}function v(o,t){if("backups"===t){const t=n.listToolBackups(o).flatMap(o=>{const t=o.file.replace(/^.*[/\\]/,"");return o.backups.length?o.backups.map(o=>`${e.cyan(t)} ${e.gray(o.name.split(".bak-")[1]||o.name)}`):[`${e.cyan(t)} ${e.gray("("+i.t("config.empty_list")+")")}`]});return void y(i.t("config.tool_backups_title",{tool:l[o].displayName}),t)}const r=n.restorePrivateConfig(o).filter(o=>o.result.restored);0!==r.length?(console.log(e.green(i.t("config.config_restored",{tool:l[o].displayName}))),r.forEach(o=>console.log(e.gray(` ${o.file} ← ${o.result.from}`))),console.log(e.yellow(" ! "+i.t("config.reopen_hint",{tool:l[o].displayName})))):console.log(e.yellow(i.t("config.restore_no_backup",{tool:l[o].displayName})))}async function w(a,p,m){if(!l[a])return void console.log(e.red(i.t("config.unknown_tool",{tool:a})));const _=(p[0]||"").toLowerCase();if("backups"!==_&&"list-backups"!==_)if("restore"!==_){if("remove"===_||"unload"===_){const o=l[a].displayName;return void await c({description:i.t("config.remove_dry_run",{tool:o}),json:{action:"remove",tool:a},apply:async()=>{if(!await s({message:i.t("config.confirm_remove",{tool:o,name:a}),defaultValue:!0}))return;const t=n.holdsOurConfig(a),l=n.unloadPrivateConfig(a);t?(console.log(e.green(i.t("config.remove_done",{tool:o}))),l.forEach(o=>console.log(e.yellow(" ! "+o.text)))):console.log(e.gray(i.t("config.remove_nothing",{tool:o})))}})}if("clear-model"===_||"clear-models"===_){const o=l[a].displayName;return n.supportsClearPinnedModels(a)?void await c({description:i.t("config.clear_model_dry_run",{tool:o}),json:{action:"clear_model",tool:a},apply:async()=>{const t=await n.clearPinnedModels(a);0!==t.length?(console.log(e.green(i.t("config.clear_model_done",{tool:o}))),t.forEach(o=>console.log(e.gray(` - ${o}`))),console.log(e.gray(i.t("config.clear_model_restart_hint",{tool:o})))):console.log(e.yellow(i.t("config.clear_model_none",{tool:o})))}}):void console.log(e.yellow(i.t("config.clear_model_unsupported",{tool:o})))}if(g())await c({description:i.t("config.tool_apply_dry_run",{tool:l[a].displayName}),json:{action:"apply",tool:a,force:Boolean(m.force)},apply:()=>{}});else{if(!n.isToolInstalled(a)){if(m.nonInteractive)return void console.log(e.yellow(i.t("wizard.tool_not_installed",{tool:l[a].displayName})));if(console.log(e.yellow(i.t("wizard.tool_not_installed",{tool:l[a].displayName}))),!f())return;const{shouldInstall:t}=await o.prompt([{type:"confirm",name:"shouldInstall",message:i.t("wizard.install_tool_confirm"),default:!0}]);if(!t)return void console.log(e.yellow(i.t("wizard.install_skipped")));try{await n.installTool(a)}catch(o){return console.error(e.red(i.t("install.install_failed_detail"))),void(o instanceof Error&&o.message&&console.error(e.gray(o.message)))}}if(m.nonInteractive||m.force){const o=r.getApiKeyForTool(a);if(!o)return void console.log(e.red(i.t("auth.reload_missing_config")));if(m.force&&!m.nonInteractive&&!await s({message:i.t("config.confirm_force",{tool:l[a].displayName}),defaultValue:!1}))return;return await n.applyPrivateConfig(a,o,r.getModelsForTool(a),{force:m.force}),m.force&&console.log(e.yellow(i.t("config.force_done",{tool:l[a].displayName,name:a}))),void n.printApplied(a)}d(),await t.showToolMenu(a)}}else await c({description:i.t("config.tool_restore_dry_run",{tool:l[a].displayName}),json:{action:"tool_restore",tool:a},apply:async()=>{await s({message:i.t("config.confirm_restore",{tool:l[a].displayName}),defaultValue:!1})&&v(a,"restore")}});else v(a,"backups")}export async function configCommand(t){const{positional:n,options:d}=function(o){const e=[],t={};(p()||m())&&(t.nonInteractive=!0);for(const n of o)"--non-interactive"===n||"-y"===n?t.nonInteractive=!0:"--force"===n||"-f"===n?t.force=!0:e.push(n);return{positional:e,options:t}}(t),g=n[0],v=n.slice(1);if(g){switch(g){case"profile":return void await async function(o){const t=o[0],n=o[1];if(!t||"list"===t){const o=r.getActiveProfileName(),t=r.listProfiles().map(t=>{const n=t===o;return`${n?e.green("●"):e.gray("○")} ${t}${n?e.gray(" ("+i.t("config.profile_active_label")+")"):""}`});return void y(i.t("config.profile_list_title"),t)}if("create"===t){const o=u(n,"profile");return r.listProfiles().includes(o)?void console.log(e.yellow(i.t("config.profile_exists",{name:o}))):void await c({description:i.t("config.profile_create_dry_run",{name:o}),json:{action:"profile_create",name:o},apply:()=>{r.createProfile(o),console.log(e.green(i.t("config.profile_created",{name:o})))}})}if("use"===t){const o=u(n,"profile");return void await c({description:i.t("config.profile_use_dry_run",{name:o}),json:{action:"profile_use",name:o},apply:()=>{r.setActiveProfile(o),console.log(e.green(i.t("config.profile_activated",{name:o})))}})}if("delete"===t||"remove"===t){const o=u(n,"profile");return o===a&&1===r.listProfiles().length?void console.log(e.yellow(i.t("config.profile_cannot_delete_last"))):void await c({description:i.t("config.profile_delete_dry_run",{name:o}),json:{action:"profile_delete",name:o},apply:async()=>{await s({message:i.t("config.profile_delete_confirm",{name:o}),defaultValue:!1})?(r.deleteProfile(o),console.log(e.green(i.t("config.profile_deleted",{name:o})))):console.log(e.yellow(i.t("config.profile_delete_aborted")))}})}console.log(e.red(i.t("config.unknown_action",{action:t})))}(v);case"preset":return void await async function(o){const t=o[0],n=o[1];if(!t||"list"===t){const o=Object.entries(r.getCustomPresets()).map(([o,t])=>`${e.cyan(o)} ${e.gray(`H:${t.models.haiku} S:${t.models.sonnet} O:${t.models.opus}`)}`);return void y(i.t("config.preset_list_title"),o)}if("save"===t){const o=u(n,"preset");return void await c({description:i.t("config.preset_save_dry_run",{name:o}),json:{action:"preset_save",name:o},apply:()=>{r.saveCustomPreset(o,r.getModels()),console.log(e.green(i.t("config.preset_saved",{name:o})))}})}if("use"===t||"apply"===t){const o=u(n,"preset"),t=r.getCustomPresets()[o];return t?void await c({description:i.t("config.preset_use_dry_run",{name:o}),json:{action:"preset_use",name:o},apply:()=>{r.setModels(t.models),console.log(e.green(i.t("config.preset_applied",{name:o})))}}):void console.log(e.red(i.t("config.preset_not_found",{name:o})))}if("delete"===t||"remove"===t){const o=u(n,"preset");return void await c({description:i.t("config.preset_delete_dry_run",{name:o}),json:{action:"preset_delete",name:o},apply:()=>{r.deleteCustomPreset(o),console.log(e.green(i.t("config.preset_deleted",{name:o})))}})}console.log(e.red(i.t("config.unknown_action",{action:t})))}(v);case"tool-model":return void await async function(o){const t=o[0];if(!t||"list"===t){const o=r.getProfile().tool_models||{},t=Object.entries(o).map(([o,t])=>{const n=Object.entries(t).map(([o,e])=>`${o}=${e}`).join(" ");return`${e.cyan(o)} ${e.gray(n)}`});return void y(i.t("config.tool_model_list_title"),t)}if("set"===t){const t=(o[1]||"").trim(),n=o.length>=4?(o[2]||"").trim():"opus",a=(o.length>=4?o[3]:o[2]||"").trim();return l[t]?a&&_.test(n)?void await c({description:i.t("config.tool_model_set_dry_run",{tool:t,slot:n,model:a}),json:{action:"tool_model_set",tool:t,slot:n,model:a},apply:()=>{r.setToolModel(t,{[n]:a}),console.log(e.green(i.t("config.tool_model_set",{tool:t,slot:n,model:a})))}}):void console.log(e.red(i.t("config.tool_model_usage"))):void console.log(e.red(t?i.t("config.unknown_tool",{tool:t}):i.t("config.tool_model_usage")))}if("clear"===t||"remove"===t){const t=(o[1]||"").trim();return l[t]?void await c({description:i.t("config.tool_model_clear_dry_run",{tool:t}),json:{action:"tool_model_clear",tool:t},apply:()=>{r.setToolModel(t,null),console.log(e.green(i.t("config.tool_model_cleared",{tool:t})))}}):void console.log(e.red(t?i.t("config.unknown_tool",{tool:t}):i.t("config.tool_model_usage")))}console.log(e.red(i.t("config.unknown_action",{action:t})))}(v);case"backup":return void await function(o){return async function(o){const t=o[0],n=o[1];if(!t||"list"===t){const o=r.listBackups().map(o=>{const t=new Date(o.mtimeMs).toISOString();return`${e.cyan(o.name)} ${e.gray(t)}`});return void y(i.t("config.backup_list_title"),o)}if("create"!==t&&"snapshot"!==t)return"restore"===t?n?void await c({description:i.t("config.backup_restore_dry_run",{name:n}),json:{action:"backup_restore",name:n},apply:async()=>{await s({message:i.t("config.backup_restore_confirm",{name:n}),defaultValue:!1})?(r.restoreBackup(n),console.log(e.green(i.t("config.backup_restored",{name:n})))):console.log(e.yellow(i.t("config.backup_restore_aborted")))}}):void console.log(e.red(i.t("config.backup_restore_missing_name"))):void console.log(e.red(i.t("config.unknown_action",{action:t})));await c({description:i.t("config.backup_create_dry_run"),json:{action:"backup_create",name:n??null},apply:()=>{const o=r.createBackup(n);console.log(e.green(i.t("config.backup_created",{path:o})))}})}(o)}(v)}"claude-code"!==g&&"claude-code"!==v[0]?l[g]?await w(g,v,d):(console.error(e.red(i.t("config.unknown_command",{command:g}))),console.log(e.gray(i.t("config.usage_hint"))),Object.values(l).filter(o=>!o.hidden).forEach(o=>{console.log(e.gray(` - ${o.name}: ${o.displayName}`))})):await w("claude-code",v,d)}else await async function(t){if(t.nonInteractive||!f())return void console.log(e.red(i.t("config.requires_argument")));const{selectedTool:n}=await o.prompt([{type:"list",name:"selectedTool",message:i.t("wizard.select_tool"),choices:Object.values(l).filter(o=>!o.hidden).map(o=>({name:`${o.displayName} (${o.name})`,value:o.name}))}]);await w(n,[],t)}(d)}
|
|
1
|
+
import o from"inquirer";import e from"chalk";import{wizard as t}from"../lib/wizard.js";import{runFollowUps as n}from"../lib/post-apply.js";import{toolManager as l,SUPPORTED_TOOLS as i}from"../lib/tool-manager.js";import{i18n as r}from"../lib/i18n.js";import{configManager as a,DEFAULT_PROFILE_NAME as s}from"../lib/config.js";import{confirmAction as c,applyOrDryRun as d,requireTerminal as f}from"../lib/confirm.js";import{canPrompt as g,isDryRun as p,isNonInteractive as m,shouldAutoConfirm as _}from"../lib/runtime-options.js";const u=/^[a-zA-Z0-9._-]+$/;function y(o,e){const t=(o||"").trim();if(!t||!u.test(t))throw new Error(r.t(`config.${e}_invalid_name`,{name:t||"<empty>"}));return t}function v(o,t){console.log("\n"+e.bold(o)),0!==t.length?t.forEach(o=>console.log(" "+o)):console.log(e.gray(" ("+r.t("config.empty_list")+")"))}function w(o,t){if("backups"===t){const t=l.listToolBackups(o).flatMap(o=>{const t=o.file.replace(/^.*[/\\]/,"");return o.backups.length?o.backups.map(o=>`${e.cyan(t)} ${e.gray(o.name.split(".bak-")[1]||o.name)}`):[`${e.cyan(t)} ${e.gray("("+r.t("config.empty_list")+")")}`]});return void v(r.t("config.tool_backups_title",{tool:i[o].displayName}),t)}const n=l.restorePrivateConfig(o).filter(o=>o.result.restored);0!==n.length?(console.log(e.green(r.t("config.config_restored",{tool:i[o].displayName}))),n.forEach(o=>console.log(e.gray(` ${o.file} ← ${o.result.from}`))),console.log(e.yellow(" ! "+r.t("config.reopen_hint",{tool:i[o].displayName})))):console.log(e.yellow(r.t("config.restore_no_backup",{tool:i[o].displayName})))}async function b(s,m,_){if(!i[s])return void console.log(e.red(r.t("config.unknown_tool",{tool:s})));const u=(m[0]||"").toLowerCase();if("backups"!==u&&"list-backups"!==u)if("restore"!==u){if("remove"===u||"unload"===u){const o=i[s].displayName;return void await d({description:r.t("config.remove_dry_run",{tool:o}),json:{action:"remove",tool:s},apply:async()=>{if(!await c({message:r.t("config.confirm_remove",{tool:o,name:s}),defaultValue:!0}))return;const t=l.holdsOurConfig(s),n=l.unloadPrivateConfig(s);t?(console.log(e.green(r.t("config.remove_done",{tool:o}))),n.forEach(o=>console.log(e.yellow(" ! "+o.text)))):console.log(e.gray(r.t("config.remove_nothing",{tool:o})))}})}if("clear-model"===u||"clear-models"===u){const o=i[s].displayName;return l.supportsClearPinnedModels(s)?void await d({description:r.t("config.clear_model_dry_run",{tool:o}),json:{action:"clear_model",tool:s},apply:async()=>{const t=await l.clearPinnedModels(s);0!==t.length?(console.log(e.green(r.t("config.clear_model_done",{tool:o}))),t.forEach(o=>console.log(e.gray(` - ${o}`))),console.log(e.gray(r.t("config.clear_model_restart_hint",{tool:o})))):console.log(e.yellow(r.t("config.clear_model_none",{tool:o})))}}):void console.log(e.yellow(r.t("config.clear_model_unsupported",{tool:o})))}if(p())await d({description:r.t("config.tool_apply_dry_run",{tool:i[s].displayName}),json:{action:"apply",tool:s,force:Boolean(_.force)},apply:()=>{}});else{if(!l.isToolInstalled(s)){if(_.nonInteractive)return void console.log(e.yellow(r.t("wizard.tool_not_installed",{tool:i[s].displayName})));if(console.log(e.yellow(r.t("wizard.tool_not_installed",{tool:i[s].displayName}))),!g())return;const{shouldInstall:t}=await o.prompt([{type:"confirm",name:"shouldInstall",message:r.t("wizard.install_tool_confirm"),default:!0}]);if(!t)return void console.log(e.yellow(r.t("wizard.install_skipped")));try{await l.installTool(s)}catch(o){return console.error(e.red(r.t("install.install_failed_detail"))),void(o instanceof Error&&o.message&&console.error(e.gray(o.message)))}}if(_.nonInteractive||_.force){const o=a.getApiKeyForTool(s);if(!o)return void console.log(e.red(r.t("auth.reload_missing_config")));if(_.force&&!_.nonInteractive&&!await c({message:r.t("config.confirm_force",{tool:i[s].displayName}),defaultValue:!1}))return;return await l.applyPrivateConfig(s,o,a.getModelsForTool(s),{force:_.force,takeOver:!0}),_.force&&console.log(e.yellow(r.t("config.force_done",{tool:i[s].displayName,name:s}))),l.printApplied(s),void await n([s])}f(),await t.showToolMenu(s)}}else await d({description:r.t("config.tool_restore_dry_run",{tool:i[s].displayName}),json:{action:"tool_restore",tool:s},apply:async()=>{await c({message:r.t("config.confirm_restore",{tool:i[s].displayName}),defaultValue:!1})&&w(s,"restore")}});else w(s,"backups")}export async function configCommand(t){const{positional:n,options:l}=function(o){const e=[],t={};(m()||_())&&(t.nonInteractive=!0);for(const n of o)"--non-interactive"===n||"-y"===n?t.nonInteractive=!0:"--force"===n||"-f"===n?t.force=!0:e.push(n);return{positional:e,options:t}}(t),f=n[0],p=n.slice(1);if(f){switch(f){case"profile":return void await async function(o){const t=o[0],n=o[1];if(!t||"list"===t){const o=a.getActiveProfileName(),t=a.listProfiles().map(t=>{const n=t===o;return`${n?e.green("●"):e.gray("○")} ${t}${n?e.gray(" ("+r.t("config.profile_active_label")+")"):""}`});return void v(r.t("config.profile_list_title"),t)}if("create"===t){const o=y(n,"profile");return a.listProfiles().includes(o)?void console.log(e.yellow(r.t("config.profile_exists",{name:o}))):void await d({description:r.t("config.profile_create_dry_run",{name:o}),json:{action:"profile_create",name:o},apply:()=>{a.createProfile(o),console.log(e.green(r.t("config.profile_created",{name:o})))}})}if("use"===t){const o=y(n,"profile");return void await d({description:r.t("config.profile_use_dry_run",{name:o}),json:{action:"profile_use",name:o},apply:()=>{a.setActiveProfile(o),console.log(e.green(r.t("config.profile_activated",{name:o})))}})}if("delete"===t||"remove"===t){const o=y(n,"profile");return o===s&&1===a.listProfiles().length?void console.log(e.yellow(r.t("config.profile_cannot_delete_last"))):void await d({description:r.t("config.profile_delete_dry_run",{name:o}),json:{action:"profile_delete",name:o},apply:async()=>{await c({message:r.t("config.profile_delete_confirm",{name:o}),defaultValue:!1})?(a.deleteProfile(o),console.log(e.green(r.t("config.profile_deleted",{name:o})))):console.log(e.yellow(r.t("config.profile_delete_aborted")))}})}console.log(e.red(r.t("config.unknown_action",{action:t})))}(p);case"preset":return void await async function(o){const t=o[0],n=o[1];if(!t||"list"===t){const o=Object.entries(a.getCustomPresets()).map(([o,t])=>`${e.cyan(o)} ${e.gray(`H:${t.models.haiku} S:${t.models.sonnet} O:${t.models.opus}`)}`);return void v(r.t("config.preset_list_title"),o)}if("save"===t){const o=y(n,"preset");return void await d({description:r.t("config.preset_save_dry_run",{name:o}),json:{action:"preset_save",name:o},apply:()=>{a.saveCustomPreset(o,a.getModels()),console.log(e.green(r.t("config.preset_saved",{name:o})))}})}if("use"===t||"apply"===t){const o=y(n,"preset"),t=a.getCustomPresets()[o];return t?void await d({description:r.t("config.preset_use_dry_run",{name:o}),json:{action:"preset_use",name:o},apply:()=>{a.setModels(t.models),console.log(e.green(r.t("config.preset_applied",{name:o})))}}):void console.log(e.red(r.t("config.preset_not_found",{name:o})))}if("delete"===t||"remove"===t){const o=y(n,"preset");return void await d({description:r.t("config.preset_delete_dry_run",{name:o}),json:{action:"preset_delete",name:o},apply:()=>{a.deleteCustomPreset(o),console.log(e.green(r.t("config.preset_deleted",{name:o})))}})}console.log(e.red(r.t("config.unknown_action",{action:t})))}(p);case"tool-model":return void await async function(o){const t=o[0];if(!t||"list"===t){const o=a.getProfile().tool_models||{},t=Object.entries(o).map(([o,t])=>{const n=Object.entries(t).map(([o,e])=>`${o}=${e}`).join(" ");return`${e.cyan(o)} ${e.gray(n)}`});return void v(r.t("config.tool_model_list_title"),t)}if("set"===t){const t=(o[1]||"").trim(),n=o.length>=4?(o[2]||"").trim():"opus",l=(o.length>=4?o[3]:o[2]||"").trim();return i[t]?l&&u.test(n)?void await d({description:r.t("config.tool_model_set_dry_run",{tool:t,slot:n,model:l}),json:{action:"tool_model_set",tool:t,slot:n,model:l},apply:()=>{a.setToolModel(t,{[n]:l}),console.log(e.green(r.t("config.tool_model_set",{tool:t,slot:n,model:l})))}}):void console.log(e.red(r.t("config.tool_model_usage"))):void console.log(e.red(t?r.t("config.unknown_tool",{tool:t}):r.t("config.tool_model_usage")))}if("clear"===t||"remove"===t){const t=(o[1]||"").trim();return i[t]?void await d({description:r.t("config.tool_model_clear_dry_run",{tool:t}),json:{action:"tool_model_clear",tool:t},apply:()=>{a.setToolModel(t,null),console.log(e.green(r.t("config.tool_model_cleared",{tool:t})))}}):void console.log(e.red(t?r.t("config.unknown_tool",{tool:t}):r.t("config.tool_model_usage")))}console.log(e.red(r.t("config.unknown_action",{action:t})))}(p);case"backup":return void await function(o){return async function(o){const t=o[0],n=o[1];if(!t||"list"===t){const o=a.listBackups().map(o=>{const t=new Date(o.mtimeMs).toISOString();return`${e.cyan(o.name)} ${e.gray(t)}`});return void v(r.t("config.backup_list_title"),o)}if("create"!==t&&"snapshot"!==t)return"restore"===t?n?void await d({description:r.t("config.backup_restore_dry_run",{name:n}),json:{action:"backup_restore",name:n},apply:async()=>{await c({message:r.t("config.backup_restore_confirm",{name:n}),defaultValue:!1})?(a.restoreBackup(n),console.log(e.green(r.t("config.backup_restored",{name:n})))):console.log(e.yellow(r.t("config.backup_restore_aborted")))}}):void console.log(e.red(r.t("config.backup_restore_missing_name"))):void console.log(e.red(r.t("config.unknown_action",{action:t})));await d({description:r.t("config.backup_create_dry_run"),json:{action:"backup_create",name:n??null},apply:()=>{const o=a.createBackup(n);console.log(e.green(r.t("config.backup_created",{path:o})))}})}(o)}(p)}"claude-code"!==f&&"claude-code"!==p[0]?i[f]?await b(f,p,l):(console.error(e.red(r.t("config.unknown_command",{command:f}))),console.log(e.gray(r.t("config.usage_hint"))),Object.values(i).filter(o=>!o.hidden).forEach(o=>{console.log(e.gray(` - ${o.name}: ${o.displayName}`))})):await b("claude-code",p,l)}else await async function(t){if(t.nonInteractive||!g())return void console.log(e.red(r.t("config.requires_argument")));const{selectedTool:n}=await o.prompt([{type:"list",name:"selectedTool",message:r.t("wizard.select_tool"),choices:Object.values(i).filter(o=>!o.hidden).map(o=>({name:`${o.displayName} (${o.name})`,value:o.name}))}]);await b(n,[],t)}(l)}
|
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 c}from"net";import{join as i}from"path";import{configManager as l}from"../lib/config.js";import{savedApiKey as d}from"./base.js";import{toolManager as p}from"../lib/tool-manager.js";import{i18n as u}from"../lib/i18n.js";import{validateApiKey as m}from"../lib/api-validator.js";import{getAdapter as f}from"../lib/tools/registry.js";import{findInstalls as _,installLabel as g}from"../lib/tools/tool-installs.js";import{detectManagedOverrides as h}from"../lib/tools/claude-managed.js";import{codexAuthProblem as y,codexCatalogRejection as k,codexConfigPath as b,codexWorkModeOn as w}from"../lib/tools/codex.js";import{claudeAccountLoginPresent as v}from"../lib/tools/claude-code.js";import{toolHome as j}from"../lib/tools/types.js";import{gatewayAddresses as x,probeGatewayAddress as $}from"../lib/gateway-addresses.js";import{listAdapters as T}from"../lib/tools/registry.js";import{logger as A}from"../utils/logger.js";import{maskHome as P,maskSecrets as R,uploadReport as N}from"../lib/telemetry.js";import{CLI_NAME as O}from"../lib/brand.js";import{appStatus as C,appStatusText as I,appTools as H,appUpgradeCommand as L}from"../lib/app-update.js";import{balanceLookupEnabled as S,balanceNeedsAttention as U,balanceText as E,fetchKeyBalances as K}from"../lib/key-balance.js";const B=["HTTPS_PROXY","https_proxy","HTTP_PROXY","http_proxy","ALL_PROXY","all_proxy"];function G(o,t,e=3e3){return new Promise(s=>{const r=c({host:o,port:t}),n=o=>{r.destroy(),s(o)};r.setTimeout(e,()=>n(!1)),r.once("connect",()=>n(!0)),r.once("error",()=>n(!1))})}function D(){const o=A.getLogDir();if(!r(o))return"";const t=n(o).filter(o=>/^\d{4}-\d{2}-\d{2}\.log$/.test(o)).sort().slice(-2).map(t=>`== ${t}\n`+a(i(o,t),"utf-8")).join("\n");return R(t.slice(-15e4))}function q(){const o={};for(const t of B){const e=process.env[t]?.trim();if(e)try{const s=new URL(e.includes("://")?e:`http://${e}`);o[t]=`${s.protocol}//${s.host}`}catch{o[t]="(unparsable)"}}return o}export async function doctorCommand(r={}){const n=e(u.t("doctor.checking")).start(),c=[],A=Number(process.versions.node.split(".")[0]);c.push({name:"Node.js",status:A>=20?"pass":"fail",message:`v${process.versions.node}`}),n.text=u.t("doctor.check_proxy"),c.push(await async function(){const o=u.t("doctor.proxy"),t=new Map;for(const o of B){const e=process.env[o]?.trim();e&&!t.has(e)&&t.set(e,o)}if(0===t.size)return{name:o,status:"pass",message:u.t("doctor.proxy_none")};const e=[];for(const[o,s]of t){let t;try{t=new URL(o.includes("://")?o:`http://${o}`)}catch{e.push(`${s}=${o}`);continue}const r=Number(t.port)||("https:"===t.protocol?443:t.protocol.startsWith("socks")?1080:80);await G(t.hostname,r)||e.push(`${s}=${o}`)}return 0===e.length?{name:o,status:"pass",message:[...t.keys()].join(", ")}:{name:o,status:"fail",message:u.t("doctor.proxy_dead",{proxies:e.join(", ")})}}()),n.text=u.t("doctor.check_api_key_network");const R=d(),F=u.t("doctor.api_key_network");if(R){const o=await m(R);o.valid?(c.push({name:F,status:"pass"}),n.text=u.t("doctor.check_balance"),c.push(...await async function(o){if(!S())return[];const t=l.listToolApiKeys().map(o=>({tool:o,key:l.getApiKeyForTool(o)})).filter(t=>Boolean(t.key)&&t.key!==o),e=await K([o,...t.map(o=>o.key)]),s=[{name:u.t("doctor.balance"),key:o},...t.map(o=>({name:u.t("doctor.balance_tool",{tool:f(o.tool)?.displayName??o.tool}),key:o.key}))],r=[];for(const o of s){const t=e.get(o.key);t&&r.push({name:o.name,status:U(t)?"warn":"pass",message:E(t)})}return r}(R))):"invalid_api_key"===o.error?c.push({name:F,status:"fail",message:u.t("doctor.api_key_invalid")}):(c.push({name:F,status:"fail",message:`${u.t("doctor.network_error")}: ${o.message??o.error}`}),n.text=u.t("doctor.check_other_addresses"),c.push(await async function(){const o=u.t("doctor.other_addresses"),t=l.getBaseUrl(),e=x().filter(o=>o.url!==t),s=d(),r=await Promise.all(e.map(o=>$(o.url,{apiKey:s}))),n=e.filter((o,t)=>r[t].ok).map(o=>o.url);return 0===n.length?{name:o,status:"fail",message:u.t("doctor.other_addresses_none")}:{name:o,status:"warn",message:u.t("doctor.other_addresses_found",{urls:n.join(", ")})}}()))}else c.push({name:F,status:"fail",message:u.t("doctor.api_key_missing")});n.text=u.t("doctor.check_client_config");const M=await o();c.push({name:u.t("doctor.client_config"),status:"cloud"===M.source||"cache"===M.source&&!M.problem?"pass":"warn",message:[M.source?u.t(`refresh.source.${M.source}`):u.t("refresh.source.none"),M.revision?u.t("doctor.client_config_revision",{revision:M.revision}):"",M.problem??""].filter(Boolean).join(" · ")}),n.text=u.t("doctor.check_tools");const X=p.getInstalledTools();c.push({name:u.t("doctor.installed_tools"),status:X.length>0?"pass":"warn",message:X.length>0?X.map(o=>f(o)?.displayName??o).join(u.t("setup.list_separator")):u.t("doctor.no_tools_installed")}),c.push(...function(){const o=[];for(const t of p.getInstalledTools()){const e=f(t);if(!e?.installSpec)continue;const s=_(e.installSpec);if(0===s.length)continue;const r=[],n=p.outdatedVersion(t);n&&r.push(u.t("doctor.tool_outdated",{min:n.min})),s.length>1&&r.push(u.t("doctor.tool_duplicates",{others:s.slice(1).map(g).join("、")})),o.push({name:e.displayName,status:r.length>0?"warn":"pass",message:[g(s[0]),...r,...r.length>0?[u.t("doctor.run_upgrade",{tool:t})]:[]].join("\n ")})}return o}()),c.push(...await async function(){const o=[];for(const t of H()){const e=await C(t,{refresh:!0});if(!e.installed||!e.current)continue;const s=u.t("doctor.app_version",{tool:e.name});if(e.outdated){const r=e.blocker?u.t(`app_update.blocked_${e.blocker}`,{tool:e.name}):u.t("doctor.run_app_upgrade",{command:L(t)});o.push({name:s,status:"warn",message:`${I(e)}\n ${r}`})}else o.push({name:s,status:"pass",message:I(e)})}return o}());const Y=function(){if(!p.isToolInstalled("claude-code"))return null;const o=u.t("doctor.claude_config"),t=h();if(t.length>0){const e=t.map(o=>`${o.source}: ${o.keys.join(", ")}`).join("; ");return{name:o,status:"fail",message:u.t("doctor.claude_managed",{detail:e})}}let e={};try{e=JSON.parse(a(i(process.env.CLAUDE_CONFIG_DIR?.trim()||i(j(),".claude"),"settings.json"),"utf-8")).env??{}}catch{}const s=l.getApiKeyForTool("claude-code");return e.ANTHROPIC_AUTH_TOKEN&&e.ANTHROPIC_BASE_URL?e.ANTHROPIC_BASE_URL!==l.getBaseUrl()||s&&e.ANTHROPIC_AUTH_TOKEN!==s?{name:o,status:"warn",message:u.t("doctor.claude_config_changed")}:{name:o,status:"pass"}:{name:o,status:"warn",message:u.t("doctor.claude_not_configured")}}();Y&&c.push(Y),X.includes("claude-code")&&v()&&c.push({name:u.t("doctor.claude_login"),status:"pass",message:u.t("tools.claude_code.account_login_overridden")});const V=X.includes("codex")?y():null;if(X.includes("codex")&&c.push({name:u.t("doctor.codex_auth"),status:V?"fail":"pass",message:V?u.t(`doctor.codex_${V}`,{path:P(b())}):void 0}),X.includes("codex")){const o=k();c.push({name:u.t("doctor.codex_catalog"),status:o?"fail":"pass",message:o?u.t("doctor.codex_catalog_rejected",{path:o.bin,version:o.version??"?",error:o.error}):void 0})}X.includes("codex")&&w()&&c.push({name:u.t("doctor.codex_work_mode"),status:"warn",message:u.t("tools.codex.work_mode_on")}),"win32"===process.platform&&X.includes("claude-code")&&!process.env.CLAUDE_CODE_GIT_BASH_PATH&&c.push({name:"Git for Windows",status:p.isGitInstalled()?"pass":"warn",message:p.isGitInstalled()?void 0:u.t("tools.claude_code.no_git_bash")}),r.deep&&X.includes("claude-code")&&(n.text=u.t("doctor.check_claude_request"),c.push(function(){const o=u.t("doctor.claude_request"),t=_(f("claude-code").installSpec)[0];if(!t)return{name:o,status:"warn",message:u.t("doctor.claude_request_skipped")};const e={encoding:"utf-8",timeout:12e4,windowsHide:!0,stdio:["ignore","pipe","pipe"]},r=["-p","Reply with the single word OK."],n=/\.cmd$/i.test(t.path)?s(`"${t.path}" ${r.map(o=>`"${o}"`).join(" ")}`,{...e,shell:!0}):s(t.path,r,e),a=`${n.stdout??""}`.trim();if(0===n.status&&a)return{name:o,status:"pass",message:a.slice(0,80)};const c=(`${n.stderr??""}`.trim()||a||n.error?.message||`exit ${n.status}`).slice(0,300);return{name:o,status:"fail",message:u.t("doctor.claude_request_failed",{reason:c})}}())),n.stop(),console.log("\n"+t.bold(u.t("doctor.results_title"))+"\n");const W={pass:t.green("√"),warn:t.yellow("!"),fail:t.red("×")};for(const o of c)console.log(`${W[o.status]} ${o.name}`),o.message&&console.log(t.gray(` ${o.message}`));if(c.every(o=>"pass"===o.status)&&console.log("\n"+t.green.bold(u.t("doctor.all_good"))),!r.deep&&X.includes("claude-code")&&console.log(t.gray("\n"+u.t("doctor.deep_hint"))),r.report){const o=e(u.t("doctor.report_uploading")).start(),t=await N(function(o,t){const e={};for(const o of T()){if(o.hidden)continue;let t=null;try{t=p.detectCurrentConfig(o.name).apiKey?"has_key":"no_key"}catch{t="unreadable"}e[o.name]={installed:p.isToolInstalled(o.name),version:p.installedVersion(o.name),copies:o.installSpec?_(o.installSpec).map(o=>({kind:o.kind,version:o.version,path:o.path})):void 0,config:t}}const s=l.getProfile();return{checks:o,tools:e,settings:{base_url:l.getBaseUrl(),profile:l.getActiveProfileName(),profiles:l.listProfiles().length,key_fingerprint:l.getApiKeyFingerprint()||null,tool_keys:Object.keys(s.tool_api_keys??{}),models:s.models,tool_models:s.tool_models??{},tool_settings:s.tool_settings??{},lang:l.getLang()},client_config:t,env:{shell:process.env.SHELL??process.env.ComSpec??null,term:process.env.TERM_PROGRAM??null,proxies:q()},log:D()}}(c,{source:M.source??void 0,revision:M.revision,problem:M.problem}));t?o.succeed(u.t("doctor.report_done",{code:t})):o.fail(u.t("doctor.report_failed",{cli:O}))}else c.some(o=>"fail"===o.status)&&console.log(t.gray("\n"+u.t("doctor.report_hint",{cli:O})));c.some(o=>"fail"===o.status)&&(process.exitCode=1)}
|
|
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 p}from"../lib/api-validator.js";import{CODEX_ONE_MILLION_CONTEXT_SETTING as d,setCodexOneMillionContext as c}from"../lib/tools/codex.js";import{resolveModelCatalog as u}from"../lib/model-catalog.js";import{CLAUDE_DESKTOP_FORCE_REGISTRY_SETTING as f,CLAUDE_DESKTOP_HIDE_OFFICIAL_LOGIN_SETTING as m}from"../lib/tools/claude-desktop.js";import{operationError as g,authenticationError as y,networkError as _,EXIT_CODES as k}from"../lib/errors.js";import{canPrompt as h,emitJson as b,isColorEnabled as w,isDryRun as v,isJsonMode as x,isNonInteractive as C,shouldAutoConfirm as j}from"../lib/runtime-options.js";import{appUpgradeCommand as K}from"../lib/app-update.js";import{join as $}from"path";import{confirmWritePlan as T,printWritePlan as G,toolWritePlan as M}from"../lib/write-plan.js";import N from"inquirer";import{logger as S}from"../utils/logger.js";import{forgetInstalls as E}from"../lib/tools/tool-installs.js";import{CLI_NAME as I,brandEnv as A}from"../lib/brand.js";export const DEDICATED_KEYS=[{option:"claudekey",tool:"claude-code",need:"claude"},{option:"codexkey",tool:"codex",need:"gpt"},{option:"grokkey",tool:"grok",need:"grok"},{option:"desktopkey",tool:"claude-desktop",need:"claude"},{option:"agykey",tool:"agy",need:"gemini"},{option:"openclawkey",tool:"openclaw",need:"any",hidden:!0},{option:"hermeskey",tool:"hermes",need:"any",hidden:!0},{option:"atomcodekey",tool:"atomcode",need:"any",hidden:!0}];async function O(o){const e=await p(o);if(!e.ok)return{hasClaude:!0,hasGpt:!0,hasGrok:!0,hasGemini:!0,probed:!1};const t=e.models.map(o=>o.toLowerCase());return{hasClaude:t.some(o=>o.includes("claude")),hasGpt:t.some(o=>o.startsWith("gpt")||o.includes("gpt-")||/^o\d/.test(o)),hasGrok:t.some(o=>o.includes("grok")),hasGemini:t.some(o=>o.startsWith("gemini")),probed:!0}}function B(o,e){switch(e){case"claude":return o.hasClaude;case"gpt":return o.hasGpt;case"grok":return o.hasGrok;case"gemini":return o.hasGemini;default:return!0}}export function parseOnOff(o){const e=(o??"").trim().toLowerCase();return!!["on","true","show","1","yes","y"].includes(e)||!["off","false","hide","0","no","n"].includes(e)&&void 0}function D(e){console.log(o.green(e))}function F(e){console.log(o.yellow(e))}function L(e){console.error(o.red(e))}let R=null;function P(o){const e={operation:1,authentication:2,network:3};(!R||e[o]>e[R])&&(R=o)}async function Y(e,t){x()||console.log(o.gray(l.t("setup.validating",{label:e})));const i=await r(t);if(i.valid)return!0;const a=l.t("errors.key_placeholder"),n="--key"===e?`${I} setup --key ${a}`:`${I} setup ${e} ${a}`;let p;if("network_error"===i.error?(P("network"),p=_(l.t("setup.unreachable",{url:s.getBaseUrl(),reason:i.message||"network error"}),`${I} base auto`,"network_error")):"invalid_api_key"===i.error?(P("authentication"),p=y(l.t("setup.invalid_key",{label:e,reason:i.message||"invalid"}),n,"invalid_api_key")):(P("operation"),p=g(l.t("setup.validate_failed",{label:e,reason:i.message||i.error||"unknown"}),n,i.error)),x())throw p;return L(p.message),console.log(o.gray(l.t("errors.next_step",{command:p.hint}))),!1}async function q(t,i,r={}){const{oneMillion:p,officialLogin:c,desktopRegistry:u,force:y}=r,_=n[t];try{"claude-desktop"===t&&void 0!==u&&s.setToolSetting("claude-desktop",f,u),"codex"===t&&void 0!==p&&s.setToolSetting("codex",d,p),"claude-desktop"===t&&void 0!==c&&s.setToolSetting("claude-desktop",m,!c),await a.applyPrivateConfig(t,i,s.getModelsForTool(t),{force:y})}catch(o){if(x())throw g(o instanceof Error?o.message:String(o),`${I} setup --key ${l.t("errors.key_placeholder")}`,"config_write_failed");const e=(o instanceof Error?o.message:String(o)).replace(/\s+/g," ").trim();return L("× "+l.t("setup.apply_failed",{tool:_.displayName,reason:e})),!1}return a.printApplied(t),y&&console.log(o.gray(" "+l.t("config.force_done",{tool:_.displayName,name:t}))),"codex"===t&&void 0!==p&&console.log(o.gray(" "+l.t(p?"setup.codex_1m_enabled":"setup.codex_1m_disabled"))),e(t)?.isInstalled&&!a.isToolInstalled(t)&&console.log(o.yellow(" ! "+l.t("setup.gui_preconfigured",{tool:_.displayName,install:_.installCommand}))),!0}function H(o){return!e(o)?.isInstalled&&!a.isToolInstalled(o)}export async function installMissingApps(t,i){const s=t.filter(o=>{const t=e(o)?.appInstaller;try{return Boolean(t&&!t.blocker()&&!t.installedPath())}catch(e){return S.logError(`setup: app installed? ${o}`,e),!1}});if(0===s.length)return!1;let a=i;if(void 0===a&&h()&&!j()){const o=s.map(o=>n[o].displayName).join(l.t("setup.list_separator"));console.log(""),a=(await N.prompt([{type:"confirm",name:"go",message:l.t("setup.install_app_confirm",{tools:o}),default:!1}])).go}if(!a&&!x())for(const e of s)console.log(o.gray(l.t("setup.install_app_hint",{tool:n[e].displayName,command:K(e)})));return Boolean(a)}function W(o){F(l.t("setup.still_missing",{tools:o.map(o=>n[o].displayName).join(l.t("setup.list_separator")),commands:o.map(o=>`${I} config ${o} --yes`).join(l.t("setup.list_separator"))}))}function U(e,t,i=[]){const a=M(e),n=$(s.getConfigDir(),"config.yaml");if(x())b({dry_run:!0,tools:a,install_first:i,key_file:t?n:null});else{if(0===a.length&&0===i.length){const e=(w()?o.cyan:o=>o)(l.t("runtime.dry_run_label"));return void console.log(`${e} ${l.t("setup.dry_run_none")}`)}G(a,{label:l.t("runtime.dry_run_label"),keyFile:t?n:void 0,installFirst:i})}}function z(){return"darwin"===process.platform||"win32"===process.platform||a.isToolInstalled("claude-desktop")}export async function setupCommand(r){R=null;const p=r.key?.trim(),f=DEDICATED_KEYS.map(o=>({...o,apiKey:r[o.option]?.trim()})).filter(o=>Boolean(o.apiKey)),m=void 0!==r.oneMillion,g=void 0!==r.claudeOfficial;let y;if(g&&(y=parseOnOff(r.claudeOfficial),void 0===y))return L(l.t("setup.claude_official_invalid",{value:String(r.claudeOfficial)})),void(process.exitCode=1);const _=void 0!==r.desktopRegistry;let h;if(_&&(h=parseOnOff(r.desktopRegistry),void 0===h))return L(l.t("setup.desktop_registry_invalid",{value:String(r.desktopRegistry)})),void(process.exitCode=1);const b=g||_,w=Boolean(p||f.length>0),K={oneMillion:r.oneMillion,officialLogin:y,desktopRegistry:h,force:r.force};if(!w&&(m||b)&&v())return void U([...m?["codex"]:[],...b?["claude-desktop"]:[]],!1);if(!w&&(m||b)){if(m){const o=s.getApiKeyForTool("codex");if(o)try{const e=!0===r.oneMillion;s.setToolSetting("codex",d,e);const t=await u(o);c(e,t??void 0),D(l.t(e?"setup.codex_1m_enabled":"setup.codex_1m_disabled"))}catch(o){L(l.t("setup.apply_failed",{tool:n.codex.displayName,reason:o instanceof Error?o.message:String(o)})),process.exitCode=1}else L(l.t("setup.codex_1m_missing_key")),process.exitCode=1}if(b){const o=s.getApiKeyForTool("claude-desktop");o?await q("claude-desktop",o,{...K,oneMillion:void 0})?await t(["claude-desktop"],{apps:{install:!1}}):process.exitCode=1:(L(l.t("setup.desktop_official_login_missing_key")),process.exitCode=1)}return}if(!w)return L(l.t("setup.usage")),void(process.exitCode=1);const G=v();G||await i(p||f[0].apiKey);const M=[],P=[];let J,Q=0,V=0;const X=new Set,Z=f.map(o=>({tool:o.tool,label:`--${o.option}`,apiKey:o.apiKey,need:o.need}));for(const o of Z){if(!await Y(o.label,o.apiKey)){V+=1;continue}const e=await O(o.apiKey);!e.probed||B(e,o.need)?(e.probed||F(l.t("setup.probe_failed",{label:o.label})),M.push({tool:o.tool,apiKey:o.apiKey,dedicated:!0}),X.add(o.tool)):(L(l.t(`setup.key_no_${o.need}`,{label:o.label,tool:n[o.tool].displayName})),V+=1)}const oo=!!p&&await Y("--key",p);p&&!oo&&(J=k[R??"operation"]);const eo=p&&oo?await O(p):void 0;if(p&&eo&&!eo.probed&&F(l.t("setup.probe_failed",{label:"--key"})),!(p&&eo&&eo.probed)||eo.hasClaude||eo.hasGpt||eo.hasGrok||eo.hasGemini||(L(l.t("setup.key_no_family")),J=1),p&&eo&&void 0===J){const o=[{tool:"claude-code",capable:eo.hasClaude,skipMsg:l.t(z()?"setup.skip_no_claude_desktop":"setup.skip_no_claude")},{tool:"codex",capable:eo.hasGpt,skipMsg:l.t("setup.skip_no_gpt")},{tool:"grok",capable:eo.hasGrok,skipMsg:l.t("setup.skip_no_grok")},{tool:"claude-desktop",capable:eo.hasClaude&&z(),skipMsg:"",quiet:!0},{tool:"agy",capable:eo.hasGemini,skipMsg:l.t("setup.skip_no_gemini")}];for(const e of o)X.has(e.tool)||(e.capable?(M.push({tool:e.tool,apiKey:p,dedicated:!1}),X.add(e.tool)):e.quiet||F(e.skipMsg))}const to=Boolean(p&&oo&&void 0===J);if(G)return U(M.filter(o=>!H(o.tool)).map(o=>o.tool),M.length>0,M.filter(o=>H(o.tool)).map(o=>o.tool)),void((V>0||void 0!==J)&&(process.exitCode=J??k[R??"operation"]));const io=M.filter(o=>!H(o.tool)),lo=to||M.some(o=>o.dedicated);if((M.length>0||lo)&&!r.fromInstaller&&!await T(io.map(o=>o.tool),{keyFile:lo?$(s.getConfigDir(),"config.yaml"):void 0,installFirst:M.filter(o=>H(o.tool)).map(o=>o.tool)}))return void(process.exitCode=k.cancelled);to&&p&&s.setApiKey(p);for(const o of M)o.dedicated&&s.setToolApiKey(o.tool,o.apiKey),H(o.tool)?P.push({tool:o.tool,apiKey:o.apiKey}):await q(o.tool,o.apiKey,K)?Q+=1:(V+=1,X.delete(o.tool));if(void 0!==J)return P.length>0&&W(P.map(o=>o.tool)),void(process.exitCode=J);let so=[];if(P.length>0){const e=await async function(e,t,i){const s=e.map(o=>o.tool);if(0===s.length)return{still:[],applied:[],failed:[]};const r=s.map(o=>n[o].displayName).join(l.t("setup.list_separator"));let p=t;if(void 0!==p||x()||(j()?p=!C():process.stdin.isTTY&&(console.log(""),p=(await N.prompt([{type:"confirm",name:"go",message:l.t("setup.install_confirm",{tools:r}),default:!0}])).go)),!p){console.log("");for(const e of s)console.log(o.yellow("! "+l.t("setup.install_hint",{tool:n[e].displayName,install:n[e].installCommand})));return x()||console.log(o.gray(l.t("setup.install_all_hint",{cli:I}))),{still:s,applied:[],failed:[]}}const d=[];for(const e of s){console.log(o.bold(`\n${n[e].displayName}`));try{await a.installTool(e)}catch(o){S.logError(`setup: install ${e}`,o)}E(),a.isToolInstalled(e)||d.push(e)}const c=s.filter(o=>!d.includes(o));c.length>0&&console.log("");const u=[],f=[];for(const{tool:o,apiKey:t}of e.filter(o=>c.includes(o.tool)))await q(o,t,i)?u.push(o):f.push(o);return{still:d,applied:u,failed:f}}(P,r.install,K);so=e.still,Q+=e.applied.length,V+=e.failed.length;for(const o of[...so,...e.failed])X.delete(o)}if(Q>0){const t=[...X].filter(o=>!e(o)?.isInstalled&&!so.includes(o)),i=t.map(o=>n[o]?.command).filter(Boolean).join(" / "),s=l.t("setup.done",{count:String(Q)});D("\n"+(i?`${s}${l.t("setup.done_commands",{commands:i})}`:s)),so.length>0&&W(so);for(const o of t){const e=a.ensureNativeOnPath(o);e&&D(l.t("setup.path_added",{tool:n[o].displayName,dir:e}))}const r=t.filter(o=>!a.isOnPath(o));if(r.length>0&&!x()&&"1"!==A("PATH_HINT_BY_CALLER")){const e=r.map(o=>n[o].command).join(" / ");console.log(o.yellow(" ! "+l.t("win32"===process.platform?"setup.path_reload_windows":"setup.path_reload",{commands:e})))}}0===Q&&so.length>0&&W(so),V>0&&(L(l.t("setup.failed_summary",{count:String(V)})),x()||console.error(`${I} setup --key ${l.t("errors.key_placeholder")}`)),await t([...X],{apps:{install:await installMissingApps([...X],r.install)}}),(V>0||0===Q&&0===so.length)&&(process.exitCode=k[R??"operation"])}
|
|
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 v,isDryRun as w,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{asksBeforeWriting as G,confirmWritePlan as O,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 B,brandEnv as D}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 F(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 L(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 R(e){console.log(o.green(e))}function P(e){console.log(o.yellow(e))}function Y(e){console.error(o.red(e))}let q=null;function z(o){const e={operation:1,authentication:2,network:3};(!q||e[o]>e[q])&&(q=o)}async function H(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?`${B} setup --key ${a}`:`${B} setup ${e} ${a}`;let p;if("network_error"===i.error?(z("network"),p=_(l.t("setup.unreachable",{url:s.getBaseUrl(),reason:i.message||"network error"}),`${B} base auto`,"network_error")):"invalid_api_key"===i.error?(z("authentication"),p=y(l.t("setup.invalid_key",{label:e,reason:i.message||"invalid"}),n,"invalid_api_key")):(z("operation"),p=g(l.t("setup.validate_failed",{label:e,reason:i.message||i.error||"unknown"}),n,i.error)),x())throw p;return Y(p.message),console.log(o.gray(l.t("errors.next_step",{command:p.hint}))),!1}async function W(t,i,r={}){const{oneMillion:p,officialLogin:c,desktopRegistry:u,force:y,takeOver:_}=r,k=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,takeOver:_})}catch(o){if(x())throw g(o instanceof Error?o.message:String(o),`${B} setup --key ${l.t("errors.key_placeholder")}`,"config_write_failed");const e=(o instanceof Error?o.message:String(o)).replace(/\s+/g," ").trim();return Y("× "+l.t("setup.apply_failed",{tool:k.displayName,reason:e})),!1}return a.printApplied(t),y&&console.log(o.gray(" "+l.t("config.force_done",{tool:k.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:k.displayName,install:k.installCommand}))),!0}function U(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 J(o){P(l.t("setup.still_missing",{tools:o.map(o=>n[o].displayName).join(l.t("setup.list_separator")),commands:o.map(o=>`${B} config ${o} --yes`).join(l.t("setup.list_separator"))}))}function Q(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=(v()?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 V(){return"darwin"===process.platform||"win32"===process.platform||a.isToolInstalled("claude-desktop")}export async function setupCommand(r){q=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 Y(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 Y(l.t("setup.desktop_registry_invalid",{value:String(r.desktopRegistry)})),void(process.exitCode=1);const b=g||_,v=Boolean(p||f.length>0),K={oneMillion:r.oneMillion,officialLogin:y,desktopRegistry:h,force:r.force};if(!v&&(m||b)&&w())return void Q([...m?["codex"]:[],...b?["claude-desktop"]:[]],!1);if(!v&&(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),R(l.t(e?"setup.codex_1m_enabled":"setup.codex_1m_disabled"))}catch(o){Y(l.t("setup.apply_failed",{tool:n.codex.displayName,reason:o instanceof Error?o.message:String(o)})),process.exitCode=1}else Y(l.t("setup.codex_1m_missing_key")),process.exitCode=1}if(b){const o=s.getApiKeyForTool("claude-desktop");o?await W("claude-desktop",o,{...K,oneMillion:void 0,takeOver:!0})?await t(["claude-desktop"],{apps:{install:!1}}):process.exitCode=1:(Y(l.t("setup.desktop_official_login_missing_key")),process.exitCode=1)}return}if(!v)return Y(l.t("setup.usage")),void(process.exitCode=1);const $=w();$||await i(p||f[0].apiKey);const T=[],S=[];let I,z=0,X=0;const Z=new Set,oo=f.map(o=>({tool:o.tool,label:`--${o.option}`,apiKey:o.apiKey,need:o.need}));for(const o of oo){if(!await H(o.label,o.apiKey)){X+=1;continue}const e=await F(o.apiKey);!e.probed||L(e,o.need)?(e.probed||P(l.t("setup.probe_failed",{label:o.label})),T.push({tool:o.tool,apiKey:o.apiKey,dedicated:!0}),Z.add(o.tool)):(Y(l.t(`setup.key_no_${o.need}`,{label:o.label,tool:n[o.tool].displayName})),X+=1)}const eo=!!p&&await H("--key",p);p&&!eo&&(I=k[q??"operation"]);const to=p&&eo?await F(p):void 0;if(p&&to&&!to.probed&&P(l.t("setup.probe_failed",{label:"--key"})),!(p&&to&&to.probed)||to.hasClaude||to.hasGpt||to.hasGrok||to.hasGemini||(Y(l.t("setup.key_no_family")),I=1),p&&to&&void 0===I){const o=[{tool:"claude-code",capable:to.hasClaude,skipMsg:l.t(V()?"setup.skip_no_claude_desktop":"setup.skip_no_claude")},{tool:"codex",capable:to.hasGpt,skipMsg:l.t("setup.skip_no_gpt")},{tool:"grok",capable:to.hasGrok,skipMsg:l.t("setup.skip_no_grok")},{tool:"claude-desktop",capable:to.hasClaude&&V(),skipMsg:"",quiet:!0},{tool:"agy",capable:to.hasGemini,skipMsg:l.t("setup.skip_no_gemini")}];for(const e of o)Z.has(e.tool)||(e.capable?(T.push({tool:e.tool,apiKey:p,dedicated:!1}),Z.add(e.tool)):e.quiet||P(e.skipMsg))}const io=Boolean(p&&eo&&void 0===I);if($)return Q(T.filter(o=>!U(o.tool)).map(o=>o.tool),T.length>0,T.filter(o=>U(o.tool)).map(o=>o.tool)),void((X>0||void 0!==I)&&(process.exitCode=I??k[q??"operation"]));const lo=T.filter(o=>!U(o.tool)),so=io||T.some(o=>o.dedicated),ao=!r.fromInstaller&&G();if((T.length>0||so)&&!r.fromInstaller&&!await O(lo.map(o=>o.tool),{keyFile:so?M(s.getConfigDir(),"config.yaml"):void 0,installFirst:T.filter(o=>U(o.tool)).map(o=>o.tool)}))return void(process.exitCode=k.cancelled);io&&p&&s.setApiKey(p);for(const o of T)o.dedicated&&s.setToolApiKey(o.tool,o.apiKey),U(o.tool)?S.push({tool:o.tool,apiKey:o.apiKey}):await W(o.tool,o.apiKey,{...K,takeOver:o.dedicated||ao})?z+=1:(X+=1,Z.delete(o.tool));if(void 0!==I)return S.length>0&&J(S.map(o=>o.tool)),void(process.exitCode=I);let no=[];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:B}))),{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 W(o,t,i)?u.push(o):f.push(o);return{still:d,applied:u,failed:f}}(S,r.install,K);no=e.still,z+=e.applied.length,X+=e.failed.length;for(const o of[...no,...e.failed])Z.delete(o)}if(z>0){const t=[...Z].filter(o=>!e(o)?.isInstalled&&!no.includes(o)),i=t.map(o=>n[o]?.command).filter(Boolean).join(" / "),s=l.t("setup.done",{count:String(z)});R("\n"+(i?`${s}${l.t("setup.done_commands",{commands:i})}`:s)),no.length>0&&J(no);for(const o of t){const e=a.ensureNativeOnPath(o);e&&R(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"!==D("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===z&&no.length>0&&J(no),X>0&&(Y(l.t("setup.failed_summary",{count:String(X)})),x()||console.error(`${B} setup --key ${l.t("errors.key_placeholder")}`)),await t([...Z],{apps:{install:await installMissingApps([...Z],r.install)}}),(X>0||0===z&&0===no.length)&&(process.exitCode=k[q??"operation"])}
|
package/dist/commands/upgrade.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import o from"chalk";import{appTools as t,upgradeApp as
|
|
1
|
+
import o from"chalk";import{appTools as t,getApp as e,upgradeApp as n}from"../lib/app-update.js";import{i18n as l}from"../lib/i18n.js";import{emitJson as r,isJsonMode as i,progressToStderr as s}from"../lib/runtime-options.js";import{toolManager as a}from"../lib/tool-manager.js";import{listAdapters as p}from"../lib/tools/registry.js";import{upgradeTool as c}from"../lib/tool-upgrade.js";import{listComponents as d,resolveComponent as m,runRuntime as u}from"../lib/components.js";import{outdatedRuntimeHints as f}from"./components.js";export async function upgradeCommand(g,h={}){const j=t(),b=new Set;g=g.map(o=>{const t=m(o);return t?("runtime"===t.category&&b.add(t.id),t.adapter??t.app??t.id):o});const w=[...p().filter(o=>o.installSpec).map(o=>o.name),...j,...b],y=g.length>0?g:w.filter(o=>j.includes(o)?(o=>{const t=e(o)?.appInstaller;return Boolean(t&&!t.blocker()&&t.installedPath())})(o):a.isToolInstalled(o)),k=y.filter(o=>!w.includes(o));if(k.length>0){console.error(o.red(l.t("upgrade.unsupported",{tool:k.join(", ")})));const t=d().filter(o=>"runtime"===o.category).map(o=>o.id);return console.error(l.t("upgrade.supported",{tools:[...new Set([...w,...t])].join(" / ")})),void(process.exitCode=1)}if(0===y.length)return void(i()?r({tools:[]}):console.log(l.t("upgrade.nothing_installed",{tools:w.join(" / ")})));let x=0;const C=[];for(const t of y){if(b.has(t)){const e=m(t);i()||console.log(o.bold(`\n${e.name}`));const n=await s(()=>u(e,"upgrade",{force:h.force}));n.ok||(x+=1),C.push(n);continue}if(j.includes(t)){const l=e(t)?.displayName??t;i()||console.log(o.bold(`\n${l}`));const r=await s(()=>n(t,{install:!0,force:h.force})),a=["installed","upgraded","up_to_date","declined"].includes(r.result);a||(x+=1),C.push({...r,ok:a});continue}const l=await s(()=>c(t));l||(x+=1),C.push({tool:t,ok:l})}if(i())r({tools:C});else if(0===g.length){const t=await f();t.length&&console.log("\n"+t.map(t=>o.yellow(" ! "+t)).join("\n"))}x>0&&(process.exitCode=1)}
|