20 KiB
WebUI als einzige Oberfläche — und Englisch komplett
Auftrag für einen eigenen Agenten. Beschlossen am 2026-10-02 (Mensch). Roadmap-Eintrag im Deploymentcenter: #764 (Themenbereich UI). Teil davon: #661 (Englisch als Hauptsprache).
Lies das ganz, bevor du die erste Datei anfasst. Die Stufen bauen aufeinander auf, und mehrere Grenzen in Abschnitt 2 sind keine Stilfragen, sondern Datenverlust oder Sicherheitslücken, wenn man sie übersieht.
1 — Worum es geht
- Eine Oberfläche statt zwei. Gepflegt wird nur noch die WebUI
(
src/ClawdDotNet.Manager.Web/wwwroot/), getragen vom Instanzmanager. Die Avalonia-Fenster insrc/ClawdDotNet.Desktop/Viewsverschwinden. Übrig bleibt eine Hülle, die den Manager startet und die WebUI zeigt. - Englisch komplett. Seit #661 (2026-09-19) entsteht Neues auf Englisch, Texte kommen aus
Sprachpaketen (
wwwroot/i18n/en.json,de.json). Der Bestand ist noch gemischt. Dieser Auftrag räumt ihn auf: Bezeichner, Kommentare und Oberflächentexte auf Englisch, jeder sichtbare Text über einen Sprachschlüssel, Deutsch nur noch als Sprachpaket.
Warum: Jede Funktion zweimal zu bauen kostet, die Desktop-Oberfläche hat keine Testabdeckung, und der Zielbetrieb (Linux, 24/7) läuft ohnehin über Manager und WebUI. Seit 0.1.17 kennt die Desktop-Oberfläche Einheiten, Stichproben, Abstimmungen, Vorlagen, Trigger, MCP-Server und Automatisierung nicht mehr — die Lücke ist schon da.
2 — Was nicht passieren darf
| Grenze | Warum |
|---|---|
Die Programmdatei ClawdDotNet bleibt. Program.cs, CommandLine.cs, HeadlessRun.cs, McpBridgeRun.cs bleiben lauffähig |
Sie ist der Instanzprozess (--headless --managed --instance …, so startet der Manager jede Instanz) und die MCP-Brücke. Fällt sie weg, startet keine Instanz mehr |
| Gespeicherte Namen nicht umbenennen — ohne Migration und Test mit einer alten Datei | Sonst sind Einstellungen, Rechte oder Datenbanken nach dem Update leer oder kaputt. Siehe Abschnitt 6 |
| Begründungskommentare übersetzen, nie löschen | Sie erklären, warum etwas so ist (oft ein Vorfall). Ein früherer Umbau durch ein Flash-Modell hat sie stillschweigend entfernt. Übersetzen: ja. Kürzen auf „was der Code tut“: nein |
| Texte, die ein Modell liest, nicht nebenbei umformulieren | Werkzeugbeschreibungen, ToolResult-Meldungen, Rahmen um Fremdinhalt (UntrustedContent), Systemhinweise — das sind Prompts. Übersetzen ändert das Verhalten der Agenten. Eigene Stufe, eigener Test auf der VM (Stufe 4d) |
| Sicherheitsstellen nicht anfassen, außer in Stufe 2 und nur wie dort beschrieben | AccessToken.cs, TokenGate.cs, McpTransport.cs, alles unter Security/, ConfigSecrets, Lizenzprüfung |
Kein innerHTML, kein Paketmanager, keine neuen CDN-Abhängigkeiten in der WebUI |
Siehe WebUI-Leitfaden |
Radius 0, App-Akzent var(--accent), keine zugeklappten Ebenen |
Hausstil, Entscheidung 2026-09-24 |
| Nur pushen, wenn alle vier Suiten grün sind — unter Windows und Linux | Siehe Teststrategie; Linux auf der Test-VM |
3 — Die Stufen
Jede Stufe ist ein eigener Branch und ein eigener Merge. Nach jeder Stufe: Suiten grün,
Kommentar am Roadmap-Eintrag (dc_comment), dann die nächste.
Stufe 0 — Bestandsaufnahme (Flash: ja)
Lege eine Tabelle an (in dieser Datei, Abschnitt 7): jede Funktion der Desktop-Oberfläche
und ob die WebUI sie hat. Quelle sind die Fenster in src/ClawdDotNet.Desktop/Views:
AddAgentWindow, AddJobWindow, AddServiceWindow, AgentChatsPageView, AgentsPageView,
BackupPageView, ChatPageView, InfoPageView, InstancePickerWindow, LicenseWindow,
LogPageView, MainWindow, RestoreBackupWindow, SettingsPageView, TasksPageView,
TextEditorWindow, TokenUsagePageView, ToolSettingsView.
Verdächtig, nur im Desktop zu stehen — besonders genau prüfen:
- Erstinstallation und Lizenz (
LicenseWindow) - Wiederherstellungs-Passphrase des Schlüsselbunds (im Start-Log steht die Warnung „kein Wiederherstellungsfach“ — wo setzt man sie heute?)
- Instanz anlegen / wählen (
InstancePickerWindow) - Sicherung zurückspielen (
RestoreBackupWindow) - Dateiauswahl-Dialoge, Texteditor für Identity/Soul (
TextEditorWindow)
Ergebnis: Liste „fehlt in der WebUI“. Nichts bauen in dieser Stufe.
Stufe 1 — Lücken der WebUI schließen (Flash: ja für reine Ansichten, nein sobald C# nötig ist)
Für jede Zeile aus Stufe 0 mit „fehlt“: zuerst prüfen, ob die API den Endpunkt hat.
- Hat sie ihn: Ansicht bauen, Texte in beide Sprachpakete.
- Hat sie ihn nicht: Endpunkt in
src/ClawdDotNet.Web/Endpoints(Instanz) odersrc/ClawdDotNet.Manager.Web/Endpoints.cs(Manager), Fachlogik inClawdDotNet.App(nie im Endpunkt), mit Test intests/ClawdDotNet.Web.TestsoderApp.Tests. Lizenz und Schlüsselbund sind Sicherheitsstellen → starkes Modell.
Stand 2026-10-02: erledigt (Branch feat/764-stufe1-webui-luecken, Suiten grün unter
Windows und Linux). L1, L3–L11 gebaut, L2 ist #780. Was dabei entschieden wurde:
| Lücke | Weg | Bewusst so |
|---|---|---|
| L1 Lizenz | PUT /api/verwaltung/license → LicenseGate.ApplyKeyAsync |
Gespeichert wird nur ein vom Server bestätigter Schlüssel; abgelehnt oder Server nicht erreichbar → der alte bleibt. Ein bestätigter hebt die Sperre ohne Neustart auf und startet die Autostart-Instanzen |
| L3 Manager | GET/PUT /api/verwaltung/settings |
Nur Deploymentcenter-Adresse, Master-Token, Update-Kanal. Port, Bindung und Web-Token nicht — ein falscher Wert sperrte die Seite aus, von der er gesetzt wurde |
| L3/L4/L5 Instanz + Anwendung | GET/PUT /api/settings (SettingsAdministration) |
Nur bei laufender Instanz: Die Instanzdatei gehört dem Instanzprozess. Die Antwort nennt, was erst nach einem Neustart greift |
| L6/L7 Agent | PUT /api/agents/{id}, GET …/texts |
Lange Texte nicht in der Agentenliste (50–100 Agenten) |
| L8 Werkzeuge | GET/PUT …/tools/{tool}/form (ToolSettingsForms) |
Formular aus den typisierten Klassen; ersetzt werden nur geänderte Schlüssel, sonst bleibt die Datei wie sie war |
| L10 Zeitplan | über /api/settings, in der Sicherungsansicht |
wie L4 |
| L11 Import | POST /api/verwaltung/backups/import?name=…, Datei als Rumpf, bis 4 GB |
Nie in ein bestehendes Verzeichnis; Pfade der alten Maschine zurückgesetzt; Kopie neben dem Original bekommt neue ID und neues Melde-Token; Autostart aus |
Nebenbei behoben: Database.allowedTables wurde beim Speichern als roher JSON-Text zerlegt;
api.js schickte Dateien als "{}"; Dialoge blieben beim Seitenwechsel offen; der Log-Hinweis
auf --license-set-key zeigte auf einen Schalter, den es nie gab. Die Sprachpakete prüft jetzt
LanguagePackTests bei jedem Lauf (gleiche Schlüssel, gleiche Platzhalter, jeder benutzte
Schlüssel vorhanden).
Stufe 2 — Die Hülle (Flash: nein)
Empfehlung (vom Menschen noch zu bestätigen, bevor du anfängst — frage im Roadmap-Eintrag):
Starter mit Systembrowser statt eingebettetem Browser.
- Startet den Instanzmanager, wenn er nicht läuft (unter Linux ist das der systemd-Dienst
clawddotnet-manager.service— nicht doppelt starten). - Öffnet die WebUI im Standardbrowser, angemeldet über einen Einmal-Link: der Manager erzeugt auf Anfrage über seinen lokalen Socket (nicht über TCP) einen Zufallswert, gültig einmal und höchstens 60 Sekunden; die WebUI tauscht ihn gegen das Sitzungstoken. Das Token selbst steht nie in einer Adresse.
- Taskleistensymbol mit Zustand (läuft / gestoppt / Fehler) und „WebUI öffnen“.
- Begründung: keine neue Abhängigkeit (ein eingebetteter Browser braucht unter Linux WebKitGTK als Systempaket), am wenigsten Code.
Der Einmal-Link ist eine neue Anmeldeart — Test für: zweimal benutzt, zu spät benutzt, über TCP statt Socket angefordert. Alle drei müssen scheitern.
Entscheidung des Menschen, 2026-10-02: eingebetteter Browser, nicht Systembrowser. Die Hülle bleibt ein eigenes Fenster. Folgen: Unter Linux wird eine Web-Engine als Systempaket gebraucht (WebKitGTK) — das muss ins Paket bzw. in die Installationsanleitung, und die Wahl der Einbettungsbibliothek ist vor dem Bauen mit dem Menschen abzustimmen (neue Abhängigkeit). Der Einmal-Link über den lokalen Socket bleibt der Anmeldeweg: Auch ein eingebettetes Fenster soll das Sitzungstoken nicht in einer Adresse tragen.
Stufe 3 — Avalonia-Fenster entfernen (Flash: mit Vorsicht)
Views/,Controls/,Converters/, ViewModels der Fenster,App.axaml— weg.- Avalonia-Pakete aus der
.csproj, soweit die Hülle sie nicht braucht. Program.cs: ohne--headless/--managed/MCP-Brücke startet künftig die Hülle.deploy/publish.pyund das Paket prüfen: Was fällt weg, was muss dabei bleiben? Ein Probepaket mit--dry-runbauen und auf der VM--headlessstarten.docs/Oberflaechen-Leitfaden.md→ nachdocs/archiv/, Verweise inCLAUDE.mdanpassen.
Stufe 4 — Englisch komplett
| Teil | Was | Flash? |
|---|---|---|
| 4a | WebUI: jeder sichtbare Text über t("…"), Schlüssel in en.json und de.json. Heute stehen noch Umlaut-Texte direkt in .js-Dateien |
ja |
| 4b | WebUI: deutsche Bezeichner in JS (erstelleElement, zeigeMeldung, lade …, 28 Dateien) und CSS-Klassen (karte, schaltflaeche, gedaempft …, ~49) auf Englisch. Mechanisch, aber groß: eine Umbenennung je Commit, danach jede Ansicht im Browser öffnen |
ja, in kleinen Schritten |
| 4c | C#: Kommentare und nicht gespeicherte Bezeichner (Klassen, Methoden, Variablen) in ~167 Dateien. StagingAktion, Vorgabe, Rahmen, Werkzeugrechte … Öffentliche Namen ändern bricht Aufrufer — nach jedem Schritt bauen und testen |
ja, dateiweise |
| 4d | C#: Texte, die Modelle lesen — Werkzeugbeschreibungen, Fehlermeldungen an Agenten, Systemhinweise (~23 Werkzeugdateien, ~20 Meldungen). Danach eine Nacht Testinstanz auf der VM und Audit-Vergleich: arbeiten die Agenten wie vorher? | nein |
| 4e | API-Pfade: /api/verwaltung, /api/instanz, /instanzen, /hooks/{instanz} → englisch. Das bricht Absender von außen (n8n, Claude Code über MCP). Alte Pfade eine Version lang als Umleitung behalten |
nein |
Prüfung der Sprachpakete nach jeder Stufe:
python -c "import json;e=json.load(open('src/ClawdDotNet.Manager.Web/wwwroot/i18n/en.json',encoding='utf-8'));d=json.load(open('src/ClawdDotNet.Manager.Web/wwwroot/i18n/de.json',encoding='utf-8'));print(set(e)^set(d) or 'gleich')"
Besser: als Test in tests/ClawdDotNet.Web.Tests anlegen, dann prüft ihn jeder Lauf.
4 — Wer was macht
Der Mensch fragte, ob ein Gemini Flash genügt. Antwort: für etwa zwei Drittel ja — für Stufe 0, 1 (reine Ansichten), 3 und 4a–4c, wenn diese Datei mitgegeben wird und jede Stufe vor dem Merge von einem starken Modell gegengelesen wird. Nicht für Stufe 2 (neue Anmeldeart), 4d (Prompts) und 4e (Pfade nach außen) und nicht für Lizenz/Schlüsselbund in Stufe 1.
Gegenlesen heißt mindestens: git diff --stat auf unerwartet große Löschungen prüfen; nach
gelöschten Kommentarblöcken suchen (git diff | grep '^-\s*//'); Sprachpakete gleich; alle
vier Suiten grün auf Windows und Linux.
5 — Fertig ist es, wenn
src/ClawdDotNet.Desktopkeine Avalonia-Fenster mehr enthält und die Hülle unter Windows und Linux die WebUI angemeldet öffnet- jede Funktion aus der Tabelle in Abschnitt 7 in der WebUI erreichbar ist
grep -rn "[äöüÄÖÜß]" src --include=*.cs --include=*.js --include=*.cssnur noch Treffer ini18n/de.json-Inhalten, Testdaten und Kommentaren mit Zitaten liefert- die Testinstanz auf der VM eine Nacht mit der neuen Fassung läuft und das Audit keine neuen Fehlerbilder zeigt
6 — Gespeicherte Namen: nicht umbenennen
Diese Namen stehen in Dateien und Datenbanken bestehender Installationen. Eine Umbenennung braucht eine Migration (alt lesen, neu schreiben) und einen Test mit einer alten Datei. Im Zweifel: deutsch lassen und im Code mit einem englischen Namen kapseln.
| Wo | Beispiele |
|---|---|
Werkzeugeinstellungen der Agenten (AgentSettings.json, Tools.<Name>) |
erlaubt, verboten (Datenbank-/Werkzeugrechte), sharedAccessLevel, … |
Tabellen in state.db (SqliteStorage.cs) |
Dauerfreigaben, Spalten aller Tabellen |
Audit-Einträge, Source-Werte, DecidedBy-Präfixe |
werden gelesen und ausgewertet |
| Aufgabendateien (Frontmatter), Taskboard-Felder | onlyWhenMarketOpen, require_approval … |
manager.json, InstanceSettings.json (PascalCase-Altbestand) |
Schlüssel exakt so lassen |
| Sprachschlüssel selbst | sind schon englisch — gut so |
7 — Bestandsaufnahme (Stufe 0 füllt das aus)
Stand 2026-10-02, erhoben gegen main (c03d6d0). Quelle je Zeile: die [RelayCommand]s und
[ObservableProperty]s der Ansichtsmodelle in src/ClawdDotNet.Desktop/ViewModels.
| Desktop-Funktion | Fenster | In der WebUI? | Endpunkt vorhanden? | Bemerkung |
|---|---|---|---|---|
| Navigation, Seitenleiste einklappen, Hell/Dunkel, Sprache | MainWindow |
ja | — | index.html / app.js |
| Statusleiste: OpenRouter erreichbar, Guthaben, Tokens 1 h/24 h | MainWindow |
ja | GET /api/status |
Kopfzeile in app.js |
| Benachrichtigungsleiste | MainWindow |
— | — | war im Desktop immer leer (Platzhalter), entfällt |
| Instanzordner im Dateimanager öffnen | MainWindow, InfoPageView |
nein | — | entfällt: Browser kann keinen Ordner öffnen; Pfad steht auf der Info-Seite |
| Instanzliste, wählen, wechseln | InstancePickerWindow |
ja | GET /api/verwaltung/instanzen |
views/instances.js |
| Instanz anlegen | InstancePickerWindow |
ja | POST /api/verwaltung/instanzen |
|
| Instanz starten / anhalten | — (Manager) | ja | …/start, …/stop |
|
| „Fenster der Instanz zeigen" | — | ja | POST …/instanzen/{id}/fenster, /api/instanz/fenster |
entfällt in Stufe 3 — es gibt dann kein Fenster mehr |
| Lizenzschlüssel eingeben (Erststart, Ablauf, Hardwarewechsel) | LicenseWindow |
nein — nur Anzeige „verschlüsselt" | nein | Manager fragt nie (NonInteractiveLicensePrompt); heute nur über manager.json von der Einrichtung. Der Hinweis auf --license-set-key im Log verweist auf einen Schalter, den es nicht gibt. Sicherheitsstelle → starkes Modell |
| Lizenzschlüssel ändern | SettingsPageView |
nein | nein | wie oben, Schreiben nur, nie zurücklesen |
| Wiederherstellungs-Passphrase des Schlüsselbunds | — | nein | nein | Gibt es nirgends, auch im Desktop nicht: SecretKeyStore.SetRecoveryPassphrase hat außer Tests keinen Aufrufer. Die Startwarnung ist damit heute nicht behebbar. Sicherheitsstelle |
| Anwendungseinstellungen: Instanzverzeichnis, Log-Stufe, Log-Zeilen, Log-Takt, OpenRouter-URL, Prüftakt | SettingsPageView |
nur Anzeige, teils fest im JS (dc.mhdf.de, Port) |
nein | views/settings.js zeigt Text, liest keine echten Werte |
| Deploymentcenter: URL, Token, Umgebung, Fehlerberichte an/aus, Updateprüfung, Kanal | SettingsPageView |
nur Anzeige (fest im JS) | nein | Token = Geheimnis, nur schreiben |
| Instanzeinstellungen: Name, Log-Verzeichnis, Autostart durch Manager | SettingsPageView |
nur Anzeige | nein | Autostart wird angezeigt (autostart in der Instanzliste), aber nicht schaltbar |
| OpenRouter-API-Schlüssel der Instanz | SettingsPageView |
nein (maskiert angezeigt) | nein | ohne ihn startet keine Agent-Engine — Erstinstallation hängt daran |
| Tagesbudget der Instanz (USD, Tokens) | SettingsPageView |
nein | nein | Agentenbudgets gehen über Einheiten (/organisation/units/{id}/settings), das Instanzbudget nicht |
| Agentenliste, Werkzeuge an/aus | AgentsPageView |
ja | GET /api/agents, PUT …/tools/{tool} |
|
| Agent anlegen / löschen | AddAgentWindow, AgentsPageView |
ja | POST/DELETE /api/agents |
|
| Agent jetzt laufen lassen | AgentsPageView |
nein | ja, POST /api/agents/{id}/run |
reine Ansicht |
| Agent bearbeiten: Anzeigename, Modell, Systemprompt, Beschreibung, Prompt-Caching, max. Schritte/Kontext/Werkzeugausgabe, Zeitlimit, Budget, „wenn erschöpft", aktiv | AgentsPageView |
nein | nein (kein PUT /api/agents/{id}) |
Modell/Budget/„wenn erschöpft" teilweise über Einheiten-Einstellungen (PerAgent), der Rest gar nicht |
| Identity / Soul bearbeiten (Texteditor) | TextEditorWindow |
nein | nein | Dateien im Agentenordner; gehen in den Prompt → Eingabe ist Prompt-Inhalt |
| Agentenordner öffnen | AgentsPageView |
nein | — | entfällt (Browser) |
| Werkzeugeinstellungen je Agent (FTP, Mail, Datenbank, Telegram, DirectAPI, WebFetch, SocialMedia, FileRW) inkl. Zugangsdaten | ToolSettingsView |
nur Lesen | nur GET …/tools/{tool}/settings, kein PUT |
Zugangsdaten → nur schreiben, nie zurücklesen (Muster: PUT /organisation/units/{id}/credentials, #692). Gespeicherte Schlüssel bleiben (Abschnitt 6) |
| Werkzeugrechte (erlaubt / Freigabe / verboten) | — | ja | GET/PUT …/rights |
nur WebUI |
| Chat mit Agent, abbrechen, Verlauf löschen | ChatPageView |
ja | /api/agents/{id}/chat |
|
| Agentengespräche (A2A) | AgentChatsPageView |
ja | GET /api/agents/communications |
|
| Aufgaben / geplante Läufe („Jobs") anlegen, bearbeiten, löschen, an/aus, jetzt starten, Verlauf | TasksPageView, AddJobWindow |
ja (Taskboard) | /api/tasks |
Desktop-Reiter „Jobs" schreibt die Alt-Konfiguration, die seit #594 wirkungslos ist — kein Nachbau |
| Dienste anlegen, löschen, an/aus | TasksPageView, AddServiceWindow |
ja | /api/services |
|
| Tokenverbrauch | TokenUsagePageView |
ja (mehr als Desktop) | /api/usage… |
|
| Protokoll live, Modul-/Stufenfilter, leeren | LogPageView |
ja | /events/logs, /api/logs/modules |
|
| Protokollordner öffnen | LogPageView |
nein | — | entfällt (Browser) |
| Sicherung anlegen, Liste, löschen | BackupPageView |
ja | /api/verwaltung/instanzen/{id}/backups |
Manager verschlüsselt immer mit dem Lizenzschlüssel; Desktop-Wahl „Zugangsdaten ausschließen / Passphrase" entfällt bewusst |
| Sicherung zurückspielen in die bestehende Instanz | RestoreBackupWindow |
ja | POST …/backups/{file}/restore |
inkl. fremder Lizenz |
| Sicherung in ein neues Zielverzeichnis zurückspielen / Sicherungsdatei von außen einspielen | RestoreBackupWindow |
nein | nein | Umzug auf eine neue Maschine: dort gibt es noch keine Instanz und damit keine Sicherungsliste. Braucht Hochladen + „als neue Instanz anlegen" |
| Automatische Sicherung: an/aus, Uhrzeit, Anzahl behalten | BackupPageView |
nein | nein | Manager führt sie aus (ManagerBackups, liest autoBackupEnabled/autoBackupTime aus InstanceSettings.json) — nur einstellen kann man sie nicht mehr |
| Sicherung im Ordner zeigen | BackupPageView |
nein | — | entfällt (Browser) |
| FTP-Upload der Sicherungen | — | ja | /api/verwaltung/sicherung/ftp |
nur WebUI |
| Info-Seite: Version, Pfade, Teilsysteme | InfoPageView |
ja | GET /api/info |
|
| Beenden | MainWindow |
— | — | Aufgabe der Hülle (Stufe 2) |
Fehlt in der WebUI — Eingang für Stufe 1
| # | Lücke | C# nötig? | Sicherheitsstelle? |
|---|---|---|---|
| L1 | Lizenzschlüssel eingeben / ändern (Manager) | ja, Manager-Endpunkt | ja |
| Wiederherstellungs-Passphrase setzen | ja — gibt es nirgends | ja — vom Menschen am 2026-10-02 herausgelöst: eigenes Item #780 | |
| L3 | Anwendungs- und Deploymentcenter-Einstellungen bearbeiten (Settings-Seite liest heute nichts Echtes) | ja | DC-Token: ja |
| L4 | Instanzeinstellungen: Name, Log-Verzeichnis, Autostart, Instanzbudget | ja | nein |
| L5 | OpenRouter-API-Schlüssel der Instanz setzen | ja | ja (Geheimnis) |
| L6 | Agent bearbeiten (Stammdaten, Grenzen, Budget, aktiv) | ja, PUT /api/agents/{id} |
nein |
| L7 | Identity / Soul bearbeiten | ja | Prompt-Inhalt, nicht Sicherheit |
| L8 | Werkzeugeinstellungen inkl. Zugangsdaten schreiben | ja | ja (Geheimnisse) |
| L9 | Agent „jetzt laufen lassen" | nein, Endpunkt da | nein |
| L10 | Automatische Sicherung einstellen | ja | nein |
| L11 | Sicherung hochladen / als neue Instanz zurückspielen — vom Menschen am 2026-10-02 für Stufe 1 bestätigt | ja | Upload → ja |