@nxuss/lemma 1.2.3 → 1.2.4

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/cli.js CHANGED
@@ -8,7 +8,7 @@ const { execSync } = require('child_process');
8
8
 
9
9
  const LEMMA_CACHE = path.join(os.homedir(), '.lemma-cache');
10
10
  const BRAIN_FILE = path.join(LEMMA_CACHE, 'lemma_brain.json');
11
- const PORT = process.env.LEMMA_PROXY_PORT || '9090';
11
+ const PORT_FILE = path.join(LEMMA_CACHE, 'proxy.port');
12
12
 
13
13
  const INPUT_COST = 3.00 / 1000000;
14
14
  const OUTPUT_COST = 15.00 / 1000000;
@@ -21,6 +21,16 @@ function loadBrain() {
21
21
  return null;
22
22
  }
23
23
 
24
+ function getPort() {
25
+ try {
26
+ if (fs.existsSync(PORT_FILE)) {
27
+ const port = fs.readFileSync(PORT_FILE, 'utf8').trim();
28
+ if (port) return port;
29
+ }
30
+ } catch {}
31
+ return process.env.LEMMA_PROXY_PORT || '8081';
32
+ }
33
+
24
34
  function daemonStatus() {
25
35
  try {
26
36
  const isMac = process.platform === 'darwin';
@@ -34,7 +44,7 @@ function daemonStatus() {
34
44
  }
35
45
  } catch {}
36
46
  try {
37
- const port = PORT;
47
+ const port = getPort();
38
48
  const http = require('http');
39
49
  return new Promise(resolve => {
40
50
  const req = http.get(`http://localhost:${port}/v1/models`, res => resolve('running'));
@@ -47,11 +57,12 @@ function daemonStatus() {
47
57
  async function main() {
48
58
  const brain = loadBrain();
49
59
  const daemon = await daemonStatus();
60
+ const port = getPort();
50
61
 
51
62
  process.stderr.write(`\n ${B}${C}═══ Lemma Cache Dashboard ═══${R}\n\n`);
52
63
 
53
64
  const statusColor = daemon === 'running' ? G : Y;
54
- process.stderr.write(` ${C}Proxy:${R} :${PORT} ${statusColor}${daemon === 'running' ? '● running' : '○ stopped'}${R}\n`);
65
+ process.stderr.write(` ${C}Proxy:${R} :${port} ${statusColor}${daemon === 'running' ? '● running' : '○ stopped'}${R}\n`);
55
66
  process.stderr.write(` ${C}MCP Server:${R} lemma mcp\n`);
56
67
  process.stderr.write(` ${C}Env File:${R} ${D}${LEMMA_CACHE}/env${R}\n\n`);
57
68
 
package/bin/init.js CHANGED
@@ -9,9 +9,9 @@ const { execSync, spawn } = require('child_process');
9
9
  const LEMMA_CACHE = path.join(os.homedir(), '.lemma-cache');
10
10
  const BRAIN_FILE = path.join(LEMMA_CACHE, 'lemma_brain.json');
11
11
  const ENV_FILE = path.join(LEMMA_CACHE, 'env');
12
- const MCP_SERVER_PATH = path.join(__dirname, '..', 'mcp-server.js');
12
+ const MCP_SERVER_PATH = path.join(__dirname, '..', 'dist', 'cjs', 'mcp', 'index.js');
13
13
  const PROXY_PATH = path.join(__dirname, '..', 'cache-proxy.js');
14
- const PORT = '9090';
14
+ const PORT = '8081';
15
15
  const CYAN = '\x1b[36m', GREEN = '\x1b[32m', YELLOW = '\x1b[33m', DIM = '\x1b[2m', RESET = '\x1b[0m', BOLD = '\x1b[1m';
16
16
 
17
17
  function ensureDir(p) { try { fs.mkdirSync(p, { recursive: true }); } catch {} }
@@ -133,15 +133,20 @@ function configureCodexCliMcp() {
133
133
  function configureOpenCodeMcp() {
134
134
  const configDir = path.join(os.homedir(), '.opencode');
135
135
  const configFile = path.join(configDir, 'mcp.json');
136
+ const lemmaServerConfig = {
137
+ command: 'node',
138
+ args: [MCP_SERVER_PATH],
139
+ type: 'local',
140
+ enabled: true
141
+ };
136
142
  ensureDir(configDir);
137
143
  let config = {};
138
144
  try {
139
145
  if (fs.existsSync(configFile)) config = JSON.parse(fs.readFileSync(configFile, 'utf8'));
140
146
  } catch {}
141
147
  if (!config.mcpServers) config.mcpServers = {};
142
- config.mcpServers['lemma-mcp-server'] = {
143
- command: 'node', args: [MCP_SERVER_PATH], type: 'local', enabled: true
144
- };
148
+ delete config.mcpServers['lemma-mcp-server'];
149
+ config.mcpServers.lemma = lemmaServerConfig;
145
150
  fs.writeFileSync(configFile, JSON.stringify(config, null, 2), 'utf8');
146
151
 
147
152
  const localOpenCode = path.join(process.cwd(), 'opencode.json');
@@ -149,29 +154,45 @@ function configureOpenCodeMcp() {
149
154
  try {
150
155
  const lc = JSON.parse(fs.readFileSync(localOpenCode, 'utf8'));
151
156
  if (!lc.mcp) lc.mcp = {};
152
- if (!lc.mcp['lemma-mcp-server']) {
153
- lc.mcp['lemma-mcp-server'] = {
154
- type: 'local', command: ['node', MCP_SERVER_PATH], enabled: true
155
- };
156
- fs.writeFileSync(localOpenCode, JSON.stringify(lc, null, 2), 'utf8');
157
- }
157
+ delete lc.mcp['lemma-mcp-server'];
158
+ lc.mcp.lemma = {
159
+ type: 'local',
160
+ command: ['node', MCP_SERVER_PATH],
161
+ enabled: true
162
+ };
163
+ fs.writeFileSync(localOpenCode, JSON.stringify(lc, null, 2), 'utf8');
158
164
  } catch {}
159
165
  }
160
166
  return true;
161
167
  }
162
168
 
169
+ function getClaudeDesktopConfigFile() {
170
+ if (process.platform === 'darwin') {
171
+ return path.join(os.homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
172
+ }
173
+ if (process.platform === 'win32' && process.env.APPDATA) {
174
+ return path.join(process.env.APPDATA, 'Claude', 'claude_desktop_config.json');
175
+ }
176
+ return path.join(os.homedir(), '.config', 'Claude', 'claude_desktop_config.json');
177
+ }
178
+
163
179
  function configureClaudeDesktop() {
164
- const configDir = path.join(os.homedir(), '.lemma-cache');
165
- const configFile = path.join(configDir, 'claude_mcp.json');
180
+ const configFile = getClaudeDesktopConfigFile();
181
+ const legacyConfigFile = path.join(os.homedir(), '.lemma-cache', 'claude_mcp.json');
166
182
  let config = {};
167
183
  try {
168
184
  if (fs.existsSync(configFile)) config = JSON.parse(fs.readFileSync(configFile, 'utf8'));
169
185
  } catch {}
186
+ ensureDir(path.dirname(configFile));
170
187
  if (!config.mcpServers) config.mcpServers = {};
171
- config.mcpServers['lemma-mcp-server'] = {
188
+ delete config.mcpServers['lemma-mcp-server'];
189
+ config.mcpServers.lemma = {
172
190
  command: 'node', args: [MCP_SERVER_PATH]
173
191
  };
174
192
  fs.writeFileSync(configFile, JSON.stringify(config, null, 2), 'utf8');
193
+ try {
194
+ if (fs.existsSync(legacyConfigFile)) fs.unlinkSync(legacyConfigFile);
195
+ } catch {}
175
196
  return true;
176
197
  }
177
198
 
package/cache-proxy.js CHANGED
@@ -7,10 +7,21 @@ const fs = require('fs');
7
7
  const path = require('path');
8
8
  const os = require('os');
9
9
 
10
- const PORT = parseInt(process.env.LEMMA_PROXY_PORT || '9090', 10);
10
+ const CACHE_DIR = path.join(os.homedir(), '.lemma-cache');
11
+ const PORT_FILE = path.join(CACHE_DIR, 'proxy.port');
12
+ const PORT = parseInt(process.env.LEMMA_PROXY_PORT || '8081', 10);
11
13
  const UPSTREAM = process.env.LEMMA_UPSTREAM || 'https://api.openai.com';
12
14
  const API_KEY = process.env.LEMMA_API_KEY || process.env.OPENAI_API_KEY || '';
13
- const BRAIN_FILE = path.join(os.homedir(), '.lemma-cache', 'lemma_brain.json');
15
+ const BRAIN_FILE = path.join(CACHE_DIR, 'lemma_brain.json');
16
+
17
+ function persistPort() {
18
+ try {
19
+ fs.mkdirSync(CACHE_DIR, { recursive: true });
20
+ fs.writeFileSync(PORT_FILE, String(PORT), 'utf8');
21
+ } catch (e) {
22
+ console.error('[cache-proxy] Failed to persist proxy.port:', e.message);
23
+ }
24
+ }
14
25
 
15
26
  function loadBrain() {
16
27
  try {
@@ -184,6 +195,7 @@ const server = http.createServer((req, res) => {
184
195
  });
185
196
 
186
197
  server.listen(PORT, () => {
198
+ persistPort();
187
199
  console.error(`[cache-proxy] Lemma Cache Proxy on :${PORT}`);
188
200
  console.error(`[cache-proxy] Upstream: ${UPSTREAM}`);
189
201
  console.error(`[cache-proxy] Caching ANY provider via OpenAI-compatible endpoint`);
@@ -871,7 +871,7 @@ const toolDefinitions = [
871
871
  name: "import_tree_context",
872
872
  description: "Build a bidirectional import graph for a file. Shows what it imports, what imports it, and external dependencies. Zero LLM cost. Essential before refactors.",
873
873
  inputSchema: {
874
- type: "tool",
874
+ type: "object",
875
875
  properties: {
876
876
  filePath: { type: "string", description: "Path relative to the project root" },
877
877
  depth: { type: "number", description: "Traversal depth (default: 2)", default: 2 }