feat: v0.8.2 安全纵深补全 · 协议保真 · 断链修复 — 图片SSRF/根MEMORY.md保护根治 · Anthropic thinking回传+pause_turn续传 · 2523 用例全量回归 + E2E 扩充
CI / 类型检查 + Lint + 单元测试 (push) Failing after 9m45s
CI / 全量测试 (Electron ABI) (push) Failing after 6m28s
CI / 产物编译验证 (push) Successful in 11m18s

This commit is contained in:
2026-09-08 14:30:27 +08:00
parent 69776e447f
commit 4cd6e997b5
86 changed files with 4303 additions and 956 deletions
+18 -3
View File
@@ -10,6 +10,8 @@ import type { IPCContext } from './context';
import type { AuditEventType } from '../services/audit.service';
import { UpdateService } from '../services/update.service';
import { assertSafeConfigTarget } from '../harness/tools/built-in/ssrf-guard';
// v0.8.2 P2-5: 用户可见文案出层(ui.locale 驱动)
import { mt } from '../utils/main-locale';
import log from 'electron-log';
export function registerAppHandlers(ctx: IPCContext): void {
@@ -36,17 +38,30 @@ export function registerAppHandlers(ctx: IPCContext): void {
});
// ===== v0.8.0 P2-3: 下载并安装更新(electron-updater;未启用时明确失败) =====
// v0.8.2 P1-3: 语义拆分 —— updateInstall 仅下载(完成后广播 downloaded
// 不再自动重启退出);重启安装由用户确认后经 app:updateInstallNow 触发
ipcMain.handle('app:updateInstall', async () => {
const { getAutoUpdaterHandle } = await import('../services/update.service');
const handle = getAutoUpdaterHandle();
if (!handle) {
return { success: false, error: '自动更新未启用(未配置更新源或开发模式)' };
return { success: false, error: mt('app.update.disabled') };
}
// fire-and-forget:进度经 update:status 广播,完成后 quitAndInstall
// fire-and-forget:进度经 update:status 广播,完成后等待用户确认安装
void handle.downloadAndInstall();
return { success: true };
});
// ===== v0.8.2 P1-3: 安装已下载的更新并重启(用户显式确认后调用) =====
ipcMain.handle('app:updateInstallNow', async () => {
const { getAutoUpdaterHandle } = await import('../services/update.service');
const handle = getAutoUpdaterHandle();
if (!handle) {
return { success: false, error: mt('app.update.disabled') };
}
handle.installNow();
return { success: true };
});
// ===== v0.7.3 P3-4: 健康快照(SLO 指标 + 最近健康检查报告)=====
ipcMain.handle('app:healthSnapshot', async () => {
try {
@@ -116,7 +131,7 @@ export function registerAppHandlers(ctx: IPCContext): void {
const result = await dialog.showOpenDialog(callerWin, {
properties: ['openDirectory', 'createDirectory'],
defaultPath: defaultPath ?? app.getPath('home'),
title: '选择工作空间目录',
title: mt('app.dialog.selectWorkspace.title'),
});
if (result.canceled || result.filePaths.length === 0) return { canceled: true, path: '' };
return { canceled: false, path: result.filePaths[0] };