Forge
csharpdeeb25a2
1using System.Text.Json;
2using CascadeIDE.Contracts;
3using GitMcp.Core;
4
5namespace CascadeIDE.Features.IdeMcp.Application;
6
7/// <summary>
8/// Application-level helpers for IDE MCP git actions.
9/// Keeps common JSON/result shaping out of MainWindowViewModel.
10/// </summary>
11[ApplicationOrchestrator]
12public static class IdeMcpGitOrchestrator
13{
14 public static string WorkspaceUnavailableMessage() =>
15 "Workspace path is not available.";
16
17 public static string BuildInvalidGitBranchActionError() =>
18 BuildValidationError("git_branch: action must be list, create, or delete.");
19
20 public static string BuildInvalidGitSubmoduleActionError() =>
21 BuildValidationError("git_submodule: action must be status or update.");
22
23 public static string TruncateOutput(string? text, int maxChars)
24 {
25 if (string.IsNullOrEmpty(text))
26 return "";
27 return text.Length > maxChars ? text[..maxChars] + "\n... (output truncated)" : text;
28 }
29
30 public static string BuildValidationError(string error) =>
31 JsonSerializer.Serialize(new { success = false, error });
32
33 public static string BuildCommandResult(bool success, int exitCode, string output) =>
34 JsonSerializer.Serialize(new
35 {
36 success,
37 exit_code = exitCode,
38 output
39 });
40
41 public static string BuildStepFailure(string step, int exitCode, string output) =>
42 JsonSerializer.Serialize(new { success = false, step, exit_code = exitCode, output });
43
44 public static string BuildMissingCommitMessageError() =>
45 JsonSerializer.Serialize(new { success = false, error = "Commit message is required." });
46
47 public static string BuildPreflightReport(bool staged, GitPreflight.Report report) =>
48 JsonSerializer.Serialize(new
49 {
50 success = true,
51 staged,
52 changed_files = report.ChangedFiles,
53 untracked_files = report.UntrackedFiles,
54 semantic_files = report.SemanticFiles,
55 whitespace_only_files = report.WhitespaceOnlyFiles,
56 eol_only_files = report.EolOnlyFiles,
57 bom_only_files = report.BomOnlyFiles,
58 suggested_safe_fix_commands = report.SuggestedSafeFixCommands
59 });
60
61 public static string BuildCommitResult(bool success, int exitCode, string output) =>
62 JsonSerializer.Serialize(new
63 {
64 success,
65 exit_code = exitCode,
66 output
67 });
68
69 public static string BuildPreflightFixSafeResult(string postPreflightJson, IReadOnlyList<string> appliedCommands)
70 {
71 using var doc = JsonDocument.Parse(postPreflightJson);
72 if (!doc.RootElement.TryGetProperty("success", out var ok) || ok.ValueKind != JsonValueKind.True)
73 return postPreflightJson;
74
75 return JsonSerializer.Serialize(new
76 {
77 success = true,
78 applied = appliedCommands,
79 changed_files = doc.RootElement.GetProperty("changed_files"),
80 untracked_files = doc.RootElement.GetProperty("untracked_files"),
81 semantic_files = doc.RootElement.GetProperty("semantic_files"),
82 whitespace_only_files = doc.RootElement.GetProperty("whitespace_only_files"),
83 eol_only_files = doc.RootElement.GetProperty("eol_only_files"),
84 bom_only_files = doc.RootElement.GetProperty("bom_only_files"),
85 suggested_safe_fix_commands = doc.RootElement.GetProperty("suggested_safe_fix_commands")
86 });
87 }
88
89 public static string NormalizeAction(string? action, string defaultAction) =>
90 string.IsNullOrWhiteSpace(action) ? defaultAction : action.Trim().ToLowerInvariant();
91
92 /// <summary>Запуск MCP-git сессии или JSON-ошибки, если workspace недоступен.</summary>
93 public static Task<string> RunWithWorkspaceSession(
94 IGitCommandRunner runner,
95 string? workspacePath,
96 Func<IdeMcpGitWorkspaceSession, Task<string>> action)
97 {
98 if (!IdeMcpGitWorkspaceSession.TryCreate(runner, workspacePath, out var session, out var err))
99 return Task.FromResult(err);
100 return action(session);
101 }
102}
103
View only · write via MCP/CIDE