agent-relay 11.5.0 → 11.5.2
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/cli/commands/local-agent.d.ts +11 -2
- package/dist/cli/commands/local-agent.d.ts.map +1 -1
- package/dist/cli/commands/local-agent.js +106 -1
- package/dist/cli/commands/local-agent.js.map +1 -1
- package/dist/cli/lib/attach-drive.d.ts +6 -0
- package/dist/cli/lib/attach-drive.d.ts.map +1 -1
- package/dist/cli/lib/attach-drive.js +3 -1
- package/dist/cli/lib/attach-drive.js.map +1 -1
- package/dist/cli/lib/attach-fleet-node.d.ts +31 -0
- package/dist/cli/lib/attach-fleet-node.d.ts.map +1 -0
- package/dist/cli/lib/attach-fleet-node.js +545 -0
- package/dist/cli/lib/attach-fleet-node.js.map +1 -0
- package/dist/cli/lib/attach-mode.d.ts +2 -0
- package/dist/cli/lib/attach-mode.d.ts.map +1 -0
- package/dist/cli/lib/attach-mode.js +2 -0
- package/dist/cli/lib/attach-mode.js.map +1 -0
- package/dist/cli/lib/attach-passthrough.d.ts +6 -0
- package/dist/cli/lib/attach-passthrough.d.ts.map +1 -1
- package/dist/cli/lib/attach-passthrough.js +3 -1
- package/dist/cli/lib/attach-passthrough.js.map +1 -1
- package/dist/cli/lib/attach-remote-node.d.ts +21 -0
- package/dist/cli/lib/attach-remote-node.d.ts.map +1 -0
- package/dist/cli/lib/attach-remote-node.js +133 -0
- package/dist/cli/lib/attach-remote-node.js.map +1 -0
- package/dist/cli/lib/attach-view.d.ts +6 -0
- package/dist/cli/lib/attach-view.d.ts.map +1 -1
- package/dist/cli/lib/attach-view.js +3 -1
- package/dist/cli/lib/attach-view.js.map +1 -1
- package/dist/cli/lib/attach.d.ts +19 -4
- package/dist/cli/lib/attach.d.ts.map +1 -1
- package/dist/cli/lib/attach.js +50 -3
- package/dist/cli/lib/attach.js.map +1 -1
- package/dist/cli/lib/fleet-hint.d.ts +49 -0
- package/dist/cli/lib/fleet-hint.d.ts.map +1 -0
- package/dist/cli/lib/fleet-hint.js +85 -0
- package/dist/cli/lib/fleet-hint.js.map +1 -0
- package/package.json +8 -8
|
@@ -0,0 +1,545 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ticketed fleet-node attach adapter.
|
|
3
|
+
*
|
|
4
|
+
* The established attach clients intentionally continue to speak the local
|
|
5
|
+
* broker HTTP/WebSocket contract. This short-lived loopback adapter maps that
|
|
6
|
+
* contract onto Relaycast's authenticated terminal session, so view/drive and
|
|
7
|
+
* passthrough retain their behaviour without exposing a remote broker listener
|
|
8
|
+
* or copying a broker API key off a physical or Daytona node.
|
|
9
|
+
*/
|
|
10
|
+
import { createServer } from 'node:http';
|
|
11
|
+
import { once } from 'node:events';
|
|
12
|
+
import { Buffer } from 'node:buffer';
|
|
13
|
+
import { randomBytes } from 'node:crypto';
|
|
14
|
+
import WebSocket, { WebSocketServer } from 'ws';
|
|
15
|
+
import { resolveBaseUrl, resolveWorkspaceKey } from './sdk-client.js';
|
|
16
|
+
const MAX_BUFFERED_BYTES = 1024 * 1024;
|
|
17
|
+
const SNAPSHOT_WAIT_MS = 10_000;
|
|
18
|
+
const INITIAL_RECONNECT_DELAY_MS = 500;
|
|
19
|
+
const MAX_RECONNECT_DELAY_MS = 30_000;
|
|
20
|
+
const MAX_RECONNECT_ATTEMPTS = 5;
|
|
21
|
+
export class FleetNodeAttachError extends Error {
|
|
22
|
+
code;
|
|
23
|
+
constructor(message, code) {
|
|
24
|
+
super(message);
|
|
25
|
+
this.code = code;
|
|
26
|
+
this.name = 'FleetNodeAttachError';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function json(response, status, payload) {
|
|
30
|
+
response.writeHead(status, { 'Content-Type': 'application/json', 'Cache-Control': 'no-store' });
|
|
31
|
+
response.end(JSON.stringify(payload));
|
|
32
|
+
}
|
|
33
|
+
function readBody(request) {
|
|
34
|
+
return new Promise((resolve) => {
|
|
35
|
+
let settled = false;
|
|
36
|
+
const finish = (body) => {
|
|
37
|
+
if (settled)
|
|
38
|
+
return;
|
|
39
|
+
settled = true;
|
|
40
|
+
resolve(body);
|
|
41
|
+
};
|
|
42
|
+
let body = '';
|
|
43
|
+
request.setEncoding('utf8');
|
|
44
|
+
request.on('data', (chunk) => {
|
|
45
|
+
body += chunk;
|
|
46
|
+
});
|
|
47
|
+
request.on('end', () => {
|
|
48
|
+
try {
|
|
49
|
+
const parsed = JSON.parse(body);
|
|
50
|
+
finish(parsed && typeof parsed === 'object' && !Array.isArray(parsed)
|
|
51
|
+
? parsed
|
|
52
|
+
: {});
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
finish({});
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
request.on('error', () => finish({}));
|
|
59
|
+
request.on('aborted', () => finish({}));
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function asWsUrl(value) {
|
|
63
|
+
return value.replace(/^http/i, 'ws');
|
|
64
|
+
}
|
|
65
|
+
function safeNodePath(node) {
|
|
66
|
+
const trimmed = node.trim().replace(/^#/, '');
|
|
67
|
+
if (!trimmed)
|
|
68
|
+
throw new FleetNodeAttachError('Error: --node requires a node name or id.', 'invalid_node');
|
|
69
|
+
return encodeURIComponent(trimmed);
|
|
70
|
+
}
|
|
71
|
+
function parseFrame(data) {
|
|
72
|
+
try {
|
|
73
|
+
const parsed = JSON.parse(rawDataToString(data));
|
|
74
|
+
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : null;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function rawDataToString(data) {
|
|
81
|
+
if (Buffer.isBuffer(data))
|
|
82
|
+
return data.toString('utf8');
|
|
83
|
+
if (data instanceof ArrayBuffer)
|
|
84
|
+
return Buffer.from(data).toString('utf8');
|
|
85
|
+
if (Array.isArray(data))
|
|
86
|
+
return Buffer.concat(data).toString('utf8');
|
|
87
|
+
return String(data);
|
|
88
|
+
}
|
|
89
|
+
/** Start a broker-compatible loopback proxy for one remote terminal session. */
|
|
90
|
+
export async function startFleetNodeAttachProxy(options) {
|
|
91
|
+
const env = options.env ?? process.env;
|
|
92
|
+
const fetchFn = options.fetch ?? globalThis.fetch;
|
|
93
|
+
const workspaceKey = options.workspaceKey ?? resolveWorkspaceKey({ env });
|
|
94
|
+
const baseUrl = (options.baseUrl ?? resolveBaseUrl({ env }) ?? 'https://cast.agentrelay.com').replace(/\/+$/, '');
|
|
95
|
+
const nodePath = safeNodePath(options.node);
|
|
96
|
+
const ticketResponse = await fetchFn(`${baseUrl}/v1/nodes/${nodePath}/terminal/sessions`, {
|
|
97
|
+
method: 'POST',
|
|
98
|
+
headers: { Authorization: `Bearer ${workspaceKey}`, 'Content-Type': 'application/json' },
|
|
99
|
+
body: JSON.stringify({ agent: options.agent, mode: options.mode }),
|
|
100
|
+
});
|
|
101
|
+
const ticketPayload = (await ticketResponse.json().catch(() => ({})));
|
|
102
|
+
const terminalUrl = ticketPayload.data?.terminal_url;
|
|
103
|
+
const sessionId = ticketPayload.data?.session_id;
|
|
104
|
+
const resumeToken = ticketPayload.data?.resume_token;
|
|
105
|
+
if (!ticketResponse.ok || !terminalUrl || !sessionId || !resumeToken) {
|
|
106
|
+
const code = ticketPayload.error?.code;
|
|
107
|
+
const message = ticketPayload.error?.message ?? `terminal session request failed (HTTP ${ticketResponse.status})`;
|
|
108
|
+
throw new FleetNodeAttachError(`Error: ${message}`, code);
|
|
109
|
+
}
|
|
110
|
+
let connectionGeneration = 0;
|
|
111
|
+
const createReadiness = () => {
|
|
112
|
+
let resolve;
|
|
113
|
+
let reject;
|
|
114
|
+
const promise = new Promise((resolvePromise, rejectPromise) => {
|
|
115
|
+
resolve = resolvePromise;
|
|
116
|
+
reject = rejectPromise;
|
|
117
|
+
});
|
|
118
|
+
// A failure can land before a snapshot request attaches its waiter. Keep
|
|
119
|
+
// the rejection observable while avoiding an unhandled-rejection warning.
|
|
120
|
+
void promise.catch(() => undefined);
|
|
121
|
+
return { generation: ++connectionGeneration, settled: false, promise, resolve, reject };
|
|
122
|
+
};
|
|
123
|
+
let activeReadiness = createReadiness();
|
|
124
|
+
const resolveReadiness = (readiness) => {
|
|
125
|
+
if (readiness.settled)
|
|
126
|
+
return;
|
|
127
|
+
readiness.settled = true;
|
|
128
|
+
readiness.resolve();
|
|
129
|
+
};
|
|
130
|
+
const rejectReadiness = (readiness, error) => {
|
|
131
|
+
if (readiness.settled)
|
|
132
|
+
return;
|
|
133
|
+
readiness.settled = true;
|
|
134
|
+
readiness.reject(error);
|
|
135
|
+
};
|
|
136
|
+
const waitForCurrentReadiness = async () => {
|
|
137
|
+
for (;;) {
|
|
138
|
+
const readiness = activeReadiness;
|
|
139
|
+
await readiness.promise;
|
|
140
|
+
if (readiness === activeReadiness)
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
const snapshot = {
|
|
145
|
+
screen: '',
|
|
146
|
+
rows: 24,
|
|
147
|
+
cols: 80,
|
|
148
|
+
offset: 0,
|
|
149
|
+
};
|
|
150
|
+
const eventSockets = new Set();
|
|
151
|
+
const inputSockets = new Set();
|
|
152
|
+
const outputHistory = [];
|
|
153
|
+
let outputHistoryBytes = 0;
|
|
154
|
+
let remote;
|
|
155
|
+
let stopped = false;
|
|
156
|
+
let terminalEnded = false;
|
|
157
|
+
let terminalEverReady = false;
|
|
158
|
+
let reconnecting = false;
|
|
159
|
+
let reconnectAttempts = 0;
|
|
160
|
+
let reconnectTimer;
|
|
161
|
+
const loopbackApiKey = randomBytes(32).toString('base64url');
|
|
162
|
+
const loopbackAuthorized = (headers) => headers.authorization === `Bearer ${loopbackApiKey}` || headers['x-api-key'] === loopbackApiKey;
|
|
163
|
+
const server = createServer(async (request, response) => {
|
|
164
|
+
if (!loopbackAuthorized(request.headers)) {
|
|
165
|
+
json(response, 401, {
|
|
166
|
+
error: { code: 'unauthorized', message: 'loopback terminal token is required' },
|
|
167
|
+
});
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const path = new URL(request.url ?? '/', 'http://127.0.0.1').pathname;
|
|
171
|
+
if (request.method === 'GET' && path === `/api/spawned/${encodeURIComponent(options.agent)}/snapshot`) {
|
|
172
|
+
try {
|
|
173
|
+
await new Promise((resolve, reject) => {
|
|
174
|
+
const timer = setTimeout(() => reject(new Error('terminal snapshot timed out')), SNAPSHOT_WAIT_MS);
|
|
175
|
+
void waitForCurrentReadiness().then(() => {
|
|
176
|
+
clearTimeout(timer);
|
|
177
|
+
resolve();
|
|
178
|
+
}, (error) => {
|
|
179
|
+
clearTimeout(timer);
|
|
180
|
+
reject(error);
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
const terminalError = error instanceof FleetNodeAttachError ? error : undefined;
|
|
186
|
+
const status = terminalError?.code === 'agent_not_found'
|
|
187
|
+
? 404
|
|
188
|
+
: terminalError?.code === 'unsupported_runtime'
|
|
189
|
+
? 409
|
|
190
|
+
: 503;
|
|
191
|
+
json(response, status, {
|
|
192
|
+
error: {
|
|
193
|
+
code: terminalError?.code ?? 'snapshot_unavailable',
|
|
194
|
+
message: terminalError?.message ?? (error instanceof Error ? error.message : 'snapshot unavailable'),
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
json(response, 200, { format: 'ansi', ...snapshot });
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
const name = encodeURIComponent(options.agent);
|
|
203
|
+
if (path === `/api/spawned/${name}/delivery-mode`) {
|
|
204
|
+
if (request.method === 'GET') {
|
|
205
|
+
json(response, 200, { mode: options.mode === 'drive' ? 'manual_flush' : 'auto_inject' });
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
await readBody(request);
|
|
209
|
+
json(response, 200, {
|
|
210
|
+
mode: options.mode === 'drive' ? 'manual_flush' : 'auto_inject',
|
|
211
|
+
flushed: 0,
|
|
212
|
+
matched: true,
|
|
213
|
+
revision: '1',
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
if (request.method === 'GET' && path === `/api/spawned/${name}/pending`) {
|
|
219
|
+
json(response, 200, { pending: [] });
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
if (request.method === 'POST' && path === `/api/spawned/${name}/flush`) {
|
|
223
|
+
json(response, 200, { flushed: 0 });
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
if (request.method === 'GET' && path === '/api/spawned') {
|
|
227
|
+
json(response, 200, { agents: [{ name: options.agent, workerPid: 1 }] });
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (request.method === 'POST' && path === `/api/resize/${name}`) {
|
|
231
|
+
const body = await readBody(request);
|
|
232
|
+
if (body.release === true) {
|
|
233
|
+
json(response, 200, { name: options.agent, released: true });
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
const rows = typeof body.rows === 'number' ? body.rows : 0;
|
|
237
|
+
const cols = typeof body.cols === 'number' ? body.cols : 0;
|
|
238
|
+
if (!Number.isInteger(rows) || !Number.isInteger(cols) || rows < 1 || cols < 1) {
|
|
239
|
+
json(response, 400, {
|
|
240
|
+
error: { code: 'invalid_dimensions', message: 'rows and cols must be positive integers' },
|
|
241
|
+
});
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
try {
|
|
245
|
+
await new Promise((resolve, reject) => {
|
|
246
|
+
const timer = setTimeout(() => reject(new Error('terminal resize timed out')), SNAPSHOT_WAIT_MS);
|
|
247
|
+
void waitForCurrentReadiness().then(() => {
|
|
248
|
+
clearTimeout(timer);
|
|
249
|
+
resolve();
|
|
250
|
+
}, (error) => {
|
|
251
|
+
clearTimeout(timer);
|
|
252
|
+
reject(error);
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
catch (error) {
|
|
257
|
+
json(response, 503, {
|
|
258
|
+
error: {
|
|
259
|
+
code: 'session_not_ready',
|
|
260
|
+
message: error instanceof Error ? error.message : 'terminal session is not ready',
|
|
261
|
+
},
|
|
262
|
+
});
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
if (!remote || remote.readyState !== WebSocket.OPEN || remote.bufferedAmount > MAX_BUFFERED_BYTES) {
|
|
266
|
+
json(response, 503, {
|
|
267
|
+
error: { code: 'node_unreachable', message: 'terminal transport is unavailable' },
|
|
268
|
+
});
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
remote.send(JSON.stringify({ type: 'terminal.resize', session_id: sessionId, rows, cols }));
|
|
272
|
+
json(response, 200, { name: options.agent, rows, cols, applied: true });
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
json(response, 404, { error: { code: 'not_found', message: 'loopback terminal endpoint not found' } });
|
|
276
|
+
});
|
|
277
|
+
const websocketServer = new WebSocketServer({ noServer: true });
|
|
278
|
+
const closeSocket = (socket, code, reason) => {
|
|
279
|
+
try {
|
|
280
|
+
socket.close(code, reason);
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
/* connection already gone */
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
const broadcast = (sockets, payload) => {
|
|
287
|
+
const encoded = JSON.stringify(payload);
|
|
288
|
+
let accepted = false;
|
|
289
|
+
for (const socket of sockets) {
|
|
290
|
+
if (socket.readyState !== WebSocket.OPEN)
|
|
291
|
+
continue;
|
|
292
|
+
if (socket.bufferedAmount > MAX_BUFFERED_BYTES) {
|
|
293
|
+
closeSocket(socket, 1013, 'loopback client backpressure exceeded');
|
|
294
|
+
sockets.delete(socket);
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
try {
|
|
298
|
+
socket.send(encoded);
|
|
299
|
+
accepted = true;
|
|
300
|
+
}
|
|
301
|
+
catch {
|
|
302
|
+
sockets.delete(socket);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return accepted;
|
|
306
|
+
};
|
|
307
|
+
const workerStreamEvent = (chunk, offset) => ({
|
|
308
|
+
kind: 'worker_stream',
|
|
309
|
+
name: options.agent,
|
|
310
|
+
stream: 'stdout',
|
|
311
|
+
chunk,
|
|
312
|
+
...(offset === undefined ? {} : { offset }),
|
|
313
|
+
});
|
|
314
|
+
const retainOutput = (chunk, offset) => {
|
|
315
|
+
const bytes = Buffer.byteLength(chunk, 'utf8');
|
|
316
|
+
if (outputHistoryBytes + bytes > MAX_BUFFERED_BYTES)
|
|
317
|
+
return false;
|
|
318
|
+
outputHistory.push({ chunk, ...(offset === undefined ? {} : { offset }) });
|
|
319
|
+
outputHistoryBytes += bytes;
|
|
320
|
+
return true;
|
|
321
|
+
};
|
|
322
|
+
websocketServer.on('connection', (socket, request) => {
|
|
323
|
+
const path = new URL(request.url ?? '/', 'http://127.0.0.1').pathname;
|
|
324
|
+
if (path === '/ws') {
|
|
325
|
+
eventSockets.add(socket);
|
|
326
|
+
socket.on('close', () => eventSockets.delete(socket));
|
|
327
|
+
let replayed = 0;
|
|
328
|
+
for (const event of outputHistory) {
|
|
329
|
+
if (socket.readyState !== WebSocket.OPEN || socket.bufferedAmount > MAX_BUFFERED_BYTES)
|
|
330
|
+
break;
|
|
331
|
+
try {
|
|
332
|
+
socket.send(JSON.stringify(workerStreamEvent(event.chunk, event.offset)));
|
|
333
|
+
}
|
|
334
|
+
catch {
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
337
|
+
replayed += 1;
|
|
338
|
+
}
|
|
339
|
+
if (replayed > 0) {
|
|
340
|
+
const sentBytes = outputHistory
|
|
341
|
+
.slice(0, replayed)
|
|
342
|
+
.reduce((total, event) => total + Buffer.byteLength(event.chunk, 'utf8'), 0);
|
|
343
|
+
outputHistory.splice(0, replayed);
|
|
344
|
+
outputHistoryBytes -= sentBytes;
|
|
345
|
+
}
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
if (path === `/api/input/${encodeURIComponent(options.agent)}/stream`) {
|
|
349
|
+
inputSockets.add(socket);
|
|
350
|
+
socket.on('close', () => inputSockets.delete(socket));
|
|
351
|
+
socket.send(JSON.stringify({ type: 'pty_input_ready', name: options.agent }));
|
|
352
|
+
socket.on('message', (data) => {
|
|
353
|
+
if (!remote || remote.readyState !== WebSocket.OPEN || remote.bufferedAmount > MAX_BUFFERED_BYTES) {
|
|
354
|
+
broadcast(inputSockets, {
|
|
355
|
+
type: 'pty_input_error',
|
|
356
|
+
code: 'node_unreachable',
|
|
357
|
+
message: 'terminal transport is unavailable',
|
|
358
|
+
});
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
const raw = rawDataToString(data);
|
|
362
|
+
remote.send(JSON.stringify({
|
|
363
|
+
type: 'terminal.input',
|
|
364
|
+
session_id: sessionId,
|
|
365
|
+
data_base64: Buffer.from(raw, 'utf8').toString('base64'),
|
|
366
|
+
}));
|
|
367
|
+
});
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
closeSocket(socket, 1008, 'unknown loopback endpoint');
|
|
371
|
+
});
|
|
372
|
+
server.on('upgrade', (request, socket, head) => {
|
|
373
|
+
if (!loopbackAuthorized(request.headers)) {
|
|
374
|
+
socket.write('HTTP/1.1 401 Unauthorized\r\nConnection: close\r\n\r\n');
|
|
375
|
+
socket.destroy();
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
websocketServer.handleUpgrade(request, socket, head, (client) => websocketServer.emit('connection', client, request));
|
|
379
|
+
});
|
|
380
|
+
server.listen(0, '127.0.0.1');
|
|
381
|
+
await once(server, 'listening');
|
|
382
|
+
const address = server.address();
|
|
383
|
+
if (!address || typeof address === 'string')
|
|
384
|
+
throw new FleetNodeAttachError('Error: could not allocate loopback terminal listener.', 'loopback_unavailable');
|
|
385
|
+
const resumeUrl = new URL(terminalUrl);
|
|
386
|
+
resumeUrl.searchParams.delete('ticket');
|
|
387
|
+
resumeUrl.searchParams.set('session_id', sessionId);
|
|
388
|
+
resumeUrl.searchParams.set('resume', resumeToken);
|
|
389
|
+
const endTerminal = (error) => {
|
|
390
|
+
if (terminalEnded)
|
|
391
|
+
return;
|
|
392
|
+
terminalEnded = true;
|
|
393
|
+
if (reconnectTimer) {
|
|
394
|
+
clearTimeout(reconnectTimer);
|
|
395
|
+
reconnectTimer = undefined;
|
|
396
|
+
}
|
|
397
|
+
const activeRemote = remote;
|
|
398
|
+
remote = undefined;
|
|
399
|
+
rejectReadiness(activeReadiness, error);
|
|
400
|
+
broadcast(inputSockets, { type: 'pty_input_error', code: error.code, message: error.message });
|
|
401
|
+
for (const socket of eventSockets)
|
|
402
|
+
closeSocket(socket, 1011, error.message);
|
|
403
|
+
if (activeRemote && activeRemote.readyState !== WebSocket.CLOSED) {
|
|
404
|
+
try {
|
|
405
|
+
activeRemote.terminate();
|
|
406
|
+
}
|
|
407
|
+
catch {
|
|
408
|
+
// The socket may have closed between the state check and terminate.
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
const failRemote = (message) => {
|
|
413
|
+
endTerminal(new FleetNodeAttachError(message, 'node_unreachable'));
|
|
414
|
+
};
|
|
415
|
+
const connect = (url, readiness) => {
|
|
416
|
+
if (stopped || terminalEnded)
|
|
417
|
+
return;
|
|
418
|
+
const socket = new WebSocket(asWsUrl(url));
|
|
419
|
+
remote = socket;
|
|
420
|
+
socket.on('message', (data) => {
|
|
421
|
+
// A late frame from a transport superseded during reconnect must never
|
|
422
|
+
// overwrite the fresh snapshot or end the replacement session.
|
|
423
|
+
if (remote !== socket || stopped || terminalEnded)
|
|
424
|
+
return;
|
|
425
|
+
const frame = parseFrame(data);
|
|
426
|
+
if (!frame || frame.session_id !== sessionId)
|
|
427
|
+
return;
|
|
428
|
+
if (frame.type === 'terminal.ready') {
|
|
429
|
+
snapshot.screen = typeof frame.screen === 'string' ? frame.screen : '';
|
|
430
|
+
snapshot.rows = typeof frame.rows === 'number' ? frame.rows : 24;
|
|
431
|
+
snapshot.cols = typeof frame.cols === 'number' ? frame.cols : 80;
|
|
432
|
+
snapshot.offset = typeof frame.offset === 'number' ? frame.offset : 0;
|
|
433
|
+
terminalEverReady = true;
|
|
434
|
+
reconnectAttempts = 0;
|
|
435
|
+
if (readiness === activeReadiness) {
|
|
436
|
+
resolveReadiness(readiness);
|
|
437
|
+
// A reconnect gets a fresh ANSI grid but existing local `/ws`
|
|
438
|
+
// consumers have already performed their initial HTTP snapshot.
|
|
439
|
+
// Re-emit this screen without an offset so they repaint instead of
|
|
440
|
+
// retaining a stale pre-reconnect terminal image.
|
|
441
|
+
if (readiness.generation > 1 && snapshot.screen) {
|
|
442
|
+
broadcast(eventSockets, workerStreamEvent(snapshot.screen));
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
else if (frame.type === 'terminal.output' && typeof frame.chunk === 'string') {
|
|
447
|
+
const offset = typeof frame.offset === 'number' ? frame.offset : undefined;
|
|
448
|
+
if (!broadcast(eventSockets, workerStreamEvent(frame.chunk, offset))) {
|
|
449
|
+
if (!retainOutput(frame.chunk, offset)) {
|
|
450
|
+
endTerminal(new FleetNodeAttachError('terminal output exceeded the bounded loopback buffer', 'output_backpressure'));
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
else if (frame.type === 'terminal.input_ack') {
|
|
455
|
+
broadcast(inputSockets, {
|
|
456
|
+
type: 'pty_input_ack',
|
|
457
|
+
name: options.agent,
|
|
458
|
+
bytes_written: typeof frame.bytes_written === 'number' ? frame.bytes_written : 0,
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
else if (frame.type === 'terminal.error') {
|
|
462
|
+
const message = typeof frame.message === 'string' ? frame.message : 'remote terminal failed';
|
|
463
|
+
const code = typeof frame.code === 'string' ? frame.code : 'terminal_error';
|
|
464
|
+
if (readiness === activeReadiness && !readiness.settled) {
|
|
465
|
+
endTerminal(new FleetNodeAttachError(message, code));
|
|
466
|
+
}
|
|
467
|
+
else {
|
|
468
|
+
broadcast(inputSockets, { type: 'pty_input_error', code, message });
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
else if (frame.type === 'terminal.closed') {
|
|
472
|
+
endTerminal(new FleetNodeAttachError('remote terminal session closed', 'terminal_closed'));
|
|
473
|
+
}
|
|
474
|
+
});
|
|
475
|
+
socket.on('error', () => {
|
|
476
|
+
// Initial connection failure has no terminal state worth preserving.
|
|
477
|
+
// Fail promptly with the canonical unavailable-node error instead of
|
|
478
|
+
// letting the HTTP snapshot timeout mask it. Once Ready has been seen,
|
|
479
|
+
// the close handler retains the bounded resume/backoff behaviour.
|
|
480
|
+
if (remote === socket && readiness === activeReadiness && !readiness.settled && !terminalEverReady) {
|
|
481
|
+
failRemote('terminal transport could not connect to the fleet node');
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
socket.on('close', () => {
|
|
485
|
+
if (remote !== socket || stopped || terminalEnded || reconnecting)
|
|
486
|
+
return;
|
|
487
|
+
// Any waiter that observed the prior connection must retry against the
|
|
488
|
+
// fresh generation instead of receiving its stale resolved snapshot.
|
|
489
|
+
resolveReadiness(readiness);
|
|
490
|
+
const nextReadiness = createReadiness();
|
|
491
|
+
activeReadiness = nextReadiness;
|
|
492
|
+
if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
|
|
493
|
+
failRemote('terminal transport could not reconnect to the fleet node');
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
reconnecting = true;
|
|
497
|
+
const delay = Math.min(INITIAL_RECONNECT_DELAY_MS * 2 ** reconnectAttempts, MAX_RECONNECT_DELAY_MS);
|
|
498
|
+
reconnectAttempts += 1;
|
|
499
|
+
reconnectTimer = setTimeout(() => {
|
|
500
|
+
reconnectTimer = undefined;
|
|
501
|
+
reconnecting = false;
|
|
502
|
+
connect(resumeUrl.toString(), nextReadiness);
|
|
503
|
+
}, delay);
|
|
504
|
+
});
|
|
505
|
+
};
|
|
506
|
+
connect(terminalUrl, activeReadiness);
|
|
507
|
+
return {
|
|
508
|
+
brokerUrl: `http://127.0.0.1:${address.port}`,
|
|
509
|
+
apiKey: loopbackApiKey,
|
|
510
|
+
async close() {
|
|
511
|
+
if (stopped)
|
|
512
|
+
return;
|
|
513
|
+
stopped = true;
|
|
514
|
+
terminalEnded = true;
|
|
515
|
+
if (reconnectTimer) {
|
|
516
|
+
clearTimeout(reconnectTimer);
|
|
517
|
+
reconnectTimer = undefined;
|
|
518
|
+
}
|
|
519
|
+
rejectReadiness(activeReadiness, new FleetNodeAttachError('terminal attach closed', 'closed'));
|
|
520
|
+
const activeRemote = remote;
|
|
521
|
+
remote = undefined;
|
|
522
|
+
if (activeRemote && activeRemote.readyState === WebSocket.OPEN) {
|
|
523
|
+
try {
|
|
524
|
+
activeRemote.send(JSON.stringify({ type: 'terminal.close', session_id: sessionId }));
|
|
525
|
+
}
|
|
526
|
+
catch {
|
|
527
|
+
// Best effort; terminate below still prevents a late reconnect.
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
if (activeRemote && activeRemote.readyState !== WebSocket.CLOSED) {
|
|
531
|
+
try {
|
|
532
|
+
activeRemote.terminate();
|
|
533
|
+
}
|
|
534
|
+
catch {
|
|
535
|
+
// Socket is already gone.
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
for (const socket of [...eventSockets, ...inputSockets])
|
|
539
|
+
closeSocket(socket, 1000, 'terminal attach closed');
|
|
540
|
+
websocketServer.close();
|
|
541
|
+
await new Promise((resolve) => server.close(() => resolve()));
|
|
542
|
+
},
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
//# sourceMappingURL=attach-fleet-node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attach-fleet-node.js","sourceRoot":"","sources":["../../../src/cli/lib/attach-fleet-node.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAA6C,MAAM,WAAW,CAAC;AACpF,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,SAAS,EAAE,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAGhD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtE,MAAM,kBAAkB,GAAG,IAAI,GAAG,IAAI,CAAC;AACvC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAChC,MAAM,0BAA0B,GAAG,GAAG,CAAC;AACvC,MAAM,sBAAsB,GAAG,MAAM,CAAC;AACtC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAsCjC,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAGlC;IAFX,YACE,OAAe,EACN,IAAa;QAEtB,KAAK,CAAC,OAAO,CAAC,CAAC;QAFN,SAAI,GAAJ,IAAI,CAAS;QAGtB,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,SAAS,IAAI,CAAC,QAAwB,EAAE,MAAc,EAAE,OAAgB;IACtE,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,eAAe,EAAE,UAAU,EAAE,CAAC,CAAC;IAChG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,SAAS,QAAQ,CAAC,OAAwB;IACxC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,MAAM,MAAM,GAAG,CAAC,IAA6B,EAAE,EAAE;YAC/C,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,CAAC;QACF,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC5B,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACnC,IAAI,IAAI,KAAK,CAAC;QAChB,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACrB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAY,CAAC;gBAC3C,MAAM,CACJ,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;oBAC5D,CAAC,CAAE,MAAkC;oBACrC,CAAC,CAAC,EAAE,CACP,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,CAAC,EAAE,CAAC,CAAC;YACb,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QACtC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,OAAO,CAAC,KAAa;IAC5B,OAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,YAAY,CAAC,IAAY;IAChC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC9C,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,oBAAoB,CAAC,2CAA2C,EAAE,cAAc,CAAC,CAAC;IAC1G,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,UAAU,CAAC,IAAuB;IACzC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAY,CAAC;QAC5D,OAAO,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,MAAwB,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3G,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,IAAuB;IAC9C,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACxD,IAAI,IAAI,YAAY,WAAW;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3E,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACrE,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;AACtB,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,OAA+B;IAE/B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACvC,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC;IAClD,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,mBAAmB,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;IAC1E,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,cAAc,CAAC,EAAE,GAAG,EAAE,CAAC,IAAI,6BAA6B,CAAC,CAAC,OAAO,CACnG,MAAM,EACN,EAAE,CACH,CAAC;IACF,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,GAAG,OAAO,aAAa,QAAQ,oBAAoB,EAAE;QACxF,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,YAAY,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QACxF,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;KACnE,CAAC,CAAC;IACH,MAAM,aAAa,GAAG,CAAC,MAAM,cAAc,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAyB,CAAC;IAC9F,MAAM,WAAW,GAAG,aAAa,CAAC,IAAI,EAAE,YAAY,CAAC;IACrD,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC;IACjD,MAAM,WAAW,GAAG,aAAa,CAAC,IAAI,EAAE,YAAY,CAAC;IACrD,IAAI,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC,WAAW,IAAI,CAAC,SAAS,IAAI,CAAC,WAAW,EAAE,CAAC;QACrE,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC;QACvC,MAAM,OAAO,GACX,aAAa,CAAC,KAAK,EAAE,OAAO,IAAI,yCAAyC,cAAc,CAAC,MAAM,GAAG,CAAC;QACpG,MAAM,IAAI,oBAAoB,CAAC,UAAU,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,oBAAoB,GAAG,CAAC,CAAC;IAC7B,MAAM,eAAe,GAAG,GAAsB,EAAE;QAC9C,IAAI,OAAoB,CAAC;QACzB,IAAI,MAA+B,CAAC;QACpC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAO,CAAC,cAAc,EAAE,aAAa,EAAE,EAAE;YAClE,OAAO,GAAG,cAAc,CAAC;YACzB,MAAM,GAAG,aAAa,CAAC;QACzB,CAAC,CAAC,CAAC;QACH,yEAAyE;QACzE,0EAA0E;QAC1E,KAAK,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACpC,OAAO,EAAE,UAAU,EAAE,EAAE,oBAAoB,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAC1F,CAAC,CAAC;IACF,IAAI,eAAe,GAAG,eAAe,EAAE,CAAC;IACxC,MAAM,gBAAgB,GAAG,CAAC,SAA4B,EAAE,EAAE;QACxD,IAAI,SAAS,CAAC,OAAO;YAAE,OAAO;QAC9B,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC;QACzB,SAAS,CAAC,OAAO,EAAE,CAAC;IACtB,CAAC,CAAC;IACF,MAAM,eAAe,GAAG,CAAC,SAA4B,EAAE,KAAY,EAAE,EAAE;QACrE,IAAI,SAAS,CAAC,OAAO;YAAE,OAAO;QAC9B,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC;QACzB,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC,CAAC;IACF,MAAM,uBAAuB,GAAG,KAAK,IAAmB,EAAE;QACxD,SAAS,CAAC;YACR,MAAM,SAAS,GAAG,eAAe,CAAC;YAClC,MAAM,SAAS,CAAC,OAAO,CAAC;YACxB,IAAI,SAAS,KAAK,eAAe;gBAAE,OAAO;QAC5C,CAAC;IACH,CAAC,CAAC;IACF,MAAM,QAAQ,GAAmE;QAC/E,MAAM,EAAE,EAAE;QACV,IAAI,EAAE,EAAE;QACR,IAAI,EAAE,EAAE;QACR,MAAM,EAAE,CAAC;KACV,CAAC;IACF,MAAM,YAAY,GAAG,IAAI,GAAG,EAAa,CAAC;IAC1C,MAAM,YAAY,GAAG,IAAI,GAAG,EAAa,CAAC;IAC1C,MAAM,aAAa,GAA8C,EAAE,CAAC;IACpE,IAAI,kBAAkB,GAAG,CAAC,CAAC;IAC3B,IAAI,MAA6B,CAAC;IAClC,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,IAAI,iBAAiB,GAAG,KAAK,CAAC;IAC9B,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,IAAI,iBAAiB,GAAG,CAAC,CAAC;IAC1B,IAAI,cAAyD,CAAC;IAC9D,MAAM,cAAc,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC7D,MAAM,kBAAkB,GAAG,CAAC,OAAmC,EAAE,EAAE,CACjE,OAAO,CAAC,aAAa,KAAK,UAAU,cAAc,EAAE,IAAI,OAAO,CAAC,WAAW,CAAC,KAAK,cAAc,CAAC;IAElG,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;QACtD,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACzC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE;gBAClB,KAAK,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,qCAAqC,EAAE;aAChF,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,EAAE,kBAAkB,CAAC,CAAC,QAAQ,CAAC;QACtE,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,IAAI,KAAK,gBAAgB,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACtG,IAAI,CAAC;gBACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;oBAC1C,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;oBACnG,KAAK,uBAAuB,EAAE,CAAC,IAAI,CACjC,GAAG,EAAE;wBACH,YAAY,CAAC,KAAK,CAAC,CAAC;wBACpB,OAAO,EAAE,CAAC;oBACZ,CAAC,EACD,CAAC,KAAY,EAAE,EAAE;wBACf,YAAY,CAAC,KAAK,CAAC,CAAC;wBACpB,MAAM,CAAC,KAAK,CAAC,CAAC;oBAChB,CAAC,CACF,CAAC;gBACJ,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,aAAa,GAAG,KAAK,YAAY,oBAAoB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;gBAChF,MAAM,MAAM,GACV,aAAa,EAAE,IAAI,KAAK,iBAAiB;oBACvC,CAAC,CAAC,GAAG;oBACL,CAAC,CAAC,aAAa,EAAE,IAAI,KAAK,qBAAqB;wBAC7C,CAAC,CAAC,GAAG;wBACL,CAAC,CAAC,GAAG,CAAC;gBACZ,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE;oBACrB,KAAK,EAAE;wBACL,IAAI,EAAE,aAAa,EAAE,IAAI,IAAI,sBAAsB;wBACnD,OAAO,EACL,aAAa,EAAE,OAAO,IAAI,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,sBAAsB,CAAC;qBAC9F;iBACF,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YACD,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,IAAI,KAAK,gBAAgB,IAAI,gBAAgB,EAAE,CAAC;YAClD,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;gBAC7B,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC;YAC3F,CAAC;iBAAM,CAAC;gBACN,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;gBACxB,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE;oBAClB,IAAI,EAAE,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa;oBAC/D,OAAO,EAAE,CAAC;oBACV,OAAO,EAAE,IAAI;oBACb,QAAQ,EAAE,GAAG;iBACd,CAAC,CAAC;YACL,CAAC;YACD,OAAO;QACT,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,IAAI,KAAK,gBAAgB,IAAI,UAAU,EAAE,CAAC;YACxE,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;YACrC,OAAO;QACT,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,KAAK,gBAAgB,IAAI,QAAQ,EAAE,CAAC;YACvE,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;YACpC,OAAO;QACT,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;YACxD,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACzE,OAAO;QACT,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,KAAK,eAAe,IAAI,EAAE,EAAE,CAAC;YAChE,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;YACrC,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;gBAC1B,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC7D,OAAO;YACT,CAAC;YACD,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3D,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3D,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;gBAC/E,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE;oBAClB,KAAK,EAAE,EAAE,IAAI,EAAE,oBAAoB,EAAE,OAAO,EAAE,yCAAyC,EAAE;iBAC1F,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;oBAC1C,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;oBACjG,KAAK,uBAAuB,EAAE,CAAC,IAAI,CACjC,GAAG,EAAE;wBACH,YAAY,CAAC,KAAK,CAAC,CAAC;wBACpB,OAAO,EAAE,CAAC;oBACZ,CAAC,EACD,CAAC,KAAY,EAAE,EAAE;wBACf,YAAY,CAAC,KAAK,CAAC,CAAC;wBACpB,MAAM,CAAC,KAAK,CAAC,CAAC;oBAChB,CAAC,CACF,CAAC;gBACJ,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE;oBAClB,KAAK,EAAE;wBACL,IAAI,EAAE,mBAAmB;wBACzB,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,+BAA+B;qBAClF;iBACF,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YACD,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,IAAI,MAAM,CAAC,cAAc,GAAG,kBAAkB,EAAE,CAAC;gBAClG,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE;oBAClB,KAAK,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,mCAAmC,EAAE;iBAClF,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC5F,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACxE,OAAO;QACT,CAAC;QACD,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,sCAAsC,EAAE,EAAE,CAAC,CAAC;IACzG,CAAC,CAAC,CAAC;IACH,MAAM,eAAe,GAAG,IAAI,eAAe,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAEhE,MAAM,WAAW,GAAG,CAAC,MAAiB,EAAE,IAAY,EAAE,MAAc,EAAE,EAAE;QACtE,IAAI,CAAC;YACH,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,6BAA6B;QAC/B,CAAC;IACH,CAAC,CAAC;IACF,MAAM,SAAS,GAAG,CAAC,OAAuB,EAAE,OAAgB,EAAW,EAAE;QACvE,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI;gBAAE,SAAS;YACnD,IAAI,MAAM,CAAC,cAAc,GAAG,kBAAkB,EAAE,CAAC;gBAC/C,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,uCAAuC,CAAC,CAAC;gBACnE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBACvB,SAAS;YACX,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACrB,QAAQ,GAAG,IAAI,CAAC;YAClB,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACzB,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;IACF,MAAM,iBAAiB,GAAG,CAAC,KAAa,EAAE,MAAe,EAAE,EAAE,CAAC,CAAC;QAC7D,IAAI,EAAE,eAAe;QACrB,IAAI,EAAE,OAAO,CAAC,KAAK;QACnB,MAAM,EAAE,QAAQ;QAChB,KAAK;QACL,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;KAC5C,CAAC,CAAC;IACH,MAAM,YAAY,GAAG,CAAC,KAAa,EAAE,MAA0B,EAAW,EAAE;QAC1E,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC/C,IAAI,kBAAkB,GAAG,KAAK,GAAG,kBAAkB;YAAE,OAAO,KAAK,CAAC;QAClE,aAAa,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAC3E,kBAAkB,IAAI,KAAK,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;QACnD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,EAAE,kBAAkB,CAAC,CAAC,QAAQ,CAAC;QACtE,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YACnB,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACzB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;YACtD,IAAI,QAAQ,GAAG,CAAC,CAAC;YACjB,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;gBAClC,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,IAAI,MAAM,CAAC,cAAc,GAAG,kBAAkB;oBAAE,MAAM;gBAC9F,IAAI,CAAC;oBACH,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC5E,CAAC;gBAAC,MAAM,CAAC;oBACP,MAAM;gBACR,CAAC;gBACD,QAAQ,IAAI,CAAC,CAAC;YAChB,CAAC;YACD,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;gBACjB,MAAM,SAAS,GAAG,aAAa;qBAC5B,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC;qBAClB,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC/E,aAAa,CAAC,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;gBAClC,kBAAkB,IAAI,SAAS,CAAC;YAClC,CAAC;YACD,OAAO;QACT,CAAC;QACD,IAAI,IAAI,KAAK,cAAc,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;YACtE,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACzB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;YACtD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YAC9E,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC5B,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,IAAI,MAAM,CAAC,cAAc,GAAG,kBAAkB,EAAE,CAAC;oBAClG,SAAS,CAAC,YAAY,EAAE;wBACtB,IAAI,EAAE,iBAAiB;wBACvB,IAAI,EAAE,kBAAkB;wBACxB,OAAO,EAAE,mCAAmC;qBAC7C,CAAC,CAAC;oBACH,OAAO;gBACT,CAAC;gBACD,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;gBAClC,MAAM,CAAC,IAAI,CACT,IAAI,CAAC,SAAS,CAAC;oBACb,IAAI,EAAE,gBAAgB;oBACtB,UAAU,EAAE,SAAS;oBACrB,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;iBACzD,CAAC,CACH,CAAC;YACJ,CAAC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,2BAA2B,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;QAC7C,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACzC,MAAM,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;YACvE,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QACD,eAAe,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAC9D,eAAe,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,CACpD,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;IAC9B,MAAM,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAChC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;IACjC,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ;QACzC,MAAM,IAAI,oBAAoB,CAC5B,uDAAuD,EACvD,sBAAsB,CACvB,CAAC;IAEJ,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;IACvC,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACxC,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IACpD,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAClD,MAAM,WAAW,GAAG,CAAC,KAA2B,EAAE,EAAE;QAClD,IAAI,aAAa;YAAE,OAAO;QAC1B,aAAa,GAAG,IAAI,CAAC;QACrB,IAAI,cAAc,EAAE,CAAC;YACnB,YAAY,CAAC,cAAc,CAAC,CAAC;YAC7B,cAAc,GAAG,SAAS,CAAC;QAC7B,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,CAAC;QAC5B,MAAM,GAAG,SAAS,CAAC;QACnB,eAAe,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QACxC,SAAS,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/F,KAAK,MAAM,MAAM,IAAI,YAAY;YAAE,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5E,IAAI,YAAY,IAAI,YAAY,CAAC,UAAU,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC;YACjE,IAAI,CAAC;gBACH,YAAY,CAAC,SAAS,EAAE,CAAC;YAC3B,CAAC;YAAC,MAAM,CAAC;gBACP,oEAAoE;YACtE,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IACF,MAAM,UAAU,GAAG,CAAC,OAAe,EAAE,EAAE;QACrC,WAAW,CAAC,IAAI,oBAAoB,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC;IACF,MAAM,OAAO,GAAG,CAAC,GAAW,EAAE,SAA4B,EAAE,EAAE;QAC5D,IAAI,OAAO,IAAI,aAAa;YAAE,OAAO;QACrC,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3C,MAAM,GAAG,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE;YAC5B,uEAAuE;YACvE,+DAA+D;YAC/D,IAAI,MAAM,KAAK,MAAM,IAAI,OAAO,IAAI,aAAa;gBAAE,OAAO;YAC1D,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;YAC/B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS;gBAAE,OAAO;YACrD,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;gBACpC,QAAQ,CAAC,MAAM,GAAG,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvE,QAAQ,CAAC,IAAI,GAAG,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjE,QAAQ,CAAC,IAAI,GAAG,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjE,QAAQ,CAAC,MAAM,GAAG,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtE,iBAAiB,GAAG,IAAI,CAAC;gBACzB,iBAAiB,GAAG,CAAC,CAAC;gBACtB,IAAI,SAAS,KAAK,eAAe,EAAE,CAAC;oBAClC,gBAAgB,CAAC,SAAS,CAAC,CAAC;oBAC5B,8DAA8D;oBAC9D,gEAAgE;oBAChE,mEAAmE;oBACnE,kDAAkD;oBAClD,IAAI,SAAS,CAAC,UAAU,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;wBAChD,SAAS,CAAC,YAAY,EAAE,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;oBAC9D,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC/E,MAAM,MAAM,GAAG,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;gBAC3E,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,iBAAiB,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC;oBACrE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;wBACvC,WAAW,CACT,IAAI,oBAAoB,CACtB,sDAAsD,EACtD,qBAAqB,CACtB,CACF,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;gBAC/C,SAAS,CAAC,YAAY,EAAE;oBACtB,IAAI,EAAE,eAAe;oBACrB,IAAI,EAAE,OAAO,CAAC,KAAK;oBACnB,aAAa,EAAE,OAAO,KAAK,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;iBACjF,CAAC,CAAC;YACL,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;gBAC3C,MAAM,OAAO,GAAG,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC;gBAC7F,MAAM,IAAI,GAAG,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC;gBAC5E,IAAI,SAAS,KAAK,eAAe,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;oBACxD,WAAW,CAAC,IAAI,oBAAoB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;gBACvD,CAAC;qBAAM,CAAC;oBACN,SAAS,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;gBACtE,CAAC;YACH,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;gBAC5C,WAAW,CAAC,IAAI,oBAAoB,CAAC,gCAAgC,EAAE,iBAAiB,CAAC,CAAC,CAAC;YAC7F,CAAC;QACH,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACtB,qEAAqE;YACrE,qEAAqE;YACrE,uEAAuE;YACvE,kEAAkE;YAClE,IAAI,MAAM,KAAK,MAAM,IAAI,SAAS,KAAK,eAAe,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBACnG,UAAU,CAAC,wDAAwD,CAAC,CAAC;YACvE,CAAC;QACH,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACtB,IAAI,MAAM,KAAK,MAAM,IAAI,OAAO,IAAI,aAAa,IAAI,YAAY;gBAAE,OAAO;YAC1E,uEAAuE;YACvE,qEAAqE;YACrE,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAC5B,MAAM,aAAa,GAAG,eAAe,EAAE,CAAC;YACxC,eAAe,GAAG,aAAa,CAAC;YAChC,IAAI,iBAAiB,IAAI,sBAAsB,EAAE,CAAC;gBAChD,UAAU,CAAC,0DAA0D,CAAC,CAAC;gBACvE,OAAO;YACT,CAAC;YACD,YAAY,GAAG,IAAI,CAAC;YACpB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,0BAA0B,GAAG,CAAC,IAAI,iBAAiB,EAAE,sBAAsB,CAAC,CAAC;YACpG,iBAAiB,IAAI,CAAC,CAAC;YACvB,cAAc,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC/B,cAAc,GAAG,SAAS,CAAC;gBAC3B,YAAY,GAAG,KAAK,CAAC;gBACrB,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,aAAa,CAAC,CAAC;YAC/C,CAAC,EAAE,KAAK,CAAC,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IACF,OAAO,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;IAEtC,OAAO;QACL,SAAS,EAAE,oBAAoB,OAAO,CAAC,IAAI,EAAE;QAC7C,MAAM,EAAE,cAAc;QACtB,KAAK,CAAC,KAAK;YACT,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,aAAa,GAAG,IAAI,CAAC;YACrB,IAAI,cAAc,EAAE,CAAC;gBACnB,YAAY,CAAC,cAAc,CAAC,CAAC;gBAC7B,cAAc,GAAG,SAAS,CAAC;YAC7B,CAAC;YACD,eAAe,CAAC,eAAe,EAAE,IAAI,oBAAoB,CAAC,wBAAwB,EAAE,QAAQ,CAAC,CAAC,CAAC;YAC/F,MAAM,YAAY,GAAG,MAAM,CAAC;YAC5B,MAAM,GAAG,SAAS,CAAC;YACnB,IAAI,YAAY,IAAI,YAAY,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;gBAC/D,IAAI,CAAC;oBACH,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;gBACvF,CAAC;gBAAC,MAAM,CAAC;oBACP,gEAAgE;gBAClE,CAAC;YACH,CAAC;YACD,IAAI,YAAY,IAAI,YAAY,CAAC,UAAU,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC;gBACjE,IAAI,CAAC;oBACH,YAAY,CAAC,SAAS,EAAE,CAAC;gBAC3B,CAAC;gBAAC,MAAM,CAAC;oBACP,0BAA0B;gBAC5B,CAAC;YACH,CAAC;YACD,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,YAAY,EAAE,GAAG,YAAY,CAAC;gBACrD,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,wBAAwB,CAAC,CAAC;YACtD,eAAe,CAAC,KAAK,EAAE,CAAC;YACxB,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACtE,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attach-mode.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/attach-mode.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,MAAM,GAAG,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attach-mode.js","sourceRoot":"","sources":["../../../src/cli/lib/attach-mode.ts"],"names":[],"mappings":""}
|
|
@@ -78,6 +78,12 @@ export interface PassthroughDependencies {
|
|
|
78
78
|
exit: ExitFn;
|
|
79
79
|
fetch: typeof globalThis.fetch;
|
|
80
80
|
captureAndRenderSnapshot: (connection: AttachSnapshotConnection, name: string, deps: AttachSnapshotDeps) => ReturnType<typeof captureAndRenderSnapshot>;
|
|
81
|
+
/**
|
|
82
|
+
* Best-effort workspace lookup for improving cross-node 404 messages.
|
|
83
|
+
* Defaults to `resolveFleetHint` from `fleet-hint.ts`. Tests inject a stub
|
|
84
|
+
* to avoid network calls.
|
|
85
|
+
*/
|
|
86
|
+
fleetHint?: (name: string) => Promise<string | null>;
|
|
81
87
|
stdin: PassthroughStdin;
|
|
82
88
|
terminal: PassthroughTerminal;
|
|
83
89
|
/** Opens the SDK PTY input stream used for raw human keystrokes. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attach-passthrough.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/attach-passthrough.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC,OAAO,SAAS,MAAM,IAAI,CAAC;AAE3B,OAAO,EACL,wBAAwB,EAiBxB,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACxB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"attach-passthrough.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/attach-passthrough.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC,OAAO,SAAS,MAAM,IAAI,CAAC;AAE3B,OAAO,EACL,wBAAwB,EAiBxB,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACxB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,6BAA6B,CAAC;AAQrC,OAAO,EACL,KAAK,iBAAiB,EAKtB,KAAK,mBAAmB,EACzB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAwB,KAAK,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AACrG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,KAAK,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC;AAEtC,wEAAwE;AACxE,MAAM,WAAW,oBAAoB;IACnC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;IACjD,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC;IAC3E,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC;IAC9E,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC;IAC5D,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7C;AAED,MAAM,MAAM,2BAA2B,GAAG,CACxC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC5B,oBAAoB,CAAC;AAE1B,MAAM,WAAW,0BAA0B;IACzC,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;CACpF;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC;IACxC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,IAAI,OAAO,CAAC;IAClB,KAAK,IAAI,OAAO,CAAC;IACjB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC;IAC9D,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC;IAChE,cAAc,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC;CAC5E;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,uBAAuB;IACtC,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAClD,kBAAkB,EAAE,MAAM,MAAM,CAAC;IACjC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,eAAe,EAAE,2BAA2B,CAAC;IAC7C,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,QAAQ,EAAE,0BAA0B,CAAC;IACrC,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAClC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAC/B,wBAAwB,EAAE,CACxB,UAAU,EAAE,wBAAwB,EACpC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,kBAAkB,KACrB,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAC;IACjD;;;;OAIG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACrD,KAAK,EAAE,gBAAgB,CAAC;IACxB,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,oEAAoE;IACpE,eAAe,EAAE,CAAC,UAAU,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,KAAK,iBAAiB,CAAC;IACnF;;;OAGG;IACH,oBAAoB,CAAC,EAAE,CAAC,IAAI,EAAE,2BAA2B,KAAK,cAAc,GAAG,IAAI,CAAC;IACpF;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,4EAA4E;IAC5E,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;;;OAIG;IACH,iBAAiB,EAAE,CAAC,UAAU,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC3F;AAoDD;;;mEAGmE;AACnE,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAEtB;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAgBpF;AAED,wCAAwC;AAExC,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,wBAAwB,EAAE,CAAC;CACrC;AAED,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;AAEhD;;;;;;GAMG;AACH,qBAAa,wBAAwB;IACnC,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,yBAAyB;IAe9C,KAAK,IAAI,IAAI;CACd;AAED,wCAAwC;AAExC;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,mBAAmB,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GAAG,MAAM,CAWT;AAED,sCAAsC;AAEtC;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EACnE,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAmoBjB;AAED,8GAA8G;AAC9G,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EACnE,SAAS,GAAE,OAAO,CAAC,uBAAuB,CAAM,GAC/C,OAAO,CAAC,MAAM,CAAC,CAEjB"}
|