@zuvia-software-solutions/code-mapper 2.3.10 → 2.3.12

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.
@@ -291,6 +291,7 @@ export const analyzeCommand = async (inputPath, options) => {
291
291
  }
292
292
  // Phase 4: Embeddings (90-98%)
293
293
  const stats = getStats(db);
294
+ let embeddingFailed = false;
294
295
  if (options?.embeddings) {
295
296
  recordPhase('embeddings');
296
297
  updateBar(90, 'Generating embeddings...');
@@ -301,7 +302,7 @@ export const analyzeCommand = async (inputPath, options) => {
301
302
  const { spawn: spawnChild } = await import('child_process');
302
303
  const { fileURLToPath } = await import('url');
303
304
  const mlxScript = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..', 'models', 'mlx-embedder.py');
304
- await new Promise((resolve, reject) => {
305
+ await new Promise((resolve) => {
305
306
  // Use spawn (not execFile) — no internal buffer limit, streams only.
306
307
  // execFile buffers all stdout in memory which causes OOM/kill on large codebases.
307
308
  const proc = spawnChild('python3', [mlxScript, 'batch', dbPath, '--dims', '256', '--max-tokens', '2048'], {
@@ -310,21 +311,23 @@ export const analyzeCommand = async (inputPath, options) => {
310
311
  let stderrBuf = '';
311
312
  proc.stderr?.on('data', (chunk) => {
312
313
  stderrBuf += chunk.toString();
313
- // Keep only last 10KB of stderr for error reporting
314
314
  if (stderrBuf.length > 10240)
315
315
  stderrBuf = stderrBuf.slice(-10240);
316
316
  });
317
317
  proc.on('close', (code) => {
318
318
  if (code !== 0) {
319
- console.error(stderrBuf);
320
- reject(new Error(`Embedding failed: python3 exited with code ${code}`));
321
- }
322
- else {
323
- resolve();
319
+ // Non-fatal: index is already saved, just embeddings failed
320
+ console.error(`\n Warning: Embedding failed (exit code ${code}). Index saved without embeddings.`);
321
+ if (stderrBuf.trim())
322
+ console.error(` ${stderrBuf.trim().split('\n').slice(-3).join('\n ')}`);
323
+ embeddingFailed = true;
324
324
  }
325
+ resolve();
325
326
  });
326
327
  proc.on('error', (err) => {
327
- reject(new Error(`Embedding failed: ${err.message}`));
328
+ console.error(`\n Warning: Embedding failed: ${err.message}. Index saved without embeddings.`);
329
+ embeddingFailed = true;
330
+ resolve();
328
331
  });
329
332
  // Stream progress from Python's JSON lines on stdout
330
333
  let lineBuf = '';
@@ -422,7 +425,8 @@ export const analyzeCommand = async (inputPath, options) => {
422
425
  process.stdout.write('\x1b[2K');
423
426
  // Summary
424
427
  const embeddingsCached = cachedEmbeddings.length > 0;
425
- console.log(`\n Repository indexed successfully (${totalTime}s)${embeddingsCached ? ` [${cachedEmbeddings.length} embeddings cached]` : ''}\n`);
428
+ const embeddingNote = embeddingFailed ? ' [embeddings failed — re-run with --embeddings]' : embeddingsCached ? ` [${cachedEmbeddings.length} embeddings cached]` : '';
429
+ console.log(`\n Repository indexed successfully (${totalTime}s)${embeddingNote}\n`);
426
430
  console.log(` ${stats.nodes.toLocaleString()} nodes | ${stats.edges.toLocaleString()} edges | ${pipelineResult.communityResult?.stats.totalCommunities || 0} clusters | ${pipelineResult.processResult?.stats.totalProcesses || 0} flows`);
427
431
  // Resource usage
428
432
  const cpuEnd = process.cpuUsage(cpuStart);
@@ -294,16 +294,32 @@ export class TsgoService {
294
294
  }
295
295
  }
296
296
  findTsgoBinary() {
297
- // Try resolving via the @typescript/native-preview platform package
297
+ const pkgName = `@typescript/native-preview-${process.platform}-${process.arch}`;
298
+ // 1. Try resolving from the global install (code-mapper's own node_modules)
298
299
  try {
299
- const pkgName = `@typescript/native-preview-${process.platform}-${process.arch}`;
300
300
  const pkgJsonPath = esmRequire.resolve(`${pkgName}/package.json`);
301
301
  const exe = path.join(path.dirname(pkgJsonPath), 'lib', 'tsgo');
302
302
  if (fs.existsSync(exe))
303
303
  return exe;
304
304
  }
305
305
  catch { }
306
- // Try which/where
306
+ // 2. Try resolving from the PROJECT's node_modules (where devDependencies live)
307
+ try {
308
+ const projectRequire = createRequire(path.join(this.projectRoot, 'node_modules', '.package-lock.json'));
309
+ const pkgJsonPath = projectRequire.resolve(`${pkgName}/package.json`);
310
+ const exe = path.join(path.dirname(pkgJsonPath), 'lib', 'tsgo');
311
+ if (fs.existsSync(exe))
312
+ return exe;
313
+ }
314
+ catch { }
315
+ // 3. Try direct path in project's node_modules
316
+ try {
317
+ const exe = path.join(this.projectRoot, 'node_modules', pkgName, 'lib', 'tsgo');
318
+ if (fs.existsSync(exe))
319
+ return exe;
320
+ }
321
+ catch { }
322
+ // 4. Try which/where (on PATH)
307
323
  try {
308
324
  const cmd = process.platform === 'win32' ? 'where' : 'which';
309
325
  const result = execFileSync(cmd, ['tsgo'], { encoding: 'utf-8', timeout: 3000 }).trim();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zuvia-software-solutions/code-mapper",
3
- "version": "2.3.10",
3
+ "version": "2.3.12",
4
4
  "description": "Graph-powered code intelligence for AI agents. Index any codebase, query via MCP or CLI.",
5
5
  "author": "Abhigyan Patwari",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",