@nxuss/lemma 0.5.4 → 0.5.6
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/README.md +30 -0
- package/dist/cjs/cli/lemma-proxy.d.ts +9 -2
- package/dist/cjs/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/cjs/cli/lemma-proxy.js +187 -118
- package/dist/cjs/cli/lemma-proxy.js.map +1 -1
- package/dist/cjs/cloud/BurstRateLimiter.d.ts +26 -0
- package/dist/cjs/cloud/BurstRateLimiter.d.ts.map +1 -0
- package/dist/cjs/cloud/BurstRateLimiter.js +63 -0
- package/dist/cjs/cloud/BurstRateLimiter.js.map +1 -0
- package/dist/cjs/cloud/KeyManager.d.ts +1 -0
- package/dist/cjs/cloud/KeyManager.d.ts.map +1 -1
- package/dist/cjs/cloud/KeyManager.js +28 -1
- package/dist/cjs/cloud/KeyManager.js.map +1 -1
- package/dist/cjs/cloud/PostgresQuotaLimiter.d.ts +60 -0
- package/dist/cjs/cloud/PostgresQuotaLimiter.d.ts.map +1 -0
- package/dist/cjs/cloud/PostgresQuotaLimiter.js +200 -0
- package/dist/cjs/cloud/PostgresQuotaLimiter.js.map +1 -0
- package/dist/cjs/cloud/TenantCache.d.ts +1 -1
- package/dist/cjs/cloud/TenantCache.d.ts.map +1 -1
- package/dist/cjs/cloud/TenantCache.js +21 -3
- package/dist/cjs/cloud/TenantCache.js.map +1 -1
- package/dist/cjs/cloud/server.d.ts +3 -1
- package/dist/cjs/cloud/server.d.ts.map +1 -1
- package/dist/cjs/cloud/server.js +42 -5
- package/dist/cjs/cloud/server.js.map +1 -1
- package/dist/cjs/cloud/types.d.ts +3 -0
- package/dist/cjs/cloud/types.d.ts.map +1 -1
- package/dist/cjs/cloud/types.js +3 -3
- package/dist/cjs/cloud/types.js.map +1 -1
- package/dist/esm/cli/lemma-proxy.d.ts +9 -2
- package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
- package/dist/esm/cli/lemma-proxy.js +187 -118
- package/dist/esm/cli/lemma-proxy.js.map +1 -1
- package/dist/esm/cloud/BurstRateLimiter.d.ts +26 -0
- package/dist/esm/cloud/BurstRateLimiter.d.ts.map +1 -0
- package/dist/esm/cloud/BurstRateLimiter.js +59 -0
- package/dist/esm/cloud/BurstRateLimiter.js.map +1 -0
- package/dist/esm/cloud/KeyManager.d.ts +1 -0
- package/dist/esm/cloud/KeyManager.d.ts.map +1 -1
- package/dist/esm/cloud/KeyManager.js +28 -1
- package/dist/esm/cloud/KeyManager.js.map +1 -1
- package/dist/esm/cloud/PostgresQuotaLimiter.d.ts +60 -0
- package/dist/esm/cloud/PostgresQuotaLimiter.d.ts.map +1 -0
- package/dist/esm/cloud/PostgresQuotaLimiter.js +196 -0
- package/dist/esm/cloud/PostgresQuotaLimiter.js.map +1 -0
- package/dist/esm/cloud/TenantCache.d.ts +1 -1
- package/dist/esm/cloud/TenantCache.d.ts.map +1 -1
- package/dist/esm/cloud/TenantCache.js +21 -3
- package/dist/esm/cloud/TenantCache.js.map +1 -1
- package/dist/esm/cloud/server.d.ts +3 -1
- package/dist/esm/cloud/server.d.ts.map +1 -1
- package/dist/esm/cloud/server.js +41 -5
- package/dist/esm/cloud/server.js.map +1 -1
- package/dist/esm/cloud/types.d.ts +3 -0
- package/dist/esm/cloud/types.d.ts.map +1 -1
- package/dist/esm/cloud/types.js +3 -3
- package/dist/esm/cloud/types.js.map +1 -1
- package/package.json +1 -2
|
@@ -24,7 +24,7 @@ function getVersion() {
|
|
|
24
24
|
catch { }
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
-
return '0.5.
|
|
27
|
+
return '0.5.4';
|
|
28
28
|
}
|
|
29
29
|
const VERSION = getVersion();
|
|
30
30
|
import ComplexityRouter from '../proxy/ComplexityRouter';
|
|
@@ -209,141 +209,207 @@ function ensureGitIgnore() {
|
|
|
209
209
|
return added;
|
|
210
210
|
}
|
|
211
211
|
const CLIPBOARD_PID_FILE = path.join(CACHE_DIR, 'clipboard.pid');
|
|
212
|
-
export function autoConfigureAll(projectName) {
|
|
212
|
+
export function autoConfigureAll(projectName, cliOpts) {
|
|
213
213
|
const project = projectName || detectProject();
|
|
214
214
|
const HOME = process.env.HOME || process.env.USERPROFILE || '~';
|
|
215
|
-
//
|
|
215
|
+
// Load configuration if it exists
|
|
216
|
+
let configDisabled = false;
|
|
217
|
+
let configEditor = true;
|
|
218
|
+
let configShell = true;
|
|
219
|
+
let configClaude = true;
|
|
216
220
|
try {
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
if (
|
|
224
|
-
|
|
225
|
-
|
|
221
|
+
const configPath = path.join(process.cwd(), 'lemma.config.json');
|
|
222
|
+
if (fs.existsSync(configPath)) {
|
|
223
|
+
const rawConfig = fs.readFileSync(configPath, 'utf8');
|
|
224
|
+
const config = JSON.parse(rawConfig);
|
|
225
|
+
const systemConfig = config.system || {};
|
|
226
|
+
const autoConfig = systemConfig.autoConfigure || {};
|
|
227
|
+
if (autoConfig.disabled === true)
|
|
228
|
+
configDisabled = true;
|
|
229
|
+
if (autoConfig.editor === false)
|
|
230
|
+
configEditor = false;
|
|
231
|
+
if (autoConfig.shell === false)
|
|
232
|
+
configShell = false;
|
|
233
|
+
if (autoConfig.claude === false)
|
|
234
|
+
configClaude = false;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
catch { }
|
|
238
|
+
// Merge CLI overrides and config
|
|
239
|
+
const shouldConfigure = cliOpts?.configure !== false && !configDisabled;
|
|
240
|
+
if (!shouldConfigure) {
|
|
241
|
+
console.log(`⏭️ [Auto-Configure] Skipped auto-configuration (disabled via options or config).`);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
const runEditor = cliOpts?.editor !== false && configEditor;
|
|
245
|
+
const runShell = cliOpts?.shell !== false && configShell;
|
|
246
|
+
const runClaude = cliOpts?.claude !== false && configClaude;
|
|
247
|
+
// 1. Claude Desktop Config
|
|
248
|
+
if (runClaude) {
|
|
249
|
+
try {
|
|
250
|
+
const isWin = process.platform === 'win32';
|
|
251
|
+
const claudePath = isWin
|
|
252
|
+
? path.join(process.env.APPDATA || '', 'Claude/claude_desktop_config.json')
|
|
253
|
+
: path.join(HOME, 'Library/Application Support/Claude/claude_desktop_config.json');
|
|
254
|
+
if (fs.existsSync(path.dirname(claudePath))) {
|
|
255
|
+
let config = { mcpServers: {} };
|
|
256
|
+
if (fs.existsSync(claudePath)) {
|
|
257
|
+
try {
|
|
258
|
+
config = JSON.parse(fs.readFileSync(claudePath, 'utf8'));
|
|
259
|
+
}
|
|
260
|
+
catch { }
|
|
226
261
|
}
|
|
227
|
-
|
|
262
|
+
if (!config.mcpServers)
|
|
263
|
+
config.mcpServers = {};
|
|
264
|
+
config.mcpServers.lemma = {
|
|
265
|
+
command: 'npx',
|
|
266
|
+
args: ['-y', '@nxuss/lemma', 'mcp'],
|
|
267
|
+
env: { LEMMA_PROJECT: project }
|
|
268
|
+
};
|
|
269
|
+
fs.writeFileSync(claudePath, JSON.stringify(config, null, 2));
|
|
270
|
+
console.log(`✅ [Claude Desktop] Configured automatically in: ${claudePath} (Restart Claude to activate)`);
|
|
228
271
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
command: 'npx',
|
|
233
|
-
args: ['-y', '@nxuss/lemma', 'mcp'],
|
|
234
|
-
env: { LEMMA_PROJECT: project }
|
|
235
|
-
};
|
|
236
|
-
fs.writeFileSync(claudePath, JSON.stringify(config, null, 2));
|
|
237
|
-
console.log(`✅ [Claude Desktop] Configured automatically! (Restart Claude to activate)`);
|
|
272
|
+
}
|
|
273
|
+
catch (e) {
|
|
274
|
+
console.log(`⚠️ Could not auto-configure Claude Desktop: ${e.message}`);
|
|
238
275
|
}
|
|
239
276
|
}
|
|
240
|
-
|
|
241
|
-
console.log(
|
|
277
|
+
else {
|
|
278
|
+
console.log(`⏭️ [Claude Desktop] Skip auto-configuration.`);
|
|
242
279
|
}
|
|
243
280
|
// 2. Shell Profiles Environment Override
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
281
|
+
if (runShell) {
|
|
282
|
+
try {
|
|
283
|
+
const profiles = [
|
|
284
|
+
path.join(HOME, '.zshrc'),
|
|
285
|
+
path.join(HOME, '.bashrc'),
|
|
286
|
+
path.join(HOME, '.bash_profile'),
|
|
287
|
+
path.join(HOME, '.profile')
|
|
288
|
+
];
|
|
289
|
+
const lines = [
|
|
290
|
+
'',
|
|
291
|
+
'# Lemma AI Gateway Overrides',
|
|
292
|
+
'export OPENAI_BASE_URL="http://localhost:8081/v1"',
|
|
293
|
+
'export ANTHROPIC_BASE_URL="http://localhost:8081"',
|
|
294
|
+
'export LEMMA_PROJECT="' + project + '"',
|
|
295
|
+
''
|
|
296
|
+
].join('\n');
|
|
297
|
+
for (const profile of profiles) {
|
|
298
|
+
if (fs.existsSync(profile)) {
|
|
299
|
+
try {
|
|
300
|
+
const content = fs.readFileSync(profile, 'utf8');
|
|
301
|
+
if (!content.includes('OPENAI_BASE_URL') && !content.includes('LEMMA_PROJECT')) {
|
|
302
|
+
fs.appendFileSync(profile, lines);
|
|
303
|
+
console.log(`✅ [Shell Profile] Configured ${path.basename(profile)} with local redirect variables!`);
|
|
304
|
+
}
|
|
266
305
|
}
|
|
306
|
+
catch { }
|
|
267
307
|
}
|
|
268
|
-
catch { }
|
|
269
308
|
}
|
|
270
309
|
}
|
|
310
|
+
catch (e) {
|
|
311
|
+
console.log(`⚠️ Could not auto-configure shell profiles: ${e.message}`);
|
|
312
|
+
}
|
|
271
313
|
}
|
|
272
|
-
|
|
273
|
-
console.log(
|
|
314
|
+
else {
|
|
315
|
+
console.log(`⏭️ [Shell Profile] Skip auto-configuration.`);
|
|
274
316
|
}
|
|
275
317
|
// 3. Cursor & Windsurf settings.json updates
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
+
if (runEditor) {
|
|
319
|
+
try {
|
|
320
|
+
const isWin = process.platform === 'win32';
|
|
321
|
+
const isMac = process.platform === 'darwin';
|
|
322
|
+
const candidates = [];
|
|
323
|
+
if (isMac) {
|
|
324
|
+
candidates.push({
|
|
325
|
+
name: 'Cursor',
|
|
326
|
+
path: path.join(HOME, 'Library/Application Support/Cursor/User/settings.json')
|
|
327
|
+
});
|
|
328
|
+
candidates.push({
|
|
329
|
+
name: 'Windsurf',
|
|
330
|
+
path: path.join(HOME, 'Library/Application Support/Windsurf/User/settings.json')
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
else if (isWin) {
|
|
334
|
+
const appData = process.env.APPDATA || '';
|
|
335
|
+
candidates.push({
|
|
336
|
+
name: 'Cursor',
|
|
337
|
+
path: path.join(appData, 'Cursor/User/settings.json')
|
|
338
|
+
});
|
|
339
|
+
candidates.push({
|
|
340
|
+
name: 'Windsurf',
|
|
341
|
+
path: path.join(appData, 'Windsurf/User/settings.json')
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
candidates.push({
|
|
346
|
+
name: 'Cursor',
|
|
347
|
+
path: path.join(HOME, '.config/Cursor/User/settings.json')
|
|
348
|
+
});
|
|
349
|
+
candidates.push({
|
|
350
|
+
name: 'Windsurf',
|
|
351
|
+
path: path.join(HOME, '.config/Windsurf/User/settings.json')
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
for (const cand of candidates) {
|
|
355
|
+
const dir = path.dirname(cand.path);
|
|
356
|
+
if (fs.existsSync(dir)) {
|
|
357
|
+
let settings = {};
|
|
358
|
+
if (fs.existsSync(cand.path)) {
|
|
359
|
+
try {
|
|
360
|
+
settings = JSON.parse(fs.readFileSync(cand.path, 'utf8'));
|
|
361
|
+
}
|
|
362
|
+
catch { }
|
|
318
363
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
364
|
+
let updated = false;
|
|
365
|
+
// Settings configuration to route custom openai/anthropic models through the proxy
|
|
366
|
+
const updates = {
|
|
367
|
+
"openai.baseURL": "http://localhost:8081/v1",
|
|
368
|
+
"openai.apiKey": "dummy-key-for-lemma",
|
|
369
|
+
"anthropic.baseURL": "http://localhost:8081",
|
|
370
|
+
"anthropic.apiKey": "dummy-key-for-lemma"
|
|
371
|
+
};
|
|
372
|
+
for (const [key, value] of Object.entries(updates)) {
|
|
373
|
+
if (settings[key] !== value) {
|
|
374
|
+
settings[key] = value;
|
|
375
|
+
updated = true;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
if (updated) {
|
|
379
|
+
fs.writeFileSync(cand.path, JSON.stringify(settings, null, 2));
|
|
380
|
+
console.log(`✅ [${cand.name}] Configured editor settings in ${cand.path} to route via local gateway!`);
|
|
333
381
|
}
|
|
334
|
-
}
|
|
335
|
-
if (updated) {
|
|
336
|
-
fs.writeFileSync(cand.path, JSON.stringify(settings, null, 2));
|
|
337
|
-
console.log(`✅ [${cand.name}] Configured editor settings to route via local gateway!`);
|
|
338
382
|
}
|
|
339
383
|
}
|
|
340
384
|
}
|
|
385
|
+
catch (e) {
|
|
386
|
+
console.log(`⚠️ Could not auto-configure editor settings: ${e.message}`);
|
|
387
|
+
}
|
|
341
388
|
}
|
|
342
|
-
|
|
343
|
-
console.log(
|
|
389
|
+
else {
|
|
390
|
+
console.log(`⏭️ [Editor Settings] Skip auto-configuration.`);
|
|
344
391
|
}
|
|
345
392
|
}
|
|
346
|
-
export function startBackgroundClipboardWatcher() {
|
|
393
|
+
export function startBackgroundClipboardWatcher(cliOpts) {
|
|
394
|
+
// Load configuration if it exists
|
|
395
|
+
let configDisabled = false;
|
|
396
|
+
try {
|
|
397
|
+
const configPath = path.join(process.cwd(), 'lemma.config.json');
|
|
398
|
+
if (fs.existsSync(configPath)) {
|
|
399
|
+
const rawConfig = fs.readFileSync(configPath, 'utf8');
|
|
400
|
+
const config = JSON.parse(rawConfig);
|
|
401
|
+
const systemConfig = config.system || {};
|
|
402
|
+
const clipConfig = systemConfig.clipboardWatcher || {};
|
|
403
|
+
if (clipConfig.disabled === true)
|
|
404
|
+
configDisabled = true;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
catch { }
|
|
408
|
+
const shouldWatch = cliOpts?.clipboard !== false && !configDisabled;
|
|
409
|
+
if (!shouldWatch) {
|
|
410
|
+
console.log(`⏭️ [Clipboard] Background clipboard watcher is disabled (via options or config).`);
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
347
413
|
try {
|
|
348
414
|
if (fs.existsSync(CLIPBOARD_PID_FILE)) {
|
|
349
415
|
const oldPid = fs.readFileSync(CLIPBOARD_PID_FILE, 'utf8');
|
|
@@ -1506,6 +1572,8 @@ program.command('start')
|
|
|
1506
1572
|
.option('--project <name>', 'Override project name')
|
|
1507
1573
|
.option('--stack', 'Launch full development stack (Chroma + Router + Dashboard + Autopilot)')
|
|
1508
1574
|
.option('--autopilot', 'Launch background compiler watcher & healer', false)
|
|
1575
|
+
.option('--no-configure', 'Skip automatic configuration of editors, shell overrides, and Claude Desktop')
|
|
1576
|
+
.option('--no-clipboard', 'Skip launching background clipboard watcher')
|
|
1509
1577
|
.action(async (opts) => {
|
|
1510
1578
|
const port = parseInt(opts.port, 10);
|
|
1511
1579
|
// Ensure ChromaDB is running for semantic caching/search
|
|
@@ -1517,15 +1585,15 @@ program.command('start')
|
|
|
1517
1585
|
console.log(`💡 Use 'lemma status' for details or 'lemma stop' to restart.\n`);
|
|
1518
1586
|
// Keep configurations up to date even if server was already started
|
|
1519
1587
|
const runningProject = resp.data.project || detectProject();
|
|
1520
|
-
autoConfigureAll(runningProject);
|
|
1521
|
-
startBackgroundClipboardWatcher();
|
|
1588
|
+
autoConfigureAll(runningProject, { configure: opts.configure });
|
|
1589
|
+
startBackgroundClipboardWatcher({ clipboard: opts.clipboard });
|
|
1522
1590
|
process.exit(0);
|
|
1523
1591
|
}
|
|
1524
1592
|
}
|
|
1525
1593
|
catch { }
|
|
1526
1594
|
const startProject = opts.project || detectProject();
|
|
1527
|
-
autoConfigureAll(startProject);
|
|
1528
|
-
startBackgroundClipboardWatcher();
|
|
1595
|
+
autoConfigureAll(startProject, { configure: opts.configure });
|
|
1596
|
+
startBackgroundClipboardWatcher({ clipboard: opts.clipboard });
|
|
1529
1597
|
// Automatically enable autopilot if stack is enabled and user is Pro
|
|
1530
1598
|
const runAutopilot = opts.autopilot || opts.stack;
|
|
1531
1599
|
if (runAutopilot) {
|
|
@@ -1701,7 +1769,8 @@ program.command('activate <key>')
|
|
|
1701
1769
|
});
|
|
1702
1770
|
program.command('init')
|
|
1703
1771
|
.description('Initialize Lemma in the current project (auto-discovery)')
|
|
1704
|
-
.
|
|
1772
|
+
.option('--no-configure', 'Skip automatic configuration of editors, shell overrides, and Claude Desktop')
|
|
1773
|
+
.action(async (opts) => {
|
|
1705
1774
|
const project = detectProject();
|
|
1706
1775
|
console.log(`\n🛠️ Initializing Lemma for [${project}]...`);
|
|
1707
1776
|
// Ensure ChromaDB is running for semantic caching/search
|
|
@@ -1731,7 +1800,7 @@ program.command('init')
|
|
|
1731
1800
|
console.log('✅ Created .env with Lemma configuration');
|
|
1732
1801
|
}
|
|
1733
1802
|
console.log('\n🧠 \x1b[35mAuto-Setup MCP and redirection overrides for AI IDEs...\x1b[0m');
|
|
1734
|
-
autoConfigureAll(project);
|
|
1803
|
+
autoConfigureAll(project, { configure: opts.configure });
|
|
1735
1804
|
console.log('\n✨ Project initialized for the Agentic Era!');
|
|
1736
1805
|
console.log('🚀 Run "lemma start" to begin.\n');
|
|
1737
1806
|
});
|