@tradejs/cli 3.1.0 → 3.1.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.
@@ -0,0 +1,290 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/scripts/runtimeConfig.ts
31
+ var runtimeConfig_exports = {};
32
+ __export(runtimeConfig_exports, {
33
+ main: () => main,
34
+ runtimeConfig: () => runtimeConfig
35
+ });
36
+ module.exports = __toCommonJS(runtimeConfig_exports);
37
+ var import_config = require("dotenv/config");
38
+ var import_promises = require("fs/promises");
39
+ var import_node_path = __toESM(require("path"));
40
+ var import_runtimeDeployments = require("@tradejs/infra/runtimeDeployments");
41
+ var import_runtimeStrategyConfigs = require("@tradejs/infra/runtimeStrategyConfigs");
42
+ var import_runtimeStrategyReleases = require("@tradejs/infra/runtimeStrategyReleases");
43
+ var import_runtimeStrategies = require("@tradejs/node/runtimeStrategies");
44
+ var import_strategies = require("@tradejs/node/strategies");
45
+ var argv = process.argv.slice(2);
46
+ var action = argv[0] ?? "inspect";
47
+ var option = (name) => {
48
+ const index = argv.indexOf(`--${name}`);
49
+ return index >= 0 ? argv[index + 1] : void 0;
50
+ };
51
+ var hasFlag = (name) => argv.includes(`--${name}`);
52
+ var required = (name) => {
53
+ const value = String(option(name) ?? "").trim();
54
+ if (!value) throw new Error(`--${name} is required`);
55
+ return value;
56
+ };
57
+ var projectRoot = String(process.env.PROJECT_CWD || process.cwd()).trim() || process.cwd();
58
+ var userName = String(option("user") ?? process.env.USER_NAME ?? "root");
59
+ var OPERATIONAL_CONFIG_KEYS = [
60
+ "ACCOUNT_ID",
61
+ "AI_REPLAY_ANALYSES",
62
+ "DEPLOYMENT_ID",
63
+ "ENABLE",
64
+ "ENV",
65
+ "MAKE_ORDERS",
66
+ "RECORD_RUNTIME_TRADES",
67
+ "configId"
68
+ ];
69
+ var toReleaseConfig = async (strategyName, sourceConfig) => {
70
+ const defaults = await (0, import_strategies.getStrategyDefaults)(strategyName, projectRoot) ?? {};
71
+ const config = { ...defaults, ...sourceConfig };
72
+ for (const key of OPERATIONAL_CONFIG_KEYS) delete config[key];
73
+ return config;
74
+ };
75
+ var writeMigrationBackup = async (payload) => {
76
+ const directory = import_node_path.default.join(projectRoot, "data", "runtime-config-backups");
77
+ await (0, import_promises.mkdir)(directory, { recursive: true });
78
+ const backupPath = import_node_path.default.join(
79
+ directory,
80
+ `${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}.json`
81
+ );
82
+ await (0, import_promises.writeFile)(backupPath, `${JSON.stringify(payload, null, 2)}
83
+ `, {
84
+ flag: "wx"
85
+ });
86
+ return backupPath;
87
+ };
88
+ var publish = async ({
89
+ strategyName,
90
+ sourceConfig
91
+ }) => {
92
+ const config = await toReleaseConfig(strategyName, sourceConfig);
93
+ const metadata = await (0, import_runtimeStrategies.getRuntimeStrategyPackageMetadata)({
94
+ strategyName,
95
+ projectRoot
96
+ });
97
+ return (0, import_runtimeStrategyReleases.publishRuntimeStrategyRelease)({
98
+ userName,
99
+ strategyName,
100
+ config,
101
+ ...metadata,
102
+ createdBy: `cli:${userName}`
103
+ });
104
+ };
105
+ var migrate = async () => {
106
+ const strategyName = required("strategy");
107
+ const configId = option("config") ?? "config";
108
+ const deploymentId = required("deployment");
109
+ const [sourceConfig, deployment] = await Promise.all([
110
+ (0, import_runtimeStrategyConfigs.getRuntimeStrategyConfig)(userName, strategyName, configId),
111
+ (0, import_runtimeDeployments.getRuntimeDeployment)(userName, deploymentId)
112
+ ]);
113
+ if (!sourceConfig) {
114
+ throw new Error(`Legacy config not found: ${strategyName}:${configId}`);
115
+ }
116
+ if (!deployment) throw new Error(`Deployment not found: ${deploymentId}`);
117
+ const reference = deployment.strategies.find(
118
+ (strategy) => strategy.strategyName === strategyName
119
+ );
120
+ if (!reference) {
121
+ throw new Error(`${strategyName} is not bound to ${deploymentId}`);
122
+ }
123
+ const preview = {
124
+ source: { configId, config: sourceConfig },
125
+ releaseConfig: await toReleaseConfig(strategyName, sourceConfig),
126
+ deployment: {
127
+ id: deployment.id,
128
+ accountId: deployment.accountId,
129
+ strategy: {
130
+ strategyName,
131
+ releaseVersion: "<allocated on write>",
132
+ controlState: "entries_paused"
133
+ }
134
+ }
135
+ };
136
+ if (!hasFlag("write")) {
137
+ console.log(JSON.stringify({ dryRun: true, ...preview }, null, 2));
138
+ return;
139
+ }
140
+ const backupPath = await writeMigrationBackup({
141
+ userName,
142
+ capturedAt: Date.now(),
143
+ deployment,
144
+ legacyConfig: sourceConfig
145
+ });
146
+ const release = await publish({ strategyName, sourceConfig });
147
+ const updatedDeployment = {
148
+ ...deployment,
149
+ strategies: deployment.strategies.map(
150
+ (strategy) => strategy.strategyName === strategyName ? {
151
+ strategyName,
152
+ releaseVersion: release.releaseVersion,
153
+ controlState: "entries_paused"
154
+ } : strategy
155
+ )
156
+ };
157
+ await (0, import_runtimeDeployments.saveRuntimeDeployment)(userName, updatedDeployment);
158
+ console.log(
159
+ JSON.stringify(
160
+ { migrated: true, backupPath, release, deployment: updatedDeployment },
161
+ null,
162
+ 2
163
+ )
164
+ );
165
+ };
166
+ var publishDraft = async () => {
167
+ const strategyName = required("strategy");
168
+ const draft = await (0, import_runtimeStrategyReleases.getRuntimeStrategyDraft)(userName, strategyName);
169
+ if (!draft) throw new Error(`Draft not found: ${strategyName}`);
170
+ const release = await publish({ strategyName, sourceConfig: draft.config });
171
+ console.log(JSON.stringify({ release }, null, 2));
172
+ };
173
+ var updateControlState = async (nextState) => {
174
+ const strategyName = required("strategy");
175
+ const deploymentId = required("deployment");
176
+ const deployment = await (0, import_runtimeDeployments.getRuntimeDeployment)(userName, deploymentId);
177
+ if (!deployment) throw new Error(`Deployment not found: ${deploymentId}`);
178
+ const reference = deployment.strategies.find(
179
+ (strategy) => strategy.strategyName === strategyName
180
+ );
181
+ if (!reference?.releaseVersion) {
182
+ throw new Error(`${strategyName} is not a versioned deployment reference`);
183
+ }
184
+ const previousState = reference.controlState ?? "active";
185
+ const updated = await (0, import_runtimeDeployments.saveRuntimeDeployment)(userName, {
186
+ ...deployment,
187
+ strategies: deployment.strategies.map(
188
+ (strategy) => strategy.strategyName === strategyName ? { ...strategy, controlState: nextState } : strategy
189
+ )
190
+ });
191
+ const event = previousState === nextState ? null : await (0, import_runtimeStrategyReleases.recordRuntimeStrategyControlEvent)({
192
+ userName,
193
+ deploymentId,
194
+ strategyName,
195
+ releaseVersion: reference.releaseVersion,
196
+ previousState,
197
+ nextState,
198
+ createdBy: `cli:${userName}`
199
+ });
200
+ console.log(JSON.stringify({ deployment: updated, event }, null, 2));
201
+ };
202
+ var rollback = async () => {
203
+ const strategyName = required("strategy");
204
+ const deploymentId = required("deployment");
205
+ const releaseVersion = Number(required("release"));
206
+ if (!Number.isSafeInteger(releaseVersion) || releaseVersion <= 0) {
207
+ throw new Error("--release must be a positive integer");
208
+ }
209
+ const deployment = await (0, import_runtimeDeployments.getRuntimeDeployment)(userName, deploymentId);
210
+ if (!deployment) throw new Error(`Deployment not found: ${deploymentId}`);
211
+ const release = (await (0, import_runtimeStrategyReleases.listRuntimeStrategyReleases)(userName, strategyName)).find((candidate) => candidate.releaseVersion === releaseVersion);
212
+ if (!release)
213
+ throw new Error(`Release not found: ${strategyName} v${releaseVersion}`);
214
+ const backupPath = await writeMigrationBackup({
215
+ userName,
216
+ capturedAt: Date.now(),
217
+ deployment,
218
+ reason: "rollback"
219
+ });
220
+ const updated = await (0, import_runtimeDeployments.saveRuntimeDeployment)(userName, {
221
+ ...deployment,
222
+ strategies: deployment.strategies.map(
223
+ (strategy) => strategy.strategyName === strategyName ? {
224
+ strategyName,
225
+ releaseVersion,
226
+ controlState: "entries_paused"
227
+ } : strategy
228
+ )
229
+ });
230
+ console.log(JSON.stringify({ backupPath, deployment: updated }, null, 2));
231
+ };
232
+ var verify = async () => {
233
+ const deployments = await (0, import_runtimeDeployments.listRuntimeDeployments)(userName);
234
+ const selected = option("deployment") ? deployments.filter((deployment) => deployment.id === option("deployment")) : deployments;
235
+ const results = [];
236
+ for (const deployment of selected) {
237
+ try {
238
+ const strategies = await (0, import_runtimeStrategies.loadResolvedRuntimeStrategies)({
239
+ userName,
240
+ projectRoot,
241
+ deployment,
242
+ connectorName: deployment.connectorName
243
+ });
244
+ results.push({
245
+ deploymentId: deployment.id,
246
+ ok: true,
247
+ strategies: strategies.map((strategy) => ({
248
+ strategyName: strategy.strategyName,
249
+ releaseVersion: strategy.releaseVersion,
250
+ controlState: strategy.controlState,
251
+ interval: strategy.interval,
252
+ universe: strategy.universe,
253
+ accountId: strategy.accountId
254
+ }))
255
+ });
256
+ } catch (error) {
257
+ results.push({
258
+ deploymentId: deployment.id,
259
+ ok: false,
260
+ error: error instanceof Error ? error.message : String(error)
261
+ });
262
+ }
263
+ }
264
+ console.log(JSON.stringify({ userName, results }, null, 2));
265
+ if (results.some((result) => !result.ok)) process.exitCode = 1;
266
+ };
267
+ var inspect = async () => {
268
+ const strategyName = option("strategy");
269
+ const deployments = await (0, import_runtimeDeployments.listRuntimeDeployments)(userName);
270
+ const releases = strategyName ? await (0, import_runtimeStrategyReleases.listRuntimeStrategyReleases)(userName, strategyName) : void 0;
271
+ console.log(JSON.stringify({ userName, deployments, releases }, null, 2));
272
+ };
273
+ var runtimeConfig = async () => {
274
+ if (action === "migrate") return migrate();
275
+ if (action === "publish-draft") return publishDraft();
276
+ if (action === "verify") return verify();
277
+ if (action === "pause") return updateControlState("entries_paused");
278
+ if (action === "resume") return updateControlState("active");
279
+ if (action === "rollback") return rollback();
280
+ if (action === "inspect") return inspect();
281
+ throw new Error(
282
+ "Usage: tradejs runtime-config inspect|verify|migrate|publish-draft|pause|resume|rollback"
283
+ );
284
+ };
285
+ var main = runtimeConfig;
286
+ // Annotate the CommonJS export names for ESM import in node:
287
+ 0 && (module.exports = {
288
+ main,
289
+ runtimeConfig
290
+ });
@@ -573,7 +573,7 @@ var import_promises2 = __toESM(require("fs/promises"));
573
573
  var import_node_path2 = __toESM(require("path"));
574
574
 
575
575
  // src/lib/runtimeLineage.ts
576
- var runtimeLineageKey = (lineage) => [
576
+ var runtimeLineageKey = (lineage) => lineage.schemaVersion === 2 ? ["v2", lineage.releaseVersion].join(":") : [
577
577
  lineage.schemaVersion,
578
578
  lineage.compositionId ?? "unbound-composition",
579
579
  lineage.gitSha ?? "unknown",
@@ -4808,7 +4808,7 @@ var buildRuntimeModeStrategyConfig = ({
4808
4808
  ...strategyConfig,
4809
4809
  ENV: env,
4810
4810
  MAKE_ORDERS: makeOrders,
4811
- INTERVAL: interval2,
4811
+ INTERVAL: strategyConfig.INTERVAL ?? interval2,
4812
4812
  ...typeof recordRuntimeTrades === "boolean" ? { RECORD_RUNTIME_TRADES: recordRuntimeTrades } : {},
4813
4813
  ...aiReplayAnalyses?.length ? { AI_REPLAY_ANALYSES: aiReplayAnalyses } : {}
4814
4814
  });