-
Notifications
You must be signed in to change notification settings - Fork 4.4k
feat(desktop): Computer Use for macOS, Windows, and Linux #6537
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
sheehanmunim
wants to merge
90
commits into
pingdotgg:main
Choose a base branch
from
sheehanmunim:mac/computer-use
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+16,728
−78
Open
Changes from all commits
Commits
Show all changes
90 commits
Select commit
Hold shift + click to select a range
8ac5e65
feat(codex): surface Computer Use and MCP tool approvals; Windows nat…
Nelglor 69846bf
fix(desktop): declare NSAppleEventsUsageDescription so Computer Use c…
sheehanmunim 96340cd
Add macOS desktop control and agent-owned browser tabs
sheehanmunim 07d36fb
Avoid a needless spread when listing agent tabs
sheehanmunim 0fb502d
test(desktop): cover the Apple Events usage description in build config
sheehanmunim c91b49e
refactor(codex): drop the Windows Computer Use transport bridge
sheehanmunim b5cee73
feat(desktop): add the Windows desktop-control MCP server
sheehanmunim 0edf91a
feat(desktop): add the Linux desktop-control backend
sheehanmunim 3a1a52d
feat(desktop): ship the desktop-control server on Windows and Linux
sheehanmunim 6ddc9b8
fix(desktop): write text through AT-SPI on Linux instead of synthetic…
sheehanmunim 96ed810
feat(desktop): bring agent-owned Chrome tabs to Windows and Linux
sheehanmunim 345390d
fix(repo): stop the pre-commit formatter failing on native-only changes
sheehanmunim 9bd7d6b
fix(desktop): prefer X11 for capture when both display servers are pr…
sheehanmunim 8564ef9
fix(desktop): capture on Wayland through wlr-screencopy when xcap cannot
sheehanmunim 9928d9c
fix(desktop): commit the desktop server lockfile
sheehanmunim 7f6e512
refactor(desktop): name the desktop server executable in one place
sheehanmunim 5e67704
fix(desktop): report the requested url when a new tab has not loaded
sheehanmunim 2a0ce40
fix(desktop): confirm browser actions in the macOS server's words
sheehanmunim 13bbdfa
feat(desktop): give the agent its own pointer, and stop taking the us…
sheehanmunim a2ad55a
feat(desktop): Computer Use settings, pointer polish, Windows backgro…
sheehanmunim d9931d0
feat(desktop): polish Computer Use settings and fix Windows Gdi import
sheehanmunim bf31335
fix(desktop): satisfy Effect diagnostics in Computer Use permissions
sheehanmunim a71267c
fix(desktop): inject t3-desktop MCP for Cursor/Grok without HTTP session
sheehanmunim 6a2a6bd
fix(desktop): address Computer Use review findings
sheehanmunim 7d3efc1
fix(desktop): resolve Computer Use settings without widening session R
sheehanmunim 7a8bafd
fix(desktop): skip bad MCP binary candidates and avoid overlay SIGPIPE
sheehanmunim d3ada85
fix(desktop): make ServerSettings acquisition unmistakable for Macros…
sheehanmunim 0f06464
fix(desktop): finish Computer Use correctness follow-ups
sheehanmunim 3fcd438
fix(desktop): harden background input fallbacks and group creation
sheehanmunim c7c6370
fix(desktop): close remaining Computer Use correctness gaps
sheehanmunim 5a9df75
fix(desktop): inject t3-desktop MCP into Codex sessions
sheehanmunim e58f0e7
fix(desktop): avoid JSON.stringify in Codex MCP -c overrides
sheehanmunim 2b374c4
fix(desktop): Windows agent cursor and Chrome extension reconnect
sheehanmunim ea2e1c3
fix(desktop): address Computer Use bot review findings
sheehanmunim 1d4c73d
fix(desktop): unique MCP elicitation correlation and session teardown
sheehanmunim 97dab49
fix(desktop): serialize Chrome session cleanup and clear Effect path
sheehanmunim 894906e
fix(chrome-extension): keep agent group id across reconnect cleanup
sheehanmunim cb8a4d7
fix(desktop-mcp): raise Linux apps via EWMH when AT-SPI focus fails
sheehanmunim 3244b65
fix(desktop-mcp): harden Linux activate/type/press_key and Windows chmod
sheehanmunim 2babdd7
fix(desktop-mcp): use short bridge socket path when App Support is to…
sheehanmunim 0e9955a
fix(desktop-mcp): harden agent window ownership and Linux input cleanup
sheehanmunim 98f9f8e
fix(desktop-mcp): address follow-up Computer Use bot findings
sheehanmunim 4587f66
fix(desktop-mcp): process follow-up Computer Use bot findings
sheehanmunim 32e7ea3
fix(desktop-mcp): clear remaining Linux Computer Use bot findings
sheehanmunim bc0b619
fix(desktop-mcp): drop accidental history.rs from Computer Use branch
sheehanmunim b9bfe2f
fix(desktop-mcp): keep AT-SPI insert on caret errors; harden Wayland …
sheehanmunim b1fd0c1
fix(desktop-mcp): append on caret miss; drop Effect shim; Wayland scroll
sheehanmunim 5beb81c
fix(desktop-mcp): error when Shift is required but unavailable
sheehanmunim d8efd92
fix(desktop-mcp): reject out-of-range pointer coords; lazy Shift_R lo…
sheehanmunim 2e2c0e7
fix(desktop-mcp): sync Computer Use with Macroscope MCP hardening
sheehanmunim d9015ee
fix(desktop): repair ipc doc comment; drop unused Codex stateDir
sheehanmunim 5463d69
fix(settings): decorative brand icons and Computer Use bridge fallback
sheehanmunim 22f058e
fix(desktop): port pointer animation and Win/Linux Computer Use parity
sheehanmunim 872e4e9
fix(desktop): repair desktop-mcp stage JSDoc opener
sheehanmunim 5bb0416
fix(desktop): clear Macroscope Computer Use correctness findings
sheehanmunim d37f87d
fix(desktop): restore CaptureBox for window PNG race safety
sheehanmunim 4f09070
fix(desktop): clear follow-up Macroscope and Bugbot findings
sheehanmunim 6aa103e
fix(desktop): prefer under-point click targets and cap click_count
sheehanmunim 0b47c9a
fix(desktop): scope browser disconnects and tighten click/app resolution
sheehanmunim fe5b700
fix(desktop): constrain click targeting and lock disconnect generation
sheehanmunim e7249ca
fix(desktop): report real tab ids and clearer off-screen click errors
sheehanmunim 3c1d79a
fix(desktop): ignore agent-cursor overlay in under-point hit tests
sheehanmunim 8d5f292
fix(desktop): resolve explicit app for drag/click without stale pid
sheehanmunim d4da8a1
fix(desktop): allow background drags under occluding windows
sheehanmunim 144db52
fix(settings): use shared CollapsibleContent for More browsers
sheehanmunim 4e6c7b4
fix(web): use CollapsiblePanel for More browsers disclosure
sheehanmunim a3338e5
fix(settings): extract More browsers collapsible into shared component
sheehanmunim ce3f53a
fix(native): harden shared Computer Use bridge, capture, and app listing
sheehanmunim 34a70a2
fix(settings): share SettingRowTitle across Computer Use settings
sheehanmunim 2248211
fix(native): hold agent-window lock through creation
sheehanmunim d46a160
fix(native): drop computer-history entry from computer-use main
sheehanmunim a18f529
fix(cu): align bridge socket cleanup, display listing, and privacy se…
sheehanmunim f10b773
fix(desktop): port shared Computer Use correctness fixes from history…
sheehanmunim 9abb20a
fix(desktop): reject empty app query in macOS resolveApp
sheehanmunim af7c7e5
fix(desktop-mcp): resolve numeric app names when PID is absent
sheehanmunim 21085c3
fix(desktop-mcp): keep agent windows across AX gaps; exact numeric names
sheehanmunim 22f85b6
fix(desktop-mcp): remove History CLI; exact-match numeric app names
sheehanmunim 409bd09
fix(desktop-mcp): remove stray brace after native-host entry
sheehanmunim 6dabb18
fix(desktop-mcp): port shared Macroscope CU hardening from History
sheehanmunim 8278c4e
fix(desktop-mcp): use MSG_DONTWAIT bridge writes; fix Shift and FRONT…
sheehanmunim ed24147
fix(desktop-mcp): invoke press/click AT-SPI actions by name
sheehanmunim 1343aa0
fix(chrome-extension): use prod toolbar icon and unclip pointer favicon
sheehanmunim 95d3a38
fix(desktop-mcp): harden Computer Use paths flagged on History rebase
sheehanmunim 179ddbd
fix(web): clean agent cursor settings icon
sheehanmunim 27530f6
fix(web): use real agent-cursor overlay art in settings
sheehanmunim dcdbd03
fix(desktop): Effect 4 Context refs and softer agent-cursor icons
sheehanmunim 0616bb1
fix(web): soft-extend agent-cursor badge glow into purple frame
sheehanmunim 03b1beb
fix(desktop-mcp): harden cross-window drag and bridge socket path
sheehanmunim 92d6674
fix(desktop-mcp): harden browser bridge and Linux/Windows input paths
sheehanmunim c918e12
fix(desktop-mcp): keep ambiguous activate_app matches fail-closed
sheehanmunim File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| // @effect-diagnostics nodeBuiltinImport:off - Fixture reads of Chrome Secure Preferences stay synchronous. | ||
| import * as NodeFS from "node:fs"; | ||
| import * as NodeOS from "node:os"; | ||
| import * as NodePath from "node:path"; | ||
| import { assert, describe, it } from "@effect/vitest"; | ||
| import { vi } from "vite-plus/test"; | ||
|
|
||
| vi.mock("electron", () => ({ | ||
| systemPreferences: { | ||
| isTrustedAccessibilityClient: vi.fn(() => false), | ||
| getMediaAccessStatus: vi.fn(() => "denied"), | ||
| }, | ||
| shell: { | ||
| openExternal: vi.fn(async () => undefined), | ||
| }, | ||
| })); | ||
|
|
||
| import * as Electron from "electron"; | ||
|
|
||
| import { openComputerUsePrivacySettings, readComputerUsePermissions } from "./permissions.ts"; | ||
|
|
||
| describe("computerUse permissions", () => { | ||
| it("reports accessibility and screen recording on darwin", () => { | ||
| const previous = process.platform; | ||
| Object.defineProperty(process, "platform", { value: "darwin" }); | ||
| try { | ||
| const state = readComputerUsePermissions(); | ||
| assert.equal(state.platform, "darwin"); | ||
| assert.deepEqual( | ||
| state.permissions.map((permission) => permission.kind), | ||
| ["accessibility", "screenRecording"], | ||
| ); | ||
| assert.equal(state.permissions[0]?.status, "denied"); | ||
| assert.equal(state.permissions[1]?.status, "denied"); | ||
| } finally { | ||
| Object.defineProperty(process, "platform", { value: previous }); | ||
| } | ||
| }); | ||
|
|
||
| it("marks privacy permissions not required off macOS", () => { | ||
| const previous = process.platform; | ||
| Object.defineProperty(process, "platform", { value: "linux" }); | ||
| try { | ||
| const state = readComputerUsePermissions(); | ||
| assert.equal(state.platform, "linux"); | ||
| assert.isTrue(state.permissions.every((permission) => permission.status === "notRequired")); | ||
| } finally { | ||
| Object.defineProperty(process, "platform", { value: previous }); | ||
| } | ||
| }); | ||
|
|
||
| it("opens the Accessibility privacy pane and prompts trust", async () => { | ||
| const previous = process.platform; | ||
| Object.defineProperty(process, "platform", { value: "darwin" }); | ||
| try { | ||
| const opened = await openComputerUsePrivacySettings("accessibility"); | ||
| assert.isTrue(opened); | ||
| assert.equal( | ||
| vi.mocked(Electron.systemPreferences.isTrustedAccessibilityClient).mock.calls.at(-1)?.[0], | ||
| true, | ||
| ); | ||
| assert.equal( | ||
| vi.mocked(Electron.shell.openExternal).mock.calls.at(-1)?.[0], | ||
| "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility", | ||
| ); | ||
| } finally { | ||
| Object.defineProperty(process, "platform", { value: previous }); | ||
| } | ||
| }); | ||
|
|
||
| it("detects an unpacked extension from Secure Preferences without state", () => { | ||
| const previous = process.platform; | ||
| Object.defineProperty(process, "platform", { value: "darwin" }); | ||
| const home = NodeOS.homedir(); | ||
| const securePath = NodePath.join( | ||
| home, | ||
| "Library/Application Support/Google/Chrome/Default/Secure Preferences", | ||
| ); | ||
| try { | ||
| if (!NodeFS.existsSync(securePath)) return; | ||
| const raw = NodeFS.readFileSync(securePath, "utf8"); | ||
| const parsed = JSON.parse(raw) as { | ||
| extensions?: { settings?: Record<string, unknown> }; | ||
| }; | ||
| const hasExtension = Boolean(parsed.extensions?.settings?.kgdolgnijopbghhomnblabjkmjhnoage); | ||
| const state = readComputerUsePermissions(); | ||
| if (hasExtension) { | ||
| assert.deepEqual(state.chromeExtension, { | ||
| status: "installed", | ||
| detail: "Browser extension installed", | ||
| }); | ||
| } else { | ||
| assert.isTrue(["missing", "unknown"].includes(state.chromeExtension.status)); | ||
| } | ||
| } finally { | ||
| Object.defineProperty(process, "platform", { value: previous }); | ||
| } | ||
| }); | ||
| }); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 Medium
scripts/electron-launcher.mjs:234Existing
.electron-runtimebundles continue to lackNSAppleEventsUsageDescription, so Computer Use Apple Events remain denied for developers with a cached launcher.buildMacLauncherreturns the cached bundle before callingpatchMainBundleInfoPlist; bumpLAUNCHER_VERSIONfrom 15 to invalidate those bundles and apply the new key.🤖 Copy this AI Prompt to have your agent fix this: