Files
app/tauri/README.md
T

138 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# LineUp Tauri Reference Host
这是 LineUp Mini Runtime 的第一版 Tauri 2 Reference Host。它独立于当前 `upstream/tangsengdaodao-android/` 快速实验工程,不替换或修改现有 Android 验证路径。
## 已实现的最小闭环
- 可信 Host 前端:AppServer 地址、手机号/验证码登录、退出;
- AppServer 交互:`/login``/messages/send``/messages/sync`
- 用户消息本地即时回显与送达状态;
- HTTP 同步游标:首次 `0`、后续最后序号 `+ 1`
- `lineup.v1.text``agent.status``agent.progress``error` 的基础 Renderer
- `marked + DOMPurify` 的 GFM Markdown 安全渲染;
- Tauri 2 Rust Host、capability 文件与桌面窗口配置。
AppServer 已配置只允许 `tauri://localhost``https://tauri.localhost``http://tauri.localhost` 三个 Tauri Host origin 跨源调用。若产品使用新的 Tauri origin 或独立 Web 客户端,应先在 `lineup-app-server/configs/lineup.yaml``client.allowedOrigins` 显式加入,不能放开任意 Origin。
macOS 的 `src-tauri/Info.plist` 为当前 Tailscale / 私网 HTTP AppServer 配置了 `NSAllowsArbitraryLoadsInWebContent`。该例外仅作用于 Host 的 WKWebView 内容请求,使其能访问类似 `http://100.x.y.z:8090` 的地址,不放宽 Rust 原生网络层;待所有 AppServer 都迁移到 HTTPS 后应移除。
`ui.open / patch / close``app.call` 已被协议层识别,但目前安全降级为可见提示;它们是下一阶段 Mini Runtime Surface Host 与 Capability Registry 的实现范围,不能在当前 Host 页面中直接执行 Agent JavaScript 或直接授予设备能力。
## Milestone 0 当前行为基线
本节记录 Runtime 重构前已经由 Mac 开发态验证的行为。它是 M0 的回归基线,不代表最终模块结构;正式阶段任务和准入门槛见 [App Layer 架构方案 §9.1](../../设计/02.正式方案/lineup-app-layer-architecture.md#91-阶段任务清单与硬性准入门槛)。
| 范围 | 当前行为 | 当前实现位置 | 重构后必须保持 |
|---|---|---|---|
| 登录 | 用户输入 AppServer 地址、手机号、验证码;登录请求 10 秒超时;地址仅保存到 localStorage | `src/main.ts` | 成功登录进入会话;失败原因对用户可见 |
| 会话 | 当前只有一个 Agent channel;退出清空页面内消息并停止同步 | `src/main.ts` | 会话状态必须可由 Store 管理,不能依赖 DOM |
| 发送 | 用户消息先本地显示,再调用 `/messages/send`;显示已发送或失败 | `src/main.ts` | 即时反馈、送达状态与失败可见性不退化 |
| 历史同步 | 首次从 cursor `0` 连续拉取到空页;之后以 `lastSeq + 1` 每 1.5 秒增量轮询 | `src/main.ts` | 保持包含式 cursor 语义,不能漏消息或无限热循环 |
| Agent 文本 | 将 `lineup.v1.text` 解码为 Markdown,使用 `marked + DOMPurify` 渲染 | `src/protocol.ts``src/main.ts` | GFM、安全净化和外链防护不退化 |
| Agent 状态 | `thinking` 显示临时指示器;其他状态更新顶栏 presence | `src/protocol.ts``src/main.ts` | 状态应更新已有状态项,而非无限追加气泡 |
| 进度和错误 | progress/error 目前以系统提示显示 | `src/protocol.ts``src/main.ts` | 迁移后至少保持可见,M1 再升级为正式卡片 |
| 未实现扩展 | `ui.open / patch / close``app.call` 仅安全降级为提示,绝不执行不可信脚本或原生能力 | `src/protocol.ts``src/main.ts` | 在 M2/M3 完成前始终保持拒绝执行 |
### M0 回归场景
每次迁移或拆分模块后,至少执行以下场景;其中 `R01` 为构建级检查,其余为 Mac 浏览器访问 Linux 开发 Host 的人工验收,直至 M0 建立自动化测试。
- **M0-R01:构建。** `npm run build` 通过 TypeScript 检查与 Vite 打包。
- **M0-R02:登录。** 使用 Tailscale AppServer 登录;成功切换到聊天页,错误地址/超时给出可理解提示。
- **M0-R03:历史追平。** 登录后 presence 从“正在同步消息”变为“已同步,等待消息”,已有 Agent 历史可见。
- **M0-R04:本地回显。** 发送普通文本后,用户气泡立即出现,随后显示已发送或发送失败。
- **M0-R05Agent 回复。** Hermes 回复能够在未刷新页面时出现,并按 Markdown 安全渲染。
- **M0-R06:刷新恢复。** 刷新并重新登录后,历史仍可追平,不能重复无限渲染同一条 Agent 消息。
- **M0-R07:安全降级。** 收到未知 `lineup.v1.*` 类型、`ui.*``app.*` 请求时,页面不崩溃、不执行脚本/能力,并给出可见提示。
### 当前结构债务(M0 的改造对象)
`src/main.ts` 目前同时包含 App Shell、页面 DOM、登录、直接 HTTP `fetch`、会话 cursor、同步循环、协议到展示的映射和 renderer。M0 的目的不是改变上述用户行为,而是将它们迁入 `app-shell``transport``conversation-store``interaction-kernel``renderer-registry` 等独立边界;在 M0 准入前不新增 Surface 或 Capability 功能。
### M0-02 协议模型(已完成)
`src/protocol.ts` 是目前唯一允许把 Transport 原始 payload 转换成可信表现模型的入口。它定义了 `JsonValue``Actor`、严格 `Envelope``ConversationItem``UserAction``DeliveryState``ProtocolFallback`,并提供:
- `parseEnvelope(value)`:校验版本、消息类型、`id``conversation_id`、sender/target、timestamp 和 JSON payload
- `parseEnvelopeJSON(raw)`:供不接受历史纯文本的 Transport / Kernel 路径把非法 JSON 明确归为 `invalid_json`
- `decodeConversationItem(raw)`:保留历史纯文本作为 Markdown 的兼容行为;对于非法 LineUp envelope、未知类型和各类非法 payload,返回受控 fallback,绝不触发执行。
该文件不依赖 DOM、`fetch`、Tauri 或本地存储。Surface 与 Capability 在本阶段只校验其基础合约并降级显示;不加载 bundle,也不调用能力。下一项 M0-03 才会将此模型接入 Interaction Kernel 和 Renderer Registry。
### M0-03 Interaction Kernel 与 Renderer Registry(已完成)
`src/runtime/interaction-kernel.ts` 是 Transport 与表现层之间的唯一入口:它将原始同步/实时 payload 解码为 `ConversationItem`,对有有效 LineUp `id` 的消息实施有界去重,并将 Agent status 投影为可读取的 presence 快照。它不执行 `ui.*``app.*` 或用户动作。
`src/runtime/renderer-registry.ts` 只根据已验证的 `ConversationItem.kind` 分派已注册的可信 renderer;renderer 的输入只有表现项与 View context,不会获得 Transport 或 Capability 对象。当前聊天页已通过该 Registry 渲染同步进入的标准项。为了避免在 M0-03 跨阶段重写 UI,具体 DOM renderer 仍在 `main.ts`;M0-06 会把它们迁移为独立可信 renderer 模块。
## 本地命令
```bash
cd lineup-app/tauri
npm install
# 日常开发:启动 Vite 热更新 + 未打包的 Tauri 桌面壳
npm run desktop:dev
# 纯 Web 开发:Linux 开发机监听全部网卡,供 Mac 浏览器访问
npm run web:dev
# Mac 浏览器访问(经 Tailscale
# http://100.121.118.116:1420
# 仅检查并构建前端静态文件
npm run build
# Linux:仅构建 Debian 包,避免为不需要的 AppImage 下载额外运行器
npm run tauri -- build --debug --bundles deb
# macOSApple Silicon / Intel):生成 .app 与 .dmg
npm run tauri build -- --debug
```
`npm run desktop:dev` 不生成 `.app``.dmg` 或安装包。前端 TypeScript / CSS / HTML 保存后会由 Vite 自动热更新;改动 `src-tauri/` 中的 Rust Host 代码时,Tauri 会重新编译并重启开发窗口。只有需要交付可安装文件时才执行 `tauri build`
`npm run web:dev` 只运行同一份可信 Host Web UI,适合在浏览器中快速调试登录、消息和 Renderer。它监听 `0.0.0.0:1420`Mac 通过 Tailscale 打开 `http://100.121.118.116:1420`,直接验证 Linux 工作区的 Vite 热更新;不需要为每次验证将源码同步到 Mac。它不具备 Tauri 原生能力,也不应作为第三方 Mini Runtime Surface 的安全验收环境。AppServer 仅对固定开发 Origin `http://127.0.0.1:1420``http://100.121.118.116:1420` 配置 CORS;若改动 Vite 端口或 Host 地址,必须同步收紧更新 AppServer 的 `client.allowedOrigins`,不得改为 wildcard。
本项目的 `tauri``check:rust` npm 脚本会自动识别 Linux x86_64、macOS Apple Silicon、macOS Intel 的 Rust stable toolchain,并加入 `PATH`。因此不要直接执行裸 `tauri build`;统一使用 `npm run tauri build -- --debug`。如 Rust toolchain 安装在其他位置,可临时覆盖:
```bash
RUST_TOOLCHAIN_BIN=/path/to/rust/bin npm run tauri build -- --debug
```
## 本机构建状态(2026-08-03
- `npm run build`:已通过;
- Cargo/Tauri Rust crates:已下载并开始编译;
- Tauri Linux desktop build:已通过;debug 可执行文件和 Debian 包已生成;
- Android Spike:尚未开始。仍需要 Android NDK、Rust Android targets 与 Tauri Android 初始化。
Linux 桌面构建依赖以下系统开发库;本机已具备。新环境缺少时可安装:
```bash
sudo apt-get update
sudo apt-get install -y pkg-config libdbus-1-dev libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev
```
本机已生成的产物:
```text
src-tauri/target/debug/lineup-tauri
src-tauri/target/debug/bundle/deb/LineUp_0.1.0_amd64.deb
```
Tauri 构建产物位于 `src-tauri/target/`,已被 Git 忽略。图标源文件是 `src-tauri/icons/icon.svg`,其余 PNG/ICO/ICNS 与 Android/iOS 图标由 `npm run tauri icon src-tauri/icons/icon.svg` 生成。
## 目录边界
```text
tauri/
├── src/ # 可信 LineUp Host 前端
│ ├── main.ts # 会话 UI、AppServer transport、Renderer 调度
│ └── protocol.ts # 平台无关的 LineUp v1 → ConversationItem 解码
├── src-tauri/ # Tauri Rust Host 与 capability 配置
└── package.json # Vite、Tauri CLI 与前端依赖
```
第三方 Agent Surface 未来必须运行于独立隔离执行域,只能经 LineUp Mini Runtime 事件桥与 Capability Gateway 通信;不得访问 Tauri `invoke`、Host DOM、登录态或本机特权。