@trading-boy/cli 1.11.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.bundle.js +135 -373
- package/dist/cli.js +2 -2
- package/dist/commands/agent-cmd.js +4 -9
- package/dist/commands/onboarding.js +2 -19
- package/dist/commands/strategy-cmd.js +2 -7
- package/package.json +1 -1
package/dist/cli.bundle.js
CHANGED
|
@@ -20186,7 +20186,7 @@ var require_atomic_sleep = __commonJS({
|
|
|
20186
20186
|
"../../node_modules/.pnpm/atomic-sleep@1.0.0/node_modules/atomic-sleep/index.js"(exports, module) {
|
|
20187
20187
|
"use strict";
|
|
20188
20188
|
if (typeof SharedArrayBuffer !== "undefined" && typeof Atomics !== "undefined") {
|
|
20189
|
-
let
|
|
20189
|
+
let sleep5 = function(ms) {
|
|
20190
20190
|
const valid = ms > 0 && ms < Infinity;
|
|
20191
20191
|
if (valid === false) {
|
|
20192
20192
|
if (typeof ms !== "number" && typeof ms !== "bigint") {
|
|
@@ -20197,9 +20197,9 @@ var require_atomic_sleep = __commonJS({
|
|
|
20197
20197
|
Atomics.wait(nil, 0, 0, Number(ms));
|
|
20198
20198
|
};
|
|
20199
20199
|
const nil = new Int32Array(new SharedArrayBuffer(4));
|
|
20200
|
-
module.exports =
|
|
20200
|
+
module.exports = sleep5;
|
|
20201
20201
|
} else {
|
|
20202
|
-
let
|
|
20202
|
+
let sleep5 = function(ms) {
|
|
20203
20203
|
const valid = ms > 0 && ms < Infinity;
|
|
20204
20204
|
if (valid === false) {
|
|
20205
20205
|
if (typeof ms !== "number" && typeof ms !== "bigint") {
|
|
@@ -20211,7 +20211,7 @@ var require_atomic_sleep = __commonJS({
|
|
|
20211
20211
|
while (target > Date.now()) {
|
|
20212
20212
|
}
|
|
20213
20213
|
};
|
|
20214
|
-
module.exports =
|
|
20214
|
+
module.exports = sleep5;
|
|
20215
20215
|
}
|
|
20216
20216
|
}
|
|
20217
20217
|
});
|
|
@@ -20224,7 +20224,7 @@ var require_sonic_boom = __commonJS({
|
|
|
20224
20224
|
var EventEmitter = __require("events");
|
|
20225
20225
|
var inherits = __require("util").inherits;
|
|
20226
20226
|
var path5 = __require("path");
|
|
20227
|
-
var
|
|
20227
|
+
var sleep5 = require_atomic_sleep();
|
|
20228
20228
|
var assert2 = __require("assert");
|
|
20229
20229
|
var BUSY_WRITE_TIMEOUT = 100;
|
|
20230
20230
|
var kEmptyBuffer = Buffer.allocUnsafe(0);
|
|
@@ -20370,7 +20370,7 @@ var require_sonic_boom = __commonJS({
|
|
|
20370
20370
|
if ((err.code === "EAGAIN" || err.code === "EBUSY") && this.retryEAGAIN(err, this._writingBuf.length, this._len - this._writingBuf.length)) {
|
|
20371
20371
|
if (this.sync) {
|
|
20372
20372
|
try {
|
|
20373
|
-
|
|
20373
|
+
sleep5(BUSY_WRITE_TIMEOUT);
|
|
20374
20374
|
this.release(void 0, 0);
|
|
20375
20375
|
} catch (err2) {
|
|
20376
20376
|
this.release(err2);
|
|
@@ -20683,7 +20683,7 @@ var require_sonic_boom = __commonJS({
|
|
|
20683
20683
|
if (shouldRetry && !this.retryEAGAIN(err, buf.length, this._len - buf.length)) {
|
|
20684
20684
|
throw err;
|
|
20685
20685
|
}
|
|
20686
|
-
|
|
20686
|
+
sleep5(BUSY_WRITE_TIMEOUT);
|
|
20687
20687
|
}
|
|
20688
20688
|
}
|
|
20689
20689
|
try {
|
|
@@ -20720,7 +20720,7 @@ var require_sonic_boom = __commonJS({
|
|
|
20720
20720
|
if (shouldRetry && !this.retryEAGAIN(err, buf.length, this._len - buf.length)) {
|
|
20721
20721
|
throw err;
|
|
20722
20722
|
}
|
|
20723
|
-
|
|
20723
|
+
sleep5(BUSY_WRITE_TIMEOUT);
|
|
20724
20724
|
}
|
|
20725
20725
|
}
|
|
20726
20726
|
}
|
|
@@ -21457,7 +21457,7 @@ var require_transport = __commonJS({
|
|
|
21457
21457
|
var getCallers = require_caller();
|
|
21458
21458
|
var { join: join2, isAbsolute, sep } = __require("node:path");
|
|
21459
21459
|
var { fileURLToPath: fileURLToPath3 } = __require("node:url");
|
|
21460
|
-
var
|
|
21460
|
+
var sleep5 = require_atomic_sleep();
|
|
21461
21461
|
var onExit2 = require_on_exit_leak_free();
|
|
21462
21462
|
var ThreadStream = require_thread_stream();
|
|
21463
21463
|
function setupOnExit(stream) {
|
|
@@ -21580,7 +21580,7 @@ var require_transport = __commonJS({
|
|
|
21580
21580
|
return;
|
|
21581
21581
|
}
|
|
21582
21582
|
stream.flushSync();
|
|
21583
|
-
|
|
21583
|
+
sleep5(100);
|
|
21584
21584
|
stream.end();
|
|
21585
21585
|
}
|
|
21586
21586
|
return stream;
|
|
@@ -24521,30 +24521,30 @@ var init_line = __esm({
|
|
|
24521
24521
|
// ../../node_modules/.pnpm/openai@6.27.0_ws@8.19.0_bufferutil@4.1.0_utf-8-validate@6.0.6__zod@4.3.6/node_modules/openai/internal/utils/log.mjs
|
|
24522
24522
|
function noop() {
|
|
24523
24523
|
}
|
|
24524
|
-
function makeLogFn(fnLevel,
|
|
24525
|
-
if (!
|
|
24524
|
+
function makeLogFn(fnLevel, logger32, logLevel) {
|
|
24525
|
+
if (!logger32 || levelNumbers[fnLevel] > levelNumbers[logLevel]) {
|
|
24526
24526
|
return noop;
|
|
24527
24527
|
} else {
|
|
24528
|
-
return
|
|
24528
|
+
return logger32[fnLevel].bind(logger32);
|
|
24529
24529
|
}
|
|
24530
24530
|
}
|
|
24531
24531
|
function loggerFor(client) {
|
|
24532
|
-
const
|
|
24532
|
+
const logger32 = client.logger;
|
|
24533
24533
|
const logLevel = client.logLevel ?? "off";
|
|
24534
|
-
if (!
|
|
24534
|
+
if (!logger32) {
|
|
24535
24535
|
return noopLogger;
|
|
24536
24536
|
}
|
|
24537
|
-
const cachedLogger = cachedLoggers.get(
|
|
24537
|
+
const cachedLogger = cachedLoggers.get(logger32);
|
|
24538
24538
|
if (cachedLogger && cachedLogger[0] === logLevel) {
|
|
24539
24539
|
return cachedLogger[1];
|
|
24540
24540
|
}
|
|
24541
24541
|
const levelLogger = {
|
|
24542
|
-
error: makeLogFn("error",
|
|
24543
|
-
warn: makeLogFn("warn",
|
|
24544
|
-
info: makeLogFn("info",
|
|
24545
|
-
debug: makeLogFn("debug",
|
|
24542
|
+
error: makeLogFn("error", logger32, logLevel),
|
|
24543
|
+
warn: makeLogFn("warn", logger32, logLevel),
|
|
24544
|
+
info: makeLogFn("info", logger32, logLevel),
|
|
24545
|
+
debug: makeLogFn("debug", logger32, logLevel)
|
|
24546
24546
|
};
|
|
24547
|
-
cachedLoggers.set(
|
|
24547
|
+
cachedLoggers.set(logger32, [logLevel, levelLogger]);
|
|
24548
24548
|
return levelLogger;
|
|
24549
24549
|
}
|
|
24550
24550
|
var levelNumbers, parseLogLevel, noopLogger, cachedLoggers, formatRequestDetails;
|
|
@@ -24671,7 +24671,7 @@ var init_streaming = __esm({
|
|
|
24671
24671
|
}
|
|
24672
24672
|
static fromSSEResponse(response, controller, client, synthesizeEventData) {
|
|
24673
24673
|
let consumed = false;
|
|
24674
|
-
const
|
|
24674
|
+
const logger32 = client ? loggerFor(client) : console;
|
|
24675
24675
|
async function* iterator() {
|
|
24676
24676
|
if (consumed) {
|
|
24677
24677
|
throw new OpenAIError("Cannot iterate over a consumed stream, use `.tee()` to split the stream.");
|
|
@@ -24691,8 +24691,8 @@ var init_streaming = __esm({
|
|
|
24691
24691
|
try {
|
|
24692
24692
|
data = JSON.parse(sse.data);
|
|
24693
24693
|
} catch (e) {
|
|
24694
|
-
|
|
24695
|
-
|
|
24694
|
+
logger32.error(`Could not parse message into JSON:`, sse.data);
|
|
24695
|
+
logger32.error(`From chunk:`, sse.raw);
|
|
24696
24696
|
throw e;
|
|
24697
24697
|
}
|
|
24698
24698
|
if (data && data.error) {
|
|
@@ -31632,30 +31632,30 @@ var init_sleep2 = __esm({
|
|
|
31632
31632
|
// ../../node_modules/.pnpm/@anthropic-ai+sdk@0.52.0/node_modules/@anthropic-ai/sdk/internal/utils/log.mjs
|
|
31633
31633
|
function noop2() {
|
|
31634
31634
|
}
|
|
31635
|
-
function makeLogFn2(fnLevel,
|
|
31636
|
-
if (!
|
|
31635
|
+
function makeLogFn2(fnLevel, logger32, logLevel) {
|
|
31636
|
+
if (!logger32 || levelNumbers2[fnLevel] > levelNumbers2[logLevel]) {
|
|
31637
31637
|
return noop2;
|
|
31638
31638
|
} else {
|
|
31639
|
-
return
|
|
31639
|
+
return logger32[fnLevel].bind(logger32);
|
|
31640
31640
|
}
|
|
31641
31641
|
}
|
|
31642
31642
|
function loggerFor2(client) {
|
|
31643
|
-
const
|
|
31643
|
+
const logger32 = client.logger;
|
|
31644
31644
|
const logLevel = client.logLevel ?? "off";
|
|
31645
|
-
if (!
|
|
31645
|
+
if (!logger32) {
|
|
31646
31646
|
return noopLogger2;
|
|
31647
31647
|
}
|
|
31648
|
-
const cachedLogger = cachedLoggers2.get(
|
|
31648
|
+
const cachedLogger = cachedLoggers2.get(logger32);
|
|
31649
31649
|
if (cachedLogger && cachedLogger[0] === logLevel) {
|
|
31650
31650
|
return cachedLogger[1];
|
|
31651
31651
|
}
|
|
31652
31652
|
const levelLogger = {
|
|
31653
|
-
error: makeLogFn2("error",
|
|
31654
|
-
warn: makeLogFn2("warn",
|
|
31655
|
-
info: makeLogFn2("info",
|
|
31656
|
-
debug: makeLogFn2("debug",
|
|
31653
|
+
error: makeLogFn2("error", logger32, logLevel),
|
|
31654
|
+
warn: makeLogFn2("warn", logger32, logLevel),
|
|
31655
|
+
info: makeLogFn2("info", logger32, logLevel),
|
|
31656
|
+
debug: makeLogFn2("debug", logger32, logLevel)
|
|
31657
31657
|
};
|
|
31658
|
-
cachedLoggers2.set(
|
|
31658
|
+
cachedLoggers2.set(logger32, [logLevel, levelLogger]);
|
|
31659
31659
|
return levelLogger;
|
|
31660
31660
|
}
|
|
31661
31661
|
var levelNumbers2, parseLogLevel2, noopLogger2, cachedLoggers2, formatRequestDetails2;
|
|
@@ -35669,6 +35669,41 @@ var init_llm = __esm({
|
|
|
35669
35669
|
}
|
|
35670
35670
|
});
|
|
35671
35671
|
|
|
35672
|
+
// ../core/dist/strategy-utils.js
|
|
35673
|
+
function generateRegimeBehavior(setupTypes = ["BREAKOUT", "MOMENTUM", "MEAN-REVERSION", "CATALYST"]) {
|
|
35674
|
+
return {
|
|
35675
|
+
MARKUP: {
|
|
35676
|
+
enabled: true,
|
|
35677
|
+
maxPositionSize: 0.5,
|
|
35678
|
+
confidenceThreshold: 0,
|
|
35679
|
+
preferredSetups: setupTypes
|
|
35680
|
+
},
|
|
35681
|
+
ACCUMULATION: {
|
|
35682
|
+
enabled: true,
|
|
35683
|
+
maxPositionSize: 0.25,
|
|
35684
|
+
confidenceThreshold: 0,
|
|
35685
|
+
preferredSetups: setupTypes
|
|
35686
|
+
},
|
|
35687
|
+
DISTRIBUTION: {
|
|
35688
|
+
enabled: true,
|
|
35689
|
+
maxPositionSize: 0.15,
|
|
35690
|
+
confidenceThreshold: 0,
|
|
35691
|
+
preferredSetups: setupTypes
|
|
35692
|
+
},
|
|
35693
|
+
MARKDOWN: {
|
|
35694
|
+
enabled: true,
|
|
35695
|
+
maxPositionSize: 0.1,
|
|
35696
|
+
confidenceThreshold: 0,
|
|
35697
|
+
preferredSetups: setupTypes
|
|
35698
|
+
}
|
|
35699
|
+
};
|
|
35700
|
+
}
|
|
35701
|
+
var init_strategy_utils = __esm({
|
|
35702
|
+
"../core/dist/strategy-utils.js"() {
|
|
35703
|
+
"use strict";
|
|
35704
|
+
}
|
|
35705
|
+
});
|
|
35706
|
+
|
|
35672
35707
|
// ../core/dist/index.js
|
|
35673
35708
|
var init_dist2 = __esm({
|
|
35674
35709
|
"../core/dist/index.js"() {
|
|
@@ -35688,6 +35723,7 @@ var init_dist2 = __esm({
|
|
|
35688
35723
|
init_errors3();
|
|
35689
35724
|
init_crypto();
|
|
35690
35725
|
init_llm();
|
|
35726
|
+
init_strategy_utils();
|
|
35691
35727
|
}
|
|
35692
35728
|
});
|
|
35693
35729
|
|
|
@@ -39040,7 +39076,7 @@ function parseIntOption(value) {
|
|
|
39040
39076
|
function isApiError(error49) {
|
|
39041
39077
|
return error49 instanceof Error && error49.name === "ApiError" && "status" in error49;
|
|
39042
39078
|
}
|
|
39043
|
-
function handleApiError(error49, context,
|
|
39079
|
+
function handleApiError(error49, context, logger32) {
|
|
39044
39080
|
if (isApiError(error49)) {
|
|
39045
39081
|
switch (error49.status) {
|
|
39046
39082
|
case 401:
|
|
@@ -39063,7 +39099,7 @@ function handleApiError(error49, context, logger33) {
|
|
|
39063
39099
|
}
|
|
39064
39100
|
} else {
|
|
39065
39101
|
const message = error49 instanceof Error ? error49.message : String(error49);
|
|
39066
|
-
|
|
39102
|
+
logger32.error({ error: message }, context);
|
|
39067
39103
|
console.error(source_default.red(`Error: ${message}`));
|
|
39068
39104
|
}
|
|
39069
39105
|
process.exitCode = isApiError(error49) ? 2 : 1;
|
|
@@ -57322,255 +57358,6 @@ async function openBrowser(url2) {
|
|
|
57322
57358
|
}
|
|
57323
57359
|
}
|
|
57324
57360
|
|
|
57325
|
-
// dist/commands/connect-claude.js
|
|
57326
|
-
init_source();
|
|
57327
|
-
init_dist2();
|
|
57328
|
-
init_api_client();
|
|
57329
|
-
init_utils3();
|
|
57330
|
-
import http2 from "node:http";
|
|
57331
|
-
import { URL as URL3 } from "node:url";
|
|
57332
|
-
var logger24 = createLogger("cli-connect-claude");
|
|
57333
|
-
var CALLBACK_PORT2 = 1456;
|
|
57334
|
-
var CALLBACK_PATH2 = "/callback";
|
|
57335
|
-
var AUTH_TIMEOUT_MS2 = 3 * 60 * 1e3;
|
|
57336
|
-
var POLL_INTERVAL_MS2 = 2e3;
|
|
57337
|
-
function registerConnectClaudeCommand(program2) {
|
|
57338
|
-
program2.command("connect-claude").description("Connect your Claude subscription as your LLM provider (no API key needed)").option("--disconnect", "Disconnect your Claude account").action(async (options) => {
|
|
57339
|
-
try {
|
|
57340
|
-
if (!await isRemoteMode()) {
|
|
57341
|
-
console.error(source_default.yellow(" Requires API connection. Run: trading-boy login"));
|
|
57342
|
-
process.exitCode = 1;
|
|
57343
|
-
return;
|
|
57344
|
-
}
|
|
57345
|
-
if (options.disconnect) {
|
|
57346
|
-
await handleDisconnect2();
|
|
57347
|
-
} else {
|
|
57348
|
-
await handleConnect2();
|
|
57349
|
-
}
|
|
57350
|
-
} catch (error49) {
|
|
57351
|
-
const msg = error49 instanceof Error ? error49.message : String(error49);
|
|
57352
|
-
logger24.error({ error: msg }, "connect-claude failed");
|
|
57353
|
-
const connHelp = formatConnectionError(msg);
|
|
57354
|
-
if (connHelp) {
|
|
57355
|
-
console.error(source_default.red(`
|
|
57356
|
-
Connection failed.
|
|
57357
|
-
`));
|
|
57358
|
-
console.error(connHelp);
|
|
57359
|
-
} else {
|
|
57360
|
-
console.error(source_default.red(`
|
|
57361
|
-
Error: ${msg}`));
|
|
57362
|
-
}
|
|
57363
|
-
process.exitCode = error49 instanceof ApiError ? 2 : 1;
|
|
57364
|
-
}
|
|
57365
|
-
});
|
|
57366
|
-
}
|
|
57367
|
-
async function handleConnect2() {
|
|
57368
|
-
try {
|
|
57369
|
-
const current = await apiRequest("/api/v1/llm-config");
|
|
57370
|
-
if (current.anthropicOAuthConnected) {
|
|
57371
|
-
console.log("");
|
|
57372
|
-
console.log(source_default.green(" \u2713 Claude is already connected"));
|
|
57373
|
-
console.log(source_default.dim(` Provider: anthropic / ${current.model}`));
|
|
57374
|
-
console.log("");
|
|
57375
|
-
console.log(source_default.dim(" To disconnect: trading-boy connect-claude --disconnect"));
|
|
57376
|
-
return;
|
|
57377
|
-
}
|
|
57378
|
-
} catch {
|
|
57379
|
-
}
|
|
57380
|
-
console.log("");
|
|
57381
|
-
console.log(source_default.bold.cyan(" Connect Claude"));
|
|
57382
|
-
console.log(source_default.gray(" " + "\u2500".repeat(50)));
|
|
57383
|
-
console.log(source_default.dim(" Use your Claude subscription to power your trading agents."));
|
|
57384
|
-
console.log(source_default.dim(" No API key needed \u2014 authenticates via your Anthropic account."));
|
|
57385
|
-
console.log("");
|
|
57386
|
-
const { authUrl, state } = await apiRequest("/api/v1/anthropic-oauth/auth-url");
|
|
57387
|
-
const result = await raceForAuth2(authUrl, state);
|
|
57388
|
-
if (result.via === "local") {
|
|
57389
|
-
console.log(source_default.dim(" Exchanging authorization code..."));
|
|
57390
|
-
await apiRequest("/api/v1/anthropic-oauth/callback", {
|
|
57391
|
-
method: "POST",
|
|
57392
|
-
body: { code: result.code, state: result.state }
|
|
57393
|
-
});
|
|
57394
|
-
printSuccess2(null);
|
|
57395
|
-
} else {
|
|
57396
|
-
printSuccess2(result.config.model);
|
|
57397
|
-
}
|
|
57398
|
-
}
|
|
57399
|
-
function printSuccess2(model) {
|
|
57400
|
-
console.log("");
|
|
57401
|
-
console.log(source_default.green(" \u2713 Claude connected!"));
|
|
57402
|
-
console.log("");
|
|
57403
|
-
console.log(` ${source_default.gray("Provider:")} anthropic`);
|
|
57404
|
-
if (model)
|
|
57405
|
-
console.log(` ${source_default.gray("Model:")} ${model}`);
|
|
57406
|
-
console.log("");
|
|
57407
|
-
console.log(source_default.dim(" Your agents will now use your Claude subscription for LLM calls."));
|
|
57408
|
-
console.log(source_default.dim(" Change model: trading-boy config set-llm-key --provider anthropic --model <model>"));
|
|
57409
|
-
}
|
|
57410
|
-
async function raceForAuth2(authUrl, state) {
|
|
57411
|
-
const controller = new AbortController();
|
|
57412
|
-
const localCallback = startLocalCallbackServer2(state, controller.signal);
|
|
57413
|
-
const polling = pollForConnection2(controller.signal);
|
|
57414
|
-
console.log(source_default.white(" Opening Claude login in your browser..."));
|
|
57415
|
-
await openBrowser2(authUrl);
|
|
57416
|
-
console.log(source_default.dim(" Complete sign-in in your browser to continue."));
|
|
57417
|
-
console.log(source_default.dim(" Waiting for authentication..."));
|
|
57418
|
-
console.log("");
|
|
57419
|
-
try {
|
|
57420
|
-
const result = await Promise.race([localCallback, polling]);
|
|
57421
|
-
controller.abort();
|
|
57422
|
-
return result;
|
|
57423
|
-
} catch (err) {
|
|
57424
|
-
controller.abort();
|
|
57425
|
-
throw err;
|
|
57426
|
-
}
|
|
57427
|
-
}
|
|
57428
|
-
function startLocalCallbackServer2(state, signal) {
|
|
57429
|
-
return new Promise((resolve4, reject) => {
|
|
57430
|
-
if (signal.aborted) {
|
|
57431
|
-
reject(new Error("Cancelled"));
|
|
57432
|
-
return;
|
|
57433
|
-
}
|
|
57434
|
-
const timeout = setTimeout(() => {
|
|
57435
|
-
server.close();
|
|
57436
|
-
reject(new Error("Timed out waiting for Claude authentication (3 minutes)"));
|
|
57437
|
-
}, AUTH_TIMEOUT_MS2);
|
|
57438
|
-
signal.addEventListener("abort", () => {
|
|
57439
|
-
clearTimeout(timeout);
|
|
57440
|
-
server.close();
|
|
57441
|
-
}, { once: true });
|
|
57442
|
-
const server = http2.createServer((req, res) => {
|
|
57443
|
-
const url2 = new URL3(req.url ?? "/", `http://localhost:${CALLBACK_PORT2}`);
|
|
57444
|
-
if (url2.pathname !== CALLBACK_PATH2) {
|
|
57445
|
-
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
57446
|
-
res.end("Not found");
|
|
57447
|
-
return;
|
|
57448
|
-
}
|
|
57449
|
-
const errorParam = url2.searchParams.get("error");
|
|
57450
|
-
const errorDesc = url2.searchParams.get("error_description");
|
|
57451
|
-
const codeParam = url2.searchParams.get("code");
|
|
57452
|
-
if (errorParam) {
|
|
57453
|
-
res.writeHead(200, { "Content-Type": "text/html" });
|
|
57454
|
-
res.end(callbackHtml2(false, errorDesc || errorParam));
|
|
57455
|
-
clearTimeout(timeout);
|
|
57456
|
-
server.close();
|
|
57457
|
-
reject(new Error(`Anthropic returned error: ${errorDesc || errorParam}`));
|
|
57458
|
-
return;
|
|
57459
|
-
}
|
|
57460
|
-
if (!codeParam) {
|
|
57461
|
-
res.writeHead(200, { "Content-Type": "text/html" });
|
|
57462
|
-
res.end(callbackHtml2(false, "Missing authorization code"));
|
|
57463
|
-
clearTimeout(timeout);
|
|
57464
|
-
server.close();
|
|
57465
|
-
reject(new Error("No authorization code in callback"));
|
|
57466
|
-
return;
|
|
57467
|
-
}
|
|
57468
|
-
res.writeHead(200, { "Content-Type": "text/html" });
|
|
57469
|
-
res.end(callbackHtml2(true));
|
|
57470
|
-
clearTimeout(timeout);
|
|
57471
|
-
server.close();
|
|
57472
|
-
resolve4({ via: "local", code: codeParam, state });
|
|
57473
|
-
});
|
|
57474
|
-
server.on("error", (err) => {
|
|
57475
|
-
clearTimeout(timeout);
|
|
57476
|
-
if (err.code === "EADDRINUSE") {
|
|
57477
|
-
logger24.debug("Port %d in use, falling back to polling only", CALLBACK_PORT2);
|
|
57478
|
-
return;
|
|
57479
|
-
}
|
|
57480
|
-
reject(err);
|
|
57481
|
-
});
|
|
57482
|
-
server.listen(CALLBACK_PORT2, "127.0.0.1");
|
|
57483
|
-
});
|
|
57484
|
-
}
|
|
57485
|
-
async function pollForConnection2(signal) {
|
|
57486
|
-
const deadline = Date.now() + AUTH_TIMEOUT_MS2;
|
|
57487
|
-
while (Date.now() < deadline) {
|
|
57488
|
-
if (signal.aborted)
|
|
57489
|
-
throw new Error("Cancelled");
|
|
57490
|
-
await sleep4(POLL_INTERVAL_MS2);
|
|
57491
|
-
if (signal.aborted)
|
|
57492
|
-
throw new Error("Cancelled");
|
|
57493
|
-
try {
|
|
57494
|
-
const config2 = await apiRequest("/api/v1/llm-config");
|
|
57495
|
-
if (config2.anthropicOAuthConnected) {
|
|
57496
|
-
return { via: "poll", config: config2 };
|
|
57497
|
-
}
|
|
57498
|
-
} catch {
|
|
57499
|
-
logger24.debug("Poll attempt failed, retrying...");
|
|
57500
|
-
}
|
|
57501
|
-
}
|
|
57502
|
-
throw new Error("Timed out waiting for Claude authentication (3 minutes)");
|
|
57503
|
-
}
|
|
57504
|
-
async function handleDisconnect2() {
|
|
57505
|
-
const { confirm } = await Promise.resolve().then(() => (init_esm15(), esm_exports));
|
|
57506
|
-
const yes = await confirm({
|
|
57507
|
-
message: "Disconnect your Claude account?",
|
|
57508
|
-
default: false
|
|
57509
|
-
});
|
|
57510
|
-
if (!yes) {
|
|
57511
|
-
console.log(source_default.dim(" Cancelled."));
|
|
57512
|
-
return;
|
|
57513
|
-
}
|
|
57514
|
-
await apiRequest("/api/v1/anthropic-oauth/disconnect", {
|
|
57515
|
-
method: "POST"
|
|
57516
|
-
});
|
|
57517
|
-
console.log(source_default.green(" \u2713 Claude disconnected."));
|
|
57518
|
-
console.log(source_default.dim(" Your agents will need an API key to continue. Set one:"));
|
|
57519
|
-
console.log(source_default.dim(" trading-boy config set-llm-key <your-api-key>"));
|
|
57520
|
-
}
|
|
57521
|
-
function callbackHtml2(success3, errorMsg) {
|
|
57522
|
-
const title = success3 ? "Claude Connected" : "Connection Failed";
|
|
57523
|
-
const icon = success3 ? "✓" : "✗";
|
|
57524
|
-
const color = success3 ? "#22c55e" : "#ef4444";
|
|
57525
|
-
const message = success3 ? "Your Claude subscription is now connected to Trading Boy.<br>You can close this tab." : `Something went wrong: ${escapeHtml2(errorMsg ?? "Unknown error")}.<br>Please try again.`;
|
|
57526
|
-
return `<!DOCTYPE html>
|
|
57527
|
-
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
57528
|
-
<title>${title} \u2014 Trading Boy</title>
|
|
57529
|
-
<style>*{margin:0;padding:0;box-sizing:border-box}body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;background:#0a0a0a;color:#e5e5e5}
|
|
57530
|
-
.card{text-align:center;padding:3rem;max-width:480px}.icon{font-size:4rem;color:${color};margin-bottom:1rem}h1{font-size:1.5rem;margin-bottom:1rem}p{color:#a3a3a3;line-height:1.6}</style>
|
|
57531
|
-
</head><body><div class="card"><div class="icon">${icon}</div><h1>${title}</h1><p>${message}</p></div></body></html>`;
|
|
57532
|
-
}
|
|
57533
|
-
function escapeHtml2(str2) {
|
|
57534
|
-
return str2.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
57535
|
-
}
|
|
57536
|
-
function sleep4(ms) {
|
|
57537
|
-
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
57538
|
-
}
|
|
57539
|
-
var ALLOWED_AUTH_DOMAINS2 = /* @__PURE__ */ new Set([
|
|
57540
|
-
"platform.claude.com",
|
|
57541
|
-
"claude.ai",
|
|
57542
|
-
"claude.com"
|
|
57543
|
-
]);
|
|
57544
|
-
function validateAuthUrl2(url2) {
|
|
57545
|
-
const parsed = new URL3(url2);
|
|
57546
|
-
if (parsed.protocol !== "https:") {
|
|
57547
|
-
throw new Error(`Refusing to open non-HTTPS URL: ${url2}`);
|
|
57548
|
-
}
|
|
57549
|
-
if (!ALLOWED_AUTH_DOMAINS2.has(parsed.hostname)) {
|
|
57550
|
-
throw new Error(`Refusing to open URL with untrusted domain: ${parsed.hostname}`);
|
|
57551
|
-
}
|
|
57552
|
-
}
|
|
57553
|
-
async function openBrowser2(url2) {
|
|
57554
|
-
try {
|
|
57555
|
-
validateAuthUrl2(url2);
|
|
57556
|
-
const { default: open2 } = await Promise.resolve().then(() => (init_open(), open_exports));
|
|
57557
|
-
await open2(url2);
|
|
57558
|
-
} catch (err) {
|
|
57559
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
57560
|
-
if (message.startsWith("Refusing to open")) {
|
|
57561
|
-
console.error(source_default.red(`
|
|
57562
|
-
${message}`));
|
|
57563
|
-
throw err;
|
|
57564
|
-
}
|
|
57565
|
-
console.log(source_default.yellow(`
|
|
57566
|
-
Could not open browser automatically.`));
|
|
57567
|
-
console.log(source_default.yellow(` Please open this URL manually:
|
|
57568
|
-
`));
|
|
57569
|
-
console.log(` ${source_default.cyan.underline(url2)}
|
|
57570
|
-
`);
|
|
57571
|
-
}
|
|
57572
|
-
}
|
|
57573
|
-
|
|
57574
57361
|
// dist/commands/onboarding.js
|
|
57575
57362
|
async function runOnboarding() {
|
|
57576
57363
|
const { confirm, input } = await Promise.resolve().then(() => (init_esm15(), esm_exports));
|
|
@@ -57678,11 +57465,6 @@ async function runOnboarding() {
|
|
|
57678
57465
|
const llmChoice = await select({
|
|
57679
57466
|
message: "How do you want to power your agent?",
|
|
57680
57467
|
choices: [
|
|
57681
|
-
{
|
|
57682
|
-
name: "Use my Claude subscription (no API key needed)",
|
|
57683
|
-
value: "claude",
|
|
57684
|
-
description: "Sign in with your Anthropic account \u2014 uses your existing Claude Pro/Max/Team plan"
|
|
57685
|
-
},
|
|
57686
57468
|
{
|
|
57687
57469
|
name: "Use my ChatGPT subscription (no API key needed)",
|
|
57688
57470
|
value: "chatgpt",
|
|
@@ -57699,15 +57481,7 @@ async function runOnboarding() {
|
|
|
57699
57481
|
}
|
|
57700
57482
|
]
|
|
57701
57483
|
});
|
|
57702
|
-
if (llmChoice === "
|
|
57703
|
-
try {
|
|
57704
|
-
await handleConnect2();
|
|
57705
|
-
} catch (error49) {
|
|
57706
|
-
const msg = error49 instanceof Error ? error49.message : String(error49);
|
|
57707
|
-
console.log(source_default.yellow(` Could not connect Claude: ${msg}`));
|
|
57708
|
-
console.log(source_default.dim(" Try later: trading-boy connect-claude"));
|
|
57709
|
-
}
|
|
57710
|
-
} else if (llmChoice === "chatgpt") {
|
|
57484
|
+
if (llmChoice === "chatgpt") {
|
|
57711
57485
|
try {
|
|
57712
57486
|
await handleConnect();
|
|
57713
57487
|
} catch (error49) {
|
|
@@ -57749,8 +57523,7 @@ async function runOnboarding() {
|
|
|
57749
57523
|
console.log("");
|
|
57750
57524
|
console.log(source_default.yellow(" \u26A0 Without an LLM provider, agents can scan prices but cannot"));
|
|
57751
57525
|
console.log(source_default.yellow(" analyze markets or make trade decisions."));
|
|
57752
|
-
console.log(source_default.dim(" Set it later: trading-boy connect-
|
|
57753
|
-
console.log(source_default.dim(" Or ChatGPT: trading-boy connect-chatgpt"));
|
|
57526
|
+
console.log(source_default.dim(" Set it later: trading-boy connect-chatgpt"));
|
|
57754
57527
|
console.log(source_default.dim(" Or BYOK: trading-boy config set-llm-key <your-api-key>"));
|
|
57755
57528
|
}
|
|
57756
57529
|
} catch (error49) {
|
|
@@ -57826,8 +57599,8 @@ function isUserAbort(error49) {
|
|
|
57826
57599
|
}
|
|
57827
57600
|
|
|
57828
57601
|
// dist/commands/subscribe.js
|
|
57829
|
-
var
|
|
57830
|
-
var
|
|
57602
|
+
var logger24 = createLogger("cli-subscribe");
|
|
57603
|
+
var POLL_INTERVAL_MS2 = 3e3;
|
|
57831
57604
|
var POLL_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
57832
57605
|
async function createCheckoutSession(email3, plan = "starter") {
|
|
57833
57606
|
const response = await fetch(`${getApiBase()}/api/v1/billing/checkout`, {
|
|
@@ -57890,9 +57663,9 @@ async function pollCryptoPayment(reference, provisioningToken, onTick) {
|
|
|
57890
57663
|
return { success: false, error: "Payment expired or not found. Please try again." };
|
|
57891
57664
|
}
|
|
57892
57665
|
} catch (err) {
|
|
57893
|
-
|
|
57666
|
+
logger24.debug({ error: err }, "Crypto poll attempt failed, retrying");
|
|
57894
57667
|
}
|
|
57895
|
-
await
|
|
57668
|
+
await sleep4(CRYPTO_POLL_INTERVAL);
|
|
57896
57669
|
}
|
|
57897
57670
|
if (Date.now() - start >= POLL_TIMEOUT_MS) {
|
|
57898
57671
|
return { success: false, error: "Timed out waiting for USDC payment. If you sent the payment, contact support." };
|
|
@@ -57908,9 +57681,9 @@ async function pollCryptoPayment(reference, provisioningToken, onTick) {
|
|
|
57908
57681
|
return { success: false, error: "Provisioning token expired after payment. Contact support." };
|
|
57909
57682
|
}
|
|
57910
57683
|
} catch (err) {
|
|
57911
|
-
|
|
57684
|
+
logger24.debug({ error: err }, "Provision poll attempt failed, retrying");
|
|
57912
57685
|
}
|
|
57913
|
-
await
|
|
57686
|
+
await sleep4(POLL_INTERVAL_MS2);
|
|
57914
57687
|
}
|
|
57915
57688
|
return { success: false, error: "Timed out waiting for API key provisioning. Contact support." };
|
|
57916
57689
|
}
|
|
@@ -57943,9 +57716,9 @@ async function pollForApiKey(token, onTick) {
|
|
|
57943
57716
|
};
|
|
57944
57717
|
}
|
|
57945
57718
|
} catch (err) {
|
|
57946
|
-
|
|
57719
|
+
logger24.debug({ error: err }, "Poll attempt failed, retrying");
|
|
57947
57720
|
}
|
|
57948
|
-
await
|
|
57721
|
+
await sleep4(POLL_INTERVAL_MS2);
|
|
57949
57722
|
elapsed = Date.now() - start;
|
|
57950
57723
|
}
|
|
57951
57724
|
return {
|
|
@@ -58069,7 +57842,7 @@ function registerSubscribeCommand(program2) {
|
|
|
58069
57842
|
return;
|
|
58070
57843
|
}
|
|
58071
57844
|
const message = error49 instanceof Error ? error49.message : String(error49);
|
|
58072
|
-
|
|
57845
|
+
logger24.error({ error: message }, "Subscribe command failed");
|
|
58073
57846
|
console.error(source_default.red(` Error: ${message}`));
|
|
58074
57847
|
process.exitCode = 1;
|
|
58075
57848
|
}
|
|
@@ -58120,7 +57893,7 @@ async function handleStripeCheckout(email3, plan) {
|
|
|
58120
57893
|
return;
|
|
58121
57894
|
}
|
|
58122
57895
|
console.log(source_default.white(" Opening Stripe Checkout in your browser..."));
|
|
58123
|
-
await
|
|
57896
|
+
await openBrowser2(checkout.checkoutUrl);
|
|
58124
57897
|
console.log(source_default.dim(" Complete payment in your browser to continue."));
|
|
58125
57898
|
console.log("");
|
|
58126
57899
|
let pollResult;
|
|
@@ -58225,7 +57998,7 @@ async function storeAndDisplayKey(pollResult) {
|
|
|
58225
57998
|
console.error(source_default.yellow(" Warning: Could not save API key automatically."));
|
|
58226
57999
|
console.error(source_default.yellow(` Your API key: ${pollResult.apiKey}`));
|
|
58227
58000
|
console.error(source_default.yellow(" Save this key and run: trading-boy login --api-key <key>"));
|
|
58228
|
-
|
|
58001
|
+
logger24.error({ error: err }, "Failed to save credentials");
|
|
58229
58002
|
process.exitCode = 1;
|
|
58230
58003
|
return;
|
|
58231
58004
|
}
|
|
@@ -58238,7 +58011,7 @@ async function storeAndDisplayKey(pollResult) {
|
|
|
58238
58011
|
function isValidEmail(email3) {
|
|
58239
58012
|
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email3);
|
|
58240
58013
|
}
|
|
58241
|
-
function
|
|
58014
|
+
function sleep4(ms) {
|
|
58242
58015
|
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
58243
58016
|
}
|
|
58244
58017
|
var ALLOWED_CHECKOUT_DOMAINS = /* @__PURE__ */ new Set([
|
|
@@ -58255,7 +58028,7 @@ function validateBrowserUrl(url2) {
|
|
|
58255
58028
|
throw new Error(`Refusing to open URL with untrusted domain: ${parsed.hostname}`);
|
|
58256
58029
|
}
|
|
58257
58030
|
}
|
|
58258
|
-
async function
|
|
58031
|
+
async function openBrowser2(url2) {
|
|
58259
58032
|
try {
|
|
58260
58033
|
validateBrowserUrl(url2);
|
|
58261
58034
|
const { default: open2 } = await Promise.resolve().then(() => (init_open(), open_exports));
|
|
@@ -58610,7 +58383,7 @@ init_source();
|
|
|
58610
58383
|
init_dist2();
|
|
58611
58384
|
init_api_client();
|
|
58612
58385
|
init_utils3();
|
|
58613
|
-
var
|
|
58386
|
+
var logger25 = createLogger("cli-coaching");
|
|
58614
58387
|
var BYOK_HINT = `LLM API key required. Run: ${source_default.white("trading-boy config set-llm-key <key>")}`;
|
|
58615
58388
|
function isByokError(error49) {
|
|
58616
58389
|
if (error49 instanceof ApiError && error49.status === 422)
|
|
@@ -58705,7 +58478,7 @@ function registerCoachingCommand(program2) {
|
|
|
58705
58478
|
return;
|
|
58706
58479
|
}
|
|
58707
58480
|
const message = error49 instanceof ApiError ? error49.message : error49 instanceof Error ? error49.message : String(error49);
|
|
58708
|
-
|
|
58481
|
+
logger25.error({ error: message }, "Pre-trade coaching failed");
|
|
58709
58482
|
console.error(source_default.red(`Error: ${message}`));
|
|
58710
58483
|
process.exitCode = error49 instanceof ApiError ? 2 : 1;
|
|
58711
58484
|
}
|
|
@@ -58746,7 +58519,7 @@ function registerCoachingCommand(program2) {
|
|
|
58746
58519
|
return;
|
|
58747
58520
|
}
|
|
58748
58521
|
const message = error49 instanceof ApiError ? error49.message : error49 instanceof Error ? error49.message : String(error49);
|
|
58749
|
-
|
|
58522
|
+
logger25.error({ error: message }, "Post-trade coaching failed");
|
|
58750
58523
|
console.error(source_default.red(`Error: ${message}`));
|
|
58751
58524
|
process.exitCode = error49 instanceof ApiError ? 2 : 1;
|
|
58752
58525
|
}
|
|
@@ -58762,7 +58535,7 @@ function registerCoachingCommand(program2) {
|
|
|
58762
58535
|
console.log("");
|
|
58763
58536
|
} catch (error49) {
|
|
58764
58537
|
const message = error49 instanceof ApiError ? error49.message : error49 instanceof Error ? error49.message : String(error49);
|
|
58765
|
-
|
|
58538
|
+
logger25.error({ error: message }, "Acknowledge failed");
|
|
58766
58539
|
console.error(source_default.red(`Error: ${message}`));
|
|
58767
58540
|
process.exitCode = error49 instanceof ApiError ? 2 : 1;
|
|
58768
58541
|
}
|
|
@@ -58777,7 +58550,7 @@ function registerCoachingCommand(program2) {
|
|
|
58777
58550
|
console.log("");
|
|
58778
58551
|
} catch (error49) {
|
|
58779
58552
|
const message = error49 instanceof ApiError ? error49.message : error49 instanceof Error ? error49.message : String(error49);
|
|
58780
|
-
|
|
58553
|
+
logger25.error({ error: message }, "Reset failed");
|
|
58781
58554
|
console.error(source_default.red(`Error: ${message}`));
|
|
58782
58555
|
process.exitCode = error49 instanceof ApiError ? 2 : 1;
|
|
58783
58556
|
}
|
|
@@ -58789,7 +58562,7 @@ init_source();
|
|
|
58789
58562
|
init_dist2();
|
|
58790
58563
|
init_api_client();
|
|
58791
58564
|
init_utils3();
|
|
58792
|
-
var
|
|
58565
|
+
var logger26 = createLogger("cli-thesis");
|
|
58793
58566
|
var BYOK_HINT2 = `LLM API key required. Run: ${source_default.white("trading-boy config set-llm-key <key>")}`;
|
|
58794
58567
|
function formatThesisOutput(response) {
|
|
58795
58568
|
const lines = [];
|
|
@@ -58890,7 +58663,7 @@ function registerThesisCommand(program2) {
|
|
|
58890
58663
|
return;
|
|
58891
58664
|
}
|
|
58892
58665
|
const message = error49 instanceof ApiError ? error49.message : error49 instanceof Error ? error49.message : String(error49);
|
|
58893
|
-
|
|
58666
|
+
logger26.error({ error: message }, "Thesis extraction failed");
|
|
58894
58667
|
console.error(source_default.red(`Error: ${message}`));
|
|
58895
58668
|
process.exitCode = error49 instanceof ApiError ? 2 : 1;
|
|
58896
58669
|
}
|
|
@@ -58902,7 +58675,7 @@ init_source();
|
|
|
58902
58675
|
init_dist2();
|
|
58903
58676
|
init_api_client();
|
|
58904
58677
|
init_utils3();
|
|
58905
|
-
var
|
|
58678
|
+
var logger27 = createLogger("cli-strategy");
|
|
58906
58679
|
function formatShortDate2(isoString) {
|
|
58907
58680
|
try {
|
|
58908
58681
|
return new Date(isoString).toISOString().slice(0, 16).replace("T", " ");
|
|
@@ -59012,12 +58785,7 @@ function registerStrategyCommand(program2) {
|
|
|
59012
58785
|
agentId: options.agentId,
|
|
59013
58786
|
tokens,
|
|
59014
58787
|
setupTypes,
|
|
59015
|
-
regimeBehavior:
|
|
59016
|
-
ACCUMULATION: { enabled: true, maxPositionSize: 0.25, confidenceThreshold: 0.6, preferredSetups: setupTypes },
|
|
59017
|
-
MARKUP: { enabled: true, maxPositionSize: 0.5, confidenceThreshold: 0.5, preferredSetups: setupTypes },
|
|
59018
|
-
DISTRIBUTION: { enabled: true, maxPositionSize: 0.15, confidenceThreshold: 0.7, preferredSetups: setupTypes },
|
|
59019
|
-
MARKDOWN: { enabled: false, maxPositionSize: 0.1, confidenceThreshold: 0.8, preferredSetups: setupTypes }
|
|
59020
|
-
},
|
|
58788
|
+
regimeBehavior: generateRegimeBehavior(setupTypes),
|
|
59021
58789
|
riskLimits: {
|
|
59022
58790
|
maxDrawdown: 0.2,
|
|
59023
58791
|
maxConcurrentPositions: 5,
|
|
@@ -59038,7 +58806,7 @@ function registerStrategyCommand(program2) {
|
|
|
59038
58806
|
console.log(formatStrategyDetail(result));
|
|
59039
58807
|
}
|
|
59040
58808
|
} catch (error49) {
|
|
59041
|
-
handleApiError(error49, "Strategy create failed",
|
|
58809
|
+
handleApiError(error49, "Strategy create failed", logger27);
|
|
59042
58810
|
}
|
|
59043
58811
|
});
|
|
59044
58812
|
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) => {
|
|
@@ -59058,7 +58826,7 @@ function registerStrategyCommand(program2) {
|
|
|
59058
58826
|
console.log(formatStrategyList(result));
|
|
59059
58827
|
}
|
|
59060
58828
|
} catch (error49) {
|
|
59061
|
-
handleApiError(error49, "Strategy list failed",
|
|
58829
|
+
handleApiError(error49, "Strategy list failed", logger27);
|
|
59062
58830
|
}
|
|
59063
58831
|
});
|
|
59064
58832
|
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) => {
|
|
@@ -59072,7 +58840,7 @@ function registerStrategyCommand(program2) {
|
|
|
59072
58840
|
console.log(formatStrategyDetail(result));
|
|
59073
58841
|
}
|
|
59074
58842
|
} catch (error49) {
|
|
59075
|
-
handleApiError(error49, "Strategy show failed",
|
|
58843
|
+
handleApiError(error49, "Strategy show failed", logger27);
|
|
59076
58844
|
}
|
|
59077
58845
|
});
|
|
59078
58846
|
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) => {
|
|
@@ -59101,7 +58869,7 @@ function registerStrategyCommand(program2) {
|
|
|
59101
58869
|
console.log(formatStrategyDetail(result));
|
|
59102
58870
|
}
|
|
59103
58871
|
} catch (error49) {
|
|
59104
|
-
handleApiError(error49, "Strategy update failed",
|
|
58872
|
+
handleApiError(error49, "Strategy update failed", logger27);
|
|
59105
58873
|
}
|
|
59106
58874
|
});
|
|
59107
58875
|
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) => {
|
|
@@ -59115,7 +58883,7 @@ function registerStrategyCommand(program2) {
|
|
|
59115
58883
|
console.log(formatHistoryList(result));
|
|
59116
58884
|
}
|
|
59117
58885
|
} catch (error49) {
|
|
59118
|
-
handleApiError(error49, "Strategy history failed",
|
|
58886
|
+
handleApiError(error49, "Strategy history failed", logger27);
|
|
59119
58887
|
}
|
|
59120
58888
|
});
|
|
59121
58889
|
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) => {
|
|
@@ -59141,7 +58909,7 @@ function registerStrategyCommand(program2) {
|
|
|
59141
58909
|
console.log(output);
|
|
59142
58910
|
}
|
|
59143
58911
|
} catch (error49) {
|
|
59144
|
-
handleApiError(error49, "Strategy export failed",
|
|
58912
|
+
handleApiError(error49, "Strategy export failed", logger27);
|
|
59145
58913
|
}
|
|
59146
58914
|
});
|
|
59147
58915
|
}
|
|
@@ -59151,7 +58919,7 @@ init_source();
|
|
|
59151
58919
|
init_dist2();
|
|
59152
58920
|
init_api_client();
|
|
59153
58921
|
init_utils3();
|
|
59154
|
-
var
|
|
58922
|
+
var logger28 = createLogger("cli-replay");
|
|
59155
58923
|
function formatPercent2(val) {
|
|
59156
58924
|
const sign = val >= 0 ? "+" : "";
|
|
59157
58925
|
const str2 = `${sign}${val.toFixed(2)}%`;
|
|
@@ -59217,7 +58985,7 @@ function formatWinRate2(rate) {
|
|
|
59217
58985
|
return source_default.yellow(str2);
|
|
59218
58986
|
return source_default.red(str2);
|
|
59219
58987
|
}
|
|
59220
|
-
var
|
|
58988
|
+
var POLL_INTERVAL_MS3 = 2e3;
|
|
59221
58989
|
var POLL_TIMEOUT_MS2 = 6e4;
|
|
59222
58990
|
async function pollReplayJob(jobId) {
|
|
59223
58991
|
const deadline = Date.now() + POLL_TIMEOUT_MS2;
|
|
@@ -59226,7 +58994,7 @@ async function pollReplayJob(jobId) {
|
|
|
59226
58994
|
if (status.status === "COMPLETE" || status.status === "FAILED") {
|
|
59227
58995
|
return status;
|
|
59228
58996
|
}
|
|
59229
|
-
await new Promise((resolve4) => setTimeout(resolve4,
|
|
58997
|
+
await new Promise((resolve4) => setTimeout(resolve4, POLL_INTERVAL_MS3));
|
|
59230
58998
|
}
|
|
59231
58999
|
throw new Error(`Replay job ${jobId} did not complete within ${POLL_TIMEOUT_MS2 / 1e3}s timeout.`);
|
|
59232
59000
|
}
|
|
@@ -59268,7 +59036,7 @@ function registerReplayCommand(program2) {
|
|
|
59268
59036
|
submitSpinner.succeed(source_default.dim(`Job submitted: ${jobId}`));
|
|
59269
59037
|
} catch (error49) {
|
|
59270
59038
|
submitSpinner.fail("Failed to submit replay job");
|
|
59271
|
-
handleApiError(error49, "Replay submit failed",
|
|
59039
|
+
handleApiError(error49, "Replay submit failed", logger28);
|
|
59272
59040
|
return;
|
|
59273
59041
|
}
|
|
59274
59042
|
const pollSpinner = (await createSpinner2("Running replay\u2026")).start();
|
|
@@ -59278,7 +59046,7 @@ function registerReplayCommand(program2) {
|
|
|
59278
59046
|
pollSpinner.stop();
|
|
59279
59047
|
} catch (error49) {
|
|
59280
59048
|
pollSpinner.fail("Replay timed out or encountered an error");
|
|
59281
|
-
handleApiError(error49, "Replay polling failed",
|
|
59049
|
+
handleApiError(error49, "Replay polling failed", logger28);
|
|
59282
59050
|
return;
|
|
59283
59051
|
}
|
|
59284
59052
|
if (!finalStatus.result) {
|
|
@@ -59451,7 +59219,7 @@ init_source();
|
|
|
59451
59219
|
init_dist2();
|
|
59452
59220
|
init_api_client();
|
|
59453
59221
|
init_utils3();
|
|
59454
|
-
var
|
|
59222
|
+
var logger29 = createLogger("cli-suggestions");
|
|
59455
59223
|
function formatSuggestionsList(data) {
|
|
59456
59224
|
const lines = [];
|
|
59457
59225
|
lines.push("");
|
|
@@ -59513,7 +59281,7 @@ function registerSuggestionsCommand(program2) {
|
|
|
59513
59281
|
}
|
|
59514
59282
|
} catch (error49) {
|
|
59515
59283
|
const message = error49 instanceof ApiError ? error49.message : error49 instanceof Error ? error49.message : String(error49);
|
|
59516
|
-
|
|
59284
|
+
logger29.error({ error: message }, "Failed to list suggestions");
|
|
59517
59285
|
console.error(source_default.red(`Error: ${message}`));
|
|
59518
59286
|
process.exitCode = error49 instanceof ApiError ? 2 : 1;
|
|
59519
59287
|
}
|
|
@@ -59532,7 +59300,7 @@ function registerSuggestionsCommand(program2) {
|
|
|
59532
59300
|
}
|
|
59533
59301
|
} catch (error49) {
|
|
59534
59302
|
const message = error49 instanceof ApiError ? error49.message : error49 instanceof Error ? error49.message : String(error49);
|
|
59535
|
-
|
|
59303
|
+
logger29.error({ error: message }, "Failed to approve suggestion");
|
|
59536
59304
|
console.error(source_default.red(`Error: ${message}`));
|
|
59537
59305
|
process.exitCode = error49 instanceof ApiError ? 2 : 1;
|
|
59538
59306
|
}
|
|
@@ -59551,7 +59319,7 @@ function registerSuggestionsCommand(program2) {
|
|
|
59551
59319
|
}
|
|
59552
59320
|
} catch (error49) {
|
|
59553
59321
|
const message = error49 instanceof ApiError ? error49.message : error49 instanceof Error ? error49.message : String(error49);
|
|
59554
|
-
|
|
59322
|
+
logger29.error({ error: message }, "Failed to reject suggestion");
|
|
59555
59323
|
console.error(source_default.red(`Error: ${message}`));
|
|
59556
59324
|
process.exitCode = error49 instanceof ApiError ? 2 : 1;
|
|
59557
59325
|
}
|
|
@@ -59563,7 +59331,7 @@ init_source();
|
|
|
59563
59331
|
init_dist2();
|
|
59564
59332
|
init_api_client();
|
|
59565
59333
|
init_utils3();
|
|
59566
|
-
var
|
|
59334
|
+
var logger30 = createLogger("cli-cron");
|
|
59567
59335
|
function formatShortDate4(isoString) {
|
|
59568
59336
|
if (!isoString)
|
|
59569
59337
|
return source_default.dim("\u2014");
|
|
@@ -59635,7 +59403,7 @@ function registerCronCommand(program2) {
|
|
|
59635
59403
|
console.log("");
|
|
59636
59404
|
}
|
|
59637
59405
|
} catch (error49) {
|
|
59638
|
-
handleApiError(error49, "Cron create failed",
|
|
59406
|
+
handleApiError(error49, "Cron create failed", logger30);
|
|
59639
59407
|
}
|
|
59640
59408
|
});
|
|
59641
59409
|
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) => {
|
|
@@ -59662,7 +59430,7 @@ function registerCronCommand(program2) {
|
|
|
59662
59430
|
console.log(source_default.dim(` ${result.count} job(s)`));
|
|
59663
59431
|
console.log("");
|
|
59664
59432
|
} catch (error49) {
|
|
59665
|
-
handleApiError(error49, "Cron list failed",
|
|
59433
|
+
handleApiError(error49, "Cron list failed", logger30);
|
|
59666
59434
|
}
|
|
59667
59435
|
});
|
|
59668
59436
|
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) => {
|
|
@@ -59690,7 +59458,7 @@ function registerCronCommand(program2) {
|
|
|
59690
59458
|
console.log(` ${source_default.gray("Created:")} ${formatShortDate4(job.createdAt)}`);
|
|
59691
59459
|
console.log("");
|
|
59692
59460
|
} catch (error49) {
|
|
59693
|
-
handleApiError(error49, "Cron show failed",
|
|
59461
|
+
handleApiError(error49, "Cron show failed", logger30);
|
|
59694
59462
|
}
|
|
59695
59463
|
});
|
|
59696
59464
|
cron.command("pause <jobId>").description("Pause a cron job").action(async (jobId) => {
|
|
@@ -59703,7 +59471,7 @@ function registerCronCommand(program2) {
|
|
|
59703
59471
|
});
|
|
59704
59472
|
console.log(source_default.green(` Job ${jobId} paused`));
|
|
59705
59473
|
} catch (error49) {
|
|
59706
|
-
handleApiError(error49, "Cron pause failed",
|
|
59474
|
+
handleApiError(error49, "Cron pause failed", logger30);
|
|
59707
59475
|
}
|
|
59708
59476
|
});
|
|
59709
59477
|
cron.command("resume <jobId>").description("Resume a paused cron job").action(async (jobId) => {
|
|
@@ -59716,7 +59484,7 @@ function registerCronCommand(program2) {
|
|
|
59716
59484
|
});
|
|
59717
59485
|
console.log(source_default.green(` Job ${jobId} resumed`));
|
|
59718
59486
|
} catch (error49) {
|
|
59719
|
-
handleApiError(error49, "Cron resume failed",
|
|
59487
|
+
handleApiError(error49, "Cron resume failed", logger30);
|
|
59720
59488
|
}
|
|
59721
59489
|
});
|
|
59722
59490
|
cron.command("delete <jobId>").description("Delete a cron job").action(async (jobId) => {
|
|
@@ -59728,7 +59496,7 @@ function registerCronCommand(program2) {
|
|
|
59728
59496
|
});
|
|
59729
59497
|
console.log(source_default.green(` Job ${jobId} deleted`));
|
|
59730
59498
|
} catch (error49) {
|
|
59731
|
-
handleApiError(error49, "Cron delete failed",
|
|
59499
|
+
handleApiError(error49, "Cron delete failed", logger30);
|
|
59732
59500
|
}
|
|
59733
59501
|
});
|
|
59734
59502
|
cron.command("run <jobId>").description("Trigger immediate execution of a cron job").action(async (jobId) => {
|
|
@@ -59740,7 +59508,7 @@ function registerCronCommand(program2) {
|
|
|
59740
59508
|
});
|
|
59741
59509
|
console.log(source_default.green(` Job ${jobId} execution triggered`));
|
|
59742
59510
|
} catch (error49) {
|
|
59743
|
-
handleApiError(error49, "Cron run failed",
|
|
59511
|
+
handleApiError(error49, "Cron run failed", logger30);
|
|
59744
59512
|
}
|
|
59745
59513
|
});
|
|
59746
59514
|
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) => {
|
|
@@ -59768,7 +59536,7 @@ function registerCronCommand(program2) {
|
|
|
59768
59536
|
console.log(source_default.dim(` ${result.count} run(s)`));
|
|
59769
59537
|
console.log("");
|
|
59770
59538
|
} catch (error49) {
|
|
59771
|
-
handleApiError(error49, "Cron history failed",
|
|
59539
|
+
handleApiError(error49, "Cron history failed", logger30);
|
|
59772
59540
|
}
|
|
59773
59541
|
});
|
|
59774
59542
|
}
|
|
@@ -59780,7 +59548,7 @@ init_source();
|
|
|
59780
59548
|
init_dist2();
|
|
59781
59549
|
init_api_client();
|
|
59782
59550
|
init_utils3();
|
|
59783
|
-
var
|
|
59551
|
+
var logger31 = createLogger("cli-agent");
|
|
59784
59552
|
function formatShortDate5(isoString) {
|
|
59785
59553
|
if (!isoString)
|
|
59786
59554
|
return source_default.dim("\u2014");
|
|
@@ -59843,7 +59611,7 @@ function parseHumanInterval(value) {
|
|
|
59843
59611
|
var MIN_SCAN_INTERVAL_MS = 6e4;
|
|
59844
59612
|
function registerAgentCommand(program2) {
|
|
59845
59613
|
const agent = program2.command("agent").description("Manage autonomous trading agents");
|
|
59846
|
-
agent.command("create").description("Create a new agent").option("--trader-id <traderId>", "Trader ID").option("--strategy-id <strategyId>", "Strategy ID").option("--name <name>", "Agent name").option("--autonomy <level>", "Autonomy level: OBSERVE_ONLY, SUGGEST, AUTO_WITH_APPROVAL, FULLY_AUTONOMOUS", "OBSERVE_ONLY").option("--scan-interval <ms>", "Scan interval in ms (min 60000)", "300000").option("--scan-interval-human <duration>", "Scan interval in human-readable format (e.g. 1m, 5m, 15m, 30m, 1h)").option("--watchlist <symbols>", "Comma-separated token symbols").option("--max-daily-trades <n>", "Max daily trades", "10").option("--max-daily-loss <usd>", "Max daily loss in USD", "500").option("--max-position-size <pct>", "Max position size as decimal (0.10 = 10%)", "0.10").option("--min-confidence <n>", "Min confidence threshold (0-1)", "0.60").option("--scan-model <model>", "LLM model for market scanning").option("--analyze-model <model>", "LLM model for deep analysis").option("--decide-model <model>", "LLM model for trade decisions").addOption(new Option("--asset-class <class>", "Asset class for this agent").choices(["crypto", "commodities", "mixed"]).default("crypto")).option("--soul-override <text>", "Custom soul/personality for this agent").option("--purpose-override <text>", "Custom purpose/mission for this agent").option("--soul-file <path>", "Load soul from a file").option("--purpose-file <path>", "Load purpose from a file").option("--exit-reasoner", "Enable LLM-powered exit reasoning for this agent").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (options) => {
|
|
59614
|
+
agent.command("create").description("Create a new agent").option("--trader-id <traderId>", "Trader ID").option("--strategy-id <strategyId>", "Strategy ID (optional \u2014 auto-creates if omitted)").option("--name <name>", "Agent name").option("--autonomy <level>", "Autonomy level: OBSERVE_ONLY, SUGGEST, AUTO_WITH_APPROVAL, FULLY_AUTONOMOUS", "OBSERVE_ONLY").option("--scan-interval <ms>", "Scan interval in ms (min 60000)", "300000").option("--scan-interval-human <duration>", "Scan interval in human-readable format (e.g. 1m, 5m, 15m, 30m, 1h)").option("--watchlist <symbols>", "Comma-separated token symbols").option("--max-daily-trades <n>", "Max daily trades", "10").option("--max-daily-loss <usd>", "Max daily loss in USD", "500").option("--max-position-size <pct>", "Max position size as decimal (0.10 = 10%)", "0.10").option("--min-confidence <n>", "Min confidence threshold (0-1)", "0.60").option("--scan-model <model>", "LLM model for market scanning").option("--analyze-model <model>", "LLM model for deep analysis").option("--decide-model <model>", "LLM model for trade decisions").addOption(new Option("--asset-class <class>", "Asset class for this agent").choices(["crypto", "commodities", "mixed"]).default("crypto")).option("--soul-override <text>", "Custom soul/personality for this agent").option("--purpose-override <text>", "Custom purpose/mission for this agent").option("--soul-file <path>", "Load soul from a file").option("--purpose-file <path>", "Load purpose from a file").option("--exit-reasoner", "Enable LLM-powered exit reasoning for this agent").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (options) => {
|
|
59847
59615
|
if (!await ensureRemote())
|
|
59848
59616
|
return;
|
|
59849
59617
|
if (!options.traderId) {
|
|
@@ -59852,16 +59620,11 @@ function registerAgentCommand(program2) {
|
|
|
59852
59620
|
process.exitCode = 1;
|
|
59853
59621
|
return;
|
|
59854
59622
|
}
|
|
59855
|
-
if (!options.strategyId) {
|
|
59856
|
-
console.error(source_default.red("Error: --strategy-id is required."));
|
|
59857
|
-
console.log(source_default.dim(" Find yours with: trading-boy strategy list"));
|
|
59858
|
-
process.exitCode = 1;
|
|
59859
|
-
return;
|
|
59860
|
-
}
|
|
59861
59623
|
const body = {
|
|
59862
|
-
traderId: options.traderId
|
|
59863
|
-
strategyId: options.strategyId
|
|
59624
|
+
traderId: options.traderId
|
|
59864
59625
|
};
|
|
59626
|
+
if (options.strategyId)
|
|
59627
|
+
body.strategyId = options.strategyId;
|
|
59865
59628
|
if (options.name)
|
|
59866
59629
|
body.name = options.name;
|
|
59867
59630
|
if (options.autonomy)
|
|
@@ -59937,14 +59700,14 @@ function registerAgentCommand(program2) {
|
|
|
59937
59700
|
console.log(` ${source_default.gray("ID:")} ${result.id}`);
|
|
59938
59701
|
console.log(` ${source_default.gray("Name:")} ${result.name}`);
|
|
59939
59702
|
console.log(` ${source_default.gray("Trader:")} ${result.traderId}`);
|
|
59940
|
-
console.log(` ${source_default.gray("Strategy:")} ${result.strategyId}`);
|
|
59703
|
+
console.log(` ${source_default.gray("Strategy:")} ${result.strategyId}${result.autoStrategyCreated ? source_default.dim(" (auto-created)") : ""}`);
|
|
59941
59704
|
console.log(` ${source_default.gray("Autonomy:")} ${formatAutonomy(result.autonomyLevel)}`);
|
|
59942
59705
|
console.log(` ${source_default.gray("Interval:")} ${formatInterval(result.scanIntervalMs)}`);
|
|
59943
59706
|
console.log(` ${source_default.gray("Next scan:")} ${formatShortDate5(result.nextScanAt)}`);
|
|
59944
59707
|
console.log("");
|
|
59945
59708
|
}
|
|
59946
59709
|
} catch (error49) {
|
|
59947
|
-
handleApiError(error49, "Agent create failed",
|
|
59710
|
+
handleApiError(error49, "Agent create failed", logger31);
|
|
59948
59711
|
}
|
|
59949
59712
|
});
|
|
59950
59713
|
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) => {
|
|
@@ -59977,7 +59740,7 @@ function registerAgentCommand(program2) {
|
|
|
59977
59740
|
console.log(source_default.dim(` ${result.count} agent(s)`));
|
|
59978
59741
|
console.log("");
|
|
59979
59742
|
} catch (error49) {
|
|
59980
|
-
handleApiError(error49, "Agent list failed",
|
|
59743
|
+
handleApiError(error49, "Agent list failed", logger31);
|
|
59981
59744
|
}
|
|
59982
59745
|
});
|
|
59983
59746
|
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) => {
|
|
@@ -60050,7 +59813,7 @@ function registerAgentCommand(program2) {
|
|
|
60050
59813
|
}
|
|
60051
59814
|
console.log("");
|
|
60052
59815
|
} catch (error49) {
|
|
60053
|
-
handleApiError(error49, "Agent show failed",
|
|
59816
|
+
handleApiError(error49, "Agent show failed", logger31);
|
|
60054
59817
|
}
|
|
60055
59818
|
});
|
|
60056
59819
|
agent.command("pause <agentId>").description("Pause an agent").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (agentId, options) => {
|
|
@@ -60066,7 +59829,7 @@ function registerAgentCommand(program2) {
|
|
|
60066
59829
|
console.log(source_default.green(` Agent ${agentId} paused`));
|
|
60067
59830
|
}
|
|
60068
59831
|
} catch (error49) {
|
|
60069
|
-
handleApiError(error49, "Agent pause failed",
|
|
59832
|
+
handleApiError(error49, "Agent pause failed", logger31);
|
|
60070
59833
|
}
|
|
60071
59834
|
});
|
|
60072
59835
|
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) => {
|
|
@@ -60082,7 +59845,7 @@ function registerAgentCommand(program2) {
|
|
|
60082
59845
|
console.log(source_default.green(` Agent ${agentId} resumed`));
|
|
60083
59846
|
}
|
|
60084
59847
|
} catch (error49) {
|
|
60085
|
-
handleApiError(error49, "Agent resume failed",
|
|
59848
|
+
handleApiError(error49, "Agent resume failed", logger31);
|
|
60086
59849
|
}
|
|
60087
59850
|
});
|
|
60088
59851
|
agent.command("delete <agentId>").description("Delete an agent").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (agentId, options) => {
|
|
@@ -60098,7 +59861,7 @@ function registerAgentCommand(program2) {
|
|
|
60098
59861
|
console.log(source_default.green(` Agent ${agentId} deleted`));
|
|
60099
59862
|
}
|
|
60100
59863
|
} catch (error49) {
|
|
60101
|
-
handleApiError(error49, "Agent delete failed",
|
|
59864
|
+
handleApiError(error49, "Agent delete failed", logger31);
|
|
60102
59865
|
}
|
|
60103
59866
|
});
|
|
60104
59867
|
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) => {
|
|
@@ -60127,7 +59890,7 @@ function registerAgentCommand(program2) {
|
|
|
60127
59890
|
console.log("");
|
|
60128
59891
|
}
|
|
60129
59892
|
} catch (error49) {
|
|
60130
|
-
handleApiError(error49, "Position exit failed",
|
|
59893
|
+
handleApiError(error49, "Position exit failed", logger31);
|
|
60131
59894
|
}
|
|
60132
59895
|
});
|
|
60133
59896
|
agent.command("update <agentId>").description("Update agent config").option("--name <name>", "Agent name").option("--autonomy <level>", "Autonomy level").option("--scan-interval <ms>", "Scan interval in ms").option("--scan-interval-human <duration>", "Scan interval in human-readable format (e.g. 1m, 5m, 15m, 30m, 1h)").option("--watchlist <symbols>", "Comma-separated token symbols").option("--max-daily-trades <n>", "Max daily trades").option("--max-daily-loss <usd>", "Max daily loss in USD").option("--max-position-size <pct>", "Max position size as decimal").option("--min-confidence <n>", "Min confidence threshold").option("--scan-model <model>", "LLM model for market scanning").option("--analyze-model <model>", "LLM model for deep analysis").option("--decide-model <model>", "LLM model for trade decisions").addOption(new Option("--asset-class <class>", "Asset class for this agent").choices(["crypto", "commodities", "mixed"])).option("--soul-override <text>", "Custom soul/personality for this agent").option("--purpose-override <text>", "Custom purpose/mission for this agent").option("--soul-file <path>", "Load soul from a file").option("--purpose-file <path>", "Load purpose from a file").option("--exit-reasoner", "Enable LLM-powered exit reasoning for this agent").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (agentId, options) => {
|
|
@@ -60212,7 +59975,7 @@ function registerAgentCommand(program2) {
|
|
|
60212
59975
|
console.log(source_default.green(` Agent ${agentId} updated`));
|
|
60213
59976
|
}
|
|
60214
59977
|
} catch (error49) {
|
|
60215
|
-
handleApiError(error49, "Agent update failed",
|
|
59978
|
+
handleApiError(error49, "Agent update failed", logger31);
|
|
60216
59979
|
}
|
|
60217
59980
|
});
|
|
60218
59981
|
}
|
|
@@ -60258,7 +60021,6 @@ function createCli() {
|
|
|
60258
60021
|
registerBillingCommand(program2);
|
|
60259
60022
|
registerSubscribeCommand(program2);
|
|
60260
60023
|
registerConnectChatgptCommand(program2);
|
|
60261
|
-
registerConnectClaudeCommand(program2);
|
|
60262
60024
|
registerCoachingCommand(program2);
|
|
60263
60025
|
registerThesisCommand(program2);
|
|
60264
60026
|
registerStrategyCommand(program2);
|
package/dist/cli.js
CHANGED
|
@@ -43,7 +43,7 @@ import { registerSuggestionsCommand } from './commands/suggestions-cmd.js';
|
|
|
43
43
|
import { registerCronCommand } from './commands/cron-cmd.js';
|
|
44
44
|
import { registerAgentCommand } from './commands/agent-cmd.js';
|
|
45
45
|
import { registerConnectChatgptCommand } from './commands/connect-chatgpt.js';
|
|
46
|
-
import { registerConnectClaudeCommand } from './commands/connect-claude.js';
|
|
46
|
+
// import { registerConnectClaudeCommand } from './commands/connect-claude.js'; // Hidden — Anthropic ToS prohibits OAuth for third-party use
|
|
47
47
|
import { readFileSync } from 'node:fs';
|
|
48
48
|
import { fileURLToPath } from 'node:url';
|
|
49
49
|
import { dirname, resolve } from 'node:path';
|
|
@@ -87,7 +87,7 @@ export function createCli() {
|
|
|
87
87
|
registerBillingCommand(program);
|
|
88
88
|
registerSubscribeCommand(program);
|
|
89
89
|
registerConnectChatgptCommand(program);
|
|
90
|
-
registerConnectClaudeCommand(program);
|
|
90
|
+
// registerConnectClaudeCommand(program); // Hidden — Anthropic ToS prohibits OAuth for third-party use
|
|
91
91
|
// Learning & coaching
|
|
92
92
|
registerCoachingCommand(program);
|
|
93
93
|
registerThesisCommand(program);
|
|
@@ -79,7 +79,7 @@ export function registerAgentCommand(program) {
|
|
|
79
79
|
.command('create')
|
|
80
80
|
.description('Create a new agent')
|
|
81
81
|
.option('--trader-id <traderId>', 'Trader ID')
|
|
82
|
-
.option('--strategy-id <strategyId>', 'Strategy ID')
|
|
82
|
+
.option('--strategy-id <strategyId>', 'Strategy ID (optional — auto-creates if omitted)')
|
|
83
83
|
.option('--name <name>', 'Agent name')
|
|
84
84
|
.option('--autonomy <level>', 'Autonomy level: OBSERVE_ONLY, SUGGEST, AUTO_WITH_APPROVAL, FULLY_AUTONOMOUS', 'OBSERVE_ONLY')
|
|
85
85
|
.option('--scan-interval <ms>', 'Scan interval in ms (min 60000)', '300000')
|
|
@@ -108,16 +108,11 @@ export function registerAgentCommand(program) {
|
|
|
108
108
|
process.exitCode = 1;
|
|
109
109
|
return;
|
|
110
110
|
}
|
|
111
|
-
if (!options.strategyId) {
|
|
112
|
-
console.error(chalk.red('Error: --strategy-id is required.'));
|
|
113
|
-
console.log(chalk.dim(' Find yours with: trading-boy strategy list'));
|
|
114
|
-
process.exitCode = 1;
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
111
|
const body = {
|
|
118
112
|
traderId: options.traderId,
|
|
119
|
-
strategyId: options.strategyId,
|
|
120
113
|
};
|
|
114
|
+
if (options.strategyId)
|
|
115
|
+
body.strategyId = options.strategyId;
|
|
121
116
|
if (options.name)
|
|
122
117
|
body.name = options.name;
|
|
123
118
|
if (options.autonomy)
|
|
@@ -200,7 +195,7 @@ export function registerAgentCommand(program) {
|
|
|
200
195
|
console.log(` ${chalk.gray('ID:')} ${result.id}`);
|
|
201
196
|
console.log(` ${chalk.gray('Name:')} ${result.name}`);
|
|
202
197
|
console.log(` ${chalk.gray('Trader:')} ${result.traderId}`);
|
|
203
|
-
console.log(` ${chalk.gray('Strategy:')} ${result.strategyId}`);
|
|
198
|
+
console.log(` ${chalk.gray('Strategy:')} ${result.strategyId}${result.autoStrategyCreated ? chalk.dim(' (auto-created)') : ''}`);
|
|
204
199
|
console.log(` ${chalk.gray('Autonomy:')} ${formatAutonomy(result.autonomyLevel)}`);
|
|
205
200
|
console.log(` ${chalk.gray('Interval:')} ${formatInterval(result.scanIntervalMs)}`);
|
|
206
201
|
console.log(` ${chalk.gray('Next scan:')} ${formatShortDate(result.nextScanAt)}`);
|
|
@@ -11,7 +11,6 @@ import chalk from 'chalk';
|
|
|
11
11
|
import { isRemoteMode, apiRequest, ApiError } from '../api-client.js';
|
|
12
12
|
import { runSoulWizardAndUpload } from './soul-wizard.js';
|
|
13
13
|
import { connectChatgpt } from './connect-chatgpt.js';
|
|
14
|
-
import { connectClaude } from './connect-claude.js';
|
|
15
14
|
// ─── Onboarding Flow ───
|
|
16
15
|
/**
|
|
17
16
|
* Run the interactive onboarding wizard.
|
|
@@ -135,11 +134,6 @@ export async function runOnboarding() {
|
|
|
135
134
|
const llmChoice = await select({
|
|
136
135
|
message: 'How do you want to power your agent?',
|
|
137
136
|
choices: [
|
|
138
|
-
{
|
|
139
|
-
name: 'Use my Claude subscription (no API key needed)',
|
|
140
|
-
value: 'claude',
|
|
141
|
-
description: 'Sign in with your Anthropic account — uses your existing Claude Pro/Max/Team plan',
|
|
142
|
-
},
|
|
143
137
|
{
|
|
144
138
|
name: 'Use my ChatGPT subscription (no API key needed)',
|
|
145
139
|
value: 'chatgpt',
|
|
@@ -156,17 +150,7 @@ export async function runOnboarding() {
|
|
|
156
150
|
},
|
|
157
151
|
],
|
|
158
152
|
});
|
|
159
|
-
if (llmChoice === '
|
|
160
|
-
try {
|
|
161
|
-
await connectClaude();
|
|
162
|
-
}
|
|
163
|
-
catch (error) {
|
|
164
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
165
|
-
console.log(chalk.yellow(` Could not connect Claude: ${msg}`));
|
|
166
|
-
console.log(chalk.dim(' Try later: trading-boy connect-claude'));
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
else if (llmChoice === 'chatgpt') {
|
|
153
|
+
if (llmChoice === 'chatgpt') {
|
|
170
154
|
try {
|
|
171
155
|
await connectChatgpt();
|
|
172
156
|
}
|
|
@@ -213,8 +197,7 @@ export async function runOnboarding() {
|
|
|
213
197
|
console.log('');
|
|
214
198
|
console.log(chalk.yellow(' ⚠ Without an LLM provider, agents can scan prices but cannot'));
|
|
215
199
|
console.log(chalk.yellow(' analyze markets or make trade decisions.'));
|
|
216
|
-
console.log(chalk.dim(' Set it later: trading-boy connect-
|
|
217
|
-
console.log(chalk.dim(' Or ChatGPT: trading-boy connect-chatgpt'));
|
|
200
|
+
console.log(chalk.dim(' Set it later: trading-boy connect-chatgpt'));
|
|
218
201
|
console.log(chalk.dim(' Or BYOK: trading-boy config set-llm-key <your-api-key>'));
|
|
219
202
|
}
|
|
220
203
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Option } from 'commander';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import { createLogger } from '@trading-boy/core';
|
|
3
|
+
import { createLogger, generateRegimeBehavior } from '@trading-boy/core';
|
|
4
4
|
import { apiRequest } from '../api-client.js';
|
|
5
5
|
import { padRight, handleApiError, ensureRemote } from '../utils.js';
|
|
6
6
|
// ─── Logger ───
|
|
@@ -155,12 +155,7 @@ export function registerStrategyCommand(program) {
|
|
|
155
155
|
agentId: options.agentId,
|
|
156
156
|
tokens,
|
|
157
157
|
setupTypes,
|
|
158
|
-
regimeBehavior:
|
|
159
|
-
ACCUMULATION: { enabled: true, maxPositionSize: 0.25, confidenceThreshold: 0.6, preferredSetups: setupTypes },
|
|
160
|
-
MARKUP: { enabled: true, maxPositionSize: 0.5, confidenceThreshold: 0.5, preferredSetups: setupTypes },
|
|
161
|
-
DISTRIBUTION: { enabled: true, maxPositionSize: 0.15, confidenceThreshold: 0.7, preferredSetups: setupTypes },
|
|
162
|
-
MARKDOWN: { enabled: false, maxPositionSize: 0.1, confidenceThreshold: 0.8, preferredSetups: setupTypes },
|
|
163
|
-
},
|
|
158
|
+
regimeBehavior: generateRegimeBehavior(setupTypes),
|
|
164
159
|
riskLimits: {
|
|
165
160
|
maxDrawdown: 0.2,
|
|
166
161
|
maxConcurrentPositions: 5,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trading-boy/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "Trading Boy CLI — crypto context intelligence for traders and AI agents. Query real-time prices, funding rates, whale activity, and DeFi risk for 100+ Solana tokens and 229 Hyperliquid perpetuals.",
|
|
5
5
|
"homepage": "https://cabal.ventures",
|
|
6
6
|
"repository": {
|