@zltquant/zlt-mcp 0.5.0 → 0.6.0-beta.1
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/README.md +14 -1
- package/config.json +10 -9
- package/package.json +1 -1
- package/zlt-mcp-proxy.bundle.cjs +382 -180
package/zlt-mcp-proxy.bundle.cjs
CHANGED
|
@@ -1147,8 +1147,8 @@ 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
|
|
1151
|
-
var
|
|
1150
|
+
var path16 = require("node:path");
|
|
1151
|
+
var fs15 = require("node:fs");
|
|
1152
1152
|
var process4 = require("node:process");
|
|
1153
1153
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
1154
1154
|
var { CommanderError: CommanderError2 } = require_error();
|
|
@@ -2129,7 +2129,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2129
2129
|
* @param {string} subcommandName
|
|
2130
2130
|
*/
|
|
2131
2131
|
_checkForMissingExecutable(executableFile, executableDir, subcommandName) {
|
|
2132
|
-
if (
|
|
2132
|
+
if (fs15.existsSync(executableFile)) return;
|
|
2133
2133
|
const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
|
|
2134
2134
|
const executableMissing = `'${executableFile}' does not exist
|
|
2135
2135
|
- if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
|
|
@@ -2147,11 +2147,11 @@ 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 =
|
|
2151
|
-
if (
|
|
2152
|
-
if (sourceExt.includes(
|
|
2150
|
+
const localBin = path16.resolve(baseDir, baseName);
|
|
2151
|
+
if (fs15.existsSync(localBin)) return localBin;
|
|
2152
|
+
if (sourceExt.includes(path16.extname(baseName))) return void 0;
|
|
2153
2153
|
const foundExt = sourceExt.find(
|
|
2154
|
-
(ext) =>
|
|
2154
|
+
(ext) => fs15.existsSync(`${localBin}${ext}`)
|
|
2155
2155
|
);
|
|
2156
2156
|
if (foundExt) return `${localBin}${foundExt}`;
|
|
2157
2157
|
return void 0;
|
|
@@ -2163,21 +2163,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2163
2163
|
if (this._scriptPath) {
|
|
2164
2164
|
let resolvedScriptPath;
|
|
2165
2165
|
try {
|
|
2166
|
-
resolvedScriptPath =
|
|
2166
|
+
resolvedScriptPath = fs15.realpathSync(this._scriptPath);
|
|
2167
2167
|
} catch {
|
|
2168
2168
|
resolvedScriptPath = this._scriptPath;
|
|
2169
2169
|
}
|
|
2170
|
-
executableDir =
|
|
2171
|
-
|
|
2170
|
+
executableDir = path16.resolve(
|
|
2171
|
+
path16.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 = path16.basename(
|
|
2179
2179
|
this._scriptPath,
|
|
2180
|
-
|
|
2180
|
+
path16.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(path16.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 = path16.basename(filename, path16.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(path17) {
|
|
3053
|
+
if (path17 === void 0) return this._executableDir;
|
|
3054
|
+
this._executableDir = path17;
|
|
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(path16) {
|
|
6520
|
+
let input = path16;
|
|
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 [path16, query] = wsComponent.resourceName.split("?");
|
|
6720
|
+
wsComponent.path = path16 && path16 !== "/" ? path16 : void 0;
|
|
6721
6721
|
wsComponent.query = query;
|
|
6722
6722
|
wsComponent.resourceName = void 0;
|
|
6723
6723
|
}
|
|
@@ -10079,12 +10079,12 @@ var require_dist = __commonJS({
|
|
|
10079
10079
|
throw new Error(`Unknown format "${name}"`);
|
|
10080
10080
|
return f;
|
|
10081
10081
|
};
|
|
10082
|
-
function addFormats(ajv, list,
|
|
10082
|
+
function addFormats(ajv, list, fs15, exportName) {
|
|
10083
10083
|
var _a;
|
|
10084
10084
|
var _b;
|
|
10085
10085
|
(_a = (_b = ajv.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
|
|
10086
10086
|
for (const f of list)
|
|
10087
|
-
ajv.addFormat(f,
|
|
10087
|
+
ajv.addFormat(f, fs15[f]);
|
|
10088
10088
|
}
|
|
10089
10089
|
module2.exports = exports2 = formatsPlugin;
|
|
10090
10090
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -10097,8 +10097,8 @@ var require_windows = __commonJS({
|
|
|
10097
10097
|
"../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/windows.js"(exports2, module2) {
|
|
10098
10098
|
module2.exports = isexe;
|
|
10099
10099
|
isexe.sync = sync;
|
|
10100
|
-
var
|
|
10101
|
-
function checkPathExt(
|
|
10100
|
+
var fs15 = require("fs");
|
|
10101
|
+
function checkPathExt(path16, 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 && path16.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, path16, options) {
|
|
10119
10119
|
if (!stat.isSymbolicLink() && !stat.isFile()) {
|
|
10120
10120
|
return false;
|
|
10121
10121
|
}
|
|
10122
|
-
return checkPathExt(
|
|
10122
|
+
return checkPathExt(path16, options);
|
|
10123
10123
|
}
|
|
10124
|
-
function isexe(
|
|
10125
|
-
|
|
10126
|
-
cb(er, er ? false : checkStat(stat,
|
|
10124
|
+
function isexe(path16, options, cb) {
|
|
10125
|
+
fs15.stat(path16, function(er, stat) {
|
|
10126
|
+
cb(er, er ? false : checkStat(stat, path16, options));
|
|
10127
10127
|
});
|
|
10128
10128
|
}
|
|
10129
|
-
function sync(
|
|
10130
|
-
return checkStat(
|
|
10129
|
+
function sync(path16, options) {
|
|
10130
|
+
return checkStat(fs15.statSync(path16), path16, options);
|
|
10131
10131
|
}
|
|
10132
10132
|
}
|
|
10133
10133
|
});
|
|
@@ -10137,14 +10137,14 @@ var require_mode = __commonJS({
|
|
|
10137
10137
|
"../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/mode.js"(exports2, module2) {
|
|
10138
10138
|
module2.exports = isexe;
|
|
10139
10139
|
isexe.sync = sync;
|
|
10140
|
-
var
|
|
10141
|
-
function isexe(
|
|
10142
|
-
|
|
10140
|
+
var fs15 = require("fs");
|
|
10141
|
+
function isexe(path16, options, cb) {
|
|
10142
|
+
fs15.stat(path16, function(er, stat) {
|
|
10143
10143
|
cb(er, er ? false : checkStat(stat, options));
|
|
10144
10144
|
});
|
|
10145
10145
|
}
|
|
10146
|
-
function sync(
|
|
10147
|
-
return checkStat(
|
|
10146
|
+
function sync(path16, options) {
|
|
10147
|
+
return checkStat(fs15.statSync(path16), options);
|
|
10148
10148
|
}
|
|
10149
10149
|
function checkStat(stat, options) {
|
|
10150
10150
|
return stat.isFile() && checkMode(stat, options);
|
|
@@ -10168,7 +10168,7 @@ var require_mode = __commonJS({
|
|
|
10168
10168
|
// ../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js
|
|
10169
10169
|
var require_isexe = __commonJS({
|
|
10170
10170
|
"../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js"(exports2, module2) {
|
|
10171
|
-
var
|
|
10171
|
+
var fs15 = require("fs");
|
|
10172
10172
|
var core;
|
|
10173
10173
|
if (process.platform === "win32" || global.TESTING_WINDOWS) {
|
|
10174
10174
|
core = require_windows();
|
|
@@ -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(path16, 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(resolve8, reject) {
|
|
10190
|
-
isexe(
|
|
10190
|
+
isexe(path16, 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(path16, 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(path16, options) {
|
|
10210
10210
|
try {
|
|
10211
|
-
return core.sync(
|
|
10211
|
+
return core.sync(path16, 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 path16 = 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 ? resolve8(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 = path16.join(pathPart, cmd);
|
|
10266
10266
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
10267
10267
|
resolve8(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 = path16.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 path16 = 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 ? path16.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 = path16.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 [path16, argument] = match[0].replace(/#! ?/, "").split(" ");
|
|
10422
|
+
const binary = path16.split("/").pop();
|
|
10423
10423
|
if (binary === "env") {
|
|
10424
10424
|
return argument;
|
|
10425
10425
|
}
|
|
@@ -10432,16 +10432,16 @@ var require_shebang_command = __commonJS({
|
|
|
10432
10432
|
var require_readShebang = __commonJS({
|
|
10433
10433
|
"../../node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.js"(exports2, module2) {
|
|
10434
10434
|
"use strict";
|
|
10435
|
-
var
|
|
10435
|
+
var fs15 = require("fs");
|
|
10436
10436
|
var shebangCommand = require_shebang_command();
|
|
10437
10437
|
function readShebang(command) {
|
|
10438
10438
|
const size = 150;
|
|
10439
10439
|
const buffer = Buffer.alloc(size);
|
|
10440
10440
|
let fd;
|
|
10441
10441
|
try {
|
|
10442
|
-
fd =
|
|
10443
|
-
|
|
10444
|
-
|
|
10442
|
+
fd = fs15.openSync(command, "r");
|
|
10443
|
+
fs15.readSync(fd, buffer, 0, size, 0);
|
|
10444
|
+
fs15.closeSync(fd);
|
|
10445
10445
|
} catch (e) {
|
|
10446
10446
|
}
|
|
10447
10447
|
return shebangCommand(buffer.toString());
|
|
@@ -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 path16 = 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 = path16.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(" ");
|
|
@@ -10607,8 +10607,8 @@ var {
|
|
|
10607
10607
|
} = import_index.default;
|
|
10608
10608
|
|
|
10609
10609
|
// src/index.ts
|
|
10610
|
-
var
|
|
10611
|
-
var
|
|
10610
|
+
var fs14 = __toESM(require("node:fs"), 1);
|
|
10611
|
+
var path15 = __toESM(require("node:path"), 1);
|
|
10612
10612
|
|
|
10613
10613
|
// src/cli.ts
|
|
10614
10614
|
var fs9 = __toESM(require("fs"), 1);
|
|
@@ -10812,10 +10812,10 @@ function assignProp(target, prop, value) {
|
|
|
10812
10812
|
configurable: true
|
|
10813
10813
|
});
|
|
10814
10814
|
}
|
|
10815
|
-
function getElementAtPath(obj,
|
|
10816
|
-
if (!
|
|
10815
|
+
function getElementAtPath(obj, path16) {
|
|
10816
|
+
if (!path16)
|
|
10817
10817
|
return obj;
|
|
10818
|
-
return
|
|
10818
|
+
return path16.reduce((acc, key) => acc?.[key], obj);
|
|
10819
10819
|
}
|
|
10820
10820
|
function promiseAllObject(promisesObj) {
|
|
10821
10821
|
const keys = Object.keys(promisesObj);
|
|
@@ -11135,11 +11135,11 @@ function aborted(x, startIndex = 0) {
|
|
|
11135
11135
|
}
|
|
11136
11136
|
return false;
|
|
11137
11137
|
}
|
|
11138
|
-
function prefixIssues(
|
|
11138
|
+
function prefixIssues(path16, issues) {
|
|
11139
11139
|
return issues.map((iss) => {
|
|
11140
11140
|
var _a;
|
|
11141
11141
|
(_a = iss).path ?? (_a.path = []);
|
|
11142
|
-
iss.path.unshift(
|
|
11142
|
+
iss.path.unshift(path16);
|
|
11143
11143
|
return iss;
|
|
11144
11144
|
});
|
|
11145
11145
|
}
|
|
@@ -19166,18 +19166,18 @@ async function waitForPipe(workRoot, pipePrefix, timeout) {
|
|
|
19166
19166
|
throw new Error(`\u7B49\u5F85 ${pipePrefix} \u7BA1\u9053\u8D85\u65F6`);
|
|
19167
19167
|
}
|
|
19168
19168
|
async function readZltContent(workRoot, temporaryZltFile) {
|
|
19169
|
-
const
|
|
19170
|
-
const
|
|
19171
|
-
const zltFile =
|
|
19172
|
-
return
|
|
19169
|
+
const fs15 = await import("fs");
|
|
19170
|
+
const path16 = await import("path");
|
|
19171
|
+
const zltFile = path16.join(workRoot, temporaryZltFile || "Temporary/zlt");
|
|
19172
|
+
return fs15.existsSync(zltFile) ? fs15.readFileSync(zltFile, "utf-8").trim() : "";
|
|
19173
19173
|
}
|
|
19174
19174
|
async function pipeExists2(pipeName) {
|
|
19175
|
-
const
|
|
19175
|
+
const fs15 = await import("fs");
|
|
19176
19176
|
try {
|
|
19177
19177
|
if (process.platform === "win32") {
|
|
19178
|
-
return
|
|
19178
|
+
return fs15.readdirSync("\\\\.\\pipe\\").includes(pipeName);
|
|
19179
19179
|
}
|
|
19180
|
-
return
|
|
19180
|
+
return fs15.existsSync(`/tmp/${pipeName}`);
|
|
19181
19181
|
} catch {
|
|
19182
19182
|
return false;
|
|
19183
19183
|
}
|
|
@@ -19387,8 +19387,8 @@ async function updateRuntimeLeaseActiveJob(handle, runId, active, options = {})
|
|
|
19387
19387
|
async function releaseRuntimeLease(handle, options = {}) {
|
|
19388
19388
|
const deps = options.deps ?? defaultRuntimeLifecycleDeps;
|
|
19389
19389
|
return withLifecycleLock(handle.workRoot, deps, async (stateDir) => {
|
|
19390
|
-
const
|
|
19391
|
-
if (
|
|
19390
|
+
const record3 = readJson(leasePath(stateDir, handle.token));
|
|
19391
|
+
if (record3 && sameIdentity(record3.holder, handle.holder)) {
|
|
19392
19392
|
fs3.rmSync(leasePath(stateDir, handle.token), { force: true });
|
|
19393
19393
|
}
|
|
19394
19394
|
const recordedOwner = readJson(ownerPath(stateDir));
|
|
@@ -19591,13 +19591,13 @@ function readAndPruneStore(stateDir, deps) {
|
|
|
19591
19591
|
if (!entry.isFile() || !entry.name.endsWith(".json"))
|
|
19592
19592
|
continue;
|
|
19593
19593
|
const filePath = path3.join(leasesDir, entry.name);
|
|
19594
|
-
const
|
|
19595
|
-
const current =
|
|
19596
|
-
if (!
|
|
19594
|
+
const record3 = readJson(filePath);
|
|
19595
|
+
const current = record3 ? deps.inspectProcess(record3.holder.pid) : null;
|
|
19596
|
+
if (!record3 || !current || !sameIdentity(current, record3.holder)) {
|
|
19597
19597
|
fs3.rmSync(filePath, { force: true });
|
|
19598
19598
|
continue;
|
|
19599
19599
|
}
|
|
19600
|
-
leases.push(
|
|
19600
|
+
leases.push(record3);
|
|
19601
19601
|
}
|
|
19602
19602
|
let owner = normalizeRuntimeOwnerRecord(readJson(ownerPath(stateDir)));
|
|
19603
19603
|
if (owner) {
|
|
@@ -19609,21 +19609,21 @@ function readAndPruneStore(stateDir, deps) {
|
|
|
19609
19609
|
}
|
|
19610
19610
|
return { owner, leases };
|
|
19611
19611
|
}
|
|
19612
|
-
function normalizeRuntimeOwnerRecord(
|
|
19613
|
-
if (!
|
|
19612
|
+
function normalizeRuntimeOwnerRecord(record3) {
|
|
19613
|
+
if (!record3)
|
|
19614
19614
|
return null;
|
|
19615
|
-
const activeJobIds = new Set(normalizeRunIds(
|
|
19616
|
-
const legacyBoundJobIds = normalizeRunIds(
|
|
19617
|
-
const legacyResolvedJobIds = new Set(normalizeRunIds(
|
|
19615
|
+
const activeJobIds = new Set(normalizeRunIds(record3.activeJobIds));
|
|
19616
|
+
const legacyBoundJobIds = normalizeRunIds(record3.legacyBoundJobIds);
|
|
19617
|
+
const legacyResolvedJobIds = new Set(normalizeRunIds(record3.legacyResolvedJobIds));
|
|
19618
19618
|
for (const runId of legacyBoundJobIds) {
|
|
19619
19619
|
activeJobIds.add(runId);
|
|
19620
19620
|
legacyResolvedJobIds.delete(runId);
|
|
19621
19621
|
}
|
|
19622
19622
|
return {
|
|
19623
|
-
process:
|
|
19624
|
-
startedAt:
|
|
19623
|
+
process: record3.process,
|
|
19624
|
+
startedAt: record3.startedAt,
|
|
19625
19625
|
activeJobIds: [...activeJobIds].sort(),
|
|
19626
|
-
legacyActiveJobs:
|
|
19626
|
+
legacyActiveJobs: record3.legacyActiveJobs === void 0 ? normalizeLegacyActiveJobs(record3.activeJobs) : normalizeLegacyActiveJobs(record3.legacyActiveJobs),
|
|
19627
19627
|
legacyBoundJobIds,
|
|
19628
19628
|
legacyResolvedJobIds: [...legacyResolvedJobIds].sort()
|
|
19629
19629
|
};
|
|
@@ -21715,14 +21715,14 @@ function appendHistory(outputDir, uri, statusCode, contentSize, respFile) {
|
|
|
21715
21715
|
fs9.writeFileSync(historyPath, kept.join("\n") + "\n", "utf-8");
|
|
21716
21716
|
}
|
|
21717
21717
|
}
|
|
21718
|
-
const
|
|
21718
|
+
const record3 = {
|
|
21719
21719
|
time: getTimestampISO(),
|
|
21720
21720
|
uri,
|
|
21721
21721
|
status: statusCode,
|
|
21722
21722
|
size: contentSize
|
|
21723
21723
|
};
|
|
21724
|
-
if (respFile)
|
|
21725
|
-
fs9.appendFileSync(historyPath, JSON.stringify(
|
|
21724
|
+
if (respFile) record3.file = respFile;
|
|
21725
|
+
fs9.appendFileSync(historyPath, JSON.stringify(record3) + "\n", "utf-8");
|
|
21726
21726
|
}
|
|
21727
21727
|
function cleanOutput(clientRootDir, maxDays = 1) {
|
|
21728
21728
|
const outputDir = getOutputDir(clientRootDir);
|
|
@@ -21895,13 +21895,13 @@ function backtestHandoff(result) {
|
|
|
21895
21895
|
const payload = parseMcpResult(result);
|
|
21896
21896
|
const data = payload?.Data;
|
|
21897
21897
|
if (!data || typeof data !== "object" || Array.isArray(data)) return null;
|
|
21898
|
-
const
|
|
21899
|
-
const status = Number(
|
|
21898
|
+
const record3 = data;
|
|
21899
|
+
const status = Number(record3.status);
|
|
21900
21900
|
if (Number.isFinite(status) && status !== 0 && status !== 1) return null;
|
|
21901
|
-
const runId = typeof
|
|
21901
|
+
const runId = typeof record3.runId === "string" ? record3.runId.trim() : "";
|
|
21902
21902
|
if (!runId) return null;
|
|
21903
|
-
const evidence =
|
|
21904
|
-
const rawCodePath = typeof
|
|
21903
|
+
const evidence = record3.evidence && typeof record3.evidence === "object" && !Array.isArray(record3.evidence) ? record3.evidence : void 0;
|
|
21904
|
+
const rawCodePath = typeof record3.codePath === "string" ? record3.codePath.trim() : typeof evidence?.runDir === "string" ? evidence.runDir.trim() : "";
|
|
21905
21905
|
return {
|
|
21906
21906
|
runId,
|
|
21907
21907
|
...rawCodePath && path9.isAbsolute(rawCodePath) ? { codePath: rawCodePath } : {}
|
|
@@ -21915,13 +21915,13 @@ function parseKeepaliveLockRecord(raw) {
|
|
|
21915
21915
|
try {
|
|
21916
21916
|
const parsed = JSON.parse(raw.toString("utf-8"));
|
|
21917
21917
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
21918
|
-
const
|
|
21919
|
-
const processIdentity = parseRuntimeProcessIdentity(
|
|
21920
|
-
return typeof
|
|
21921
|
-
token:
|
|
21922
|
-
pid: Number(
|
|
21918
|
+
const record3 = parsed;
|
|
21919
|
+
const processIdentity = parseRuntimeProcessIdentity(record3.processIdentity);
|
|
21920
|
+
return typeof record3.token === "string" && record3.token.length > 0 && Number.isSafeInteger(record3.pid) && Number(record3.pid) > 0 && processIdentity?.pid === Number(record3.pid) && Number.isSafeInteger(record3.heartbeatAt) && Number(record3.heartbeatAt) > 0 ? {
|
|
21921
|
+
token: record3.token,
|
|
21922
|
+
pid: Number(record3.pid),
|
|
21923
21923
|
processIdentity,
|
|
21924
|
-
heartbeatAt: Number(
|
|
21924
|
+
heartbeatAt: Number(record3.heartbeatAt)
|
|
21925
21925
|
} : null;
|
|
21926
21926
|
} catch {
|
|
21927
21927
|
return null;
|
|
@@ -21929,11 +21929,11 @@ function parseKeepaliveLockRecord(raw) {
|
|
|
21929
21929
|
}
|
|
21930
21930
|
function parseRuntimeProcessIdentity(value) {
|
|
21931
21931
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
21932
|
-
const
|
|
21933
|
-
return Number.isSafeInteger(
|
|
21934
|
-
pid: Number(
|
|
21935
|
-
executablePath:
|
|
21936
|
-
creationTime:
|
|
21932
|
+
const record3 = value;
|
|
21933
|
+
return Number.isSafeInteger(record3.pid) && Number(record3.pid) > 0 && typeof record3.executablePath === "string" && record3.executablePath.length > 0 && typeof record3.creationTime === "string" && record3.creationTime.length > 0 ? {
|
|
21934
|
+
pid: Number(record3.pid),
|
|
21935
|
+
executablePath: record3.executablePath,
|
|
21936
|
+
creationTime: record3.creationTime
|
|
21937
21937
|
} : null;
|
|
21938
21938
|
}
|
|
21939
21939
|
function readKeepaliveLock(lockPath) {
|
|
@@ -21975,15 +21975,15 @@ function currentKeepaliveProcessIdentity() {
|
|
|
21975
21975
|
if (!identity) throw new Error(`Unable to identify keepalive process pid=${process.pid}`);
|
|
21976
21976
|
return identity;
|
|
21977
21977
|
}
|
|
21978
|
-
function keepaliveProcessIsCurrent(
|
|
21979
|
-
if (!processIsAlive(
|
|
21980
|
-
const current = inspectRuntimeProcess(
|
|
21981
|
-
return current ? sameProcessIdentity(current,
|
|
21978
|
+
function keepaliveProcessIsCurrent(record3) {
|
|
21979
|
+
if (!processIsAlive(record3.pid)) return false;
|
|
21980
|
+
const current = inspectRuntimeProcess(record3.pid);
|
|
21981
|
+
return current ? sameProcessIdentity(current, record3.processIdentity) : true;
|
|
21982
21982
|
}
|
|
21983
|
-
function writeNewKeepaliveLock(lockPath,
|
|
21983
|
+
function writeNewKeepaliveLock(lockPath, record3) {
|
|
21984
21984
|
const descriptor = fs9.openSync(lockPath, "wx", 384);
|
|
21985
21985
|
try {
|
|
21986
|
-
fs9.writeFileSync(descriptor, JSON.stringify(
|
|
21986
|
+
fs9.writeFileSync(descriptor, JSON.stringify(record3), "utf-8");
|
|
21987
21987
|
} finally {
|
|
21988
21988
|
fs9.closeSync(descriptor);
|
|
21989
21989
|
}
|
|
@@ -22054,8 +22054,8 @@ function releaseKeepaliveLock(ownership) {
|
|
|
22054
22054
|
retireKeepaliveLockIfUnchanged(ownership.lockPath, current.identity);
|
|
22055
22055
|
}
|
|
22056
22056
|
}
|
|
22057
|
-
function keepaliveLeaseIsFresh(
|
|
22058
|
-
return keepaliveTimestampIsFresh(
|
|
22057
|
+
function keepaliveLeaseIsFresh(record3) {
|
|
22058
|
+
return keepaliveTimestampIsFresh(record3.heartbeatAt);
|
|
22059
22059
|
}
|
|
22060
22060
|
function keepaliveTimestampIsFresh(timestamp) {
|
|
22061
22061
|
const age = Date.now() - timestamp;
|
|
@@ -23123,9 +23123,9 @@ var StdioServerTransport = class {
|
|
|
23123
23123
|
};
|
|
23124
23124
|
|
|
23125
23125
|
// src/mcp-server.ts
|
|
23126
|
-
var
|
|
23126
|
+
var fs13 = __toESM(require("node:fs"), 1);
|
|
23127
23127
|
var os5 = __toESM(require("node:os"), 1);
|
|
23128
|
-
var
|
|
23128
|
+
var path14 = __toESM(require("node:path"), 1);
|
|
23129
23129
|
|
|
23130
23130
|
// src/tool-profile-contract.mjs
|
|
23131
23131
|
var UNIVERSAL_AGENT_RUNTIME_TOOL_NAMES = Object.freeze([
|
|
@@ -23188,9 +23188,9 @@ var NPM_PACKAGE_CONFIG_TOOL_NAMES = Object.freeze([
|
|
|
23188
23188
|
]);
|
|
23189
23189
|
|
|
23190
23190
|
// src/tool-pipeline.ts
|
|
23191
|
-
var
|
|
23192
|
-
var
|
|
23193
|
-
var
|
|
23191
|
+
var fs12 = __toESM(require("node:fs"), 1);
|
|
23192
|
+
var path12 = __toESM(require("node:path"), 1);
|
|
23193
|
+
var import_node_crypto3 = require("node:crypto");
|
|
23194
23194
|
|
|
23195
23195
|
// src/feature-set.ts
|
|
23196
23196
|
function resolveFeatureSet() {
|
|
@@ -23199,6 +23199,119 @@ function resolveFeatureSet() {
|
|
|
23199
23199
|
var MASKED_FACTOR_MESSAGE = "\u56E0\u5B50\u7814\u7A76\u529F\u80FD\u5728\u5F53\u524D\u7248\u672C\u672A\u5F00\u653E\u3002";
|
|
23200
23200
|
var MASKED_FUTURES_MESSAGE = "\u671F\u8D27\u56DE\u6D4B\u5728\u5F53\u524D\u7248\u672C\u672A\u5F00\u653E\uFF1ArunParams.marketIds \u542B\u671F\u8D27\u4EA4\u6613\u6240\uFF08zj/zs/ds/sq/gq\uFF09\u6216 account_list \u7684 account_type \u4E3A\u671F\u8D27\u3002\u8BF7\u4F7F\u7528\u80A1\u7968\u5E02\u573A\uFF08sh/sz\uFF09\u4E0E account_type=1\u3002";
|
|
23201
23201
|
|
|
23202
|
+
// src/backtest-config.ts
|
|
23203
|
+
var fs11 = __toESM(require("node:fs"), 1);
|
|
23204
|
+
var path11 = __toESM(require("node:path"), 1);
|
|
23205
|
+
var import_node_crypto2 = require("node:crypto");
|
|
23206
|
+
var BACKTEST_CONFIG_KEYS = [
|
|
23207
|
+
"start",
|
|
23208
|
+
"end",
|
|
23209
|
+
"freq",
|
|
23210
|
+
"kcount",
|
|
23211
|
+
"marketIds",
|
|
23212
|
+
"trade_type",
|
|
23213
|
+
"initial_capital",
|
|
23214
|
+
"account_list",
|
|
23215
|
+
"base_tpl_obj",
|
|
23216
|
+
"ratio_tpl_obj"
|
|
23217
|
+
];
|
|
23218
|
+
var INTERNAL_CONFIG_KEYS = ["btmode", "st_parmas", "mode", "class_type", "base_tpl_id", "ratio_tpl_id"];
|
|
23219
|
+
var BASE_KEYS = [
|
|
23220
|
+
"name",
|
|
23221
|
+
"zhCnName",
|
|
23222
|
+
"benchmark",
|
|
23223
|
+
"matching_mode",
|
|
23224
|
+
"slippage",
|
|
23225
|
+
"avoid_future",
|
|
23226
|
+
"open_cache",
|
|
23227
|
+
"match_with_order_book",
|
|
23228
|
+
"max_trade_ratio",
|
|
23229
|
+
"order_volume_ratio",
|
|
23230
|
+
"take_fee_type",
|
|
23231
|
+
"adjust_aqty_by_avail",
|
|
23232
|
+
"jv_kuan_open_avg_cost_switch"
|
|
23233
|
+
];
|
|
23234
|
+
var FEE_KEYS = [
|
|
23235
|
+
"open_commission",
|
|
23236
|
+
"close_commission",
|
|
23237
|
+
"close_today_commission",
|
|
23238
|
+
"min_commission",
|
|
23239
|
+
"open_tax",
|
|
23240
|
+
"close_tax",
|
|
23241
|
+
"margin_ratio"
|
|
23242
|
+
];
|
|
23243
|
+
var record2 = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
23244
|
+
var pick2 = (v, keys) => Object.fromEntries(keys.filter((k) => Object.prototype.hasOwnProperty.call(v, k)).map((k) => [k, v[k]]));
|
|
23245
|
+
function readBacktestBaseline(tool, args) {
|
|
23246
|
+
const create = tool === "mcp-create-and-run-backtest";
|
|
23247
|
+
if (!create && tool !== "mcp-re-backtest") return void 0;
|
|
23248
|
+
const directory = args[create ? "strategyPath" : "codePath"];
|
|
23249
|
+
if (directory === void 0) return void 0;
|
|
23250
|
+
if (typeof directory !== "string" || !path11.isAbsolute(directory)) throw new Error("Configuration baseline requires an absolute directory path");
|
|
23251
|
+
const root = fs11.realpathSync(directory);
|
|
23252
|
+
if (create && path11.basename(path11.dirname(root)).toLowerCase() === "backtest") {
|
|
23253
|
+
throw new Error("strategyPath must identify the strategy root, not a historical backtest directory");
|
|
23254
|
+
}
|
|
23255
|
+
const file = path11.join(root, ".vscode", "tradesetting.json");
|
|
23256
|
+
const raw = fs11.readFileSync(file);
|
|
23257
|
+
let config2;
|
|
23258
|
+
try {
|
|
23259
|
+
config2 = JSON.parse(raw.toString("utf8").replace(/^\uFEFF/, ""));
|
|
23260
|
+
} catch {
|
|
23261
|
+
throw new Error("Configuration baseline is not valid JSON");
|
|
23262
|
+
}
|
|
23263
|
+
if (!record2(config2) || config2.strategy_id !== args.strategyId) throw new Error("Configuration baseline strategy_id is missing or mismatched");
|
|
23264
|
+
if (!create && (typeof args.runId !== "string" || config2.backtest_id !== args.runId)) {
|
|
23265
|
+
throw new Error("Configuration baseline backtest_id does not match the requested runId");
|
|
23266
|
+
}
|
|
23267
|
+
const params = pick2(config2, [...BACKTEST_CONFIG_KEYS, ...INTERNAL_CONFIG_KEYS]);
|
|
23268
|
+
for (const key of ["base_tpl_obj", "ratio_tpl_obj"]) {
|
|
23269
|
+
if (params[key] !== void 0 && !record2(params[key])) throw new Error(`Configuration baseline ${key} must be an object`);
|
|
23270
|
+
}
|
|
23271
|
+
if (record2(params.base_tpl_obj)) params.base_tpl_obj = pick2(params.base_tpl_obj, BASE_KEYS);
|
|
23272
|
+
if (record2(params.ratio_tpl_obj)) {
|
|
23273
|
+
const fees = params.ratio_tpl_obj;
|
|
23274
|
+
for (const asset of ["stock", "future", "fund", "bond"]) {
|
|
23275
|
+
if (fees[asset] !== void 0 && !record2(fees[asset])) throw new Error(`Configuration baseline fee section ${asset} must be an object`);
|
|
23276
|
+
}
|
|
23277
|
+
params.ratio_tpl_obj = {
|
|
23278
|
+
...pick2(fees, ["name", "zhCnName"]),
|
|
23279
|
+
...Object.fromEntries(["stock", "future", "fund", "bond"].filter((k) => record2(fees[k])).map((k) => [k, pick2(fees[k], FEE_KEYS)]))
|
|
23280
|
+
};
|
|
23281
|
+
}
|
|
23282
|
+
if (Array.isArray(params.account_list)) {
|
|
23283
|
+
params.account_list = params.account_list.map((account) => {
|
|
23284
|
+
if (!record2(account)) throw new Error("Configuration baseline account_list contains a non-object");
|
|
23285
|
+
const result = pick2(account, ["pindex", "account_id", "cash", "account_type"]);
|
|
23286
|
+
if (create && typeof result.account_id === "string" && /^RN-[A-Za-z0-9-]+_\d+$/.test(result.account_id)) result.account_id = "";
|
|
23287
|
+
return result;
|
|
23288
|
+
});
|
|
23289
|
+
}
|
|
23290
|
+
return { params, evidence: {
|
|
23291
|
+
kind: create ? "strategy_current" : "selected_run",
|
|
23292
|
+
path: file,
|
|
23293
|
+
sha256: (0, import_node_crypto2.createHash)("sha256").update(raw).digest("hex")
|
|
23294
|
+
} };
|
|
23295
|
+
}
|
|
23296
|
+
function reconcileBaselineCapital(params, overrides) {
|
|
23297
|
+
const accounts = params.account_list;
|
|
23298
|
+
if (!Array.isArray(accounts) || !accounts.length || accounts.some((a) => !record2(a) || typeof a.cash !== "number" || !Number.isFinite(a.cash) || a.cash < 0)) {
|
|
23299
|
+
throw new Error("Configuration baseline requires accounts with finite nonnegative cash");
|
|
23300
|
+
}
|
|
23301
|
+
const explicitCapital = Object.prototype.hasOwnProperty.call(overrides, "initial_capital");
|
|
23302
|
+
const explicitAccounts = Object.prototype.hasOwnProperty.call(overrides, "account_list");
|
|
23303
|
+
if (explicitCapital && !explicitAccounts) {
|
|
23304
|
+
if (accounts.length !== 1) throw new Error("Changing capital for multiple accounts requires an explicit account_list allocation");
|
|
23305
|
+
if (typeof params.initial_capital !== "number" || !Number.isFinite(params.initial_capital) || params.initial_capital <= 0) throw new Error("initial_capital must be positive and finite");
|
|
23306
|
+
accounts[0] = { ...accounts[0], cash: params.initial_capital };
|
|
23307
|
+
}
|
|
23308
|
+
const total = accounts.reduce((sum, a) => sum + a.cash, 0);
|
|
23309
|
+
if (explicitAccounts && !explicitCapital || params.initial_capital === void 0) params.initial_capital = total;
|
|
23310
|
+
if (typeof params.initial_capital !== "number" || !Number.isFinite(params.initial_capital) || params.initial_capital <= 0 || Math.abs(params.initial_capital - total) > 5e-3) {
|
|
23311
|
+
throw new Error("initial_capital must match the sum of account cash; supply a consistent allocation");
|
|
23312
|
+
}
|
|
23313
|
+
}
|
|
23314
|
+
|
|
23202
23315
|
// src/tool-pipeline.ts
|
|
23203
23316
|
function finitePositiveNumber(value) {
|
|
23204
23317
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
|
|
@@ -23228,6 +23341,44 @@ function isFuturesRun(marketIds) {
|
|
|
23228
23341
|
return marketIds.some((id) => FUTURES_MARKET_IDS.has(String(id).trim().toLowerCase()));
|
|
23229
23342
|
}
|
|
23230
23343
|
var identityRepairHint = (data) => data;
|
|
23344
|
+
function prepareToolCallArgs(tool, args, contexts) {
|
|
23345
|
+
const clean = { ...args };
|
|
23346
|
+
delete clean.__configBaseline;
|
|
23347
|
+
delete clean.__storedRunParams;
|
|
23348
|
+
try {
|
|
23349
|
+
if (tool.name === "mcp-re-backtest" && (clean.runParams === void 0 || isRecord2(clean.runParams) && Object.keys(clean.runParams).length === 0)) {
|
|
23350
|
+
readBacktestBaseline(tool.name, clean);
|
|
23351
|
+
const prior = typeof clean.runId === "string" ? contexts.get(clean.runId) : void 0;
|
|
23352
|
+
if (prior && prior.strategyId !== clean.strategyId) throw new Error("Cached run belongs to another strategy");
|
|
23353
|
+
delete clean.runParams;
|
|
23354
|
+
return prepareToolArgs(tool, applyToolArgDefaults(tool, { ...clean, __storedRunParams: true }), contexts);
|
|
23355
|
+
}
|
|
23356
|
+
const baseline = readBacktestBaseline(tool.name, clean);
|
|
23357
|
+
if (!baseline) {
|
|
23358
|
+
if (tool.name === "mcp-re-backtest") {
|
|
23359
|
+
const prior = typeof clean.runId === "string" ? contexts.get(clean.runId) : void 0;
|
|
23360
|
+
if (prior && prior.strategyId !== clean.strategyId) throw new Error("Cached run belongs to another strategy");
|
|
23361
|
+
const supplied = isRecord2(clean.runParams) ? clean.runParams : {};
|
|
23362
|
+
if (!prior?.runParams && BACKTEST_CONFIG_KEYS.some((key) => supplied[key] === void 0 || supplied[key] === null)) {
|
|
23363
|
+
throw new Error("Rerun has no persistent or cached baseline; supply codePath or complete runParams");
|
|
23364
|
+
}
|
|
23365
|
+
}
|
|
23366
|
+
return prepareToolArgs(tool, applyToolArgDefaults(tool, clean), contexts);
|
|
23367
|
+
}
|
|
23368
|
+
if (clean.runParams !== void 0 && !isRecord2(clean.runParams)) throw new Error("runParams overrides must be an object");
|
|
23369
|
+
const overrides = clean.runParams ?? {};
|
|
23370
|
+
const runParams = applyBodyDefaults(baseline.params, overrides);
|
|
23371
|
+
const merged = applyToolArgDefaults(tool, { ...clean, runParams, __configBaseline: baseline.evidence });
|
|
23372
|
+
reconcileBaselineCapital(merged.runParams, overrides);
|
|
23373
|
+
return prepareToolArgs(tool, merged, contexts);
|
|
23374
|
+
} catch (error2) {
|
|
23375
|
+
return jsonToolResult(10063, "\u56DE\u6D4B\u914D\u7F6E\u57FA\u7EBF\u4E0D\u53EF\u7528\u6216\u8986\u76D6\u53C2\u6570\u51B2\u7A81", {
|
|
23376
|
+
reason: error2 instanceof Error ? error2.message : String(error2),
|
|
23377
|
+
toolExecution: "not_started",
|
|
23378
|
+
action: "Check the supplied strategyPath/codePath, configuration identity and account allocation, then retry."
|
|
23379
|
+
}, true);
|
|
23380
|
+
}
|
|
23381
|
+
}
|
|
23231
23382
|
function prepareToolArgs(tool, args, contexts) {
|
|
23232
23383
|
const inherited = inheritReBacktestRunParams(tool, args, contexts);
|
|
23233
23384
|
const dated = applyBacktestDateDefaults(tool, inherited);
|
|
@@ -23362,7 +23513,7 @@ function readSlaveProperties(filePath) {
|
|
|
23362
23513
|
const entries = /* @__PURE__ */ new Map();
|
|
23363
23514
|
let raw;
|
|
23364
23515
|
try {
|
|
23365
|
-
raw =
|
|
23516
|
+
raw = fs12.readFileSync(filePath, "utf-8");
|
|
23366
23517
|
} catch {
|
|
23367
23518
|
return entries;
|
|
23368
23519
|
}
|
|
@@ -23386,18 +23537,18 @@ function resolveFactorProjectRoot(clientRootDir) {
|
|
|
23386
23537
|
if (cached2) return cached2;
|
|
23387
23538
|
const root = clientRootDir.replace(/[\\/]+$/, "");
|
|
23388
23539
|
const configured = expandSlaveValue(
|
|
23389
|
-
readSlaveProperties(
|
|
23540
|
+
readSlaveProperties(path12.join(root, ...ZLTAF_CONFIG_SEGMENTS)),
|
|
23390
23541
|
"slave.factor.project-path",
|
|
23391
23542
|
root
|
|
23392
23543
|
);
|
|
23393
|
-
const resolved = configured ?
|
|
23544
|
+
const resolved = configured ? path12.normalize(configured) : path12.join(root, ...FALLBACK_FACTOR_PROJECT_PATH);
|
|
23394
23545
|
factorProjectRootCache.set(clientRootDir, resolved);
|
|
23395
23546
|
return resolved;
|
|
23396
23547
|
}
|
|
23397
23548
|
function resolveFactorWorkspacePath(clientRootDir, factorId) {
|
|
23398
23549
|
if (!clientRootDir || !factorId) return void 0;
|
|
23399
23550
|
const projectRoot = resolveFactorProjectRoot(clientRootDir);
|
|
23400
|
-
return projectRoot ?
|
|
23551
|
+
return projectRoot ? path12.join(projectRoot, factorId) : void 0;
|
|
23401
23552
|
}
|
|
23402
23553
|
var MODULE_LEVEL_FACTOR_EXPORT = /^(?:(?:async\s+)?def\s+get_factor\s*\(|get_factor\s*=(?!=)|Factor\s*=(?!=))/m;
|
|
23403
23554
|
function checkFactorSourceLoadable(clientRootDir, factorId) {
|
|
@@ -23405,7 +23556,7 @@ function checkFactorSourceLoadable(clientRootDir, factorId) {
|
|
|
23405
23556
|
if (!workspacePath) return null;
|
|
23406
23557
|
let source;
|
|
23407
23558
|
try {
|
|
23408
|
-
source =
|
|
23559
|
+
source = fs12.readFileSync(path12.join(workspacePath, "main.py"), "utf8");
|
|
23409
23560
|
} catch {
|
|
23410
23561
|
return null;
|
|
23411
23562
|
}
|
|
@@ -23504,6 +23655,9 @@ var CONTROL_PARAMS = [
|
|
|
23504
23655
|
"timeout",
|
|
23505
23656
|
"confirm",
|
|
23506
23657
|
"codePath",
|
|
23658
|
+
"strategyPath",
|
|
23659
|
+
"__configBaseline",
|
|
23660
|
+
"__storedRunParams",
|
|
23507
23661
|
"attemptFence",
|
|
23508
23662
|
"__attemptStartedAtMs",
|
|
23509
23663
|
"__resultBaseline"
|
|
@@ -23524,12 +23678,12 @@ function normalizeBacktestRunName(tool, args) {
|
|
|
23524
23678
|
};
|
|
23525
23679
|
}
|
|
23526
23680
|
function inheritReBacktestRunParams(tool, args, contexts) {
|
|
23527
|
-
if (tool.name !== "mcp-re-backtest") return args;
|
|
23681
|
+
if (tool.name !== "mcp-re-backtest" || args.__configBaseline || args.__storedRunParams) return args;
|
|
23528
23682
|
const runId = typeof args.runId === "string" ? args.runId.trim() : "";
|
|
23529
23683
|
const prior = runId ? contexts.get(runId)?.runParams : void 0;
|
|
23530
23684
|
if (!prior) return args;
|
|
23531
23685
|
const runParams = isRecord2(args.runParams) ? args.runParams : {};
|
|
23532
|
-
return { ...args, runParams:
|
|
23686
|
+
return { ...args, runParams: applyBodyDefaults(prior, runParams) };
|
|
23533
23687
|
}
|
|
23534
23688
|
function applyBacktestDateDefaults(tool, args) {
|
|
23535
23689
|
if (tool.name !== "mcp-create-and-run-backtest") return args;
|
|
@@ -23645,18 +23799,18 @@ function backtestWindowPreflightError(tool, reason, message, details) {
|
|
|
23645
23799
|
}, true);
|
|
23646
23800
|
}
|
|
23647
23801
|
function isExistingAbsoluteDirectory(value) {
|
|
23648
|
-
if (!value || !
|
|
23802
|
+
if (!value || !path12.isAbsolute(value)) return false;
|
|
23649
23803
|
try {
|
|
23650
|
-
return
|
|
23804
|
+
return fs12.statSync(value).isDirectory();
|
|
23651
23805
|
} catch {
|
|
23652
23806
|
return false;
|
|
23653
23807
|
}
|
|
23654
23808
|
}
|
|
23655
23809
|
function readBacktestIdFromCodePath(codePath) {
|
|
23656
23810
|
try {
|
|
23657
|
-
const tradesettingPath =
|
|
23658
|
-
if (!
|
|
23659
|
-
const parsed = JSON.parse(
|
|
23811
|
+
const tradesettingPath = path12.join(codePath, ".vscode", "tradesetting.json");
|
|
23812
|
+
if (!fs12.existsSync(tradesettingPath)) return void 0;
|
|
23813
|
+
const parsed = JSON.parse(fs12.readFileSync(tradesettingPath, "utf-8"));
|
|
23660
23814
|
if (!isRecord2(parsed)) return void 0;
|
|
23661
23815
|
const value = parsed.backtest_id ?? parsed.backtestId;
|
|
23662
23816
|
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
@@ -23680,7 +23834,7 @@ function capturePendingBacktestAttempt(tool, args, contexts) {
|
|
|
23680
23834
|
if (tool.name !== "mcp-create-and-run-backtest" && tool.name !== "mcp-re-backtest") return;
|
|
23681
23835
|
const runId = typeof args.runId === "string" ? args.runId.trim() : "";
|
|
23682
23836
|
const suppliedCodePath = typeof args.codePath === "string" ? args.codePath.trim() : "";
|
|
23683
|
-
const codePath = (runId ? contexts.get(runId)?.codePath : void 0) || suppliedCodePath;
|
|
23837
|
+
const codePath = args.__configBaseline ? suppliedCodePath : (runId ? contexts.get(runId)?.codePath : void 0) || suppliedCodePath;
|
|
23684
23838
|
const resultFile = codePath ? readRunResultFile(codePath) : null;
|
|
23685
23839
|
pendingBacktestAttempts.set(args, {
|
|
23686
23840
|
...resultFile ? { resultBaseline: resultFile.identity } : {},
|
|
@@ -24352,9 +24506,9 @@ var FACTOR_FAILURE_SIGNATURES = [
|
|
|
24352
24506
|
function factorFailureMessage(data) {
|
|
24353
24507
|
if (typeof data.errorMessage === "string" && data.errorMessage) return data.errorMessage;
|
|
24354
24508
|
for (const key of ["calculateRecord", "detectRecord"]) {
|
|
24355
|
-
const
|
|
24356
|
-
if (isRecord2(
|
|
24357
|
-
return
|
|
24509
|
+
const record3 = data[key];
|
|
24510
|
+
if (isRecord2(record3) && typeof record3.errorMessage === "string" && record3.errorMessage) {
|
|
24511
|
+
return record3.errorMessage;
|
|
24358
24512
|
}
|
|
24359
24513
|
}
|
|
24360
24514
|
return "";
|
|
@@ -24798,18 +24952,18 @@ function applyBacktestResultGuards(tool, args, result, states, contexts, activeR
|
|
|
24798
24952
|
}
|
|
24799
24953
|
function readRunResultFile(codePath) {
|
|
24800
24954
|
try {
|
|
24801
|
-
const resultPath =
|
|
24802
|
-
if (!
|
|
24803
|
-
const before =
|
|
24804
|
-
const raw =
|
|
24805
|
-
const after =
|
|
24955
|
+
const resultPath = path12.join(codePath, "log", "result.json");
|
|
24956
|
+
if (!fs12.existsSync(resultPath)) return null;
|
|
24957
|
+
const before = fs12.statSync(resultPath);
|
|
24958
|
+
const raw = fs12.readFileSync(resultPath);
|
|
24959
|
+
const after = fs12.statSync(resultPath);
|
|
24806
24960
|
if (before.mtimeMs !== after.mtimeMs || before.size !== after.size) return null;
|
|
24807
24961
|
const parsed = JSON.parse(raw.toString("utf-8"));
|
|
24808
24962
|
if (!isRecord2(parsed)) return null;
|
|
24809
24963
|
return {
|
|
24810
24964
|
data: parsed,
|
|
24811
24965
|
identity: {
|
|
24812
|
-
sha256: (0,
|
|
24966
|
+
sha256: (0, import_node_crypto3.createHash)("sha256").update(raw).digest("hex"),
|
|
24813
24967
|
mtimeMs: after.mtimeMs,
|
|
24814
24968
|
size: after.size
|
|
24815
24969
|
}
|
|
@@ -24918,7 +25072,7 @@ function captureBacktestRunContext(tool, args, result, contexts, activeRunIds) {
|
|
|
24918
25072
|
const strategyId = typeof args.strategyId === "string" ? args.strategyId : "";
|
|
24919
25073
|
const start = typeof runParams.start === "string" ? runParams.start : "";
|
|
24920
25074
|
const end = typeof runParams.end === "string" ? runParams.end : "";
|
|
24921
|
-
if (!strategyId || !start || !end) return;
|
|
25075
|
+
if (!strategyId || (!start || !end) && !args.__storedRunParams) return;
|
|
24922
25076
|
try {
|
|
24923
25077
|
const parsed = JSON.parse(result.content[0].text);
|
|
24924
25078
|
if (!isRecord2(parsed) || !isRecord2(parsed.Data)) return;
|
|
@@ -24926,7 +25080,7 @@ function captureBacktestRunContext(tool, args, result, contexts, activeRunIds) {
|
|
|
24926
25080
|
const runId = echoedRunId || (isRerun && typeof args.runId === "string" ? args.runId.trim() : "");
|
|
24927
25081
|
const prior = runId ? contexts.get(runId) : void 0;
|
|
24928
25082
|
const suppliedCodePath = typeof args.codePath === "string" ? args.codePath.trim() : "";
|
|
24929
|
-
const codePath = typeof parsed.Data.codePath === "string" && parsed.Data.codePath.trim() ? parsed.Data.codePath.trim() : prior?.codePath || suppliedCodePath;
|
|
25083
|
+
const codePath = typeof parsed.Data.codePath === "string" && parsed.Data.codePath.trim() ? parsed.Data.codePath.trim() : args.__configBaseline ? suppliedCodePath : prior?.codePath || suppliedCodePath;
|
|
24930
25084
|
if (runId) {
|
|
24931
25085
|
const marketIds = Array.isArray(runParams.marketIds) ? runParams.marketIds.filter((id) => typeof id === "string") : prior?.marketIds;
|
|
24932
25086
|
const sourceSha256 = hashBacktestSource(codePath) ?? prior?.sourceSha256;
|
|
@@ -24955,6 +25109,11 @@ function echoResolvedBacktestConfig(tool, args, result, contexts) {
|
|
|
24955
25109
|
const resolvedCapital = resolveBacktestCapital(runParams);
|
|
24956
25110
|
const resolvedBenchmark = resolveBacktestBenchmark(runParams);
|
|
24957
25111
|
const echo = {};
|
|
25112
|
+
echo.configurationEvidence = {
|
|
25113
|
+
source: args.__storedRunParams ? "zltaf_stored_parameters" : "mcp_submission",
|
|
25114
|
+
persistenceVerified: false,
|
|
25115
|
+
...args.__configBaseline ? { baseline: args.__configBaseline } : {}
|
|
25116
|
+
};
|
|
24958
25117
|
if (resolvedStart) echo.resolvedStart = resolvedStart;
|
|
24959
25118
|
if (resolvedEnd) echo.resolvedEnd = resolvedEnd;
|
|
24960
25119
|
if (resolvedCapital !== null) echo.resolvedCapital = resolvedCapital;
|
|
@@ -24976,7 +25135,7 @@ function echoResolvedBacktestConfig(tool, args, result, contexts) {
|
|
|
24976
25135
|
echo.codePath = context.codePath;
|
|
24977
25136
|
echo.runDir = context.codePath;
|
|
24978
25137
|
}
|
|
24979
|
-
if (context?.runParams) echo.runParams = { ...context.runParams };
|
|
25138
|
+
if (context?.runParams && !args.__storedRunParams) echo.runParams = { ...context.runParams };
|
|
24980
25139
|
if (context?.attemptStartedAtMs) {
|
|
24981
25140
|
echo.attemptFence = {
|
|
24982
25141
|
attemptStartedAtMs: context.attemptStartedAtMs,
|
|
@@ -24989,7 +25148,7 @@ function echoResolvedBacktestConfig(tool, args, result, contexts) {
|
|
|
24989
25148
|
backtestId: runId,
|
|
24990
25149
|
...context?.codePath ? { runDir: context.codePath } : {},
|
|
24991
25150
|
...context?.strategyId ? { strategyId: context.strategyId } : {},
|
|
24992
|
-
...context?.runParams ? { effectiveRunParams: { ...context.runParams } } : {},
|
|
25151
|
+
...context?.runParams && !args.__storedRunParams ? { effectiveRunParams: { ...context.runParams } } : {},
|
|
24993
25152
|
...context?.sourceSha256 ? { sourceSha256: context.sourceSha256 } : {}
|
|
24994
25153
|
};
|
|
24995
25154
|
}
|
|
@@ -25011,9 +25170,9 @@ function echoResolvedBacktestConfig(tool, args, result, contexts) {
|
|
|
25011
25170
|
function hashBacktestSource(codePath) {
|
|
25012
25171
|
if (!codePath) return void 0;
|
|
25013
25172
|
try {
|
|
25014
|
-
const sourcePath =
|
|
25015
|
-
if (!
|
|
25016
|
-
return (0,
|
|
25173
|
+
const sourcePath = path12.join(codePath, "main.py");
|
|
25174
|
+
if (!fs12.statSync(sourcePath).isFile()) return void 0;
|
|
25175
|
+
return (0, import_node_crypto3.createHash)("sha256").update(fs12.readFileSync(sourcePath)).digest("hex");
|
|
25017
25176
|
} catch {
|
|
25018
25177
|
return void 0;
|
|
25019
25178
|
}
|
|
@@ -25059,7 +25218,7 @@ function resolveBacktestBenchmark(runParams) {
|
|
|
25059
25218
|
var STRATEGY_DOCS_TOOLS = /* @__PURE__ */ new Set(["mcp-create-strategy", "mcp-create-strategy-with-template"]);
|
|
25060
25219
|
function resolveStrategyDocsPath(clientRootDir) {
|
|
25061
25220
|
if (!clientRootDir) return void 0;
|
|
25062
|
-
const docsPath =
|
|
25221
|
+
const docsPath = path12.join(
|
|
25063
25222
|
clientRootDir,
|
|
25064
25223
|
"python",
|
|
25065
25224
|
"Lib",
|
|
@@ -25069,7 +25228,7 @@ function resolveStrategyDocsPath(clientRootDir) {
|
|
|
25069
25228
|
"docs"
|
|
25070
25229
|
);
|
|
25071
25230
|
try {
|
|
25072
|
-
if (!
|
|
25231
|
+
if (!fs12.existsSync(docsPath)) return void 0;
|
|
25073
25232
|
} catch {
|
|
25074
25233
|
return void 0;
|
|
25075
25234
|
}
|
|
@@ -25086,7 +25245,7 @@ function injectDebugRunId(tool, result) {
|
|
|
25086
25245
|
const localPath = typeof parsed.Data.localPath === "string" ? parsed.Data.localPath.trim() : "";
|
|
25087
25246
|
if (!localPath) return result;
|
|
25088
25247
|
const settings = JSON.parse(
|
|
25089
|
-
|
|
25248
|
+
fs12.readFileSync(path12.join(localPath, ".vscode", "tradesetting.json"), "utf8")
|
|
25090
25249
|
);
|
|
25091
25250
|
const debugRunId = isRecord2(settings) && typeof settings.backtest_id === "string" ? settings.backtest_id.trim() : "";
|
|
25092
25251
|
if (!debugRunId) return result;
|
|
@@ -25582,12 +25741,12 @@ function preflightCreatedBacktestSource(toolName, body) {
|
|
|
25582
25741
|
if (toolName !== "mcp-create-and-run-backtest") return null;
|
|
25583
25742
|
const runId = typeof body.runId === "string" ? body.runId.trim() : "";
|
|
25584
25743
|
const codePath = typeof body.codePath === "string" ? body.codePath.trim() : "";
|
|
25585
|
-
if (!codePath || !
|
|
25586
|
-
const sourcePath =
|
|
25587
|
-
if (!
|
|
25744
|
+
if (!codePath || !fs12.existsSync(codePath)) return null;
|
|
25745
|
+
const sourcePath = path12.join(codePath, "main.py");
|
|
25746
|
+
if (!fs12.existsSync(sourcePath)) return null;
|
|
25588
25747
|
let source;
|
|
25589
25748
|
try {
|
|
25590
|
-
source =
|
|
25749
|
+
source = fs12.readFileSync(sourcePath, "utf8");
|
|
25591
25750
|
} catch (error2) {
|
|
25592
25751
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
25593
25752
|
return jsonToolResult(10061, "\u56DE\u6D4B\u4EE3\u7801\u5FEB\u7167\u65E0\u6CD5\u8BFB\u53D6\uFF0C\u672A\u542F\u52A8\u7B56\u7565\u5F15\u64CE\u3002", {
|
|
@@ -25607,7 +25766,7 @@ function preflightCreatedBacktestSource(toolName, body) {
|
|
|
25607
25766
|
codePath,
|
|
25608
25767
|
sourcePath,
|
|
25609
25768
|
sourcePreflight: "blocked",
|
|
25610
|
-
sourceSha256: (0,
|
|
25769
|
+
sourceSha256: (0, import_node_crypto3.createHash)("sha256").update(source).digest("hex"),
|
|
25611
25770
|
violations,
|
|
25612
25771
|
userAction: "\u628A current_data.get(security) \u6539\u4E3A current_data[security]\uFF0C\u5E76\u7528 KeyError \u5904\u7406\u7F3A\u5931\u8BC1\u5238\uFF1B\u7136\u540E\u91CD\u65B0\u521B\u5EFA\u5E76\u8FD0\u884C\u56DE\u6D4B\u3002"
|
|
25613
25772
|
}, true);
|
|
@@ -25827,7 +25986,7 @@ function normalizeDataRoot(raw, clientRootDir) {
|
|
|
25827
25986
|
}
|
|
25828
25987
|
function readJsonFile(filePath) {
|
|
25829
25988
|
try {
|
|
25830
|
-
const parsed = JSON.parse(
|
|
25989
|
+
const parsed = JSON.parse(fs12.readFileSync(filePath, "utf-8"));
|
|
25831
25990
|
return isRecord2(parsed) ? parsed : void 0;
|
|
25832
25991
|
} catch {
|
|
25833
25992
|
return void 0;
|
|
@@ -25841,8 +26000,8 @@ function resolveDataRoots(clientRootDir) {
|
|
|
25841
26000
|
const cached2 = Date.now() - readAt < DATA_ROOTS_TTL_MS ? dataRootsCache.get(clientRootDir) : void 0;
|
|
25842
26001
|
if (cached2) return cached2;
|
|
25843
26002
|
const root = clientRootDir.replace(/[\\/]+$/, "");
|
|
25844
|
-
const dcSdk = readJsonFile(
|
|
25845
|
-
const dcm = readJsonFile(
|
|
26003
|
+
const dcSdk = readJsonFile(path12.join(root, ...DC_SDK_CONFIG_SEGMENTS));
|
|
26004
|
+
const dcm = readJsonFile(path12.join(root, ...DCM_CONFIG_SEGMENTS));
|
|
25846
26005
|
const engineRoot = normalizeDataRoot(isRecord2(dcSdk?.mdf) ? dcSdk.mdf.path : void 0, root);
|
|
25847
26006
|
const downloadRoot = normalizeDataRoot(dcm?.download_home, root);
|
|
25848
26007
|
const resolved = Boolean(engineRoot && downloadRoot);
|
|
@@ -25872,9 +26031,9 @@ function hqSeriesFromResults(resultItems) {
|
|
|
25872
26031
|
function engineHasAnyHqSeries(engineRoot, series) {
|
|
25873
26032
|
if (!engineRoot || series.length === 0) return void 0;
|
|
25874
26033
|
for (const { exchangeId, dataType } of series) {
|
|
25875
|
-
const dir =
|
|
26034
|
+
const dir = path12.join(engineRoot, "hqdata", "his", exchangeId, dataType);
|
|
25876
26035
|
try {
|
|
25877
|
-
if (
|
|
26036
|
+
if (fs12.existsSync(dir) && fs12.readdirSync(dir).length > 0) return true;
|
|
25878
26037
|
} catch {
|
|
25879
26038
|
return void 0;
|
|
25880
26039
|
}
|
|
@@ -26869,8 +27028,7 @@ async function startMcpServer() {
|
|
|
26869
27028
|
isError: true
|
|
26870
27029
|
};
|
|
26871
27030
|
}
|
|
26872
|
-
const
|
|
26873
|
-
const preparedArgs = prepareToolArgs(tool, defaultedToolArgs, backtestRunContexts);
|
|
27031
|
+
const preparedArgs = prepareToolCallArgs(tool, args ?? {}, backtestRunContexts);
|
|
26874
27032
|
if ("content" in preparedArgs) return preparedArgs;
|
|
26875
27033
|
const toolArgs = preparedArgs;
|
|
26876
27034
|
if (tool.localHandler === "currentUser") {
|
|
@@ -27444,13 +27602,13 @@ function syncCredentialsFromEnvAtStartup() {
|
|
|
27444
27602
|
function signalCliKeepaliveReady() {
|
|
27445
27603
|
const raw = process.env.ZLT_MCP_KEEPALIVE_READY_FILE?.trim();
|
|
27446
27604
|
if (process.env.ZLT_MCP_CLI !== "1" || !raw) return;
|
|
27447
|
-
const readyFile =
|
|
27448
|
-
if (
|
|
27605
|
+
const readyFile = path14.resolve(raw);
|
|
27606
|
+
if (path14.dirname(readyFile) !== path14.resolve(os5.tmpdir()) || !path14.basename(readyFile).startsWith("zlt-mcp-keepalive-")) {
|
|
27449
27607
|
return;
|
|
27450
27608
|
}
|
|
27451
27609
|
try {
|
|
27452
|
-
const fd =
|
|
27453
|
-
|
|
27610
|
+
const fd = fs13.openSync(readyFile, "wx", 384);
|
|
27611
|
+
fs13.closeSync(fd);
|
|
27454
27612
|
} catch (error2) {
|
|
27455
27613
|
if (error2.code !== "EEXIST") {
|
|
27456
27614
|
process.stderr.write(`[zlt-mcp-cli] keepalive readiness signal failed: ${error2 instanceof Error ? error2.message : String(error2)}
|
|
@@ -27547,54 +27705,98 @@ if (process.argv.length <= 2) {
|
|
|
27547
27705
|
startMcpServer();
|
|
27548
27706
|
} else {
|
|
27549
27707
|
const program2 = new Command();
|
|
27550
|
-
program2.name(CLI_NAME).description("MCP proxy for ZLTHost IPC service").version(resolveCliVersion());
|
|
27708
|
+
program2.name(CLI_NAME).description("MCP proxy for ZLTHost IPC service").version(resolveCliVersion()).addHelpText("after", "\nDiscovery: list for names; list --tool <name> --json for one complete input schema.\nUse call --help for input, output and diagnostic handling.");
|
|
27551
27709
|
program2.command("__keepalive <kind> <id> [codePath]", { hidden: true }).action(async (kind, id, codePath) => {
|
|
27552
27710
|
if (kind !== "backtest") throw new Error(`Unsupported keepalive kind: ${kind}`);
|
|
27553
27711
|
await keepMcpBacktestAlive(id, codePath);
|
|
27554
27712
|
});
|
|
27555
|
-
program2.command("call <tool>").description("Call any MCP tool through the bundled MCP server").option("--args-json <json>", "JSON object containing tool arguments").option("--args-file <path>", "Read the JSON argument object from a file").option("--output-json <path>", "Save the complete result to a new JSON file and print a compact receipt").option("--timeout-ms <ms>", "MCP request inactivity timeout in milliseconds").option("--max-total-timeout-ms <ms>", "Optional hard upper bound for the request").option("--no-progress", "Suppress progress diagnostics on stderr").
|
|
27713
|
+
program2.command("call <tool>").description("Call any MCP tool through the bundled MCP server").option("--args-json <json>", "JSON object containing tool arguments").option("--args-file <path>", "Read the JSON argument object from a file").option("--output-json <path>", "Save the complete result to a new JSON file and print a compact receipt").option("--timeout-ms <ms>", "MCP request inactivity timeout in milliseconds").option("--max-total-timeout-ms <ms>", "Optional hard upper bound for the request").option("--no-progress", "Suppress progress diagnostics on stderr").addHelpText("after", `
|
|
27714
|
+
Input: omitted arguments mean {}; use --args-json for small objects and --args-file
|
|
27715
|
+
for nested configuration or shell-sensitive text. Follow the selected tool schema
|
|
27716
|
+
from list --tool <name> --json. Windows paths must be native paths (C:/...), not /c/....
|
|
27717
|
+
Output: by default stdout contains the complete MCP JSON envelope plus cliProvenance.
|
|
27718
|
+
JSON business responses are inside content[].text (or structuredContent when present).
|
|
27719
|
+
Use --output-json for large results or downstream evidence: it saves the complete
|
|
27720
|
+
envelope and prints only a compact receipt. The parent directory must exist and the
|
|
27721
|
+
file must be new. A receipt is not the full business response.
|
|
27722
|
+
Diagnostics: preserve stderr separately and check this process's exit code before
|
|
27723
|
+
parsing output. Do not discard stderr, merge it into JSON, or pipe calls through
|
|
27724
|
+
head/tail/parsers that can hide the CLI exit code. --no-progress only disables progress.
|
|
27725
|
+
If saving fails after execution, the complete response is on stdout; preserve it
|
|
27726
|
+
and inspect the returned state before retrying any operation that may have run.
|
|
27727
|
+
Thrown call failures emit Error: followed by JSON on stderr with stage, message,
|
|
27728
|
+
toolExecution and retry. not_started means the CLI did not call the tool; correct
|
|
27729
|
+
the input/path before retrying. unknown means execution may have occurred (including
|
|
27730
|
+
transport or keepalive failure); inspect state first. response_received means a
|
|
27731
|
+
response was received, not that the business succeeded; inspect that result first.
|
|
27732
|
+
Credentials belong in the configured local credential store, never in arguments.
|
|
27733
|
+
`).action(async (tool, options) => {
|
|
27556
27734
|
let outputFd;
|
|
27735
|
+
let stage = "arguments";
|
|
27736
|
+
let toolExecution = "not_started";
|
|
27557
27737
|
try {
|
|
27558
27738
|
const args = parseMcpArgs(options.argsJson, options.argsFile);
|
|
27559
27739
|
const timeoutMs = parseTimeoutOption(options.timeoutMs, "--timeout-ms");
|
|
27560
27740
|
const maxTotalTimeoutMs = parseTimeoutOption(options.maxTotalTimeoutMs, "--max-total-timeout-ms");
|
|
27561
|
-
const resultFile = options.outputJson === void 0 ? void 0 :
|
|
27562
|
-
|
|
27741
|
+
const resultFile = options.outputJson === void 0 ? void 0 : path15.resolve(options.outputJson);
|
|
27742
|
+
stage = "output_prepare";
|
|
27743
|
+
if (resultFile !== void 0) outputFd = fs14.openSync(resultFile, "wx");
|
|
27744
|
+
stage = "tool_call";
|
|
27745
|
+
toolExecution = "unknown";
|
|
27563
27746
|
const result = await callMcpTool(tool, args, {
|
|
27564
27747
|
timeoutMs,
|
|
27565
27748
|
maxTotalTimeoutMs,
|
|
27566
27749
|
showProgress: options.progress !== false
|
|
27567
27750
|
});
|
|
27751
|
+
toolExecution = "response_received";
|
|
27752
|
+
stage = "output_serialize";
|
|
27568
27753
|
const complete = withCliProvenance(result);
|
|
27569
27754
|
const serialized = JSON.stringify(complete) + "\n";
|
|
27570
27755
|
if (outputFd !== void 0 && resultFile !== void 0) {
|
|
27756
|
+
stage = "output_write";
|
|
27571
27757
|
try {
|
|
27572
|
-
|
|
27573
|
-
|
|
27758
|
+
fs14.writeFileSync(outputFd, serialized, "utf-8");
|
|
27759
|
+
fs14.closeSync(outputFd);
|
|
27574
27760
|
outputFd = void 0;
|
|
27575
27761
|
} catch (error2) {
|
|
27576
27762
|
process.stdout.write(serialized);
|
|
27577
27763
|
throw new Error(`Tool returned a result, but saving ${resultFile} failed; complete result is on stdout. Do not repeat the tool automatically. ${String(error2)}`);
|
|
27578
27764
|
}
|
|
27765
|
+
stage = "output_emit";
|
|
27579
27766
|
const receipt = compactCliReceipt(tool, complete, resultFile);
|
|
27580
27767
|
process.stdout.write(JSON.stringify(receipt) + "\n");
|
|
27581
27768
|
if (!receipt.ok) process.exitCode = 1;
|
|
27582
27769
|
} else {
|
|
27770
|
+
stage = "output_emit";
|
|
27583
27771
|
process.stdout.write(serialized);
|
|
27584
27772
|
}
|
|
27585
27773
|
if (result.isError === true) process.exitCode = 1;
|
|
27586
27774
|
} catch (error2) {
|
|
27587
27775
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
27588
|
-
|
|
27776
|
+
const code = error2?.code;
|
|
27777
|
+
const retry = toolExecution === "not_started" ? "fix_input_then_retry" : toolExecution === "response_received" ? "inspect_result_before_retry" : "inspect_state_before_retry";
|
|
27778
|
+
process.stderr.write(`Error: ${JSON.stringify({
|
|
27779
|
+
tool,
|
|
27780
|
+
stage,
|
|
27781
|
+
toolExecution,
|
|
27782
|
+
retry,
|
|
27783
|
+
...typeof code === "string" ? { code } : {},
|
|
27784
|
+
message
|
|
27785
|
+
})}
|
|
27589
27786
|
`);
|
|
27590
27787
|
process.exitCode = 1;
|
|
27591
27788
|
} finally {
|
|
27592
|
-
if (outputFd !== void 0)
|
|
27789
|
+
if (outputFd !== void 0) fs14.closeSync(outputFd);
|
|
27593
27790
|
}
|
|
27594
27791
|
});
|
|
27595
|
-
program2.command("list").description("List MCP tools exposed by the bundled server").option("--json", "Emit the complete tools/list response as JSON").action(async (options) => {
|
|
27792
|
+
program2.command("list").description("List MCP tools exposed by the bundled server").option("--json", "Emit the complete tools/list response as JSON").option("--tool <name>", "Select one exact tool name; combine with --json for its complete schema").addHelpText("after", "\nReuse discovery within a task. Query one schema with list --tool <name> --json.\nUnknown names fail with exit code 1. Preserve stderr separately from JSON stdout.").action(async (options) => {
|
|
27596
27793
|
try {
|
|
27597
|
-
|
|
27794
|
+
let result = await listMcpTools();
|
|
27795
|
+
if (options.tool !== void 0) {
|
|
27796
|
+
const tools2 = Array.isArray(result.tools) ? result.tools.filter((tool) => tool.name === options.tool) : [];
|
|
27797
|
+
if (tools2.length === 0) throw new Error(`Unknown tool: ${options.tool}. Use list to discover available names.`);
|
|
27798
|
+
result = { ...result, tools: tools2 };
|
|
27799
|
+
}
|
|
27598
27800
|
if (options.json) {
|
|
27599
27801
|
process.stdout.write(JSON.stringify(withCliProvenance(result)) + "\n");
|
|
27600
27802
|
return;
|
|
@@ -27664,17 +27866,17 @@ function resolveCliVersion() {
|
|
|
27664
27866
|
return resolveCliPackageProvenance().packageVersion;
|
|
27665
27867
|
}
|
|
27666
27868
|
function resolveCliPackageProvenance() {
|
|
27667
|
-
let current =
|
|
27869
|
+
let current = path15.dirname(path15.resolve(process.argv[1] || process.cwd()));
|
|
27668
27870
|
for (let depth = 0; depth < 6; depth += 1) {
|
|
27669
|
-
const manifestPath =
|
|
27871
|
+
const manifestPath = path15.join(current, "package.json");
|
|
27670
27872
|
try {
|
|
27671
|
-
const manifest = JSON.parse(
|
|
27873
|
+
const manifest = JSON.parse(fs14.readFileSync(manifestPath, "utf-8"));
|
|
27672
27874
|
if ((manifest.name === "@zltquant/zlt-mcp" || manifest.name === "zlt-mcp-proxy") && typeof manifest.version === "string") {
|
|
27673
27875
|
return { packageName: manifest.name, packageVersion: manifest.version };
|
|
27674
27876
|
}
|
|
27675
27877
|
} catch {
|
|
27676
27878
|
}
|
|
27677
|
-
const parent =
|
|
27879
|
+
const parent = path15.dirname(current);
|
|
27678
27880
|
if (parent === current) break;
|
|
27679
27881
|
current = parent;
|
|
27680
27882
|
}
|