diff --git a/src/example.js b/src/example.js index cdf05cf..d7d8455 100644 --- a/src/example.js +++ b/src/example.js @@ -4,9 +4,7 @@ import StatVitTerm from './stat-vit-term.js'; const termSession = new StatVitTerm(); termSession.on('std', (data) => { - // Entferne ANSI Escape Sequenzen für saubere Ausgabe - const cleanData = data.replace(/\u001b\[[0-9;]*m/g, '').replace(/\u001b\][0-9;]*\u0007/g, ''); - process.stdout.write(cleanData); + process.stdout.write(data); }); termSession.on('err', (data) => { @@ -20,22 +18,19 @@ termSession.on('close', (code) => { termSession.on('ready', () => { console.log('Terminal ready\n'); - // Test mit einem Befehl, der wirklich lange läuft - console.log('--- Starte langen Prozess ---'); - termSession.input('sleep 10 &\n'); // Hintergrundprozess + // Top-Befehl starten + console.log('--- Starte top ---'); + termSession.input('top\n'); + // Nach 3 Sekunden abbrechen setTimeout(() => { - console.log('\n--- Jobs anzeigen ---'); - termSession.input('jobs\n'); - }, 1000); - - setTimeout(() => { - console.log('\n--- Alle Prozesse stoppen ---'); - termSession.input('^C'); // Das sollte alle Prozesse stoppen - }, 2000); + console.log('\n--- Top abbrechen mit ^C ---'); + termSession.input('^C'); + }, 3000); + // Nach 4 Sekunden beenden setTimeout(() => { console.log('\n--- Terminal beenden ---'); termSession.kill(); - }, 3000); + }, 4000); }); \ No newline at end of file diff --git a/src/stat-vit-term.js b/src/stat-vit-term.js index b175290..0170aac 100644 --- a/src/stat-vit-term.js +++ b/src/stat-vit-term.js @@ -8,7 +8,11 @@ class StatVitTerm extends EventEmitter { this.options = { shell: process.platform === 'win32' ? 'cmd.exe' : '/bin/bash', cwd: process.cwd(), - env: process.env, + env: { + ...process.env, + PS1: '$ ', + TERM: 'xterm-256color' + }, ...options }; this.process = null; @@ -18,10 +22,13 @@ class StatVitTerm extends EventEmitter { _init() { try { - this.process = spawn(this.options.shell, [], { + // Wichtige Änderung: Shell im richtigen Modus starten + const args = process.platform === 'win32' ? [] : ['-i', '-l']; // login shell + this.process = spawn(this.options.shell, args, { stdio: ['pipe', 'pipe', 'pipe'], cwd: this.options.cwd, - env: this.options.env + env: this.options.env, + detached: true // Wichtig für Signalbehandlung }); this.process.stdout.on('data', (data) => { @@ -29,7 +36,7 @@ class StatVitTerm extends EventEmitter { }); this.process.stderr.on('data', (data) => { - this.emit('std', data.toString()); // stderr als std behandeln + this.emit('std', data.toString()); }); this.process.on('close', (code) => { @@ -42,9 +49,10 @@ class StatVitTerm extends EventEmitter { }); this.isRunning = true; + setTimeout(() => { this.emit('ready'); - }, 100); + }, 500); } catch (err) { this.emit('err', err.message); @@ -59,11 +67,28 @@ class StatVitTerm extends EventEmitter { try { if (data === '^C') { - // WICHTIG: Sende Ctrl+C direkt an stdin - this.process.stdin.write('\x03'); + // Methode 1: SIGINT an die Prozessgruppe senden + if (process.platform !== 'win32' && this.process.pid) { + try { + process.kill(-this.process.pid, 'SIGINT'); + } catch (e) { + // Fallback: Ctrl+C direkt senden + this.process.stdin.write('\x03'); + } + } else { + this.process.stdin.write('\x03'); + } return true; } else if (data === '^Z') { - this.process.stdin.write('\x1A'); + if (process.platform !== 'win32' && this.process.pid) { + try { + process.kill(-this.process.pid, 'SIGTSTP'); + } catch (e) { + this.process.stdin.write('\x1A'); + } + } else { + this.process.stdin.write('\x1A'); + } return true; } @@ -77,7 +102,25 @@ class StatVitTerm extends EventEmitter { kill() { if (this.process) { - this.process.kill('SIGTERM'); + try { + if (process.platform !== 'win32' && this.process.pid) { + // SIGINT an Prozessgruppe + process.kill(-this.process.pid, 'SIGINT'); + setTimeout(() => { + if (this.process) { + this.process.kill('SIGTERM'); + } + }, 100); + } else { + this.process.kill('SIGTERM'); + } + } catch (err) { + try { + this.process.kill('SIGKILL'); + } catch (err2) { + this.emit('err', 'Could not kill process'); + } + } this.isRunning = false; } }