@nxuss/lemma 1.2.0 → 1.2.2
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/bin/init.js +135 -84
- package/package.json +1 -1
package/bin/init.js
CHANGED
|
@@ -71,6 +71,65 @@ function configureCursor() {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
function configureCursorMcp() {
|
|
75
|
+
const globalCursorDir = path.join(os.homedir(), '.cursor');
|
|
76
|
+
const globalMcpFile = path.join(globalCursorDir, 'mcp.json');
|
|
77
|
+
const projectCursorDir = path.join(process.cwd(), '.cursor');
|
|
78
|
+
const projectMcpFile = path.join(projectCursorDir, 'mcp.json');
|
|
79
|
+
const lemmaServerConfig = { command: 'npx', args: ['-y', '@nxuss/lemma', 'mcp'] };
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
ensureDir(globalCursorDir);
|
|
83
|
+
let globalConfig = {};
|
|
84
|
+
if (fs.existsSync(globalMcpFile)) {
|
|
85
|
+
globalConfig = JSON.parse(fs.readFileSync(globalMcpFile, 'utf8'));
|
|
86
|
+
}
|
|
87
|
+
if (!globalConfig.mcpServers) globalConfig.mcpServers = {};
|
|
88
|
+
globalConfig.mcpServers.lemma = lemmaServerConfig;
|
|
89
|
+
fs.writeFileSync(globalMcpFile, JSON.stringify(globalConfig, null, 2), 'utf8');
|
|
90
|
+
|
|
91
|
+
ensureDir(projectCursorDir);
|
|
92
|
+
let projectConfig = {};
|
|
93
|
+
if (fs.existsSync(projectMcpFile)) {
|
|
94
|
+
projectConfig = JSON.parse(fs.readFileSync(projectMcpFile, 'utf8'));
|
|
95
|
+
}
|
|
96
|
+
if (!projectConfig.mcpServers) projectConfig.mcpServers = {};
|
|
97
|
+
projectConfig.mcpServers.lemma = lemmaServerConfig;
|
|
98
|
+
fs.writeFileSync(projectMcpFile, JSON.stringify(projectConfig, null, 2), 'utf8');
|
|
99
|
+
return true;
|
|
100
|
+
} catch {
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function configureCodexCliMcp() {
|
|
106
|
+
const codexDir = path.join(os.homedir(), '.codex');
|
|
107
|
+
const codexConfigFile = path.join(codexDir, 'config.toml');
|
|
108
|
+
const lemmaEntry = [
|
|
109
|
+
'',
|
|
110
|
+
'[mcp_servers.lemma]',
|
|
111
|
+
'command = "npx"',
|
|
112
|
+
'args = ["-y", "@nxuss/lemma", "mcp"]',
|
|
113
|
+
'enabled = true',
|
|
114
|
+
''
|
|
115
|
+
].join('\n');
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
ensureDir(codexDir);
|
|
119
|
+
let config = '';
|
|
120
|
+
if (fs.existsSync(codexConfigFile)) {
|
|
121
|
+
config = fs.readFileSync(codexConfigFile, 'utf8');
|
|
122
|
+
}
|
|
123
|
+
if (config.includes('[mcp_servers.lemma]')) {
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
fs.writeFileSync(codexConfigFile, `${config.replace(/\s*$/, '')}${lemmaEntry}`, 'utf8');
|
|
127
|
+
return true;
|
|
128
|
+
} catch {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
74
133
|
function configureOpenCodeMcp() {
|
|
75
134
|
const configDir = path.join(os.homedir(), '.opencode');
|
|
76
135
|
const configFile = path.join(configDir, 'mcp.json');
|
|
@@ -117,64 +176,66 @@ function configureClaudeDesktop() {
|
|
|
117
176
|
}
|
|
118
177
|
|
|
119
178
|
// ─── Lemma MCP tool names (server prefix: "lemma") ────────────────────────────
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
'
|
|
123
|
-
'
|
|
124
|
-
'
|
|
125
|
-
'
|
|
126
|
-
'
|
|
127
|
-
'
|
|
128
|
-
'
|
|
129
|
-
|
|
130
|
-
'
|
|
131
|
-
'
|
|
132
|
-
'
|
|
133
|
-
'
|
|
134
|
-
'
|
|
135
|
-
|
|
136
|
-
'mcp__lemma__get_project_onboarding',
|
|
137
|
-
'mcp__lemma__get_telepathic_hints',
|
|
138
|
-
'mcp__lemma__get_ast_hologram',
|
|
139
|
-
'mcp__lemma__get_symbol_surgical_context',
|
|
140
|
-
'mcp__lemma__compress_context',
|
|
141
|
-
'mcp__lemma__collapse_context',
|
|
142
|
-
// Token optimization
|
|
143
|
-
'mcp__lemma__squeeze_prompt',
|
|
144
|
-
'mcp__lemma__turbosqueeze',
|
|
145
|
-
'mcp__lemma__wormhole_squeeze',
|
|
146
|
-
'mcp__lemma__token_budget',
|
|
147
|
-
'mcp__lemma__prune_conversation_history',
|
|
148
|
-
'mcp__lemma__summarize_long_text',
|
|
149
|
-
// Code quality & patching
|
|
150
|
-
'mcp__lemma__validate_patch_sandbox',
|
|
151
|
-
'mcp__lemma__surgical_ast_insert',
|
|
152
|
-
'mcp__lemma__diff_only',
|
|
153
|
-
'mcp__lemma__local_semantic_autofix',
|
|
154
|
-
'mcp__lemma__auto_heal',
|
|
155
|
-
// Analysis
|
|
156
|
-
'mcp__lemma__get_routing_advice',
|
|
157
|
-
'mcp__lemma__query_hybrid_consensus',
|
|
158
|
-
'mcp__lemma__batch_tool_calls',
|
|
159
|
-
'mcp__lemma__scrub_privacy',
|
|
160
|
-
'mcp__lemma__entropy_score',
|
|
161
|
-
'mcp__lemma__coupling_radar',
|
|
162
|
-
'mcp__lemma__pattern_fossil',
|
|
163
|
-
'mcp__lemma__git_heatmap_risk',
|
|
164
|
-
'mcp__lemma__precrime_static',
|
|
165
|
-
'mcp__lemma__semantic_dedup_guard',
|
|
166
|
-
'mcp__lemma__dead_export_necromancer',
|
|
167
|
-
'mcp__lemma__depgraph',
|
|
168
|
-
'mcp__lemma__refactor',
|
|
169
|
-
// PR Review
|
|
170
|
-
'mcp__lemma__review_diff',
|
|
171
|
-
'mcp__lemma__review_pr',
|
|
172
|
-
'mcp__lemma__pr_status',
|
|
173
|
-
'mcp__lemma__generate_pr_workflow',
|
|
174
|
-
// Reporting
|
|
175
|
-
'mcp__lemma__generate_executive_roi_report',
|
|
179
|
+
const FALLBACK_LEMMA_TOOL_NAMES = [
|
|
180
|
+
'read_workspace_file', 'write_workspace_file', 'create_workspace_file', 'list_workspace_dir',
|
|
181
|
+
'search_workspace', 'apply_workspace_patch', 'run_workspace_command',
|
|
182
|
+
'search_memory', 'store_memory', 'smarter_cache',
|
|
183
|
+
'get_project_onboarding', 'get_telepathic_hints', 'get_ast_hologram',
|
|
184
|
+
'get_symbol_surgical_context', 'compress_context',
|
|
185
|
+
'squeeze_prompt', 'turbosqueeze', 'wormhole_squeeze',
|
|
186
|
+
'token_budget', 'prune_conversation_history', 'summarize_long_text',
|
|
187
|
+
'validate_patch_sandbox', 'surgical_ast_insert', 'diff_only',
|
|
188
|
+
'local_semantic_autofix', 'auto_heal', 'get_routing_advice',
|
|
189
|
+
'query_hybrid_consensus', 'batch_tool_calls', 'scrub_privacy',
|
|
190
|
+
'entropy_score', 'coupling_radar', 'pattern_fossil',
|
|
191
|
+
'git_heatmap_risk', 'precrime_static', 'semantic_dedup_guard',
|
|
192
|
+
'dead_export_necromancer', 'depgraph', 'refactor',
|
|
193
|
+
'review_diff', 'review_pr', 'pr_status',
|
|
194
|
+
'generate_pr_workflow', 'generate_executive_roi_report',
|
|
176
195
|
];
|
|
177
196
|
|
|
197
|
+
function extractToolNamesFromSource(source, containerName) {
|
|
198
|
+
const blockRegex = new RegExp(`const ${containerName}(?:\\s*:\\s*[^=]+)?\\s*=\\s*\\{([\\s\\S]*?)\\n\\};`);
|
|
199
|
+
const match = source.match(blockRegex);
|
|
200
|
+
if (!match) return [];
|
|
201
|
+
const names = [];
|
|
202
|
+
const seen = new Set();
|
|
203
|
+
const keyRegex = /\n\s*([a-zA-Z0-9_]+):\s*(?:handle[A-Za-z0-9_]+|async\s*\()/g;
|
|
204
|
+
for (const hit of match[1].matchAll(keyRegex)) {
|
|
205
|
+
const name = hit[1];
|
|
206
|
+
if (seen.has(name)) continue;
|
|
207
|
+
seen.add(name);
|
|
208
|
+
names.push(name);
|
|
209
|
+
}
|
|
210
|
+
return names;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function loadLemmaToolNames() {
|
|
214
|
+
const seen = new Set();
|
|
215
|
+
const collected = [];
|
|
216
|
+
const candidates = [
|
|
217
|
+
['toolHandlers', path.join(__dirname, '..', 'src', 'mcp', 'tools.ts')],
|
|
218
|
+
['toolHandlers', path.join(__dirname, '..', 'dist', 'cjs', 'mcp', 'tools.js')],
|
|
219
|
+
['handlers', path.join(__dirname, '..', 'src', 'infra', 'mcp-tools.ts')],
|
|
220
|
+
['handlers', path.join(__dirname, '..', 'dist', 'cjs', 'infra', 'mcp-tools.js')],
|
|
221
|
+
];
|
|
222
|
+
for (const [containerName, filePath] of candidates) {
|
|
223
|
+
if (!fs.existsSync(filePath)) continue;
|
|
224
|
+
try {
|
|
225
|
+
const source = fs.readFileSync(filePath, 'utf8');
|
|
226
|
+
for (const name of extractToolNamesFromSource(source, containerName)) {
|
|
227
|
+
if (seen.has(name)) continue;
|
|
228
|
+
seen.add(name);
|
|
229
|
+
collected.push(name);
|
|
230
|
+
}
|
|
231
|
+
} catch {}
|
|
232
|
+
}
|
|
233
|
+
return collected.length > 0 ? collected : FALLBACK_LEMMA_TOOL_NAMES;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const LEMMA_TOOL_NAMES = loadLemmaToolNames();
|
|
237
|
+
const LEMMA_MCP_TOOLS = LEMMA_TOOL_NAMES.map((name) => `mcp__lemma__${name}`);
|
|
238
|
+
|
|
178
239
|
const CLAUDE_MD_CONTENT = `# Lemma MCP — Reglas de Comportamiento Obligatorio
|
|
179
240
|
|
|
180
241
|
> ⚠️ ESTAS REGLAS SON ABSOLUTAS. Síguilas sin excepción.
|
|
@@ -255,10 +316,11 @@ function configureClaudeCode() {
|
|
|
255
316
|
);
|
|
256
317
|
settings.enableAllProjectMcpServers = true;
|
|
257
318
|
|
|
258
|
-
//
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
319
|
+
// Rebuild Lemma tool permissions from the current catalog while preserving non-Lemma tools.
|
|
320
|
+
const preservedTools = (settings.allowedTools || []).filter(
|
|
321
|
+
(tool) => !tool.startsWith('mcp__lemma__')
|
|
322
|
+
);
|
|
323
|
+
settings.allowedTools = [...preservedTools, ...LEMMA_MCP_TOOLS];
|
|
262
324
|
|
|
263
325
|
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
|
|
264
326
|
|
|
@@ -276,25 +338,6 @@ function configureClaudeCode() {
|
|
|
276
338
|
return true;
|
|
277
339
|
}
|
|
278
340
|
|
|
279
|
-
// ─── Short tool names (for non-Claude tools that don't use mcp__ prefix) ───────
|
|
280
|
-
const LEMMA_TOOL_NAMES = [
|
|
281
|
-
'read_workspace_file', 'write_workspace_file', 'create_workspace_file', 'list_workspace_dir',
|
|
282
|
-
'search_workspace', 'apply_workspace_patch', 'run_workspace_command',
|
|
283
|
-
'search_memory', 'store_memory', 'smarter_cache',
|
|
284
|
-
'get_project_onboarding', 'get_telepathic_hints', 'get_ast_hologram',
|
|
285
|
-
'get_symbol_surgical_context', 'compress_context',
|
|
286
|
-
'squeeze_prompt', 'turbosqueeze', 'wormhole_squeeze',
|
|
287
|
-
'token_budget', 'prune_conversation_history', 'summarize_long_text',
|
|
288
|
-
'validate_patch_sandbox', 'surgical_ast_insert', 'diff_only',
|
|
289
|
-
'local_semantic_autofix', 'auto_heal', 'get_routing_advice',
|
|
290
|
-
'query_hybrid_consensus', 'batch_tool_calls', 'scrub_privacy',
|
|
291
|
-
'entropy_score', 'coupling_radar', 'pattern_fossil',
|
|
292
|
-
'git_heatmap_risk', 'precrime_static', 'semantic_dedup_guard',
|
|
293
|
-
'dead_export_necromancer', 'depgraph', 'refactor',
|
|
294
|
-
'review_diff', 'review_pr', 'pr_status',
|
|
295
|
-
'generate_pr_workflow', 'generate_executive_roi_report',
|
|
296
|
-
];
|
|
297
|
-
|
|
298
341
|
const LEMMA_RULES_CONTENT = `# Lemma MCP — Autonomous Behaviors
|
|
299
342
|
|
|
300
343
|
> ⚠️ MANDATORY RULES — Follow without exception.
|
|
@@ -612,15 +655,23 @@ async function main() {
|
|
|
612
655
|
const hasCursor = detectTool('Cursor', () => fs.existsSync(path.join(os.homedir(), '.cursor')));
|
|
613
656
|
if (hasCursor) {
|
|
614
657
|
const configured = configureCursor();
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
658
|
+
const mcpConfigured = configureCursorMcp();
|
|
659
|
+
if (configured && mcpConfigured) ok('Cursor configured (API base + MCP registration)');
|
|
660
|
+
else warn('Cursor detected but config could not be fully auto-updated');
|
|
661
|
+
} else {
|
|
662
|
+
const projectCursorConfigured = configureCursorMcp();
|
|
663
|
+
if (projectCursorConfigured) ok('Project Cursor MCP configured');
|
|
664
|
+
else skip('Cursor not detected');
|
|
665
|
+
}
|
|
618
666
|
|
|
619
667
|
const hasCodex = detectTool('Codex CLI', () => {
|
|
620
668
|
try { execSync('which codex', { stdio: 'ignore' }); return true; } catch { return false; }
|
|
621
669
|
});
|
|
622
|
-
if (hasCodex)
|
|
623
|
-
|
|
670
|
+
if (hasCodex) {
|
|
671
|
+
const codexConfigured = configureCodexCliMcp();
|
|
672
|
+
if (codexConfigured) ok('Codex CLI configured (MCP + OPENAI_BASE_URL env)');
|
|
673
|
+
else warn('Codex CLI detected but MCP config could not be auto-updated');
|
|
674
|
+
} else skip('Codex CLI not detected');
|
|
624
675
|
|
|
625
676
|
const hasWindsurf = detectTool('Windsurf', () => fs.existsSync(path.join(os.homedir(), '.windsurfrules')));
|
|
626
677
|
if (hasWindsurf) ok('Windsurf detected — env auto-configured');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxuss/lemma",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "Intelligent AI Gateway for IDEs & Agents — Semantic cache, Privacy Firewall, Infrastructure Command Center, and Autonomous Cost-Optimization.",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|