lunel-cli 0.1.5 → 0.1.7

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.
Files changed (2) hide show
  1. package/dist/index.js +50 -43
  2. package/package.json +1 -2
package/dist/index.js CHANGED
@@ -8,9 +8,8 @@ import * as path from "path";
8
8
  import * as os from "os";
9
9
  import { spawn, execSync } from "child_process";
10
10
  import { createServer } from "net";
11
- import * as pty from "node-pty";
12
11
  const PROXY_URL = process.env.LUNEL_PROXY_URL || "https://gateway.lunel.dev";
13
- const VERSION = "0.1.4";
12
+ const VERSION = "0.1.6";
14
13
  // Root directory - sandbox all file operations to this
15
14
  const ROOT_DIR = process.cwd();
16
15
  const terminals = new Map();
@@ -481,40 +480,61 @@ async function handleGitDiscard(payload) {
481
480
  // ============================================================================
482
481
  let dataChannel = null;
483
482
  function handleTerminalSpawn(payload) {
484
- const shell = payload.shell || process.env.SHELL || (os.platform() === 'win32' ? 'powershell.exe' : '/bin/bash');
485
- const cols = payload.cols || 80;
486
- const rows = payload.rows || 24;
483
+ // Find a working shell
484
+ let shell = payload.shell || process.env.SHELL || '';
485
+ const possibleShells = os.platform() === 'win32'
486
+ ? ['powershell.exe', 'cmd.exe']
487
+ : [shell, '/bin/zsh', '/bin/bash', '/bin/sh'].filter(Boolean);
488
+ shell = '';
489
+ for (const candidate of possibleShells) {
490
+ if (!candidate)
491
+ continue;
492
+ try {
493
+ if (os.platform() !== 'win32') {
494
+ execSync(`test -x "${candidate}"`, { stdio: 'ignore' });
495
+ }
496
+ shell = candidate;
497
+ break;
498
+ }
499
+ catch {
500
+ // Try next
501
+ }
502
+ }
503
+ if (!shell) {
504
+ throw Object.assign(new Error('No valid shell found'), { code: 'ENOSHELL' });
505
+ }
487
506
  const terminalId = `term-${Date.now()}-${Math.random().toString(36).substring(2, 8)}`;
488
- // Spawn PTY process
489
- const ptyProcess = pty.spawn(shell, [], {
490
- name: 'xterm-256color',
491
- cols,
492
- rows,
507
+ // Clean environment
508
+ const cleanEnv = {};
509
+ for (const [key, value] of Object.entries(process.env)) {
510
+ if (value !== undefined) {
511
+ cleanEnv[key] = value;
512
+ }
513
+ }
514
+ cleanEnv['TERM'] = 'dumb'; // Simple terminal - no escape codes
515
+ // Spawn shell process
516
+ const proc = spawn(shell, ['-i'], {
493
517
  cwd: ROOT_DIR,
494
- env: {
495
- ...process.env,
496
- TERM: 'xterm-256color',
497
- },
518
+ env: cleanEnv,
519
+ stdio: ['pipe', 'pipe', 'pipe'],
498
520
  });
499
- terminals.set(terminalId, {
500
- pty: ptyProcess,
501
- cols,
502
- rows,
503
- });
504
- // Stream output to app via data channel
505
- ptyProcess.onData((data) => {
521
+ terminals.set(terminalId, { proc, shell });
522
+ // Stream output to app
523
+ const sendOutput = (data) => {
506
524
  if (dataChannel && dataChannel.readyState === WebSocket.OPEN) {
507
525
  const msg = {
508
526
  v: 1,
509
527
  id: `evt-${Date.now()}`,
510
528
  ns: "terminal",
511
529
  action: "output",
512
- payload: { terminalId, data },
530
+ payload: { terminalId, data: data.toString() },
513
531
  };
514
532
  dataChannel.send(JSON.stringify(msg));
515
533
  }
516
- });
517
- ptyProcess.onExit(({ exitCode }) => {
534
+ };
535
+ proc.stdout?.on('data', sendOutput);
536
+ proc.stderr?.on('data', sendOutput);
537
+ proc.on('close', (code) => {
518
538
  terminals.delete(terminalId);
519
539
  if (dataChannel && dataChannel.readyState === WebSocket.OPEN) {
520
540
  const msg = {
@@ -522,12 +542,12 @@ function handleTerminalSpawn(payload) {
522
542
  id: `evt-${Date.now()}`,
523
543
  ns: "terminal",
524
544
  action: "exit",
525
- payload: { terminalId, code: exitCode },
545
+ payload: { terminalId, code: code || 0 },
526
546
  };
527
547
  dataChannel.send(JSON.stringify(msg));
528
548
  }
529
549
  });
530
- return { terminalId };
550
+ return { terminalId, shell };
531
551
  }
532
552
  function handleTerminalWrite(payload) {
533
553
  const terminalId = payload.terminalId;
@@ -539,24 +559,11 @@ function handleTerminalWrite(payload) {
539
559
  const session = terminals.get(terminalId);
540
560
  if (!session)
541
561
  throw Object.assign(new Error("Terminal not found"), { code: "ENOTERM" });
542
- session.pty.write(data);
562
+ session.proc.stdin?.write(data);
543
563
  return {};
544
564
  }
545
565
  function handleTerminalResize(payload) {
546
- const terminalId = payload.terminalId;
547
- const cols = payload.cols;
548
- const rows = payload.rows;
549
- if (!terminalId)
550
- throw Object.assign(new Error("terminalId is required"), { code: "EINVAL" });
551
- if (!cols || !rows)
552
- throw Object.assign(new Error("cols and rows are required"), { code: "EINVAL" });
553
- const session = terminals.get(terminalId);
554
- if (!session)
555
- throw Object.assign(new Error("Terminal not found"), { code: "ENOTERM" });
556
- // Resize PTY
557
- session.pty.resize(cols, rows);
558
- session.cols = cols;
559
- session.rows = rows;
566
+ // No-op for simple terminal - resize not supported without PTY
560
567
  return {};
561
568
  }
562
569
  function handleTerminalKill(payload) {
@@ -566,7 +573,7 @@ function handleTerminalKill(payload) {
566
573
  const session = terminals.get(terminalId);
567
574
  if (!session)
568
575
  throw Object.assign(new Error("Terminal not found"), { code: "ENOTERM" });
569
- session.pty.kill();
576
+ session.proc.kill();
570
577
  terminals.delete(terminalId);
571
578
  return {};
572
579
  }
@@ -1363,7 +1370,7 @@ function connectWebSocket(code) {
1363
1370
  console.log("\nShutting down...");
1364
1371
  // Kill all terminals
1365
1372
  for (const [id, session] of terminals) {
1366
- session.pty.kill();
1373
+ session.proc.kill();
1367
1374
  }
1368
1375
  terminals.clear();
1369
1376
  // Kill all managed processes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lunel-cli",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "author": [
5
5
  {
6
6
  "name": "Soham Bharambe",
@@ -26,7 +26,6 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "ignore": "^6.0.2",
29
- "node-pty": "^1.0.0",
30
29
  "qrcode-terminal": "^0.12.0",
31
30
  "ws": "^8.18.0"
32
31
  },