Files
ELY-Browser/PRD.md
T

1811 lines
66 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.
# PRD.md — ELY Browser by Elydora
文档日期:2026-05-07
状态:完整产品规格
产品名称:ELY Browser
品牌归属:Elydora
产品形态:跨平台 Native Rust 桌面浏览器
核心技术:Rust、GPUI、Servo WebView、gpui-component、awesome-gpui 生态组件
云端基础设施:Cloudflare Workers、Cloudflare D1、Cloudflare R2、Cloudflare Workers KV、Better Auth
核心能力:垂直标签页、Spaces、Profiles、Split View、登录、端到端加密 Sync、自有插件系统、隐私与性能控制
产品定位:clean browser;默认安静、界面克制、行为透明、数据可控
---
## 1. 产品结论
ELY Browser by Elydora 是一款纯净、快速、低打扰的 Native Rust 桌面浏览器。它以左侧垂直标签页作为默认信息架构,以 Spaces 承载任务上下文,以 Profiles 隔离账号、Cookie、历史与站点权限,以 Split View 支持同窗多网页并排工作,以端到端加密 Sync 保持多设备状态一致,以自有 `.rplug` Wasm 插件系统提供可审计、可撤销、可签名发布的扩展能力。
浏览器引擎使用 Servo。桌面 Shell 使用 GPUI。主组件库使用 gpui-component,并通过 awesome-gpui 生态中的 adabraka-ui、ferrum-flow、gpui-flow、gpui-form、gpui-hooks、gpui-nav、gpui-router、gpui-storybook、gpui-symbols、gpui-d3rs、gpui-px、gpui-video-player、plotters-gpui 完成完整桌面产品能力建设。
登录和 Sync 使用 Elydora Cloud,运行在 Cloudflare Workers。Better Auth 负责身份、账号、会话、OAuth、设备登录与会话安全;Cloudflare D1 负责结构化账号数据、设备索引、Sync 对象索引、变更日志、插件注册表元数据;Cloudflare R2 负责加密后的大对象、Sync 快照、头像、插件包、崩溃附件和导出文件;Cloudflare Workers KV 负责读多写少的全局配置、会话缓存、插件市场索引缓存、公开密钥缓存、更新清单缓存和短期同步游标缓存。
产品对标方向是 Zed 式 Native Rust/GPUI 高性能软件体验、Arc 的 Spaces / Profiles / Favorites / Split View / Auto Archive、Dia 的清爽任务表面与分屏入口、Zen Browser 的垂直标签与工作区、Vivaldi 的深度标签管理、Edge 与 Chrome 的主流化垂直标签体验。产品边界始终围绕 clean browser:界面克制、用户可控、隐私优先、插件安全、默认安静。
完整交付边界:
- 桌面端 macOS、Windows、Linux 原生安装包、签名、自动更新、崩溃恢复。
- Servo WebView 嵌入、导航、输入、缩放、截图、站点权限、下载、历史、书签、阅读模式、DevTools 入口。
- 左侧垂直标签系统、Spaces、Profiles、Favorites、Pinned Tabs、Tab Groups、Split View、自动归档、会话恢复。
- 登录、设备管理、端到端加密 Sync、本地加密数据库、冲突处理、离线可用。
- 自有 `.rplug` 插件系统、Wasm Component Model、WIT 接口、权限弹窗、插件管理器、插件市场、签名发布、审计日志。
- GPUI 设计系统、Storybook、设置中心、命令面板、键盘快捷键、菜单栏、托盘/通知、无障碍、国际化。
- Cloudflare Workers API、Better Auth、D1 schema、R2 bucket、KV namespace、密钥轮换、备份、监控、限流。
- 浏览器安全模型、隐私控制、遥测最小化、站点兼容性面板、性能任务管理器、发布验收矩阵。
本 PRD 只定义完整产品形态和完整实现要求。研发任务可以并行拆解,但产品规格本身保持单一完整交付边界。
---
## 2. Deep Research 依据
### 2.1 垂直标签页已经进入主流浏览器体验
Google Chrome 在 2026-04-07 发布的产品更新中推出“Show Tabs Vertically”,官方说明侧边标签可以读取完整页面标题并更容易管理标签组,尤其适合双位数标签场景。[R1]
Microsoft Edge 官方将 Vertical Tabs 定义为让用户在侧边栏中更容易扫描、组织和管理大量标签页的功能,覆盖 Windows 与 macOS。[R2]
Vivaldi 长期提供 Workspaces、Tab Stacks 与 Tab Tiling。官方说明 Workspaces 可以按类别分组标签和标签堆,Tab Tiling 可以把多个标签平铺到同一窗口内,减少反复切换。[R5][R6]
结论:垂直标签本身已经成为主流浏览器能力。ELY 的差异需要落在“垂直标签 + 任务空间 + 隐私同步 + 原生性能 + 插件安全 + 低打扰体验”的组合上。
### 2.2 Arc、Dia、Zen、Vivaldi 的可采纳体验
Arc 的 Favorites 是跨所有 Spaces 常驻的顶部标签;Auto Archive 会按用户设置清理 idle unpinned tabs,并支持按 Profile 调整归档时机。[R3][R4]
Vivaldi 的 Workspaces 让用户切换工作区时只看到该类别下的标签;Tab Tiling 支持垂直、水平、网格和自定义布局,并支持拖拽调整。[R5][R6]
Dia 的产品体验可作为清爽任务表面和分屏入口的参考:导航区尽量轻,内容区优先,分屏操作应在当前任务中就地完成。ELY 采纳其布局克制和任务连续性,产品能力仍保持 clean browser 边界。
结论:ELY 的 clean 浏览体验需要把 Arc 的上下文模型、Dia 的低噪声表面、Zen 的侧栏优先和 Vivaldi 的深度标签管理统一成一套更克制的 Native Rust 桌面交互。
### 2.3 GPUI 与 Native Rust 桌面 Shell
GPUI 官方定义为来自 Zed 创建者的快速、高生产力 Rust UI 框架;docs.rs 将 GPUI 描述为 hybrid immediate/retained mode、GPU accelerated 的 Rust UI 框架。[R7][R8]
Zed 团队公开说明,Zed 以类似游戏渲染管线的方式使用 Rust 和 GPU 构建高响应 UI;这为 ELY 的浏览器 Shell 提供性能和交互基准。[R9]
gpui-component 提供 60+ 跨平台桌面 UI 组件,包含虚拟化 Table/List、Dock 布局、主题系统、输入控件、弹窗、菜单等能力,适合作为浏览器设置页、侧栏、弹窗、列表、下载管理、历史记录、插件管理器的主组件库。[R10]
awesome-gpui 收录了 GPUI 应用、组件库、路由、表单、Hooks、图表、Storybook、符号、视频播放器和 Plotters 后端等生态项目。指定库均可映射到浏览器的实际产品模块。[R11]
结论:GPUI 承担原生 ShellServo 承担网页渲染,gpui-component 承担主要 UI 组件,awesome-gpui 生态补齐路由、表单、可视化、Storybook、图标、视频、图表与状态组织。
### 2.4 Servo 嵌入能力与约束
Servo 是 Rust 编写的 Web 渲染引擎,支持 WebGL/WebGPU,面向桌面、移动和嵌入式,并提供 WebView API 让应用嵌入 Web 内容。[R12]
Servo 在 2026-04-13 发布 `servo` crate,官方说明这是第一个允许 Servo 作为 library 使用的 crates.io release,同时说明该 release 仍处在 `1.0` 前,embedding API 仍会演进,并提供 LTS 轨道承接安全修复与迁移指导。[R13]
结论:ELY 需要把 Servo 当作浏览器引擎子系统集成。GPUI 与 Servo 之间需要专门的 WebView Host、输入桥、渲染桥、焦点桥、IME 桥、权限桥、下载桥和崩溃恢复桥。
### 2.5 Cloudflare + Better Auth 适合登录与 Sync 后端
Cloudflare D1 是托管 serverless SQL database,使用 SQLite 语义,支持 Workers 和 HTTP API 访问,并提供 Time Travel 与 read replication 能力。[R14]
Cloudflare 官方数据产品说明中,D1 适合持久化、关系型用户数据和账号数据;R2 是 S3-compatible blob storage,适合大对象和静态资源,并提供 per-object strong consistencyWorkers KV 是 eventually consistent 的低延迟键值存储,适合高读取量配置、会话和分布式配置。[R15]
Workers KV 的一致性模型是 eventually consistent,跨地区可见性可能需要 60 秒或更久,因此 ELY 把 KV 用于缓存和读多写少数据,把 D1 作为结构化事实源,把 R2 作为加密大对象事实源。[R16]
Better Auth 1.5 已将 Cloudflare D1 作为 first-class database option,允许直接传入 D1 binding;官方也说明 D1 不支持 interactive transactionsBetter Auth 使用 D1 `batch()` API 处理原子性。[R17]
第一版需要支持 GoogleGithubEmail OTP signin。
D1 当前单数据库上限为 Workers Paid 10 GB / Free 500 MB,账号级上限和数据库数量需要按 Cloudflare 限制设计;ELY 的 Sync schema 因此按账户、地区和对象类型预留拆分策略。[R18]
结论:ELY Cloud 使用 Cloudflare Workers + Better Auth + D1/R2/KV 可覆盖登录、设备、安全会话、同步索引、加密对象存储、插件市场和发布资产,同时需要严格区分事实源、缓存和对象存储。
### 2.6 自有插件系统采用 Wasm Component Model
WebAssembly Component Model 提供可移植、跨语言组合的组件架构,并使用 WIT 描述组件与 host 之间的接口;Wasmtime 提供 Component Model 嵌入 API。[R19][R20]
Wasmtime 安全文档说明 WebAssembly 的目标之一是以沙箱方式运行不受信代码,Wasm 默认需要显式 import 才能获得 host 能力。[R21]
结论:ELY 插件系统采用 `.rplug` 包、`plugin.toml` 清单、WIT 接口、Wasmtime Host、能力授权和签名发布。插件 API 完全由 ELY 定义,面向浏览器 UI、标签、书签、历史、下载、命令、侧栏、页面桥接和设置扩展。
---
## 3. 产品定位
### 3.1 目标用户
核心用户是长期依赖浏览器完成知识工作的人群,包括软件工程师、产品经理、设计师、研究人员、运营、创作者、学生和重度网页应用用户。共同特征是常开 20–200 个标签页,经常在项目、账号、文档、工具、资料之间切换,并需要低干扰、可恢复、可同步的浏览环境。
### 3.2 价值主张
用户通过左侧垂直工作台管理大量网页,通过 Spaces 将标签按任务上下文聚合,通过 Profiles 分离工作/个人/客户/项目账号,通过 Split View 在同一窗口并排处理资料,通过端到端加密 Sync 在多设备间恢复状态,通过自有插件系统扩展工作流,同时保持界面清爽、动作透明和数据可控。
### 3.3 产品原则
- Clean first:默认界面克制,空白、层级、动效、通知和入口数量受控。
- Local first:标签、历史、书签、会话、设置、插件配置先写本地数据库,云端承担同步与备份。
- Privacy firstSync 数据端到端加密,遥测默认最小化,敏感数据使用系统钥匙串保存。
- Keyboard first:核心浏览动作均可通过命令面板和快捷键完成。
- Vertical first:垂直标签页是默认信息架构,顶部区域只保留地址栏、命令入口和必要状态。
- Profile strictCookie、Storage、历史、权限、证书例外、下载策略按 Profile 明确隔离。
- Plugin safe:插件通过显式权限、Wasm 沙箱、签名、审计、资源限额和可撤销授权运行。
- Engine honestServo 兼容性以可见状态、反馈入口和站点诊断面板展示。
- Desktop native:窗口、菜单、快捷键、拖拽、文件、通知、系统主题、IME 和无障碍遵循平台习惯。
---
## 4. 品牌与命名
产品正式名称为 ELY Browser by Elydora。界面中主名称使用 “ELY Browser”,品牌页、关于页、法律页和安装包发行方使用 “Elydora”。短名称使用 “ELY”。
命名规范:
- App nameELY Browser
- Company / brandElydora
- Short display nameELY
- macOS bundle id`com.elydora.ely-browser`
- Windows app id`Elydora.ELYBrowser`
- Linux desktop id`com.elydora.ely-browser.desktop`
- Sync service nameElydora Cloud
- Plugin package suffix`.rplug`
- Plugin registry nameElydora Plugin Registry
- Protocol handler`ely://`
- Auth callback`ely://auth/callback`
- Plugin deep link`ely://plugin/<plugin_id>`
- Settings deep link`ely://settings/<section>`
视觉方向:ELY 使用冷静、轻量、低饱和的桌面应用气质。品牌表达偏专业,不使用过度拟物、重渐变和高频动效。默认主题遵循系统浅色/深色,允许用户设置 Space 级强调色。
---
## 5. 用户画像与关键场景
### 5.1 软件工程师
工程师在浏览器中频繁打开 GitHub、GitLab、Linear、Jira、文档、本地开发地址、日志平台和云控制台。浏览器需要把一个项目的所有网页放在同一 Space 中,并允许使用 Split View 同时查看本地页面、PR、接口文档和日志。
关键需求:
- 每个项目一个 Space,每个客户或公司账号一个 Profile。
- Localhost、PR、Issue、文档、Dashboard 可固定在同一 Space。
- 地址栏支持命令、URL、书签、历史和打开标签搜索。
- 标签支持按域名、项目、标题规则自动归组。
- 下载、证书例外、站点权限与 Profile 绑定。
- 插件可提供本地开发面板、API 收藏、Mock 切换、路由查看、日志链接解析。
### 5.2 产品经理 / 项目管理者
产品经理需要在任务系统、文档、表格、会议记录、设计稿和数据看板间切换。浏览器需要减少标签噪声,并保留每个项目上下文。
关键需求:
- Space 支持图标、颜色、顺序、固定页、分组、自动归档。
- Split View 支持文档 + 看板、需求 + 设计、表格 + 数据页。
- 书签支持项目级集合,历史支持按 Space 过滤。
- 同步可恢复其他设备上未完成的工作空间。
- 插件可扩展项目看板入口、状态徽标、页面右键操作。
### 5.3 UI/UX 设计师
设计师需要浏览竞品、Figma、文档、原型、视频素材和评论。浏览器需要更好的分屏、截图、媒体预览和页面信息收集。
关键需求:
- Split View 支持最多四个网页区域,并可保存为复合标签。
- 侧栏支持页面截图、颜色采样、字体信息、可访问性摘要。
- 内置媒体预览支持视频文件和网页下载内容。
- 工作区图谱可显示竞品页、参考页、设计稿与备注之间的关系。
- 插件可扩展页面审查、截图导出、链接收集和设计资源标记。
### 5.4 研究人员 / 内容创作者
研究人员需要保存大量资料、阅读长文、管理引用、记录来源并跨设备继续阅读。浏览器需要高质量阅读模式、书签集合、摘录、历史搜索和 Sync。
关键需求:
- 阅读模式保留标题、作者、时间、正文、图片、链接来源。
- 书签集合支持标签、备注、排序、导出。
- 历史搜索支持域名、标题、正文索引和 Space 过滤。
- 侧栏支持当前页面备注和摘录。
- 插件可扩展文献管理、RSS、导出器和外部笔记系统。
---
## 6. 信息架构
```text
ELY Browser
├─ Identity
│ ├─ Account
│ ├─ Sessions
│ ├─ Devices
│ ├─ Recovery Keys
│ └─ Sync Vault
├─ Windows
│ └─ Browser Window
│ ├─ Title Bar / Traffic Controls
│ ├─ Command Bar
│ ├─ Vertical Workspace
│ │ ├─ Favorites
│ │ ├─ Spaces
│ │ ├─ Tab Groups
│ │ ├─ Pinned Tabs
│ │ ├─ Unpinned Tabs
│ │ └─ Archived Tabs
│ ├─ WebView Canvas
│ │ ├─ Single WebView
│ │ ├─ Split View
│ │ └─ Error / Recovery View
│ ├─ Side Panels
│ │ ├─ Bookmarks
│ │ ├─ History
│ │ ├─ Downloads
│ │ ├─ Reading List
│ │ ├─ Notes
│ │ ├─ Plugin Panels
│ │ └─ Task Manager
│ └─ Status Bar
├─ Browser Data
│ ├─ Profiles
│ ├─ Site Data
│ ├─ Permissions
│ ├─ Certificates
│ ├─ Bookmarks
│ ├─ History
│ ├─ Downloads
│ ├─ Reading List
│ ├─ Notes
│ └─ Sessions
├─ Plugin System
│ ├─ Plugin Registry
│ ├─ Wasm Host
│ ├─ Permission Broker
│ ├─ UI Contributions
│ ├─ Page Bridge
│ ├─ Package Store
│ ├─ Signature Verifier
│ └─ Audit Log
├─ Elydora Cloud
│ ├─ Cloudflare Workers API
│ ├─ Better Auth
│ ├─ Cloudflare D1
│ ├─ Cloudflare R2
│ ├─ Cloudflare Workers KV
│ └─ Observability
└─ Platform Services
├─ Keychain
├─ Notifications
├─ Menus
├─ Clipboard
├─ File Picker
├─ Protocol Handler
├─ Auto Update
└─ Accessibility
```
---
## 7. 核心 UI/UX
### 7.1 主窗口布局
```text
┌──────────────────────────────────────────────────────────────────────────────┐
│ ELY [Space: Work ▾] [Search or enter address........................] ⋯ │
├───────────────┬──────────────────────────────────────────────────────────────┤
│ ★ Favorites │ │
│ ○ Mail │ │
│ ○ Calendar │ │
│ ○ Docs │ │
│───────────────│ │
│ Work │ │
│ ▾ Project A │ │
│ ● PR #241 │ Servo WebView Canvas │
│ ● API Docs │ │
│ ● Logs │ │
│ ▸ Design │ │
│───────────────│ │
│ Spaces │ │
│ Work │ │
│ Personal │ │
│ Research │ │
│───────────────│ │
│ + New Tab │ │
└───────────────┴──────────────────────────────────────────────────────────────┘
```
布局要求:
- 左侧侧栏默认宽度 280px,可收缩到 56px 图标态。
- 顶部地址栏固定在内容区顶部,避免顶部标签挤压。
- 垂直标签列表使用虚拟化渲染,支持 1,000 个标签对象仍保持流畅滚动。
- 当前标签、悬浮标签、未读变化、加载中、错误态、静音态、固定态、归档态都有清晰视觉标识。
- 在全屏和专注模式下,侧栏可自动隐藏,鼠标靠近左缘或快捷键唤起。
- 所有浏览动作均可通过命令面板执行。
### 7.2 Split View
```text
┌──────────────────────────────────────────────────────────────────────────────┐
│ [Address / Command Bar] [Split ▾] │
├───────────────┬─────────────────────────────┬────────────────────────────────┤
│ Vertical Tabs │ │ │
│ │ WebView A │ WebView B │
│ │ │ │
│ ├─────────────────────────────┴────────────────────────────────┤
│ │ Split Controls: swap | duplicate | detach | save | close │
└───────────────┴──────────────────────────────────────────────────────────────┘
```
Split View 要求:
- 支持 2、3、4 个 WebView。
- 支持横向、纵向、网格和自定义拖拽布局。
- Split View 作为一个复合标签保存在垂直侧栏中。
- 复合标签可固定、归档、移动到其他 Space、参与 Sync。
- 每个子 WebView 独立导航、刷新、下载、站点权限和错误恢复。
- 地址栏对当前聚焦子 WebView 生效。
- 链接右键支持“在 Split View 中打开”。
- 标签拖入内容区边缘时显示 Split Drop Target。
### 7.3 Command Bar
Command Bar 是 ELY 的统一入口,支持 URL、搜索、命令、书签、历史、打开标签、设置项、插件命令。
输入行为:
- `github.com`:导航到 URL。
- `? rust async book`:使用默认搜索引擎。
- `>`:进入命令模式。
- `@tabs`:只搜已打开标签。
- `@bookmarks`:只搜书签。
- `@history`:只搜历史。
- `@settings`:只搜设置项。
- `@plugins`:只搜插件命令。
命令示例:
- `New Space`
- `Switch Profile`
- `Open Downloads`
- `Clear Site Data for This Profile`
- `Save Split View`
- `Move Tab to Space`
- `Archive Idle Tabs`
- `Install Plugin from File`
- `Open Sync Status`
### 7.4 Settings
Settings 使用 `gpui-router` 管理路由,使用 `gpui-form` 管理表单,使用 gpui-component 提供 Tabs、Form、Switch、Select、Table、Dialog、Toast、List、Sidebar、Search。
设置页结构:
```text
Settings
├─ General
├─ Appearance
├─ Sidebar & Tabs
├─ Spaces
├─ Profiles
├─ Search
├─ Privacy & Security
├─ Sync
├─ Downloads
├─ Site Permissions
├─ Plugins
├─ Shortcuts
├─ Updates
├─ Advanced
└─ About ELY Browser
```
设置页要求:
- 每个设置项必须有即时校验、保存状态、恢复默认值。
- 参与 Sync 的设置必须显示同步状态。
- 高风险设置必须二次确认。
- 设置搜索支持标题、说明、关键词、快捷键。
- About 页展示 ELY Browser、Elydora、构建号、Servo 构建信息、GPUI 构建信息、许可证入口。
---
## 8. 浏览器功能规格
### 8.1 垂直标签系统
标签对象字段:
| 字段 | 说明 |
|---|---|
| `tab_id` | 本地唯一 ID |
| `space_id` | 所属 Space |
| `profile_id` | 所属 Profile |
| `parent_tab_id` | opener 来源 |
| `title` | 页面标题 |
| `url` | 当前 URL |
| `display_url` | 脱敏展示 URL |
| `favicon_key` | favicon 本地缓存 key |
| `state` | loading / ready / crashed / discarded / archived |
| `is_pinned` | 是否固定 |
| `is_favorite` | 是否跨 Space 常驻 |
| `group_id` | 所属 Tab Group |
| `split_id` | 所属 Split View |
| `last_active_at` | 最近使用时间 |
| `created_at` | 创建时间 |
| `sort_key` | CRDT ordered list 排序键 |
| `sync_enabled` | 是否参与 Sync |
标签行为:
- 新标签默认插入当前标签下方。
- 从当前页面打开的新标签保留 opener 关系。
- 支持拖拽排序、拖拽到 Space、拖拽成 Split View、拖拽成 Tab Group。
- 支持批量选择、批量移动、批量归档、批量关闭。
- 支持搜索当前窗口、当前 Space、全部窗口中的打开标签。
- 支持标签休眠,休眠后释放 Servo WebView 资源,仅保留会话数据。
- 支持崩溃恢复,崩溃标签保留 URL、标题、favicon 和表单恢复提示。
### 8.2 Spaces
Space 是任务上下文。每个 Space 拥有自己的标签、固定区、分组、自动归档策略、主题强调色、默认 Profile 和侧栏状态。
Space 字段:
| 字段 | 说明 |
|---|---|
| `space_id` | 全局唯一 ID |
| `name` | 名称 |
| `icon` | 图标 |
| `accent_color` | 强调色 |
| `default_profile_id` | 默认 Profile |
| `archive_policy` | 自动归档策略 |
| `sidebar_width` | 侧栏宽度 |
| `sort_key` | 排序键 |
| `created_at` | 创建时间 |
| `updated_at` | 更新时间 |
Space 行为:
- Space 切换只改变可见标签集合,不强制打开新窗口。
- 一个窗口可以持有多个 Space。
- 同一 Space 可在多个窗口打开,但编辑冲突必须可恢复。
- Space 可导出为 `.elyspace` 文件。
- Space 可导入,导入时可选择是否保留 Profile 映射。
- Space 删除进入本地回收站,保留 30 天。
### 8.3 Profiles
Profile 是站点数据隔离边界。Profile 隔离 Cookie、Storage、Cache、History scope、Permissions、Certificates、Downloads policy、Search engine preference。
Profile 字段:
| 字段 | 说明 |
|---|---|
| `profile_id` | 全局唯一 ID |
| `name` | 名称 |
| `color` | 颜色 |
| `icon` | 图标 |
| `cookie_store_id` | Cookie 容器 |
| `history_policy` | 历史策略 |
| `download_policy` | 下载策略 |
| `permission_policy` | 权限策略 |
| `is_private` | 是否隐私 Profile |
| `sync_policy` | 同步策略 |
Profile 行为:
- 每个 Space 绑定一个默认 Profile。
- 单个标签可覆盖 Profile。
- Profile 切换需要明确展示视觉标识,避免用户在错误账号环境下操作。
- 隐私 Profile 关闭后清理 Cookie、Storage、Cache、临时下载索引和页面会话。
- Profile 可暂停 Sync。
- Profile 删除需要先展示受影响站点数据、历史、权限和下载策略。
### 8.4 Favorites / Pinned / Archived
Favorites 是跨所有 Spaces 常驻的顶部标签,适合邮箱、日历、任务系统、常用文档和音乐。Pinned Tabs 是 Space 内常驻标签。Archived Tabs 是被关闭或自动归档但可恢复的标签。
要求:
- Favorites 上限默认 12,可在设置中调整。
- Favorites 始终显示 favicon,悬浮显示标题和 Profile。
- Pinned Tabs 展示在当前 Space 顶部。
- Unpinned Tabs 按使用顺序和分组展示。
- 自动归档只作用于 Unpinned Tabs。
- 归档记录保留 URL、标题、favicon、Space、Profile、关闭时间、来源。
- 归档搜索支持域名、标题、Space、Profile、日期。
### 8.5 Tab Groups
Tab Group 用于 Space 内的二级组织。
能力:
- 支持名称、颜色、折叠、排序。
- 支持拖拽标签进出 Group。
- 支持 Group 内批量刷新、关闭、休眠、归档。
- 支持按域名自动归组。
- 支持把 Group 转成 Split View。
- 支持把 Split View 解散成 Group。
### 8.6 History
历史记录按 Profile 隔离,并可按 Space 建立上下文索引。
能力:
- 记录 URL、标题、访问时间、来源标签、Space、Profile、favicon、访问次数。
- 支持全文索引页面标题和 URL。
- 阅读模式页面支持正文索引,用户可关闭。
- 支持按域名清理、按时间清理、按 Profile 清理。
- 支持历史 Sync,默认关闭正文索引同步。
- 隐私 Profile 不写入持久历史。
### 8.7 Bookmarks / Reading List / Notes
书签支持集合、标签、备注和导入导出。Reading List 用于稍后阅读。Notes 是页面侧栏轻量备注。
能力:
- 书签集合可绑定 Space。
- 书签可保存页面截图缩略图。
- Reading List 保存阅读进度、页面标题、来源 URL、添加时间。
- Notes 绑定 URL 或具体标签对象。
- Notes 支持 Markdown 子集。
- 书签、Reading List、Notes 均参与端到端加密 Sync。
### 8.8 Downloads
下载管理器提供下载生命周期控制和安全提示。
能力:
- start / pause / resume / cancel / retry / open / reveal。
- 下载路径按 Profile 设置。
- 危险扩展名提示。
- 文件 checksum 可选计算。
- 下载历史可按 Profile 清理。
- 下载文件本体默认不参与 Sync,下载元数据可参与 Sync。
- 下载完成后可触发插件事件。
### 8.9 Site Permissions
站点权限按 Profile 隔离。
权限类型:
- Camera
- Microphone
- Screen capture
- Location
- Notifications
- Clipboard read
- Clipboard write
- Downloads
- Popups
- Autoplay
- WebUSB / WebHID / WebSerial
- Storage persistence
- Insecure content
- Certificate exception
要求:
- 权限弹窗显示站点、Profile、权限类型、风险说明。
- 用户可选择一次允许、始终允许、始终拒绝。
- 权限变更写入审计日志。
- Site Settings 可按站点查看所有授权。
### 8.10 Reading Mode
Reading Mode 提供低干扰阅读体验。
能力:
- 提取标题、作者、发布时间、正文、图片、链接。
- 支持字体、字号、行高、页面宽度、主题。
- 支持目录导航。
- 支持保存到 Reading List。
- 支持复制引用信息。
- 支持导出 Markdown。
- 支持按 Profile 和 Space 记录阅读进度。
### 8.11 Private Windows
Private Window 使用临时 Profile。
要求:
- 不写持久历史。
- 不持久化 Cookie、Storage、Cache。
- 下载文件保留在用户选择位置,下载索引关闭窗口后清理。
- 插件默认禁用,用户可为单个插件开启 Private Window 权限。
- Sync 在 Private Window 中默认禁用。
---
## 9. 登录与 Sync
### 9.1 总体原则
ELY 使用账户登录建立设备身份,使用端到端加密保护 Sync 内容。身份系统和 Sync 加密系统职责独立:Better Auth 确认“谁登录”,Sync Vault 决定“谁能解密”。Elydora Cloud 永远只保存密文 payload、索引、游标和必要元数据。
本地优先写入流程:
```text
User Action
Local Encrypted Store
Sync Queue
Client-side Encryption
Cloudflare Workers Sync API
D1 Object Index + R2 Encrypted Payload + KV Cache
Other Devices Pull Delta
Decrypt + Merge + Apply
```
### 9.2 登录能力
登录入口:
- Email + password。
- OAuth provider,可配置 Apple、Google、GitHub。
- Passkey。
- 设备二维码登录。
- Recovery key 登录恢复。
登录 UX
- 首次打开 ELY 可跳过登录,浏览器完整离线可用。
- 登录后进入 Sync 设置向导。
- 用户可选择同步范围。
- 登录会话保存在系统钥匙串。
- 本地浏览器数据库密钥保存在系统钥匙串。
- 账号注销时可以选择保留本地数据或清理本地数据。
Better Auth 职责:
- 用户注册、登录、邮箱验证、OAuth、Passkey、会话刷新、会话撤销。
- 设备登录授权。
- 账号删除流程。
- 安全事件记录。
- 与 D1 绑定,存储用户、账号、会话和验证相关表。
Desktop auth callback
```text
ELY Browser → Open auth page in WebView or system browser
Auth completed on Elydora Cloud
Cloudflare Worker redirects to ely://auth/callback?code=...
ELY exchanges code for session
Session token stored in platform keychain
Sync setup starts inside ELY settings
```
### 9.3 Sync 数据对象
| 对象 | 默认同步 | 加密 | 冲突策略 |
|---|---:|---:|---|
| Account profile display info | 是 | 部分 | Last writer wins |
| Devices | 是 | 否 | Server authority |
| Spaces | 是 | 是 | CRDT ordered list |
| Tabs | 是 | 是 | CRDT ordered list + focus timestamp |
| Split Views | 是 | 是 | Object merge |
| Tab Groups | 是 | 是 | CRDT ordered list |
| Favorites | 是 | 是 | CRDT ordered list |
| Pinned Tabs | 是 | 是 | CRDT ordered list |
| Archived Tabs | 是 | 是 | Append-only log |
| Profiles metadata | 是 | 是 | Object merge |
| Cookies | 否 | 是 | 用户显式开启 |
| Site permissions | 是 | 是 | Last writer wins + audit |
| Bookmarks | 是 | 是 | CRDT tree |
| Reading List | 是 | 是 | Object merge |
| Notes | 是 | 是 | CRDT text |
| History | 可选 | 是 | Append-only log |
| Downloads metadata | 可选 | 是 | Append-only log |
| Browser settings | 是 | 是 | Last writer wins |
| Shortcuts | 是 | 是 | Last writer wins |
| Plugin list | 是 | 是 | Object merge |
| Plugin settings | 可选 | 是 | Plugin-defined merge |
### 9.4 Sync 加密模型
密钥结构:
```text
User Secret
├─ Account Recovery Key
├─ Device Key Pair
└─ Sync Root Key
├─ Spaces Key
├─ Tabs Key
├─ Bookmarks Key
├─ History Key
├─ Settings Key
├─ Plugin Data Key
└─ Snapshot Key
```
要求:
- Sync Root Key 在客户端生成。
- Better Auth 密码、OAuth 账号和服务器会话均不能直接解密 Sync payload。
- 新设备加入时,需要已登录设备批准、Recovery Key 或 Passkey + Recovery Key 组合。
- 密文 payload 使用 AEAD 加密。
- 每个对象保存 `object_id``object_type``encrypted_payload``payload_hash``schema_rev``created_at``updated_at`
- D1 只存索引和小型密文;大型密文写入 R2。
- R2 object key 不直接暴露 URL、标题、站点名等敏感信息。
- 服务端日志不得记录 URL 明文、标题明文、书签明文、历史明文。
### 9.5 Sync 冲突处理
冲突来源:
- 两台设备同时移动同一标签。
- 同一 Space 在多设备同时重命名。
- 同一书签树节点同时移动。
- 同一设置项同时修改。
- 某设备离线数天后重新上线。
处理方式:
- 有序列表使用 CRDT ordered list,保留稳定排序键。
- 普通对象使用 `updated_at + device_id + logical_clock` 解决。
- 不可自动合并的冲突进入 Conflict Center。
- Conflict Center 展示对象类型、设备、时间、差异和操作按钮。
- 用户可保留本机、保留远端、手动合并或复制副本。
### 9.6 Sync 状态 UI
```text
Settings / Sync
┌────────────────────────────────────────────────────┐
│ Account: zachary@example.com │
│ Device: MacBook Pro │
│ Sync: Connected │
├────────────────────────────────────────────────────┤
│ Spaces [on] Last synced: just now │
│ Tabs [on] Last synced: just now │
│ Bookmarks [on] Last synced: 2 min ago │
│ History [off] Privacy controlled │
│ Plugin settings [on] Last synced: just now │
├────────────────────────────────────────────────────┤
│ Devices │
│ • MacBook Pro current │
│ • Windows Desktop active │
│ • Linux Laptop last seen yesterday │
├────────────────────────────────────────────────────┤
│ [Add Device] [View Recovery Key] [Reset Sync Data] │
└────────────────────────────────────────────────────┘
```
状态要求:
- 顶栏只在 Sync 异常时显示小型状态图标。
- 设置页展示最近同步时间、队列长度、失败对象数量。
- Sync 失败不阻塞本地浏览。
- 用户可以按对象类型暂停同步。
- 用户可以导出加密 Sync 备份。
- 用户可以从云端删除全部 Sync 数据。
---
## 10. Elydora Cloud 后端规格
### 10.1 架构
```text
ELY Desktop Client
↓ HTTPS
Cloudflare Workers API
├─ /api/auth/* Better Auth
├─ /api/sync/push Sync object upload
├─ /api/sync/pull Delta pull
├─ /api/sync/snapshot Snapshot upload/download
├─ /api/devices/* Device management
├─ /api/plugins/* Plugin registry
├─ /api/releases/* Update manifest
└─ /api/telemetry/* Minimal diagnostics
Cloudflare D1
├─ better_auth_* tables
├─ user_devices
├─ sync_objects
├─ sync_change_log
├─ sync_snapshots
├─ plugin_registry
├─ plugin_reviews
└─ audit_events
Cloudflare R2
├─ sync-payloads/
├─ sync-snapshots/
├─ plugin-packages/
├─ user-avatars/
├─ crash-attachments/
└─ exports/
Cloudflare Workers KV
├─ public_config
├─ auth_session_cache
├─ plugin_registry_cache
├─ public_signing_keys
├─ release_manifest_cache
└─ sync_cursor_cache
```
### 10.2 Cloudflare D1 使用边界
D1 是结构化事实源。
D1 存储:
- Better Auth 用户、账号、会话、验证相关表。
- 设备记录:设备 ID、设备公钥、设备名称、平台、最后活跃时间。
- Sync 对象索引:对象 ID、对象类型、owner、payload 位置、hash、schema、时间戳。
- Sync 变更日志:用于增量拉取。
- Sync 快照索引:指向 R2 snapshot object。
- 插件注册表元数据:插件 ID、名称、作者、权限声明、签名状态、包位置。
- 审计事件:登录、设备加入、设备撤销、权限变更、插件安装、Sync reset。
D1 不存储:
- URL 明文。
- 页面标题明文。
- 书签明文。
- 历史明文。
- Notes 明文。
- Cookie 明文。
- 插件私有配置明文。
D1 schema 设计要求:
- 所有用户数据表必须有 `user_id`
- 所有 Sync 事实表必须有 `object_id``object_type``logical_clock``device_id`
- 所有可删除对象必须有 `deleted_at` tombstone。
- 所有增量拉取必须通过 `sync_change_log` 读取。
- 所有 D1 写入必须可幂等重放。
- 单个 D1 数据库接近容量阈值时按地区或账户拆分。
### 10.3 Cloudflare R2 使用边界
R2 是加密大对象事实源。
R2 存储:
- 大型 Sync payload。
- 周期性 Sync snapshot。
- 插件 `.rplug` 包。
- 插件图标、截图和说明文件。
- 用户头像。
- 加密导出文件。
- 用户主动提交的崩溃附件。
R2 object key 规范:
```text
sync-payloads/{region}/{user_hash}/{object_type}/{object_id}/{payload_hash}.bin
sync-snapshots/{region}/{user_hash}/{snapshot_id}.bin
plugin-packages/{plugin_id}/{package_hash}.rplug
plugin-assets/{plugin_id}/{asset_hash}
user-avatars/{user_hash}/{avatar_hash}
crash-attachments/{report_id}/{attachment_hash}
exports/{user_hash}/{export_id}.bin
```
要求:
- 所有 Sync payload 上传前在客户端加密。
- R2 metadata 不写敏感明文。
- Worker 只签发短期上传/下载访问。
- 插件包必须通过签名验证后才进入 registry 可见状态。
- 用户删除账号时触发 R2 对象清理任务。
### 10.4 Cloudflare Workers KV 使用边界
KV 是缓存和读多写少配置存储。
KV 存储:
- `public_config`:公开运行配置、服务端开关、地区路由提示。
- `auth_session_cache`:短期会话验证缓存。
- `plugin_registry_cache`:插件市场列表缓存。
- `public_signing_keys`:插件签名公钥、服务端公钥。
- `release_manifest_cache`:自动更新清单缓存。
- `sync_cursor_cache`:短期同步游标缓存。
KV 使用规则:
- KV 不作为 Sync 事实源。
- KV 不存储端到端加密密钥。
- KV 不存储需要强一致的对象状态。
- KV 缓存可随时失效,所有关键数据必须可从 D1/R2 重建。
- KV key 设计必须包含 namespace 和环境前缀。
- KV TTL 必须按用途设置,默认不得无限期保存短期状态。
### 10.5 Better Auth 集成
Better Auth 在 Cloudflare Workers 中初始化,D1 binding 作为 database 传入。
能力要求:
- Email/password 注册登录。
- OAuth provider 配置。
- Passkey 支持。
- 邮箱验证。
- 会话刷新。
- 会话撤销。
- 设备登录授权。
- 安全事件记录。
- 账号删除。
- 管理所有 `/api/auth/*` 路由。
会话策略:
- Access session 短期有效。
- Refresh session 存放在系统钥匙串。
- 服务端可以撤销单设备或全部设备会话。
- Desktop client 每次启动执行 session validation。
- 高风险操作要求重新验证。
### 10.6 API 规格
Auth
| Endpoint | Method | 说明 |
|---|---|---|
| `/api/auth/*` | Any | Better Auth handler |
| `/api/devices` | GET | 当前账号设备列表 |
| `/api/devices/register` | POST | 注册当前设备公钥 |
| `/api/devices/approve` | POST | 批准新设备加入 |
| `/api/devices/revoke` | POST | 撤销设备 |
Sync
| Endpoint | Method | 说明 |
|---|---|---|
| `/api/sync/push` | POST | 上传对象变更 |
| `/api/sync/pull` | GET | 按 cursor 拉取增量 |
| `/api/sync/snapshot` | POST | 上传加密快照 |
| `/api/sync/snapshot` | GET | 下载加密快照 |
| `/api/sync/reset` | POST | 删除云端 Sync 数据 |
| `/api/sync/status` | GET | 获取队列和游标状态 |
Plugin
| Endpoint | Method | 说明 |
|---|---|---|
| `/api/plugins` | GET | 插件列表 |
| `/api/plugins/:id` | GET | 插件详情 |
| `/api/plugins/:id/package` | GET | 获取签名包下载信息 |
| `/api/plugins/publish` | POST | 发布插件包 |
| `/api/plugins/revoke` | POST | 撤销插件包 |
Update
| Endpoint | Method | 说明 |
|---|---|---|
| `/api/releases/manifest` | GET | 自动更新清单 |
| `/api/releases/signature` | GET | 发布包签名信息 |
### 10.7 后端数据表
Better Auth 表由 Better Auth schema 管理。ELY 自定义表如下:
| 表 | 用途 |
|---|---|
| `user_devices` | 用户设备、公钥、平台、活跃状态 |
| `device_approvals` | 新设备加入批准记录 |
| `sync_objects` | Sync 对象索引 |
| `sync_change_log` | Sync 增量日志 |
| `sync_snapshots` | Sync 快照索引 |
| `sync_tombstones` | 删除标记 |
| `plugin_registry` | 插件注册表 |
| `plugin_packages` | 插件包和签名 |
| `plugin_reviews` | 插件审核记录 |
| `audit_events` | 安全审计事件 |
| `release_manifests` | 发布清单索引 |
`sync_objects` 字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| `object_id` | text | 对象 ID |
| `user_id` | text | 用户 ID |
| `object_type` | text | 对象类型 |
| `payload_inline` | blob nullable | 小型密文 |
| `payload_r2_key` | text nullable | R2 key |
| `payload_hash` | text | payload hash |
| `schema_rev` | integer | schema 修订号 |
| `logical_clock` | integer | 逻辑时钟 |
| `device_id` | text | 来源设备 |
| `created_at` | integer | 创建时间 |
| `updated_at` | integer | 更新时间 |
| `deleted_at` | integer nullable | 删除时间 |
`sync_change_log` 字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| `change_id` | integer | 自增变更 ID |
| `user_id` | text | 用户 ID |
| `object_id` | text | 对象 ID |
| `object_type` | text | 对象类型 |
| `operation` | text | upsert / delete |
| `payload_hash` | text | payload hash |
| `logical_clock` | integer | 逻辑时钟 |
| `device_id` | text | 来源设备 |
| `created_at` | integer | 创建时间 |
---
## 11. 自有插件系统
### 11.1 插件定位
ELY 只支持自有 `.rplug` 插件协议。插件用于扩展浏览器命令、侧栏、设置页、上下文菜单、下载处理、书签导出、页面信息读取、开发工具和工作流集成。
插件设计目标:
- 安全:默认无能力,所有能力显式授权。
- 可审计:所有权限声明、运行事件、用户授权和异常都记录。
- 可撤销:用户可以随时停用插件或撤销单项权限。
- 可移植:插件以 Wasm Component Model 作为运行边界。
- 可签名:市场插件必须签名,侧载插件显示风险提示。
- 可恢复:插件崩溃不得影响浏览器主进程和网页渲染。
### 11.2 `.rplug` 包结构
```text
my-plugin.rplug
├─ plugin.toml
├─ component.wasm
├─ wit/
│ └─ ely-browser.wit
├─ assets/
│ ├─ icon.svg
│ └─ preview.png
├─ README.md
├─ LICENSE
└─ signatures/
└─ ed25519.sig
```
`plugin.toml` 字段:
| 字段 | 说明 |
|---|---|
| `id` | 插件唯一 ID |
| `name` | 插件名 |
| `description` | 简介 |
| `author` | 作者 |
| `homepage` | 主页 |
| `permissions` | 权限声明 |
| `contributes` | UI / command / menu 贡献点 |
| `min_ely_build` | 最低 ELY 构建要求 |
| `checksum` | Wasm checksum |
| `signature` | 签名信息 |
### 11.3 插件权限
权限清单:
| 权限 | 能力 |
|---|---|
| `tabs:read` | 读取标签元数据 |
| `tabs:write` | 创建、移动、关闭标签 |
| `spaces:read` | 读取 Space 元数据 |
| `spaces:write` | 创建、修改、删除 Space |
| `bookmarks:read` | 读取书签 |
| `bookmarks:write` | 写入书签 |
| `history:read` | 读取历史 |
| `downloads:read` | 读取下载列表 |
| `downloads:write` | 控制下载 |
| `page:metadata` | 读取当前页面标题、URL、favicon |
| `page:screenshot` | 获取当前页面截图 |
| `page:script` | 注入受限页面脚本 |
| `clipboard:read` | 读取剪贴板 |
| `clipboard:write` | 写入剪贴板 |
| `filesystem:read` | 读取用户选择的文件 |
| `filesystem:write` | 写入用户选择的位置 |
| `network:fetch` | 插件发起网络请求 |
| `settings:read` | 读取插件设置 |
| `settings:write` | 写入插件设置 |
| `sync:plugin` | 插件配置参与 Sync |
| `ui:panel` | 注册侧栏 Panel |
| `ui:command` | 注册命令 |
| `ui:context_menu` | 注册右键菜单 |
授权要求:
- 首次安装展示权限列表。
- 高风险权限单独确认。
- 页面脚本权限必须按域名授权。
- 网络权限必须声明目标域名或使用用户确认。
- 文件权限必须通过系统文件选择器授予。
- 插件权限变更必须重新确认。
### 11.4 插件 UI 贡献点
贡献点:
- Command Bar commands。
- Tab context menu。
- Page context menu。
- Sidebar panels。
- Settings pages。
- Status bar indicators。
- Download actions。
- Bookmark actions。
- Reading Mode exporters。
插件 UI 使用 GPUI Host 提供的声明式组件接口,不允许直接访问主进程内部对象。插件 UI 只能通过 WIT host calls 请求数据和提交事件。
### 11.5 插件市场
插件市场提供:
- 列表、搜索、分类、详情页。
- 权限摘要。
- 签名状态。
- 作者信息。
- 安装量。
- 最近更新。
- 用户评分。
- 安全审核状态。
- 安装、禁用、卸载、更新。
插件详情页必须展示:
- 插件名称、作者、描述。
- 权限清单和解释。
- 数据访问范围。
- 是否参与 Sync。
- 包 checksum。
- 签名状态。
- 举报入口。
---
## 12. 技术架构
### 12.1 本地架构
```text
ELY Desktop
├─ App Shell (Rust + GPUI)
│ ├─ Window Manager
│ ├─ Command Bar
│ ├─ Sidebar
│ ├─ Settings
│ ├─ Panels
│ └─ Notifications
├─ Browser Core
│ ├─ Tab Manager
│ ├─ Space Manager
│ ├─ Profile Manager
│ ├─ Session Manager
│ ├─ Permission Manager
│ ├─ Download Manager
│ ├─ History Manager
│ ├─ Bookmark Manager
│ └─ Reading Mode
├─ Servo Host
│ ├─ WebView Host
│ ├─ Rendering Bridge
│ ├─ Input Bridge
│ ├─ Focus Bridge
│ ├─ IME Bridge
│ ├─ Permission Bridge
│ ├─ Download Bridge
│ └─ DevTools Bridge
├─ Data Layer
│ ├─ Local Encrypted SQLite
│ ├─ Object Store
│ ├─ Search Index
│ ├─ Keychain Adapter
│ └─ Migration Engine
├─ Sync Core
│ ├─ Queue
│ ├─ Crypto
│ ├─ Merge Engine
│ ├─ Conflict Center
│ └─ Cloud API Client
├─ Plugin Host
│ ├─ Wasmtime Runtime
│ ├─ WIT Bindings
│ ├─ Permission Broker
│ ├─ UI Host
│ ├─ Event Bus
│ └─ Audit Log
└─ Platform Adapters
├─ macOS
├─ Windows
└─ Linux
```
### 12.2 GPUI 生态映射
| 库 | 用途 | 验收要求 |
|---|---|---|
| gpui-component | 主组件库,设置页、列表、弹窗、菜单、表格、Dock | 所有核心 UI 使用统一主题、间距、焦点态 |
| adabraka-ui | 视觉增强组件、空状态、卡片、按钮组 | 只用于提升 clean UI 表达,不引入视觉噪声 |
| ferrum-flow | 工作区图谱、插件可视化配置、导入导出流程 | 节点编辑场景可拖拽、缩放、保存 |
| gpui-flow | 轻量可视化节点编辑 | 用于规则编辑器和插件工作流图 |
| gpui-form | 设置表单、Profile 表单、插件权限表单 | 表单字段自动校验、错误提示、重置 |
| gpui-hooks | 组件内部状态复用 | Hook 边界清晰,避免跨模块隐式状态 |
| gpui-nav | 设置导航、侧栏导航、面板导航 | 支持键盘导航和焦点恢复 |
| gpui-router | Settings、internal pages、plugin pages | `ely://settings/*` 可直接打开 |
| gpui-storybook | 设计系统和组件验收 | 每个核心组件有 Story |
| gpui-symbols | 平台符号图标 | macOS 使用 SF Symbols 风格,其他平台 fallback |
| gpui-tea | 浏览器 Shell 状态循环 | 适用于 Tab/Space/Window 事件模型 |
| gpui-d3rs | 低层图表 | 性能任务管理器与诊断图表 |
| gpui-px | 高层图表 | 历史趋势、下载速度、Sync 状态 |
| plotters-gpui | plotters 后端 | 高级性能分析图 |
| gpui-video-player | 本地视频下载预览 | 下载完成后可预览视频文件 |
### 12.3 Servo 集成
Servo Host 需要实现:
- WebView 生命周期:create、attach、detach、sleep、restore、destroy。
- 导航:load URL、back、forward、reload、stop、same-document navigation。
- 输入:mouse、keyboard、touch、wheel、drag、drop。
- IMEcomposition start/update/end、candidate window placement。
- 渲染:texture handoff、resize、damage tracking、frame scheduling。
- 焦点:WebView focus、address bar focus、plugin panel focus。
- 权限:permission request → GPUI dialog → profile policy → Servo response。
- 下载:download start → Download Manager → file picker / policy。
- 截图:tab thumbnail、reading capture、plugin screenshot permission。
- DevTools:打开当前 WebView 调试入口。
- 崩溃恢复:WebView crash event → tab recovery view。
站点兼容性要求:
- 内置 Site Compatibility Panel。
- 用户可复制诊断信息。
- 诊断信息包括 Servo build、URL host、Profile、权限、错误码、控制台摘要。
- 用户可选择提交匿名站点兼容报告。
- 报告默认去除 URL path 和 query。
### 12.4 本地数据
本地数据使用加密 SQLite + 对象文件夹。
本地库:
- `ely_browser.db`:核心关系数据。
- `ely_search.db`:搜索索引。
- `ely_sync.db`Sync 队列和游标。
- `objects/`:截图、favicon、阅读缓存、插件包。
- `profiles/`Profile 级 Servo site data。
本地加密要求:
- 数据库密钥存储于系统钥匙串。
- 用户可启用启动密码。
- 隐私 Profile 使用临时密钥。
- 退出时清理隐私 Profile 临时数据。
- 崩溃恢复文件同样加密。
---
## 13. 安全与隐私
### 13.1 安全边界
- GPUI Shell 与 Servo WebView 分离。
- Web 内容与插件运行时分离。
- 插件默认无权限。
- Profile 之间站点数据隔离。
- Sync 密文与账号会话分离。
- 本地密钥与云端会话分离。
- 高风险操作有显式确认和审计日志。
### 13.2 隐私默认值
- 遥测默认最小化。
- 历史 Sync 默认由用户选择。
- Cookie Sync 默认关闭。
- 插件网络权限默认关闭。
- 插件页面脚本权限默认关闭。
- 站点通知默认询问。
- 位置权限默认询问。
- 第三方插件市场安装默认显示风险提示。
### 13.3 审计日志
本地审计日志记录:
- 登录和注销。
- 新设备加入。
- 设备撤销。
- Sync reset。
- 插件安装、启用、禁用、卸载。
- 插件权限授权和撤销。
- 站点权限授权和撤销。
- 证书例外。
- 私有数据清理。
审计日志默认只保存在本地,可选择端到端加密同步。
---
## 14. 性能指标
| 指标 | 要求 |
|---|---:|
| 冷启动到首窗可交互 | P95 < 1.5s |
| 新建标签响应 | P95 < 80ms |
| Command Bar 打开 | P95 < 50ms |
| 侧栏滚动 | 60fps 目标 |
| 1,000 标签侧栏内存增量 | < 80MB |
| 标签切换 Shell 响应 | P95 < 80ms |
| WebView 崩溃恢复 UI | < 300ms |
| Sync 10k 对象增量应用 | P95 < 2s |
| 插件启动 | P95 < 300ms |
| 插件单次 host call | P95 < 20ms |
| 设置页路由切换 | P95 < 80ms |
| 下载列表 10k 项滚动 | 60fps 目标 |
性能工具:
- 内置 Task Manager。
- Tab memory usage。
- WebView CPU / memory。
- Plugin CPU / memory / calls。
- Sync queue length。
- Download throughput。
- GPUI frame time。
- Servo frame time。
---
## 15. 跨平台要求
### 15.1 macOS
- Universal binary。
- Notarization。
- Native menu bar。
- Traffic lights integration。
- Keychain。
- Notification Center。
- Services menu。
- Drag/drop files and URLs。
- Fullscreen and Spaces behavior。
- Touchpad gestures。
- IME support。
### 15.2 Windows
- x64 installer。
- Code signing。
- Windows Credential Manager。
- Jump List。
- System notifications。
- Snap layout support。
- High contrast mode。
- Per-monitor DPI。
- IME support。
- Protocol handler registration。
### 15.3 Linux
- AppImage / deb / rpm。
- Secret Service integration。
- Wayland + X11。
- Desktop file。
- Portal file picker。
- Notifications。
- System theme detection。
- IME support。
- Protocol handler registration。
---
## 16. 可访问性与国际化
### 16.1 可访问性
要求:
- 所有可交互控件提供 accessible name。
- 侧栏标签可键盘遍历。
- Command Bar 支持屏幕阅读器。
- 弹窗焦点 trap。
- Dialog 关闭后焦点返回触发元素。
- 高对比主题。
- Reduced motion。
- 可配置字号和 UI density。
- Split View 子区域有明确焦点边框。
- 错误提示使用文本和图标双重表达。
### 16.2 国际化
默认语言:English、简体中文。
后续语言通过资源文件扩展。
要求:
- 文案不硬编码。
- 日期、时间、数字格式本地化。
- 快捷键显示按平台本地化。
- RTL 布局预留。
- 插件市场支持插件多语言说明。
---
## 17. 内置页面
内置页面使用 `ely://` 协议。
| 路由 | 页面 |
|---|---|
| `ely://new-tab` | 新标签页 |
| `ely://settings` | 设置 |
| `ely://settings/sync` | Sync 设置 |
| `ely://settings/profiles` | Profiles 设置 |
| `ely://settings/plugins` | 插件设置 |
| `ely://history` | 历史 |
| `ely://bookmarks` | 书签 |
| `ely://downloads` | 下载 |
| `ely://reading-list` | Reading List |
| `ely://archive` | Archived Tabs |
| `ely://task-manager` | 任务管理器 |
| `ely://plugins` | 插件市场 |
| `ely://plugin/<id>` | 插件详情 |
| `ely://sync/status` | Sync 状态 |
| `ely://about` | 关于 ELY Browser |
| `ely://crash/<tab_id>` | 标签崩溃恢复 |
| `ely://site/<origin>` | 站点设置 |
---
## 18. 键盘快捷键
| 动作 | macOS | Windows/Linux |
|---|---|---|
| Command Bar | `Cmd+L` / `Cmd+T` | `Ctrl+L` / `Ctrl+T` |
| 命令模式 | `Cmd+Shift+P` | `Ctrl+Shift+P` |
| 新建标签 | `Cmd+T` | `Ctrl+T` |
| 关闭标签 | `Cmd+W` | `Ctrl+W` |
| 恢复关闭标签 | `Cmd+Shift+T` | `Ctrl+Shift+T` |
| 切换下一个标签 | `Cmd+Option+↓` | `Ctrl+Alt+↓` |
| 切换上一个标签 | `Cmd+Option+↑` | `Ctrl+Alt+↑` |
| 切换 Space | `Cmd+Option+←/→` | `Ctrl+Alt+←/→` |
| Toggle Sidebar | `Cmd+B` | `Ctrl+B` |
| Split Right | `Cmd+\` | `Ctrl+\` |
| Open Downloads | `Cmd+Shift+J` | `Ctrl+Shift+J` |
| Open History | `Cmd+Y` | `Ctrl+H` |
| Open Settings | `Cmd+,` | `Ctrl+,` |
| Task Manager | `Cmd+Esc` | `Shift+Esc` |
快捷键要求:
- 所有快捷键可自定义。
- 冲突检测必须实时提示。
- 插件快捷键必须进入同一冲突检测系统。
- 用户可导入导出快捷键配置。
---
## 19. 验收矩阵
### 19.1 产品验收
| ID | 模块 | 验收标准 |
|---|---|---|
| P-001 | Brand | 应用、安装包、关于页、协议、服务名统一为 ELY Browser by Elydora |
| P-002 | Vertical Tabs | 1,000 标签可滚动、搜索、拖拽、批量操作 |
| P-003 | Spaces | 创建、切换、排序、导出、导入、删除恢复完整可用 |
| P-004 | Profiles | Cookie、Storage、History、Permissions 严格隔离 |
| P-005 | Split View | 2/3/4 WebView 支持保存为复合标签 |
| P-006 | Favorites | 跨 Space 常驻并可 Sync |
| P-007 | Archive | Unpinned Tabs 自动归档并可搜索恢复 |
| P-008 | Command Bar | URL、搜索、命令、书签、历史、标签统一搜索 |
| P-009 | Downloads | 生命周期控制、Profile 策略、安全提示完整 |
| P-010 | Reading Mode | 正文提取、样式设置、阅读进度、导出完整 |
| P-011 | Settings | 所有设置项可搜索、校验、保存、恢复默认 |
| P-012 | Login | Better Auth 登录、OAuth、Passkey、设备管理可用 |
| P-013 | Sync | Spaces、tabs、bookmarks、settings、plugin settings 可端到端加密同步 |
| P-014 | Cloudflare | D1/R2/KV 边界清晰,所有 API 可观测、可限流、可恢复 |
| P-015 | Plugins | `.rplug` 安装、授权、运行、停用、卸载、市场完整 |
| P-016 | Privacy | 用户可查看、导出、删除本地和云端数据 |
| P-017 | Cross-platform | macOS、Windows、Linux 构建、签名、安装、更新可用 |
### 19.2 安全验收
| ID | 模块 | 验收标准 |
|---|---|---|
| S-001 | Sync encryption | 服务端无法解密 Sync payload |
| S-002 | Keychain | session token 和本地数据库密钥存入系统钥匙串 |
| S-003 | Device revoke | 撤销设备后无法继续拉取 Sync delta |
| S-004 | Plugin sandbox | 插件无声明权限时无法访问 tabs/bookmarks/history/page |
| S-005 | Plugin signature | 市场插件必须签名验证通过 |
| S-006 | Site permissions | 所有站点权限按 Profile 隔离 |
| S-007 | Private Window | 关闭后无持久 Cookie、Storage、History |
| S-008 | Audit log | 高风险操作全部写入本地审计日志 |
| S-009 | Cloud logs | 服务端日志不得记录敏感明文 URL、标题、历史、书签 |
| S-010 | Account deletion | 删除账号触发 D1/R2/KV 数据清理 |
### 19.3 性能验收
| ID | 指标 | 验收标准 |
|---|---|---:|
| F-001 | Cold start | P95 < 1.5s |
| F-002 | New tab | P95 < 80ms |
| F-003 | Command Bar | P95 < 50ms |
| F-004 | Sidebar scroll | 60fps 目标 |
| F-005 | Tab switch | P95 < 80ms |
| F-006 | Sync apply | 10k delta P95 < 2s |
| F-007 | Plugin launch | P95 < 300ms |
| F-008 | Settings route | P95 < 80ms |
| F-009 | Downloads list | 10k rows 60fps 目标 |
| F-010 | Split resize | 60fps 目标 |
---
## 20. 工程组织与开发规范
### 20.1 Rust workspace
```text
ely-browser/
├─ crates/
│ ├─ ely_app/
│ ├─ ely_ui/
│ ├─ ely_design_system/
│ ├─ ely_browser_core/
│ ├─ ely_servo_host/
│ ├─ ely_profiles/
│ ├─ ely_tabs/
│ ├─ ely_spaces/
│ ├─ ely_history/
│ ├─ ely_bookmarks/
│ ├─ ely_downloads/
│ ├─ ely_permissions/
│ ├─ ely_sync/
│ ├─ ely_crypto/
│ ├─ ely_plugins/
│ ├─ ely_plugin_wit/
│ ├─ ely_cloud_client/
│ ├─ ely_storage/
│ ├─ ely_search/
│ ├─ ely_platform/
│ └─ ely_telemetry/
├─ cloudflare/
│ ├─ worker/
│ ├─ migrations/
│ ├─ wrangler.toml
│ └─ tests/
├─ plugins/
│ ├─ examples/
│ └─ sdk/
├─ assets/
├─ stories/
├─ tests/
└─ docs/
```
### 20.2 Cloudflare worker workspace
```text
cloudflare/
├─ worker/
│ ├─ src/
│ │ ├─ index.ts
│ │ ├─ auth.ts
│ │ ├─ sync.ts
│ │ ├─ devices.ts
│ │ ├─ plugins.ts
│ │ ├─ releases.ts
│ │ ├─ audit.ts
│ │ └─ bindings.ts
│ ├─ package.json
│ └─ tsconfig.json
├─ migrations/
│ ├─ 0001_auth.sql
│ ├─ 0002_devices.sql
│ ├─ 0003_sync.sql
│ ├─ 0004_plugins.sql
│ └─ 0005_audit.sql
├─ wrangler.toml
└─ tests/
```
Cloudflare 绑定:
```text
D1 binding: ELY_DB
R2 bucket: ELY_STORAGE
KV namespace: ELY_KV
```
环境要求:
- `local`:本地开发。
- `staging`:预发布验证。
- `production`:正式服务。
每个环境必须拥有独立 D1 database、R2 bucket、KV namespace 和 Better Auth secret。
### 20.3 代码规范
- Rust 使用 workspace lint。
- 所有跨模块事件使用 typed event。
- 所有 Sync object 变更必须有 migration、merge、encryption test。
- 所有插件 host call 必须有权限测试。
- 所有设置项必须有 schema、默认值、校验器、UI story。
- 所有 Cloudflare API 必须有 auth、rate limit、schema validation、audit。
- 所有 D1 migration 必须可回放。
- 所有 R2 object write 必须校验 checksum。
- 所有 KV 写入必须设置命名空间前缀。
### 20.4 测试要求
测试类型:
- Unit tests。
- Integration tests。
- Snapshot tests。
- UI story tests。
- Sync conflict tests。
- Encryption tests。
- Plugin sandbox tests。
- Cloudflare Worker API tests。
- D1 migration tests。
- R2 upload/download tests。
- KV cache invalidation tests。
- Cross-platform smoke tests。
- Servo site compatibility smoke tests。
测试数据:
- 10 tabs。
- 100 tabs。
- 1,000 tabs。
- 10,000 history rows。
- 10,000 bookmarks。
- 10,000 Sync objects。
- 100 plugins installed but inactive。
- 10 active plugins。
- 4 Split View panes。
- 3 Profiles。
- 20 Spaces。
---
## 21. 运营、监控与发布
### 21.1 遥测最小化
默认收集:
- App 启动成功/失败。
- 崩溃报告。
- WebView crash 类型。
- Sync 错误码。
- 插件崩溃事件。
- 更新成功/失败。
默认不收集:
- URL 明文。
- 页面标题。
- 搜索词。
- 书签内容。
- 历史内容。
- Notes 内容。
- Cookie。
- 表单输入。
用户可在 Settings / Privacy & Security 中关闭诊断上报。
### 21.2 Cloudflare 监控
监控项:
- Worker request rate。
- Worker error rate。
- Auth success/failure rate。
- D1 query latency。
- D1 write failure。
- R2 upload/download failure。
- KV cache hit rate。
- Sync push/pull latency。
- Sync conflict rate。
- Device revoke events。
- Plugin install failure。
- Plugin signature failure。
告警:
- Auth failure spike。
- Sync 5xx spike。
- D1 query latency spike。
- R2 write failure spike。
- KV stale cache anomaly。
- Plugin signature verification failure spike。
### 21.3 更新系统
更新系统要求:
- 发布包签名验证。
- 更新清单通过 Cloudflare Workers 提供,并缓存到 KV。
- 发布包存储在 R2。
- 客户端下载后验证 checksum 和签名。
- 更新失败回滚到上一可用构建。
- 用户可选择自动更新或手动更新。
---
## 22. 风险与应对
| 风险 | 影响 | 应对 |
|---|---|---|
| Servo 站点兼容不足 | 复杂网页渲染、登录、媒体可能异常 | 站点兼容面板、Top sites smoke、错误恢复、诊断提交 |
| GPUI 生态仍在快速演进 | API 变动影响 UI 工程 | 锁定依赖 commit、封装 UI facade、Storybook 覆盖核心组件 |
| D1 单数据库容量限制 | 大规模 Sync 元数据增长 | 按账户、地区、对象类型拆分;R2 承担大 payload |
| KV eventual consistency | 用户看到短期缓存滞后 | KV 只做缓存,D1/R2 作为事实源 |
| Better Auth 与 Workers 运行差异 | Auth callback、session、cookie 策略复杂 | 独立 Auth 集成测试,Desktop callback smoke |
| 插件滥用权限 | 用户数据风险 | Wasm 沙箱、权限 broker、审计日志、签名市场、资源限额 |
| Sync 冲突 | 多设备状态混乱 | CRDT ordered list、Conflict Center、对象级审计 |
| 跨平台输入法问题 | 中文、日文、韩文输入体验受损 | IME 桥专项测试、平台适配器、候选框定位测试 |
| Split View 资源消耗 | 多 WebView 内存上涨 | 休眠策略、任务管理器、资源提示 |
| 下载安全风险 | 恶意文件执行 | 危险扩展名提示、checksum、下载来源展示 |
---
## 23. 关键决策
| 决策 | 结果 |
|---|---|
| 产品名称 | ELY Browser by Elydora |
| 产品定位 | clean browser |
| UI 框架 | GPUI |
| 主组件库 | gpui-component |
| Web 引擎 | Servo |
| 标签形态 | 左侧垂直标签为默认信息架构 |
| 任务上下文 | Spaces |
| 账号/站点隔离 | Profiles |
| 多网页并排 | Split View |
| 登录 | Better Auth on Cloudflare Workers |
| 数据库 | Cloudflare D1 |
| 对象存储 | Cloudflare R2 |
| 缓存/配置 | Cloudflare Workers KV |
| Sync | 本地优先 + 端到端加密 + D1/R2/KV |
| 插件系统 | 自有 `.rplug` Wasm Component Model |
| 插件市场 | Elydora Plugin Registry |
| 外部浏览器插件运行时 | 不纳入产品接口 |
| 遥测 | 默认最小化,可关闭 |
---
## 24. Reference
[R1] Google Chrome — Get more done with new vertical tabs and immersive reading mode in Chrome — https://blog.google/products-and-platforms/products/chrome/new-chrome-productivity-features/
[R2] Microsoft Edge — Vertical Tabs — https://explore.microsoft.com/en-us/edge/features/vertical-tabs?form=MT0160 <br>
[R3] Arc Help Center — Favorites: Top Tabs Across Every Space — https://resources.arc.net/hc/en-us/articles/19230755904151-Favorites-Top-Tabs-Across-Every-Space
[R4] Arc Help Center — Auto Archive: Clean as you go — https://resources.arc.net/hc/en-us/articles/19228855311127-Auto-Archive-Clean-as-you-go
[R5] Vivaldi — Workspaces — https://vivaldi.com/features/workspaces/
[R6] Vivaldi Help — Tab Tiling — https://help.vivaldi.com/desktop/tabs/tab-tiling/
[R7] GPUI official — https://gpui.rs/ <br>
[R8] docs.rs — GPUI — https://docs.rs/gpui
[R9] Zed Blog — Leveraging Rust and the GPU to render user interfaces at 120 FPS — https://zed.dev/blog/videogame
[R10] gpui-component — https://github.com/longbridge/gpui-component
[R11] zed-industries/awesome-gpui — https://github.com/zed-industries/awesome-gpui
[R12] Servo official — https://servo.org/
[R13] Servo Blog — Servo is now available on crates.io — https://servo.org/blog/2026/04/13/servo-0.1.0-release/
[R14] Cloudflare D1 docs — https://developers.cloudflare.com/d1/
[R15] Cloudflare Workers docs — Choose a data or storage product — https://developers.cloudflare.com/workers/platform/storage-options/
[R16] Cloudflare Workers KV docs — How KV works — https://developers.cloudflare.com/kv/concepts/how-kv-works/
[R17] Better Auth 1.5 — Cloudflare D1 Support — https://better-auth.com/blog/1-5
[R18] Cloudflare D1 limits — https://developers.cloudflare.com/d1/platform/limits/
[R19] WebAssembly Component Model — https://component-model.bytecodealliance.org/
[R20] Wasmtime Component Model embedding API — https://docs.wasmtime.dev/api/wasmtime/component/index.html
[R21] Wasmtime Security — https://docs.wasmtime.dev/security.html