@juspay/shooter 1.22.0 → 1.24.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/build/client/_app/immutable/chunks/CbINytmr.js +3 -0
- package/build/client/_app/immutable/chunks/CbINytmr.js.br +0 -0
- package/build/client/_app/immutable/chunks/CbINytmr.js.gz +0 -0
- package/build/client/_app/immutable/chunks/D868VwmX.js +6 -0
- package/build/client/_app/immutable/chunks/D868VwmX.js.br +0 -0
- package/build/client/_app/immutable/chunks/D868VwmX.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{CZg4kn4E.js → Dd1KNHg-.js} +1 -1
- package/build/client/_app/immutable/chunks/Dd1KNHg-.js.br +0 -0
- package/build/client/_app/immutable/chunks/Dd1KNHg-.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{DhK7PwI_.js → V8pbM9cl.js} +1 -1
- package/build/client/_app/immutable/chunks/V8pbM9cl.js.br +0 -0
- package/build/client/_app/immutable/chunks/V8pbM9cl.js.gz +0 -0
- package/build/client/_app/immutable/entry/{app.CTqz33nP.js → app.CiQHPW0j.js} +2 -2
- package/build/client/_app/immutable/entry/app.CiQHPW0j.js.br +0 -0
- package/build/client/_app/immutable/entry/app.CiQHPW0j.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.DUCXuMLl.js +1 -0
- package/build/client/_app/immutable/entry/start.DUCXuMLl.js.br +2 -0
- package/build/client/_app/immutable/entry/start.DUCXuMLl.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{0.Qn7Ktiht.js → 0.BRFdS_ay.js} +1 -1
- package/build/client/_app/immutable/nodes/0.BRFdS_ay.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.BRFdS_ay.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{1.BxWOfNlo.js → 1.B1pgwYu3.js} +1 -1
- package/build/client/_app/immutable/nodes/1.B1pgwYu3.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.B1pgwYu3.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{10.BGPYD1s1.js → 10.558mUFIl.js} +1 -1
- package/build/client/_app/immutable/nodes/10.558mUFIl.js.br +0 -0
- package/build/client/_app/immutable/nodes/10.558mUFIl.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{11.BxY1PUjC.js → 11.CdmPyt4k.js} +2 -2
- package/build/client/_app/immutable/nodes/11.CdmPyt4k.js.br +0 -0
- package/build/client/_app/immutable/nodes/{11.BxY1PUjC.js.gz → 11.CdmPyt4k.js.gz} +0 -0
- package/build/client/_app/immutable/nodes/{2.Bc2qALkX.js → 2.1tiK5o4L.js} +1 -1
- package/build/client/_app/immutable/nodes/2.1tiK5o4L.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.1tiK5o4L.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{3.N2-A8noI.js → 3.DyQTorXE.js} +1 -1
- package/build/client/_app/immutable/nodes/3.DyQTorXE.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.DyQTorXE.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{6.BWF9Qx6F.js → 6.Chn2ZM2V.js} +1 -1
- package/build/client/_app/immutable/nodes/6.Chn2ZM2V.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.Chn2ZM2V.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{7.DHuDIdpz.js → 7.DhJ2K3GQ.js} +1 -1
- package/build/client/_app/immutable/nodes/7.DhJ2K3GQ.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.DhJ2K3GQ.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{8.D0Ijt9Vv.js → 8.B4pLxBkI.js} +1 -1
- package/build/client/_app/immutable/nodes/8.B4pLxBkI.js.br +0 -0
- package/build/client/_app/immutable/nodes/8.B4pLxBkI.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{9.2Piwo35J.js → 9.CVsskPw5.js} +1 -1
- package/build/client/_app/immutable/nodes/9.CVsskPw5.js.br +0 -0
- package/build/client/_app/immutable/nodes/9.CVsskPw5.js.gz +0 -0
- package/build/client/_app/version.json +1 -1
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/server/chunks/{0-CVGsyVKN.js → 0-DZO0pCuJ.js} +2 -2
- package/build/server/chunks/{0-CVGsyVKN.js.map → 0-DZO0pCuJ.js.map} +1 -1
- package/build/server/chunks/{1-BAlAsKdp.js → 1-D2SDQFeq.js} +2 -2
- package/build/server/chunks/{1-BAlAsKdp.js.map → 1-D2SDQFeq.js.map} +1 -1
- package/build/server/chunks/{10-BUCX7Aqz.js → 10-CEJDEhpQ.js} +2 -2
- package/build/server/chunks/{10-BUCX7Aqz.js.map → 10-CEJDEhpQ.js.map} +1 -1
- package/build/server/chunks/{11-DHPvc2yA.js → 11-CMC_i3co.js} +2 -2
- package/build/server/chunks/{11-DHPvc2yA.js.map → 11-CMC_i3co.js.map} +1 -1
- package/build/server/chunks/{2-DLOMdCHW.js → 2-C1XSBNj7.js} +2 -2
- package/build/server/chunks/{2-DLOMdCHW.js.map → 2-C1XSBNj7.js.map} +1 -1
- package/build/server/chunks/{3-DCf69LYo.js → 3-DRjTDzaV.js} +2 -2
- package/build/server/chunks/{3-DCf69LYo.js.map → 3-DRjTDzaV.js.map} +1 -1
- package/build/server/chunks/{6-DUrC2Naz.js → 6-BcgshtK4.js} +2 -2
- package/build/server/chunks/{6-DUrC2Naz.js.map → 6-BcgshtK4.js.map} +1 -1
- package/build/server/chunks/{7-TXwjMHt2.js → 7-BBsuxiGz.js} +2 -2
- package/build/server/chunks/{7-TXwjMHt2.js.map → 7-BBsuxiGz.js.map} +1 -1
- package/build/server/chunks/{8-D2X_jBsT.js → 8-B0qM-Zzs.js} +2 -2
- package/build/server/chunks/{8-D2X_jBsT.js.map → 8-B0qM-Zzs.js.map} +1 -1
- package/build/server/chunks/{9-DK0hH5Xa.js → 9-XIfsp2D_.js} +2 -2
- package/build/server/chunks/{9-DK0hH5Xa.js.map → 9-XIfsp2D_.js.map} +1 -1
- package/build/server/chunks/{_server.ts-DiBMY7Ho.js → _server.ts-B-Gekwsu.js} +3 -2
- package/build/server/chunks/_server.ts-B-Gekwsu.js.map +1 -0
- package/build/server/chunks/{_server.ts-C0PO_cAu.js → _server.ts-BhP3b8A5.js} +3 -2
- package/build/server/chunks/{_server.ts-C0PO_cAu.js.map → _server.ts-BhP3b8A5.js.map} +1 -1
- package/build/server/chunks/{_server.ts-Bol54_Qo.js → _server.ts-CTdFxJdD.js} +3 -2
- package/build/server/chunks/_server.ts-CTdFxJdD.js.map +1 -0
- package/build/server/chunks/{_server.ts-B54Pvhgc.js → _server.ts-Cx0S__hk.js} +3 -2
- package/build/server/chunks/_server.ts-Cx0S__hk.js.map +1 -0
- package/build/server/chunks/{_server.ts-CZb-BI5H.js → _server.ts-DtT-ZXki.js} +3 -2
- package/build/server/chunks/_server.ts-DtT-ZXki.js.map +1 -0
- package/build/server/chunks/{pty-manager-CoWVT56F.js → pty-manager-BsHXoNks.js} +287 -27
- package/build/server/chunks/pty-manager-BsHXoNks.js.map +1 -0
- package/build/server/index.js +1 -1
- package/build/server/index.js.map +1 -1
- package/build/server/manifest.js +16 -16
- package/build/server/manifest.js.map +1 -1
- package/package.json +4 -2
- package/server.ts +5 -2
- package/src/lib/modules/client/terminal/xterm-wrapper.ts +56 -15
- package/src/lib/modules/server/terminal/pty-manager.ts +291 -35
- package/src/lib/modules/server/terminal/terminal-emulator.ts +102 -0
- package/src/lib/modules/server/terminal/terminal-store.ts +10 -0
- package/src/lib/modules/server/ws/server.ts +18 -2
- package/src/lib/modules/server/ws/terminal-handler.ts +60 -14
- package/src/lib/types/generated/WsProtocol.ts +10 -1
- package/src/lib/types/server.ts +34 -1
- package/src/lib/types/terminal-client.ts +3 -0
- package/src/lib/types/ws.ts +7 -2
- package/src/routes/api/terminals/[id]/resize/+server.ts +3 -0
- package/build/client/_app/immutable/chunks/BfbPKMXz.js +0 -3
- package/build/client/_app/immutable/chunks/BfbPKMXz.js.br +0 -0
- package/build/client/_app/immutable/chunks/BfbPKMXz.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CZg4kn4E.js.br +0 -0
- package/build/client/_app/immutable/chunks/CZg4kn4E.js.gz +0 -0
- package/build/client/_app/immutable/chunks/DhK7PwI_.js.br +0 -0
- package/build/client/_app/immutable/chunks/DhK7PwI_.js.gz +0 -0
- package/build/client/_app/immutable/chunks/J5-Cr5oR.js +0 -6
- package/build/client/_app/immutable/chunks/J5-Cr5oR.js.br +0 -0
- package/build/client/_app/immutable/chunks/J5-Cr5oR.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.CTqz33nP.js.br +0 -0
- package/build/client/_app/immutable/entry/app.CTqz33nP.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.Dj-Kvgwo.js +0 -1
- package/build/client/_app/immutable/entry/start.Dj-Kvgwo.js.br +0 -2
- package/build/client/_app/immutable/entry/start.Dj-Kvgwo.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.Qn7Ktiht.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.Qn7Ktiht.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.BxWOfNlo.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.BxWOfNlo.js.gz +0 -0
- package/build/client/_app/immutable/nodes/10.BGPYD1s1.js.br +0 -0
- package/build/client/_app/immutable/nodes/10.BGPYD1s1.js.gz +0 -0
- package/build/client/_app/immutable/nodes/11.BxY1PUjC.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.Bc2qALkX.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.Bc2qALkX.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.N2-A8noI.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.N2-A8noI.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.BWF9Qx6F.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.BWF9Qx6F.js.gz +0 -0
- package/build/client/_app/immutable/nodes/7.DHuDIdpz.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.DHuDIdpz.js.gz +0 -0
- package/build/client/_app/immutable/nodes/8.D0Ijt9Vv.js.br +0 -0
- package/build/client/_app/immutable/nodes/8.D0Ijt9Vv.js.gz +0 -0
- package/build/client/_app/immutable/nodes/9.2Piwo35J.js.br +0 -0
- package/build/client/_app/immutable/nodes/9.2Piwo35J.js.gz +0 -0
- package/build/server/chunks/_server.ts-B54Pvhgc.js.map +0 -1
- package/build/server/chunks/_server.ts-Bol54_Qo.js.map +0 -1
- package/build/server/chunks/_server.ts-CZb-BI5H.js.map +0 -1
- package/build/server/chunks/_server.ts-DiBMY7Ho.js.map +0 -1
- package/build/server/chunks/pty-manager-CoWVT56F.js.map +0 -1
|
@@ -56,8 +56,24 @@ export function setupWebSocketHandlers(
|
|
|
56
56
|
): void {
|
|
57
57
|
const host = request.headers.host ?? 'localhost';
|
|
58
58
|
let pathname: string;
|
|
59
|
+
let snapshotCapable = false;
|
|
60
|
+
let lastSeq = 0;
|
|
59
61
|
try {
|
|
60
|
-
|
|
62
|
+
const url = new URL(request.url || '/', `http://${host}`);
|
|
63
|
+
pathname = url.pathname;
|
|
64
|
+
// Capability negotiation: clients that understand the {snapshot} frame
|
|
65
|
+
// advertise ?caps=snapshot. Others fall back to raw scrollback replay.
|
|
66
|
+
snapshotCapable = url.searchParams.get('caps') === 'snapshot';
|
|
67
|
+
// Reconnect resume (Phase 2): a returning client passes the highest output
|
|
68
|
+
// seq it already applied so the server can replay just the gap (or snapshot
|
|
69
|
+
// if the gap aged out of the ring). Absent / non-numeric ⇒ fresh join.
|
|
70
|
+
const rawLastSeq = url.searchParams.get('lastSeq');
|
|
71
|
+
if (rawLastSeq !== null) {
|
|
72
|
+
const parsed = Number(rawLastSeq);
|
|
73
|
+
if (Number.isFinite(parsed) && parsed > 0) {
|
|
74
|
+
lastSeq = Math.floor(parsed);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
61
77
|
} catch {
|
|
62
78
|
socket.destroy();
|
|
63
79
|
return;
|
|
@@ -103,7 +119,7 @@ export function setupWebSocketHandlers(
|
|
|
103
119
|
|
|
104
120
|
if (terminalMatch) {
|
|
105
121
|
const terminalId = terminalMatch[1];
|
|
106
|
-
handleTerminalConnection(ws, terminalId, scope);
|
|
122
|
+
handleTerminalConnection(ws, terminalId, scope, snapshotCapable, lastSeq);
|
|
107
123
|
} else if (superSessionMatch) {
|
|
108
124
|
const superSessionId = superSessionMatch[1];
|
|
109
125
|
handleSuperSessionConnection(ws, superSessionId);
|
|
@@ -11,6 +11,8 @@ import type {
|
|
|
11
11
|
} from '$lib/types';
|
|
12
12
|
import type { WebSocket } from 'ws';
|
|
13
13
|
|
|
14
|
+
import { randomBytes } from 'crypto';
|
|
15
|
+
|
|
14
16
|
// ── Constants ────────────────────────────────────────────────────────
|
|
15
17
|
|
|
16
18
|
/** Signal name → numeric code for process.kill(). */
|
|
@@ -32,7 +34,9 @@ let _ptyManager: null | PtyManagerLike = null;
|
|
|
32
34
|
export function handleTerminalConnection(
|
|
33
35
|
ws: WebSocket,
|
|
34
36
|
terminalId: string,
|
|
35
|
-
scope?: TicketScope
|
|
37
|
+
scope?: TicketScope,
|
|
38
|
+
snapshotCapable = false,
|
|
39
|
+
lastSeq = 0
|
|
36
40
|
): void {
|
|
37
41
|
// ── 1. Look up the terminal ──────────────────────────────────────
|
|
38
42
|
if (!_ptyManager) {
|
|
@@ -48,11 +52,18 @@ export function handleTerminalConnection(
|
|
|
48
52
|
return;
|
|
49
53
|
}
|
|
50
54
|
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
// Phase 3: stable per-connection id, used to claim/hold resize authority.
|
|
56
|
+
// Phase 4 will pass this in from setupWebSocketHandlers (the WS upgrade handler).
|
|
57
|
+
const connectionId = randomBytes(8).toString('hex');
|
|
58
|
+
|
|
59
|
+
// ── 2. Attach via pty-manager (registers client + sends initial state) ──
|
|
60
|
+
// Snapshot-capable clients (?caps=snapshot) get a serialized current-screen
|
|
61
|
+
// snapshot; others get the legacy raw scrollback replay. A reconnecting
|
|
62
|
+
// client also passes lastSeq (>0) so attach() can replay only the missing
|
|
63
|
+
// frames from the ring instead of re-snapshotting. attach() adds the ws to
|
|
64
|
+
// terminal.clients + outputBuffers; broadcastOutput() then delivers all live
|
|
65
|
+
// PTY output — no per-client onData listener needed.
|
|
66
|
+
_ptyManager.attach(terminalId, ws, { lastSeq, snapshot: snapshotCapable });
|
|
56
67
|
|
|
57
68
|
// If the terminal already exited, tell the client immediately.
|
|
58
69
|
if (terminal.status === 'exited') {
|
|
@@ -85,15 +96,21 @@ export function handleTerminalConnection(
|
|
|
85
96
|
break;
|
|
86
97
|
|
|
87
98
|
case 'resize': {
|
|
88
|
-
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
99
|
+
// Phase 3: driver-authoritative resize (fixes G4). Only the authority
|
|
100
|
+
// connection's resize reaches the PTY; non-authority senders keep their
|
|
101
|
+
// own xterm fitted locally — no PTY call and no broadcast from here.
|
|
102
|
+
if (!isResizeAuthority(connectionId, terminal.authorityConnectionId)) {
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
// Claim the slot on the first authoritative resize (sticky until this
|
|
106
|
+
// connection disconnects — see the close handler below).
|
|
107
|
+
if (terminal.authorityConnectionId === null) {
|
|
108
|
+
terminal.authorityConnectionId = connectionId;
|
|
96
109
|
}
|
|
110
|
+
// Route through the manager so dims persist (G5) and the new size
|
|
111
|
+
// broadcasts to ALL clients including this sender (a no-op echo),
|
|
112
|
+
// matching the REST /resize path.
|
|
113
|
+
_ptyManager?.resize(terminal.id, msg.cols, msg.rows);
|
|
97
114
|
break;
|
|
98
115
|
}
|
|
99
116
|
|
|
@@ -117,6 +134,11 @@ export function handleTerminalConnection(
|
|
|
117
134
|
|
|
118
135
|
// ── 4. Cleanup on disconnect ─────────────────────────────────────
|
|
119
136
|
ws.on('close', () => {
|
|
137
|
+
// Phase 3: release resize authority if this connection held it, so the next
|
|
138
|
+
// interactive client can claim it. Phase 4 replaces this with driver release.
|
|
139
|
+
if (terminal.authorityConnectionId === connectionId) {
|
|
140
|
+
terminal.authorityConnectionId = null;
|
|
141
|
+
}
|
|
120
142
|
_ptyManager?.detach(terminalId, ws);
|
|
121
143
|
});
|
|
122
144
|
|
|
@@ -126,6 +148,30 @@ export function handleTerminalConnection(
|
|
|
126
148
|
});
|
|
127
149
|
}
|
|
128
150
|
|
|
151
|
+
/**
|
|
152
|
+
* Phase 3: driver-authoritative resize predicate (D1). Returns true iff this
|
|
153
|
+
* connection may resize the PTY.
|
|
154
|
+
*
|
|
155
|
+
* P3 policy: the first interactive (non-readOnly) connection to send a resize
|
|
156
|
+
* claims authority; it stays the authority until that connection disconnects,
|
|
157
|
+
* at which point the slot clears and the next interactive resize claims it.
|
|
158
|
+
* This is "first-claimer, sticky-until-disconnect" — NOT last-writer-wins, which
|
|
159
|
+
* is exactly what causes the multi-client resize fight (G4).
|
|
160
|
+
*
|
|
161
|
+
* Pure decision (the caller performs the claim/clear), so it mirrors the unit
|
|
162
|
+
* test and lets Phase 4 swap the body to `connectionId === terminal.driver`
|
|
163
|
+
* without touching the call site.
|
|
164
|
+
*/
|
|
165
|
+
export function isResizeAuthority(
|
|
166
|
+
connectionId: string,
|
|
167
|
+
authorityConnectionId: null | string
|
|
168
|
+
): boolean {
|
|
169
|
+
if (authorityConnectionId === null) {
|
|
170
|
+
return true; // unclaimed — the first interactive resize wins
|
|
171
|
+
}
|
|
172
|
+
return connectionId === authorityConnectionId;
|
|
173
|
+
}
|
|
174
|
+
|
|
129
175
|
// ── Helpers ──────────────────────────────────────────────────────────
|
|
130
176
|
|
|
131
177
|
/**
|
|
@@ -238,20 +238,29 @@ export type TerminalOutputMessage = {
|
|
|
238
238
|
* @memberof TerminalOutputMessage
|
|
239
239
|
*/
|
|
240
240
|
data: string;
|
|
241
|
+
/**
|
|
242
|
+
* @description Monotonic per-terminal sequence number (starts at 1, increments by 1 for every broadcast output frame). Clients track lastSeq to enable gap detection and reconnect resume (Phase 2).
|
|
243
|
+
|
|
244
|
+
* @type { number }
|
|
245
|
+
* @memberof TerminalOutputMessage
|
|
246
|
+
*/
|
|
247
|
+
seq: number;
|
|
241
248
|
};
|
|
242
249
|
|
|
243
250
|
export function decodeTerminalOutputMessage(rawInput: unknown): TerminalOutputMessage | null {
|
|
244
251
|
if (isJSON(rawInput)) {
|
|
245
252
|
const decodedType = decodeString(rawInput['type']);
|
|
246
253
|
const decodedData = decodeString(rawInput['data']);
|
|
254
|
+
const decodedSeq = decodeNumber(rawInput['seq']);
|
|
247
255
|
|
|
248
|
-
if (decodedType === null || decodedData === null) {
|
|
256
|
+
if (decodedType === null || decodedData === null || decodedSeq === null) {
|
|
249
257
|
return null;
|
|
250
258
|
}
|
|
251
259
|
|
|
252
260
|
return {
|
|
253
261
|
type: decodedType,
|
|
254
262
|
data: decodedData,
|
|
263
|
+
seq: decodedSeq,
|
|
255
264
|
};
|
|
256
265
|
}
|
|
257
266
|
return null;
|
package/src/lib/types/server.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type WebSocket from 'ws';
|
|
|
10
10
|
|
|
11
11
|
import type { CodexStreamParser } from '../modules/server/sessions/codex-parser';
|
|
12
12
|
import type { HolderClient } from '../modules/server/terminal/holder-client';
|
|
13
|
+
import type { TerminalEmulator } from '../modules/server/terminal/terminal-emulator';
|
|
13
14
|
import type { ConversationMessage } from './sessions';
|
|
14
15
|
|
|
15
16
|
// ── holder-client types ─────────────────────────────────────────────
|
|
@@ -81,12 +82,21 @@ export interface OpenCodeWatchState {
|
|
|
81
82
|
|
|
82
83
|
export interface PtyManagedTerminal {
|
|
83
84
|
args: string[];
|
|
85
|
+
/**
|
|
86
|
+
* Phase 3: the connection currently allowed to resize the PTY (driver-
|
|
87
|
+
* authoritative resize, D1). null = unclaimed — the first interactive
|
|
88
|
+
* resize claims it, sticky until that connection disconnects. Phase 4
|
|
89
|
+
* replaces this slot with the driver token from the control registry.
|
|
90
|
+
*/
|
|
91
|
+
authorityConnectionId: null | string;
|
|
84
92
|
clients: Set<WebSocket>;
|
|
85
93
|
cols: number;
|
|
86
94
|
command: string;
|
|
87
95
|
createdAt: Date;
|
|
88
96
|
currentCwd: null | string;
|
|
89
97
|
cwd: string;
|
|
98
|
+
/** Server-side headless emulator for snapshot-on-join (null when disabled). */
|
|
99
|
+
emulator: null | TerminalEmulator;
|
|
90
100
|
exitCode: null | number;
|
|
91
101
|
exitedAt: Date | null;
|
|
92
102
|
holderPid: number;
|
|
@@ -100,6 +110,10 @@ export interface PtyManagedTerminal {
|
|
|
100
110
|
pty: HolderClient;
|
|
101
111
|
rows: number;
|
|
102
112
|
scrollback: string;
|
|
113
|
+
/** Monotonic counter; equals the last assigned seq for this terminal. */
|
|
114
|
+
seqCounter: number;
|
|
115
|
+
/** Bounded replay ring of recent output chunks (max SEQ_RING_MAX_ENTRIES). */
|
|
116
|
+
seqRing: SeqRingEntry[];
|
|
103
117
|
sessionFile: null | string;
|
|
104
118
|
socketPath: string;
|
|
105
119
|
status: 'exited' | 'running';
|
|
@@ -113,7 +127,14 @@ export interface PtyOutputBuffer {
|
|
|
113
127
|
size: number;
|
|
114
128
|
}
|
|
115
129
|
|
|
116
|
-
|
|
130
|
+
/**
|
|
131
|
+
* One entry in the per-terminal sequence ring (in-memory store type;
|
|
132
|
+
* structurally identical to the generated wire SeqRingEntry).
|
|
133
|
+
*/
|
|
134
|
+
export interface SeqRingEntry {
|
|
135
|
+
data: string;
|
|
136
|
+
seq: number;
|
|
137
|
+
}
|
|
117
138
|
|
|
118
139
|
export interface SessionWatchedFile {
|
|
119
140
|
callbacks: Set<OnNewEntries>;
|
|
@@ -121,3 +142,15 @@ export interface SessionWatchedFile {
|
|
|
121
142
|
offset: number;
|
|
122
143
|
watcher: FSWatcher;
|
|
123
144
|
}
|
|
145
|
+
|
|
146
|
+
// ── generic-session-watcher types ───────────────────────────────────
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* A serialized snapshot of a terminal's current screen (VT escape string)
|
|
150
|
+
* produced by the server-side headless emulator, plus its dimensions.
|
|
151
|
+
*/
|
|
152
|
+
export interface TerminalSnapshot {
|
|
153
|
+
cols: number;
|
|
154
|
+
data: string;
|
|
155
|
+
rows: number;
|
|
156
|
+
}
|
|
@@ -108,6 +108,8 @@ export interface ShortcutsHelpProps {
|
|
|
108
108
|
export interface TerminalInstance {
|
|
109
109
|
dispose: () => void;
|
|
110
110
|
fitAddon: FitAddon | null;
|
|
111
|
+
/** Highest output `seq` seen from the server (for Phase 2 reconnect resume). */
|
|
112
|
+
getLastSeq: () => number;
|
|
111
113
|
sendInput: (data: string) => void;
|
|
112
114
|
term: Terminal;
|
|
113
115
|
}
|
|
@@ -147,5 +149,6 @@ export interface WsTerminalInboundMessage {
|
|
|
147
149
|
data?: string;
|
|
148
150
|
path?: string;
|
|
149
151
|
rows?: number;
|
|
152
|
+
seq?: number;
|
|
150
153
|
type: string;
|
|
151
154
|
}
|
package/src/lib/types/ws.ts
CHANGED
|
@@ -60,6 +60,8 @@ export interface SessionWatcherLike {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
export interface TerminalManagedTerminal {
|
|
63
|
+
/** Phase 3: connection allowed to resize the PTY; null = unclaimed. */
|
|
64
|
+
authorityConnectionId: null | string;
|
|
63
65
|
clients: Set<WebSocket>;
|
|
64
66
|
exitCode: null | number;
|
|
65
67
|
id: string;
|
|
@@ -73,9 +75,11 @@ export interface TerminalManagedTerminal {
|
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
export interface TerminalPtyManagerLike {
|
|
76
|
-
attach: (id: string, ws: WebSocket) => boolean;
|
|
78
|
+
attach: (id: string, ws: WebSocket, opts?: { lastSeq?: number; snapshot?: boolean }) => boolean;
|
|
77
79
|
detach: (id: string, ws: WebSocket) => boolean;
|
|
78
80
|
getTerminal: (id: string) => TerminalManagedTerminal | undefined;
|
|
81
|
+
/** Phase 3: route resize through the manager so dims persist + broadcast to all. */
|
|
82
|
+
resize: (id: string, cols: number, rows: number) => boolean;
|
|
79
83
|
}
|
|
80
84
|
|
|
81
85
|
/** A message in the history payload. */
|
|
@@ -146,8 +150,9 @@ export type WireTerminalServerMessage =
|
|
|
146
150
|
| { bytes: number; type: 'output-dropped' }
|
|
147
151
|
| { chunk: number; data: string; total: number; type: 'scrollback' }
|
|
148
152
|
| { code: null | number; signal: null | string; type: 'exit' }
|
|
153
|
+
| { cols: number; data: string; rows: number; seq: number; type: 'snapshot' }
|
|
149
154
|
| { cols: number; rows: number; type: 'resize' }
|
|
150
|
-
| { data: string; type: 'output' }
|
|
155
|
+
| { data: string; seq: number; type: 'output' }
|
|
151
156
|
| { message: string; type: 'error' };
|
|
152
157
|
|
|
153
158
|
// ── notification-sessions type alias ────────────────────────────────
|
|
@@ -52,6 +52,9 @@ export const POST: RequestHandler = async ({ params, request }) => {
|
|
|
52
52
|
return json({ error: 'Terminal already exited' }, { status: 409 });
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
// Phase 3: ptyManager.resize() persists cols/rows to SQLite (G5) and
|
|
56
|
+
// broadcasts the new size to ALL attached clients (including this caller's
|
|
57
|
+
// own clients), intentionally consistent with the WS authority path.
|
|
55
58
|
ptyManager.resize(params.id, cols, rows);
|
|
56
59
|
|
|
57
60
|
console.log(`[terminals] Resized terminal ${params.id} to ${cols}x${rows}`);
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{bv as Te,v as Ve,s as P,g as j,b as N,P as oe,bw as At}from"./DWmC0QM7.js";class pe{constructor(t,n){this.status=t,typeof n=="string"?this.body={message:n}:n?this.body=n:this.body={message:`Error: ${t}`}}toString(){return JSON.stringify(this.body)}}class Le{constructor(t,n){this.status=t,this.location=n}}class Pe extends Error{constructor(t,n,r){super(r),this.status=t,this.text=n}}new URL("sveltekit-internal://");function Et(e,t){return e==="/"||t==="ignore"?e:t==="never"?e.endsWith("/")?e.slice(0,-1):e:t==="always"&&!e.endsWith("/")?e+"/":e}function kt(e){return e.split("%25").map(decodeURI).join("%25")}function Rt(e){for(const t in e)e[t]=decodeURIComponent(e[t]);return e}function ye({href:e}){return e.split("#")[0]}function St(...e){let t=5381;for(const n of e)if(typeof n=="string"){let r=n.length;for(;r;)t=t*33^n.charCodeAt(--r)}else if(ArrayBuffer.isView(n)){const r=new Uint8Array(n.buffer,n.byteOffset,n.byteLength);let a=r.length;for(;a;)t=t*33^r[--a]}else throw new TypeError("value must be a string or TypedArray");return(t>>>0).toString(36)}new TextEncoder;const It=new TextDecoder;function Ut(e){const t=atob(e),n=new Uint8Array(t.length);for(let r=0;r<t.length;r++)n[r]=t.charCodeAt(r);return n}const Tt=window.fetch;window.fetch=(e,t)=>((e instanceof Request?e.method:t?.method||"GET")!=="GET"&&z.delete(je(e)),Tt(e,t));const z=new Map;function Lt(e,t){const n=je(e,t),r=document.querySelector(n);if(r?.textContent){r.remove();let{body:a,...s}=JSON.parse(r.textContent);const o=r.getAttribute("data-ttl");return o&&z.set(n,{body:a,init:s,ttl:1e3*Number(o)}),r.getAttribute("data-b64")!==null&&(a=Ut(a)),Promise.resolve(new Response(a,s))}return window.fetch(e,t)}function Pt(e,t,n){if(z.size>0){const r=je(e,n),a=z.get(r);if(a){if(performance.now()<a.ttl&&["default","force-cache","only-if-cached",void 0].includes(n?.cache))return new Response(a.body,a.init);z.delete(r)}}return window.fetch(t,n)}function je(e,t){let r=`script[data-sveltekit-fetched][data-url=${JSON.stringify(e instanceof Request?e.url:e)}]`;if(t?.headers||t?.body){const a=[];t.headers&&a.push([...new Headers(t.headers)].join(",")),t.body&&(typeof t.body=="string"||ArrayBuffer.isView(t.body))&&a.push(t.body),r+=`[data-hash="${St(...a)}"]`}return r}const jt=/^(\[)?(\.\.\.)?(\w+)(?:=(\w+))?(\])?$/;function Nt(e){const t=[];return{pattern:e==="/"?/^\/$/:new RegExp(`^${xt(e).map(r=>{const a=/^\[\.\.\.(\w+)(?:=(\w+))?\]$/.exec(r);if(a)return t.push({name:a[1],matcher:a[2],optional:!1,rest:!0,chained:!0}),"(?:/([^]*))?";const s=/^\[\[(\w+)(?:=(\w+))?\]\]$/.exec(r);if(s)return t.push({name:s[1],matcher:s[2],optional:!0,rest:!1,chained:!0}),"(?:/([^/]+))?";if(!r)return;const o=r.split(/\[(.+?)\](?!\])/);return"/"+o.map((i,l)=>{if(l%2){if(i.startsWith("x+"))return ve(String.fromCharCode(parseInt(i.slice(2),16)));if(i.startsWith("u+"))return ve(String.fromCharCode(...i.slice(2).split("-").map(g=>parseInt(g,16))));const u=jt.exec(i),[,d,p,h,f]=u;return t.push({name:h,matcher:f,optional:!!d,rest:!!p,chained:p?l===1&&o[0]==="":!1}),p?"([^]*?)":d?"([^/]*)?":"([^/]+?)"}return ve(i)}).join("")}).join("")}/?$`),params:t}}function Ot(e){return e!==""&&!/^\([^)]+\)$/.test(e)}function xt(e){return e.slice(1).split("/").filter(Ot)}function Ct(e,t,n){const r={},a=e.slice(1),s=a.filter(c=>c!==void 0);let o=0;for(let c=0;c<t.length;c+=1){const i=t[c];let l=a[c-o];if(i.chained&&i.rest&&o&&(l=a.slice(c-o,c+1).filter(u=>u).join("/"),o=0),l===void 0)if(i.rest)l="";else continue;if(!i.matcher||n[i.matcher](l)){r[i.name]=l;const u=t[c+1],d=a[c+1];u&&!u.rest&&u.optional&&d&&i.chained&&(o=0),!u&&!d&&Object.keys(r).length===s.length&&(o=0);continue}if(i.optional&&i.chained){o++;continue}return}if(!o)return r}function ve(e){return e.normalize().replace(/[[\]]/g,"\\$&").replace(/%/g,"%25").replace(/\//g,"%2[Ff]").replace(/\?/g,"%3[Ff]").replace(/#/g,"%23").replace(/[.*+?^${}()|\\]/g,"\\$&")}function Dt({nodes:e,server_loads:t,dictionary:n,matchers:r}){const a=new Set(t);return Object.entries(n).map(([c,[i,l,u]])=>{const{pattern:d,params:p}=Nt(c),h={id:c,exec:f=>{const g=d.exec(f);if(g)return Ct(g,p,r)},errors:[1,...u||[]].map(f=>e[f]),layouts:[0,...l||[]].map(o),leaf:s(i)};return h.errors.length=h.layouts.length=Math.max(h.errors.length,h.layouts.length),h});function s(c){const i=c<0;return i&&(c=~c),[i,e[c]]}function o(c){return c===void 0?c:[a.has(c),e[c]]}}function Qe(e,t=JSON.parse){try{return t(sessionStorage[e])}catch{}}function qe(e,t,n=JSON.stringify){const r=n(t);try{sessionStorage[e]=r}catch{}}const U=globalThis.__sveltekit_1gln3aw?.base??"",$t=globalThis.__sveltekit_1gln3aw?.assets??U??"",Bt="1781369023861",et="sveltekit:snapshot",tt="sveltekit:scroll",nt="sveltekit:states",Ft="sveltekit:pageurl",q="sveltekit:history",Q="sveltekit:navigation",B={tap:1,hover:2,viewport:3,eager:4,off:-1,false:-1},re=location.origin;function Ne(e){if(e instanceof URL)return e;let t=document.baseURI;if(!t){const n=document.getElementsByTagName("base");t=n.length?n[0].href:document.URL}return new URL(e,t)}function M(){return{x:pageXOffset,y:pageYOffset}}function V(e,t){return e.getAttribute(`data-sveltekit-${t}`)}const Ye={...B,"":B.hover};function rt(e){let t=e.assignedSlot??e.parentNode;return t?.nodeType===11&&(t=t.host),t}function at(e,t){for(;e&&e!==t;){if(e.nodeName.toUpperCase()==="A"&&e.hasAttribute("href"))return e;e=rt(e)}}function Ee(e,t,n){let r;try{if(r=new URL(e instanceof SVGAElement?e.href.baseVal:e.href,document.baseURI),n&&r.hash.match(/^#[^/]/)){const c=location.hash.split("#")[1]||"/";r.hash=`#${c}${r.hash}`}}catch{}const a=e instanceof SVGAElement?e.target.baseVal:e.target,s=!r||!!a||_e(r,t,n)||(e.getAttribute("rel")||"").split(/\s+/).includes("external"),o=r?.origin===re&&e.hasAttribute("download");return{url:r,external:s,target:a,download:o}}function se(e){let t=null,n=null,r=null,a=null,s=null,o=null,c=e;for(;c&&c!==document.documentElement;)r===null&&(r=V(c,"preload-code")),a===null&&(a=V(c,"preload-data")),t===null&&(t=V(c,"keepfocus")),n===null&&(n=V(c,"noscroll")),s===null&&(s=V(c,"reload")),o===null&&(o=V(c,"replacestate")),c=rt(c);function i(l){switch(l){case"":case"true":return!0;case"off":case"false":return!1;default:return}}return{preload_code:Ye[r??"off"],preload_data:Ye[a??"off"],keepfocus:i(t),noscroll:i(n),reload:i(s),replace_state:i(o)}}function Ge(e){const t=Te(e);let n=!0;function r(){n=!0,t.update(o=>o)}function a(o){n=!1,t.set(o)}function s(o){let c;return t.subscribe(i=>{(c===void 0||n&&i!==c)&&o(c=i)})}return{notify:r,set:a,subscribe:s}}const ot={v:()=>{}};function Mt(){const{set:e,subscribe:t}=Te(!1);let n;async function r(){clearTimeout(n);try{const a=await fetch(`${$t}/_app/version.json`,{headers:{pragma:"no-cache","cache-control":"no-cache"}});if(!a.ok)return!1;const o=(await a.json()).version!==Bt;return o&&(e(!0),ot.v(),clearTimeout(n)),o}catch{return!1}}return{subscribe:t,check:r}}function _e(e,t,n){return e.origin!==re||!e.pathname.startsWith(t)?!0:n?e.pathname!==location.pathname:!1}function jn(e){}const Vt=-1,qt=-2,Yt=-3,Gt=-4,Kt=-5,Wt=-6,Ht=-7,st=2**32-1,ke=st-1;function Xt(e){return!(!Number.isInteger(e)||e<0||e>ke)}function zt(e){return!(!Number.isInteger(e)||e<0||e>st)}function Jt(e){return Uint8Array.fromBase64(e).buffer}function Zt(e){return Uint8Array.from(Buffer.from(e,"base64")).buffer}function Qt(e){const t=atob(e),n=t.length,r=new Uint8Array(n);for(let a=0;a<n;a++)r[a]=t.charCodeAt(a);return r.buffer}const en=typeof Uint8Array.fromBase64=="function",tn=typeof process=="object"&&process.versions?.node!==void 0,nn=en?Jt:tn?Zt:Qt;function rn(e,t){if(typeof e=="number")return s(e,!0);if(!Array.isArray(e)||e.length===0)throw new Error("Invalid input");const n=e,r=Array(n.length);let a=null;function s(o,c=!1){if(o===Vt)return;if(o===Yt)return NaN;if(o===Gt)return 1/0;if(o===Kt)return-1/0;if(o===Wt)return-0;if(c||typeof o!="number")throw new Error("Invalid input");if(o in r)return r[o];const i=n[o];if(!i||typeof i!="object")r[o]=i;else if(Array.isArray(i))if(typeof i[0]=="string"){const l=i[0],u=t&&Object.hasOwn(t,l)?t[l]:void 0;if(u){let d=i[1];if(typeof d!="number"&&(d=n.push(i[1])-1),a??=new Set,a.has(d))throw new Error("Invalid circular reference");return a.add(d),r[o]=u(s(d)),a.delete(d),r[o]}switch(l){case"Date":r[o]=new Date(i[1]);break;case"Set":const d=new Set;r[o]=d;for(let f=1;f<i.length;f+=1)d.add(s(i[f]));break;case"Map":const p=new Map;r[o]=p;for(let f=1;f<i.length;f+=2)p.set(s(i[f]),s(i[f+1]));break;case"RegExp":r[o]=new RegExp(i[1],i[2]);break;case"Object":{const f=i[1];if(typeof n[f]=="object"&&n[f][0]!=="BigInt")throw new Error("Invalid input");r[o]=Object(s(f));break}case"BigInt":r[o]=BigInt(i[1]);break;case"null":const h=Object.create(null);r[o]=h;for(let f=1;f<i.length;f+=2){if(i[f]==="__proto__")throw new Error("Cannot parse an object with a `__proto__` property");h[i[f]]=s(i[f+1])}break;case"Int8Array":case"Uint8Array":case"Uint8ClampedArray":case"Int16Array":case"Uint16Array":case"Float16Array":case"Int32Array":case"Uint32Array":case"Float32Array":case"Float64Array":case"BigInt64Array":case"BigUint64Array":case"DataView":{if(n[i[1]][0]!=="ArrayBuffer")throw new Error("Invalid data");const f=globalThis[l],g=s(i[1]);r[o]=i[2]!==void 0?new f(g,i[2],i[3]):new f(g);break}case"ArrayBuffer":{const f=i[1];if(typeof f!="string")throw new Error("Invalid ArrayBuffer encoding");const g=nn(f);r[o]=g;break}case"Temporal.Duration":case"Temporal.Instant":case"Temporal.PlainDate":case"Temporal.PlainTime":case"Temporal.PlainDateTime":case"Temporal.PlainMonthDay":case"Temporal.PlainYearMonth":case"Temporal.ZonedDateTime":{const f=l.slice(9);r[o]=Temporal[f].from(i[1]);break}case"URL":{const f=new URL(i[1]);r[o]=f;break}case"URLSearchParams":{const f=new URLSearchParams(i[1]);r[o]=f;break}default:throw new Error(`Unknown type ${l}`)}}else if(i[0]===Ht){const l=i[1];if(!zt(l))throw new Error("Invalid input");const u=[];r[o]=u,u[ke]=void 0,delete u[ke];for(let d=2;d<i.length;d+=2){const p=i[d];if(!Xt(p)||p>=l)throw new Error("Invalid input");u[p]=s(i[d+1])}u.length=l}else{const l=new Array(i.length);r[o]=l;for(let u=0;u<i.length;u+=1){const d=i[u];d!==qt&&(l[u]=s(d))}}else{const l={};r[o]=l;for(const u of Object.keys(i)){if(u==="__proto__")throw new Error("Cannot parse an object with a `__proto__` property");const d=i[u];l[u]=s(d)}}return r[o]}return s(0)}const it=new Set(["load","prerender","csr","ssr","trailingSlash","config"]);[...it];const an=new Set([...it]);[...an];function on(e){return e.filter(t=>t!=null)}const sn="x-sveltekit-invalidated",cn="x-sveltekit-trailing-slash";function ie(e){return e instanceof pe||e instanceof Pe?e.status:500}function ln(e){return e instanceof Pe?e.text:"Internal Error"}let S,ee,be;const fn=Ve.toString().includes("$$")||/function \w+\(\) \{\}/.test(Ve.toString()),Ke="a:";fn?(S={data:{},form:null,error:null,params:{},route:{id:null},state:{},status:-1,url:new URL(Ke)},ee={current:null},be={current:!1}):(S=new class{#e=P({});get data(){return j(this.#e)}set data(t){N(this.#e,t)}#t=P(null);get form(){return j(this.#t)}set form(t){N(this.#t,t)}#n=P(null);get error(){return j(this.#n)}set error(t){N(this.#n,t)}#r=P({});get params(){return j(this.#r)}set params(t){N(this.#r,t)}#a=P({id:null});get route(){return j(this.#a)}set route(t){N(this.#a,t)}#o=P({});get state(){return j(this.#o)}set state(t){N(this.#o,t)}#s=P(-1);get status(){return j(this.#s)}set status(t){N(this.#s,t)}#i=P(new URL(Ke));get url(){return j(this.#i)}set url(t){N(this.#i,t)}},ee=new class{#e=P(null);get current(){return j(this.#e)}set current(t){N(this.#e,t)}},be=new class{#e=P(!1);get current(){return j(this.#e)}set current(t){N(this.#e,t)}},ot.v=()=>be.current=!0);function un(e){Object.assign(S,e)}const dn="/__data.json",hn=".html__data.json";function pn(e){return e.endsWith(".html")?e.replace(/\.html$/,hn):e.replace(/\/$/,"")+dn}const _n=new Set(["icon","shortcut icon","apple-touch-icon"]);let H=null;const D=Qe(tt)??{},te=Qe(et)??{},C={url:Ge({}),page:Ge({}),navigating:Te(null),updated:Mt()};function Oe(e){D[e]=M()}function gn(e,t){let n=e+1;for(;D[n];)delete D[n],n+=1;for(n=t+1;te[n];)delete te[n],n+=1}function K(e,t=!1){return t?location.replace(e.href):location.href=e.href,new Promise(()=>{})}async function ct(){if("serviceWorker"in navigator){const e=await navigator.serviceWorker.getRegistration(U||"/");e&&await e.update()}}function We(){}let xe,Re,ce,x,Se,A;const le=[],fe=[];let L=null;function Ie(){L?.fork?.then(e=>e?.discard()),L=null}const ae=new Map,lt=new Set,mn=new Set,J=new Set;let w={branch:[],error:null,url:null},Ce=!1,ue=!1,He=!0,ne=!1,X=!1,ft=!1,De=!1,ut,R,I,F;const Z=new Set,Xe=new Map;async function Cn(e,t,n){globalThis.__sveltekit_1gln3aw?.data&&globalThis.__sveltekit_1gln3aw.data,document.URL!==location.href&&(location.href=location.href),A=e,await e.hooks.init?.(),xe=Dt(e),x=document.documentElement,Se=t,Re=e.nodes[0],ce=e.nodes[1],Re(),ce(),R=history.state?.[q],I=history.state?.[Q],R||(R=I=Date.now(),history.replaceState({...history.state,[q]:R,[Q]:I},""));const r=D[R];function a(){r&&(history.scrollRestoration="manual",scrollTo(r.x,r.y))}n?(a(),await Un(Se,n)):(await Y({type:"enter",url:Ne(A.hash?Ln(new URL(location.href)):location.href),replace_state:!0}),a()),In()}function wn(){le.length=0,De=!1}function dt(e){fe.some(t=>t?.snapshot)&&(te[e]=fe.map(t=>t?.snapshot?.capture()))}function ht(e){te[e]?.forEach((t,n)=>{fe[n]?.snapshot?.restore(t)})}function ze(){Oe(R),qe(tt,D),dt(I),qe(et,te)}async function pt(e,t,n,r){let a;t.invalidateAll&&Ie(),await Y({type:"goto",url:Ne(e),keepfocus:t.keepFocus,noscroll:t.noScroll,replace_state:t.replaceState,state:t.state,redirect_count:n,nav_token:r,accept:()=>{t.invalidateAll&&(De=!0,a=[...Xe.keys()]),t.invalidate&&t.invalidate.forEach(Sn)}}),t.invalidateAll&&oe().then(oe).then(()=>{Xe.forEach(({resource:s},o)=>{a?.includes(o)&&s.refresh?.()})})}async function yn(e){if(e.id!==L?.id){Ie();const t={};Z.add(t),L={id:e.id,token:t,promise:gt({...e,preload:t}).then(n=>(Z.delete(t),n.type==="loaded"&&n.state.error&&Ie(),n)),fork:null}}return L.promise}async function Ae(e){const t=(await me(e,!1))?.route;t&&await Promise.all([...t.layouts,t.leaf].filter(Boolean).map(n=>n[1]()))}async function _t(e,t,n){const r={params:w.params,route:{id:w.route?.id??null},url:new URL(location.href)};w={...e.state,nav:r};const a=document.querySelector("style[data-sveltekit]");if(a&&a.remove(),Object.assign(S,e.props.page),ut=new A.root({target:t,props:{...e.props,stores:C,components:fe},hydrate:n,sync:!1,transformError:void 0}),await Promise.resolve(),ht(I),n){const s={from:null,to:{...r,scroll:D[R]??M()},willUnload:!1,type:"enter",complete:Promise.resolve()};J.forEach(o=>o(s))}ue=!0}async function de({url:e,params:t,branch:n,errors:r,status:a,error:s,route:o,form:c}){let i="never";if(U&&(e.pathname===U||e.pathname===U+"/"))i="always";else for(const f of n)f?.slash!==void 0&&(i=f.slash);e.pathname=Et(e.pathname,i),e.search=e.search;const l={type:"loaded",state:{url:e,params:t,branch:n,error:s,route:o},props:{constructors:on(n).map(f=>f.node.component),page:Me(S)}};c!==void 0&&(l.props.form=c);let u={},d=!S,p=0;for(let f=0;f<Math.max(n.length,w.branch.length);f+=1){const g=n[f],b=w.branch[f];g?.data!==b?.data&&(d=!0),g&&(u={...u,...g.data},d&&(l.props[`data_${p}`]=u),p+=1)}return(!w.url||e.href!==w.url.href||w.error!==s||c!==void 0&&c!==S.form||d)&&(l.props.page={error:s,params:t,route:{id:o?.id??null},state:{},status:a,url:new URL(e),form:c??null,data:d?u:S.data}),l}async function $e({loader:e,parent:t,url:n,params:r,route:a,server_data_node:s}){let o=null;const c={dependencies:new Set,params:new Set,parent:!1,route:!1,url:!1,search_params:new Set},i=await e();return{node:i,loader:e,server:s,universal:i.universal?.load?{type:"data",data:o,uses:c}:null,data:o??s?.data??null,slash:i.universal?.trailingSlash??s?.slash}}function vn(e,t,n){let r=e instanceof Request?e.url:e;const a=new URL(r,n);a.origin===n.origin&&(r=a.href.slice(n.origin.length));const s=ue?Pt(r,a.href,t):Lt(r,t);return{resolved:a,promise:s}}function Je(e,t,n,r,a,s){if(De)return!0;if(!a)return!1;if(a.parent&&e||a.route&&t||a.url&&n)return!0;for(const o of a.search_params)if(r.has(o))return!0;for(const o of a.params)if(s[o]!==w.params[o])return!0;for(const o of a.dependencies)if(le.some(c=>c(new URL(o))))return!0;return!1}function Be(e,t){return e?.type==="data"?e:e?.type==="skip"?t??null:null}function bn(e,t){if(!e)return new Set(t.searchParams.keys());const n=new Set([...e.searchParams.keys(),...t.searchParams.keys()]);for(const r of n){const a=e.searchParams.getAll(r),s=t.searchParams.getAll(r);a.every(o=>s.includes(o))&&s.every(o=>a.includes(o))&&n.delete(r)}return n}function Ze({error:e,url:t,route:n,params:r}){return{type:"loaded",state:{error:e,url:t,route:n,params:r,branch:[]},props:{page:Me(S),constructors:[]}}}async function gt({id:e,invalidating:t,url:n,params:r,route:a,preload:s}){if(L?.id===e)return Z.delete(L.token),L.promise;const{errors:o,layouts:c,leaf:i}=a,l=[...c,i];o.forEach(m=>m?.().catch(()=>{})),l.forEach(m=>m?.[1]().catch(()=>{}));let u=null;const d=w.url?e!==he(w.url):!1,p=w.route?a.id!==w.route.id:!1,h=bn(w.url,n);let f=!1;{const m=l.map((y,E)=>{const k=w.branch[E],v=!!y?.[0]&&(k?.loader!==y[1]||Je(f,p,d,h,k.server?.uses,r));return v&&(f=!0),v});if(m.some(Boolean)){try{u=await yt(n,m)}catch(y){const E=await G(y,{url:n,params:r,route:{id:e}});return Z.has(s)?Ze({error:E,url:n,params:r,route:a}):ge({status:ie(y),error:E,url:n,route:a})}if(u.type==="redirect")return u}}const g=u?.nodes;let b=!1;const _=l.map(async(m,y)=>{if(!m)return;const E=w.branch[y],k=g?.[y];if((!k||k.type==="skip")&&m[1]===E?.loader&&!Je(b,p,d,h,E.universal?.uses,r))return E;if(b=!0,k?.type==="error")throw k;return $e({loader:m[1],url:n,params:r,route:a,parent:async()=>{const O={};for(let $=0;$<y;$+=1)Object.assign(O,(await _[$])?.data);return O},server_data_node:Be(k===void 0&&m[0]?{type:"skip"}:k??null,m[0]?E?.server:void 0)})});for(const m of _)m.catch(()=>{});const T=[];for(let m=0;m<l.length;m+=1)if(l[m])try{T.push(await _[m])}catch(y){if(y instanceof Le)return{type:"redirect",location:y.location};if(Z.has(s))return Ze({error:await G(y,{params:r,url:n,route:{id:a.id}}),url:n,params:r,route:a});let E=ie(y),k;if(g?.includes(y))E=y.status??E,k=y.error;else if(y instanceof pe)k=y.body;else{if(await C.updated.check())return await ct(),await K(n);k=await G(y,{params:r,url:n,route:{id:a.id}})}const v=await An(m,T,o);return v?de({url:n,params:r,branch:T.slice(0,v.idx).concat(v.node),errors:o,status:E,error:k,route:a}):await wt(n,{id:a.id},k,E)}else T.push(void 0);return de({url:n,params:r,branch:T,errors:o,status:200,error:null,route:a,form:t?void 0:null})}async function An(e,t,n){for(;e--;)if(n[e]){let r=e;for(;!t[r];)r-=1;try{return{idx:r+1,node:{node:await n[e](),loader:n[e],data:{},server:null,universal:null}}}catch{continue}}}async function ge({status:e,error:t,url:n,route:r}){const a={};let s=null;if(A.server_loads[0]===0)try{const c=await yt(n,[!0]);if(c.type!=="data"||c.nodes[0]&&c.nodes[0].type!=="data")throw 0;s=c.nodes[0]??null}catch{(n.origin!==re||n.pathname!==location.pathname||Ce)&&await K(n)}try{const o=await $e({loader:Re,url:n,params:a,route:r,parent:()=>Promise.resolve({}),server_data_node:Be(s)}),c={node:await ce(),loader:ce,universal:null,server:null,data:null};return de({url:n,params:a,branch:[o,c],status:e,error:t,errors:[],route:null})}catch(o){if(o instanceof Le)return pt(new URL(o.location,location.href),{},0);throw o}}async function En(e){const t=e.href;if(ae.has(t))return ae.get(t);let n;try{const r=(async()=>{let a=await A.hooks.reroute({url:new URL(e),fetch:async(s,o)=>vn(s,o,e).promise})??e;if(typeof a=="string"){const s=new URL(e);A.hash?s.hash=a:s.pathname=a,a=s}return a})();ae.set(t,r),n=await r}catch{ae.delete(t);return}return n}async function me(e,t){if(e&&!_e(e,U,A.hash)){const n=await En(e);if(!n)return;const r=kn(n);for(const a of xe){const s=a.exec(r);if(s)return{id:he(e),invalidating:t,route:a,params:Rt(s),url:e}}}}function kn(e){return kt(A.hash?e.hash.replace(/^#/,"").replace(/[?#].+/,""):e.pathname.slice(U.length))||"/"}function he(e){return(A.hash?e.hash.replace(/^#/,""):e.pathname)+e.search}function mt({url:e,type:t,intent:n,delta:r,event:a,scroll:s}){let o=!1;const c=Fe(w,n,e,t,s??null);r!==void 0&&(c.navigation.delta=r),a!==void 0&&(c.navigation.event=a);const i={...c.navigation,cancel:()=>{o=!0,c.reject(new Error("navigation cancelled"))}};return ne||lt.forEach(l=>l(i)),o?null:c}async function Y({type:e,url:t,popped:n,keepfocus:r,noscroll:a,replace_state:s,state:o={},redirect_count:c=0,nav_token:i={},accept:l=We,block:u=We,event:d}){const p=F;F=i;const h=await me(t,!1),f=e==="enter"?Fe(w,h,t,e):mt({url:t,type:e,delta:n?.delta,intent:h,scroll:n?.scroll,event:d});if(!f){u(),F===i&&(F=p);return}const g=R,b=I;l(),ne=!0,ue&&f.navigation.type!=="enter"&&C.navigating.set(ee.current=f.navigation);let _=h&&await gt(h);if(!_){if(_e(t,U,A.hash))return await K(t,s);_=await wt(t,{id:null},await G(new Pe(404,"Not Found",`Not found: ${t.pathname}`),{url:t,params:{},route:{id:null}}),404,s)}if(t=h?.url||t,F!==i)return f.reject(new Error("navigation aborted")),!1;if(_.type==="redirect"){if(c<20){await Y({type:e,url:new URL(_.location,t),popped:n,keepfocus:r,noscroll:a,replace_state:s,state:o,redirect_count:c+1,nav_token:i}),f.fulfil(void 0);return}_=await ge({status:500,error:await G(new Error("Redirect loop"),{url:t,params:{},route:{id:null}}),url:t,route:{id:null}})}else _.props.page.status>=400&&await C.updated.check()&&(await ct(),await K(t,s));if(wn(),Oe(g),dt(b),_.props.page.url.pathname!==t.pathname&&(t.pathname=_.props.page.url.pathname),o=n?n.state:o,!n){const v=s?0:1,O={[q]:R+=v,[Q]:I+=v,[nt]:o};(s?history.replaceState:history.pushState).call(history,O,"",t),s||gn(R,I)}const T=h&&L?.id===h.id?L.fork:null;L=null,_.props.page.state=o;let m;if(ue){const v=(await Promise.all(Array.from(mn,W=>W(f.navigation)))).filter(W=>typeof W=="function");if(v.length>0){let W=function(){v.forEach(we=>{J.delete(we)})};v.push(W),v.forEach(we=>{J.add(we)})}const O=f.navigation.to;w={..._.state,nav:{params:O.params,route:O.route,url:O.url}},_.props.page&&(_.props.page.url=t);const $=T&&await T;$?m=$.commit():(H=null,ut.$set(_.props),H&&Object.assign(_.props.page,H),un(_.props.page),m=At?.()),ft=!0}else await _t(_,Se,!1);const{activeElement:y}=document;await m,await oe(),await oe();let E=null;if(He){const v=n?n.scroll:a?M():null;v?scrollTo(v.x,v.y):(E=t.hash&&document.getElementById(bt(t)))?E.scrollIntoView():scrollTo(0,0)}const k=document.activeElement!==y&&document.activeElement!==document.body;!r&&!k&&Tn(t,!E),He=!0,_.props.page&&(H&&Object.assign(_.props.page,H),Object.assign(S,_.props.page)),ne=!1,e==="popstate"&&ht(I),f.fulfil(void 0),f.navigation.to&&(f.navigation.to.scroll=M()),J.forEach(v=>v(f.navigation)),C.navigating.set(ee.current=null)}async function wt(e,t,n,r,a){return e.origin===re&&e.pathname===location.pathname&&!Ce?await ge({status:r,error:n,url:e,route:t}):await K(e,a)}function Rn(){let e,t={element:void 0,href:void 0},n;x.addEventListener("mousemove",c=>{const i=c.target;clearTimeout(e),e=setTimeout(()=>{s(i,B.hover)},20)});function r(c){c.defaultPrevented||s(c.composedPath()[0],B.tap)}x.addEventListener("mousedown",r),x.addEventListener("touchstart",r,{passive:!0});const a=new IntersectionObserver(c=>{for(const i of c)i.isIntersecting&&(Ae(new URL(i.target.href)),a.unobserve(i.target))},{threshold:0});async function s(c,i){const l=at(c,x),u=l===t.element&&l?.href===t.href&&i>=n;if(!l||u)return;const{url:d,external:p,download:h}=Ee(l,U,A.hash);if(p||h)return;const f=se(l),g=d&&he(w.url)===he(d);if(!(f.reload||g))if(i<=f.preload_data){t={element:l,href:l.href},n=B.tap;const b=await me(d,!1);if(!b)return;yn(b)}else i<=f.preload_code&&(t={element:l,href:l.href},n=i,Ae(d))}function o(){a.disconnect();for(const c of x.querySelectorAll("a")){const{url:i,external:l,download:u}=Ee(c,U,A.hash);if(l||u)continue;const d=se(c);d.reload||(d.preload_code===B.viewport&&a.observe(c),d.preload_code===B.eager&&Ae(i))}}J.add(o),o()}function G(e,t){if(e instanceof pe)return e.body;const n=ie(e),r=ln(e);return A.hooks.handleError({error:e,event:t,status:n,message:r})??{message:r}}function Dn(e,t={}){return e=new URL(Ne(e)),e.origin!==re?Promise.reject(new Error("goto: invalid URL")):pt(e,t,0)}function Sn(e){if(typeof e=="function")le.push(e);else{const{href:t}=new URL(e,location.href);le.push(n=>n.href===t)}}function In(){history.scrollRestoration="manual",addEventListener("beforeunload",t=>{let n=!1;if(ze(),!ne){const r=Fe(w,void 0,null,"leave"),a={...r.navigation,cancel:()=>{n=!0,r.reject(new Error("navigation cancelled"))}};lt.forEach(s=>s(a))}n?(t.preventDefault(),t.returnValue=""):history.scrollRestoration="auto"}),addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&ze()}),navigator.connection?.saveData||Rn(),x.addEventListener("click",async t=>{if(t.button||t.which!==1||t.metaKey||t.ctrlKey||t.shiftKey||t.altKey||t.defaultPrevented)return;const n=at(t.composedPath()[0],x);if(!n)return;const{url:r,external:a,target:s,download:o}=Ee(n,U,A.hash);if(!r)return;if(s==="_parent"||s==="_top"){if(window.parent!==window)return}else if(s&&s!=="_self")return;const c=se(n);if(!(n instanceof SVGAElement)&&r.protocol!==location.protocol&&!(r.protocol==="https:"||r.protocol==="http:")||o)return;const[l,u]=(A.hash?r.hash.replace(/^#/,""):r.href).split("#"),d=l===ye(location);if(a||c.reload&&(!d||!u)){mt({url:r,type:"link",event:t})?ne=!0:t.preventDefault();return}if(u!==void 0&&d){const[,p]=w.url.href.split("#");if(p===u){if(t.preventDefault(),u===""||u==="top"&&n.ownerDocument.getElementById("top")===null)scrollTo({top:0});else{const h=n.ownerDocument.getElementById(decodeURIComponent(u));h&&(h.scrollIntoView(),h.focus())}return}if(X=!0,Oe(R),e(r),!c.replace_state)return;X=!1}t.preventDefault(),await new Promise(p=>{requestAnimationFrame(()=>{setTimeout(p,0)}),setTimeout(p,100)}),await Y({type:"link",url:r,keepfocus:c.keepfocus,noscroll:c.noscroll,replace_state:c.replace_state??r.href===location.href,event:t})}),x.addEventListener("submit",t=>{if(t.defaultPrevented)return;const n=HTMLFormElement.prototype.cloneNode.call(t.target),r=t.submitter;if((r?.formTarget||n.target)==="_blank"||(r?.formMethod||n.method)!=="get")return;const o=new URL(r?.hasAttribute("formaction")&&r?.formAction||n.action);if(_e(o,U,!1))return;const c=t.target,i=se(c);if(i.reload)return;t.preventDefault(),t.stopPropagation();const l=new FormData(c,r);o.search=new URLSearchParams(l).toString(),Y({type:"form",url:o,keepfocus:i.keepfocus,noscroll:i.noscroll,replace_state:i.replace_state??o.href===location.href,event:t})}),addEventListener("popstate",async t=>{if(!Ue){if(t.state?.[q]){const n=t.state[q];if(F={},n===R)return;const r=D[n],a=t.state[nt]??{},s=new URL(t.state[Ft]??location.href),o=t.state[Q],c=w.url?ye(location)===ye(w.url):!1;if(o===I&&(ft||c)){a!==S.state&&(S.state=a),e(s),D[R]=M(),r&&scrollTo(r.x,r.y),R=n;return}const l=n-R;await Y({type:"popstate",url:s,popped:{state:a,scroll:r,delta:l},accept:()=>{R=n,I=o},block:()=>{history.go(-l)},nav_token:F,event:t})}else if(!X){const n=new URL(location.href);e(n),A.hash&&location.reload()}}}),addEventListener("hashchange",()=>{X&&(X=!1,history.replaceState({...history.state,[q]:++R,[Q]:I},"",location.href))});for(const t of document.querySelectorAll("link"))_n.has(t.rel)&&(t.href=t.href);addEventListener("pageshow",t=>{t.persisted&&C.navigating.set(ee.current=null)});function e(t){w.url=S.url=t,C.page.set(Me(S)),C.page.notify()}}async function Un(e,{status:t=200,error:n,node_ids:r,params:a,route:s,server_route:o,data:c,form:i}){Ce=!0;const l=new URL(location.href);let u;({params:a={},route:s={id:null}}=await me(l,!1)||{}),u=xe.find(({id:h})=>h===s.id);let d,p=!0;try{const h=r.map(async(g,b)=>{const _=c[b];return _?.uses&&(_.uses=vt(_.uses)),$e({loader:A.nodes[g],url:l,params:a,route:s,parent:async()=>{const T={};for(let m=0;m<b;m+=1)Object.assign(T,(await h[m]).data);return T},server_data_node:Be(_)})}),f=await Promise.all(h);if(u){const g=u.layouts;for(let b=0;b<g.length;b++)g[b]||f.splice(b,0,void 0)}d=await de({url:l,params:a,branch:f,status:t,error:n,errors:u?.errors,form:i,route:u??null})}catch(h){if(h instanceof Le){await K(new URL(h.location,location.href));return}d=await ge({status:ie(h),error:await G(h,{url:l,params:a,route:s}),url:l,route:s}),e.textContent="",p=!1}d.props.page&&(d.props.page.state={}),await _t(d,e,p)}async function yt(e,t){const n=new URL(e);n.pathname=pn(e.pathname),e.pathname.endsWith("/")&&n.searchParams.append(cn,"1"),n.searchParams.append(sn,t.map(s=>s?"1":"0").join(""));const r=window.fetch,a=await r(n.href,{});if(!a.ok){let s;throw a.headers.get("content-type")?.includes("application/json")?s=await a.json():a.status===404?s="Not Found":a.status===500&&(s="Internal Error"),new pe(a.status,s)}return new Promise(async s=>{const o=new Map,c=a.body.getReader();function i(u){return rn(u,{...A.decoders,Promise:d=>new Promise((p,h)=>{o.set(d,{fulfil:p,reject:h})})})}let l="";for(;;){const{done:u,value:d}=await c.read();if(u&&!l)break;for(l+=!d&&l?`
|
|
2
|
-
`:It.decode(d,{stream:!0});;){const p=l.indexOf(`
|
|
3
|
-
`);if(p===-1)break;const h=JSON.parse(l.slice(0,p));if(l=l.slice(p+1),h.type==="redirect")return s(h);if(h.type==="data")h.nodes?.forEach(f=>{f?.type==="data"&&(f.uses=vt(f.uses),f.data=i(f.data))}),s(h);else if(h.type==="chunk"){const{id:f,data:g,error:b}=h,_=o.get(f);o.delete(f),b?_.reject(i(b)):_.fulfil(i(g))}}}})}function vt(e){return{dependencies:new Set(e?.dependencies??[]),params:new Set(e?.params??[]),parent:!!e?.parent,route:!!e?.route,url:!!e?.url,search_params:new Set(e?.search_params??[])}}let Ue=!1;function Tn(e,t=!0){const n=document.querySelector("[autofocus]");if(n)n.focus();else{const r=bt(e);if(r&&document.getElementById(r)){const{x:s,y:o}=M();setTimeout(()=>{const c=history.state;Ue=!0,location.replace(new URL(`#${r}`,location.href)),history.replaceState(c,"",e),t&&scrollTo(s,o),Ue=!1})}else{const s=document.body,o=s.getAttribute("tabindex");s.tabIndex=-1,s.focus({preventScroll:!0,focusVisible:!1}),o!==null?s.setAttribute("tabindex",o):s.removeAttribute("tabindex")}const a=getSelection();if(a&&a.type!=="None"){const s=[];for(let o=0;o<a.rangeCount;o+=1)s.push(a.getRangeAt(o));setTimeout(()=>{if(a.rangeCount===s.length){for(let o=0;o<a.rangeCount;o+=1){const c=s[o],i=a.getRangeAt(o);if(c.commonAncestorContainer!==i.commonAncestorContainer||c.startContainer!==i.startContainer||c.endContainer!==i.endContainer||c.startOffset!==i.startOffset||c.endOffset!==i.endOffset)return}a.removeAllRanges()}})}}}function Fe(e,t,n,r,a=null){let s,o;const c=new Promise((l,u)=>{s=l,o=u});return c.catch(()=>{}),{navigation:{from:{params:e.params,route:{id:e.route?.id??null},url:e.url,scroll:M()},to:n&&{params:t?.params??null,route:{id:t?.route?.id??null},url:n,scroll:a},willUnload:!t,type:r,complete:c},fulfil:s,reject:o}}function Me(e){return{data:e.data,error:e.error,form:e.form,params:e.params,route:e.route,state:e.state,status:e.status,url:e.url}}function Ln(e){const t=new URL(e);return t.hash=decodeURIComponent(e.hash),t}function bt(e){let t;if(A.hash){const[,,n]=e.hash.split("#",3);t=n??""}else t=e.hash.slice(1);return decodeURIComponent(t)}export{Cn as a,Dn as g,jn as l,S as p,C as s};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["../assets/xterm.DFuMZ0ql.css"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{_ as u}from"./PPVm8Dsz.js";async function D(e){const{Terminal:y}=await u(async()=>{const{Terminal:r}=await import("./BTGVxaYV.js").then(n=>n.x);return{Terminal:r}},[],import.meta.url),{FitAddon:h}=await u(async()=>{const{FitAddon:r}=await import("./BlxrFPDK.js").then(n=>n.a);return{FitAddon:r}},[],import.meta.url),{WebLinksAddon:S}=await u(async()=>{const{WebLinksAddon:r}=await import("./DLu6yJIZ.js").then(n=>n.a);return{WebLinksAddon:r}},[],import.meta.url);await u(()=>Promise.resolve({}),__vite__mapDeps([0]),import.meta.url);const d=new h,a=new y({allowTransparency:!0,cursorBlink:!0,cursorStyle:"block",fontFamily:"'SF Mono', 'Fira Code', 'Cascadia Code', 'Menlo', monospace",fontSize:e.fontSize||14,theme:{background:"#0a0a0f",black:"#0a0a0f",blue:"#3b82f6",brightBlack:"#64748b",brightBlue:"#60a5fa",brightCyan:"#67e8f9",brightGreen:"#4ade80",brightMagenta:"#c4b5fd",brightRed:"#f87171",brightWhite:"#f8fafc",brightYellow:"#fbbf24",cursor:"#e2e8f0",cursorAccent:"#0a0a0f",cyan:"#38bdf8",foreground:"#e2e8f0",green:"#22c55e",magenta:"#a78bfa",red:"#ef4444",selectionBackground:"rgba(99, 102, 241, 0.3)",white:"#e2e8f0",yellow:"#f59e0b"}});a.loadAddon(d),a.loadAddon(new S),a.open(e.container),e.readOnly&&e.initialCols&&e.initialRows?a.resize(e.initialCols,e.initialRows):d.fit();const O=new Set(["f","g","h","j","n","o","p","q","s","t","u","w"]);a.attachCustomKeyEventHandler(r=>{const n=r.key.toLowerCase();return r.metaKey?n==="c"||n==="v"?!0:!O.has(n):!0});let l=null;if(e.terminalId&&e.apiKey&&!e.readOnly){const r=e.terminalId,n=e.apiKey;l=t=>{(async()=>{try{if(!t.clipboardData)return;const g=Array.from(t.clipboardData.items).find(b=>b.type.startsWith("image/"));if(!g)return;const p=g.getAsFile();if(!p)return;t.preventDefault();const f=new FileReader,v=await new Promise((b,A)=>{f.onload=()=>{b(f.result)},f.onerror=A,f.readAsDataURL(p)});(await fetch(`/api/terminals/${r}/paste-image`,{body:JSON.stringify({image:v}),headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"},method:"POST"})).ok&&i?.readyState===WebSocket.OPEN&&i.send(JSON.stringify({data:"",type:"input"}))}catch{}})()},e.container.addEventListener("paste",l)}let i=null,s=null,o=1e3,c=!1;async function m(){if(c)return;let r;try{r=await e.getTicket()}catch{c||(e.onDisconnect?.(),s=setTimeout(()=>{o=Math.min(o*2,3e4),m()},o));return}c||(i=new WebSocket(`${e.wsUrl}?ticket=${r}`),i.onopen=()=>{o=1e3,e.onReconnect?.()},i.onmessage=n=>{const t=JSON.parse(n.data);t.type==="output"||t.type==="scrollback"?a.write(t.data??""):t.type==="exit"?(a.write(`\r
|
|
3
|
-
\x1B[90m[Process exited with code ${String(t.code)}]\x1B[0m\r
|
|
4
|
-
`),c=!0,s&&clearTimeout(s),e.onExit?.(t.code??0)):t.type==="output-dropped"?a.write(`\r
|
|
5
|
-
\x1B[33m[${String(t.bytes)} bytes dropped]\x1B[0m\r
|
|
6
|
-
`):t.type==="activity"?e.onActivity?.(t.active??!1):t.type==="cwd"?e.onCwd?.(t.path??""):t.type==="resize"&&e.readOnly&&t.cols&&t.rows&&a.resize(t.cols,t.rows)},i.onclose=()=>{c||(e.onDisconnect?.(),s=setTimeout(()=>{o=Math.min(o*2,3e4),m()},o))})}m(),a.onData(r=>{e.readOnly||i?.readyState===WebSocket.OPEN&&i.send(JSON.stringify({data:r,type:"input"}))});const w=new ResizeObserver(()=>{e.readOnly||!e.container.offsetWidth||!e.container.offsetHeight||(d.fit(),i?.readyState===WebSocket.OPEN&&i.send(JSON.stringify({cols:a.cols,rows:a.rows,type:"resize"})))});w.observe(e.container);function _(){c=!0,s&&clearTimeout(s),l&&e.container.removeEventListener("paste",l),w.disconnect(),i?.close(),a.dispose()}function k(r){i?.readyState===WebSocket.OPEN&&i.send(JSON.stringify({data:r,type:"input"}))}return{dispose:_,fitAddon:d,sendInput:k,term:a}}function N(e,y){e.readyState===WebSocket.OPEN&&e.send(JSON.stringify({signal:y,type:"signal"}))}export{D as createTerminal,N as sendSignal};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{l as o,a as r}from"../chunks/BfbPKMXz.js";export{o as load_css,r as start};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_server.ts-B54Pvhgc.js","sources":["../../../.svelte-kit/adapter-node/entries/endpoints/api/terminals/_id_/_server.ts.js"],"sourcesContent":["import { v as validateAuth } from \"../../../../../chunks/auth.js\";\nimport { p as ptyManager } from \"../../../../../chunks/pty-manager.js\";\nimport { r as resolveAccess } from \"../../../../../chunks/share-auth.js\";\nimport { s as shareStore } from \"../../../../../chunks/share-store.js\";\nimport { t as toErrorMessage } from \"../../../../../chunks/error.js\";\nimport { c as closeGuests } from \"../../../../../chunks/guest-registry.js\";\nimport { json } from \"@sveltejs/kit\";\nfunction lastScrollbackLine(scrollback) {\n if (!scrollback) {\n return null;\n }\n const lines = scrollback.trimEnd().split(\"\\n\");\n for (let i = lines.length - 1; i >= 0; i--) {\n const line = lines[i].trim();\n if (line) {\n return line.slice(0, 200);\n }\n }\n return null;\n}\nconst GET = ({ params, request }) => {\n const access = resolveAccess(request, params.id);\n if (!access) {\n return json({ error: \"Unauthorized\" }, { status: 401 });\n }\n try {\n const terminal = ptyManager.get(params.id);\n if (!terminal) {\n return json({ error: \"Terminal not found\" }, { status: 404 });\n }\n return json({\n args: terminal.args,\n clientCount: terminal.clients.size,\n cols: terminal.cols,\n command: terminal.command,\n createdAt: terminal.createdAt.toISOString(),\n cwd: terminal.cwd,\n exitCode: terminal.exitCode,\n exitedAt: terminal.exitedAt?.toISOString() ?? null,\n id: terminal.id,\n lastOutput: lastScrollbackLine(terminal.scrollback),\n pid: terminal.pid,\n rows: terminal.rows,\n sessionWs: `/ws/session/${terminal.id}`,\n status: terminal.status,\n timestamp: (/* @__PURE__ */ new Date()).toISOString(),\n ws: `/ws/terminal/${terminal.id}`,\n ...access.level === \"guest\" ? { shareMode: access.mode } : {}\n });\n } catch (error) {\n console.error(\"[terminals] Failed to get terminal:\", toErrorMessage(error));\n return json({ error: \"Failed to get terminal\" }, { status: 500 });\n }\n};\nconst DELETE = ({ params, request }) => {\n const authError = validateAuth(request);\n if (authError) {\n return authError;\n }\n try {\n const terminal = ptyManager.get(params.id);\n if (!terminal) {\n return json({ error: \"Terminal not found\" }, { status: 404 });\n }\n if (terminal.status === \"exited\") {\n ptyManager.remove(params.id);\n shareStore.deleteShare(params.id);\n closeGuests(params.id);\n console.log(`[terminals] Removed exited terminal ${params.id}`);\n return json({\n removed: true,\n success: true,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n }\n ptyManager.kill(params.id);\n shareStore.deleteShare(params.id);\n closeGuests(params.id);\n console.log(`[terminals] Killed terminal ${params.id} (pid=${terminal.pid})`);\n return json({\n success: true,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n } catch (error) {\n console.error(\"[terminals] Failed to kill terminal:\", toErrorMessage(error));\n return json({ error: \"Failed to kill terminal\" }, { status: 500 });\n }\n};\nexport {\n DELETE,\n GET\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_server.ts-Bol54_Qo.js","sources":["../../../.svelte-kit/adapter-node/entries/endpoints/api/terminals/_server.ts.js"],"sourcesContent":["import { v as validateAuth } from \"../../../../chunks/auth.js\";\nimport { P as PROVIDER_COMMANDS } from \"../../../../chunks/registry.js\";\nimport { p as ptyManager } from \"../../../../chunks/pty-manager.js\";\nimport { t as toErrorMessage } from \"../../../../chunks/error.js\";\nimport { json } from \"@sveltejs/kit\";\nimport { realpathSync, statSync } from \"fs\";\nimport { relative, isAbsolute } from \"path\";\nconst ALLOWED_COMMANDS = [\"zsh\", \"bash\", \"sh\", \"fish\", ...PROVIDER_COMMANDS];\nfunction lastScrollbackLine(scrollback) {\n if (!scrollback) {\n return null;\n }\n const lines = scrollback.trimEnd().split(\"\\n\");\n for (let i = lines.length - 1; i >= 0; i--) {\n const line = lines[i].trim();\n if (line) {\n return line.slice(0, 200);\n }\n }\n return null;\n}\nconst GET = ({ request }) => {\n const authError = validateAuth(request);\n if (authError) {\n return authError;\n }\n try {\n const terminals = ptyManager.list().map((t) => ({\n args: t.args,\n clientCount: t.clients.size,\n command: t.command,\n createdAt: t.createdAt.toISOString(),\n currentCwd: t.currentCwd,\n cwd: t.cwd,\n exitCode: t.exitCode,\n exitedAt: t.exitedAt?.toISOString() ?? null,\n id: t.id,\n isActive: t.isActive,\n lastOutput: lastScrollbackLine(t.scrollback),\n pid: t.pid,\n status: t.status\n }));\n return json({\n count: terminals.length,\n terminals,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n } catch (error) {\n console.error(\"[terminals] Failed to list terminals:\", toErrorMessage(error));\n return json({ error: \"Failed to list terminals\" }, { status: 500 });\n }\n};\nconst POST = async ({ request }) => {\n const authError = validateAuth(request);\n if (authError) {\n return authError;\n }\n let body;\n try {\n body = await request.json();\n } catch {\n return json({ error: \"Invalid JSON in request body\" }, { status: 400 });\n }\n try {\n const { args, cols, command, cwd, rows } = body;\n if (!command) {\n return json({ error: \"command is required\" }, { status: 400 });\n }\n if (command.includes(\"/\") || command.includes(\"\\\\\") || !ALLOWED_COMMANDS.includes(command)) {\n return json(\n { error: `Command not allowed. Allowed: ${ALLOWED_COMMANDS.join(\", \")}` },\n { status: 400 }\n );\n }\n if (!cwd) {\n return json({ error: \"cwd is required\" }, { status: 400 });\n }\n let realCwd;\n try {\n realCwd = realpathSync(cwd);\n if (!statSync(realCwd).isDirectory()) {\n return json({ error: \"cwd must be a directory\" }, { status: 400 });\n }\n } catch {\n return json({ error: \"cwd must be a directory\" }, { status: 400 });\n }\n const home = process.env.HOME || \"\";\n if (home) {\n const rel = relative(home, realCwd);\n if (rel.startsWith(\"..\") || isAbsolute(rel)) {\n return json({ error: \"Working directory must be under home directory\" }, { status: 400 });\n }\n }\n if (args !== void 0 && !Array.isArray(args)) {\n return json({ error: \"args must be an array of strings\" }, { status: 400 });\n }\n if (args && !args.every((a) => typeof a === \"string\")) {\n return json({ error: \"All args must be strings\" }, { status: 400 });\n }\n if (cols !== void 0 && (typeof cols !== \"number\" || cols < 1)) {\n return json({ error: \"cols must be a positive number\" }, { status: 400 });\n }\n if (rows !== void 0 && (typeof rows !== \"number\" || rows < 1)) {\n return json({ error: \"rows must be a positive number\" }, { status: 400 });\n }\n const terminal = await ptyManager.create(command, args ?? [], realCwd, cols ?? 80, rows ?? 24);\n console.log(\n `[terminals] Created terminal ${terminal.id} (pid=${terminal.pid}, command=${command})`\n );\n return json(\n {\n command: terminal.command,\n createdAt: terminal.createdAt instanceof Date ? terminal.createdAt.toISOString() : terminal.createdAt,\n cwd: terminal.cwd,\n id: terminal.id,\n pid: terminal.pid,\n sessionWs: `/ws/session/${terminal.id}`,\n ws: `/ws/terminal/${terminal.id}`\n },\n { status: 201 }\n );\n } catch (error) {\n console.error(\"[terminals] Failed to create terminal:\", toErrorMessage(error));\n return json({ error: \"Failed to create terminal\" }, { status: 500 });\n }\n};\nexport {\n GET,\n POST\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_server.ts-CZb-BI5H.js","sources":["../../../.svelte-kit/adapter-node/entries/endpoints/api/terminals/_id_/share/_server.ts.js"],"sourcesContent":["import { v as validateAuth } from \"../../../../../../chunks/auth.js\";\nimport { p as ptyManager } from \"../../../../../../chunks/pty-manager.js\";\nimport { s as shareStore, h as hashPassword } from \"../../../../../../chunks/share-store.js\";\nimport { c as closeGuests } from \"../../../../../../chunks/guest-registry.js\";\nimport { json } from \"@sveltejs/kit\";\nconst MIN_PASSWORD_LENGTH = 6;\nconst MODES = [\"view\", \"control\"];\nfunction toInfo(terminalId) {\n const share = shareStore.getShare(terminalId);\n if (!share) {\n return { active: false, createdAt: null, mode: null, updatedAt: null };\n }\n return { active: true, createdAt: share.createdAt, mode: share.mode, updatedAt: share.updatedAt };\n}\nconst GET = ({ params, request }) => {\n const authError = validateAuth(request);\n if (authError) {\n return authError;\n }\n return json(toInfo(params.id));\n};\nconst PUT = async ({ params, request }) => {\n const authError = validateAuth(request);\n if (authError) {\n return authError;\n }\n if (!ptyManager.get(params.id)) {\n return json({ error: \"Terminal not found\" }, { status: 404 });\n }\n let body;\n try {\n body = await request.json();\n } catch {\n return json({ error: \"Invalid JSON\" }, { status: 400 });\n }\n if (!MODES.includes(body.mode)) {\n return json({ error: \"mode must be 'view' or 'control'\" }, { status: 400 });\n }\n const existing = shareStore.getShare(params.id);\n const password = typeof body.password === \"string\" ? body.password : \"\";\n if (!existing && password.length < MIN_PASSWORD_LENGTH) {\n return json(\n { error: `password is required (min ${String(MIN_PASSWORD_LENGTH)} chars)` },\n { status: 400 }\n );\n }\n if (password && password.length < MIN_PASSWORD_LENGTH) {\n return json(\n { error: `password must be at least ${String(MIN_PASSWORD_LENGTH)} chars` },\n { status: 400 }\n );\n }\n const now = Date.now();\n shareStore.setShare({\n createdAt: existing?.createdAt ?? now,\n mode: body.mode,\n // `existing` is guaranteed non-null when password is empty (validated above).\n passwordHash: password ? hashPassword(password) : existing?.passwordHash ?? \"\",\n terminalId: params.id,\n updatedAt: now\n });\n if (password) {\n shareStore.deleteSessions(params.id);\n }\n if (password || existing?.mode !== body.mode) {\n closeGuests(params.id);\n }\n return json(toInfo(params.id));\n};\nconst DELETE = ({ params, request }) => {\n const authError = validateAuth(request);\n if (authError) {\n return authError;\n }\n shareStore.deleteShare(params.id);\n const closed = closeGuests(params.id);\n return json({ closedConnections: closed, success: true });\n};\nexport {\n DELETE,\n GET,\n PUT\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAKA,MAAM,mBAAmB,GAAG,CAAC;AAC7B,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC;AACjC,SAAS,MAAM,CAAC,UAAU,EAAE;AAC5B,EAAE,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC;AAC/C,EAAE,IAAI,CAAC,KAAK,EAAE;AACd,IAAI,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE;AAC1E,EAAE;AACF,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE;AACnG;AACK,MAAC,GAAG,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK;AACrC,EAAE,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC;AACzC,EAAE,IAAI,SAAS,EAAE;AACjB,IAAI,OAAO,SAAS;AACpB,EAAE;AACF,EAAE,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAChC;AACK,MAAC,GAAG,GAAG,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK;AAC3C,EAAE,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC;AACzC,EAAE,IAAI,SAAS,EAAE;AACjB,IAAI,OAAO,SAAS;AACpB,EAAE;AACF,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;AAClC,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AACjE,EAAE;AACF,EAAE,IAAI,IAAI;AACV,EAAE,IAAI;AACN,IAAI,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE;AAC/B,EAAE,CAAC,CAAC,MAAM;AACV,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AAC3D,EAAE;AACF,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;AAClC,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,EAAE,kCAAkC,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AAC/E,EAAE;AACF,EAAE,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;AACjD,EAAE,MAAM,QAAQ,GAAG,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,GAAG,IAAI,CAAC,QAAQ,GAAG,EAAE;AACzE,EAAE,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,mBAAmB,EAAE;AAC1D,IAAI,OAAO,IAAI;AACf,MAAM,EAAE,KAAK,EAAE,CAAC,0BAA0B,EAAE,MAAM,CAAC,mBAAmB,CAAC,CAAC,OAAO,CAAC,EAAE;AAClF,MAAM,EAAE,MAAM,EAAE,GAAG;AACnB,KAAK;AACL,EAAE;AACF,EAAE,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,mBAAmB,EAAE;AACzD,IAAI,OAAO,IAAI;AACf,MAAM,EAAE,KAAK,EAAE,CAAC,0BAA0B,EAAE,MAAM,CAAC,mBAAmB,CAAC,CAAC,MAAM,CAAC,EAAE;AACjF,MAAM,EAAE,MAAM,EAAE,GAAG;AACnB,KAAK;AACL,EAAE;AACF,EAAE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;AACxB,EAAE,UAAU,CAAC,QAAQ,CAAC;AACtB,IAAI,SAAS,EAAE,QAAQ,EAAE,SAAS,IAAI,GAAG;AACzC,IAAI,IAAI,EAAE,IAAI,CAAC,IAAI;AACnB;AACA,IAAI,YAAY,EAAE,QAAQ,GAAG,YAAY,CAAC,QAAQ,CAAC,GAAG,QAAQ,EAAE,YAAY,IAAI,EAAE;AAClF,IAAI,UAAU,EAAE,MAAM,CAAC,EAAE;AACzB,IAAI,SAAS,EAAE;AACf,GAAG,CAAC;AACJ,EAAE,IAAI,QAAQ,EAAE;AAChB,IAAI,UAAU,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;AACxC,EAAE;AACF,EAAE,IAAI,QAAQ,IAAI,QAAQ,EAAE,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE;AAChD,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;AAC1B,EAAE;AACF,EAAE,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAChC;AACK,MAAC,MAAM,GAAG,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK;AACxC,EAAE,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC;AACzC,EAAE,IAAI,SAAS,EAAE;AACjB,IAAI,OAAO,SAAS;AACpB,EAAE;AACF,EAAE,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;AACnC,EAAE,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;AACvC,EAAE,OAAO,IAAI,CAAC,EAAE,iBAAiB,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC3D;;;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_server.ts-DiBMY7Ho.js","sources":["../../../.svelte-kit/adapter-node/entries/endpoints/api/terminals/_id_/resize/_server.ts.js"],"sourcesContent":["import { p as ptyManager } from \"../../../../../../chunks/pty-manager.js\";\nimport { r as resolveAccess } from \"../../../../../../chunks/share-auth.js\";\nimport { t as toErrorMessage } from \"../../../../../../chunks/error.js\";\nimport { json } from \"@sveltejs/kit\";\nconst POST = async ({ params, request }) => {\n const access = resolveAccess(request, params.id);\n if (!access) {\n return json({ error: \"Unauthorized\" }, { status: 401 });\n }\n if (access.level === \"guest\" && access.mode !== \"control\") {\n return json({ error: \"View-only access\" }, { status: 403 });\n }\n let body;\n try {\n body = await request.json();\n } catch {\n return json({ error: \"Invalid JSON in request body\" }, { status: 400 });\n }\n try {\n const { cols, rows } = body;\n if (cols === void 0 || rows === void 0) {\n return json({ error: \"cols and rows are required\" }, { status: 400 });\n }\n if (typeof cols !== \"number\" || cols < 1) {\n return json({ error: \"cols must be a positive number\" }, { status: 400 });\n }\n if (typeof rows !== \"number\" || rows < 1) {\n return json({ error: \"rows must be a positive number\" }, { status: 400 });\n }\n if (cols > 500 || rows > 200) {\n return json({ error: \"cols must be <= 500 and rows must be <= 200\" }, { status: 400 });\n }\n const terminal = ptyManager.get(params.id);\n if (!terminal) {\n return json({ error: \"Terminal not found\" }, { status: 404 });\n }\n if (terminal.status === \"exited\") {\n return json({ error: \"Terminal already exited\" }, { status: 409 });\n }\n ptyManager.resize(params.id, cols, rows);\n console.log(`[terminals] Resized terminal ${params.id} to ${cols}x${rows}`);\n return json({\n success: true,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n } catch (error) {\n console.error(\"[terminals] Failed to resize terminal:\", toErrorMessage(error));\n return json({ error: \"Failed to resize terminal\" }, { status: 500 });\n }\n};\nexport {\n POST\n};\n"],"names":[],"mappings":"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"}
|