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,14 @@
1
+ import type { TargetType } from "./window_manager.js";
2
+ /**
3
+ * Auto-detect the target type for video recording and interaction based on
4
+ * the project structure and host OS.
5
+ *
6
+ * Detection priority:
7
+ * 1. Flutter project (pubspec.yaml) → check which platform is targeted
8
+ * 2. Xcode project (.xcodeproj) → ios_simulator (macOS only)
9
+ * 3. Android project (build.gradle) → android_emulator
10
+ * 4. Web project (package.json with web framework) → browser
11
+ * 5. Default → desktop
12
+ */
13
+ export declare function detectTargetType(cwd: string): Promise<TargetType>;
14
+ //# sourceMappingURL=platform_detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform_detect.d.ts","sourceRoot":"","sources":["../../src/runners/platform_detect.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAyCvE"}
@@ -0,0 +1,102 @@
1
+ import { existsSync, readFileSync, readdirSync } from "fs";
2
+ import { join } from "path";
3
+ import { platform } from "os";
4
+ /**
5
+ * Auto-detect the target type for video recording and interaction based on
6
+ * the project structure and host OS.
7
+ *
8
+ * Detection priority:
9
+ * 1. Flutter project (pubspec.yaml) → check which platform is targeted
10
+ * 2. Xcode project (.xcodeproj) → ios_simulator (macOS only)
11
+ * 3. Android project (build.gradle) → android_emulator
12
+ * 4. Web project (package.json with web framework) → browser
13
+ * 5. Default → desktop
14
+ */
15
+ export async function detectTargetType(cwd) {
16
+ // Flutter project detection
17
+ const pubspecPath = join(cwd, "pubspec.yaml");
18
+ if (existsSync(pubspecPath)) {
19
+ return detectFlutterTargetType(cwd, pubspecPath);
20
+ }
21
+ // Xcode project (native iOS/macOS)
22
+ if (hasFileWithExtension(cwd, ".xcodeproj") || hasFileWithExtension(cwd, ".xcworkspace")) {
23
+ const os = platform();
24
+ if (os === "darwin") {
25
+ // Check if it's a macOS app (look for macOS target) or iOS app
26
+ if (existsSync(join(cwd, "macos")))
27
+ return "desktop";
28
+ return "ios_simulator";
29
+ }
30
+ return "desktop";
31
+ }
32
+ // Android project (native)
33
+ if (existsSync(join(cwd, "build.gradle")) || existsSync(join(cwd, "build.gradle.kts")) ||
34
+ existsSync(join(cwd, "app", "build.gradle")) || existsSync(join(cwd, "app", "build.gradle.kts"))) {
35
+ return "android_emulator";
36
+ }
37
+ // Web project
38
+ const packageJsonPath = join(cwd, "package.json");
39
+ if (existsSync(packageJsonPath)) {
40
+ try {
41
+ const pkg = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
42
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
43
+ const webFrameworks = [
44
+ "react", "next", "vue", "nuxt", "svelte", "@sveltejs/kit",
45
+ "angular", "@angular/core", "gatsby", "remix", "astro", "vite",
46
+ ];
47
+ if (webFrameworks.some(fw => fw in deps)) {
48
+ return "browser";
49
+ }
50
+ }
51
+ catch { /* ignore parse errors */ }
52
+ }
53
+ return "desktop";
54
+ }
55
+ function detectFlutterTargetType(cwd, _pubspecPath) {
56
+ const os = platform();
57
+ // Check which platform directories exist in the Flutter project
58
+ const hasAndroid = existsSync(join(cwd, "android"));
59
+ const hasIos = existsSync(join(cwd, "ios"));
60
+ const hasMacos = existsSync(join(cwd, "macos"));
61
+ const hasWindows = existsSync(join(cwd, "windows"));
62
+ const hasLinux = existsSync(join(cwd, "linux"));
63
+ const hasWeb = existsSync(join(cwd, "web"));
64
+ // Prefer the platform that matches the host OS
65
+ if (os === "darwin") {
66
+ if (hasMacos)
67
+ return "desktop";
68
+ if (hasIos)
69
+ return "ios_simulator";
70
+ if (hasWeb)
71
+ return "browser";
72
+ if (hasAndroid)
73
+ return "android_emulator";
74
+ }
75
+ else if (os === "win32") {
76
+ if (hasWindows)
77
+ return "desktop";
78
+ if (hasAndroid)
79
+ return "android_emulator";
80
+ if (hasWeb)
81
+ return "browser";
82
+ }
83
+ else {
84
+ if (hasLinux)
85
+ return "desktop";
86
+ if (hasAndroid)
87
+ return "android_emulator";
88
+ if (hasWeb)
89
+ return "browser";
90
+ }
91
+ return "desktop";
92
+ }
93
+ function hasFileWithExtension(dir, ext) {
94
+ try {
95
+ const entries = readdirSync(dir);
96
+ return entries.some(e => e.endsWith(ext));
97
+ }
98
+ catch {
99
+ return false;
100
+ }
101
+ }
102
+ //# sourceMappingURL=platform_detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform_detect.js","sourceRoot":"","sources":["../../src/runners/platform_detect.ts"],"names":[],"mappings":"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"}
@@ -5,13 +5,9 @@ export interface ScreenshotResult {
5
5
  error?: string;
6
6
  }
7
7
  /**
8
- * Capture a screenshot of the current screen/display.
9
- * Cross-platform: macOS (screencapture), Windows (PowerShell), Linux (import/gnome-screenshot).
10
- * Falls back gracefully if no capture tool is available.
11
- */
12
- export declare function captureScreenshot(outputDir: string, label?: string): Promise<ScreenshotResult>;
13
- /**
14
- * List all PNG screenshots already present in a directory.
8
+ * Capture a screenshot. If appName is provided, brings the app to front,
9
+ * captures only that app's window, then restores the previous frontmost app.
15
10
  */
11
+ export declare function captureScreenshot(outputDir: string, label?: string, appName?: string): Promise<ScreenshotResult>;
16
12
  export declare function listScreenshots(dir: string): string[];
17
13
  //# sourceMappingURL=screenshot.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/runners/screenshot.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,MAAiB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAW3B;AAsFD;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAMrD"}
1
+ {"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/runners/screenshot.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,MAAiB,EACxB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,CAAC,CAY3B;AAuLD,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAMrD"}
@@ -1,32 +1,58 @@
1
- import { existsSync, readdirSync } from "fs";
1
+ import { existsSync, readdirSync, mkdirSync } from "fs";
2
2
  import { join } from "path";
3
3
  import { platform } from "os";
4
4
  import { runCommand, checkToolAvailable } from "./base.js";
5
+ import { findWindowId, bringAppToFront, restorePreviousApp } from "./window_manager.js";
5
6
  /**
6
- * Capture a screenshot of the current screen/display.
7
- * Cross-platform: macOS (screencapture), Windows (PowerShell), Linux (import/gnome-screenshot).
8
- * Falls back gracefully if no capture tool is available.
7
+ * Capture a screenshot. If appName is provided, brings the app to front,
8
+ * captures only that app's window, then restores the previous frontmost app.
9
9
  */
10
- export async function captureScreenshot(outputDir, label = "screen") {
10
+ export async function captureScreenshot(outputDir, label = "screen", appName) {
11
+ mkdirSync(outputDir, { recursive: true });
11
12
  const outputPath = join(outputDir, `${label}_${Date.now()}.png`);
12
13
  const os = platform();
13
14
  if (os === "darwin") {
14
- return captureMacOS(outputPath);
15
+ return captureMacOS(outputPath, appName);
15
16
  }
16
17
  else if (os === "win32") {
17
- return captureWindows(outputPath);
18
+ return captureWindows(outputPath, appName);
18
19
  }
19
20
  else {
20
- return captureLinux(outputPath);
21
+ return captureLinux(outputPath, appName);
21
22
  }
22
23
  }
23
- async function captureMacOS(outputPath) {
24
+ async function captureMacOS(outputPath, appName) {
24
25
  if (!(await checkToolAvailable("screencapture"))) {
25
26
  return { captured: false, paths: [], method: "screencapture", error: "screencapture not found" };
26
27
  }
28
+ if (appName) {
29
+ const windowId = await findWindowId(appName);
30
+ if (windowId) {
31
+ const wResult = await runCommand("screencapture", ["-l", windowId, "-x", "-o", outputPath], process.cwd());
32
+ if (wResult.exit_code === 0 && existsSync(outputPath)) {
33
+ return { captured: true, paths: [outputPath], method: `screencapture -l ${windowId} (window: ${appName})` };
34
+ }
35
+ }
36
+ const previousApp = await bringAppToFront(appName);
37
+ const fResult = await runCommand("screencapture", ["-x", "-o", outputPath], process.cwd());
38
+ const captured = fResult.exit_code === 0 && existsSync(outputPath);
39
+ if (previousApp && previousApp !== appName) {
40
+ await restorePreviousApp(previousApp);
41
+ }
42
+ if (captured) {
43
+ const hint = windowId
44
+ ? ". Tip: Grant Screen Recording permission (System Settings > Privacy & Security > Screen Recording) for window-only capture"
45
+ : "";
46
+ return { captured: true, paths: [outputPath], method: `screencapture (app "${appName}" brought to front, then restored)${hint}` };
47
+ }
48
+ }
27
49
  const result = await runCommand("screencapture", ["-x", "-o", outputPath], process.cwd());
28
50
  if (result.exit_code === 0 && existsSync(outputPath)) {
29
- return { captured: true, paths: [outputPath], method: "screencapture" };
51
+ return {
52
+ captured: true,
53
+ paths: [outputPath],
54
+ method: appName ? `screencapture (full screen — could not find window "${appName}")` : "screencapture (full screen)",
55
+ };
30
56
  }
31
57
  return {
32
58
  captured: false,
@@ -35,8 +61,53 @@ async function captureMacOS(outputPath) {
35
61
  error: result.stderr || `screencapture exited with code ${result.exit_code}`,
36
62
  };
37
63
  }
38
- async function captureWindows(outputPath) {
39
- const script = `
64
+ async function captureWindows(outputPath, appName) {
65
+ const hasPowershell = await checkToolAvailable("powershell");
66
+ if (!hasPowershell) {
67
+ return { captured: false, paths: [], method: "powershell", error: "powershell not found" };
68
+ }
69
+ let previousApp = "";
70
+ if (appName) {
71
+ previousApp = await bringAppToFront(appName);
72
+ }
73
+ let script;
74
+ if (appName) {
75
+ script = `
76
+ Add-Type -AssemblyName System.Windows.Forms
77
+ Add-Type -AssemblyName System.Drawing
78
+ Add-Type @"
79
+ using System;
80
+ using System.Runtime.InteropServices;
81
+ public class Win32 {
82
+ [DllImport("user32.dll")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
83
+ [DllImport("user32.dll")] public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
84
+ [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left, Top, Right, Bottom; }
85
+ }
86
+ "@
87
+ $procs = Get-Process | Where-Object { $_.MainWindowTitle -match '${appName}' -and $_.MainWindowHandle -ne 0 }
88
+ if ($procs.Count -gt 0) {
89
+ $hwnd = $procs[0].MainWindowHandle
90
+ $rect = New-Object Win32+RECT
91
+ [Win32]::GetWindowRect($hwnd, [ref]$rect)
92
+ $w = $rect.Right - $rect.Left
93
+ $h = $rect.Bottom - $rect.Top
94
+ $bitmap = New-Object System.Drawing.Bitmap($w, $h)
95
+ $graphics = [System.Drawing.Graphics]::FromImage($bitmap)
96
+ $graphics.CopyFromScreen($rect.Left, $rect.Top, 0, 0, (New-Object System.Drawing.Size($w, $h)))
97
+ $bitmap.Save('${outputPath.replace(/\\/g, "\\\\")}', [System.Drawing.Imaging.ImageFormat]::Png)
98
+ $graphics.Dispose(); $bitmap.Dispose()
99
+ } else {
100
+ $screen = [System.Windows.Forms.Screen]::PrimaryScreen
101
+ $bitmap = New-Object System.Drawing.Bitmap($screen.Bounds.Width, $screen.Bounds.Height)
102
+ $graphics = [System.Drawing.Graphics]::FromImage($bitmap)
103
+ $graphics.CopyFromScreen($screen.Bounds.Location, [System.Drawing.Point]::Empty, $screen.Bounds.Size)
104
+ $bitmap.Save('${outputPath.replace(/\\/g, "\\\\")}', [System.Drawing.Imaging.ImageFormat]::Png)
105
+ $graphics.Dispose(); $bitmap.Dispose()
106
+ }
107
+ `;
108
+ }
109
+ else {
110
+ script = `
40
111
  Add-Type -AssemblyName System.Windows.Forms
41
112
  Add-Type -AssemblyName System.Drawing
42
113
  $screen = [System.Windows.Forms.Screen]::PrimaryScreen
@@ -44,16 +115,15 @@ $bitmap = New-Object System.Drawing.Bitmap($screen.Bounds.Width, $screen.Bounds.
44
115
  $graphics = [System.Drawing.Graphics]::FromImage($bitmap)
45
116
  $graphics.CopyFromScreen($screen.Bounds.Location, [System.Drawing.Point]::Empty, $screen.Bounds.Size)
46
117
  $bitmap.Save('${outputPath.replace(/\\/g, "\\\\")}', [System.Drawing.Imaging.ImageFormat]::Png)
47
- $graphics.Dispose()
48
- $bitmap.Dispose()
118
+ $graphics.Dispose(); $bitmap.Dispose()
49
119
  `;
50
- const hasPowershell = await checkToolAvailable("powershell");
51
- if (!hasPowershell) {
52
- return { captured: false, paths: [], method: "powershell", error: "powershell not found" };
53
120
  }
54
121
  const result = await runCommand("powershell", ["-NoProfile", "-Command", script], process.cwd());
122
+ if (previousApp && previousApp !== appName) {
123
+ await restorePreviousApp(previousApp);
124
+ }
55
125
  if (result.exit_code === 0 && existsSync(outputPath)) {
56
- return { captured: true, paths: [outputPath], method: "powershell" };
126
+ return { captured: true, paths: [outputPath], method: appName ? `powershell (window: ${appName})` : "powershell (full screen)" };
57
127
  }
58
128
  return {
59
129
  captured: false,
@@ -62,25 +132,45 @@ $bitmap.Dispose()
62
132
  error: result.stderr || `powershell exited with code ${result.exit_code}`,
63
133
  };
64
134
  }
65
- async function captureLinux(outputPath) {
66
- if (await checkToolAvailable("import")) {
135
+ async function captureLinux(outputPath, appName) {
136
+ let previousApp = "";
137
+ if (appName) {
138
+ previousApp = await bringAppToFront(appName);
139
+ }
140
+ let captured = false;
141
+ if (appName && (await checkToolAvailable("xdotool")) && (await checkToolAvailable("import"))) {
142
+ const windowId = await findWindowId(appName);
143
+ if (windowId) {
144
+ const result = await runCommand("import", ["-window", windowId, outputPath], process.cwd());
145
+ if (result.exit_code === 0 && existsSync(outputPath)) {
146
+ captured = true;
147
+ }
148
+ }
149
+ }
150
+ if (!captured && (await checkToolAvailable("import"))) {
67
151
  const result = await runCommand("import", ["-window", "root", outputPath], process.cwd());
68
152
  if (result.exit_code === 0 && existsSync(outputPath)) {
69
- return { captured: true, paths: [outputPath], method: "import (ImageMagick)" };
153
+ captured = true;
70
154
  }
71
155
  }
72
- if (await checkToolAvailable("gnome-screenshot")) {
156
+ if (!captured && (await checkToolAvailable("gnome-screenshot"))) {
73
157
  const result = await runCommand("gnome-screenshot", ["-f", outputPath], process.cwd());
74
158
  if (result.exit_code === 0 && existsSync(outputPath)) {
75
- return { captured: true, paths: [outputPath], method: "gnome-screenshot" };
159
+ captured = true;
76
160
  }
77
161
  }
78
- if (await checkToolAvailable("scrot")) {
162
+ if (!captured && (await checkToolAvailable("scrot"))) {
79
163
  const result = await runCommand("scrot", [outputPath], process.cwd());
80
164
  if (result.exit_code === 0 && existsSync(outputPath)) {
81
- return { captured: true, paths: [outputPath], method: "scrot" };
165
+ captured = true;
82
166
  }
83
167
  }
168
+ if (previousApp && previousApp !== appName) {
169
+ await restorePreviousApp(previousApp);
170
+ }
171
+ if (captured) {
172
+ return { captured: true, paths: [outputPath], method: appName ? `screenshot (window: ${appName})` : "screenshot (full screen)" };
173
+ }
84
174
  return {
85
175
  captured: false,
86
176
  paths: [],
@@ -88,9 +178,6 @@ async function captureLinux(outputPath) {
88
178
  error: "No screenshot tool found (tried: import, gnome-screenshot, scrot)",
89
179
  };
90
180
  }
91
- /**
92
- * List all PNG screenshots already present in a directory.
93
- */
94
181
  export function listScreenshots(dir) {
95
182
  if (!existsSync(dir))
96
183
  return [];
@@ -1 +1 @@
1
- {"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../src/runners/screenshot.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../src/runners/screenshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import type { TargetType } from "./window_manager.js";
2
+ export interface VideoRecordResult {
3
+ recorded: boolean;
4
+ path: string;
5
+ duration_seconds: number;
6
+ method: string;
7
+ error?: string;
8
+ }
9
+ export interface BackgroundRecordingHandle {
10
+ recording_id: string;
11
+ output_path: string;
12
+ app_name: string;
13
+ previous_app: string;
14
+ started_at: number;
15
+ target_type: TargetType;
16
+ log_capture: boolean;
17
+ }
18
+ /**
19
+ * Blocking video recording. Brings app to front, records for a fixed
20
+ * duration, then restores the previous frontmost app.
21
+ */
22
+ export declare function recordVideo(outputDir: string, durationSeconds?: number, appName?: string): Promise<VideoRecordResult>;
23
+ /**
24
+ * Start recording in the background. Returns a handle immediately so the
25
+ * agent can interact with the app while recording is active.
26
+ * Call stopBackgroundRecording() when done.
27
+ *
28
+ * targetType selects the capture method:
29
+ * - "desktop": ffmpeg screen capture (macOS/Windows/Linux)
30
+ * - "android_emulator": adb shell screenrecord
31
+ * - "ios_simulator": xcrun simctl io booted recordVideo
32
+ * - "browser": ffmpeg or Playwright recordVideo
33
+ */
34
+ export declare function startBackgroundRecording(outputDir: string, appName: string, maxDurationSeconds?: number, targetType?: TargetType): Promise<BackgroundRecordingHandle | {
35
+ error: string;
36
+ }>;
37
+ /**
38
+ * Stop a background recording. Sends SIGINT to finalize the video file,
39
+ * then restores the previous frontmost app.
40
+ * For Android, pulls the recorded file from the device.
41
+ */
42
+ export declare function stopBackgroundRecording(recordingId: string): Promise<VideoRecordResult & {
43
+ log_path?: string;
44
+ }>;
45
+ /** List all active background recordings. */
46
+ export declare function listActiveRecordings(): string[];
47
+ //# sourceMappingURL=video_recorder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video_recorder.d.ts","sourceRoot":"","sources":["../../src/runners/video_recorder.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAgFtD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,yBAAyB;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,UAAU,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;CACtB;AAaD;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,SAAS,EAAE,MAAM,EACjB,eAAe,GAAE,MAAW,EAC5B,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,iBAAiB,CAAC,CAwB5B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,kBAAkB,GAAE,MAAY,EAChC,UAAU,GAAE,UAAsB,GACjC,OAAO,CAAC,yBAAyB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CA+LxD;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAqFpD;AAED,6CAA6C;AAC7C,wBAAgB,oBAAoB,IAAI,MAAM,EAAE,CAE/C"}