Initial commit: ClawdDotNet

Import des bestehenden Projektstands in Git.
- .NET 10 WinForms Anwendung (Multi-Agent / Tool-System)
- .gitignore fuer Build-Artefakte, Secrets und Runtime-Daten ergaenzt

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-07-26 18:21:46 +02:00
co-authored by Claude Opus 4.8
commit 2fed388c99
154 changed files with 29736 additions and 0 deletions
+247
View File
@@ -0,0 +1,247 @@
using ClawdDotNet.Core.Api;
using ClawdDotNet.Core.Config;
using ClawdDotNet.Core.Engine;
using ClawdDotNet.Core.Logging;
using ClawdDotNet.Core.Security;
using ClawdDotNet.Core.Scheduling;
using ClawdDotNet.Core.Tools;
using ClawdDotNet.Core.State;
using ClawdDotNet.Services;
using ClawdDotNet.Tools.FileRW;
using ClawdDotNet.Tools.Telegram;
using ClawdDotNet.Tools.Mail;
using ClawdDotNet.Tools.Database;
using ClawdDotNet.Tools.FTP;
using ClawdDotNet.Tools.DirectAPI;
using ClawdDotNet.Tools.WebFetch;
using ClawdDotNet.Tools.WebMonitor;
using ClawdDotNet.Tools.AgentComm;
using ClawdDotNet.Tools.AgentSpawn;
using ClawdDotNet.Tools.SocialMediaManager;
using ClawdDotNet.Tools.AgentEditor;
using ClawdDotNet.Tools.TelegramClient;
using ClawdDotNet.UI;
using Microsoft.Extensions.Logging;
namespace ClawdDotNet;
internal static class Program
{
[STAThread]
static void Main(string[] args)
{
ApplicationConfiguration.Initialize();
// ─── 0. Embedded UI extrahieren ───
EmbeddedUiManager.ExtractToTemp();
// ─── 1. App-Settings laden ───
var settingsManager = new SettingsManager();
settingsManager.Load();
var appSettings = settingsManager.AppSettings;
// ─── 2. InstanceDirectoryManager erstellen ───
var instancesDir = Path.GetFullPath(appSettings.InstancesDirectory);
var dirManager = new InstanceDirectoryManager(instancesDir);
// ─── 3. Instanz-Verzeichnis auswählen ───
string instancePath;
#if DEBUG
// Im Debug-Modus: Dev-Instanz automatisch erstellen/starten
const string devInstanceName = "Dev";
instancePath = dirManager.GetInstancePath(devInstanceName);
if (!Directory.Exists(instancePath))
{
dirManager.CreateInstance(devInstanceName);
}
#else
// Im Release-Modus: InstanceManager anzeigen
var instanceManager = new frm_InstanceManager(dirManager, settingsManager);
var dialogResult = instanceManager.ShowDialog();
if (dialogResult != DialogResult.OK || string.IsNullOrWhiteSpace(instanceManager.SelectedInstancePath))
{
return; // Benutzer hat abgebrochen
}
instancePath = instanceManager.SelectedInstancePath;
instanceManager.Dispose();
#endif
// ─── 4. Instanz-Config aus Verzeichnisstruktur laden ───
InstanceConfig instanceConfig;
try
{
instanceConfig = dirManager.LoadInstanceConfig(instancePath);
}
catch (Exception ex)
{
MessageBox.Show(
$"Fehler beim Laden der Instanz:\n{instancePath}\n\n{ex.Message}",
"ClawdDotNet Fehler",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// ─── 5. Logging-System initialisieren ───
var logDir = Path.GetFullPath(
!string.IsNullOrWhiteSpace(instanceConfig.LogDirectory)
? instanceConfig.LogDirectory
: appSettings.LogDirectory);
var minLevel = Enum.TryParse<ClawdDotNet.Core.Logging.LogLevel>(
appSettings.MinimumLogLevel, true, out var ml)
? ml
: ClawdDotNet.Core.Logging.LogLevel.Info;
var loggerFactory = LoggingExtensions.CreateClawdLoggerFactory(logDir, minLevel);
var coreLogger = loggerFactory.CreateLogger("ClawdDotNet.Core.Startup");
coreLogger.LogInformation("ClawdDotNet startet Instanz: {Instance} ({Id})",
instanceConfig.InstanceName, instanceConfig.InstanceId);
coreLogger.LogInformation("Instanz-Verzeichnis: {Path}", instancePath);
// ─── 6. Core-Komponenten erzeugen ───
var toolRegistry = new ToolRegistry();
toolRegistry.Register(new FileRWTool());
toolRegistry.Register(new TelegramTool());
toolRegistry.Register(new MailTool());
toolRegistry.Register(new DatabaseTool());
toolRegistry.Register(new FTPTool());
toolRegistry.Register(new DirectApiTool());
toolRegistry.Register(new WebFetchTool());
toolRegistry.Register(new WebMonitorTool());
toolRegistry.Register(new AgentCommTool());
toolRegistry.Register(new SocialMediaManagerTool());
toolRegistry.Register(new AgentSpawnTool());
toolRegistry.Register(new AgentEditorTool());
// ─── 6a. TelegramClient (MTProto User-API) ───
TelegramClientManager? tgClientManager = null;
if (instanceConfig.TelegramClient is not null)
{
tgClientManager = new TelegramClientManager(
instanceConfig,
instancePath,
loggerFactory.CreateLogger("ClawdDotNet.Tools.TelegramClient"));
toolRegistry.Register(new TelegramClientTool(tgClientManager));
coreLogger.LogInformation("TelegramClient-Tool registriert");
}
var permissionGate = new PermissionGate();
// TODO: Tools aus tools/ Ordner laden
// foreach (var toolDll in Directory.GetFiles("./tools", "*.dll"))
// LoadToolPlugin(toolDll, toolRegistry);
OpenRouterClient? openRouterClient = null;
AgentEngine? agentEngine = null;
AgentScheduler? agentScheduler = null;
ToolJobScheduler? toolJobScheduler = null;
if (!string.IsNullOrWhiteSpace(instanceConfig.OpenRouterApiKey))
{
openRouterClient = new OpenRouterClient(
instanceConfig.OpenRouterApiKey,
loggerFactory.CreateLogger("ClawdDotNet.Core.Api.OpenRouterClient"));
// ModelTypeConverter mit dem Client verbinden für PropertyGrid-Dropdown
ClawdDotNet.Models.ModelTypeConverter.Client = openRouterClient;
// ─── 6.1. StateStore initialisieren ───
var stateDbPath = Path.Combine(instancePath, "state.db");
var stateStore = new SqliteStateStore(stateDbPath);
agentEngine = new AgentEngine(openRouterClient, toolRegistry, permissionGate, stateStore, loggerFactory);
agentEngine.SetAgentConfigProvider(
() => instanceConfig.Agents,
instanceConfig.InstanceId,
agentId =>
{
var agent = instanceConfig.Agents.FirstOrDefault(a => a.AgentId == agentId);
if (agent is null) return null;
return string.IsNullOrWhiteSpace(agent.AgentDir) ? null : agent.AgentDir;
});
agentEngine.LoadPersistedChats();
agentScheduler = new AgentScheduler(agentEngine, instanceConfig.InstanceId, loggerFactory);
agentScheduler.RegisterAll(instanceConfig.Agents);
toolJobScheduler = new ToolJobScheduler(agentEngine, toolRegistry, stateStore, loggerFactory, instanceConfig.InstanceId);
toolJobScheduler.RegisterAll(instanceConfig.Agents);
coreLogger.LogInformation("AgentEngine und Scheduler erstellt, Chat-Verläufe geladen");
}
else
{
coreLogger.LogWarning("Kein OpenRouter API-Key konfiguriert Agenten sind deaktiviert");
}
// ─── 6b. TelegramClient verbinden (Session oder interaktiver Login) ───
if (tgClientManager is not null)
{
tgClientManager.OnLoginCodeRequired += async (prompt) =>
{
string? code = null;
await Task.Run(() =>
{
code = Microsoft.VisualBasic.Interaction.InputBox(
prompt, "Telegram Verifizierung", "");
});
return code ?? "";
};
tgClientManager.On2FAPasswordRequired += async () =>
{
string? pw = null;
await Task.Run(() =>
{
pw = Microsoft.VisualBasic.Interaction.InputBox(
"Bitte 2FA-Passwort eingeben:", "Telegram 2FA", "");
});
return pw ?? "";
};
try
{
tgClientManager.ConnectAsync(CancellationToken.None)
.GetAwaiter().GetResult();
}
catch (Exception ex)
{
coreLogger.LogError(ex, "Telegram: Login fehlgeschlagen");
}
}
// ─── 7. MainForm starten ───
var form = new frm_main(
settingsManager,
instanceConfig,
instancePath,
logDir,
loggerFactory,
toolRegistry,
dirManager,
agentEngine,
agentScheduler,
toolJobScheduler);
Application.Run(form);
// ─── 8. Aufräumen ───
coreLogger.LogInformation("ClawdDotNet wird beendet");
if (toolJobScheduler is not null)
toolJobScheduler.DisposeAsync().AsTask().GetAwaiter().GetResult();
if (agentScheduler is not null)
agentScheduler.DisposeAsync().AsTask().GetAwaiter().GetResult();
if (tgClientManager is not null)
tgClientManager.DisposeAsync().AsTask().GetAwaiter().GetResult();
openRouterClient?.Dispose();
loggerFactory.Dispose();
}
}