codeloop-mcp-server 0.1.3 → 0.1.5

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 (59) hide show
  1. package/dist/index.js +606 -20
  2. package/dist/index.js.map +1 -1
  3. package/dist/project-discovery.d.ts +17 -0
  4. package/dist/project-discovery.d.ts.map +1 -0
  5. package/dist/project-discovery.js +109 -0
  6. package/dist/project-discovery.js.map +1 -0
  7. package/dist/runners/app_logger.d.ts +31 -0
  8. package/dist/runners/app_logger.d.ts.map +1 -0
  9. package/dist/runners/app_logger.js +203 -0
  10. package/dist/runners/app_logger.js.map +1 -0
  11. package/dist/runners/base.d.ts.map +1 -1
  12. package/dist/runners/base.js +4 -2
  13. package/dist/runners/base.js.map +1 -1
  14. package/dist/runners/flutter.d.ts +1 -0
  15. package/dist/runners/flutter.d.ts.map +1 -1
  16. package/dist/runners/flutter.js +29 -0
  17. package/dist/runners/flutter.js.map +1 -1
  18. package/dist/runners/platform_detect.d.ts +14 -0
  19. package/dist/runners/platform_detect.d.ts.map +1 -0
  20. package/dist/runners/platform_detect.js +102 -0
  21. package/dist/runners/platform_detect.js.map +1 -0
  22. package/dist/runners/screenshot.d.ts +3 -7
  23. package/dist/runners/screenshot.d.ts.map +1 -1
  24. package/dist/runners/screenshot.js +115 -28
  25. package/dist/runners/screenshot.js.map +1 -1
  26. package/dist/runners/video_recorder.d.ts +47 -0
  27. package/dist/runners/video_recorder.d.ts.map +1 -0
  28. package/dist/runners/video_recorder.js +478 -0
  29. package/dist/runners/video_recorder.js.map +1 -0
  30. package/dist/runners/window_manager.d.ts +55 -0
  31. package/dist/runners/window_manager.d.ts.map +1 -0
  32. package/dist/runners/window_manager.js +481 -0
  33. package/dist/runners/window_manager.js.map +1 -0
  34. package/dist/tools/design_compare.d.ts +1 -1
  35. package/dist/tools/design_compare.d.ts.map +1 -1
  36. package/dist/tools/design_compare.js +1 -2
  37. package/dist/tools/design_compare.js.map +1 -1
  38. package/dist/tools/discover_screens.d.ts +14 -0
  39. package/dist/tools/discover_screens.d.ts.map +1 -0
  40. package/dist/tools/discover_screens.js +178 -0
  41. package/dist/tools/discover_screens.js.map +1 -0
  42. package/dist/tools/gate_check.js +13 -1
  43. package/dist/tools/gate_check.js.map +1 -1
  44. package/dist/tools/init-project.d.ts +15 -0
  45. package/dist/tools/init-project.d.ts.map +1 -0
  46. package/dist/tools/init-project.js +273 -0
  47. package/dist/tools/init-project.js.map +1 -0
  48. package/dist/tools/interaction_replay.d.ts +2 -1
  49. package/dist/tools/interaction_replay.d.ts.map +1 -1
  50. package/dist/tools/interaction_replay.js +24 -2
  51. package/dist/tools/interaction_replay.js.map +1 -1
  52. package/dist/tools/verify.d.ts.map +1 -1
  53. package/dist/tools/verify.js +235 -16
  54. package/dist/tools/verify.js.map +1 -1
  55. package/dist/tools/visual_review.d.ts +1 -1
  56. package/dist/tools/visual_review.d.ts.map +1 -1
  57. package/dist/tools/visual_review.js +1 -2
  58. package/dist/tools/visual_review.js.map +1 -1
  59. package/package.json +1 -1
@@ -0,0 +1,478 @@
1
+ import { existsSync, mkdirSync } from "fs";
2
+ import { join, dirname } from "path";
3
+ import { platform } from "os";
4
+ import { spawn, execFile } from "child_process";
5
+ import { runCommand, checkToolAvailable } from "./base.js";
6
+ import { findWindowId, bringAppToFront, restorePreviousApp, getWindowBounds, checkDependency } from "./window_manager.js";
7
+ import { startLogCapture, stopLogCapture } from "./app_logger.js";
8
+ /**
9
+ * Parse all macOS avfoundation screen capture device indices.
10
+ * Returns a map of screen index → ffmpeg device index, e.g. { 0: "4", 1: "5" }.
11
+ */
12
+ async function listMacOSScreenDevices() {
13
+ return new Promise((resolve) => {
14
+ execFile("ffmpeg", ["-f", "avfoundation", "-list_devices", "true", "-i", ""], {
15
+ timeout: 5000,
16
+ }, (_err, _stdout, stderr) => {
17
+ const devices = new Map();
18
+ const lines = (stderr || "").split("\n");
19
+ for (const line of lines) {
20
+ const match = line.match(/\[(\d+)\]\s+Capture screen\s+(\d+)/i);
21
+ if (match) {
22
+ devices.set(parseInt(match[2], 10), match[1]);
23
+ }
24
+ }
25
+ resolve(devices);
26
+ });
27
+ });
28
+ }
29
+ /**
30
+ * Get screen origins (logical coordinates) for each display.
31
+ * Returns array of { index, x, y, width, height } sorted by index.
32
+ */
33
+ async function getMacOSScreenBounds() {
34
+ return new Promise((resolve) => {
35
+ const script = `
36
+ import AppKit
37
+ for (i, screen) in NSScreen.screens.enumerated() {
38
+ let f = screen.frame
39
+ print("\\(i),\\(Int(f.origin.x)),\\(Int(f.origin.y)),\\(Int(f.width)),\\(Int(f.height))")
40
+ }`;
41
+ execFile("swift", ["-e", script], { timeout: 10000 }, (_err, stdout) => {
42
+ const screens = [];
43
+ for (const line of (stdout || "").trim().split("\n")) {
44
+ const parts = line.split(",").map(Number);
45
+ if (parts.length === 5 && !parts.some(isNaN)) {
46
+ screens.push({ index: parts[0], x: parts[1], y: parts[2], width: parts[3], height: parts[4] });
47
+ }
48
+ }
49
+ resolve(screens);
50
+ });
51
+ });
52
+ }
53
+ /**
54
+ * Find the correct macOS avfoundation device index for the screen
55
+ * that contains the given window bounds. Falls back to screen 0.
56
+ */
57
+ async function findMacOSScreenDevice(windowBounds) {
58
+ const devices = await listMacOSScreenDevices();
59
+ if (devices.size === 0)
60
+ return "1";
61
+ if (devices.size === 1 || !windowBounds)
62
+ return devices.values().next().value;
63
+ const screens = await getMacOSScreenBounds();
64
+ if (screens.length === 0)
65
+ return devices.get(0) ?? devices.values().next().value;
66
+ const windowCenterX = windowBounds.x + windowBounds.width / 2;
67
+ const windowCenterY = windowBounds.y + windowBounds.height / 2;
68
+ for (const screen of screens) {
69
+ if (windowCenterX >= screen.x &&
70
+ windowCenterX < screen.x + screen.width &&
71
+ windowCenterY >= screen.y &&
72
+ windowCenterY < screen.y + screen.height) {
73
+ const device = devices.get(screen.index);
74
+ if (device)
75
+ return device;
76
+ }
77
+ }
78
+ return devices.get(0) ?? devices.values().next().value;
79
+ }
80
+ const activeRecordings = new Map();
81
+ /**
82
+ * Blocking video recording. Brings app to front, records for a fixed
83
+ * duration, then restores the previous frontmost app.
84
+ */
85
+ export async function recordVideo(outputDir, durationSeconds = 10, appName) {
86
+ mkdirSync(outputDir, { recursive: true });
87
+ const os = platform();
88
+ let previousApp = "";
89
+ if (appName) {
90
+ previousApp = await bringAppToFront(appName);
91
+ }
92
+ let result;
93
+ if (os === "darwin") {
94
+ result = await recordMacOS(outputDir, durationSeconds, appName);
95
+ }
96
+ else if (os === "win32") {
97
+ result = await recordWindows(outputDir, durationSeconds, appName);
98
+ }
99
+ else {
100
+ result = await recordLinux(outputDir, durationSeconds, appName);
101
+ }
102
+ if (previousApp && previousApp !== appName) {
103
+ await restorePreviousApp(previousApp);
104
+ }
105
+ return result;
106
+ }
107
+ /**
108
+ * Start recording in the background. Returns a handle immediately so the
109
+ * agent can interact with the app while recording is active.
110
+ * Call stopBackgroundRecording() when done.
111
+ *
112
+ * targetType selects the capture method:
113
+ * - "desktop": ffmpeg screen capture (macOS/Windows/Linux)
114
+ * - "android_emulator": adb shell screenrecord
115
+ * - "ios_simulator": xcrun simctl io booted recordVideo
116
+ * - "browser": ffmpeg or Playwright recordVideo
117
+ */
118
+ export async function startBackgroundRecording(outputDir, appName, maxDurationSeconds = 120, targetType = "desktop") {
119
+ mkdirSync(outputDir, { recursive: true });
120
+ const os = platform();
121
+ const recordingId = `rec_${Date.now()}`;
122
+ const outputPath = join(outputDir, `recording_${Date.now()}.mp4`);
123
+ const logsDir = join(dirname(outputDir), "logs");
124
+ let child;
125
+ // ── Android emulator: use adb screenrecord ──
126
+ if (targetType === "android_emulator") {
127
+ const depErr = await checkDependency("adb", "Android emulator video recording");
128
+ if (depErr)
129
+ return { error: depErr };
130
+ const devicePath = "/sdcard/codeloop_rec.mp4";
131
+ child = spawn("adb", [
132
+ "shell", "screenrecord", "--time-limit", String(Math.min(maxDurationSeconds, 180)),
133
+ devicePath,
134
+ ], { cwd: process.cwd(), stdio: "pipe", detached: false });
135
+ activeRecordings.set(recordingId, {
136
+ process: child,
137
+ outputPath,
138
+ appName,
139
+ previousApp: "",
140
+ startedAt: Date.now(),
141
+ targetType,
142
+ });
143
+ child.on("exit", () => { });
144
+ const logResult = await startLogCapture(logsDir, appName, targetType);
145
+ const hasLog = !("error" in logResult);
146
+ if (hasLog) {
147
+ const rec = activeRecordings.get(recordingId);
148
+ if (rec) {
149
+ rec.logPath = logResult.logPath;
150
+ rec.logId = logResult.logId;
151
+ }
152
+ }
153
+ return {
154
+ recording_id: recordingId,
155
+ output_path: outputPath,
156
+ app_name: appName,
157
+ previous_app: "",
158
+ started_at: Date.now(),
159
+ target_type: targetType,
160
+ log_capture: hasLog,
161
+ };
162
+ }
163
+ // ── iOS Simulator: use xcrun simctl io recordVideo ──
164
+ if (targetType === "ios_simulator") {
165
+ if (os !== "darwin") {
166
+ return { error: "iOS Simulator recording is only available on macOS. iOS development requires a Mac." };
167
+ }
168
+ const depErr = await checkDependency("xcrun", "iOS Simulator video recording");
169
+ if (depErr)
170
+ return { error: depErr };
171
+ child = spawn("xcrun", [
172
+ "simctl", "io", "booted", "recordVideo", "--codec=h264", outputPath,
173
+ ], { cwd: process.cwd(), stdio: "pipe", detached: false });
174
+ activeRecordings.set(recordingId, {
175
+ process: child,
176
+ outputPath,
177
+ appName,
178
+ previousApp: "",
179
+ startedAt: Date.now(),
180
+ targetType,
181
+ });
182
+ child.on("exit", () => { });
183
+ const logResult = await startLogCapture(logsDir, appName, targetType);
184
+ const hasLog = !("error" in logResult);
185
+ if (hasLog) {
186
+ const rec = activeRecordings.get(recordingId);
187
+ if (rec) {
188
+ rec.logPath = logResult.logPath;
189
+ rec.logId = logResult.logId;
190
+ }
191
+ }
192
+ return {
193
+ recording_id: recordingId,
194
+ output_path: outputPath,
195
+ app_name: appName,
196
+ previous_app: "",
197
+ started_at: Date.now(),
198
+ target_type: targetType,
199
+ log_capture: hasLog,
200
+ };
201
+ }
202
+ // ── Desktop / Browser recording ──
203
+ const previousApp = await bringAppToFront(appName);
204
+ // Pre-flight: verify the window exists and is capturable
205
+ const windowId = await findWindowId(appName);
206
+ if (!windowId) {
207
+ await restorePreviousApp(previousApp);
208
+ return { error: `Cannot find a window for "${appName}". Make sure the app is running and has a visible window. Check the exact app name — it must match the process name shown in the menu bar (e.g., "Google Chrome", not "Chrome").` };
209
+ }
210
+ if (os === "darwin") {
211
+ if (await checkToolAvailable("ffmpeg")) {
212
+ const bounds = await getWindowBounds(appName);
213
+ const screenDevice = await findMacOSScreenDevice(bounds);
214
+ const ffmpegArgs = [
215
+ "-f", "avfoundation", "-framerate", "30", "-capture_cursor", "1",
216
+ "-i", `${screenDevice}:none`,
217
+ ];
218
+ if (bounds && bounds.width > 0 && bounds.height > 0) {
219
+ const scale = 2;
220
+ const cropW = bounds.width * scale;
221
+ const cropH = bounds.height * scale;
222
+ const cropX = bounds.x * scale;
223
+ const cropY = bounds.y * scale;
224
+ ffmpegArgs.push("-vf", `crop=${cropW}:${cropH}:${cropX}:${cropY}`);
225
+ }
226
+ ffmpegArgs.push("-r", "10", "-pix_fmt", "yuv420p", "-t", String(maxDurationSeconds), "-y", outputPath);
227
+ child = spawn("ffmpeg", ffmpegArgs, { cwd: process.cwd(), stdio: "pipe", detached: false });
228
+ }
229
+ else {
230
+ await restorePreviousApp(previousApp);
231
+ const depErr = await checkDependency("ffmpeg", "video recording");
232
+ return { error: depErr || "Neither screencapture nor ffmpeg available" };
233
+ }
234
+ }
235
+ else if (!(await checkToolAvailable("ffmpeg"))) {
236
+ await restorePreviousApp(previousApp);
237
+ const depErr = await checkDependency("ffmpeg", "video recording");
238
+ return { error: depErr || "ffmpeg not found" };
239
+ }
240
+ else if (os === "win32") {
241
+ const bounds = await getWindowBounds(appName);
242
+ if (bounds && bounds.width > 0 && bounds.height > 0) {
243
+ child = spawn("ffmpeg", [
244
+ "-f", "gdigrab", "-framerate", "10",
245
+ "-offset_x", String(bounds.x), "-offset_y", String(bounds.y),
246
+ "-video_size", `${bounds.width}x${bounds.height}`,
247
+ "-i", "desktop",
248
+ "-t", String(maxDurationSeconds), "-y", outputPath,
249
+ ], { cwd: process.cwd(), stdio: "pipe", detached: false });
250
+ }
251
+ else {
252
+ const inputSource = `title=${appName}`;
253
+ child = spawn("ffmpeg", [
254
+ "-f", "gdigrab", "-framerate", "10", "-i", inputSource,
255
+ "-t", String(maxDurationSeconds), "-y", outputPath,
256
+ ], { cwd: process.cwd(), stdio: "pipe", detached: false });
257
+ }
258
+ }
259
+ else {
260
+ const bounds = await getWindowBounds(appName);
261
+ if (bounds && bounds.width > 0 && bounds.height > 0) {
262
+ child = spawn("ffmpeg", [
263
+ "-f", "x11grab", "-framerate", "10",
264
+ "-video_size", `${bounds.width}x${bounds.height}`,
265
+ "-i", `:0.0+${bounds.x},${bounds.y}`,
266
+ "-t", String(maxDurationSeconds), "-y", outputPath,
267
+ ], { cwd: process.cwd(), stdio: "pipe", detached: false });
268
+ }
269
+ else {
270
+ child = spawn("ffmpeg", [
271
+ "-f", "x11grab", "-framerate", "10", "-video_size", "1920x1080",
272
+ "-i", ":0.0", "-t", String(maxDurationSeconds), "-y", outputPath,
273
+ ], { cwd: process.cwd(), stdio: "pipe", detached: false });
274
+ }
275
+ }
276
+ activeRecordings.set(recordingId, {
277
+ process: child,
278
+ outputPath,
279
+ appName,
280
+ previousApp,
281
+ startedAt: Date.now(),
282
+ targetType,
283
+ });
284
+ child.on("exit", () => {
285
+ /* auto-cleanup on natural exit (timeout) */
286
+ });
287
+ const logResult = await startLogCapture(logsDir, appName, targetType);
288
+ const hasLog = !("error" in logResult);
289
+ if (hasLog) {
290
+ const rec = activeRecordings.get(recordingId);
291
+ if (rec) {
292
+ rec.logPath = logResult.logPath;
293
+ rec.logId = logResult.logId;
294
+ }
295
+ }
296
+ return {
297
+ recording_id: recordingId,
298
+ output_path: outputPath,
299
+ app_name: appName,
300
+ previous_app: previousApp,
301
+ started_at: Date.now(),
302
+ target_type: targetType,
303
+ log_capture: hasLog,
304
+ };
305
+ }
306
+ /**
307
+ * Stop a background recording. Sends SIGINT to finalize the video file,
308
+ * then restores the previous frontmost app.
309
+ * For Android, pulls the recorded file from the device.
310
+ */
311
+ export async function stopBackgroundRecording(recordingId) {
312
+ const rec = activeRecordings.get(recordingId);
313
+ if (!rec) {
314
+ return {
315
+ recorded: false,
316
+ path: "",
317
+ duration_seconds: 0,
318
+ method: "background",
319
+ error: `No active recording found with id: ${recordingId}`,
320
+ };
321
+ }
322
+ const durationMs = Date.now() - rec.startedAt;
323
+ if (rec.process.exitCode === null) {
324
+ const os = platform();
325
+ if (os === "win32" && rec.process.stdin) {
326
+ rec.process.stdin.write("q");
327
+ rec.process.stdin.end();
328
+ }
329
+ else {
330
+ rec.process.kill("SIGINT");
331
+ }
332
+ await new Promise((resolve) => {
333
+ const timeout = setTimeout(() => {
334
+ rec.process.kill("SIGKILL");
335
+ resolve();
336
+ }, 5000);
337
+ rec.process.on("exit", () => {
338
+ clearTimeout(timeout);
339
+ resolve();
340
+ });
341
+ });
342
+ }
343
+ // For Android, pull the recorded file from the device
344
+ if (rec.targetType === "android_emulator") {
345
+ await new Promise(r => setTimeout(r, 1000));
346
+ const devicePath = "/sdcard/codeloop_rec.mp4";
347
+ await runCommand("adb", ["pull", devicePath, rec.outputPath], process.cwd());
348
+ await runCommand("adb", ["shell", "rm", devicePath], process.cwd());
349
+ }
350
+ // Stop log capture if active
351
+ if (rec.logId) {
352
+ const logPath = await stopLogCapture(rec.logId);
353
+ if (logPath)
354
+ rec.logPath = logPath;
355
+ }
356
+ activeRecordings.delete(recordingId);
357
+ if (rec.previousApp && rec.previousApp !== rec.appName) {
358
+ await restorePreviousApp(rec.previousApp);
359
+ }
360
+ if (existsSync(rec.outputPath)) {
361
+ const { statSync } = await import("fs");
362
+ const fileSize = statSync(rec.outputPath).size;
363
+ if (fileSize < 1024) {
364
+ return {
365
+ recorded: false,
366
+ path: rec.outputPath,
367
+ duration_seconds: Math.round(durationMs / 1000),
368
+ method: `background recording (${rec.appName}, ${rec.targetType})`,
369
+ error: `Video file created but too small (${fileSize} bytes). The recording may have captured a blank screen. Check that the app window is visible and not on a different monitor. Use codeloop_capture_screenshot first to verify the correct window is being targeted.`,
370
+ log_path: rec.logPath,
371
+ };
372
+ }
373
+ return {
374
+ recorded: true,
375
+ path: rec.outputPath,
376
+ duration_seconds: Math.round(durationMs / 1000),
377
+ method: `background recording (${rec.appName}, ${rec.targetType})`,
378
+ log_path: rec.logPath,
379
+ };
380
+ }
381
+ return {
382
+ recorded: false,
383
+ path: "",
384
+ duration_seconds: Math.round(durationMs / 1000),
385
+ method: "background",
386
+ error: `Recording process exited but no video file was created. Possible causes: (1) The app "${rec.appName}" window was not found — verify the exact app name. (2) On macOS multi-monitor setups, the wrong screen device may have been selected. (3) ffmpeg/screencapture may lack Screen Recording permission (System Settings > Privacy & Security > Screen Recording). Try running codeloop_capture_screenshot first to verify the app window can be captured.`,
387
+ };
388
+ }
389
+ /** List all active background recordings. */
390
+ export function listActiveRecordings() {
391
+ return Array.from(activeRecordings.keys());
392
+ }
393
+ async function recordMacOS(outputDir, durationSeconds, appName) {
394
+ if (!(await checkToolAvailable("screencapture"))) {
395
+ return { recorded: false, path: "", duration_seconds: durationSeconds, method: "screencapture", error: "screencapture not found" };
396
+ }
397
+ const outputPath = join(outputDir, `recording_${Date.now()}.mov`);
398
+ const args = ["-v", "-V", String(durationSeconds), "-x"];
399
+ if (appName) {
400
+ const windowId = await findWindowId(appName);
401
+ if (windowId) {
402
+ args.push("-l", windowId);
403
+ }
404
+ }
405
+ args.push(outputPath);
406
+ const result = await runCommand("screencapture", args, process.cwd());
407
+ if (result.exit_code === 0 && existsSync(outputPath)) {
408
+ return {
409
+ recorded: true,
410
+ path: outputPath,
411
+ duration_seconds: durationSeconds,
412
+ method: appName ? `screencapture -v (window: ${appName})` : "screencapture -v (full screen)",
413
+ };
414
+ }
415
+ return {
416
+ recorded: false,
417
+ path: "",
418
+ duration_seconds: durationSeconds,
419
+ method: "screencapture",
420
+ error: result.stderr || `screencapture exited with code ${result.exit_code}`,
421
+ };
422
+ }
423
+ async function recordWindows(outputDir, durationSeconds, appName) {
424
+ if (!(await checkToolAvailable("ffmpeg"))) {
425
+ return { recorded: false, path: "", duration_seconds: durationSeconds, method: "ffmpeg", error: "ffmpeg not found — install with: winget install ffmpeg" };
426
+ }
427
+ const outputPath = join(outputDir, `recording_${Date.now()}.mp4`);
428
+ const inputSource = appName ? `title=${appName}` : "desktop";
429
+ const result = await runCommand("ffmpeg", ["-f", "gdigrab", "-framerate", "10", "-i", inputSource, "-t", String(durationSeconds), "-y", outputPath], process.cwd());
430
+ if (result.exit_code === 0 && existsSync(outputPath)) {
431
+ return {
432
+ recorded: true,
433
+ path: outputPath,
434
+ duration_seconds: durationSeconds,
435
+ method: appName ? `ffmpeg gdigrab (window: ${appName})` : "ffmpeg gdigrab (desktop)",
436
+ };
437
+ }
438
+ return {
439
+ recorded: false,
440
+ path: "",
441
+ duration_seconds: durationSeconds,
442
+ method: "ffmpeg",
443
+ error: result.stderr || `ffmpeg exited with code ${result.exit_code}`,
444
+ };
445
+ }
446
+ async function recordLinux(outputDir, durationSeconds, appName) {
447
+ if (!(await checkToolAvailable("ffmpeg"))) {
448
+ const depErr = await checkDependency("ffmpeg", "video recording");
449
+ return { recorded: false, path: "", duration_seconds: durationSeconds, method: "ffmpeg", error: depErr || "ffmpeg not found" };
450
+ }
451
+ const outputPath = join(outputDir, `recording_${Date.now()}.mp4`);
452
+ const bounds = appName ? await getWindowBounds(appName) : null;
453
+ const ffmpegArgs = ["-f", "x11grab", "-framerate", "10"];
454
+ if (bounds && bounds.width > 0 && bounds.height > 0) {
455
+ ffmpegArgs.push("-video_size", `${bounds.width}x${bounds.height}`, "-i", `:0.0+${bounds.x},${bounds.y}`);
456
+ }
457
+ else {
458
+ ffmpegArgs.push("-video_size", "1920x1080", "-i", ":0.0");
459
+ }
460
+ ffmpegArgs.push("-t", String(durationSeconds), "-y", outputPath);
461
+ const result = await runCommand("ffmpeg", ffmpegArgs, process.cwd());
462
+ if (result.exit_code === 0 && existsSync(outputPath)) {
463
+ return {
464
+ recorded: true,
465
+ path: outputPath,
466
+ duration_seconds: durationSeconds,
467
+ method: bounds ? `ffmpeg x11grab (window: ${appName})` : "ffmpeg x11grab (full screen)",
468
+ };
469
+ }
470
+ return {
471
+ recorded: false,
472
+ path: "",
473
+ duration_seconds: durationSeconds,
474
+ method: "ffmpeg",
475
+ error: result.stderr || `ffmpeg exited with code ${result.exit_code}`,
476
+ };
477
+ }
478
+ //# sourceMappingURL=video_recorder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video_recorder.js","sourceRoot":"","sources":["../../src/runners/video_recorder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Cross-platform window ID lookup.
3
+ * macOS: CGWindowListCopyWindowInfo via Swift
4
+ * Linux: xdotool search
5
+ * Windows: not needed (uses process handle)
6
+ */
7
+ export declare function findWindowId(appName: string): Promise<string | null>;
8
+ /**
9
+ * Bring an app to the front, un-minimizing if needed.
10
+ * Returns the name/title of the previously frontmost app for later restoration.
11
+ */
12
+ export declare function bringAppToFront(appName: string): Promise<string>;
13
+ /**
14
+ * Get the window bounds (position + size) for cropping video capture.
15
+ * Returns { x, y, width, height } in screen points.
16
+ */
17
+ export declare function getWindowBounds(appName: string): Promise<{
18
+ x: number;
19
+ y: number;
20
+ width: number;
21
+ height: number;
22
+ } | null>;
23
+ /**
24
+ * Click at screen coordinates using CGEvent (macOS), user32.dll (Windows),
25
+ * or xdotool (Linux). These are low-level HID events that Flutter and all
26
+ * frameworks receive.
27
+ */
28
+ export declare function clickAtPosition(x: number, y: number): Promise<boolean>;
29
+ /**
30
+ * Send a keystroke using CGEvent (macOS), user32.dll keybd_event (Windows),
31
+ * or xdotool (Linux).
32
+ *
33
+ * keyCode values are platform-specific:
34
+ * - macOS: CGKeyCode (e.g., 36=Return, 53=Escape, 48=Tab)
35
+ * - Windows: Virtual Key code (e.g., 0x0D=Enter, 0x1B=Escape, 0x09=Tab)
36
+ * - Linux: X11 keysym name as string via keyName param, or keyCode ignored
37
+ */
38
+ export declare function sendKeystroke(keyCode: number, keyName?: string): Promise<boolean>;
39
+ export declare function adbTap(x: number, y: number): Promise<boolean>;
40
+ export declare function adbType(text: string): Promise<boolean>;
41
+ export declare function adbKey(keycode: string): Promise<boolean>;
42
+ export declare function adbSwipe(x1: number, y1: number, x2: number, y2: number, durationMs?: number): Promise<boolean>;
43
+ export declare function simctlLaunch(bundleId: string): Promise<boolean>;
44
+ export declare function simctlTerminate(bundleId: string): Promise<boolean>;
45
+ export type TargetType = "desktop" | "android_emulator" | "ios_simulator" | "browser";
46
+ /**
47
+ * Check if a required external tool is installed.
48
+ * Returns null if available, or a user-facing error message with install instructions.
49
+ */
50
+ export declare function checkDependency(tool: string, action: string): Promise<string | null>;
51
+ /**
52
+ * Restore the previously frontmost app/window after capture is complete.
53
+ */
54
+ export declare function restorePreviousApp(previousApp: string): Promise<void>;
55
+ //# sourceMappingURL=window_manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"window_manager.d.ts","sourceRoot":"","sources":["../../src/runners/window_manager.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAK1E;AAwCD;;;GAGG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKtE;AA+ED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAM9H;AA2FD;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA+C5E;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA6CvF;AAID,wBAAsB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGnE;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAI5D;AAED,wBAAsB,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAG9D;AAED,wBAAsB,QAAQ,CAC5B,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,GAAE,MAAY,GACvE,OAAO,CAAC,OAAO,CAAC,CAQlB;AAID,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGrE;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGxE;AAID,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,kBAAkB,GAAG,eAAe,GAAG,SAAS,CAAC;AAoCtF;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAc1F;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA+B3E"}