@zltquant/zlt-mcp 0.7.3 → 0.7.4

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.
@@ -1147,7 +1147,7 @@ var require_command = __commonJS({
1147
1147
  "../../node_modules/.pnpm/commander@13.1.0/node_modules/commander/lib/command.js"(exports2) {
1148
1148
  var EventEmitter = require("node:events").EventEmitter;
1149
1149
  var childProcess = require("node:child_process");
1150
- var path27 = require("node:path");
1150
+ var path28 = require("node:path");
1151
1151
  var fs28 = require("node:fs");
1152
1152
  var process4 = require("node:process");
1153
1153
  var { Argument: Argument2, humanReadableArgName } = require_argument();
@@ -2147,9 +2147,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
2147
2147
  let launchWithNode = false;
2148
2148
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
2149
2149
  function findFile(baseDir, baseName) {
2150
- const localBin = path27.resolve(baseDir, baseName);
2150
+ const localBin = path28.resolve(baseDir, baseName);
2151
2151
  if (fs28.existsSync(localBin)) return localBin;
2152
- if (sourceExt.includes(path27.extname(baseName))) return void 0;
2152
+ if (sourceExt.includes(path28.extname(baseName))) return void 0;
2153
2153
  const foundExt = sourceExt.find(
2154
2154
  (ext) => fs28.existsSync(`${localBin}${ext}`)
2155
2155
  );
@@ -2167,17 +2167,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
2167
2167
  } catch {
2168
2168
  resolvedScriptPath = this._scriptPath;
2169
2169
  }
2170
- executableDir = path27.resolve(
2171
- path27.dirname(resolvedScriptPath),
2170
+ executableDir = path28.resolve(
2171
+ path28.dirname(resolvedScriptPath),
2172
2172
  executableDir
2173
2173
  );
2174
2174
  }
2175
2175
  if (executableDir) {
2176
2176
  let localFile = findFile(executableDir, executableFile);
2177
2177
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
2178
- const legacyName = path27.basename(
2178
+ const legacyName = path28.basename(
2179
2179
  this._scriptPath,
2180
- path27.extname(this._scriptPath)
2180
+ path28.extname(this._scriptPath)
2181
2181
  );
2182
2182
  if (legacyName !== this._name) {
2183
2183
  localFile = findFile(
@@ -2188,7 +2188,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2188
2188
  }
2189
2189
  executableFile = localFile || executableFile;
2190
2190
  }
2191
- launchWithNode = sourceExt.includes(path27.extname(executableFile));
2191
+ launchWithNode = sourceExt.includes(path28.extname(executableFile));
2192
2192
  let proc;
2193
2193
  if (process4.platform !== "win32") {
2194
2194
  if (launchWithNode) {
@@ -3035,7 +3035,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
3035
3035
  * @return {Command}
3036
3036
  */
3037
3037
  nameFromFilename(filename) {
3038
- this._name = path27.basename(filename, path27.extname(filename));
3038
+ this._name = path28.basename(filename, path28.extname(filename));
3039
3039
  return this;
3040
3040
  }
3041
3041
  /**
@@ -3049,9 +3049,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
3049
3049
  * @param {string} [path]
3050
3050
  * @return {(string|null|Command)}
3051
3051
  */
3052
- executableDir(path28) {
3053
- if (path28 === void 0) return this._executableDir;
3054
- this._executableDir = path28;
3052
+ executableDir(path29) {
3053
+ if (path29 === void 0) return this._executableDir;
3054
+ this._executableDir = path29;
3055
3055
  return this;
3056
3056
  }
3057
3057
  /**
@@ -6516,8 +6516,8 @@ var require_utils = __commonJS({
6516
6516
  }
6517
6517
  return ind;
6518
6518
  }
6519
- function removeDotSegments(path27) {
6520
- let input = path27;
6519
+ function removeDotSegments(path28) {
6520
+ let input = path28;
6521
6521
  const output = [];
6522
6522
  let nextSlash = -1;
6523
6523
  let len = 0;
@@ -6716,8 +6716,8 @@ var require_schemes = __commonJS({
6716
6716
  wsComponent.secure = void 0;
6717
6717
  }
6718
6718
  if (wsComponent.resourceName) {
6719
- const [path27, query] = wsComponent.resourceName.split("?");
6720
- wsComponent.path = path27 && path27 !== "/" ? path27 : void 0;
6719
+ const [path28, query] = wsComponent.resourceName.split("?");
6720
+ wsComponent.path = path28 && path28 !== "/" ? path28 : void 0;
6721
6721
  wsComponent.query = query;
6722
6722
  wsComponent.resourceName = void 0;
6723
6723
  }
@@ -10098,7 +10098,7 @@ var require_windows = __commonJS({
10098
10098
  module2.exports = isexe;
10099
10099
  isexe.sync = sync;
10100
10100
  var fs28 = require("fs");
10101
- function checkPathExt(path27, options) {
10101
+ function checkPathExt(path28, options) {
10102
10102
  var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
10103
10103
  if (!pathext) {
10104
10104
  return true;
@@ -10109,25 +10109,25 @@ var require_windows = __commonJS({
10109
10109
  }
10110
10110
  for (var i = 0; i < pathext.length; i++) {
10111
10111
  var p = pathext[i].toLowerCase();
10112
- if (p && path27.substr(-p.length).toLowerCase() === p) {
10112
+ if (p && path28.substr(-p.length).toLowerCase() === p) {
10113
10113
  return true;
10114
10114
  }
10115
10115
  }
10116
10116
  return false;
10117
10117
  }
10118
- function checkStat(stat, path27, options) {
10118
+ function checkStat(stat, path28, options) {
10119
10119
  if (!stat.isSymbolicLink() && !stat.isFile()) {
10120
10120
  return false;
10121
10121
  }
10122
- return checkPathExt(path27, options);
10122
+ return checkPathExt(path28, options);
10123
10123
  }
10124
- function isexe(path27, options, cb) {
10125
- fs28.stat(path27, function(er, stat) {
10126
- cb(er, er ? false : checkStat(stat, path27, options));
10124
+ function isexe(path28, options, cb) {
10125
+ fs28.stat(path28, function(er, stat) {
10126
+ cb(er, er ? false : checkStat(stat, path28, options));
10127
10127
  });
10128
10128
  }
10129
- function sync(path27, options) {
10130
- return checkStat(fs28.statSync(path27), path27, options);
10129
+ function sync(path28, options) {
10130
+ return checkStat(fs28.statSync(path28), path28, options);
10131
10131
  }
10132
10132
  }
10133
10133
  });
@@ -10138,13 +10138,13 @@ var require_mode = __commonJS({
10138
10138
  module2.exports = isexe;
10139
10139
  isexe.sync = sync;
10140
10140
  var fs28 = require("fs");
10141
- function isexe(path27, options, cb) {
10142
- fs28.stat(path27, function(er, stat) {
10141
+ function isexe(path28, options, cb) {
10142
+ fs28.stat(path28, function(er, stat) {
10143
10143
  cb(er, er ? false : checkStat(stat, options));
10144
10144
  });
10145
10145
  }
10146
- function sync(path27, options) {
10147
- return checkStat(fs28.statSync(path27), options);
10146
+ function sync(path28, options) {
10147
+ return checkStat(fs28.statSync(path28), options);
10148
10148
  }
10149
10149
  function checkStat(stat, options) {
10150
10150
  return stat.isFile() && checkMode(stat, options);
@@ -10177,7 +10177,7 @@ var require_isexe = __commonJS({
10177
10177
  }
10178
10178
  module2.exports = isexe;
10179
10179
  isexe.sync = sync;
10180
- function isexe(path27, options, cb) {
10180
+ function isexe(path28, options, cb) {
10181
10181
  if (typeof options === "function") {
10182
10182
  cb = options;
10183
10183
  options = {};
@@ -10187,7 +10187,7 @@ var require_isexe = __commonJS({
10187
10187
  throw new TypeError("callback not provided");
10188
10188
  }
10189
10189
  return new Promise(function(resolve12, reject) {
10190
- isexe(path27, options || {}, function(er, is) {
10190
+ isexe(path28, options || {}, function(er, is) {
10191
10191
  if (er) {
10192
10192
  reject(er);
10193
10193
  } else {
@@ -10196,7 +10196,7 @@ var require_isexe = __commonJS({
10196
10196
  });
10197
10197
  });
10198
10198
  }
10199
- core(path27, options || {}, function(er, is) {
10199
+ core(path28, options || {}, function(er, is) {
10200
10200
  if (er) {
10201
10201
  if (er.code === "EACCES" || options && options.ignoreErrors) {
10202
10202
  er = null;
@@ -10206,9 +10206,9 @@ var require_isexe = __commonJS({
10206
10206
  cb(er, is);
10207
10207
  });
10208
10208
  }
10209
- function sync(path27, options) {
10209
+ function sync(path28, options) {
10210
10210
  try {
10211
- return core.sync(path27, options || {});
10211
+ return core.sync(path28, options || {});
10212
10212
  } catch (er) {
10213
10213
  if (options && options.ignoreErrors || er.code === "EACCES") {
10214
10214
  return false;
@@ -10224,7 +10224,7 @@ var require_isexe = __commonJS({
10224
10224
  var require_which = __commonJS({
10225
10225
  "../../node_modules/.pnpm/which@2.0.2/node_modules/which/which.js"(exports2, module2) {
10226
10226
  var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
10227
- var path27 = require("path");
10227
+ var path28 = require("path");
10228
10228
  var COLON = isWindows ? ";" : ":";
10229
10229
  var isexe = require_isexe();
10230
10230
  var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
@@ -10262,7 +10262,7 @@ var require_which = __commonJS({
10262
10262
  return opt.all && found.length ? resolve12(found) : reject(getNotFoundError(cmd));
10263
10263
  const ppRaw = pathEnv[i];
10264
10264
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
10265
- const pCmd = path27.join(pathPart, cmd);
10265
+ const pCmd = path28.join(pathPart, cmd);
10266
10266
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
10267
10267
  resolve12(subStep(p, i, 0));
10268
10268
  });
@@ -10289,7 +10289,7 @@ var require_which = __commonJS({
10289
10289
  for (let i = 0; i < pathEnv.length; i++) {
10290
10290
  const ppRaw = pathEnv[i];
10291
10291
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
10292
- const pCmd = path27.join(pathPart, cmd);
10292
+ const pCmd = path28.join(pathPart, cmd);
10293
10293
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
10294
10294
  for (let j = 0; j < pathExt.length; j++) {
10295
10295
  const cur = p + pathExt[j];
@@ -10337,7 +10337,7 @@ var require_path_key = __commonJS({
10337
10337
  var require_resolveCommand = __commonJS({
10338
10338
  "../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.js"(exports2, module2) {
10339
10339
  "use strict";
10340
- var path27 = require("path");
10340
+ var path28 = require("path");
10341
10341
  var which = require_which();
10342
10342
  var getPathKey = require_path_key();
10343
10343
  function resolveCommandAttempt(parsed, withoutPathExt) {
@@ -10355,7 +10355,7 @@ var require_resolveCommand = __commonJS({
10355
10355
  try {
10356
10356
  resolved = which.sync(parsed.command, {
10357
10357
  path: env[getPathKey({ env })],
10358
- pathExt: withoutPathExt ? path27.delimiter : void 0
10358
+ pathExt: withoutPathExt ? path28.delimiter : void 0
10359
10359
  });
10360
10360
  } catch (e) {
10361
10361
  } finally {
@@ -10364,7 +10364,7 @@ var require_resolveCommand = __commonJS({
10364
10364
  }
10365
10365
  }
10366
10366
  if (resolved) {
10367
- resolved = path27.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
10367
+ resolved = path28.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
10368
10368
  }
10369
10369
  return resolved;
10370
10370
  }
@@ -10418,8 +10418,8 @@ var require_shebang_command = __commonJS({
10418
10418
  if (!match) {
10419
10419
  return null;
10420
10420
  }
10421
- const [path27, argument] = match[0].replace(/#! ?/, "").split(" ");
10422
- const binary = path27.split("/").pop();
10421
+ const [path28, argument] = match[0].replace(/#! ?/, "").split(" ");
10422
+ const binary = path28.split("/").pop();
10423
10423
  if (binary === "env") {
10424
10424
  return argument;
10425
10425
  }
@@ -10454,7 +10454,7 @@ var require_readShebang = __commonJS({
10454
10454
  var require_parse = __commonJS({
10455
10455
  "../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.js"(exports2, module2) {
10456
10456
  "use strict";
10457
- var path27 = require("path");
10457
+ var path28 = require("path");
10458
10458
  var resolveCommand = require_resolveCommand();
10459
10459
  var escape2 = require_escape();
10460
10460
  var readShebang = require_readShebang();
@@ -10479,7 +10479,7 @@ var require_parse = __commonJS({
10479
10479
  const needsShell = !isExecutableRegExp.test(commandFile);
10480
10480
  if (parsed.options.forceShell || needsShell) {
10481
10481
  const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
10482
- parsed.command = path27.normalize(parsed.command);
10482
+ parsed.command = path28.normalize(parsed.command);
10483
10483
  parsed.command = escape2.command(parsed.command);
10484
10484
  parsed.args = parsed.args.map((arg) => escape2.argument(arg, needsDoubleEscapeMetaChars));
10485
10485
  const shellCommand = [parsed.command].concat(parsed.args).join(" ");
@@ -10801,10 +10801,20 @@ var COMMON_CALL_HELP = `
10801
10801
  Input: omitted arguments mean {}; use --args-json for a JSON object or --args-file
10802
10802
  for nested or shell-sensitive input. Read the current schema with
10803
10803
  list --tool <name> --json; schema properties are JSON keys, not CLI flags.
10804
- Output: stdout contains the complete MCP JSON envelope by default. --output-json
10805
- saves that envelope to a new file and prints a compact receipt. --evidence-dir
10806
- saves an execution record in a new directory; it cannot be combined with
10807
- --output-json. Preserve stderr and the CLI exit code before parsing business data.
10804
+ Output: stdout carries the MCP JSON response by default. Its underlying
10805
+ business data may be large; size and completeness are controlled
10806
+ by the selected tool rather than this CLI.
10807
+ --output-json saves the complete envelope to a new file and prints a compact
10808
+ receipt. --evidence-dir saves an execution record in a new directory; it
10809
+ cannot be combined with --output-json. Preserve stderr and the CLI exit code
10810
+ before parsing business data. The complete result.json is evidence, not the
10811
+ default conversational payload.
10812
+ For more detail or smaller model context, use only schema-exposed
10813
+ reportSections, offset/limit, page/pageSize, or fields, selecting the smallest
10814
+ set needed for the next decision. Do not invent parameter names. includeReport,
10815
+ when exposed, may be large and is not promised to truncate. result.json saves
10816
+ the complete CLI response for the selected request; it cannot restore omitted
10817
+ business data. The detail contract does not change public CLI flags.
10808
10818
  For mcp-download-data, --verify-download submits once on one MCP connection,
10809
10819
  waits for that uuid, and only after a verifiable DONE collects range, disk-space,
10810
10820
  and bounded physical-file evidence. Files never prove continuous coverage.
@@ -10860,28 +10870,28 @@ var UNSUPPORTED_SCHEMA_KEYWORDS = [
10860
10870
  "propertyNames",
10861
10871
  "unevaluatedProperties"
10862
10872
  ];
10863
- function unsupportedSchemaConstraint(schemaValue, path27 = "inputSchema") {
10873
+ function unsupportedSchemaConstraint(schemaValue, path28 = "inputSchema") {
10864
10874
  const schema = record(schemaValue);
10865
- if (!schema) return path27;
10875
+ if (!schema) return path28;
10866
10876
  for (const keyword of UNSUPPORTED_SCHEMA_KEYWORDS) {
10867
- if (Object.prototype.hasOwnProperty.call(schema, keyword)) return `${path27}.${keyword}`;
10877
+ if (Object.prototype.hasOwnProperty.call(schema, keyword)) return `${path28}.${keyword}`;
10868
10878
  }
10869
10879
  const properties = record(schema.properties);
10870
10880
  if (properties) {
10871
10881
  for (const [name, property] of Object.entries(properties)) {
10872
- const unsupported = unsupportedSchemaConstraint(property, `${path27}.properties.${name}`);
10882
+ const unsupported = unsupportedSchemaConstraint(property, `${path28}.properties.${name}`);
10873
10883
  if (unsupported) return unsupported;
10874
10884
  }
10875
10885
  }
10876
10886
  if (schema.items !== void 0) {
10877
- const unsupported = unsupportedSchemaConstraint(schema.items, `${path27}.items`);
10887
+ const unsupported = unsupportedSchemaConstraint(schema.items, `${path28}.items`);
10878
10888
  if (unsupported) return unsupported;
10879
10889
  }
10880
10890
  return void 0;
10881
10891
  }
10882
- function explicitValue(schemaValue, path27) {
10892
+ function explicitValue(schemaValue, path28) {
10883
10893
  const schema = record(schemaValue);
10884
- if (!schema) return { available: false, missing: [path27] };
10894
+ if (!schema) return { available: false, missing: [path28] };
10885
10895
  if (Object.prototype.hasOwnProperty.call(schema, "example")) {
10886
10896
  return { available: true, value: cloneValue(schema.example), missing: [] };
10887
10897
  }
@@ -10903,13 +10913,13 @@ function explicitValue(schemaValue, path27) {
10903
10913
  const value = {};
10904
10914
  const missing = [];
10905
10915
  for (const name of required2) {
10906
- const child = explicitValue(properties[name], path27 ? `${path27}.${name}` : name);
10916
+ const child = explicitValue(properties[name], path28 ? `${path28}.${name}` : name);
10907
10917
  if (child.available) value[name] = child.value;
10908
10918
  missing.push(...child.missing);
10909
10919
  }
10910
10920
  return { available: missing.length === 0, value, missing };
10911
10921
  }
10912
- return { available: false, missing: [path27] };
10922
+ return { available: false, missing: [path28] };
10913
10923
  }
10914
10924
  function buildArgumentExample(tool) {
10915
10925
  const schema = record(tool.inputSchema);
@@ -10975,7 +10985,11 @@ function buildCliUsage(tool, tools) {
10975
10985
  example: buildArgumentExample(tool)
10976
10986
  },
10977
10987
  output: {
10978
- default: "Read the complete MCP JSON envelope from stdout and preserve stderr and the CLI exit code.",
10988
+ default: "Read the MCP JSON envelope from stdout and preserve stderr and the CLI exit code. The selected tool may return a large business payload; use schema-exposed reportSections, offset/limit, page/pageSize, or fields to select detail for routine model context.",
10989
+ detail: {
10990
+ contract: "Follow the selected tool schema and do not invent parameter names. includeReport may be large; it is not a promise of truncation or a substitute for explicit selection where the schema provides it.",
10991
+ completeEvidence: "result.json in evidence mode is the complete CLI response for the selected request, page, and fields; it cannot recover underlying business data omitted by that request."
10992
+ },
10979
10993
  outputJson: {
10980
10994
  option: "--output-json <new-file>",
10981
10995
  result: "The complete envelope is saved; stdout is a compact receipt."
@@ -11007,11 +11021,11 @@ function buildCliUsage(tool, tools) {
11007
11021
 
11008
11022
  // src/index.ts
11009
11023
  var fs27 = __toESM(require("node:fs"), 1);
11010
- var path26 = __toESM(require("node:path"), 1);
11024
+ var path27 = __toESM(require("node:path"), 1);
11011
11025
 
11012
11026
  // src/cli.ts
11013
11027
  var fs15 = __toESM(require("fs"), 1);
11014
- var path14 = __toESM(require("path"), 1);
11028
+ var path15 = __toESM(require("path"), 1);
11015
11029
 
11016
11030
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v4/core/core.js
11017
11031
  var NEVER = Object.freeze({
@@ -11208,10 +11222,10 @@ function assignProp(target, prop, value) {
11208
11222
  configurable: true
11209
11223
  });
11210
11224
  }
11211
- function getElementAtPath(obj, path27) {
11212
- if (!path27)
11225
+ function getElementAtPath(obj, path28) {
11226
+ if (!path28)
11213
11227
  return obj;
11214
- return path27.reduce((acc, key) => acc?.[key], obj);
11228
+ return path28.reduce((acc, key) => acc?.[key], obj);
11215
11229
  }
11216
11230
  function promiseAllObject(promisesObj) {
11217
11231
  const keys = Object.keys(promisesObj);
@@ -11531,11 +11545,11 @@ function aborted(x, startIndex = 0) {
11531
11545
  }
11532
11546
  return false;
11533
11547
  }
11534
- function prefixIssues(path27, issues) {
11548
+ function prefixIssues(path28, issues) {
11535
11549
  return issues.map((iss) => {
11536
11550
  var _a;
11537
11551
  (_a = iss).path ?? (_a.path = []);
11538
- iss.path.unshift(path27);
11552
+ iss.path.unshift(path28);
11539
11553
  return iss;
11540
11554
  });
11541
11555
  }
@@ -18322,6 +18336,7 @@ var OFFICIAL_INSTALLERS = {
18322
18336
  full: {
18323
18337
  artifact: "zlt_client",
18324
18338
  version: "v1.14.2",
18339
+ installedVersion: "2026.09.11.4",
18325
18340
  sha256: "B65F39EAE5F37545D79F1149C3DC436B5ED9E1BEC8F21893FB91BD5A09081B0F"
18326
18341
  },
18327
18342
  // 2026-08-15 抬到 2026.08.14.5:公网 OSS 与内网镜像是同一份字节(ETag 113b3cff…、
@@ -18338,9 +18353,11 @@ var OFFICIAL_INSTALLERS = {
18338
18353
  // VSCODE_INSTALL_TYPE),full 槽位只在已装 full 的机器上参与升级判定。
18339
18354
  // **本版没有装机验证**:本机停在 2026.08.28.7,08-30 对 .7 做的那轮活体复核
18340
18355
  // (三进程起得来、ZLTHQHost 管道在、两轮 check:npm-live 全绿)不适用于本版。
18356
+ // Exact pinned bytes report FileVersion 2026.09.11.5; post-install InstallInfo.xml acceptance is pending.
18341
18357
  mini: {
18342
18358
  artifact: "zlt_plugin",
18343
18359
  version: "v1.14.2",
18360
+ installedVersion: "2026.09.11.5",
18344
18361
  sha256: "4E96214F0DDA6A6560D5C820D6BC230466BFF06095336C5250A90C44B4A52BB6"
18345
18362
  }
18346
18363
  },
@@ -18349,11 +18366,13 @@ var OFFICIAL_INSTALLERS = {
18349
18366
  full: {
18350
18367
  artifact: "zlt_client",
18351
18368
  version: "v1.14.2",
18369
+ installedVersion: "2026.09.11.4",
18352
18370
  sha256: "B65F39EAE5F37545D79F1149C3DC436B5ED9E1BEC8F21893FB91BD5A09081B0F"
18353
18371
  },
18354
18372
  mini: {
18355
18373
  artifact: "zlt_plugin",
18356
18374
  version: "v1.14.2",
18375
+ installedVersion: "2026.09.11.5",
18357
18376
  sha256: "4E96214F0DDA6A6560D5C820D6BC230466BFF06095336C5250A90C44B4A52BB6"
18358
18377
  }
18359
18378
  }
@@ -18365,6 +18384,10 @@ function officialInstallerUrl(slot, mirror = "public") {
18365
18384
  const spec = OFFICIAL_INSTALLERS[mirror][slot];
18366
18385
  return `${OFFICIAL_MIRROR_ROOTS[mirror]}/pkg/${spec.artifact}_${spec.version}.exe`;
18367
18386
  }
18387
+ function officialInstallerVersionIndexUrl(slot, mirror = "public") {
18388
+ const name = slot === "full" ? "zlt_client_versions.json" : "zlt_plugin_versions.json";
18389
+ return `${OFFICIAL_MIRROR_ROOTS[mirror]}/pkg/${name}`;
18390
+ }
18368
18391
  function officialVersionIndexUrl(mirror = "public") {
18369
18392
  return `${OFFICIAL_MIRROR_ROOTS[mirror]}/VscodeMarketPlugin/zlt_quant_version_index.json`;
18370
18393
  }
@@ -18420,8 +18443,8 @@ var defaultAssistantRuntimeConfig = {
18420
18443
  // OFFICIAL_INSTALLERS,结构上不可能只改 URL 不改这里。
18421
18444
  backserviceDownloadVersion: {
18422
18445
  OFFICIAL: {
18423
- full: OFFICIAL_INSTALLERS.public.full.version,
18424
- mini: OFFICIAL_INSTALLERS.public.mini.version
18446
+ full: OFFICIAL_INSTALLERS.public.full.installedVersion,
18447
+ mini: OFFICIAL_INSTALLERS.public.mini.installedVersion
18425
18448
  },
18426
18449
  REL: { full: "", mini: "" },
18427
18450
  DEBUG: {
@@ -18678,7 +18701,7 @@ function applyInstallerMirror(config2, mirror) {
18678
18701
  },
18679
18702
  backserviceDownloadVersion: {
18680
18703
  ...config2.backserviceDownloadVersion,
18681
- OFFICIAL: { full: pins.full.version, mini: pins.mini.version }
18704
+ OFFICIAL: { full: pins.full.installedVersion, mini: pins.mini.installedVersion }
18682
18705
  }
18683
18706
  };
18684
18707
  }
@@ -18940,7 +18963,7 @@ function pipeExists(clientRootDir, explicitPipeName) {
18940
18963
  // ../zlt-runtime-core/dist/runtime.js
18941
18964
  var fs7 = __toESM(require("fs"), 1);
18942
18965
  var os2 = __toESM(require("os"), 1);
18943
- var path7 = __toESM(require("path"), 1);
18966
+ var path8 = __toESM(require("path"), 1);
18944
18967
  var import_child_process4 = require("child_process");
18945
18968
 
18946
18969
  // ../zlt-runtime-core/dist/assistant-ipc.js
@@ -19648,8 +19671,8 @@ async function waitForPipe(workRoot, pipePrefix, timeout) {
19648
19671
  }
19649
19672
  async function readZltContent(workRoot, temporaryZltFile) {
19650
19673
  const fs28 = await import("fs");
19651
- const path27 = await import("path");
19652
- const zltFile = path27.join(workRoot, temporaryZltFile || "Temporary/zlt");
19674
+ const path28 = await import("path");
19675
+ const zltFile = path28.join(workRoot, temporaryZltFile || "Temporary/zlt");
19653
19676
  return fs28.existsSync(zltFile) ? fs28.readFileSync(zltFile, "utf-8").trim() : "";
19654
19677
  }
19655
19678
  async function pipeExists2(pipeName) {
@@ -19986,6 +20009,7 @@ function inspectRuntimeProcess(pid) {
19986
20009
  "if ($p) { [pscustomobject]@{ pid=[int]$p.ProcessId; executablePath=[string]$p.ExecutablePath; creationTime=$p.CreationDate.ToUniversalTime().ToString('o') } | ConvertTo-Json -Compress }"
19987
20010
  ].join("; ");
19988
20011
  const result = (0, import_child_process2.spawnSync)(powershell, ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", command], {
20012
+ stdio: ["ignore", "pipe", "pipe"],
19989
20013
  encoding: "utf8",
19990
20014
  env: { ...process.env, ZLT_RUNTIME_PID: String(pid) },
19991
20015
  timeout: 1e4,
@@ -20020,6 +20044,7 @@ var defaultRuntimeLifecycleDeps = {
20020
20044
  "Stop-Process -Id $p.ProcessId -Force -ErrorAction Stop"
20021
20045
  ].join("; ");
20022
20046
  const result = (0, import_child_process2.spawnSync)(powershell, ["-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", command], {
20047
+ stdio: ["ignore", "pipe", "pipe"],
20023
20048
  encoding: "utf8",
20024
20049
  env: {
20025
20050
  ...process.env,
@@ -20249,13 +20274,130 @@ function writeJson(filePath, value) {
20249
20274
 
20250
20275
  // ../zlt-runtime-core/dist/assistant-base-upgrade.js
20251
20276
  var fs5 = __toESM(require("fs"), 1);
20252
- var path5 = __toESM(require("path"), 1);
20277
+ var path6 = __toESM(require("path"), 1);
20253
20278
 
20254
20279
  // ../zlt-runtime-core/dist/version-gates.js
20255
20280
  function versionGatesDisabled() {
20256
20281
  return ""?.trim() === "1";
20257
20282
  }
20258
20283
 
20284
+ // ../zlt-runtime-core/dist/assistant-installer-descriptor.js
20285
+ var path5 = __toESM(require("path"), 1);
20286
+ async function resolveAssistantInstallerDescriptor(config2, installType, options = {}) {
20287
+ const normalized = normalizeAssistantInstallType(installType);
20288
+ const fallback = resolvePinnedAssistantInstallerDescriptor(config2, normalized);
20289
+ const mirror = matchingOfficialMirror(config2, normalized);
20290
+ if (!mirror)
20291
+ return fallback;
20292
+ const indexUrl = officialInstallerVersionIndexUrl(normalized, mirror);
20293
+ const fetchImpl = options.fetchImpl ?? ((url, init) => fetch(url, init));
20294
+ const controller = new AbortController();
20295
+ const timer = setTimeout(() => controller.abort(), config2.baseRequirementTimeout);
20296
+ try {
20297
+ const response = await fetchImpl(indexUrl, { signal: controller.signal });
20298
+ if (!response.ok)
20299
+ return { ...fallback, fallbackReason: `\u5B89\u88C5\u5305\u7248\u672C\u5217\u8868\u8BF7\u6C42\u5931\u8D25: HTTP ${response.status}` };
20300
+ const body = await response.json();
20301
+ if (!Array.isArray(body))
20302
+ return { ...fallback, fallbackReason: "\u5B89\u88C5\u5305\u7248\u672C\u5217\u8868\u4E0D\u662F JSON \u6570\u7EC4" };
20303
+ const records = body.filter((item) => Boolean(item) && typeof item === "object" && !Array.isArray(item)).flatMap((record5) => {
20304
+ const version2 = normalizeStableProductVersion(record5.version);
20305
+ return version2 ? [{ record: record5, version: version2 }] : [];
20306
+ }).sort((left, right) => compareNumericVersion(right.version, left.version));
20307
+ if (records.length === 0)
20308
+ return { ...fallback, fallbackReason: "\u5B89\u88C5\u5305\u7248\u672C\u5217\u8868\u6CA1\u6709\u7A33\u5B9A\u8BED\u4E49\u7248\u672C" };
20309
+ const latest = records[0];
20310
+ const latestRecords = records.filter((item) => item.version === latest.version);
20311
+ if (latestRecords.some((item) => JSON.stringify(item.record) !== JSON.stringify(latest.record))) {
20312
+ return { ...fallback, fallbackReason: `\u6700\u65B0\u5B89\u88C5\u5305\u7248\u672C ${latest.version} \u5B58\u5728\u91CD\u590D\u8BB0\u5F55` };
20313
+ }
20314
+ const validated = validateLatestRecord(latest.record, normalized);
20315
+ if (typeof validated === "string")
20316
+ return { ...fallback, fallbackReason: `\u6700\u65B0\u5B89\u88C5\u5305\u8BB0\u5F55\u65E0\u6548: ${validated}` };
20317
+ if (compareNumericVersion(validated.internalVersion, fallback.internalVersion) < 0) {
20318
+ return { ...fallback, fallbackReason: "\u6700\u65B0\u5B89\u88C5\u5305 internalVersion \u4F4E\u4E8E\u5185\u7F6E fallback" };
20319
+ }
20320
+ return {
20321
+ source: "dynamic",
20322
+ installType: normalized,
20323
+ url: new URL(validated.fileName, `${indexUrl.slice(0, indexUrl.lastIndexOf("/") + 1)}`).toString(),
20324
+ productVersion: latest.version,
20325
+ internalVersion: validated.internalVersion,
20326
+ fileName: validated.fileName,
20327
+ fileSize: validated.fileSize
20328
+ };
20329
+ } catch (error2) {
20330
+ return {
20331
+ ...fallback,
20332
+ fallbackReason: `\u5B89\u88C5\u5305\u7248\u672C\u5217\u8868\u4E0D\u53EF\u7528: ${error2 instanceof Error ? error2.message : String(error2)}`
20333
+ };
20334
+ } finally {
20335
+ clearTimeout(timer);
20336
+ }
20337
+ }
20338
+ function resolvePinnedAssistantInstallerDescriptor(config2, installType) {
20339
+ const normalized = normalizeAssistantInstallType(installType);
20340
+ const url = config2.backserviceDownload[config2.envMode][normalized]?.trim() || "";
20341
+ return {
20342
+ source: "pinned",
20343
+ installType: normalized,
20344
+ url,
20345
+ productVersion: path5.basename(safeUrlPath(url)).replace(/^zlt_(?:client|plugin)_/i, "").replace(/\.exe$/i, ""),
20346
+ internalVersion: config2.backserviceDownloadVersion[config2.envMode][normalized]?.trim() || "",
20347
+ fileName: path5.basename(safeUrlPath(url)) || "zlt-runtime-installer.exe",
20348
+ sha256: config2.backserviceDownloadSha256[config2.envMode][normalized]?.trim() || void 0
20349
+ };
20350
+ }
20351
+ function matchingOfficialMirror(config2, installType) {
20352
+ if (config2.envMode !== "OFFICIAL")
20353
+ return null;
20354
+ for (const mirror of ["public", "internal"]) {
20355
+ const pin = OFFICIAL_INSTALLERS[mirror][installType];
20356
+ if (config2.backserviceDownload.OFFICIAL[installType] === officialInstallerUrl(installType, mirror) && config2.backserviceDownloadVersion.OFFICIAL[installType] === pin.installedVersion && config2.backserviceDownloadSha256.OFFICIAL[installType].toUpperCase() === pin.sha256)
20357
+ return mirror;
20358
+ }
20359
+ return null;
20360
+ }
20361
+ function validateLatestRecord(record5, installType) {
20362
+ const internalVersion = typeof record5.internalVersion === "string" ? record5.internalVersion.trim() : "";
20363
+ if (!/^\d+(?:\.\d+)+$/.test(internalVersion) || internalVersion.split(".").some((part) => !Number.isSafeInteger(Number(part)))) {
20364
+ return "internalVersion \u7F3A\u5931\u6216\u4E0D\u662F\u5B89\u5168\u7684\u6570\u5B57\u70B9\u5206\u7248\u672C";
20365
+ }
20366
+ const fileName = typeof record5.fileName === "string" ? record5.fileName.trim() : "";
20367
+ if (!fileName || path5.basename(fileName) !== fileName || !/^[A-Za-z0-9._-]+\.exe$/i.test(fileName)) {
20368
+ return "fileName \u5FC5\u987B\u662F\u7EAF\u6587\u4EF6\u540D";
20369
+ }
20370
+ const prefix = installType === "full" ? "zlt_client_" : "zlt_plugin_";
20371
+ if (!fileName.toLowerCase().startsWith(prefix) || !fileName.toLowerCase().endsWith(".exe")) {
20372
+ return `fileName \u5FC5\u987B\u5339\u914D ${prefix}*.exe`;
20373
+ }
20374
+ const fileSize = Number.isSafeInteger(record5.fileSize) && Number(record5.fileSize) > 0 ? Number(record5.fileSize) : void 0;
20375
+ return { internalVersion, fileName, fileSize };
20376
+ }
20377
+ function normalizeStableProductVersion(value) {
20378
+ if (typeof value !== "string")
20379
+ return null;
20380
+ const normalized = value.trim().replace(/^v/i, "");
20381
+ return /^\d+\.\d+\.\d+$/.test(normalized) && normalized.split(".").every((part) => Number.isSafeInteger(Number(part))) ? normalized : null;
20382
+ }
20383
+ function compareNumericVersion(left, right) {
20384
+ const leftParts = left.split(".").map(Number);
20385
+ const rightParts = right.split(".").map(Number);
20386
+ for (let index = 0; index < Math.max(leftParts.length, rightParts.length); index++) {
20387
+ const delta = (leftParts[index] || 0) - (rightParts[index] || 0);
20388
+ if (delta !== 0)
20389
+ return delta < 0 ? -1 : 1;
20390
+ }
20391
+ return 0;
20392
+ }
20393
+ function safeUrlPath(url) {
20394
+ try {
20395
+ return new URL(url).pathname;
20396
+ } catch {
20397
+ return url;
20398
+ }
20399
+ }
20400
+
20259
20401
  // ../zlt-runtime-core/dist/assistant-base-upgrade.js
20260
20402
  var INSTALL_INFO_FILE = "InstallInfo.xml";
20261
20403
  var REQUIREMENT_CACHE_TTL_MS = 5 * 6e4;
@@ -20263,7 +20405,7 @@ var requirementCache = /* @__PURE__ */ new Map();
20263
20405
  var requirementInFlight = /* @__PURE__ */ new Map();
20264
20406
  function readInstalledAssistantBaseVersion(workRoot) {
20265
20407
  try {
20266
- const content = fs5.readFileSync(path5.join(workRoot, INSTALL_INFO_FILE), "utf-8");
20408
+ const content = fs5.readFileSync(path6.join(workRoot, INSTALL_INFO_FILE), "utf-8");
20267
20409
  const matched = content.match(/<InstallAppReleaseVer>(.*?)<\/InstallAppReleaseVer>/i);
20268
20410
  const version2 = matched?.[1]?.trim();
20269
20411
  return version2 ? version2 : null;
@@ -20272,8 +20414,8 @@ function readInstalledAssistantBaseVersion(workRoot) {
20272
20414
  }
20273
20415
  }
20274
20416
  function compareAssistantVersions(left, right) {
20275
- const leftParts = left.split(".");
20276
- const rightParts = right.split(".");
20417
+ const leftParts = left.trim().replace(/^v(?=\d)/i, "").split(".");
20418
+ const rightParts = right.trim().replace(/^v(?=\d)/i, "").split(".");
20277
20419
  const length = Math.max(leftParts.length, rightParts.length);
20278
20420
  for (let index = 0; index < length; index++) {
20279
20421
  const leftPart = parseVersionPart(leftParts[index]);
@@ -20314,7 +20456,9 @@ async function fetchRemoteBaseRequirement(config2, installType, options = {}) {
20314
20456
  return attempt;
20315
20457
  }
20316
20458
  async function checkAssistantBaseUpgrade(workRoot, config2, installType, options = {}) {
20317
- const pinnedVersion = resolveAssistantDownloadVersion(config2, installType);
20459
+ const normalizedInstallType = normalizeAssistantInstallType(installType);
20460
+ let installer = resolvePinnedAssistantInstallerDescriptor(config2, normalizedInstallType);
20461
+ let pinnedVersion = installer.internalVersion || resolveAssistantDownloadVersion(config2, installType);
20318
20462
  if (versionGatesDisabled()) {
20319
20463
  return {
20320
20464
  updateAvailable: false,
@@ -20324,10 +20468,16 @@ async function checkAssistantBaseUpgrade(workRoot, config2, installType, options
20324
20468
  pinnedVersion,
20325
20469
  remoteMin: null,
20326
20470
  blockedByPlugin: false,
20327
- installType: normalizeAssistantInstallType(installType),
20471
+ installType: normalizedInstallType,
20472
+ installer,
20473
+ installerFallbackReason: installer.fallbackReason,
20328
20474
  reason: "\u5185\u6D4B\u6784\u5EFA\u5DF2\u5173\u95ED\u667A\u80FD\u7BA1\u5BB6\u7248\u672C\u6821\u9A8C\uFF08ZLT_DISABLE_VERSION_GATES=1\uFF09\uFF0C\u8DF3\u8FC7\u672C\u4F53\u5347\u7EA7\u5224\u5B9A"
20329
20475
  };
20330
20476
  }
20477
+ installer = await resolveAssistantInstallerDescriptor(config2, normalizedInstallType, {
20478
+ fetchImpl: options.installerFetchImpl
20479
+ });
20480
+ pinnedVersion = installer.internalVersion || pinnedVersion;
20331
20481
  const requirement = await fetchRemoteBaseRequirement(config2, installType, options);
20332
20482
  const remoteMin = requirement?.min?.trim() || null;
20333
20483
  const installed = readInstalledAssistantBaseVersion(workRoot);
@@ -20342,7 +20492,9 @@ async function checkAssistantBaseUpgrade(workRoot, config2, installType, options
20342
20492
  remoteMin,
20343
20493
  // 远程要求高于我们钉住的安装包:装我们这份也满足不了,必须升级插件本身。
20344
20494
  blockedByPlugin: Boolean(remoteMin) && Boolean(pinnedVersion) && compareAssistantVersions(remoteMin, pinnedVersion) > 0,
20345
- installType: normalizeAssistantInstallType(installType)
20495
+ installType: normalizedInstallType,
20496
+ installer,
20497
+ installerFallbackReason: installer.fallbackReason
20346
20498
  };
20347
20499
  if (!installed) {
20348
20500
  return { ...verdict, reason: `\u672A\u80FD\u4ECE ${INSTALL_INFO_FILE} \u8BFB\u53D6\u667A\u80FD\u7BA1\u5BB6\u672C\u4F53\u7248\u672C\uFF0C\u8DF3\u8FC7\u672C\u4F53\u5347\u7EA7\u5224\u5B9A` };
@@ -20400,7 +20552,7 @@ function parseVersionPart(part) {
20400
20552
  // ../zlt-runtime-core/dist/runtime-install.js
20401
20553
  var fs6 = __toESM(require("fs"), 1);
20402
20554
  var os = __toESM(require("os"), 1);
20403
- var path6 = __toESM(require("path"), 1);
20555
+ var path7 = __toESM(require("path"), 1);
20404
20556
  var http = __toESM(require("http"), 1);
20405
20557
  var https = __toESM(require("https"), 1);
20406
20558
  var import_crypto3 = require("crypto");
@@ -20408,7 +20560,7 @@ var import_child_process3 = require("child_process");
20408
20560
  var MANAGED_PROCESS_EXIT_TIMEOUT_MS = 5e3;
20409
20561
  var MANAGED_PROCESS_EXIT_INTERVAL_MS = 200;
20410
20562
  var MANAGED_PROCESS_RESPAWN_RETRY_ROUNDS = 3;
20411
- var ASSISTANT_UPGRADE_FINISH_LOCK = path6.join("Temporary", "upgradeFinsh.lock");
20563
+ var ASSISTANT_UPGRADE_FINISH_LOCK = path7.join("Temporary", "upgradeFinsh.lock");
20412
20564
  async function installRuntimeTransaction(host, options) {
20413
20565
  if (!options.installerPath && options.installModules === false) {
20414
20566
  const baseRoot = options.installDir || await host.readRegistryInstallLocationRaw(options.config);
@@ -20436,10 +20588,11 @@ async function installRuntimeTransaction(host, options) {
20436
20588
  }
20437
20589
  }
20438
20590
  const installDir = options.installDir || host.getDefaultInstallPath();
20439
- const installerPath = options.installerPath || await downloadRuntimeInstaller(options.config, options.onProgress, options.installType || "full");
20591
+ const selectedInstaller = options.installerPath ? void 0 : options.installerDescriptor ?? await resolveAssistantInstallerDescriptor(options.config, options.installType || "full");
20592
+ const installerPath = options.installerPath || await downloadRuntimeInstaller(options.config, options.onProgress, options.installType || "full", selectedInstaller);
20440
20593
  fs6.mkdirSync(installDir, { recursive: true });
20441
- const installerLogPath = path6.join(installDir, "Temporary", "logs", "install.log");
20442
- fs6.mkdirSync(path6.dirname(installerLogPath), { recursive: true });
20594
+ const installerLogPath = path7.join(installDir, "Temporary", "logs", "install.log");
20595
+ fs6.mkdirSync(path7.dirname(installerLogPath), { recursive: true });
20443
20596
  options.onProgress?.(`\u6267\u884C\u5B89\u88C5\u7A0B\u5E8F: ${installerPath}`);
20444
20597
  const exitCode = await executeInstallerProcess(installerPath, installDir, installerLogPath);
20445
20598
  options.onProgress?.(`\u5B89\u88C5\u8FDB\u7A0B\u9000\u51FA\u7801: ${exitCode}`);
@@ -20454,6 +20607,12 @@ async function installRuntimeTransaction(host, options) {
20454
20607
  options.onProgress?.(`\u5B89\u88C5\u7A0B\u5E8F\u9000\u51FA\u7801\u975E 0\uFF0C\u4F46\u57FA\u7840 runtime \u6587\u4EF6\u5DF2\u5B58\u5728\uFF0C\u7EE7\u7EED\u521D\u59CB\u5316: ${exitCode}`);
20455
20608
  }
20456
20609
  const workRoot = options.installModules === false ? await verifyInstalledBaseRoot(host, installDir, options.config, options.verifyTimeoutMs ?? 10 * 6e4, options.onProgress) : await verifyInstalledWorkRoot(host, installDir, options.config, options.verifyTimeoutMs ?? 10 * 6e4, options.onProgress);
20610
+ if (selectedInstaller?.source === "dynamic") {
20611
+ const installedVersion = readInstalledAssistantBaseVersion(workRoot);
20612
+ if (!installedVersion || compareAssistantVersions(installedVersion, selectedInstaller.internalVersion) < 0) {
20613
+ throw new Error(`\u667A\u80FD\u7BA1\u5BB6\u5B89\u88C5\u540E\u7248\u672C\u4E0D\u6EE1\u8DB3\u6240\u9009\u5B89\u88C5\u5305: \u5F53\u524D ${installedVersion || "\u672A\u77E5"}\uFF0C\u6240\u9009 ${selectedInstaller.internalVersion}`);
20614
+ }
20615
+ }
20457
20616
  if (options.installModules !== false) {
20458
20617
  await initializeInstalledRuntimeTransaction(host, workRoot, options.config, {
20459
20618
  installModules: true,
@@ -20474,7 +20633,7 @@ async function upgradeOutdatedInstalledBase(host, workRoot, config2, onProgress)
20474
20633
  if (!verdict.updateAvailable)
20475
20634
  return null;
20476
20635
  if (verdict.blockedByPlugin) {
20477
- onProgress?.(`\u5DF2\u5B89\u88C5\u7684\u667A\u80FD\u7BA1\u5BB6\u672C\u4F53\u4E3A ${verdict.installed ?? "\u672A\u77E5"}\uFF0C\u8981\u6C42 ${verdict.required}\uFF0C\u9AD8\u4E8E\u672C\u63D2\u4EF6\u5185\u7F6E\u7684\u5B89\u88C5\u5305\uFF0C\u8BF7\u5347\u7EA7 ZLT Quant \u63D2\u4EF6\u540E\u91CD\u8BD5`);
20636
+ onProgress?.(`\u5DF2\u5B89\u88C5\u7684\u667A\u80FD\u7BA1\u5BB6\u672C\u4F53\u4E3A ${verdict.installed ?? "\u672A\u77E5"}\uFF0C\u8981\u6C42 ${verdict.required}\uFF0C\u9AD8\u4E8E\u5F53\u524D\u7248\u672C\u5217\u8868\u4E2D\u53EF\u7528\u7684\u5B89\u88C5\u5305\uFF0C\u8BF7\u7B49\u5F85\u5B89\u88C5\u5305\u7248\u672C\u5217\u8868\u66F4\u65B0\u540E\u91CD\u8BD5`);
20478
20637
  return null;
20479
20638
  }
20480
20639
  onProgress?.(`\u5DF2\u5B89\u88C5\u7684\u667A\u80FD\u7BA1\u5BB6\u672C\u4F53\u8FC7\u65E7\uFF08${verdict.installed ?? "\u672A\u77E5"} \u2192 ${verdict.required}\uFF09\uFF0C\u5148\u8986\u76D6\u5B89\u88C5\u672C\u4F53`);
@@ -20525,7 +20684,7 @@ async function installMissingBacktestModulesTransaction(host, workRoot, config2,
20525
20684
  if (moduleIndex !== clientModuleIndex && moduleIndex !== TY_MODULE_INDEX)
20526
20685
  return;
20527
20686
  if (moduleIndex === clientModuleIndex) {
20528
- fs6.rmSync(path6.join(workRoot, ASSISTANT_UPGRADE_FINISH_LOCK), { force: true });
20687
+ fs6.rmSync(path7.join(workRoot, ASSISTANT_UPGRADE_FINISH_LOCK), { force: true });
20529
20688
  }
20530
20689
  await quiesceTyModuleProcesses(workRoot, onProgress, (selected) => {
20531
20690
  stoppedPayloadProcesses = [...stoppedPayloadProcesses, ...selected];
@@ -20544,7 +20703,7 @@ async function installMissingBacktestModulesTransaction(host, workRoot, config2,
20544
20703
  } else {
20545
20704
  await installBacktestModules(workRoot, upgradedZltContent, config2, onProgress, installHooks);
20546
20705
  }
20547
- fs6.rmSync(path6.join(workRoot, ASSISTANT_UPGRADE_FINISH_LOCK), { force: true });
20706
+ fs6.rmSync(path7.join(workRoot, ASSISTANT_UPGRADE_FINISH_LOCK), { force: true });
20548
20707
  }
20549
20708
  } catch (error2) {
20550
20709
  if (runtimeStopped || stoppedPayloadProcesses.length > 0) {
@@ -20571,14 +20730,14 @@ function shouldInstallBacktestModules(workRoot, config2) {
20571
20730
  async function upgradeAssistantBaseTransaction(host, workRoot, config2, onProgress, options = {}) {
20572
20731
  const verdict = options.verdict ?? await checkAssistantBaseUpgrade(workRoot, config2, await host.readRegistryInstallType(config2));
20573
20732
  if (verdict.blockedByPlugin) {
20574
- throw new Error(`\u8FDC\u7A0B\u8981\u6C42\u7684\u667A\u80FD\u7BA1\u5BB6\u7248\u672C ${verdict.required} \u9AD8\u4E8E\u5F53\u524D\u63D2\u4EF6\u5185\u7F6E\u7684\u5B89\u88C5\u5305 ${verdict.pinnedVersion}\uFF0C\u8BF7\u5148\u5347\u7EA7 ZLT Quant \u63D2\u4EF6`);
20733
+ throw new Error(`\u8FDC\u7A0B\u8981\u6C42\u7684\u667A\u80FD\u7BA1\u5BB6\u7248\u672C ${verdict.required} \u9AD8\u4E8E\u5F53\u524D\u7248\u672C\u5217\u8868\u4E2D\u53EF\u7528\u7684\u5B89\u88C5\u5305 ${verdict.pinnedVersion}`);
20575
20734
  }
20576
20735
  if (!verdict.updateAvailable)
20577
20736
  return verdict.installed || "";
20578
20737
  onProgress?.(`\u51C6\u5907\u8986\u76D6\u5B89\u88C5\u667A\u80FD\u7BA1\u5BB6\u672C\u4F53: ${verdict.installed} \u2192 ${verdict.required}`);
20579
20738
  const stopped = await quiesceRuntimeForBaseUpgrade(workRoot, config2, onProgress);
20580
20739
  try {
20581
- const installerPath = await downloadRuntimeInstaller(config2, onProgress, verdict.installType);
20740
+ const installerPath = await downloadRuntimeInstaller(config2, onProgress, verdict.installType, verdict.installer);
20582
20741
  await installRuntimeTransaction(host, {
20583
20742
  config: config2,
20584
20743
  installerPath,
@@ -20617,14 +20776,14 @@ function ensurePythonToolchain(workRoot) {
20617
20776
  if (!fs6.existsSync(targetPython)) {
20618
20777
  throw new Error(`\u6295\u7814\u6A21\u5757\u5C1A\u672A\u4E0B\u53D1 Python \u8FD0\u884C\u65F6: ${targetPython}\u3002\u8BF7\u5728\u667A\u80FD\u7BA1\u5BB6\u4E2D\u5B89\u88C5\u6216\u4FEE\u590D\u6295\u7814\u6A21\u5757\u540E\u91CD\u8BD5\u3002`);
20619
20778
  }
20620
- const abiDll = path6.join(path6.dirname(targetPython), `python${PYTHON_SDK_ABI_TAG.replace(/^cp/, "")}.dll`);
20779
+ const abiDll = path7.join(path7.dirname(targetPython), `python${PYTHON_SDK_ABI_TAG.replace(/^cp/, "")}.dll`);
20621
20780
  if (!fs6.existsSync(abiDll)) {
20622
20781
  throw new Error(`\u6295\u7814\u6A21\u5757\u4E0B\u53D1\u7684 Python \u4E0E zltsdk-plugin \u7684 ${PYTHON_SDK_ABI_TAG} wheel ABI \u4E0D\u5339\u914D\uFF1A\u672A\u627E\u5230 ${abiDll}\u3002\u8BF7\u5728\u667A\u80FD\u7BA1\u5BB6\u4E2D\u91CD\u65B0\u5B89\u88C5\u6295\u7814\u6A21\u5757\u3002`);
20623
20782
  }
20624
20783
  return targetPython;
20625
20784
  }
20626
20785
  function toolchainDownloadCacheDir() {
20627
- return path6.join(os.tmpdir(), "zlt-runtime-toolchains");
20786
+ return path7.join(os.tmpdir(), "zlt-runtime-toolchains");
20628
20787
  }
20629
20788
  async function ensureVerifiedToolchainAsset(options) {
20630
20789
  const { label, url, sha256, destination, timeoutMs, onProgress } = options;
@@ -20646,8 +20805,8 @@ async function ensureVerifiedToolchainAsset(options) {
20646
20805
  onProgress?.(`${label} SHA256 \u6821\u9A8C\u901A\u8FC7: ${sha256}`);
20647
20806
  }
20648
20807
  async function ensureManagedPipWheel(workRoot, config2, onProgress) {
20649
- const destination = path6.join(toolchainDownloadCacheDir(), "pip-26.1.2-py3-none-any.whl");
20650
- fs6.mkdirSync(path6.dirname(destination), { recursive: true });
20808
+ const destination = path7.join(toolchainDownloadCacheDir(), "pip-26.1.2-py3-none-any.whl");
20809
+ fs6.mkdirSync(path7.dirname(destination), { recursive: true });
20651
20810
  await ensureVerifiedToolchainAsset({
20652
20811
  label: "pip 26.1.2 wheel",
20653
20812
  url: config2.pythonPipWheelUrl,
@@ -20668,27 +20827,27 @@ function assertFileSha256(filePath, expectedSha256) {
20668
20827
  async function quiesceTyModuleProcesses(workRoot, onProgress, onWillStop) {
20669
20828
  if (process.platform !== "win32")
20670
20829
  return [];
20671
- const managedCodePath = path6.resolve(workRoot, "vscode", "Code.exe");
20672
- const jsserviceRoot = `${path6.resolve(workRoot, "jsservice")}${path6.sep}`.toLowerCase();
20673
- const managedGitRoot = path6.resolve(workRoot, "mingit");
20830
+ const managedCodePath = path7.resolve(workRoot, "vscode", "Code.exe");
20831
+ const jsserviceRoot = `${path7.resolve(workRoot, "jsservice")}${path7.sep}`.toLowerCase();
20832
+ const managedGitRoot = path7.resolve(workRoot, "mingit");
20674
20833
  assertPathInside(workRoot, managedGitRoot);
20675
20834
  const executablePaths = [
20676
- path6.join(workRoot, "zltaf", "zltaf.exe"),
20677
- path6.join(workRoot, "python", "python.exe"),
20678
- path6.join(workRoot, "mingit", "cmd", "git.exe"),
20679
- path6.join(workRoot, "zltHost", "ZltDcmClient.exe"),
20835
+ path7.join(workRoot, "zltaf", "zltaf.exe"),
20836
+ path7.join(workRoot, "python", "python.exe"),
20837
+ path7.join(workRoot, "mingit", "cmd", "git.exe"),
20838
+ path7.join(workRoot, "zltHost", "ZltDcmClient.exe"),
20680
20839
  managedCodePath
20681
20840
  ].map((candidate) => {
20682
- const resolved = path6.resolve(candidate);
20841
+ const resolved = path7.resolve(candidate);
20683
20842
  assertPathInside(workRoot, resolved);
20684
20843
  return resolved;
20685
20844
  });
20686
20845
  const installedExecutablePaths = executablePaths.filter((candidate) => fs6.existsSync(candidate));
20687
- const installedExecutableRoots = fs6.existsSync(managedGitRoot) ? [`${managedGitRoot}${path6.sep}`] : [];
20846
+ const installedExecutableRoots = fs6.existsSync(managedGitRoot) ? [`${managedGitRoot}${path7.sep}`] : [];
20688
20847
  if (installedExecutablePaths.length === 0 && installedExecutableRoots.length === 0)
20689
20848
  return [];
20690
20849
  const selectTyPayloadProcesses = () => listManagedRuntimeProcesses(installedExecutablePaths, installedExecutableRoots).filter((item) => {
20691
- if (path6.resolve(item.executablePath).toLowerCase() !== managedCodePath.toLowerCase())
20850
+ if (path7.resolve(item.executablePath).toLowerCase() !== managedCodePath.toLowerCase())
20692
20851
  return true;
20693
20852
  const commandLine = item.commandLine.replaceAll("/", "\\").toLowerCase();
20694
20853
  return commandLine.includes(jsserviceRoot) && commandLine.includes("--ms-enable-electron-run-as-node");
@@ -20746,12 +20905,12 @@ async function stopManagedRuntimeProcesses(workRoot, config2, onProgress, messag
20746
20905
  if (process.platform !== "win32")
20747
20906
  return [];
20748
20907
  const executablePaths = [
20749
- path6.join(workRoot, config2.hostPath),
20750
- path6.join(workRoot, config2.backservicePath),
20751
- path6.join(workRoot, "zltHost", "zlthost.exe"),
20752
- path6.join(workRoot, "zltaf", "zltaf.exe")
20908
+ path7.join(workRoot, config2.hostPath),
20909
+ path7.join(workRoot, config2.backservicePath),
20910
+ path7.join(workRoot, "zltHost", "zlthost.exe"),
20911
+ path7.join(workRoot, "zltaf", "zltaf.exe")
20753
20912
  ].map((candidate) => {
20754
- const resolved = path6.resolve(candidate);
20913
+ const resolved = path7.resolve(candidate);
20755
20914
  assertPathInside(workRoot, resolved);
20756
20915
  return resolved;
20757
20916
  });
@@ -20768,7 +20927,7 @@ async function stopManagedRuntimeProcesses(workRoot, config2, onProgress, messag
20768
20927
  throw new Error(`${messages.failed}: ${formatManagedProcessList(remaining)}\u3002\u8BF7\u5173\u95ED\u667A\u91CF\u901A\u76F8\u5173\u4EFB\u52A1\u540E\u91CD\u8BD5\u5B89\u88C5\u3002`);
20769
20928
  }
20770
20929
  }
20771
- const zltMarker = path6.resolve(workRoot, config2.temporaryZltFile || "Temporary/zlt");
20930
+ const zltMarker = path7.resolve(workRoot, config2.temporaryZltFile || "Temporary/zlt");
20772
20931
  assertPathInside(workRoot, zltMarker);
20773
20932
  fs6.rmSync(zltMarker, { force: true });
20774
20933
  if (running.length > 0)
@@ -20779,6 +20938,7 @@ function killManagedRuntimeProcesses(running) {
20779
20938
  const taskkill = windowsSystemToolPath("taskkill.exe");
20780
20939
  for (const item of running) {
20781
20940
  (0, import_child_process3.spawnSync)(taskkill, ["/PID", String(item.pid), "/T", "/F"], {
20941
+ stdio: ["ignore", "pipe", "pipe"],
20782
20942
  encoding: "utf8",
20783
20943
  timeout: 15e3,
20784
20944
  windowsHide: true
@@ -20812,6 +20972,7 @@ function listManagedRuntimeProcesses(executablePaths, executableRoots = []) {
20812
20972
  "-Command",
20813
20973
  command
20814
20974
  ], {
20975
+ stdio: ["ignore", "pipe", "pipe"],
20815
20976
  encoding: "utf8",
20816
20977
  env: { ...process.env, ZLT_MANAGED_RUNTIME_PATHS: encodedPaths },
20817
20978
  timeout: 15e3,
@@ -20840,7 +21001,7 @@ ${result.stderr || ""}`);
20840
21001
  return [];
20841
21002
  return [{
20842
21003
  pid,
20843
- name: typeof item.Name === "string" ? item.Name : path6.basename(item.ExecutablePath),
21004
+ name: typeof item.Name === "string" ? item.Name : path7.basename(item.ExecutablePath),
20844
21005
  executablePath: item.ExecutablePath,
20845
21006
  commandLine: typeof item.CommandLine === "string" ? item.CommandLine : ""
20846
21007
  }];
@@ -20848,10 +21009,10 @@ ${result.stderr || ""}`);
20848
21009
  }
20849
21010
  function windowsSystemToolPath(relativePath) {
20850
21011
  const systemRoot = process.env.SystemRoot || process.env.WINDIR;
20851
- if (!systemRoot || !path6.isAbsolute(systemRoot)) {
21012
+ if (!systemRoot || !path7.isAbsolute(systemRoot)) {
20852
21013
  throw new Error("\u65E0\u6CD5\u5B89\u5168\u5B9A\u4F4D Windows \u7CFB\u7EDF\u5DE5\u5177: SystemRoot \u672A\u8BBE\u7F6E");
20853
21014
  }
20854
- return path6.join(systemRoot, "System32", ...relativePath.split("/"));
21015
+ return path7.join(systemRoot, "System32", ...relativePath.split("/"));
20855
21016
  }
20856
21017
  function ensureGitToolchain(workRoot) {
20857
21018
  const targetGit = getGitExePath(workRoot);
@@ -20896,6 +21057,7 @@ function validatePythonSdkComplete(workRoot, config2) {
20896
21057
  "sys.exit(1 if missing else 0)"
20897
21058
  ].join("\n");
20898
21059
  const result = (0, import_child_process3.spawnSync)(pythonPath, ["-c", probe, JSON.stringify(pinned), JSON.stringify(imports)], {
21060
+ stdio: ["ignore", "pipe", "pipe"],
20899
21061
  encoding: "utf8",
20900
21062
  timeout: config2.pythonSdkImportTimeout,
20901
21063
  windowsHide: true
@@ -21003,22 +21165,29 @@ function buildManagedPipEnvironment(runtimeIndexUrl, baseEnvironment = process.e
21003
21165
  no_proxy: noProxy
21004
21166
  };
21005
21167
  }
21006
- async function downloadRuntimeInstaller(config2, onProgress, installType = "full") {
21007
- const url = resolveAssistantDownloadUrl(config2, installType);
21008
- const sha256 = resolveAssistantDownloadSha256(config2, installType);
21009
- const filename = path6.basename(new URL(url).pathname) || "zlt-runtime-installer.exe";
21010
- const dir = path6.join(os.tmpdir(), config2.downloadTempDir);
21011
- const destination = path6.join(dir, filename);
21168
+ async function downloadRuntimeInstaller(config2, onProgress, installType = "full", descriptor) {
21169
+ const selected = descriptor ?? await resolveAssistantInstallerDescriptor(config2, installType);
21170
+ const url = selected.url || resolveAssistantDownloadUrl(config2, installType);
21171
+ if (selected.source === "pinned" && !/^[a-fA-F0-9]{64}$/.test(selected.sha256 || "")) {
21172
+ throw new Error(`\u5F53\u524D\u73AF\u5883\u6A21\u5F0F ${config2.envMode} \u672A\u914D\u7F6E ${installType} \u5B89\u88C5\u5305 SHA256`);
21173
+ }
21174
+ const filename = selected.fileName || path7.basename(new URL(url).pathname) || "zlt-runtime-installer.exe";
21175
+ const dir = path7.join(os.tmpdir(), config2.downloadTempDir);
21176
+ const destination = path7.join(dir, filename);
21012
21177
  fs6.mkdirSync(dir, { recursive: true });
21013
21178
  onProgress?.(`\u4E0B\u8F7D\u5B89\u88C5\u5305: ${url}`);
21179
+ if (selected.fallbackReason)
21180
+ onProgress?.(`\u52A8\u6001\u5B89\u88C5\u5305\u4E0D\u53EF\u7528\uFF0C\u4F7F\u7528\u5185\u7F6E fallback: ${selected.fallbackReason}`);
21014
21181
  await downloadFile(url, destination);
21015
21182
  try {
21016
- assertFileSha256(destination, sha256);
21183
+ if (selected.source !== "dynamic") {
21184
+ assertFileSha256(destination, selected.sha256 || resolveAssistantDownloadSha256(config2, installType));
21185
+ }
21017
21186
  } catch (error2) {
21018
21187
  fs6.rmSync(destination, { force: true });
21019
21188
  throw error2;
21020
21189
  }
21021
- onProgress?.(`\u5B89\u88C5\u5305 SHA256 \u6821\u9A8C\u901A\u8FC7: ${sha256}`);
21190
+ onProgress?.(selected.source === "dynamic" ? `\u5B89\u88C5\u5305\u5DF2\u4E0B\u8F7D\uFF08\u7248\u672C\u5217\u8868 fileSize \u4EC5\u4F9B\u5C55\u793A: ${selected.fileSize ?? "\u672A\u63D0\u4F9B"}\uFF09` : `\u5B89\u88C5\u5305 SHA256 \u6821\u9A8C\u901A\u8FC7: ${selected.sha256}`);
21022
21191
  return destination;
21023
21192
  }
21024
21193
  function describeInstallerExitCode(exitCode) {
@@ -21151,7 +21320,7 @@ function downloadFile(url, destination, redirectCount = 0, timeoutMs = 0, initia
21151
21320
  if (redirectCount > 5) {
21152
21321
  return Promise.reject(new Error(`\u4E0B\u8F7D\u91CD\u5B9A\u5411\u8FC7\u591A: ${url}`));
21153
21322
  }
21154
- fs6.mkdirSync(path6.dirname(destination), { recursive: true });
21323
+ fs6.mkdirSync(path7.dirname(destination), { recursive: true });
21155
21324
  const partialPath = `${destination}.${process.pid}.${(0, import_crypto3.randomUUID)()}.part`;
21156
21325
  return new Promise((resolve12, reject) => {
21157
21326
  let settled = false;
@@ -21237,10 +21406,10 @@ function delay(ms) {
21237
21406
  return new Promise((resolve12) => setTimeout(resolve12, ms));
21238
21407
  }
21239
21408
  function getPythonExePath(workRoot) {
21240
- return path6.join(workRoot, "python", "python.exe");
21409
+ return path7.join(workRoot, "python", "python.exe");
21241
21410
  }
21242
21411
  function getGitExePath(workRoot) {
21243
- return path6.join(workRoot, "mingit", "cmd", "git.exe");
21412
+ return path7.join(workRoot, "mingit", "cmd", "git.exe");
21244
21413
  }
21245
21414
  function resolveManagedPythonExe(workRoot) {
21246
21415
  return getPythonExePath(workRoot || getDefaultInstallPath());
@@ -21258,19 +21427,19 @@ function getDefaultInstallPath() {
21258
21427
  if (process.platform === "win32") {
21259
21428
  return fs6.existsSync("D:\\") ? "D:\\ZLTClient" : "C:\\ZLTClient";
21260
21429
  }
21261
- return path6.join(os.homedir(), "ZLTClient");
21430
+ return path7.join(os.homedir(), "ZLTClient");
21262
21431
  }
21263
21432
  function getZltafExePath(workRoot) {
21264
- return path6.join(workRoot, "zltaf", "zltaf.exe");
21433
+ return path7.join(workRoot, "zltaf", "zltaf.exe");
21265
21434
  }
21266
21435
  function getZltafConfigPath(workRoot) {
21267
- return path6.join(workRoot, "zltaf", "application-local.properties");
21436
+ return path7.join(workRoot, "zltaf", "application-local.properties");
21268
21437
  }
21269
21438
  function assertPathInside(root2, targetPath) {
21270
- const resolvedRoot = path6.resolve(root2);
21271
- const resolvedTarget = path6.resolve(targetPath);
21272
- const relative2 = path6.relative(resolvedRoot, resolvedTarget);
21273
- if (relative2.startsWith("..") || path6.isAbsolute(relative2)) {
21439
+ const resolvedRoot = path7.resolve(root2);
21440
+ const resolvedTarget = path7.resolve(targetPath);
21441
+ const relative2 = path7.relative(resolvedRoot, resolvedTarget);
21442
+ if (relative2.startsWith("..") || path7.isAbsolute(relative2)) {
21274
21443
  throw new Error(`\u62D2\u7EDD\u5199\u5165\u5B89\u88C5\u76EE\u5F55\u5916\u8DEF\u5F84: ${resolvedTarget}`);
21275
21444
  }
21276
21445
  }
@@ -21286,7 +21455,7 @@ function normalizeRequiredPythonPackages(config2) {
21286
21455
  function areBundledSitePackagesPresent(workRoot, packages) {
21287
21456
  if (packages.some(hasPythonVersionSpecifier))
21288
21457
  return false;
21289
- const sitePackages = path6.join(workRoot, "python", "Lib", "site-packages");
21458
+ const sitePackages = path7.join(workRoot, "python", "Lib", "site-packages");
21290
21459
  if (!fs6.existsSync(sitePackages))
21291
21460
  return false;
21292
21461
  let entries = [];
@@ -21300,10 +21469,10 @@ function areBundledSitePackagesPresent(workRoot, packages) {
21300
21469
  const normalized = normalizePythonPackageName(requirementName);
21301
21470
  const importName = pythonDistributionImportName(packageName);
21302
21471
  const candidateFiles = [
21303
- path6.join(sitePackages, requirementName, "__init__.py"),
21304
- path6.join(sitePackages, `${requirementName}.py`),
21305
- path6.join(sitePackages, importName, "__init__.py"),
21306
- path6.join(sitePackages, `${importName}.py`)
21472
+ path7.join(sitePackages, requirementName, "__init__.py"),
21473
+ path7.join(sitePackages, `${requirementName}.py`),
21474
+ path7.join(sitePackages, importName, "__init__.py"),
21475
+ path7.join(sitePackages, `${importName}.py`)
21307
21476
  ];
21308
21477
  return candidateFiles.some((candidate) => fs6.existsSync(candidate)) || entries.some((entry) => entry.startsWith(`${normalized}-`) && (entry.endsWith(".dist-info") || entry.endsWith(".egg-info")));
21309
21478
  });
@@ -21334,7 +21503,7 @@ function getDefaultInstallPath2() {
21334
21503
  if (process.platform === "win32") {
21335
21504
  return fs7.existsSync("D:\\") ? "D:\\ZLTClient" : "C:\\ZLTClient";
21336
21505
  }
21337
- return path7.join(os2.homedir(), "ZLTClient");
21506
+ return path8.join(os2.homedir(), "ZLTClient");
21338
21507
  }
21339
21508
  function validateWorkRootComplete(workRoot, _config) {
21340
21509
  if (!fs7.existsSync(workRoot)) {
@@ -21354,7 +21523,7 @@ function validateWorkRootComplete(workRoot, _config) {
21354
21523
  function validateAssistantBaseComplete(workRoot, config2) {
21355
21524
  if (!fs7.existsSync(workRoot))
21356
21525
  return { complete: false, reason: `\u5DE5\u7A0B\u8DEF\u5F84\u4E0D\u5B58\u5728: ${workRoot}` };
21357
- const hostPath = path7.join(workRoot, config2.hostPath);
21526
+ const hostPath = path8.join(workRoot, config2.hostPath);
21358
21527
  return fs7.existsSync(hostPath) ? { complete: true } : { complete: false, reason: `\u7F3A\u5C11\u667A\u80FD\u7BA1\u5BB6\u7A0B\u5E8F: ${hostPath}` };
21359
21528
  }
21360
21529
  function validateDependencyWorkRootComplete(workRoot, config2) {
@@ -21379,7 +21548,7 @@ function validateRuntimeLaunchReady(workRoot, config2) {
21379
21548
  return { complete: true };
21380
21549
  }
21381
21550
  function ensureUsersProjectsDirectory(workRoot) {
21382
- const projectsDir = path7.join(workRoot, "Users", "projects");
21551
+ const projectsDir = path8.join(workRoot, "Users", "projects");
21383
21552
  if (fs7.existsSync(projectsDir)) {
21384
21553
  if (!fs7.statSync(projectsDir).isDirectory()) {
21385
21554
  throw new Error(`Users\\projects \u8DEF\u5F84\u5DF2\u5B58\u5728\u4F46\u4E0D\u662F\u76EE\u5F55: ${projectsDir}`);
@@ -21425,7 +21594,7 @@ async function resolveRuntimeRoot(config2, options = {}) {
21425
21594
  const workRoot = candidate?.trim();
21426
21595
  if (!workRoot)
21427
21596
  continue;
21428
- const key = path7.resolve(workRoot).toLowerCase();
21597
+ const key = path8.resolve(workRoot).toLowerCase();
21429
21598
  if (seen.has(key))
21430
21599
  continue;
21431
21600
  seen.add(key);
@@ -21468,7 +21637,7 @@ async function runDoctor(config2, options = {}) {
21468
21637
  }
21469
21638
  const assistant = workRoot ? validateWorkRootComplete(workRoot, config2) : { complete: false, reason: "\u672A\u53D1\u73B0\u53EF\u7528 InstallLocation" };
21470
21639
  const dependency = workRoot ? validateDependencyWorkRootComplete(workRoot, config2) : { complete: false, reason: "\u672A\u53D1\u73B0\u53EF\u7528 InstallLocation" };
21471
- const zltFile = workRoot ? path7.join(workRoot, config2.temporaryZltFile) : void 0;
21640
+ const zltFile = workRoot ? path8.join(workRoot, config2.temporaryZltFile) : void 0;
21472
21641
  let pipePath;
21473
21642
  let ipcReachable = false;
21474
21643
  const explicitPipeName = process.env.ZLT_PIPE_NAME?.trim();
@@ -21517,13 +21686,13 @@ function startZltafRuntime(workRoot, config2) {
21517
21686
  if (!fs7.existsSync(configPath)) {
21518
21687
  throw new Error(`ZLTAF \u914D\u7F6E\u4E0D\u5B58\u5728: ${configPath}`);
21519
21688
  }
21520
- const tmpDir = path7.join(workRoot, "zltaf", "tmp");
21689
+ const tmpDir = path8.join(workRoot, "zltaf", "tmp");
21521
21690
  fs7.mkdirSync(tmpDir, { recursive: true });
21522
21691
  const child = (0, import_child_process4.spawn)(zltafPath, [
21523
21692
  `-Dconfig.path=${configPath}`,
21524
21693
  `-Djava.io.tmpdir=${tmpDir}`
21525
21694
  ], {
21526
- cwd: path7.dirname(zltafPath),
21695
+ cwd: path8.dirname(zltafPath),
21527
21696
  detached: true,
21528
21697
  stdio: "ignore",
21529
21698
  windowsHide: true
@@ -21588,15 +21757,15 @@ async function ensureAssistantHostRunning(workRoot, config2, onProgress, options
21588
21757
  if (zltContent && masterPipeExists(zltContent))
21589
21758
  return zltContent;
21590
21759
  }
21591
- throw new Error(`\u7B49\u5F85\u667A\u80FD\u7BA1\u5BB6 IPC \u914D\u7F6E\u8D85\u65F6\uFF08\u540E\u7F00\u6587\u4EF6\u6216\u4E3B\u7BA1\u9053\u672A\u5C31\u7EEA\uFF09: ${path7.join(workRoot, config2.temporaryZltFile)}`);
21760
+ throw new Error(`\u7B49\u5F85\u667A\u80FD\u7BA1\u5BB6 IPC \u914D\u7F6E\u8D85\u65F6\uFF08\u540E\u7F00\u6587\u4EF6\u6216\u4E3B\u7BA1\u9053\u672A\u5C31\u7EEA\uFF09: ${path8.join(workRoot, config2.temporaryZltFile)}`);
21592
21761
  }
21593
- var ASSISTANT_UPGRADE_FINISH_LOCK2 = path7.join("Temporary", "upgradeFinsh.lock");
21762
+ var ASSISTANT_UPGRADE_FINISH_LOCK2 = path8.join("Temporary", "upgradeFinsh.lock");
21594
21763
  function launchAssistantHost(workRoot, config2, onProgress) {
21595
- const hostPath = path7.join(workRoot, config2.hostPath);
21764
+ const hostPath = path8.join(workRoot, config2.hostPath);
21596
21765
  onProgress?.("\u542F\u52A8\u667A\u80FD\u7BA1\u5BB6");
21597
21766
  const { ELECTRON_RUN_AS_NODE: _dropped, ...env } = process.env;
21598
21767
  const child = (0, import_child_process4.spawn)(hostPath, ["startwithplugin", "selfstart"], {
21599
- cwd: path7.dirname(hostPath),
21768
+ cwd: path8.dirname(hostPath),
21600
21769
  detached: true,
21601
21770
  stdio: "ignore",
21602
21771
  windowsHide: true,
@@ -21613,7 +21782,7 @@ async function locateInstalledRuntime(config2) {
21613
21782
  return workRoot;
21614
21783
  }
21615
21784
  async function waitForUpgradedAssistantClient(workRoot, config2, onProgress, versionBefore) {
21616
- const finishLockPath = path7.join(workRoot, ASSISTANT_UPGRADE_FINISH_LOCK2);
21785
+ const finishLockPath = path8.join(workRoot, ASSISTANT_UPGRADE_FINISH_LOCK2);
21617
21786
  const finishStartedAt = Date.now();
21618
21787
  const versionRaised = () => {
21619
21788
  if (!versionBefore)
@@ -21676,21 +21845,21 @@ function delay2(ms) {
21676
21845
  return delay(ms);
21677
21846
  }
21678
21847
  function getZltafExePath2(workRoot) {
21679
- return path7.join(workRoot, "zltaf", "zltaf.exe");
21848
+ return path8.join(workRoot, "zltaf", "zltaf.exe");
21680
21849
  }
21681
21850
  function getZltafConfigPath2(workRoot) {
21682
- return path7.join(workRoot, "zltaf", "application-local.properties");
21851
+ return path8.join(workRoot, "zltaf", "application-local.properties");
21683
21852
  }
21684
21853
  function resolveZltafLaunchConfigPath(workRoot, config2) {
21685
21854
  if (config2.zltafConfigFile === ZLTAF_CONFIG_FILE_DEFAULT) {
21686
21855
  return getZltafConfigPath2(workRoot);
21687
21856
  }
21688
- const preferred = path7.join(workRoot, "zltaf", config2.zltafConfigFile);
21857
+ const preferred = path8.join(workRoot, "zltaf", config2.zltafConfigFile);
21689
21858
  if (fs7.existsSync(preferred)) {
21690
21859
  return preferred;
21691
21860
  }
21692
21861
  const base = getZltafConfigPath2(workRoot);
21693
- process.stderr.write(`[zlt-runtime] ZLTAF \u914D\u7F6E ${config2.zltafConfigFile} \u4E0D\u5B58\u5728\uFF0C\u56DE\u9000\u5230 ${path7.basename(base)}
21862
+ process.stderr.write(`[zlt-runtime] ZLTAF \u914D\u7F6E ${config2.zltafConfigFile} \u4E0D\u5B58\u5728\uFF0C\u56DE\u9000\u5230 ${path8.basename(base)}
21694
21863
  `);
21695
21864
  return base;
21696
21865
  }
@@ -21715,7 +21884,7 @@ async function waitForZltafPipe(workRoot, config2, options) {
21715
21884
  // ../zlt-runtime-core/dist/auth.js
21716
21885
  var fs9 = __toESM(require("fs"), 1);
21717
21886
  var os3 = __toESM(require("os"), 1);
21718
- var path8 = __toESM(require("path"), 1);
21887
+ var path9 = __toESM(require("path"), 1);
21719
21888
 
21720
21889
  // ../zlt-runtime-core/dist/private-path.js
21721
21890
  var fs8 = __toESM(require("node:fs"), 1);
@@ -21766,13 +21935,13 @@ function resolveZltQuantHome(env = process.env) {
21766
21935
  const configuredHome = env.ZLTQUANT_HOME?.trim();
21767
21936
  if (configuredHome)
21768
21937
  return expandHome(configuredHome);
21769
- return path8.join(os3.homedir(), ".zltquant");
21938
+ return path9.join(os3.homedir(), ".zltquant");
21770
21939
  }
21771
21940
  function resolveCredentialsPath(env = process.env) {
21772
21941
  const configuredPath = env.ZLTQUANT_CREDENTIALS?.trim();
21773
21942
  if (configuredPath)
21774
21943
  return expandHome(configuredPath);
21775
- return path8.join(resolveZltQuantHome(env), "credentials.json");
21944
+ return path9.join(resolveZltQuantHome(env), "credentials.json");
21776
21945
  }
21777
21946
  function readCredentials(env = process.env) {
21778
21947
  const credentialsPath = resolveCredentialsPath(env);
@@ -21821,7 +21990,7 @@ function writeCredentials(input, env = process.env) {
21821
21990
  source,
21822
21991
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
21823
21992
  };
21824
- fs9.mkdirSync(path8.dirname(credentialsPath), { recursive: true });
21993
+ fs9.mkdirSync(path9.dirname(credentialsPath), { recursive: true });
21825
21994
  const tempPath = `${credentialsPath}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`;
21826
21995
  try {
21827
21996
  if (source === "zlt-mcp-device-login") {
@@ -21928,9 +22097,9 @@ function expandHome(input) {
21928
22097
  if (input === "~")
21929
22098
  return os3.homedir();
21930
22099
  if (input.startsWith("~/") || input.startsWith("~\\")) {
21931
- return path8.join(os3.homedir(), input.slice(2));
22100
+ return path9.join(os3.homedir(), input.slice(2));
21932
22101
  }
21933
- return path8.resolve(input);
22102
+ return path9.resolve(input);
21934
22103
  }
21935
22104
  function tryReadCredentials(env) {
21936
22105
  try {
@@ -22040,7 +22209,7 @@ function persistDeviceAuthorization(grant, env) {
22040
22209
  throw new DeviceAuthorizationError("credentials_conflict", "Persisted device credential is not effective");
22041
22210
  return { status: "success", authStatus: authStatus2 };
22042
22211
  }
22043
- async function requestJson(options, base, path27, payload, allowPoll400 = false) {
22212
+ async function requestJson(options, base, path28, payload, allowPoll400 = false) {
22044
22213
  const controller = new AbortController();
22045
22214
  const externalAbort = () => controller.abort();
22046
22215
  if (options.signal?.aborted)
@@ -22049,7 +22218,7 @@ async function requestJson(options, base, path27, payload, allowPoll400 = false)
22049
22218
  options.signal?.addEventListener("abort", externalAbort, { once: true });
22050
22219
  const timeout = setTimeout(() => controller.abort(), options.requestTimeoutMs ?? 15e3);
22051
22220
  try {
22052
- const response = await (options.fetch ?? globalThis.fetch)(new URL(path27, base), {
22221
+ const response = await (options.fetch ?? globalThis.fetch)(new URL(path28, base), {
22053
22222
  method: "POST",
22054
22223
  redirect: "error",
22055
22224
  headers: { "content-type": "application/json" },
@@ -22183,7 +22352,7 @@ var import_node_crypto = require("node:crypto");
22183
22352
  var fs10 = __toESM(require("node:fs"), 1);
22184
22353
  var net2 = __toESM(require("node:net"), 1);
22185
22354
  var os4 = __toESM(require("node:os"), 1);
22186
- var path9 = __toESM(require("node:path"), 1);
22355
+ var path10 = __toESM(require("node:path"), 1);
22187
22356
  function urlEncode(value) {
22188
22357
  let result = "";
22189
22358
  for (const code of Buffer.from(value, "utf8")) {
@@ -22336,7 +22505,7 @@ var ZltafHttpPacket = class {
22336
22505
  }
22337
22506
  }
22338
22507
  };
22339
- var LOG_FILE = path9.join(os4.tmpdir(), "zlt-mcp-proxy.log");
22508
+ var LOG_FILE = path10.join(os4.tmpdir(), "zlt-mcp-proxy.log");
22340
22509
  var pendingLogLines = [];
22341
22510
  var logWriteInFlight = false;
22342
22511
  function log(tag, message) {
@@ -22535,17 +22704,17 @@ __export(config_exports, {
22535
22704
  resolveDefaultRuntimeConfigPath: () => resolveDefaultRuntimeConfigPath
22536
22705
  });
22537
22706
  var fs11 = __toESM(require("fs"), 1);
22538
- var path10 = __toESM(require("path"), 1);
22707
+ var path11 = __toESM(require("path"), 1);
22539
22708
  function loadConfig(configPath) {
22540
22709
  const raw = fs11.readFileSync(configPath, "utf-8");
22541
22710
  return JSON.parse(raw);
22542
22711
  }
22543
22712
  function resolveDefaultConfigPath() {
22544
22713
  if (process.env.ZLT_MCP_CONFIG) return process.env.ZLT_MCP_CONFIG;
22545
- const cwdCandidate = path10.resolve(process.cwd(), "config.json");
22714
+ const cwdCandidate = path11.resolve(process.cwd(), "config.json");
22546
22715
  const candidates = [
22547
- path10.resolve(path10.dirname(process.argv[1] || ""), "..", "config.json"),
22548
- path10.resolve(path10.dirname(process.argv[1] || ""), "config.json"),
22716
+ path11.resolve(path11.dirname(process.argv[1] || ""), "..", "config.json"),
22717
+ path11.resolve(path11.dirname(process.argv[1] || ""), "config.json"),
22549
22718
  cwdCandidate
22550
22719
  ];
22551
22720
  for (const candidate of candidates) {
@@ -22556,9 +22725,9 @@ function resolveDefaultConfigPath() {
22556
22725
  function resolveDefaultRuntimeConfigPath() {
22557
22726
  if (process.env.ZLT_RUNTIME_CONFIG) return process.env.ZLT_RUNTIME_CONFIG;
22558
22727
  const candidates = [
22559
- path10.resolve(path10.dirname(process.argv[1] || ""), "..", "runtime.cfg.json"),
22560
- path10.resolve(path10.dirname(process.argv[1] || ""), "runtime.cfg.json"),
22561
- path10.resolve(process.cwd(), "runtime.cfg.json")
22728
+ path11.resolve(path11.dirname(process.argv[1] || ""), "..", "runtime.cfg.json"),
22729
+ path11.resolve(path11.dirname(process.argv[1] || ""), "runtime.cfg.json"),
22730
+ path11.resolve(process.cwd(), "runtime.cfg.json")
22562
22731
  ];
22563
22732
  return candidates.find((candidate) => fs11.existsSync(candidate));
22564
22733
  }
@@ -22595,7 +22764,7 @@ function hasHighBytes(str) {
22595
22764
 
22596
22765
  // src/download-verification.ts
22597
22766
  var fs12 = __toESM(require("node:fs"), 1);
22598
- var path11 = __toESM(require("node:path"), 1);
22767
+ var path12 = __toESM(require("node:path"), 1);
22599
22768
  var MAX_INVENTORY_ENTRIES = 25e3;
22600
22769
  var MAX_INVENTORY_DEPTH = 8;
22601
22770
  var SAFE_SEGMENT = /^[A-Za-z0-9_-]+$/;
@@ -22692,11 +22861,11 @@ async function downloadAndVerify(args, invoke, inventory, onUuid) {
22692
22861
  }
22693
22862
  function configuredDownloadHome(clientRootDir) {
22694
22863
  try {
22695
- const configPath = path11.join(clientRootDir, "zltHost", "moudles", "dcm.json");
22864
+ const configPath = path12.join(clientRootDir, "zltHost", "moudles", "dcm.json");
22696
22865
  const config2 = JSON.parse(fs12.readFileSync(configPath, "utf8"));
22697
22866
  if (!isRecord2(config2) || typeof config2.download_home !== "string" || !config2.download_home.trim()) return null;
22698
22867
  const expanded = config2.download_home.trim().replace(/%HomePath%/gi, clientRootDir);
22699
- return path11.isAbsolute(expanded) ? path11.resolve(expanded) : path11.resolve(clientRootDir, expanded);
22868
+ return path12.isAbsolute(expanded) ? path12.resolve(expanded) : path12.resolve(clientRootDir, expanded);
22700
22869
  } catch {
22701
22870
  return null;
22702
22871
  }
@@ -22705,7 +22874,7 @@ function diskSpaceDownloadHome(result) {
22705
22874
  const data = dataRecord(result);
22706
22875
  if (!data) return null;
22707
22876
  const value = data.download_home ?? data.downloadHome;
22708
- return typeof value === "string" && value.trim() ? path11.resolve(value.trim()) : null;
22877
+ return typeof value === "string" && value.trim() ? path12.resolve(value.trim()) : null;
22709
22878
  }
22710
22879
  function requestedScopes(params) {
22711
22880
  if (!Array.isArray(params) || params.length === 0) return null;
@@ -22732,7 +22901,7 @@ function inventoryDownloadedFiles(clientRootDir, params, diskSpace, limits = {})
22732
22901
  if (!configured) return unknown2("download-home-config-unavailable");
22733
22902
  const reported = diskSpaceDownloadHome(diskSpace);
22734
22903
  if (!reported) return unknown2("disk-space-download-home-unavailable", configured);
22735
- if (path11.resolve(configured).toLowerCase() !== path11.resolve(reported).toLowerCase()) return unknown2("download-home-mismatch", configured);
22904
+ if (path12.resolve(configured).toLowerCase() !== path12.resolve(reported).toLowerCase()) return unknown2("download-home-mismatch", configured);
22736
22905
  const scopes = requestedScopes(params);
22737
22906
  if (!scopes) return unknown2("invalid-request-scope", configured);
22738
22907
  if (scopes.some((scope) => !scope.exchangeId || !/^(dk|mk|tk)[a-z0-9_-]*$/.test(scope.dataType))) {
@@ -22759,7 +22928,7 @@ function inventoryDownloadedFiles(clientRootDir, params, diskSpace, limits = {})
22759
22928
  let candidate = root2;
22760
22929
  let present = true;
22761
22930
  for (const segment of ["hqdata", lane, scope.exchangeId, scope.dataType]) {
22762
- candidate = path11.join(candidate, segment);
22931
+ candidate = path12.join(candidate, segment);
22763
22932
  let component;
22764
22933
  try {
22765
22934
  component = fs12.lstatSync(candidate);
@@ -22786,7 +22955,7 @@ function inventoryDownloadedFiles(clientRootDir, params, diskSpace, limits = {})
22786
22955
  for (const entry of fs12.readdirSync(current.dir, { withFileTypes: true })) {
22787
22956
  entries += 1;
22788
22957
  if (entries > (limits.maxEntries ?? MAX_INVENTORY_ENTRIES)) return unknown2("inventory-entry-limit", configured);
22789
- const full = path11.join(current.dir, entry.name);
22958
+ const full = path12.join(current.dir, entry.name);
22790
22959
  if (entry.isSymbolicLink()) return unknown2("symlink-or-reparse-point", configured);
22791
22960
  const stat = fs12.lstatSync(full);
22792
22961
  const attrs = stat.attributes;
@@ -22809,7 +22978,7 @@ function inventoryDownloadedFiles(clientRootDir, params, diskSpace, limits = {})
22809
22978
  // src/local-auth-guard.ts
22810
22979
  var fs13 = __toESM(require("node:fs"), 1);
22811
22980
  var os5 = __toESM(require("node:os"), 1);
22812
- var path12 = __toESM(require("node:path"), 1);
22981
+ var path13 = __toESM(require("node:path"), 1);
22813
22982
  var RECOVERY_HANDLERS = /* @__PURE__ */ new Set([
22814
22983
  "currentUser",
22815
22984
  "runtimeDoctor",
@@ -22822,8 +22991,8 @@ function resolveLocalCredentialsPath(env = process.env) {
22822
22991
  const configuredPath = env.ZLTQUANT_CREDENTIALS?.trim();
22823
22992
  if (configuredPath) return expandHome2(configuredPath);
22824
22993
  const configuredHome = env.ZLTQUANT_HOME?.trim();
22825
- const home = configuredHome ? expandHome2(configuredHome) : path12.join(os5.homedir(), ".zltquant");
22826
- return path12.join(home, "credentials.json");
22994
+ const home = configuredHome ? expandHome2(configuredHome) : path13.join(os5.homedir(), ".zltquant");
22995
+ return path13.join(home, "credentials.json");
22827
22996
  }
22828
22997
  function inspectLocalCredential(env = process.env) {
22829
22998
  const credentialsPath = resolveLocalCredentialsPath(env);
@@ -22891,8 +23060,8 @@ function preservedTaskIdentity(args) {
22891
23060
  }
22892
23061
  function expandHome2(input) {
22893
23062
  if (input === "~") return os5.homedir();
22894
- if (input.startsWith("~/") || input.startsWith("~\\")) return path12.join(os5.homedir(), input.slice(2));
22895
- return path12.resolve(input);
23063
+ if (input.startsWith("~/") || input.startsWith("~\\")) return path13.join(os5.homedir(), input.slice(2));
23064
+ return path13.resolve(input);
22896
23065
  }
22897
23066
  function isRecord3(value) {
22898
23067
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
@@ -22900,14 +23069,14 @@ function isRecord3(value) {
22900
23069
 
22901
23070
  // src/local-runtime-readiness.ts
22902
23071
  var fs14 = __toESM(require("node:fs"), 1);
22903
- var path13 = __toESM(require("node:path"), 1);
23072
+ var path14 = __toESM(require("node:path"), 1);
22904
23073
  function inspectLocalRuntimeReadiness(workRoot) {
22905
23074
  const required2 = [
22906
23075
  ["\u5DE5\u7A0B\u8DEF\u5F84", workRoot],
22907
- ["ZLTAF \u7A0B\u5E8F", path13.join(workRoot, "zltaf", "zltaf.exe")],
22908
- ["ZLTAF \u914D\u7F6E", path13.join(workRoot, "zltaf", "application-local.properties")],
22909
- ["Python \u7A0B\u5E8F", path13.join(workRoot, "python", "python.exe")],
22910
- ["MinGit \u7A0B\u5E8F", path13.join(workRoot, "mingit", "cmd", "git.exe")]
23076
+ ["ZLTAF \u7A0B\u5E8F", path14.join(workRoot, "zltaf", "zltaf.exe")],
23077
+ ["ZLTAF \u914D\u7F6E", path14.join(workRoot, "zltaf", "application-local.properties")],
23078
+ ["Python \u7A0B\u5E8F", path14.join(workRoot, "python", "python.exe")],
23079
+ ["MinGit \u7A0B\u5E8F", path14.join(workRoot, "mingit", "cmd", "git.exe")]
22911
23080
  ];
22912
23081
  for (const [label, filePath] of required2) {
22913
23082
  if (!fs14.existsSync(filePath)) {
@@ -22939,13 +23108,13 @@ function ensureDir(dir) {
22939
23108
  function writeResponseFile(outputDir, content) {
22940
23109
  ensureDir(outputDir);
22941
23110
  const filename = `resp_${getTimestamp()}.json`;
22942
- const filePath = path14.join(outputDir, filename);
23111
+ const filePath = path15.join(outputDir, filename);
22943
23112
  fs15.writeFileSync(filePath, content, "utf-8");
22944
23113
  return filePath;
22945
23114
  }
22946
23115
  function appendHistory(outputDir, uri, statusCode, contentSize, respFile) {
22947
23116
  ensureDir(outputDir);
22948
- const historyPath = path14.join(outputDir, "history.jsonl");
23117
+ const historyPath = path15.join(outputDir, "history.jsonl");
22949
23118
  if (fs15.existsSync(historyPath)) {
22950
23119
  const lines = fs15.readFileSync(historyPath, "utf-8").split("\n").filter((l) => l.trim());
22951
23120
  if (lines.length > HISTORY_MAX_LINES) {
@@ -22970,7 +23139,7 @@ function cleanOutput(clientRootDir, maxDays = 1) {
22970
23139
  let removed = 0;
22971
23140
  for (const entry of fs15.readdirSync(outputDir)) {
22972
23141
  if (!entry.startsWith("resp_") || !entry.endsWith(".json")) continue;
22973
- const filePath = path14.join(outputDir, entry);
23142
+ const filePath = path15.join(outputDir, entry);
22974
23143
  const stat = fs15.statSync(filePath);
22975
23144
  if (stat.mtimeMs < cutoff) {
22976
23145
  fs15.unlinkSync(filePath);
@@ -22981,7 +23150,7 @@ function cleanOutput(clientRootDir, maxDays = 1) {
22981
23150
  }
22982
23151
  async function execCommand(funcName, options) {
22983
23152
  const resolver = resolveDefaultConfigPath;
22984
- const configPath = typeof resolver === "function" ? resolver() : process.env.ZLT_MCP_CONFIG || path14.resolve(process.cwd(), "config.json");
23153
+ const configPath = typeof resolver === "function" ? resolver() : process.env.ZLT_MCP_CONFIG || path15.resolve(process.cwd(), "config.json");
22985
23154
  const config2 = loadConfig2(configPath);
22986
23155
  const tool = config2.tools.find((t) => t.name === funcName);
22987
23156
  if (!tool) {
@@ -23167,7 +23336,7 @@ function backtestHandoff(result) {
23167
23336
  const rawCodePath = typeof record5.codePath === "string" ? record5.codePath.trim() : typeof evidence?.runDir === "string" ? evidence.runDir.trim() : "";
23168
23337
  return {
23169
23338
  runId,
23170
- ...rawCodePath && path14.isAbsolute(rawCodePath) ? { codePath: rawCodePath } : {},
23339
+ ...rawCodePath && path15.isAbsolute(rawCodePath) ? { codePath: rawCodePath } : {},
23171
23340
  ...record5.attemptFence !== void 0 ? { attemptFence: record5.attemptFence } : {}
23172
23341
  };
23173
23342
  }
@@ -23184,7 +23353,7 @@ function mergeBacktestWait(launched, waited, handoff) {
23184
23353
  for (const id of [data.runId, data.backtestId]) {
23185
23354
  if (id !== void 0 && id !== handoff.runId) throw new Error("Backtest wait returned a different run ID");
23186
23355
  }
23187
- if (data.codePath !== void 0 && handoff.codePath && (typeof data.codePath !== "string" || path14.resolve(data.codePath).toLowerCase() !== path14.resolve(handoff.codePath).toLowerCase())) {
23356
+ if (data.codePath !== void 0 && handoff.codePath && (typeof data.codePath !== "string" || path15.resolve(data.codePath).toLowerCase() !== path15.resolve(handoff.codePath).toLowerCase())) {
23188
23357
  throw new Error("Backtest wait returned a different run directory");
23189
23358
  }
23190
23359
  const status = typeof data.status === "number" || typeof data.status === "string" && data.status.trim() ? Number(data.status) : NaN;
@@ -23422,7 +23591,7 @@ function buildIpcTimeout(tool, options, defaultTimeout) {
23422
23591
 
23423
23592
  // src/skill-generator.ts
23424
23593
  var fs16 = __toESM(require("fs"), 1);
23425
- var path15 = __toESM(require("path"), 1);
23594
+ var path16 = __toESM(require("path"), 1);
23426
23595
  function generateSkills(configPath, opts) {
23427
23596
  const config2 = loadConfig(configPath);
23428
23597
  const toolsWithSkills = config2.tools.filter((t) => t.skill);
@@ -23442,7 +23611,7 @@ ${content}
23442
23611
  if (!fs16.existsSync(outDir)) {
23443
23612
  fs16.mkdirSync(outDir, { recursive: true });
23444
23613
  }
23445
- const filePath = path15.join(outDir, `zlt-${tool.name.replace(/_/g, "-")}.md`);
23614
+ const filePath = path16.join(outDir, `zlt-${tool.name.replace(/_/g, "-")}.md`);
23446
23615
  fs16.writeFileSync(filePath, content);
23447
23616
  process.stderr.write(`Generated: ${filePath}
23448
23617
  `);
@@ -24140,15 +24309,15 @@ var fs25 = __toESM(require("node:fs"), 1);
24140
24309
  // src/install-task.ts
24141
24310
  var fs17 = __toESM(require("node:fs"), 1);
24142
24311
  var os6 = __toESM(require("node:os"), 1);
24143
- var path16 = __toESM(require("node:path"), 1);
24312
+ var path17 = __toESM(require("node:path"), 1);
24144
24313
  var import_node_child_process2 = require("node:child_process");
24145
- var DEFAULT_TASK_ROOT = path16.join(os6.tmpdir(), "zlt-mcp-install-tasks");
24314
+ var DEFAULT_TASK_ROOT = path17.join(os6.tmpdir(), "zlt-mcp-install-tasks");
24146
24315
  var STARTUP_GRACE_MS = 3e4;
24147
24316
  function taskRoot() {
24148
24317
  return process.env.ZLT_MCP_INSTALL_TASK_ROOT || DEFAULT_TASK_ROOT;
24149
24318
  }
24150
24319
  function taskPath(taskId) {
24151
- return path16.join(taskRoot(), `${taskId}.json`);
24320
+ return path17.join(taskRoot(), `${taskId}.json`);
24152
24321
  }
24153
24322
  function write(record5) {
24154
24323
  fs17.mkdirSync(taskRoot(), { recursive: true });
@@ -24221,7 +24390,7 @@ function startInstallTask(entrypoint, argsJson, spawnProcess = import_node_child
24221
24390
  status: "queued",
24222
24391
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
24223
24392
  launcherPid: process.pid,
24224
- logPath: path16.join(taskRoot(), `${taskId}.log`)
24393
+ logPath: path17.join(taskRoot(), `${taskId}.log`)
24225
24394
  };
24226
24395
  write(record5);
24227
24396
  let logFd;
@@ -24273,7 +24442,7 @@ var import_promises = require("node:timers/promises");
24273
24442
 
24274
24443
  // src/tool-pipeline.ts
24275
24444
  var fs24 = __toESM(require("node:fs"), 1);
24276
- var path23 = __toESM(require("node:path"), 1);
24445
+ var path24 = __toESM(require("node:path"), 1);
24277
24446
  var import_node_crypto4 = require("node:crypto");
24278
24447
 
24279
24448
  // src/feature-set.ts
@@ -24285,7 +24454,7 @@ var MASKED_FUTURES_MESSAGE = "\u671F\u8D27\u56DE\u6D4B\u5728\u5F53\u524D\u7248\u
24285
24454
 
24286
24455
  // src/backtest-config.ts
24287
24456
  var fs18 = __toESM(require("node:fs"), 1);
24288
- var path17 = __toESM(require("node:path"), 1);
24457
+ var path18 = __toESM(require("node:path"), 1);
24289
24458
  var import_node_crypto2 = require("node:crypto");
24290
24459
  var BACKTEST_CONFIG_KEYS = [
24291
24460
  "start",
@@ -24331,12 +24500,12 @@ function readBacktestBaseline(tool, args) {
24331
24500
  if (!create && tool !== "mcp-re-backtest") return void 0;
24332
24501
  const directory = args[create ? "strategyPath" : "codePath"];
24333
24502
  if (directory === void 0) return void 0;
24334
- if (typeof directory !== "string" || !path17.isAbsolute(directory)) throw new Error("Configuration baseline requires an absolute directory path");
24503
+ if (typeof directory !== "string" || !path18.isAbsolute(directory)) throw new Error("Configuration baseline requires an absolute directory path");
24335
24504
  const root2 = fs18.realpathSync(directory);
24336
- if (create && path17.basename(path17.dirname(root2)).toLowerCase() === "backtest") {
24505
+ if (create && path18.basename(path18.dirname(root2)).toLowerCase() === "backtest") {
24337
24506
  throw new Error("strategyPath must identify the strategy root, not a historical backtest directory");
24338
24507
  }
24339
- const file = path17.join(root2, ".vscode", "tradesetting.json");
24508
+ const file = path18.join(root2, ".vscode", "tradesetting.json");
24340
24509
  const raw = fs18.readFileSync(file);
24341
24510
  let config2;
24342
24511
  try {
@@ -24398,7 +24567,7 @@ function reconcileBaselineCapital(params, overrides) {
24398
24567
 
24399
24568
  // src/backtest-execution-progress.ts
24400
24569
  var fs19 = __toESM(require("node:fs"), 1);
24401
- var path18 = __toESM(require("node:path"), 1);
24570
+ var path19 = __toESM(require("node:path"), 1);
24402
24571
  var MAX_TAIL_BYTES = 128 * 1024;
24403
24572
  var FUTURE_SKEW_MS = 5e3;
24404
24573
  function beijingTimestamp(value) {
@@ -24413,9 +24582,9 @@ function readBacktestExecutionProgress(input) {
24413
24582
  const { runId, codePath, attemptStartedAtMs, nowMs = Date.now() } = input;
24414
24583
  if (!runId || !codePath || !Number.isFinite(attemptStartedAtMs) || attemptStartedAtMs <= 0 || !Number.isFinite(nowMs)) return void 0;
24415
24584
  try {
24416
- const config2 = JSON.parse(fs19.readFileSync(path18.join(codePath, ".vscode", "tradesetting.json"), "utf8"));
24585
+ const config2 = JSON.parse(fs19.readFileSync(path19.join(codePath, ".vscode", "tradesetting.json"), "utf8"));
24417
24586
  if (config2?.backtest_id !== runId) return void 0;
24418
- const fd = fs19.openSync(path18.join(codePath, "log", "strategy.log"), "r");
24587
+ const fd = fs19.openSync(path19.join(codePath, "log", "strategy.log"), "r");
24419
24588
  let text2;
24420
24589
  try {
24421
24590
  const before = fs19.fstatSync(fd);
@@ -24462,6 +24631,261 @@ function toFiniteNumber(value) {
24462
24631
  return Number.isFinite(n) ? n : 0;
24463
24632
  }
24464
24633
 
24634
+ // src/list-result-disclosure.ts
24635
+ var LIST_DISCLOSURE_TOOLS = /* @__PURE__ */ new Set([
24636
+ "mcp-get-strategy-list",
24637
+ "mcp-strategy-get-template-list",
24638
+ "mcp-get-strategy-tree-list"
24639
+ ]);
24640
+ var MAX_BYTES = 8 * 1024;
24641
+ var MAX_FIELDS = 50;
24642
+ var MAX_FIELD_NAME_BYTES = 128;
24643
+ var MAX_UNKNOWN_FIELDS = 50;
24644
+ var MAX_OMITTED_FIELDS = 100;
24645
+ function shapeListResultDisclosure(tool, args, result) {
24646
+ if (!LIST_DISCLOSURE_TOOLS.has(tool.name) || result.isError) return result;
24647
+ try {
24648
+ const envelope = JSON.parse(result.content[0]?.text ?? "");
24649
+ if (!isRecord4(envelope) || envelope.disclosure || Number(envelope.ErrNo ?? 0) !== 0) return result;
24650
+ if (!Array.isArray(envelope.Data)) return result;
24651
+ const source = envelope.Data;
24652
+ const offset = integer2(args.offset, 0, 0, Number.MAX_SAFE_INTEGER);
24653
+ const limit = integer2(args.limit, 20, 1, 50);
24654
+ const fields = Array.isArray(args.fields) ? [...new Set(args.fields.filter((field) => typeof field === "string"))].slice(0, MAX_FIELDS).map((field) => field.slice(0, MAX_FIELD_NAME_BYTES)) : [];
24655
+ const allAvailableFields = [...new Set(source.flatMap((row) => isRecord4(row) ? Object.keys(row) : []))];
24656
+ const availableFields = allAvailableFields.slice(0, MAX_FIELDS).map((field) => field.slice(0, MAX_FIELD_NAME_BYTES));
24657
+ const rows = [];
24658
+ let nextCursor = offset;
24659
+ const omittedFields = [];
24660
+ const metadata = () => {
24661
+ const detail = {
24662
+ total: source.length,
24663
+ offset,
24664
+ returned: rows.length,
24665
+ hasMore: nextCursor < source.length,
24666
+ nextOffset: nextCursor < source.length ? nextCursor : null,
24667
+ availableFields,
24668
+ ...fields.length ? (() => {
24669
+ const unknownFields = fields.filter((field) => !allAvailableFields.includes(field));
24670
+ return {
24671
+ unknownFields: unknownFields.slice(0, MAX_UNKNOWN_FIELDS).map((field) => field.slice(0, MAX_FIELD_NAME_BYTES)),
24672
+ ...unknownFields.length > MAX_UNKNOWN_FIELDS ? { unknownFieldsTruncated: true } : {}
24673
+ };
24674
+ })() : {},
24675
+ ...allAvailableFields.length > availableFields.length ? { availableFieldsTruncated: true } : {},
24676
+ ...omittedFields.length ? {
24677
+ omittedFields: omittedFields.slice(0, MAX_OMITTED_FIELDS).map((entry) => ({ ...entry, field: entry.field.slice(0, MAX_FIELD_NAME_BYTES) })),
24678
+ ...omittedFields.length > MAX_OMITTED_FIELDS ? { omittedFieldsTruncated: true } : {},
24679
+ nextAction: "Fields marked readable can be requested alone using fields at the same offset and limit:1. Fields marked readable:false exceed this bounded interface; inspect local raw data or use an additional interface. Repeating the list call cannot recover them."
24680
+ } : {}
24681
+ };
24682
+ for (const key of ["omittedFields", "unknownFields", "availableFields"]) {
24683
+ const entries = detail[key];
24684
+ if (!Array.isArray(entries)) continue;
24685
+ while (valueBytes(detail) > 2048 && entries.length) {
24686
+ entries.pop();
24687
+ detail[`${key}Truncated`] = true;
24688
+ }
24689
+ }
24690
+ return detail;
24691
+ };
24692
+ const bytes = (candidateRows = rows) => Buffer.byteLength(JSON.stringify({ ...envelope, Data: candidateRows, disclosure: metadata() }), "utf8");
24693
+ for (let index = offset; index < Math.min(source.length, offset + limit); index++) {
24694
+ const raw = source[index];
24695
+ const omissionStart = omittedFields.length;
24696
+ let row = isRecord4(raw) ? Object.fromEntries(Object.entries(raw).filter(([key]) => !fields.length || fields.includes(key))) : raw;
24697
+ if (bytes([...rows, row]) > MAX_BYTES && rows.length > 0 && bytes([row]) <= MAX_BYTES) break;
24698
+ if (bytes([row]) > MAX_BYTES && isRecord4(row)) {
24699
+ const largest = Object.keys(row).filter((key) => !/^(id|.*Id|name|title)$/i.test(key)).sort((a, b) => valueBytes(row[b]) - valueBytes(row[a]));
24700
+ for (const field of largest) {
24701
+ if (bytes([row]) <= MAX_BYTES) break;
24702
+ const size = valueBytes(row[field]);
24703
+ delete row[field];
24704
+ omittedFields.push({ index, field, bytes: size, readable: size < MAX_BYTES - 1024, reason: "json-budget-exceeded" });
24705
+ }
24706
+ if (bytes([row]) > MAX_BYTES) {
24707
+ const identity = Object.keys(row).filter((key) => /^(id|.*Id|name|title)$/i.test(key)).sort((a, b) => valueBytes(row[b]) - valueBytes(row[a]));
24708
+ let identityRemoved = false;
24709
+ for (const field of identity) {
24710
+ if (bytes([row]) <= MAX_BYTES) break;
24711
+ const size = valueBytes(row[field]);
24712
+ delete row[field];
24713
+ identityRemoved = true;
24714
+ omittedFields.push({ index, field, bytes: size, readable: false, reason: "identity-field-exceeds-json-budget" });
24715
+ }
24716
+ if (identityRemoved || bytes([row]) > MAX_BYTES) {
24717
+ row = { _omittedIndex: index, _omittedReason: "row-exceeds-json-budget" };
24718
+ omittedFields.push({ index, field: "*row*", bytes: valueBytes(raw), readable: false, reason: "row-exceeds-json-budget" });
24719
+ }
24720
+ }
24721
+ }
24722
+ if (bytes([...rows, row]) > MAX_BYTES) {
24723
+ if (rows.length === 0) {
24724
+ row = { _omittedIndex: index, _omittedReason: "row-exceeds-json-budget" };
24725
+ omittedFields.push({ index, field: "*row*", bytes: valueBytes(raw), readable: false, reason: "row-exceeds-json-budget" });
24726
+ if (bytes([row]) <= MAX_BYTES) rows.push(row);
24727
+ } else {
24728
+ omittedFields.splice(omissionStart);
24729
+ break;
24730
+ }
24731
+ nextCursor = index + 1;
24732
+ break;
24733
+ }
24734
+ rows.push(row);
24735
+ nextCursor = index + 1;
24736
+ }
24737
+ return replace(envelope, rows, metadata(), result);
24738
+ } catch {
24739
+ return result;
24740
+ }
24741
+ }
24742
+ function integer2(value, fallback, min, max) {
24743
+ return typeof value === "number" && Number.isInteger(value) ? Math.min(max, Math.max(min, value)) : fallback;
24744
+ }
24745
+ function valueBytes(value) {
24746
+ return Buffer.byteLength(JSON.stringify(value), "utf8");
24747
+ }
24748
+ function replace(envelope, data, disclosure, result) {
24749
+ return { ...result, content: [{ type: "text", text: JSON.stringify({ ...envelope, Data: data, disclosure }) }] };
24750
+ }
24751
+
24752
+ // src/data-result-disclosure.ts
24753
+ var ARRAY_BUDGET = 8 * 1024;
24754
+ var KIND = "data-result-page-v1";
24755
+ var DATA_DISCLOSURE_TOOLS = /* @__PURE__ */ new Set(["mcp-get-data-range", "mcp-get-cache-diff"]);
24756
+ var DECISION_FIELDS = /* @__PURE__ */ new Set([
24757
+ "coverageStatus",
24758
+ "blocksBacktest",
24759
+ "assessment",
24760
+ "nextAction",
24761
+ "reasonCode",
24762
+ "verificationEvidenceComplete",
24763
+ "requestCoverage"
24764
+ ]);
24765
+ function utf8Bytes(value) {
24766
+ return Buffer.byteLength(JSON.stringify(value) ?? "", "utf8");
24767
+ }
24768
+ function fitDataBudget(data, budget, preserveSeriesCoverage = false) {
24769
+ const fitted = { ...data };
24770
+ const omitted = {};
24771
+ const keysBySize = () => Object.keys(fitted).filter((key) => key !== "disclosure" && key !== "disclosureOmitted" && !DECISION_FIELDS.has(key) && !["ranges", "series", "missing", "changed", "windows"].includes(key) && !(preserveSeriesCoverage && key === "seriesCoverage")).map((key) => ({ key, bytes: utf8Bytes(fitted[key]) })).sort((a, b) => b.bytes - a.bytes);
24772
+ while (utf8Bytes(fitted) > budget) {
24773
+ const candidate = keysBySize()[0];
24774
+ if (!candidate) break;
24775
+ const value = fitted[candidate.key];
24776
+ omitted[candidate.key] = candidate.bytes;
24777
+ delete fitted[candidate.key];
24778
+ }
24779
+ if (Object.keys(omitted).length > 0) fitted.disclosureOmitted = omitted;
24780
+ return fitted;
24781
+ }
24782
+ function boundSeriesCoverage(data) {
24783
+ const value = data.seriesCoverage;
24784
+ if (!Array.isArray(value) || utf8Bytes(value) <= 2048) return data;
24785
+ let keep = value.length;
24786
+ while (keep > 0 && utf8Bytes(value.slice(0, keep)) > 2048) keep--;
24787
+ return { ...data, seriesCoverage: value.slice(0, keep), seriesCoverageOmitted: value.length - keep };
24788
+ }
24789
+ function shapeDataResultDisclosure(tool, args, result) {
24790
+ if (!DATA_DISCLOSURE_TOOLS.has(tool.name) || result.isError) return result;
24791
+ try {
24792
+ const parsed = JSON.parse(result.content[0]?.text ?? "");
24793
+ if (!isRecord4(parsed) || !isRecord4(parsed.Data) || Number(parsed.ErrNo ?? 0) !== 0) return result;
24794
+ const original = parsed.Data;
24795
+ if (isRecord4(original.disclosure) && original.disclosure.kind === KIND) return result;
24796
+ const units = [];
24797
+ const totals = /* @__PURE__ */ new Map();
24798
+ const selectedIndexes = /* @__PURE__ */ new Map();
24799
+ const target = (path28) => /\.(ranges|series|missing|changed|windows)$/.test(path28);
24800
+ const nested = (entry) => isRecord4(entry) && Object.entries(entry).some(([key, child]) => target(`.${key}`) && Array.isArray(child) && child.length > 0);
24801
+ const scan = (value, jsonPath) => {
24802
+ if (Array.isArray(value)) {
24803
+ if (target(jsonPath)) {
24804
+ totals.set(jsonPath, value.length);
24805
+ value.forEach((entry, index) => {
24806
+ if (!nested(entry)) units.push({ path: jsonPath, index });
24807
+ });
24808
+ }
24809
+ value.forEach((entry, index) => scan(entry, `${jsonPath}[${index}]`));
24810
+ return;
24811
+ }
24812
+ if (isRecord4(value)) for (const [key, child] of Object.entries(value)) scan(child, `${jsonPath}.${key}`);
24813
+ };
24814
+ const displaySource = fitDataBudget(boundSeriesCoverage(original), ARRAY_BUDGET - 2048, true);
24815
+ scan(displaySource, "$.Data");
24816
+ const explicit = args.offset !== void 0 || args.limit !== void 0;
24817
+ const offset = Number.isInteger(args.offset) && Number(args.offset) >= 0 ? Number(args.offset) : 0;
24818
+ const limit = Number.isInteger(args.limit) && Number(args.limit) > 0 ? Math.min(50, Number(args.limit)) : 20;
24819
+ const selected = /* @__PURE__ */ new Set();
24820
+ const render = (value, jsonPath) => {
24821
+ if (Array.isArray(value)) {
24822
+ const indexes = selectedIndexes.get(jsonPath);
24823
+ if (target(jsonPath)) return value.flatMap((entry, index) => {
24824
+ const entryPath = `${jsonPath}[${index}]`;
24825
+ if (!indexes?.has(index) && ![...selected].some((key) => key.startsWith(`${entryPath}.`))) return [];
24826
+ return [render(entry, entryPath)];
24827
+ });
24828
+ return value.map((entry, index) => render(entry, `${jsonPath}[${index}]`));
24829
+ }
24830
+ if (!isRecord4(value)) return value;
24831
+ return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, render(child, `${jsonPath}.${key}`)]));
24832
+ };
24833
+ const arrayBytes = (value) => {
24834
+ if (Array.isArray(value)) return Buffer.byteLength(JSON.stringify(value), "utf8");
24835
+ return isRecord4(value) ? Object.values(value).reduce((sum, child) => sum + arrayBytes(child), 0) : 0;
24836
+ };
24837
+ if (!explicit && units.length <= limit && utf8Bytes(original) <= ARRAY_BUDGET) return result;
24838
+ let cursor = Math.min(offset, units.length);
24839
+ let oversized = 0;
24840
+ while (cursor < units.length && selected.size < limit) {
24841
+ const unit = units[cursor];
24842
+ const key = `${unit.path}[${unit.index}]`;
24843
+ selected.add(key);
24844
+ const indexes = selectedIndexes.get(unit.path) ?? /* @__PURE__ */ new Set();
24845
+ indexes.add(unit.index);
24846
+ selectedIndexes.set(unit.path, indexes);
24847
+ if (utf8Bytes(render(displaySource, "$.Data")) > ARRAY_BUDGET - 2048) {
24848
+ selected.delete(key);
24849
+ indexes.delete(unit.index);
24850
+ if (selected.size > 0) break;
24851
+ oversized++;
24852
+ }
24853
+ cursor++;
24854
+ }
24855
+ let data = render(displaySource, "$.Data");
24856
+ data = fitDataBudget(data, ARRAY_BUDGET - 2048);
24857
+ const paths = [...totals.keys()].filter((path28) => !path28.includes("[") || selectedIndexes.has(path28));
24858
+ const shownPaths = paths.slice(0, 50);
24859
+ const arrays = shownPaths.map((path28) => {
24860
+ const returnedCount = new Set([...selected].filter((key) => key.startsWith(`${path28}[`)).map((key) => key.slice(path28.length + 1).split("]")[0])).size;
24861
+ return { path: path28, total: totals.get(path28), returned: returnedCount, omitted: totals.get(path28) - returnedCount };
24862
+ });
24863
+ data.disclosure = {
24864
+ kind: KIND,
24865
+ unit: "leaf-array-entry",
24866
+ offset,
24867
+ limit,
24868
+ total: units.length,
24869
+ returned: selected.size,
24870
+ omitted: units.length - selected.size,
24871
+ hasMore: cursor < units.length,
24872
+ nextOffset: cursor < units.length ? cursor : null,
24873
+ arrayBytes: arrayBytes(data),
24874
+ dataBytes: utf8Bytes(data),
24875
+ dataByteBudget: ARRAY_BUDGET,
24876
+ oversizedEntriesOmitted: oversized,
24877
+ arrays,
24878
+ omittedArrayMetadata: totals.size - shownPaths.length,
24879
+ decisionsUseFullResult: true,
24880
+ displayIsPartial: selected.size < units.length,
24881
+ nextAction: "Repeat the same tool and params with offset=nextOffset; the cursor is over leaf array entries. Or narrow params by exchange_id/data_type (cache-diff also accepts start/end). Never treat this displayed page as complete coverage; retain the full-result coverageStatus/blocksBacktest/assessment and evidence."
24882
+ };
24883
+ return { ...result, content: [{ type: "text", text: JSON.stringify({ ...parsed, Data: data }) }, ...result.content.slice(1)] };
24884
+ } catch {
24885
+ return result;
24886
+ }
24887
+ }
24888
+
24465
24889
  // src/ipc-tool-result.ts
24466
24890
  function normalizeResponse(raw) {
24467
24891
  if (raw && typeof raw === "object" && "ErrNo" in raw) return raw;
@@ -24575,6 +24999,8 @@ function annotateSkippedCalculation(tool, result) {
24575
24999
  }
24576
25000
  }
24577
25001
  var FACTOR_DETECT_RESULT_KIND = "factor-detect";
25002
+ var FACTOR_REPORT_SECTION_MAX_BYTES = 8 * 1024;
25003
+ var FACTOR_REPORT_SECTION_MAX_ITEMS = 10;
24578
25004
  var FACTOR_DETECT_OMIT_KEYS = [
24579
25005
  "ranking",
24580
25006
  "returnsByQuantile",
@@ -24592,6 +25018,48 @@ function pickByPeriod(source, period, index) {
24592
25018
  if (isRecord4(source)) return numberOrNull(source[period]);
24593
25019
  return null;
24594
25020
  }
25021
+ function ownPathValue(root2, path28) {
25022
+ const parts = path28.split(".").filter(Boolean);
25023
+ if (parts.length === 0) return { found: false };
25024
+ let current = root2;
25025
+ for (const part of parts) {
25026
+ if (!isRecord4(current) || !Object.prototype.hasOwnProperty.call(current, part)) return { found: false };
25027
+ current = current[part];
25028
+ }
25029
+ return { found: true, value: current };
25030
+ }
25031
+ function reportPathParent(root2, path28) {
25032
+ const parts = path28.split(".").filter(Boolean);
25033
+ if (parts.length === 0) return void 0;
25034
+ const parentPath = parts.slice(0, -1).join(".");
25035
+ const parent = parentPath ? ownPathValue(root2, parentPath).value : root2;
25036
+ if (!isRecord4(parent)) return void 0;
25037
+ return { path: parentPath, fields: Object.keys(parent) };
25038
+ }
25039
+ function jsonBytes(value) {
25040
+ return Buffer.byteLength(JSON.stringify(value) ?? "", "utf8");
25041
+ }
25042
+ function reportType(value) {
25043
+ if (value === null) return "null";
25044
+ if (Array.isArray(value)) return "array";
25045
+ return typeof value;
25046
+ }
25047
+ function omitUndistillableReport(parsed, data, reportJson, reason, validJson) {
25048
+ const { reportJson: _raw, ...scalars } = data;
25049
+ return {
25050
+ content: [{ type: "text", text: JSON.stringify({
25051
+ ...parsed,
25052
+ Data: {
25053
+ ...scalars,
25054
+ resultKind: FACTOR_DETECT_RESULT_KIND,
25055
+ ...reason === "Invalid report JSON." ? { reportParseError: true } : {},
25056
+ reportParse: { validJson, type: reportType(reportJson) },
25057
+ reportOmitted: { bytes: jsonBytes(reportJson), reason },
25058
+ nextAction: "The report was omitted from the default response. Use includeReport:true only for an explicit raw-evidence request."
25059
+ }
25060
+ }) }]
25061
+ };
25062
+ }
24595
25063
  function distillFactorDetectReport(tool, args, result) {
24596
25064
  if (tool.name !== "mcp-factor-detect-detail" || result.isError) return result;
24597
25065
  if (args.includeReport === true) return result;
@@ -24601,14 +25069,58 @@ function distillFactorDetectReport(tool, args, result) {
24601
25069
  if (!isRecord4(parsed) || !isRecord4(parsed.Data)) return result;
24602
25070
  const data = parsed.Data;
24603
25071
  if (data.resultKind === FACTOR_DETECT_RESULT_KIND) return result;
24604
- if (typeof data.reportJson !== "string" || data.reportJson.length === 0) return result;
25072
+ if (!Object.prototype.hasOwnProperty.call(data, "reportJson")) return result;
25073
+ const rawReport = data.reportJson;
25074
+ if (typeof rawReport !== "string") {
25075
+ return omitUndistillableReport(parsed, data, rawReport, "Valid report JSON is not an object; raw report omitted.", false);
25076
+ }
25077
+ if (rawReport.length === 0) return omitUndistillableReport(parsed, data, rawReport, "Invalid report JSON.", false);
24605
25078
  let report;
24606
25079
  try {
24607
- report = JSON.parse(data.reportJson);
25080
+ report = JSON.parse(rawReport);
24608
25081
  } catch {
24609
- return result;
25082
+ return omitUndistillableReport(parsed, data, rawReport, "Invalid report JSON.", false);
25083
+ }
25084
+ if (!isRecord4(report)) return omitUndistillableReport(parsed, data, report, "Valid report JSON is not an object; raw report omitted.", true);
25085
+ const requestedSections = Array.isArray(args.reportSections) ? [...new Set(args.reportSections.filter((section) => typeof section === "string"))].slice(0, FACTOR_REPORT_SECTION_MAX_ITEMS) : [];
25086
+ const reportOffset = Math.max(0, Math.floor(Number(args.reportOffset) || 0));
25087
+ const reportLimit = Math.min(50, Math.max(1, Math.floor(Number(args.reportLimit) || 20)));
25088
+ const reportSections = /* @__PURE__ */ Object.create(null);
25089
+ const unknownReportSections = [];
25090
+ const availableReportFields = /* @__PURE__ */ Object.create(null);
25091
+ const omittedReportSections = [];
25092
+ let disclosedBytes = 0;
25093
+ if (requestedSections.length > 0) {
25094
+ for (const section of requestedSections) {
25095
+ const selected = ownPathValue(report, section);
25096
+ if (selected.found) {
25097
+ const value = selected.value;
25098
+ const total = Array.isArray(value) ? value.length : typeof value === "string" ? Array.from(value).length : void 0;
25099
+ const paged = Array.isArray(value) ? { items: value.slice(reportOffset, reportOffset + reportLimit), total, offset: reportOffset, limit: reportLimit } : typeof value === "string" ? { value: Array.from(value).slice(reportOffset, reportOffset + reportLimit).join(""), total, offset: reportOffset, limit: reportLimit } : { value };
25100
+ const shaped = total !== void 0 ? { ...paged, hasMore: reportOffset + reportLimit < total, ...reportOffset + reportLimit < total ? { nextOffset: reportOffset + reportLimit } : {} } : value;
25101
+ const bytes = jsonBytes(shaped) + jsonBytes(section) + 1;
25102
+ const remainingBytes = FACTOR_REPORT_SECTION_MAX_BYTES - disclosedBytes;
25103
+ if (bytes <= remainingBytes) {
25104
+ reportSections[section] = shaped;
25105
+ disclosedBytes += bytes;
25106
+ } else if (!omittedReportSections.some((item) => item.name === section)) {
25107
+ omittedReportSections.push({
25108
+ name: section,
25109
+ bytes,
25110
+ maxBytes: remainingBytes,
25111
+ reason: "Section exceeds the remaining progressive-disclosure budget; narrow the path or page further."
25112
+ });
25113
+ if (isRecord4(value)) {
25114
+ availableReportFields[section] = Object.keys(value);
25115
+ }
25116
+ }
25117
+ } else if (!unknownReportSections.includes(section)) {
25118
+ unknownReportSections.push(section);
25119
+ const parent = reportPathParent(report, section);
25120
+ if (parent) availableReportFields[parent.path] = parent.fields;
25121
+ }
25122
+ }
24610
25123
  }
24611
- if (!isRecord4(report)) return result;
24612
25124
  const alphalens = isRecord4(report.alphalens) ? report.alphalens : {};
24613
25125
  const ic = isRecord4(alphalens.ic) ? alphalens.ic : {};
24614
25126
  const periodNames = Array.isArray(alphalens.periods) ? alphalens.periods.filter((p) => typeof p === "string") : [];
@@ -24627,13 +25139,21 @@ function distillFactorDetectReport(tool, args, result) {
24627
25139
  const omittedKeys = {};
24628
25140
  let omittedBytes = 0;
24629
25141
  for (const key of FACTOR_DETECT_OMIT_KEYS) {
24630
- const source = key in report ? report[key] : alphalens[key];
25142
+ const topLevel = Object.prototype.hasOwnProperty.call(report, key);
25143
+ if (Object.prototype.hasOwnProperty.call(reportSections, topLevel ? key : "alphalens")) continue;
25144
+ const source = topLevel ? report[key] : alphalens[key];
24631
25145
  if (source === void 0) continue;
24632
- const size = JSON.stringify(source).length;
25146
+ const size = jsonBytes(source);
24633
25147
  omittedKeys[key] = size;
24634
25148
  omittedBytes += size;
24635
25149
  }
24636
25150
  const { reportJson, ...scalars } = data;
25151
+ const disclosedSections = requestedSections.length > 0 ? {
25152
+ reportSections,
25153
+ ...unknownReportSections.length > 0 ? { unknownReportSections } : {},
25154
+ ...Object.keys(availableReportFields).length > 0 ? { availableReportFields } : {},
25155
+ ...omittedReportSections.length > 0 ? { omittedReportSections } : {}
25156
+ } : {};
24637
25157
  return {
24638
25158
  content: [{
24639
25159
  type: "text",
@@ -24652,12 +25172,14 @@ function distillFactorDetectReport(tool, args, result) {
24652
25172
  effective: report.effectivePreprocess ?? null,
24653
25173
  stats: report.preprocessStats ?? null
24654
25174
  },
25175
+ ...disclosedSections,
25176
+ availableReportSections: Object.keys(report),
24655
25177
  reportOmitted: {
24656
25178
  bytes: omittedBytes,
24657
25179
  keys: omittedKeys,
24658
25180
  reason: "Alphalens plot series, not needed to read IC or layered returns."
24659
25181
  },
24660
- nextAction: "Read IC from periods[]: icMean/icIr with tStat and pValue for the SAME period. A near-zero icMean with |tStat| under 2 and pValue above 0.05 does not support any claim about the factor working \u2014 say so rather than reporting the sign. quantileMean holds the layered returns, verifyPassed the platform's own threshold verdict. The plot series listed in reportOmitted were dropped to keep this readable; pass includeReport:true to get the raw report back (it is over 1 MB and will be truncated)."
25182
+ nextAction: `Read IC from periods[]: icMean/icIr with tStat and pValue for the SAME period. A near-zero icMean with |tStat| under 2 and pValue above 0.05 does not support any claim about the factor working \u2014 say so rather than reporting the sign. quantileMean holds the layered returns, verifyPassed the platform's own threshold verdict. The plot series listed in reportOmitted were dropped to keep this readable; pass reportSections:["path"] with reportOffset/reportLimit to disclose a narrow section or page (the combined disclosure budget is 8 KiB; unavailable fields are listed in availableReportFields), or use includeReport:true only for an explicit raw-evidence request.`
24661
25183
  }
24662
25184
  })
24663
25185
  }]
@@ -24815,7 +25337,7 @@ function buildIpcBody2(tool, args) {
24815
25337
  if (tool.bodyParamKey) {
24816
25338
  return JSON.stringify(args[tool.bodyParamKey] ?? {});
24817
25339
  }
24818
- return tool.bodyFromParams ? JSON.stringify(stripControlParams(args)) : "{}";
25340
+ return tool.bodyFromParams ? JSON.stringify(stripControlParams(args, tool.name)) : "{}";
24819
25341
  }
24820
25342
  function buildIpcTimeout2(tool, args, defaultTimeout) {
24821
25343
  const declared = Number(tool.timeoutMs);
@@ -24836,9 +25358,24 @@ var CONTROL_PARAMS = [
24836
25358
  "__attemptStartedAtMs",
24837
25359
  "__resultBaseline"
24838
25360
  ];
24839
- function stripControlParams(args) {
25361
+ function stripControlParams(args, toolName) {
24840
25362
  const filtered = { ...args };
24841
25363
  for (const key of CONTROL_PARAMS) delete filtered[key];
25364
+ if (toolName && LIST_DISCLOSURE_TOOLS.has(toolName)) {
25365
+ delete filtered.offset;
25366
+ delete filtered.limit;
25367
+ delete filtered.fields;
25368
+ }
25369
+ if (toolName && DATA_DISCLOSURE_TOOLS.has(toolName)) {
25370
+ delete filtered.offset;
25371
+ delete filtered.limit;
25372
+ }
25373
+ if (toolName === "mcp-factor-detect-detail") {
25374
+ delete filtered.includeReport;
25375
+ delete filtered.reportSections;
25376
+ delete filtered.reportOffset;
25377
+ delete filtered.reportLimit;
25378
+ }
24842
25379
  return filtered;
24843
25380
  }
24844
25381
  function applySchemaDefaults(schema, value) {
@@ -24907,11 +25444,11 @@ function cloneDefaultValue(value) {
24907
25444
 
24908
25445
  // src/factor-operations.ts
24909
25446
  var fs21 = __toESM(require("node:fs"), 1);
24910
- var path20 = __toESM(require("node:path"), 1);
25447
+ var path21 = __toESM(require("node:path"), 1);
24911
25448
 
24912
25449
  // src/data-result-transforms.ts
24913
25450
  var fs20 = __toESM(require("node:fs"), 1);
24914
- var path19 = __toESM(require("node:path"), 1);
25451
+ var path20 = __toESM(require("node:path"), 1);
24915
25452
  var MARKET_ID_TO_NAME = {
24916
25453
  29544: "\u4E0A\u4EA4\u6240(sh)",
24917
25454
  29562: "\u6DF1\u4EA4\u6240(sz)",
@@ -24995,8 +25532,8 @@ function resolveDataRoots(clientRootDir) {
24995
25532
  const cached2 = Date.now() - readAt < DATA_ROOTS_TTL_MS ? dataRootsCache.get(clientRootDir) : void 0;
24996
25533
  if (cached2) return cached2;
24997
25534
  const root2 = clientRootDir.replace(/[\\/]+$/, "");
24998
- const dcSdk = readJsonFile(path19.join(root2, ...DC_SDK_CONFIG_SEGMENTS));
24999
- const dcm = readJsonFile(path19.join(root2, ...DCM_CONFIG_SEGMENTS));
25535
+ const dcSdk = readJsonFile(path20.join(root2, ...DC_SDK_CONFIG_SEGMENTS));
25536
+ const dcm = readJsonFile(path20.join(root2, ...DCM_CONFIG_SEGMENTS));
25000
25537
  const engineRoot = normalizeDataRoot(isRecord4(dcSdk?.mdf) ? dcSdk.mdf.path : void 0, root2);
25001
25538
  const downloadRoot = normalizeDataRoot(dcm?.download_home, root2);
25002
25539
  const resolved = Boolean(engineRoot && downloadRoot);
@@ -25066,7 +25603,7 @@ function engineHasHqSeries(engineRoot, series) {
25066
25603
  if (!engineRoot || !series.exchangeId || !HQ_DATA_FAMILIES.has(splitDataTypeToken(series.dataType).family)) {
25067
25604
  return void 0;
25068
25605
  }
25069
- const dir = path19.join(engineRoot, "hqdata", "his", series.exchangeId, series.dataType);
25606
+ const dir = path20.join(engineRoot, "hqdata", "his", series.exchangeId, series.dataType);
25070
25607
  try {
25071
25608
  return fs20.readdirSync(dir).length > 0;
25072
25609
  } catch (error2) {
@@ -25647,18 +26184,18 @@ function resolveFactorProjectRoot(clientRootDir) {
25647
26184
  if (cached2) return cached2;
25648
26185
  const root2 = clientRootDir.replace(/[\\/]+$/, "");
25649
26186
  const configured = expandSlaveValue(
25650
- readSlaveProperties(path20.join(root2, ...ZLTAF_CONFIG_SEGMENTS)),
26187
+ readSlaveProperties(path21.join(root2, ...ZLTAF_CONFIG_SEGMENTS)),
25651
26188
  "slave.factor.project-path",
25652
26189
  root2
25653
26190
  );
25654
- const resolved = configured ? path20.normalize(configured) : path20.join(root2, ...FALLBACK_FACTOR_PROJECT_PATH);
26191
+ const resolved = configured ? path21.normalize(configured) : path21.join(root2, ...FALLBACK_FACTOR_PROJECT_PATH);
25655
26192
  factorProjectRootCache.set(clientRootDir, resolved);
25656
26193
  return resolved;
25657
26194
  }
25658
26195
  function resolveFactorWorkspacePath(clientRootDir, factorId) {
25659
26196
  if (!clientRootDir || !factorId) return void 0;
25660
26197
  const projectRoot = resolveFactorProjectRoot(clientRootDir);
25661
- return projectRoot ? path20.join(projectRoot, factorId) : void 0;
26198
+ return projectRoot ? path21.join(projectRoot, factorId) : void 0;
25662
26199
  }
25663
26200
  var MODULE_LEVEL_FACTOR_EXPORT = /^(?:(?:async\s+)?def\s+get_factor\s*\(|get_factor\s*=(?!=)|Factor\s*=(?!=))/m;
25664
26201
  function checkFactorSourceLoadable(clientRootDir, factorId) {
@@ -25666,7 +26203,7 @@ function checkFactorSourceLoadable(clientRootDir, factorId) {
25666
26203
  if (!workspacePath) return null;
25667
26204
  let source;
25668
26205
  try {
25669
- source = fs21.readFileSync(path20.join(workspacePath, "main.py"), "utf8");
26206
+ source = fs21.readFileSync(path21.join(workspacePath, "main.py"), "utf8");
25670
26207
  } catch {
25671
26208
  return null;
25672
26209
  }
@@ -26085,11 +26622,11 @@ async function queryFactorValuesForLatestRecord(tool, args, client2, timeout, se
26085
26622
 
26086
26623
  // src/strategy-operations.ts
26087
26624
  var fs22 = __toESM(require("node:fs"), 1);
26088
- var path21 = __toESM(require("node:path"), 1);
26625
+ var path22 = __toESM(require("node:path"), 1);
26089
26626
  var STRATEGY_DOCS_TOOLS = /* @__PURE__ */ new Set(["mcp-create-strategy", "mcp-create-strategy-with-template"]);
26090
26627
  function resolveStrategyDocsPath(clientRootDir) {
26091
26628
  if (!clientRootDir) return void 0;
26092
- const docsPath = path21.join(
26629
+ const docsPath = path22.join(
26093
26630
  clientRootDir,
26094
26631
  "python",
26095
26632
  "Lib",
@@ -26116,7 +26653,7 @@ function injectDebugRunId(tool, result) {
26116
26653
  const localPath = typeof parsed.Data.localPath === "string" ? parsed.Data.localPath.trim() : "";
26117
26654
  if (!localPath) return result;
26118
26655
  const settings = JSON.parse(
26119
- fs22.readFileSync(path21.join(localPath, ".vscode", "tradesetting.json"), "utf8")
26656
+ fs22.readFileSync(path22.join(localPath, ".vscode", "tradesetting.json"), "utf8")
26120
26657
  );
26121
26658
  const debugRunId = isRecord4(settings) && typeof settings.backtest_id === "string" ? settings.backtest_id.trim() : "";
26122
26659
  if (!debugRunId) return result;
@@ -26521,7 +27058,7 @@ async function runWaitLoop(lane, client2, timeout, session, control) {
26521
27058
 
26522
27059
  // src/tool-steps.ts
26523
27060
  var fs23 = __toESM(require("node:fs"), 1);
26524
- var path22 = __toESM(require("node:path"), 1);
27061
+ var path23 = __toESM(require("node:path"), 1);
26525
27062
  var import_node_crypto3 = require("node:crypto");
26526
27063
  async function executeSteps(steps, client2, initialBody, timeout, repairHint = identityRepairHint, toolName) {
26527
27064
  let body = { ...initialBody };
@@ -26665,7 +27202,7 @@ function preflightCreatedBacktestSource(toolName, body) {
26665
27202
  const runId = typeof body.runId === "string" ? body.runId.trim() : "";
26666
27203
  const codePath = typeof body.codePath === "string" ? body.codePath.trim() : "";
26667
27204
  if (!codePath || !fs23.existsSync(codePath)) return null;
26668
- const sourcePath = path22.join(codePath, "main.py");
27205
+ const sourcePath = path23.join(codePath, "main.py");
26669
27206
  if (!fs23.existsSync(sourcePath)) return null;
26670
27207
  let source;
26671
27208
  try {
@@ -26814,8 +27351,8 @@ function validateToolCallArguments(tool, args) {
26814
27351
  }
26815
27352
  function validateDataRangeArguments(args) {
26816
27353
  const errors = [];
26817
- const error2 = (path27, message) => errors.push({ path: path27, message });
26818
- const input = stripControlParams(args);
27354
+ const error2 = (path28, message) => errors.push({ path: path28, message });
27355
+ const input = stripControlParams(args, "mcp-get-data-range");
26819
27356
  for (const key of Object.keys(input)) {
26820
27357
  if (key !== "params") error2(`$.${key}`, "Unsupported top-level field; query combinations belong in params[]. Date filters are not accepted.");
26821
27358
  }
@@ -26893,7 +27430,11 @@ async function dispatchSpecialTool(tool, args, client2, timeout, session, waitCo
26893
27430
  if (blocked) return blocked;
26894
27431
  }
26895
27432
  if (tool.name === "mcp-get-strategy-list") {
26896
- return listStrategies(client2, args, timeout, session.repairHint);
27433
+ return shapeListResultDisclosure(
27434
+ tool,
27435
+ args,
27436
+ await listStrategies(client2, args, timeout, session.repairHint)
27437
+ );
26897
27438
  }
26898
27439
  if (tool.name === "mcp-create-strategy") {
26899
27440
  return rejectDuplicateStrategyName(client2, args, timeout, session.repairHint);
@@ -26935,7 +27476,8 @@ function shapeToolResult(tool, args, result, session) {
26935
27476
  const withWorkspace = echoFactorWorkspacePath(tool, skipAware, session.clientRootDir);
26936
27477
  const diagnosed = tool.name === "mcp-factor-calculate-detail" ? diagnoseFactorFailure(withWorkspace) : withWorkspace;
26937
27478
  const distilled = distillFactorDetectReport(tool, args, diagnosed);
26938
- return injectDebugRunId(tool, injectStrategyDocsHint(tool, distilled, session.docsPath));
27479
+ const enriched = injectDebugRunId(tool, injectStrategyDocsHint(tool, distilled, session.docsPath));
27480
+ return shapeDataResultDisclosure(tool, args, shapeListResultDisclosure(tool, args, enriched));
26939
27481
  }
26940
27482
  function backtestStatusNumber(status) {
26941
27483
  return typeof status === "number" || typeof status === "string" && status.trim() !== "" ? Number(status) : NaN;
@@ -27101,7 +27643,7 @@ function backtestWindowPreflightError(tool, reason, message, details) {
27101
27643
  }, true);
27102
27644
  }
27103
27645
  function isExistingAbsoluteDirectory(value) {
27104
- if (!value || !path23.isAbsolute(value)) return false;
27646
+ if (!value || !path24.isAbsolute(value)) return false;
27105
27647
  try {
27106
27648
  return fs24.statSync(value).isDirectory();
27107
27649
  } catch {
@@ -27110,7 +27652,7 @@ function isExistingAbsoluteDirectory(value) {
27110
27652
  }
27111
27653
  function readBacktestIdFromCodePath(codePath) {
27112
27654
  try {
27113
- const tradesettingPath = path23.join(codePath, ".vscode", "tradesetting.json");
27655
+ const tradesettingPath = path24.join(codePath, ".vscode", "tradesetting.json");
27114
27656
  if (!fs24.existsSync(tradesettingPath)) return void 0;
27115
27657
  const parsed = JSON.parse(fs24.readFileSync(tradesettingPath, "utf-8"));
27116
27658
  if (!isRecord4(parsed)) return void 0;
@@ -27580,7 +28122,7 @@ function applyBacktestResultGuards(tool, args, result, states, contexts, activeR
27580
28122
  }
27581
28123
  function readRunResultFile(codePath) {
27582
28124
  try {
27583
- const resultPath = path23.join(codePath, "log", "result.json");
28125
+ const resultPath = path24.join(codePath, "log", "result.json");
27584
28126
  if (!fs24.existsSync(resultPath)) return null;
27585
28127
  const before = fs24.statSync(resultPath);
27586
28128
  const raw = fs24.readFileSync(resultPath);
@@ -27799,7 +28341,7 @@ function echoResolvedBacktestConfig(tool, args, result, contexts) {
27799
28341
  function hashBacktestSource(codePath) {
27800
28342
  if (!codePath) return void 0;
27801
28343
  try {
27802
- const sourcePath = path23.join(codePath, "main.py");
28344
+ const sourcePath = path24.join(codePath, "main.py");
27803
28345
  if (!fs24.statSync(sourcePath).isFile()) return void 0;
27804
28346
  return (0, import_node_crypto4.createHash)("sha256").update(fs24.readFileSync(sourcePath)).digest("hex");
27805
28347
  } catch {
@@ -29433,7 +29975,7 @@ function runtimeRecoveryStopData(message, extra = {}, handler = "runtimeStart")
29433
29975
 
29434
29976
  // src/auth-cli.ts
29435
29977
  var fs26 = __toESM(require("node:fs"), 1);
29436
- var path25 = __toESM(require("node:path"), 1);
29978
+ var path26 = __toESM(require("node:path"), 1);
29437
29979
  var import_node_crypto5 = require("node:crypto");
29438
29980
  var SOURCE = "zlt-mcp-device-login";
29439
29981
  var IGNORED_API_ENV = /* @__PURE__ */ new Set(["ZLTQUANT_API_KEY", "ZLTQUANT_API_BASE"]);
@@ -29465,14 +30007,14 @@ function buildShowWidgetPayload(s) {
29465
30007
  }
29466
30008
  };
29467
30009
  }
29468
- var root = (e = process.env) => path25.join(resolveZltQuantHome(e), "device-auth-sessions");
30010
+ var root = (e = process.env) => path26.join(resolveZltQuantHome(e), "device-auth-sessions");
29469
30011
  function saveDeviceSession(s, e = process.env) {
29470
30012
  if (!validSession(s)) throw new Error("Invalid authentication session");
29471
30013
  const id = (0, import_node_crypto5.randomUUID)();
29472
30014
  fs26.mkdirSync(root(e), { recursive: true, mode: 448 });
29473
30015
  protectPrivatePath(root(e), true);
29474
30016
  fs26.writeFileSync(
29475
- path25.join(root(e), id + ".json"),
30017
+ path26.join(root(e), id + ".json"),
29476
30018
  JSON.stringify({ authorization: s, expiresAt: s.issuedAt + s.expiresIn * 1e3 }),
29477
30019
  { mode: 384, flag: "wx" }
29478
30020
  );
@@ -29508,7 +30050,7 @@ function authErrorMessage(error2) {
29508
30050
  }
29509
30051
  function sessionPath(id, e = process.env) {
29510
30052
  if (!SESSION_ID.test(id)) throw Error("Invalid authentication session");
29511
- return path25.join(root(e), id + ".json");
30053
+ return path26.join(root(e), id + ".json");
29512
30054
  }
29513
30055
  function validateAuthSessionId(id) {
29514
30056
  if (!SESSION_ID.test(id)) throw Error("Invalid authentication session");
@@ -29561,7 +30103,8 @@ async function runAuthLogin(o = {}) {
29561
30103
  status: "pending",
29562
30104
  verificationUri: s.verificationUri,
29563
30105
  userCode: s.userCode
29564
- }) + "\n" : `Open ${s.verificationUri} and enter code ${s.userCode}.
30106
+ }) + "\n" : `Open ${s.verificationUriComplete}
30107
+ If needed, visit ${s.verificationUri} and enter code ${s.userCode}.
29565
30108
  `
29566
30109
  );
29567
30110
  return finish(s, e, c, o.json, o.emit !== false);
@@ -29795,7 +30338,7 @@ if (process.argv.length <= 2) {
29795
30338
  const args = parseMcpArgs(options.argsJson, options.argsFile);
29796
30339
  const timeoutMs = parseTimeoutOption(options.timeoutMs, "--timeout-ms");
29797
30340
  const maxTotalTimeoutMs = parseTimeoutOption(options.maxTotalTimeoutMs, "--max-total-timeout-ms");
29798
- const resultFile = evidence?.resultFile ?? (options.outputJson === void 0 ? void 0 : path26.resolve(options.outputJson));
30341
+ const resultFile = evidence?.resultFile ?? (options.outputJson === void 0 ? void 0 : path27.resolve(options.outputJson));
29799
30342
  stage = "output_prepare";
29800
30343
  if (resultFile !== void 0) outputFd = fs27.openSync(resultFile, "wx");
29801
30344
  stage = "tool_call";
@@ -30028,9 +30571,9 @@ function resolveCliVersion() {
30028
30571
  return resolveCliPackageProvenance().packageVersion;
30029
30572
  }
30030
30573
  function resolveCliPackageProvenance() {
30031
- let current = path26.dirname(path26.resolve(process.argv[1] || process.cwd()));
30574
+ let current = path27.dirname(path27.resolve(process.argv[1] || process.cwd()));
30032
30575
  for (let depth = 0; depth < 6; depth += 1) {
30033
- const manifestPath = path26.join(current, "package.json");
30576
+ const manifestPath = path27.join(current, "package.json");
30034
30577
  try {
30035
30578
  const manifest = JSON.parse(fs27.readFileSync(manifestPath, "utf-8"));
30036
30579
  if ((manifest.name === "@zltquant/zlt-mcp" || manifest.name === "zlt-mcp-proxy") && typeof manifest.version === "string") {
@@ -30038,7 +30581,7 @@ function resolveCliPackageProvenance() {
30038
30581
  }
30039
30582
  } catch {
30040
30583
  }
30041
- const parent = path26.dirname(current);
30584
+ const parent = path27.dirname(current);
30042
30585
  if (parent === current) break;
30043
30586
  current = parent;
30044
30587
  }