x-shell.js 0.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 (38) hide show
  1. package/README.md +304 -0
  2. package/dist/client/browser-bundle.js +314 -0
  3. package/dist/client/browser-bundle.js.map +7 -0
  4. package/dist/client/index.d.ts +7 -0
  5. package/dist/client/index.d.ts.map +1 -0
  6. package/dist/client/index.js +5 -0
  7. package/dist/client/index.js.map +1 -0
  8. package/dist/client/terminal-client.d.ts +122 -0
  9. package/dist/client/terminal-client.d.ts.map +1 -0
  10. package/dist/client/terminal-client.js +328 -0
  11. package/dist/client/terminal-client.js.map +1 -0
  12. package/dist/server/index.d.ts +7 -0
  13. package/dist/server/index.d.ts.map +1 -0
  14. package/dist/server/index.js +5 -0
  15. package/dist/server/index.js.map +1 -0
  16. package/dist/server/terminal-server.d.ts +107 -0
  17. package/dist/server/terminal-server.d.ts.map +1 -0
  18. package/dist/server/terminal-server.js +392 -0
  19. package/dist/server/terminal-server.js.map +1 -0
  20. package/dist/shared/types.d.ts +133 -0
  21. package/dist/shared/types.d.ts.map +1 -0
  22. package/dist/shared/types.js +5 -0
  23. package/dist/shared/types.js.map +1 -0
  24. package/dist/ui/browser-bundle.js +1654 -0
  25. package/dist/ui/browser-bundle.js.map +7 -0
  26. package/dist/ui/index.d.ts +6 -0
  27. package/dist/ui/index.d.ts.map +1 -0
  28. package/dist/ui/index.js +6 -0
  29. package/dist/ui/index.js.map +1 -0
  30. package/dist/ui/styles.d.ts +16 -0
  31. package/dist/ui/styles.d.ts.map +1 -0
  32. package/dist/ui/styles.js +125 -0
  33. package/dist/ui/styles.js.map +1 -0
  34. package/dist/ui/x-shell-terminal.d.ts +100 -0
  35. package/dist/ui/x-shell-terminal.d.ts.map +1 -0
  36. package/dist/ui/x-shell-terminal.js +540 -0
  37. package/dist/ui/x-shell-terminal.js.map +1 -0
  38. package/package.json +94 -0
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Terminal client for connecting to x-shell server
3
+ *
4
+ * Example usage:
5
+ * ```typescript
6
+ * import { TerminalClient } from 'x-shell.js/client';
7
+ *
8
+ * const client = new TerminalClient({ url: 'ws://localhost:3000/terminal' });
9
+ * await client.connect();
10
+ *
11
+ * client.onData((data) => console.log(data));
12
+ * client.onExit((code) => console.log('Exited with code:', code));
13
+ *
14
+ * await client.spawn({ shell: '/bin/bash', cwd: '/home/user' });
15
+ * client.write('ls -la\n');
16
+ * client.resize(120, 40);
17
+ * client.kill();
18
+ * ```
19
+ */
20
+ import type { ClientConfig, TerminalOptions, SessionInfo } from '../shared/types.js';
21
+ /**
22
+ * Connection state
23
+ */
24
+ export type ConnectionState = 'disconnected' | 'connecting' | 'connected';
25
+ /**
26
+ * Terminal client class
27
+ */
28
+ export declare class TerminalClient {
29
+ private config;
30
+ private ws;
31
+ private state;
32
+ private sessionId;
33
+ private sessionInfo;
34
+ private reconnectAttempts;
35
+ private reconnectTimeout;
36
+ private connectHandlers;
37
+ private disconnectHandlers;
38
+ private dataHandlers;
39
+ private exitHandlers;
40
+ private errorHandlers;
41
+ private spawnedHandlers;
42
+ private spawnResolve;
43
+ private spawnReject;
44
+ constructor(config: ClientConfig);
45
+ /**
46
+ * Connect to the terminal server
47
+ */
48
+ connect(): Promise<void>;
49
+ /**
50
+ * Disconnect from the terminal server
51
+ */
52
+ disconnect(): void;
53
+ /**
54
+ * Schedule a reconnection attempt
55
+ */
56
+ private scheduleReconnect;
57
+ /**
58
+ * Handle incoming message
59
+ */
60
+ private handleMessage;
61
+ /**
62
+ * Spawn a terminal session
63
+ */
64
+ spawn(options?: TerminalOptions): Promise<SessionInfo>;
65
+ /**
66
+ * Write data to the terminal
67
+ */
68
+ write(data: string): void;
69
+ /**
70
+ * Resize the terminal
71
+ */
72
+ resize(cols: number, rows: number): void;
73
+ /**
74
+ * Kill the terminal session
75
+ */
76
+ kill(): void;
77
+ /**
78
+ * Called when connected to server
79
+ */
80
+ onConnect(handler: () => void): void;
81
+ /**
82
+ * Called when disconnected from server
83
+ */
84
+ onDisconnect(handler: () => void): void;
85
+ /**
86
+ * Called when data is received from the terminal
87
+ */
88
+ onData(handler: (data: string) => void): void;
89
+ /**
90
+ * Called when the terminal session exits
91
+ */
92
+ onExit(handler: (code: number) => void): void;
93
+ /**
94
+ * Called when an error occurs
95
+ */
96
+ onError(handler: (error: Error) => void): void;
97
+ /**
98
+ * Called when a session is spawned
99
+ */
100
+ onSpawned(handler: (info: SessionInfo) => void): void;
101
+ /**
102
+ * Get current connection state
103
+ */
104
+ getState(): ConnectionState;
105
+ /**
106
+ * Check if connected
107
+ */
108
+ isConnected(): boolean;
109
+ /**
110
+ * Get current session ID
111
+ */
112
+ getSessionId(): string | null;
113
+ /**
114
+ * Get current session info
115
+ */
116
+ getSessionInfo(): SessionInfo | null;
117
+ /**
118
+ * Check if a session is active
119
+ */
120
+ hasActiveSession(): boolean;
121
+ }
122
+ //# sourceMappingURL=terminal-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-client.d.ts","sourceRoot":"","sources":["../../src/client/terminal-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EAEf,WAAW,EACZ,MAAM,oBAAoB,CAAC;AAE5B;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,YAAY,GAAG,WAAW,CAAC;AAE1E;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,gBAAgB,CAA8C;IAGtE,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,kBAAkB,CAAsB;IAChD,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,eAAe,CAAuC;IAG9D,OAAO,CAAC,YAAY,CAA8C;IAClE,OAAO,CAAC,WAAW,CAAyC;gBAEhD,MAAM,EAAE,YAAY;IAShC;;OAEG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAuDxB;;OAEG;IACH,UAAU,IAAI,IAAI;IAkBlB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAezB;;OAEG;IACH,OAAO,CAAC,aAAa;IAoDrB;;OAEG;IACH,KAAK,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,WAAW,CAAC;IAwB1D;;OAEG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAoBzB;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAqBxC;;OAEG;IACH,IAAI,IAAI,IAAI;IAwBZ;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAIpC;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAIvC;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAI7C;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAI7C;;OAEG;IACH,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAI9C;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,GAAG,IAAI;IAQrD;;OAEG;IACH,QAAQ,IAAI,eAAe;IAI3B;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,YAAY,IAAI,MAAM,GAAG,IAAI;IAI7B;;OAEG;IACH,cAAc,IAAI,WAAW,GAAG,IAAI;IAIpC;;OAEG;IACH,gBAAgB,IAAI,OAAO;CAG5B"}
@@ -0,0 +1,328 @@
1
+ /**
2
+ * Terminal client for connecting to x-shell server
3
+ *
4
+ * Example usage:
5
+ * ```typescript
6
+ * import { TerminalClient } from 'x-shell.js/client';
7
+ *
8
+ * const client = new TerminalClient({ url: 'ws://localhost:3000/terminal' });
9
+ * await client.connect();
10
+ *
11
+ * client.onData((data) => console.log(data));
12
+ * client.onExit((code) => console.log('Exited with code:', code));
13
+ *
14
+ * await client.spawn({ shell: '/bin/bash', cwd: '/home/user' });
15
+ * client.write('ls -la\n');
16
+ * client.resize(120, 40);
17
+ * client.kill();
18
+ * ```
19
+ */
20
+ /**
21
+ * Terminal client class
22
+ */
23
+ export class TerminalClient {
24
+ constructor(config) {
25
+ this.ws = null;
26
+ this.state = 'disconnected';
27
+ this.sessionId = null;
28
+ this.sessionInfo = null;
29
+ this.reconnectAttempts = 0;
30
+ this.reconnectTimeout = null;
31
+ // Event handlers
32
+ this.connectHandlers = [];
33
+ this.disconnectHandlers = [];
34
+ this.dataHandlers = [];
35
+ this.exitHandlers = [];
36
+ this.errorHandlers = [];
37
+ this.spawnedHandlers = [];
38
+ // Promise resolvers for spawn
39
+ this.spawnResolve = null;
40
+ this.spawnReject = null;
41
+ this.config = {
42
+ url: config.url,
43
+ reconnect: config.reconnect ?? true,
44
+ maxReconnectAttempts: config.maxReconnectAttempts ?? 10,
45
+ reconnectDelay: config.reconnectDelay ?? 1000,
46
+ };
47
+ }
48
+ /**
49
+ * Connect to the terminal server
50
+ */
51
+ connect() {
52
+ return new Promise((resolve, reject) => {
53
+ if (this.state === 'connected') {
54
+ resolve();
55
+ return;
56
+ }
57
+ this.state = 'connecting';
58
+ try {
59
+ this.ws = new WebSocket(this.config.url);
60
+ }
61
+ catch (error) {
62
+ this.state = 'disconnected';
63
+ reject(error);
64
+ return;
65
+ }
66
+ this.ws.onopen = () => {
67
+ this.state = 'connected';
68
+ this.reconnectAttempts = 0;
69
+ this.connectHandlers.forEach((handler) => handler());
70
+ resolve();
71
+ };
72
+ this.ws.onclose = () => {
73
+ const wasConnected = this.state === 'connected';
74
+ this.state = 'disconnected';
75
+ this.sessionId = null;
76
+ this.sessionInfo = null;
77
+ if (wasConnected) {
78
+ this.disconnectHandlers.forEach((handler) => handler());
79
+ }
80
+ // Attempt reconnection
81
+ if (this.config.reconnect && this.reconnectAttempts < this.config.maxReconnectAttempts) {
82
+ this.scheduleReconnect();
83
+ }
84
+ };
85
+ this.ws.onerror = (event) => {
86
+ const error = new Error('WebSocket error');
87
+ this.errorHandlers.forEach((handler) => handler(error));
88
+ if (this.state === 'connecting') {
89
+ reject(error);
90
+ }
91
+ };
92
+ this.ws.onmessage = (event) => {
93
+ this.handleMessage(event.data);
94
+ };
95
+ });
96
+ }
97
+ /**
98
+ * Disconnect from the terminal server
99
+ */
100
+ disconnect() {
101
+ this.config.reconnect = false; // Prevent auto-reconnect
102
+ if (this.reconnectTimeout) {
103
+ clearTimeout(this.reconnectTimeout);
104
+ this.reconnectTimeout = null;
105
+ }
106
+ if (this.ws) {
107
+ this.ws.close();
108
+ this.ws = null;
109
+ }
110
+ this.state = 'disconnected';
111
+ this.sessionId = null;
112
+ this.sessionInfo = null;
113
+ }
114
+ /**
115
+ * Schedule a reconnection attempt
116
+ */
117
+ scheduleReconnect() {
118
+ if (this.reconnectTimeout)
119
+ return;
120
+ const delay = this.config.reconnectDelay * Math.pow(2, this.reconnectAttempts);
121
+ const maxDelay = 30000; // 30 seconds max
122
+ this.reconnectTimeout = setTimeout(() => {
123
+ this.reconnectTimeout = null;
124
+ this.reconnectAttempts++;
125
+ this.connect().catch(() => {
126
+ // Error handled by onclose
127
+ });
128
+ }, Math.min(delay, maxDelay));
129
+ }
130
+ /**
131
+ * Handle incoming message
132
+ */
133
+ handleMessage(data) {
134
+ let message;
135
+ try {
136
+ message = JSON.parse(data);
137
+ }
138
+ catch {
139
+ console.error('[x-shell] Invalid message:', data);
140
+ return;
141
+ }
142
+ switch (message.type) {
143
+ case 'spawned':
144
+ this.sessionId = message.sessionId;
145
+ this.sessionInfo = {
146
+ sessionId: message.sessionId,
147
+ shell: message.shell,
148
+ cwd: message.cwd,
149
+ cols: message.cols,
150
+ rows: message.rows,
151
+ createdAt: new Date(),
152
+ };
153
+ this.spawnedHandlers.forEach((handler) => handler(this.sessionInfo));
154
+ if (this.spawnResolve) {
155
+ this.spawnResolve(this.sessionInfo);
156
+ this.spawnResolve = null;
157
+ this.spawnReject = null;
158
+ }
159
+ break;
160
+ case 'data':
161
+ this.dataHandlers.forEach((handler) => handler(message.data));
162
+ break;
163
+ case 'exit':
164
+ const exitCode = message.exitCode;
165
+ this.exitHandlers.forEach((handler) => handler(exitCode));
166
+ this.sessionId = null;
167
+ this.sessionInfo = null;
168
+ break;
169
+ case 'error':
170
+ const error = new Error(message.error);
171
+ this.errorHandlers.forEach((handler) => handler(error));
172
+ if (this.spawnReject) {
173
+ this.spawnReject(error);
174
+ this.spawnResolve = null;
175
+ this.spawnReject = null;
176
+ }
177
+ break;
178
+ }
179
+ }
180
+ /**
181
+ * Spawn a terminal session
182
+ */
183
+ spawn(options = {}) {
184
+ return new Promise((resolve, reject) => {
185
+ if (this.state !== 'connected' || !this.ws) {
186
+ reject(new Error('Not connected to server'));
187
+ return;
188
+ }
189
+ if (this.sessionId) {
190
+ reject(new Error('Session already spawned. Call kill() first.'));
191
+ return;
192
+ }
193
+ this.spawnResolve = resolve;
194
+ this.spawnReject = reject;
195
+ this.ws.send(JSON.stringify({
196
+ type: 'spawn',
197
+ options,
198
+ }));
199
+ });
200
+ }
201
+ /**
202
+ * Write data to the terminal
203
+ */
204
+ write(data) {
205
+ if (!this.ws || this.state !== 'connected') {
206
+ console.error('[x-shell] Cannot write: not connected');
207
+ return;
208
+ }
209
+ if (!this.sessionId) {
210
+ console.error('[x-shell] Cannot write: no active session');
211
+ return;
212
+ }
213
+ this.ws.send(JSON.stringify({
214
+ type: 'data',
215
+ sessionId: this.sessionId,
216
+ data,
217
+ }));
218
+ }
219
+ /**
220
+ * Resize the terminal
221
+ */
222
+ resize(cols, rows) {
223
+ if (!this.ws || this.state !== 'connected') {
224
+ console.error('[x-shell] Cannot resize: not connected');
225
+ return;
226
+ }
227
+ if (!this.sessionId) {
228
+ console.error('[x-shell] Cannot resize: no active session');
229
+ return;
230
+ }
231
+ this.ws.send(JSON.stringify({
232
+ type: 'resize',
233
+ sessionId: this.sessionId,
234
+ cols,
235
+ rows,
236
+ }));
237
+ }
238
+ /**
239
+ * Kill the terminal session
240
+ */
241
+ kill() {
242
+ if (!this.ws || this.state !== 'connected') {
243
+ return;
244
+ }
245
+ if (!this.sessionId) {
246
+ return;
247
+ }
248
+ this.ws.send(JSON.stringify({
249
+ type: 'close',
250
+ sessionId: this.sessionId,
251
+ }));
252
+ this.sessionId = null;
253
+ this.sessionInfo = null;
254
+ }
255
+ // ==========================================
256
+ // Event handlers
257
+ // ==========================================
258
+ /**
259
+ * Called when connected to server
260
+ */
261
+ onConnect(handler) {
262
+ this.connectHandlers.push(handler);
263
+ }
264
+ /**
265
+ * Called when disconnected from server
266
+ */
267
+ onDisconnect(handler) {
268
+ this.disconnectHandlers.push(handler);
269
+ }
270
+ /**
271
+ * Called when data is received from the terminal
272
+ */
273
+ onData(handler) {
274
+ this.dataHandlers.push(handler);
275
+ }
276
+ /**
277
+ * Called when the terminal session exits
278
+ */
279
+ onExit(handler) {
280
+ this.exitHandlers.push(handler);
281
+ }
282
+ /**
283
+ * Called when an error occurs
284
+ */
285
+ onError(handler) {
286
+ this.errorHandlers.push(handler);
287
+ }
288
+ /**
289
+ * Called when a session is spawned
290
+ */
291
+ onSpawned(handler) {
292
+ this.spawnedHandlers.push(handler);
293
+ }
294
+ // ==========================================
295
+ // Getters
296
+ // ==========================================
297
+ /**
298
+ * Get current connection state
299
+ */
300
+ getState() {
301
+ return this.state;
302
+ }
303
+ /**
304
+ * Check if connected
305
+ */
306
+ isConnected() {
307
+ return this.state === 'connected';
308
+ }
309
+ /**
310
+ * Get current session ID
311
+ */
312
+ getSessionId() {
313
+ return this.sessionId;
314
+ }
315
+ /**
316
+ * Get current session info
317
+ */
318
+ getSessionInfo() {
319
+ return this.sessionInfo;
320
+ }
321
+ /**
322
+ * Check if a session is active
323
+ */
324
+ hasActiveSession() {
325
+ return this.sessionId !== null;
326
+ }
327
+ }
328
+ //# sourceMappingURL=terminal-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-client.js","sourceRoot":"","sources":["../../src/client/terminal-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * x-shell.js server exports
3
+ */
4
+ export { TerminalServer, createTerminalMiddleware } from './terminal-server.js';
5
+ export type { TerminalServerOptions } from './terminal-server.js';
6
+ export type { ServerConfig, TerminalOptions, SessionInfo, } from '../shared/types.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChF,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAClE,YAAY,EACV,YAAY,EACZ,eAAe,EACf,WAAW,GACZ,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * x-shell.js server exports
3
+ */
4
+ export { TerminalServer, createTerminalMiddleware } from './terminal-server.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Server-side terminal handler using node-pty
3
+ *
4
+ * Manages PTY sessions and WebSocket connections for web-based terminals.
5
+ */
6
+ import type { Server as HttpServer } from 'http';
7
+ import type { ServerConfig, SessionInfo } from '../shared/types.js';
8
+ /**
9
+ * Terminal server options
10
+ */
11
+ export interface TerminalServerOptions extends ServerConfig {
12
+ /** HTTP server to attach to (for upgrade handling) */
13
+ server?: HttpServer;
14
+ /** WebSocket path (default: '/terminal') */
15
+ path?: string;
16
+ /** Port for standalone WebSocket server */
17
+ port?: number;
18
+ /** Enable verbose logging */
19
+ verbose?: boolean;
20
+ }
21
+ /**
22
+ * Terminal server class
23
+ */
24
+ export declare class TerminalServer {
25
+ private config;
26
+ private sessions;
27
+ private wss;
28
+ private pty;
29
+ private cleanupInterval;
30
+ constructor(options?: TerminalServerOptions);
31
+ /**
32
+ * Initialize node-pty (lazy load)
33
+ */
34
+ private initPty;
35
+ /**
36
+ * Attach to an existing HTTP server
37
+ */
38
+ attach(server: HttpServer): void;
39
+ /**
40
+ * Start standalone WebSocket server
41
+ */
42
+ listen(port: number): void;
43
+ /**
44
+ * Setup WebSocket server event handlers
45
+ */
46
+ private setupWebSocketServer;
47
+ /**
48
+ * Handle WebSocket connection
49
+ */
50
+ private handleConnection;
51
+ /**
52
+ * Handle message from client
53
+ */
54
+ private handleMessage;
55
+ /**
56
+ * Validate shell path
57
+ */
58
+ private isShellAllowed;
59
+ /**
60
+ * Validate working directory
61
+ */
62
+ private isCwdAllowed;
63
+ /**
64
+ * Spawn a new terminal session
65
+ */
66
+ private spawnSession;
67
+ /**
68
+ * Write data to session
69
+ */
70
+ private writeToSession;
71
+ /**
72
+ * Resize session
73
+ */
74
+ private resizeSession;
75
+ /**
76
+ * Close session
77
+ */
78
+ private closeSession;
79
+ /**
80
+ * Clean up inactive sessions
81
+ */
82
+ private cleanupSessions;
83
+ /**
84
+ * Send error message to client
85
+ */
86
+ private sendError;
87
+ /**
88
+ * Log message
89
+ */
90
+ private log;
91
+ /**
92
+ * Get all active sessions
93
+ */
94
+ getSessions(): SessionInfo[];
95
+ /**
96
+ * Close all sessions and stop server
97
+ */
98
+ close(): void;
99
+ }
100
+ /**
101
+ * Express middleware to attach terminal server
102
+ */
103
+ export declare function createTerminalMiddleware(options?: Omit<TerminalServerOptions, 'server' | 'port'>): {
104
+ server: TerminalServer;
105
+ attach: (httpServer: HttpServer) => void;
106
+ };
107
+ //# sourceMappingURL=terminal-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-server.d.ts","sourceRoot":"","sources":["../../src/server/terminal-server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAC;AACjD,OAAO,KAAK,EACV,YAAY,EAGZ,WAAW,EACZ,MAAM,oBAAoB,CAAC;AA2B5B;;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;CACnB;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;IAgB/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;;OAEG;YACW,gBAAgB;IAmC9B;;OAEG;IACH,OAAO,CAAC,aAAa;IA6BrB;;OAEG;IACH,OAAO,CAAC,cAAc;IAgBtB;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;OAEG;IACH,OAAO,CAAC,YAAY;IA2GpB;;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,WAAW,IAAI,WAAW,EAAE;IAW5B;;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"}