@co0ontty/wand 4.36.0 → 4.37.0
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/build-info.json +3 -3
- package/dist/npm-update-utils.js +1 -1
- package/dist/process-manager.d.ts +10 -2
- package/dist/process-manager.js +144 -47
- package/dist/pty-shell-launch.d.ts +36 -0
- package/dist/pty-shell-launch.js +116 -0
- package/dist/pty-terminal-state.d.ts +39 -0
- package/dist/pty-terminal-state.js +93 -0
- package/dist/server.js +14 -3
- package/dist/session-transport.js +2 -0
- package/dist/types.d.ts +4 -0
- package/dist/web-ui/content/scripts.js +85 -64
- package/dist/web-ui/content/styles.css +1 -1
- package/dist/web-ui/content/vendor/xterm/xterm.bundle.js +80 -0
- package/dist/web-ui/content/vendor/xterm/xterm.css +285 -0
- package/dist/web-ui/embedded-assets.d.ts +5 -5
- package/dist/web-ui/embedded-assets.js +9 -9
- package/dist/web-ui/index.js +4 -4
- package/dist/web-ui/provider-identity.d.ts +2 -1
- package/dist/web-ui/provider-identity.js +5 -2
- package/dist/ws-broadcast.d.ts +15 -1
- package/dist/ws-broadcast.js +109 -13
- package/package.json +9 -5
- package/dist/web-ui/content/vendor/wterm/terminal.css +0 -162
- package/dist/web-ui/content/vendor/wterm/wterm.bundle.js +0 -1
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import headless from "@xterm/headless";
|
|
2
|
+
import { SerializeAddon } from "@xterm/addon-serialize";
|
|
3
|
+
import { Unicode11Addon } from "@xterm/addon-unicode11";
|
|
4
|
+
const { Terminal } = headless;
|
|
5
|
+
/**
|
|
6
|
+
* Server-side xterm screen model used only for reconnect snapshots. Live PTY
|
|
7
|
+
* bytes still travel unchanged from node-pty to the browser terminal.
|
|
8
|
+
*/
|
|
9
|
+
export class PtyTerminalState {
|
|
10
|
+
terminal;
|
|
11
|
+
serializer = new SerializeAddon();
|
|
12
|
+
unicode = new Unicode11Addon();
|
|
13
|
+
pending = [];
|
|
14
|
+
tail = Promise.resolve();
|
|
15
|
+
checkpointTimer;
|
|
16
|
+
nextId = 1;
|
|
17
|
+
committedData = "";
|
|
18
|
+
committedCols;
|
|
19
|
+
committedRows;
|
|
20
|
+
disposed = false;
|
|
21
|
+
constructor(cols, rows, initialData = "") {
|
|
22
|
+
this.committedCols = cols;
|
|
23
|
+
this.committedRows = rows;
|
|
24
|
+
this.terminal = new Terminal({ cols, rows, allowProposedApi: true, scrollback: 5000 });
|
|
25
|
+
this.terminal.loadAddon(this.serializer);
|
|
26
|
+
this.terminal.loadAddon(this.unicode);
|
|
27
|
+
this.terminal.unicode.activeVersion = "11";
|
|
28
|
+
if (initialData)
|
|
29
|
+
this.write(initialData);
|
|
30
|
+
}
|
|
31
|
+
write(data) {
|
|
32
|
+
if (this.disposed || !data)
|
|
33
|
+
return;
|
|
34
|
+
const pending = this.addPending({ type: "data", data });
|
|
35
|
+
this.tail = this.tail.then(() => new Promise((resolve) => {
|
|
36
|
+
if (this.disposed)
|
|
37
|
+
return resolve();
|
|
38
|
+
this.terminal.write(data, () => resolve());
|
|
39
|
+
}));
|
|
40
|
+
this.scheduleCheckpoint(pending.id);
|
|
41
|
+
}
|
|
42
|
+
resize(cols, rows) {
|
|
43
|
+
if (this.disposed)
|
|
44
|
+
return;
|
|
45
|
+
const pending = this.addPending({ type: "resize", cols, rows });
|
|
46
|
+
this.tail = this.tail.then(() => {
|
|
47
|
+
if (!this.disposed)
|
|
48
|
+
this.terminal.resize(cols, rows);
|
|
49
|
+
});
|
|
50
|
+
this.scheduleCheckpoint(pending.id);
|
|
51
|
+
}
|
|
52
|
+
snapshot() {
|
|
53
|
+
return {
|
|
54
|
+
version: 1,
|
|
55
|
+
data: this.committedData,
|
|
56
|
+
cols: this.committedCols,
|
|
57
|
+
rows: this.committedRows,
|
|
58
|
+
pending: this.pending.map(({ operation }) => ({ ...operation })),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
dispose() {
|
|
62
|
+
if (this.disposed)
|
|
63
|
+
return;
|
|
64
|
+
this.disposed = true;
|
|
65
|
+
if (this.checkpointTimer)
|
|
66
|
+
clearTimeout(this.checkpointTimer);
|
|
67
|
+
this.checkpointTimer = undefined;
|
|
68
|
+
this.pending = [];
|
|
69
|
+
this.terminal.dispose();
|
|
70
|
+
}
|
|
71
|
+
addPending(operation) {
|
|
72
|
+
const pending = { id: this.nextId++, operation };
|
|
73
|
+
this.pending.push(pending);
|
|
74
|
+
return pending;
|
|
75
|
+
}
|
|
76
|
+
scheduleCheckpoint(_operationId) {
|
|
77
|
+
if (this.checkpointTimer || this.disposed)
|
|
78
|
+
return;
|
|
79
|
+
this.checkpointTimer = setTimeout(() => {
|
|
80
|
+
this.checkpointTimer = undefined;
|
|
81
|
+
const cutoff = this.pending.at(-1)?.id ?? 0;
|
|
82
|
+
this.tail = this.tail.then(() => {
|
|
83
|
+
if (this.disposed)
|
|
84
|
+
return;
|
|
85
|
+
this.committedData = this.serializer.serialize({ scrollback: 5000 });
|
|
86
|
+
this.committedCols = this.terminal.cols;
|
|
87
|
+
this.committedRows = this.terminal.rows;
|
|
88
|
+
this.pending = this.pending.filter((entry) => entry.id > cutoff);
|
|
89
|
+
});
|
|
90
|
+
}, 100);
|
|
91
|
+
this.checkpointTimer.unref?.();
|
|
92
|
+
}
|
|
93
|
+
}
|
package/dist/server.js
CHANGED
|
@@ -551,8 +551,8 @@ export async function startServer(config, configPath, options = {}) {
|
|
|
551
551
|
res.setHeader("Cache-Control", "public, max-age=604800, immutable");
|
|
552
552
|
res.type(asset.contentType).send(asset.content);
|
|
553
553
|
};
|
|
554
|
-
app.get("/vendor/
|
|
555
|
-
app.get("/vendor/
|
|
554
|
+
app.get("/vendor/xterm/xterm.bundle.js", (req, res) => sendEmbeddedVendorAsset("/vendor/xterm/xterm.bundle.js", req, res));
|
|
555
|
+
app.get("/vendor/xterm/xterm.css", (req, res) => sendEmbeddedVendorAsset("/vendor/xterm/xterm.css", req, res));
|
|
556
556
|
app.get("/vendor/qrcode/qrcode.bundle.js", (req, res) => sendEmbeddedVendorAsset("/vendor/qrcode/qrcode.bundle.js", req, res));
|
|
557
557
|
// ── Web UI endpoints ──
|
|
558
558
|
app.get("/", (_req, res) => {
|
|
@@ -1088,7 +1088,18 @@ export async function startServer(config, configPath, options = {}) {
|
|
|
1088
1088
|
},
|
|
1089
1089
|
});
|
|
1090
1090
|
const wsManager = new WsBroadcastManager(wss, () => config.cardDefaults ?? {}, useHttps, authService);
|
|
1091
|
-
wsManager.setup(
|
|
1091
|
+
wsManager.setup({
|
|
1092
|
+
getSession: (id) => sessionRegistry.get(id),
|
|
1093
|
+
getTerminalState: (id) => processes.getTerminalState(id),
|
|
1094
|
+
sendPtyInput: (id, input, shortcutKey, userInput) => {
|
|
1095
|
+
processes.sendInput(id, input, "terminal", shortcutKey, userInput);
|
|
1096
|
+
},
|
|
1097
|
+
resizePty: (id, cols, rows) => {
|
|
1098
|
+
processes.resize(id, cols, rows);
|
|
1099
|
+
},
|
|
1100
|
+
pausePtyOutput: (id) => processes.pauseOutput(id),
|
|
1101
|
+
resumePtyOutput: (id) => processes.resumeOutput(id),
|
|
1102
|
+
});
|
|
1092
1103
|
disconnectAuthenticatedSockets = () => wsManager.disconnectAll();
|
|
1093
1104
|
wss.on("error", (err) => {
|
|
1094
1105
|
if (err.code === "EADDRINUSE")
|
|
@@ -22,6 +22,8 @@ function sessionBase(snapshot) {
|
|
|
22
22
|
automationId: snapshot.automationId,
|
|
23
23
|
sessionKind: snapshot.sessionKind,
|
|
24
24
|
provider: snapshot.provider,
|
|
25
|
+
providerCliActive: snapshot.providerCliActive,
|
|
26
|
+
providerCliExitCode: snapshot.providerCliExitCode,
|
|
25
27
|
runner: snapshot.runner,
|
|
26
28
|
command: snapshot.command,
|
|
27
29
|
cwd: snapshot.cwd,
|
package/dist/types.d.ts
CHANGED
|
@@ -492,6 +492,10 @@ export interface SessionSnapshot {
|
|
|
492
492
|
automationId?: string;
|
|
493
493
|
sessionKind?: SessionKind;
|
|
494
494
|
provider?: SessionProvider;
|
|
495
|
+
/** True while the provider CLI owns the PTY; false after it returns to the persistent shell. */
|
|
496
|
+
providerCliActive?: boolean;
|
|
497
|
+
/** Provider CLI exit status; separate from exitCode, which belongs to the persistent PTY shell. */
|
|
498
|
+
providerCliExitCode?: number | null;
|
|
495
499
|
runner?: SessionRunner;
|
|
496
500
|
command: string;
|
|
497
501
|
cwd: string;
|