@vitalops/opendesk-sdk 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.
- package/README.md +176 -0
- package/bin/opendesk-mcp.js +14 -0
- package/bin/opendesk.js +40 -0
- package/dist/client.d.ts +74 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +55 -0
- package/dist/client.js.map +1 -0
- package/dist/computer/sandbox.d.ts +31 -0
- package/dist/computer/sandbox.d.ts.map +1 -0
- package/dist/computer/sandbox.js +65 -0
- package/dist/computer/sandbox.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/install.d.ts +10 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +49 -0
- package/dist/install.js.map +1 -0
- package/dist/mcp.d.ts +18 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +56 -0
- package/dist/mcp.js.map +1 -0
- package/dist/registry.d.ts +9 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +41 -0
- package/dist/registry.js.map +1 -0
- package/dist/tools/app.d.ts +21 -0
- package/dist/tools/app.d.ts.map +1 -0
- package/dist/tools/app.js +101 -0
- package/dist/tools/app.js.map +1 -0
- package/dist/tools/audit.d.ts +21 -0
- package/dist/tools/audit.d.ts.map +1 -0
- package/dist/tools/audit.js +34 -0
- package/dist/tools/audit.js.map +1 -0
- package/dist/tools/base.d.ts +33 -0
- package/dist/tools/base.d.ts.map +1 -0
- package/dist/tools/base.js +22 -0
- package/dist/tools/base.js.map +1 -0
- package/dist/tools/clipboard.d.ts +21 -0
- package/dist/tools/clipboard.d.ts.map +1 -0
- package/dist/tools/clipboard.js +39 -0
- package/dist/tools/clipboard.js.map +1 -0
- package/dist/tools/keyboard.d.ts +37 -0
- package/dist/tools/keyboard.d.ts.map +1 -0
- package/dist/tools/keyboard.js +62 -0
- package/dist/tools/keyboard.js.map +1 -0
- package/dist/tools/mouse.d.ts +37 -0
- package/dist/tools/mouse.d.ts.map +1 -0
- package/dist/tools/mouse.js +77 -0
- package/dist/tools/mouse.js.map +1 -0
- package/dist/tools/ocr.d.ts +19 -0
- package/dist/tools/ocr.d.ts.map +1 -0
- package/dist/tools/ocr.js +39 -0
- package/dist/tools/ocr.js.map +1 -0
- package/dist/tools/screenshot.d.ts +28 -0
- package/dist/tools/screenshot.d.ts.map +1 -0
- package/dist/tools/screenshot.js +41 -0
- package/dist/tools/screenshot.js.map +1 -0
- package/dist/tools/ui.d.ts +55 -0
- package/dist/tools/ui.d.ts.map +1 -0
- package/dist/tools/ui.js +173 -0
- package/dist/tools/ui.js.map +1 -0
- package/package.json +45 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Tool } from "./tools/base.js";
|
|
2
|
+
export declare class ToolRegistry {
|
|
3
|
+
private tools;
|
|
4
|
+
register(tool: Tool): this;
|
|
5
|
+
get(name: string): Tool;
|
|
6
|
+
all(): Tool[];
|
|
7
|
+
}
|
|
8
|
+
export declare function createRegistry(): ToolRegistry;
|
|
9
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAUvC,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAA2B;IAExC,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAK1B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAMvB,GAAG,IAAI,IAAI,EAAE;CAGd;AAED,wBAAgB,cAAc,IAAI,YAAY,CAe7C"}
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ScreenshotTool } from "./tools/screenshot.js";
|
|
2
|
+
import { MouseTool } from "./tools/mouse.js";
|
|
3
|
+
import { KeyboardTool } from "./tools/keyboard.js";
|
|
4
|
+
import { AppTool } from "./tools/app.js";
|
|
5
|
+
import { ClipboardTool } from "./tools/clipboard.js";
|
|
6
|
+
import { OCRTool } from "./tools/ocr.js";
|
|
7
|
+
import { UITool } from "./tools/ui.js";
|
|
8
|
+
import { AuditTool } from "./tools/audit.js";
|
|
9
|
+
export class ToolRegistry {
|
|
10
|
+
tools = new Map();
|
|
11
|
+
register(tool) {
|
|
12
|
+
this.tools.set(tool.name, tool);
|
|
13
|
+
return this;
|
|
14
|
+
}
|
|
15
|
+
get(name) {
|
|
16
|
+
const tool = this.tools.get(name);
|
|
17
|
+
if (!tool)
|
|
18
|
+
throw new Error(`Tool '${name}' not found. Available: ${[...this.tools.keys()].join(", ")}`);
|
|
19
|
+
return tool;
|
|
20
|
+
}
|
|
21
|
+
all() {
|
|
22
|
+
return [...this.tools.values()];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function createRegistry() {
|
|
26
|
+
const registry = new ToolRegistry();
|
|
27
|
+
for (const tool of [
|
|
28
|
+
new ScreenshotTool(),
|
|
29
|
+
new MouseTool(),
|
|
30
|
+
new KeyboardTool(),
|
|
31
|
+
new AppTool(),
|
|
32
|
+
new UITool(),
|
|
33
|
+
new ClipboardTool(),
|
|
34
|
+
new OCRTool(),
|
|
35
|
+
new AuditTool(),
|
|
36
|
+
]) {
|
|
37
|
+
registry.register(tool);
|
|
38
|
+
}
|
|
39
|
+
return registry;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,MAAM,OAAO,YAAY;IACf,KAAK,GAAG,IAAI,GAAG,EAAgB,CAAC;IAExC,QAAQ,CAAC,IAAU;QACjB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,GAAG,CAAC,IAAY;QACd,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,2BAA2B,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxG,OAAO,IAAI,CAAC;IACd,CAAC;IAED,GAAG;QACD,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAClC,CAAC;CACF;AAED,MAAM,UAAU,cAAc;IAC5B,MAAM,QAAQ,GAAG,IAAI,YAAY,EAAE,CAAC;IACpC,KAAK,MAAM,IAAI,IAAI;QACjB,IAAI,cAAc,EAAE;QACpB,IAAI,SAAS,EAAE;QACf,IAAI,YAAY,EAAE;QAClB,IAAI,OAAO,EAAE;QACb,IAAI,MAAM,EAAE;QACZ,IAAI,aAAa,EAAE;QACnB,IAAI,OAAO,EAAE;QACb,IAAI,SAAS,EAAE;KAChB,EAAE,CAAC;QACF,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Tool, ToolContext, ToolResult } from "./base.js";
|
|
2
|
+
export declare class AppTool extends Tool {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
schema: {
|
|
6
|
+
type: string;
|
|
7
|
+
required: string[];
|
|
8
|
+
properties: {
|
|
9
|
+
action: {
|
|
10
|
+
type: string;
|
|
11
|
+
enum: string[];
|
|
12
|
+
};
|
|
13
|
+
name: {
|
|
14
|
+
type: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
execute(ctx: ToolContext, params: Record<string, unknown>): Promise<ToolResult>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=app.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/tools/app.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAmB,MAAM,WAAW,CAAC;AAK3E,qBAAa,OAAQ,SAAQ,IAAI;IAC/B,IAAI,SAAS;IACb,WAAW,SAA+C;IAE1D,MAAM;;;;;;;;;;;;;MAOJ;IAEI,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;CA0EtF"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
import { Tool, checkPermission } from "./base.js";
|
|
4
|
+
import { getSandbox } from "../computer/sandbox.js";
|
|
5
|
+
const exec = promisify(execFile);
|
|
6
|
+
export class AppTool extends Tool {
|
|
7
|
+
name = "app";
|
|
8
|
+
description = "Open, close, focus, or list applications.";
|
|
9
|
+
schema = {
|
|
10
|
+
type: "object",
|
|
11
|
+
required: ["action"],
|
|
12
|
+
properties: {
|
|
13
|
+
action: { type: "string", enum: ["open", "close", "focus", "list"] },
|
|
14
|
+
name: { type: "string", description: "Application name or path — required for open/close/focus" },
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
async execute(ctx, params) {
|
|
18
|
+
const { action, name } = params;
|
|
19
|
+
await checkPermission(ctx, "app", `${action} ${name ?? ""}`, `App ${action}`);
|
|
20
|
+
const sandbox = getSandbox(ctx.sessionId);
|
|
21
|
+
if (name && !sandbox.isAppAllowed(name)) {
|
|
22
|
+
return this.err("App denied", `'${name}' is not in the allowed apps list.`);
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const platform = process.platform;
|
|
26
|
+
switch (action) {
|
|
27
|
+
case "open": {
|
|
28
|
+
if (!name)
|
|
29
|
+
return this.err("App error", "name is required for action=open");
|
|
30
|
+
if (platform === "darwin")
|
|
31
|
+
await exec("open", ["-a", name]);
|
|
32
|
+
else if (platform === "win32")
|
|
33
|
+
await exec("cmd", ["/c", "start", "", name]);
|
|
34
|
+
else
|
|
35
|
+
await exec("xdg-open", [name]);
|
|
36
|
+
sandbox.recordAction("app_open", params, "ok");
|
|
37
|
+
return this.ok("App open", `Opened '${name}'.`);
|
|
38
|
+
}
|
|
39
|
+
case "close": {
|
|
40
|
+
if (!name)
|
|
41
|
+
return this.err("App error", "name is required for action=close");
|
|
42
|
+
if (platform === "darwin") {
|
|
43
|
+
await exec("osascript", ["-e", `quit app "${name}"`]);
|
|
44
|
+
}
|
|
45
|
+
else if (platform === "win32") {
|
|
46
|
+
await exec("taskkill", ["/IM", `${name}.exe`, "/F"]);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
await exec("pkill", ["-f", name]);
|
|
50
|
+
}
|
|
51
|
+
sandbox.recordAction("app_close", params, "ok");
|
|
52
|
+
return this.ok("App close", `Closed '${name}'.`);
|
|
53
|
+
}
|
|
54
|
+
case "focus": {
|
|
55
|
+
if (!name)
|
|
56
|
+
return this.err("App error", "name is required for action=focus");
|
|
57
|
+
if (platform === "darwin") {
|
|
58
|
+
await exec("osascript", ["-e", `tell application "${name}" to activate`]);
|
|
59
|
+
}
|
|
60
|
+
else if (platform === "win32") {
|
|
61
|
+
await exec("powershell", [
|
|
62
|
+
"-Command",
|
|
63
|
+
`(New-Object -ComObject WScript.Shell).AppActivate('${name}')`,
|
|
64
|
+
]);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
await exec("wmctrl", ["-a", name]);
|
|
68
|
+
}
|
|
69
|
+
sandbox.recordAction("app_focus", params, "ok");
|
|
70
|
+
return this.ok("App focus", `Focused '${name}'.`);
|
|
71
|
+
}
|
|
72
|
+
case "list": {
|
|
73
|
+
let output = "";
|
|
74
|
+
if (platform === "darwin") {
|
|
75
|
+
const { stdout } = await exec("osascript", [
|
|
76
|
+
"-e",
|
|
77
|
+
"tell application \"System Events\" to get name of every process whose background only is false",
|
|
78
|
+
]);
|
|
79
|
+
output = stdout.trim();
|
|
80
|
+
}
|
|
81
|
+
else if (platform === "win32") {
|
|
82
|
+
const { stdout } = await exec("tasklist", ["/fo", "csv", "/nh"]);
|
|
83
|
+
output = stdout.trim();
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
const { stdout } = await exec("wmctrl", ["-l"]);
|
|
87
|
+
output = stdout.trim();
|
|
88
|
+
}
|
|
89
|
+
sandbox.recordAction("app_list", params, "ok");
|
|
90
|
+
return this.ok("App list", output);
|
|
91
|
+
}
|
|
92
|
+
default:
|
|
93
|
+
return this.err("App error", `Unknown action: ${action}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (e) {
|
|
97
|
+
return this.err("App error", `${e}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/tools/app.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Tool, ToolContext, ToolResult } from "./base.js";
|
|
2
|
+
export declare class AuditTool extends Tool {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
schema: {
|
|
6
|
+
type: string;
|
|
7
|
+
properties: {
|
|
8
|
+
format: {
|
|
9
|
+
type: string;
|
|
10
|
+
enum: string[];
|
|
11
|
+
default: string;
|
|
12
|
+
};
|
|
13
|
+
sessionId: {
|
|
14
|
+
type: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
execute(ctx: ToolContext, params: Record<string, unknown>): Promise<ToolResult>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/tools/audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAG1D,qBAAa,SAAU,SAAQ,IAAI;IACjC,IAAI,SAAW;IACf,WAAW,SAEuF;IAElG,MAAM;;;;;;;;;;;;;MAMJ;IAEI,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;CAuBtF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Tool } from "./base.js";
|
|
2
|
+
import { getSandbox } from "../computer/sandbox.js";
|
|
3
|
+
export class AuditTool extends Tool {
|
|
4
|
+
name = "audit";
|
|
5
|
+
description = "Show the session audit log — every action taken so far. " +
|
|
6
|
+
"Use format='summary' for a one-line count, or format='full' for the complete timestamped log.";
|
|
7
|
+
schema = {
|
|
8
|
+
type: "object",
|
|
9
|
+
properties: {
|
|
10
|
+
format: { type: "string", enum: ["summary", "full"], default: "full" },
|
|
11
|
+
sessionId: { type: "string", description: "Session to inspect — defaults to current session" },
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
async execute(ctx, params) {
|
|
15
|
+
const format = params.format ?? "full";
|
|
16
|
+
const sessionId = params.sessionId ?? ctx.sessionId;
|
|
17
|
+
const sandbox = getSandbox(sessionId);
|
|
18
|
+
if (format === "summary") {
|
|
19
|
+
return this.ok("Audit summary", sandbox.summary());
|
|
20
|
+
}
|
|
21
|
+
const log = sandbox.exportAuditLog();
|
|
22
|
+
if (!log.length) {
|
|
23
|
+
return this.ok("Audit log", `No actions recorded yet for session '${sessionId}'.`);
|
|
24
|
+
}
|
|
25
|
+
const lines = [`Audit log — session '${sessionId}' (${log.length} actions)\n`];
|
|
26
|
+
for (const entry of log) {
|
|
27
|
+
const ts = new Date(entry.timestamp * 1000).toISOString().replace("T", " ").slice(0, 19);
|
|
28
|
+
const errorTag = entry.error ? ` ERROR: ${entry.error}` : "";
|
|
29
|
+
lines.push(`[${ts}] ${entry.action.padEnd(20)} ${JSON.stringify(entry.params)}${errorTag}`);
|
|
30
|
+
}
|
|
31
|
+
return this.ok("Audit log", lines.join("\n"));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/tools/audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAA2B,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,MAAM,OAAO,SAAU,SAAQ,IAAI;IACjC,IAAI,GAAG,OAAO,CAAC;IACf,WAAW,GACT,0DAA0D;QAC1D,+FAA+F,CAAC;IAElG,MAAM,GAAG;QACP,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE;YACtE,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kDAAkD,EAAE;SAC/F;KACF,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,GAAgB,EAAE,MAA+B;QAC7D,MAAM,MAAM,GAAI,MAAM,CAAC,MAAiB,IAAI,MAAM,CAAC;QACnD,MAAM,SAAS,GAAI,MAAM,CAAC,SAAoB,IAAI,GAAG,CAAC,SAAS,CAAC;QAChE,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;QAEtC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC,EAAE,CAAC,eAAe,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QACrD,CAAC;QAED,MAAM,GAAG,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;QACrC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,wCAAwC,SAAS,IAAI,CAAC,CAAC;QACrF,CAAC;QAED,MAAM,KAAK,GAAG,CAAC,wBAAwB,SAAS,MAAM,GAAG,CAAC,MAAM,aAAa,CAAC,CAAC;QAC/E,KAAK,MAAM,KAAK,IAAI,GAAG,EAAE,CAAC;YACxB,MAAM,EAAE,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACzF,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,QAAQ,EAAE,CAAC,CAAC;QAC9F,CAAC;QAED,OAAO,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,CAAC;CACF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base abstractions for all opendesk JS tools — mirrors Python's tools/base.py.
|
|
3
|
+
*/
|
|
4
|
+
export interface Attachment {
|
|
5
|
+
filename: string;
|
|
6
|
+
mediaType: string;
|
|
7
|
+
content: Buffer;
|
|
8
|
+
}
|
|
9
|
+
export interface ToolResult {
|
|
10
|
+
title: string;
|
|
11
|
+
output: string;
|
|
12
|
+
error: boolean;
|
|
13
|
+
attachments: Attachment[];
|
|
14
|
+
metadata: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
export type PermissionHandler = (tool: string, argument: string, description: string) => Promise<void>;
|
|
17
|
+
export declare class PermissionDeniedError extends Error {
|
|
18
|
+
}
|
|
19
|
+
export interface ToolContext {
|
|
20
|
+
sessionId: string;
|
|
21
|
+
permissionHandler?: PermissionHandler;
|
|
22
|
+
}
|
|
23
|
+
export declare function allowAllContext(sessionId?: string): ToolContext;
|
|
24
|
+
export declare function checkPermission(ctx: ToolContext, tool: string, argument: string, description: string): Promise<void>;
|
|
25
|
+
export declare abstract class Tool {
|
|
26
|
+
abstract name: string;
|
|
27
|
+
abstract description: string;
|
|
28
|
+
abstract schema: Record<string, unknown>;
|
|
29
|
+
abstract execute(ctx: ToolContext, params: Record<string, unknown>): Promise<ToolResult>;
|
|
30
|
+
ok(title: string, output: string, attachments?: Attachment[], metadata?: Record<string, unknown>): ToolResult;
|
|
31
|
+
err(title: string, output: string): ToolResult;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/tools/base.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEvG,qBAAa,qBAAsB,SAAQ,KAAK;CAAG;AAEnD,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED,wBAAgB,eAAe,CAAC,SAAS,SAAY,GAAG,WAAW,CAElE;AAED,wBAAsB,eAAe,CACnC,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED,8BAAsB,IAAI;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;IAExF,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAE,UAAU,EAAO,EAAE,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,UAAU;IAIrH,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU;CAG/C"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base abstractions for all opendesk JS tools — mirrors Python's tools/base.py.
|
|
3
|
+
*/
|
|
4
|
+
export class PermissionDeniedError extends Error {
|
|
5
|
+
}
|
|
6
|
+
export function allowAllContext(sessionId = "default") {
|
|
7
|
+
return { sessionId };
|
|
8
|
+
}
|
|
9
|
+
export async function checkPermission(ctx, tool, argument, description) {
|
|
10
|
+
if (ctx.permissionHandler) {
|
|
11
|
+
await ctx.permissionHandler(tool, argument, description);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class Tool {
|
|
15
|
+
ok(title, output, attachments = [], metadata = {}) {
|
|
16
|
+
return { title, output, error: false, attachments, metadata };
|
|
17
|
+
}
|
|
18
|
+
err(title, output) {
|
|
19
|
+
return { title, output, error: true, attachments: [], metadata: {} };
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/tools/base.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkBH,MAAM,OAAO,qBAAsB,SAAQ,KAAK;CAAG;AAOnD,MAAM,UAAU,eAAe,CAAC,SAAS,GAAG,SAAS;IACnD,OAAO,EAAE,SAAS,EAAE,CAAC;AACvB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAgB,EAChB,IAAY,EACZ,QAAgB,EAChB,WAAmB;IAEnB,IAAI,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAC1B,MAAM,GAAG,CAAC,iBAAiB,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC;AAED,MAAM,OAAgB,IAAI;IAMxB,EAAE,CAAC,KAAa,EAAE,MAAc,EAAE,cAA4B,EAAE,EAAE,WAAoC,EAAE;QACtG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;IAChE,CAAC;IAED,GAAG,CAAC,KAAa,EAAE,MAAc;QAC/B,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IACvE,CAAC;CACF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Tool, ToolContext, ToolResult } from "./base.js";
|
|
2
|
+
export declare class ClipboardTool extends Tool {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
schema: {
|
|
6
|
+
type: string;
|
|
7
|
+
required: string[];
|
|
8
|
+
properties: {
|
|
9
|
+
action: {
|
|
10
|
+
type: string;
|
|
11
|
+
enum: string[];
|
|
12
|
+
};
|
|
13
|
+
text: {
|
|
14
|
+
type: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
execute(ctx: ToolContext, params: Record<string, unknown>): Promise<ToolResult>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=clipboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clipboard.d.ts","sourceRoot":"","sources":["../../src/tools/clipboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAmB,MAAM,WAAW,CAAC;AAG3E,qBAAa,aAAc,SAAQ,IAAI;IACrC,IAAI,SAAe;IACnB,WAAW,SAAyC;IAEpD,MAAM;;;;;;;;;;;;;MAOJ;IAEI,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;CAuBtF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Tool, checkPermission } from "./base.js";
|
|
2
|
+
import { getSandbox } from "../computer/sandbox.js";
|
|
3
|
+
export class ClipboardTool extends Tool {
|
|
4
|
+
name = "clipboard";
|
|
5
|
+
description = "Read or write the system clipboard.";
|
|
6
|
+
schema = {
|
|
7
|
+
type: "object",
|
|
8
|
+
required: ["action"],
|
|
9
|
+
properties: {
|
|
10
|
+
action: { type: "string", enum: ["read", "write"] },
|
|
11
|
+
text: { type: "string", description: "Text to write — required for action=write" },
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
async execute(ctx, params) {
|
|
15
|
+
const { action, text } = params;
|
|
16
|
+
await checkPermission(ctx, "clipboard", action, `Clipboard ${action}`);
|
|
17
|
+
try {
|
|
18
|
+
const clipboard = await import("clipboardy");
|
|
19
|
+
const sandbox = getSandbox(ctx.sessionId);
|
|
20
|
+
if (action === "read") {
|
|
21
|
+
const content = await clipboard.default.read();
|
|
22
|
+
sandbox.recordAction("clipboard_read", params, `${content.length} chars`);
|
|
23
|
+
return this.ok("Clipboard read", content);
|
|
24
|
+
}
|
|
25
|
+
else if (action === "write") {
|
|
26
|
+
if (!text)
|
|
27
|
+
return this.err("Clipboard error", "text is required for action=write");
|
|
28
|
+
await clipboard.default.write(text);
|
|
29
|
+
sandbox.recordAction("clipboard_write", params, "ok");
|
|
30
|
+
return this.ok("Clipboard write", `Written ${text.length} chars to clipboard.`);
|
|
31
|
+
}
|
|
32
|
+
return this.err("Clipboard error", `Unknown action: ${action}`);
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
return this.err("Clipboard error", `${e}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=clipboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clipboard.js","sourceRoot":"","sources":["../../src/tools/clipboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAA2B,eAAe,EAAE,MAAM,WAAW,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,MAAM,OAAO,aAAc,SAAQ,IAAI;IACrC,IAAI,GAAG,WAAW,CAAC;IACnB,WAAW,GAAG,qCAAqC,CAAC;IAEpD,MAAM,GAAG;QACP,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,CAAC,QAAQ,CAAC;QACpB,UAAU,EAAE;YACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;YACnD,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,2CAA2C,EAAE;SACnF;KACF,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,GAAgB,EAAE,MAA+B;QAC7D,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAA2C,CAAC;QACrE,MAAM,eAAe,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,MAAM,EAAE,CAAC,CAAC;QAEvE,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;YAC7C,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAE1C,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBACtB,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;gBAC/C,OAAO,CAAC,YAAY,CAAC,gBAAgB,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,QAAQ,CAAC,CAAC;gBAC1E,OAAO,IAAI,CAAC,EAAE,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;YAC5C,CAAC;iBAAM,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;gBAC9B,IAAI,CAAC,IAAI;oBAAE,OAAO,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,mCAAmC,CAAC,CAAC;gBACnF,MAAM,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACpC,OAAO,CAAC,YAAY,CAAC,iBAAiB,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;gBACtD,OAAO,IAAI,CAAC,EAAE,CAAC,iBAAiB,EAAE,WAAW,IAAI,CAAC,MAAM,sBAAsB,CAAC,CAAC;YAClF,CAAC;YACD,OAAO,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,mBAAmB,MAAM,EAAE,CAAC,CAAC;QAClE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Tool, ToolContext, ToolResult } from "./base.js";
|
|
2
|
+
export declare class KeyboardTool extends Tool {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
schema: {
|
|
6
|
+
type: string;
|
|
7
|
+
required: string[];
|
|
8
|
+
properties: {
|
|
9
|
+
action: {
|
|
10
|
+
type: string;
|
|
11
|
+
enum: string[];
|
|
12
|
+
};
|
|
13
|
+
text: {
|
|
14
|
+
type: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
key: {
|
|
18
|
+
type: string;
|
|
19
|
+
description: string;
|
|
20
|
+
};
|
|
21
|
+
keys: {
|
|
22
|
+
type: string;
|
|
23
|
+
items: {
|
|
24
|
+
type: string;
|
|
25
|
+
};
|
|
26
|
+
description: string;
|
|
27
|
+
};
|
|
28
|
+
holdDuration: {
|
|
29
|
+
type: string;
|
|
30
|
+
default: number;
|
|
31
|
+
description: string;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
execute(ctx: ToolContext, params: Record<string, unknown>): Promise<ToolResult>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=keyboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyboard.d.ts","sourceRoot":"","sources":["../../src/tools/keyboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAmB,MAAM,WAAW,CAAC;AAG3E,qBAAa,YAAa,SAAQ,IAAI;IACpC,IAAI,SAAc;IAClB,WAAW,SAAqF;IAEhG,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAUJ;IAEI,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;CA8CtF"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Tool, checkPermission } from "./base.js";
|
|
2
|
+
import { getSandbox } from "../computer/sandbox.js";
|
|
3
|
+
export class KeyboardTool extends Tool {
|
|
4
|
+
name = "keyboard";
|
|
5
|
+
description = "Simulate keyboard input — type text, press a key, send a hotkey, or hold a key.";
|
|
6
|
+
schema = {
|
|
7
|
+
type: "object",
|
|
8
|
+
required: ["action"],
|
|
9
|
+
properties: {
|
|
10
|
+
action: { type: "string", enum: ["type", "press", "hotkey", "hold"] },
|
|
11
|
+
text: { type: "string", description: "Text to type — for action=type" },
|
|
12
|
+
key: { type: "string", description: "Key name — for action=press or hold" },
|
|
13
|
+
keys: { type: "array", items: { type: "string" }, description: "Key combination — for action=hotkey" },
|
|
14
|
+
holdDuration: { type: "number", default: 1, description: "Seconds to hold — for action=hold" },
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
async execute(ctx, params) {
|
|
18
|
+
const { action, text, key, keys, holdDuration = 1 } = params;
|
|
19
|
+
await checkPermission(ctx, "keyboard", action, `Keyboard ${action}`);
|
|
20
|
+
try {
|
|
21
|
+
const { keyboard, Key } = await import("@nut-tree-fork/nut-js");
|
|
22
|
+
const resolveKey = (k) => {
|
|
23
|
+
const upper = k.charAt(0).toUpperCase() + k.slice(1).toLowerCase();
|
|
24
|
+
return Key[upper] ?? Key[k.toUpperCase()] ?? k;
|
|
25
|
+
};
|
|
26
|
+
switch (action) {
|
|
27
|
+
case "type":
|
|
28
|
+
if (!text)
|
|
29
|
+
return this.err("Keyboard error", "text is required for action=type");
|
|
30
|
+
await keyboard.type(text);
|
|
31
|
+
break;
|
|
32
|
+
case "press":
|
|
33
|
+
if (!key)
|
|
34
|
+
return this.err("Keyboard error", "key is required for action=press");
|
|
35
|
+
await keyboard.pressKey(resolveKey(key));
|
|
36
|
+
await keyboard.releaseKey(resolveKey(key));
|
|
37
|
+
break;
|
|
38
|
+
case "hotkey":
|
|
39
|
+
if (!keys?.length)
|
|
40
|
+
return this.err("Keyboard error", "keys is required for action=hotkey");
|
|
41
|
+
await keyboard.pressKey(...keys.map(resolveKey));
|
|
42
|
+
await keyboard.releaseKey(...keys.map(resolveKey));
|
|
43
|
+
break;
|
|
44
|
+
case "hold":
|
|
45
|
+
if (!key)
|
|
46
|
+
return this.err("Keyboard error", "key is required for action=hold");
|
|
47
|
+
await keyboard.pressKey(resolveKey(key));
|
|
48
|
+
await new Promise((r) => setTimeout(r, holdDuration * 1000));
|
|
49
|
+
await keyboard.releaseKey(resolveKey(key));
|
|
50
|
+
break;
|
|
51
|
+
default:
|
|
52
|
+
return this.err("Keyboard error", `Unknown action: ${action}`);
|
|
53
|
+
}
|
|
54
|
+
getSandbox(ctx.sessionId).recordAction(`keyboard_${action}`, params, "ok");
|
|
55
|
+
return this.ok(`Keyboard ${action}`, `${action} done.`);
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
return this.err("Keyboard error", `${e}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=keyboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyboard.js","sourceRoot":"","sources":["../../src/tools/keyboard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Tool, ToolContext, ToolResult } from "./base.js";
|
|
2
|
+
export declare class MouseTool extends Tool {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
schema: {
|
|
6
|
+
type: string;
|
|
7
|
+
required: string[];
|
|
8
|
+
properties: {
|
|
9
|
+
action: {
|
|
10
|
+
type: string;
|
|
11
|
+
enum: string[];
|
|
12
|
+
};
|
|
13
|
+
x: {
|
|
14
|
+
type: string;
|
|
15
|
+
};
|
|
16
|
+
y: {
|
|
17
|
+
type: string;
|
|
18
|
+
};
|
|
19
|
+
endX: {
|
|
20
|
+
type: string;
|
|
21
|
+
};
|
|
22
|
+
endY: {
|
|
23
|
+
type: string;
|
|
24
|
+
};
|
|
25
|
+
direction: {
|
|
26
|
+
type: string;
|
|
27
|
+
enum: string[];
|
|
28
|
+
};
|
|
29
|
+
amount: {
|
|
30
|
+
type: string;
|
|
31
|
+
default: number;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
execute(ctx: ToolContext, params: Record<string, unknown>): Promise<ToolResult>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=mouse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mouse.d.ts","sourceRoot":"","sources":["../../src/tools/mouse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAmB,MAAM,WAAW,CAAC;AAG3E,qBAAa,SAAU,SAAQ,IAAI;IACjC,IAAI,SAAW;IACf,WAAW,SAEgF;IAE3F,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAeJ;IAEI,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;CAwDtF"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Tool, checkPermission } from "./base.js";
|
|
2
|
+
import { getSandbox } from "../computer/sandbox.js";
|
|
3
|
+
export class MouseTool extends Tool {
|
|
4
|
+
name = "mouse";
|
|
5
|
+
description = "Control the mouse — click, double-click, right-click, scroll, drag, move. " +
|
|
6
|
+
"Always prefer the ui tool first. Use mouse only for elements with no accessible label.";
|
|
7
|
+
schema = {
|
|
8
|
+
type: "object",
|
|
9
|
+
required: ["action"],
|
|
10
|
+
properties: {
|
|
11
|
+
action: {
|
|
12
|
+
type: "string",
|
|
13
|
+
enum: ["move", "click", "double_click", "right_click", "scroll", "drag", "cursor_position"],
|
|
14
|
+
},
|
|
15
|
+
x: { type: "integer" },
|
|
16
|
+
y: { type: "integer" },
|
|
17
|
+
endX: { type: "integer" },
|
|
18
|
+
endY: { type: "integer" },
|
|
19
|
+
direction: { type: "string", enum: ["up", "down", "left", "right"] },
|
|
20
|
+
amount: { type: "integer", default: 3 },
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
async execute(ctx, params) {
|
|
24
|
+
const { action, x, y, endX, endY, direction, amount = 3 } = params;
|
|
25
|
+
await checkPermission(ctx, "mouse", `${action} at (${x},${y})`, `Mouse ${action}`);
|
|
26
|
+
const sandbox = getSandbox(ctx.sessionId);
|
|
27
|
+
if (x !== undefined && y !== undefined && !sandbox.isCoordinateAllowed(x, y)) {
|
|
28
|
+
return this.err("Mouse denied", "Coordinates outside permitted screen region.");
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const { mouse, straightTo, Point, Button } = await import("@nut-tree-fork/nut-js");
|
|
32
|
+
switch (action) {
|
|
33
|
+
case "move":
|
|
34
|
+
await mouse.move(straightTo(new Point(x, y)));
|
|
35
|
+
break;
|
|
36
|
+
case "click":
|
|
37
|
+
await mouse.move(straightTo(new Point(x, y)));
|
|
38
|
+
await mouse.click(Button.LEFT);
|
|
39
|
+
break;
|
|
40
|
+
case "double_click":
|
|
41
|
+
await mouse.move(straightTo(new Point(x, y)));
|
|
42
|
+
await mouse.doubleClick(Button.LEFT);
|
|
43
|
+
break;
|
|
44
|
+
case "right_click":
|
|
45
|
+
await mouse.move(straightTo(new Point(x, y)));
|
|
46
|
+
await mouse.click(Button.RIGHT);
|
|
47
|
+
break;
|
|
48
|
+
case "scroll":
|
|
49
|
+
if (direction === "down")
|
|
50
|
+
await mouse.scrollDown(amount);
|
|
51
|
+
else if (direction === "up")
|
|
52
|
+
await mouse.scrollUp(amount);
|
|
53
|
+
else if (direction === "left")
|
|
54
|
+
await mouse.scrollLeft(amount);
|
|
55
|
+
else
|
|
56
|
+
await mouse.scrollRight(amount);
|
|
57
|
+
break;
|
|
58
|
+
case "drag":
|
|
59
|
+
await mouse.drag(straightTo(new Point(endX, endY)));
|
|
60
|
+
break;
|
|
61
|
+
case "cursor_position": {
|
|
62
|
+
const pos = await mouse.getPosition();
|
|
63
|
+
sandbox.recordAction("cursor_position", params, `(${pos.x},${pos.y})`);
|
|
64
|
+
return this.ok("Cursor position", `x=${pos.x}, y=${pos.y}`);
|
|
65
|
+
}
|
|
66
|
+
default:
|
|
67
|
+
return this.err("Mouse error", `Unknown action: ${action}`);
|
|
68
|
+
}
|
|
69
|
+
sandbox.recordAction(`mouse_${action}`, params, "ok");
|
|
70
|
+
return this.ok(`Mouse ${action}`, `${action} at (${x ?? ""},${y ?? ""}) done.`);
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
return this.err("Mouse error", `${e}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=mouse.js.map
|