Forge
csharpdeeb25a2
1using CascadeIDE.Features.Debug;
2using CascadeIDE.ViewModels;
3using CascadeIDE.Models;
4using CascadeIDE.Services;
5
6namespace CascadeIDE.Features.IdeMcp.Application;
7
8/// <summary>Панель отладки и снимок DAP (ADR 0002): один <see cref="DebugSessionSnapshot"/>.</summary>
9internal sealed partial class MainWindowIdeMcpHost
10{
11 /// <summary>Один раз на останов (breakpoint/step): показать док инструментов и Mfd «Отладка · стек» — в т.ч. при launch/attach в обход UI (например MCP <c>debug_launch</c>).</summary>
12 private bool _mfdDebugPagePrimedForCurrentStop;
13
14 internal void ApplyDapDebugSnapshotToUi()
15 {
16 var s = _host.DapDebug.GetSnapshot();
17 var plan = IdeMcpDebugOrchestrator.BuildDapSnapshotUiPlan(s, _mfdDebugPagePrimedForCurrentStop);
18 _mfdDebugPagePrimedForCurrentStop = plan.MfdPrimedForCurrentStopNext;
19
20 if (plan.ActivateInstrumentationDockAndDebugStack)
21 {
22 _host.IsInstrumentationDockVisible = true;
23 _host.TryNavigateToMfdShellPage(MfdShellPage.DebugStack);
24 }
25
26 _host.DebugPositionFile = plan.DebugPositionFile;
27 _host.DebugPositionLine = plan.DebugPositionLine;
28
29 if (plan.ShouldAttemptOpenStoppedSource
30 && plan.StoppedSourcePathForOpenAttempt is { } stoppedPath
31 && !string.IsNullOrEmpty(stoppedPath)
32 && File.Exists(stoppedPath))
33 {
34 var normalized = CanonicalFilePath.Normalize(stoppedPath);
35 if (!CanonicalFilePath.Equals(_host.CurrentFilePath, normalized))
36 {
37 _host.IsLoadingCurrentFile = true;
38 try
39 {
40 _host.Documents.OpenOrActivateDocument(normalized);
41 }
42 finally
43 {
44 _host.IsLoadingCurrentFile = false;
45 }
46 }
47 }
48
49 _host.InstrumentationPanel.DebugStackFrames.Clear();
50 var fi = 0;
51 foreach (var frame in s.StackFrames)
52 _host.InstrumentationPanel.DebugStackFrames.Add(new DebugStackFrameViewModel(fi++, frame.Name, frame.File, frame.Line));
53 _host.InstrumentationPanel.DebugVariableRoots.Clear();
54 ExpandDebugVariableChildrenAsync expand =
55 (vref, iv, nv, ct) => _host.DapDebug.ExpandVariableChildrenAsync(vref, iv, nv, ct);
56 foreach (var g in s.VariableRootScopes)
57 _host.InstrumentationPanel.DebugVariableRoots.Add(DebugVariableNodeViewModel.CreateScope(g.ScopeName, g.Roots, expand));
58 _host.McpSuppressDebugStackSelectedIndex = true;
59 try
60 {
61 var idx = plan.DebugStackSelectedIndex;
62 if (_host.DebugStackSelectedIndex != idx)
63 {
64 _host.McpDebugStackSelectedIndex = idx;
65 _host.McpNotifyPropertyChanged(nameof(MainWindowViewModel.DebugStackSelectedIndex));
66 }
67 }
68 finally
69 {
70 _host.McpSuppressDebugStackSelectedIndex = false;
71 }
72
73 _host.McpNotifyPropertyChanged(nameof(MainWindowViewModel.BreakpointLinesInCurrentFile));
74 _host.McpNotifyPropertyChanged(nameof(MainWindowViewModel.AllBreakpointLinesInCurrentFile));
75 _host.McpNotifyPropertyChanged(nameof(MainWindowViewModel.IdeHealthDebugText));
76 _host.McpNotifyPropertyChanged(nameof(MainWindowViewModel.IdeHealthDebugCockpitShort));
77 }
78
79 public Task<string> GetDebugSnapshotAsync(CancellationToken cancellationToken)
80 {
81 cancellationToken.ThrowIfCancellationRequested();
82 var s = _host.DapDebug.GetSnapshot();
83 cancellationToken.ThrowIfCancellationRequested();
84 return Task.FromResult(IdeMcpDebugOrchestrator.SerializeDebugSnapshot(s));
85 }
86}
87
View only · write via MCP/CIDE