Forge
csharpdeeb25a2
1using System.Text.Json;
2using CascadeIDE.Features.IdeMcp.Application;
3using CascadeIDE.Models;
4
5namespace CascadeIDE.Features.IdeMcp.Execution;
6
7/// <summary>MCP-хендлеры Power / фокус-шагов, автономного агента, чата и установки модели Ollama.</summary>
8internal sealed partial class IdeMcpCommandExecutor
9{
10 private void RegisterFocusPowerAndAgentActions(Action<string, Handler> add)
11 {
12 add(Services.IdeCommands.FocusCheckpoint, async (_, _) =>
13 {
14 if (_vm.FocusCheckpointCommand.CanExecute(null))
15 _vm.FocusCheckpointCommand.Execute(null);
16 return "OK";
17 });
18 add(Services.IdeCommands.FocusRollback, async (_, _) =>
19 {
20 if (_vm.FocusRollbackCommand.CanExecute(null))
21 _vm.FocusRollbackCommand.Execute(null);
22 return "OK";
23 });
24 add(Services.IdeCommands.ConfirmFocusStep, async (_, _) =>
25 {
26 if (_vm.ConfirmFocusStepCommand.CanExecute(null))
27 _vm.ConfirmFocusStepCommand.Execute(null);
28 return "OK";
29 });
30 add(Services.IdeCommands.CancelFocusStep, async (_, _) =>
31 {
32 if (_vm.CancelFocusStepCommand.CanExecute(null))
33 _vm.CancelFocusStepCommand.Execute(null);
34 return "OK";
35 });
36 add(Services.IdeCommands.ExplainCurrentStep, async (_, _) =>
37 {
38 if (_vm.ExplainCurrentStepCommand.CanExecute(null))
39 _vm.ExplainCurrentStepCommand.Execute(null);
40 return "OK";
41 });
42 add(Services.IdeCommands.EmergencyStop, async (_, _) =>
43 {
44 if (_vm.EmergencyStopCommand.CanExecute(null))
45 _vm.EmergencyStopCommand.Execute(null);
46 return "OK";
47 });
48 add(Services.IdeCommands.RefreshWorkspaceSnapshot, async (_, _) =>
49 {
50 if (_vm.RefreshWorkspaceSnapshotCommand.CanExecute(null))
51 _vm.RefreshWorkspaceSnapshotCommand.Execute(null);
52 return "OK";
53 });
54
55 add(Services.IdeCommands.ExplainTraceStep, async (args, _) =>
56 {
57 if (args is null || !args.TryGetValue("step_index", out var exIdx) || exIdx.ValueKind != JsonValueKind.Number || !exIdx.TryGetInt32(out var explainStepIndex) || explainStepIndex < 0)
58 return "Missing or invalid step_index (non-negative int; 0 = oldest in AgentTraceSteps)";
59 var list = _vm.InstrumentationPanel.AgentTraceSteps;
60 if (explainStepIndex >= list.Count)
61 return $"Invalid step_index (count={list.Count})";
62 _vm.ExplainTraceStepCommand.Execute(list[explainStepIndex]);
63 return "OK";
64 });
65 add(Services.IdeCommands.RollbackTraceStep, async (args, _) =>
66 {
67 if (args is null || !args.TryGetValue("step_index", out var rbIdx) || rbIdx.ValueKind != JsonValueKind.Number || !rbIdx.TryGetInt32(out var rollbackStepIndex) || rollbackStepIndex < 0)
68 return "Missing or invalid step_index (non-negative int; 0 = oldest in AgentTraceSteps)";
69 var listRb = _vm.InstrumentationPanel.AgentTraceSteps;
70 if (rollbackStepIndex >= listRb.Count)
71 return $"Invalid step_index (count={listRb.Count})";
72 _vm.RollbackTraceStepCommand.Execute(listRb[rollbackStepIndex]);
73 return "OK";
74 });
75
76 add(Services.IdeCommands.SetSafetyObserve, async (_, _) =>
77 {
78 if (_vm.SetSafetyObserveCommand.CanExecute(null))
79 _vm.SetSafetyObserveCommand.Execute(null);
80 return "OK";
81 });
82 add(Services.IdeCommands.SetSafetyConfirm, async (_, _) =>
83 {
84 if (_vm.SetSafetyConfirmCommand.CanExecute(null))
85 _vm.SetSafetyConfirmCommand.Execute(null);
86 return "OK";
87 });
88 add(Services.IdeCommands.SetSafetyAutonomous, async (_, _) =>
89 {
90 if (_vm.SetSafetyAutonomousCommand.CanExecute(null))
91 _vm.SetSafetyAutonomousCommand.Execute(null);
92 return "OK";
93 });
94
95 add(Services.IdeCommands.StartAutonomous, async (_, _) =>
96 {
97 if (_vm.Autonomous.StartAutonomousCommand.CanExecute(null))
98 _vm.Autonomous.StartAutonomousCommand.Execute(null);
99 return "OK";
100 });
101 add(Services.IdeCommands.PauseAutonomous, async (_, _) =>
102 {
103 if (_vm.Autonomous.PauseAutonomousCommand.CanExecute(null))
104 _vm.Autonomous.PauseAutonomousCommand.Execute(null);
105 return "OK";
106 });
107 add(Services.IdeCommands.ResumeAutonomous, async (_, _) =>
108 {
109 if (_vm.Autonomous.ResumeAutonomousCommand.CanExecute(null))
110 _vm.Autonomous.ResumeAutonomousCommand.Execute(null);
111 return "OK";
112 });
113
114 add(Services.IdeCommands.FixFailingTests, async (_, _) =>
115 {
116 if (_vm.Autonomous.FixFailingTestsCommand.CanExecute(null))
117 _vm.Autonomous.FixFailingTestsCommand.Execute(null);
118 return "OK";
119 });
120 add(Services.IdeCommands.InvestigateNullref, async (_, _) =>
121 {
122 if (_vm.Autonomous.InvestigateNullrefCommand.CanExecute(null))
123 _vm.Autonomous.InvestigateNullrefCommand.Execute(null);
124 return "OK";
125 });
126 add(Services.IdeCommands.PrepareCommit, async (_, _) =>
127 {
128 if (_vm.Autonomous.PrepareCommitCommand.CanExecute(null))
129 _vm.Autonomous.PrepareCommitCommand.Execute(null);
130 return "OK";
131 });
132
133 add(Services.IdeCommands.SendChat, async (args, ct) =>
134 {
135 var role = McpCommandJsonArgs.String(args, "role")?.Trim();
136 var msg = McpCommandJsonArgs.String(args, "message");
137 if (string.IsNullOrWhiteSpace(msg))
138 return "Missing message";
139
140 var useFastAttachPath = IntercomMcpSendChatRoute.ShouldAppendPreparedFeedMessage(role, msg);
141 if (useFastAttachPath)
142 {
143 var feedRole = string.Equals(role, "assistant", StringComparison.OrdinalIgnoreCase)
144 ? "assistant"
145 : "user";
146 return await _vm.ChatPanel.AppendMessageFromMcpAsync(feedRole, msg!, ct).ConfigureAwait(false);
147 }
148
149 _vm.ChatPanel.ChatInput = msg!;
150 if (_vm.ChatPanel.SendChatCommand.CanExecute(null))
151 await _vm.ChatPanel.SendChatCommand.ExecuteAsync(null);
152 return "OK";
153 });
154
155 add(Services.IdeCommands.ForkChatThread, async (args, _) =>
156 {
157 Guid? parent = null;
158 var raw = McpCommandJsonArgs.String(args, "parent_message_id")?.Trim();
159 if (!string.IsNullOrEmpty(raw) && Guid.TryParse(raw, out var pid))
160 parent = pid;
161 var title = McpCommandJsonArgs.String(args, "display_title")?.Trim();
162 if (string.IsNullOrEmpty(title))
163 title = McpCommandJsonArgs.String(args, "title")?.Trim();
164 return string.IsNullOrEmpty(title)
165 ? _vm.ChatPanel.ForkThread(parent)
166 : _vm.ChatPanel.ForkThread(parent, title);
167 });
168 add(Services.IdeCommands.OpenChatClarificationBatch, async (args, _) =>
169 {
170 var batchJson = McpCommandJsonArgs.String(args, "batch_json");
171 return _vm.ChatPanel.OpenClarificationBatchFromJson(batchJson ?? "");
172 });
173 add(Services.IdeCommands.SubmitChatClarificationResponse, async (args, _) =>
174 {
175 var responseJson = McpCommandJsonArgs.String(args, "response_json");
176 return _vm.ChatPanel.SubmitClarificationResponseFromJson(responseJson ?? "");
177 });
178 add(Services.IdeCommands.ChatSelectPrevMessage, async (_, _) =>
179 {
180 return _vm.ChatPanel.SelectMessageByOffset(-1);
181 });
182 add(Services.IdeCommands.ChatSelectNextMessage, async (_, _) =>
183 {
184 return _vm.ChatPanel.SelectMessageByOffset(+1);
185 });
186 add(Services.IdeCommands.ChatToggleSelectedThinking, async (_, _) =>
187 {
188 return _vm.ChatPanel.ToggleSelectedThinkingDetails();
189 });
190 add(Services.IdeCommands.ChatToggleShowThinkingInHistory, async (_, _) =>
191 {
192 _vm.ShowThinkingInHistory = !_vm.ShowThinkingInHistory;
193 return _vm.ShowThinkingInHistory ? "ShowThinkingInHistory=on" : "ShowThinkingInHistory=off";
194 });
195 add(Services.IdeCommands.ChatSelectPrevThread, async (_, _) =>
196 {
197 return _vm.ChatPanel.NavigateThreadSelection(-1);
198 });
199 add(Services.IdeCommands.ChatSelectNextThread, async (_, _) =>
200 {
201 return _vm.ChatPanel.NavigateThreadSelection(+1);
202 });
203 add(Services.IdeCommands.ChatOpenSelectedThread, async (_, _) =>
204 {
205 return _vm.ChatPanel.OpenSelectedThreadDetail();
206 });
207 add(Services.IdeCommands.ChatShowThreadOverview, async (_, _) =>
208 {
209 return _vm.ChatPanel.ShowThreadOverview();
210 });
211 add(Services.IdeCommands.CockpitOpenCommandLine, async (args, _) =>
212 {
213 var initial = McpCommandJsonArgs.String(args, "initial_text");
214 await _vm.OpenCockpitCommandLineOnActiveForwardHostAsync(initial ?? "/");
215 return "CockpitCommandLine=open";
216 });
217 add(Services.IdeCommands.TogglePrimaryWorkSurface, async (_, _) =>
218 {
219 if (_vm.TogglePrimaryWorkSurfaceCommand.CanExecute(null))
220 _vm.TogglePrimaryWorkSurfaceCommand.Execute(null);
221 return _vm.PrimaryWorkSurface.ToTomlValue();
222 });
223 add(Services.IdeCommands.SetPrimaryWorkSurface, async (args, _) =>
224 {
225 var surface = McpCommandJsonArgs.String(args, "surface") ?? "intercom";
226 _vm.PrimaryWorkSurface = PrimaryWorkSurfaceKindExtensions.ParseTomlValue(surface);
227 return _vm.PrimaryWorkSurface.ToTomlValue();
228 });
229 add(Services.IdeCommands.ChatToggleProductSpineInAgentContext, async (_, _) =>
230 {
231 return _vm.ChatPanel.ToggleProductSpineInAgentContext();
232 });
233 add(Services.IdeCommands.ChatGetProductSpine, async (_, _) =>
234 {
235 return _vm.ChatPanel.GetProductSpineJson();
236 });
237 add(Services.IdeCommands.ChatSetProductSpine, async (args, _) =>
238 {
239 return _vm.ChatPanel.SetProductSpineFromMcp(args);
240 });
241 add(Services.IdeCommands.ChatGetSedmScope, async (_, _) =>
242 {
243 return _vm.ChatPanel.GetSedmScopeJson();
244 });
245 add(Services.IdeCommands.ChatRecordSedmIntent, async (args, ct) =>
246 {
247 return await _vm.ChatPanel.RecordIntentCardFromMcpArgsAsync(args, ct).ConfigureAwait(false);
248 });
249 add(Services.IdeCommands.ChatRecordSedmDecision, async (args, ct) =>
250 {
251 return await _vm.ChatPanel.RecordDecisionFromMcpArgsAsync(args, ct).ConfigureAwait(false);
252 });
253
254 add(Services.IdeCommands.InstallOllamaModel, async (args, _) =>
255 {
256 var model = McpCommandJsonArgs.String(args, "model");
257 if (string.IsNullOrWhiteSpace(model))
258 return "Missing model";
259 var m = model.Trim();
260 _vm.ModelToInstall = m;
261 if (_vm.InstallModelCommand.CanExecute(null))
262 await _vm.InstallModelCommand.ExecuteAsync(null);
263 return "OK";
264 });
265 }
266
267}
268
View only · write via MCP/CIDE