@trading-boy/cli 2.0.0 → 2.1.0

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 (3) hide show
  1. package/README.md +17 -10
  2. package/dist/cli.bundle.js +822 -360
  3. package/package.json +2 -2
@@ -6119,118 +6119,37 @@ var init_ansi_regex = __esm({
6119
6119
  }
6120
6120
  });
6121
6121
 
6122
- // ../../node_modules/.pnpm/strip-ansi@7.2.0/node_modules/strip-ansi/index.js
6122
+ // ../../node_modules/.pnpm/strip-ansi@7.1.2/node_modules/strip-ansi/index.js
6123
6123
  function stripAnsi(string) {
6124
6124
  if (typeof string !== "string") {
6125
6125
  throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
6126
6126
  }
6127
- if (!string.includes("\x1B") && !string.includes("\x9B")) {
6128
- return string;
6129
- }
6130
6127
  return string.replace(regex, "");
6131
6128
  }
6132
6129
  var regex;
6133
6130
  var init_strip_ansi = __esm({
6134
- "../../node_modules/.pnpm/strip-ansi@7.2.0/node_modules/strip-ansi/index.js"() {
6131
+ "../../node_modules/.pnpm/strip-ansi@7.1.2/node_modules/strip-ansi/index.js"() {
6135
6132
  init_ansi_regex();
6136
6133
  regex = ansiRegex();
6137
6134
  }
6138
6135
  });
6139
6136
 
6140
- // ../../node_modules/.pnpm/get-east-asian-width@1.5.0/node_modules/get-east-asian-width/lookup-data.js
6141
- var ambiguousRanges, fullwidthRanges, halfwidthRanges, narrowRanges, wideRanges;
6142
- var init_lookup_data = __esm({
6143
- "../../node_modules/.pnpm/get-east-asian-width@1.5.0/node_modules/get-east-asian-width/lookup-data.js"() {
6144
- ambiguousRanges = [161, 161, 164, 164, 167, 168, 170, 170, 173, 174, 176, 180, 182, 186, 188, 191, 198, 198, 208, 208, 215, 216, 222, 225, 230, 230, 232, 234, 236, 237, 240, 240, 242, 243, 247, 250, 252, 252, 254, 254, 257, 257, 273, 273, 275, 275, 283, 283, 294, 295, 299, 299, 305, 307, 312, 312, 319, 322, 324, 324, 328, 331, 333, 333, 338, 339, 358, 359, 363, 363, 462, 462, 464, 464, 466, 466, 468, 468, 470, 470, 472, 472, 474, 474, 476, 476, 593, 593, 609, 609, 708, 708, 711, 711, 713, 715, 717, 717, 720, 720, 728, 731, 733, 733, 735, 735, 768, 879, 913, 929, 931, 937, 945, 961, 963, 969, 1025, 1025, 1040, 1103, 1105, 1105, 8208, 8208, 8211, 8214, 8216, 8217, 8220, 8221, 8224, 8226, 8228, 8231, 8240, 8240, 8242, 8243, 8245, 8245, 8251, 8251, 8254, 8254, 8308, 8308, 8319, 8319, 8321, 8324, 8364, 8364, 8451, 8451, 8453, 8453, 8457, 8457, 8467, 8467, 8470, 8470, 8481, 8482, 8486, 8486, 8491, 8491, 8531, 8532, 8539, 8542, 8544, 8555, 8560, 8569, 8585, 8585, 8592, 8601, 8632, 8633, 8658, 8658, 8660, 8660, 8679, 8679, 8704, 8704, 8706, 8707, 8711, 8712, 8715, 8715, 8719, 8719, 8721, 8721, 8725, 8725, 8730, 8730, 8733, 8736, 8739, 8739, 8741, 8741, 8743, 8748, 8750, 8750, 8756, 8759, 8764, 8765, 8776, 8776, 8780, 8780, 8786, 8786, 8800, 8801, 8804, 8807, 8810, 8811, 8814, 8815, 8834, 8835, 8838, 8839, 8853, 8853, 8857, 8857, 8869, 8869, 8895, 8895, 8978, 8978, 9312, 9449, 9451, 9547, 9552, 9587, 9600, 9615, 9618, 9621, 9632, 9633, 9635, 9641, 9650, 9651, 9654, 9655, 9660, 9661, 9664, 9665, 9670, 9672, 9675, 9675, 9678, 9681, 9698, 9701, 9711, 9711, 9733, 9734, 9737, 9737, 9742, 9743, 9756, 9756, 9758, 9758, 9792, 9792, 9794, 9794, 9824, 9825, 9827, 9829, 9831, 9834, 9836, 9837, 9839, 9839, 9886, 9887, 9919, 9919, 9926, 9933, 9935, 9939, 9941, 9953, 9955, 9955, 9960, 9961, 9963, 9969, 9972, 9972, 9974, 9977, 9979, 9980, 9982, 9983, 10045, 10045, 10102, 10111, 11094, 11097, 12872, 12879, 57344, 63743, 65024, 65039, 65533, 65533, 127232, 127242, 127248, 127277, 127280, 127337, 127344, 127373, 127375, 127376, 127387, 127404, 917760, 917999, 983040, 1048573, 1048576, 1114109];
6145
- fullwidthRanges = [12288, 12288, 65281, 65376, 65504, 65510];
6146
- halfwidthRanges = [8361, 8361, 65377, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, 65512, 65518];
6147
- narrowRanges = [32, 126, 162, 163, 165, 166, 172, 172, 175, 175, 10214, 10221, 10629, 10630];
6148
- wideRanges = [4352, 4447, 8986, 8987, 9001, 9002, 9193, 9196, 9200, 9200, 9203, 9203, 9725, 9726, 9748, 9749, 9776, 9783, 9800, 9811, 9855, 9855, 9866, 9871, 9875, 9875, 9889, 9889, 9898, 9899, 9917, 9918, 9924, 9925, 9934, 9934, 9940, 9940, 9962, 9962, 9970, 9971, 9973, 9973, 9978, 9978, 9981, 9981, 9989, 9989, 9994, 9995, 10024, 10024, 10060, 10060, 10062, 10062, 10067, 10069, 10071, 10071, 10133, 10135, 10160, 10160, 10175, 10175, 11035, 11036, 11088, 11088, 11093, 11093, 11904, 11929, 11931, 12019, 12032, 12245, 12272, 12287, 12289, 12350, 12353, 12438, 12441, 12543, 12549, 12591, 12593, 12686, 12688, 12773, 12783, 12830, 12832, 12871, 12880, 42124, 42128, 42182, 43360, 43388, 44032, 55203, 63744, 64255, 65040, 65049, 65072, 65106, 65108, 65126, 65128, 65131, 94176, 94180, 94192, 94198, 94208, 101589, 101631, 101662, 101760, 101874, 110576, 110579, 110581, 110587, 110589, 110590, 110592, 110882, 110898, 110898, 110928, 110930, 110933, 110933, 110948, 110951, 110960, 111355, 119552, 119638, 119648, 119670, 126980, 126980, 127183, 127183, 127374, 127374, 127377, 127386, 127488, 127490, 127504, 127547, 127552, 127560, 127568, 127569, 127584, 127589, 127744, 127776, 127789, 127797, 127799, 127868, 127870, 127891, 127904, 127946, 127951, 127955, 127968, 127984, 127988, 127988, 127992, 128062, 128064, 128064, 128066, 128252, 128255, 128317, 128331, 128334, 128336, 128359, 128378, 128378, 128405, 128406, 128420, 128420, 128507, 128591, 128640, 128709, 128716, 128716, 128720, 128722, 128725, 128728, 128732, 128735, 128747, 128748, 128756, 128764, 128992, 129003, 129008, 129008, 129292, 129338, 129340, 129349, 129351, 129535, 129648, 129660, 129664, 129674, 129678, 129734, 129736, 129736, 129741, 129756, 129759, 129770, 129775, 129784, 131072, 196605, 196608, 262141];
6149
- }
6150
- });
6151
-
6152
- // ../../node_modules/.pnpm/get-east-asian-width@1.5.0/node_modules/get-east-asian-width/utilities.js
6153
- var isInRange;
6154
- var init_utilities2 = __esm({
6155
- "../../node_modules/.pnpm/get-east-asian-width@1.5.0/node_modules/get-east-asian-width/utilities.js"() {
6156
- isInRange = (ranges, codePoint) => {
6157
- let low = 0;
6158
- let high = Math.floor(ranges.length / 2) - 1;
6159
- while (low <= high) {
6160
- const mid = Math.floor((low + high) / 2);
6161
- const i = mid * 2;
6162
- if (codePoint < ranges[i]) {
6163
- high = mid - 1;
6164
- } else if (codePoint > ranges[i + 1]) {
6165
- low = mid + 1;
6166
- } else {
6167
- return true;
6168
- }
6169
- }
6170
- return false;
6171
- };
6172
- }
6173
- });
6174
-
6175
- // ../../node_modules/.pnpm/get-east-asian-width@1.5.0/node_modules/get-east-asian-width/lookup.js
6176
- function findWideFastPathRange(ranges) {
6177
- let fastPathStart = ranges[0];
6178
- let fastPathEnd = ranges[1];
6179
- for (let index = 0; index < ranges.length; index += 2) {
6180
- const start = ranges[index];
6181
- const end = ranges[index + 1];
6182
- if (commonCjkCodePoint >= start && commonCjkCodePoint <= end) {
6183
- return [start, end];
6184
- }
6185
- if (end - start > fastPathEnd - fastPathStart) {
6186
- fastPathStart = start;
6187
- fastPathEnd = end;
6188
- }
6189
- }
6190
- return [fastPathStart, fastPathEnd];
6137
+ // ../../node_modules/.pnpm/get-east-asian-width@1.4.0/node_modules/get-east-asian-width/lookup.js
6138
+ function isAmbiguous(x) {
6139
+ return x === 161 || x === 164 || x === 167 || x === 168 || x === 170 || x === 173 || x === 174 || x >= 176 && x <= 180 || x >= 182 && x <= 186 || x >= 188 && x <= 191 || x === 198 || x === 208 || x === 215 || x === 216 || x >= 222 && x <= 225 || x === 230 || x >= 232 && x <= 234 || x === 236 || x === 237 || x === 240 || x === 242 || x === 243 || x >= 247 && x <= 250 || x === 252 || x === 254 || x === 257 || x === 273 || x === 275 || x === 283 || x === 294 || x === 295 || x === 299 || x >= 305 && x <= 307 || x === 312 || x >= 319 && x <= 322 || x === 324 || x >= 328 && x <= 331 || x === 333 || x === 338 || x === 339 || x === 358 || x === 359 || x === 363 || x === 462 || x === 464 || x === 466 || x === 468 || x === 470 || x === 472 || x === 474 || x === 476 || x === 593 || x === 609 || x === 708 || x === 711 || x >= 713 && x <= 715 || x === 717 || x === 720 || x >= 728 && x <= 731 || x === 733 || x === 735 || x >= 768 && x <= 879 || x >= 913 && x <= 929 || x >= 931 && x <= 937 || x >= 945 && x <= 961 || x >= 963 && x <= 969 || x === 1025 || x >= 1040 && x <= 1103 || x === 1105 || x === 8208 || x >= 8211 && x <= 8214 || x === 8216 || x === 8217 || x === 8220 || x === 8221 || x >= 8224 && x <= 8226 || x >= 8228 && x <= 8231 || x === 8240 || x === 8242 || x === 8243 || x === 8245 || x === 8251 || x === 8254 || x === 8308 || x === 8319 || x >= 8321 && x <= 8324 || x === 8364 || x === 8451 || x === 8453 || x === 8457 || x === 8467 || x === 8470 || x === 8481 || x === 8482 || x === 8486 || x === 8491 || x === 8531 || x === 8532 || x >= 8539 && x <= 8542 || x >= 8544 && x <= 8555 || x >= 8560 && x <= 8569 || x === 8585 || x >= 8592 && x <= 8601 || x === 8632 || x === 8633 || x === 8658 || x === 8660 || x === 8679 || x === 8704 || x === 8706 || x === 8707 || x === 8711 || x === 8712 || x === 8715 || x === 8719 || x === 8721 || x === 8725 || x === 8730 || x >= 8733 && x <= 8736 || x === 8739 || x === 8741 || x >= 8743 && x <= 8748 || x === 8750 || x >= 8756 && x <= 8759 || x === 8764 || x === 8765 || x === 8776 || x === 8780 || x === 8786 || x === 8800 || x === 8801 || x >= 8804 && x <= 8807 || x === 8810 || x === 8811 || x === 8814 || x === 8815 || x === 8834 || x === 8835 || x === 8838 || x === 8839 || x === 8853 || x === 8857 || x === 8869 || x === 8895 || x === 8978 || x >= 9312 && x <= 9449 || x >= 9451 && x <= 9547 || x >= 9552 && x <= 9587 || x >= 9600 && x <= 9615 || x >= 9618 && x <= 9621 || x === 9632 || x === 9633 || x >= 9635 && x <= 9641 || x === 9650 || x === 9651 || x === 9654 || x === 9655 || x === 9660 || x === 9661 || x === 9664 || x === 9665 || x >= 9670 && x <= 9672 || x === 9675 || x >= 9678 && x <= 9681 || x >= 9698 && x <= 9701 || x === 9711 || x === 9733 || x === 9734 || x === 9737 || x === 9742 || x === 9743 || x === 9756 || x === 9758 || x === 9792 || x === 9794 || x === 9824 || x === 9825 || x >= 9827 && x <= 9829 || x >= 9831 && x <= 9834 || x === 9836 || x === 9837 || x === 9839 || x === 9886 || x === 9887 || x === 9919 || x >= 9926 && x <= 9933 || x >= 9935 && x <= 9939 || x >= 9941 && x <= 9953 || x === 9955 || x === 9960 || x === 9961 || x >= 9963 && x <= 9969 || x === 9972 || x >= 9974 && x <= 9977 || x === 9979 || x === 9980 || x === 9982 || x === 9983 || x === 10045 || x >= 10102 && x <= 10111 || x >= 11094 && x <= 11097 || x >= 12872 && x <= 12879 || x >= 57344 && x <= 63743 || x >= 65024 && x <= 65039 || x === 65533 || x >= 127232 && x <= 127242 || x >= 127248 && x <= 127277 || x >= 127280 && x <= 127337 || x >= 127344 && x <= 127373 || x === 127375 || x === 127376 || x >= 127387 && x <= 127404 || x >= 917760 && x <= 917999 || x >= 983040 && x <= 1048573 || x >= 1048576 && x <= 1114109;
6140
+ }
6141
+ function isFullWidth(x) {
6142
+ return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
6143
+ }
6144
+ function isWide(x) {
6145
+ return x >= 4352 && x <= 4447 || x === 8986 || x === 8987 || x === 9001 || x === 9002 || x >= 9193 && x <= 9196 || x === 9200 || x === 9203 || x === 9725 || x === 9726 || x === 9748 || x === 9749 || x >= 9776 && x <= 9783 || x >= 9800 && x <= 9811 || x === 9855 || x >= 9866 && x <= 9871 || x === 9875 || x === 9889 || x === 9898 || x === 9899 || x === 9917 || x === 9918 || x === 9924 || x === 9925 || x === 9934 || x === 9940 || x === 9962 || x === 9970 || x === 9971 || x === 9973 || x === 9978 || x === 9981 || x === 9989 || x === 9994 || x === 9995 || x === 10024 || x === 10060 || x === 10062 || x >= 10067 && x <= 10069 || x === 10071 || x >= 10133 && x <= 10135 || x === 10160 || x === 10175 || x === 11035 || x === 11036 || x === 11088 || x === 11093 || x >= 11904 && x <= 11929 || x >= 11931 && x <= 12019 || x >= 12032 && x <= 12245 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12353 && x <= 12438 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12773 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 42124 || x >= 42128 && x <= 42182 || x >= 43360 && x <= 43388 || x >= 44032 && x <= 55203 || x >= 63744 && x <= 64255 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 94176 && x <= 94180 || x >= 94192 && x <= 94198 || x >= 94208 && x <= 101589 || x >= 101631 && x <= 101662 || x >= 101760 && x <= 101874 || x >= 110576 && x <= 110579 || x >= 110581 && x <= 110587 || x === 110589 || x === 110590 || x >= 110592 && x <= 110882 || x === 110898 || x >= 110928 && x <= 110930 || x === 110933 || x >= 110948 && x <= 110951 || x >= 110960 && x <= 111355 || x >= 119552 && x <= 119638 || x >= 119648 && x <= 119670 || x === 126980 || x === 127183 || x === 127374 || x >= 127377 && x <= 127386 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x === 127568 || x === 127569 || x >= 127584 && x <= 127589 || x >= 127744 && x <= 127776 || x >= 127789 && x <= 127797 || x >= 127799 && x <= 127868 || x >= 127870 && x <= 127891 || x >= 127904 && x <= 127946 || x >= 127951 && x <= 127955 || x >= 127968 && x <= 127984 || x === 127988 || x >= 127992 && x <= 128062 || x === 128064 || x >= 128066 && x <= 128252 || x >= 128255 && x <= 128317 || x >= 128331 && x <= 128334 || x >= 128336 && x <= 128359 || x === 128378 || x === 128405 || x === 128406 || x === 128420 || x >= 128507 && x <= 128591 || x >= 128640 && x <= 128709 || x === 128716 || x >= 128720 && x <= 128722 || x >= 128725 && x <= 128728 || x >= 128732 && x <= 128735 || x === 128747 || x === 128748 || x >= 128756 && x <= 128764 || x >= 128992 && x <= 129003 || x === 129008 || x >= 129292 && x <= 129338 || x >= 129340 && x <= 129349 || x >= 129351 && x <= 129535 || x >= 129648 && x <= 129660 || x >= 129664 && x <= 129674 || x >= 129678 && x <= 129734 || x === 129736 || x >= 129741 && x <= 129756 || x >= 129759 && x <= 129770 || x >= 129775 && x <= 129784 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
6191
6146
  }
6192
- var minimumAmbiguousCodePoint, maximumAmbiguousCodePoint, minimumFullWidthCodePoint, maximumFullWidthCodePoint, minimumHalfWidthCodePoint, maximumHalfWidthCodePoint, minimumNarrowCodePoint, maximumNarrowCodePoint, minimumWideCodePoint, maximumWideCodePoint, commonCjkCodePoint, wideFastPathStart, wideFastPathEnd, isAmbiguous, isFullWidth, isWide;
6193
6147
  var init_lookup = __esm({
6194
- "../../node_modules/.pnpm/get-east-asian-width@1.5.0/node_modules/get-east-asian-width/lookup.js"() {
6195
- init_lookup_data();
6196
- init_utilities2();
6197
- minimumAmbiguousCodePoint = ambiguousRanges[0];
6198
- maximumAmbiguousCodePoint = ambiguousRanges.at(-1);
6199
- minimumFullWidthCodePoint = fullwidthRanges[0];
6200
- maximumFullWidthCodePoint = fullwidthRanges.at(-1);
6201
- minimumHalfWidthCodePoint = halfwidthRanges[0];
6202
- maximumHalfWidthCodePoint = halfwidthRanges.at(-1);
6203
- minimumNarrowCodePoint = narrowRanges[0];
6204
- maximumNarrowCodePoint = narrowRanges.at(-1);
6205
- minimumWideCodePoint = wideRanges[0];
6206
- maximumWideCodePoint = wideRanges.at(-1);
6207
- commonCjkCodePoint = 19968;
6208
- [wideFastPathStart, wideFastPathEnd] = findWideFastPathRange(wideRanges);
6209
- isAmbiguous = (codePoint) => {
6210
- if (codePoint < minimumAmbiguousCodePoint || codePoint > maximumAmbiguousCodePoint) {
6211
- return false;
6212
- }
6213
- return isInRange(ambiguousRanges, codePoint);
6214
- };
6215
- isFullWidth = (codePoint) => {
6216
- if (codePoint < minimumFullWidthCodePoint || codePoint > maximumFullWidthCodePoint) {
6217
- return false;
6218
- }
6219
- return isInRange(fullwidthRanges, codePoint);
6220
- };
6221
- isWide = (codePoint) => {
6222
- if (codePoint >= wideFastPathStart && codePoint <= wideFastPathEnd) {
6223
- return true;
6224
- }
6225
- if (codePoint < minimumWideCodePoint || codePoint > maximumWideCodePoint) {
6226
- return false;
6227
- }
6228
- return isInRange(wideRanges, codePoint);
6229
- };
6148
+ "../../node_modules/.pnpm/get-east-asian-width@1.4.0/node_modules/get-east-asian-width/lookup.js"() {
6230
6149
  }
6231
6150
  });
6232
6151
 
6233
- // ../../node_modules/.pnpm/get-east-asian-width@1.5.0/node_modules/get-east-asian-width/index.js
6152
+ // ../../node_modules/.pnpm/get-east-asian-width@1.4.0/node_modules/get-east-asian-width/index.js
6234
6153
  function validate(codePoint) {
6235
6154
  if (!Number.isSafeInteger(codePoint)) {
6236
6155
  throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`);
@@ -6244,25 +6163,12 @@ function eastAsianWidth(codePoint, { ambiguousAsWide = false } = {}) {
6244
6163
  return 1;
6245
6164
  }
6246
6165
  var init_get_east_asian_width = __esm({
6247
- "../../node_modules/.pnpm/get-east-asian-width@1.5.0/node_modules/get-east-asian-width/index.js"() {
6166
+ "../../node_modules/.pnpm/get-east-asian-width@1.4.0/node_modules/get-east-asian-width/index.js"() {
6248
6167
  init_lookup();
6249
6168
  }
6250
6169
  });
6251
6170
 
6252
- // ../../node_modules/.pnpm/string-width@8.2.0/node_modules/string-width/index.js
6253
- function isDoubleWidthNonRgiEmojiSequence(segment) {
6254
- if (segment.length > 50) {
6255
- return false;
6256
- }
6257
- if (unqualifiedKeycapRegex.test(segment)) {
6258
- return true;
6259
- }
6260
- if (segment.includes("\u200D")) {
6261
- const pictographics = segment.match(extendedPictographicRegex);
6262
- return pictographics !== null && pictographics.length >= 2;
6263
- }
6264
- return false;
6265
- }
6171
+ // ../../node_modules/.pnpm/string-width@8.1.1/node_modules/string-width/index.js
6266
6172
  function baseVisible(segment) {
6267
6173
  return segment.replace(leadingNonPrintingRegex, "");
6268
6174
  }
@@ -6289,22 +6195,19 @@ function stringWidth(input, options = {}) {
6289
6195
  countAnsiEscapeCodes = false
6290
6196
  } = options;
6291
6197
  let string = input;
6292
- if (!countAnsiEscapeCodes && (string.includes("\x1B") || string.includes("\x9B"))) {
6198
+ if (!countAnsiEscapeCodes) {
6293
6199
  string = stripAnsi(string);
6294
6200
  }
6295
6201
  if (string.length === 0) {
6296
6202
  return 0;
6297
6203
  }
6298
- if (/^[\u0020-\u007E]*$/.test(string)) {
6299
- return string.length;
6300
- }
6301
6204
  let width = 0;
6302
6205
  const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow };
6303
6206
  for (const { segment } of segmenter.segment(string)) {
6304
6207
  if (isZeroWidthCluster(segment)) {
6305
6208
  continue;
6306
6209
  }
6307
- if (rgiEmojiRegex.test(segment) || isDoubleWidthNonRgiEmojiSequence(segment)) {
6210
+ if (rgiEmojiRegex.test(segment)) {
6308
6211
  width += 2;
6309
6212
  continue;
6310
6213
  }
@@ -6314,17 +6217,15 @@ function stringWidth(input, options = {}) {
6314
6217
  }
6315
6218
  return width;
6316
6219
  }
6317
- var segmenter, zeroWidthClusterRegex, leadingNonPrintingRegex, rgiEmojiRegex, unqualifiedKeycapRegex, extendedPictographicRegex;
6220
+ var segmenter, zeroWidthClusterRegex, leadingNonPrintingRegex, rgiEmojiRegex;
6318
6221
  var init_string_width = __esm({
6319
- "../../node_modules/.pnpm/string-width@8.2.0/node_modules/string-width/index.js"() {
6222
+ "../../node_modules/.pnpm/string-width@8.1.1/node_modules/string-width/index.js"() {
6320
6223
  init_strip_ansi();
6321
6224
  init_get_east_asian_width();
6322
6225
  segmenter = new Intl.Segmenter();
6323
6226
  zeroWidthClusterRegex = new RegExp("^(?:\\p{Default_Ignorable_Code_Point}|\\p{Control}|\\p{Format}|\\p{Mark}|\\p{Surrogate})+$", "v");
6324
6227
  leadingNonPrintingRegex = new RegExp("^[\\p{Default_Ignorable_Code_Point}\\p{Control}\\p{Format}\\p{Mark}\\p{Surrogate}]+", "v");
6325
6228
  rgiEmojiRegex = new RegExp("^\\p{RGI_Emoji}$", "v");
6326
- unqualifiedKeycapRegex = /^[\d#*]\u20E3$/;
6327
- extendedPictographicRegex = new RegExp("\\p{Extended_Pictographic}", "gu");
6328
6229
  }
6329
6230
  });
6330
6231
 
@@ -7319,7 +7220,7 @@ function parseIntOption(value) {
7319
7220
  function isApiError(error2) {
7320
7221
  return error2 instanceof Error && error2.name === "ApiError" && "status" in error2;
7321
7222
  }
7322
- function handleApiError(error2, context, logger30) {
7223
+ function handleApiError(error2, context, logger31) {
7323
7224
  if (isApiError(error2)) {
7324
7225
  switch (error2.status) {
7325
7226
  case 401:
@@ -7342,7 +7243,7 @@ function handleApiError(error2, context, logger30) {
7342
7243
  }
7343
7244
  } else {
7344
7245
  const message = error2 instanceof Error ? error2.message : String(error2);
7345
- logger30.error({ error: message }, context);
7246
+ logger31.error({ error: message }, context);
7346
7247
  console.error(source_default.red(`Error: ${message}`));
7347
7248
  }
7348
7249
  process.exitCode = isApiError(error2) ? 2 : 1;
@@ -7364,10 +7265,10 @@ var init_utils = __esm({
7364
7265
  }
7365
7266
  });
7366
7267
 
7367
- // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/key.js
7268
+ // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/key.js
7368
7269
  var isUpKey, isDownKey, isSpaceKey, isBackspaceKey, isTabKey, isNumberKey, isEnterKey;
7369
7270
  var init_key = __esm({
7370
- "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/key.js"() {
7271
+ "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/key.js"() {
7371
7272
  isUpKey = (key, keybindings = []) => (
7372
7273
  // The up key
7373
7274
  key.name === "up" || // Vim keybinding: hjkl keys map to left/down/up/right
@@ -7388,10 +7289,10 @@ var init_key = __esm({
7388
7289
  }
7389
7290
  });
7390
7291
 
7391
- // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/errors.js
7292
+ // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/errors.js
7392
7293
  var AbortPromptError, CancelPromptError, ExitPromptError, HookError, ValidationError;
7393
7294
  var init_errors = __esm({
7394
- "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/errors.js"() {
7295
+ "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/errors.js"() {
7395
7296
  AbortPromptError = class extends Error {
7396
7297
  name = "AbortPromptError";
7397
7298
  message = "Prompt was aborted";
@@ -7416,7 +7317,7 @@ var init_errors = __esm({
7416
7317
  }
7417
7318
  });
7418
7319
 
7419
- // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/hook-engine.js
7320
+ // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/hook-engine.js
7420
7321
  import { AsyncLocalStorage, AsyncResource } from "node:async_hooks";
7421
7322
  function createStore(rl) {
7422
7323
  const store = {
@@ -7491,7 +7392,7 @@ function handleChange() {
7491
7392
  }
7492
7393
  var hookStorage, effectScheduler;
7493
7394
  var init_hook_engine = __esm({
7494
- "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/hook-engine.js"() {
7395
+ "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/hook-engine.js"() {
7495
7396
  init_errors();
7496
7397
  hookStorage = new AsyncLocalStorage();
7497
7398
  effectScheduler = {
@@ -7528,7 +7429,7 @@ var init_hook_engine = __esm({
7528
7429
  }
7529
7430
  });
7530
7431
 
7531
- // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/use-state.js
7432
+ // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/use-state.js
7532
7433
  import { AsyncResource as AsyncResource2 } from "node:async_hooks";
7533
7434
  function useState(defaultValue) {
7534
7435
  return withPointer((pointer) => {
@@ -7547,12 +7448,12 @@ function useState(defaultValue) {
7547
7448
  });
7548
7449
  }
7549
7450
  var init_use_state = __esm({
7550
- "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/use-state.js"() {
7451
+ "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/use-state.js"() {
7551
7452
  init_hook_engine();
7552
7453
  }
7553
7454
  });
7554
7455
 
7555
- // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/use-effect.js
7456
+ // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/use-effect.js
7556
7457
  function useEffect(cb, depArray) {
7557
7458
  withPointer((pointer) => {
7558
7459
  const oldDeps = pointer.get();
@@ -7564,7 +7465,7 @@ function useEffect(cb, depArray) {
7564
7465
  });
7565
7466
  }
7566
7467
  var init_use_effect = __esm({
7567
- "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/use-effect.js"() {
7468
+ "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/use-effect.js"() {
7568
7469
  init_hook_engine();
7569
7470
  }
7570
7471
  });
@@ -7942,10 +7843,10 @@ var init_esm = __esm({
7942
7843
  }
7943
7844
  });
7944
7845
 
7945
- // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/theme.js
7846
+ // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/theme.js
7946
7847
  var import_yoctocolors_cjs, defaultTheme;
7947
7848
  var init_theme = __esm({
7948
- "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/theme.js"() {
7849
+ "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/theme.js"() {
7949
7850
  import_yoctocolors_cjs = __toESM(require_yoctocolors_cjs(), 1);
7950
7851
  init_esm();
7951
7852
  defaultTheme = {
@@ -7970,7 +7871,7 @@ var init_theme = __esm({
7970
7871
  }
7971
7872
  });
7972
7873
 
7973
- // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/make-theme.js
7874
+ // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/make-theme.js
7974
7875
  function isPlainObject(value) {
7975
7876
  if (typeof value !== "object" || value === null)
7976
7877
  return false;
@@ -7998,12 +7899,12 @@ function makeTheme(...themes) {
7998
7899
  return deepMerge(...themesToMerge);
7999
7900
  }
8000
7901
  var init_make_theme = __esm({
8001
- "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/make-theme.js"() {
7902
+ "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/make-theme.js"() {
8002
7903
  init_theme();
8003
7904
  }
8004
7905
  });
8005
7906
 
8006
- // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/use-prefix.js
7907
+ // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/use-prefix.js
8007
7908
  function usePrefix({ status = "idle", theme }) {
8008
7909
  const [showLoader, setShowLoader] = useState(false);
8009
7910
  const [tick, setTick] = useState(0);
@@ -8034,14 +7935,14 @@ function usePrefix({ status = "idle", theme }) {
8034
7935
  return typeof prefix === "string" ? prefix : prefix[iconName] ?? prefix["idle"];
8035
7936
  }
8036
7937
  var init_use_prefix = __esm({
8037
- "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/use-prefix.js"() {
7938
+ "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/use-prefix.js"() {
8038
7939
  init_use_state();
8039
7940
  init_use_effect();
8040
7941
  init_make_theme();
8041
7942
  }
8042
7943
  });
8043
7944
 
8044
- // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/use-memo.js
7945
+ // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/use-memo.js
8045
7946
  function useMemo(fn, dependencies) {
8046
7947
  return withPointer((pointer) => {
8047
7948
  const prev = pointer.get();
@@ -8054,22 +7955,22 @@ function useMemo(fn, dependencies) {
8054
7955
  });
8055
7956
  }
8056
7957
  var init_use_memo = __esm({
8057
- "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/use-memo.js"() {
7958
+ "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/use-memo.js"() {
8058
7959
  init_hook_engine();
8059
7960
  }
8060
7961
  });
8061
7962
 
8062
- // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/use-ref.js
7963
+ // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/use-ref.js
8063
7964
  function useRef(val) {
8064
7965
  return useState({ current: val })[0];
8065
7966
  }
8066
7967
  var init_use_ref = __esm({
8067
- "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/use-ref.js"() {
7968
+ "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/use-ref.js"() {
8068
7969
  init_use_state();
8069
7970
  }
8070
7971
  });
8071
7972
 
8072
- // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/use-keypress.js
7973
+ // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/use-keypress.js
8073
7974
  function useKeypress(userHandler) {
8074
7975
  const signal = useRef(userHandler);
8075
7976
  signal.current = userHandler;
@@ -8088,7 +7989,7 @@ function useKeypress(userHandler) {
8088
7989
  }, []);
8089
7990
  }
8090
7991
  var init_use_keypress = __esm({
8091
- "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/use-keypress.js"() {
7992
+ "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/use-keypress.js"() {
8092
7993
  init_use_ref();
8093
7994
  init_use_effect();
8094
7995
  init_hook_engine();
@@ -9475,7 +9376,7 @@ var require_wrap_ansi = __commonJS({
9475
9376
  }
9476
9377
  });
9477
9378
 
9478
- // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/utils.js
9379
+ // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/utils.js
9479
9380
  function breakLines(content, width) {
9480
9381
  return content.split("\n").flatMap((line) => (0, import_wrap_ansi.default)(line, width, { trim: false, hard: true }).split("\n").map((str) => str.trimEnd())).join("\n");
9481
9382
  }
@@ -9484,14 +9385,14 @@ function readlineWidth() {
9484
9385
  }
9485
9386
  var import_cli_width, import_wrap_ansi;
9486
9387
  var init_utils2 = __esm({
9487
- "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/utils.js"() {
9388
+ "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/utils.js"() {
9488
9389
  import_cli_width = __toESM(require_cli_width(), 1);
9489
9390
  import_wrap_ansi = __toESM(require_wrap_ansi(), 1);
9490
9391
  init_hook_engine();
9491
9392
  }
9492
9393
  });
9493
9394
 
9494
- // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/pagination/use-pagination.js
9395
+ // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/pagination/use-pagination.js
9495
9396
  function usePointerPosition({ active, renderedItems, pageSize, loop }) {
9496
9397
  const state = useRef({
9497
9398
  lastPointer: active,
@@ -9580,7 +9481,7 @@ function usePagination({ items, active, renderItem, pageSize, loop = true }) {
9580
9481
  return pageBuffer.filter((line) => typeof line === "string").join("\n");
9581
9482
  }
9582
9483
  var init_use_pagination = __esm({
9583
- "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/pagination/use-pagination.js"() {
9484
+ "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/pagination/use-pagination.js"() {
9584
9485
  init_use_ref();
9585
9486
  init_utils2();
9586
9487
  }
@@ -9729,11 +9630,11 @@ var init_esm2 = __esm({
9729
9630
  }
9730
9631
  });
9731
9632
 
9732
- // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/screen-manager.js
9633
+ // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/screen-manager.js
9733
9634
  import { stripVTControlCharacters as stripVTControlCharacters2 } from "node:util";
9734
9635
  var height, lastLine, ScreenManager;
9735
9636
  var init_screen_manager = __esm({
9736
- "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/screen-manager.js"() {
9637
+ "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/screen-manager.js"() {
9737
9638
  init_utils2();
9738
9639
  init_esm2();
9739
9640
  height = (content) => content.split("\n").length;
@@ -9797,10 +9698,10 @@ var init_screen_manager = __esm({
9797
9698
  }
9798
9699
  });
9799
9700
 
9800
- // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/promise-polyfill.js
9701
+ // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/promise-polyfill.js
9801
9702
  var PromisePolyfill;
9802
9703
  var init_promise_polyfill = __esm({
9803
- "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/promise-polyfill.js"() {
9704
+ "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/promise-polyfill.js"() {
9804
9705
  PromisePolyfill = class extends Promise {
9805
9706
  // Available starting from Node 22
9806
9707
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
@@ -9817,7 +9718,7 @@ var init_promise_polyfill = __esm({
9817
9718
  }
9818
9719
  });
9819
9720
 
9820
- // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/create-prompt.js
9721
+ // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/create-prompt.js
9821
9722
  import * as readline2 from "node:readline";
9822
9723
  import { AsyncResource as AsyncResource3 } from "node:async_hooks";
9823
9724
  function getCallSites() {
@@ -9907,7 +9808,7 @@ function createPrompt(view) {
9907
9808
  }
9908
9809
  var import_mute_stream;
9909
9810
  var init_create_prompt = __esm({
9910
- "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/create-prompt.js"() {
9811
+ "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/create-prompt.js"() {
9911
9812
  import_mute_stream = __toESM(require_lib(), 1);
9912
9813
  init_mjs();
9913
9814
  init_screen_manager();
@@ -9917,10 +9818,10 @@ var init_create_prompt = __esm({
9917
9818
  }
9918
9819
  });
9919
9820
 
9920
- // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/Separator.js
9821
+ // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/Separator.js
9921
9822
  var import_yoctocolors_cjs2, Separator;
9922
9823
  var init_Separator = __esm({
9923
- "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/lib/Separator.js"() {
9824
+ "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/lib/Separator.js"() {
9924
9825
  import_yoctocolors_cjs2 = __toESM(require_yoctocolors_cjs(), 1);
9925
9826
  init_esm();
9926
9827
  Separator = class {
@@ -9938,9 +9839,9 @@ var init_Separator = __esm({
9938
9839
  }
9939
9840
  });
9940
9841
 
9941
- // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/index.js
9842
+ // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/index.js
9942
9843
  var init_esm3 = __esm({
9943
- "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.5.2/node_modules/@inquirer/core/dist/esm/index.js"() {
9844
+ "../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@25.2.3/node_modules/@inquirer/core/dist/esm/index.js"() {
9944
9845
  init_key();
9945
9846
  init_errors();
9946
9847
  init_use_prefix();
@@ -9956,7 +9857,7 @@ var init_esm3 = __esm({
9956
9857
  }
9957
9858
  });
9958
9859
 
9959
- // ../../node_modules/.pnpm/@inquirer+checkbox@4.3.2_@types+node@25.5.2/node_modules/@inquirer/checkbox/dist/esm/index.js
9860
+ // ../../node_modules/.pnpm/@inquirer+checkbox@4.3.2_@types+node@25.2.3/node_modules/@inquirer/checkbox/dist/esm/index.js
9960
9861
  function isSelectable(item) {
9961
9862
  return !Separator.isSeparator(item) && !item.disabled;
9962
9863
  }
@@ -10002,7 +9903,7 @@ function normalizeChoices(choices) {
10002
9903
  }
10003
9904
  var import_yoctocolors_cjs3, checkboxTheme, esm_default2;
10004
9905
  var init_esm4 = __esm({
10005
- "../../node_modules/.pnpm/@inquirer+checkbox@4.3.2_@types+node@25.5.2/node_modules/@inquirer/checkbox/dist/esm/index.js"() {
9906
+ "../../node_modules/.pnpm/@inquirer+checkbox@4.3.2_@types+node@25.2.3/node_modules/@inquirer/checkbox/dist/esm/index.js"() {
10006
9907
  init_esm3();
10007
9908
  init_esm2();
10008
9909
  import_yoctocolors_cjs3 = __toESM(require_yoctocolors_cjs(), 1);
@@ -19569,10 +19470,10 @@ var require_lib3 = __commonJS({
19569
19470
  }
19570
19471
  });
19571
19472
 
19572
- // ../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@25.5.2/node_modules/@inquirer/external-editor/dist/esm/errors/CreateFileError.js
19473
+ // ../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@25.2.3/node_modules/@inquirer/external-editor/dist/esm/errors/CreateFileError.js
19573
19474
  var CreateFileError;
19574
19475
  var init_CreateFileError = __esm({
19575
- "../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@25.5.2/node_modules/@inquirer/external-editor/dist/esm/errors/CreateFileError.js"() {
19476
+ "../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@25.2.3/node_modules/@inquirer/external-editor/dist/esm/errors/CreateFileError.js"() {
19576
19477
  CreateFileError = class extends Error {
19577
19478
  originalError;
19578
19479
  constructor(originalError) {
@@ -19583,10 +19484,10 @@ var init_CreateFileError = __esm({
19583
19484
  }
19584
19485
  });
19585
19486
 
19586
- // ../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@25.5.2/node_modules/@inquirer/external-editor/dist/esm/errors/LaunchEditorError.js
19487
+ // ../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@25.2.3/node_modules/@inquirer/external-editor/dist/esm/errors/LaunchEditorError.js
19587
19488
  var LaunchEditorError;
19588
19489
  var init_LaunchEditorError = __esm({
19589
- "../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@25.5.2/node_modules/@inquirer/external-editor/dist/esm/errors/LaunchEditorError.js"() {
19490
+ "../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@25.2.3/node_modules/@inquirer/external-editor/dist/esm/errors/LaunchEditorError.js"() {
19590
19491
  LaunchEditorError = class extends Error {
19591
19492
  originalError;
19592
19493
  constructor(originalError) {
@@ -19597,10 +19498,10 @@ var init_LaunchEditorError = __esm({
19597
19498
  }
19598
19499
  });
19599
19500
 
19600
- // ../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@25.5.2/node_modules/@inquirer/external-editor/dist/esm/errors/ReadFileError.js
19501
+ // ../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@25.2.3/node_modules/@inquirer/external-editor/dist/esm/errors/ReadFileError.js
19601
19502
  var ReadFileError;
19602
19503
  var init_ReadFileError = __esm({
19603
- "../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@25.5.2/node_modules/@inquirer/external-editor/dist/esm/errors/ReadFileError.js"() {
19504
+ "../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@25.2.3/node_modules/@inquirer/external-editor/dist/esm/errors/ReadFileError.js"() {
19604
19505
  ReadFileError = class extends Error {
19605
19506
  originalError;
19606
19507
  constructor(originalError) {
@@ -19611,10 +19512,10 @@ var init_ReadFileError = __esm({
19611
19512
  }
19612
19513
  });
19613
19514
 
19614
- // ../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@25.5.2/node_modules/@inquirer/external-editor/dist/esm/errors/RemoveFileError.js
19515
+ // ../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@25.2.3/node_modules/@inquirer/external-editor/dist/esm/errors/RemoveFileError.js
19615
19516
  var RemoveFileError;
19616
19517
  var init_RemoveFileError = __esm({
19617
- "../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@25.5.2/node_modules/@inquirer/external-editor/dist/esm/errors/RemoveFileError.js"() {
19518
+ "../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@25.2.3/node_modules/@inquirer/external-editor/dist/esm/errors/RemoveFileError.js"() {
19618
19519
  RemoveFileError = class extends Error {
19619
19520
  originalError;
19620
19521
  constructor(originalError) {
@@ -19625,7 +19526,7 @@ var init_RemoveFileError = __esm({
19625
19526
  }
19626
19527
  });
19627
19528
 
19628
- // ../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@25.5.2/node_modules/@inquirer/external-editor/dist/esm/index.js
19529
+ // ../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@25.2.3/node_modules/@inquirer/external-editor/dist/esm/index.js
19629
19530
  import { spawn, spawnSync } from "child_process";
19630
19531
  import { readFileSync as readFileSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync2 } from "fs";
19631
19532
  import path from "node:path";
@@ -19670,7 +19571,7 @@ function splitStringBySpace(str) {
19670
19571
  }
19671
19572
  var import_chardet, import_iconv_lite, ExternalEditor;
19672
19573
  var init_esm5 = __esm({
19673
- "../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@25.5.2/node_modules/@inquirer/external-editor/dist/esm/index.js"() {
19574
+ "../../node_modules/.pnpm/@inquirer+external-editor@1.0.3_@types+node@25.2.3/node_modules/@inquirer/external-editor/dist/esm/index.js"() {
19674
19575
  import_chardet = __toESM(require_lib2(), 1);
19675
19576
  import_iconv_lite = __toESM(require_lib3(), 1);
19676
19577
  init_CreateFileError();
@@ -19795,10 +19696,10 @@ var init_esm5 = __esm({
19795
19696
  }
19796
19697
  });
19797
19698
 
19798
- // ../../node_modules/.pnpm/@inquirer+editor@4.2.23_@types+node@25.5.2/node_modules/@inquirer/editor/dist/esm/index.js
19699
+ // ../../node_modules/.pnpm/@inquirer+editor@4.2.23_@types+node@25.2.3/node_modules/@inquirer/editor/dist/esm/index.js
19799
19700
  var editorTheme, esm_default3;
19800
19701
  var init_esm6 = __esm({
19801
- "../../node_modules/.pnpm/@inquirer+editor@4.2.23_@types+node@25.5.2/node_modules/@inquirer/editor/dist/esm/index.js"() {
19702
+ "../../node_modules/.pnpm/@inquirer+editor@4.2.23_@types+node@25.2.3/node_modules/@inquirer/editor/dist/esm/index.js"() {
19802
19703
  init_esm5();
19803
19704
  init_esm3();
19804
19705
  editorTheme = {
@@ -19871,7 +19772,7 @@ var init_esm6 = __esm({
19871
19772
  }
19872
19773
  });
19873
19774
 
19874
- // ../../node_modules/.pnpm/@inquirer+confirm@5.1.21_@types+node@25.5.2/node_modules/@inquirer/confirm/dist/esm/index.js
19775
+ // ../../node_modules/.pnpm/@inquirer+confirm@5.1.21_@types+node@25.2.3/node_modules/@inquirer/confirm/dist/esm/index.js
19875
19776
  function getBooleanValue(value, defaultValue) {
19876
19777
  let answer = defaultValue !== false;
19877
19778
  if (/^(y|yes)/i.test(value))
@@ -19885,7 +19786,7 @@ function boolToString(value) {
19885
19786
  }
19886
19787
  var esm_default4;
19887
19788
  var init_esm7 = __esm({
19888
- "../../node_modules/.pnpm/@inquirer+confirm@5.1.21_@types+node@25.5.2/node_modules/@inquirer/confirm/dist/esm/index.js"() {
19789
+ "../../node_modules/.pnpm/@inquirer+confirm@5.1.21_@types+node@25.2.3/node_modules/@inquirer/confirm/dist/esm/index.js"() {
19889
19790
  init_esm3();
19890
19791
  esm_default4 = createPrompt((config, done) => {
19891
19792
  const { transformer = boolToString } = config;
@@ -19923,10 +19824,10 @@ var init_esm7 = __esm({
19923
19824
  }
19924
19825
  });
19925
19826
 
19926
- // ../../node_modules/.pnpm/@inquirer+input@4.3.1_@types+node@25.5.2/node_modules/@inquirer/input/dist/esm/index.js
19827
+ // ../../node_modules/.pnpm/@inquirer+input@4.3.1_@types+node@25.2.3/node_modules/@inquirer/input/dist/esm/index.js
19927
19828
  var inputTheme, esm_default5;
19928
19829
  var init_esm8 = __esm({
19929
- "../../node_modules/.pnpm/@inquirer+input@4.3.1_@types+node@25.5.2/node_modules/@inquirer/input/dist/esm/index.js"() {
19830
+ "../../node_modules/.pnpm/@inquirer+input@4.3.1_@types+node@25.2.3/node_modules/@inquirer/input/dist/esm/index.js"() {
19930
19831
  init_esm3();
19931
19832
  inputTheme = {
19932
19833
  validationFailureMode: "keep"
@@ -20014,7 +19915,7 @@ var init_esm8 = __esm({
20014
19915
  }
20015
19916
  });
20016
19917
 
20017
- // ../../node_modules/.pnpm/@inquirer+number@3.0.23_@types+node@25.5.2/node_modules/@inquirer/number/dist/esm/index.js
19918
+ // ../../node_modules/.pnpm/@inquirer+number@3.0.23_@types+node@25.2.3/node_modules/@inquirer/number/dist/esm/index.js
20018
19919
  function isStepOf(value, step, min) {
20019
19920
  const valuePow = value * Math.pow(10, 6);
20020
19921
  const stepPow = step * Math.pow(10, 6);
@@ -20033,7 +19934,7 @@ function validateNumber(value, { min, max, step }) {
20033
19934
  }
20034
19935
  var esm_default6;
20035
19936
  var init_esm9 = __esm({
20036
- "../../node_modules/.pnpm/@inquirer+number@3.0.23_@types+node@25.5.2/node_modules/@inquirer/number/dist/esm/index.js"() {
19937
+ "../../node_modules/.pnpm/@inquirer+number@3.0.23_@types+node@25.2.3/node_modules/@inquirer/number/dist/esm/index.js"() {
20037
19938
  init_esm3();
20038
19939
  esm_default6 = createPrompt((config, done) => {
20039
19940
  const { validate: validate2 = () => true, min = -Infinity, max = Infinity, step = 1, required = false } = config;
@@ -20101,7 +20002,7 @@ var init_esm9 = __esm({
20101
20002
  }
20102
20003
  });
20103
20004
 
20104
- // ../../node_modules/.pnpm/@inquirer+expand@4.0.23_@types+node@25.5.2/node_modules/@inquirer/expand/dist/esm/index.js
20005
+ // ../../node_modules/.pnpm/@inquirer+expand@4.0.23_@types+node@25.2.3/node_modules/@inquirer/expand/dist/esm/index.js
20105
20006
  function normalizeChoices2(choices) {
20106
20007
  return choices.map((choice) => {
20107
20008
  if (Separator.isSeparator(choice)) {
@@ -20118,7 +20019,7 @@ function normalizeChoices2(choices) {
20118
20019
  }
20119
20020
  var import_yoctocolors_cjs4, helpChoice, esm_default7;
20120
20021
  var init_esm10 = __esm({
20121
- "../../node_modules/.pnpm/@inquirer+expand@4.0.23_@types+node@25.5.2/node_modules/@inquirer/expand/dist/esm/index.js"() {
20022
+ "../../node_modules/.pnpm/@inquirer+expand@4.0.23_@types+node@25.2.3/node_modules/@inquirer/expand/dist/esm/index.js"() {
20122
20023
  init_esm3();
20123
20024
  import_yoctocolors_cjs4 = __toESM(require_yoctocolors_cjs(), 1);
20124
20025
  init_esm3();
@@ -20204,7 +20105,7 @@ var init_esm10 = __esm({
20204
20105
  }
20205
20106
  });
20206
20107
 
20207
- // ../../node_modules/.pnpm/@inquirer+rawlist@4.1.11_@types+node@25.5.2/node_modules/@inquirer/rawlist/dist/esm/index.js
20108
+ // ../../node_modules/.pnpm/@inquirer+rawlist@4.1.11_@types+node@25.2.3/node_modules/@inquirer/rawlist/dist/esm/index.js
20208
20109
  function isSelectableChoice(choice) {
20209
20110
  return choice != null && !Separator.isSeparator(choice);
20210
20111
  }
@@ -20243,7 +20144,7 @@ function getSelectedChoice(input, choices) {
20243
20144
  }
20244
20145
  var import_yoctocolors_cjs5, numberRegex, esm_default8;
20245
20146
  var init_esm11 = __esm({
20246
- "../../node_modules/.pnpm/@inquirer+rawlist@4.1.11_@types+node@25.5.2/node_modules/@inquirer/rawlist/dist/esm/index.js"() {
20147
+ "../../node_modules/.pnpm/@inquirer+rawlist@4.1.11_@types+node@25.2.3/node_modules/@inquirer/rawlist/dist/esm/index.js"() {
20247
20148
  init_esm3();
20248
20149
  import_yoctocolors_cjs5 = __toESM(require_yoctocolors_cjs(), 1);
20249
20150
  init_esm3();
@@ -20321,10 +20222,10 @@ var init_esm11 = __esm({
20321
20222
  }
20322
20223
  });
20323
20224
 
20324
- // ../../node_modules/.pnpm/@inquirer+password@4.0.23_@types+node@25.5.2/node_modules/@inquirer/password/dist/esm/index.js
20225
+ // ../../node_modules/.pnpm/@inquirer+password@4.0.23_@types+node@25.2.3/node_modules/@inquirer/password/dist/esm/index.js
20325
20226
  var esm_default9;
20326
20227
  var init_esm12 = __esm({
20327
- "../../node_modules/.pnpm/@inquirer+password@4.0.23_@types+node@25.5.2/node_modules/@inquirer/password/dist/esm/index.js"() {
20228
+ "../../node_modules/.pnpm/@inquirer+password@4.0.23_@types+node@25.2.3/node_modules/@inquirer/password/dist/esm/index.js"() {
20328
20229
  init_esm3();
20329
20230
  init_esm2();
20330
20231
  esm_default9 = createPrompt((config, done) => {
@@ -20377,7 +20278,7 @@ var init_esm12 = __esm({
20377
20278
  }
20378
20279
  });
20379
20280
 
20380
- // ../../node_modules/.pnpm/@inquirer+search@3.2.2_@types+node@25.5.2/node_modules/@inquirer/search/dist/esm/index.js
20281
+ // ../../node_modules/.pnpm/@inquirer+search@3.2.2_@types+node@25.2.3/node_modules/@inquirer/search/dist/esm/index.js
20381
20282
  function isSelectable2(item) {
20382
20283
  return !Separator.isSeparator(item) && !item.disabled;
20383
20284
  }
@@ -20408,7 +20309,7 @@ function normalizeChoices4(choices) {
20408
20309
  }
20409
20310
  var import_yoctocolors_cjs6, searchTheme, esm_default10;
20410
20311
  var init_esm13 = __esm({
20411
- "../../node_modules/.pnpm/@inquirer+search@3.2.2_@types+node@25.5.2/node_modules/@inquirer/search/dist/esm/index.js"() {
20312
+ "../../node_modules/.pnpm/@inquirer+search@3.2.2_@types+node@25.2.3/node_modules/@inquirer/search/dist/esm/index.js"() {
20412
20313
  init_esm3();
20413
20314
  import_yoctocolors_cjs6 = __toESM(require_yoctocolors_cjs(), 1);
20414
20315
  init_esm();
@@ -20556,7 +20457,7 @@ var init_esm13 = __esm({
20556
20457
  }
20557
20458
  });
20558
20459
 
20559
- // ../../node_modules/.pnpm/@inquirer+select@4.4.2_@types+node@25.5.2/node_modules/@inquirer/select/dist/esm/index.js
20460
+ // ../../node_modules/.pnpm/@inquirer+select@4.4.2_@types+node@25.2.3/node_modules/@inquirer/select/dist/esm/index.js
20560
20461
  function isSelectable3(item) {
20561
20462
  return !Separator.isSeparator(item) && !item.disabled;
20562
20463
  }
@@ -20587,7 +20488,7 @@ function normalizeChoices5(choices) {
20587
20488
  }
20588
20489
  var import_yoctocolors_cjs7, selectTheme, esm_default11;
20589
20490
  var init_esm14 = __esm({
20590
- "../../node_modules/.pnpm/@inquirer+select@4.4.2_@types+node@25.5.2/node_modules/@inquirer/select/dist/esm/index.js"() {
20491
+ "../../node_modules/.pnpm/@inquirer+select@4.4.2_@types+node@25.2.3/node_modules/@inquirer/select/dist/esm/index.js"() {
20591
20492
  init_esm3();
20592
20493
  init_esm2();
20593
20494
  import_yoctocolors_cjs7 = __toESM(require_yoctocolors_cjs(), 1);
@@ -20729,7 +20630,7 @@ var init_esm14 = __esm({
20729
20630
  }
20730
20631
  });
20731
20632
 
20732
- // ../../node_modules/.pnpm/@inquirer+prompts@7.10.1_@types+node@25.5.2/node_modules/@inquirer/prompts/dist/esm/index.js
20633
+ // ../../node_modules/.pnpm/@inquirer+prompts@7.10.1_@types+node@25.2.3/node_modules/@inquirer/prompts/dist/esm/index.js
20733
20634
  var esm_exports = {};
20734
20635
  __export(esm_exports, {
20735
20636
  Separator: () => Separator,
@@ -20745,7 +20646,7 @@ __export(esm_exports, {
20745
20646
  select: () => esm_default11
20746
20647
  });
20747
20648
  var init_esm15 = __esm({
20748
- "../../node_modules/.pnpm/@inquirer+prompts@7.10.1_@types+node@25.5.2/node_modules/@inquirer/prompts/dist/esm/index.js"() {
20649
+ "../../node_modules/.pnpm/@inquirer+prompts@7.10.1_@types+node@25.2.3/node_modules/@inquirer/prompts/dist/esm/index.js"() {
20749
20650
  init_esm4();
20750
20651
  init_esm6();
20751
20652
  init_esm7();
@@ -21524,6 +21425,20 @@ function createLogger(_name) {
21524
21425
  }
21525
21426
 
21526
21427
  // src/public-core-shim.ts
21428
+ function normalizeWatchlistSymbol(value) {
21429
+ const trimmed = value.trim();
21430
+ if (trimmed.length === 0) return trimmed;
21431
+ const colonIndex = trimmed.indexOf(":");
21432
+ if (colonIndex <= 0 || colonIndex === trimmed.length - 1) {
21433
+ return trimmed.toUpperCase();
21434
+ }
21435
+ const prefix = trimmed.slice(0, colonIndex).toLowerCase();
21436
+ const symbol = trimmed.slice(colonIndex + 1).toUpperCase();
21437
+ return `${prefix}:${symbol}`;
21438
+ }
21439
+ function normalizeWatchlistSymbols(values) {
21440
+ return values.map(normalizeWatchlistSymbol);
21441
+ }
21527
21442
  var EventType = {
21528
21443
  TOKEN_UNLOCK: "TOKEN_UNLOCK",
21529
21444
  GOVERNANCE_VOTE: "GOVERNANCE_VOTE",
@@ -21687,6 +21602,17 @@ function formatMarketSection(market) {
21687
21602
  if (market.openInterestChange24h !== null) {
21688
21603
  lines.push(` ${source_default.gray("OI Change (24h):")} ${colorChange(market.openInterestChange24h)}`);
21689
21604
  }
21605
+ if (market.movingAverages) {
21606
+ const ma = market.movingAverages;
21607
+ const formatMaybeUsd = (value) => value === null ? source_default.dim("n/a") : formatUsd(value);
21608
+ const formatMaybePct = (value) => value === null ? source_default.dim("n/a") : colorChange(value * 100);
21609
+ lines.push(` ${source_default.gray("MA Trend:")} ${source_default.white(ma.maTrend)} ${source_default.dim(`(${ma.crossSignal})`)}`);
21610
+ lines.push(` ${source_default.gray("SMA 20/50/200:")} ${formatMaybeUsd(ma.sma20)} / ${formatMaybeUsd(ma.sma50)} / ${formatMaybeUsd(ma.sma200)}`);
21611
+ lines.push(` ${source_default.gray("Price vs SMA:")} 20d ${formatMaybePct(ma.priceVsSma20)} | 50d ${formatMaybePct(ma.priceVsSma50)} | 200d ${formatMaybePct(ma.priceVsSma200)}`);
21612
+ if (ma.status === "insufficient_history") {
21613
+ lines.push(` ${source_default.gray("MA History:")} ${source_default.yellow(`${ma.historyDays}/${ma.requiredHistoryDays} daily bars`)}`);
21614
+ }
21615
+ }
21690
21616
  return lines.join("\n");
21691
21617
  }
21692
21618
  function formatOnchainSection(onchain) {
@@ -22546,6 +22472,7 @@ init_utils();
22546
22472
  init_api_client();
22547
22473
  init_esm15();
22548
22474
  var logger9 = createLogger("cli-trader");
22475
+ var ALIAS_PATTERN = /^[a-zA-Z0-9_-]{3,30}$/;
22549
22476
  function formatTraderOutput(trader, wallets) {
22550
22477
  const lines = [];
22551
22478
  lines.push("");
@@ -22569,6 +22496,10 @@ function formatTraderOutput(trader, wallets) {
22569
22496
  lines.push(` ${source_default.dim("\u2022")} ${source_default.white(w.address)} ${source_default.dim(`(${w.chain})`)} ${source_default.dim(`since ${w.since}`)}`);
22570
22497
  }
22571
22498
  }
22499
+ lines.push(` ${source_default.gray("Public Board:")} ${trader.benchmarkOptIn ? source_default.green("visible") : source_default.dim("private")}`);
22500
+ if (trader.publicAlias) {
22501
+ lines.push(` ${source_default.gray("Public Alias:")} ${source_default.white(trader.publicAlias)}`);
22502
+ }
22572
22503
  lines.push("");
22573
22504
  lines.push(` ${source_default.gray("Created:")} ${source_default.dim(trader.createdAt)}`);
22574
22505
  lines.push(` ${source_default.gray("Updated:")} ${source_default.dim(trader.updatedAt)}`);
@@ -22600,14 +22531,26 @@ function formatTraderListOutput(traders) {
22600
22531
  }
22601
22532
  function registerTraderCommand(program2) {
22602
22533
  const trader = program2.command("trader").description("Manage trader profiles");
22603
- trader.command("register").description("Register a new trader profile").requiredOption("--name <name>", "Trader display name").option("--wallet <address>", "Initial Solana wallet address").option("--max-drawdown <pct>", "Max acceptable drawdown percentage", parseFloatOption).addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (options) => {
22534
+ trader.command("register").description("Register a new trader profile").requiredOption("--name <name>", "Trader display name").option("--wallet <address>", "Initial Solana wallet address").option("--max-drawdown <pct>", "Max acceptable drawdown percentage", parseFloatOption).option("--public-leaderboard", "Opt this trader into the public leaderboard").option("--alias <alias>", "Public leaderboard alias for --public-leaderboard").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (options) => {
22535
+ if (options.publicLeaderboard && !options.alias) {
22536
+ console.error(source_default.red("Error: --alias is required with --public-leaderboard."));
22537
+ process.exitCode = 1;
22538
+ return;
22539
+ }
22540
+ if (options.alias && !ALIAS_PATTERN.test(options.alias)) {
22541
+ console.error(source_default.red("Error: Invalid alias. Must be 3-30 characters, alphanumeric with underscores and hyphens."));
22542
+ process.exitCode = 1;
22543
+ return;
22544
+ }
22604
22545
  try {
22605
22546
  const result = await apiRequest("/api/v1/traders", {
22606
22547
  method: "POST",
22607
22548
  body: {
22608
22549
  name: options.name,
22609
22550
  wallet: options.wallet,
22610
- maxDrawdown: options.maxDrawdown
22551
+ maxDrawdown: options.maxDrawdown,
22552
+ benchmarkOptIn: options.publicLeaderboard === true,
22553
+ publicAlias: options.alias
22611
22554
  }
22612
22555
  });
22613
22556
  const traderId = result.name ?? result.id;
@@ -22623,8 +22566,11 @@ function registerTraderCommand(program2) {
22623
22566
  } else {
22624
22567
  console.log(formatTraderOutput(result));
22625
22568
  console.log(source_default.green(" Trader registered successfully."));
22626
- if (result.alias) {
22627
- console.log(` ${source_default.gray("Leaderboard alias:")} ${source_default.white(result.alias)} ${source_default.dim("(change with: trading-boy trader set-alias <name> <alias>)")}`);
22569
+ if (result.publicAlias) {
22570
+ console.log(` ${source_default.gray("Leaderboard alias:")} ${source_default.white(result.publicAlias)} ${source_default.dim("(change with: trading-boy trader set-alias <name> <alias>)")}`);
22571
+ } else {
22572
+ console.log(` ${source_default.gray("Public leaderboard:")} ${source_default.dim("private by default")}`);
22573
+ console.log(` ${source_default.dim("Opt in later:")} ${source_default.white("trading-boy trader leaderboard opt-in <name> <alias>")}`);
22628
22574
  }
22629
22575
  console.log("");
22630
22576
  console.log(source_default.bold(" Next: Set up your trading identity"));
@@ -22710,7 +22656,46 @@ function registerTraderCommand(program2) {
22710
22656
  process.exitCode = error2 instanceof ApiError ? 2 : 1;
22711
22657
  }
22712
22658
  });
22713
- const ALIAS_PATTERN = /^[a-zA-Z0-9_-]{3,30}$/;
22659
+ const leaderboard = trader.command("leaderboard").description("Manage public leaderboard visibility");
22660
+ leaderboard.command("opt-in").description("Show a trader on the public leaderboard").argument("<name-or-id>", "Trader name or ID").argument("<alias>", "Public alias (3-30 chars, alphanumeric/underscores/hyphens)").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (nameOrId, alias, options) => {
22661
+ const jsonMode = options.format === "json";
22662
+ if (!ALIAS_PATTERN.test(alias)) {
22663
+ const msg = "Invalid alias. Must be 3-30 characters, alphanumeric with underscores and hyphens.";
22664
+ if (jsonMode)
22665
+ console.error(JSON.stringify({ error: msg }));
22666
+ else
22667
+ console.error(source_default.red(` ${msg}`));
22668
+ process.exitCode = 1;
22669
+ return;
22670
+ }
22671
+ try {
22672
+ const result = await apiRequest(`/api/v1/traders/${encodeURIComponent(nameOrId)}/public-profile`, { method: "PATCH", body: { benchmarkOptIn: true, publicAlias: alias } });
22673
+ if (jsonMode) {
22674
+ console.log(JSON.stringify(result));
22675
+ } else {
22676
+ console.log("");
22677
+ console.log(source_default.green(` Public leaderboard enabled as: ${source_default.white(result.publicAlias)}`));
22678
+ console.log("");
22679
+ }
22680
+ } catch (error2) {
22681
+ handlePublicProfileError(error2, jsonMode, "enable public leaderboard");
22682
+ }
22683
+ });
22684
+ leaderboard.command("opt-out").description("Hide a trader from the public leaderboard").argument("<name-or-id>", "Trader name or ID").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (nameOrId, options) => {
22685
+ const jsonMode = options.format === "json";
22686
+ try {
22687
+ const result = await apiRequest(`/api/v1/traders/${encodeURIComponent(nameOrId)}/public-profile`, { method: "PATCH", body: { benchmarkOptIn: false } });
22688
+ if (jsonMode) {
22689
+ console.log(JSON.stringify(result));
22690
+ } else {
22691
+ console.log("");
22692
+ console.log(source_default.green(" Public leaderboard disabled. This trader is private."));
22693
+ console.log("");
22694
+ }
22695
+ } catch (error2) {
22696
+ handlePublicProfileError(error2, jsonMode, "disable public leaderboard");
22697
+ }
22698
+ });
22714
22699
  trader.command("set-alias").description("Set a public leaderboard alias").argument("<name-or-id>", "Trader name or ID").argument("<alias>", "Leaderboard alias (3-30 chars, alphanumeric/underscores/hyphens)").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (nameOrId, alias, options) => {
22715
22700
  const jsonMode = options.format === "json";
22716
22701
  if (!ALIAS_PATTERN.test(alias)) {
@@ -23284,6 +23269,19 @@ function handleAgentError(error2, jsonMode, agentId, action) {
23284
23269
  }
23285
23270
  process.exitCode = error2 instanceof ApiError ? 2 : 1;
23286
23271
  }
23272
+ function handlePublicProfileError(error2, jsonMode, action) {
23273
+ let message = error2 instanceof Error ? error2.message : String(error2);
23274
+ if (error2 instanceof ApiError && error2.status === 409) {
23275
+ message = "Alias already taken. Try a different name.";
23276
+ }
23277
+ logger9.error({ error: message }, `Failed to ${action}`);
23278
+ if (jsonMode) {
23279
+ console.error(JSON.stringify({ error: message }));
23280
+ } else {
23281
+ console.error(source_default.red(`Error: ${message}`));
23282
+ }
23283
+ process.exitCode = error2 instanceof ApiError ? 2 : 1;
23284
+ }
23287
23285
  function parseFloatOption(value) {
23288
23286
  return parseFloat(value);
23289
23287
  }
@@ -24556,8 +24554,8 @@ function registerConfigCommand(program2) {
24556
24554
  console.log(` ${source_default.gray("API URL:")} ${apiBase}`);
24557
24555
  console.log(` ${source_default.gray("LLM Status:")} ${llmStatus}`);
24558
24556
  if (llmStatus === "missing") {
24559
- console.log(source_default.dim(" Run: trading-boy config set-llm-key <your-api-key>"));
24560
- console.log(source_default.dim(" Or: trading-boy connect-chatgpt"));
24557
+ console.log(source_default.dim(" Add an LLM provider API key: trading-boy config set-llm-key <your-llm-provider-api-key>"));
24558
+ console.log(source_default.dim(" Or connect ChatGPT: trading-boy connect-chatgpt"));
24561
24559
  console.log("");
24562
24560
  return;
24563
24561
  }
@@ -24568,7 +24566,7 @@ function registerConfigCommand(program2) {
24568
24566
  }
24569
24567
  printLlmConfig(llmConfig);
24570
24568
  });
24571
- configCmd.command("set-llm-key <apiKey>").description("Store your LLM API key for thesis extraction + coaching (BYOK)").addOption(new Option("-p, --provider <provider>", "LLM provider (auto-detected from key prefix if omitted)").choices(["anthropic", "openai", "openrouter", "ollama", "gemini", "groq", "deepseek", "codex", "custom"])).option("-m, --model <model>", "Model name (default for all phases)").option("--base-url <url>", "Custom base URL (for openrouter/ollama/custom providers)").option("--scan-model <model>", "Model for market scanning").option("--analyze-model <model>", "Model for deep analysis").option("--decide-model <model>", "Model for trade decisions").addOption(new Option("--scan-provider <provider>", "Provider for scan phase").choices(["anthropic", "openai", "openrouter", "ollama", "gemini", "groq", "deepseek", "custom"])).option("--scan-key <key>", "API key for scan phase provider").addOption(new Option("--analyze-provider <provider>", "Provider for analyze phase").choices(["anthropic", "openai", "openrouter", "ollama", "gemini", "groq", "deepseek", "custom"])).option("--analyze-key <key>", "API key for analyze phase provider").addOption(new Option("--decide-provider <provider>", "Provider for decide phase").choices(["anthropic", "openai", "openrouter", "ollama", "gemini", "groq", "deepseek", "custom"])).option("--decide-key <key>", "API key for decide phase provider").action(async (apiKey, opts) => {
24569
+ configCmd.command("set-llm-key <apiKey>").description("Store your LLM provider API key for agents, thesis extraction, and coaching (BYOK)").addOption(new Option("-p, --provider <provider>", "LLM provider (auto-detected from key prefix if omitted)").choices(["anthropic", "openai", "openrouter", "ollama", "gemini", "groq", "deepseek", "codex", "custom"])).option("-m, --model <model>", "Model name (default for all phases)").option("--base-url <url>", "Custom base URL (for openrouter/ollama/custom providers)").option("--scan-model <model>", "Model for market scanning").option("--analyze-model <model>", "Model for deep analysis").option("--decide-model <model>", "Model for trade decisions").addOption(new Option("--scan-provider <provider>", "Provider for scan phase").choices(["anthropic", "openai", "openrouter", "ollama", "gemini", "groq", "deepseek", "custom"])).option("--scan-key <key>", "LLM provider API key for the scan phase").addOption(new Option("--analyze-provider <provider>", "Provider for analyze phase").choices(["anthropic", "openai", "openrouter", "ollama", "gemini", "groq", "deepseek", "custom"])).option("--analyze-key <key>", "LLM provider API key for the analyze phase").addOption(new Option("--decide-provider <provider>", "Provider for decide phase").choices(["anthropic", "openai", "openrouter", "ollama", "gemini", "groq", "deepseek", "custom"])).option("--decide-key <key>", "LLM provider API key for the decide phase").action(async (apiKey, opts) => {
24572
24570
  if (!await ensureRemote())
24573
24571
  return;
24574
24572
  try {
@@ -24591,7 +24589,7 @@ function registerConfigCommand(program2) {
24591
24589
  }
24592
24590
  });
24593
24591
  console.log("");
24594
- console.log(source_default.green(" LLM API key saved successfully"));
24592
+ console.log(source_default.green(" LLM provider API key saved successfully"));
24595
24593
  console.log(` ${source_default.gray("Provider:")} ${result.provider}`);
24596
24594
  if (result.effectiveProvider && (result.effectiveProvider !== result.provider || result.effectiveModel !== result.model)) {
24597
24595
  console.log(` ${source_default.gray("Effective:")} ${result.effectiveProvider} / ${result.effectiveModel ?? result.model}`);
@@ -24606,9 +24604,9 @@ function registerConfigCommand(program2) {
24606
24604
  if (result.decideProvider || result.decideModel) {
24607
24605
  console.log(` ${source_default.gray("Decide:")} ${result.decideProvider ?? result.provider} / ${result.decideModel ?? result.model}${opts.decideKey ? " (own key)" : ""}`);
24608
24606
  }
24609
- console.log(` ${source_default.gray("Key:")} ${apiKey.slice(0, 8)}${"*".repeat(Math.max(0, apiKey.length - 8))}`);
24607
+ console.log(` ${source_default.gray("LLM key:")} ${apiKey.slice(0, 8)}${"*".repeat(Math.max(0, apiKey.length - 8))}`);
24610
24608
  console.log("");
24611
- console.log(source_default.dim(" Your key is encrypted at rest. Thesis extraction and coaching are now enabled."));
24609
+ console.log(source_default.dim(" Your LLM provider API key is encrypted at rest. Agents, thesis extraction, and coaching are now enabled."));
24612
24610
  console.log("");
24613
24611
  } catch (error2) {
24614
24612
  const message = error2 instanceof Error ? error2.message : String(error2);
@@ -24617,7 +24615,7 @@ function registerConfigCommand(program2) {
24617
24615
  process.exitCode = error2 instanceof ApiError ? 2 : 1;
24618
24616
  }
24619
24617
  });
24620
- configCmd.command("set-models").description("Update per-stage model assignments (works with API key or ChatGPT OAuth)").option("-m, --model <model>", "Default model for all phases").option("--scan-model <model>", "Model for market scanning").option("--analyze-model <model>", "Model for deep analysis").option("--decide-model <model>", "Model for trade decisions").option("--exit-heartbeat-model <model>", "Model for exit heartbeat checks").option("--exit-event-model <model>", "Model for exit event-driven analysis").action(async (opts) => {
24618
+ configCmd.command("set-models").description("Update per-stage model assignments (works with BYOK or a ChatGPT connection)").option("-m, --model <model>", "Default model for all phases").option("--scan-model <model>", "Model for market scanning").option("--analyze-model <model>", "Model for deep analysis").option("--decide-model <model>", "Model for trade decisions").option("--exit-heartbeat-model <model>", "Model for exit heartbeat checks").option("--exit-event-model <model>", "Model for exit event-driven analysis").action(async (opts) => {
24621
24619
  if (!await ensureRemote())
24622
24620
  return;
24623
24621
  if (!opts.model && !opts.scanModel && !opts.analyzeModel && !opts.decideModel && !opts.exitHeartbeatModel && !opts.exitEventModel) {
@@ -24757,7 +24755,7 @@ async function executeLogin(apiKey) {
24757
24755
  };
24758
24756
  }
24759
24757
  function registerLoginCommand(program2) {
24760
- program2.command("login").description("Authenticate with your Trading Boy API key").addOption(new Option("--api-key <key>", "API key (deprecated \u2014 use TRADING_BOY_API_KEY env var)").hideHelp()).action(async (opts) => {
24758
+ program2.command("login").description("Authenticate your Trading Boy account with a Trading Boy API key").addOption(new Option("--api-key <key>", "Trading Boy API key (deprecated \u2014 use TRADING_BOY_API_KEY env var)").hideHelp()).action(async (opts) => {
24761
24759
  try {
24762
24760
  let apiKey;
24763
24761
  if (opts.apiKey) {
@@ -24768,23 +24766,24 @@ function registerLoginCommand(program2) {
24768
24766
  console.log("");
24769
24767
  console.log(source_default.bold(" Trading Boy \u2014 Login"));
24770
24768
  console.log(source_default.gray(" " + "\u2500".repeat(40)));
24771
- console.log(source_default.dim(" Don't have a key? Run: trading-boy subscribe"));
24769
+ console.log(source_default.dim(" Authenticate your Trading Boy account on this machine."));
24770
+ console.log(source_default.dim(" Don't have a Trading Boy API key yet? Run: trading-boy subscribe"));
24772
24771
  console.log("");
24773
24772
  apiKey = await password({
24774
- message: "Enter your API key",
24773
+ message: "Enter your Trading Boy API key",
24775
24774
  mask: "*",
24776
24775
  validate: (input) => {
24777
24776
  if (!input)
24778
- return "API key is required";
24777
+ return "Trading Boy API key is required";
24779
24778
  if (!validateApiKeyFormat(input)) {
24780
- return "Invalid key format. Expected: tb_live_<32hex>, tb_test_<32hex>, or tb_free_<32hex>";
24779
+ return "Invalid Trading Boy API key format. Expected: tb_live_<32hex>, tb_test_<32hex>, or tb_free_<32hex>";
24781
24780
  }
24782
24781
  return true;
24783
24782
  }
24784
24783
  });
24785
24784
  }
24786
24785
  if (!validateApiKeyFormat(apiKey)) {
24787
- console.error(source_default.red(" Invalid key format. Expected: tb_live_<32hex>, tb_test_<32hex>, or tb_free_<32hex>"));
24786
+ console.error(source_default.red(" Invalid Trading Boy API key format. Expected: tb_live_<32hex>, tb_test_<32hex>, or tb_free_<32hex>"));
24788
24787
  process.exitCode = 1;
24789
24788
  return;
24790
24789
  }
@@ -24792,7 +24791,7 @@ function registerLoginCommand(program2) {
24792
24791
  const spinner = (await createSpinner2(" Verifying key...")).start();
24793
24792
  const result = await executeLogin(apiKey);
24794
24793
  if (!result.success) {
24795
- spinner.fail(" Invalid API key");
24794
+ spinner.fail(" Invalid Trading Boy API key");
24796
24795
  process.exitCode = 1;
24797
24796
  return;
24798
24797
  }
@@ -24807,7 +24806,7 @@ function registerLoginCommand(program2) {
24807
24806
  if (result.keyId) {
24808
24807
  console.log(` ${source_default.gray("Key ID:")} ${result.keyId}`);
24809
24808
  }
24810
- console.log(` ${source_default.gray("Key:")} ${redactApiKey(apiKey)}`);
24809
+ console.log(` ${source_default.gray("Trading Boy API key:")} ${redactApiKey(apiKey)}`);
24811
24810
  console.log("");
24812
24811
  } catch (error2) {
24813
24812
  const message = error2 instanceof Error ? error2.message : String(error2);
@@ -25164,6 +25163,27 @@ init_api_client();
25164
25163
  // dist/commands/onboarding.js
25165
25164
  init_source();
25166
25165
  init_api_client();
25166
+
25167
+ // dist/product-events.js
25168
+ init_logger();
25169
+ init_api_client();
25170
+ var logger19 = createLogger2("cli-product-events");
25171
+ function emitCliProductEvent(eventType, metadata = {}) {
25172
+ void apiRequest("/api/v1/product-events", {
25173
+ method: "POST",
25174
+ body: {
25175
+ eventType,
25176
+ metadata
25177
+ }
25178
+ }).catch((error2) => {
25179
+ logger19.warn({
25180
+ eventType,
25181
+ error: error2 instanceof Error ? error2.message : String(error2)
25182
+ }, "Failed to emit CLI product event");
25183
+ });
25184
+ }
25185
+
25186
+ // dist/commands/onboarding.js
25167
25187
  init_soul_wizard();
25168
25188
 
25169
25189
  // dist/commands/connect-chatgpt.js
@@ -25172,16 +25192,16 @@ import http from "node:http";
25172
25192
  import { URL as URL2 } from "node:url";
25173
25193
  init_api_client();
25174
25194
  init_utils();
25175
- var logger19 = createLogger("cli-connect-chatgpt");
25195
+ var logger20 = createLogger("cli-connect-chatgpt");
25176
25196
  var CALLBACK_PORT = 1455;
25177
25197
  var CALLBACK_PATH = "/auth/callback";
25178
25198
  var AUTH_TIMEOUT_MS = 3 * 60 * 1e3;
25179
25199
  var POLL_INTERVAL_MS = 2e3;
25180
25200
  function registerConnectChatgptCommand(program2) {
25181
- program2.command("connect-chatgpt").description("Connect your ChatGPT subscription as your LLM provider (no API key needed)").option("--disconnect", "Disconnect your ChatGPT account").action(async (options) => {
25201
+ program2.command("connect-chatgpt").description("Connect your ChatGPT subscription as your agent LLM provider (after Trading Boy login)").option("--disconnect", "Disconnect your ChatGPT account").action(async (options) => {
25182
25202
  try {
25183
25203
  if (!await isRemoteMode()) {
25184
- console.error(source_default.yellow(" Requires API connection. Run: trading-boy login"));
25204
+ console.error(source_default.yellow(" Requires Trading Boy account auth on this machine. Run: trading-boy login"));
25185
25205
  process.exitCode = 1;
25186
25206
  return;
25187
25207
  }
@@ -25192,7 +25212,7 @@ function registerConnectChatgptCommand(program2) {
25192
25212
  }
25193
25213
  } catch (error2) {
25194
25214
  const msg = error2 instanceof Error ? error2.message : String(error2);
25195
- logger19.error({ error: msg }, "connect-chatgpt failed");
25215
+ logger20.error({ error: msg }, "connect-chatgpt failed");
25196
25216
  const connHelp = formatConnectionError(msg);
25197
25217
  if (connHelp) {
25198
25218
  console.error(source_default.red(`
@@ -25224,8 +25244,9 @@ async function handleConnect() {
25224
25244
  console.log("");
25225
25245
  console.log(source_default.bold.cyan(" Connect ChatGPT"));
25226
25246
  console.log(source_default.gray(" " + "\u2500".repeat(50)));
25247
+ console.log(source_default.dim(" Your Trading Boy account is already authenticated."));
25227
25248
  console.log(source_default.dim(" Use your ChatGPT subscription to power your trading agents."));
25228
- console.log(source_default.dim(" No API key needed \u2014 authenticates via your OpenAI account."));
25249
+ console.log(source_default.dim(" No LLM provider API key needed \u2014 sign in with your OpenAI account instead."));
25229
25250
  console.log("");
25230
25251
  const { authUrl, state } = await apiRequest("/api/v1/codex/auth-url");
25231
25252
  const result = await raceForAuth(authUrl, state);
@@ -25250,7 +25271,7 @@ function printSuccess(accountId, model) {
25250
25271
  if (model)
25251
25272
  console.log(` ${source_default.gray("Model:")} ${model}`);
25252
25273
  console.log("");
25253
- console.log(source_default.dim(" Your agents will now use your ChatGPT subscription for LLM calls."));
25274
+ console.log(source_default.dim(" Your agents will now use your ChatGPT connection for LLM calls."));
25254
25275
  console.log(source_default.dim(" Change model: trading-boy config set-models --model <model>"));
25255
25276
  }
25256
25277
  async function raceForAuth(authUrl, state) {
@@ -25320,7 +25341,7 @@ function startLocalCallbackServer(state, signal) {
25320
25341
  server.on("error", (err) => {
25321
25342
  clearTimeout(timeout);
25322
25343
  if (err.code === "EADDRINUSE") {
25323
- logger19.debug("Port %d in use, falling back to polling only", CALLBACK_PORT);
25344
+ logger20.debug("Port %d in use, falling back to polling only", CALLBACK_PORT);
25324
25345
  return;
25325
25346
  }
25326
25347
  reject(err);
@@ -25342,7 +25363,7 @@ async function pollForConnection(signal) {
25342
25363
  return { via: "poll", config };
25343
25364
  }
25344
25365
  } catch {
25345
- logger19.debug("Poll attempt failed, retrying...");
25366
+ logger20.debug("Poll attempt failed, retrying...");
25346
25367
  }
25347
25368
  }
25348
25369
  throw new Error("Timed out waiting for OpenAI authentication (3 minutes)");
@@ -25361,8 +25382,8 @@ async function handleDisconnect() {
25361
25382
  method: "POST"
25362
25383
  });
25363
25384
  console.log(source_default.green(" \u2713 ChatGPT disconnected."));
25364
- console.log(source_default.dim(" Your agents will need an API key to continue. Set one:"));
25365
- console.log(source_default.dim(" trading-boy config set-llm-key <your-api-key>"));
25385
+ console.log(source_default.dim(" Your agents will need another LLM provider connection to continue. Set one:"));
25386
+ console.log(source_default.dim(" trading-boy config set-llm-key <your-llm-provider-api-key>"));
25366
25387
  }
25367
25388
  function callbackHtml(success2, errorMsg) {
25368
25389
  const title = success2 ? "ChatGPT Connected" : "Connection Failed";
@@ -25418,15 +25439,66 @@ async function openBrowser(url) {
25418
25439
  }
25419
25440
 
25420
25441
  // dist/commands/onboarding.js
25442
+ var DEFAULT_FIRST_AGENT_AUTONOMY = "FULLY_AUTONOMOUS";
25443
+ var MIN_SCAN_INTERVAL_MS = 6e4;
25444
+ var LEADERBOARD_ALIAS_PATTERN = /^[a-zA-Z0-9_-]{3,30}$/;
25445
+ function defaultLeaderboardAlias(name) {
25446
+ const normalized = name.trim().replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
25447
+ const alias = normalized || "trader";
25448
+ return alias.slice(0, 24);
25449
+ }
25450
+ function trackOnboardingEvent(eventType, metadata = {}) {
25451
+ try {
25452
+ emitCliProductEvent(eventType, {
25453
+ source: "cli_onboarding",
25454
+ ...metadata
25455
+ });
25456
+ } catch {
25457
+ }
25458
+ }
25421
25459
  async function runOnboarding() {
25422
- const { confirm, input } = await Promise.resolve().then(() => (init_esm15(), esm_exports));
25460
+ const { confirm, input, select } = await Promise.resolve().then(() => (init_esm15(), esm_exports));
25461
+ trackOnboardingEvent("cli.onboarding.started");
25423
25462
  console.log("");
25424
- console.log(source_default.bold.cyan(" Get Started"));
25463
+ console.log(source_default.bold.cyan(" Get Started With Trading Boy"));
25425
25464
  console.log(source_default.gray(" " + "\u2500".repeat(50)));
25426
- console.log(source_default.dim(" Let\u2019s set up your account. You can skip any step."));
25465
+ console.log(source_default.dim(" Trading Boy can be used two ways: manual context and journaling, or hosted agents."));
25466
+ console.log(source_default.dim(" Trading Boy account auth gets you into the product."));
25467
+ console.log(source_default.dim(" ChatGPT or an LLM provider API key powers agent decisions."));
25427
25468
  console.log("");
25469
+ let onboardingPath;
25470
+ try {
25471
+ onboardingPath = await select({
25472
+ message: "What do you want to set up first?",
25473
+ choices: [
25474
+ {
25475
+ name: "Explore context and journal",
25476
+ value: "explore",
25477
+ description: "Start with context, decisions, and journaling. Skip agent setup for now."
25478
+ },
25479
+ {
25480
+ name: "Build my first agent",
25481
+ value: "agent",
25482
+ description: "Set up hosted-agent prerequisites and review runtime behavior."
25483
+ }
25484
+ ]
25485
+ });
25486
+ } catch (error2) {
25487
+ if (isUserAbort(error2))
25488
+ return;
25489
+ throw error2;
25490
+ }
25491
+ trackOnboardingEvent("cli.onboarding.path_selected", {
25492
+ path: onboardingPath === "explore" ? "explore_manual" : "build_agent"
25493
+ });
25494
+ if (onboardingPath === "explore") {
25495
+ printExploreQuickReference();
25496
+ trackOnboardingEvent("cli.onboarding.completed", { path: "explore_manual" });
25497
+ return;
25498
+ }
25428
25499
  let traderRegistered = false;
25429
25500
  let traderName = "default";
25501
+ let traderId = null;
25430
25502
  try {
25431
25503
  const wantsTrader = await confirm({
25432
25504
  message: "Register your trader profile?",
@@ -25448,19 +25520,40 @@ async function runOnboarding() {
25448
25520
  return true;
25449
25521
  }
25450
25522
  });
25523
+ const benchmarkOptIn = await confirm({
25524
+ message: "Show this trader on the public leaderboard? You can opt in later from the CLI.",
25525
+ default: false
25526
+ });
25527
+ let publicAlias;
25528
+ if (benchmarkOptIn) {
25529
+ publicAlias = await input({
25530
+ message: "Public leaderboard alias (3-30 letters, numbers, underscores, or hyphens)",
25531
+ default: defaultLeaderboardAlias(name),
25532
+ validate: (v) => LEADERBOARD_ALIAS_PATTERN.test(v.trim()) ? true : "Alias must be 3-30 characters using letters, numbers, underscores, or hyphens."
25533
+ });
25534
+ }
25451
25535
  try {
25452
25536
  if (await isRemoteMode()) {
25453
25537
  const result = await apiRequest("/api/v1/traders", {
25454
25538
  method: "POST",
25455
- body: { name: name.trim(), riskToleranceMax: parseFloat(maxDrawdown) }
25539
+ body: {
25540
+ name: name.trim(),
25541
+ maxDrawdown: parseFloat(maxDrawdown),
25542
+ benchmarkOptIn,
25543
+ publicAlias: publicAlias?.trim()
25544
+ }
25456
25545
  });
25457
25546
  console.log(source_default.green(` \u2713 Trader "${result.name}" registered (id: ${result.id})`));
25458
25547
  if (result.publicAlias) {
25459
25548
  console.log(source_default.dim(` Leaderboard alias: ${result.publicAlias}`));
25460
25549
  console.log(source_default.dim(" This alias is public on the leaderboard. Change it anytime:"));
25461
25550
  console.log(source_default.dim(" trading-boy trader set-alias <name> <new-alias>"));
25551
+ } else {
25552
+ console.log(source_default.dim(" Public leaderboard: private. Opt in later with:"));
25553
+ console.log(source_default.dim(" trading-boy trader leaderboard opt-in <name> <alias>"));
25462
25554
  }
25463
25555
  traderName = name.trim();
25556
+ traderId = result.id;
25464
25557
  traderRegistered = true;
25465
25558
  } else {
25466
25559
  console.log(source_default.yellow(" Skipped \u2014 not connected to API. Run: trading-boy trader register"));
@@ -25470,6 +25563,7 @@ async function runOnboarding() {
25470
25563
  console.log(source_default.green(" \u2713 Trader profile already exists."));
25471
25564
  traderName = name.trim();
25472
25565
  traderRegistered = true;
25566
+ traderId = await resolveTraderId(name.trim());
25473
25567
  } else {
25474
25568
  const msg = error2 instanceof Error ? error2.message : String(error2);
25475
25569
  console.log(source_default.yellow(` Could not register trader: ${msg}`));
@@ -25485,54 +25579,24 @@ async function runOnboarding() {
25485
25579
  throw error2;
25486
25580
  }
25487
25581
  console.log("");
25488
- if (traderRegistered) {
25489
- try {
25490
- const wantsIdentity = await confirm({
25491
- message: "Set up your trading identity? (interactive SOUL wizard)",
25492
- default: true
25493
- });
25494
- if (wantsIdentity) {
25495
- console.log("");
25496
- console.log(source_default.dim(" Your identity personalizes context \u2014 bias warnings, scope checks,"));
25497
- console.log(source_default.dim(" and tailored synthesis based on who you are as a trader."));
25498
- console.log("");
25499
- try {
25500
- await runSoulWizardAndUpload(traderName);
25501
- } catch (wizardError) {
25502
- if (isUserAbort(wizardError))
25503
- return;
25504
- const msg = wizardError instanceof Error ? wizardError.message : String(wizardError);
25505
- console.log(source_default.yellow(` Could not complete SOUL wizard: ${msg}`));
25506
- console.log(source_default.dim(" You can do this later: trading-boy trader soul-wizard <name>"));
25507
- }
25508
- } else {
25509
- console.log(source_default.dim(" Skipped. Run later: trading-boy trader soul-wizard <name>"));
25510
- }
25511
- } catch (error2) {
25512
- if (isUserAbort(error2))
25513
- return;
25514
- throw error2;
25515
- }
25516
- console.log("");
25517
- }
25518
25582
  try {
25519
25583
  console.log(source_default.bold.cyan(" LLM Provider (required for agents)"));
25520
25584
  console.log(source_default.gray(" " + "\u2500".repeat(50)));
25585
+ console.log(source_default.dim(" Your Trading Boy account is already authenticated."));
25521
25586
  console.log(source_default.dim(" Your agent needs an LLM to analyze markets and make decisions."));
25522
25587
  console.log("");
25523
- const { select } = await Promise.resolve().then(() => (init_esm15(), esm_exports));
25524
25588
  const llmChoice = await select({
25525
25589
  message: "How do you want to power your agent?",
25526
25590
  choices: [
25527
25591
  {
25528
- name: "Use my ChatGPT subscription (no API key needed)",
25592
+ name: "Use my ChatGPT subscription (OpenAI sign-in, no LLM provider API key)",
25529
25593
  value: "chatgpt",
25530
- description: "Sign in with your OpenAI account \u2014 uses your existing ChatGPT Plus/Pro/Team plan"
25594
+ description: "Connect ChatGPT after Trading Boy login \u2014 uses your existing ChatGPT Plus/Pro/Team plan"
25531
25595
  },
25532
25596
  {
25533
- name: "Bring my own API key (Anthropic, Gemini, OpenAI, etc.)",
25597
+ name: "Use an LLM provider API key (Anthropic, Gemini, OpenAI, etc.)",
25534
25598
  value: "byok",
25535
- description: "Paste an API key from any supported provider"
25599
+ description: "Paste an LLM provider API key from any supported provider"
25536
25600
  },
25537
25601
  {
25538
25602
  name: "Skip for now",
@@ -25540,6 +25604,9 @@ async function runOnboarding() {
25540
25604
  }
25541
25605
  ]
25542
25606
  });
25607
+ trackOnboardingEvent("cli.onboarding.llm_setup_choice", {
25608
+ choice: llmChoice === "byok" ? "provider_api_key" : llmChoice === "skip" ? "skipped" : "chatgpt"
25609
+ });
25543
25610
  if (llmChoice === "chatgpt") {
25544
25611
  try {
25545
25612
  await handleConnect();
@@ -25559,8 +25626,8 @@ async function runOnboarding() {
25559
25626
  console.log(` ${source_default.white("Ollama")} ${source_default.dim("\u2014 Local models")}`);
25560
25627
  console.log("");
25561
25628
  const llmKey = await input({
25562
- message: "Paste your API key",
25563
- validate: (v) => v.trim().length > 5 ? true : "Key is too short"
25629
+ message: "Paste your LLM provider API key",
25630
+ validate: (v) => v.trim().length > 5 ? true : "LLM provider API key is too short"
25564
25631
  });
25565
25632
  try {
25566
25633
  if (await isRemoteMode()) {
@@ -25568,22 +25635,22 @@ async function runOnboarding() {
25568
25635
  method: "PUT",
25569
25636
  body: { apiKey: llmKey.trim() }
25570
25637
  });
25571
- console.log(source_default.green(` \u2713 LLM key saved \u2014 ${result.provider} / ${result.model}`));
25572
- console.log(source_default.dim(" Change model later: trading-boy config set-llm-key <key> --model <model>"));
25638
+ console.log(source_default.green(` \u2713 LLM provider API key saved \u2014 ${result.provider} / ${result.model}`));
25639
+ console.log(source_default.dim(" Change model later: trading-boy config set-llm-key <your-llm-provider-api-key> --model <model>"));
25573
25640
  } else {
25574
25641
  console.log(source_default.yellow(" Skipped \u2014 not connected to API."));
25575
25642
  }
25576
25643
  } catch (error2) {
25577
25644
  const msg = error2 instanceof Error ? error2.message : String(error2);
25578
- console.log(source_default.yellow(` Could not save LLM key: ${msg}`));
25579
- console.log(source_default.dim(" Set it later: trading-boy config set-llm-key <your-api-key>"));
25645
+ console.log(source_default.yellow(` Could not save LLM provider API key: ${msg}`));
25646
+ console.log(source_default.dim(" Set it later: trading-boy config set-llm-key <your-llm-provider-api-key>"));
25580
25647
  }
25581
25648
  } else {
25582
25649
  console.log("");
25583
25650
  console.log(source_default.yellow(" \u26A0 Without an LLM provider, agents can scan prices but cannot"));
25584
25651
  console.log(source_default.yellow(" analyze markets or make trade decisions."));
25585
25652
  console.log(source_default.dim(" Set it later: trading-boy connect-chatgpt"));
25586
- console.log(source_default.dim(" Or BYOK: trading-boy config set-llm-key <your-api-key>"));
25653
+ console.log(source_default.dim(" Or BYOK: trading-boy config set-llm-key <your-llm-provider-api-key>"));
25587
25654
  }
25588
25655
  } catch (error2) {
25589
25656
  if (isUserAbort(error2))
@@ -25591,15 +25658,47 @@ async function runOnboarding() {
25591
25658
  throw error2;
25592
25659
  }
25593
25660
  console.log("");
25661
+ if (traderRegistered) {
25662
+ try {
25663
+ const wantsIdentity = await confirm({
25664
+ message: "Set up your trading identity? (interactive SOUL wizard)",
25665
+ default: true
25666
+ });
25667
+ if (wantsIdentity) {
25668
+ console.log("");
25669
+ console.log(source_default.dim(" Optional, but useful: your identity personalizes context \u2014 bias warnings, scope checks,"));
25670
+ console.log(source_default.dim(" and tailored synthesis based on who you are as a trader."));
25671
+ console.log("");
25672
+ try {
25673
+ await runSoulWizardAndUpload(traderName);
25674
+ } catch (wizardError) {
25675
+ if (isUserAbort(wizardError))
25676
+ return;
25677
+ const msg = wizardError instanceof Error ? wizardError.message : String(wizardError);
25678
+ console.log(source_default.yellow(` Could not complete SOUL wizard: ${msg}`));
25679
+ console.log(source_default.dim(" You can do this later: trading-boy trader soul-wizard <name>"));
25680
+ }
25681
+ } else {
25682
+ console.log(source_default.dim(" Skipped. Run later: trading-boy trader soul-wizard <name>"));
25683
+ }
25684
+ } catch (error2) {
25685
+ if (isUserAbort(error2))
25686
+ return;
25687
+ throw error2;
25688
+ }
25689
+ console.log("");
25690
+ }
25594
25691
  try {
25595
25692
  const wantsTelegram = await confirm({
25596
25693
  message: "Connect Telegram for daily summaries?",
25597
25694
  default: true
25598
25695
  });
25599
25696
  if (wantsTelegram) {
25697
+ console.log("");
25698
+ console.log(source_default.dim(" Optional, but useful: Telegram keeps alerts and summaries close to your existing workflow."));
25600
25699
  console.log("");
25601
25700
  console.log(source_default.white(" Click to open the bot: ") + source_default.cyan.underline("https://t.me/TradingBoy1_Bot"));
25602
- console.log(source_default.white(" Send ") + source_default.cyan("/start") + source_default.white(" and paste your API key to connect."));
25701
+ console.log(source_default.white(" Send ") + source_default.cyan("/start") + source_default.white(" and paste your Trading Boy API key to connect."));
25603
25702
  console.log("");
25604
25703
  console.log(source_default.dim(" The bot will send you a daily trading summary at 08:00 UTC."));
25605
25704
  console.log(source_default.dim(" You can also use /summary, /agents, /positions, /pause, and /soul."));
@@ -25612,29 +25711,59 @@ async function runOnboarding() {
25612
25711
  throw error2;
25613
25712
  }
25614
25713
  console.log("");
25714
+ printAgentRuntimeOverview();
25715
+ try {
25716
+ await runFirstAgentCreationStep(confirm, input, select, traderId, traderRegistered);
25717
+ } catch (error2) {
25718
+ if (isUserAbort(error2))
25719
+ return;
25720
+ throw error2;
25721
+ }
25722
+ printAgentQuickReference(traderRegistered);
25723
+ trackOnboardingEvent("cli.onboarding.completed", { path: "build_agent" });
25724
+ }
25725
+ function printExploreQuickReference() {
25726
+ console.log(source_default.bold.cyan(" Explore Context And Journal"));
25727
+ console.log(source_default.gray(" " + "\u2500".repeat(50)));
25728
+ console.log("");
25729
+ console.log(source_default.dim(" You can start manually and come back for agents later."));
25730
+ console.log("");
25731
+ console.log(` ${source_default.white("trading-boy context SOL")} ${source_default.dim("Full context for any token")}`);
25732
+ console.log(` ${source_default.white("trading-boy query BTC")} ${source_default.dim("Quick price + funding snapshot")}`);
25733
+ console.log(` ${source_default.white("trading-boy decisions")} ${source_default.dim("Review trade decisions and outcomes")}`);
25734
+ console.log(` ${source_default.white("trading-boy journal list")} ${source_default.dim("Review your journal entries")}`);
25735
+ console.log(` ${source_default.white("trading-boy stats")} ${source_default.dim("Track performance")}`);
25736
+ console.log("");
25737
+ console.log(source_default.dim(" Build an agent later: trading-boy onboarding"));
25738
+ console.log(source_default.dim(" Full docs: https://api.cabal.ventures/docs"));
25739
+ console.log("");
25740
+ }
25741
+ function printAgentRuntimeOverview() {
25615
25742
  console.log(source_default.bold.cyan(" How Agents Work"));
25616
25743
  console.log(source_default.gray(" " + "\u2500".repeat(50)));
25617
25744
  console.log("");
25618
25745
  console.log(source_default.dim(" Once you create an agent, it runs continuously on our servers:"));
25619
25746
  console.log("");
25620
- console.log(` ${source_default.white("Scan")} ${source_default.dim("Every 30 min by default \u2014 scans your watchlist for setups")}`);
25747
+ console.log(` ${source_default.white("Scan")} ${source_default.dim("Every 5 min by default \u2014 scans your watchlist for setups")}`);
25621
25748
  console.log(` ${source_default.white("Analyze")} ${source_default.dim("When a setup is found \u2014 deep context analysis via your LLM")}`);
25622
25749
  console.log(` ${source_default.white("Decide")} ${source_default.dim("After analysis \u2014 enter/exit/hold based on your strategy")}`);
25623
25750
  console.log(` ${source_default.white("Learn")} ${source_default.dim("After trades close \u2014 updates edge profile from outcomes")}`);
25624
25751
  console.log("");
25625
25752
  console.log(source_default.dim(" Scan interval controls how often your agent checks for setups."));
25626
- console.log(source_default.dim(" Lower intervals = more LLM calls = higher cost. Recommended: 30m."));
25627
- console.log(source_default.dim(" Change it: trading-boy agent update <name> --scan-interval 15m"));
25753
+ console.log(source_default.dim(" Lower intervals = more LLM calls = higher cost."));
25754
+ console.log(source_default.dim(" Use --scan-interval-human for readable values like 15m or 1h."));
25755
+ console.log(source_default.dim(" Use --scan-interval for raw milliseconds like 300000."));
25756
+ console.log(source_default.dim(" Change it: trading-boy agent update <agent-id> --scan-interval-human 15m"));
25628
25757
  console.log("");
25629
25758
  console.log(source_default.dim(" Autonomy levels:"));
25630
- console.log(` ${source_default.cyan("OBSERVE_ONLY")} ${source_default.dim("Scans and analyzes \u2014 takes no action")}`);
25631
- console.log(` ${source_default.cyan("SUGGEST")} ${source_default.dim("Sends trade ideas to your Telegram")}`);
25632
- console.log(` ${source_default.cyan("AUTO_WITH_APPROVAL")} ${source_default.dim("Proposes trades, waits for your OK")}`);
25633
- console.log(` ${source_default.cyan("FULLY_AUTONOMOUS")} ${source_default.dim("Trades within your guardrails, no human in the loop")}`);
25634
- console.log("");
25635
- console.log(source_default.dim(" Create your first agent:"));
25636
- console.log(` ${source_default.white("trading-boy agent create --help")}`);
25759
+ console.log(source_default.dim(" New agents default to Fully auto (FULLY_AUTONOMOUS). Other modes are available if you want more control."));
25760
+ console.log(` ${source_default.cyan("Fully auto")} ${source_default.dim("(FULLY_AUTONOMOUS) \u2014 Default: trades within your guardrails, no human in the loop")}`);
25761
+ console.log(` ${source_default.cyan("Auto with approval")} ${source_default.dim("(AUTO_WITH_APPROVAL) \u2014 Proposes trades, waits for your OK")}`);
25762
+ console.log(` ${source_default.cyan("Suggest only")} ${source_default.dim("(SUGGEST) \u2014 Sends trade ideas to your Telegram")}`);
25763
+ console.log(` ${source_default.cyan("Observe only")} ${source_default.dim("(OBSERVE_ONLY) \u2014 Scans and analyzes, but takes no action")}`);
25637
25764
  console.log("");
25765
+ }
25766
+ function printAgentQuickReference(traderRegistered) {
25638
25767
  console.log(source_default.bold.cyan(" Quick Reference"));
25639
25768
  console.log(source_default.gray(" " + "\u2500".repeat(50)));
25640
25769
  console.log("");
@@ -25646,19 +25775,321 @@ async function runOnboarding() {
25646
25775
  console.log(` ${source_default.white("trading-boy narrative list")} ${source_default.dim("Active market narratives")}`);
25647
25776
  console.log(` ${source_default.white("trading-boy catalysts")} ${source_default.dim("Upcoming events")}`);
25648
25777
  if (traderRegistered) {
25649
- console.log(` ${source_default.white("trading-boy edge")} ${source_default.dim("Your edge profile")}`);
25650
- console.log(` ${source_default.white("trading-boy behavioral")} ${source_default.dim("Behavioral analysis")}`);
25778
+ console.log(` ${source_default.white("trading-boy edge <trader-id>")} ${source_default.dim("Your edge profile")}`);
25779
+ console.log(` ${source_default.white("trading-boy behavioral profile --trader <trader-id>")} ${source_default.dim("Behavioral analysis")}`);
25651
25780
  }
25652
25781
  console.log("");
25653
25782
  console.log(source_default.dim(" Full docs: https://api.cabal.ventures/docs"));
25654
25783
  console.log("");
25655
25784
  }
25785
+ async function resolveTraderId(nameOrId) {
25786
+ try {
25787
+ const result = await apiRequest(`/api/v1/traders/${encodeURIComponent(nameOrId)}`);
25788
+ return typeof result.id === "string" && result.id.length > 0 ? result.id : null;
25789
+ } catch {
25790
+ return null;
25791
+ }
25792
+ }
25793
+ async function runFirstAgentCreationStep(confirm, input, select, traderId, traderRegistered) {
25794
+ console.log(source_default.bold.cyan(" First Agent"));
25795
+ console.log(source_default.gray(" " + "\u2500".repeat(50)));
25796
+ console.log("");
25797
+ if (!traderId) {
25798
+ if (traderRegistered) {
25799
+ console.log(source_default.yellow(" Skipping first-agent creation because Trading Boy could not resolve your trader ID automatically."));
25800
+ console.log(source_default.dim(" Find it later with: trading-boy trader list"));
25801
+ } else {
25802
+ console.log(source_default.yellow(" Skipping first-agent creation because no trader profile is available yet."));
25803
+ console.log(source_default.dim(' Register one later: trading-boy trader register --name "YourName"'));
25804
+ }
25805
+ console.log(source_default.dim(" Then create an agent with: trading-boy agent create --trader-id <id>"));
25806
+ console.log("");
25807
+ return;
25808
+ }
25809
+ const wantsFirstAgent = await confirm({
25810
+ message: "Create your first agent now?",
25811
+ default: true
25812
+ });
25813
+ if (!wantsFirstAgent) {
25814
+ console.log(source_default.dim(` Skipped first-agent creation. Run later: trading-boy agent create --trader-id ${traderId}`));
25815
+ console.log("");
25816
+ return;
25817
+ }
25818
+ const setupMode = await select({
25819
+ message: "Choose your first-agent setup",
25820
+ choices: [
25821
+ {
25822
+ name: "Default setup",
25823
+ value: "default",
25824
+ description: "Use the standard fully-auto setup with default risk and scan settings."
25825
+ },
25826
+ {
25827
+ name: "Advanced setup",
25828
+ value: "advanced",
25829
+ description: "Tune autonomy, watchlist, interval, confidence, risk, and asset class."
25830
+ }
25831
+ ]
25832
+ });
25833
+ const body = {
25834
+ traderId,
25835
+ autonomyLevel: DEFAULT_FIRST_AGENT_AUTONOMY
25836
+ };
25837
+ if (setupMode === "advanced") {
25838
+ trackOnboardingEvent("cli.onboarding.advanced_setup_opened", {
25839
+ path: "build_agent"
25840
+ });
25841
+ console.log("");
25842
+ console.log(source_default.dim(" Advanced setup exposes the highest-value controls now. Leave a field blank to keep the default."));
25843
+ console.log("");
25844
+ Object.assign(body, await promptAdvancedAgentConfig(input, select));
25845
+ }
25846
+ if (String(body.autonomyLevel) === DEFAULT_FIRST_AGENT_AUTONOMY) {
25847
+ console.log("");
25848
+ console.log(source_default.dim(` This first agent starts in Fully auto (${DEFAULT_FIRST_AGENT_AUTONOMY}).`));
25849
+ console.log(source_default.dim(" It can trade within the default guardrails and scan interval."));
25850
+ console.log(source_default.dim(" You can change autonomy later to Auto with approval, Suggest only, or Observe only."));
25851
+ console.log("");
25852
+ const confirmFullyAuto = await confirm({
25853
+ message: "Create this Fully auto first agent now?",
25854
+ default: true
25855
+ });
25856
+ if (!confirmFullyAuto) {
25857
+ console.log(source_default.dim(` Skipped first-agent creation. Run later: trading-boy agent create --trader-id ${traderId}`));
25858
+ console.log("");
25859
+ return;
25860
+ }
25861
+ } else {
25862
+ console.log("");
25863
+ console.log(source_default.dim(` This first agent starts in ${formatAutonomyLabel(String(body.autonomyLevel))}.`));
25864
+ console.log(source_default.dim(" You can still change autonomy, risk, and model routing later."));
25865
+ console.log("");
25866
+ const confirmAdvanced = await confirm({
25867
+ message: `Create this ${formatAutonomyProductLabel(String(body.autonomyLevel))} first agent now?`,
25868
+ default: true
25869
+ });
25870
+ if (!confirmAdvanced) {
25871
+ console.log(source_default.dim(` Skipped first-agent creation. Run later: trading-boy agent create --trader-id ${traderId}`));
25872
+ console.log("");
25873
+ return;
25874
+ }
25875
+ }
25876
+ try {
25877
+ const result = await apiRequest("/api/v1/agents", {
25878
+ method: "POST",
25879
+ body
25880
+ });
25881
+ trackOnboardingEvent("cli.onboarding.first_agent_created", {
25882
+ setup_mode: setupMode,
25883
+ autonomy: String(body.autonomyLevel),
25884
+ asset_class: typeof body.assetClass === "string" ? body.assetClass : "crypto",
25885
+ has_watchlist: Array.isArray(body.watchlist) && body.watchlist.length > 0,
25886
+ used_advanced_setup: setupMode === "advanced"
25887
+ });
25888
+ console.log("");
25889
+ console.log(source_default.green(" First Agent Ready"));
25890
+ console.log(` ${source_default.gray("ID:")} ${result.id}`);
25891
+ console.log(` ${source_default.gray("Autonomy:")} ${formatAutonomyLabel(result.autonomyLevel)}`);
25892
+ console.log(` ${source_default.gray("Interval:")} ${formatInterval(result.scanIntervalMs)}`);
25893
+ console.log(` ${source_default.gray("Exit reasoner:")} ${result.exitReasonerEnabled ? source_default.green("enabled") : source_default.dim("disabled")}`);
25894
+ console.log("");
25895
+ console.log(source_default.dim(" Next:"));
25896
+ console.log(source_default.dim(" trading-boy agent list"));
25897
+ console.log(source_default.dim(` trading-boy agent update ${result.id} --autonomy AUTO_WITH_APPROVAL`));
25898
+ console.log(source_default.dim(" Advanced toggles:"));
25899
+ console.log(source_default.dim(` exit reasoner on: trading-boy agent update ${result.id} --exit-reasoner`));
25900
+ console.log(source_default.dim(` exit reasoner off: trading-boy agent update ${result.id} --disable-exit-reasoner`));
25901
+ console.log(source_default.dim(" More customization later:"));
25902
+ console.log(source_default.dim(" per-stage models/providers: trading-boy config set-models --help"));
25903
+ console.log(source_default.dim(` full agent flags and overrides: trading-boy agent update ${result.id} --help`));
25904
+ console.log("");
25905
+ } catch (error2) {
25906
+ const msg = error2 instanceof Error ? error2.message : String(error2);
25907
+ console.log(source_default.yellow(` Could not create your first agent: ${msg}`));
25908
+ console.log(source_default.dim(` Create it later: trading-boy agent create --trader-id ${traderId}`));
25909
+ console.log(source_default.dim(" You can review agents anytime with: trading-boy agent list"));
25910
+ console.log("");
25911
+ }
25912
+ }
25913
+ function formatAutonomyLabel(level) {
25914
+ switch (level) {
25915
+ case "FULLY_AUTONOMOUS":
25916
+ return "Fully auto (FULLY_AUTONOMOUS)";
25917
+ case "AUTO_WITH_APPROVAL":
25918
+ return "Auto with approval (AUTO_WITH_APPROVAL)";
25919
+ case "SUGGEST":
25920
+ return "Suggest only (SUGGEST)";
25921
+ case "OBSERVE_ONLY":
25922
+ return "Observe only (OBSERVE_ONLY)";
25923
+ default:
25924
+ return level;
25925
+ }
25926
+ }
25927
+ function formatAutonomyProductLabel(level) {
25928
+ switch (level) {
25929
+ case "FULLY_AUTONOMOUS":
25930
+ return "Fully auto";
25931
+ case "AUTO_WITH_APPROVAL":
25932
+ return "Auto with approval";
25933
+ case "SUGGEST":
25934
+ return "Suggest only";
25935
+ case "OBSERVE_ONLY":
25936
+ return "Observe only";
25937
+ default:
25938
+ return level;
25939
+ }
25940
+ }
25941
+ function formatInterval(ms) {
25942
+ if (ms < 6e4)
25943
+ return `${Math.round(ms / 1e3)}s`;
25944
+ if (ms < 36e5)
25945
+ return `${Math.round(ms / 6e4)}m`;
25946
+ return `${(ms / 36e5).toFixed(ms % 36e5 === 0 ? 0 : 1)}h`;
25947
+ }
25948
+ async function promptAdvancedAgentConfig(input, select) {
25949
+ const autonomyLevel = await select({
25950
+ message: "Autonomy mode",
25951
+ choices: [
25952
+ {
25953
+ name: "Fully auto (FULLY_AUTONOMOUS)",
25954
+ value: "FULLY_AUTONOMOUS",
25955
+ description: "Default. Trades within your guardrails, no human in the loop."
25956
+ },
25957
+ {
25958
+ name: "Auto with approval (AUTO_WITH_APPROVAL)",
25959
+ value: "AUTO_WITH_APPROVAL",
25960
+ description: "Proposes trades, waits for your OK."
25961
+ },
25962
+ {
25963
+ name: "Suggest only (SUGGEST)",
25964
+ value: "SUGGEST",
25965
+ description: "Sends trade ideas without placing trades."
25966
+ },
25967
+ {
25968
+ name: "Observe only (OBSERVE_ONLY)",
25969
+ value: "OBSERVE_ONLY",
25970
+ description: "Scans and analyzes, but takes no action."
25971
+ }
25972
+ ]
25973
+ });
25974
+ const watchlist = await promptOptionalValue(input, {
25975
+ message: "Watchlist (optional, comma-separated symbols like SOL,JUP)",
25976
+ parse: parseWatchlist,
25977
+ invalidMessage: "Enter at least one symbol, or leave it blank to keep the default."
25978
+ });
25979
+ const scanIntervalMs = await promptOptionalValue(input, {
25980
+ message: "Scan interval (optional, use 15m, 30m, 1h. Leave blank for default)",
25981
+ parse: parseScanInterval,
25982
+ invalidMessage: "Use a readable duration like 15m, 30m, or 1h, with a minimum of 1m."
25983
+ });
25984
+ const minConfidence = await promptOptionalValue(input, {
25985
+ message: "Minimum confidence threshold (optional, 0-1 where 0.70 = 70%. Leave blank for default)",
25986
+ parse: parseMinConfidence,
25987
+ invalidMessage: "Enter a number from 0 to 1, for example 0.70 = 70%, or leave it blank for the default."
25988
+ });
25989
+ const maxDailyLossUsd = await promptOptionalValue(input, {
25990
+ message: "Max daily loss in USD (optional. Leave blank for default)",
25991
+ parse: parsePositiveNumber,
25992
+ invalidMessage: "Enter a positive USD amount, or leave it blank for the default."
25993
+ });
25994
+ const maxPositionSizePct = await promptOptionalValue(input, {
25995
+ message: "Max position size (optional decimal, so 0.10 = 10%. Leave blank for default)",
25996
+ parse: parsePositionSize,
25997
+ invalidMessage: "Enter a decimal between 0 and 1, such as 0.10 = 10%, or leave it blank for the default."
25998
+ });
25999
+ const assetClass = await select({
26000
+ message: "Asset class",
26001
+ choices: [
26002
+ {
26003
+ name: "Keep the default asset class",
26004
+ value: "default"
26005
+ },
26006
+ {
26007
+ name: "Crypto",
26008
+ value: "crypto"
26009
+ },
26010
+ {
26011
+ name: "Commodities",
26012
+ value: "commodities"
26013
+ },
26014
+ {
26015
+ name: "Mixed",
26016
+ value: "mixed"
26017
+ }
26018
+ ]
26019
+ });
26020
+ return {
26021
+ autonomyLevel,
26022
+ ...watchlist ? { watchlist } : {},
26023
+ ...scanIntervalMs !== void 0 ? { scanIntervalMs } : {},
26024
+ ...minConfidence !== void 0 ? { minConfidence } : {},
26025
+ ...maxDailyLossUsd !== void 0 ? { maxDailyLossUsd } : {},
26026
+ ...maxPositionSizePct !== void 0 ? { maxPositionSizePct } : {},
26027
+ ...assetClass !== "default" ? { assetClass } : {}
26028
+ };
26029
+ }
26030
+ async function promptOptionalValue(input, options) {
26031
+ const raw = (await input({ message: options.message, default: "" })).trim();
26032
+ if (raw.length === 0)
26033
+ return void 0;
26034
+ const parsed = options.parse(raw);
26035
+ if (parsed !== null)
26036
+ return parsed;
26037
+ console.log(source_default.yellow(` ${options.invalidMessage}`));
26038
+ return promptOptionalValue(input, options);
26039
+ }
26040
+ function parseWatchlist(value) {
26041
+ const normalized = normalizeWatchlistSymbols(value.split(","));
26042
+ return normalized.length > 0 ? normalized : null;
26043
+ }
26044
+ function parseHumanInterval(value) {
26045
+ const match = value.trim().match(/^(\d+(?:\.\d+)?)\s*(s|m|h)$/i);
26046
+ if (!match)
26047
+ return null;
26048
+ const amount = parseFloat(match[1]);
26049
+ const unit = match[2].toLowerCase();
26050
+ if (Number.isNaN(amount) || amount <= 0)
26051
+ return null;
26052
+ switch (unit) {
26053
+ case "s":
26054
+ return amount * 1e3;
26055
+ case "m":
26056
+ return amount * 6e4;
26057
+ case "h":
26058
+ return amount * 36e5;
26059
+ default:
26060
+ return null;
26061
+ }
26062
+ }
26063
+ function parseScanInterval(value) {
26064
+ const ms = parseHumanInterval(value);
26065
+ if (ms === null || ms < MIN_SCAN_INTERVAL_MS)
26066
+ return null;
26067
+ return ms;
26068
+ }
26069
+ function parseMinConfidence(value) {
26070
+ const parsed = parseFloat(value);
26071
+ if (Number.isNaN(parsed) || parsed < 0 || parsed > 1)
26072
+ return null;
26073
+ return parsed;
26074
+ }
26075
+ function parsePositiveNumber(value) {
26076
+ const parsed = parseFloat(value);
26077
+ if (Number.isNaN(parsed) || parsed <= 0)
26078
+ return null;
26079
+ return parsed;
26080
+ }
26081
+ function parsePositionSize(value) {
26082
+ const parsed = parseFloat(value);
26083
+ if (Number.isNaN(parsed) || parsed <= 0 || parsed > 1)
26084
+ return null;
26085
+ return parsed;
26086
+ }
25656
26087
  function isUserAbort(error2) {
25657
26088
  return error2 instanceof Error && error2.message.includes("User force closed");
25658
26089
  }
25659
26090
 
25660
26091
  // dist/commands/subscribe.js
25661
- var logger20 = createLogger("cli-subscribe");
26092
+ var logger21 = createLogger("cli-subscribe");
25662
26093
  var POLL_INTERVAL_MS2 = 3e3;
25663
26094
  var POLL_TIMEOUT_MS = 5 * 60 * 1e3;
25664
26095
  async function createCheckoutSession(email, plan = "starter") {
@@ -25722,7 +26153,7 @@ async function pollCryptoPayment(reference, provisioningToken, onTick) {
25722
26153
  return { success: false, error: "Payment expired or not found. Please try again." };
25723
26154
  }
25724
26155
  } catch (err) {
25725
- logger20.debug({ error: err }, "Crypto poll attempt failed, retrying");
26156
+ logger21.debug({ error: err }, "Crypto poll attempt failed, retrying");
25726
26157
  }
25727
26158
  await sleep2(CRYPTO_POLL_INTERVAL);
25728
26159
  }
@@ -25743,7 +26174,7 @@ async function pollCryptoPayment(reference, provisioningToken, onTick) {
25743
26174
  return { success: false, error: "Provisioning token expired after payment. Contact support." };
25744
26175
  }
25745
26176
  } catch (err) {
25746
- logger20.debug({ error: err }, "Provision poll attempt failed, retrying");
26177
+ logger21.debug({ error: err }, "Provision poll attempt failed, retrying");
25747
26178
  }
25748
26179
  await sleep2(POLL_INTERVAL_MS2);
25749
26180
  }
@@ -25787,7 +26218,7 @@ async function pollForApiKey(token, onTick) {
25787
26218
  };
25788
26219
  }
25789
26220
  } catch (err) {
25790
- logger20.debug({ error: err }, "Poll attempt failed, retrying");
26221
+ logger21.debug({ error: err }, "Poll attempt failed, retrying");
25791
26222
  }
25792
26223
  await sleep2(POLL_INTERVAL_MS2);
25793
26224
  elapsed = Date.now() - start;
@@ -25828,13 +26259,13 @@ function formatSubscribeSuccess(result) {
25828
26259
  lines.push(` ${source_default.bold("Plan:")} ${result.plan}`);
25829
26260
  }
25830
26261
  if (result.apiKey) {
25831
- lines.push(` ${source_default.bold("API Key:")} ${source_default.yellow(result.apiKey)}`);
26262
+ lines.push(` ${source_default.bold("Trading Boy API key:")} ${source_default.yellow(result.apiKey)}`);
25832
26263
  lines.push("");
25833
- lines.push(source_default.dim(" \u26A0\uFE0F Copy this key now \u2014 it will not be shown again."));
26264
+ lines.push(source_default.dim(" \u26A0\uFE0F Copy this Trading Boy API key now \u2014 it will not be shown again."));
25834
26265
  lines.push(source_default.dim(" Connect Telegram: ") + source_default.dim.underline("https://t.me/TradingBoy1_Bot"));
25835
- lines.push(source_default.dim(" Send /start and paste this key when prompted."));
26266
+ lines.push(source_default.dim(" Send /start and paste your Trading Boy API key when prompted."));
25836
26267
  } else if (result.reusedExistingKey) {
25837
- lines.push(` ${source_default.bold("API Key:")} ${source_default.green("Your existing key remains active")}`);
26268
+ lines.push(` ${source_default.bold("Trading Boy API key:")} ${source_default.green("Your existing key remains active")}`);
25838
26269
  lines.push("");
25839
26270
  lines.push(source_default.dim(" No new key was issued for this upgrade."));
25840
26271
  lines.push(source_default.dim(" If Trading Boy is already configured, no action is required."));
@@ -25844,7 +26275,7 @@ function formatSubscribeSuccess(result) {
25844
26275
  }
25845
26276
  lines.push("");
25846
26277
  if (result.apiKey) {
25847
- lines.push(source_default.dim(" Your API key has been stored locally."));
26278
+ lines.push(source_default.dim(" Your Trading Boy API key has been stored locally."));
25848
26279
  lines.push(source_default.dim(" You can also view it anytime: trading-boy whoami --show-key"));
25849
26280
  } else {
25850
26281
  lines.push(source_default.dim(" Your stored Trading Boy credentials remain unchanged."));
@@ -25855,7 +26286,7 @@ function formatSubscribeSuccess(result) {
25855
26286
  return lines.join("\n");
25856
26287
  }
25857
26288
  function registerSubscribeCommand(program2) {
25858
- program2.command("subscribe").description("Subscribe to Trading Boy and get your API key").requiredOption("-e, --email <email>", "Your email address").option("--plan <plan>", "Subscription plan: starter, pro, or edge").option("--pay <method>", "Payment method: crypto (USDC on Solana) or stripe").action(async (options) => {
26289
+ program2.command("subscribe").description("Subscribe to Trading Boy and get your Trading Boy API key").requiredOption("-e, --email <email>", "Your email address").option("--plan <plan>", "Subscription plan: starter, pro, or edge").option("--pay <method>", "Payment method: crypto (USDC on Solana) or stripe").action(async (options) => {
25859
26290
  const { email } = options;
25860
26291
  let { plan, pay } = options;
25861
26292
  if (!isValidEmail(email)) {
@@ -25923,7 +26354,7 @@ function registerSubscribeCommand(program2) {
25923
26354
  return;
25924
26355
  }
25925
26356
  const message = error2 instanceof Error ? error2.message : String(error2);
25926
- logger20.error({ error: message }, "Subscribe command failed");
26357
+ logger21.error({ error: message }, "Subscribe command failed");
25927
26358
  console.error(source_default.red(` Error: ${message}`));
25928
26359
  process.exitCode = 1;
25929
26360
  }
@@ -26085,9 +26516,9 @@ async function storeAndDisplayKey(pollResult) {
26085
26516
  } catch (err) {
26086
26517
  console.error("");
26087
26518
  console.error(source_default.yellow(" Warning: Could not save API key automatically."));
26088
- console.error(source_default.yellow(` Your API key: ${pollResult.apiKey}`));
26089
- console.error(source_default.yellow(" Save this key and run: trading-boy login --api-key <key>"));
26090
- logger20.error({ error: err }, "Failed to save credentials");
26519
+ console.error(source_default.yellow(` Your Trading Boy API key: ${pollResult.apiKey}`));
26520
+ console.error(source_default.yellow(" Save this key and run: trading-boy login --api-key <trading-boy-api-key>"));
26521
+ logger21.error({ error: err }, "Failed to save credentials");
26091
26522
  process.exitCode = 1;
26092
26523
  return;
26093
26524
  }
@@ -26152,7 +26583,7 @@ function formatConnectionError2(message) {
26152
26583
  init_source();
26153
26584
  init_credentials();
26154
26585
  init_api_client();
26155
- var logger21 = createLogger("cli-rotate-key");
26586
+ var logger22 = createLogger("cli-rotate-key");
26156
26587
  async function rotateApiKey(currentKey) {
26157
26588
  const response = await fetch(`${getApiBase()}/api/v1/auth/rotate`, {
26158
26589
  method: "POST",
@@ -26220,7 +26651,7 @@ function registerRotateKeyCommand(program2) {
26220
26651
  return;
26221
26652
  }
26222
26653
  const message = error2 instanceof Error ? error2.message : String(error2);
26223
- logger21.error({ error: message }, "rotate-key failed");
26654
+ logger22.error({ error: message }, "rotate-key failed");
26224
26655
  console.error(source_default.red(` Error: ${message}`));
26225
26656
  process.exitCode = 1;
26226
26657
  }
@@ -26231,7 +26662,7 @@ function registerRotateKeyCommand(program2) {
26231
26662
  init_source();
26232
26663
  init_credentials();
26233
26664
  init_api_client();
26234
- var logger22 = createLogger("cli-forgot-key");
26665
+ var logger23 = createLogger("cli-forgot-key");
26235
26666
  async function requestKeyRecovery(email) {
26236
26667
  const response = await fetch(`${getApiBase()}/api/v1/auth/forgot-key`, {
26237
26668
  method: "POST",
@@ -26327,7 +26758,7 @@ function registerForgotKeyCommand(program2) {
26327
26758
  return;
26328
26759
  }
26329
26760
  const message = error2 instanceof Error ? error2.message : String(error2);
26330
- logger22.error({ error: message }, "forgot-key failed");
26761
+ logger23.error({ error: message }, "forgot-key failed");
26331
26762
  console.error(source_default.red(` Error: ${message}`));
26332
26763
  process.exitCode = 1;
26333
26764
  }
@@ -26657,7 +27088,7 @@ function registerEdgeGuardCommand(program2) {
26657
27088
  init_source();
26658
27089
  init_api_client();
26659
27090
  init_utils();
26660
- var logger23 = createLogger("cli-coaching");
27091
+ var logger24 = createLogger("cli-coaching");
26661
27092
  var BYOK_HINT = `LLM API key required. Run: ${source_default.white("trading-boy config set-llm-key <key>")}`;
26662
27093
  function isByokError(error2) {
26663
27094
  if (error2 instanceof ApiError && error2.status === 422)
@@ -26752,7 +27183,7 @@ function registerCoachingCommand(program2) {
26752
27183
  return;
26753
27184
  }
26754
27185
  const message = error2 instanceof ApiError ? error2.message : error2 instanceof Error ? error2.message : String(error2);
26755
- logger23.error({ error: message }, "Pre-trade coaching failed");
27186
+ logger24.error({ error: message }, "Pre-trade coaching failed");
26756
27187
  console.error(source_default.red(`Error: ${message}`));
26757
27188
  process.exitCode = error2 instanceof ApiError ? 2 : 1;
26758
27189
  }
@@ -26793,7 +27224,7 @@ function registerCoachingCommand(program2) {
26793
27224
  return;
26794
27225
  }
26795
27226
  const message = error2 instanceof ApiError ? error2.message : error2 instanceof Error ? error2.message : String(error2);
26796
- logger23.error({ error: message }, "Post-trade coaching failed");
27227
+ logger24.error({ error: message }, "Post-trade coaching failed");
26797
27228
  console.error(source_default.red(`Error: ${message}`));
26798
27229
  process.exitCode = error2 instanceof ApiError ? 2 : 1;
26799
27230
  }
@@ -26809,7 +27240,7 @@ function registerCoachingCommand(program2) {
26809
27240
  console.log("");
26810
27241
  } catch (error2) {
26811
27242
  const message = error2 instanceof ApiError ? error2.message : error2 instanceof Error ? error2.message : String(error2);
26812
- logger23.error({ error: message }, "Acknowledge failed");
27243
+ logger24.error({ error: message }, "Acknowledge failed");
26813
27244
  console.error(source_default.red(`Error: ${message}`));
26814
27245
  process.exitCode = error2 instanceof ApiError ? 2 : 1;
26815
27246
  }
@@ -26824,7 +27255,7 @@ function registerCoachingCommand(program2) {
26824
27255
  console.log("");
26825
27256
  } catch (error2) {
26826
27257
  const message = error2 instanceof ApiError ? error2.message : error2 instanceof Error ? error2.message : String(error2);
26827
- logger23.error({ error: message }, "Reset failed");
27258
+ logger24.error({ error: message }, "Reset failed");
26828
27259
  console.error(source_default.red(`Error: ${message}`));
26829
27260
  process.exitCode = error2 instanceof ApiError ? 2 : 1;
26830
27261
  }
@@ -26835,7 +27266,7 @@ function registerCoachingCommand(program2) {
26835
27266
  init_source();
26836
27267
  init_api_client();
26837
27268
  init_utils();
26838
- var logger24 = createLogger("cli-thesis");
27269
+ var logger25 = createLogger("cli-thesis");
26839
27270
  var BYOK_HINT2 = `LLM API key required. Run: ${source_default.white("trading-boy config set-llm-key <key>")}`;
26840
27271
  function formatThesisOutput(response) {
26841
27272
  const lines = [];
@@ -26936,7 +27367,7 @@ function registerThesisCommand(program2) {
26936
27367
  return;
26937
27368
  }
26938
27369
  const message = error2 instanceof ApiError ? error2.message : error2 instanceof Error ? error2.message : String(error2);
26939
- logger24.error({ error: message }, "Thesis extraction failed");
27370
+ logger25.error({ error: message }, "Thesis extraction failed");
26940
27371
  console.error(source_default.red(`Error: ${message}`));
26941
27372
  process.exitCode = error2 instanceof ApiError ? 2 : 1;
26942
27373
  }
@@ -26947,7 +27378,7 @@ function registerThesisCommand(program2) {
26947
27378
  init_source();
26948
27379
  init_api_client();
26949
27380
  init_utils();
26950
- var logger25 = createLogger("cli-strategy");
27381
+ var logger26 = createLogger("cli-strategy");
26951
27382
  function formatShortDate2(isoString) {
26952
27383
  try {
26953
27384
  return new Date(isoString).toISOString().slice(0, 16).replace("T", " ");
@@ -26955,6 +27386,9 @@ function formatShortDate2(isoString) {
26955
27386
  return isoString;
26956
27387
  }
26957
27388
  }
27389
+ function normalizeStrategyTokens(tokens) {
27390
+ return normalizeWatchlistSymbols(tokens.split(",").map((t) => t.trim()).filter(Boolean));
27391
+ }
26958
27392
  function formatStrategyDetail(s) {
26959
27393
  const lines = [];
26960
27394
  lines.push("");
@@ -27049,7 +27483,7 @@ function registerStrategyCommand(program2) {
27049
27483
  strategy.command("create").description("Create a new agent strategy").requiredOption("--name <name>", "Strategy name").requiredOption("--trader-id <id>", "Trader ID").requiredOption("--agent-id <id>", "Agent ID").requiredOption("--tokens <tokens>", "Comma-separated token symbols").option("--setups <types>", "Comma-separated setup types").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (options) => {
27050
27484
  if (!await ensureRemote())
27051
27485
  return;
27052
- const tokens = options.tokens.split(",").map((t) => t.trim().toUpperCase()).filter(Boolean);
27486
+ const tokens = normalizeStrategyTokens(options.tokens);
27053
27487
  const setupTypes = options.setups ? options.setups.split(",").map((s) => s.trim().toUpperCase()).filter(Boolean) : ["BREAKOUT"];
27054
27488
  const body = {
27055
27489
  name: options.name,
@@ -27069,7 +27503,7 @@ function registerStrategyCommand(program2) {
27069
27503
  console.log(formatStrategyDetail(result));
27070
27504
  }
27071
27505
  } catch (error2) {
27072
- handleApiError(error2, "Strategy create failed", logger25);
27506
+ handleApiError(error2, "Strategy create failed", logger26);
27073
27507
  }
27074
27508
  });
27075
27509
  strategy.command("list").description("List strategies for a trader").requiredOption("--trader-id <id>", "Trader ID").option("--agent-id <id>", "Filter by agent ID").option("--limit <n>", "Maximum results", "20").option("--offset <n>", "Pagination offset", "0").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (options) => {
@@ -27089,7 +27523,7 @@ function registerStrategyCommand(program2) {
27089
27523
  console.log(formatStrategyList(result));
27090
27524
  }
27091
27525
  } catch (error2) {
27092
- handleApiError(error2, "Strategy list failed", logger25);
27526
+ handleApiError(error2, "Strategy list failed", logger26);
27093
27527
  }
27094
27528
  });
27095
27529
  strategy.command("show <id>").description("Show full details for a strategy").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (id, options) => {
@@ -27103,7 +27537,7 @@ function registerStrategyCommand(program2) {
27103
27537
  console.log(formatStrategyDetail(result));
27104
27538
  }
27105
27539
  } catch (error2) {
27106
- handleApiError(error2, "Strategy show failed", logger25);
27540
+ handleApiError(error2, "Strategy show failed", logger26);
27107
27541
  }
27108
27542
  });
27109
27543
  strategy.command("update <id>").description("Update a strategy").option("--name <name>", "New strategy name").option("--tokens <tokens>", "New comma-separated token symbols (replaces existing)").option("--setups <types>", "New comma-separated setup types (replaces existing)").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (id, options) => {
@@ -27114,7 +27548,7 @@ function registerStrategyCommand(program2) {
27114
27548
  body.name = options.name;
27115
27549
  }
27116
27550
  if (options.tokens) {
27117
- body.tokens = options.tokens.split(",").map((t) => t.trim().toUpperCase()).filter(Boolean);
27551
+ body.tokens = normalizeStrategyTokens(options.tokens);
27118
27552
  }
27119
27553
  if (options.setups) {
27120
27554
  body.setupTypes = options.setups.split(",").map((s) => s.trim().toUpperCase()).filter(Boolean);
@@ -27132,7 +27566,7 @@ function registerStrategyCommand(program2) {
27132
27566
  console.log(formatStrategyDetail(result));
27133
27567
  }
27134
27568
  } catch (error2) {
27135
- handleApiError(error2, "Strategy update failed", logger25);
27569
+ handleApiError(error2, "Strategy update failed", logger26);
27136
27570
  }
27137
27571
  });
27138
27572
  strategy.command("history <id>").description("Show version history for a strategy").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (id, options) => {
@@ -27146,7 +27580,7 @@ function registerStrategyCommand(program2) {
27146
27580
  console.log(formatHistoryList(result));
27147
27581
  }
27148
27582
  } catch (error2) {
27149
- handleApiError(error2, "Strategy history failed", logger25);
27583
+ handleApiError(error2, "Strategy history failed", logger26);
27150
27584
  }
27151
27585
  });
27152
27586
  strategy.command("export").description("Export a strategy in json, elizaos, or freqtrade format").requiredOption("--id <id>", "Strategy ID to export").addOption(new Option("--format <format>", "Export format").choices(["json", "elizaos", "freqtrade"]).default("json")).option("--output <file>", "Write output to a file instead of stdout").action(async (options) => {
@@ -27172,7 +27606,7 @@ function registerStrategyCommand(program2) {
27172
27606
  console.log(output);
27173
27607
  }
27174
27608
  } catch (error2) {
27175
- handleApiError(error2, "Strategy export failed", logger25);
27609
+ handleApiError(error2, "Strategy export failed", logger26);
27176
27610
  }
27177
27611
  });
27178
27612
  }
@@ -27181,7 +27615,7 @@ function registerStrategyCommand(program2) {
27181
27615
  init_source();
27182
27616
  init_api_client();
27183
27617
  init_utils();
27184
- var logger26 = createLogger("cli-replay");
27618
+ var logger27 = createLogger("cli-replay");
27185
27619
  function formatPercent2(val) {
27186
27620
  const sign = val >= 0 ? "+" : "";
27187
27621
  const str = `${sign}${val.toFixed(2)}%`;
@@ -27298,7 +27732,7 @@ function registerReplayCommand(program2) {
27298
27732
  submitSpinner.succeed(source_default.dim(`Job submitted: ${jobId}`));
27299
27733
  } catch (error2) {
27300
27734
  submitSpinner.fail("Failed to submit replay job");
27301
- handleApiError(error2, "Replay submit failed", logger26);
27735
+ handleApiError(error2, "Replay submit failed", logger27);
27302
27736
  return;
27303
27737
  }
27304
27738
  const pollSpinner = (await createSpinner2("Running replay\u2026")).start();
@@ -27308,7 +27742,7 @@ function registerReplayCommand(program2) {
27308
27742
  pollSpinner.stop();
27309
27743
  } catch (error2) {
27310
27744
  pollSpinner.fail("Replay timed out or encountered an error");
27311
- handleApiError(error2, "Replay polling failed", logger26);
27745
+ handleApiError(error2, "Replay polling failed", logger27);
27312
27746
  return;
27313
27747
  }
27314
27748
  if (!finalStatus.result) {
@@ -27480,7 +27914,7 @@ function registerBenchmarkCommand(program2) {
27480
27914
  init_source();
27481
27915
  init_api_client();
27482
27916
  init_utils();
27483
- var logger27 = createLogger("cli-suggestions");
27917
+ var logger28 = createLogger("cli-suggestions");
27484
27918
  function formatSuggestionsList(data) {
27485
27919
  const lines = [];
27486
27920
  lines.push("");
@@ -27542,7 +27976,7 @@ function registerSuggestionsCommand(program2) {
27542
27976
  }
27543
27977
  } catch (error2) {
27544
27978
  const message = error2 instanceof ApiError ? error2.message : error2 instanceof Error ? error2.message : String(error2);
27545
- logger27.error({ error: message }, "Failed to list suggestions");
27979
+ logger28.error({ error: message }, "Failed to list suggestions");
27546
27980
  console.error(source_default.red(`Error: ${message}`));
27547
27981
  process.exitCode = error2 instanceof ApiError ? 2 : 1;
27548
27982
  }
@@ -27561,7 +27995,7 @@ function registerSuggestionsCommand(program2) {
27561
27995
  }
27562
27996
  } catch (error2) {
27563
27997
  const message = error2 instanceof ApiError ? error2.message : error2 instanceof Error ? error2.message : String(error2);
27564
- logger27.error({ error: message }, "Failed to approve suggestion");
27998
+ logger28.error({ error: message }, "Failed to approve suggestion");
27565
27999
  console.error(source_default.red(`Error: ${message}`));
27566
28000
  process.exitCode = error2 instanceof ApiError ? 2 : 1;
27567
28001
  }
@@ -27580,7 +28014,7 @@ function registerSuggestionsCommand(program2) {
27580
28014
  }
27581
28015
  } catch (error2) {
27582
28016
  const message = error2 instanceof ApiError ? error2.message : error2 instanceof Error ? error2.message : String(error2);
27583
- logger27.error({ error: message }, "Failed to reject suggestion");
28017
+ logger28.error({ error: message }, "Failed to reject suggestion");
27584
28018
  console.error(source_default.red(`Error: ${message}`));
27585
28019
  process.exitCode = error2 instanceof ApiError ? 2 : 1;
27586
28020
  }
@@ -27591,7 +28025,7 @@ function registerSuggestionsCommand(program2) {
27591
28025
  init_source();
27592
28026
  init_api_client();
27593
28027
  init_utils();
27594
- var logger28 = createLogger("cli-cron");
28028
+ var logger29 = createLogger("cli-cron");
27595
28029
  function formatShortDate4(isoString) {
27596
28030
  if (!isoString)
27597
28031
  return source_default.dim("\u2014");
@@ -27663,7 +28097,7 @@ function registerCronCommand(program2) {
27663
28097
  console.log("");
27664
28098
  }
27665
28099
  } catch (error2) {
27666
- handleApiError(error2, "Cron create failed", logger28);
28100
+ handleApiError(error2, "Cron create failed", logger29);
27667
28101
  }
27668
28102
  });
27669
28103
  cron.command("list").description("List cron jobs").option("--status <status>", "Filter by status: active, paused").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (options) => {
@@ -27690,7 +28124,7 @@ function registerCronCommand(program2) {
27690
28124
  console.log(source_default.dim(` ${result.count} job(s)`));
27691
28125
  console.log("");
27692
28126
  } catch (error2) {
27693
- handleApiError(error2, "Cron list failed", logger28);
28127
+ handleApiError(error2, "Cron list failed", logger29);
27694
28128
  }
27695
28129
  });
27696
28130
  cron.command("show <jobId>").description("Show details of a cron job").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (jobId, options) => {
@@ -27718,7 +28152,7 @@ function registerCronCommand(program2) {
27718
28152
  console.log(` ${source_default.gray("Created:")} ${formatShortDate4(job.createdAt)}`);
27719
28153
  console.log("");
27720
28154
  } catch (error2) {
27721
- handleApiError(error2, "Cron show failed", logger28);
28155
+ handleApiError(error2, "Cron show failed", logger29);
27722
28156
  }
27723
28157
  });
27724
28158
  cron.command("pause <jobId>").description("Pause a cron job").action(async (jobId) => {
@@ -27731,7 +28165,7 @@ function registerCronCommand(program2) {
27731
28165
  });
27732
28166
  console.log(source_default.green(` Job ${jobId} paused`));
27733
28167
  } catch (error2) {
27734
- handleApiError(error2, "Cron pause failed", logger28);
28168
+ handleApiError(error2, "Cron pause failed", logger29);
27735
28169
  }
27736
28170
  });
27737
28171
  cron.command("resume <jobId>").description("Resume a paused cron job").action(async (jobId) => {
@@ -27744,7 +28178,7 @@ function registerCronCommand(program2) {
27744
28178
  });
27745
28179
  console.log(source_default.green(` Job ${jobId} resumed`));
27746
28180
  } catch (error2) {
27747
- handleApiError(error2, "Cron resume failed", logger28);
28181
+ handleApiError(error2, "Cron resume failed", logger29);
27748
28182
  }
27749
28183
  });
27750
28184
  cron.command("delete <jobId>").description("Delete a cron job").action(async (jobId) => {
@@ -27756,7 +28190,7 @@ function registerCronCommand(program2) {
27756
28190
  });
27757
28191
  console.log(source_default.green(` Job ${jobId} deleted`));
27758
28192
  } catch (error2) {
27759
- handleApiError(error2, "Cron delete failed", logger28);
28193
+ handleApiError(error2, "Cron delete failed", logger29);
27760
28194
  }
27761
28195
  });
27762
28196
  cron.command("run <jobId>").description("Trigger immediate execution of a cron job").action(async (jobId) => {
@@ -27768,7 +28202,7 @@ function registerCronCommand(program2) {
27768
28202
  });
27769
28203
  console.log(source_default.green(` Job ${jobId} execution triggered`));
27770
28204
  } catch (error2) {
27771
- handleApiError(error2, "Cron run failed", logger28);
28205
+ handleApiError(error2, "Cron run failed", logger29);
27772
28206
  }
27773
28207
  });
27774
28208
  cron.command("history <jobId>").description("View execution history for a cron job").option("--limit <n>", "Number of runs to show", "20").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (jobId, options) => {
@@ -27796,7 +28230,7 @@ function registerCronCommand(program2) {
27796
28230
  console.log(source_default.dim(` ${result.count} run(s)`));
27797
28231
  console.log("");
27798
28232
  } catch (error2) {
27799
- handleApiError(error2, "Cron history failed", logger28);
28233
+ handleApiError(error2, "Cron history failed", logger29);
27800
28234
  }
27801
28235
  });
27802
28236
  }
@@ -27807,7 +28241,14 @@ import { resolve } from "node:path";
27807
28241
  init_source();
27808
28242
  init_api_client();
27809
28243
  init_utils();
27810
- var logger29 = createLogger("cli-agent");
28244
+ var logger30 = createLogger("cli-agent");
28245
+ var AUTONOMY_HELP_CREATE = "Autonomy mode. Choose Fully auto (FULLY_AUTONOMOUS, default), Auto with approval (AUTO_WITH_APPROVAL), Suggest only (SUGGEST), or Observe only (OBSERVE_ONLY)";
28246
+ var AUTONOMY_HELP_UPDATE = "Autonomy mode. Choose Fully auto (FULLY_AUTONOMOUS), Auto with approval (AUTO_WITH_APPROVAL), Suggest only (SUGGEST), or Observe only (OBSERVE_ONLY)";
28247
+ var MIN_CONFIDENCE_HELP = "Minimum confidence threshold (0-1, so 0.70 = 70%)";
28248
+ var EXIT_REASONER_HELP = "Enable LLM-powered exit reasoning for open positions (hold, exit, tighten stop, or extend take profit)";
28249
+ var DISABLE_EXIT_REASONER_HELP = "Disable LLM-powered exit reasoning for open positions";
28250
+ var SHARED_SCAN_CACHE_INTERNAL_HELP = "Internal/load-test only: bypass shared scan cache for this agent";
28251
+ var ENABLE_SHARED_SCAN_CACHE_HELP = "Internal/load-test only: re-enable shared scan cache for this agent";
27811
28252
  function formatShortDate5(isoString) {
27812
28253
  if (!isoString)
27813
28254
  return source_default.dim("\u2014");
@@ -27832,25 +28273,25 @@ function formatStatus2(status) {
27832
28273
  function formatAutonomy(level) {
27833
28274
  switch (level) {
27834
28275
  case "OBSERVE_ONLY":
27835
- return source_default.dim("observe");
28276
+ return source_default.dim("Observe only");
27836
28277
  case "SUGGEST":
27837
- return source_default.blue("suggest");
28278
+ return source_default.blue("Suggest only");
27838
28279
  case "AUTO_WITH_APPROVAL":
27839
- return source_default.yellow("auto+approve");
28280
+ return source_default.yellow("Auto with approval");
27840
28281
  case "FULLY_AUTONOMOUS":
27841
- return source_default.red("autonomous");
28282
+ return source_default.red("Fully auto");
27842
28283
  default:
27843
28284
  return level;
27844
28285
  }
27845
28286
  }
27846
- function formatInterval(ms) {
28287
+ function formatInterval2(ms) {
27847
28288
  if (ms < 6e4)
27848
28289
  return `${(ms / 1e3).toFixed(0)}s`;
27849
28290
  if (ms < 36e5)
27850
28291
  return `${(ms / 6e4).toFixed(0)}m`;
27851
28292
  return `${(ms / 36e5).toFixed(1)}h`;
27852
28293
  }
27853
- function parseHumanInterval(value) {
28294
+ function parseHumanInterval2(value) {
27854
28295
  const match = value.trim().match(/^(\d+(?:\.\d+)?)\s*(s|m|h)$/i);
27855
28296
  if (!match)
27856
28297
  return null;
@@ -27867,10 +28308,10 @@ function parseHumanInterval(value) {
27867
28308
  return null;
27868
28309
  }
27869
28310
  }
27870
- var MIN_SCAN_INTERVAL_MS = 6e4;
28311
+ var MIN_SCAN_INTERVAL_MS2 = 6e4;
27871
28312
  function registerAgentCommand(program2) {
27872
28313
  const agent = program2.command("agent").description("Manage autonomous trading agents");
27873
- agent.command("create").description("Create a new agent").option("--trader-id <traderId>", "Trader ID").option("--strategy-id <strategyId>", "Strategy ID (optional \u2014 auto-creates if omitted)").option("--name <name>", "Agent name").option("--autonomy <level>", "Autonomy level: OBSERVE_ONLY, SUGGEST, AUTO_WITH_APPROVAL, FULLY_AUTONOMOUS", "OBSERVE_ONLY").option("--scan-interval <ms>", "Scan interval in ms (min 60000)", "300000").option("--scan-interval-human <duration>", "Scan interval in human-readable format (e.g. 1m, 5m, 15m, 30m, 1h)").option("--watchlist <symbols>", "Comma-separated token symbols").option("--max-daily-trades <n>", "Max daily trades", "10").option("--max-daily-loss <usd>", "Max daily loss in USD", "500").option("--max-position-size <pct>", "Max position size as decimal (0.10 = 10%)", "0.10").option("--min-confidence <n>", "Min confidence threshold (0-1)", "0.60").option("--scan-model <model>", "LLM model for market scanning").option("--analyze-model <model>", "LLM model for deep analysis").option("--decide-model <model>", "LLM model for trade decisions").addOption(new Option("--asset-class <class>", "Asset class for this agent").choices(["crypto", "commodities", "mixed"]).default("crypto")).option("--soul-override <text>", "Custom soul/personality for this agent").option("--purpose-override <text>", "Custom purpose/mission for this agent").option("--soul-file <path>", "Load soul from a file").option("--purpose-file <path>", "Load purpose from a file").option("--exit-reasoner", "Enable LLM-powered exit reasoning for this agent").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (options) => {
28314
+ agent.command("create").description("Create a new agent").option("--trader-id <traderId>", "Trader ID").option("--strategy-id <strategyId>", "Strategy ID (optional \u2014 auto-creates if omitted)").option("--name <name>", "Agent name").option("--autonomy <level>", AUTONOMY_HELP_CREATE, "FULLY_AUTONOMOUS").option("--scan-interval <ms>", "Scan interval in raw milliseconds (min 60000; e.g. 300000 = 5m)", "300000").option("--scan-interval-human <duration>", "Scan interval in human-readable format (e.g. 1m, 5m, 15m, 30m, 1h). Overrides --scan-interval").option("--watchlist <symbols>", "Comma-separated token symbols").option("--max-daily-trades <n>", "Max daily trades", "10").option("--max-daily-loss <usd>", "Max daily loss in USD", "500").option("--max-position-size <pct>", "Max position size as decimal (0.10 = 10%)", "0.10").option("--min-confidence <n>", MIN_CONFIDENCE_HELP, "0.60").option("--scan-model <model>", "LLM model for market scanning").option("--analyze-model <model>", "LLM model for deep analysis").option("--decide-model <model>", "LLM model for trade decisions").option("--disable-shared-scan-cache", SHARED_SCAN_CACHE_INTERNAL_HELP).addOption(new Option("--asset-class <class>", "Asset class for this agent").choices(["crypto", "commodities", "mixed"]).default("crypto")).option("--soul-override <text>", "Custom soul/personality for this agent").option("--purpose-override <text>", "Custom purpose/mission for this agent").option("--soul-file <path>", "Load soul from a file").option("--purpose-file <path>", "Load purpose from a file").option("--exit-reasoner", EXIT_REASONER_HELP).addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (options) => {
27874
28315
  if (!await ensureRemote())
27875
28316
  return;
27876
28317
  if (!options.traderId) {
@@ -27889,14 +28330,14 @@ function registerAgentCommand(program2) {
27889
28330
  if (options.autonomy)
27890
28331
  body.autonomyLevel = options.autonomy;
27891
28332
  if (options.scanIntervalHuman) {
27892
- const ms = parseHumanInterval(options.scanIntervalHuman);
28333
+ const ms = parseHumanInterval2(options.scanIntervalHuman);
27893
28334
  if (ms === null) {
27894
28335
  console.error(source_default.red(`Error: Invalid duration "${options.scanIntervalHuman}". Use format like 1m, 5m, 15m, 30m, 1h.`));
27895
28336
  process.exitCode = 1;
27896
28337
  return;
27897
28338
  }
27898
- if (ms < MIN_SCAN_INTERVAL_MS) {
27899
- console.error(source_default.red(`Error: Scan interval must be at least 1m (60000ms). Got ${formatInterval(ms)}.`));
28339
+ if (ms < MIN_SCAN_INTERVAL_MS2) {
28340
+ console.error(source_default.red(`Error: Scan interval must be at least 1m (60000ms). Got ${formatInterval2(ms)}.`));
27900
28341
  process.exitCode = 1;
27901
28342
  return;
27902
28343
  }
@@ -27905,7 +28346,7 @@ function registerAgentCommand(program2) {
27905
28346
  body.scanIntervalMs = parseInt(options.scanInterval, 10);
27906
28347
  }
27907
28348
  if (options.watchlist)
27908
- body.watchlist = options.watchlist.split(",").map((s) => s.trim().toUpperCase());
28349
+ body.watchlist = normalizeWatchlistSymbols(options.watchlist.split(","));
27909
28350
  if (options.maxDailyTrades)
27910
28351
  body.maxDailyTrades = parseInt(options.maxDailyTrades, 10);
27911
28352
  if (options.maxDailyLoss)
@@ -27920,6 +28361,8 @@ function registerAgentCommand(program2) {
27920
28361
  body.analyzeModel = options.analyzeModel;
27921
28362
  if (options.decideModel)
27922
28363
  body.decideModel = options.decideModel;
28364
+ if (options.disableSharedScanCache)
28365
+ body.disableSharedScanCache = true;
27923
28366
  if (options.assetClass)
27924
28367
  body.assetClass = options.assetClass;
27925
28368
  if (options.exitReasoner)
@@ -27961,12 +28404,13 @@ function registerAgentCommand(program2) {
27961
28404
  console.log(` ${source_default.gray("Trader:")} ${result.traderId}`);
27962
28405
  console.log(` ${source_default.gray("Strategy:")} ${result.strategyId}${result.autoStrategyCreated ? source_default.dim(" (auto-created)") : ""}`);
27963
28406
  console.log(` ${source_default.gray("Autonomy:")} ${formatAutonomy(result.autonomyLevel)}`);
27964
- console.log(` ${source_default.gray("Interval:")} ${formatInterval(result.scanIntervalMs)}`);
28407
+ console.log(` ${source_default.gray("Exit reasoner:")} ${result.exitReasonerEnabled ? source_default.green("enabled") : source_default.dim("disabled")}`);
28408
+ console.log(` ${source_default.gray("Interval:")} ${formatInterval2(result.scanIntervalMs)}`);
27965
28409
  console.log(` ${source_default.gray("Next scan:")} ${formatShortDate5(result.nextScanAt)}`);
27966
28410
  console.log("");
27967
28411
  }
27968
28412
  } catch (error2) {
27969
- handleApiError(error2, "Agent create failed", logger29);
28413
+ handleApiError(error2, "Agent create failed", logger30);
27970
28414
  }
27971
28415
  });
27972
28416
  agent.command("list").description("List agents").option("--status <status>", "Filter by status: active, paused").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (options) => {
@@ -27990,16 +28434,16 @@ function registerAgentCommand(program2) {
27990
28434
  return;
27991
28435
  }
27992
28436
  console.log("");
27993
- console.log(" " + padRight("Name", 24) + padRight("Autonomy", 14) + padRight("Interval", 10) + padRight("Status", 10) + padRight("Ticks", 7) + padRight("Errors", 8) + "Next Scan");
27994
- console.log(source_default.gray(" " + "\u2500".repeat(100)));
28437
+ console.log(" " + padRight("Name", 24) + padRight("Autonomy", 22) + padRight("Interval", 10) + padRight("Status", 10) + padRight("Ticks", 7) + padRight("Errors", 8) + "Next Scan");
28438
+ console.log(source_default.gray(" " + "\u2500".repeat(108)));
27995
28439
  for (const a of result.agents) {
27996
- console.log(" " + padRight(a.name.slice(0, 22), 24) + padRight(formatAutonomy(a.autonomyLevel), 14) + padRight(formatInterval(a.scanIntervalMs), 10) + padRight(formatStatus2(a.status), 10) + padRight(String(a.tickCount), 7) + padRight(String(a.errorCount), 8) + formatShortDate5(a.nextScanAt));
28440
+ console.log(" " + padRight(a.name.slice(0, 22), 24) + padRight(formatAutonomy(a.autonomyLevel), 22) + padRight(formatInterval2(a.scanIntervalMs), 10) + padRight(formatStatus2(a.status), 10) + padRight(String(a.tickCount), 7) + padRight(String(a.errorCount), 8) + formatShortDate5(a.nextScanAt));
27997
28441
  }
27998
28442
  console.log("");
27999
28443
  console.log(source_default.dim(` ${result.count} agent(s)`));
28000
28444
  console.log("");
28001
28445
  } catch (error2) {
28002
- handleApiError(error2, "Agent list failed", logger29);
28446
+ handleApiError(error2, "Agent list failed", logger30);
28003
28447
  }
28004
28448
  });
28005
28449
  agent.command("show <agentId>").description("Show agent details and live state").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (agentId, options) => {
@@ -28029,7 +28473,9 @@ function registerAgentCommand(program2) {
28029
28473
  console.log(` ${source_default.gray("Analyze model:")} ${a.analyzeModel}`);
28030
28474
  if (a.decideModel)
28031
28475
  console.log(` ${source_default.gray("Decide model:")} ${a.decideModel}`);
28032
- console.log(` ${source_default.gray("Scan interval:")} ${formatInterval(a.scanIntervalMs)}`);
28476
+ console.log(` ${source_default.gray("Shared scan cache:")} ${a.disableSharedScanCache ? source_default.yellow("bypassed") : source_default.dim("enabled")}`);
28477
+ console.log(` ${source_default.gray("Exit reasoner:")} ${a.exitReasonerEnabled ? source_default.green("enabled") : source_default.dim("disabled")}`);
28478
+ console.log(` ${source_default.gray("Scan interval:")} ${formatInterval2(a.scanIntervalMs)}`);
28033
28479
  console.log(` ${source_default.gray("Max daily trades:")} ${a.maxDailyTrades}`);
28034
28480
  console.log(` ${source_default.gray("Max daily loss:")} $${a.maxDailyLossUsd}`);
28035
28481
  console.log(` ${source_default.gray("Max position:")} ${(a.maxPositionSizePct * 100).toFixed(0)}%`);
@@ -28072,7 +28518,7 @@ function registerAgentCommand(program2) {
28072
28518
  }
28073
28519
  console.log("");
28074
28520
  } catch (error2) {
28075
- handleApiError(error2, "Agent show failed", logger29);
28521
+ handleApiError(error2, "Agent show failed", logger30);
28076
28522
  }
28077
28523
  });
28078
28524
  agent.command("pause <agentId>").description("Pause an agent").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (agentId, options) => {
@@ -28088,7 +28534,7 @@ function registerAgentCommand(program2) {
28088
28534
  console.log(source_default.green(` Agent ${agentId} paused`));
28089
28535
  }
28090
28536
  } catch (error2) {
28091
- handleApiError(error2, "Agent pause failed", logger29);
28537
+ handleApiError(error2, "Agent pause failed", logger30);
28092
28538
  }
28093
28539
  });
28094
28540
  agent.command("resume <agentId>").description("Resume a paused agent").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (agentId, options) => {
@@ -28104,7 +28550,7 @@ function registerAgentCommand(program2) {
28104
28550
  console.log(source_default.green(` Agent ${agentId} resumed`));
28105
28551
  }
28106
28552
  } catch (error2) {
28107
- handleApiError(error2, "Agent resume failed", logger29);
28553
+ handleApiError(error2, "Agent resume failed", logger30);
28108
28554
  }
28109
28555
  });
28110
28556
  agent.command("delete <agentId>").description("Delete an agent").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (agentId, options) => {
@@ -28120,7 +28566,7 @@ function registerAgentCommand(program2) {
28120
28566
  console.log(source_default.green(` Agent ${agentId} deleted`));
28121
28567
  }
28122
28568
  } catch (error2) {
28123
- handleApiError(error2, "Agent delete failed", logger29);
28569
+ handleApiError(error2, "Agent delete failed", logger30);
28124
28570
  }
28125
28571
  });
28126
28572
  agent.command("exit <agentId>").description("Exit/close an open position for an agent").requiredOption("--symbol <symbol>", "Token symbol to exit (e.g. xyz:NATGAS)").option("--reason <text>", "Reason for exit").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (agentId, options) => {
@@ -28149,28 +28595,26 @@ function registerAgentCommand(program2) {
28149
28595
  console.log("");
28150
28596
  }
28151
28597
  } catch (error2) {
28152
- handleApiError(error2, "Position exit failed", logger29);
28598
+ handleApiError(error2, "Position exit failed", logger30);
28153
28599
  }
28154
28600
  });
28155
- agent.command("update <agentId>").description("Update agent config").option("--name <name>", "Agent name").option("--autonomy <level>", "Autonomy level").option("--scan-interval <ms>", "Scan interval in ms").option("--scan-interval-human <duration>", "Scan interval in human-readable format (e.g. 1m, 5m, 15m, 30m, 1h)").option("--watchlist <symbols>", "Comma-separated token symbols").option("--max-daily-trades <n>", "Max daily trades").option("--max-daily-loss <usd>", "Max daily loss in USD").option("--max-position-size <pct>", "Max position size as decimal").option("--min-confidence <n>", "Min confidence threshold").option("--scan-model <model>", "LLM model for market scanning").option("--analyze-model <model>", "LLM model for deep analysis").option("--decide-model <model>", "LLM model for trade decisions").addOption(new Option("--asset-class <class>", "Asset class for this agent").choices(["crypto", "commodities", "mixed"])).option("--soul-override <text>", "Custom soul/personality for this agent").option("--purpose-override <text>", "Custom purpose/mission for this agent").option("--soul-file <path>", "Load soul from a file").option("--purpose-file <path>", "Load purpose from a file").option("--exit-reasoner", "Enable LLM-powered exit reasoning for this agent").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (agentId, options) => {
28601
+ agent.command("update <agentId>").description("Update agent config").option("--name <name>", "Agent name").option("--autonomy <level>", AUTONOMY_HELP_UPDATE).option("--scan-interval <ms>", "Scan interval in raw milliseconds (e.g. 300000 = 5m)").option("--scan-interval-human <duration>", "Scan interval in human-readable format (e.g. 1m, 5m, 15m, 30m, 1h). Overrides --scan-interval").option("--watchlist <symbols>", "Comma-separated token symbols").option("--max-daily-trades <n>", "Max daily trades").option("--max-daily-loss <usd>", "Max daily loss in USD").option("--max-position-size <pct>", "Max position size as decimal").option("--min-confidence <n>", MIN_CONFIDENCE_HELP).option("--scan-model <model>", "LLM model for market scanning").option("--analyze-model <model>", "LLM model for deep analysis").option("--decide-model <model>", "LLM model for trade decisions").option("--disable-shared-scan-cache", SHARED_SCAN_CACHE_INTERNAL_HELP).option("--enable-shared-scan-cache", ENABLE_SHARED_SCAN_CACHE_HELP).addOption(new Option("--asset-class <class>", "Asset class for this agent").choices(["crypto", "commodities", "mixed"])).option("--soul-override <text>", "Custom soul/personality for this agent").option("--purpose-override <text>", "Custom purpose/mission for this agent").option("--soul-file <path>", "Load soul from a file").option("--purpose-file <path>", "Load purpose from a file").option("--exit-reasoner", EXIT_REASONER_HELP).option("--disable-exit-reasoner", DISABLE_EXIT_REASONER_HELP).addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (agentId, options) => {
28156
28602
  if (!await ensureRemote())
28157
28603
  return;
28158
28604
  const body = {};
28159
28605
  if (options.name)
28160
28606
  body.name = options.name;
28161
- if (options.exitReasoner)
28162
- body.exitReasonerEnabled = true;
28163
28607
  if (options.autonomy)
28164
28608
  body.autonomyLevel = options.autonomy;
28165
28609
  if (options.scanIntervalHuman) {
28166
- const ms = parseHumanInterval(options.scanIntervalHuman);
28610
+ const ms = parseHumanInterval2(options.scanIntervalHuman);
28167
28611
  if (ms === null) {
28168
28612
  console.error(source_default.red(`Error: Invalid duration "${options.scanIntervalHuman}". Use format like 1m, 5m, 15m, 30m, 1h.`));
28169
28613
  process.exitCode = 1;
28170
28614
  return;
28171
28615
  }
28172
- if (ms < MIN_SCAN_INTERVAL_MS) {
28173
- console.error(source_default.red(`Error: Scan interval must be at least 1m (60000ms). Got ${formatInterval(ms)}.`));
28616
+ if (ms < MIN_SCAN_INTERVAL_MS2) {
28617
+ console.error(source_default.red(`Error: Scan interval must be at least 1m (60000ms). Got ${formatInterval2(ms)}.`));
28174
28618
  process.exitCode = 1;
28175
28619
  return;
28176
28620
  }
@@ -28179,7 +28623,7 @@ function registerAgentCommand(program2) {
28179
28623
  body.scanIntervalMs = parseInt(options.scanInterval, 10);
28180
28624
  }
28181
28625
  if (options.watchlist)
28182
- body.watchlist = options.watchlist.split(",").map((s) => s.trim().toUpperCase());
28626
+ body.watchlist = normalizeWatchlistSymbols(options.watchlist.split(","));
28183
28627
  if (options.maxDailyTrades)
28184
28628
  body.maxDailyTrades = parseInt(options.maxDailyTrades, 10);
28185
28629
  if (options.maxDailyLoss)
@@ -28194,6 +28638,24 @@ function registerAgentCommand(program2) {
28194
28638
  body.analyzeModel = options.analyzeModel;
28195
28639
  if (options.decideModel)
28196
28640
  body.decideModel = options.decideModel;
28641
+ if (options.disableSharedScanCache && options.enableSharedScanCache) {
28642
+ console.error(source_default.red("Error: Choose either --disable-shared-scan-cache or --enable-shared-scan-cache."));
28643
+ process.exitCode = 1;
28644
+ return;
28645
+ }
28646
+ if (options.exitReasoner && options.disableExitReasoner) {
28647
+ console.error(source_default.red("Error: Choose either --exit-reasoner or --disable-exit-reasoner."));
28648
+ process.exitCode = 1;
28649
+ return;
28650
+ }
28651
+ if (options.disableSharedScanCache)
28652
+ body.disableSharedScanCache = true;
28653
+ if (options.enableSharedScanCache)
28654
+ body.disableSharedScanCache = false;
28655
+ if (options.exitReasoner)
28656
+ body.exitReasonerEnabled = true;
28657
+ if (options.disableExitReasoner)
28658
+ body.exitReasonerEnabled = false;
28197
28659
  if (options.assetClass)
28198
28660
  body.assetClass = options.assetClass;
28199
28661
  if (options.soulFile) {
@@ -28234,7 +28696,7 @@ function registerAgentCommand(program2) {
28234
28696
  console.log(source_default.green(` Agent ${agentId} updated`));
28235
28697
  }
28236
28698
  } catch (error2) {
28237
- handleApiError(error2, "Agent update failed", logger29);
28699
+ handleApiError(error2, "Agent update failed", logger30);
28238
28700
  }
28239
28701
  });
28240
28702
  }