Forge
csharpdeeb25a2
1#nullable enable
2using CascadeIDE.Contracts;
3
4namespace CascadeIDE.Features.Launch.Application;
5
6/// <summary>
7/// Режим B <c>debug_launch</c> (MCP): явный <paramref name="targetPath"/> или resolve по профилю / решению.
8/// </summary>
9[ApplicationOrchestrator("debug-launch-mcp-profile")]
10public static class DebugLaunchByProfileMcpOrchestrator
11{
12 public static async Task<string> RunAsync(
13 string workspacePath,
14 string? targetPath,
15 string? profileName,
16 string? netcoredbgPath,
17 IReadOnlyList<string>? mcpProgramArgs,
18 IDotnetCommandRunner dotnetRunner,
19 IdeDapDebugSession dapDebug,
20 CancellationToken cancellationToken = default)
21 {
22 if (!string.IsNullOrWhiteSpace(targetPath))
23 {
24 return await dapDebug.LaunchAsync(
25 workspacePath,
26 targetPath!,
27 netcoredbgPath,
28 mcpProgramArgs,
29 environment: null,
30 workingDirectoryOverride: null,
31 cancellationToken)
32 .ConfigureAwait(false);
33 }
34
35 var sln = DebugWorkspacePath.TryResolveWorkspaceToSolutionPath(workspacePath);
36 if (string.IsNullOrEmpty(sln))
37 return "# Error: no_solution_in_workspace: укажи каталог с .sln или путь к .sln, либо target_path к .dll.";
38
39 var solutionDir = BreakpointsFileService.GetWorkspaceRoot(sln);
40 if (string.IsNullOrEmpty(solutionDir))
41 return "# Error: workspace_root_unresolved.";
42
43 var preResolve = LaunchPreResolvePipelineUnit.Default.Compose(
44 sln,
45 explicitProfileName: profileName,
46 solutionDirectory: solutionDir,
47 startupProjectFullPath: null);
48
49 var resolvedProfile = preResolve.Profile;
50 var readiness = preResolve.Readiness;
51
52 if (!readiness.CanAttemptResolve || readiness.Source != LaunchReadinessSource.Profile || resolvedProfile is not { } launchProfile)
53 {
54 return preResolve.McpResolveError
55 ?? LaunchMcpErrorFormatUnit.Default.FormatResolveFailure(
56 readiness,
57 explicitProfileName: profileName,
58 solutionDirectory: solutionDir);
59 }
60
61 var (target, err) = await MsBuildDebugTargetResolver
62 .TryResolveAsync(readiness.SelectedProjectFullPath!, dotnetRunner, launchProfile.Configuration, cancellationToken)
63 .ConfigureAwait(false);
64 if (string.IsNullOrEmpty(target))
65 return "# Error: " + (err ?? "msbuild_unresolved");
66
67 var prg = mcpProgramArgs is { Count: > 0 } ? mcpProgramArgs : launchProfile.ProgramArgs;
68 IReadOnlyDictionary<string, string>? env = DebugLaunchFromProfile.NonEmptyEnvironmentOrNull(launchProfile);
69 var launchResult = await dapDebug.LaunchAsync(
70 workspacePath,
71 target,
72 netcoredbgPath,
73 prg,
74 env,
75 launchProfile.WorkingDirectoryRelative,
76 cancellationToken)
77 .ConfigureAwait(false);
78 if (launchProfile.OpenLaunchBrowser)
79 KestrelLaunchBrowser.TryOpenAfterLaunch(
80 DebugLaunchFromProfile.NonEmptyEnvironmentOrNull(launchProfile),
81 launchProfile.LaunchUrl);
82 return launchResult;
83 }
84}
85
View only · write via MCP/CIDE