@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.
Files changed (64) hide show
  1. package/README.md +176 -0
  2. package/bin/opendesk-mcp.js +14 -0
  3. package/bin/opendesk.js +40 -0
  4. package/dist/client.d.ts +74 -0
  5. package/dist/client.d.ts.map +1 -0
  6. package/dist/client.js +55 -0
  7. package/dist/client.js.map +1 -0
  8. package/dist/computer/sandbox.d.ts +31 -0
  9. package/dist/computer/sandbox.d.ts.map +1 -0
  10. package/dist/computer/sandbox.js +65 -0
  11. package/dist/computer/sandbox.js.map +1 -0
  12. package/dist/index.d.ts +8 -0
  13. package/dist/index.d.ts.map +1 -0
  14. package/dist/index.js +8 -0
  15. package/dist/index.js.map +1 -0
  16. package/dist/install.d.ts +10 -0
  17. package/dist/install.d.ts.map +1 -0
  18. package/dist/install.js +49 -0
  19. package/dist/install.js.map +1 -0
  20. package/dist/mcp.d.ts +18 -0
  21. package/dist/mcp.d.ts.map +1 -0
  22. package/dist/mcp.js +56 -0
  23. package/dist/mcp.js.map +1 -0
  24. package/dist/registry.d.ts +9 -0
  25. package/dist/registry.d.ts.map +1 -0
  26. package/dist/registry.js +41 -0
  27. package/dist/registry.js.map +1 -0
  28. package/dist/tools/app.d.ts +21 -0
  29. package/dist/tools/app.d.ts.map +1 -0
  30. package/dist/tools/app.js +101 -0
  31. package/dist/tools/app.js.map +1 -0
  32. package/dist/tools/audit.d.ts +21 -0
  33. package/dist/tools/audit.d.ts.map +1 -0
  34. package/dist/tools/audit.js +34 -0
  35. package/dist/tools/audit.js.map +1 -0
  36. package/dist/tools/base.d.ts +33 -0
  37. package/dist/tools/base.d.ts.map +1 -0
  38. package/dist/tools/base.js +22 -0
  39. package/dist/tools/base.js.map +1 -0
  40. package/dist/tools/clipboard.d.ts +21 -0
  41. package/dist/tools/clipboard.d.ts.map +1 -0
  42. package/dist/tools/clipboard.js +39 -0
  43. package/dist/tools/clipboard.js.map +1 -0
  44. package/dist/tools/keyboard.d.ts +37 -0
  45. package/dist/tools/keyboard.d.ts.map +1 -0
  46. package/dist/tools/keyboard.js +62 -0
  47. package/dist/tools/keyboard.js.map +1 -0
  48. package/dist/tools/mouse.d.ts +37 -0
  49. package/dist/tools/mouse.d.ts.map +1 -0
  50. package/dist/tools/mouse.js +77 -0
  51. package/dist/tools/mouse.js.map +1 -0
  52. package/dist/tools/ocr.d.ts +19 -0
  53. package/dist/tools/ocr.d.ts.map +1 -0
  54. package/dist/tools/ocr.js +39 -0
  55. package/dist/tools/ocr.js.map +1 -0
  56. package/dist/tools/screenshot.d.ts +28 -0
  57. package/dist/tools/screenshot.d.ts.map +1 -0
  58. package/dist/tools/screenshot.js +41 -0
  59. package/dist/tools/screenshot.js.map +1 -0
  60. package/dist/tools/ui.d.ts +55 -0
  61. package/dist/tools/ui.d.ts.map +1 -0
  62. package/dist/tools/ui.js +173 -0
  63. package/dist/tools/ui.js.map +1 -0
  64. package/package.json +45 -0
package/README.md ADDED
@@ -0,0 +1,176 @@
1
+ # @vitalops/opendesk-sdk — JavaScript/TypeScript SDK
2
+
3
+ Give any JavaScript or TypeScript AI agent eyes and hands on your desktop.
4
+
5
+ No Python required. All desktop automation runs natively in Node.js — screenshot capture, mouse/keyboard control, accessibility APIs, OCR, clipboard, and audit logging.
6
+
7
+ ---
8
+
9
+ ## Requirements
10
+
11
+ - Node.js 18+
12
+
13
+ ---
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ npm install @vitalops/opendesk-sdk
19
+ ```
20
+
21
+ ### Claude Code / Claude Desktop
22
+
23
+ ```bash
24
+ npx opendesk-js install
25
+ ```
26
+
27
+ This registers the native MCP server with Claude Code. The tools (`screenshot`, `mouse`, `keyboard`, `ui`, etc.) are then available in every Claude Code conversation.
28
+
29
+ To remove:
30
+
31
+ ```bash
32
+ npx opendesk-js uninstall
33
+ ```
34
+
35
+ ### Claude Desktop
36
+
37
+ Add to your config file (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
38
+
39
+ ```json
40
+ {
41
+ "mcpServers": {
42
+ "opendesk": {
43
+ "command": "node",
44
+ "args": ["/path/to/node_modules/@vitalops/opendesk-sdk/bin/opendesk-mcp.js"]
45
+ }
46
+ }
47
+ }
48
+ ```
49
+
50
+ ---
51
+
52
+ ## Usage
53
+
54
+ ### Programmatic (agent loop)
55
+
56
+ ```typescript
57
+ import { OpenDeskClient } from "@vitalops/opendesk-sdk";
58
+
59
+ const client = new OpenDeskClient();
60
+
61
+ // Take a screenshot with Set-of-Marks
62
+ const shot = await client.screenshot({ marks: true });
63
+ console.log(shot.output);
64
+
65
+ // Click a button by name — no coordinates needed
66
+ await client.ui({ action: "click", app: "Safari", title: "Go" });
67
+
68
+ // Type text
69
+ await client.keyboard({ action: "type", text: "Hello from JS" });
70
+
71
+ // Open an app
72
+ await client.app({ action: "open", name: "Spotify" });
73
+
74
+ // Read clipboard
75
+ const clip = await client.clipboard({ action: "read" });
76
+ console.log(clip.output);
77
+
78
+ // OCR a region
79
+ const text = await client.ocr({ region: [0, 0, 800, 400] });
80
+
81
+ // Show audit log
82
+ const log = await client.audit({ format: "summary" });
83
+ ```
84
+
85
+ ### With Vercel AI SDK
86
+
87
+ ```typescript
88
+ import { OpenDeskClient } from "@vitalops/opendesk-sdk";
89
+ import { generateText } from "ai";
90
+ import { anthropic } from "@ai-sdk/anthropic";
91
+
92
+ const client = new OpenDeskClient();
93
+
94
+ const shot = await client.screenshot({ marks: true });
95
+ const response = await generateText({
96
+ model: anthropic("claude-opus-4-6"),
97
+ messages: [
98
+ {
99
+ role: "user",
100
+ content: [
101
+ { type: "text", text: "What do you see on screen? Click the most prominent button." },
102
+ { type: "image", image: shot.attachments[0].content },
103
+ ],
104
+ },
105
+ ],
106
+ });
107
+ ```
108
+
109
+ ### Expose as MCP server
110
+
111
+ ```typescript
112
+ import { createMcpServer } from "@vitalops/opendesk-sdk";
113
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
114
+
115
+ const server = createMcpServer();
116
+ const transport = new StdioServerTransport();
117
+ await server.connect(transport);
118
+ ```
119
+
120
+ ### Custom session ID or permission handler
121
+
122
+ ```typescript
123
+ import { OpenDeskClient } from "@vitalops/opendesk-sdk";
124
+
125
+ const client = new OpenDeskClient({
126
+ sessionId: "my-agent-session",
127
+ permissionHandler: async (tool, action, description) => {
128
+ console.log(`Allow ${description}? [y/n]`);
129
+ // return true to allow, false to deny
130
+ return true;
131
+ },
132
+ });
133
+ ```
134
+
135
+ ---
136
+
137
+ ## Tools
138
+
139
+ Full reference: [docs/tools.md](../docs/tools.md)
140
+
141
+ | Tool | Method | Description |
142
+ |------|--------|-------------|
143
+ | `screenshot` | `client.screenshot(params?)` | Capture screen, optional SoM marks |
144
+ | `ui` | `client.ui(params)` | Click/type by element name — no coordinates |
145
+ | `mouse` | `client.mouse(params)` | Pixel-level mouse control |
146
+ | `keyboard` | `client.keyboard(params)` | Type, press keys, hotkeys |
147
+ | `app` | `client.app(params)` | Open, close, focus applications |
148
+ | `clipboard` | `client.clipboard(params)` | Read/write system clipboard |
149
+ | `ocr` | `client.ocr(params?)` | Extract text from screen |
150
+ | `audit` | `client.audit(params?)` | Show session audit log |
151
+
152
+ ---
153
+
154
+ ## How it works
155
+
156
+ ```
157
+ Your JS/TS code
158
+
159
+
160
+ @vitalops/opendesk-sdk (Node.js)
161
+
162
+ ├── screenshot (screenshot-desktop)
163
+ ├── mouse/keyboard (@nut-tree-fork/nut-js)
164
+ ├── ui (osascript / PowerShell UI Automation / xdotool)
165
+ ├── ocr (tesseract.js)
166
+ ├── clipboard (clipboardy)
167
+ └── audit (in-process session log)
168
+ ```
169
+
170
+ All platform-specific automation runs directly in Node.js. No external process is required.
171
+
172
+ ---
173
+
174
+ ## License
175
+
176
+ MIT
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * opendesk native MCP server — run over stdio.
4
+ * Used by Claude Code / Claude Desktop as the MCP command.
5
+ *
6
+ * Registered automatically by: npx opendesk-js install
7
+ */
8
+
9
+ import { runMcpStdio } from "../dist/mcp.js";
10
+
11
+ runMcpStdio().catch((err) => {
12
+ console.error(err);
13
+ process.exit(1);
14
+ });
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * opendesk-js CLI
4
+ *
5
+ * Commands:
6
+ * install [--scope=user|project] — register native MCP server with Claude Code
7
+ * uninstall — remove MCP server from Claude Code
8
+ * mcp — run the native MCP server over stdio
9
+ */
10
+
11
+ import { install, uninstall } from "../dist/install.js";
12
+ import { runMcpStdio } from "../dist/mcp.js";
13
+
14
+ const [, , command, ...rest] = process.argv;
15
+
16
+ switch (command) {
17
+ case "install": {
18
+ const scopeArg = rest.find((a) => a.startsWith("--scope="));
19
+ const scope = scopeArg ? scopeArg.split("=")[1] : "user";
20
+ install(scope);
21
+ break;
22
+ }
23
+ case "uninstall":
24
+ uninstall();
25
+ break;
26
+ case "mcp":
27
+ runMcpStdio().catch((err) => {
28
+ console.error(err);
29
+ process.exit(1);
30
+ });
31
+ break;
32
+ default:
33
+ console.log(`opendesk-js — JavaScript SDK for opendesk
34
+
35
+ Usage:
36
+ opendesk-js install [--scope=user|project] Register native MCP server with Claude Code
37
+ opendesk-js uninstall Remove MCP server from Claude Code
38
+ opendesk-js mcp Run native MCP server over stdio
39
+ `);
40
+ }
@@ -0,0 +1,74 @@
1
+ /**
2
+ * OpenDeskClient — programmatic interface to all native opendesk tools.
3
+ * No Python required. All desktop automation runs in Node.js.
4
+ *
5
+ * Usage:
6
+ *
7
+ * import { OpenDeskClient } from "@opendesk/sdk";
8
+ *
9
+ * const client = new OpenDeskClient();
10
+ * const result = await client.screenshot({ marks: true });
11
+ * console.log(result.output);
12
+ */
13
+ import { ToolRegistry } from "./registry.js";
14
+ import { ToolResult, PermissionHandler } from "./tools/base.js";
15
+ export interface OpenDeskClientOptions {
16
+ sessionId?: string;
17
+ permissionHandler?: PermissionHandler;
18
+ registry?: ToolRegistry;
19
+ }
20
+ export declare class OpenDeskClient {
21
+ private registry;
22
+ private ctx;
23
+ constructor(options?: OpenDeskClientOptions);
24
+ private call;
25
+ screenshot(params?: {
26
+ marks?: boolean;
27
+ savePath?: string;
28
+ region?: number[];
29
+ }): Promise<ToolResult>;
30
+ mouse(params: {
31
+ action: string;
32
+ x?: number;
33
+ y?: number;
34
+ endX?: number;
35
+ endY?: number;
36
+ direction?: string;
37
+ amount?: number;
38
+ }): Promise<ToolResult>;
39
+ keyboard(params: {
40
+ action: string;
41
+ text?: string;
42
+ key?: string;
43
+ keys?: string[];
44
+ holdDuration?: number;
45
+ }): Promise<ToolResult>;
46
+ app(params: {
47
+ action: string;
48
+ name?: string;
49
+ }): Promise<ToolResult>;
50
+ ui(params: {
51
+ action: string;
52
+ app: string;
53
+ title?: string;
54
+ role?: string;
55
+ menu?: string;
56
+ menuItem?: string;
57
+ text?: string;
58
+ key?: string;
59
+ modifiers?: string[];
60
+ }): Promise<ToolResult>;
61
+ clipboard(params: {
62
+ action: string;
63
+ text?: string;
64
+ }): Promise<ToolResult>;
65
+ ocr(params?: {
66
+ region?: number[];
67
+ }): Promise<ToolResult>;
68
+ audit(params?: {
69
+ format?: "summary" | "full";
70
+ sessionId?: string;
71
+ }): Promise<ToolResult>;
72
+ listTools(): string[];
73
+ }
74
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAkB,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAgC,UAAU,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAE9F,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,GAAG,CAAc;gBAEb,OAAO,GAAE,qBAA0B;IAQ/C,OAAO,CAAC,IAAI;IAIZ,UAAU,CAAC,MAAM,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;KAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAIvG,KAAK,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAIjJ,QAAQ,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAI9H,GAAG,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAInE,EAAE,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAIpL,SAAS,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAIzE,GAAG,CAAC,MAAM,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;KAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAI5D,KAAK,CAAC,MAAM,GAAE;QAAE,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAI5F,SAAS,IAAI,MAAM,EAAE;CAGtB"}
package/dist/client.js ADDED
@@ -0,0 +1,55 @@
1
+ /**
2
+ * OpenDeskClient — programmatic interface to all native opendesk tools.
3
+ * No Python required. All desktop automation runs in Node.js.
4
+ *
5
+ * Usage:
6
+ *
7
+ * import { OpenDeskClient } from "@opendesk/sdk";
8
+ *
9
+ * const client = new OpenDeskClient();
10
+ * const result = await client.screenshot({ marks: true });
11
+ * console.log(result.output);
12
+ */
13
+ import { createRegistry } from "./registry.js";
14
+ export class OpenDeskClient {
15
+ registry;
16
+ ctx;
17
+ constructor(options = {}) {
18
+ this.registry = options.registry ?? createRegistry();
19
+ this.ctx = {
20
+ sessionId: options.sessionId ?? "default",
21
+ permissionHandler: options.permissionHandler,
22
+ };
23
+ }
24
+ call(name, params = {}) {
25
+ return this.registry.get(name).execute(this.ctx, params);
26
+ }
27
+ screenshot(params = {}) {
28
+ return this.call("screenshot", params);
29
+ }
30
+ mouse(params) {
31
+ return this.call("mouse", params);
32
+ }
33
+ keyboard(params) {
34
+ return this.call("keyboard", params);
35
+ }
36
+ app(params) {
37
+ return this.call("app", params);
38
+ }
39
+ ui(params) {
40
+ return this.call("ui", params);
41
+ }
42
+ clipboard(params) {
43
+ return this.call("clipboard", params);
44
+ }
45
+ ocr(params = {}) {
46
+ return this.call("ocr", params);
47
+ }
48
+ audit(params = {}) {
49
+ return this.call("audit", params);
50
+ }
51
+ listTools() {
52
+ return this.registry.all().map((t) => t.name);
53
+ }
54
+ }
55
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,cAAc,EAAgB,MAAM,eAAe,CAAC;AAS7D,MAAM,OAAO,cAAc;IACjB,QAAQ,CAAe;IACvB,GAAG,CAAc;IAEzB,YAAY,UAAiC,EAAE;QAC7C,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,cAAc,EAAE,CAAC;QACrD,IAAI,CAAC,GAAG,GAAG;YACT,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,SAAS;YACzC,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;SAC7C,CAAC;IACJ,CAAC;IAEO,IAAI,CAAC,IAAY,EAAE,SAAkC,EAAE;QAC7D,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC3D,CAAC;IAED,UAAU,CAAC,SAAoE,EAAE;QAC/E,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,MAAiC,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,MAAqH;QACzH,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAiC,CAAC,CAAC;IAC/D,CAAC;IAED,QAAQ,CAAC,MAA+F;QACtG,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAiC,CAAC,CAAC;IAClE,CAAC;IAED,GAAG,CAAC,MAAyC;QAC3C,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,MAAiC,CAAC,CAAC;IAC7D,CAAC;IAED,EAAE,CAAC,MAA2J;QAC5J,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAiC,CAAC,CAAC;IAC5D,CAAC;IAED,SAAS,CAAC,MAAyC;QACjD,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAiC,CAAC,CAAC;IACnE,CAAC;IAED,GAAG,CAAC,SAAgC,EAAE;QACpC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,MAAiC,CAAC,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,SAA8D,EAAE;QACpE,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAiC,CAAC,CAAC;IAC/D,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAChD,CAAC;CACF"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Per-session audit sandbox — mirrors Python's computer/sandbox.py.
3
+ */
4
+ export interface AuditEntry {
5
+ id: string;
6
+ timestamp: number;
7
+ action: string;
8
+ params: Record<string, unknown>;
9
+ sessionId: string;
10
+ result?: string;
11
+ error?: string;
12
+ }
13
+ export declare class ComputerSandbox {
14
+ readonly sessionId: string;
15
+ allowedApps: string[];
16
+ screenRegion?: [number, number, number, number];
17
+ lastScreenshot?: Buffer;
18
+ private log;
19
+ constructor(sessionId: string);
20
+ isAppAllowed(appName: string): boolean;
21
+ isCoordinateAllowed(x: number, y: number): boolean;
22
+ recordAction(action: string, params: Record<string, unknown>, result?: string, error?: string): AuditEntry;
23
+ exportAuditLog(): AuditEntry[];
24
+ summary(): string;
25
+ }
26
+ export declare function getSandbox(sessionId: string): ComputerSandbox;
27
+ export declare function configureSandbox(sessionId: string, opts: {
28
+ allowedApps?: string[];
29
+ screenRegion?: [number, number, number, number];
30
+ }): ComputerSandbox;
31
+ //# sourceMappingURL=sandbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/computer/sandbox.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,eAAe;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,EAAE,CAAM;IAC3B,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,GAAG,CAAoB;gBAEnB,SAAS,EAAE,MAAM;IAI7B,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAKtC,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO;IAMlD,YAAY,CACV,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,CAAC,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,MAAM,GACb,UAAU;IAcb,cAAc,IAAI,UAAU,EAAE;IAI9B,OAAO,IAAI,MAAM;CASlB;AAID,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,CAG7D;AAED,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAChF,eAAe,CAKjB"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Per-session audit sandbox — mirrors Python's computer/sandbox.py.
3
+ */
4
+ export class ComputerSandbox {
5
+ sessionId;
6
+ allowedApps = [];
7
+ screenRegion;
8
+ lastScreenshot;
9
+ log = [];
10
+ constructor(sessionId) {
11
+ this.sessionId = sessionId;
12
+ }
13
+ isAppAllowed(appName) {
14
+ if (this.allowedApps.length === 0)
15
+ return true;
16
+ return this.allowedApps.some((a) => appName.toLowerCase().includes(a.toLowerCase()));
17
+ }
18
+ isCoordinateAllowed(x, y) {
19
+ if (!this.screenRegion)
20
+ return true;
21
+ const [rx, ry, rw, rh] = this.screenRegion;
22
+ return x >= rx && x <= rx + rw && y >= ry && y <= ry + rh;
23
+ }
24
+ recordAction(action, params, result, error) {
25
+ const entry = {
26
+ id: crypto.randomUUID(),
27
+ timestamp: Date.now() / 1000,
28
+ action,
29
+ params,
30
+ sessionId: this.sessionId,
31
+ result,
32
+ error,
33
+ };
34
+ this.log.push(entry);
35
+ return entry;
36
+ }
37
+ exportAuditLog() {
38
+ return [...this.log];
39
+ }
40
+ summary() {
41
+ const counts = {};
42
+ for (const e of this.log)
43
+ counts[e.action] = (counts[e.action] ?? 0) + 1;
44
+ const parts = Object.entries(counts)
45
+ .sort()
46
+ .map(([k, v]) => `${v}x ${k}`)
47
+ .join(", ");
48
+ return `session=${this.sessionId.slice(0, 12)}… | ${this.log.length} actions: ${parts || "none"}`;
49
+ }
50
+ }
51
+ const sandboxes = new Map();
52
+ export function getSandbox(sessionId) {
53
+ if (!sandboxes.has(sessionId))
54
+ sandboxes.set(sessionId, new ComputerSandbox(sessionId));
55
+ return sandboxes.get(sessionId);
56
+ }
57
+ export function configureSandbox(sessionId, opts) {
58
+ const sandbox = getSandbox(sessionId);
59
+ if (opts.allowedApps)
60
+ sandbox.allowedApps = opts.allowedApps;
61
+ if (opts.screenRegion)
62
+ sandbox.screenRegion = opts.screenRegion;
63
+ return sandbox;
64
+ }
65
+ //# sourceMappingURL=sandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/computer/sandbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @opendesk/sdk — public API surface
3
+ */
4
+ export { OpenDeskClient, type OpenDeskClientOptions } from "./client.js";
5
+ export { createMcpServer, runMcpStdio } from "./mcp.js";
6
+ export { ToolRegistry, createRegistry } from "./registry.js";
7
+ export { Tool, type ToolResult, type ToolContext, type PermissionHandler, type Attachment, allowAllContext, checkPermission, PermissionDeniedError, } from "./tools/base.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EACL,IAAI,EACJ,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,eAAe,EACf,eAAe,EACf,qBAAqB,GACtB,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @opendesk/sdk — public API surface
3
+ */
4
+ export { OpenDeskClient } from "./client.js";
5
+ export { createMcpServer, runMcpStdio } from "./mcp.js";
6
+ export { ToolRegistry, createRegistry } from "./registry.js";
7
+ export { Tool, allowAllContext, checkPermission, PermissionDeniedError, } from "./tools/base.js";
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAA8B,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EACL,IAAI,EAKJ,eAAe,EACf,eAAe,EACf,qBAAqB,GACtB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * CLI install/uninstall commands — register the JS MCP bridge with Claude Code.
3
+ *
4
+ * Usage:
5
+ * npx opendesk-js install
6
+ * npx opendesk-js uninstall
7
+ */
8
+ export declare function install(scope?: "user" | "project"): void;
9
+ export declare function uninstall(): void;
10
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAyBH,wBAAgB,OAAO,CAAC,KAAK,GAAE,MAAM,GAAG,SAAkB,GAAG,IAAI,CAoBhE;AAED,wBAAgB,SAAS,IAAI,IAAI,CAIhC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * CLI install/uninstall commands — register the JS MCP bridge with Claude Code.
3
+ *
4
+ * Usage:
5
+ * npx opendesk-js install
6
+ * npx opendesk-js uninstall
7
+ */
8
+ import { execFileSync, execSync } from "node:child_process";
9
+ import { fileURLToPath } from "node:url";
10
+ import path from "node:path";
11
+ function findClaude() {
12
+ try {
13
+ const cmd = process.platform === "win32" ? "where claude" : "which claude";
14
+ const result = execSync(cmd, { encoding: "utf-8" }).trim().split("\n")[0].replace(/\r/g, "");
15
+ if (result)
16
+ return result;
17
+ }
18
+ catch {
19
+ // fall through
20
+ }
21
+ throw new Error("claude command not found.\n" +
22
+ "Install Claude Code first: https://claude.ai/code");
23
+ }
24
+ function findMcpBin() {
25
+ const thisFile = fileURLToPath(import.meta.url);
26
+ const pkgRoot = path.resolve(path.dirname(thisFile), "..");
27
+ return path.join(pkgRoot, "bin", "opendesk-mcp.js");
28
+ }
29
+ export function install(scope = "user") {
30
+ const claude = findClaude();
31
+ const mcpBin = findMcpBin();
32
+ // Remove existing entry if any
33
+ try {
34
+ execFileSync(claude, ["mcp", "remove", "opendesk-js"], { stdio: "pipe" });
35
+ }
36
+ catch {
37
+ // Not registered yet — fine
38
+ }
39
+ execFileSync(claude, ["mcp", "add", "opendesk-js", `--scope=${scope}`, "--", "node", mcpBin], { stdio: "inherit", shell: process.platform === "win32" });
40
+ console.log(`opendesk JS MCP server registered (${scope}).`);
41
+ console.log(` Server: ${mcpBin}`);
42
+ console.log("Start a Claude Code conversation and say 'take a screenshot' to verify.");
43
+ }
44
+ export function uninstall() {
45
+ const claude = findClaude();
46
+ execFileSync(claude, ["mcp", "remove", "opendesk-js"], { stdio: "inherit", shell: process.platform === "win32" });
47
+ console.log("opendesk JS MCP server removed from Claude Code.");
48
+ }
49
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC;QAC3E,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC7F,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,eAAe;IACjB,CAAC;IACD,MAAM,IAAI,KAAK,CACb,6BAA6B;QAC7B,mDAAmD,CACpD,CAAC;AACJ,CAAC;AACD,SAAS,UAAU;IACjB,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3D,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,QAA4B,MAAM;IACxD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,+BAA+B;IAC/B,IAAI,CAAC;QACH,YAAY,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,aAAa,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAC5E,CAAC;IAAC,MAAM,CAAC;QACP,4BAA4B;IAC9B,CAAC;IAED,YAAY,CACV,MAAM,EACN,CAAC,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EACvE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAC1D,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,sCAAsC,KAAK,IAAI,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,aAAa,MAAM,EAAE,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,yEAAyE,CAAC,CAAC;AACzF,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,YAAY,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,aAAa,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC,CAAC;IAClH,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;AAClE,CAAC"}
package/dist/mcp.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Standalone MCP server — exposes all native opendesk tools over the
3
+ * Model Context Protocol. No Python required.
4
+ *
5
+ * Usage:
6
+ * npx opendesk-js mcp — run over stdio (for Claude Code / Claude Desktop)
7
+ *
8
+ * Or programmatically:
9
+ * import { createMcpServer, runMcpStdio } from "@opendesk/sdk";
10
+ * const server = createMcpServer();
11
+ * // connect your own transport
12
+ */
13
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
14
+ import { ToolRegistry } from "./registry.js";
15
+ import { ToolContext } from "./tools/base.js";
16
+ export declare function createMcpServer(registry?: ToolRegistry, ctx?: ToolContext): Server;
17
+ export declare function runMcpStdio(registry?: ToolRegistry, ctx?: ToolContext): Promise<void>;
18
+ //# sourceMappingURL=mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAGnE,OAAO,EAAkB,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAmB,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE/D,wBAAgB,eAAe,CAAC,QAAQ,CAAC,EAAE,YAAY,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,MAAM,CA0ClF;AAED,wBAAsB,WAAW,CAAC,QAAQ,CAAC,EAAE,YAAY,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAI3F"}
package/dist/mcp.js ADDED
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Standalone MCP server — exposes all native opendesk tools over the
3
+ * Model Context Protocol. No Python required.
4
+ *
5
+ * Usage:
6
+ * npx opendesk-js mcp — run over stdio (for Claude Code / Claude Desktop)
7
+ *
8
+ * Or programmatically:
9
+ * import { createMcpServer, runMcpStdio } from "@opendesk/sdk";
10
+ * const server = createMcpServer();
11
+ * // connect your own transport
12
+ */
13
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
14
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
15
+ import { ListToolsRequestSchema, CallToolRequestSchema } from "@modelcontextprotocol/sdk/types.js";
16
+ import { createRegistry } from "./registry.js";
17
+ import { allowAllContext } from "./tools/base.js";
18
+ export function createMcpServer(registry, ctx) {
19
+ const reg = registry ?? createRegistry();
20
+ const context = ctx ?? allowAllContext();
21
+ const server = new Server({ name: "opendesk", version: "0.1.0" }, { capabilities: { tools: {} } });
22
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
23
+ tools: reg.all().map((t) => ({
24
+ name: t.name,
25
+ description: t.description,
26
+ inputSchema: t.schema,
27
+ })),
28
+ }));
29
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
30
+ const { name, arguments: args = {} } = request.params;
31
+ const tool = reg.get(name);
32
+ const result = await tool.execute(context, args);
33
+ const contents = [];
34
+ if (result.output) {
35
+ contents.push({ type: "text", text: result.output });
36
+ }
37
+ for (const att of result.attachments) {
38
+ if (att.mediaType.startsWith("image/")) {
39
+ contents.push({ type: "image", data: att.content.toString("base64"), mimeType: att.mediaType });
40
+ }
41
+ else {
42
+ contents.push({ type: "text", text: `[Attachment: ${att.filename}]\ndata:${att.mediaType};base64,${att.content.toString("base64")}` });
43
+ }
44
+ }
45
+ if (!contents.length)
46
+ contents.push({ type: "text", text: "(no output)" });
47
+ return { content: contents };
48
+ });
49
+ return server;
50
+ }
51
+ export async function runMcpStdio(registry, ctx) {
52
+ const server = createMcpServer(registry, ctx);
53
+ const transport = new StdioServerTransport();
54
+ await server.connect(transport);
55
+ }
56
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}