Communitygithub.com

iwishwp/AgentOS

操作 AgentOS 桌面(niri/Wayland):窗口與工作區管理、GUI 應用無障礙操作、瀏覽器自動化、檔案產物、桌面通知與呈現。任何掛載了 AgentOS 八個 MCP 擴展(niri/desktop/system/files/session/a11y/browser/cred)的 agent 框架均可使用。涉及「操作用戶桌面上的應用/窗口/檔案/通知」時使用。

AgentOS 是什麼?

AgentOS 是一個桌面操作技能,專為 AI 代理(如 Claude Code、Cursor、Goose 等)設計,使其能夠透過 MCP 協定控制基於 Wayland 的 Linux 桌面環境(niri 合成器)。它將桌面操作分為四個層級:L0(系統層,最穩定)、L1(無障礙樹,無需焦點即可操作 GUI 應用)、L2(瀏覽器 CDP,用於網頁自動化)和 L3(視覺/輸入備援)。技能提供八個 MCP 擴展:niri(窗口/工作區管理)、desktop(通知/剪貼板/確認對話框)、system(系統查詢)、files(安全檔案沙箱)、session(獨立的代理專用視窗會話)、a11y(無障礙樹操作)、browser(無頭 Chromium 網頁自動化)和 cred(安全憑證管理)。它特別強調穩定性,建議優先使用 L0 系統層,並提供了完整的環境陷阱排查指南。

相容平台✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/iwishwp/AgentOS/tree/HEAD/skills/agentos-desktop

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

AgentOS 桌面操作手冊(任何 agent 通用)

本手冊自包含:只要你的框架能掛 stdio MCP server(goose / Claude Code / Z Code / Cursor 等), 按 §1 掛載後即可獲得下面全部能力。所有條目均真機實測(Fedora + niri Wayland, 2026-10 端到端證據見倉庫 docs/capabilities.md)。

0. 心智模型:四層能力,按優先級降級

  1. L0 系統層——窗口/工作區/啟動/檔案/通知/剪貼板(niri/desktop/system/files 擴展):最穩,優先用;
  2. L1 無障礙樹——GUI 應用內按名稱點擊/讀寫文字(a11y 擴展,AT-SPI2):無需焦點、不打擾用戶, GTK3/GTK4/Qt 實測全通(Qt 的全局開關與 Chromium 的 toolkit-accessibility 已是系統默認, 2026-10-18 起);Chromium 樹讀/文字輸入可達(頁面點擊走 L2);Java 未裝(路徑見 capabilities.md 附錄 B);純 X11 應用(xterm 類)無樹,只能 L3;
  3. L2 瀏覽器 CDP——網頁一切操作(browser 擴展,agent 專屬無頭 Chromium);
  4. L3 視覺/輸入兜底——grim 截圖(可靠)、鍵盤注入(scripts/kb-inject.sh:wtype 用戶級 為主力,文字/組合鍵可靠;控制鍵(Enter/Tab)回落 ydotool 需 sudo)、指針注入(不可靠: 加速度下漂移,只作最後手段)。

遇到「打不開/打不好」的應用:先想是不是 L1 前置條件沒滿足(a11y 開關),再用 L3 截圖看真實狀態, 不要盲目重試。

1. 掛載(一次性)

goose(~/.config/goose/config.yaml,1.54 實測格式;name: 字段必填,缺了整條擴展被靜默丟棄):

extensions:
  niri:
    type: stdio
    name: niri
    enabled: true
    cmd: /path/to/AgentOS/scripts/env/with-niri-env.sh
    args: []
    env_keys: []
    envs: {}
    timeout: 300          # 單位秒
  # desktop/system/files/session/a11y/browser/cred 同構,
  # cmd 分別用 with-desktop-env.sh / with-system-env.sh / ... (scripts/env/ 下八個啟動器)

其他框架(Claude Code / Z Code 等 mcpServers JSON 風格):

{
  "mcpServers": {
    "niri":    { "command": "/path/to/AgentOS/scripts/env/with-niri-env.sh" },
    "desktop": { "command": "/path/to/AgentOS/scripts/env/with-desktop-env.sh" },
    "system":  { "command": "/path/to/AgentOS/scripts/env/with-system-env.sh" },
    "files":   { "command": "/path/to/AgentOS/scripts/env/with-files-env.sh" },
    "session": { "command": "/path/to/AgentOS/scripts/env/with-session-env.sh" },
    "a11y":    { "command": "/path/to/AgentOS/scripts/env/with-atspi-env.sh" },
    "browser": { "command": "/path/to/AgentOS/scripts/env/with-browser-env.sh" },
    "cred":    { "command": "/path/to/AgentOS/scripts/env/with-cred-env.sh" }
  }
}

要點:

  • 用啟動器腳本,不要直接指 node dist/index.js——啟動器負責發現 niri IPC socket (路徑含 compositor PID,每次會話不同,如 /run/user/1000/niri.wayland-1.2762.sock)和補齊 Wayland/dbus 環境(XDG_RUNTIME_DIR/WAYLAND_DISPLAY/DBUS_SESSION_BUS_ADDRESS), 從 SSH/服務環境拉起時工具才可用;
  • 手測啟動器:timeout 2 scripts/env/with-niri-env.sh </dev/null,exit 0 即正常;
  • 前置:Node ≥ 20、倉庫已 npm install && npm run build、運行在 niri 圖形會話所屬用戶下。

2. 工具速查(按擴展分組,工具名 = <擴展>__<工具>)

niri —— 窗口/工作區/啟動(L0)

工具用途關鍵參數
list_windows列所有窗口(id/app_id/標題/工作區/焦點)—
list_workspaces列工作區(idx 序號 與 id 是兩個東西,move 用序號或名稱)—
list_outputs列顯示器—
focus_window切前台聚焦(會切用戶視角,慎用)id
focus_workspace切工作區(會切用戶視角)reference: "3" 或名稱
move_window_to_workspace移窗口(不搶焦點,整理用)id?(缺省=聚焦窗)、reference
close_window關窗口id?
open_app在用戶桌面啟動程式command: 陣列,如 ["ghostty"]

a11y —— GUI 應用內操作(L1,AT-SPI2)

工具用途關鍵參數
a11y_list_apps列無障礙總線上註冊的應用—
a11y_dump_tree倒某應用的無障礙樹(找按鈕名/結構)app
a11y_click按 accessible 名稱點擊(無需焦點不打擾用戶)app、buttonName
a11y_read_texts讀應用全部非空文字(顯示屏/結果/標籤)app
a11y_set_text按節點名寫文字框app、match(名稱子串,缺省 * 第一個)、text

實測紀律:按名稱尋址,不要按樹索引(樹結構跨 AT 連接會重建);GTK4 的樹要等 AT 客戶端 註冊後才完整;同名多實例時橋解析到先註冊者——先讀文字對狀態判別實例,必要時關掉多餘實例。 Chromium 例外注意:樹懶構建(橋自動觸發,首次 dump 多等 1-2 秒屬正常);寫文字框用 "grabFocus + kb-inject type"組合(Chromium 的 entry 不吃 setTextContents);頁面按鈕點擊 不生效(doAction 派發但 onclick 不跑),頁面操作一律走 browser 擴展。

browser —— 網頁操作(L2,agent 專屬無頭 Chromium)

工具用途關鍵參數
browser_open導航(首次調用自動拉起瀏覽器)url
browser_eval頁面內執行 JS,填表/點擊/讀內容全靠它JS 代碼
browser_screenshot截圖(瀏覽器無頭,視覺全靠它)—

填表標準動作:el.value = "..." 後必須 el.dispatchEvent(new Event("input", {bubbles: true})), 否則現代框架收不到輸入。遇驗證碼:停下告知用戶,絕不自動繞過。

files —— 檔案沙箱(L0,根 = ~/Agent/,路徑都寫相對)

工具用途關鍵參數
read_file / write_file讀寫文字(自動建父目錄)path、content
list_dir / create_dir列目錄/建目錄path
move / delete移動 / 刪(進 .trash 可恢復,別用 shell rm)source/dest、path
find_by_name按名找檔案pattern
downloadhttp(s) 下載進沙箱(≤50MB / 60s,別用 shell curl)url、path

desktop —— 呈現/通知/剪貼板/確認(L0)

工具用途關鍵參數
open打開產物:URL 或檔案;office 文檔必須帶 app: "libreoffice"(白名單,系統 MIME 關聯不可靠)target、app?
notify桌面通知(三檔見 §3)summary(必填)、body、urgency、action?
confirm向用戶請示/要決策(T1 四橫幅:允許/會話允許/拒絕/永不,30s 無應答=拒絕)summary(不放敏感內容)、tier?(t1/t2,影響文案)
clipboard_read / clipboard_write剪貼板讀寫—

session —— 水族館(agent 專屬嵌套 niri 會話,GUI 活都在這幹)

工具用途
agent_session_start / agent_session_stop / agent_session_status嵌套會話生命週期(桌面上出現一個可圍觀的窗口)
agent_open_app在水族館裡啟動應用(如 gnome-calculator、chromium)
agent_list_windows列水族館內窗口
agent_screenshot定向截水族館內部(grim)

system —— 系統查詢(L0 唯讀全放行)

system_status / list_services / service_status / journal / network_info / list_packages / package_info / package_install(T2 強確認:彈 polkit 密碼框,需人在; 無頭跑必 300s 逾時拒絕——別在無人值守時調)。

cred —— 憑證(agent 拿引用不拿明文)

cred_list(可用憑證及其引用/env 變數名)· cred_autofill(通道 A:頁面自動填充,明文即棄)· cred_exec(通道 B:白名單代執行+輸出打碼)· cred_inject(通道 C:短 TTL 環境變數注入, 到點整組收割)。任何需要密碼/token 的操作只走 cred,禁止向用戶索要明文。

3. 行為約定(實測有效的紀律)

  1. 產物統一落 ~/Agent/,按 downloads/ inbox/ reports/ notes/ canvas/ screenshots/ 分類; 落位即自動進 artifacts 索引(http://127.0.0.1:7788/artifacts),用戶問「我上次的報告在哪」 → 打開該頁或報相對路徑;
  2. 呈現優先級:儀表板/報告/互動內容 → 寫自包含單檔案 HTML 到 canvas/<名>/index.html 再 open 打開 http://127.0.0.1:7788/<名>/;office 文檔 → open 帶 app: "libreoffice"; 網頁 → browser 擴展;
  3. 通知三檔:完成 → notify urgency=low + action({kind:"open_path", path:"reports/x.fodt"} 或 {kind:"open_url", url:...},點通知直達產物);失敗/需盡快知道 → urgency=critical + 一句話結論 + 原因建議;要用戶決策 → 不用 notify,走 confirm(notify 沒有選擇語意)。 非同步結果一律通知,不要默默完成;
  4. 確認與分寸:不要動用戶正在用的窗口,除非明確要求(先 list_windows 認準目標); 策略拒絕(isError 且提示「策略拒絕」)時如實告知,不要繞路;GUI 操作在水族館裡做, 不搶用戶焦點;
  5. 憑證只走 cred-mcp 引用(§2 cred 表後那句紀律)。

4. 環境坑速查(全部踩過)

坑現象處置
niri IPC socket 路徑每次會話變niri msg 連不上用啟動器(自動發現 NIRI_SOCKET),別硬編碼
Chromium 鑰匙圈鎖死網路服務瀏覽器拉起即卡啟動帶 --password-store=basic(browser 擴展已內建;自己起 chromium 記得帶)
soffice 單實例鎖已開 LibreOffice 時再 open 同類文檔可能無窗/卡先確認 soffice 行程狀態;文檔打開用 app:"libreoffice" 走啟動器語意;上次異常退出還會彈 "Document Recovery" 窗口(2026-10-18 實測),列表確認窗口時別把它當成目標文檔窗
LibreOffice MIME 關聯不可靠Fedora 把 fodt 識別成 text/xml 用編輯器打開open 必須帶 app:"libreoffice"
Qt 應用不出現在 a11y 總線a11y_list_apps 看不到系統已全局開(/etc/environment 的 QT_LINUX_ACCESSIBILITY_ALWAYS_ON=1,重啟持久);仍看不到=應用啟動早於環境落位或非 Qt 官方綁定,重啟應用
Chromium/Electron a11y 樹為空dump 不出內容① 啟動帶 --force-renderer-accessibility(browser 擴展已默認帶);② toolkit-accessibility 必須在應用啟動前為 true(已全局開;後改無效,須重啟應用);③ 樹懶構建,dump 一次讓橋觸發(見 §2 a11y 紀律)
鍵盤注入選型需要打字/快捷鍵scripts/kb-inject.sh:文字與組合鍵用 wtype(用戶級);Enter/Tab 等控制鍵 wtype 對 GTK 不生效,走 ydotool(sudo);中文可能丟首字元,輸完從 a11y 樹讀回核對
水族館初始有 niri 熱鍵浮層截圖被"Important Hotkeys"遮擋注入 Esc 關閉;agent 沙箱裡連不上 ydotoold socket(root 600),借 niri__open_app 在真實桌面環境執行注入
ydotool 指針漂移絕對定位失準(libinput 加速度 ≈0.5)指針不可依賴;鍵盤注入可靠;socket 路徑注意 /tmp/.ydotool_socket vs $XDG_RUNTIME_DIR 的版本差異
GTK4 樹初始不完整dump 只有十幾個節點先 a11y_list_apps/dump 一次讓 AT 客戶端註冊,再 dump 才完整(16→105 節點實測)
無頭跑 T1/T2 確認30s/300s 無人應答自動拒絕預期行為:寫操作需要用戶在場,或測試時經 org.agentos.Confirm1.Respond 程式設計應答
裝包被 packagekitd 搶鎖dnf 偶發失敗裝前 systemctl stop packagekit(T2 helper 已處理)

5. 升級路徑(當目標應用打不開時按序嘗試)

L0(系統層,永遠先試)→ L1(a11y:GTK3/4/Qt 已默認可達;Chromium 檢查 flag 與 toolkit-accessibility 順序;第三方 Electron 按 capabilities.md 附錄 B 加 flag)→ L2(網頁類必走)→ L3 兜底(grim 看 + kb-inject 鍵盤;指針不可靠)。 仍打不開的類型:純 X11 應用(xterm 類,無樹,L3 是終點)、Java(需 JAB,路徑見 capabilities.md 附錄 B)、合成器自身 UI 只能輸入注入——詳表見倉庫 docs/capabilities.md。

相關技能