@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.
- package/README.md +434 -0
- package/dist/browserbox.d.ts +145 -0
- package/dist/browserbox.d.ts.map +1 -0
- package/dist/browserbox.js +234 -0
- package/dist/browserbox.js.map +1 -0
- package/dist/codebox.d.ts +144 -0
- package/dist/codebox.d.ts.map +1 -0
- package/dist/codebox.js +202 -0
- package/dist/codebox.js.map +1 -0
- package/dist/computerbox.d.ts +271 -0
- package/dist/computerbox.d.ts.map +1 -0
- package/dist/computerbox.js +406 -0
- package/dist/computerbox.js.map +1 -0
- package/dist/constants.d.ts +24 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +32 -0
- package/dist/constants.js.map +1 -0
- package/dist/errors.d.ts +82 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +114 -0
- package/dist/errors.js.map +1 -0
- package/dist/exec.d.ts +32 -0
- package/dist/exec.d.ts.map +1 -0
- package/dist/exec.js +3 -0
- package/dist/exec.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/interactivebox.d.ts +155 -0
- package/dist/interactivebox.d.ts.map +1 -0
- package/dist/interactivebox.js +299 -0
- package/dist/interactivebox.js.map +1 -0
- package/dist/native.d.ts +20 -0
- package/dist/native.d.ts.map +1 -0
- package/dist/native.js +41 -0
- package/dist/native.js.map +1 -0
- package/dist/simplebox.d.ts +175 -0
- package/dist/simplebox.d.ts.map +1 -0
- package/dist/simplebox.js +232 -0
- package/dist/simplebox.js.map +1 -0
- package/package.json +57 -0
|
@@ -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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"}
|