cmux next: on macOS 26, computer use runs its helper from a verified copy outside the app so screenshots work

Closed
LU
11d ago
+753-9

On macOS 26, computer use in cmux NEXT cannot take screenshots, even with "cmux Computer Use" on in Screen & System Audio Recording. tccd checks Screen Recording against the outermost app bundle that holds the executable. NEXT launches the helper from inside the app (cmux NIGHTLY.app/Contents/Library/cmux Computer Use.app), so every capture check runs as com.cmuxterm.app.nightly, and the person's toggle for com.cmuxterm.cua is never read. Accessibility checks from the same process use com.cmuxterm.cua, which is why only capture fails. Seen on 2026-10-27 on macOS 26.6 in the tccd log: the same pid, 13 ms apart, Accessibility subject=com.cmuxterm.cua authValue=2, ScreenCapture subject=com.cmuxterm.app.nightly authValue=0.

This PR runs the helper from a verified copy outside the app, as classic cmux does.

  • Copy (ComputerUseHelperStaging): copies the helper to ~/Library/Application Support/cmux/cmux-cua/helper/next-<scope>/ (legacy) or next-v2-<scope>/ (upstream helper). It removes the quarantine flag, checks the copy's signature, and moves it into place with an atomic rename. A matching copy is reused, and a changed or tampered copy is replaced.
  • Signature checks: the legacy copy must meet the release helper's Developer ID requirement. The v2 copy must meet the designated requirement of the helper in the app.
  • Running process: after launch, the app checks the running pid against the requirement it captured before staging. A mismatch stops the helper before it gets its tokens or endpoint.
  • Folders: every folder from home down to the copy must be a real directory owned by this user and not group or world writable. Symlinks are refused, and real paths are compared.
  • Races: when another launch wins the rename (EEXIST), its copy is used only if it passes the same checks. .staging-* folders older than five minutes are removed.
  • Setup tile: the "drag this app" tile in the setup names only a verified copy (ComputerUseSetup).

Changelog

  • Fixed: on macOS 26, computer use can take screenshots after Screen Recording is allowed.

Tests

  • Packages/macOS/CmuxNext/Tests/CmuxNextAppTests/ComputerUseHelperStagingTests.swift: copy made outside the app, reuse, replace on change or tamper, failed signature refused, symlinked copy, folder and ancestor refused, writable and foreign ancestor refused, a concurrent winner used only when verified, stale staging sweep, the setup tile, launch from the copy, and a swapped running helper (legacy and v2) stopped before it gets its configuration.

Observed / Not run

  • Ran locally (Xcode 26.6): swift test --package-path Packages/macOS/CmuxNext --filter 'ComputerUseHelperStagingTests|ComputerUseCursorFadeTests|ComputerUseHelperV2PeerTests': 21 passed.
  • Seen live in a tagged build with the copy (before the review fixes): computer_use.status gave screen_recording: true, tccd gave authValue=2 for com.cmuxterm.cua, and an agent clicked through Calculator with screenshots.
  • Not run live: the review fixes (running-pid check, folder checks, race, sweep). Tests only.

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.