@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.
- package/config.json +92 -0
- package/package.json +1 -1
- package/zlt-mcp-proxy.bundle.cjs +787 -244
package/zlt-mcp-proxy.bundle.cjs
CHANGED
|
@@ -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
|
|
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 =
|
|
2150
|
+
const localBin = path28.resolve(baseDir, baseName);
|
|
2151
2151
|
if (fs28.existsSync(localBin)) return localBin;
|
|
2152
|
-
if (sourceExt.includes(
|
|
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 =
|
|
2171
|
-
|
|
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 =
|
|
2178
|
+
const legacyName = path28.basename(
|
|
2179
2179
|
this._scriptPath,
|
|
2180
|
-
|
|
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(
|
|
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 =
|
|
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(
|
|
3053
|
-
if (
|
|
3054
|
-
this._executableDir =
|
|
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(
|
|
6520
|
-
let input =
|
|
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 [
|
|
6720
|
-
wsComponent.path =
|
|
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(
|
|
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 &&
|
|
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,
|
|
10118
|
+
function checkStat(stat, path28, options) {
|
|
10119
10119
|
if (!stat.isSymbolicLink() && !stat.isFile()) {
|
|
10120
10120
|
return false;
|
|
10121
10121
|
}
|
|
10122
|
-
return checkPathExt(
|
|
10122
|
+
return checkPathExt(path28, options);
|
|
10123
10123
|
}
|
|
10124
|
-
function isexe(
|
|
10125
|
-
fs28.stat(
|
|
10126
|
-
cb(er, er ? false : checkStat(stat,
|
|
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(
|
|
10130
|
-
return checkStat(fs28.statSync(
|
|
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(
|
|
10142
|
-
fs28.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(
|
|
10147
|
-
return checkStat(fs28.statSync(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
10209
|
+
function sync(path28, options) {
|
|
10210
10210
|
try {
|
|
10211
|
-
return core.sync(
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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 ?
|
|
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 =
|
|
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 [
|
|
10422
|
-
const binary =
|
|
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
|
|
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 =
|
|
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
|
|
10805
|
-
|
|
10806
|
-
|
|
10807
|
-
--output-json
|
|
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,
|
|
10873
|
+
function unsupportedSchemaConstraint(schemaValue, path28 = "inputSchema") {
|
|
10864
10874
|
const schema = record(schemaValue);
|
|
10865
|
-
if (!schema) return
|
|
10875
|
+
if (!schema) return path28;
|
|
10866
10876
|
for (const keyword of UNSUPPORTED_SCHEMA_KEYWORDS) {
|
|
10867
|
-
if (Object.prototype.hasOwnProperty.call(schema, keyword)) return `${
|
|
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, `${
|
|
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, `${
|
|
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,
|
|
10892
|
+
function explicitValue(schemaValue, path28) {
|
|
10883
10893
|
const schema = record(schemaValue);
|
|
10884
|
-
if (!schema) return { available: false, missing: [
|
|
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],
|
|
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: [
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
11212
|
-
if (!
|
|
11225
|
+
function getElementAtPath(obj, path28) {
|
|
11226
|
+
if (!path28)
|
|
11213
11227
|
return obj;
|
|
11214
|
-
return
|
|
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(
|
|
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(
|
|
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.
|
|
18424
|
-
mini: OFFICIAL_INSTALLERS.public.mini.
|
|
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.
|
|
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
|
|
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
|
|
19652
|
-
const zltFile =
|
|
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
|
|
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(
|
|
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
|
|
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:
|
|
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:
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
20442
|
-
fs6.mkdirSync(
|
|
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\
|
|
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(
|
|
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(
|
|
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\
|
|
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 =
|
|
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
|
|
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 =
|
|
20650
|
-
fs6.mkdirSync(
|
|
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 =
|
|
20672
|
-
const jsserviceRoot = `${
|
|
20673
|
-
const managedGitRoot =
|
|
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
|
-
|
|
20677
|
-
|
|
20678
|
-
|
|
20679
|
-
|
|
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 =
|
|
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}${
|
|
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 (
|
|
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
|
-
|
|
20750
|
-
|
|
20751
|
-
|
|
20752
|
-
|
|
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 =
|
|
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 =
|
|
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 :
|
|
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 || !
|
|
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
|
|
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
|
|
21008
|
-
const
|
|
21009
|
-
|
|
21010
|
-
|
|
21011
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
21409
|
+
return path7.join(workRoot, "python", "python.exe");
|
|
21241
21410
|
}
|
|
21242
21411
|
function getGitExePath(workRoot) {
|
|
21243
|
-
return
|
|
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
|
|
21430
|
+
return path7.join(os.homedir(), "ZLTClient");
|
|
21262
21431
|
}
|
|
21263
21432
|
function getZltafExePath(workRoot) {
|
|
21264
|
-
return
|
|
21433
|
+
return path7.join(workRoot, "zltaf", "zltaf.exe");
|
|
21265
21434
|
}
|
|
21266
21435
|
function getZltafConfigPath(workRoot) {
|
|
21267
|
-
return
|
|
21436
|
+
return path7.join(workRoot, "zltaf", "application-local.properties");
|
|
21268
21437
|
}
|
|
21269
21438
|
function assertPathInside(root2, targetPath) {
|
|
21270
|
-
const resolvedRoot =
|
|
21271
|
-
const resolvedTarget =
|
|
21272
|
-
const relative2 =
|
|
21273
|
-
if (relative2.startsWith("..") ||
|
|
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 =
|
|
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
|
-
|
|
21304
|
-
|
|
21305
|
-
|
|
21306
|
-
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 ?
|
|
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 =
|
|
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:
|
|
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: ${
|
|
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 =
|
|
21762
|
+
var ASSISTANT_UPGRADE_FINISH_LOCK2 = path8.join("Temporary", "upgradeFinsh.lock");
|
|
21594
21763
|
function launchAssistantHost(workRoot, config2, onProgress) {
|
|
21595
|
-
const 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:
|
|
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 =
|
|
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
|
|
21848
|
+
return path8.join(workRoot, "zltaf", "zltaf.exe");
|
|
21680
21849
|
}
|
|
21681
21850
|
function getZltafConfigPath2(workRoot) {
|
|
21682
|
-
return
|
|
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 =
|
|
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 ${
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
22100
|
+
return path9.join(os3.homedir(), input.slice(2));
|
|
21932
22101
|
}
|
|
21933
|
-
return
|
|
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,
|
|
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(
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
22714
|
+
const cwdCandidate = path11.resolve(process.cwd(), "config.json");
|
|
22546
22715
|
const candidates = [
|
|
22547
|
-
|
|
22548
|
-
|
|
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
|
-
|
|
22560
|
-
|
|
22561
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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() ?
|
|
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 (
|
|
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 =
|
|
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 =
|
|
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
|
|
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) :
|
|
22826
|
-
return
|
|
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
|
|
22895
|
-
return
|
|
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
|
|
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",
|
|
22908
|
-
["ZLTAF \u914D\u7F6E",
|
|
22909
|
-
["Python \u7A0B\u5E8F",
|
|
22910
|
-
["MinGit \u7A0B\u5E8F",
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 ||
|
|
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 &&
|
|
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" ||
|
|
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
|
|
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 =
|
|
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
|
|
24312
|
+
var path17 = __toESM(require("node:path"), 1);
|
|
24144
24313
|
var import_node_child_process2 = require("node:child_process");
|
|
24145
|
-
var DEFAULT_TASK_ROOT =
|
|
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
|
|
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:
|
|
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
|
|
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
|
|
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" || !
|
|
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 &&
|
|
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 =
|
|
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
|
|
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(
|
|
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(
|
|
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 (
|
|
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(
|
|
25080
|
+
report = JSON.parse(rawReport);
|
|
24608
25081
|
} catch {
|
|
24609
|
-
return
|
|
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
|
|
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 =
|
|
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:
|
|
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
|
|
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
|
|
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(
|
|
24999
|
-
const dcm = readJsonFile(
|
|
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 =
|
|
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(
|
|
26187
|
+
readSlaveProperties(path21.join(root2, ...ZLTAF_CONFIG_SEGMENTS)),
|
|
25651
26188
|
"slave.factor.project-path",
|
|
25652
26189
|
root2
|
|
25653
26190
|
);
|
|
25654
|
-
const resolved = configured ?
|
|
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 ?
|
|
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(
|
|
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
|
|
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 =
|
|
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(
|
|
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
|
|
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 =
|
|
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 = (
|
|
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
|
|
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
|
-
|
|
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 || !
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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) =>
|
|
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
|
-
|
|
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
|
|
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.
|
|
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 :
|
|
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 =
|
|
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 =
|
|
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 =
|
|
30584
|
+
const parent = path27.dirname(current);
|
|
30042
30585
|
if (parent === current) break;
|
|
30043
30586
|
current = parent;
|
|
30044
30587
|
}
|