@tradejs/cli 2.0.18 → 2.0.20

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 (56) hide show
  1. package/dist/cli.js +14522 -15704
  2. package/dist/lib/aiExport.js +15 -1608
  3. package/dist/lib/aiPocketSearch.js +499 -67
  4. package/dist/lib/aiPocketSearchCli.js +113 -0
  5. package/dist/lib/aiTrainCharts.js +14 -1
  6. package/dist/lib/aiTrainMetrics.js +4 -1
  7. package/dist/lib/aiTrainResearch.js +88 -54
  8. package/dist/lib/binanceMarketContextBackfill.js +7 -6
  9. package/dist/lib/coinMarketCapContextBackfill.js +19 -18
  10. package/dist/lib/coreResearch.js +2738 -0
  11. package/dist/lib/derivativesContextBackfill.js +10 -9
  12. package/dist/lib/executionCalibration.js +6 -3
  13. package/dist/lib/hyperliquidWhaleBackfill.js +8 -8
  14. package/dist/lib/hyperliquidWhaleStream.js +4 -4
  15. package/dist/lib/marketContextPrepare.js +83 -1686
  16. package/dist/lib/runEnvironment.js +14 -1666
  17. package/dist/lib/runFormatting.js +1 -1607
  18. package/dist/lib/runtimeDebugEvidence.js +2 -48
  19. package/dist/lib/runtimeLineage.js +81 -48
  20. package/dist/lib/runtimeRedis.js +6 -57
  21. package/dist/lib/runtimeScorecard.js +153 -10
  22. package/dist/lib/runtimeStrategyBacktest.js +2 -48
  23. package/dist/lib/strategyGateFingerprint.js +80 -0
  24. package/dist/lib/strategyRelease.js +1365 -0
  25. package/dist/scripts/aiExport.js +17 -1610
  26. package/dist/scripts/aiPocketSearch.js +1070 -1770
  27. package/dist/scripts/aiTrain.js +108 -1688
  28. package/dist/scripts/backtest.js +120 -1760
  29. package/dist/scripts/binanceMarketIngest.js +5 -4
  30. package/dist/scripts/candlesMigrateProvider.js +6 -5186
  31. package/dist/scripts/cleanupMarketContext.js +4 -3
  32. package/dist/scripts/continuity.js +4 -3
  33. package/dist/scripts/coreResearch.js +2830 -0
  34. package/dist/scripts/derivativesIngest.js +6 -4
  35. package/dist/scripts/derivativesIngestCoinalyzeAll.js +5 -4
  36. package/dist/scripts/doctor.js +2 -5184
  37. package/dist/scripts/executionCalibration.js +6 -3
  38. package/dist/scripts/hyperliquidWhaleBackfill.js +8 -8
  39. package/dist/scripts/hyperliquidWhaleIngest.js +4 -4
  40. package/dist/scripts/hyperliquidWhalesUpdate.js +1 -1
  41. package/dist/scripts/migration.js +3 -3
  42. package/dist/scripts/mlExport.js +1 -1607
  43. package/dist/scripts/replay.js +239 -1855
  44. package/dist/scripts/replayRunner.js +239 -1855
  45. package/dist/scripts/replayRuntimeEvidence.js +29 -62
  46. package/dist/scripts/researchAuto.js +3 -49
  47. package/dist/scripts/results.js +1 -1607
  48. package/dist/scripts/runtimeEvidence.js +18 -56
  49. package/dist/scripts/runtimeParity.js +121 -1746
  50. package/dist/scripts/runtimeScorecard.js +883 -29
  51. package/dist/scripts/signals.js +1178 -2724
  52. package/dist/scripts/signalsDaemon.js +1183 -2696
  53. package/dist/scripts/signalsSummary.js +4 -26
  54. package/dist/scripts/strategyRelease.js +1469 -0
  55. package/dist/workers/testerWorker.js +2 -2
  56. package/package.json +13 -9
@@ -5,13 +5,6 @@ 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 __commonJS = (cb, mod) => function __require() {
9
- try {
10
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
11
- } catch (e) {
12
- throw mod = 0, e;
13
- }
14
- };
15
8
  var __export = (target, all) => {
16
9
  for (var name in all)
17
10
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -34,1605 +27,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
34
27
  ));
35
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
36
29
 
37
- // ../../node_modules/ms/index.js
38
- var require_ms = __commonJS({
39
- "../../node_modules/ms/index.js"(exports2, module2) {
40
- "use strict";
41
- var s = 1e3;
42
- var m = s * 60;
43
- var h = m * 60;
44
- var d = h * 24;
45
- var w = d * 7;
46
- var y = d * 365.25;
47
- module2.exports = function(val, options) {
48
- options = options || {};
49
- var type = typeof val;
50
- if (type === "string" && val.length > 0) {
51
- return parse(val);
52
- } else if (type === "number" && isFinite(val)) {
53
- return options.long ? fmtLong(val) : fmtShort(val);
54
- }
55
- throw new Error(
56
- "val is not a non-empty string or a valid number. val=" + JSON.stringify(val)
57
- );
58
- };
59
- function parse(str) {
60
- str = String(str);
61
- if (str.length > 100) {
62
- return;
63
- }
64
- var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
65
- str
66
- );
67
- if (!match) {
68
- return;
69
- }
70
- var n = parseFloat(match[1]);
71
- var type = (match[2] || "ms").toLowerCase();
72
- switch (type) {
73
- case "years":
74
- case "year":
75
- case "yrs":
76
- case "yr":
77
- case "y":
78
- return n * y;
79
- case "weeks":
80
- case "week":
81
- case "w":
82
- return n * w;
83
- case "days":
84
- case "day":
85
- case "d":
86
- return n * d;
87
- case "hours":
88
- case "hour":
89
- case "hrs":
90
- case "hr":
91
- case "h":
92
- return n * h;
93
- case "minutes":
94
- case "minute":
95
- case "mins":
96
- case "min":
97
- case "m":
98
- return n * m;
99
- case "seconds":
100
- case "second":
101
- case "secs":
102
- case "sec":
103
- case "s":
104
- return n * s;
105
- case "milliseconds":
106
- case "millisecond":
107
- case "msecs":
108
- case "msec":
109
- case "ms":
110
- return n;
111
- default:
112
- return void 0;
113
- }
114
- }
115
- function fmtShort(ms) {
116
- var msAbs = Math.abs(ms);
117
- if (msAbs >= d) {
118
- return Math.round(ms / d) + "d";
119
- }
120
- if (msAbs >= h) {
121
- return Math.round(ms / h) + "h";
122
- }
123
- if (msAbs >= m) {
124
- return Math.round(ms / m) + "m";
125
- }
126
- if (msAbs >= s) {
127
- return Math.round(ms / s) + "s";
128
- }
129
- return ms + "ms";
130
- }
131
- function fmtLong(ms) {
132
- var msAbs = Math.abs(ms);
133
- if (msAbs >= d) {
134
- return plural(ms, msAbs, d, "day");
135
- }
136
- if (msAbs >= h) {
137
- return plural(ms, msAbs, h, "hour");
138
- }
139
- if (msAbs >= m) {
140
- return plural(ms, msAbs, m, "minute");
141
- }
142
- if (msAbs >= s) {
143
- return plural(ms, msAbs, s, "second");
144
- }
145
- return ms + " ms";
146
- }
147
- function plural(ms, msAbs, n, name) {
148
- var isPlural = msAbs >= n * 1.5;
149
- return Math.round(ms / n) + " " + name + (isPlural ? "s" : "");
150
- }
151
- }
152
- });
153
-
154
- // ../../node_modules/list-it/node_modules/debug/src/common.js
155
- var require_common = __commonJS({
156
- "../../node_modules/list-it/node_modules/debug/src/common.js"(exports2, module2) {
157
- "use strict";
158
- function setup(env) {
159
- createDebug.debug = createDebug;
160
- createDebug.default = createDebug;
161
- createDebug.coerce = coerce;
162
- createDebug.disable = disable;
163
- createDebug.enable = enable;
164
- createDebug.enabled = enabled;
165
- createDebug.humanize = require_ms();
166
- createDebug.destroy = destroy;
167
- Object.keys(env).forEach((key) => {
168
- createDebug[key] = env[key];
169
- });
170
- createDebug.names = [];
171
- createDebug.skips = [];
172
- createDebug.formatters = {};
173
- function selectColor(namespace) {
174
- let hash = 0;
175
- for (let i = 0; i < namespace.length; i++) {
176
- hash = (hash << 5) - hash + namespace.charCodeAt(i);
177
- hash |= 0;
178
- }
179
- return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
180
- }
181
- createDebug.selectColor = selectColor;
182
- function createDebug(namespace) {
183
- let prevTime;
184
- let enableOverride = null;
185
- let namespacesCache;
186
- let enabledCache;
187
- function debug(...args2) {
188
- if (!debug.enabled) {
189
- return;
190
- }
191
- const self = debug;
192
- const curr = Number(/* @__PURE__ */ new Date());
193
- const ms = curr - (prevTime || curr);
194
- self.diff = ms;
195
- self.prev = prevTime;
196
- self.curr = curr;
197
- prevTime = curr;
198
- args2[0] = createDebug.coerce(args2[0]);
199
- if (typeof args2[0] !== "string") {
200
- args2.unshift("%O");
201
- }
202
- let index = 0;
203
- args2[0] = args2[0].replace(/%([a-zA-Z%])/g, (match, format) => {
204
- if (match === "%%") {
205
- return "%";
206
- }
207
- index++;
208
- const formatter = createDebug.formatters[format];
209
- if (typeof formatter === "function") {
210
- const val = args2[index];
211
- match = formatter.call(self, val);
212
- args2.splice(index, 1);
213
- index--;
214
- }
215
- return match;
216
- });
217
- createDebug.formatArgs.call(self, args2);
218
- const logFn = self.log || createDebug.log;
219
- logFn.apply(self, args2);
220
- }
221
- debug.namespace = namespace;
222
- debug.useColors = createDebug.useColors();
223
- debug.color = createDebug.selectColor(namespace);
224
- debug.extend = extend;
225
- debug.destroy = createDebug.destroy;
226
- Object.defineProperty(debug, "enabled", {
227
- enumerable: true,
228
- configurable: false,
229
- get: () => {
230
- if (enableOverride !== null) {
231
- return enableOverride;
232
- }
233
- if (namespacesCache !== createDebug.namespaces) {
234
- namespacesCache = createDebug.namespaces;
235
- enabledCache = createDebug.enabled(namespace);
236
- }
237
- return enabledCache;
238
- },
239
- set: (v) => {
240
- enableOverride = v;
241
- }
242
- });
243
- if (typeof createDebug.init === "function") {
244
- createDebug.init(debug);
245
- }
246
- return debug;
247
- }
248
- function extend(namespace, delimiter) {
249
- const newDebug = createDebug(this.namespace + (typeof delimiter === "undefined" ? ":" : delimiter) + namespace);
250
- newDebug.log = this.log;
251
- return newDebug;
252
- }
253
- function enable(namespaces) {
254
- createDebug.save(namespaces);
255
- createDebug.namespaces = namespaces;
256
- createDebug.names = [];
257
- createDebug.skips = [];
258
- const split = (typeof namespaces === "string" ? namespaces : "").trim().replace(/\s+/g, ",").split(",").filter(Boolean);
259
- for (const ns of split) {
260
- if (ns[0] === "-") {
261
- createDebug.skips.push(ns.slice(1));
262
- } else {
263
- createDebug.names.push(ns);
264
- }
265
- }
266
- }
267
- function matchesTemplate(search, template) {
268
- let searchIndex = 0;
269
- let templateIndex = 0;
270
- let starIndex = -1;
271
- let matchIndex = 0;
272
- while (searchIndex < search.length) {
273
- if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === "*")) {
274
- if (template[templateIndex] === "*") {
275
- starIndex = templateIndex;
276
- matchIndex = searchIndex;
277
- templateIndex++;
278
- } else {
279
- searchIndex++;
280
- templateIndex++;
281
- }
282
- } else if (starIndex !== -1) {
283
- templateIndex = starIndex + 1;
284
- matchIndex++;
285
- searchIndex = matchIndex;
286
- } else {
287
- return false;
288
- }
289
- }
290
- while (templateIndex < template.length && template[templateIndex] === "*") {
291
- templateIndex++;
292
- }
293
- return templateIndex === template.length;
294
- }
295
- function disable() {
296
- const namespaces = [
297
- ...createDebug.names,
298
- ...createDebug.skips.map((namespace) => "-" + namespace)
299
- ].join(",");
300
- createDebug.enable("");
301
- return namespaces;
302
- }
303
- function enabled(name) {
304
- for (const skip of createDebug.skips) {
305
- if (matchesTemplate(name, skip)) {
306
- return false;
307
- }
308
- }
309
- for (const ns of createDebug.names) {
310
- if (matchesTemplate(name, ns)) {
311
- return true;
312
- }
313
- }
314
- return false;
315
- }
316
- function coerce(val) {
317
- if (val instanceof Error) {
318
- return val.stack || val.message;
319
- }
320
- return val;
321
- }
322
- function destroy() {
323
- console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.");
324
- }
325
- createDebug.enable(createDebug.load());
326
- return createDebug;
327
- }
328
- module2.exports = setup;
329
- }
330
- });
331
-
332
- // ../../node_modules/list-it/node_modules/debug/src/browser.js
333
- var require_browser = __commonJS({
334
- "../../node_modules/list-it/node_modules/debug/src/browser.js"(exports2, module2) {
335
- "use strict";
336
- exports2.formatArgs = formatArgs;
337
- exports2.save = save;
338
- exports2.load = load;
339
- exports2.useColors = useColors;
340
- exports2.storage = localstorage();
341
- exports2.destroy = /* @__PURE__ */ (() => {
342
- let warned = false;
343
- return () => {
344
- if (!warned) {
345
- warned = true;
346
- console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.");
347
- }
348
- };
349
- })();
350
- exports2.colors = [
351
- "#0000CC",
352
- "#0000FF",
353
- "#0033CC",
354
- "#0033FF",
355
- "#0066CC",
356
- "#0066FF",
357
- "#0099CC",
358
- "#0099FF",
359
- "#00CC00",
360
- "#00CC33",
361
- "#00CC66",
362
- "#00CC99",
363
- "#00CCCC",
364
- "#00CCFF",
365
- "#3300CC",
366
- "#3300FF",
367
- "#3333CC",
368
- "#3333FF",
369
- "#3366CC",
370
- "#3366FF",
371
- "#3399CC",
372
- "#3399FF",
373
- "#33CC00",
374
- "#33CC33",
375
- "#33CC66",
376
- "#33CC99",
377
- "#33CCCC",
378
- "#33CCFF",
379
- "#6600CC",
380
- "#6600FF",
381
- "#6633CC",
382
- "#6633FF",
383
- "#66CC00",
384
- "#66CC33",
385
- "#9900CC",
386
- "#9900FF",
387
- "#9933CC",
388
- "#9933FF",
389
- "#99CC00",
390
- "#99CC33",
391
- "#CC0000",
392
- "#CC0033",
393
- "#CC0066",
394
- "#CC0099",
395
- "#CC00CC",
396
- "#CC00FF",
397
- "#CC3300",
398
- "#CC3333",
399
- "#CC3366",
400
- "#CC3399",
401
- "#CC33CC",
402
- "#CC33FF",
403
- "#CC6600",
404
- "#CC6633",
405
- "#CC9900",
406
- "#CC9933",
407
- "#CCCC00",
408
- "#CCCC33",
409
- "#FF0000",
410
- "#FF0033",
411
- "#FF0066",
412
- "#FF0099",
413
- "#FF00CC",
414
- "#FF00FF",
415
- "#FF3300",
416
- "#FF3333",
417
- "#FF3366",
418
- "#FF3399",
419
- "#FF33CC",
420
- "#FF33FF",
421
- "#FF6600",
422
- "#FF6633",
423
- "#FF9900",
424
- "#FF9933",
425
- "#FFCC00",
426
- "#FFCC33"
427
- ];
428
- function useColors() {
429
- if (typeof window !== "undefined" && window.process && (window.process.type === "renderer" || window.process.__nwjs)) {
430
- return true;
431
- }
432
- if (typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
433
- return false;
434
- }
435
- let m;
436
- return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773
437
- typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31?
438
- // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
439
- typeof navigator !== "undefined" && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker
440
- typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/);
441
- }
442
- function formatArgs(args2) {
443
- args2[0] = (this.useColors ? "%c" : "") + this.namespace + (this.useColors ? " %c" : " ") + args2[0] + (this.useColors ? "%c " : " ") + "+" + module2.exports.humanize(this.diff);
444
- if (!this.useColors) {
445
- return;
446
- }
447
- const c = "color: " + this.color;
448
- args2.splice(1, 0, c, "color: inherit");
449
- let index = 0;
450
- let lastC = 0;
451
- args2[0].replace(/%[a-zA-Z%]/g, (match) => {
452
- if (match === "%%") {
453
- return;
454
- }
455
- index++;
456
- if (match === "%c") {
457
- lastC = index;
458
- }
459
- });
460
- args2.splice(lastC, 0, c);
461
- }
462
- exports2.log = console.debug || console.log || (() => {
463
- });
464
- function save(namespaces) {
465
- try {
466
- if (namespaces) {
467
- exports2.storage.setItem("debug", namespaces);
468
- } else {
469
- exports2.storage.removeItem("debug");
470
- }
471
- } catch (error) {
472
- }
473
- }
474
- function load() {
475
- let r;
476
- try {
477
- r = exports2.storage.getItem("debug") || exports2.storage.getItem("DEBUG");
478
- } catch (error) {
479
- }
480
- if (!r && typeof process !== "undefined" && "env" in process) {
481
- r = process.env.DEBUG;
482
- }
483
- return r;
484
- }
485
- function localstorage() {
486
- try {
487
- return localStorage;
488
- } catch (error) {
489
- }
490
- }
491
- module2.exports = require_common()(exports2);
492
- var { formatters } = module2.exports;
493
- formatters.j = function(v) {
494
- try {
495
- return JSON.stringify(v);
496
- } catch (error) {
497
- return "[UnexpectedJSONParseError]: " + error.message;
498
- }
499
- };
500
- }
501
- });
502
-
503
- // ../../node_modules/has-flag/index.js
504
- var require_has_flag = __commonJS({
505
- "../../node_modules/has-flag/index.js"(exports2, module2) {
506
- "use strict";
507
- module2.exports = (flag, argv = process.argv) => {
508
- const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
509
- const position = argv.indexOf(prefix + flag);
510
- const terminatorPosition = argv.indexOf("--");
511
- return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
512
- };
513
- }
514
- });
515
-
516
- // ../../node_modules/supports-color/index.js
517
- var require_supports_color = __commonJS({
518
- "../../node_modules/supports-color/index.js"(exports2, module2) {
519
- "use strict";
520
- var os = require("os");
521
- var tty = require("tty");
522
- var hasFlag = require_has_flag();
523
- var { env } = process;
524
- var forceColor;
525
- if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
526
- forceColor = 0;
527
- } else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
528
- forceColor = 1;
529
- }
530
- if ("FORCE_COLOR" in env) {
531
- if (env.FORCE_COLOR === "true") {
532
- forceColor = 1;
533
- } else if (env.FORCE_COLOR === "false") {
534
- forceColor = 0;
535
- } else {
536
- forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3);
537
- }
538
- }
539
- function translateLevel(level) {
540
- if (level === 0) {
541
- return false;
542
- }
543
- return {
544
- level,
545
- hasBasic: true,
546
- has256: level >= 2,
547
- has16m: level >= 3
548
- };
549
- }
550
- function supportsColor(haveStream, streamIsTTY) {
551
- if (forceColor === 0) {
552
- return 0;
553
- }
554
- if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
555
- return 3;
556
- }
557
- if (hasFlag("color=256")) {
558
- return 2;
559
- }
560
- if (haveStream && !streamIsTTY && forceColor === void 0) {
561
- return 0;
562
- }
563
- const min = forceColor || 0;
564
- if (env.TERM === "dumb") {
565
- return min;
566
- }
567
- if (process.platform === "win32") {
568
- const osRelease = os.release().split(".");
569
- if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
570
- return Number(osRelease[2]) >= 14931 ? 3 : 2;
571
- }
572
- return 1;
573
- }
574
- if ("CI" in env) {
575
- if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "GITHUB_ACTIONS", "BUILDKITE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
576
- return 1;
577
- }
578
- return min;
579
- }
580
- if ("TEAMCITY_VERSION" in env) {
581
- return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
582
- }
583
- if (env.COLORTERM === "truecolor") {
584
- return 3;
585
- }
586
- if ("TERM_PROGRAM" in env) {
587
- const version = parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
588
- switch (env.TERM_PROGRAM) {
589
- case "iTerm.app":
590
- return version >= 3 ? 3 : 2;
591
- case "Apple_Terminal":
592
- return 2;
593
- }
594
- }
595
- if (/-256(color)?$/i.test(env.TERM)) {
596
- return 2;
597
- }
598
- if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
599
- return 1;
600
- }
601
- if ("COLORTERM" in env) {
602
- return 1;
603
- }
604
- return min;
605
- }
606
- function getSupportLevel(stream) {
607
- const level = supportsColor(stream, stream && stream.isTTY);
608
- return translateLevel(level);
609
- }
610
- module2.exports = {
611
- supportsColor: getSupportLevel,
612
- stdout: translateLevel(supportsColor(true, tty.isatty(1))),
613
- stderr: translateLevel(supportsColor(true, tty.isatty(2)))
614
- };
615
- }
616
- });
617
-
618
- // ../../node_modules/list-it/node_modules/debug/src/node.js
619
- var require_node = __commonJS({
620
- "../../node_modules/list-it/node_modules/debug/src/node.js"(exports2, module2) {
621
- "use strict";
622
- var tty = require("tty");
623
- var util = require("util");
624
- exports2.init = init;
625
- exports2.log = log;
626
- exports2.formatArgs = formatArgs;
627
- exports2.save = save;
628
- exports2.load = load;
629
- exports2.useColors = useColors;
630
- exports2.destroy = util.deprecate(
631
- () => {
632
- },
633
- "Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."
634
- );
635
- exports2.colors = [6, 2, 3, 4, 5, 1];
636
- try {
637
- const supportsColor = require_supports_color();
638
- if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {
639
- exports2.colors = [
640
- 20,
641
- 21,
642
- 26,
643
- 27,
644
- 32,
645
- 33,
646
- 38,
647
- 39,
648
- 40,
649
- 41,
650
- 42,
651
- 43,
652
- 44,
653
- 45,
654
- 56,
655
- 57,
656
- 62,
657
- 63,
658
- 68,
659
- 69,
660
- 74,
661
- 75,
662
- 76,
663
- 77,
664
- 78,
665
- 79,
666
- 80,
667
- 81,
668
- 92,
669
- 93,
670
- 98,
671
- 99,
672
- 112,
673
- 113,
674
- 128,
675
- 129,
676
- 134,
677
- 135,
678
- 148,
679
- 149,
680
- 160,
681
- 161,
682
- 162,
683
- 163,
684
- 164,
685
- 165,
686
- 166,
687
- 167,
688
- 168,
689
- 169,
690
- 170,
691
- 171,
692
- 172,
693
- 173,
694
- 178,
695
- 179,
696
- 184,
697
- 185,
698
- 196,
699
- 197,
700
- 198,
701
- 199,
702
- 200,
703
- 201,
704
- 202,
705
- 203,
706
- 204,
707
- 205,
708
- 206,
709
- 207,
710
- 208,
711
- 209,
712
- 214,
713
- 215,
714
- 220,
715
- 221
716
- ];
717
- }
718
- } catch (error) {
719
- }
720
- exports2.inspectOpts = Object.keys(process.env).filter((key) => {
721
- return /^debug_/i.test(key);
722
- }).reduce((obj, key) => {
723
- const prop = key.substring(6).toLowerCase().replace(/_([a-z])/g, (_, k) => {
724
- return k.toUpperCase();
725
- });
726
- let val = process.env[key];
727
- if (/^(yes|on|true|enabled)$/i.test(val)) {
728
- val = true;
729
- } else if (/^(no|off|false|disabled)$/i.test(val)) {
730
- val = false;
731
- } else if (val === "null") {
732
- val = null;
733
- } else {
734
- val = Number(val);
735
- }
736
- obj[prop] = val;
737
- return obj;
738
- }, {});
739
- function useColors() {
740
- return "colors" in exports2.inspectOpts ? Boolean(exports2.inspectOpts.colors) : tty.isatty(process.stderr.fd);
741
- }
742
- function formatArgs(args2) {
743
- const { namespace: name, useColors: useColors2 } = this;
744
- if (useColors2) {
745
- const c = this.color;
746
- const colorCode = "\x1B[3" + (c < 8 ? c : "8;5;" + c);
747
- const prefix = ` ${colorCode};1m${name} \x1B[0m`;
748
- args2[0] = prefix + args2[0].split("\n").join("\n" + prefix);
749
- args2.push(colorCode + "m+" + module2.exports.humanize(this.diff) + "\x1B[0m");
750
- } else {
751
- args2[0] = getDate() + name + " " + args2[0];
752
- }
753
- }
754
- function getDate() {
755
- if (exports2.inspectOpts.hideDate) {
756
- return "";
757
- }
758
- return (/* @__PURE__ */ new Date()).toISOString() + " ";
759
- }
760
- function log(...args2) {
761
- return process.stderr.write(util.formatWithOptions(exports2.inspectOpts, ...args2) + "\n");
762
- }
763
- function save(namespaces) {
764
- if (namespaces) {
765
- process.env.DEBUG = namespaces;
766
- } else {
767
- delete process.env.DEBUG;
768
- }
769
- }
770
- function load() {
771
- return process.env.DEBUG;
772
- }
773
- function init(debug) {
774
- debug.inspectOpts = {};
775
- const keys = Object.keys(exports2.inspectOpts);
776
- for (let i = 0; i < keys.length; i++) {
777
- debug.inspectOpts[keys[i]] = exports2.inspectOpts[keys[i]];
778
- }
779
- }
780
- module2.exports = require_common()(exports2);
781
- var { formatters } = module2.exports;
782
- formatters.o = function(v) {
783
- this.inspectOpts.colors = this.useColors;
784
- return util.inspect(v, this.inspectOpts).split("\n").map((str) => str.trim()).join(" ");
785
- };
786
- formatters.O = function(v) {
787
- this.inspectOpts.colors = this.useColors;
788
- return util.inspect(v, this.inspectOpts);
789
- };
790
- }
791
- });
792
-
793
- // ../../node_modules/list-it/node_modules/debug/src/index.js
794
- var require_src = __commonJS({
795
- "../../node_modules/list-it/node_modules/debug/src/index.js"(exports2, module2) {
796
- "use strict";
797
- if (typeof process === "undefined" || process.type === "renderer" || process.browser === true || process.__nwjs) {
798
- module2.exports = require_browser();
799
- } else {
800
- module2.exports = require_node();
801
- }
802
- }
803
- });
804
-
805
- // ../../node_modules/eastasianwidth/eastasianwidth.js
806
- var require_eastasianwidth = __commonJS({
807
- "../../node_modules/eastasianwidth/eastasianwidth.js"(exports2, module2) {
808
- "use strict";
809
- var eaw = {};
810
- if ("undefined" == typeof module2) {
811
- window.eastasianwidth = eaw;
812
- } else {
813
- module2.exports = eaw;
814
- }
815
- eaw.eastAsianWidth = function(character) {
816
- var x = character.charCodeAt(0);
817
- var y = character.length == 2 ? character.charCodeAt(1) : 0;
818
- var codePoint = x;
819
- if (55296 <= x && x <= 56319 && (56320 <= y && y <= 57343)) {
820
- x &= 1023;
821
- y &= 1023;
822
- codePoint = x << 10 | y;
823
- codePoint += 65536;
824
- }
825
- if (12288 == codePoint || 65281 <= codePoint && codePoint <= 65376 || 65504 <= codePoint && codePoint <= 65510) {
826
- return "F";
827
- }
828
- if (8361 == codePoint || 65377 <= codePoint && codePoint <= 65470 || 65474 <= codePoint && codePoint <= 65479 || 65482 <= codePoint && codePoint <= 65487 || 65490 <= codePoint && codePoint <= 65495 || 65498 <= codePoint && codePoint <= 65500 || 65512 <= codePoint && codePoint <= 65518) {
829
- return "H";
830
- }
831
- if (4352 <= codePoint && codePoint <= 4447 || 4515 <= codePoint && codePoint <= 4519 || 4602 <= codePoint && codePoint <= 4607 || 9001 <= codePoint && codePoint <= 9002 || 11904 <= codePoint && codePoint <= 11929 || 11931 <= codePoint && codePoint <= 12019 || 12032 <= codePoint && codePoint <= 12245 || 12272 <= codePoint && codePoint <= 12283 || 12289 <= codePoint && codePoint <= 12350 || 12353 <= codePoint && codePoint <= 12438 || 12441 <= codePoint && codePoint <= 12543 || 12549 <= codePoint && codePoint <= 12589 || 12593 <= codePoint && codePoint <= 12686 || 12688 <= codePoint && codePoint <= 12730 || 12736 <= codePoint && codePoint <= 12771 || 12784 <= codePoint && codePoint <= 12830 || 12832 <= codePoint && codePoint <= 12871 || 12880 <= codePoint && codePoint <= 13054 || 13056 <= codePoint && codePoint <= 19903 || 19968 <= codePoint && codePoint <= 42124 || 42128 <= codePoint && codePoint <= 42182 || 43360 <= codePoint && codePoint <= 43388 || 44032 <= codePoint && codePoint <= 55203 || 55216 <= codePoint && codePoint <= 55238 || 55243 <= codePoint && codePoint <= 55291 || 63744 <= codePoint && codePoint <= 64255 || 65040 <= codePoint && codePoint <= 65049 || 65072 <= codePoint && codePoint <= 65106 || 65108 <= codePoint && codePoint <= 65126 || 65128 <= codePoint && codePoint <= 65131 || 110592 <= codePoint && codePoint <= 110593 || 127488 <= codePoint && codePoint <= 127490 || 127504 <= codePoint && codePoint <= 127546 || 127552 <= codePoint && codePoint <= 127560 || 127568 <= codePoint && codePoint <= 127569 || 131072 <= codePoint && codePoint <= 194367 || 177984 <= codePoint && codePoint <= 196605 || 196608 <= codePoint && codePoint <= 262141) {
832
- return "W";
833
- }
834
- if (32 <= codePoint && codePoint <= 126 || 162 <= codePoint && codePoint <= 163 || 165 <= codePoint && codePoint <= 166 || 172 == codePoint || 175 == codePoint || 10214 <= codePoint && codePoint <= 10221 || 10629 <= codePoint && codePoint <= 10630) {
835
- return "Na";
836
- }
837
- if (161 == codePoint || 164 == codePoint || 167 <= codePoint && codePoint <= 168 || 170 == codePoint || 173 <= codePoint && codePoint <= 174 || 176 <= codePoint && codePoint <= 180 || 182 <= codePoint && codePoint <= 186 || 188 <= codePoint && codePoint <= 191 || 198 == codePoint || 208 == codePoint || 215 <= codePoint && codePoint <= 216 || 222 <= codePoint && codePoint <= 225 || 230 == codePoint || 232 <= codePoint && codePoint <= 234 || 236 <= codePoint && codePoint <= 237 || 240 == codePoint || 242 <= codePoint && codePoint <= 243 || 247 <= codePoint && codePoint <= 250 || 252 == codePoint || 254 == codePoint || 257 == codePoint || 273 == codePoint || 275 == codePoint || 283 == codePoint || 294 <= codePoint && codePoint <= 295 || 299 == codePoint || 305 <= codePoint && codePoint <= 307 || 312 == codePoint || 319 <= codePoint && codePoint <= 322 || 324 == codePoint || 328 <= codePoint && codePoint <= 331 || 333 == codePoint || 338 <= codePoint && codePoint <= 339 || 358 <= codePoint && codePoint <= 359 || 363 == codePoint || 462 == codePoint || 464 == codePoint || 466 == codePoint || 468 == codePoint || 470 == codePoint || 472 == codePoint || 474 == codePoint || 476 == codePoint || 593 == codePoint || 609 == codePoint || 708 == codePoint || 711 == codePoint || 713 <= codePoint && codePoint <= 715 || 717 == codePoint || 720 == codePoint || 728 <= codePoint && codePoint <= 731 || 733 == codePoint || 735 == codePoint || 768 <= codePoint && codePoint <= 879 || 913 <= codePoint && codePoint <= 929 || 931 <= codePoint && codePoint <= 937 || 945 <= codePoint && codePoint <= 961 || 963 <= codePoint && codePoint <= 969 || 1025 == codePoint || 1040 <= codePoint && codePoint <= 1103 || 1105 == codePoint || 8208 == codePoint || 8211 <= codePoint && codePoint <= 8214 || 8216 <= codePoint && codePoint <= 8217 || 8220 <= codePoint && codePoint <= 8221 || 8224 <= codePoint && codePoint <= 8226 || 8228 <= codePoint && codePoint <= 8231 || 8240 == codePoint || 8242 <= codePoint && codePoint <= 8243 || 8245 == codePoint || 8251 == codePoint || 8254 == codePoint || 8308 == codePoint || 8319 == codePoint || 8321 <= codePoint && codePoint <= 8324 || 8364 == codePoint || 8451 == codePoint || 8453 == codePoint || 8457 == codePoint || 8467 == codePoint || 8470 == codePoint || 8481 <= codePoint && codePoint <= 8482 || 8486 == codePoint || 8491 == codePoint || 8531 <= codePoint && codePoint <= 8532 || 8539 <= codePoint && codePoint <= 8542 || 8544 <= codePoint && codePoint <= 8555 || 8560 <= codePoint && codePoint <= 8569 || 8585 == codePoint || 8592 <= codePoint && codePoint <= 8601 || 8632 <= codePoint && codePoint <= 8633 || 8658 == codePoint || 8660 == codePoint || 8679 == codePoint || 8704 == codePoint || 8706 <= codePoint && codePoint <= 8707 || 8711 <= codePoint && codePoint <= 8712 || 8715 == codePoint || 8719 == codePoint || 8721 == codePoint || 8725 == codePoint || 8730 == codePoint || 8733 <= codePoint && codePoint <= 8736 || 8739 == codePoint || 8741 == codePoint || 8743 <= codePoint && codePoint <= 8748 || 8750 == codePoint || 8756 <= codePoint && codePoint <= 8759 || 8764 <= codePoint && codePoint <= 8765 || 8776 == codePoint || 8780 == codePoint || 8786 == codePoint || 8800 <= codePoint && codePoint <= 8801 || 8804 <= codePoint && codePoint <= 8807 || 8810 <= codePoint && codePoint <= 8811 || 8814 <= codePoint && codePoint <= 8815 || 8834 <= codePoint && codePoint <= 8835 || 8838 <= codePoint && codePoint <= 8839 || 8853 == codePoint || 8857 == codePoint || 8869 == codePoint || 8895 == codePoint || 8978 == codePoint || 9312 <= codePoint && codePoint <= 9449 || 9451 <= codePoint && codePoint <= 9547 || 9552 <= codePoint && codePoint <= 9587 || 9600 <= codePoint && codePoint <= 9615 || 9618 <= codePoint && codePoint <= 9621 || 9632 <= codePoint && codePoint <= 9633 || 9635 <= codePoint && codePoint <= 9641 || 9650 <= codePoint && codePoint <= 9651 || 9654 <= codePoint && codePoint <= 9655 || 9660 <= codePoint && codePoint <= 9661 || 9664 <= codePoint && codePoint <= 9665 || 9670 <= codePoint && codePoint <= 9672 || 9675 == codePoint || 9678 <= codePoint && codePoint <= 9681 || 9698 <= codePoint && codePoint <= 9701 || 9711 == codePoint || 9733 <= codePoint && codePoint <= 9734 || 9737 == codePoint || 9742 <= codePoint && codePoint <= 9743 || 9748 <= codePoint && codePoint <= 9749 || 9756 == codePoint || 9758 == codePoint || 9792 == codePoint || 9794 == codePoint || 9824 <= codePoint && codePoint <= 9825 || 9827 <= codePoint && codePoint <= 9829 || 9831 <= codePoint && codePoint <= 9834 || 9836 <= codePoint && codePoint <= 9837 || 9839 == codePoint || 9886 <= codePoint && codePoint <= 9887 || 9918 <= codePoint && codePoint <= 9919 || 9924 <= codePoint && codePoint <= 9933 || 9935 <= codePoint && codePoint <= 9953 || 9955 == codePoint || 9960 <= codePoint && codePoint <= 9983 || 10045 == codePoint || 10071 == codePoint || 10102 <= codePoint && codePoint <= 10111 || 11093 <= codePoint && codePoint <= 11097 || 12872 <= codePoint && codePoint <= 12879 || 57344 <= codePoint && codePoint <= 63743 || 65024 <= codePoint && codePoint <= 65039 || 65533 == codePoint || 127232 <= codePoint && codePoint <= 127242 || 127248 <= codePoint && codePoint <= 127277 || 127280 <= codePoint && codePoint <= 127337 || 127344 <= codePoint && codePoint <= 127386 || 917760 <= codePoint && codePoint <= 917999 || 983040 <= codePoint && codePoint <= 1048573 || 1048576 <= codePoint && codePoint <= 1114109) {
838
- return "A";
839
- }
840
- return "N";
841
- };
842
- eaw.characterLength = function(character) {
843
- var code = this.eastAsianWidth(character);
844
- if (code == "F" || code == "W" || code == "A") {
845
- return 2;
846
- } else {
847
- return 1;
848
- }
849
- };
850
- function stringToArray(string) {
851
- return string.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g) || [];
852
- }
853
- eaw.length = function(string) {
854
- var characters = stringToArray(string);
855
- var len = 0;
856
- for (var i = 0; i < characters.length; i++) {
857
- len = len + this.characterLength(characters[i]);
858
- }
859
- return len;
860
- };
861
- eaw.slice = function(text, start, end) {
862
- textLen = eaw.length(text);
863
- start = start ? start : 0;
864
- end = end ? end : 1;
865
- if (start < 0) {
866
- start = textLen + start;
867
- }
868
- if (end < 0) {
869
- end = textLen + end;
870
- }
871
- var result = "";
872
- var eawLen = 0;
873
- var chars = stringToArray(text);
874
- for (var i = 0; i < chars.length; i++) {
875
- var char = chars[i];
876
- var charLen = eaw.length(char);
877
- if (eawLen >= start - (charLen == 2 ? 1 : 0)) {
878
- if (eawLen + charLen <= end) {
879
- result += char;
880
- } else {
881
- break;
882
- }
883
- }
884
- eawLen += charLen;
885
- }
886
- return result;
887
- };
888
- }
889
- });
890
-
891
- // ../../node_modules/list-it/lib/data-cell.js
892
- var require_data_cell = __commonJS({
893
- "../../node_modules/list-it/lib/data-cell.js"(exports2, module2) {
894
- "use strict";
895
- var eaw = require_eastasianwidth();
896
- function DataCell() {
897
- this.data = "";
898
- }
899
- module2.exports = DataCell;
900
- DataCell.prototype.getData = function() {
901
- return this.data;
902
- };
903
- DataCell.prototype.setData = function(data) {
904
- this.data = data;
905
- };
906
- DataCell.prototype.visibleLength = function() {
907
- if (typeof this.data != "string") {
908
- return ("" + this.data).length;
909
- }
910
- return DataCell.visibleLength(this.data);
911
- };
912
- DataCell.visibleLength = function(data) {
913
- const s = data.replace(/\x1b[^m]*m/g, "");
914
- return eaw.length(s);
915
- };
916
- }
917
- });
918
-
919
- // ../../node_modules/list-it/lib/row.js
920
- var require_row = __commonJS({
921
- "../../node_modules/list-it/lib/row.js"(exports2, module2) {
922
- "use strict";
923
- function Row() {
924
- this.cells = [];
925
- this.empty = true;
926
- this.fixed = false;
927
- }
928
- module2.exports = Row;
929
- Row.prototype.getCellLength = function() {
930
- return this.cells.length;
931
- };
932
- Row.prototype.getCell = function(idx) {
933
- return this.cells[idx];
934
- };
935
- Row.prototype.pushCell = function(cell) {
936
- if (this.isFixed()) {
937
- throw "pushCell Fail, The row was already fixed.";
938
- }
939
- this.empty = false;
940
- return this.cells.push(cell);
941
- };
942
- Row.prototype.fix = function() {
943
- this.fixed = true;
944
- };
945
- Row.prototype.isEmpty = function() {
946
- return this.empty;
947
- };
948
- Row.prototype.isFixed = function() {
949
- return this.fixed;
950
- };
951
- }
952
- });
953
-
954
- // ../../node_modules/list-it/lib/column.js
955
- var require_column = __commonJS({
956
- "../../node_modules/list-it/lib/column.js"(exports2, module2) {
957
- "use strict";
958
- var DataCell = require_data_cell();
959
- function Column() {
960
- this.opt = {
961
- "autoAlign": false
962
- };
963
- this.width = 0;
964
- this.textWidth = null;
965
- this.intLen = 0;
966
- this.fracLen = 0;
967
- this.expLen = 0;
968
- this.cellAtRow = {};
969
- this.header = null;
970
- }
971
- module2.exports = Column;
972
- Column.prototype.getWidth = function() {
973
- return this.width;
974
- };
975
- Column.prototype.setTextWidth = function(textWidth) {
976
- this.textWidth = textWidth;
977
- };
978
- Column.prototype.setCellAt = function(row, cell) {
979
- this.cellAtRow[row] = cell;
980
- };
981
- Column.prototype.setHeader = function(header) {
982
- this.header = header;
983
- };
984
- Column.prototype.hasHeader = function() {
985
- return this.header != null;
986
- };
987
- Column.prototype.updateWidth = function() {
988
- const headerWidth = !this.hasHeader() ? 0 : DataCell.visibleLength("" + this.header);
989
- this.width = headerWidth;
990
- Object.keys(this.cellAtRow).forEach((key) => {
991
- const cell = this.cellAtRow[key];
992
- const data = cell.getData();
993
- let width = cell.visibleLength();
994
- if (typeof data == "number") {
995
- if (this.opt.autoAlign) {
996
- this.updateNumWidth(data);
997
- width = this.getNumMaxWidth();
998
- }
999
- }
1000
- if (width > this.width) {
1001
- this.width = width;
1002
- }
1003
- if (typeof data == "string") {
1004
- if (this.textWidth && this.textWidth > headerWidth) {
1005
- if (this.width > this.textWidth) {
1006
- this.width = this.textWidth;
1007
- }
1008
- }
1009
- }
1010
- });
1011
- };
1012
- Column.prototype.formatColumnHeader = function() {
1013
- if (!this.hasHeader()) {
1014
- return null;
1015
- }
1016
- const width = this.getWidth();
1017
- const header = this.header;
1018
- const headerWidth = DataCell.visibleLength("" + header);
1019
- if (header.length == headerWidth && width - headerWidth <= 0) {
1020
- return ("" + header).substring(0, width);
1021
- }
1022
- return "" + header + " ".repeat(width - headerWidth);
1023
- };
1024
- Column.prototype.formatCell = function(data) {
1025
- const width = this.getWidth();
1026
- if (this.opt.autoAlign) {
1027
- if (typeof data == "number") {
1028
- return this.makeAutoAlignNum(data).padStart(width, " ");
1029
- }
1030
- }
1031
- const dataWidth = DataCell.visibleLength("" + data);
1032
- if (data.length == dataWidth && width - dataWidth <= 0) {
1033
- return ("" + data).substring(0, width);
1034
- }
1035
- return "" + data + " ".repeat(width - dataWidth);
1036
- };
1037
- Column.prototype.setAutoAlign = function(autoAlign) {
1038
- this.opt.autoAlign = autoAlign;
1039
- };
1040
- Column.prototype.updateNumWidth = function(num) {
1041
- const numInfo = this.analyzeNumber(num);
1042
- const intLen = numInfo.intStr.length;
1043
- const fracLen = numInfo.fracStr.length;
1044
- const expLen = numInfo.expStr.length;
1045
- if (intLen > this.intLen) {
1046
- this.intLen = intLen;
1047
- }
1048
- if (fracLen > this.fracLen) {
1049
- this.fracLen = fracLen;
1050
- }
1051
- if (expLen > this.expLen) {
1052
- this.expLen = expLen;
1053
- }
1054
- };
1055
- Column.prototype.getNumMaxWidth = function() {
1056
- return this.intLen + this.fracLen + (this.fracLen > 0 ? 1 : 0) + this.expLen + (this.expLen > 0 ? 1 : 0);
1057
- };
1058
- Column.prototype.makeAutoAlignNum = function(num) {
1059
- const numInfo = this.analyzeNumber(num);
1060
- const intStr = numInfo.intStr.padStart(this.intLen, " ");
1061
- const fracStr = numInfo.expStr != "" ? numInfo.fracStr.padEnd(this.fracLen, "0") : numInfo.fracStr.padEnd(this.fracLen, " ");
1062
- const expStr = numInfo.expStr.padEnd(this.expLen, " ");
1063
- if (numInfo.expStr != "") {
1064
- return [intStr, ".", fracStr, "e", expStr].join("");
1065
- }
1066
- if (numInfo.pointPos >= 0) {
1067
- if (this.expLen > 0) {
1068
- return [intStr, ".", fracStr, " ", expStr].join("");
1069
- }
1070
- return [intStr, ".", fracStr].join("");
1071
- } else if (this.fracLen == 0) {
1072
- return intStr;
1073
- }
1074
- if (this.expLen > 0) {
1075
- return [intStr, ".0", fracStr.substr(1), " ", expStr].join("");
1076
- }
1077
- return [intStr, ".0", fracStr.substr(1)].join("");
1078
- };
1079
- Column.prototype.analyzeNumber = function(num) {
1080
- const s = "" + num;
1081
- let intStr = "";
1082
- let fracStr = "";
1083
- const pointPos = s.indexOf(".");
1084
- const expIndex = s.indexOf("e");
1085
- if (expIndex >= 0) {
1086
- if (pointPos < 0) {
1087
- return {
1088
- pointPos: expIndex,
1089
- intStr: s.substr(0, expIndex),
1090
- fracStr: "0",
1091
- expStr: s.substr(expIndex + 1)
1092
- };
1093
- }
1094
- return {
1095
- pointPos,
1096
- intStr: s.substr(0, pointPos),
1097
- fracStr: s.substring(pointPos + 1, expIndex),
1098
- expStr: s.substr(expIndex + 1)
1099
- };
1100
- }
1101
- if (pointPos < 0) {
1102
- intStr = s;
1103
- } else {
1104
- intStr = s.substr(0, pointPos);
1105
- fracStr = s.substr(pointPos + 1);
1106
- }
1107
- return {
1108
- "pointPos": pointPos,
1109
- "intStr": intStr,
1110
- "fracStr": fracStr,
1111
- "expStr": ""
1112
- };
1113
- };
1114
- }
1115
- });
1116
-
1117
- // ../../node_modules/ansi-escape-sequences/dist/index.cjs
1118
- var require_dist = __commonJS({
1119
- "../../node_modules/ansi-escape-sequences/dist/index.cjs"(exports2, module2) {
1120
- "use strict";
1121
- function isObject(input) {
1122
- return typeof input === "object" && input !== null;
1123
- }
1124
- function isArrayLike(input) {
1125
- return isObject(input) && typeof input.length === "number";
1126
- }
1127
- function arrayify(input) {
1128
- if (Array.isArray(input)) {
1129
- return input;
1130
- } else if (input === void 0) {
1131
- return [];
1132
- } else if (isArrayLike(input) || input instanceof Set) {
1133
- return Array.from(input);
1134
- } else {
1135
- return [input];
1136
- }
1137
- }
1138
- var csi = "\x1B[";
1139
- var ansi = {};
1140
- ansi.style = {
1141
- reset: "\x1B[0m",
1142
- bold: "\x1B[1m",
1143
- italic: "\x1B[3m",
1144
- underline: "\x1B[4m",
1145
- fontDefault: "\x1B[10m",
1146
- font2: "\x1B[11m",
1147
- font3: "\x1B[12m",
1148
- font4: "\x1B[13m",
1149
- font5: "\x1B[14m",
1150
- font6: "\x1B[15m",
1151
- imageNegative: "\x1B[7m",
1152
- imagePositive: "\x1B[27m",
1153
- black: "\x1B[30m",
1154
- red: "\x1B[31m",
1155
- green: "\x1B[32m",
1156
- yellow: "\x1B[33m",
1157
- blue: "\x1B[34m",
1158
- magenta: "\x1B[35m",
1159
- cyan: "\x1B[36m",
1160
- white: "\x1B[37m",
1161
- grey: "\x1B[90m",
1162
- gray: "\x1B[90m",
1163
- brightRed: "\x1B[91m",
1164
- brightGreen: "\x1B[92m",
1165
- brightYellow: "\x1B[93m",
1166
- brightBlue: "\x1B[94m",
1167
- brightMagenta: "\x1B[95m",
1168
- brightCyan: "\x1B[96m",
1169
- brightWhite: "\x1B[97m",
1170
- "bg-black": "\x1B[40m",
1171
- "bg-red": "\x1B[41m",
1172
- "bg-green": "\x1B[42m",
1173
- "bg-yellow": "\x1B[43m",
1174
- "bg-blue": "\x1B[44m",
1175
- "bg-magenta": "\x1B[45m",
1176
- "bg-cyan": "\x1B[46m",
1177
- "bg-white": "\x1B[47m",
1178
- "bg-grey": "\x1B[100m",
1179
- "bg-gray": "\x1B[100m",
1180
- "bg-brightRed": "\x1B[101m",
1181
- "bg-brightGreen": "\x1B[102m",
1182
- "bg-brightYellow": "\x1B[103m",
1183
- "bg-brightBlue": "\x1B[104m",
1184
- "bg-brightMagenta": "\x1B[105m",
1185
- "bg-brightCyan": "\x1B[106m",
1186
- "bg-brightWhite": "\x1B[107m"
1187
- };
1188
- ansi.rgb = function(r, g, b) {
1189
- return `\x1B[38;2;${r};${g};${b}m`;
1190
- };
1191
- ansi.bgRgb = function(r, g, b) {
1192
- return `\x1B[48;2;${r};${g};${b}m`;
1193
- };
1194
- ansi.styles = function(styles) {
1195
- styles = arrayify(styles);
1196
- return styles.map(function(effect) {
1197
- const rgbMatches = effect.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
1198
- const bgRgbMatches = effect.match(/bg-rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
1199
- if (bgRgbMatches) {
1200
- const [full, r, g, b] = bgRgbMatches;
1201
- return ansi.bgRgb(r, g, b);
1202
- } else if (rgbMatches) {
1203
- const [full, r, g, b] = rgbMatches;
1204
- return ansi.rgb(r, g, b);
1205
- } else {
1206
- return ansi.style[effect];
1207
- }
1208
- }).join("");
1209
- };
1210
- ansi.format = function(str, styleArray) {
1211
- const re = /\[([\w\s-\(\),]+)\]{([^]*?)}/;
1212
- let matches;
1213
- str = String(str);
1214
- if (!str) return "";
1215
- while (matches = str.match(re)) {
1216
- const inlineStyles = matches[1].split(/\s+/);
1217
- const inlineString = matches[2];
1218
- str = str.replace(matches[0], ansi.format(inlineString, inlineStyles));
1219
- }
1220
- return styleArray && styleArray.length ? ansi.styles(styleArray) + str + ansi.style.reset : str;
1221
- };
1222
- ansi.cursor = {
1223
- /**
1224
- * Moves the cursor `lines` cells up. If the cursor is already at the edge of the screen, this has no effect
1225
- * @param [lines=1] {number}
1226
- * @return {string}
1227
- */
1228
- up: function(lines) {
1229
- return csi + (lines || 1) + "A";
1230
- },
1231
- /**
1232
- * Moves the cursor `lines` cells down. If the cursor is already at the edge of the screen, this has no effect
1233
- * @param [lines=1] {number}
1234
- * @return {string}
1235
- */
1236
- down: function(lines) {
1237
- return csi + (lines || 1) + "B";
1238
- },
1239
- /**
1240
- * Moves the cursor `lines` cells forward. If the cursor is already at the edge of the screen, this has no effect
1241
- * @param [lines=1] {number}
1242
- * @return {string}
1243
- */
1244
- forward: function(lines) {
1245
- return csi + (lines || 1) + "C";
1246
- },
1247
- /**
1248
- * Moves the cursor `lines` cells back. If the cursor is already at the edge of the screen, this has no effect
1249
- * @param [lines=1] {number}
1250
- * @return {string}
1251
- */
1252
- back: function(lines) {
1253
- return csi + (lines || 1) + "D";
1254
- },
1255
- /**
1256
- * Moves cursor to beginning of the line n lines down.
1257
- * @param [lines=1] {number}
1258
- * @return {string}
1259
- */
1260
- nextLine: function(lines) {
1261
- return csi + (lines || 1) + "E";
1262
- },
1263
- /**
1264
- * Moves cursor to beginning of the line n lines up.
1265
- * @param [lines=1] {number}
1266
- * @return {string}
1267
- */
1268
- previousLine: function(lines) {
1269
- return csi + (lines || 1) + "F";
1270
- },
1271
- /**
1272
- * Moves the cursor to column n.
1273
- * @param n {number} - column number
1274
- * @return {string}
1275
- */
1276
- horizontalAbsolute: function(n) {
1277
- return csi + n + "G";
1278
- },
1279
- /**
1280
- * Moves the cursor to row n, column m. The values are 1-based, and default to 1 (top left corner) if omitted.
1281
- * @param n {number} - row number
1282
- * @param m {number} - column number
1283
- * @return {string}
1284
- */
1285
- position: function(n, m) {
1286
- return csi + (n || 1) + ";" + (m || 1) + "H";
1287
- },
1288
- /**
1289
- * Hides the cursor
1290
- */
1291
- hide: csi + "?25l",
1292
- /**
1293
- * Shows the cursor
1294
- */
1295
- show: csi + "?25h"
1296
- };
1297
- ansi.erase = {
1298
- /**
1299
- * Clears part of the screen. If n is 0 (or missing), clear from cursor to end of screen. If n is 1, clear from cursor to beginning of the screen. If n is 2, clear entire screen.
1300
- * @param n {number}
1301
- * @return {string}
1302
- */
1303
- display: function(n) {
1304
- return csi + (n || 0) + "J";
1305
- },
1306
- /**
1307
- * Erases part of the line. If n is zero (or missing), clear from cursor to the end of the line. If n is one, clear from cursor to beginning of the line. If n is two, clear entire line. Cursor position does not change.
1308
- * @param n {number}
1309
- * @return {string}
1310
- */
1311
- inLine: function(n) {
1312
- return csi + (n || 0) + "K";
1313
- }
1314
- };
1315
- module2.exports = ansi;
1316
- }
1317
- });
1318
-
1319
- // ../../node_modules/list-it/lib/list-it-buffer.js
1320
- var require_list_it_buffer = __commonJS({
1321
- "../../node_modules/list-it/lib/list-it-buffer.js"(exports2, module2) {
1322
- "use strict";
1323
- var debug = require_src()("list-it-buffer");
1324
- var DataCell = require_data_cell();
1325
- var Row = require_row();
1326
- var Column = require_column();
1327
- var ansi = require_dist();
1328
- function ListItBuffer(opt) {
1329
- opt = opt || {};
1330
- this.opt = {
1331
- "autoAlign": true,
1332
- "columnWidth": null,
1333
- "header": null,
1334
- "headerBold": false,
1335
- "headerColor": "",
1336
- "headerUnderline": false
1337
- };
1338
- if (opt.header != null && !Array.isArray(opt.header)) {
1339
- throw new Error([
1340
- `Invalid header was specified. It must be an array, but (${JSON.stringify(opt.header)}):${typeof opt.header} was specified.`
1341
- ].join(" "));
1342
- }
1343
- if (opt.headerColor && !(opt.headerColor in COLORS)) {
1344
- throw new Error([
1345
- `Invalid color ${JSON.stringify(opt.headerColor)} was specified.`,
1346
- "Available color names:",
1347
- ...AVAILABLE_COLORS.map((color) => `* ${JSON.stringify(color)}`)
1348
- ].join("\n"));
1349
- }
1350
- Object.keys(this.opt).forEach((key) => {
1351
- if (key in opt) {
1352
- this.opt[key] = opt[key];
1353
- }
1354
- });
1355
- this.lines = [];
1356
- this.columns = [];
1357
- this.columnWidth = this.opt.columnWidth;
1358
- if (this.opt.header) {
1359
- this.setHeaderRow(this.opt.header);
1360
- }
1361
- }
1362
- module2.exports = ListItBuffer;
1363
- ListItBuffer.prototype.nl = function() {
1364
- const lastRowIndex = this.lines.length - 1;
1365
- if (lastRowIndex >= 0 && !this.lines[lastRowIndex].isFixed()) {
1366
- this.lines[lastRowIndex].fix();
1367
- }
1368
- this.pushNewRow();
1369
- return this;
1370
- };
1371
- ListItBuffer.prototype.d = function(data) {
1372
- if (arguments.length > 1) {
1373
- const array = Array.apply(null, arguments);
1374
- if (ListItBuffer.isMultiDimensionalArray(array)) {
1375
- array.forEach((row) => this.addRow(row));
1376
- } else {
1377
- array.forEach((data2) => this.d(data2));
1378
- }
1379
- return this;
1380
- }
1381
- if (Array.isArray(data)) {
1382
- if (ListItBuffer.isMultiDimensionalArray(data)) {
1383
- data.forEach((row) => this.addRow(row));
1384
- } else if (ListItBuffer.isObjectArray(data)) {
1385
- data = objectArrayToTable(data);
1386
- if (!this.header && (this.opt.headerBold || this.opt.headerColor || this.opt.headerUnderline)) {
1387
- this.setHeaderRow(data.shift());
1388
- }
1389
- data.forEach((row) => this.addRow(row));
1390
- } else {
1391
- this.addRow(data);
1392
- }
1393
- return this;
1394
- }
1395
- const rowidx = this.lines.length - 1;
1396
- if (rowidx < 0 || this.lines[rowidx].isFixed()) {
1397
- this.pushNewRow();
1398
- }
1399
- const cell = new DataCell();
1400
- cell.setData(data);
1401
- const iRow = this.lines.length - 1;
1402
- let iCol = this.lines[iRow].getCellLength();
1403
- if (iCol >= this.columns.length) {
1404
- this.addColumn();
1405
- }
1406
- this.columns[iCol].setCellAt(iRow, cell);
1407
- this.lines[iRow].pushCell(cell);
1408
- return this;
1409
- };
1410
- ListItBuffer.isMultiDimensionalArray = function(arr) {
1411
- if (!Array.isArray(arr)) {
1412
- throw Error("The parameter arr must be array");
1413
- }
1414
- for (let element of arr) {
1415
- if (!Array.isArray(element)) {
1416
- return false;
1417
- }
1418
- }
1419
- return true;
1420
- };
1421
- ListItBuffer.isObjectArray = function(arr) {
1422
- if (!Array.isArray(arr)) {
1423
- throw Error("The parameter arr must be array");
1424
- }
1425
- const ctor = arr[0].constructor;
1426
- for (let element of arr) {
1427
- if (typeof element != "object") {
1428
- return false;
1429
- } else {
1430
- if (element.constructor.name != ctor.name) {
1431
- return false;
1432
- }
1433
- }
1434
- }
1435
- return true;
1436
- };
1437
- ListItBuffer.prototype.addRow = function(row) {
1438
- row.forEach((col) => {
1439
- switch (typeof col) {
1440
- case "string":
1441
- case "number":
1442
- this.d(col);
1443
- break;
1444
- default:
1445
- this.d(col != null ? col.toString() : "(null)");
1446
- break;
1447
- }
1448
- });
1449
- this.nl();
1450
- };
1451
- ListItBuffer.prototype.pushNewRow = function() {
1452
- this.lines.push(new Row());
1453
- };
1454
- ListItBuffer.prototype.toString = function() {
1455
- const rows = [];
1456
- this.columns.forEach((column, iCol) => {
1457
- if (this.header != null) {
1458
- column.setHeader(this.header[iCol] || "");
1459
- }
1460
- column.setTextWidth(this.getColumnWidth(iCol));
1461
- column.updateWidth();
1462
- });
1463
- if (this.header != null) {
1464
- const headerLine = this.applyHeaderStyleOption(
1465
- this.columns.map((column) => column.formatColumnHeader()).join(" ")
1466
- );
1467
- rows.push(headerLine);
1468
- const headerUnderline = this.generateHeaderUnderline();
1469
- if (headerUnderline) {
1470
- rows.push(headerUnderline);
1471
- }
1472
- }
1473
- this.lines.forEach((line) => {
1474
- if (line.isFixed() || !line.isEmpty()) {
1475
- if (line.isEmpty()) {
1476
- rows.push("\n");
1477
- } else {
1478
- rows.push(this.columns.map((column, iCol) => {
1479
- const cell = line.getCell(iCol);
1480
- const data = cell.getData();
1481
- return column.formatCell(data);
1482
- }).join(" "));
1483
- }
1484
- }
1485
- });
1486
- return rows.join("\n");
1487
- };
1488
- var COLORS = {};
1489
- var BGCOLORS = {};
1490
- Object.keys(ansi.style).forEach((key) => {
1491
- const value = ansi.style[key];
1492
- if (/^bg-/.test(key)) {
1493
- BGCOLORS[key.substr(3)] = value;
1494
- } else {
1495
- COLORS[key] = value;
1496
- debug(`COLOR-KEY: ${key}`);
1497
- }
1498
- });
1499
- Object.keys(COLORS).forEach((key) => {
1500
- if (!(key in BGCOLORS)) {
1501
- delete COLORS[key];
1502
- debug(`remove COLOR-KEY: ${key}`);
1503
- }
1504
- });
1505
- var AVAILABLE_COLORS = Object.keys(COLORS);
1506
- debug(`AVAILABLE_COLORS:${JSON.stringify(AVAILABLE_COLORS)}`);
1507
- ListItBuffer.prototype.applyHeaderStyleOption = function(line) {
1508
- if (!this.opt.headerBold && !this.opt.headerColor) {
1509
- return line;
1510
- }
1511
- const textBuffer = [];
1512
- if (this.opt.headerBold) {
1513
- textBuffer.push(ansi.style.bold);
1514
- }
1515
- if (this.opt.headerColor) {
1516
- textBuffer.push(COLORS[this.opt.headerColor]);
1517
- }
1518
- textBuffer.push(line);
1519
- textBuffer.push(ansi.style.reset);
1520
- return textBuffer.join("");
1521
- };
1522
- ListItBuffer.prototype.generateHeaderUnderline = function() {
1523
- if (!this.opt.headerUnderline) {
1524
- return null;
1525
- }
1526
- if (this.header == null) {
1527
- return null;
1528
- }
1529
- return this.columns.map(
1530
- (column) => "-".repeat(column.getWidth())
1531
- ).join(" ");
1532
- };
1533
- function objectArrayToTable(objects) {
1534
- const keys = Object.keys(objects[0]);
1535
- const body = objects.map((item) => keys.map((key) => {
1536
- if (item[key] != null && typeof item[key] == "object" && item[key].constructor.name == "Date") {
1537
- return item[key].toISOString();
1538
- }
1539
- return item[key];
1540
- }));
1541
- return [keys, ...body];
1542
- }
1543
- ListItBuffer.prototype.setColumnWidth = function(indexOfColumns, width) {
1544
- this.columnWidth = this.columnWidth || [];
1545
- if (typeof indexOfColumns !== "number") {
1546
- throw new Error("indexOfColumns must be a number");
1547
- }
1548
- if (!width) {
1549
- delete this.columnWidth[indexOfColumns];
1550
- } else {
1551
- if (typeof width !== "number") {
1552
- throw new Error("width must be a number");
1553
- }
1554
- this.columnWidth[indexOfColumns] = width;
1555
- }
1556
- return this;
1557
- };
1558
- ListItBuffer.prototype.setColumnWidthAll = function(widthForAll) {
1559
- if (widthForAll != null && !Array.isArray(widthForAll) && typeof widthForAll !== "number") {
1560
- throw new Error(
1561
- "widthForAll must be one of a null, an Array or a number"
1562
- );
1563
- }
1564
- if (Array.isArray(widthForAll)) {
1565
- for (let i = 0; i < widthForAll.length; i++) {
1566
- const width = widthForAll[i];
1567
- if (width != void 0 && typeof width !== "number") {
1568
- throw new Error(
1569
- `widthForAll[${i}] must be an undefined or a number`
1570
- );
1571
- }
1572
- }
1573
- }
1574
- this.columnWidth = widthForAll;
1575
- return this;
1576
- };
1577
- ListItBuffer.prototype.getColumnWidth = function(indexOfColumns) {
1578
- if (Array.isArray(this.columnWidth)) {
1579
- return this.columnWidth[indexOfColumns];
1580
- }
1581
- return this.columnWidth;
1582
- };
1583
- ListItBuffer.prototype.setHeaderRow = function(header) {
1584
- if (header && !Array.isArray(header)) {
1585
- throw new Error([
1586
- "The header must be an array,",
1587
- `but ${typeof header} was specified.`,
1588
- `header: ${JSON.stringify(header)}`
1589
- ].join(" "));
1590
- }
1591
- this.header = header;
1592
- if (this.header == null) {
1593
- this.columns.forEach((column) => column.setHeader(null));
1594
- } else {
1595
- this.header.forEach((headerText, iCol) => {
1596
- if (iCol >= this.columns.length) {
1597
- this.addColumn(headerText);
1598
- }
1599
- });
1600
- }
1601
- return this;
1602
- };
1603
- ListItBuffer.prototype.addColumn = function(headerText) {
1604
- const column = new Column();
1605
- if (headerText) {
1606
- column.setHeader(headerText);
1607
- }
1608
- if (this.opt.autoAlign) {
1609
- column.setAutoAlign(true);
1610
- }
1611
- this.columns.push(column);
1612
- };
1613
- }
1614
- });
1615
-
1616
- // ../../node_modules/list-it/index.js
1617
- var require_list_it = __commonJS({
1618
- "../../node_modules/list-it/index.js"(exports2, module2) {
1619
- "use strict";
1620
- var ListItBuffer = require_list_it_buffer();
1621
- function ListIt2(opt) {
1622
- ListItBuffer.call(this, opt);
1623
- }
1624
- ListIt2.prototype = new ListItBuffer();
1625
- ListIt2.buffer = function(opt) {
1626
- opt = opt || {};
1627
- if (!("autoAlign" in opt)) {
1628
- opt.autoAlign = false;
1629
- }
1630
- return new ListIt2(opt);
1631
- };
1632
- module2.exports = ListIt2;
1633
- }
1634
- });
1635
-
1636
30
  // src/scripts/aiPocketSearch.ts
1637
31
  var aiPocketSearch_exports = {};
1638
32
  __export(aiPocketSearch_exports, {
@@ -2020,6 +414,7 @@ var resolveAiTrainRecentLimit = ({
2020
414
  var DAY_MS2 = 24 * 60 * 60 * 1e3;
2021
415
  var DAYS_PER_WEEK2 = 7;
2022
416
  var DAYS_PER_MONTH2 = 30.4375;
417
+ var PRODUCTION_CANDIDATE_MIN_EVENTS = 25;
2023
418
  var OUTCOME_SEGMENTS = /* @__PURE__ */ new Set([
2024
419
  "actual",
2025
420
  "aiapproved",
@@ -2105,6 +500,146 @@ var METADATA_LEAVES = /* @__PURE__ */ new Set([
2105
500
  "targetsymbol",
2106
501
  "universe"
2107
502
  ]);
503
+ var normalizeFeaturePath = (path2) => (Array.isArray(path2) ? path2 : path2.split(".")).filter(Boolean).map((segment) => segment.toLowerCase());
504
+ var classifyAiPocketCoverageFeaturePath = (path2) => {
505
+ const segments = normalizeFeaturePath(path2);
506
+ const normalizedPath = segments.join(".");
507
+ if (segments.some(
508
+ (segment) => segment.includes("cmc") || segment.includes("coinmarketcap")
509
+ )) {
510
+ return "cmc";
511
+ }
512
+ if (segments.some(
513
+ (segment) => segment.includes("derivative") || segment.includes("coinalyze")
514
+ ) || /(?:^|\.)(?:funding|openinterest|oi(?:change|acceleration|divergence)|priceoi|liq(?:long|short|total|imbalance|spike)|liquidation)/.test(
515
+ normalizedPath
516
+ )) {
517
+ return "coinalyze";
518
+ }
519
+ return null;
520
+ };
521
+ var hasUsableContextPrimitive = (value) => {
522
+ if (Array.isArray(value) || value == null) {
523
+ return false;
524
+ }
525
+ if (isFeaturePrimitive(value)) {
526
+ return typeof value !== "string" || value.toLowerCase() !== "unknown";
527
+ }
528
+ if (!isPlainRecord(value)) {
529
+ return false;
530
+ }
531
+ return Object.entries(value).some(([key, child]) => {
532
+ const normalizedKey = key.toLowerCase();
533
+ if (DATA_QUALITY_LEAVES.has(normalizedKey) || METADATA_LEAVES.has(normalizedKey) || normalizedKey === "riskflags" || normalizedKey.endsWith("timestamp") || normalizedKey.endsWith("agems")) {
534
+ return false;
535
+ }
536
+ return hasUsableContextPrimitive(child);
537
+ });
538
+ };
539
+ var isUsableCmcContext = (value) => isPlainRecord(value) && value.available !== false && value.stale !== true && hasUsableContextPrimitive(value);
540
+ var hasUsableCmcContext = (baseContext) => {
541
+ const relative = isPlainRecord(baseContext?.relative) ? baseContext.relative : null;
542
+ return Boolean(
543
+ relative && Object.entries(relative).some(
544
+ ([key, value]) => key.toLowerCase().startsWith("cmc") && isUsableCmcContext(value)
545
+ )
546
+ );
547
+ };
548
+ var isUsableDerivativesContext = (context) => {
549
+ if (!context) {
550
+ return false;
551
+ }
552
+ const summary = isPlainRecord(context.summary) ? context.summary : null;
553
+ const riskFlags = Array.isArray(summary?.riskFlags) ? summary.riskFlags.filter(
554
+ (flag) => typeof flag === "string"
555
+ ) : [];
556
+ if (riskFlags.includes("missing_derivatives") || riskFlags.includes("stale_derivatives")) {
557
+ return false;
558
+ }
559
+ const intervals = isPlainRecord(context.intervals) ? context.intervals : null;
560
+ return Boolean(
561
+ intervals && Object.values(intervals).some(
562
+ (interval) => isPlainRecord(interval) && interval.stale !== true && hasUsableContextPrimitive(interval)
563
+ )
564
+ );
565
+ };
566
+ var hasUsableCoinalyzeContext = (baseContext) => {
567
+ const derivatives = isPlainRecord(baseContext?.derivatives) ? baseContext.derivatives : null;
568
+ if (!derivatives) {
569
+ return false;
570
+ }
571
+ if (isUsableDerivativesContext(derivatives)) {
572
+ return true;
573
+ }
574
+ const targetContext = isPlainRecord(derivatives.targetContext) ? derivatives.targetContext : null;
575
+ if (isUsableDerivativesContext(targetContext)) {
576
+ return true;
577
+ }
578
+ const referenceContexts = isPlainRecord(derivatives.referenceContexts) ? derivatives.referenceContexts : null;
579
+ return Boolean(
580
+ referenceContexts && Object.values(referenceContexts).some(
581
+ (context) => isUsableDerivativesContext(isPlainRecord(context) ? context : null)
582
+ )
583
+ );
584
+ };
585
+ var resolveAiPocketFeatureCoverage = (payload) => {
586
+ const additionalIndicators = isPlainRecord(payload.additionalIndicators) ? payload.additionalIndicators : null;
587
+ const baseContext = isPlainRecord(additionalIndicators?.baseContext) ? additionalIndicators.baseContext : null;
588
+ return {
589
+ cmc: hasUsableCmcContext(baseContext),
590
+ coinalyze: hasUsableCoinalyzeContext(baseContext)
591
+ };
592
+ };
593
+ var isAiPocketCoverageFeatureUsable = ({
594
+ payload,
595
+ segments,
596
+ family,
597
+ familyCoverage
598
+ }) => {
599
+ const additionalIndicators = isPlainRecord(payload.additionalIndicators) ? payload.additionalIndicators : null;
600
+ const baseContext = isPlainRecord(additionalIndicators?.baseContext) ? additionalIndicators.baseContext : null;
601
+ const baseContextIndex = segments.findIndex(
602
+ (segment) => segment.toLowerCase() === "basecontext"
603
+ );
604
+ if (family === "cmc") {
605
+ const relative = isPlainRecord(baseContext?.relative) ? baseContext.relative : null;
606
+ if (relative && baseContextIndex >= 0 && segments[baseContextIndex + 1]?.toLowerCase() === "relative") {
607
+ const contextKey = segments[baseContextIndex + 2];
608
+ if (contextKey?.toLowerCase().startsWith("cmc")) {
609
+ return isUsableCmcContext(relative[contextKey]);
610
+ }
611
+ }
612
+ return familyCoverage.cmc;
613
+ }
614
+ const derivatives = isPlainRecord(baseContext?.derivatives) ? baseContext.derivatives : null;
615
+ if (!derivatives || baseContextIndex < 0 || segments[baseContextIndex + 1]?.toLowerCase() !== "derivatives") {
616
+ return isUsableDerivativesContext(derivatives);
617
+ }
618
+ const branch = segments[baseContextIndex + 2]?.toLowerCase();
619
+ if (branch == null) {
620
+ return familyCoverage.coinalyze;
621
+ }
622
+ if (branch === "referencecontexts") {
623
+ const referenceContexts = isPlainRecord(derivatives.referenceContexts) ? derivatives.referenceContexts : null;
624
+ const symbol = segments[baseContextIndex + 3];
625
+ if (!symbol) {
626
+ return Boolean(
627
+ referenceContexts && Object.values(referenceContexts).some(
628
+ (context) => isUsableDerivativesContext(isPlainRecord(context) ? context : null)
629
+ )
630
+ );
631
+ }
632
+ return isUsableDerivativesContext(
633
+ symbol && referenceContexts && isPlainRecord(referenceContexts[symbol]) ? referenceContexts[symbol] : null
634
+ );
635
+ }
636
+ if (branch === "targetcontext" || branch === "targetderived") {
637
+ return isUsableDerivativesContext(
638
+ isPlainRecord(derivatives.targetContext) ? derivatives.targetContext : null
639
+ );
640
+ }
641
+ return isUsableDerivativesContext(derivatives);
642
+ };
2108
643
  var DERIVED_POLICY_FRAGMENTS = [
2109
644
  "approval",
2110
645
  "decisionhint",
@@ -2443,7 +978,7 @@ var addSignalRiskDistanceFeatures = ({
2443
978
  features["derived.takeProfitDistanceBps"] = Math.abs(takeProfitPrice - currentPrice) / Math.abs(currentPrice) * 1e4;
2444
979
  }
2445
980
  };
2446
- var collectAiPocketFeatures = ({
981
+ var collectAiPocketFeatureSnapshot = ({
2447
982
  payload,
2448
983
  gateContext,
2449
984
  includeSymbol = false,
@@ -2453,6 +988,7 @@ var collectAiPocketFeatures = ({
2453
988
  onFeatureExcluded
2454
989
  }) => {
2455
990
  const features = {};
991
+ const featureCoverage = resolveAiPocketFeatureCoverage(payload);
2456
992
  const signal = payload.signal ?? {};
2457
993
  const source = {
2458
994
  signal: {
@@ -2471,6 +1007,19 @@ var collectAiPocketFeatures = ({
2471
1007
  segments: [],
2472
1008
  maxDepth: 8,
2473
1009
  shouldSkipPath: (segments) => {
1010
+ const coverageFamily = classifyAiPocketCoverageFeaturePath(segments);
1011
+ if (featurePolicy === "causal-stationary" && coverageFamily != null && !isAiPocketCoverageFeatureUsable({
1012
+ payload,
1013
+ segments,
1014
+ family: coverageFamily,
1015
+ familyCoverage: featureCoverage
1016
+ })) {
1017
+ onFeatureExcluded?.({
1018
+ path: segments.join("."),
1019
+ classification: "data-quality"
1020
+ });
1021
+ return true;
1022
+ }
2474
1023
  if (featureProfile === "compact" && isCompactFeaturePathSkipped(segments)) {
2475
1024
  return true;
2476
1025
  }
@@ -2501,7 +1050,7 @@ var collectAiPocketFeatures = ({
2501
1050
  }
2502
1051
  addSignalRiskDistanceFeatures({ features, signal });
2503
1052
  addDirectionalDerivedFeatures(features);
2504
- return features;
1053
+ return { features, featureCoverage };
2505
1054
  };
2506
1055
  var formatNumber = (value) => {
2507
1056
  if (Number.isInteger(value)) {
@@ -2768,6 +1317,37 @@ var summarizeRowIndexes = (rows, rowIndexes) => {
2768
1317
  return finalizeAiPocketSummary({ rows, accumulator });
2769
1318
  };
2770
1319
  var summarizeAiPocketRows = (rows) => summarizeSelectedRows(rows, rows);
1320
+ var summarizeAiPocketFeatureCoverage = (rows, family) => {
1321
+ const coveredRows = rows.filter(
1322
+ (row) => row.featureCoverage?.[family] === true
1323
+ );
1324
+ const allEvents = /* @__PURE__ */ new Set();
1325
+ const coveredEvents = /* @__PURE__ */ new Set();
1326
+ let minTimestamp = null;
1327
+ let maxTimestamp = null;
1328
+ for (const row of rows) {
1329
+ if (isFiniteNumber(row.timestamp)) {
1330
+ allEvents.add(row.timestamp);
1331
+ }
1332
+ }
1333
+ for (const row of coveredRows) {
1334
+ if (!isFiniteNumber(row.timestamp)) {
1335
+ continue;
1336
+ }
1337
+ coveredEvents.add(row.timestamp);
1338
+ minTimestamp = minTimestamp == null ? row.timestamp : Math.min(minTimestamp, row.timestamp);
1339
+ maxTimestamp = maxTimestamp == null ? row.timestamp : Math.max(maxTimestamp, row.timestamp);
1340
+ }
1341
+ return {
1342
+ family,
1343
+ rows: coveredRows.length,
1344
+ rowRatio: rows.length > 0 ? coveredRows.length / rows.length : 0,
1345
+ events: coveredEvents.size,
1346
+ eventRatio: allEvents.size > 0 ? coveredEvents.size / allEvents.size : 0,
1347
+ minTimestamp,
1348
+ maxTimestamp
1349
+ };
1350
+ };
2771
1351
  var matchesPredicate = (value, predicate) => {
2772
1352
  if (predicate.kind === "numeric") {
2773
1353
  if (!isFiniteNumber(value)) {
@@ -3080,6 +1660,19 @@ var createPocketResult = (rows, predicates, mask, validationRows, testRows, obje
3080
1660
  const condition = publicPredicates.map((predicate) => predicate.label).join(" AND ");
3081
1661
  const validationScore = validationSummary == null || validationObjectiveSummary == null ? void 0 : validationSummary.support > 0 ? scorePositivePocket(validationObjectiveSummary) - (objective === "standalone" ? 0 : scorePositivePocket(validationObjectiveBaseline)) : Number.NEGATIVE_INFINITY;
3082
1662
  const testScore = testSummary == null || testObjectiveSummary == null ? void 0 : testSummary.support > 0 ? scorePositivePocket(testObjectiveSummary) - (objective === "standalone" ? 0 : scorePositivePocket(testObjectiveBaseline)) : Number.NEGATIVE_INFINITY;
1663
+ const readinessReasons = [];
1664
+ if (summary.events < PRODUCTION_CANDIDATE_MIN_EVENTS) {
1665
+ readinessReasons.push(
1666
+ `train events ${summary.events} < ${PRODUCTION_CANDIDATE_MIN_EVENTS}`
1667
+ );
1668
+ }
1669
+ if (testSummary == null) {
1670
+ readinessReasons.push("untouched test missing");
1671
+ } else if (testSummary.events < PRODUCTION_CANDIDATE_MIN_EVENTS) {
1672
+ readinessReasons.push(
1673
+ `test events ${testSummary.events} < ${PRODUCTION_CANDIDATE_MIN_EVENTS}`
1674
+ );
1675
+ }
3083
1676
  return {
3084
1677
  id: publicPredicates.map((predicate) => predicate.id).join("&&"),
3085
1678
  depth: publicPredicates.length,
@@ -3093,6 +1686,8 @@ var createPocketResult = (rows, predicates, mask, validationRows, testRows, obje
3093
1686
  ...objective !== "standalone" && testObjectiveSummary ? { testObjectiveSummary } : {},
3094
1687
  ...validationScore != null ? { validationScore } : {},
3095
1688
  ...testScore != null ? { testScore } : {},
1689
+ readiness: readinessReasons.length === 0 ? "production-candidate" : "research-only",
1690
+ readinessReasons,
3096
1691
  score: scorePositivePocket(objectiveSummary) - (objective === "standalone" ? 0 : scorePositivePocket(objectiveBaseline))
3097
1692
  };
3098
1693
  };
@@ -3187,6 +1782,43 @@ var diversifyPredicatePool = (predicates, maximum) => {
3187
1782
  }
3188
1783
  return selected;
3189
1784
  };
1785
+ var prioritizeRequiredFeatureFamilyPredicates = ({
1786
+ selected,
1787
+ predicates,
1788
+ requiredFeatureFamilies,
1789
+ maximum
1790
+ }) => {
1791
+ if (!requiredFeatureFamilies.length) {
1792
+ return selected;
1793
+ }
1794
+ const perFamilyLimit = Math.max(
1795
+ 6,
1796
+ Math.floor(maximum * 0.2 / requiredFeatureFamilies.length)
1797
+ );
1798
+ const prioritized = /* @__PURE__ */ new Map();
1799
+ for (const family of requiredFeatureFamilies) {
1800
+ const familyPredicates = predicates.filter(
1801
+ (predicate) => classifyAiPocketCoverageFeaturePath(predicate.featureKey) === family
1802
+ );
1803
+ const positive = [...familyPredicates].sort(
1804
+ (left, right) => scorePositivePocket(right.atomSummary) - scorePositivePocket(left.atomSummary)
1805
+ ).slice(0, Math.ceil(perFamilyLimit * 0.5));
1806
+ const negative = [...familyPredicates].sort(
1807
+ (left, right) => scoreNegativePocket(right.atomSummary) - scoreNegativePocket(left.atomSummary)
1808
+ ).slice(0, Math.ceil(perFamilyLimit * 0.3));
1809
+ const broad = [...familyPredicates].sort((left, right) => right.support - left.support).slice(0, Math.ceil(perFamilyLimit * 0.2));
1810
+ for (const predicate of [...positive, ...negative, ...broad]) {
1811
+ if (prioritized.size >= perFamilyLimit * requiredFeatureFamilies.length) {
1812
+ break;
1813
+ }
1814
+ prioritized.set(predicate.id, predicate);
1815
+ }
1816
+ }
1817
+ for (const predicate of selected) {
1818
+ prioritized.set(predicate.id, predicate);
1819
+ }
1820
+ return [...prioritized.values()].slice(0, maximum);
1821
+ };
3190
1822
  var canCombinePredicate = (chosen, candidate) => {
3191
1823
  const sameFeature = chosen.filter(
3192
1824
  (predicate) => predicate.featureKey === candidate.featureKey
@@ -3202,7 +1834,11 @@ var canCombinePredicate = (chosen, candidate) => {
3202
1834
  return lower <= upper;
3203
1835
  };
3204
1836
  var searchAiPockets = (rows, options = {}) => {
3205
- const minSupport = Math.max(1, Math.trunc(options.minSupport ?? 20));
1837
+ const cadenceProfileOption = options.cadenceProfile;
1838
+ const minSupport = Math.max(
1839
+ 1,
1840
+ Math.trunc(cadenceProfileOption?.minSupport ?? options.minSupport ?? 20)
1841
+ );
3206
1842
  const minProfitFactor = Math.max(0, options.minProfitFactor ?? 1.2);
3207
1843
  const minTotalProfit = options.minTotalProfit ?? 0;
3208
1844
  const minWinRate = Math.max(0, options.minWinRate ?? 0);
@@ -3220,17 +1856,27 @@ var searchAiPockets = (rows, options = {}) => {
3220
1856
  const testRows = options.testRows ?? [];
3221
1857
  const minValidationSupport = Math.max(
3222
1858
  0,
3223
- Math.trunc(options.minValidationSupport ?? 0)
1859
+ Math.trunc(
1860
+ cadenceProfileOption?.minValidationSupport ?? options.minValidationSupport ?? 0
1861
+ )
1862
+ );
1863
+ const minEvents = Math.max(
1864
+ 1,
1865
+ Math.trunc(cadenceProfileOption?.minEvents ?? options.minEvents ?? 1)
3224
1866
  );
3225
- const minEvents = Math.max(1, Math.trunc(options.minEvents ?? 1));
3226
1867
  const minValidationEvents = Math.max(
3227
1868
  0,
3228
- Math.trunc(options.minValidationEvents ?? 0)
1869
+ Math.trunc(
1870
+ cadenceProfileOption?.minValidationEvents ?? options.minValidationEvents ?? 0
1871
+ )
3229
1872
  );
3230
1873
  const maxBatch = Math.max(1, options.maxBatch ?? Number.POSITIVE_INFINITY);
3231
1874
  const maxEventCountShare = Math.max(
3232
1875
  0,
3233
- Math.min(1, options.maxEventCountShare ?? 1)
1876
+ Math.min(
1877
+ 1,
1878
+ cadenceProfileOption?.maxEventCountShare ?? options.maxEventCountShare ?? 1
1879
+ )
3234
1880
  );
3235
1881
  const maxSymbolCountShare = Math.max(
3236
1882
  0,
@@ -3248,18 +1894,59 @@ var searchAiPockets = (rows, options = {}) => {
3248
1894
  const allowRiskRegression = options.allowRiskRegression === true;
3249
1895
  const requireValidationEligibility = options.requireValidationEligibility === true;
3250
1896
  const dedupeEquivalentSelections = options.dedupeEquivalentSelections !== false;
1897
+ const requiredFeatureFamilies = [
1898
+ ...new Set(options.requiredFeatureFamilies ?? [])
1899
+ ];
1900
+ const excludedFeatureFamilies = [
1901
+ ...new Set(options.excludedFeatureFamilies ?? [])
1902
+ ];
3251
1903
  const progressInterval = Math.max(
3252
1904
  1,
3253
1905
  Math.trunc(options.progressInterval ?? 500)
3254
1906
  );
3255
1907
  const onProgress = options.onProgress;
1908
+ const summarizePartition = (partitionRows) => {
1909
+ const summary = summarizeAiPocketRows(partitionRows);
1910
+ const periodDays = getPeriodDays(partitionRows);
1911
+ return {
1912
+ rows: partitionRows.length,
1913
+ events: summary.events,
1914
+ periodDays,
1915
+ eventsPerDay: periodDays == null ? null : summary.events / periodDays
1916
+ };
1917
+ };
1918
+ const trainPartition = summarizePartition(rows);
1919
+ const validationPartition = summarizePartition(validationRows);
1920
+ const testPartition = summarizePartition(testRows);
1921
+ const cadenceProfile = cadenceProfileOption ?? {
1922
+ mode: "fixed",
1923
+ lowCadence: false,
1924
+ sparseSample: false,
1925
+ adaptiveThresholds: false,
1926
+ trainRows: trainPartition.rows,
1927
+ trainEvents: trainPartition.events,
1928
+ trainPeriodDays: trainPartition.periodDays,
1929
+ trainEventsPerDay: trainPartition.eventsPerDay,
1930
+ validationRows: validationPartition.rows,
1931
+ validationEvents: validationPartition.events,
1932
+ testRows: testPartition.rows,
1933
+ testEvents: testPartition.events,
1934
+ minSupport,
1935
+ minEvents,
1936
+ minValidationSupport,
1937
+ minValidationEvents,
1938
+ maxEventCountShare
1939
+ };
3256
1940
  const predicateResult = buildAiPocketPredicateResult(rows, {
3257
1941
  minSupport,
3258
1942
  maxCategories: options.maxCategories,
3259
1943
  progressInterval,
3260
1944
  onProgress
3261
1945
  });
3262
- const { predicates } = predicateResult;
1946
+ const predicates = predicateResult.predicates.filter((predicate) => {
1947
+ const family = classifyAiPocketCoverageFeaturePath(predicate.featureKey);
1948
+ return family == null || !excludedFeatureFamilies.includes(family);
1949
+ });
3263
1950
  let lastMaskProgress = 0;
3264
1951
  const emitMaskProgress = (current, done = false) => {
3265
1952
  if (!onProgress) {
@@ -3291,10 +1978,15 @@ var searchAiPockets = (rows, options = {}) => {
3291
1978
  [...predicatePool, ...negativePool, ...supportPool].forEach((predicate) => {
3292
1979
  predicatePoolById.set(predicate.id, predicate);
3293
1980
  });
3294
- const diversifiedPredicates = diversifyPredicatePool(
3295
- [...predicatePoolById.values()],
3296
- maxAtomicPredicates
3297
- );
1981
+ const diversifiedPredicates = prioritizeRequiredFeatureFamilyPredicates({
1982
+ selected: diversifyPredicatePool(
1983
+ [...predicatePoolById.values()],
1984
+ maxAtomicPredicates
1985
+ ),
1986
+ predicates: scoredPredicates,
1987
+ requiredFeatureFamilies,
1988
+ maximum: maxAtomicPredicates
1989
+ });
3298
1990
  const selectedPredicatePool = diversifiedPredicates.map(
3299
1991
  (predicate) => {
3300
1992
  const { mask, support } = buildMask(rows, predicate);
@@ -3335,6 +2027,13 @@ var searchAiPockets = (rows, options = {}) => {
3335
2027
  });
3336
2028
  };
3337
2029
  const addPocket = (pocketPredicates, mask) => {
2030
+ if (requiredFeatureFamilies.some(
2031
+ (family) => !pocketPredicates.some(
2032
+ (predicate) => classifyAiPocketCoverageFeaturePath(predicate.featureKey) === family
2033
+ )
2034
+ )) {
2035
+ return;
2036
+ }
3338
2037
  const pocket = createPocketResult(
3339
2038
  rows,
3340
2039
  pocketPredicates,
@@ -3452,7 +2151,7 @@ var searchAiPockets = (rows, options = {}) => {
3452
2151
  negativePockets: [...negativePockets.values()].sort(compareNegativePockets).slice(0, top),
3453
2152
  stats: {
3454
2153
  rows: rows.length,
3455
- featureKeys: predicateResult.featureKeys,
2154
+ featureKeys: new Set(predicates.map((predicate) => predicate.featureKey)).size,
3456
2155
  predicates: predicates.length,
3457
2156
  atomicPredicatesUsed: selectedPredicatePool.length,
3458
2157
  estimatedCombinations,
@@ -3467,6 +2166,9 @@ var searchAiPockets = (rows, options = {}) => {
3467
2166
  )
3468
2167
  )
3469
2168
  ],
2169
+ requiredFeatureFamilies,
2170
+ excludedFeatureFamilies,
2171
+ cadence: cadenceProfile,
3470
2172
  truncated
3471
2173
  }
3472
2174
  };
@@ -3528,16 +2230,20 @@ var pocketRows = (pockets) => pockets.map((pocket, index) => [
3528
2230
  pocket.objectiveSummary ? formatMdNumber(pocket.objectiveSummary.totalProfit) : "n/a",
3529
2231
  formatMdNumber(pocket.summary.maxDrawdown),
3530
2232
  pocket.validationSummary?.support ?? "n/a",
2233
+ pocket.validationSummary?.events ?? "n/a",
3531
2234
  pocket.validationSummary ? formatMdPercent(pocket.validationSummary.winRate) : "n/a",
3532
2235
  pocket.validationSummary ? formatMdNumber(pocket.validationSummary.profitFactor) : "n/a",
3533
2236
  pocket.validationSummary ? formatMdNumber(pocket.validationSummary.totalProfit) : "n/a",
3534
2237
  pocket.testSummary?.support ?? "n/a",
2238
+ pocket.testSummary?.events ?? "n/a",
3535
2239
  pocket.testSummary ? formatMdNumber(pocket.testSummary.profitFactor) : "n/a",
3536
2240
  pocket.testSummary ? formatMdNumber(pocket.testSummary.totalProfit) : "n/a",
3537
2241
  pocket.testObjectiveSummary ? formatMdNumber(pocket.testObjectiveSummary.totalProfit) : "n/a",
3538
2242
  formatMdNumber(pocket.summary.avgTradesPerDay),
3539
2243
  pocket.summary.losingMonths,
3540
2244
  formatMdNumber(pocket.score),
2245
+ pocket.readiness,
2246
+ pocket.readinessReasons.join("; ") || "none",
3541
2247
  pocket.condition
3542
2248
  ]);
3543
2249
  var buildAiPocketMarkdownReport = ({
@@ -3545,6 +2251,7 @@ var buildAiPocketMarkdownReport = ({
3545
2251
  run,
3546
2252
  currentGate,
3547
2253
  pocketSearch,
2254
+ coverageSearches = [],
3548
2255
  errors
3549
2256
  }) => {
3550
2257
  const generatedIso = new Date(generatedAt).toISOString();
@@ -3555,6 +2262,34 @@ var buildAiPocketMarkdownReport = ({
3555
2262
  audit?.paths ?? 0,
3556
2263
  audit?.samples.join(", ") ?? ""
3557
2264
  ]);
2265
+ const pocketTableHeaders = [
2266
+ "#",
2267
+ "N",
2268
+ "Events",
2269
+ "Max batch",
2270
+ "Support",
2271
+ "WR",
2272
+ "PF",
2273
+ "PNL",
2274
+ "Objective PNL",
2275
+ "Max DD",
2276
+ "Val N",
2277
+ "Val Events",
2278
+ "Val WR",
2279
+ "Val PF",
2280
+ "Val PNL",
2281
+ "Test N",
2282
+ "Test Events",
2283
+ "Test PF",
2284
+ "Test PNL",
2285
+ "Test objective PNL",
2286
+ "Trades/Day",
2287
+ "Losing Months",
2288
+ "Score",
2289
+ "Readiness",
2290
+ "Readiness reasons",
2291
+ "Pocket"
2292
+ ];
3558
2293
  const lines = [
3559
2294
  "# AI Pocket Search Report",
3560
2295
  "",
@@ -3578,6 +2313,17 @@ var buildAiPocketMarkdownReport = ({
3578
2313
  ["test_rows", run.testRows],
3579
2314
  ["validation_split", formatMdPercent(run.validationSplit)],
3580
2315
  ["test_split", formatMdPercent(run.testSplit)],
2316
+ ["test_sealed", run.sealedTest?.sealed ? "yes" : "no"],
2317
+ ["sealed_test_rows", run.sealedTest?.rows ?? run.testRows],
2318
+ ["sealed_test_events", run.sealedTest?.events ?? "n/a"],
2319
+ [
2320
+ "sealed_test_start",
2321
+ run.sealedTest?.startTimestamp == null ? "n/a" : new Date(run.sealedTest.startTimestamp).toISOString()
2322
+ ],
2323
+ [
2324
+ "sealed_test_end",
2325
+ run.sealedTest?.endTimestamp == null ? "n/a" : new Date(run.sealedTest.endTimestamp).toISOString()
2326
+ ],
3581
2327
  ["min_validation_support", run.minValidationSupport],
3582
2328
  ["failed", run.failed],
3583
2329
  ["recent", run.recent === 0 ? "all" : run.recent],
@@ -3619,6 +2365,22 @@ var buildAiPocketMarkdownReport = ({
3619
2365
  ["include_gate_context", run.includeGateContext ? "on" : "off"],
3620
2366
  ["feature_profile", run.featureProfile ?? "all"],
3621
2367
  ["feature_policy", run.featurePolicy ?? "all"],
2368
+ ["coverage_mode", run.coverageMode ?? "full"],
2369
+ ["cadence_mode", run.cadenceMode ?? "fixed"],
2370
+ ["low_cadence", pocketSearch.stats.cadence.lowCadence ? "yes" : "no"],
2371
+ [
2372
+ "sparse_sample",
2373
+ pocketSearch.stats.cadence.sparseSample ? "yes" : "no"
2374
+ ],
2375
+ [
2376
+ "adaptive_thresholds",
2377
+ pocketSearch.stats.cadence.adaptiveThresholds ? "on" : "off"
2378
+ ],
2379
+ ["train_events", pocketSearch.stats.cadence.trainEvents],
2380
+ [
2381
+ "train_events_per_day",
2382
+ formatMdNumber(pocketSearch.stats.cadence.trainEventsPerDay, 4)
2383
+ ],
3622
2384
  ["report_path", run.reportPath]
3623
2385
  ]
3624
2386
  ),
@@ -3704,10 +2466,32 @@ var buildAiPocketMarkdownReport = ({
3704
2466
  ["predicates", pocketSearch.stats.predicates],
3705
2467
  ["atomic_used", pocketSearch.stats.atomicPredicatesUsed],
3706
2468
  ["feature_families", pocketSearch.stats.featureFamiliesUsed.join(", ")],
2469
+ [
2470
+ "required_feature_families",
2471
+ pocketSearch.stats.requiredFeatureFamilies.join(", ") || "none"
2472
+ ],
2473
+ [
2474
+ "excluded_feature_families",
2475
+ pocketSearch.stats.excludedFeatureFamilies.join(", ") || "none"
2476
+ ],
3707
2477
  ["estimated_combinations", pocketSearch.stats.estimatedCombinations],
3708
2478
  ["combinations_evaluated", pocketSearch.stats.combinationsEvaluated],
3709
2479
  ["validation_rows", pocketSearch.stats.validationRows],
3710
2480
  ["test_rows", pocketSearch.stats.testRows],
2481
+ ["effective_min_support", pocketSearch.stats.cadence.minSupport],
2482
+ ["effective_min_events", pocketSearch.stats.cadence.minEvents],
2483
+ [
2484
+ "effective_min_validation_support",
2485
+ pocketSearch.stats.cadence.minValidationSupport
2486
+ ],
2487
+ [
2488
+ "effective_min_validation_events",
2489
+ pocketSearch.stats.cadence.minValidationEvents
2490
+ ],
2491
+ [
2492
+ "effective_max_event_count_share",
2493
+ formatMdPercent(pocketSearch.stats.cadence.maxEventCountShare)
2494
+ ],
3711
2495
  [
3712
2496
  "duplicate_pockets_skipped",
3713
2497
  pocketSearch.stats.duplicatePocketsSkipped
@@ -3718,65 +2502,98 @@ var buildAiPocketMarkdownReport = ({
3718
2502
  "",
3719
2503
  "## Top Positive Pockets",
3720
2504
  "",
3721
- markdownTable(
3722
- [
3723
- "#",
3724
- "N",
3725
- "Events",
3726
- "Max batch",
3727
- "Support",
3728
- "WR",
3729
- "PF",
3730
- "PNL",
3731
- "Objective PNL",
3732
- "Max DD",
3733
- "Val N",
3734
- "Val WR",
3735
- "Val PF",
3736
- "Val PNL",
3737
- "Test N",
3738
- "Test PF",
3739
- "Test PNL",
3740
- "Test objective PNL",
3741
- "Trades/Day",
3742
- "Losing Months",
3743
- "Score",
3744
- "Pocket"
3745
- ],
3746
- pocketRows(pocketSearch.positivePockets)
3747
- ),
2505
+ markdownTable(pocketTableHeaders, pocketRows(pocketSearch.positivePockets)),
3748
2506
  "",
3749
2507
  "## Top Loss Pockets",
3750
2508
  "",
3751
- markdownTable(
3752
- [
3753
- "#",
3754
- "N",
3755
- "Events",
3756
- "Max batch",
3757
- "Support",
3758
- "WR",
3759
- "PF",
3760
- "PNL",
3761
- "Objective PNL",
3762
- "Max DD",
3763
- "Val N",
3764
- "Val WR",
3765
- "Val PF",
3766
- "Val PNL",
3767
- "Test N",
3768
- "Test PF",
3769
- "Test PNL",
3770
- "Test objective PNL",
3771
- "Trades/Day",
3772
- "Losing Months",
3773
- "Score",
3774
- "Pocket"
3775
- ],
3776
- pocketRows(pocketSearch.negativePockets)
3777
- ),
2509
+ markdownTable(pocketTableHeaders, pocketRows(pocketSearch.negativePockets)),
3778
2510
  ""
3779
2511
  ];
2512
+ for (const cohort of coverageSearches) {
2513
+ const title = cohort.family === "cmc" ? "CMC" : "Coinalyze";
2514
+ lines.push(
2515
+ `## Coverage Cohort: ${title}`,
2516
+ "",
2517
+ markdownTable(
2518
+ ["Field", "Value"],
2519
+ [
2520
+ ["coverage_rows", cohort.coverage.rows],
2521
+ ["coverage_row_ratio", formatMdPercent(cohort.coverage.rowRatio)],
2522
+ ["coverage_events", cohort.coverage.events],
2523
+ ["coverage_event_ratio", formatMdPercent(cohort.coverage.eventRatio)],
2524
+ [
2525
+ "coverage_from",
2526
+ cohort.coverage.minTimestamp == null ? "n/a" : new Date(cohort.coverage.minTimestamp).toISOString()
2527
+ ],
2528
+ [
2529
+ "coverage_to",
2530
+ cohort.coverage.maxTimestamp == null ? "n/a" : new Date(cohort.coverage.maxTimestamp).toISOString()
2531
+ ],
2532
+ ["scope_rows", cohort.scopeRows],
2533
+ ["train_rows", cohort.trainRows],
2534
+ ["validation_rows", cohort.validationRows],
2535
+ ["test_rows", cohort.testRows],
2536
+ [
2537
+ "low_cadence",
2538
+ cohort.search.stats.cadence.lowCadence ? "yes" : "no"
2539
+ ],
2540
+ [
2541
+ "sparse_sample",
2542
+ cohort.search.stats.cadence.sparseSample ? "yes" : "no"
2543
+ ],
2544
+ [
2545
+ "adaptive_thresholds",
2546
+ cohort.search.stats.cadence.adaptiveThresholds ? "on" : "off"
2547
+ ],
2548
+ ["train_events", cohort.search.stats.cadence.trainEvents],
2549
+ [
2550
+ "train_events_per_day",
2551
+ formatMdNumber(cohort.search.stats.cadence.trainEventsPerDay, 4)
2552
+ ],
2553
+ ["effective_min_support", cohort.search.stats.cadence.minSupport],
2554
+ ["effective_min_events", cohort.search.stats.cadence.minEvents],
2555
+ [
2556
+ "effective_min_validation_support",
2557
+ cohort.search.stats.cadence.minValidationSupport
2558
+ ],
2559
+ [
2560
+ "effective_min_validation_events",
2561
+ cohort.search.stats.cadence.minValidationEvents
2562
+ ],
2563
+ [
2564
+ "effective_max_event_count_share",
2565
+ formatMdPercent(cohort.search.stats.cadence.maxEventCountShare)
2566
+ ],
2567
+ [
2568
+ "required_feature_families",
2569
+ cohort.search.stats.requiredFeatureFamilies.join(", ") || "none"
2570
+ ]
2571
+ ]
2572
+ ),
2573
+ "",
2574
+ `### ${title} Train Baseline`,
2575
+ "",
2576
+ markdownTable(
2577
+ ["Metric", "Value"],
2578
+ summaryMetricRows(cohort.search.baseline)
2579
+ ),
2580
+ "",
2581
+ `### ${title} Top Positive Pockets`,
2582
+ "",
2583
+ markdownTable(
2584
+ pocketTableHeaders,
2585
+ pocketRows(cohort.search.positivePockets)
2586
+ ),
2587
+ "",
2588
+ `### ${title} Top Loss Pockets`,
2589
+ "",
2590
+ markdownTable(
2591
+ pocketTableHeaders,
2592
+ pocketRows(cohort.search.negativePockets)
2593
+ ),
2594
+ ""
2595
+ );
2596
+ }
3780
2597
  if (errors.length) {
3781
2598
  lines.push("## Errors", "", ...errors.map((error) => `- ${error}`), "");
3782
2599
  }
@@ -3785,6 +2602,90 @@ var buildAiPocketMarkdownReport = ({
3785
2602
  };
3786
2603
 
3787
2604
  // src/lib/aiPocketSearchCli.ts
2605
+ var DAY_MS3 = 24 * 60 * 60 * 1e3;
2606
+ var DEFAULT_MIN_SUPPORT = 20;
2607
+ var LOW_CADENCE_EVENT_LIMIT = 200;
2608
+ var LOW_CADENCE_MAX_EVENT_SHARE = 1 / 3;
2609
+ var countIndependentEvents = (rows) => {
2610
+ const timestampEvents = /* @__PURE__ */ new Set();
2611
+ let rowsWithoutTimestamp = 0;
2612
+ for (const row of rows) {
2613
+ if (typeof row.timestamp === "number" && Number.isFinite(row.timestamp)) {
2614
+ timestampEvents.add(row.timestamp);
2615
+ } else {
2616
+ rowsWithoutTimestamp += 1;
2617
+ }
2618
+ }
2619
+ return timestampEvents.size + rowsWithoutTimestamp;
2620
+ };
2621
+ var getPeriodDays2 = (rows) => {
2622
+ let minTimestamp = null;
2623
+ let maxTimestamp = null;
2624
+ for (const row of rows) {
2625
+ const timestamp = row.timestamp;
2626
+ if (typeof timestamp !== "number" || !Number.isFinite(timestamp)) {
2627
+ continue;
2628
+ }
2629
+ minTimestamp = minTimestamp == null ? timestamp : Math.min(minTimestamp, timestamp);
2630
+ maxTimestamp = maxTimestamp == null ? timestamp : Math.max(maxTimestamp, timestamp);
2631
+ }
2632
+ if (minTimestamp == null || maxTimestamp == null) {
2633
+ return null;
2634
+ }
2635
+ return Math.max((maxTimestamp - minTimestamp) / DAY_MS3, 1);
2636
+ };
2637
+ var clampInt = (value, minimum, maximum) => Math.max(minimum, Math.min(maximum, Math.ceil(value)));
2638
+ var resolveAiPocketCadenceProfile = ({
2639
+ trainRows,
2640
+ validationRows = [],
2641
+ testRows = [],
2642
+ mode = "auto",
2643
+ validationSplit = 0.25,
2644
+ minSupport,
2645
+ minEvents,
2646
+ minValidationSupport,
2647
+ minValidationEvents,
2648
+ maxEventCountShare = 0.25,
2649
+ explicitMaxEventCountShare = false
2650
+ }) => {
2651
+ const trainEvents = countIndependentEvents(trainRows);
2652
+ const validationEvents = countIndependentEvents(validationRows);
2653
+ const testEvents = countIndependentEvents(testRows);
2654
+ const trainPeriodDays = getPeriodDays2(trainRows);
2655
+ const trainEventsPerDay = trainPeriodDays == null ? null : trainEvents / trainPeriodDays;
2656
+ const sparseSample = trainEvents < LOW_CADENCE_EVENT_LIMIT;
2657
+ const lowCadence = trainEventsPerDay != null && trainEventsPerDay < 0.25;
2658
+ const adaptiveSample = mode === "auto" && sparseSample;
2659
+ const adaptiveThresholds = adaptiveSample && (minSupport == null || minEvents == null || validationRows.length > 0 && (minValidationSupport == null || minValidationEvents == null) || !explicitMaxEventCountShare);
2660
+ const resolvedMinSupport = minSupport ?? (adaptiveSample ? clampInt(trainEvents * 0.1, 3, DEFAULT_MIN_SUPPORT) : DEFAULT_MIN_SUPPORT);
2661
+ const resolvedMinEvents = minEvents ?? (minSupport != null || !adaptiveSample ? Math.max(5, Math.ceil(resolvedMinSupport * 0.5)) : clampInt(resolvedMinSupport * 0.5, 3, 10));
2662
+ const hasValidation = validationRows.length > 0;
2663
+ const resolvedMinValidationSupport = minValidationSupport ?? (hasValidation ? Math.max(3, Math.ceil(resolvedMinSupport * validationSplit * 0.5)) : 0);
2664
+ const resolvedMinValidationEvents = minValidationEvents ?? (hasValidation ? Math.max(
2665
+ adaptiveSample ? 3 : 2,
2666
+ Math.ceil(resolvedMinEvents * validationSplit * 0.5)
2667
+ ) : 0);
2668
+ const resolvedMaxEventCountShare = adaptiveSample && !explicitMaxEventCountShare ? Math.max(maxEventCountShare, LOW_CADENCE_MAX_EVENT_SHARE) : maxEventCountShare;
2669
+ return {
2670
+ mode,
2671
+ lowCadence,
2672
+ sparseSample,
2673
+ adaptiveThresholds,
2674
+ trainRows: trainRows.length,
2675
+ trainEvents,
2676
+ trainPeriodDays,
2677
+ trainEventsPerDay,
2678
+ validationRows: validationRows.length,
2679
+ validationEvents,
2680
+ testRows: testRows.length,
2681
+ testEvents,
2682
+ minSupport: resolvedMinSupport,
2683
+ minEvents: resolvedMinEvents,
2684
+ minValidationSupport: resolvedMinValidationSupport,
2685
+ minValidationEvents: resolvedMinValidationEvents,
2686
+ maxEventCountShare: resolvedMaxEventCountShare
2687
+ };
2688
+ };
3788
2689
  var AI_POCKET_SEARCH_CLI_DECIMAL_DEFAULTS = {
3789
2690
  minProfitFactor: "1.2",
3790
2691
  minWinRate: "0",
@@ -3831,6 +2732,29 @@ var splitAiPocketResearchRowsByTimestamp = (rows, validationSplit, testSplit = 0
3831
2732
  testRows: rows.filter((row) => isIn(testTimestamps, row.timestamp))
3832
2733
  };
3833
2734
  };
2735
+ var splitAiPocketCoverageRowsByTimestamp = (rows, family, validationSplit, testSplit = 0) => splitAiPocketResearchRowsByTimestamp(
2736
+ rows.filter((row) => row.featureCoverage?.[family] === true),
2737
+ validationSplit,
2738
+ testSplit
2739
+ );
2740
+ var sealAiPocketTestPartition = (split, sealed) => {
2741
+ const finiteTimestamps = split.testRows.map((row) => row.timestamp).filter((timestamp) => Number.isFinite(timestamp));
2742
+ return {
2743
+ discoveryRows: [
2744
+ ...split.trainRows,
2745
+ ...split.validationRows,
2746
+ ...sealed ? [] : split.testRows
2747
+ ],
2748
+ searchTestRows: sealed ? [] : split.testRows,
2749
+ evidence: {
2750
+ sealed,
2751
+ rows: split.testRows.length,
2752
+ events: countIndependentEvents(split.testRows),
2753
+ startTimestamp: finiteTimestamps.length ? Math.min(...finiteTimestamps) : null,
2754
+ endTimestamp: finiteTimestamps.length ? Math.max(...finiteTimestamps) : null
2755
+ }
2756
+ };
2757
+ };
3834
2758
  var readAiPocketSearchCliOption = ({
3835
2759
  argv,
3836
2760
  longName,
@@ -3850,7 +2774,7 @@ var readAiPocketSearchCliOption = ({
3850
2774
  };
3851
2775
 
3852
2776
  // src/scripts/aiPocketSearch.ts
3853
- var ListIt = require_list_it();
2777
+ var ListIt = require("list-it");
3854
2778
  import_args.default.example(
3855
2779
  "yarn ai-pocket-search --strategy LiquidityZones -n 0 --maxDepth 2 --minSupport 25",
3856
2780
  "Search deterministic AI-gate pockets over the latest LiquidityZones AI export"
@@ -3904,7 +2828,11 @@ import_args.default.option(
3904
2828
  ""
3905
2829
  );
3906
2830
  import_args.default.option(["d", "maxDepth"], "Maximum predicate-combination depth", 2);
3907
- import_args.default.option(["m", "minSupport"], "Minimum rows required for a pocket", 20);
2831
+ import_args.default.option(
2832
+ ["m", "minSupport"],
2833
+ "Minimum rows override; cadence auto derives it when omitted",
2834
+ 20
2835
+ );
3908
2836
  import_args.default.option(
3909
2837
  ["F", "minProfitFactor"],
3910
2838
  "Minimum profit factor required for positive pockets",
@@ -3940,6 +2868,11 @@ import_args.default.option(
3940
2868
  "Trailing timestamp-grouped scope share withheld as untouched test",
3941
2869
  AI_POCKET_SEARCH_CLI_DECIMAL_DEFAULTS.testSplit
3942
2870
  );
2871
+ import_args.default.option(
2872
+ ["w", "sealTest"],
2873
+ "Reserve test bounds without exposing its rows or economics to discovery",
2874
+ false
2875
+ );
3943
2876
  import_args.default.option(
3944
2877
  ["N", "minValidationSupport"],
3945
2878
  "Minimum validation rows required for positive pockets (0 = auto)",
@@ -4007,6 +2940,16 @@ import_args.default.option(
4007
2940
  "Feature policy: causal-stationary or all",
4008
2941
  "causal-stationary"
4009
2942
  );
2943
+ import_args.default.option(
2944
+ ["Q", "coverageMode"],
2945
+ "Coverage-aware search mode: auto or full",
2946
+ "auto"
2947
+ );
2948
+ import_args.default.option(
2949
+ ["c", "cadenceMode"],
2950
+ "Cadence thresholds: auto adapts discovery support, fixed keeps legacy defaults",
2951
+ "auto"
2952
+ );
4010
2953
  import_args.default.option(
4011
2954
  ["r", "reportDir"],
4012
2955
  "Directory for generated Markdown reports",
@@ -4128,6 +3071,24 @@ var normalizeFeaturePolicy = (value) => {
4128
3071
  }
4129
3072
  return normalized;
4130
3073
  };
3074
+ var normalizeCoverageMode = (value) => {
3075
+ const normalized = String(value || "auto").trim().toLowerCase();
3076
+ if (!["auto", "full"].includes(normalized)) {
3077
+ throw new Error(
3078
+ `Unsupported --coverageMode "${normalized}". Use auto or full.`
3079
+ );
3080
+ }
3081
+ return normalized;
3082
+ };
3083
+ var normalizeCadenceMode = (value) => {
3084
+ const normalized = String(value || "auto").trim().toLowerCase();
3085
+ if (!["auto", "fixed"].includes(normalized)) {
3086
+ throw new Error(
3087
+ `Unsupported --cadenceMode "${normalized}". Use auto or fixed.`
3088
+ );
3089
+ }
3090
+ return normalized;
3091
+ };
4131
3092
  var normalizeObjective = (value, scope) => {
4132
3093
  const normalized = String(value || "auto").trim().toLowerCase();
4133
3094
  if (normalized === "auto") {
@@ -4355,16 +3316,20 @@ var buildPocketRows = (pockets) => pockets.map((pocket, index) => [
4355
3316
  pocket.objectiveSummary ? colorizeProfit(pocket.objectiveSummary.totalProfit) : import_chalk.default.gray("n/a"),
4356
3317
  colorizeProfit(-pocket.summary.maxDrawdown),
4357
3318
  pocket.validationSummary ? import_chalk.default.cyan(String(pocket.validationSummary.support)) : import_chalk.default.gray("n/a"),
3319
+ pocket.validationSummary ? import_chalk.default.cyan(String(pocket.validationSummary.events)) : import_chalk.default.gray("n/a"),
4358
3320
  pocket.validationSummary ? colorizeRatio(pocket.validationSummary.winRate) : import_chalk.default.gray("n/a"),
4359
3321
  pocket.validationSummary ? colorizeNumber(pocket.validationSummary.profitFactor) : import_chalk.default.gray("n/a"),
4360
3322
  pocket.validationSummary ? colorizeProfit(pocket.validationSummary.totalProfit) : import_chalk.default.gray("n/a"),
4361
3323
  pocket.testSummary ? import_chalk.default.cyan(String(pocket.testSummary.support)) : import_chalk.default.gray("n/a"),
3324
+ pocket.testSummary ? import_chalk.default.cyan(String(pocket.testSummary.events)) : import_chalk.default.gray("n/a"),
4362
3325
  pocket.testSummary ? colorizeNumber(pocket.testSummary.profitFactor) : import_chalk.default.gray("n/a"),
4363
3326
  pocket.testSummary ? colorizeProfit(pocket.testSummary.totalProfit) : import_chalk.default.gray("n/a"),
4364
3327
  pocket.testObjectiveSummary ? colorizeProfit(pocket.testObjectiveSummary.totalProfit) : import_chalk.default.gray("n/a"),
4365
3328
  colorizeNumber(pocket.summary.avgTradesPerDay),
4366
3329
  import_chalk.default.yellow(String(pocket.summary.losingMonths)),
4367
3330
  colorizeNumber(pocket.score),
3331
+ pocket.readiness === "production-candidate" ? import_chalk.default.green(pocket.readiness) : import_chalk.default.yellow(pocket.readiness),
3332
+ pocket.readinessReasons.length ? import_chalk.default.yellow(pocket.readinessReasons.join("; ")) : import_chalk.default.gray("none"),
4368
3333
  pocket.condition
4369
3334
  ]);
4370
3335
  var buildQualityRows = (qualityThresholds) => qualityThresholds.map(({ label, summary }) => [
@@ -4424,7 +3389,7 @@ var main = async () => {
4424
3389
  );
4425
3390
  }
4426
3391
  const maxDepth = normalizePositiveInt(flags.maxDepth, 2);
4427
- const minSupport = normalizePositiveInt(flags.minSupport, 20);
3392
+ const explicitMinSupport = hasCliOption2("minSupport", "m") ? normalizePositiveInt(flags.minSupport, 20) : void 0;
4428
3393
  const minProfitFactor = normalizeNonNegativeNumber(
4429
3394
  readAiPocketSearchCliOption({
4430
3395
  argv: process.argv,
@@ -4468,6 +3433,10 @@ var main = async () => {
4468
3433
  }) ?? flags.testSplit,
4469
3434
  0
4470
3435
  ) : 0;
3436
+ const sealTest = Boolean(flags.sealTest);
3437
+ if (sealTest && testSplit <= 0) {
3438
+ throw new Error("--sealTest requires a positive --testSplit");
3439
+ }
4471
3440
  const explicitMinValidationSupport = normalizeInt(
4472
3441
  flags.minValidationSupport,
4473
3442
  0
@@ -4505,6 +3474,8 @@ var main = async () => {
4505
3474
  const includeGateContext = Boolean(flags.includeGateContext);
4506
3475
  const featureProfile = normalizeFeatureProfile(flags.featureProfile);
4507
3476
  const featurePolicy = normalizeFeaturePolicy(flags.featurePolicy);
3477
+ const coverageMode = normalizeCoverageMode(flags.coverageMode);
3478
+ const cadenceMode = normalizeCadenceMode(flags.cadenceMode);
4508
3479
  const jsonOutput = Boolean(flags.json);
4509
3480
  const outputPath = String(flags.output || "").trim();
4510
3481
  const reportDir = String(flags.reportDir || "data/ai/output").trim();
@@ -4598,6 +3569,19 @@ var main = async () => {
4598
3569
  const modelDirection = typeof analysis.direction === "string" && analysis.direction.trim() ? analysis.direction : null;
4599
3570
  const modelDirectionMatches = modelDirection === row.direction;
4600
3571
  const profit = Number(row.profit);
3572
+ const featureSnapshot = collectAiPocketFeatureSnapshot({
3573
+ payload,
3574
+ gateContext,
3575
+ includeSymbol,
3576
+ includeGateContext,
3577
+ featureProfile,
3578
+ featurePolicy,
3579
+ onFeatureExcluded: ({ path: featurePath, classification }) => {
3580
+ const paths = excludedFeaturePaths.get(classification) ?? /* @__PURE__ */ new Set();
3581
+ paths.add(featurePath);
3582
+ excludedFeaturePaths.set(classification, paths);
3583
+ }
3584
+ });
4601
3585
  rows.push({
4602
3586
  signalId: row.signalId,
4603
3587
  strategy: row.strategyName,
@@ -4610,19 +3594,8 @@ var main = async () => {
4610
3594
  quality,
4611
3595
  modelDirectionMatches,
4612
3596
  modelCandidate: getDeterministicModelCandidate(signal),
4613
- features: collectAiPocketFeatures({
4614
- payload,
4615
- gateContext,
4616
- includeSymbol,
4617
- includeGateContext,
4618
- featureProfile,
4619
- featurePolicy,
4620
- onFeatureExcluded: ({ path: featurePath, classification }) => {
4621
- const paths = excludedFeaturePaths.get(classification) ?? /* @__PURE__ */ new Set();
4622
- paths.add(featurePath);
4623
- excludedFeaturePaths.set(classification, paths);
4624
- }
4625
- })
3597
+ features: featureSnapshot.features,
3598
+ featureCoverage: featureSnapshot.featureCoverage
4626
3599
  });
4627
3600
  bar?.tick(1, {
4628
3601
  symbol: import_chalk.default.gray(row.symbol),
@@ -4644,86 +3617,188 @@ var main = async () => {
4644
3617
  });
4645
3618
  const directionRows = direction ? rows.filter((row) => row.direction === direction) : rows;
4646
3619
  const scopeRows = resolveScopeRows(directionRows, scope);
4647
- const split = splitAiPocketResearchRowsByTimestamp(
3620
+ const fullSplit = splitAiPocketResearchRowsByTimestamp(
4648
3621
  directionRows,
4649
3622
  validationSplit,
4650
3623
  testSplit
4651
3624
  );
4652
- const trainRows = resolveScopeRows(split.trainRows, scope);
4653
- const validationRows = resolveScopeRows(split.validationRows, scope);
4654
- const testRows = resolveScopeRows(split.testRows, scope);
4655
- const baselineRows = split.trainRows.filter((row) => row.aiApproved);
4656
- const validationBaselineRows = split.validationRows.filter(
3625
+ const sealedFullSplit = sealAiPocketTestPartition(fullSplit, sealTest);
3626
+ const discoveryRows = sealedFullSplit.discoveryRows;
3627
+ const trainRows = resolveScopeRows(fullSplit.trainRows, scope);
3628
+ const validationRows = resolveScopeRows(fullSplit.validationRows, scope);
3629
+ const testRows = resolveScopeRows(sealedFullSplit.searchTestRows, scope);
3630
+ const baselineRows = fullSplit.trainRows.filter((row) => row.aiApproved);
3631
+ const validationBaselineRows = fullSplit.validationRows.filter(
4657
3632
  (row) => row.aiApproved
4658
3633
  );
4659
- const testBaselineRows = split.testRows.filter((row) => row.aiApproved);
4660
- const minValidationSupport = explicitMinValidationSupport > 0 ? explicitMinValidationSupport : validationRows.length ? Math.max(3, Math.ceil(minSupport * validationSplit * 0.5)) : 0;
4661
- const minEvents = explicitMinEvents > 0 ? explicitMinEvents : Math.max(5, Math.ceil(minSupport * 0.5));
4662
- const minValidationEvents = explicitMinValidationEvents > 0 ? explicitMinValidationEvents : validationRows.length ? Math.max(2, Math.ceil(minEvents * validationSplit * 0.5)) : 0;
4663
- const currentGateSummary = summarizeAiTrainEvaluations(rows);
4664
- const currentGateQualityThresholds = summarizeAiTrainEvaluationsByQualityThreshold(rows, qualityThresholds);
4665
- let searchBar = null;
4666
- let searchBarPhase = null;
4667
- const search = searchAiPockets(trainRows, {
4668
- minSupport,
4669
- minProfitFactor,
4670
- minTotalProfit,
4671
- minWinRate,
4672
- maxDepth,
4673
- maxAtomicPredicates,
4674
- maxCombinations,
4675
- top,
4676
- validationRows,
4677
- testRows,
4678
- minValidationSupport,
4679
- minEvents,
4680
- minValidationEvents,
4681
- ...maxBatch > 0 ? { maxBatch } : {},
4682
- maxEventCountShare,
4683
- maxSymbolCountShare,
4684
- objective,
4685
- baselineRows,
4686
- validationBaselineRows,
4687
- testBaselineRows,
4688
- allowRiskRegression,
4689
- requireValidationEligibility,
4690
- dedupeEquivalentSelections,
4691
- progressInterval: 250,
4692
- onProgress: (progress) => {
4693
- if (searchBar && searchBarPhase !== progress.phase) {
4694
- tickProgressBarTo(searchBar, searchBar.total, {
4695
- status: import_chalk.default.gray("done")
3634
+ const testBaselineRows = sealedFullSplit.searchTestRows.filter(
3635
+ (row) => row.aiApproved
3636
+ );
3637
+ const currentGateSummary = summarizeAiTrainEvaluations(discoveryRows);
3638
+ const currentGateQualityThresholds = summarizeAiTrainEvaluationsByQualityThreshold(
3639
+ discoveryRows,
3640
+ qualityThresholds
3641
+ );
3642
+ const runSearch = ({
3643
+ label,
3644
+ train,
3645
+ validation,
3646
+ test,
3647
+ trainBaseline,
3648
+ validationBaseline,
3649
+ testBaseline,
3650
+ requiredFeatureFamilies = [],
3651
+ excludedFeatureFamilies = []
3652
+ }) => {
3653
+ const cadenceProfile = resolveAiPocketCadenceProfile({
3654
+ trainRows: train,
3655
+ validationRows: validation,
3656
+ testRows: test,
3657
+ mode: cadenceMode,
3658
+ validationSplit,
3659
+ ...explicitMinSupport != null ? { minSupport: explicitMinSupport } : {},
3660
+ ...explicitMinEvents > 0 ? { minEvents: explicitMinEvents } : {},
3661
+ ...explicitMinValidationSupport > 0 ? { minValidationSupport: explicitMinValidationSupport } : {},
3662
+ ...explicitMinValidationEvents > 0 ? { minValidationEvents: explicitMinValidationEvents } : {},
3663
+ maxEventCountShare,
3664
+ explicitMaxEventCountShare: hasCliOption2("maxEventCountShare", "U")
3665
+ });
3666
+ let searchBar = null;
3667
+ let searchBarPhase = null;
3668
+ return searchAiPockets(train, {
3669
+ minSupport: cadenceProfile.minSupport,
3670
+ minProfitFactor,
3671
+ minTotalProfit,
3672
+ minWinRate,
3673
+ maxDepth,
3674
+ maxAtomicPredicates,
3675
+ maxCombinations,
3676
+ top,
3677
+ validationRows: validation,
3678
+ testRows: test,
3679
+ minValidationSupport: cadenceProfile.minValidationSupport,
3680
+ minEvents: cadenceProfile.minEvents,
3681
+ minValidationEvents: cadenceProfile.minValidationEvents,
3682
+ ...maxBatch > 0 ? { maxBatch } : {},
3683
+ maxEventCountShare: cadenceProfile.maxEventCountShare,
3684
+ maxSymbolCountShare,
3685
+ objective,
3686
+ baselineRows: trainBaseline,
3687
+ validationBaselineRows: validationBaseline,
3688
+ testBaselineRows: testBaseline,
3689
+ allowRiskRegression,
3690
+ requireValidationEligibility,
3691
+ dedupeEquivalentSelections,
3692
+ requiredFeatureFamilies,
3693
+ excludedFeatureFamilies,
3694
+ cadenceProfile,
3695
+ progressInterval: 250,
3696
+ onProgress: (progress) => {
3697
+ if (searchBar && searchBarPhase !== progress.phase) {
3698
+ tickProgressBarTo(searchBar, searchBar.total, {
3699
+ status: import_chalk.default.gray("done")
3700
+ });
3701
+ searchBar = null;
3702
+ }
3703
+ if (!searchBar) {
3704
+ searchBarPhase = progress.phase;
3705
+ const phaseLabel = searchPhaseLabels[progress.phase].padEnd(8, " ");
3706
+ console.error(
3707
+ import_chalk.default.gray(
3708
+ `stage: ${label}/${searchPhaseLabels[progress.phase]} (${progress.total})`
3709
+ )
3710
+ );
3711
+ searchBar = new import_progress.default(
3712
+ `${phaseLabel} :current/:total [:bar] :percent :status`,
3713
+ {
3714
+ total: Math.max(progress.total, 1),
3715
+ width: 20,
3716
+ stream: process.stderr
3717
+ }
3718
+ );
3719
+ }
3720
+ tickProgressBarTo(searchBar, progress.current, {
3721
+ status: progress.truncated ? import_chalk.default.yellow("truncated") : "running"
4696
3722
  });
4697
- searchBar = null;
4698
- }
4699
- if (!searchBar) {
4700
- searchBarPhase = progress.phase;
4701
- const label = searchPhaseLabels[progress.phase].padEnd(8, " ");
4702
- console.error(
4703
- import_chalk.default.gray(
4704
- `stage: ${searchPhaseLabels[progress.phase]} (${progress.total})`
4705
- )
4706
- );
4707
- searchBar = new import_progress.default(
4708
- `${label} :current/:total [:bar] :percent :status`,
4709
- {
4710
- total: Math.max(progress.total, 1),
4711
- width: 20,
4712
- stream: process.stderr
4713
- }
4714
- );
3723
+ if (progress.done) {
3724
+ tickProgressBarTo(searchBar, searchBar.total, {
3725
+ status: progress.truncated ? import_chalk.default.yellow("truncated") : "done"
3726
+ });
3727
+ searchBar = null;
3728
+ }
4715
3729
  }
4716
- tickProgressBarTo(searchBar, progress.current, {
4717
- status: progress.truncated ? import_chalk.default.yellow("truncated") : "running"
3730
+ });
3731
+ };
3732
+ const search = runSearch({
3733
+ label: "full",
3734
+ train: trainRows,
3735
+ validation: validationRows,
3736
+ test: testRows,
3737
+ trainBaseline: baselineRows,
3738
+ validationBaseline: validationBaselineRows,
3739
+ testBaseline: testBaselineRows,
3740
+ ...coverageMode === "auto" ? {
3741
+ excludedFeatureFamilies: [
3742
+ "cmc",
3743
+ "coinalyze"
3744
+ ]
3745
+ } : {}
3746
+ });
3747
+ const coverageSearches = [];
3748
+ if (coverageMode === "auto") {
3749
+ for (const family of ["cmc", "coinalyze"]) {
3750
+ const cohortSplit = splitAiPocketCoverageRowsByTimestamp(
3751
+ directionRows,
3752
+ family,
3753
+ validationSplit,
3754
+ testSplit
3755
+ );
3756
+ const sealedCohortSplit = sealAiPocketTestPartition(
3757
+ cohortSplit,
3758
+ sealTest
3759
+ );
3760
+ const cohortTrainRows = resolveScopeRows(cohortSplit.trainRows, scope);
3761
+ const cohortValidationRows = resolveScopeRows(
3762
+ cohortSplit.validationRows,
3763
+ scope
3764
+ );
3765
+ const cohortTestRows = resolveScopeRows(
3766
+ sealedCohortSplit.searchTestRows,
3767
+ scope
3768
+ );
3769
+ const cohortSearch = runSearch({
3770
+ label: family,
3771
+ train: cohortTrainRows,
3772
+ validation: cohortValidationRows,
3773
+ test: cohortTestRows,
3774
+ trainBaseline: cohortSplit.trainRows.filter((row) => row.aiApproved),
3775
+ validationBaseline: cohortSplit.validationRows.filter(
3776
+ (row) => row.aiApproved
3777
+ ),
3778
+ testBaseline: sealedCohortSplit.searchTestRows.filter(
3779
+ (row) => row.aiApproved
3780
+ ),
3781
+ requiredFeatureFamilies: [family]
3782
+ });
3783
+ coverageSearches.push({
3784
+ family,
3785
+ coverage: summarizeAiPocketFeatureCoverage(
3786
+ sealedCohortSplit.discoveryRows,
3787
+ family
3788
+ ),
3789
+ scopeRows: resolveScopeRows(
3790
+ sealedCohortSplit.discoveryRows.filter(
3791
+ (row) => row.featureCoverage?.[family] === true
3792
+ ),
3793
+ scope
3794
+ ).length,
3795
+ trainRows: cohortTrainRows.length,
3796
+ validationRows: cohortValidationRows.length,
3797
+ testRows: cohortTestRows.length,
3798
+ search: cohortSearch
4718
3799
  });
4719
- if (progress.done) {
4720
- tickProgressBarTo(searchBar, searchBar.total, {
4721
- status: progress.truncated ? import_chalk.default.yellow("truncated") : "done"
4722
- });
4723
- searchBar = null;
4724
- }
4725
3800
  }
4726
- });
3801
+ }
4727
3802
  const result = {
4728
3803
  generatedAt,
4729
3804
  run: {
@@ -4752,6 +3827,25 @@ var main = async () => {
4752
3827
  includeGateContext,
4753
3828
  featureProfile,
4754
3829
  featurePolicy,
3830
+ coverageMode,
3831
+ cadenceMode,
3832
+ coverageSearches: coverageSearches.map(
3833
+ ({
3834
+ family,
3835
+ coverage,
3836
+ scopeRows: scopeRows2,
3837
+ trainRows: trainRows2,
3838
+ validationRows: validationRows2,
3839
+ testRows: testRows2
3840
+ }) => ({
3841
+ family,
3842
+ coverage,
3843
+ scopeRows: scopeRows2,
3844
+ trainRows: trainRows2,
3845
+ validationRows: validationRows2,
3846
+ testRows: testRows2
3847
+ })
3848
+ ),
4755
3849
  featurePolicyAudit: Object.fromEntries(
4756
3850
  [...excludedFeaturePaths.entries()].map(([classification, paths]) => [
4757
3851
  classification,
@@ -4764,26 +3858,27 @@ var main = async () => {
4764
3858
  objective,
4765
3859
  validationSplit,
4766
3860
  testSplit,
4767
- minValidationSupport,
3861
+ sealedTest: sealedFullSplit.evidence,
3862
+ minValidationSupport: search.stats.cadence.minValidationSupport,
4768
3863
  reportPath,
4769
3864
  search: {
4770
3865
  maxDepth,
4771
- minSupport,
3866
+ minSupport: search.stats.cadence.minSupport,
4772
3867
  minProfitFactor,
4773
3868
  minWinRate,
4774
3869
  minTotalProfit,
4775
3870
  maxAtomicPredicates,
4776
3871
  maxCombinations,
4777
- minEvents,
4778
- minValidationEvents,
3872
+ minEvents: search.stats.cadence.minEvents,
3873
+ minValidationEvents: search.stats.cadence.minValidationEvents,
4779
3874
  ...maxBatch > 0 ? { maxBatch } : {},
4780
- maxEventCountShare,
3875
+ maxEventCountShare: search.stats.cadence.maxEventCountShare,
4781
3876
  maxSymbolCountShare,
4782
3877
  allowRiskRegression,
4783
3878
  requireValidationEligibility,
3879
+ cadence: search.stats.cadence,
4784
3880
  validationSplit,
4785
3881
  testSplit,
4786
- minValidationSupport,
4787
3882
  dedupeEquivalentSelections,
4788
3883
  top
4789
3884
  }
@@ -4793,6 +3888,7 @@ var main = async () => {
4793
3888
  qualityThresholds: currentGateQualityThresholds
4794
3889
  },
4795
3890
  pocketSearch: search,
3891
+ coverageSearches,
4796
3892
  errors
4797
3893
  };
4798
3894
  const markdownReport = buildAiPocketMarkdownReport(result);
@@ -4852,17 +3948,53 @@ var main = async () => {
4852
3948
  ],
4853
3949
  ["min_quality", import_chalk.default.magenta(String(minQuality))],
4854
3950
  ["max_depth", import_chalk.default.magenta(String(maxDepth))],
4855
- ["min_support", import_chalk.default.magenta(String(minSupport))],
4856
- ["min_events", import_chalk.default.magenta(String(minEvents))],
4857
- ["min_validation_events", import_chalk.default.magenta(String(minValidationEvents))],
3951
+ ["cadence_mode", import_chalk.default.magenta(cadenceMode)],
3952
+ [
3953
+ "low_cadence",
3954
+ search.stats.cadence.lowCadence ? import_chalk.default.yellow("yes") : import_chalk.default.green("no")
3955
+ ],
3956
+ [
3957
+ "sparse_sample",
3958
+ search.stats.cadence.sparseSample ? import_chalk.default.yellow("yes") : import_chalk.default.green("no")
3959
+ ],
3960
+ [
3961
+ "adaptive_thresholds",
3962
+ search.stats.cadence.adaptiveThresholds ? import_chalk.default.yellow("on") : import_chalk.default.gray("off")
3963
+ ],
3964
+ [
3965
+ "train_events",
3966
+ import_chalk.default.magenta(String(search.stats.cadence.trainEvents))
3967
+ ],
3968
+ [
3969
+ "train_events_per_day",
3970
+ import_chalk.default.magenta(formatNumber2(search.stats.cadence.trainEventsPerDay))
3971
+ ],
3972
+ ["min_support", import_chalk.default.magenta(String(search.stats.cadence.minSupport))],
3973
+ ["min_events", import_chalk.default.magenta(String(search.stats.cadence.minEvents))],
3974
+ [
3975
+ "min_validation_events",
3976
+ import_chalk.default.magenta(String(search.stats.cadence.minValidationEvents))
3977
+ ],
4858
3978
  ["max_batch", import_chalk.default.magenta(maxBatch > 0 ? String(maxBatch) : "off")],
4859
- ["max_event_share", import_chalk.default.magenta(formatRatio(maxEventCountShare))],
3979
+ [
3980
+ "max_event_share",
3981
+ import_chalk.default.magenta(formatRatio(search.stats.cadence.maxEventCountShare))
3982
+ ],
4860
3983
  ["max_symbol_share", import_chalk.default.magenta(formatRatio(maxSymbolCountShare))],
4861
3984
  ["max_atomic_predicates", import_chalk.default.magenta(String(maxAtomicPredicates))],
4862
3985
  ["max_combinations", import_chalk.default.magenta(String(maxCombinations))],
4863
3986
  ["validation_split", import_chalk.default.magenta(formatRatio(validationSplit))],
4864
3987
  ["test_split", import_chalk.default.magenta(formatRatio(testSplit))],
4865
- ["min_validation_support", import_chalk.default.magenta(String(minValidationSupport))],
3988
+ [
3989
+ "test_evidence",
3990
+ sealedFullSplit.evidence.sealed ? import_chalk.default.green(
3991
+ `sealed (${sealedFullSplit.evidence.rows} rows / ${sealedFullSplit.evidence.events} events)`
3992
+ ) : import_chalk.default.yellow("open")
3993
+ ],
3994
+ [
3995
+ "min_validation_support",
3996
+ import_chalk.default.magenta(String(search.stats.cadence.minValidationSupport))
3997
+ ],
4866
3998
  [
4867
3999
  "dedupe_equivalent",
4868
4000
  dedupeEquivalentSelections ? import_chalk.default.green("on") : import_chalk.default.gray("off")
@@ -4877,6 +4009,7 @@ var main = async () => {
4877
4009
  ],
4878
4010
  ["feature_profile", import_chalk.default.magenta(featureProfile)],
4879
4011
  ["feature_policy", import_chalk.default.magenta(featurePolicy)],
4012
+ ["coverage_mode", import_chalk.default.magenta(coverageMode)],
4880
4013
  [
4881
4014
  "allow_risk_regression",
4882
4015
  allowRiskRegression ? import_chalk.default.yellow("on") : import_chalk.default.green("off")
@@ -4952,6 +4085,14 @@ var main = async () => {
4952
4085
  "feature_families",
4953
4086
  import_chalk.default.cyan(search.stats.featureFamiliesUsed.join(", "))
4954
4087
  ],
4088
+ [
4089
+ "required_feature_families",
4090
+ import_chalk.default.cyan(search.stats.requiredFeatureFamilies.join(", ") || "none")
4091
+ ],
4092
+ [
4093
+ "excluded_feature_families",
4094
+ import_chalk.default.cyan(search.stats.excludedFeatureFamilies.join(", ") || "none")
4095
+ ],
4955
4096
  [
4956
4097
  "estimated_combinations",
4957
4098
  import_chalk.default.cyan(String(search.stats.estimatedCombinations))
@@ -4962,6 +4103,27 @@ var main = async () => {
4962
4103
  ],
4963
4104
  ["validation_rows", import_chalk.default.cyan(String(search.stats.validationRows))],
4964
4105
  ["test_rows", import_chalk.default.cyan(String(search.stats.testRows))],
4106
+ ["train_events", import_chalk.default.cyan(String(search.stats.cadence.trainEvents))],
4107
+ [
4108
+ "train_events_per_day",
4109
+ import_chalk.default.cyan(formatNumber2(search.stats.cadence.trainEventsPerDay))
4110
+ ],
4111
+ [
4112
+ "effective_min_support",
4113
+ import_chalk.default.cyan(String(search.stats.cadence.minSupport))
4114
+ ],
4115
+ [
4116
+ "effective_min_events",
4117
+ import_chalk.default.cyan(String(search.stats.cadence.minEvents))
4118
+ ],
4119
+ [
4120
+ "effective_min_validation_support",
4121
+ import_chalk.default.cyan(String(search.stats.cadence.minValidationSupport))
4122
+ ],
4123
+ [
4124
+ "effective_min_validation_events",
4125
+ import_chalk.default.cyan(String(search.stats.cadence.minValidationEvents))
4126
+ ],
4965
4127
  [
4966
4128
  "duplicate_pockets_skipped",
4967
4129
  import_chalk.default.cyan(String(search.stats.duplicatePocketsSkipped))
@@ -4988,16 +4150,20 @@ var main = async () => {
4988
4150
  import_chalk.default.gray("OBJ_PNL"),
4989
4151
  import_chalk.default.gray("MAX_DD"),
4990
4152
  import_chalk.default.gray("VAL_N"),
4153
+ import_chalk.default.gray("VAL_EVENTS"),
4991
4154
  import_chalk.default.gray("VAL_WR"),
4992
4155
  import_chalk.default.gray("VAL_PF"),
4993
4156
  import_chalk.default.gray("VAL_PNL"),
4994
4157
  import_chalk.default.gray("TEST_N"),
4158
+ import_chalk.default.gray("TEST_EVENTS"),
4995
4159
  import_chalk.default.gray("TEST_PF"),
4996
4160
  import_chalk.default.gray("TEST_PNL"),
4997
4161
  import_chalk.default.gray("TEST_OBJ"),
4998
4162
  import_chalk.default.gray("TR/D"),
4999
4163
  import_chalk.default.gray("LOSS_M"),
5000
4164
  import_chalk.default.gray("SCORE"),
4165
+ import_chalk.default.gray("READINESS"),
4166
+ import_chalk.default.gray("REASONS"),
5001
4167
  import_chalk.default.gray("POCKET")
5002
4168
  ],
5003
4169
  buildPocketRows(search.positivePockets)
@@ -5018,21 +4184,155 @@ var main = async () => {
5018
4184
  import_chalk.default.gray("OBJ_PNL"),
5019
4185
  import_chalk.default.gray("MAX_DD"),
5020
4186
  import_chalk.default.gray("VAL_N"),
4187
+ import_chalk.default.gray("VAL_EVENTS"),
5021
4188
  import_chalk.default.gray("VAL_WR"),
5022
4189
  import_chalk.default.gray("VAL_PF"),
5023
4190
  import_chalk.default.gray("VAL_PNL"),
5024
4191
  import_chalk.default.gray("TEST_N"),
4192
+ import_chalk.default.gray("TEST_EVENTS"),
5025
4193
  import_chalk.default.gray("TEST_PF"),
5026
4194
  import_chalk.default.gray("TEST_PNL"),
5027
4195
  import_chalk.default.gray("TEST_OBJ"),
5028
4196
  import_chalk.default.gray("TR/D"),
5029
4197
  import_chalk.default.gray("LOSS_M"),
5030
4198
  import_chalk.default.gray("SCORE"),
4199
+ import_chalk.default.gray("READINESS"),
4200
+ import_chalk.default.gray("REASONS"),
5031
4201
  import_chalk.default.gray("POCKET")
5032
4202
  ],
5033
4203
  buildPocketRows(search.negativePockets)
5034
4204
  )
5035
4205
  );
4206
+ for (const cohort of coverageSearches) {
4207
+ const title = cohort.family === "cmc" ? "CMC" : "COINALYZE";
4208
+ printSection(
4209
+ `${title} COVERAGE COHORT`,
4210
+ createTable(
4211
+ [import_chalk.default.gray("FIELD"), import_chalk.default.gray("VALUE")],
4212
+ [
4213
+ ["coverage_rows", import_chalk.default.cyan(String(cohort.coverage.rows))],
4214
+ ["coverage_ratio", import_chalk.default.cyan(formatRatio(cohort.coverage.rowRatio))],
4215
+ ["coverage_events", import_chalk.default.cyan(String(cohort.coverage.events))],
4216
+ ["event_ratio", import_chalk.default.cyan(formatRatio(cohort.coverage.eventRatio))],
4217
+ [
4218
+ "coverage_from",
4219
+ cohort.coverage.minTimestamp == null ? import_chalk.default.gray("n/a") : import_chalk.default.gray(
4220
+ new Date(cohort.coverage.minTimestamp).toISOString()
4221
+ )
4222
+ ],
4223
+ [
4224
+ "coverage_to",
4225
+ cohort.coverage.maxTimestamp == null ? import_chalk.default.gray("n/a") : import_chalk.default.gray(
4226
+ new Date(cohort.coverage.maxTimestamp).toISOString()
4227
+ )
4228
+ ],
4229
+ ["scope_rows", import_chalk.default.cyan(String(cohort.scopeRows))],
4230
+ ["train_rows", import_chalk.default.cyan(String(cohort.trainRows))],
4231
+ ["validation_rows", import_chalk.default.cyan(String(cohort.validationRows))],
4232
+ ["test_rows", import_chalk.default.cyan(String(cohort.testRows))],
4233
+ [
4234
+ "low_cadence",
4235
+ cohort.search.stats.cadence.lowCadence ? import_chalk.default.yellow("yes") : import_chalk.default.green("no")
4236
+ ],
4237
+ [
4238
+ "sparse_sample",
4239
+ cohort.search.stats.cadence.sparseSample ? import_chalk.default.yellow("yes") : import_chalk.default.green("no")
4240
+ ],
4241
+ [
4242
+ "adaptive_thresholds",
4243
+ cohort.search.stats.cadence.adaptiveThresholds ? import_chalk.default.yellow("on") : import_chalk.default.gray("off")
4244
+ ],
4245
+ [
4246
+ "train_events",
4247
+ import_chalk.default.cyan(String(cohort.search.stats.cadence.trainEvents))
4248
+ ],
4249
+ [
4250
+ "effective_min_support",
4251
+ import_chalk.default.cyan(String(cohort.search.stats.cadence.minSupport))
4252
+ ],
4253
+ [
4254
+ "effective_min_events",
4255
+ import_chalk.default.cyan(String(cohort.search.stats.cadence.minEvents))
4256
+ ]
4257
+ ]
4258
+ )
4259
+ );
4260
+ printSection(
4261
+ `${title} TRAIN BASELINE`,
4262
+ createTable(
4263
+ [import_chalk.default.gray("METRIC"), import_chalk.default.gray("VALUE")],
4264
+ buildSummaryRows(cohort.search.baseline)
4265
+ )
4266
+ );
4267
+ printSection(
4268
+ `${title} TOP POSITIVE POCKETS`,
4269
+ createTable(
4270
+ [
4271
+ import_chalk.default.gray("#"),
4272
+ import_chalk.default.gray("N"),
4273
+ import_chalk.default.gray("EVENTS"),
4274
+ import_chalk.default.gray("MAX_B"),
4275
+ import_chalk.default.gray("SUP"),
4276
+ import_chalk.default.gray("WR"),
4277
+ import_chalk.default.gray("PF"),
4278
+ import_chalk.default.gray("PNL"),
4279
+ import_chalk.default.gray("OBJ_PNL"),
4280
+ import_chalk.default.gray("MAX_DD"),
4281
+ import_chalk.default.gray("VAL_N"),
4282
+ import_chalk.default.gray("VAL_EVENTS"),
4283
+ import_chalk.default.gray("VAL_WR"),
4284
+ import_chalk.default.gray("VAL_PF"),
4285
+ import_chalk.default.gray("VAL_PNL"),
4286
+ import_chalk.default.gray("TEST_N"),
4287
+ import_chalk.default.gray("TEST_EVENTS"),
4288
+ import_chalk.default.gray("TEST_PF"),
4289
+ import_chalk.default.gray("TEST_PNL"),
4290
+ import_chalk.default.gray("TEST_OBJ"),
4291
+ import_chalk.default.gray("TR/D"),
4292
+ import_chalk.default.gray("LOSS_M"),
4293
+ import_chalk.default.gray("SCORE"),
4294
+ import_chalk.default.gray("READINESS"),
4295
+ import_chalk.default.gray("REASONS"),
4296
+ import_chalk.default.gray("POCKET")
4297
+ ],
4298
+ buildPocketRows(cohort.search.positivePockets)
4299
+ )
4300
+ );
4301
+ printSection(
4302
+ `${title} TOP LOSS POCKETS`,
4303
+ createTable(
4304
+ [
4305
+ import_chalk.default.gray("#"),
4306
+ import_chalk.default.gray("N"),
4307
+ import_chalk.default.gray("EVENTS"),
4308
+ import_chalk.default.gray("MAX_B"),
4309
+ import_chalk.default.gray("SUP"),
4310
+ import_chalk.default.gray("WR"),
4311
+ import_chalk.default.gray("PF"),
4312
+ import_chalk.default.gray("PNL"),
4313
+ import_chalk.default.gray("OBJ_PNL"),
4314
+ import_chalk.default.gray("MAX_DD"),
4315
+ import_chalk.default.gray("VAL_N"),
4316
+ import_chalk.default.gray("VAL_EVENTS"),
4317
+ import_chalk.default.gray("VAL_WR"),
4318
+ import_chalk.default.gray("VAL_PF"),
4319
+ import_chalk.default.gray("VAL_PNL"),
4320
+ import_chalk.default.gray("TEST_N"),
4321
+ import_chalk.default.gray("TEST_EVENTS"),
4322
+ import_chalk.default.gray("TEST_PF"),
4323
+ import_chalk.default.gray("TEST_PNL"),
4324
+ import_chalk.default.gray("TEST_OBJ"),
4325
+ import_chalk.default.gray("TR/D"),
4326
+ import_chalk.default.gray("LOSS_M"),
4327
+ import_chalk.default.gray("SCORE"),
4328
+ import_chalk.default.gray("READINESS"),
4329
+ import_chalk.default.gray("REASONS"),
4330
+ import_chalk.default.gray("POCKET")
4331
+ ],
4332
+ buildPocketRows(cohort.search.negativePockets)
4333
+ )
4334
+ );
4335
+ }
5036
4336
  if (errors.length) {
5037
4337
  console.log(import_chalk.default.yellow("Errors:"));
5038
4338
  errors.forEach((error) => console.log(import_chalk.default.yellow(`- ${error}`)));