ucu-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,18 @@
1
+ import type { Platform, ScreenRegion, ScreenSize, CursorPosition, WindowInfo, WindowState, OcrResult, FindElementOptions, FindElementResult } from "./base.js";
2
+ export declare class WindowsPlatform implements Platform {
3
+ screenshot(_display?: number, _region?: ScreenRegion): Promise<Buffer>;
4
+ getScreenSize(_display?: number): ScreenSize;
5
+ listWindows(_includeMinimized?: boolean): Promise<WindowInfo[]>;
6
+ getWindowState(_windowId?: string, _depth?: number, _includeBounds?: boolean): Promise<WindowState>;
7
+ click(_x: number, _y: number, _button?: "left" | "right" | "middle", _doubleClick?: boolean): Promise<void>;
8
+ move(_x: number, _y: number): Promise<void>;
9
+ drag(_startX: number, _startY: number, _endX: number, _endY: number, _button?: "left" | "right" | "middle", _duration?: number): Promise<void>;
10
+ scroll(_x: number, _y: number, _deltaX: number, _deltaY: number): Promise<void>;
11
+ getCursorPosition(): CursorPosition;
12
+ type(_text: string, _delay?: number): Promise<void>;
13
+ key(_keys: string[]): Promise<void>;
14
+ ocr(_display?: number, _region?: ScreenRegion): Promise<OcrResult>;
15
+ findElement(_options: FindElementOptions): Promise<FindElementResult[]>;
16
+ clickElement(_elementId: string, _app?: string): Promise<void>;
17
+ typeInElement(_elementId: string, _text: string, _app?: string, _clearFirst?: boolean): Promise<void>;
18
+ }
@@ -0,0 +1,48 @@
1
+ export class WindowsPlatform {
2
+ async screenshot(_display, _region) {
3
+ throw new Error("Not implemented: Windows screenshot");
4
+ }
5
+ getScreenSize(_display) {
6
+ throw new Error("Not implemented: Windows getScreenSize");
7
+ }
8
+ async listWindows(_includeMinimized) {
9
+ throw new Error("Not implemented: Windows listWindows");
10
+ }
11
+ async getWindowState(_windowId, _depth, _includeBounds) {
12
+ // TODO: Implement using UI Automation API
13
+ throw new Error("Not implemented: Windows getWindowState");
14
+ }
15
+ async click(_x, _y, _button, _doubleClick) {
16
+ throw new Error("Not implemented: Windows click");
17
+ }
18
+ async move(_x, _y) {
19
+ throw new Error("Not implemented: Windows move");
20
+ }
21
+ async drag(_startX, _startY, _endX, _endY, _button, _duration) {
22
+ throw new Error("Not implemented: Windows drag");
23
+ }
24
+ async scroll(_x, _y, _deltaX, _deltaY) {
25
+ throw new Error("Not implemented: Windows scroll");
26
+ }
27
+ getCursorPosition() {
28
+ throw new Error("Not implemented: Windows getCursorPosition");
29
+ }
30
+ async type(_text, _delay) {
31
+ throw new Error("Not implemented: Windows type");
32
+ }
33
+ async key(_keys) {
34
+ throw new Error("Not implemented: Windows key");
35
+ }
36
+ async ocr(_display, _region) {
37
+ throw new Error("Not implemented: Windows OCR");
38
+ }
39
+ async findElement(_options) {
40
+ throw new Error("Not implemented: Windows findElement");
41
+ }
42
+ async clickElement(_elementId, _app) {
43
+ throw new Error("Not implemented: Windows clickElement");
44
+ }
45
+ async typeInElement(_elementId, _text, _app, _clearFirst) {
46
+ throw new Error("Not implemented: Windows typeInElement");
47
+ }
48
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * SafetyGuard - Action safety checker for UCU automation.
3
+ *
4
+ * Evaluates proposed actions against a set of configurable rules:
5
+ * - key-blocklist: blocks dangerous keyboard shortcuts
6
+ * - window-skip: skips sensitive windows (banking, password managers)
7
+ * - rate-limit: throttles action frequency
8
+ */
9
+ export interface SafetyCheckResult {
10
+ allowed: boolean;
11
+ reason?: string;
12
+ }
13
+ export interface SafetyGuardConfig {
14
+ /** Extra shortcut patterns to block (in addition to built-ins). */
15
+ blockedKeys?: string[];
16
+ /** Extra window title patterns to skip (in addition to built-ins). */
17
+ skippedWindows?: string[];
18
+ /** Extra URL patterns to block (in addition to built-ins). */
19
+ blockedUrls?: string[];
20
+ /** Disable text injection scanning for controlled test harnesses. */
21
+ allowUnsafeText?: boolean;
22
+ /** Minimum milliseconds between consecutive actions (default 100). */
23
+ rateLimitMs?: number;
24
+ }
25
+ export declare class SafetyGuard {
26
+ private readonly blockedKeys;
27
+ private readonly skippedWindows;
28
+ private readonly blockedUrls;
29
+ private readonly allowUnsafeText;
30
+ private readonly rateLimitMs;
31
+ private lastActionTime;
32
+ private lastUserActivityTime;
33
+ private userActivityPauseMs;
34
+ constructor(config?: SafetyGuardConfig);
35
+ /**
36
+ * Evaluate whether the proposed action should be allowed.
37
+ *
38
+ * @param action The action type (e.g. "key", "click", "type", "screenshot").
39
+ * @param params Arbitrary action parameters; expected keys depend on action.
40
+ * - "key": { keys: string[] }
41
+ * - any action: { windowTitle?: string }
42
+ */
43
+ checkAction(action: string, params?: Record<string, unknown>): SafetyCheckResult;
44
+ /** Record that the user performed an activity (mouse/keyboard). */
45
+ recordUserActivity(): void;
46
+ /** Set the pause duration after user activity (default 2000ms). */
47
+ setUserActivityPauseMs(ms: number): void;
48
+ /** Check if user activity pause is still active. */
49
+ isUserActivityPauseActive(): boolean;
50
+ }
@@ -0,0 +1,220 @@
1
+ /**
2
+ * SafetyGuard - Action safety checker for UCU automation.
3
+ *
4
+ * Evaluates proposed actions against a set of configurable rules:
5
+ * - key-blocklist: blocks dangerous keyboard shortcuts
6
+ * - window-skip: skips sensitive windows (banking, password managers)
7
+ * - rate-limit: throttles action frequency
8
+ */
9
+ // ---------------------------------------------------------------------------
10
+ // Built-in blocked shortcuts
11
+ // ---------------------------------------------------------------------------
12
+ const DEFAULT_BLOCKED_KEYS = [
13
+ // macOS – app-level
14
+ "cmd+q",
15
+ "cmd+w",
16
+ "cmd+l", // lock screen
17
+ // macOS – system-level
18
+ "cmd+option+esc", // Force-quit dialog
19
+ "cmd+ctrl+power", // force restart
20
+ "cmd+option+power", // sleep
21
+ // Windows / Linux
22
+ "alt+f4",
23
+ "alt+f2", // Linux run dialog
24
+ "ctrl+alt+del",
25
+ "ctrl+alt+backspace", // Linux kill X
26
+ "ctrl+alt+t", // Linux terminal
27
+ ];
28
+ // ---------------------------------------------------------------------------
29
+ // Built-in sensitive window patterns (case-insensitive substring match)
30
+ // ---------------------------------------------------------------------------
31
+ const DEFAULT_SKIPPED_WINDOWS = [
32
+ "1password",
33
+ "bitwarden",
34
+ "lastpass",
35
+ "keepass",
36
+ "dashlane",
37
+ "keychain access",
38
+ "钥匙串访问",
39
+ "bank",
40
+ "银行",
41
+ "paypal",
42
+ "stripe",
43
+ "robinhood",
44
+ "coinbase",
45
+ ];
46
+ const DEFAULT_BLOCKED_URL_PATTERNS = [
47
+ "1password.com",
48
+ "bitwarden.com",
49
+ "lastpass.com",
50
+ "dashlane.com",
51
+ "keepersecurity.com",
52
+ "icloud.com/keychain",
53
+ "paypal.com",
54
+ "stripe.com",
55
+ "bank",
56
+ "bankofamerica.com",
57
+ "chase.com",
58
+ "wellsfargo.com",
59
+ "capitalone.com",
60
+ "americanexpress.com",
61
+ "coinbase.com",
62
+ "robinhood.com",
63
+ "binance.com",
64
+ "kraken.com",
65
+ ];
66
+ const DEFAULT_TEXT_INJECTION_PATTERNS = [
67
+ { pattern: /\$\s*\(/, reason: "shell command substitution" },
68
+ { pattern: /`[^`]+`/, reason: "shell backtick substitution" },
69
+ { pattern: /&&|\|\|/, reason: "shell command chaining" },
70
+ { pattern: /\|\s*(sh|bash|zsh|python|ruby|perl|node)\b/i, reason: "piping into an interpreter" },
71
+ { pattern: /\b(sudo\s+rm|rm\s+-rf|mkfs|diskutil\s+erase|dd\s+if=|chmod\s+-R\s+777)\b/i, reason: "dangerous shell command" },
72
+ { pattern: /\b(ObjC\.import|Application\s*\(|do\s+shell\s+script)\b/, reason: "AppleScript/JXA injection primitive" },
73
+ ];
74
+ // ---------------------------------------------------------------------------
75
+ // Helpers
76
+ // ---------------------------------------------------------------------------
77
+ /** Normalize a shortcut string to lowercase, trimmed, sorted modifiers. */
78
+ function normalizeShortcut(raw) {
79
+ return raw
80
+ .toLowerCase()
81
+ .split("+")
82
+ .map((s) => s.trim())
83
+ .sort()
84
+ .join("+");
85
+ }
86
+ // ---------------------------------------------------------------------------
87
+ // SafetyGuard
88
+ // ---------------------------------------------------------------------------
89
+ export class SafetyGuard {
90
+ blockedKeys;
91
+ skippedWindows;
92
+ blockedUrls;
93
+ allowUnsafeText;
94
+ rateLimitMs;
95
+ lastActionTime = 0;
96
+ lastUserActivityTime = 0;
97
+ userActivityPauseMs = 2000;
98
+ constructor(config) {
99
+ const extra = (config?.blockedKeys ?? []).map(normalizeShortcut);
100
+ this.blockedKeys = new Set([
101
+ ...DEFAULT_BLOCKED_KEYS.map(normalizeShortcut),
102
+ ...extra,
103
+ ]);
104
+ this.skippedWindows = [
105
+ ...DEFAULT_SKIPPED_WINDOWS,
106
+ ...(config?.skippedWindows ?? []),
107
+ ].map((p) => p.toLowerCase());
108
+ this.blockedUrls = [
109
+ ...DEFAULT_BLOCKED_URL_PATTERNS,
110
+ ...(config?.blockedUrls ?? []),
111
+ ].map((p) => p.toLowerCase());
112
+ this.allowUnsafeText = config?.allowUnsafeText ?? false;
113
+ this.rateLimitMs = config?.rateLimitMs ?? 100;
114
+ }
115
+ // -----------------------------------------------------------------------
116
+ // Public API
117
+ // -----------------------------------------------------------------------
118
+ /**
119
+ * Evaluate whether the proposed action should be allowed.
120
+ *
121
+ * @param action The action type (e.g. "key", "click", "type", "screenshot").
122
+ * @param params Arbitrary action parameters; expected keys depend on action.
123
+ * - "key": { keys: string[] }
124
+ * - any action: { windowTitle?: string }
125
+ */
126
+ checkAction(action, params = {}) {
127
+ // 1. Key blocklist -------------------------------------------------------
128
+ if (action === "key" || action === "press_key") {
129
+ const keys = params.keys;
130
+ if (keys && keys.length > 0) {
131
+ const normalized = normalizeShortcut(keys.join("+"));
132
+ if (this.blockedKeys.has(normalized)) {
133
+ return {
134
+ allowed: false,
135
+ reason: `Blocked shortcut: ${keys.join("+")}`,
136
+ };
137
+ }
138
+ }
139
+ }
140
+ // 2. Window skip ----------------------------------------------------------
141
+ const windowTitle = typeof params.windowTitle === "string" ? params.windowTitle : undefined;
142
+ if (windowTitle) {
143
+ const lower = windowTitle.toLowerCase();
144
+ for (const pattern of this.skippedWindows) {
145
+ if (lower.includes(pattern)) {
146
+ return {
147
+ allowed: false,
148
+ reason: `Skipped sensitive window: "${windowTitle}"`,
149
+ };
150
+ }
151
+ }
152
+ }
153
+ // 3. URL blocklist --------------------------------------------------------
154
+ const url = typeof params.url === "string" ? params.url : undefined;
155
+ if (url) {
156
+ const lower = url.toLowerCase();
157
+ for (const pattern of this.blockedUrls) {
158
+ if (lower.includes(pattern)) {
159
+ return {
160
+ allowed: false,
161
+ reason: `Blocked sensitive URL: ${url}`,
162
+ };
163
+ }
164
+ }
165
+ }
166
+ // 4. Text injection scan --------------------------------------------------
167
+ if (!this.allowUnsafeText && (action === "type" || action === "type_text" || action === "type_in_element" || action === "set_value")) {
168
+ const text = typeof params.text === "string"
169
+ ? params.text
170
+ : typeof params.value === "string"
171
+ ? params.value
172
+ : undefined;
173
+ if (text) {
174
+ for (const { pattern, reason } of DEFAULT_TEXT_INJECTION_PATTERNS) {
175
+ if (pattern.test(text)) {
176
+ return {
177
+ allowed: false,
178
+ reason: `Blocked suspicious typed text (${reason})`,
179
+ };
180
+ }
181
+ }
182
+ }
183
+ }
184
+ // 5. Rate limit -----------------------------------------------------------
185
+ const now = Date.now();
186
+ const elapsed = now - this.lastActionTime;
187
+ if (elapsed < this.rateLimitMs) {
188
+ return {
189
+ allowed: false,
190
+ reason: `Rate-limited: ${elapsed}ms since last action (min ${this.rateLimitMs}ms)`,
191
+ };
192
+ }
193
+ this.lastActionTime = now;
194
+ // 6. User activity pause --------------------------------------------------
195
+ if (this.isUserActivityPauseActive()) {
196
+ return {
197
+ allowed: false,
198
+ reason: `User activity detected — pausing automation for ${this.userActivityPauseMs}ms`,
199
+ };
200
+ }
201
+ return { allowed: true };
202
+ }
203
+ // -----------------------------------------------------------------------
204
+ // User Activity Monitoring
205
+ // -----------------------------------------------------------------------
206
+ /** Record that the user performed an activity (mouse/keyboard). */
207
+ recordUserActivity() {
208
+ this.lastUserActivityTime = Date.now();
209
+ }
210
+ /** Set the pause duration after user activity (default 2000ms). */
211
+ setUserActivityPauseMs(ms) {
212
+ this.userActivityPauseMs = ms;
213
+ }
214
+ /** Check if user activity pause is still active. */
215
+ isUserActivityPauseActive() {
216
+ if (this.userActivityPauseMs <= 0)
217
+ return false;
218
+ return Date.now() - this.lastUserActivityTime < this.userActivityPauseMs;
219
+ }
220
+ }
@@ -0,0 +1,17 @@
1
+ export type PermissionType = "accessibility" | "screenRecording";
2
+ export interface PermissionCheckResult {
3
+ granted: boolean;
4
+ missing: PermissionType[];
5
+ }
6
+ export interface PermissionDetail {
7
+ type: PermissionType;
8
+ granted: boolean;
9
+ instructions: string;
10
+ }
11
+ export declare function checkPermissions(): Promise<PermissionCheckResult>;
12
+ export declare function checkPermission(type: "accessibility" | "screenRecording"): Promise<{
13
+ granted: boolean;
14
+ message?: string;
15
+ }>;
16
+ export declare function getPermissionInstructions(type: PermissionType): string;
17
+ export declare function runPermissionDoctor(): Promise<PermissionDetail[]>;
@@ -0,0 +1,184 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ const execFileAsync = promisify(execFile);
4
+ /**
5
+ * Get the name of the terminal app that the user needs to authorize.
6
+ */
7
+ function getTerminalAppName() {
8
+ // Walk up the process tree to find the terminal emulator
9
+ const ppid = process.ppid;
10
+ // Common terminal app names
11
+ const env = process.env.TERM_PROGRAM || "";
12
+ const nameMap = {
13
+ "Apple_Terminal": "Terminal.app",
14
+ "iTerm.app": "iTerm.app",
15
+ "vscode": "Visual Studio Code",
16
+ "alacritty": "Alacritty",
17
+ "kitty": "kitty",
18
+ "wezterm": "WezTerm",
19
+ "ghostty": "Ghostty",
20
+ "warp": "Warp",
21
+ "hyper": "Hyper",
22
+ };
23
+ return nameMap[env] || env || "your terminal app";
24
+ }
25
+ /**
26
+ * Open the macOS System Settings page for a permission.
27
+ */
28
+ async function openPermissionSettings(type) {
29
+ const url = type === "accessibility"
30
+ ? "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"
31
+ : "x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture";
32
+ try {
33
+ await execFileAsync("/usr/bin/open", [url], { timeout: 3000 });
34
+ }
35
+ catch {
36
+ // Non-critical — best effort
37
+ }
38
+ }
39
+ /**
40
+ * Request accessibility permission by triggering the macOS system dialog.
41
+ * Uses AXIsProcessTrustedWithOptions with kAXTrustedCheckOptionPrompt=true
42
+ * which shows the system authorization prompt.
43
+ */
44
+ async function requestAccessibilityWithPrompt() {
45
+ try {
46
+ const script = `
47
+ ObjC.import('CoreServices');
48
+ var opts = $.NSDictionary.dictionaryWithObjectForObject(
49
+ $(true), $("kAXTrustedCheckOptionPrompt")
50
+ );
51
+ $.AXIsProcessTrustedWithOptions(opts);
52
+ `;
53
+ const { stdout } = await execFileAsync("/usr/bin/osascript", [
54
+ "-l", "JavaScript", "-e", script,
55
+ ], { timeout: 10000 });
56
+ return stdout.trim() === "true";
57
+ }
58
+ catch {
59
+ return false;
60
+ }
61
+ }
62
+ /**
63
+ * Check accessibility by trying to use System Events via osascript.
64
+ * macOS grants the PARENT process the TCC entry — we check via
65
+ * a simple AXAPI call that returns the current process's status.
66
+ *
67
+ * NOTE: When running via `node`, the TCC entry is for "Terminal.app"
68
+ * (or whichever terminal hosts node). The osascript subprocess
69
+ * inherits the parent's TCC for accessibility because it runs
70
+ * under the same application context via the shell.
71
+ */
72
+ async function checkAccessibility() {
73
+ if (process.platform !== "darwin")
74
+ return true;
75
+ try {
76
+ const script = `
77
+ tell application "System Events"
78
+ return (count of processes) as text
79
+ end tell
80
+ `;
81
+ const { stdout } = await execFileAsync("/usr/bin/osascript", ["-e", script], {
82
+ timeout: 5000,
83
+ });
84
+ const count = parseInt(stdout.trim(), 10);
85
+ return !isNaN(count) && count > 0;
86
+ }
87
+ catch {
88
+ return false;
89
+ }
90
+ }
91
+ /**
92
+ * Check screen recording by attempting a minimal screenshot.
93
+ * screencapture respects TCC — it fails with a specific error
94
+ * if the calling process doesn't have Screen Recording permission.
95
+ */
96
+ async function checkScreenRecording() {
97
+ if (process.platform !== "darwin")
98
+ return true;
99
+ try {
100
+ await execFileAsync("/usr/sbin/screencapture", [
101
+ "-x", "-R", "0,0,1,1", "/dev/null",
102
+ ], { timeout: 5000 });
103
+ return true;
104
+ }
105
+ catch (e) {
106
+ const msg = (e.stderr || e.message || "").toLowerCase();
107
+ // screencapture returns error when no permission
108
+ if (msg.includes("not authorized") || msg.includes("denied") || msg.includes("permission")) {
109
+ return false;
110
+ }
111
+ // Other errors (file system) — permission is likely granted
112
+ return true;
113
+ }
114
+ }
115
+ export async function checkPermissions() {
116
+ if (process.platform !== "darwin") {
117
+ return { granted: true, missing: [] };
118
+ }
119
+ const [hasAccessibility, hasScreenRecording] = await Promise.all([
120
+ checkAccessibility(),
121
+ checkScreenRecording(),
122
+ ]);
123
+ const missing = [];
124
+ if (!hasAccessibility)
125
+ missing.push("accessibility");
126
+ if (!hasScreenRecording)
127
+ missing.push("screenRecording");
128
+ return { granted: missing.length === 0, missing };
129
+ }
130
+ export async function checkPermission(type) {
131
+ if (process.platform !== "darwin") {
132
+ return { granted: true };
133
+ }
134
+ const appName = getTerminalAppName();
135
+ if (type === "accessibility") {
136
+ const granted = await checkAccessibility();
137
+ if (!granted) {
138
+ // Trigger the macOS system prompt for Accessibility
139
+ await requestAccessibilityWithPrompt();
140
+ // Also open System Settings as a fallback
141
+ await openPermissionSettings("accessibility");
142
+ return {
143
+ granted: false,
144
+ message: `macOS Accessibility permission required for ${appName}. A system dialog should have appeared requesting authorization — please approve it. If no dialog appeared, open System Settings > Privacy & Security > Accessibility and manually enable ${appName}. Then restart ucu-mcp.`,
145
+ };
146
+ }
147
+ return { granted: true };
148
+ }
149
+ const granted = await checkScreenRecording();
150
+ if (!granted) {
151
+ // Open System Settings for Screen Recording
152
+ await openPermissionSettings("screenRecording");
153
+ return {
154
+ granted: false,
155
+ message: `macOS Screen Recording permission required for ${appName}. Opening System Settings now — please navigate to Privacy & Security > Screen Recording and enable ${appName}. Then restart ucu-mcp.`,
156
+ };
157
+ }
158
+ return { granted: true };
159
+ }
160
+ export function getPermissionInstructions(type) {
161
+ const instructions = {
162
+ accessibility: "Open System Settings > Privacy & Security > Accessibility. Add and enable your terminal application (e.g. Terminal.app, iTerm2, Alacritty). Restart ucu-mcp after granting.",
163
+ screenRecording: "Open System Settings > Privacy & Security > Screen Recording. Add and enable your terminal application. Restart ucu-mcp after granting.",
164
+ };
165
+ return instructions[type];
166
+ }
167
+ export async function runPermissionDoctor() {
168
+ const details = [];
169
+ const [accessibility, screenRecording] = await Promise.all([
170
+ checkAccessibility(),
171
+ checkScreenRecording(),
172
+ ]);
173
+ details.push({
174
+ type: "accessibility",
175
+ granted: accessibility,
176
+ instructions: getPermissionInstructions("accessibility"),
177
+ });
178
+ details.push({
179
+ type: "screenRecording",
180
+ granted: screenRecording,
181
+ instructions: getPermissionInstructions("screenRecording"),
182
+ });
183
+ return details;
184
+ }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Error taxonomy for UCU-MCP.
3
+ *
4
+ * All errors inherit from UcuError and are categorized by:
5
+ * - code: machine-readable error code
6
+ * - retryable: whether the operation can be retried
7
+ */
8
+ export declare class UcuError extends Error {
9
+ readonly code: string;
10
+ readonly retryable: boolean;
11
+ constructor(message: string, code?: string, retryable?: boolean);
12
+ }
13
+ /**
14
+ * Native API call failed (permissions, OS error, timeout).
15
+ */
16
+ export declare class PlatformError extends UcuError {
17
+ constructor(message: string, retryable?: boolean);
18
+ }
19
+ /**
20
+ * Action blocked by safety guard.
21
+ */
22
+ export declare class SafetyError extends UcuError {
23
+ constructor(message: string);
24
+ }
25
+ /**
26
+ * Missing OS accessibility/screen-recording permissions.
27
+ */
28
+ export declare class PermissionError extends UcuError {
29
+ constructor(permission: string, platform: string);
30
+ }
31
+ /**
32
+ * Requested window ID no longer exists.
33
+ */
34
+ export declare class WindowNotFoundError extends UcuError {
35
+ constructor(windowId: string);
36
+ }
37
+ /**
38
+ * Click/scroll target is outside screen bounds.
39
+ */
40
+ export declare class CoordinateError extends UcuError {
41
+ constructor(x: number, y: number, bounds: {
42
+ width: number;
43
+ height: number;
44
+ });
45
+ }
46
+ /**
47
+ * Keystroke or mouse event injection failed.
48
+ */
49
+ export declare class InputSynthesisError extends UcuError {
50
+ constructor(message: string);
51
+ }
52
+ /**
53
+ * The request is well-formed JSON, but asks for a parameter combination this
54
+ * implementation does not support.
55
+ */
56
+ export declare class UnsupportedParameterError extends UcuError {
57
+ constructor(message: string);
58
+ }
59
+ /**
60
+ * Screenshot or window-state capture failed.
61
+ */
62
+ export declare class CaptureError extends UcuError {
63
+ constructor(message: string);
64
+ }