@trading-boy/cli 1.8.0 → 1.9.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.
@@ -56362,7 +56362,7 @@ function registerConfigCommand(program2) {
56362
56362
  process.exitCode = 1;
56363
56363
  }
56364
56364
  });
56365
- configCmd.command("set-llm-key <apiKey>").description("Store your LLM API key for thesis extraction + coaching (BYOK)").addOption(new Option("-p, --provider <provider>", "LLM provider (auto-detected from key prefix if omitted)").choices(["anthropic", "openai", "openrouter", "ollama", "gemini", "custom"])).option("-m, --model <model>", "Model name (default for all phases)").option("--base-url <url>", "Custom base URL (for openrouter/ollama/custom providers)").option("--scan-model <model>", "Model for market scanning (e.g. claude-haiku-4-5)").option("--analyze-model <model>", "Model for deep analysis (e.g. claude-sonnet-4-6)").option("--decide-model <model>", "Model for trade decisions (e.g. claude-opus-4-6)").action(async (apiKey, opts) => {
56365
+ configCmd.command("set-llm-key <apiKey>").description("Store your LLM API key for thesis extraction + coaching (BYOK)").addOption(new Option("-p, --provider <provider>", "LLM provider (auto-detected from key prefix if omitted)").choices(["anthropic", "openai", "openrouter", "ollama", "gemini", "custom"])).option("-m, --model <model>", "Model name (default for all phases)").option("--base-url <url>", "Custom base URL (for openrouter/ollama/custom providers)").option("--scan-model <model>", "Model for market scanning (e.g. claude-haiku-4-5)").option("--analyze-model <model>", "Model for deep analysis (e.g. claude-sonnet-4-6)").option("--decide-model <model>", "Model for trade decisions (e.g. claude-opus-4-6)").addOption(new Option("--scan-provider <provider>", "Provider for scan phase").choices(["anthropic", "openai", "openrouter", "ollama", "gemini", "custom"])).option("--scan-key <key>", "API key for scan phase provider").addOption(new Option("--analyze-provider <provider>", "Provider for analyze phase").choices(["anthropic", "openai", "openrouter", "ollama", "gemini", "custom"])).option("--analyze-key <key>", "API key for analyze phase provider").addOption(new Option("--decide-provider <provider>", "Provider for decide phase").choices(["anthropic", "openai", "openrouter", "ollama", "gemini", "custom"])).option("--decide-key <key>", "API key for decide phase provider").action(async (apiKey, opts) => {
56366
56366
  try {
56367
56367
  const result = await apiRequest("/api/v1/llm-config", {
56368
56368
  method: "PUT",
@@ -56373,23 +56373,29 @@ function registerConfigCommand(program2) {
56373
56373
  ...opts.baseUrl ? { baseUrl: opts.baseUrl } : {},
56374
56374
  ...opts.scanModel ? { scanModel: opts.scanModel } : {},
56375
56375
  ...opts.analyzeModel ? { analyzeModel: opts.analyzeModel } : {},
56376
- ...opts.decideModel ? { decideModel: opts.decideModel } : {}
56376
+ ...opts.decideModel ? { decideModel: opts.decideModel } : {},
56377
+ ...opts.scanProvider ? { scanProvider: opts.scanProvider } : {},
56378
+ ...opts.scanKey ? { scanApiKey: opts.scanKey } : {},
56379
+ ...opts.analyzeProvider ? { analyzeProvider: opts.analyzeProvider } : {},
56380
+ ...opts.analyzeKey ? { analyzeApiKey: opts.analyzeKey } : {},
56381
+ ...opts.decideProvider ? { decideProvider: opts.decideProvider } : {},
56382
+ ...opts.decideKey ? { decideApiKey: opts.decideKey } : {}
56377
56383
  }
56378
56384
  });
56379
56385
  console.log("");
56380
56386
  console.log(source_default.green(" LLM API key saved successfully"));
56381
- console.log(` ${source_default.gray("Provider:")} ${result.provider}`);
56382
- console.log(` ${source_default.gray("Model:")} ${result.model}`);
56383
- if (result.scanModel) {
56384
- console.log(` ${source_default.gray("Scan model:")} ${result.scanModel}`);
56387
+ console.log(` ${source_default.gray("Provider:")} ${result.provider}`);
56388
+ console.log(` ${source_default.gray("Model:")} ${result.model}`);
56389
+ if (result.scanProvider || result.scanModel) {
56390
+ console.log(` ${source_default.gray("Scan:")} ${result.scanProvider ?? result.provider} / ${result.scanModel ?? result.model}${opts.scanKey ? " (own key)" : ""}`);
56385
56391
  }
56386
- if (result.analyzeModel) {
56387
- console.log(` ${source_default.gray("Analyze model:")} ${result.analyzeModel}`);
56392
+ if (result.analyzeProvider || result.analyzeModel) {
56393
+ console.log(` ${source_default.gray("Analyze:")} ${result.analyzeProvider ?? result.provider} / ${result.analyzeModel ?? result.model}${opts.analyzeKey ? " (own key)" : ""}`);
56388
56394
  }
56389
- if (result.decideModel) {
56390
- console.log(` ${source_default.gray("Decide model:")} ${result.decideModel}`);
56395
+ if (result.decideProvider || result.decideModel) {
56396
+ console.log(` ${source_default.gray("Decide:")} ${result.decideProvider ?? result.provider} / ${result.decideModel ?? result.model}${opts.decideKey ? " (own key)" : ""}`);
56391
56397
  }
56392
- console.log(` ${source_default.gray("Key:")} ${apiKey.slice(0, 8)}${"*".repeat(Math.max(0, apiKey.length - 8))}`);
56398
+ console.log(` ${source_default.gray("Key:")} ${apiKey.slice(0, 8)}${"*".repeat(Math.max(0, apiKey.length - 8))}`);
56393
56399
  console.log("");
56394
56400
  console.log(source_default.dim(" Your key is encrypted at rest. Thesis extraction and coaching are now enabled."));
56395
56401
  console.log("");
@@ -56411,14 +56417,14 @@ function registerConfigCommand(program2) {
56411
56417
  console.log(source_default.gray(" " + "\u2500".repeat(40)));
56412
56418
  console.log(` ${source_default.gray("Provider:")} ${result.provider}`);
56413
56419
  console.log(` ${source_default.gray("Model:")} ${result.model}`);
56414
- if (result.scanModel) {
56415
- console.log(` ${source_default.gray("Scan model:")} ${result.scanModel}`);
56420
+ if (result.scanProvider || result.scanModel) {
56421
+ console.log(` ${source_default.gray("Scan:")} ${result.scanProvider ?? result.provider} / ${result.scanModel ?? result.model}`);
56416
56422
  }
56417
- if (result.analyzeModel) {
56418
- console.log(` ${source_default.gray("Analyze model:")} ${result.analyzeModel}`);
56423
+ if (result.analyzeProvider || result.analyzeModel) {
56424
+ console.log(` ${source_default.gray("Analyze:")} ${result.analyzeProvider ?? result.provider} / ${result.analyzeModel ?? result.model}`);
56419
56425
  }
56420
- if (result.decideModel) {
56421
- console.log(` ${source_default.gray("Decide model:")} ${result.decideModel}`);
56426
+ if (result.decideProvider || result.decideModel) {
56427
+ console.log(` ${source_default.gray("Decide:")} ${result.decideProvider ?? result.provider} / ${result.decideModel ?? result.model}`);
56422
56428
  }
56423
56429
  if (result.baseUrl) {
56424
56430
  console.log(` ${source_default.gray("Base URL:")} ${result.baseUrl}`);
@@ -328,6 +328,12 @@ export function registerConfigCommand(program) {
328
328
  .option('--scan-model <model>', 'Model for market scanning (e.g. claude-haiku-4-5)')
329
329
  .option('--analyze-model <model>', 'Model for deep analysis (e.g. claude-sonnet-4-6)')
330
330
  .option('--decide-model <model>', 'Model for trade decisions (e.g. claude-opus-4-6)')
331
+ .addOption(new Option('--scan-provider <provider>', 'Provider for scan phase').choices(['anthropic', 'openai', 'openrouter', 'ollama', 'gemini', 'custom']))
332
+ .option('--scan-key <key>', 'API key for scan phase provider')
333
+ .addOption(new Option('--analyze-provider <provider>', 'Provider for analyze phase').choices(['anthropic', 'openai', 'openrouter', 'ollama', 'gemini', 'custom']))
334
+ .option('--analyze-key <key>', 'API key for analyze phase provider')
335
+ .addOption(new Option('--decide-provider <provider>', 'Provider for decide phase').choices(['anthropic', 'openai', 'openrouter', 'ollama', 'gemini', 'custom']))
336
+ .option('--decide-key <key>', 'API key for decide phase provider')
331
337
  .action(async (apiKey, opts) => {
332
338
  try {
333
339
  const result = await apiRequest('/api/v1/llm-config', {
@@ -340,22 +346,28 @@ export function registerConfigCommand(program) {
340
346
  ...(opts.scanModel ? { scanModel: opts.scanModel } : {}),
341
347
  ...(opts.analyzeModel ? { analyzeModel: opts.analyzeModel } : {}),
342
348
  ...(opts.decideModel ? { decideModel: opts.decideModel } : {}),
349
+ ...(opts.scanProvider ? { scanProvider: opts.scanProvider } : {}),
350
+ ...(opts.scanKey ? { scanApiKey: opts.scanKey } : {}),
351
+ ...(opts.analyzeProvider ? { analyzeProvider: opts.analyzeProvider } : {}),
352
+ ...(opts.analyzeKey ? { analyzeApiKey: opts.analyzeKey } : {}),
353
+ ...(opts.decideProvider ? { decideProvider: opts.decideProvider } : {}),
354
+ ...(opts.decideKey ? { decideApiKey: opts.decideKey } : {}),
343
355
  },
344
356
  });
345
357
  console.log('');
346
358
  console.log(chalk.green(' LLM API key saved successfully'));
347
- console.log(` ${chalk.gray('Provider:')} ${result.provider}`);
348
- console.log(` ${chalk.gray('Model:')} ${result.model}`);
349
- if (result.scanModel) {
350
- console.log(` ${chalk.gray('Scan model:')} ${result.scanModel}`);
359
+ console.log(` ${chalk.gray('Provider:')} ${result.provider}`);
360
+ console.log(` ${chalk.gray('Model:')} ${result.model}`);
361
+ if (result.scanProvider || result.scanModel) {
362
+ console.log(` ${chalk.gray('Scan:')} ${result.scanProvider ?? result.provider} / ${result.scanModel ?? result.model}${opts.scanKey ? ' (own key)' : ''}`);
351
363
  }
352
- if (result.analyzeModel) {
353
- console.log(` ${chalk.gray('Analyze model:')} ${result.analyzeModel}`);
364
+ if (result.analyzeProvider || result.analyzeModel) {
365
+ console.log(` ${chalk.gray('Analyze:')} ${result.analyzeProvider ?? result.provider} / ${result.analyzeModel ?? result.model}${opts.analyzeKey ? ' (own key)' : ''}`);
354
366
  }
355
- if (result.decideModel) {
356
- console.log(` ${chalk.gray('Decide model:')} ${result.decideModel}`);
367
+ if (result.decideProvider || result.decideModel) {
368
+ console.log(` ${chalk.gray('Decide:')} ${result.decideProvider ?? result.provider} / ${result.decideModel ?? result.model}${opts.decideKey ? ' (own key)' : ''}`);
357
369
  }
358
- console.log(` ${chalk.gray('Key:')} ${apiKey.slice(0, 8)}${'*'.repeat(Math.max(0, apiKey.length - 8))}`);
370
+ console.log(` ${chalk.gray('Key:')} ${apiKey.slice(0, 8)}${'*'.repeat(Math.max(0, apiKey.length - 8))}`);
359
371
  console.log('');
360
372
  console.log(chalk.dim(' Your key is encrypted at rest. Thesis extraction and coaching are now enabled.'));
361
373
  console.log('');
@@ -384,14 +396,14 @@ export function registerConfigCommand(program) {
384
396
  console.log(chalk.gray(' ' + '\u2500'.repeat(40)));
385
397
  console.log(` ${chalk.gray('Provider:')} ${result.provider}`);
386
398
  console.log(` ${chalk.gray('Model:')} ${result.model}`);
387
- if (result.scanModel) {
388
- console.log(` ${chalk.gray('Scan model:')} ${result.scanModel}`);
399
+ if (result.scanProvider || result.scanModel) {
400
+ console.log(` ${chalk.gray('Scan:')} ${result.scanProvider ?? result.provider} / ${result.scanModel ?? result.model}`);
389
401
  }
390
- if (result.analyzeModel) {
391
- console.log(` ${chalk.gray('Analyze model:')} ${result.analyzeModel}`);
402
+ if (result.analyzeProvider || result.analyzeModel) {
403
+ console.log(` ${chalk.gray('Analyze:')} ${result.analyzeProvider ?? result.provider} / ${result.analyzeModel ?? result.model}`);
392
404
  }
393
- if (result.decideModel) {
394
- console.log(` ${chalk.gray('Decide model:')} ${result.decideModel}`);
405
+ if (result.decideProvider || result.decideModel) {
406
+ console.log(` ${chalk.gray('Decide:')} ${result.decideProvider ?? result.provider} / ${result.decideModel ?? result.model}`);
395
407
  }
396
408
  if (result.baseUrl) {
397
409
  console.log(` ${chalk.gray('Base URL:')} ${result.baseUrl}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trading-boy/cli",
3
- "version": "1.8.0",
3
+ "version": "1.9.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": {