CHANGELOG

更新日志

每个版本的详细变更记录,包含新功能、缺陷修复与体验优化。

版本索引

  • v2.3.11 — 白屏根因闭环(内容级强制提交)、Mermaid 塌缩防护、LAN 访客页对齐桌面端
  • v2.3.10 — 合成层自愈:DOM 健康但画面不绘制时强制重绘 + 常显「显示修复」按钮
  • v2.3.9 — 启动护栏:启动期异常不再静默白屏 + 主界面 watchdog
  • v2.3.8 — 桌面端图表/公式库同源自托管(离线可用)+ 缓存戳幂等修复
  • v2.3.7 — 体验层升级(工作区空间色 + 触缘浮出 + 文档卡片 + 表达力视觉语言)
  • v2.3.6 — 局域网共享真机修复(访客页可达 + 关闭即断 + 开关样式)
  • v2.3.5 — 局域网共享增强(共享工作区白名单 + 设置面板 UI 修复)
  • v2.3.4 — 局域网共享可用性修复(访客配对协议扁平化 + 回归锁)
  • v2.3.3 — 局域网共享(6 位口令配对 + 访客白名单 + 只读/可编辑);13 项安全审计修复(分享不可枚举 / 路径穿越 / DNS rebinding / 保存竞态)
  • v2.3.2 — 分享图片丢失修复(ws_ 工作区前缀引用按工作区 id 取图);分享页补上代码块复制行为与目录索引抽屉
  • v2.3.1 — 分享图片丢失修复(ws_ 工作区前缀引用按工作区 id 取图);分享页补上代码块复制行为与目录索引抽屉
  • v2.3.0 — 桌面端也能生成临时分享链接,支持 1/7/30 天或永久自动过期;过期由数据层拦截,同文档复用同一条链接,随时可撤销
  • v2.2.7 — 修复非 UTF-8 文档打开即误报「外部修改」(保存保留原编码);暗色主题代码高亮变量/函数不可读修复,五套主题配色补齐;自定义高亮颜色按主题记忆 + 一键恢复默认
  • v2.2.6 — 状态栏编码切换(ANSI/GBK 等 10 种编码直接选择并保存)+ 代码文件语法高亮与缩进参考线(方法/变量/关键字分色),Markdown 不受影响;修两个窗口缩放即报错的预存缺陷
  • v2.2.5 — 云同步可靠性修复:个别含脚本的 .html 文档点「一键推送」永远传不上云端(正文命中平台内容安全策略被拒写,而拒绝响应不带跨源头,浏览器只报一句误导性的「缺少跨源响应头」)。现在:推送前把 HTML 的脚本剥离成云端安全形态再上传(本机文件不动)、失败逐篇定位原因并显示、被拒自动降级重试、失败不再误写同步基线、云端与分享页识别标记并提示
  • v2.2.4 — HTML 文档阅读体验修复:手机端预览变窄(响应式网页只剩 91% 宽、固定宽度网页只剩 32%)、长网页被 20000px 高度上限截断成双层滚动、反复打开无缓存;现在高度上限提到 200000px、云端与分享页补上「放大」全屏入口、正文与成品预览会话内缓存(重开 0 次网络请求)
  • v2.2.3 — 图片同步修复:桌面端「一键推送」的截图 / 视频此前永远传不上去(官方 SDK 的存储请求带了两个平台 CORS 白名单里没有的头,预检被拦、请求根本不发出;登录与文档的头都在白名单内,所以文档能同步、图片永远缺失)。改为只带白名单头的直连上传,并让失败原因可见、失败不再写「已核对」戳;旧核对戳一律作废,升级后点一次「一键推送」即可补齐历史图片
  • v2.2.2 — 独立的 .html 文件也能同步到云端:桌面端一直把 .html 当一等公民(网页预览、去标签检索),只有同步白名单没放行 —— 本机能看、云端永远没有;云端工作台与分享页按扩展名分派渲染(沙箱网页 + 随分享带走的图片)。.json / .csv 仍不同步
  • v2.2.1 — 手机端截图不再「未同步」:桌面端「一键推送」补齐图片 / 视频(此前只传正文);分享出去的网页不再被压在小窗里;安卓启动第一帧改用品牌方牌(此前是系统占位图标)
  • v2.2.0 — 重命名后缀修复:显式扩展名(如 hello.html)不再被强行改成 hello.html.md;不写扩展名仍自动补 .md;非 Markdown 文件允许移动;「仅显示 md」工作区下的边界行为改为明确提示
  • v2.1.42 — 内嵌网页体验修复:修「点放大没反应」(浮层样式选择器带错前缀,永远匹配不上);内嵌网页改为按内容高度自适应,整页网页不再挤在固定小窗里(桌面 / 网页 / 手机三端同步)
  • v2.1.41 — HTML 文件渲染:打开 .html 就像打开网页(编辑态左源码、阅读态整页渲染,可放大全屏);重新收紧沙箱——网页里的脚本已无法读取你的登录态与知识库;搜索索引不再命中标签噪音
  • v2.1.40 — 图片同步补齐:桌面端「一键推送」把笔记里引用的本机截图 / 视频一并同步到云端(此前只传文本,手机端与网页端图片全是裂图);正文没变时也会补齐缺失的图片,按体积做增量、图片没变 / 上传失败 / 超过 12MB 分别报数;Android 客户端 1.1.1 图标与启动图重制
  • v2.1.39 — 首轮实机反馈修复:桌面端修「可同步内容恒为暂无 Markdown」(驼峰字段错配,连带修复拉取冲突检测),面板显示推送目标、支持选择同步工作区;云端 / Android 登录界面重排(验证码为主路径,密码框默认收起)
  • v2.1.38 — 三端直连打通:桌面端可直接登录云端并双向同步(新增「拉取云端更新」,本机文件永不被静默覆盖,两端都改过时自动留冲突副本);Android 应用补齐原生能力(返回键分层回退、分享、复制、导出 .md、断网提示、状态栏配色)并升级到 1.1.0
  • v2.1.37 — 知识库上云 + 手机端:新增云端知识库工作台(邮箱 / 手机号 / 微信登录,三端共用同一份笔记);桌面端「云同步」面板新增一键推送,先比对内容指纹、只上传改动过的笔记,且桌面端仅向云端开放三个只读接口;同步发布 Android 应用;修复云同步面板「可同步篇数」恒显示为空
  • v2.1.36 — 界面设计系统重制:颜色 / 间距 / 字号收敛为一套设计令牌,四套主题配色全部达到无障碍对比度标准;编辑 / 预览 / 沉浸三视图行高与版心对齐;沉浸模式支持加粗 / 斜体 / 链接 / 删除线 / 高亮等行内标记按最终效果渲染;交互热区与键盘可达性补强
  • v2.1.35 — 沉浸模式公式与图表修复:段落内公式正常渲染、多块公式 / 图表不再只剩最后一块,图表恢复自然尺寸不再拉满版心
  • v2.1.34 — 沉浸模式企业级排版(正文居中版心 / 隐藏行号栏 / 块间空行收缩)+ 内存占用优化(纸张纹理无缝平铺、录屏窗口资源释放、后端分配器升级)
  • v2.1.33 — 行内颜色 / 背景 / 字号在裸段落中恢复显示,图表居中与放大清晰度修复
  • v2.1.32 — 沉浸模式排版对齐预览栏:图片不再过大,表格 / 代码块 / 引用 / 链接恢复正常样式
  • v2.1.31 — 沉浸模式显示补全:公式 / 表格 / 提示块 / 图片 / 字体颜色 / 背景色 / 高亮全部正常呈现
  • v2.1.30 — 沉浸模式重构为所见即所得:进入沉浸后正文按最终效果渲染,光标所在段落保留源码可直接编辑,退出即完整还原,不影响其它功能
  • v2.1.29 — 图表三连修复:锁定升级 Mermaid 11(架构图可用)+ 渲染后按内容自动外扩(底部不再被裁)+ 预览白底与拖拽平移
  • v2.1.28 — AI 规则首次接入写入链路(越权写入可拦截)+ 知识库问答检索修复(重建索引不再落空、中文提问可召回、首次使用自动建索引)+ 图表放大预览修复
  • v2.1.27 — 录屏画面修复(不再静止/卡顿、启动不再误弹遮罩)+ 知识脉络分析恢复 + 文档标准与 AI 规则、知识标签适配修复
  • v2.1.26 — 托盘图标 + 关窗可唤回(点快捷方式/托盘图标重新打开主界面)
  • v2.1.25 — 单实例保护:重复点击快捷方式不再开出多个窗口
  • v2.1.24 — 截图/录屏「闪屏」彻底修复 + 长按快捷键闪退
  • v2.1.23 — 修复冷启动授权校验超时被误判为「未授权」
  • v2.1.22 — 稳定性修复:导出截图资源崩溃 + 升级后启动失败(资源缓存)+ 高亮语言包补齐 + Agent 规则状态 404
  • v2.1.21 — 新功能:导出文档内本地截图资源 + 推广页 webp 背景图清理
  • v2.1.16 — 打包流程稳定化(build-release.ps1 一键脚本 + 启动自动检查更新 + 静默下载安装)
  • v2.1.13 — JSON 格式化全面修复(MD 代码块树形 + 模式切换不失效 + processJsonCodeBlocks 统一)
  • v2.1.12 — JSON 树形三处渲染路径统一 + setMode 跳过非 Markdown 渲染
  • v2.1.11 — 小文档 BOM 检测修复(BOM 移到 UTF-8 纯解码之前)
  • v2.1.10 — JSON 预览实时更新修复(setPreviewVisible + renderCurrentPreviewAsync)
  • v2.1.9 — JSON 宽松解析 + 录屏 captureStream 修复
  • v2.1.8 — JSON 格式化预览新增 + 小文件编辑器同步修复
  • v2.1.7 — 版本自升级修复(check_update + 更新对话框)
  • v2.1.6 — 录屏鼠标可操作性修复(click-through + Alt+M 停止)
  • v2.1.4 — 版本自升级缺陷修复(后端 version.json + 前端更新对话框)
  • v2.1.3 — 录屏功能稳定性加固(多次录制失败 + 默认桌面捕获 + 保存清理)
  • v2.1.2 — 截图保存后再次截图失败修复 + 文字大小可调
  • v2.1.1 — 截图选区边界约束(选区框越界难以选中)
  • v2.1.0 — 录屏功能稳定性加固(多次录制失败 + 桌面选择器 + 状态清理)
  • v2.0.9 — 知识库智能管理故障排查与稳定性增强
  • v2.0.8 — AI 忠实性强约束 + 反幻觉机制
  • v2.0.7 — 启动授权弹窗修复(WMI 缓存预热 + 超时放宽)
  • v2.0.6 — 截图/录屏健壮性加固(黑窗 + 遮罩挡鼠标 + 录屏选择器)
  • v2.0.5 — 截图核心缺陷彻底修复(多次截图失败 + 保存后卡死)
  • v2.0.3 — 截图架构重构 + 防卡死保障 + 图表修复
  • v2.0.2 — 截图标注 + 录屏 + OCR + 独立窗口无感触发
  • v2.0.1 — 图谱修复 + 轻量绘图 + AI增强 + 代码高亮 + 导出优化 + DeepSeek接入
  • v1.8.107 — 阅读模式不弹AI菜单 + 工作区外部新增文件自动刷新 + .key文件正常显示 + 代码语法高亮
  • v1.8.106 — 文档切换编辑位置保留 + 外部编辑器异步编辑冲突检测 + 重新加载强制读磁盘
  • v1.8.105 — 全局搜索中文 MD「打不开/没内容」空白屏·三重修复
  • v1.8.104 — 安装后启动失败(前端资源缺失)紧急修复·双重保险
  • v1.8.103 — 原生另存为 + 路径查看 + DOCX/RTF/ODT 正文提取
  • v1.8.102 — 其他电脑安装后 HTTP 404 白屏紧急修复
  • v1.8.101 — 全格式导出质量升级 & Frontmatter 不再外漏
  • v1.8.100 — 启动红屏 SyntaxError 紧急修复
  • v1.8.99 — 阅读栏/阅读模式公式/图表全面修复
  • v1.8.98 — PDF 导出大升级
  • v1.8.97 — 编辑器字体优化 + 字号快捷键修复
  • v1.8.96 — 代码文件保存最终修复 + 工作区视图
  • v1.8.95 — 工作区视图重写 + 基础保存修复
  • v1.8.94 — 工作区与编辑器增强
  • v1.8.93 — 界面与体验升级 + 性能优化

v2.3.11 · 白屏根因闭环 + 图表塌缩防护 + LAN 访客页对齐

这一版由三个实测反馈驱动:v2.3.10 装上后白屏仍在(且「显示修复」按钮救不回来)、思维导图节点挤成一条斜线、局域网共享访客页与桌面端体验差距过大。三个问题各自深挖到了根因,都有决定性实验数据支撑。

① 白屏:根因钉死,自愈升级为「内容级强制提交」

  • 决定性证据:白屏时 DOM 完全健康、WebView2 的 GPU / 渲染进程全部存活、自愈端点执行成功——但画面仍不出现。而用户按下 Ctrl+Q 切换侧栏的瞬间画面当场恢复。这说明渲染管线本身没坏,坏的是合成器卡在「内容有脏区但不提交」的状态,且只有页面内容布局变化能把它踢出来。
  • 由此排除了所有表面级手段:bounds 1px 抖动(v2.3.10 的方案)、顶层窗口移动、甚至结束 GPU 进程让其重建——全部实测无效。
  • 升级后的自愈三连:bounds 抖动 + NotifyParentWindowPositionChanged(WebView2 官方的位置失同步修复)+ eval 内容级强制提交——用 will-change 合成层的创建 / 销毁制造等效布局事件,零视觉变化,等效于「替你按了一次 Ctrl+Q」。
  • 两个新挂钩补齐窗口期:页面就绪后 1.2 秒自愈(实测冷启动时 GPU 进程比主进程晚约 18 秒就绪,原 2.5s / 6s 定时全部落在页面加载之前=空抖);每 45 秒周期兜底(虚拟显示器拓扑静默翻转可能不产生任何窗口事件)。
  • 触发环境确认:向日葵虚拟显示器(2022 年驱动)+ MuMu 模拟器虚拟显示的机器上,拓扑 / DPI 翻转期间最易触发。环境侧建议更新或停用老虚拟显示驱动。

② 思维导图 / 流程图压成一条斜线:页面隐藏期间测量塌缩

  • 实测复现:同一份库、同一份文档,页面可见时渲染 viewBox 321×419 布局正常;页面隐藏期间渲染直接塌成 20×20,节点挤成一条近竖直线——正是截图里的异常形态。
  • 机制:页面处于 hidden 状态(启动窗口尚未显示、最小化、后台标签页)时,getBBox 对所有文本返回 0 尺寸,mermaid 的布局测量整体塌缩。应用启动时窗口本来就是隐藏的(页面就绪后才显示),预览渲染正好撞进这个窗口期。
  • 三层防护:渲染串行链先等页面可见(visibilitychange + 3 秒超时放行);插入后做塌缩检测(真实内容双向 >3× 自报 viewBox 即判塌缩——实测塌缩时比值达 6.9× / 9.75×);检出后自动重渲染一次(校验渲染代次,防旧盖新、不死循环)。
  • 云端分享页同步修复:后台标签页打开分享页同样会塌缩,已同步并递增云端缓存戳。

③ 局域网共享访客页:补齐预览与图片,观感对齐桌面端

  • 编辑 / 预览双视图:顶栏分段切换(Ctrl+P 直达预览;只读共享默认进预览——访客的主要场景就是阅读)。预览管线与桌面端同源:markdown 渲染 → KaTeX 公式 → Mermaid 图表(含本版的塌缩防护)→ highlight.js 代码高亮(18 个语言包)→ 沙箱帧自适应高度。
  • 图片正常显示:文档图片走 /source/* 资产端点,而访客路由此前没有它——这就是图片全部裂开的根因。新增访客专用资产端点,且比桌面版更收紧:只认工作区前缀格式 + 共享白名单闸门 + 拒绝路径穿越,不做桌面版的跨工作区模糊扫描(避免把未共享工作区的资产泄漏给访客)。
  • 目录栏任意宽度可折叠:旧实现把折叠样式写在窄屏媒体查询里,宽屏点按钮毫无反应——现在所有宽度都能折叠 / 展开。
  • 观感统一:配色全部改引主应用设计令牌(同一暖米底、同一强调色),预览正文直接复用桌面端阅读区版式。

验证

  • 自动化测试 323/323 通过(新增 Mermaid 塌缩防护 2 条、LAN 访客页 4 条回归锁)。
  • 真浏览器验收:访客页端到端 18/18(PIN 配对 → 开文档 → 预览渲染「图片加载、公式、图表非塌缩、代码高亮」→ 侧栏折叠 → 切回编辑内容保留 → 只读默认预览);渲染自愈 7/7;启动护栏 22/22;体验层 11/11;桌面 vendor 18/18。

升级后无需迁移任何文档或配置;编辑中的草稿、共享口令与窗口布局全部保留。局域网访客刷新页面即可拿到新访客页。

v2.3.10 · 合成层自愈:画面没画出来的那半边

上一版补的是「启动异常被静默吞掉」,靠 DOM 探针判断主界面是否正常。但实测反馈里还有一种白屏:DOM 完全健康——侧栏、列表、编辑器节点齐备,尺寸与位置都对,控制台零报错,可屏幕上就是只有背景。探针全绿,画面空白,watchdog 自然也不会触发。这类故障不在页面层,而在渲染管线:WebView2 的合成层(视觉树到屏幕的那一层)丢了,页面以为自己画完了,屏幕上什么也没有。

为什么 DOM 探针查不出来

  • 页面渲染分两步:先把 DOM 排版绘制成视觉树,再由合成器把这棵树提交到屏幕上。丢的是后一步,前一步的所有可观测指标(节点、尺寸、样式、脚本执行)都正常。
  • 因此 v2.3.9 的可见性检查在这类场景里全是通过——这正是「提示已修复、白屏还在」的原因。
  • 已知触发点集中在窗口重新聚焦(尤其最小化后恢复)与缩放 / DPI 变化:这两类事件会让合成器重建表面,重建失败就只剩背景。

修复:从渲染管线一侧强行让整棵树重画一次

  • 新增进程内自愈动作 nudge_webview_composition:读取 WebView2 控制器当前的 bounds,宽度 +1 像素再还原。尺寸变化会强制合成器重建表面并重新提交整棵视觉树。
  • 为什么抖 bounds 而不是缩放窗口 / 刷新页面:不重建页面、不丢编辑状态(未保存的光标与草稿都在)、不动窗口尺寸与最大化状态、全程约 1 帧(约 16ms),肉眼不可感知。
  • 自动触发:启动完成后的 2.5 秒与 6 秒各一次(覆盖首帧最脆弱的窗口期);窗口重新聚焦、缩放 / DPI 变化后各补一次;同类事件 1.5 秒内去抖,反复切换窗口不会抖个不停。
  • 用户出口常显:主界面右下角新增「显示修复」按钮。第一次点击执行强制重绘并给出提示,5 秒内再点一次则判定自愈无效、直接刷新页面兜底——不需要记快捷键,触屏与纯鼠标环境都可用。
  • 新增 POST /api/window/nudge(HTTP 与 IPC 双通道):按钮、watchdog 与启动流程共用同一入口。

边界说清楚

  • 绘制结果无法从进程内自证,所以自愈动作只保证「已提交一次重绘」,不谎报「已修复」——按钮文案是「若仍空白请在 5 秒内再次点击刷新页面」,把判断权交回给你。
  • 若刷新后依旧白屏,问题不在渲染合成层,需要看 WebView2 Runtime 版本与显卡驱动,可用恢复浮层里的「复制诊断」把环境信息一起反馈。

验证

  • 自动化测试 315/315 通过;新增 7 条渲染自愈契约锁(端点注册、去抖、按钮双阶段、不得误碰页面状态)。
  • 渲染自愈真浏览器验收 7/7:按钮存在且可点、首次点击只重绘不刷新、二次点击才刷新、按钮不遮挡既有浮层;启动护栏回归 22/22 仍全通过。
  • 性能预算 9/9:自愈动作不在启动关键路径上,首屏体积与 DOM 计数零变化,输入延迟与帧时间基线未动。

升级后无需迁移任何文档或配置;编辑中的草稿、主题与窗口布局全部保留。

v2.3.9 · 启动护栏:异常不再静默白屏

这一版修的是一个「无声故障」:应用启动后主界面整体消失,只剩主题背景与两个角落的小浮层,没有任何报错、没有任何恢复入口,用户只能对着背景发呆。排查后确认渲染逻辑没有问题——问题在于启动期任何异常都会被静默吞掉,系统对此既没有提示也没有自愈能力。

根因:错误提示写进了一个已经不存在的节点

  • 桌面端以 skipSplash=1 启动,启动流程第一件事就把「启动完成」标记置位、移除启动画面节点,之后才执行授权检查与应用初始化。
  • 全局错误钩子的设计是「启动完成后的运行时错误只记录、不打断编辑」——本是好意,但启动期的异常也被当成了运行时错误:只写一行控制台警告,用户什么都看不到。
  • 原有的失败文案写在启动画面 DOM 里,而那个节点早已被移除;15 秒进度超时兜底也因进度已置 100% 而失效。净效果:任何启动期异常 = 无声白屏。

修复:让失败可见、可诊断、可恢复

  • 「启动完成」标记推迟到初始化成功之后;启动链路全部包上异常捕获,任何一步失败都会显示恢复浮层,而不是被静默吞掉。
  • 新增独立的错误恢复浮层:标题、错误详情、「尝试恢复」(清除误加的隐藏样式并触发一次重绘)、「复制诊断」(把错误信息放进剪贴板,方便反馈)、「重新加载」。
  • 新增主界面可见性 watchdog:启动 12 秒后检查主界面的显示状态、尺寸与关键子元素,界面没画出来就给出恢复入口;30 秒仍未启动完成也会提示。恢复动作只做布局刷新,不改任何视觉与坐标。
  • 启动失败的 10 秒自动刷新保留,但加了最多 2 次的上限(存储在会话级,启动成功即清零),避免持续失败时无限刷新闪屏。

既有契约不变

  • 启动成功后的运行时错误仍只记录、不弹窗、不刷新——编辑器里写文档时遇到的临时错误依旧不会打断你,这一点用真浏览器回归锁死。
  • 未改任何主题颜色、未动渲染合成与性能基线;浮层用纯背景色,不创建常驻 GPU 层。

验证

  • 自动化测试 309/309 通过;新增 8 条启动护栏契约锁。
  • 真浏览器验收 22/22:正常启动不弹浮层 / 模拟主界面隐藏后 watchdog 触发且一键恢复生效 / 启动后运行时错误不弹窗 / 模拟启动期异常后浮层出现且复制诊断与恢复均可用、自动刷新带次数上限。
  • 性能预算 9/9:首屏堆 5.24 MB、DOM 1660、输入 P95 8.2 ms、帧 5.7 ms、零长任务,均在预算内。

升级后无需迁移任何文档或配置。极少数「纯 GPU 合成层丢失」场景(DOM 完全健康但画面未绘制)仍需 Ctrl+R 手动恢复。

v2.3.8 · 图表与公式彻底离线可用:桌面端零第三方 CDN

这一版修的是一个真实可见的故障:部分网络下预览里所有 Mermaid 图表整片显示「Mermaid 库加载失败」。渲染逻辑本身没有问题,问题在于桌面端仍向境外 CDN 动态加载第三方库。修复后桌面端与云端工作台使用同一批随包资产,断网也能正常出图出公式。

根因:主机名级 TLS 阻断,不是语法也不是缓存

  • 实测 curl https://cdn.jsdelivr.net/npm/mermaid@11.12.2/… 返回 (35) schannel: failed to receive handshake、HTTP 000、0 字节;同一时刻另一个镜像主机能正常返回 200,说明不是断网,而是该主机名在国内常见线路上握手被重置。
  • 云端工作台早已把全部第三方库自托管,桌面端却只镜像了登录 SDK,于是同一篇文档在云端能出图、装到本机就报红。
  • 影响面不止 Mermaid:数学公式、Chart.js / ECharts 图表会静默降级,导出 PDF 与打印同样缺图(打印路径复用同一个加载函数)。

修复:四个库 + 公式字体随安装包自带

  • Mermaid 11.12.2、KaTeX 0.16.9、Chart.js 4.4.7、ECharts 5.5.1,外加 KaTeX 的 20 个 woff2 字体,共 26 个文件 / 4.79 MB,与云端 vendor/ 逐字节一致,由同一脚本镜像生成,不会出现两份实现各自漂移。
  • 六个加载点全部改为同源路径:Mermaid、KaTeX 的 JS 与 CSS、两段自包含图表模板、Markdown 渲染 worker 的资源目录参数。云端与桌面端的渲染 worker 仍是同一份文件,三端 Markdown 渲染器零改动。
  • 内嵌图表页运行在不含 allow-same-origin 的沙箱 iframe 里;真浏览器实测根相对路径在该沙箱中可正常加载,因此模板不写死端口或域名,文档换设备、换端口依然可用。
  • 错误提示不再把用户指向外网;桌面端运行时零第三方域名请求。

顺手修掉静态缓存戳的自引用

  • 缓存戳由参与打包的前端文件内容算出,但其中两个文件又会被脚本改写戳,形成自引用:每跑一次戳都会变(曾连跑 4 次得到 4 个不同值),产生无谓 diff。
  • 现在算指纹前先把戳本身归一化成占位符:真实内容变化仍会刷新缓存,戳自身变化不会;云端人工戳不归一化,改它照样触发更新。实测连跑三次:首次定稿,后两次均「无需变更」。

验证

  • 自动化测试 301/301 通过;新增「桌面端零 CDN」「缓存戳幂等」两组回归锁。
  • 真浏览器验收 18/18:Mermaid 真渲染出含 viewBox 的 SVG、KaTeX 真出公式且字体 200、沙箱 iframe 与 worker 均加载本地库、零 404 / 零请求失败 / 零外部域名请求。
  • 资产镜像脚本二次运行 54 个文件全部跳过(幂等);静态资源缓存戳 35 处统一。

升级后无需迁移任何文档或配置;首次启动会多占用约 4.8 MB 安装包体积。

v2.3.7 · 体验层升级:空间色彩、触缘浮出与文档卡片

这一版只打磨「看得见的手感」:渲染架构、数据格式、同步与共享逻辑一行未改,三端 Markdown 渲染器零改动。

每个工作区有了自己的颜色

  • 6 种低饱和主色(砂金 / 胭粉 / 苔绿 / 雾蓝 / 藕紫 / 琥珀)由工作区 id 稳定哈希得出:同一个工作区在任何设备、任何启动顺序下颜色都一致。
  • 可在「工作路径」弹窗里手动改色,覆盖关系只写本机 localStorage;不改 workspaces.json、不新增后端字段、不动任何 API。
  • 对外只下发 4 个 CSS 变量,染色全在样式层完成,原有主题令牌基线零漂移。

折叠的侧栏会在鼠标靠近时浮出

  • 侧栏收起后,鼠标靠近屏幕左缘时它会临时滑出、移开自动收回,沉浸式写作时不必先点按钮展开。
  • 用纯 CSS :has() 状态机实现,无定时器、无观察器、无逐节点遍历,静息时零常驻开销。

阅读区变成文档卡片,正文排版一个像素没动

  • 用 ::before 伪元素给阅读区加卡片衬底与细边,不新增 DOM 节点、不包裹正文容器。
  • 刻意不改 .markdown-body 的宽度、内边距与行高:换行位置、复制结果与打印输出与旧版完全一致。

表达力细节全部用 CSS 补齐

  • 二级标题锚点、行内高亮、表格斑马纹、代码块顶线等视觉层次均为样式规则,不注入内容、不改写文档字节。
  • Markdown 语法能力此前已完整(提示块、任务列表、脚注等),本版没有引入任何新语法,老文档无需迁移。

性能与内存仍在预算内

  • CSS 379,201 → 384,767 B(+5.6 KB),app.js 778,345 → 782,343 B(+4.0 KB),DOM 节点 1638 → 1648(+10)。
  • 首屏 JS 堆 5.23 → 5.24 MB;输入延迟 P95 5.1~5.6 → 4.7 ms,帧间隔 P95 5.8~6.0 → 5.8 ms;大文档堆增量 6.55 MB,长任务 0 个。

自动化测试 291 项全绿;体验层真浏览器断言 11/11、性能预算断言 9/9。

v2.3.6 · 局域网共享真机修复:访客页可达、关闭即断、开关样式

这个版本由端到端探针在真实安装环境实测驱动,一次修复三处问题。

访客页现在可以打开了

  • 问题:访客浏览器打开访客地址只会看到错误提示——访客页所需的静态资源(页面/脚本/样式)被鉴权中间件一并拦截,口令配对页根本无法加载。
  • 修复:鉴权中间件对访客静态白名单(含根路径)放行,白名单之外的文件依旧 404,主应用入口(index.html / app.js)对访客仍不可见。
  • 现在打开访客地址即可看到口令输入页,配对流程完整可用。

关闭共享后立即断开

  • 问题:关闭共享开关后,访客浏览器里已建立的连接仍可继续请求(监听端口已关,但浏览器与服务器间的旧连接还会存活一段时间)。
  • 修复:关闭开关后所有访客请求一律拒绝服务(503),并主动验证监听端口已真实关闭;新连接直接被拒。
  • 口令、访问令牌同时立即作废。

设置面板开关样式修复

  • 问题:共享开关被设置弹窗的通用输入框样式拉成通栏长条,勾选状态几乎看不出变化。
  • 修复:样式优先级缺陷修正,开关恢复为标准滑动开关;「共享工作区」列表里的勾选框尺寸同步修正。
  • 关闭共享后,访客地址/口令区块现在会正确隐藏。

自动化测试 284 项全绿;端到端探针的 4 条失败断言全部转绿。

v2.3.5 · 局域网共享增强:可指定共享范围

这个版本让「局域网共享」更可控,并修复了设置面板的三处显示缺陷。

共享工作区白名单

  • 设置面板新增「共享工作区」多选列表:只把勾选的工作区开放给局域网访客;不勾选任何工作区时默认共享全部。
  • 白名单在访客通道全部端点生效:目录、文档读取、搜索、新建、保存都按范围过滤,白名单外的工作区对访客完全不可见。
  • 被拒请求一律返回 404(而不是 403),不向访客泄露受限工作区的存在。
  • 白名单实时生效并持久化,重启后保留;主应用自身功能零改动。

设置面板修复

  • 开关视觉:共享开关改为滑动开关样式,开启/关闭状态一目了然。
  • 信息区显隐:关闭共享后访客地址/口令区块现在会正确隐藏(此前被样式覆盖无法隐藏)。
  • 地址与口令刷新:修复响应解包缺陷——此前开启共享后地址与口令一直显示「—」、复制按钮无效。

自动化测试 284 项全绿;局域网共享端到端探针新增共享范围断言。

v2.3.4 · 局域网共享可用性修复

v2.3.3 的「局域网共享」在真机端到端验证中发现两处缺陷,本版修复。

修复内容

  • 访客配对协议:口令校验接口此前多包了一层响应信封,访客页按扁平格式读取,导致输入正确口令后无法进入访客页。现改为扁平响应,与访客端错误响应及其他接口约定一致。
  • 会话态读取:只读/可编辑状态接口同样多包一层,访客页的只读标记与保存按钮禁用判断恒失效。同版修复。
  • 回归锁:新增自动化结构断言,钉住「访客协议端点必须扁平返回」,防止未来重构再次引入包装层。
  • 验证基建修正:本机安全探针的伪造 Host 探测改用原生 socket 发送——此前使用的 fetch 会忽略自定义 Host 头,把请求的 Host 覆写回本机地址,导致 Host 守卫被误判为失效(实际守卫一直正常)。
  • 局域网共享行为验证脚本:同步修正管理接口响应解包,端到端探针与真实访客协议对齐。
  • 升级提示:桌面主界面与既有功能零改动;若你已开启共享,升级后访客需重新输入口令(口令本身不变)。

自动化测试 283 项全绿(新增访客协议回归锁);主界面与既有功能零改动。

v2.3.3 · 局域网共享 + 13 项安全审计修复

这个版本干了两件事:把你的知识库安全地开放给同一局域网的设备,以及把此前一次系统性安全审计里发现的 13 项缺陷全部修掉。

局域网共享:口令配对,访客白名单

  • 设置面板新增「局域网共享」开关。开启后显示访客地址与 6 位口令,同网段设备用浏览器打开、输口令即进轻量访客页。
  • 访客可浏览与搜索全部工作区文档;「可编辑」模式下还能新建和修改文档,保存冲突(他人正在改同一篇)会明确提示二选一,不做静默覆盖。
  • 安全模型是「白名单内才存在」:删除、移动、重命名、目录浏览、AI 与系统功能对访客不提供任何端点;口令连错 5 次锁定 60 秒;只读 / 可编辑两档运行中随时切换。
  • 独立监听通道与桌面应用完全隔离,关闭开关或退出应用端口立即关闭,数据全程不出局域网。

安全审计:13 项修复

  • 分享链接不可枚举:临时分享从「表级读权 + 链接保密」升级为「远程调用白名单 + 链接保密」,第三方无法靠猜 id 批量扫库。
  • 路径穿越防护:读写删移统一路径净化 + 落点包含性校验(拒 ..、盘符、NTFS 数据流、软链逃逸),独立 Rust 单测锁定。
  • DNS rebinding 封堵:本地服务只接受回环 Host,恶意网页无法把自己变成「同源」来调本机接口。
  • 保存竞态加锁:指纹比对与落盘进同一临界区;撤销分享改为真删数据并验证生效;分享体积上限与超限如实计数等。

自动化测试 282 项全绿;独立 Rust 路径守卫单测 5/5;旧版本漏洞基线实测 4/4 复现后修复。

v2.3.2 · 分享取图兜底链:工作区换 id 后老文档的图也能带走

v2.3.1 修完图片丢失的当晚,真实使用又踩出了第三种形态——修复本身没错,但少了一道兜底。

这次是什么情况

  • 截图按工作区归档,老文档里的引用带着当时的工作区 id。工作区一旦重建,id 就换新了,老 id 在注册表里查无此项。
  • v2.3.1 的取图逻辑是「按 id 精确取」——解析是对的,但 id 失效后 404,图片再次静默丢失。
  • 而编辑器预览一直显示正常:预览走的端点自带兜底,id 找不到时会按文件名扫描所有工作区。

修复:取图兜底链

  • 先按工作区 id 精确取(快、准);取不到自动落到预览用的同一个端点——预览能看到什么,分享就带什么,两条通道彻底同源。
  • 写进云端的键保持原样引用路径,访客侧匹配不受影响;老分享重新点一次「生成分享链接」即可补齐图片。
  • 缺失依旧如实计数显示(「N 张未找到」),不做静默吞错。

自动化测试 266 项全绿;真浏览器端到端 17/17(新增「失效 ws id 经 /source 兜底取到图」两条断言)。

v2.3.1 · 分享体验修复:图片丢失、复制无响应、缺目录

v2.3.0 把临时分享带上桌面之后,第一批真实用户反馈来了三个问题,这一版全部修掉。

图片在生成分享那一刻就丢了

  • 现象:文档里的截图在分享页全部显示「这张图片没有随分享一起带走」,云端数据里资产数是 0。
  • 根因:截图保存时按工作区归档,文档里的引用形如 /source/ws_xxx/截图.webp——ws_ 这一段其实是工作区 id。生成分享时它被当成了 source/ 底下的一个子文件夹,去一条根本不存在的路径找文件,全部按「找不到」静默丢弃。
  • 修复:按正确语义解析——ws_ 段还原成工作区 id 去取本机字节;写进云端的键也改成与访客侧匹配规则同一套命名,取到了图还要能对上号才算修完。
  • 旧分享重新点一次「生成分享链接」即可自愈:同一文档复用同一条链接并补齐图片,链接不用作废重发。

代码块「复制」点了没反应

  • 渲染器生成的复制按钮只有个壳:工作台页面自己绑了点击事件,分享页从没绑过。
  • 分享页已补上同样的绑定,并加了两处增强:不支持剪贴板 API 的环境(如微信内置浏览器)自动退回老方法;点击后按钮直接显示「已复制 / 复制失败」。此修复已在线上生效,无需升级。

长文档没有目录索引

  • 工作台阅读区一直有左侧「本文目录」,分享页却没有。现在正文右下角有浮动「目录」按钮,点开右侧抽屉:标题逐级缩进、点击平滑跳转、滚动时高亮当前小节。
  • 没有标题的文档(纯文字笔记、独立 HTML 页)不显示按钮。此修复同样已在线上生效。

自动化测试 265 项全绿;真浏览器端到端 13/13(新增 ws_ 引用取图与写库键断言)+ 目录专项 8/8。

v2.3.0 · 桌面端临时分享链接(支持自动过期)

手机端早就能把文档临时分享给外部的人,桌面端一直没有入口。这一版补齐,并且把「什么时候失效」交给数据层而不是前端。

入口与操作

  • 「文件」菜单新增 🔗 分享链接…:选有效期(1 天 / 7 天 / 30 天 / 永久有效)→ 一键生成只读链接 → 复制发出,对方无需登录即可阅读。
  • 弹窗下半部分是「我的分享」:这条文档已有的链接、还有几天到期(≤2 天转为警示色)、随时撤销。
  • 有效期选择会记住,下次打开沿用;同一文档重复分享复用同一条链接,只更新内容与到期时间,不会每点一次堆一条死链。

过期由数据层保证,不是前端判断

  • 云表新增到期时间字段,公开读取策略改为「未撤销且未过期」才下发 —— 链接到期后连内容都取不到,本地改系统时间也绕不过去。
  • 访客侧再做一次兜底:链接已失效时明确提示「可能已到期自动失效,或被分享者撤销」,不再是含糊的「已撤销或输入有误」。
  • 分享页会显示具体到期日期,接收方知道这条链接还能用多久。

安全边界不变

  • HTML 文档上传前剥离脚本与内联事件,转成「云端安全形态」——本机文件一个字节不动,只有云端那份受限。
  • 文档里引用的图片随分享一起带走(最多 20 张,大图压成 WebP),对方打开不会看到一片空白。
  • 分享链接只读,不能写入、不能列举你的其他文档;撤销后立即失效。

自动化测试 264 项全绿;真浏览器端到端 13/13(含到期写入、链接形态、剩余天数、复用、撤销、HTML 剥离)。

v2.2.7 · 打开即误报修复 + 高亮全面适配主题

三类问题一次收口:跨编码文档的误报与编码保真、代码高亮的主题适配、自定义颜色的主题记忆。

非 UTF-8 文档:不再打开即误报「外部修改」

  • 根因:打开文档与后台轮询对同一份磁盘文件用了两种指纹口径(解码字符串 vs 磁盘原始字节),非 UTF-8 文件(GBK/ANSI 老文档)两者必不相等 → 打开 5 秒后必弹「文件已被外部修改」并反复出现;UTF-8 文件两口径恒等所以从未暴露。
  • 修复:整条链路(打开 / 轮询 / 冲突检测 / 保存返回)统一为磁盘字节口径;索引里的编码字段同步刷新,状态栏不再错显。
  • 保存保留原编码:普通保存(Ctrl+S)按文件当前编码写盘,GBK 文件不再被静默转成 UTF-8;只有显式在编码菜单里换编码才转换。

代码高亮:五套主题全套配色

  • 暗色主题此前漏定义变量 / 函数 / 标签 / 属性 / 元信息的颜色,回落到浅色主题的近黑值,在深底上被背景吞掉(用户截图实锤)——现按暗色板补齐:变量暖浅灰、函数暖金橙,与关键字 / 字符串 / 数字清晰区分。
  • 图片主题新增「深色背景图」整套亮色变体,跟随背景图明暗自动切换;浅色 / 护眼 / 柔光主题 24 项历史低对比颜色按 WCAG AA 加深一档(色相不变)。
  • 六组主题环境 × 15 种 token 的 WCAG 对比度实测 90/90 达标(正文级 ≥ 4.5:1、装饰级 ≥ 3:1),并沉淀为常驻审计脚本。

自定义颜色:按主题记忆 + 一键恢复默认

  • 设置里的 Markdown 文字高亮与代码语法高亮自定义颜色改为按主题分别记忆:每个主题独立一套,切换主题使用该主题的自定义配色(未自定义则跟随主题默认),不再全局一套串色。
  • 两个区域各新增「恢复默认颜色」按钮:一键清除当前主题的自定义、回落主题最佳配色,其他主题不受影响。
  • 顺带修复自定义代码高亮色重启后丢失的旧问题;已有自定义会自动迁移到设置时的主题名下,无需重新设置。

自动化测试 260 项全绿;真浏览器端到端 21/21;编码往返与对比度审计全通过。

v2.2.6 · 状态栏编码切换 + 代码编辑增强

两项编辑器基础能力补齐:跨编码文件(GBK/ANSI 老文档)与代码文件的编辑体验。

文件编码:状态栏直接换,保存即生效

  • 底部状态栏的编码项(如 UTF-8)现在可以点击,弹出菜单列出 10 种常见编码:UTF-8、UTF-8 (BOM)、ANSI (GBK)、GB18030、Big5、UTF-16 LE / BE、Shift_JIS、EUC-KR、Windows-1252,当前编码带勾选标记。
  • 选择后确认即按所选编码保存覆盖磁盘文件(未保存的修改一并写入);状态栏立即更新,且不会误报「文件已被外部修改」。
  • GBK 无法表示的字符(如 emoji)会写成数字字符引用(😀)而不是丢失或乱码;UTF-16 写盘按码元手工编码,规避了底层库对 UTF-16 编码静默回退 UTF-8 的坑。

代码文件:缩进参考线 + 语法着色

  • 缩进参考线:每个缩进层级画一条竖线(与主流编辑器同规则),缩进单位(2~8 空格或 Tab)按全文自动探测。
  • 语法着色:按扩展名启用(vbs/vb/js/ts/java/c/cpp/cs/go/py/sh/bat/sql/lua/ini/yaml/json 等约 40 种),关键字、方法与函数名(定义加粗)、内置函数、字符串、数字、注释、常量、运算符分色。
  • 零新增依赖;Markdown、txt、html 与未知扩展名保持原有行为,完全不受影响。

顺手修复

  • 两个预存缺陷:窗口一缩放就抛 closeAllMenus is not defined 与 applyLayout is not defined(处理器引用了局部作用域函数)。

实测与回归

  • 自动化测试 251 项全绿;真浏览器端到端 13/13(GBK 打开不乱码、菜单/确认/转换/重开全链路、竖线与 8 种 token 颜色、Markdown 零影响)。
  • 编码往返专项 11/11(GBK / GB18030 / Big5 / Shift_JIS / EUC-KR / Windows-1252 / UTF-16 LE·BE / UTF-8 BOM,含 BOM 识别与不可映射字符处理)。

v2.2.5 · 云同步可靠性修复(被平台拦下的文档不再静默失败)

实机反馈:个别 .html 文档点「一键推送」永远传不上云端,面板只显示一句「失败」,原因完全看不出来。用 Node 直连云端数据面(不受浏览器跨源约束)复现后拿到了服务端的真实响应。

真因:上传正文被平台内容安全策略拦下

  • 接口本身正常:跨源预检返回 204 并放行全部请求头,同一批纯文本与普通 Markdown 全部写入成功。
  • 被拦下的是正文特征:命中 <script>(连 <script></script> 空标签都算)或内联 onclick= 的文档,服务端返回 403「WAF拦截页面」。与文件名是否中文无关、与文件体积无关(10~80 万字符纯文本都能写入)。
  • 误导点:这个 403 响应不携带跨源响应头,浏览器与官方 SDK 一律翻译成「缺少 Access-Control-Allow-Origin 头」,于是问题看起来像跨源配置错误,实际是服务端拒绝。

修复

  • 云端安全形态:推送前把 HTML 里的脚本剥离掉再上传(<script> 三种写法、on* 内联事件、javascript: 链接),并在文档顶部留下标记。本机文件一个字节都不动——剥离只发生在发往云端的那一份。
  • 失败不再静默:批量推送改为逐篇重试,哪一篇失败、失败原因是什么,直接写进同步结果面板。
  • 被拒自动降级:只有被平台拒绝的 HTML 才走剥离重试,同批其他文档不受牵连;Markdown 等不受内容策略影响的文件保持原样。
  • 不再误写基线:失败文档不再被标记为「已同步」,下次点推送会重试(此前一旦失败就永不重试)。
  • 拉取侧保护:从云端拉回时识别「安全形态」标记,不会用云端被剥离的版本覆盖本机完整正文。
  • 云端与分享页提示:阅读该文档时说明栏会写明「云端版已按平台安全策略移除脚本,本机阅读不受影响」,访客不再把纯静态页面当成加载故障。

实测与回归

  • 真浏览器端到端验证 13/13 通过(假本机服务 + 按正文特征拒写的桩 SDK + 真实云端工作台页面):含脚本文档推送成功、本机文件逐字节不变、同批 Markdown 不被连带、面板原文可见。
  • 自动化测试 245 → 251 全绿,新增「剥离后本机不变」「同批不连带」「被拒不写基线」「剥离实现两端同源」等回归。

说明

  • 剥离是规避而非根治:平台侧对数据库接口请求体的内容检测仍在。已按最小改动原则处理,提交给云端的副本不含脚本,也不影响本机预览与编辑。需要脚本交互的网页,本机打开完全正常。

v2.2.4 · HTML 文档阅读体验修复(更宽、更顺、有缓存)

实机反馈:手机上打开 .html 文档,页面比浏览器里窄一截、长网页卡顿、反复打开又慢。用真浏览器把「浏览器直接打开」和「应用内沙箱预览」放在同一份 542KB 文档上对跑,三个问题的成因都拿到了实测数据。

问题一:页面变窄(两个成因)

  • 响应式网页:预览被正文区的左右留白与卡片边框挤掉 34px,手机 390px 屏上只剩 356px(约 91%)。
  • 固定宽度网页(导出型 HTML 很常见):1100px 的设计宽度在帧内只剩 32%,表格右半必须左右拖动才看得见。

问题二:长网页不流畅(高度被截断)

  • 预览帧的高度上限写死在 20000px,超长网页会被截断,变成「外层滚 + 帧内滚」两层滚动,滚动时两层互相抢手势。实测一份 542KB 文档内容高 44 万 px,只显示了 1/22。
  • 单次装载还会在主线程上阻塞 67–100ms(肉眼可见的顿挫)—— srcdoc 是整份字符串,每次都要重新解析。

问题三:没有缓存

  • 同一份文档连续打开三次耗时 0.27s / 0.19s / 0.23s,完全不收敛:srcdoc 没有 URL,浏览器 HTTP 缓存用不上;云端每次打开都全量重建预览帧。

修复

  • 高度上限提到 200000px:长网页完整撑开,不再双层滚动。实测 7.2 万 px 的网页从「截到 20000px」变成「72062px = 内容高」。
  • 补上「放大」全屏入口(云端与分享页此前没有):全屏后预览帧铺满视口,宽度利用率回到 100%,用 100vh 排版的页面也回到真实视口高度。按钮常显——触屏没有悬停态,照搬桌面端那套「悬停才出现」在手机上等于没有按钮。
  • 补齐缓存:打开过的文档正文与「找引用 → 批量签名 → 改写资源」的成品预览都在会话内缓存,返回列表再点回来不再重新拉取与重建。实测重开:0 次网络请求、0 次签名、84ms(首次 190ms)。
  • 顺手修:桌面端点「放大」后关闭不恢复页面滚动,会导致整页再也滚不动。

说明

  • 为安全起见,预览始终运行在沙箱里(网页脚本读不到你的登录态与知识库)。因此与「浏览器直接打开」仍有少量固有限制:localStorage / Cookie / 缓存 API 不可用、100vh 按预览框高度计算(全屏后即恢复正常)。这些是沙箱本身的边界,本次未改动。

实测与回归

  • 真浏览器移动端(390×844、微信 UA)自动化验证 24/24 通过;云端与分享页双跑。
  • 自动化测试 241 → 245 全绿,新增「三端高度上限同值」「放大入口契约」「浮层样式常显」「双层缓存与失效点」四条回归。

v2.2.3 · 图片同步修复(真的传上去了)

实机反馈:桌面端点了「一键推送」,文档都在,手机和网页上引用的截图却全是「未同步」。上一版给同步链路补上了图片上传代码,可一查云存储 —— 对象总数是 0。一张都没传上去过。

根因:平台 CORS 白名单挡住了官方 SDK 的存储请求

  • 不是权限、不是路径、不是账号:RLS 策略齐全且与代码一致,路径拼接正确,用桌面端的真实登录凭据直连上传可以成功 —— 平台侧完全正常。
  • 差别在浏览器才校验的 CORS 预检:官方 SDK 每次存储请求都会带 X-Client-Info(上传另加 X-Upsert),而平台的跨源放行头里没有这两个。浏览器因此判定预检失败,请求根本不发出(控制台报 blocked by CORS policy / net::ERR_FAILED)。
  • 为什么文档没事、只有图片出事:登录与数据库用到的头都在白名单内,所以同步文档一路正常;只有图片这一路会踩到那两个头。云端网页端与手机端因为和接口同源、不触发预检,也一直是好的 —— 问题只在桌面端(跨源)。
  • 真浏览器对照实测:用 SDK 走 upload / exists 被 CORS 拦下;换成只带白名单头的等价请求,POST / HEAD 都能抵达服务器。

两个让故障静默的放大器

  • 失败也照写「已核对」戳:上传抛错被逐文件捕获后,核对戳照写不误 —— 意思是「这篇引用的图片都确认在云端了」。于是第一次失败就永久跳过,之后每次同步都报「内容已一致」,看起来像没事发生。
  • 异常被静默吞掉:错误连一条日志都没留下,面板上只显示「同步完成」。

修复

  • 资产上传不再走 SDK:改为只携带平台白名单内请求头的直连请求,请求体沿用同一份 multipart 契约(cacheControl 分片 + 无名 Blob 分片),云端行为不变。已有对象照样先探针、不重传。
  • 失败可见:逐文件收集去重后的失败原因,写进同步结果与提示(「图片失败 N 张(原因)」),控制台也有明细。
  • 只有零失败才写核对戳:出错的下次同步会自动重试,不需要手动清状态。
  • 旧核对戳一次性作废:旧版本留下的戳是「失败也写」的代码产生的,不可信。升级后第一次同步会整批重新核对 —— 老库点一次「一键推送」就能把历史缺失的图片补齐,而不是直接跳过。
  • 类型兜底:本机服务没给出 content-type 时按扩展名补上,避免图片在云端落成通用二进制、手机端变成「下载」而不是直接显示。

实测

  • 清掉云端对象后用修复后的内核重跑:assetPush: 3 / assetFailed: 0;再跑一次 assetExists: 3 / assetPush: 0(不重传)。
  • 数据库实查:云存储出现 3 个对象,MIME 为 image/webp,字节数与本地文件逐一对上;取回地址返回 200,手机与网页现在就能正常显示这些截图。
  • 自动化测试 235 → 237 全绿,新增「失败要可见且不得写核对戳」「旧世代核对戳必须作废」两条回归。

升级提示

  • 装好 2.2.3 后,请对每个工作区点一次「一键推送」:历史缺失的图片会在这一次补齐,之后就不会再重跑了。(云端网页端与手机端无需更新,它们本来就正常显示。)

v2.2.2 · 独立的 .html 文件同步到云端

实机反馈:工作区里的 hello.html 在桌面端能打开、能预览、能搜到,云端却怎么都找不到。一查,不是同步坏了 —— 是同步的白名单压根没放行 .html。

根因:桌面端把 .html 当一等公民,只有同步层没跟上

  • 本机侧一直是支持 html 的:索引照常收录(只要不是二进制类型)、阅读态用沙箱网页渲染、检索会先剥掉标签再匹配。所以你在应用里能看到、能打开、能编辑、能搜到。
  • 同步侧的扩展名白名单只认 Markdown 与纯文本:.html 从没进过同步判据 —— 不推、不拉,连「失败」都不会报,静默地当作不存在。同一个白名单还在网页端的手动导入、压缩包导入里挡着,所以从网页端选文件也是那句「不是可同步的类型」。
  • 实测证据:默认工作区 12 个文件,8 篇 md、2 篇 txt 逐一对上云端,hello.html 与 test/small.json 一个都没有。

桌面端

  • 白名单放行 .html / .htm / .xhtml,它们与 Markdown 一样参与三路同步(推送 / 拉取 / 冲突检测)。
  • 单个 HTML 文档设 1.2MB 上限:云端正文是一列文本,整页 HTML 不设限会把列表与检索拖慢。超限的文件会跳过并在同步结果里明确报「N 个 HTML 文档过大未上传」,不会悄悄丢掉。
  • 标题取页面 <title>:HTML 文档的标题不再被正文里的 # 行误判,与桌面端本机的取标题规则一致。
  • 文档里的图片一起上云:HTML 里 <img> / <video> 引用的本机资源走上一版打通的图片同步链路,缺哪张补哪张。

云端工作台与分享页

  • 按扩展名分派渲染:打开 .html 文档不再被 Markdown 渲染成一堆标签文本,而是装进与本机同款的沙箱网页里原样呈现(脚本能跑、表单能用,但读不到你的登录态与知识库)。
  • 图片引用在入帧前改写:沙箱网页是独立来源,外层碰不到帧内内容,所以图片地址在塞进去之前就替换好 —— 工作台换成云存储的短期签名地址,分享页换成随分享快照一起带走的图片。
  • 检索片段先剥标签:HTML 文档的搜索结果不再是一屏 <div> 噪声。
  • 导出按原后缀:导出 HTML 文档得到的是 .html,不再一律给 .md。

为什么 .json / .csv 仍然不同步

  • 工作区里的 .json 常常是配置文件(插件设置、令牌、密钥),一旦随工作区自动上云就是一条泄漏通道;权限隔离只认账号,分享出去或账号失窃都会外泄。本轮按「只放开网页文件」的范围收口,.json / .csv 保持不同步,并有测试锁死这条边界。

v2.2.1 · 手机端截图不再是「未同步」

三条实机反馈一起修:桌面端推上云的笔记,手机 / 网页打开图片全是一排「未同步」;分享出去的网页只显示顶上一条、要在一个小窗里套着滚;安卓应用启动的第一帧是一个系统占位图标。

桌面端「一键推送」补齐图片 / 视频(关键修复)

  • 根因:桌面端的同步内核只搬正文,从来没有上传过图片字节 —— 用「一键推送」推上去的库,文档在、图片全缺,手机 / 网页自然只能显示「未同步」。云端工作台那条上传链路是好的,所以问题只在桌面端推的库上。
  • 图片随笔记一起上云:推送时逐篇读本机正文、解析出笔记里引用的图片 / 视频,云端缺哪张才补哪张。对象路径与文档的相对路径同构(users/<账号>/assets/<分区>/source/x.webp),两端算出的是同一条路径,不需要映射表。
  • 老库能修回来:按「笔记里的引用」判断,而不是按「笔记有没有变」。此前推送过的库正文全都一致、图片全缺 —— 只按内容指纹判断的话这类库永远修不回来。现在再点一次「一键推送」即可补齐。
  • 不重复上传:云端已有该对象时只发一次 HEAD 探针、不上传;正文与图片都核对过的笔记会记下核对戳,后续同步不再重复读正文,库越大越省。
  • 结果如实报数:补传几张、本机找不到几张、超过 12MB 几张、失败几张,分项列出;全部已同步时也会说明「N 张引用图片也都在云端」,而不是笼统一句「没有需要同步的内容」。
  • 云端工作台补探针:本地上传清单命中时不再直接跳过,而是先向云端确认对象确实存在 —— 历史上传失败、换账号登录、对象被清掉留下的「清单说有、云端没有」死记录,现在会被发现并补传。

分享出去的网页不再被压在小窗里

  • 补上缺失的样式:分享页没有内嵌网页卡片的那几条样式,帧落回浏览器默认的 300×150,长网页只能在小窗里嵌套滚动 —— 这就是「显示不全」。
  • 高度自适应一并搬过去:帧内把真实内容高度上报给外层,外层把网页撑到内容高度;高度限制在 240px ~ 20000px,且只认自家帧上报的消息。

安卓启动第一帧

  • 启动图标不再是系统占位图:启动主题沿用了 Android 官方启动屏模板,其中的启动图标默认值是系统自带的占位图标、底色是系统默认色 —— 启动第一帧会看到一个不属于本应用的图标。现已显式指定为品牌方牌与品牌底色(浅色 / 深色各一套)。
  • 收屏时机受控:接入原生启动屏插件,启动屏一直盖着,直到云端页面首个视图真正渲染完成才收起,最长 5 秒(断网、加载失败也不会卡在启动屏)。
  • 消除「未套样式」首帧:云端页把首屏骨架样式内联在页面里,不再等外链样式到位;外链到达后由它接管,期间零跳变。

Android 客户端 1.1.2

  • 包含以上启动屏与图标修复。手机端图片显示不需要安装新版本 —— 云端界面随网页端即时生效,把桌面端升到 2.2.1 后再点一次「一键推送」即可补齐历史图片。

v2.2.0 · 重命名后缀修复

实机反馈:把 hello.md 重命名成 hello.html,落盘却成了 hello.html.md —— 输入的扩展名被静默改写。本轮把它修掉,并顺带放宽同类的移动限制。

桌面端

  • 显式扩展名被尊重:重命名时写了后缀就按写的来(hello.html → hello.html);此前后端对文件名一刀切,凡不以 .md 结尾一律追加 .md。
  • 裸名字行为不变:不写扩展名时仍自动补 .md(输入 hello 得 hello.md),旧习惯不受影响;目录重命名永不补后缀。
  • 移动限制同步放宽:此前非 Markdown 文件一律禁止移动(「Only .md files can be moved」),而 .html 等文件自 2.1.41 起本就进索引、可渲染 —— 现允许移动。
  • 「仅显示 md」的边界改为明确提示:该开关是视图过滤,在这类工作区里把文件改成其它后缀会导致它从列表消失(文件仍在磁盘)。重命名 / 移动时会明确拒绝并指路(设置 → 工作区 取消勾选「仅显示 md」),不再静默改写输入。
  • 健壮性细节:非法字符净化后处理结尾的点,绝不产生 hello..md 这类名字;扩展名判定大小写不敏感(.HTML 与 .html 等价)。

同批包含 2.1.42 的内容

  • 内嵌网页体验修复:修「点放大没反应」(浮层样式选择器带错前缀,永远匹配不上);内嵌网页按内容高度自适应,整页网页不再挤在固定小窗里嵌套滚动。

v2.1.42 · 内嵌网页体验修复

v2.1.41 上线内嵌网页渲染后收到两条实机反馈:点「放大」没反应;网页只显示顶上一条、要在一个小窗里套着滚动。逐条修掉,三端(桌面 / 网页 / 手机)同步生效。

修复「放大」没反应

  • 根因是样式选择器带错前缀:全屏浮层是挂在页面最外层的,而样式规则却写成了「必须是正文容器内的后代」才生效 —— 浮层永远匹配不上,点击后其实创建了浮层,但它没有任何尺寸与位置,看起来就是「没反应」。去掉前缀后浮层正常铺满窗口,点背景或 × 关闭,Esc 也可关。
  • 真浏览器实测:浮层计算样式 position:fixed、z-index 9999、尺寸与视口完全一致。

内嵌网页按内容高度自适应

  • 不再挤在小窗里:此前内嵌网页固定高度(正文里约一屏的三分之一),整页网页只能在小窗里嵌套滚动,手机上尤其难受。现在帧内把实际内容高度上报给外层,外层把网页撑到内容高度 —— 网页多高就显示多高,像看普通长文一样顺着滚。
  • 动态页面也跟着长:内容高度变化(图片加载、展开折叠)会持续上报,高度实时跟随;内容变矮时高度也会回落。
  • 异常值有边界:高度限制在 240px ~ 20000px 之间,且只认自家内嵌帧上报的消息 —— 页面里其他来源的同名消息不会生效。
  • 三端同一份实现:桌面端与云端共用同一渲染器,网页端与手机端(安卓应用加载云端页面)同步获得此修复,无需重新安装应用。

v2.1.41 · HTML 文件渲染

知识库里常有些从浏览器另存的 .html:抓下来的技术文档、导出的报告、单页小工具。此前打开它们只能看到源码,要看得见效果就得切到浏览器。这一版把编辑 / 阅读两种形态都补齐,同时收紧了渲染所依赖的安全边界、修掉了 HTML 带来的检索噪音。

打开 .html 就像打开网页

  • 双轨与 Markdown 一致:打开仍是编辑态(左栏源码可改可存),右侧预览把网页画出来;切到阅读态则整页渲染。保持「打开即编辑」的既有心智,不引入新的操作路径。
  • 可放大全屏:预览右上角「放大」按钮复用既有的全屏浮层,长页面与小屏都看得舒服。
  • 内容没变不重跑脚本:预览按内容指纹去重,编辑时输入不会让页面里的脚本反复执行一遍。
  • 阅读态延时装载:只有真正切到阅读态才装入页面,因此同一篇文档不会同时跑两份脚本;切回编辑态会自动卸掉后台那一份。
  • 相对资源说明,不假装渲染坏了:内嵌渲染的解析基准没有目录,./style.css、./img/a.png 这类同目录引用取不到,页面顶部会明确提示「相对路径资源不可用」;指向外部的 http(s) 样式、脚本与图片照常加载。

安全:渲染不可信网页不能等于放权

  • 去掉同源授权:渲染容器此前同时开启了脚本执行与同源(allow-scripts + allow-same-origin),这两项同给等于沙箱失效 —— 网页里的脚本可以直接访问宿主页面、读取登录状态、调用应用能力。现在只保留脚本执行,同源被摘掉,脚本能跑但拿不到宿主。
  • 实测验证:真浏览器对照测试,新策略下网页内的 parent.document、localStorage、应用能力入口全部被拒(SecurityError),宿主也读不到容器内部文档;旧策略下这三项全部可达。
  • Markdown 里的 HTML 代码块同步收紧:同样的容器也用在 Markdown 的 HTML 围栏上,一并按新策略处理,不让旧组合留在别处。

检索不再被标签噪音淹没

  • 按文件类型产出纯文本:索引取词改为按扩展名分派 —— Markdown 去语法、HTML 去标签与脚本样式、其余格式原文保留。此前 HTML 是带着标签整段入库的,全局搜索会命中一堆 <div class="...">。
  • 实体与注释一并处理:&nbsp; 这类转义会还原成字符,注释与 style / script 内容不进索引。
  • 标题取 <title>:HTML 文档的标题改为读取页面 <title>,不再被正文里恰好以 # 开头的一行误判。
  • 顺带修掉一处既有缺陷:代码类文件此前会被无条件按 Markdown 去语法,把 * [ ] # 等符号抹成空格,导致搜索这类符号时命中不准;现在非 Markdown 文件原文保留。

沉浸模式与云同步不受牵连

  • 沉浸模式的块级渲染只对 Markdown 生效:HTML / 代码 / JSON 仍可进入沉浸(界面照旧精简),但不会把源码按 Markdown 语义解析 —— 否则标签会被当成语法渲染坏掉。
  • HTML 不进入云文档表:云同步的文本类型本来就只有 Markdown 与纯文本,HTML 不会写进云端文档内容列、不会撑大体积,本次以测试锁定该边界,防止将来误加。

v2.1.40 · 图片同步补齐(手机端截图不再是裂图)

此前笔记里的截图只在桌面端正常:桌面端直接读本机 source/ 目录,而云端与手机端拿不到这些文件, 也没人把它们传上去 —— 上传链路只收 Markdown / 文本。这一版把这条链补齐。

图片与视频随笔记一起上云

  • 上传侧放行图片 / 视频:网页端选择文件夹或文件、拖拽、zip 包,以及桌面端「一键推送」,都支持 png / jpg / webp / avif / svg / gif / mp4 / webm 等常见格式;此前这些文件被静默丢弃,界面上看不出任何异常。
  • 图片绝不写进正文:资源单独进云存储,按 分区/相对路径 与笔记同构存放,所以笔记里写 source/x.webp 就能直接对上,不需要维护映射表;一篇 20 图的笔记也不会因此把正文撑大、拖慢列表与检索。
  • 先图后文:图片先落地,文档正文随后入库 —— 反过来的话,点开笔记先看到的是一排「未同步」。

手机端 / 网页端:图片真的显示出来

  • 渲染时自动改写地址:正文渲染完成后,把 source/…、/source/…、ws-asset/… 三类本机相对引用换成云存储的短期签名地址(存储桶不对外暴露公开地址,读也必须签名)。
  • 缺图给占位,不给裂图:云端确实没有这张图时,渲染成「未同步 + 原路径」的提示条,而不是让用户对着一张裂图猜原因;外链(http / data / blob)原样交给浏览器,不会被误当成存储对象。
  • 本机旧库能修回来:图片按「笔记里的引用」同步,而不是按「笔记有没有变」。此前推送过的知识库正文全都一致、图片全缺 —— 只按内容指纹判断的话这类库永远修不回来。现在再点一次「一键推送」即可补齐。

增量与提示

  • 按体积增量:同一分区同一路径、体积没变就跳过重传;先用 HEAD 探体积,连整张图都不用下载。换账号、删除分区、清空云端都会作废对应的上传记录。
  • 结果如实报数:新增 / 更新 / 跳过未变(文档与图片分开)、图片上传失败、超过 12MB / 单文件上限被跳过、被忽略的不支持文件,逐项列出 —— 不再静默丢弃让用户以为传成功了。

Android 客户端 1.1.1

  • 图标与启动图重制:与网页端统一为「殿宇拱弧 + 知识核心 + 展开的书」的品牌标识;启动图改用带品牌底的方牌,浅色与深色启动背景下都清晰。
  • 云端工作台的内容更新随网页端即时生效,无需重新安装应用。

v2.1.39 · 首轮实机反馈修复

v2.1.38 发布当天收到第一批实机反馈:面板看不到推送到了哪、没法选工作区、明明有笔记却提示「暂无 Markdown」。逐条修掉。

桌面端:修「永远 0 篇」,补面板信息

  • 修复「可同步内容恒为暂无 Markdown」:后端字段是驼峰命名(workspaceId / contentSha256),前端按旧拼写读取导致永远匹配出 0 篇,推送自然「没有需要同步的内容」;同时修复了拉取时冲突检测因此整体失效的隐患。实测同一台机器:默认工作区 10 篇、temple 110 篇全部正确读出。
  • 显示推送目标:面板标明推送到哪个云端、落到哪个分区,不再「点了不知道传去哪」。
  • 工作区可选:多工作区可下拉选择要同步的工作区(选项里带各工作区篇数),选择会被记住;此前锁死默认工作区,别的库根本推不上去。
  • 提示语具体化:无事可做时不再笼统一句「没有需要同步的内容」,而是说明原因——例如「云端此分区还是空的:用『推送本机 → 云端』可上传本机 N 篇」「内容已一致(本机 11 篇 = 云端 11 篇)」。

云端 / Android:登录界面重排

  • 验证码是主路径:密码框默认隐藏,只在首次注册、切到密码登录、找回密码三种情形出现;此前验证码、密码、找回三套控件同时摊在一张卡上,看不出该走哪条。
  • 密码登录入口改为切换:「用密码登录 / 改用验证码登录」一键往返,提交按钮文案随形态变化(登录 / 注册 → 登录 → 确认重置密码)。
  • 触控目标加大:发送验证码等按钮加高到 42px,间距与聚焦反馈统一。

v2.1.38 · 三端直连打通

v2.1.37 让笔记上了云,但桌面端自己还连不上云——只能在浏览器里绕一圈。这一版把绕的那一圈去掉了:电脑、手机、网页三端各自直连同一份数据。

桌面端:双向同步,本机优先

  • 不用再开浏览器:桌面端「云端同步」面板里直接登录(邮箱验证码 / 手机验证码 / 邮箱密码),登录后即可拉取与推送。
  • 新增「拉取云端更新」:在手机上改过的笔记,回到电脑点一下就同步下来;此前只能上传、不能拉回。
  • 本机永不被静默覆盖:同步前先核对"上次同步时的内容指纹",只有确认本机没动过的文件才会被云端版本替换;写入时再比对一次磁盘内容,中途被外部编辑器改过就自动放弃覆盖。
  • 两端都改过 → 各留一份:本机内容原样保留,云端那一版另存为 原名.conflict-云-时间.md,两边都不丢。
  • 删除更安全:云端删除只提示、绝不删本机文件;本机删除则给云端打一个可恢复的删除标记,而不是物理删除。

Android 应用 1.1.0:补齐手机该有的能力

  • 返回键按层级回退:先关弹层,再退出文章,最后才退出应用,不会再一点返回就退出。
  • 分享 / 复制 / 导出:文章页底部多了一排按钮,可以分享到微信、一键复制正文、把 .md 导出到手机「文档」。
  • 断网有提示:网络断开时顶部出现提示条,已打开的正文不受影响。
  • 观感统一:状态栏配色跟随页面的暖色主题与深色模式。
  • 权限仍然最小:只申请「网络」与「网络状态」两项,不需要存储与相机权限。

其它

  • 旧的浏览器中转路径仍在:桌面端不想直连时,面板里仍可让云端页读取本机(只读接口,写操作不开放)。
  • 安装包体积:桌面版 6.62 MB;Android 版 2.73 MB。

v2.1.37 · 知识库上云 + 手机端

这一版回答一个此前一直没有答案的问题:笔记能不能不只待在这一台电脑上。新增的云端知识库工作台把工作区搬上了网,电脑和手机上都能接着写;同一个账号下,多端看到的是同一份内容。本地功能一行没动——不上云,它照样是那个纯本地的 Markdown 工作区。

云端知识库工作台

  • 浏览器直接打开:一套与桌面端同源的 Markdown 工作台,运行在 mytemple-cloud.app.workbuddy.host,不用安装,任意浏览器输网址即可使用。
  • 三种登录方式:邮箱验证码 / 邮箱密码(含找回密码)、手机验证码、微信扫码,挑一种顺手的即可。
  • 数据只属于你:文档按账号隔离,且这条规则由服务端强制执行——"只能读写自己的数据"是数据库层面的策略,不依赖前端自觉;即便有人伪造请求,也取不到别人的笔记。
  • 与桌面端同样的渲染:云端和桌面共用同一个 Markdown 渲染器,同一篇笔记在两边的排版结果逐字节一致,公式、图表、代码高亮都不打折。

桌面端:一键推送到云端

  • 不用导出再上传:桌面端「云同步」面板新增"一键推送到云端",点一下就把本机工作区送到云端工作台,随后在云端页面上确认即可完成同步。
  • 只传变化的部分:同步前先逐篇比对内容指纹,只有真正改动过的笔记才上传正文。笔记多的库不会每次全量重传。
  • 只读、最小授权:桌面端为此只向云端工作台开放了三个"读取"接口,且仅认可云端这一个来源;所有写入、删除类接口一律不对外开放,同一局域网里的其它页面拿不到你的数据。

Android 应用

  • 手机端可用:随本版同步发布配套 Android 应用,安装后相当于把云端工作台随身带着走。可在 下载页 获取安装包。
  • 断网有兜底:启动时若网络不通会显示一张离线页并自动重试,不会卡在空白页。
  • 随云端一起升级:应用承载的是云端工作台本身,工作台更新后手机端无需重新安装即可用上新功能。

修复

  • 云同步面板"可同步篇数"恒显示为空:该处此前把服务端返回的数据整体当成了列表,于是无论本机有多少篇 Markdown,都显示"暂无"。现按实际字段读取,篇数恢复正常。

影响范围

  • 本地功能零改动:编辑、预览、沉浸模式、关系图谱、知识库健康度、本地检索等既有能力的行为与数据流程完全不变;不开启云同步时,工作区仍然只在这台电脑上。
  • 回归验证:161 项自动化测试全部通过(上一版为 124 项),其中 37 项为本次新增,覆盖云端同步契约、桌面端只读授权边界与移动端打包配置三块。

v2.1.36 · 界面设计系统重制

这一版把界面的"视觉底座"重做了一遍:把长期散落在各处的颜色、间距、字号、圆角收敛成一套统一的设计令牌,让四套主题(浅色 / 深色 / 护眼 / 柔光)在同样的规则下工作;同时修掉一批"看着别扭却说不上哪里别扭"的排版与交互细节。所有改动都限定在样式与前端渲染层,功能与数据流程零改动。

设计令牌体系(颜色 / 间距 / 字号 / 圆角统一)

  • 悬空变量清零:界面样式里引用了 23 个从未被定义的颜色变量——它们不会报错,只会静静地让元素退回浏览器默认色(白底、黑字、默认蓝链接)。现已全部收敛为真实存在的令牌,实测悬空引用从 23 处降到 0。
  • 四主题配色全部达标:以 WCAG 2.x 逐项实测,浅色 / 深色 / 护眼 / 柔光四套主题的文字与图形配色对照目标全部通过 4.5:1(正文)与 3:1(图形)门槛,不达标项从 8 项降到 0。典型如深色主题下的侧栏选中项,从 1.25:1(几乎看不见)提升到 6.02:1;主题标签从 2.29:1 提升到 7.30:1。
  • 令牌分四层管理:度量与刻度(间距 / 圆角 / 字号 / 动画时长)全主题共享且主题不可覆盖,之上依次是基元色板、语义令牌、组件令牌——换主题只动语义层,不会再牵一发动全身。

正文排版三视图对齐

  • 行高统一:编辑态、预览态、沉浸态三种视图此前各有一套行高(1.66 / 1.74 / 1.82),切换时能看到文字"跳一下"。现统一为 1.78,四套主题下实测计算行高均为 28.48px,完全一致。
  • 每行字数对齐:预览栏与沉浸模式的正文版心同为 53.75em,同样字号下换行位置一致,"所见即所得"从"大概像"变成"逐行对齐"。
  • 小字号不再缩水:沉浸正文字号按文档字号的 1.04 倍放大,此前小于 15.4px 的字号会因取整而显示异常,现已全部实测通过。

沉浸模式:行内标记按最终效果渲染

  • 支持范围:段落里的加粗、斜体、行内代码、链接、删除线、高亮现在直接以排版结果呈现,不再露出 **、==、~~ 这类语法符号。
  • 与编辑互不干扰:只替换标记所占的字符范围,段落本身仍是普通段落,光标所在段落保持源码可直接编辑;三类行内装饰(样式标记 / 公式 / 语义标记)共用一套"占位"机制,不会互相抢占范围导致渲染异常。嵌套写法(如加粗里再套链接)按深度安全展开,标记未闭合时保留源码、不误吞正文。
  • 链接可点:正文中的链接按住 Ctrl 点击可在浏览器中打开(普通点击仍是定位光标),仅放行 http/https/mailto/tel,其它协议一律不动作。

交互密度与可达性

  • 分隔条更好抓:左右面板之间的拖拽分隔条命中区从 3px 增到 10px,不必再费力对准那一根细线。
  • 工具栏不裁切:1440px 宽度下四个工具组单行完整显示,窄屏自动换行。
  • 状态栏精简:常驻信息收敛为 4 项,并在 1200 / 1000 / 780px 三档断点渐进收起次要项,不再挤成一团。
  • 键盘可达:全界面 22 个可聚焦元素在 Tab 遍历时都有清晰可见的焦点环;开启系统"减少动态效果"后,11 个动画元素全部静止。

工程护栏(防止日后回潮)

  • 样式分层构建:单一的超大样式文件拆分为 5 个按序合并的源文件,构建产物逐字节可复现;层序被改错会被自动化测试拦下。
  • 基线快照:令牌(5 主题 × 26 项)与计算样式(4 主题 × 3 视图 × 15 目标)建立基线,任何无意改动能被比对出来。
  • 对比度与排版护栏:四主题对比度审计与三视图排版审计固化为常驻检查命令,可随时一键复跑。

影响范围

  • 仅样式与前端渲染层:未改动任何类名契约、DOM 结构与业务逻辑,功能与数据流程与旧版完全一致。
  • 回归验证:124 项自动化测试全部通过(上一版为 94 项),对比度审计 0 项不达标,三视图 × 四主题计算样式一致性 12 组全部通过。

v2.1.35 · 沉浸模式公式与图表修复

这一版集中修掉沉浸模式下两类"看起来像没做"的内容:公式不渲染、图表大得离谱。两类问题的表现都在沉浸模式,根因却各不相同——公式是渲染调度方式不对,图表是尺寸策略与渲染库的并发限制。

公式不再"时有时无、多块只出一块"

  • 问题一:同一屏里写了多个公式,只显示最后一个。旧实现用一个全局序号标记渲染任务,沉浸模式是"每个内容块各自触发一次渲染",同一帧里几个块并发跑起来后,后一次会把前一次的渲染结果判定为"已过期"而丢弃——于是前几块的公式永远停在空白源码,且不会自愈,必须点进去改动一下才恢复。现在改为按每个容器分别记账,各块互不干扰。实测 5 个含公式的块全部渲染且稳定保留。
  • 问题二:写在普通段落中间的公式压根不渲染。沉浸模式的渲染只接管 5 类"块",普通段落刻意不参与(为了保证光标落点)。因此像"结论是 $E=mc^2$ 这样"的写法,公式被当成正文原样显示成 LaTeX 源码。本次沿用上一版"行内样式标记"的成熟做法:只把公式的字符范围替换成排版结果,段落仍是普通段落,行高与光标完全不受影响。段落里的 $$…$$ 也按行内方式排版,避免块级盒子把一行劈成两段。
  • 问题三:阅读栏里跨行的公式块会显示成 MBLK_0_MBLK 这样的占位符。渲染管线用占位符暂存公式,再还原成公式块;过程中一个"清理控制字符"的步骤把这个占位符连同它的边界符一起删掉了,导致公式还原失败。现已保留该占位符,跨行公式块可正常还原。

图表恢复自然尺寸,不再拉满整个版心

  • 不再被强行放大:此前图表生成后会被强制设为"占满版心宽度",一个本来只有四五个节点的中文流程图被拉伸到 3.27 倍、节点文字渲染成 52px 的巨型字号,一张图几乎占满整屏。现改为以图表自身内容的自然宽度为上限:小图按原尺寸居中显示,大图才会等比缩放到版心内。同一份流程图的显示尺寸从 922×1091 回落到 282×334,占屏比例从 73.8% 降到 14.1%,字号回到正常 16px。
  • 同一屏的多张图不再互相"删掉":渲染库会用传入的标识命名它生成的临时元素,并在渲染结束时按这个标识清理。旧实现的标识在沉浸模式下会重复,于是后一张图渲染收尾时把前面已经画好的图从页面里删掉——这正是"同一屏四张图只显示一张"的真正原因。现改用全局唯一标识。
  • 渲染过程改为排队执行:渲染库本身不是并发安全的,同帧并发时会出现"一张图永久卡在加载中""一张图量出 2412×512 的失真画布"这类问题。现在把真正的渲染排成一条队依次执行,并加了超时兜底——单张图出问题也不会把后面的图永久堵死。
  • 块底空白与错误区收敛:图表与代码块之间残留的大段空白(曾达 190px)纳入空行收缩;渲染失败的报错区在沉浸模式下限高并可内部滚动,不再是一大块无意义的长条。

影响范围

  • 仅前端渲染层:改动集中在沉浸模式的公式 / 图表渲染调度与少量样式,普通编辑态、预览栏、导出流程的行为与旧版一致。
  • 回归验证:94 项自动化测试全部通过,另以真实编辑器实例在多种文档(纯公式、混合内容、多图表)下做了逐块几何测量,页面零错误。

v2.1.34 · 沉浸模式企业级排版 + 内存占用优化

这一版做了两件事:让沉浸模式的正文排版真正像一份"文档"而不是"代码编辑器",以及削减几处长期挂着的内存占用。

正文居中版心

  • 问题:旧版沉浸正文按视口全宽左对齐铺满(左右留白仅 4~6px)。在 1920 宽的屏幕上,一行文字横跨近两千像素,读起来要不停左右摆头。
  • 本次解法:正文收进约 957px 的版心并水平居中显示,两侧留白随窗口等分。版心取 920px × 1.04——预览栏的阅读测度是 920px,沉浸正文字号是预览的 1.04 倍,等比放大后两种视图每行字符数一致、换行位置对齐,"所见即所得"才真正成立。
  • 窄屏自动适配:窗口较窄时版心自动退化为贴边留白,不会出现文字被两侧留白挤成窄条的情况。

排版细节对齐文档结构

  • 隐藏行号栏:沉浸模式不再显示左侧行号与折叠箭头,去掉"代码编辑器"的观感;返回普通编辑态时行号栏照常出现。
  • 块间空行收缩:此前每个空行都占满整行高度,导致标题与正文、段落之间的间距是预览栏的两倍,纵向节奏松散。现在空行收缩到约 16px(与预览的段落间距一致),文档结构一眼可辨。
  • 顶部留白对齐预览:正文顶部留白调整为与预览栏一致。

内存占用优化

  • 纸张纹理改无缝平铺:护眼主题的纸张背景此前是按视口尺寸逐像素生成一张最大 2400×2400 的位图——生成时峰值内存约 23MB,编码出的字符串数百 KB 到数 MB 且永久缓存,显卡再解码一张同样大小的纹理;窗口一缩放还会整张重生成。现改为生成一张 512×512 的无缝环绕纹理并平铺,用多层周期噪声复现原有的粗 / 中 / 细层次,视觉观感一致而三处内存同时下降两个数量级;尺寸与视口解耦,缩放窗口不再重新生成。实测同一视口下纹理数据从 1.85MB 降到 263KB,解码位图从 7.3MB 降到 1.0MB,生成耗时从约 1.6 秒降到 0.3 秒。
  • 录屏窗口关闭后释放资源:录屏结束后隐藏窗口会一直持有整屏背景帧的解码位图、一个从未回收的资源句柄,以及两块画布缓存——隐藏窗口里垃圾回收触发很晚,这些内存长期不释放。现于关闭时显式清理,且不影响"下次触发瞬间可用"的既有体验。
  • 后端分配器升级:Rust 侧改用更抗碎片的内存分配器,改善长时间运行、频繁读写大知识库后的内存增长。

影响范围

  • 排版改动全部为样式层:只作用于沉浸模式的 CSS 作用域,普通编辑态逐字节不受影响;沉浸模式的行高、字号、光标落点、表格与代码块滚动均无回归。
  • 回归验证:87 项自动化测试全部通过;另以真实编辑器实例在多种窗口宽度与主题下做了几何测量,正文居中误差为 0px。

v2.1.33 · 行内样式在裸段落中生效 + 图表居中放大修复

v2.1.32 让沉浸模式的块级排版对齐了预览栏,但仍有一类内容遗漏:写在普通段落里的颜色 / 背景色 / 字号标记不显示效果,而是把 {color:#dc2626|文字} 这样的源码原样露出来。同时修复了状态图等图表不居中、放大后依然模糊的问题。

行内样式在裸段落中恢复显示

  • 问题所在:沉浸模式的渲染只接管 5 类"块"(代码块、引用块、表格、列表、标题与图片行)。出于"不影响光标落点"的考虑,普通段落刻意不参与渲染——因此直接写在段落里的样式标记永远显示源码。
  • 本次解法:改为只把标记字符本身替换成渲染结果,段落依旧是普通段落,行高与光标落点完全不受影响。既补上了效果,又不动已然稳定的块级渲染。
  • 嵌套也正确:{size:18|{color:#16a34a|文字}} 这类多层嵌套按花括号配对逐层渲染,不会因为只认最内层而把外层标记泄漏成源码。
  • 编辑体验不变:光标所在的段落仍整体显示源码,方便直接修改;光标无法停在标记语法内部(标记范围是原子的),不会被半截花括号卡住。

图表居中与放大清晰度

  • 不再偏在右上角:此前图表画布的 viewBox 只会向外扩张、从不回收,只要有一个元素坐标偏出集群,整个画布就被永久撑大,图表被挤到角落只剩一小块。现在改为以内容实际包围盒为准,双向夹紧,图表默认占满画布。
  • 放大后真正变清晰:点击放大时按"紧扣内容"的 viewBox 生成图片固有尺寸,不再得到一个巨大的近正方形空白画布;放大是对矢量重新光栅化而非拉伸位图,因此边缘清晰。
  • 异常数据有兜底:甘特图等内容会报告超大(数万像素)的包围盒,此时自动回退到图表自身声明的 viewBox,避免过度裁剪。
  • 字体就绪后再测量:渲染前等待字体加载完成,避免用回退字体的包围盒做测量导致偏移。

影响范围

  • 普通编辑态零影响:本次改动只作用于沉浸模式的渲染扩展与图表渲染后处理;退出沉浸后编辑器行为与上一版逐字节一致。
  • 回归验证:73 项自动化测试全部通过,含"普通段落不得纳入块级替换"的既有约束;另以真实编辑器实例做了端到端验证——标记全部渲染、无花括号泄漏、颜色 / 背景 / 字号逐层命中,107 个光标停留点无一卡在标记语法内。

v2.1.32 · 沉浸模式排版对齐预览栏

v2.1.31 解决了沉浸模式"内容不显示"的问题,但显示出来的排版与预览栏并不一致:图片按原始像素撑满页面、表格被压成细条、代码块没有底色、链接变成浏览器默认蓝。本次让沉浸模式直接复用预览栏的整套排版规则,两边效果彻底统一。

图片不再过大

  • 图片恢复限宽限高:此前的图片约束规则只对预览栏生效,沉浸模式下图片会按原图尺寸硬渲染——一张高分屏截图就能撑爆整个页面、横向溢出。现在沉浸模式下图片自动限制在容器宽度以内、最高 600px,并恢复圆角与居中摆放。
  • 视频同样受限:嵌入的视频也一并恢复宽度与高度约束,不会再撑破版面。

排版恢复整洁

  • 表格:恢复单元格边框与 8px×10px 内边距,表格重新撑满可用宽度,不再塌成一根细条。
  • 代码块:恢复深色底、内边距与圆角,长代码行恢复横向滚动,不再与正文糊成一片。
  • 引用块:恢复左侧竖线与 18px 缩进,引用内容重新有清晰的视觉标识。
  • 行高与间距:段落、列表行高恢复为文档正文字号比例,标题上边距恢复,章节层次重新拉开。

配色跟随主题

  • 链接恢复主题色:此前沉浸模式下链接退回浏览器默认蓝,与整体配色脱节。现在链接使用与预览栏一致的主题强调色。
  • 主题适配全面生效:护眼、辉光、图片等主题此前在沉浸模式下整体不响应,现在与预览栏一样跟随主题切换。

实现方式与影响范围

  • 不再维护两份样式:改为让沉浸模式直接复用预览栏那套已被验证的排版规则,从根本上消除"两边逐步分叉"的问题——以后新增任何排版样式,沉浸模式会自动同步,不会再掉队。
  • 正文宽度与留白不变:沉浸模式的页面宽度、上下留白仍由编辑器自身控制,观感与之前一致,只是内容排版变整齐了。
  • 其它功能零影响:普通编辑态、语法着色、颜色 / 背景色 / 高亮、加粗斜体删除线下划线等均已逐一回归验证,行为与上一版完全一致。

v2.1.31 · 沉浸模式显示补全

v2.1.30 上线沉浸模式后,收到反馈:公式、表格、提示块、图片以及字体颜色、背景色在沉浸模式下没有正常显示。本次完整补齐了这些内容,沉浸模式的呈现效果现在与预览栏完全一致。

内容渲染补全

  • 更多块类型参与渲染:此前沉浸模式只把「标题 / 分隔线 / 代码块」三类内容按排版效果显示,其余内容仍然显示 Markdown 源码。现在数学公式块、表格、引用与提示块、列表、独立图片行都会按最终效果呈现。
  • 公式与图表真正渲染:公式、图表、代码高亮需要挂到页面上之后才能完成绘制,此前缺少这一步,所以只看到占位。现在沉浸模式复用与预览栏完全相同的渲染流程(图表 → 公式 → JSON 树形视图 → 代码高亮),两条路径不会再出现效果分叉。
  • 普通段落依旧不动:段落保持源码可编辑,避免行高变化影响光标落点。

字体颜色 / 背景色 / 高亮修复

  • 颜色与背景恢复显示:沉浸模式为了提升流畅度会关闭编辑器的语法着色,但这条规则写得过于宽泛,把正文里你自己设置的颜色、背景色、高亮底也一并清掉了。现在该规则只作用于源码着色,文档自身的颜色与背景样式完整保留。
  • 字号与加粗斜体本就正常:字号、加粗、斜体、删除线、下划线不受影响,可放心使用。
  • 全类型复核:已逐一核对标题字号、加粗、斜体、删除线、高亮、下划线、行内码、颜色、背景、字号、链接、任务复选框、提示块、表格、代码块底色、图片、图表共 17 项,沉浸模式与普通模式下的显示完全一致。

其它

  • 沉浸模式的开关方式、光标位置、撤销历史、滚动位置等行为均未改变,退出后与之前完全一致。

v2.1.30 · 沉浸模式重构为所见即所得

此前的「沉浸模式」本质上是「精简外壳」:隐藏侧边栏、关闭预览,正文仍然是 Markdown 源码。本次按所见即所得的思路重构,让沉浸模式下直接看到排版后的效果。

沉浸模式:正文按最终效果呈现

  • 块级所见即所得:进入沉浸模式后,标题、分隔线、代码块会按最终排版效果直接显示(标题就是标题的字号与粗细,代码块就是带底色的代码卡片),不用再在脑海里把 #、``` 换算成样子。
  • 光标所在段落保留源码:光标落在哪一块,哪一块就自动回显 Markdown 源码,可以直接编辑,改完移开光标即恢复渲染效果——既能所见即所得,又不影响精确编辑。
  • 其它部分一切照旧:普通段落不做任何转换,工具栏、快捷键、AI 改写、保存、大纲等全部功能保持不变。

不影响其它功能的实现方式

  • 热插拔设计:所见即所得是一个默认关闭、可随时开关的编辑器扩展,仅在你主动进入沉浸模式时启用。关闭状态下编辑器行为与旧版完全一致,撤销历史、光标位置、滚动位置全程不丢失。
  • 绝不重建编辑器:开关过程只切换渲染层,不做任何编辑器重建,因此不会出现「切个模式就丢历史 / 光标跳回开头」这类问题。
  • 按需渲染:只渲染当前视口附近的区块,长文档打开沉浸模式也不会卡顿。

沉浸模式使用提示

  • 进入 / 退出:点击工具栏「⚡ 沉浸」按钮,或按 Ctrl/Cmd + Shift + F(快捷键 Alt + O 亦可切换);Esc 退出。
  • 建议在沉浸模式下配合「隐藏预览」使用,正文区域更宽,专注写作体验更好。

v2.1.29 · Mermaid 图表渲染彻底修复

上一版(v2.1.28)修复了图表放大预览的两处缺陷,但部分用户反馈问题依旧。经真实浏览器逐项排查,本次找到并根治了底层原因。

流程图 / 图表底部被裁切

  • 根因:应用内的 Mermaid 图表库是运行时从公共 CDN 的「滚动版本」地址(mermaid@10)加载的——这个地址永远不会变化,浏览器磁盘缓存里存住的是什么版本就会一直用什么版本。早期 10.x 版本存在「图表底部被裁掉」的已知缺陷,命中旧缓存的机器上无论怎么升级应用都不会好转。
  • 修复:改为锁定精确版本 Mermaid 11.12.2 并附带缓存破坏参数,所有用户从此加载到确定的最新代码;同时新增渲染后兜底——按图表内容的真实边界自动外扩可视区域,即使某个版本的库计算出的边界偏小,底部节点也不会再被裁掉。

架构图无法加载

  • 根因:三重叠加——工具栏「架构图」生成的是 architecture-beta 类型,但该类型 Mermaid 10 根本不支持(11 才内置),所以必然报「渲染失败」;旧模板的连线语法本身也不合法;且该图类型的解析器完全不接受中文标签(连 [中文名] 都会报错)。
  • 修复:升级到 Mermaid 11 后该类型可用,模板已替换为经真实浏览器逐行验证的合法语法。注意:架构图(architecture-beta)暂不支持中文标签,模板使用英文服务名并附中文注释说明,这是 Mermaid 解析器的硬限制。

放大预览背景发黑、超出窗口无法查看

  • 白底卡片:Mermaid 输出的图表背景是透明的,此前放大后透出的是预览窗口的纯黑底色,浅色图表浮在黑底上难以辨认。现在导出预览图时自动铺一层白色背景,任何主题下都是清晰的白底卡片。
  • 拖拽平移:放大超过窗口大小后,此前看不到的部分没有任何办法查看。现在按住鼠标即可拖拽平移(配合矢量缩放,放大到多大都保持线条锐利)。

v2.1.28 · AI 写入约束、知识库问答检索与图表预览修复

本次补齐了「规则写了却没人执行」和「点了没反应」两类长期存在的链路断点,并修复了图表放大后看不全、看不清的问题。

AI 规则真正生效

  • 规则文件首次接入 AI 写入链路:此前界面承诺「.mytemple/AGENTS.md 规则可约束 AI 的读写范围」,规则文件的读写已经通了,但校验逻辑从未被任何写入路径调用——也就是说在编辑器里让 AI 改写文档时,规则形同虚设。现在 AI 自动写入会真正经过规则校验:命中禁止路径、或规则设为只读模式时会被拦截并给出提示,不会再默默写入。
  • 零打扰的保守策略:没有创建规则文件的用户完全无感知(一律放行);只有 AI 自动写入才校验,你手动编辑、导入文件、勾选任务等操作一律不受影响;规则中「允许路径」只做记录不阻断,避免出现「AI 改写一个 txt 突然失败」这类突兀行为。
  • 写入操作留下审计记录:AI 的写入动作会记录到操作审计文件,出问题时可回溯「谁在什么时候改了哪个文件」。

知识库问答:为什么检索结果总是 0 段

  • 修复「重建索引落盘的其实是空索引」:这是一个从 v2.1.1 起就存在的缺陷——重建时用于写盘的分块数据在写盘前已先行清空,导致落盘的索引文件里一条内容都没有,而界面提示的「已重建 N 个分块」用的是清空前的数字,所以看起来一直是成功的。现在重建会真正落盘完整索引数据。
  • 问答面板首次使用自动建索引:此前检索索引只能到设置里手动点「重建索引」才会生成,问答面板既不检查也不提示,没建过索引就提问必然是 0 结果。现在首次打开问答面板时若发现索引为空,会自动在本地构建一次并提示「检索索引已就绪:N 段」。
  • 中文整句提问可正常召回:中文分词此前把一整句连续汉字当成一个词去精确匹配,「剑魔伤害高」这类提问几乎不可能命中文档段落。现在会对中文查询词做二字滑动切分扩展,「剑魔」等关键片段即可命中对应段落,召回率显著提升(排序权重未改动)。

图表

  • 修复「点击图表放大后显示不完整」:编辑器内的图表会被移除固定宽高以便自适应显示,放大预览时直接把这个「没有尺寸」的图交给预览窗口,会被按浏览器默认的极小尺寸渲染,图表被裁掉大半。现在放大前会从图表自身信息中还原真实尺寸,完整显示整张图。
  • 修复「放大后模糊」:此前放大是把已渲染好的画面直接拉伸,只是把像素放大、越放越糊。现在矢量图表放大时会按目标尺寸重新绘制,放到多大都保持线条锐利(缩小不影响清晰度)。

v2.1.27 · 录屏画面修复与知识管理功能恢复

本次集中修复了一批「界面看着正常、实际没有生效」的功能缺陷,其中大部分是后端重写过程中遗漏或接错线的部分。

录屏

  • 修复「录出来的视频完全静止不动」:录制时的画面合成画布此前被放在屏幕之外并设为完全透明,系统判定它不可见后就不再刷新它的画面,导致最终视频只有第一帧、后面全是静止图。已改到视口内并用极小透明度保留刷新,画面恢复动态。
  • 大幅提升录屏流畅度:此前每一帧都要把整个屏幕的画面无损压缩后再完整传给录制界面,单帧数据量高达数 MB、耗时数百毫秒,实际帧率只有 1~3 帧/秒(表现为幻灯片式卡顿)。现在改为只采集选区内的画面 + 改用体积小得多的有损压缩,单帧数据量降到一两百 KB、耗时降到几十毫秒,帧率可达录制上限。
  • 修复「软件一启动就弹出录屏选区遮罩」:为保证按 Alt+M 能秒开,应用启动时会在后台预先创建一个隐藏的录屏窗口。但该页面一加载就会去请求背景画面,取不到时也照样通知后端「已就绪」,后端收到通知便无条件显示窗口,于是启动瞬间弹出全屏半透明遮罩。现在后端增加了前置判断(没有正在进行的录屏任务就不显示),前端也改为拿不到背景画面时静默待命。
  • 修复「录屏选区界面没有背景画面」:选区界面此前取背景走的是截图通道,导致始终取不到、只有一层纯色遮罩。现已接入录屏专用通道,选区时第一次能真正看到冻结的桌面画面。

知识管理

  • 修复「点击『分析知识脉络』没有任何数据」:该功能的后端实现此前在旧版服务端清理时被一并删除,之后一直没补回来;由于请求本身是成功的,界面不报错,只是所有统计恒为 0、评分恒为 0 分、三个待处理列表永远空着,看起来像「点了没反应」。现已补齐完整实现:链接密度(40 分)、标签覆盖(30 分)、知识活跃(20 分)、概念关联(10 分)四个维度的扫描与百分制评分。
  • 配套打通「文档浏览记录」——此前从未被记录,「待温习」维度因此没有数据源;同时修好了面板里的「温习周期」设置项(此前从界面到后端整条链路是断的,改了不生效)。说明:修复后第一次分析时,「待温习」会列出全部文档并显示「从未浏览」,这是符合设计的初始状态,随日常阅读会自然收敛。
  • 修复「标准化当前文档」不可用:此前弹窗打开后修改前后对照是空白的,「确认应用」按钮永远处于禁用状态点不动;而且应用时不做原文备份,界面却提示「原文已备份」。现在正常显示对照内容、按钮可用,应用前会先把原文备份到 backups/日期/ 目录并写入操作审计,内容没有变化时不会重复写盘。
  • 修复「AI 规则文件不被识别」:界面提示会在 .mytemple 目录创建 AGENTS.md 规则文件,但旧实现实际读写的是另一个 JSON 文件,导致按提示手工创建的 AGENTS.md 永远不会被读取,界面恒显示「尚未创建规则文件」。现已统一读写 AGENTS.md,规则状态与文件内容保持一致;规则校验也第一次接入了实际操作预览。
  • 修复「智能适配标签」无法使用:该功能的请求格式前后端对不上,一执行就失败(提示语义分析失败)。现已补齐全库分析能力:全库词频统计 + 逆文档频率加权 + 标题加权 + 停用词过滤 + 保留已有标签并清除占位标签「待分类」,支持先预览变更内容、确认后再应用。

v2.1.26 · 托盘图标与关窗唤回

  • 修复「关掉主窗口后再点桌面快捷方式没反应」:应用为保证截图/录屏能做到「无感触发」,会一直预创建相关窗口,进程因此不会随主窗口关闭而退出;但旧逻辑在唤回时只去找已存在的主窗口,找不到就静默放弃,于是表现为「点了快捷方式毫无反应」。现在主窗口不存在时会自动重建并显示,点快捷方式即可把应用重新打开。
  • 新增托盘图标:在任务栏通知区域常驻一个托盘图标,单击图标即可唤回主界面(窗口已关闭则重新打开、还在则聚焦到前台)。同时提供右键菜单:显示主界面、区域截图(Alt+A)、区域录屏(Alt+M)、退出 MyTemple Knowledge。
  • 关闭窗口不再退出应用:点右上角「×」只是隐藏主窗口,应用继续在后台待命,快捷键截图/录屏照常可用,需要彻底退出时用托盘菜单的「退出」。
  • 稳定性:托盘创建失败时不影响应用正常启动,只丢弃托盘能力(此时关闭窗口即退出);单实例唤回、托盘唤回统一走同一套「存在则聚焦、不存在则重建」逻辑,行为一致。

v2.1.25 · 单实例保护

  • 修复「点击桌面快捷方式开出多个窗口」:应用此前没有单实例保护,冷启动耗时较长时连点快捷方式会拉起多个完整实例(多个窗口同时抢同一份数据目录,存在配置竞写风险)。现在第二个实例启动时会立即退出,并自动把已有窗口还原聚焦到前台——重复点击快捷方式的效果变成「把应用调回来」,和主流桌面软件行为一致。

v2.1.24 · 截图/录屏「闪屏」修复

  • 修复「按 Alt+A 截图时屏幕闪一下」:截图窗口此前在抓到画面后立即显示,但冻结画面还要经过前端轮询(约 100 毫秒)→ 下载 → 解码才会画上去,中间这段时间窗口已经置顶,用户看到的是实时桌面(外加一个白色「加载中…」提示),冻结帧一盖上来画面就「跳回」按下瞬间。现在截图窗口改为唯一的显示时机由前端就绪信号驱动:冻结帧解码完成后再显示,出现即定格,不再有时序空窗。
  • 修复「关闭截图/录屏时再闪一次」:旧关闭流程用「取消置顶 → 最小化 → 隐藏 → 移出屏幕」四连,其中最小化会播 Windows 系统动画、移出屏幕会再触发一次画面重新合成。现在关闭只做隐藏,动画与重合成全部消除。
  • 修复「长按 Alt+A 截图窗口一闪即退」:快捷键长按会自动重复,旧逻辑把重复触发当成「再次按下即关闭」,导致窗口刚出现就消失。现在窗口显示期间忽略重复触发,取消统一按 ESC(原有的心跳监控与超时保护仍会兜底防止卡死)。
  • 修复「录屏开始瞬间白屏闪一下」:录屏窗口复用时会重新加载页面,旧流程在页面重载过程中就把窗口显示出来,重载期间页面是白底。现在同样改为就绪后再显示,并为录屏补齐了就绪信号接口。
  • 体验优化:窗口尺寸/位置只在真正变化时才重设(减少画面重新合成);触发时由后端主动唤醒截图页面,响应更快;截图窗口从「屏幕外预创建、显示时移回来」改为直接在最终位置预创建,显示零位移。

v2.1.23 · 授权校验健壮性修复

  • 修复「冷启动授权校验超时被误判为未授权」:部分机器上启动后会弹出全屏「软件未授权」授权窗(已授权用户也被挡)。原因是授权校验依赖硬件指纹,而该指纹的 WMI 查询会阻塞请求(单次数秒,最坏可达数十秒),超过前端 3 秒超时;前端又把这个「还没算完」直接当成「没授权」处理。
  • 后端:硬件相关缓存改为「只计算一次」语义,避免启动预热与首个校验请求重复拉起 WMI 查询;同时收紧查询超时,缩短最坏阻塞时间。
  • 前端:首次(冷启动)校验超时由 3 秒放宽到 12 秒;拿不到确定结论时不再判定为未授权,而是标记为「结论未知」并自动重试数次后才下判断;周期检查、403 复查、缓存后台复查三处入口同样排除该状态。
  • 兼容:新增内存级授权缓存兜底,当系统策略阻断浏览器存储(控制台出现 Tracking Prevention blocked access to storage)时,授权状态仍可正确缓存,不再每次都重新走一遍慢查询。

v2.1.22 · 稳定性修复版(启动失败 / 导出崩溃 / 高亮语言)

  • 修复「升级后启动失败」:旧版本前端曾同时存在 import escapeHtml 与顶层 function escapeHtml 声明(模块作用域重复声明属致命语法错误),且静态资源长期复用它旧 URL 参数、服务端也不返回缓存头,WebView2 会继续加载磁盘缓存的旧文件。本版为静态资源统一加 Cache-Control: no-cache,并递增资源版本参数,从此不再出现新旧文件混用。
  • 修复「导出截图资源」点击即报错:函数内声明的是 imgUrlSet,过滤时误用未声明的 urlSet,每次导出都会抛 ReferenceError 导致功能不可用。
  • 修复代码块高亮缺语言:白名单声称支持的语言里有 7 种没有实际语言包,控制台会报 Could not find the language 'bat' 并退化为无高亮。已补齐 bat/cmd、tex、scala、fortran、protobuf、handlebars 语言包,git 差异块改用 diff 语法渲染。
  • 修复 Agent 规则状态读取失败(404):前端误把「工作区/文档」复合引用当作工作区 id 传给后端;现已前后端统一按工作区段解析,并修正状态文案判断依据。
  • 工程质量:清理仓库中历史遗留的旧 Node 后端与临时文件、历史大文件瘦身(.git 903MB → 52MB),CI 新增 Windows 端 Rust 编译与测试检查,前端测试增至 15 例(含高亮语言覆盖与本次崩溃的回归防护)。

v2.1.21 · 导出截图资源 + 推广页整理

  • 新功能「🖼️ 导出截图资源」:打开含截图的文档 → 菜单点击「导出截图资源」,前端解析 Markdown 中所有 ![](url) 和 <img src=url> 引用,过滤外部链接,只保留本地资源,逐个转 base64 后调用后端 /api/export/save-images,弹出文件夹选择对话框批量写入图片文件,Toast 提示成功数量和路径。
  • 后端:handlers.rs 新增 /api/export/save-images 路由与 save_images_http(文件夹对话框 + base64 批量写盘)。
  • 推广页:清理 52 张旧 webp 背景图与临时 webp.html 页面,整理版本展示。

v2.1.16 · 打包流程稳定化

  • 一键打包脚本 build-release.ps1:npx tauri build → NSIS → dist/ + promo/downloads/ 全链路自动化,自动同步 6 处版本号,图标以 packaging/logo.* 为唯一主源。
  • 启动自动检查更新:启动时读取 version.json 检查新版本,支持自动下载安装。
  • 修复:JSON toggle、长 URL 参数处理。

v2.1.13 · JSON 格式化全面修复

  • MD 中 JSON 代码块自动渲染树形视图:renderMarkdown 新增 JSON 代码块分支,生成带 data-json-raw 属性的容器;processJsonCodeBlocks 统一后处理函数在阅读模式、编辑模式预览、chunked 分片渲染三个路径都调用,遍历 .json-code-block 调用 renderJsonTree 替换为可折叠树形视图。
  • 编辑/阅读模式切换格式化不再失效:renderCurrentPreviewNow(同步渲染)新增 JSON 分支:canPreviewAsJson() 时直接调 renderJsonTree 渲染树形,不再走 cachedRenderMarkdown 把 JSON 当 Markdown 渲染。
  • renderJsonTree 三级宽松解析:严格 JSON.parse → repairJson(去注释/补引号/去尾逗号)→ extractFirstJsonObject(从混合文本提取 JSON 并自动补全缺失括号)。
  • looksLikeJson 正则修复:s* 修正为 \s*,修复 txt/log 文件 JSON 内容检测。
  • chunked 渲染路径 JSON 后处理:renderReaderContentChunked 单片和多片路径都增加 processJsonCodeBlocks 调用。

v2.1.12 · JSON 树形三处渲染路径统一 + setMode 跳过非 Markdown 渲染

  • openDoc 同时渲染到 preview + markdownView:JSON 树形原本只渲染到 els.preview(编辑模式可见),阅读模式切换后看不到内容。修复后同步渲染到 els.markdownView,保证两个模式都能看到。
  • JSON 降级路径和其他代码文件也同步到 markdownView:renderCodePreview 降级路径和其他非 Markdown 文件都额外渲染到 els.markdownView。
  • setMode('view') 跳过非 Markdown 的 renderReaderContent:非 Markdown 文件 + markdownView 已有内容时只恢复滚动位置,不再走 renderReaderContent 把 JSON 当 Markdown 解析输出纯 <pre><code>。
  • MD 中 JSON 代码块新增特殊标记:renderMarkdown 的 else if (normalizedLang === "json") 分支生成 <div class="code-block json-code-block" data-json-raw="..."> 容器。

v2.1.11 · 小文档 BOM 检测修复

  • BOM 检测顺序修复(app.rs decode_bytes_smart):原代码 UTF-8 纯解码(std::str::from_utf8)排在 BOM 检测之前,UTF-8 BOM(EF BB BF)是合法 UTF-8 字节序列所以解码成功,但 U+FEFF 字符被当作内容开头保留,导致 looksLikeJson 检测失败和 JSON.parse 失败。修复:BOM 5 种检测(UTF-8/16LE/16BE/32LE/32BE)全部移到 UTF-8 纯解码之前,先剥离 BOM 字节再解码 body。
  • 影响范围:中文 Windows 记事本、WPS 等编辑器保存小文件时默认写入 UTF-8 BOM,修复后 encoding: utf-8-bom,首字节 123 = {(BOM 已剥离)。

v2.1.10 · JSON 预览实时更新修复

  • setPreviewVisible 不再强制禁用 JSON 文件:原代码 !state.currentIsMarkdown 就强制隐藏预览面板,修复为 !state.currentIsMarkdown && !canPreviewAsJson()。
  • 预览按钮不再禁用 JSON 文件:previewToggleBtn.disabled 条件增加 !canPreviewAsJson()。
  • renderCurrentPreviewAsync 增加 JSON 分支:编辑器输入时实时更新树形视图,不再只走 cachedRenderMarkdown。
  • 新增 canPreviewAsJson 辅助函数:检测 .json/.jsonc/.json5 扩展名,以及 .txt/.log 文件内容疑似 JSON(looksLikeJson)。

v2.1.9 · JSON 宽松解析 + 录屏 captureStream 修复

  • parseJsonLenient 三级解析策略:严格 JSON.parse → repairJson(未加引号 key、单引号字符串、尾随逗号、JS 注释)→ extractFirstJsonObject(从混合文本如 HTTP 日志中自动提取 JSON 对象,自动补全缺失括号)。
  • .txt/.log 文件自动检测 JSON 内容:通过 looksLikeJson 判断内容是否包含 JSON 结构,是则尝试树形渲染。
  • 宽松解析提示条:内容经过修复/提取时显示橙色提示。
  • 录屏 captureStream 修复(recorder.html):outCanvas 加入 DOM(position:absolute; left:-99999px),确保 WebView2 中 captureStream 稳定产生帧,解决录制黑屏/无画面问题。
  • 录屏提示条 3 秒后自动淡出:避免被 xcap 捕获进录屏画面,用户仍可通过 Alt+M 停止录制。

v2.1.8 · JSON 格式化预览新增 + 小文件编辑器同步修复

  • JSON 树形视图新增(app.js + styles.css):renderJsonTree + renderJsonNode 实现 bejson 风格可折叠树形视图,类型颜色标记(紫色 key、绿色 string、蓝色 number、红色 boolean、灰色 null)。亮/暗主题自动适配。
  • 小文件编辑器内容同步修复:打开大文件后立即打开小文件时编辑器有时显示大文件内容。修复:requestAnimationFrame 中调 els.editor.view.dispatch 强制刷新 CodeMirror 内容。
  • JSON 解析失败降级:renderJsonTree 返回 null 时自动降级到 renderCodePreview 普通代码高亮。
  • 代码预览重构:提取 renderCodePreview 可复用函数。

v2.1.7 · 版本自升级修复

  • 后端 check_update 使用本地 version.json(handlers.rs + ipc.rs):原代码使用编译时 CARGO_PKG_VERSION,与关于页显示版本不一致。修复:新增 read_local_version_json 和 read_local_version_string 辅助函数,check_update 读取本地 version.json 的版本号。
  • 前端更新对话框(app.js + index.html + styles.css):checkUpdateBtn 重写,捕获 check_update 响应:upToDate=false 弹出更新对话框("立即下载"通过 /api/open-url 打开浏览器下载 + "稍后提醒"按钮);upToDate=true 提示"已是最新版本"。

v2.1.6 · 录屏鼠标可操作性修复

  • 录屏窗口 click-through(global_capture.rs + recorder.html):新增 IPC 命令 recorder_set_ignore_cursor,录制时让录屏窗口鼠标穿透(click-through),用户可正常操作底层软件。停止录制弹出保存对话框时恢复交互。
  • 停止录制改为 Alt+M 热键:click-through 后停止按钮不可点击,改用 Alt+M 全局热键停止录制。
  • Browse 文件夹按钮修复:PowerShell FolderBrowserDialog 替换为 Tauri dialog 插件的 pick_folder,通过新 IPC 命令 recorder_browse_folder 调用。
  • 默认保存路径:确认工作区根目录的 Videos 目录(如 C:\Users\fshby\dos\Videos)。

v2.1.4 · 版本自升级缺陷修复

  • 后端 check_update 读取 version.json(handlers.rs):原 check_update 使用编译时 CARGO_PKG_VERSION 作为当前版本号,与关于页显示的版本号不一致(关于页读 version.json)。修复:改为读取本地 version.json 的版本号,与关于页保持一致。
  • 新增 read_local_version_json / read_local_version_string(ipc.rs):辅助函数读取并解析 version.json。
  • 前端捕获 check_update 响应(app.js):checkUpdateBtn 重写:upToDate=false 弹出更新对话框,提供"立即下载"(通过 /api/open-url 打开浏览器下载)和"稍后提醒"按钮;upToDate=true 提示"已是最新版本"。
  • 更新对话框 UI(index.html + styles.css):新增 .update-dialog 模态框和样式。

v2.1.3 · 录屏功能稳定性加固

  • 缺陷1修复(录制源未默认桌面):startRecording() 调用 api_start_native_record 前先调用 api_stop_native_record 确保上次录屏状态完全释放,防止 RecordState 残留导致 start_native_record 返回"录屏已在进行中" → 前端降级到 getDisplayMedia 弹出桌面选择器。
  • 缺陷2修复(多次录制失败):
    • 后端 start_native_record 新增 3 次重试 + DXGI 恢复延迟(每次等待 300/600ms):DXGI Desktop Duplication 在上次录屏停止后可能需要短暂恢复时间,第一次 video_recorder() 或 recorder.start() 可能失败,重试后即可成功。
    • 前端 startRecording() 调用 api_start_native_record 失败后等待 1 秒再重试一次,两次都失败才降级到 getDisplayMedia。
    • start_native_record 入口检测 RecordState 残留时强制清理 + 等待 500ms 让 DXGI 资源释放,而不是直接报错。
  • 缺陷3修复(保存与清理):stopRecording 中 FileReader 添加 10s 超时保护,超时走 closeRecorderWindow 兜底释放窗口和锁。handle_recorder_result 保存成功后已清理背景帧临时文件 + 释放锁 + 停止原生录屏。
  • 健壮性增强:
    • stop_native_record 用 catch_unwind 防止 recorder.stop() panic 卡住锁。
    • close_recorder_window 兜底调用 stop_native_record 释放 RecordState。
    • handle_recorder_result 保存失败也释放锁和状态,防止卡住。
  • 不影响其他功能:仅修改 global_capture.rs 和 recorder.html。截图、AI、知识库管理不受影响。无遮罩干扰。

v2.1.2 · 截图保存后再次截图失败修复 + 文字大小可调

  • 缺陷修复(screenshot.html confirmEdit):截图保存后再次截图失败。
  • 根因:confirmEdit 中 bgImg/tagCounter/currentTool/currentWidth 等关键变量未重置;FileReader.onload 为异步回调,若 readAsDataURL 卡住或失败,窗口和截图锁永不释放,导致下次截图被锁阻塞。
  • 修复:
    • confirmEdit 完整重置所有全局变量(bgImg/scaleX/scaleY/bgImgWidth/bgImgHeight/tagCounter/currentTool/currentColor/currentWidth/currentFontSize)。
    • toBlob 添加 5s 超时保护:Promise.race 竞争 toBlob 和 setTimeout,防止 Canvas 污染导致 toBlob 永不回调。
    • FileReader 添加 5s 超时保护 + onerror 回调:超时或出错时走 closeWindow 兜底释放锁和窗口。
    • drawImage 添加 try-catch:防止 bgImg/annoCanvas 异常时抛错导致后续清理代码不执行。
    • 健壮性检查:confirmEdit 入口检查 region/bgImg/annoCanvas/scaleX/scaleY 是否有效,无效时直接 cleanupAndClose。
    • cleanupAndClose 也完整重置所有变量(含 bgImg/scaleX/scaleY/tagCounter/currentFontSize 等)。
  • 新功能(文字大小可调):
    • 新增 FONT_SIZES = [14, 18, 24, 32] 四档字体大小。
    • 工具栏新增字体大小按钮区域,点击切换字体大小,选中高亮。
    • showTextInput 使用 currentFontSize 替代硬编码 16px。
    • 文字标注创建使用 currentFontSize 替代硬编码 18。
    • 编辑文字时切换字体大小可实时同步到输入框。
  • 不影响其他功能:仅修改 screenshot.html。录屏功能、AI 功能、知识库管理不受影响。无遮罩干扰。

v2.1.1 · 截图选区边界约束(选区框越界难以选中)

  • 缺陷修复(screenshot.html):自定义截图区域过大靠近屏幕边界时选区框出现在边界外难以选中。
  • 根因:startRegionSelection 的 onDown 直接 startX = curX = e.clientX、onMove 直接 curX = e.clientX,鼠标坐标未经任何边界约束。当用户拖拽到屏幕边缘/外时,选区框坐标超出视口范围(负值或超过 innerWidth/innerHeight),选区框部分或全部跑到屏幕外,用户难以选中框边缘进行操作。
  • 修复:
    • onDown:startX/curX 用 Math.max(0, Math.min(e.clientX, window.innerWidth)) 约束;startY/curY 同理。
    • onMove:curX/curY 用同样的 clamp 约束,确保拖拽过程中选区框始终在视口内。
    • onUp:最终 region 对象也 clamp(x 不超过 innerWidth-w,y 不超过 innerHeight-h)作为防御性保底。
    • 工具提示(tooltip)位置也 clamp 到视口内(left 不超过 innerWidth-120,top 不超过 innerHeight-30)。
  • 健壮性增强:三层边界约束(onDown + onMove + onUp),任一层失效也有下一层保底。工具提示不会跑到屏幕外不可见。
  • 不影响其他功能:仅修改 screenshot.html 的 startRegionSelection 函数内 onDown/onMove/onUp 和 draw 的 tooltip 位置逻辑。录屏功能、AI 功能、知识库管理不受影响。无遮罩干扰(截图窗口已有 always_on_top + 透明 + 全屏覆盖,选区框在 canvas 内绘制不会遮挡鼠标)。

v2.1.0 · 录屏功能稳定性加固(多次录制失败 + 桌面选择器 + 状态清理)

  • 第二次及后续录制失败修复(global_capture.rs + recorder.html):根因为 show_recorder_window 复用已有录屏窗口时仅 set_always_on_top + unminimize + show,不 reload 页面。前端 recording/recorder/chunks/region 等变量残留上次录屏状态,DOM 已被 document.body.innerHTML='' 清空,init() 不再执行 → 用户看到空白窗口无法操作;或 api_start_native_record 因前端状态错乱失败 → 降级到 getDisplayMedia 弹出桌面/窗口选择器。修复:复用窗口时 eval window.location.href='recorder.html?_t=时间戳' 重新加载页面,确保 init() 重新执行、所有 JS 变量重置。
  • 录屏默认录桌面不弹选择器修复:根因同上。RecordState 残留为 Some 导致 start_native_record 返回「录屏已在进行中」→ 前端降级到 getDisplayMedia 弹出选择器。修复后窗口 reload 确保前端状态干净,api_start_native_record 成功走 xcap DXGI 桌面捕获(无选择器)。close_recorder_window 已有的 stop_native_record 兜底 + 新增页面 reload 双重保险确保 RecordState 不残留。
  • stop_native_record 健壮性增强(global_capture.rs):原代码 state.recorder.stop() 可能阻塞或 panic,如果 panic 会卡住 Mutex 锁导致后续所有录屏操作死锁。修复:用 std::panic::catch_unwind(AssertUnwindSafe) 包裹 recorder.stop(),即使 panic 也确保 guard.take() 已移除 RecordState,锁正常释放。
  • handle_recorder_result 保存后清理 + 健壮性:保存成功后执行 stop_native_record + release_record_lock + 清理 pending_record_bg 临时文件 + emit recorder-saved 事件(含 path/filename/size)。保存失败也释放锁和状态防止卡住。新增空内容校验:bytes.is_empty() 时跳过保存返回错误。
  • close_recorder_window 页面重置:关闭窗口后 eval 导航到 about:blank,下次 show_recorder_window 复用时 reload 到 recorder.html 获得干净状态。
  • 前端状态完整重置(recorder.html):cleanupAndClose 完整重置 recording/timerInterval/recorder(MediaRecorder.stop)/chunks/overlay/canvas/ctx/outCanvas/outCtx/frameImg/bgImg/region/elapsed 全部变量。stopRecording 保存 recorder/chunks 到临时变量 savedRecorder/savedChunks,保存完成后 recorder=null/chunks=[] 清理引用;FileReader.onerror 也走 cleanupAndClose 防止卡住。等待最后一帧从 200ms 增加到 300ms 确保数据完整性。
  • 不影响其他功能:仅修改 show_recorder_window/close_recorder_window/stop_native_record/handle_recorder_result 后端函数和 recorder.html 前端 cleanupAndClose/stopRecording 函数。截图功能、AI 功能、知识库管理不受影响。无遮罩干扰(已有 always_on_top(false) + minimize + hide + 移出屏幕 多重保险)。

v2.0.9 · 知识库智能管理故障排查与稳定性增强

  • ai_reindex 内存浪费修复(handlers.rs):原代码在更新 state.chunks 时执行 *chunks_ref = all_chunks.clone(),万级 chunk 场景下 clone 全量拷贝几十 MB 堆数据后再丢弃原 vec,造成无谓内存峰值。修复:改为 std::mem::take(&mut all_chunks) 零拷贝转移所有权。
  • ai_reindex 静默吞错修复(handlers.rs):原代码 read_file_force 失败时 Err(_) => continue,既不记日志也不计数,用户无法知道哪些文件被跳过。修复:改为 Err(e) => log::warn 记录失败文件路径和错误 + skipped += 1;同时新增内容为空检查,空文件也跳过并计数。响应新增 skipped 和 totalFiles 字段,前端 Toast 显示「X/Y 文件跳过」。
  • ai_reindex 进度反馈修复(handlers.rs):原代码 progress 字段在全量重建过程中从未更新(status() 返回的 progress 始终为 0,0),前端无法获知进度。修复:重建开始时设 (0, total_files),逐文件递增 done,每 10 文件 log::info 输出进度,完成后设 (total, total)。
  • DeepSeek/Ollama 错误响应切片 panic 修复(rag.rs):原代码 &text[..text.len().min(500)] 在错误响应包含多字节 UTF-8 字符时,500 字节位置可能落在字符中间导致 panic(与之前中文切片 bug 同类)。修复:chat_with_deepseek 和 chat_with_ollama 均改为 text.chars().take(500).collect::<String>(),按字符边界安全截断。
  • lexical_search 性能优化(rag.rs):原代码在 O(chunks × unique_tokens) 双重循环中,每个 token 对每个 chunk 反复调用 chunk.title.to_lowercase() / heading / text,导致同一 chunk 被重复 lowercase 多次。修复:预计算 title_lower / heading_lower / text_lower 一次,循环内直接 contains 查找,降低 String 分配次数从 O(chunks × tokens) 到 O(chunks)。
  • 并发安全(handlers.rs):ai_reindex 入口新增 progress 检查:若 total > 0 && done < total,直接返回 { ok: false, error: '索引重建正在进行中' },防止用户快速点击或前端重试导致并发重建。
  • 前端改进(app.js):aiReindexBtn 点击处理器增强:检测 result.ok === false 显示并发拒绝提示;正常路径 Toast 显示分块数、文档数、跳过数。
  • 不影响其他功能:仅修改 ai_reindex / lexical_search / chat_with_deepseek / chat_with_ollama 和前端 aiReindexBtn 处理器,不改变 API 路由结构、请求格式、响应基本结构(仅新增可选字段)。其他功能(截图/录屏/授权/AI 文本加工)不受影响。

v2.0.8 · AI 忠实性强约束 + 反幻觉机制

  • 选中文本加工忠实性约束(新增 AI_FAITHFULNESS_RULE):适用模式 polish/rewrite/summary/keypoints/terms/comment。五重约束:① 严格基于原文:禁止编造/臆测/补充原文中不存在的事实、数据、引用、人名、日期、结论;禁止引入训练数据中的「常识」填补原文未提及的内容;信息不足时标注「【注意】原文中缺少XXX信息,已跳过」。② 不得篡改核心语义:可调整措辞与语序,但不得改变事实判断/观点立场/因果关系/数量关系(原文「可能」不得改「必然」,「A导致B」不得改「B导致A」)。③ 不得删减关键信息:可精简冗余表述,但不得删除关键事实/数据/条件/前提/限定词。④ 反幻觉自检:输出前逐句自问「这句话的信息是否直接来自原文?」若否则删除或替换为忠实转述。⑤ 用户自定义要求即硬边界。
  • 翻译模式忠实性强化:新增 4 条忠实性约束(译文不得擅自增加原文没有的信息;不得删减原文关键信息——每段每句每个术语必须有对应译文;不得篡改原文条件/因果/程度/时态等限定关系;逐句对照自检——原文几句译文几句)。自检提示从「有没有非目标语言字」扩展为「① 有没有非目标语言字 ② 有没有增删原文信息」。
  • 用户自定义要求硬边界化:所有模式的用户 instruction 从「用户额外要求:...」升级为「【用户自定义要求 — 硬边界,必须严格执行,不得偏离】」。inline-chat 新增「用户指令即硬边界」system prompt:用户设定的风格/字数/格式/视角/禁用词必须严格执行,不得以「更好」为由偏离;用户请求与文档上下文矛盾时以用户请求为准。
  • RAG 知识库反幻觉强化:新增 4 条反幻觉强约束:只能基于检索到的文档片段回答,不得引入训练数据外部信息;无相关信息时必须如实说明「检索到的文档中未包含相关内容」,不得编造;不得将碎片信息拼接臆测为完整结论;回答引用来源编号 [n] 可溯源验证。
  • 不影响其他功能:仅修改 AI system/user prompt 构造逻辑,不改变 API 路由/请求格式/响应结构/前端 UI。

v2.0.7 · 启动授权弹窗修复(WMI 缓存预热 + 超时放宽)

  • 启动未授权弹窗几秒后自动消失(缺陷修复):软件每次启动后弹出「未授权」窗口,等待几秒后自动消失。根因:首次调用 /api/license/check 时,后端 verify_license 需通过 PowerShell 查询 WMI 获取硬件标识(Win32_Processor.ProcessorId、Win32_DiskDrive.SerialNumber、Win32_BaseBoard.SerialNumber、Win32_ComputerSystemProduct.UUID)和操作系统安装时间(Win32_OperatingSystem.InstallDate),单次查询耗时 2~5 秒。这些值虽有进程内缓存,但进程启动时缓存为空。前端 LICENSE_NET_TIMEOUT_MS=1500ms 超时导致 Promise.race 先返回 timeout,误判为未授权并弹出窗口;随后后台请求完成、缓存就绪,下一次 1.5s 轮询命中缓存才清除弹窗。
  • 后端预热缓存:license.rs 新增 pub fn prewarm_caches(),调用 get_machine_code()(触发 WMI 查询,写入 HARDWARE_CACHE + MACHINE_CODE_CACHE)和 get_system_reference_time()(触发 OS 安装时间查询,写入 SYSTEM_REF_TIME_CACHE)。lib.rs::run() 在 env_logger::init() 之后立即 std::thread::spawn 专用 OS 线程调用 prewarm_caches(),不阻塞启动流程。前端发起授权检查时缓存已就绪,verify_license 走缓存路径微秒级返回。
  • 前端超时放宽:LICENSE_NET_TIMEOUT_MS 从 1500ms 调整为 3000ms,为慢机器/首次冷启动留足余量(正常响应 <100ms,3s 仅为极端兜底)。
  • 不影响其他功能:prewarm_caches 仅在后台线程执行,不阻塞启动流程;超时放宽只影响授权检查,不改变其他 API 行为。

v2.0.6 · 截图/录屏健壮性加固(黑窗 + 遮罩挡鼠标 + 录屏选择器)

  • 截图勾选✓弹黑色命令窗口(缺陷修复):截图区域勾选✓确认后屏幕闪现黑色 PowerShell/CMD 控制台窗口。根因:copy_image_to_clipboard 与 OCR 识别使用 std::process::Command::new("powershell") 启动子进程,未设置 CREATE_NO_WINDOW 标志,Windows 默认为控制台程序分配可见窗口。修复:两处 PowerShell 调用统一补 .creation_flags(0x08000000)(CREATE_NO_WINDOW),子进程不再弹黑窗。
  • 录屏后遮罩残留挡住鼠标(缺陷修复):录屏结束/取消后录屏遮罩窗口仍覆盖屏幕,鼠标无法点击桌面与其他软件。根因:recorder.html 的 closeRecorderWindow() 调用 /api/screenshot/close,该端点执行 close_screenshot_window 只关闭截图窗口;录屏窗口(label=recorder)保持 always_on_top 可见,导致鼠标被遮挡。修复:新增独立 HTTP 端点 POST /api/recorder/close,执行 close_recorder_window 真正关闭录屏窗口(取消置顶→最小化→隐藏→移出屏幕);recorder.html 改用 /api/recorder/close + IPC recorder_window_close 双重关闭。
  • 录屏默认不录系统桌面弹选择器(缺陷修复):录屏时不默认录制系统桌面,而是弹出 getDisplayMedia 桌面/窗口选择器让用户选择。根因:取消/异常退出录屏时 cleanupAndClose() 未调用 api_stop_native_record,RecordState 残留为 Some;下一次 start_native_record 返回"录屏已在进行中"错误,前端降级到 navigator.mediaDevices.getDisplayMedia 弹出选择器。修复:close_recorder_window 兜底调用 stop_native_record 释放 RecordState;cleanupAndClose 显式调用 api_stop_native_record;确保任何关闭路径都释放原生录屏状态,下次直接走 xcap DXGI 桌面捕获(无选择器)。
  • 健壮性增强:新增 POST /api/recorder/result HTTP 降级端点(先关窗口再 spawn_blocking 后台保存),IPC 失败时录屏文件不丢失;recorder.html 停止录屏结果保存走 IPC recorder_result,失败降级 HTTP /api/recorder/result;close_recorder_window 统一兜底停止原生录屏 + 释放锁 + 多重保险隐藏窗口。

v2.0.5 · 截图核心缺陷彻底修复(多次截图失败 + 保存后卡死)

  • 多次截图失败根因修复:resetScreenshotUI() 中 const overlay = document.getElementById('screenshotOverlay') 声明了局部常量,遮蔽了全局 let overlay。随后 overlay = null 尝试给 const 赋值,在 ES Module 严格模式下抛出 TypeError,导致 loadAndShow 中断、isActive 卡在 true、轮询永久停止。修复:局部变量重命名为 oldOverlay/oldOcrModal,不再遮蔽全局。
  • 保存后卡死根因修复:screenshot_result IPC 处理函数同步调用 handle_screenshot_result,其中 PowerShell 剪贴板操作阻塞 async runtime 1-3 秒。修复:改用 tauri::async_runtime::spawn_blocking 在独立线程执行保存/剪贴板操作,IPC 立即返回。
  • 新增 HTTP 降级端点:新增 POST /api/screenshot/result,接收 {image, action} JSON,先关窗口再 spawn_blocking 保存。前端 confirmEdit 中 IPC 失败时自动降级走 HTTP,截图不丢失。
  • 移除 window.close() 调用:该调用会销毁 WebView 页面上下文,导致窗口复用时页面空白。移除后窗口由后端 hide() 控制,复用更稳定。
  • 全局变量完整重置:confirmEdit 中重置 overlay/canvas/ctx/annoCanvas/annoCtx/toolbar/tooltip/hint/annotations/redoStack/isDrawing/brushPath/startPos/curPos/textInputEl/mosaicCanvas 全部全局变量。resetScreenshotUI 中释放上一次截图的 blob URL,防止内存泄漏。
  • 错误恢复机制:loadAndShow 的 catch 和 img.onerror 分支中重置 isActive=false,确保错误后轮询不中断,下一次截图仍可正常触发。
  • 剪贴板临时文件唯一化:copy_image_to_clipboard 临时文件从 mt_clip_{pid}.png 改为 mt_clip_{uuid}.png,避免并发截图时文件冲突。

v2.0.3 · 截图架构重构 + 防卡死保障 + 图表修复

  • 截图架构重构(最稳定方案):去掉 fullscreen 模式,改用无边框窗口+手动设置尺寸覆盖屏幕,避免透明+全屏组合在集显上的驱动兼容性问题(Intel 集显尤其严重)。
  • 窗口预创建 + 毫秒级响应:应用启动后 500ms 后台预创建截图/录屏窗口并预加载页面,用户按 Alt+A/Alt+M 时只做"截图 + show 窗口",毫秒级响应,对标微信体验。
  • 纯 HTTP 通信架构:截图窗口与后端通信完全走 HTTP fetch,不依赖 Tauri IPC,避开 External URL 页面 IPC 桥不注入、IPC 消息大小限制等问题,通信最稳定可靠。
  • 九重防卡死保障:① Alt+A/Alt+M 切换关闭(再按一次立即退出)② 前端 ESC 关闭 ③ 前端三重关闭保险(HTTP+IPC+window.close)④ 后端四重关闭保险(取消置顶+最小化+隐藏+移出屏幕)⑤ visibilitychange 立即检测 ⑥ 心跳监控强制关闭(前端每2秒心跳,后端每5秒检测,15秒无心跳则强制关闭)⑦ 原子锁 30 秒超时自动释放 ⑧ 5 分钟超时自动关闭 ⑨ 窗口移出屏幕终极兜底。
  • 临时文件传递方案:xcap 截图写入临时 PNG 文件,通过版本号轮询通知前端,HTTP GET 获取二进制字节 → Blob URL 加载,避免大 base64 字符串通过 IPC 导致消息丢失。
  • 图表显示修复:Mermaid SVG 渲染后移除固定 width/height 属性,完全由 CSS 控制缩放,集显上更可靠;容器顶部对齐确保图表不被裁;高度超出时显示滚动提示。
  • 首页精简优化:核心能力从 10 条竖排长列表改为 5x2 图标卡片网格布局,更简洁整洁,hover 有上浮动效。
  • 文档导入状态修复:导入按钮"导入中..."状态在打开/关闭弹窗、渲染文件列表时三处重置,避免状态残留导致用户以为"一直在导入中"。
  • RTF 导入修复:新增完整 RTF 解析器,处理控制字/参数、跳过 fonttbl/colortbl/pict 等非文本 destination、支持 \uNNNN Unicode 字符、\'XX 十六进制字节、转义字符、表格单元格。
  • DOCX/ODT 导入改进:检测 Heading1-6 标题样式生成 Markdown 标题,检测表格结构用 | 分隔单元格,ODT 修复只从 text:span 提取文本的缺陷。
  • 导出保存性能修复:saveBlobWithDialog 从 btoa 逐字节拼接改为 FileReader.readAsDataURL 方案,避免大文件时性能崩溃。

v2.0.2 · 截图标注 + 录屏 + OCR + 独立窗口无感触发

  • 独立截图窗口:Alt+A 触发截图时不再调起主程序界面,创建独立透明全屏窗口,系统任意位置无感触发。窗口无边框、透明、置顶、全屏、跳过任务栏,前端加载完成后才显示避免白屏闪烁。
  • 截图标注编辑器:对标微信截图,支持矩形框、箭头、画笔、文字、马赛克、序号标签 6 种标注工具,6 色调色板(红/黄/绿/蓝/白/黑)+ 3 档线宽(2/4/8px)+ 撤销重做(Ctrl+Z / Ctrl+Y)+ 确认/取消。
  • OCR 文字识别:截图后点击 OCR 按钮调用 Windows 内置 OCR API,支持中文/英文自动识别,弹窗显示识别结果可复制。
  • 独立录屏窗口:Alt+M 同样独立透明窗口,背景帧 + 区域选择 + 原生 xcap DXGI 帧捕获 + WebM 保存。选区遮罩与截图一致(红色虚线选区 + 像素 tooltip + 开始/取消工具栏 + 录屏提示条)。
  • 遮罩不消失致命缺陷修复:窗口销毁从 hide 改为 destroy;前端先清空 document.body 再调 IPC;三层降级保障(DOM 清空 → window.destroy() → window.close())。
  • 前端 Alt+A/Alt+M 改为 IPC 触发:调用 api_trigger_screenshot / api_trigger_record IPC 命令(和全局快捷键走同一路径),不再走 HTTP 调起主窗口。HTTP 降级路径也不再调起主窗口。
  • 快捷键面板全面更新:设置面板快捷键栏分为全局快捷键、编辑器快捷键、AI 快捷键三个分区。修复多处快捷键显示与实际不一致问题(Ctrl+E→Alt+E、Ctrl+W→Alt+W、Ctrl+Shift+F 描述等)。欢迎页快捷键更新为实际生效的 8 个核心快捷键。

v2.0.1 · 图谱修复 + 轻量绘图 + AI增强 + 代码高亮 + 导出优化 + DeepSeek接入

  • 图谱界面无文档节点修复:FileEntry.content 懒加载后为 None,get_graph 得空字符串无 wikilink 边,前端过滤掉所有 doc 节点;修复为对 content=None 的文件调 read_file_force 触发磁盘读取并回填缓存。
  • 内置轻量 Canvas 绘图编辑器:新建 draw-editor.js(30KB 零依赖 100% 离线),7 种工具(选择/矩形/圆形/菱形/箭头/直线/文字/自由画笔)+ 样式(边框/填充/线宽/字号)+ 撤销重做(最多 50 步)+ 键盘快捷键(1-8 切换工具),保存为 Excalidraw 兼容 JSON。
  • AI 生成 HTML 图表/动画正确显示:过滤 AI 输出控制字符防 JSON 解析失败、iframe sandbox 补 allow-scripts、AI 内容包裹为 html-inline fence 块在隔离 iframe 中渲染。
  • DeepSeek API 接入:API Key 输入隐藏 + 跨升级持久化 + 连接测试按钮 + Ollama 失败自动切换 DeepSeek + 关键词 AI 搜索降级。
  • AI 二次优化上下文增强:Ctrl+I 行内 AI 上下文提取为 4 维度叠加(光标所在 fence + 上方最近 fence + 光标所在段落 + 前后短上下文),确保 AI 能看到完整原作。
  • 配置丢失修复:移除 deepseek_api_key 的 skip_serializing 属性 + 统一配置保存/加载路径。
  • 代码语法高亮 CSS 全覆盖:styles.css 补齐 30+ 种 hljs span class 映射到 CSS 变量,亮/暗主题自动切换。
  • 代码块语言选择器:编辑工具栏新增 40+ 语言下拉面板(常用/编程/Web/数据库/数据配置 5 组)。
  • 内嵌 HTML 导出优化:导出时轮询 iframe srcdoc 内容高度并写入内联 style,消除固定 min-height 裁剪和滚动条。

v1.8.107 · 阅读模式不弹AI菜单 + 工作区外部新增文件自动刷新 + .key文件正常显示 + 代码语法高亮

  • 阅读栏/阅读模式选中文字不再弹AI提示框:refreshAiSelectionMenu 函数开头判断 state.mode==='view' 时直接隐藏AI菜单并 return,仅编辑模式保留 AI 选区菜单,阅读模式下选中文本可自由复制不被打断。
  • 外部保存新文件到工作区目录后文件树自动刷新:新增 refreshTreeThrottled 节流函数(15s 内不重复刷)调 bootstrap(true) 触发后端 refresh_cache() 全量扫描,visibilitychange 页面恢复可见 + window.focus 窗口聚焦两个回调触发刷新,startTreeRefreshInterval 60s 低频定时兜底,document.hidden 时跳过避免无谓 IO。
  • .key结尾文件正常显示:is_binary_ext 移除 'key',.key 文件被扫描进文件树 + 全文搜索 + read_file 能读内容(agent_policy deny **/*.key 保留确保 AI 不自动读密钥内容但用户能手动打开看)。
  • 代码语法高亮引入 highlight.js:下载 highlight.min.js(11.9.0,121KB,35+ 常用语言)到 public/vendor/highlight/ 离线打包,styles.css 新增 .hljs-* 到 --syn-* CSS 变量映射适配亮/暗主题切换,app.js 新增 highlightCodeBlocks 函数 + requestIdleCallback 分批每批 8 个 + dataset.highlighted 防重复 + hljs 未加载静默降级,调用点 5 处全覆盖。

v1.8.106 · 文档切换编辑位置保留 + 外部编辑器异步编辑冲突检测 + 重新加载强制读磁盘

  • 临时区多文档切换保留编辑位置:扩展草稿机制新增 saveDraftState/restoreDraftState,按文档路径在 localStorage 持久化光标 selectionStart/End + 编辑器 scrollTop + 阅读器 scrollTop,openDoc 切换时 restoreDraft 回填文本后立即恢复光标和双滚动位置(包在 requestAnimationFrame 中等待 DOM 布局完成避免 scrollTop 被钳制为 0),关闭文档时 removeItem 清理。
  • 外部编辑器异步同时编辑同一文档不再静默覆盖:后端 save_file 新增 base_hash 参数保存前 sha256 比对磁盘文件不一致拒绝保存返回 __CONFLICT__:disk_hash,前端 saveCurrentDoc 收到 conflict:true 弹窗确认覆盖或取消;新增 /api/doc-check 端点前端每 5s 轮询当前文档哈希,与打开时记录的 currentVersion 不同则 Toast 提示「重新加载/忽略」,重新加载前若有未保存编辑二次确认丢弃。
  • 点击「重新加载」强制读磁盘绕过 cache:read_file L1 cache 命中时直接返回内存旧 content,导致 check_file 检出外部修改后点重新加载仍看到旧内容;新增 read_file_force 方法跳过 cache 从磁盘重读 + decode + 写回 cache,/api/doc 新增 force=1 参数,前端两处重新加载按钮均带 forceReload=true。

v1.8.105 · 全局搜索中文 MD「打不开/没内容」空白屏·三重修复

  • NFC 路径全链路归一:Mac HFS+ NFD / Win NTFS NFC / NAS 短名/UNC 中文路径搜索结果点不开的根因是字符串 == 字节序列不同漏查;引入 unicode-normalization crate,全链路 ref_path NFC 归一。
  • basename 三级弱匹配兜底:主路径 cache==/NFC 都 miss 后,按 basename NFC 精确相等+同 workspace 唯一、去尾缀再唯一、全局 workspace 内 basename 全局唯一三级匹配。
  • 空内容/空白屏不再静默:右侧阅读栏渲染灰底虚线卡片提示「WPS/Word/江西电信导出 MD 请记事本另存为 UTF-8 覆盖原文件」,左侧编辑器设置多行空内容占位符,Worker 抛错 catch 分支顶部 prepend 红色异常 banner。
  • BOM + GBK/UTF16/UTF32 智能编码解码兜底:引入 encoding_rs,scan_workspace 和 read_file 都从 read_to_string UTF-8 改为 read bytes → BOM → GB18030/GBK/BIG5/SHIFT_JIS/EUC_KR 序列候选,识别出的非 UTF-8 编码写入 FileEntry.encoding 前端状态栏可见。

v1.8.104 · 安装后启动失败(前端资源缺失)紧急修复·双重保险

  • 打包侧强制目标映射:tauri.conf.json 的 bundle.resources 从字符串数组改为 Tauri 2.x 对象映射,强制写死安装目的地 {src:../public,target:resources/public} + {src:WebView2Loader.dll,target:""},消除 NSIS 字符串资源解包路径歧义。
  • 运行时 10 级候选 + 404 页完整枚举:resolve_public_root 从返回 PathBuf 升级为返回 (PathBuf, Vec<PathBuf>),候选从 5 条扩充到 10 条,内置 404 友好页打印编号后的全部候选。
  • 端口占用自动回退:bind_first_available 按 7321..=7420 顺序扫描返回第一个空闲端口,轮询 axum / splash 加载 / 首页导航 / 30s 超时提示全部使用真实端口。
  • 前端资源缺失内置中文错误页:如果 10 级候选都找不到 public/index.html,Rust 端直接返回内置最小 HTML 错误页(深色主题 + 当前尝试路径列表 + 3 步解决操作提示)。

v1.8.103 · 原生另存为 + 路径查看 + DOCX/RTF/ODT 正文提取

  • 7 项导出统一接入系统原生「另存为」:新增 Rust Tauri 命令(save file dialog + 真写磁盘 + 返回绝对路径 + 打开文件 / 在文件夹中查看),保存成功后 Toast 显示完整绝对路径 + 两按钮;取消对话框静默不报错;非 Tauri / 插件失败自动降级 Blob 下载。
  • 导入 DOCX/RTF/ODT 正文自动提取:Rust 新增 3 个正文提取 helper(ZIP + 控制字剥离 + strip_inner_tags),不再生成 pandoc 占位文档。
  • 导入弹窗原生系统按钮:importModal 按钮区新增「系统文件对话框」(Tauri 环境下自动显示),accept 与 Rust 过滤器同步 11 类文件。
  • 全链路兼容与健壮:所有 invoke 双重兼容 window.__TAURI__.core.invoke 与 window.__TAURI__.invoke,base64 编解码统一。

v1.8.102 · 其他电脑安装后 HTTP 404 白屏紧急修复

  • 致命根因:tauri.conf.json bundle.resources 原本只有 WebView2Loader.dll,前端 public/ 目录完全没有进入 NSIS 安装包,用户电脑安装后 axum 的 resolve_public_root 用编译期 CARGO_MANIFEST_DIR/../public 指向开发机目录(其他电脑不存在),请求全部返回 HTTP ERROR 404。
  • 打包侧修复:bundle.resources 追加 "../public",NSIS 安装器会把 public 整个目录解包到安装目录/resources/public/。
  • 运行时 5 级候选 + index.html 真校验:优先级环境变量 > exe_dir/resources/public > exe_dir/public > CARGO_MANIFEST_DIR/../public > ./public,候选目录必须同时"是目录 + 含 index.html 文件"才会被选中。
  • 端口占用自动回退:bind_first_available 按 7321..=7420 顺序扫描返回第一个空闲端口。
  • 前端资源缺失内置中文错误页 & 30s 超时中文引导:Rust 端直接返回内置最小 HTML 错误页。

v1.8.101 · 全格式导出质量升级 & Frontmatter 不再外漏

  • Frontmatter YAML 不再出现在任何导出文件:菜单 7 项导出在写入前统一使用 stripFrontmatter() 或 Rust split_frontmatter().body 剥离 frontmatter 块;原 MD 文件写入磁盘时仍 100% 保留 frontmatter。
  • HTML 导出:从 HTTP 400 升级为高品质离线文档:前端 buildExportableHtml() 离屏 900px 容器渲染 → KaTeX DOM + Mermaid SVG → 本地图片全部转 data URI → 内联 PRINT_STYLES + KATEX_PRINT_CSS → 文末品牌推荐卡片 → Blob 下载。生成文件离线双击也能显示公式/Mermaid/中文/图片。
  • Word DOCX 导出:从 HTTP 400 升级为 Word/WPS 可直接打开的兼容格式:使用 HTML 导出的全链路内联结果 + 写入 UTF-8 BOM + application/msword MIME → 文件名后缀 .doc。
  • TXT 导出:语法糖剥离 + 中文编码防乱码:Rust strip_markdown_for_txt() 删除 fenced 包裹行 / ATX 前缀 / Setext 下划线 / 引用块前缀 / 加粗 / 斜体 / 删除线 / 代码 / 图片 → alt / 链接 → text / HTML 注释;前端兜底写入 UTF-8 BOM 防中文乱码。
  • 保存成功率统一修复:所有 Blob 下载改用 triggerBlobDownload:<a> 入 DOM 后 setTimeout 50ms 再触发 click,3000ms 后 remove 节点 + revokeObjectURL。

v1.8.100 · 启动红屏 SyntaxError 紧急修复

  • 致命语法错误修复:app.js 第 1872 行 KATEX_PRINT_CSS 中 IE10 老 Hack box-sizing:content-box \10 在模板字符串内被 WebView2/Chromium 解析为八进制转义序列,严格模式直接抛 Uncaught SyntaxError,app.js 文件级解析失败 → 启动红屏。删除无用 IE10 hack 后模板字符串语法合法,红屏立消。
  • 保持 v1.8.99 三项阅读栏/阅读模式修复完整:Worker 三分支补齐 renderMathInPreview + renderChartsInPreview、markdown-worker.js 侧 mermaid/excalidraw chart-block 容器结构生成、renderMarkdown 与 Worker 双处「跨行 $$...$$ 占位符保护 + 还原」三条核心修复继续生效。
  • 缓存强失效:MARKDOWN_WORKER_URL query 升级、MARKDOWN_RENDER_VERSION 升级,编辑预览/阅读栏/阅读模式三路缓存全部强制重算。

v1.8.99 · 阅读栏/阅读模式公式/图表全面修复

  • 阅读栏/阅读模式渲染调用补齐:renderReaderContent 主路径、catch 回退路径、renderReaderContentChunked 单 slice 分支三处全部在写入 markdownView.innerHTML 后立即调用 renderMathInPreview + renderChartsInPreview,解决常见文档下公式、Mermaid、Excalidraw 永远不渲染的主因。
  • Worker 端 Mermaid / Excalidraw 占位生成补齐:markdown-worker.js 渲染主路径 fenced 代码块闭合分支与主线程 renderMarkdown 严格对齐:mermaid 输出 .chart-block.mermaid-block + pre.mermaid-source + div.mermaid-container(空占位);excalidraw 输出 .chart-block.excalidraw-block + pre.excalidraw-source + div.excalidraw-container(空占位)。
  • 跨行块级公式 $$...$$ 修复:markdown-worker.js 与 app.js:renderMarkdown 都新增「先保护后还原」占位符机制:按 fence 分段 → 非 fence 段用占位符把整段 $$...$$ 替换为一行 token → HTML 生成完成后还原为 <span class="math-block" data-math="...">;彻底解决旧逐行切割跨行公式的问题。
  • 缓存与脚本版本强制失效:MARKDOWN_RENDER_VERSION 和 MARKDOWN_WORKER_URL query 升级,保证 cachedRenderMarkdown LRU + Worker 脚本 + 前端静态资源浏览器缓存全部强制走新解析。

v1.8.98 · PDF 导出大升级

  • 图表导出:Mermaid 代码块在打印前异步调用 mermaid.render 生成 SVG → 逐节点 getComputedStyle 把 fill/stroke/stroke-width/opacity 写入 inline style → XMLSerializer 转 data:image/svg+xml → 独立 <img> 替代;脱离外部 CSS 后 PDF 内仍能完整显示。Excalidraw 块无运行时则降级为等宽源码显示。
  • 公式导出:.math-block 与 .math-inline 在打印前使用 katex.render() 真实渲染 DOM;同时 PRINT_STYLES 内联注入约 90 条 KaTeX 关键布局类,about:blank iframe 无需再请求 CDN CSS;\frac、\sqrt、上下标、矩阵、\sum 均正确输出。
  • 品牌推荐语:文末默认追加独立品牌推荐卡片(流式文档流、page-break-inside:avoid,非 fixed/watermark,绝不会遮挡正文):紫蓝渐变圆形徽章 M + 标题 + slogan + 官网下载超链接;多页 PDF 仅末页显示。
  • 图片内联:容器内相对路径 <img> 再次 fetch → blob → readAsDataURL 内联,PDF 离线打开图片仍完整显示;打印样式 @page size:A4;margin:18mm 14mm;图表块与品牌卡片用 page-break-inside:avoid 防跨页切裂。

v1.8.97 · 编辑器字体优化 + 字号快捷键修复

  • Ctrl+/- 编辑器字号快捷键最终修复:事件监听同时注册在编辑器宿主和 document 全局两重,编辑区焦点、工具栏焦点、目录焦点三种上下文都能稳定放大/缩小字号;Ctrl+0 立即重置。
  • 重启保留用户习惯字号:loadSettings → applySettings 末尾主动 applyEditorFontSizeToDom,把 localStorage 的 docContentFontSize 同步到 #editor 及 CodeMirror 多节点。
  • 编辑模式字体全面优化:等宽字体栈 Cascadia Mono / Cascadia Code / JetBrains Mono / Fira Code → 中文 Sarasa Mono SC / Source Han Mono SC / PingFang SC / Microsoft YaHei UI → Consolas 兜底;font-feature-settings liga/calt/cv11/ss01 开启等宽连字与数字替代;行距与留白优化。
  • 兼容保障:字号调整会对 .cm-editor/.cm-scroller/.cm-content/.cm-line/.cm-gutters/selection/cursor/activeLine 层以及 #cursor-overlay 全部显式 setProperty(important),并调用 requestMeasure 强制 CodeMirror 重绘避免滚动条错位。

v1.8.96 · 代码文件保存最终修复 + 工作区视图

  • UI 拒绝文案彻底清除:打开代码/文本文件时 saveBtn.disabled=false、清除旧 title、强制替换为「保存 (Ctrl+S)」、移除 readonly/disabled/unsupported class。
  • 底部 lastSaveText 正确显示:非 Markdown 不再出现「不可保存」。openDoc 末尾按编辑器与原内容一致性判断:有草稿且不同→未保存+scheduleAutoSave,其余→保存。
  • 保存链路再确认:非 md 文档打开即自动 setMode('edit') → runAutoSave gate 通过 → saveCurrentDoc → /api/save(后端 save_file 已对任意文本后缀放行 v1.8.94)。
  • 工作区视图:折叠态整个工作区扁平 Top10 按 modified 倒序 + 当前打开文档兜底可见;展开态 renderTree 递归完整目录树(文件夹独立展开/收起 + 每层文件按 modified 倒序)。

v1.8.95 · 工作区视图重写 + 基础保存修复

  • 基础保存修复:代码后缀打开默认进入编辑态,避免 runAutoSave 被 view 模式短路。
  • 工作区折叠态:收起时整个工作区全部文件按 modified 倒序取前 10 个 + 保证当前打开文档可见;尾部「共 X 项,展开查看全部」。
  • 工作区展开态:渲染真正目录树结构;所有文件夹独立展开/收起;每层文件按 modified 倒序;尾部「收起」按钮返回折叠视图。

v1.8.94 · 工作区与编辑器增强

  • 非 MD 文件显示:工作区目录 mdOnly=false 时显示 bat/vbs/js/py/ini/txt/sh/code 等文本/代码文件(二进制黑名单+10MB 上限)。
  • 展开全部修复:工作区目录「展开全部」时无数量限制显示全部文件,收起时保持简洁。
  • 代码文件支持:代码后缀可正常打开编辑保存;非 MD 预览使用等宽字体+换行样式。
  • 文件排序:工作区目录文件按修改时间倒序排列(最新在前)。
  • 字体快捷键:Ctrl+= 增大编辑器字体,Ctrl+- 减小,Ctrl+0 重置(10~32px,localStorage 持久化)。

v1.8.93 · 界面与体验升级 + 性能优化

  • 界面与体验升级:工作区添加对话框 UI 修复(z-index+遮罩层级);搜索支持多关键词 AND + 精确短语 + 评分排序;快捷键调整(Ctrl+W → Alt+W / 新增 Alt+E / Alt+O);自升级真实 fetch 远程版本语义化比较;窗口启动默认最大化。
  • 功能无损性能优化:状态栏 DOM 引用缓存(_statusFieldCache),每秒避免 4+ 次 querySelectorAll;页面隐藏时暂停系统时间 setInterval;合并编辑器 3 个 scroll 监听器为 1 个 passive;5 个 resize 监听器统一 100ms 去抖。
  • 沉浸+轻量模式整合:一个按钮(⚡ 沉浸)同时实现沉浸写作与轻量编辑——进入时终止 Markdown Worker、禁用语法高亮 CSS、隐藏预览/大纲面板,退出时自动重建 Worker 并刷新预览。
  • 文档安全加固:渲染序号竞态防护(readerRenderSeq)、Worker 失败后 5 秒冷却可重建、openDoc 被覆盖时回滚清理、切换文档前同步保存草稿、保存接口返回 contentSha256 支持乐观锁。
  • 内存/GPU 优化:contentStore LRU 缓存(最多 50 热文档)、知识文档上限 300、轻度 trim 250MB/激进 320MB;图谱模拟间隔拉长 30%、shadowBlur 降级、backdrop-filter blur 缩小。

← 返回首页