diff --git a/.npmrc.example b/.npmrc.example
index 5ebd230..2d66759 100644
--- a/.npmrc.example
+++ b/.npmrc.example
@@ -1,15 +1,19 @@
-# MarkLite npm 配置模板
-# 复制本文件为 .npmrc 后生效(.npmrc 已被 .gitignore 忽略,不会提交个人配置)
-#
-# 国内开发者推荐使用 npmmirror 镜像源以加速依赖下载:
-# registry=https://registry.npmmirror.com
-# ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/
-# ELECTRON_BUILDER_BINARIES_MIRROR=https://npmmirror.com/mirrors/electron-builder-binaries/
-#
-# 配置说明:
-# registry — npm 包下载源
-# ELECTRON_MIRROR — Electron 二进制文件下载源
-# ELECTRON_BUILDER_BINARIES_MIRROR — electron-builder 打包工具链下载源
-#
-# 注意:修改 .npmrc 后务必新开一个命令行窗口,否则环境变量不生效。
-# 详见 DEVSETUP.md
+# MarkLite npm 配置模板
+# 复制本文件为 .npmrc 后生效(.npmrc 已被 .gitignore 忽略,不会提交个人配置)
+#
+# 国内开发者推荐使用 npmmirror 镜像源以加速依赖下载:
+# registry=https://registry.npmmirror.com
+# ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/
+# ELECTRON_BUILDER_BINARIES_MIRROR=https://npmmirror.com/mirrors/electron-builder-binaries/
+#
+# @metona-team 私有 registry(metona-editor / metona-toast / metona-sqlark):
+# @metona-team:registry=https://git.metona.cn/api/packages/MetonaTeam/npm/
+# //git.metona.cn/api/packages/MetonaTeam/npm/:always-auth=true
+#
+# 配置说明:
+# registry — npm 包下载源
+# ELECTRON_MIRROR — Electron 二进制文件下载源
+# ELECTRON_BUILDER_BINARIES_MIRROR — electron-builder 打包工具链下载源
+#
+# 注意:修改 .npmrc 后务必新开一个命令行窗口,否则环境变量不生效。
+# 详见 DEVSETUP.md
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 01c9c16..87b368a 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,123 +1,123 @@
-# 贡献指南
-
-感谢你对 MarkLite 项目的关注!以下是参与贡献的指南。
-
-## 开发环境
-
-1. **前置要求**
- - Node.js >= 18.x
- - npm >= 9.x
- - Windows 10/11 x64
-
-2. **克隆并安装**
- ```bash
- git clone https://git.metona.cn/MetonaTeam/MarkLite.git
- cd MarkLite
- npm install
- ```
-
-3. **启动开发**
- ```bash
- npm run dev
- ```
-
-## 代码规范
-
-- **TypeScript**: 严格模式,所有函数参数需显式类型标注
-- **ESLint**: 提交前确保 `npm run lint` 通过
-- **Prettier**: 提交前确保 `npm run format:check` 通过
-- **Git Hooks**: pre-commit 自动执行 ESLint + typecheck
-
-## 分支策略
-
-- `master` — 稳定版本
-- `dev` — 开发分支
-- `feature/*` — 功能分支
-- `fix/*` — 修复分支
-
-## 提交规范
-
-使用语义化提交信息:
-
-```
-():
-
-[optional body]
-```
-
-类型(type):
-- `feat`: 新功能
-- `fix`: 修复 Bug
-- `docs`: 文档变更
-- `style`: 代码格式(不影响逻辑)
-- `refactor`: 重构
-- `perf`: 性能优化
-- `test`: 测试相关
-- `chore`: 构建/工具链变更
-
-示例:
-```
-feat(editor): 添加代码折叠功能
-fix(tab): 修复关闭标签后焦点丢失问题
-perf(markdown): 引入 processor LRU 缓存
-```
-
-## Pull Request 流程
-
-1. Fork 仓库并创建功能分支
-2. 确保所有检查通过:
- ```bash
- npm run lint # ESLint
- npm run typecheck # TypeScript 类型检查
- npm run test # 单元测试
- ```
-3. 编写清晰的 PR 描述,说明变更内容和原因
-4. 等待代码审查
-
-## 添加测试
-
-- 测试文件放在 `__tests__/` 目录下,命名为 `*.test.ts` 或 `*.test.tsx`
-- 使用 Vitest + React Testing Library
-- 至少覆盖 stores、hooks、lib 目录下的核心模块
-
-```bash
-# 运行测试
-npm run test
-
-# 监听模式
-npm run test:watch
-
-# 覆盖率报告
-npm run test:coverage
-```
-
-## 项目结构
-
-```
-src/
-├── main/ # 主进程 (Node.js)
-├── preload/ # 预加载脚本
-├── renderer/ # 渲染进程 (React)
-│ ├── components/ # UI 组件(Toolbar · TabBar · Editor · Sidebar 等)
-│ ├── stores/ # Zustand 状态管理(tabStore · editorStore · sidebarStore · autoSaveStore)
-│ ├── hooks/ # 自定义 Hooks(useTheme · useAutoSave · useKeyboard 等)
-│ ├── lib/ # 工具库(markdown · fileUtils · errorHandler · toast)
-│ ├── db/ # IndexedDB 持久化(schema · repositories)
-│ ├── types/ # TypeScript 类型定义
-│ └── styles/ # 全局样式(variables · global · markdown-body)
-└── shared/ # 主进程/渲染进程共享(IPC 通道 · 共享类型 · 常量)
-```
-
-### 编辑器架构
-
-MarkLite 使用 [MetonaEditor](https://git.metona.cn/MetonaTeam/MetonaEditor) v0.1.3 作为编辑器核心:
-
-- **三模式视图**(编辑 / 分屏 / 预览),由 MetonaEditor 内置工具栏切换
-- **渲染管线**:通过 `render` 钩子接入 unified/rehype 管线,处理图片路径修复和代码高亮
-- **插件**:searchReplace(搜索替换)+ imagePaste(粘贴图片)
-- **自动保存**:自定义 `useAutoSave` hook,通过 Electron IPC 保存到文件系统(非 localStorage)
-- **主题同步**:应用暗色模式与编辑器主题双向同步
-
-## 许可证
-
-贡献的代码将遵循项目的 [MIT 许可证](LICENSE)。
+# 贡献指南
+
+感谢你对 MarkLite 项目的关注!以下是参与贡献的指南。
+
+## 开发环境
+
+1. **前置要求**
+ - Node.js >= 18.x
+ - npm >= 9.x
+ - Windows 10/11 x64
+
+2. **克隆并安装**
+ ```bash
+ git clone https://git.metona.cn/MetonaTeam/MarkLite.git
+ cd MarkLite
+ npm install
+ ```
+
+3. **启动开发**
+ ```bash
+ npm run dev
+ ```
+
+## 代码规范
+
+- **TypeScript**: 严格模式,所有函数参数需显式类型标注
+- **ESLint**: 提交前确保 `npm run lint` 通过
+- **Prettier**: 提交前确保 `npm run format:check` 通过
+- **Git Hooks**: pre-commit 自动执行 ESLint + typecheck
+
+## 分支策略
+
+- `master` — 稳定版本
+- `dev` — 开发分支
+- `feature/*` — 功能分支
+- `fix/*` — 修复分支
+
+## 提交规范
+
+使用语义化提交信息:
+
+```
+():
+
+[optional body]
+```
+
+类型(type):
+- `feat`: 新功能
+- `fix`: 修复 Bug
+- `docs`: 文档变更
+- `style`: 代码格式(不影响逻辑)
+- `refactor`: 重构
+- `perf`: 性能优化
+- `test`: 测试相关
+- `chore`: 构建/工具链变更
+
+示例:
+```
+feat(editor): 添加代码折叠功能
+fix(tab): 修复关闭标签后焦点丢失问题
+perf(markdown): 引入 processor LRU 缓存
+```
+
+## Pull Request 流程
+
+1. Fork 仓库并创建功能分支
+2. 确保所有检查通过:
+ ```bash
+ npm run lint # ESLint
+ npm run typecheck # TypeScript 类型检查
+ npm run test # 单元测试
+ ```
+3. 编写清晰的 PR 描述,说明变更内容和原因
+4. 等待代码审查
+
+## 添加测试
+
+- 测试文件放在 `__tests__/` 目录下,命名为 `*.test.ts` 或 `*.test.tsx`
+- 使用 Vitest + React Testing Library
+- 至少覆盖 stores、hooks、lib 目录下的核心模块
+
+```bash
+# 运行测试
+npm run test
+
+# 监听模式
+npm run test:watch
+
+# 覆盖率报告
+npm run test:coverage
+```
+
+## 项目结构
+
+```
+src/
+├── main/ # 主进程 (Node.js)
+├── preload/ # 预加载脚本
+├── renderer/ # 渲染进程 (React)
+│ ├── components/ # UI 组件(Toolbar · TabBar · Editor · Sidebar 等)
+│ ├── stores/ # Zustand 状态管理(tabStore · editorStore · sidebarStore · autoSaveStore)
+│ ├── hooks/ # 自定义 Hooks(useTheme · useAutoSave · useKeyboard 等)
+│ ├── lib/ # 工具库(markdown · fileUtils · errorHandler · toast)
+│ ├── db/ # IndexedDB 持久化(schema · repositories)
+│ ├── types/ # TypeScript 类型定义
+│ └── styles/ # 全局样式(variables · global · markdown-body)
+└── shared/ # 主进程/渲染进程共享(IPC 通道 · 共享类型 · 常量)
+```
+
+### 编辑器架构
+
+MarkLite 使用 [MetonaEditor](https://git.metona.cn/MetonaTeam/MetonaEditor) v0.1.3 作为编辑器核心:
+
+- **三模式视图**(编辑 / 分屏 / 预览),由 MetonaEditor 内置工具栏切换
+- **渲染管线**:通过 `render` 钩子接入 unified/rehype 管线,处理图片路径修复和代码高亮
+- **插件**:searchReplace(搜索替换)+ imagePaste(粘贴图片)
+- **自动保存**:自定义 `useAutoSave` hook,通过 Electron IPC 保存到文件系统(非 localStorage)
+- **主题同步**:应用暗色模式与编辑器主题双向同步
+
+## 许可证
+
+贡献的代码将遵循项目的 [MIT 许可证](LICENSE)。
diff --git a/DESIGN.md b/DESIGN.md
index 030e59c..a5ba0a1 100644
--- a/DESIGN.md
+++ b/DESIGN.md
@@ -1,420 +1,433 @@
-# MarkLite v0.4.3 — 架构设计文档
-
-## 1. 项目概述
-
-MarkLite 是一款轻量级的 Windows 本地 Markdown 编辑器桌面应用程序。基于 Electron + React + TypeScript 构建,采用 MetonaEditor v0.1.14 编辑器(三模式视图 + 插件系统)、Zustand 状态管理、IndexedDB 持久化、unified/rehype Markdown 渲染管线。
-
-### 1.1 核心原则
-
-1. **类型安全** — 全量 TypeScript,所有 IPC 通信、状态、接口均有类型定义
-2. **模块化** — 源文件按职责分层:主进程 / 预加载 / 渲染进程(组件 / stores / hooks / lib / db / types)
-3. **安全隔离** — contextIsolation + nodeIntegration:false + CSP + rehype-sanitize
-4. **可测试性** — 业务逻辑(lib/)与 UI(components/)解耦
-
-## 2. 技术架构
-
-### 2.1 技术栈
-
-| 组件 | 技术 | 版本 | 说明 |
-|------|------|------|------|
-| 桌面框架 | Electron | v28 | 跨平台桌面应用框架 |
-| 前端框架 | React | v18 | 函数组件 + Hooks |
-| 类型系统 | TypeScript | v5.6 | 全量类型安全 |
-| 编辑器 | MetonaEditor | v0.1.14 | 零依赖 Markdown 编辑器,三模式视图 + 插件系统 |
-| 状态管理 | Zustand | v5 | 轻量级状态管理 |
-| 持久化 | Dexie.js (IndexedDB) | v4 | 标签页状态 / 用户设置 / 最近文件 |
-| Markdown 解析 | unified / remark / rehype | v11 | 插件化渲染管线(作为 MetonaEditor render 钩子) |
-| 代码高亮 | rehype-highlight | v7 | 基于 highlight.js |
-| Toast | @metona-team/metona-toast | v2.0.1 | 通知提示组件 |
-| 构建工具 | electron-vite | v3 | Electron + Vite,HMR 热更新 |
-| 打包工具 | electron-builder | v25 | Windows NSIS 安装包 |
-| 样式 | CSS Variables | — | 主题驱动,亮色/暗色 |
-
-### 2.2 进程架构
-
-```
-┌──────────────────────────────────────────────────────────────┐
-│ Main Process (src/main/) 5 文件 │
-│ index.ts 入口:窗口创建、app 生命周期、单实例锁 │
-│ ipc-handlers.ts 所有 ipcMain.handle 注册 │
-│ file-system.ts 文件读写、目录树构建、BOM 剥离 │
-│ file-watcher.ts fs.watch 封装(单文件 + 目录监听) │
-│ window-manager.ts 窗口创建、关闭拦截、单实例锁 │
-└───────────────────────┬──────────────────────────────────────┘
- │ contextBridge (安全隔离)
-┌───────────────────────▼──────────────────────────────────────┐
-│ Preload Script (src/preload/) 1 文件 │
-│ index.ts contextBridge 类型安全暴露 │
-│ electronAPI 22 个方法/事件的类型安全接口 │
-└───────────────────────┬──────────────────────────────────────┘
- │
-┌───────────────────────▼──────────────────────────────────────┐
-│ Renderer Process (src/renderer/) React 18 │
-│ │
-│ components/ Toolbar · TabBar · Editor · Sidebar │
-│ FileTree · OutlinePanel · WelcomeScreen │
-│ ConfirmDialog · ModifiedBanner │
-│ DropOverlay · ErrorBoundary · AboutDialog│
-│ LoadingSpinner · Icons │
-│ │
-│ stores/ (4) tabStore · editorStore · sidebarStore │
-│ autoSaveStore │
-│ hooks/ (15) useTheme · useSettingsInit · useKeyboard │
-│ useDragDrop · useFileWatch · useAutoSave │
-│ useIpcListeners · useFileOperations ... │
-│ lib/ (4) markdown · fileUtils · errorHandler │
-│ toast · constants │
-│ db/ (4) schema · tabRepository · settingsRepo │
-│ recentFilesRepository │
-│ types/ (5) tab · file · settings · ipc · index │
-│ styles/ (3) variables · global · markdown-body │
-└──────────────────────────────────────────────────────────────┘
-
-┌──────────────────────────────────────────────────────────────┐
-│ Shared (src/shared/) 3 文件 │
-│ ipc-channels.ts IPC 通道名常量 │
-│ types.ts 共享类型定义 │
-│ constants.ts 共享常量 (版本号、文件大小限制等) │
-└──────────────────────────────────────────────────────────────┘
-```
-
-### 2.3 安全模型
-
-| 层级 | 措施 | 说明 |
-|------|------|------|
-| Electron | `contextIsolation: true` | 渲染进程与主进程隔离 |
-| Electron | `nodeIntegration: false` | 渲染进程无法访问 Node.js API |
-| IPC | `contextBridge.exposeInMainWorld` | 仅暴露 18 个类型安全方法 + 4 个事件订阅 |
-| CSP | `default-src 'self'; script-src 'self'` | 阻断内联脚本、外部资源 |
-| HTML | `rehype-sanitize` | 渲染 Markdown 时过滤危险标签/属性 |
-| 链接 | 协议白名单 | 仅允许 `http:` / `https:` / `#` 锚点 |
-| 路径 | `validatePath()` | 防止路径遍历攻击 |
-
-## 3. 状态管理架构
-
-### 3.1 Zustand Stores
-
-```
-┌─────────────────────────────────────────────────────────┐
-│ App.tsx (根组件) │
-├─────────┬──────────┬──────────┬──────────────────────────┤
-│Toolbar │ TabBar │ Sidebar │ Editor (MetonaEditor) │
-├─────────┴──────────┴──────────┴──────────────────────────┤
-│ Zustand Stores │
-│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────────┐ │
-│ │ tabStore │ │editorStore│ │sidebarStore│ │autoSaveStore│ │
-│ │ - tabs │ │- viewMode│ │- tree │ │- isSaving │ │
-│ │- activeId│ │- darkMode│ │- expanded │ │- enabled │ │
-│ │ - mru │ │- extMod │ │- rootPath │ │ │ │
-│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └─────┬──────┘ │
-│ │ │ │ │ │
-│ ┌────▼────────────▼────────────▼──────────────▼──────┐ │
-│ │ IndexedDB (Dexie.js) │ │
-│ │ tabSnapshots │ settings │ recentFiles │ activeTab │ │
-│ └───────────────────────────────────────────────────┘ │
-└─────────────────────────────────────────────────────────┘
-```
-
-### 3.2 tabStore — 标签页状态
-
-```typescript
-interface TabState {
- tabs: Tab[] // 所有标签页
- activeTabId: string | null // 当前活动标签 ID
- mruStack: string[] // MRU 标签栈(Ctrl+Tab 切换)
-
- createTab(filePath?, content?) // 创建标签(同文件不重复打开)
- closeTab(tabId) // 关闭标签(自动切换到相邻标签)
- switchToTab(tabId) // 切换标签
- updateTabContent(tabId, content) // 更新内容(标记修改)
- setModified(tabId, modified) // 设置修改状态
- getActiveTab() // 获取当前标签
- updateTabScroll(tabId, scroll) // 更新滚动/光标位置
- saveToDB() // 保存到 IndexedDB(防抖 500ms)
- loadFromDB() // 从 IndexedDB 加载
-}
-```
-
-### 3.3 editorStore — 编辑器状态
-
-```typescript
-interface EditorState {
- viewMode: 'editor' | 'preview' | 'source' // 视图模式
- darkMode: boolean // 暗色主题
- externallyModified: { filePath: string } | null // 外部修改检测状态
- loadingStates: Record // 全局加载状态
-}
-
-// 模块级 getter — 供 Sidebar/OutlinePanel 访问 MetonaEditor 实例
-function getMetonaEditor(): MarkdownEditor | null
-function setMetonaEditorGetter(fn: () => MarkdownEditor | null): void
-```
-
-### 3.4 sidebarStore — 侧边栏状态
-
-```typescript
-interface SidebarState {
- isVisible: boolean // 是否显示
- rootPath: string | null // 当前打开的文件夹路径
- tree: FileNode[] // 目录树数据
- expandedDirs: string[] // 已展开的目录集合
- sidebarWidth: number // 侧边栏宽度 (180~500)
-}
-```
-
-## 4. 数据持久化 — IndexedDB
-
-通过 Dexie.js 封装 IndexedDB:
-
-### 4.1 数据库 Schema
-
-```typescript
-const db = new Dexie('MarkLite')
-
-db.version(1).stores({
- tabSnapshots: 'id, filePath, updatedAt', // 标签页快照
- settings: 'id', // 用户设置
- recentFiles: '++id, filePath, lastOpened', // 最近打开文件
- activeTab: 'id' // 当前活动标签
-})
-```
-
-### 4.2 数据模型
-
-| Store | 字段 | 说明 |
-|-------|------|------|
-| `tabSnapshots` | id, filePath, content, scrollTop, selectionStart, selectionEnd, isModified, updatedAt | 标签页状态快照 |
-| `settings` | id, darkMode, viewMode, sidebarCollapsed, sidebarWidth | 用户偏好设置 |
-| `recentFiles` | ++id, filePath, lastOpened | 最近打开文件列表 |
-| `activeTab` | id, activeTabId | 当前活动标签 ID |
-
-## 5. IPC 通信设计
-
-### 5.1 渲染进程 → 主进程(invoke)
-
-| 通道 | 参数 | 返回值 | 说明 |
-|------|------|--------|------|
-| `dialog:openFile` | 无 | `OpenFileResponse` | 打开文件对话框 |
-| `file:read` | `filePath` | `ReadFileResult` | 读取文件内容 |
-| `file:save` | `{ filePath, content }` | `SaveFileResult` | 保存文件 |
-| `file:saveAs` | `{ content }` | `SaveFileResult` | 另存为 |
-| `file:getCurrentPath` | 无 | `string \| null` | 获取当前文件路径 |
-| `file:stats` | `filePath` | `FileStatsResult` | 获取文件元信息 |
-| `file:reload` | 无 | `ReloadFileResult` | 重新加载当前文件 |
-| `tab:switched` | `filePath \| null` | `void` | 通知主进程切换活动文件 |
-| `window:forceClose` | 无 | `void` | 强制关闭窗口 |
-| `window:cancelClose` | 无 | `void` | 取消关闭 |
-| `dir:readTree` | `dirPath` | `ReadDirTreeResult` | 递归读取目录树 |
-| `dir:openDialog` | 无 | `string \| null` | 打开文件夹选择对话框 |
-| `dir:watch` | `dirPath` | `void` | 监听目录变化 |
-| `dir:unwatch` | 无 | `void` | 停止监听目录变化 |
-
-### 5.2 主进程 → 渲染进程(send)
-
-| 通道 | 数据 | 说明 |
-|------|------|------|
-| `file:openInTab` | `{ filePath, content }` | 在新标签中打开文件 |
-| `file:externallyModified` | `filePath` | 文件被外部修改 |
-| `window:confirmClose` | 无 | 请求确认关闭 |
-| `sidebar:dirChanged` | 无 | 目录结构变化 |
-
-## 6. 编辑器架构 — MetonaEditor v0.1.14
-
-### 6.1 三模式视图
-
-- **编辑模式 (edit)**:纯文本编辑器,显示 Markdown 源码
-- **分屏模式 (split)**:左侧编辑、右侧实时预览,同步滚动
-- **预览模式 (preview)**:仅显示渲染后的 HTML
-
-MetonaEditor 内置模式切换工具栏,与应用层的 viewMode store 双向同步,切换时自动持久化到 IndexedDB。
-
-### 6.2 内置功能
-
-| 功能 | 说明 |
-|------|------|
-| 格式化工具栏 | bold / italic / strikethrough / underline / code / h1-h3 / quote / ul / ol / indent / outdent / link / image / table / hr |
-| 搜索替换 | Ctrl+F / Ctrl+H,支持正则、大小写敏感 |
-| 历史栈 | undo / redo,防抖合并,可配置上限 |
-| 主题 | light / dark / auto / warm,CSS 变量驱动 |
-| 国际化 | zh-CN / en-US 完整翻译 |
-| 全屏模式 | 编辑器全屏展示 |
-
-### 6.3 插件体系
-
-通过 `plugins` 配置数组安装 MetonaEditor 预设插件:
-
-| 插件 | 说明 |
-|------|------|
-| searchReplace | Ctrl+F 查找、Ctrl+H 替换面板 |
-| imagePaste | Ctrl+V 粘贴剪贴板图片,自动转 base64 |
-
-> 注:autoSave 插件仅支持 localStorage,而 MarkLite 需要文件系统保存(Electron IPC),因此使用自定义 useAutoSave hook。
-
-### 6.4 渲染管线集成
-
-通过 MetonaEditor 的 `render` 钩子接入 unified/rehype 管线,实现:
-
-- **相对路径图片解析**:将相对路径转换为 `file://` 绝对路径
-- **XSS 防护**:rehype-sanitize 过滤危险标签
-- **代码高亮**:rehype-highlight 语法高亮
-- **处理器缓存**:LRU 缓存(最多 20 个),按文件路径分桶
-
-```
-Markdown 源码
- │
- ▼
-unified 管线(renderMarkdownSync)
- ├── remark-parse 解析为 MDAST
- ├── remark-gfm GFM 扩展
- ├── remark-rehype 转换为 HAST
- ├── rehype-raw 解析内联 HTML
- ├── rehype-sanitize 安全过滤
- ├── rehype-fixImages 相对路径 → file://
- ├── rehype-highlight 代码高亮
- └── rehype-stringify 序列化为 HTML
- │
- ▼
-MetonaEditor 预览区渲染
-```
-
-### 6.5 主题切换
-
-MetonaEditor 的 CSS 样式通过 wrapper 元素上的 inline `--md-*` CSS 变量驱动。主题切换流程:
-
-1. `MeEditor.setTheme(dark/light)` — 更新 documentElement 全局变量 + localStorage
-2. 手动覆写 `.me-wrapper` 上的 inline CSS 变量(`style.setProperty`)
-3. 双向同步:应用工具栏暗色按钮 ⇄ 编辑器主题
-
-### 6.6 内容同步
-
-- **编辑 → 存储**:`onChange` 回调 → `updateTabContent` + `setModified`
-- **标签切换**:`setValue(content, { silent: true })` 静默更新,避免重复触发 onChange
-- **滚动持久化**:切换标签时通过 DOM 查询 `textarea` / `.me-preview` 保存/恢复滚动位置
-
-## 7. Markdown 渲染管线
-
-```
-Markdown 文本
- │
- ▼
-remark-parse 解析为 MDAST
- │
- ▼
-remark-gfm 扩展 GFM 语法
- │
- ▼
-remark-rehype 转换为 HAST
- │
- ▼
-rehype-raw 解析内联 HTML
- │
- ▼
-rehype-sanitize 安全过滤
- │
- ▼
-rehype-fixImages 相对路径图片转 file:// URL
- │
- ▼
-rehype-highlight 代码语法高亮
- │
- ▼
-rehype-stringify 序列化为 HTML
- │
- ▼
-Renderer (MetonaEditor preview / Preview component)
-```
-
-## 8. UI 设计
-
-### 8.1 色彩方案
-
-#### 亮色主题
-
-| 角色 | CSS 变量 | 色值 |
-|------|----------|------|
-| 主色调 | `--primary` | `#1a73e8` |
-| 背景色 | `--bg` | `#ffffff` |
-| 次级背景 | `--bg-secondary` | `#f8f9fa` |
-| 文字色 | `--text` | `#333333` |
-| 边框色 | `--border` | `#e1e4e8` |
-
-#### 暗色主题
-
-| 角色 | CSS 变量 | 色值 |
-|------|----------|------|
-| 主色调 | `--primary` | `#8ab4f8` |
-| 背景色 | `--bg` | `#1e1e1e` |
-| 次级背景 | `--bg-secondary` | `#252526` |
-| 文字色 | `--text` | `#d4d4d4` |
-| 边框色 | `--border` | `#3e3e3e` |
-
-### 8.2 布局
-
-```
-┌──────────────────────────────────────────────────────────────────────────┐
-│ MarkLite - filename.md ─ □ ✕ │
-├──────────────────────────────────────────────────────────────────────────┤
-│ 📁 打开 │ 💾 保存 │ 自动 │ 🌙 🌐 ℹ️ │
-├──────────────────────────────────────────────────────────────────────────┤
-│ [file1.md] [file2.md] [未命名] [+] │
-├──────────┬───────────────────────────────────────────────────────────────┤
-│ 资源管理器 │ │
-│ ▼ project │ ┌─────────────────────────────────────────────┐ │
-│ 📁 src │ │ B I S U > │ H1 H2 H3 │ " 1. 2. ≡ ⇥ ⇤ │ │ │
-│ 📄 file1│ │ 🔗 🖼 ⊞ — │ ↶ ↷ │ 📝 ⇔ 👁 ⊞ │ │ │
-│ 📄 file2│ ├─────────────────────────────────────────────┤ │
-│ │ │ # Title │ Title │ │
-│ 文档大纲 │ │ │ ─────── │ │
-│ · Title │ │ content... │ content... │ │
-├──────────┴──┴─────────────────────────────────────────────┴──────────────┤
-│ (MetonaEditor 底栏: 字数/行数/阅读时间) │
-└──────────────────────────────────────────────────────────────────────────┘
-```
-
-## 9. 构建与发布
-
-### 9.1 开发模式
-
-```bash
-npm run dev # electron-vite dev(HMR 热更新)
-```
-
-### 9.2 生产构建
-
-```bash
-npm run build # electron-vite build + electron-builder --win
-npm run build:portable # 便携版(免安装)
-```
-
-### 9.3 打包配置
-
-- 输出格式:NSIS 安装包(.exe)
-- 目标平台:Windows x64
-- 应用图标:assets/icon.ico
-- 文件关联:`.md` / `.markdown` / `.txt`
-- 支持自定义安装目录、桌面/开始菜单快捷方式
-
-## 10. 依赖清单
-
-### 运行时依赖
-
-| 包名 | 版本 | 用途 |
-|------|------|------|
-| react / react-dom | ^18.3 | UI 框架 |
-| zustand | ^5.0 | 状态管理 |
-| dexie | ^4.0 | IndexedDB 封装 |
-| nanoid | ^5.0 | 唯一 ID 生成 |
-| @metona-team/metona-editor | 0.1.14 | Markdown 编辑器(零依赖) |
-| @metona-team/metona-toast | ^2.0.1 | Toast 通知组件 |
-| unified / remark / rehype | ^11.0 | Markdown 渲染管线 |
-| rehype-highlight | ^7.0 | 代码语法高亮 |
-
-### 开发依赖
-
-| 包名 | 版本 | 用途 |
-|------|------|------|
-| electron | ^28.0 | 桌面框架 |
-| electron-builder | ^25.0 | 打包工具 |
-| electron-vite | ^3.0 | 构建工具 |
-| typescript | ^5.6 | 类型系统 |
-| eslint | ^9.0 | 代码检查 |
+# MarkLite v0.4.3 — 架构设计文档
+
+## 1. 项目概述
+
+MarkLite 是一款轻量级的 Windows 本地 Markdown 编辑器桌面应用程序。基于 Electron + React + TypeScript 构建,采用 MetonaEditor v0.1.14 编辑器(三模式视图 + 插件系统)、Zustand 状态管理、IndexedDB 持久化、unified/rehype Markdown 渲染管线。
+
+### 1.1 核心原则
+
+1. **类型安全** — 全量 TypeScript,所有 IPC 通信、状态、接口均有类型定义
+2. **模块化** — 源文件按职责分层:主进程 / 预加载 / 渲染进程(组件 / stores / hooks / lib / db / types)
+3. **安全隔离** — contextIsolation + nodeIntegration:false + CSP + rehype-sanitize
+4. **可测试性** — 业务逻辑(lib/)与 UI(components/)解耦
+
+## 2. 技术架构
+
+### 2.1 技术栈
+
+| 组件 | 技术 | 版本 | 说明 |
+|------|------|------|------|
+| 桌面框架 | Electron | v28 | 跨平台桌面应用框架 |
+| 前端框架 | React | v18 | 函数组件 + Hooks |
+| 类型系统 | TypeScript | v5.6 | 全量类型安全 |
+| 编辑器 | MetonaEditor | v0.4.0 | 零依赖 Markdown 编辑器,三模式视图 + 插件系统 |
+| 状态管理 | Zustand | v5 | 轻量级状态管理 |
+| 持久化 | MetonaSqlark (IndexedDB) | v0.4.1 | 标签页状态 / 用户设置 / 最近文件(AriaEngine) |
+| Markdown 解析 | unified / remark / rehype | v11 | 插件化渲染管线(作为 MetonaEditor render 钩子) |
+| 代码高亮 | rehype-highlight | v7 | 基于 highlight.js |
+| Toast | @metona-team/metona-toast | v0.5.0 | 通知提示组件 |
+| 构建工具 | electron-vite | v3 | Electron + Vite,HMR 热更新 |
+| 打包工具 | electron-builder | v25 | Windows NSIS 安装包 |
+| 样式 | CSS Variables | — | 主题驱动,亮色/暗色 |
+
+### 2.2 进程架构
+
+```
+┌──────────────────────────────────────────────────────────────┐
+│ Main Process (src/main/) 5 文件 │
+│ index.ts 入口:窗口创建、app 生命周期、单实例锁 │
+│ ipc-handlers.ts 所有 ipcMain.handle 注册 │
+│ file-system.ts 文件读写、目录树构建、BOM 剥离 │
+│ file-watcher.ts fs.watch 封装(单文件 + 目录监听) │
+│ window-manager.ts 窗口创建、关闭拦截、单实例锁 │
+└───────────────────────┬──────────────────────────────────────┘
+ │ contextBridge (安全隔离)
+┌───────────────────────▼──────────────────────────────────────┐
+│ Preload Script (src/preload/) 1 文件 │
+│ index.ts contextBridge 类型安全暴露 │
+│ electronAPI 22 个方法/事件的类型安全接口 │
+└───────────────────────┬──────────────────────────────────────┘
+ │
+┌───────────────────────▼──────────────────────────────────────┐
+│ Renderer Process (src/renderer/) React 18 │
+│ │
+│ components/ Toolbar · TabBar · Editor · Sidebar │
+│ FileTree · OutlinePanel · WelcomeScreen │
+│ ConfirmDialog · ModifiedBanner │
+│ DropOverlay · ErrorBoundary · AboutDialog│
+│ LoadingSpinner · Icons │
+│ │
+│ stores/ (4) tabStore · editorStore · sidebarStore │
+│ autoSaveStore │
+│ hooks/ (15) useTheme · useSettingsInit · useKeyboard │
+│ useDragDrop · useFileWatch · useAutoSave │
+│ useIpcListeners · useFileOperations ... │
+│ lib/ (4) markdown · fileUtils · errorHandler │
+│ toast · constants │
+│ db/ (4) schema · tabRepository · settingsRepo │
+│ recentFilesRepository │
+│ types/ (5) tab · file · settings · ipc · index │
+│ styles/ (3) variables · global · markdown-body │
+└──────────────────────────────────────────────────────────────┘
+
+┌──────────────────────────────────────────────────────────────┐
+│ Shared (src/shared/) 3 文件 │
+│ ipc-channels.ts IPC 通道名常量 │
+│ types.ts 共享类型定义 │
+│ constants.ts 共享常量 (版本号、文件大小限制等) │
+└──────────────────────────────────────────────────────────────┘
+```
+
+### 2.3 安全模型
+
+| 层级 | 措施 | 说明 |
+|------|------|------|
+| Electron | `contextIsolation: true` | 渲染进程与主进程隔离 |
+| Electron | `nodeIntegration: false` | 渲染进程无法访问 Node.js API |
+| IPC | `contextBridge.exposeInMainWorld` | 仅暴露 18 个类型安全方法 + 4 个事件订阅 |
+| CSP | `default-src 'self'; script-src 'self'` | 阻断内联脚本、外部资源 |
+| HTML | `rehype-sanitize` | 渲染 Markdown 时过滤危险标签/属性 |
+| 链接 | 协议白名单 | 仅允许 `http:` / `https:` / `#` 锚点 |
+| 路径 | `validatePath()` | 防止路径遍历攻击 |
+
+## 3. 状态管理架构
+
+### 3.1 Zustand Stores
+
+```
+┌─────────────────────────────────────────────────────────┐
+│ App.tsx (根组件) │
+├─────────┬──────────┬──────────┬──────────────────────────┤
+│Toolbar │ TabBar │ Sidebar │ Editor (MetonaEditor) │
+├─────────┴──────────┴──────────┴──────────────────────────┤
+│ Zustand Stores │
+│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────────┐ │
+│ │ tabStore │ │editorStore│ │sidebarStore│ │autoSaveStore│ │
+│ │ - tabs │ │- viewMode│ │- tree │ │- isSaving │ │
+│ │- activeId│ │- darkMode│ │- expanded │ │- enabled │ │
+│ │ - mru │ │- extMod │ │- rootPath │ │ │ │
+│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └─────┬──────┘ │
+│ │ │ │ │ │
+│ ┌────▼────────────▼────────────▼──────────────▼──────┐ │
+│ │ IndexedDB (MetonaSqlark) │ │
+│ │ tabSnapshots │ settings │ recentFiles │ activeTab │ │
+│ └───────────────────────────────────────────────────┘ │
+└─────────────────────────────────────────────────────────┘
+```
+
+### 3.2 tabStore — 标签页状态
+
+```typescript
+interface TabState {
+ tabs: Tab[] // 所有标签页
+ activeTabId: string | null // 当前活动标签 ID
+ mruStack: string[] // MRU 标签栈(Ctrl+Tab 切换)
+
+ createTab(filePath?, content?) // 创建标签(同文件不重复打开)
+ closeTab(tabId) // 关闭标签(自动切换到相邻标签)
+ switchToTab(tabId) // 切换标签
+ updateTabContent(tabId, content) // 更新内容(标记修改)
+ setModified(tabId, modified) // 设置修改状态
+ getActiveTab() // 获取当前标签
+ updateTabScroll(tabId, scroll) // 更新滚动/光标位置
+ saveToDB() // 保存到 IndexedDB(防抖 500ms)
+ loadFromDB() // 从 IndexedDB 加载
+}
+```
+
+### 3.3 editorStore — 编辑器状态
+
+```typescript
+interface EditorState {
+ viewMode: 'editor' | 'preview' | 'source' // 视图模式
+ darkMode: boolean // 暗色主题
+ externallyModified: { filePath: string } | null // 外部修改检测状态
+ loadingStates: Record // 全局加载状态
+}
+
+// 模块级 getter — 供 Sidebar/OutlinePanel 访问 MetonaEditor 实例
+function getMetonaEditor(): MarkdownEditor | null
+function setMetonaEditorGetter(fn: () => MarkdownEditor | null): void
+```
+
+### 3.4 sidebarStore — 侧边栏状态
+
+```typescript
+interface SidebarState {
+ isVisible: boolean // 是否显示
+ rootPath: string | null // 当前打开的文件夹路径
+ tree: FileNode[] // 目录树数据
+ expandedDirs: string[] // 已展开的目录集合
+ sidebarWidth: number // 侧边栏宽度 (180~500)
+}
+```
+
+## 4. 数据持久化 — IndexedDB
+
+v0.5.0: 由 Dexie.js 迁移至 MetonaSqlark(AriaEngine:自研 LSM-Tree + WAL + MVCC 存储引擎,对标 SQLite)。
+MetonaSqlark 的 create() 为异步,采用懒加载单例(getDb()),
+表结构幂等创建(查表名后 defineTable),数据库名更换为 MarkLiteV2(旧 Dexie 数据已放弃)。
+
+### 4.1 数据库 Schema
+
+```typescript
+// schema.ts — 懒加载单例
+let dbPromise: Promise | null = null
+export function getDb(): Promise {
+ if (!dbPromise) {
+ dbPromise = MetonaSqlark.create({
+ name: 'MarkLiteV2',
+ mode: 'aria', // AriaEngine: LSM-Tree + WAL + MVCC 快照隔离
+ diskEngine: 'indexeddb', // 底层存储后端(indexeddb | opfs | memory)
+ version: 1,
+ }).then(async (db) => {
+ if (!(await db.getTableNames()).includes('tabSnapshots')) {
+ await db.defineTable('tabSnapshots', { id: { type: 'string', primaryKey: true }, ... })
+ }
+ // settings / recentFiles / activeTab 同理
+ return db
+ })
+ }
+ return dbPromise
+}
+```
+
+### 4.2 数据模型
+
+| Store | 字段 | 说明 |
+|-------|------|------|
+| `tabSnapshots` | id(PK), filePath, content, scrollTop, selectionStart, selectionEnd, isModified, updatedAt(index) | 标签页状态快照 |
+| `settings` | id(PK), themeMode, viewMode, sidebarCollapsed, sidebarWidth | 用户偏好设置 |
+| `recentFiles` | filePath(PK), lastOpened(index) | 最近打开文件列表(v0.5.0 改用 filePath 主键,sqlark 无自增) |
+| `activeTab` | id(PK), activeTabId | 当前活动标签 ID |
+
+## 5. IPC 通信设计
+
+### 5.1 渲染进程 → 主进程(invoke)
+
+| 通道 | 参数 | 返回值 | 说明 |
+|------|------|--------|------|
+| `dialog:openFile` | 无 | `OpenFileResponse` | 打开文件对话框 |
+| `file:read` | `filePath` | `ReadFileResult` | 读取文件内容 |
+| `file:save` | `{ filePath, content }` | `SaveFileResult` | 保存文件 |
+| `file:saveAs` | `{ content }` | `SaveFileResult` | 另存为 |
+| `file:getCurrentPath` | 无 | `string \| null` | 获取当前文件路径 |
+| `file:stats` | `filePath` | `FileStatsResult` | 获取文件元信息 |
+| `file:reload` | 无 | `ReloadFileResult` | 重新加载当前文件 |
+| `tab:switched` | `filePath \| null` | `void` | 通知主进程切换活动文件 |
+| `window:forceClose` | 无 | `void` | 强制关闭窗口 |
+| `window:cancelClose` | 无 | `void` | 取消关闭 |
+| `dir:readTree` | `dirPath` | `ReadDirTreeResult` | 递归读取目录树 |
+| `dir:openDialog` | 无 | `string \| null` | 打开文件夹选择对话框 |
+| `dir:watch` | `dirPath` | `void` | 监听目录变化 |
+| `dir:unwatch` | 无 | `void` | 停止监听目录变化 |
+
+### 5.2 主进程 → 渲染进程(send)
+
+| 通道 | 数据 | 说明 |
+|------|------|------|
+| `file:openInTab` | `{ filePath, content }` | 在新标签中打开文件 |
+| `file:externallyModified` | `filePath` | 文件被外部修改 |
+| `window:confirmClose` | 无 | 请求确认关闭 |
+| `sidebar:dirChanged` | 无 | 目录结构变化 |
+
+## 6. 编辑器架构 — MetonaEditor v0.1.14
+
+### 6.1 三模式视图
+
+- **编辑模式 (edit)**:纯文本编辑器,显示 Markdown 源码
+- **分屏模式 (split)**:左侧编辑、右侧实时预览,同步滚动
+- **预览模式 (preview)**:仅显示渲染后的 HTML
+
+MetonaEditor 内置模式切换工具栏,与应用层的 viewMode store 双向同步,切换时自动持久化到 IndexedDB。
+
+### 6.2 内置功能
+
+| 功能 | 说明 |
+|------|------|
+| 格式化工具栏 | bold / italic / strikethrough / underline / code / h1-h3 / quote / ul / ol / indent / outdent / link / image / table / hr |
+| 搜索替换 | Ctrl+F / Ctrl+H,支持正则、大小写敏感 |
+| 历史栈 | undo / redo,防抖合并,可配置上限 |
+| 主题 | light / dark / auto / warm,CSS 变量驱动 |
+| 国际化 | zh-CN / en-US 完整翻译 |
+| 全屏模式 | 编辑器全屏展示 |
+
+### 6.3 插件体系
+
+通过 `plugins` 配置数组安装 MetonaEditor 预设插件:
+
+| 插件 | 说明 |
+|------|------|
+| searchReplace | Ctrl+F 查找、Ctrl+H 替换面板 |
+| imagePaste | Ctrl+V 粘贴剪贴板图片,自动转 base64 |
+
+> 注:autoSave 插件仅支持 localStorage,而 MarkLite 需要文件系统保存(Electron IPC),因此使用自定义 useAutoSave hook。
+
+### 6.4 渲染管线集成
+
+通过 MetonaEditor 的 `render` 钩子接入 unified/rehype 管线,实现:
+
+- **相对路径图片解析**:将相对路径转换为 `file://` 绝对路径
+- **XSS 防护**:rehype-sanitize 过滤危险标签
+- **代码高亮**:rehype-highlight 语法高亮
+- **处理器缓存**:LRU 缓存(最多 20 个),按文件路径分桶
+
+```
+Markdown 源码
+ │
+ ▼
+unified 管线(renderMarkdownSync)
+ ├── remark-parse 解析为 MDAST
+ ├── remark-gfm GFM 扩展
+ ├── remark-rehype 转换为 HAST
+ ├── rehype-raw 解析内联 HTML
+ ├── rehype-sanitize 安全过滤
+ ├── rehype-fixImages 相对路径 → file://
+ ├── rehype-highlight 代码高亮
+ └── rehype-stringify 序列化为 HTML
+ │
+ ▼
+MetonaEditor 预览区渲染
+```
+
+### 6.5 主题切换
+
+MetonaEditor 的 CSS 样式通过 wrapper 元素上的 inline `--md-*` CSS 变量驱动。主题切换流程:
+
+1. `MeEditor.setTheme(dark/light)` — 更新 documentElement 全局变量 + localStorage
+2. 手动覆写 `.me-wrapper` 上的 inline CSS 变量(`style.setProperty`)
+3. 双向同步:应用工具栏暗色按钮 ⇄ 编辑器主题
+
+### 6.6 内容同步
+
+- **编辑 → 存储**:`onChange` 回调 → `updateTabContent` + `setModified`
+- **标签切换**:`setValue(content, { silent: true })` 静默更新,避免重复触发 onChange
+- **滚动持久化**:切换标签时通过 DOM 查询 `textarea` / `.me-preview` 保存/恢复滚动位置
+
+## 7. Markdown 渲染管线
+
+```
+Markdown 文本
+ │
+ ▼
+remark-parse 解析为 MDAST
+ │
+ ▼
+remark-gfm 扩展 GFM 语法
+ │
+ ▼
+remark-rehype 转换为 HAST
+ │
+ ▼
+rehype-raw 解析内联 HTML
+ │
+ ▼
+rehype-sanitize 安全过滤
+ │
+ ▼
+rehype-fixImages 相对路径图片转 file:// URL
+ │
+ ▼
+rehype-highlight 代码语法高亮
+ │
+ ▼
+rehype-stringify 序列化为 HTML
+ │
+ ▼
+Renderer (MetonaEditor preview / Preview component)
+```
+
+## 8. UI 设计
+
+### 8.1 色彩方案
+
+#### 亮色主题
+
+| 角色 | CSS 变量 | 色值 |
+|------|----------|------|
+| 主色调 | `--primary` | `#1a73e8` |
+| 背景色 | `--bg` | `#ffffff` |
+| 次级背景 | `--bg-secondary` | `#f8f9fa` |
+| 文字色 | `--text` | `#333333` |
+| 边框色 | `--border` | `#e1e4e8` |
+
+#### 暗色主题
+
+| 角色 | CSS 变量 | 色值 |
+|------|----------|------|
+| 主色调 | `--primary` | `#8ab4f8` |
+| 背景色 | `--bg` | `#1e1e1e` |
+| 次级背景 | `--bg-secondary` | `#252526` |
+| 文字色 | `--text` | `#d4d4d4` |
+| 边框色 | `--border` | `#3e3e3e` |
+
+### 8.2 布局
+
+```
+┌──────────────────────────────────────────────────────────────────────────┐
+│ MarkLite - filename.md ─ □ ✕ │
+├──────────────────────────────────────────────────────────────────────────┤
+│ 📁 打开 │ 💾 保存 │ 自动 │ 🌙 🌐 ℹ️ │
+├──────────────────────────────────────────────────────────────────────────┤
+│ [file1.md] [file2.md] [未命名] [+] │
+├──────────┬───────────────────────────────────────────────────────────────┤
+│ 资源管理器 │ │
+│ ▼ project │ ┌─────────────────────────────────────────────┐ │
+│ 📁 src │ │ B I S U > │ H1 H2 H3 │ " 1. 2. ≡ ⇥ ⇤ │ │ │
+│ 📄 file1│ │ 🔗 🖼 ⊞ — │ ↶ ↷ │ 📝 ⇔ 👁 ⊞ │ │ │
+│ 📄 file2│ ├─────────────────────────────────────────────┤ │
+│ │ │ # Title │ Title │ │
+│ 文档大纲 │ │ │ ─────── │ │
+│ · Title │ │ content... │ content... │ │
+├──────────┴──┴─────────────────────────────────────────────┴──────────────┤
+│ (MetonaEditor 底栏: 字数/行数/阅读时间) │
+└──────────────────────────────────────────────────────────────────────────┘
+```
+
+## 9. 构建与发布
+
+### 9.1 开发模式
+
+```bash
+npm run dev # electron-vite dev(HMR 热更新)
+```
+
+### 9.2 生产构建
+
+```bash
+npm run build # electron-vite build + electron-builder --win
+npm run build:portable # 便携版(免安装)
+```
+
+### 9.3 打包配置
+
+- 输出格式:NSIS 安装包(.exe)
+- 目标平台:Windows x64
+- 应用图标:assets/icon.ico
+- 文件关联:`.md` / `.markdown` / `.txt`
+- 支持自定义安装目录、桌面/开始菜单快捷方式
+
+## 10. 依赖清单
+
+### 运行时依赖
+
+| 包名 | 版本 | 用途 |
+|------|------|------|
+| react / react-dom | ^18.3 | UI 框架 |
+| zustand | ^5.0 | 状态管理 |
+| @metona-team/metona-sqlark | 0.4.1 | 前端关系型数据库(IndexedDB) |
+| nanoid | ^5.0 | 唯一 ID 生成 |
+| @metona-team/metona-editor | 0.4.0 | Markdown 编辑器(零依赖) |
+| @metona-team/metona-toast | 0.5.0 | Toast 通知组件 |
+| unified / remark / rehype | ^11.0 | Markdown 渲染管线 |
+| rehype-highlight | ^7.0 | 代码语法高亮 |
+
+### 开发依赖
+
+| 包名 | 版本 | 用途 |
+|------|------|------|
+| electron | ^28.0 | 桌面框架 |
+| electron-builder | ^25.0 | 打包工具 |
+| electron-vite | ^3.0 | 构建工具 |
+| typescript | ^5.6 | 类型系统 |
+| eslint | ^9.0 | 代码检查 |
diff --git a/DEVSETUP.md b/DEVSETUP.md
index 2d92b9f..fdd3b26 100644
--- a/DEVSETUP.md
+++ b/DEVSETUP.md
@@ -1,93 +1,93 @@
-# MarkLite v0.4.3 — 开发环境配置指南
-
-以下涵盖从 Node 版本管理、镜像源配置到 electron-builder 打包的全流程。
-
-## 一、Node 版本管理(nvm)
-
-安装 nvm-windows 后,使用以下命令管理 Node 版本:
-
-```bash
-# 安装需要的版本(以 Node 18 为例)
-nvm install 18
-
-# 设为当前终端使用的版本
-nvm use 18
-
-# 设为默认版本(新终端自动生效)
-nvm alias default 18
-```
-
-## 二、配置镜像源
-
-npm v9+ 已不支持 `npm config set` 设置自定义键名,必须直接编辑 `.npmrc` 文件。
-
-### 项目级 .npmrc(推荐)
-
-在项目根目录下创建或编辑 `.npmrc` 文件,写入以下内容:
-
-```
-registry=https://registry.npmmirror.com
-@metona-team:registry=https://git.metona.cn/api/packages/MetonaTeam/npm/
-//git.metona.cn/api/packages/MetonaTeam/npm/:_auth=
-//git.metona.cn/api/packages/MetonaTeam/npm/:always-auth=true
-
-# Electron 二进制下载镜像
-ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/
-ELECTRON_BUILDER_BINARIES_MIRROR=https://npmmirror.com/mirrors/electron-builder-binaries/
-```
-
-> 注:`@metona-team` scope 指向 MetonaTeam 私有 npm registry,用于安装 `@metona-team/metona-editor` 和 `@metona-team/metona-toast`。如需使用公开版本可参考 `.npmrc.example`。
-
-如果想让所有项目都生效,编辑全局 `.npmrc`(可通过 `npm config get userconfig` 查看路径),内容同上。
-
-## 三、配置文件说明
-
-| 配置项 | 作用 |
-|:-------|:-----|
-| `registry` | npm 包下载源,避免从 npmjs.org 拉包缓慢 |
-| `@metona-team:registry` | MetonaTeam 私有包 scope registry |
-| `ELECTRON_MIRROR` | Electron 二进制文件(electron.exe 等)的下载源 |
-| `ELECTRON_BUILDER_BINARIES_MIRROR` | electron-builder 打包工具链的下载源 |
-
-## 四、开始打包
-
-> **关键:** 保存 `.npmrc` 后务必新开一个命令行窗口,否则环境变量不生效。
-
-```bash
-# 1. 清除旧缓存,确保不走之前的错误源
-npm cache clean --force
-
-# 2. 安装依赖(如果还没装或 node_modules 不完整)
-npm install
-
-# 3. 执行构建
-npm run build
-```
-
-构建成功后,安装包会生成在 `dist/` 目录下。
-
-## 五、一次性完整操作步骤总结
-
-```bash
-# ① 确保 Node 版本正确
-nvm use 18
-
-# ② 在项目根目录创建 .npmrc,写入:
-# registry=https://registry.npmmirror.com
-# @metona-team:registry=https://git.metona.cn/api/packages/MetonaTeam/npm/
-# //git.metona.cn/api/packages/MetonaTeam/npm/:_auth=
-# ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/
-# ELECTRON_BUILDER_BINARIES_MIRROR=https://npmmirror.com/mirrors/electron-builder-binaries/
-
-# ③ 关闭当前终端,新开一个终端,然后执行:
-npm cache clean --force
-npm install
-npm run build
-```
-
-## 六、常见问题排查
-
-- **`ELECTRON_MIRROR is not a valid npm option`**:npm 版本太新,禁止用 `npm config set` 设置自定义键,改用编辑 `.npmrc` 文件解决。
-- **`@metona-team` 包安装失败**:检查 `.npmrc` 中 `@metona-team:registry` 和认证 token 配置是否正确。
-- **下载 Electron 还是走 GitHub**:检查 `.npmrc` 文件名是否正确(不要写成 `.npmrc.txt`),以及是否重新打开了终端。
-- **nvm 切换版本后 node 没变**:确保以管理员身份运行终端,且 nvm 安装路径没有中文或空格。
+# MarkLite v0.5.0 — 开发环境配置指南
+
+以下涵盖从 Node 版本管理、镜像源配置到 electron-builder 打包的全流程。
+
+## 一、Node 版本管理(nvm)
+
+安装 nvm-windows 后,使用以下命令管理 Node 版本:
+
+```bash
+# 安装需要的版本(以 Node 18 为例)
+nvm install 18
+
+# 设为当前终端使用的版本
+nvm use 18
+
+# 设为默认版本(新终端自动生效)
+nvm alias default 18
+```
+
+## 二、配置镜像源
+
+npm v9+ 已不支持 `npm config set` 设置自定义键名,必须直接编辑 `.npmrc` 文件。
+
+### 项目级 .npmrc(推荐)
+
+在项目根目录下创建或编辑 `.npmrc` 文件,写入以下内容:
+
+```
+registry=https://registry.npmmirror.com
+@metona-team:registry=https://git.metona.cn/api/packages/MetonaTeam/npm/
+//git.metona.cn/api/packages/MetonaTeam/npm/:_auth=
+//git.metona.cn/api/packages/MetonaTeam/npm/:always-auth=true
+
+# Electron 二进制下载镜像
+ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/
+ELECTRON_BUILDER_BINARIES_MIRROR=https://npmmirror.com/mirrors/electron-builder-binaries/
+```
+
+> 注:`@metona-team` scope 指向 MetonaTeam 私有 npm registry,用于安装 `@metona-team/metona-editor` 和 `@metona-team/metona-toast`。如需使用公开版本可参考 `.npmrc.example`。
+
+如果想让所有项目都生效,编辑全局 `.npmrc`(可通过 `npm config get userconfig` 查看路径),内容同上。
+
+## 三、配置文件说明
+
+| 配置项 | 作用 |
+|:-------|:-----|
+| `registry` | npm 包下载源,避免从 npmjs.org 拉包缓慢 |
+| `@metona-team:registry` | MetonaTeam 私有包 scope registry |
+| `ELECTRON_MIRROR` | Electron 二进制文件(electron.exe 等)的下载源 |
+| `ELECTRON_BUILDER_BINARIES_MIRROR` | electron-builder 打包工具链的下载源 |
+
+## 四、开始打包
+
+> **关键:** 保存 `.npmrc` 后务必新开一个命令行窗口,否则环境变量不生效。
+
+```bash
+# 1. 清除旧缓存,确保不走之前的错误源
+npm cache clean --force
+
+# 2. 安装依赖(如果还没装或 node_modules 不完整)
+npm install
+
+# 3. 执行构建
+npm run build
+```
+
+构建成功后,安装包会生成在 `dist/` 目录下。
+
+## 五、一次性完整操作步骤总结
+
+```bash
+# ① 确保 Node 版本正确
+nvm use 18
+
+# ② 在项目根目录创建 .npmrc,写入:
+# registry=https://registry.npmmirror.com
+# @metona-team:registry=https://git.metona.cn/api/packages/MetonaTeam/npm/
+# //git.metona.cn/api/packages/MetonaTeam/npm/:_auth=
+# ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/
+# ELECTRON_BUILDER_BINARIES_MIRROR=https://npmmirror.com/mirrors/electron-builder-binaries/
+
+# ③ 关闭当前终端,新开一个终端,然后执行:
+npm cache clean --force
+npm install
+npm run build
+```
+
+## 六、常见问题排查
+
+- **`ELECTRON_MIRROR is not a valid npm option`**:npm 版本太新,禁止用 `npm config set` 设置自定义键,改用编辑 `.npmrc` 文件解决。
+- **`@metona-team` 包安装失败**:检查 `.npmrc` 中 `@metona-team:registry` 和认证 token 配置是否正确。
+- **下载 Electron 还是走 GitHub**:检查 `.npmrc` 文件名是否正确(不要写成 `.npmrc.txt`),以及是否重新打开了终端。
+- **nvm 切换版本后 node 没变**:确保以管理员身份运行终端,且 nvm 安装路径没有中文或空格。
diff --git a/README.md b/README.md
index e09e162..11d1726 100644
--- a/README.md
+++ b/README.md
@@ -14,12 +14,12 @@
-
+
基于 Electron + React + TypeScript 构建的现代化 Markdown 桌面编辑器。
- 多标签页 · 实时预览 · 代码高亮 · 暗色主题 · 拖拽打开 · 搜索替换 · 文件树 · IndexedDB 持久化。
+ 多标签页 · 实时预览 · 代码高亮 · 暗色主题 · 拖拽打开 · 搜索替换 · 文件树 · Mermaid 图表 · 状态持久化。
---
@@ -30,16 +30,17 @@
|------|------|
| 📑 **多标签页** | 同时打开多个文件,Ctrl+T 新建、Ctrl+W 关闭、Ctrl+Tab MRU 切换 |
| 📂 **文件打开** | 按钮打开 / 拖拽打开 / 文件关联(双击 .md) / 命令行参数 |
-| ✏️ **编辑器** | 基于 MetonaEditor 的代码+预览编辑器,内置格式化工具栏、三模式切换(编辑/分屏/预览)、搜索替换、撤销重做、粘贴图片转 base64 |
+| ✏️ **编辑器** | 基于 MetonaEditor 的代码+预览编辑器,内置格式化工具栏、浮动格式栏、三模式切换(编辑/分屏/预览)、搜索替换、撤销重做、粘贴图片转 base64 |
| 👁 **实时预览** | 分屏模式下左侧编辑、右侧实时预览,基于 unified/rehype 管线渲染 |
| 🔤 **代码高亮** | 基于 rehype-highlight,支持 180+ 种编程语言语法高亮 |
| 🎨 **三种视图** | 编辑模式 / 分屏模式 / 预览模式,自由切换 |
-| 🌙 **暗色主题** | 一键切换亮色/暗色主题,偏好自动记忆(IndexedDB),编辑器主题同步切换 |
+| 🌙 **暗色主题** | 一键切换亮色/暗色/暖色主题,偏好自动记忆(MetonaSqlark),编辑器主题同步切换 |
| 🔔 **文件监听** | 外部修改文件时自动提示,支持重新加载或忽略 |
| 💾 **文件保存** | 保存 / 另存为,支持 .md / .markdown / .txt 格式 |
| 🔍 **搜索替换** | Ctrl+F 搜索、Ctrl+H 替换,支持正则表达式、大小写敏感 |
| 📁 **文件树** | 侧边栏浏览项目目录,点击打开文件,目录变化自动刷新 |
-| 💾 **状态持久化** | 标签页状态、用户设置通过 IndexedDB 持久化,关闭后可恢复 |
+| 📊 **Mermaid 图表** | 代码块中渲染 Mermaid 流程图 / 时序图 / 甘特图等 |
+| 💾 **状态持久化** | 标签页状态、用户设置通过 MetonaSqlark(AriaEngine)持久化,关闭后可恢复 |
| ⌨️ **快捷键** | 完整的键盘快捷键支持,操作高效 |
| 📦 **NSIS 安装包** | 一键打包为 Windows exe 安装程序 / 便携版 |
| 🖼️ **粘贴图片** | Ctrl+V 粘贴剪贴板图片,自动转为 base64 内嵌 |
@@ -134,7 +135,9 @@ npm run test:coverage
| `Ctrl + H` | 搜索并替换 |
| `Ctrl + Z` / `Ctrl + Y` | 撤销 / 重做 |
| `Ctrl + B` / `Ctrl + I` | 粗体 / 斜体(编辑器内置) |
+| `Ctrl + E` / `Ctrl + K` / `Ctrl + Q` | 行内代码 / 链接 / 引用(编辑器内置) |
| `Ctrl + 1/2/3` | 切换模式(编辑器内置) |
+| `?` | 快捷键帮助面板(编辑器内置) |
## 🛠️ 技术栈
@@ -143,12 +146,12 @@ npm run test:coverage
| 桌面框架 | [Electron](https://www.electronjs.org/) v28 | 跨平台桌面应用框架 |
| 前端框架 | [React](https://react.dev/) v18 | 函数组件 + Hooks |
| 类型系统 | [TypeScript](https://www.typescriptlang.org/) v5.6 | 全量类型安全 |
-| 编辑器 | [MetonaEditor](https://git.metona.cn/MetonaTeam/MetonaEditor) v0.1.14 | 零依赖 Markdown 编辑器,三模式视图 + 插件系统 |
+| 编辑器 | [MetonaEditor](https://git.metona.cn/MetonaTeam/MetonaEditor) v0.4.0 | 零依赖 Markdown 编辑器,三模式视图 + 浮动格式栏 + 插件系统 |
| 状态管理 | [Zustand](https://zustand-demo.pmnd.rs/) v5 | 轻量级状态管理 |
-| 持久化 | [Dexie.js](https://dexie.org/) v4 (IndexedDB) | 标签页状态 & 用户设置持久化 |
+| 持久化 | [MetonaSqlark](https://git.metona.cn/MetonaTeam/MetonaSqlark) v0.4.1 (IndexedDB, AriaEngine) | 标签页状态 & 用户设置持久化 |
| Markdown 解析 | [unified](https://unifiedjs.com/) / [remark](https://remark.js.org/) / [rehype](https://rehype.js.org/) | 插件化 Markdown 渲染管线 |
| 代码高亮 | [rehype-highlight](https://github.com/rehypejs/rehype-highlight) | 基于 highlight.js 的语法高亮 |
-| Toast | [@metona-team/metona-toast](https://git.metona.cn/MetonaTeam/-/packages/npm/@metona-team%2Fmetona-toast) v2.0.1 | 通知提示组件 |
+| Toast | [@metona-team/metona-toast](https://git.metona.cn/MetonaTeam/-/packages/npm/@metona-team%2Fmetona-toast) v0.5.0 | 通知提示组件 |
| 构建工具 | [electron-vite](https://electron-vite.org/) v3 | Electron + Vite 集成,HMR 热更新 |
| 打包工具 | [electron-builder](https://www.electron.build/) | 生成 exe 安装包 |
| 样式 | CSS Variables | 主题驱动,亮色/暗色切换 |
@@ -223,8 +226,8 @@ MarkLite/
│ │ │ ├── toast.ts # Toast 通知(MetonaToast)
│ │ │ └── constants.ts # 常量定义
│ │ │
-│ │ ├── db/ # IndexedDB 持久化层
-│ │ │ ├── schema.ts # Dexie 数据库定义
+│ │ ├── db/ # MetonaSqlark 持久化层
+│ │ │ ├── schema.ts # 数据库定义(懒初始化单例)
│ │ │ ├── tabRepository.ts # 标签页 CRUD
│ │ │ ├── settingsRepository.ts # 设置 CRUD
│ │ │ └── recentFilesRepository.ts # 最近文件
@@ -259,6 +262,7 @@ MarkLite/
- ✅ 引用块
- ✅ 水平线
- ✅ Emoji 短码 `:smile:` `:rocket:`
+- ✅ Mermaid 图表 ` ```mermaid `
- ✅ HTML 内联元素
- ✅ GFM(GitHub Flavored Markdown)
diff --git a/docs/metona-editor-demo.html b/docs/metona-editor-demo.html
index 5281b54..c454678 100644
--- a/docs/metona-editor-demo.html
+++ b/docs/metona-editor-demo.html
@@ -4,7 +4,7 @@
-MetonaEditor v0.2.4 — 全功能演示
+MetonaEditor v0.4.0 — 全功能演示
+
+
+
+
+
+
+ Memory 模式 — v0.4.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
⚡
+
执行 SQL 查询以查看结果
+
Ctrl + Enter 快捷执行 · 支持多语句
+
+
+
+
+
+
+
+
+