@ellery/terminal-mcp 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +151 -5
- package/dist/index.js +51 -1
- package/dist/index.js.map +1 -1
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +8 -0
- package/dist/prompts/index.js.map +1 -1
- package/dist/server.d.ts +2 -3
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +21 -0
- package/dist/server.js.map +1 -1
- package/dist/terminal/index.d.ts +1 -1
- package/dist/terminal/index.d.ts.map +1 -1
- package/dist/terminal/manager.d.ts +66 -63
- package/dist/terminal/manager.d.ts.map +1 -1
- package/dist/terminal/manager.js +255 -101
- package/dist/terminal/manager.js.map +1 -1
- package/dist/terminal/session.d.ts +13 -0
- package/dist/terminal/session.d.ts.map +1 -1
- package/dist/terminal/session.js +116 -0
- package/dist/terminal/session.js.map +1 -1
- package/dist/tools/createSession.d.ts +44 -0
- package/dist/tools/createSession.d.ts.map +1 -0
- package/dist/tools/createSession.js +41 -0
- package/dist/tools/createSession.js.map +1 -0
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/definitions.js +8 -2
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/destroySession.d.ts +31 -0
- package/dist/tools/destroySession.d.ts.map +1 -0
- package/dist/tools/destroySession.js +32 -0
- package/dist/tools/destroySession.js.map +1 -0
- package/dist/tools/getContent.d.ts +7 -0
- package/dist/tools/getContent.d.ts.map +1 -1
- package/dist/tools/getContent.js +8 -3
- package/dist/tools/getContent.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +20 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/listSessions.d.ts +19 -0
- package/dist/tools/listSessions.d.ts.map +1 -0
- package/dist/tools/listSessions.js +23 -0
- package/dist/tools/listSessions.js.map +1 -0
- package/dist/tools/screenshot.d.ts +26 -3
- package/dist/tools/screenshot.d.ts.map +1 -1
- package/dist/tools/screenshot.js +55 -5
- package/dist/tools/screenshot.js.map +1 -1
- package/dist/tools/sendKey.d.ts +7 -0
- package/dist/tools/sendKey.d.ts.map +1 -1
- package/dist/tools/sendKey.js +7 -2
- package/dist/tools/sendKey.js.map +1 -1
- package/dist/tools/startRecording.js +1 -1
- package/dist/tools/startRecording.js.map +1 -1
- package/dist/tools/type.d.ts +7 -0
- package/dist/tools/type.d.ts.map +1 -1
- package/dist/tools/type.js +7 -2
- package/dist/tools/type.js.map +1 -1
- package/dist/utils/render.d.ts +21 -0
- package/dist/utils/render.d.ts.map +1 -0
- package/dist/utils/render.js +162 -0
- package/dist/utils/render.js.map +1 -0
- package/package.json +4 -1
- package/sandbox-permissions.png +0 -0
|
@@ -2,9 +2,6 @@ import { TerminalSession, TerminalSessionOptions, ScreenshotResult } from "./ses
|
|
|
2
2
|
import type { SandboxController } from "../sandbox/index.js";
|
|
3
3
|
import { RecordingManager } from "../recording/index.js";
|
|
4
4
|
import type { RecordingMode, RecordingFormat, RecordingMetadata } from "../recording/index.js";
|
|
5
|
-
/**
|
|
6
|
-
* Options for creating a TerminalManager
|
|
7
|
-
*/
|
|
8
5
|
export interface TerminalManagerOptions extends TerminalSessionOptions {
|
|
9
6
|
sandboxController?: SandboxController;
|
|
10
7
|
record?: RecordingMode;
|
|
@@ -13,97 +10,103 @@ export interface TerminalManagerOptions extends TerminalSessionOptions {
|
|
|
13
10
|
idleTimeLimit?: number;
|
|
14
11
|
maxDuration?: number;
|
|
15
12
|
inactivityTimeout?: number;
|
|
13
|
+
maxSessions?: number;
|
|
14
|
+
sessionIdleTimeout?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface CreateSessionOptions {
|
|
17
|
+
shell?: string;
|
|
18
|
+
cols?: number;
|
|
19
|
+
rows?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface SessionMetadata {
|
|
22
|
+
sessionId: string;
|
|
23
|
+
shell: string;
|
|
24
|
+
cols: number;
|
|
25
|
+
rows: number;
|
|
26
|
+
createdAt: string;
|
|
27
|
+
lastActivityAt: string;
|
|
28
|
+
isDefault: boolean;
|
|
16
29
|
}
|
|
17
30
|
/**
|
|
18
|
-
* Manages
|
|
19
|
-
*
|
|
31
|
+
* Manages one or more terminal sessions in a single process.
|
|
32
|
+
*
|
|
33
|
+
* The "default" session is created lazily on first access and is never
|
|
34
|
+
* idle-evicted; it's what the existing single-session API operates on
|
|
35
|
+
* when no sessionId is passed. Additional sessions can be created via
|
|
36
|
+
* createSession() and addressed by ID.
|
|
20
37
|
*/
|
|
21
38
|
export declare class TerminalManager {
|
|
22
|
-
private
|
|
23
|
-
private
|
|
39
|
+
private sessions;
|
|
40
|
+
private defaultSessionId;
|
|
41
|
+
private defaultSessionPromise;
|
|
42
|
+
private idleCheckInterval;
|
|
24
43
|
private options;
|
|
25
44
|
private sandboxController?;
|
|
26
45
|
private recordingManager;
|
|
27
46
|
private autoRecordingId;
|
|
47
|
+
private maxSessions;
|
|
48
|
+
private sessionIdleTimeoutMs;
|
|
28
49
|
constructor(options?: TerminalManagerOptions);
|
|
50
|
+
private generateSessionId;
|
|
51
|
+
private touchSession;
|
|
52
|
+
private cleanupIdleSessions;
|
|
29
53
|
/**
|
|
30
|
-
*
|
|
54
|
+
* Wire recording hooks onto a session so its output is captured by any
|
|
55
|
+
* active recordings.
|
|
31
56
|
*/
|
|
32
|
-
|
|
57
|
+
private wireRecording;
|
|
33
58
|
/**
|
|
34
|
-
* Get the
|
|
35
|
-
* Returns null if no session exists yet
|
|
59
|
+
* Get or create the default session. Idempotent and concurrency-safe.
|
|
36
60
|
*/
|
|
61
|
+
getSessionAsync(): Promise<TerminalSession>;
|
|
37
62
|
getCurrentSession(): TerminalSession | null;
|
|
38
63
|
/**
|
|
39
|
-
* @deprecated Use getSessionAsync()
|
|
40
|
-
*
|
|
64
|
+
* @deprecated Use getSessionAsync(). Throws if the default session
|
|
65
|
+
* hasn't been created yet.
|
|
41
66
|
*/
|
|
42
67
|
getSession(): TerminalSession;
|
|
43
|
-
/**
|
|
44
|
-
* Initialize the session eagerly
|
|
45
|
-
* Call this at startup to create the session before it's needed
|
|
46
|
-
*/
|
|
47
68
|
initSession(): Promise<TerminalSession>;
|
|
48
|
-
/**
|
|
49
|
-
* Start auto-recording based on CLI options
|
|
50
|
-
*/
|
|
51
69
|
private startAutoRecording;
|
|
52
70
|
/**
|
|
53
|
-
*
|
|
71
|
+
* Create a new non-default session.
|
|
54
72
|
*/
|
|
55
|
-
|
|
73
|
+
createSession(opts?: CreateSessionOptions): Promise<SessionMetadata>;
|
|
74
|
+
destroySession(sessionId: string): {
|
|
75
|
+
success: boolean;
|
|
76
|
+
message: string;
|
|
77
|
+
};
|
|
78
|
+
listSessions(): {
|
|
79
|
+
sessions: SessionMetadata[];
|
|
80
|
+
maxSessions: number;
|
|
81
|
+
sessionIdleTimeout: number;
|
|
82
|
+
};
|
|
56
83
|
/**
|
|
57
|
-
*
|
|
58
|
-
*
|
|
84
|
+
* Resolve a session by ID. If sessionId is omitted/undefined, returns the
|
|
85
|
+
* default session (creating it if needed).
|
|
59
86
|
*/
|
|
60
|
-
|
|
87
|
+
resolveSession(sessionId?: string): Promise<TerminalSession>;
|
|
61
88
|
/**
|
|
62
|
-
*
|
|
89
|
+
* Synchronous variant of resolveSession() — requires the session to
|
|
90
|
+
* already exist. Throws if not created yet (used by sync tool handlers).
|
|
63
91
|
*/
|
|
92
|
+
resolveSessionSync(sessionId?: string): TerminalSession;
|
|
64
93
|
hasActiveSession(): boolean;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
* Get visible content only
|
|
75
|
-
*/
|
|
76
|
-
getVisibleContent(): string;
|
|
77
|
-
/**
|
|
78
|
-
* Take a screenshot
|
|
79
|
-
*/
|
|
80
|
-
takeScreenshot(): ScreenshotResult;
|
|
81
|
-
/**
|
|
82
|
-
* Clear the terminal
|
|
83
|
-
*/
|
|
84
|
-
clear(): void;
|
|
85
|
-
/**
|
|
86
|
-
* Resize the terminal
|
|
87
|
-
*/
|
|
88
|
-
resize(cols: number, rows: number): void;
|
|
89
|
-
/**
|
|
90
|
-
* Get terminal dimensions
|
|
91
|
-
*/
|
|
92
|
-
getDimensions(): {
|
|
94
|
+
write(data: string, sessionId?: string): void;
|
|
95
|
+
getContent(sessionId?: string): string;
|
|
96
|
+
getVisibleContent(sessionId?: string): string;
|
|
97
|
+
getAnsiContent(visibleOnly?: boolean, sessionId?: string): string;
|
|
98
|
+
getTerminal(sessionId?: string): import("@xterm/headless").Terminal;
|
|
99
|
+
takeScreenshot(sessionId?: string): ScreenshotResult;
|
|
100
|
+
clear(sessionId?: string): void;
|
|
101
|
+
resize(cols: number, rows: number, sessionId?: string): void;
|
|
102
|
+
getDimensions(sessionId?: string): {
|
|
93
103
|
cols: number;
|
|
94
104
|
rows: number;
|
|
95
105
|
};
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
*/
|
|
106
|
+
getRecordingManager(): RecordingManager;
|
|
107
|
+
finalizeRecordings(exitCode: number): Promise<RecordingMetadata[]>;
|
|
99
108
|
dispose(): void;
|
|
100
|
-
/**
|
|
101
|
-
* Async dispose that also cleans up sandbox resources
|
|
102
|
-
*/
|
|
103
109
|
disposeAsync(): Promise<void>;
|
|
104
|
-
/**
|
|
105
|
-
* Get the sandbox controller if one is configured
|
|
106
|
-
*/
|
|
107
110
|
getSandboxController(): SandboxController | undefined;
|
|
108
111
|
}
|
|
109
112
|
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/terminal/manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/terminal/manager.ts"],"names":[],"mappings":"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"}
|
package/dist/terminal/manager.js
CHANGED
|
@@ -1,17 +1,28 @@
|
|
|
1
|
+
import { randomBytes } from "crypto";
|
|
1
2
|
import { TerminalSession } from "./session.js";
|
|
2
3
|
import { RecordingManager } from "../recording/index.js";
|
|
3
4
|
import { getDefaultRecordDir } from "../utils/platform.js";
|
|
5
|
+
const DEFAULT_MAX_SESSIONS = 5;
|
|
6
|
+
const DEFAULT_SESSION_IDLE_TIMEOUT = 600; // 10 minutes
|
|
4
7
|
/**
|
|
5
|
-
* Manages
|
|
6
|
-
*
|
|
8
|
+
* Manages one or more terminal sessions in a single process.
|
|
9
|
+
*
|
|
10
|
+
* The "default" session is created lazily on first access and is never
|
|
11
|
+
* idle-evicted; it's what the existing single-session API operates on
|
|
12
|
+
* when no sessionId is passed. Additional sessions can be created via
|
|
13
|
+
* createSession() and addressed by ID.
|
|
7
14
|
*/
|
|
8
15
|
export class TerminalManager {
|
|
9
|
-
|
|
10
|
-
|
|
16
|
+
sessions = new Map();
|
|
17
|
+
defaultSessionId = null;
|
|
18
|
+
defaultSessionPromise = null;
|
|
19
|
+
idleCheckInterval = null;
|
|
11
20
|
options;
|
|
12
21
|
sandboxController;
|
|
13
22
|
recordingManager;
|
|
14
23
|
autoRecordingId = null;
|
|
24
|
+
maxSessions;
|
|
25
|
+
sessionIdleTimeoutMs;
|
|
15
26
|
constructor(options = {}) {
|
|
16
27
|
this.options = options;
|
|
17
28
|
this.sandboxController = options.sandboxController;
|
|
@@ -23,73 +34,128 @@ export class TerminalManager {
|
|
|
23
34
|
maxDuration: options.maxDuration ?? 3600,
|
|
24
35
|
inactivityTimeout: options.inactivityTimeout ?? 600,
|
|
25
36
|
});
|
|
37
|
+
this.maxSessions = options.maxSessions ?? DEFAULT_MAX_SESSIONS;
|
|
38
|
+
this.sessionIdleTimeoutMs = (options.sessionIdleTimeout ?? DEFAULT_SESSION_IDLE_TIMEOUT) * 1000;
|
|
39
|
+
// Periodic idle cleanup for non-default sessions
|
|
40
|
+
this.idleCheckInterval = setInterval(() => this.cleanupIdleSessions(), 60 * 1000);
|
|
41
|
+
this.idleCheckInterval.unref();
|
|
42
|
+
}
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// Session lookup helpers
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
generateSessionId() {
|
|
47
|
+
while (true) {
|
|
48
|
+
const id = randomBytes(3).toString("hex").slice(0, 5);
|
|
49
|
+
if (!this.sessions.has(id))
|
|
50
|
+
return id;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
touchSession(sessionId) {
|
|
54
|
+
const entry = this.sessions.get(sessionId);
|
|
55
|
+
if (entry) {
|
|
56
|
+
entry.lastActivity = Date.now();
|
|
57
|
+
entry.metadata.lastActivityAt = new Date().toISOString();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
cleanupIdleSessions() {
|
|
61
|
+
const now = Date.now();
|
|
62
|
+
// Snapshot to avoid mutation-during-iteration
|
|
63
|
+
for (const [sessionId, entry] of Array.from(this.sessions.entries())) {
|
|
64
|
+
if (entry.isDefault)
|
|
65
|
+
continue;
|
|
66
|
+
if (now - entry.lastActivity > this.sessionIdleTimeoutMs) {
|
|
67
|
+
entry.session.dispose();
|
|
68
|
+
this.sessions.delete(sessionId);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
26
71
|
}
|
|
27
72
|
/**
|
|
28
|
-
*
|
|
73
|
+
* Wire recording hooks onto a session so its output is captured by any
|
|
74
|
+
* active recordings.
|
|
75
|
+
*/
|
|
76
|
+
wireRecording(session) {
|
|
77
|
+
session.onData((data) => this.recordingManager.recordOutputToAll(data));
|
|
78
|
+
session.onResize((cols, rows) => this.recordingManager.recordResizeToAll(cols, rows));
|
|
79
|
+
}
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
// Default session (single-session API surface)
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
/**
|
|
84
|
+
* Get or create the default session. Idempotent and concurrency-safe.
|
|
29
85
|
*/
|
|
30
86
|
async getSessionAsync() {
|
|
31
|
-
if (this.
|
|
32
|
-
|
|
87
|
+
if (this.defaultSessionId) {
|
|
88
|
+
const entry = this.sessions.get(this.defaultSessionId);
|
|
89
|
+
if (entry && entry.session.isActive()) {
|
|
90
|
+
this.touchSession(this.defaultSessionId);
|
|
91
|
+
return entry.session;
|
|
92
|
+
}
|
|
93
|
+
this.defaultSessionId = null;
|
|
33
94
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return this.sessionPromise;
|
|
95
|
+
if (this.defaultSessionPromise) {
|
|
96
|
+
return this.defaultSessionPromise;
|
|
37
97
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
98
|
+
this.defaultSessionPromise = (async () => {
|
|
99
|
+
const session = await TerminalSession.create({
|
|
100
|
+
...this.options,
|
|
101
|
+
sandboxController: this.sandboxController,
|
|
102
|
+
});
|
|
103
|
+
const id = this.generateSessionId();
|
|
104
|
+
const dims = session.getDimensions();
|
|
105
|
+
const now = new Date().toISOString();
|
|
106
|
+
const entry = {
|
|
107
|
+
session,
|
|
108
|
+
metadata: {
|
|
109
|
+
sessionId: id,
|
|
110
|
+
shell: this.options.shell ?? process.env.SHELL ?? "/bin/bash",
|
|
111
|
+
cols: dims.cols,
|
|
112
|
+
rows: dims.rows,
|
|
113
|
+
createdAt: now,
|
|
114
|
+
lastActivityAt: now,
|
|
115
|
+
isDefault: true,
|
|
116
|
+
},
|
|
117
|
+
lastActivity: Date.now(),
|
|
118
|
+
isDefault: true,
|
|
119
|
+
};
|
|
120
|
+
this.sessions.set(id, entry);
|
|
121
|
+
this.defaultSessionId = id;
|
|
122
|
+
this.wireRecording(session);
|
|
123
|
+
return session;
|
|
124
|
+
})();
|
|
43
125
|
try {
|
|
44
|
-
|
|
45
|
-
return this.session;
|
|
126
|
+
return await this.defaultSessionPromise;
|
|
46
127
|
}
|
|
47
128
|
finally {
|
|
48
|
-
this.
|
|
129
|
+
this.defaultSessionPromise = null;
|
|
49
130
|
}
|
|
50
131
|
}
|
|
51
|
-
/**
|
|
52
|
-
* Get the current session if it exists and is active
|
|
53
|
-
* Returns null if no session exists yet
|
|
54
|
-
*/
|
|
55
132
|
getCurrentSession() {
|
|
56
|
-
if (this.
|
|
57
|
-
return
|
|
58
|
-
|
|
59
|
-
return null;
|
|
133
|
+
if (!this.defaultSessionId)
|
|
134
|
+
return null;
|
|
135
|
+
const entry = this.sessions.get(this.defaultSessionId);
|
|
136
|
+
return entry && entry.session.isActive() ? entry.session : null;
|
|
60
137
|
}
|
|
61
138
|
/**
|
|
62
|
-
* @deprecated Use getSessionAsync()
|
|
63
|
-
*
|
|
139
|
+
* @deprecated Use getSessionAsync(). Throws if the default session
|
|
140
|
+
* hasn't been created yet.
|
|
64
141
|
*/
|
|
65
142
|
getSession() {
|
|
66
|
-
|
|
143
|
+
const session = this.getCurrentSession();
|
|
144
|
+
if (!session) {
|
|
67
145
|
throw new Error("Session not initialized. Use getSessionAsync() or call initSession() first.");
|
|
68
146
|
}
|
|
69
|
-
return
|
|
147
|
+
return session;
|
|
70
148
|
}
|
|
71
|
-
/**
|
|
72
|
-
* Initialize the session eagerly
|
|
73
|
-
* Call this at startup to create the session before it's needed
|
|
74
|
-
*/
|
|
75
149
|
async initSession() {
|
|
76
150
|
const session = await this.getSessionAsync();
|
|
77
|
-
// Wire up recording hooks
|
|
78
|
-
session.onData((data) => this.recordingManager.recordOutputToAll(data));
|
|
79
|
-
session.onResize((cols, rows) => this.recordingManager.recordResizeToAll(cols, rows));
|
|
80
|
-
// Start auto-recording if CLI mode !== 'off'
|
|
81
151
|
if (this.options.record && this.options.record !== 'off') {
|
|
82
152
|
this.startAutoRecording();
|
|
83
153
|
}
|
|
84
154
|
return session;
|
|
85
155
|
}
|
|
86
|
-
/**
|
|
87
|
-
* Start auto-recording based on CLI options
|
|
88
|
-
*/
|
|
89
156
|
startAutoRecording() {
|
|
90
|
-
if (this.autoRecordingId)
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
157
|
+
if (this.autoRecordingId)
|
|
158
|
+
return;
|
|
93
159
|
const recorder = this.recordingManager.createRecording({
|
|
94
160
|
mode: this.options.record,
|
|
95
161
|
outputDir: this.options.recordDir ?? getDefaultRecordDir(),
|
|
@@ -98,95 +164,183 @@ export class TerminalManager {
|
|
|
98
164
|
maxDuration: this.options.maxDuration ?? 3600,
|
|
99
165
|
inactivityTimeout: this.options.inactivityTimeout ?? 600,
|
|
100
166
|
});
|
|
101
|
-
const
|
|
167
|
+
const session = this.getCurrentSession();
|
|
168
|
+
const dimensions = session?.getDimensions() ?? { cols: 120, rows: 40 };
|
|
102
169
|
recorder.start(dimensions.cols, dimensions.rows, {
|
|
103
170
|
SHELL: this.options.shell ?? process.env.SHELL,
|
|
104
171
|
TERM: 'xterm-256color',
|
|
105
172
|
});
|
|
106
173
|
this.autoRecordingId = recorder.id;
|
|
107
174
|
}
|
|
175
|
+
// ---------------------------------------------------------------------------
|
|
176
|
+
// Multi-session API
|
|
177
|
+
// ---------------------------------------------------------------------------
|
|
108
178
|
/**
|
|
109
|
-
*
|
|
179
|
+
* Create a new non-default session.
|
|
110
180
|
*/
|
|
111
|
-
|
|
112
|
-
|
|
181
|
+
async createSession(opts = {}) {
|
|
182
|
+
if (this.sessions.size >= this.maxSessions) {
|
|
183
|
+
throw new Error(`Maximum session limit reached (${this.maxSessions}). ` +
|
|
184
|
+
`Destroy an existing session or raise --max-sessions.`);
|
|
185
|
+
}
|
|
186
|
+
const id = this.generateSessionId();
|
|
187
|
+
const session = await TerminalSession.create({
|
|
188
|
+
...this.options,
|
|
189
|
+
shell: opts.shell ?? this.options.shell,
|
|
190
|
+
cols: opts.cols ?? this.options.cols,
|
|
191
|
+
rows: opts.rows ?? this.options.rows,
|
|
192
|
+
// Created sessions don't share the interactive startup banner
|
|
193
|
+
startupBanner: undefined,
|
|
194
|
+
sandboxController: this.sandboxController,
|
|
195
|
+
});
|
|
196
|
+
const dims = session.getDimensions();
|
|
197
|
+
const now = new Date().toISOString();
|
|
198
|
+
const metadata = {
|
|
199
|
+
sessionId: id,
|
|
200
|
+
shell: opts.shell ?? this.options.shell ?? process.env.SHELL ?? "/bin/bash",
|
|
201
|
+
cols: dims.cols,
|
|
202
|
+
rows: dims.rows,
|
|
203
|
+
createdAt: now,
|
|
204
|
+
lastActivityAt: now,
|
|
205
|
+
isDefault: false,
|
|
206
|
+
};
|
|
207
|
+
this.sessions.set(id, {
|
|
208
|
+
session,
|
|
209
|
+
metadata,
|
|
210
|
+
lastActivity: Date.now(),
|
|
211
|
+
isDefault: false,
|
|
212
|
+
});
|
|
213
|
+
this.wireRecording(session);
|
|
214
|
+
return metadata;
|
|
215
|
+
}
|
|
216
|
+
destroySession(sessionId) {
|
|
217
|
+
const entry = this.sessions.get(sessionId);
|
|
218
|
+
if (!entry) {
|
|
219
|
+
return { success: false, message: `Session '${sessionId}' not found` };
|
|
220
|
+
}
|
|
221
|
+
if (entry.isDefault) {
|
|
222
|
+
return {
|
|
223
|
+
success: false,
|
|
224
|
+
message: `Session '${sessionId}' is the default session and cannot be destroyed`,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
entry.session.dispose();
|
|
228
|
+
this.sessions.delete(sessionId);
|
|
229
|
+
return { success: true, message: `Session '${sessionId}' destroyed` };
|
|
230
|
+
}
|
|
231
|
+
listSessions() {
|
|
232
|
+
const sessions = [];
|
|
233
|
+
for (const [sessionId, entry] of Array.from(this.sessions.entries())) {
|
|
234
|
+
if (entry.session.isActive()) {
|
|
235
|
+
sessions.push({ ...entry.metadata });
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
this.sessions.delete(sessionId);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
sessions,
|
|
243
|
+
maxSessions: this.maxSessions,
|
|
244
|
+
sessionIdleTimeout: this.sessionIdleTimeoutMs / 1000,
|
|
245
|
+
};
|
|
113
246
|
}
|
|
114
247
|
/**
|
|
115
|
-
*
|
|
116
|
-
*
|
|
248
|
+
* Resolve a session by ID. If sessionId is omitted/undefined, returns the
|
|
249
|
+
* default session (creating it if needed).
|
|
117
250
|
*/
|
|
118
|
-
async
|
|
119
|
-
|
|
251
|
+
async resolveSession(sessionId) {
|
|
252
|
+
if (!sessionId) {
|
|
253
|
+
return this.getSessionAsync();
|
|
254
|
+
}
|
|
255
|
+
const entry = this.sessions.get(sessionId);
|
|
256
|
+
if (!entry) {
|
|
257
|
+
throw new Error(`Session '${sessionId}' not found`);
|
|
258
|
+
}
|
|
259
|
+
if (!entry.session.isActive()) {
|
|
260
|
+
this.sessions.delete(sessionId);
|
|
261
|
+
throw new Error(`Session '${sessionId}' is no longer active`);
|
|
262
|
+
}
|
|
263
|
+
this.touchSession(sessionId);
|
|
264
|
+
return entry.session;
|
|
120
265
|
}
|
|
121
266
|
/**
|
|
122
|
-
*
|
|
267
|
+
* Synchronous variant of resolveSession() — requires the session to
|
|
268
|
+
* already exist. Throws if not created yet (used by sync tool handlers).
|
|
123
269
|
*/
|
|
270
|
+
resolveSessionSync(sessionId) {
|
|
271
|
+
if (!sessionId) {
|
|
272
|
+
return this.getSession();
|
|
273
|
+
}
|
|
274
|
+
const entry = this.sessions.get(sessionId);
|
|
275
|
+
if (!entry) {
|
|
276
|
+
throw new Error(`Session '${sessionId}' not found`);
|
|
277
|
+
}
|
|
278
|
+
if (!entry.session.isActive()) {
|
|
279
|
+
this.sessions.delete(sessionId);
|
|
280
|
+
throw new Error(`Session '${sessionId}' is no longer active`);
|
|
281
|
+
}
|
|
282
|
+
this.touchSession(sessionId);
|
|
283
|
+
return entry.session;
|
|
284
|
+
}
|
|
285
|
+
// ---------------------------------------------------------------------------
|
|
286
|
+
// Single-session shortcuts (now sessionId-aware)
|
|
287
|
+
// ---------------------------------------------------------------------------
|
|
124
288
|
hasActiveSession() {
|
|
125
|
-
return this.
|
|
289
|
+
return this.getCurrentSession() !== null;
|
|
126
290
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
*/
|
|
130
|
-
write(data) {
|
|
131
|
-
this.getSession().write(data);
|
|
291
|
+
write(data, sessionId) {
|
|
292
|
+
this.resolveSessionSync(sessionId).write(data);
|
|
132
293
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
*/
|
|
136
|
-
getContent() {
|
|
137
|
-
return this.getSession().getContent();
|
|
294
|
+
getContent(sessionId) {
|
|
295
|
+
return this.resolveSessionSync(sessionId).getContent();
|
|
138
296
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
*/
|
|
142
|
-
getVisibleContent() {
|
|
143
|
-
return this.getSession().getVisibleContent();
|
|
297
|
+
getVisibleContent(sessionId) {
|
|
298
|
+
return this.resolveSessionSync(sessionId).getVisibleContent();
|
|
144
299
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
*/
|
|
148
|
-
takeScreenshot() {
|
|
149
|
-
return this.getSession().takeScreenshot();
|
|
300
|
+
getAnsiContent(visibleOnly = false, sessionId) {
|
|
301
|
+
return this.resolveSessionSync(sessionId).getAnsiContent(visibleOnly);
|
|
150
302
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
*/
|
|
154
|
-
clear() {
|
|
155
|
-
this.getSession().clear();
|
|
303
|
+
getTerminal(sessionId) {
|
|
304
|
+
return this.resolveSessionSync(sessionId).getTerminal();
|
|
156
305
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
*/
|
|
160
|
-
resize(cols, rows) {
|
|
161
|
-
this.getSession().resize(cols, rows);
|
|
306
|
+
takeScreenshot(sessionId) {
|
|
307
|
+
return this.resolveSessionSync(sessionId).takeScreenshot();
|
|
162
308
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
309
|
+
clear(sessionId) {
|
|
310
|
+
this.resolveSessionSync(sessionId).clear();
|
|
311
|
+
}
|
|
312
|
+
resize(cols, rows, sessionId) {
|
|
313
|
+
this.resolveSessionSync(sessionId).resize(cols, rows);
|
|
314
|
+
}
|
|
315
|
+
getDimensions(sessionId) {
|
|
316
|
+
return this.resolveSessionSync(sessionId).getDimensions();
|
|
317
|
+
}
|
|
318
|
+
// ---------------------------------------------------------------------------
|
|
319
|
+
// Recording / lifecycle
|
|
320
|
+
// ---------------------------------------------------------------------------
|
|
321
|
+
getRecordingManager() {
|
|
322
|
+
return this.recordingManager;
|
|
323
|
+
}
|
|
324
|
+
async finalizeRecordings(exitCode) {
|
|
325
|
+
return this.recordingManager.finalizeAll(exitCode);
|
|
168
326
|
}
|
|
169
|
-
/**
|
|
170
|
-
* Dispose of the current session and cleanup sandbox
|
|
171
|
-
*/
|
|
172
327
|
dispose() {
|
|
173
|
-
if (this.
|
|
174
|
-
this.
|
|
175
|
-
this.
|
|
328
|
+
if (this.idleCheckInterval) {
|
|
329
|
+
clearInterval(this.idleCheckInterval);
|
|
330
|
+
this.idleCheckInterval = null;
|
|
331
|
+
}
|
|
332
|
+
for (const [, entry] of this.sessions) {
|
|
333
|
+
entry.session.dispose();
|
|
176
334
|
}
|
|
335
|
+
this.sessions.clear();
|
|
336
|
+
this.defaultSessionId = null;
|
|
177
337
|
}
|
|
178
|
-
/**
|
|
179
|
-
* Async dispose that also cleans up sandbox resources
|
|
180
|
-
*/
|
|
181
338
|
async disposeAsync() {
|
|
182
339
|
this.dispose();
|
|
183
340
|
if (this.sandboxController) {
|
|
184
341
|
await this.sandboxController.cleanup();
|
|
185
342
|
}
|
|
186
343
|
}
|
|
187
|
-
/**
|
|
188
|
-
* Get the sandbox controller if one is configured
|
|
189
|
-
*/
|
|
190
344
|
getSandboxController() {
|
|
191
345
|
return this.sandboxController;
|
|
192
346
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/terminal/manager.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/terminal/manager.ts"],"names":[],"mappings":"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"}
|