Forge
csharp3407750f
1using System.Text.Json;
2using AgentForge.Abstractions;
3
4namespace AgentForge.Mcp.Core;
5
6internal static class ForgeMcpArgParser
7{
8 public static CreateRepoPayload ParseCreateRepo(IReadOnlyDictionary<string, JsonElement> args) =>
9 new(
10 RequireString(args, "name"),
11 OptionalString(args, "description"),
12 OptionalString(args, "drive_mode") ?? OptionalString(args, "driveMode"),
13 OptionalString(args, "group"),
14 OptionalString(args, "org"),
15 OptionalString(args, "visibility"));
16
17 public static CreateOrgPayload ParseCreateOrg(IReadOnlyDictionary<string, JsonElement> args) =>
18 new(
19 RequireString(args, "slug"),
20 OptionalString(args, "display_name") ?? OptionalString(args, "displayName"),
21 OptionalString(args, "description"),
22 OptionalString(args, "default_visibility") ?? OptionalString(args, "defaultVisibility"));
23
24 public static AddOrgMemberPayload ParseAddOrgMember(IReadOnlyDictionary<string, JsonElement> args) =>
25 new(
26 RequireString(args, "provider"),
27 RequireString(args, "login"),
28 OptionalString(args, "role"));
29
30 public static AddInstanceAdminPayload ParseAddInstanceAdmin(IReadOnlyDictionary<string, JsonElement> args) =>
31 new(
32 RequireString(args, "provider"),
33 RequireString(args, "login"));
34
35 public static CreateRepoGroupPayload ParseCreateRepoGroup(IReadOnlyDictionary<string, JsonElement> args) =>
36 new(
37 RequireString(args, "slug"),
38 OptionalString(args, "display_name") ?? OptionalString(args, "displayName"),
39 OptionalString(args, "description"),
40 OptionalString(args, "default_visibility") ?? OptionalString(args, "defaultVisibility"),
41 OptionalString(args, "parent"));
42
43 public static CreateIssuePayload ParseCreateIssue(IReadOnlyDictionary<string, JsonElement> args) =>
44 new(
45 RequireString(args, "title"),
46 OptionalString(args, "body"),
47 AnchorArgs.ParseOptional(args, "anchors"),
48 AnchorArgs.ParseOptionalBrackets(args, "anchor_brackets") ?? AnchorArgs.ParseOptionalBrackets(args, "anchorBrackets"),
49 OptionalString(args, "author"));
50
51 public static UpdateIssuePayload ParseUpdateIssue(IReadOnlyDictionary<string, JsonElement> args) =>
52 new(OptionalString(args, "title"), OptionalString(args, "body"), OptionalString(args, "status"));
53
54 public static AddIssueCommentPayload ParseAddComment(IReadOnlyDictionary<string, JsonElement> args) =>
55 new(RequireString(args, "body"), OptionalString(args, "author"));
56
57 public static LinkIssueAnchorsPayload ParseLinkAnchors(IReadOnlyDictionary<string, JsonElement> args)
58 {
59 var anchors = AnchorArgs.ParseOptional(args, "anchors");
60 var brackets = AnchorArgs.ParseOptionalBrackets(args, "anchor_brackets")
61 ?? AnchorArgs.ParseOptionalBrackets(args, "anchorBrackets");
62 if ((anchors is null || anchors.Count == 0) && brackets is null)
63 throw new ArgumentException("anchors or anchor_brackets is required.");
64 return new LinkIssueAnchorsPayload(anchors, brackets);
65 }
66
67 public static CreateMergeRequestPayload ParseCreateMergeRequest(IReadOnlyDictionary<string, JsonElement> args) =>
68 new(
69 RequireString(args, "title"),
70 RequireString(args, "source_branch"),
71 OptionalString(args, "target_branch"),
72 AnchorArgs.ParseOptional(args, "anchors"),
73 OptionalString(args, "author"));
74
75 public static RecordCommitProvenancePayload ParseRecordProvenance(IReadOnlyDictionary<string, JsonElement> args) =>
76 new(
77 RequireString(args, "sha"),
78 new CommitProvenancePayload(
79 RequireString(args, "actor"),
80 RequireString(args, "branch"),
81 ParseOptionalIntList(args, "issue_numbers") ?? ParseOptionalIntList(args, "issueNumbers"),
82 OptionalInt(args, "mr_number") ?? OptionalInt(args, "mrNumber"),
83 OptionalString(args, "run_id") ?? OptionalString(args, "runId"),
84 AnchorArgs.ParseOptional(args, "anchors"),
85 OptionalString(args, "logical_line_id") ?? OptionalString(args, "logicalLineId")));
86
87 public static string RequireString(IReadOnlyDictionary<string, JsonElement> args, string key)
88 {
89 var value = OptionalString(args, key);
90 if (string.IsNullOrWhiteSpace(value))
91 throw new ArgumentException($"{key} is required.");
92 return value.Trim();
93 }
94
95 public static int RequireInt(IReadOnlyDictionary<string, JsonElement> args, string key)
96 {
97 if (!args.TryGetValue(key, out var value) || !value.TryGetInt32(out var number))
98 throw new ArgumentException($"{key} is required and must be an integer.");
99 return number;
100 }
101
102 public static string? OptionalString(IReadOnlyDictionary<string, JsonElement> args, string key) =>
103 args.TryGetValue(key, out var value) ? value.GetString() : null;
104
105 public static int? OptionalInt(IReadOnlyDictionary<string, JsonElement> args, string key)
106 {
107 if (!args.TryGetValue(key, out var value))
108 return null;
109 return value.ValueKind == JsonValueKind.Null ? null : value.GetInt32();
110 }
111
112 public static IReadOnlyList<int>? ParseOptionalIntList(IReadOnlyDictionary<string, JsonElement> args, string key)
113 {
114 if (!args.TryGetValue(key, out var value) || value.ValueKind != JsonValueKind.Array)
115 return null;
116
117 return value.EnumerateArray()
118 .Where(e => e.TryGetInt32(out _))
119 .Select(e => e.GetInt32())
120 .ToList();
121 }
122}
123
View only · write via MCP/CIDE