@trading-boy/cli 1.2.15 → 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.
@@ -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 (sensitive values redacted)").addOption(new Option("--format <format>", "Output format").choices(["text", "json"]).default("text")).action((options) => {
49901
- let config2 = null;
49902
- try {
49903
- config2 = getConfig();
49904
- } catch {
49905
- config2 = null;
49906
- }
49907
- if (config2) {
49908
- if (options.format === "json") {
49909
- const configRecord = config2;
49910
- const redacted = {};
49911
- for (const key of VALID_KEYS) {
49912
- const value = configRecord[key];
49913
- redacted[key] = value !== void 0 ? redactValue(key, value) : "";
49914
- }
49915
- console.log(JSON.stringify(redacted, null, 2));
49916
- } else {
49917
- console.log(formatConfigOutput(config2));
49918
- }
49919
- } else {
49920
- console.log(source_default.yellow(" Note: Full config validation unavailable (server env vars not set)\n"));
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
- const value = process.env[key];
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;
49933
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("");
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 {
@@ -1,6 +1,6 @@
1
1
  import { Option } from 'commander';
2
2
  import chalk from 'chalk';
3
- import { getConfig, createLogger } from '@trading-boy/core';
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 (sensitive values redacted)')
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
- let config = null;
226
- try {
227
- config = getConfig();
228
- }
229
- catch {
230
- // Config validation failed (e.g. missing DB passwords in CLI-only mode)
231
- // Fall back to showing raw env vars
232
- config = null;
233
- }
234
- if (config) {
235
- if (options.format === 'json') {
236
- const configRecord = config;
237
- const redacted = {};
238
- for (const key of VALID_KEYS) {
239
- const value = configRecord[key];
240
- redacted[key] = value !== undefined ? redactValue(key, value) : '';
241
- }
242
- console.log(JSON.stringify(redacted, null, 2));
243
- }
244
- else {
245
- console.log(formatConfigOutput(config));
246
- }
247
- }
248
- else {
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
- const value = process.env[key];
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trading-boy/cli",
3
- "version": "1.2.15",
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": {