Releases: xyy277/doc77
Releases · xyy277/doc77
Release list
v1.1.10
[2026-08-19] — 1.1.10
Fixed — preview 多 tab 内容缓存失效链(core/web)
- 外部修改自动刷新:SSE
file-tree:changedmodify/mixed 事件命中打开中的 tab 时,活动 tab 1s 节流自动重载新内容(编辑中/页面隐藏不打断,横幅保留);后台 tab 切回激活时强制 fresh 重拉。修复前三层前端缓存(tabDataCache/paneCache/SW SWR)命中即走、从不校验新鲜度——外部更新后已打开 tab 与"刷新目录树后重开"均显示历史内容 - SW 缓存绕过:内容请求引入
x-doc77-fresh网络优先语义(横幅手动重载、后台 tab 激活、启动校验共用),修复"清内存缓存后首次仍被 SW SWR 喂旧数据";fresh 响应照常写回缓存,离线能力不变 - 启动新鲜度校验:boot 恢复的 tab 后台校验(带 If-None-Match,未变走 ETag 304 零渲染),覆盖"应用关闭期间文档被外部修改、重启后显示旧内容"
- 目录树刷新兜底:刷新后对比 open tab 的服务端 mtime(SSE 断线/漏事件/单事件 paths>50 truncated 时生效),走与 SSE 同款自动刷新链路
- ETag 精度:markdown ETag 去
Math.round保留mtimeMs小数,粗粒度文件系统同秒内修改不再 304 复用旧体 - 新增
doc-freshness.js纯函数模块(isNewer/autoReloadDecision);SWCACHE_VERSIONv4→v5 清除修复前残留的过期 SWR 条目
验证
- 测试 929 passed(+8:doc-freshness 决策矩阵、ETag 小数精度)
- 实测:ETag 小数精度、If-None-Match 304、外部修改 etag 失效、SSE modify 事件携带路径
v1.1.9
[2026-08-18] — 1.1.9
Fixed — watcher OOM(core)
- chokidar
followSymlinks: false:注册项目为 pnpm monorepo 时(packages/*/node_modules→.pnpm虚拟 store 交叉 symlink 图),chokidar 默认跟随 symlink 展开成指数级枚举——ready永不触发、零事件、以 ~17-25MB/s 分配 fs 对象直至 V8 4GB 堆满 OOM(打开 Dashboard 后 ~4 分钟崩溃,exit 134)。symlink 按普通文件处理(node_modules 本就在忽略列表);项目根fs.realpathSync归一化保证 symlink 项目根仍可监听。回归测试:symlink web fixture(120 包 + 60 symlink)旧代码watcherReady()超时、新代码毫秒级 - 沙箱实测:全量 preview 流量 3 分钟 RSS 恒定 ~323MB(修复前 80s OOM)
Fixed — config 敏感值加密(core/cli/electron)
- 机器密钥文件
config.key(与data.db同目录、权限 0600、AES-256-GCM):ai.token等敏感 config 值统一加密落库。修复前 CLIdoc77 config set从未加密;设置页加密分支依赖user_auth.pbkdf2_salt,DEK 迁移后该字段被清空导致加密失效 → 明文落库 setConfig/getConfig统一加解密(读取三级回退:机器密钥 → 旧 pbkdf2 派生 key → 明文兼容);listConfig/GET /api/config敏感值解密后打码- 启动幂等迁移
migrateSensitiveConfigs()(CLI + Electron):历史明文/旧密文 → 机器密钥加密 - 删除 app.ts 三处复制粘贴的手工 pbkdf2 解密分支
Fixed — bfcache 僵尸 SSE 连接(core/web)
- preview/graph 页
pagehide(persisted)主动关闭 EventSource、pageshow重建(Chromium bfcache 冻结页面连接不关闭,占用每源 6 连接槽位 → 反复进出页面后同源请求永久排队) - SSE 心跳 30s(NAT/代理空闲超时)+ write 失败即收割(
res.destroy()保证 watcher 引用释放) - graph 页 SSE 作用域提升至 factory 级(pageshow 可重建);SW
CACHE_SHELLLRU 上限 50
验证
- 测试 921 passed(+13:watcher followSymlinks 回归、config 加密 roundtrip/兼容/迁移幂等/权限)
v1.1.7
[2026-08-16] — 1.1.7
全包 (1.1.7)
Added — 知识图谱二阶段:可视化 + 洞察(core)
/graph力导向图谱页:Canvas + vendor 懒加载 d3-force(dispatch/quadtree/timer/force 4 模块按序),5000 节点 <60fps(DPR≤2、视口裁剪、标签上限、收敛即停);节点大小 = 入链数、颜色 = 首标签、孤立页淡化开关;拖拽/缩放/点击打开文档、FTS 搜索定位(缩放居中 + 高亮)- 多项目聚合图谱:
/api/graph?projects=家族(nodes/stats/orphans/broken,查询层 IN 合并零表结构改动)+mode=full全量模式(20k 节点/200k 边上限 + truncated 探测);项目 tab 切换含"全部" - 洞察侧栏:孤立页/死链列表(与 stats 同谓词共享,计数永远一致),断链行点击打开源文档编辑
- 入口:dashboard 导航 + preview 工具栏;PWA shell 资产;i18n
web.graph.*双语
Added — AI 对话引擎(ai/cli/electron)
- AgentLoop 会话处理(SessionStore 持久化)+ Ollama provider 支持 + 会话消息树/中断/regenerate
Changed
- SSE 认证:
/api/events接受?token=查询参数(EventSource 无法携带 header;窄范围仅该端点,header 优先)——预览页与图谱页设密后事件推送恢复 - 安全加固(独立对抗性审查 38 项发现修复):XFF 信任边界(修复伪造
X-Forwarded-For: 127.0.0.1绕过隧道门控的 P1 漏洞,仅本机代理转发时信任且取末条真实 IP);limit 参数下界 clamp(负值不再绕过上限,防 LAN 内存 DoS);聚合路由 FULL caps;JSON.parse(tags)防御;严格整数参数解析 - 图谱页修复(审查确认 21 项):拖拽失效(sim 收敛后保留引用 lazy restart)、属性注入 XSS(escAttr → esc)、命中半径随缩放、reload 保留缩放视图、SSE 401 重连循环(3 次失败提示)、d3 vendor 探测缺失(离线即挂)、孤儿 >10000 上限提示
Fixed
- d3-force UMD 依赖加载(单文件加载抛
r.timer is not a function) - POST
/api/graph/:id/index双重建(5s 去抖计时器未取消 → 全量 ×2) - 子图边查询窗口截断(>8000 边项目锚点边静默缺失)
验证
- 测试 853 passed(+21 独立验证新增);perf 回归:5000 节点全量图接口 ~49ms、20 万边表孤儿/断链 ~30ms、事件循环停顿 <50ms
- Playwright 浏览器冒烟 13/13(
pnpm exec tsx scripts/graph-e2e-smoke.mts) - 审查记录
docs/planning/graph-viz-review.md;手工冒烟清单docs/planning/graph-viz-smoke-checklist.md
v1.1.6
[2026-08-16] — 1.1.6
全包 (1.1.6)
Fixed
- 目录树刷新失效(1.1.5 回归):外部新增文件后,已展开的目录内容不更新(点 🔄 刷新、重进项目均无效)
- Web: 🔄 刷新按钮改为刷新根目录 + 所有已展开的目录(此前只刷新根目录,展开子目录的 DOM 与 SW 缓存条目永不更新)
- Web: Service Worker
CACHE_VERSIONbump 至doc77-v4—— 清除 1.1.4 时代缓存的旧/api/tree条目(SWR 命中即返回旧数据) - Core: watcher 初始枚举窗口期(chokidar 递归建 watch,大项目根可达数十秒)内发生的文件变化不产生事件 →
ready后为每个项目补发一次全量刷新事件;另加 SSE 连接 5s 定时兜底(ready不触发的大目录环境)
v1.1.5
[2026-08-15] — 1.1.5
全包 (1.1.5)
Changed
- DB 层迁移:sql.js(WASM 全内存)→ better-sqlite3(原生) — 三个性能根因一次性根除:
- Core: 删除 sql.js 全库 export 序列化 + 去抖落盘机制(1.1.3 性能灾难放大器,1.1.4 节流为临时缓解)— WAL 模式下每写即落盘,崩溃不丢数据,
flushDatabase()保留为 no-op 兼容导出 - Core: DB 不再常驻 WASM 堆,内存基线不再随库大小线性增长
- Core: FTS5 搜索真实可用(sql.js 官方 dist 无 FTS5,此前一直是 LIKE 全表扫描);历史库自动迁移(v14:FTS 表 DROP 重建 + 一次性全量重索引)
- Core: 删除 sql.js 全库 export 序列化 + 去抖落盘机制(1.1.3 性能灾难放大器,1.1.4 节流为临时缓解)— WAL 模式下每写即落盘,崩溃不丢数据,
- Core:
flushDatabase语义变更(no-op),persist-throttle测试改写为 WAL/持久化/FTS5 回归
Fixed
- Web: 删除/新建/重命名文件后,目录树在刷新或重进项目时可能仍显示旧状态(再操作报"文件不存在")— Service Worker 的 SWR 缓存对
/api/tree命中即返回旧数据且变更后从未失效;现在变更类请求通过时清除该项目范围的缓存条目,SSE 刷新响应同步写回缓存
Docs
docs/planning/performance-architecture-review.md:P-A 专项标记完成 ✅,记录实际改动与遗留问题
v1.1.4
[2026-08-15] — 1.1.4
全包 (1.1.4)
Fixed
- 致命性能回归(1.1.3 引入):文件监听链路每个 fs 事件 → 目录缓存 DB 写 → sql.js 整库序列化落盘,导致内存暴涨至 ~1500MB、CPU 持续 ~10%、打开即卡死
- Core: 目录树缓存移入进程内内存 Map(不再读写
filetree_cache表,热路径 0 DB 写;表结构保留,历史行启动时清理;删除scanned_at死写) - Core: sql.js 全库序列化落盘加最小间隔节流(连续写入时最多每 2s 一次,与写入频率/库大小解耦;
flushDatabase()仍强制立即落盘,新增导出) - Core: 文件监听改为惰性启动(首个 SSE 客户端连接才启动,断开后延迟停止)— 无 UI 客户端时零开销;移除
awaitWriteFinish的 50ms stat 轮询;去抖 300ms → 500ms - Web: 目录树刷新合并为 1s 去抖,页面隐藏时不刷新(恢复可见补刷)
- Core: 目录树缓存移入进程内内存 Map(不再读写
- Core: 目录扫描缓存校验从逐条目 statSync 降为单次目录 stat(O(N) → O(1),"进入项目/展开目录"明显提速;内容修改由 watcher 精确失效兜底)
- Core: 启动不再无条件加载 4.5MB AWS SDK / webdav / simple-git / sharp(改为按需动态加载)— 冷启动提速
- Electron: 启动补
pruneAiSessions(24)与audit_log/sync_log90 天保留窗(此前仅 CLI 清理会话,Electron 永不清 → 表无限膨胀拖慢全库序列化) - Web: Service Worker API 缓存(Cache API + IndexedDB 各一份)加 200 条上限 + 30 天过期裁剪(此前无上限,长期使用存储无限膨胀)
- Web: 首屏去阻塞 — 移除远程 phosphor 图标脚本(3 处图标改文字字形)、脚本加
defer、highlight 主题 CSS 改懒加载(原远程渲染阻塞)
Docs
docs/planning/performance-architecture-review.md:性能根因证据链(sql.js 全库序列化放大器 + watcher 引爆链路)、修复记录、后续架构专项路线图(better-sqlite3 迁移 P-A / 搜索改造 P-B / boot 并行化 P-C)
已知风险
sync调度器interval_seconds无下限(用户可配置 1s 全量同步)— 级联已拆断后仅剩扫描成本,后续专项处理
v1.1.2
[2026-08-14] — 1.1.2
全包 (1.1.2)
Fixed
- Electron: 修复发布门禁测试 — fileAssociations 断言从
package.json迁移至electron-builder.yml(构建配置已随 95721cb 迁移) - Web: AI workspace 新增 settings 抽屉,修复 dark theme 与 preview settings 面板侧移(
translate-x-full)问题 - Web: 预览复制改为复制渲染后的 HTML(而非原始 JSON)
- Web: 修复
wireActions中 aiMessages 节点被错误替换的问题 - Gallery: 恢复 auth token、thumbnail API 与目录导航
v1.1.1
[2026-08-12] — 1.1.1
全包 (1.1.1)
Added
- Electron: 登录门禁强制重设(Force Reset)— 同时忘记密码与 recovery code 时,经 IPC + 原生对话框双重确认重置认证,清除全部敏感配置(token / API key 类),保留文档与项目数据
- Core:
forceResetPassword()清除范围扩展至全部敏感 config(isSensitiveKey+ legacyai.base_url/ai.model),新增 in-memory reset-state 清理与source审计参数(cli/electron/web) - LICENSE: 新增 MIT 许可证,修复 README license badge 死链
Security
- Force reset 通道仅限 Electron 进程内(IPC),LAN / web 客户端无法触发;重置后撤销全部会话并清空 DEK 缓存
v1.1.0
[2026-08-10] — 1.1.0
全包 (1.1.0)
Added
- Sync: three-way merge(三向合并)引擎、E2EE(End-to-End Encryption)加密适配器(Git / WebDAV / S3)、conflict 检测与 AI 辅助合并、定时调度器、keyring 密钥管理
- AI: RAG(Retrieval-Augmented Generation)引擎 — chunker / embedder / retriever / vector-store,Provider 动态切换
- Core: plugin 沙箱(vm 隔离 + renderer takeover)、tunnel 配置与设备管理 + 强制远程认证、PWA SW 策略、csv/tsv 表格渲染、DB migrations
- Web: sync / tunnel / plugin / conflict / encryption 设置面板,i18n 扩展(+92 keys,共 1074 keys)
- Electron: 系统通知、待处理文件(pending-files)、文件关联(file associations)、接线 sync/rag/plugin 路由
- CLI: wiring-regression 接线回归测试(真实服务器启动 + 真实 fetch 验证)
Security
- tunnel 强制远程认证(forced remote auth)
- Sync E2EE 适配器 + keyring 加密存储
v1.0.8
[2026-07-24] — 1.0.8
全包 (1.0.8)
Fixed
- Gallery: Tailwind CSS 构建时添加
@source指令扫描 gallery 文件,确保样式正确生成 - Monorepo: vitest 添加 root 配置,修复 monorepo workspace 解析问题