@ebowwa/terminal 0.2.1 → 0.3.1

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.
@@ -0,0 +1,272 @@
1
+ /**
2
+ * tmux-based Local Terminal Sessions
3
+ * Provides persistent terminal sessions using local tmux for SSH connections
4
+ * SSH connections stay active within tmux sessions on the local machine
5
+ */
6
+ /**
7
+ * Local tmux session configuration
8
+ */
9
+ interface LocalTmuxConfig {
10
+ /** Session name prefix for local MCP SSH sessions */
11
+ sessionPrefix: string;
12
+ /** Default shell to use in tmux */
13
+ defaultShell: string;
14
+ /** Terminal type */
15
+ term: string;
16
+ /** Timeout for local commands (seconds) */
17
+ timeout: number;
18
+ /** Scrollback limit (lines) */
19
+ historyLimit: number;
20
+ /** Session age limit for cleanup (milliseconds) */
21
+ sessionAgeLimit: number;
22
+ }
23
+ /**
24
+ * Options for creating a local tmux SSH session
25
+ */
26
+ export interface LocalTmuxSessionOptions {
27
+ /** Initial command to run after SSH connection */
28
+ initialCommand?: string;
29
+ /** Custom session name (auto-generated if not provided) */
30
+ sessionName?: string;
31
+ /** Window name */
32
+ windowName?: string;
33
+ }
34
+ /**
35
+ * Result of creating a local tmux session
36
+ */
37
+ export interface LocalTmuxSessionResult {
38
+ /** Session name */
39
+ sessionName: string;
40
+ /** Whether the session was newly created */
41
+ newlyCreated: boolean;
42
+ /** Full tmux command used to create the session */
43
+ command: string;
44
+ }
45
+ /**
46
+ * Check if tmux is installed locally
47
+ */
48
+ export declare function isLocalTmuxInstalled(): Promise<boolean>;
49
+ /**
50
+ * Generate a local tmux session name for a host
51
+ * @param host - Remote host IP or hostname
52
+ * @param user - SSH user (default: "root")
53
+ * @returns Session name (e.g., "mcp-ssh-192-168-1-1")
54
+ */
55
+ export declare function generateLocalSessionName(host: string, user?: string): string;
56
+ /**
57
+ * List all local tmux sessions
58
+ * @returns Array of session names
59
+ */
60
+ export declare function listLocalSessions(): Promise<string[]>;
61
+ /**
62
+ * Check if a specific local tmux session exists
63
+ * @param sessionName - Session name to check
64
+ * @returns True if session exists
65
+ */
66
+ export declare function hasLocalSession(sessionName: string): Promise<boolean>;
67
+ /**
68
+ * Create a local tmux session with an active SSH connection
69
+ *
70
+ * This function creates a tmux session on the local machine that maintains
71
+ * an active SSH connection to the remote host. The connection stays alive
72
+ * within the tmux session, allowing for persistent interactions.
73
+ *
74
+ * @param host - Remote host IP or hostname
75
+ * @param user - SSH user (default: "root")
76
+ * @param keyPath - Path to SSH private key (for key-based auth)
77
+ * @param password - SSH password (for password-based auth)
78
+ * @param options - Additional options for session creation
79
+ * @returns Session creation result
80
+ *
81
+ * @example
82
+ * ```ts
83
+ * // Key-based authentication
84
+ * const result = await createLocalTmuxSSHSession(
85
+ * "192.168.1.100",
86
+ * "root",
87
+ * "/path/to/key"
88
+ * );
89
+ *
90
+ * // Password-based authentication (requires sshpass)
91
+ * const result = await createLocalTmuxSSHSession(
92
+ * "192.168.1.100",
93
+ * "root",
94
+ * undefined,
95
+ * "mypassword"
96
+ * );
97
+ * ```
98
+ */
99
+ export declare function createLocalTmuxSSHSession(host: string, user?: string, keyPath?: string, password?: string, options?: LocalTmuxSessionOptions): Promise<LocalTmuxSessionResult>;
100
+ /**
101
+ * Send a command to a local tmux pane (already SSH'd into the remote host)
102
+ *
103
+ * This function sends a command to the tmux pane, which will be executed
104
+ * on the remote host since the SSH connection is already active.
105
+ *
106
+ * @param sessionName - Local tmux session name
107
+ * @param command - Command to send to the remote host
108
+ * @param paneIndex - Pane index (default: "0")
109
+ * @param windowName - Window name (default: auto-detects first window)
110
+ * @returns True if command was sent successfully
111
+ */
112
+ export declare function sendCommandToLocalSession(sessionName: string, command: string, paneIndex?: string, windowName?: string): Promise<boolean>;
113
+ /**
114
+ * Capture output from a local tmux pane
115
+ *
116
+ * This captures the current visible content of the pane, including
117
+ * the scrollback history.
118
+ *
119
+ * @param sessionName - Local tmux session name
120
+ * @param paneIndex - Pane index (default: "0")
121
+ * @param windowName - Window name (default: auto-detects first window)
122
+ * @returns Captured output or null if failed
123
+ */
124
+ export declare function captureLocalPane(sessionName: string, paneIndex?: string, windowName?: string): Promise<string | null>;
125
+ /**
126
+ * Get scrollback/history from a local tmux pane
127
+ *
128
+ * @param sessionName - Local tmux session name
129
+ * @param paneIndex - Pane index (default: "0")
130
+ * @param lines - Number of lines to retrieve (default: -1 for all)
131
+ * @param windowName - Window name (default: auto-detects first window)
132
+ * @returns History content or null if failed
133
+ */
134
+ export declare function getLocalPaneHistory(sessionName: string, paneIndex?: string, lines?: number, windowName?: string): Promise<string | null>;
135
+ /**
136
+ * Kill a local tmux session
137
+ *
138
+ * @param sessionName - Session name to kill
139
+ * @returns True if session was killed successfully
140
+ */
141
+ export declare function killLocalSession(sessionName: string): Promise<boolean>;
142
+ /**
143
+ * Get information about a local tmux session
144
+ *
145
+ * @param sessionName - Session name to query
146
+ * @returns Session information or null if session doesn't exist
147
+ */
148
+ export declare function getLocalSessionInfo(sessionName: string): Promise<{
149
+ exists: boolean;
150
+ windows?: number;
151
+ panes?: number;
152
+ } | null>;
153
+ /**
154
+ * List all windows in a local tmux session
155
+ *
156
+ * @param sessionName - Local tmux session name
157
+ * @returns Array of window information
158
+ */
159
+ export declare function listLocalSessionWindows(sessionName: string): Promise<Array<{
160
+ index: string;
161
+ name: string;
162
+ active: boolean;
163
+ }>>;
164
+ /**
165
+ * List all panes in a local tmux session window
166
+ *
167
+ * @param sessionName - Local tmux session name
168
+ * @param windowIndex - Window index (default: "0")
169
+ * @returns Array of pane information
170
+ */
171
+ export declare function listLocalWindowPanes(sessionName: string, windowIndex?: string): Promise<Array<{
172
+ index: string;
173
+ currentPath: string;
174
+ pid: string;
175
+ active: boolean;
176
+ }>>;
177
+ /**
178
+ * Split a pane horizontally or vertically in a local tmux session
179
+ *
180
+ * @param sessionName - Local tmux session name
181
+ * @param direction - Split direction: "h" (horizontal) or "v" (vertical)
182
+ * @param command - Optional command to run in the new pane
183
+ * @param windowName - Window name (default: auto-detects first window)
184
+ * @returns The new pane index or null if failed
185
+ */
186
+ export declare function splitLocalPane(sessionName: string, direction?: "h" | "v", command?: string, windowName?: string): Promise<string | null>;
187
+ /**
188
+ * Cleanup old local tmux sessions
189
+ *
190
+ * @param config - Optional configuration (uses default age limit if not provided)
191
+ * @returns Object with cleaned count and errors
192
+ */
193
+ export declare function cleanupOldLocalSessions(config?: Partial<LocalTmuxConfig>): Promise<{
194
+ cleaned: number;
195
+ errors: string[];
196
+ }>;
197
+ /**
198
+ * Get resource usage information for local tmux sessions
199
+ *
200
+ * @returns Resource usage summary
201
+ */
202
+ export declare function getLocalTmuxResourceUsage(): Promise<{
203
+ totalSessions: number;
204
+ mcpSessions: number;
205
+ estimatedMemoryMB: number;
206
+ } | null>;
207
+ /**
208
+ * Wait for a specific text to appear in the pane output
209
+ *
210
+ * @param sessionName - Local tmux session name
211
+ * @param text - Text to wait for
212
+ * @param timeoutMs - Maximum time to wait in milliseconds (default: 30000)
213
+ * @param paneIndex - Pane index (default: "0")
214
+ * @param windowName - Window name (default: auto-detects first window)
215
+ * @returns True if text appeared, false if timeout
216
+ */
217
+ export declare function waitForTextInPane(sessionName: string, text: string, timeoutMs?: number, paneIndex?: string, windowName?: string): Promise<boolean>;
218
+ /**
219
+ * Switch to a specific window in a local tmux session
220
+ *
221
+ * @param sessionName - Local tmux session name
222
+ * @param windowIndex - Target window index
223
+ * @returns True if successful
224
+ */
225
+ export declare function switchLocalWindow(sessionName: string, windowIndex: string): Promise<boolean>;
226
+ /**
227
+ * Switch to a specific pane in a local tmux session window
228
+ *
229
+ * @param sessionName - Local tmux session name
230
+ * @param paneIndex - Target pane index (e.g., "0", "1", "0.1" for window.pane)
231
+ * @returns True if successful
232
+ */
233
+ export declare function switchLocalPane(sessionName: string, paneIndex: string): Promise<boolean>;
234
+ /**
235
+ * Rename a window in a local tmux session
236
+ *
237
+ * @param sessionName - Local tmux session name
238
+ * @param windowIndex - Window index (default: "0")
239
+ * @param newName - New window name
240
+ * @returns True if successful
241
+ */
242
+ export declare function renameLocalWindow(sessionName: string, windowIndex: string, newName: string): Promise<boolean>;
243
+ /**
244
+ * Kill a specific pane in a local tmux session
245
+ *
246
+ * @param sessionName - Local tmux session name
247
+ * @param paneIndex - Pane index to kill
248
+ * @param windowName - Window name (default: auto-detects first window)
249
+ * @returns True if successful
250
+ */
251
+ export declare function killLocalPane(sessionName: string, paneIndex: string, windowName?: string): Promise<boolean>;
252
+ /**
253
+ * Get detailed information about all panes in a local session
254
+ *
255
+ * @param sessionName - Local tmux session name
256
+ * @returns Detailed session information or null
257
+ */
258
+ export declare function getDetailedLocalSessionInfo(sessionName: string): Promise<{
259
+ exists: boolean;
260
+ windows: Array<{
261
+ index: string;
262
+ name: string;
263
+ active: boolean;
264
+ panes: Array<{
265
+ index: string;
266
+ currentPath: string;
267
+ pid: string;
268
+ active: boolean;
269
+ }>;
270
+ }>;
271
+ } | null>;
272
+ export {};
@@ -0,0 +1,327 @@
1
+ /**
2
+ * Multi-Node Tmux Session Manager
3
+ * Provides unified management of tmux sessions across multiple VPS nodes
4
+ * Supports batch operations, session tracking, and parallel execution
5
+ */
6
+ /**
7
+ * Represents a single node (server) in the cluster
8
+ */
9
+ export interface Node {
10
+ /** Unique identifier (server ID from Hetzner) */
11
+ id: string;
12
+ /** Server name */
13
+ name: string;
14
+ /** IPv4 address */
15
+ ip: string;
16
+ /** IPv6 address (optional) */
17
+ ipv6?: string | null;
18
+ /** SSH user */
19
+ user: string;
20
+ /** SSH port */
21
+ port: number;
22
+ /** SSH key path (optional) */
23
+ keyPath?: string;
24
+ /** Node status */
25
+ status: "running" | "stopped" | "unreachable";
26
+ /** Metadata tags */
27
+ tags?: string[];
28
+ /** Datacenter location */
29
+ location?: string;
30
+ }
31
+ /**
32
+ * Represents a tmux session on a node
33
+ */
34
+ export interface TmuxSession {
35
+ /** Session name */
36
+ name: string;
37
+ /** Node ID */
38
+ nodeId: string;
39
+ /** Number of windows */
40
+ windows?: number;
41
+ /** Number of panes */
42
+ panes?: number;
43
+ /** Session exists */
44
+ exists: boolean;
45
+ }
46
+ /**
47
+ * Detailed session information with windows and panes
48
+ */
49
+ export interface DetailedTmuxSession extends TmuxSession {
50
+ windows: Array<{
51
+ index: string;
52
+ name: string;
53
+ active: boolean;
54
+ panes: Array<{
55
+ index: string;
56
+ currentPath: string;
57
+ pid: string;
58
+ active: boolean;
59
+ }>;
60
+ }>;
61
+ }
62
+ /**
63
+ * Batch operation result across multiple nodes
64
+ */
65
+ export interface BatchOperationResult<T = any> {
66
+ /** Total nodes in batch */
67
+ total: number;
68
+ /** Successful operations */
69
+ successful: number;
70
+ /** Failed operations */
71
+ failed: number;
72
+ /** Results per node */
73
+ results: Array<{
74
+ nodeId: string;
75
+ nodeName: string;
76
+ success: boolean;
77
+ data?: T;
78
+ error?: string;
79
+ }>;
80
+ }
81
+ /**
82
+ * Options for creating a new tmux session
83
+ */
84
+ export interface CreateSessionOptions {
85
+ /** Session name (auto-generated if not provided) */
86
+ sessionName?: string;
87
+ /** Initial working directory */
88
+ cwd?: string;
89
+ /** Initial command to run */
90
+ initialCommand?: string;
91
+ /** Window layout */
92
+ layout?: "even-horizontal" | "even-vertical" | "main-horizontal" | "main-vertical" | "tiled";
93
+ }
94
+ /**
95
+ * Options for batch command execution
96
+ */
97
+ export interface BatchCommandOptions {
98
+ /** Command to execute */
99
+ command: string;
100
+ /** Target pane index (default: "0") */
101
+ paneIndex?: string;
102
+ /** Execute in parallel (default: true) */
103
+ parallel?: boolean;
104
+ /** Continue on error (default: true) */
105
+ continueOnError?: boolean;
106
+ /** Timeout per node (seconds) */
107
+ timeout?: number;
108
+ }
109
+ /**
110
+ * Options for multi-node session queries
111
+ */
112
+ export interface SessionQueryOptions {
113
+ /** Filter by node IDs */
114
+ nodeIds?: string[];
115
+ /** Filter by tags */
116
+ tags?: string[];
117
+ /** Include detailed session info */
118
+ detailed?: boolean;
119
+ /** Include inactive sessions */
120
+ includeInactive?: boolean;
121
+ }
122
+ /**
123
+ * Multi-Node Tmux Session Manager
124
+ * Manages tmux sessions across multiple VPS nodes
125
+ */
126
+ export declare class TmuxSessionManager {
127
+ private nodes;
128
+ private sessionCache;
129
+ private cacheTimeout;
130
+ private lastCacheUpdate;
131
+ /**
132
+ * Add or update a node in the manager
133
+ */
134
+ addNode(node: Node): void;
135
+ /**
136
+ * Remove a node from the manager
137
+ */
138
+ removeNode(nodeId: string): void;
139
+ /**
140
+ * Get a node by ID
141
+ */
142
+ getNode(nodeId: string): Node | undefined;
143
+ /**
144
+ * Get all nodes
145
+ */
146
+ getAllNodes(): Node[];
147
+ /**
148
+ * Get nodes by tag
149
+ */
150
+ getNodesByTag(tag: string): Node[];
151
+ /**
152
+ * Get active nodes (running and reachable)
153
+ */
154
+ getActiveNodes(): Node[];
155
+ /**
156
+ * Get SSH options for a node
157
+ */
158
+ private getSSHOptions;
159
+ /**
160
+ * Invalidate session cache for a node or all nodes
161
+ */
162
+ invalidateCache(nodeId?: string): void;
163
+ /**
164
+ * Check if cache is valid for a node
165
+ */
166
+ private isCacheValid;
167
+ /**
168
+ * Create a new tmux session on a node
169
+ */
170
+ createSession(nodeId: string, options?: CreateSessionOptions): Promise<{
171
+ success: boolean;
172
+ sessionName?: string;
173
+ error?: string;
174
+ }>;
175
+ /**
176
+ * Attach to a tmux session on a node (returns SSH command args)
177
+ */
178
+ attachSession(nodeId: string, sessionName?: string): Promise<{
179
+ success: true;
180
+ sshArgs: string[];
181
+ sessionName: string;
182
+ } | {
183
+ success: false;
184
+ error: string;
185
+ }>;
186
+ /**
187
+ * List all sessions across nodes
188
+ */
189
+ listSessions(options?: SessionQueryOptions): Promise<TmuxSession[]>;
190
+ /**
191
+ * Get detailed session information
192
+ */
193
+ getDetailedSession(nodeId: string, sessionName: string): Promise<DetailedTmuxSession | null>;
194
+ /**
195
+ * Kill a session on a node
196
+ */
197
+ killSession(nodeId: string, sessionName: string): Promise<{
198
+ success: boolean;
199
+ error?: string;
200
+ }>;
201
+ /**
202
+ * Send a command to a specific session on a node
203
+ */
204
+ sendCommand(nodeId: string, sessionName: string, command: string, paneIndex?: string): Promise<{
205
+ success: boolean;
206
+ error?: string;
207
+ }>;
208
+ /**
209
+ * Send command to multiple nodes (batch operation)
210
+ */
211
+ sendCommandToNodes(nodeIds: string[], sessionName: string, command: string, options?: BatchCommandOptions): Promise<BatchOperationResult>;
212
+ /**
213
+ * Split a pane in a session
214
+ */
215
+ splitPaneOnNode(nodeId: string, sessionName: string, direction?: "h" | "v", command?: string | null, windowIndex?: string): Promise<{
216
+ success: boolean;
217
+ newPaneIndex?: string;
218
+ error?: string;
219
+ }>;
220
+ /**
221
+ * Capture pane output from a session
222
+ */
223
+ capturePaneOutput(nodeId: string, sessionName: string, paneIndex?: string): Promise<{
224
+ success: boolean;
225
+ output?: string;
226
+ error?: string;
227
+ }>;
228
+ /**
229
+ * Get pane history (scrollback buffer)
230
+ */
231
+ getPaneHistory(nodeId: string, sessionName: string, paneIndex?: string, lines?: number): Promise<{
232
+ success: boolean;
233
+ history?: string;
234
+ error?: string;
235
+ }>;
236
+ /**
237
+ * List windows in a session
238
+ */
239
+ listWindows(nodeId: string, sessionName: string): Promise<{
240
+ success: boolean;
241
+ windows?: Array<{
242
+ index: string;
243
+ name: string;
244
+ active: boolean;
245
+ }>;
246
+ error?: string;
247
+ }>;
248
+ /**
249
+ * List panes in a window
250
+ */
251
+ listPanes(nodeId: string, sessionName: string, windowIndex?: string): Promise<{
252
+ success: boolean;
253
+ panes?: Array<{
254
+ index: string;
255
+ currentPath: string;
256
+ pid: string;
257
+ active: boolean;
258
+ }>;
259
+ error?: string;
260
+ }>;
261
+ /**
262
+ * Switch to a different window in a session
263
+ */
264
+ switchToWindow(nodeId: string, sessionName: string, windowIndex: string): Promise<{
265
+ success: boolean;
266
+ error?: string;
267
+ }>;
268
+ /**
269
+ * Switch to a different pane in a session
270
+ */
271
+ switchToPane(nodeId: string, sessionName: string, paneIndex: string): Promise<{
272
+ success: boolean;
273
+ error?: string;
274
+ }>;
275
+ /**
276
+ * Rename a window in a session
277
+ */
278
+ renameWindowInSession(nodeId: string, sessionName: string, windowIndex: string, newName: string): Promise<{
279
+ success: boolean;
280
+ error?: string;
281
+ }>;
282
+ /**
283
+ * Kill a pane in a session
284
+ */
285
+ killPaneInSession(nodeId: string, sessionName: string, paneIndex: string): Promise<{
286
+ success: boolean;
287
+ error?: string;
288
+ }>;
289
+ /**
290
+ * Cleanup old sessions on a node
291
+ */
292
+ cleanupOldSessions(nodeId: string, ageLimitMs?: number): Promise<{
293
+ success: boolean;
294
+ cleaned?: number;
295
+ errors?: string[];
296
+ }>;
297
+ /**
298
+ * Get resource usage for sessions on a node
299
+ */
300
+ getResourceUsage(nodeId: string): Promise<{
301
+ success: boolean;
302
+ usage?: {
303
+ totalSessions: number;
304
+ codespacesSessions: number;
305
+ estimatedMemoryMB: number;
306
+ };
307
+ error?: string;
308
+ }>;
309
+ /**
310
+ * Get summary statistics across all nodes
311
+ */
312
+ getSummary(): Promise<{
313
+ totalNodes: number;
314
+ activeNodes: number;
315
+ totalSessions: number;
316
+ totalMemoryUsageMB: number;
317
+ nodesWithSessions: number;
318
+ }>;
319
+ }
320
+ /**
321
+ * Get the global tmux session manager instance
322
+ */
323
+ export declare function getTmuxManager(): TmuxSessionManager;
324
+ /**
325
+ * Reset the global manager (for testing)
326
+ */
327
+ export declare function resetTmuxManager(): void;