agentgui 1.0.489 → 1.0.490
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.
- package/package.json +2 -1
- package/server.js +72 -26
- package/static/js/terminal.js +28 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentgui",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.490",
|
|
4
4
|
"description": "Multi-agent ACP client with real-time communication",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "server.js",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"form-data": "^4.0.5",
|
|
33
33
|
"fsbrowse": "^0.2.18",
|
|
34
34
|
"google-auth-library": "^10.5.0",
|
|
35
|
+
"node-pty": "^1.0.0",
|
|
35
36
|
"onnxruntime-node": "1.21.0",
|
|
36
37
|
"opencode-ai": "^1.2.15",
|
|
37
38
|
"puppeteer-core": "^24.37.5",
|
package/server.js
CHANGED
|
@@ -4090,33 +4090,79 @@ wsRouter.onLegacy((data, ws) => {
|
|
|
4090
4090
|
if (ws.terminalProc) {
|
|
4091
4091
|
try { ws.terminalProc.kill(); } catch(e) {}
|
|
4092
4092
|
}
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4093
|
+
try {
|
|
4094
|
+
const pty = require('node-pty');
|
|
4095
|
+
const shell = process.env.SHELL || '/bin/bash';
|
|
4096
|
+
const cwd = data.cwd || process.env.STARTUP_CWD || process.env.HOME || '/';
|
|
4097
|
+
const proc = pty.spawn(shell, [], {
|
|
4098
|
+
name: 'xterm-256color',
|
|
4099
|
+
cols: data.cols || 80,
|
|
4100
|
+
rows: data.rows || 24,
|
|
4101
|
+
cwd: cwd,
|
|
4102
|
+
env: { ...process.env, TERM: 'xterm-256color', COLORTERM: 'truecolor' }
|
|
4103
|
+
});
|
|
4104
|
+
ws.terminalProc = proc;
|
|
4105
|
+
ws.terminalPty = true;
|
|
4106
|
+
proc.on('data', (chunk) => {
|
|
4107
|
+
if (ws.readyState === 1) ws.send(JSON.stringify({ type: 'terminal_output', data: chunk.toString('base64'), encoding: 'base64' }));
|
|
4108
|
+
});
|
|
4109
|
+
proc.on('exit', (code) => {
|
|
4110
|
+
if (ws.readyState === 1) ws.send(JSON.stringify({ type: 'terminal_exit', code }));
|
|
4111
|
+
ws.terminalProc = null;
|
|
4112
|
+
});
|
|
4113
|
+
proc.on('error', (err) => {
|
|
4114
|
+
console.error('[TERMINAL] PTY error (contained):', err.message);
|
|
4115
|
+
if (ws.readyState === 1) ws.send(JSON.stringify({ type: 'terminal_exit', code: 1, error: err.message }));
|
|
4116
|
+
ws.terminalProc = null;
|
|
4117
|
+
});
|
|
4118
|
+
ws.send(JSON.stringify({ type: 'terminal_started', timestamp: Date.now() }));
|
|
4119
|
+
} catch (e) {
|
|
4120
|
+
console.error('[TERMINAL] Failed to spawn PTY, falling back to pipes:', e.message);
|
|
4121
|
+
const { spawn } = require('child_process');
|
|
4122
|
+
const shell = process.env.SHELL || '/bin/bash';
|
|
4123
|
+
const cwd = data.cwd || process.env.STARTUP_CWD || process.env.HOME || '/';
|
|
4124
|
+
const proc = spawn(shell, ['-i'], { cwd, env: { ...process.env, TERM: 'xterm-256color', COLORTERM: 'truecolor' }, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
4125
|
+
ws.terminalProc = proc;
|
|
4126
|
+
ws.terminalPty = false;
|
|
4127
|
+
proc.stdout.on('data', (chunk) => {
|
|
4128
|
+
if (ws.readyState === 1) ws.send(JSON.stringify({ type: 'terminal_output', data: chunk.toString('base64'), encoding: 'base64' }));
|
|
4129
|
+
});
|
|
4130
|
+
proc.stderr.on('data', (chunk) => {
|
|
4131
|
+
if (ws.readyState === 1) ws.send(JSON.stringify({ type: 'terminal_output', data: chunk.toString('base64'), encoding: 'base64' }));
|
|
4132
|
+
});
|
|
4133
|
+
proc.on('exit', (code) => {
|
|
4134
|
+
if (ws.readyState === 1) ws.send(JSON.stringify({ type: 'terminal_exit', code }));
|
|
4135
|
+
ws.terminalProc = null;
|
|
4136
|
+
});
|
|
4137
|
+
proc.on('error', (err) => {
|
|
4138
|
+
console.error('[TERMINAL] Spawn error (contained):', err.message);
|
|
4139
|
+
if (ws.readyState === 1) ws.send(JSON.stringify({ type: 'terminal_exit', code: 1, error: err.message }));
|
|
4140
|
+
ws.terminalProc = null;
|
|
4141
|
+
});
|
|
4142
|
+
proc.stdin.on('error', () => {});
|
|
4143
|
+
proc.stdout.on('error', () => {});
|
|
4144
|
+
proc.stderr.on('error', () => {});
|
|
4145
|
+
ws.send(JSON.stringify({ type: 'terminal_started', timestamp: Date.now() }));
|
|
4146
|
+
}
|
|
4117
4147
|
} else if (data.type === 'terminal_input') {
|
|
4118
|
-
if (ws.terminalProc
|
|
4119
|
-
try {
|
|
4148
|
+
if (ws.terminalProc) {
|
|
4149
|
+
try {
|
|
4150
|
+
const input = Buffer.from(data.data, 'base64');
|
|
4151
|
+
if (ws.terminalPty) {
|
|
4152
|
+
ws.terminalProc.write(input);
|
|
4153
|
+
} else if (ws.terminalProc.stdin && ws.terminalProc.stdin.writable) {
|
|
4154
|
+
ws.terminalProc.stdin.write(input);
|
|
4155
|
+
}
|
|
4156
|
+
} catch (e) {}
|
|
4157
|
+
}
|
|
4158
|
+
} else if (data.type === 'terminal_resize') {
|
|
4159
|
+
if (ws.terminalProc && ws.terminalPty) {
|
|
4160
|
+
try {
|
|
4161
|
+
const { cols, rows } = data;
|
|
4162
|
+
if (cols && rows && typeof ws.terminalProc.resize === 'function') {
|
|
4163
|
+
ws.terminalProc.resize(cols, rows);
|
|
4164
|
+
}
|
|
4165
|
+
} catch (e) {}
|
|
4120
4166
|
}
|
|
4121
4167
|
} else if (data.type === 'terminal_stop') {
|
|
4122
4168
|
if (ws.terminalProc) {
|
package/static/js/terminal.js
CHANGED
|
@@ -42,9 +42,29 @@
|
|
|
42
42
|
}
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
+
term.onResize(function(size) {
|
|
46
|
+
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
47
|
+
ws.send(JSON.stringify({ type: 'terminal_resize', cols: size.cols, rows: size.rows }));
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
var resizeTimer;
|
|
45
52
|
window.addEventListener('resize', function() {
|
|
46
|
-
if (fitAddon)
|
|
53
|
+
if (fitAddon) {
|
|
54
|
+
try { fitAddon.fit(); } catch(_) {}
|
|
55
|
+
clearTimeout(resizeTimer);
|
|
56
|
+
resizeTimer = setTimeout(function() {
|
|
57
|
+
if (term && ws && ws.readyState === WebSocket.OPEN) {
|
|
58
|
+
ws.send(JSON.stringify({ type: 'terminal_resize', cols: term.cols, rows: term.rows }));
|
|
59
|
+
}
|
|
60
|
+
}, 200);
|
|
61
|
+
}
|
|
47
62
|
});
|
|
63
|
+
|
|
64
|
+
output.addEventListener('click', function() {
|
|
65
|
+
if (term && term.focus) term.focus();
|
|
66
|
+
});
|
|
67
|
+
|
|
48
68
|
return true;
|
|
49
69
|
}
|
|
50
70
|
|
|
@@ -52,18 +72,22 @@
|
|
|
52
72
|
console.log('Terminal: Connecting to WebSocket');
|
|
53
73
|
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
54
74
|
console.log('Terminal: Sending terminal_start command');
|
|
55
|
-
|
|
75
|
+
var dims = term ? { cols: term.cols, rows: term.rows } : { cols: 80, rows: 24 };
|
|
76
|
+
ws.send(JSON.stringify({ type: 'terminal_start', cwd: window.__STARTUP_CWD || undefined, cols: dims.cols, rows: dims.rows }));
|
|
77
|
+
setTimeout(function() { if (term && term.focus) term.focus(); }, 100);
|
|
56
78
|
return;
|
|
57
79
|
}
|
|
58
80
|
if (ws && ws.readyState === WebSocket.CONNECTING) {
|
|
59
81
|
console.log('Terminal: WebSocket already connecting');
|
|
60
82
|
return;
|
|
61
83
|
}
|
|
62
|
-
|
|
84
|
+
|
|
63
85
|
ws = new WebSocket(getWsUrl());
|
|
64
86
|
ws.onopen = function() {
|
|
65
87
|
console.log('Terminal: WebSocket connected, starting terminal');
|
|
66
|
-
|
|
88
|
+
var dims = term ? { cols: term.cols, rows: term.rows } : { cols: 80, rows: 24 };
|
|
89
|
+
ws.send(JSON.stringify({ type: 'terminal_start', cwd: window.__STARTUP_CWD || undefined, cols: dims.cols, rows: dims.rows }));
|
|
90
|
+
setTimeout(function() { if (term && term.focus) term.focus(); }, 100);
|
|
67
91
|
};
|
|
68
92
|
ws.onmessage = function(e) {
|
|
69
93
|
try {
|