Skip to content
Open
Show file tree
Hide file tree
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 Aug 10, 2026
69846bf
fix(desktop): declare NSAppleEventsUsageDescription so Computer Use c…
sheehanmunim Aug 13, 2026
96340cd
Add macOS desktop control and agent-owned browser tabs
sheehanmunim Aug 13, 2026
07d36fb
Avoid a needless spread when listing agent tabs
sheehanmunim Aug 13, 2026
0fb502d
test(desktop): cover the Apple Events usage description in build config
sheehanmunim Aug 13, 2026
c91b49e
refactor(codex): drop the Windows Computer Use transport bridge
sheehanmunim Aug 13, 2026
b5cee73
feat(desktop): add the Windows desktop-control MCP server
sheehanmunim Aug 13, 2026
0edf91a
feat(desktop): add the Linux desktop-control backend
sheehanmunim Aug 13, 2026
3a1a52d
feat(desktop): ship the desktop-control server on Windows and Linux
sheehanmunim Aug 13, 2026
6ddc9b8
fix(desktop): write text through AT-SPI on Linux instead of synthetic…
sheehanmunim Aug 13, 2026
96ed810
feat(desktop): bring agent-owned Chrome tabs to Windows and Linux
sheehanmunim Aug 13, 2026
345390d
fix(repo): stop the pre-commit formatter failing on native-only changes
sheehanmunim Aug 13, 2026
9bd7d6b
fix(desktop): prefer X11 for capture when both display servers are pr…
sheehanmunim Aug 13, 2026
8564ef9
fix(desktop): capture on Wayland through wlr-screencopy when xcap cannot
sheehanmunim Aug 13, 2026
9928d9c
fix(desktop): commit the desktop server lockfile
sheehanmunim Aug 13, 2026
7f6e512
refactor(desktop): name the desktop server executable in one place
sheehanmunim Aug 13, 2026
5e67704
fix(desktop): report the requested url when a new tab has not loaded
sheehanmunim Aug 13, 2026
2a0ce40
fix(desktop): confirm browser actions in the macOS server's words
sheehanmunim Aug 13, 2026
13bbdfa
feat(desktop): give the agent its own pointer, and stop taking the us…
sheehanmunim Aug 13, 2026
a2ad55a
feat(desktop): Computer Use settings, pointer polish, Windows backgro…
sheehanmunim Aug 13, 2026
d9931d0
feat(desktop): polish Computer Use settings and fix Windows Gdi import
sheehanmunim Aug 13, 2026
bf31335
fix(desktop): satisfy Effect diagnostics in Computer Use permissions
sheehanmunim Aug 13, 2026
a71267c
fix(desktop): inject t3-desktop MCP for Cursor/Grok without HTTP session
sheehanmunim Aug 13, 2026
6a2a6bd
fix(desktop): address Computer Use review findings
sheehanmunim Aug 13, 2026
7d3efc1
fix(desktop): resolve Computer Use settings without widening session R
sheehanmunim Aug 13, 2026
7a8bafd
fix(desktop): skip bad MCP binary candidates and avoid overlay SIGPIPE
sheehanmunim Aug 13, 2026
d3ada85
fix(desktop): make ServerSettings acquisition unmistakable for Macros…
sheehanmunim Aug 13, 2026
0f06464
fix(desktop): finish Computer Use correctness follow-ups
sheehanmunim Aug 13, 2026
3fcd438
fix(desktop): harden background input fallbacks and group creation
sheehanmunim Aug 13, 2026
c7c6370
fix(desktop): close remaining Computer Use correctness gaps
sheehanmunim Aug 13, 2026
5a9df75
fix(desktop): inject t3-desktop MCP into Codex sessions
sheehanmunim Aug 13, 2026
e58f0e7
fix(desktop): avoid JSON.stringify in Codex MCP -c overrides
sheehanmunim Aug 13, 2026
2b374c4
fix(desktop): Windows agent cursor and Chrome extension reconnect
sheehanmunim Aug 14, 2026
ea2e1c3
fix(desktop): address Computer Use bot review findings
sheehanmunim Aug 14, 2026
1d4c73d
fix(desktop): unique MCP elicitation correlation and session teardown
sheehanmunim Aug 14, 2026
97dab49
fix(desktop): serialize Chrome session cleanup and clear Effect path
sheehanmunim Aug 14, 2026
894906e
fix(chrome-extension): keep agent group id across reconnect cleanup
sheehanmunim Aug 14, 2026
cb8a4d7
fix(desktop-mcp): raise Linux apps via EWMH when AT-SPI focus fails
sheehanmunim Aug 14, 2026
3244b65
fix(desktop-mcp): harden Linux activate/type/press_key and Windows chmod
sheehanmunim Aug 14, 2026
2babdd7
fix(desktop-mcp): use short bridge socket path when App Support is to…
sheehanmunim Aug 14, 2026
0e9955a
fix(desktop-mcp): harden agent window ownership and Linux input cleanup
sheehanmunim Aug 14, 2026
98f9f8e
fix(desktop-mcp): address follow-up Computer Use bot findings
sheehanmunim Aug 14, 2026
4587f66
fix(desktop-mcp): process follow-up Computer Use bot findings
sheehanmunim Aug 14, 2026
32e7ea3
fix(desktop-mcp): clear remaining Linux Computer Use bot findings
sheehanmunim Aug 14, 2026
bc0b619
fix(desktop-mcp): drop accidental history.rs from Computer Use branch
sheehanmunim Aug 14, 2026
b9bfe2f
fix(desktop-mcp): keep AT-SPI insert on caret errors; harden Wayland …
sheehanmunim Aug 14, 2026
b1fd0c1
fix(desktop-mcp): append on caret miss; drop Effect shim; Wayland scroll
sheehanmunim Aug 14, 2026
5beb81c
fix(desktop-mcp): error when Shift is required but unavailable
sheehanmunim Aug 14, 2026
d8efd92
fix(desktop-mcp): reject out-of-range pointer coords; lazy Shift_R lo…
sheehanmunim Aug 14, 2026
2e2c0e7
fix(desktop-mcp): sync Computer Use with Macroscope MCP hardening
sheehanmunim Aug 15, 2026
d9015ee
fix(desktop): repair ipc doc comment; drop unused Codex stateDir
sheehanmunim Aug 15, 2026
5463d69
fix(settings): decorative brand icons and Computer Use bridge fallback
sheehanmunim Aug 15, 2026
22f058e
fix(desktop): port pointer animation and Win/Linux Computer Use parity
sheehanmunim Aug 15, 2026
872e4e9
fix(desktop): repair desktop-mcp stage JSDoc opener
sheehanmunim Aug 15, 2026
5bb0416
fix(desktop): clear Macroscope Computer Use correctness findings
sheehanmunim Aug 15, 2026
d37f87d
fix(desktop): restore CaptureBox for window PNG race safety
sheehanmunim Aug 15, 2026
4f09070
fix(desktop): clear follow-up Macroscope and Bugbot findings
sheehanmunim Aug 15, 2026
6aa103e
fix(desktop): prefer under-point click targets and cap click_count
sheehanmunim Aug 15, 2026
0b47c9a
fix(desktop): scope browser disconnects and tighten click/app resolution
sheehanmunim Aug 15, 2026
fe5b700
fix(desktop): constrain click targeting and lock disconnect generation
sheehanmunim Aug 15, 2026
e7249ca
fix(desktop): report real tab ids and clearer off-screen click errors
sheehanmunim Aug 15, 2026
3c1d79a
fix(desktop): ignore agent-cursor overlay in under-point hit tests
sheehanmunim Aug 15, 2026
8d5f292
fix(desktop): resolve explicit app for drag/click without stale pid
sheehanmunim Aug 15, 2026
d4da8a1
fix(desktop): allow background drags under occluding windows
sheehanmunim Aug 15, 2026
144db52
fix(settings): use shared CollapsibleContent for More browsers
sheehanmunim Aug 15, 2026
4e6c7b4
fix(web): use CollapsiblePanel for More browsers disclosure
sheehanmunim Aug 15, 2026
a3338e5
fix(settings): extract More browsers collapsible into shared component
sheehanmunim Aug 15, 2026
ce3f53a
fix(native): harden shared Computer Use bridge, capture, and app listing
sheehanmunim Aug 15, 2026
34a70a2
fix(settings): share SettingRowTitle across Computer Use settings
sheehanmunim Aug 15, 2026
2248211
fix(native): hold agent-window lock through creation
sheehanmunim Aug 15, 2026
d46a160
fix(native): drop computer-history entry from computer-use main
sheehanmunim Aug 15, 2026
a18f529
fix(cu): align bridge socket cleanup, display listing, and privacy se…
sheehanmunim Aug 15, 2026
f10b773
fix(desktop): port shared Computer Use correctness fixes from history…
sheehanmunim Aug 15, 2026
9abb20a
fix(desktop): reject empty app query in macOS resolveApp
sheehanmunim Aug 15, 2026
af7c7e5
fix(desktop-mcp): resolve numeric app names when PID is absent
sheehanmunim Aug 15, 2026
21085c3
fix(desktop-mcp): keep agent windows across AX gaps; exact numeric names
sheehanmunim Aug 15, 2026
22f85b6
fix(desktop-mcp): remove History CLI; exact-match numeric app names
sheehanmunim Aug 15, 2026
409bd09
fix(desktop-mcp): remove stray brace after native-host entry
sheehanmunim Aug 15, 2026
6dabb18
fix(desktop-mcp): port shared Macroscope CU hardening from History
sheehanmunim Aug 15, 2026
8278c4e
fix(desktop-mcp): use MSG_DONTWAIT bridge writes; fix Shift and FRONT…
sheehanmunim Aug 15, 2026
ed24147
fix(desktop-mcp): invoke press/click AT-SPI actions by name
sheehanmunim Aug 15, 2026
1343aa0
fix(chrome-extension): use prod toolbar icon and unclip pointer favicon
sheehanmunim Aug 16, 2026
95d3a38
fix(desktop-mcp): harden Computer Use paths flagged on History rebase
sheehanmunim Aug 16, 2026
179ddbd
fix(web): clean agent cursor settings icon
sheehanmunim Aug 16, 2026
27530f6
fix(web): use real agent-cursor overlay art in settings
sheehanmunim Aug 16, 2026
dcdbd03
fix(desktop): Effect 4 Context refs and softer agent-cursor icons
sheehanmunim Aug 16, 2026
0616bb1
fix(web): soft-extend agent-cursor badge glow into purple frame
sheehanmunim Aug 16, 2026
03b1beb
fix(desktop-mcp): harden cross-window drag and bridge socket path
sheehanmunim Aug 16, 2026
92d6674
fix(desktop-mcp): harden browser bridge and Linux/Windows input paths
sheehanmunim Aug 16, 2026
c918e12
fix(desktop-mcp): keep ambiguous activate_app matches fail-closed
sheehanmunim Aug 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions apps/desktop/scripts/electron-launcher.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,14 @@ function patchMainBundleInfoPlist(appBundlePath, iconPath, executableName) {
setPlistString(infoPlistPath, "CFBundleIdentifier", APP_BUNDLE_ID);
setPlistString(infoPlistPath, "CFBundleExecutable", executableName);
setPlistString(infoPlistPath, "CFBundleIconFile", "icon.icns");
// Without this key macOS denies every Apple Event with errAEEventNotPermitted
// (-1743) and never shows the Automation prompt, so Codex Computer Use and any
// other MCP server we spawn silently fail to drive other apps.
setPlistString(

Copy link
Copy Markdown
Contributor

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:234

Existing .electron-runtime bundles continue to lack NSAppleEventsUsageDescription, so Computer Use Apple Events remain denied for developers with a cached launcher. buildMacLauncher returns the cached bundle before calling patchMainBundleInfoPlist; bump LAUNCHER_VERSION from 15 to invalidate those bundles and apply the new key.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/desktop/scripts/electron-launcher.mjs around line 234:

Existing `.electron-runtime` bundles continue to lack `NSAppleEventsUsageDescription`, so Computer Use Apple Events remain denied for developers with a cached launcher. `buildMacLauncher` returns the cached bundle before calling `patchMainBundleInfoPlist`; bump `LAUNCHER_VERSION` from 15 to invalidate those bundles and apply the new key.

infoPlistPath,
"NSAppleEventsUsageDescription",
"This app needs to control other apps to run Computer Use automations you approve.",
);
setPlistJson(infoPlistPath, "CFBundleURLTypes", [
{
CFBundleURLName: APP_BUNDLE_ID,
Expand Down
99 changes: 99 additions & 0 deletions apps/desktop/src/computerUse/permissions.test.ts
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 });
}
});
});
Loading
Loading