@tradejs/cli 3.1.29-beta.277 → 3.1.29-beta.280
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 +291 -316
- package/dist/lib/mcpReplayProcess.js +47 -73
- package/dist/scripts/mcpWorker.js +69 -97
- package/package.json +7 -7
|
@@ -35,16 +35,35 @@ __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
|
+
const temporary = file + '.request.tmp-' + process.pid;
|
|
53
|
+
fs.writeFileSync(temporary, request, {flag:'wx'});
|
|
54
|
+
try { fs.linkSync(temporary, file + '.request'); }
|
|
55
|
+
catch (error) { if (error.code !== 'EEXIST') throw error; if (fs.readFileSync(file + '.request', 'utf8') !== request) throw new Error('Replay request identity conflict'); }
|
|
56
|
+
finally { fs.unlinkSync(temporary); }
|
|
57
|
+
process.on('SIGTERM', () => { fs.writeFileSync(file + '.cancel', 'cancel'); process.exit(143); });
|
|
58
|
+
const timer = setInterval(() => {
|
|
59
|
+
try {
|
|
60
|
+
const result = JSON.parse(fs.readFileSync(file + '.result', 'utf8'));
|
|
61
|
+
console.log(result.message);
|
|
62
|
+
clearInterval(timer);
|
|
63
|
+
process.exit(result.exitCode === 0 ? 0 : 1);
|
|
64
|
+
} catch (error) { if (error.code !== 'ENOENT') throw error; }
|
|
65
|
+
}, 1000);
|
|
66
|
+
`;
|
|
48
67
|
var buildMcpReplayProcess = async ({
|
|
49
68
|
evidencePath,
|
|
50
69
|
outDir,
|
|
@@ -52,79 +71,34 @@ var buildMcpReplayProcess = async ({
|
|
|
52
71
|
projectRoot,
|
|
53
72
|
env
|
|
54
73
|
}) => {
|
|
55
|
-
if (!/^[a-
|
|
56
|
-
throw new Error("Invalid replay
|
|
74
|
+
if (!/^[a-f0-9]{64}$/.test(runId))
|
|
75
|
+
throw new Error("Invalid replay request id");
|
|
57
76
|
const bundle = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(import_node_path.default.dirname(evidencePath));
|
|
58
77
|
if (import_node_path.default.resolve(evidencePath) !== import_node_path.default.resolve(bundle.payloadPath))
|
|
59
78
|
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
|
|
79
|
+
const relative = import_node_path.default.relative(import_node_path.default.join(projectRoot, "data"), evidencePath);
|
|
80
|
+
if (relative.startsWith("..") || import_node_path.default.isAbsolute(relative))
|
|
81
|
+
throw new Error("Evidence must be inside Project data");
|
|
82
|
+
const root = env.MCP_REPLAY_REQUEST_ROOT || import_node_path.default.join(projectRoot, "data/mcp-replay-requests");
|
|
83
|
+
const heartbeat = JSON.parse(
|
|
84
|
+
await import_promises.default.readFile(import_node_path.default.join(root, "heartbeat.json"), "utf8")
|
|
126
85
|
);
|
|
127
|
-
|
|
86
|
+
if (!Number.isFinite(heartbeat.observedAt) || Date.now() - heartbeat.observedAt < 0 || Date.now() - heartbeat.observedAt > 12e4)
|
|
87
|
+
throw new Error("Host replay runner heartbeat is stale");
|
|
88
|
+
const bytes = await import_promises.default.readFile(evidencePath);
|
|
89
|
+
const request = JSON.stringify({
|
|
90
|
+
schemaVersion: 1,
|
|
91
|
+
id: runId,
|
|
92
|
+
evidence: relative,
|
|
93
|
+
artifactId: bundle.manifest.artifactId,
|
|
94
|
+
deploymentId: bundle.manifest.deploymentId,
|
|
95
|
+
payloadSha256: (0, import_node_crypto.createHash)("sha256").update(bytes).digest("hex")
|
|
96
|
+
});
|
|
97
|
+
void outDir;
|
|
98
|
+
return {
|
|
99
|
+
executable: process.execPath,
|
|
100
|
+
args: ["-e", client, root, runId, request]
|
|
101
|
+
};
|
|
128
102
|
};
|
|
129
103
|
// Annotate the CommonJS export names for ESM import in node:
|
|
130
104
|
0 && (module.exports = {
|
|
@@ -35,23 +35,42 @@ __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
|
+
const temporary = file + '.request.tmp-' + process.pid;
|
|
60
|
+
fs.writeFileSync(temporary, request, {flag:'wx'});
|
|
61
|
+
try { fs.linkSync(temporary, file + '.request'); }
|
|
62
|
+
catch (error) { if (error.code !== 'EEXIST') throw error; if (fs.readFileSync(file + '.request', 'utf8') !== request) throw new Error('Replay request identity conflict'); }
|
|
63
|
+
finally { fs.unlinkSync(temporary); }
|
|
64
|
+
process.on('SIGTERM', () => { fs.writeFileSync(file + '.cancel', 'cancel'); process.exit(143); });
|
|
65
|
+
const timer = setInterval(() => {
|
|
66
|
+
try {
|
|
67
|
+
const result = JSON.parse(fs.readFileSync(file + '.result', 'utf8'));
|
|
68
|
+
console.log(result.message);
|
|
69
|
+
clearInterval(timer);
|
|
70
|
+
process.exit(result.exitCode === 0 ? 0 : 1);
|
|
71
|
+
} catch (error) { if (error.code !== 'ENOENT') throw error; }
|
|
72
|
+
}, 1000);
|
|
73
|
+
`;
|
|
55
74
|
var buildMcpReplayProcess = async ({
|
|
56
75
|
evidencePath,
|
|
57
76
|
outDir,
|
|
@@ -59,79 +78,34 @@ var buildMcpReplayProcess = async ({
|
|
|
59
78
|
projectRoot,
|
|
60
79
|
env
|
|
61
80
|
}) => {
|
|
62
|
-
if (!/^[a-
|
|
63
|
-
throw new Error("Invalid replay
|
|
81
|
+
if (!/^[a-f0-9]{64}$/.test(runId))
|
|
82
|
+
throw new Error("Invalid replay request id");
|
|
64
83
|
const bundle = await (0, runtimeEvidenceArtifacts_exports.verifyRuntimeEvidenceBundle)(import_node_path.default.dirname(evidencePath));
|
|
65
84
|
if (import_node_path.default.resolve(evidencePath) !== import_node_path.default.resolve(bundle.payloadPath))
|
|
66
85
|
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
|
|
86
|
+
const relative = import_node_path.default.relative(import_node_path.default.join(projectRoot, "data"), evidencePath);
|
|
87
|
+
if (relative.startsWith("..") || import_node_path.default.isAbsolute(relative))
|
|
88
|
+
throw new Error("Evidence must be inside Project data");
|
|
89
|
+
const root = env.MCP_REPLAY_REQUEST_ROOT || import_node_path.default.join(projectRoot, "data/mcp-replay-requests");
|
|
90
|
+
const heartbeat = JSON.parse(
|
|
91
|
+
await import_promises.default.readFile(import_node_path.default.join(root, "heartbeat.json"), "utf8")
|
|
133
92
|
);
|
|
134
|
-
|
|
93
|
+
if (!Number.isFinite(heartbeat.observedAt) || Date.now() - heartbeat.observedAt < 0 || Date.now() - heartbeat.observedAt > 12e4)
|
|
94
|
+
throw new Error("Host replay runner heartbeat is stale");
|
|
95
|
+
const bytes = await import_promises.default.readFile(evidencePath);
|
|
96
|
+
const request = JSON.stringify({
|
|
97
|
+
schemaVersion: 1,
|
|
98
|
+
id: runId,
|
|
99
|
+
evidence: relative,
|
|
100
|
+
artifactId: bundle.manifest.artifactId,
|
|
101
|
+
deploymentId: bundle.manifest.deploymentId,
|
|
102
|
+
payloadSha256: (0, import_node_crypto.createHash)("sha256").update(bytes).digest("hex")
|
|
103
|
+
});
|
|
104
|
+
void outDir;
|
|
105
|
+
return {
|
|
106
|
+
executable: process.execPath,
|
|
107
|
+
args: ["-e", client, root, runId, request]
|
|
108
|
+
};
|
|
135
109
|
};
|
|
136
110
|
|
|
137
111
|
// src/scripts/mcpWorker.ts
|
|
@@ -140,7 +114,7 @@ var leaseKey = "worker:lease";
|
|
|
140
114
|
var LEASE_SECONDS = 15;
|
|
141
115
|
var JOB_TIMEOUT_MS = 60 * 60 * 1e3;
|
|
142
116
|
var main = async (options = {}) => {
|
|
143
|
-
const owner = (0,
|
|
117
|
+
const owner = (0, import_node_crypto2.randomUUID)();
|
|
144
118
|
if (!await import_redis.mcpStorage.put(leaseKey, owner, LEASE_SECONDS, true))
|
|
145
119
|
throw new Error("Another MCP worker owns this storage");
|
|
146
120
|
let stopping = false;
|
|
@@ -148,6 +122,18 @@ var main = async (options = {}) => {
|
|
|
148
122
|
let renewing = false;
|
|
149
123
|
let leaseLost = false;
|
|
150
124
|
let manifestHash = "";
|
|
125
|
+
let replayReady = false;
|
|
126
|
+
const updateReplayReady = async () => {
|
|
127
|
+
try {
|
|
128
|
+
const root = process.env.MCP_REPLAY_REQUEST_ROOT || `${process.env.PROJECT_CWD || process.cwd()}/data/mcp-replay-requests`;
|
|
129
|
+
const heartbeat2 = JSON.parse(
|
|
130
|
+
await (0, import_promises2.readFile)(`${root}/heartbeat.json`, "utf8")
|
|
131
|
+
);
|
|
132
|
+
replayReady = Number.isFinite(heartbeat2.observedAt) && Date.now() - heartbeat2.observedAt >= 0 && Date.now() - heartbeat2.observedAt < 12e4;
|
|
133
|
+
} catch {
|
|
134
|
+
replayReady = false;
|
|
135
|
+
}
|
|
136
|
+
};
|
|
151
137
|
const signalChild = (signal) => {
|
|
152
138
|
if (!child?.pid) return;
|
|
153
139
|
try {
|
|
@@ -161,9 +147,7 @@ var main = async (options = {}) => {
|
|
|
161
147
|
const heartbeatValue = () => ({
|
|
162
148
|
observedAt: Date.now(),
|
|
163
149
|
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
|
-
)
|
|
150
|
+
replayAvailable: replayReady
|
|
167
151
|
});
|
|
168
152
|
const stop = () => {
|
|
169
153
|
stopping = true;
|
|
@@ -179,6 +163,7 @@ var main = async (options = {}) => {
|
|
|
179
163
|
try {
|
|
180
164
|
if (!await import_redis.mcpStorage.compare(leaseKey, owner, owner, LEASE_SECONDS))
|
|
181
165
|
throw new Error("Worker lease lost");
|
|
166
|
+
await updateReplayReady();
|
|
182
167
|
await import_redis.mcpStorage.put("worker:heartbeat", heartbeatValue(), LEASE_SECONDS);
|
|
183
168
|
} catch {
|
|
184
169
|
leaseLost = true;
|
|
@@ -189,6 +174,7 @@ var main = async (options = {}) => {
|
|
|
189
174
|
}, 2e3);
|
|
190
175
|
try {
|
|
191
176
|
manifestHash = await (0, import_mcp.mcpPackageManifestHash)();
|
|
177
|
+
await updateReplayReady();
|
|
192
178
|
await import_redis.mcpStorage.put("worker:heartbeat", heartbeatValue(), LEASE_SECONDS);
|
|
193
179
|
let cursor = "0";
|
|
194
180
|
do {
|
|
@@ -253,7 +239,7 @@ var main = async (options = {}) => {
|
|
|
253
239
|
);
|
|
254
240
|
continue;
|
|
255
241
|
}
|
|
256
|
-
await (0,
|
|
242
|
+
await (0, import_promises2.mkdir)((0, import_mcp.mcpJobDirectory)(started), { recursive: true });
|
|
257
243
|
if (started.kind === "backtest")
|
|
258
244
|
await (0, import_redis.setDataStrict)(
|
|
259
245
|
import_redis.redisKeys.backtestConfig(
|
|
@@ -276,7 +262,9 @@ var main = async (options = {}) => {
|
|
|
276
262
|
};
|
|
277
263
|
if (started.kind === "runtime-feedback-replay") {
|
|
278
264
|
for (const name of Object.keys(jobEnv)) {
|
|
279
|
-
if (/secret|token|api.?key|private.?key|cookie|credential/i.test(
|
|
265
|
+
if (/secret|password|token|api.?key|private.?key|cookie|credential/i.test(
|
|
266
|
+
name
|
|
267
|
+
))
|
|
280
268
|
delete jobEnv[name];
|
|
281
269
|
}
|
|
282
270
|
Object.assign(jobEnv, {
|
|
@@ -317,8 +305,6 @@ var main = async (options = {}) => {
|
|
|
317
305
|
);
|
|
318
306
|
continue;
|
|
319
307
|
}
|
|
320
|
-
if (started.kind === "runtime-feedback-replay" && process.env.PG_PASSWORD)
|
|
321
|
-
jobEnv.PG_PASSWORD = process.env.PG_PASSWORD;
|
|
322
308
|
child = (0, import_node_child_process.spawn)(command.executable, command.args, {
|
|
323
309
|
cwd: process.env.PROJECT_CWD || process.cwd(),
|
|
324
310
|
env: jobEnv,
|
|
@@ -373,20 +359,6 @@ var main = async (options = {}) => {
|
|
|
373
359
|
);
|
|
374
360
|
currentChild.once("exit", (code) => resolve({ code }));
|
|
375
361
|
});
|
|
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
362
|
clearTimeout(timeout);
|
|
391
363
|
clearInterval(monitor);
|
|
392
364
|
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.280",
|
|
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.280",
|
|
41
|
+
"@tradejs/core": "^3.1.29-beta.280",
|
|
42
|
+
"@tradejs/indicators": "^3.1.29-beta.280",
|
|
43
|
+
"@tradejs/infra": "^3.1.29-beta.280",
|
|
44
|
+
"@tradejs/node": "^3.1.29-beta.280",
|
|
45
45
|
"@tradejs/strategy-kit": "3.0.6",
|
|
46
|
-
"@tradejs/types": "^3.1.29-beta.
|
|
46
|
+
"@tradejs/types": "^3.1.29-beta.280",
|
|
47
47
|
"args": "^5.0.3",
|
|
48
48
|
"bcryptjs": "^2.4.3",
|
|
49
49
|
"chalk": "4.1.2",
|