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>
65 lines
2.7 KiB
C#
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));
|
|
}
|