Files
core 02d3d11523 fix: Chat-Isolation, Tab-Besitz und eigene Seiten für Einstellungen/Verlauf
Ereignisse landeten im falschen Chat: der Broker markiert jedes Ereignis mit
chatId, das Panel filtert aber auf sessionId — handleBrokerMessage reichte die
Nachricht unverändert weiter, der Filter griff also nie und alles landete im
gerade sichtbaren Chat. chatId wird jetzt beim Weiterreichen übersetzt.

Tab-Isolation war reine Optik — die Gruppen wurden nirgends durchgesetzt:
- getActiveTab() nahm sich den gerade sichtbaren Tab (auch den eines anderen
  Chats oder einen losen Tab des Nutzers) und zog ihn in die eigene Gruppe.
  Fremde Tabs werden jetzt nie adoptiert; der Chat öffnet sich einen eigenen.
- browser_tabs_create legte den neuen Tab in die Gruppe der SICHTBAREN statt
  der aufrufenden Konversation (sessionId fehlte).
- browser_tabs_select/close prüften den Besitz gar nicht — der Agent konnte
  jeden Tab übernehmen oder schließen, auch die des Nutzers.
- browser_tabs_list zeigte jeden offenen Tab; Tabs anderer Chats sind jetzt
  unsichtbar, Nutzer-Tabs klar als "nicht anfassen" markiert.
Besitz wird über Chromes Tab-Gruppen bestimmt — überlebt einen Neustart des
Service Workers, anders als reiner Speicher.

Session wird explizit durch runTool/dispatchTool/getActiveTab gereicht. Der
bisherige Trick, activeSessionId kurz umzubiegen, hielt nur ohne Parallelität:
zwischen Setzen und Zurücksetzen liegt ein await.

Einstellungen und Verlauf nehmen dem Chat keinen Platz mehr weg: Einstellungen
sind eine eigene Seite (vorher ausklappbar bis 45vh), der Verlauf ein Overlay
über dem Header-Knopf. Abschnitte als eigene Module mit Icon und Akzentkante.
Nebenbei repariert: nach der Umbenennung .settings -> .settings-panel zeigten
mehrere Regeln ins Leere.

Kimi K2.5, GLM-5 und Gemini 3.1 Flash Lite im Nexus-Katalog; Kimi/GLM laufen
über /moonshot bzw. /zai statt über den Azure-Deployment-Pfad. Ollama als
lokaler Anbieter wählbar (kein Key nötig).

Enthält außerdem ältere, noch nicht committete Arbeit, die nicht von diesem
Durchgang stammt und sich nicht sauber abtrennen ließ: kräftigerer Glow mit
Farbverlauf (spotlight.ts), Raster-Overlay für Screenshots (computer.ts) und
ein Ein/Aus-Schalter für CDP (cdp.ts).
2026-08-12 11:24:35 +02:00

152 lines
6.2 KiB
Markdown

# Nexus Browser Pilot
Chrome/Brave-Extension, die den Browser **wie ein Mensch bedient**: echter Mauszeiger,
echte Tastatur, echte Ereignisse. Sie handelt selbstständig und fragt nicht nach — es sei
denn, du schaltest den Nachfrage-Modus ein.
---
## Neue Features
| | |
|---|---|
| **Markdown-Output** | Assistenten-Antworten werden als Markdown gerendert — Code-Blöcke, Listen, Tabellen, Links. |
| **Konversationsverlauf** | Gespräche werden persistent gespeichert und überleben Panel-Schließen und Browser-Neustart. Über das Dropdown wechselst du zwischen Konversationen. |
| **Memory-Anbindung** | Anbindung an `memory.cnull.net` — relevante Erinnerungen werden automatisch als Kontext injiziert, Gespräche können per Klick synchronisiert werden. |
| **Provider-Wahl** | Neben Anthropic und OpenAI jetzt auch **Requesty**, **Kimi K2** (Moonshot) und **Ollama** (lokal, kein Key nötig) — alle OpenAI-kompatibel. Basis-URL und Modell frei wählbar. |
| **Coding-Agent-Anbindung** | Im Broker-Modus verbindet sich die Extension mit dem lokalen Coding-Agent (CLI/Web UI via `agent-web.bat`). |
| **System-Prompt** | Frei editierbarer System-Prompt in den Einstellungen (driveMode 'direct'). |
---
## Was sie anders macht
| | |
|---|---|
| **Echte Eingaben** | Alle Klicks und Tastendrücke laufen über `chrome.debugger` + CDP `Input.dispatch*` und tragen `isTrusted=true`. Damit funktionieren Canvas/WebGL, natives Drag & Drop, native `<select>`-Dropdowns und strenge Enterprise-SPAs. |
| **Sehen und zielen** | `browser_computer` arbeitet auf Pixelkoordinaten eines Screenshots — Screenshot ansehen, dann dorthin klicken. Genau wie ein Mensch. |
| **Sichtbarer Mauszeiger** | Ein Overlay zeigt, wohin der Agent fährt und klickt. Du siehst zu, statt zu raten. |
| **Autonom per Standard** | Keine Blocklisten, keine Domain-Sperren, keine Rückfragen. `riskMode` steht auf `off`. |
| **Zuschaltbare Bestätigung** | `riskMode: 'confirm'` fragt **nur** vor Aktionen mit echter Außenwirkung — Formular absenden, Nachricht senden, Kauf, Löschen, Zahlung. Erkannt wird die **Wirkung**, nicht der Tool-Name. |
---
## Installation in Brave
1. `brave://extensions` öffnen
2. Oben rechts **Entwicklermodus** einschalten
3. **Entpackte Erweiterung laden** → dieses Verzeichnis wählen:
`C:\Users\TTOMCZA\MB\extension`
Das war's — die Installation bleibt bestehen. Nach Codeänderungen genügt der
**Aktualisieren**-Knopf auf derselben Seite.
> Brave zeigt beim ersten echten Klick eine Leiste „… wird debuggt". Das ist der Preis für
> `isTrusted=true` und lässt sich nur per Startflag `--silent-debugger-extension-api`
> oder Enterprise-Policy unterdrücken.
### Bauen
```bash
cd extension
npm install
npm run build # erzeugt dist/ (prebuild generiert die Tool-Schemas)
npm run typecheck
```
---
## Die drei Antriebe
Alle drei münden im selben Engpass `runTool()` — der Risikomodus gilt also überall.
**1. Broker (Standard).** Der Agent-Loop läuft in `agent/ext_bridge.py` und spricht über das
Nexus-Gateway mit dem Modell. Starten:
```bat
agent-web.bat
```
Die Extension verbindet sich dann automatisch mit `ws://127.0.0.1:8765/ext/ws`.
**Ohne laufenden Broker gibt es keine Verbindung** — das ist die häufigste Ursache für
„nicht verbunden" im Panel.
**2. Eingebauter Loop.** In den Einstellungen `driveMode` auf `direct` stellen und einen
Endpunkt eintragen (Anthropic oder OpenAI-kompatibel). Läuft ohne Python, ohne Broker.
**3. MCP-Bridge.** Für Claude Code, Claude Desktop oder Cursor:
```bash
cd extension/mcp-bridge
node server.js
```
Der Server druckt beim Start ein Token und die fertige `brokerUrl`. Details in
`mcp-bridge/README.md`.
---
## Bedienung
Klick auf den Mercedes-Stern in der Symbolleiste öffnet das Side Panel.
- **Autonom** (Standard) — handelt ohne Rückfrage
- **Nachfragen** — fragt vor Absenden, Kauf, Löschen
Der Moduswechsel wirkt sofort und für alle Antriebe.
---
## Werkzeuge
31 Tools, definiert in `tools/schema/*.json`. Diese Dateien sind die **einzige Quelle**:
`tools/generate_tool_defs.py` erzeugt daraus sowohl die Python-Definitionen für den Broker
als auch die TypeScript-Typen für die Extension. Ein neues Tool wird dort angelegt, nicht
an drei Stellen gepflegt.
Kernstücke:
- `browser_computer` — koordinatenbasiert: `screenshot`, `left_click`, `double_click`,
`left_click_drag`, `scroll`, `type`, `key`, `hold_key`, `mouse_move`
- `browser_read_page` — Barrierefreiheits-Baum mit stabilen `ref_id`s, `type`-Attribut und
Koordinaten je Element
- `browser_find` — Element per natürlicher Beschreibung
- `browser_execute_js` — läuft im **MAIN world**, sieht also `window.React`, App-State usw.
- `browser_read_network` / `browser_read_console` — echter CDP-Mitschnitt, Konsole per
MAIN-world-Hook (nicht durch die CSP der Seite blockierbar)
---
## Aufbau
```
extension/
├── manifest.json
├── src/
│ ├── background/
│ │ ├── index.ts Engpass runTool(), Tool-Dispatch, Panel-Relay
│ │ ├── cdp.ts CDP-Eingabeschicht — Maus, Tastatur, Screenshot, Netzwerk
│ │ ├── computer.ts koordinatenbasiertes Bedienen
│ │ ├── risk.ts wirkungsbasierte Risikoerkennung
│ │ ├── agent.ts eingebauter Agent-Loop
│ │ └── llm.ts Anthropic-/OpenAI-Adapter
│ ├── content/
│ │ ├── inject.ts ISOLATED world: Brücke und Seitenfehler
│ │ ├── console-hook.ts MAIN world: Konsolen-Erfassung
│ │ └── cursor.ts sichtbarer Mauszeiger
│ ├── sidepanel/ Bedienoberfläche
│ └── shared/ Konfiguration und Protokolltypen
└── mcp-bridge/ MCP-Server für externe Clients
```
---
## Abnahme
Der Funktionsnachweis läuft gegen ein echtes Brave mit einer Prüfseite, die `isTrusted`
protokolliert. Stand der letzten Ausführung: **35 von 35 Prüfungen bestanden** — darunter
echter Canvas-Klick mit korrekter Koordinate, echte Tastatureingabe mit `keyCode`,
Submit-Erkennung im Baum, MAIN-world-Zugriff, Konsolen- und Netzwerkmitschnitt sowie der
vollständige Bestätigungskreislauf (Dialog → „Ausführen" → ausgeführt, „Abbrechen" →
`USER_DECLINED`).