brosh 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +181 -0
- package/brosh_brandmark.svg +3 -0
- package/brosh_logo.svg +27 -0
- package/cli_icon.svg +52 -0
- package/dist/client.d.ts +5 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +138 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +618 -0
- package/dist/index.js.map +1 -0
- package/dist/lib.d.ts +25 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +28 -0
- package/dist/lib.js.map +1 -0
- package/dist/mode-selector.d.ts +7 -0
- package/dist/mode-selector.d.ts.map +1 -0
- package/dist/mode-selector.js +138 -0
- package/dist/mode-selector.js.map +1 -0
- package/dist/prompts/index.d.ts +3 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +79 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/recording/index.d.ts +4 -0
- package/dist/recording/index.d.ts.map +1 -0
- package/dist/recording/index.js +3 -0
- package/dist/recording/index.js.map +1 -0
- package/dist/recording/manager.d.ts +62 -0
- package/dist/recording/manager.d.ts.map +1 -0
- package/dist/recording/manager.js +123 -0
- package/dist/recording/manager.js.map +1 -0
- package/dist/recording/recorder.d.ts +95 -0
- package/dist/recording/recorder.d.ts.map +1 -0
- package/dist/recording/recorder.js +330 -0
- package/dist/recording/recorder.js.map +1 -0
- package/dist/recording/types.d.ts +65 -0
- package/dist/recording/types.d.ts.map +1 -0
- package/dist/recording/types.js +2 -0
- package/dist/recording/types.js.map +1 -0
- package/dist/sandbox/ModeSelector.d.ts +2 -0
- package/dist/sandbox/ModeSelector.d.ts.map +1 -0
- package/dist/sandbox/ModeSelector.js +2 -0
- package/dist/sandbox/ModeSelector.js.map +1 -0
- package/dist/sandbox/config.d.ts +46 -0
- package/dist/sandbox/config.d.ts.map +1 -0
- package/dist/sandbox/config.js +144 -0
- package/dist/sandbox/config.js.map +1 -0
- package/dist/sandbox/controller.d.ts +72 -0
- package/dist/sandbox/controller.d.ts.map +1 -0
- package/dist/sandbox/controller.js +208 -0
- package/dist/sandbox/controller.js.map +1 -0
- package/dist/sandbox/index.d.ts +6 -0
- package/dist/sandbox/index.d.ts.map +1 -0
- package/dist/sandbox/index.js +4 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/sandbox/mode-prompt.d.ts +10 -0
- package/dist/sandbox/mode-prompt.d.ts.map +1 -0
- package/dist/sandbox/mode-prompt.js +130 -0
- package/dist/sandbox/mode-prompt.js.map +1 -0
- package/dist/sandbox/prompt.d.ts +10 -0
- package/dist/sandbox/prompt.d.ts.map +1 -0
- package/dist/sandbox/prompt.js +434 -0
- package/dist/sandbox/prompt.js.map +1 -0
- package/dist/server.d.ts +28 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +59 -0
- package/dist/server.js.map +1 -0
- package/dist/terminal/index.d.ts +5 -0
- package/dist/terminal/index.d.ts.map +1 -0
- package/dist/terminal/index.js +3 -0
- package/dist/terminal/index.js.map +1 -0
- package/dist/terminal/manager.d.ts +153 -0
- package/dist/terminal/manager.d.ts.map +1 -0
- package/dist/terminal/manager.js +276 -0
- package/dist/terminal/manager.js.map +1 -0
- package/dist/terminal/session.d.ts +137 -0
- package/dist/terminal/session.d.ts.map +1 -0
- package/dist/terminal/session.js +752 -0
- package/dist/terminal/session.js.map +1 -0
- package/dist/tools/definitions.d.ts +18 -0
- package/dist/tools/definitions.d.ts.map +1 -0
- package/dist/tools/definitions.js +114 -0
- package/dist/tools/definitions.js.map +1 -0
- package/dist/tools/getContent.d.ts +32 -0
- package/dist/tools/getContent.d.ts.map +1 -0
- package/dist/tools/getContent.js +38 -0
- package/dist/tools/getContent.js.map +1 -0
- package/dist/tools/index.d.ts +4 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +49 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/screenshot.d.ts +20 -0
- package/dist/tools/screenshot.d.ts.map +1 -0
- package/dist/tools/screenshot.js +28 -0
- package/dist/tools/screenshot.js.map +1 -0
- package/dist/tools/sendKey.d.ts +31 -0
- package/dist/tools/sendKey.d.ts.map +1 -0
- package/dist/tools/sendKey.js +38 -0
- package/dist/tools/sendKey.js.map +1 -0
- package/dist/tools/startRecording.d.ts +68 -0
- package/dist/tools/startRecording.d.ts.map +1 -0
- package/dist/tools/startRecording.js +111 -0
- package/dist/tools/startRecording.js.map +1 -0
- package/dist/tools/stopRecording.d.ts +31 -0
- package/dist/tools/stopRecording.d.ts.map +1 -0
- package/dist/tools/stopRecording.js +76 -0
- package/dist/tools/stopRecording.js.map +1 -0
- package/dist/tools/type.d.ts +31 -0
- package/dist/tools/type.d.ts.map +1 -0
- package/dist/tools/type.js +31 -0
- package/dist/tools/type.js.map +1 -0
- package/dist/transport/gui-protocol.d.ts +163 -0
- package/dist/transport/gui-protocol.d.ts.map +1 -0
- package/dist/transport/gui-protocol.js +68 -0
- package/dist/transport/gui-protocol.js.map +1 -0
- package/dist/transport/gui-stream.d.ts +139 -0
- package/dist/transport/gui-stream.d.ts.map +1 -0
- package/dist/transport/gui-stream.js +440 -0
- package/dist/transport/gui-stream.js.map +1 -0
- package/dist/transport/index.d.ts +6 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +6 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/socket.d.ts +46 -0
- package/dist/transport/socket.d.ts.map +1 -0
- package/dist/transport/socket.js +310 -0
- package/dist/transport/socket.js.map +1 -0
- package/dist/types/mcp-client-info.d.ts +226 -0
- package/dist/types/mcp-client-info.d.ts.map +1 -0
- package/dist/types/mcp-client-info.js +62 -0
- package/dist/types/mcp-client-info.js.map +1 -0
- package/dist/ui/index.d.ts +12 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +84 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/utils/env.d.ts +17 -0
- package/dist/utils/env.d.ts.map +1 -0
- package/dist/utils/env.js +35 -0
- package/dist/utils/env.js.map +1 -0
- package/dist/utils/keys.d.ts +16 -0
- package/dist/utils/keys.d.ts.map +1 -0
- package/dist/utils/keys.js +155 -0
- package/dist/utils/keys.js.map +1 -0
- package/dist/utils/platform.d.ts +16 -0
- package/dist/utils/platform.d.ts.map +1 -0
- package/dist/utils/platform.js +41 -0
- package/dist/utils/platform.js.map +1 -0
- package/dist/utils/session-logger.d.ts +31 -0
- package/dist/utils/session-logger.d.ts.map +1 -0
- package/dist/utils/session-logger.js +125 -0
- package/dist/utils/session-logger.js.map +1 -0
- package/dist/utils/stats.d.ts +46 -0
- package/dist/utils/stats.d.ts.map +1 -0
- package/dist/utils/stats.js +89 -0
- package/dist/utils/stats.js.map +1 -0
- package/dist/utils/version.d.ts +2 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +9 -0
- package/dist/utils/version.js.map +1 -0
- package/logo.png +0 -0
- package/package.json +61 -0
- package/packages/desktop-electron/THIRD-PARTY-NOTICES +56 -0
- package/packages/desktop-electron/build/afterPack.cjs +147 -0
- package/packages/desktop-electron/package-lock.json +10071 -0
- package/packages/desktop-electron/package.json +170 -0
- package/packages/desktop-electron/resources/icons/mac/icon.icns +0 -0
- package/packages/desktop-electron/resources/icons/png/1024x1024.png +0 -0
- package/packages/desktop-electron/resources/icons/png/128x128.png +0 -0
- package/packages/desktop-electron/resources/icons/png/16x16.png +0 -0
- package/packages/desktop-electron/resources/icons/png/24x24.png +0 -0
- package/packages/desktop-electron/resources/icons/png/256x256.png +0 -0
- package/packages/desktop-electron/resources/icons/png/32x32.png +0 -0
- package/packages/desktop-electron/resources/icons/png/48x48.png +0 -0
- package/packages/desktop-electron/resources/icons/png/512x512.png +0 -0
- package/packages/desktop-electron/resources/icons/png/64x64.png +0 -0
- package/packages/desktop-electron/resources/icons/win/icon.ico +0 -0
- package/packages/desktop-electron/scripts/download-models.js +97 -0
- package/packages/desktop-electron/scripts/prepare-sandbox-bins.js +186 -0
- package/packages/desktop-electron/tests/main/ai-detection/additionalFunctions.test.ts +224 -0
- package/packages/desktop-electron/tests/main/ai-detection/checkOverridePrefix.test.ts +162 -0
- package/packages/desktop-electron/tests/main/ai-detection/classifyInput.test.ts +132 -0
- package/packages/desktop-electron/tests/main/ai-detection/detectTypos.test.ts +342 -0
- package/packages/desktop-electron/tests/main/ai-detection/fixtures/commands.ts +134 -0
- package/packages/desktop-electron/tests/main/ai-detection/fixtures/natural-language.ts +133 -0
- package/packages/desktop-electron/tests/main/ai-detection/fixtures/typos.ts +123 -0
- package/packages/desktop-electron/tests/main/ai-detection/hasValidSubcommand.test.ts +218 -0
- package/packages/desktop-electron/tests/main/ai-detection/isCommandNotFound.test.ts +117 -0
- package/packages/desktop-electron/tests/main/error-triage/buildTriagePrompt.test.ts +133 -0
- package/packages/desktop-electron/tests/main/error-triage/parseTriageResponse.test.ts +123 -0
- package/packages/desktop-electron/tests/main/terminal-bridge/battery-optimization.test.ts +243 -0
- package/packages/desktop-electron/tests/main/terminal-bridge/command-fast-track.test.ts +292 -0
- package/packages/desktop-electron/tests/main/terminal-bridge/default-cwd.test.ts +70 -0
- package/packages/desktop-electron/tests/setup.ts +274 -0
- package/packages/desktop-electron/tsconfig.json +18 -0
- package/packages/desktop-electron/tsconfig.main.json +20 -0
- package/packages/desktop-electron/vite.config.ts +19 -0
- package/packages/desktop-electron/vitest.config.ts +18 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { TerminalSession, TerminalSessionOptions, ScreenshotResult } from "./session.js";
|
|
2
|
+
import type { SandboxController } from "../sandbox/index.js";
|
|
3
|
+
import { RecordingManager } from "../recording/index.js";
|
|
4
|
+
import type { RecordingMode, RecordingFormat, RecordingMetadata } from "../recording/index.js";
|
|
5
|
+
/**
|
|
6
|
+
* Options for creating a TerminalManager
|
|
7
|
+
*/
|
|
8
|
+
export interface TerminalManagerOptions extends TerminalSessionOptions {
|
|
9
|
+
sandboxController?: SandboxController;
|
|
10
|
+
record?: RecordingMode;
|
|
11
|
+
recordDir?: string;
|
|
12
|
+
recordFormat?: RecordingFormat;
|
|
13
|
+
idleTimeLimit?: number;
|
|
14
|
+
maxDuration?: number;
|
|
15
|
+
inactivityTimeout?: number;
|
|
16
|
+
/** Skip prompt customization and use user's native shell config */
|
|
17
|
+
nativeShell?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Options for creating an individual session
|
|
21
|
+
*/
|
|
22
|
+
export interface CreateSessionOptions {
|
|
23
|
+
cols?: number;
|
|
24
|
+
rows?: number;
|
|
25
|
+
shell?: string;
|
|
26
|
+
cwd?: string;
|
|
27
|
+
env?: Record<string, string>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Extended session with ID for multi-session support
|
|
31
|
+
*/
|
|
32
|
+
export interface ManagedSession extends TerminalSession {
|
|
33
|
+
id: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Manages the terminal session lifecycle
|
|
37
|
+
* Supports both single-session (legacy) and multi-session modes
|
|
38
|
+
*/
|
|
39
|
+
export declare class TerminalManager {
|
|
40
|
+
private session;
|
|
41
|
+
private sessionPromise;
|
|
42
|
+
private sessions;
|
|
43
|
+
private sessionCounter;
|
|
44
|
+
private options;
|
|
45
|
+
private sandboxController?;
|
|
46
|
+
private recordingManager;
|
|
47
|
+
private autoRecordingId;
|
|
48
|
+
constructor(options?: TerminalManagerOptions);
|
|
49
|
+
/**
|
|
50
|
+
* Get the default shell path
|
|
51
|
+
*/
|
|
52
|
+
getDefaultShell(): string;
|
|
53
|
+
/**
|
|
54
|
+
* Create a new terminal session with a unique ID
|
|
55
|
+
*/
|
|
56
|
+
createSession(options?: CreateSessionOptions): Promise<ManagedSession>;
|
|
57
|
+
/**
|
|
58
|
+
* Get a session by ID
|
|
59
|
+
*/
|
|
60
|
+
getSessionById(sessionId: string): TerminalSession | null;
|
|
61
|
+
/**
|
|
62
|
+
* Close a session by ID
|
|
63
|
+
*/
|
|
64
|
+
closeSession(sessionId: string): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Get all active session IDs
|
|
67
|
+
*/
|
|
68
|
+
getSessionIds(): string[];
|
|
69
|
+
/**
|
|
70
|
+
* Get count of active sessions
|
|
71
|
+
*/
|
|
72
|
+
getSessionCount(): number;
|
|
73
|
+
/**
|
|
74
|
+
* Get or create the terminal session (async)
|
|
75
|
+
*/
|
|
76
|
+
getSessionAsync(): Promise<TerminalSession>;
|
|
77
|
+
/**
|
|
78
|
+
* Get the current session if it exists and is active
|
|
79
|
+
* Returns null if no session exists yet
|
|
80
|
+
*/
|
|
81
|
+
getCurrentSession(): TerminalSession | null;
|
|
82
|
+
/**
|
|
83
|
+
* @deprecated Use getSessionAsync() instead. This method exists for backwards compatibility
|
|
84
|
+
* but will throw if the session hasn't been created yet.
|
|
85
|
+
*/
|
|
86
|
+
getSession(): TerminalSession;
|
|
87
|
+
/**
|
|
88
|
+
* Initialize the session eagerly
|
|
89
|
+
* Call this at startup to create the session before it's needed
|
|
90
|
+
*/
|
|
91
|
+
initSession(): Promise<TerminalSession>;
|
|
92
|
+
/**
|
|
93
|
+
* Start auto-recording based on CLI options
|
|
94
|
+
*/
|
|
95
|
+
private startAutoRecording;
|
|
96
|
+
/**
|
|
97
|
+
* Get the RecordingManager instance
|
|
98
|
+
*/
|
|
99
|
+
getRecordingManager(): RecordingManager;
|
|
100
|
+
/**
|
|
101
|
+
* Finalize all recordings and return their metadata
|
|
102
|
+
* Called by the caller when the session exits
|
|
103
|
+
*/
|
|
104
|
+
finalizeRecordings(exitCode: number): Promise<RecordingMetadata[]>;
|
|
105
|
+
/**
|
|
106
|
+
* Check if a session exists and is active
|
|
107
|
+
*/
|
|
108
|
+
hasActiveSession(): boolean;
|
|
109
|
+
/**
|
|
110
|
+
* Write data to the terminal
|
|
111
|
+
*/
|
|
112
|
+
write(data: string): void;
|
|
113
|
+
/**
|
|
114
|
+
* Get terminal content
|
|
115
|
+
*/
|
|
116
|
+
getContent(): string;
|
|
117
|
+
/**
|
|
118
|
+
* Get visible content only
|
|
119
|
+
*/
|
|
120
|
+
getVisibleContent(): string;
|
|
121
|
+
/**
|
|
122
|
+
* Take a screenshot
|
|
123
|
+
*/
|
|
124
|
+
takeScreenshot(): ScreenshotResult;
|
|
125
|
+
/**
|
|
126
|
+
* Clear the terminal
|
|
127
|
+
*/
|
|
128
|
+
clear(): void;
|
|
129
|
+
/**
|
|
130
|
+
* Resize the terminal
|
|
131
|
+
*/
|
|
132
|
+
resize(cols: number, rows: number): void;
|
|
133
|
+
/**
|
|
134
|
+
* Get terminal dimensions
|
|
135
|
+
*/
|
|
136
|
+
getDimensions(): {
|
|
137
|
+
cols: number;
|
|
138
|
+
rows: number;
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Dispose of the current session and cleanup sandbox
|
|
142
|
+
*/
|
|
143
|
+
dispose(): void;
|
|
144
|
+
/**
|
|
145
|
+
* Async dispose that also cleans up sandbox resources
|
|
146
|
+
*/
|
|
147
|
+
disposeAsync(): Promise<void>;
|
|
148
|
+
/**
|
|
149
|
+
* Get the sandbox controller if one is configured
|
|
150
|
+
*/
|
|
151
|
+
getSandboxController(): SandboxController | undefined;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/terminal/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { TerminalSession } from "./session.js";
|
|
2
|
+
import { RecordingManager } from "../recording/index.js";
|
|
3
|
+
import { getDefaultRecordDir, getDefaultShell } from "../utils/platform.js";
|
|
4
|
+
import { randomUUID } from "crypto";
|
|
5
|
+
/**
|
|
6
|
+
* Manages the terminal session lifecycle
|
|
7
|
+
* Supports both single-session (legacy) and multi-session modes
|
|
8
|
+
*/
|
|
9
|
+
export class TerminalManager {
|
|
10
|
+
// Legacy single-session support
|
|
11
|
+
session = null;
|
|
12
|
+
sessionPromise = null;
|
|
13
|
+
// Multi-session support
|
|
14
|
+
sessions = new Map();
|
|
15
|
+
sessionCounter = 0;
|
|
16
|
+
options;
|
|
17
|
+
sandboxController;
|
|
18
|
+
recordingManager;
|
|
19
|
+
autoRecordingId = null;
|
|
20
|
+
constructor(options = {}) {
|
|
21
|
+
this.options = options;
|
|
22
|
+
this.sandboxController = options.sandboxController;
|
|
23
|
+
this.recordingManager = new RecordingManager({
|
|
24
|
+
mode: options.record ?? 'off',
|
|
25
|
+
outputDir: options.recordDir ?? getDefaultRecordDir(),
|
|
26
|
+
format: options.recordFormat ?? 'v2',
|
|
27
|
+
idleTimeLimit: options.idleTimeLimit ?? 2,
|
|
28
|
+
maxDuration: options.maxDuration ?? 3600,
|
|
29
|
+
inactivityTimeout: options.inactivityTimeout ?? 600,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get the default shell path
|
|
34
|
+
*/
|
|
35
|
+
getDefaultShell() {
|
|
36
|
+
return this.options.shell || getDefaultShell();
|
|
37
|
+
}
|
|
38
|
+
// =========================================================================
|
|
39
|
+
// Multi-Session API (for GUI/Electron)
|
|
40
|
+
// =========================================================================
|
|
41
|
+
/**
|
|
42
|
+
* Create a new terminal session with a unique ID
|
|
43
|
+
*/
|
|
44
|
+
async createSession(options = {}) {
|
|
45
|
+
const sessionId = `session-${++this.sessionCounter}-${randomUUID().slice(0, 8)}`;
|
|
46
|
+
const session = await TerminalSession.create({
|
|
47
|
+
cols: options.cols ?? this.options.cols ?? 120,
|
|
48
|
+
rows: options.rows ?? this.options.rows ?? 40,
|
|
49
|
+
shell: options.shell ?? this.options.shell,
|
|
50
|
+
cwd: options.cwd ?? this.options.cwd,
|
|
51
|
+
env: options.env ?? this.options.env,
|
|
52
|
+
nativeShell: this.options.nativeShell,
|
|
53
|
+
setLocaleEnv: this.options.setLocaleEnv,
|
|
54
|
+
sandboxController: this.sandboxController,
|
|
55
|
+
});
|
|
56
|
+
// Store in map
|
|
57
|
+
this.sessions.set(sessionId, session);
|
|
58
|
+
// Wire up recording hooks
|
|
59
|
+
session.onData((data) => this.recordingManager.recordOutputToAll(data));
|
|
60
|
+
session.onResize((cols, rows) => this.recordingManager.recordResizeToAll(cols, rows));
|
|
61
|
+
// Clean up when session exits
|
|
62
|
+
session.onExit(() => {
|
|
63
|
+
this.sessions.delete(sessionId);
|
|
64
|
+
});
|
|
65
|
+
// Return session with ID attached
|
|
66
|
+
const managedSession = session;
|
|
67
|
+
managedSession.id = sessionId;
|
|
68
|
+
return managedSession;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get a session by ID
|
|
72
|
+
*/
|
|
73
|
+
getSessionById(sessionId) {
|
|
74
|
+
return this.sessions.get(sessionId) ?? null;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Close a session by ID
|
|
78
|
+
*/
|
|
79
|
+
closeSession(sessionId) {
|
|
80
|
+
const session = this.sessions.get(sessionId);
|
|
81
|
+
if (session) {
|
|
82
|
+
session.dispose();
|
|
83
|
+
this.sessions.delete(sessionId);
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get all active session IDs
|
|
90
|
+
*/
|
|
91
|
+
getSessionIds() {
|
|
92
|
+
return Array.from(this.sessions.keys());
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get count of active sessions
|
|
96
|
+
*/
|
|
97
|
+
getSessionCount() {
|
|
98
|
+
return this.sessions.size;
|
|
99
|
+
}
|
|
100
|
+
// =========================================================================
|
|
101
|
+
// Legacy Single-Session API (for CLI/MCP compatibility)
|
|
102
|
+
// =========================================================================
|
|
103
|
+
/**
|
|
104
|
+
* Get or create the terminal session (async)
|
|
105
|
+
*/
|
|
106
|
+
async getSessionAsync() {
|
|
107
|
+
if (this.session && this.session.isActive()) {
|
|
108
|
+
return this.session;
|
|
109
|
+
}
|
|
110
|
+
// If there's already a creation in progress, wait for it
|
|
111
|
+
if (this.sessionPromise) {
|
|
112
|
+
return this.sessionPromise;
|
|
113
|
+
}
|
|
114
|
+
// Create new session
|
|
115
|
+
this.sessionPromise = TerminalSession.create({
|
|
116
|
+
...this.options,
|
|
117
|
+
sandboxController: this.sandboxController,
|
|
118
|
+
});
|
|
119
|
+
try {
|
|
120
|
+
this.session = await this.sessionPromise;
|
|
121
|
+
return this.session;
|
|
122
|
+
}
|
|
123
|
+
finally {
|
|
124
|
+
this.sessionPromise = null;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Get the current session if it exists and is active
|
|
129
|
+
* Returns null if no session exists yet
|
|
130
|
+
*/
|
|
131
|
+
getCurrentSession() {
|
|
132
|
+
if (this.session && this.session.isActive()) {
|
|
133
|
+
return this.session;
|
|
134
|
+
}
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* @deprecated Use getSessionAsync() instead. This method exists for backwards compatibility
|
|
139
|
+
* but will throw if the session hasn't been created yet.
|
|
140
|
+
*/
|
|
141
|
+
getSession() {
|
|
142
|
+
if (!this.session || !this.session.isActive()) {
|
|
143
|
+
throw new Error("Session not initialized. Use getSessionAsync() or call initSession() first.");
|
|
144
|
+
}
|
|
145
|
+
return this.session;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Initialize the session eagerly
|
|
149
|
+
* Call this at startup to create the session before it's needed
|
|
150
|
+
*/
|
|
151
|
+
async initSession() {
|
|
152
|
+
const session = await this.getSessionAsync();
|
|
153
|
+
// Wire up recording hooks
|
|
154
|
+
session.onData((data) => this.recordingManager.recordOutputToAll(data));
|
|
155
|
+
session.onResize((cols, rows) => this.recordingManager.recordResizeToAll(cols, rows));
|
|
156
|
+
// Start auto-recording if CLI mode !== 'off'
|
|
157
|
+
if (this.options.record && this.options.record !== 'off') {
|
|
158
|
+
this.startAutoRecording();
|
|
159
|
+
}
|
|
160
|
+
return session;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Start auto-recording based on CLI options
|
|
164
|
+
*/
|
|
165
|
+
startAutoRecording() {
|
|
166
|
+
if (this.autoRecordingId) {
|
|
167
|
+
return; // Already recording
|
|
168
|
+
}
|
|
169
|
+
const recorder = this.recordingManager.createRecording({
|
|
170
|
+
mode: this.options.record,
|
|
171
|
+
outputDir: this.options.recordDir ?? getDefaultRecordDir(),
|
|
172
|
+
format: this.options.recordFormat ?? 'v2',
|
|
173
|
+
idleTimeLimit: this.options.idleTimeLimit ?? 2,
|
|
174
|
+
maxDuration: this.options.maxDuration ?? 3600,
|
|
175
|
+
inactivityTimeout: this.options.inactivityTimeout ?? 600,
|
|
176
|
+
});
|
|
177
|
+
const dimensions = this.session?.getDimensions() ?? { cols: 120, rows: 40 };
|
|
178
|
+
recorder.start(dimensions.cols, dimensions.rows, {
|
|
179
|
+
SHELL: this.options.shell ?? process.env.SHELL,
|
|
180
|
+
TERM: 'xterm-256color',
|
|
181
|
+
});
|
|
182
|
+
this.autoRecordingId = recorder.id;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Get the RecordingManager instance
|
|
186
|
+
*/
|
|
187
|
+
getRecordingManager() {
|
|
188
|
+
return this.recordingManager;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Finalize all recordings and return their metadata
|
|
192
|
+
* Called by the caller when the session exits
|
|
193
|
+
*/
|
|
194
|
+
async finalizeRecordings(exitCode) {
|
|
195
|
+
return this.recordingManager.finalizeAll(exitCode);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Check if a session exists and is active
|
|
199
|
+
*/
|
|
200
|
+
hasActiveSession() {
|
|
201
|
+
return this.session !== null && this.session.isActive();
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Write data to the terminal
|
|
205
|
+
*/
|
|
206
|
+
write(data) {
|
|
207
|
+
this.getSession().write(data);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Get terminal content
|
|
211
|
+
*/
|
|
212
|
+
getContent() {
|
|
213
|
+
return this.getSession().getContent();
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Get visible content only
|
|
217
|
+
*/
|
|
218
|
+
getVisibleContent() {
|
|
219
|
+
return this.getSession().getVisibleContent();
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Take a screenshot
|
|
223
|
+
*/
|
|
224
|
+
takeScreenshot() {
|
|
225
|
+
return this.getSession().takeScreenshot();
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Clear the terminal
|
|
229
|
+
*/
|
|
230
|
+
clear() {
|
|
231
|
+
this.getSession().clear();
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Resize the terminal
|
|
235
|
+
*/
|
|
236
|
+
resize(cols, rows) {
|
|
237
|
+
this.getSession().resize(cols, rows);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Get terminal dimensions
|
|
241
|
+
*/
|
|
242
|
+
getDimensions() {
|
|
243
|
+
return this.getSession().getDimensions();
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Dispose of the current session and cleanup sandbox
|
|
247
|
+
*/
|
|
248
|
+
dispose() {
|
|
249
|
+
// Dispose legacy session
|
|
250
|
+
if (this.session) {
|
|
251
|
+
this.session.dispose();
|
|
252
|
+
this.session = null;
|
|
253
|
+
}
|
|
254
|
+
// Dispose all multi-session instances
|
|
255
|
+
for (const session of this.sessions.values()) {
|
|
256
|
+
session.dispose();
|
|
257
|
+
}
|
|
258
|
+
this.sessions.clear();
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Async dispose that also cleans up sandbox resources
|
|
262
|
+
*/
|
|
263
|
+
async disposeAsync() {
|
|
264
|
+
this.dispose();
|
|
265
|
+
if (this.sandboxController) {
|
|
266
|
+
await this.sandboxController.cleanup();
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Get the sandbox controller if one is configured
|
|
271
|
+
*/
|
|
272
|
+
getSandboxController() {
|
|
273
|
+
return this.sandboxController;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/terminal/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import type { SandboxController } from "../sandbox/index.js";
|
|
2
|
+
export interface TerminalSessionOptions {
|
|
3
|
+
cols?: number;
|
|
4
|
+
rows?: number;
|
|
5
|
+
shell?: string;
|
|
6
|
+
cwd?: string;
|
|
7
|
+
env?: Record<string, string>;
|
|
8
|
+
startupBanner?: string;
|
|
9
|
+
sandboxController?: SandboxController;
|
|
10
|
+
/** Skip prompt customization and use user's native shell config */
|
|
11
|
+
nativeShell?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Also set LC_CTYPE in addition to LANG.
|
|
14
|
+
* When false (default), only LANG is set, matching iTerm2 behavior.
|
|
15
|
+
* When true, also sets LC_CTYPE which may cause issues when SSH'ing
|
|
16
|
+
* to remote servers that don't have the same locales installed
|
|
17
|
+
* (SSH forwards LC_* variables via SendEnv).
|
|
18
|
+
*/
|
|
19
|
+
setLocaleEnv?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface ScreenshotResult {
|
|
22
|
+
content: string;
|
|
23
|
+
cursor: {
|
|
24
|
+
x: number;
|
|
25
|
+
y: number;
|
|
26
|
+
};
|
|
27
|
+
dimensions: {
|
|
28
|
+
cols: number;
|
|
29
|
+
rows: number;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Terminal session that combines node-pty with xterm.js headless
|
|
34
|
+
* for full terminal emulation
|
|
35
|
+
*/
|
|
36
|
+
export declare class TerminalSession {
|
|
37
|
+
private ptyProcess;
|
|
38
|
+
private terminal;
|
|
39
|
+
private disposed;
|
|
40
|
+
private dataListeners;
|
|
41
|
+
private exitListeners;
|
|
42
|
+
private resizeListeners;
|
|
43
|
+
private rcFile;
|
|
44
|
+
private zdotdir;
|
|
45
|
+
/**
|
|
46
|
+
* Private constructor - use TerminalSession.create() instead
|
|
47
|
+
*/
|
|
48
|
+
private constructor();
|
|
49
|
+
/**
|
|
50
|
+
* Factory method to create a TerminalSession
|
|
51
|
+
* Use this instead of the constructor to support async sandbox initialization
|
|
52
|
+
*/
|
|
53
|
+
static create(options?: TerminalSessionOptions): Promise<TerminalSession>;
|
|
54
|
+
/**
|
|
55
|
+
* Set up shell-specific prompt customization
|
|
56
|
+
* Returns args to pass to shell and env modifications
|
|
57
|
+
*/
|
|
58
|
+
private setupShellPrompt;
|
|
59
|
+
/**
|
|
60
|
+
* Get a list of available UTF-8 locales on the system.
|
|
61
|
+
* Returns the best one to use, preferring the user's existing locale if valid.
|
|
62
|
+
*/
|
|
63
|
+
private getAvailableUtf8Locale;
|
|
64
|
+
/**
|
|
65
|
+
* Ensure proper UTF-8 locale settings for the terminal.
|
|
66
|
+
* Electron apps launched from Finder on macOS don't inherit shell locale settings,
|
|
67
|
+
* which breaks programs like mosh that require UTF-8.
|
|
68
|
+
*/
|
|
69
|
+
private ensureUtf8Locale;
|
|
70
|
+
/**
|
|
71
|
+
* Initialize the terminal session
|
|
72
|
+
* This is called by the create() factory method
|
|
73
|
+
*/
|
|
74
|
+
private initialize;
|
|
75
|
+
/**
|
|
76
|
+
* Subscribe to PTY output data
|
|
77
|
+
*/
|
|
78
|
+
onData(listener: (data: string) => void): void;
|
|
79
|
+
/**
|
|
80
|
+
* Subscribe to PTY exit
|
|
81
|
+
*/
|
|
82
|
+
onExit(listener: (code: number) => void): void;
|
|
83
|
+
/**
|
|
84
|
+
* Subscribe to terminal resize events
|
|
85
|
+
*/
|
|
86
|
+
onResize(listener: (cols: number, rows: number) => void): void;
|
|
87
|
+
/**
|
|
88
|
+
* Write data to the terminal (simulates typing)
|
|
89
|
+
*/
|
|
90
|
+
write(data: string): void;
|
|
91
|
+
/**
|
|
92
|
+
* Get the current terminal buffer content as plain text
|
|
93
|
+
*/
|
|
94
|
+
getContent(): string;
|
|
95
|
+
/**
|
|
96
|
+
* Get only the visible viewport content
|
|
97
|
+
*/
|
|
98
|
+
getVisibleContent(): string;
|
|
99
|
+
/**
|
|
100
|
+
* Take a screenshot of the terminal state
|
|
101
|
+
*/
|
|
102
|
+
takeScreenshot(): ScreenshotResult;
|
|
103
|
+
/**
|
|
104
|
+
* Clear the terminal screen
|
|
105
|
+
*/
|
|
106
|
+
clear(): void;
|
|
107
|
+
/**
|
|
108
|
+
* Resize the terminal
|
|
109
|
+
*/
|
|
110
|
+
resize(cols: number, rows: number): void;
|
|
111
|
+
/**
|
|
112
|
+
* Check if the session is still active
|
|
113
|
+
*/
|
|
114
|
+
isActive(): boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Get terminal dimensions
|
|
117
|
+
*/
|
|
118
|
+
getDimensions(): {
|
|
119
|
+
cols: number;
|
|
120
|
+
rows: number;
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* Get the current foreground process name
|
|
124
|
+
* On macOS/Linux this returns the actual process running in the terminal
|
|
125
|
+
*/
|
|
126
|
+
getProcess(): string;
|
|
127
|
+
/**
|
|
128
|
+
* Get the current working directory of the foreground process
|
|
129
|
+
* Uses process tree traversal to find the deepest child process
|
|
130
|
+
*/
|
|
131
|
+
getCwd(): string | null;
|
|
132
|
+
/**
|
|
133
|
+
* Dispose of the terminal session
|
|
134
|
+
*/
|
|
135
|
+
dispose(): void;
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/terminal/session.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAoC7D,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,mEAAmE;IACnE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE;QACN,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;KACX,CAAC;IACF,UAAU,EAAE;QACV,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,UAAU,CAAY;IAC9B,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAAqC;IAC1D,OAAO,CAAC,aAAa,CAAqC;IAC1D,OAAO,CAAC,eAAe,CAAmD;IAE1E,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,OAAO,CAAuB;IAEtC;;OAEG;IACH,OAAO;IAEP;;;OAGG;WACU,MAAM,CAAC,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,eAAe,CAAC;IAMnF;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAkIxB;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAgD9B;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAqCxB;;;OAGG;YACW,UAAU;IAyPxB;;OAEG;IACH,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAI9C;;OAEG;IACH,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAI9C;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAI9D;;OAEG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAOzB;;OAEG;IACH,UAAU,IAAI,MAAM;IAwBpB;;OAEG;IACH,iBAAiB,IAAI,MAAM;IAmB3B;;OAEG;IACH,cAAc,IAAI,gBAAgB;IAoBlC;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAaxC;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,aAAa,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAO/C;;;OAGG;IACH,UAAU,IAAI,MAAM;IAYpB;;;OAGG;IACH,MAAM,IAAI,MAAM,GAAG,IAAI;IAkFvB;;OAEG;IACH,OAAO,IAAI,IAAI;CAuBhB"}
|