Forge
csharp4405de34
1#nullable enable
2using System.Diagnostics;
3using System.Text;
4using CascadeIDE.Contracts;
5
6namespace CascadeIDE.Features.CursorAcp.DataAcquisition;
7
8/// <summary>
9/// DAL: stdio-процесс <c>cursor-agent acp</c> для <see cref="CascadeIDE.Services.CursorAcp.CursorAcpChatConnection"/> (UTF-8, перенаправленные потоки).
10/// </summary>
11[IoBoundary]
12public static class CursorAcpChatAgentProcess
13{
14 /// <summary>
15 /// Создаёт процесс, подписывается на stderr (построчно), вызывает <see cref="Process.Start"/>, затем <see cref="Process.BeginErrorReadLine"/>.
16 /// </summary>
17 /// <param name="cmdPath">Полный путь к <c>cursor-agent.cmd</c> или аналогу.</param>
18 /// <param name="agentWorkingDirectory">Рабочий каталог агента; если пусто — каталог <paramref name="cmdPath"/>.</param>
19 /// <param name="onStderrLine">Не-null строки из stderr (как в <c>ErrorDataReceived</c>).</param>
20 /// <exception cref="InvalidOperationException">Не удалось запустить процесс.</exception>
21 public static Process Start(string cmdPath, string agentWorkingDirectory, Action<string>? onStderrLine)
22 {
23 var workDir = string.IsNullOrEmpty(agentWorkingDirectory)
24 ? Path.GetDirectoryName(cmdPath) ?? ""
25 : agentWorkingDirectory;
26
27 var psi = new ProcessStartInfo
28 {
29 FileName = cmdPath,
30 Arguments = "acp",
31 WorkingDirectory = workDir,
32 UseShellExecute = false,
33 CreateNoWindow = true,
34 RedirectStandardInput = true,
35 RedirectStandardOutput = true,
36 RedirectStandardError = true,
37 // Иначе на Windows OEM — JSON/UTF-8 от агента искажается.
38 StandardInputEncoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false),
39 StandardOutputEncoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false),
40 StandardErrorEncoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false),
41 };
42
43 var p = new Process { StartInfo = psi };
44 if (onStderrLine is not null)
45 {
46 p.ErrorDataReceived += (_, e) =>
47 {
48 if (!string.IsNullOrEmpty(e.Data))
49 onStderrLine(e.Data);
50 };
51 }
52
53 if (!p.Start())
54 throw new InvalidOperationException("Не удалось запустить cursor-agent (ACP).");
55
56 p.BeginErrorReadLine();
57 return p;
58 }
59}
60
View only · write via MCP/CIDE