@frontendxlab/opencode-computer-use 0.1.4 → 0.1.5
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/CHANGELOG.md +52 -0
- package/README.md +162 -35
- package/SECURITY.md +6 -2
- package/THIRD_PARTY_NOTICES.md +4 -0
- package/bin/opencode-computer-use-permissions.js +134 -21
- package/bin/opencode-computer-use-repl.js +25 -3
- package/bin/opencode-computer-use-setup.js +113 -95
- package/docs/NATIVE_VALIDATION.md +102 -0
- package/docs/index.html +577 -42
- package/docs/llms-full.txt +146 -35
- package/docs/llms.txt +8 -2
- package/docs/sitemap.xml +1 -1
- package/docs/webmcp.js +2 -2
- package/lib/backend.js +50 -14
- package/lib/json-line-peer.mjs +3 -0
- package/lib/sandbox.mjs +51 -4
- package/package.json +7 -5
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.5 — 2026-10-30
|
|
4
|
+
|
|
5
|
+
### Setup and discovery
|
|
6
|
+
|
|
7
|
+
- Register a development checkout with `opencode-computer-use-setup --source .`.
|
|
8
|
+
- Use backed-up JSON/JSONC edits for both global and local setup instead of
|
|
9
|
+
assuming a particular OpenCode plugin-management subcommand.
|
|
10
|
+
- Reject invalid JSONC and conflicting V1/V2 configurations before writing.
|
|
11
|
+
- Preserve pinned npm entries, avoid duplicate registration across configuration
|
|
12
|
+
files, retain options when switching to a checkout, and preserve backups on
|
|
13
|
+
unchanged runs.
|
|
14
|
+
- Return failure for unsuccessful manual setup while keeping dependency
|
|
15
|
+
postinstall best-effort.
|
|
16
|
+
- Recognize Windows executable/environment-name conventions and resolve npm
|
|
17
|
+
native-runtime shims without invoking a shell for desktop control.
|
|
18
|
+
- Include guided desktop prerequisite onboarding when lifecycle scripts run.
|
|
19
|
+
|
|
20
|
+
### Runtime fixes
|
|
21
|
+
|
|
22
|
+
- Enforce an empty deny-by-default app policy before native app binding.
|
|
23
|
+
- Emit filtered `getState()` and `listApps()` inventories by default and honor
|
|
24
|
+
`emit: false` without exposing denied apps.
|
|
25
|
+
- Handle native stdio failures as controlled transport errors and clean up the
|
|
26
|
+
owned child process.
|
|
27
|
+
- Parse executable import syntax instead of rejecting the word `import` inside
|
|
28
|
+
typed text, strings, comments, regexes, and ordinary property names. Executable
|
|
29
|
+
imports and the existing VM restrictions remain blocked.
|
|
30
|
+
- Make REPL `--help` exit without starting native automation, and report startup
|
|
31
|
+
configuration failures without an uncaught stack trace.
|
|
32
|
+
|
|
33
|
+
### Verification and documentation
|
|
34
|
+
|
|
35
|
+
- Add regressions for the setup, policy, inventory, transport, import, and CLI
|
|
36
|
+
failures above.
|
|
37
|
+
- Add an opt-in real OpenCode smoke test with isolated settings and fake/native
|
|
38
|
+
startup modes, plus a Linux/macOS/Windows CI integration job pinned to 1.19.3.
|
|
39
|
+
- Document checkout installation, correct scoped npm executable commands,
|
|
40
|
+
registration troubleshooting, per-device installation, and server-host scope.
|
|
41
|
+
- Correct WebMCP API-reference lookups for method names with signatures.
|
|
42
|
+
|
|
43
|
+
### Support boundaries
|
|
44
|
+
|
|
45
|
+
The adapter controls the desktop of the machine running its local MCP process.
|
|
46
|
+
This release does not add remote device pairing, a network transport, or mobile
|
|
47
|
+
native runtimes. Linux x64 registration, read-only discovery, and semantic click
|
|
48
|
+
and text-value actions in a disposable GTK fixture are exercised locally.
|
|
49
|
+
Screenshots were unavailable in the tested GNOME Wayland session. Packaged
|
|
50
|
+
macOS/Windows runtimes still require live desktop validation;
|
|
51
|
+
headless adapter or CLI tests do not certify screenshot/input behavior. Wayland
|
|
52
|
+
capture and synthetic input remain dependent on the compositor and target app.
|
package/README.md
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
A dual-generation OpenCode plugin that provides a Codex-style Computer Use
|
|
4
4
|
session.
|
|
5
5
|
|
|
6
|
+
It registers a local MCP server named `cua_repl` with two tools, `js` and
|
|
7
|
+
`js_reset`. It does not add a slash command or a dedicated OpenCode panel.
|
|
8
|
+
|
|
6
9
|
Documentation: https://opencode-computer-use.pages.dev/
|
|
7
10
|
|
|
8
11
|
The model does not receive a pile of low-level desktop MCP tools. It receives a
|
|
@@ -51,25 +54,34 @@ The optional `open-computer-use@0.3.5` package ships native runtimes for:
|
|
|
51
54
|
- `linux-arm64`, `linux-x64`
|
|
52
55
|
- `win32-arm64`, `win32-x64`
|
|
53
56
|
|
|
54
|
-
The
|
|
55
|
-
and Windows
|
|
56
|
-
|
|
57
|
+
The repository CI is configured to test the adapter headlessly on Linux, macOS,
|
|
58
|
+
and Windows through a GitHub Actions matrix. The native package publishes binaries for the six targets
|
|
59
|
+
above. Live accessibility, capture, focus, and input behavior still depends on
|
|
60
|
+
the host desktop session and must be validated on each operating system.
|
|
57
61
|
|
|
58
62
|
### Validation status
|
|
59
63
|
|
|
60
|
-
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
accessibility
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
64
|
+
- The JavaScript adapter, MCP registration, sandbox, timeout recovery, setup,
|
|
65
|
+
packaging, and fake-native integration suite are designed to run on Linux,
|
|
66
|
+
macOS, and Windows without a graphical desktop.
|
|
67
|
+
- Linux x64 native discovery, app listing, actual OpenCode 1.19.3 registration,
|
|
68
|
+
persistent JavaScript bindings, and session reset passed local smoke tests.
|
|
69
|
+
- On 2026-10-30, a disposable GTK 3 window in Ubuntu/GNOME Wayland exposed an
|
|
70
|
+
actionable accessibility tree. An element-index click changed its counter
|
|
71
|
+
from 0 to 1, and `setValue` changed its text field; both results were checked
|
|
72
|
+
against fresh accessibility state and the test application's own state.
|
|
73
|
+
- Screenshot capture for that window returned `Screenshot unavailable`.
|
|
74
|
+
Keyboard/coordinate input was not certified. Other apps may expose incomplete
|
|
75
|
+
accessibility trees, and Wayland capture/input behavior remains app- and
|
|
76
|
+
compositor-dependent. See the dated record in `docs/NATIVE_VALIDATION.md`.
|
|
77
|
+
- macOS and Windows native desktop behavior has not been live-certified from
|
|
78
|
+
this development machine. Their accessibility, screen-capture, foreground,
|
|
79
|
+
and OS permission behavior must still be verified on real interactive hosts.
|
|
80
|
+
|
|
81
|
+
The Codex-style surface is portable across the published x64/ARM64 desktop
|
|
82
|
+
targets, but native desktop capabilities remain OS, permission, display-server,
|
|
83
|
+
and session dependent. Other CPU/OS combinations fail with an explicit target
|
|
84
|
+
diagnostic and can use a compatible custom backend.
|
|
73
85
|
|
|
74
86
|
## Requirements
|
|
75
87
|
|
|
@@ -81,9 +93,34 @@ capabilities remain OS and session dependent.
|
|
|
81
93
|
- Linux AT-SPI and the input/capture services required by the native runtime.
|
|
82
94
|
- Windows UI Automation in the current interactive desktop session.
|
|
83
95
|
|
|
96
|
+
The V1 integration has been exercised with OpenCode 1.19.3. The V2 entrypoint
|
|
97
|
+
has adapter contract tests; a real OpenCode2 installation remains a separate
|
|
98
|
+
integration check. A native runtime's successful `doctor` exit is a prerequisite
|
|
99
|
+
check, not proof that screenshots, focus, or input work in a particular app.
|
|
100
|
+
|
|
84
101
|
The plugin cannot control a lock screen, login screen, UAC secure desktop, or
|
|
85
102
|
other OS-owned consent surface. It does not bypass permissions.
|
|
86
103
|
|
|
104
|
+
## Which computer is controlled?
|
|
105
|
+
|
|
106
|
+
The controlled desktop belongs to the machine running the OpenCode **server
|
|
107
|
+
and its MCP child process**. There is no built-in device discovery, pairing,
|
|
108
|
+
remote desktop transport, or session synchronization.
|
|
109
|
+
|
|
110
|
+
| Setup | Desktop controlled |
|
|
111
|
+
| --- | --- |
|
|
112
|
+
| OpenCode runs on computer A | Computer A's signed-in graphical session. |
|
|
113
|
+
| A browser or attached OpenCode client on B connects to the server on A | Still computer A. |
|
|
114
|
+
| Install and run OpenCode plus this plugin separately on B | Computer B, after its own runtime and permission checks. |
|
|
115
|
+
| Copy a configuration containing A's absolute paths to B | Paths must be re-created for B; configuration alone does not install the runtime. |
|
|
116
|
+
|
|
117
|
+
Cross-platform support means separate installations on the packaged macOS,
|
|
118
|
+
Linux, and Windows targets. Android and iOS are not native targets. Containers,
|
|
119
|
+
WSL, SSH sessions, and background services do not automatically expose another
|
|
120
|
+
machine's or the host operating system's interactive desktop. A custom backend
|
|
121
|
+
must implement the native protocol; selecting `custom` does not add remote
|
|
122
|
+
device support by itself.
|
|
123
|
+
|
|
87
124
|
## Install
|
|
88
125
|
|
|
89
126
|
The published package is `@frontendxlab/opencode-computer-use`. It registers a
|
|
@@ -102,12 +139,18 @@ When both generations are installed, it uses an existing `plugin` or `plugins`
|
|
|
102
139
|
configuration to disambiguate. If that is not possible, it makes no change and
|
|
103
140
|
prints both manual configuration formats.
|
|
104
141
|
|
|
142
|
+
Both local and global setup use a backed-up JSON/JSONC edit. Setup does not
|
|
143
|
+
depend on a version-specific `opencode plugin add` command. A project install
|
|
144
|
+
affects that project; use `--global` to configure all projects for the current
|
|
145
|
+
user. Package installation and OpenCode registration are separate steps when
|
|
146
|
+
lifecycle scripts are disabled.
|
|
147
|
+
|
|
105
148
|
You can run setup explicitly at any time:
|
|
106
149
|
|
|
107
150
|
```sh
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
151
|
+
npm exec --package=@frontendxlab/opencode-computer-use -- opencode-computer-use-setup --local --v1
|
|
152
|
+
npm exec --package=@frontendxlab/opencode-computer-use -- opencode-computer-use-setup --local --v2
|
|
153
|
+
npm exec --package=@frontendxlab/opencode-computer-use -- opencode-computer-use-setup --global --v1
|
|
111
154
|
```
|
|
112
155
|
|
|
113
156
|
Use `--dry-run` to inspect the action without changing files. Set
|
|
@@ -115,21 +158,30 @@ Use `--dry-run` to inspect the action without changing files. Set
|
|
|
115
158
|
skips automatically when `CI=1` or `CI=true`. Restart OpenCode after a
|
|
116
159
|
successful setup so the plugin is loaded.
|
|
117
160
|
|
|
118
|
-
|
|
161
|
+
Explicit setup returns a nonzero exit status when it fails; automatic dependency
|
|
162
|
+
`postinstall` remains best-effort and prints manual instructions. Check the
|
|
163
|
+
reported configuration path. The shorthand `npx opencode-computer-use-setup`
|
|
164
|
+
only selects this package's executable when it is already installed locally;
|
|
165
|
+
the scoped `npm exec --package=...` form above also works from a fresh directory.
|
|
166
|
+
|
|
167
|
+
Starting with v0.1.5, desktop prerequisite onboarding is part of `postinstall` when lifecycle scripts are allowed.
|
|
168
|
+
After OpenCode configuration, the installer runs `opencode-computer-use-permissions --install`:
|
|
169
|
+
|
|
170
|
+
- macOS runs the native `doctor` check and opens the Open Computer Use onboarding/System Settings when Accessibility or Screen Recording is missing. Apple still requires the user to click the protected privacy toggles.
|
|
171
|
+
- GNOME Linux best-effort enables `org.gnome.desktop.interface toolkit-accessibility` and then runs the native AT-SPI/session check. Other Linux desktops get diagnostics without changing desktop settings.
|
|
172
|
+
- Windows runs the UI Automation/session check. Windows has no separate UI Automation permission toggle; it must run in the signed-in interactive desktop session.
|
|
173
|
+
|
|
174
|
+
Rerun the guided check at any time:
|
|
119
175
|
|
|
120
176
|
```sh
|
|
121
|
-
|
|
177
|
+
npm exec --package=@frontendxlab/opencode-computer-use -- opencode-computer-use-permissions --strict
|
|
122
178
|
# or, from a pnpm project
|
|
123
|
-
pnpm exec opencode-computer-use-permissions
|
|
179
|
+
pnpm exec opencode-computer-use-permissions --strict
|
|
124
180
|
```
|
|
125
181
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
and interactive-session requirements. The command never changes permissions
|
|
130
|
-
automatically. Use `--strict` when a missing or failed native
|
|
131
|
-
check should return a nonzero exit status, or set
|
|
132
|
-
`OPENCODE_COMPUTER_USE_SKIP_PERMISSIONS=1` to skip it.
|
|
182
|
+
Set `OPENCODE_COMPUTER_USE_SKIP_PERMISSIONS=1` to skip install-time desktop onboarding.
|
|
183
|
+
CI and package-development installs skip it automatically. The helper never bypasses macOS TCC,
|
|
184
|
+
Windows secure desktops, or other OS permission boundaries.
|
|
133
185
|
|
|
134
186
|
Recent pnpm releases may require explicit approval before running lifecycle
|
|
135
187
|
scripts from dependencies. If pnpm reports `ERR_PNPM_IGNORED_BUILDS`, approve
|
|
@@ -142,8 +194,30 @@ pnpm install
|
|
|
142
194
|
|
|
143
195
|
If scripts are intentionally disabled, run `pnpm exec opencode-computer-use-setup` manually instead.
|
|
144
196
|
|
|
145
|
-
|
|
146
|
-
|
|
197
|
+
### Run this checkout
|
|
198
|
+
|
|
199
|
+
Cloning this repository does not register it in OpenCode. A development
|
|
200
|
+
`npm install` intentionally skips the automatic configuration and desktop
|
|
201
|
+
onboarding hooks. Run these commands from the checkout:
|
|
202
|
+
|
|
203
|
+
```sh
|
|
204
|
+
npm ci --ignore-scripts
|
|
205
|
+
node bin/opencode-computer-use-setup.js --local --v1 --source .
|
|
206
|
+
node bin/opencode-computer-use-permissions.js --strict
|
|
207
|
+
opencode mcp list
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Close and reopen an already-running OpenCode session. The MCP list should show
|
|
211
|
+
`cua_repl` as connected. To make this checkout available to all projects, replace
|
|
212
|
+
`--local` with `--global`. For OpenCode2, select `--v2` and use that runtime's MCP
|
|
213
|
+
status command. The `--source` flag accepts a directory, an entrypoint file, or
|
|
214
|
+
a file URL and writes the canonical absolute `file://` URL. It requires this
|
|
215
|
+
checkout's updated setup script; an older published package may not have it.
|
|
216
|
+
|
|
217
|
+
The generated local `opencode.json` is machine-specific and ignored by this
|
|
218
|
+
repository. Re-run setup on a second computer rather than copying its absolute
|
|
219
|
+
path. Install dependencies on that computer; do not copy `node_modules` between
|
|
220
|
+
operating systems or CPU architectures.
|
|
147
221
|
|
|
148
222
|
### OpenCode 1
|
|
149
223
|
|
|
@@ -233,6 +307,29 @@ syntax:
|
|
|
233
307
|
The custom command must implement the native MCP operations used by `cua`:
|
|
234
308
|
`initialize`, `tools/list`, `tools/call`, and notifications.
|
|
235
309
|
|
|
310
|
+
If plugin loading is unavailable in your host version, the same REPL can also
|
|
311
|
+
be registered directly as a local MCP server. Use exactly one registration:
|
|
312
|
+
|
|
313
|
+
```json
|
|
314
|
+
{
|
|
315
|
+
"mcp": {
|
|
316
|
+
"cua_repl": {
|
|
317
|
+
"type": "local",
|
|
318
|
+
"command": ["node", "/absolute/path/to/opencode-computer-use/bin/opencode-computer-use-repl.js"],
|
|
319
|
+
"environment": {
|
|
320
|
+
"OPENCODE_COMPUTER_USE_SAFETY_MODE": "read-only"
|
|
321
|
+
},
|
|
322
|
+
"enabled": true
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
This example uses read-only mode for initial validation. Replace the path with
|
|
329
|
+
the actual installed checkout path, and use an absolute Node path if the host
|
|
330
|
+
cannot resolve `node`. Plugin options do not apply to a separately configured
|
|
331
|
+
MCP server; use the matching environment variables in that case.
|
|
332
|
+
|
|
236
333
|
## Model workflow
|
|
237
334
|
|
|
238
335
|
The `js` tool accepts:
|
|
@@ -272,6 +369,10 @@ The `cua` API includes:
|
|
|
272
369
|
- `app.setValue(elementIndex, value)`
|
|
273
370
|
- `app.performSecondaryAction(elementIndex, action)`
|
|
274
371
|
|
|
372
|
+
`cua.getState()` and `cua.listApps()` emit the permitted app inventory by default.
|
|
373
|
+
Use `{ emit: false }` when assigning it to a variable and writing your own output.
|
|
374
|
+
Both the returned inventory and its visible output honor `appAccess` rules.
|
|
375
|
+
|
|
275
376
|
Use `nodeRepl.write(value)` for text output and
|
|
276
377
|
`await nodeRepl.emitImage(bytesOrDataUrl)` for screenshots or other images.
|
|
277
378
|
|
|
@@ -334,24 +435,50 @@ Policy, and a compatible browser or Cloudflare Browser Run lab session.
|
|
|
334
435
|
Before asking an agent to act, run the native runtime's read-only checks:
|
|
335
436
|
|
|
336
437
|
```bash
|
|
337
|
-
open-computer-use doctor
|
|
338
|
-
open-computer-use list-apps
|
|
438
|
+
npm exec --package=open-computer-use@0.3.5 -- open-computer-use doctor
|
|
439
|
+
npm exec --package=open-computer-use@0.3.5 -- open-computer-use list-apps
|
|
339
440
|
```
|
|
340
441
|
|
|
341
442
|
The first screenshot may trigger a desktop permission dialog. A screenshot,
|
|
342
443
|
accessibility tree, or typed value can contain sensitive data and should stay
|
|
343
444
|
local.
|
|
344
445
|
|
|
446
|
+
## Troubleshooting registration and desktop access
|
|
447
|
+
|
|
448
|
+
| Symptom | Check and remedy |
|
|
449
|
+
| --- | --- |
|
|
450
|
+
| No `cua_repl` in OpenCode | Run setup for the right project/global scope and generation, check its printed config path, then restart OpenCode and run `opencode mcp list`. A clone or dependency install by itself is not registration. |
|
|
451
|
+
| Installed from npm but new fixes are missing | Compare `npm view @frontendxlab/opencode-computer-use version` with the checkout's `package.json`. Use `--source .` to test the checkout before publication. |
|
|
452
|
+
| `--pure` / `OPENCODE_PURE` is enabled | OpenCode deliberately skips external plugins. Start it with plugins enabled. |
|
|
453
|
+
| An existing `cua_repl` entry is disabled or points elsewhere | The plugin preserves that entry by default. Correct it, or explicitly use the plugin's `override: true` option after reviewing the replacement. |
|
|
454
|
+
| `node` cannot be found | Set `OPENCODE_NODE` to the absolute Node executable in the environment that starts OpenCode. A desktop launcher may have a different `PATH` from a terminal. |
|
|
455
|
+
| Native runtime unavailable | Install the optional `open-computer-use@0.3.5` dependency; check whether the package manager omitted optional packages. Run the permissions helper from the same graphical session. |
|
|
456
|
+
| `cua_repl` connects but the app list is empty | Verify the signed-in desktop/session and accessibility prerequisites. An MCP handshake does not prove native app access. |
|
|
457
|
+
| Linux actions return but the app does not change | Refresh accessibility state and verify the result. Wayland may block synthetic input or capture; prefer semantic AT-SPI actions when the app exposes them. |
|
|
458
|
+
| Works on one computer but not another | Install on each supported desktop and re-run its permission/session checks. Absolute paths, environment, architecture, and app accessibility differ. |
|
|
459
|
+
|
|
460
|
+
For Windows npm command shims, the backend resolves the adjacent packaged native
|
|
461
|
+
`.exe` without invoking a shell. A nonstandard `.cmd`/`.bat` installation without
|
|
462
|
+
that executable must use an absolute native `OPEN_COMPUTER_USE_NATIVE_COMMAND`.
|
|
463
|
+
|
|
345
464
|
## Development
|
|
346
465
|
|
|
347
466
|
```bash
|
|
348
|
-
npm
|
|
467
|
+
npm ci --ignore-scripts
|
|
349
468
|
npm test
|
|
350
469
|
npm run lint
|
|
470
|
+
npm run test:opencode
|
|
351
471
|
```
|
|
352
472
|
|
|
353
473
|
The adapter tests use a fake native MCP server and never require a real desktop.
|
|
354
|
-
|
|
474
|
+
The repository CI is configured to run them on Linux, macOS, and Windows across
|
|
475
|
+
the declared Node compatibility matrix. `test:opencode` additionally requires an
|
|
476
|
+
installed OpenCode CLI and checks actual plugin registration/MCP startup in an
|
|
477
|
+
isolated configuration with a fake native backend. Use `npm run test:opencode --
|
|
478
|
+
--native` on an interactive host to check registration with its native backend.
|
|
479
|
+
Neither smoke test sends desktop input. Live desktop validation remains a separate release check for native input,
|
|
480
|
+
capture, focus, and accessibility behavior.
|
|
481
|
+
Use `docs/NATIVE_VALIDATION.md` for the per-OS certification checklist.
|
|
355
482
|
|
|
356
483
|
## License and attribution
|
|
357
484
|
|
package/SECURITY.md
CHANGED
|
@@ -28,8 +28,12 @@ sandbox.
|
|
|
28
28
|
conflicting or malformed configuration. Ambiguous setup is non-destructive
|
|
29
29
|
and prints manual instructions. CI and explicit skip environments bypass
|
|
30
30
|
postinstall mutation.
|
|
31
|
-
-
|
|
32
|
-
|
|
31
|
+
- Install-time permission onboarding is guided and best-effort. The postinstall
|
|
32
|
+
hook delegates to the native runtime's `doctor` flow. On macOS it may open
|
|
33
|
+
Accessibility/Screen Recording onboarding, but the protected TCC toggles still
|
|
34
|
+
require user approval. On GNOME Linux it may enable toolkit accessibility.
|
|
35
|
+
Windows only validates UI Automation/session requirements. The installer never
|
|
36
|
+
bypasses OS permission boundaries or grants protected permissions silently.
|
|
33
37
|
|
|
34
38
|
## Operator responsibilities
|
|
35
39
|
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -18,6 +18,10 @@ The automatic setup command uses `jsonc-parser@3.3.1`, copyright Microsoft
|
|
|
18
18
|
Corporation and contributors, under the MIT license. It is used only to make
|
|
19
19
|
targeted edits to OpenCode JSONC configuration files.
|
|
20
20
|
|
|
21
|
+
The import-syntax guard uses `acorn@8.19.0` under the MIT license to parse
|
|
22
|
+
JavaScript without executing it. Acorn's license is included in its separately
|
|
23
|
+
installed dependency package.
|
|
24
|
+
|
|
21
25
|
The adapter was changed to resolve the optional runtime package, use a
|
|
22
26
|
minimal desktop environment allowlist, expose the session through the
|
|
23
27
|
OpenCode plugin entrypoint, and run model code in a restricted VM context.
|
|
@@ -11,35 +11,84 @@ const SKIP_ENV = "OPENCODE_COMPUTER_USE_SKIP_PERMISSIONS";
|
|
|
11
11
|
const PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
12
12
|
|
|
13
13
|
function print(text, stream = "stdout") {
|
|
14
|
-
process[stream].write(
|
|
14
|
+
process[stream].write(String(text) + "\n");
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export function usage() {
|
|
18
|
-
return
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
--
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
18
|
+
return [
|
|
19
|
+
"Usage: opencode-computer-use-permissions [options]",
|
|
20
|
+
"",
|
|
21
|
+
"Run the native Open Computer Use permission and runtime onboarding check.",
|
|
22
|
+
"",
|
|
23
|
+
"Options:",
|
|
24
|
+
" --install Guided install mode used by the package postinstall hook",
|
|
25
|
+
" --strict Return a failure when the native check cannot run",
|
|
26
|
+
" --help, -h Show this help",
|
|
27
|
+
"",
|
|
28
|
+
"The command uses the installed open-computer-use runtime:",
|
|
29
|
+
" macOS checks or launches Accessibility and Screen Recording onboarding.",
|
|
30
|
+
" macOS still requires the user to approve protected TCC toggles.",
|
|
31
|
+
" Linux checks AT-SPI and the signed-in desktop session. On GNOME, install",
|
|
32
|
+
" mode best-effort enables toolkit accessibility with gsettings.",
|
|
33
|
+
" Windows checks UI Automation and the interactive signed-in desktop session.",
|
|
34
|
+
].join("\n");
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
function parseArguments(argv) {
|
|
34
|
-
const options = { strict: false, help: false };
|
|
38
|
+
const options = { install: false, strict: false, help: false };
|
|
35
39
|
for (const argument of argv) {
|
|
36
|
-
if (argument === "--
|
|
40
|
+
if (argument === "--install") options.install = true;
|
|
41
|
+
else if (argument === "--strict") options.strict = true;
|
|
37
42
|
else if (argument === "--help" || argument === "-h") options.help = true;
|
|
38
|
-
else throw new Error(
|
|
43
|
+
else throw new Error("Unknown permission option: " + argument);
|
|
39
44
|
}
|
|
40
45
|
return options;
|
|
41
46
|
}
|
|
42
47
|
|
|
48
|
+
export function platformGuidance(platform = process.platform) {
|
|
49
|
+
if (platform === "darwin") {
|
|
50
|
+
return [
|
|
51
|
+
"macOS permission setup:",
|
|
52
|
+
" - Requires macOS 14 or newer.",
|
|
53
|
+
" - Open Computer Use needs Accessibility and Screen Recording.",
|
|
54
|
+
" - The installer runs the native doctor; if either permission is missing,",
|
|
55
|
+
" the Open Computer Use onboarding window opens and guides you to System Settings.",
|
|
56
|
+
" - macOS requires a human approval for these protected TCC permissions.",
|
|
57
|
+
" - Manual: open-computer-use doctor",
|
|
58
|
+
' - Accessibility pane: open "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"',
|
|
59
|
+
' - Screen Recording pane: open "x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture"',
|
|
60
|
+
];
|
|
61
|
+
}
|
|
62
|
+
if (platform === "linux") {
|
|
63
|
+
return [
|
|
64
|
+
"Linux desktop setup:",
|
|
65
|
+
" - There is no macOS-style permission dialog.",
|
|
66
|
+
" - Open Computer Use needs a signed-in graphical session with AT-SPI2/D-Bus.",
|
|
67
|
+
" - On GNOME, install mode best-effort enables toolkit accessibility with:",
|
|
68
|
+
" gsettings set org.gnome.desktop.interface toolkit-accessibility true",
|
|
69
|
+
" - Wayland screenshot and coordinate input support remains compositor-dependent.",
|
|
70
|
+
" - Manual verification: open-computer-use doctor && open-computer-use call list_apps",
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
if (platform === "win32") {
|
|
74
|
+
return [
|
|
75
|
+
"Windows desktop setup:",
|
|
76
|
+
" - There is no separate UI Automation permission toggle to grant.",
|
|
77
|
+
" - Open Computer Use must run in the signed-in interactive desktop session.",
|
|
78
|
+
" - Detached services/session 0 cannot control the user's desktop.",
|
|
79
|
+
" - Manual verification: open-computer-use doctor && open-computer-use call list_apps",
|
|
80
|
+
];
|
|
81
|
+
}
|
|
82
|
+
return [
|
|
83
|
+
"Desktop permission setup is not defined for " + platform + ".",
|
|
84
|
+
"Use a supported macOS, Linux, or Windows native runtime.",
|
|
85
|
+
];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function printPlatformGuidance(platform, io) {
|
|
89
|
+
for (const line of platformGuidance(platform)) io(line);
|
|
90
|
+
}
|
|
91
|
+
|
|
43
92
|
function shouldSkip(env) {
|
|
44
93
|
const developmentInstall = env.npm_lifecycle_event === "postinstall"
|
|
45
94
|
&& env.INIT_CWD
|
|
@@ -47,15 +96,67 @@ function shouldSkip(env) {
|
|
|
47
96
|
return developmentInstall || env.CI === "true" || env.CI === "1" || env[SKIP_ENV] === "1";
|
|
48
97
|
}
|
|
49
98
|
|
|
99
|
+
function commandAvailable(command, env) {
|
|
100
|
+
const result = spawnSync(command, ["--version"], {
|
|
101
|
+
env,
|
|
102
|
+
stdio: "ignore",
|
|
103
|
+
windowsHide: true,
|
|
104
|
+
timeout: 5_000,
|
|
105
|
+
});
|
|
106
|
+
return !result.error && result.status === 0;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function maybeEnableGnomeAccessibility(env, io) {
|
|
110
|
+
const desktop = ((env.XDG_CURRENT_DESKTOP || "") + " " + (env.DESKTOP_SESSION || "")).toLowerCase();
|
|
111
|
+
if (!desktop.includes("gnome")) {
|
|
112
|
+
io("Linux accessibility auto-enable skipped: GNOME was not detected; AT-SPI will be verified by the native runtime.");
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (!commandAvailable("gsettings", env)) {
|
|
116
|
+
io("Linux accessibility auto-enable skipped: gsettings is unavailable.");
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const result = spawnSync(
|
|
120
|
+
"gsettings",
|
|
121
|
+
["set", "org.gnome.desktop.interface", "toolkit-accessibility", "true"],
|
|
122
|
+
{
|
|
123
|
+
env,
|
|
124
|
+
encoding: "utf8",
|
|
125
|
+
windowsHide: true,
|
|
126
|
+
timeout: 10_000,
|
|
127
|
+
},
|
|
128
|
+
);
|
|
129
|
+
if (result.error || result.status !== 0) {
|
|
130
|
+
io("Linux accessibility auto-enable could not update GNOME settings. Run the documented gsettings command manually.");
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
io("GNOME toolkit accessibility enabled.");
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function printInstallSessionHint(platform, env, io) {
|
|
137
|
+
if (platform === "linux") {
|
|
138
|
+
io("Desktop: " + (env.XDG_CURRENT_DESKTOP || env.DESKTOP_SESSION || "unknown")
|
|
139
|
+
+ "; session: " + (env.XDG_SESSION_TYPE || "unknown") + ".");
|
|
140
|
+
if (!env.DBUS_SESSION_BUS_ADDRESS) {
|
|
141
|
+
io("No DBUS_SESSION_BUS_ADDRESS is visible to the installer; the native runtime will try to discover the signed-in user's session automatically.");
|
|
142
|
+
}
|
|
143
|
+
} else if (platform === "win32") {
|
|
144
|
+
io("Windows session: " + (env.SESSIONNAME || "unknown")
|
|
145
|
+
+ ". UI Automation requires the signed-in interactive desktop.");
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
50
149
|
export function main(argv = process.argv.slice(2), env = process.env, io = print) {
|
|
51
150
|
let options;
|
|
52
151
|
try {
|
|
53
152
|
options = parseArguments(argv);
|
|
54
153
|
} catch (error) {
|
|
55
|
-
io(
|
|
154
|
+
io("[opencode-computer-use-permissions] "
|
|
155
|
+
+ (error instanceof Error ? error.message : String(error)), "stderr");
|
|
56
156
|
io(usage(), "stderr");
|
|
57
157
|
return 2;
|
|
58
158
|
}
|
|
159
|
+
|
|
59
160
|
if (options.help) {
|
|
60
161
|
io(usage());
|
|
61
162
|
return 0;
|
|
@@ -65,12 +166,19 @@ export function main(argv = process.argv.slice(2), env = process.env, io = print
|
|
|
65
166
|
return 0;
|
|
66
167
|
}
|
|
67
168
|
|
|
169
|
+
if (options.install) {
|
|
170
|
+
io("OpenCode Computer Use is checking desktop prerequisites as part of installation.");
|
|
171
|
+
printPlatformGuidance(process.platform, io);
|
|
172
|
+
printInstallSessionHint(process.platform, env, io);
|
|
173
|
+
if (process.platform === "linux") maybeEnableGnomeAccessibility(env, io);
|
|
174
|
+
}
|
|
175
|
+
|
|
68
176
|
let backend;
|
|
69
177
|
try {
|
|
70
178
|
backend = resolveBackend({ backend: "native" }, env);
|
|
71
179
|
} catch (error) {
|
|
72
180
|
const message = error instanceof Error ? error.message : String(error);
|
|
73
|
-
io(
|
|
181
|
+
io("[opencode-computer-use-permissions] Native permission check unavailable: " + message);
|
|
74
182
|
if (options.strict) return 1;
|
|
75
183
|
io("Install the optional open-computer-use runtime, then run this command again.");
|
|
76
184
|
return 0;
|
|
@@ -83,13 +191,18 @@ export function main(argv = process.argv.slice(2), env = process.env, io = print
|
|
|
83
191
|
timeout: 120_000,
|
|
84
192
|
});
|
|
85
193
|
if (result.error) {
|
|
86
|
-
io(
|
|
194
|
+
io("[opencode-computer-use-permissions] Permission check failed: " + result.error.message);
|
|
87
195
|
return options.strict ? 1 : 0;
|
|
88
196
|
}
|
|
89
197
|
if (result.status !== 0) {
|
|
90
|
-
io(
|
|
198
|
+
io("[opencode-computer-use-permissions] Native permission check exited with status "
|
|
199
|
+
+ result.status + ".");
|
|
91
200
|
return options.strict ? 1 : 0;
|
|
92
201
|
}
|
|
202
|
+
if (options.install) {
|
|
203
|
+
io("Desktop onboarding check complete.");
|
|
204
|
+
io("You can rerun it any time with: npx opencode-computer-use-permissions --strict");
|
|
205
|
+
}
|
|
93
206
|
return 0;
|
|
94
207
|
}
|
|
95
208
|
|
|
@@ -2,11 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
import { resolveNativeCommand, runServer } from "../lib/repl.mjs";
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
|
|
5
|
+
const argv = process.argv.slice(2);
|
|
6
|
+
const help = `Usage: opencode-computer-use-repl [-- native-command [args...]]
|
|
7
|
+
|
|
8
|
+
Start the local stdio MCP server exposing js and js_reset.
|
|
9
|
+
With no command override, use the configured open-computer-use native runtime.
|
|
10
|
+
|
|
11
|
+
Options:
|
|
12
|
+
--help, -h Show this help without starting the native runtime
|
|
13
|
+
|
|
14
|
+
Configuration: OPENCODE_COMPUTER_USE_* environment variables.
|
|
15
|
+
Desktop access requires the server host's signed-in graphical session.
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
if (argv.length === 1 && (argv[0] === "--help" || argv[0] === "-h")) {
|
|
20
|
+
process.stdout.write(help);
|
|
21
|
+
} else {
|
|
22
|
+
if (argv.length > 0 && argv[0] !== "--") {
|
|
23
|
+
throw new Error(`Unknown REPL option: ${argv[0]}. Use --help or -- followed by a native command.`);
|
|
24
|
+
}
|
|
25
|
+
const native = resolveNativeCommand(argv);
|
|
26
|
+
await runServer(native);
|
|
27
|
+
}
|
|
28
|
+
} catch (error) {
|
|
7
29
|
const message = (error instanceof Error ? error.message : String(error))
|
|
8
30
|
.replace(/\b(token|secret|password|api[_-]?key|authorization)\s*[:=]\s*(?:bearer|basic)?[^\n\r,;]*/giu, "$1=[redacted]")
|
|
9
31
|
.slice(0, 4_000);
|
|
10
32
|
process.stderr.write(`[opencode-computer-use] ${message}\n`);
|
|
11
33
|
process.exitCode = 1;
|
|
12
|
-
}
|
|
34
|
+
}
|