@tradejs/cli 3.1.29-beta.277 → 3.1.29-beta.278
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/dist/cli.js +288 -316
- package/dist/lib/mcpReplayProcess.js +44 -73
- package/dist/scripts/mcpWorker.js +66 -97
- package/package.json +7 -7
|
@@ -35,16 +35,32 @@ __export(mcpReplayProcess_exports, {
|
|
|
35
35
|
});
|
|
36
36
|
module.exports = __toCommonJS(mcpReplayProcess_exports);
|
|
37
37
|
var import_node_path = __toESM(require("path"));
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
var runtimeEvidenceProducer_exports = {};
|
|
41
|
-
__reExport(runtimeEvidenceProducer_exports, require("@tradejs/node/diagnostics"));
|
|
38
|
+
var import_node_crypto = require("crypto");
|
|
39
|
+
var import_promises = __toESM(require("fs/promises"));
|
|
42
40
|
|
|
43
41
|
// src/lib/runtimeEvidenceArtifacts.ts
|
|
44
42
|
var runtimeEvidenceArtifacts_exports = {};
|
|
45
43
|
__reExport(runtimeEvidenceArtifacts_exports, require("@tradejs/node/diagnostics"));
|
|
46
44
|
|
|
47
45
|
// src/lib/mcpReplayProcess.ts
|
|
46
|
+
var client = `
|
|
47
|
+
const fs = require('node:fs');
|
|
48
|
+
const path = require('node:path');
|
|
49
|
+
const [root, id, request] = process.argv.slice(1);
|
|
50
|
+
const file = path.join(root, id);
|
|
51
|
+
fs.mkdirSync(root, {recursive:true});
|
|
52
|
+
try { fs.writeFileSync(file + '.request', request, {flag:'wx'}); }
|
|
53
|
+
catch (error) { if (error.code !== 'EEXIST') throw error; if (fs.readFileSync(file + '.request', 'utf8') !== request) throw new Error('Replay request identity conflict'); }
|
|
54
|
+
process.on('SIGTERM', () => { fs.writeFileSync(file + '.cancel', 'cancel'); process.exit(143); });
|
|
55
|
+
const timer = setInterval(() => {
|
|
56
|
+
try {
|
|
57
|
+
const result = JSON.parse(fs.readFileSync(file + '.result', 'utf8'));
|
|
58
|
+
console.log(result.message);
|
|
59
|
+
clearInterval(timer);
|
|
60
|
+
process.exit(result.exitCode === 0 ? 0 : 1);
|
|
61
|
+
} catch (error) { if (error.code !== 'ENOENT') throw error; }
|
|
62
|
+
}, 1000);
|
|
63
|
+
`;
|
|
48
64
|
var buildMcpReplayProcess = async ({
|
|
49
65
|
evidencePath,
|
|
50
66
|
outDir,
|
|
@@ -52,79 +68,34 @@ var buildMcpReplayProcess = async ({
|
|
|
52
68
|
projectRoot,
|
|
53
69
|
env
|
|
54
70
|
}) => {
|
|
55
|
-
if (!/^[a-
|
|
56
|
-
throw new Error("Invalid replay
|
|
71
|
+
if (!/^[a-f0-9]{64}$/.test(runId))
|
|
72
|
+
throw new Error("Invalid replay request id");
|
|
57
73
|
const bundle = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(import_node_path.default.dirname(evidencePath));
|
|
58
74
|
if (import_node_path.default.resolve(evidencePath) !== import_node_path.default.resolve(bundle.payloadPath))
|
|
59
75
|
throw new Error("Replay requires the verified bundle payload");
|
|
60
|
-
const
|
|
61
|
-
if (
|
|
62
|
-
throw new Error(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const relative = import_node_path.default.relative(projectRoot, file);
|
|
67
|
-
if (relative.startsWith("..") || import_node_path.default.isAbsolute(relative))
|
|
68
|
-
throw new Error("Replay mounts must be inside the Project");
|
|
69
|
-
return import_node_path.default.join(env.MCP_REPLAY_HOST_PROJECT_ROOT, relative);
|
|
70
|
-
};
|
|
71
|
-
const args = [
|
|
72
|
-
"run",
|
|
73
|
-
"--rm",
|
|
74
|
-
"--name",
|
|
75
|
-
`tradejs-replay-${runId}`,
|
|
76
|
-
"--memory=1536m",
|
|
77
|
-
"--cpus=1",
|
|
78
|
-
"--pids-limit=512",
|
|
79
|
-
"--read-only",
|
|
80
|
-
"--cap-drop=ALL",
|
|
81
|
-
"--security-opt=no-new-privileges",
|
|
82
|
-
"--network",
|
|
83
|
-
env.MCP_REPLAY_NETWORK,
|
|
84
|
-
"--tmpfs",
|
|
85
|
-
"/tmp",
|
|
86
|
-
"--tmpfs",
|
|
87
|
-
"/app/data",
|
|
88
|
-
"--entrypoint",
|
|
89
|
-
"/app/node_modules/.bin/tradejs",
|
|
90
|
-
"--mount",
|
|
91
|
-
`type=bind,src=${hostPath(import_node_path.default.dirname(evidencePath))},dst=/evidence,readonly`,
|
|
92
|
-
"--mount",
|
|
93
|
-
`type=bind,src=${hostPath(outDir)},dst=/replay-output`
|
|
94
|
-
];
|
|
95
|
-
const safeEnv = {
|
|
96
|
-
PROJECT_CWD: "/app",
|
|
97
|
-
DOTENV_CONFIG_PATH: "/dev/null",
|
|
98
|
-
TRADEJS_PROJECT_SHA: producer.projectSha,
|
|
99
|
-
TRADEJS_PROJECT_IMAGE_DIGEST: producer.imageDigest,
|
|
100
|
-
NODE_OPTIONS: "--max-old-space-size=1024",
|
|
101
|
-
MAKE_ORDERS: "false",
|
|
102
|
-
TRADEJS_EXTERNAL_ORDER_PLACEMENT: "false",
|
|
103
|
-
AI_ENABLED: "false",
|
|
104
|
-
ML_ENABLED: "false",
|
|
105
|
-
RUNTIME_FEEDBACK_ISOLATED_REDIS: "true",
|
|
106
|
-
REDIS_HOST: env.MCP_REPLAY_REDIS_HOST,
|
|
107
|
-
REDIS_PORT: "6379",
|
|
108
|
-
REDIS_DB: "0",
|
|
109
|
-
PGOPTIONS: "-c default_transaction_read_only=on",
|
|
110
|
-
TRADEJS_TIMESCALE_READ_ONLY: "true"
|
|
111
|
-
};
|
|
112
|
-
for (const name of ["PG_HOST", "PG_PORT", "PG_USER", "PG_DATABASE", "PG_DB"])
|
|
113
|
-
if (env[name]) safeEnv[name] = env[name];
|
|
114
|
-
for (const [name, value] of Object.entries(safeEnv))
|
|
115
|
-
if (value !== void 0) args.push("--env", `${name}=${value}`);
|
|
116
|
-
if (env.PG_PASSWORD) args.push("--env", "PG_PASSWORD");
|
|
117
|
-
args.push(
|
|
118
|
-
`${env.MCP_REPLAY_IMAGE_REPOSITORY}@${producer.imageDigest}`,
|
|
119
|
-
"runtime-feedback-replay",
|
|
120
|
-
"--runtimeEvidence",
|
|
121
|
-
`/evidence/${import_node_path.default.basename(evidencePath)}`,
|
|
122
|
-
"--outDir",
|
|
123
|
-
"/replay-output",
|
|
124
|
-
"--runId",
|
|
125
|
-
runId
|
|
76
|
+
const relative = import_node_path.default.relative(import_node_path.default.join(projectRoot, "data"), evidencePath);
|
|
77
|
+
if (relative.startsWith("..") || import_node_path.default.isAbsolute(relative))
|
|
78
|
+
throw new Error("Evidence must be inside Project data");
|
|
79
|
+
const root = env.MCP_REPLAY_REQUEST_ROOT || import_node_path.default.join(projectRoot, "data/mcp-replay-requests");
|
|
80
|
+
const heartbeat = JSON.parse(
|
|
81
|
+
await import_promises.default.readFile(import_node_path.default.join(root, "heartbeat.json"), "utf8")
|
|
126
82
|
);
|
|
127
|
-
|
|
83
|
+
if (!Number.isFinite(heartbeat.observedAt) || Date.now() - heartbeat.observedAt < 0 || Date.now() - heartbeat.observedAt > 12e4)
|
|
84
|
+
throw new Error("Host replay runner heartbeat is stale");
|
|
85
|
+
const bytes = await import_promises.default.readFile(evidencePath);
|
|
86
|
+
const request = JSON.stringify({
|
|
87
|
+
schemaVersion: 1,
|
|
88
|
+
id: runId,
|
|
89
|
+
evidence: relative,
|
|
90
|
+
artifactId: bundle.manifest.artifactId,
|
|
91
|
+
deploymentId: bundle.manifest.deploymentId,
|
|
92
|
+
payloadSha256: (0, import_node_crypto.createHash)("sha256").update(bytes).digest("hex")
|
|
93
|
+
});
|
|
94
|
+
void outDir;
|
|
95
|
+
return {
|
|
96
|
+
executable: process.execPath,
|
|
97
|
+
args: ["-e", client, root, runId, request]
|
|
98
|
+
};
|
|
128
99
|
};
|
|
129
100
|
// Annotate the CommonJS export names for ESM import in node:
|
|
130
101
|
0 && (module.exports = {
|
|
@@ -35,23 +35,39 @@ __export(mcpWorker_exports, {
|
|
|
35
35
|
});
|
|
36
36
|
module.exports = __toCommonJS(mcpWorker_exports);
|
|
37
37
|
var import_node_child_process = require("child_process");
|
|
38
|
-
var
|
|
39
|
-
var
|
|
38
|
+
var import_node_crypto2 = require("crypto");
|
|
39
|
+
var import_promises2 = require("fs/promises");
|
|
40
40
|
var import_redis = require("@tradejs/infra/redis");
|
|
41
41
|
var import_mcp = require("@tradejs/node/mcp");
|
|
42
42
|
|
|
43
43
|
// src/lib/mcpReplayProcess.ts
|
|
44
44
|
var import_node_path = __toESM(require("path"));
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
var runtimeEvidenceProducer_exports = {};
|
|
48
|
-
__reExport(runtimeEvidenceProducer_exports, require("@tradejs/node/diagnostics"));
|
|
45
|
+
var import_node_crypto = require("crypto");
|
|
46
|
+
var import_promises = __toESM(require("fs/promises"));
|
|
49
47
|
|
|
50
48
|
// src/lib/runtimeEvidenceArtifacts.ts
|
|
51
49
|
var runtimeEvidenceArtifacts_exports = {};
|
|
52
50
|
__reExport(runtimeEvidenceArtifacts_exports, require("@tradejs/node/diagnostics"));
|
|
53
51
|
|
|
54
52
|
// src/lib/mcpReplayProcess.ts
|
|
53
|
+
var client = `
|
|
54
|
+
const fs = require('node:fs');
|
|
55
|
+
const path = require('node:path');
|
|
56
|
+
const [root, id, request] = process.argv.slice(1);
|
|
57
|
+
const file = path.join(root, id);
|
|
58
|
+
fs.mkdirSync(root, {recursive:true});
|
|
59
|
+
try { fs.writeFileSync(file + '.request', request, {flag:'wx'}); }
|
|
60
|
+
catch (error) { if (error.code !== 'EEXIST') throw error; if (fs.readFileSync(file + '.request', 'utf8') !== request) throw new Error('Replay request identity conflict'); }
|
|
61
|
+
process.on('SIGTERM', () => { fs.writeFileSync(file + '.cancel', 'cancel'); process.exit(143); });
|
|
62
|
+
const timer = setInterval(() => {
|
|
63
|
+
try {
|
|
64
|
+
const result = JSON.parse(fs.readFileSync(file + '.result', 'utf8'));
|
|
65
|
+
console.log(result.message);
|
|
66
|
+
clearInterval(timer);
|
|
67
|
+
process.exit(result.exitCode === 0 ? 0 : 1);
|
|
68
|
+
} catch (error) { if (error.code !== 'ENOENT') throw error; }
|
|
69
|
+
}, 1000);
|
|
70
|
+
`;
|
|
55
71
|
var buildMcpReplayProcess = async ({
|
|
56
72
|
evidencePath,
|
|
57
73
|
outDir,
|
|
@@ -59,79 +75,34 @@ var buildMcpReplayProcess = async ({
|
|
|
59
75
|
projectRoot,
|
|
60
76
|
env
|
|
61
77
|
}) => {
|
|
62
|
-
if (!/^[a-
|
|
63
|
-
throw new Error("Invalid replay
|
|
78
|
+
if (!/^[a-f0-9]{64}$/.test(runId))
|
|
79
|
+
throw new Error("Invalid replay request id");
|
|
64
80
|
const bundle = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(import_node_path.default.dirname(evidencePath));
|
|
65
81
|
if (import_node_path.default.resolve(evidencePath) !== import_node_path.default.resolve(bundle.payloadPath))
|
|
66
82
|
throw new Error("Replay requires the verified bundle payload");
|
|
67
|
-
const
|
|
68
|
-
if (
|
|
69
|
-
throw new Error(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const relative = import_node_path.default.relative(projectRoot, file);
|
|
74
|
-
if (relative.startsWith("..") || import_node_path.default.isAbsolute(relative))
|
|
75
|
-
throw new Error("Replay mounts must be inside the Project");
|
|
76
|
-
return import_node_path.default.join(env.MCP_REPLAY_HOST_PROJECT_ROOT, relative);
|
|
77
|
-
};
|
|
78
|
-
const args = [
|
|
79
|
-
"run",
|
|
80
|
-
"--rm",
|
|
81
|
-
"--name",
|
|
82
|
-
`tradejs-replay-${runId}`,
|
|
83
|
-
"--memory=1536m",
|
|
84
|
-
"--cpus=1",
|
|
85
|
-
"--pids-limit=512",
|
|
86
|
-
"--read-only",
|
|
87
|
-
"--cap-drop=ALL",
|
|
88
|
-
"--security-opt=no-new-privileges",
|
|
89
|
-
"--network",
|
|
90
|
-
env.MCP_REPLAY_NETWORK,
|
|
91
|
-
"--tmpfs",
|
|
92
|
-
"/tmp",
|
|
93
|
-
"--tmpfs",
|
|
94
|
-
"/app/data",
|
|
95
|
-
"--entrypoint",
|
|
96
|
-
"/app/node_modules/.bin/tradejs",
|
|
97
|
-
"--mount",
|
|
98
|
-
`type=bind,src=${hostPath(import_node_path.default.dirname(evidencePath))},dst=/evidence,readonly`,
|
|
99
|
-
"--mount",
|
|
100
|
-
`type=bind,src=${hostPath(outDir)},dst=/replay-output`
|
|
101
|
-
];
|
|
102
|
-
const safeEnv = {
|
|
103
|
-
PROJECT_CWD: "/app",
|
|
104
|
-
DOTENV_CONFIG_PATH: "/dev/null",
|
|
105
|
-
TRADEJS_PROJECT_SHA: producer.projectSha,
|
|
106
|
-
TRADEJS_PROJECT_IMAGE_DIGEST: producer.imageDigest,
|
|
107
|
-
NODE_OPTIONS: "--max-old-space-size=1024",
|
|
108
|
-
MAKE_ORDERS: "false",
|
|
109
|
-
TRADEJS_EXTERNAL_ORDER_PLACEMENT: "false",
|
|
110
|
-
AI_ENABLED: "false",
|
|
111
|
-
ML_ENABLED: "false",
|
|
112
|
-
RUNTIME_FEEDBACK_ISOLATED_REDIS: "true",
|
|
113
|
-
REDIS_HOST: env.MCP_REPLAY_REDIS_HOST,
|
|
114
|
-
REDIS_PORT: "6379",
|
|
115
|
-
REDIS_DB: "0",
|
|
116
|
-
PGOPTIONS: "-c default_transaction_read_only=on",
|
|
117
|
-
TRADEJS_TIMESCALE_READ_ONLY: "true"
|
|
118
|
-
};
|
|
119
|
-
for (const name of ["PG_HOST", "PG_PORT", "PG_USER", "PG_DATABASE", "PG_DB"])
|
|
120
|
-
if (env[name]) safeEnv[name] = env[name];
|
|
121
|
-
for (const [name, value] of Object.entries(safeEnv))
|
|
122
|
-
if (value !== void 0) args.push("--env", `${name}=${value}`);
|
|
123
|
-
if (env.PG_PASSWORD) args.push("--env", "PG_PASSWORD");
|
|
124
|
-
args.push(
|
|
125
|
-
`${env.MCP_REPLAY_IMAGE_REPOSITORY}@${producer.imageDigest}`,
|
|
126
|
-
"runtime-feedback-replay",
|
|
127
|
-
"--runtimeEvidence",
|
|
128
|
-
`/evidence/${import_node_path.default.basename(evidencePath)}`,
|
|
129
|
-
"--outDir",
|
|
130
|
-
"/replay-output",
|
|
131
|
-
"--runId",
|
|
132
|
-
runId
|
|
83
|
+
const relative = import_node_path.default.relative(import_node_path.default.join(projectRoot, "data"), evidencePath);
|
|
84
|
+
if (relative.startsWith("..") || import_node_path.default.isAbsolute(relative))
|
|
85
|
+
throw new Error("Evidence must be inside Project data");
|
|
86
|
+
const root = env.MCP_REPLAY_REQUEST_ROOT || import_node_path.default.join(projectRoot, "data/mcp-replay-requests");
|
|
87
|
+
const heartbeat = JSON.parse(
|
|
88
|
+
await import_promises.default.readFile(import_node_path.default.join(root, "heartbeat.json"), "utf8")
|
|
133
89
|
);
|
|
134
|
-
|
|
90
|
+
if (!Number.isFinite(heartbeat.observedAt) || Date.now() - heartbeat.observedAt < 0 || Date.now() - heartbeat.observedAt > 12e4)
|
|
91
|
+
throw new Error("Host replay runner heartbeat is stale");
|
|
92
|
+
const bytes = await import_promises.default.readFile(evidencePath);
|
|
93
|
+
const request = JSON.stringify({
|
|
94
|
+
schemaVersion: 1,
|
|
95
|
+
id: runId,
|
|
96
|
+
evidence: relative,
|
|
97
|
+
artifactId: bundle.manifest.artifactId,
|
|
98
|
+
deploymentId: bundle.manifest.deploymentId,
|
|
99
|
+
payloadSha256: (0, import_node_crypto.createHash)("sha256").update(bytes).digest("hex")
|
|
100
|
+
});
|
|
101
|
+
void outDir;
|
|
102
|
+
return {
|
|
103
|
+
executable: process.execPath,
|
|
104
|
+
args: ["-e", client, root, runId, request]
|
|
105
|
+
};
|
|
135
106
|
};
|
|
136
107
|
|
|
137
108
|
// src/scripts/mcpWorker.ts
|
|
@@ -140,7 +111,7 @@ var leaseKey = "worker:lease";
|
|
|
140
111
|
var LEASE_SECONDS = 15;
|
|
141
112
|
var JOB_TIMEOUT_MS = 60 * 60 * 1e3;
|
|
142
113
|
var main = async (options = {}) => {
|
|
143
|
-
const owner = (0,
|
|
114
|
+
const owner = (0, import_node_crypto2.randomUUID)();
|
|
144
115
|
if (!await import_redis.mcpStorage.put(leaseKey, owner, LEASE_SECONDS, true))
|
|
145
116
|
throw new Error("Another MCP worker owns this storage");
|
|
146
117
|
let stopping = false;
|
|
@@ -148,6 +119,18 @@ var main = async (options = {}) => {
|
|
|
148
119
|
let renewing = false;
|
|
149
120
|
let leaseLost = false;
|
|
150
121
|
let manifestHash = "";
|
|
122
|
+
let replayReady = false;
|
|
123
|
+
const updateReplayReady = async () => {
|
|
124
|
+
try {
|
|
125
|
+
const root = process.env.MCP_REPLAY_REQUEST_ROOT || `${process.env.PROJECT_CWD || process.cwd()}/data/mcp-replay-requests`;
|
|
126
|
+
const heartbeat2 = JSON.parse(
|
|
127
|
+
await (0, import_promises2.readFile)(`${root}/heartbeat.json`, "utf8")
|
|
128
|
+
);
|
|
129
|
+
replayReady = Number.isFinite(heartbeat2.observedAt) && Date.now() - heartbeat2.observedAt >= 0 && Date.now() - heartbeat2.observedAt < 12e4;
|
|
130
|
+
} catch {
|
|
131
|
+
replayReady = false;
|
|
132
|
+
}
|
|
133
|
+
};
|
|
151
134
|
const signalChild = (signal) => {
|
|
152
135
|
if (!child?.pid) return;
|
|
153
136
|
try {
|
|
@@ -161,9 +144,7 @@ var main = async (options = {}) => {
|
|
|
161
144
|
const heartbeatValue = () => ({
|
|
162
145
|
observedAt: Date.now(),
|
|
163
146
|
packageManifestSha256: manifestHash,
|
|
164
|
-
replayAvailable:
|
|
165
|
-
process.env.MCP_REPLAY_REDIS_HOST && process.env.MCP_REPLAY_HOST_PROJECT_ROOT && process.env.MCP_REPLAY_NETWORK && process.env.MCP_REPLAY_IMAGE_REPOSITORY
|
|
166
|
-
)
|
|
147
|
+
replayAvailable: replayReady
|
|
167
148
|
});
|
|
168
149
|
const stop = () => {
|
|
169
150
|
stopping = true;
|
|
@@ -179,6 +160,7 @@ var main = async (options = {}) => {
|
|
|
179
160
|
try {
|
|
180
161
|
if (!await import_redis.mcpStorage.compare(leaseKey, owner, owner, LEASE_SECONDS))
|
|
181
162
|
throw new Error("Worker lease lost");
|
|
163
|
+
await updateReplayReady();
|
|
182
164
|
await import_redis.mcpStorage.put("worker:heartbeat", heartbeatValue(), LEASE_SECONDS);
|
|
183
165
|
} catch {
|
|
184
166
|
leaseLost = true;
|
|
@@ -189,6 +171,7 @@ var main = async (options = {}) => {
|
|
|
189
171
|
}, 2e3);
|
|
190
172
|
try {
|
|
191
173
|
manifestHash = await (0, import_mcp.mcpPackageManifestHash)();
|
|
174
|
+
await updateReplayReady();
|
|
192
175
|
await import_redis.mcpStorage.put("worker:heartbeat", heartbeatValue(), LEASE_SECONDS);
|
|
193
176
|
let cursor = "0";
|
|
194
177
|
do {
|
|
@@ -253,7 +236,7 @@ var main = async (options = {}) => {
|
|
|
253
236
|
);
|
|
254
237
|
continue;
|
|
255
238
|
}
|
|
256
|
-
await (0,
|
|
239
|
+
await (0, import_promises2.mkdir)((0, import_mcp.mcpJobDirectory)(started), { recursive: true });
|
|
257
240
|
if (started.kind === "backtest")
|
|
258
241
|
await (0, import_redis.setDataStrict)(
|
|
259
242
|
import_redis.redisKeys.backtestConfig(
|
|
@@ -276,7 +259,9 @@ var main = async (options = {}) => {
|
|
|
276
259
|
};
|
|
277
260
|
if (started.kind === "runtime-feedback-replay") {
|
|
278
261
|
for (const name of Object.keys(jobEnv)) {
|
|
279
|
-
if (/secret|token|api.?key|private.?key|cookie|credential/i.test(
|
|
262
|
+
if (/secret|password|token|api.?key|private.?key|cookie|credential/i.test(
|
|
263
|
+
name
|
|
264
|
+
))
|
|
280
265
|
delete jobEnv[name];
|
|
281
266
|
}
|
|
282
267
|
Object.assign(jobEnv, {
|
|
@@ -317,8 +302,6 @@ var main = async (options = {}) => {
|
|
|
317
302
|
);
|
|
318
303
|
continue;
|
|
319
304
|
}
|
|
320
|
-
if (started.kind === "runtime-feedback-replay" && process.env.PG_PASSWORD)
|
|
321
|
-
jobEnv.PG_PASSWORD = process.env.PG_PASSWORD;
|
|
322
305
|
child = (0, import_node_child_process.spawn)(command.executable, command.args, {
|
|
323
306
|
cwd: process.env.PROJECT_CWD || process.cwd(),
|
|
324
307
|
env: jobEnv,
|
|
@@ -373,20 +356,6 @@ var main = async (options = {}) => {
|
|
|
373
356
|
);
|
|
374
357
|
currentChild.once("exit", (code) => resolve({ code }));
|
|
375
358
|
});
|
|
376
|
-
if (started.kind === "runtime-feedback-replay") {
|
|
377
|
-
await new Promise((resolve) => {
|
|
378
|
-
const cleanup = (0, import_node_child_process.spawn)(
|
|
379
|
-
"docker",
|
|
380
|
-
["rm", "--force", `tradejs-replay-${started.id}`],
|
|
381
|
-
{
|
|
382
|
-
stdio: "ignore",
|
|
383
|
-
timeout: 1e4
|
|
384
|
-
}
|
|
385
|
-
);
|
|
386
|
-
cleanup.once("error", () => resolve());
|
|
387
|
-
cleanup.once("close", () => resolve());
|
|
388
|
-
});
|
|
389
|
-
}
|
|
390
359
|
clearTimeout(timeout);
|
|
391
360
|
clearInterval(monitor);
|
|
392
361
|
child = void 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tradejs/cli",
|
|
3
|
-
"version": "3.1.29-beta.
|
|
3
|
+
"version": "3.1.29-beta.278",
|
|
4
4
|
"description": "Official CLI for the TradeJS TypeScript framework: infra setup, backtests, signals, bots, and ML workflows.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tradejs",
|
|
@@ -37,13 +37,13 @@
|
|
|
37
37
|
"tradejs": "dist/cli.js"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@tradejs/connectors": "^3.1.29-beta.
|
|
41
|
-
"@tradejs/core": "^3.1.29-beta.
|
|
42
|
-
"@tradejs/indicators": "^3.1.29-beta.
|
|
43
|
-
"@tradejs/infra": "^3.1.29-beta.
|
|
44
|
-
"@tradejs/node": "^3.1.29-beta.
|
|
40
|
+
"@tradejs/connectors": "^3.1.29-beta.278",
|
|
41
|
+
"@tradejs/core": "^3.1.29-beta.278",
|
|
42
|
+
"@tradejs/indicators": "^3.1.29-beta.278",
|
|
43
|
+
"@tradejs/infra": "^3.1.29-beta.278",
|
|
44
|
+
"@tradejs/node": "^3.1.29-beta.278",
|
|
45
45
|
"@tradejs/strategy-kit": "3.0.6",
|
|
46
|
-
"@tradejs/types": "^3.1.29-beta.
|
|
46
|
+
"@tradejs/types": "^3.1.29-beta.278",
|
|
47
47
|
"args": "^5.0.3",
|
|
48
48
|
"bcryptjs": "^2.4.3",
|
|
49
49
|
"chalk": "4.1.2",
|