Update package dependencies to include node-pty for improved terminal handling. Refactor stat-vit-term.js to utilize node-pty for process management and streamline input simulation. Clean up example.js by removing unnecessary input commands.

This commit is contained in:
sebseb7
2025-08-12 01:36:10 +02:00
parent 2c83d402fc
commit 91d28779d6
4 changed files with 57 additions and 136 deletions

17
package-lock.json generated
View File

@@ -42,6 +42,7 @@
"ms": "^2.1.3", "ms": "^2.1.3",
"node-domexception": "^1.0.0", "node-domexception": "^1.0.0",
"node-fetch": "^2.7.0", "node-fetch": "^2.7.0",
"node-pty": "^1.0.0",
"openai": "^4.104.0", "openai": "^4.104.0",
"resolve-pkg-maps": "^1.0.0", "resolve-pkg-maps": "^1.0.0",
"terminal-kit": "^3.1.2", "terminal-kit": "^3.1.2",
@@ -945,6 +946,12 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/nan": {
"version": "2.23.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.23.0.tgz",
"integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==",
"license": "MIT"
},
"node_modules/ndarray": { "node_modules/ndarray": {
"version": "1.0.19", "version": "1.0.19",
"resolved": "https://registry.npmjs.org/ndarray/-/ndarray-1.0.19.tgz", "resolved": "https://registry.npmjs.org/ndarray/-/ndarray-1.0.19.tgz",
@@ -1022,6 +1029,16 @@
} }
} }
}, },
"node_modules/node-pty": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-pty/-/node-pty-1.0.0.tgz",
"integrity": "sha512-wtBMWWS7dFZm/VgqElrTvtfMq4GzJ6+edFI0Y0zyzygUSZMgZdraDUMUhCIvkjhJjme15qWmbyJbtAx4ot4uZA==",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"nan": "^2.17.0"
}
},
"node_modules/omggif": { "node_modules/omggif": {
"version": "1.0.10", "version": "1.0.10",
"resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz",

View File

@@ -4,8 +4,6 @@
"type": "module", "type": "module",
"main": "cli.js", "main": "cli.js",
"dependencies": { "dependencies": {
"terminal-kit": "^3.1.2",
"dotenv": "^16.4.5",
"abort-controller": "^3.0.0", "abort-controller": "^3.0.0",
"agentkeepalive": "^4.6.0", "agentkeepalive": "^4.6.0",
"asynckit": "^0.4.0", "asynckit": "^0.4.0",
@@ -13,6 +11,7 @@
"chalk": "^5.5.0", "chalk": "^5.5.0",
"combined-stream": "^1.0.8", "combined-stream": "^1.0.8",
"delayed-stream": "^1.0.0", "delayed-stream": "^1.0.0",
"dotenv": "^16.4.5",
"dunder-proto": "^1.0.1", "dunder-proto": "^1.0.1",
"es-define-property": "^1.0.1", "es-define-property": "^1.0.1",
"es-errors": "^1.3.0", "es-errors": "^1.3.0",
@@ -38,8 +37,10 @@
"ms": "^2.1.3", "ms": "^2.1.3",
"node-domexception": "^1.0.0", "node-domexception": "^1.0.0",
"node-fetch": "^2.7.0", "node-fetch": "^2.7.0",
"node-pty": "^1.0.0",
"openai": "^4.104.0", "openai": "^4.104.0",
"resolve-pkg-maps": "^1.0.0", "resolve-pkg-maps": "^1.0.0",
"terminal-kit": "^3.1.2",
"tr46": "^0.0.3", "tr46": "^0.0.3",
"tsx": "^4.20.3", "tsx": "^4.20.3",
"typescript": "^5.9.2", "typescript": "^5.9.2",

View File

@@ -27,10 +27,6 @@ termSession.on('ready', () => {
console.log('\n--- Ping abbrechen mit ^C ---'); console.log('\n--- Ping abbrechen mit ^C ---');
termSession.input('^C'); termSession.input('^C');
termSession.input("sdfsdfsdaf\n");
termSession.input("\n");
termSession.input("\n");
termSession.input("\n");
}, 3000); }, 3000);
// Nach 4 Sekunden beenden // Nach 4 Sekunden beenden

View File

@@ -1,138 +1,45 @@
// stat-vit-term.js // src/stat-vit-term.js
import { EventEmitter } from 'events';
import { spawn } from 'child_process';
import pty from 'node-pty';
class StatVitTerm extends EventEmitter { const shell = process.platform === 'win32' ? 'powershell.exe' : 'bash';
constructor(options = {}) {
super();
this.options = {
shell: process.platform === 'win32' ? 'cmd.exe' : '/bin/bash',
cwd: process.cwd(),
env: {
...process.env,
PS1: '$ ',
TERM: 'xterm-256color'
},
...options
};
this.process = null;
this.isRunning = false;
this._init();
}
_init() { const ptyProcess = pty.spawn(shell, [], {
try { name: 'xterm-256color',
// Wichtige Änderung: Shell im richtigen Modus starten cols: 120,
const args = process.platform === 'win32' ? [] : ['-l']; // login shell rows: 30,
this.process = spawn(this.options.shell, args, { cwd: process.cwd(),
stdio: ['pipe', 'pipe', 'pipe'], env: {
cwd: this.options.cwd, ...process.env,
env: this.options.env, TERM: 'xterm-256color',
detached: true // Wichtig für Signalbehandlung COLORTERM: 'truecolor',
}); LANG: 'en_US.UTF-8',
PWD: process.cwd(),
},
});
this.process.stdout.on('data', (data) => { // Handle output
this.emit('std', data.toString()); ptyProcess.onData((data) => {
}); process.stdout.write(data); // Preserve formatting
});
this.process.stderr.on('data', (data) => { // Handle exit
this.emit('std', data.toString()); ptyProcess.onExit(({ exitCode, signal }) => {
}); console.log(`\n\n✨ Shell exited with code ${exitCode}${signal ? ` (via signal ${signal})` : ''}`);
});
this.process.on('close', (code) => { // Simulate input
this.isRunning = false; setTimeout(() => {
this.emit('close', code); console.log('\n[INPUT] Starting ping...');
}); ptyProcess.write('ping 127.0.0.1\r');
}, 1000);
this.process.on('error', (err) => { setTimeout(() => {
this.emit('err', err.message); console.log('\n[INPUT] Sending Ctrl+C...');
}); ptyProcess.write('\x03'); // Ctrl+C
}, 5000);
this.isRunning = true; setTimeout(() => {
console.log('\n[INPUT] Exiting shell...');
setTimeout(() => { ptyProcess.write('exit\r');
this.emit('ready'); }, 7000);
}, 500);
} 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') {
// 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') {
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;
}
this.process.stdin.write(data);
return true;
} catch (err) {
this.emit('err', err.message);
return false;
}
}
kill() {
if (this.process) {
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;
}
}
get pid() {
return this.process ? this.process.pid : null;
}
get running() {
return this.isRunning;
}
}
export default StatVitTerm;