Der Managerprozess. ClawdDotNet.Instanzmanager ist eine Konsolenanwendung: Lizenz pruefen, uebernehmen was laeuft, Weboberflaeche aufhaengen, warten. Beim Herunterfahren beendet er keine Instanz. Zwei neue Projekte. ClawdDotNet.Manager.Web traegt die Weboberflaeche - ohne jeden Verweis auf ClawdDotNet.Web, denn dort haengt App und daran sechzehn Werkzeugprojekte. ClawdDotNet.ManagerApp ist der Einstiegspunkt. wwwroot ist aus der Instanz in den Manager gezogen. DER SCHNITT DER HTTP-FLAECHE: Unter /api/verwaltung steht, was den Manager angeht - auflisten, anlegen, starten, anhalten. Alles andere unter /api geht unveraendert an eine Instanz. Er leitet weiter, er implementiert nicht. Welche Instanz gemeint ist, sagt die Kopfzeile X-Instanz; laeuft genau eine, ist sie gemeint, und laufen mehrere, wird nachgefragt statt geraten - eine Anfrage an die falsche Instanz ist schlimmer als eine abgelehnte. Der zusammengefuehrte Ereignisstrom haelt je laufender Instanz eine Zuleitung und schreibt an jedes Ereignis, von wem es kommt. Ergaenzt statt verpackt: Ein Umschlag waere einfacher gewesen, haette aber jede Ansicht der Weboberflaeche zum Umschreiben gezwungen. ABNAHME gegen laufende Prozesse: 401 ohne Token, Oberflaeche ohne Token 200, Instanz ueber den Manager gestartet und angehalten, /api/info und /api/status unverfaelscht durchgereicht, /events/logs mit "instanz":"Instance-Test" an jeder Zeile. Manager abgeschossen: Instanz laeuft weiter. Manager neu gestartet: "1 Instanzen bekannt, 1 laufen bereits" - uebernommen. E-M6 damit in beide Richtungen belegt. DREI DEFEKTE, die erst der Lauf gezeigt hat: 1. Der Manager hing an einer Konsolenabfrage nach dem Lizenzschluessel. Ein Test auf Console.IsInputRedirected reicht dafuer NICHT: Er beantwortet "ist die Eingabe umgeleitet", nicht "kann jemand antworten" - ein Prozess ganz ohne Konsole, der gefaehrlichste Fall, ist nicht umgeleitet. Der Manager fragt jetzt gar nicht. 2. Eine unlesbare manager.json wurde stillschweigend durch Vorgaben ersetzt: falsches Instanzverzeichnis, anderer Port, Lizenzfrage - und nichts sagte, woran es lag. LoadProblem meldet den Grund jetzt. 3. Der Instanzprozess erbte CLAWD_CONFIG_DIR vom Manager und legte sich in dessen Konfigurationsverzeichnis eine eigene Settings.json an. Eine Umgebungsvariable vererbt sich, ein Argument nicht - der Manager nimmt sein Verzeichnis jetzt ueber --config. SharedLoggerProvider ist nach Core gezogen: Es gibt jetzt zwei Webhosts, die dasselbe brauchen, und sie duerfen einander nicht kennen. NOCH OFFEN in dieser Stufe: Die Weboberflaeche kennt noch keine Instanzen - Instanzauswahl, X-Instanz und die Verwaltungsansicht sind Arbeit an wwwroot. Und webServerPort steht noch in der Instanz. Build ohne Warnungen, 775 Tests gruen, 8 uebersprungen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
173 lines
8.5 KiB
HTML
173 lines
8.5 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>ClawdDotNet</title>
|
|
<link rel="stylesheet" href="app.css">
|
|
</head>
|
|
<body>
|
|
|
|
<!-- ─── Anmelde-Ansicht ─── -->
|
|
<div id="anmeldung">
|
|
<div class="karte anmelde-kasten">
|
|
<div class="karte-kopf">
|
|
<h2>ClawdDotNet</h2>
|
|
</div>
|
|
<p class="hinweis">
|
|
Bitte gib das Zugangstoken der Instanz ein (<code>webUiToken</code> in der Instanzdatei).
|
|
</p>
|
|
<form id="anmeldeformular" class="formular-raster">
|
|
<input type="password" id="token-eingabe" placeholder="Zugangstoken (mind. 20 Zeichen)" autocomplete="current-password" required>
|
|
<button type="submit" class="primaer">Anmelden</button>
|
|
<p id="anmeldefehler" class="fehler" hidden></p>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ─── Hauptanwendung ─── -->
|
|
<div id="anwendung" hidden>
|
|
<div id="seitenleiste-backdrop" class="seitenleiste-backdrop" hidden></div>
|
|
|
|
<!-- Seitenleiste / Navigation -->
|
|
<aside id="seitenleiste" class="seitenleiste">
|
|
<div class="seitenleiste-kopf">
|
|
<span class="marke">ClawdDotNet</span>
|
|
<button id="sidebar-toggle" class="schaltflaeche-icon flach" title="Seitenleiste ein-/ausklappen" type="button">
|
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="M15 18l-6-6 6-6"/>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
|
|
<nav class="seitenleiste-inhalt">
|
|
<div class="nav-gruppe">
|
|
<div class="nav-gruppe-titel">Arbeiten</div>
|
|
<a href="#/chat" class="nav-link" title="Chat">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75">
|
|
<path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/>
|
|
</svg>
|
|
<span class="nav-label">Chat</span>
|
|
</a>
|
|
<a href="#/agenten" class="nav-link" title="Agenten">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75">
|
|
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2 M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8z M23 21v-2a4 4 0 0 0-3-3.87 M16 3.13a4 4 0 0 1 0 7.75"/>
|
|
</svg>
|
|
<span class="nav-label">Agenten</span>
|
|
</a>
|
|
<a href="#/aufgaben" class="nav-link" title="Aufgaben">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75">
|
|
<path d="M9 11l3 3L22 4 M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/>
|
|
</svg>
|
|
<span class="nav-label">Aufgaben</span>
|
|
</a>
|
|
<a href="#/dienste" class="nav-link" title="Dienste">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75">
|
|
<path d="M4 14a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v6a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-6z M4 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4z M12 6v6 M8 8h.01 M16 8h.01"/>
|
|
</svg>
|
|
<span class="nav-label">Dienste</span>
|
|
</a>
|
|
</div>
|
|
|
|
<div class="nav-gruppe">
|
|
<div class="nav-gruppe-titel">Analyse</div>
|
|
<a href="#/verbrauch" class="nav-link" title="Tokennutzung">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75">
|
|
<path d="M3 3v18h18 M7 15v4 M11 11v8 M15 7v12 M19 12v7"/>
|
|
</svg>
|
|
<span class="nav-label">Tokennutzung</span>
|
|
</a>
|
|
<a href="#/agenten-chats" class="nav-link" title="Agenten-Chats">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75">
|
|
<path d="M8 12h.01M12 12h.01M16 12h.01 M21 12c0 4.4-4 8-9 8-1.3 0-2.6-.2-3.7-.7L3 20l1-4.2C3.4 14.6 3 13.3 3 12c0-4.4 4-8 9-8s9 3.6 9 8Z"/>
|
|
</svg>
|
|
<span class="nav-label">Agenten-Chats</span>
|
|
</a>
|
|
</div>
|
|
|
|
<div class="nav-gruppe">
|
|
<div class="nav-gruppe-titel">System</div>
|
|
<a href="#/staging" class="nav-link" title="Freigaben">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75">
|
|
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z M9 12l2 2 4-4"/>
|
|
</svg>
|
|
<span class="nav-label">Freigaben</span>
|
|
<span id="staging-badge" class="nav-badge" hidden>0</span>
|
|
</a>
|
|
<a href="#/protokoll" class="nav-link" title="Protokoll">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75">
|
|
<path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20 M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z M8 7h8 M8 11h6"/>
|
|
</svg>
|
|
<span class="nav-label">Protokoll</span>
|
|
</a>
|
|
<a href="#/sicherung" class="nav-link" title="Sicherung">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75">
|
|
<path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z M17 21v-8H7v8 M7 3v5h8"/>
|
|
</svg>
|
|
<span class="nav-label">Sicherung</span>
|
|
</a>
|
|
<a href="#/einstellungen" class="nav-link" title="Einstellungen">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75">
|
|
<circle cx="12" cy="12" r="3"/>
|
|
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>
|
|
</svg>
|
|
<span class="nav-label">Einstellungen</span>
|
|
</a>
|
|
<a href="#/info" class="nav-link" title="Info">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75">
|
|
<circle cx="12" cy="12" r="10"/>
|
|
<line x1="12" y1="16" x2="12" y2="12"/>
|
|
<line x1="12" y1="8" x2="12.01" y2="8"/>
|
|
</svg>
|
|
<span class="nav-label">Info</span>
|
|
</a>
|
|
</div>
|
|
</nav>
|
|
</aside>
|
|
|
|
<!-- Hauptinhalt -->
|
|
<div class="hauptbereich">
|
|
<header class="kopfzeile">
|
|
<div class="kopfzeile-links">
|
|
<button id="mobil-menue-btn" class="schaltflaeche-icon flach" title="Menü öffnen" type="button">
|
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<line x1="3" y1="12" x2="21" y2="12"/>
|
|
<line x1="3" y1="6" x2="21" y2="6"/>
|
|
<line x1="3" y1="18" x2="21" y2="18"/>
|
|
</svg>
|
|
</button>
|
|
<span id="kopf-instanz" class="gedaempft"></span>
|
|
</div>
|
|
|
|
<div class="kopfzeile-rechts">
|
|
<span id="kopf-openrouter-status" class="gedaempft text-klein"></span>
|
|
<span id="verbindung-punkt" class="status-punkt" title="Ereignisstrom: getrennt"></span>
|
|
<button id="theme-schalter" class="schaltflaeche-icon flach" title="Farbschema umschalten" type="button">
|
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<circle cx="12" cy="12" r="5"/>
|
|
<line x1="12" y1="1" x2="12" y2="3"/>
|
|
<line x1="12" y1="21" x2="12" y2="23"/>
|
|
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
|
|
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
|
|
<line x1="1" y1="12" x2="3" y2="12"/>
|
|
<line x1="21" y1="12" x2="23" y2="12"/>
|
|
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
|
|
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
|
|
</svg>
|
|
</button>
|
|
<button id="abmelden-btn" class="schaltflaeche flach klein" title="Abmelden" type="button">
|
|
Abmelden
|
|
</button>
|
|
</div>
|
|
</header>
|
|
|
|
<main class="inhalt-scroll">
|
|
<div id="ansicht-inhalt"></div>
|
|
</main>
|
|
</div>
|
|
</div>
|
|
|
|
<script type="module" src="app.js"></script>
|
|
</body>
|
|
</html>
|