feat(ui): complete Avalonia UI port with 7 main pages, tool settings & top MenuBar

This commit is contained in:
Richard
2026-08-10 10:48:34 +02:00
parent a0e18d2a57
commit b5bf97ae74
187 changed files with 20054 additions and 882 deletions
-28
View File
@@ -1,28 +0,0 @@
using System.Text.Json.Serialization;
namespace ClawdDotNet.Models;
/// <summary>
/// Eintrag in der AgentList.json Basisinformationen zu einem Agenten.
/// Liegt im Agents/-Ordner einer Instanz.
/// </summary>
public sealed class AgentListItem
{
[JsonPropertyName("name")]
public string Name { get; set; } = "";
[JsonPropertyName("description")]
public string Description { get; set; } = "";
[JsonPropertyName("folderName")]
public string FolderName { get; set; } = "";
}
/// <summary>
/// Root-Objekt der AgentList.json
/// </summary>
public sealed class AgentListFile
{
[JsonPropertyName("agents")]
public List<AgentListItem> Agents { get; set; } = new();
}
-82
View File
@@ -1,82 +0,0 @@
using System.ComponentModel;
using System.Text.Json.Serialization;
namespace ClawdDotNet.Models;
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class AppSettings
{
[Category("Allgemein")]
[DisplayName("Log-Verzeichnis")]
[Description("Pfad zum Verzeichnis, in dem Log-Dateien gespeichert werden.")]
[JsonPropertyName("logDirectory")]
public string LogDirectory { get; set; } = "./Logs";
[Category("Allgemein")]
[DisplayName("Instanzen-Verzeichnis")]
[Description("Pfad zum Verzeichnis, in dem alle Instanz-Ordner liegen.")]
[JsonPropertyName("instancesDirectory")]
public string InstancesDirectory { get; set; } = "./Instances";
[Category("Allgemein")]
[DisplayName("Standard-Konfigurations-Datei")]
[Description("Pfad zur Standard-Instanz-Konfiguration (Legacy). Neue Instanzen nutzen das Instanzen-Verzeichnis.")]
[JsonPropertyName("defaultConfigPath")]
public string DefaultConfigPath { get; set; } = "./configs/config.json";
[Category("Allgemein")]
[DisplayName("Minimaler Log-Level")]
[Description("Minimaler Log-Level für die Datei-Logs (Debug, Info, Warn, Error).")]
[JsonPropertyName("minimumLogLevel")]
public string MinimumLogLevel { get; set; } = "Info";
[Category("UI")]
[DisplayName("Max. Log-Zeilen in UI")]
[Description("Maximale Anzahl Zeilen in der Log-RichTextBox bevor bereinigt wird.")]
[JsonPropertyName("maxLogLinesInUi")]
public int MaxLogLinesInUi { get; set; } = 2000;
[Category("UI")]
[DisplayName("Log-Aktualisierungsintervall (ms)")]
[Description("Intervall in Millisekunden, in dem die Log-Anzeige aktualisiert wird.")]
[JsonPropertyName("logRefreshIntervalMs")]
public int LogRefreshIntervalMs { get; set; } = 500;
[Category("API")]
[DisplayName("Status-Check-Intervall (Sek)")]
[Description("Intervall in Sekunden für den OpenRouter-API-Status-Check.")]
[JsonPropertyName("statusCheckIntervalSeconds")]
public int StatusCheckIntervalSeconds { get; set; } = 60;
[Category("API")]
[DisplayName("OpenRouter Base-URL")]
[Description("Basis-URL der OpenRouter-API.")]
[JsonPropertyName("openRouterBaseUrl")]
public string OpenRouterBaseUrl { get; set; } = "https://openrouter.ai/api/v1/";
[Category("Backup")]
[DisplayName("Backup-Verzeichnis")]
[Description("Ordner, in dem Sicherungen abgelegt werden.")]
[JsonPropertyName("backupDirectory")]
public string BackupDirectory { get; set; } = "./Backups";
[Category("Backup")]
[DisplayName("Automatisch sichern")]
[Description("Erstellt täglich zur angegebenen Uhrzeit eine Sicherung der laufenden Instanz.")]
[JsonPropertyName("autoBackupEnabled")]
public bool AutoBackupEnabled { get; set; }
[Category("Backup")]
[DisplayName("Uhrzeit der automatischen Sicherung")]
[Description("Tageszeit im Format HH:mm.")]
[JsonPropertyName("autoBackupTime")]
public string AutoBackupTime { get; set; } = "03:00";
[Category("Backup")]
[DisplayName("Aufbewahrte Sicherungen")]
[Description("Wie viele Sicherungen je Instanz behalten werden. Ältere werden entfernt. 0 = alle behalten.")]
[JsonPropertyName("backupKeepCount")]
public int BackupKeepCount { get; set; } = 14;
public override string ToString() => "Anwendungseinstellungen";
}
-13
View File
@@ -1,13 +0,0 @@
namespace ClawdDotNet.Models;
/// <summary>
/// Zusammenfassung einer Instanz für die Anzeige im InstanceManager.
/// </summary>
public sealed class InstanceInfo
{
public string InstanceName { get; set; } = "";
public string FolderName { get; set; } = "";
public string FolderPath { get; set; } = "";
public int AgentCount { get; set; }
public string ApiKeyStatus { get; set; } = "—";
}
+39
View File
@@ -78,6 +78,45 @@ public sealed class InstanceSettingsViewModel
[ReadOnly(true)]
public int AgentCount => _config.Agents.Count;
// ─── WatchDog (Instanz-Heartbeat) ───
// Server-URL und Master-Token stehen app-weit in den Anwendungseinstellungen. Die
// Instanz registriert sich damit selbst; hier stehen nur Source/Gruppe/Intervall.
// Ein/Aus läuft über den Service „Instanz-Watchdog" im Worker-Tab. Änderungen greifen
// beim nächsten Start der Instanz.
[Category("WatchDog")]
[DisplayName("Source")]
[Description("Dienst-Kennung im WatchDog. Alle Instanzen teilen sich dieselbe Source.")]
public string WatchdogSource
{
get => _config.Watchdog.Source;
set => _config.Watchdog.Source = value;
}
[Category("WatchDog")]
[DisplayName("Gruppe")]
[Description("Gruppierung im WatchDog-Dashboard.")]
public string WatchdogGroup
{
get => _config.Watchdog.Group;
set => _config.Watchdog.Group = value;
}
[Category("WatchDog")]
[DisplayName("Intervall (Sek)")]
[Description("Sende-Takt der Heartbeats in Sekunden (mindestens 5).")]
public int WatchdogIntervalSeconds
{
get => _config.Watchdog.IntervalSeconds;
set => _config.Watchdog.IntervalSeconds = value;
}
[Category("WatchDog")]
[DisplayName("Token registriert")]
[Description("Ob diese Instanz bereits einen eigenen Agent-Token vom WatchDog erhalten hat.")]
[ReadOnly(true)]
public bool WatchdogTokenRegistered => _config.Watchdog.HasToken;
[Browsable(false)]
public InstanceConfig UnderlyingConfig => _config;
-24
View File
@@ -1,24 +0,0 @@
using System.Text.Json.Serialization;
namespace ClawdDotNet.Models;
public sealed class JobHistoryEntry
{
[JsonPropertyName("jobName")]
public string JobName { get; set; } = "";
[JsonPropertyName("agent")]
public string Agent { get; set; } = "";
[JsonPropertyName("time")]
public DateTime Time { get; set; } = DateTime.Now;
[JsonPropertyName("jobDescription")]
public string JobDescription { get; set; } = "";
[JsonPropertyName("info")]
public string Info { get; set; } = "";
[JsonPropertyName("status")]
public string Status { get; set; } = "Success"; // Success, Error, Manual
}
-51
View File
@@ -1,51 +0,0 @@
using System.Text.Json.Serialization;
namespace ClawdDotNet.Models;
public sealed class TokenUsageRecord
{
[JsonPropertyName("timestamp")]
public DateTime Timestamp { get; set; } = DateTime.Now;
[JsonPropertyName("agentId")]
public string AgentId { get; set; } = "";
[JsonPropertyName("agentName")]
public string AgentName { get; set; } = "";
[JsonPropertyName("model")]
public string Model { get; set; } = "";
[JsonPropertyName("promptTokens")]
public int PromptTokens { get; set; }
[JsonPropertyName("completionTokens")]
public int CompletionTokens { get; set; }
[JsonPropertyName("totalTokens")]
public int TotalTokens { get; set; }
[JsonPropertyName("costUsd")]
public double CostUsd { get; set; }
[JsonPropertyName("status")]
public string Status { get; set; } = "";
[JsonPropertyName("stepCount")]
public int StepCount { get; set; }
[JsonPropertyName("durationMs")]
public long DurationMs { get; set; }
}
public sealed class TokenUsageFile
{
[JsonPropertyName("instanceId")]
public string InstanceId { get; set; } = "";
[JsonPropertyName("instanceName")]
public string InstanceName { get; set; } = "";
[JsonPropertyName("records")]
public List<TokenUsageRecord> Records { get; set; } = new();
}