Plugin-Panel im rechten Seitenpanel — dritter Reiter „Plugin“, chat-gebunden, Plugin-UI im WKWebView #169

Closed
opened 2026-10-24 21:20:58 +00:00 by alf · 10 comments
Owner

Kontext

Das rechte Seitenpanel im Chat-Fenster kennt zwei Inhalte: die verbundene Notiz und den Browser des
Chats. Umschaltung: Iris/RemoteClientView.swift, enum Panels { case note, browser } und
sidePanelSwitcher. Auf iOS dasselbe, handgemacht und nicht geteilt:
frontend/ios/.../ChatNotePager.swift, enum ChatNotePage { case chat, note, browser }.

Ein Plugin mit eigener Oberfläche bekommt davon nichts ab: seine Web-Seiten öffnen heute eigene
Fenster
(settingsWebViewPath → „Konfigurieren", usageWebViewPath → der „Plugins"-Chevron,
beide über HTMLPreviewWindowController.open). Ein Plugin, das mit dem Nutzer an einem Stand
arbeitet (FreeCAD-Viewer, Schnitt-Bridge), steht damit neben dem Chat statt darin — und Hermes
sieht diesen Stand nicht, weil er in einem Fenster lebt, das zu keinem Chat gehört.

Gewünscht: ein dritter Reiter „Plugin", chat-gebunden, sodass der Agent denselben Stand liest und
verändert wie der Nutzer.

Die Entscheidungen sind in einer grill-me-Sitzung am 2026-10-24 ausgehandelt und abgeschlossen.
Der vollständige Plan mit Begründungen, Datei-Inventar und Fallstricken liegt in
obsidian-docs/plans/SEITENPANEL-PLUGIN.md — vor dem ersten Commit lesen.

Was gebaut wird

  1. Manifest: vierter Web-View-Schlüssel side_panel: "web/panel.html" (Pfad, kein Objekt —
    Label kommt aus name). Gilt unabhängig von providedBlockTypes; das bestehende webViewPath
    ist an Canvas-Blöcke gekoppelt und macht ohne sie nichts (PluginManager.registerPluginWebView).
  2. Registry: PluginSidePanelRegistry nach Vorbild PluginWebViewRegistry.
  3. Draht (beide Server, drei Clients, im selben Zug): has_side_panel_web_view in GET /plugins
    (berechnet, Muster has_settings_web_view) und GET /plugins/:id/side-panel-webview-url, das wie
    die bestehenden Routen einen kurzlebigen cfg_token münzt. iOS: dritter Fall in
    enum PluginWebViewKind.
  4. Chat-Kennung: chat_id in der URL neben cfg_token; die Seite schickt ihn bei jedem
    panel_api-Aufruf mit. Kein Sicherheitspfand — der Deckel ist Sichtbarmachung (Punkt 6).
  5. Pflichtbefehl status, erweitert um summary — nur verlangt, wenn side_panel im Manifest
    steht. Antwort: {ok, chat_id, summary, detail}. summary eine Zeile, von Iris auf 300 Zeichen
    gekappt; detail kommt nie automatisch in eine Nachricht. Vier Plugins haben status schon
    (filmcraft, iris-nextcloud-cookbook, iris-plugin-dev, iris-solidcraft).
  6. Host-View: PluginPanelView (macOS, WKWebView, Pinning wie PinnedWebView) und Gegenstück
    auf iOS neben PluginCanvasWebView. Polling-Gating wie BrowserPanelModel. Weicht der
    zurückgegebene chat_id vom gesendeten ab, zeigt der Reiter einen Fehler statt fremder Daten.
  7. Zeiger in den Chat: status alle ~5 s solange der Reiter offen ist (nie blockierend), beim
    Senden als Prefix aus dem Cache. cursorContextPrefix wird zu generischem contextPrefix mit
    zwei Lieferanten, fester Reihenfolge (Notiz zuerst). Keine Protokolländerung — der Server
    sieht weiter nur text.
  8. Dritter Reiter in Panels (macOS) und ChatNotePage (iOS), drittes Segment, drittes
    ZStack-Kind nach dem opacity-/allowsHitTesting-Muster, .id(selectedJobID). Zweiter Picker
    im Reiter, wenn mehrere Plugins ein Panel haben. Kein drittes Segment, wenn kein Plugin eines hat.
  9. Erster echter Fall: iris-solidcraft im selben Zug — viewer.html in den Reiter, status
    um summary und chat_id erweitern, Skill dem Agenten die Schreibbefehle erklären.

Bewusst so entschieden

  • Der Browser-Reiter bleibt Co-Arbeit an echten Websites und wird nicht über den neuen
    Mechanismus gestülpt. Interne Plugin-Oberflächen sind eine andere Fläche.
  • Neuladen bei Chat-Wechsel — kein überlebender WKWebView, kein Persistenz-Zwang für
    Plugin-Autoren. Ein Formularstand, der nur im JS lebt, ist beim Chat-Wechsel weg.
  • Kein „darauf beziehen"-Knopf. Hermes holt detail selbst über die Befehle des Plugins; sein
    Skill muss sie ihm erklären.
  • Iris prüft chat_id nicht — Durchsetzen kann Iris nicht, ihr ist die Datenstruktur des
    Plugins unbekannt.

Fallstricke

  • irisCall ist die Falle. PluginActionsCore.bridgeScript führt Skripte auf dem Rechner des
    Clients aus und existiert auf iOS nicht (kein einziges WKUserScript in frontend/ios). Sie
    wird in CanvasPluginWebBlockView eingespielt — wer den Host kopiert, bekommt sie gratis und baut
    ein Panel, das auf iOS nicht läuft. Vertrag ist panel_api.
  • Fließende Breite: Panel ist 320–900 pt (notePanelMinWidth/MaxWidth), ein echter WKWebView
    laid out in echter Breite, nicht skaliert wie das Browser-JPEG. Die Seite muss damit umgehen.
  • Der Picker hat ein hartes .frame(width: 180) (sidePanelSwitcher) und trägt drei Segmente
    nicht.
  • status darf nie blockieren — Manifeste erlauben Timeout bis 240 s (iris-server-hosts).

Abgrenzung

Der Chat, der sich Notiz, Tabs und Panel merkt und alles in den Chat-Export bringt, ist ein
eigenes Issue danach. Notiz (vaultNotePath am AgentJob) und Tabs (<jobID>-browser im Plugin
iris-browser) liegen heute an verschiedenen Orten; ein halber generischer Mechanismus ist der
teuerste. Dieses Issue liefert die Voraussetzung: status mit summary/detail, ohne laufenden
Client aufrufbar.

## Kontext Das rechte Seitenpanel im Chat-Fenster kennt zwei Inhalte: die verbundene Notiz und den Browser des Chats. Umschaltung: `Iris/RemoteClientView.swift`, `enum Panels { case note, browser }` und `sidePanelSwitcher`. Auf iOS dasselbe, handgemacht und nicht geteilt: `frontend/ios/.../ChatNotePager.swift`, `enum ChatNotePage { case chat, note, browser }`. Ein Plugin mit eigener Oberfläche bekommt davon nichts ab: seine Web-Seiten öffnen heute **eigene Fenster** (`settingsWebViewPath` → „Konfigurieren", `usageWebViewPath` → der „Plugins"-Chevron, beide über `HTMLPreviewWindowController.open`). Ein Plugin, das mit dem Nutzer an einem Stand arbeitet (FreeCAD-Viewer, Schnitt-Bridge), steht damit **neben** dem Chat statt darin — und Hermes sieht diesen Stand nicht, weil er in einem Fenster lebt, das zu keinem Chat gehört. Gewünscht: ein dritter Reiter **„Plugin"**, chat-gebunden, sodass der Agent denselben Stand liest und verändert wie der Nutzer. Die Entscheidungen sind in einer grill-me-Sitzung am 2026-10-24 ausgehandelt und abgeschlossen. Der vollständige Plan mit Begründungen, Datei-Inventar und Fallstricken liegt in `obsidian-docs/plans/SEITENPANEL-PLUGIN.md` — **vor dem ersten Commit lesen.** ## Was gebaut wird 1. **Manifest**: vierter Web-View-Schlüssel `side_panel: "web/panel.html"` (Pfad, kein Objekt — Label kommt aus `name`). Gilt unabhängig von `providedBlockTypes`; das bestehende `webViewPath` ist an Canvas-Blöcke gekoppelt und macht ohne sie nichts (`PluginManager.registerPluginWebView`). 2. **Registry**: `PluginSidePanelRegistry` nach Vorbild `PluginWebViewRegistry`. 3. **Draht** (beide Server, drei Clients, im selben Zug): `has_side_panel_web_view` in `GET /plugins` (berechnet, Muster `has_settings_web_view`) und `GET /plugins/:id/side-panel-webview-url`, das wie die bestehenden Routen einen kurzlebigen `cfg_token` münzt. iOS: dritter Fall in `enum PluginWebViewKind`. 4. **Chat-Kennung**: `chat_id` in der URL neben `cfg_token`; die Seite schickt ihn bei jedem `panel_api`-Aufruf mit. **Kein Sicherheitspfand** — der Deckel ist Sichtbarmachung (Punkt 6). 5. **Pflichtbefehl `status`, erweitert um `summary`** — nur verlangt, wenn `side_panel` im Manifest steht. Antwort: `{ok, chat_id, summary, detail}`. `summary` eine Zeile, von Iris auf 300 Zeichen gekappt; `detail` kommt nie automatisch in eine Nachricht. Vier Plugins haben `status` schon (filmcraft, iris-nextcloud-cookbook, iris-plugin-dev, iris-solidcraft). 6. **Host-View**: `PluginPanelView` (macOS, WKWebView, Pinning wie `PinnedWebView`) und Gegenstück auf iOS neben `PluginCanvasWebView`. Polling-Gating wie `BrowserPanelModel`. Weicht der zurückgegebene `chat_id` vom gesendeten ab, zeigt der Reiter einen Fehler statt fremder Daten. 7. **Zeiger in den Chat**: `status` alle ~5 s solange der Reiter offen ist (nie blockierend), beim Senden als Prefix aus dem Cache. `cursorContextPrefix` wird zu generischem `contextPrefix` mit zwei Lieferanten, fester Reihenfolge (Notiz zuerst). **Keine Protokolländerung** — der Server sieht weiter nur `text`. 8. **Dritter Reiter** in `Panels` (macOS) und `ChatNotePage` (iOS), drittes Segment, drittes `ZStack`-Kind nach dem opacity-/`allowsHitTesting`-Muster, `.id(selectedJobID)`. Zweiter Picker im Reiter, wenn mehrere Plugins ein Panel haben. Kein drittes Segment, wenn kein Plugin eines hat. 9. **Erster echter Fall: `iris-solidcraft`** im selben Zug — `viewer.html` in den Reiter, `status` um `summary` und `chat_id` erweitern, Skill dem Agenten die Schreibbefehle erklären. ## Bewusst so entschieden - **Der Browser-Reiter bleibt Co-Arbeit an echten Websites** und wird nicht über den neuen Mechanismus gestülpt. Interne Plugin-Oberflächen sind eine andere Fläche. - **Neuladen bei Chat-Wechsel** — kein überlebender WKWebView, kein Persistenz-Zwang für Plugin-Autoren. Ein Formularstand, der nur im JS lebt, ist beim Chat-Wechsel weg. - **Kein „darauf beziehen"-Knopf.** Hermes holt `detail` selbst über die Befehle des Plugins; sein Skill muss sie ihm erklären. - **Iris prüft `chat_id` nicht** — Durchsetzen kann Iris nicht, ihr ist die Datenstruktur des Plugins unbekannt. ## Fallstricke - **`irisCall` ist die Falle.** `PluginActionsCore.bridgeScript` führt Skripte auf dem Rechner des **Clients** aus und existiert auf iOS nicht (kein einziges `WKUserScript` in `frontend/ios`). Sie wird in `CanvasPluginWebBlockView` eingespielt — wer den Host kopiert, bekommt sie gratis und baut ein Panel, das auf iOS nicht läuft. **Vertrag ist `panel_api`.** - **Fließende Breite**: Panel ist 320–900 pt (`notePanelMinWidth`/`MaxWidth`), ein echter WKWebView laid out in echter Breite, nicht skaliert wie das Browser-JPEG. Die Seite muss damit umgehen. - **Der Picker hat ein hartes `.frame(width: 180)`** (`sidePanelSwitcher`) und trägt drei Segmente nicht. - **`status` darf nie blockieren** — Manifeste erlauben Timeout bis 240 s (iris-server-hosts). ## Abgrenzung Der Chat, der sich Notiz, Tabs und Panel **merkt** und alles in den Chat-Export bringt, ist ein **eigenes Issue danach**. Notiz (`vaultNotePath` am `AgentJob`) und Tabs (`<jobID>-browser` im Plugin iris-browser) liegen heute an verschiedenen Orten; ein halber generischer Mechanismus ist der teuerste. Dieses Issue liefert die Voraussetzung: `status` mit `summary`/`detail`, ohne laufenden Client aufrufbar.
Author
Owner

PR #170 gemergt: feat(side-panel): Plugin-Reiter im rechten Seitenpanel — side_panel im Manifest, Route side-panel-webview-url, prüfbarer Kern, dritter Reiter (#169)
#170

Commits:

  • feat(side-panel): Plugin-Reiter im rechten Seitenpanel — side_panel im Manifest, Route side-panel-webview-url, prüfbarer Kern, dritter Reiter (#169)

Stand — Plugin-Reiter gebaut (Mac)

Befund: Issue durchgrillt und geplant (plans/SEITENPANEL-PLUGIN.md), Umsetzung in diesem Zug gebaut.

Geändert: InstalledPlugin.swift — viertes Web-View-Feld sidePanelWebViewPath (Coding-Key side_panel);
IrisRemoteServer.swift — has_side_panel_web_view in GET /plugins (berechnet) und Route
GET /plugins/:id/side-panel-webview-url (cfg_token gemintet, chat_id hängt der Client an);
PluginSidePanelCore.swift (neu, rein Foundation) — der prüfbare Vertrag: Pflichtbefehl status mit
{ok, chat_id, summary, detail}, Auslegung valid/mismatch/invalid, summary auf eine Zeile/300 Zeichen,
Marker [PLUGIN-PANEL: <Plugin>], Reihenfolge der Kontext-Marker; zugleich Quelle der iOS-Kopie
(viertes Paar in check-marketplace-page-sync). ChatNoteCursorRegistry.swift → ChatContextRegistry.swift
(zwei Lieferanten, ein Prefix, feste Reihenfolge). PluginSidePanelRegistry.swift, PluginPanelView.swift,
PluginPanelModel.swift (neu) — dritter Reiter mit WKWebView, Polling nur bei offenem Reiter;
RemoteClientView.swift, RemoteJobChatView.swift, RemoteServerClient.swift, AgentJob.swift,
VaultNoteSourceEditor.swift — Reiter, Prefix-Versand, Client-Routen, Agenten-Hinweis.

Geprüft: scripts/test-plugin-side-panel-core.sh — 20 Prüfungen grün (chat_id-Abweichung,
300-Zeichen-Kappung, Marker-Reihenfolge); Parse-Check aller geänderten Dateien;
swiftc -typecheck für Core + Registries zusammen; check-marketplace-page-sync identisch.

Nicht geprüft: kein Xcode-Build von Iris/IrisClient (neue Dateien liegen im synchronisierten
Ordner, brauchen keine pbxproj-Einträge — das bestätigt erst der Build); kein Klicktest, kein Reiter
gegen ein echtes Plugin.

Grenzen / offen: iris-solidcraft als erster echter Fall noch nicht angepasst (weder side_panel
im Manifest noch summary/chat_id in seinem status); Gegenstücke: iOS (2ndbrain-ios), Linux-Server
(iris-linux-server), Doku im Wurzel-Repo — werden im selben Zug geshippt. Issue bleibt mit
status/zu-testen offen; Test im Alltag.

PR #170 gemergt: feat(side-panel): Plugin-Reiter im rechten Seitenpanel — side_panel im Manifest, Route side-panel-webview-url, prüfbarer Kern, dritter Reiter (#169) https://forgejo.lewerken.duckdns.org/iris/Iris/pulls/170 Commits: - feat(side-panel): Plugin-Reiter im rechten Seitenpanel — side_panel im Manifest, Route side-panel-webview-url, prüfbarer Kern, dritter Reiter (#169) --- ## Stand — Plugin-Reiter gebaut (Mac) **Befund:** Issue durchgrillt und geplant (`plans/SEITENPANEL-PLUGIN.md`), Umsetzung in diesem Zug gebaut. **Geändert:** `InstalledPlugin.swift` — viertes Web-View-Feld `sidePanelWebViewPath` (Coding-Key `side_panel`); `IrisRemoteServer.swift` — `has_side_panel_web_view` in `GET /plugins` (berechnet) und Route `GET /plugins/:id/side-panel-webview-url` (cfg_token gemintet, `chat_id` hängt der Client an); `PluginSidePanelCore.swift` (neu, rein Foundation) — der prüfbare Vertrag: Pflichtbefehl `status` mit `{ok, chat_id, summary, detail}`, Auslegung `valid/mismatch/invalid`, summary auf eine Zeile/300 Zeichen, Marker `[PLUGIN-PANEL: <Plugin>]`, Reihenfolge der Kontext-Marker; zugleich Quelle der iOS-Kopie (viertes Paar in `check-marketplace-page-sync`). `ChatNoteCursorRegistry.swift` → `ChatContextRegistry.swift` (zwei Lieferanten, ein Prefix, feste Reihenfolge). `PluginSidePanelRegistry.swift`, `PluginPanelView.swift`, `PluginPanelModel.swift` (neu) — dritter Reiter mit WKWebView, Polling nur bei offenem Reiter; `RemoteClientView.swift`, `RemoteJobChatView.swift`, `RemoteServerClient.swift`, `AgentJob.swift`, `VaultNoteSourceEditor.swift` — Reiter, Prefix-Versand, Client-Routen, Agenten-Hinweis. **Geprüft:** `scripts/test-plugin-side-panel-core.sh` — 20 Prüfungen grün (chat_id-Abweichung, 300-Zeichen-Kappung, Marker-Reihenfolge); Parse-Check aller geänderten Dateien; `swiftc -typecheck` für Core + Registries zusammen; `check-marketplace-page-sync` identisch. **Nicht geprüft:** kein Xcode-Build von `Iris`/`IrisClient` (neue Dateien liegen im synchronisierten Ordner, brauchen keine pbxproj-Einträge — das bestätigt erst der Build); kein Klicktest, kein Reiter gegen ein echtes Plugin. **Grenzen / offen:** `iris-solidcraft` als erster echter Fall noch nicht angepasst (weder `side_panel` im Manifest noch `summary`/`chat_id` in seinem `status`); Gegenstücke: iOS (2ndbrain-ios), Linux-Server (iris-linux-server), Doku im Wurzel-Repo — werden im selben Zug geshippt. Issue bleibt mit `status/zu-testen` offen; Test im Alltag.
Author
Owner

PR #43 gemergt: feat(side-panel): Plugin-Reiter im Chat — dritter Reiter neben Notiz und Browser, panel_api ohne Bridge (#42, iris/Iris#169)
iris/2ndbrain-ios#43

Commits:

  • feat(side-panel): Plugin-Reiter im Chat — dritter Reiter neben Notiz und Browser, panel_api ohne Bridge (#42, iris/Iris#169)

Stand — Plugin-Reiter gebaut (iOS)

Befund: Gegenstück zu iris/Iris#169, auf iOS gebaut.

Geändert: Plugin.swift — hasSidePanelWebView am Plugin-Eintrag, case sidePanel beim Web-View-Typ
(dieselbe Route wie auf dem Mac, chat_id hängt der Client an); ChatPluginPanelPageView.swift (neu) —
der Host, bewusst ohne Bridge: Vertrag ist panel_api, nie irisCall; Zertifikat gegen den beim
Koppeln gemerkten Fingerabdruck. ChatPluginPanelRegistry.swift (neu) — Kontext-Lieferant pro Chat,
Registrierung an Sichtbarkeit (onAppear/onChange(isVisible)), der Versand liest nur den Cache.
ChatNotePager.swift — dritter ChatNotePage-Fall: Segment im schmalen Umschalter und im breiten
Seitenbereich; Reiter fehlt ganz, wenn kein Plugin ein Panel hat. AgentChatView.swift — Panel-Marker
über das Registry vor die Nachricht. PluginSidePanelCore.swift — Kopie aus der Mac-App, viertes
Paar in tools/check-marketplace-page-sync.

Geprüft: Parse-Check aller geänderten Dateien; xcrun -sdk iphoneos swiftc -target arm64-apple-ios17.0 -typecheck für PluginSidePanelCore.swift + ChatPluginPanelRegistry.swift (exit 0);
check-marketplace-page-sync identisch. Neue Dateien liegen im synchronisierten Root-Group-Ordner,
kein pbxproj-Eintrag nötig.

Nicht geprüft: kein Xcode-Build des Targets, keine Installation auf einem Gerät, kein Reiter gegen
ein echtes Plugin.

Grenzen / offen: Speicher pro WKWebView (ein WKWebView je Chat) ist die offene Frage des Plans;
Cursor-Zeile der Notiz auf iOS noch nicht gebaut (CHAT-NOTIZ-CURSOR-KONTEXT Phase 2 offen — hier meldet
sich nur der Panel-Lieferant). Mac (iris/Iris#169), Linux-Server und Doku im Wurzel-Repo werden im
selben Zug geshippt. Issue bleibt mit status/zu-testen offen.

PR #43 gemergt: feat(side-panel): Plugin-Reiter im Chat — dritter Reiter neben Notiz und Browser, panel_api ohne Bridge (#42, iris/Iris#169) https://forgejo.lewerken.duckdns.org/iris/2ndbrain-ios/pulls/43 Commits: - feat(side-panel): Plugin-Reiter im Chat — dritter Reiter neben Notiz und Browser, panel_api ohne Bridge (#42, iris/Iris#169) --- ## Stand — Plugin-Reiter gebaut (iOS) **Befund:** Gegenstück zu iris/Iris#169, auf iOS gebaut. **Geändert:** `Plugin.swift` — `hasSidePanelWebView` am Plugin-Eintrag, `case sidePanel` beim Web-View-Typ (dieselbe Route wie auf dem Mac, `chat_id` hängt der Client an); `ChatPluginPanelPageView.swift` (neu) — der Host, bewusst **ohne** Bridge: Vertrag ist `panel_api`, nie `irisCall`; Zertifikat gegen den beim Koppeln gemerkten Fingerabdruck. `ChatPluginPanelRegistry.swift` (neu) — Kontext-Lieferant pro Chat, Registrierung an **Sichtbarkeit** (onAppear/onChange(isVisible)), der Versand liest nur den Cache. `ChatNotePager.swift` — dritter `ChatNotePage`-Fall: Segment im schmalen Umschalter und im breiten Seitenbereich; Reiter fehlt ganz, wenn kein Plugin ein Panel hat. `AgentChatView.swift` — Panel-Marker über das Registry vor die Nachricht. `PluginSidePanelCore.swift` — **Kopie** aus der Mac-App, viertes Paar in `tools/check-marketplace-page-sync`. **Geprüft:** Parse-Check aller geänderten Dateien; `xcrun -sdk iphoneos swiftc -target arm64-apple-ios17.0 -typecheck` für `PluginSidePanelCore.swift` + `ChatPluginPanelRegistry.swift` (exit 0); `check-marketplace-page-sync` identisch. Neue Dateien liegen im synchronisierten Root-Group-Ordner, kein pbxproj-Eintrag nötig. **Nicht geprüft:** kein Xcode-Build des Targets, keine Installation auf einem Gerät, kein Reiter gegen ein echtes Plugin. **Grenzen / offen:** Speicher pro WKWebView (ein WKWebView je Chat) ist die offene Frage des Plans; Cursor-Zeile der Notiz auf iOS noch nicht gebaut (CHAT-NOTIZ-CURSOR-KONTEXT Phase 2 offen — hier meldet sich nur der Panel-Lieferant). Mac (iris/Iris#169), Linux-Server und Doku im Wurzel-Repo werden im selben Zug geshippt. Issue bleibt mit `status/zu-testen` offen.
Author
Owner

PR #98 gemergt: feat(side-panel): Gegenstück zum Plugin-Reiter — side_panel im Index, side-panel-webview-url, PLUGIN-PANEL-Hinweis (#97, iris/Iris#169)
iris/iris-linux-server#98

Commits:

  • feat(side-panel): Gegenstück zum Plugin-Reiter — side_panel im Index, side-panel-webview-url, PLUGIN-PANEL-Hinweis (#97, iris/Iris#169)

Stand — Gegenstück zum Plugin-Reiter gebaut (Linux-Server)

Befund: Der Linux-Server bildet das Mac-Original von iris/Iris#169 nach.

Geändert: plugin_installer.py — side_panel aus dem Manifest in den Index-Eintrag (persistiert wie
usage_web_view_path, das Wire-Feld wird daraus berechnet). plugins_routes.py — has_side_panel_web_view
in GET /plugins (berechnet, bewusst ohne has_settings_panel-Gate) und
GET /plugins/{plugin_id}/side-panel-webview-url als drittes Gegenstück zu config-/usage-webview-url:
gleicher _CFG_TOKENS-Namensraum, 16 Hex-Zeichen, /htmlserver/-Pfad, 404 wenn das Plugin fehlt oder
kein side_panel hat. agent_jobs.py — PLUGIN-PANEL-Abschnitt in _hermes_base_instructions, Wortlaut
identisch zum Mac (AgentJob.swift), bewusst unabhängig von note_line. ROUTES.md — die beiden
fehlenden Web-View-Token-Routen und POST /plugins/{id}/api/{command} nachgezogen.

Was der Server nicht tut: die Chat-Kennung. Er mintet den plugin-gebundenen Token und sonst nichts;
chat_id hängt der Client an, der Server prüft es nie.

Geprüft: python3 -m py_compile über die drei geänderten Dateien.

Nicht geprüft: keine pytest-Suite für die neue Route — tests/test_plugins.py deckt config-, doc- und
panel_api-Routen ab, die neue nicht; ein Test nach dem Muster
test_plugin_config_route_accepts_cfg_token_without_bearer wäre die natürliche Ergänzung. Kein Lauf gegen
alf@iris-server, kein Deploy per rsync, kein docker compose. Der Mac-Client wurde nicht gegen diesen
Server getestet.

Grenzen / offen: Mac (iris/Iris#169), iOS (2ndbrain-ios#42) und die Doku im Wurzel-Repo werden im
selben Zug geshippt. Issue bleibt mit status/zu-testen offen.

PR #98 gemergt: feat(side-panel): Gegenstück zum Plugin-Reiter — side_panel im Index, side-panel-webview-url, PLUGIN-PANEL-Hinweis (#97, iris/Iris#169) https://forgejo.lewerken.duckdns.org/iris/iris-linux-server/pulls/98 Commits: - feat(side-panel): Gegenstück zum Plugin-Reiter — side_panel im Index, side-panel-webview-url, PLUGIN-PANEL-Hinweis (#97, iris/Iris#169) --- ## Stand — Gegenstück zum Plugin-Reiter gebaut (Linux-Server) **Befund:** Der Linux-Server bildet das Mac-Original von iris/Iris#169 nach. **Geändert:** `plugin_installer.py` — `side_panel` aus dem Manifest in den Index-Eintrag (persistiert wie `usage_web_view_path`, das Wire-Feld wird daraus berechnet). `plugins_routes.py` — `has_side_panel_web_view` in `GET /plugins` (berechnet, bewusst ohne `has_settings_panel`-Gate) und `GET /plugins/{plugin_id}/side-panel-webview-url` als drittes Gegenstück zu config-/usage-webview-url: gleicher `_CFG_TOKENS`-Namensraum, 16 Hex-Zeichen, `/htmlserver/`-Pfad, `404` wenn das Plugin fehlt oder kein `side_panel` hat. `agent_jobs.py` — PLUGIN-PANEL-Abschnitt in `_hermes_base_instructions`, Wortlaut identisch zum Mac (`AgentJob.swift`), bewusst unabhängig von `note_line`. `ROUTES.md` — die beiden fehlenden Web-View-Token-Routen und `POST /plugins/{id}/api/{command}` nachgezogen. Was der Server **nicht** tut: die Chat-Kennung. Er mintet den plugin-gebundenen Token und sonst nichts; `chat_id` hängt der Client an, der Server prüft es nie. **Geprüft:** `python3 -m py_compile` über die drei geänderten Dateien. **Nicht geprüft:** keine pytest-Suite für die neue Route — `tests/test_plugins.py` deckt config-, doc- und panel_api-Routen ab, die neue nicht; ein Test nach dem Muster `test_plugin_config_route_accepts_cfg_token_without_bearer` wäre die natürliche Ergänzung. Kein Lauf gegen `alf@iris-server`, kein Deploy per rsync, kein `docker compose`. Der Mac-Client wurde nicht gegen diesen Server getestet. **Grenzen / offen:** Mac (iris/Iris#169), iOS (2ndbrain-ios#42) und die Doku im Wurzel-Repo werden im selben Zug geshippt. Issue bleibt mit `status/zu-testen` offen.
Author
Owner

PR #107 gemergt: docs(wire): Plugin-Reiter im Seitenpanel — side_panel, side-panel-webview-url, Befehlsroute; PluginSidePanelCore.swift als viertes Kopien-Paar (iris/Iris#169)
alf/2ndbrain#107

Commits:

  • docs(wire): Plugin-Reiter im Seitenpanel — side_panel, side-panel-webview-url, Befehlsroute; PluginSidePanelCore.swift als viertes Kopien-Paar (iris/Iris#169)

Stand — Plugin-Reiter gebaut (Mac)

Befund: Issue durchgrillt und geplant (plans/SEITENPANEL-PLUGIN.md), Umsetzung in diesem Zug gebaut.

Geändert: InstalledPlugin.swift — viertes Web-View-Feld sidePanelWebViewPath (Coding-Key side_panel);
IrisRemoteServer.swift — has_side_panel_web_view in GET /plugins (berechnet) und Route
GET /plugins/:id/side-panel-webview-url (cfg_token gemintet, chat_id hängt der Client an);
PluginSidePanelCore.swift (neu, rein Foundation) — der prüfbare Vertrag: Pflichtbefehl status mit
{ok, chat_id, summary, detail}, Auslegung valid/mismatch/invalid, summary auf eine Zeile/300 Zeichen,
Marker [PLUGIN-PANEL: <Plugin>], Reihenfolge der Kontext-Marker; zugleich Quelle der iOS-Kopie
(viertes Paar in check-marketplace-page-sync). ChatNoteCursorRegistry.swift → ChatContextRegistry.swift
(zwei Lieferanten, ein Prefix, feste Reihenfolge). PluginSidePanelRegistry.swift, PluginPanelView.swift,
PluginPanelModel.swift (neu) — dritter Reiter mit WKWebView, Polling nur bei offenem Reiter;
RemoteClientView.swift, RemoteJobChatView.swift, RemoteServerClient.swift, AgentJob.swift,
VaultNoteSourceEditor.swift — Reiter, Prefix-Versand, Client-Routen, Agenten-Hinweis.

Geprüft: scripts/test-plugin-side-panel-core.sh — 20 Prüfungen grün (chat_id-Abweichung,
300-Zeichen-Kappung, Marker-Reihenfolge); Parse-Check aller geänderten Dateien;
swiftc -typecheck für Core + Registries zusammen; check-marketplace-page-sync identisch.

Nicht geprüft: kein Xcode-Build von Iris/IrisClient (neue Dateien liegen im synchronisierten
Ordner, brauchen keine pbxproj-Einträge — das bestätigt erst der Build); kein Klicktest, kein Reiter
gegen ein echtes Plugin.

Grenzen / offen: iris-solidcraft als erster echter Fall noch nicht angepasst (weder side_panel
im Manifest noch summary/chat_id in seinem status); Gegenstücke: iOS (2ndbrain-ios), Linux-Server
(iris-linux-server), Doku im Wurzel-Repo — werden im selben Zug geshippt. Issue bleibt mit
status/zu-testen offen; Test im Alltag.

PR #107 gemergt: docs(wire): Plugin-Reiter im Seitenpanel — side_panel, side-panel-webview-url, Befehlsroute; PluginSidePanelCore.swift als viertes Kopien-Paar (iris/Iris#169) https://forgejo.lewerken.duckdns.org/alf/2ndbrain/pulls/107 Commits: - docs(wire): Plugin-Reiter im Seitenpanel — side_panel, side-panel-webview-url, Befehlsroute; PluginSidePanelCore.swift als viertes Kopien-Paar (iris/Iris#169) --- ## Stand — Plugin-Reiter gebaut (Mac) **Befund:** Issue durchgrillt und geplant (`plans/SEITENPANEL-PLUGIN.md`), Umsetzung in diesem Zug gebaut. **Geändert:** `InstalledPlugin.swift` — viertes Web-View-Feld `sidePanelWebViewPath` (Coding-Key `side_panel`); `IrisRemoteServer.swift` — `has_side_panel_web_view` in `GET /plugins` (berechnet) und Route `GET /plugins/:id/side-panel-webview-url` (cfg_token gemintet, `chat_id` hängt der Client an); `PluginSidePanelCore.swift` (neu, rein Foundation) — der prüfbare Vertrag: Pflichtbefehl `status` mit `{ok, chat_id, summary, detail}`, Auslegung `valid/mismatch/invalid`, summary auf eine Zeile/300 Zeichen, Marker `[PLUGIN-PANEL: <Plugin>]`, Reihenfolge der Kontext-Marker; zugleich Quelle der iOS-Kopie (viertes Paar in `check-marketplace-page-sync`). `ChatNoteCursorRegistry.swift` → `ChatContextRegistry.swift` (zwei Lieferanten, ein Prefix, feste Reihenfolge). `PluginSidePanelRegistry.swift`, `PluginPanelView.swift`, `PluginPanelModel.swift` (neu) — dritter Reiter mit WKWebView, Polling nur bei offenem Reiter; `RemoteClientView.swift`, `RemoteJobChatView.swift`, `RemoteServerClient.swift`, `AgentJob.swift`, `VaultNoteSourceEditor.swift` — Reiter, Prefix-Versand, Client-Routen, Agenten-Hinweis. **Geprüft:** `scripts/test-plugin-side-panel-core.sh` — 20 Prüfungen grün (chat_id-Abweichung, 300-Zeichen-Kappung, Marker-Reihenfolge); Parse-Check aller geänderten Dateien; `swiftc -typecheck` für Core + Registries zusammen; `check-marketplace-page-sync` identisch. **Nicht geprüft:** kein Xcode-Build von `Iris`/`IrisClient` (neue Dateien liegen im synchronisierten Ordner, brauchen keine pbxproj-Einträge — das bestätigt erst der Build); kein Klicktest, kein Reiter gegen ein echtes Plugin. **Grenzen / offen:** `iris-solidcraft` als erster echter Fall noch nicht angepasst (weder `side_panel` im Manifest noch `summary`/`chat_id` in seinem `status`); Gegenstücke: iOS (2ndbrain-ios), Linux-Server (iris-linux-server), Doku im Wurzel-Repo — werden im selben Zug geshippt. Issue bleibt mit `status/zu-testen` offen; Test im Alltag.
Author
Owner

Stand des ganzen Zugs — gebaut und geshippt, noch nicht getestet

Der Plugin-Reiter ist in allen vier Repos gemergt, jeder Teil auf seinem eigenen PR:

Repo PR Was
iris/Iris (Mac) #170 Manifest side_panel, Route side-panel-webview-url, PluginSidePanelCore (prüfbarer Vertrag, Quelle der iOS-Kopie), ChatNoteCursorRegistry → ChatContextRegistry, dritter Reiter in RemoteClientView, Prefix-Versand, Agenten-Hinweis
iris/2ndbrain-ios #43 Issue 42 angelegt (fehlte — die Branch-Nummer 40 war ein Auto-Issue eines anderen Zugs). Dritter ChatNotePage-Fall, ChatPluginPanelPageView ohne Bridge, Registry für den Prefix, Kern als Kopie
iris/iris-linux-server #98 Issue 97 angelegt (94 existierte nicht). side_panel im Index, has_side_panel_web_view, Route, PLUGIN-PANEL-Hinweis byte-gleich zum Mac, ROUTES.md nachgezogen
alf/2ndbrain (Doku) #107 Wire-Abschnitt „Plugin-Reiter im Seitenpanel", side_panel/has_side_panel_web_view im Plugin-System, PluginSidePanelCore.swift als viertes Kopien-Paar im Vertrag und in check-marketplace-page-sync

Geprüft: Kern-Prüfskript scripts/test-plugin-side-panel-core.sh (20 Prüfungen grün: chat_id-Abweichung, 300-Zeichen-Kappung, Marker-Reihenfolge); Parse-Checks Mac und iOS; swiftc -typecheck (Mac: Core + Registries; iOS: -sdk iphoneos -target arm64-apple-ios17.0 für Core + Registry, exit 0); py_compile Linux; check-marketplace-page-sync — alle vier Paare identisch.

Nicht geprüft: kein Xcode-Build von Iris/IrisClient/iOS-Target, kein Gerät, kein Reiter gegen ein echtes Plugin, kein pytest für die neue Linux-Route, kein Deploy auf alf@iris-server.

Offen: iris-solidcraft als erster echter Fall anpassen (side_panel im Manifest, summary/chat_id in seinem status); iOS-Speicherfrage (ein WKWebView je Chat); pytest für side-panel-webview-url.

Alle drei Projekt-Issues (#169, 2ndbrain-ios#42, iris-linux-server#97) tragen status/zu-testen — Test im Alltag, Schließen bleibt beim Nutzer. Branches sind aufgeräumt: alle Repos auf main, die vier Platzhalter-Branches und die beiden toten 167-Branches in iris-plugins gelöscht.

## Stand des ganzen Zugs — gebaut und geshippt, noch nicht getestet Der Plugin-Reiter ist in **allen vier Repos gemergt**, jeder Teil auf seinem eigenen PR: | Repo | PR | Was | |---|---|---| | iris/Iris (Mac) | [#170](https://forgejo.lewerken.duckdns.org/iris/Iris/pulls/170) | Manifest `side_panel`, Route `side-panel-webview-url`, `PluginSidePanelCore` (prüfbarer Vertrag, Quelle der iOS-Kopie), `ChatNoteCursorRegistry` → `ChatContextRegistry`, dritter Reiter in `RemoteClientView`, Prefix-Versand, Agenten-Hinweis | | iris/2ndbrain-ios | [#43](https://forgejo.lewerken.duckdns.org/iris/2ndbrain-ios/pulls/43) | Issue [42](https://forgejo.lewerken.duckdns.org/iris/2ndbrain-ios/issues/42) angelegt (fehlte — die Branch-Nummer 40 war ein Auto-Issue eines anderen Zugs). Dritter `ChatNotePage`-Fall, `ChatPluginPanelPageView` ohne Bridge, Registry für den Prefix, Kern als Kopie | | iris/iris-linux-server | [#98](https://forgejo.lewerken.duckdns.org/iris/iris-linux-server/pulls/98) | Issue [97](https://forgejo.lewerken.duckdns.org/iris/iris-linux-server/issues/97) angelegt (94 existierte nicht). `side_panel` im Index, `has_side_panel_web_view`, Route, PLUGIN-PANEL-Hinweis byte-gleich zum Mac, `ROUTES.md` nachgezogen | | alf/2ndbrain (Doku) | [#107](https://forgejo.lewerken.duckdns.org/alf/2ndbrain/pulls/107) | Wire-Abschnitt „Plugin-Reiter im Seitenpanel", `side_panel`/`has_side_panel_web_view` im Plugin-System, `PluginSidePanelCore.swift` als viertes Kopien-Paar im Vertrag und in `check-marketplace-page-sync` | **Geprüft:** Kern-Prüfskript `scripts/test-plugin-side-panel-core.sh` (20 Prüfungen grün: chat_id-Abweichung, 300-Zeichen-Kappung, Marker-Reihenfolge); Parse-Checks Mac und iOS; `swiftc -typecheck` (Mac: Core + Registries; iOS: `-sdk iphoneos -target arm64-apple-ios17.0` für Core + Registry, exit 0); `py_compile` Linux; `check-marketplace-page-sync` — alle vier Paare identisch. **Nicht geprüft:** kein Xcode-Build von `Iris`/`IrisClient`/iOS-Target, kein Gerät, kein Reiter gegen ein echtes Plugin, kein pytest für die neue Linux-Route, kein Deploy auf `alf@iris-server`. **Offen:** `iris-solidcraft` als erster echter Fall anpassen (`side_panel` im Manifest, `summary`/`chat_id` in seinem `status`); iOS-Speicherfrage (ein WKWebView je Chat); pytest für `side-panel-webview-url`. Alle drei Projekt-Issues (#169, 2ndbrain-ios#42, iris-linux-server#97) tragen `status/zu-testen` — Test im Alltag, Schließen bleibt beim Nutzer. Branches sind aufgeräumt: alle Repos auf `main`, die vier Platzhalter-Branches und die beiden toten 167-Branches in iris-plugins gelöscht.
Author
Owner

PR #171 gemergt: fix(side-panel): Buildfehler aus #169 — Self-Bezug auf AgentJob, Combine-Import, self in Logger-Interpolation (#169)
#171

Commits:

  • fix(side-panel): Buildfehler aus #169 — Self-Bezug auf AgentJob, Combine-Import, self in Logger-Interpolation (#169)

Befund: Der Build von #169 war nie gelaufen (Stand-Kommentar nannte ihn „nicht geprüft"). Xcode meldete drei Fehler.

Geändert:

  • AgentJob.swift (3295, 3806, 4126): Self.pluginPanelInstructionLine → AgentJob.pluginPanelInstructionLine. Die Interpolationen liegen in AgentJobManager; Self meint dort den Manager, das statische Glied gehört zu AgentJob.
  • PluginPanelModel.swift: import Combine ergänzt — das Ziel baut mit MemberImportVisibility, @Published kommt aus Combine, import SwiftUI genügt nicht.
  • PluginPanelModel.swift:109: self.jobID.uuidString in der Logger-Interpolation (Autoclosure verlangt explizites self).

Geprüft: xcodebuild -scheme Iris -configuration Debug build grün; -scheme IrisClient grün; check-marketplace-page-sync alle vier Paare identisch.

Nicht geprüft: unverändert aus #169 — kein Klicktest, kein Reiter gegen ein echtes Plugin, iris-solidcraft noch nicht angepasst. status/zu-testen bleibt.

PR #171 gemergt: fix(side-panel): Buildfehler aus #169 — Self-Bezug auf AgentJob, Combine-Import, self in Logger-Interpolation (#169) https://forgejo.lewerken.duckdns.org/iris/Iris/pulls/171 Commits: - fix(side-panel): Buildfehler aus #169 — Self-Bezug auf AgentJob, Combine-Import, self in Logger-Interpolation (#169) --- **Befund:** Der Build von #169 war nie gelaufen (Stand-Kommentar nannte ihn „nicht geprüft"). Xcode meldete drei Fehler. **Geändert:** - `AgentJob.swift` (3295, 3806, 4126): `Self.pluginPanelInstructionLine` → `AgentJob.pluginPanelInstructionLine`. Die Interpolationen liegen in `AgentJobManager`; `Self` meint dort den Manager, das statische Glied gehört zu `AgentJob`. - `PluginPanelModel.swift`: `import Combine` ergänzt — das Ziel baut mit `MemberImportVisibility`, `@Published` kommt aus Combine, `import SwiftUI` genügt nicht. - `PluginPanelModel.swift:109`: `self.jobID.uuidString` in der Logger-Interpolation (Autoclosure verlangt explizites `self`). **Geprüft:** `xcodebuild -scheme Iris -configuration Debug build` grün; `-scheme IrisClient` grün; `check-marketplace-page-sync` alle vier Paare identisch. **Nicht geprüft:** unverändert aus #169 — kein Klicktest, kein Reiter gegen ein echtes Plugin, `iris-solidcraft` noch nicht angepasst. `status/zu-testen` bleibt.
Author
Owner

PR #172 gemergt: fix(side-panel): Seitenpanel-Registry auch beim App-Start füllen — Reiter überlebte keinen Neustart (#169)
#172

Commits:

  • fix(side-panel): Seitenpanel-Registry auch beim App-Start füllen — Reiter überlebte keinen Neustart (#169)

Befund: Beim App-Start wurden nur Canvas-Blöcke, Settings-Panel und Web-View neu registriert — registerPluginSidePanel fehlte in dieser Schleife (PluginManager.swift:1209). Die Registry ist rein im Speicher: nach einem Iris-Neustart war has_side_panel_web_view zwar im Index, aber der Reiter fand keine Entry-Datei. Aufgetaucht beim ersten echten Fall (iris-solidcraft 0.2.0, iris/iris-plugins).

Geändert: registerPluginSidePanel(for:pluginID:) in die Start-Schleife ergänzt — dieselbe Stelle, an der die drei anderen Registrierungen schon stehen.

Geprüft: xcodebuild -scheme Iris -configuration Debug build grün.

Nicht geprüft: kein Neustart-Klicktest (Reiter nach Iris-Neustart mit installiertem iris-solidcraft 0.2.0). status/zu-testen bleibt.

Mit im Commit: Localizable.xcstrings — Xcode hat die drei neuen Texte aus #169 (Plugin-Reiter) automatisch extrahiert.

PR #172 gemergt: fix(side-panel): Seitenpanel-Registry auch beim App-Start füllen — Reiter überlebte keinen Neustart (#169) https://forgejo.lewerken.duckdns.org/iris/Iris/pulls/172 Commits: - fix(side-panel): Seitenpanel-Registry auch beim App-Start füllen — Reiter überlebte keinen Neustart (#169) --- **Befund:** Beim App-Start wurden nur Canvas-Blöcke, Settings-Panel und Web-View neu registriert — `registerPluginSidePanel` fehlte in dieser Schleife (`PluginManager.swift:1209`). Die Registry ist rein im Speicher: nach einem Iris-Neustart war `has_side_panel_web_view` zwar im Index, aber der Reiter fand keine Entry-Datei. Aufgetaucht beim ersten echten Fall (iris-solidcraft 0.2.0, iris/iris-plugins). **Geändert:** `registerPluginSidePanel(for:pluginID:)` in die Start-Schleife ergänzt — dieselbe Stelle, an der die drei anderen Registrierungen schon stehen. **Geprüft:** `xcodebuild -scheme Iris -configuration Debug build` grün. **Nicht geprüft:** kein Neustart-Klicktest (Reiter nach Iris-Neustart mit installiertem iris-solidcraft 0.2.0). `status/zu-testen` bleibt. Mit im Commit: `Localizable.xcstrings` — Xcode hat die drei neuen Texte aus #169 (Plugin-Reiter) automatisch extrahiert.
alf closed this issue 2026-10-27 10:38:36 +00:00
Author
Owner

PR #48 gemergt: fix(side-panel): iOS — Plugin-Wechsel lädt die Seite, Auswahl als Dropdown (iris/Iris#169)
iris/2ndbrain-ios#48

Commits:

  • fix(side-panel): iOS — Plugin-Wechsel lädt die Seite, Auswahl als Dropdown (iris/Iris#169)

Befund: In der iOS-App wechselte die Plugin-Auswahl im Seitenpanel den Namen, aber nicht die Seite: die WebView-id enthielt nur Chat und Reload-Zähler, PinnedRemoteHTMLView lädt in updateUIView nie neu. Zusätzlich war die segmentierte Pillenliste bei sechs und mehr Plugins unlesbar (Namen gekürzt).

Geändert: Auswahl als Dropdown (Menü mit Häkchen am aktiven Plugin); die WebView-id enthält die Plugin-ID, ein Wechsel lädt die neue Seite.

Geprüft: xcodebuild grün.
Nicht geprüft: Wechsel auf dem Gerät (nach der Installation).

PR #48 gemergt: fix(side-panel): iOS — Plugin-Wechsel lädt die Seite, Auswahl als Dropdown (iris/Iris#169) https://forgejo.lewerken.duckdns.org/iris/2ndbrain-ios/pulls/48 Commits: - fix(side-panel): iOS — Plugin-Wechsel lädt die Seite, Auswahl als Dropdown (iris/Iris#169) --- **Befund:** In der iOS-App wechselte die Plugin-Auswahl im Seitenpanel den Namen, aber nicht die Seite: die WebView-`id` enthielt nur Chat und Reload-Zähler, `PinnedRemoteHTMLView` lädt in `updateUIView` nie neu. Zusätzlich war die segmentierte Pillenliste bei sechs und mehr Plugins unlesbar (Namen gekürzt). **Geändert:** Auswahl als Dropdown (Menü mit Häkchen am aktiven Plugin); die WebView-`id` enthält die Plugin-ID, ein Wechsel lädt die neue Seite. **Geprüft:** `xcodebuild` grün. **Nicht geprüft:** Wechsel auf dem Gerät (nach der Installation).
Author
Owner

PR #49 gemergt: fix(side-panel): iOS — Plugin-Wechsel zeigt nie die Seite des vorigen Plugins (iris/Iris#169)
iris/2ndbrain-ios#49

Commits:

  • fix(side-panel): iOS — Plugin-Wechsel zeigt nie die Seite des vorigen Plugins (iris/Iris#169)

Befund: Der Dropdown-Fix aus #48 reichte nicht: Beim Wechsel änderte sich die Plugin-ID sofort, die neue Adresse kam erst nach dem Server-Aufruf. Die neu angelegte WebView bekam dadurch noch die Adresse des vorigen Plugins und lud nie neu (Kopfzeile „Buchhaltung“, Inhalt „Hintergrundjobs“).

Geändert: selectPlugin leert die Adresse sofort; die WebView-Identität hängt an der Adresse, nicht an der Plugin-ID.

Geprüft: xcodebuild grün; Ursache aus dem Screenshot (Kopfzeile und Statuszeile Buchhaltung, Inhalt Hintergrundjobs) abgeleitet.
Nicht geprüft: Wechsel auf dem Gerät vor dem Einreichen.

PR #49 gemergt: fix(side-panel): iOS — Plugin-Wechsel zeigt nie die Seite des vorigen Plugins (iris/Iris#169) https://forgejo.lewerken.duckdns.org/iris/2ndbrain-ios/pulls/49 Commits: - fix(side-panel): iOS — Plugin-Wechsel zeigt nie die Seite des vorigen Plugins (iris/Iris#169) --- **Befund:** Der Dropdown-Fix aus #48 reichte nicht: Beim Wechsel änderte sich die Plugin-ID sofort, die neue Adresse kam erst nach dem Server-Aufruf. Die neu angelegte WebView bekam dadurch noch die Adresse des vorigen Plugins und lud nie neu (Kopfzeile „Buchhaltung“, Inhalt „Hintergrundjobs“). **Geändert:** `selectPlugin` leert die Adresse sofort; die WebView-Identität hängt an der Adresse, nicht an der Plugin-ID. **Geprüft:** `xcodebuild` grün; Ursache aus dem Screenshot (Kopfzeile und Statuszeile Buchhaltung, Inhalt Hintergrundjobs) abgeleitet. **Nicht geprüft:** Wechsel auf dem Gerät vor dem Einreichen.
Author
Owner

PR #50 gemergt: fix(side-panel): iOS — Randwisch wechselt zur Nachbarseite (Notiz ↔ Browser ↔ Plugin) (iris/Iris#169)
iris/2ndbrain-ios#50

Commits:

  • fix(side-panel): iOS — Randwisch wechselt zur Nachbarseite (Notiz ↔ Browser ↔ Plugin) (iris/Iris#169)

Befund: Auf dem iPhone ließ sich nur zwischen Chat und Notiz wischen. Auf Notiz-, Browser- und Plugin-Seite ist das freie Seiten-Scrollen bewusst aus (Tabellen, Textauswahl, Block-Ziehen, WebViews); die einzige Randzone führte immer zum Chat.

Geändert: Randzonen (32 pt) führen zur jeweiligen Nachbarseite: links zur vorigen, rechts zur nächsten (Notiz → Browser → Plugin). Freies Wischen bleibt dem Inhalt.

Geprüft: xcodebuild grün.
Nicht geprüft: Gestik auf dem Gerät; ob die rechte Randzone im Browser mit Seiten-Gesten der WebView kollidiert. Nicht installiert.

PR #50 gemergt: fix(side-panel): iOS — Randwisch wechselt zur Nachbarseite (Notiz ↔ Browser ↔ Plugin) (iris/Iris#169) https://forgejo.lewerken.duckdns.org/iris/2ndbrain-ios/pulls/50 Commits: - fix(side-panel): iOS — Randwisch wechselt zur Nachbarseite (Notiz ↔ Browser ↔ Plugin) (iris/Iris#169) --- **Befund:** Auf dem iPhone ließ sich nur zwischen Chat und Notiz wischen. Auf Notiz-, Browser- und Plugin-Seite ist das freie Seiten-Scrollen bewusst aus (Tabellen, Textauswahl, Block-Ziehen, WebViews); die einzige Randzone führte immer zum Chat. **Geändert:** Randzonen (32 pt) führen zur jeweiligen Nachbarseite: links zur vorigen, rechts zur nächsten (Notiz → Browser → Plugin). Freies Wischen bleibt dem Inhalt. **Geprüft:** `xcodebuild` grün. **Nicht geprüft:** Gestik auf dem Gerät; ob die rechte Randzone im Browser mit Seiten-Gesten der WebView kollidiert. Nicht installiert.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
iris/Iris#169
No description provided.