| 1 | #nullable enable |
| 2 | |
| 3 | using CascadeIDE.Features.Workspace.DataAcquisition; |
| 4 | using CascadeIDE.Models.Intercom; |
| 5 | using CascadeIDE.Services; |
| 6 | using CascadeIDE.Services.Intercom; |
| 7 | |
| 8 | namespace CascadeIDE.ViewModels; |
| 9 | |
| 10 | /// <summary>Reveal вложения Intercom из чата: загрузка решения при необходимости, затем навигация в редактор (ADR 0128).</summary> |
| 11 | public partial class MainWindowViewModel |
| 12 | { |
| 13 | internal async Task<string> RevealIntercomAttachmentInIdeAsync( |
| 14 | AttachmentAnchor anchor, |
| 15 | bool select, |
| 16 | CancellationToken cancellationToken = default) |
| 17 | { |
| 18 | cancellationToken.ThrowIfCancellationRequested(); |
| 19 | |
| 20 | if (string.IsNullOrWhiteSpace(anchor.File)) |
| 21 | return "excerpt_only: нет file в anchor."; |
| 22 | |
| 23 | var workspaceRoot = GetWorkspacePath(); |
| 24 | if (_settings.Intercom.Attachments.Code.ShouldLoadSolutionBeforeReveal() |
| 25 | && AttachmentAnchorPaths.TryResolveAbsolute(anchor.File, workspaceRoot, out var absolute, out _) |
| 26 | && File.Exists(absolute)) |
| 27 | { |
| 28 | var sln = SolutionFileLocator.TryFindSolutionForSourceFile(absolute); |
| 29 | if (SolutionFileLocator.NeedsLoadSolutionBeforeBreakpoint(sln, Workspace.SolutionPath)) |
| 30 | { |
| 31 | cancellationToken.ThrowIfCancellationRequested(); |
| 32 | await LoadSolutionAsync(sln!).ConfigureAwait(false); |
| 33 | workspaceRoot = GetWorkspacePath(); |
| 34 | } |
| 35 | } |
| 36 | |
| 37 | cancellationToken.ThrowIfCancellationRequested(); |
| 38 | return await UiScheduler.Default.InvokeAsync(() => |
| 39 | IntercomAttachmentNavigator.Apply( |
| 40 | IdeMcp, |
| 41 | _settings.Intercom, |
| 42 | GetWorkspacePath(), |
| 43 | anchor, |
| 44 | selectExplicit: select, |
| 45 | shiftSelect: false, |
| 46 | durationMs: null, |
| 47 | solutionPath: ChatPanel.ResolveAttachSolutionPath())) |
| 48 | .ConfigureAwait(false); |
| 49 | } |
| 50 | } |
| 51 | |