@nxuss/lemma 0.7.9 → 0.8.1

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 (68) hide show
  1. package/README.md +86 -5
  2. package/dist/cjs/cli/lemma-proxy.d.ts.map +1 -1
  3. package/dist/cjs/cli/lemma-proxy.js +76 -14
  4. package/dist/cjs/cli/lemma-proxy.js.map +1 -1
  5. package/dist/cjs/cloud/server.d.ts.map +1 -1
  6. package/dist/cjs/cloud/server.js +81 -3
  7. package/dist/cjs/cloud/server.js.map +1 -1
  8. package/dist/cjs/config/index.d.ts.map +1 -1
  9. package/dist/cjs/config/index.js +2 -1
  10. package/dist/cjs/config/index.js.map +1 -1
  11. package/dist/cjs/mcp/index.js +1 -0
  12. package/dist/cjs/mcp/index.js.map +1 -1
  13. package/dist/cjs/mcp/prompts.d.ts +1 -0
  14. package/dist/cjs/mcp/prompts.d.ts.map +1 -1
  15. package/dist/cjs/mcp/prompts.js +58 -1
  16. package/dist/cjs/mcp/prompts.js.map +1 -1
  17. package/dist/cjs/mcp/resources.d.ts.map +1 -1
  18. package/dist/cjs/mcp/resources.js +3 -2
  19. package/dist/cjs/mcp/resources.js.map +1 -1
  20. package/dist/cjs/mcp/tools.d.ts.map +1 -1
  21. package/dist/cjs/mcp/tools.js +311 -10
  22. package/dist/cjs/mcp/tools.js.map +1 -1
  23. package/dist/cjs/mcp/utils.d.ts +13 -0
  24. package/dist/cjs/mcp/utils.d.ts.map +1 -1
  25. package/dist/cjs/mcp/utils.js +63 -2
  26. package/dist/cjs/mcp/utils.js.map +1 -1
  27. package/dist/cjs/proxy/KeyManager.d.ts.map +1 -1
  28. package/dist/cjs/proxy/KeyManager.js +9 -1
  29. package/dist/cjs/proxy/KeyManager.js.map +1 -1
  30. package/dist/cjs/types/index.d.ts +1 -0
  31. package/dist/cjs/types/index.d.ts.map +1 -1
  32. package/dist/cjs/utils/reportSavings.d.ts.map +1 -1
  33. package/dist/cjs/utils/reportSavings.js +2 -2
  34. package/dist/cjs/utils/reportSavings.js.map +1 -1
  35. package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
  36. package/dist/esm/cli/lemma-proxy.js +76 -14
  37. package/dist/esm/cli/lemma-proxy.js.map +1 -1
  38. package/dist/esm/cloud/server.d.ts.map +1 -1
  39. package/dist/esm/cloud/server.js +81 -3
  40. package/dist/esm/cloud/server.js.map +1 -1
  41. package/dist/esm/config/index.d.ts.map +1 -1
  42. package/dist/esm/config/index.js +2 -1
  43. package/dist/esm/config/index.js.map +1 -1
  44. package/dist/esm/mcp/index.js +2 -1
  45. package/dist/esm/mcp/index.js.map +1 -1
  46. package/dist/esm/mcp/prompts.d.ts +1 -0
  47. package/dist/esm/mcp/prompts.d.ts.map +1 -1
  48. package/dist/esm/mcp/prompts.js +57 -0
  49. package/dist/esm/mcp/prompts.js.map +1 -1
  50. package/dist/esm/mcp/resources.d.ts.map +1 -1
  51. package/dist/esm/mcp/resources.js +3 -2
  52. package/dist/esm/mcp/resources.js.map +1 -1
  53. package/dist/esm/mcp/tools.d.ts.map +1 -1
  54. package/dist/esm/mcp/tools.js +312 -11
  55. package/dist/esm/mcp/tools.js.map +1 -1
  56. package/dist/esm/mcp/utils.d.ts +13 -0
  57. package/dist/esm/mcp/utils.d.ts.map +1 -1
  58. package/dist/esm/mcp/utils.js +61 -2
  59. package/dist/esm/mcp/utils.js.map +1 -1
  60. package/dist/esm/proxy/KeyManager.d.ts.map +1 -1
  61. package/dist/esm/proxy/KeyManager.js +9 -1
  62. package/dist/esm/proxy/KeyManager.js.map +1 -1
  63. package/dist/esm/types/index.d.ts +1 -0
  64. package/dist/esm/types/index.d.ts.map +1 -1
  65. package/dist/esm/utils/reportSavings.d.ts.map +1 -1
  66. package/dist/esm/utils/reportSavings.js +2 -2
  67. package/dist/esm/utils/reportSavings.js.map +1 -1
  68. package/package.json +4 -1
package/README.md CHANGED
@@ -1,11 +1,11 @@
1
- # 🧠 Lemma v0.7.8
1
+ # 🧠 Lemma v0.8.1
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@nxuss/lemma.svg?color=orange&style=flat-square)](https://www.npmjs.com/package/@nxuss/lemma)
4
4
  [![License](https://img.shields.io/npm/l/@nxuss/lemma.svg?color=blue&style=flat-square)](https://github.com/Nxusbets/lemma/blob/main/LICENSE)
5
5
  [![Build Status](https://img.shields.io/badge/tests-139%20passed-brightgreen.svg?style=flat-square)](https://github.com/Nxusbets/lemma)
6
6
  [![Security](https://img.shields.io/badge/privacy-firewall%20active-blueviolet?style=flat-square)](https://github.com/Nxusbets/lemma)
7
7
  [![Caching](https://img.shields.io/badge/semantic%20memory-enabled-success?style=flat-square)](https://github.com/Nxusbets/lemma)
8
- [![MCP Tools](https://img.shields.io/badge/MCP%20tools-21-ff69b4?style=flat-square)](https://github.com/Nxusbets/lemma)
8
+ [![MCP Tools](https://img.shields.io/badge/MCP%20tools-25-ff69b4?style=flat-square)](https://github.com/Nxusbets/lemma)
9
9
 
10
10
  ```text
11
11
  __
@@ -154,9 +154,9 @@ Create or edit `lemma.config.json` in your project root to disable or fine-tune
154
154
 
155
155
  ---
156
156
 
157
- ## 🛠️ MCP Tools Reference (v0.7.821 Tools)
157
+ ## 🛠️ MCP Tools Reference (v0.8.025 Tools)
158
158
 
159
- When connected via `lemma mcp`, your Chat IDE gains access to **21 native tools** covering workspace navigation, code safety, semantic memory, AI cost optimization, and autonomous project context injection.
159
+ When connected via `lemma mcp`, your Chat IDE gains access to **25 native tools** covering workspace navigation, code safety, semantic memory, AI cost optimization, autonomous project context injection, and TurboMode optimization.
160
160
 
161
161
  ### 🗂️ Workspace Tools
162
162
 
@@ -198,6 +198,32 @@ When connected via `lemma mcp`, your Chat IDE gains access to **21 native tools*
198
198
  | `get_routing_advice` | Analyze a prompt and get the optimal model recommendation from the Complexity Router. |
199
199
  | `auto_heal` | Diagnose and auto-heal the latest local server crash from Lemma's live context logs. |
200
200
  | `get_project_onboarding` | Download a one-shot architectural mental model of the current project codebase. |
201
+ | `turbosqueeze` | Extreme prompt compression — strips comments, imports, whitespace, compacts JSON. |
202
+ | `compress_context` | Summarize old conversation turns via Ollama (fallback: truncation). |
203
+ | `smarter_cache` | Predictive cache — queries The Brain at 75% threshold before reasoning. |
204
+ | `token_budget` | Optimization dashboard with multiplier, savings, and recommendations. |
205
+
206
+ ### 🚀 TurboMode Tools (NEW in v0.8.0)
207
+
208
+ | Tool | Description |
209
+ | :--- | :--- |
210
+ | `turbosqueeze` | **Extreme prompt compression.** Strips comments, imports, whitespace, and compacts JSON. Returns reduction stats and reports savings to proxy ledger. |
211
+ | `compress_context` | **Conversation summarization.** Summarizes old turns via Ollama (falls back to truncation), keeps last N turns intact, reports token savings. |
212
+ | `smarter_cache` | **Predictive cache.** Queries The Brain at 75% threshold before any reasoning, auto-suggests `store_memory` on MISS. |
213
+ | `token_budget` | **Optimization dashboard.** Displays current multiplier, tokens saved, tool calls, and optimization recommendations. |
214
+
215
+ ### ⚡ TurboMode Auto-Injection
216
+ When connected via `lemma mcp`, Lemma automatically injects 7 TurboMode rules into the agent's system prompt during handshake — no manual prompt loading required:
217
+ 1. `turbosqueeze` before writing code
218
+ 2. `smarter_cache` before any reasoning
219
+ 3. `compress_context` every turn
220
+ 4. `store_memory` after every solution
221
+ 5. `get_ast_hologram` before reading files
222
+ 6. `batch_tool_calls` for parallel operations
223
+ 7. No fluff or chit-chat
224
+
225
+ ### 📡 Dashboard MCP Toggle
226
+ The Dashboard Header now shows a **clickable MCP status badge** — click to enable/disable MCP integration instantly. The badge cycles through `active` (cyan), `idle` (gray), and `offline` (red) states.
201
227
 
202
228
  ### 📡 MCP Resources
203
229
 
@@ -252,7 +278,7 @@ For **Lemma Pro** users, expose Lemma's entire intelligence layer — Privacy Fi
252
278
  * **Name**: `Lemma`
253
279
  * **Type**: `command`
254
280
  * **Command**: `lemma mcp`
255
- 4. Click **Save**. A green **"Connected"** dot will appear, confirming that the IDE has loaded all 21 of Lemma's tools.
281
+ 4. Click **Save**. A green **"Connected"** dot will appear, confirming that the IDE has loaded all 25 of Lemma's tools.
256
282
 
257
283
  #### 🟢 Claude Desktop:
258
284
  Add the following to your `claude_desktop_config.json` configuration file:
@@ -276,4 +302,59 @@ Add the following to your `claude_desktop_config.json` configuration file:
276
302
 
277
303
  ---
278
304
 
305
+ ## 🔒 Security & Privacy
306
+
307
+ ### Network Binding
308
+ By default, Lemma binds only to `127.0.0.1` (localhost). It is **not accessible from the network** unless you explicitly set:
309
+ ```env
310
+ LEMMA_BIND_HOST=0.0.0.0
311
+ ```
312
+ > ⚠️ If you do expose Lemma to the network, always enable authentication first:
313
+ > ```env
314
+ > AUTH_ENABLED=true
315
+ > AUTH_REQUIRE_API_KEY=true
316
+ > AUTH_ALLOWED_ORIGINS=https://yourdomain.com
317
+ > ```
318
+
319
+ ### 📋 Clipboard Watcher Disclosure
320
+ The **Clipboard Telepathic Watcher** polls your system clipboard every 1 second to automatically compress code you copy. This is disclosed in the startup banner. To disable it:
321
+ ```env
322
+ # In your .env
323
+ LEMMA_DISABLE_CLIPBOARD=true
324
+ ```
325
+ Or via CLI flag: `lemma start --no-clipboard`
326
+
327
+ ### MCP Command Allowlist
328
+ The `run_workspace_command` MCP tool only executes commands from an allowlist. Default safe prefixes include `npm`, `npx`, `git`, `tsc`, `node`, `jest`, `eslint`, `ls`, `grep`, and more.
329
+
330
+ To extend the allowlist for your project, add to `lemma.config.json`:
331
+ ```json
332
+ {
333
+ "mcp": {
334
+ "allowedCommandPrefixes": ["your-tool", "another-cmd"]
335
+ }
336
+ }
337
+ ```
338
+
339
+ ### License Security (Cloud Server)
340
+ When running the cloud server in production, set a private license salt:
341
+ ```env
342
+ # Generate with: openssl rand -hex 32
343
+ LEMMA_LICENSE_SALT=your-random-64-char-hex-string
344
+ ```
345
+
346
+ ### Stripe Webhooks (Cloud Server)
347
+ The Stripe webhook endpoint requires a webhook signing secret in production:
348
+ ```env
349
+ STRIPE_WEBHOOK_SECRET=whsec_...
350
+ ```
351
+ Get this from **Stripe Dashboard → Developers → Webhooks → Signing Secret**. Without it, the endpoint is disabled in `NODE_ENV=production`.
352
+
353
+ For local testing: `STRIPE_SKIP_SIGNATURE_VERIFY=true`
354
+
355
+ ### Full Security Template
356
+ See [`.env.security.example`](.env.security.example) for all security-related environment variables.
357
+
358
+ ---
359
+
279
360
  MIT © Nxus Studio | [Upgrade to Lemma Pro](https://lemma.nxus.studio/upgrade)
@@ -1 +1 @@
1
- {"version":3,"file":"lemma-proxy.d.ts","sourceRoot":"","sources":["../../../src/cli/lemma-proxy.ts"],"names":[],"mappings":";AAqZA,wBAAgB,+BAA+B,CAAC,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CA4DvF;AAkiED,wBAAsB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA6KhL"}
1
+ {"version":3,"file":"lemma-proxy.d.ts","sourceRoot":"","sources":["../../../src/cli/lemma-proxy.ts"],"names":[],"mappings":";AA0bA,wBAAgB,+BAA+B,CAAC,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CA4DvF;AA2jED,wBAAsB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA6KhL"}
@@ -14,6 +14,7 @@ const crypto_1 = __importDefault(require("crypto"));
14
14
  const chromadb_1 = require("chromadb");
15
15
  const https_1 = __importDefault(require("https"));
16
16
  const http_1 = __importDefault(require("http"));
17
+ const os_1 = __importDefault(require("os"));
17
18
  const axios_1 = __importDefault(require("axios"));
18
19
  const readline_1 = __importDefault(require("readline"));
19
20
  function getVersion() {
@@ -54,7 +55,7 @@ const semanticScrubber = new SemanticScrubber_1.default();
54
55
  const cloudSync = new CloudSyncClient_1.default();
55
56
  const agentMultiplexer = new AgentMultiplexer_1.AgentMultiplexer();
56
57
  // ── Paths ──────────────────────────────────────────────────────────────────────
57
- const HOME = process.env.HOME || process.env.USERPROFILE || '~';
58
+ const HOME = os_1.default.homedir();
58
59
  const CACHE_DIR = path_1.default.join(HOME, '.lemma-cache');
59
60
  const PID_FILE = path_1.default.join(CACHE_DIR, 'proxy.pid');
60
61
  const PORT_FILE = path_1.default.join(CACHE_DIR, 'proxy.port');
@@ -168,7 +169,7 @@ function autoConfigureAll(project, opts) {
168
169
  fs_1.default.mkdirSync(mcpDir, { recursive: true });
169
170
  }
170
171
  // Register lemma MCP server in Claude Desktop config
171
- const claudeConfigDir = path_1.default.join(process.env.HOME || '~', 'Library', 'Application Support', 'Claude');
172
+ const claudeConfigDir = path_1.default.join(os_1.default.homedir(), 'Library', 'Application Support', 'Claude');
172
173
  const claudeConfigFile = path_1.default.join(claudeConfigDir, 'claude_desktop_config.json');
173
174
  if (fs_1.default.existsSync(claudeConfigDir)) {
174
175
  let claudeConfig = { mcpServers: {} };
@@ -194,7 +195,7 @@ function autoConfigureAll(project, opts) {
194
195
  }
195
196
  }
196
197
  // Register lemma MCP server in Cursor config
197
- const cursorConfigDir = path_1.default.join(process.env.HOME || '~', '.cursor');
198
+ const cursorConfigDir = path_1.default.join(os_1.default.homedir(), '.cursor');
198
199
  const cursorConfigFile = path_1.default.join(cursorConfigDir, 'mcp.json');
199
200
  if (fs_1.default.existsSync(cursorConfigDir)) {
200
201
  let cursorConfig = { mcpServers: {} };
@@ -219,7 +220,7 @@ function autoConfigureAll(project, opts) {
219
220
  }
220
221
  }
221
222
  // Register lemma MCP server in Windsurf config
222
- const windsurfConfigDir = path_1.default.join(process.env.HOME || '~', '.codeium', 'windsurf');
223
+ const windsurfConfigDir = path_1.default.join(os_1.default.homedir(), '.codeium', 'windsurf');
223
224
  const windsurfConfigFile = path_1.default.join(windsurfConfigDir, 'mcp_config.json');
224
225
  if (fs_1.default.existsSync(windsurfConfigDir)) {
225
226
  let windsurfConfig = { mcpServers: {} };
@@ -246,7 +247,7 @@ function autoConfigureAll(project, opts) {
246
247
  }
247
248
  // Register lemma MCP server in Kiro config
248
249
  const kiroDirs = [
249
- path_1.default.join(process.env.HOME || '~', '.kiro', 'settings'),
250
+ path_1.default.join(os_1.default.homedir(), '.kiro', 'settings'),
250
251
  path_1.default.join(process.cwd(), '.kiro', 'settings'),
251
252
  ];
252
253
  for (const kiroDir of kiroDirs) {
@@ -318,7 +319,7 @@ function autoConfigureAll(project, opts) {
318
319
  catch { }
319
320
  }
320
321
  // Register lemma MCP server in Codex CLI config (~/.codex/config.toml)
321
- const codexConfigFile = path_1.default.join(process.env.HOME || '~', '.codex', 'config.toml');
322
+ const codexConfigFile = path_1.default.join(os_1.default.homedir(), '.codex', 'config.toml');
322
323
  const codexConfigDir = path_1.default.dirname(codexConfigFile);
323
324
  if (fs_1.default.existsSync(codexConfigDir)) {
324
325
  try {
@@ -339,6 +340,42 @@ enabled = true
339
340
  }
340
341
  catch { }
341
342
  }
343
+ // Register lemma MCP server in Claude Code Extension config (.mcp.json project scope)
344
+ const claudeMcpFile = path_1.default.join(process.cwd(), '.mcp.json');
345
+ if (!fs_1.default.existsSync(claudeMcpFile)) {
346
+ try {
347
+ const claudeConfig = {
348
+ mcpServers: {
349
+ lemma: {
350
+ command: 'npx',
351
+ args: ['-y', '@nxuss/lemma', 'mcp'],
352
+ },
353
+ },
354
+ };
355
+ fs_1.default.writeFileSync(claudeMcpFile, JSON.stringify(claudeConfig, null, 2));
356
+ console.log('✅ [Claude Code] Registered lemma MCP server in .mcp.json');
357
+ }
358
+ catch { }
359
+ }
360
+ // Register lemma MCP server in Claude Code user config (~/.claude.json user scope)
361
+ const claudeUserMcpFile = path_1.default.join(os_1.default.homedir(), '.claude.json');
362
+ try {
363
+ let claudeUserConfig = {};
364
+ if (fs_1.default.existsSync(claudeUserMcpFile)) {
365
+ claudeUserConfig = JSON.parse(fs_1.default.readFileSync(claudeUserMcpFile, 'utf8'));
366
+ }
367
+ if (!claudeUserConfig.mcpServers)
368
+ claudeUserConfig.mcpServers = {};
369
+ if (!claudeUserConfig.mcpServers.lemma) {
370
+ claudeUserConfig.mcpServers.lemma = {
371
+ command: 'npx',
372
+ args: ['-y', '@nxuss/lemma', 'mcp'],
373
+ };
374
+ fs_1.default.writeFileSync(claudeUserMcpFile, JSON.stringify(claudeUserConfig, null, 2));
375
+ console.log('✅ [Claude Code] Registered lemma MCP server in ~/.claude.json');
376
+ }
377
+ }
378
+ catch { }
342
379
  console.log(`✅ Auto-configured Lemma for [${project}]`);
343
380
  }
344
381
  const EVENT_LOG = [];
@@ -347,7 +384,8 @@ const MAX_EVENTS = 100;
347
384
  const MCP_STATUS = {
348
385
  lastActivity: Date.now(),
349
386
  toolCallCount: 0,
350
- status: 'idle'
387
+ status: 'idle',
388
+ mcpEnabled: true,
351
389
  };
352
390
  function logEvent(event) {
353
391
  const ev = { id: Math.random().toString(36).slice(2, 11), timestamp: Date.now(), ...event };
@@ -980,12 +1018,20 @@ class LemmaServer {
980
1018
  }
981
1019
  res.json({
982
1020
  status,
1021
+ enabled: MCP_STATUS.mcpEnabled,
983
1022
  lastActivity: new Date(MCP_STATUS.lastActivity).toISOString(),
984
1023
  toolCallCount: MCP_STATUS.toolCallCount,
985
1024
  secondsSinceActive: Math.floor(secondsSinceActive),
986
1025
  uptime: Math.floor(process.uptime())
987
1026
  });
988
1027
  });
1028
+ // MCP Toggle endpoint
1029
+ this.app.post('/api/mcp/toggle', (req, res) => {
1030
+ MCP_STATUS.mcpEnabled = !MCP_STATUS.mcpEnabled;
1031
+ const state = MCP_STATUS.mcpEnabled ? 'enabled' : 'disabled';
1032
+ console.log(`🔄 [MCP] Toggled ${state}`);
1033
+ res.json({ enabled: MCP_STATUS.mcpEnabled, status: state });
1034
+ });
989
1035
  // Project registration from MCP handshake
990
1036
  this.app.post('/api/handshake', (req, res) => {
991
1037
  const { projectPath, projectName, stack } = req.body;
@@ -1960,14 +2006,23 @@ Adjusted Answer:`;
1960
2006
  }
1961
2007
  throw e;
1962
2008
  });
1963
- server.listen(this.port, async () => {
2009
+ const BIND_HOST = process.env.LEMMA_BIND_HOST || '127.0.0.1';
2010
+ server.listen(this.port, BIND_HOST, async () => {
1964
2011
  fs_1.default.writeFileSync(PID_FILE, String(process.pid));
1965
2012
  fs_1.default.writeFileSync(PORT_FILE, String(this.port));
2013
+ // Security warning if binding to all interfaces without auth
2014
+ if (BIND_HOST !== '127.0.0.1' && BIND_HOST !== 'localhost') {
2015
+ const authEnabled = process.env.AUTH_ENABLED === 'true';
2016
+ if (!authEnabled) {
2017
+ console.warn(`\n\x1b[33m⚠️ [SECURITY] Lemma proxy is bound to ${BIND_HOST} (all interfaces) with AUTH_ENABLED=false.`);
2018
+ console.warn(` Set AUTH_ENABLED=true and AUTH_REQUIRE_API_KEY=true before exposing to any network.\x1b[0m\n`);
2019
+ }
2020
+ }
1966
2021
  const pro = await isPro();
1967
2022
  console.log(`\x1b[1m\x1b[35m┌──────────────────────────────────────────────────────────┐\x1b[0m`);
1968
2023
  console.log(`\x1b[1m\x1b[35m│ 🚀 LEMMA PROXY v${VERSION} — THE UNIVERSAL AI GATEWAY │\x1b[0m`);
1969
2024
  console.log(`\x1b[1m\x1b[35m└──────────────────────────────────────────────────────────┘\x1b[0m`);
1970
- console.log(`\n📁 Project : ${this.projectName}\n🔌 Port : ${this.port}`);
2025
+ console.log(`\n📁 Project : ${this.projectName}\n🔌 Port : ${this.port} (bound to ${BIND_HOST})`);
1971
2026
  if (this.dashboardPath && fs_1.default.existsSync(this.dashboardPath)) {
1972
2027
  console.log(`📊 Dashboard UI : \x1b[36mhttp://localhost:${this.port}/dashboard/\x1b[0m`);
1973
2028
  if (this.openBrowser) {
@@ -2006,12 +2061,19 @@ Adjusted Answer:`;
2006
2061
  console.log(`\n \x1b[1m\x1b[33mlemma mcp\x1b[0m\n`);
2007
2062
  console.log('────────────────────────────────────────────────\n');
2008
2063
  // Auto-start the Local Clipboard Optimizer Watcher in the background
2009
- try {
2010
- const { startClipboardWatcher } = require('../utils/ClipboardWatcher');
2011
- startClipboardWatcher(1000);
2064
+ const clipboardDisabled = process.env.LEMMA_DISABLE_CLIPBOARD === 'true';
2065
+ if (clipboardDisabled) {
2066
+ console.log(`📋 Clipboard Watcher : \x1b[90m[DISABLED via LEMMA_DISABLE_CLIPBOARD]\x1b[0m`);
2012
2067
  }
2013
- catch (err) {
2014
- console.warn(`⚠️ Could not auto-initialize Clipboard Watcher: ${err.message}`);
2068
+ else {
2069
+ console.log(`📋 Clipboard Watcher : \x1b[33m[ACTIVE]\x1b[0m polling clipboard every 1s (disable: LEMMA_DISABLE_CLIPBOARD=true)`);
2070
+ try {
2071
+ const { startClipboardWatcher } = require('../utils/ClipboardWatcher');
2072
+ startClipboardWatcher(1000);
2073
+ }
2074
+ catch (err) {
2075
+ console.warn(`⚠️ Could not auto-initialize Clipboard Watcher: ${err.message}`);
2076
+ }
2015
2077
  }
2016
2078
  });
2017
2079
  process.on('SIGTERM', () => server.close());