@darksol/terminal 0.3.2 → 0.3.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darksol/terminal",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "DARKSOL Terminal — unified CLI for all DARKSOL services. Market intel, trading, oracle, casino, and more.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -611,8 +611,8 @@ export function cli(argv) {
611
611
 
612
612
  const cfg = getAllConfig();
613
613
  const wallet = cfg.activeWallet;
614
- const { hasKey } = await import('./config/keys.js');
615
- const hasLLM = ['openai', 'anthropic', 'openrouter', 'ollama'].some(s => hasKey(s));
614
+ const { hasAnyLLM } = await import('./config/keys.js');
615
+ const hasLLM = hasAnyLLM();
616
616
 
617
617
  // ── Status bar ──
618
618
  const statusParts = [
@@ -351,13 +351,54 @@ export function getKeyAuto(service) {
351
351
  }
352
352
 
353
353
  /**
354
- * Check if any key exists for a service (stored or env)
354
+ * Check if a VALID key exists for a service (stored or env)
355
+ * Actually validates format, not just existence
355
356
  */
356
357
  export function hasKey(service) {
357
- const vault = loadVault();
358
- if (vault.keys[service]) return true;
359
358
  const svc = SERVICES[service];
360
- if (svc?.envVar && process.env[svc.envVar]) return true;
359
+ const vault = loadVault();
360
+
361
+ // Check vault (auto-stored keys)
362
+ if (vault.keys[service]) {
363
+ // If auto-stored, try to decrypt and validate
364
+ if (vault.keys[service].autoStored) {
365
+ try {
366
+ const key = decrypt(vault.keys[service].encrypted, getMachineVaultPass());
367
+ if (svc?.validate && !svc.validate(key)) return false;
368
+ return true;
369
+ } catch { return false; }
370
+ }
371
+ return true; // manually stored keys are assumed valid
372
+ }
373
+
374
+ // Check environment variable
375
+ if (svc?.envVar && process.env[svc.envVar]) {
376
+ const envVal = process.env[svc.envVar];
377
+ // For Ollama, just having OLLAMA_HOST doesn't mean AI is ready
378
+ // — we need actual LLM providers with API keys
379
+ if (service === 'ollama') {
380
+ // Ollama is "ready" if host is set and looks like a URL
381
+ return envVal.startsWith('http') && envVal.length > 10;
382
+ }
383
+ // For API key services, validate the key format
384
+ if (svc.validate) {
385
+ return svc.validate(envVal);
386
+ }
387
+ return envVal.length > 0;
388
+ }
389
+
390
+ return false;
391
+ }
392
+
393
+ /**
394
+ * Quick check: is any LLM provider properly configured?
395
+ * Only returns true if a real API key is validated
396
+ */
397
+ export function hasAnyLLM() {
398
+ // Cloud providers — need real validated API keys
399
+ if (['openai', 'anthropic', 'openrouter'].some(s => hasKey(s))) return true;
400
+ // Ollama — check if explicitly configured via hasKey (validates URL format)
401
+ if (hasKey('ollama')) return true;
361
402
  return false;
362
403
  }
363
404
 
@@ -3,7 +3,7 @@ import { theme } from '../ui/theme.js';
3
3
  import { showSection, showDivider } from '../ui/banner.js';
4
4
  import { success, error, warn, info, kvDisplay } from '../ui/components.js';
5
5
  import { getConfig, setConfig } from '../config/store.js';
6
- import { addKeyDirect, hasKey, SERVICES } from '../config/keys.js';
6
+ import { addKeyDirect, hasKey, hasAnyLLM, SERVICES } from '../config/keys.js';
7
7
  import { createServer } from 'http';
8
8
  import open from 'open';
9
9
  import crypto from 'crypto';
@@ -16,9 +16,9 @@ import crypto from 'crypto';
16
16
  * Check if this is a first run (no LLM keys configured)
17
17
  */
18
18
  export function isFirstRun() {
19
- const hasAnyLLM = ['openai', 'anthropic', 'openrouter', 'ollama'].some(s => hasKey(s));
19
+ const llmReady = hasAnyLLM();
20
20
  const setupDone = getConfig('setupComplete');
21
- return !hasAnyLLM && !setupDone;
21
+ return !llmReady && !setupDone;
22
22
  }
23
23
 
24
24
  /**
package/src/ui/banner.js CHANGED
@@ -26,7 +26,7 @@ export function showBanner(opts = {}) {
26
26
  );
27
27
  console.log(
28
28
  theme.dim(' ║ ') +
29
- theme.subtle(' v0.3.2') +
29
+ theme.subtle(' v0.3.3') +
30
30
  theme.dim(' ') +
31
31
  theme.gold('🌑') +
32
32
  theme.dim(' ║')
@@ -44,7 +44,7 @@ export function showBanner(opts = {}) {
44
44
 
45
45
  export function showMiniBanner() {
46
46
  console.log('');
47
- console.log(theme.gold.bold(' 🌑 DARKSOL TERMINAL') + theme.dim(' v0.3.2'));
47
+ console.log(theme.gold.bold(' 🌑 DARKSOL TERMINAL') + theme.dim(' v0.3.3'));
48
48
  console.log(theme.dim(' ─────────────────────────────'));
49
49
  console.log('');
50
50
  }
@@ -65,3 +65,4 @@ export function showDivider() {
65
65
 
66
66
 
67
67
 
68
+