feat: add quick memo switcher and update demo seed notes

This commit is contained in:
tianma-if committed 2026-08-23 17:13:30 +08:00
1 parent 3de4fc2115
commit 537f8675db
11 files changed
+1196 -56

No files matched your search

+2 -17
View File
@@ -45,22 +45,7 @@ export const decodeDemoAttachment = (resource: DemoAttachmentSeed): Uint8Array =
return Uint8Array.from(binary, (character) => character.charCodeAt(0));
};
export const DEMO_ATTACHMENT_MARKDOWN_ZH = `
### 📎 7. 附件上传与下载示例
export const DEMO_ATTACHMENT_MARKDOWN_ZH = "";
下面这些是真实存储在 Demo R2 中的示例附件,点击即可下载,帮助你快速体验不同文件类型的附件能力:
export const DEMO_ATTACHMENT_MARKDOWN_EN = "";
- [📄 产品简介 PDF:edgeever-product-brief.pdf](/api/v1/resources/res_demo_product_brief_pdf/blob)
- [📊 功能矩阵 CSV:feature-matrix.csv](/api/v1/resources/res_demo_feature_matrix_csv/blob)
- [📦 附件示例压缩包:edgeever-attachment-demo.zip](/api/v1/resources/res_demo_attachment_bundle_zip/blob)
`;
export const DEMO_ATTACHMENT_MARKDOWN_EN = `
### 📎 7. Attachment Upload & Download Demo
These are real sample files stored in the Demo R2 bucket. Click any card to download and try different attachment types:
- [📄 Product brief PDF: edgeever-product-brief.pdf](/api/v1/resources/res_demo_product_brief_pdf/blob)
- [📊 Feature matrix CSV: feature-matrix.csv](/api/v1/resources/res_demo_feature_matrix_csv/blob)
- [📦 Attachment demo archive: edgeever-attachment-demo.zip](/api/v1/resources/res_demo_attachment_bundle_zip/blob)
`;
+421 -10
View File
@@ -16,42 +16,438 @@ export const DEMO_SEED_NOTEBOOKS = [
{ id: "nb_demo_features", parentId: "nb_projects", name: "功能演示", slug: "demo-features", icon: "notebook", color: "#0891b2", sortOrder: 21 },
{ id: "nb_demo_features_en", parentId: "nb_projects", name: "Feature Demos", slug: "feature-demos", icon: "notebook", color: "#0e7490", sortOrder: 22 },
];
export const DEMO_SEED_MEMOS_ZH = [
{
id: "memo_demo_overview",
notebookId: "nb_demo_features",
title: "🌟 欢迎使用 EdgeEver",
tags: ["overview", "features", "demo"],
title: "🌿 欢迎使用 EdgeEver:为极客与创作者打造的现代开源知识库",
tags: ["overview", "guide", "features", "ai-agent"],
isPinned: true,
markdown:
"## 🚀 开启您的 EdgeEver 笔记之旅\n\n> **EdgeEver** 是一款专为极客与创作者打造的现代开源 Serverless 个人知识库。它找回了经典的**印象笔记三栏式双视图布局**,以 Cloudflare 免费额度提供 **100% 免费**的自建云端,数据完全掌控,并原生集成 AI Agent (MCP) 接口。\n\n---\n\n### ⚡ 1. 核心产品特性对比\n\n*提示:在线模式下点击表格单元格可以直接修改文本;右键可快捷操作行列。*\n\n| 核心维度 | 传统云笔记 (如 Evernote) | 本地知识库 (如 Obsidian) | EdgeEver 极客笔记 |\n| :--- | :--- | :--- | :--- |\n| **云端托管成本** | 商业订阅高昂 ($10+/月) | 官方同步收费 ($5/月) | **100% 免费 (Cloudflare 免费额度)** |\n| **数据与隐私** | 封闭平台,导出受限 | 本地文件,同步需配置 | **完全掌控 (D1 SQLite 数据库 / R2 / WebDAV)** |\n| **编辑体验** | 富文本编辑 | 纯 Markdown | **双视图自由切换 (富文本 / Markdown 源码)** |\n| **多端支持** | 限制设备数量 | 移动端配置繁琐 | **Web / PWA / Android / macOS / iOS (审核中)** |\n| **创作者排版** | 无优化,格式易乱 | 需借助外部工具 | **微信公众号、Substack 一键富文本格式复制** |\n| **AI 原生集成** | 限制/仅特定付费版本 | 需繁琐的第三方插件 | **原生支持 MCP 协议与标准 OpenAPI** |\n\n---\n\n### 🎨 2. 沉浸式写作与排版美学\n\nEdgeEver 追求极致的创作体验,将设计美学融于字里行间:\n\n- **双视图编辑器**:点击右上角 `</>` 按钮,可在**所见即所得富文本**与 **Markdown 源码**间无缝切换,格式完全兼容。\n- **左侧可折叠大纲**:提供固定或折叠的大纲目录视图,支持点击标题平滑滚动定位,助您轻松掌控长文结构。\n- **8+ 款精致编辑器主题**:可在 **个人中心 / 设置** 中一键切换如 `WeChat Classic Green (微信经典绿)`、`Modern Mint (薄荷青)`、`minimal-emerald (极简祖母绿)` 等排版风格。\n- **自媒体一键排版复制**:专为创作者设计。点击右上角“复制到公众号”按钮,系统会自动将笔记转化为带行内样式的公众号美化格式,直接粘贴至微信公众号、Substack 或 WordPress 后台,排版与代码高亮完美保真。\n- **列表缩进与快捷操作**:支持快捷缩进列表,双击或选中文本可通过快捷键快速关联已有笔记。\n\n---\n\n### 📝 3. 模板中心与单篇导出\n\n- **可视化推荐模板库**:内置多种精美模板,点击即可弹窗预览。支持在当前笔记本中一键套用模板创建笔记,并支持一键返回列表。\n- **用户自定义模板**:您可以将常用笔记结构保存为自定义模板,实现效率翻倍。\n- **单篇便捷导出**:支持将当前笔记一键导出为标准的 `.md` Markdown 文件或排版优美的 `.pdf` 电子文档,便于独立归档与分发。\n\n---\n\n### 📊 4. 原生 Mermaid 动态图表渲染\n\n在代码块中使用 `mermaid` 标记,即可实时渲染高保真的动态逻辑图。支持多款**精致图表主题**选择,且微信复制时尺寸完美兼容:\n\n#### 1️⃣ 架构流程图 (Flowchart)\n```mermaid\nflowchart TD\n subgraph Client[\"📱 客户端生态\"]\n A[\"Web / PWA 浏览器\"]\n B[\"macOS / Android / iOS 客户端\"]\n end\n\n subgraph Backend[\"⚡ Cloudflare Serverless\"]\n C[\"Cloudflare Workers API\"]\n D[(\"D1 SQLite 数据库\")]\n E[(\"R2 资源存储\")]\n end\n\n A & B --> C\n C <--> D & E\n```\n\n#### 2️⃣ 交互时序图 (Sequence Diagram)\n```mermaid\nsequenceDiagram\n autonumber\n actor User as 用户\n participant App as 客户端 App\n participant Worker as Cloudflare Worker API\n participant D1 as D1 数据库\n\n User->>App: 编辑并保存笔记\n App->>Worker: POST /api/v1/memos (提交更改)\n Worker->>D1: 写入笔记 & 更新修订版本\n D1-->>Worker: 返回成功 (revision + 1)\n Worker-->>App: 200 OK (同步最新游标)\n App-->>User: 界面显示「已保存」\n```\n\n---\n\n### 📁 5. 多端覆盖、自动同步与剪藏\n\n- **全平台多端覆盖**:已发布 Web、Android 原生 App 以及 macOS 桌面端(支持 Apple Silicon 和 Intel Mac),iOS 客户端正在 App Store 审核中。\n- **网页裁剪器 (Web Clipper)**:已上架 Chrome, Edge 和 Firefox 插件商店,支持一键剪藏网页。\n- **微信文章一键剪藏**:在手机上直接将微信公众号文章分享至 EdgeEver App,系统将智能提取正文并保存为可编辑笔记。\n- **离线草稿与同步队列**:无网环境下自动保存本地,恢复连线后自动入队同步;支持在设置中灵活配置自动同步间隔。\n\n---\n\n### 🖼️ 6. 多媒体集成与图片前端压缩\n\n支持直接拖拽或粘贴插入图片与文件附件。本地浏览 Line truncated
`# <img src="/api/v1/resources/res_demo_logo/blob" alt="EdgeEver Logo" width="36" align="absmiddle" /> 欢迎使用 EdgeEver:为极客与创作者打造的现代开源知识库
> **EdgeEver** 是一款兼具**经典三栏美学**与 **AI 原生动力**的开源 Serverless / 容器化个人知识库。它既找回了极客们钟爱的经典印象笔记式双视图与树状目录,又以零服务器成本、完全数据自主、全端原生覆盖与深度 MCP 智能体协同,重新定义了下一代个人第二大脑。
---
## ⚡ 1. 为什么选择 EdgeEver?
*提示:在编辑器模式下,你可以直接点击任意表格单元格进行行内编辑,或右键快捷插入/删除行列。*
| 核心维度 | 传统商业云笔记 (如 Evernote) | 本地离线知识库 (如 Obsidian) | EdgeEver 极客知识库 |
| :--- | :--- | :--- | :--- |
| **云端托管成本** | 商业订阅高昂($10+/月) | 官方云同步收费($5+/月) | **100% 永久免费 (Cloudflare 免费额度 / Docker 自建)** |
| **数据资产所有权** | 专有格式封闭,导出困难 | 本地 Markdown,移动端同步繁琐 | **完全自主掌控 (D1 SQLite 数据库 / R2 / 无损 ZIP 导出)** |
| **写作与编辑体验** | 仅富文本,排版易错乱 | 纯 Markdown,缺乏沉浸所见即所得 | **双视图自由切换 (所见即所得富文本 ⇄ Markdown 源码)** |
| **自媒体排版分发** | 无样式优化,格式丢失 | 需借助外部排版扩展或工具 | **一键复制到微信公众号 / Substack / Medium / WordPress** |
| **社交卡片分享** | 截图粗糙或无排版设计 | 需第三方插件实现 | **内置 8 款精美海报主题,支持自定义字体与 PNG/JPEG 导出** |
| **AI 原生集成生态** | 封闭收费,仅限特定功能 | 需配置复杂的第三方插件 | **原生内置 MCP 服务端点 (\`/mcp\`) 与行内 AI 智能体协同** |
| **全平台多端覆盖** | 限制免费设备登录数量 | 多端同步与移动端体验门槛高 | **Web / PWA / Android / iOS / macOS / Windows (即将推出)** |
---
## 🏗️ 2. 全景架构与生态联动
通过下面的 Mermaid 架构图,你可以清晰了解 EdgeEver 如何将多端客户端、零成本云基础设施与 AI Agent 紧密串联:
\`\`\`mermaid
flowchart TD
subgraph MultiClients["全端客户端矩阵"]
C1["Web / PWA (离线草稿 & 增量同步)"]
C2["macOS 桌面端 (Electron + Rust Sidecar)"]
C3["Android 原生 App (Expo + SQLite)"]
C4["iOS 原生 App (SwiftUI + GRDB)"]
C5["浏览器剪藏插件 (Chrome / Edge / Firefox)"]
end
subgraph CoreEngine["业务与数据服务层"]
API["Hono API 引擎 (Cloudflare Workers / Docker)"]
MCP["原生 MCP Endpoint (/mcp 2026-07-28 & 2025)"]
D1[("D1 / SQLite 数据库 (双向同步 & 修订版本)")]
R2[("R2 / S3 资源存储 (图片与多媒体附件)")]
end
subgraph AIAgents["AI 智能体与外部生态"]
A1["Claude Code / Cursor / Antigravity"]
A2["行内 AI 助手 (OpenAI / Gemini / DeepSeek)"]
A3["Notion 数据库 / 飞书多维表格联动"]
end
MultiClients <==>|REST API & 同步游标| API
API <==> D1 & R2
MCP <==> D1 & R2
A1 <==>|MCP Tools / SSE| MCP
A2 -.->|BYOK 密钥直连| MultiClients
A1 -.->|双向数据同步| A3
\`\`\`
---
## 🎨 3. 极致创作体验与排版美学
EdgeEver 将高效与优雅融入每一处交互细节,助你专注于思考与表达:
### 🖥️ 双视图编辑器与沉浸模式
- **自由切换视图**:点击右上角 \`</>\` 按钮或使用快捷键,可在**所见即所得富文本**与 **Markdown 源码**间无缝切换,实时双向保真。
- **左侧可折叠大纲**:自动解析文档 \`H1-H3\` 标题层级,支持点击平滑滚动跳转,助你轻松把控万字长文。
- **Zen 专注模式**:按下 \`Cmd/Ctrl + Shift + F\`,隐藏所有侧边栏与干扰元素,进入纯粹写作心流。
- **阅读保护模式 (Reading Protection)**:日常翻阅或查阅笔记时,按下 \`Cmd/Ctrl + E\` 即可一键开启只读保护,锁定当前编辑状态,避免沉浸阅读时误触键盘或意外改动笔记内容;再次按下即可随手切回编辑。
### 🎭 精选排版主题与一键自媒体发布
- **内置排版主题**:支持一键切换 \`WeChat Classic Green (微信经典绿)\`、\`Modern Mint (薄荷青)\`、\`Minimal Emerald (极简祖母绿)\`、\`Outline Emerald (大纲祖母绿)\` 等风格。
- **一键排版复制**:专为内容创作者设计。点击顶部工具栏的**微信公众号图标**,系统自动将当前笔记转为内联 CSS 样式的优雅富文本,直接粘贴至微信公众号后台、Substack 或 WordPress,排版与代码高亮完美保真。
### 🖼️ 8 套精美社交分享海报 (Poster Cards)
点击右上角“分享为卡片”,即可将任意笔记或片段渲染为高清分享海报,支持:
- **8 大主题风格**:\`Slate (岩灰)\`、\`Aurora (极光青)\`、\`Sunset (落日暖橙)\`、\`Midnight (暗夜极客)\`、\`Mint (清爽薄荷)\`、\`Notepad (复古便签)\`、\`Xuan (宣纸水墨)\`、\`Lavender (薰衣草紫)\`。
- **排版定制**:支持无衬线 (Sans)、宋体/明朝 (Serif)、等宽代码 (Mono) 字体切换,自由选择紧凑、标准或宽幅卡片,一键导出为高清晰度 PNG 或 JPEG 图片。
---
## ⌨️ 4. 效率工具箱:斜杠指令、双链与数学公式
### 🪄 斜杠指令 (Slash Commands)
在正文空白行输入 \`/\` 或直接按下 \`空格键\`,即可呼出快捷指令菜单:
- 快速插入 \`H1/H2/H3\` 标题、引用、分割线、代码块与富文本表格;
- 输入 \`/date\`、\`/time\` 或 \`/now\` 快速插入当前标准时间戳;
- 插入附件、图片或调起行内 AI 智能助手。
### 🔗 知识双链与笔记引用
在编辑器中输入 \`@\` 或插入 \`#memo=<笔记ID>\` 链接,即可建立笔记间的双向关联,点击即可在工作区内快速打开关联笔记,构建结构化网状知识库。
### 📐 KaTeX 专业数学公式渲染
EdgeEver 原生支持 LaTeX 数学表达式,无论是行内微积分还是多行物理方程,均可毫秒级高保真渲染:
- **行内公式**:例如质能方程 $E = mc^2$,以及正态分布概率密度函数 $f(x) = \\frac{1}{\\sigma \\sqrt{2\\pi}} e^{-\\frac{(x-\\mu)^2}{2\\sigma^2}}$。
- **多行独立公式块**:
$$
\\oint_{\\partial \\Omega} \\mathbf{E} \\cdot d\\mathbf{S} = \\frac{1}{\\varepsilon_0} \\iiint_{\\Omega} \\rho \\, dV, \\quad \\oint_{\\partial \\Omega} \\mathbf{B} \\cdot d\\mathbf{S} = 0
$$
### ✅ 交互式待办清单 (Task Lists)
- [x] 体验 EdgeEver 双视图与大纲导航
- [x] 探索 8 款编辑器主题与 8 套社交海报卡片
- [ ] 尝试使用斜杠指令 \`/\` 插入当前日期与结构化表格
- [ ] 配置个人 AI API Key,体验行内智能总结与续写
- [ ] 开启 MCP 协议,让 AI Agent 协助整理工作区
---
## 🤖 5. AI 原生协同与 MCP 智能体生态
EdgeEver 走在 AI 时代前沿,将大语言模型与智能体深度融入知识管理生命周期:
\`\`\`mermaid
sequenceDiagram
autonumber
actor User as 创作者 / 知识工作者
participant Client as EdgeEver 多端应用
participant MCP as EdgeEver MCP 服务端点
participant Agent as AI Agent (Claude / Cursor / Antigravity)
participant Database as Notion / 飞书多维表格
User->>Client: 快速记录碎片想法与会议灵感
Agent->>MCP: tools/call memo_search (检索近期未整理笔记)
MCP-->>Agent: 返回结构化 Markdown 笔记内容与标签
Agent->>Agent: 理解内容、自动提炼核心摘要并归类标签
Agent->>MCP: tools/call memo_update (写回智能总结与增强标签)
Agent->>Database: 同步结构化字段至个人知识总库
Client-->>User: 客户端毫秒级感知更新,笔记井井有条
\`\`\`
### 1️⃣ 行内 AI 助手 (Inline AI Assistant)
在正文空白行直接按下 **\`空格键 (Space)\`**、输入 **\`/ai\`**、通过 **\`/\`** 斜杠指令菜单,或选中文本点击浮动工具栏中的 **AI 按钮**,即可即时呼出 AI 写作助手面板:
- **精炼总结与要点提取**:一键压缩提炼全文核心结论、提取待办事项与关键行动项;
- **格式保真智能翻译**:在严格保留原有 Markdown、数学公式、链接与代码块的前提下,精准翻译多国语言;
- **内容重塑与风格改写**:支持改进表达、修正错别字与语法、转为社交媒体(如小红书/推特)风格,或按上下文顺滑续写;
- **BYOK 隐私直连 (Bring Your Own Key)**:支持直连 OpenAI、Anthropic Claude、Google Gemini、DeepSeek 及各类 OpenAI 兼容的中继 API,数据完全由端侧直发,不经过任何第三方中转。
### 2️⃣ 开放 MCP 协议 (Model Context Protocol)
在**设置 → MCP 设置**中生成专属令牌,即可将 EdgeEver 接入 Claude Code、Cursor、Antigravity、OpenClaw 等主流 AI 编码助手与智能体平台:
- **无缝读写**:支持标准 MCP 端点 \`/mcp\`(兼容最新的无状态 \`2026-07-28\` 协议与经典握手协议);
- **自动化流转**:AI Agent 可自动读取笔记、智能归档、批量打标,甚至与 Notion、飞书多维表格建立跨平台自动化同步。
---
## 📱 6. 全平台原生覆盖、离线同步与智能剪藏
- **多端原生支持**:
- **Web / PWA**:支持现代浏览器全功能运行与离线安装;
- **Android 原生客户端**:基于 Expo 与 SQLite 构建,已上架 Google Play,并提供签名 APK 下载;
- **iOS 原生客户端**:基于 Swift / SwiftUI 与 GRDB 原生实现,流畅细腻,已上架 App Store;
- **macOS 桌面端**:Electron + Rust 高性能 Sidecar,支持 Apple Silicon 和 Intel Mac,内置静默后台更新;
- **Windows 桌面端**:已开发完毕,即将正式推出。
- **浏览器网页剪藏 (Web Clipper)**:已在 Chrome、Edge 和 Firefox 官方扩展商店发布,一键剔除网页广告,将正文纯净沉淀为 Markdown 笔记。
- **微信公众号一键剪藏**:在移动端系统分享菜单中,直接将微信文章分享到 EdgeEver,客户端将自动提取图文排版并转换为可编辑笔记。
- **离线草稿与弹性同步**:地铁、飞行模式等无网络环境下自由编辑,重新联网后自动入队完成增量同步与冲突协调。
---
## 📦 7. 多媒体管理、无损备份与零成本自建
### 🖼️ 智能本地图片压缩
在笔记中粘贴或拖入高分辨率图片时,前端会在本地自动将其转码压缩为 WebP 格式,在保证视觉无损的前提下**减少 50% - 90% 的体积**,大幅降低云端存储占用并提升跨端加载速度。
![EdgeEver 极客猫猫吉祥物](/api/v1/resources/res_demo_cat_image/blob)
### 📎 多类型附件自由挂载
支持在笔记中嵌入 PDF 文档、CSV 表格、压缩包及多媒体资源,点击即可在线预览或下载:
- [📄 产品白皮书 PDF:edgeever-product-brief.pdf](/api/v1/resources/res_demo_product_brief_pdf/blob)
- [📊 功能矩阵 CSV:feature-matrix.csv](/api/v1/resources/res_demo_feature_matrix_csv/blob)
- [📦 示例附件压缩包:edgeever-attachment-demo.zip](/api/v1/resources/res_demo_attachment_bundle_zip/blob)
### 🚀 两种自建部署方案:Serverless 与 Docker
1. **Cloudflare Serverless(推荐,永久 100% 免费)**:基于 Workers + D1 数据库 + R2 对象存储构建,完全处于 Cloudflare 免费额度内,无需采购服务器,免运维、免证书续期。
2. **Docker 一键自建(VPS / NAS / 家用服务器)**:
\`\`\`sh
# 国际 VPS / NAS 极速安装(GHCR 镜像)
curl -fsSL https://edgeever.org/install.sh | bash
# 大陆地区 VPS / NAS 镜像加速(腾讯云 TCR 镜像)
curl -fsSL https://edgeever-installer-1256854452.cos.ap-guangzhou.myqcloud.com/install.sh | bash -s -- --mirror tcr
\`\`\`
单命令自动配置 Docker Compose 环境,并内置每日定时自动更新。
### 💾 绝对的数据自由:无损 ZIP 导入与导出
在**个人中心 → 导入与导出**中,可随时将完整笔记库打包导出为结构清晰的 ZIP 压缩包。解压后即为包含标准 YAML Front Matter、相对路径附件图片与完整修订版本的纯 Markdown 文件树,随时可在 Obsidian、VS Code 等任意工具中无缝打开,永不担心平台绑定!
---
> 💡 **快速体验小贴士**:
> 1. 点击右上角 **\`</>\`** 体验丝滑的双视图切换;
> 2. 按下 **\`Cmd/Ctrl + E\`** 试一试阅读保护模式,锁定只读避免误改内容;
> 3. 按下 **\`Cmd/Ctrl + O\`** 呼出快速切换器 (Quick Switcher);
> 4. 点击顶部 **微信图标**,体验一键带格式排版复制;
> 5. 点击 **“分享为卡片”**,挑选一款你心仪的社交海报风格并导出;
> 6. 随时在侧边栏或设置中点击 **“恢复 Demo 数据”**,一键重置演示工作区。
`,
},
];
export const DEMO_SEED_REVISIONS = [
{
id: "rev_demo_revision_1",
memoId: "memo_demo_overview",
revision: 1,
title: "🌟 欢迎使用 EdgeEver",
title: "🌿 欢迎使用 EdgeEver:为极客与创作者打造的现代开源知识库",
markdown:
"## 🌟 欢迎使用 EdgeEver(草稿)\n\n- 印象笔记经典三栏与自建 Serverless\n- 可视化表格与 Markdown 源码双向切换",
"## 🌿 欢迎使用 EdgeEver(初版草稿)\n\n- 印象笔记经典三栏与自建 Serverless\n- 可视化表格与 Markdown 源码双向切换\n- 原生 MCP 与 AI 智能体协同",
},
{
id: "rev_demo_revision_1_en",
memoId: "memo_demo_overview_en",
revision: 1,
title: "🌟 Welcome to EdgeEver",
title: "🌿 Welcome to EdgeEver: Modern Open-Source Knowledge Base for Geeks & Creators",
markdown:
"## 🌟 Welcome to EdgeEver (Draft)\n\n- Classic Evernote 3-pane layout & Serverless self-hosted\n- Visual table editing & Markdown source toggle",
"## 🌿 Welcome to EdgeEver (Initial Draft)\n\n- Classic Evernote 3-pane layout & Serverless self-hosted\n- Visual table editing & Markdown source toggle\n- Native MCP & AI agent synergy",
},
];
export const DEMO_MEMO_ENGLISH = {
memo_demo_overview: {
title: "🌟 Welcome to EdgeEver",
title: "🌿 Welcome to EdgeEver: Modern Open-Source Knowledge Base for Geeks & Creators",
markdown:
"## 🚀 Get Started with EdgeEver: The Geek's Knowledge Base\n\n> **EdgeEver** is a modern, open-source, serverless personal knowledge base built for geeks and creators. It restores the classic **Evernote-style three-pane layout**, while offering **100% free hosting** using Cloudflare's free tier, full data ownership, dual-view editing, and native AI Agent (MCP) integration.\n\n---\n\n### ⚡ 1. Feature Comparison\n\n*Tip: Click any cell in the table below to edit directly; right-click in editor mode to insert/delete rows or columns.*\n\n| Metric | Traditional Cloud Notes (e.g. Evernote) | Local Offline Notes (e.g. Obsidian) | EdgeEver Notes |\n| :--- | :--- | :--- | :--- |\n| **Hosting Cost** | High monthly fee ($10+/mo) | Official sync fee ($5/mo) | **100% Free (Cloudflare Free Tier)** |\n| **Data & Privacy** | Closed platform, locked export | Local files, sync needs setup | **Full Ownership (D1 SQLite, R2, WebDAV)** |\n| **Editing Mode** | Rich Text | Pure Markdown | **Seamless Dual-View Toggle (Rich Text / MD)** |\n| **Device Sync** | Limits active devices | Complicated mobile setup | **Web / PWA / Android / macOS / iOS (In Review)** |\n| **For Creators** | No formatting optimizations | Requires 3rd-party tools | **One-Click Rich Copy for WeChat & Substack** |\n| **AI Integration**| Paid/Limited versions only | Requires heavy plugin config | **Native MCP Protocol & Standard OpenAPI** |\n\n---\n\n### 🎨 2. Immersive Writing & Typography Aesthetics\n\nEdgeEver is crafted to provide a distraction-free and beautiful writing experience:\n\n- **Seamless Dual-View Editor**: Click the `</>` button in the top right to switch effortlessly between **WYSIWYG Rich Text** and **Markdown Source Code** with 100% compatibility.\n- **Collapsible Outline View**: Enjoy a fixed or collapsible sidebar outline of your document headings. Click any heading to navigate smoothly.\n- **8+ Exquisite Editor Themes**: Change your writing vibe instantly in **User Settings / Profile** with preset themes such as `WeChat Classic Green`, `Modern Mint`, `minimal-emerald`, and more.\n- **One-Click Publishing Export**: Built for publishers. Click \"Copy for WeChat / Publishing\" to automatically format your note with inline CSS. Paste it directly into WeChat, Substack, Medium, or WordPress editor while preserving layout and syntax highlighting.\n- **List Indentation & Quick Link**: Use quick keys for list indents, and double-click or select text to quickly link to existing notes with shortcut hints.\n\n---\n\n### 📝 3. Template Center & Single-Note Export\n\n- **Visual Template Library**: Access a curated collection of note templates with live modal preview cards. Instantly create notes using a template and jump back with one click.\n- **Custom Templates**: Save your frequent note structures as custom templates to double your productivity.\n- **Flexible File Export**: Export the current note as a standard `.md` Markdown file or a beautifully styled `.pdf` document for offline archival and sharing.\n\n---\n\n### 📊 4. Native Mermaid Diagram Rendering\n\nUse standard `mermaid` fenced code blocks to render beautiful diagrams in real time, with support for **selectable diagram themes** and dimension-preserved copying:\n\n#### 1️⃣ System Flowchart\n```mermaid\nflowchart TD\n subgraph Client[\"📱 Clients Ecosystem\"]\n A[\"Web / PWA\"]\n B[\"macOS / Android / iOS Apps\"]\n end\n\n subgraph Backend[\"⚡ Cloudflare Serverless\"]\n C[\"Cloudflare Workers API\"]\n D[(\"D1 SQLite DB\")]\n E[(\"R2 Object Storage\")]\n end\n\n A & B --> C\n C <--> D & E\n```\n\n#### 2️⃣ Interactive Sequence Diagram\n```mermaid\nsequenceDiagram\n autonumber\n actor User as User\n participant App as EdgeEver Client\n participant Worker as Cloudflare Worker API\n participant D1 as D1 Database\n\n User->>App: Edit and save note\n App->>Worker: POST /api/v1/memos (Save changes)\n Worker->>D1: Write note content & update revision\n D1-->>Worker: Return success (revision + 1)\n Worker-->>App: 200 OK (Latest sync cursor)\n App-->>User: Status updated to \"Saved\"\n```\n\n---\n\n### 📁 5. Multi-Device Sync, Offline Queue & Clipping\n\n- **Everywhere You Need It**: Native clients are available for Web, Android, and macOS (Intel & Apple Silicon), with the iOS client under App Store review.\n- **Web Clipper**: Available on Chrome, Edge, and Firefox Add-ons stores to save webpage contents with one click.\n- **Mobile WeChat Clipper**: Share any WeChat article to EdgeEver on your phone, and it automatically extracts the article content as an editable note.\n- **Offline Sync & Queue**: Keep writing even without network. Your edits are queued locally and synchronized automatically when connection resumes. Customize sync intervals in settings.\n\n---\n\n### 🖼️ 6. Rich Media & Smart Image Compression\n\nDrag-and-drop or paste images directly into your editor. EdgeEver compr Line truncated
`# <img src="/api/v1/resources/res_demo_logo/blob" alt="EdgeEver Logo" width="36" align="absmiddle" /> Welcome to EdgeEver: Modern Open-Source Knowledge Base for Geeks & Creators
> **EdgeEver** is an open-source, AI-native, and portable serverless/containerized personal knowledge base that revives the beloved **Evernote-style three-pane layout**. Designed for geeks and content creators, it combines 100% free serverless hosting, absolute data ownership, native cross-platform clients, and seamless AI Agent (MCP) synergy to redefine your digital second brain.
---
## ⚡ 1. Why Choose EdgeEver?
*Tip: In editor mode, click any table cell to edit text directly, or right-click to insert/delete rows and columns.*
| Dimension | Traditional Cloud Notes (e.g. Evernote) | Local Offline Notes (e.g. Obsidian) | EdgeEver Geek Knowledge Base |
| :--- | :--- | :--- | :--- |
| **Hosting Cost** | Costly commercial subscriptions ($10+/mo) | Official cloud sync subscription ($5+/mo) | **100% Free Forever (Cloudflare Free Tier / Docker Self-Hosted)** |
| **Data Ownership** | Proprietary lock-in, hard to export | Local Markdown, cumbersome mobile sync | **Full Ownership (D1 SQLite, R2 Storage, Lossless ZIP Archives)** |
| **Editing Experience** | Rich text only, fragile formatting | Plain Markdown, lacks WYSIWYG flow | **Seamless Dual-View (WYSIWYG Rich Text ⇄ Markdown Source)** |
| **Publishing Ready** | No typography styling, loses format | Requires 3rd-party plugins or scripts | **One-Click Rich Copy for WeChat, Substack, Medium & WordPress** |
| **Social Poster Cards** | Basic screenshots without styling | Requires external tools or plugins | **8 Built-in Exquisite Poster Themes with Typography Options & PNG/JPEG Export** |
| **Native AI Ecosystem** | Paywalled, limited features | Heavy plugin setup required | **Native MCP Server (\`/mcp\`) & Inline AI Agent Synergy** |
| **Cross-Platform Matrix** | Restricts active free devices | Complex setup across platforms | **Web / PWA / Android / iOS / macOS / Windows (Coming Soon)** |
---
## 🏗️ 2. Architectural Overview & Ecosystem
The Mermaid diagram below demonstrates how EdgeEver connects cross-platform clients, zero-cost cloud infrastructure, and AI Agents into a cohesive workflow:
\`\`\`mermaid
flowchart TD
subgraph MultiClients["Client Matrix"]
C1["Web / PWA (Offline Drafts & Sync Queue)"]
C2["macOS Desktop (Electron + Rust Sidecar)"]
C3["Android Native App (Expo + SQLite)"]
C4["iOS Native App (SwiftUI + GRDB)"]
C5["Web Clipper (Chrome / Edge / Firefox)"]
end
subgraph CoreEngine["Service & Storage Core"]
API["Hono API Engine (Cloudflare Workers / Docker)"]
MCP["Native MCP Endpoint (/mcp 2026-07-28 & 2025)"]
D1[("D1 / SQLite Database (Sync Cursor & Revisions)")]
R2[("R2 / S3 Storage (Images & Media Attachments)")]
end
subgraph AIAgents["AI Agents & Integrations"]
A1["Claude Code / Cursor / Antigravity"]
A2["Inline AI Assistant (OpenAI / Gemini / DeepSeek)"]
A3["Notion DB / Feishu Bitable Sync"]
end
MultiClients <==>|REST API & Sync Cursor| API
API <==> D1 & R2
MCP <==> D1 & R2
A1 <==>|MCP Tools / SSE| MCP
A2 -.->|BYOK Direct Key| MultiClients
A1 -.->|Bi-directional Sync| A3
\`\`\`
---
## 🎨 3. Immersive Writing & Typography Aesthetics
EdgeEver is engineered to provide a distraction-free, elegant writing experience:
### 🖥️ Dual-View Editor & Focus Modes
- **Seamless Dual-View**: Click the \`</>\` button in the top-right corner (or use shortcuts) to instantly toggle between **WYSIWYG Rich Text** and **Markdown Source Code** with 100% fidelity.
- **Collapsible Outline Navigation**: Automatically indexes \`H1-H3\` heading hierarchies with smooth jump scrolling, keeping lengthy documents organized.
- **Zen Focus Mode**: Press \`Cmd/Ctrl + Shift + F\` to hide sidebars and distractions, immersing yourself in pure writing flow.
- **Reading Protection Mode**: When reading or reviewing notes, press \`Cmd/Ctrl + E\` to toggle read-only protection, locking the editor to prevent accidental edits while browsing; press it again to seamlessly resume editing.
### 🎭 Curated Typography Themes & Publishing Export
- **Preset Editor Themes**: Switch effortlessly between \`WeChat Classic Green\`, \`Modern Mint\`, \`Minimal Emerald\`, \`Outline Emerald\`, and more.
- **One-Click Publishing Export**: Built for publishers and bloggers. Click the **WeChat Icon** in the top bar to format your note with inline CSS. Paste directly into WeChat Official Account editor, Substack, Medium, or WordPress while preserving layout and syntax highlighting.
### 🖼️ 8 Exquisite Social Poster Themes
Click **"Share as Card"** in the top-right menu to turn any note into an eye-catching poster card:
- **8 Themes**: \`Slate\`, \`Aurora\`, \`Sunset\`, \`Midnight\`, \`Mint\`, \`Notepad\` (skeuomorphic paper), \`Xuan\` (rice paper & Chinese ink), \`Lavender\`.
- **Customizable Typography**: Switch between Sans, Serif (Songti/Ming), and Monospace fonts, select compact, standard, or wide card widths, and export as high-resolution PNG or JPEG.
---
## ⌨️ 4. Power Productivity Toolbox: Slash Commands, Backlinks & Math
### 🪄 Slash Commands
Type \`/\` or press \`Space\` on an empty line to invoke the command menu:
- Insert \`H1/H2/H3\` headings, quotes, horizontal rules, code blocks, and rich tables;
- Use \`/date\`, \`/time\`, or \`/now\` to insert current timestamps instantly;
- Attach files, insert images, or summon the inline AI assistant.
### 🔗 Bi-directional Note Links & Backlinks
Type \`@\` or insert \`#memo=<memoId>\` links to establish bi-directional references across your knowledge base, building an interconnected web of thoughts.
### 📐 KaTeX Professional LaTeX Mathematics
Native support for KaTeX renders complex mathematical equations in milliseconds:
- **Inline Math**: For instance, Einstein's mass-energy equivalence $E = mc^2$ or the Gaussian probability density function $f(x) = \\frac{1}{\\sigma \\sqrt{2\\pi}} e^{-\\frac{(x-\\mu)^2}{2\\sigma^2}}$.
- **Display Block Math**:
$$
\\oint_{\\partial \\Omega} \\mathbf{E} \\cdot d\\mathbf{S} = \\frac{1}{\\varepsilon_0} \\iiint_{\\Omega} \\rho \\, dV, \\quad \\oint_{\\partial \\Omega} \\mathbf{B} \\cdot d\\mathbf{S} = 0
$$
### ✅ Interactive Task Lists
- [x] Explore EdgeEver's dual-view editing and outline navigation
- [x] Experiment with 8 editor themes and 8 social poster card styles
- [ ] Try typing \`/\` on an empty line to insert current timestamp and tables
- [ ] Connect your AI API Key to experience inline summarization and continuation
- [ ] Connect AI Agents via MCP to automate note categorization
---
## 🤖 5. Native AI Agent Synergy & MCP Protocol
EdgeEver is architected for the agentic AI era, weaving LLMs directly into the knowledge management lifecycle:
\`\`\`mermaid
sequenceDiagram
autonumber
actor User as Creator / Knowledge Worker
participant Client as EdgeEver Clients
participant MCP as EdgeEver MCP Endpoint
participant Agent as AI Agent (Claude / Cursor / Antigravity)
participant Database as Notion / Feishu Bitable
User->>Client: Capture quick spark or meeting notes
Agent->>MCP: tools/call memo_search (Query unprocessed memos)
MCP-->>Agent: Returns structured Markdown & tags
Agent->>Agent: Analyzes content, extracts key takeaways & tags
Agent->>MCP: tools/call memo_update (Writes back summary & tags)
Agent->>Database: Syncs structured records to master database
Client-->>User: Sub-second live updates in client UI
\`\`\`
### 1️⃣ Inline AI Assistant
Press the **\`Space\` bar** in an empty block, type **\`/ai\`**, use the **\`/\`** slash command menu, or select text and click the **AI button** on the floating toolbar to instantly summon the AI writing assistant:
- **Summarization & Action Items**: Condense documents into key takeaways, conclusions, and actionable todos;
- **Format-Preserving Translation**: Translate accurately into multiple languages while strictly preserving Markdown, math equations, links, and code blocks;
- **Rewriting & Style Transformation**: Improve phrasing, fix spelling/grammar, adapt to social media styles (e.g. Xiaohongshu / Twitter), or continue writing seamlessly;
- **BYOK Direct Key (Bring Your Own Key)**: Direct client-side connection with OpenAI, Anthropic Claude, Google Gemini, DeepSeek, and OpenAI-compatible relays with zero third-party data transit.
### 2️⃣ Model Context Protocol (MCP) Integration
Generate an API token in **Settings → MCP Settings** to connect EdgeEver directly with Claude Code, Cursor, Antigravity, OpenClaw, and other agent platforms:
- **Direct Reading & Writing**: Connect via the \`/mcp\` endpoint (supports stateless \`2026-07-28\` protocol and handshake-based 2025 specs);
- **Automated Workflows**: Let AI Agents read, organize, summarize, tag, and synchronize notes with Notion databases and Feishu Bitable.
---
## 📱 6. Multi-Platform Ecosystem, Offline Sync & Smart Clipping
- **Cross-Platform Native Apps**:
- **Web / PWA**: Full-featured in modern browsers with offline installation support;
- **Android Native App**: Built with Expo & SQLite, available on Google Play and GitHub Releases;
- **iOS Native App**: Native Swift / SwiftUI with GRDB local mirror, available on the App Store;
- **macOS Desktop App**: Electron + Rust Sidecar for Apple Silicon & Intel Mac with silent background updates;
- **Windows Desktop App**: Development is complete, coming soon.
- **Browser Web Clipper**: Available on Chrome, Edge, and Firefox extension stores to extract clean, ad-free Markdown articles in one click.
- **Mobile WeChat Article Clipper**: Share any WeChat article to EdgeEver on your phone to automatically extract and format it as an editable note.
- **Offline Drafts & Sync Queue**: Keep writing seamlessly without network connectivity; changes are queued locally and automatically synced once reconnected.
---
## 📦 7. Rich Media, Lossless Portability & Zero-Cost Hosting
### 🖼️ Smart Client-Side Image Compression
When pasting or dragging images into notes, EdgeEver compresses them to WebP locally in your browser before upload, **reducing file size by 50% - 90%** while preserving visual fidelity.
![EdgeEver Mascot: Geek Cat](/api/v1/resources/res_demo_cat_image/blob)
### 📎 Universal File Attachments
Embed PDFs, spreadsheets, archives, and multimedia files directly in notes for preview or download:
- [📄 Product brief PDF: edgeever-product-brief.pdf](/api/v1/resources/res_demo_product_brief_pdf/blob)
- [📊 Feature matrix CSV: feature-matrix.csv](/api/v1/resources/res_demo_feature_matrix_csv/blob)
- [📦 Sample attachment archive: edgeever-attachment-demo.zip](/api/v1/resources/res_demo_attachment_bundle_zip/blob)
### 🚀 Zero-Cost Serverless & Docker Self-Hosting
1. **Cloudflare Serverless (Recommended, 100% Free Forever)**: Runs entirely within Cloudflare's free tier (Workers + D1 SQLite + R2 Storage). No server bills, no VPS maintenance.
2. **Docker One-Command Deployment (VPS / NAS / Home Server)**:
\`\`\`sh
# International VPS / NAS installer (GHCR image)
curl -fsSL https://edgeever.org/install.sh | bash
# Mainland China mirror installer (Tencent TCR image)
curl -fsSL https://edgeever-installer-1256854452.cos.ap-guangzhou.myqcloud.com/install.sh | bash -s -- --mirror tcr
\`\`\`
Configures Docker Compose and automated daily background updates with one command.
### 💾 Complete Data Freedom: Lossless ZIP Portability
Export your entire library at any time from **Profile → Import and export**. The archive contains pure Markdown files with standard YAML Front Matter, relative media paths, and full revision histories—compatible with Obsidian, VS Code, and any plain text editor.
---
> 💡 **Quick Exploration Tips**:
> 1. Click **\`</>\`** in the top right to try seamless dual-view toggling;
> 2. Press **\`Cmd/Ctrl + E\`** to test reading protection mode against accidental edits;
> 3. Press **\`Cmd/Ctrl + O\`** to summon the Quick Switcher;
> 4. Click the **WeChat Icon** to copy formatted rich text ready for publishing;
> 5. Click **"Share as Card"** to export a stunning social poster card;
> 6. Click **"Reset Demo Data"** in settings or the sidebar anytime to restore the demo workspace.
`,
},
} as const;
export const DEMO_SEED_MEMOS_EN = DEMO_SEED_MEMOS_ZH.map((memo) => {
const english = DEMO_MEMO_ENGLISH[memo.id as keyof typeof DEMO_MEMO_ENGLISH];
if (!english) {
@@ -66,12 +462,25 @@ export const DEMO_SEED_MEMOS_EN = DEMO_SEED_MEMOS_ZH.map((memo) => {
markdown: `${english.markdown}${DEMO_ATTACHMENT_MARKDOWN_EN}`,
};
}).filter((memo): memo is NonNullable<typeof memo> => memo !== null);
export const DEMO_SEED_MEMOS_ZH_WITH_ATTACHMENTS = DEMO_SEED_MEMOS_ZH.map((memo) => ({
...memo,
markdown: `${memo.markdown}${DEMO_ATTACHMENT_MARKDOWN_ZH}`,
}));
export const DEMO_SEED_MEMOS = [...DEMO_SEED_MEMOS_ZH_WITH_ATTACHMENTS, ...DEMO_SEED_MEMOS_EN];
export const DEMO_SEED_RESOURCES = [
{
id: "res_demo_logo",
memoId: "memo_demo_overview",
filename: "edgeever-icon.svg",
mimeType: "image/svg+xml",
width: 1024,
height: 1024,
svg:
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024" role="img" aria-labelledby="title desc"><title id="title">EdgeEver</title><desc id="desc">An open cat face in near-black on the EdgeEver green rounded tile.</desc><rect x="100" y="100" width="824" height="824" rx="188" fill="#16a06e" /><g transform="translate(100 100) scale(0.74234234) translate(-72 -72)"><path fill="#07130b" fill-rule="evenodd" d="M253.5 707.5Q249 678 249.5 655Q250 632 253.5 611.5Q257 591 264.5 568.5Q272 546 281 530Q290 514 287 485Q284 456 283.5 417Q283 378 285 351.5Q287 325 292 299Q297 273 304.5 254.5Q312 236 318.5 227.5Q325 219 336 213Q347 207 358.5 207.5Q370 208 383 213.5Q396 219 407 226.5Q418 234 428 242.5Q438 251 455 268.5Q472 286 485.5 303.5Q499 321 510.5 339Q522 357 528 368.5Q534 380 534 385.5Q534 391 532.5 394.5Q531 398 527.5 401Q524 404 518 405Q512 406 507 404Q502 402 499.5 399.5Q497 397 491.5 386Q486 375 474 357Q462 339 450.5 324.5Q439 310 426 296.5Q413 283 400.5 272.5Q388 262 377 255.5Q366 249 361 248Q356 247 352.5 249.5Q349 252 344.5 261Q340 270 337 280Q334 290 329 325.5Q324 361 323.5 400Q323 439 327 479.5Q331 520 321 538Q311 556 306 568.5Q301 581 297 596Q293 611 291 624.5Q289 638 289 661Q289 684 292 702Q295 720 301 739.5Q307 759 315.5 776.5Q324 794 335 810Q346 826 358 838.5Q370 851 386.5 863.5Q403 876 419.5 884.5Q436 893 456 899.5Q476 906 501 909.5Q526 913 529.5 916Q533 919 534.5 922Q536 925 536 931.5Q536 938 532.5 943Q529 948 524 950Q519 952 505.5 951Q492 950 473 946Q454 942 426 931Q398 920 385.5 912.5Q373 905 359.5 894.5Q346 884 333.5 871.5Q321 859 313 849Q305 839 291 815Q277 791 267.5 764Q258 737 253.5 707.5ZM719 941.5Q716 936 717 929Q718 922 721 918.5Q724 915 727 913.5Q730 912 749 910Q768 908 785 903.5Q802 899 823 889.5Q844 880 860.5 868.5Q877 857 887.5 847Q898 837 911 820Q924 803 932 788.5Q940 774 947.5 753.5Q955 733 959.5 708Q964 683 964 660.5Q964 638 960.5 617.5Q957 597 952.5 582.5Q948 568 943.5 558Q939 548 931 535Q923 522 927 479Q931 436 930.5 400Q930 364 925.5 329Q921 294 917 280Q913 266 909 258.5Q905 251 902 249Q899 247 893 248.5Q887 250 867.5 264Q848 278 835.5 290.5Q823 303 810.5 318Q798 333 783.5 354Q769 375 762 387.5Q755 400 751 402.5Q747 405 742 405.5Q737 406 732 404Q727 402 723.5 397Q720 392 720.5 385Q721 378 736.5 353Q752 328 768 307.5Q784 287 803.5 267Q823 247 834 238Q845 229 858.5 221Q872 213 881 210Q890 207 899.5 207Q909 207 918.5 212Q928 217 935.5 226.5Q943 236 949.5 252Q956 268 960 286Q964 304 967.5 344.5Q971 385 970.5 418Q970 451 967 482.5Q964 514 972 528Q980 542 986 558Q992 574 996 591Q1000 608 1002 624.5Q1004 641 1003.5 667Q1003 693 998 719.5Q993 746 985 768Q977 790 964.5 812Q952 834 940 849Q928 864 915.5 876Q903 888 892.5 896Q882 904 858 917Q834 930 820 935Q806 940 789.5 944Q773 948 753 950Q733 952 727.5 949.5Q722 947 719 941.5ZM378.5 728Q373 718 373 714.5Q373 711 375.5 708Q378 705 387 699Q396 693 405 689Q414 685 426 682.5Q438 680 447.5 680Q457 680 467.5 682Q478 684 490 690Q502 696 512.5 706.5Q523 717 530.5 733Q538 749 539.5 762Q541 775 537 778Q533 781 515.5 784Q498 787 481 786.5Q464 786 451 783Q438 780 428.5 775.5Q419 771 412 766Q405 761 394.5 749.5Q384 738 378.5 728ZM713.5 778Q710 775 710.5 767Q711 759 714 749Q717 739 723.5 727.5Q730 716 740.5 706Q751 696 762 690.5Q773 685 785.5 682.5Q798 680 813 681Q828 682 843.5 688Q859 694 869.5 702.5Q880 711 880 714.5Q880 718 871.5 732Q863 746 853 755.5Q843 765 830.5 772Q818 779 804 782.5Q790 786 772.5 786.5Q755 787 736 784Q717 781 713.5 778ZM406 710Q395 716 398 722.5Q401 729 410 738.5Q419 748 427 753Q435 758 441 760Q447 762 444.5 749.5Q442 737 442.5 726.5Q443 716 445 707.5Q447 699 432 701.5Q417 704 406 710ZM819.5 701Q806 699 808 708.5Q810 718 810 730.5Q810 743 808 750.5Q806 758 806 760Q806 762 807 762Q808 762 815 759Q822 756 830.5 750Q839 744 846 736Q853 728 855.5 722Q858 716 845.5 709.5Q833 703 819.5 701ZM471 759.5Q469 763 469 765Q469 767 472 767.5Q475 768 488.5 768Q502 768 512 766Q522 764 519.5 754Q517 744 511 734Q505 724 498.5 718Q492 712 484.5 708Q477 704 475.5 704Q474 704 475 723Q476 742 474.5 749Q473 756 471 759.5ZM733 750.5Q730 759 730 761.5Q730 764 737 765.5Q744 767 763.5 767Q783 767 779.5 752Q776 737 776 730.5Q776 724 778 714Q780 704 770.5 708Q761 712 753 719.5Q745 727 740.5 734.5Q736 742 733 750.5ZM592.5 848.5Q588 841 588 836.5Q588 832 590 829Q592 826 599.5 822.5Q607 819 613.5 818Q620 817 626.5 817Q633 817 642.5 819Q652 821 655 822.5Q658 824 661.5 828.5Q665 833 664.5 838Q664 843 659.5 850Q655 857 645 867Q635 877 631.5 878.5Q628 880 625 879.5Q622 879 617.5 876Q613 873 605 864.5Q597 856 592.5 848.5Z" />\n </g>\n</svg>',
},
{
id: "res_demo_cat_image",
memoId: "memo_demo_overview",
@@ -80,8 +489,10 @@ export const DEMO_SEED_RESOURCES = [
width: 960,
height: 540,
svg:
'<svg xmlns="http://www.w3.org/2000/svg" width="960" height="540" viewBox="0 0 960 540" fill="none"><rect width="960" height="540" rx="32" fill="#f0fdfa"/><g transform="translate(480, 270) scale(2.2)"><path d="M-60,-20 C-60,-60 -30,-80 0,-80 C30,-80 60,-60 60,-20 C60,20 40,40 0,40 C-40,40 -60,20 -60,-20 Z" stroke="#0f766e" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" fill="none"/><path d="M-45,-68 L-55,-100 L-20,-78" stroke="#0f766e" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" fill="none"/><path d="M45,-68 L55,-100 L20,-78" stroke="#0f766e" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" fill="none"/><path d="M-30,-25 Q-20,-15 -10,-25" stroke="#0f766e" stroke-width="5" stroke-linecap="round" fill="none"/><path d="M10,-25 Q20,-15 30,-25" stroke="#0f766e" stroke-width="5" stroke-linecap="round" fill="none"/><path d="M-5,-10 L5,-10 L0,-5 Z" fill="#0f766e"/><path d="M0,-5 Q-5,5 -10,2 M0,-5 Q5,5 10,2" stroke="#0f766e" stroke-width="4" stroke-linecap="round" fill="none"/><path d="M-40,-5 L-65,-8" stroke="#0f766e" stroke-width="4" stroke-linecap="round"/><path d="M-42,5 L-68,7" stroke="#0f766e" stroke-width="4" stroke-linecap="round"/><path d="M40,-5 L65,-8" stroke="#0f766e" stroke-width="4" stroke-linecap="round"/><path d="M42,5 L68,7" stroke="#0f766e" stroke-width="4" stroke-linecap="round"/><path d="M-30,35 C-30,70 -10,90 0,90 C10,90 30,70 30,35" stroke="#0f766e" stroke-width="6" stroke-linecap="round" fill="none"/><path d="M25,75 C45,75 55,60 55,45 C55,30 45,25 40,30 C35,35 40,45 45,45" stroke="#0f766e" stroke-width="6" stroke-linecap="round" fill="none"/></g></svg>'},
'<svg xmlns="http://www.w3.org/2000/svg" width="960" height="540" viewBox="0 0 960 540" fill="none"><rect width="960" height="540" rx="32" fill="#f0fdfa"/><g transform="translate(480, 270) scale(2.2)"><path d="M-60,-20 C-60,-60 -30,-80 0,-80 C30,-80 60,-60 60,-20 C60,20 40,40 0,40 C-40,40 -60,20 -60,-20 Z" stroke="#0f766e" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" fill="none"/><path d="M-45,-68 L-55,-100 L-20,-78" stroke="#0f766e" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" fill="none"/><path d="M45,-68 L55,-100 L20,-78" stroke="#0f766e" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" fill="none"/><path d="M-30,-25 Q-20,-15 -10,-25" stroke="#0f766e" stroke-width="5" stroke-linecap="round" fill="none"/><path d="M10,-25 Q20,-15 30,-25" stroke="#0f766e" stroke-width="5" stroke-linecap="round" fill="none"/><path d="M-5,-10 L5,-10 L0,-5 Z" fill="#0f766e"/><path d="M0,-5 Q-5,5 -10,2 M0,-5 Q5,5 10,2" stroke="#0f766e" stroke-width="4" stroke-linecap="round" fill="none"/><path d="M-40,-5 L-65,-8" stroke="#0f766e" stroke-width="4" stroke-linecap="round"/><path d="M-42,5 L-68,7" stroke="#0f766e" stroke-width="4" stroke-linecap="round"/><path d="M40,-5 L65,-8" stroke="#0f766e" stroke-width="4" stroke-linecap="round"/><path d="M42,5 L68,7" stroke="#0f766e" stroke-width="4" stroke-linecap="round"/><path d="M-30,35 C-30,70 -10,90 0,90 C10,90 30,70 30,35" stroke="#0f766e" stroke-width="6" stroke-linecap="round" fill="none"/><path d="M25,75 C45,75 55,60 55,45 C55,30 45,25 40,30 C35,35 40,45 45,45" stroke="#0f766e" stroke-width="6" stroke-linecap="round" fill="none"/></g></svg>',
},
] as const;
export const DEMO_SEED_ATTACHMENT_RESOURCES = [...DEMO_SEED_RESOURCES, ...DEMO_ATTACHMENT_RESOURCES];
export const DEMO_SEED_NOTEBOOK_IDS = DEMO_SEED_NOTEBOOKS.map((notebook) => notebook.id);
export const DEMO_SEED_MEMO_IDS = DEMO_SEED_MEMOS.map((memo) => memo.id);
+2 -2
View File
@@ -397,8 +397,8 @@ const buildApplicationMenu = () => {
{
label: "View",
submenu: [
{ label: "Focus Search", accelerator: "CmdOrCtrl+K", click: () => sendDesktopCommand("focus-search") },
{ label: "Toggle Focus Mode", accelerator: "CmdOrCtrl+Shift+F", click: () => sendDesktopCommand("toggle-focus-mode") },
{ label: "Focus Search", accelerator: "CmdOrCtrl+Shift+F", click: () => sendDesktopCommand("focus-search") },
{ label: "Toggle Focus Mode", click: () => sendDesktopCommand("toggle-focus-mode") },
{ type: "separator" },
{ role: "togglefullscreen" }, { role: "resetZoom" }, { role: "zoomIn" }, { role: "zoomOut" },
],
@@ -0,0 +1,119 @@
import { useDeferredValue, useEffect, useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { FileText, LoaderCircle } from "lucide-react";
import { useTranslation } from "react-i18next";
import type { MemoSummary } from "@edgeever/shared";
import type { EdgeEverRepository } from "@/lib/repository";
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
COMMAND_ITEM_STRONG_SELECTED_CLASS_NAME,
} from "@/components/ui/command";
import {
Dialog,
DialogContent,
DialogDescription,
DialogTitle,
} from "@/components/ui/dialog";
type QuickMemoSwitcherProps = {
open: boolean;
query: string;
repository: EdgeEverRepository;
onOpenChange: (open: boolean) => void;
onQueryChange: (query: string) => void;
onOpenMemo: (memo: MemoSummary) => void;
};
const EMPTY_MEMOS: MemoSummary[] = [];
export const QuickMemoSwitcher = ({
open,
query,
repository,
onOpenChange,
onQueryChange,
onOpenMemo,
}: QuickMemoSwitcherProps) => {
const { t } = useTranslation();
const [selectedMemoId, setSelectedMemoId] = useState("");
const deferredQuery = useDeferredValue(query.trim());
const memoQuery = useQuery({
queryKey: ["quick-memo-switcher", deferredQuery],
queryFn: () => repository.listMemos({
notebookId: null,
q: deferredQuery,
trash: false,
filter: "all",
sort: "updated-desc",
offset: 0,
limit: 50,
}),
enabled: open,
staleTime: 15_000,
});
const memos = memoQuery.data?.memos ?? EMPTY_MEMOS;
const loading = memoQuery.isPending || memoQuery.isFetching;
useEffect(() => {
setSelectedMemoId((current) => (
memos.some((memo) => memo.id === current) ? current : memos[0]?.id ?? ""
));
}, [memos]);
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="top-[18%] block max-w-xl translate-y-0 overflow-hidden p-0">
<DialogTitle className="sr-only">{t("quickSwitcher.title")}</DialogTitle>
<DialogDescription className="sr-only">{t("quickSwitcher.description")}</DialogDescription>
<Command shouldFilter={false} value={selectedMemoId} onValueChange={setSelectedMemoId}>
<CommandInput
autoFocus
className="pr-9"
placeholder={t("quickSwitcher.placeholder")}
value={query}
onValueChange={onQueryChange}
/>
<CommandList className="max-h-[min(26rem,60dvh)] p-1.5">
{loading ? (
<div className="flex items-center justify-center gap-2 py-8 text-sm text-slate-500" role="status">
<LoaderCircle className="h-4 w-4 animate-spin" />
{t("quickSwitcher.loading")}
</div>
) : (
<>
<CommandEmpty>{t("quickSwitcher.empty")}</CommandEmpty>
<CommandGroup heading={deferredQuery ? t("quickSwitcher.results") : t("quickSwitcher.recent")}>
{memos.map((memo) => (
<CommandItem
key={memo.id}
className={COMMAND_ITEM_STRONG_SELECTED_CLASS_NAME}
value={memo.id}
onSelect={() => onOpenMemo(memo)}
>
<FileText className="h-4 w-4 shrink-0 text-slate-500" />
<div className="min-w-0 flex-1 py-0.5">
<div className="truncate font-medium text-slate-900">{memo.title}</div>
{memo.excerpt ? (
<div className="mt-0.5 truncate text-xs text-slate-500">{memo.excerpt}</div>
) : null}
</div>
</CommandItem>
))}
</CommandGroup>
</>
)}
</CommandList>
<div className="flex items-center justify-between border-t border-slate-100 px-3 py-2 text-xs text-slate-400">
<span>{t("quickSwitcher.openHint")}</span>
<span>{t("quickSwitcher.closeHint")}</span>
</div>
</Command>
</DialogContent>
</Dialog>
);
};
+93 -10
View File
@@ -25,6 +25,7 @@ import {
DrawerTitle,
} from "@/components/ui/drawer";
import { MemoListPane, MemoSelectionActionBar } from "./MemoListPane";
import { QuickMemoSwitcher } from "./QuickMemoSwitcher";
import { AppConfirmDialog, MemoDeleteConfirmDialog, NotebookNameDialog } from "./dialogs/ConfirmDialogs";
import { api } from "@/lib/api";
import {
@@ -704,6 +705,7 @@ export const WorkspaceApp = ({
const autoSelectedDemoNotebookRef = useRef(false);
const [createdMemoEditId, setCreatedMemoEditId] = useState<string | null>(null);
const pendingCreatedMemoIdRef = useRef<string | null>(null);
const pendingQuickSwitcherMemoIdRef = useRef<string | null>(null);
const creatingMemoSelectionRef = useRef(false);
const memoDocumentActionIdRef = useRef(0);
const [memoDocumentActionRequest, setMemoDocumentActionRequest] = useState<MemoDocumentActionRequest | null>(null);
@@ -795,6 +797,8 @@ export const WorkspaceApp = ({
: "home"
);
const [mobileSearchFocusToken, setMobileSearchFocusToken] = useState(0);
const [quickSwitcherOpen, setQuickSwitcherOpen] = useState(false);
const [quickSwitcherQuery, setQuickSwitcherQuery] = useState("");
const [noteSearchFocusToken, setNoteSearchFocusToken] = useState(0);
const [noteReplaceFocusToken, setNoteReplaceFocusToken] = useState(0);
const [noteAiAssistantOpenToken, setNoteAiAssistantOpenToken] = useState(0);
@@ -1357,6 +1361,13 @@ export const WorkspaceApp = ({
return;
}
if (pendingQuickSwitcherMemoIdRef.current) {
if (!memos.some((memo) => memo.id === pendingQuickSwitcherMemoIdRef.current)) {
return;
}
pendingQuickSwitcherMemoIdRef.current = null;
}
if (createdMemoEditId && selectedMemoId === createdMemoEditId) {
// Keep the create request alive until the editor consumes it. The new
// memo can appear in the list before its detail query has mounted the
@@ -2216,11 +2227,40 @@ export const WorkspaceApp = ({
setActivePane("memos");
};
const handleMobileSearch = () => {
const handleMobileSearch = useCallback(() => {
setMobileBottomNavActive("search");
setActivePane("memos");
setMobileSearchFocusToken((value) => value + 1);
};
}, []);
const handleGlobalSearch = useCallback(() => {
navigateWorkspaceHome();
setMemoView("notebook");
setSelectedTag(null);
setSelectedNotebookId(null);
setMemoFilterMode("all");
setRightView("editor");
clearMemoSelection();
handleMobileSearch();
}, [clearMemoSelection, handleMobileSearch, navigateWorkspaceHome, setSelectedNotebookId]);
const handleOpenQuickSwitcherMemo = useCallback((memo: MemoSummary) => {
pendingQuickSwitcherMemoIdRef.current = memo.id;
setQuickSwitcherOpen(false);
setQuickSwitcherQuery("");
navigateWorkspaceHome();
setMemoView("notebook");
setSelectedTag(null);
setSelectedNotebookId(memo.notebookId);
setSearch("");
setMemoFilterMode("all");
setRightView("editor");
clearMemoSelection();
clearPendingCreatedMemo();
setCreatedMemoEditId(null);
setSelectedMemoId(memo.id);
setActivePane("editor");
}, [clearMemoSelection, clearPendingCreatedMemo, navigateWorkspaceHome, setSelectedMemoId, setSelectedNotebookId]);
const handleCancelMobileSearch = () => {
setSearch("");
@@ -2336,7 +2376,7 @@ export const WorkspaceApp = ({
const removeCommandListener = bridge.onCommand((command) => {
if (command === "new-memo") handleCreateMemo();
if (command === "new-notebook") handleCreateNotebook();
if (command === "focus-search") handleMobileSearch();
if (command === "focus-search") handleGlobalSearch();
if (command === "toggle-focus-mode") toggleDesktopFocusMode();
if (command === "sync-now") {
void runQueuedSync();
@@ -2366,7 +2406,7 @@ export const WorkspaceApp = ({
removeCommandListener();
removeMarkdownListener();
};
}, [createMemoMutation, defaultMemoNotebookId, handleCreateMemo, handleCreateNotebook, handleMobileSearch, notebooks, selectedNotebookId, toggleDesktopFocusMode]);
}, [createMemoMutation, defaultMemoNotebookId, handleCreateMemo, handleCreateNotebook, handleGlobalSearch, notebooks, selectedNotebookId, toggleDesktopFocusMode]);
const handleWorkspaceBackRequest = useCallback(() => {
if (appNoticeDialog) {
@@ -2535,6 +2575,16 @@ export const WorkspaceApp = ({
return;
}
if (action === "openQuickSwitcher") {
event.preventDefault();
if (event.repeat || event.isComposing) {
return;
}
setQuickSwitcherQuery("");
setQuickSwitcherOpen(true);
return;
}
const targetElement = event.target instanceof Element ? event.target : null;
const isEditorTextTarget = Boolean(targetElement?.closest(".ProseMirror"));
@@ -2546,7 +2596,8 @@ export const WorkspaceApp = ({
mobileNotebookPickerOpen ||
notebookDeleteConfirmation ||
notebookNameDialog ||
templatesOpen
templatesOpen ||
quickSwitcherOpen
);
if (
@@ -2554,6 +2605,8 @@ export const WorkspaceApp = ({
|| action === "saveAndSync"
|| action === "toggleReadingProtection"
|| action === "toggleEditorMode"
|| action === "openPreviousMemo"
|| action === "openNextMemo"
) {
// These replace browser-level commands, so consume them throughout the
// workspace even when the current editor cannot perform the action.
@@ -2569,8 +2622,15 @@ export const WorkspaceApp = ({
setNoteSaveAndSyncToken((value) => value + 1);
} else if (action === "toggleReadingProtection") {
setNoteReadingProtectionToggleToken((value) => value + 1);
} else {
} else if (action === "toggleEditorMode") {
setNoteEditorModeToggleToken((value) => value + 1);
} else {
const targetMemoId = action === "openPreviousMemo" ? previousMemoId : nextMemoId;
if (targetMemoId) {
clearPendingCreatedMemo();
setCreatedMemoEditId(null);
setSelectedMemoId(targetMemoId);
}
}
return;
}
@@ -2585,10 +2645,7 @@ export const WorkspaceApp = ({
if (action === "focusSearch") {
event.preventDefault();
if (event.shiftKey || !selectedMemoId || !isDesktopViewport()) {
if (event.shiftKey) {
setSearch("");
}
if (!selectedMemoId || !isDesktopViewport()) {
clearMemoSelection();
handleMobileSearch();
return;
@@ -2598,6 +2655,12 @@ export const WorkspaceApp = ({
return;
}
if (action === "focusGlobalSearch") {
event.preventDefault();
handleGlobalSearch();
return;
}
if (action === "focusReplace") {
if (!selectedMemoId || memoView === "trash" || !isDesktopViewport()) {
return;
@@ -2628,11 +2691,13 @@ export const WorkspaceApp = ({
rightView,
appNoticeDialog,
canCreateMemo,
clearPendingCreatedMemo,
clearMemoSelection,
createNotebookMutation.isPending,
createMemoMutation.isPending,
handleCreateNotebook,
handleCreateMemo,
handleGlobalSearch,
handleMobileSearch,
shortcutSettings,
emptyTrashConfirmationOpen,
@@ -2641,7 +2706,11 @@ export const WorkspaceApp = ({
mobileNotebookPickerOpen,
notebookDeleteConfirmation,
notebookNameDialog,
nextMemoId,
previousMemoId,
quickSwitcherOpen,
selectedMemoId,
setSelectedMemoId,
templatesOpen,
]);
@@ -3140,6 +3209,20 @@ export const WorkspaceApp = ({
</main>
</div>
<QuickMemoSwitcher
open={quickSwitcherOpen}
query={quickSwitcherQuery}
repository={repository}
onOpenChange={(open) => {
setQuickSwitcherOpen(open);
if (!open) {
setQuickSwitcherQuery("");
}
}}
onQueryChange={setQuickSwitcherQuery}
onOpenMemo={handleOpenQuickSwitcherMemo}
/>
{memoDeleteConfirmation && (
<MemoDeleteConfirmDialog
confirmation={memoDeleteConfirmation}
+57 -3
View File
@@ -231,7 +231,21 @@ describe("automatic sync interval preference", () => {
});
describe("workspace shortcut preferences", () => {
test("provides AI, save, sync, reading protection, and editor mode defaults", () => {
test("provides navigation, AI, save, reading protection, and editor mode defaults", () => {
expect(DEFAULT_SHORTCUT_SETTINGS.focusGlobalSearch).toEqual({
key: "f",
ctrlOrMeta: true,
shift: true,
alt: false,
});
expect(DEFAULT_SHORTCUT_SETTINGS.openQuickSwitcher).toEqual({
key: "o",
ctrlOrMeta: true,
shift: false,
alt: false,
});
expect(DEFAULT_SHORTCUT_SETTINGS.openPreviousMemo.key).toBe("[");
expect(DEFAULT_SHORTCUT_SETTINGS.openNextMemo.key).toBe("]");
expect(DEFAULT_SHORTCUT_SETTINGS.openAiAssistant).toEqual({
key: "j",
ctrlOrMeta: true,
@@ -251,7 +265,27 @@ describe("workspace shortcut preferences", () => {
alt: false,
});
expect(DEFAULT_SHORTCUT_SETTINGS.toggleReadingProtection).toEqual({
key: "l",
key: "e",
ctrlOrMeta: true,
shift: false,
alt: false,
});
});
test("migrates the unreleased reading protection shortcut without replacing custom bindings", () => {
const values = installLocalStorage();
values.set(SHORTCUT_SETTINGS_STORAGE_KEY, JSON.stringify({
toggleReadingProtection: { key: "l", ctrlOrMeta: true, shift: true, alt: false },
}));
expect(readShortcutSettingsPreference().toggleReadingProtection).toEqual(
DEFAULT_SHORTCUT_SETTINGS.toggleReadingProtection,
);
values.set(SHORTCUT_SETTINGS_STORAGE_KEY, JSON.stringify({
toggleReadingProtection: { key: "r", ctrlOrMeta: true, shift: true, alt: false },
}));
expect(readShortcutSettingsPreference().toggleReadingProtection).toEqual({
key: "r",
ctrlOrMeta: true,
shift: true,
alt: false,
@@ -267,6 +301,10 @@ describe("workspace shortcut preferences", () => {
const settings = readShortcutSettingsPreference();
expect(settings.createMemo.key).toBe("m");
expect(settings.openAiAssistant).toEqual(DEFAULT_SHORTCUT_SETTINGS.openAiAssistant);
expect(settings.focusGlobalSearch).toEqual(DEFAULT_SHORTCUT_SETTINGS.focusGlobalSearch);
expect(settings.openQuickSwitcher).toEqual(DEFAULT_SHORTCUT_SETTINGS.openQuickSwitcher);
expect(settings.openPreviousMemo).toEqual(DEFAULT_SHORTCUT_SETTINGS.openPreviousMemo);
expect(settings.openNextMemo).toEqual(DEFAULT_SHORTCUT_SETTINGS.openNextMemo);
expect(settings.saveAndSync).toEqual(DEFAULT_SHORTCUT_SETTINGS.saveAndSync);
expect(settings.toggleReadingProtection).toEqual(DEFAULT_SHORTCUT_SETTINGS.toggleReadingProtection);
expect(settings.toggleEditorMode).toEqual(DEFAULT_SHORTCUT_SETTINGS.toggleEditorMode);
@@ -282,6 +320,22 @@ describe("workspace shortcut preferences", () => {
...modifiers,
});
expect(getShortcutActionForEvent(
keyboardEvent("f", { metaKey: true, shiftKey: true }),
DEFAULT_SHORTCUT_SETTINGS,
)).toBe("focusGlobalSearch");
expect(getShortcutActionForEvent(
keyboardEvent("o", { ctrlKey: true }),
DEFAULT_SHORTCUT_SETTINGS,
)).toBe("openQuickSwitcher");
expect(getShortcutActionForEvent(
keyboardEvent("[", { metaKey: true }),
DEFAULT_SHORTCUT_SETTINGS,
)).toBe("openPreviousMemo");
expect(getShortcutActionForEvent(
keyboardEvent("]", { ctrlKey: true }),
DEFAULT_SHORTCUT_SETTINGS,
)).toBe("openNextMemo");
expect(getShortcutActionForEvent(
keyboardEvent("j", { metaKey: true }),
DEFAULT_SHORTCUT_SETTINGS,
@@ -291,7 +345,7 @@ describe("workspace shortcut preferences", () => {
DEFAULT_SHORTCUT_SETTINGS,
)).toBe("saveAndSync");
expect(getShortcutActionForEvent(
keyboardEvent("l", { ctrlKey: true, shiftKey: true }),
keyboardEvent("e", { ctrlKey: true }),
DEFAULT_SHORTCUT_SETTINGS,
)).toBe("toggleReadingProtection");
expect(getShortcutActionForEvent(
+52 -10
View File
@@ -17,7 +17,11 @@ export type ShortcutAction =
| "createMemo"
| "createNotebook"
| "focusSearch"
| "focusGlobalSearch"
| "focusReplace"
| "openQuickSwitcher"
| "openPreviousMemo"
| "openNextMemo"
| "openAiAssistant"
| "saveAndSync"
| "toggleReadingProtection"
@@ -190,11 +194,31 @@ export const getShortcutActionOptions = (
label: t("shortcuts.actions.focusSearch.label"),
description: t("shortcuts.actions.focusSearch.description"),
},
{
value: "focusGlobalSearch",
label: t("shortcuts.actions.focusGlobalSearch.label"),
description: t("shortcuts.actions.focusGlobalSearch.description"),
},
{
value: "focusReplace",
label: t("shortcuts.actions.focusReplace.label"),
description: t("shortcuts.actions.focusReplace.description"),
},
{
value: "openQuickSwitcher",
label: t("shortcuts.actions.openQuickSwitcher.label"),
description: t("shortcuts.actions.openQuickSwitcher.description"),
},
{
value: "openPreviousMemo",
label: t("shortcuts.actions.openPreviousMemo.label"),
description: t("shortcuts.actions.openPreviousMemo.description"),
},
{
value: "openNextMemo",
label: t("shortcuts.actions.openNextMemo.label"),
description: t("shortcuts.actions.openNextMemo.description"),
},
{
value: "openAiAssistant",
label: t("shortcuts.actions.openAiAssistant.label"),
@@ -221,13 +245,24 @@ export const DEFAULT_SHORTCUT_SETTINGS: ShortcutSettings = {
createMemo: { key: "n", ctrlOrMeta: true, shift: false, alt: false },
createNotebook: { key: "n", ctrlOrMeta: true, shift: true, alt: false },
focusSearch: { key: "f", ctrlOrMeta: true, shift: false, alt: false },
focusGlobalSearch: { key: "f", ctrlOrMeta: true, shift: true, alt: false },
focusReplace: { key: "h", ctrlOrMeta: true, shift: false, alt: false },
openQuickSwitcher: { key: "o", ctrlOrMeta: true, shift: false, alt: false },
openPreviousMemo: { key: "[", ctrlOrMeta: true, shift: false, alt: false },
openNextMemo: { key: "]", ctrlOrMeta: true, shift: false, alt: false },
openAiAssistant: { key: "j", ctrlOrMeta: true, shift: false, alt: false },
saveAndSync: { key: "s", ctrlOrMeta: true, shift: false, alt: false },
toggleReadingProtection: { key: "l", ctrlOrMeta: true, shift: true, alt: false },
toggleReadingProtection: { key: "e", ctrlOrMeta: true, shift: false, alt: false },
toggleEditorMode: { key: "/", ctrlOrMeta: true, shift: false, alt: false },
};
const LEGACY_READING_PROTECTION_SHORTCUT: ShortcutBinding = {
key: "l",
ctrlOrMeta: true,
shift: true,
alt: false,
};
const SHORTCUT_ALIASES: Partial<Record<ShortcutAction, ShortcutBinding[]>> = {
focusReplace: [{ key: "h", ctrlOrMeta: true, shift: true, alt: false }],
};
@@ -236,7 +271,11 @@ const SHORTCUT_ACTION_VALUES: ShortcutAction[] = [
"createMemo",
"createNotebook",
"focusSearch",
"focusGlobalSearch",
"focusReplace",
"openQuickSwitcher",
"openPreviousMemo",
"openNextMemo",
"openAiAssistant",
"saveAndSync",
"toggleReadingProtection",
@@ -440,15 +479,18 @@ export const readShortcutSettingsPreference = (): ShortcutSettings => {
}
const parsedValue = JSON.parse(rawValue) as Partial<ShortcutSettings>;
return SHORTCUT_ACTION_VALUES.reduce<ShortcutSettings>(
(settings, action) => ({
...settings,
[action]: isShortcutBinding(parsedValue[action])
? { ...parsedValue[action], key: normalizeShortcutKey(parsedValue[action].key) }
: DEFAULT_SHORTCUT_SETTINGS[action],
}),
{ ...DEFAULT_SHORTCUT_SETTINGS }
);
return SHORTCUT_ACTION_VALUES.reduce<ShortcutSettings>((settings, action) => {
const storedBinding = parsedValue[action];
const normalizedBinding = isShortcutBinding(storedBinding)
? { ...storedBinding, key: normalizeShortcutKey(storedBinding.key) }
: DEFAULT_SHORTCUT_SETTINGS[action];
const binding = action === "toggleReadingProtection"
&& shortcutBindingsEqual(normalizedBinding, LEGACY_READING_PROTECTION_SHORTCUT)
? DEFAULT_SHORTCUT_SETTINGS.toggleReadingProtection
: normalizedBinding;
return { ...settings, [action]: binding };
}, { ...DEFAULT_SHORTCUT_SETTINGS });
} catch {
return DEFAULT_SHORTCUT_SETTINGS;
}
+196
View File
@@ -0,0 +1,196 @@
# <img src="/api/v1/resources/res_demo_logo/blob" alt="EdgeEver Logo" width="36" align="absmiddle" /> Welcome to EdgeEver: Modern Open-Source Knowledge Base for Geeks & Creators
> **EdgeEver** is an open-source, AI-native, and portable serverless/containerized personal knowledge base that revives the beloved **Evernote-style three-pane layout**. Designed for geeks and content creators, it combines 100% free serverless hosting, absolute data ownership, native cross-platform clients, and seamless AI Agent (MCP) synergy to redefine your digital second brain.
---
## ⚡ 1. Why Choose EdgeEver?
*Tip: In editor mode, click any table cell to edit text directly, or right-click to insert/delete rows and columns.*
| Dimension | Traditional Cloud Notes (e.g. Evernote) | Local Offline Notes (e.g. Obsidian) | EdgeEver Geek Knowledge Base |
| :--- | :--- | :--- | :--- |
| **Hosting Cost** | Costly commercial subscriptions ($10+/mo) | Official cloud sync subscription ($5+/mo) | **100% Free Forever (Cloudflare Free Tier / Docker Self-Hosted)** |
| **Data Ownership** | Proprietary lock-in, hard to export | Local Markdown, cumbersome mobile sync | **Full Ownership (D1 SQLite, R2 Storage, Lossless ZIP Archives)** |
| **Editing Experience** | Rich text only, fragile formatting | Plain Markdown, lacks WYSIWYG flow | **Seamless Dual-View (WYSIWYG Rich Text ⇄ Markdown Source)** |
| **Publishing Ready** | No typography styling, loses format | Requires 3rd-party plugins or scripts | **One-Click Rich Copy for WeChat, Substack, Medium & WordPress** |
| **Social Poster Cards** | Basic screenshots without styling | Requires external tools or plugins | **8 Built-in Exquisite Poster Themes with Typography Options & PNG/JPEG Export** |
| **Native AI Ecosystem** | Paywalled, limited features | Heavy plugin setup required | **Native MCP Server (`/mcp`) & Inline AI Agent Synergy** |
| **Cross-Platform Matrix** | Restricts active free devices | Complex setup across platforms | **Web / PWA / Android / iOS / macOS / Windows (Coming Soon)** |
---
## 🏗️ 2. Architectural Overview & Ecosystem
The Mermaid diagram below demonstrates how EdgeEver connects cross-platform clients, zero-cost cloud infrastructure, and AI Agents into a cohesive workflow:
```mermaid
flowchart TD
subgraph MultiClients["Client Matrix"]
C1["Web / PWA (Offline Drafts & Sync Queue)"]
C2["macOS Desktop (Electron + Rust Sidecar)"]
C3["Android Native App (Expo + SQLite)"]
C4["iOS Native App (SwiftUI + GRDB)"]
C5["Web Clipper (Chrome / Edge / Firefox)"]
end
subgraph CoreEngine["Service & Storage Core"]
API["Hono API Engine (Cloudflare Workers / Docker)"]
MCP["Native MCP Endpoint (/mcp 2026-07-28 & 2025)"]
D1[("D1 / SQLite Database (Sync Cursor & Revisions)")]
R2[("R2 / S3 Storage (Images & Media Attachments)")]
end
subgraph AIAgents["AI Agents & Integrations"]
A1["Claude Code / Cursor / Antigravity"]
A2["Inline AI Assistant (OpenAI / Gemini / DeepSeek)"]
A3["Notion DB / Feishu Bitable Sync"]
end
MultiClients <==>|REST API & Sync Cursor| API
API <==> D1 & R2
MCP <==> D1 & R2
A1 <==>|MCP Tools / SSE| MCP
A2 -.->|BYOK Direct Key| MultiClients
A1 -.->|Bi-directional Sync| A3
```
---
## 🎨 3. Immersive Writing & Typography Aesthetics
EdgeEver is engineered to provide a distraction-free, elegant writing experience:
### 🖥️ Dual-View Editor & Focus Modes
- **Seamless Dual-View**: Click the `</>` button in the top-right corner (or use shortcuts) to instantly toggle between **WYSIWYG Rich Text** and **Markdown Source Code** with 100% fidelity.
- **Collapsible Outline Navigation**: Automatically indexes `H1-H3` heading hierarchies with smooth jump scrolling, keeping lengthy documents organized.
- **Zen Focus Mode**: Press `Cmd/Ctrl + Shift + F` to hide sidebars and distractions, immersing yourself in pure writing flow.
- **Reading Protection Mode**: When reading or reviewing notes, press `Cmd/Ctrl + E` to toggle read-only protection, locking the editor to prevent accidental edits while browsing; press it again to seamlessly resume editing.
### 🎭 Curated Typography Themes & Publishing Export
- **Preset Editor Themes**: Switch effortlessly between `WeChat Classic Green`, `Modern Mint`, `Minimal Emerald`, `Outline Emerald`, and more.
- **One-Click Publishing Export**: Built for publishers and bloggers. Click the **WeChat Icon** in the top bar to format your note with inline CSS. Paste directly into WeChat Official Account editor, Substack, Medium, or WordPress while preserving layout and syntax highlighting.
### 🖼️ 8 Exquisite Social Poster Themes
Click **"Share as Card"** in the top-right menu to turn any note into an eye-catching poster card:
- **8 Themes**: `Slate`, `Aurora`, `Sunset`, `Midnight`, `Mint`, `Notepad` (skeuomorphic paper), `Xuan` (rice paper & Chinese ink), `Lavender`.
- **Customizable Typography**: Switch between Sans, Serif (Songti/Ming), and Monospace fonts, select compact, standard, or wide card widths, and export as high-resolution PNG or JPEG.
---
## ⌨️ 4. Power Productivity Toolbox: Slash Commands, Backlinks & Math
### 🪄 Slash Commands
Type `/` or press `Space` on an empty line to invoke the command menu:
- Insert `H1/H2/H3` headings, quotes, horizontal rules, code blocks, and rich tables;
- Use `/date`, `/time`, or `/now` to insert current timestamps instantly;
- Attach files, insert images, or summon the inline AI assistant.
### 🔗 Bi-directional Note Links & Backlinks
Type `@` or insert `#memo=<memoId>` links to establish bi-directional references across your knowledge base, building an interconnected web of thoughts.
### 📐 KaTeX Professional LaTeX Mathematics
Native support for KaTeX renders complex mathematical equations in milliseconds:
- **Inline Math**: For instance, Einstein's mass-energy equivalence $E = mc^2$ or the Gaussian probability density function $f(x) = \frac{1}{\sigma \sqrt{2\pi}} e^{-\frac{(x-\mu)^2}{2\sigma^2}}$.
- **Display Block Math**:
$$
\oint_{\partial \Omega} \mathbf{E} \cdot d\mathbf{S} = \frac{1}{\varepsilon_0} \iiint_{\Omega} \rho \, dV, \quad \oint_{\partial \Omega} \mathbf{B} \cdot d\mathbf{S} = 0
$$
### ✅ Interactive Task Lists
- [x] Explore EdgeEver's dual-view editing and outline navigation
- [x] Experiment with 8 editor themes and 8 social poster card styles
- [ ] Try typing `/` on an empty line to insert current timestamp and tables
- [ ] Connect your AI API Key to experience inline summarization and continuation
- [ ] Connect AI Agents via MCP to automate note categorization
---
## 🤖 5. Native AI Agent Synergy & MCP Protocol
EdgeEver is architected for the agentic AI era, weaving LLMs directly into the knowledge management lifecycle:
```mermaid
sequenceDiagram
autonumber
actor User as Creator / Knowledge Worker
participant Client as EdgeEver Clients
participant MCP as EdgeEver MCP Endpoint
participant Agent as AI Agent (Claude / Cursor / Antigravity)
participant Database as Notion / Feishu Bitable
User->>Client: Capture quick spark or meeting notes
Agent->>MCP: tools/call memo_search (Query unprocessed memos)
MCP-->>Agent: Returns structured Markdown & tags
Agent->>Agent: Analyzes content, extracts key takeaways & tags
Agent->>MCP: tools/call memo_update (Writes back summary & tags)
Agent->>Database: Syncs structured records to master database
Client-->>User: Sub-second live updates in client UI
```
### 1️⃣ Inline AI Assistant
Press the **`Space` bar** in an empty block, type **`/ai`**, use the **`/`** slash command menu, or select text and click the **AI button** on the floating toolbar to instantly summon the AI writing assistant:
- **Summarization & Action Items**: Condense documents into key takeaways, conclusions, and actionable todos;
- **Format-Preserving Translation**: Translate accurately into multiple languages while strictly preserving Markdown, math equations, links, and code blocks;
- **Rewriting & Style Transformation**: Improve phrasing, fix spelling/grammar, adapt to social media styles (e.g. Xiaohongshu / Twitter), or continue writing seamlessly;
- **BYOK Direct Key (Bring Your Own Key)**: Direct client-side connection with OpenAI, Anthropic Claude, Google Gemini, DeepSeek, and OpenAI-compatible relays with zero third-party data transit.
### 2️⃣ Model Context Protocol (MCP) Integration
Generate an API token in **Settings → MCP Settings** to connect EdgeEver directly with Claude Code, Cursor, Antigravity, OpenClaw, and other agent platforms:
- **Direct Reading & Writing**: Connect via the `/mcp` endpoint (supports stateless `2026-07-28` protocol and handshake-based 2025 specs);
- **Automated Workflows**: Let AI Agents read, organize, summarize, tag, and synchronize notes with Notion databases and Feishu Bitable.
---
## 📱 6. Multi-Platform Ecosystem, Offline Sync & Smart Clipping
- **Cross-Platform Native Apps**:
- **Web / PWA**: Full-featured in modern browsers with offline installation support;
- **Android Native App**: Built with Expo & SQLite, available on Google Play and GitHub Releases;
- **iOS Native App**: Native Swift / SwiftUI with GRDB local mirror, available on the App Store;
- **macOS Desktop App**: Electron + Rust Sidecar for Apple Silicon & Intel Mac with silent background updates;
- **Windows Desktop App**: Development is complete, coming soon.
- **Browser Web Clipper**: Available on Chrome, Edge, and Firefox extension stores to extract clean, ad-free Markdown articles in one click.
- **Mobile WeChat Article Clipper**: Share any WeChat article to EdgeEver on your phone to automatically extract and format it as an editable note.
- **Offline Drafts & Sync Queue**: Keep writing seamlessly without network connectivity; changes are queued locally and automatically synced once reconnected.
---
## 📦 7. Rich Media, Lossless Portability & Zero-Cost Hosting
### 🖼️ Smart Client-Side Image Compression
When pasting or dragging images into notes, EdgeEver compresses them to WebP locally in your browser before upload, **reducing file size by 50% - 90%** while preserving visual fidelity.
![EdgeEver Mascot: Geek Cat](/api/v1/resources/res_demo_cat_image/blob)
### 📎 Universal File Attachments
Embed PDFs, spreadsheets, archives, and multimedia files directly in notes for preview or download:
- [📄 Product brief PDF: edgeever-product-brief.pdf](/api/v1/resources/res_demo_product_brief_pdf/blob)
- [📊 Feature matrix CSV: feature-matrix.csv](/api/v1/resources/res_demo_feature_matrix_csv/blob)
- [📦 Sample attachment archive: edgeever-attachment-demo.zip](/api/v1/resources/res_demo_attachment_bundle_zip/blob)
### 🚀 Zero-Cost Serverless & Docker Self-Hosting
1. **Cloudflare Serverless (Recommended, 100% Free Forever)**: Runs entirely within Cloudflare's free tier (Workers + D1 SQLite + R2 Storage). No server bills, no VPS maintenance.
2. **Docker One-Command Deployment (VPS / NAS / Home Server)**:
```sh
# International VPS / NAS installer (GHCR image)
curl -fsSL https://edgeever.org/install.sh | bash
# Mainland China mirror installer (Tencent TCR image)
curl -fsSL https://edgeever-installer-1256854452.cos.ap-guangzhou.myqcloud.com/install.sh | bash -s -- --mirror tcr
```
Configures Docker Compose and automated daily background updates with one command.
### 💾 Complete Data Freedom: Lossless ZIP Portability
Export your entire library at any time from **Profile → Import and export**. The archive contains pure Markdown files with standard YAML Front Matter, relative media paths, and full revision histories—compatible with Obsidian, VS Code, and any plain text editor.
---
> 💡 **Quick Exploration Tips**:
> 1. Click **`</>`** in the top right to try seamless dual-view toggling;
> 2. Press **`Cmd/Ctrl + E`** to test reading protection mode against accidental edits;
> 3. Press **`Cmd/Ctrl + O`** to summon the Quick Switcher;
> 4. Click the **WeChat Icon** to copy formatted rich text ready for publishing;
> 5. Click **"Share as Card"** to export a stunning social poster card;
> 6. Click **"Reset Demo Data"** in settings or the sidebar anytime to restore the demo workspace.
+196
View File
@@ -0,0 +1,196 @@
# <img src="/api/v1/resources/res_demo_logo/blob" alt="EdgeEver Logo" width="36" align="absmiddle" /> 欢迎使用 EdgeEver:为极客与创作者打造的现代开源知识库
> **EdgeEver** 是一款兼具**经典三栏美学**与 **AI 原生动力**的开源 Serverless / 容器化个人知识库。它既找回了极客们钟爱的经典印象笔记式双视图与树状目录,又以零服务器成本、完全数据自主、全端原生覆盖与深度 MCP 智能体协同,重新定义了下一代个人第二大脑。
---
## ⚡ 1. 为什么选择 EdgeEver?
*提示:在编辑器模式下,你可以直接点击任意表格单元格进行行内编辑,或右键快捷插入/删除行列。*
| 核心维度 | 传统商业云笔记 (如 Evernote) | 本地离线知识库 (如 Obsidian) | EdgeEver 极客知识库 |
| :--- | :--- | :--- | :--- |
| **云端托管成本** | 商业订阅高昂($10+/月) | 官方云同步收费($5+/月) | **100% 永久免费 (Cloudflare 免费额度 / Docker 自建)** |
| **数据资产所有权** | 专有格式封闭,导出困难 | 本地 Markdown,移动端同步繁琐 | **完全自主掌控 (D1 SQLite 数据库 / R2 / 无损 ZIP 导出)** |
| **写作与编辑体验** | 仅富文本,排版易错乱 | 纯 Markdown,缺乏沉浸所见即所得 | **双视图自由切换 (所见即所得富文本 ⇄ Markdown 源码)** |
| **自媒体排版分发** | 无样式优化,格式丢失 | 需借助外部排版扩展或工具 | **一键复制到微信公众号 / Substack / Medium / WordPress** |
| **社交卡片分享** | 截图粗糙或无排版设计 | 需第三方插件实现 | **内置 8 款精美海报主题,支持自定义字体与 PNG/JPEG 导出** |
| **AI 原生集成生态** | 封闭收费,仅限特定功能 | 需配置复杂的第三方插件 | **原生内置 MCP 服务端点 (`/mcp`) 与行内 AI 智能体协同** |
| **全平台多端覆盖** | 限制免费设备登录数量 | 多端同步与移动端体验门槛高 | **Web / PWA / Android / iOS / macOS / Windows (即将推出)** |
---
## 🏗️ 2. 全景架构与生态联动
通过下面的 Mermaid 架构图,你可以清晰了解 EdgeEver 如何将多端客户端、零成本云基础设施与 AI Agent 紧密串联:
```mermaid
flowchart TD
subgraph MultiClients["全端客户端矩阵"]
C1["Web / PWA (离线草稿 & 增量同步)"]
C2["macOS 桌面端 (Electron + Rust Sidecar)"]
C3["Android 原生 App (Expo + SQLite)"]
C4["iOS 原生 App (SwiftUI + GRDB)"]
C5["浏览器剪藏插件 (Chrome / Edge / Firefox)"]
end
subgraph CoreEngine["业务与数据服务层"]
API["Hono API 引擎 (Cloudflare Workers / Docker)"]
MCP["原生 MCP Endpoint (/mcp 2026-07-28 & 2025)"]
D1[("D1 / SQLite 数据库 (双向同步 & 修订版本)")]
R2[("R2 / S3 资源存储 (图片与多媒体附件)")]
end
subgraph AIAgents["AI 智能体与外部生态"]
A1["Claude Code / Cursor / Antigravity"]
A2["行内 AI 助手 (OpenAI / Gemini / DeepSeek)"]
A3["Notion 数据库 / 飞书多维表格联动"]
end
MultiClients <==>|REST API & 同步游标| API
API <==> D1 & R2
MCP <==> D1 & R2
A1 <==>|MCP Tools / SSE| MCP
A2 -.->|BYOK 密钥直连| MultiClients
A1 -.->|双向数据同步| A3
```
---
## 🎨 3. 极致创作体验与排版美学
EdgeEver 将高效与优雅融入每一处交互细节,助你专注于思考与表达:
### 🖥️ 双视图编辑器与沉浸模式
- **自由切换视图**:点击右上角 `</>` 按钮或使用快捷键,可在**所见即所得富文本**与 **Markdown 源码**间无缝切换,实时双向保真。
- **左侧可折叠大纲**:自动解析文档 `H1-H3` 标题层级,支持点击平滑滚动跳转,助你轻松把控万字长文。
- **Zen 专注模式**:按下 `Cmd/Ctrl + Shift + F`,隐藏所有侧边栏与干扰元素,进入纯粹写作心流。
- **阅读保护模式 (Reading Protection)**:日常翻阅或查阅笔记时,按下 `Cmd/Ctrl + E` 即可一键开启只读保护,锁定当前编辑状态,避免沉浸阅读时误触键盘或意外改动笔记内容;再次按下即可随手切回编辑。
### 🎭 精选排版主题与一键自媒体发布
- **内置排版主题**:支持一键切换 `WeChat Classic Green (微信经典绿)`、`Modern Mint (薄荷青)`、`Minimal Emerald (极简祖母绿)`、`Outline Emerald (大纲祖母绿)` 等风格。
- **一键排版复制**:专为内容创作者设计。点击顶部工具栏的**微信公众号图标**,系统自动将当前笔记转为内联 CSS 样式的优雅富文本,直接粘贴至微信公众号后台、Substack 或 WordPress,排版与代码高亮完美保真。
### 🖼️ 8 套精美社交分享海报 (Poster Cards)
点击右上角“分享为卡片”,即可将任意笔记或片段渲染为高清分享海报,支持:
- **8 大主题风格**:`Slate (岩灰)`、`Aurora (极光青)`、`Sunset (落日暖橙)`、`Midnight (暗夜极客)`、`Mint (清爽薄荷)`、`Notepad (复古便签)`、`Xuan (宣纸水墨)`、`Lavender (薰衣草紫)`。
- **排版定制**:支持无衬线 (Sans)、宋体/明朝 (Serif)、等宽代码 (Mono) 字体切换,自由选择紧凑、标准或宽幅卡片,一键导出为高清晰度 PNG 或 JPEG 图片。
---
## ⌨️ 4. 效率工具箱:斜杠指令、双链与数学公式
### 🪄 斜杠指令 (Slash Commands)
在正文空白行输入 `/` 或直接按下 `空格键`,即可呼出快捷指令菜单:
- 快速插入 `H1/H2/H3` 标题、引用、分割线、代码块与富文本表格;
- 输入 `/date`、`/time` 或 `/now` 快速插入当前标准时间戳;
- 插入附件、图片或调起行内 AI 智能助手。
### 🔗 知识双链与笔记引用
在编辑器中输入 `@` 或插入 `#memo=<笔记ID>` 链接,即可建立笔记间的双向关联,点击即可在工作区内快速打开关联笔记,构建结构化网状知识库。
### 📐 KaTeX 专业数学公式渲染
EdgeEver 原生支持 LaTeX 数学表达式,无论是行内微积分还是多行物理方程,均可毫秒级高保真渲染:
- **行内公式**:例如质能方程 $E = mc^2$,以及正态分布概率密度函数 $f(x) = \frac{1}{\sigma \sqrt{2\pi}} e^{-\frac{(x-\mu)^2}{2\sigma^2}}$。
- **多行独立公式块**:
$$
\oint_{\partial \Omega} \mathbf{E} \cdot d\mathbf{S} = \frac{1}{\varepsilon_0} \iiint_{\Omega} \rho \, dV, \quad \oint_{\partial \Omega} \mathbf{B} \cdot d\mathbf{S} = 0
$$
### ✅ 交互式待办清单 (Task Lists)
- [x] 体验 EdgeEver 双视图与大纲导航
- [x] 探索 8 款编辑器主题与 8 套社交海报卡片
- [ ] 尝试使用斜杠指令 `/` 插入当前日期与结构化表格
- [ ] 配置个人 AI API Key,体验行内智能总结与续写
- [ ] 开启 MCP 协议,让 AI Agent 协助整理工作区
---
## 🤖 5. AI 原生协同与 MCP 智能体生态
EdgeEver 走在 AI 时代前沿,将大语言模型与智能体深度融入知识管理生命周期:
```mermaid
sequenceDiagram
autonumber
actor User as 创作者 / 知识工作者
participant Client as EdgeEver 多端应用
participant MCP as EdgeEver MCP 服务端点
participant Agent as AI Agent (Claude / Cursor / Antigravity)
participant Database as Notion / 飞书多维表格
User->>Client: 快速记录碎片想法与会议灵感
Agent->>MCP: tools/call memo_search (检索近期未整理笔记)
MCP-->>Agent: 返回结构化 Markdown 笔记内容与标签
Agent->>Agent: 理解内容、自动提炼核心摘要并归类标签
Agent->>MCP: tools/call memo_update (写回智能总结与增强标签)
Agent->>Database: 同步结构化字段至个人知识总库
Client-->>User: 客户端毫秒级感知更新,笔记井井有条
```
### 1️⃣ 行内 AI 助手 (Inline AI Assistant)
在正文空白行直接按下 **`空格键 (Space)`**、输入 **`/ai`**、通过 **`/`** 斜杠指令菜单,或选中文本点击浮动工具栏中的 **AI 按钮**,即可即时呼出 AI 写作助手面板:
- **精炼总结与要点提取**:一键压缩提炼全文核心结论、提取待办事项与关键行动项;
- **格式保真智能翻译**:在严格保留原有 Markdown、数学公式、链接与代码块的前提下,精准翻译多国语言;
- **内容重塑与风格改写**:支持改进表达、修正错别字与语法、转为社交媒体(如小红书/推特)风格,或按上下文顺滑续写;
- **BYOK 隐私直连 (Bring Your Own Key)**:支持直连 OpenAI、Anthropic Claude、Google Gemini、DeepSeek 及各类 OpenAI 兼容的中继 API,数据完全由端侧直发,不经过任何第三方中转。
### 2️⃣ 开放 MCP 协议 (Model Context Protocol)
在**设置 → MCP 设置**中生成专属令牌,即可将 EdgeEver 接入 Claude Code、Cursor、Antigravity、OpenClaw 等主流 AI 编码助手与智能体平台:
- **无缝读写**:支持标准 MCP 端点 `/mcp`(兼容最新的无状态 `2026-07-28` 协议与经典握手协议);
- **自动化流转**:AI Agent 可自动读取笔记、智能归档、批量打标,甚至与 Notion、飞书多维表格建立跨平台自动化同步。
---
## 📱 6. 全平台原生覆盖、离线同步与智能剪藏
- **多端原生支持**:
- **Web / PWA**:支持现代浏览器全功能运行与离线安装;
- **Android 原生客户端**:基于 Expo 与 SQLite 构建,已上架 Google Play,并提供签名 APK 下载;
- **iOS 原生客户端**:基于 Swift / SwiftUI 与 GRDB 原生实现,流畅细腻,已上架 App Store;
- **macOS 桌面端**:Electron + Rust 高性能 Sidecar,支持 Apple Silicon 和 Intel Mac,内置静默后台更新;
- **Windows 桌面端**:已开发完毕,即将正式推出。
- **浏览器网页剪藏 (Web Clipper)**:已在 Chrome、Edge 和 Firefox 官方扩展商店发布,一键剔除网页广告,将正文纯净沉淀为 Markdown 笔记。
- **微信公众号一键剪藏**:在移动端系统分享菜单中,直接将微信文章分享到 EdgeEver,客户端将自动提取图文排版并转换为可编辑笔记。
- **离线草稿与弹性同步**:地铁、飞行模式等无网络环境下自由编辑,重新联网后自动入队完成增量同步与冲突协调。
---
## 📦 7. 多媒体管理、无损备份与零成本自建
### 🖼️ 智能本地图片压缩
在笔记中粘贴或拖入高分辨率图片时,前端会在本地自动将其转码压缩为 WebP 格式,在保证视觉无损的前提下**减少 50% - 90% 的体积**,大幅降低云端存储占用并提升跨端加载速度。
![EdgeEver 极客猫猫吉祥物](/api/v1/resources/res_demo_cat_image/blob)
### 📎 多类型附件自由挂载
支持在笔记中嵌入 PDF 文档、CSV 表格、压缩包及多媒体资源,点击即可在线预览或下载:
- [📄 产品白皮书 PDF:edgeever-product-brief.pdf](/api/v1/resources/res_demo_product_brief_pdf/blob)
- [📊 功能矩阵 CSV:feature-matrix.csv](/api/v1/resources/res_demo_feature_matrix_csv/blob)
- [📦 示例附件压缩包:edgeever-attachment-demo.zip](/api/v1/resources/res_demo_attachment_bundle_zip/blob)
### 🚀 两种自建部署方案:Serverless 与 Docker
1. **Cloudflare Serverless(推荐,永久 100% 免费)**:基于 Workers + D1 数据库 + R2 对象存储构建,完全处于 Cloudflare 免费额度内,无需采购服务器,免运维、免证书续期。
2. **Docker 一键自建(VPS / NAS / 家用服务器)**:
```sh
# 国际 VPS / NAS 极速安装(GHCR 镜像)
curl -fsSL https://edgeever.org/install.sh | bash
# 大陆地区 VPS / NAS 镜像加速(腾讯云 TCR 镜像)
curl -fsSL https://edgeever-installer-1256854452.cos.ap-guangzhou.myqcloud.com/install.sh | bash -s -- --mirror tcr
```
单命令自动配置 Docker Compose 环境,并内置每日定时自动更新。
### 💾 绝对的数据自由:无损 ZIP 导入与导出
在**个人中心 → 导入与导出**中,可随时将完整笔记库打包导出为结构清晰的 ZIP 压缩包。解压后即为包含标准 YAML Front Matter、相对路径附件图片与完整修订版本的纯 Markdown 文件树,随时可在 Obsidian、VS Code 等任意工具中无缝打开,永不担心平台绑定!
---
> 💡 **快速体验小贴士**:
> 1. 点击右上角 **`</>`** 体验丝滑的双视图切换;
> 2. 按下 **`Cmd/Ctrl + E`** 试一试阅读保护模式,锁定只读避免误改内容;
> 3. 按下 **`Cmd/Ctrl + O`** 呼出快速切换器 (Quick Switcher);
> 4. 点击顶部 **微信图标**,体验一键带格式排版复制;
> 5. 点击 **“分享为卡片”**,挑选一款你心仪的社交海报风格并导出;
> 6. 随时在侧边栏或设置中点击 **“恢复 Demo 数据”**,一键重置演示工作区。
+29 -2
View File
@@ -703,13 +703,29 @@ export const enUS = {
description: "Create a new notebook at the current level.",
},
focusSearch: {
label: "Search notes",
description: "Open search or focus search within the current note.",
label: "Search current note",
description: "Focus text search within the current note.",
},
focusGlobalSearch: {
label: "Search all notes",
description: "Focus list search to find content across all notes.",
},
focusReplace: {
label: "Replace text",
description: "Open replace in the current note.",
},
openQuickSwitcher: {
label: "Quick switcher",
description: "Search and open any note that is not in trash.",
},
openPreviousMemo: {
label: "Previous note",
description: "Open the previous note in the current list.",
},
openNextMemo: {
label: "Next note",
description: "Open the next note in the current list.",
},
openAiAssistant: {
label: "Open AI assistant",
description: "Open the inline AI composer at the current selection or cursor.",
@@ -728,6 +744,17 @@ export const enUS = {
},
},
},
quickSwitcher: {
title: "Quick switcher",
description: "Search and open any note that is not in trash.",
placeholder: "Search note titles or content…",
recent: "Recently updated",
results: "Search results",
empty: "No matching notes",
loading: "Searching…",
openHint: "Open · Enter",
closeHint: "Close · Esc",
},
options: {
memoDensity: {
preview: "Preview list",
+29 -2
View File
@@ -703,13 +703,29 @@ export const zhCN = {
description: "在当前层级创建一个新笔记本。",
},
focusSearch: {
label: "搜索笔记",
description: "打开搜索或聚焦笔记内搜索。",
label: "搜索当前笔记",
description: "聚焦当前笔记内的文本搜索。",
},
focusGlobalSearch: {
label: "全局搜索笔记",
description: "聚焦笔记列表搜索,在全部笔记内容中查找。",
},
focusReplace: {
label: "替换文本",
description: "在当前笔记中打开替换。",
},
openQuickSwitcher: {
label: "快速切换笔记",
description: "搜索并打开任意未删除的笔记。",
},
openPreviousMemo: {
label: "上一篇笔记",
description: "打开当前列表中的上一篇笔记。",
},
openNextMemo: {
label: "下一篇笔记",
description: "打开当前列表中的下一篇笔记。",
},
openAiAssistant: {
label: "打开 AI 助手",
description: "在当前选区或光标位置打开内联 AI 输入框。",
@@ -728,6 +744,17 @@ export const zhCN = {
},
},
},
quickSwitcher: {
title: "快速切换笔记",
description: "搜索并打开任意未删除的笔记。",
placeholder: "搜索笔记标题或内容…",
recent: "最近更新",
results: "搜索结果",
empty: "没有找到匹配的笔记",
loading: "正在搜索…",
openHint: "打开 · Enter",
closeHint: "关闭 · Esc",
},
options: {
memoDensity: {
preview: "预览列表",