@tradejs/cli 1.0.8 → 1.0.10

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.
Files changed (76) hide show
  1. package/dist/cli.js +29748 -13641
  2. package/dist/lib/aiPocketSearch.js +1316 -0
  3. package/dist/lib/aiTrainCharts.js +711 -0
  4. package/dist/lib/aiTrainDataset.js +40 -0
  5. package/dist/lib/aiTrainEvaluationDump.js +76 -0
  6. package/dist/lib/aiTrainMetrics.js +148 -8
  7. package/dist/lib/aiTrainOptions.js +130 -0
  8. package/dist/lib/aiTrainQuarantine.js +199 -0
  9. package/dist/lib/aiTrainResearch.js +467 -0
  10. package/dist/lib/binanceMarketContextBackfill.js +841 -0
  11. package/dist/lib/binanceMarketData.js +392 -0
  12. package/dist/lib/coinMarketCapContextBackfill.js +1088 -0
  13. package/dist/lib/continuity.js +60 -0
  14. package/dist/lib/derivativesContextBackfill.js +490 -77
  15. package/dist/lib/executionCalibration.js +705 -0
  16. package/dist/lib/marketContextPrepare.js +4403 -0
  17. package/dist/lib/paritySummary.js +101 -0
  18. package/dist/lib/runBot.js +1 -0
  19. package/dist/lib/runEnvironment.js +2254 -0
  20. package/dist/lib/runFormatting.js +1657 -0
  21. package/dist/lib/runtimeDebugEvidence.js +526 -0
  22. package/dist/lib/runtimeModeConfig.js +53 -0
  23. package/dist/lib/runtimeParity.js +88 -11
  24. package/dist/lib/runtimeParityDetails.js +751 -0
  25. package/dist/lib/runtimeRedis.js +157 -0
  26. package/dist/lib/runtimeSignalsLoader.js +187 -0
  27. package/dist/lib/runtimeSignalsStorage.js +185 -0
  28. package/dist/lib/runtimeStrategyBacktest.js +134 -0
  29. package/dist/lib/runtimeTradeSync.js +263 -0
  30. package/dist/lib/telegramReports.js +9 -0
  31. package/dist/lib/tickerUniverseCache.js +116 -0
  32. package/dist/lib/timeWindow.js +3 -3
  33. package/dist/scripts/agentRun.js +28 -8
  34. package/dist/scripts/aiExport.js +1721 -7
  35. package/dist/scripts/aiExportSelect.js +16 -4
  36. package/dist/scripts/aiPocketSearch.js +4190 -0
  37. package/dist/scripts/aiTrain.js +1866 -87
  38. package/dist/scripts/backtest.js +4509 -818
  39. package/dist/scripts/binanceMarketIngest.js +565 -0
  40. package/dist/scripts/bot.js +16 -2
  41. package/dist/scripts/candlesMigrateProvider.js +32 -22
  42. package/dist/scripts/cleanDir.js +15 -2
  43. package/dist/scripts/cleanRedis.js +15 -2
  44. package/dist/scripts/cleanTests.js +38 -2
  45. package/dist/scripts/cleanupMarketContext.js +69 -0
  46. package/dist/scripts/continuity.js +148 -67
  47. package/dist/scripts/derivativesIngest.js +14 -4
  48. package/dist/scripts/derivativesIngestCoinalyzeAll.js +14 -4
  49. package/dist/scripts/doctor.js +14 -4
  50. package/dist/scripts/executionCalibration.js +792 -0
  51. package/dist/scripts/infraCommon.js +10 -0
  52. package/dist/scripts/infraDown.js +14 -4
  53. package/dist/scripts/infraInit.js +24 -4
  54. package/dist/scripts/infraUp.js +14 -4
  55. package/dist/scripts/marketWs.js +222 -0
  56. package/dist/scripts/migration.js +15 -2
  57. package/dist/scripts/mlExport.js +1698 -10
  58. package/dist/scripts/mlExportSelect.js +16 -4
  59. package/dist/scripts/mlInspect.js +13 -3
  60. package/dist/scripts/mlTrainLatestSelect.js +14 -4
  61. package/dist/scripts/replay.js +8824 -0
  62. package/dist/scripts/replayRunner.js +8827 -0
  63. package/dist/scripts/replayRuntimeEvidence.js +868 -0
  64. package/dist/scripts/researchAuto.js +289 -60
  65. package/dist/scripts/results.js +3 -3
  66. package/dist/scripts/runtimeEvidence.js +605 -0
  67. package/dist/scripts/runtimeParity.js +6360 -1004
  68. package/dist/scripts/serverHealth.js +588 -0
  69. package/dist/scripts/signals.js +5623 -486
  70. package/dist/scripts/signalsDaemon.js +6167 -0
  71. package/dist/scripts/signalsSummary.js +954 -312
  72. package/dist/scripts/test-ml.js +25 -3
  73. package/dist/scripts/test.js +26 -1
  74. package/dist/scripts/user-add.js +15 -2
  75. package/dist/workers/testerWorker.js +130 -21
  76. package/package.json +18 -12
@@ -0,0 +1,263 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/lib/runtimeTradeSync.ts
21
+ var runtimeTradeSync_exports = {};
22
+ __export(runtimeTradeSync_exports, {
23
+ EXCHANGE_HISTORY_MAX_RANGE_MS: () => EXCHANGE_HISTORY_MAX_RANGE_MS,
24
+ consumeClosedPnlMatch: () => consumeClosedPnlMatch,
25
+ formatRuntimeTradeSyncError: () => formatRuntimeTradeSyncError,
26
+ loadClosedPnlRows: () => loadClosedPnlRows,
27
+ splitExchangeHistoryTimeRange: () => splitExchangeHistoryTimeRange,
28
+ syncRuntimeTrades: () => syncRuntimeTrades
29
+ });
30
+ module.exports = __toCommonJS(runtimeTradeSync_exports);
31
+ var import_constants = require("@tradejs/core/constants");
32
+ var import_time = require("@tradejs/core/time");
33
+ var import_redis = require("@tradejs/infra/redis");
34
+ var CLOSED_PNL_LIMIT = 100;
35
+ var EXCHANGE_HISTORY_MAX_RANGE_MS = 7 * 24 * 60 * 60 * 1e3;
36
+ var splitExchangeHistoryTimeRange = ({
37
+ startTime,
38
+ endTime,
39
+ maxRangeMs = EXCHANGE_HISTORY_MAX_RANGE_MS
40
+ }) => {
41
+ if (!Number.isFinite(startTime) || !Number.isFinite(endTime) || !Number.isFinite(maxRangeMs) || maxRangeMs <= 0 || endTime <= startTime) {
42
+ return [{ startTime, endTime }];
43
+ }
44
+ const chunks = [];
45
+ let chunkStart = Math.trunc(startTime);
46
+ const finalEnd = Math.trunc(endTime);
47
+ const maxRange = Math.trunc(maxRangeMs);
48
+ while (chunkStart < finalEnd) {
49
+ const chunkEnd = Math.min(finalEnd, chunkStart + maxRange);
50
+ chunks.push({ startTime: chunkStart, endTime: chunkEnd });
51
+ if (chunkEnd >= finalEnd) {
52
+ break;
53
+ }
54
+ chunkStart = chunkEnd + 1;
55
+ }
56
+ return chunks;
57
+ };
58
+ var formatRuntimeTradeSyncError = (error) => {
59
+ if (!error || typeof error !== "object") {
60
+ return String(error || "unknown error");
61
+ }
62
+ const record = error;
63
+ const message = typeof record.message === "string" && record.message.trim() ? record.message.trim() : String(error);
64
+ const code = typeof record.code === "string" && record.code.trim() ? record.code.trim() : null;
65
+ const isAxiosError = record.isAxiosError === true;
66
+ const config = record.config && typeof record.config === "object" ? record.config : null;
67
+ const response = record.response && typeof record.response === "object" ? record.response : null;
68
+ const method = typeof config?.method === "string" && config.method.trim() ? config.method.toUpperCase() : null;
69
+ const url = typeof config?.url === "string" && config.url.trim() ? config.url.trim() : null;
70
+ const timeout = typeof config?.timeout === "number" && Number.isFinite(config.timeout) ? config.timeout : null;
71
+ const status = typeof response?.status === "number" && Number.isFinite(response.status) ? response.status : null;
72
+ const details = [
73
+ isAxiosError ? "axios" : null,
74
+ code,
75
+ status == null ? null : `status=${status}`,
76
+ method && url ? `${method} ${url}` : url,
77
+ timeout == null ? null : `timeout=${timeout}ms`
78
+ ].filter(Boolean);
79
+ return details.length > 0 ? `${message} (${details.join(", ")})` : message;
80
+ };
81
+ var loadClosedPnlRows = async ({
82
+ connector,
83
+ startTime,
84
+ endTime,
85
+ callbacks
86
+ }) => {
87
+ if (typeof connector.getClosedPnl !== "function") {
88
+ callbacks?.onUnsupported?.();
89
+ return [];
90
+ }
91
+ const rows = [];
92
+ const chunks = splitExchangeHistoryTimeRange({ startTime, endTime });
93
+ for (const chunk of chunks) {
94
+ try {
95
+ const chunkRows = await connector.getClosedPnl({
96
+ startTime: chunk.startTime,
97
+ endTime: chunk.endTime,
98
+ limit: CLOSED_PNL_LIMIT
99
+ });
100
+ if (chunkRows.length >= CLOSED_PNL_LIMIT) {
101
+ callbacks?.onCapped?.(chunkRows.length);
102
+ }
103
+ rows.push(...chunkRows);
104
+ } catch (error) {
105
+ callbacks?.onError?.(error);
106
+ }
107
+ }
108
+ return rows.sort((left, right) => left.closedAt - right.closedAt);
109
+ };
110
+ var consumeClosedPnlMatch = (buckets, trade) => {
111
+ const rows = buckets.get(trade.symbol);
112
+ if (!rows?.length) {
113
+ return null;
114
+ }
115
+ const minimumClosedAt = trade.entryTimestamp - 5 * 6e4;
116
+ const matchIndex = rows.findIndex(
117
+ (row2) => Number.isFinite(row2.closedAt) && row2.closedAt >= minimumClosedAt
118
+ );
119
+ if (matchIndex < 0) {
120
+ return null;
121
+ }
122
+ const [row] = rows.splice(matchIndex, 1);
123
+ return row ?? null;
124
+ };
125
+ var syncRuntimeTrades = async ({
126
+ userName,
127
+ connector,
128
+ trades,
129
+ startTime,
130
+ endTime,
131
+ closedPnlCallbacks,
132
+ openPositionCallbacks
133
+ }) => {
134
+ let openPositions = [];
135
+ let openPositionsReliable = true;
136
+ if (typeof connector.getOpenPositionPnl === "function") {
137
+ try {
138
+ openPositions = await connector.getOpenPositionPnl();
139
+ } catch (error) {
140
+ openPositionCallbacks?.onError?.(error);
141
+ openPositionsReliable = false;
142
+ openPositions = [];
143
+ }
144
+ }
145
+ const openPositionsBySymbol = new Map(
146
+ openPositions.map((position) => [position.symbol, position])
147
+ );
148
+ const activeOrderIdBySymbol = /* @__PURE__ */ new Map();
149
+ const symbols = [...new Set(trades.map((trade) => trade.symbol))];
150
+ await Promise.all(
151
+ symbols.map(async (symbol) => {
152
+ const activeRef = await (0, import_redis.getData)(
153
+ import_redis.redisKeys.runtimeActiveTrade(userName, symbol),
154
+ null
155
+ );
156
+ activeOrderIdBySymbol.set(
157
+ symbol,
158
+ typeof activeRef?.orderId === "string" ? activeRef.orderId : null
159
+ );
160
+ })
161
+ );
162
+ const closedPnlRows = await loadClosedPnlRows({
163
+ connector,
164
+ startTime,
165
+ endTime,
166
+ callbacks: closedPnlCallbacks
167
+ });
168
+ const closedPnlBuckets = /* @__PURE__ */ new Map();
169
+ for (const row of closedPnlRows) {
170
+ const bucket = closedPnlBuckets.get(row.symbol) ?? [];
171
+ bucket.push(row);
172
+ closedPnlBuckets.set(row.symbol, bucket);
173
+ }
174
+ const syncedTrades = [];
175
+ for (const trade of trades) {
176
+ if (trade.status !== "active") {
177
+ syncedTrades.push(trade);
178
+ continue;
179
+ }
180
+ const openPosition = openPositionsBySymbol.get(trade.symbol);
181
+ const activeOrderId = activeOrderIdBySymbol.get(trade.symbol);
182
+ const isCurrentActiveTrade = activeOrderId === trade.orderId;
183
+ if (!openPositionsReliable) {
184
+ syncedTrades.push({
185
+ ...trade,
186
+ status: "active",
187
+ lastSyncedAt: endTime
188
+ });
189
+ continue;
190
+ }
191
+ if (isCurrentActiveTrade && openPosition && openPosition.direction === trade.direction) {
192
+ const nextTrade2 = {
193
+ ...trade,
194
+ status: "active",
195
+ currentPrice: openPosition.currentPrice,
196
+ currentPnl: openPosition.unrealizedPnl,
197
+ lastSyncedAt: endTime
198
+ };
199
+ await (0, import_redis.setData)(
200
+ import_redis.redisKeys.runtimeTrade(userName, trade.orderId),
201
+ nextTrade2,
202
+ {
203
+ expire: 0
204
+ }
205
+ );
206
+ await (0, import_redis.setHashJsonField)(
207
+ import_redis.redisKeys.runtimeTradeBucket(
208
+ userName,
209
+ (0, import_time.getRuntimeStorageDayKey)(trade.entryTimestamp)
210
+ ),
211
+ trade.orderId,
212
+ nextTrade2,
213
+ { expire: 0 }
214
+ );
215
+ syncedTrades.push(nextTrade2);
216
+ continue;
217
+ }
218
+ const matchedClosedPnl = consumeClosedPnlMatch(closedPnlBuckets, trade);
219
+ const nextTrade = {
220
+ ...trade,
221
+ status: "closed",
222
+ currentPrice: matchedClosedPnl?.exitPrice ?? trade.currentPrice ?? null,
223
+ currentPnl: matchedClosedPnl?.closedPnl ?? trade.closedPnl ?? trade.currentPnl ?? null,
224
+ closedPnl: matchedClosedPnl?.closedPnl ?? trade.closedPnl ?? trade.currentPnl ?? null,
225
+ actualEntryPrice: matchedClosedPnl?.entryPrice ?? trade.actualEntryPrice ?? null,
226
+ exitPrice: matchedClosedPnl?.exitPrice ?? trade.exitPrice ?? null,
227
+ actualExitPrice: matchedClosedPnl?.exitPrice ?? trade.actualExitPrice ?? null,
228
+ exitTimestamp: matchedClosedPnl?.closedAt ?? trade.exitTimestamp ?? endTime,
229
+ exitType: trade.exitType ?? null,
230
+ openFee: matchedClosedPnl?.openFee ?? trade.openFee ?? null,
231
+ closeFee: matchedClosedPnl?.closeFee ?? trade.closeFee ?? null,
232
+ fundingFee: matchedClosedPnl?.fundingFee ?? trade.fundingFee ?? null,
233
+ totalFee: matchedClosedPnl?.totalFee ?? trade.totalFee ?? null,
234
+ lastSyncedAt: endTime
235
+ };
236
+ await Promise.all([
237
+ (0, import_redis.setData)(import_redis.redisKeys.runtimeTrade(userName, trade.orderId), nextTrade, {
238
+ expire: import_constants.TTL_1M
239
+ }),
240
+ (0, import_redis.setHashJsonField)(
241
+ import_redis.redisKeys.runtimeTradeBucket(
242
+ userName,
243
+ (0, import_time.getRuntimeStorageDayKey)(trade.entryTimestamp)
244
+ ),
245
+ trade.orderId,
246
+ nextTrade,
247
+ { expire: import_constants.TTL_1M }
248
+ ),
249
+ ...isCurrentActiveTrade ? [(0, import_redis.delKey)(import_redis.redisKeys.runtimeActiveTrade(userName, trade.symbol))] : []
250
+ ]);
251
+ syncedTrades.push(nextTrade);
252
+ }
253
+ return syncedTrades;
254
+ };
255
+ // Annotate the CommonJS export names for ESM import in node:
256
+ 0 && (module.exports = {
257
+ EXCHANGE_HISTORY_MAX_RANGE_MS,
258
+ consumeClosedPnlMatch,
259
+ formatRuntimeTradeSyncError,
260
+ loadClosedPnlRows,
261
+ splitExchangeHistoryTimeRange,
262
+ syncRuntimeTrades
263
+ });
@@ -68,8 +68,16 @@ ${line}` : line;
68
68
  };
69
69
  var sendTelegramReport = async (message, options = {}) => {
70
70
  const chunks = splitTelegramReport(message);
71
+ const sendAttachments = async () => {
72
+ for (const attachment of options.attachments || []) {
73
+ await (0, import_cli.sendDocumentToTG)(attachment, {
74
+ userName: options.userName
75
+ });
76
+ }
77
+ };
71
78
  if (chunks.length === 1) {
72
79
  await (0, import_cli.sendTextToTG)(chunks[0], options);
80
+ await sendAttachments();
73
81
  return chunks.length;
74
82
  }
75
83
  for (const [index, chunk] of chunks.entries()) {
@@ -81,6 +89,7 @@ ${chunk}`, {
81
89
  markup: index === chunks.length - 1 ? options.markup : void 0
82
90
  });
83
91
  }
92
+ await sendAttachments();
84
93
  return chunks.length;
85
94
  };
86
95
  // Annotate the CommonJS export names for ESM import in node:
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/lib/tickerUniverseCache.ts
21
+ var tickerUniverseCache_exports = {};
22
+ __export(tickerUniverseCache_exports, {
23
+ loadRunTickers: () => loadRunTickers
24
+ });
25
+ module.exports = __toCommonJS(tickerUniverseCache_exports);
26
+ var import_tickers = require("@tradejs/core/tickers");
27
+ var import_redis = require("@tradejs/infra/redis");
28
+ var import_cli = require("@tradejs/node/cli");
29
+ var TICKER_CACHE_VERSION = 1;
30
+ var parseSymbolsFromCLI = (symbols = "") => symbols.split(",").map((symbol) => symbol.trim().toUpperCase()).filter(Boolean);
31
+ var isTickerLike = (value) => {
32
+ if (!value || typeof value !== "object") {
33
+ return false;
34
+ }
35
+ const ticker = value;
36
+ return typeof ticker.symbol === "string" && ticker.symbol.trim().length > 0 && typeof ticker.volume24h === "number" && Number.isFinite(ticker.volume24h);
37
+ };
38
+ var readCachedTickerUniverse = async (cacheKey) => {
39
+ const cached = await (0, import_redis.getData)(cacheKey, null);
40
+ if (!cached || !Array.isArray(cached.tickers)) {
41
+ return null;
42
+ }
43
+ const tickers = cached.tickers.filter(isTickerLike);
44
+ return tickers.length ? tickers : null;
45
+ };
46
+ var selectTickerSymbols = ({
47
+ tickers,
48
+ exclude,
49
+ limit
50
+ }) => {
51
+ const excludedTickers = parseSymbolsFromCLI(exclude);
52
+ return (0, import_tickers.getTopTickers)(tickers, limit).map(({ value }) => value).filter((ticker) => !excludedTickers.includes(ticker));
53
+ };
54
+ var loadRunTickers = async ({
55
+ connector,
56
+ connectorName,
57
+ userName,
58
+ include,
59
+ exclude,
60
+ limit,
61
+ cacheOnly,
62
+ universe,
63
+ accountId,
64
+ assetClasses
65
+ }) => {
66
+ if (include?.trim()) {
67
+ return (0, import_cli.getTickers)(connector, include, exclude, limit, void 0, {
68
+ universe,
69
+ assetClasses
70
+ });
71
+ }
72
+ const cacheKey = import_redis.redisKeys.tickerUniverse(
73
+ userName,
74
+ connectorName,
75
+ universe,
76
+ accountId
77
+ );
78
+ if (cacheOnly) {
79
+ const cachedTickers = await readCachedTickerUniverse(cacheKey);
80
+ if (!cachedTickers) {
81
+ throw new Error(
82
+ `No cached ticker universe for ${connectorName}. Run once without --cacheOnly or pass --tickers explicitly.`
83
+ );
84
+ }
85
+ return selectTickerSymbols({
86
+ tickers: cachedTickers,
87
+ exclude,
88
+ limit
89
+ });
90
+ }
91
+ const exchangeTickers = await connector.getTickers({
92
+ universe,
93
+ assetClasses
94
+ });
95
+ if (exchangeTickers.length) {
96
+ await (0, import_redis.setData)(
97
+ cacheKey,
98
+ {
99
+ version: TICKER_CACHE_VERSION,
100
+ connectorName,
101
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
102
+ tickers: exchangeTickers
103
+ },
104
+ { expire: 0 }
105
+ );
106
+ }
107
+ return selectTickerSymbols({
108
+ tickers: exchangeTickers,
109
+ exclude,
110
+ limit
111
+ });
112
+ };
113
+ // Annotate the CommonJS export names for ESM import in node:
114
+ 0 && (module.exports = {
115
+ loadRunTickers
116
+ });
@@ -54,9 +54,10 @@ var resolveTimeWindow = ({
54
54
  }) => {
55
55
  const explicitStart = toEpochMs(startTime);
56
56
  const explicitEnd = toEpochMs(endTime);
57
+ const resolvedDays = toPositiveNumber(days);
57
58
  if (explicitStart != null || explicitEnd != null) {
58
- const resolvedEnd2 = explicitEnd ?? defaultEndMs ?? nowMs;
59
- const resolvedStart = explicitStart ?? defaultStartMs;
59
+ const resolvedStart = explicitStart ?? (resolvedDays != null && explicitEnd != null ? explicitEnd - resolvedDays * ONE_DAY_MS : defaultStartMs);
60
+ const resolvedEnd2 = explicitEnd ?? (resolvedDays != null && explicitStart != null ? explicitStart + resolvedDays * ONE_DAY_MS : defaultEndMs ?? nowMs);
60
61
  if (resolvedStart >= resolvedEnd2) {
61
62
  throw new Error(
62
63
  `Invalid time window: startTime (${resolvedStart}) must be less than endTime (${resolvedEnd2})`
@@ -68,7 +69,6 @@ var resolveTimeWindow = ({
68
69
  source: "explicit"
69
70
  };
70
71
  }
71
- const resolvedDays = toPositiveNumber(days);
72
72
  if (resolvedDays != null) {
73
73
  const resolvedEnd2 = defaultEndMs ?? nowMs;
74
74
  const resolvedStart = resolvedEnd2 - resolvedDays * ONE_DAY_MS;
@@ -5,6 +5,10 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
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
+ };
8
12
  var __copyProps = (to, from, except, desc) => {
9
13
  if (from && typeof from === "object" || typeof from === "function") {
10
14
  for (let key of __getOwnPropNames(from))
@@ -21,14 +25,21 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
21
25
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
26
  mod
23
27
  ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
24
29
 
25
30
  // src/scripts/agentRun.ts
31
+ var agentRun_exports = {};
32
+ __export(agentRun_exports, {
33
+ main: () => main
34
+ });
35
+ module.exports = __toCommonJS(agentRun_exports);
26
36
  var import_args = __toESM(require("args"));
27
37
  var import_chalk = __toESM(require("chalk"));
28
38
  var import_promises = __toESM(require("fs/promises"));
29
39
  var import_node_os = __toESM(require("os"));
30
40
  var import_node_path2 = __toESM(require("path"));
31
41
  var import_node_child_process = require("child_process");
42
+ var import_constants = require("@tradejs/core/constants");
32
43
  var import_redis = require("@tradejs/infra/redis");
33
44
  var import_userSettings = require("@tradejs/infra/userSettings");
34
45
 
@@ -76,8 +87,16 @@ ${line}` : line;
76
87
  };
77
88
  var sendTelegramReport = async (message, options = {}) => {
78
89
  const chunks = splitTelegramReport(message);
90
+ const sendAttachments = async () => {
91
+ for (const attachment of options.attachments || []) {
92
+ await (0, import_cli.sendDocumentToTG)(attachment, {
93
+ userName: options.userName
94
+ });
95
+ }
96
+ };
79
97
  if (chunks.length === 1) {
80
98
  await (0, import_cli.sendTextToTG)(chunks[0], options);
99
+ await sendAttachments();
81
100
  return chunks.length;
82
101
  }
83
102
  for (const [index, chunk] of chunks.entries()) {
@@ -89,6 +108,7 @@ ${chunk}`, {
89
108
  markup: index === chunks.length - 1 ? options.markup : void 0
90
109
  });
91
110
  }
111
+ await sendAttachments();
92
112
  return chunks.length;
93
113
  };
94
114
 
@@ -593,9 +613,11 @@ var saveAgentRun = async (userName, runId, strategy, agentRun) => {
593
613
  ...run.artifacts,
594
614
  agentRun
595
615
  };
596
- await (0, import_redis.setData)(import_redis.redisKeys.researchRun(userName, runId), run, { expire: 0 });
616
+ await (0, import_redis.setData)(import_redis.redisKeys.researchRun(userName, runId), run, {
617
+ expire: import_constants.TTL_1M
618
+ });
597
619
  await (0, import_redis.setData)(import_redis.redisKeys.researchLatestRun(userName, strategy), run, {
598
- expire: 0
620
+ expire: import_constants.TTL_1M
599
621
  });
600
622
  };
601
623
  var resolveGithubRepository = async (worktreePath) => {
@@ -887,9 +909,7 @@ Return a corrected unified diff only. Keep the same allowed paths.`
887
909
  }
888
910
  }
889
911
  };
890
- if (require.main === module) {
891
- main().catch((error) => {
892
- console.error(import_chalk.default.red(error?.message || String(error)));
893
- process.exit(1);
894
- });
895
- }
912
+ // Annotate the CommonJS export names for ESM import in node:
913
+ 0 && (module.exports = {
914
+ main
915
+ });