@trading-boy/cli 1.2.14 → 1.2.16
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 +66 -88
- package/dist/commands/config-cmd.js +50 -30
- package/dist/commands/logout.js +20 -7
- package/package.json +1 -1
package/dist/cli.bundle.js
CHANGED
|
@@ -39723,21 +39723,6 @@ function date4(params) {
|
|
|
39723
39723
|
// ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/external.js
|
|
39724
39724
|
config(en_default());
|
|
39725
39725
|
|
|
39726
|
-
// ../core/dist/errors/index.js
|
|
39727
|
-
var TradingBoyError = class extends Error {
|
|
39728
|
-
code;
|
|
39729
|
-
constructor(message, code) {
|
|
39730
|
-
super(message);
|
|
39731
|
-
this.name = this.constructor.name;
|
|
39732
|
-
this.code = code;
|
|
39733
|
-
}
|
|
39734
|
-
};
|
|
39735
|
-
var ConfigError = class extends TradingBoyError {
|
|
39736
|
-
constructor(message) {
|
|
39737
|
-
super(message, "CONFIG_ERROR");
|
|
39738
|
-
}
|
|
39739
|
-
};
|
|
39740
|
-
|
|
39741
39726
|
// ../core/dist/config/env.js
|
|
39742
39727
|
import_dotenv.default.config({ quiet: true });
|
|
39743
39728
|
var PRODUCTION_REQUIRED_PASSWORDS = [
|
|
@@ -39853,19 +39838,6 @@ var envSchema = external_exports.object({
|
|
|
39853
39838
|
}
|
|
39854
39839
|
}
|
|
39855
39840
|
});
|
|
39856
|
-
var _config = null;
|
|
39857
|
-
function getConfig() {
|
|
39858
|
-
if (!_config) {
|
|
39859
|
-
const result = envSchema.safeParse(process.env);
|
|
39860
|
-
if (!result.success) {
|
|
39861
|
-
const messages = result.error.issues.map((issue2) => ` - ${issue2.path.join(".")}: ${issue2.message}`).join("\n");
|
|
39862
|
-
throw new ConfigError(`Environment validation failed:
|
|
39863
|
-
${messages}`);
|
|
39864
|
-
}
|
|
39865
|
-
_config = result.data;
|
|
39866
|
-
}
|
|
39867
|
-
return _config;
|
|
39868
|
-
}
|
|
39869
39841
|
|
|
39870
39842
|
// ../core/dist/logging/logger.js
|
|
39871
39843
|
var import_pino = __toESM(require_pino(), 1);
|
|
@@ -49808,37 +49780,6 @@ function redactValue(key, value) {
|
|
|
49808
49780
|
}
|
|
49809
49781
|
return strValue.slice(0, 3) + "****";
|
|
49810
49782
|
}
|
|
49811
|
-
function formatConfigOutput(config2) {
|
|
49812
|
-
const lines = [];
|
|
49813
|
-
lines.push("");
|
|
49814
|
-
lines.push(source_default.bold.cyan(" Configuration"));
|
|
49815
|
-
lines.push(source_default.gray(" " + "\u2500".repeat(60)));
|
|
49816
|
-
lines.push("");
|
|
49817
|
-
const groups = [
|
|
49818
|
-
{ name: "Runtime", keys: ["NODE_ENV", "LOG_LEVEL"] },
|
|
49819
|
-
{ name: "Neo4j", keys: ["NEO4J_URI", "NEO4J_USER", "NEO4J_PASSWORD"] },
|
|
49820
|
-
{ name: "TimescaleDB", keys: ["TIMESCALE_HOST", "TIMESCALE_PORT", "TIMESCALE_USER", "TIMESCALE_PASSWORD", "TIMESCALE_DB"] },
|
|
49821
|
-
{ name: "Redis", keys: ["REDIS_URL", "REDIS_PASSWORD"] },
|
|
49822
|
-
{ name: "Data Sources", keys: ["HELIUS_API_KEY", "COINGECKO_API_KEY", "ALCHEMY_API_KEY", "GLASSNODE_API_KEY", "TWITTER_BEARER_TOKEN"] },
|
|
49823
|
-
{ name: "AI / LLM", keys: ["ANTHROPIC_API_KEY", "LLM_PROVIDER", "LLM_API_KEY", "LLM_BASE_URL", "LLM_MODEL", "LLM_FALLBACK_PROVIDER", "LLM_FALLBACK_MODEL", "LLM_FALLBACK_API_KEY", "LLM_MAX_RETRIES", "LLM_TIMEOUT_MS", "LLM_ENCRYPTION_KEY", "ENABLE_LLM"] },
|
|
49824
|
-
{ name: "Learning", keys: ["BELIEF_HMAC_KEY", "ENABLE_LEARNING", "ENABLE_SOCIAL"] },
|
|
49825
|
-
{ name: "API", keys: ["API_PORT", "API_KEY_HASHES", "API_KEY_AUTH_ENABLED"] },
|
|
49826
|
-
{ name: "Billing", keys: ["STRIPE_SECRET_KEY", "STRIPE_WEBHOOK_SECRET", "STRIPE_PRICE_ID_STARTER", "STRIPE_PRICE_ID_PRO", "STRIPE_PRICE_ID_EDGE", "APP_URL"] },
|
|
49827
|
-
{ name: "Telegram", keys: ["TELEGRAM_BOT_TOKEN", "TELEGRAM_ALLOWED_CHAT_IDS"] },
|
|
49828
|
-
{ name: "Email", keys: ["RESEND_API_KEY", "EMAIL_FROM_ADDRESS", "EMAIL_FROM_NAME", "SMTP_HOST", "SMTP_PORT", "SMTP_USER", "SMTP_PASS", "NOTIFICATION_FROM_EMAIL"] }
|
|
49829
|
-
];
|
|
49830
|
-
const configRecord = config2;
|
|
49831
|
-
for (const group of groups) {
|
|
49832
|
-
lines.push(source_default.bold(` ${group.name}`));
|
|
49833
|
-
for (const key of group.keys) {
|
|
49834
|
-
const value = configRecord[key];
|
|
49835
|
-
const displayValue = value !== void 0 ? redactValue(key, value) : source_default.dim("(not set)");
|
|
49836
|
-
lines.push(` ${source_default.gray(padRight(key, 26))} ${displayValue}`);
|
|
49837
|
-
}
|
|
49838
|
-
lines.push("");
|
|
49839
|
-
}
|
|
49840
|
-
return lines.join("\n");
|
|
49841
|
-
}
|
|
49842
49783
|
function resolveEnvPath() {
|
|
49843
49784
|
return resolve(process.cwd(), ".env");
|
|
49844
49785
|
}
|
|
@@ -49897,31 +49838,32 @@ function writeEnvValue(filePath, key, value) {
|
|
|
49897
49838
|
}
|
|
49898
49839
|
function registerConfigCommand(program2) {
|
|
49899
49840
|
const configCmd = program2.command("config").description("Configuration management commands");
|
|
49900
|
-
configCmd.command("show").description("Display current configuration
|
|
49901
|
-
|
|
49902
|
-
|
|
49903
|
-
|
|
49904
|
-
|
|
49905
|
-
|
|
49906
|
-
|
|
49907
|
-
|
|
49908
|
-
|
|
49909
|
-
|
|
49910
|
-
|
|
49911
|
-
|
|
49912
|
-
|
|
49913
|
-
|
|
49914
|
-
|
|
49915
|
-
|
|
49916
|
-
|
|
49917
|
-
|
|
49918
|
-
|
|
49919
|
-
|
|
49920
|
-
|
|
49841
|
+
configCmd.command("show").description("Display current configuration").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).addOption(new Option("--all", "Show all config variables (including server/infrastructure)")).action((options) => {
|
|
49842
|
+
const USER_CONFIG = [
|
|
49843
|
+
{ section: "Connection", keys: [
|
|
49844
|
+
{ key: "TRADING_BOY_API_URL", label: "API URL" }
|
|
49845
|
+
] },
|
|
49846
|
+
{ section: "LLM (Coaching)", keys: [
|
|
49847
|
+
{ key: "LLM_PROVIDER", label: "Provider" },
|
|
49848
|
+
{ key: "LLM_MODEL", label: "Model" },
|
|
49849
|
+
{ key: "LLM_API_KEY", label: "API Key" },
|
|
49850
|
+
{ key: "LLM_BASE_URL", label: "Base URL" }
|
|
49851
|
+
] },
|
|
49852
|
+
{ section: "Notifications", keys: [
|
|
49853
|
+
{ key: "TELEGRAM_BOT_TOKEN", label: "Telegram Bot" },
|
|
49854
|
+
{ key: "TELEGRAM_ALLOWED_CHAT_IDS", label: "Telegram Chat IDs" }
|
|
49855
|
+
] }
|
|
49856
|
+
];
|
|
49857
|
+
const getEnv = (key) => {
|
|
49858
|
+
const value = process.env[key];
|
|
49859
|
+
if (!value)
|
|
49860
|
+
return source_default.dim("not set");
|
|
49861
|
+
return SENSITIVE_KEYS.has(key) ? redactValue(key, value) : value;
|
|
49862
|
+
};
|
|
49863
|
+
if (options.all) {
|
|
49921
49864
|
const redacted = {};
|
|
49922
49865
|
for (const key of VALID_KEYS) {
|
|
49923
|
-
|
|
49924
|
-
redacted[key] = value !== void 0 ? redactValue(key, value) : source_default.dim("(not set)");
|
|
49866
|
+
redacted[key] = getEnv(key);
|
|
49925
49867
|
}
|
|
49926
49868
|
if (options.format === "json") {
|
|
49927
49869
|
console.log(JSON.stringify(redacted, null, 2));
|
|
@@ -49930,7 +49872,29 @@ function registerConfigCommand(program2) {
|
|
|
49930
49872
|
console.log(` ${source_default.cyan(key.padEnd(30))} ${value}`);
|
|
49931
49873
|
}
|
|
49932
49874
|
}
|
|
49875
|
+
return;
|
|
49876
|
+
}
|
|
49877
|
+
if (options.format === "json") {
|
|
49878
|
+
const result = {};
|
|
49879
|
+
for (const section of USER_CONFIG) {
|
|
49880
|
+
for (const { key } of section.keys) {
|
|
49881
|
+
result[key] = process.env[key] ?? "";
|
|
49882
|
+
}
|
|
49883
|
+
}
|
|
49884
|
+
console.log(JSON.stringify(result, null, 2));
|
|
49885
|
+
return;
|
|
49886
|
+
}
|
|
49887
|
+
console.log("");
|
|
49888
|
+
for (const section of USER_CONFIG) {
|
|
49889
|
+
console.log(source_default.bold(` ${section.section}`));
|
|
49890
|
+
console.log(source_default.gray(" " + "\u2500".repeat(40)));
|
|
49891
|
+
for (const { key, label } of section.keys) {
|
|
49892
|
+
console.log(` ${source_default.cyan(label.padEnd(22))} ${getEnv(key)}`);
|
|
49893
|
+
}
|
|
49894
|
+
console.log("");
|
|
49933
49895
|
}
|
|
49896
|
+
console.log(source_default.dim(" Use --all to show all config variables."));
|
|
49897
|
+
console.log("");
|
|
49934
49898
|
});
|
|
49935
49899
|
configCmd.command("set <key> <value>").description("Set a config value in the .env file").action((key, value) => {
|
|
49936
49900
|
try {
|
|
@@ -50252,6 +50216,7 @@ function registerLoginCommand(program2) {
|
|
|
50252
50216
|
|
|
50253
50217
|
// dist/commands/logout.js
|
|
50254
50218
|
init_source();
|
|
50219
|
+
init_esm15();
|
|
50255
50220
|
var logger20 = createLogger("cli-logout");
|
|
50256
50221
|
async function executeLogout() {
|
|
50257
50222
|
const existing = await loadCredentials();
|
|
@@ -50263,15 +50228,28 @@ async function executeLogout() {
|
|
|
50263
50228
|
function registerLogoutCommand(program2) {
|
|
50264
50229
|
program2.command("logout").description("Clear stored API key and credentials").action(async () => {
|
|
50265
50230
|
try {
|
|
50266
|
-
const
|
|
50267
|
-
|
|
50268
|
-
|
|
50269
|
-
console.log(source_default.green(` Logged out successfully.`));
|
|
50270
|
-
console.log(` ${source_default.gray("Cleared key:")} ${result.redactedKey}`);
|
|
50271
|
-
} else {
|
|
50231
|
+
const existing = await loadCredentials();
|
|
50232
|
+
if (!existing) {
|
|
50233
|
+
console.log("");
|
|
50272
50234
|
console.log(source_default.dim(" No credentials found \u2014 already logged out."));
|
|
50235
|
+
console.log("");
|
|
50236
|
+
return;
|
|
50273
50237
|
}
|
|
50274
50238
|
console.log("");
|
|
50239
|
+
console.log(source_default.yellow(" Warning: Your API key will be cleared from this machine."));
|
|
50240
|
+
console.log(source_default.yellow(" You will need your API key to log back in."));
|
|
50241
|
+
console.log(source_default.yellow(" There is no way to recover a lost key \u2014 a new one must be provisioned."));
|
|
50242
|
+
console.log("");
|
|
50243
|
+
const proceed = await esm_default4({ message: "Are you sure you want to logout?" });
|
|
50244
|
+
if (!proceed) {
|
|
50245
|
+
console.log(source_default.dim(" Logout cancelled."));
|
|
50246
|
+
return;
|
|
50247
|
+
}
|
|
50248
|
+
const result = await executeLogout();
|
|
50249
|
+
console.log("");
|
|
50250
|
+
console.log(source_default.green(` Logged out successfully.`));
|
|
50251
|
+
console.log(` ${source_default.gray("Cleared key:")} ${result.redactedKey}`);
|
|
50252
|
+
console.log("");
|
|
50275
50253
|
} catch (error49) {
|
|
50276
50254
|
const message = error49 instanceof Error ? error49.message : String(error49);
|
|
50277
50255
|
logger20.error({ error: message }, "Logout failed");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Option } from 'commander';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import {
|
|
3
|
+
import { createLogger } from '@trading-boy/core';
|
|
4
4
|
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
|
|
5
5
|
import { resolve } from 'node:path';
|
|
6
6
|
import { apiRequest, ApiError } from '../api-client.js';
|
|
@@ -219,39 +219,37 @@ export function registerConfigCommand(program) {
|
|
|
219
219
|
// ─── config show ───
|
|
220
220
|
configCmd
|
|
221
221
|
.command('show')
|
|
222
|
-
.description('Display current configuration
|
|
222
|
+
.description('Display current configuration')
|
|
223
223
|
.addOption(new Option('--format <format>', 'Output format').choices(['text', 'json']).default('text'))
|
|
224
|
+
.addOption(new Option('--all', 'Show all config variables (including server/infrastructure)'))
|
|
224
225
|
.action((options) => {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
// Graceful fallback: show available env vars without full validation
|
|
250
|
-
console.log(chalk.yellow(' Note: Full config validation unavailable (server env vars not set)\n'));
|
|
226
|
+
// User-facing config: only what a CLI user cares about
|
|
227
|
+
const USER_CONFIG = [
|
|
228
|
+
{ section: 'Connection', keys: [
|
|
229
|
+
{ key: 'TRADING_BOY_API_URL', label: 'API URL' },
|
|
230
|
+
] },
|
|
231
|
+
{ section: 'LLM (Coaching)', keys: [
|
|
232
|
+
{ key: 'LLM_PROVIDER', label: 'Provider' },
|
|
233
|
+
{ key: 'LLM_MODEL', label: 'Model' },
|
|
234
|
+
{ key: 'LLM_API_KEY', label: 'API Key' },
|
|
235
|
+
{ key: 'LLM_BASE_URL', label: 'Base URL' },
|
|
236
|
+
] },
|
|
237
|
+
{ section: 'Notifications', keys: [
|
|
238
|
+
{ key: 'TELEGRAM_BOT_TOKEN', label: 'Telegram Bot' },
|
|
239
|
+
{ key: 'TELEGRAM_ALLOWED_CHAT_IDS', label: 'Telegram Chat IDs' },
|
|
240
|
+
] },
|
|
241
|
+
];
|
|
242
|
+
const getEnv = (key) => {
|
|
243
|
+
const value = process.env[key];
|
|
244
|
+
if (!value)
|
|
245
|
+
return chalk.dim('not set');
|
|
246
|
+
return SENSITIVE_KEYS.has(key) ? redactValue(key, value) : value;
|
|
247
|
+
};
|
|
248
|
+
if (options.all) {
|
|
249
|
+
// Full dump for developers
|
|
251
250
|
const redacted = {};
|
|
252
251
|
for (const key of VALID_KEYS) {
|
|
253
|
-
|
|
254
|
-
redacted[key] = value !== undefined ? redactValue(key, value) : chalk.dim('(not set)');
|
|
252
|
+
redacted[key] = getEnv(key);
|
|
255
253
|
}
|
|
256
254
|
if (options.format === 'json') {
|
|
257
255
|
console.log(JSON.stringify(redacted, null, 2));
|
|
@@ -261,7 +259,29 @@ export function registerConfigCommand(program) {
|
|
|
261
259
|
console.log(` ${chalk.cyan(key.padEnd(30))} ${value}`);
|
|
262
260
|
}
|
|
263
261
|
}
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
if (options.format === 'json') {
|
|
265
|
+
const result = {};
|
|
266
|
+
for (const section of USER_CONFIG) {
|
|
267
|
+
for (const { key } of section.keys) {
|
|
268
|
+
result[key] = process.env[key] ?? '';
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
console.log(JSON.stringify(result, null, 2));
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
console.log('');
|
|
275
|
+
for (const section of USER_CONFIG) {
|
|
276
|
+
console.log(chalk.bold(` ${section.section}`));
|
|
277
|
+
console.log(chalk.gray(' ' + '─'.repeat(40)));
|
|
278
|
+
for (const { key, label } of section.keys) {
|
|
279
|
+
console.log(` ${chalk.cyan(label.padEnd(22))} ${getEnv(key)}`);
|
|
280
|
+
}
|
|
281
|
+
console.log('');
|
|
264
282
|
}
|
|
283
|
+
console.log(chalk.dim(' Use --all to show all config variables.'));
|
|
284
|
+
console.log('');
|
|
265
285
|
});
|
|
266
286
|
// ─── config set ───
|
|
267
287
|
configCmd
|
package/dist/commands/logout.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { createLogger } from '@trading-boy/core';
|
|
3
3
|
import { clearCredentials, loadCredentials, redactApiKey } from '../credentials.js';
|
|
4
|
+
import { confirm } from '@inquirer/prompts';
|
|
4
5
|
const logger = createLogger('cli-logout');
|
|
5
6
|
// ─── Logout Logic ───
|
|
6
7
|
export async function executeLogout() {
|
|
@@ -17,15 +18,27 @@ export function registerLogoutCommand(program) {
|
|
|
17
18
|
.description('Clear stored API key and credentials')
|
|
18
19
|
.action(async () => {
|
|
19
20
|
try {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
console.log(chalk.green(` Logged out successfully.`));
|
|
24
|
-
console.log(` ${chalk.gray('Cleared key:')} ${result.redactedKey}`);
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
21
|
+
const existing = await loadCredentials();
|
|
22
|
+
if (!existing) {
|
|
23
|
+
console.log('');
|
|
27
24
|
console.log(chalk.dim(' No credentials found — already logged out.'));
|
|
25
|
+
console.log('');
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
console.log('');
|
|
29
|
+
console.log(chalk.yellow(' Warning: Your API key will be cleared from this machine.'));
|
|
30
|
+
console.log(chalk.yellow(' You will need your API key to log back in.'));
|
|
31
|
+
console.log(chalk.yellow(' There is no way to recover a lost key — a new one must be provisioned.'));
|
|
32
|
+
console.log('');
|
|
33
|
+
const proceed = await confirm({ message: 'Are you sure you want to logout?' });
|
|
34
|
+
if (!proceed) {
|
|
35
|
+
console.log(chalk.dim(' Logout cancelled.'));
|
|
36
|
+
return;
|
|
28
37
|
}
|
|
38
|
+
const result = await executeLogout();
|
|
39
|
+
console.log('');
|
|
40
|
+
console.log(chalk.green(` Logged out successfully.`));
|
|
41
|
+
console.log(` ${chalk.gray('Cleared key:')} ${result.redactedKey}`);
|
|
29
42
|
console.log('');
|
|
30
43
|
}
|
|
31
44
|
catch (error) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trading-boy/cli",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.16",
|
|
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": {
|