Files
ClawdDotNet/src/ClawdDotNet.Desktop/CommandLine.cs
T
RichardandClaude Opus 5.5 cb46289bb6 ClawdDotNet als MCP-Server: durch dieselben Pruefstellen (#713)
Eine fremde Laufzeit oder der eigene Claude Code des Menschen spricht per MCP
mit der Instanz. Der Server bietet genau die Werkzeuge des Agenten hinter dem
Token an; jeder Aufruf laeuft durch die Engine wie ein Aufruf des eigenen
Modells (Rechtetor, Vorpruefung, Werkzeugrechte, Staging, Audit mit Quelle
mcp, Rahmung), und der Aufrufer gilt als Leser fremder Inhalte (#715).

Eigener Socket mcp.sock statt manager.sock: ueber den Instanz-Socket antwortet
die Verwaltung ohne Token, ueber mcp.sock gibt es nur /mcp und nur mit
MCP-Token. Lauf-Tokens nur im Speicher, enden mit dem Lauf; persoenliche Tokens
(hoechstens 90 Tage, widerrufbar, nur als SHA-256) in der Agentenansicht.
Transporte: HTTP auf mcp.sock, Weboberflaeche und Manager (/mcp/{instanz}),
stdio ueber ClawdDotNet --mcp-bridge (Token nur aus Umgebung oder 0600-Datei).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 17:28:47 +02:00

65 lines
2.7 KiB
C#

namespace ClawdDotNet.Desktop;
/// <summary>
/// Die Argumente, die vor allem anderen gelesen werden müssen.
///
/// <para>Eigene Klasse, weil sie zwei Aufrufer hat, die sich nicht kennen dürfen:
/// <see cref="Program"/> entscheidet damit, ob überhaupt ein Fenster entsteht, und
/// <see cref="App"/> übernimmt die vorgewählte Instanz in den Startvorgang. Lägen sie in
/// <c>App</c>, müsste <c>Program</c> die Oberfläche anfassen, um zu erfahren, dass keine
/// gebraucht wird.</para>
/// </summary>
internal static class CommandLine
{
public const string InstanceArgument = "--instance";
/// <summary>Läuft ohne Fenster: nur Aufbau, Socket und Warten (#528, Stufe 2).</summary>
public const string HeadlessArgument = "--headless";
/// <summary>
/// Gestartet und beaufsichtigt vom Instanzmanager (#528, Stufe 5).
///
/// <para>Dann gehört der Instanzwechsel dorthin und nicht in dieses Fenster: Der
/// Manager hält die Fenster aller Instanzen im Hintergrund und holt das gewünschte
/// nach vorn. Ein Fenster, das sich selbst mit einer anderen Instanz neu startet,
/// nähme dabei genau die Instanz mit, aus der heraus jemand wechselt — und das ist
/// der Vorfall, mit dem dieses Vorhaben angefangen hat (#529).</para>
/// </summary>
public const string ManagedArgument = "--managed";
/// <summary>
/// Der Instanzpfad hinter <c>--instance</c>, oder <c>null</c>.
///
/// <para>Bewusst ohne Prüfung, ob es das Verzeichnis gibt — das entscheidet der
/// Aufrufer, und er entscheidet es unterschiedlich: Mit Fenster erscheint dann der
/// Auswahldialog, ohne Fenster ist es ein Abbruch mit Meldung.</para>
/// </summary>
public static string? ReadInstancePath(IReadOnlyList<string>? args)
{
if (args is null) return null;
for (var i = 0; i < args.Count - 1; i++)
{
if (string.Equals(args[i], InstanceArgument, StringComparison.OrdinalIgnoreCase))
return args[i + 1];
}
return null;
}
/// <summary>#713: Only the stdio bridge to a running instance's MCP server — no application.</summary>
public static bool IsMcpBridge(IReadOnlyList<string>? args)
=> Has(args, Core.Mcp.McpStdioBridge.Argument);
public static bool IsHeadless(IReadOnlyList<string>? args)
=> Has(args, HeadlessArgument);
/// <inheritdoc cref="ManagedArgument"/>
public static bool IsManaged(IReadOnlyList<string>? args)
=> Has(args, ManagedArgument);
private static bool Has(IReadOnlyList<string>? args, string flag)
=> args is not null
&& args.Any(a => string.Equals(a, flag, StringComparison.OrdinalIgnoreCase));
}