gekto 0.0.1
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/dist/agents/ClaudeAgent.js +72 -0
- package/dist/agents/HeadlessAgent.js +141 -0
- package/dist/agents/agentPool.js +211 -0
- package/dist/agents/agentWebSocket.js +264 -0
- package/dist/agents/gektoOrchestrator.js +195 -0
- package/dist/agents/gektoPersistent.js +239 -0
- package/dist/agents/gektoSimple.js +137 -0
- package/dist/agents/gektoTools.js +223 -0
- package/dist/proxy.js +318 -0
- package/dist/store.js +53 -0
- package/dist/terminal.js +106 -0
- package/dist/widget/gekto-widget.iife.js +4077 -0
- package/dist/widget/logo.svg +32 -0
- package/dist/widget/vite.svg +1 -0
- package/package.json +37 -0
package/dist/terminal.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { WebSocket, WebSocketServer } from 'ws';
|
|
2
|
+
import * as pty from 'node-pty';
|
|
3
|
+
const sessions = new Map();
|
|
4
|
+
export function setupTerminalWebSocket(server, path = '/__gekto/terminal') {
|
|
5
|
+
const wss = new WebSocketServer({ noServer: true });
|
|
6
|
+
// Handle WebSocket upgrade for terminal path
|
|
7
|
+
server.on('upgrade', (request, socket, head) => {
|
|
8
|
+
const url = request.url || '';
|
|
9
|
+
if (url === path || url.startsWith(path + '?')) {
|
|
10
|
+
wss.handleUpgrade(request, socket, head, (ws) => {
|
|
11
|
+
wss.emit('connection', ws, request);
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
// Other upgrade requests (like Vite HMR) are handled elsewhere
|
|
15
|
+
});
|
|
16
|
+
wss.on('connection', (ws) => {
|
|
17
|
+
// Create session but don't spawn PTY yet - wait for resize
|
|
18
|
+
const session = {
|
|
19
|
+
pty: null,
|
|
20
|
+
ws,
|
|
21
|
+
cols: 80,
|
|
22
|
+
rows: 24,
|
|
23
|
+
};
|
|
24
|
+
sessions.set(ws, session);
|
|
25
|
+
const spawnShell = () => {
|
|
26
|
+
if (session.pty)
|
|
27
|
+
return; // Already spawned
|
|
28
|
+
try {
|
|
29
|
+
const shell = process.env.SHELL || '/bin/bash';
|
|
30
|
+
const isZsh = shell.endsWith('zsh');
|
|
31
|
+
// For zsh: pass -c to run unsetopt first, then exec interactive shell
|
|
32
|
+
const args = isZsh ? ['-c', 'unsetopt PROMPT_SP PROMPT_CR; exec zsh -i'] : [];
|
|
33
|
+
const ptyProcess = pty.spawn(shell, args, {
|
|
34
|
+
name: 'xterm-256color',
|
|
35
|
+
cols: session.cols,
|
|
36
|
+
rows: session.rows,
|
|
37
|
+
cwd: process.cwd(),
|
|
38
|
+
env: {
|
|
39
|
+
...process.env,
|
|
40
|
+
TERM: 'xterm',
|
|
41
|
+
COLUMNS: String(session.cols),
|
|
42
|
+
LINES: String(session.rows),
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
session.pty = ptyProcess;
|
|
46
|
+
// PTY output → WebSocket
|
|
47
|
+
ptyProcess.onData((data) => {
|
|
48
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
49
|
+
ws.send(JSON.stringify({ type: 'output', data }));
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
ptyProcess.onExit(({ exitCode }) => {
|
|
53
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
54
|
+
ws.send(JSON.stringify({ type: 'exit', code: exitCode }));
|
|
55
|
+
ws.close();
|
|
56
|
+
}
|
|
57
|
+
sessions.delete(ws);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
ws.send(JSON.stringify({
|
|
62
|
+
type: 'error',
|
|
63
|
+
message: `Failed to start terminal: ${err}`
|
|
64
|
+
}));
|
|
65
|
+
ws.close();
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
// WebSocket → PTY
|
|
69
|
+
ws.on('message', (message) => {
|
|
70
|
+
try {
|
|
71
|
+
const msg = JSON.parse(message.toString());
|
|
72
|
+
switch (msg.type) {
|
|
73
|
+
case 'input':
|
|
74
|
+
session.pty?.write(msg.data);
|
|
75
|
+
break;
|
|
76
|
+
case 'resize':
|
|
77
|
+
if (msg.cols && msg.rows) {
|
|
78
|
+
session.cols = msg.cols;
|
|
79
|
+
session.rows = msg.rows;
|
|
80
|
+
if (session.pty) {
|
|
81
|
+
session.pty.resize(msg.cols, msg.rows);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
// First resize - spawn the shell now
|
|
85
|
+
spawnShell();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
// If not JSON, treat as raw input
|
|
93
|
+
session.pty?.write(message.toString());
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
ws.on('close', () => {
|
|
97
|
+
session.pty?.kill();
|
|
98
|
+
sessions.delete(ws);
|
|
99
|
+
});
|
|
100
|
+
ws.on('error', () => {
|
|
101
|
+
session.pty?.kill();
|
|
102
|
+
sessions.delete(ws);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
return wss;
|
|
106
|
+
}
|