f7a720204a
- 移除 GovAI, nomifun-tauri, 算力盒子 的 submodule 引用 - 添加所有子项目的完整源代码 - 保留原始 .git 为 .git.bak 备份
147 lines
9.5 KiB
Markdown
147 lines
9.5 KiB
Markdown
# 以桌面应用方式运行 NomiFun
|
||
|
||
桌面应用 (`nomifun-desktop`) 是一个 [Tauri](https://tauri.app/) 外壳,**在同一进程内**链接 Rust 后端 (`nomifun-app`)。这里没有派生的后端二进制,没有 Electron,也没有捆绑的 `nomicore`。外壳在一个空闲的 `127.0.0.1` 端口上将后端启动为异步任务,然后将打包好的 SPA (`ui/dist`) 加载进 WebView,并使其指向 `http://127.0.0.1:<port>/api`。
|
||
|
||
桌面 WebView 不显示登录页。嵌入式后端使用 `AuthPolicy::TrustLocalToken`:
|
||
外壳把每次启动生成的本地信任 secret 注入自己的 WebView,只有携带该 secret
|
||
的请求会被视为桌面用户。如果你想要登录 + 远程浏览器/手机访问,请参阅
|
||
[WebUI 远程访问](./webui-remote-access.zh.md)(应用内功能),或
|
||
[自托管 Web 服务器](./web-server-deployment.zh.md)(独立服务器)。
|
||
|
||

|
||
|
||
## 快速开始
|
||
|
||
### 前置条件
|
||
|
||
桌面应用需要:
|
||
|
||
- Tauri 支持的平台 (Windows 10+、macOS 11+、主流 Linux 发行版)。
|
||
- WebView 运行时:Windows 上的 **WebView2** (Win 11 预装;Win 10 上请安装 [Evergreen Bootstrapper](https://developer.microsoft.com/microsoft-edge/webview2/)),macOS 上的 **WKWebView** (内置),Linux 上的 **WebKitGTK** (`libwebkit2gtk-4.1-0`)。
|
||
- 用于开发:Rust 工具链、[Bun](https://bun.sh) ≥ 1.3.13,以及对应平台的 Tauri 构建依赖 (参见 [Tauri 前置条件](https://v2.tauri.app/start/prerequisites/))。
|
||
|
||
### 从源码运行 (开发模式)
|
||
|
||
在仓库根目录:
|
||
|
||
```bash
|
||
bun install
|
||
bun run dev
|
||
```
|
||
|
||
这会执行 `tauri dev --config apps/desktop/tauri.conf.json`。它启动 Vite 开发服务器 (`http://localhost:5173`) 来托管 SPA,构建并启动 `nomifun-desktop`,并在每次启动时在一个全新的空闲 localhost 端口上启动嵌入的后端。
|
||
|
||
### 构建发布包
|
||
|
||
```bash
|
||
bun run build
|
||
```
|
||
|
||
输出包按平台落到 `target/release/bundle/` 下 (Windows 上是 NSIS 安装器 + MSI,macOS 上是 `.app` + `.dmg`,Linux 上是 `.deb` + `.AppImage`)。要生成签名的更新器构件 (额外的 `.sig` 文件),请在配置好签名密钥后使用 `bun run build:updater` (参见下方[更新器状态](#更新器状态))。
|
||
|
||
构建成功后会打印包的位置,例如在 macOS 上:
|
||
|
||
```text
|
||
$ bun run build
|
||
Compiling nomifun-app v0.1.0
|
||
Finished `release` profile [optimized] target(s)
|
||
Bundling NomiFun.app (macos)
|
||
Bundling NomiFun_0.1.0_aarch64.dmg (macos)
|
||
Finished 2 bundles at:
|
||
target/release/bundle/macos/NomiFun.app
|
||
target/release/bundle/dmg/NomiFun_0.1.0_aarch64.dmg
|
||
```
|
||
|
||
## 窗口与标题栏
|
||
|
||
主窗口在 Windows 和 Linux 上是**无边框**的:React 标题栏组件在与应用内导航同一行绘制最小化/最大化/关闭按钮。在 macOS 上,原生的红绿灯按钮通过 Tauri 的 `Overlay` 标题栏样式得以保留,内容延伸至栏底之下。
|
||
|
||
- 默认尺寸:`1280 × 832`,最小 `880 × 600`。
|
||
- 各处都可调整大小 (即使没有 OS 绘制的装饰,Windows 上的边缘调整和 Snap 仍然可用)。
|
||
- 标题栏:`NomiFun`。
|
||
|
||
> 窗口边框因系统而异:Windows / Linux 上是带应用内控件的无边框标题栏,macOS
|
||
> 上保留原生红绿灯按钮(内容延伸至 `Overlay` 栏下)。
|
||
|
||
## 单实例
|
||
|
||
`tauri-plugin-single-instance` 在 Windows 和 Linux 上强制应用只运行一个副本。试图启动第二个 `nomifun-desktop` 不会在另一个端口上启动新的后端,而是会静默地聚焦到已有的窗口。
|
||
|
||
## 深度链接
|
||
|
||
应用注册了 `nomifun://` URL 协议 (在 `apps/desktop/tauri.conf.json` 的 `plugins.deep-link.desktop.schemes` 下配置)。当操作系统通过 `nomifun://...` URL 启动 Nomi 时,外壳会通过 Tauri 事件 `deep-link://received` 将 URL 转发给渲染进程。渲染进程可以使用 `@tauri-apps/api/event` 中的 `listen('deep-link://received', ...)` 订阅以处理负载。
|
||
|
||
启动时会调用 `register_all()` 来安装该协议;在需要带外注册步骤的平台上 (某些 Linux 桌面、开发环境),该调用是尽力而为的,失败会被忽略。
|
||
|
||
## 自启动
|
||
|
||
外壳附带 `tauri-plugin-autostart`,使得渲染进程可以通过插件的 invoke API 让应用加入 "登录时启动"。在 macOS 上这使用 `LaunchAgent`;在 Windows 上使用注册表的 `Run` 键;在 Linux 上则使用 autostart 文件夹中的 `.desktop` 文件。面向用户的开关位于应用设置中。
|
||
|
||
## 通知
|
||
|
||
`tauri-plugin-notification` 已启用。渲染进程可以显示 OS 级别的通知 (例如,当 agent 完成一个长任务或 AutoWork 有结果时)。在 macOS 上,第一次会请求用户授权;在 Windows 上,通知使用现代的操作中心;在 Linux 上则通过 `libnotify`。
|
||
|
||
## 数据存储位置
|
||
|
||
桌面应用将 SQLite 数据库、agent 状态、日志和 Bun 运行时缓存持久化到按用户的应用数据目录下 —— Windows 上是 **`%LOCALAPPDATA%\NomiFun\Nomi`**,macOS 上是 **`~/Library/Application Support/NomiFun/Nomi`**,Linux 上是 **`$XDG_DATA_HOME/NomiFun/Nomi`** (由共享的 `nomifun_app::cli::default_data_dir()` 解析)。这与 `nomifun-web` 宿主和开发脚本使用的是同一个默认目录,因此在一个宿主里配置的 provider 或伙伴在其他宿主里同样可见。
|
||
|
||
在启动应用前设置 `NOMIFUN_DATA_DIR=<absolute path>`,数据目录就会变为 `$NOMIFUN_DATA_DIR/Nomi`。后端启动时会对数据目录取排他的 `server.lock`;若启动失败 (例如该目录已被另一个实例占用),桌面外壳会弹出原生错误对话框并退出。
|
||
|
||
> 旧版本默认使用 `<system temp>/nomifun-data/Nomi`。在那里发现的安装会在启动时自动迁移到按用户位置 (一次性):数据被复制,数据库中存储的绝对路径会被改写,旧目录保留作为备份。可再生的缓存 (解压出的 Bun 运行时、日志、浏览器配置 …) 不会带过去 —— 它们会在首次使用时重建。
|
||
|
||
要重新开始,**退出应用**并删除该目录。要迁移,将该目录复制到新机器上即可。
|
||
|
||
```text
|
||
~/Library/Application Support/NomiFun/Nomi/ # macOS(Windows/Linux 路径见上文)
|
||
├── nomifun-backend.db # SQLite 状态(会话、设置、session 等)
|
||
├── logs/ # nomicore.log
|
||
├── companion/ # 伙伴 + 共享记忆中枢
|
||
├── knowledge/ # 受管理的知识库
|
||
├── runtime/ # 解压出的 Bun 运行时缓存(可再生)
|
||
└── server.lock # 后端运行期间持有的排他锁
|
||
```
|
||
|
||
## 认证与本地信任
|
||
|
||
桌面外壳不会把旧式完全无鉴权后端暴露给所有 localhost 调用者。它以
|
||
`TrustLocalToken` 启动嵌入式后端,向 WebView 注入 `window.__nomiLocalTrust`,
|
||
渲染端在 HTTP 与 WebSocket 请求中呈递该 secret。只知道
|
||
`127.0.0.1:<port>/api` 的其他进程不会自动被信任。
|
||
|
||
桌面应用仍是单用户工具:启动它的 OS 账户拥有 agent 能做的一切,包括 shell
|
||
和文件访问。
|
||
|
||
如果你想从另一台设备访问同一个安装,**不要**直接暴露嵌入的端口。请使用以下之一:
|
||
|
||
- **WebUI 远程访问** (一个按实例启用的功能,参见 [WebUI 远程访问](./webui-remote-access.zh.md)) —— 启动一个独立的认证服务器并提供二维码登录。
|
||
- **自托管 Web 服务器** ([Web 服务器部署](./web-server-deployment.zh.md)) —— 在 `nomifun-web` 下以无头方式运行同一个后端,并要求认证。
|
||
|
||
## 更新器状态
|
||
|
||
Tauri 更新器插件 (`tauri-plugin-updater`) 已接入,渲染进程暴露了 `invoke('check_for_updates')` (返回新版本字符串,若已是最新则返回 `null`)。然而:
|
||
|
||
- 在 `apps/desktop/tauri.conf.json` 中配置的端点 (`plugins.updater.endpoints`) 是一个**占位符** (`https://REPLACE-WITH-YOUR-HOST/...`)。在你将其替换为一个提供已签名的 `latest.json` 的真实 HTTPS URL 之前,更新器检查会失败。
|
||
- 包含的 `pubkey` 是一个为本地测试生成的**开发密钥**。**在任何公开发布前请替换它**,并将私钥存储在 CI 密钥中。
|
||
- `bun run build:updater` 会生成已签名的更新构件 (在每个安装器旁边附带 `.sig` 文件)。
|
||
|
||
完整 updater 流程(签名环境变量、`latest.json` schema、支持的平台键)在
|
||
`apps/desktop/updater/README.md` 中。OS 级别代码签名/公证是另一层:macOS
|
||
Developer ID 签名与公证已通过 `bun run build:signed` 和
|
||
`apps/desktop/signing/README.md` 接好;Windows 签名仍需要外部代码签名证书。
|
||
|
||
## 故障排查
|
||
|
||
**窗口打开后是空白白屏。**
|
||
确保已安装 WebView 运行时 (Windows 10 上的 WebView2 需要 Evergreen Bootstrapper)。在 Linux 上需要 `libwebkit2gtk-4.1-0`。
|
||
|
||
**"Failed to bind backend port"。**
|
||
另一个进程占用了 `127.0.0.1` 临时端口。后端会尝试 `pick_free_port()`,失败时回退到 `8799` —— 退出任何其他 NomiFun 实例后再试。
|
||
|
||
**Agent 命令失败并报 `bun: command not found`。**
|
||
Agent 引擎会派生 Bun 作为子进程来执行工具。请安装 Bun (`curl -fsSL https://bun.sh/install | bash`) 并确保它在系统 `PATH` 上,或者使用 `NOMIFUN_EMBED_BUN=1` 构建桌面包以将其嵌入。
|
||
|
||
## 另请参阅
|
||
|
||
- [Web 服务器部署](./web-server-deployment.zh.md) —— 在 `nomifun-web` 下以无头方式运行同一个后端。
|
||
- [WebUI 远程访问](./webui-remote-access.zh.md) —— 暴露你的桌面实例供远程浏览器/手机使用。
|