bx-mac 1.5.1 → 1.6.1
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 +20 -2
- package/dist/bx.js +8 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -166,7 +166,6 @@ App definitions in TOML format. Each `[<name>]` section becomes a CLI mode — u
|
|
|
166
166
|
[cursor]
|
|
167
167
|
bundle = "com.todesktop.230313mzl4w4u92"
|
|
168
168
|
binary = "Contents/MacOS/Cursor"
|
|
169
|
-
args = ["--no-sandbox"]
|
|
170
169
|
|
|
171
170
|
# Add Zed (explicit path, no discovery)
|
|
172
171
|
[zed]
|
|
@@ -177,6 +176,8 @@ path = "/Applications/Zed.app/Contents/MacOS/zed"
|
|
|
177
176
|
path = "/usr/local/bin/code"
|
|
178
177
|
```
|
|
179
178
|
|
|
179
|
+
**Electron apps:** bx automatically detects Electron-based apps (by checking for `Electron Framework.framework` inside the `.app` bundle) and adds `--no-sandbox` to disable Chromium's internal sandbox, which conflicts with `sandbox-exec`. No manual `args = ["--no-sandbox"]` needed.
|
|
180
|
+
|
|
180
181
|
| Field | Description |
|
|
181
182
|
| --- | --- |
|
|
182
183
|
| `mode` | Inherit from another app (e.g. `"code"`, `"cursor"`) — only `paths` / overrides needed |
|
|
@@ -361,7 +362,8 @@ bx detects and prevents problematic scenarios:
|
|
|
361
362
|
- **🔄 Sandbox nesting:** If `CODEBOX_SANDBOX=1` is set (auto-propagated), bx refuses to start — nested sandboxes cause silent failures.
|
|
362
363
|
- **🔍 Unknown sandbox:** On startup, bx probes `~/Documents`, `~/Desktop`, `~/Downloads`. If any return `EPERM`, another sandbox is active — bx aborts.
|
|
363
364
|
- **⚠️ VSCode terminal:** If `VSCODE_PID` is set, bx warns that it will launch a *new* instance, not sandbox the current one.
|
|
364
|
-
- **🧩 App already sandboxed:** For GUI app modes, bx inspects app entitlements (best effort) and warns if Apple App Sandbox is enabled, since
|
|
365
|
+
- **🧩 App already sandboxed:** For GUI app modes, bx inspects app entitlements (best effort) and warns if Apple App Sandbox is enabled, since bx's `sandbox-exec` wrapper may not apply correctly when the app is already sandboxed by macOS.
|
|
366
|
+
- **⚡ Electron auto-detection:** bx detects Electron-based apps (by checking for `Electron Framework.framework` in the `.app` bundle) and automatically adds `--no-sandbox` to disable Chromium's internal sandbox, which conflicts with `sandbox-exec`. This works for VSCode, Cursor, Windsurf, and any other Electron app.
|
|
365
367
|
- **🔁 App already running:** If the target app is already running, bx warns that the new workspace would open in the existing (unsandboxed) instance and asks for confirmation. This is important because Electron apps like VSCode, Cursor, etc. always reuse the running process — `sandbox-exec` has no effect on the already-running instance.
|
|
366
368
|
|
|
367
369
|
### Single-instance apps
|
|
@@ -394,6 +396,22 @@ ls ~/work/other-project/ # ❌ Operation not permitted
|
|
|
394
396
|
cat ./src/index.ts # ✅ Works!
|
|
395
397
|
```
|
|
396
398
|
|
|
399
|
+
**Drag and drop from `~/Downloads` (or other blocked dirs)** — if dragging files from Finder into a sandboxed app fails silently, the source folder is blocked. Grant read-only access by adding it to `~/.bxignore`:
|
|
400
|
+
|
|
401
|
+
```gitignore
|
|
402
|
+
ro:Downloads
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
The app can then read (and copy) the dragged file, but not modify the original. Same trick works for `ro:Desktop`, `ro:Documents`, etc.
|
|
406
|
+
|
|
407
|
+
**`npm install` fails with auth or registry errors** — `.npmrc` is blocked by default (may contain tokens). If your install needs the registry config but not write access, expose it read-only:
|
|
408
|
+
|
|
409
|
+
```gitignore
|
|
410
|
+
ro:.npmrc
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
Same pattern applies to other tools whose config dotfiles are on the protected list (`.pypirc`, ...).
|
|
414
|
+
|
|
397
415
|
## ⚠️ Known limitations
|
|
398
416
|
|
|
399
417
|
- **⚠️ Sandbox profile is static:** The sandbox rules are generated **once at launch** by scanning the current state of `$HOME`. Directories or files created **after** the sandbox starts are **not protected** — for example, if a tool creates `~/new-project/` while the sandbox is running, that directory will be fully accessible. Similarly, project-level `.bxignore` patterns only match files that exist at launch time; files matching a blocked pattern (e.g. `.env`) that are created later will **not** be denied. Re-run `bx` to pick up changes.
|
package/dist/bx.js
CHANGED
|
@@ -1483,6 +1483,11 @@ function executableFromBundle(bundlePath, app) {
|
|
|
1483
1483
|
if (app.binary) return join(bundlePath, app.binary);
|
|
1484
1484
|
return join(bundlePath, "Contents", "MacOS", basename(bundlePath, ".app"));
|
|
1485
1485
|
}
|
|
1486
|
+
function isElectronApp(resolvedPath) {
|
|
1487
|
+
const bundle = appBundleFromPath(resolvedPath);
|
|
1488
|
+
if (!bundle) return false;
|
|
1489
|
+
return existsSync(join(bundle, "Contents", "Frameworks", "Electron Framework.framework"));
|
|
1490
|
+
}
|
|
1486
1491
|
const SANDBOX_KEY = "com.apple.security.app-sandbox";
|
|
1487
1492
|
function hasAppSandboxEntitlement(entitlements) {
|
|
1488
1493
|
if (new RegExp(`<key>\\s*${SANDBOX_KEY.replace(/\./g, "\\.")}\\s*</key>\\s*<true\\s*/>`, "i").test(entitlements)) return true;
|
|
@@ -1565,6 +1570,7 @@ function buildAppCommand(mode, workDirs, home, profileSandbox, appArgs, apps) {
|
|
|
1565
1570
|
args.push("--extensions-dir", join(dataDir, "extensions"));
|
|
1566
1571
|
}
|
|
1567
1572
|
if (app.args) args.push(...app.args);
|
|
1573
|
+
if (!args.includes("--no-sandbox") && isElectronApp(resolvedPath)) args.push("--no-sandbox");
|
|
1568
1574
|
if (appArgs.length > 0) args.push(...appArgs);
|
|
1569
1575
|
args.push(...getPassPaths(app, workDirs, home));
|
|
1570
1576
|
return {
|
|
@@ -1609,7 +1615,7 @@ function getNestedSandboxWarning(mode, apps) {
|
|
|
1609
1615
|
"pipe",
|
|
1610
1616
|
"pipe"
|
|
1611
1617
|
]
|
|
1612
|
-
}))) return
|
|
1618
|
+
}))) return `"${mode}" has Apple App Sandbox enabled — bx sandbox may not apply correctly`;
|
|
1613
1619
|
} catch {}
|
|
1614
1620
|
return null;
|
|
1615
1621
|
}
|
|
@@ -1773,7 +1779,7 @@ function printDryRunTree({ home, blockedDirs, ignoredPaths, readOnlyDirs, workDi
|
|
|
1773
1779
|
}
|
|
1774
1780
|
//#endregion
|
|
1775
1781
|
//#region src/index.ts
|
|
1776
|
-
const VERSION = "1.
|
|
1782
|
+
const VERSION = "1.6.1";
|
|
1777
1783
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
1778
1784
|
if (process$1.argv.includes("--version") || process$1.argv.includes("-v")) {
|
|
1779
1785
|
console.log(`bx ${VERSION}`);
|