AgentOS Desktop-Handbuch (für jeden Agenten geeignet)
Dieses Handbuch ist in sich abgeschlossen: Wenn Ihr Framework einen stdio MCP-Server einbinden kann (goose / Claude Code / Z Code / Cursor usw.), erhalten Sie nach der Einbindung gemäß §1 alle unten aufgeführten Fähigkeiten. Alle Einträge wurden an echter Hardware getestet (Fedora + niri Wayland, Ende-zu-Ende-Nachweise vom 2026-10 befinden sich im Repository unter docs/capabilities.md).
0. Geistiges Modell: Vier Fähigkeitsebenen, absteigende Priorität
- L0 Systemebene – Fenster/Arbeitsflächen/Starten/Dateien/Benachrichtigungen/Zwischenablage (niri/desktop/system/files-Erweiterungen): Am stabilsten, zuerst verwenden;
- L1 Barrierefreiheitsbaum – Innerhalb von GUI-Anwendungen per Namen klicken/Text lesen und schreiben (a11y-Erweiterung, AT-SPI2): Benötigt keinen Fokus, stört den Benutzer nicht. GTK3/GTK4/Qt wurden alle getestet (Qts globaler Schalter und Chromiums toolkit-accessibility sind seit dem 18.10.2026 systemweit standardmäßig aktiviert); Chromium-Baum-Lesen/ Texteingabe sind möglich (Klicks auf Seiten gehen über L2); Java nicht installiert (Pfad siehe capabilities.md Anhang B); Reine X11-Anwendungen (xterm-Klasse) haben keinen Baum, nur L3;
- L2 Browser CDP – Alle Webseiten-Operationen (browser-Erweiterung, agenteneigener kopfloser Chromium);
- L3 Visuelle/Eingabe-Notfall – grim-Screenshots (zuverlässig), Tastatureingabe (
scripts/kb-inject.sh: wtype auf Benutzerebene als Hauptmethode, Texte/Kombinationen zuverlässig; Steuertasten (Enter/Tab) fallen auf ydotool mit sudo zurück), Mauszeiger-Injektion (unzuverlässig: Drift unter Beschleunigung, nur letztes Mittel).
Wenn eine Anwendung „sich nicht öffnen/nicht richtig funktionieren“ will: Überlegen Sie zuerst, ob die L1-Voraussetzung nicht erfüllt ist (a11y-Schalter), und verwenden Sie dann L3-Screenshots, um den tatsächlichen Zustand zu sehen. Nicht blind wiederholen.
1. Einbindung (einmalig)
goose (~/.config/goose/config.yaml, getestetes Format ab Version 1.54; Feld name: ist erforderlich, fehlt es, wird die gesamte Erweiterung stillschweigend verworfen):
extensions:
niri:
type: stdio
name: niri
enabled: true
cmd: /pfad/zu/AgentOS/scripts/env/with-niri-env.sh
args: []
env_keys: []
envs: {}
timeout: 300 # Einheit: Sekunden
# desktop/system/files/session/a11y/browser/cred sind gleich aufgebaut,
# cmd verwendet jeweils with-desktop-env.sh / with-system-env.sh / ... (acht Starter unter scripts/env/)
Andere Frameworks (Claude Code / Z Code usw. mcpServers JSON-Stil):
{
"mcpServers": {
"niri": { "command": "/pfad/zu/AgentOS/scripts/env/with-niri-env.sh" },
"desktop": { "command": "/pfad/zu/AgentOS/scripts/env/with-desktop-env.sh" },
"system": { "command": "/pfad/zu/AgentOS/scripts/env/with-system-env.sh" },
"files": { "command": "/pfad/zu/AgentOS/scripts/env/with-files-env.sh" },
"session": { "command": "/pfad/zu/AgentOS/scripts/env/with-session-env.sh" },
"a11y": { "command": "/pfad/zu/AgentOS/scripts/env/with-atspi-env.sh" },
"browser": { "command": "/pfad/zu/AgentOS/scripts/env/with-browser-env.sh" },
"cred": { "command": "/pfad/zu/AgentOS/scripts/env/with-cred-env.sh" }
}
}
Wichtig:
- Die Startskripte verwenden, nicht direkt auf node dist/index.js verweisen – die Startskripte finden den niri IPC-Socket
(Pfad enthält die PID des Compositors, ändert sich pro Sitzung, z. B.
/run/user/1000/niri.wayland-1.2762.sock) und ergänzen die Wayland/dbus-Umgebung (XDG_RUNTIME_DIR/WAYLAND_DISPLAY/DBUS_SESSION_BUS_ADDRESS), sodass die Tools auch beim Start aus einer SSH-/Service-Umgebung verfügbar sind; - Manueller Test des Startskripts:
timeout 2 scripts/env/with-niri-env.sh </dev/null, exit 0 bedeutet OK; - Voraussetzungen: Node ≥ 20, das Repository wurde
npm install && npm run buildausgeführt, und Sie sind als derselbe Benutzer angemeldet, der die niri-Grafiksitzung besitzt.
2. Tool-Übersicht (gruppiert nach Erweiterung, Tool-Name = <Erweiterung>__<Tool>)
niri – Fenster/Arbeitsflächen/Starten (L0)
| Tool | Zweck | Wichtige Parameter |
|---|---|---|
list_windows | Alle Fenster auflisten (id/app_id/Titel/Arbeitsfläche/Fokus) | — |
list_workspaces | Arbeitsflächen auflisten (idx-Nummer und id sind zwei verschiedene Dinge, move verwendet Nummer oder Namen) | — |
list_outputs | Bildschirme auflisten | — |
focus_window | Vordergrundfokus wechseln (ändert die Benutzeransicht, vorsichtig verwenden) | id |
focus_workspace | Arbeitsfläche wechseln (ändert die Benutzeransicht) | reference: "3" oder Name |
move_window_to_workspace | Fenster verschieben (ohne Fokus zu stehlen, zum Aufräumen) | id? (Standard = fokussiertes Fenster), reference |
close_window | Fenster schließen | id? |
open_app | Programm auf dem Benutzer-Desktop starten | command: Array, z. B. ["ghostty"] |
a11y – GUI-Anwendungsinteraktion (L1, AT-SPI2)
| Tool | Zweck | Wichtige Parameter |
|---|---|---|
a11y_list_apps | Im Barrierefreiheitsbus registrierte Anwendungen auflisten | — |
a11y_dump_tree | Barrierefreiheitsbaum einer Anwendung ausgeben (Schaltflächennamen/Struktur finden) | app |
a11y_click | Per accessible Name klicken (kein Fokus nötig, stört den Benutzer nicht) | app, buttonName |
a11y_read_texts | Alle nicht-leeren Texte einer Anwendung lesen (Bildschirminhalt/Ergebnisse/Beschriftungen) | app |
a11y_set_text | Textfeld per Knotenname beschreiben | app, match (Namensteilzeichenkette, Standard * = erster), text |
Praktische Disziplin: Per Namen adressieren, nicht per Baumindex (die Baumstruktur wird bei jeder AT-Verbindung neu aufgebaut); GTK4-Baum wird erst vollständig, nachdem sich ein AT-Client registriert hat; bei mehreren Instanzen mit demselben Namen wird die zuerst registrierte aufgelöst – zuerst Text lesen, um den Status zu unterscheiden, und ggf. überflüssige Instanzen schließen. Chromium-Ausnahme beachten: Träger Baumaufbau (Brücke wird automatisch ausgelöst, erstes dump 1–2 Sekunden mehr Zeit einplanen ist normal); Textfelder mit "grabFocus + kb-inject type"-Kombination beschreiben (Chromiums entry frisst setTextContents nicht); Schaltflächenklicks auf Seiten funktionieren nicht (doAction wird ausgelöst, aber onclick läuft nicht), Seitenoperationen immer über die browser-Erweiterung durchführen.
browser – Webseitenoperationen (L2, agenteneigener kopfloser Chromium)
| Tool | Zweck | Wichtige Parameter |
|---|---|---|
browser_open | Navigation (erster Aufruf startet den Browser automatisch) | url |
browser_eval | JavaScript auf der Seite ausführen, Formulare ausfüllen/klicken/Inhalte lesen – alles darüber | JS-Code |
browser_screenshot | Screenshot (Browser kopflos, visuelles Arbeiten nur so) | — |
Standardaktion zum Ausfüllen von Formularen: Nach el.value = "..." muss el.dispatchEvent(new Event("input", {bubbles: true})) ausgeführt werden, sonst empfangen moderne Frameworks die Eingabe nicht. Bei Captchas: Anhalten und den Benutzer informieren, niemals automatisch umgehen.
files – Datei-Sandbox (L0, Root = ~/Agent/, Pfade immer relativ)
| Tool | Zweck | Wichtige Parameter |
|---|---|---|
read_file / write_file | Text lesen/schreiben (erstellt Elternverzeichnisse automatisch) | path, content |
list_dir / create_dir | Verzeichnis auflisten/erstellen | path |
move / delete | Verschieben / Löschen (kommt in .trash, wiederherstellbar, nicht shell rm verwenden) | source/dest, path |
find_by_name | Datei nach Namen suchen | pattern |
download | http(s)-Download in die Sandbox (≤50 MB / 60s, nicht shell curl verwenden) | url, path |
desktop – Präsentation/Benachrichtigungen/Zwischenablage/Bestätigung (L0)
| Tool | Zweck | Wichtige Parameter |
|---|---|---|
open | Artefakt öffnen: URL oder Datei; Office-Dokumente müssen app: "libreoffice" mitgeben (Whitelist, systemweite MIME-Zuordnung unzuverlässig) | target, app? |
notify | Desktop-Benachrichtigung (drei Stufen siehe §3) | summary (erforderlich), body, urgency, action? |
confirm | Benutzer um Erlaubnis/Entscheidung bitten (T1 vier Banner: Erlauben/Sitzung erlauben/Ablehnen/Nie, 30s keine Antwort = Ablehnen) | summary (keine sensiblen Inhalte), tier? (t1/t2, beeinflusst Text) |
clipboard_read / clipboard_write | Zwischenablage lesen/schreiben | — |
session – Aquarium (agenteneigene eingebettete niri-Sitzung, alle GUI-Arbeiten werden hier erledigt)
| Tool | Zweck |
|---|---|
agent_session_start / agent_session_stop / agent_session_status | Lebenszyklus der eingebetteten Sitzung (auf dem Desktop erscheint ein zuschauersicheres Fenster) |
agent_open_app | Anwendung im Aquarium starten (z. B. gnome-calculator, chromium) |
agent_list_windows | Fenster im Aquarium auflisten |
agent_screenshot | Gezielter Screenshot des Aquariums (grim) |
system – Systemabfragen (L0 schreibgeschützt, alles freigegeben)
system_status / list_services / service_status / journal / network_info /
list_packages / package_info / package_install (T2 starke Bestätigung: polkit-Passwortdialog, Benutzer muss anwesend sein; bei unbeaufsichtigtem Lauf nach 300s Timeout abgelehnt – nicht bei unbeaufsichtigtem Betrieb aufrufen).
cred – Anmeldeinformationen (Agent erhält Referenz, keinen Klartext)
cred_list (verfügbare Anmeldeinformationen und deren Referenzen/Umgebungsvariablennamen) · cred_autofill (Kanal A: Automatisches Ausfüllen von Seiten, Klartext sofort verworfen) ·
cred_exec (Kanal B: Whitelist-Ausführung mit maskierter Ausgabe) · cred_inject (Kanal C: Kurzlebige TTL-Umgebungsvariablen-Injektion, alle zum Zeitpunkt abgeräumt). Jegliche Operation, die Passwort/Token benötigt, läuft nur über cred; niemals den Benutzer nach Klartext fragen.
3. Verhaltensregeln (praktisch erprobte Disziplin)
- Artefakte einheitlich nach
~/Agent/ablegen, sortiert indownloads/ inbox/ reports/ notes/ canvas/ screenshots/; Der Speicherort wird automatisch in den Artefakt-Index aufgenommen (http://127.0.0.1:7788/artifacts), sodass der Benutzer bei der Frage „Wo war mein letzter Bericht?“ auf diese Seite oder den relativen Pfad verwiesen wird; - Präsentationspriorität: Dashboards/Berichte/interaktive Inhalte → Selbstständige HTML-Datei nach
canvas/<Name>/index.htmlschreiben und dann mitopenunterhttp://127.0.0.1:7788/<Name>/öffnen; Office-Dokumente →openmitapp: "libreoffice"; Webseite → browser-Erweiterung; - Drei Benachrichtigungsstufen: Fertig →
notifyurgency=low + action ({kind:"open_path", path:"reports/x.fodt"}oder{kind:"open_url", url:...}, Klick auf Benachrichtigung führt direkt zum Artefakt); Fehlgeschlagen/muss schnell bekannt sein → urgency=critical + ein Satz Ergebnis + Ursachenempfehlung; Benutzerentscheidung erforderlich → nicht notify verwenden, sondernconfirm(notify hat keine Auswahl-Semantik). Asynchrone Ergebnisse immer benachrichtigen, nicht im Stillen abschließen; - Bestätigung und Augenmaß: Nicht das Fenster des Benutzers manipulieren, es sei denn, es wurde explizit angefordert (zuerst
list_windows, um das Ziel zu identifizieren); Richtlinienablehnung (isError mit Hinweis „Richtlinienablehnung“) ehrlich mitteilen, nicht umgehen; GUI-Operationen im Aquarium durchführen, ohne den Fokus des Benutzers zu stehlen; - Anmeldeinformationen nur über cred-mcp-Referenzen (der Satz nach der cred-Tabelle in §2).
4. Schnelle Umgebungsfallen (alle selbst erlebt)
| Falle | Symptom | Behandlung |
|---|---|---|
| niri IPC-Socket-Pfad ändert sich pro Sitzung | niri msg kann keine Verbindung herstellen | Startskript verwenden (findet automatisch NIRI_SOCKET), nicht hartcodieren |
| Chromium-Schlüsselbund blockiert Netzwerkdienste | Browser startet und bleibt hängen | Mit --password-store=basic starten (browser-Erweiterung hat dies bereits integriert; wenn Sie Chromium selbst starten, denken Sie daran) |
| soffice-Einzelinstanz-Sperre | Wenn LibreOffice bereits geöffnet ist, kann das Öffnen eines ähnlichen Dokuments zu keinem Fenster oder Hängen führen | Zuerst den soffice-Prozessstatus prüfen; Dokument öffnen mit app:"libreoffice" für Startskript-Semantik; nach einem abnormalen Beenden erscheint möglicherweise ein "Dokumentwiederherstellung"-Fenster (Stand 18.10.2026 getestet), verwechseln Sie dies nicht mit dem Zielfenster bei der Fensterauflistung |
| LibreOffice-MIME-Zuordnung unzuverlässig | Fedora erkennt fodt als text/xml und öffnet es mit einem Editor | open muss app:"libreoffice"" mitgeben |
| Qt-Anwendung erscheint nicht im a11y-Bus | a11y_list_apps zeigt sie nicht | Die systemweite Aktivierung ist bereits erfolgt (QT_LINUX_ACCESSIBILITY_ALWAYS_ON=1 in /etc/environment, nach Neustart dauerhaft); trotzdem nicht sichtbar = Anwendung wurde vor der Umgebungssetzung gestartet oder ist keine offizielle Qt-Bindung, Anwendung neu starten |
| Chromium/Electron a11y-Baum ist leer | dump liefert keinen Inhalt | ① Mit --force-renderer-accessibility starten (browser-Erweiterung hat dies standardmäßig aktiviert); ② toolkit-accessibility muss vor dem Start der Anwendung true sein (systemweit gesetzt; nachträgliche Änderung wirkungslos, Anwendung neu starten); ③ Träger Baumaufbau, einmal dump-en, um die Brücke auszulösen (siehe §2 a11y-Disziplin) |
| Tastatureingabe-Auswahl | Benötigt Tippen/Tastenkombinationen | scripts/kb-inject.sh: Text und Tastenkombinationen mit wtype (Benutzerebene); Steuertasten wie Enter/Tab funktionieren mit wtype unter GTK nicht, daher ydotool (sudo) verwenden; Chinesisch könnte das erste Zeichen verlieren, nach der Eingabe über den a11y-Baum zurückschreiben und prüfen |
| Aquarium hat anfangs niri-Hotkey-Overlay | Screenshot wird durch "Important Hotkeys" verdeckt | Esc einfügen, um es zu schließen; Agents Sandbox kann keine Verbindung zum ydotoold-Socket herstellen (root 600), daher niri__open_app verwenden, um die Injektion in der echten Desktop-Umgebung auszuführen |
| ydotool-Mauszeiger-Drift | Absolute Positionierung ungenau (libinput-Beschleunigung ≈0.5) | Mauszeiger nicht verlassen; Tastatureingabe zuverlässig; Socket-Pfad beachten: /tmp/.ydotool_socket vs. $XDG_RUNTIME_DIR-Versionen |
| GTK4-Baum anfänglich unvollständig | dump hat nur ein Dutzend Knoten | Zuerst a11y_list_apps/dump einmal ausführen, damit der AT-Client registriert wird, dann dump erneut, dann ist er vollständig (16→105 Knoten getestet) |
| T1/T2-Bestätigung bei unbeaufsichtigtem Lauf | 30s/300s ohne Antwort wird automatisch abgelehnt | Erwartetes Verhalten: Schreiboperationen erfordern die Anwesenheit des Benutzers, oder, zu Testzwecken, programmatische Antwort über org.agentos.Confirm1.Respond |
| Paketinstallation wird durch packagekitd-Sperre blockiert | dnf schlägt gelegentlich fehl | Vor der Installation systemctl stop packagekit (T2-Helfer hat dies bereits behandelt) |
5. Upgrade-Pfad (bei Problemen mit der Zielanwendung der Reihe nach versuchen)
L0 (Systemebene, immer zuerst versuchen) → L1 (a11y: GTK3/4/Qt sind standardmäßig erreichbar; Chromium Flag- und toolkit-accessibility-Reihenfolge prüfen; Drittanbieter-Electron gemäß capabilities.md Anhang B Flag hinzufügen) →
L2 (Webseiten müssen diesen Weg gehen) → L3 Notfall (grim ansehen + kb-inject Tastatur; Mauszeiger unzuverlässig).
Immer noch nicht öffnbare Typen: Reine X11-Anwendungen (xterm-Klasse, kein Baum, L3 ist Endstation), Java (benötigt JAB, Pfad siehe capabilities.md Anhang B), Compositor-eigene UI nur per Eingabe-Injektion – detaillierte Tabelle im Repository unter docs/capabilities.md.