@intentic/desktop-automation 1.326.0 → 1.328.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -8
- package/dist/actions.d.ts +21 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +76 -0
- package/dist/actions.js.map +1 -0
- package/dist/cua.d.ts +49 -0
- package/dist/cua.d.ts.map +1 -0
- package/dist/cua.js +315 -0
- package/dist/cua.js.map +1 -0
- package/dist/frames.d.ts +42 -0
- package/dist/frames.d.ts.map +1 -0
- package/dist/frames.js +91 -0
- package/dist/frames.js.map +1 -0
- package/dist/index.d.ts +13 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +97 -11
- package/dist/index.js.map +1 -1
- package/dist/{apps-linux.d.ts → linux/apps-linux.d.ts} +1 -1
- package/dist/linux/apps-linux.d.ts.map +1 -0
- package/dist/{apps-linux.js → linux/apps-linux.js} +10 -9
- package/dist/linux/apps-linux.js.map +1 -0
- package/dist/{input-linux.d.ts → linux/input-linux.d.ts} +2 -1
- package/dist/linux/input-linux.d.ts.map +1 -0
- package/dist/{input-linux.js → linux/input-linux.js} +10 -5
- package/dist/linux/input-linux.js.map +1 -0
- package/dist/parse.d.ts +9 -1
- package/dist/parse.d.ts.map +1 -1
- package/dist/parse.js +120 -1
- package/dist/parse.js.map +1 -1
- package/dist/png.d.ts +11 -0
- package/dist/png.d.ts.map +1 -0
- package/dist/png.js +348 -0
- package/dist/png.js.map +1 -0
- package/dist/run.d.ts +8 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +10 -5
- package/dist/run.js.map +1 -1
- package/dist/screen.d.ts +4 -2
- package/dist/screen.d.ts.map +1 -1
- package/dist/screen.js +56 -15
- package/dist/screen.js.map +1 -1
- package/dist/types.d.ts +38 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/view.d.ts +46 -0
- package/dist/view.d.ts.map +1 -0
- package/dist/view.js +114 -0
- package/dist/view.js.map +1 -0
- package/dist/{apps-windows.d.ts → windows/apps-windows.d.ts} +3 -1
- package/dist/windows/apps-windows.d.ts.map +1 -0
- package/dist/{apps-windows.js → windows/apps-windows.js} +13 -7
- package/dist/windows/apps-windows.js.map +1 -0
- package/dist/windows/elements-windows.d.ts +8 -0
- package/dist/windows/elements-windows.d.ts.map +1 -0
- package/dist/windows/elements-windows.js +223 -0
- package/dist/windows/elements-windows.js.map +1 -0
- package/dist/{input-windows.d.ts → windows/input-windows.d.ts} +2 -1
- package/dist/windows/input-windows.d.ts.map +1 -0
- package/dist/{input-windows.js → windows/input-windows.js} +16 -13
- package/dist/windows/input-windows.js.map +1 -0
- package/dist/{notice-windows.d.ts → windows/notice-windows.d.ts} +1 -1
- package/dist/windows/notice-windows.d.ts.map +1 -0
- package/dist/{notice-windows.js → windows/notice-windows.js} +1 -1
- package/dist/windows/notice-windows.js.map +1 -0
- package/dist/windows/powershell.d.ts +2 -0
- package/dist/windows/powershell.d.ts.map +1 -0
- package/dist/windows/powershell.js +2 -0
- package/dist/windows/powershell.js.map +1 -0
- package/dist/windows/windows-dpi.d.ts +2 -0
- package/dist/windows/windows-dpi.d.ts.map +1 -0
- package/dist/windows/windows-dpi.js +5 -0
- package/dist/windows/windows-dpi.js.map +1 -0
- package/package.json +4 -3
- package/dist/apps-linux.d.ts.map +0 -1
- package/dist/apps-linux.js.map +0 -1
- package/dist/apps-windows.d.ts.map +0 -1
- package/dist/apps-windows.js.map +0 -1
- package/dist/input-linux.d.ts.map +0 -1
- package/dist/input-linux.js.map +0 -1
- package/dist/input-windows.d.ts.map +0 -1
- package/dist/input-windows.js.map +0 -1
- package/dist/notice-windows.d.ts.map +0 -1
- package/dist/notice-windows.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,23 +1,52 @@
|
|
|
1
1
|
# desktop-automation
|
|
2
2
|
|
|
3
|
-
Moves a real desktop from Node on Windows and Linux: captures the screen, moves the pointer, clicks, types, scrolls, lists and focuses windows, and uses the clipboard.
|
|
3
|
+
Moves a real desktop from Node on Windows and Linux: captures the screen, moves the pointer, clicks, types, scrolls, lists and focuses windows, reads a window's controls, and uses the clipboard.
|
|
4
4
|
|
|
5
5
|
```mermaid
|
|
6
6
|
flowchart LR
|
|
7
7
|
machine["intentic-machine<br/>screenshot, device, apps tools"] --> desktop(["desktop()"])
|
|
8
|
+
sandbox["sandbox daemon<br/>its own virtual desktop"] --> desktop
|
|
8
9
|
smoke["desktop-smoke-windows"] --> desktop
|
|
9
10
|
desktop -->|"Windows"| ps["PowerShell calling user32"]
|
|
10
11
|
desktop -->|"Linux X11"| x11["xdotool, wmctrl, xclip"]
|
|
11
12
|
desktop -->|"Linux Wayland"| wl["ydotool, wtype, sway IPC"]
|
|
13
|
+
desktop -->|"macOS; Linux elements; opt-in anywhere"| cua["cua-driver over MCP stdio"]
|
|
12
14
|
```
|
|
13
15
|
|
|
14
16
|
- Runs on the user's device inside [`intentic-machine`](../machine). It knows nothing about agents or permissions;
|
|
15
17
|
the machine's device tools decide what is allowed before calling `desktop()`.
|
|
16
18
|
- No native modules, so it works from a single-file compiled binary: every action runs an existing program
|
|
17
19
|
(`run.ts`), and a missing one fails with a `DesktopError` that says what to install.
|
|
18
|
-
- Coordinates are
|
|
19
|
-
|
|
20
|
-
-
|
|
20
|
+
- Coordinates are pixels of the whole virtual desktop, its top-left at `(0,0)`: points, window bounds, display bounds
|
|
21
|
+
and element bounds alike. On Windows each action adds the virtual desktop's origin, which is not `(0,0)` on every
|
|
22
|
+
multi-monitor setup.
|
|
23
|
+
- A screenshot an agent sees is a frame (`frames.ts`): captured at the screen's own resolution, cut to a region if
|
|
24
|
+
asked, shrunk to fit what a model reads whole (1456 px on the long edge, 1.15 megapixels), and given an id. A point
|
|
25
|
+
read off it is mapped back by `toDesktop`; `FrameLog` refuses one read off a frame that is no longer the newest, and
|
|
26
|
+
recognises a capture identical to the newest. Past those limits a model API shrinks the image itself and every
|
|
27
|
+
coordinate read off it lands short. The PNG decoding, cropping, area-average shrinking and encoding are pure
|
|
28
|
+
TypeScript over `node:zlib` (`png.ts`), about 0.2 s for a 5760×2160 desktop.
|
|
29
|
+
- Every Windows script declares itself per-monitor DPI-aware (v2) first (`windows/windows-dpi.ts`). Without it, a 4K monitor at
|
|
30
|
+
150% reads as 2560×1440 and only its top-left part is ever captured. Only per-monitor v2, no older fallback: the
|
|
31
|
+
system-wide `SetProcessDPIAware` reads a mixed-DPI desk wrong in a new way, and Defender rejected the script that
|
|
32
|
+
carried both beside a screen copy (2026-10-05, on a 4K-at-150% monitor beside a 1920×1200 one).
|
|
33
|
+
- `elements()` reads a window's controls through UI Automation (`windows/elements-windows.ts`, Windows only): one cache request
|
|
34
|
+
over the whole subtree, from a C# helper PowerShell compiles, under a second for a VS Code window of 1330 controls.
|
|
35
|
+
Chromium and Electron windows build their tree only once asked, so a bare first read is read again. An element is
|
|
36
|
+
found again by its runtime id; `elementAct` invokes, sets, toggles, expands, collapses, selects or focuses it through
|
|
37
|
+
its pattern, without the pointer, on a thread given 4 s, since an Invoke that opens a modal dialog does not return.
|
|
38
|
+
- `desktop({ env })` runs every program with that environment, so one process can drive a display of its own (the
|
|
39
|
+
sandbox's agent desktop) without writing `DISPLAY` into its own `process.env`.
|
|
40
|
+
- [cua-driver](https://github.com/trycua/cua), where the owner installed it (`cua.ts`), is driven over its own MCP
|
|
41
|
+
server on stdio, never loaded into this process: it is the whole backend on macOS, where this package has no input of
|
|
42
|
+
its own (without it every input method there throws, naming how to install it); on Linux it reads a window's controls
|
|
43
|
+
through AT-SPI, which nothing here speaks without a native module; and `INTENTIC_DESKTOP_DRIVER=cua` puts every
|
|
44
|
+
platform on it, for its background delivery. It is found at `INTENTIC_CUA_DRIVER`, on PATH, or where its installers
|
|
45
|
+
put it. Measured against cua-driver 0.33.4 on Linux/X11 (2026-10-05); macOS is untested.
|
|
46
|
+
- On Wayland, window listing works only under sway.
|
|
47
|
+
- Linux window bounds come from `xwininfo -root -tree` where it is installed: wmctrl counts a window's frame offset
|
|
48
|
+
twice under a reparenting window manager (openbox put a window 18 px too low), which cut off the top of a window's
|
|
49
|
+
screenshot.
|
|
21
50
|
- `notice()` (Windows only) shows a banner that never takes focus or appears in a capture, and reports a global
|
|
22
51
|
hotkey press; the machine uses it to pause input. `windowsSession()` says whether the sign-in screen is up, since
|
|
23
52
|
keys typed then reach nothing.
|
|
@@ -26,7 +55,7 @@ flowchart LR
|
|
|
26
55
|
|
|
27
56
|
- [src/index.ts](src/index.ts) — `desktop()`: picks the backend for the current platform.
|
|
28
57
|
- [src/types.ts](src/types.ts) — the `Desktop` interface and the coordinate model.
|
|
29
|
-
- [src/
|
|
30
|
-
- [src/
|
|
31
|
-
- [src/
|
|
32
|
-
- [src/notice-windows.ts](src/notice-windows.ts) — the on-screen notice and its hotkey.
|
|
58
|
+
- [src/windows/input-windows.ts](src/windows/input-windows.ts) — pointer and keyboard through user32 from PowerShell.
|
|
59
|
+
- [src/frames.ts](src/frames.ts) — screenshots as frames: fitting, ids, and mapping points back to the desktop.
|
|
60
|
+
- [src/windows/elements-windows.ts](src/windows/elements-windows.ts) — a window's controls through UI Automation.
|
|
61
|
+
- [src/windows/notice-windows.ts](src/windows/notice-windows.ts) — the on-screen notice and its hotkey.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type Desktop, type ScrollDirection } from "./types.js";
|
|
2
|
+
import type { Pointing } from "./view.js";
|
|
3
|
+
export type InputAction = "mouse_move" | "left_click" | "right_click" | "middle_click" | "double_click" | "left_click_drag" | "type" | "key" | "scroll" | "wait";
|
|
4
|
+
export interface InputCall {
|
|
5
|
+
readonly action: InputAction;
|
|
6
|
+
readonly coordinate?: readonly [number, number] | undefined;
|
|
7
|
+
readonly to?: readonly [number, number] | undefined;
|
|
8
|
+
readonly element?: string | undefined;
|
|
9
|
+
readonly text?: string | undefined;
|
|
10
|
+
readonly direction?: ScrollDirection | undefined;
|
|
11
|
+
readonly amount?: number | undefined;
|
|
12
|
+
readonly ms?: number | undefined;
|
|
13
|
+
}
|
|
14
|
+
export declare const SETTLE_MS = 400;
|
|
15
|
+
export declare const MAX_WAIT_MS = 10000;
|
|
16
|
+
export declare const MAX_SCROLL_NOTCHES = 50;
|
|
17
|
+
export declare const settle: () => Promise<void>;
|
|
18
|
+
export declare const describeInput: (input: InputCall) => string;
|
|
19
|
+
export declare const keyboardText: (action: "type" | "key", text: string | undefined) => string;
|
|
20
|
+
export declare const perform: (screen: Desktop, input: InputCall, pointing: Pointing) => Promise<void>;
|
|
21
|
+
//# sourceMappingURL=actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,OAAO,EAA8C,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAC5G,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAO1C,MAAM,MAAM,WAAW,GACnB,YAAY,GAAG,YAAY,GAAG,aAAa,GAAG,cAAc,GAAG,cAAc,GAAG,iBAAiB,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE3I,MAAM,WAAW,SAAS;IACtB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAC5D,QAAQ,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IAEpD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC;IACjD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAID,eAAO,MAAM,SAAS,MAAM,CAAC;AAE7B,eAAO,MAAM,WAAW,QAAS,CAAC;AAIlC,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC,eAAO,MAAM,MAAM,QAAa,OAAO,CAAC,IAAI,CAA2B,CAAC;AAoBxE,eAAO,MAAM,aAAa,UAAW,SAAS,KAAG,MAehD,CAAC;AAGF,eAAO,MAAM,YAAY,WAAY,MAAM,GAAG,KAAK,QAAQ,MAAM,GAAG,SAAS,KAAG,MAO/E,CAAC;AAgCF,eAAO,MAAM,OAAO,WAAkB,OAAO,SAAS,SAAS,YAAY,QAAQ,KAAG,OAAO,CAAC,IAAI,CAWjG,CAAC"}
|
package/dist/actions.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { setTimeout as sleep } from "node:timers/promises";
|
|
2
|
+
import { DesktopError } from "./types.js";
|
|
3
|
+
export const SETTLE_MS = 400;
|
|
4
|
+
export const MAX_WAIT_MS = 10_000;
|
|
5
|
+
export const MAX_SCROLL_NOTCHES = 50;
|
|
6
|
+
export const settle = async () => await sleep(SETTLE_MS);
|
|
7
|
+
const point = (value, name) => {
|
|
8
|
+
if (value === undefined || value.length !== 2 || !Number.isFinite(value[0]) || !Number.isFinite(value[1])) {
|
|
9
|
+
throw new DesktopError(`"${name}" must be [x, y] in screenshot pixels, or name an element ref instead.`);
|
|
10
|
+
}
|
|
11
|
+
return { x: value[0], y: value[1] };
|
|
12
|
+
};
|
|
13
|
+
const CLICK_BUTTON = new Map([
|
|
14
|
+
["left_click", "left"],
|
|
15
|
+
["right_click", "right"],
|
|
16
|
+
["middle_click", "middle"],
|
|
17
|
+
]);
|
|
18
|
+
const where = (input) => input.element === undefined || input.element === "" ? `(${input.coordinate?.join(", ") ?? ""})` : `element ${input.element}`;
|
|
19
|
+
export const describeInput = (input) => {
|
|
20
|
+
switch (input.action) {
|
|
21
|
+
case "type":
|
|
22
|
+
return `Typed ${input.text?.length ?? 0} characters.`;
|
|
23
|
+
case "key":
|
|
24
|
+
return `Pressed ${input.text ?? ""}.`;
|
|
25
|
+
case "wait":
|
|
26
|
+
return `Waited ${Math.min(input.ms ?? SETTLE_MS, MAX_WAIT_MS)}ms.`;
|
|
27
|
+
case "scroll":
|
|
28
|
+
return `Scrolled ${input.direction ?? "down"} at ${where(input)}.`;
|
|
29
|
+
case "left_click_drag":
|
|
30
|
+
return `Dragged from ${where(input)} to (${input.to?.join(", ") ?? ""}).`;
|
|
31
|
+
default:
|
|
32
|
+
return `${input.action.replace(/_/g, " ")} at ${where(input)}.`;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
export const keyboardText = (action, text) => {
|
|
36
|
+
if (text === undefined || text === "") {
|
|
37
|
+
throw new DesktopError(action === "type" ? `"text" is required to type.` : `"text" is required to press a key: for example "Return", "ctrl+c", "alt+Tab".`);
|
|
38
|
+
}
|
|
39
|
+
return text;
|
|
40
|
+
};
|
|
41
|
+
const target = async (pointing, input) => input.element === undefined || input.element === ""
|
|
42
|
+
? await pointing.point(point(input.coordinate, "coordinate"), "The coordinate")
|
|
43
|
+
: await pointing.element(input.element);
|
|
44
|
+
const pointer = async (screen, input, pointing) => {
|
|
45
|
+
const at = await target(pointing, input);
|
|
46
|
+
switch (input.action) {
|
|
47
|
+
case "mouse_move":
|
|
48
|
+
return await screen.move(at);
|
|
49
|
+
case "double_click":
|
|
50
|
+
return await screen.doubleClick(at);
|
|
51
|
+
case "left_click_drag":
|
|
52
|
+
return await screen.drag(at, await pointing.point(point(input.to, "to"), "The drag target"));
|
|
53
|
+
case "scroll":
|
|
54
|
+
return await screen.scroll(at, input.direction ?? "down", Math.min(input.amount ?? 3, MAX_SCROLL_NOTCHES));
|
|
55
|
+
default: {
|
|
56
|
+
const button = CLICK_BUTTON.get(input.action);
|
|
57
|
+
if (button === undefined) {
|
|
58
|
+
throw new DesktopError(`"${input.action}" is not something this desktop can do.`);
|
|
59
|
+
}
|
|
60
|
+
return await screen.click(at, button);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
export const perform = async (screen, input, pointing) => {
|
|
65
|
+
if (input.action === "wait") {
|
|
66
|
+
await sleep(Math.min(Math.max(0, input.ms ?? SETTLE_MS), MAX_WAIT_MS));
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (input.action === "type" || input.action === "key") {
|
|
70
|
+
const text = keyboardText(input.action, input.text);
|
|
71
|
+
await (input.action === "type" ? screen.type(text) : screen.key(text));
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
await pointer(screen, input, pointing);
|
|
75
|
+
};
|
|
76
|
+
//# sourceMappingURL=actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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"}
|
package/dist/cua.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type Desktop, type ElementAction, type Rect, type WindowInfo } from "./types.js";
|
|
3
|
+
export declare const cuaDriverCandidates: (env?: NodeJS.ProcessEnv, home?: string) => string[];
|
|
4
|
+
export declare const findCuaDriver: (env?: NodeJS.ProcessEnv) => string | undefined;
|
|
5
|
+
declare const ToolResultSchema: z.ZodObject<{
|
|
6
|
+
content: z.ZodCatch<z.ZodArray<z.ZodObject<{
|
|
7
|
+
type: z.ZodCatch<z.ZodString>;
|
|
8
|
+
text: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
9
|
+
data: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
10
|
+
}, z.core.$strip>>>;
|
|
11
|
+
structuredContent: z.ZodOptional<z.ZodUnknown>;
|
|
12
|
+
isError: z.ZodCatch<z.ZodBoolean>;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
type ToolResult = z.infer<typeof ToolResultSchema>;
|
|
15
|
+
export declare class CuaClient {
|
|
16
|
+
#private;
|
|
17
|
+
constructor(binary: string, env?: NodeJS.ProcessEnv);
|
|
18
|
+
call(name: string, args?: ToolArgs, timeoutMs?: number): Promise<ToolResult>;
|
|
19
|
+
stop(): void;
|
|
20
|
+
}
|
|
21
|
+
type Json = string | number | boolean | null | readonly Json[] | {
|
|
22
|
+
readonly [key: string]: Json | undefined;
|
|
23
|
+
};
|
|
24
|
+
type ToolArgs = {
|
|
25
|
+
readonly [key: string]: Json | undefined;
|
|
26
|
+
};
|
|
27
|
+
export declare const cuaKey: (combo: string) => {
|
|
28
|
+
key: string;
|
|
29
|
+
modifiers: import("./keys.js").Modifier[];
|
|
30
|
+
};
|
|
31
|
+
export declare const parseCuaWindows: (result: ToolResult) => WindowInfo[];
|
|
32
|
+
export declare const parseCuaElements: (result: ToolResult, window: Rect) => {
|
|
33
|
+
elements: {
|
|
34
|
+
id: string;
|
|
35
|
+
role: string;
|
|
36
|
+
name: string;
|
|
37
|
+
value: string | undefined;
|
|
38
|
+
bounds: Rect;
|
|
39
|
+
enabled: boolean;
|
|
40
|
+
focused: boolean;
|
|
41
|
+
actions: ElementAction[];
|
|
42
|
+
depth: number;
|
|
43
|
+
}[];
|
|
44
|
+
complete: boolean;
|
|
45
|
+
};
|
|
46
|
+
export declare const cuaDesktop: (client: CuaClient) => Desktop;
|
|
47
|
+
export declare const cuaElementsOnly: (client: CuaClient) => Pick<Desktop, "elements" | "element" | "elementAct">;
|
|
48
|
+
export {};
|
|
49
|
+
//# sourceMappingURL=cua.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cua.d.ts","sourceRoot":"","sources":["../src/cua.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EACH,KAAK,OAAO,EAGZ,KAAK,aAAa,EAIlB,KAAK,IAAI,EAIT,KAAK,UAAU,EAClB,MAAM,YAAY,CAAC;AAoBpB,eAAO,MAAM,mBAAmB,SAAS,MAAM,CAAC,UAAU,SAAwB,MAAM,KAAe,MAAM,EAQ5G,CAAC;AAEF,eAAO,MAAM,aAAa,SAAS,MAAM,CAAC,UAAU,KAAmB,MAAM,GAAG,SAAsE,CAAC;AAGvJ,QAAA,MAAM,gBAAgB;;;;;;;;iBAMpB,CAAC;AAEH,KAAK,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAmBnD,qBAAa,SAAS;;IAUlB,YAAY,MAAM,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAA0B,EAIjE;IA2EK,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,QAAa,EAAE,SAAS,GAAE,MAAwB,GAAG,OAAO,CAAC,UAAU,CAAC,CAYtG;IAED,IAAI,IAAI,IAAI,CAGX;CACJ;AAGD,KAAK,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,IAAI,EAAE,GAAG;IAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;CAAE,CAAC;AAC9G,KAAK,QAAQ,GAAG;IAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;CAAE,CAAC;AAuD7D,eAAO,MAAM,MAAM,UAAW,MAAM;;;CAInC,CAAC;AA0BF,eAAO,MAAM,eAAe,WAAY,UAAU,KAAG,UAAU,EASzD,CAAC;AAoDP,eAAO,MAAM,gBAAgB,WAAY,UAAU,UAAU,IAAI;;;;;;;;;;;;;CAWhE,CAAC;AAOF,eAAO,MAAM,UAAU,WAAY,SAAS,KAAG,OAoE9C,CAAC;AAGF,eAAO,MAAM,eAAe,WAAY,SAAS,KAAG,IAAI,CAAC,OAAO,EAAE,UAAU,GAAG,SAAS,GAAG,YAAY,CAGtG,CAAC"}
|
package/dist/cua.js
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
import { parseChord } from "./keys.js";
|
|
8
|
+
import { looksLikeUrl } from "./parse.js";
|
|
9
|
+
import { environment } from "./run.js";
|
|
10
|
+
import { DesktopError, } from "./types.js";
|
|
11
|
+
const CALL_TIMEOUT_MS = 30_000;
|
|
12
|
+
const START_TIMEOUT_MS = 10_000;
|
|
13
|
+
const PROTOCOL_VERSION = "2025-06-18";
|
|
14
|
+
const INSTALL = "Install cua-driver (https://cua.ai/driver): curl -fsSL https://cua.ai/driver/install.sh | bash, or install.ps1 on Windows";
|
|
15
|
+
const DESKTOP_TARGET = { kind: "desktop", display_id: "primary" };
|
|
16
|
+
export const cuaDriverCandidates = (env = environment(), home = homedir()) => [
|
|
17
|
+
...(env["INTENTIC_CUA_DRIVER"] === undefined || env["INTENTIC_CUA_DRIVER"] === "" ? [] : [env["INTENTIC_CUA_DRIVER"]]),
|
|
18
|
+
...(env["PATH"] ?? "")
|
|
19
|
+
.split(process.platform === "win32" ? ";" : ":")
|
|
20
|
+
.filter((dir) => dir !== "")
|
|
21
|
+
.map((dir) => join(dir, process.platform === "win32" ? "cua-driver.exe" : "cua-driver")),
|
|
22
|
+
join(home, ".local", "bin", "cua-driver"),
|
|
23
|
+
...(env["LOCALAPPDATA"] === undefined ? [] : [join(env["LOCALAPPDATA"], "Programs", "Cua", "cua-driver", "bin", "cua-driver.exe")]),
|
|
24
|
+
];
|
|
25
|
+
export const findCuaDriver = (env = environment()) => cuaDriverCandidates(env).find((path) => existsSync(path));
|
|
26
|
+
const ToolResultSchema = z.object({
|
|
27
|
+
content: z
|
|
28
|
+
.array(z.object({ type: z.string().catch(""), text: z.string().optional().catch(undefined), data: z.string().optional().catch(undefined) }))
|
|
29
|
+
.catch([]),
|
|
30
|
+
structuredContent: z.unknown().optional(),
|
|
31
|
+
isError: z.boolean().catch(false),
|
|
32
|
+
});
|
|
33
|
+
const AnswerSchema = z.object({
|
|
34
|
+
id: z.number(),
|
|
35
|
+
result: z.unknown().optional(),
|
|
36
|
+
error: z.object({ message: z.string().catch("no reason given") }).optional().catch(undefined),
|
|
37
|
+
});
|
|
38
|
+
export class CuaClient {
|
|
39
|
+
#binary;
|
|
40
|
+
#env;
|
|
41
|
+
#session = `intentic-${randomUUID()}`;
|
|
42
|
+
#child;
|
|
43
|
+
#ready;
|
|
44
|
+
#buffer = "";
|
|
45
|
+
#next = 0;
|
|
46
|
+
#pending = new Map();
|
|
47
|
+
constructor(binary, env = environment()) {
|
|
48
|
+
this.#binary = binary;
|
|
49
|
+
this.#env = { ...env, CUA_DRIVER_RS_TELEMETRY_ENABLED: "false", CUA_DRIVER_RS_UPDATE_CHECK: "false" };
|
|
50
|
+
}
|
|
51
|
+
#fail(error) {
|
|
52
|
+
for (const [, pending] of this.#pending) {
|
|
53
|
+
clearTimeout(pending.timer);
|
|
54
|
+
pending.reject(error);
|
|
55
|
+
}
|
|
56
|
+
this.#pending.clear();
|
|
57
|
+
this.#child = undefined;
|
|
58
|
+
this.#ready = undefined;
|
|
59
|
+
}
|
|
60
|
+
#read(chunk) {
|
|
61
|
+
this.#buffer += chunk.toString("utf8");
|
|
62
|
+
for (let end = this.#buffer.indexOf("\n"); end >= 0; end = this.#buffer.indexOf("\n")) {
|
|
63
|
+
const line = this.#buffer.slice(0, end).trim();
|
|
64
|
+
this.#buffer = this.#buffer.slice(end + 1);
|
|
65
|
+
if (line === "") {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const message = answerIn(line);
|
|
69
|
+
const pending = message === undefined ? undefined : this.#pending.get(message.id);
|
|
70
|
+
if (message !== undefined && pending !== undefined) {
|
|
71
|
+
clearTimeout(pending.timer);
|
|
72
|
+
this.#pending.delete(message.id);
|
|
73
|
+
pending.resolve(message);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
#request(method, params, timeoutMs) {
|
|
78
|
+
const child = this.#child;
|
|
79
|
+
if (child?.stdin === null || child?.stdin === undefined) {
|
|
80
|
+
return Promise.reject(new DesktopError("cua-driver is not running."));
|
|
81
|
+
}
|
|
82
|
+
this.#next += 1;
|
|
83
|
+
const id = this.#next;
|
|
84
|
+
return new Promise((resolve, reject) => {
|
|
85
|
+
const timer = setTimeout(() => {
|
|
86
|
+
this.#pending.delete(id);
|
|
87
|
+
reject(new DesktopError(`cua-driver did not answer ${method} within ${timeoutMs / 1_000}s.`));
|
|
88
|
+
}, timeoutMs);
|
|
89
|
+
this.#pending.set(id, { resolve, reject, timer });
|
|
90
|
+
child.stdin?.write(`${JSON.stringify({ jsonrpc: "2.0", id, method, params })}\n`);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
#start() {
|
|
94
|
+
const child = spawn(this.#binary, ["mcp"], { env: this.#env, stdio: ["pipe", "pipe", "ignore"], windowsHide: true });
|
|
95
|
+
this.#child = child;
|
|
96
|
+
child.stdout?.on("data", (chunk) => this.#read(chunk));
|
|
97
|
+
child.on("error", (error) => this.#fail(new DesktopError(error.code === "ENOENT" ? `There is no cua-driver at ${this.#binary}.` : `cua-driver failed: ${error.message}`, INSTALL)));
|
|
98
|
+
child.on("exit", (code) => this.#fail(new DesktopError(`cua-driver exited (${code ?? "signal"}).`)));
|
|
99
|
+
return (async () => {
|
|
100
|
+
await this.#request("initialize", { protocolVersion: PROTOCOL_VERSION, capabilities: {}, clientInfo: { name: "intentic", version: "1" } }, START_TIMEOUT_MS);
|
|
101
|
+
child.stdin?.write(`${JSON.stringify({ jsonrpc: "2.0", method: "notifications/initialized" })}\n`);
|
|
102
|
+
await this.#call("start_session", {}, START_TIMEOUT_MS);
|
|
103
|
+
})();
|
|
104
|
+
}
|
|
105
|
+
async #call(name, args, timeoutMs) {
|
|
106
|
+
const answer = await this.#request("tools/call", { name, arguments: { ...args, session: this.#session } }, timeoutMs);
|
|
107
|
+
if (answer.error !== undefined) {
|
|
108
|
+
throw new DesktopError(`cua-driver refused ${name}: ${answer.error.message}`);
|
|
109
|
+
}
|
|
110
|
+
const result = ToolResultSchema.safeParse(answer.result ?? {});
|
|
111
|
+
if (!result.success) {
|
|
112
|
+
throw new DesktopError(`cua-driver answered ${name} with something that is not a tool result.`);
|
|
113
|
+
}
|
|
114
|
+
return result.data;
|
|
115
|
+
}
|
|
116
|
+
async call(name, args = {}, timeoutMs = CALL_TIMEOUT_MS) {
|
|
117
|
+
this.#ready ??= this.#start().catch((error) => {
|
|
118
|
+
this.#child?.kill();
|
|
119
|
+
this.#fail(error instanceof Error ? error : new Error(String(error)));
|
|
120
|
+
throw error;
|
|
121
|
+
});
|
|
122
|
+
await this.#ready;
|
|
123
|
+
const result = await this.#call(name, args, timeoutMs);
|
|
124
|
+
if (result.isError) {
|
|
125
|
+
throw new DesktopError(`cua-driver ${name}: ${textOf(result) || "failed"}`);
|
|
126
|
+
}
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
stop() {
|
|
130
|
+
this.#child?.kill();
|
|
131
|
+
this.#fail(new DesktopError("cua-driver was stopped."));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const answerIn = (line) => {
|
|
135
|
+
try {
|
|
136
|
+
const parsed = AnswerSchema.safeParse(JSON.parse(line));
|
|
137
|
+
return parsed.success ? parsed.data : undefined;
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
const textOf = (result) => result.content
|
|
144
|
+
.flatMap((part) => (part.type === "text" && part.text !== undefined ? [part.text] : []))
|
|
145
|
+
.join("\n")
|
|
146
|
+
.trim();
|
|
147
|
+
const imageOf = (result) => {
|
|
148
|
+
const image = result.content.find((part) => part.type === "image" && part.data !== undefined);
|
|
149
|
+
if (image?.data === undefined) {
|
|
150
|
+
throw new DesktopError("cua-driver answered the screenshot without an image.");
|
|
151
|
+
}
|
|
152
|
+
return Buffer.from(image.data, "base64");
|
|
153
|
+
};
|
|
154
|
+
const length = z.number().refine(Number.isFinite).catch(0);
|
|
155
|
+
const structured = (result, schema) => schema.parse(result.structuredContent ?? {});
|
|
156
|
+
const CUA_KEYS = new Map([
|
|
157
|
+
["Return", "return"],
|
|
158
|
+
["Escape", "escape"],
|
|
159
|
+
["BackSpace", "backspace"],
|
|
160
|
+
["Delete", "delete"],
|
|
161
|
+
["Insert", "insert"],
|
|
162
|
+
["Tab", "tab"],
|
|
163
|
+
["space", "space"],
|
|
164
|
+
["Up", "up"],
|
|
165
|
+
["Down", "down"],
|
|
166
|
+
["Left", "left"],
|
|
167
|
+
["Right", "right"],
|
|
168
|
+
["Home", "home"],
|
|
169
|
+
["End", "end"],
|
|
170
|
+
["Page_Up", "pageup"],
|
|
171
|
+
["Page_Down", "pagedown"],
|
|
172
|
+
]);
|
|
173
|
+
export const cuaKey = (combo) => {
|
|
174
|
+
const chord = parseChord(combo);
|
|
175
|
+
const key = CUA_KEYS.get(chord.key) ?? (/^F\d{1,2}$/i.test(chord.key) ? chord.key.toLowerCase() : chord.key);
|
|
176
|
+
return { key, modifiers: [...chord.modifiers] };
|
|
177
|
+
};
|
|
178
|
+
const windowKey = (pid, windowId) => `${pid}:${windowId}`;
|
|
179
|
+
const windowArgs = (id) => {
|
|
180
|
+
const [pid, windowId] = id.split(":").map(Number);
|
|
181
|
+
if (pid === undefined || windowId === undefined || !Number.isInteger(pid) || !Number.isInteger(windowId)) {
|
|
182
|
+
throw new DesktopError(`"${id}" is not a window id from this device's window list.`);
|
|
183
|
+
}
|
|
184
|
+
return { pid, window_id: windowId };
|
|
185
|
+
};
|
|
186
|
+
const WindowRowSchema = z.object({
|
|
187
|
+
pid: z.number(),
|
|
188
|
+
window_id: z.number(),
|
|
189
|
+
title: z.string().catch(""),
|
|
190
|
+
app_name: z.string().catch("unknown"),
|
|
191
|
+
is_on_screen: z.boolean().catch(true),
|
|
192
|
+
z_index: z.number().optional().catch(undefined),
|
|
193
|
+
bounds: z.object({ x: length, y: length, width: length, height: length }).catch({ x: 0, y: 0, width: 0, height: 0 }),
|
|
194
|
+
});
|
|
195
|
+
const WindowsSchema = z.object({ windows: z.array(z.unknown()).catch([]) }).catch({ windows: [] });
|
|
196
|
+
export const parseCuaWindows = (result) => structured(result, WindowsSchema).windows.flatMap((raw) => {
|
|
197
|
+
const row = WindowRowSchema.safeParse(raw);
|
|
198
|
+
if (!row.success || !row.data.is_on_screen) {
|
|
199
|
+
return [];
|
|
200
|
+
}
|
|
201
|
+
const { pid, window_id: windowId, title, app_name: app, bounds, z_index: stacking } = row.data;
|
|
202
|
+
return [{ id: windowKey(pid, windowId), title, app, bounds, focused: stacking === 0 }];
|
|
203
|
+
});
|
|
204
|
+
const SETTABLE = /^(text|entry|edit|password text|spin button|combo box|AXTextField|AXTextArea|AXComboBox|search field|terminal)$/i;
|
|
205
|
+
const FrameSchema = z.object({ x: length, y: length, w: length, h: length });
|
|
206
|
+
const ElementRowSchema = z.object({
|
|
207
|
+
element_token: z.string().min(1),
|
|
208
|
+
role: z.string().catch(""),
|
|
209
|
+
label: z.string().catch(""),
|
|
210
|
+
value: z.string().optional().catch(undefined),
|
|
211
|
+
actions: z.array(z.string()).catch([]),
|
|
212
|
+
enabled: z.boolean().catch(true),
|
|
213
|
+
focused: z.boolean().catch(false),
|
|
214
|
+
depth: length,
|
|
215
|
+
frame: FrameSchema.optional().catch(undefined),
|
|
216
|
+
screenshot_frame: FrameSchema.optional().catch(undefined),
|
|
217
|
+
});
|
|
218
|
+
const ElementsSchema = z.object({ elements: z.array(z.unknown()).catch([]), elements_complete: z.boolean().catch(true) }).catch({ elements: [], elements_complete: true });
|
|
219
|
+
const placeOf = (row, window) => {
|
|
220
|
+
const unknown = { x: 0, y: 0, width: 0, height: 0 };
|
|
221
|
+
const placed = row.frame !== undefined
|
|
222
|
+
? { x: row.frame.x, y: row.frame.y, width: row.frame.w, height: row.frame.h }
|
|
223
|
+
: row.screenshot_frame !== undefined
|
|
224
|
+
? { x: window.x + row.screenshot_frame.x, y: window.y + row.screenshot_frame.y, width: row.screenshot_frame.w, height: row.screenshot_frame.h }
|
|
225
|
+
: unknown;
|
|
226
|
+
const atWindowOrigin = placed.x === window.x && placed.y === window.y && (placed.width !== window.width || placed.height !== window.height);
|
|
227
|
+
return row.depth > 0 && atWindowOrigin ? unknown : placed;
|
|
228
|
+
};
|
|
229
|
+
const actionsOf = (row) => {
|
|
230
|
+
const names = row.actions.map((name) => name.toLowerCase());
|
|
231
|
+
return [
|
|
232
|
+
...(names.some((name) => /click|press|activate|jump|invoke|open/.test(name)) ? ["invoke"] : []),
|
|
233
|
+
...(SETTABLE.test(row.role) ? ["set_value"] : []),
|
|
234
|
+
...(names.some((name) => name.includes("toggle")) ? ["toggle"] : []),
|
|
235
|
+
...(names.some((name) => name.includes("expand")) ? ["expand", "collapse"] : []),
|
|
236
|
+
];
|
|
237
|
+
};
|
|
238
|
+
export const parseCuaElements = (result, window) => {
|
|
239
|
+
const snapshot = structured(result, ElementsSchema);
|
|
240
|
+
const elements = snapshot.elements.flatMap((raw) => {
|
|
241
|
+
const row = ElementRowSchema.safeParse(raw);
|
|
242
|
+
if (!row.success) {
|
|
243
|
+
return [];
|
|
244
|
+
}
|
|
245
|
+
const { element_token: id, role, label, value, enabled, focused, depth } = row.data;
|
|
246
|
+
return [{ id, role: role.toLowerCase(), name: label, value, bounds: placeOf(row.data, window), enabled, focused, actions: actionsOf(row.data), depth }];
|
|
247
|
+
});
|
|
248
|
+
return { elements, complete: snapshot.elements_complete };
|
|
249
|
+
};
|
|
250
|
+
const ScreenSizeSchema = z.object({ width: length, height: length, scale_factor: z.number().positive().catch(1) });
|
|
251
|
+
const ClipboardSchema = z.object({ text: z.string().catch("") }).catch({ text: "" });
|
|
252
|
+
export const cuaDesktop = (client) => {
|
|
253
|
+
const snapshots = new Map();
|
|
254
|
+
const screenSize = async () => {
|
|
255
|
+
const size = structured(await client.call("get_screen_size"), ScreenSizeSchema);
|
|
256
|
+
return { width: Math.round(size.width * size.scale_factor), height: Math.round(size.height * size.scale_factor), origin: { x: 0, y: 0 } };
|
|
257
|
+
};
|
|
258
|
+
const windows = async () => parseCuaWindows(await client.call("list_windows", { on_screen_only: true }));
|
|
259
|
+
const at = (point) => ({ x: Math.round(point.x), y: Math.round(point.y) });
|
|
260
|
+
const press = async (combo) => {
|
|
261
|
+
const { key, modifiers } = cuaKey(combo);
|
|
262
|
+
await client.call("press_key", { key, modifiers, target: DESKTOP_TARGET });
|
|
263
|
+
};
|
|
264
|
+
const elementsOf = async (window) => {
|
|
265
|
+
const listed = (await windows()).find((candidate) => candidate.id === window);
|
|
266
|
+
if (listed === undefined) {
|
|
267
|
+
throw new DesktopError(`There is no window ${window} on this device now. List the windows again.`);
|
|
268
|
+
}
|
|
269
|
+
const state = await client.call("get_window_state", { ...windowArgs(window), include_screenshot: false, max_elements: 2_500 });
|
|
270
|
+
const { elements, complete } = parseCuaElements(state, listed.bounds);
|
|
271
|
+
snapshots.set(window, elements);
|
|
272
|
+
return { window: { id: window, title: listed.title, app: listed.app }, elements, truncated: !complete };
|
|
273
|
+
};
|
|
274
|
+
return {
|
|
275
|
+
frame: screenSize,
|
|
276
|
+
capture: async () => imageOf(await client.call("get_desktop_state")),
|
|
277
|
+
displays: async () => {
|
|
278
|
+
const { width, height } = await screenSize();
|
|
279
|
+
return [{ name: "primary", primary: true, bounds: { x: 0, y: 0, width, height } }];
|
|
280
|
+
},
|
|
281
|
+
move: async (to) => void (await client.call("move_cursor", { ...at(to), target: DESKTOP_TARGET })),
|
|
282
|
+
click: async (point, button) => void (await client.call("click", { ...at(point), button, target: DESKTOP_TARGET })),
|
|
283
|
+
doubleClick: async (point) => void (await client.call("click", { ...at(point), count: 2, target: DESKTOP_TARGET })),
|
|
284
|
+
drag: async (from, to) => void (await client.call("drag", { from_x: Math.round(from.x), from_y: Math.round(from.y), to_x: Math.round(to.x), to_y: Math.round(to.y), target: DESKTOP_TARGET })),
|
|
285
|
+
type: async (text) => void (await client.call("type_text", { text, target: DESKTOP_TARGET })),
|
|
286
|
+
key: press,
|
|
287
|
+
scroll: async (point, direction, amount) => void (await client.call("scroll", { ...at(point), direction, by: "line", amount: Math.max(1, Math.round(amount)), target: DESKTOP_TARGET })),
|
|
288
|
+
windows,
|
|
289
|
+
focusWindow: async (id) => void (await client.call("bring_to_front", windowArgs(id))),
|
|
290
|
+
launch: async (target) => void (await client.call("launch_app", looksLikeUrl(target) ? { urls: [target] } : existsSync(target) ? { launch_path: target } : { name: target })),
|
|
291
|
+
readClipboard: async () => structured(await client.call("clipboard_read", { include_text: true }), ClipboardSchema).text,
|
|
292
|
+
writeClipboard: async (text) => void (await client.call("clipboard_write", { text })),
|
|
293
|
+
elements: async (window) => {
|
|
294
|
+
const target = window ?? (await windows()).find((candidate) => candidate.focused)?.id;
|
|
295
|
+
if (target === undefined) {
|
|
296
|
+
throw new DesktopError("No window has the keyboard; name one from the window list.");
|
|
297
|
+
}
|
|
298
|
+
return await elementsOf(target);
|
|
299
|
+
},
|
|
300
|
+
element: async (window, id) => snapshots.get(window)?.find((element) => element.id === id),
|
|
301
|
+
elementAct: async (window, id, action, value) => {
|
|
302
|
+
const { pid } = windowArgs(window);
|
|
303
|
+
if (action === "set_value") {
|
|
304
|
+
await client.call("set_value", { pid, element_token: id, value: value ?? "" });
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
await client.call("click", { pid, element_token: id });
|
|
308
|
+
},
|
|
309
|
+
};
|
|
310
|
+
};
|
|
311
|
+
export const cuaElementsOnly = (client) => {
|
|
312
|
+
const whole = cuaDesktop(client);
|
|
313
|
+
return { elements: whole.elements, element: whole.element, elementAct: whole.elementAct };
|
|
314
|
+
};
|
|
315
|
+
//# sourceMappingURL=cua.js.map
|
package/dist/cua.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cua.js","sourceRoot":"","sources":["../src/cua.ts"],"names":[],"mappings":"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"}
|
package/dist/frames.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type Desktop, type Point, type Rect } from "./types.js";
|
|
2
|
+
export interface ImageLimits {
|
|
3
|
+
readonly maxEdge: number;
|
|
4
|
+
readonly maxPixels: number;
|
|
5
|
+
}
|
|
6
|
+
export declare const MODEL_IMAGE_LIMITS: {
|
|
7
|
+
maxEdge: number;
|
|
8
|
+
maxPixels: number;
|
|
9
|
+
};
|
|
10
|
+
export declare const fitSize: (width: number, height: number, limits?: ImageLimits) => {
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
13
|
+
};
|
|
14
|
+
export interface Frame {
|
|
15
|
+
readonly id: string;
|
|
16
|
+
readonly region: Rect;
|
|
17
|
+
readonly width: number;
|
|
18
|
+
readonly height: number;
|
|
19
|
+
readonly digest: string;
|
|
20
|
+
}
|
|
21
|
+
export declare const toDesktop: (frame: Frame, at: Point) => Point;
|
|
22
|
+
export declare const toImage: (frame: Frame, rect: Rect) => Rect;
|
|
23
|
+
export declare const regionOf: (frame: Frame, rect: Rect) => Rect;
|
|
24
|
+
export declare class FrameLog {
|
|
25
|
+
#private;
|
|
26
|
+
latest(): Frame | undefined;
|
|
27
|
+
resolve(id: string | undefined): Frame | undefined;
|
|
28
|
+
record(region: Rect, width: number, height: number, digest: string): {
|
|
29
|
+
frame: Frame;
|
|
30
|
+
unchanged: boolean;
|
|
31
|
+
};
|
|
32
|
+
unchangedStreak(): number;
|
|
33
|
+
sent(): void;
|
|
34
|
+
}
|
|
35
|
+
export interface Shot {
|
|
36
|
+
readonly frame: Frame;
|
|
37
|
+
readonly png: Buffer;
|
|
38
|
+
readonly unchanged: boolean;
|
|
39
|
+
}
|
|
40
|
+
export declare const shoot: (desktop: Desktop, log: FrameLog, region?: Rect, limits?: ImageLimits) => Promise<Shot>;
|
|
41
|
+
export declare const defaultFrame: (desktop: Desktop, limits?: ImageLimits) => Promise<Frame>;
|
|
42
|
+
//# sourceMappingURL=frames.d.ts.map
|