Forge
csharpdeeb25a2
1#nullable enable
2
3using System.Net.Http.Headers;
4using System.Net.Http.Json;
5using System.Text.Json;
6using System.Text.Json.Serialization;
7
8namespace CascadeIDE.Features.Forge.Infrastructure;
9
10/// <summary>Runtime import of forge DOI slash catalog (FORGE-ADR-0015 Phase D).</summary>
11public static class ForgeCapabilitiesClient
12{
13 private static readonly JsonSerializerOptions JsonOptions = new()
14 {
15 PropertyNameCaseInsensitive = true,
16 PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
17 };
18
19 public static async Task<IReadOnlyList<ForgeCapabilitiesCommand>> FetchCommandsAsync(
20 string baseUrl,
21 string? apiToken,
22 CancellationToken cancellationToken = default)
23 {
24 var normalized = baseUrl.Trim().TrimEnd('/');
25 using var http = new HttpClient { BaseAddress = new Uri(normalized), Timeout = TimeSpan.FromSeconds(15) };
26 if (!string.IsNullOrEmpty(apiToken))
27 http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiToken);
28
29 using var response = await http.GetAsync("/api/v1/capabilities", cancellationToken).ConfigureAwait(false);
30 response.EnsureSuccessStatusCode();
31
32 await using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
33 using var doc = await JsonDocument.ParseAsync(stream, cancellationToken: cancellationToken).ConfigureAwait(false);
34 if (!doc.RootElement.TryGetProperty("commands", out var commandsElement)
35 || commandsElement.ValueKind != JsonValueKind.Array)
36 {
37 return [];
38 }
39
40 var list = new List<ForgeCapabilitiesCommand>(commandsElement.GetArrayLength());
41 foreach (var item in commandsElement.EnumerateArray())
42 {
43 var command = item.Deserialize<ForgeCapabilitiesCommand>(JsonOptions);
44 if (command is null || string.IsNullOrWhiteSpace(command.CommandId))
45 continue;
46 list.Add(command);
47 }
48
49 return list;
50 }
51}
52
53public sealed class ForgeCapabilitiesCommand
54{
55 public string Domain { get; init; } = "";
56
57 public string Object { get; init; } = "";
58
59 public string Intent { get; init; } = "";
60
61 public string CommandId { get; init; } = "";
62
63 public string Path { get; init; } = "";
64
65 public IReadOnlyList<string> PathAliases { get; init; } = [];
66
67 public string? Help { get; init; }
68
69 public string? Category { get; init; }
70
71 public string ArgTail { get; init; } = "optional";
72
73 [JsonPropertyName("requiredCapabilities")]
74 public IReadOnlyList<string> RequiredCapabilities { get; init; } = [];
75}
76
View only · write via MCP/CIDE