@trading-boy/cli 2.0.0 → 2.0.1
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/LICENSE +22 -0
- package/README.md +17 -10
- package/dist/cli.bundle.js +718 -354
- package/package.json +11 -12
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) {
|
|
@@ -24556,8 +24482,8 @@ function registerConfigCommand(program2) {
|
|
|
24556
24482
|
console.log(` ${source_default.gray("API URL:")} ${apiBase}`);
|
|
24557
24483
|
console.log(` ${source_default.gray("LLM Status:")} ${llmStatus}`);
|
|
24558
24484
|
if (llmStatus === "missing") {
|
|
24559
|
-
console.log(source_default.dim("
|
|
24560
|
-
console.log(source_default.dim(" Or:
|
|
24485
|
+
console.log(source_default.dim(" Add an LLM provider API key: trading-boy config set-llm-key <your-llm-provider-api-key>"));
|
|
24486
|
+
console.log(source_default.dim(" Or connect ChatGPT: trading-boy connect-chatgpt"));
|
|
24561
24487
|
console.log("");
|
|
24562
24488
|
return;
|
|
24563
24489
|
}
|
|
@@ -24568,7 +24494,7 @@ function registerConfigCommand(program2) {
|
|
|
24568
24494
|
}
|
|
24569
24495
|
printLlmConfig(llmConfig);
|
|
24570
24496
|
});
|
|
24571
|
-
configCmd.command("set-llm-key <apiKey>").description("Store your LLM API key for thesis extraction
|
|
24497
|
+
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
24498
|
if (!await ensureRemote())
|
|
24573
24499
|
return;
|
|
24574
24500
|
try {
|
|
@@ -24591,7 +24517,7 @@ function registerConfigCommand(program2) {
|
|
|
24591
24517
|
}
|
|
24592
24518
|
});
|
|
24593
24519
|
console.log("");
|
|
24594
|
-
console.log(source_default.green(" LLM API key saved successfully"));
|
|
24520
|
+
console.log(source_default.green(" LLM provider API key saved successfully"));
|
|
24595
24521
|
console.log(` ${source_default.gray("Provider:")} ${result.provider}`);
|
|
24596
24522
|
if (result.effectiveProvider && (result.effectiveProvider !== result.provider || result.effectiveModel !== result.model)) {
|
|
24597
24523
|
console.log(` ${source_default.gray("Effective:")} ${result.effectiveProvider} / ${result.effectiveModel ?? result.model}`);
|
|
@@ -24606,9 +24532,9 @@ function registerConfigCommand(program2) {
|
|
|
24606
24532
|
if (result.decideProvider || result.decideModel) {
|
|
24607
24533
|
console.log(` ${source_default.gray("Decide:")} ${result.decideProvider ?? result.provider} / ${result.decideModel ?? result.model}${opts.decideKey ? " (own key)" : ""}`);
|
|
24608
24534
|
}
|
|
24609
|
-
console.log(` ${source_default.gray("
|
|
24535
|
+
console.log(` ${source_default.gray("LLM key:")} ${apiKey.slice(0, 8)}${"*".repeat(Math.max(0, apiKey.length - 8))}`);
|
|
24610
24536
|
console.log("");
|
|
24611
|
-
console.log(source_default.dim(" Your key is encrypted at rest.
|
|
24537
|
+
console.log(source_default.dim(" Your LLM provider API key is encrypted at rest. Agents, thesis extraction, and coaching are now enabled."));
|
|
24612
24538
|
console.log("");
|
|
24613
24539
|
} catch (error2) {
|
|
24614
24540
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
@@ -24617,7 +24543,7 @@ function registerConfigCommand(program2) {
|
|
|
24617
24543
|
process.exitCode = error2 instanceof ApiError ? 2 : 1;
|
|
24618
24544
|
}
|
|
24619
24545
|
});
|
|
24620
|
-
configCmd.command("set-models").description("Update per-stage model assignments (works with
|
|
24546
|
+
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
24547
|
if (!await ensureRemote())
|
|
24622
24548
|
return;
|
|
24623
24549
|
if (!opts.model && !opts.scanModel && !opts.analyzeModel && !opts.decideModel && !opts.exitHeartbeatModel && !opts.exitEventModel) {
|
|
@@ -24757,7 +24683,7 @@ async function executeLogin(apiKey) {
|
|
|
24757
24683
|
};
|
|
24758
24684
|
}
|
|
24759
24685
|
function registerLoginCommand(program2) {
|
|
24760
|
-
program2.command("login").description("Authenticate with
|
|
24686
|
+
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
24687
|
try {
|
|
24762
24688
|
let apiKey;
|
|
24763
24689
|
if (opts.apiKey) {
|
|
@@ -24768,23 +24694,24 @@ function registerLoginCommand(program2) {
|
|
|
24768
24694
|
console.log("");
|
|
24769
24695
|
console.log(source_default.bold(" Trading Boy \u2014 Login"));
|
|
24770
24696
|
console.log(source_default.gray(" " + "\u2500".repeat(40)));
|
|
24771
|
-
console.log(source_default.dim("
|
|
24697
|
+
console.log(source_default.dim(" Authenticate your Trading Boy account on this machine."));
|
|
24698
|
+
console.log(source_default.dim(" Don't have a Trading Boy API key yet? Run: trading-boy subscribe"));
|
|
24772
24699
|
console.log("");
|
|
24773
24700
|
apiKey = await password({
|
|
24774
|
-
message: "Enter your API key",
|
|
24701
|
+
message: "Enter your Trading Boy API key",
|
|
24775
24702
|
mask: "*",
|
|
24776
24703
|
validate: (input) => {
|
|
24777
24704
|
if (!input)
|
|
24778
|
-
return "API key is required";
|
|
24705
|
+
return "Trading Boy API key is required";
|
|
24779
24706
|
if (!validateApiKeyFormat(input)) {
|
|
24780
|
-
return "Invalid key format. Expected: tb_live_<32hex>, tb_test_<32hex>, or tb_free_<32hex>";
|
|
24707
|
+
return "Invalid Trading Boy API key format. Expected: tb_live_<32hex>, tb_test_<32hex>, or tb_free_<32hex>";
|
|
24781
24708
|
}
|
|
24782
24709
|
return true;
|
|
24783
24710
|
}
|
|
24784
24711
|
});
|
|
24785
24712
|
}
|
|
24786
24713
|
if (!validateApiKeyFormat(apiKey)) {
|
|
24787
|
-
console.error(source_default.red(" Invalid key format. Expected: tb_live_<32hex>, tb_test_<32hex>, or tb_free_<32hex>"));
|
|
24714
|
+
console.error(source_default.red(" Invalid Trading Boy API key format. Expected: tb_live_<32hex>, tb_test_<32hex>, or tb_free_<32hex>"));
|
|
24788
24715
|
process.exitCode = 1;
|
|
24789
24716
|
return;
|
|
24790
24717
|
}
|
|
@@ -24792,7 +24719,7 @@ function registerLoginCommand(program2) {
|
|
|
24792
24719
|
const spinner = (await createSpinner2(" Verifying key...")).start();
|
|
24793
24720
|
const result = await executeLogin(apiKey);
|
|
24794
24721
|
if (!result.success) {
|
|
24795
|
-
spinner.fail(" Invalid API key");
|
|
24722
|
+
spinner.fail(" Invalid Trading Boy API key");
|
|
24796
24723
|
process.exitCode = 1;
|
|
24797
24724
|
return;
|
|
24798
24725
|
}
|
|
@@ -24807,7 +24734,7 @@ function registerLoginCommand(program2) {
|
|
|
24807
24734
|
if (result.keyId) {
|
|
24808
24735
|
console.log(` ${source_default.gray("Key ID:")} ${result.keyId}`);
|
|
24809
24736
|
}
|
|
24810
|
-
console.log(` ${source_default.gray("
|
|
24737
|
+
console.log(` ${source_default.gray("Trading Boy API key:")} ${redactApiKey(apiKey)}`);
|
|
24811
24738
|
console.log("");
|
|
24812
24739
|
} catch (error2) {
|
|
24813
24740
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
@@ -25164,6 +25091,27 @@ init_api_client();
|
|
|
25164
25091
|
// dist/commands/onboarding.js
|
|
25165
25092
|
init_source();
|
|
25166
25093
|
init_api_client();
|
|
25094
|
+
|
|
25095
|
+
// dist/product-events.js
|
|
25096
|
+
init_logger();
|
|
25097
|
+
init_api_client();
|
|
25098
|
+
var logger19 = createLogger2("cli-product-events");
|
|
25099
|
+
function emitCliProductEvent(eventType, metadata = {}) {
|
|
25100
|
+
void apiRequest("/api/v1/product-events", {
|
|
25101
|
+
method: "POST",
|
|
25102
|
+
body: {
|
|
25103
|
+
eventType,
|
|
25104
|
+
metadata
|
|
25105
|
+
}
|
|
25106
|
+
}).catch((error2) => {
|
|
25107
|
+
logger19.warn({
|
|
25108
|
+
eventType,
|
|
25109
|
+
error: error2 instanceof Error ? error2.message : String(error2)
|
|
25110
|
+
}, "Failed to emit CLI product event");
|
|
25111
|
+
});
|
|
25112
|
+
}
|
|
25113
|
+
|
|
25114
|
+
// dist/commands/onboarding.js
|
|
25167
25115
|
init_soul_wizard();
|
|
25168
25116
|
|
|
25169
25117
|
// dist/commands/connect-chatgpt.js
|
|
@@ -25172,16 +25120,16 @@ import http from "node:http";
|
|
|
25172
25120
|
import { URL as URL2 } from "node:url";
|
|
25173
25121
|
init_api_client();
|
|
25174
25122
|
init_utils();
|
|
25175
|
-
var
|
|
25123
|
+
var logger20 = createLogger("cli-connect-chatgpt");
|
|
25176
25124
|
var CALLBACK_PORT = 1455;
|
|
25177
25125
|
var CALLBACK_PATH = "/auth/callback";
|
|
25178
25126
|
var AUTH_TIMEOUT_MS = 3 * 60 * 1e3;
|
|
25179
25127
|
var POLL_INTERVAL_MS = 2e3;
|
|
25180
25128
|
function registerConnectChatgptCommand(program2) {
|
|
25181
|
-
program2.command("connect-chatgpt").description("Connect your ChatGPT subscription as your LLM provider (
|
|
25129
|
+
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
25130
|
try {
|
|
25183
25131
|
if (!await isRemoteMode()) {
|
|
25184
|
-
console.error(source_default.yellow(" Requires
|
|
25132
|
+
console.error(source_default.yellow(" Requires Trading Boy account auth on this machine. Run: trading-boy login"));
|
|
25185
25133
|
process.exitCode = 1;
|
|
25186
25134
|
return;
|
|
25187
25135
|
}
|
|
@@ -25192,7 +25140,7 @@ function registerConnectChatgptCommand(program2) {
|
|
|
25192
25140
|
}
|
|
25193
25141
|
} catch (error2) {
|
|
25194
25142
|
const msg = error2 instanceof Error ? error2.message : String(error2);
|
|
25195
|
-
|
|
25143
|
+
logger20.error({ error: msg }, "connect-chatgpt failed");
|
|
25196
25144
|
const connHelp = formatConnectionError(msg);
|
|
25197
25145
|
if (connHelp) {
|
|
25198
25146
|
console.error(source_default.red(`
|
|
@@ -25224,8 +25172,9 @@ async function handleConnect() {
|
|
|
25224
25172
|
console.log("");
|
|
25225
25173
|
console.log(source_default.bold.cyan(" Connect ChatGPT"));
|
|
25226
25174
|
console.log(source_default.gray(" " + "\u2500".repeat(50)));
|
|
25175
|
+
console.log(source_default.dim(" Your Trading Boy account is already authenticated."));
|
|
25227
25176
|
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
|
|
25177
|
+
console.log(source_default.dim(" No LLM provider API key needed \u2014 sign in with your OpenAI account instead."));
|
|
25229
25178
|
console.log("");
|
|
25230
25179
|
const { authUrl, state } = await apiRequest("/api/v1/codex/auth-url");
|
|
25231
25180
|
const result = await raceForAuth(authUrl, state);
|
|
@@ -25250,7 +25199,7 @@ function printSuccess(accountId, model) {
|
|
|
25250
25199
|
if (model)
|
|
25251
25200
|
console.log(` ${source_default.gray("Model:")} ${model}`);
|
|
25252
25201
|
console.log("");
|
|
25253
|
-
console.log(source_default.dim(" Your agents will now use your ChatGPT
|
|
25202
|
+
console.log(source_default.dim(" Your agents will now use your ChatGPT connection for LLM calls."));
|
|
25254
25203
|
console.log(source_default.dim(" Change model: trading-boy config set-models --model <model>"));
|
|
25255
25204
|
}
|
|
25256
25205
|
async function raceForAuth(authUrl, state) {
|
|
@@ -25320,7 +25269,7 @@ function startLocalCallbackServer(state, signal) {
|
|
|
25320
25269
|
server.on("error", (err) => {
|
|
25321
25270
|
clearTimeout(timeout);
|
|
25322
25271
|
if (err.code === "EADDRINUSE") {
|
|
25323
|
-
|
|
25272
|
+
logger20.debug("Port %d in use, falling back to polling only", CALLBACK_PORT);
|
|
25324
25273
|
return;
|
|
25325
25274
|
}
|
|
25326
25275
|
reject(err);
|
|
@@ -25342,7 +25291,7 @@ async function pollForConnection(signal) {
|
|
|
25342
25291
|
return { via: "poll", config };
|
|
25343
25292
|
}
|
|
25344
25293
|
} catch {
|
|
25345
|
-
|
|
25294
|
+
logger20.debug("Poll attempt failed, retrying...");
|
|
25346
25295
|
}
|
|
25347
25296
|
}
|
|
25348
25297
|
throw new Error("Timed out waiting for OpenAI authentication (3 minutes)");
|
|
@@ -25361,8 +25310,8 @@ async function handleDisconnect() {
|
|
|
25361
25310
|
method: "POST"
|
|
25362
25311
|
});
|
|
25363
25312
|
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>"));
|
|
25313
|
+
console.log(source_default.dim(" Your agents will need another LLM provider connection to continue. Set one:"));
|
|
25314
|
+
console.log(source_default.dim(" trading-boy config set-llm-key <your-llm-provider-api-key>"));
|
|
25366
25315
|
}
|
|
25367
25316
|
function callbackHtml(success2, errorMsg) {
|
|
25368
25317
|
const title = success2 ? "ChatGPT Connected" : "Connection Failed";
|
|
@@ -25418,15 +25367,60 @@ async function openBrowser(url) {
|
|
|
25418
25367
|
}
|
|
25419
25368
|
|
|
25420
25369
|
// dist/commands/onboarding.js
|
|
25370
|
+
var DEFAULT_FIRST_AGENT_AUTONOMY = "FULLY_AUTONOMOUS";
|
|
25371
|
+
var MIN_SCAN_INTERVAL_MS = 6e4;
|
|
25372
|
+
function trackOnboardingEvent(eventType, metadata = {}) {
|
|
25373
|
+
try {
|
|
25374
|
+
emitCliProductEvent(eventType, {
|
|
25375
|
+
source: "cli_onboarding",
|
|
25376
|
+
...metadata
|
|
25377
|
+
});
|
|
25378
|
+
} catch {
|
|
25379
|
+
}
|
|
25380
|
+
}
|
|
25421
25381
|
async function runOnboarding() {
|
|
25422
|
-
const { confirm, input } = await Promise.resolve().then(() => (init_esm15(), esm_exports));
|
|
25382
|
+
const { confirm, input, select } = await Promise.resolve().then(() => (init_esm15(), esm_exports));
|
|
25383
|
+
trackOnboardingEvent("cli.onboarding.started");
|
|
25423
25384
|
console.log("");
|
|
25424
|
-
console.log(source_default.bold.cyan(" Get Started"));
|
|
25385
|
+
console.log(source_default.bold.cyan(" Get Started With Trading Boy"));
|
|
25425
25386
|
console.log(source_default.gray(" " + "\u2500".repeat(50)));
|
|
25426
|
-
console.log(source_default.dim("
|
|
25387
|
+
console.log(source_default.dim(" Trading Boy can be used two ways: manual context and journaling, or hosted agents."));
|
|
25388
|
+
console.log(source_default.dim(" Trading Boy account auth gets you into the product."));
|
|
25389
|
+
console.log(source_default.dim(" ChatGPT or an LLM provider API key powers agent decisions."));
|
|
25427
25390
|
console.log("");
|
|
25391
|
+
let onboardingPath;
|
|
25392
|
+
try {
|
|
25393
|
+
onboardingPath = await select({
|
|
25394
|
+
message: "What do you want to set up first?",
|
|
25395
|
+
choices: [
|
|
25396
|
+
{
|
|
25397
|
+
name: "Explore context and journal",
|
|
25398
|
+
value: "explore",
|
|
25399
|
+
description: "Start with context, decisions, and journaling. Skip agent setup for now."
|
|
25400
|
+
},
|
|
25401
|
+
{
|
|
25402
|
+
name: "Build my first agent",
|
|
25403
|
+
value: "agent",
|
|
25404
|
+
description: "Set up hosted-agent prerequisites and review runtime behavior."
|
|
25405
|
+
}
|
|
25406
|
+
]
|
|
25407
|
+
});
|
|
25408
|
+
} catch (error2) {
|
|
25409
|
+
if (isUserAbort(error2))
|
|
25410
|
+
return;
|
|
25411
|
+
throw error2;
|
|
25412
|
+
}
|
|
25413
|
+
trackOnboardingEvent("cli.onboarding.path_selected", {
|
|
25414
|
+
path: onboardingPath === "explore" ? "explore_manual" : "build_agent"
|
|
25415
|
+
});
|
|
25416
|
+
if (onboardingPath === "explore") {
|
|
25417
|
+
printExploreQuickReference();
|
|
25418
|
+
trackOnboardingEvent("cli.onboarding.completed", { path: "explore_manual" });
|
|
25419
|
+
return;
|
|
25420
|
+
}
|
|
25428
25421
|
let traderRegistered = false;
|
|
25429
25422
|
let traderName = "default";
|
|
25423
|
+
let traderId = null;
|
|
25430
25424
|
try {
|
|
25431
25425
|
const wantsTrader = await confirm({
|
|
25432
25426
|
message: "Register your trader profile?",
|
|
@@ -25461,6 +25455,7 @@ async function runOnboarding() {
|
|
|
25461
25455
|
console.log(source_default.dim(" trading-boy trader set-alias <name> <new-alias>"));
|
|
25462
25456
|
}
|
|
25463
25457
|
traderName = name.trim();
|
|
25458
|
+
traderId = result.id;
|
|
25464
25459
|
traderRegistered = true;
|
|
25465
25460
|
} else {
|
|
25466
25461
|
console.log(source_default.yellow(" Skipped \u2014 not connected to API. Run: trading-boy trader register"));
|
|
@@ -25470,6 +25465,7 @@ async function runOnboarding() {
|
|
|
25470
25465
|
console.log(source_default.green(" \u2713 Trader profile already exists."));
|
|
25471
25466
|
traderName = name.trim();
|
|
25472
25467
|
traderRegistered = true;
|
|
25468
|
+
traderId = await resolveTraderId(name.trim());
|
|
25473
25469
|
} else {
|
|
25474
25470
|
const msg = error2 instanceof Error ? error2.message : String(error2);
|
|
25475
25471
|
console.log(source_default.yellow(` Could not register trader: ${msg}`));
|
|
@@ -25485,54 +25481,24 @@ async function runOnboarding() {
|
|
|
25485
25481
|
throw error2;
|
|
25486
25482
|
}
|
|
25487
25483
|
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
25484
|
try {
|
|
25519
25485
|
console.log(source_default.bold.cyan(" LLM Provider (required for agents)"));
|
|
25520
25486
|
console.log(source_default.gray(" " + "\u2500".repeat(50)));
|
|
25487
|
+
console.log(source_default.dim(" Your Trading Boy account is already authenticated."));
|
|
25521
25488
|
console.log(source_default.dim(" Your agent needs an LLM to analyze markets and make decisions."));
|
|
25522
25489
|
console.log("");
|
|
25523
|
-
const { select } = await Promise.resolve().then(() => (init_esm15(), esm_exports));
|
|
25524
25490
|
const llmChoice = await select({
|
|
25525
25491
|
message: "How do you want to power your agent?",
|
|
25526
25492
|
choices: [
|
|
25527
25493
|
{
|
|
25528
|
-
name: "Use my ChatGPT subscription (no API key
|
|
25494
|
+
name: "Use my ChatGPT subscription (OpenAI sign-in, no LLM provider API key)",
|
|
25529
25495
|
value: "chatgpt",
|
|
25530
|
-
description: "
|
|
25496
|
+
description: "Connect ChatGPT after Trading Boy login \u2014 uses your existing ChatGPT Plus/Pro/Team plan"
|
|
25531
25497
|
},
|
|
25532
25498
|
{
|
|
25533
|
-
name: "
|
|
25499
|
+
name: "Use an LLM provider API key (Anthropic, Gemini, OpenAI, etc.)",
|
|
25534
25500
|
value: "byok",
|
|
25535
|
-
description: "Paste an API key from any supported provider"
|
|
25501
|
+
description: "Paste an LLM provider API key from any supported provider"
|
|
25536
25502
|
},
|
|
25537
25503
|
{
|
|
25538
25504
|
name: "Skip for now",
|
|
@@ -25540,6 +25506,9 @@ async function runOnboarding() {
|
|
|
25540
25506
|
}
|
|
25541
25507
|
]
|
|
25542
25508
|
});
|
|
25509
|
+
trackOnboardingEvent("cli.onboarding.llm_setup_choice", {
|
|
25510
|
+
choice: llmChoice === "byok" ? "provider_api_key" : llmChoice === "skip" ? "skipped" : "chatgpt"
|
|
25511
|
+
});
|
|
25543
25512
|
if (llmChoice === "chatgpt") {
|
|
25544
25513
|
try {
|
|
25545
25514
|
await handleConnect();
|
|
@@ -25559,8 +25528,8 @@ async function runOnboarding() {
|
|
|
25559
25528
|
console.log(` ${source_default.white("Ollama")} ${source_default.dim("\u2014 Local models")}`);
|
|
25560
25529
|
console.log("");
|
|
25561
25530
|
const llmKey = await input({
|
|
25562
|
-
message: "Paste your API key",
|
|
25563
|
-
validate: (v) => v.trim().length > 5 ? true : "
|
|
25531
|
+
message: "Paste your LLM provider API key",
|
|
25532
|
+
validate: (v) => v.trim().length > 5 ? true : "LLM provider API key is too short"
|
|
25564
25533
|
});
|
|
25565
25534
|
try {
|
|
25566
25535
|
if (await isRemoteMode()) {
|
|
@@ -25568,22 +25537,22 @@ async function runOnboarding() {
|
|
|
25568
25537
|
method: "PUT",
|
|
25569
25538
|
body: { apiKey: llmKey.trim() }
|
|
25570
25539
|
});
|
|
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>"));
|
|
25540
|
+
console.log(source_default.green(` \u2713 LLM provider API key saved \u2014 ${result.provider} / ${result.model}`));
|
|
25541
|
+
console.log(source_default.dim(" Change model later: trading-boy config set-llm-key <your-llm-provider-api-key> --model <model>"));
|
|
25573
25542
|
} else {
|
|
25574
25543
|
console.log(source_default.yellow(" Skipped \u2014 not connected to API."));
|
|
25575
25544
|
}
|
|
25576
25545
|
} catch (error2) {
|
|
25577
25546
|
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>"));
|
|
25547
|
+
console.log(source_default.yellow(` Could not save LLM provider API key: ${msg}`));
|
|
25548
|
+
console.log(source_default.dim(" Set it later: trading-boy config set-llm-key <your-llm-provider-api-key>"));
|
|
25580
25549
|
}
|
|
25581
25550
|
} else {
|
|
25582
25551
|
console.log("");
|
|
25583
25552
|
console.log(source_default.yellow(" \u26A0 Without an LLM provider, agents can scan prices but cannot"));
|
|
25584
25553
|
console.log(source_default.yellow(" analyze markets or make trade decisions."));
|
|
25585
25554
|
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>"));
|
|
25555
|
+
console.log(source_default.dim(" Or BYOK: trading-boy config set-llm-key <your-llm-provider-api-key>"));
|
|
25587
25556
|
}
|
|
25588
25557
|
} catch (error2) {
|
|
25589
25558
|
if (isUserAbort(error2))
|
|
@@ -25591,15 +25560,47 @@ async function runOnboarding() {
|
|
|
25591
25560
|
throw error2;
|
|
25592
25561
|
}
|
|
25593
25562
|
console.log("");
|
|
25563
|
+
if (traderRegistered) {
|
|
25564
|
+
try {
|
|
25565
|
+
const wantsIdentity = await confirm({
|
|
25566
|
+
message: "Set up your trading identity? (interactive SOUL wizard)",
|
|
25567
|
+
default: true
|
|
25568
|
+
});
|
|
25569
|
+
if (wantsIdentity) {
|
|
25570
|
+
console.log("");
|
|
25571
|
+
console.log(source_default.dim(" Optional, but useful: your identity personalizes context \u2014 bias warnings, scope checks,"));
|
|
25572
|
+
console.log(source_default.dim(" and tailored synthesis based on who you are as a trader."));
|
|
25573
|
+
console.log("");
|
|
25574
|
+
try {
|
|
25575
|
+
await runSoulWizardAndUpload(traderName);
|
|
25576
|
+
} catch (wizardError) {
|
|
25577
|
+
if (isUserAbort(wizardError))
|
|
25578
|
+
return;
|
|
25579
|
+
const msg = wizardError instanceof Error ? wizardError.message : String(wizardError);
|
|
25580
|
+
console.log(source_default.yellow(` Could not complete SOUL wizard: ${msg}`));
|
|
25581
|
+
console.log(source_default.dim(" You can do this later: trading-boy trader soul-wizard <name>"));
|
|
25582
|
+
}
|
|
25583
|
+
} else {
|
|
25584
|
+
console.log(source_default.dim(" Skipped. Run later: trading-boy trader soul-wizard <name>"));
|
|
25585
|
+
}
|
|
25586
|
+
} catch (error2) {
|
|
25587
|
+
if (isUserAbort(error2))
|
|
25588
|
+
return;
|
|
25589
|
+
throw error2;
|
|
25590
|
+
}
|
|
25591
|
+
console.log("");
|
|
25592
|
+
}
|
|
25594
25593
|
try {
|
|
25595
25594
|
const wantsTelegram = await confirm({
|
|
25596
25595
|
message: "Connect Telegram for daily summaries?",
|
|
25597
25596
|
default: true
|
|
25598
25597
|
});
|
|
25599
25598
|
if (wantsTelegram) {
|
|
25599
|
+
console.log("");
|
|
25600
|
+
console.log(source_default.dim(" Optional, but useful: Telegram keeps alerts and summaries close to your existing workflow."));
|
|
25600
25601
|
console.log("");
|
|
25601
25602
|
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."));
|
|
25603
|
+
console.log(source_default.white(" Send ") + source_default.cyan("/start") + source_default.white(" and paste your Trading Boy API key to connect."));
|
|
25603
25604
|
console.log("");
|
|
25604
25605
|
console.log(source_default.dim(" The bot will send you a daily trading summary at 08:00 UTC."));
|
|
25605
25606
|
console.log(source_default.dim(" You can also use /summary, /agents, /positions, /pause, and /soul."));
|
|
@@ -25612,29 +25613,59 @@ async function runOnboarding() {
|
|
|
25612
25613
|
throw error2;
|
|
25613
25614
|
}
|
|
25614
25615
|
console.log("");
|
|
25616
|
+
printAgentRuntimeOverview();
|
|
25617
|
+
try {
|
|
25618
|
+
await runFirstAgentCreationStep(confirm, input, select, traderId, traderRegistered);
|
|
25619
|
+
} catch (error2) {
|
|
25620
|
+
if (isUserAbort(error2))
|
|
25621
|
+
return;
|
|
25622
|
+
throw error2;
|
|
25623
|
+
}
|
|
25624
|
+
printAgentQuickReference(traderRegistered);
|
|
25625
|
+
trackOnboardingEvent("cli.onboarding.completed", { path: "build_agent" });
|
|
25626
|
+
}
|
|
25627
|
+
function printExploreQuickReference() {
|
|
25628
|
+
console.log(source_default.bold.cyan(" Explore Context And Journal"));
|
|
25629
|
+
console.log(source_default.gray(" " + "\u2500".repeat(50)));
|
|
25630
|
+
console.log("");
|
|
25631
|
+
console.log(source_default.dim(" You can start manually and come back for agents later."));
|
|
25632
|
+
console.log("");
|
|
25633
|
+
console.log(` ${source_default.white("trading-boy context SOL")} ${source_default.dim("Full context for any token")}`);
|
|
25634
|
+
console.log(` ${source_default.white("trading-boy query BTC")} ${source_default.dim("Quick price + funding snapshot")}`);
|
|
25635
|
+
console.log(` ${source_default.white("trading-boy decisions")} ${source_default.dim("Review trade decisions and outcomes")}`);
|
|
25636
|
+
console.log(` ${source_default.white("trading-boy journal list")} ${source_default.dim("Review your journal entries")}`);
|
|
25637
|
+
console.log(` ${source_default.white("trading-boy stats")} ${source_default.dim("Track performance")}`);
|
|
25638
|
+
console.log("");
|
|
25639
|
+
console.log(source_default.dim(" Build an agent later: trading-boy onboarding"));
|
|
25640
|
+
console.log(source_default.dim(" Full docs: https://api.cabal.ventures/docs"));
|
|
25641
|
+
console.log("");
|
|
25642
|
+
}
|
|
25643
|
+
function printAgentRuntimeOverview() {
|
|
25615
25644
|
console.log(source_default.bold.cyan(" How Agents Work"));
|
|
25616
25645
|
console.log(source_default.gray(" " + "\u2500".repeat(50)));
|
|
25617
25646
|
console.log("");
|
|
25618
25647
|
console.log(source_default.dim(" Once you create an agent, it runs continuously on our servers:"));
|
|
25619
25648
|
console.log("");
|
|
25620
|
-
console.log(` ${source_default.white("Scan")} ${source_default.dim("Every
|
|
25649
|
+
console.log(` ${source_default.white("Scan")} ${source_default.dim("Every 5 min by default \u2014 scans your watchlist for setups")}`);
|
|
25621
25650
|
console.log(` ${source_default.white("Analyze")} ${source_default.dim("When a setup is found \u2014 deep context analysis via your LLM")}`);
|
|
25622
25651
|
console.log(` ${source_default.white("Decide")} ${source_default.dim("After analysis \u2014 enter/exit/hold based on your strategy")}`);
|
|
25623
25652
|
console.log(` ${source_default.white("Learn")} ${source_default.dim("After trades close \u2014 updates edge profile from outcomes")}`);
|
|
25624
25653
|
console.log("");
|
|
25625
25654
|
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("
|
|
25655
|
+
console.log(source_default.dim(" Lower intervals = more LLM calls = higher cost."));
|
|
25656
|
+
console.log(source_default.dim(" Use --scan-interval-human for readable values like 15m or 1h."));
|
|
25657
|
+
console.log(source_default.dim(" Use --scan-interval for raw milliseconds like 300000."));
|
|
25658
|
+
console.log(source_default.dim(" Change it: trading-boy agent update <agent-id> --scan-interval-human 15m"));
|
|
25628
25659
|
console.log("");
|
|
25629
25660
|
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")}`);
|
|
25661
|
+
console.log(source_default.dim(" New agents default to Fully auto (FULLY_AUTONOMOUS). Other modes are available if you want more control."));
|
|
25662
|
+
console.log(` ${source_default.cyan("Fully auto")} ${source_default.dim("(FULLY_AUTONOMOUS) \u2014 Default: trades within your guardrails, no human in the loop")}`);
|
|
25663
|
+
console.log(` ${source_default.cyan("Auto with approval")} ${source_default.dim("(AUTO_WITH_APPROVAL) \u2014 Proposes trades, waits for your OK")}`);
|
|
25664
|
+
console.log(` ${source_default.cyan("Suggest only")} ${source_default.dim("(SUGGEST) \u2014 Sends trade ideas to your Telegram")}`);
|
|
25665
|
+
console.log(` ${source_default.cyan("Observe only")} ${source_default.dim("(OBSERVE_ONLY) \u2014 Scans and analyzes, but takes no action")}`);
|
|
25637
25666
|
console.log("");
|
|
25667
|
+
}
|
|
25668
|
+
function printAgentQuickReference(traderRegistered) {
|
|
25638
25669
|
console.log(source_default.bold.cyan(" Quick Reference"));
|
|
25639
25670
|
console.log(source_default.gray(" " + "\u2500".repeat(50)));
|
|
25640
25671
|
console.log("");
|
|
@@ -25646,19 +25677,321 @@ async function runOnboarding() {
|
|
|
25646
25677
|
console.log(` ${source_default.white("trading-boy narrative list")} ${source_default.dim("Active market narratives")}`);
|
|
25647
25678
|
console.log(` ${source_default.white("trading-boy catalysts")} ${source_default.dim("Upcoming events")}`);
|
|
25648
25679
|
if (traderRegistered) {
|
|
25649
|
-
console.log(` ${source_default.white("trading-boy edge")}
|
|
25650
|
-
console.log(` ${source_default.white("trading-boy behavioral")}
|
|
25680
|
+
console.log(` ${source_default.white("trading-boy edge <trader-id>")} ${source_default.dim("Your edge profile")}`);
|
|
25681
|
+
console.log(` ${source_default.white("trading-boy behavioral profile --trader <trader-id>")} ${source_default.dim("Behavioral analysis")}`);
|
|
25651
25682
|
}
|
|
25652
25683
|
console.log("");
|
|
25653
25684
|
console.log(source_default.dim(" Full docs: https://api.cabal.ventures/docs"));
|
|
25654
25685
|
console.log("");
|
|
25655
25686
|
}
|
|
25687
|
+
async function resolveTraderId(nameOrId) {
|
|
25688
|
+
try {
|
|
25689
|
+
const result = await apiRequest(`/api/v1/traders/${encodeURIComponent(nameOrId)}`);
|
|
25690
|
+
return typeof result.id === "string" && result.id.length > 0 ? result.id : null;
|
|
25691
|
+
} catch {
|
|
25692
|
+
return null;
|
|
25693
|
+
}
|
|
25694
|
+
}
|
|
25695
|
+
async function runFirstAgentCreationStep(confirm, input, select, traderId, traderRegistered) {
|
|
25696
|
+
console.log(source_default.bold.cyan(" First Agent"));
|
|
25697
|
+
console.log(source_default.gray(" " + "\u2500".repeat(50)));
|
|
25698
|
+
console.log("");
|
|
25699
|
+
if (!traderId) {
|
|
25700
|
+
if (traderRegistered) {
|
|
25701
|
+
console.log(source_default.yellow(" Skipping first-agent creation because Trading Boy could not resolve your trader ID automatically."));
|
|
25702
|
+
console.log(source_default.dim(" Find it later with: trading-boy trader list"));
|
|
25703
|
+
} else {
|
|
25704
|
+
console.log(source_default.yellow(" Skipping first-agent creation because no trader profile is available yet."));
|
|
25705
|
+
console.log(source_default.dim(' Register one later: trading-boy trader register --name "YourName"'));
|
|
25706
|
+
}
|
|
25707
|
+
console.log(source_default.dim(" Then create an agent with: trading-boy agent create --trader-id <id>"));
|
|
25708
|
+
console.log("");
|
|
25709
|
+
return;
|
|
25710
|
+
}
|
|
25711
|
+
const wantsFirstAgent = await confirm({
|
|
25712
|
+
message: "Create your first agent now?",
|
|
25713
|
+
default: true
|
|
25714
|
+
});
|
|
25715
|
+
if (!wantsFirstAgent) {
|
|
25716
|
+
console.log(source_default.dim(` Skipped first-agent creation. Run later: trading-boy agent create --trader-id ${traderId}`));
|
|
25717
|
+
console.log("");
|
|
25718
|
+
return;
|
|
25719
|
+
}
|
|
25720
|
+
const setupMode = await select({
|
|
25721
|
+
message: "Choose your first-agent setup",
|
|
25722
|
+
choices: [
|
|
25723
|
+
{
|
|
25724
|
+
name: "Default setup",
|
|
25725
|
+
value: "default",
|
|
25726
|
+
description: "Use the standard fully-auto setup with default risk and scan settings."
|
|
25727
|
+
},
|
|
25728
|
+
{
|
|
25729
|
+
name: "Advanced setup",
|
|
25730
|
+
value: "advanced",
|
|
25731
|
+
description: "Tune autonomy, watchlist, interval, confidence, risk, and asset class."
|
|
25732
|
+
}
|
|
25733
|
+
]
|
|
25734
|
+
});
|
|
25735
|
+
const body = {
|
|
25736
|
+
traderId,
|
|
25737
|
+
autonomyLevel: DEFAULT_FIRST_AGENT_AUTONOMY
|
|
25738
|
+
};
|
|
25739
|
+
if (setupMode === "advanced") {
|
|
25740
|
+
trackOnboardingEvent("cli.onboarding.advanced_setup_opened", {
|
|
25741
|
+
path: "build_agent"
|
|
25742
|
+
});
|
|
25743
|
+
console.log("");
|
|
25744
|
+
console.log(source_default.dim(" Advanced setup exposes the highest-value controls now. Leave a field blank to keep the default."));
|
|
25745
|
+
console.log("");
|
|
25746
|
+
Object.assign(body, await promptAdvancedAgentConfig(input, select));
|
|
25747
|
+
}
|
|
25748
|
+
if (String(body.autonomyLevel) === DEFAULT_FIRST_AGENT_AUTONOMY) {
|
|
25749
|
+
console.log("");
|
|
25750
|
+
console.log(source_default.dim(` This first agent starts in Fully auto (${DEFAULT_FIRST_AGENT_AUTONOMY}).`));
|
|
25751
|
+
console.log(source_default.dim(" It can trade within the default guardrails and scan interval."));
|
|
25752
|
+
console.log(source_default.dim(" You can change autonomy later to Auto with approval, Suggest only, or Observe only."));
|
|
25753
|
+
console.log("");
|
|
25754
|
+
const confirmFullyAuto = await confirm({
|
|
25755
|
+
message: "Create this Fully auto first agent now?",
|
|
25756
|
+
default: true
|
|
25757
|
+
});
|
|
25758
|
+
if (!confirmFullyAuto) {
|
|
25759
|
+
console.log(source_default.dim(` Skipped first-agent creation. Run later: trading-boy agent create --trader-id ${traderId}`));
|
|
25760
|
+
console.log("");
|
|
25761
|
+
return;
|
|
25762
|
+
}
|
|
25763
|
+
} else {
|
|
25764
|
+
console.log("");
|
|
25765
|
+
console.log(source_default.dim(` This first agent starts in ${formatAutonomyLabel(String(body.autonomyLevel))}.`));
|
|
25766
|
+
console.log(source_default.dim(" You can still change autonomy, risk, and model routing later."));
|
|
25767
|
+
console.log("");
|
|
25768
|
+
const confirmAdvanced = await confirm({
|
|
25769
|
+
message: `Create this ${formatAutonomyProductLabel(String(body.autonomyLevel))} first agent now?`,
|
|
25770
|
+
default: true
|
|
25771
|
+
});
|
|
25772
|
+
if (!confirmAdvanced) {
|
|
25773
|
+
console.log(source_default.dim(` Skipped first-agent creation. Run later: trading-boy agent create --trader-id ${traderId}`));
|
|
25774
|
+
console.log("");
|
|
25775
|
+
return;
|
|
25776
|
+
}
|
|
25777
|
+
}
|
|
25778
|
+
try {
|
|
25779
|
+
const result = await apiRequest("/api/v1/agents", {
|
|
25780
|
+
method: "POST",
|
|
25781
|
+
body
|
|
25782
|
+
});
|
|
25783
|
+
trackOnboardingEvent("cli.onboarding.first_agent_created", {
|
|
25784
|
+
setup_mode: setupMode,
|
|
25785
|
+
autonomy: String(body.autonomyLevel),
|
|
25786
|
+
asset_class: typeof body.assetClass === "string" ? body.assetClass : "crypto",
|
|
25787
|
+
has_watchlist: Array.isArray(body.watchlist) && body.watchlist.length > 0,
|
|
25788
|
+
used_advanced_setup: setupMode === "advanced"
|
|
25789
|
+
});
|
|
25790
|
+
console.log("");
|
|
25791
|
+
console.log(source_default.green(" First Agent Ready"));
|
|
25792
|
+
console.log(` ${source_default.gray("ID:")} ${result.id}`);
|
|
25793
|
+
console.log(` ${source_default.gray("Autonomy:")} ${formatAutonomyLabel(result.autonomyLevel)}`);
|
|
25794
|
+
console.log(` ${source_default.gray("Interval:")} ${formatInterval(result.scanIntervalMs)}`);
|
|
25795
|
+
console.log(` ${source_default.gray("Exit reasoner:")} ${result.exitReasonerEnabled ? source_default.green("enabled") : source_default.dim("disabled")}`);
|
|
25796
|
+
console.log("");
|
|
25797
|
+
console.log(source_default.dim(" Next:"));
|
|
25798
|
+
console.log(source_default.dim(" trading-boy agent list"));
|
|
25799
|
+
console.log(source_default.dim(` trading-boy agent update ${result.id} --autonomy AUTO_WITH_APPROVAL`));
|
|
25800
|
+
console.log(source_default.dim(" Advanced toggles:"));
|
|
25801
|
+
console.log(source_default.dim(` exit reasoner on: trading-boy agent update ${result.id} --exit-reasoner`));
|
|
25802
|
+
console.log(source_default.dim(` exit reasoner off: trading-boy agent update ${result.id} --disable-exit-reasoner`));
|
|
25803
|
+
console.log(source_default.dim(" More customization later:"));
|
|
25804
|
+
console.log(source_default.dim(" per-stage models/providers: trading-boy config set-models --help"));
|
|
25805
|
+
console.log(source_default.dim(` full agent flags and overrides: trading-boy agent update ${result.id} --help`));
|
|
25806
|
+
console.log("");
|
|
25807
|
+
} catch (error2) {
|
|
25808
|
+
const msg = error2 instanceof Error ? error2.message : String(error2);
|
|
25809
|
+
console.log(source_default.yellow(` Could not create your first agent: ${msg}`));
|
|
25810
|
+
console.log(source_default.dim(` Create it later: trading-boy agent create --trader-id ${traderId}`));
|
|
25811
|
+
console.log(source_default.dim(" You can review agents anytime with: trading-boy agent list"));
|
|
25812
|
+
console.log("");
|
|
25813
|
+
}
|
|
25814
|
+
}
|
|
25815
|
+
function formatAutonomyLabel(level) {
|
|
25816
|
+
switch (level) {
|
|
25817
|
+
case "FULLY_AUTONOMOUS":
|
|
25818
|
+
return "Fully auto (FULLY_AUTONOMOUS)";
|
|
25819
|
+
case "AUTO_WITH_APPROVAL":
|
|
25820
|
+
return "Auto with approval (AUTO_WITH_APPROVAL)";
|
|
25821
|
+
case "SUGGEST":
|
|
25822
|
+
return "Suggest only (SUGGEST)";
|
|
25823
|
+
case "OBSERVE_ONLY":
|
|
25824
|
+
return "Observe only (OBSERVE_ONLY)";
|
|
25825
|
+
default:
|
|
25826
|
+
return level;
|
|
25827
|
+
}
|
|
25828
|
+
}
|
|
25829
|
+
function formatAutonomyProductLabel(level) {
|
|
25830
|
+
switch (level) {
|
|
25831
|
+
case "FULLY_AUTONOMOUS":
|
|
25832
|
+
return "Fully auto";
|
|
25833
|
+
case "AUTO_WITH_APPROVAL":
|
|
25834
|
+
return "Auto with approval";
|
|
25835
|
+
case "SUGGEST":
|
|
25836
|
+
return "Suggest only";
|
|
25837
|
+
case "OBSERVE_ONLY":
|
|
25838
|
+
return "Observe only";
|
|
25839
|
+
default:
|
|
25840
|
+
return level;
|
|
25841
|
+
}
|
|
25842
|
+
}
|
|
25843
|
+
function formatInterval(ms) {
|
|
25844
|
+
if (ms < 6e4)
|
|
25845
|
+
return `${Math.round(ms / 1e3)}s`;
|
|
25846
|
+
if (ms < 36e5)
|
|
25847
|
+
return `${Math.round(ms / 6e4)}m`;
|
|
25848
|
+
return `${(ms / 36e5).toFixed(ms % 36e5 === 0 ? 0 : 1)}h`;
|
|
25849
|
+
}
|
|
25850
|
+
async function promptAdvancedAgentConfig(input, select) {
|
|
25851
|
+
const autonomyLevel = await select({
|
|
25852
|
+
message: "Autonomy mode",
|
|
25853
|
+
choices: [
|
|
25854
|
+
{
|
|
25855
|
+
name: "Fully auto (FULLY_AUTONOMOUS)",
|
|
25856
|
+
value: "FULLY_AUTONOMOUS",
|
|
25857
|
+
description: "Default. Trades within your guardrails, no human in the loop."
|
|
25858
|
+
},
|
|
25859
|
+
{
|
|
25860
|
+
name: "Auto with approval (AUTO_WITH_APPROVAL)",
|
|
25861
|
+
value: "AUTO_WITH_APPROVAL",
|
|
25862
|
+
description: "Proposes trades, waits for your OK."
|
|
25863
|
+
},
|
|
25864
|
+
{
|
|
25865
|
+
name: "Suggest only (SUGGEST)",
|
|
25866
|
+
value: "SUGGEST",
|
|
25867
|
+
description: "Sends trade ideas without placing trades."
|
|
25868
|
+
},
|
|
25869
|
+
{
|
|
25870
|
+
name: "Observe only (OBSERVE_ONLY)",
|
|
25871
|
+
value: "OBSERVE_ONLY",
|
|
25872
|
+
description: "Scans and analyzes, but takes no action."
|
|
25873
|
+
}
|
|
25874
|
+
]
|
|
25875
|
+
});
|
|
25876
|
+
const watchlist = await promptOptionalValue(input, {
|
|
25877
|
+
message: "Watchlist (optional, comma-separated symbols like SOL,JUP)",
|
|
25878
|
+
parse: parseWatchlist,
|
|
25879
|
+
invalidMessage: "Enter at least one symbol, or leave it blank to keep the default."
|
|
25880
|
+
});
|
|
25881
|
+
const scanIntervalMs = await promptOptionalValue(input, {
|
|
25882
|
+
message: "Scan interval (optional, use 15m, 30m, 1h. Leave blank for default)",
|
|
25883
|
+
parse: parseScanInterval,
|
|
25884
|
+
invalidMessage: "Use a readable duration like 15m, 30m, or 1h, with a minimum of 1m."
|
|
25885
|
+
});
|
|
25886
|
+
const minConfidence = await promptOptionalValue(input, {
|
|
25887
|
+
message: "Minimum confidence threshold (optional, 0-1 where 0.70 = 70%. Leave blank for default)",
|
|
25888
|
+
parse: parseMinConfidence,
|
|
25889
|
+
invalidMessage: "Enter a number from 0 to 1, for example 0.70 = 70%, or leave it blank for the default."
|
|
25890
|
+
});
|
|
25891
|
+
const maxDailyLossUsd = await promptOptionalValue(input, {
|
|
25892
|
+
message: "Max daily loss in USD (optional. Leave blank for default)",
|
|
25893
|
+
parse: parsePositiveNumber,
|
|
25894
|
+
invalidMessage: "Enter a positive USD amount, or leave it blank for the default."
|
|
25895
|
+
});
|
|
25896
|
+
const maxPositionSizePct = await promptOptionalValue(input, {
|
|
25897
|
+
message: "Max position size (optional decimal, so 0.10 = 10%. Leave blank for default)",
|
|
25898
|
+
parse: parsePositionSize,
|
|
25899
|
+
invalidMessage: "Enter a decimal between 0 and 1, such as 0.10 = 10%, or leave it blank for the default."
|
|
25900
|
+
});
|
|
25901
|
+
const assetClass = await select({
|
|
25902
|
+
message: "Asset class",
|
|
25903
|
+
choices: [
|
|
25904
|
+
{
|
|
25905
|
+
name: "Keep the default asset class",
|
|
25906
|
+
value: "default"
|
|
25907
|
+
},
|
|
25908
|
+
{
|
|
25909
|
+
name: "Crypto",
|
|
25910
|
+
value: "crypto"
|
|
25911
|
+
},
|
|
25912
|
+
{
|
|
25913
|
+
name: "Commodities",
|
|
25914
|
+
value: "commodities"
|
|
25915
|
+
},
|
|
25916
|
+
{
|
|
25917
|
+
name: "Mixed",
|
|
25918
|
+
value: "mixed"
|
|
25919
|
+
}
|
|
25920
|
+
]
|
|
25921
|
+
});
|
|
25922
|
+
return {
|
|
25923
|
+
autonomyLevel,
|
|
25924
|
+
...watchlist ? { watchlist } : {},
|
|
25925
|
+
...scanIntervalMs !== void 0 ? { scanIntervalMs } : {},
|
|
25926
|
+
...minConfidence !== void 0 ? { minConfidence } : {},
|
|
25927
|
+
...maxDailyLossUsd !== void 0 ? { maxDailyLossUsd } : {},
|
|
25928
|
+
...maxPositionSizePct !== void 0 ? { maxPositionSizePct } : {},
|
|
25929
|
+
...assetClass !== "default" ? { assetClass } : {}
|
|
25930
|
+
};
|
|
25931
|
+
}
|
|
25932
|
+
async function promptOptionalValue(input, options) {
|
|
25933
|
+
const raw = (await input({ message: options.message, default: "" })).trim();
|
|
25934
|
+
if (raw.length === 0)
|
|
25935
|
+
return void 0;
|
|
25936
|
+
const parsed = options.parse(raw);
|
|
25937
|
+
if (parsed !== null)
|
|
25938
|
+
return parsed;
|
|
25939
|
+
console.log(source_default.yellow(` ${options.invalidMessage}`));
|
|
25940
|
+
return promptOptionalValue(input, options);
|
|
25941
|
+
}
|
|
25942
|
+
function parseWatchlist(value) {
|
|
25943
|
+
const normalized = normalizeWatchlistSymbols(value.split(","));
|
|
25944
|
+
return normalized.length > 0 ? normalized : null;
|
|
25945
|
+
}
|
|
25946
|
+
function parseHumanInterval(value) {
|
|
25947
|
+
const match = value.trim().match(/^(\d+(?:\.\d+)?)\s*(s|m|h)$/i);
|
|
25948
|
+
if (!match)
|
|
25949
|
+
return null;
|
|
25950
|
+
const amount = parseFloat(match[1]);
|
|
25951
|
+
const unit = match[2].toLowerCase();
|
|
25952
|
+
if (Number.isNaN(amount) || amount <= 0)
|
|
25953
|
+
return null;
|
|
25954
|
+
switch (unit) {
|
|
25955
|
+
case "s":
|
|
25956
|
+
return amount * 1e3;
|
|
25957
|
+
case "m":
|
|
25958
|
+
return amount * 6e4;
|
|
25959
|
+
case "h":
|
|
25960
|
+
return amount * 36e5;
|
|
25961
|
+
default:
|
|
25962
|
+
return null;
|
|
25963
|
+
}
|
|
25964
|
+
}
|
|
25965
|
+
function parseScanInterval(value) {
|
|
25966
|
+
const ms = parseHumanInterval(value);
|
|
25967
|
+
if (ms === null || ms < MIN_SCAN_INTERVAL_MS)
|
|
25968
|
+
return null;
|
|
25969
|
+
return ms;
|
|
25970
|
+
}
|
|
25971
|
+
function parseMinConfidence(value) {
|
|
25972
|
+
const parsed = parseFloat(value);
|
|
25973
|
+
if (Number.isNaN(parsed) || parsed < 0 || parsed > 1)
|
|
25974
|
+
return null;
|
|
25975
|
+
return parsed;
|
|
25976
|
+
}
|
|
25977
|
+
function parsePositiveNumber(value) {
|
|
25978
|
+
const parsed = parseFloat(value);
|
|
25979
|
+
if (Number.isNaN(parsed) || parsed <= 0)
|
|
25980
|
+
return null;
|
|
25981
|
+
return parsed;
|
|
25982
|
+
}
|
|
25983
|
+
function parsePositionSize(value) {
|
|
25984
|
+
const parsed = parseFloat(value);
|
|
25985
|
+
if (Number.isNaN(parsed) || parsed <= 0 || parsed > 1)
|
|
25986
|
+
return null;
|
|
25987
|
+
return parsed;
|
|
25988
|
+
}
|
|
25656
25989
|
function isUserAbort(error2) {
|
|
25657
25990
|
return error2 instanceof Error && error2.message.includes("User force closed");
|
|
25658
25991
|
}
|
|
25659
25992
|
|
|
25660
25993
|
// dist/commands/subscribe.js
|
|
25661
|
-
var
|
|
25994
|
+
var logger21 = createLogger("cli-subscribe");
|
|
25662
25995
|
var POLL_INTERVAL_MS2 = 3e3;
|
|
25663
25996
|
var POLL_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
25664
25997
|
async function createCheckoutSession(email, plan = "starter") {
|
|
@@ -25722,7 +26055,7 @@ async function pollCryptoPayment(reference, provisioningToken, onTick) {
|
|
|
25722
26055
|
return { success: false, error: "Payment expired or not found. Please try again." };
|
|
25723
26056
|
}
|
|
25724
26057
|
} catch (err) {
|
|
25725
|
-
|
|
26058
|
+
logger21.debug({ error: err }, "Crypto poll attempt failed, retrying");
|
|
25726
26059
|
}
|
|
25727
26060
|
await sleep2(CRYPTO_POLL_INTERVAL);
|
|
25728
26061
|
}
|
|
@@ -25743,7 +26076,7 @@ async function pollCryptoPayment(reference, provisioningToken, onTick) {
|
|
|
25743
26076
|
return { success: false, error: "Provisioning token expired after payment. Contact support." };
|
|
25744
26077
|
}
|
|
25745
26078
|
} catch (err) {
|
|
25746
|
-
|
|
26079
|
+
logger21.debug({ error: err }, "Provision poll attempt failed, retrying");
|
|
25747
26080
|
}
|
|
25748
26081
|
await sleep2(POLL_INTERVAL_MS2);
|
|
25749
26082
|
}
|
|
@@ -25787,7 +26120,7 @@ async function pollForApiKey(token, onTick) {
|
|
|
25787
26120
|
};
|
|
25788
26121
|
}
|
|
25789
26122
|
} catch (err) {
|
|
25790
|
-
|
|
26123
|
+
logger21.debug({ error: err }, "Poll attempt failed, retrying");
|
|
25791
26124
|
}
|
|
25792
26125
|
await sleep2(POLL_INTERVAL_MS2);
|
|
25793
26126
|
elapsed = Date.now() - start;
|
|
@@ -25828,13 +26161,13 @@ function formatSubscribeSuccess(result) {
|
|
|
25828
26161
|
lines.push(` ${source_default.bold("Plan:")} ${result.plan}`);
|
|
25829
26162
|
}
|
|
25830
26163
|
if (result.apiKey) {
|
|
25831
|
-
lines.push(` ${source_default.bold("API
|
|
26164
|
+
lines.push(` ${source_default.bold("Trading Boy API key:")} ${source_default.yellow(result.apiKey)}`);
|
|
25832
26165
|
lines.push("");
|
|
25833
|
-
lines.push(source_default.dim(" \u26A0\uFE0F Copy this key now \u2014 it will not be shown again."));
|
|
26166
|
+
lines.push(source_default.dim(" \u26A0\uFE0F Copy this Trading Boy API key now \u2014 it will not be shown again."));
|
|
25834
26167
|
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
|
|
26168
|
+
lines.push(source_default.dim(" Send /start and paste your Trading Boy API key when prompted."));
|
|
25836
26169
|
} else if (result.reusedExistingKey) {
|
|
25837
|
-
lines.push(` ${source_default.bold("API
|
|
26170
|
+
lines.push(` ${source_default.bold("Trading Boy API key:")} ${source_default.green("Your existing key remains active")}`);
|
|
25838
26171
|
lines.push("");
|
|
25839
26172
|
lines.push(source_default.dim(" No new key was issued for this upgrade."));
|
|
25840
26173
|
lines.push(source_default.dim(" If Trading Boy is already configured, no action is required."));
|
|
@@ -25844,7 +26177,7 @@ function formatSubscribeSuccess(result) {
|
|
|
25844
26177
|
}
|
|
25845
26178
|
lines.push("");
|
|
25846
26179
|
if (result.apiKey) {
|
|
25847
|
-
lines.push(source_default.dim(" Your API key has been stored locally."));
|
|
26180
|
+
lines.push(source_default.dim(" Your Trading Boy API key has been stored locally."));
|
|
25848
26181
|
lines.push(source_default.dim(" You can also view it anytime: trading-boy whoami --show-key"));
|
|
25849
26182
|
} else {
|
|
25850
26183
|
lines.push(source_default.dim(" Your stored Trading Boy credentials remain unchanged."));
|
|
@@ -25855,7 +26188,7 @@ function formatSubscribeSuccess(result) {
|
|
|
25855
26188
|
return lines.join("\n");
|
|
25856
26189
|
}
|
|
25857
26190
|
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) => {
|
|
26191
|
+
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
26192
|
const { email } = options;
|
|
25860
26193
|
let { plan, pay } = options;
|
|
25861
26194
|
if (!isValidEmail(email)) {
|
|
@@ -25923,7 +26256,7 @@ function registerSubscribeCommand(program2) {
|
|
|
25923
26256
|
return;
|
|
25924
26257
|
}
|
|
25925
26258
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
25926
|
-
|
|
26259
|
+
logger21.error({ error: message }, "Subscribe command failed");
|
|
25927
26260
|
console.error(source_default.red(` Error: ${message}`));
|
|
25928
26261
|
process.exitCode = 1;
|
|
25929
26262
|
}
|
|
@@ -26085,9 +26418,9 @@ async function storeAndDisplayKey(pollResult) {
|
|
|
26085
26418
|
} catch (err) {
|
|
26086
26419
|
console.error("");
|
|
26087
26420
|
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
|
-
|
|
26421
|
+
console.error(source_default.yellow(` Your Trading Boy API key: ${pollResult.apiKey}`));
|
|
26422
|
+
console.error(source_default.yellow(" Save this key and run: trading-boy login --api-key <trading-boy-api-key>"));
|
|
26423
|
+
logger21.error({ error: err }, "Failed to save credentials");
|
|
26091
26424
|
process.exitCode = 1;
|
|
26092
26425
|
return;
|
|
26093
26426
|
}
|
|
@@ -26152,7 +26485,7 @@ function formatConnectionError2(message) {
|
|
|
26152
26485
|
init_source();
|
|
26153
26486
|
init_credentials();
|
|
26154
26487
|
init_api_client();
|
|
26155
|
-
var
|
|
26488
|
+
var logger22 = createLogger("cli-rotate-key");
|
|
26156
26489
|
async function rotateApiKey(currentKey) {
|
|
26157
26490
|
const response = await fetch(`${getApiBase()}/api/v1/auth/rotate`, {
|
|
26158
26491
|
method: "POST",
|
|
@@ -26220,7 +26553,7 @@ function registerRotateKeyCommand(program2) {
|
|
|
26220
26553
|
return;
|
|
26221
26554
|
}
|
|
26222
26555
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
26223
|
-
|
|
26556
|
+
logger22.error({ error: message }, "rotate-key failed");
|
|
26224
26557
|
console.error(source_default.red(` Error: ${message}`));
|
|
26225
26558
|
process.exitCode = 1;
|
|
26226
26559
|
}
|
|
@@ -26231,7 +26564,7 @@ function registerRotateKeyCommand(program2) {
|
|
|
26231
26564
|
init_source();
|
|
26232
26565
|
init_credentials();
|
|
26233
26566
|
init_api_client();
|
|
26234
|
-
var
|
|
26567
|
+
var logger23 = createLogger("cli-forgot-key");
|
|
26235
26568
|
async function requestKeyRecovery(email) {
|
|
26236
26569
|
const response = await fetch(`${getApiBase()}/api/v1/auth/forgot-key`, {
|
|
26237
26570
|
method: "POST",
|
|
@@ -26327,7 +26660,7 @@ function registerForgotKeyCommand(program2) {
|
|
|
26327
26660
|
return;
|
|
26328
26661
|
}
|
|
26329
26662
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
26330
|
-
|
|
26663
|
+
logger23.error({ error: message }, "forgot-key failed");
|
|
26331
26664
|
console.error(source_default.red(` Error: ${message}`));
|
|
26332
26665
|
process.exitCode = 1;
|
|
26333
26666
|
}
|
|
@@ -26657,7 +26990,7 @@ function registerEdgeGuardCommand(program2) {
|
|
|
26657
26990
|
init_source();
|
|
26658
26991
|
init_api_client();
|
|
26659
26992
|
init_utils();
|
|
26660
|
-
var
|
|
26993
|
+
var logger24 = createLogger("cli-coaching");
|
|
26661
26994
|
var BYOK_HINT = `LLM API key required. Run: ${source_default.white("trading-boy config set-llm-key <key>")}`;
|
|
26662
26995
|
function isByokError(error2) {
|
|
26663
26996
|
if (error2 instanceof ApiError && error2.status === 422)
|
|
@@ -26752,7 +27085,7 @@ function registerCoachingCommand(program2) {
|
|
|
26752
27085
|
return;
|
|
26753
27086
|
}
|
|
26754
27087
|
const message = error2 instanceof ApiError ? error2.message : error2 instanceof Error ? error2.message : String(error2);
|
|
26755
|
-
|
|
27088
|
+
logger24.error({ error: message }, "Pre-trade coaching failed");
|
|
26756
27089
|
console.error(source_default.red(`Error: ${message}`));
|
|
26757
27090
|
process.exitCode = error2 instanceof ApiError ? 2 : 1;
|
|
26758
27091
|
}
|
|
@@ -26793,7 +27126,7 @@ function registerCoachingCommand(program2) {
|
|
|
26793
27126
|
return;
|
|
26794
27127
|
}
|
|
26795
27128
|
const message = error2 instanceof ApiError ? error2.message : error2 instanceof Error ? error2.message : String(error2);
|
|
26796
|
-
|
|
27129
|
+
logger24.error({ error: message }, "Post-trade coaching failed");
|
|
26797
27130
|
console.error(source_default.red(`Error: ${message}`));
|
|
26798
27131
|
process.exitCode = error2 instanceof ApiError ? 2 : 1;
|
|
26799
27132
|
}
|
|
@@ -26809,7 +27142,7 @@ function registerCoachingCommand(program2) {
|
|
|
26809
27142
|
console.log("");
|
|
26810
27143
|
} catch (error2) {
|
|
26811
27144
|
const message = error2 instanceof ApiError ? error2.message : error2 instanceof Error ? error2.message : String(error2);
|
|
26812
|
-
|
|
27145
|
+
logger24.error({ error: message }, "Acknowledge failed");
|
|
26813
27146
|
console.error(source_default.red(`Error: ${message}`));
|
|
26814
27147
|
process.exitCode = error2 instanceof ApiError ? 2 : 1;
|
|
26815
27148
|
}
|
|
@@ -26824,7 +27157,7 @@ function registerCoachingCommand(program2) {
|
|
|
26824
27157
|
console.log("");
|
|
26825
27158
|
} catch (error2) {
|
|
26826
27159
|
const message = error2 instanceof ApiError ? error2.message : error2 instanceof Error ? error2.message : String(error2);
|
|
26827
|
-
|
|
27160
|
+
logger24.error({ error: message }, "Reset failed");
|
|
26828
27161
|
console.error(source_default.red(`Error: ${message}`));
|
|
26829
27162
|
process.exitCode = error2 instanceof ApiError ? 2 : 1;
|
|
26830
27163
|
}
|
|
@@ -26835,7 +27168,7 @@ function registerCoachingCommand(program2) {
|
|
|
26835
27168
|
init_source();
|
|
26836
27169
|
init_api_client();
|
|
26837
27170
|
init_utils();
|
|
26838
|
-
var
|
|
27171
|
+
var logger25 = createLogger("cli-thesis");
|
|
26839
27172
|
var BYOK_HINT2 = `LLM API key required. Run: ${source_default.white("trading-boy config set-llm-key <key>")}`;
|
|
26840
27173
|
function formatThesisOutput(response) {
|
|
26841
27174
|
const lines = [];
|
|
@@ -26936,7 +27269,7 @@ function registerThesisCommand(program2) {
|
|
|
26936
27269
|
return;
|
|
26937
27270
|
}
|
|
26938
27271
|
const message = error2 instanceof ApiError ? error2.message : error2 instanceof Error ? error2.message : String(error2);
|
|
26939
|
-
|
|
27272
|
+
logger25.error({ error: message }, "Thesis extraction failed");
|
|
26940
27273
|
console.error(source_default.red(`Error: ${message}`));
|
|
26941
27274
|
process.exitCode = error2 instanceof ApiError ? 2 : 1;
|
|
26942
27275
|
}
|
|
@@ -26947,7 +27280,7 @@ function registerThesisCommand(program2) {
|
|
|
26947
27280
|
init_source();
|
|
26948
27281
|
init_api_client();
|
|
26949
27282
|
init_utils();
|
|
26950
|
-
var
|
|
27283
|
+
var logger26 = createLogger("cli-strategy");
|
|
26951
27284
|
function formatShortDate2(isoString) {
|
|
26952
27285
|
try {
|
|
26953
27286
|
return new Date(isoString).toISOString().slice(0, 16).replace("T", " ");
|
|
@@ -26955,6 +27288,9 @@ function formatShortDate2(isoString) {
|
|
|
26955
27288
|
return isoString;
|
|
26956
27289
|
}
|
|
26957
27290
|
}
|
|
27291
|
+
function normalizeStrategyTokens(tokens) {
|
|
27292
|
+
return normalizeWatchlistSymbols(tokens.split(",").map((t) => t.trim()).filter(Boolean));
|
|
27293
|
+
}
|
|
26958
27294
|
function formatStrategyDetail(s) {
|
|
26959
27295
|
const lines = [];
|
|
26960
27296
|
lines.push("");
|
|
@@ -27049,7 +27385,7 @@ function registerStrategyCommand(program2) {
|
|
|
27049
27385
|
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
27386
|
if (!await ensureRemote())
|
|
27051
27387
|
return;
|
|
27052
|
-
const tokens = options.tokens
|
|
27388
|
+
const tokens = normalizeStrategyTokens(options.tokens);
|
|
27053
27389
|
const setupTypes = options.setups ? options.setups.split(",").map((s) => s.trim().toUpperCase()).filter(Boolean) : ["BREAKOUT"];
|
|
27054
27390
|
const body = {
|
|
27055
27391
|
name: options.name,
|
|
@@ -27069,7 +27405,7 @@ function registerStrategyCommand(program2) {
|
|
|
27069
27405
|
console.log(formatStrategyDetail(result));
|
|
27070
27406
|
}
|
|
27071
27407
|
} catch (error2) {
|
|
27072
|
-
handleApiError(error2, "Strategy create failed",
|
|
27408
|
+
handleApiError(error2, "Strategy create failed", logger26);
|
|
27073
27409
|
}
|
|
27074
27410
|
});
|
|
27075
27411
|
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 +27425,7 @@ function registerStrategyCommand(program2) {
|
|
|
27089
27425
|
console.log(formatStrategyList(result));
|
|
27090
27426
|
}
|
|
27091
27427
|
} catch (error2) {
|
|
27092
|
-
handleApiError(error2, "Strategy list failed",
|
|
27428
|
+
handleApiError(error2, "Strategy list failed", logger26);
|
|
27093
27429
|
}
|
|
27094
27430
|
});
|
|
27095
27431
|
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 +27439,7 @@ function registerStrategyCommand(program2) {
|
|
|
27103
27439
|
console.log(formatStrategyDetail(result));
|
|
27104
27440
|
}
|
|
27105
27441
|
} catch (error2) {
|
|
27106
|
-
handleApiError(error2, "Strategy show failed",
|
|
27442
|
+
handleApiError(error2, "Strategy show failed", logger26);
|
|
27107
27443
|
}
|
|
27108
27444
|
});
|
|
27109
27445
|
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 +27450,7 @@ function registerStrategyCommand(program2) {
|
|
|
27114
27450
|
body.name = options.name;
|
|
27115
27451
|
}
|
|
27116
27452
|
if (options.tokens) {
|
|
27117
|
-
body.tokens = options.tokens
|
|
27453
|
+
body.tokens = normalizeStrategyTokens(options.tokens);
|
|
27118
27454
|
}
|
|
27119
27455
|
if (options.setups) {
|
|
27120
27456
|
body.setupTypes = options.setups.split(",").map((s) => s.trim().toUpperCase()).filter(Boolean);
|
|
@@ -27132,7 +27468,7 @@ function registerStrategyCommand(program2) {
|
|
|
27132
27468
|
console.log(formatStrategyDetail(result));
|
|
27133
27469
|
}
|
|
27134
27470
|
} catch (error2) {
|
|
27135
|
-
handleApiError(error2, "Strategy update failed",
|
|
27471
|
+
handleApiError(error2, "Strategy update failed", logger26);
|
|
27136
27472
|
}
|
|
27137
27473
|
});
|
|
27138
27474
|
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 +27482,7 @@ function registerStrategyCommand(program2) {
|
|
|
27146
27482
|
console.log(formatHistoryList(result));
|
|
27147
27483
|
}
|
|
27148
27484
|
} catch (error2) {
|
|
27149
|
-
handleApiError(error2, "Strategy history failed",
|
|
27485
|
+
handleApiError(error2, "Strategy history failed", logger26);
|
|
27150
27486
|
}
|
|
27151
27487
|
});
|
|
27152
27488
|
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 +27508,7 @@ function registerStrategyCommand(program2) {
|
|
|
27172
27508
|
console.log(output);
|
|
27173
27509
|
}
|
|
27174
27510
|
} catch (error2) {
|
|
27175
|
-
handleApiError(error2, "Strategy export failed",
|
|
27511
|
+
handleApiError(error2, "Strategy export failed", logger26);
|
|
27176
27512
|
}
|
|
27177
27513
|
});
|
|
27178
27514
|
}
|
|
@@ -27181,7 +27517,7 @@ function registerStrategyCommand(program2) {
|
|
|
27181
27517
|
init_source();
|
|
27182
27518
|
init_api_client();
|
|
27183
27519
|
init_utils();
|
|
27184
|
-
var
|
|
27520
|
+
var logger27 = createLogger("cli-replay");
|
|
27185
27521
|
function formatPercent2(val) {
|
|
27186
27522
|
const sign = val >= 0 ? "+" : "";
|
|
27187
27523
|
const str = `${sign}${val.toFixed(2)}%`;
|
|
@@ -27298,7 +27634,7 @@ function registerReplayCommand(program2) {
|
|
|
27298
27634
|
submitSpinner.succeed(source_default.dim(`Job submitted: ${jobId}`));
|
|
27299
27635
|
} catch (error2) {
|
|
27300
27636
|
submitSpinner.fail("Failed to submit replay job");
|
|
27301
|
-
handleApiError(error2, "Replay submit failed",
|
|
27637
|
+
handleApiError(error2, "Replay submit failed", logger27);
|
|
27302
27638
|
return;
|
|
27303
27639
|
}
|
|
27304
27640
|
const pollSpinner = (await createSpinner2("Running replay\u2026")).start();
|
|
@@ -27308,7 +27644,7 @@ function registerReplayCommand(program2) {
|
|
|
27308
27644
|
pollSpinner.stop();
|
|
27309
27645
|
} catch (error2) {
|
|
27310
27646
|
pollSpinner.fail("Replay timed out or encountered an error");
|
|
27311
|
-
handleApiError(error2, "Replay polling failed",
|
|
27647
|
+
handleApiError(error2, "Replay polling failed", logger27);
|
|
27312
27648
|
return;
|
|
27313
27649
|
}
|
|
27314
27650
|
if (!finalStatus.result) {
|
|
@@ -27480,7 +27816,7 @@ function registerBenchmarkCommand(program2) {
|
|
|
27480
27816
|
init_source();
|
|
27481
27817
|
init_api_client();
|
|
27482
27818
|
init_utils();
|
|
27483
|
-
var
|
|
27819
|
+
var logger28 = createLogger("cli-suggestions");
|
|
27484
27820
|
function formatSuggestionsList(data) {
|
|
27485
27821
|
const lines = [];
|
|
27486
27822
|
lines.push("");
|
|
@@ -27542,7 +27878,7 @@ function registerSuggestionsCommand(program2) {
|
|
|
27542
27878
|
}
|
|
27543
27879
|
} catch (error2) {
|
|
27544
27880
|
const message = error2 instanceof ApiError ? error2.message : error2 instanceof Error ? error2.message : String(error2);
|
|
27545
|
-
|
|
27881
|
+
logger28.error({ error: message }, "Failed to list suggestions");
|
|
27546
27882
|
console.error(source_default.red(`Error: ${message}`));
|
|
27547
27883
|
process.exitCode = error2 instanceof ApiError ? 2 : 1;
|
|
27548
27884
|
}
|
|
@@ -27561,7 +27897,7 @@ function registerSuggestionsCommand(program2) {
|
|
|
27561
27897
|
}
|
|
27562
27898
|
} catch (error2) {
|
|
27563
27899
|
const message = error2 instanceof ApiError ? error2.message : error2 instanceof Error ? error2.message : String(error2);
|
|
27564
|
-
|
|
27900
|
+
logger28.error({ error: message }, "Failed to approve suggestion");
|
|
27565
27901
|
console.error(source_default.red(`Error: ${message}`));
|
|
27566
27902
|
process.exitCode = error2 instanceof ApiError ? 2 : 1;
|
|
27567
27903
|
}
|
|
@@ -27580,7 +27916,7 @@ function registerSuggestionsCommand(program2) {
|
|
|
27580
27916
|
}
|
|
27581
27917
|
} catch (error2) {
|
|
27582
27918
|
const message = error2 instanceof ApiError ? error2.message : error2 instanceof Error ? error2.message : String(error2);
|
|
27583
|
-
|
|
27919
|
+
logger28.error({ error: message }, "Failed to reject suggestion");
|
|
27584
27920
|
console.error(source_default.red(`Error: ${message}`));
|
|
27585
27921
|
process.exitCode = error2 instanceof ApiError ? 2 : 1;
|
|
27586
27922
|
}
|
|
@@ -27591,7 +27927,7 @@ function registerSuggestionsCommand(program2) {
|
|
|
27591
27927
|
init_source();
|
|
27592
27928
|
init_api_client();
|
|
27593
27929
|
init_utils();
|
|
27594
|
-
var
|
|
27930
|
+
var logger29 = createLogger("cli-cron");
|
|
27595
27931
|
function formatShortDate4(isoString) {
|
|
27596
27932
|
if (!isoString)
|
|
27597
27933
|
return source_default.dim("\u2014");
|
|
@@ -27663,7 +27999,7 @@ function registerCronCommand(program2) {
|
|
|
27663
27999
|
console.log("");
|
|
27664
28000
|
}
|
|
27665
28001
|
} catch (error2) {
|
|
27666
|
-
handleApiError(error2, "Cron create failed",
|
|
28002
|
+
handleApiError(error2, "Cron create failed", logger29);
|
|
27667
28003
|
}
|
|
27668
28004
|
});
|
|
27669
28005
|
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 +28026,7 @@ function registerCronCommand(program2) {
|
|
|
27690
28026
|
console.log(source_default.dim(` ${result.count} job(s)`));
|
|
27691
28027
|
console.log("");
|
|
27692
28028
|
} catch (error2) {
|
|
27693
|
-
handleApiError(error2, "Cron list failed",
|
|
28029
|
+
handleApiError(error2, "Cron list failed", logger29);
|
|
27694
28030
|
}
|
|
27695
28031
|
});
|
|
27696
28032
|
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 +28054,7 @@ function registerCronCommand(program2) {
|
|
|
27718
28054
|
console.log(` ${source_default.gray("Created:")} ${formatShortDate4(job.createdAt)}`);
|
|
27719
28055
|
console.log("");
|
|
27720
28056
|
} catch (error2) {
|
|
27721
|
-
handleApiError(error2, "Cron show failed",
|
|
28057
|
+
handleApiError(error2, "Cron show failed", logger29);
|
|
27722
28058
|
}
|
|
27723
28059
|
});
|
|
27724
28060
|
cron.command("pause <jobId>").description("Pause a cron job").action(async (jobId) => {
|
|
@@ -27731,7 +28067,7 @@ function registerCronCommand(program2) {
|
|
|
27731
28067
|
});
|
|
27732
28068
|
console.log(source_default.green(` Job ${jobId} paused`));
|
|
27733
28069
|
} catch (error2) {
|
|
27734
|
-
handleApiError(error2, "Cron pause failed",
|
|
28070
|
+
handleApiError(error2, "Cron pause failed", logger29);
|
|
27735
28071
|
}
|
|
27736
28072
|
});
|
|
27737
28073
|
cron.command("resume <jobId>").description("Resume a paused cron job").action(async (jobId) => {
|
|
@@ -27744,7 +28080,7 @@ function registerCronCommand(program2) {
|
|
|
27744
28080
|
});
|
|
27745
28081
|
console.log(source_default.green(` Job ${jobId} resumed`));
|
|
27746
28082
|
} catch (error2) {
|
|
27747
|
-
handleApiError(error2, "Cron resume failed",
|
|
28083
|
+
handleApiError(error2, "Cron resume failed", logger29);
|
|
27748
28084
|
}
|
|
27749
28085
|
});
|
|
27750
28086
|
cron.command("delete <jobId>").description("Delete a cron job").action(async (jobId) => {
|
|
@@ -27756,7 +28092,7 @@ function registerCronCommand(program2) {
|
|
|
27756
28092
|
});
|
|
27757
28093
|
console.log(source_default.green(` Job ${jobId} deleted`));
|
|
27758
28094
|
} catch (error2) {
|
|
27759
|
-
handleApiError(error2, "Cron delete failed",
|
|
28095
|
+
handleApiError(error2, "Cron delete failed", logger29);
|
|
27760
28096
|
}
|
|
27761
28097
|
});
|
|
27762
28098
|
cron.command("run <jobId>").description("Trigger immediate execution of a cron job").action(async (jobId) => {
|
|
@@ -27768,7 +28104,7 @@ function registerCronCommand(program2) {
|
|
|
27768
28104
|
});
|
|
27769
28105
|
console.log(source_default.green(` Job ${jobId} execution triggered`));
|
|
27770
28106
|
} catch (error2) {
|
|
27771
|
-
handleApiError(error2, "Cron run failed",
|
|
28107
|
+
handleApiError(error2, "Cron run failed", logger29);
|
|
27772
28108
|
}
|
|
27773
28109
|
});
|
|
27774
28110
|
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 +28132,7 @@ function registerCronCommand(program2) {
|
|
|
27796
28132
|
console.log(source_default.dim(` ${result.count} run(s)`));
|
|
27797
28133
|
console.log("");
|
|
27798
28134
|
} catch (error2) {
|
|
27799
|
-
handleApiError(error2, "Cron history failed",
|
|
28135
|
+
handleApiError(error2, "Cron history failed", logger29);
|
|
27800
28136
|
}
|
|
27801
28137
|
});
|
|
27802
28138
|
}
|
|
@@ -27807,7 +28143,14 @@ import { resolve } from "node:path";
|
|
|
27807
28143
|
init_source();
|
|
27808
28144
|
init_api_client();
|
|
27809
28145
|
init_utils();
|
|
27810
|
-
var
|
|
28146
|
+
var logger30 = createLogger("cli-agent");
|
|
28147
|
+
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)";
|
|
28148
|
+
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)";
|
|
28149
|
+
var MIN_CONFIDENCE_HELP = "Minimum confidence threshold (0-1, so 0.70 = 70%)";
|
|
28150
|
+
var EXIT_REASONER_HELP = "Enable LLM-powered exit reasoning for open positions (hold, exit, tighten stop, or extend take profit)";
|
|
28151
|
+
var DISABLE_EXIT_REASONER_HELP = "Disable LLM-powered exit reasoning for open positions";
|
|
28152
|
+
var SHARED_SCAN_CACHE_INTERNAL_HELP = "Internal/load-test only: bypass shared scan cache for this agent";
|
|
28153
|
+
var ENABLE_SHARED_SCAN_CACHE_HELP = "Internal/load-test only: re-enable shared scan cache for this agent";
|
|
27811
28154
|
function formatShortDate5(isoString) {
|
|
27812
28155
|
if (!isoString)
|
|
27813
28156
|
return source_default.dim("\u2014");
|
|
@@ -27832,25 +28175,25 @@ function formatStatus2(status) {
|
|
|
27832
28175
|
function formatAutonomy(level) {
|
|
27833
28176
|
switch (level) {
|
|
27834
28177
|
case "OBSERVE_ONLY":
|
|
27835
|
-
return source_default.dim("
|
|
28178
|
+
return source_default.dim("Observe only");
|
|
27836
28179
|
case "SUGGEST":
|
|
27837
|
-
return source_default.blue("
|
|
28180
|
+
return source_default.blue("Suggest only");
|
|
27838
28181
|
case "AUTO_WITH_APPROVAL":
|
|
27839
|
-
return source_default.yellow("
|
|
28182
|
+
return source_default.yellow("Auto with approval");
|
|
27840
28183
|
case "FULLY_AUTONOMOUS":
|
|
27841
|
-
return source_default.red("
|
|
28184
|
+
return source_default.red("Fully auto");
|
|
27842
28185
|
default:
|
|
27843
28186
|
return level;
|
|
27844
28187
|
}
|
|
27845
28188
|
}
|
|
27846
|
-
function
|
|
28189
|
+
function formatInterval2(ms) {
|
|
27847
28190
|
if (ms < 6e4)
|
|
27848
28191
|
return `${(ms / 1e3).toFixed(0)}s`;
|
|
27849
28192
|
if (ms < 36e5)
|
|
27850
28193
|
return `${(ms / 6e4).toFixed(0)}m`;
|
|
27851
28194
|
return `${(ms / 36e5).toFixed(1)}h`;
|
|
27852
28195
|
}
|
|
27853
|
-
function
|
|
28196
|
+
function parseHumanInterval2(value) {
|
|
27854
28197
|
const match = value.trim().match(/^(\d+(?:\.\d+)?)\s*(s|m|h)$/i);
|
|
27855
28198
|
if (!match)
|
|
27856
28199
|
return null;
|
|
@@ -27867,10 +28210,10 @@ function parseHumanInterval(value) {
|
|
|
27867
28210
|
return null;
|
|
27868
28211
|
}
|
|
27869
28212
|
}
|
|
27870
|
-
var
|
|
28213
|
+
var MIN_SCAN_INTERVAL_MS2 = 6e4;
|
|
27871
28214
|
function registerAgentCommand(program2) {
|
|
27872
28215
|
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>",
|
|
28216
|
+
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
28217
|
if (!await ensureRemote())
|
|
27875
28218
|
return;
|
|
27876
28219
|
if (!options.traderId) {
|
|
@@ -27889,14 +28232,14 @@ function registerAgentCommand(program2) {
|
|
|
27889
28232
|
if (options.autonomy)
|
|
27890
28233
|
body.autonomyLevel = options.autonomy;
|
|
27891
28234
|
if (options.scanIntervalHuman) {
|
|
27892
|
-
const ms =
|
|
28235
|
+
const ms = parseHumanInterval2(options.scanIntervalHuman);
|
|
27893
28236
|
if (ms === null) {
|
|
27894
28237
|
console.error(source_default.red(`Error: Invalid duration "${options.scanIntervalHuman}". Use format like 1m, 5m, 15m, 30m, 1h.`));
|
|
27895
28238
|
process.exitCode = 1;
|
|
27896
28239
|
return;
|
|
27897
28240
|
}
|
|
27898
|
-
if (ms <
|
|
27899
|
-
console.error(source_default.red(`Error: Scan interval must be at least 1m (60000ms). Got ${
|
|
28241
|
+
if (ms < MIN_SCAN_INTERVAL_MS2) {
|
|
28242
|
+
console.error(source_default.red(`Error: Scan interval must be at least 1m (60000ms). Got ${formatInterval2(ms)}.`));
|
|
27900
28243
|
process.exitCode = 1;
|
|
27901
28244
|
return;
|
|
27902
28245
|
}
|
|
@@ -27905,7 +28248,7 @@ function registerAgentCommand(program2) {
|
|
|
27905
28248
|
body.scanIntervalMs = parseInt(options.scanInterval, 10);
|
|
27906
28249
|
}
|
|
27907
28250
|
if (options.watchlist)
|
|
27908
|
-
body.watchlist = options.watchlist.split(",")
|
|
28251
|
+
body.watchlist = normalizeWatchlistSymbols(options.watchlist.split(","));
|
|
27909
28252
|
if (options.maxDailyTrades)
|
|
27910
28253
|
body.maxDailyTrades = parseInt(options.maxDailyTrades, 10);
|
|
27911
28254
|
if (options.maxDailyLoss)
|
|
@@ -27920,6 +28263,8 @@ function registerAgentCommand(program2) {
|
|
|
27920
28263
|
body.analyzeModel = options.analyzeModel;
|
|
27921
28264
|
if (options.decideModel)
|
|
27922
28265
|
body.decideModel = options.decideModel;
|
|
28266
|
+
if (options.disableSharedScanCache)
|
|
28267
|
+
body.disableSharedScanCache = true;
|
|
27923
28268
|
if (options.assetClass)
|
|
27924
28269
|
body.assetClass = options.assetClass;
|
|
27925
28270
|
if (options.exitReasoner)
|
|
@@ -27961,12 +28306,13 @@ function registerAgentCommand(program2) {
|
|
|
27961
28306
|
console.log(` ${source_default.gray("Trader:")} ${result.traderId}`);
|
|
27962
28307
|
console.log(` ${source_default.gray("Strategy:")} ${result.strategyId}${result.autoStrategyCreated ? source_default.dim(" (auto-created)") : ""}`);
|
|
27963
28308
|
console.log(` ${source_default.gray("Autonomy:")} ${formatAutonomy(result.autonomyLevel)}`);
|
|
27964
|
-
console.log(` ${source_default.gray("
|
|
28309
|
+
console.log(` ${source_default.gray("Exit reasoner:")} ${result.exitReasonerEnabled ? source_default.green("enabled") : source_default.dim("disabled")}`);
|
|
28310
|
+
console.log(` ${source_default.gray("Interval:")} ${formatInterval2(result.scanIntervalMs)}`);
|
|
27965
28311
|
console.log(` ${source_default.gray("Next scan:")} ${formatShortDate5(result.nextScanAt)}`);
|
|
27966
28312
|
console.log("");
|
|
27967
28313
|
}
|
|
27968
28314
|
} catch (error2) {
|
|
27969
|
-
handleApiError(error2, "Agent create failed",
|
|
28315
|
+
handleApiError(error2, "Agent create failed", logger30);
|
|
27970
28316
|
}
|
|
27971
28317
|
});
|
|
27972
28318
|
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 +28336,16 @@ function registerAgentCommand(program2) {
|
|
|
27990
28336
|
return;
|
|
27991
28337
|
}
|
|
27992
28338
|
console.log("");
|
|
27993
|
-
console.log(" " + padRight("Name", 24) + padRight("Autonomy",
|
|
27994
|
-
console.log(source_default.gray(" " + "\u2500".repeat(
|
|
28339
|
+
console.log(" " + padRight("Name", 24) + padRight("Autonomy", 22) + padRight("Interval", 10) + padRight("Status", 10) + padRight("Ticks", 7) + padRight("Errors", 8) + "Next Scan");
|
|
28340
|
+
console.log(source_default.gray(" " + "\u2500".repeat(108)));
|
|
27995
28341
|
for (const a of result.agents) {
|
|
27996
|
-
console.log(" " + padRight(a.name.slice(0, 22), 24) + padRight(formatAutonomy(a.autonomyLevel),
|
|
28342
|
+
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
28343
|
}
|
|
27998
28344
|
console.log("");
|
|
27999
28345
|
console.log(source_default.dim(` ${result.count} agent(s)`));
|
|
28000
28346
|
console.log("");
|
|
28001
28347
|
} catch (error2) {
|
|
28002
|
-
handleApiError(error2, "Agent list failed",
|
|
28348
|
+
handleApiError(error2, "Agent list failed", logger30);
|
|
28003
28349
|
}
|
|
28004
28350
|
});
|
|
28005
28351
|
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 +28375,9 @@ function registerAgentCommand(program2) {
|
|
|
28029
28375
|
console.log(` ${source_default.gray("Analyze model:")} ${a.analyzeModel}`);
|
|
28030
28376
|
if (a.decideModel)
|
|
28031
28377
|
console.log(` ${source_default.gray("Decide model:")} ${a.decideModel}`);
|
|
28032
|
-
console.log(` ${source_default.gray("
|
|
28378
|
+
console.log(` ${source_default.gray("Shared scan cache:")} ${a.disableSharedScanCache ? source_default.yellow("bypassed") : source_default.dim("enabled")}`);
|
|
28379
|
+
console.log(` ${source_default.gray("Exit reasoner:")} ${a.exitReasonerEnabled ? source_default.green("enabled") : source_default.dim("disabled")}`);
|
|
28380
|
+
console.log(` ${source_default.gray("Scan interval:")} ${formatInterval2(a.scanIntervalMs)}`);
|
|
28033
28381
|
console.log(` ${source_default.gray("Max daily trades:")} ${a.maxDailyTrades}`);
|
|
28034
28382
|
console.log(` ${source_default.gray("Max daily loss:")} $${a.maxDailyLossUsd}`);
|
|
28035
28383
|
console.log(` ${source_default.gray("Max position:")} ${(a.maxPositionSizePct * 100).toFixed(0)}%`);
|
|
@@ -28072,7 +28420,7 @@ function registerAgentCommand(program2) {
|
|
|
28072
28420
|
}
|
|
28073
28421
|
console.log("");
|
|
28074
28422
|
} catch (error2) {
|
|
28075
|
-
handleApiError(error2, "Agent show failed",
|
|
28423
|
+
handleApiError(error2, "Agent show failed", logger30);
|
|
28076
28424
|
}
|
|
28077
28425
|
});
|
|
28078
28426
|
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 +28436,7 @@ function registerAgentCommand(program2) {
|
|
|
28088
28436
|
console.log(source_default.green(` Agent ${agentId} paused`));
|
|
28089
28437
|
}
|
|
28090
28438
|
} catch (error2) {
|
|
28091
|
-
handleApiError(error2, "Agent pause failed",
|
|
28439
|
+
handleApiError(error2, "Agent pause failed", logger30);
|
|
28092
28440
|
}
|
|
28093
28441
|
});
|
|
28094
28442
|
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 +28452,7 @@ function registerAgentCommand(program2) {
|
|
|
28104
28452
|
console.log(source_default.green(` Agent ${agentId} resumed`));
|
|
28105
28453
|
}
|
|
28106
28454
|
} catch (error2) {
|
|
28107
|
-
handleApiError(error2, "Agent resume failed",
|
|
28455
|
+
handleApiError(error2, "Agent resume failed", logger30);
|
|
28108
28456
|
}
|
|
28109
28457
|
});
|
|
28110
28458
|
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 +28468,7 @@ function registerAgentCommand(program2) {
|
|
|
28120
28468
|
console.log(source_default.green(` Agent ${agentId} deleted`));
|
|
28121
28469
|
}
|
|
28122
28470
|
} catch (error2) {
|
|
28123
|
-
handleApiError(error2, "Agent delete failed",
|
|
28471
|
+
handleApiError(error2, "Agent delete failed", logger30);
|
|
28124
28472
|
}
|
|
28125
28473
|
});
|
|
28126
28474
|
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 +28497,26 @@ function registerAgentCommand(program2) {
|
|
|
28149
28497
|
console.log("");
|
|
28150
28498
|
}
|
|
28151
28499
|
} catch (error2) {
|
|
28152
|
-
handleApiError(error2, "Position exit failed",
|
|
28500
|
+
handleApiError(error2, "Position exit failed", logger30);
|
|
28153
28501
|
}
|
|
28154
28502
|
});
|
|
28155
|
-
agent.command("update <agentId>").description("Update agent config").option("--name <name>", "Agent name").option("--autonomy <level>",
|
|
28503
|
+
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
28504
|
if (!await ensureRemote())
|
|
28157
28505
|
return;
|
|
28158
28506
|
const body = {};
|
|
28159
28507
|
if (options.name)
|
|
28160
28508
|
body.name = options.name;
|
|
28161
|
-
if (options.exitReasoner)
|
|
28162
|
-
body.exitReasonerEnabled = true;
|
|
28163
28509
|
if (options.autonomy)
|
|
28164
28510
|
body.autonomyLevel = options.autonomy;
|
|
28165
28511
|
if (options.scanIntervalHuman) {
|
|
28166
|
-
const ms =
|
|
28512
|
+
const ms = parseHumanInterval2(options.scanIntervalHuman);
|
|
28167
28513
|
if (ms === null) {
|
|
28168
28514
|
console.error(source_default.red(`Error: Invalid duration "${options.scanIntervalHuman}". Use format like 1m, 5m, 15m, 30m, 1h.`));
|
|
28169
28515
|
process.exitCode = 1;
|
|
28170
28516
|
return;
|
|
28171
28517
|
}
|
|
28172
|
-
if (ms <
|
|
28173
|
-
console.error(source_default.red(`Error: Scan interval must be at least 1m (60000ms). Got ${
|
|
28518
|
+
if (ms < MIN_SCAN_INTERVAL_MS2) {
|
|
28519
|
+
console.error(source_default.red(`Error: Scan interval must be at least 1m (60000ms). Got ${formatInterval2(ms)}.`));
|
|
28174
28520
|
process.exitCode = 1;
|
|
28175
28521
|
return;
|
|
28176
28522
|
}
|
|
@@ -28179,7 +28525,7 @@ function registerAgentCommand(program2) {
|
|
|
28179
28525
|
body.scanIntervalMs = parseInt(options.scanInterval, 10);
|
|
28180
28526
|
}
|
|
28181
28527
|
if (options.watchlist)
|
|
28182
|
-
body.watchlist = options.watchlist.split(",")
|
|
28528
|
+
body.watchlist = normalizeWatchlistSymbols(options.watchlist.split(","));
|
|
28183
28529
|
if (options.maxDailyTrades)
|
|
28184
28530
|
body.maxDailyTrades = parseInt(options.maxDailyTrades, 10);
|
|
28185
28531
|
if (options.maxDailyLoss)
|
|
@@ -28194,6 +28540,24 @@ function registerAgentCommand(program2) {
|
|
|
28194
28540
|
body.analyzeModel = options.analyzeModel;
|
|
28195
28541
|
if (options.decideModel)
|
|
28196
28542
|
body.decideModel = options.decideModel;
|
|
28543
|
+
if (options.disableSharedScanCache && options.enableSharedScanCache) {
|
|
28544
|
+
console.error(source_default.red("Error: Choose either --disable-shared-scan-cache or --enable-shared-scan-cache."));
|
|
28545
|
+
process.exitCode = 1;
|
|
28546
|
+
return;
|
|
28547
|
+
}
|
|
28548
|
+
if (options.exitReasoner && options.disableExitReasoner) {
|
|
28549
|
+
console.error(source_default.red("Error: Choose either --exit-reasoner or --disable-exit-reasoner."));
|
|
28550
|
+
process.exitCode = 1;
|
|
28551
|
+
return;
|
|
28552
|
+
}
|
|
28553
|
+
if (options.disableSharedScanCache)
|
|
28554
|
+
body.disableSharedScanCache = true;
|
|
28555
|
+
if (options.enableSharedScanCache)
|
|
28556
|
+
body.disableSharedScanCache = false;
|
|
28557
|
+
if (options.exitReasoner)
|
|
28558
|
+
body.exitReasonerEnabled = true;
|
|
28559
|
+
if (options.disableExitReasoner)
|
|
28560
|
+
body.exitReasonerEnabled = false;
|
|
28197
28561
|
if (options.assetClass)
|
|
28198
28562
|
body.assetClass = options.assetClass;
|
|
28199
28563
|
if (options.soulFile) {
|
|
@@ -28234,7 +28598,7 @@ function registerAgentCommand(program2) {
|
|
|
28234
28598
|
console.log(source_default.green(` Agent ${agentId} updated`));
|
|
28235
28599
|
}
|
|
28236
28600
|
} catch (error2) {
|
|
28237
|
-
handleApiError(error2, "Agent update failed",
|
|
28601
|
+
handleApiError(error2, "Agent update failed", logger30);
|
|
28238
28602
|
}
|
|
28239
28603
|
});
|
|
28240
28604
|
}
|