@frontendxlab/opencode-computer-use 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/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 OpenCode Computer Use contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ The persistent JavaScript session adapter is adapted from
24
+ iFurySt/open-codex-computer-use, Copyright (c) 2026 Leo, under the same MIT
25
+ license. See THIRD_PARTY_NOTICES.md.
package/README.md ADDED
@@ -0,0 +1,285 @@
1
+ # OpenCode Computer Use
2
+
3
+ A dual-generation OpenCode plugin that provides a Codex-style Computer Use
4
+ session.
5
+
6
+ Documentation: https://opencode-computer-use.pages.dev/
7
+
8
+ The model does not receive a pile of low-level desktop MCP tools. It receives a
9
+ small persistent JavaScript tool surface, matching the way Codex Computer Use
10
+ works through `cua_repl`:
11
+
12
+ ```json
13
+ {
14
+ "code": "var app = await cua.getApp('TextEdit'); await app.getAXState();"
15
+ }
16
+ ```
17
+
18
+ The session exposes `js` and `js_reset` only. The JavaScript session persists
19
+ between calls, so app bindings and variables survive across model turns. Native
20
+ desktop calls are made by the underlying open-source `open-computer-use` runtime.
21
+
22
+ This project does not copy OpenAI's closed Codex driver or bundled service. It
23
+ uses the MIT-licensed `iFurySt/open-codex-computer-use` runtime and keeps the
24
+ Codex-style session adapter separate from the native OS implementation.
25
+
26
+ ## Why this is different from `computer-use-linux`
27
+
28
+ `computer-use-linux` is an established low-level MCP server. This package does
29
+ not recreate it and does not make it the model-facing interface.
30
+
31
+ The plugin adds the missing Codex-style layer:
32
+
33
+ - one persistent JavaScript session;
34
+ - an asynchronous `cua` API;
35
+ - app bindings through `cua.getApp(...)`;
36
+ - `getAXState()`, `getScreenshot()`, and `getAXStateAndScreenshot()`;
37
+ - semantic element-first actions;
38
+ - `nodeRepl.write(...)` and `nodeRepl.emitImage(...)`;
39
+ - `js_reset` for a clean session;
40
+ - a worker boundary so a timed-out JavaScript loop cannot wedge the MCP server.
41
+
42
+ The native runtime still has OS limitations. The adapter does not pretend that
43
+ a missing accessibility tree, permission, secure desktop, or unsupported window
44
+ operation is available.
45
+
46
+ ## Supported runtime targets
47
+
48
+ The optional `open-computer-use@0.3.5` package ships native runtimes for:
49
+
50
+ - `darwin-arm64`, `darwin-x64`
51
+ - `linux-arm64`, `linux-x64`
52
+ - `win32-arm64`, `win32-x64`
53
+
54
+ The current project has been exercised against the Linux runtime contract. macOS
55
+ and Windows support is provided by the upstream native packages, but live
56
+ permission and desktop validation must still be run on those operating systems.
57
+
58
+ ### Validation status
59
+
60
+ - Linux x64 native discovery, read-only app listing, MCP registration, and the
61
+ persistent JavaScript session have passed local smoke tests.
62
+ - The current Ubuntu/GNOME Wayland session exposed a Chrome pseudo-window whose
63
+ AT-SPI tree had no actionable children. The native Linux runtime accepted
64
+ coordinate and keyboard requests, but those synthetic events did not change
65
+ that window. The adapter reports the native result rather than claiming that
66
+ an unsupported input path worked.
67
+ - macOS and Windows have not been live-tested in this environment. Their
68
+ accessibility, screen-capture, foreground, and OS permission behavior must be
69
+ verified on those operating systems.
70
+
71
+ The Codex-style surface is portable, but the native runtime's desktop
72
+ capabilities remain OS and session dependent.
73
+
74
+ ## Requirements
75
+
76
+ - Node.js 18 or newer.
77
+ - OpenCode 1.18.29 or newer for the hybrid V1 entrypoint.
78
+ - OpenCode2 V2 for the `setup(ctx)` entrypoint.
79
+ - A signed-in graphical desktop session.
80
+ - macOS Accessibility and Screen Recording permissions.
81
+ - Linux AT-SPI and the input/capture services required by the native runtime.
82
+ - Windows UI Automation in the current interactive desktop session.
83
+
84
+ The plugin cannot control a lock screen, login screen, UAC secure desktop, or
85
+ other OS-owned consent surface. It does not bypass permissions.
86
+
87
+ ## Install
88
+
89
+ The published package is `@frontendxlab/opencode-computer-use`. It registers a
90
+ local MCP server named `cua_repl` by default.
91
+
92
+ ```sh
93
+ npm install @frontendxlab/opencode-computer-use
94
+ ```
95
+
96
+ A local checkout can be loaded by replacing the package name with its absolute
97
+ path.
98
+
99
+ ### OpenCode 1
100
+
101
+ `opencode.json` or `opencode.jsonc`:
102
+
103
+ ```json
104
+ {
105
+ "$schema": "https://opencode.ai/config.json",
106
+ "plugin": [
107
+ ["@frontendxlab/opencode-computer-use", { "backend": "auto" }]
108
+ ]
109
+ }
110
+ ```
111
+
112
+ ### OpenCode2 V2
113
+
114
+ `opencode.json` or `opencode.jsonc`:
115
+
116
+ ```json
117
+ {
118
+ "$schema": "https://opencode.ai/config.json",
119
+ "plugins": [
120
+ {
121
+ "package": "@frontendxlab/opencode-computer-use",
122
+ "options": { "backend": "auto" }
123
+ }
124
+ ]
125
+ }
126
+ ```
127
+
128
+ If the OpenCode process cannot find Node through `PATH`, set `OPENCODE_NODE` to
129
+ an absolute Node executable before starting OpenCode. The plugin does not use
130
+ OpenCode's own executable as the MCP runtime, because that executable may be a
131
+ Bun-based OpenCode binary.
132
+
133
+ Do not configure the same package both as an explicit plugin and through
134
+ automatic plugin discovery. That loads the session twice.
135
+
136
+ ## Options
137
+
138
+ | Option | Default | Meaning |
139
+ | --- | --- | --- |
140
+ | `backend` | `auto` | `auto`, `native`, or `custom`. |
141
+ | `command` | none | Required for `custom`; a native MCP executable followed by argv. |
142
+ | `serverName` | `cua_repl` | MCP server name. |
143
+ | `override` | `false` | Replace an existing MCP server with the same name. |
144
+ | `timeoutMs` | `30000` | Default and maximum JavaScript evaluation timeout. |
145
+ | `disabled` | `false` | Register the server disabled. |
146
+ | `maxTextChars` | `200000` | Aggregate text budget for one tool result. |
147
+ | `maxImageBytes` | `2097152` | Aggregate image payload budget for one tool result. |
148
+ | `allowGlobalPointerFallbacks` | `false` | Explicitly allow native global pointer fallback for coordinate clicks and drags. |
149
+
150
+ The proxy reads corresponding `OPENCODE_COMPUTER_USE_*` environment variables
151
+ when launched directly.
152
+
153
+ For a custom native runtime, use a fixed executable and argv. Do not use shell
154
+ syntax:
155
+
156
+ ```json
157
+ {
158
+ "backend": "custom",
159
+ "command": ["/absolute/path/to/open-computer-use", "mcp"]
160
+ }
161
+ ```
162
+
163
+ The custom command must implement the native MCP operations used by `cua`:
164
+ `initialize`, `tools/list`, `tools/call`, and notifications.
165
+
166
+ ## Model workflow
167
+
168
+ The `js` tool accepts:
169
+
170
+ - `code`: required JavaScript source;
171
+ - `timeout_ms`: optional timeout, capped at 300 seconds;
172
+ - `title`: optional short action title.
173
+
174
+ Typical first call:
175
+
176
+ ```js
177
+ var apps = await cua.listApps({ emit: false });
178
+ var app = await cua.getApp(apps[0].id);
179
+ await app.getAXState();
180
+ ```
181
+
182
+ Typical action and verification:
183
+
184
+ ```js
185
+ var save = await app.click(12);
186
+ await app.getAXState();
187
+ ```
188
+
189
+ The `cua` API includes:
190
+
191
+ - `cua.getState(options?)`
192
+ - `cua.listApps(options?)`
193
+ - `cua.getApp(nameOrBundleID)`
194
+ - `app.getAXState(options?)`
195
+ - `app.getScreenshot(options?)`
196
+ - `app.getAXStateAndScreenshot(options?)`
197
+ - `app.click(elementIndexOrPoint, options?)`
198
+ - `app.scroll(elementIndex, direction, pages?)`
199
+ - `app.drag([fromX, fromY], [toX, toY])`
200
+ - `app.typeText(text)`
201
+ - `app.pressKey(key)`
202
+ - `app.setValue(elementIndex, value)`
203
+ - `app.performSecondaryAction(elementIndex, action)`
204
+
205
+ Use `nodeRepl.write(value)` for text output and
206
+ `await nodeRepl.emitImage(bytesOrDataUrl)` for screenshots or other images.
207
+
208
+ ## State and action rules
209
+
210
+ - Call `getAXState()` or `getAXStateAndScreenshot()` before acting on a new
211
+ layout.
212
+ - Element indexes belong to the most recent state. Re-derive them after a
213
+ navigation, dialog, scroll, resize, or rerender.
214
+ - Prefer `app.click(elementIndex)` and semantic actions over coordinates.
215
+ - Use coordinates only when the surface has no useful accessibility data.
216
+ - Batch deterministic actions and the following state read in one `js` call.
217
+ - Do not replay a mutating action after a timeout or transport failure. Observe
218
+ again and make a new decision.
219
+ - `js_reset` discards JavaScript bindings but does not reset native application
220
+ state.
221
+
222
+ ## Safety
223
+
224
+ This is a high-privilege desktop-control surface. The restricted VM is a
225
+ capability guard, not a complete security sandbox. OpenCode permissions and
226
+ operating-system permissions remain the enforcement layer.
227
+
228
+ The model-facing `js` tool is marked conservatively as mutating. Keep
229
+ OpenCode approval prompts enabled for consequential actions such as sending,
230
+ deleting, purchasing, uploading, or changing permissions. Do not expose the
231
+ session to an untrusted model or run it unattended against password managers,
232
+ banking, administrator, or other high-value applications.
233
+
234
+ `allowGlobalPointerFallbacks` is off by default because it can move the real
235
+ pointer and change foreground focus. Enable it only for an explicit desktop
236
+ automation test where that system-level input is intended.
237
+
238
+ The JavaScript session runs in a restricted VM context. `require`, `process`,
239
+ `fetch`, Node built-ins, filesystem access, dynamic imports, code generation,
240
+ dynamic host objects, and arbitrary shell execution are not available through
241
+ the model-facing session. The native
242
+ `run_shell` operation is not part of the Codex-style `cua` API. Do not add an
243
+ arbitrary shell escape to the JavaScript session.
244
+
245
+ ## Documentation WebMCP preview
246
+
247
+ The Cloudflare Pages documentation includes a progressive, read-only WebMCP
248
+ enhancement based on the current `document.modelContext.registerTool()` draft.
249
+ When a supporting browser exposes the API, agents can discover
250
+ `search_docs`, `get_install_config`, and `get_api_reference`. The page remains
251
+ fully usable without WebMCP, and no desktop-control or mutating tool is exposed
252
+ through the documentation site.
253
+
254
+ WebMCP is experimental. It requires a secure context, the `tools` Permissions
255
+ Policy, and a compatible browser or Cloudflare Browser Run lab session.
256
+
257
+ ## Manual checks
258
+
259
+ Before asking an agent to act, run the native runtime's read-only checks:
260
+
261
+ ```bash
262
+ open-computer-use doctor
263
+ open-computer-use list-apps
264
+ ```
265
+
266
+ The first screenshot may trigger a desktop permission dialog. A screenshot,
267
+ accessibility tree, or typed value can contain sensitive data and should stay
268
+ local.
269
+
270
+ ## Development
271
+
272
+ ```bash
273
+ npm install
274
+ npm test
275
+ npm run lint
276
+ ```
277
+
278
+ The adapter tests use a fake native MCP server and never require a real desktop.
279
+ Live desktop validation must be run separately on each supported OS.
280
+
281
+ ## License and attribution
282
+
283
+ This package is MIT licensed. The Codex-style session adapter is adapted from
284
+ `iFurySt/open-codex-computer-use`, also MIT licensed. See
285
+ `THIRD_PARTY_NOTICES.md` for attribution and the native runtime's license.
package/SECURITY.md ADDED
@@ -0,0 +1,36 @@
1
+ # Security Policy
2
+
3
+ This plugin exposes a persistent JavaScript session that can observe and control
4
+ the interactive desktop as the current user. The VM is not a complete security
5
+ sandbox.
6
+
7
+ ## Default protections
8
+
9
+ - The OpenCode host starts the local MCP server.
10
+ - The MCP server starts a fixed native runtime without a shell.
11
+ - The model-facing surface contains only `js` and `js_reset`.
12
+ - The `cua` API has no arbitrary shell operation.
13
+ - JavaScript executes in a restricted VM context inside a worker and timed-out
14
+ evaluations are terminated.
15
+ - `require`, `process`, `fetch`, Node built-ins, filesystem access, dynamic
16
+ imports, code generation, and dynamic host objects are unavailable in the
17
+ model-facing context.
18
+ - Native calls are serialized through the persistent session.
19
+ - Desktop environment variables are allowlisted.
20
+ - Screenshot and text results remain local MCP content.
21
+
22
+ ## Operator responsibilities
23
+
24
+ - Review the native runtime and its source before installation.
25
+ - Grant only the OS permissions required for the target desktop.
26
+ - Keep OpenCode approval prompts enabled for consequential actions.
27
+ - Do not run unattended against banking, password-manager, administrator, or
28
+ other high-value sessions.
29
+ - Treat screenshots, accessibility trees, and typed text as sensitive data.
30
+ - Lock or switch the desktop session when the agent is not needed.
31
+
32
+ ## Reporting a vulnerability
33
+
34
+ Do not include screenshots, accessibility content, credentials, or raw model
35
+ transcripts in a public issue. Report suspected vulnerabilities privately to the
36
+ maintainer with a minimal reproduction and affected version.
@@ -0,0 +1,22 @@
1
+ # Third-party notices
2
+
3
+ ## Open Codex Computer Use
4
+
5
+ The persistent JavaScript session adapter in `lib/repl.mjs`,
6
+ `lib/repl-kernel.mjs`, and `lib/sandbox.mjs` is adapted from:
7
+
8
+ - Project: `iFurySt/open-codex-computer-use`
9
+ - URL: https://github.com/iFurySt/open-codex-computer-use
10
+ - License: MIT
11
+ - Copyright: Copyright (c) 2026 Leo
12
+ - Source revision: `51f3a590e734c374b627c25ca9831a912eb02b14`
13
+
14
+ The native runtime is installed separately as the optional dependency
15
+ `open-computer-use@0.3.5`, which is distributed under the same MIT license.
16
+
17
+ The adapter was changed to resolve the optional runtime package, use a
18
+ minimal desktop environment allowlist, expose the session through the
19
+ OpenCode plugin entrypoint, and run model code in a restricted VM context.
20
+
21
+ The original MIT license text must remain available in the upstream project
22
+ and in the installed `open-computer-use` package.
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { resolveNativeCommand, runServer } from "../lib/repl.mjs";
4
+
5
+ const native = resolveNativeCommand(process.argv.slice(2));
6
+ runServer(native).catch((error) => {
7
+ const message = (error instanceof Error ? error.message : String(error))
8
+ .replace(/\b(token|secret|password|api[_-]?key|authorization)\s*[:=]\s*(?:bearer|basic)?[^\n\r,;]*/giu, "$1=[redacted]")
9
+ .slice(0, 4_000);
10
+ process.stderr.write(`[opencode-computer-use] ${message}\n`);
11
+ process.exitCode = 1;
12
+ });
package/docs/_headers ADDED
@@ -0,0 +1,12 @@
1
+ /*
2
+ X-Content-Type-Options: nosniff
3
+ X-Frame-Options: DENY
4
+ Referrer-Policy: strict-origin-when-cross-origin
5
+ Permissions-Policy: camera=(), microphone=(), geolocation=(), tools=(self)
6
+ Content-Security-Policy: default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; connect-src 'self'; font-src 'self'; upgrade-insecure-requests
7
+
8
+ /index.html
9
+ Cache-Control: public, max-age=0, must-revalidate
10
+
11
+ /webmcp.js
12
+ Cache-Control: public, max-age=31536000, immutable
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
2
+ <rect width="64" height="64" rx="14" fill="#0a0a0a"/>
3
+ <path d="M16 14h32v8H24v8h20v8H24v8h24v8H16z" fill="#60a5fa"/>
4
+ </svg>