@projectservan8n/cnapse 0.9.0 → 0.10.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/dist/ProviderSelector-GZYF26LL.js +7 -0
- package/dist/autonomous-VGEVIXXQ.js +419 -0
- package/dist/browser-YLFWQXIY.js +87 -0
- package/dist/{chunk-OPX7FFL6.js → chunk-7SDY7OPA.js} +14 -55
- package/dist/chunk-COKO6V5J.js +50 -0
- package/dist/chunk-GP73OJCZ.js +377 -0
- package/dist/chunk-MOKGR7WE.js +344 -0
- package/dist/chunk-OIVTPXE4.js +307 -0
- package/dist/chunk-TFHK5CYF.js +650 -0
- package/dist/chunk-WSBJFRQH.js +366 -0
- package/dist/index.js +495 -1391
- package/dist/learner-KH3TFTD7.js +14 -0
- package/dist/vision-S57PWSCU.js +19 -0
- package/package.json +1 -1
- package/src/agents/autonomous.ts +515 -0
- package/src/agents/learner.ts +489 -0
- package/src/lib/tasks.ts +179 -54
- package/src/lib/vision.ts +139 -0
- package/src/services/screen-monitor.ts +288 -0
- package/src/services/telegram.ts +312 -5
- package/src/tools/computer.ts +226 -0
- package/dist/ProviderSelector-MXRZFAOB.js +0 -6
|
@@ -0,0 +1,650 @@
|
|
|
1
|
+
// src/tools/computer.ts
|
|
2
|
+
import { exec as exec3 } from "child_process";
|
|
3
|
+
import { promisify as promisify3 } from "util";
|
|
4
|
+
|
|
5
|
+
// src/tools/shell.ts
|
|
6
|
+
import { exec } from "child_process";
|
|
7
|
+
import { promisify } from "util";
|
|
8
|
+
var execAsync = promisify(exec);
|
|
9
|
+
async function runCommand(cmd, timeout = 3e4) {
|
|
10
|
+
try {
|
|
11
|
+
const isWindows = process.platform === "win32";
|
|
12
|
+
const shell = isWindows ? "cmd.exe" : "/bin/sh";
|
|
13
|
+
const shellArg = isWindows ? "/C" : "-c";
|
|
14
|
+
const { stdout, stderr } = await execAsync(cmd, {
|
|
15
|
+
shell,
|
|
16
|
+
timeout,
|
|
17
|
+
maxBuffer: 10 * 1024 * 1024
|
|
18
|
+
// 10MB
|
|
19
|
+
});
|
|
20
|
+
if (stderr && stderr.trim()) {
|
|
21
|
+
return ok(`${stdout}
|
|
22
|
+
[stderr]: ${stderr}`);
|
|
23
|
+
}
|
|
24
|
+
return ok(stdout || "(no output)");
|
|
25
|
+
} catch (error) {
|
|
26
|
+
if (error.killed) {
|
|
27
|
+
return err(`Command timed out after ${timeout}ms`);
|
|
28
|
+
}
|
|
29
|
+
const stderr = error.stderr || "";
|
|
30
|
+
const stdout = error.stdout || "";
|
|
31
|
+
return {
|
|
32
|
+
success: false,
|
|
33
|
+
output: stdout,
|
|
34
|
+
error: `Exit code: ${error.code || -1}
|
|
35
|
+
${stderr}`
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/tools/filesystem.ts
|
|
41
|
+
import { promises as fs } from "fs";
|
|
42
|
+
import { join, dirname } from "path";
|
|
43
|
+
async function readFile(path) {
|
|
44
|
+
try {
|
|
45
|
+
const content = await fs.readFile(path, "utf-8");
|
|
46
|
+
return ok(content);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
return err(`Failed to read file: ${error.message}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async function writeFile(path, content) {
|
|
52
|
+
try {
|
|
53
|
+
const dir = dirname(path);
|
|
54
|
+
await fs.mkdir(dir, { recursive: true });
|
|
55
|
+
await fs.writeFile(path, content, "utf-8");
|
|
56
|
+
return ok(`Written ${content.length} bytes to ${path}`);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
return err(`Failed to write file: ${error.message}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async function listDir(path, recursive = false) {
|
|
62
|
+
try {
|
|
63
|
+
const stat = await fs.stat(path);
|
|
64
|
+
if (!stat.isDirectory()) {
|
|
65
|
+
return err(`Not a directory: ${path}`);
|
|
66
|
+
}
|
|
67
|
+
const entries = [];
|
|
68
|
+
async function walkDir(dir, prefix) {
|
|
69
|
+
const items = await fs.readdir(dir, { withFileTypes: true });
|
|
70
|
+
for (const item of items) {
|
|
71
|
+
const displayPath = prefix ? `${prefix}/${item.name}` : item.name;
|
|
72
|
+
if (item.isDirectory()) {
|
|
73
|
+
entries.push(`${displayPath}/`);
|
|
74
|
+
if (recursive) {
|
|
75
|
+
await walkDir(join(dir, item.name), displayPath);
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
entries.push(displayPath);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
await walkDir(path, "");
|
|
83
|
+
entries.sort();
|
|
84
|
+
return ok(entries.join("\n"));
|
|
85
|
+
} catch (error) {
|
|
86
|
+
return err(`Failed to list directory: ${error.message}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// src/tools/clipboard.ts
|
|
91
|
+
import clipboardy from "clipboardy";
|
|
92
|
+
|
|
93
|
+
// src/tools/process.ts
|
|
94
|
+
import { exec as exec2 } from "child_process";
|
|
95
|
+
import { promisify as promisify2 } from "util";
|
|
96
|
+
var execAsync2 = promisify2(exec2);
|
|
97
|
+
|
|
98
|
+
// src/tools/index.ts
|
|
99
|
+
function ok(output) {
|
|
100
|
+
return { success: true, output };
|
|
101
|
+
}
|
|
102
|
+
function err(error) {
|
|
103
|
+
return { success: false, output: "", error };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// src/tools/computer.ts
|
|
107
|
+
var execAsync3 = promisify3(exec3);
|
|
108
|
+
async function moveMouse(x, y) {
|
|
109
|
+
try {
|
|
110
|
+
if (process.platform === "win32") {
|
|
111
|
+
await execAsync3(`powershell -Command "Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point(${x}, ${y})"`, { shell: "cmd.exe" });
|
|
112
|
+
} else if (process.platform === "darwin") {
|
|
113
|
+
await execAsync3(`cliclick m:${x},${y}`);
|
|
114
|
+
} else {
|
|
115
|
+
await execAsync3(`xdotool mousemove ${x} ${y}`);
|
|
116
|
+
}
|
|
117
|
+
return ok(`Mouse moved to (${x}, ${y})`);
|
|
118
|
+
} catch (error) {
|
|
119
|
+
return err(`Failed to move mouse: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async function clickMouse(button = "left") {
|
|
123
|
+
try {
|
|
124
|
+
if (process.platform === "win32") {
|
|
125
|
+
const script = `
|
|
126
|
+
Add-Type -MemberDefinition @"
|
|
127
|
+
[DllImport("user32.dll",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]
|
|
128
|
+
public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
|
|
129
|
+
"@ -Name Mouse -Namespace Win32
|
|
130
|
+
${button === "left" ? "[Win32.Mouse]::mouse_event(0x02, 0, 0, 0, 0); [Win32.Mouse]::mouse_event(0x04, 0, 0, 0, 0)" : button === "right" ? "[Win32.Mouse]::mouse_event(0x08, 0, 0, 0, 0); [Win32.Mouse]::mouse_event(0x10, 0, 0, 0, 0)" : "[Win32.Mouse]::mouse_event(0x20, 0, 0, 0, 0); [Win32.Mouse]::mouse_event(0x40, 0, 0, 0, 0)"}`;
|
|
131
|
+
await execAsync3(`powershell -Command "${script.replace(/\n/g, " ")}"`, { shell: "cmd.exe" });
|
|
132
|
+
} else if (process.platform === "darwin") {
|
|
133
|
+
await execAsync3(`cliclick c:.`);
|
|
134
|
+
} else {
|
|
135
|
+
const btn = button === "left" ? "1" : button === "right" ? "3" : "2";
|
|
136
|
+
await execAsync3(`xdotool click ${btn}`);
|
|
137
|
+
}
|
|
138
|
+
return ok(`Clicked ${button} button`);
|
|
139
|
+
} catch (error) {
|
|
140
|
+
return err(`Failed to click: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
async function doubleClick() {
|
|
144
|
+
try {
|
|
145
|
+
if (process.platform === "win32") {
|
|
146
|
+
const script = `
|
|
147
|
+
Add-Type -MemberDefinition @"
|
|
148
|
+
[DllImport("user32.dll",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]
|
|
149
|
+
public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
|
|
150
|
+
"@ -Name Mouse -Namespace Win32
|
|
151
|
+
[Win32.Mouse]::mouse_event(0x02, 0, 0, 0, 0); [Win32.Mouse]::mouse_event(0x04, 0, 0, 0, 0)
|
|
152
|
+
Start-Sleep -Milliseconds 50
|
|
153
|
+
[Win32.Mouse]::mouse_event(0x02, 0, 0, 0, 0); [Win32.Mouse]::mouse_event(0x04, 0, 0, 0, 0)`;
|
|
154
|
+
await execAsync3(`powershell -Command "${script.replace(/\n/g, " ")}"`, { shell: "cmd.exe" });
|
|
155
|
+
} else if (process.platform === "darwin") {
|
|
156
|
+
await execAsync3(`cliclick dc:.`);
|
|
157
|
+
} else {
|
|
158
|
+
await execAsync3(`xdotool click --repeat 2 --delay 50 1`);
|
|
159
|
+
}
|
|
160
|
+
return ok("Double clicked");
|
|
161
|
+
} catch (error) {
|
|
162
|
+
return err(`Failed to double click: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
async function typeText(text) {
|
|
166
|
+
try {
|
|
167
|
+
if (process.platform === "win32") {
|
|
168
|
+
const escapedText = text.replace(/'/g, "''").replace(/[+^%~(){}[\]]/g, "{$&}");
|
|
169
|
+
await execAsync3(`powershell -Command "Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.SendKeys]::SendWait('${escapedText}')"`, { shell: "cmd.exe" });
|
|
170
|
+
} else if (process.platform === "darwin") {
|
|
171
|
+
const escaped = text.replace(/'/g, "'\\''");
|
|
172
|
+
await execAsync3(`osascript -e 'tell application "System Events" to keystroke "${escaped}"'`);
|
|
173
|
+
} else {
|
|
174
|
+
const escaped = text.replace(/'/g, "'\\''");
|
|
175
|
+
await execAsync3(`xdotool type '${escaped}'`);
|
|
176
|
+
}
|
|
177
|
+
return ok(`Typed: ${text}`);
|
|
178
|
+
} catch (error) {
|
|
179
|
+
return err(`Failed to type: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
async function pressKey(key) {
|
|
183
|
+
try {
|
|
184
|
+
if (process.platform === "win32") {
|
|
185
|
+
const winKeyMap = {
|
|
186
|
+
"enter": "{ENTER}",
|
|
187
|
+
"return": "{ENTER}",
|
|
188
|
+
"escape": "{ESC}",
|
|
189
|
+
"esc": "{ESC}",
|
|
190
|
+
"tab": "{TAB}",
|
|
191
|
+
"space": " ",
|
|
192
|
+
"backspace": "{BACKSPACE}",
|
|
193
|
+
"delete": "{DELETE}",
|
|
194
|
+
"up": "{UP}",
|
|
195
|
+
"down": "{DOWN}",
|
|
196
|
+
"left": "{LEFT}",
|
|
197
|
+
"right": "{RIGHT}",
|
|
198
|
+
"home": "{HOME}",
|
|
199
|
+
"end": "{END}",
|
|
200
|
+
"pageup": "{PGUP}",
|
|
201
|
+
"pagedown": "{PGDN}",
|
|
202
|
+
"f1": "{F1}",
|
|
203
|
+
"f2": "{F2}",
|
|
204
|
+
"f3": "{F3}",
|
|
205
|
+
"f4": "{F4}",
|
|
206
|
+
"f5": "{F5}",
|
|
207
|
+
"f6": "{F6}",
|
|
208
|
+
"f7": "{F7}",
|
|
209
|
+
"f8": "{F8}",
|
|
210
|
+
"f9": "{F9}",
|
|
211
|
+
"f10": "{F10}",
|
|
212
|
+
"f11": "{F11}",
|
|
213
|
+
"f12": "{F12}"
|
|
214
|
+
};
|
|
215
|
+
const winKey = winKeyMap[key.toLowerCase()] || key;
|
|
216
|
+
await execAsync3(`powershell -Command "Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.SendKeys]::SendWait('${winKey}')"`, { shell: "cmd.exe" });
|
|
217
|
+
} else if (process.platform === "darwin") {
|
|
218
|
+
const macKeyMap = {
|
|
219
|
+
"return": 36,
|
|
220
|
+
"enter": 36,
|
|
221
|
+
"escape": 53,
|
|
222
|
+
"esc": 53,
|
|
223
|
+
"tab": 48,
|
|
224
|
+
"space": 49,
|
|
225
|
+
"backspace": 51,
|
|
226
|
+
"delete": 117,
|
|
227
|
+
"up": 126,
|
|
228
|
+
"down": 125,
|
|
229
|
+
"left": 123,
|
|
230
|
+
"right": 124
|
|
231
|
+
};
|
|
232
|
+
const keyCode = macKeyMap[key.toLowerCase()];
|
|
233
|
+
if (keyCode) {
|
|
234
|
+
await execAsync3(`osascript -e 'tell application "System Events" to key code ${keyCode}'`);
|
|
235
|
+
} else {
|
|
236
|
+
await execAsync3(`osascript -e 'tell application "System Events" to keystroke "${key}"'`);
|
|
237
|
+
}
|
|
238
|
+
} else {
|
|
239
|
+
await execAsync3(`xdotool key ${key}`);
|
|
240
|
+
}
|
|
241
|
+
return ok(`Pressed: ${key}`);
|
|
242
|
+
} catch (error) {
|
|
243
|
+
return err(`Failed to press key: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
async function keyCombo(keys) {
|
|
247
|
+
try {
|
|
248
|
+
if (process.platform === "win32") {
|
|
249
|
+
const hasWin = keys.some((k) => k.toLowerCase() === "meta" || k.toLowerCase() === "win");
|
|
250
|
+
const hasR = keys.some((k) => k.toLowerCase() === "r");
|
|
251
|
+
if (hasWin && hasR) {
|
|
252
|
+
await execAsync3(`powershell -Command "$shell = New-Object -ComObject WScript.Shell; $shell.Run('explorer shell:::{2559a1f3-21d7-11d4-bdaf-00c04f60b9f0}')"`, { shell: "cmd.exe" });
|
|
253
|
+
return ok(`Pressed: ${keys.join("+")}`);
|
|
254
|
+
}
|
|
255
|
+
const modifierMap = {
|
|
256
|
+
"control": "^",
|
|
257
|
+
"ctrl": "^",
|
|
258
|
+
"alt": "%",
|
|
259
|
+
"shift": "+"
|
|
260
|
+
};
|
|
261
|
+
let combo = "";
|
|
262
|
+
const regularKeys = [];
|
|
263
|
+
for (const key of keys) {
|
|
264
|
+
const lower = key.toLowerCase();
|
|
265
|
+
if (modifierMap[lower]) {
|
|
266
|
+
combo += modifierMap[lower];
|
|
267
|
+
} else if (lower !== "meta" && lower !== "win") {
|
|
268
|
+
regularKeys.push(key.toLowerCase());
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
combo += regularKeys.join("");
|
|
272
|
+
await execAsync3(`powershell -Command "Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.SendKeys]::SendWait('${combo}')"`, { shell: "cmd.exe" });
|
|
273
|
+
} else if (process.platform === "darwin") {
|
|
274
|
+
const modifiers = keys.filter((k) => ["control", "ctrl", "alt", "shift", "command", "meta"].includes(k.toLowerCase()));
|
|
275
|
+
const regular = keys.filter((k) => !["control", "ctrl", "alt", "shift", "command", "meta"].includes(k.toLowerCase()));
|
|
276
|
+
let cmd = 'tell application "System Events" to keystroke "' + regular.join("") + '"';
|
|
277
|
+
if (modifiers.length > 0) {
|
|
278
|
+
const modMap = {
|
|
279
|
+
"control": "control down",
|
|
280
|
+
"ctrl": "control down",
|
|
281
|
+
"alt": "option down",
|
|
282
|
+
"shift": "shift down",
|
|
283
|
+
"command": "command down",
|
|
284
|
+
"meta": "command down"
|
|
285
|
+
};
|
|
286
|
+
cmd += " using {" + modifiers.map((m) => modMap[m.toLowerCase()]).join(", ") + "}";
|
|
287
|
+
}
|
|
288
|
+
await execAsync3(`osascript -e '${cmd}'`);
|
|
289
|
+
} else {
|
|
290
|
+
await execAsync3(`xdotool key ${keys.join("+")}`);
|
|
291
|
+
}
|
|
292
|
+
return ok(`Pressed: ${keys.join("+")}`);
|
|
293
|
+
} catch (error) {
|
|
294
|
+
return err(`Failed to press combo: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
async function getActiveWindow() {
|
|
298
|
+
try {
|
|
299
|
+
if (process.platform === "win32") {
|
|
300
|
+
const script = `
|
|
301
|
+
Add-Type @"
|
|
302
|
+
using System;
|
|
303
|
+
using System.Runtime.InteropServices;
|
|
304
|
+
using System.Text;
|
|
305
|
+
public class Win32 {
|
|
306
|
+
[DllImport("user32.dll")]
|
|
307
|
+
public static extern IntPtr GetForegroundWindow();
|
|
308
|
+
[DllImport("user32.dll")]
|
|
309
|
+
public static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
|
|
310
|
+
}
|
|
311
|
+
"@
|
|
312
|
+
$hwnd = [Win32]::GetForegroundWindow()
|
|
313
|
+
$sb = New-Object System.Text.StringBuilder 256
|
|
314
|
+
[Win32]::GetWindowText($hwnd, $sb, 256)
|
|
315
|
+
$sb.ToString()`;
|
|
316
|
+
const { stdout } = await execAsync3(`powershell -Command "${script.replace(/\n/g, " ")}"`, { shell: "cmd.exe" });
|
|
317
|
+
return ok(stdout.trim() || "Unknown window");
|
|
318
|
+
} else if (process.platform === "darwin") {
|
|
319
|
+
const { stdout } = await execAsync3(`osascript -e 'tell application "System Events" to get name of first application process whose frontmost is true'`);
|
|
320
|
+
return ok(stdout.trim());
|
|
321
|
+
} else {
|
|
322
|
+
const { stdout } = await execAsync3(`xdotool getactivewindow getwindowname`);
|
|
323
|
+
return ok(stdout.trim());
|
|
324
|
+
}
|
|
325
|
+
} catch (error) {
|
|
326
|
+
return err(`Failed to get active window: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
async function listWindows() {
|
|
330
|
+
try {
|
|
331
|
+
if (process.platform === "win32") {
|
|
332
|
+
const { stdout } = await execAsync3(`powershell -Command "Get-Process | Where-Object {$_.MainWindowTitle} | Select-Object ProcessName, MainWindowTitle | Format-Table -AutoSize"`, { shell: "cmd.exe" });
|
|
333
|
+
return ok(stdout);
|
|
334
|
+
} else if (process.platform === "darwin") {
|
|
335
|
+
const { stdout } = await execAsync3(`osascript -e 'tell application "System Events" to get name of every application process whose visible is true'`);
|
|
336
|
+
return ok(stdout);
|
|
337
|
+
} else {
|
|
338
|
+
const { stdout } = await execAsync3(`wmctrl -l`);
|
|
339
|
+
return ok(stdout);
|
|
340
|
+
}
|
|
341
|
+
} catch (error) {
|
|
342
|
+
return err(`Failed to list windows: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
async function focusWindow(title) {
|
|
346
|
+
try {
|
|
347
|
+
if (process.platform === "win32") {
|
|
348
|
+
const escaped = title.replace(/'/g, "''");
|
|
349
|
+
await execAsync3(`powershell -Command "$wshell = New-Object -ComObject wscript.shell; $wshell.AppActivate('${escaped}')"`, { shell: "cmd.exe" });
|
|
350
|
+
} else if (process.platform === "darwin") {
|
|
351
|
+
await execAsync3(`osascript -e 'tell application "${title}" to activate'`);
|
|
352
|
+
} else {
|
|
353
|
+
await execAsync3(`wmctrl -a "${title}"`);
|
|
354
|
+
}
|
|
355
|
+
return ok(`Focused window: ${title}`);
|
|
356
|
+
} catch (error) {
|
|
357
|
+
return err(`Failed to focus window: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
async function minimizeWindow(title) {
|
|
361
|
+
try {
|
|
362
|
+
if (process.platform === "win32") {
|
|
363
|
+
if (title) {
|
|
364
|
+
const escaped = title.replace(/'/g, "''");
|
|
365
|
+
const script = `
|
|
366
|
+
$proc = Get-Process | Where-Object { $_.MainWindowTitle -like '*${escaped}*' -and $_.MainWindowHandle -ne 0 } | Select-Object -First 1
|
|
367
|
+
if ($proc) {
|
|
368
|
+
Add-Type @"
|
|
369
|
+
using System;
|
|
370
|
+
using System.Runtime.InteropServices;
|
|
371
|
+
public class Win32 {
|
|
372
|
+
[DllImport("user32.dll")]
|
|
373
|
+
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
|
|
374
|
+
}
|
|
375
|
+
"@
|
|
376
|
+
[Win32]::ShowWindow($proc.MainWindowHandle, 6)
|
|
377
|
+
Write-Output "Minimized: $($proc.MainWindowTitle)"
|
|
378
|
+
} else {
|
|
379
|
+
Write-Output "NOT_FOUND"
|
|
380
|
+
}`;
|
|
381
|
+
const { stdout } = await execAsync3(`powershell -Command "${script.replace(/\n/g, " ")}"`, { shell: "cmd.exe" });
|
|
382
|
+
if (stdout.includes("NOT_FOUND")) {
|
|
383
|
+
return err(`Window containing "${title}" not found`);
|
|
384
|
+
}
|
|
385
|
+
return ok(stdout.trim());
|
|
386
|
+
} else {
|
|
387
|
+
await execAsync3(`powershell -Command "Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.SendKeys]::SendWait('% n')"`, { shell: "cmd.exe" });
|
|
388
|
+
return ok("Minimized active window");
|
|
389
|
+
}
|
|
390
|
+
} else if (process.platform === "darwin") {
|
|
391
|
+
if (title) {
|
|
392
|
+
await execAsync3(`osascript -e 'tell application "${title}" to set miniaturized of window 1 to true'`);
|
|
393
|
+
} else {
|
|
394
|
+
await execAsync3(`osascript -e 'tell application "System Events" to keystroke "m" using command down'`);
|
|
395
|
+
}
|
|
396
|
+
return ok(`Minimized window${title ? `: ${title}` : ""}`);
|
|
397
|
+
} else {
|
|
398
|
+
if (title) {
|
|
399
|
+
await execAsync3(`wmctrl -r "${title}" -b add,hidden`);
|
|
400
|
+
} else {
|
|
401
|
+
await execAsync3(`xdotool getactivewindow windowminimize`);
|
|
402
|
+
}
|
|
403
|
+
return ok(`Minimized window${title ? `: ${title}` : ""}`);
|
|
404
|
+
}
|
|
405
|
+
} catch (error) {
|
|
406
|
+
return err(`Failed to minimize window: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
async function maximizeWindow(title) {
|
|
410
|
+
try {
|
|
411
|
+
if (process.platform === "win32") {
|
|
412
|
+
if (title) {
|
|
413
|
+
const escaped = title.replace(/'/g, "''");
|
|
414
|
+
const script = `
|
|
415
|
+
$proc = Get-Process | Where-Object { $_.MainWindowTitle -like '*${escaped}*' -and $_.MainWindowHandle -ne 0 } | Select-Object -First 1
|
|
416
|
+
if ($proc) {
|
|
417
|
+
Add-Type @"
|
|
418
|
+
using System;
|
|
419
|
+
using System.Runtime.InteropServices;
|
|
420
|
+
public class Win32 {
|
|
421
|
+
[DllImport("user32.dll")]
|
|
422
|
+
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
|
|
423
|
+
}
|
|
424
|
+
"@
|
|
425
|
+
[Win32]::ShowWindow($proc.MainWindowHandle, 3)
|
|
426
|
+
Write-Output "Maximized: $($proc.MainWindowTitle)"
|
|
427
|
+
} else {
|
|
428
|
+
Write-Output "NOT_FOUND"
|
|
429
|
+
}`;
|
|
430
|
+
const { stdout } = await execAsync3(`powershell -Command "${script.replace(/\n/g, " ")}"`, { shell: "cmd.exe" });
|
|
431
|
+
if (stdout.includes("NOT_FOUND")) {
|
|
432
|
+
return err(`Window containing "${title}" not found`);
|
|
433
|
+
}
|
|
434
|
+
return ok(stdout.trim());
|
|
435
|
+
} else {
|
|
436
|
+
await execAsync3(`powershell -Command "Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.SendKeys]::SendWait('% x')"`, { shell: "cmd.exe" });
|
|
437
|
+
return ok("Maximized active window");
|
|
438
|
+
}
|
|
439
|
+
} else if (process.platform === "darwin") {
|
|
440
|
+
if (title) {
|
|
441
|
+
await execAsync3(`osascript -e 'tell application "${title}" to set zoomed of window 1 to true'`);
|
|
442
|
+
} else {
|
|
443
|
+
await execAsync3(`osascript -e 'tell application "System Events" to keystroke "f" using {control down, command down}'`);
|
|
444
|
+
}
|
|
445
|
+
return ok(`Maximized window${title ? `: ${title}` : ""}`);
|
|
446
|
+
} else {
|
|
447
|
+
if (title) {
|
|
448
|
+
await execAsync3(`wmctrl -r "${title}" -b add,maximized_vert,maximized_horz`);
|
|
449
|
+
} else {
|
|
450
|
+
await execAsync3(`wmctrl -r :ACTIVE: -b add,maximized_vert,maximized_horz`);
|
|
451
|
+
}
|
|
452
|
+
return ok(`Maximized window${title ? `: ${title}` : ""}`);
|
|
453
|
+
}
|
|
454
|
+
} catch (error) {
|
|
455
|
+
return err(`Failed to maximize window: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
async function closeWindow(title) {
|
|
459
|
+
try {
|
|
460
|
+
if (process.platform === "win32") {
|
|
461
|
+
if (title) {
|
|
462
|
+
const escaped = title.replace(/'/g, "''");
|
|
463
|
+
await execAsync3(`powershell -Command "Get-Process | Where-Object { $_.MainWindowTitle -like '*${escaped}*' } | ForEach-Object { $_.CloseMainWindow() }"`, { shell: "cmd.exe" });
|
|
464
|
+
return ok(`Closed window: ${title}`);
|
|
465
|
+
} else {
|
|
466
|
+
await execAsync3(`powershell -Command "Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.SendKeys]::SendWait('%{F4}')"`, { shell: "cmd.exe" });
|
|
467
|
+
return ok("Closed active window");
|
|
468
|
+
}
|
|
469
|
+
} else if (process.platform === "darwin") {
|
|
470
|
+
if (title) {
|
|
471
|
+
await execAsync3(`osascript -e 'tell application "${title}" to close window 1'`);
|
|
472
|
+
} else {
|
|
473
|
+
await execAsync3(`osascript -e 'tell application "System Events" to keystroke "w" using command down'`);
|
|
474
|
+
}
|
|
475
|
+
return ok(`Closed window${title ? `: ${title}` : ""}`);
|
|
476
|
+
} else {
|
|
477
|
+
if (title) {
|
|
478
|
+
await execAsync3(`wmctrl -c "${title}"`);
|
|
479
|
+
} else {
|
|
480
|
+
await execAsync3(`xdotool getactivewindow windowclose`);
|
|
481
|
+
}
|
|
482
|
+
return ok(`Closed window${title ? `: ${title}` : ""}`);
|
|
483
|
+
}
|
|
484
|
+
} catch (error) {
|
|
485
|
+
return err(`Failed to close window: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
async function restoreWindow(title) {
|
|
489
|
+
try {
|
|
490
|
+
if (process.platform === "win32") {
|
|
491
|
+
const escaped = title.replace(/'/g, "''");
|
|
492
|
+
const script = `
|
|
493
|
+
$proc = Get-Process | Where-Object { $_.MainWindowTitle -like '*${escaped}*' -and $_.MainWindowHandle -ne 0 } | Select-Object -First 1
|
|
494
|
+
if ($proc) {
|
|
495
|
+
Add-Type @"
|
|
496
|
+
using System;
|
|
497
|
+
using System.Runtime.InteropServices;
|
|
498
|
+
public class Win32 {
|
|
499
|
+
[DllImport("user32.dll")]
|
|
500
|
+
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
|
|
501
|
+
}
|
|
502
|
+
"@
|
|
503
|
+
[Win32]::ShowWindow($proc.MainWindowHandle, 9)
|
|
504
|
+
Write-Output "Restored: $($proc.MainWindowTitle)"
|
|
505
|
+
} else {
|
|
506
|
+
Write-Output "NOT_FOUND"
|
|
507
|
+
}`;
|
|
508
|
+
const { stdout } = await execAsync3(`powershell -Command "${script.replace(/\n/g, " ")}"`, { shell: "cmd.exe" });
|
|
509
|
+
if (stdout.includes("NOT_FOUND")) {
|
|
510
|
+
return err(`Window containing "${title}" not found`);
|
|
511
|
+
}
|
|
512
|
+
return ok(stdout.trim());
|
|
513
|
+
} else if (process.platform === "darwin") {
|
|
514
|
+
await execAsync3(`osascript -e 'tell application "${title}" to set miniaturized of window 1 to false'`);
|
|
515
|
+
return ok(`Restored window: ${title}`);
|
|
516
|
+
} else {
|
|
517
|
+
await execAsync3(`wmctrl -r "${title}" -b remove,hidden`);
|
|
518
|
+
return ok(`Restored window: ${title}`);
|
|
519
|
+
}
|
|
520
|
+
} catch (error) {
|
|
521
|
+
return err(`Failed to restore window: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
async function scrollMouse(amount) {
|
|
525
|
+
try {
|
|
526
|
+
if (process.platform === "win32") {
|
|
527
|
+
const direction = amount > 0 ? 120 * Math.abs(amount) : -120 * Math.abs(amount);
|
|
528
|
+
const script = `
|
|
529
|
+
Add-Type -MemberDefinition @"
|
|
530
|
+
[DllImport("user32.dll",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]
|
|
531
|
+
public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
|
|
532
|
+
"@ -Name Mouse -Namespace Win32
|
|
533
|
+
[Win32.Mouse]::mouse_event(0x0800, 0, 0, ${direction}, 0)`;
|
|
534
|
+
await execAsync3(`powershell -Command "${script.replace(/\n/g, " ")}"`, { shell: "cmd.exe" });
|
|
535
|
+
} else if (process.platform === "darwin") {
|
|
536
|
+
const dir = amount > 0 ? "u" : "d";
|
|
537
|
+
await execAsync3(`cliclick -r ${dir}:${Math.abs(amount)}`);
|
|
538
|
+
} else {
|
|
539
|
+
const btn = amount > 0 ? "4" : "5";
|
|
540
|
+
await execAsync3(`xdotool click --repeat ${Math.abs(amount)} ${btn}`);
|
|
541
|
+
}
|
|
542
|
+
return ok(`Scrolled ${amount > 0 ? "up" : "down"} by ${Math.abs(amount)}`);
|
|
543
|
+
} catch (error) {
|
|
544
|
+
return err(`Failed to scroll: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
async function getMousePosition() {
|
|
548
|
+
try {
|
|
549
|
+
if (process.platform === "win32") {
|
|
550
|
+
const { stdout } = await execAsync3(`powershell -Command "Add-Type -AssemblyName System.Windows.Forms; $p = [System.Windows.Forms.Cursor]::Position; Write-Output \\"$($p.X),$($p.Y)\\""`, { shell: "cmd.exe" });
|
|
551
|
+
return ok(`Mouse position: ${stdout.trim()}`);
|
|
552
|
+
} else if (process.platform === "darwin") {
|
|
553
|
+
const { stdout } = await execAsync3(`cliclick p`);
|
|
554
|
+
return ok(`Mouse position: ${stdout.trim()}`);
|
|
555
|
+
} else {
|
|
556
|
+
const { stdout } = await execAsync3(`xdotool getmouselocation --shell`);
|
|
557
|
+
return ok(stdout);
|
|
558
|
+
}
|
|
559
|
+
} catch (error) {
|
|
560
|
+
return err(`Failed to get mouse position: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
564
|
+
async function moveMouseSmooth(targetX, targetY, durationMs = 300) {
|
|
565
|
+
try {
|
|
566
|
+
const posResult = await getMousePosition();
|
|
567
|
+
const match = posResult.output.match(/(\d+)[,\s]+(\d+)/);
|
|
568
|
+
let startX = 0, startY = 0;
|
|
569
|
+
if (match) {
|
|
570
|
+
startX = parseInt(match[1]);
|
|
571
|
+
startY = parseInt(match[2]);
|
|
572
|
+
}
|
|
573
|
+
const steps = Math.max(10, Math.ceil(durationMs / 16));
|
|
574
|
+
const stepDelay = durationMs / steps;
|
|
575
|
+
for (let i = 1; i <= steps; i++) {
|
|
576
|
+
const t = i / steps;
|
|
577
|
+
const easeT = 1 - Math.pow(1 - t, 2);
|
|
578
|
+
const x = Math.round(startX + (targetX - startX) * easeT);
|
|
579
|
+
const y = Math.round(startY + (targetY - startY) * easeT);
|
|
580
|
+
await moveMouse(x, y);
|
|
581
|
+
await sleep(stepDelay);
|
|
582
|
+
}
|
|
583
|
+
return ok(`Smoothly moved to (${targetX}, ${targetY})`);
|
|
584
|
+
} catch (error) {
|
|
585
|
+
return err(`Failed to move smoothly: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
async function typeTextHuman(text, wpm = 60) {
|
|
589
|
+
try {
|
|
590
|
+
const baseDelayMs = 6e4 / (wpm * 5);
|
|
591
|
+
for (let i = 0; i < text.length; i++) {
|
|
592
|
+
const char = text[i];
|
|
593
|
+
await typeText(char);
|
|
594
|
+
const delay = baseDelayMs * (0.8 + Math.random() * 0.4);
|
|
595
|
+
await sleep(delay);
|
|
596
|
+
if (Math.random() < 0.05) {
|
|
597
|
+
await sleep(200 + Math.random() * 400);
|
|
598
|
+
}
|
|
599
|
+
if ([".", ",", "!", "?", ";"].includes(char) && Math.random() < 0.3) {
|
|
600
|
+
await sleep(100 + Math.random() * 200);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
return ok(`Typed (human-like): ${text.slice(0, 50)}${text.length > 50 ? "..." : ""}`);
|
|
604
|
+
} catch (error) {
|
|
605
|
+
return err(`Failed to type: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
async function findAndClick(description) {
|
|
609
|
+
try {
|
|
610
|
+
const { captureScreenshot, findElementCoordinates } = await import("./vision-S57PWSCU.js");
|
|
611
|
+
const screenshot = await captureScreenshot();
|
|
612
|
+
if (!screenshot) {
|
|
613
|
+
return err("Failed to capture screenshot");
|
|
614
|
+
}
|
|
615
|
+
const coords = await findElementCoordinates(screenshot, description);
|
|
616
|
+
if (!coords) {
|
|
617
|
+
return err(`Could not find element: ${description}`);
|
|
618
|
+
}
|
|
619
|
+
await moveMouseSmooth(coords.x, coords.y, 250);
|
|
620
|
+
await sleep(100);
|
|
621
|
+
await clickMouse("left");
|
|
622
|
+
return ok(`Found and clicked: ${description} at (${coords.x}, ${coords.y})`);
|
|
623
|
+
} catch (error) {
|
|
624
|
+
return err(`Failed to find and click: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
export {
|
|
629
|
+
readFile,
|
|
630
|
+
writeFile,
|
|
631
|
+
listDir,
|
|
632
|
+
moveMouse,
|
|
633
|
+
clickMouse,
|
|
634
|
+
doubleClick,
|
|
635
|
+
typeText,
|
|
636
|
+
pressKey,
|
|
637
|
+
keyCombo,
|
|
638
|
+
getActiveWindow,
|
|
639
|
+
listWindows,
|
|
640
|
+
focusWindow,
|
|
641
|
+
minimizeWindow,
|
|
642
|
+
maximizeWindow,
|
|
643
|
+
closeWindow,
|
|
644
|
+
restoreWindow,
|
|
645
|
+
scrollMouse,
|
|
646
|
+
getMousePosition,
|
|
647
|
+
typeTextHuman,
|
|
648
|
+
findAndClick,
|
|
649
|
+
runCommand
|
|
650
|
+
};
|