Skip to content

Commit b742f66

Browse files
committed
重写本地环境修复编排
桌面桥接改为后台启动本地环境修复流程,并仅在发送 WebView 消息和桌面通知时回到 UI 线程。 将本地依赖修复拆分为编排服务、命令执行器和进度通道;管理员当前进程路径改用内存进度执行,不再轮询状态文件。 提权子进程状态文件新增启动状态、5 秒无进度失败和命令心跳进度,同时保留单条命令 20 分钟超时。 前端桥接在 localDependencyRepairStarted 时生成中文开始进度,保持既有请求、进度和结果协议。 新增并更新本地环境修复、桌面桥接和前端 bridge 测试,覆盖后台调度、管理员路径、命令启动异常、心跳、无进度失败和 started 进度。
1 parent 2c7c460 commit b742f66

8 files changed

Lines changed: 1576 additions & 966 deletions

File tree

resources/webui/upstream/source/src/desktop/bridge.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,20 @@ function handleLocalDependencyMessage(message: unknown): boolean {
729729
}
730730

731731
if (message.type === 'localDependencyRepairStarted') {
732+
const requestId = typeof message.requestId === 'string' ? message.requestId : '';
733+
const actionId = typeof message.actionId === 'string' ? message.actionId : '';
734+
if (!requestId || !actionId) return true;
735+
const pending = pendingLocalDependencyRequests.get(requestId);
736+
pending?.onProgress?.({
737+
actionId,
738+
phase: 'starting',
739+
message: '正在准备修复。',
740+
commandLine: null,
741+
recentOutput: [],
742+
logPath: null,
743+
updatedAt: new Date().toISOString(),
744+
exitCode: null,
745+
});
732746
return true;
733747
}
734748

resources/webui/upstream/source/tests/desktop/localDependencyBridge.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,12 @@ describe('local dependency desktop bridge', () => {
179179
await Promise.resolve();
180180
expect(settled).toBe(false);
181181
expect(progressEvents).toEqual([
182+
expect.objectContaining({
183+
actionId: 'repair-user-path',
184+
phase: 'starting',
185+
message: '正在准备修复。',
186+
recentOutput: [],
187+
}),
182188
expect.objectContaining({
183189
actionId: 'repair-user-path',
184190
phase: 'commandRunning',

src/CodexCliPlus.App/MainWindow.WebViewHost.cs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -610,8 +610,9 @@ await SaveCodexUserFileAsync(
610610
&& actionIdElement.ValueKind == JsonValueKind.String
611611
? actionIdElement.GetString()
612612
: null;
613-
_ = Dispatcher.InvokeAsync(async () =>
614-
await RunLocalDependencyRepairAsync(ReadRequestId(root), actionId)
613+
var repairRequestId = ReadRequestId(root);
614+
_ = Task.Run(() =>
615+
RunLocalDependencyRepairAsync(repairRequestId, actionId)
615616
);
616617
break;
617618

@@ -1099,7 +1100,7 @@ private async Task RunLocalDependencyRepairAsync(string? requestId, string? acti
10991100
"未知修复动作。",
11001101
"桌面端只接受内置白名单 action id。"
11011102
);
1102-
PostWebUiCommand(
1103+
await PostWebUiCommandOnDispatcherAsync(
11031104
new
11041105
{
11051106
type = "localDependencyRepairResult",
@@ -1114,7 +1115,7 @@ private async Task RunLocalDependencyRepairAsync(string? requestId, string? acti
11141115
LocalDependencySnapshot? snapshot = null;
11151116
try
11161117
{
1117-
PostWebUiCommand(
1118+
await PostWebUiCommandOnDispatcherAsync(
11181119
new
11191120
{
11201121
type = "localDependencyRepairStarted",
@@ -1126,7 +1127,7 @@ private async Task RunLocalDependencyRepairAsync(string? requestId, string? acti
11261127
result = await _localDependencyRepairService.RunElevatedRepairAsync(
11271128
actionId,
11281129
progress =>
1129-
Dispatcher.InvokeAsync(() =>
1130+
_ = Dispatcher.InvokeAsync(() =>
11301131
PostWebUiCommand(
11311132
new
11321133
{
@@ -1152,7 +1153,7 @@ private async Task RunLocalDependencyRepairAsync(string? requestId, string? acti
11521153
);
11531154
}
11541155

1155-
PostWebUiCommand(
1156+
await PostWebUiCommandOnDispatcherAsync(
11561157
new
11571158
{
11581159
type = "localDependencyRepairResult",
@@ -1166,7 +1167,7 @@ private async Task RunLocalDependencyRepairAsync(string? requestId, string? acti
11661167
{
11671168
_logger.LogError($"Local dependency repair '{actionId}' failed before result.", exception);
11681169
result = CreateLocalDependencyRepairFailure(actionId, "本地环境修复失败。", exception.Message);
1169-
PostWebUiCommand(
1170+
await PostWebUiCommandOnDispatcherAsync(
11701171
new
11711172
{
11721173
type = "localDependencyRepairResult",
@@ -1179,12 +1180,25 @@ private async Task RunLocalDependencyRepairAsync(string? requestId, string? acti
11791180
if (result.Succeeded)
11801181
{
11811182
_changeBroadcastService.Broadcast("local-environment");
1182-
_notificationService.ShowAuto(result.Summary);
1183+
await Dispatcher.InvokeAsync(() => _notificationService.ShowAuto(result.Summary));
11831184
}
11841185
else
11851186
{
1186-
_notificationService.ShowManual(result.Summary, result.Detail);
1187+
await Dispatcher.InvokeAsync(() =>
1188+
_notificationService.ShowManual(result.Summary, result.Detail)
1189+
);
1190+
}
1191+
}
1192+
1193+
private Task PostWebUiCommandOnDispatcherAsync(object message)
1194+
{
1195+
if (Dispatcher.CheckAccess())
1196+
{
1197+
PostWebUiCommand(message);
1198+
return Task.CompletedTask;
11871199
}
1200+
1201+
return Dispatcher.InvokeAsync(() => PostWebUiCommand(message)).Task;
11881202
}
11891203

11901204
private LocalDependencyRepairResult CreateLocalDependencyRepairFailure(

0 commit comments

Comments
 (0)