x-shell.js 1.0.0 → 1.1.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +292 -2
  3. package/dist/client/browser-bundle.js +197 -3
  4. package/dist/client/browser-bundle.js.map +2 -2
  5. package/dist/client/index.d.ts +1 -1
  6. package/dist/client/index.d.ts.map +1 -1
  7. package/dist/client/terminal-client.d.ts +59 -3
  8. package/dist/client/terminal-client.d.ts.map +1 -1
  9. package/dist/client/terminal-client.js +194 -4
  10. package/dist/client/terminal-client.js.map +1 -1
  11. package/dist/server/circular-buffer.d.ts +55 -0
  12. package/dist/server/circular-buffer.d.ts.map +1 -0
  13. package/dist/server/circular-buffer.js +91 -0
  14. package/dist/server/circular-buffer.js.map +1 -0
  15. package/dist/server/index.d.ts +4 -1
  16. package/dist/server/index.d.ts.map +1 -1
  17. package/dist/server/index.js +3 -0
  18. package/dist/server/index.js.map +1 -1
  19. package/dist/server/session-manager.d.ts +195 -0
  20. package/dist/server/session-manager.d.ts.map +1 -0
  21. package/dist/server/session-manager.js +448 -0
  22. package/dist/server/session-manager.js.map +1 -0
  23. package/dist/server/terminal-server.d.ts +54 -6
  24. package/dist/server/terminal-server.d.ts.map +1 -1
  25. package/dist/server/terminal-server.js +313 -80
  26. package/dist/server/terminal-server.js.map +1 -1
  27. package/dist/shared/types.d.ts +122 -2
  28. package/dist/shared/types.d.ts.map +1 -1
  29. package/dist/ui/browser-bundle.js +745 -47
  30. package/dist/ui/browser-bundle.js.map +3 -3
  31. package/dist/ui/x-shell-terminal.d.ts +99 -1
  32. package/dist/ui/x-shell-terminal.d.ts.map +1 -1
  33. package/dist/ui/x-shell-terminal.js +604 -48
  34. package/dist/ui/x-shell-terminal.js.map +1 -1
  35. package/package.json +5 -2
@@ -0,0 +1,448 @@
1
+ /**
2
+ * Session manager for multiplexed terminal sessions.
3
+ *
4
+ * Responsibilities:
5
+ * - Manage shared session lifecycle
6
+ * - Track client connections per session
7
+ * - Handle orphan session cleanup
8
+ * - Maintain history buffers
9
+ * - Broadcast messages to session clients
10
+ */
11
+ import { EventEmitter } from 'events';
12
+ import { CircularBuffer } from './circular-buffer.js';
13
+ export class SessionManager extends EventEmitter {
14
+ constructor(config = {}) {
15
+ super();
16
+ this.sessions = new Map();
17
+ this.clientToSessions = new Map(); // clientId -> sessionIds
18
+ this.orphanTimers = new Map();
19
+ this.config = {
20
+ maxClientsPerSession: config.maxClientsPerSession ?? 10,
21
+ orphanTimeout: config.orphanTimeout ?? 60000,
22
+ historySize: config.historySize ?? 50000,
23
+ historyEnabled: config.historyEnabled ?? true,
24
+ maxSessionsTotal: config.maxSessionsTotal ?? 100,
25
+ verbose: config.verbose ?? false,
26
+ };
27
+ }
28
+ log(message, level = 'info') {
29
+ if (this.config.verbose || level === 'error') {
30
+ const prefix = `[SessionManager]`;
31
+ if (level === 'error') {
32
+ console.error(`${prefix} ${message}`);
33
+ }
34
+ else if (level === 'warn') {
35
+ console.warn(`${prefix} ${message}`);
36
+ }
37
+ else {
38
+ console.log(`${prefix} ${message}`);
39
+ }
40
+ }
41
+ }
42
+ // ==========================================================================
43
+ // Session CRUD
44
+ // ==========================================================================
45
+ /**
46
+ * Create a new shared session.
47
+ */
48
+ createSession(options) {
49
+ if (this.sessions.size >= this.config.maxSessionsTotal) {
50
+ throw new Error('Maximum number of sessions reached');
51
+ }
52
+ const now = new Date();
53
+ const session = {
54
+ id: options.id,
55
+ type: options.type,
56
+ pty: options.pty,
57
+ shell: options.shell,
58
+ cwd: options.cwd,
59
+ cols: options.cols,
60
+ rows: options.rows,
61
+ createdAt: now,
62
+ lastActivity: now,
63
+ container: options.container,
64
+ clients: new Map(),
65
+ owner: options.ownerId,
66
+ label: options.label,
67
+ accepting: options.allowJoin !== false,
68
+ historyBuffer: new CircularBuffer(this.config.historySize),
69
+ historyEnabled: options.enableHistory !== false && this.config.historyEnabled,
70
+ orphanedAt: null,
71
+ };
72
+ // Add owner as first client
73
+ session.clients.set(options.ownerId, {
74
+ id: options.ownerId,
75
+ ws: options.ownerWs,
76
+ joinedAt: now,
77
+ lastActivity: now,
78
+ });
79
+ // Track client -> sessions mapping
80
+ this.trackClientSession(options.ownerId, session.id);
81
+ this.sessions.set(session.id, session);
82
+ this.log(`Created session ${session.id} (type: ${session.type}, owner: ${options.ownerId})`);
83
+ this.emit('sessionCreated', session);
84
+ return session;
85
+ }
86
+ /**
87
+ * Get a session by ID.
88
+ */
89
+ getSession(sessionId) {
90
+ return this.sessions.get(sessionId);
91
+ }
92
+ /**
93
+ * Get all sessions, optionally filtered.
94
+ */
95
+ getSessions(filter) {
96
+ let sessions = Array.from(this.sessions.values());
97
+ if (filter) {
98
+ if (filter.type) {
99
+ sessions = sessions.filter((s) => s.type === filter.type);
100
+ }
101
+ if (filter.container) {
102
+ sessions = sessions.filter((s) => s.container === filter.container);
103
+ }
104
+ if (filter.accepting !== undefined) {
105
+ sessions = sessions.filter((s) => s.accepting === filter.accepting);
106
+ }
107
+ }
108
+ return sessions;
109
+ }
110
+ /**
111
+ * Close a session and clean up.
112
+ */
113
+ closeSession(sessionId, reason) {
114
+ const session = this.sessions.get(sessionId);
115
+ if (!session)
116
+ return;
117
+ this.log(`Closing session ${sessionId} (reason: ${reason})`);
118
+ // Clear orphan timer if any
119
+ this.clearOrphanTimer(sessionId);
120
+ // Kill PTY
121
+ try {
122
+ session.pty.kill();
123
+ }
124
+ catch (e) {
125
+ this.log(`Error killing PTY for session ${sessionId}: ${e}`, 'warn');
126
+ }
127
+ // Remove session from all client mappings
128
+ for (const clientId of session.clients.keys()) {
129
+ const clientSessions = this.clientToSessions.get(clientId);
130
+ if (clientSessions) {
131
+ clientSessions.delete(sessionId);
132
+ if (clientSessions.size === 0) {
133
+ this.clientToSessions.delete(clientId);
134
+ }
135
+ }
136
+ }
137
+ // Remove session
138
+ this.sessions.delete(sessionId);
139
+ this.emit('sessionClosed', sessionId, reason);
140
+ }
141
+ /**
142
+ * Check if a session exists.
143
+ */
144
+ hasSession(sessionId) {
145
+ return this.sessions.has(sessionId);
146
+ }
147
+ /**
148
+ * Get session count.
149
+ */
150
+ getSessionCount() {
151
+ return this.sessions.size;
152
+ }
153
+ // ==========================================================================
154
+ // Client Management
155
+ // ==========================================================================
156
+ /**
157
+ * Add a client to a session.
158
+ */
159
+ addClient(sessionId, clientId, ws) {
160
+ const session = this.sessions.get(sessionId);
161
+ if (!session) {
162
+ this.log(`Cannot add client to non-existent session ${sessionId}`, 'warn');
163
+ return false;
164
+ }
165
+ if (!session.accepting) {
166
+ this.log(`Session ${sessionId} is not accepting new clients`, 'warn');
167
+ return false;
168
+ }
169
+ if (session.clients.size >= this.config.maxClientsPerSession) {
170
+ this.log(`Session ${sessionId} is full`, 'warn');
171
+ return false;
172
+ }
173
+ // If session was orphaned, clear the timer
174
+ if (session.orphanedAt) {
175
+ session.orphanedAt = null;
176
+ this.clearOrphanTimer(sessionId);
177
+ this.log(`Session ${sessionId} is no longer orphaned`);
178
+ }
179
+ const now = new Date();
180
+ session.clients.set(clientId, {
181
+ id: clientId,
182
+ ws,
183
+ joinedAt: now,
184
+ lastActivity: now,
185
+ });
186
+ this.trackClientSession(clientId, sessionId);
187
+ this.log(`Client ${clientId} joined session ${sessionId} (${session.clients.size} clients)`);
188
+ this.emit('clientJoined', sessionId, clientId, session.clients.size);
189
+ return true;
190
+ }
191
+ /**
192
+ * Remove a client from a session.
193
+ */
194
+ removeClient(sessionId, clientId) {
195
+ const session = this.sessions.get(sessionId);
196
+ if (!session)
197
+ return;
198
+ if (!session.clients.has(clientId))
199
+ return;
200
+ session.clients.delete(clientId);
201
+ // Update client -> sessions mapping
202
+ const clientSessions = this.clientToSessions.get(clientId);
203
+ if (clientSessions) {
204
+ clientSessions.delete(sessionId);
205
+ if (clientSessions.size === 0) {
206
+ this.clientToSessions.delete(clientId);
207
+ }
208
+ }
209
+ this.log(`Client ${clientId} left session ${sessionId} (${session.clients.size} clients remaining)`);
210
+ this.emit('clientLeft', sessionId, clientId, session.clients.size);
211
+ // Check if session is now orphaned
212
+ if (session.clients.size === 0) {
213
+ this.handleOrphanedSession(session);
214
+ }
215
+ }
216
+ /**
217
+ * Remove a client from all sessions.
218
+ */
219
+ removeClientFromAllSessions(clientId) {
220
+ const clientSessions = this.clientToSessions.get(clientId);
221
+ if (!clientSessions)
222
+ return [];
223
+ const sessionIds = Array.from(clientSessions);
224
+ for (const sessionId of sessionIds) {
225
+ this.removeClient(sessionId, clientId);
226
+ }
227
+ return sessionIds;
228
+ }
229
+ /**
230
+ * Get all clients in a session.
231
+ */
232
+ getSessionClients(sessionId) {
233
+ const session = this.sessions.get(sessionId);
234
+ return session ? Array.from(session.clients.values()) : [];
235
+ }
236
+ /**
237
+ * Get client count for a session.
238
+ */
239
+ getClientCount(sessionId) {
240
+ const session = this.sessions.get(sessionId);
241
+ return session ? session.clients.size : 0;
242
+ }
243
+ /**
244
+ * Check if a client is in a session.
245
+ */
246
+ isClientInSession(sessionId, clientId) {
247
+ const session = this.sessions.get(sessionId);
248
+ return session ? session.clients.has(clientId) : false;
249
+ }
250
+ /**
251
+ * Get all sessions a client is in.
252
+ */
253
+ getClientSessions(clientId) {
254
+ const clientSessions = this.clientToSessions.get(clientId);
255
+ return clientSessions ? Array.from(clientSessions) : [];
256
+ }
257
+ trackClientSession(clientId, sessionId) {
258
+ let clientSessions = this.clientToSessions.get(clientId);
259
+ if (!clientSessions) {
260
+ clientSessions = new Set();
261
+ this.clientToSessions.set(clientId, clientSessions);
262
+ }
263
+ clientSessions.add(sessionId);
264
+ }
265
+ // ==========================================================================
266
+ // Broadcasting
267
+ // ==========================================================================
268
+ /**
269
+ * Broadcast a message to all clients in a session.
270
+ */
271
+ broadcastToSession(sessionId, message, excludeClientId) {
272
+ const session = this.sessions.get(sessionId);
273
+ if (!session)
274
+ return;
275
+ const messageStr = JSON.stringify(message);
276
+ for (const [clientId, client] of session.clients) {
277
+ if (clientId === excludeClientId)
278
+ continue;
279
+ try {
280
+ if (client.ws.readyState === 1) {
281
+ // WebSocket.OPEN
282
+ client.ws.send(messageStr);
283
+ }
284
+ }
285
+ catch (e) {
286
+ this.log(`Error broadcasting to client ${clientId}: ${e}`, 'warn');
287
+ }
288
+ }
289
+ }
290
+ /**
291
+ * Send a message to a specific client in a session.
292
+ */
293
+ sendToClient(sessionId, clientId, message) {
294
+ const session = this.sessions.get(sessionId);
295
+ if (!session)
296
+ return false;
297
+ const client = session.clients.get(clientId);
298
+ if (!client)
299
+ return false;
300
+ try {
301
+ if (client.ws.readyState === 1) {
302
+ client.ws.send(JSON.stringify(message));
303
+ return true;
304
+ }
305
+ }
306
+ catch (e) {
307
+ this.log(`Error sending to client ${clientId}: ${e}`, 'warn');
308
+ }
309
+ return false;
310
+ }
311
+ // ==========================================================================
312
+ // History
313
+ // ==========================================================================
314
+ /**
315
+ * Append data to a session's history buffer.
316
+ */
317
+ appendHistory(sessionId, data) {
318
+ const session = this.sessions.get(sessionId);
319
+ if (session && session.historyEnabled) {
320
+ session.historyBuffer.append(data);
321
+ }
322
+ }
323
+ /**
324
+ * Get history from a session.
325
+ */
326
+ getHistory(sessionId, limit) {
327
+ const session = this.sessions.get(sessionId);
328
+ if (!session || !session.historyEnabled)
329
+ return '';
330
+ return session.historyBuffer.toString(limit);
331
+ }
332
+ /**
333
+ * Clear history for a session.
334
+ */
335
+ clearHistory(sessionId) {
336
+ const session = this.sessions.get(sessionId);
337
+ if (session) {
338
+ session.historyBuffer.clear();
339
+ }
340
+ }
341
+ // ==========================================================================
342
+ // Activity Tracking
343
+ // ==========================================================================
344
+ /**
345
+ * Update last activity timestamp for a session.
346
+ */
347
+ updateSessionActivity(sessionId) {
348
+ const session = this.sessions.get(sessionId);
349
+ if (session) {
350
+ session.lastActivity = new Date();
351
+ }
352
+ }
353
+ /**
354
+ * Update last activity for a client.
355
+ */
356
+ updateClientActivity(sessionId, clientId) {
357
+ const session = this.sessions.get(sessionId);
358
+ if (session) {
359
+ session.lastActivity = new Date();
360
+ const client = session.clients.get(clientId);
361
+ if (client) {
362
+ client.lastActivity = new Date();
363
+ }
364
+ }
365
+ }
366
+ // ==========================================================================
367
+ // Orphan Handling
368
+ // ==========================================================================
369
+ handleOrphanedSession(session) {
370
+ session.orphanedAt = new Date();
371
+ this.log(`Session ${session.id} is now orphaned, starting cleanup timer`);
372
+ this.emit('sessionOrphaned', session.id);
373
+ // Start orphan timer
374
+ const timer = setTimeout(() => {
375
+ // Check if still orphaned
376
+ if (session.clients.size === 0) {
377
+ this.log(`Orphan timeout for session ${session.id}, closing`);
378
+ this.closeSession(session.id, 'orphan_timeout');
379
+ }
380
+ }, this.config.orphanTimeout);
381
+ this.orphanTimers.set(session.id, timer);
382
+ }
383
+ clearOrphanTimer(sessionId) {
384
+ const timer = this.orphanTimers.get(sessionId);
385
+ if (timer) {
386
+ clearTimeout(timer);
387
+ this.orphanTimers.delete(sessionId);
388
+ }
389
+ }
390
+ // ==========================================================================
391
+ // Session Info
392
+ // ==========================================================================
393
+ /**
394
+ * Convert a session to SharedSessionInfo for client consumption.
395
+ */
396
+ toSharedSessionInfo(session) {
397
+ return {
398
+ sessionId: session.id,
399
+ type: session.type,
400
+ shell: session.shell,
401
+ cwd: session.cwd,
402
+ cols: session.cols,
403
+ rows: session.rows,
404
+ createdAt: session.createdAt,
405
+ container: session.container,
406
+ clientCount: session.clients.size,
407
+ accepting: session.accepting,
408
+ ownerId: session.owner,
409
+ label: session.label,
410
+ historyEnabled: session.historyEnabled,
411
+ };
412
+ }
413
+ // ==========================================================================
414
+ // Cleanup
415
+ // ==========================================================================
416
+ /**
417
+ * Clean up all sessions and resources.
418
+ */
419
+ cleanup() {
420
+ this.log('Cleaning up all sessions');
421
+ // Clear all orphan timers
422
+ for (const timer of this.orphanTimers.values()) {
423
+ clearTimeout(timer);
424
+ }
425
+ this.orphanTimers.clear();
426
+ // Close all sessions
427
+ for (const sessionId of this.sessions.keys()) {
428
+ this.closeSession(sessionId, 'cleanup');
429
+ }
430
+ this.clientToSessions.clear();
431
+ }
432
+ /**
433
+ * Get manager statistics.
434
+ */
435
+ getStats() {
436
+ let orphanedCount = 0;
437
+ for (const session of this.sessions.values()) {
438
+ if (session.orphanedAt)
439
+ orphanedCount++;
440
+ }
441
+ return {
442
+ sessionCount: this.sessions.size,
443
+ clientCount: this.clientToSessions.size,
444
+ orphanedCount,
445
+ };
446
+ }
447
+ }
448
+ //# sourceMappingURL=session-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../src/server/session-manager.ts"],"names":[],"mappings":"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"}
@@ -2,10 +2,11 @@
2
2
  * Server-side terminal handler using node-pty
3
3
  *
4
4
  * Manages PTY sessions and WebSocket connections for web-based terminals.
5
+ * Supports session multiplexing - multiple clients can connect to the same session.
5
6
  */
6
7
  import { WebSocket } from 'ws';
7
8
  import type { Server as HttpServer } from 'http';
8
- import type { ServerConfig, SessionInfo } from '../shared/types.js';
9
+ import type { ServerConfig, SessionInfo, SharedSessionInfo, SessionListFilter } from '../shared/types.js';
9
10
  /**
10
11
  * Terminal server options
11
12
  */
@@ -20,17 +21,36 @@ export interface TerminalServerOptions extends ServerConfig {
20
21
  verbose?: boolean;
21
22
  /** Path to Docker CLI (default: 'docker') */
22
23
  dockerPath?: string;
24
+ /** Maximum clients per session (default: 10) */
25
+ maxClientsPerSession?: number;
26
+ /** Orphan session timeout in ms (default: 60000) */
27
+ orphanTimeout?: number;
28
+ /** History buffer size in characters (default: 50000) */
29
+ historySize?: number;
30
+ /** Enable session history (default: true) */
31
+ historyEnabled?: boolean;
32
+ /** Maximum total sessions (default: 100) */
33
+ maxSessionsTotal?: number;
23
34
  }
24
35
  /**
25
- * Terminal server class
36
+ * Terminal server class with session multiplexing support
26
37
  */
27
38
  export declare class TerminalServer {
28
39
  private config;
29
- private sessions;
40
+ private sessionManager;
30
41
  private wss;
31
42
  private pty;
32
43
  private cleanupInterval;
44
+ private clientIds;
33
45
  constructor(options?: TerminalServerOptions);
46
+ /**
47
+ * Generate a unique client ID
48
+ */
49
+ private generateClientId;
50
+ /**
51
+ * Get or create client ID for a WebSocket
52
+ */
53
+ private getClientId;
34
54
  /**
35
55
  * Initialize node-pty (lazy load)
36
56
  */
@@ -56,6 +76,18 @@ export declare class TerminalServer {
56
76
  * Handle message from client
57
77
  */
58
78
  private handleMessage;
79
+ /**
80
+ * Handle list sessions request
81
+ */
82
+ private handleListSessions;
83
+ /**
84
+ * Handle join session request
85
+ */
86
+ private handleJoinSession;
87
+ /**
88
+ * Handle leave session request
89
+ */
90
+ private handleLeaveSession;
59
91
  /**
60
92
  * Validate shell path
61
93
  */
@@ -71,7 +103,11 @@ export declare class TerminalServer {
71
103
  /**
72
104
  * Spawn a Docker exec session
73
105
  */
74
- private spawnDockerSession;
106
+ private spawnDockerExecSession;
107
+ /**
108
+ * Spawn a Docker attach session (connects to container's main process)
109
+ */
110
+ private spawnDockerAttachSession;
75
111
  /**
76
112
  * Spawn a new terminal session
77
113
  */
@@ -89,7 +125,7 @@ export declare class TerminalServer {
89
125
  */
90
126
  private resizeSession;
91
127
  /**
92
- * Close session
128
+ * Close session (only owner can close, or force close)
93
129
  */
94
130
  private closeSession;
95
131
  /**
@@ -113,9 +149,21 @@ export declare class TerminalServer {
113
149
  */
114
150
  private listContainers;
115
151
  /**
116
- * Get all active sessions
152
+ * Get all active sessions (for external access)
117
153
  */
118
154
  getSessions(): SessionInfo[];
155
+ /**
156
+ * Get all active sessions with multiplexing info
157
+ */
158
+ getSharedSessions(filter?: SessionListFilter): SharedSessionInfo[];
159
+ /**
160
+ * Get session manager statistics
161
+ */
162
+ getStats(): {
163
+ sessionCount: number;
164
+ clientCount: number;
165
+ orphanedCount: number;
166
+ };
119
167
  /**
120
168
  * Close all sessions and stop server
121
169
  */
@@ -1 +1 @@
1
- {"version":3,"file":"terminal-server.d.ts","sourceRoot":"","sources":["../../src/server/terminal-server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAmB,MAAM,IAAI,CAAC;AAGhD,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAC;AACjD,OAAO,KAAK,EACV,YAAY,EAGZ,WAAW,EAGZ,MAAM,oBAAoB,CAAC;AA8B5B;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,YAAY;IACzD,sDAAsD;IACtD,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAA2D;IACzE,OAAO,CAAC,QAAQ,CAAsC;IACtD,OAAO,CAAC,GAAG,CAAgC;IAC3C,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,eAAe,CAA+C;gBAE1D,OAAO,GAAE,qBAA0B;IAqB/C;;OAEG;YACW,OAAO;IAarB;;OAEG;IACH,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAUhC;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAM1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAS5B;;;OAGG;IACG,gBAAgB,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAsC9D;;OAEG;IACH,OAAO,CAAC,aAAa;IAiCrB;;OAEG;IACH,OAAO,CAAC,cAAc;IAgBtB;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAmB1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAoE1B;;OAEG;IACH,OAAO,CAAC,YAAY;IAyHpB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IA+B5B;;OAEG;IACH,OAAO,CAAC,cAAc;IAWtB;;OAEG;IACH,OAAO,CAAC,aAAa;IAYrB;;OAEG;IACH,OAAO,CAAC,YAAY;IAcpB;;OAEG;IACH,OAAO,CAAC,eAAe;IAoBvB;;OAEG;IACH,OAAO,CAAC,SAAS;IAUjB;;OAEG;IACH,OAAO,CAAC,GAAG;IAgBX;;OAEG;IACH,OAAO,CAAC,cAAc;IActB;;OAEG;IACH,OAAO,CAAC,cAAc;IAmDtB;;OAEG;IACH,WAAW,IAAI,WAAW,EAAE;IAY5B;;OAEG;IACH,KAAK,IAAI,IAAI;CAoBd;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,GAAE,IAAI,CAAC,qBAAqB,EAAE,QAAQ,GAAG,MAAM,CAAM,GAC3D;IACD,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;CAC1C,CAMA"}
1
+ {"version":3,"file":"terminal-server.d.ts","sourceRoot":"","sources":["../../src/server/terminal-server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAmB,MAAM,IAAI,CAAC;AAGhD,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAC;AACjD,OAAO,KAAK,EACV,YAAY,EAGZ,WAAW,EAIX,iBAAiB,EACjB,iBAAiB,EAElB,MAAM,oBAAoB,CAAC;AAc5B;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,YAAY;IACzD,sDAAsD;IACtD,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,gDAAgD;IAChD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,oDAAoD;IACpD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,4CAA4C;IAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAA2D;IACzE,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,GAAG,CAAgC;IAC3C,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,eAAe,CAA+C;IACtE,OAAO,CAAC,SAAS,CAAoC;gBAEzC,OAAO,GAAE,qBAA0B;IA0C/C;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAIxB;;OAEG;IACH,OAAO,CAAC,WAAW;IASnB;;OAEG;YACW,OAAO;IAarB;;OAEG;IACH,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAUhC;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAM1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAS5B;;;OAGG;IACG,gBAAgB,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAyC9D;;OAEG;IACH,OAAO,CAAC,aAAa;IAkDrB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAc1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA+DzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAuC1B;;OAEG;IACH,OAAO,CAAC,cAAc;IAgBtB;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAuB1B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA0E9B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA4DhC;;OAEG;IACH,OAAO,CAAC,YAAY;IAiIpB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAyC5B;;OAEG;IACH,OAAO,CAAC,cAAc;IAiBtB;;OAEG;IACH,OAAO,CAAC,aAAa;IAYrB;;OAEG;IACH,OAAO,CAAC,YAAY;IAwBpB;;OAEG;IACH,OAAO,CAAC,eAAe;IAqBvB;;OAEG;IACH,OAAO,CAAC,SAAS;IAUjB;;OAEG;IACH,OAAO,CAAC,GAAG;IAgBX;;OAEG;IACH,OAAO,CAAC,cAAc;IAgBtB;;OAEG;IACH,OAAO,CAAC,cAAc;IAyDtB;;OAEG;IACH,WAAW,IAAI,WAAW,EAAE;IAY5B;;OAEG;IACH,iBAAiB,CAAC,MAAM,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,EAAE;IAMlE;;OAEG;IACH,QAAQ,IAAI;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE;IAIhF;;OAEG;IACH,KAAK,IAAI,IAAI;CAkBd;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,GAAE,IAAI,CAAC,qBAAqB,EAAE,QAAQ,GAAG,MAAM,CAAM,GAC3D;IACD,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;CAC1C,CAMA"}