00 · 设计总览
1. 产品定位
Mosu(下文简称 Mosu)是一个桌面优先、本地优先的 Markdown 编辑器, 交互范式是「无缝实时预览」: 单一编辑区域,内容以渲染后的形态呈现;光标所在的那个元素(且仅那个元素)就地展开为 Markdown 源码,可以直接改。
它要服务的人:
- 用 Markdown 写长文档、技术文档、笔记的人;
- 在意「文件就是我的资产」、不接受私有格式或云端锁定的人;
- 需要把同一份稿子导出成 HTML / PDF / Word 交付的人。
它不打算成为:知识库(双链图谱、卡片盒)、协作文档平台、通用富文本编辑器。
从 2026-08 起加上第四条定位:AI Native。改写、翻译、总结、问文档这类能力是 内置的,不是装出来的 —— 用户不需要知道「插件」这个词。这条决定连带把插件系统 推后了,完整推理见 ADR-0006。
2. 目标(Goals)
G1 · 编辑体验
- 实时预览下的输入延迟 p95 < 16ms(一帧),10k 行文档打开到可编辑 < 300ms。 (✅ 已建基准并达标,实测 0.1ms / 36ms。注意这个指标量法有坑, 第一版量出来的数字下限由帧率决定 —— 见 07 §2.2。)
- 中日韩输入法(IME)在任何装饰区域内都不丢字、不错位 —— 这是硬性门槛,不是「后续优化」。 (✅ 有专门的回归用例。)
- 键盘可完成全部高频操作;命令面板可达全部命令。(✅)
- 界面可读、可被读屏软件正确使用;对比度满足 WCAG AA。 (✅ 六套主题全过;axe 违规数为 0 且直接卡用例。一处明知故犯的例外: 专注模式的变暗只有 2.1:1,取舍见 07 §3.1。)
G2 · 格式保真
- 任意合法 Markdown 文本,经「打开 → 不做任何编辑 → 保存」后与原文件逐字节相同。
- 局部编辑只产生局部 diff:改一个词不会重排整个文档的缩进 / 引号 / 换行风格。
- 遵循 CommonMark + GFM;遇到不认识的语法按纯文本原样保留,绝不吞掉内容。
G3 · 可扩展
- 主题只用 CSS,有稳定的类名与变量契约,升级不炸。
- 命令与快捷键可配置(✅),命令面板可达全部命令(✅),导入导出(✅ HTML / PDF)—— 这些都是不需要执行第三方代码的扩展面。文档模板与命令行入口今天还不存在 (⬜,见 05 二 §1),它们属于同一类,只是没做。
- 这一条在 2026-08 收窄过。 原来写的是「插件可以注册命令、快捷键、面板、 以及完整的语法扩展」,并承诺「内置的数学 / 图表 / 脚注自身就用插件 API 实现」。 两句都撤回:v1 不做开放插件系统,将来要开放的是受控的 Tool API 而不是 Plugin API。理由与重估条件见 ADR-0006。
G4 · 交付
- macOS / Windows / Linux 三平台,安装包体积 < 180MB,冷启动 < 1.5s。 (原定 120MB,M1.5 放宽 —— Electron 运行时本身就占去 100MB 上下, 余量太小会逼着在语法高亮这类真实需求上做无谓妥协。 ✅ 冷启动实测 807ms;Linux AppImage 113.6MB。 ⚠️ 空闲内存 550MB,超出 300MB 的预算,见 07 §2.3。)
- 导出 HTML(自包含单文件)、PDF(✅);检测到 Pandoc 时额外支持 DOCX / ePub / LaTeX(⏸ 未做,见 06 §4)。
- 界面语言:简体中文 / English / 日本語,设置里切换,不重启(✅ 见 07 §4)。
G5 · AI 是内置能力
- 装完就能用改写、翻译、总结、润色、问文档、生成大纲 / TOC / Mermaid / front matter,不需要装任何东西。
- AI 永远不直接改文档:它只产出 Patch,经 diff 预览与用户确认之后才落成 一次 CodeMirror transaction,⌘Z 一次就能全撤销。
- 自带 key(BYOK),没有我们的服务端,凭据不出 main 进程。
- AI 不可用时编辑器一切照常 —— 这是 P2 的推论,不是「尽量」。
- (⬜ 未开始,M5。设计见 10 AI。)
3. 非目标(Non-Goals)
明确不做,避免范围蔓延:
- 不做实时协作(至少 v1 不做)。但内核选型要保证以后能加(见 ADR-0002)。
- 不做云同步 / 账号体系。同步交给 Git、iCloud、Syncthing 等既有工具。
- 不做通用富文本。不支持字号、字色这类 Markdown 表达不了的排版属性。
- 不做移动端。内核是纯 Web 库,将来别人要做是可能的,但不在本项目范围。
- 不复刻 Typora。不抄袭其代码、图标、主题资源、界面截图;只借鉴公开的交互范式。
- 不做开放插件系统(v1)。不加载第三方代码;扩展只走不需要执行代码的那几条面 (主题 CSS、命令与快捷键、导入导出,加上还没做的模板与 CLI)。 重估条件见 ADR-0006。
- 不做 coding agent。没有 shell、没有终端、没有 git 工作流、没有「跑一下测试 再改」。那是另一个产品,而且它会把提示注入的后果从「插入一段烂文字」变成 「任意代码执行」(10 §6)。
- 不代付推理、不中转。AI 走 BYOK,没有我们的服务端在链路上。
4. 设计原则
P1 · 文本是唯一真相(Text is the source of truth)
编辑器缓冲区里存的就是磁盘上的字符序列。没有「文档模型 → 序列化成 Markdown」这一步, 因此不存在序列化偏差、不存在「保存后格式被改写」这类问题。渲染是投影,不是转换。
这条原则是整个架构的地基,第 02、03 号文档都是它的推论。
P2 · 渲染失败必须优雅降级
公式写错、图表语法错、图片路径不存在 —— 显示错误提示,但源码文本必须仍然可编辑, 且保存时原样写回。任何渲染器崩溃都不能吃掉用户的字。
P3 · 内核不认识 Electron
@mosu/editor 是纯浏览器代码,不 import 任何 Node / Electron API。所有文件、对话框、 菜单能力通过注入的 HostBridge 接口获得。这样才能有 Web 版、才能被别的壳复用、 才能在纯 jsdom/Playwright 里测。
P4 · 能力最小化
渲染进程不开 nodeIntegration,开 contextIsolation,跑严格 CSP。 Markdown 里的原始 HTML 一律经过消毒;本地图片走自定义协议并限定在工作区内。 细节见 01 架构 · 安全模型。
P5 · 先做对,再做全
宁可 v1 只支持 CommonMark + GFM 但做到零损耗,也不要支持二十种语法但每种都有边角 bug。 路线图(08)按这个顺序排。
这条原则在实践中最常见的形态不是「少做一个语法」,而是换一种做法把问题绕开。 三个真实例子:
- 表格没有做网格编辑器,改成「每条命令是一次纯文本变换」(02 §6.4);
- 行内 HTML 没有做消毒器,改成「一个字节的 HTML 都不进 DOM」(02 §5.1);
- 块级 HTML 决定不做 —— 它的意义几乎全在属性里,而属性正是上面那条绕不开的 地方(03 §3.1)。
放弃的东西要写下来放弃的理由,不能只留一个「⏸」。
5. 与既有方案的取舍
| 方案 | 为什么不直接用 |
|---|---|
| VS Code + 预览插件 | 分屏范式,不是本项目要的交互 |
| Obsidian | 闭源、且定位是知识库;其 Live Preview 证明了本项目的技术路线可行 |
| Typora | 闭源、付费;本项目提供开源替代 |
| 纯 ProseMirror 方案(如多数 WYSIWYG) | 富文本模型与 Markdown 源码往返有固有损耗,违反 G2 / P1,见 ADR-0002 |
6. 现在做到哪一步
一句话:M2 / M3 / M4 完成,M4.5 六件硬骨头全部落地,M6 提前做了四项 (专注 / 打字机模式、国际化、无障碍整改、性能基准),v0.2.0 又补上了工作区写操作、 Quick Open、全工作区搜索与大纲长文导航。
下一步是 AI 基座(M5),不是插件系统 —— M5 的内容在 2026-08 被整个换掉了, 理由见 ADR-0006,设计见 10 AI。
逐个里程碑的「计划与实际的偏差」写在 08 路线图 每一节末尾。 那份偏差清单是这套文档里最该读的部分 —— 它记的是被推翻的结论, 而不是完成的功能。
分发相关(签名、公证、Mac App Store 的可行性、定价)单独在 09 分发。
7. 命名与法律提示
产品名为 Mosu(M1 之后确定)。仓库名与内部包名
@mosu/*现已全部对齐。 旧仓库地址open-typo-md由 GitHub 永久重定向,已有的 clone 与外链都不用改。改名当天不会有任何东西坏掉,这一点是查过的:
.github/workflows/里没有一处 写死仓库 slug,全走${{ github.repository }}这类上下文变量。真正跟着 slug 走的只有一处会发出去的东西 —— 打进安装包的app-update.yml里那行repo:(由package.json的repository.url推导)。自动更新今天靠重定向 也能用,但把一个会过期的名字焊进已发布的二进制里不是好主意,所以在v0.1.0之前就改掉了。Typora 是他人商标。本项目名称、图标、宣传语都不得与之近似。
Mosu与之毫无字面或读音上的关联,混淆风险已经不成问题; 但正式发布前仍应确认这个名字在目标市场没有冲突。不得移植、反编译或参考 Typora 的源码与私有资源。所有实现从公开规范与开源库出发。
依赖许可要与 MIT 兼容;GPL 组件(例如 Pandoc)只能作为外部可选进程调用,不能打包进发行版。