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:
17
package-lock.json
generated
17
package-lock.json
generated
@@ -42,6 +42,7 @@
|
||||
"ms": "^2.1.3",
|
||||
"node-domexception": "^1.0.0",
|
||||
"node-fetch": "^2.7.0",
|
||||
"node-pty": "^1.0.0",
|
||||
"openai": "^4.104.0",
|
||||
"resolve-pkg-maps": "^1.0.0",
|
||||
"terminal-kit": "^3.1.2",
|
||||
@@ -945,6 +946,12 @@
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"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": {
|
||||
"version": "1.0.19",
|
||||
"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": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz",
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
"type": "module",
|
||||
"main": "cli.js",
|
||||
"dependencies": {
|
||||
"terminal-kit": "^3.1.2",
|
||||
"dotenv": "^16.4.5",
|
||||
"abort-controller": "^3.0.0",
|
||||
"agentkeepalive": "^4.6.0",
|
||||
"asynckit": "^0.4.0",
|
||||
@@ -13,6 +11,7 @@
|
||||
"chalk": "^5.5.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"delayed-stream": "^1.0.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"dunder-proto": "^1.0.1",
|
||||
"es-define-property": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
@@ -38,8 +37,10 @@
|
||||
"ms": "^2.1.3",
|
||||
"node-domexception": "^1.0.0",
|
||||
"node-fetch": "^2.7.0",
|
||||
"node-pty": "^1.0.0",
|
||||
"openai": "^4.104.0",
|
||||
"resolve-pkg-maps": "^1.0.0",
|
||||
"terminal-kit": "^3.1.2",
|
||||
"tr46": "^0.0.3",
|
||||
"tsx": "^4.20.3",
|
||||
"typescript": "^5.9.2",
|
||||
|
||||
@@ -27,10 +27,6 @@ termSession.on('ready', () => {
|
||||
console.log('\n--- Ping abbrechen mit ^C ---');
|
||||
termSession.input('^C');
|
||||
|
||||
termSession.input("sdfsdfsdaf\n");
|
||||
termSession.input("\n");
|
||||
termSession.input("\n");
|
||||
termSession.input("\n");
|
||||
}, 3000);
|
||||
|
||||
// Nach 4 Sekunden beenden
|
||||
|
||||
@@ -1,138 +1,45 @@
|
||||
// stat-vit-term.js
|
||||
import { EventEmitter } from 'events';
|
||||
import { spawn } from 'child_process';
|
||||
// src/stat-vit-term.js
|
||||
|
||||
import pty from 'node-pty';
|
||||
|
||||
class StatVitTerm extends EventEmitter {
|
||||
constructor(options = {}) {
|
||||
super();
|
||||
this.options = {
|
||||
shell: process.platform === 'win32' ? 'cmd.exe' : '/bin/bash',
|
||||
const shell = process.platform === 'win32' ? 'powershell.exe' : 'bash';
|
||||
|
||||
const ptyProcess = pty.spawn(shell, [], {
|
||||
name: 'xterm-256color',
|
||||
cols: 120,
|
||||
rows: 30,
|
||||
cwd: process.cwd(),
|
||||
env: {
|
||||
...process.env,
|
||||
PS1: '$ ',
|
||||
TERM: 'xterm-256color'
|
||||
TERM: 'xterm-256color',
|
||||
COLORTERM: 'truecolor',
|
||||
LANG: 'en_US.UTF-8',
|
||||
PWD: process.cwd(),
|
||||
},
|
||||
...options
|
||||
};
|
||||
this.process = null;
|
||||
this.isRunning = false;
|
||||
this._init();
|
||||
}
|
||||
|
||||
_init() {
|
||||
try {
|
||||
// Wichtige Änderung: Shell im richtigen Modus starten
|
||||
const args = process.platform === 'win32' ? [] : ['-l']; // login shell
|
||||
this.process = spawn(this.options.shell, args, {
|
||||
stdio: ['pipe', 'pipe', 'pipe'],
|
||||
cwd: this.options.cwd,
|
||||
env: this.options.env,
|
||||
detached: true // Wichtig für Signalbehandlung
|
||||
});
|
||||
|
||||
this.process.stdout.on('data', (data) => {
|
||||
this.emit('std', data.toString());
|
||||
// Handle output
|
||||
ptyProcess.onData((data) => {
|
||||
process.stdout.write(data); // Preserve formatting
|
||||
});
|
||||
|
||||
this.process.stderr.on('data', (data) => {
|
||||
this.emit('std', data.toString());
|
||||
// Handle exit
|
||||
ptyProcess.onExit(({ exitCode, signal }) => {
|
||||
console.log(`\n\n✨ Shell exited with code ${exitCode}${signal ? ` (via signal ${signal})` : ''}`);
|
||||
});
|
||||
|
||||
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;
|
||||
// Simulate input
|
||||
setTimeout(() => {
|
||||
console.log('\n[INPUT] Starting ping...');
|
||||
ptyProcess.write('ping 127.0.0.1\r');
|
||||
}, 1000);
|
||||
|
||||
setTimeout(() => {
|
||||
this.emit('ready');
|
||||
}, 500);
|
||||
console.log('\n[INPUT] Sending Ctrl+C...');
|
||||
ptyProcess.write('\x03'); // Ctrl+C
|
||||
}, 5000);
|
||||
|
||||
} 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;
|
||||
console.log('\n[INPUT] Exiting shell...');
|
||||
ptyProcess.write('exit\r');
|
||||
}, 7000);
|
||||
Reference in New Issue
Block a user