open-computer-use-mcp 0.1.32 → 0.1.35

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.
@@ -1,9 +1,74 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
-
4
- print_launcher_help() {
5
- cat <<'EOF'
6
- Open Computer Use
1
+ #!/usr/bin/env node
2
+ const { spawn } = require("node:child_process");
3
+ const fs = require("node:fs");
4
+ const path = require("node:path");
5
+
6
+ const platformPackages = {
7
+ "darwin-arm64": {
8
+ "executablePath": [
9
+ "dist",
10
+ "Open Computer Use.app",
11
+ "Contents",
12
+ "MacOS",
13
+ "OpenComputerUse"
14
+ ]
15
+ },
16
+ "darwin-x64": {
17
+ "executablePath": [
18
+ "dist",
19
+ "Open Computer Use.app",
20
+ "Contents",
21
+ "MacOS",
22
+ "OpenComputerUse"
23
+ ]
24
+ },
25
+ "linux-arm64": {
26
+ "executablePath": [
27
+ "dist",
28
+ "linux",
29
+ "arm64",
30
+ "open-computer-use"
31
+ ]
32
+ },
33
+ "linux-x64": {
34
+ "executablePath": [
35
+ "dist",
36
+ "linux",
37
+ "amd64",
38
+ "open-computer-use"
39
+ ]
40
+ },
41
+ "win32-arm64": {
42
+ "executablePath": [
43
+ "dist",
44
+ "windows",
45
+ "arm64",
46
+ "open-computer-use.exe"
47
+ ]
48
+ },
49
+ "win32-x64": {
50
+ "executablePath": [
51
+ "dist",
52
+ "windows",
53
+ "amd64",
54
+ "open-computer-use.exe"
55
+ ]
56
+ }
57
+ };
58
+ const packageRoot = path.resolve(__dirname, "..");
59
+ const args = process.argv.slice(2);
60
+ const command = args[0] || "";
61
+ const installCommands = new Map([
62
+ ["install-claude-mcp", "install-claude-mcp.sh"],
63
+ ["install-clauce-mcp", "install-claude-mcp.sh"],
64
+ ["install-gemini-mcp", "install-gemini-mcp.sh"],
65
+ ["install-codex-mcp", "install-codex-mcp.sh"],
66
+ ["install-opencode-mcp", "install-opencode-mcp.sh"],
67
+ ["install-codex-plugin", "install-codex-plugin.sh"],
68
+ ]);
69
+
70
+ function printLauncherHelp() {
71
+ console.log(`Open Computer Use
7
72
 
8
73
  Usage:
9
74
  open-computer-use [command] [options]
@@ -11,13 +76,15 @@ Usage:
11
76
 
12
77
  Commands:
13
78
  mcp Start the stdio MCP server.
14
- doctor Print permission status and launch onboarding if needed.
79
+ doctor Print permission status and launch onboarding if needed on macOS.
15
80
  list-apps Print running or recently used apps.
16
81
  snapshot <app> Print the current accessibility snapshot for an app.
17
- call <tool> Call one tool, or run a JSON array of tool calls.
82
+ call <tool> Call one tool, or run a JSON array of tool calls.
18
83
  turn-ended Notify the running MCP process that the host turn ended.
19
84
  install-claude-mcp Install the MCP server into ~/.claude.json for this project.
85
+ install-gemini-mcp Install the MCP server into Gemini CLI config.
20
86
  install-codex-mcp Install the MCP server into ~/.codex/config.toml.
87
+ install-opencode-mcp Install the MCP server into ~/.config/opencode.
21
88
  install-codex-plugin Install this npm package into the local Codex plugin cache.
22
89
  help [command] Show general or command-specific help.
23
90
  version Print the CLI version.
@@ -27,84 +94,115 @@ Global options:
27
94
  -v, --version Show version.
28
95
 
29
96
  Notes:
30
- Running without a command launches the permission onboarding app.
31
- Use `open-computer-use help <command>` for command-specific help.
32
- EOF
97
+ This npm package bundles native runtimes for supported platforms and selects the current os-arch at launch.
98
+ Use 'open-computer-use help <command>' for command-specific help.`);
33
99
  }
34
100
 
35
- script_path="${BASH_SOURCE[0]}"
36
- while [[ -L "${script_path}" ]]; do
37
- script_dir="$(cd "$(dirname "${script_path}")" && pwd)"
38
- script_path="$(readlink "${script_path}")"
39
- if [[ "${script_path}" != /* ]]; then
40
- script_path="${script_dir}/${script_path}"
41
- fi
42
- done
43
- package_root="$(cd "$(dirname "${script_path}")/.." && pwd)"
44
- app_binary="${package_root}/dist/Open Computer Use.app/Contents/MacOS/OpenComputerUse"
45
- install_claude_mcp_script="${package_root}/scripts/install-claude-mcp.sh"
46
- install_mcp_script="${package_root}/scripts/install-codex-mcp.sh"
47
- install_script="${package_root}/scripts/install-codex-plugin.sh"
48
-
49
- if [[ "${1:-}" == "install-claude-mcp" || "${1:-}" == "install-clauce-mcp" ]]; then
50
- shift
51
- exec "${install_claude_mcp_script}" "$@"
52
- fi
53
-
54
- if [[ "${1:-}" == "install-codex-mcp" ]]; then
55
- shift
56
- exec "${install_mcp_script}" "$@"
57
- fi
58
-
59
- if [[ "${1:-}" == "install-codex-plugin" ]]; then
60
- shift
61
- exec "${install_script}" "$@"
62
- fi
63
-
64
- if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
65
- print_launcher_help
66
- exit 0
67
- fi
68
-
69
- if [[ "${1:-}" == "help" && $# -le 1 ]]; then
70
- print_launcher_help
71
- exit 0
72
- fi
73
-
74
- if [[ "${1:-}" == "help" && "${2:-}" == "install-codex-plugin" ]]; then
75
- cat <<'EOF'
76
- Usage:
77
- open-computer-use install-codex-plugin
101
+ function printInstallHelp(scriptName, usage) {
102
+ console.log(`Usage:
103
+ ${usage}
78
104
 
79
- Install this npm package into the local Codex plugin cache.
80
- EOF
81
- exit 0
82
- fi
105
+ This helper updates a local MCP or plugin config to run:
106
+ open-computer-use mcp
83
107
 
84
- if [[ "${1:-}" == "help" && "${2:-}" == "install-codex-mcp" ]]; then
85
- cat <<'EOF'
86
- Usage:
87
- open-computer-use install-codex-mcp
108
+ Script:
109
+ ${scriptName}`);
110
+ }
88
111
 
89
- Install the open-computer-use MCP server into ~/.codex/config.toml.
90
- EOF
91
- exit 0
92
- fi
112
+ function fail(message) {
113
+ console.error(message);
114
+ process.exit(1);
115
+ }
93
116
 
94
- if [[ "${1:-}" == "help" && ( "${2:-}" == "install-claude-mcp" || "${2:-}" == "install-clauce-mcp" ) ]]; then
95
- cat <<'EOF'
96
- Usage:
97
- open-computer-use install-claude-mcp
98
- open-computer-use install-clauce-mcp
117
+ function spawnAndExit(executable, executableArgs) {
118
+ const child = spawn(executable, executableArgs, {
119
+ stdio: "inherit",
120
+ windowsHide: false,
121
+ });
122
+
123
+ child.on("error", (error) => {
124
+ fail(`Failed to start ${executable}: ${error.message}`);
125
+ });
126
+
127
+ for (const signal of ["SIGINT", "SIGTERM"]) {
128
+ process.on(signal, () => {
129
+ child.kill(signal);
130
+ });
131
+ }
132
+
133
+ child.on("exit", (code, signal) => {
134
+ if (signal) {
135
+ process.exit(1);
136
+ }
137
+ process.exit(code ?? 0);
138
+ });
139
+ }
99
140
 
100
- Install the open-computer-use MCP server into ~/.claude.json for the current project.
101
- EOF
102
- exit 0
103
- fi
141
+ function runInstallCommand(scriptName, scriptArgs) {
142
+ if (process.platform === "win32") {
143
+ fail(`${command} currently requires a POSIX shell. Configure your MCP client with command "open-computer-use" and args ["mcp"] on Windows.`);
144
+ }
104
145
 
105
- if [[ ! -x "${app_binary}" ]]; then
106
- echo "open-computer-use could not find a runnable app bundle at ${app_binary}." >&2
107
- exit 1
108
- fi
146
+ const scriptPath = path.join(packageRoot, "scripts", scriptName);
147
+ if (!fs.existsSync(scriptPath)) {
148
+ fail(`Missing installer helper at ${scriptPath}.`);
149
+ }
150
+
151
+ spawnAndExit(scriptPath, scriptArgs);
152
+ }
153
+
154
+ function resolveNativeExecutable() {
155
+ const platformKey = `${process.platform}-${process.arch}`;
156
+ const target = platformPackages[platformKey];
157
+ if (!target) {
158
+ const supported = Object.keys(platformPackages).sort().join(", ");
159
+ fail(`Unsupported platform ${platformKey}. Supported platforms: ${supported}.`);
160
+ }
161
+
162
+ const executablePath = path.join(packageRoot, ...target.executablePath);
163
+ if (!fs.existsSync(executablePath)) {
164
+ fail(`Missing bundled native runtime for ${platformKey} at ${executablePath}.
165
+
166
+ Reinstall with:
167
+ npm install -g open-computer-use`);
168
+ }
169
+
170
+ return executablePath;
171
+ }
109
172
 
110
- exec "${app_binary}" "$@"
173
+ if (command === "-h" || command === "--help" || (command === "help" && args.length <= 1)) {
174
+ printLauncherHelp();
175
+ process.exit(0);
176
+ }
177
+
178
+ if (command === "help" && args[1] === "install-codex-plugin") {
179
+ printInstallHelp("install-codex-plugin.sh", "open-computer-use install-codex-plugin");
180
+ process.exit(0);
181
+ }
182
+
183
+ if (command === "help" && args[1] === "install-codex-mcp") {
184
+ printInstallHelp("install-codex-mcp.sh", "open-computer-use install-codex-mcp");
185
+ process.exit(0);
186
+ }
187
+
188
+ if (command === "help" && args[1] === "install-gemini-mcp") {
189
+ printInstallHelp("install-gemini-mcp.sh", "open-computer-use install-gemini-mcp [--scope project|user]");
190
+ process.exit(0);
191
+ }
192
+
193
+ if (command === "help" && args[1] === "install-opencode-mcp") {
194
+ printInstallHelp("install-opencode-mcp.sh", "open-computer-use install-opencode-mcp");
195
+ process.exit(0);
196
+ }
197
+
198
+ if (command === "help" && (args[1] === "install-claude-mcp" || args[1] === "install-clauce-mcp")) {
199
+ printInstallHelp("install-claude-mcp.sh", "open-computer-use install-claude-mcp");
200
+ process.exit(0);
201
+ }
202
+
203
+ if (installCommands.has(command)) {
204
+ const scriptName = installCommands.get(command);
205
+ runInstallCommand(scriptName, args.slice(1));
206
+ } else {
207
+ spawnAndExit(resolveNativeExecutable(), args);
208
+ }
@@ -21,7 +21,7 @@
21
21
  <key>CFBundlePackageType</key>
22
22
  <string>APPL</string>
23
23
  <key>CFBundleShortVersionString</key>
24
- <string>0.1.32</string>
24
+ <string>0.1.35</string>
25
25
  <key>CFBundleVersion</key>
26
26
  <string>1</string>
27
27
  <key>LSMinimumSystemVersion</key>
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "open-computer-use-mcp",
3
- "version": "0.1.32",
4
- "description": "Prebuilt macOS Computer Use MCP server. After install, run open-computer-use doctor.",
3
+ "version": "0.1.35",
4
+ "description": "Cross-platform Computer Use MCP server launcher. After install, configure open-computer-use mcp.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/iFurySt/open-codex-computer-use",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "https://github.com/iFurySt/open-codex-computer-use"
9
+ "url": "git+https://github.com/iFurySt/open-codex-computer-use.git"
10
10
  },
11
11
  "bugs": {
12
12
  "url": "https://github.com/iFurySt/open-codex-computer-use/issues"
@@ -16,15 +16,10 @@
16
16
  "codex",
17
17
  "mcp",
18
18
  "macos",
19
+ "linux",
20
+ "windows",
19
21
  "automation"
20
22
  ],
21
- "os": [
22
- "darwin"
23
- ],
24
- "cpu": [
25
- "arm64",
26
- "x64"
27
- ],
28
23
  "preferGlobal": true,
29
24
  "publishConfig": {
30
25
  "access": "public"
@@ -41,13 +36,17 @@
41
36
  ".agents/plugins/marketplace.json",
42
37
  "bin/",
43
38
  "dist/Open Computer Use.app/",
39
+ "dist/linux/",
40
+ "dist/windows/",
44
41
  "plugins/open-computer-use/.codex-plugin/",
45
42
  "plugins/open-computer-use/.mcp.json",
46
43
  "plugins/open-computer-use/assets/",
47
44
  "plugins/open-computer-use/scripts/",
48
45
  "scripts/install-claude-mcp.sh",
46
+ "scripts/install-gemini-mcp.sh",
49
47
  "scripts/install-config-helper.mjs",
50
48
  "scripts/install-codex-mcp.sh",
49
+ "scripts/install-opencode-mcp.sh",
51
50
  "scripts/install-codex-plugin.sh",
52
51
  "scripts/postinstall.mjs",
53
52
  "README.md",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "open-computer-use",
3
- "version": "0.1.32",
4
- "description": "Open-source macOS Computer Use MCP server packaged as a Codex plugin.",
3
+ "version": "0.1.35",
4
+ "description": "Open-source cross-platform Computer Use MCP server packaged as a Codex plugin.",
5
5
  "author": {
6
6
  "name": "Leo",
7
7
  "url": "https://github.com/iFurySt"
@@ -19,8 +19,8 @@
19
19
  "mcpServers": "./.mcp.json",
20
20
  "interface": {
21
21
  "displayName": "Open Computer Use",
22
- "shortDescription": "Control macOS apps from Codex with the open local server",
23
- "longDescription": "Open Computer Use packages this repository's open-source macOS automation server as a Codex plugin. It exposes the same nine desktop-control MCP tools through the locally built OpenComputerUse app bundle, with an AX-first and keyboard-first strategy that tries to avoid stealing focus until global pointer input is truly required.",
22
+ "shortDescription": "Control desktop apps from Codex with the open local server",
23
+ "longDescription": "Open Computer Use packages this repository's open-source desktop automation server as a Codex plugin. It exposes the same nine desktop-control MCP tools through a local macOS app bundle or Linux / Windows native binary, with semantic accessibility paths preferred before fallback input.",
24
24
  "developerName": "Leo",
25
25
  "category": "Productivity",
26
26
  "capabilities": [
@@ -32,7 +32,7 @@
32
32
  "privacyPolicyURL": "https://github.com/iFurySt/open-codex-computer-use/blob/main/SECURITY.md",
33
33
  "termsOfServiceURL": "https://github.com/iFurySt/open-codex-computer-use/blob/main/LICENSE",
34
34
  "defaultPrompt": [
35
- "Inspect the current UI state of this Mac app without stealing focus when possible",
35
+ "Inspect the current UI state of this desktop app without stealing focus when possible",
36
36
  "Open a new local document with keyboard shortcuts first, then type content without moving my real pointer unless required",
37
37
  "Drive the fixture app and verify the nine computer-use tools still behave correctly"
38
38
  ],
@@ -8,9 +8,15 @@ candidate_binaries=(
8
8
  "${plugin_root}/Open Computer Use.app/Contents/MacOS/OpenComputerUse"
9
9
  "${plugin_root}/Open Computer Use (Dev).app/Contents/MacOS/OpenComputerUse"
10
10
  "${plugin_root}/OpenComputerUse.app/Contents/MacOS/OpenComputerUse"
11
+ "${plugin_root}/open-computer-use"
12
+ "${plugin_root}/open-computer-use.exe"
11
13
  "${repo_root}/dist/Open Computer Use (Dev).app/Contents/MacOS/OpenComputerUse"
12
14
  "${repo_root}/dist/Open Computer Use.app/Contents/MacOS/OpenComputerUse"
13
15
  "${repo_root}/dist/OpenComputerUse.app/Contents/MacOS/OpenComputerUse"
16
+ "${repo_root}/dist/linux/arm64/open-computer-use"
17
+ "${repo_root}/dist/linux/amd64/open-computer-use"
18
+ "${repo_root}/dist/windows/arm64/open-computer-use.exe"
19
+ "${repo_root}/dist/windows/amd64/open-computer-use.exe"
14
20
  )
15
21
 
16
22
  for app_binary in "${candidate_binaries[@]}"; do
@@ -24,10 +30,15 @@ for app_binary in "${candidate_binaries[@]}"; do
24
30
  fi
25
31
  done
26
32
 
27
- echo "open-computer-use could not find a runnable app bundle." >&2
33
+ if command -v open-computer-use >/dev/null 2>&1; then
34
+ exec open-computer-use mcp
35
+ fi
36
+
37
+ echo "open-computer-use could not find a runnable native runtime." >&2
28
38
  echo "Checked:" >&2
29
39
  for app_binary in "${candidate_binaries[@]}"; do
30
40
  echo " - ${app_binary}" >&2
31
41
  done
42
+ echo " - open-computer-use on PATH" >&2
32
43
  echo "Run ./scripts/install-codex-plugin.sh to populate the Codex plugin cache." >&2
33
44
  exit 1
@@ -10,10 +10,24 @@ marketplace_name="open-computer-use-local"
10
10
  plugin_name="open-computer-use"
11
11
  plugin_source_root="${repo_root}/plugins/${plugin_name}"
12
12
  plugin_manifest="${plugin_source_root}/.codex-plugin/plugin.json"
13
- build_script="${repo_root}/scripts/build-open-computer-use-app.sh"
13
+ macos_build_script="${repo_root}/scripts/build-open-computer-use-app.sh"
14
+ linux_build_script="${repo_root}/scripts/build-open-computer-use-linux.sh"
15
+ windows_build_script="${repo_root}/scripts/build-open-computer-use-windows.sh"
14
16
  configuration="debug"
15
17
  rebuild="false"
16
18
 
19
+ node_arch() {
20
+ node -p "process.arch" 2>/dev/null || true
21
+ }
22
+
23
+ go_arch_for_node_arch() {
24
+ case "$1" in
25
+ arm64) printf '%s\n' "arm64" ;;
26
+ x64) printf '%s\n' "amd64" ;;
27
+ *) return 1 ;;
28
+ esac
29
+ }
30
+
17
31
  resolve_app_bundle() {
18
32
  local -a candidates
19
33
 
@@ -24,8 +38,39 @@ resolve_app_bundle() {
24
38
  fi
25
39
 
26
40
  for bundle_name in "${candidates[@]}"; do
27
- local candidate="${repo_root}/dist/${bundle_name}"
28
- if [[ -d "${candidate}" ]]; then
41
+ for candidate in "${repo_root}/dist/${bundle_name}"; do
42
+ if [[ -d "${candidate}" ]]; then
43
+ printf '%s\n' "${candidate}"
44
+ return 0
45
+ fi
46
+ done
47
+ done
48
+
49
+ return 1
50
+ }
51
+
52
+ resolve_native_binary() {
53
+ local platform="$1"
54
+ local arch="$2"
55
+ local go_arch
56
+ go_arch="$(go_arch_for_node_arch "${arch}" || true)"
57
+ local -a candidates=()
58
+
59
+ case "${platform}" in
60
+ linux)
61
+ if [[ -n "${go_arch}" ]]; then
62
+ candidates+=("${repo_root}/dist/linux/${go_arch}/open-computer-use")
63
+ fi
64
+ ;;
65
+ win32)
66
+ if [[ -n "${go_arch}" ]]; then
67
+ candidates+=("${repo_root}/dist/windows/${go_arch}/open-computer-use.exe")
68
+ fi
69
+ ;;
70
+ esac
71
+
72
+ for candidate in "${candidates[@]}"; do
73
+ if [[ -x "${candidate}" ]]; then
29
74
  printf '%s\n' "${candidate}"
30
75
  return 0
31
76
  fi
@@ -56,16 +101,81 @@ while [[ $# -gt 0 ]]; do
56
101
  esac
57
102
  done
58
103
 
59
- app_bundle="$(resolve_app_bundle || true)"
60
- app_binary="${app_bundle:+${app_bundle}/Contents/MacOS/OpenComputerUse}"
104
+ platform="$(node -p "process.platform")"
105
+ arch="$(node_arch)"
106
+ payload_path=""
107
+
108
+ case "${platform}" in
109
+ darwin)
110
+ payload_path="$(resolve_app_bundle || true)"
111
+ app_binary="${payload_path:+${payload_path}/Contents/MacOS/OpenComputerUse}"
112
+ if [[ "${rebuild}" == "true" || -z "${app_binary}" || ! -x "${app_binary}" ]]; then
113
+ if [[ -x "${macos_build_script}" ]]; then
114
+ "${macos_build_script}" "${configuration}"
115
+ payload_path="$(resolve_app_bundle || true)"
116
+ app_binary="${payload_path:+${payload_path}/Contents/MacOS/OpenComputerUse}"
117
+ else
118
+ echo "Missing runnable app bundle at ${app_binary} and no local build script is available." >&2
119
+ exit 1
120
+ fi
121
+ fi
122
+ if [[ -z "${payload_path}" || ! -x "${app_binary}" ]]; then
123
+ echo "Missing runnable app binary at ${app_binary}" >&2
124
+ exit 1
125
+ fi
126
+ ;;
127
+ linux)
128
+ payload_path="$(resolve_native_binary linux "${arch}" || true)"
129
+ if [[ "${rebuild}" == "true" || -z "${payload_path}" || ! -x "${payload_path}" ]]; then
130
+ go_arch="$(go_arch_for_node_arch "${arch}" || true)"
131
+ if [[ -n "${go_arch}" && -x "${linux_build_script}" ]]; then
132
+ "${linux_build_script}" --configuration "${configuration}" --arch "${go_arch}"
133
+ payload_path="$(resolve_native_binary linux "${arch}" || true)"
134
+ fi
135
+ fi
136
+ if [[ -z "${payload_path}" || ! -x "${payload_path}" ]]; then
137
+ echo "Missing runnable Linux binary for ${platform}-${arch}." >&2
138
+ exit 1
139
+ fi
140
+ ;;
141
+ win32)
142
+ payload_path="$(resolve_native_binary win32 "${arch}" || true)"
143
+ if [[ "${rebuild}" == "true" || -z "${payload_path}" || ! -x "${payload_path}" ]]; then
144
+ go_arch="$(go_arch_for_node_arch "${arch}" || true)"
145
+ if [[ -n "${go_arch}" && -x "${windows_build_script}" ]]; then
146
+ "${windows_build_script}" --configuration "${configuration}" --arch "${go_arch}"
147
+ payload_path="$(resolve_native_binary win32 "${arch}" || true)"
148
+ fi
149
+ fi
150
+ if [[ -z "${payload_path}" || ! -x "${payload_path}" ]]; then
151
+ echo "Missing runnable Windows binary for ${platform}-${arch}." >&2
152
+ exit 1
153
+ fi
154
+ ;;
155
+ *)
156
+ echo "Unsupported Codex plugin install platform: ${platform}-${arch}" >&2
157
+ exit 1
158
+ ;;
159
+ esac
61
160
 
62
- if [[ "${rebuild}" == "true" || -z "${app_binary}" || ! -x "${app_binary}" ]]; then
63
- if [[ -x "${build_script}" ]]; then
64
- "${build_script}" "${configuration}"
65
- app_bundle="$(resolve_app_bundle || true)"
66
- app_binary="${app_bundle:+${app_bundle}/Contents/MacOS/OpenComputerUse}"
67
- else
68
- echo "Missing runnable app bundle at ${app_binary} and no local build script is available." >&2
161
+ if [[ -z "${payload_path}" ]]; then
162
+ echo "Failed to resolve native runtime payload for ${platform}-${arch}" >&2
163
+ exit 1
164
+ fi
165
+
166
+ if [[ ! -e "${payload_path}" ]]; then
167
+ echo "Missing native runtime payload at ${payload_path}" >&2
168
+ exit 1
169
+ fi
170
+
171
+ if [[ ! -d "${payload_path}" && ! -x "${payload_path}" ]]; then
172
+ echo "Native runtime payload is not executable: ${payload_path}" >&2
173
+ exit 1
174
+ fi
175
+
176
+ if [[ "${platform}" != "darwin" ]]; then
177
+ if [[ ! -x "${payload_path}" ]]; then
178
+ echo "Native runtime payload is not executable: ${payload_path}" >&2
69
179
  exit 1
70
180
  fi
71
181
  fi
@@ -80,11 +190,6 @@ if [[ ! -f "${plugin_manifest}" ]]; then
80
190
  exit 1
81
191
  fi
82
192
 
83
- if [[ -z "${app_bundle}" || ! -x "${app_binary}" ]]; then
84
- echo "Missing runnable app binary at ${app_binary}" >&2
85
- exit 1
86
- fi
87
-
88
193
  plugin_version="$(node "${config_helper}" codex-plugin-version "${plugin_manifest}")"
89
194
 
90
195
  if [[ -z "${plugin_version}" ]]; then
@@ -99,7 +204,7 @@ mkdir -p "${codex_home}" "${plugin_cache_root}"
99
204
  rm -rf "${plugin_install_root}"
100
205
  mkdir -p "${plugin_install_root}"
101
206
 
102
- node "${config_helper}" copy-into-dir "${plugin_install_root}" "${plugin_source_root}" "${app_bundle}"
207
+ node "${config_helper}" copy-into-dir "${plugin_install_root}" "${plugin_source_root}" "${payload_path}"
103
208
 
104
209
  node "${config_helper}" codex-plugin-config "${config_path}" "${repo_root}" "${marketplace_name}" "${plugin_name}"
105
210