Companion Panel: Button für die Hermes Web-GUI #70
Labels
No labels
herkunft/alpha-feedback
status
blockiert
status
zu-testen
typ
bug
typ
docs
typ
enhancement
typ
feature
typ
idea
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
iris/Iris#70
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Zweck
Im Header des Companion Panels gibt es die drei Agent-Buttons (Hermes, opencode, Claude Code), die
alle denselben Terminal-Prozess öffnen, dazu Index-Manager und System-Monitor. Es fehlt ein Zugang zur
Hermes-Web-GUI (
hermes dashboard) — der Oberfläche für Hermes-Konfiguration, API-Keys, Sessions undSkills. Es soll ein eigener Button im Header geben, der diese Web-GUI öffnet und den dafür nötigen
Dienst bei Bedarf selbst startet.
Spezifikation
Öffnen: in einem Iris-eigenen Fenster (WKWebView), nicht im System-Browser. Bei erneutem Klick wird
dasselbe Fenster fokussiert, nicht ein zweites geöffnet.
Dienststart: Iris prüft, ob sein eigener Web-GUI-Dienst läuft. Läuft keiner, wird gestartet:
hermes dashboard --isolated --no-open --port 0. Der Port wird aus der Sentinel-ZeileHERMES_DASHBOARD_READY port=Ngelesen, die Hermes auf fd 1 schreibt.Status im Button: farbig (Hermes-Purple), wenn der Dienst läuft; sonst grau — wie der
System-Monitor-Button.
Rechtsklick-Menü: „Web-GUI-Dienst neu starten" und „Web-GUI-Dienst stoppen", deaktiviert wenn der
Dienst nicht läuft. Betrifft nur Iris' eigenen Dienst.
Sichtbarkeit: nur wenn Hermes installiert ist (wie die Agent-Buttons).
Rahmen, der die Bauform bestimmt (live geprüft)
(
com.nousresearch.hermes-serve,hermes serve --host 0.0.0.0 --skip-build) ist headless:app.state.serves_spa = not headless(hermes_cli/web_server.py:1326). Live:GET http://127.0.0.1:9119/→302 /login. Einhermes dashboardohne--isolatedverweigert sichgegen diesen Backend mit exit 78 („headless
hermes servebackend with no dashboard UI"). Der Buttonbraucht ein eigenes Backend, kein Anhängen an den LaunchAgent.
(
should_require_auth,hermes_cli/web_server.py:481). Live bestätigt: ein--isolatedDashboardauf loopback liefert das SPA ohne Login. Das gespeicherte Passwort
(
hermesRemoteServeUsername/hermesRemoteServePassword) wird dafür nicht gebraucht.--port 0statt 9119, weil 9119 vom LaunchAgent belegt ist. Wenn der LaunchAgent läuft, laufendanach zwei Hermes-Webserver parallel (9119 headless + Iris' GUI-Backend) — gewollt, der LaunchAgent
bleibt unberührt.
hermes dashboard --stopfür das Stoppen: das trifft auch den LaunchAgent, der sich alsKeepAlive-Job selbst neu startet (live: gestopfter PID 813, 6 Sekunden später neu als 80825).Gestoppt wird per SIGTERM auf Iris' eigenen Prozess.
Beteiligte Dateien
Iris/HermesWebGUIManager.swift(neu) — dependency-free, damit dasIrisClient-Target mitbautIris/HermesWebGUIWindowController.swift(neu) — Singleton-NSWindow-Pattern wieVaultIndexManagerWindowController, Inhalt WKWebView wieHTMLPreviewWindowControllerIris/CompanionPanelView.swift—panelHeaderIris/Localizable.xcstrings— neue Schlüssel mit englischer ÜbersetzungNicht enthalten
PR #71 gemergt: feat(panel): Hermes Web-GUI-Button im Header (iris/Iris#70)
#71
Commits:
PR #72 gemergt: feat(panel): HermesWebGUIManager + Fenster-Controllee (iris/Iris#70)
#72
Commits:
PR #73 gemergt: fix(panel): Sentinel-Timeout 120 s und Prozess-Beenden ohne Port (iris/Iris#70)
#73
Commits:
Beschreibung des fertigen Zustands
Anmerkung: Forgejo hat keine Anhang-API für Issues (die Anhang-Route antwortet mit 404), daher steht
der fertige Zustand hier als Kommentar.
Was jetzt existiert
Im Header des Companion Panels, zwischen dem Claude-Code-Button und Index-Manager, ein Button
(
globe):erneutem Klick wird dasselbe Fenster fokussiert, nicht ein zweites geöffnet. Läuft der Dienst noch
nicht, startet Iris ihn vorher.
Dienst nicht läuft. Betrifft nur Iris' eigenen Dienst, nicht den LaunchAgent.
Dienst
hermes dashboard --isolated --no-open --port 0. Der Port wird aus der Sentinel-ZeileHERMES_DASHBOARD_READY port=Ngelesen, die Hermes auf fd 1 schreibt;BACKEND_PORT_IN_USE port=Nistder Fehlerfall.
--port 0, weil 9119 vom Onboarding-LaunchAgent belegt ist. Kein--skip-build, damitHermes die Dist-Freshness selbst prüft; das Sentinel-Timeout ist 120 s, weil ein npm-Build länger dauern
kann. Endet der Prozess vor dem Sentinel, wird er beendet, damit er nicht als Waise weiterläuft.
Login ist nicht nötig: das Auth-Gate greift nur bei non-loopback Bind, Iris' Backend ist loopback. Das
gespeicherte Passwort (
hermesRemoteServeUsername/hermesRemoteServePassword) wird nicht verwendet.Wenn der LaunchAgent läuft, laufen danach zwei Hermes-Webserver parallel — 9119 (headless, kein SPA) und
Iris' eigenes GUI-Backend. Gewollt, der LaunchAgent bleibt unberührt.
Dateien
Iris/HermesWebGUIManager.swift(neu) — dependency-free, damitIrisClientmitbaut, ohne imException-Set zu stehen. Hermes-Pfad wird pro Aufruf übergeben (
AgentAvailability.hermesPath).Iris/HermesWebGUIWindowController.swift(neu) — Singleton-NSWindow mit WKWebView, Pattern wieVaultIndexManagerWindowController. Kein Certificate-Pinning (loopback HTTP, kein selbst-signiertes TLS).Iris/CompanionPanelView.swift—panelHeader.Iris/Localizable.xcstrings— drei neue Schlüssel mit englischer Übersetzung.Geprüft
HERMES_DASHBOARD_READY port=53120.--isolatedauf loopback liefert SPA-HTML ohne Login.Noch nicht geprüft: der Button selbst im laufenden Iris — die laufende App ist der Build vor der
Änderung. Klick, Fensterfokus und Rechtsklick-Menü erst nach einem Neustart von Iris.
Doku:
obsidian-docs/Iris/plans/HERMES-WEB-GUI.md, Daily Log 2026-10-17.PR #71 — Button im Panel-Header
#71
Der Button selbst:
globe-Icon impanelHeader, zwischen Claude Code und Index-Manager, im bestehendenStil (20×20, Circle-Background,
pointerCursor(),headerButtonTooltip). Klick ruftHermesWebGUIManager.openWebGUI(hermesPath:), Rechtsklick das Kontextmenü mit Stop und Neu starten.Farbe Hermes-Purple wenn der Dienst läuft, sonst
textTertiary. Sichtbar nur bei installiertem Hermes.Dazu
@ObservedObjectauf den Manager im Panel und die drei neuenLocalizable.xcstrings-Schlüssel.Dieser PR enthält nur die Panel-Seite — die Manager- und Fenster-Dateien kamen in PR #72, weil
shipneue Dateien erst mit
-amitnimmt.PR #72 — Manager und Fenster-Controllee
#72
HermesWebGUIManager.swift: startethermes dashboard --isolated --no-open --port 0, liest den Port ausder Sentinel-Zeile auf fd 1, hält den Prozess unsupervised (ein lebender Prozess ist der
Erfolgszustand), Stop und Restart per SIGTERM auf den eigenen PID. Bewusst dependency-free für das
IrisClient-Target.HermesWebGUIWindowController.swift: Singleton-NSWindow mit WKWebView, fokussiert bei erneutem Klickund lädt auf den neuen Port um, wenn der Dienst neu gestartet wurde. Kein Pinning, weil loopback HTTP.
PR #73 — Sentinel-Timeout und Waisen-Prozess
#73
Zwei Korrekturen am Manager:
--skip-buildprüft Hermes die Dist-Freshness und baut das Web-UI neu,wenn es veraltet ist — ein npm-Build dauert länger als 20 s. Im Test reichten 20 s nur, weil die Dist
frisch war.
Build-Fehler), blieb er bisher als Waise laufen, während
isRunningfalsch herum entschied — dernächste Klick hätte einen zweiten Dienst gestartet.
Zusätzlich
isRunningüberrunningPortabgeleitet statt über den Prozess: nurrunningPortist@Published, und die Farbe soll erst dann umspringen, wenn der Dienst wirklich erreichbar ist, nichtschon in der Sekunde des Prozessstarts.