codex-computer-use-mcp 0.3.3 → 0.4.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 +38 -121
- package/SECURITY.md +5 -63
- package/dist/audit.d.ts +1 -7
- package/dist/audit.js +4 -12
- package/dist/audit.js.map +1 -1
- package/dist/direct-broker.d.ts +18 -30
- package/dist/direct-broker.js +87 -161
- package/dist/direct-broker.js.map +1 -1
- package/dist/direct-service.d.ts +13 -21
- package/dist/direct-service.js +82 -301
- package/dist/direct-service.js.map +1 -1
- package/dist/mcp-elicitation.d.ts +1 -2
- package/dist/mcp-elicitation.js +18 -23
- package/dist/mcp-elicitation.js.map +1 -1
- package/dist/mcp-server.js +34 -38
- package/dist/mcp-server.js.map +1 -1
- package/dist/session-executor.d.ts +22 -0
- package/dist/session-executor.js +89 -0
- package/dist/session-executor.js.map +1 -0
- package/dist/tools.d.ts +743 -81
- package/dist/tools.js +55 -178
- package/dist/tools.js.map +1 -1
- package/dist/version.d.ts +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/integrations/pi/index.ts +99 -244
- package/package.json +13 -26
- package/ARCHITECTURE.md +0 -162
- package/CHANGELOG.md +0 -13
- package/CONTRIBUTING.md +0 -33
- package/MIGRATION.md +0 -125
- package/PROOF.md +0 -160
- package/dist/config.d.ts +0 -12
- package/dist/config.js +0 -10
- package/dist/config.js.map +0 -1
- package/dist/lock.d.ts +0 -17
- package/dist/lock.js +0 -137
- package/dist/lock.js.map +0 -1
- package/dist/system.d.ts +0 -27
- package/dist/system.js +0 -215
- package/dist/system.js.map +0 -1
- package/docs/adr/0001-standalone-code-mode-mcp.md +0 -45
- package/integrations/pi/README.md +0 -73
- package/integrations/pi/mcp.json.example +0 -15
- package/npm-shrinkwrap.json +0 -4827
package/README.md
CHANGED
|
@@ -1,95 +1,45 @@
|
|
|
1
1
|
# Codex Computer Use MCP
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Expose OpenAI's official signed macOS Computer Use tools directly to Pi and MCP clients. The calling agent chooses each method and its arguments. This package runs no nested model and generates no action plan.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- no nested model call;
|
|
8
|
-
- no model-generated action plan;
|
|
9
|
-
- no subagent;
|
|
10
|
-
- no prompt sent to Codex;
|
|
11
|
-
- no separate model-token usage.
|
|
12
|
-
|
|
13
|
-
It does use OpenAI's signed `codex app-server` as the official host for the bundled Computer Use MCP client. The current official `mcpServer/tool/call` API requires a loaded thread identifier, so the bridge creates an empty, in-memory, zero-turn context (`ephemeral: true`, `turns: []`, `path: null`). It never calls `turn/start` and fails closed if any `turn/*` or `item/*` model activity appears.
|
|
14
|
-
|
|
15
|
-
> **Independent project.** This is not an OpenAI product and is not endorsed by OpenAI. The app-server API is marked experimental and ChatGPT's reviewed component locations may change.
|
|
16
|
-
|
|
17
|
-
## Direct tools
|
|
18
|
-
|
|
19
|
-
Pi registers namespaced tools to avoid collisions with Pi's built-ins. The MCP server exposes the upstream method names.
|
|
20
|
-
|
|
21
|
-
| Pi tool | MCP method | No-permissions | Purpose |
|
|
22
|
-
|---|---|---:|---|
|
|
23
|
-
| `computer_use_list_apps` | `list_apps` | yes | List running and recently used apps |
|
|
24
|
-
| `computer_use_get_app_state` | `get_app_state` | yes | Read the key-window screenshot and accessibility tree |
|
|
25
|
-
| `computer_use_click` | `click` | yes | Click an element or screenshot coordinates |
|
|
26
|
-
| `computer_use_perform_secondary_action` | `perform_secondary_action` | yes | Invoke a named accessibility action |
|
|
27
|
-
| `computer_use_set_value` | `set_value` | yes | Assign an accessibility value |
|
|
28
|
-
| `computer_use_select_text` | `select_text` | yes | Select text or place the cursor |
|
|
29
|
-
| `computer_use_scroll` | `scroll` | yes | Scroll an element |
|
|
30
|
-
| `computer_use_drag` | `drag` | yes | Drag between screenshot coordinates |
|
|
31
|
-
| `computer_use_press_key` | `press_key` | yes | Send a key or key combination |
|
|
32
|
-
| `computer_use_type_text` | `type_text` | yes | Type literal text |
|
|
33
|
-
|
|
34
|
-
The MCP façade preserves the official signed helper's tool descriptions, input schemas, and annotations exactly. The Pi façade preserves its descriptions and input schemas; Pi's tool API does not expose MCP annotations. In particular, all ten MCP methods have `destructiveHint: false`; the wrapper does not conflate changing UI state with destructive behavior or add argument restrictions absent from the official schemas.
|
|
35
|
-
|
|
36
|
-
Pi registers and activates all ten definitions together in every fresh session, while preserving active tools owned by Pi and other extensions. This prevents interaction methods from being absent or loaded through an incompatible provider binding.
|
|
37
|
-
|
|
38
|
-
As the official contract specifies, Pi—not a nested planner—calls `computer_use_get_app_state` once per assistant turn before interacting with an app, then chooses and executes actions itself. The adapter retains one verified app-server runtime and signed Computer Use client for that inspection-action pair, so the action reuses the official active-app session established by `get_app_state`. It closes and verifies the retained process tree after the action, when a new inspection supersedes it, or on Pi session shutdown.
|
|
39
|
-
|
|
40
|
-
## Authorization policy: durable no-permissions
|
|
41
|
-
|
|
42
|
-
`no-permissions` has one precise meaning here: **the wrapper asks no permission questions and exposes all ten official actions**. It is the only mode and the durable default. There is no safe/full selector, config file, environment override, slash command, CLI switch, per-call elevation, app allowlist, intent classifier, task schema, per-action confirmation, special-case app policy, or method gate.
|
|
43
|
-
|
|
44
|
-
The app-server runtime uses the official Full access combination: `approvalPolicy: "never"` and `sandbox: "danger-full-access"`. In the pinned Codex host, that maps to a disabled permission profile and automatically accepts empty-schema MCP approval elicitations. Normal Computer Use app-access checks therefore proceed without a per-app prompt, just as they do in Codex Full access. The bridge does not edit the service's persistent per-bundle approval file. If app-server emits an elicitation instead of resolving it under Full access, the bridge still forwards it faithfully to the invoking client; unsupported clients return `cancel`, never a fabricated `accept` or `decline`.
|
|
45
|
-
|
|
46
|
-
No-permissions leaves the official and transport requirements unchanged:
|
|
47
|
-
|
|
48
|
-
- macOS Screen Recording, Accessibility, and TCC controls remain authoritative;
|
|
49
|
-
- the adapter still selects and verifies the official signed components required for the supported transport;
|
|
50
|
-
- the wrapper verifies compatibility with the upstream ten-tool contract.
|
|
51
|
-
|
|
52
|
-
The current release also retains behavior from the earlier background-computer-use wrapper. This includes canonical app resolution, per-user/per-app coordination, focus completion telemetry, process cleanup, and metadata-only audit. These provide compatibility, lifecycle management, and observability. They do not provide extra authorization or a sandbox. Do not use them as a foundation for more wrapper safeguards.
|
|
53
|
-
|
|
54
|
-
## Why the signed app-server is required
|
|
55
|
-
|
|
56
|
-
Calling the signed `SkyComputerUseClient mcp` binary directly from an ordinary Pi/Node parent successfully initializes and lists all ten schemas, but real calls are rejected with:
|
|
57
|
-
|
|
58
|
-
```text
|
|
59
|
-
Computer Use server error -10000: Sender process is not authenticated
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
OpenAI's app-server exposes a documented `mcpServer/tool/call` endpoint. That endpoint calls a configured MCP tool directly; no model turn is required. Running it from the signed app-bundled binary preserves the official responsible-process/authentication chain without injection, re-signing, TCC changes, private socket emulation, or credential extraction.
|
|
63
|
-
|
|
64
|
-
See [`ARCHITECTURE.md`](ARCHITECTURE.md) for source links and the full restriction inventory.
|
|
5
|
+
OpenAI does not produce or endorse this independent project. It relies on an experimental app-server API and installed ChatGPT components that may change.
|
|
65
6
|
|
|
66
7
|
## Requirements
|
|
67
8
|
|
|
68
|
-
- macOS
|
|
9
|
+
- macOS with an unlocked user session
|
|
69
10
|
- Node.js 22 or newer
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
-
-
|
|
73
|
-
|
|
74
|
-
The bridge follows ChatGPT's current launcher contract for `SkyComputerUseClient` under that per-user component directory. It does not honor `HOME`, `CODEX_HOME`, or an arbitrary path override when resolving the production client. The former exact app-in-plugin layout remains a strict compatibility candidate only when the current component is absent. Every selected client must be at a canonical reviewed path, pass strict code-signature verification, and carry OpenAI Team ID `2DC432GLL2`.
|
|
11
|
+
- the official ChatGPT macOS app at `/Applications/ChatGPT.app`
|
|
12
|
+
- the Computer Use component installed by ChatGPT under `~/.codex/computer-use/`
|
|
13
|
+
- Pi 0.80.7 or newer when using the Pi integration
|
|
75
14
|
|
|
76
|
-
|
|
15
|
+
macOS Screen Recording, Accessibility and TCC controls still apply.
|
|
77
16
|
|
|
78
|
-
|
|
17
|
+
## Pi
|
|
79
18
|
|
|
80
|
-
|
|
19
|
+
Install from npm:
|
|
81
20
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
21
|
+
```bash
|
|
22
|
+
pi install npm:codex-computer-use-mcp
|
|
23
|
+
```
|
|
85
24
|
|
|
86
|
-
|
|
25
|
+
The extension registers and activates these tools:
|
|
87
26
|
|
|
88
|
-
```
|
|
89
|
-
|
|
27
|
+
```text
|
|
28
|
+
computer_use_list_apps
|
|
29
|
+
computer_use_get_app_state
|
|
30
|
+
computer_use_click
|
|
31
|
+
computer_use_perform_secondary_action
|
|
32
|
+
computer_use_set_value
|
|
33
|
+
computer_use_select_text
|
|
34
|
+
computer_use_scroll
|
|
35
|
+
computer_use_drag
|
|
36
|
+
computer_use_press_key
|
|
37
|
+
computer_use_type_text
|
|
90
38
|
```
|
|
91
39
|
|
|
92
|
-
|
|
40
|
+
Use `/computer-use-status` to inspect the installed component and transport status.
|
|
41
|
+
|
|
42
|
+
To run a source checkout:
|
|
93
43
|
|
|
94
44
|
```bash
|
|
95
45
|
npm ci
|
|
@@ -97,30 +47,22 @@ npm run build
|
|
|
97
47
|
pi -ne -e /absolute/path/to/codex-computer-use-mcp/integrations/pi/index.ts
|
|
98
48
|
```
|
|
99
49
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
```text
|
|
103
|
-
/computer-use-status
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
The native Pi adapter is the primary product path. It registers and activates all ten typed tools directly, and routes the required `get_app_state` and following action through one retained signed-client session. It exposes no mode-changing command or wrapper-generated approval UI. Official app-access approval elicitations are resolved by Codex Full access before they reach Pi. Any elicitation that app-server does emit is shown through Pi's UI, and only the user's choice is returned to the service.
|
|
50
|
+
## MCP
|
|
107
51
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
Running the binary without arguments starts a stdio MCP server exposing the same ten direct methods plus `computer_use_status`:
|
|
52
|
+
Running the package binary starts a stdio MCP server with the same ten methods and `computer_use_status`:
|
|
111
53
|
|
|
112
54
|
```bash
|
|
113
|
-
|
|
55
|
+
npx codex-computer-use-mcp
|
|
114
56
|
```
|
|
115
57
|
|
|
116
|
-
|
|
58
|
+
Example Pi MCP configuration:
|
|
117
59
|
|
|
118
60
|
```json
|
|
119
61
|
{
|
|
120
62
|
"mcpServers": {
|
|
121
63
|
"computer-use": {
|
|
122
|
-
"command": "
|
|
123
|
-
"args": ["
|
|
64
|
+
"command": "npx",
|
|
65
|
+
"args": ["codex-computer-use-mcp"],
|
|
124
66
|
"lifecycle": "lazy",
|
|
125
67
|
"requestTimeoutMs": 180000,
|
|
126
68
|
"directTools": false
|
|
@@ -129,34 +71,15 @@ For Pi's generic MCP gateway, keep `directTools: false` so this powerful surface
|
|
|
129
71
|
}
|
|
130
72
|
```
|
|
131
73
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
## Execution and privacy
|
|
74
|
+
## Behaviour
|
|
135
75
|
|
|
136
|
-
|
|
76
|
+
The adapter has one mode. All ten official methods are available without wrapper permission prompts. It adds no app allowlist, action gate, intent classifier, selector rewrite or focus policy. App-server uses Codex Full access. The adapter forwards any elicitation that the official host still emits.
|
|
137
77
|
|
|
138
|
-
|
|
139
|
-
2. applies the single durable no-permissions policy with no mode or prompt branch;
|
|
140
|
-
3. resolves a target to a canonical installed bundle ID;
|
|
141
|
-
4. acquires a fixed per-user/per-app kernel lock shared across all supported clients and state roots;
|
|
142
|
-
5. starts global focus telemetry;
|
|
143
|
-
6. verifies fixed OpenAI-signed broker/client binaries;
|
|
144
|
-
7. starts a credential-free isolated app-server process tree with model transport disabled;
|
|
145
|
-
8. requires explicit `ephemeral: true`, `turns: []`, and `path: null` attestation;
|
|
146
|
-
9. verifies the exact upstream ten-tool inventory and schemas;
|
|
147
|
-
10. issues exactly one `mcpServer/tool/call`;
|
|
148
|
-
11. rejects any model-turn notification, including during teardown;
|
|
149
|
-
12. combines partial-preserving ancestry enumeration with private-working-directory ownership recovery, then freezes, terminates, and verifies the app-server plus separately grouped or reparented helpers; finally it removes temporary state, releases the lock, and writes a content-safe audit with separate broker/lease cleanup evidence.
|
|
78
|
+
Production calls require verified OpenAI-signed app-server and Computer Use binaries with Team ID `2DC432GLL2`. The adapter uses an isolated, credential-free app-server context. It rejects any model-turn activity. Calls after `get_app_state` reuse the signed session, preserving element identifiers and official app state.
|
|
150
79
|
|
|
151
|
-
|
|
80
|
+
Audit records contain bounded metadata. They exclude arguments, app content, screenshots, prompts and credentials. MCP and CLI state defaults to `~/.direct-computer-use`. Pi state defaults to `direct-computer-use` under the Pi agent directory. Set `CODEX_COMPUTER_USE_HOME` to override either default.
|
|
152
81
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
## State and migration
|
|
156
|
-
|
|
157
|
-
Audit state defaults to `~/.direct-computer-use`; override with `CODEX_COMPUTER_USE_HOME`. Permission policy is not read from that agent-writable path: no-permissions is compiled as the only interface. Legacy `config.json` files are ignored.
|
|
158
|
-
|
|
159
|
-
See [`MIGRATION.md`](MIGRATION.md) for version 0.1 migration, source acceptance, rollback, and conflict avoidance.
|
|
82
|
+
Pi limits returned text to 50KB or 2,000 lines. When text exceeds that limit, the complete text is written to a mode-0600 file in a private directory under `/tmp`. Images are returned directly and are never spilled to disk.
|
|
160
83
|
|
|
161
84
|
## Development
|
|
162
85
|
|
|
@@ -166,14 +89,8 @@ npm run check
|
|
|
166
89
|
npm run check:pi
|
|
167
90
|
npm test
|
|
168
91
|
npm run build
|
|
169
|
-
npm audit --omit=dev
|
|
170
|
-
npm pack --dry-run
|
|
171
92
|
```
|
|
172
93
|
|
|
173
|
-
Registry dependency tarballs are exact-pinned with integrity and the package includes `npm-shrinkwrap.json`.
|
|
174
|
-
|
|
175
|
-
See [`CHANGELOG.md`](CHANGELOG.md), [`PROOF.md`](PROOF.md), [`SECURITY.md`](SECURITY.md), and [`CONTRIBUTING.md`](CONTRIBUTING.md). Agent contributors must also follow [`AGENTS.md`](AGENTS.md). It records the maintainer's thin-adapter intent and review standard.
|
|
176
|
-
|
|
177
94
|
## License
|
|
178
95
|
|
|
179
96
|
MIT
|
package/SECURITY.md
CHANGED
|
@@ -1,69 +1,11 @@
|
|
|
1
1
|
# Security policy
|
|
2
2
|
|
|
3
|
-
##
|
|
4
|
-
|
|
5
|
-
Do not open a public issue for a concrete vulnerability in the supported production path. This includes realistic paths to untrusted component execution, unauthorized wrapper dispatch, credential or result-content exposure, or materially false completion reporting.
|
|
6
|
-
|
|
7
|
-
Use GitHub private vulnerability reporting. Include the affected commit and version, a small non-sensitive reproduction, and the expected and observed behavior. Provide evidence that the path is realistically reachable. State whether an official action completed before failure. Speculative hardening ideas without a reachable material effect are not vulnerability reports.
|
|
8
|
-
|
|
9
|
-
Never include credentials, tokens, customer/private content, sensitive screenshots, raw app-state payloads, elicitation contents, or private audit files.
|
|
10
|
-
|
|
11
|
-
## Architecture boundary
|
|
12
|
-
|
|
13
|
-
Raw Pi/Node invocation of the signed Computer Use MCP helper is not an authenticated responsible-process path for real calls. The bridge therefore uses the official signed app-server `mcpServer/tool/call` API.
|
|
14
|
-
|
|
15
|
-
The API requires a loaded thread ID. The bridge creates an empty, pathless, ephemeral context solely to own the MCP runtime and requires the response to explicitly attest `ephemeral: true`, `path: null`, and `turns: []` before dispatch. It never calls `turn/start`; any `turn/*` or `item/*` event—including one received during teardown—is a fatal architecture violation. The temporary `CODEX_HOME` contains no auth file, API key, user MCPs, plugins, history, memories, or account configuration. A non-websocket dummy model provider points at unreachable loopback, and plugin/remote-control features are disabled, preventing app-server model prewarm and Responses API traffic.
|
|
16
|
-
|
|
17
|
-
This is direct tool dispatch—not model orchestration.
|
|
18
|
-
|
|
19
|
-
## Authority and non-goals
|
|
20
|
-
|
|
21
|
-
This package is a thin adapter to official Codex Computer Use. Codex and macOS remain authoritative for tool behavior, app access, and platform permissions. The wrapper must not add permission policy, risk classification, app allowlists, action gates, content inspection, or speculative defence-in-depth.
|
|
22
|
-
|
|
23
|
-
The earlier background-computer-use wrapper provided canonical app resolution, same-app locking, focus completion telemetry, and metadata-only audit. The current release retains these legacy behaviors. They do not provide independent security or authorization boundaries. Do not expand them because a hypothetical safeguard is possible. A maintainer must explicitly approve their removal or material simplification because this changes the release contract.
|
|
24
|
-
|
|
25
|
-
## Current adapter invariants
|
|
26
|
-
|
|
27
|
-
These invariants describe the supported transport, zero-model-turn architecture, current released behavior, process lifecycle, and privacy contract. They are not a general security framework or a mandate to add safeguards.
|
|
28
|
-
|
|
29
|
-
1. Only the fixed app-bundled Codex path and reviewed official Computer Use layouts are allowed in production. The current client is resolved from the OS account home under `~/.codex/computer-use/`; `HOME`, `CODEX_HOME`, arbitrary paths, and symlinked layouts are not accepted. The former exact plugin-bundle layout is considered only when the current component is absent.
|
|
30
|
-
2. Both binaries pass strict code-signature verification and OpenAI Team ID `2DC432GLL2` checks before dispatch. A present current-layout client that fails verification never falls back.
|
|
31
|
-
3. The helper's exact ten method names and input schemas match the pinned expected inventory before every call; release tests also verify its descriptions and annotations.
|
|
32
|
-
4. `no-permissions` is the only wrapper policy: all ten methods are exposed and no wrapper permission prompt is opened.
|
|
33
|
-
5. There is no config file, environment override, command, tool argument, per-call branch, or alternate safe/full route that an agent can select.
|
|
34
|
-
6. App-server uses the official Full access combination, `approvalPolicy: "never"` plus `sandbox: "danger-full-access"`. The pinned Codex host automatically accepts empty-schema MCP approval elicitations, so normal first-party app-access checks proceed without prompts. The wrapper does not synthesize this response or edit persistent per-app approvals. Any elicitation app-server emits is forwarded faithfully; an unavailable client cancels.
|
|
35
|
-
7. As current legacy wrapper behavior, target selectors resolve to canonical installed bundle IDs before dispatch.
|
|
36
|
-
8. As current legacy wrapper coordination, same-app work is excluded across native Pi, generic MCP, and custom state roots with one fixed per-user kernel `lockf` lease namespace.
|
|
37
|
-
9. As current legacy completion telemetry, target focus events, periodic samples, watcher health, queued ASN resolution, and final state are checked. This is post-action reporting, not a preventive OS sandbox or an official Codex access control.
|
|
38
|
-
10. One direct request emits one official `mcpServer/tool/call`; no model turn, subagent, shell, web, plugin, prompt, or reachable model transport is available.
|
|
39
|
-
11. App-server and helper share one private broker-session working directory. One-shot calls close it immediately; Pi retains it only across the required `get_app_state` and following action, then closes it after the action, before replacement inspection, or on session shutdown. Cleanup combines strict ancestry enumeration (preserving partial results) with working-directory ownership recovery, freezes processes to a stable set, kills every owned process, awaits stdio closure, and verifies exit. This still finds a helper reparented by an early app-server exit; enumeration/freeze/exit uncertainty is fatal.
|
|
40
|
-
12. Protocol JSONL is bounded before an unterminated line can exceed 8 MB in memory.
|
|
41
|
-
13. Per-call `CODEX_HOME` and work directories are mode-private and recursively removed.
|
|
42
|
-
14. Only validated text/image result blocks cross to the invoking client. No full-result spill file is written.
|
|
43
|
-
15. Audits contain metadata only, including separate `brokerCleanupVerified` and `appLeaseReleased` evidence. A retained Pi inspection truthfully records broker cleanup as pending (`false`); the paired action does not return if final retained-session cleanup fails. Lease-release failure changes the audited outcome before surfacing. Arguments, values, screenshots, app-state text, result content, prompts, approvals, credentials, and tokens are forbidden.
|
|
44
|
-
16. Policy rejections are audited; audit failure is fatal once a secure state path exists.
|
|
45
|
-
17. Runtime and development dependency tarballs are exact-pinned with integrity in `npm-shrinkwrap.json`.
|
|
46
|
-
|
|
47
|
-
## Permission semantics
|
|
48
|
-
|
|
49
|
-
### No-permissions
|
|
50
|
-
|
|
51
|
-
All ten official methods and arbitrary resolvable app targets are available without wrapper permission prompts. The name means “ask no permission,” not “disable tools.” This is broad authorization. It does not imply that actions are reversible or that focus detection can prevent an already dispatched action.
|
|
52
|
-
|
|
53
|
-
The mode is compiled as the sole policy. Agent-writable audit state and legacy configuration files cannot change it, and there is no CLI/slash/tool/environment mode selector.
|
|
54
|
-
|
|
55
|
-
## Elicitations
|
|
56
|
-
|
|
57
|
-
The bridge starts app-server with `approvalPolicy: "never"` and `sandbox: "danger-full-access"`. This is Codex's Full access policy, not a wrapper-side approximation. Codex 0.144.2 maps the sandbox value to a disabled permission profile and automatically accepts empty-schema MCP approval elicitations before they are emitted to the client. That covers normal Computer Use app-access prompts without mutating the service's persistent approval file.
|
|
58
|
-
|
|
59
|
-
If app-server emits a form, OpenAI-form, or URL elicitation, Pi renders it and stdio MCP forwards supported standard modes through `elicitation/create`. The wrapper preserves the user/client response. Missing UI or an unsupported client produces `cancel`, never a fabricated decision.
|
|
60
|
-
|
|
61
|
-
## Visible content
|
|
3
|
+
## Supported versions
|
|
62
4
|
|
|
63
|
-
|
|
5
|
+
Only the latest release is supported.
|
|
64
6
|
|
|
65
|
-
##
|
|
7
|
+
## Reporting a vulnerability
|
|
66
8
|
|
|
67
|
-
|
|
9
|
+
Use GitHub private vulnerability reporting for a concrete vulnerability in the supported production path. Include the affected version or commit, expected and observed behaviour, and a small non-sensitive reproduction.
|
|
68
10
|
|
|
69
|
-
|
|
11
|
+
Do not include credentials, tokens, private content, screenshots, raw app-state payloads, elicitation contents or audit files. Do not open a public issue before the report has been assessed.
|
package/dist/audit.d.ts
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import type { PermissionMode } from "./config.ts";
|
|
2
1
|
import type { DirectMethod } from "./tools.ts";
|
|
3
2
|
export interface AuditRecord {
|
|
4
3
|
timestamp: string;
|
|
5
4
|
runId: string;
|
|
6
5
|
method: DirectMethod | "invalid_request";
|
|
7
|
-
permissionMode: PermissionMode;
|
|
8
6
|
app: string | null;
|
|
9
|
-
mutating: boolean;
|
|
10
|
-
authorization: "no_permissions_unrestricted" | "none";
|
|
11
7
|
inputBytes: number;
|
|
12
8
|
outcome: string;
|
|
13
9
|
durationMs: number;
|
|
@@ -17,10 +13,8 @@ export interface AuditRecord {
|
|
|
17
13
|
modelTurnsStarted: number;
|
|
18
14
|
ephemeralThread: boolean | null;
|
|
19
15
|
elicitationRequests: number;
|
|
20
|
-
backgroundPreserved: boolean | null;
|
|
21
16
|
brokerCleanupVerified: boolean;
|
|
22
|
-
appLeaseReleased: boolean;
|
|
23
17
|
resultContentTypes: string[];
|
|
24
18
|
resultBytes: number;
|
|
25
19
|
}
|
|
26
|
-
export declare function appendAudit(stateDir: string, record: AuditRecord
|
|
20
|
+
export declare function appendAudit(stateDir: string, record: AuditRecord): Promise<void>;
|
package/dist/audit.js
CHANGED
|
@@ -8,35 +8,27 @@ async function ensurePrivateDirectory(directory) {
|
|
|
8
8
|
throw new Error("Audit state path must be a non-symlink directory");
|
|
9
9
|
}
|
|
10
10
|
catch (error) {
|
|
11
|
-
if (error
|
|
11
|
+
if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT")
|
|
12
12
|
throw error;
|
|
13
13
|
await mkdir(directory, { recursive: true, mode: 0o700 });
|
|
14
|
-
const info = await lstat(directory);
|
|
15
|
-
if (info.isSymbolicLink() || !info.isDirectory())
|
|
16
|
-
throw new Error("Audit state path must be a non-symlink directory");
|
|
17
14
|
}
|
|
18
15
|
await chmod(directory, 0o700);
|
|
19
16
|
}
|
|
20
|
-
export async function appendAudit(stateDir, record
|
|
21
|
-
if (path.basename(fileName) !== fileName)
|
|
22
|
-
throw new Error("Audit filename must not contain a path");
|
|
17
|
+
export async function appendAudit(stateDir, record) {
|
|
23
18
|
await ensurePrivateDirectory(stateDir);
|
|
24
19
|
const auditDir = path.join(stateDir, "audit");
|
|
25
20
|
await ensurePrivateDirectory(auditDir);
|
|
26
|
-
const auditPath = path.join(auditDir,
|
|
21
|
+
const auditPath = path.join(auditDir, "direct-computer-use.jsonl");
|
|
27
22
|
const flags = constants.O_APPEND | constants.O_CREAT | constants.O_WRONLY | constants.O_NOFOLLOW;
|
|
28
23
|
const handle = await open(auditPath, flags, 0o600);
|
|
29
24
|
try {
|
|
30
|
-
|
|
31
|
-
if (!info.isFile())
|
|
25
|
+
if (!(await handle.stat()).isFile())
|
|
32
26
|
throw new Error("Audit target must be a regular file");
|
|
33
27
|
await handle.chmod(0o600);
|
|
34
28
|
await handle.writeFile(`${JSON.stringify(record)}\n`, "utf8");
|
|
35
|
-
await handle.sync();
|
|
36
29
|
}
|
|
37
30
|
finally {
|
|
38
31
|
await handle.close();
|
|
39
32
|
}
|
|
40
|
-
return auditPath;
|
|
41
33
|
}
|
|
42
34
|
//# sourceMappingURL=audit.js.map
|
package/dist/audit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,IAAI,MAAM,WAAW,CAAC;AAsB7B,KAAK,UAAU,sBAAsB,CAAC,SAAiB;IACtD,IAAI,CAAC;QACJ,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC;QACpC,IAAI,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACvH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,KAAK,CAAC;QAC5F,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,MAAM,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAgB,EAAE,MAAmB;IACtE,MAAM,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9C,MAAM,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,2BAA2B,CAAC,CAAC;IACnE,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,OAAO,GAAG,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,UAAU,CAAC;IACjG,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IACnD,IAAI,CAAC;QACJ,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QAC5F,MAAM,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC1B,MAAM,MAAM,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC/D,CAAC;YAAS,CAAC;QACV,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;AACF,CAAC"}
|
package/dist/direct-broker.d.ts
CHANGED
|
@@ -1,27 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { DirectMethod, DirectToolArguments, JsonObject, JsonValue } from "./tools.ts";
|
|
3
|
+
declare const elicitationRequestSchema: z.ZodObject<{
|
|
4
|
+
mode: z.ZodOptional<z.ZodString>;
|
|
5
|
+
message: z.ZodOptional<z.ZodString>;
|
|
6
|
+
requestedSchema: z.ZodOptional<z.ZodJSONSchema>;
|
|
7
|
+
url: z.ZodOptional<z.ZodString>;
|
|
8
|
+
elicitationId: z.ZodOptional<z.ZodString>;
|
|
9
|
+
_meta: z.ZodOptional<z.ZodJSONSchema>;
|
|
10
|
+
}, z.core.$catchall<z.ZodJSONSchema>>;
|
|
11
|
+
export type DirectBrokerElicitationRequest = z.infer<typeof elicitationRequestSchema>;
|
|
13
12
|
export interface DirectBrokerElicitationResponse {
|
|
14
13
|
action: "accept" | "decline" | "cancel";
|
|
15
|
-
content?:
|
|
16
|
-
_meta?:
|
|
14
|
+
content?: JsonValue;
|
|
15
|
+
_meta?: JsonValue;
|
|
17
16
|
}
|
|
18
17
|
export interface DirectBrokerResult {
|
|
19
|
-
content:
|
|
20
|
-
structuredContent?:
|
|
18
|
+
content: JsonObject[];
|
|
19
|
+
structuredContent?: JsonValue;
|
|
21
20
|
isError: boolean;
|
|
22
21
|
brokerVersion: string;
|
|
23
22
|
clientBuild: string;
|
|
24
|
-
durationMs: number;
|
|
25
23
|
elicitationRequests: number;
|
|
26
24
|
modelTurnsStarted: 0;
|
|
27
25
|
ephemeralThread: true;
|
|
@@ -40,13 +38,8 @@ export interface DirectBrokerOptions {
|
|
|
40
38
|
skipSignatureVerification?: boolean;
|
|
41
39
|
/** Test-only process-enumerator override. */
|
|
42
40
|
processEnumeratorCommand?: string;
|
|
43
|
-
/** Test-only working-directory process-enumerator override. */
|
|
44
|
-
cwdEnumeratorCommand?: string;
|
|
45
41
|
onSpawn?: (pid: number) => void;
|
|
46
42
|
}
|
|
47
|
-
export declare class BrokerVerificationError extends Error {
|
|
48
|
-
constructor(message: string);
|
|
49
|
-
}
|
|
50
43
|
export declare class DirectBrokerCallError extends Error {
|
|
51
44
|
readonly cleanupVerified: boolean;
|
|
52
45
|
readonly directCalls: number;
|
|
@@ -66,8 +59,8 @@ export declare class DirectBrokerCallError extends Error {
|
|
|
66
59
|
}
|
|
67
60
|
interface CommandResult {
|
|
68
61
|
status: number | null;
|
|
69
|
-
stdout?: string
|
|
70
|
-
stderr?: string
|
|
62
|
+
stdout?: string;
|
|
63
|
+
stderr?: string;
|
|
71
64
|
}
|
|
72
65
|
type RunSync = (command: string, args: string[]) => CommandResult;
|
|
73
66
|
export interface OfficialComputerUseClient {
|
|
@@ -91,14 +84,9 @@ export declare function verifyOfficialDirectBroker(options?: ResolveOfficialComp
|
|
|
91
84
|
};
|
|
92
85
|
export declare function buildDirectAppServerArgs(mcpCwd?: string, clientPath?: string): string[];
|
|
93
86
|
export interface OfficialDirectToolSession {
|
|
94
|
-
call(method: DirectMethod, args: DirectToolArguments, options?: Pick<DirectBrokerOptions, "timeoutMs" | "signal" | "onElicitation"
|
|
87
|
+
call(method: DirectMethod, args: DirectToolArguments, options?: Pick<DirectBrokerOptions, "timeoutMs" | "signal" | "onElicitation">): Promise<DirectBrokerResult>;
|
|
95
88
|
close(): Promise<void>;
|
|
96
89
|
}
|
|
97
|
-
/**
|
|
98
|
-
* Start one verified app-server runtime and retain its signed Computer Use MCP
|
|
99
|
-
* client across calls. Pi uses this for the required get_app_state -> action
|
|
100
|
-
* sequence; one-shot callers continue to use callOfficialDirectTool below.
|
|
101
|
-
*/
|
|
102
90
|
export declare function createOfficialDirectToolSession(options?: DirectBrokerOptions): Promise<OfficialDirectToolSession>;
|
|
103
91
|
export declare function callOfficialDirectTool(method: DirectMethod, args: DirectToolArguments, options?: DirectBrokerOptions): Promise<DirectBrokerResult>;
|
|
104
92
|
export {};
|