| 1 | using System.Text.Json; |
| 2 | |
| 3 | using CascadeIDE.Models.Editor; |
| 4 | |
| 5 | namespace CascadeIDE.Features.IdeMcp.Execution; |
| 6 | |
| 7 | /// <summary>MCP: открытие файла, загрузка решения, выделение в редакторе, выбор/редактирование сообщений чата.</summary> |
| 8 | internal sealed partial class IdeMcpCommandExecutor |
| 9 | { |
| 10 | private void RegisterEditorAndSolution(Action<string, Handler> add) |
| 11 | { |
| 12 | add(Services.IdeCommands.OpenFile, async (args, _) => |
| 13 | { |
| 14 | var a = _actions; |
| 15 | if (string.IsNullOrEmpty(McpCommandJsonArgs.String(args, "path"))) return "Missing path"; |
| 16 | a.OpenFile(McpCommandJsonArgs.String(args, "path")!); |
| 17 | return await Task.FromResult("OK"); |
| 18 | }); |
| 19 | add(Services.IdeCommands.LoadSolution, async (args, ct) => |
| 20 | { |
| 21 | var a = _actions; |
| 22 | if (string.IsNullOrEmpty(McpCommandJsonArgs.String(args, "path"))) |
| 23 | return "Missing path"; |
| 24 | return await a.LoadSolutionAndWaitAsync(McpCommandJsonArgs.String(args, "path")!, ct).ConfigureAwait(false); |
| 25 | }); |
| 26 | add(Services.IdeCommands.CreateProjectInSolution, async (args, ct) => |
| 27 | { |
| 28 | var template = McpCommandJsonArgs.String(args, "template"); |
| 29 | var projectName = McpCommandJsonArgs.String(args, "project_name"); |
| 30 | if (string.IsNullOrWhiteSpace(template)) |
| 31 | return "Missing template"; |
| 32 | if (string.IsNullOrWhiteSpace(projectName)) |
| 33 | return "Missing project_name"; |
| 34 | return await _vm.TryCreateProjectInSolutionAsync(template!, projectName!, ct).ConfigureAwait(false); |
| 35 | }); |
| 36 | add(Services.IdeCommands.Select, async (args, _) => |
| 37 | { |
| 38 | var a = _actions; |
| 39 | if (!EditorTextSpan.TryParse(args, out var span, out var err)) |
| 40 | return err; |
| 41 | a.SelectInEditor(span.File.Value, span.StartLine.Value, span.StartColumn.Value, span.EndLine.Value, span.EndColumn.Value); |
| 42 | return await Task.FromResult("OK"); |
| 43 | }); |
| 44 | add(Services.IdeCommands.ChatSelectMessage, async (args, _) => |
| 45 | { |
| 46 | var a = _actions; |
| 47 | var ordinal = Services.McpCommandJsonArgs.OptionalInt32(args, "ordinal"); |
| 48 | var endOrdinal = Services.McpCommandJsonArgs.OptionalInt32(args, "end_ordinal"); |
| 49 | var index = Services.McpCommandJsonArgs.OptionalInt32(args, "index"); |
| 50 | if (ordinal is not null && index is not null) |
| 51 | return "Specify either ordinal or index, not both."; |
| 52 | if (ordinal is { } start) |
| 53 | { |
| 54 | var end = endOrdinal ?? start; |
| 55 | return await a.SelectChatMessageByOrdinalAsync(start, end); |
| 56 | } |
| 57 | |
| 58 | if (index is { } globalIndex) |
| 59 | return await a.SelectChatMessageAsync(globalIndex); |
| 60 | |
| 61 | return "Missing ordinal (1-based in active detail branch) or index (0-based global ChatMessages)."; |
| 62 | }); |
| 63 | add(Services.IdeCommands.ChatGetSelectedMessage, async (_, _) => |
| 64 | { |
| 65 | var a = _actions; |
| 66 | return await a.GetSelectedChatMessageAsync(); |
| 67 | }); |
| 68 | add(Services.IdeCommands.ChatEditMessage, async (args, ct) => |
| 69 | { |
| 70 | var a = _actions; |
| 71 | if (string.IsNullOrWhiteSpace(McpCommandJsonArgs.String(args, "message_id"))) |
| 72 | return "Missing message_id"; |
| 73 | if (args is null || !args.TryGetValue("new_content", out _)) |
| 74 | return "Missing new_content"; |
| 75 | _ = ct; |
| 76 | return await a.EditChatAssistantMessageAsync( |
| 77 | McpCommandJsonArgs.String(args, "message_id")!, |
| 78 | McpCommandJsonArgs.String(args, "new_content") ?? "", |
| 79 | McpCommandJsonArgs.String(args, "reason")); |
| 80 | }); |
| 81 | } |
| 82 | } |
| 83 | |