@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.
- package/README.md +17 -10
- package/dist/cli.bundle.js +822 -360
- package/package.json +2 -2
package/dist/cli.bundle.js
CHANGED
|
@@ -6119,118 +6119,37 @@ var init_ansi_regex = __esm({
|
|
|
6119
6119
|
}
|
|
6120
6120
|
});
|
|
6121
6121
|
|
|
6122
|
-
// ../../node_modules/.pnpm/strip-ansi@7.2
|
|
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
|
|
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.
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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)
|
|
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
|
|
6220
|
+
var segmenter, zeroWidthClusterRegex, leadingNonPrintingRegex, rgiEmojiRegex;
|
|
6318
6221
|
var init_string_width = __esm({
|
|
6319
|
-
"../../node_modules/.pnpm/string-width@8.
|
|
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,
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
22627
|
-
console.log(` ${source_default.gray("Leaderboard alias:")} ${source_default.white(result.
|
|
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
|
|
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("
|
|
24560
|
-
console.log(source_default.dim(" Or:
|
|
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
|
|
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("
|
|
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.
|
|
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
|
|
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
|
|
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("
|
|
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("
|
|
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
|
|
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 (
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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("
|
|
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: {
|
|
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
|
|
25592
|
+
name: "Use my ChatGPT subscription (OpenAI sign-in, no LLM provider API key)",
|
|
25529
25593
|
value: "chatgpt",
|
|
25530
|
-
description: "
|
|
25594
|
+
description: "Connect ChatGPT after Trading Boy login \u2014 uses your existing ChatGPT Plus/Pro/Team plan"
|
|
25531
25595
|
},
|
|
25532
25596
|
{
|
|
25533
|
-
name: "
|
|
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 : "
|
|
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
|
|
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.
|
|
25627
|
-
console.log(source_default.dim("
|
|
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(
|
|
25631
|
-
console.log(` ${source_default.cyan("
|
|
25632
|
-
console.log(` ${source_default.cyan("
|
|
25633
|
-
console.log(` ${source_default.cyan("
|
|
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")}
|
|
25650
|
-
console.log(` ${source_default.white("trading-boy behavioral")}
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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",
|
|
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",
|
|
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",
|
|
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
|
|
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",
|
|
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",
|
|
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",
|
|
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
|
|
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",
|
|
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",
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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",
|
|
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",
|
|
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",
|
|
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",
|
|
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",
|
|
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",
|
|
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",
|
|
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",
|
|
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
|
|
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("
|
|
28276
|
+
return source_default.dim("Observe only");
|
|
27836
28277
|
case "SUGGEST":
|
|
27837
|
-
return source_default.blue("
|
|
28278
|
+
return source_default.blue("Suggest only");
|
|
27838
28279
|
case "AUTO_WITH_APPROVAL":
|
|
27839
|
-
return source_default.yellow("
|
|
28280
|
+
return source_default.yellow("Auto with approval");
|
|
27840
28281
|
case "FULLY_AUTONOMOUS":
|
|
27841
|
-
return source_default.red("
|
|
28282
|
+
return source_default.red("Fully auto");
|
|
27842
28283
|
default:
|
|
27843
28284
|
return level;
|
|
27844
28285
|
}
|
|
27845
28286
|
}
|
|
27846
|
-
function
|
|
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
|
|
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
|
|
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>",
|
|
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 =
|
|
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 <
|
|
27899
|
-
console.error(source_default.red(`Error: Scan interval must be at least 1m (60000ms). Got ${
|
|
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(",")
|
|
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("
|
|
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",
|
|
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",
|
|
27994
|
-
console.log(source_default.gray(" " + "\u2500".repeat(
|
|
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),
|
|
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",
|
|
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("
|
|
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",
|
|
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",
|
|
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",
|
|
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",
|
|
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",
|
|
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>",
|
|
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 =
|
|
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 <
|
|
28173
|
-
console.error(source_default.red(`Error: Scan interval must be at least 1m (60000ms). Got ${
|
|
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(",")
|
|
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",
|
|
28699
|
+
handleApiError(error2, "Agent update failed", logger30);
|
|
28238
28700
|
}
|
|
28239
28701
|
});
|
|
28240
28702
|
}
|