Skip to content

feat(computer-use): ask for missing macOS permissions in the conversation - #6588

Merged
M4n5ter merged 12 commits into
rust-previewfrom
feat/cua-permission-card
Nov 3, 2026
Merged

M4n5ter merged 12 commits into
rust-previewfrom
feat/cua-permission-card

Conversation

@UncertaintyDeterminesYou4ndMe

@UncertaintyDeterminesYou4ndMe UncertaintyDeterminesYou4ndMe commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #6582 and #6587.

When a Computer Use operation needs Accessibility or Screen Recording and the Host lacks the required grant, the Host asks macOS to show its own request and then shows a System permission request card in the conversation:

  • The card names the missing grants and has one button per grant that opens the matching System Settings pane.
  • While the card is open, the Host checks the grants again every 1.5 s. Once they are on, the tool call continues by itself, with no retry and no Host restart.
  • Cancel request fails the call with the permission_required lines from fix(computer-use): report missing macOS permissions before native work #6582. The REPL stays usable.
  • With request_permissions off, the call fails at once with the same lines, as before.

To grant ahead of an unattended run, ask for one screenshot first. The card appears, and once granted the permissions persist.

Choices the diff does not explain on its own:

  • A new interaction kind, system_permission. The user can only cancel it (system_permission_cancel becomes a producer_cancelled closure). Only the producer commits system_permission_granted. A user answer cannot claim the grants are on, because the operating system decides that. Like computer_app, it cannot time out: the cell timeout is suspended while the card waits.
  • A cancel stands. If the grants arrive just as the user cancels, the call still fails, so the card and the call agree.
  • One card per native command. The request id includes the per-command operation id, as computer_app approvals do. Concurrent commands in one cell each get their own card instead of conflicting.
  • No Settings section. The grants are requested where they are needed. A status display could not be trusted anyway, because a running process cannot observe a revoked Accessibility grant.
  • ACP. Clients get a permission prompt whose only option is Cancel, titled " needs Accessibility and Screen Recording". Choosing it or dismissing it cancels. When an interaction settles without the client, for example because the Host saw the grants arrive, the client callback is now dropped. The session therefore returns to Running instead of holding RequiresAction and a callback slot. ACP cannot withdraw a prompt, so the client's dialog itself stays open until dismissed.

Review follow-up

Permissions are selected for the actual command: documentation, browser setup, inventory and cursor configuration do not wait for unrelated native grants; native observation requires Accessibility and Screen Recording, and audio start requires Screen Recording. Permission-result persistence failures now propagate through the existing withdrawal path. ACP no longer imposes the unrelated five-minute response deadline or fixed interaction-count limits. The arbitrary application-name length limit and its fixed-number assertion are removed, and generated schemas are updated. The branch includes the updated lower PRs and latest rust-preview.

AI use

  • Generative tooling made a substantive contribution

Tool(s) and scope: Claude Code wrote the change and this description and drove the live checks on macOS 26.6; the commit carries Co-Authored-By: Claude Opus 5.5. Codex implemented the review follow-up fixes.

Native Computer Use on macOS needs Accessibility and Screen Recording,
which macOS grants to the application that started the Host. Without
them the first AX call failed with an opaque -25211 deep inside a tool.

Check both grants before native work, ask macOS to show its request
the first time one is missing, and fail with a single
permission_required: line naming the application to allow. The check
is a real call (an AX query to this user's Dock, a ScreenCaptureKit
listing), because AXIsProcessTrusted and CGPreflightScreenCaptureAccess
keep their first answer in a Host without a run loop; a grant the user
turns on is seen by the next call without restarting the Host. A
confirmed grant is remembered, and failures that a missing grant
explains (AX -25211, a refused ScreenCaptureKit listing) check again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
macOS grants privacy permissions such as Accessibility and Screen
Recording to the application responsible for a process. The Host
belonged to whichever application started it first: Maka, or the
terminal a CLI ran in. Users had to find and allow that application,
and a grant could follow the wrong one.

Maka.app now carries Helpers/Maka Host.app. Its executable starts
itself again with responsibility disclaimed and runs the Host, passing
stdio through, forwarding termination signals and returning the Host's
status. Interactive, activation and launchd starts run the Host through
it, so its grants belong to "Maka Host".

macOS ties a grant to the bytes of the helper's executable, and each
package lives in a directory of its own. The helper is therefore copied
once into the account data directory and replaced only when a package
carries a higher bundle version. Without a helper, the Host runs
directly as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tion

When native Computer Use needs Accessibility or Screen Recording and the
Host lacks it, the Host asks macOS to show its request and then shows a
System permission request card in the conversation. The card names the
missing grants and opens the matching System Settings pane. The Host
checks the grants every 1.5 s while the card is open and continues the
tool call as soon as they are on, with no retry and no restart.
Cancelling the card fails the call with the permission_required lines.
With request_permissions off, the call fails at once as before.

The new system_permission interaction can only be cancelled by the
user; only its producer commits SystemPermissionGranted, and it cannot
time out. ACP clients get a prompt whose only option is Cancel, and a
prompt whose interaction settles elsewhere no longer holds the session
in RequiresAction.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep permission waits cancellable without arbitrary ACP deadlines or count limits. Propagate producer outcome persistence failures through the existing cleanup path.

Generated-by: Codex

@M4n5ter M4n5ter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

English

The review fixes are pushed in b3c4b55a6. This branch includes the updated #6582/#6587 and the latest rust-preview, with no merge conflicts.

  • Request permissions for the actual operation. Documentation, browser setup, inventory and cursor configuration no longer wait for unrelated native grants. Native observation requests Accessibility and Screen Recording; audio start requests Screen Recording, and stopping audio does not open a permission card.
  • Keep human permission waits cancellable without an arbitrary deadline. Removed ACP's five-minute response timeout and its fixed 16-callback/1,024-interaction limits. Connection shutdown and cancellation still end the wait.
  • Propagate persistence failures. A failed producer outcome write now follows the existing withdrawal/cleanup path, preserving the error cause, instead of stopping detection and waiting for an outcome that was never committed.
  • Remove the unsupported application-name cap. Removed the 256-character limit, its fixed-number rejection assertion and the corresponding generated schema constraint. Added a focused regression test for browser setup/documentation, with native app binding and audio permission requirements as positive controls.

Validation: related nextest tests 6/6, packaging tests 9/9, compilation, Clippy with warnings denied, SDK type checking and generated-schema consistency checks all passed locally. The macOS permission flow was not exercised on this WSL machine. The new GitHub CI run is currently queued.

简体中文

已在 b3c4b55a6 补上评审中的修复。该分支已包含更新后的 #6582/#6587 和最新 rust-preview,没有合并冲突。

  • 按实际操作请求权限。 文档、浏览器初始化、清单查询和光标配置不再等待无关的原生权限。原生观察请求 Accessibility 和 Screen Recording;启动音频录制只请求 Screen Recording,停止录制不会弹出权限卡片。
  • 用户授权等待保留取消能力,不设置任意期限。 删除 ACP 的五分钟响应超时,以及固定的 16 个回调、1024 条交互上限。连接关闭和取消仍会结束等待。
  • 传播持久化错误。 producer 写入授权结果失败时,保留错误原因并走已有的撤回与清理路径,不再停止检测后等待一个从未成功写入的结果。
  • 删除没有依据的应用名上限。 移除 256 字符限制、固化该数字的拒绝断言及对应生成 schema 约束。补了一个针对浏览器初始化和文档读取的回归测试,并用原生应用绑定、音频所需权限作为正向对照。

验证:相关 nextest 测试 6/6、打包测试 9/9,编译、Clippy(警告视为错误)、SDK 类型检查和生成 schema 一致性检查均通过。WSL 下未实测 macOS 授权流程。新的 GitHub CI 目前仍在排队。

@github-actions github-actions Bot added the effort/XXL Over 2500 readable lines label Nov 3, 2026
@M4n5ter
M4n5ter merged commit 6ef382b into rust-preview Nov 3, 2026
11 checks passed
@M4n5ter
M4n5ter deleted the feat/cua-permission-card branch November 3, 2026 04:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/XXL Over 2500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants