@elizaos/plugin-vision 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/.npmignore +5 -0
  2. package/README.md +270 -0
  3. package/build.config.ts +70 -0
  4. package/dist/action.d.ts +8 -0
  5. package/dist/action.js +1212 -0
  6. package/dist/action.js.map +1 -0
  7. package/dist/audio-capture-stream.d.ts +42 -0
  8. package/dist/audio-capture-stream.js +516 -0
  9. package/dist/audio-capture-stream.js.map +1 -0
  10. package/dist/audio-capture.d.ts +25 -0
  11. package/dist/audio-capture.js +412 -0
  12. package/dist/audio-capture.js.map +1 -0
  13. package/dist/basic.test.d.ts +1 -0
  14. package/dist/basic.test.js +97 -0
  15. package/dist/basic.test.js.map +1 -0
  16. package/dist/config.d.ts +73 -0
  17. package/dist/config.js +254 -0
  18. package/dist/config.js.map +1 -0
  19. package/dist/entity-tracker.d.ts +32 -0
  20. package/dist/entity-tracker.js +361 -0
  21. package/dist/entity-tracker.js.map +1 -0
  22. package/dist/errors.d.ts +67 -0
  23. package/dist/errors.js +395 -0
  24. package/dist/errors.js.map +1 -0
  25. package/dist/face-recognition.d.ts +31 -0
  26. package/dist/face-recognition.js +332 -0
  27. package/dist/face-recognition.js.map +1 -0
  28. package/dist/florence2-local.d.ts +25 -0
  29. package/dist/florence2-local.js +280 -0
  30. package/dist/florence2-local.js.map +1 -0
  31. package/dist/florence2-model.d.ts +36 -0
  32. package/dist/florence2-model.js +503 -0
  33. package/dist/florence2-model.js.map +1 -0
  34. package/dist/index.d.ts +3 -0
  35. package/dist/index.js +73 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/ocr-service-real.d.ts +32 -0
  38. package/dist/ocr-service-real.js +396 -0
  39. package/dist/ocr-service-real.js.map +1 -0
  40. package/dist/ocr-service.d.ts +28 -0
  41. package/dist/ocr-service.js +216 -0
  42. package/dist/ocr-service.js.map +1 -0
  43. package/dist/provider.d.ts +2 -0
  44. package/dist/provider.js +285 -0
  45. package/dist/provider.js.map +1 -0
  46. package/dist/screen-capture.d.ts +16 -0
  47. package/dist/screen-capture.js +302 -0
  48. package/dist/screen-capture.js.map +1 -0
  49. package/dist/service.d.ts +73 -0
  50. package/dist/service.js +1662 -0
  51. package/dist/service.js.map +1 -0
  52. package/dist/tests/e2e/index.d.ts +8 -0
  53. package/dist/tests/e2e/index.js +33 -0
  54. package/dist/tests/e2e/index.js.map +1 -0
  55. package/dist/tests/e2e/run-local.d.ts +2 -0
  56. package/dist/tests/e2e/run-local.js +166 -0
  57. package/dist/tests/e2e/run-local.js.map +1 -0
  58. package/dist/tests/e2e/screen-vision.d.ts +11 -0
  59. package/dist/tests/e2e/screen-vision.js +384 -0
  60. package/dist/tests/e2e/screen-vision.js.map +1 -0
  61. package/dist/tests/e2e/vision-autonomy.d.ts +11 -0
  62. package/dist/tests/e2e/vision-autonomy.js +375 -0
  63. package/dist/tests/e2e/vision-autonomy.js.map +1 -0
  64. package/dist/tests/e2e/vision-basic.d.ts +11 -0
  65. package/dist/tests/e2e/vision-basic.js +434 -0
  66. package/dist/tests/e2e/vision-basic.js.map +1 -0
  67. package/dist/tests/e2e/vision-capture-log.d.ts +11 -0
  68. package/dist/tests/e2e/vision-capture-log.js +302 -0
  69. package/dist/tests/e2e/vision-capture-log.js.map +1 -0
  70. package/dist/tests/e2e/vision-runtime.d.ts +11 -0
  71. package/dist/tests/e2e/vision-runtime.js +357 -0
  72. package/dist/tests/e2e/vision-runtime.js.map +1 -0
  73. package/dist/tests/e2e/vision-worker-tests.d.ts +11 -0
  74. package/dist/tests/e2e/vision-worker-tests.js +466 -0
  75. package/dist/tests/e2e/vision-worker-tests.js.map +1 -0
  76. package/dist/tests/test-pattern-generator.d.ts +40 -0
  77. package/dist/tests/test-pattern-generator.js +191 -0
  78. package/dist/tests/test-pattern-generator.js.map +1 -0
  79. package/dist/tests.d.ts +3 -0
  80. package/dist/tests.js +11 -0
  81. package/dist/tests.js.map +1 -0
  82. package/dist/types.d.ts +222 -0
  83. package/dist/types.js +16 -0
  84. package/dist/types.js.map +1 -0
  85. package/dist/vision-models.d.ts +47 -0
  86. package/dist/vision-models.js +501 -0
  87. package/dist/vision-models.js.map +1 -0
  88. package/dist/vision-worker-manager.d.ts +61 -0
  89. package/dist/vision-worker-manager.js +668 -0
  90. package/dist/vision-worker-manager.js.map +1 -0
  91. package/dist/workers/florence2-worker-simple.d.ts +13 -0
  92. package/dist/workers/florence2-worker-simple.js +121 -0
  93. package/dist/workers/florence2-worker-simple.js.map +1 -0
  94. package/dist/workers/florence2-worker.d.ts +1 -0
  95. package/dist/workers/florence2-worker.js +328 -0
  96. package/dist/workers/florence2-worker.js.map +1 -0
  97. package/dist/workers/ocr-worker.d.ts +1 -0
  98. package/dist/workers/ocr-worker.js +354 -0
  99. package/dist/workers/ocr-worker.js.map +1 -0
  100. package/dist/workers/screen-capture-worker.d.ts +1 -0
  101. package/dist/workers/screen-capture-worker.js +427 -0
  102. package/dist/workers/screen-capture-worker.js.map +1 -0
  103. package/dist/workers/worker-logger.d.ts +9 -0
  104. package/dist/workers/worker-logger.js +95 -0
  105. package/dist/workers/worker-logger.js.map +1 -0
  106. package/package.json +100 -0
@@ -0,0 +1,427 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ var worker_threads_1 = require("worker_threads");
40
+ var child_process_1 = require("child_process");
41
+ var util_1 = require("util");
42
+ var fs = require("fs/promises");
43
+ var path = require("path");
44
+ var sharp_1 = require("sharp");
45
+ var worker_logger_1 = require("./worker-logger");
46
+ var execAsync = (0, util_1.promisify)(child_process_1.exec);
47
+ var ScreenCaptureWorker = /** @class */ (function () {
48
+ function ScreenCaptureWorker(config, sharedBuffer) {
49
+ this.isRunning = true;
50
+ this.frameCount = 0;
51
+ this.lastFPSReport = Date.now();
52
+ this.displays = [];
53
+ this.currentDisplayIndex = 0;
54
+ // Atomic indices
55
+ this.FRAME_ID_INDEX = 0;
56
+ this.WRITE_LOCK_INDEX = 1;
57
+ this.WIDTH_INDEX = 2;
58
+ this.HEIGHT_INDEX = 3;
59
+ this.DISPLAY_INDEX = 4;
60
+ this.TIMESTAMP_INDEX = 5;
61
+ this.DATA_OFFSET = 24; // 6 * 4 bytes for metadata
62
+ this.config = config;
63
+ this.sharedBuffer = sharedBuffer;
64
+ this.dataView = new DataView(sharedBuffer);
65
+ this.atomicState = new Int32Array(sharedBuffer, 0, 6);
66
+ }
67
+ ScreenCaptureWorker.prototype.initialize = function () {
68
+ return __awaiter(this, void 0, void 0, function () {
69
+ var _a;
70
+ return __generator(this, function (_b) {
71
+ switch (_b.label) {
72
+ case 0:
73
+ // Get display information
74
+ _a = this;
75
+ return [4 /*yield*/, this.getDisplays()];
76
+ case 1:
77
+ // Get display information
78
+ _a.displays = _b.sent();
79
+ if (this.displays.length === 0) {
80
+ throw new Error('No displays found');
81
+ }
82
+ // Set initial display
83
+ if (this.config.displayIndex !== undefined && this.config.displayIndex < this.displays.length) {
84
+ this.currentDisplayIndex = this.config.displayIndex;
85
+ }
86
+ worker_logger_1.logger.info("[ScreenCaptureWorker] Initialized with ".concat(this.displays.length, " displays"));
87
+ this.displays.forEach(function (d, i) {
88
+ worker_logger_1.logger.info(" Display ".concat(i, ": ").concat(d.name, " (").concat(d.width, "x").concat(d.height, ") ").concat(d.isPrimary ? '[PRIMARY]' : ''));
89
+ });
90
+ return [2 /*return*/];
91
+ }
92
+ });
93
+ });
94
+ };
95
+ ScreenCaptureWorker.prototype.getDisplays = function () {
96
+ return __awaiter(this, void 0, void 0, function () {
97
+ var platform, stdout, data, displays_1, gpuInfo, items, stdout, displays, lines, _i, lines_1, line, match, stdout, displays_2, lines, error_1;
98
+ return __generator(this, function (_a) {
99
+ switch (_a.label) {
100
+ case 0:
101
+ platform = process.platform;
102
+ _a.label = 1;
103
+ case 1:
104
+ _a.trys.push([1, 8, , 9]);
105
+ if (!(platform === 'darwin')) return [3 /*break*/, 3];
106
+ return [4 /*yield*/, execAsync('system_profiler SPDisplaysDataType -json')];
107
+ case 2:
108
+ stdout = (_a.sent()).stdout;
109
+ data = JSON.parse(stdout);
110
+ displays_1 = [];
111
+ if (data.SPDisplaysDataType && data.SPDisplaysDataType[0]) {
112
+ gpuInfo = data.SPDisplaysDataType[0];
113
+ items = gpuInfo._items || [];
114
+ items.forEach(function (item, index) {
115
+ var resolution = item.native_resolution;
116
+ if (resolution) {
117
+ var match = resolution.match(/(\d+) x (\d+)/);
118
+ if (match) {
119
+ displays_1.push({
120
+ id: "display-".concat(index),
121
+ name: item._name || "Display ".concat(index + 1),
122
+ width: parseInt(match[1], 10),
123
+ height: parseInt(match[2], 10),
124
+ x: 0,
125
+ y: 0,
126
+ isPrimary: index === 0,
127
+ });
128
+ }
129
+ }
130
+ });
131
+ }
132
+ return [2 /*return*/, displays_1];
133
+ case 3:
134
+ if (!(platform === 'linux')) return [3 /*break*/, 5];
135
+ return [4 /*yield*/, execAsync('xrandr --query')];
136
+ case 4:
137
+ stdout = (_a.sent()).stdout;
138
+ displays = [];
139
+ lines = stdout.split('\n');
140
+ for (_i = 0, lines_1 = lines; _i < lines_1.length; _i++) {
141
+ line = lines_1[_i];
142
+ if (line.includes(' connected')) {
143
+ match = line.match(/^(\S+) connected (?:primary )?(\d+)x(\d+)\+(\d+)\+(\d+)/);
144
+ if (match) {
145
+ displays.push({
146
+ id: match[1],
147
+ name: match[1],
148
+ width: parseInt(match[2], 10),
149
+ height: parseInt(match[3], 10),
150
+ x: parseInt(match[4], 10),
151
+ y: parseInt(match[5], 10),
152
+ isPrimary: line.includes('primary'),
153
+ });
154
+ }
155
+ }
156
+ }
157
+ return [2 /*return*/, displays];
158
+ case 5:
159
+ if (!(platform === 'win32')) return [3 /*break*/, 7];
160
+ return [4 /*yield*/, execAsync('wmic path Win32_DesktopMonitor get DeviceID,ScreenWidth,ScreenHeight /format:csv')];
161
+ case 6:
162
+ stdout = (_a.sent()).stdout;
163
+ displays_2 = [];
164
+ lines = stdout.trim().split('\n').slice(2);
165
+ lines.forEach(function (line, index) {
166
+ var parts = line.split(',');
167
+ if (parts.length >= 4) {
168
+ var width = parseInt(parts[2], 10);
169
+ var height = parseInt(parts[3], 10);
170
+ if (!isNaN(width) && !isNaN(height)) {
171
+ displays_2.push({
172
+ id: parts[1],
173
+ name: parts[1] || "Display ".concat(index + 1),
174
+ width: width,
175
+ height: height,
176
+ x: 0,
177
+ y: 0,
178
+ isPrimary: index === 0,
179
+ });
180
+ }
181
+ }
182
+ });
183
+ return [2 /*return*/, displays_2.length > 0
184
+ ? displays_2
185
+ : [
186
+ {
187
+ id: 'primary',
188
+ name: 'Primary Display',
189
+ width: 1920,
190
+ height: 1080,
191
+ x: 0,
192
+ y: 0,
193
+ isPrimary: true,
194
+ },
195
+ ]];
196
+ case 7: return [3 /*break*/, 9];
197
+ case 8:
198
+ error_1 = _a.sent();
199
+ worker_logger_1.logger.error('[ScreenCaptureWorker] Failed to get display info:', error_1);
200
+ return [3 /*break*/, 9];
201
+ case 9:
202
+ // Fallback
203
+ return [2 /*return*/, [
204
+ {
205
+ id: 'default',
206
+ name: 'Default Display',
207
+ width: 1920,
208
+ height: 1080,
209
+ x: 0,
210
+ y: 0,
211
+ isPrimary: true,
212
+ },
213
+ ]];
214
+ }
215
+ });
216
+ });
217
+ };
218
+ ScreenCaptureWorker.prototype.run = function () {
219
+ return __awaiter(this, void 0, void 0, function () {
220
+ var _loop_1, this_1;
221
+ return __generator(this, function (_a) {
222
+ switch (_a.label) {
223
+ case 0: return [4 /*yield*/, this.initialize()];
224
+ case 1:
225
+ _a.sent();
226
+ worker_logger_1.logger.info('[ScreenCaptureWorker] Starting capture loop...');
227
+ _loop_1 = function () {
228
+ var startTime, now, fps, frameTime_1, elapsed_1, error_2;
229
+ return __generator(this, function (_b) {
230
+ switch (_b.label) {
231
+ case 0:
232
+ startTime = Date.now();
233
+ _b.label = 1;
234
+ case 1:
235
+ _b.trys.push([1, 5, , 7]);
236
+ return [4 /*yield*/, this_1.captureFrame()];
237
+ case 2:
238
+ _b.sent();
239
+ this_1.frameCount++;
240
+ now = Date.now();
241
+ if (now - this_1.lastFPSReport >= 1000) {
242
+ fps = this_1.frameCount / ((now - this_1.lastFPSReport) / 1000);
243
+ worker_logger_1.logger.info("[ScreenCaptureWorker] FPS: ".concat(fps.toFixed(2), ", Display: ").concat(this_1.currentDisplayIndex));
244
+ worker_threads_1.parentPort === null || worker_threads_1.parentPort === void 0 ? void 0 : worker_threads_1.parentPort.postMessage({
245
+ type: 'fps',
246
+ fps: fps,
247
+ frameCount: this_1.frameCount,
248
+ displayIndex: this_1.currentDisplayIndex,
249
+ });
250
+ this_1.frameCount = 0;
251
+ this_1.lastFPSReport = now;
252
+ }
253
+ // Cycle through displays if configured
254
+ if (this_1.config.captureAllDisplays && this_1.displays.length > 1) {
255
+ this_1.currentDisplayIndex = (this_1.currentDisplayIndex + 1) % this_1.displays.length;
256
+ }
257
+ if (!this_1.config.targetFPS) return [3 /*break*/, 4];
258
+ frameTime_1 = 1000 / this_1.config.targetFPS;
259
+ elapsed_1 = Date.now() - startTime;
260
+ if (!(elapsed_1 < frameTime_1)) return [3 /*break*/, 4];
261
+ return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, frameTime_1 - elapsed_1); })];
262
+ case 3:
263
+ _b.sent();
264
+ _b.label = 4;
265
+ case 4: return [3 /*break*/, 7];
266
+ case 5:
267
+ error_2 = _b.sent();
268
+ worker_logger_1.logger.error('[ScreenCaptureWorker] Capture error:', error_2);
269
+ return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 100); })];
270
+ case 6:
271
+ _b.sent(); // Brief pause on error
272
+ return [3 /*break*/, 7];
273
+ case 7: return [2 /*return*/];
274
+ }
275
+ });
276
+ };
277
+ this_1 = this;
278
+ _a.label = 2;
279
+ case 2:
280
+ if (!this.isRunning) return [3 /*break*/, 4];
281
+ return [5 /*yield**/, _loop_1()];
282
+ case 3:
283
+ _a.sent();
284
+ return [3 /*break*/, 2];
285
+ case 4: return [2 /*return*/];
286
+ }
287
+ });
288
+ });
289
+ };
290
+ ScreenCaptureWorker.prototype.captureFrame = function () {
291
+ return __awaiter(this, void 0, void 0, function () {
292
+ var display, tempFile, imageBuffer, image, metadata, width, height, rawData, maxDataSize, dataSize, i, error_3;
293
+ return __generator(this, function (_a) {
294
+ switch (_a.label) {
295
+ case 0:
296
+ display = this.displays[this.currentDisplayIndex];
297
+ tempFile = path.join(process.cwd(), "temp_screen_".concat(Date.now(), "_").concat(this.currentDisplayIndex, ".png"));
298
+ _a.label = 1;
299
+ case 1:
300
+ _a.trys.push([1, 7, , 9]);
301
+ // Capture the screen
302
+ return [4 /*yield*/, this.captureScreenToFile(tempFile, display)];
303
+ case 2:
304
+ // Capture the screen
305
+ _a.sent();
306
+ return [4 /*yield*/, fs.readFile(tempFile)];
307
+ case 3:
308
+ imageBuffer = _a.sent();
309
+ image = (0, sharp_1.default)(imageBuffer);
310
+ return [4 /*yield*/, image.metadata()];
311
+ case 4:
312
+ metadata = _a.sent();
313
+ width = metadata.width || display.width;
314
+ height = metadata.height || display.height;
315
+ return [4 /*yield*/, image.ensureAlpha().raw().toBuffer()];
316
+ case 5:
317
+ rawData = _a.sent();
318
+ // Wait for write lock
319
+ while (Atomics.compareExchange(this.atomicState, this.WRITE_LOCK_INDEX, 0, 1) !== 0) {
320
+ // Spin wait - in practice this should be very brief
321
+ }
322
+ try {
323
+ // Write metadata
324
+ Atomics.store(this.atomicState, this.WIDTH_INDEX, width);
325
+ Atomics.store(this.atomicState, this.HEIGHT_INDEX, height);
326
+ Atomics.store(this.atomicState, this.DISPLAY_INDEX, this.currentDisplayIndex);
327
+ Atomics.store(this.atomicState, this.TIMESTAMP_INDEX, Date.now());
328
+ maxDataSize = this.sharedBuffer.byteLength - this.DATA_OFFSET;
329
+ dataSize = Math.min(rawData.length, maxDataSize);
330
+ for (i = 0; i < dataSize; i++) {
331
+ this.dataView.setUint8(this.DATA_OFFSET + i, rawData[i]);
332
+ }
333
+ // Update frame ID (signals new frame available)
334
+ Atomics.add(this.atomicState, this.FRAME_ID_INDEX, 1);
335
+ }
336
+ finally {
337
+ // Release write lock
338
+ Atomics.store(this.atomicState, this.WRITE_LOCK_INDEX, 0);
339
+ }
340
+ // Clean up temp file
341
+ return [4 /*yield*/, fs.unlink(tempFile).catch(function () { })];
342
+ case 6:
343
+ // Clean up temp file
344
+ _a.sent();
345
+ return [3 /*break*/, 9];
346
+ case 7:
347
+ error_3 = _a.sent();
348
+ // Clean up temp file on error
349
+ return [4 /*yield*/, fs.unlink(tempFile).catch(function () { })];
350
+ case 8:
351
+ // Clean up temp file on error
352
+ _a.sent();
353
+ throw error_3;
354
+ case 9: return [2 /*return*/];
355
+ }
356
+ });
357
+ });
358
+ };
359
+ ScreenCaptureWorker.prototype.captureScreenToFile = function (outputPath, display) {
360
+ return __awaiter(this, void 0, void 0, function () {
361
+ var platform, displayArg, script, error_4;
362
+ return __generator(this, function (_a) {
363
+ switch (_a.label) {
364
+ case 0:
365
+ platform = process.platform;
366
+ _a.label = 1;
367
+ case 1:
368
+ _a.trys.push([1, 11, , 12]);
369
+ if (!(platform === 'darwin')) return [3 /*break*/, 3];
370
+ displayArg = this.currentDisplayIndex > 0 ? "-D ".concat(this.currentDisplayIndex + 1) : '';
371
+ return [4 /*yield*/, execAsync("screencapture -x ".concat(displayArg, " \"").concat(outputPath, "\""))];
372
+ case 2:
373
+ _a.sent();
374
+ return [3 /*break*/, 10];
375
+ case 3:
376
+ if (!(platform === 'linux')) return [3 /*break*/, 8];
377
+ if (!(display.x !== 0 || display.y !== 0)) return [3 /*break*/, 5];
378
+ // Multi-monitor setup
379
+ return [4 /*yield*/, execAsync("scrot -a ".concat(display.x, ",").concat(display.y, ",").concat(display.width, ",").concat(display.height, " \"").concat(outputPath, "\""))];
380
+ case 4:
381
+ // Multi-monitor setup
382
+ _a.sent();
383
+ return [3 /*break*/, 7];
384
+ case 5: return [4 /*yield*/, execAsync("scrot \"".concat(outputPath, "\""))];
385
+ case 6:
386
+ _a.sent();
387
+ _a.label = 7;
388
+ case 7: return [3 /*break*/, 10];
389
+ case 8:
390
+ if (!(platform === 'win32')) return [3 /*break*/, 10];
391
+ script = "\n Add-Type -AssemblyName System.Windows.Forms;\n Add-Type -AssemblyName System.Drawing;\n $screens = [System.Windows.Forms.Screen]::AllScreens;\n $screen = $screens[".concat(this.currentDisplayIndex, "];\n $bounds = $screen.Bounds;\n $bitmap = New-Object System.Drawing.Bitmap $bounds.Width, $bounds.Height;\n $graphics = [System.Drawing.Graphics]::FromImage($bitmap);\n $graphics.CopyFromScreen($bounds.Location, [System.Drawing.Point]::Empty, $bounds.Size);\n $bitmap.Save('").concat(outputPath.replace(/\\/g, '\\\\'), "');\n $graphics.Dispose();\n $bitmap.Dispose();\n ");
392
+ return [4 /*yield*/, execAsync("powershell -Command \"".concat(script.replace(/\n/g, ' '), "\""))];
393
+ case 9:
394
+ _a.sent();
395
+ _a.label = 10;
396
+ case 10: return [3 /*break*/, 12];
397
+ case 11:
398
+ error_4 = _a.sent();
399
+ throw new Error("Screen capture failed: ".concat(error_4.message));
400
+ case 12: return [2 /*return*/];
401
+ }
402
+ });
403
+ });
404
+ };
405
+ ScreenCaptureWorker.prototype.stop = function () {
406
+ this.isRunning = false;
407
+ };
408
+ return ScreenCaptureWorker;
409
+ }());
410
+ // Worker entry point
411
+ if (worker_threads_1.parentPort) {
412
+ var config = worker_threads_1.workerData.config, sharedBuffer = worker_threads_1.workerData.sharedBuffer;
413
+ var worker_1 = new ScreenCaptureWorker(config, sharedBuffer);
414
+ // Handle messages from main thread
415
+ worker_threads_1.parentPort.on('message', function (msg) {
416
+ if (msg.type === 'stop') {
417
+ worker_1.stop();
418
+ }
419
+ });
420
+ // Run the worker
421
+ worker_1.run().catch(function (error) {
422
+ worker_logger_1.logger.error('[ScreenCaptureWorker] Fatal error:', error);
423
+ worker_threads_1.parentPort === null || worker_threads_1.parentPort === void 0 ? void 0 : worker_threads_1.parentPort.postMessage({ type: 'error', error: error.message });
424
+ process.exit(1);
425
+ });
426
+ }
427
+ //# sourceMappingURL=screen-capture-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen-capture-worker.js","sourceRoot":"","sources":["../../src/workers/screen-capture-worker.ts"],"names":[],"mappings":"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","sourcesContent":["import { parentPort, workerData } from 'worker_threads';\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport sharp from 'sharp';\nimport { logger } from './worker-logger';\n\nconst execAsync = promisify(exec);\n\ninterface WorkerConfig {\n displayIndex?: number;\n captureAllDisplays?: boolean;\n targetFPS?: number;\n sharedBufferSize: number;\n}\n\ninterface DisplayInfo {\n id: string;\n name: string;\n width: number;\n height: number;\n x: number;\n y: number;\n isPrimary?: boolean;\n}\n\nclass ScreenCaptureWorker {\n private config: WorkerConfig;\n private sharedBuffer: SharedArrayBuffer;\n private dataView: DataView;\n private atomicState: Int32Array;\n private isRunning = true;\n private frameCount = 0;\n private lastFPSReport = Date.now();\n private displays: DisplayInfo[] = [];\n private currentDisplayIndex = 0;\n\n // Atomic indices\n private readonly FRAME_ID_INDEX = 0;\n private readonly WRITE_LOCK_INDEX = 1;\n private readonly WIDTH_INDEX = 2;\n private readonly HEIGHT_INDEX = 3;\n private readonly DISPLAY_INDEX = 4;\n private readonly TIMESTAMP_INDEX = 5;\n private readonly DATA_OFFSET = 24; // 6 * 4 bytes for metadata\n\n constructor(config: WorkerConfig, sharedBuffer: SharedArrayBuffer) {\n this.config = config;\n this.sharedBuffer = sharedBuffer;\n this.dataView = new DataView(sharedBuffer);\n this.atomicState = new Int32Array(sharedBuffer, 0, 6);\n }\n\n async initialize(): Promise<void> {\n // Get display information\n this.displays = await this.getDisplays();\n\n if (this.displays.length === 0) {\n throw new Error('No displays found');\n }\n\n // Set initial display\n if (this.config.displayIndex !== undefined && this.config.displayIndex < this.displays.length) {\n this.currentDisplayIndex = this.config.displayIndex;\n }\n\n logger.info(`[ScreenCaptureWorker] Initialized with ${this.displays.length} displays`);\n this.displays.forEach((d, i) => {\n logger.info(\n ` Display ${i}: ${d.name} (${d.width}x${d.height}) ${d.isPrimary ? '[PRIMARY]' : ''}`\n );\n });\n }\n\n private async getDisplays(): Promise<DisplayInfo[]> {\n const platform = process.platform;\n\n try {\n if (platform === 'darwin') {\n // macOS: Use system_profiler\n const { stdout } = await execAsync('system_profiler SPDisplaysDataType -json');\n const data = JSON.parse(stdout);\n const displays: DisplayInfo[] = [];\n\n if (data.SPDisplaysDataType && data.SPDisplaysDataType[0]) {\n const gpuInfo = data.SPDisplaysDataType[0];\n const items = gpuInfo._items || [];\n\n items.forEach((item: any, index: number) => {\n const resolution = item.native_resolution;\n if (resolution) {\n const match = resolution.match(/(\\d+) x (\\d+)/);\n if (match) {\n displays.push({\n id: `display-${index}`,\n name: item._name || `Display ${index + 1}`,\n width: parseInt(match[1], 10),\n height: parseInt(match[2], 10),\n x: 0,\n y: 0,\n isPrimary: index === 0,\n });\n }\n }\n });\n }\n\n return displays;\n } else if (platform === 'linux') {\n // Linux: Use xrandr\n const { stdout } = await execAsync('xrandr --query');\n const displays: DisplayInfo[] = [];\n const lines = stdout.split('\\n');\n\n for (const line of lines) {\n if (line.includes(' connected')) {\n const match = line.match(/^(\\S+) connected (?:primary )?(\\d+)x(\\d+)\\+(\\d+)\\+(\\d+)/);\n if (match) {\n displays.push({\n id: match[1],\n name: match[1],\n width: parseInt(match[2], 10),\n height: parseInt(match[3], 10),\n x: parseInt(match[4], 10),\n y: parseInt(match[5], 10),\n isPrimary: line.includes('primary'),\n });\n }\n }\n }\n\n return displays;\n } else if (platform === 'win32') {\n // Windows: Use wmic\n const { stdout } = await execAsync(\n 'wmic path Win32_DesktopMonitor get DeviceID,ScreenWidth,ScreenHeight /format:csv'\n );\n const displays: DisplayInfo[] = [];\n const lines = stdout.trim().split('\\n').slice(2); // Skip headers\n\n lines.forEach((line, index) => {\n const parts = line.split(',');\n if (parts.length >= 4) {\n const width = parseInt(parts[2], 10);\n const height = parseInt(parts[3], 10);\n if (!isNaN(width) && !isNaN(height)) {\n displays.push({\n id: parts[1],\n name: parts[1] || `Display ${index + 1}`,\n width,\n height,\n x: 0,\n y: 0,\n isPrimary: index === 0,\n });\n }\n }\n });\n\n return displays.length > 0\n ? displays\n : [\n {\n id: 'primary',\n name: 'Primary Display',\n width: 1920,\n height: 1080,\n x: 0,\n y: 0,\n isPrimary: true,\n },\n ];\n }\n } catch (error) {\n logger.error('[ScreenCaptureWorker] Failed to get display info:', error);\n }\n\n // Fallback\n return [\n {\n id: 'default',\n name: 'Default Display',\n width: 1920,\n height: 1080,\n x: 0,\n y: 0,\n isPrimary: true,\n },\n ];\n }\n\n async run(): Promise<void> {\n await this.initialize();\n\n logger.info('[ScreenCaptureWorker] Starting capture loop...');\n\n while (this.isRunning) {\n const startTime = Date.now();\n\n try {\n await this.captureFrame();\n this.frameCount++;\n\n // Report FPS every second\n const now = Date.now();\n if (now - this.lastFPSReport >= 1000) {\n const fps = this.frameCount / ((now - this.lastFPSReport) / 1000);\n logger.info(\n `[ScreenCaptureWorker] FPS: ${fps.toFixed(2)}, Display: ${this.currentDisplayIndex}`\n );\n\n parentPort?.postMessage({\n type: 'fps',\n fps,\n frameCount: this.frameCount,\n displayIndex: this.currentDisplayIndex,\n });\n\n this.frameCount = 0;\n this.lastFPSReport = now;\n }\n\n // Cycle through displays if configured\n if (this.config.captureAllDisplays && this.displays.length > 1) {\n this.currentDisplayIndex = (this.currentDisplayIndex + 1) % this.displays.length;\n }\n\n // Target FPS limiting\n if (this.config.targetFPS) {\n const frameTime = 1000 / this.config.targetFPS;\n const elapsed = Date.now() - startTime;\n if (elapsed < frameTime) {\n await new Promise((resolve) => setTimeout(resolve, frameTime - elapsed));\n }\n }\n } catch (error) {\n logger.error('[ScreenCaptureWorker] Capture error:', error);\n await new Promise((resolve) => setTimeout(resolve, 100)); // Brief pause on error\n }\n }\n }\n\n private async captureFrame(): Promise<void> {\n const display = this.displays[this.currentDisplayIndex];\n const tempFile = path.join(\n process.cwd(),\n `temp_screen_${Date.now()}_${this.currentDisplayIndex}.png`\n );\n\n try {\n // Capture the screen\n await this.captureScreenToFile(tempFile, display);\n\n // Load and process the image\n const imageBuffer = await fs.readFile(tempFile);\n const image = sharp(imageBuffer);\n const metadata = await image.metadata();\n\n const width = metadata.width || display.width;\n const height = metadata.height || display.height;\n\n // Convert to raw RGBA for shared buffer\n const rawData = await image.ensureAlpha().raw().toBuffer();\n\n // Wait for write lock\n while (Atomics.compareExchange(this.atomicState, this.WRITE_LOCK_INDEX, 0, 1) !== 0) {\n // Spin wait - in practice this should be very brief\n }\n\n try {\n // Write metadata\n Atomics.store(this.atomicState, this.WIDTH_INDEX, width);\n Atomics.store(this.atomicState, this.HEIGHT_INDEX, height);\n Atomics.store(this.atomicState, this.DISPLAY_INDEX, this.currentDisplayIndex);\n Atomics.store(this.atomicState, this.TIMESTAMP_INDEX, Date.now());\n\n // Write image data\n const maxDataSize = this.sharedBuffer.byteLength - this.DATA_OFFSET;\n const dataSize = Math.min(rawData.length, maxDataSize);\n\n for (let i = 0; i < dataSize; i++) {\n this.dataView.setUint8(this.DATA_OFFSET + i, rawData[i]);\n }\n\n // Update frame ID (signals new frame available)\n Atomics.add(this.atomicState, this.FRAME_ID_INDEX, 1);\n } finally {\n // Release write lock\n Atomics.store(this.atomicState, this.WRITE_LOCK_INDEX, 0);\n }\n\n // Clean up temp file\n await fs.unlink(tempFile).catch(() => {});\n } catch (error) {\n // Clean up temp file on error\n await fs.unlink(tempFile).catch(() => {});\n throw error;\n }\n }\n\n private async captureScreenToFile(outputPath: string, display: DisplayInfo): Promise<void> {\n const platform = process.platform;\n\n try {\n if (platform === 'darwin') {\n // macOS: Use screencapture with display index\n const displayArg = this.currentDisplayIndex > 0 ? `-D ${this.currentDisplayIndex + 1}` : '';\n await execAsync(`screencapture -x ${displayArg} \"${outputPath}\"`);\n } else if (platform === 'linux') {\n // Linux: Use scrot with geometry for specific display\n if (display.x !== 0 || display.y !== 0) {\n // Multi-monitor setup\n await execAsync(\n `scrot -a ${display.x},${display.y},${display.width},${display.height} \"${outputPath}\"`\n );\n } else {\n await execAsync(`scrot \"${outputPath}\"`);\n }\n } else if (platform === 'win32') {\n // Windows: PowerShell script for specific monitor\n const script = `\n Add-Type -AssemblyName System.Windows.Forms;\n Add-Type -AssemblyName System.Drawing;\n $screens = [System.Windows.Forms.Screen]::AllScreens;\n $screen = $screens[${this.currentDisplayIndex}];\n $bounds = $screen.Bounds;\n $bitmap = New-Object System.Drawing.Bitmap $bounds.Width, $bounds.Height;\n $graphics = [System.Drawing.Graphics]::FromImage($bitmap);\n $graphics.CopyFromScreen($bounds.Location, [System.Drawing.Point]::Empty, $bounds.Size);\n $bitmap.Save('${outputPath.replace(/\\\\/g, '\\\\\\\\')}');\n $graphics.Dispose();\n $bitmap.Dispose();\n `;\n await execAsync(`powershell -Command \"${script.replace(/\\n/g, ' ')}\"`);\n }\n } catch (error: any) {\n throw new Error(`Screen capture failed: ${error.message}`);\n }\n }\n\n stop(): void {\n this.isRunning = false;\n }\n}\n\n// Worker entry point\nif (parentPort) {\n const { config, sharedBuffer } = workerData;\n const worker = new ScreenCaptureWorker(config, sharedBuffer);\n\n // Handle messages from main thread\n parentPort.on('message', (msg) => {\n if (msg.type === 'stop') {\n worker.stop();\n }\n });\n\n // Run the worker\n worker.run().catch((error) => {\n logger.error('[ScreenCaptureWorker] Fatal error:', error);\n parentPort?.postMessage({ type: 'error', error: error.message });\n process.exit(1);\n });\n}\n"]}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Worker-safe logger that sends log messages to the main thread
3
+ */
4
+ export declare const logger: {
5
+ info: (message: string, ...args: any[]) => void;
6
+ warn: (message: string, ...args: any[]) => void;
7
+ error: (message: string, ...args: any[]) => void;
8
+ debug: (message: string, ...args: any[]) => void;
9
+ };
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
3
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
4
+ if (ar || !(i in from)) {
5
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
6
+ ar[i] = from[i];
7
+ }
8
+ }
9
+ return to.concat(ar || Array.prototype.slice.call(from));
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.logger = void 0;
13
+ var worker_threads_1 = require("worker_threads");
14
+ /**
15
+ * Worker-safe logger that sends log messages to the main thread
16
+ */
17
+ exports.logger = {
18
+ info: function (message) {
19
+ var args = [];
20
+ for (var _i = 1; _i < arguments.length; _i++) {
21
+ args[_i - 1] = arguments[_i];
22
+ }
23
+ var logMessage = {
24
+ type: 'log',
25
+ level: 'info',
26
+ message: message,
27
+ args: args,
28
+ timestamp: new Date().toISOString(),
29
+ };
30
+ if (worker_threads_1.parentPort) {
31
+ worker_threads_1.parentPort.postMessage(logMessage);
32
+ }
33
+ else {
34
+ console.log.apply(console, __spreadArray(["[INFO] ".concat(message)], args, false));
35
+ }
36
+ },
37
+ warn: function (message) {
38
+ var args = [];
39
+ for (var _i = 1; _i < arguments.length; _i++) {
40
+ args[_i - 1] = arguments[_i];
41
+ }
42
+ var logMessage = {
43
+ type: 'log',
44
+ level: 'warn',
45
+ message: message,
46
+ args: args,
47
+ timestamp: new Date().toISOString(),
48
+ };
49
+ if (worker_threads_1.parentPort) {
50
+ worker_threads_1.parentPort.postMessage(logMessage);
51
+ }
52
+ else {
53
+ console.warn.apply(console, __spreadArray(["[WARN] ".concat(message)], args, false));
54
+ }
55
+ },
56
+ error: function (message) {
57
+ var args = [];
58
+ for (var _i = 1; _i < arguments.length; _i++) {
59
+ args[_i - 1] = arguments[_i];
60
+ }
61
+ var logMessage = {
62
+ type: 'log',
63
+ level: 'error',
64
+ message: message,
65
+ args: args,
66
+ timestamp: new Date().toISOString(),
67
+ };
68
+ if (worker_threads_1.parentPort) {
69
+ worker_threads_1.parentPort.postMessage(logMessage);
70
+ }
71
+ else {
72
+ console.error.apply(console, __spreadArray(["[ERROR] ".concat(message)], args, false));
73
+ }
74
+ },
75
+ debug: function (message) {
76
+ var args = [];
77
+ for (var _i = 1; _i < arguments.length; _i++) {
78
+ args[_i - 1] = arguments[_i];
79
+ }
80
+ var logMessage = {
81
+ type: 'log',
82
+ level: 'debug',
83
+ message: message,
84
+ args: args,
85
+ timestamp: new Date().toISOString(),
86
+ };
87
+ if (worker_threads_1.parentPort) {
88
+ worker_threads_1.parentPort.postMessage(logMessage);
89
+ }
90
+ else {
91
+ console.debug.apply(console, __spreadArray(["[DEBUG] ".concat(message)], args, false));
92
+ }
93
+ },
94
+ };
95
+ //# sourceMappingURL=worker-logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-logger.js","sourceRoot":"","sources":["../../src/workers/worker-logger.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,iDAA4C;AAE5C;;GAEG;AACU,QAAA,MAAM,GAAG;IACpB,IAAI,EAAE,UAAC,OAAe;QAAE,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,6BAAc;;QACpC,IAAM,UAAU,GAAG;YACjB,IAAI,EAAE,KAAK;YACX,KAAK,EAAE,MAAM;YACb,OAAO,SAAA;YACP,IAAI,MAAA;YACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QAEF,IAAI,2BAAU,EAAE,CAAC;YACf,2BAAU,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,OAAX,OAAO,iBAAK,iBAAU,OAAO,CAAE,GAAK,IAAI,UAAE;QAC5C,CAAC;IACH,CAAC;IAED,IAAI,EAAE,UAAC,OAAe;QAAE,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,6BAAc;;QACpC,IAAM,UAAU,GAAG;YACjB,IAAI,EAAE,KAAK;YACX,KAAK,EAAE,MAAM;YACb,OAAO,SAAA;YACP,IAAI,MAAA;YACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QAEF,IAAI,2BAAU,EAAE,CAAC;YACf,2BAAU,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,OAAZ,OAAO,iBAAM,iBAAU,OAAO,CAAE,GAAK,IAAI,UAAE;QAC7C,CAAC;IACH,CAAC;IAED,KAAK,EAAE,UAAC,OAAe;QAAE,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,6BAAc;;QACrC,IAAM,UAAU,GAAG;YACjB,IAAI,EAAE,KAAK;YACX,KAAK,EAAE,OAAO;YACd,OAAO,SAAA;YACP,IAAI,MAAA;YACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QAEF,IAAI,2BAAU,EAAE,CAAC;YACf,2BAAU,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,OAAb,OAAO,iBAAO,kBAAW,OAAO,CAAE,GAAK,IAAI,UAAE;QAC/C,CAAC;IACH,CAAC;IAED,KAAK,EAAE,UAAC,OAAe;QAAE,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,6BAAc;;QACrC,IAAM,UAAU,GAAG;YACjB,IAAI,EAAE,KAAK;YACX,KAAK,EAAE,OAAO;YACd,OAAO,SAAA;YACP,IAAI,MAAA;YACJ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QAEF,IAAI,2BAAU,EAAE,CAAC;YACf,2BAAU,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,OAAb,OAAO,iBAAO,kBAAW,OAAO,CAAE,GAAK,IAAI,UAAE;QAC/C,CAAC;IACH,CAAC;CACF,CAAC","sourcesContent":["import { parentPort } from 'worker_threads';\n\n/**\n * Worker-safe logger that sends log messages to the main thread\n */\nexport const logger = {\n info: (message: string, ...args: any[]) => {\n const logMessage = {\n type: 'log',\n level: 'info',\n message,\n args,\n timestamp: new Date().toISOString(),\n };\n\n if (parentPort) {\n parentPort.postMessage(logMessage);\n } else {\n console.log(`[INFO] ${message}`, ...args);\n }\n },\n\n warn: (message: string, ...args: any[]) => {\n const logMessage = {\n type: 'log',\n level: 'warn',\n message,\n args,\n timestamp: new Date().toISOString(),\n };\n\n if (parentPort) {\n parentPort.postMessage(logMessage);\n } else {\n console.warn(`[WARN] ${message}`, ...args);\n }\n },\n\n error: (message: string, ...args: any[]) => {\n const logMessage = {\n type: 'log',\n level: 'error',\n message,\n args,\n timestamp: new Date().toISOString(),\n };\n\n if (parentPort) {\n parentPort.postMessage(logMessage);\n } else {\n console.error(`[ERROR] ${message}`, ...args);\n }\n },\n\n debug: (message: string, ...args: any[]) => {\n const logMessage = {\n type: 'log',\n level: 'debug',\n message,\n args,\n timestamp: new Date().toISOString(),\n };\n\n if (parentPort) {\n parentPort.postMessage(logMessage);\n } else {\n console.debug(`[DEBUG] ${message}`, ...args);\n }\n },\n};\n"]}