@ljwei-stak/dsh-model-router 0.18.1 → 0.19.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 +210 -43
- package/.dsh-plugin/index.mjs +14 -7
- package/.dsh-plugin/official-tools-remote-service.mjs +7 -3
- package/.dsh-plugin/shared/cli-terminal-protocol.mjs +15 -5
- package/.dsh-plugin/shared/cli-terminal.mjs +126 -18
- package/.dsh-plugin/shared/official-tool-executor.mjs +7 -7
- package/.dsh-plugin/shared/official-tool-registry.mjs +20 -3
- package/.dsh-plugin/shared/official-tools-runtime.mjs +169 -24
- package/.dsh-plugin/shared/task-executors.mjs +52 -3
- package/.dsh-plugin/shared/tool-install-preferences.mjs +42 -1
- package/.dsh-plugin/shared/zcode-bundle.mjs +29 -8
- package/.dsh-plugin/shared/zcode-installer.mjs +2 -2
- package/CHANGELOG.md +21 -0
- package/README.md +10 -6
- package/README.zh.md +10 -6
- package/docs/INSTALLATION_GUIDE.zh.md +12 -12
- package/docs/WORKBENCH_USER_GUIDE.zh.md +13 -7
- package/package.json +2 -2
package/.dsh-plugin/client.js
CHANGED
|
@@ -77,6 +77,8 @@ function scriptMethod(id2, label, {
|
|
|
77
77
|
scriptBinaryNames,
|
|
78
78
|
registryEnv,
|
|
79
79
|
installDirSubdir,
|
|
80
|
+
legacySharedInstallDir = false,
|
|
81
|
+
sharedDefaultBin = false,
|
|
80
82
|
uninstallUnsupportedReason,
|
|
81
83
|
scriptFallbackUrls
|
|
82
84
|
}) {
|
|
@@ -97,6 +99,8 @@ function scriptMethod(id2, label, {
|
|
|
97
99
|
installDirEnv,
|
|
98
100
|
installDirSuffix,
|
|
99
101
|
...installDirSubdir ? { installDirSubdir } : {},
|
|
102
|
+
...legacySharedInstallDir ? { legacySharedInstallDir: true } : {},
|
|
103
|
+
...sharedDefaultBin ? { sharedDefaultBin: true } : {},
|
|
100
104
|
...uninstallUnsupportedReason ? { uninstallUnsupportedReason } : {},
|
|
101
105
|
...defaultScriptInstallDir ? { defaultScriptInstallDir } : {},
|
|
102
106
|
...defaultScriptInstallDirEnv ? { defaultScriptInstallDirEnv } : {},
|
|
@@ -131,6 +135,8 @@ var OFFICIAL_TOOLS = Object.freeze([
|
|
|
131
135
|
supportsInstallDir: true,
|
|
132
136
|
installDirEnv: "KIMI_INSTALL_DIR",
|
|
133
137
|
installDirSuffix: "bin",
|
|
138
|
+
installDirSubdir: "kimi-code",
|
|
139
|
+
legacySharedInstallDir: true,
|
|
134
140
|
env: ["KIMI_INSTALL_DIR"],
|
|
135
141
|
scriptBinaryNames: ["kimi"],
|
|
136
142
|
verify: Object.freeze({ mustInclude: ["kimi-code", "code.kimi.com/kimi-code"] })
|
|
@@ -142,6 +148,8 @@ var OFFICIAL_TOOLS = Object.freeze([
|
|
|
142
148
|
supportsInstallDir: true,
|
|
143
149
|
installDirEnv: "KIMI_INSTALL_DIR",
|
|
144
150
|
installDirSuffix: "bin",
|
|
151
|
+
installDirSubdir: "kimi-code",
|
|
152
|
+
legacySharedInstallDir: true,
|
|
145
153
|
env: ["KIMI_INSTALL_DIR"],
|
|
146
154
|
scriptBinaryNames: ["kimi.exe"],
|
|
147
155
|
verify: Object.freeze({ mustInclude: ["kimi-code", "code.kimi.com/kimi-code"] })
|
|
@@ -174,6 +182,7 @@ var OFFICIAL_TOOLS = Object.freeze([
|
|
|
174
182
|
scriptFallbackUrls: ["https://downloads.claude.ai/claude-code-releases/bootstrap.sh"],
|
|
175
183
|
platforms: ["linux", "darwin"],
|
|
176
184
|
scriptBinaryNames: ["claude"],
|
|
185
|
+
sharedDefaultBin: true,
|
|
177
186
|
verify: Object.freeze({ mustInclude: ["downloads.claude.ai/claude-code-releases", "manifest.json"] })
|
|
178
187
|
}),
|
|
179
188
|
scriptMethod("script-powershell", "irm | iex", {
|
|
@@ -182,6 +191,7 @@ var OFFICIAL_TOOLS = Object.freeze([
|
|
|
182
191
|
scriptFallbackUrls: ["https://downloads.claude.ai/claude-code-releases/bootstrap.ps1"],
|
|
183
192
|
platforms: ["win32"],
|
|
184
193
|
scriptBinaryNames: ["claude.exe"],
|
|
194
|
+
sharedDefaultBin: true,
|
|
185
195
|
verify: Object.freeze({ mustInclude: ["downloads.claude.ai/claude-code-releases", "manifest.json"] })
|
|
186
196
|
})
|
|
187
197
|
])
|
|
@@ -210,6 +220,9 @@ var OFFICIAL_TOOLS = Object.freeze([
|
|
|
210
220
|
supportsInstallDir: true,
|
|
211
221
|
installDirEnv: "CODEX_INSTALL_DIR",
|
|
212
222
|
env: ["CODEX_INSTALL_DIR"],
|
|
223
|
+
installDirSubdir: "codex/bin",
|
|
224
|
+
legacySharedInstallDir: true,
|
|
225
|
+
sharedDefaultBin: true,
|
|
213
226
|
scriptBinaryNames: ["codex"],
|
|
214
227
|
verify: Object.freeze({ mustInclude: ["releases.openai.com/codex", "CODEX_INSTALL_DIR"] })
|
|
215
228
|
}),
|
|
@@ -259,6 +272,8 @@ var OFFICIAL_TOOLS = Object.freeze([
|
|
|
259
272
|
supportsInstallDir: true,
|
|
260
273
|
installDirEnv: "MCODE_INSTALL_DIR",
|
|
261
274
|
installDirSuffix: "bin",
|
|
275
|
+
installDirSubdir: "minimax-code",
|
|
276
|
+
legacySharedInstallDir: true,
|
|
262
277
|
registryEnv: "MCODE_NPM_REGISTRY",
|
|
263
278
|
env: ["MCODE_INSTALL_DIR", "MCODE_NPM_REGISTRY"],
|
|
264
279
|
verify: Object.freeze({ mustInclude: ["MiniMax Code CLI", "@minimax-ai/code"] })
|
|
@@ -269,6 +284,8 @@ var OFFICIAL_TOOLS = Object.freeze([
|
|
|
269
284
|
platforms: ["win32"],
|
|
270
285
|
supportsInstallDir: true,
|
|
271
286
|
installDirEnv: "MCODE_INSTALL_DIR",
|
|
287
|
+
installDirSubdir: "minimax-code",
|
|
288
|
+
legacySharedInstallDir: true,
|
|
272
289
|
registryEnv: "MCODE_NPM_REGISTRY",
|
|
273
290
|
env: ["MCODE_INSTALL_DIR", "MCODE_NPM_REGISTRY"],
|
|
274
291
|
defaultScriptInstallDir: ".minimax-code",
|
|
@@ -307,6 +324,8 @@ var OFFICIAL_TOOLS = Object.freeze([
|
|
|
307
324
|
supportsInstallDir: true,
|
|
308
325
|
installDirEnv: "MIMOCODE_INSTALL_DIR",
|
|
309
326
|
env: ["MIMOCODE_INSTALL_DIR"],
|
|
327
|
+
installDirSubdir: "mimo-code",
|
|
328
|
+
legacySharedInstallDir: true,
|
|
310
329
|
scriptBinaryNames: ["mimo.exe"],
|
|
311
330
|
verify: Object.freeze({ mustInclude: ["mimo.xiaomi.com", ".mimocode"] })
|
|
312
331
|
})
|
|
@@ -336,6 +355,8 @@ var OFFICIAL_TOOLS = Object.freeze([
|
|
|
336
355
|
supportsInstallDir: true,
|
|
337
356
|
installDirEnv: "GROK_BIN_DIR",
|
|
338
357
|
env: ["GROK_BIN_DIR"],
|
|
358
|
+
installDirSubdir: "grok-build",
|
|
359
|
+
legacySharedInstallDir: true,
|
|
339
360
|
scriptBinaryNames: ["grok", "agent"],
|
|
340
361
|
verify: Object.freeze({ mustInclude: ["Grok CLI installer", "x.ai/cli"] })
|
|
341
362
|
}),
|
|
@@ -346,6 +367,8 @@ var OFFICIAL_TOOLS = Object.freeze([
|
|
|
346
367
|
supportsInstallDir: true,
|
|
347
368
|
installDirEnv: "GROK_BIN_DIR",
|
|
348
369
|
env: ["GROK_BIN_DIR"],
|
|
370
|
+
installDirSubdir: "grok-build",
|
|
371
|
+
legacySharedInstallDir: true,
|
|
349
372
|
scriptBinaryNames: ["grok.exe", "agent.exe", "grove.exe", "grove-fsmonitor.exe", "grove-credential.exe"],
|
|
350
373
|
verify: Object.freeze({ mustInclude: ["Grok CLI installer", "x.ai/cli"] })
|
|
351
374
|
})
|
|
@@ -428,6 +451,10 @@ var OFFICIAL_TOOLS = Object.freeze([
|
|
|
428
451
|
installArg: ["--install-dir"],
|
|
429
452
|
env: ["STEP_INSTALL_DIR", "STEP_RELEASE_BASE_URL"],
|
|
430
453
|
supportsInstallDir: true,
|
|
454
|
+
// The installer replaces its runtime directories, including the entire
|
|
455
|
+
// node_modules tree on Windows. It must own a dedicated directory.
|
|
456
|
+
installDirSubdir: "stepcode",
|
|
457
|
+
legacySharedInstallDir: true,
|
|
431
458
|
verify: Object.freeze({
|
|
432
459
|
mustInclude: ["static-openapi.stepfun.com", "stepcode installer"],
|
|
433
460
|
mustNotInclude: ["anomalyco/opencode"]
|
|
@@ -440,6 +467,8 @@ var OFFICIAL_TOOLS = Object.freeze([
|
|
|
440
467
|
installArg: ["-InstallDir"],
|
|
441
468
|
env: ["STEP_INSTALL_DIR", "STEP_RELEASE_BASE_URL"],
|
|
442
469
|
supportsInstallDir: true,
|
|
470
|
+
installDirSubdir: "stepcode",
|
|
471
|
+
legacySharedInstallDir: true,
|
|
443
472
|
verify: Object.freeze({
|
|
444
473
|
mustInclude: ["static-openapi.stepfun.com", "stepcode"],
|
|
445
474
|
mustNotInclude: ["anomalyco/opencode"]
|
|
@@ -451,12 +480,12 @@ var OFFICIAL_TOOLS = Object.freeze([
|
|
|
451
480
|
id: "zcode",
|
|
452
481
|
label: "ZCode",
|
|
453
482
|
vendor: "Z.ai",
|
|
454
|
-
purpose: "\u667A\u8C31\u5B98\u65B9 ZCode \u684C\u9762\u7248\uFF0C\u5185\u542B GLM \
|
|
483
|
+
purpose: "\u667A\u8C31\u5B98\u65B9 ZCode \u684C\u9762\u7248\uFF0C\u5185\u542B\u53EF\u72EC\u7ACB\u8FD0\u884C\u7684 GLM CLI/TUI\u3002\u53EF\u5355\u72EC\u914D\u7F6E\u684C\u9762\u76EE\u5F55\uFF0C\u5185\u7F6E CLI \u968F\u684C\u9762\u7248\u66F4\u65B0\u3002",
|
|
455
484
|
manager: "signed-windows-installer",
|
|
456
485
|
installArgs: [],
|
|
457
486
|
uninstallArgs: [],
|
|
458
487
|
probeExecutables: [],
|
|
459
|
-
probeNote: "\u68C0\u6D4B\u7ECF\u8FC7\u6709\u6548\u7B7E\u540D\u7684 ZCode.exe \u548C\u540C\u76EE\u5F55 GLM \u8D44\u6E90\uFF1B\u684C\u9762\u5B89\u88C5\u5668\u9700\u4EBA\u5DE5\u9009\u62E9\u5B89\u88C5\u4F4D\u7F6E\u3002",
|
|
488
|
+
probeNote: "\u68C0\u6D4B\u7ECF\u8FC7\u6709\u6548\u7B7E\u540D\u7684 ZCode.exe \u548C\u540C\u76EE\u5F55 GLM CLI/TUI \u8D44\u6E90\uFF1B\u684C\u9762\u5B89\u88C5\u5668\u9700\u4EBA\u5DE5\u9009\u62E9\u5B89\u88C5\u4F4D\u7F6E\u3002",
|
|
460
489
|
providerHints: ["zai", "z.ai", "zcode", "glm", "zhipu", "bigmodel"]
|
|
461
490
|
})
|
|
462
491
|
]);
|
|
@@ -784,6 +813,25 @@ function expandInstallDir(value, { home = "", env = {} } = {}) {
|
|
|
784
813
|
if (/^\\\\[^\\]+\\[^\\]+$/.test(withoutTrailing)) throw new Error("\u5B89\u88C5\u76EE\u5F55\u4E0D\u80FD\u662F\u7F51\u7EDC\u5171\u4EAB\u6839\u76EE\u5F55\u3002");
|
|
785
814
|
return expanded;
|
|
786
815
|
}
|
|
816
|
+
function normalizeZCodeInstallDir(value, options = {}) {
|
|
817
|
+
const input = String(value ?? "");
|
|
818
|
+
if (/[\x00-\x1f]/.test(input)) throw new Error("ZCode \u5B89\u88C5\u4F4D\u7F6E\u5305\u542B\u65E0\u6548\u5B57\u7B26\u3002");
|
|
819
|
+
const raw = input.trim().replace(/^"(.*)"$/, "$1");
|
|
820
|
+
if (!raw) return "";
|
|
821
|
+
let path;
|
|
822
|
+
try {
|
|
823
|
+
path = expandInstallDir(raw, options);
|
|
824
|
+
} catch (error) {
|
|
825
|
+
throw new Error(`ZCode \u5B89\u88C5\u4F4D\u7F6E\u65E0\u6548\uFF1A${error.message}`);
|
|
826
|
+
}
|
|
827
|
+
if (!/^[A-Za-z]:[\\/]/.test(path)) {
|
|
828
|
+
throw new Error("ZCode \u5B89\u88C5\u4F4D\u7F6E\u5FC5\u987B\u662F Windows \u672C\u5730\u7EDD\u5BF9\u76EE\u5F55\u6216 ZCode.exe \u8DEF\u5F84\u3002");
|
|
829
|
+
}
|
|
830
|
+
if (/\.exe[\\/]*$/i.test(path) && !/[\\/]ZCode\.exe[\\/]*$/i.test(path)) {
|
|
831
|
+
throw new Error("ZCode \u7A0B\u5E8F\u8DEF\u5F84\u5FC5\u987B\u6307\u5411\u5B98\u65B9 ZCode.exe\u3002");
|
|
832
|
+
}
|
|
833
|
+
return path.replace(/[\\/]+$/, "");
|
|
834
|
+
}
|
|
787
835
|
function normalizeSourceUrl(value, subject) {
|
|
788
836
|
const raw = String(value ?? "").trim();
|
|
789
837
|
if (!raw) return "";
|
|
@@ -827,6 +875,7 @@ function keepKnownToolIds(raw, known, subject) {
|
|
|
827
875
|
function parseInstallPreferences(config = {}, { tools = [], home = "", env = {} } = {}) {
|
|
828
876
|
const known = new Set(tools.map((tool) => tool.id));
|
|
829
877
|
const installDir = expandInstallDir(valueOf(config, "toolInstallDir", ""), { home, env });
|
|
878
|
+
const zcodeInstallDir = normalizeZCodeInstallDir(valueOf(config, "zcodeInstallDir", ""), { home, env });
|
|
830
879
|
const registry = normalizeSourceUrl(valueOf(config, "toolNpmRegistry", DEFAULT_NPM_REGISTRY), "npm \u6E90") || DEFAULT_NPM_REGISTRY;
|
|
831
880
|
const methodRaw = keepKnownToolIds(
|
|
832
881
|
parseJsonObject(valueOf(config, "toolInstallMethodsJson", "{}"), "\u5B89\u88C5\u65B9\u5F0F\u8986\u76D6"),
|
|
@@ -851,6 +900,7 @@ function parseInstallPreferences(config = {}, { tools = [], home = "", env = {}
|
|
|
851
900
|
}
|
|
852
901
|
return {
|
|
853
902
|
installDir,
|
|
903
|
+
zcodeInstallDir,
|
|
854
904
|
registry,
|
|
855
905
|
methods,
|
|
856
906
|
scriptUrls,
|
|
@@ -2346,18 +2396,20 @@ var INSTALL_DEFAULTS = Object.freeze({
|
|
|
2346
2396
|
toolInstallDir: "",
|
|
2347
2397
|
toolNpmRegistry: DEFAULT_NPM_REGISTRY,
|
|
2348
2398
|
toolScriptUrlsJson: "{}",
|
|
2349
|
-
toolAllowScriptInstall: true
|
|
2399
|
+
toolAllowScriptInstall: true,
|
|
2400
|
+
zcodeInstallDir: ""
|
|
2350
2401
|
});
|
|
2351
2402
|
function toolInstallSettingsSignature(value = {}) {
|
|
2352
2403
|
try {
|
|
2353
|
-
const preferences = parseInstallPreferences({ ...value, toolInstallDir: "" }, { tools: OFFICIAL_TOOLS });
|
|
2404
|
+
const preferences = parseInstallPreferences({ ...value, toolInstallDir: "", zcodeInstallDir: "" }, { tools: OFFICIAL_TOOLS });
|
|
2354
2405
|
const sorted = (map) => Object.entries(map).sort(([left], [right]) => left.localeCompare(right));
|
|
2355
2406
|
return JSON.stringify([
|
|
2356
2407
|
String(value.toolInstallDir ?? "").trim(),
|
|
2357
2408
|
preferences.registry,
|
|
2358
2409
|
sorted(preferences.methods),
|
|
2359
2410
|
sorted(preferences.scriptUrls),
|
|
2360
|
-
preferences.allowScriptInstall
|
|
2411
|
+
preferences.allowScriptInstall,
|
|
2412
|
+
String(value.zcodeInstallDir ?? "").trim()
|
|
2361
2413
|
]);
|
|
2362
2414
|
} catch {
|
|
2363
2415
|
return JSON.stringify([
|
|
@@ -2366,7 +2418,8 @@ function toolInstallSettingsSignature(value = {}) {
|
|
|
2366
2418
|
value.toolNpmRegistry,
|
|
2367
2419
|
value.toolInstallMethodsJson,
|
|
2368
2420
|
value.toolScriptUrlsJson,
|
|
2369
|
-
value.toolAllowScriptInstall
|
|
2421
|
+
value.toolAllowScriptInstall,
|
|
2422
|
+
value.zcodeInstallDir
|
|
2370
2423
|
]);
|
|
2371
2424
|
}
|
|
2372
2425
|
}
|
|
@@ -2377,7 +2430,8 @@ function installSummaryMatchesSettings(summary, value) {
|
|
|
2377
2430
|
toolNpmRegistry: summary.registry || DEFAULT_NPM_REGISTRY,
|
|
2378
2431
|
toolInstallMethodsJson: JSON.stringify(summary.methods ?? {}),
|
|
2379
2432
|
toolScriptUrlsJson: JSON.stringify(summary.scriptUrls ?? {}),
|
|
2380
|
-
toolAllowScriptInstall: summary.allowScriptInstall !== false
|
|
2433
|
+
toolAllowScriptInstall: summary.allowScriptInstall !== false,
|
|
2434
|
+
zcodeInstallDir: summary.requestedZCodeInstallDir ?? summary.zcodeInstallDir ?? ""
|
|
2381
2435
|
});
|
|
2382
2436
|
}
|
|
2383
2437
|
function savedToolInstallMethods(value = {}) {
|
|
@@ -2423,6 +2477,10 @@ function toolInstallAction({ tool, probe, readiness, job, probeStatus, latestVer
|
|
|
2423
2477
|
const installed = probe?.installed === true;
|
|
2424
2478
|
const order = installed && latestVersion ? compareReleaseVersions(probe.version, latestVersion) : null;
|
|
2425
2479
|
const desktop = tool.manager === "signed-windows-installer";
|
|
2480
|
+
if (desktop) return {
|
|
2481
|
+
label: running ? "\u684C\u9762\u5B89\u88C5\u5904\u7406\u4E2D\u2026" : installed ? "\u68C0\u67E5\u5E76\u66F4\u65B0\u684C\u9762\u7248" : job?.status === "failed" ? "\u91CD\u8BD5\u684C\u9762\u5B89\u88C5" : "\u5B89\u88C5 ZCode \u684C\u9762\u7248",
|
|
2482
|
+
disabled: !(probeStatus === "ready" || probeStatus === "refreshing") || running
|
|
2483
|
+
};
|
|
2426
2484
|
const noRunner = desktop || tool.headlessAdapter === true;
|
|
2427
2485
|
const repair = installed && !noRunner && readiness?.ready === false && order !== 0;
|
|
2428
2486
|
const label = running ? "\u5B89\u88C5\u4E2D\u2026" : !installed ? job?.status === "failed" ? "\u91CD\u8BD5\u5B89\u88C5" : desktop ? "\u4E0B\u8F7D\u6700\u65B0\u5B89\u88C5\u5668" : "\u4E00\u952E\u5B89\u88C5\u6700\u65B0\u7248" : order === -1 ? `\u66F4\u65B0\u5230\u6700\u65B0\u7248 ${latestVersion}` : order === 1 ? "\u5DF2\u9AD8\u4E8E\u6700\u65B0\u6B63\u5F0F\u7248" : repair ? "\u4FEE\u590D\u5B98\u65B9\u6267\u884C\u5165\u53E3" : order === 0 ? "\u5DF2\u662F\u6700\u65B0\u7248\u672C" : "\u5B89\u88C5\u6700\u65B0\u7248";
|
|
@@ -2441,9 +2499,9 @@ function toolMaintenanceActions({ tool, probe, job, probeStatus, summary }) {
|
|
|
2441
2499
|
const busy = running || !interactive;
|
|
2442
2500
|
return {
|
|
2443
2501
|
repair: {
|
|
2444
|
-
label: "\u4E00\u952E\u4FEE\u590D",
|
|
2445
|
-
title: "\u7528\u540C\u4E00\u6761\u56FA\u5B9A\u5B98\u65B9\u5B89\u88C5\u547D\u4EE4\u91CD\u65B0\u5B89\u88C5\u4E00\u904D\uFF0C\u4FEE\u590D\u635F\u574F\u6216\u4E0D\u5B8C\u6574\u7684\u5B89\u88C5",
|
|
2446
|
-
disabled: busy ||
|
|
2502
|
+
label: desktop ? "\u91CD\u65B0\u5B89\u88C5\u684C\u9762\u7248" : "\u4E00\u952E\u4FEE\u590D",
|
|
2503
|
+
title: desktop ? "\u6253\u5F00\u5DF2\u6838\u9A8C\u7684\u5B98\u65B9\u684C\u9762\u5B89\u88C5\u5668\uFF1B\u5B8C\u6210\u5B89\u88C5\u540E\u91CD\u65B0\u4F53\u68C0\uFF0C\u5237\u65B0\u5185\u7F6E TUI" : "\u7528\u540C\u4E00\u6761\u56FA\u5B9A\u5B98\u65B9\u5B89\u88C5\u547D\u4EE4\u91CD\u65B0\u5B89\u88C5\u4E00\u904D\uFF0C\u4FEE\u590D\u635F\u574F\u6216\u4E0D\u5B8C\u6574\u7684\u5B89\u88C5",
|
|
2504
|
+
disabled: busy || summary?.installable === false
|
|
2447
2505
|
},
|
|
2448
2506
|
uninstall: {
|
|
2449
2507
|
label: "\u4E00\u952E\u5378\u8F7D",
|
|
@@ -2455,7 +2513,7 @@ function toolMaintenanceActions({ tool, probe, job, probeStatus, summary }) {
|
|
|
2455
2513
|
function installClickRefusal({ tool, submitting = false, running = false, operation = "install", pendingSettings = false, installError = "" } = {}) {
|
|
2456
2514
|
if (!tool) return "\u672A\u77E5\u5B98\u65B9\u5DE5\u5177\uFF0C\u65E0\u6CD5\u5F00\u59CB\u5B89\u88C5\u3002";
|
|
2457
2515
|
if (tool.unsupported) return String(tool.unsupportedReason ?? "").trim() || "\u6B64\u5DE5\u5177\u6682\u4E0D\u652F\u6301\u4E00\u952E\u5B89\u88C5\u3002";
|
|
2458
|
-
if (tool.manager === "signed-windows-installer" && operation
|
|
2516
|
+
if (tool.manager === "signed-windows-installer" && operation === "uninstall") {
|
|
2459
2517
|
return `${tool.label} \u7531\u5B98\u65B9\u7B7E\u540D\u684C\u9762\u5B89\u88C5\u5668\u5B89\u88C5\uFF0C\u8BF7\u5728\u7CFB\u7EDF\u201C\u5E94\u7528\u201D\u4E2D\u5378\u8F7D\u5B83\u3002`;
|
|
2460
2518
|
}
|
|
2461
2519
|
if (submitting || running) {
|
|
@@ -12704,7 +12762,7 @@ var xterm_default = `/**
|
|
|
12704
12762
|
`;
|
|
12705
12763
|
|
|
12706
12764
|
// .dsh-plugin/client/host-version.mjs
|
|
12707
|
-
var ROUTER_CLIENT_VERSION = true ? "0.
|
|
12765
|
+
var ROUTER_CLIENT_VERSION = true ? "0.19.0" : "";
|
|
12708
12766
|
var STALE_HOST_MESSAGE = "\u63D2\u4EF6\u540E\u53F0\u7248\u672C\u8F83\u65E7\uFF0C\u8BF7\u5B8C\u5168\u9000\u51FA\u5E76\u91CD\u542F Harness\uFF08\u5305\u62EC\u6258\u76D8\u56FE\u6807\uFF09\u540E\u518D\u4F7F\u7528\u3002";
|
|
12709
12767
|
function isMissingRemoteMethod(message) {
|
|
12710
12768
|
const value = String(message ?? "");
|
|
@@ -12722,7 +12780,7 @@ function staleHostNotice({ hostVersion, clientVersion = ROUTER_CLIENT_VERSION, l
|
|
|
12722
12780
|
}
|
|
12723
12781
|
|
|
12724
12782
|
// .dsh-plugin/shared/cli-terminal-protocol.mjs
|
|
12725
|
-
var TERMINAL_TOOL_IDS = Object.freeze(
|
|
12783
|
+
var TERMINAL_TOOL_IDS = Object.freeze(OFFICIAL_TOOLS.filter((tool) => !tool.unsupported && (tool.probeExecutables?.length || tool.manager === "signed-windows-installer")).map((tool) => tool.id));
|
|
12726
12784
|
var TERMINAL_SHELL_ID = "shell";
|
|
12727
12785
|
var TERMINAL_TARGETS = Object.freeze([TERMINAL_SHELL_ID, ...TERMINAL_TOOL_IDS]);
|
|
12728
12786
|
var TERMINAL_MODES = Object.freeze(["interactive", "login"]);
|
|
@@ -12752,8 +12810,14 @@ var TERMINAL_LOGIN_ARGS = Object.freeze({
|
|
|
12752
12810
|
"minimax-code": Object.freeze(["login"]),
|
|
12753
12811
|
"mimo-code": Object.freeze(["auth", "login"]),
|
|
12754
12812
|
"grok-build": Object.freeze(["login"]),
|
|
12755
|
-
gemini: Object.freeze([])
|
|
12813
|
+
gemini: Object.freeze([]),
|
|
12814
|
+
opencode: Object.freeze(["auth", "login"]),
|
|
12815
|
+
stepcode: Object.freeze(["login"]),
|
|
12816
|
+
zcode: Object.freeze([])
|
|
12756
12817
|
});
|
|
12818
|
+
function terminalCanLogin(target) {
|
|
12819
|
+
return Boolean(TERMINAL_LOGIN_ARGS[target]?.length);
|
|
12820
|
+
}
|
|
12757
12821
|
var SESSION_ID = /^term-[a-z0-9]{6,40}$/;
|
|
12758
12822
|
function plainObject(value, subject) {
|
|
12759
12823
|
if (value === null || typeof value !== "object" || Array.isArray(value)) throw new TypeError(`${subject} must be an object`);
|
|
@@ -12779,7 +12843,7 @@ function terminalTargetLabel(target) {
|
|
|
12779
12843
|
function terminalCommandPreview(target, mode = "interactive", platform = "win32") {
|
|
12780
12844
|
if (target === TERMINAL_SHELL_ID) return platform === "win32" ? "powershell.exe -NoLogo" : "$SHELL -l";
|
|
12781
12845
|
const tool = getOfficialTool(target);
|
|
12782
|
-
const executable = tool?.probeExecutables?.[0] ?? String(target);
|
|
12846
|
+
const executable = target === "zcode" ? "ZCode \u684C\u9762\u7248\u5185\u7F6E TUI" : tool?.probeExecutables?.[0] ?? String(target);
|
|
12783
12847
|
const args = mode === "login" ? TERMINAL_LOGIN_ARGS[target] ?? [] : [];
|
|
12784
12848
|
return [executable, ...args].join(" ");
|
|
12785
12849
|
}
|
|
@@ -12788,7 +12852,7 @@ function parseTerminalStart(value) {
|
|
|
12788
12852
|
if (!TERMINAL_TARGETS.includes(request.target)) throw new TypeError("target must be the shell or a fixed official CLI");
|
|
12789
12853
|
const mode = request.mode === void 0 ? "interactive" : request.mode;
|
|
12790
12854
|
if (!TERMINAL_MODES.includes(mode)) throw new TypeError("mode must be interactive or login");
|
|
12791
|
-
if (mode === "login" && request.target
|
|
12855
|
+
if (mode === "login" && !terminalCanLogin(request.target)) throw new TypeError("this target has no login mode");
|
|
12792
12856
|
if (!isAbsoluteDirectoryText(request.cwd)) throw new TypeError("cwd must be an absolute directory path");
|
|
12793
12857
|
if (request.confirmed !== true) throw new TypeError("starting a terminal requires the user's confirmation");
|
|
12794
12858
|
return {
|
|
@@ -12838,7 +12902,11 @@ function terminalTargets(healthTools = [], platform = "win32") {
|
|
|
12838
12902
|
const installed = new Set((Array.isArray(healthTools) ? healthTools : []).filter((item) => item?.installed).map((item) => item.id));
|
|
12839
12903
|
return [
|
|
12840
12904
|
{ id: TERMINAL_SHELL_ID, label: platform === "win32" ? "PowerShell\uFF08\u7CFB\u7EDF\u7EC8\u7AEF\uFF09" : "Shell\uFF08\u7CFB\u7EDF\u7EC8\u7AEF\uFF09", canLogin: false },
|
|
12841
|
-
...TERMINAL_TOOL_IDS.filter((id2) => installed.has(id2)).map((id2) => ({
|
|
12905
|
+
...TERMINAL_TOOL_IDS.filter((id2) => installed.has(id2)).map((id2) => ({
|
|
12906
|
+
id: id2,
|
|
12907
|
+
label: id2 === "zcode" ? `${terminalTargetLabel(id2)}\uFF08\u684C\u9762\u7248\u5185\u7F6E TUI\uFF09` : terminalTargetLabel(id2),
|
|
12908
|
+
canLogin: terminalCanLogin(id2)
|
|
12909
|
+
}))
|
|
12842
12910
|
];
|
|
12843
12911
|
}
|
|
12844
12912
|
function startProblem({ target, cwd, targets }) {
|
|
@@ -12898,6 +12966,26 @@ async function loadTerminalInfo(api) {
|
|
|
12898
12966
|
if (!info || typeof info !== "object" || !["pty", "pipe"].includes(info.backend)) throw new Error("\u7EC8\u7AEF\u72B6\u6001\u683C\u5F0F\u65E0\u6548\u3002");
|
|
12899
12967
|
return info;
|
|
12900
12968
|
}
|
|
12969
|
+
var TerminalInfoRefresher = class {
|
|
12970
|
+
constructor() {
|
|
12971
|
+
this.generation = 0;
|
|
12972
|
+
}
|
|
12973
|
+
invalidate() {
|
|
12974
|
+
this.generation += 1;
|
|
12975
|
+
}
|
|
12976
|
+
async load(api) {
|
|
12977
|
+
const generation = ++this.generation;
|
|
12978
|
+
try {
|
|
12979
|
+
const value = await loadTerminalInfo(api);
|
|
12980
|
+
return generation === this.generation ? { status: "ready", value, error: "" } : null;
|
|
12981
|
+
} catch (error) {
|
|
12982
|
+
return generation === this.generation ? { status: "error", value: null, error: remoteErrorText(text3(error?.message), "\u65E0\u6CD5\u8BFB\u53D6\u7EC8\u7AEF\u72B6\u6001\u3002") } : null;
|
|
12983
|
+
}
|
|
12984
|
+
}
|
|
12985
|
+
};
|
|
12986
|
+
function terminalInfoTools(info, healthTools = []) {
|
|
12987
|
+
return Array.isArray(info?.tools) ? info.tools : Array.isArray(healthTools) ? healthTools : [];
|
|
12988
|
+
}
|
|
12901
12989
|
async function startTerminal(api, request) {
|
|
12902
12990
|
const session = unwrap(await api.terminalStart({ ...request, confirmed: true }), "\u7EC8\u7AEF\u542F\u52A8\u5931\u8D25\u3002");
|
|
12903
12991
|
if (!isTerminalSessionId(session?.sessionId)) throw new Error("\u7EC8\u7AEF\u542F\u52A8\u7ED3\u679C\u7F3A\u5C11\u6709\u6548\u7684\u4F1A\u8BDD ID\u3002");
|
|
@@ -13091,7 +13179,7 @@ function TerminalPane({ api, session, active, onEnded }) {
|
|
|
13091
13179
|
}, [session.sessionId]);
|
|
13092
13180
|
return /* @__PURE__ */ import_react4.default.createElement("div", { className: "mr-term-pane", style: { display: active ? "block" : "none" } }, session.limitation && /* @__PURE__ */ import_react4.default.createElement("p", { className: "mr-caption mr-term-warning" }, session.limitation, session.ptyError ? `\uFF08${session.ptyError}\uFF09` : ""), error && /* @__PURE__ */ import_react4.default.createElement("p", { className: "mr-caption mr-term-warning", role: "alert" }, error), /* @__PURE__ */ import_react4.default.createElement("div", { className: "mr-term-screen", ref: host }));
|
|
13093
13181
|
}
|
|
13094
|
-
function CliTerminalCard({ api, health }) {
|
|
13182
|
+
function CliTerminalCard({ api, health, settingsSignature = "" }) {
|
|
13095
13183
|
const [info, setInfo] = import_react4.default.useState({ status: "loading", value: null, error: "" });
|
|
13096
13184
|
const [target, setTarget] = import_react4.default.useState("shell");
|
|
13097
13185
|
const [mode, setMode] = import_react4.default.useState("interactive");
|
|
@@ -13101,29 +13189,38 @@ function CliTerminalCard({ api, health }) {
|
|
|
13101
13189
|
const [startError, setStartError] = import_react4.default.useState("");
|
|
13102
13190
|
const [sessions, setSessions] = import_react4.default.useState([]);
|
|
13103
13191
|
const [activeId, setActiveId] = import_react4.default.useState("");
|
|
13192
|
+
const [tools, setTools] = import_react4.default.useState(health?.tools ?? []);
|
|
13104
13193
|
const mounted = import_react4.default.useRef(true);
|
|
13194
|
+
const refresher = import_react4.default.useRef(null);
|
|
13195
|
+
if (!refresher.current) refresher.current = new TerminalInfoRefresher();
|
|
13196
|
+
const healthTools = import_react4.default.useRef(health?.tools);
|
|
13197
|
+
healthTools.current = health?.tools;
|
|
13198
|
+
const settingsScope = import_react4.default.useRef({ tools: health?.tools, signature: settingsSignature });
|
|
13105
13199
|
const loadInfo = import_react4.default.useCallback(async () => {
|
|
13106
|
-
|
|
13107
|
-
|
|
13108
|
-
|
|
13109
|
-
|
|
13110
|
-
} catch (error) {
|
|
13111
|
-
if (mounted.current) setInfo({ status: "error", value: null, error: errorText(error, "\u65E0\u6CD5\u8BFB\u53D6\u7EC8\u7AEF\u72B6\u6001\u3002") });
|
|
13112
|
-
}
|
|
13200
|
+
const result = await refresher.current.load(api);
|
|
13201
|
+
if (!mounted.current || !result) return;
|
|
13202
|
+
setInfo(result);
|
|
13203
|
+
if (result.status === "ready") setTools(terminalInfoTools(result.value, healthTools.current));
|
|
13113
13204
|
}, [api]);
|
|
13114
13205
|
import_react4.default.useEffect(() => {
|
|
13115
13206
|
mounted.current = true;
|
|
13116
13207
|
void loadInfo();
|
|
13117
13208
|
return () => {
|
|
13118
13209
|
mounted.current = false;
|
|
13210
|
+
refresher.current.invalidate();
|
|
13119
13211
|
};
|
|
13120
13212
|
}, [loadInfo]);
|
|
13213
|
+
import_react4.default.useEffect(() => {
|
|
13214
|
+
if (settingsScope.current.tools === health?.tools && settingsScope.current.signature === settingsSignature) return;
|
|
13215
|
+
settingsScope.current = { tools: health?.tools, signature: settingsSignature };
|
|
13216
|
+
void loadInfo();
|
|
13217
|
+
}, [health?.tools, settingsSignature, loadInfo]);
|
|
13121
13218
|
const platform = info.value?.platform ?? clientPlatform();
|
|
13122
|
-
const targets = terminalTargets(
|
|
13219
|
+
const targets = terminalTargets(tools, platform);
|
|
13123
13220
|
const selected = targets.find((item) => item.id === target) ?? targets[0];
|
|
13124
13221
|
import_react4.default.useEffect(() => {
|
|
13125
13222
|
if (!targets.some((item) => item.id === target)) setTarget("shell");
|
|
13126
|
-
}, [
|
|
13223
|
+
}, [tools, target]);
|
|
13127
13224
|
import_react4.default.useEffect(() => {
|
|
13128
13225
|
if (!selected?.canLogin && mode === "login") setMode("interactive");
|
|
13129
13226
|
}, [selected?.id]);
|
|
@@ -13167,7 +13264,7 @@ function CliTerminalCard({ api, health }) {
|
|
|
13167
13264
|
};
|
|
13168
13265
|
const active = sessions.find((item) => item.sessionId === activeId);
|
|
13169
13266
|
const history = info.value?.history ?? [];
|
|
13170
|
-
return /* @__PURE__ */ import_react4.default.createElement("section", { className: "mr-card", "aria-label": "\u5B98\u65B9\u5DE5\u5177\u7EC8\u7AEF" }, /* @__PURE__ */ import_react4.default.createElement("style", null, xterm_default), /* @__PURE__ */ import_react4.default.createElement("div", { className: "mr-card-head" }, /* @__PURE__ */ import_react4.default.createElement("div", null, /* @__PURE__ */ import_react4.default.createElement("h2", { className: "mr-card-title" }, "\u5B98\u65B9\u5DE5\u5177\u7EC8\u7AEF"), /* @__PURE__ */ import_react4.default.createElement("p", { className: "mr-card-copy" }, "\u5728\u5DE5\u4F5C\u53F0\u91CC\u4EA4\u4E92\u5F0F\u8FD0\u884C PowerShell
|
|
13267
|
+
return /* @__PURE__ */ import_react4.default.createElement("section", { className: "mr-card", "aria-label": "\u5B98\u65B9\u5DE5\u5177\u7EC8\u7AEF" }, /* @__PURE__ */ import_react4.default.createElement("style", null, xterm_default), /* @__PURE__ */ import_react4.default.createElement("div", { className: "mr-card-head" }, /* @__PURE__ */ import_react4.default.createElement("div", null, /* @__PURE__ */ import_react4.default.createElement("h2", { className: "mr-card-title" }, "\u5B98\u65B9\u5DE5\u5177\u7EC8\u7AEF"), /* @__PURE__ */ import_react4.default.createElement("p", { className: "mr-card-copy" }, "\u5728\u5DE5\u4F5C\u53F0\u91CC\u4EA4\u4E92\u5F0F\u8FD0\u884C PowerShell\u3001\u5DF2\u5B89\u88C5\u7684\u5B98\u65B9 CLI \u6216 ZCode \u684C\u9762\u7248\u5185\u7F6E TUI\uFF08\u591A\u8F6E\u5BF9\u8BDD\u3001\u5B9E\u65F6\u8F93\u51FA\uFF0C\u53EF\u7528\u4E8E ", /* @__PURE__ */ import_react4.default.createElement("code", null, "codex login"), " \u7B49\u767B\u5F55\uFF09\u3002\u542F\u52A8\u5165\u53E3\u4E0E\u5B98\u65B9\u5DE5\u5177\u7684\u5B89\u88C5\u65B9\u5F0F\u548C\u76EE\u5F55\u540C\u6B65\u3002\u7EC8\u7AEF\u4E0D\u7ECF\u8FC7 Harness \u6C99\u7BB1\uFF0C\u4F7F\u7528\u4F60\u81EA\u5DF1\u7684\u767B\u5F55\u548C\u73AF\u5883\u53D8\u91CF\u3002")), /* @__PURE__ */ import_react4.default.createElement("button", { className: "mr-button mr-button-secondary", type: "button", onClick: () => {
|
|
13171
13268
|
void loadInfo();
|
|
13172
13269
|
} }, "\u5237\u65B0")), /* @__PURE__ */ import_react4.default.createElement("div", { className: "mr-card-body" }, info.status === "error" && /* @__PURE__ */ import_react4.default.createElement("div", { className: "mr-error", role: "alert" }, info.error), info.value && /* @__PURE__ */ import_react4.default.createElement("p", { className: "mr-caption" }, info.value.backend === "pty" ? "\u7EC8\u7AEF\u7EC4\u4EF6\uFF1A\u4F2A\u7EC8\u7AEF\uFF08PTY\uFF09\uFF0C\u652F\u6301\u5168\u5C4F\u754C\u9762\u3001\u989C\u8272\u548C\u7A97\u53E3\u5927\u5C0F\u540C\u6B65\u3002" : `\u7EC8\u7AEF\u7EC4\u4EF6\uFF1A\u7BA1\u9053\u6A21\u5F0F\u3002${info.value.limitation ?? ""}${info.value.ptyError ? `\uFF08PTY \u52A0\u8F7D\u5931\u8D25\uFF1A${info.value.ptyError}\uFF09` : ""}`), /* @__PURE__ */ import_react4.default.createElement("div", { className: "mr-controls" }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "mr-control-group" }, /* @__PURE__ */ import_react4.default.createElement("label", { className: "mr-control-label", htmlFor: "mr-term-target" }, "\u542F\u52A8"), /* @__PURE__ */ import_react4.default.createElement("select", { className: "mr-input", id: "mr-term-target", value: selected?.id ?? "shell", onChange: (event) => {
|
|
13173
13270
|
setTarget(event.target.value);
|
|
@@ -13191,7 +13288,7 @@ function CliTerminalCard({ api, health }) {
|
|
|
13191
13288
|
setConfirming(false);
|
|
13192
13289
|
}
|
|
13193
13290
|
}
|
|
13194
|
-
))), targets.length === 1 && /* @__PURE__ */ import_react4.default.createElement("p", { className: "mr-caption" }, "\
|
|
13291
|
+
))), targets.length === 1 && /* @__PURE__ */ import_react4.default.createElement("p", { className: "mr-caption" }, "\u5C1A\u672A\u53D1\u73B0\u5DF2\u5B89\u88C5\u7684\u5B98\u65B9 CLI\uFF1B\u5B89\u88C5\u6216\u914D\u7F6E\u76EE\u5F55\u540E\u70B9\u672C\u5361\u7247\u201C\u5237\u65B0\u201D\u6216\u201C\u5B98\u65B9\u5DE5\u5177 \xB7 \u4F53\u68C0\u201D\u7684\u201C\u91CD\u65B0\u4F53\u68C0\u201D\uFF0C\u8FD9\u91CC\u4F1A\u51FA\u73B0\u5BF9\u5E94\u9009\u9879\u3002"), !confirming && /* @__PURE__ */ import_react4.default.createElement("div", { className: "mr-actions" }, /* @__PURE__ */ import_react4.default.createElement("button", { className: "mr-button", type: "button", disabled: Boolean(problem) || live >= maxSessions || info.status !== "ready", onClick: () => {
|
|
13195
13292
|
setStartError("");
|
|
13196
13293
|
setConfirming(true);
|
|
13197
13294
|
} }, "\u5F00\u59CB"), /* @__PURE__ */ import_react4.default.createElement("span", { className: "mr-caption" }, problem || (live >= maxSessions ? `\u6700\u591A\u540C\u65F6\u8FD0\u884C ${maxSessions} \u4E2A\u4F1A\u8BDD\u3002` : `\u5C06\u8FD0\u884C\uFF1A${details.command}`))), confirming && /* @__PURE__ */ import_react4.default.createElement("div", { className: "mr-term-confirm", role: "dialog", "aria-label": "\u786E\u8BA4\u542F\u52A8\u7EC8\u7AEF" }, /* @__PURE__ */ import_react4.default.createElement("strong", null, details.title), /* @__PURE__ */ import_react4.default.createElement("p", { className: "mr-caption" }, "\u547D\u4EE4\uFF1A", /* @__PURE__ */ import_react4.default.createElement("code", null, details.command), /* @__PURE__ */ import_react4.default.createElement("br", null), "\u5DE5\u4F5C\u76EE\u5F55\uFF1A", /* @__PURE__ */ import_react4.default.createElement("code", null, details.cwd)), /* @__PURE__ */ import_react4.default.createElement("ul", null, details.points.map((point) => /* @__PURE__ */ import_react4.default.createElement("li", { key: point }, point))), /* @__PURE__ */ import_react4.default.createElement("div", { className: "mr-actions" }, /* @__PURE__ */ import_react4.default.createElement("button", { className: "mr-button", type: "button", disabled: starting, onClick: () => {
|
|
@@ -13537,10 +13634,10 @@ function probeLabel(probe) {
|
|
|
13537
13634
|
var INSTALL_SETTING_FIELDS = [
|
|
13538
13635
|
{
|
|
13539
13636
|
key: "toolInstallDir",
|
|
13540
|
-
label: "\u7EDF\u4E00\u5B89\u88C5\u76EE\u5F55",
|
|
13637
|
+
label: "\u7EDF\u4E00\u5B89\u88C5\u6839\u76EE\u5F55",
|
|
13541
13638
|
fallback: "",
|
|
13542
13639
|
placeholder: "\u7559\u7A7A = \u5404\u5382\u5546\u9ED8\u8BA4\u76EE\u5F55",
|
|
13543
|
-
hint: "\
|
|
13640
|
+
hint: "\u4F8B\u5982 D:/AI/tools\u3002npm / pnpm \u4F7F\u7528\u8BE5\u6839\uFF1B\u5382\u5546\u811A\u672C\u4F7F\u7528\u5DE5\u5177\u4E13\u5C5E\u5B50\u76EE\u5F55\uFF0C\u5B9E\u9645\u5730\u5740\u89C1\u5DE5\u5177\u884C\u3002\u56FA\u5B9A\u5382\u5546\u5730\u5740\u7684\u65B9\u5F0F\u4F1A\u8BF4\u660E\u539F\u56E0\u3002"
|
|
13544
13641
|
},
|
|
13545
13642
|
{
|
|
13546
13643
|
key: "toolNpmRegistry",
|
|
@@ -13557,7 +13654,14 @@ var INSTALL_SETTING_FIELDS = [
|
|
|
13557
13654
|
hint: "\u6309\u5DE5\u5177 ID \u6307\u5B9A https \u955C\u50CF\u5730\u5740\u3002\u811A\u672C\u4E0B\u8F7D\u540E\u4ECD\u4F1A\u6838\u5BF9\u5382\u5546\u6807\u8BB0\uFF0C\u518D\u6267\u884C\u672C\u5730\u526F\u672C\u3002"
|
|
13558
13655
|
}
|
|
13559
13656
|
];
|
|
13560
|
-
|
|
13657
|
+
var ZCODE_SETTING_FIELDS = [{
|
|
13658
|
+
key: "zcodeInstallDir",
|
|
13659
|
+
label: "ZCode \u684C\u9762\u5B89\u88C5\u76EE\u5F55",
|
|
13660
|
+
fallback: "",
|
|
13661
|
+
placeholder: "\u4F8B\u5982 D:/Program Files/ZCode\uFF0C\u7559\u7A7A\u81EA\u52A8\u68C0\u6D4B",
|
|
13662
|
+
hint: "\u5DF2\u5B89\u88C5\u684C\u9762\u7248\u5373\u53EF\u4F7F\u7528\u5185\u7F6E TUI\u3002\u4FDD\u5B58\u76EE\u5F55\u540E\u91CD\u65B0\u6838\u9A8C\u684C\u9762\u7A0B\u5E8F\u548C\u5185\u7F6E CLI\uFF1B\u65E0\u9700\u72EC\u7ACB CLI \u5B89\u88C5\u5305\u3002"
|
|
13663
|
+
}];
|
|
13664
|
+
function InstallSettings({ settingsScope, install, onPendingChange, onMutationStart, zcode = false }) {
|
|
13561
13665
|
const [snapshot, setSnapshot] = import_react5.default.useState(() => settingsScope?.getSnapshot?.() ?? { value: {}, writable: false });
|
|
13562
13666
|
const [drafts, setDrafts] = import_react5.default.useState({});
|
|
13563
13667
|
const [saving, setSaving] = import_react5.default.useState(false);
|
|
@@ -13579,7 +13683,8 @@ function InstallSettings({ settingsScope, install, onPendingChange, onMutationSt
|
|
|
13579
13683
|
if (!settingsScope) return null;
|
|
13580
13684
|
const writable = snapshot.writable === true && !saving;
|
|
13581
13685
|
const shown = (field2) => drafts[field2.key] ?? String(snapshot.value?.[field2.key] ?? field2.fallback);
|
|
13582
|
-
const
|
|
13686
|
+
const fields = zcode ? ZCODE_SETTING_FIELDS : INSTALL_SETTING_FIELDS;
|
|
13687
|
+
const errors = Object.fromEntries(fields.map((field2) => [field2.key, validateToolInstallSetting(field2.key, shown(field2))]));
|
|
13583
13688
|
const invalid = Object.values(errors).some(Boolean);
|
|
13584
13689
|
const edit = (key, value) => {
|
|
13585
13690
|
const next = retainToolInstallDrafts({ ...drafts, [key]: value }, snapshot.value);
|
|
@@ -13611,7 +13716,7 @@ function InstallSettings({ settingsScope, install, onPendingChange, onMutationSt
|
|
|
13611
13716
|
setSaving(false);
|
|
13612
13717
|
}
|
|
13613
13718
|
};
|
|
13614
|
-
return /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-install-settings", "aria-label": "\u7EDF\u4E00\u5B89\u88C5\u8BBE\u7F6E" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-install-settings-head" }, /* @__PURE__ */ import_react5.default.createElement("strong", null, "\u7EDF\u4E00\u5B89\u88C5\u8BBE\u7F6E"), /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-caption" }, "\u4FDD\u5B58\u540E\u7528\u4E8E\u540E\u7EED\u5B89\u88C5\u4E0E\u66F4\u65B0\u3002\u6BCF\u4E2A\u5DE5\u5177\u4E0B\u65B9\u663E\u793A\u5B9E\u9645\u65B9\u5F0F\u548C\u76EE\u5F55\uFF0C\u63D2\u4EF6\u8BBE\u7F6E\u9875\u91CC\u4E5F\u80FD\u4FEE\u6539\u3002")), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-install-grid" },
|
|
13719
|
+
return /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-install-settings", "aria-label": zcode ? "ZCode TUI \u72EC\u7ACB\u914D\u7F6E" : "\u7EDF\u4E00\u5B89\u88C5\u8BBE\u7F6E" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-install-settings-head" }, /* @__PURE__ */ import_react5.default.createElement("strong", null, zcode ? "ZCode TUI \u72EC\u7ACB\u914D\u7F6E" : "\u7EDF\u4E00\u5B89\u88C5\u8BBE\u7F6E"), /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-caption" }, zcode ? "\u5185\u7F6E CLI \u968F\u684C\u9762\u7248\u66F4\u65B0\u3002\u4FDD\u5B58\u540E\u5728\u5B98\u65B9\u5DE5\u5177\u7EC8\u7AEF\u9009\u62E9 ZCode TUI\uFF0C\u81EA\u884C\u914D\u7F6E\u767B\u5F55\u3001\u6A21\u578B\u4E0E\u63D2\u4EF6\u3002" : "\u4FDD\u5B58\u540E\u7528\u4E8E\u540E\u7EED\u5B89\u88C5\u4E0E\u66F4\u65B0\u3002\u6BCF\u4E2A\u5DE5\u5177\u4E0B\u65B9\u663E\u793A\u5B9E\u9645\u65B9\u5F0F\u548C\u76EE\u5F55\uFF0C\u63D2\u4EF6\u8BBE\u7F6E\u9875\u91CC\u4E5F\u80FD\u4FEE\u6539\u3002")), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-install-grid" }, fields.map((field2) => /* @__PURE__ */ import_react5.default.createElement("label", { className: "mr-install-field", key: field2.key }, /* @__PURE__ */ import_react5.default.createElement("span", null, field2.label), /* @__PURE__ */ import_react5.default.createElement(
|
|
13615
13720
|
"input",
|
|
13616
13721
|
{
|
|
13617
13722
|
className: "mr-input",
|
|
@@ -13621,7 +13726,7 @@ function InstallSettings({ settingsScope, install, onPendingChange, onMutationSt
|
|
|
13621
13726
|
"aria-invalid": Boolean(errors[field2.key]),
|
|
13622
13727
|
onChange: (event) => edit(field2.key, event.target.value)
|
|
13623
13728
|
}
|
|
13624
|
-
), errors[field2.key] ? /* @__PURE__ */ import_react5.default.createElement("small", { className: "mr-install-error", role: "alert" }, errors[field2.key]) : /* @__PURE__ */ import_react5.default.createElement("small", null, field2.hint))), /* @__PURE__ */ import_react5.default.createElement("label", { className: "mr-install-field" }, /* @__PURE__ */ import_react5.default.createElement("span", null, "\u5B89\u88C5\u811A\u672C\u65B9\u5F0F"), /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-install-toggle-row" }, /* @__PURE__ */ import_react5.default.createElement(
|
|
13729
|
+
), errors[field2.key] ? /* @__PURE__ */ import_react5.default.createElement("small", { className: "mr-install-error", role: "alert" }, errors[field2.key]) : /* @__PURE__ */ import_react5.default.createElement("small", null, field2.hint))), !zcode && /* @__PURE__ */ import_react5.default.createElement("label", { className: "mr-install-field" }, /* @__PURE__ */ import_react5.default.createElement("span", null, "\u5B89\u88C5\u811A\u672C\u65B9\u5F0F"), /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-install-toggle-row" }, /* @__PURE__ */ import_react5.default.createElement(
|
|
13625
13730
|
"input",
|
|
13626
13731
|
{
|
|
13627
13732
|
type: "checkbox",
|
|
@@ -13633,11 +13738,11 @@ function InstallSettings({ settingsScope, install, onPendingChange, onMutationSt
|
|
|
13633
13738
|
}
|
|
13634
13739
|
), /* @__PURE__ */ import_react5.default.createElement("span", null, "\u5141\u8BB8 curl / irm \u5B89\u88C5\u811A\u672C")), /* @__PURE__ */ import_react5.default.createElement("small", null, "\u5173\u95ED\u540E\u53EA\u80FD\u4F7F\u7528 npm / pnpm \u65B9\u5F0F\uFF1B\u811A\u672C\u65B9\u5F0F\u9700\u8981\u5148\u4E0B\u8F7D\u5E76\u6821\u9A8C\u5382\u5546\u6807\u8BB0\u518D\u6267\u884C\u3002"))), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-install-save-row" }, /* @__PURE__ */ import_react5.default.createElement("button", { className: "mr-button mr-button-secondary", type: "button", disabled: !writable || !dirty || invalid, onClick: () => {
|
|
13635
13740
|
void apply2();
|
|
13636
|
-
} }, saving ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58\u5B89\u88C5\u8BBE\u7F6E"), dirty && /* @__PURE__ */ import_react5.default.createElement("button", { className: "mr-button mr-button-secondary", type: "button", disabled: saving, onClick: () => {
|
|
13741
|
+
} }, saving ? "\u4FDD\u5B58\u4E2D\u2026" : zcode ? "\u4FDD\u5B58\u5E76\u5237\u65B0 TUI \u5165\u53E3" : "\u4FDD\u5B58\u5B89\u88C5\u8BBE\u7F6E"), dirty && /* @__PURE__ */ import_react5.default.createElement("button", { className: "mr-button mr-button-secondary", type: "button", disabled: saving, onClick: () => {
|
|
13637
13742
|
setDrafts({});
|
|
13638
13743
|
setNotice("");
|
|
13639
13744
|
onPendingChange?.(false);
|
|
13640
|
-
} }, "\u653E\u5F03\u66F4\u6539"), dirty && /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-caption" }, invalid ? "\u8BF7\u4FEE\u6B63\u8F93\u5165\u540E\u4FDD\u5B58\u3002" : "\u66F4\u6539\u5C1A\u672A\u4FDD\u5B58\uFF0C\u5B89\u88C5\u4E0E\u66F4\u65B0\u6682\u4E0D\u53EF\u7528\u3002")), /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-caption", style: { marginTop: 8 }, role: notice ? "status" : void 0 }, "\u5F53\u524D\u751F\u6548\uFF1A\u5B89\u88C5\u76EE\u5F55
|
|
13745
|
+
} }, "\u653E\u5F03\u66F4\u6539"), dirty && /* @__PURE__ */ import_react5.default.createElement("span", { className: "mr-caption" }, invalid ? "\u8BF7\u4FEE\u6B63\u8F93\u5165\u540E\u4FDD\u5B58\u3002" : "\u66F4\u6539\u5C1A\u672A\u4FDD\u5B58\uFF0C\u5B89\u88C5\u4E0E\u66F4\u65B0\u6682\u4E0D\u53EF\u7528\u3002")), /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-caption", style: { marginTop: 8 }, role: notice ? "status" : void 0 }, zcode ? `\u5F53\u524D ZCode \u76EE\u5F55\uFF1A${install?.zcodeInstallDir || "\uFF08\u81EA\u52A8\u68C0\u6D4B\uFF09"}` : `\u5F53\u524D\u751F\u6548\uFF1A\u5B89\u88C5\u76EE\u5F55 ${install?.installDir || "\uFF08\u5404\u5382\u5546\u9ED8\u8BA4\uFF09"} \xB7 npm \u6E90 ${install?.registry || "\uFF08\u9ED8\u8BA4\uFF09"}`, notice ? ` \xB7 ${notice}` : ""));
|
|
13641
13746
|
}
|
|
13642
13747
|
function OfficialToolsCard({ listOfficialTools, loadOfficialInstallSettings, installOfficialTool, uninstallOfficialTool, repairOfficialTool, cancelOfficialToolInstall, officialToolInstallStatus, onProbes, health, onRefreshHealth, settingsScope }) {
|
|
13643
13748
|
const healthById = Object.fromEntries((health?.tools ?? []).map((item) => [item.id, item]));
|
|
@@ -13661,9 +13766,18 @@ function OfficialToolsCard({ listOfficialTools, loadOfficialInstallSettings, ins
|
|
|
13661
13766
|
const submitting = import_react5.default.useRef(/* @__PURE__ */ new Set());
|
|
13662
13767
|
const polling = import_react5.default.useRef(/* @__PURE__ */ new Set());
|
|
13663
13768
|
const jobsRef = import_react5.default.useRef({});
|
|
13769
|
+
const settingsPendingBySection = import_react5.default.useRef({ shared: false, zcode: false });
|
|
13664
13770
|
const handleSettingsPending = import_react5.default.useCallback((value) => {
|
|
13665
|
-
|
|
13666
|
-
|
|
13771
|
+
settingsPendingBySection.current.shared = value;
|
|
13772
|
+
const pending = Object.values(settingsPendingBySection.current).some(Boolean);
|
|
13773
|
+
settingsPendingRef.current = pending;
|
|
13774
|
+
setSettingsPending(pending);
|
|
13775
|
+
}, []);
|
|
13776
|
+
const handleZCodeSettingsPending = import_react5.default.useCallback((value) => {
|
|
13777
|
+
settingsPendingBySection.current.zcode = value;
|
|
13778
|
+
const pending = Object.values(settingsPendingBySection.current).some(Boolean);
|
|
13779
|
+
settingsPendingRef.current = pending;
|
|
13780
|
+
setSettingsPending(pending);
|
|
13667
13781
|
}, []);
|
|
13668
13782
|
const rememberJobs = (updater) => {
|
|
13669
13783
|
setJobs((previous) => {
|
|
@@ -13784,6 +13898,8 @@ function OfficialToolsCard({ listOfficialTools, loadOfficialInstallSettings, ins
|
|
|
13784
13898
|
}, []);
|
|
13785
13899
|
const refreshInstallSettingsRef = import_react5.default.useRef(refreshInstallSettings);
|
|
13786
13900
|
refreshInstallSettingsRef.current = refreshInstallSettings;
|
|
13901
|
+
const refreshProbesRef = import_react5.default.useRef(refresh);
|
|
13902
|
+
refreshProbesRef.current = refresh;
|
|
13787
13903
|
const beginSettingsMutation = import_react5.default.useCallback((operations) => {
|
|
13788
13904
|
const generation = ++mutationGeneration.current;
|
|
13789
13905
|
mutationPendingRef.current = { generation, operations };
|
|
@@ -13800,12 +13916,15 @@ function OfficialToolsCard({ listOfficialTools, loadOfficialInstallSettings, ins
|
|
|
13800
13916
|
if (typeof settingsScope?.subscribe !== "function") return void 0;
|
|
13801
13917
|
const signature2 = (snapshot) => toolInstallSettingsSignature(snapshot?.value);
|
|
13802
13918
|
let previous = signature2(settingsScope.getSnapshot());
|
|
13919
|
+
let previousZCode = settingsScope.getSnapshot()?.value?.zcodeInstallDir ?? "";
|
|
13803
13920
|
return settingsScope.subscribe(() => {
|
|
13804
13921
|
const snapshot = settingsScope.getSnapshot();
|
|
13805
13922
|
setSettingsSnapshot(snapshot);
|
|
13806
13923
|
const next = signature2(snapshot);
|
|
13807
13924
|
if (next === previous) return;
|
|
13808
13925
|
previous = next;
|
|
13926
|
+
const zcodeChanged = previousZCode !== (snapshot?.value?.zcodeInstallDir ?? "");
|
|
13927
|
+
previousZCode = snapshot?.value?.zcodeInstallDir ?? "";
|
|
13809
13928
|
request.current += 1;
|
|
13810
13929
|
setProbeSettingsStale(true);
|
|
13811
13930
|
setProbeState((previous2) => ({ ...previous2, status: "ready", probes: [], readiness: [], error: "" }));
|
|
@@ -13813,6 +13932,7 @@ function OfficialToolsCard({ listOfficialTools, loadOfficialInstallSettings, ins
|
|
|
13813
13932
|
previewPendingRef.current = true;
|
|
13814
13933
|
setPreviewPending(true);
|
|
13815
13934
|
void refreshInstallSettingsRef.current();
|
|
13935
|
+
if (zcodeChanged) void refreshProbesRef.current();
|
|
13816
13936
|
});
|
|
13817
13937
|
}, [settingsScope]);
|
|
13818
13938
|
import_react5.default.useEffect(() => {
|
|
@@ -13987,7 +14107,16 @@ function OfficialToolsCard({ listOfficialTools, loadOfficialInstallSettings, ins
|
|
|
13987
14107
|
const verified = Boolean(probe) && job?.status === "succeeded" && (job.operation === "uninstall" ? job.postInstallProbe?.installed === false : job.postInstallProbe?.installed === true);
|
|
13988
14108
|
const operation = job?.operation === "uninstall" ? "\u5378\u8F7D" : job?.operation === "repair" ? "\u4FEE\u590D" : "\u5B89\u88C5";
|
|
13989
14109
|
const status = running ? job.cancelRequested ? `\u6B63\u5728\u53D6\u6D88${operation}\u2026` : `${operation}\u4E2D\u2026` : job?.status === "installer-opened" ? "\u5B98\u65B9\u5B89\u88C5\u5668\u5DF2\u6253\u5F00\uFF0C\u8BF7\u5B8C\u6210\u5B89\u88C5\u540E\u91CD\u65B0\u68C0\u6D4B" : job?.status === "cancelled" ? `${operation}\u5DF2\u53D6\u6D88\uFF0C\u8BF7\u91CD\u65B0\u68C0\u6D4B` : verified ? `${operation}\u6210\u529F\u5E76\u9A8C\u8BC1` : probe ? probeLabel(probe) : "\u6240\u9009\u5B89\u88C5\u76EE\u6807\u5C1A\u672A\u4F53\u68C0";
|
|
13990
|
-
return /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-tool", role: "listitem", key: tool.id }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-tool-info" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-route-name", title: tool.purpose }, tool.label), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-route-provider" }, tool.vendor, " \xB7 ", tool.id), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-tool-status", role: "status" }, /* @__PURE__ */ import_react5.default.createElement("span", { className: `mr-tool-dot ${running ? "running" : probe?.installed ? "installed" : "missing"}` }), status, probe?.installed && probe.version ? ` \xB7 ${
|
|
14110
|
+
return /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-tool", role: "listitem", key: tool.id }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-tool-info" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-route-name", title: tool.purpose }, tool.label), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-route-provider" }, tool.vendor, " \xB7 ", tool.id), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-tool-status", role: "status" }, /* @__PURE__ */ import_react5.default.createElement("span", { className: `mr-tool-dot ${running ? "running" : probe?.installed ? "installed" : "missing"}` }), status, probe?.installed && probe.version ? ` \xB7 ${tool.id === "zcode" ? "\u684C\u9762\u7248 " : ""}${probe.version}` : "", healthById[tool.id]?.latestVersion ? ` \xB7 \u6700\u65B0 ${healthById[tool.id].latestVersion}` : ""), /* @__PURE__ */ import_react5.default.createElement(ToolLoginLine, { entry: healthById[tool.id] }), tool.id === "zcode" && /* @__PURE__ */ import_react5.default.createElement(
|
|
14111
|
+
InstallSettings,
|
|
14112
|
+
{
|
|
14113
|
+
zcode: true,
|
|
14114
|
+
settingsScope,
|
|
14115
|
+
install: probeState.install,
|
|
14116
|
+
onPendingChange: handleZCodeSettingsPending,
|
|
14117
|
+
onMutationStart: beginSettingsMutation
|
|
14118
|
+
}
|
|
14119
|
+
), probe?.installed && /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-caption mr-tool-detail" }, tool.headlessAdapter ? "\u5DF2\u53EF\u7531 model_router_execute \u4EE5\u65E0\u754C\u9762\u65B9\u5F0F\u8C03\u7528\u3002\u547D\u4EE4\u7F3A\u5931\u6216\u5931\u8D25\u65F6\u56DE\u9000\u6A21\u578B\u76EE\u5F55 API\u3002\u7B7E\u540D\u6C99\u7BB1\u5165\u53E3\u4E0D\u542F\u52A8\u6B64 CLI\u3002" : readiness?.ready ? `\u5B98\u65B9\u6267\u884C\u5165\u53E3\u5DF2\u6838\u9A8C\uFF0C\u53EF\u5728\u4F1A\u8BDD\u4E2D\u8C03\u7528 model_router_tool_run\uFF1B${capability?.modes?.includes("read-only") ? "\u652F\u6301\u53EA\u8BFB\u548C\u7ECF\u5BA1\u6279\u7684\u53EF\u7F16\u8F91\u4EFB\u52A1" : "\u4EC5\u652F\u6301\u7ECF\u5BA1\u6279\u7684\u53EF\u7F16\u8F91\u9694\u79BB\u5DE5\u4F5C\u533A\u4EFB\u52A1"}\uFF0C\u8D26\u53F7\u53CA\u6A21\u578B\u4ECD\u9700\u5B9E\u6D4B\u3002` : `\u5DF2\u5B89\u88C5\uFF0C\u4F46\u5F53\u524D\u4E0D\u53EF\u6258\u7BA1\u6267\u884C\uFF1A${readiness?.reason || capability?.reason || "\u6267\u884C\u5165\u53E3\u5C1A\u672A\u6838\u9A8C\u3002"}`), command ? /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, null, /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-caption mr-tool-detail" }, "\u5B89\u88C5\u65B9\u5F0F\uFF1A", methods.find((method) => method.id === summary?.methodId)?.label ?? (tool.manager === "signed-windows-installer" ? "\u5B98\u65B9\u684C\u9762\u5B89\u88C5\u5668" : tool.manager), " \xB7 \u5B9E\u9645\u5B89\u88C5\u76EE\u5F55\uFF1A", probe?.installDir || summary?.installDir || "\u5404\u5382\u5546\u9ED8\u8BA4\u76EE\u5F55"), /* @__PURE__ */ import_react5.default.createElement("code", { className: "mr-tool-command", "aria-label": `${tool.label} \u5B89\u88C5\u547D\u4EE4` }, command), updateCommand !== command && /* @__PURE__ */ import_react5.default.createElement(import_react5.default.Fragment, null, /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-caption mr-tool-detail" }, "\u66F4\u65B0\u6CBF\u7528\u539F\u5B89\u88C5\u4F4D\u7F6E\uFF1A", summary?.updateInstallDir || "\u5404\u5382\u5546\u9ED8\u8BA4\u76EE\u5F55"), /* @__PURE__ */ import_react5.default.createElement("code", { className: "mr-tool-command", "aria-label": `${tool.label} \u66F4\u65B0\u547D\u4EE4` }, updateCommand))) : /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-caption", style: { margin: "6px 0 0" } }, summary?.error ?? tool.unsupportedReason), (summary?.notices ?? []).map((notice) => /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-caption mr-tool-detail", key: notice }, notice)), probe?.detail && /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-caption mr-tool-detail" }, probe.detail), (rowErrors[tool.id] || job?.error) && /* @__PURE__ */ import_react5.default.createElement("p", { className: "mr-error mr-tool-error", role: "alert" }, rowErrors[tool.id] || job.error), Array.isArray(job?.outputTail) && job.outputTail.length > 0 && /* @__PURE__ */ import_react5.default.createElement("details", { className: "mr-tool-log" }, /* @__PURE__ */ import_react5.default.createElement("summary", null, "\u5B89\u88C5\u65E5\u5FD7"), /* @__PURE__ */ import_react5.default.createElement("pre", null, job.outputTail.slice(-6).join("\n")))), (command || methods.length > 0) && /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-tool-actions" }, methods.length > 0 && /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-tool-methods" }, /* @__PURE__ */ import_react5.default.createElement("label", null, /* @__PURE__ */ import_react5.default.createElement("span", null, "\u5B89\u88C5\u65B9\u5F0F"), /* @__PURE__ */ import_react5.default.createElement(
|
|
13991
14120
|
"select",
|
|
13992
14121
|
{
|
|
13993
14122
|
className: "mr-mini-select",
|
|
@@ -14370,7 +14499,14 @@ function RouterMainPage({ loadCatalog, settingsScope, listOfficialTools, loadOff
|
|
|
14370
14499
|
void workbench.refreshHealth(true);
|
|
14371
14500
|
}
|
|
14372
14501
|
}
|
|
14373
|
-
), terminalApi && /* @__PURE__ */ import_react5.default.createElement(
|
|
14502
|
+
), terminalApi && /* @__PURE__ */ import_react5.default.createElement(
|
|
14503
|
+
CliTerminalCard,
|
|
14504
|
+
{
|
|
14505
|
+
api: terminalApi,
|
|
14506
|
+
health: workbench.health.report,
|
|
14507
|
+
settingsSignature: toolInstallSettingsSignature(settingsScope?.getSnapshot?.()?.value)
|
|
14508
|
+
}
|
|
14509
|
+
)), /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-view mr-stack", role: "tabpanel", id: "mr-panel-controls", "aria-labelledby": "mr-tab-controls", hidden: view !== "controls" }, /* @__PURE__ */ import_react5.default.createElement("div", { className: "mr-view-heading" }, /* @__PURE__ */ import_react5.default.createElement("h2", null, "\u9884\u7B97\u4E0E\u5B89\u5168"), /* @__PURE__ */ import_react5.default.createElement("p", null, "\u8BBE\u7F6E\u6210\u672C\u4E0E\u8D28\u91CF\u7B56\u7565\uFF0C\u6838\u5BF9\u8BA2\u9605\u8BA1\u8D39\u548C\u6267\u884C\u8FB9\u754C\u3002")), /* @__PURE__ */ import_react5.default.createElement(
|
|
14374
14510
|
CostControlCard,
|
|
14375
14511
|
{
|
|
14376
14512
|
ledger: workbench.ledger.value,
|
|
@@ -14670,6 +14806,17 @@ function installDirField() {
|
|
|
14670
14806
|
}
|
|
14671
14807
|
};
|
|
14672
14808
|
}
|
|
14809
|
+
function zcodeInstallDirField() {
|
|
14810
|
+
const field2 = (0, import_dsh_client_ui_primitives.settingsTextField)("zcodeInstallDir");
|
|
14811
|
+
return { ...field2, parse: (text7) => {
|
|
14812
|
+
try {
|
|
14813
|
+
parseInstallPreferences({ zcodeInstallDir: text7 }, { tools: OFFICIAL_TOOLS });
|
|
14814
|
+
} catch {
|
|
14815
|
+
return void 0;
|
|
14816
|
+
}
|
|
14817
|
+
return field2.parse(text7);
|
|
14818
|
+
} };
|
|
14819
|
+
}
|
|
14673
14820
|
function npmRegistryField() {
|
|
14674
14821
|
const field2 = (0, import_dsh_client_ui_primitives.settingsTextField)("toolNpmRegistry");
|
|
14675
14822
|
return {
|
|
@@ -14731,6 +14878,7 @@ var RouterSettingsCardController = class {
|
|
|
14731
14878
|
modelProfilesField(),
|
|
14732
14879
|
quotaPatternsField(),
|
|
14733
14880
|
installDirField(),
|
|
14881
|
+
zcodeInstallDirField(),
|
|
14734
14882
|
npmRegistryField(),
|
|
14735
14883
|
installMethodsField(),
|
|
14736
14884
|
scriptUrlsField()
|
|
@@ -14746,6 +14894,7 @@ var RouterSettingsCardController = class {
|
|
|
14746
14894
|
modelProfilesJson: this.form.field("modelProfilesJson"),
|
|
14747
14895
|
quotaPatternsJson: this.form.field("quotaPatternsJson"),
|
|
14748
14896
|
toolInstallDir: this.form.field("toolInstallDir"),
|
|
14897
|
+
zcodeInstallDir: this.form.field("zcodeInstallDir"),
|
|
14749
14898
|
toolNpmRegistry: this.form.field("toolNpmRegistry"),
|
|
14750
14899
|
toolInstallMethodsJson: this.form.field("toolInstallMethodsJson"),
|
|
14751
14900
|
toolScriptUrlsJson: this.form.field("toolScriptUrlsJson")
|
|
@@ -14876,8 +15025,8 @@ function RouterSettingsCard(props) {
|
|
|
14876
15025
|
import_dsh_client_ui_primitives.SettingsValueField,
|
|
14877
15026
|
{
|
|
14878
15027
|
id: "model-router-tool-install-dir",
|
|
14879
|
-
label: "\u7EDF\u4E00\u5B89\u88C5\u76EE\u5F55",
|
|
14880
|
-
hint: "\u586B\u5199\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u7559\u7A7A\u4F7F\u7528\u5382\u5546\u9ED8\u8BA4\u4F4D\u7F6E\u3002npm / pnpm \
|
|
15028
|
+
label: "\u7EDF\u4E00\u5B89\u88C5\u6839\u76EE\u5F55",
|
|
15029
|
+
hint: "\u586B\u5199\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u7559\u7A7A\u4F7F\u7528\u5382\u5546\u9ED8\u8BA4\u4F4D\u7F6E\u3002npm / pnpm \u5171\u7528\u8BE5\u6839\uFF1B\u53EF\u914D\u7F6E\u5382\u5546\u811A\u672C\u4F7F\u7528\u5DE5\u5177\u4E13\u5C5E\u5B50\u76EE\u5F55\uFF0C\u5B9E\u9645\u4F4D\u7F6E\u89C1\u5B98\u65B9\u5DE5\u5177\u9875\u3002\u66F4\u65B0\u590D\u7528\u6240\u9009\u65B9\u5F0F\u3001\u76EE\u5F55\u4E0E\u4E0B\u8F7D\u6E90\u3002",
|
|
14881
15030
|
disabled,
|
|
14882
15031
|
...state.toolInstallDir,
|
|
14883
15032
|
overriddenLabel: FIELD_COPY.overridden,
|
|
@@ -14908,6 +15057,24 @@ function RouterSettingsCard(props) {
|
|
|
14908
15057
|
props.resetField("toolNpmRegistry");
|
|
14909
15058
|
}
|
|
14910
15059
|
}
|
|
15060
|
+
), /* @__PURE__ */ import_react6.default.createElement(
|
|
15061
|
+
import_dsh_client_ui_primitives.SettingsValueField,
|
|
15062
|
+
{
|
|
15063
|
+
id: "model-router-zcode-install-dir",
|
|
15064
|
+
label: "ZCode \u684C\u9762\u76EE\u5F55\u4E0E TUI",
|
|
15065
|
+
hint: "Windows \u5DF2\u5B89\u88C5 ZCode \u684C\u9762\u7248\u5373\u53EF\u4F7F\u7528\u5185\u7F6E TUI\u3002\u586B\u5199\u5176\u72EC\u7ACB\u76EE\u5F55\uFF08\u4F8B\u5982 D:/Program Files/ZCode\uFF09\uFF0C\u7559\u7A7A\u81EA\u52A8\u68C0\u6D4B\u3002\u4FDD\u5B58\u540E\u4F53\u68C0\u4E0E\u5B98\u65B9\u5DE5\u5177\u7EC8\u7AEF\u5171\u7528\u6B64\u5165\u53E3\uFF1B\u5185\u7F6E CLI \u968F\u684C\u9762\u7248\u66F4\u65B0\uFF0C\u767B\u5F55\u4E0E\u6A21\u578B\u5728 TUI \u4E2D\u914D\u7F6E\u3002",
|
|
15066
|
+
disabled,
|
|
15067
|
+
...state.zcodeInstallDir,
|
|
15068
|
+
overriddenLabel: FIELD_COPY.overridden,
|
|
15069
|
+
resetLabel: FIELD_COPY.reset,
|
|
15070
|
+
invalidLabel: "\u8BF7\u8F93\u5165 Windows \u672C\u5730\u7EDD\u5BF9\u684C\u9762\u76EE\u5F55\uFF0C\u6216\u7559\u7A7A\u81EA\u52A8\u68C0\u6D4B\u3002",
|
|
15071
|
+
onEdit: (value) => {
|
|
15072
|
+
props.edit("zcodeInstallDir", value);
|
|
15073
|
+
},
|
|
15074
|
+
onReset: () => {
|
|
15075
|
+
props.resetField("zcodeInstallDir");
|
|
15076
|
+
}
|
|
15077
|
+
}
|
|
14911
15078
|
), /* @__PURE__ */ import_react6.default.createElement(
|
|
14912
15079
|
import_dsh_client_ui_primitives.SettingsValueField,
|
|
14913
15080
|
{
|