@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.
@@ -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
- return {
54313
- services,
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")} ${source_default.dim("Log a trade")}`);
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")} ${source_default.dim("Daily performance review")}`);
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.keyPrefix) {
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 securely."));
55054
- lines.push(source_default.dim(" You can now use all Trading Boy commands."));
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("");
@@ -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(): Promise<InfraStatusResult>;
17
- export declare function formatInfraStatus(result: InfraStatusResult): string;
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
@@ -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
- // Parse individual service statuses from the health response
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
- return {
52
- services,
53
- overallHealthy: services.every((s) => s.healthy),
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;
@@ -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 (was Step 2) ───
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 3: Next Steps Cheat Sheet ───
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')} ${chalk.dim('Log a trade')}`);
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')} ${chalk.dim('Daily performance review')}`);
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.keyPrefix) {
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 securely.'));
221
- lines.push(chalk.dim(' You can now use all Trading Boy commands.'));
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('');
@@ -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.4.0",
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": {