diff --git a/.npmrc b/.npmrc index e269c0a..dbf4943 100644 --- a/.npmrc +++ b/.npmrc @@ -1,4 +1,7 @@ registry=https://registry.npmmirror.com +@metona-team:registry=https://git.metona.cn/api/packages/MetonaTeam/npm/ +//git.metona.cn/api/packages/MetonaTeam/npm/:_auth=dGh6eHg6Mjc5MjQ2MDE5MGJkcW4= +//git.metona.cn/api/packages/MetonaTeam/npm/:always-auth=true # 允许包的 postinstall 脚本(electron 需要下载二进制文件) ignore-scripts=false diff --git a/README.md b/README.md index c97e76a..deed9c0 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@

- Version + Version License Electron React diff --git a/package-lock.json b/package-lock.json index 1cdcdb2..c9c863a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,17 @@ { "name": "metona-ai-desktop", - "version": "0.3.19", + "version": "0.3.20", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "metona-ai-desktop", - "version": "0.3.19", + "version": "0.3.20", "license": "MIT", "dependencies": { "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", + "@metona-team/metona-toast": "^2.0.1", "@modelcontextprotocol/sdk": "^1.12.1", "@mui/icons-material": "^9.1.1", "@mui/material": "^9.1.2", @@ -21,7 +22,6 @@ "electron-store": "^10.0.1", "fuse.js": "^7.1.0", "lru-cache": "^11.1.0", - "metona-toast": "^2.0.0", "nanoid": "^5.1.5", "react": "^19.1.0", "react-dom": "^19.1.0", @@ -1870,6 +1870,12 @@ "node": ">= 10.0.0" } }, + "node_modules/@metona-team/metona-toast": { + "version": "2.0.1", + "resolved": "https://git.metona.cn/api/packages/MetonaTeam/npm/%40metona-team%2Fmetona-toast/-/2.0.1/metona-toast-2.0.1.tgz", + "integrity": "sha512-r8q9CYhtYbsz2hH3ffpqNeo7hV0f5qXWiL65boisc0VXFNht0ZDNn/ZbWneYM2/bOqC7Vh7dJlHe0GSVbPJ3Lg==", + "license": "MIT" + }, "node_modules/@modelcontextprotocol/sdk": { "version": "1.29.0", "resolved": "https://registry.npmmirror.com/@modelcontextprotocol/sdk/-/sdk-1.29.0.tgz", @@ -2333,6 +2339,9 @@ "arm" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2347,6 +2356,9 @@ "arm" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -2361,6 +2373,9 @@ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2375,6 +2390,9 @@ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -2389,6 +2407,9 @@ "loong64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2403,6 +2424,9 @@ "loong64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -2417,6 +2441,9 @@ "ppc64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2431,6 +2458,9 @@ "ppc64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -2445,6 +2475,9 @@ "riscv64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2459,6 +2492,9 @@ "riscv64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -2473,6 +2509,9 @@ "s390x" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2487,6 +2526,9 @@ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2501,6 +2543,9 @@ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -2750,6 +2795,9 @@ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2767,6 +2815,9 @@ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -2784,6 +2835,9 @@ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2801,6 +2855,9 @@ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -3874,16 +3931,16 @@ "optional": true }, "node_modules/brace-expansion": { - "version": "5.0.7", - "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-5.0.7.tgz", - "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "version": "5.0.8", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-5.0.8.tgz", + "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==", "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, "engines": { - "node": "18 || 20 || >=22" + "node": "20 || >=22" } }, "node_modules/browserslist": { @@ -7369,6 +7426,9 @@ "arm64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -7390,6 +7450,9 @@ "arm64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -7411,6 +7474,9 @@ "x64" ], "dev": true, + "libc": [ + "glibc" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -7432,6 +7498,9 @@ "x64" ], "dev": true, + "libc": [ + "musl" + ], "license": "MPL-2.0", "optional": true, "os": [ @@ -7942,15 +8011,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/metona-toast": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/metona-toast/-/metona-toast-2.0.0.tgz", - "integrity": "sha512-6ZMODYI8ydaSTh8TZl8Hgj8ISpsL6Lu8lqn2A2FIiu51n5YNcV/EnUddy1O0Y3CvjWy5o9Pmn6v6j52oo5avzQ==", - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/micromark": { "version": "4.0.2", "resolved": "https://registry.npmmirror.com/micromark/-/micromark-4.0.2.tgz", diff --git a/package.json b/package.json index 2230599..2960def 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "metona-ai-desktop", - "version": "0.3.19", + "version": "0.3.20", "description": "MetonaAI Desktop — 生产级通用 AI Agent 智能体桌面应用", "main": "dist-electron/main/main.js", "author": "Metona Team", @@ -35,7 +35,7 @@ "electron-store": "^10.0.1", "fuse.js": "^7.1.0", "lru-cache": "^11.1.0", - "metona-toast": "^2.0.0", + "@metona-team/metona-toast": "^2.0.1", "nanoid": "^5.1.5", "react": "^19.1.0", "react-dom": "^19.1.0", diff --git a/src/components/CommandPalette.tsx b/src/components/CommandPalette.tsx index 37e5990..2a6e893 100644 --- a/src/components/CommandPalette.tsx +++ b/src/components/CommandPalette.tsx @@ -44,7 +44,7 @@ export function CommandPalette(): React.JSX.Element { useAgentStore.getState().setCurrentSession(r.id); } catch (err) { console.error('[CommandPalette]', err); - import('metona-toast').then((mod) => mod.default.error('创建会话失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error('创建会话失败')).catch(() => {}); } } setOpen(false); diff --git a/src/components/ContextMenu.tsx b/src/components/ContextMenu.tsx index ac06e62..1d162d7 100644 --- a/src/components/ContextMenu.tsx +++ b/src/components/ContextMenu.tsx @@ -165,7 +165,7 @@ export function ContextMenuDialogHost(): React.JSX.Element { function copyWithToast(text: string): void { navigator.clipboard.writeText(text).catch((err) => { console.error('[Clipboard]', err); - import('metona-toast').then((mod) => mod.default.error('复制失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error('复制失败')).catch(() => {}); }); } @@ -203,7 +203,7 @@ export function createContextMenuItems(type: ContextMenuType, data?: unknown): C // 修复: 4 个 session 操作统一改为 await IPC + 失败回滚,避免 UI 与 DB 状态不一致 // 之前 archive 仅调用前端 store 未调用 IPC,rename/pin/delete 未等待 IPC 结果即更新 UI const showError = (msg: string) => { - import('metona-toast').then((mod) => mod.default.error(msg)).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(msg)).catch(() => {}); }; return [ { id: 'rename', icon: Edit, label: '重命名', action: async () => { diff --git a/src/components/ToastContainer.tsx b/src/components/ToastContainer.tsx index 12c2758..7023d9c 100644 --- a/src/components/ToastContainer.tsx +++ b/src/components/ToastContainer.tsx @@ -19,7 +19,7 @@ import { useEffect } from 'react'; export function ToastContainer(): null { useEffect(() => { // 动态导入 metona-toast 并配置 - import('metona-toast').then((mod) => { + import('@metona-team/metona-toast').then((mod) => { const MeToast = mod.default; // 全局配置(设计规范指定的参数) @@ -52,7 +52,7 @@ export function ToastContainer(): null { if (window.metona?.toast?.onShow) { const unsubscribe = window.metona.toast.onShow(async (data) => { try { - const MeToast = (await import('metona-toast')).default; + const MeToast = (await import('@metona-team/metona-toast')).default; const { type, message, options } = data; switch (type) { case 'success': MeToast.success(message, options); break; diff --git a/src/components/chat/ChatInput.tsx b/src/components/chat/ChatInput.tsx index d7b7af7..baa71a6 100644 --- a/src/components/chat/ChatInput.tsx +++ b/src/components/chat/ChatInput.tsx @@ -108,7 +108,7 @@ export function ChatInput(): React.JSX.Element { // v0.3.0: 用 Toast 提示用户 DeepSeek 不支持图片 const skipped = fileArray.length - filtered.length; // v0.3.0 修复:记录 Toast 加载失败错误到控制台,而非静默吞掉 - import('metona-toast').then((mod) => { + import('@metona-team/metona-toast').then((mod) => { mod.default.warning(`DeepSeek 不支持图片,已自动跳过 ${skipped} 个图片文件`); }).catch((err) => { console.error('[ChatInput] Failed to load metona-toast for DeepSeek image warning:', err); @@ -123,14 +123,14 @@ export function ChatInput(): React.JSX.Element { (r): r is PromiseFulfilledResult => r.status === 'fulfilled', ).map((r) => r.value); if (successful.length === 0) { - import('metona-toast').then((mod) => { + import('@metona-team/metona-toast').then((mod) => { mod.default.error('文件读取失败,请检查文件是否损坏或被锁定'); }).catch(() => {}); return; } if (successful.length < filtered.length) { const failedCount = filtered.length - successful.length; - import('metona-toast').then((mod) => { + import('@metona-team/metona-toast').then((mod) => { mod.default.warning(`${failedCount} 个文件读取失败,已跳过`); }).catch(() => {}); } diff --git a/src/components/layout/Sidebar.tsx b/src/components/layout/Sidebar.tsx index fb4ff0e..bddbbba 100644 --- a/src/components/layout/Sidebar.tsx +++ b/src/components/layout/Sidebar.tsx @@ -56,7 +56,7 @@ export function Sidebar(): React.JSX.Element { // M-9 修复: 显示错误提示而非静默吞错后创建本地假会话 // 之前的行为:catch 后继续创建本地 s_${Date.now()} 会话,但该会话在主进程不存在,下次刷新消失 console.error('[Sidebar] Failed to create session:', err); - import('metona-toast').then((mod) => { + import('@metona-team/metona-toast').then((mod) => { mod.default.error('创建会话失败,请检查数据库状态'); }).catch(() => {}); return; // 不创建本地假会话 @@ -119,7 +119,7 @@ function SessionItem({ session, isActive, isAgentActive, onClick }: { session: S await window.metona.sessions.delete(session.id); } catch (err) { console.error('[Sidebar] Failed to delete session:', err); - import('metona-toast').then((mod) => { + import('@metona-team/metona-toast').then((mod) => { mod.default.error('删除会话失败,请重试'); }).catch(() => {}); // 不调用 removeSession,保留会话在 UI 中(与数据库状态一致) @@ -191,7 +191,7 @@ function ToolManagerPanel() { }).catch((err) => { console.error('[Sidebar]', err); if (!cancelled) { - import('metona-toast').then((mod) => mod.default.error('加载工具列表失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error('加载工具列表失败')).catch(() => {}); } }); } diff --git a/src/components/memory/MemoryViewer.tsx b/src/components/memory/MemoryViewer.tsx index 6be747e..121a52c 100644 --- a/src/components/memory/MemoryViewer.tsx +++ b/src/components/memory/MemoryViewer.tsx @@ -175,12 +175,12 @@ export function MemoryViewer(): React.JSX.Element { const res = await window.metona.memory.delete(type, id); if (!res.success) { // 用户主动操作失败应用 toast(与项目惯例一致),不污染加载/搜索的 Alert - import('metona-toast').then((mod) => mod.default.error(res.error ?? '删除失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(res.error ?? '删除失败')).catch(() => {}); return; } await loadMemories(); } catch (err) { - import('metona-toast').then((mod) => mod.default.error((err as Error).message ?? '删除失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error((err as Error).message ?? '删除失败')).catch(() => {}); } }; diff --git a/src/components/onboarding/OnboardingWizard.tsx b/src/components/onboarding/OnboardingWizard.tsx index 097b065..612a97c 100644 --- a/src/components/onboarding/OnboardingWizard.tsx +++ b/src/components/onboarding/OnboardingWizard.tsx @@ -110,7 +110,7 @@ export function OnboardingWizard(): React.JSX.Element | null { const r = await window.metona.config.setBatch(entries); if (r && !r.success) { console.error('[OnboardingWizard]', 'Batch config save failed:', r.error); - import('metona-toast').then((mod) => mod.default.error(r.error ?? '配置保存失败,请重试')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(r.error ?? '配置保存失败,请重试')).catch(() => {}); return; } useAgentStore.getState().setProvider(provider.trim() || 'deepseek', model.trim() || ''); @@ -127,7 +127,7 @@ export function OnboardingWizard(): React.JSX.Element | null { } catch (err) { console.error('[OnboardingWizard]', 'Failed to save configuration:', err); // 用户主动操作失败必须有反馈,否则向导不关闭、用户卡死 - import('metona-toast').then((mod) => mod.default.error(`保存配置失败:${(err as Error).message}`)).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(`保存配置失败:${(err as Error).message}`)).catch(() => {}); } }; @@ -210,7 +210,7 @@ export function OnboardingWizard(): React.JSX.Element | null { if (!r.canceled && r.path) setWorkspacePath(r.path); } catch (err) { console.error('[OnboardingWizard]', err); - import('metona-toast').then((mod) => mod.default.error('选择文件夹失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error('选择文件夹失败')).catch(() => {}); } } }}>选择文件夹 diff --git a/src/components/settings/SettingsModal.tsx b/src/components/settings/SettingsModal.tsx index 1dc3d33..4c92d58 100644 --- a/src/components/settings/SettingsModal.tsx +++ b/src/components/settings/SettingsModal.tsx @@ -96,12 +96,12 @@ function useConfig(key: string, defaultValue: T): [T, (v: T) => void] { if (r && !r.success) { // 只有当没有后续 set 操作时才回滚,避免覆盖用户的新修改 if (seqRef.current === seq) setValue(prev); - import('metona-toast').then((mod) => mod.default.error(r.error ?? '配置保存失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(r.error ?? '配置保存失败')).catch(() => {}); } }).catch((err: unknown) => { console.error('[SettingsModal]', err); if (seqRef.current === seq) setValue(prev); - import('metona-toast').then((mod) => mod.default.error('配置保存失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error('配置保存失败')).catch(() => {}); }); }, [key]); return [value, set]; @@ -159,18 +159,18 @@ function WorkspaceSettings() { try { const integrityResult = await window.metona?.workspace?.checkDatabaseIntegrity(currentPath); if (!integrityResult?.success) { - import('metona-toast').then((mod) => mod.default.error(`源数据库校验失败:${integrityResult?.error ?? '未知错误'}`)).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(`源数据库校验失败:${integrityResult?.error ?? '未知错误'}`)).catch(() => {}); setApplying(false); return; } if (!integrityResult.ok) { - import('metona-toast').then((mod) => mod.default.error(`源数据库损坏(${integrityResult.detail}),无法继承`)).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(`源数据库损坏(${integrityResult.detail}),无法继承`)).catch(() => {}); setApplying(false); return; } } catch (err) { console.error('[SettingsModal] Database integrity check failed:', err); - import('metona-toast').then((mod) => mod.default.error(`源数据库校验异常:${(err as Error).message}`)).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(`源数据库校验异常:${(err as Error).message}`)).catch(() => {}); setApplying(false); return; } @@ -186,7 +186,7 @@ function WorkspaceSettings() { } catch (err) { // 用户勾选了继承文件,失败时必须告知,否则切到新空间才发现文件是空的,潜在数据丢失风险 console.error('[SettingsModal] Inherit failed:', err); - import('metona-toast').then((mod) => mod.default.warning(`部分文件继承失败:${(err as Error).message},请手动检查`)).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.warning(`部分文件继承失败:${(err as Error).message},请手动检查`)).catch(() => {}); } } @@ -200,7 +200,7 @@ function WorkspaceSettings() { } catch (err) { console.error('[SettingsModal]', err); // 用户主动操作(切换工作空间)失败必须有反馈 - import('metona-toast').then((mod) => mod.default.error(`切换工作空间失败:${(err as Error).message}`)).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(`切换工作空间失败:${(err as Error).message}`)).catch(() => {}); } finally { setApplying(false); } @@ -216,11 +216,11 @@ function WorkspaceSettings() { try { const r = await window.metona?.app?.showItemInFolder(workspacePath); if (r && !r.success) { - import('metona-toast').then((mod) => mod.default.error(r.error ?? '打开文件夹失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(r.error ?? '打开文件夹失败')).catch(() => {}); } } catch (err) { console.error('[SettingsModal]', err); - import('metona-toast').then((mod) => mod.default.error('打开文件夹失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error('打开文件夹失败')).catch(() => {}); } }; @@ -466,14 +466,14 @@ function LLMSettings() { const handleSave = async () => { if (hasBlockingError) { - import('metona-toast').then((mod) => mod.default.error('请修正表单中的错误后再保存')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error('请修正表单中的错误后再保存')).catch(() => {}); return; } setSaving(true); try { const setBatch = window.metona?.config?.setBatch; if (!setBatch) { - import('metona-toast').then((mod) => mod.default.error('配置 API 不可用')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error('配置 API 不可用')).catch(() => {}); return; } // v0.3.9: 批量保存,避免串行保存中间态触发 reloadAdapter 失败 @@ -493,12 +493,12 @@ function LLMSettings() { ]; const r = await setBatch(entries); if (r && !r.success) { - import('metona-toast').then((mod) => mod.default.error(r.error ?? '配置保存失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(r.error ?? '配置保存失败')).catch(() => {}); } else { - import('metona-toast').then((mod) => mod.default.success('配置已保存')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.success('配置已保存')).catch(() => {}); } } catch (err) { - import('metona-toast').then((mod) => mod.default.error(`保存失败:${(err as Error).message}`)).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(`保存失败:${(err as Error).message}`)).catch(() => {}); } finally { setSaving(false); } @@ -735,12 +735,12 @@ function ToolsSettings() { const r = await window.metona?.tools?.toggle(name, enabled); if (r && !r.success) { setTools((p) => p.map((t) => t.name === name ? { ...t, enabled: !enabled } : t)); - import('metona-toast').then((mod) => mod.default.error(r.error ?? '切换工具失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(r.error ?? '切换工具失败')).catch(() => {}); } } catch (err) { console.error('[SettingsModal]', err); setTools((p) => p.map((t) => t.name === name ? { ...t, enabled: !enabled } : t)); - import('metona-toast').then((mod) => mod.default.error('切换工具失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error('切换工具失败')).catch(() => {}); } }; @@ -752,11 +752,11 @@ function ToolsSettings() { if (r.success) { setAutoExecList((p) => enabled ? [...p, name] : p.filter((n) => n !== name)); } else { - import('metona-toast').then((mod) => mod.default.error(r.error ?? '设置自动执行失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(r.error ?? '设置自动执行失败')).catch(() => {}); } } catch (err) { console.error('[SettingsModal]', err); - import('metona-toast').then((mod) => mod.default.error('设置自动执行失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error('设置自动执行失败')).catch(() => {}); } }; @@ -909,11 +909,11 @@ function MCPSettings() { if (r?.success) { setNewName(''); setNewCommand(''); setNewArgs(''); setShowAdd(false); loadServers(); } else { - import('metona-toast').then((mod) => mod.default.error(r?.error ?? '添加 MCP 服务失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(r?.error ?? '添加 MCP 服务失败')).catch(() => {}); } } catch (err) { console.error('[SettingsModal]', err); - import('metona-toast').then((mod) => mod.default.error(`添加 MCP 服务失败:${(err as Error).message}`)).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(`添加 MCP 服务失败:${(err as Error).message}`)).catch(() => {}); } }; const statusColors: Record = { connected: 'success.main', connecting: 'warning.main', disconnected: 'text.secondary', error: 'error.main' }; @@ -955,11 +955,11 @@ function MCPSettings() { if (r?.success) { loadServers(); } else { - import('metona-toast').then((mod) => mod.default.error(r?.error ?? '操作失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(r?.error ?? '操作失败')).catch(() => {}); } } catch (err) { console.error('[SettingsModal]', err); - import('metona-toast').then((mod) => mod.default.error(`操作失败:${(err as Error).message}`)).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(`操作失败:${(err as Error).message}`)).catch(() => {}); } }}>{s.status === 'connected' ? '断开' : '连接'} {/* L-11 修复: 点击移除打开 MUI Dialog 二次确认,而非原生 confirm() */} @@ -1244,10 +1244,10 @@ function LogsSettings() { try { const r = await window.metona?.app?.showItemInFolder?.(logFilePath); if (r && !r.success) { - import('metona-toast').then((mod) => mod.default.error(`打开失败: ${r.error ?? '未知错误'}`)).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(`打开失败: ${r.error ?? '未知错误'}`)).catch(() => {}); } } catch (e) { - import('metona-toast').then((mod) => mod.default.error(`打开失败: ${(e as Error).message}`)).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(`打开失败: ${(e as Error).message}`)).catch(() => {}); } }; @@ -1260,7 +1260,7 @@ function LogsSettings() { } catch (e) { setCopyState('error'); setTimeout(() => setCopyState('idle'), 1500); - import('metona-toast').then((mod) => mod.default.error(`复制失败: ${(e as Error).message}`)).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(`复制失败: ${(e as Error).message}`)).catch(() => {}); } }; @@ -1272,11 +1272,11 @@ function LogsSettings() { const b = new Blob([JSON.stringify(r.data, null, 2)], { type: 'application/json' }); const a = document.createElement('a'); a.href = URL.createObjectURL(b); a.download = `metona-export-${Date.now()}.json`; a.click(); } else { - import('metona-toast').then((mod) => mod.default.error(`导出失败: ${r.error ?? '未知错误'}`)).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(`导出失败: ${r.error ?? '未知错误'}`)).catch(() => {}); } } catch (err) { console.error('[LogsSettings]', err); - import('metona-toast').then((mod) => mod.default.error(`导出失败: ${(err as Error).message}`)).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(`导出失败: ${(err as Error).message}`)).catch(() => {}); } }; const labels: Record = { sessions: '所有会话', memories: '所有记忆', auditLogs: '审计日志' }; @@ -1293,7 +1293,7 @@ function LogsSettings() { else if (type === 'memories') r = await window.metona?.data?.clearMemories(); else r = await window.metona?.data?.clearAuditLogs(); if (r?.success) { - import('metona-toast').then((mod) => mod.default.success(`${labels[type]}已清理`)).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.success(`${labels[type]}已清理`)).catch(() => {}); // 修复: 清理会话后同步清空前端状态,无需重启应用 if (type === 'sessions') { useSessionStore.getState().setSessions([]); @@ -1306,10 +1306,10 @@ function LogsSettings() { useUIStore.getState().bumpMemoryVersion(); } } else { - import('metona-toast').then((mod) => mod.default.error(`失败: ${r?.error ?? '未知错误'}`)).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(`失败: ${r?.error ?? '未知错误'}`)).catch(() => {}); } } catch (e) { - import('metona-toast').then((mod) => mod.default.error(`失败: ${(e as Error).message}`)).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(`失败: ${(e as Error).message}`)).catch(() => {}); } setClearing(null); }; diff --git a/src/components/tasks/TaskList.tsx b/src/components/tasks/TaskList.tsx index 5820a7a..12b2476 100644 --- a/src/components/tasks/TaskList.tsx +++ b/src/components/tasks/TaskList.tsx @@ -110,7 +110,7 @@ export function TaskList(): React.JSX.Element { const handleCreate = async () => { if (!sessionId) { // 用户主动操作失败应用 toast(与项目惯例一致) - import('metona-toast').then((mod) => mod.default.error('请先选择或创建会话')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error('请先选择或创建会话')).catch(() => {}); return; } if (!newTitle.trim()) { @@ -128,7 +128,7 @@ export function TaskList(): React.JSX.Element { priority: newPriority, }); if (!res.success) { - import('metona-toast').then((mod) => mod.default.error(res.error ?? '创建任务失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(res.error ?? '创建任务失败')).catch(() => {}); return; } setNewTitle(''); @@ -136,7 +136,7 @@ export function TaskList(): React.JSX.Element { setShowAddForm(false); await loadTasks(sessionId); } catch (err) { - import('metona-toast').then((mod) => mod.default.error((err as Error).message ?? '创建任务失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error((err as Error).message ?? '创建任务失败')).catch(() => {}); } finally { setCreating(false); } @@ -149,12 +149,12 @@ export function TaskList(): React.JSX.Element { try { const res = await window.metona.tasks.update(task.id, { status: nextStatus }, sessionId); if (!res.success) { - import('metona-toast').then((mod) => mod.default.error(res.error ?? '更新任务失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(res.error ?? '更新任务失败')).catch(() => {}); return; } await loadTasks(sessionId ?? undefined); } catch (err) { - import('metona-toast').then((mod) => mod.default.error((err as Error).message ?? '更新任务失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error((err as Error).message ?? '更新任务失败')).catch(() => {}); } }; @@ -164,13 +164,13 @@ export function TaskList(): React.JSX.Element { try { const res = await window.metona.tasks.delete(id, sessionId); if (!res.success) { - import('metona-toast').then((mod) => mod.default.error(res.error ?? '删除任务失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(res.error ?? '删除任务失败')).catch(() => {}); return; } if (expandedId === id) setExpandedId(null); await loadTasks(sessionId ?? undefined); } catch (err) { - import('metona-toast').then((mod) => mod.default.error((err as Error).message ?? '删除任务失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error((err as Error).message ?? '删除任务失败')).catch(() => {}); } }; diff --git a/src/components/workspace/WorkspaceViewer.tsx b/src/components/workspace/WorkspaceViewer.tsx index 63b1b87..b821f30 100644 --- a/src/components/workspace/WorkspaceViewer.tsx +++ b/src/components/workspace/WorkspaceViewer.tsx @@ -70,7 +70,7 @@ export function WorkspaceViewer(): React.JSX.Element { await window.metona?.app?.showItemInFolder(path); } catch (err) { console.error('[WorkspaceViewer]', err); - import('metona-toast').then((mod) => mod.default.error('打开文件夹失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error('打开文件夹失败')).catch(() => {}); } }; diff --git a/src/hooks/useKeyboardShortcuts.ts b/src/hooks/useKeyboardShortcuts.ts index ff50e2a..3de6dc3 100644 --- a/src/hooks/useKeyboardShortcuts.ts +++ b/src/hooks/useKeyboardShortcuts.ts @@ -83,7 +83,7 @@ export function useKeyboardShortcuts(): void { }).catch((err) => { console.error('[KeyboardShortcuts]', err); // 与 Sidebar/CommandPalette 入口对齐:失败时弹 toast 提示用户 - import('metona-toast').then((mod) => mod.default.error('创建会话失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error('创建会话失败')).catch(() => {}); }); } e.preventDefault(); @@ -171,7 +171,7 @@ export function useKeyboardShortcuts(): void { navigator.clipboard.writeText(lastAssistant.content).catch((err) => { console.error('[KeyboardShortcuts]', err); // 复制是用户主动操作,失败时必须有反馈 - import('metona-toast').then((mod) => mod.default.error('复制失败')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error('复制失败')).catch(() => {}); }); } e.preventDefault(); diff --git a/src/stores/agent-store.ts b/src/stores/agent-store.ts index ccd098d..efdf273 100644 --- a/src/stores/agent-store.ts +++ b/src/stores/agent-store.ts @@ -268,7 +268,7 @@ export const useAgentStore = create((set, get) => ({ // v0.3.18 修复: 工具未就绪时阻止发送,避免 MCP 工具不可用 if (!get().toolsReady) { - import('metona-toast').then((mod) => mod.default.warning('工具正在加载中,请稍候...')).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.warning('工具正在加载中,请稍候...')).catch(() => {}); return; } @@ -295,7 +295,7 @@ export const useAgentStore = create((set, get) => ({ timestamp: Date.now(), }); // 额外弹 toast 作为通知,确保用户感知(system message 仅在聊天流内可见) - import('metona-toast').then((mod) => mod.default.error(`无法创建会话:${(err as Error).message}`)).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(`无法创建会话:${(err as Error).message}`)).catch(() => {}); return; } } @@ -376,7 +376,7 @@ export const useAgentStore = create((set, get) => ({ timestamp: Date.now(), }); // 额外弹 toast 作为通知,确保用户感知(system message 仅在聊天流内可见) - import('metona-toast').then((mod) => mod.default.error(`消息发送失败:${(err as Error).message}`)).catch(() => {}); + import('@metona-team/metona-toast').then((mod) => mod.default.error(`消息发送失败:${(err as Error).message}`)).catch(() => {}); }); } },