@nxuss/lemma 0.8.1 → 0.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.
Files changed (58) hide show
  1. package/README.md +144 -236
  2. package/dist/cjs/cli/lemma-proxy.d.ts.map +1 -1
  3. package/dist/cjs/cli/lemma-proxy.js +57 -119
  4. package/dist/cjs/cli/lemma-proxy.js.map +1 -1
  5. package/dist/cjs/mcp/tools.d.ts.map +1 -1
  6. package/dist/cjs/mcp/tools.js +868 -0
  7. package/dist/cjs/mcp/tools.js.map +1 -1
  8. package/dist/cjs/observability/IdeContextSync.js +3 -3
  9. package/dist/cjs/observability/IdeContextSync.js.map +1 -1
  10. package/dist/cjs/proxy/ProjectStore.d.ts +2 -0
  11. package/dist/cjs/proxy/ProjectStore.d.ts.map +1 -1
  12. package/dist/cjs/proxy/ProjectStore.js +3 -1
  13. package/dist/cjs/proxy/ProjectStore.js.map +1 -1
  14. package/dist/cjs/proxy/SseRelay.d.ts +4 -25
  15. package/dist/cjs/proxy/SseRelay.d.ts.map +1 -1
  16. package/dist/cjs/proxy/SseRelay.js +60 -63
  17. package/dist/cjs/proxy/SseRelay.js.map +1 -1
  18. package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
  19. package/dist/esm/cli/lemma-proxy.js +29 -91
  20. package/dist/esm/cli/lemma-proxy.js.map +1 -1
  21. package/dist/esm/mcp/tools.d.ts.map +1 -1
  22. package/dist/esm/mcp/tools.js +868 -0
  23. package/dist/esm/mcp/tools.js.map +1 -1
  24. package/dist/esm/observability/IdeContextSync.js +1 -1
  25. package/dist/esm/observability/IdeContextSync.js.map +1 -1
  26. package/dist/esm/proxy/ProjectStore.d.ts +2 -0
  27. package/dist/esm/proxy/ProjectStore.d.ts.map +1 -1
  28. package/dist/esm/proxy/ProjectStore.js +2 -0
  29. package/dist/esm/proxy/ProjectStore.js.map +1 -1
  30. package/dist/esm/proxy/SseRelay.d.ts +4 -25
  31. package/dist/esm/proxy/SseRelay.d.ts.map +1 -1
  32. package/dist/esm/proxy/SseRelay.js +60 -60
  33. package/dist/esm/proxy/SseRelay.js.map +1 -1
  34. package/package.json +1 -1
  35. package/dist/cjs/protocol/iap.d.ts +0 -54
  36. package/dist/cjs/protocol/iap.d.ts.map +0 -1
  37. package/dist/cjs/protocol/iap.js +0 -108
  38. package/dist/cjs/protocol/iap.js.map +0 -1
  39. package/dist/cjs/subconscious/cache.d.ts +0 -34
  40. package/dist/cjs/subconscious/cache.d.ts.map +0 -1
  41. package/dist/cjs/subconscious/cache.js +0 -156
  42. package/dist/cjs/subconscious/cache.js.map +0 -1
  43. package/dist/cjs/subconscious/embeddings.d.ts +0 -25
  44. package/dist/cjs/subconscious/embeddings.d.ts.map +0 -1
  45. package/dist/cjs/subconscious/embeddings.js +0 -65
  46. package/dist/cjs/subconscious/embeddings.js.map +0 -1
  47. package/dist/esm/protocol/iap.d.ts +0 -54
  48. package/dist/esm/protocol/iap.d.ts.map +0 -1
  49. package/dist/esm/protocol/iap.js +0 -104
  50. package/dist/esm/protocol/iap.js.map +0 -1
  51. package/dist/esm/subconscious/cache.d.ts +0 -34
  52. package/dist/esm/subconscious/cache.d.ts.map +0 -1
  53. package/dist/esm/subconscious/cache.js +0 -152
  54. package/dist/esm/subconscious/cache.js.map +0 -1
  55. package/dist/esm/subconscious/embeddings.d.ts +0 -25
  56. package/dist/esm/subconscious/embeddings.d.ts.map +0 -1
  57. package/dist/esm/subconscious/embeddings.js +0 -58
  58. package/dist/esm/subconscious/embeddings.js.map +0 -1
@@ -45,25 +45,22 @@ const SemanticScrubber_1 = __importDefault(require("../security/SemanticScrubber
45
45
  const CloudSyncClient_1 = __importDefault(require("../cloud/CloudSyncClient"));
46
46
  const ContextSqueezer_1 = require("../utils/ContextSqueezer");
47
47
  const AgentMultiplexer_1 = require("../proxy/AgentMultiplexer");
48
+ const SseRelay_1 = require("../proxy/SseRelay");
49
+ const KeyManager_1 = require("../proxy/KeyManager");
50
+ const Gatekeeper_1 = require("../proxy/Gatekeeper");
48
51
  const ProjectRegistry_1 = require("../proxy/ProjectRegistry");
49
52
  const ContextInjector_1 = require("../proxy/ContextInjector");
50
53
  const SavingsLedger_1 = require("../utils/SavingsLedger");
54
+ const ProjectStore_1 = require("../proxy/ProjectStore");
51
55
  const chroma = new chromadb_1.ChromaClient({ host: 'localhost', port: 8000 });
52
56
  const dummyEmbeddingFunction = { generate: (texts) => Promise.resolve([]) };
53
57
  const complexityRouter = new ComplexityRouter_1.default();
54
58
  const semanticScrubber = new SemanticScrubber_1.default();
55
59
  const cloudSync = new CloudSyncClient_1.default();
56
60
  const agentMultiplexer = new AgentMultiplexer_1.AgentMultiplexer();
61
+ const keyManager = new KeyManager_1.KeyManager();
62
+ const gatekeeper = new Gatekeeper_1.Gatekeeper(keyManager);
57
63
  // ── Paths ──────────────────────────────────────────────────────────────────────
58
- const HOME = os_1.default.homedir();
59
- const CACHE_DIR = path_1.default.join(HOME, '.lemma-cache');
60
- const PID_FILE = path_1.default.join(CACHE_DIR, 'proxy.pid');
61
- const PORT_FILE = path_1.default.join(CACHE_DIR, 'proxy.port');
62
- const STATS_FILE = path_1.default.join(CACHE_DIR, 'stats.json');
63
- const USAGE_FILE = path_1.default.join(CACHE_DIR, 'usage.json');
64
- const LICENSE_FILE = path_1.default.join(CACHE_DIR, 'license.json');
65
- const CLIPBOARD_PID_FILE = path_1.default.join(CACHE_DIR, 'clipboard.pid');
66
- const FREE_LIMIT = 300;
67
64
  const VALIDATE_URL = 'https://lemma.nxus.studio/api/validate-license';
68
65
  async function checkDependency(url) {
69
66
  try {
@@ -116,7 +113,7 @@ function detectProject() {
116
113
  }
117
114
  function ensureProjectDir(projectName) {
118
115
  const hash = crypto_1.default.createHash('sha1').update(projectName).digest('hex').slice(0, 12);
119
- const dir = path_1.default.join(CACHE_DIR, hash);
116
+ const dir = path_1.default.join(ProjectStore_1.CACHE_DIR, hash);
120
117
  if (!fs_1.default.existsSync(dir)) {
121
118
  fs_1.default.mkdirSync(dir, { recursive: true });
122
119
  }
@@ -143,7 +140,7 @@ async function ensureChromaRunning() {
143
140
  catch {
144
141
  console.log('⚠️ ChromaDB is not running. Starting it...');
145
142
  const { spawn } = require('child_process');
146
- const cp = spawn('chroma', ['run', '--path', path_1.default.join(CACHE_DIR, 'chroma_data')], {
143
+ const cp = spawn('chroma', ['run', '--path', path_1.default.join(ProjectStore_1.CACHE_DIR, 'chroma_data')], {
147
144
  stdio: 'ignore',
148
145
  detached: true,
149
146
  });
@@ -471,8 +468,8 @@ function startBackgroundClipboardWatcher(cliOpts) {
471
468
  return;
472
469
  }
473
470
  try {
474
- if (fs_1.default.existsSync(CLIPBOARD_PID_FILE)) {
475
- const oldPid = fs_1.default.readFileSync(CLIPBOARD_PID_FILE, 'utf8');
471
+ if (fs_1.default.existsSync(ProjectStore_1.CLIPBOARD_PID_FILE)) {
472
+ const oldPid = fs_1.default.readFileSync(ProjectStore_1.CLIPBOARD_PID_FILE, 'utf8');
476
473
  try {
477
474
  process.kill(parseInt(oldPid, 10), 0); // Check if process is still alive
478
475
  console.log(`✅ [Clipboard] Watcher is already running in background (PID: ${oldPid})`);
@@ -481,7 +478,7 @@ function startBackgroundClipboardWatcher(cliOpts) {
481
478
  catch {
482
479
  // Process is dead, clean up pid file
483
480
  try {
484
- fs_1.default.unlinkSync(CLIPBOARD_PID_FILE);
481
+ fs_1.default.unlinkSync(ProjectStore_1.CLIPBOARD_PID_FILE);
485
482
  }
486
483
  catch { }
487
484
  }
@@ -502,7 +499,7 @@ function startBackgroundClipboardWatcher(cliOpts) {
502
499
  });
503
500
  cp.unref();
504
501
  if (cp.pid) {
505
- fs_1.default.writeFileSync(CLIPBOARD_PID_FILE, String(cp.pid));
502
+ fs_1.default.writeFileSync(ProjectStore_1.CLIPBOARD_PID_FILE, String(cp.pid));
506
503
  console.log(`✅ [Clipboard] Watcher has been started (PID: ${cp.pid})`);
507
504
  }
508
505
  }
@@ -511,21 +508,8 @@ function startBackgroundClipboardWatcher(cliOpts) {
511
508
  }
512
509
  }
513
510
  // ── License helpers ────────────────────────────────────────────────────────────
514
- let isProCached = null;
515
- let lastLicenseCheck = 0;
516
- const LICENSE_CACHE_TTL = 10000; // 10 seconds cache
517
- async function loadLicense() {
518
- return readJson(LICENSE_FILE, { isPro: false });
519
- }
520
- async function isPro() {
521
- const now = Date.now();
522
- if (isProCached !== null && (now - lastLicenseCheck) < LICENSE_CACHE_TTL) {
523
- return isProCached;
524
- }
525
- const l = await loadLicense();
526
- isProCached = !!(l && l.isPro);
527
- lastLicenseCheck = now;
528
- return isProCached;
511
+ function isPro() {
512
+ return gatekeeper.getMode() === 'pro';
529
513
  }
530
514
  async function validateKeyRemote(key) {
531
515
  return new Promise((resolve, reject) => {
@@ -562,7 +546,7 @@ async function validateKeyRemote(key) {
562
546
  }
563
547
  // ── Usage helpers ──────────────────────────────────────────────────────────────
564
548
  async function loadUsage() {
565
- const u = await readJson(USAGE_FILE, { count: 0, lastReset: new Date().toISOString(), history: [] });
549
+ const u = await readJson(ProjectStore_1.USAGE_FILE, { count: 0, lastReset: new Date().toISOString(), history: [] });
566
550
  const now = new Date();
567
551
  const last = new Date(u.lastReset || 0);
568
552
  if (now.getMonth() !== last.getMonth() || now.getFullYear() !== last.getFullYear()) {
@@ -571,14 +555,14 @@ async function loadUsage() {
571
555
  lastReset: now.toISOString(),
572
556
  history: [...(u.history || []), { month: last.toISOString().slice(0, 7), count: u.count }]
573
557
  };
574
- await writeJson(USAGE_FILE, fresh);
558
+ await writeJson(ProjectStore_1.USAGE_FILE, fresh);
575
559
  return fresh;
576
560
  }
577
561
  return u;
578
562
  }
579
563
  // ── Stats helpers ──────────────────────────────────────────────────────────────
580
564
  async function loadStats() {
581
- return readJson(STATS_FILE, {});
565
+ return readJson(ProjectStore_1.STATS_FILE, {});
582
566
  }
583
567
  async function recordStat(stats, project, fromCache, latencyMs, provider, tokensSaved) {
584
568
  if (!stats[project]) {
@@ -604,7 +588,7 @@ async function recordStat(stats, project, fromCache, latencyMs, provider, tokens
604
588
  provider,
605
589
  tokens: tkSaved
606
590
  });
607
- await writeJson(STATS_FILE, stats);
591
+ await writeJson(ProjectStore_1.STATS_FILE, stats);
608
592
  }
609
593
  const CACHE = new Map();
610
594
  const TTL_MS = 86400000 * 7;
@@ -649,7 +633,7 @@ async function getEmbedding(text) {
649
633
  }
650
634
  }
651
635
  async function semanticGet(provider, prompt, projectName = 'global') {
652
- if (!await isPro())
636
+ if (!isPro())
653
637
  return null;
654
638
  const emb = await getEmbedding(prompt);
655
639
  if (!emb)
@@ -742,7 +726,7 @@ async function semanticGet(provider, prompt, projectName = 'global') {
742
726
  return null;
743
727
  }
744
728
  async function semanticSet(provider, prompt, data, projectName = 'global') {
745
- if (!await isPro())
729
+ if (!isPro())
746
730
  return;
747
731
  const emb = await getEmbedding(prompt);
748
732
  if (!emb)
@@ -845,53 +829,6 @@ function setSseHeaders(res, fromCache, similarity, tier) {
845
829
  res.setHeader('X-Lemma-Similarity', (similarity || 1.0).toFixed(3));
846
830
  res.setHeader('X-Lemma-Tier', tier);
847
831
  }
848
- function buildOaiChunk(id, model, text, stop) {
849
- return { id, object: 'chat.completion.chunk', created: Math.floor(Date.now() / 1000), model,
850
- choices: [{ index: 0, delta: stop ? {} : { content: text }, finish_reason: stop ? 'stop' : null }] };
851
- }
852
- function buildAntChunk(text, stop) {
853
- if (stop)
854
- return { type: 'message_stop' };
855
- return { type: 'content_block_delta', index: 0, delta: { type: 'text_delta', text } };
856
- }
857
- function buildGemChunk(text, stop) {
858
- return { candidates: [{ content: { parts: [{ text }] }, finishReason: stop ? 'STOP' : undefined }] };
859
- }
860
- async function simulateHitStream(res, cachedData, provider, model, tier, similarity, cacheHeader = 'HIT') {
861
- setSseHeaders(res, cacheHeader, similarity, tier);
862
- const id = `lemma-${Date.now()}`;
863
- let text = '';
864
- try {
865
- if (provider === 'openai')
866
- text = cachedData?.choices?.[0]?.message?.content || '';
867
- else if (provider === 'anthropic') {
868
- const c = cachedData?.content;
869
- text = Array.isArray(c) ? c.map((x) => x.text || '').join('') : String(c || '');
870
- }
871
- else if (provider === 'gemini') {
872
- text = cachedData?.candidates?.[0]?.content?.parts?.[0]?.text || '';
873
- }
874
- }
875
- catch { }
876
- const chunkSize = 30;
877
- for (let i = 0; i < text.length; i += chunkSize) {
878
- const chunk = text.slice(i, i + chunkSize);
879
- let evt;
880
- if (provider === 'openai')
881
- evt = buildOaiChunk(id, model, chunk, false);
882
- else if (provider === 'anthropic')
883
- evt = buildAntChunk(chunk, false);
884
- else if (provider === 'gemini')
885
- evt = buildGemChunk(chunk, false);
886
- res.write(provider === 'gemini' ? `${JSON.stringify(evt)}\n` : `data: ${JSON.stringify(evt)}\n\n`);
887
- await new Promise(r => setTimeout(r, 15));
888
- }
889
- const stopEvt = provider === 'openai' ? buildOaiChunk(id, model, '', true) : (provider === 'anthropic' ? buildAntChunk('', true) : buildGemChunk('', true));
890
- res.write(provider === 'gemini' ? `${JSON.stringify(stopEvt)}\n` : `data: ${JSON.stringify(stopEvt)}\n\n`);
891
- if (provider !== 'gemini')
892
- res.write('data: [DONE]\n\n');
893
- res.end();
894
- }
895
832
  async function relayMissStream(res, body, provider, tier) {
896
833
  setSseHeaders(res, false, 1.0, tier);
897
834
  const apiKey = provider === 'openai' ? process.env.OPENAI_API_KEY : process.env.ANTHROPIC_API_KEY;
@@ -1001,8 +938,8 @@ class LemmaServer {
1001
938
  }
1002
939
  setupRoutes() {
1003
940
  this.app.get('/health', async (req, res) => {
1004
- const pro = await isPro();
1005
- res.json({ status: 'ok', project: this.projectName, mode: pro ? 'pro' : 'standard', tier: pro ? 'pro' : 'free', port: this.port });
941
+ const gs = gatekeeper.getStatus();
942
+ res.json({ status: 'ok', project: this.projectName, mode: gs.mode, tier: gs.isPro ? 'pro' : 'free', port: this.port });
1006
943
  });
1007
944
  // MCP Status endpoint
1008
945
  this.app.get('/api/mcp-status', (req, res) => {
@@ -1101,7 +1038,7 @@ class LemmaServer {
1101
1038
  activeAgents,
1102
1039
  totalAgents,
1103
1040
  uptime: process.uptime(),
1104
- tier: (await isPro()) ? 'pro' : 'free'
1041
+ tier: (isPro()) ? 'pro' : 'free'
1105
1042
  });
1106
1043
  });
1107
1044
  this.app.get('/api/agents', async (req, res) => {
@@ -1312,7 +1249,7 @@ class LemmaServer {
1312
1249
  totalTokensSaved: 0,
1313
1250
  providers: {}
1314
1251
  };
1315
- writeJson(STATS_FILE, this.stats);
1252
+ writeJson(ProjectStore_1.STATS_FILE, this.stats);
1316
1253
  }
1317
1254
  // Clear Chroma DB collection
1318
1255
  try {
@@ -1536,7 +1473,7 @@ class LemmaServer {
1536
1473
  s.providers['mcp'] = { hits: 0, misses: 0 };
1537
1474
  source === 'cache' ? s.providers['mcp'].hits++ : s.providers['mcp'].misses++;
1538
1475
  // Write updated stats back to disk immediately
1539
- writeJson(STATS_FILE, this.stats);
1476
+ writeJson(ProjectStore_1.STATS_FILE, this.stats);
1540
1477
  // Push to live telemetry logEvent array so the Dashboard event timeline updates instantly!
1541
1478
  logEvent({
1542
1479
  type: source === 'cache' ? 'cache:hit' : source,
@@ -1688,14 +1625,14 @@ class LemmaServer {
1688
1625
  }
1689
1626
  async handleCompletion(req, res, provider) {
1690
1627
  const t0 = Date.now();
1691
- const pro = await isPro();
1628
+ const pro = isPro();
1692
1629
  const tier = pro ? 'pro' : 'standard';
1693
1630
  const isStream = !!req.body.stream;
1694
1631
  let historyTokensSaved = 0;
1695
1632
  if (!pro) {
1696
1633
  const usage = await loadUsage();
1697
- if (usage.count >= FREE_LIMIT) {
1698
- return res.status(429).json({ error: { message: `Free tier limit (${FREE_LIMIT}/mo). Upgrade: https://lemma.nxus.studio/upgrade` } });
1634
+ if (usage.count >= ProjectStore_1.FREE_TIER_LIMIT) {
1635
+ return res.status(429).json({ error: { message: `Free tier limit (${ProjectStore_1.FREE_TIER_LIMIT}/mo). Upgrade: https://lemma.nxus.studio/upgrade` } });
1699
1636
  }
1700
1637
  }
1701
1638
  const rawPrompt = extractPrompt(req.body, provider);
@@ -1714,7 +1651,7 @@ class LemmaServer {
1714
1651
  await recordStat(this.stats, this.projectName, true, Date.now() - t0, provider, cacheTokensSaved);
1715
1652
  const unmaskedData = semanticScrubber.unmask(hit.data, tokenMap);
1716
1653
  if (isStream)
1717
- return simulateHitStream(res, unmaskedData, provider, originalModel, tier, 1.0);
1654
+ return SseRelay_1.SseRelay.simulateHit(res, unmaskedData, { provider: provider, tier, similarity: 1.0 });
1718
1655
  res.setHeader('X-Lemma-Cache', 'HIT');
1719
1656
  res.setHeader('X-Lemma-Similarity', '1.000');
1720
1657
  res.setHeader('X-Lemma-Tier', tier);
@@ -1729,7 +1666,7 @@ class LemmaServer {
1729
1666
  const unmaskedData = semanticScrubber.unmask(semHit.data, tokenMap);
1730
1667
  const cacheHeader = semHit.hiveMind ? 'HIT-HIVE-MIND' : 'HIT';
1731
1668
  if (isStream)
1732
- return simulateHitStream(res, unmaskedData, provider, originalModel, tier, semHit.similarity, cacheHeader);
1669
+ return SseRelay_1.SseRelay.simulateHit(res, unmaskedData, { provider: provider, tier, similarity: semHit.similarity, cacheHeader });
1733
1670
  res.setHeader('X-Lemma-Cache', cacheHeader);
1734
1671
  res.setHeader('X-Lemma-Similarity', semHit.similarity.toFixed(3));
1735
1672
  res.setHeader('X-Lemma-Tier', tier);
@@ -1779,7 +1716,7 @@ Adjusted Answer:`;
1779
1716
  await recordStat(this.stats, this.projectName, true, Date.now() - t0, provider, 2000);
1780
1717
  const unmaskedData = semanticScrubber.unmask(synthesizedData, tokenMap);
1781
1718
  if (isStream) {
1782
- return simulateHitStream(res, unmaskedData, provider, originalModel, tier, semHit.similarity);
1719
+ return SseRelay_1.SseRelay.simulateHit(res, unmaskedData, { provider: provider, tier, similarity: semHit.similarity });
1783
1720
  }
1784
1721
  res.setHeader('X-Lemma-Cache', 'HIT-CARS');
1785
1722
  res.setHeader('X-Lemma-Similarity', semHit.similarity.toFixed(3));
@@ -1799,7 +1736,7 @@ Adjusted Answer:`;
1799
1736
  await recordStat(this.stats, this.projectName, true, Date.now() - t0, provider, 2000);
1800
1737
  const unmaskedData = semanticScrubber.unmask(cloudHit.data, tokenMap);
1801
1738
  if (isStream)
1802
- return simulateHitStream(res, unmaskedData, provider, originalModel, tier, cloudHit.similarity || 0.95);
1739
+ return SseRelay_1.SseRelay.simulateHit(res, unmaskedData, { provider: provider, tier, similarity: cloudHit.similarity || 0.95 });
1803
1740
  res.setHeader('X-Lemma-Cache', 'HIT');
1804
1741
  res.setHeader('X-Lemma-Similarity', (cloudHit.similarity || 0.95).toFixed(3));
1805
1742
  res.setHeader('X-Lemma-Tier', tier);
@@ -1892,7 +1829,7 @@ Adjusted Answer:`;
1892
1829
  await usageWriteQueue.enqueue(async () => {
1893
1830
  const u = await loadUsage();
1894
1831
  u.count++;
1895
- await writeJson(USAGE_FILE, u);
1832
+ await writeJson(ProjectStore_1.USAGE_FILE, u);
1896
1833
  });
1897
1834
  }
1898
1835
  return relayMissStream(res, req.body, provider, tier);
@@ -1908,7 +1845,7 @@ Adjusted Answer:`;
1908
1845
  await usageWriteQueue.enqueue(async () => {
1909
1846
  const u = await loadUsage();
1910
1847
  u.count++;
1911
- await writeJson(USAGE_FILE, u);
1848
+ await writeJson(ProjectStore_1.USAGE_FILE, u);
1912
1849
  });
1913
1850
  }
1914
1851
  await recordStat(this.stats, this.projectName, false, Date.now() - t0, provider, historyTokensSaved);
@@ -2008,8 +1945,8 @@ Adjusted Answer:`;
2008
1945
  });
2009
1946
  const BIND_HOST = process.env.LEMMA_BIND_HOST || '127.0.0.1';
2010
1947
  server.listen(this.port, BIND_HOST, async () => {
2011
- fs_1.default.writeFileSync(PID_FILE, String(process.pid));
2012
- fs_1.default.writeFileSync(PORT_FILE, String(this.port));
1948
+ fs_1.default.writeFileSync(ProjectStore_1.PID_FILE, String(process.pid));
1949
+ fs_1.default.writeFileSync(ProjectStore_1.PORT_FILE, String(this.port));
2013
1950
  // Security warning if binding to all interfaces without auth
2014
1951
  if (BIND_HOST !== '127.0.0.1' && BIND_HOST !== 'localhost') {
2015
1952
  const authEnabled = process.env.AUTH_ENABLED === 'true';
@@ -2018,7 +1955,7 @@ Adjusted Answer:`;
2018
1955
  console.warn(` Set AUTH_ENABLED=true and AUTH_REQUIRE_API_KEY=true before exposing to any network.\x1b[0m\n`);
2019
1956
  }
2020
1957
  }
2021
- const pro = await isPro();
1958
+ const pro = isPro();
2022
1959
  console.log(`\x1b[1m\x1b[35m┌──────────────────────────────────────────────────────────┐\x1b[0m`);
2023
1960
  console.log(`\x1b[1m\x1b[35m│ 🚀 LEMMA PROXY v${VERSION} — THE UNIVERSAL AI GATEWAY │\x1b[0m`);
2024
1961
  console.log(`\x1b[1m\x1b[35m└──────────────────────────────────────────────────────────┘\x1b[0m`);
@@ -2112,7 +2049,7 @@ commander_1.program
2112
2049
  .version(VERSION)
2113
2050
  .addHelpText('after', `
2114
2051
  \x1b[1mPlan Comparison\x1b[0m
2115
- \x1b[32mFree\x1b[0m ${FREE_LIMIT} req/mo · Exact cache · Privacy firewall · MCP tools
2052
+ \x1b[32mFree\x1b[0m ${ProjectStore_1.FREE_TIER_LIMIT} req/mo · Exact cache · Privacy firewall · MCP tools
2116
2053
  \x1b[35mPro\x1b[0m Unlimited · Semantic cache · Cloud sync · Autopilot · Heal
2117
2054
  \x1b[36mhttps://lemma.nxus.studio/upgrade\x1b[0m
2118
2055
 
@@ -2188,7 +2125,7 @@ commander_1.program.command('start')
2188
2125
  const runAutopilot = opts.autopilot || opts.stack;
2189
2126
  if (runAutopilot) {
2190
2127
  try {
2191
- const pro = await isPro();
2128
+ const pro = isPro();
2192
2129
  if (!pro) {
2193
2130
  if (opts.autopilot) {
2194
2131
  console.log(`\n🛸 \x1b[35m[Autopilot]\x1b[0m Active background auto-healing watcher is a Lemma Pro feature.`);
@@ -2211,7 +2148,7 @@ commander_1.program.command('start')
2211
2148
  if (opts.stack) {
2212
2149
  const { spawn } = require('child_process');
2213
2150
  console.log('🚀 Launching Lemma Full Stack...');
2214
- const chromaDataPath = path_1.default.join(CACHE_DIR, 'chroma_data');
2151
+ const chromaDataPath = path_1.default.join(ProjectStore_1.CACHE_DIR, 'chroma_data');
2215
2152
  if (!fs_1.default.existsSync(chromaDataPath)) {
2216
2153
  fs_1.default.mkdirSync(chromaDataPath, { recursive: true });
2217
2154
  }
@@ -2258,8 +2195,8 @@ commander_1.program.command('stop')
2258
2195
  const port = parseInt(opts.port, 10);
2259
2196
  let stopped = false;
2260
2197
  try {
2261
- if (fs_1.default.existsSync(PID_FILE)) {
2262
- const pid = fs_1.default.readFileSync(PID_FILE, 'utf8');
2198
+ if (fs_1.default.existsSync(ProjectStore_1.PID_FILE)) {
2199
+ const pid = fs_1.default.readFileSync(ProjectStore_1.PID_FILE, 'utf8');
2263
2200
  try {
2264
2201
  process.kill(parseInt(pid), 'SIGTERM');
2265
2202
  stopped = true;
@@ -2284,18 +2221,18 @@ commander_1.program.command('stop')
2284
2221
  catch {
2285
2222
  console.log('⚠️ Could not stop process.');
2286
2223
  }
2287
- if (fs_1.default.existsSync(PID_FILE))
2288
- fs_1.default.unlinkSync(PID_FILE);
2224
+ if (fs_1.default.existsSync(ProjectStore_1.PID_FILE))
2225
+ fs_1.default.unlinkSync(ProjectStore_1.PID_FILE);
2289
2226
  // Stop background Clipboard Watcher if active
2290
2227
  try {
2291
- if (fs_1.default.existsSync(CLIPBOARD_PID_FILE)) {
2292
- const cbPid = fs_1.default.readFileSync(CLIPBOARD_PID_FILE, 'utf8');
2228
+ if (fs_1.default.existsSync(ProjectStore_1.CLIPBOARD_PID_FILE)) {
2229
+ const cbPid = fs_1.default.readFileSync(ProjectStore_1.CLIPBOARD_PID_FILE, 'utf8');
2293
2230
  try {
2294
2231
  process.kill(parseInt(cbPid, 10), 'SIGTERM');
2295
2232
  console.log(`✅ Stopped background Clipboard Watcher (PID: ${cbPid})`);
2296
2233
  }
2297
2234
  catch { }
2298
- fs_1.default.unlinkSync(CLIPBOARD_PID_FILE);
2235
+ fs_1.default.unlinkSync(ProjectStore_1.CLIPBOARD_PID_FILE);
2299
2236
  }
2300
2237
  }
2301
2238
  catch { }
@@ -2303,7 +2240,7 @@ commander_1.program.command('stop')
2303
2240
  commander_1.program.command('status')
2304
2241
  .description('Check proxy status')
2305
2242
  .action(async () => {
2306
- const port = fs_1.default.existsSync(PORT_FILE) ? fs_1.default.readFileSync(PORT_FILE, 'utf8') : '8081';
2243
+ const port = fs_1.default.existsSync(ProjectStore_1.PORT_FILE) ? fs_1.default.readFileSync(ProjectStore_1.PORT_FILE, 'utf8') : '8081';
2307
2244
  try {
2308
2245
  const resp = await axios_1.default.get(`http://localhost:${port}/health`, { timeout: 1000 });
2309
2246
  if (resp.data && resp.data.status === 'ok') {
@@ -2315,8 +2252,8 @@ commander_1.program.command('status')
2315
2252
  }
2316
2253
  catch {
2317
2254
  console.log('❌ Stopped');
2318
- if (fs_1.default.existsSync(PID_FILE))
2319
- fs_1.default.unlinkSync(PID_FILE);
2255
+ if (fs_1.default.existsSync(ProjectStore_1.PID_FILE))
2256
+ fs_1.default.unlinkSync(ProjectStore_1.PID_FILE);
2320
2257
  }
2321
2258
  });
2322
2259
  commander_1.program.command('stats')
@@ -2332,9 +2269,9 @@ commander_1.program.command('stats')
2332
2269
  console.log(`Cache Hits : ${s.hits} (${((s.hits / s.total || 0) * 100).toFixed(1)}%)`);
2333
2270
  console.log(`Tokens Saved : ${s.totalTokensSaved.toLocaleString()}`);
2334
2271
  console.log(`Avg Latency : ${(s.totalLatency / (s.total || 1)).toFixed(2)}ms`);
2335
- console.log(`Tier : ${(await isPro()) ? 'PRO' : 'FREE'}`);
2336
- if (!await isPro())
2337
- console.log(`Free Usage : ${usage.count}/${FREE_LIMIT} requests`);
2272
+ console.log(`Tier : ${(isPro()) ? 'PRO' : 'FREE'}`);
2273
+ if (!isPro())
2274
+ console.log(`Free Usage : ${usage.count}/${ProjectStore_1.FREE_TIER_LIMIT} requests`);
2338
2275
  console.log(`──────────────────────────────────\n`);
2339
2276
  });
2340
2277
  commander_1.program.command('activate <key>')
@@ -2349,7 +2286,8 @@ commander_1.program.command('activate <key>')
2349
2286
  try {
2350
2287
  const res = await validateKeyRemote(key.trim());
2351
2288
  if (res.valid) {
2352
- await writeJson(LICENSE_FILE, { key, isPro: true, activatedAt: new Date().toISOString(), validatedRemotely: true });
2289
+ await writeJson(ProjectStore_1.LICENSE_FILE, { key, isPro: true, activatedAt: new Date().toISOString(), validatedRemotely: true });
2290
+ gatekeeper.reload();
2353
2291
  console.log('✅ License activated! Enjoy Pro features (Server-verified).');
2354
2292
  }
2355
2293
  else {
@@ -2590,7 +2528,7 @@ commander_1.program.command('heal')
2590
2528
  .option('--apply', 'Apply the auto-generated code fix automatically', false)
2591
2529
  .action(async (opts) => {
2592
2530
  try {
2593
- const pro = await isPro();
2531
+ const pro = isPro();
2594
2532
  if (!pro) {
2595
2533
  console.log(`\n🩺 \x1b[35m[Heal]\x1b[0m Guided code diagnostics and auto-healing is a Lemma Pro feature.`);
2596
2534
  console.log(`💡 Upgrade to Pro in your Dashboard or visit: \x1b[4mhttps://lemma.nxus.studio/upgrade\x1b[0m\n`);
@@ -2619,7 +2557,7 @@ commander_1.program.command('autopilot')
2619
2557
  .option('--dir <directory>', 'Directory to monitor for changes', 'src')
2620
2558
  .action(async (opts) => {
2621
2559
  try {
2622
- const pro = await isPro();
2560
+ const pro = isPro();
2623
2561
  if (!pro) {
2624
2562
  console.log(`\n🛸 \x1b[35m[Autopilot]\x1b[0m Active background auto-healing watcher is a Lemma Pro feature.`);
2625
2563
  console.log(`💡 Upgrade to Pro in your Dashboard or visit: \x1b[4mhttps://lemma.nxus.studio/upgrade\x1b[0m\n`);