[0514]AI EDITOR VIBE_LOG

📅 2026/7/3 5:37:15
[0514]AI EDITOR VIBE_LOG
耗时约 6 小时从空脚手架到打包出 .exe灵感与初衷 (The Spark)起因很简单想要一个本地的、Typora 风格的 Markdown 编辑器。不要云同步、不要订阅、不要臃肿的插件系统。就是打开、写、保存——干净利落。当前市面上要么是 Typora 开始收费要么是 Obsidian 太重要么就是纯源码编辑器看不出渲染效果。另外有一个很有意思的伏笔现在不需要 AI 能力但架构上要留口子。将来某天想加 AI 功能的时候不需要把整个项目推翻重来。所以核心需求就三句话所见即所得的 Markdown 编辑像 Typora多标签页管理不是单文件也不是重型文件树AI 扩展槽位预留接口不实现头脑风暴与方案定型 (Brainstorming)编辑器引擎三个方案一个选择这是整个项目最关键的技术决策。三个备选方案方案引擎优点缺点AMilkdown(ProseMirror)开箱即用的 WYSIWYG、插件生态好深度定制需要了解 ProseMirror 内部Bmdxeditor (Lexical)Meta 出品、React 友好Markdown 支持不如 Milkdown 成熟CMonaco 自研 WYSIWYG完全可控工作量巨大大概率造出烂轮子选了A — Milkdown。原因很实在Milkdown 是为「Typora 式 Markdown 编辑器」这个场景设计的而不是通用富文本编辑器缝了个 Markdown 插件。后来在实现阶段发现 Milkdown v7 的 API 和文档里的 v6 有很大差异useEditorvsuseInstance、listenerCtx的配置方式、getMarkdown要用serializerCtx但整体方向是对的。架构定型Electron Main Process (文件 I/O 图片处理) │ IPC (contextBridge, contextIsolation) ▼ React Renderer (Context useReducer Milkdown)关键设计决策文件 I/O 放主进程不开放nodeIntegration安全第一Context useReducer而不是 Redux——这个项目状态不复杂Redux 属于杀鸡用牛刀5 分钟自动保存——用户明确要求最初讨论是 3 秒 debounce用户改成 5 分钟图片存images/同级目录——像 Typora 默认行为相对路径引用搬家不丢图AI 扩展槽——定义AIExtension接口transformtransformStreamAIPanel组件占位核心功能实现路径 (The Build)实现用的是Subagent-Driven Development模式——把 16 个 task 逐个派发独立子代理每个 task 走实现 → spec review → code quality review三轮。实现时间线Phase 1基础设施 (Task 1-3)先搭骨架。vitest testing-library 测试环境、TypeScript 类型定义Tab、EditorState、EditorAction、AIExtension、EditorContext状态管理。这里有个小插曲EditorContext的 code review 发现 context value 没包useMemo每次渲染都创建新对象。虽然当时测试都过了但确实是个性能隐患。加上后 clean。Phase 2组件搭建 (Task 4-10)一口气搞了 7 个组件ErrorBoundary、TitleBar、TabBar、StatusBar、MilkdownEditor、EditorArea、AIPanel。Milkdown 集成是这里最难的部分。代理在实现时发现 v7 的 API 和 task 描述不一样——listenerCtx要用ListenerManager实例而不是回调数组getMarkdown()要经过serializerCtx。代理自己消化了这些差异没有上来就问这点很赞。Phase 3Electron 层 (Task 11-13)preload.tsIPC 桥接、fileHandlers.ts打开/保存/另存为 大文件 2MB 警告、imageHandlers.ts图片写入images/目录 MD5 命名。Phase 4总装 (Task 14)把App.tsx彻底重写接上所有组件 键盘快捷键 IPC 调用。代理还发现了vite-env.d.ts里有一个旧版的electronAPI类型声明和新的electron.d.ts冲突导致 TypeScript 报错。删掉后 clean。Phase 5用户测试 → 5 个 bug 修复全部测试通过后启动 app用户上手试立刻发现了 5 个问题。这是今天最有价值的环节——踩坑与调试实录 (Debug Fixes)Bug 1奇怪的边距和滚动条现象编辑器周围有莫名边距和滚动条。根因两个问题叠加——①index.html没有 CSS resetbody默认 margin②EditorArea的overflow: auto让容器本身出现滚动条。修复加 CSS reset* { margin:0; padding:0; box-sizing:border-box }overflow: auto→overflow: hidden。后来用户反馈长内容无法滚动时又改成overflow-y: automin-height: 100%。Bug 2没有按钮只能快捷键现象用户不知道 CtrlN/O/S界面上没有任何可点击的东西。根因设计 spec 里根本没提工具栏。我只关注了键盘操作忘了 GUI 的基本可用性。修复新增Toolbar组件放 New / Open / Save 三个按钮。TabBar里的按钮也移到了工具栏。同时需要更新 TabBar 测试原本测试 按钮的功能。Bug 3新文件保存报错 fail to save to...现象CtrlN 新建标签页后 CtrlS 保存弹窗报错。根因新建标签页的path是空字符串saveFile(, content)直接把空字符串当路径传给了fs.writeFileSync。修复handleSave里加判断——如果path为空调saveFileAs弹出另存为对话框成功后更新 tab 的 title 和 path。这个修复的细节比较微妙需要closeTabopenTab来更新已有 tab 的 path因为EditorAction没有UPDATE_PATH。Bug 4编辑器不自动聚焦现象新建标签页后一片空白没有光标闪烁必须鼠标点击一个很小的区域才能激活编辑。根因Milkdown 的 ProseMirror 编辑器不会自动聚焦。我经历了三次迭代才搞定尝试方式结果1requestAnimationFrame(() view.focus())失败DOM 还没就绪2setTimeout(() view.focus(), 100)不稳定取决于机器速度3useInstance()监听loading状态成功第三次用了useInstance()返回的loading——只有当 Milkdown 报告 editor 已就绪时才聚焦。这才是正确的时机。同时在EditorArea加了useEffect监听activeTab.id变化tab 切换时也主动聚焦。Bug 5Typora 风格现象整个界面是 VS Code 暗色风格和 Typora 的清新浅色完全不同。修复6 个组件全面换肤——#1e1e1e→#ffffff#cccccc→#333333蓝色#007acc状态栏 → 浅灰#f5f5f5Tab 指示条从无到蓝色底部边框。Toolbar 加浅灰背景和圆角按钮。Bug 6 7光标不到位 黄边框用户反馈两个细节问题光标还是不自动出现需要进一步调试 编辑器聚焦时 ProseMirror 有黄色 outline。光标问题的根因是useEditor的时机——需要用useInstance()而不是固定延迟。黄边框修起来简单.ProseMirror:focus { outline: none !important }。高光时刻一次性写对的模块EditorContext的 reducer 逻辑。6 个 action 的状态转换、CLOSE_TAB的邻居选择算法、UPDATE_DOC的自动 dirty 标记——代理第一次就完全写对了12 个测试一举通过。这可能是因为 discriminated union 的类型约束足够强让 reducer 实现几乎没有犯错空间。反复调整的模块自动聚焦。从requestAnimationFrame到setTimeout(100)到useInstance().loading前前后后改了 4 次代码。这个教训是不要猜测异步组件的就绪时机要找框架提供的就绪信号。当前成果与遗憾 (Outcome Todo)今天交付的成果Electron 桌面应用— 可安装的 .exe 文件80MB NSIS installer27 项单元测试— 全部通过覆盖状态管理 4 个组件TypeScript 零错误— 渲染进程 主进程双配置完整文档— 设计规格、实现计划、PROJECT_README、知识图谱、本日志功能清单已实现状态Milkdown WYSIWYG Markdown 编辑✅多标签页管理打开/关闭/切换✅文件保存/另存为/打开✅图片粘贴与拖拽 →images/目录✅5 分钟自动保存✅标签页切换前自动保存✅大文件警告2MB✅崩溃降级ErrorBoundary → raw Markdown✅键盘快捷键CtrlN/O/S✅工具栏按钮New/Open/Save✅AI 扩展接口 占位面板✅接口就绪未实现Electron 打包Windows NSIS✅留给明天的 TODO右键菜单— 标签页上右键关闭其他/关闭右侧是刚需拖拽排序标签页— 目前标签页顺序固定最近打开的文件列表— 无文件树的情况下这个很实用Markdown 语法工具栏— 加粗/斜体/标题/列表的格式化按钮目前只靠 Milkdown 内置 markdown 快捷键macOS 打包测试—electron-builder配置了 dmg 目标但没验证崩溃恢复— spec 里写了检测 5 分钟自动保存的临时副本下次打开时恢复还没实现AI 功能原型— 既然接口已经有了可以先接一个简单的 LLM 调用试试图标— electron-builder 提示用的是默认图标缺一个应用 icon开发体验收获整个流程走下来最大的感受是Subagent-Driven Development 用户测试反馈这个