# Ami **Repository Path**: xcl52888/ami ## Basic Information - **Project Name**: Ami - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-11 - **Last Updated**: 2026-07-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # rust_ai_assistant 基于 **Tauri 2 + Vue 3** 的 Lightbox AI 助手,从同仓 Electron 版 `F:/core/lightbox_ai_assistant` 迁移而来。 > **迁移状态**:Electron 兼容层(`legacy/ipcMainApi` + `electronShim`)已在 2026-05-11 **全量移除**。项目中零 `window.electron` 引用,所有前端代码统一通过 `@/tauriApi` 调用 Rust 命令。详见 `ARCHITECTURE.md`。 ## 技术栈 | 层 | 选型 | |---|---| | 桌面容器 | Tauri 2.x(Rust 主进程 + WebView2) | | 前端 | Vue 3.5 · Vite 7 · TypeScript 5.8(strict) | | UI 套件 | Element Plus(`unplugin-auto-import` 自动导入) | | 路由 / 状态 | vue-router 4(hash) · Pinia 3 · pinia-plugin-persistedstate | | 样式 | Tailwind CSS v4 · SASS | | 国际化 | vue-i18n 11(cn / en) | | HTTP | axios(baseURL 来自 Rust 内置代理端口) | | 多媒体 | js-web-screen-shot · xlsx | | Rust 服务 | axum 0.7(代理)· tokio · reqwest 0.12 · notify(config watch) | ## 目录结构(精简版) ``` rust_ai_assistant/ ├── ARCHITECTURE.md # 详细架构、分层、约定、新增流程 ├── README.md # 本文档 ├── index.html # SPA 入口 ├── vite.config.ts ├── package.json ├── tsconfig.json # strict(noImplicitAny: false) │ ├── src/ # 前端(~12500 行, 81 文件) │ ├── main.ts # createApp → bootstrap → mount │ ├── bootstrap/ # 启动装配(i18n / store / router / telemetry / elementPlus) │ ├── router/ # hash 路由 + guards │ ├── tauriApi/ # ⭐ Rust 命令 / 事件的唯一入口 │ │ ├── index.ts # invokeCmd / listenEvent / AppError │ │ ├── keys.ts # Events + StoreKeys(镜像 Rust core/events.rs / keys.rs) │ │ ├── events.ts # 类型化事件订阅函数 │ │ └── modules/ # common / aiIcon / aiChat / settings / browserView / ... │ ├── types/ # Rust payload/response 的 TS 镜像 │ ├── shared/ # 跨 feature 复用:http(axios 封装)/ telemetry / eventBus │ ├── composables/ # useWindowDrag │ ├── components/layout/ # 跨 feature 纯 UI │ ├── features/ # ⭐ 核心业务积木(每个自治) │ │ ├── aiAssistant/ aiChat/ settings/ discussionGroup/ │ │ ├── moreFeatures/ rightClickMenu/ errorPages/ │ │ └── userManagement/ # 重业务(自带 api/ store/ utils/ 子路由) │ ├── features-deferred/ # Rust 端 stub:browserView / screenRecorder │ ├── locales/ styles/ assets/ │ └── env.d.ts │ └── src-tauri/ # Rust 后端(~2000 行, 36 文件) ├── Cargo.toml ├── tauri.conf.json # 多窗口、deep-link scheme、NSIS 配置 ├── capabilities/ # default.json + ai-icon.json(最小权限) ├── icons/ resources/ └── src/ ├── main.rs lib.rs # 入口极简 ├── app/ # 装配层 │ ├── builder.rs handler.rs setup.rs ├── core/ # 基础设施(不感知业务) │ ├── error.rs state.rs keys.rs events.rs ├── services/ # 长期服务 │ ├── config.rs proxy.rs intranet.rs │ ├── shortcuts.rs protocol.rs snap.rs ├── windows/ # WebviewWindow 工厂 │ └── mod.rs factory.rs ├── commands/ # 非 feature 命令 │ ├── common.rs ai_icon.rs ai_chat.rs │ ├── settings.rs aegis.rs └── features/ # 业务积木 ├── screen_recorder/{mod,commands,types}.rs ├── browser_view/{mod,commands,types}.rs └── user_management/{mod,commands,types}.rs ``` 分层规则:`core < services/windows < commands/features < app`,严格单向依赖。详见 `ARCHITECTURE.md` 第 3 节。 ## 运行 ```bash npm install # 每个新终端先把 cargo 加到 PATH(Git Bash 默认没加) export PATH="$HOME/.cargo/bin:$PATH" npm run tauri:dev # 开发(Vite HMR + Rust 热重载) npm run tauri:build # 打包(NSIS setup.exe + MSI) ``` `tauri dev` 会先启动 `vite` 在 `http://localhost:1420`,再拉起 Tauri 壳。debug build 下 aiIcon 窗口会自动打开 DevTools。 ## 打包产物 ``` src-tauri/target/release/ ├── rust_ai_assistant.exe ~19 MB 裸 exe └── bundle/ ├── nsis/Ai-Assistant_0.1.0_x64-setup.exe ~5 MB NSIS 安装器 └── msi/Ai-Assistant_0.1.0_x64_en-US.msi ~7 MB MSI 安装包 ``` > ⚠️ 打包前确认没有旧的 `rust_ai_assistant.exe` 进程在跑,否则 link 阶段会 `os error 5 拒绝访问`: > ```bash > taskkill //F //IM rust_ai_assistant.exe # Git Bash > ``` ## 代码调用约定 ### 调 Rust 命令 ```ts import { common, aiIcon, AppError } from '@/tauriApi' const port = await common.getProxyPort() await aiIcon.openLightbox() try { const info = await common.getUserInfo() } catch (e) { if (e instanceof AppError) console.error(e.code, e.message) } ``` ### 订阅 Rust 事件(必须清理) ```ts import { onMounted, onUnmounted } from 'vue' import { listenEvent, Events } from '@/tauriApi' let unlisten: (() => void) | null = null onMounted(async () => { unlisten = await listenEvent(Events.WINDOW_POSITION_UPDATED, (p) => { ... }) }) onUnmounted(() => unlisten?.()) ``` ### 新增命令 / 事件 见 `ARCHITECTURE.md` 第 11 节:新增 Rust 命令、前端 feature、Rust→前端事件的标准路径。 ## 与 Electron 原版的差异 ### 架构变化 - **主进程** Node.js → Rust - **代理服务器** Express → axum(绑定 127.0.0.1:0,端口通过 `get_proxy_port` 命令暴露) - **持久化** electron-store → tauri-plugin-store(键名兼容:`language / userInfo / shortcuts / recordingPath / isShowMain / appName / iconPosition`) - **日志** electron-log → tauri-plugin-log - **快捷键** globalShortcut → tauri-plugin-global-shortcut - **协议处理** protocol handler → tauri-plugin-deep-link + tauri-plugin-single-instance(scheme: `aiassistant://`) - **IPC** 自定义 EventRouter → 每个 IPC name 直接注册为 `#[tauri::command]`(snake_case) - **多窗口** BrowserWindow → WebviewWindow(aiIcon 静态,其余按需创建) ### 前端侧 原 Electron 风格的 `window.electron.ipcRenderer.invoke('renderer-to-main', { name, data })` 已**全部替换**为 `@/tauriApi` 类型化调用。对应: | 旧 | 新 | |---|---| | `window.electron.ipcRenderer.invoke('renderer-to-main', { name: 'foo-bar', data })` | `invokeCmd('foo_bar', { data })`(通常通过具体模块 `xxx.fooBar(data)` 调用) | | `window.electron.ipcRenderer.on(ch, cb)` | `await listenEvent(ch, cb)`(必配 `onUnmounted` 清理) | | `__API_BASE__` / `__whenApiBaseReady` | `shared/http` 内直接 `common.getProxyPort()` | | 错误:随手 catch 字符串 | `instanceof AppError`,拿 `code` + `message` | 拖拽:统一走 `composables/useWindowDrag.ts` —— 阈值内判断点击/拖拽,超过阈值调用 Tauri `getCurrentWindow().startDragging()`;mouseup 触发 `{name}-stop-drag` 命令让 Rust 发 `window-position-updated` 事件用于吸附。 ## 后置功能(当前为 stub,后续实现) 下列 Rust 命令当前返回良性默认值(不抛错),前端 UI 可渲染但功能不可用: | 功能 | 待办 | |---|---| | **屏幕录制** `screen_recorder_*` | 原 Electron 版 spawn `resources/ScreenCapture.exe`;Tauri 版可选 sidecar 或用 `scrap` / `windows-capture` crate | | **多 Tab BrowserView** `browser_view_*` / `browser_tab_*` | 多 WebviewWindow 或 iframe + `plugin-http` | | **用户管理实际业务** `*_user_management_view` / `download_user_template` | 前端完整、Rust 端需接入实际 API | | **Aegis 真实上报** `aegis_call` | 换 `aegis-web-sdk` 在 renderer 直报 | | **自动更新** | `tauri-plugin-updater` + 自托管签名服务 | ## 已知技术债 - 4 个 `tauri_plugin_shell::Shell::open` deprecation warning(Tauri 2.4+ 推荐 `tauri-plugin-opener`) - `tsconfig.json` 开了 `noImplicitAny: false`(过渡期保留灵活性) - `tauriApi/modules/*.ts` 里部分 `data?: unknown` 未收紧成具体 payload - 单元测试只有 1 个(`userManagement/utils/__tests__/tree.test.ts`) - 无 CI / lint / prettier / git hooks 配置 - CSP 为 `null`(生产前需收紧) - 6 个前端事件 Rust 端暂未 emit(`SHOW_MORE_FEATURES / HIDE_MORE_FEATURES / UPDATE_TABS / BROWSER_VIEW_IS_MAXIMIZED / USER_MANAGEMENT_IS_MAXIMIZED / VIDEO_SAVE_CALLBACK`),待对应 feature 实现激活 ## 开发注意 - Windows 首次启动会向 `%APPDATA%/Roaming/Blade/config.yml` 读 cookie;若不存在则 fallback 到 `~/Documents/Lightbox/Desktop/settings/desktop-config.ahconf` - bundle identifier 保持 `assistant.ai.lightbox`,与原 Electron 版对齐,方便双版本共存测试 - 协议 scheme:`aiassistant://aiassistant-show?appName=lightbox&posion=100and200`、`aiassistant-hide`、`aiassistant-exit` 等 - 反向唤起 Lightbox 主程序:通过 `tauri-plugin-shell` 打开 `lightbox://msgtype==showMainWindow&&show==true` - Windows 150% DPI 下,`tauri.conf.json` 声明的窗口尺寸会被错误解释;已在 `app/setup.rs` 里用 `set_size(LogicalSize)` 兜底 ## 更多 - 架构 / 分层 / 命令规范 / 新增流程:`ARCHITECTURE.md` - 专题文档(`docs/`): - [`agent-state-pet-animation.md`](docs/agent-state-pet-animation.md) — Agent hook 联动宠物动画 + 会话列表的整条链路(agent → hook.mjs → axum → Tauri emit → Vue),含扩展到新 agent 的步骤和调试路径 - Tauri 2 官方文档:https://v2.tauri.app/