Reading or using an app without 輔助使用 asks for it and says so in words (it answered PERM_DENIED and asked nobody)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
王性驊 2026-11-05 18:50:08 +08:00
parent d52def0f46
commit 60f4fa7411
1 changed files with 23 additions and 1 deletions

View File

@ -430,6 +430,20 @@ pub fn ask_permission(pane: &str) {
let _ = spawn_reaped(&mut std::process::Command::new("open").arg(format!("x-apple.systempreferences:com.apple.preference.security?{pane}"))); let _ = spawn_reaped(&mut std::process::Command::new("open").arg(format!("x-apple.systempreferences:com.apple.preference.security?{pane}")));
} }
const NO_ACCESSIBILITY: &str = "macOS 還沒讓 AnyBot 使用「輔助使用」,所以讀不到、也按不了這台電腦上的 App。這台電腦上已經跳出詢問並打開「系統設定 → 隱私權與安全性 → 輔助使用」:請使用者把 AnyBot 打開(只要一次),再叫我試一次。";
/// agent-desktop's PERM_DENIED (no 輔助使用), as words the bot can pass on — and the person asked.
fn plain_permission_words(t: String) -> String {
if !t.contains("PERM_DENIED") {
return t;
}
ask_permission("Privacy_Accessibility");
match t.split_once(",但讀不到它的畫面") {
Some((opened, _)) => format!("{opened},但讀不到它的畫面:{NO_ACCESSIBILITY}"),
None => NO_ACCESSIBILITY.to_string(),
}
}
/// The app a shown name stands for (「計算機」 → Calculator), from the apps' display names. /// The app a shown name stands for (「計算機」 → Calculator), from the apps' display names.
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
fn app_named(name: &str) -> Option<String> { fn app_named(name: &str) -> Option<String> {
@ -503,8 +517,16 @@ fn run_inner(name: &str, v: &Value) -> Result<(String, Option<String>), String>
return Err("使用者正在自己操作這台電腦(已取得控制權)。請等他交還控制權後再操作。".into()); return Err("使用者正在自己操作這台電腦(已取得控制權)。請等他交還控制權後再操作。".into());
} }
} }
// Reading and using apps by their controls needs 輔助使用: without it macOS answers
// PERM_DENIED and nobody was asked. Ask (prompt + the Settings pane, now and then) and say it
// plainly; opening an app still opens it.
let by_controls = name == "computer_use_read_app" || run_text_mode_name(name, v).is_some();
if cfg!(target_os = "macos") && by_controls && name != "computer_use_open_app" && !crate::axread::trusted(false) {
ask_permission("Privacy_Accessibility");
return Err(NO_ACCESSIBILITY.into());
}
if let Some(r) = run_text_mode(name, v) { if let Some(r) = run_text_mode(name, v) {
return r; return r.map(|(t, img)| (plain_permission_words(t), img)).map_err(plain_permission_words);
} }
if !cfg!(any(target_os = "macos", target_os = "linux")) { if !cfg!(any(target_os = "macos", target_os = "linux")) {
return Err("操作畫面只支援 macOS 和 Linux".into()); return Err("操作畫面只支援 macOS 和 Linux".into());