feat(side-panel): Ansicht des Plugin-Reiters aktualisiert sich — revision in status, Ereignis iris:panel-refresh, automatisch und manuell #178

Closed
opened 2026-10-26 13:24:57 +00:00 by alf · 4 comments
Owner

Ziel

Die Plugin-Oberfläche im Seitenpanel zeigt Änderungen, die Iris (der Agent) vornimmt, ohne dass der Nutzer neu lädt — automatisch, und auch manuell auslösbar. Das Protokoll legt fest, woran der Client eine Änderung erkennt und wie er die Seite benachrichtigt; jedes Plugin mit side_panel zieht nach (Umsetzung dort: iris/iris-plugins, siehe Verweis unten).

Befund (2026-10-26, Code gelesen)

  • Der Reiter fragt status etwa alle 5 s (PluginPanelModel.runPolling), nutzt aber nur summary (für den Marker und die Statuszeile). Die Seite erfährt davon nichts — sie zeigt den Stand vom Laden an. Ändert der Agent etwas (Spiel gebaut, Workflow registriert, Design gespeichert), bleibt die Ansicht alt.
  • Es gibt nur den Knopf „Oberfläche neu laden“ (reload() → reloadCounter → die WebView lädt die URL neu). Das ist ein harter Neustart: Seitenzustand (Suche, Filter, Auswahl im JS, Scroll) ist weg, und er kommt nur auf Nutzerklick.

Vorschlag (zu klären)

  1. status bekommt ein optionales Feld revision (Zeichenkette), das sich ändert, wenn sich der sichtbare Stand des Plugins geändert hat — ein Hash/Zähler, den das Plugin billig berechnet (z. B. Zeitstempel und Größen der Zustandsdateien, nie ein Vollindex). Gleiche revision = nichts zu tun. Fehlt das Feld, gibt es keine automatische Aktualisierung (wie heute).
  2. Der Client vergleicht bei jedem gültigen status mit der letzten gesehenen revision. Bei Änderung (nicht beim ersten Wert) meldet er der Seite per JS-Ereignis: window.dispatchEvent(new CustomEvent("iris:panel-refresh", {detail: {revision, reason: "status"|"manual"|"agent"}})) via evaluateJavaScript — ohne Neuladen. Kein Reload, der Seitenzustand bleibt; die Seite holt sich selbst, was sie braucht.
  3. Schneller als der 5-s-Takt, wenn Iris etwas getan hat: der Client löst einen zusätzlichen status-Lauf aus, sobald ein Werkzeugaufruf des Agenten im Chat fertig ist und wenn der Antwort-Stream endet. Sichtbar ist dann der neue Stand ohne Wartezeit.
  4. Manuell: der bestehende Knopf macht künftig das weiche Aktualisieren (Ereignis reason: "manual", plus ein frischer status); ein harter Reload bleibt über ⌥-Klick bzw. Kontextmenü erreichbar. Reagiert eine Seite nicht auf das Ereignis (altes Plugin ohne Kit), lädt der Client sie nach dem Ereignis hart neu — nur bei manuellem Auslösen.
  5. Protokoll: Abschnitt „Plugin-Reiter im Seitenpanel“ in 02-Wire-Protokoll.md um revision, das Ereignis und die Auslöser erweitern. Die Server reichen revision nur durch (sie kennen weder Chat noch Antwortformat); PluginSidePanelCore.swift (Quelle Mac, Kopie iOS) trägt die Auslegung und den Vergleich.

Betrifft

Mac-App (Iris, IrisClient), iOS (WKWebView kann evaluateJavaScript), Wire-Protokoll. Linux-Server unverändert (nur Durchreichen). Plugins: iris/iris-plugins (Kit + comfyui-workflows, iris-solidcraft, iris-gamebox).

Offen

  • revision vom Plugin berechnen lassen oder aus dem Marker/detail ableiten? Vorschlag: vom Plugin, weil nur es weiß, was „sichtbarer Stand“ ist.
  • Ereignisname und Nutzlast festlegen (Vorschlag oben), danach ist er Vertrag.
  • Soll der Agent die Ansicht auch aktiv anstoßen können (ein Skill-Befehl „Panel aktualisieren“)? Mit Punkt 1–3 wäre das überflüssig; nur aufnehmen, wenn die Latenz des Takts stört.
  • Bezug: iris/Iris#169 (Reiter), #175/#176 (Marker, Zustandszeile) — unabhängig, aber alle drei laufen über PluginSidePanelCore.

Gegenstück: iris/iris-plugins#281

## Ziel Die Plugin-Oberfläche im Seitenpanel zeigt Änderungen, die Iris (der Agent) vornimmt, **ohne dass der Nutzer neu lädt** — automatisch, und auch manuell auslösbar. Das Protokoll legt fest, woran der Client eine Änderung erkennt und wie er die Seite benachrichtigt; jedes Plugin mit `side_panel` zieht nach (Umsetzung dort: iris/iris-plugins, siehe Verweis unten). ## Befund (2026-10-26, Code gelesen) - Der Reiter fragt `status` etwa alle 5 s (`PluginPanelModel.runPolling`), nutzt aber nur `summary` (für den Marker und die Statuszeile). Die **Seite erfährt davon nichts** — sie zeigt den Stand vom Laden an. Ändert der Agent etwas (Spiel gebaut, Workflow registriert, Design gespeichert), bleibt die Ansicht alt. - Es gibt nur den Knopf „Oberfläche neu laden“ (`reload()` → `reloadCounter` → die WebView lädt die URL neu). Das ist ein harter Neustart: Seitenzustand (Suche, Filter, Auswahl im JS, Scroll) ist weg, und er kommt nur auf Nutzerklick. ## Vorschlag (zu klären) 1. **`status` bekommt ein optionales Feld `revision`** (Zeichenkette), das sich ändert, wenn sich der **sichtbare Stand** des Plugins geändert hat — ein Hash/Zähler, den das Plugin billig berechnet (z. B. Zeitstempel und Größen der Zustandsdateien, nie ein Vollindex). Gleiche `revision` = nichts zu tun. Fehlt das Feld, gibt es keine automatische Aktualisierung (wie heute). 2. **Der Client vergleicht** bei jedem gültigen `status` mit der letzten gesehenen `revision`. Bei Änderung (nicht beim ersten Wert) **meldet er der Seite per JS-Ereignis**: `window.dispatchEvent(new CustomEvent("iris:panel-refresh", {detail: {revision, reason: "status"|"manual"|"agent"}}))` via `evaluateJavaScript` — **ohne Neuladen**. Kein Reload, der Seitenzustand bleibt; die Seite holt sich selbst, was sie braucht. 3. **Schneller als der 5-s-Takt, wenn Iris etwas getan hat**: der Client löst einen zusätzlichen `status`-Lauf aus, sobald ein Werkzeugaufruf des Agenten im Chat fertig ist und wenn der Antwort-Stream endet. Sichtbar ist dann der neue Stand ohne Wartezeit. 4. **Manuell**: der bestehende Knopf macht künftig das **weiche** Aktualisieren (Ereignis `reason: "manual"`, plus ein frischer `status`); ein harter Reload bleibt über ⌥-Klick bzw. Kontextmenü erreichbar. Reagiert eine Seite nicht auf das Ereignis (altes Plugin ohne Kit), lädt der Client sie nach dem Ereignis hart neu — nur bei manuellem Auslösen. 5. **Protokoll**: Abschnitt „Plugin-Reiter im Seitenpanel“ in `02-Wire-Protokoll.md` um `revision`, das Ereignis und die Auslöser erweitern. Die Server reichen `revision` nur durch (sie kennen weder Chat noch Antwortformat); `PluginSidePanelCore.swift` (Quelle Mac, Kopie iOS) trägt die Auslegung und den Vergleich. ## Betrifft Mac-App (Iris, IrisClient), iOS (`WKWebView` kann `evaluateJavaScript`), Wire-Protokoll. Linux-Server unverändert (nur Durchreichen). Plugins: iris/iris-plugins (Kit + comfyui-workflows, iris-solidcraft, iris-gamebox). ## Offen - `revision` vom Plugin berechnen lassen oder aus dem Marker/`detail` ableiten? Vorschlag: vom Plugin, weil nur es weiß, was „sichtbarer Stand“ ist. - Ereignisname und Nutzlast festlegen (Vorschlag oben), danach ist er Vertrag. - Soll der Agent die Ansicht auch **aktiv** anstoßen können (ein Skill-Befehl „Panel aktualisieren“)? Mit Punkt 1–3 wäre das überflüssig; nur aufnehmen, wenn die Latenz des Takts stört. - Bezug: iris/Iris#169 (Reiter), #175/#176 (Marker, Zustandszeile) — unabhängig, aber alle drei laufen über `PluginSidePanelCore`. Gegenstück: iris/iris-plugins#281
Author
Owner

PR #179 gemergt: feat(side-panel): Ansicht des Plugin-Reiters aktualisiert sich — revision in status, Ereignis iris:panel-refresh, Anstoß nach Agenten-Schritten, weicher Knopf (iris/Iris#178)
#179

Commits:

  • feat(side-panel): Ansicht des Plugin-Reiters aktualisiert sich — revision in status, Ereignis iris:panel-refresh, Anstoß nach Agenten-Schritten, weicher Knopf (iris/Iris#178)

Stand: Client und Protokoll gebaut (Plugins folgen mit iris/iris-plugins#281)

Was jetzt gilt (Wire-Protokoll, Abschnitt „Plugin-Reiter im Seitenpanel“, alf/2ndbrain-PR zu diesem Issue):

  • status kennt ein optionales Feld revision. Der Client vergleicht sie je geöffneter Seite; der erste Wert nach dem Laden ist keine Änderung. Bei Änderung schickt er der Seite iris:panel-refresh (detail: {revision, reason}) per JavaScript — ohne Neuladen.
  • Auslöser: Takt (status), Agent (agent: nach tool.completed des Hermes-Streams und am Ende eines Laufs — iOS nur am Ende, es kennt keine Werkzeug-Ereignisse) und Knopf (manual). Läuft schon eine Abfrage, folgt danach genau eine weitere.
  • Der Knopf aktualisiert jetzt weich; harter Neustart: macOS ⌥-Klick, iOS Kontextmenü. Kennt die Seite das Ereignis nicht (Antwort des Skripts ≠ true), lädt der Client nur bei manual hart neu.
  • Kern (PluginSidePanelCore.swift, Mac → iOS-Kopie): revision(from:), revisionChanged, RefreshReason, refreshScript, agentActivityNotification. Über NotificationCenter (nicht über die Registry), damit der Agenten-Anstoß nicht an einer An-/Abmeldung hängt (Verdacht aus #175).

Geprüft: scripts/test-plugin-side-panel-core.sh grün (neu: revision, Änderungsregel, Skript mit maskierter revision, Benachrichtigung). IrisClient und Iris (Debug, eigenes DerivedData, ohne Signing) bauen, iOS (IrisRemote, Simulator-Generic, ohne Signing) baut. check-marketplace-page-sync meldet alles identisch.

Nicht geprüft: das Verhalten in der laufenden App — kein Plugin liefert bisher revision, also läuft nur der Knopf; Ereignis und Auswertung des Skriptergebnisses (true/false) sind nur kompiliert, nicht gegen eine echte Seite getestet. iOS auf Gerät nicht gestartet.

Offen: Kit (revision_of, onRefresh) und die drei Plugins (iris/iris-plugins#281); #175 (Marker fehlt) bleibt eine eigene Baustelle.

PR #179 gemergt: feat(side-panel): Ansicht des Plugin-Reiters aktualisiert sich — revision in status, Ereignis iris:panel-refresh, Anstoß nach Agenten-Schritten, weicher Knopf (iris/Iris#178) https://forgejo.lewerken.duckdns.org/iris/Iris/pulls/179 Commits: - feat(side-panel): Ansicht des Plugin-Reiters aktualisiert sich — revision in status, Ereignis iris:panel-refresh, Anstoß nach Agenten-Schritten, weicher Knopf (iris/Iris#178) --- ## Stand: Client und Protokoll gebaut (Plugins folgen mit iris/iris-plugins#281) **Was jetzt gilt** (Wire-Protokoll, Abschnitt „Plugin-Reiter im Seitenpanel“, alf/2ndbrain-PR zu diesem Issue): - `status` kennt ein optionales Feld `revision`. Der Client vergleicht sie je geöffneter Seite; der erste Wert nach dem Laden ist keine Änderung. Bei Änderung schickt er der Seite `iris:panel-refresh` (`detail: {revision, reason}`) per JavaScript — ohne Neuladen. - Auslöser: Takt (`status`), Agent (`agent`: nach `tool.completed` des Hermes-Streams und am Ende eines Laufs — iOS nur am Ende, es kennt keine Werkzeug-Ereignisse) und Knopf (`manual`). Läuft schon eine Abfrage, folgt danach genau eine weitere. - Der Knopf aktualisiert jetzt weich; harter Neustart: macOS ⌥-Klick, iOS Kontextmenü. Kennt die Seite das Ereignis nicht (Antwort des Skripts ≠ `true`), lädt der Client nur bei `manual` hart neu. - Kern (`PluginSidePanelCore.swift`, Mac → iOS-Kopie): `revision(from:)`, `revisionChanged`, `RefreshReason`, `refreshScript`, `agentActivityNotification`. Über `NotificationCenter` (nicht über die Registry), damit der Agenten-Anstoß nicht an einer An-/Abmeldung hängt (Verdacht aus #175). **Geprüft:** `scripts/test-plugin-side-panel-core.sh` grün (neu: revision, Änderungsregel, Skript mit maskierter revision, Benachrichtigung). `IrisClient` und `Iris` (Debug, eigenes DerivedData, ohne Signing) bauen, iOS (`IrisRemote`, Simulator-Generic, ohne Signing) baut. `check-marketplace-page-sync` meldet alles identisch. **Nicht geprüft:** das Verhalten in der laufenden App — kein Plugin liefert bisher `revision`, also läuft nur der Knopf; Ereignis und Auswertung des Skriptergebnisses (`true`/`false`) sind nur kompiliert, nicht gegen eine echte Seite getestet. iOS auf Gerät nicht gestartet. **Offen:** Kit (`revision_of`, `onRefresh`) und die drei Plugins (iris/iris-plugins#281); #175 (Marker fehlt) bleibt eine eigene Baustelle.
Author
Owner

PR #45 gemergt: feat(side-panel): iOS — Plugin-Reiter aktualisiert sich bei neuer revision, weicher Knopf, Anstoß am Laufende (iris/Iris#178)
iris/2ndbrain-ios#45

Commits:

  • feat(side-panel): iOS — Plugin-Reiter aktualisiert sich bei neuer revision, weicher Knopf, Anstoß am Laufende (iris/Iris#178)

Stand: iOS-Seite gebaut (zu iris/Iris#178)

PluginSidePanelCore.swift als Kopie nachgezogen (check-marketplace-page-sync: identisch). ChatPluginPanelModel: revision vergleichen, refreshRequest, Anstoß über NotificationCenter, genau eine Wiederholung nach einem Nudge während eines Laufs. PinnedRemoteHTMLView bekommt optional refreshRequest/onPageUnaware (andere Aufrufer unverändert) und führt das Skript per evaluateJavaScript aus. Der Knopf aktualisiert weich, der harte Neustart liegt im Kontextmenü. Anstoß am Ende eines Laufs (AgentJob.startStreaming, .done); iOS kennt keine Werkzeug-Ereignisse im Stream.

Geprüft: IrisRemote baut (Simulator-Generic, ohne Signing). Nicht geprüft: nicht auf Gerät oder Simulator gestartet; kein Plugin liefert bisher revision (iris/iris-plugins#281).

PR #45 gemergt: feat(side-panel): iOS — Plugin-Reiter aktualisiert sich bei neuer revision, weicher Knopf, Anstoß am Laufende (iris/Iris#178) https://forgejo.lewerken.duckdns.org/iris/2ndbrain-ios/pulls/45 Commits: - feat(side-panel): iOS — Plugin-Reiter aktualisiert sich bei neuer revision, weicher Knopf, Anstoß am Laufende (iris/Iris#178) --- ## Stand: iOS-Seite gebaut (zu iris/Iris#178) `PluginSidePanelCore.swift` als Kopie nachgezogen (`check-marketplace-page-sync`: identisch). `ChatPluginPanelModel`: `revision` vergleichen, `refreshRequest`, Anstoß über `NotificationCenter`, genau eine Wiederholung nach einem Nudge während eines Laufs. `PinnedRemoteHTMLView` bekommt optional `refreshRequest`/`onPageUnaware` (andere Aufrufer unverändert) und führt das Skript per `evaluateJavaScript` aus. Der Knopf aktualisiert weich, der harte Neustart liegt im Kontextmenü. Anstoß am Ende eines Laufs (`AgentJob.startStreaming`, `.done`); iOS kennt keine Werkzeug-Ereignisse im Stream. **Geprüft:** `IrisRemote` baut (Simulator-Generic, ohne Signing). **Nicht geprüft:** nicht auf Gerät oder Simulator gestartet; kein Plugin liefert bisher `revision` (iris/iris-plugins#281).
Author
Owner

PR #114 gemergt: docs(wire): Plugin-Reiter aktualisiert sich — revision in status, Ereignis iris:panel-refresh, Auslöser (iris/Iris#178)
alf/2ndbrain#114

Commits:

  • docs(wire): Plugin-Reiter aktualisiert sich — revision in status, Ereignis iris:panel-refresh, Auslöser (iris/Iris#178)
PR #114 gemergt: docs(wire): Plugin-Reiter aktualisiert sich — revision in status, Ereignis iris:panel-refresh, Auslöser (iris/Iris#178) https://forgejo.lewerken.duckdns.org/alf/2ndbrain/pulls/114 Commits: - docs(wire): Plugin-Reiter aktualisiert sich — revision in status, Ereignis iris:panel-refresh, Auslöser (iris/Iris#178)
Author
Owner

PR #115 gemergt: docs(wire): Stand der Aktualisierung des Plugin-Reiters — Client, Kit und drei Plugins gebaut (iris/Iris#178, iris/iris-plugins#281)
alf/2ndbrain#115

Commits:

PR #115 gemergt: docs(wire): Stand der Aktualisierung des Plugin-Reiters — Client, Kit und drei Plugins gebaut (iris/Iris#178, iris/iris-plugins#281) https://forgejo.lewerken.duckdns.org/alf/2ndbrain/pulls/115 Commits: - docs(wire): Stand der Aktualisierung des Plugin-Reiters — Client, Kit und drei Plugins gebaut (iris/Iris#178, iris/iris-plugins#281)
alf closed this issue 2026-10-27 10:35:33 +00:00
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#178
No description provided.