@oxis-dev/tessra 2.19.6 → 2.19.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxis-dev/tessra",
3
- "version": "2.19.6",
3
+ "version": "2.19.8",
4
4
  "description": "MCP server for AI coding tools and agents. Provides semantic codebase context for Cursor, Claude Code, Codex, Copilot, Antigravity, and CLI workflows without requiring full file uploads.",
5
5
  "license": "UNLICENSED",
6
6
  "author": {
@@ -328,31 +328,47 @@ function repairLinuxShellPath(binDir) {
328
328
  }
329
329
 
330
330
  // En Linux con nvm/fnm, el bin de node solo está en PATH en shells interactivos.
331
- // Crear un symlink del binario nativo en ~/.local/bin garantiza que tessra sea
332
- // accesible en cualquier contexto: scripts, IDEs lanzando MCP, shells de login.
333
- function installLinuxLocalBinSymlink(binaryPath) {
331
+ // Copia el binario nativo en ~/.local/bin y agrega ese dir al PATH en los perfiles
332
+ // de shell para que tessra funcione en terminales nuevas sin pasos extra del usuario.
333
+ function installLinuxLocalBin(binaryPath) {
334
334
  const home = process.env.HOME;
335
335
  if (!home) return;
336
336
 
337
337
  const localBin = path.join(home, '.local', 'bin');
338
- const symlinkPath = path.join(localBin, 'tessra');
338
+ const destPath = path.join(localBin, 'tessra');
339
339
 
340
+ // ── 1. Copiar el binario (no symlink — así no depende de la ruta de npm/nvm) ─
340
341
  try {
341
342
  if (!fs.existsSync(localBin)) {
342
343
  fs.mkdirSync(localBin, { recursive: true });
343
344
  }
344
345
 
345
- try {
346
- fs.lstatSync(symlinkPath); // lanza si no existe
347
- fs.unlinkSync(symlinkPath);
348
- } catch (_) { /* no existía — bien */ }
349
-
350
- fs.symlinkSync(binaryPath, symlinkPath);
351
- console.log(`tessra: symlink creado en ${symlinkPath} (disponible sin nvm activo).`);
346
+ fs.copyFileSync(binaryPath, destPath);
347
+ fs.chmodSync(destPath, 0o755);
348
+ console.log(`tessra: binario copiado en ${destPath}.`);
352
349
  } catch (err) {
353
- // No fatal — tessra sigue disponible vía el bin de npm si nvm está activo
354
- console.warn(`tessra: no se pudo crear symlink en ${symlinkPath}: ${err.message}`);
350
+ console.warn(`tessra: no se pudo copiar binario en ${destPath}: ${err.message}`);
351
+ return; // si no pudo copiar, no tiene sentido agregar al PATH
352
+ }
353
+
354
+ // ── 2. Agregar ~/.local/bin al PATH en .bashrc y .profile ────────────────────
355
+ const profilesToPatch = [
356
+ path.join(home, '.bashrc'),
357
+ path.join(home, '.profile'),
358
+ ];
359
+ const shellName = path.basename(process.env.SHELL || '');
360
+ if (shellName === 'zsh') {
361
+ profilesToPatch.push(path.join(home, '.zshrc'));
355
362
  }
363
+
364
+ const patched = [];
365
+ for (const profilePath of profilesToPatch) {
366
+ try {
367
+ const result = upsertLinuxProfilePath(profilePath, localBin);
368
+ if (result.changed) patched.push(path.basename(profilePath));
369
+ } catch (_) { /* no fatal */ }
370
+ }
371
+
356
372
  }
357
373
 
358
374
  function ensureGlobalBinOnPath() {
@@ -409,6 +425,59 @@ function ensureGlobalBinOnPath() {
409
425
  }
410
426
  }
411
427
 
428
+ // ── Resumen final de instalación ─────────────────────────────────────────────
429
+
430
+ function printInstallSummary() {
431
+ const W = 54;
432
+ const line = '─'.repeat(W);
433
+ const green = (s) => `\x1b[32m${s}\x1b[0m`;
434
+ const pad = (s) => {
435
+ const visible = s.replace(/\x1b\[[0-9;]*m/g, '');
436
+ return s + ' '.repeat(Math.max(0, W - visible.length));
437
+ };
438
+ const box = (rows) => {
439
+ console.log(`\n┌${line}┐`);
440
+ for (const row of rows) console.log(`│ ${pad(row)} │`);
441
+ console.log(`└${line}┘\n`);
442
+ };
443
+
444
+ const platform = process.platform;
445
+ const shellName = path.basename(process.env.SHELL || '');
446
+ const title = green(`Tessra ${VERSION} instalado`);
447
+
448
+ if (platform === 'linux') {
449
+ box([
450
+ title,
451
+ '',
452
+ 'Abre una nueva terminal y ejecuta:',
453
+ ' tessra --help',
454
+ '',
455
+ 'O actívalo en esta sesión sin cerrarla:',
456
+ ' source ~/.bashrc (bash)',
457
+ ' source ~/.zshrc (zsh)',
458
+ ]);
459
+ } else if (platform === 'darwin') {
460
+ box([
461
+ title,
462
+ '',
463
+ 'Abre una nueva terminal y ejecuta:',
464
+ ' tessra --help',
465
+ '',
466
+ 'O actívalo en esta sesión sin cerrarla:',
467
+ ' source ~/.zshrc (zsh, macOS por defecto)',
468
+ ' source ~/.bash_profile (bash)',
469
+ ]);
470
+ } else if (platform === 'win32') {
471
+ box([
472
+ title,
473
+ '',
474
+ 'PATH actualizado en Windows.',
475
+ 'Abre una nueva ventana de PowerShell o CMD',
476
+ 'y ejecuta: tessra --help',
477
+ ]);
478
+ }
479
+ }
480
+
412
481
  // ── Main ─────────────────────────────────────────────────────────────────────
413
482
 
414
483
  async function main() {
@@ -450,14 +519,13 @@ async function main() {
450
519
  // --version puede fallar si el binario requiere inicialización — no es fatal
451
520
  }
452
521
 
453
- // En Linux: symlink en ~/.local/bin para que tessra funcione sin nvm activo
522
+ // En Linux: copiar binario en ~/.local/bin y parchear PATH en perfiles de shell
454
523
  if (process.platform === 'linux') {
455
- installLinuxLocalBinSymlink(dest);
524
+ installLinuxLocalBin(dest);
456
525
  }
457
526
 
458
527
  ensureGlobalBinOnPath();
459
-
460
- console.log(`tessra: binario instalado correctamente en ${dest}`);
528
+ printInstallSummary();
461
529
  }
462
530
 
463
531
  main().catch((err) => {