Forge
csharpdeeb25a2
1using CascadeIDE.Features.Agent.Environment;
2
3namespace CascadeIDE.Features.Chat;
4
5public readonly record struct ChatSlashAgentResult(bool Success, string Message);
6
7public static class ChatSlashAgentActions
8{
9 public static bool TryExecute(
10 string slashPath,
11 string? argsTail,
12 IAgentEnvironmentService agentEnvironment,
13 Func<string?> getSolutionPath,
14 out ChatSlashAgentResult result)
15 {
16 result = default;
17 if (!IntentSlashCatalog.TryGetRoute(slashPath, out var route)
18 || route.ExecutionKind != ChatSlashCommandExecutionKind.LocalAgent)
19 {
20 return false;
21 }
22
23 var normalized = slashPath.Trim().ToLowerInvariant();
24 return normalized switch
25 {
26 "/agent verify" => RunVerify(argsTail, agentEnvironment, getSolutionPath, out result),
27 "/agent cancel" => RunCancel(agentEnvironment, out result),
28 "/agent status" => RunStatus(agentEnvironment, out result),
29 "/agent last" => RunLast(agentEnvironment, out result),
30 "/agent sandbox" => RunSandbox(argsTail, agentEnvironment, getSolutionPath, out result),
31 _ => Unknown(normalized, out result),
32 };
33 }
34
35 private static bool RunVerify(
36 string? argsTail,
37 IAgentEnvironmentService agentEnvironment,
38 Func<string?> getSolutionPath,
39 out ChatSlashAgentResult result)
40 {
41 var solution = getSolutionPath();
42 if (string.IsNullOrWhiteSpace(solution))
43 {
44 result = new(false, "Открой solution (.sln/.slnx) перед /agent verify.");
45 return true;
46 }
47
48 if (!AgentVerifyPolicyParser.TryParse(argsTail, out var policy))
49 {
50 result = new(false, "Политика: minimal | standard | strict | ci_parity (по умолчанию standard).");
51 return true;
52 }
53
54 var start = agentEnvironment.StartVerify(solution, policy);
55 if (!start.Accepted)
56 {
57 result = new(false, start.Error ?? "Verify не запущен.");
58 return true;
59 }
60
61 result = new(
62 true,
63 $"Verify запущен (run {start.RunId![..8]}…, snapshot {start.VerifySnapshotId}). Смотри /agent status и /agent last.");
64 return true;
65 }
66
67 private static bool RunCancel(IAgentEnvironmentService agentEnvironment, out ChatSlashAgentResult result)
68 {
69 var cancelled = agentEnvironment.CancelActive();
70 result = new(true, cancelled ? "Активный verify отменён." : "Нет активного verify.");
71 return true;
72 }
73
74 private static bool RunStatus(IAgentEnvironmentService agentEnvironment, out ChatSlashAgentResult result)
75 {
76 var status = agentEnvironment.GetStatus();
77 if (!status.IsActive)
78 {
79 result = new(true, "AEE: нет активного verify. Последний результат — /agent last.");
80 return true;
81 }
82
83 var tail = status.WritesInvalidatedVerifyEpoch ? " · правки во время verify — перезапусти verify." : "";
84 result = new(
85 true,
86 $"AEE: verify {status.RunId![..8]}… · policy {status.Policy} · snapshot {status.VerifySnapshotId}"
87 + (!string.IsNullOrEmpty(status.SandboxRunDirectory)
88 ? $" · sandbox {status.SandboxRunDirectory}"
89 : "")
90 + $"{tail}");
91 return true;
92 }
93
94 private static bool RunLast(IAgentEnvironmentService agentEnvironment, out ChatSlashAgentResult result)
95 {
96 var last = agentEnvironment.GetLastRun();
97 if (last is null)
98 {
99 result = new(true, "Пока нет завершённых verify runs в этой сессии.");
100 return true;
101 }
102
103 result = new(true, last.FormatChatTrace());
104 return true;
105 }
106
107 private static bool RunSandbox(
108 string? argsTail,
109 IAgentEnvironmentService agentEnvironment,
110 Func<string?> getWorkspaceRoot,
111 out ChatSlashAgentResult result)
112 {
113 if (!AgentSandboxProfileParser.TryParse(argsTail, out var profile))
114 {
115 result = new(false, "Профиль: agent_ephemeral | agent_worktree | in_place");
116 return true;
117 }
118
119 var prep = agentEnvironment.PrepareSandbox(profile, getWorkspaceRoot());
120 result = prep.Success
121 ? new(true, $"Sandbox {profile}: {prep.Path}\n{prep.Detail}")
122 : new(false, prep.Detail ?? "Sandbox prepare failed.");
123 return true;
124 }
125
126 private static bool Unknown(string path, out ChatSlashAgentResult result)
127 {
128 result = new(false, $"Неизвестная agent-команда: {path}. Доступно: /agent verify|cancel|status|last|sandbox");
129 return true;
130 }
131}
132
View only · write via MCP/CIDE