@trading-boy/cli 1.4.0 → 1.5.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 +38 -16
- package/dist/commands/infra.d.ts +6 -2
- package/dist/commands/infra.js +18 -11
- package/dist/commands/login.js +1 -0
- package/dist/commands/onboarding.js +4 -4
- package/dist/commands/subscribe.js +10 -3
- package/dist/commands/whoami.js +15 -1
- package/package.json +1 -1
package/dist/cli.bundle.js
CHANGED
|
@@ -54273,7 +54273,7 @@ function registerConfigCommand(program2) {
|
|
|
54273
54273
|
init_source();
|
|
54274
54274
|
init_utils();
|
|
54275
54275
|
var logger18 = createLogger("cli-infra");
|
|
54276
|
-
async function checkInfraStatus() {
|
|
54276
|
+
async function checkInfraStatus(options) {
|
|
54277
54277
|
const apiBase = getApiBase();
|
|
54278
54278
|
try {
|
|
54279
54279
|
const response = await fetch(`${apiBase}/health`);
|
|
@@ -54286,7 +54286,7 @@ async function checkInfraStatus() {
|
|
|
54286
54286
|
details: apiBase
|
|
54287
54287
|
}
|
|
54288
54288
|
];
|
|
54289
|
-
if (data.services) {
|
|
54289
|
+
if (!options?.remote && data.services) {
|
|
54290
54290
|
if (data.services.neo4j) {
|
|
54291
54291
|
services.push({
|
|
54292
54292
|
name: "Neo4j",
|
|
@@ -54309,10 +54309,8 @@ async function checkInfraStatus() {
|
|
|
54309
54309
|
});
|
|
54310
54310
|
}
|
|
54311
54311
|
}
|
|
54312
|
-
|
|
54313
|
-
|
|
54314
|
-
overallHealthy: services.every((s) => s.healthy)
|
|
54315
|
-
};
|
|
54312
|
+
const overallHealthy = options?.remote ? response.ok && data.status === "ok" : services.every((s) => s.healthy);
|
|
54313
|
+
return { services, overallHealthy };
|
|
54316
54314
|
} catch (error49) {
|
|
54317
54315
|
return {
|
|
54318
54316
|
services: [
|
|
@@ -54330,7 +54328,7 @@ async function checkInfraStatus() {
|
|
|
54330
54328
|
function formatStatusIndicator(healthy) {
|
|
54331
54329
|
return healthy ? source_default.green("\u2713 UP") : source_default.red("\u2717 DOWN");
|
|
54332
54330
|
}
|
|
54333
|
-
function formatInfraStatus(result) {
|
|
54331
|
+
function formatInfraStatus(result, options) {
|
|
54334
54332
|
const lines = [];
|
|
54335
54333
|
lines.push("");
|
|
54336
54334
|
lines.push(source_default.bold.cyan(" Infrastructure Status"));
|
|
@@ -54344,6 +54342,10 @@ function formatInfraStatus(result) {
|
|
|
54344
54342
|
}
|
|
54345
54343
|
}
|
|
54346
54344
|
lines.push("");
|
|
54345
|
+
if (options?.remote) {
|
|
54346
|
+
lines.push(source_default.dim(" Backend services are managed infrastructure. Contact support if issues persist."));
|
|
54347
|
+
lines.push("");
|
|
54348
|
+
}
|
|
54347
54349
|
if (result.overallHealthy) {
|
|
54348
54350
|
lines.push(` ${source_default.green.bold("All services healthy.")}`);
|
|
54349
54351
|
} else {
|
|
@@ -54357,12 +54359,13 @@ function registerInfraCommand(program2) {
|
|
|
54357
54359
|
const infra = program2.command("infra").description("Infrastructure management commands");
|
|
54358
54360
|
infra.command("status").description("Check health of API server and underlying infrastructure").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (options) => {
|
|
54359
54361
|
try {
|
|
54362
|
+
const remote = await isRemoteMode();
|
|
54360
54363
|
console.log(source_default.gray(" Checking infrastructure health..."));
|
|
54361
|
-
const result = await checkInfraStatus();
|
|
54364
|
+
const result = await checkInfraStatus({ remote });
|
|
54362
54365
|
if (options.format === "json") {
|
|
54363
54366
|
console.log(JSON.stringify(result, null, 2));
|
|
54364
54367
|
} else {
|
|
54365
|
-
console.log(formatInfraStatus(result));
|
|
54368
|
+
console.log(formatInfraStatus(result, { remote }));
|
|
54366
54369
|
}
|
|
54367
54370
|
if (!result.overallHealthy) {
|
|
54368
54371
|
process.exitCode = 1;
|
|
@@ -54433,6 +54436,7 @@ function registerLoginCommand(program2) {
|
|
|
54433
54436
|
console.log("");
|
|
54434
54437
|
console.log(source_default.bold(" Trading Boy \u2014 Login"));
|
|
54435
54438
|
console.log(source_default.gray(" " + "\u2500".repeat(40)));
|
|
54439
|
+
console.log(source_default.dim(" Don't have a key? Run: trading-boy subscribe"));
|
|
54436
54440
|
console.log("");
|
|
54437
54441
|
apiKey = await password({
|
|
54438
54442
|
message: "Enter your API key",
|
|
@@ -54603,7 +54607,7 @@ function formatWhoamiOutput(result) {
|
|
|
54603
54607
|
const lines = [];
|
|
54604
54608
|
lines.push("");
|
|
54605
54609
|
if (!result.authenticated) {
|
|
54606
|
-
lines.push(source_default.dim(" Not authenticated. Run `trading-boy login` to get started."));
|
|
54610
|
+
lines.push(source_default.dim(" Not authenticated. Run `trading-boy login` or `trading-boy subscribe` to get started."));
|
|
54607
54611
|
lines.push("");
|
|
54608
54612
|
return lines.join("\n");
|
|
54609
54613
|
}
|
|
@@ -54633,9 +54637,21 @@ function formatWhoamiOutput(result) {
|
|
|
54633
54637
|
return lines.join("\n");
|
|
54634
54638
|
}
|
|
54635
54639
|
function registerWhoamiCommand(program2) {
|
|
54636
|
-
program2.command("whoami").description("Show current authentication status").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action(async (options) => {
|
|
54640
|
+
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) => {
|
|
54637
54641
|
try {
|
|
54638
54642
|
const result = await executeWhoami();
|
|
54643
|
+
if (options.showKey && result.authenticated) {
|
|
54644
|
+
const envKey = process.env.TRADING_BOY_API_KEY;
|
|
54645
|
+
if (envKey) {
|
|
54646
|
+
console.log(envKey);
|
|
54647
|
+
return;
|
|
54648
|
+
}
|
|
54649
|
+
const creds = await loadCredentials();
|
|
54650
|
+
if (creds) {
|
|
54651
|
+
console.log(creds.apiKey);
|
|
54652
|
+
return;
|
|
54653
|
+
}
|
|
54654
|
+
}
|
|
54639
54655
|
if (options.format === "json") {
|
|
54640
54656
|
console.log(JSON.stringify(result, null, 2));
|
|
54641
54657
|
} else {
|
|
@@ -54871,9 +54887,9 @@ async function runOnboarding() {
|
|
|
54871
54887
|
console.log(source_default.gray(" " + "\u2500".repeat(50)));
|
|
54872
54888
|
console.log("");
|
|
54873
54889
|
console.log(` ${source_default.white("trading-boy context SOL")} ${source_default.dim("Full context for any token")}`);
|
|
54874
|
-
console.log(` ${source_default.white("trading-boy journal")}
|
|
54890
|
+
console.log(` ${source_default.white("trading-boy journal log entry SOL")} ${source_default.dim("Log a trade entry")}`);
|
|
54875
54891
|
console.log(` ${source_default.white("trading-boy decisions")} ${source_default.dim("View trade history")}`);
|
|
54876
|
-
console.log(` ${source_default.white("trading-boy review daily")}
|
|
54892
|
+
console.log(` ${source_default.white("trading-boy journal review daily")} ${source_default.dim("Review your daily trades")}`);
|
|
54877
54893
|
console.log(` ${source_default.white("trading-boy narrative list")} ${source_default.dim("Active market narratives")}`);
|
|
54878
54894
|
console.log(` ${source_default.white("trading-boy catalysts")} ${source_default.dim("Upcoming events")}`);
|
|
54879
54895
|
if (traderRegistered) {
|
|
@@ -55046,12 +55062,18 @@ function formatSubscribeSuccess(result) {
|
|
|
55046
55062
|
if (result.plan) {
|
|
55047
55063
|
lines.push(` ${source_default.bold("Plan:")} ${result.plan}`);
|
|
55048
55064
|
}
|
|
55049
|
-
if (result.
|
|
55065
|
+
if (result.apiKey) {
|
|
55066
|
+
lines.push(` ${source_default.bold("API Key:")} ${source_default.yellow(result.apiKey)}`);
|
|
55067
|
+
lines.push("");
|
|
55068
|
+
lines.push(source_default.dim(" \u26A0\uFE0F Copy this key now \u2014 it will not be shown again."));
|
|
55069
|
+
lines.push(source_default.dim(" Use it to connect Telegram: send /start to @TradingBoy1_Bot"));
|
|
55070
|
+
lines.push(source_default.dim(" and paste the key when prompted."));
|
|
55071
|
+
} else if (result.keyPrefix) {
|
|
55050
55072
|
lines.push(` ${source_default.bold("Key ID:")} ${result.keyPrefix}`);
|
|
55051
55073
|
}
|
|
55052
55074
|
lines.push("");
|
|
55053
|
-
lines.push(source_default.dim(" Your API key has been stored
|
|
55054
|
-
lines.push(source_default.dim(" You can
|
|
55075
|
+
lines.push(source_default.dim(" Your API key has been stored locally."));
|
|
55076
|
+
lines.push(source_default.dim(" You can also view it anytime: trading-boy whoami --show-key"));
|
|
55055
55077
|
lines.push("");
|
|
55056
55078
|
lines.push(source_default.cyan(" Try it: trading-boy context SOL"));
|
|
55057
55079
|
lines.push("");
|
package/dist/commands/infra.d.ts
CHANGED
|
@@ -13,8 +13,12 @@ export interface InfraStatusResult {
|
|
|
13
13
|
* Check infrastructure health via the API /health endpoint.
|
|
14
14
|
* Falls back to a basic connectivity check if the API is unreachable.
|
|
15
15
|
*/
|
|
16
|
-
export declare function checkInfraStatus(
|
|
17
|
-
|
|
16
|
+
export declare function checkInfraStatus(options?: {
|
|
17
|
+
remote?: boolean;
|
|
18
|
+
}): Promise<InfraStatusResult>;
|
|
19
|
+
export declare function formatInfraStatus(result: InfraStatusResult, options?: {
|
|
20
|
+
remote?: boolean;
|
|
21
|
+
}): string;
|
|
18
22
|
export declare function registerInfraCommand(program: Command): void;
|
|
19
23
|
export {};
|
|
20
24
|
//# sourceMappingURL=infra.d.ts.map
|
package/dist/commands/infra.js
CHANGED
|
@@ -2,7 +2,7 @@ import { Option } from 'commander';
|
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import { createLogger } from '@trading-boy/core';
|
|
4
4
|
import { padRight } from '../utils.js';
|
|
5
|
-
import { getApiBase } from '../api-client.js';
|
|
5
|
+
import { getApiBase, isRemoteMode } from '../api-client.js';
|
|
6
6
|
// ─── Logger ───
|
|
7
7
|
const logger = createLogger('cli-infra');
|
|
8
8
|
// ─── Health Check Logic ───
|
|
@@ -10,7 +10,7 @@ const logger = createLogger('cli-infra');
|
|
|
10
10
|
* Check infrastructure health via the API /health endpoint.
|
|
11
11
|
* Falls back to a basic connectivity check if the API is unreachable.
|
|
12
12
|
*/
|
|
13
|
-
export async function checkInfraStatus() {
|
|
13
|
+
export async function checkInfraStatus(options) {
|
|
14
14
|
const apiBase = getApiBase();
|
|
15
15
|
try {
|
|
16
16
|
// Call the API health endpoint directly (no auth needed)
|
|
@@ -24,8 +24,8 @@ export async function checkInfraStatus() {
|
|
|
24
24
|
details: apiBase,
|
|
25
25
|
},
|
|
26
26
|
];
|
|
27
|
-
//
|
|
28
|
-
if (data.services) {
|
|
27
|
+
// In remote mode, skip individual DB statuses — they are managed infrastructure
|
|
28
|
+
if (!options?.remote && data.services) {
|
|
29
29
|
if (data.services.neo4j) {
|
|
30
30
|
services.push({
|
|
31
31
|
name: 'Neo4j',
|
|
@@ -48,10 +48,12 @@ export async function checkInfraStatus() {
|
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
// In remote mode, use API response status to determine health
|
|
52
|
+
// (services array only contains API Server, but backend may be degraded)
|
|
53
|
+
const overallHealthy = options?.remote
|
|
54
|
+
? response.ok && data.status === 'ok'
|
|
55
|
+
: services.every((s) => s.healthy);
|
|
56
|
+
return { services, overallHealthy };
|
|
55
57
|
}
|
|
56
58
|
catch (error) {
|
|
57
59
|
// API is unreachable
|
|
@@ -72,7 +74,7 @@ export async function checkInfraStatus() {
|
|
|
72
74
|
function formatStatusIndicator(healthy) {
|
|
73
75
|
return healthy ? chalk.green('\u2713 UP') : chalk.red('\u2717 DOWN');
|
|
74
76
|
}
|
|
75
|
-
export function formatInfraStatus(result) {
|
|
77
|
+
export function formatInfraStatus(result, options) {
|
|
76
78
|
const lines = [];
|
|
77
79
|
lines.push('');
|
|
78
80
|
lines.push(chalk.bold.cyan(' Infrastructure Status'));
|
|
@@ -86,6 +88,10 @@ export function formatInfraStatus(result) {
|
|
|
86
88
|
}
|
|
87
89
|
}
|
|
88
90
|
lines.push('');
|
|
91
|
+
if (options?.remote) {
|
|
92
|
+
lines.push(chalk.dim(' Backend services are managed infrastructure. Contact support if issues persist.'));
|
|
93
|
+
lines.push('');
|
|
94
|
+
}
|
|
89
95
|
if (result.overallHealthy) {
|
|
90
96
|
lines.push(` ${chalk.green.bold('All services healthy.')}`);
|
|
91
97
|
}
|
|
@@ -107,13 +113,14 @@ export function registerInfraCommand(program) {
|
|
|
107
113
|
.addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
|
|
108
114
|
.action(async (options) => {
|
|
109
115
|
try {
|
|
116
|
+
const remote = await isRemoteMode();
|
|
110
117
|
console.log(chalk.gray(' Checking infrastructure health...'));
|
|
111
|
-
const result = await checkInfraStatus();
|
|
118
|
+
const result = await checkInfraStatus({ remote });
|
|
112
119
|
if (options.format === 'json') {
|
|
113
120
|
console.log(JSON.stringify(result, null, 2));
|
|
114
121
|
}
|
|
115
122
|
else {
|
|
116
|
-
console.log(formatInfraStatus(result));
|
|
123
|
+
console.log(formatInfraStatus(result, { remote }));
|
|
117
124
|
}
|
|
118
125
|
if (!result.overallHealthy) {
|
|
119
126
|
process.exitCode = 1;
|
package/dist/commands/login.js
CHANGED
|
@@ -72,6 +72,7 @@ export function registerLoginCommand(program) {
|
|
|
72
72
|
console.log('');
|
|
73
73
|
console.log(chalk.bold(' Trading Boy — Login'));
|
|
74
74
|
console.log(chalk.gray(' ' + '─'.repeat(40)));
|
|
75
|
+
console.log(chalk.dim(' Don\'t have a key? Run: trading-boy subscribe'));
|
|
75
76
|
console.log('');
|
|
76
77
|
apiKey = await password({
|
|
77
78
|
message: 'Enter your API key',
|
|
@@ -112,7 +112,7 @@ export async function runOnboarding() {
|
|
|
112
112
|
}
|
|
113
113
|
console.log('');
|
|
114
114
|
}
|
|
115
|
-
// ─── Step 3: Telegram Bot
|
|
115
|
+
// ─── Step 3: Telegram Bot ───
|
|
116
116
|
try {
|
|
117
117
|
const wantsTelegram = await confirm({
|
|
118
118
|
message: 'Connect Telegram for daily summaries?',
|
|
@@ -136,14 +136,14 @@ export async function runOnboarding() {
|
|
|
136
136
|
throw error;
|
|
137
137
|
}
|
|
138
138
|
console.log('');
|
|
139
|
-
// ─── Step
|
|
139
|
+
// ─── Step 4: Next Steps Cheat Sheet ───
|
|
140
140
|
console.log(chalk.bold.cyan(' Quick Reference'));
|
|
141
141
|
console.log(chalk.gray(' ' + '\u2500'.repeat(50)));
|
|
142
142
|
console.log('');
|
|
143
143
|
console.log(` ${chalk.white('trading-boy context SOL')} ${chalk.dim('Full context for any token')}`);
|
|
144
|
-
console.log(` ${chalk.white('trading-boy journal')}
|
|
144
|
+
console.log(` ${chalk.white('trading-boy journal log entry SOL')} ${chalk.dim('Log a trade entry')}`);
|
|
145
145
|
console.log(` ${chalk.white('trading-boy decisions')} ${chalk.dim('View trade history')}`);
|
|
146
|
-
console.log(` ${chalk.white('trading-boy review daily')}
|
|
146
|
+
console.log(` ${chalk.white('trading-boy journal review daily')} ${chalk.dim('Review your daily trades')}`);
|
|
147
147
|
console.log(` ${chalk.white('trading-boy narrative list')} ${chalk.dim('Active market narratives')}`);
|
|
148
148
|
console.log(` ${chalk.white('trading-boy catalysts')} ${chalk.dim('Upcoming events')}`);
|
|
149
149
|
if (traderRegistered) {
|
|
@@ -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 @TradingBoy1_Bot'));
|
|
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
|
@@ -33,7 +33,7 @@ export function formatWhoamiOutput(result) {
|
|
|
33
33
|
const lines = [];
|
|
34
34
|
lines.push('');
|
|
35
35
|
if (!result.authenticated) {
|
|
36
|
-
lines.push(chalk.dim(' Not authenticated. Run `trading-boy login` to get started.'));
|
|
36
|
+
lines.push(chalk.dim(' Not authenticated. Run `trading-boy login` or `trading-boy subscribe` to get started.'));
|
|
37
37
|
lines.push('');
|
|
38
38
|
return lines.join('\n');
|
|
39
39
|
}
|
|
@@ -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.5.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": {
|