Skip to content

feat(desktop): Codex Computer Use as a code-mode namespace - #52

Open
lidge-jun wants to merge 1 commit into
mainfrom
feat/desktop-computer-use
Open

lidge-jun wants to merge 1 commit into
mainfrom
feat/desktop-computer-use

Conversation

@lidge-jun

Copy link
Copy Markdown
Owner

Adds desktop.* so one execute_code can read a native macOS app, filter its accessibility tree in-guest, act, and verify, returning only the answer.

Why not a separate MCP: one model turn per click, and every tree/screenshot lands in context. Measured on a chat app: tree 4.8K chars + 140 KB screenshot per call; in code mode the guest returned 2 lines.

Transport: signed broker from codex-computer-use-mcp (the Sky client refuses untrusted parents). One session per server process so element indexes stay valid across calls.

macOS: host app becomes TCC responsible process; optional disclaimLauncher disclaims responsibility for the signed codex binary. Documented in structure/desktop-surface.md.

Off by default. Tests: 1107/1107 locally (+9 new). Live-checked list_apps / get_app_state / run on macOS.

Adds a guest namespace desktop.* (list_apps, get_app_state, click, set_value,
type_text, press_key, scroll, drag, select_text, perform_secondary_action, run,
status) backed by the signed codex-computer-use-mcp broker.

- One broker session per server process so element indexes survive across
  execute_code calls; the CLI closes it on exit.
- Screenshots are metadata unless requested; desktop.run batches steps and
  stops at the first failure or missing expect text.
- Off by default (config.desktop.enabled). Optional disclaimLauncher works
  around macOS making the host app the responsible process.
- Contract doc structure/desktop-surface.md, catalog and coverage rows, tests.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-08T03:11:24.390707Z 0a63df9 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0a63df9c50

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +93 to +94
const ex = await getExecutor();
const raw = await ex.execute(name, args, { signal });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Forward cancellation to shared desktop calls

When an MCP request is cancelled or execute_code reaches its deadline, the desktop operation is not cancelled: production constructs the singleton with createDesktop({ config }), so this closure's signal is always undefined. A click, keypress, or text entry can therefore execute after the caller has received a cancellation or timeout; on the CLI path, closing the executor may also wait behind that uncancelled operation. Preserve the shared executor while forwarding each execution's abort signal to its calls.

Useful? React with 👍 / 👎.

Comment on lines +76 to +80
if (executor) return executor;
const launcher = caps.disclaimLauncher || env.CU_DISCLAIM_LAUNCHER;
if (launcher) process.env.CU_DISCLAIM_LAUNCHER = launcher;
broker = await loader(caps.packageDir);
executor = new broker.DirectSessionExecutor({ idleTimeoutMs: caps.idleMs ?? 120000 });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Serialize the initial executor creation

When the first two desktop calls overlap—through Promise.all or concurrent MCP requests—both can observe executor === null, await the loader, and construct separate broker sessions. The last assignment wins, so an earlier get_app_state can return element indexes from the discarded session while a subsequent click uses the retained session, defeating the cross-call index guarantee and potentially targeting the wrong element. Memoize the initialization promise or otherwise lock this section.

Useful? React with 👍 / 👎.

Comment on lines +123 to +127
results.push({ step: i, method: r.method, ok: r.ok, ...(r.error ? { error: r.error } : {}),
text: opts.keepText ? r.text : String(r.text || '').slice(0, opts.textChars ?? 300) });
if (!r.ok) return { ok: false, complete: false, failedAt: i, results };
}
return { ok: true, complete: true, results };

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Mark trimmed desktop runs as incomplete

When a successful step returns more than the default 300 characters, or more than an explicit textChars limit, this slice silently drops the remainder but the method still returns complete: true with no truncation indicator. That contradicts the completeness contract in structure/result-completeness.md and prevents callers from distinguishing a complete accessibility tree from a clipped one. Report truncation and lower complete, or retain the full text whenever claiming completeness.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant