@boxlite-ai/boxlite 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.
@@ -0,0 +1,271 @@
1
+ /**
2
+ * ComputerBox - Desktop environment with web access.
3
+ *
4
+ * Provides a minimal, elegant API for running isolated desktop environments
5
+ * that can be viewed from a browser, with full GUI automation support.
6
+ */
7
+ import { SimpleBox, type SimpleBoxOptions } from './simplebox';
8
+ /**
9
+ * Options for creating a ComputerBox.
10
+ */
11
+ export interface ComputerBoxOptions extends Omit<SimpleBoxOptions, 'image' | 'cpus' | 'memoryMib'> {
12
+ /** Number of CPU cores (default: 2) */
13
+ cpus?: number;
14
+ /** Memory in MiB (default: 2048) */
15
+ memoryMib?: number;
16
+ /** Port for HTTP desktop GUI (default: 3000) */
17
+ guiHttpPort?: number;
18
+ /** Port for HTTPS desktop GUI (default: 3001) */
19
+ guiHttpsPort?: number;
20
+ }
21
+ /**
22
+ * Screenshot result containing image data and metadata.
23
+ */
24
+ export interface Screenshot {
25
+ /** Base64-encoded PNG image data */
26
+ data: string;
27
+ /** Image width in pixels */
28
+ width: number;
29
+ /** Image height in pixels */
30
+ height: number;
31
+ /** Image format (always 'png') */
32
+ format: 'png';
33
+ }
34
+ /**
35
+ * Desktop environment accessible via web browser.
36
+ *
37
+ * Auto-starts a full desktop environment with web interface.
38
+ * Access the desktop by opening the URL in your browser.
39
+ *
40
+ * **Note**: Uses HTTPS with self-signed certificate - your browser will show
41
+ * a security warning. Click "Advanced" and "Proceed" to access the desktop.
42
+ *
43
+ * ## Usage
44
+ *
45
+ * ```typescript
46
+ * const desktop = new ComputerBox();
47
+ * try {
48
+ * await desktop.waitUntilReady();
49
+ * const screenshot = await desktop.screenshot();
50
+ * console.log('Desktop ready!');
51
+ * } finally {
52
+ * await desktop.stop();
53
+ * }
54
+ * ```
55
+ *
56
+ * ## Example with custom settings
57
+ *
58
+ * ```typescript
59
+ * const desktop = new ComputerBox({
60
+ * memoryMib: 4096,
61
+ * cpus: 4
62
+ * });
63
+ * try {
64
+ * await desktop.waitUntilReady();
65
+ * await desktop.mouseMove(100, 200);
66
+ * await desktop.leftClick();
67
+ * } finally {
68
+ * await desktop.stop();
69
+ * }
70
+ * ```
71
+ */
72
+ export declare class ComputerBox extends SimpleBox {
73
+ /**
74
+ * Create and auto-start a desktop environment.
75
+ *
76
+ * @param options - ComputerBox configuration options
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * const desktop = new ComputerBox({
81
+ * cpus: 2,
82
+ * memoryMib: 2048,
83
+ * guiHttpPort: 3000,
84
+ * guiHttpsPort: 3001
85
+ * });
86
+ * ```
87
+ */
88
+ constructor(options?: ComputerBoxOptions);
89
+ /**
90
+ * Execute a command and throw ExecError if it fails.
91
+ *
92
+ * @param label - Label for error messages (e.g., 'mouseMove(100, 200)')
93
+ * @param cmd - Command to execute
94
+ * @param args - Command arguments
95
+ * @returns The execution result (for methods that need to parse output)
96
+ * @throws {ExecError} If command exits with non-zero code
97
+ */
98
+ private execOrThrow;
99
+ /**
100
+ * Wait until the desktop environment is fully loaded and ready.
101
+ *
102
+ * @param timeout - Maximum time to wait in seconds (default: 60)
103
+ *
104
+ * @throws {TimeoutError} If desktop doesn't become ready within timeout period
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * const desktop = new ComputerBox();
109
+ * try {
110
+ * await desktop.waitUntilReady(60);
111
+ * console.log('Desktop is ready!');
112
+ * } finally {
113
+ * await desktop.stop();
114
+ * }
115
+ * ```
116
+ */
117
+ waitUntilReady(timeout?: number): Promise<void>;
118
+ /**
119
+ * Capture a screenshot of the desktop.
120
+ *
121
+ * @returns Promise resolving to screenshot data with base64 PNG, dimensions, and format
122
+ *
123
+ * @example
124
+ * ```typescript
125
+ * const desktop = new ComputerBox();
126
+ * try {
127
+ * await desktop.waitUntilReady();
128
+ * const screenshot = await desktop.screenshot();
129
+ * console.log(`Screenshot: ${screenshot.width}x${screenshot.height}`);
130
+ * // Save screenshot.data (base64 PNG) to file or process it
131
+ * } finally {
132
+ * await desktop.stop();
133
+ * }
134
+ * ```
135
+ */
136
+ screenshot(): Promise<Screenshot>;
137
+ /**
138
+ * Move mouse cursor to absolute coordinates.
139
+ *
140
+ * @param x - X coordinate
141
+ * @param y - Y coordinate
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * await desktop.mouseMove(100, 200);
146
+ * ```
147
+ */
148
+ mouseMove(x: number, y: number): Promise<void>;
149
+ /**
150
+ * Click left mouse button at current position.
151
+ *
152
+ * @example
153
+ * ```typescript
154
+ * await desktop.leftClick();
155
+ * ```
156
+ */
157
+ leftClick(): Promise<void>;
158
+ /**
159
+ * Click right mouse button at current position.
160
+ *
161
+ * @example
162
+ * ```typescript
163
+ * await desktop.rightClick();
164
+ * ```
165
+ */
166
+ rightClick(): Promise<void>;
167
+ /**
168
+ * Click middle mouse button at current position.
169
+ *
170
+ * @example
171
+ * ```typescript
172
+ * await desktop.middleClick();
173
+ * ```
174
+ */
175
+ middleClick(): Promise<void>;
176
+ /**
177
+ * Double-click left mouse button at current position.
178
+ *
179
+ * @example
180
+ * ```typescript
181
+ * await desktop.doubleClick();
182
+ * ```
183
+ */
184
+ doubleClick(): Promise<void>;
185
+ /**
186
+ * Triple-click left mouse button at current position.
187
+ *
188
+ * @example
189
+ * ```typescript
190
+ * await desktop.tripleClick();
191
+ * ```
192
+ */
193
+ tripleClick(): Promise<void>;
194
+ /**
195
+ * Drag mouse from start position to end position with left button held.
196
+ *
197
+ * @param startX - Starting X coordinate
198
+ * @param startY - Starting Y coordinate
199
+ * @param endX - Ending X coordinate
200
+ * @param endY - Ending Y coordinate
201
+ *
202
+ * @example
203
+ * ```typescript
204
+ * await desktop.leftClickDrag(100, 100, 200, 200);
205
+ * ```
206
+ */
207
+ leftClickDrag(startX: number, startY: number, endX: number, endY: number): Promise<void>;
208
+ /**
209
+ * Get the current mouse cursor position.
210
+ *
211
+ * @returns Promise resolving to [x, y] coordinates
212
+ *
213
+ * @example
214
+ * ```typescript
215
+ * const [x, y] = await desktop.cursorPosition();
216
+ * console.log(`Cursor at: ${x}, ${y}`);
217
+ * ```
218
+ */
219
+ cursorPosition(): Promise<[number, number]>;
220
+ /**
221
+ * Type text using the keyboard.
222
+ *
223
+ * @param text - Text to type
224
+ *
225
+ * @example
226
+ * ```typescript
227
+ * await desktop.type('Hello, World!');
228
+ * ```
229
+ */
230
+ type(text: string): Promise<void>;
231
+ /**
232
+ * Press a special key or key combination.
233
+ *
234
+ * @param keySequence - Key or key combination (e.g., 'Return', 'ctrl+c', 'alt+Tab')
235
+ *
236
+ * @example
237
+ * ```typescript
238
+ * await desktop.key('Return');
239
+ * await desktop.key('ctrl+c');
240
+ * await desktop.key('alt+Tab');
241
+ * ```
242
+ */
243
+ key(keySequence: string): Promise<void>;
244
+ /**
245
+ * Scroll at a specific position.
246
+ *
247
+ * @param x - X coordinate where to scroll
248
+ * @param y - Y coordinate where to scroll
249
+ * @param direction - Scroll direction: 'up', 'down', 'left', or 'right'
250
+ * @param amount - Number of scroll units (default: 3)
251
+ *
252
+ * @example
253
+ * ```typescript
254
+ * await desktop.scroll(500, 300, 'down', 5);
255
+ * ```
256
+ */
257
+ scroll(x: number, y: number, direction: 'up' | 'down' | 'left' | 'right', amount?: number): Promise<void>;
258
+ /**
259
+ * Get the screen resolution.
260
+ *
261
+ * @returns Promise resolving to [width, height] in pixels
262
+ *
263
+ * @example
264
+ * ```typescript
265
+ * const [width, height] = await desktop.getScreenSize();
266
+ * console.log(`Screen: ${width}x${height}`);
267
+ * ```
268
+ */
269
+ getScreenSize(): Promise<[number, number]>;
270
+ }
271
+ //# sourceMappingURL=computerbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computerbox.d.ts","sourceRoot":"","sources":["../lib/computerbox.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAI/D;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,gBAAgB,EAAE,OAAO,GAAG,MAAM,GAAG,WAAW,CAAC;IAChG,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IAEb,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IAEd,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IAEf,kCAAkC;IAClC,MAAM,EAAE,KAAK,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,qBAAa,WAAY,SAAQ,SAAS;IACxC;;;;;;;;;;;;;;OAcG;gBACS,OAAO,GAAE,kBAAuB;IAqC5C;;;;;;;;OAQG;YACW,WAAW;IAQzB;;;;;;;;;;;;;;;;;OAiBG;IACG,cAAc,CAAC,OAAO,GAAE,MAAwC,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BtF;;;;;;;;;;;;;;;;;OAiBG;IACG,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC;IAqBvC;;;;;;;;;;OAUG;IACG,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpD;;;;;;;OAOG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAIhC;;;;;;;OAOG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC;;;;;;;OAOG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAIlC;;;;;;;OAOG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAIlC;;;;;;;OAOG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAIlC;;;;;;;;;;;;OAYG;IACG,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa9F;;;;;;;;;;OAUG;IACG,cAAc,IAAI,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAsBjD;;;;;;;;;OASG;IACG,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC;;;;;;;;;;;OAWG;IACG,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7C;;;;;;;;;;;;OAYG;IACG,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE,MAAM,GAAE,MAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBlH;;;;;;;;;;OAUG;IACG,aAAa,IAAI,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAUjD"}
@@ -0,0 +1,406 @@
1
+ "use strict";
2
+ /**
3
+ * ComputerBox - Desktop environment with web access.
4
+ *
5
+ * Provides a minimal, elegant API for running isolated desktop environments
6
+ * that can be viewed from a browser, with full GUI automation support.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.ComputerBox = void 0;
43
+ const simplebox_1 = require("./simplebox");
44
+ const errors_1 = require("./errors");
45
+ const constants = __importStar(require("./constants"));
46
+ /**
47
+ * Desktop environment accessible via web browser.
48
+ *
49
+ * Auto-starts a full desktop environment with web interface.
50
+ * Access the desktop by opening the URL in your browser.
51
+ *
52
+ * **Note**: Uses HTTPS with self-signed certificate - your browser will show
53
+ * a security warning. Click "Advanced" and "Proceed" to access the desktop.
54
+ *
55
+ * ## Usage
56
+ *
57
+ * ```typescript
58
+ * const desktop = new ComputerBox();
59
+ * try {
60
+ * await desktop.waitUntilReady();
61
+ * const screenshot = await desktop.screenshot();
62
+ * console.log('Desktop ready!');
63
+ * } finally {
64
+ * await desktop.stop();
65
+ * }
66
+ * ```
67
+ *
68
+ * ## Example with custom settings
69
+ *
70
+ * ```typescript
71
+ * const desktop = new ComputerBox({
72
+ * memoryMib: 4096,
73
+ * cpus: 4
74
+ * });
75
+ * try {
76
+ * await desktop.waitUntilReady();
77
+ * await desktop.mouseMove(100, 200);
78
+ * await desktop.leftClick();
79
+ * } finally {
80
+ * await desktop.stop();
81
+ * }
82
+ * ```
83
+ */
84
+ class ComputerBox extends simplebox_1.SimpleBox {
85
+ /**
86
+ * Create and auto-start a desktop environment.
87
+ *
88
+ * @param options - ComputerBox configuration options
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * const desktop = new ComputerBox({
93
+ * cpus: 2,
94
+ * memoryMib: 2048,
95
+ * guiHttpPort: 3000,
96
+ * guiHttpsPort: 3001
97
+ * });
98
+ * ```
99
+ */
100
+ constructor(options = {}) {
101
+ const { cpus = constants.COMPUTERBOX_CPUS, memoryMib = constants.COMPUTERBOX_MEMORY_MIB, guiHttpPort = constants.COMPUTERBOX_GUI_HTTP_PORT, guiHttpsPort = constants.COMPUTERBOX_GUI_HTTPS_PORT, env = {}, ports = [], ...restOptions } = options;
102
+ // Merge default and user environment variables
103
+ const defaultEnv = {
104
+ DISPLAY: constants.COMPUTERBOX_DISPLAY_NUMBER,
105
+ DISPLAY_SIZEW: constants.COMPUTERBOX_DISPLAY_WIDTH.toString(),
106
+ DISPLAY_SIZEH: constants.COMPUTERBOX_DISPLAY_HEIGHT.toString(),
107
+ SELKIES_MANUAL_WIDTH: constants.COMPUTERBOX_DISPLAY_WIDTH.toString(),
108
+ SELKIES_MANUAL_HEIGHT: constants.COMPUTERBOX_DISPLAY_HEIGHT.toString(),
109
+ SELKIES_UI_SHOW_SIDEBAR: 'false',
110
+ };
111
+ // Merge default and user ports
112
+ const defaultPorts = [
113
+ { hostPort: guiHttpPort, guestPort: constants.COMPUTERBOX_GUI_HTTP_PORT },
114
+ { hostPort: guiHttpsPort, guestPort: constants.COMPUTERBOX_GUI_HTTPS_PORT },
115
+ ];
116
+ super({
117
+ ...restOptions,
118
+ image: constants.COMPUTERBOX_IMAGE,
119
+ cpus,
120
+ memoryMib,
121
+ env: { ...defaultEnv, ...env },
122
+ ports: [...defaultPorts, ...ports],
123
+ });
124
+ }
125
+ /**
126
+ * Execute a command and throw ExecError if it fails.
127
+ *
128
+ * @param label - Label for error messages (e.g., 'mouseMove(100, 200)')
129
+ * @param cmd - Command to execute
130
+ * @param args - Command arguments
131
+ * @returns The execution result (for methods that need to parse output)
132
+ * @throws {ExecError} If command exits with non-zero code
133
+ */
134
+ async execOrThrow(label, cmd, ...args) {
135
+ const result = await this.exec(cmd, ...args);
136
+ if (result.exitCode !== 0) {
137
+ throw new errors_1.ExecError(label, result.exitCode, result.stderr);
138
+ }
139
+ return result;
140
+ }
141
+ /**
142
+ * Wait until the desktop environment is fully loaded and ready.
143
+ *
144
+ * @param timeout - Maximum time to wait in seconds (default: 60)
145
+ *
146
+ * @throws {TimeoutError} If desktop doesn't become ready within timeout period
147
+ *
148
+ * @example
149
+ * ```typescript
150
+ * const desktop = new ComputerBox();
151
+ * try {
152
+ * await desktop.waitUntilReady(60);
153
+ * console.log('Desktop is ready!');
154
+ * } finally {
155
+ * await desktop.stop();
156
+ * }
157
+ * ```
158
+ */
159
+ async waitUntilReady(timeout = constants.DESKTOP_READY_TIMEOUT) {
160
+ const startTime = Date.now();
161
+ while (true) {
162
+ const elapsed = (Date.now() - startTime) / 1000;
163
+ if (elapsed > timeout) {
164
+ throw new errors_1.TimeoutError(`Desktop did not become ready within ${timeout} seconds`);
165
+ }
166
+ try {
167
+ const result = await this.exec('xwininfo', '-tree', '-root');
168
+ const expectedSize = `${constants.COMPUTERBOX_DISPLAY_WIDTH}x${constants.COMPUTERBOX_DISPLAY_HEIGHT}`;
169
+ if (result.stdout.includes('xfdesktop') && result.stdout.includes(expectedSize)) {
170
+ return;
171
+ }
172
+ // Wait before retrying
173
+ await new Promise(resolve => setTimeout(resolve, constants.DESKTOP_READY_RETRY_DELAY * 1000));
174
+ }
175
+ catch (error) {
176
+ // Desktop not ready yet, retry
177
+ await new Promise(resolve => setTimeout(resolve, constants.DESKTOP_READY_RETRY_DELAY * 1000));
178
+ }
179
+ }
180
+ }
181
+ /**
182
+ * Capture a screenshot of the desktop.
183
+ *
184
+ * @returns Promise resolving to screenshot data with base64 PNG, dimensions, and format
185
+ *
186
+ * @example
187
+ * ```typescript
188
+ * const desktop = new ComputerBox();
189
+ * try {
190
+ * await desktop.waitUntilReady();
191
+ * const screenshot = await desktop.screenshot();
192
+ * console.log(`Screenshot: ${screenshot.width}x${screenshot.height}`);
193
+ * // Save screenshot.data (base64 PNG) to file or process it
194
+ * } finally {
195
+ * await desktop.stop();
196
+ * }
197
+ * ```
198
+ */
199
+ async screenshot() {
200
+ const pythonCode = `
201
+ from PIL import ImageGrab
202
+ import io
203
+ import base64
204
+ img = ImageGrab.grab()
205
+ buffer = io.BytesIO()
206
+ img.save(buffer, format="PNG")
207
+ print(base64.b64encode(buffer.getvalue()).decode("utf-8"))
208
+ `.trim();
209
+ const result = await this.execOrThrow('screenshot()', 'python3', '-c', pythonCode);
210
+ return {
211
+ data: result.stdout.trim(),
212
+ width: constants.COMPUTERBOX_DISPLAY_WIDTH,
213
+ height: constants.COMPUTERBOX_DISPLAY_HEIGHT,
214
+ format: 'png',
215
+ };
216
+ }
217
+ /**
218
+ * Move mouse cursor to absolute coordinates.
219
+ *
220
+ * @param x - X coordinate
221
+ * @param y - Y coordinate
222
+ *
223
+ * @example
224
+ * ```typescript
225
+ * await desktop.mouseMove(100, 200);
226
+ * ```
227
+ */
228
+ async mouseMove(x, y) {
229
+ await this.execOrThrow(`mouseMove(${x}, ${y})`, 'xdotool', 'mousemove', x.toString(), y.toString());
230
+ }
231
+ /**
232
+ * Click left mouse button at current position.
233
+ *
234
+ * @example
235
+ * ```typescript
236
+ * await desktop.leftClick();
237
+ * ```
238
+ */
239
+ async leftClick() {
240
+ await this.execOrThrow('leftClick()', 'xdotool', 'click', '1');
241
+ }
242
+ /**
243
+ * Click right mouse button at current position.
244
+ *
245
+ * @example
246
+ * ```typescript
247
+ * await desktop.rightClick();
248
+ * ```
249
+ */
250
+ async rightClick() {
251
+ await this.execOrThrow('rightClick()', 'xdotool', 'click', '3');
252
+ }
253
+ /**
254
+ * Click middle mouse button at current position.
255
+ *
256
+ * @example
257
+ * ```typescript
258
+ * await desktop.middleClick();
259
+ * ```
260
+ */
261
+ async middleClick() {
262
+ await this.execOrThrow('middleClick()', 'xdotool', 'click', '2');
263
+ }
264
+ /**
265
+ * Double-click left mouse button at current position.
266
+ *
267
+ * @example
268
+ * ```typescript
269
+ * await desktop.doubleClick();
270
+ * ```
271
+ */
272
+ async doubleClick() {
273
+ await this.execOrThrow('doubleClick()', 'xdotool', 'click', '--repeat', '2', '--delay', '100', '1');
274
+ }
275
+ /**
276
+ * Triple-click left mouse button at current position.
277
+ *
278
+ * @example
279
+ * ```typescript
280
+ * await desktop.tripleClick();
281
+ * ```
282
+ */
283
+ async tripleClick() {
284
+ await this.execOrThrow('tripleClick()', 'xdotool', 'click', '--repeat', '3', '--delay', '100', '1');
285
+ }
286
+ /**
287
+ * Drag mouse from start position to end position with left button held.
288
+ *
289
+ * @param startX - Starting X coordinate
290
+ * @param startY - Starting Y coordinate
291
+ * @param endX - Ending X coordinate
292
+ * @param endY - Ending Y coordinate
293
+ *
294
+ * @example
295
+ * ```typescript
296
+ * await desktop.leftClickDrag(100, 100, 200, 200);
297
+ * ```
298
+ */
299
+ async leftClickDrag(startX, startY, endX, endY) {
300
+ await this.execOrThrow('leftClickDrag()', 'xdotool', 'mousemove', startX.toString(), startY.toString(), 'mousedown', '1', 'sleep', '0.1', 'mousemove', endX.toString(), endY.toString(), 'sleep', '0.1', 'mouseup', '1');
301
+ }
302
+ /**
303
+ * Get the current mouse cursor position.
304
+ *
305
+ * @returns Promise resolving to [x, y] coordinates
306
+ *
307
+ * @example
308
+ * ```typescript
309
+ * const [x, y] = await desktop.cursorPosition();
310
+ * console.log(`Cursor at: ${x}, ${y}`);
311
+ * ```
312
+ */
313
+ async cursorPosition() {
314
+ const result = await this.execOrThrow('cursorPosition()', 'xdotool', 'getmouselocation', '--shell');
315
+ let x;
316
+ let y;
317
+ for (const line of result.stdout.split('\n')) {
318
+ const trimmed = line.trim();
319
+ if (trimmed.startsWith('X=')) {
320
+ x = parseInt(trimmed.slice(2), 10);
321
+ }
322
+ else if (trimmed.startsWith('Y=')) {
323
+ y = parseInt(trimmed.slice(2), 10);
324
+ }
325
+ }
326
+ if (x !== undefined && y !== undefined) {
327
+ return [x, y];
328
+ }
329
+ throw new errors_1.ParseError('Failed to parse cursor position from xdotool output');
330
+ }
331
+ /**
332
+ * Type text using the keyboard.
333
+ *
334
+ * @param text - Text to type
335
+ *
336
+ * @example
337
+ * ```typescript
338
+ * await desktop.type('Hello, World!');
339
+ * ```
340
+ */
341
+ async type(text) {
342
+ await this.execOrThrow('type()', 'xdotool', 'type', '--', text);
343
+ }
344
+ /**
345
+ * Press a special key or key combination.
346
+ *
347
+ * @param keySequence - Key or key combination (e.g., 'Return', 'ctrl+c', 'alt+Tab')
348
+ *
349
+ * @example
350
+ * ```typescript
351
+ * await desktop.key('Return');
352
+ * await desktop.key('ctrl+c');
353
+ * await desktop.key('alt+Tab');
354
+ * ```
355
+ */
356
+ async key(keySequence) {
357
+ await this.execOrThrow('key()', 'xdotool', 'key', keySequence);
358
+ }
359
+ /**
360
+ * Scroll at a specific position.
361
+ *
362
+ * @param x - X coordinate where to scroll
363
+ * @param y - Y coordinate where to scroll
364
+ * @param direction - Scroll direction: 'up', 'down', 'left', or 'right'
365
+ * @param amount - Number of scroll units (default: 3)
366
+ *
367
+ * @example
368
+ * ```typescript
369
+ * await desktop.scroll(500, 300, 'down', 5);
370
+ * ```
371
+ */
372
+ async scroll(x, y, direction, amount = 3) {
373
+ const directionMap = {
374
+ up: '4',
375
+ down: '5',
376
+ left: '6',
377
+ right: '7',
378
+ };
379
+ const button = directionMap[direction.toLowerCase()];
380
+ if (!button) {
381
+ throw new Error(`Invalid scroll direction: ${direction}`);
382
+ }
383
+ await this.execOrThrow('scroll()', 'xdotool', 'mousemove', x.toString(), y.toString(), 'click', '--repeat', amount.toString(), button);
384
+ }
385
+ /**
386
+ * Get the screen resolution.
387
+ *
388
+ * @returns Promise resolving to [width, height] in pixels
389
+ *
390
+ * @example
391
+ * ```typescript
392
+ * const [width, height] = await desktop.getScreenSize();
393
+ * console.log(`Screen: ${width}x${height}`);
394
+ * ```
395
+ */
396
+ async getScreenSize() {
397
+ const result = await this.execOrThrow('getScreenSize()', 'xdotool', 'getdisplaygeometry');
398
+ const parts = result.stdout.trim().split(/\s+/);
399
+ if (parts.length === 2) {
400
+ return [parseInt(parts[0], 10), parseInt(parts[1], 10)];
401
+ }
402
+ throw new errors_1.ParseError('Failed to parse screen size from xdotool output');
403
+ }
404
+ }
405
+ exports.ComputerBox = ComputerBox;
406
+ //# sourceMappingURL=computerbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computerbox.js","sourceRoot":"","sources":["../lib/computerbox.ts"],"names":[],"mappings":"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"}