Integrate terminal input handling into CLI tool using terminal-kit. Implement global key handler for CTRL-C and prompt user for input before initiating the LLM loop. Remove outdated test scripts for improved codebase clarity.
This commit is contained in:
41
src/example.js
Normal file
41
src/example.js
Normal file
@@ -0,0 +1,41 @@
|
||||
// example.js
|
||||
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);
|
||||
});
|
||||
|
||||
termSession.on('err', (data) => {
|
||||
process.stderr.write(data);
|
||||
});
|
||||
|
||||
termSession.on('close', (code) => {
|
||||
console.log(`\nTerminal closed with code: ${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
|
||||
|
||||
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);
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('\n--- Terminal beenden ---');
|
||||
termSession.kill();
|
||||
}, 3000);
|
||||
});
|
||||
94
src/stat-vit-term.js
Normal file
94
src/stat-vit-term.js
Normal file
@@ -0,0 +1,94 @@
|
||||
// stat-vit-term.js
|
||||
import { EventEmitter } from 'events';
|
||||
import { spawn } from 'child_process';
|
||||
|
||||
class StatVitTerm extends EventEmitter {
|
||||
constructor(options = {}) {
|
||||
super();
|
||||
this.options = {
|
||||
shell: process.platform === 'win32' ? 'cmd.exe' : '/bin/bash',
|
||||
cwd: process.cwd(),
|
||||
env: process.env,
|
||||
...options
|
||||
};
|
||||
this.process = null;
|
||||
this.isRunning = false;
|
||||
this._init();
|
||||
}
|
||||
|
||||
_init() {
|
||||
try {
|
||||
this.process = spawn(this.options.shell, [], {
|
||||
stdio: ['pipe', 'pipe', 'pipe'],
|
||||
cwd: this.options.cwd,
|
||||
env: this.options.env
|
||||
});
|
||||
|
||||
this.process.stdout.on('data', (data) => {
|
||||
this.emit('std', data.toString());
|
||||
});
|
||||
|
||||
this.process.stderr.on('data', (data) => {
|
||||
this.emit('std', data.toString()); // stderr als std behandeln
|
||||
});
|
||||
|
||||
this.process.on('close', (code) => {
|
||||
this.isRunning = false;
|
||||
this.emit('close', code);
|
||||
});
|
||||
|
||||
this.process.on('error', (err) => {
|
||||
this.emit('err', err.message);
|
||||
});
|
||||
|
||||
this.isRunning = true;
|
||||
setTimeout(() => {
|
||||
this.emit('ready');
|
||||
}, 100);
|
||||
|
||||
} catch (err) {
|
||||
this.emit('err', err.message);
|
||||
}
|
||||
}
|
||||
|
||||
input(data) {
|
||||
if (!this.isRunning || !this.process) {
|
||||
this.emit('err', 'Terminal is not running');
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
if (data === '^C') {
|
||||
// WICHTIG: Sende Ctrl+C direkt an stdin
|
||||
this.process.stdin.write('\x03');
|
||||
return true;
|
||||
} else if (data === '^Z') {
|
||||
this.process.stdin.write('\x1A');
|
||||
return true;
|
||||
}
|
||||
|
||||
this.process.stdin.write(data);
|
||||
return true;
|
||||
} catch (err) {
|
||||
this.emit('err', err.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
kill() {
|
||||
if (this.process) {
|
||||
this.process.kill('SIGTERM');
|
||||
this.isRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
get pid() {
|
||||
return this.process ? this.process.pid : null;
|
||||
}
|
||||
|
||||
get running() {
|
||||
return this.isRunning;
|
||||
}
|
||||
}
|
||||
|
||||
export default StatVitTerm;
|
||||
Reference in New Issue
Block a user