@trading-boy/cli 1.3.0 → 1.4.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/dist/cli.bundle.js +52 -4
- package/dist/commands/agent-cmd.js +38 -0
- package/dist/commands/subscribe.js +10 -3
- package/dist/commands/whoami.js +14 -0
- package/package.json +1 -1
package/dist/cli.bundle.js
CHANGED
|
@@ -39795,6 +39795,7 @@ var envSchema = external_exports.object({
|
|
|
39795
39795
|
FINNHUB_API_KEY: external_exports.string().default(""),
|
|
39796
39796
|
// Macro data sources
|
|
39797
39797
|
FRED_API_KEY: external_exports.string().default(""),
|
|
39798
|
+
EIA_API_KEY: external_exports.string().default(""),
|
|
39798
39799
|
NEWSDATA_API_KEY: external_exports.string().default(""),
|
|
39799
39800
|
KALSHI_API_KEY: external_exports.string().default(""),
|
|
39800
39801
|
OILPRICE_API_KEY: external_exports.string().default(""),
|
|
@@ -54632,9 +54633,21 @@ function formatWhoamiOutput(result) {
|
|
|
54632
54633
|
return lines.join("\n");
|
|
54633
54634
|
}
|
|
54634
54635
|
function registerWhoamiCommand(program2) {
|
|
54635
|
-
program2.command("whoami").description("Show current authentication status").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (options) => {
|
|
54636
|
+
program2.command("whoami").description("Show current authentication status").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).addOption(new Option("--show-key", "Show full API key (for Telegram setup)")).action(async (options) => {
|
|
54636
54637
|
try {
|
|
54637
54638
|
const result = await executeWhoami();
|
|
54639
|
+
if (options.showKey && result.authenticated) {
|
|
54640
|
+
const envKey = process.env.TRADING_BOY_API_KEY;
|
|
54641
|
+
if (envKey) {
|
|
54642
|
+
console.log(envKey);
|
|
54643
|
+
return;
|
|
54644
|
+
}
|
|
54645
|
+
const creds = await loadCredentials();
|
|
54646
|
+
if (creds) {
|
|
54647
|
+
console.log(creds.apiKey);
|
|
54648
|
+
return;
|
|
54649
|
+
}
|
|
54650
|
+
}
|
|
54638
54651
|
if (options.format === "json") {
|
|
54639
54652
|
console.log(JSON.stringify(result, null, 2));
|
|
54640
54653
|
} else {
|
|
@@ -55045,12 +55058,18 @@ function formatSubscribeSuccess(result) {
|
|
|
55045
55058
|
if (result.plan) {
|
|
55046
55059
|
lines.push(` ${source_default.bold("Plan:")} ${result.plan}`);
|
|
55047
55060
|
}
|
|
55048
|
-
if (result.
|
|
55061
|
+
if (result.apiKey) {
|
|
55062
|
+
lines.push(` ${source_default.bold("API Key:")} ${source_default.yellow(result.apiKey)}`);
|
|
55063
|
+
lines.push("");
|
|
55064
|
+
lines.push(source_default.dim(" \u26A0\uFE0F Copy this key now \u2014 it will not be shown again."));
|
|
55065
|
+
lines.push(source_default.dim(" Use it to connect Telegram: send /start to @TradingBoyBot"));
|
|
55066
|
+
lines.push(source_default.dim(" and paste the key when prompted."));
|
|
55067
|
+
} else if (result.keyPrefix) {
|
|
55049
55068
|
lines.push(` ${source_default.bold("Key ID:")} ${result.keyPrefix}`);
|
|
55050
55069
|
}
|
|
55051
55070
|
lines.push("");
|
|
55052
|
-
lines.push(source_default.dim(" Your API key has been stored
|
|
55053
|
-
lines.push(source_default.dim(" You can
|
|
55071
|
+
lines.push(source_default.dim(" Your API key has been stored locally."));
|
|
55072
|
+
lines.push(source_default.dim(" You can also view it anytime: trading-boy whoami --show-key"));
|
|
55054
55073
|
lines.push("");
|
|
55055
55074
|
lines.push(source_default.cyan(" Try it: trading-boy context SOL"));
|
|
55056
55075
|
lines.push("");
|
|
@@ -57256,6 +57275,35 @@ function registerAgentCommand(program2) {
|
|
|
57256
57275
|
handleApiError4(error49, "Agent delete failed");
|
|
57257
57276
|
}
|
|
57258
57277
|
});
|
|
57278
|
+
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) => {
|
|
57279
|
+
if (!await ensureRemote2())
|
|
57280
|
+
return;
|
|
57281
|
+
try {
|
|
57282
|
+
const body = {};
|
|
57283
|
+
if (options.reason)
|
|
57284
|
+
body.reason = options.reason;
|
|
57285
|
+
const result = await apiRequest(`/api/v1/agents/${encodeURIComponent(agentId)}/positions/${encodeURIComponent(options.symbol)}/exit`, { method: "POST", body });
|
|
57286
|
+
if (options.format === "json") {
|
|
57287
|
+
console.log(JSON.stringify(result, null, 2));
|
|
57288
|
+
} else {
|
|
57289
|
+
const pnlColor = result.pnl >= 0 ? source_default.green : source_default.red;
|
|
57290
|
+
const pnlSign = result.pnl >= 0 ? "+" : "";
|
|
57291
|
+
console.log("");
|
|
57292
|
+
console.log(source_default.green(" Position closed"));
|
|
57293
|
+
console.log(` ${source_default.gray("Symbol:")} ${result.symbol}`);
|
|
57294
|
+
console.log(` ${source_default.gray("Side:")} ${result.side}`);
|
|
57295
|
+
console.log(` ${source_default.gray("Exit price:")} $${result.exitPrice.toLocaleString()}`);
|
|
57296
|
+
console.log(` ${source_default.gray("PnL:")} ${pnlColor(`${pnlSign}$${result.pnl.toFixed(2)} (${pnlSign}${result.pnlPct.toFixed(2)}%)`)}`);
|
|
57297
|
+
console.log(` ${source_default.gray("Closed at:")} ${formatShortDate5(result.closedAt)}`);
|
|
57298
|
+
if (options.reason) {
|
|
57299
|
+
console.log(` ${source_default.gray("Reason:")} ${options.reason}`);
|
|
57300
|
+
}
|
|
57301
|
+
console.log("");
|
|
57302
|
+
}
|
|
57303
|
+
} catch (error49) {
|
|
57304
|
+
handleApiError4(error49, "Position exit failed");
|
|
57305
|
+
}
|
|
57306
|
+
});
|
|
57259
57307
|
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").action(async (agentId, options) => {
|
|
57260
57308
|
if (!await ensureRemote2())
|
|
57261
57309
|
return;
|
|
@@ -411,6 +411,44 @@ export function registerAgentCommand(program) {
|
|
|
411
411
|
handleApiError(error, 'Agent delete failed');
|
|
412
412
|
}
|
|
413
413
|
});
|
|
414
|
+
// ── exit ───────────────────────────────────────────────────────────────────
|
|
415
|
+
agent
|
|
416
|
+
.command('exit <agentId>')
|
|
417
|
+
.description('Exit/close an open position for an agent')
|
|
418
|
+
.requiredOption('--symbol <symbol>', 'Token symbol to exit (e.g. xyz:NATGAS)')
|
|
419
|
+
.option('--reason <text>', 'Reason for exit')
|
|
420
|
+
.addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
|
|
421
|
+
.action(async (agentId, options) => {
|
|
422
|
+
if (!(await ensureRemote()))
|
|
423
|
+
return;
|
|
424
|
+
try {
|
|
425
|
+
const body = {};
|
|
426
|
+
if (options.reason)
|
|
427
|
+
body.reason = options.reason;
|
|
428
|
+
const result = await apiRequest(`/api/v1/agents/${encodeURIComponent(agentId)}/positions/${encodeURIComponent(options.symbol)}/exit`, { method: 'POST', body });
|
|
429
|
+
if (options.format === 'json') {
|
|
430
|
+
console.log(JSON.stringify(result, null, 2));
|
|
431
|
+
}
|
|
432
|
+
else {
|
|
433
|
+
const pnlColor = result.pnl >= 0 ? chalk.green : chalk.red;
|
|
434
|
+
const pnlSign = result.pnl >= 0 ? '+' : '';
|
|
435
|
+
console.log('');
|
|
436
|
+
console.log(chalk.green(' Position closed'));
|
|
437
|
+
console.log(` ${chalk.gray('Symbol:')} ${result.symbol}`);
|
|
438
|
+
console.log(` ${chalk.gray('Side:')} ${result.side}`);
|
|
439
|
+
console.log(` ${chalk.gray('Exit price:')} $${result.exitPrice.toLocaleString()}`);
|
|
440
|
+
console.log(` ${chalk.gray('PnL:')} ${pnlColor(`${pnlSign}$${result.pnl.toFixed(2)} (${pnlSign}${result.pnlPct.toFixed(2)}%)`)}`);
|
|
441
|
+
console.log(` ${chalk.gray('Closed at:')} ${formatShortDate(result.closedAt)}`);
|
|
442
|
+
if (options.reason) {
|
|
443
|
+
console.log(` ${chalk.gray('Reason:')} ${options.reason}`);
|
|
444
|
+
}
|
|
445
|
+
console.log('');
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
catch (error) {
|
|
449
|
+
handleApiError(error, 'Position exit failed');
|
|
450
|
+
}
|
|
451
|
+
});
|
|
414
452
|
// ── update ──────────────────────────────────────────────────────────────────
|
|
415
453
|
agent
|
|
416
454
|
.command('update <agentId>')
|
|
@@ -213,12 +213,19 @@ export function formatSubscribeSuccess(result) {
|
|
|
213
213
|
if (result.plan) {
|
|
214
214
|
lines.push(` ${chalk.bold('Plan:')} ${result.plan}`);
|
|
215
215
|
}
|
|
216
|
-
if (result.
|
|
216
|
+
if (result.apiKey) {
|
|
217
|
+
lines.push(` ${chalk.bold('API Key:')} ${chalk.yellow(result.apiKey)}`);
|
|
218
|
+
lines.push('');
|
|
219
|
+
lines.push(chalk.dim(' ⚠️ Copy this key now — it will not be shown again.'));
|
|
220
|
+
lines.push(chalk.dim(' Use it to connect Telegram: send /start to @TradingBoyBot'));
|
|
221
|
+
lines.push(chalk.dim(' and paste the key when prompted.'));
|
|
222
|
+
}
|
|
223
|
+
else if (result.keyPrefix) {
|
|
217
224
|
lines.push(` ${chalk.bold('Key ID:')} ${result.keyPrefix}`);
|
|
218
225
|
}
|
|
219
226
|
lines.push('');
|
|
220
|
-
lines.push(chalk.dim(' Your API key has been stored
|
|
221
|
-
lines.push(chalk.dim(' You can
|
|
227
|
+
lines.push(chalk.dim(' Your API key has been stored locally.'));
|
|
228
|
+
lines.push(chalk.dim(' You can also view it anytime: trading-boy whoami --show-key'));
|
|
222
229
|
lines.push('');
|
|
223
230
|
lines.push(chalk.cyan(' Try it: trading-boy context SOL'));
|
|
224
231
|
lines.push('');
|
package/dist/commands/whoami.js
CHANGED
|
@@ -68,9 +68,23 @@ export function registerWhoamiCommand(program) {
|
|
|
68
68
|
.command('whoami')
|
|
69
69
|
.description('Show current authentication status')
|
|
70
70
|
.addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
|
|
71
|
+
.addOption(new Option('--show-key', 'Show full API key (for Telegram setup)'))
|
|
71
72
|
.action(async (options) => {
|
|
72
73
|
try {
|
|
73
74
|
const result = await executeWhoami();
|
|
75
|
+
// Show full key if requested
|
|
76
|
+
if (options.showKey && result.authenticated) {
|
|
77
|
+
const envKey = process.env.TRADING_BOY_API_KEY;
|
|
78
|
+
if (envKey) {
|
|
79
|
+
console.log(envKey);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const creds = await loadCredentials();
|
|
83
|
+
if (creds) {
|
|
84
|
+
console.log(creds.apiKey);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
74
88
|
if (options.format === 'json') {
|
|
75
89
|
console.log(JSON.stringify(result, null, 2));
|
|
76
90
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trading-boy/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
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": {
|