fix(run): forward text-frame keystrokes to pty and fix ws-pty upgrade dispatch
xterm.js's onData hands the browser a plain string, and WebSocket.send(string)
always emits a TEXT frame — pty-attach.js only forwarded BINARY frames to
pty.write(), so every keystroke was silently dropped as an unparseable JSON
control message. Now any non-control text frame reaches the pty.
Deeper root cause of the terminal never accepting input at all: the /ws
WebSocketServer used the {server, path} shorthand, whose own internal
upgrade listener calls handleUpgrade() for every upgrade on the shared
http.Server and aborts with 400 on a path mismatch — killing /ws-pty/*
upgrades before the PTY server's own listener ever ran. Switched /ws to
noServer + a manual path-checked dispatch, matching /ws-pty's pattern.
This commit is contained in:
@@ -71,19 +71,31 @@ function attach(ws, runId, { cols, rows }) {
|
||||
// callback arg (newer) or via `data.binary` on some transports — this
|
||||
// helper's own tests exercise the `{binary}` option shape used above.
|
||||
const binary = typeof isBinary === "boolean" ? isBinary : !!(isBinary && isBinary.binary);
|
||||
const text = data.toString("utf8");
|
||||
if (binary) {
|
||||
pty.write(data.toString("utf8"));
|
||||
pty.write(text);
|
||||
return;
|
||||
}
|
||||
let msg;
|
||||
try {
|
||||
msg = JSON.parse(data.toString("utf8"));
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
if (msg && msg.type === "resize" && Number.isFinite(msg.cols) && Number.isFinite(msg.rows)) {
|
||||
pty.resize(msg.cols, msg.rows);
|
||||
// The browser's WebSocket API sends a JS string as a text frame, and
|
||||
// xterm.js's onData callback hands over plain strings — so every
|
||||
// keystroke arrives here as text, not binary. Only a JSON control frame
|
||||
// (matched by this same prefix check the client uses for output) is
|
||||
// NOT keystroke input; everything else must reach the pty or typing
|
||||
// does nothing.
|
||||
if (text.startsWith('{"type"')) {
|
||||
let msg;
|
||||
try {
|
||||
msg = JSON.parse(text);
|
||||
} catch {
|
||||
pty.write(text);
|
||||
return;
|
||||
}
|
||||
if (msg && msg.type === "resize" && Number.isFinite(msg.cols) && Number.isFinite(msg.rows)) {
|
||||
pty.resize(msg.cols, msg.rows);
|
||||
return;
|
||||
}
|
||||
}
|
||||
pty.write(text);
|
||||
});
|
||||
|
||||
ws.on("close", () => {
|
||||
|
||||
Reference in New Issue
Block a user