@tradejs/node 3.1.29-beta.269 → 3.1.29-beta.271

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 CHANGED
@@ -2219,8 +2219,9 @@ var parseTelegramResponse = async (response) => {
2219
2219
  }
2220
2220
  }
2221
2221
  };
2222
- var getTelegramSettings = async (userName = "root") => {
2222
+ var getTelegramSettings = async (userName = "root", notification) => {
2223
2223
  const settings = await (0, import_userSettings2.getUserSettings)(userName);
2224
+ if (notification && settings[notification] === false) return null;
2224
2225
  const token = settings.TG_BOT_TOKEN;
2225
2226
  const chatId = settings.TG_CHAT_ID;
2226
2227
  if (!token || !chatId) {
@@ -2285,7 +2286,9 @@ var sendTelegramMessage = async ({
2285
2286
  return data;
2286
2287
  };
2287
2288
  var sendTextToTG = async (message, options = {}) => {
2288
- const { token, chatId } = await getTelegramSettings(options.userName);
2289
+ const telegram = await getTelegramSettings(options.userName);
2290
+ if (!telegram) return;
2291
+ const { token, chatId } = telegram;
2289
2292
  return sendTelegramMessage({
2290
2293
  message,
2291
2294
  markup: options.markup,
@@ -2294,7 +2297,12 @@ var sendTextToTG = async (message, options = {}) => {
2294
2297
  });
2295
2298
  };
2296
2299
  var sendDocumentToTG = async (document, options = {}) => {
2297
- const { token, chatId } = await getTelegramSettings(options.userName);
2300
+ const telegram = await getTelegramSettings(
2301
+ options.userName,
2302
+ "NOTIFY_RUNTIME_DEBUG"
2303
+ );
2304
+ if (!telegram) return;
2305
+ const { token, chatId } = telegram;
2298
2306
  const body = new FormData();
2299
2307
  const fileContent = typeof document.content === "string" ? document.content : (() => {
2300
2308
  const bytes = new Uint8Array(document.content.byteLength);
@@ -2427,7 +2435,12 @@ var formatMessage = (signal, analysis, _options = {}) => {
2427
2435
  };
2428
2436
  var sendSignal = async (signal, imgInterval, analysis, options = {}) => {
2429
2437
  const { symbol, signalId, interval } = signal;
2430
- const { token, chatId } = await getTelegramSettings(options.userName);
2438
+ const telegram = await getTelegramSettings(
2439
+ options.userName,
2440
+ "NOTIFY_SIGNALS"
2441
+ );
2442
+ if (!telegram) return;
2443
+ const { token, chatId } = telegram;
2431
2444
  const message = formatMessage(signal, analysis, {
2432
2445
  userName: options.userName
2433
2446
  });
@@ -2591,7 +2604,12 @@ var formatAnalysisMessage = (signal, analysis) => {
2591
2604
  return lines.join("\n");
2592
2605
  };
2593
2606
  var sendSignalAnalysis = async (signal, analysis, options = {}) => {
2594
- const { token, chatId } = await getTelegramSettings(options.userName);
2607
+ const telegram = await getTelegramSettings(
2608
+ options.userName,
2609
+ "NOTIFY_AI_ANALYSIS"
2610
+ );
2611
+ if (!telegram) return;
2612
+ const { token, chatId } = telegram;
2595
2613
  const message = formatAnalysisMessage(signal, analysis);
2596
2614
  const data = await requestTelegram({
2597
2615
  method: "sendMessage",
package/dist/cli.mjs CHANGED
@@ -629,8 +629,9 @@ var parseTelegramResponse = async (response) => {
629
629
  }
630
630
  }
631
631
  };
632
- var getTelegramSettings = async (userName = "root") => {
632
+ var getTelegramSettings = async (userName = "root", notification) => {
633
633
  const settings = await getUserSettings(userName);
634
+ if (notification && settings[notification] === false) return null;
634
635
  const token = settings.TG_BOT_TOKEN;
635
636
  const chatId = settings.TG_CHAT_ID;
636
637
  if (!token || !chatId) {
@@ -695,7 +696,9 @@ var sendTelegramMessage = async ({
695
696
  return data;
696
697
  };
697
698
  var sendTextToTG = async (message, options = {}) => {
698
- const { token, chatId } = await getTelegramSettings(options.userName);
699
+ const telegram = await getTelegramSettings(options.userName);
700
+ if (!telegram) return;
701
+ const { token, chatId } = telegram;
699
702
  return sendTelegramMessage({
700
703
  message,
701
704
  markup: options.markup,
@@ -704,7 +707,12 @@ var sendTextToTG = async (message, options = {}) => {
704
707
  });
705
708
  };
706
709
  var sendDocumentToTG = async (document, options = {}) => {
707
- const { token, chatId } = await getTelegramSettings(options.userName);
710
+ const telegram = await getTelegramSettings(
711
+ options.userName,
712
+ "NOTIFY_RUNTIME_DEBUG"
713
+ );
714
+ if (!telegram) return;
715
+ const { token, chatId } = telegram;
708
716
  const body = new FormData();
709
717
  const fileContent = typeof document.content === "string" ? document.content : (() => {
710
718
  const bytes = new Uint8Array(document.content.byteLength);
@@ -837,7 +845,12 @@ var formatMessage = (signal, analysis, _options = {}) => {
837
845
  };
838
846
  var sendSignal = async (signal, imgInterval, analysis, options = {}) => {
839
847
  const { symbol, signalId, interval } = signal;
840
- const { token, chatId } = await getTelegramSettings(options.userName);
848
+ const telegram = await getTelegramSettings(
849
+ options.userName,
850
+ "NOTIFY_SIGNALS"
851
+ );
852
+ if (!telegram) return;
853
+ const { token, chatId } = telegram;
841
854
  const message = formatMessage(signal, analysis, {
842
855
  userName: options.userName
843
856
  });
@@ -1001,7 +1014,12 @@ var formatAnalysisMessage = (signal, analysis) => {
1001
1014
  return lines.join("\n");
1002
1015
  };
1003
1016
  var sendSignalAnalysis = async (signal, analysis, options = {}) => {
1004
- const { token, chatId } = await getTelegramSettings(options.userName);
1017
+ const telegram = await getTelegramSettings(
1018
+ options.userName,
1019
+ "NOTIFY_AI_ANALYSIS"
1020
+ );
1021
+ if (!telegram) return;
1022
+ const { token, chatId } = telegram;
1005
1023
  const message = formatAnalysisMessage(signal, analysis);
1006
1024
  const data = await requestTelegram({
1007
1025
  method: "sendMessage",
package/dist/mcp.d.mts CHANGED
@@ -7,6 +7,18 @@ declare const mcpJobDirectory: (job: Pick<McpJob, "userName" | "id">) => string;
7
7
  declare const mcpPackageManifestHash: () => Promise<string>;
8
8
  declare const enqueueMcpJob: (principal: McpPrincipal, kind: McpJob["kind"], request: Record<string, unknown>, idempotencyKey: string) => Promise<McpJob>;
9
9
  declare const readMcpJob: (userName: string, id: string) => Promise<McpJob>;
10
+ declare const readAuthorizedMcpJob: (principal: McpPrincipal, id: string) => Promise<McpJob>;
11
+ /** Offsets refer to the retained worker tail, which may shift while running. */
12
+ declare const readMcpJobLogs: (principal: McpPrincipal, id: string, offset?: number, limit?: number) => Promise<{
13
+ jobId: string;
14
+ status: "running" | "completed" | "failed" | "queued" | "cancelled";
15
+ updatedAt: number;
16
+ offset: number;
17
+ nextOffset: number | null;
18
+ retainedLines: number;
19
+ retention: string;
20
+ lines: string[];
21
+ }>;
10
22
  declare const cancelMcpJob: (principal: McpPrincipal, id: string) => Promise<McpJob>;
11
23
  declare const publicMcpJob: (job: McpJob) => {
12
24
  request: {
@@ -200,4 +212,4 @@ declare const readMcpBacktestResult: (userName: string, id: string, offset?: num
200
212
  source: string;
201
213
  }>;
202
214
 
203
- export { MCP_JOB_TTL, cancelMcpJob, enqueueMcpJob, isMcpRecord, mcpId, mcpJobDirectory, mcpJobStorageId, mcpPackageManifestHash, mcpProjectRoot, publicMcpJob, readMcpBacktestPage, readMcpBacktestResult, readMcpChart, readMcpDeployments, readMcpEvaluationStats, readMcpJob, readMcpMarket, readMcpRuntimePage, readMcpSignal, readMcpStrategies, redactMcpData, requireMcpDeployment };
215
+ export { MCP_JOB_TTL, cancelMcpJob, enqueueMcpJob, isMcpRecord, mcpId, mcpJobDirectory, mcpJobStorageId, mcpPackageManifestHash, mcpProjectRoot, publicMcpJob, readAuthorizedMcpJob, readMcpBacktestPage, readMcpBacktestResult, readMcpChart, readMcpDeployments, readMcpEvaluationStats, readMcpJob, readMcpJobLogs, readMcpMarket, readMcpRuntimePage, readMcpSignal, readMcpStrategies, redactMcpData, requireMcpDeployment };
package/dist/mcp.d.ts CHANGED
@@ -7,6 +7,18 @@ declare const mcpJobDirectory: (job: Pick<McpJob, "userName" | "id">) => string;
7
7
  declare const mcpPackageManifestHash: () => Promise<string>;
8
8
  declare const enqueueMcpJob: (principal: McpPrincipal, kind: McpJob["kind"], request: Record<string, unknown>, idempotencyKey: string) => Promise<McpJob>;
9
9
  declare const readMcpJob: (userName: string, id: string) => Promise<McpJob>;
10
+ declare const readAuthorizedMcpJob: (principal: McpPrincipal, id: string) => Promise<McpJob>;
11
+ /** Offsets refer to the retained worker tail, which may shift while running. */
12
+ declare const readMcpJobLogs: (principal: McpPrincipal, id: string, offset?: number, limit?: number) => Promise<{
13
+ jobId: string;
14
+ status: "running" | "completed" | "failed" | "queued" | "cancelled";
15
+ updatedAt: number;
16
+ offset: number;
17
+ nextOffset: number | null;
18
+ retainedLines: number;
19
+ retention: string;
20
+ lines: string[];
21
+ }>;
10
22
  declare const cancelMcpJob: (principal: McpPrincipal, id: string) => Promise<McpJob>;
11
23
  declare const publicMcpJob: (job: McpJob) => {
12
24
  request: {
@@ -200,4 +212,4 @@ declare const readMcpBacktestResult: (userName: string, id: string, offset?: num
200
212
  source: string;
201
213
  }>;
202
214
 
203
- export { MCP_JOB_TTL, cancelMcpJob, enqueueMcpJob, isMcpRecord, mcpId, mcpJobDirectory, mcpJobStorageId, mcpPackageManifestHash, mcpProjectRoot, publicMcpJob, readMcpBacktestPage, readMcpBacktestResult, readMcpChart, readMcpDeployments, readMcpEvaluationStats, readMcpJob, readMcpMarket, readMcpRuntimePage, readMcpSignal, readMcpStrategies, redactMcpData, requireMcpDeployment };
215
+ export { MCP_JOB_TTL, cancelMcpJob, enqueueMcpJob, isMcpRecord, mcpId, mcpJobDirectory, mcpJobStorageId, mcpPackageManifestHash, mcpProjectRoot, publicMcpJob, readAuthorizedMcpJob, readMcpBacktestPage, readMcpBacktestResult, readMcpChart, readMcpDeployments, readMcpEvaluationStats, readMcpJob, readMcpJobLogs, readMcpMarket, readMcpRuntimePage, readMcpSignal, readMcpStrategies, redactMcpData, requireMcpDeployment };
package/dist/mcp.js CHANGED
@@ -787,12 +787,14 @@ __export(mcp_exports, {
787
787
  mcpPackageManifestHash: () => mcpPackageManifestHash,
788
788
  mcpProjectRoot: () => mcpProjectRoot,
789
789
  publicMcpJob: () => publicMcpJob,
790
+ readAuthorizedMcpJob: () => readAuthorizedMcpJob,
790
791
  readMcpBacktestPage: () => readMcpBacktestPage,
791
792
  readMcpBacktestResult: () => readMcpBacktestResult,
792
793
  readMcpChart: () => readMcpChart,
793
794
  readMcpDeployments: () => readMcpDeployments,
794
795
  readMcpEvaluationStats: () => readMcpEvaluationStats,
795
796
  readMcpJob: () => readMcpJob,
797
+ readMcpJobLogs: () => readMcpJobLogs,
796
798
  readMcpMarket: () => readMcpMarket,
797
799
  readMcpRuntimePage: () => readMcpRuntimePage,
798
800
  readMcpSignal: () => readMcpSignal,
@@ -8863,6 +8865,44 @@ var readMcpJob = async (userName, id) => {
8863
8865
  if (!job || job.userName !== userName) throw new Error("Job not found");
8864
8866
  return job;
8865
8867
  };
8868
+ var readAuthorizedMcpJob = async (principal, id) => {
8869
+ const job = await readMcpJob(principal.userName, id);
8870
+ const prefix = job.kind === "backtest" ? "backtests" : "diagnostics";
8871
+ if (!principal.scopes.some(
8872
+ (scope) => scope === `${prefix}:read` || scope === `${prefix}:run`
8873
+ ))
8874
+ throw new Error("Insufficient scope");
8875
+ return job;
8876
+ };
8877
+ var redactJobLog = (line) => line.replace(/\u001b\[[0-9;]*m/g, "").replace(/\b(Bearer|Basic)\s+\S+/gi, "$1 [redacted]").replace(/([a-z][a-z0-9+.-]*:\/\/)[^\s/@]*:[^\s/@]+@/gi, "$1[redacted]@").replace(/((?:authorization|cookie)\s*:\s*)[^\r\n]+/gi, "$1[redacted]").replace(
8878
+ /((?:[\w.-]*(?:secret|password|token|api[_-]?key|private[_-]?key|authorization|cookie|credential)[\w.-]*)["']?\s*[:=]\s*)(?:"[^"\r\n]*"|'[^'\r\n]*'|[^\s,;&}]+)/gi,
8879
+ "$1[redacted]"
8880
+ ).slice(0, 1e3);
8881
+ var readMcpJobLogs = async (principal, id, offset = 0, limit = 50) => {
8882
+ if (!Number.isSafeInteger(offset) || offset < 0 || !Number.isSafeInteger(limit) || limit < 1 || limit > 100)
8883
+ throw new Error("Select a non-negative log offset and a limit of 1\u2013100");
8884
+ const job = await readAuthorizedMcpJob(principal, id);
8885
+ const lines = [];
8886
+ let bytes = 0;
8887
+ for (const line of job.logs.slice(offset, offset + limit)) {
8888
+ const redacted = redactJobLog(line);
8889
+ const size = Buffer.byteLength(JSON.stringify(redacted)) + 1;
8890
+ if (bytes + size > 48e3) break;
8891
+ lines.push(redacted);
8892
+ bytes += size;
8893
+ }
8894
+ const next = offset + lines.length;
8895
+ return {
8896
+ jobId: job.id,
8897
+ status: job.status,
8898
+ updatedAt: job.updatedAt,
8899
+ offset,
8900
+ nextOffset: next < job.logs.length ? next : null,
8901
+ retainedLines: job.logs.length,
8902
+ retention: "worker_tail",
8903
+ lines
8904
+ };
8905
+ };
8866
8906
  var cancelMcpJob = async (principal, id) => {
8867
8907
  for (let attempt = 0; attempt < 4; attempt++) {
8868
8908
  const job = await readMcpJob(principal.userName, id);
@@ -9242,12 +9282,14 @@ var readMcpBacktestResult = async (userName, id, offset = 0, limit = 20) => {
9242
9282
  mcpPackageManifestHash,
9243
9283
  mcpProjectRoot,
9244
9284
  publicMcpJob,
9285
+ readAuthorizedMcpJob,
9245
9286
  readMcpBacktestPage,
9246
9287
  readMcpBacktestResult,
9247
9288
  readMcpChart,
9248
9289
  readMcpDeployments,
9249
9290
  readMcpEvaluationStats,
9250
9291
  readMcpJob,
9292
+ readMcpJobLogs,
9251
9293
  readMcpMarket,
9252
9294
  readMcpRuntimePage,
9253
9295
  readMcpSignal,
package/dist/mcp.mjs CHANGED
@@ -191,6 +191,44 @@ var readMcpJob = async (userName, id) => {
191
191
  if (!job || job.userName !== userName) throw new Error("Job not found");
192
192
  return job;
193
193
  };
194
+ var readAuthorizedMcpJob = async (principal, id) => {
195
+ const job = await readMcpJob(principal.userName, id);
196
+ const prefix = job.kind === "backtest" ? "backtests" : "diagnostics";
197
+ if (!principal.scopes.some(
198
+ (scope) => scope === `${prefix}:read` || scope === `${prefix}:run`
199
+ ))
200
+ throw new Error("Insufficient scope");
201
+ return job;
202
+ };
203
+ var redactJobLog = (line) => line.replace(/\u001b\[[0-9;]*m/g, "").replace(/\b(Bearer|Basic)\s+\S+/gi, "$1 [redacted]").replace(/([a-z][a-z0-9+.-]*:\/\/)[^\s/@]*:[^\s/@]+@/gi, "$1[redacted]@").replace(/((?:authorization|cookie)\s*:\s*)[^\r\n]+/gi, "$1[redacted]").replace(
204
+ /((?:[\w.-]*(?:secret|password|token|api[_-]?key|private[_-]?key|authorization|cookie|credential)[\w.-]*)["']?\s*[:=]\s*)(?:"[^"\r\n]*"|'[^'\r\n]*'|[^\s,;&}]+)/gi,
205
+ "$1[redacted]"
206
+ ).slice(0, 1e3);
207
+ var readMcpJobLogs = async (principal, id, offset = 0, limit = 50) => {
208
+ if (!Number.isSafeInteger(offset) || offset < 0 || !Number.isSafeInteger(limit) || limit < 1 || limit > 100)
209
+ throw new Error("Select a non-negative log offset and a limit of 1\u2013100");
210
+ const job = await readAuthorizedMcpJob(principal, id);
211
+ const lines = [];
212
+ let bytes = 0;
213
+ for (const line of job.logs.slice(offset, offset + limit)) {
214
+ const redacted = redactJobLog(line);
215
+ const size = Buffer.byteLength(JSON.stringify(redacted)) + 1;
216
+ if (bytes + size > 48e3) break;
217
+ lines.push(redacted);
218
+ bytes += size;
219
+ }
220
+ const next = offset + lines.length;
221
+ return {
222
+ jobId: job.id,
223
+ status: job.status,
224
+ updatedAt: job.updatedAt,
225
+ offset,
226
+ nextOffset: next < job.logs.length ? next : null,
227
+ retainedLines: job.logs.length,
228
+ retention: "worker_tail",
229
+ lines
230
+ };
231
+ };
194
232
  var cancelMcpJob = async (principal, id) => {
195
233
  for (let attempt = 0; attempt < 4; attempt++) {
196
234
  const job = await readMcpJob(principal.userName, id);
@@ -569,12 +607,14 @@ export {
569
607
  mcpPackageManifestHash,
570
608
  mcpProjectRoot,
571
609
  publicMcpJob,
610
+ readAuthorizedMcpJob,
572
611
  readMcpBacktestPage,
573
612
  readMcpBacktestResult,
574
613
  readMcpChart,
575
614
  readMcpDeployments,
576
615
  readMcpEvaluationStats,
577
616
  readMcpJob,
617
+ readMcpJobLogs,
578
618
  readMcpMarket,
579
619
  readMcpRuntimePage,
580
620
  readMcpSignal,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tradejs/node",
3
- "version": "3.1.29-beta.269",
3
+ "version": "3.1.29-beta.271",
4
4
  "description": "Node-only runtime for the TradeJS TypeScript framework: strategies, backtests, Pine strategy loading, and plugin registries.",
5
5
  "keywords": [
6
6
  "tradejs",
@@ -105,9 +105,9 @@
105
105
  "dependencies": {
106
106
  "@langchain/core": "^1.2.3",
107
107
  "@langchain/openai": "^1.5.5",
108
- "@tradejs/core": "^3.1.29-beta.269",
109
- "@tradejs/infra": "^3.1.29-beta.269",
110
- "@tradejs/types": "^3.1.29-beta.269",
108
+ "@tradejs/core": "^3.1.29-beta.271",
109
+ "@tradejs/infra": "^3.1.29-beta.271",
110
+ "@tradejs/types": "^3.1.29-beta.271",
111
111
  "@types/node": "^24",
112
112
  "chalk": "4.1.2",
113
113
  "ioredis": "5.11.1",
@@ -120,7 +120,7 @@
120
120
  "typescript": "^5.9"
121
121
  },
122
122
  "devDependencies": {
123
- "@tradejs/indicators": "^3.1.29-beta.269",
123
+ "@tradejs/indicators": "^3.1.29-beta.271",
124
124
  "@tradejs/strategy-adaptive-momentum-ribbon": "3.0.5",
125
125
  "@tradejs/strategy-hyperliquid-consensus": "3.0.5",
126
126
  "@tradejs/strategy-kit": "3.0.6",