Files
metona-ai-desktop/src/stores/ui-store.ts
T
thzxx ceb8ee644d feat: 升级至 v0.3.7 — 前后端状态同步与错误处理全量修复
核心引擎修复:
- CE-1: 上下文压缩摘要 role 从 system 改为 user,避免被 adapter 过滤
- CE-2: 工具失败时优先使用 error 字段(engine/openai-format/ollama 三处)
- P0-1: DeadLoopError 终止时正确传 error 参数,前端可见 ERROR 事件
- MT-1: 新增 waitForAbort 方法,abortSession 等待 run 结束再返回
- MT-2: TERMINATED 状态到达时标记步骤完成,避免 Trace Viewer 转圈
- MT-3: 压缩边界检测孤立 tool 消息,避免 API 400 错误
- isRetryableError 与 catch 分支统一 toLowerCase

IPC 与主进程修复:
- P0-2: createAdapter 配置缺失返回 null,FALLBACK_ADAPTER 兜底
- P0-3: reloadAdapter 失败返回 success:false 通知前端
- P1-5: 校验失败发 ERROR+DONE 流事件,防止 isStreaming 卡死
- P1-6: configLoaded 标志,配置加载前禁用发送按钮
- P1-7: MCP initialize 移到 agentLoop 后,完成后同步工具
- P2-11: beforeLoad 在 loadURL 前注册 IPC handler
- P2-12: provider 切换竞态保护

前端状态同步修复:
- clearSessions 后同步清空前端会话与消息状态
- clearMemories 通过 memoryVersion 触发 MemoryViewer 重新加载
- ContextMenu 4 个 session 操作补全 IPC 调用与 try/catch
- useConfig 配置保存失败回滚 UI 并提示
- handleToggle 工具切换失败回滚单个工具状态

错误处理全量补全:
- 所有 await window.metona 调用补全 try/catch 与 toast 反馈
- MCP addServer/toggleServer/removeServer 检查返回值
- showItemInFolder 检查返回值(handleOpen/handleOpenInFolder)
- sse-stream/ollama NDJSON 解析失败改为 log.warn
- adapter throwHttpError 带 status 属性供 isRetryableError 判断
2026-07-16 22:40:32 +08:00

115 lines
3.9 KiB
TypeScript

/**
* Zustand Store — UI 状态管理
*
* 主题、设置弹窗、引导向导等全局 UI 状态。
*
* v0.3.0 增强:
* - 添加详情面板标签控制(detailTab)— 支持斜杠命令切换标签
* - 添加侧边栏/详情面板可见性控制 — 支持快捷键切换
* - 添加专注模式 — 隐藏侧边栏和详情面板
*/
import { create } from 'zustand';
export type ThemeMode = 'dark' | 'light' | 'auto';
/** v0.3.0: 详情面板标签类型 */
export type DetailTab = 'trace' | 'memory' | 'tasks' | 'workspace';
interface UIState {
// 主题
theme: ThemeMode;
resolvedTheme: 'dark' | 'light';
// 弹窗
settingsOpen: boolean;
onboardingCompleted: boolean;
// v0.3.0: 面板可见性
sidebarVisible: boolean;
detailVisible: boolean;
focusMode: boolean;
// v0.3.0: 详情面板标签
detailTab: DetailTab;
// v0.3.0: 进入专注模式前的面板状态快照(用于恢复)
preFocusSidebarVisible: boolean;
preFocusDetailVisible: boolean;
// v0.3.6: 记忆数据版本号 — 清理记忆后自增,MemoryViewer 监听变化重新加载
// 避免 SettingsModal 清理记忆后 MemoryViewer 仍显示旧数据(需重启应用才刷新)
memoryVersion: number;
// Actions
setTheme: (theme: ThemeMode) => void;
setResolvedTheme: (theme: 'dark' | 'light') => void;
openSettings: () => void;
closeSettings: () => void;
setOnboardingCompleted: (completed: boolean) => void;
// v0.3.0: 面板控制 Actions
setDetailTab: (tab: DetailTab) => void;
toggleSidebar: () => void;
toggleDetail: () => void;
toggleFocusMode: () => void;
// v0.3.6: 记忆清理后触发前端刷新
bumpMemoryVersion: () => void;
}
export const useUIStore = create<UIState>((set) => ({
theme: 'auto',
resolvedTheme: 'dark',
settingsOpen: false,
onboardingCompleted: false,
// v0.3.0: 面板默认可见
sidebarVisible: true,
detailVisible: true,
focusMode: false,
detailTab: 'trace',
preFocusSidebarVisible: true,
preFocusDetailVisible: true,
// v0.3.6: 记忆数据版本号初始为 0
memoryVersion: 0,
setTheme: (theme) => set({ theme }),
setResolvedTheme: (resolvedTheme) => set({ resolvedTheme }),
openSettings: () => set({ settingsOpen: true }),
closeSettings: () => set({ settingsOpen: false }),
setOnboardingCompleted: (completed) => set({ onboardingCompleted: completed }),
// v0.3.0: 面板控制
setDetailTab: (tab) => set({ detailTab: tab }),
// 退出专注模式时恢复快照(若用户在专注模式下手动切换面板,视为退出专注模式)
// v0.3.0 修复: 退出专注模式时同时恢复另一个面板的快照,与 toggleFocusMode 关闭逻辑一致
toggleSidebar: () => set((s) => s.focusMode
? { sidebarVisible: !s.sidebarVisible, detailVisible: s.preFocusDetailVisible, focusMode: false }
: { sidebarVisible: !s.sidebarVisible }),
toggleDetail: () => set((s) => s.focusMode
? { detailVisible: !s.detailVisible, sidebarVisible: s.preFocusSidebarVisible, focusMode: false }
: { detailVisible: !s.detailVisible }),
// v0.3.0 修复:专注模式开启时保存当前面板状态快照,关闭时恢复快照
// 避免关闭时强制设为 true 覆盖用户进入专注模式前的原有状态
toggleFocusMode: () => set((s) => {
if (!s.focusMode) {
// 开启专注模式:保存快照,隐藏面板
return {
focusMode: true,
preFocusSidebarVisible: s.sidebarVisible,
preFocusDetailVisible: s.detailVisible,
sidebarVisible: false,
detailVisible: false,
};
}
// 关闭专注模式:恢复快照
return {
focusMode: false,
sidebarVisible: s.preFocusSidebarVisible,
detailVisible: s.preFocusDetailVisible,
};
}),
// v0.3.6: 清理记忆后自增版本号,触发 MemoryViewer 重新加载
bumpMemoryVersion: () => set((s) => ({ memoryVersion: s.memoryVersion + 1 })),
}));