@ljwei-stak/dsh-model-router 0.17.0 → 0.18.0
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/.dsh-plugin/client.js +331 -85
- package/.dsh-plugin/index.mjs +1 -1
- package/.dsh-plugin/official-tools-remote-service.mjs +46 -10
- package/.dsh-plugin/shared/official-tool-executor.mjs +135 -47
- package/.dsh-plugin/shared/official-tool-registry.mjs +145 -12
- package/.dsh-plugin/shared/official-tools-runtime.mjs +426 -118
- package/.dsh-plugin/shared/tool-install-preferences.mjs +82 -26
- package/.dsh-plugin/shared/vendor-mimo-grok-adapter.mjs +41 -16
- package/CHANGELOG.md +22 -1
- package/README.md +19 -10
- package/README.zh.md +19 -10
- package/{INSTALLATION_GUIDE.zh.md → docs/INSTALLATION_GUIDE.zh.md} +16 -16
- package/docs/WORKBENCH_USER_GUIDE.zh.md +27 -5
- package/{MIGRATION.md → docs/archive/MIGRATION.md} +1 -1
- package/docs/archive/README.md +21 -0
- package/package.json +4 -4
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
export const DEFAULT_NPM_REGISTRY = 'https://registry.npmjs.org/'
|
|
25
25
|
|
|
26
26
|
/** Shared shape of a "package manager" method: argv only, no script staging. */
|
|
27
|
-
function packageManagerMethod(id, label, manager, spec, { registryFlag = '--registry=' } = {}) {
|
|
27
|
+
function packageManagerMethod(id, label, manager, spec, { registryFlag = '--registry=', command = 'install', extraArgs = [] } = {}) {
|
|
28
28
|
return Object.freeze({
|
|
29
29
|
id,
|
|
30
30
|
label,
|
|
@@ -32,16 +32,21 @@ function packageManagerMethod(id, label, manager, spec, { registryFlag = '--regi
|
|
|
32
32
|
manager,
|
|
33
33
|
spec,
|
|
34
34
|
registryFlag,
|
|
35
|
-
installArgs: Object.freeze([
|
|
35
|
+
installArgs: Object.freeze([command, '-g', spec, ...extraArgs]),
|
|
36
36
|
uninstallArgs: Object.freeze(['uninstall', '-g', spec.replace(/@latest$/, '')]),
|
|
37
|
-
/**
|
|
37
|
+
/** The resolver binds npm prefix or pnpm global-dir/global-bin-dir. */
|
|
38
38
|
supportsInstallDir: true,
|
|
39
39
|
supportsRegistry: true,
|
|
40
40
|
})
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/** Vendor installer script run from a verified local copy. */
|
|
44
|
-
function scriptMethod(id, label, {
|
|
44
|
+
function scriptMethod(id, label, {
|
|
45
|
+
shell, scriptUrl, verify, installArg = [], env = [], platforms,
|
|
46
|
+
supportsInstallDir = false, installDirEnv = '', installDirSuffix = '',
|
|
47
|
+
defaultScriptInstallDir, defaultScriptInstallDirEnv, scriptBinaryNames,
|
|
48
|
+
registryEnv, installDirSubdir, uninstallUnsupportedReason, scriptFallbackUrls,
|
|
49
|
+
}) {
|
|
45
50
|
return Object.freeze({
|
|
46
51
|
id,
|
|
47
52
|
label,
|
|
@@ -56,7 +61,16 @@ function scriptMethod(id, label, { shell, scriptUrl, verify, installArg = [], en
|
|
|
56
61
|
platforms: Object.freeze(platforms),
|
|
57
62
|
/** Whether the vendor script honours a caller-chosen directory at all. */
|
|
58
63
|
supportsInstallDir,
|
|
59
|
-
|
|
64
|
+
installDirEnv,
|
|
65
|
+
installDirSuffix,
|
|
66
|
+
...(installDirSubdir ? { installDirSubdir } : {}),
|
|
67
|
+
...(uninstallUnsupportedReason ? { uninstallUnsupportedReason } : {}),
|
|
68
|
+
...(defaultScriptInstallDir ? { defaultScriptInstallDir } : {}),
|
|
69
|
+
...(defaultScriptInstallDirEnv ? { defaultScriptInstallDirEnv } : {}),
|
|
70
|
+
...(scriptBinaryNames ? { scriptBinaryNames: Object.freeze(scriptBinaryNames) } : {}),
|
|
71
|
+
...(scriptFallbackUrls ? { scriptFallbackUrls: Object.freeze(scriptFallbackUrls) } : {}),
|
|
72
|
+
...(registryEnv ? { registryEnv } : {}),
|
|
73
|
+
supportsRegistry: Boolean(registryEnv),
|
|
60
74
|
})
|
|
61
75
|
}
|
|
62
76
|
|
|
@@ -73,9 +87,27 @@ export const OFFICIAL_TOOLS = Object.freeze([
|
|
|
73
87
|
probeExecutables: ['kimi'],
|
|
74
88
|
probeNote: 'kimi 与旧 Python 版 kimi-cli 同名;请核对可执行文件来源和版本。',
|
|
75
89
|
providerHints: ['moonshot', 'kimi'],
|
|
90
|
+
scriptBinaryNames: Object.freeze(['kimi', 'kimi.exe']),
|
|
91
|
+
defaultScriptInstallDir: '.kimi-code/bin',
|
|
76
92
|
installMethods: Object.freeze([
|
|
77
93
|
packageManagerMethod('npm', 'npm', 'npm', '@moonshot-ai/kimi-code@latest'),
|
|
78
94
|
packageManagerMethod('pnpm', 'pnpm', 'pnpm', '@moonshot-ai/kimi-code@latest'),
|
|
95
|
+
scriptMethod('script-bash', 'curl | bash', {
|
|
96
|
+
shell: 'bash', scriptUrl: 'https://code.kimi.com/kimi-code/install.sh',
|
|
97
|
+
platforms: ['linux', 'darwin'], supportsInstallDir: true,
|
|
98
|
+
installDirEnv: 'KIMI_INSTALL_DIR', installDirSuffix: 'bin',
|
|
99
|
+
env: ['KIMI_INSTALL_DIR'],
|
|
100
|
+
scriptBinaryNames: ['kimi'],
|
|
101
|
+
verify: Object.freeze({ mustInclude: ['kimi-code', 'code.kimi.com/kimi-code'] }),
|
|
102
|
+
}),
|
|
103
|
+
scriptMethod('script-powershell', 'irm | iex', {
|
|
104
|
+
shell: 'powershell', scriptUrl: 'https://code.kimi.com/kimi-code/install.ps1',
|
|
105
|
+
platforms: ['win32'], supportsInstallDir: true,
|
|
106
|
+
installDirEnv: 'KIMI_INSTALL_DIR', installDirSuffix: 'bin',
|
|
107
|
+
env: ['KIMI_INSTALL_DIR'],
|
|
108
|
+
scriptBinaryNames: ['kimi.exe'],
|
|
109
|
+
verify: Object.freeze({ mustInclude: ['kimi-code', 'code.kimi.com/kimi-code'] }),
|
|
110
|
+
}),
|
|
79
111
|
]),
|
|
80
112
|
}),
|
|
81
113
|
Object.freeze({
|
|
@@ -89,9 +121,29 @@ export const OFFICIAL_TOOLS = Object.freeze([
|
|
|
89
121
|
uninstallArgs: ['uninstall', '-g', '@anthropic-ai/claude-code'],
|
|
90
122
|
probeExecutables: ['claude'],
|
|
91
123
|
providerHints: ['anthropic', 'claude'],
|
|
124
|
+
scriptBinaryNames: Object.freeze(['claude', 'claude.exe']),
|
|
125
|
+
defaultScriptInstallDir: '.local/bin',
|
|
92
126
|
installMethods: Object.freeze([
|
|
93
127
|
packageManagerMethod('npm', 'npm', 'npm', '@anthropic-ai/claude-code@latest'),
|
|
94
|
-
packageManagerMethod('pnpm', 'pnpm', 'pnpm', '@anthropic-ai/claude-code@latest'
|
|
128
|
+
packageManagerMethod('pnpm', 'pnpm', 'pnpm', '@anthropic-ai/claude-code@latest', {
|
|
129
|
+
command: 'add',
|
|
130
|
+
extraArgs: ['--ignore-scripts=false', '--allow-build=@anthropic-ai/claude-code'],
|
|
131
|
+
}),
|
|
132
|
+
// The native installer has no directory argument. npm/pnpm support a prefix.
|
|
133
|
+
scriptMethod('script-bash', 'curl | bash', {
|
|
134
|
+
shell: 'bash', scriptUrl: 'https://claude.ai/install.sh',
|
|
135
|
+
scriptFallbackUrls: ['https://downloads.claude.ai/claude-code-releases/bootstrap.sh'],
|
|
136
|
+
platforms: ['linux', 'darwin'],
|
|
137
|
+
scriptBinaryNames: ['claude'],
|
|
138
|
+
verify: Object.freeze({ mustInclude: ['downloads.claude.ai/claude-code-releases', 'manifest.json'] }),
|
|
139
|
+
}),
|
|
140
|
+
scriptMethod('script-powershell', 'irm | iex', {
|
|
141
|
+
shell: 'powershell', scriptUrl: 'https://claude.ai/install.ps1',
|
|
142
|
+
scriptFallbackUrls: ['https://downloads.claude.ai/claude-code-releases/bootstrap.ps1'],
|
|
143
|
+
platforms: ['win32'],
|
|
144
|
+
scriptBinaryNames: ['claude.exe'],
|
|
145
|
+
verify: Object.freeze({ mustInclude: ['downloads.claude.ai/claude-code-releases', 'manifest.json'] }),
|
|
146
|
+
}),
|
|
95
147
|
]),
|
|
96
148
|
}),
|
|
97
149
|
Object.freeze({
|
|
@@ -106,9 +158,30 @@ export const OFFICIAL_TOOLS = Object.freeze([
|
|
|
106
158
|
probeExecutables: ['codex'],
|
|
107
159
|
probeNote: 'Codex 版本横幅由适配层宽匹配;安装时取 npm 最新版。',
|
|
108
160
|
providerHints: ['openai', 'gpt', 'codex'],
|
|
161
|
+
scriptBinaryNames: Object.freeze(['codex', 'codex.exe']),
|
|
162
|
+
defaultScriptInstallDir: '.local/bin',
|
|
109
163
|
installMethods: Object.freeze([
|
|
110
164
|
packageManagerMethod('npm', 'npm', 'npm', '@openai/codex@latest'),
|
|
111
165
|
packageManagerMethod('pnpm', 'pnpm', 'pnpm', '@openai/codex@latest'),
|
|
166
|
+
scriptMethod('script-sh', 'curl | sh', {
|
|
167
|
+
shell: 'sh', scriptUrl: 'https://chatgpt.com/codex/install.sh',
|
|
168
|
+
platforms: ['linux', 'darwin'], supportsInstallDir: true,
|
|
169
|
+
installDirEnv: 'CODEX_INSTALL_DIR', env: ['CODEX_INSTALL_DIR'],
|
|
170
|
+
scriptBinaryNames: ['codex'],
|
|
171
|
+
verify: Object.freeze({ mustInclude: ['releases.openai.com/codex', 'CODEX_INSTALL_DIR'] }),
|
|
172
|
+
}),
|
|
173
|
+
scriptMethod('script-powershell', 'irm | iex', {
|
|
174
|
+
shell: 'powershell', scriptUrl: 'https://chatgpt.com/codex/install.ps1',
|
|
175
|
+
platforms: ['win32'], supportsInstallDir: true,
|
|
176
|
+
installDirEnv: 'CODEX_INSTALL_DIR', env: ['CODEX_INSTALL_DIR'],
|
|
177
|
+
defaultScriptInstallDirEnv: 'LOCALAPPDATA',
|
|
178
|
+
defaultScriptInstallDir: 'Programs/OpenAI/Codex/bin',
|
|
179
|
+
installDirSubdir: 'codex/bin',
|
|
180
|
+
uninstallUnsupportedReason: 'Codex 官方 Windows 脚本使用目录联接和版本化资源;请按官方卸载说明移除,插件不会删除联接目标。',
|
|
181
|
+
// The Windows bin directory is a junction to the versioned payload.
|
|
182
|
+
scriptBinaryNames: ['codex.exe'],
|
|
183
|
+
verify: Object.freeze({ mustInclude: ['releases.openai.com/codex', 'CODEX_INSTALL_DIR'] }),
|
|
184
|
+
}),
|
|
112
185
|
]),
|
|
113
186
|
}),
|
|
114
187
|
Object.freeze({
|
|
@@ -122,9 +195,33 @@ export const OFFICIAL_TOOLS = Object.freeze([
|
|
|
122
195
|
uninstallArgs: ['uninstall', '-g', '@minimax-ai/code'],
|
|
123
196
|
probeExecutables: ['mcode'],
|
|
124
197
|
providerHints: ['minimax'],
|
|
198
|
+
defaultMethodsByPlatform: Object.freeze({ win32: 'script-powershell' }),
|
|
199
|
+
scriptBinaryNames: Object.freeze(['mcode', 'mcode-tools']),
|
|
200
|
+
defaultScriptInstallDir: '.minimax-code/bin',
|
|
125
201
|
installMethods: Object.freeze([
|
|
126
|
-
packageManagerMethod('npm', 'npm', 'npm', '@minimax-ai/code@latest'
|
|
127
|
-
|
|
202
|
+
packageManagerMethod('npm', 'npm', 'npm', '@minimax-ai/code@latest', {
|
|
203
|
+
extraArgs: ['--ignore-scripts=false', '--include=optional', '--allow-scripts=@minimax-ai/code,better-sqlite3'],
|
|
204
|
+
}),
|
|
205
|
+
packageManagerMethod('pnpm', 'pnpm', 'pnpm', '@minimax-ai/code@latest', {
|
|
206
|
+
command: 'add',
|
|
207
|
+
extraArgs: ['--ignore-scripts=false', '--allow-build=@minimax-ai/code', '--allow-build=better-sqlite3'],
|
|
208
|
+
}),
|
|
209
|
+
scriptMethod('script-bash', 'curl | bash', {
|
|
210
|
+
shell: 'bash', scriptUrl: 'https://filecdn.minimax.chat/public/install.sh',
|
|
211
|
+
platforms: ['linux', 'darwin'], supportsInstallDir: true,
|
|
212
|
+
installDirEnv: 'MCODE_INSTALL_DIR', installDirSuffix: 'bin',
|
|
213
|
+
registryEnv: 'MCODE_NPM_REGISTRY', env: ['MCODE_INSTALL_DIR', 'MCODE_NPM_REGISTRY'],
|
|
214
|
+
verify: Object.freeze({ mustInclude: ['MiniMax Code CLI', '@minimax-ai/code'] }),
|
|
215
|
+
}),
|
|
216
|
+
scriptMethod('script-powershell', 'irm | iex', {
|
|
217
|
+
shell: 'powershell', scriptUrl: 'https://filecdn.minimax.chat/public/install.ps1',
|
|
218
|
+
platforms: ['win32'], supportsInstallDir: true,
|
|
219
|
+
installDirEnv: 'MCODE_INSTALL_DIR',
|
|
220
|
+
registryEnv: 'MCODE_NPM_REGISTRY', env: ['MCODE_INSTALL_DIR', 'MCODE_NPM_REGISTRY'],
|
|
221
|
+
defaultScriptInstallDir: '.minimax-code',
|
|
222
|
+
scriptBinaryNames: ['mcode.cmd', 'mcode.ps1', 'mcode-tools.cmd', 'mcode-tools.ps1'],
|
|
223
|
+
verify: Object.freeze({ mustInclude: ['MiniMax Code CLI', '@minimax-ai/code'] }),
|
|
224
|
+
}),
|
|
128
225
|
]),
|
|
129
226
|
}),
|
|
130
227
|
Object.freeze({
|
|
@@ -138,9 +235,24 @@ export const OFFICIAL_TOOLS = Object.freeze([
|
|
|
138
235
|
uninstallArgs: ['uninstall', '-g', '@mimo-ai/cli'],
|
|
139
236
|
probeExecutables: ['mimo'],
|
|
140
237
|
providerHints: ['mimo', 'xiaomi'],
|
|
238
|
+
scriptBinaryNames: Object.freeze(['mimo', 'mimo.exe']),
|
|
239
|
+
defaultScriptInstallDir: '.mimocode/bin',
|
|
141
240
|
installMethods: Object.freeze([
|
|
142
241
|
packageManagerMethod('npm', 'npm', 'npm', '@mimo-ai/cli@latest'),
|
|
143
242
|
packageManagerMethod('pnpm', 'pnpm', 'pnpm', '@mimo-ai/cli@latest'),
|
|
243
|
+
scriptMethod('script-bash', 'curl | bash', {
|
|
244
|
+
shell: 'bash', scriptUrl: 'https://mimo.xiaomi.com/install',
|
|
245
|
+
platforms: ['linux', 'darwin'],
|
|
246
|
+
scriptBinaryNames: ['mimo'],
|
|
247
|
+
verify: Object.freeze({ mustInclude: ['mimo.xiaomi.com', '.mimocode'] }),
|
|
248
|
+
}),
|
|
249
|
+
scriptMethod('script-powershell', 'irm | iex', {
|
|
250
|
+
shell: 'powershell', scriptUrl: 'https://mimo.xiaomi.com/install.ps1',
|
|
251
|
+
platforms: ['win32'], supportsInstallDir: true,
|
|
252
|
+
installDirEnv: 'MIMOCODE_INSTALL_DIR', env: ['MIMOCODE_INSTALL_DIR'],
|
|
253
|
+
scriptBinaryNames: ['mimo.exe'],
|
|
254
|
+
verify: Object.freeze({ mustInclude: ['mimo.xiaomi.com', '.mimocode'] }),
|
|
255
|
+
}),
|
|
144
256
|
]),
|
|
145
257
|
}),
|
|
146
258
|
Object.freeze({
|
|
@@ -154,9 +266,26 @@ export const OFFICIAL_TOOLS = Object.freeze([
|
|
|
154
266
|
uninstallArgs: ['uninstall', '-g', '@xai-official/grok'],
|
|
155
267
|
probeExecutables: ['grok'],
|
|
156
268
|
providerHints: ['xai', 'grok'],
|
|
269
|
+
scriptBinaryNames: Object.freeze(['grok', 'agent', 'grok.exe', 'agent.exe', 'grove.exe', 'grove-fsmonitor.exe', 'grove-credential.exe']),
|
|
270
|
+
defaultScriptInstallDir: '.grok/bin',
|
|
271
|
+
pathProfileMarkers: Object.freeze(['# >>> grok installer >>>', '# <<< grok installer <<<']),
|
|
157
272
|
installMethods: Object.freeze([
|
|
158
273
|
packageManagerMethod('npm', 'npm', 'npm', '@xai-official/grok@latest'),
|
|
159
274
|
packageManagerMethod('pnpm', 'pnpm', 'pnpm', '@xai-official/grok@latest'),
|
|
275
|
+
scriptMethod('script-bash', 'curl | bash', {
|
|
276
|
+
shell: 'bash', scriptUrl: 'https://x.ai/cli/install.sh',
|
|
277
|
+
platforms: ['linux', 'darwin'], supportsInstallDir: true,
|
|
278
|
+
installDirEnv: 'GROK_BIN_DIR', env: ['GROK_BIN_DIR'],
|
|
279
|
+
scriptBinaryNames: ['grok', 'agent'],
|
|
280
|
+
verify: Object.freeze({ mustInclude: ['Grok CLI installer', 'x.ai/cli'] }),
|
|
281
|
+
}),
|
|
282
|
+
scriptMethod('script-powershell', 'irm | iex', {
|
|
283
|
+
shell: 'powershell', scriptUrl: 'https://x.ai/cli/install.ps1',
|
|
284
|
+
platforms: ['win32'], supportsInstallDir: true,
|
|
285
|
+
installDirEnv: 'GROK_BIN_DIR', env: ['GROK_BIN_DIR'],
|
|
286
|
+
scriptBinaryNames: ['grok.exe', 'agent.exe', 'grove.exe', 'grove-fsmonitor.exe', 'grove-credential.exe'],
|
|
287
|
+
verify: Object.freeze({ mustInclude: ['Grok CLI installer', 'x.ai/cli'] }),
|
|
288
|
+
}),
|
|
160
289
|
]),
|
|
161
290
|
}),
|
|
162
291
|
Object.freeze({
|
|
@@ -294,7 +423,10 @@ export function installMethodsFor(tool) {
|
|
|
294
423
|
export function installMethodFor(tool, methodId) {
|
|
295
424
|
const wanted = String(methodId ?? '').trim()
|
|
296
425
|
if (!wanted) return null
|
|
297
|
-
|
|
426
|
+
// 0.17.1 saved Codex's POSIX installer as script-bash. The vendor uses sh;
|
|
427
|
+
// preserve that saved choice while returning the current declared method.
|
|
428
|
+
const canonical = tool?.id === 'codex' && wanted === 'script-bash' ? 'script-sh' : wanted
|
|
429
|
+
return installMethodsFor(tool).find(method => method.id === canonical) ?? null
|
|
298
430
|
}
|
|
299
431
|
|
|
300
432
|
/** The tool's default method, kept identical to `manager` / `installArgs`. */
|
|
@@ -310,7 +442,7 @@ export function installMethodBlockReason(method, platform = 'linux') {
|
|
|
310
442
|
|
|
311
443
|
/**
|
|
312
444
|
* A method able to place the tool in the user's chosen directory. npm and pnpm
|
|
313
|
-
*
|
|
445
|
+
* bind their global directories; vendor scripts declare an argument or environment binding.
|
|
314
446
|
*/
|
|
315
447
|
export function methodHonoursInstallDir(method) {
|
|
316
448
|
return method?.supportsInstallDir === true
|
|
@@ -329,8 +461,8 @@ export function installCommandLineFor(tool, method) {
|
|
|
329
461
|
if (!tool || tool.unsupported) return null
|
|
330
462
|
if (!method) return null
|
|
331
463
|
if (method.kind === 'script') {
|
|
332
|
-
const piped = method.shell === 'powershell' ? `irm ${method.scriptUrl} | iex` : `curl -fsSL ${method.scriptUrl} |
|
|
333
|
-
return
|
|
464
|
+
const piped = method.shell === 'powershell' ? `irm ${method.scriptUrl} | iex` : `curl -fsSL ${method.scriptUrl} | ${method.shell}`
|
|
465
|
+
return piped
|
|
334
466
|
}
|
|
335
467
|
return `${method.manager} ${method.installArgs.join(' ')}`
|
|
336
468
|
}
|
|
@@ -339,6 +471,7 @@ export function installCommandLineFor(tool, method) {
|
|
|
339
471
|
export function uninstallCommandLineFor(tool, method) {
|
|
340
472
|
if (!tool || tool.unsupported || !method) return null
|
|
341
473
|
if (tool.manager === 'signed-windows-installer') return null
|
|
474
|
+
if (method.uninstallUnsupportedReason) return method.uninstallUnsupportedReason
|
|
342
475
|
if (method.kind === 'script') return '删除官方安装的可执行文件(保留配置与登录信息)'
|
|
343
476
|
return `${method.manager} ${method.uninstallArgs.join(' ')}`
|
|
344
477
|
}
|