dsh-mcp 1.6.0 → 1.7.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/CHANGELOG.en.md CHANGED
@@ -7,6 +7,17 @@ All notable changes to this project are documented in this file.
7
7
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
8
8
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
9
9
 
10
+ ## [1.7.0] - 2026-08-21
11
+
12
+ ### Added
13
+
14
+ - **JSON config editor switched to key-value format**: server configs are shown/edited as a JSON object keyed by server name (`{ "server": { "type": "streamable_http", "url": ..., "headers": {...}, "disabled": false } }`) instead of the previous array; `type` is `streamable_http` or `stdio`, `disabled: true` disables the server
15
+
16
+ ### Fixed
17
+
18
+ - **MCP image admission diagnostics no longer misreport failures**: distinguish image count, batch/per-image byte, MIME, Base64, raster format, decoded-pixel, and maximum-dimension limits; unknown admission errors use a fixed diagnostic so valid-but-oversized images are not reported as invalid image data and attachment storage internals are not leaked (PR #5, thanks @coding-chong)
19
+ - The publish workflow now runs `npm test` (image-projection regression) before syntax checks and publishing
20
+
10
21
  ## [1.6.0] - 2026-08-17
11
22
 
12
23
  ### Added
package/CHANGELOG.md CHANGED
@@ -7,6 +7,17 @@
7
7
  格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),
8
8
  版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
9
9
 
10
+ ## [1.7.0] - 2026-08-21
11
+
12
+ ### 新增
13
+
14
+ - **JSON 配置编辑器改为 key-value 格式**:服务器配置以「服务器名 → 配置对象」的 JSON 对象展示/编辑(`{ "服务器名": { "type": "streamable_http", "url": ..., "headers": {...}, "disabled": false } }`),替代原数组格式;`type` 取值 `streamable_http`/`stdio`,`disabled: true` 表示停用
15
+
16
+ ### 修复
17
+
18
+ - **MCP 图片 admission 诊断不再误报**:区分图片数量、批量/单图字节数、MIME 类型、Base64、图片格式、解码像素数和最大边长限制;未知 admission 错误使用固定诊断,避免把有效但超尺寸的图片误报为无效图片数据,也不泄露 attachment 存储内部错误(PR #5,感谢 @coding-chong)
19
+ - 发布流水线增加 `npm test`(图片投影回归测试)后再校验语法并发布
20
+
10
21
  ## [1.6.0] - 2026-08-17
11
22
 
12
23
  ### 新增
package/README.en.md CHANGED
@@ -153,7 +153,7 @@ Check in order:
153
153
  the `web` profile (`dsh plugin --profile web add dsh-mcp` +
154
154
  `$DSH_HOME/profiles/web/cordis.patch.yml`); other profiles have their own settings pages.
155
155
  5. **Is it the latest version?** npm metadata caching can pin an old version; force the version
156
- with `dsh plugin --profile web add dsh-mcp@latest` (or `@1.6.0`).
156
+ with `dsh plugin --profile web add dsh-mcp@latest` (or `@1.7.0`).
157
157
 
158
158
  **Q2: "MCP" is visible but the server list is empty or errors?**
159
159
 
package/README.md CHANGED
@@ -136,7 +136,7 @@ dsh plugin --profile web add link:<本仓库绝对路径>
136
136
  (`dsh plugin --profile web add dsh-mcp` + `$DSH_HOME/profiles/web/cordis.patch.yml`);
137
137
  装到其他 profile 则在其他 profile 的设置页查看。
138
138
  5. **是否为最新版本**:npm 元数据缓存可能导致装到旧版,可强制指定版本
139
- `dsh plugin --profile web add dsh-mcp@latest`(或 `@1.6.0`)。
139
+ `dsh plugin --profile web add dsh-mcp@latest`(或 `@1.7.0`)。
140
140
 
141
141
  **Q2:设置页能看到「MCP」,但服务器列表为空/报错?**
142
142
 
package/lib/client.js CHANGED
@@ -27,7 +27,7 @@ __export(index_exports, {
27
27
  });
28
28
  module.exports = __toCommonJS(index_exports);
29
29
 
30
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
30
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/classic/external.js
31
31
  var external_exports = {};
32
32
  __export(external_exports, {
33
33
  $brand: () => $brand,
@@ -270,7 +270,7 @@ __export(external_exports, {
270
270
  xor: () => xor
271
271
  });
272
272
 
273
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/index.js
273
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/core/index.js
274
274
  var core_exports2 = {};
275
275
  __export(core_exports2, {
276
276
  $ZodAny: () => $ZodAny,
@@ -549,7 +549,7 @@ __export(core_exports2, {
549
549
  version: () => version
550
550
  });
551
551
 
552
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/core.js
552
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/core/core.js
553
553
  var _a;
554
554
  var NEVER = /* @__PURE__ */ Object.freeze({
555
555
  status: "aborted"
@@ -626,7 +626,7 @@ function config(newConfig) {
626
626
  return globalConfig;
627
627
  }
628
628
 
629
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/util.js
629
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/core/util.js
630
630
  var util_exports = {};
631
631
  __export(util_exports, {
632
632
  BIGINT_FORMAT_RANGES: () => BIGINT_FORMAT_RANGES,
@@ -1322,7 +1322,7 @@ var Class = class {
1322
1322
  }
1323
1323
  };
1324
1324
 
1325
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/errors.js
1325
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/core/errors.js
1326
1326
  var initializer = (inst, def) => {
1327
1327
  inst.name = "$ZodError";
1328
1328
  Object.defineProperty(inst, "_zod", {
@@ -1461,7 +1461,7 @@ function prettifyError(error51) {
1461
1461
  return lines.join("\n");
1462
1462
  }
1463
1463
 
1464
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/parse.js
1464
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/core/parse.js
1465
1465
  var _parse = (_Err) => (schema, value, _ctx, _params) => {
1466
1466
  const ctx = _ctx ? { ..._ctx, async: false } : { async: false };
1467
1467
  const result = schema._zod.run({ value, issues: [] }, ctx);
@@ -1549,7 +1549,7 @@ var _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => {
1549
1549
  };
1550
1550
  var safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync($ZodRealError);
1551
1551
 
1552
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/regexes.js
1552
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/core/regexes.js
1553
1553
  var regexes_exports = {};
1554
1554
  __export(regexes_exports, {
1555
1555
  base64: () => base64,
@@ -1708,7 +1708,7 @@ var sha512_hex = /^[0-9a-fA-F]{128}$/;
1708
1708
  var sha512_base64 = /* @__PURE__ */ fixedBase64(86, "==");
1709
1709
  var sha512_base64url = /* @__PURE__ */ fixedBase64url(86);
1710
1710
 
1711
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/checks.js
1711
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/core/checks.js
1712
1712
  var $ZodCheck = /* @__PURE__ */ $constructor("$ZodCheck", (inst, def) => {
1713
1713
  var _a3;
1714
1714
  inst._zod ?? (inst._zod = {});
@@ -2256,7 +2256,7 @@ var $ZodCheckOverwrite = /* @__PURE__ */ $constructor("$ZodCheckOverwrite", (ins
2256
2256
  };
2257
2257
  });
2258
2258
 
2259
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/doc.js
2259
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/core/doc.js
2260
2260
  var Doc = class {
2261
2261
  constructor(args = []) {
2262
2262
  this.content = [];
@@ -2292,14 +2292,14 @@ var Doc = class {
2292
2292
  }
2293
2293
  };
2294
2294
 
2295
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/versions.js
2295
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/core/versions.js
2296
2296
  var version = {
2297
2297
  major: 4,
2298
2298
  minor: 4,
2299
2299
  patch: 3
2300
2300
  };
2301
2301
 
2302
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/schemas.js
2302
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/core/schemas.js
2303
2303
  var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
2304
2304
  var _a3;
2305
2305
  inst ?? (inst = {});
@@ -4392,7 +4392,7 @@ function handleRefineResult(result, payload, input, inst) {
4392
4392
  }
4393
4393
  }
4394
4394
 
4395
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/index.js
4395
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/index.js
4396
4396
  var locales_exports = {};
4397
4397
  __export(locales_exports, {
4398
4398
  ar: () => ar_default,
@@ -4449,7 +4449,7 @@ __export(locales_exports, {
4449
4449
  zhTW: () => zh_TW_default
4450
4450
  });
4451
4451
 
4452
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ar.js
4452
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/ar.js
4453
4453
  var error = () => {
4454
4454
  const Sizable = {
4455
4455
  string: { unit: "\u062D\u0631\u0641", verb: "\u0623\u0646 \u064A\u062D\u0648\u064A" },
@@ -4556,7 +4556,7 @@ function ar_default() {
4556
4556
  };
4557
4557
  }
4558
4558
 
4559
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/az.js
4559
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/az.js
4560
4560
  var error2 = () => {
4561
4561
  const Sizable = {
4562
4562
  string: { unit: "simvol", verb: "olmal\u0131d\u0131r" },
@@ -4662,7 +4662,7 @@ function az_default() {
4662
4662
  };
4663
4663
  }
4664
4664
 
4665
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/be.js
4665
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/be.js
4666
4666
  function getBelarusianPlural(count, one, few, many) {
4667
4667
  const absCount = Math.abs(count);
4668
4668
  const lastDigit = absCount % 10;
@@ -4819,7 +4819,7 @@ function be_default() {
4819
4819
  };
4820
4820
  }
4821
4821
 
4822
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/bg.js
4822
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/bg.js
4823
4823
  var error4 = () => {
4824
4824
  const Sizable = {
4825
4825
  string: { unit: "\u0441\u0438\u043C\u0432\u043E\u043B\u0430", verb: "\u0434\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430" },
@@ -4940,7 +4940,7 @@ function bg_default() {
4940
4940
  };
4941
4941
  }
4942
4942
 
4943
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ca.js
4943
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/ca.js
4944
4944
  var error5 = () => {
4945
4945
  const Sizable = {
4946
4946
  string: { unit: "car\xE0cters", verb: "contenir" },
@@ -5049,7 +5049,7 @@ function ca_default() {
5049
5049
  };
5050
5050
  }
5051
5051
 
5052
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/cs.js
5052
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/cs.js
5053
5053
  var error6 = () => {
5054
5054
  const Sizable = {
5055
5055
  string: { unit: "znak\u016F", verb: "m\xEDt" },
@@ -5161,7 +5161,7 @@ function cs_default() {
5161
5161
  };
5162
5162
  }
5163
5163
 
5164
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/da.js
5164
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/da.js
5165
5165
  var error7 = () => {
5166
5166
  const Sizable = {
5167
5167
  string: { unit: "tegn", verb: "havde" },
@@ -5277,7 +5277,7 @@ function da_default() {
5277
5277
  };
5278
5278
  }
5279
5279
 
5280
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/de.js
5280
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/de.js
5281
5281
  var error8 = () => {
5282
5282
  const Sizable = {
5283
5283
  string: { unit: "Zeichen", verb: "zu haben" },
@@ -5386,7 +5386,7 @@ function de_default() {
5386
5386
  };
5387
5387
  }
5388
5388
 
5389
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/el.js
5389
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/el.js
5390
5390
  var error9 = () => {
5391
5391
  const Sizable = {
5392
5392
  string: { unit: "\u03C7\u03B1\u03C1\u03B1\u03BA\u03C4\u03AE\u03C1\u03B5\u03C2", verb: "\u03BD\u03B1 \u03AD\u03C7\u03B5\u03B9" },
@@ -5496,7 +5496,7 @@ function el_default() {
5496
5496
  };
5497
5497
  }
5498
5498
 
5499
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/en.js
5499
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/en.js
5500
5500
  var error10 = () => {
5501
5501
  const Sizable = {
5502
5502
  string: { unit: "characters", verb: "to have" },
@@ -5609,7 +5609,7 @@ function en_default() {
5609
5609
  };
5610
5610
  }
5611
5611
 
5612
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/eo.js
5612
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/eo.js
5613
5613
  var error11 = () => {
5614
5614
  const Sizable = {
5615
5615
  string: { unit: "karaktrojn", verb: "havi" },
@@ -5719,7 +5719,7 @@ function eo_default() {
5719
5719
  };
5720
5720
  }
5721
5721
 
5722
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/es.js
5722
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/es.js
5723
5723
  var error12 = () => {
5724
5724
  const Sizable = {
5725
5725
  string: { unit: "caracteres", verb: "tener" },
@@ -5852,7 +5852,7 @@ function es_default() {
5852
5852
  };
5853
5853
  }
5854
5854
 
5855
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/fa.js
5855
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/fa.js
5856
5856
  var error13 = () => {
5857
5857
  const Sizable = {
5858
5858
  string: { unit: "\u06A9\u0627\u0631\u0627\u06A9\u062A\u0631", verb: "\u062F\u0627\u0634\u062A\u0647 \u0628\u0627\u0634\u062F" },
@@ -5967,7 +5967,7 @@ function fa_default() {
5967
5967
  };
5968
5968
  }
5969
5969
 
5970
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/fi.js
5970
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/fi.js
5971
5971
  var error14 = () => {
5972
5972
  const Sizable = {
5973
5973
  string: { unit: "merkki\xE4", subject: "merkkijonon" },
@@ -6080,7 +6080,7 @@ function fi_default() {
6080
6080
  };
6081
6081
  }
6082
6082
 
6083
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/fr.js
6083
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/fr.js
6084
6084
  var error15 = () => {
6085
6085
  const Sizable = {
6086
6086
  string: { unit: "caract\xE8res", verb: "avoir" },
@@ -6206,7 +6206,7 @@ function fr_default() {
6206
6206
  };
6207
6207
  }
6208
6208
 
6209
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/fr-CA.js
6209
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/fr-CA.js
6210
6210
  var error16 = () => {
6211
6211
  const Sizable = {
6212
6212
  string: { unit: "caract\xE8res", verb: "avoir" },
@@ -6314,7 +6314,7 @@ function fr_CA_default() {
6314
6314
  };
6315
6315
  }
6316
6316
 
6317
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/he.js
6317
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/he.js
6318
6318
  var error17 = () => {
6319
6319
  const TypeNames = {
6320
6320
  string: { label: "\u05DE\u05D7\u05E8\u05D5\u05D6\u05EA", gender: "f" },
@@ -6509,7 +6509,7 @@ function he_default() {
6509
6509
  };
6510
6510
  }
6511
6511
 
6512
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/hr.js
6512
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/hr.js
6513
6513
  var error18 = () => {
6514
6514
  const Sizable = {
6515
6515
  string: { unit: "znakova", verb: "imati" },
@@ -6632,7 +6632,7 @@ function hr_default() {
6632
6632
  };
6633
6633
  }
6634
6634
 
6635
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/hu.js
6635
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/hu.js
6636
6636
  var error19 = () => {
6637
6637
  const Sizable = {
6638
6638
  string: { unit: "karakter", verb: "legyen" },
@@ -6741,7 +6741,7 @@ function hu_default() {
6741
6741
  };
6742
6742
  }
6743
6743
 
6744
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/hy.js
6744
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/hy.js
6745
6745
  function getArmenianPlural(count, one, many) {
6746
6746
  return Math.abs(count) === 1 ? one : many;
6747
6747
  }
@@ -6889,7 +6889,7 @@ function hy_default() {
6889
6889
  };
6890
6890
  }
6891
6891
 
6892
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/id.js
6892
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/id.js
6893
6893
  var error21 = () => {
6894
6894
  const Sizable = {
6895
6895
  string: { unit: "karakter", verb: "memiliki" },
@@ -6996,7 +6996,7 @@ function id_default() {
6996
6996
  };
6997
6997
  }
6998
6998
 
6999
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/is.js
6999
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/is.js
7000
7000
  var error22 = () => {
7001
7001
  const Sizable = {
7002
7002
  string: { unit: "stafi", verb: "a\xF0 hafa" },
@@ -7106,7 +7106,7 @@ function is_default() {
7106
7106
  };
7107
7107
  }
7108
7108
 
7109
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/it.js
7109
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/it.js
7110
7110
  var error23 = () => {
7111
7111
  const Sizable = {
7112
7112
  string: { unit: "caratteri", verb: "avere" },
@@ -7215,7 +7215,7 @@ function it_default() {
7215
7215
  };
7216
7216
  }
7217
7217
 
7218
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ja.js
7218
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/ja.js
7219
7219
  var error24 = () => {
7220
7220
  const Sizable = {
7221
7221
  string: { unit: "\u6587\u5B57", verb: "\u3067\u3042\u308B" },
@@ -7323,7 +7323,7 @@ function ja_default() {
7323
7323
  };
7324
7324
  }
7325
7325
 
7326
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ka.js
7326
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/ka.js
7327
7327
  var error25 = () => {
7328
7328
  const Sizable = {
7329
7329
  string: { unit: "\u10E1\u10D8\u10DB\u10D1\u10DD\u10DA\u10DD", verb: "\u10E3\u10DC\u10D3\u10D0 \u10E8\u10D4\u10D8\u10EA\u10D0\u10D5\u10D3\u10D4\u10E1" },
@@ -7436,7 +7436,7 @@ function ka_default() {
7436
7436
  };
7437
7437
  }
7438
7438
 
7439
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/km.js
7439
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/km.js
7440
7440
  var error26 = () => {
7441
7441
  const Sizable = {
7442
7442
  string: { unit: "\u178F\u17BD\u17A2\u1780\u17D2\u179F\u179A", verb: "\u1782\u17BD\u179A\u1798\u17B6\u1793" },
@@ -7547,12 +7547,12 @@ function km_default() {
7547
7547
  };
7548
7548
  }
7549
7549
 
7550
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/kh.js
7550
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/kh.js
7551
7551
  function kh_default() {
7552
7552
  return km_default();
7553
7553
  }
7554
7554
 
7555
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ko.js
7555
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/ko.js
7556
7556
  var error27 = () => {
7557
7557
  const Sizable = {
7558
7558
  string: { unit: "\uBB38\uC790", verb: "to have" },
@@ -7664,7 +7664,7 @@ function ko_default() {
7664
7664
  };
7665
7665
  }
7666
7666
 
7667
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/lt.js
7667
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/lt.js
7668
7668
  var capitalizeFirstCharacter = (text) => {
7669
7669
  return text.charAt(0).toUpperCase() + text.slice(1);
7670
7670
  };
@@ -7868,7 +7868,7 @@ function lt_default() {
7868
7868
  };
7869
7869
  }
7870
7870
 
7871
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/mk.js
7871
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/mk.js
7872
7872
  var error29 = () => {
7873
7873
  const Sizable = {
7874
7874
  string: { unit: "\u0437\u043D\u0430\u0446\u0438", verb: "\u0434\u0430 \u0438\u043C\u0430\u0430\u0442" },
@@ -7978,7 +7978,7 @@ function mk_default() {
7978
7978
  };
7979
7979
  }
7980
7980
 
7981
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ms.js
7981
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/ms.js
7982
7982
  var error30 = () => {
7983
7983
  const Sizable = {
7984
7984
  string: { unit: "aksara", verb: "mempunyai" },
@@ -8086,7 +8086,7 @@ function ms_default() {
8086
8086
  };
8087
8087
  }
8088
8088
 
8089
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/nl.js
8089
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/nl.js
8090
8090
  var error31 = () => {
8091
8091
  const Sizable = {
8092
8092
  string: { unit: "tekens", verb: "heeft" },
@@ -8197,7 +8197,7 @@ function nl_default() {
8197
8197
  };
8198
8198
  }
8199
8199
 
8200
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/no.js
8200
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/no.js
8201
8201
  var error32 = () => {
8202
8202
  const Sizable = {
8203
8203
  string: { unit: "tegn", verb: "\xE5 ha" },
@@ -8306,7 +8306,7 @@ function no_default() {
8306
8306
  };
8307
8307
  }
8308
8308
 
8309
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ota.js
8309
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/ota.js
8310
8310
  var error33 = () => {
8311
8311
  const Sizable = {
8312
8312
  string: { unit: "harf", verb: "olmal\u0131d\u0131r" },
@@ -8416,7 +8416,7 @@ function ota_default() {
8416
8416
  };
8417
8417
  }
8418
8418
 
8419
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ps.js
8419
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/ps.js
8420
8420
  var error34 = () => {
8421
8421
  const Sizable = {
8422
8422
  string: { unit: "\u062A\u0648\u06A9\u064A", verb: "\u0648\u0644\u0631\u064A" },
@@ -8531,7 +8531,7 @@ function ps_default() {
8531
8531
  };
8532
8532
  }
8533
8533
 
8534
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/pl.js
8534
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/pl.js
8535
8535
  var error35 = () => {
8536
8536
  const Sizable = {
8537
8537
  string: { unit: "znak\xF3w", verb: "mie\u0107" },
@@ -8641,7 +8641,7 @@ function pl_default() {
8641
8641
  };
8642
8642
  }
8643
8643
 
8644
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/pt.js
8644
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/pt.js
8645
8645
  var error36 = () => {
8646
8646
  const Sizable = {
8647
8647
  string: { unit: "caracteres", verb: "ter" },
@@ -8750,7 +8750,7 @@ function pt_default() {
8750
8750
  };
8751
8751
  }
8752
8752
 
8753
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ro.js
8753
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/ro.js
8754
8754
  var error37 = () => {
8755
8755
  const Sizable = {
8756
8756
  string: { unit: "caractere", verb: "s\u0103 aib\u0103" },
@@ -8870,7 +8870,7 @@ function ro_default() {
8870
8870
  };
8871
8871
  }
8872
8872
 
8873
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ru.js
8873
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/ru.js
8874
8874
  function getRussianPlural(count, one, few, many) {
8875
8875
  const absCount = Math.abs(count);
8876
8876
  const lastDigit = absCount % 10;
@@ -9027,7 +9027,7 @@ function ru_default() {
9027
9027
  };
9028
9028
  }
9029
9029
 
9030
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/sl.js
9030
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/sl.js
9031
9031
  var error39 = () => {
9032
9032
  const Sizable = {
9033
9033
  string: { unit: "znakov", verb: "imeti" },
@@ -9137,7 +9137,7 @@ function sl_default() {
9137
9137
  };
9138
9138
  }
9139
9139
 
9140
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/sv.js
9140
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/sv.js
9141
9141
  var error40 = () => {
9142
9142
  const Sizable = {
9143
9143
  string: { unit: "tecken", verb: "att ha" },
@@ -9248,7 +9248,7 @@ function sv_default() {
9248
9248
  };
9249
9249
  }
9250
9250
 
9251
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ta.js
9251
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/ta.js
9252
9252
  var error41 = () => {
9253
9253
  const Sizable = {
9254
9254
  string: { unit: "\u0B8E\u0BB4\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1\u0B95\u0BCD\u0B95\u0BB3\u0BCD", verb: "\u0B95\u0BCA\u0BA3\u0BCD\u0B9F\u0BBF\u0BB0\u0BC1\u0B95\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD" },
@@ -9359,7 +9359,7 @@ function ta_default() {
9359
9359
  };
9360
9360
  }
9361
9361
 
9362
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/th.js
9362
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/th.js
9363
9363
  var error42 = () => {
9364
9364
  const Sizable = {
9365
9365
  string: { unit: "\u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23", verb: "\u0E04\u0E27\u0E23\u0E21\u0E35" },
@@ -9470,7 +9470,7 @@ function th_default() {
9470
9470
  };
9471
9471
  }
9472
9472
 
9473
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/tr.js
9473
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/tr.js
9474
9474
  var error43 = () => {
9475
9475
  const Sizable = {
9476
9476
  string: { unit: "karakter", verb: "olmal\u0131" },
@@ -9576,7 +9576,7 @@ function tr_default() {
9576
9576
  };
9577
9577
  }
9578
9578
 
9579
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/uk.js
9579
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/uk.js
9580
9580
  var error44 = () => {
9581
9581
  const Sizable = {
9582
9582
  string: { unit: "\u0441\u0438\u043C\u0432\u043E\u043B\u0456\u0432", verb: "\u043C\u0430\u0442\u0438\u043C\u0435" },
@@ -9685,12 +9685,12 @@ function uk_default() {
9685
9685
  };
9686
9686
  }
9687
9687
 
9688
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ua.js
9688
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/ua.js
9689
9689
  function ua_default() {
9690
9690
  return uk_default();
9691
9691
  }
9692
9692
 
9693
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/ur.js
9693
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/ur.js
9694
9694
  var error45 = () => {
9695
9695
  const Sizable = {
9696
9696
  string: { unit: "\u062D\u0631\u0648\u0641", verb: "\u06C1\u0648\u0646\u0627" },
@@ -9801,7 +9801,7 @@ function ur_default() {
9801
9801
  };
9802
9802
  }
9803
9803
 
9804
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/uz.js
9804
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/uz.js
9805
9805
  var error46 = () => {
9806
9806
  const Sizable = {
9807
9807
  string: { unit: "belgi", verb: "bo\u2018lishi kerak" },
@@ -9912,7 +9912,7 @@ function uz_default() {
9912
9912
  };
9913
9913
  }
9914
9914
 
9915
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/vi.js
9915
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/vi.js
9916
9916
  var error47 = () => {
9917
9917
  const Sizable = {
9918
9918
  string: { unit: "k\xFD t\u1EF1", verb: "c\xF3" },
@@ -10021,7 +10021,7 @@ function vi_default() {
10021
10021
  };
10022
10022
  }
10023
10023
 
10024
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/zh-CN.js
10024
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/zh-CN.js
10025
10025
  var error48 = () => {
10026
10026
  const Sizable = {
10027
10027
  string: { unit: "\u5B57\u7B26", verb: "\u5305\u542B" },
@@ -10131,7 +10131,7 @@ function zh_CN_default() {
10131
10131
  };
10132
10132
  }
10133
10133
 
10134
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/zh-TW.js
10134
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/zh-TW.js
10135
10135
  var error49 = () => {
10136
10136
  const Sizable = {
10137
10137
  string: { unit: "\u5B57\u5143", verb: "\u64C1\u6709" },
@@ -10239,7 +10239,7 @@ function zh_TW_default() {
10239
10239
  };
10240
10240
  }
10241
10241
 
10242
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/locales/yo.js
10242
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/locales/yo.js
10243
10243
  var error50 = () => {
10244
10244
  const Sizable = {
10245
10245
  string: { unit: "\xE0mi", verb: "n\xED" },
@@ -10347,7 +10347,7 @@ function yo_default() {
10347
10347
  };
10348
10348
  }
10349
10349
 
10350
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/registries.js
10350
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/core/registries.js
10351
10351
  var _a2;
10352
10352
  var $output = /* @__PURE__ */ Symbol("ZodOutput");
10353
10353
  var $input = /* @__PURE__ */ Symbol("ZodInput");
@@ -10397,7 +10397,7 @@ function registry() {
10397
10397
  (_a2 = globalThis).__zod_globalRegistry ?? (_a2.__zod_globalRegistry = registry());
10398
10398
  var globalRegistry = globalThis.__zod_globalRegistry;
10399
10399
 
10400
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/api.js
10400
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/core/api.js
10401
10401
  // @__NO_SIDE_EFFECTS__
10402
10402
  function _string(Class2, params) {
10403
10403
  return new Class2({
@@ -11436,7 +11436,7 @@ function _stringFormat(Class2, format, fnOrRegex, _params = {}) {
11436
11436
  return inst;
11437
11437
  }
11438
11438
 
11439
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/to-json-schema.js
11439
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/core/to-json-schema.js
11440
11440
  function initializeContext(params) {
11441
11441
  let target = params?.target ?? "draft-2020-12";
11442
11442
  if (target === "draft-4")
@@ -11795,7 +11795,7 @@ var createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) =
11795
11795
  return finalize(ctx, schema);
11796
11796
  };
11797
11797
 
11798
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/json-schema-processors.js
11798
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/core/json-schema-processors.js
11799
11799
  var formatMap = {
11800
11800
  guid: "uuid",
11801
11801
  url: "uri",
@@ -12339,7 +12339,7 @@ function toJSONSchema(input, params) {
12339
12339
  return finalize(ctx, input);
12340
12340
  }
12341
12341
 
12342
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/json-schema-generator.js
12342
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/core/json-schema-generator.js
12343
12343
  var JSONSchemaGenerator = class {
12344
12344
  /** @deprecated Access via ctx instead */
12345
12345
  get metadataRegistry() {
@@ -12414,10 +12414,10 @@ var JSONSchemaGenerator = class {
12414
12414
  }
12415
12415
  };
12416
12416
 
12417
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/json-schema.js
12417
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/core/json-schema.js
12418
12418
  var json_schema_exports = {};
12419
12419
 
12420
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/schemas.js
12420
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/classic/schemas.js
12421
12421
  var schemas_exports2 = {};
12422
12422
  __export(schemas_exports2, {
12423
12423
  ZodAny: () => ZodAny,
@@ -12588,7 +12588,7 @@ __export(schemas_exports2, {
12588
12588
  xor: () => xor
12589
12589
  });
12590
12590
 
12591
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/checks.js
12591
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/classic/checks.js
12592
12592
  var checks_exports2 = {};
12593
12593
  __export(checks_exports2, {
12594
12594
  endsWith: () => _endsWith,
@@ -12622,7 +12622,7 @@ __export(checks_exports2, {
12622
12622
  uppercase: () => _uppercase
12623
12623
  });
12624
12624
 
12625
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/iso.js
12625
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/classic/iso.js
12626
12626
  var iso_exports = {};
12627
12627
  __export(iso_exports, {
12628
12628
  ZodISODate: () => ZodISODate,
@@ -12663,7 +12663,7 @@ function duration2(params) {
12663
12663
  return _isoDuration(ZodISODuration, params);
12664
12664
  }
12665
12665
 
12666
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/errors.js
12666
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/classic/errors.js
12667
12667
  var initializer2 = (inst, issues) => {
12668
12668
  $ZodError.init(inst, issues);
12669
12669
  inst.name = "ZodError";
@@ -12703,7 +12703,7 @@ var ZodRealError = /* @__PURE__ */ $constructor("ZodError", initializer2, {
12703
12703
  Parent: Error
12704
12704
  });
12705
12705
 
12706
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/parse.js
12706
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/classic/parse.js
12707
12707
  var parse2 = /* @__PURE__ */ _parse(ZodRealError);
12708
12708
  var parseAsync2 = /* @__PURE__ */ _parseAsync(ZodRealError);
12709
12709
  var safeParse2 = /* @__PURE__ */ _safeParse(ZodRealError);
@@ -12717,7 +12717,7 @@ var safeDecode2 = /* @__PURE__ */ _safeDecode(ZodRealError);
12717
12717
  var safeEncodeAsync2 = /* @__PURE__ */ _safeEncodeAsync(ZodRealError);
12718
12718
  var safeDecodeAsync2 = /* @__PURE__ */ _safeDecodeAsync(ZodRealError);
12719
12719
 
12720
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/schemas.js
12720
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/classic/schemas.js
12721
12721
  var _installedGroups = /* @__PURE__ */ new WeakMap();
12722
12722
  function _installLazyMethods(inst, group, methods) {
12723
12723
  const proto = Object.getPrototypeOf(inst);
@@ -14007,7 +14007,7 @@ function preprocess(fn, schema) {
14007
14007
  });
14008
14008
  }
14009
14009
 
14010
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/compat.js
14010
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/classic/compat.js
14011
14011
  var ZodIssueCode = {
14012
14012
  invalid_type: "invalid_type",
14013
14013
  too_big: "too_big",
@@ -14033,7 +14033,7 @@ var ZodFirstPartyTypeKind;
14033
14033
  /* @__PURE__ */ (function(ZodFirstPartyTypeKind2) {
14034
14034
  })(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
14035
14035
 
14036
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/from-json-schema.js
14036
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/classic/from-json-schema.js
14037
14037
  var z = {
14038
14038
  ...schemas_exports2,
14039
14039
  ...checks_exports2,
@@ -14513,7 +14513,7 @@ function fromJSONSchema(schema, params) {
14513
14513
  return convertSchema(normalized, ctx);
14514
14514
  }
14515
14515
 
14516
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/coerce.js
14516
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/classic/coerce.js
14517
14517
  var coerce_exports = {};
14518
14518
  __export(coerce_exports, {
14519
14519
  bigint: () => bigint3,
@@ -14538,7 +14538,7 @@ function date4(params) {
14538
14538
  return _coercedDate(ZodDate, params);
14539
14539
  }
14540
14540
 
14541
- // ../../deepseek-harness/node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
14541
+ // ../../../../.nvm/versions/node/v24.19.0/lib/node_modules/@deepseek-ai/dsh/node_modules/zod/v4/classic/external.js
14542
14542
  config(en_default());
14543
14543
 
14544
14544
  // src/client/remote-contribution.js
@@ -15295,11 +15295,11 @@ var ServersJsonEditor_default = { "panel": "panel", "editor": "editor", "hint":
15295
15295
  // src/client/ServersJsonEditor.tsx
15296
15296
  var import_jsx_runtime2 = require("react/jsx-runtime");
15297
15297
  function serversToJsonText(servers) {
15298
- const document2 = servers.map((server) => {
15298
+ const document2 = {};
15299
+ for (const server of servers) {
15299
15300
  const entry = {
15300
- serverName: server.serverName,
15301
- transport: server.transport,
15302
- enabled: server.enabled
15301
+ type: server.transport === "stdio" ? "stdio" : "streamable_http",
15302
+ disabled: !server.enabled
15303
15303
  };
15304
15304
  if (server.transport === "stdio") {
15305
15305
  entry.command = server.command;
@@ -15314,8 +15314,8 @@ function serversToJsonText(servers) {
15314
15314
  entry.toolCallTimeoutMs = server.toolCallTimeoutMs;
15315
15315
  entry.failOnStartupError = server.failOnStartupError;
15316
15316
  entry.env = server.env.map((row) => row.secret ? { name: row.name, secret: true, configured: row.configured } : { name: row.name, secret: false, ...row.value !== void 0 && row.value.length > 0 ? { value: row.value } : {} });
15317
- return entry;
15318
- });
15317
+ document2[server.serverName] = entry;
15318
+ }
15319
15319
  return `${JSON.stringify(document2, null, 2)}
15320
15320
  `;
15321
15321
  }
@@ -15326,39 +15326,37 @@ function parseServersJson(text) {
15326
15326
  } catch (error51) {
15327
15327
  return { ok: false, error: error51 instanceof Error ? error51.message : String(error51) };
15328
15328
  }
15329
- if (!Array.isArray(value)) {
15330
- return { ok: false, error: "JSON \u9876\u5C42\u5FC5\u987B\u662F\u670D\u52A1\u5668\u914D\u7F6E\u6570\u7EC4\uFF1A[ { serverName, transport, ... }, ... ]" };
15329
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
15330
+ return { ok: false, error: 'JSON \u9876\u5C42\u5FC5\u987B\u662F\u5BF9\u8C61\uFF1A{ "\u670D\u52A1\u5668\u540D": { "type": "streamable_http", ... } }' };
15331
15331
  }
15332
- if (value.length === 0) {
15332
+ const entries = Object.entries(value);
15333
+ if (entries.length === 0) {
15333
15334
  return { ok: false, error: "\u914D\u7F6E\u5217\u8868\u4E0D\u80FD\u4E3A\u7A7A" };
15334
15335
  }
15335
15336
  const servers = [];
15336
- const seen = /* @__PURE__ */ new Set();
15337
- for (const item of value) {
15338
- if (item === null || typeof item !== "object" || Array.isArray(item)) {
15339
- return { ok: false, error: "\u6BCF\u4E2A\u6761\u76EE\u5FC5\u987B\u662F\u5BF9\u8C61\uFF1A{ serverName, transport, ... }" };
15340
- }
15341
- const server = item;
15342
- const serverName = typeof server.serverName === "string" ? server.serverName.trim() : "";
15343
- if (serverName.length === 0) return { ok: false, error: "serverName \u4E0D\u80FD\u4E3A\u7A7A" };
15344
- if (seen.has(serverName)) return { ok: false, error: `serverName "${serverName}" \u91CD\u590D` };
15345
- seen.add(serverName);
15346
- const transport = server.transport;
15347
- if (transport !== "stdio" && transport !== "streamable-http") {
15348
- return { ok: false, error: `\u670D\u52A1\u5668 "${serverName}" \u7684 transport \u5FC5\u987B\u662F stdio \u6216 streamable-http` };
15349
- }
15350
- if (transport === "stdio" && (typeof server.command !== "string" || server.command.trim().length === 0)) {
15337
+ for (const [serverName, raw] of entries) {
15338
+ if (serverName.trim().length === 0) return { ok: false, error: "\u670D\u52A1\u5668\u540D\u4E0D\u80FD\u4E3A\u7A7A" };
15339
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
15340
+ return { ok: false, error: `\u670D\u52A1\u5668 "${serverName}" \u7684\u914D\u7F6E\u5FC5\u987B\u662F\u5BF9\u8C61` };
15341
+ }
15342
+ const cfg = raw;
15343
+ const type = cfg.type;
15344
+ const transport = type === "stdio" ? "stdio" : type === "streamable_http" ? "streamable-http" : void 0;
15345
+ if (transport === void 0) {
15346
+ return { ok: false, error: `\u670D\u52A1\u5668 "${serverName}" \u7684 type \u5FC5\u987B\u662F streamable_http \u6216 stdio` };
15347
+ }
15348
+ if (transport === "stdio" && (typeof cfg.command !== "string" || cfg.command.trim().length === 0)) {
15351
15349
  return { ok: false, error: `\u670D\u52A1\u5668 "${serverName}"\uFF08stdio\uFF09\u7F3A\u5C11 command` };
15352
15350
  }
15353
- if (transport === "streamable-http" && typeof server.url !== "string") {
15354
- return { ok: false, error: `\u670D\u52A1\u5668 "${serverName}"\uFF08streamable-http\uFF09\u7F3A\u5C11 url` };
15351
+ if (transport === "streamable-http" && typeof cfg.url !== "string") {
15352
+ return { ok: false, error: `\u670D\u52A1\u5668 "${serverName}"\uFF08streamable_http\uFF09\u7F3A\u5C11 url` };
15355
15353
  }
15356
- if (server.headers !== void 0) {
15357
- const headers = server.headers;
15354
+ if (cfg.headers !== void 0) {
15355
+ const headers = cfg.headers;
15358
15356
  const okHeaders = headers !== null && typeof headers === "object" && !Array.isArray(headers) || Array.isArray(headers) && headers.every((h) => h !== null && typeof h === "object" && typeof h.name === "string");
15359
15357
  if (!okHeaders) return { ok: false, error: `\u670D\u52A1\u5668 "${serverName}" \u7684 headers \u5FC5\u987B\u662F { "\u540D\u79F0": "\u503C" } \u5BF9\u8C61\u6216 { name, value } \u6570\u7EC4` };
15360
15358
  }
15361
- const envValue = server.env;
15359
+ const envValue = cfg.env;
15362
15360
  const env = Array.isArray(envValue) ? envValue : [];
15363
15361
  for (const row of env) {
15364
15362
  const r = row;
@@ -15372,6 +15370,18 @@ function parseServersJson(text) {
15372
15370
  return { ok: false, error: `\u670D\u52A1\u5668 "${serverName}" \u7684 env \u6761\u76EE "${r.name}" \u7684 value \u5FC5\u987B\u662F\u5B57\u7B26\u4E32` };
15373
15371
  }
15374
15372
  }
15373
+ const server = {
15374
+ serverName,
15375
+ transport,
15376
+ enabled: cfg.disabled !== true,
15377
+ command: typeof cfg.command === "string" ? cfg.command : "",
15378
+ args: Array.isArray(cfg.args) ? cfg.args : [],
15379
+ cwd: typeof cfg.cwd === "string" ? cfg.cwd : "",
15380
+ url: typeof cfg.url === "string" ? cfg.url : "",
15381
+ headers: cfg.headers,
15382
+ toolCallTimeoutMs: typeof cfg.toolCallTimeoutMs === "number" ? cfg.toolCallTimeoutMs : 6e4,
15383
+ failOnStartupError: cfg.failOnStartupError !== false
15384
+ };
15375
15385
  servers.push({ server, env });
15376
15386
  }
15377
15387
  return { ok: true, servers };
@@ -16132,7 +16142,7 @@ var zh = {
16132
16142
  toolsCollapse: "\u6536\u8D77\u5DE5\u5177",
16133
16143
  serversJson: "JSON \u7EF4\u62A4\u914D\u7F6E",
16134
16144
  serversJsonLabel: "\u670D\u52A1\u5668\u914D\u7F6E JSON",
16135
- serversJsonHint: "\u6574\u4E2A MCP \u670D\u52A1\u5668\u914D\u7F6E\u5217\u8868\uFF08\u6570\u7EC4\uFF09\uFF1A\u5E94\u7528\u540E\u5C06\u6309\u6B64\u5217\u8868\u66FF\u6362\u2014\u2014\u5DF2\u5217\u51FA\u7684\u670D\u52A1\u5668\u521B\u5EFA/\u66F4\u65B0\uFF0C\u672A\u5217\u51FA\u7684\u5C06\u88AB\u5220\u9664\uFF1Bsecret \u73AF\u5883\u53D8\u91CF\u503C\u4E0D\u4F1A\u5BFC\u51FA\uFF08configured \u6807\u8BB0\uFF09\uFF0C\u7559\u7A7A\u5219\u4FDD\u7559\u539F\u503C\u3002",
16145
+ serversJsonHint: "\u6574\u4E2A MCP \u670D\u52A1\u5668\u914D\u7F6E\uFF08key-value \u5BF9\u8C61\uFF0C\u670D\u52A1\u5668\u540D \u2192 \u914D\u7F6E\uFF09\uFF1A\u5E94\u7528\u540E\u5C06\u6309\u6B64\u66FF\u6362\u2014\u2014\u5DF2\u5217\u51FA\u7684\u670D\u52A1\u5668\u521B\u5EFA/\u66F4\u65B0\uFF0C\u672A\u5217\u51FA\u7684\u5C06\u88AB\u5220\u9664\uFF1Btype \u4E3A streamable_http \u6216 stdio\uFF0Cdisabled \u4E3A true \u8868\u793A\u505C\u7528\uFF1Bsecret \u73AF\u5883\u53D8\u91CF\u503C\u4E0D\u4F1A\u5BFC\u51FA\uFF08configured \u6807\u8BB0\uFF09\uFF0C\u7559\u7A7A\u5219\u4FDD\u7559\u539F\u503C\u3002",
16136
16146
  serversJsonReseed: "\u91CD\u65B0\u5BFC\u51FA",
16137
16147
  serversJsonApply: "\u5E94\u7528",
16138
16148
  serversJsonSaving: "\u5E94\u7528\u4E2D\u2026",
@@ -16230,7 +16240,7 @@ var en = {
16230
16240
  toolsCollapse: "Collapse tools",
16231
16241
  serversJson: "JSON config editor",
16232
16242
  serversJsonLabel: "Server-config JSON",
16233
- serversJsonHint: "The whole MCP server list (array): applying replaces the list \u2014 listed servers are created/updated, existing servers absent from the document are removed; secret env values are never exported (a configured flag marks them), a blank value keeps the stored one.",
16243
+ serversJsonHint: "The whole MCP server config as a key-value object (server name \u2192 config): applying replaces the list \u2014 listed servers are created/updated, servers absent from the document are removed; type is streamable_http or stdio, disabled: true disables the server; secret env values are never exported (a configured flag marks them), a blank value keeps the stored one.",
16234
16244
  serversJsonReseed: "Re-export",
16235
16245
  serversJsonApply: "Apply",
16236
16246
  serversJsonSaving: "Applying\u2026",
package/lib/mcp-client.js CHANGED
@@ -375,11 +375,15 @@ async function resolveImageAdmission(ctx, exec) {
375
375
  function admissionDiagnostic(error) {
376
376
  switch (error?.code) {
377
377
  case "TOO_MANY_IMAGES": return "image batch exceeds the active count limit";
378
- case "IMAGES_TOO_LARGE":
378
+ case "IMAGES_TOO_LARGE": return "image batch exceeds the active size limit";
379
379
  case "IMAGE_TOO_LARGE": return "image exceeds the active size limit";
380
- case "UNSUPPORTED_IMAGE_TYPE":
381
- case "IMAGE_TYPE_MISMATCH": return "image type is not accepted";
382
- default: return isImageAdmissionError(error) ? "invalid image data" : "image storage unavailable";
380
+ case "UNSUPPORTED_IMAGE_TYPE": return "image type is not accepted";
381
+ case "IMAGE_TYPE_MISMATCH": return "declared image type does not match image bytes";
382
+ case "INVALID_IMAGE_BASE64": return "invalid image Base64";
383
+ case "INVALID_IMAGE": return "malformed or unsupported image data";
384
+ case "IMAGE_TOO_MANY_PIXELS": return "image exceeds the decoded-pixel limit";
385
+ case "IMAGE_DIMENSION_TOO_LARGE": return "image exceeds the maximum side dimension";
386
+ default: return isImageAdmissionError(error) ? "image admission failed" : "image storage unavailable";
383
387
  }
384
388
  }
385
389
  async function prepareImageProjection(ctx, exec, content, toolName) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-mcp",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "MCP 管理界面 + tool search:可视化配置/启停/刷新 MCP 服务器与工具勾选,按需检索(tool search)热注入;工具列表稳定命中缓存、不撑爆上下文。DeepSeek Harness plugin: MCP management UI + tool search — stable tool list, cache-friendly, no context bloat.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -21,7 +21,8 @@
21
21
  "LICENSE"
22
22
  ],
23
23
  "scripts": {
24
- "build": "node scripts/build.mjs"
24
+ "build": "node scripts/build.mjs",
25
+ "test": "node --test test/mcp-image-projection.test.mjs"
25
26
  },
26
27
  "author": "Arvin.qi <arvin.qi@qq.com>",
27
28
  "license": "MIT",
@@ -1,23 +1,25 @@
1
1
  /**
2
2
  * JSON server-config editor: view and edit the whole MCP server list as one
3
- * JSON document. The document is an array of server definitions (the same
4
- * shape the add/edit form submits); applying it replaces the whole list —
5
- * listed servers are created or updated, existing servers absent from the
6
- * document are removed. Secret env values are never exported (a `configured`
7
- * flag marks them) and a blank secret value keeps the stored one.
3
+ * key-value JSON document (server name config). Applying it replaces the
4
+ * whole list listed servers are created or updated, existing servers
5
+ * absent from the document are removed. Secret env values are never
6
+ * exported (a `configured` flag marks them) and a blank secret value keeps
7
+ * the stored one.
8
8
  *
9
- * [
10
- * {
11
- * "serverName": "feishu-mcp",
12
- * "transport": "streamable-http",
13
- * "enabled": true,
9
+ * {
10
+ * "feishu-mcp": {
11
+ * "type": "streamable_http",
14
12
  * "url": "https://.../mcp",
15
13
  * "headers": { "Authorization": "Bearer ..." },
16
- * "toolCallTimeoutMs": 60000,
17
- * "failOnStartupError": true,
18
- * "env": []
14
+ * "disabled": false
15
+ * },
16
+ * "local": {
17
+ * "type": "stdio",
18
+ * "command": "npx",
19
+ * "args": ["-y", "some-server"],
20
+ * "disabled": false
19
21
  * }
20
- * ]
22
+ * }
21
23
  * @module dsh-mcp/client/ServersJsonEditor
22
24
  */
23
25
 
@@ -48,13 +50,13 @@ export interface ServersJsonEditorProps {
48
50
  readonly onApplied: () => void
49
51
  }
50
52
 
51
- /** Serialize the current server list into the JSON document text. */
53
+ /** Serialize the current server list into the JSON document text (key-value). */
52
54
  export function serversToJsonText(servers: readonly McpServerView[]): string {
53
- const document = servers.map((server) => {
55
+ const document: Record<string, Record<string, unknown>> = {}
56
+ for (const server of servers) {
54
57
  const entry: Record<string, unknown> = {
55
- serverName: server.serverName,
56
- transport: server.transport,
57
- enabled: server.enabled,
58
+ type: server.transport === 'stdio' ? 'stdio' : 'streamable_http',
59
+ disabled: !server.enabled,
58
60
  }
59
61
  if (server.transport === 'stdio') {
60
62
  entry.command = server.command
@@ -71,8 +73,8 @@ export function serversToJsonText(servers: readonly McpServerView[]): string {
71
73
  entry.env = server.env.map(row => row.secret
72
74
  ? { name: row.name, secret: true, configured: row.configured }
73
75
  : { name: row.name, secret: false, ...(row.value !== undefined && row.value.length > 0 ? { value: row.value } : {}) })
74
- return entry
75
- })
76
+ document[server.serverName] = entry
77
+ }
76
78
  return `${JSON.stringify(document, null, 2)}\n`
77
79
  }
78
80
 
@@ -84,40 +86,38 @@ export function parseServersJson(text: string): { ok: true; servers: readonly Se
84
86
  } catch (error) {
85
87
  return { ok: false, error: error instanceof Error ? error.message : String(error) }
86
88
  }
87
- if (!Array.isArray(value)) {
88
- return { ok: false, error: 'JSON 顶层必须是服务器配置数组:[ { serverName, transport, ... }, ... ]' }
89
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
90
+ return { ok: false, error: 'JSON 顶层必须是对象:{ "服务器名": { "type": "streamable_http", ... } }' }
89
91
  }
90
- if (value.length === 0) {
92
+ const entries = Object.entries(value as Record<string, unknown>)
93
+ if (entries.length === 0) {
91
94
  return { ok: false, error: '配置列表不能为空' }
92
95
  }
93
96
  const servers: ServersJsonEntry[] = []
94
- const seen = new Set<string>()
95
- for (const item of value) {
96
- if (item === null || typeof item !== 'object' || Array.isArray(item)) {
97
- return { ok: false, error: '每个条目必须是对象:{ serverName, transport, ... }' }
97
+ for (const [serverName, raw] of entries) {
98
+ if (serverName.trim().length === 0) return { ok: false, error: '服务器名不能为空' }
99
+ if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {
100
+ return { ok: false, error: `服务器 "${serverName}" 的配置必须是对象` }
98
101
  }
99
- const server = item as Record<string, unknown>
100
- const serverName = typeof server.serverName === 'string' ? server.serverName.trim() : ''
101
- if (serverName.length === 0) return { ok: false, error: 'serverName 不能为空' }
102
- if (seen.has(serverName)) return { ok: false, error: `serverName "${serverName}" 重复` }
103
- seen.add(serverName)
104
- const transport = server.transport
105
- if (transport !== 'stdio' && transport !== 'streamable-http') {
106
- return { ok: false, error: `服务器 "${serverName}" 的 transport 必须是 stdio 或 streamable-http` }
102
+ const cfg = raw as Record<string, unknown>
103
+ const type = cfg.type
104
+ const transport = type === 'stdio' ? 'stdio' : type === 'streamable_http' ? 'streamable-http' : undefined
105
+ if (transport === undefined) {
106
+ return { ok: false, error: `服务器 "${serverName}" 的 type 必须是 streamable_http 或 stdio` }
107
107
  }
108
- if (transport === 'stdio' && (typeof server.command !== 'string' || server.command.trim().length === 0)) {
108
+ if (transport === 'stdio' && (typeof cfg.command !== 'string' || cfg.command.trim().length === 0)) {
109
109
  return { ok: false, error: `服务器 "${serverName}"(stdio)缺少 command` }
110
110
  }
111
- if (transport === 'streamable-http' && typeof server.url !== 'string') {
112
- return { ok: false, error: `服务器 "${serverName}"(streamable-http)缺少 url` }
111
+ if (transport === 'streamable-http' && typeof cfg.url !== 'string') {
112
+ return { ok: false, error: `服务器 "${serverName}"(streamable_http)缺少 url` }
113
113
  }
114
- if (server.headers !== undefined) {
115
- const headers = server.headers as unknown
114
+ if (cfg.headers !== undefined) {
115
+ const headers = cfg.headers as unknown
116
116
  const okHeaders = (headers !== null && typeof headers === 'object' && !Array.isArray(headers))
117
117
  || (Array.isArray(headers) && headers.every(h => h !== null && typeof h === 'object' && typeof (h as { name?: unknown }).name === 'string'))
118
118
  if (!okHeaders) return { ok: false, error: `服务器 "${serverName}" 的 headers 必须是 { "名称": "值" } 对象或 { name, value } 数组` }
119
119
  }
120
- const envValue = server.env
120
+ const envValue = cfg.env
121
121
  const env: unknown[] = Array.isArray(envValue) ? envValue : []
122
122
  for (const row of env) {
123
123
  const r = row as Record<string, unknown> | null
@@ -131,6 +131,20 @@ export function parseServersJson(text: string): { ok: true; servers: readonly Se
131
131
  return { ok: false, error: `服务器 "${serverName}" 的 env 条目 "${r.name}" 的 value 必须是字符串` }
132
132
  }
133
133
  }
134
+ // Map the key-value document into the wire server shape (host upsertJson
135
+ // consumes serverName/transport/enabled/...).
136
+ const server: Record<string, unknown> = {
137
+ serverName,
138
+ transport,
139
+ enabled: cfg.disabled !== true,
140
+ command: typeof cfg.command === 'string' ? cfg.command : '',
141
+ args: Array.isArray(cfg.args) ? cfg.args : [],
142
+ cwd: typeof cfg.cwd === 'string' ? cfg.cwd : '',
143
+ url: typeof cfg.url === 'string' ? cfg.url : '',
144
+ headers: cfg.headers,
145
+ toolCallTimeoutMs: typeof cfg.toolCallTimeoutMs === 'number' ? cfg.toolCallTimeoutMs : 60000,
146
+ failOnStartupError: cfg.failOnStartupError !== false,
147
+ }
134
148
  servers.push({ server, env })
135
149
  }
136
150
  return { ok: true, servers }
@@ -75,7 +75,7 @@ export const zh = {
75
75
  toolsCollapse: '收起工具',
76
76
  serversJson: 'JSON 维护配置',
77
77
  serversJsonLabel: '服务器配置 JSON',
78
- serversJsonHint: '整个 MCP 服务器配置列表(数组):应用后将按此列表替换——已列出的服务器创建/更新,未列出的将被删除;secret 环境变量值不会导出(configured 标记),留空则保留原值。',
78
+ serversJsonHint: '整个 MCP 服务器配置(key-value 对象,服务器名 → 配置):应用后将按此替换——已列出的服务器创建/更新,未列出的将被删除;type 为 streamable_http 或 stdio,disabled 为 true 表示停用;secret 环境变量值不会导出(configured 标记),留空则保留原值。',
79
79
  serversJsonReseed: '重新导出',
80
80
  serversJsonApply: '应用',
81
81
  serversJsonSaving: '应用中…',
@@ -178,7 +178,7 @@ export const en = {
178
178
  toolsCollapse: 'Collapse tools',
179
179
  serversJson: 'JSON config editor',
180
180
  serversJsonLabel: 'Server-config JSON',
181
- serversJsonHint: 'The whole MCP server list (array): applying replaces the list — listed servers are created/updated, existing servers absent from the document are removed; secret env values are never exported (a configured flag marks them), a blank value keeps the stored one.',
181
+ serversJsonHint: 'The whole MCP server config as a key-value object (server name → config): applying replaces the list — listed servers are created/updated, servers absent from the document are removed; type is streamable_http or stdio, disabled: true disables the server; secret env values are never exported (a configured flag marks them), a blank value keeps the stored one.',
182
182
  serversJsonReseed: 'Re-export',
183
183
  serversJsonApply: 'Apply',
184
184
  serversJsonSaving: 'Applying…',