From 40fd9c23952057cab8fab4718e463adf63ba010f Mon Sep 17 00:00:00 2001 From: svtter Date: Fri, 31 Jul 2026 14:10:56 +0800 Subject: [PATCH 1/5] feat(version-chain): HTML content diff between adjacent versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在版本链基础上补齐 HTML 行级 diff——补全"v2 到底改了什么"这个最直接的问。 用户在预览页版本时间线侧栏点"Show HTML diff"即可看到相邻版本的红绿行。 算法层 (internal/session/htmldiff.go, 纯函数无依赖) - LCS 动态规划, DiffLines 输出 LineOp{Kind: Equal|Add|Delete, Text, OldNo, NewNo} - 修改 = 先 delete 后 add (符合 unified diff 习惯) - MaxDiffLines=10000 保护: 超阈值返回跳过哨兵, 不让 O(n*m) DP 拖垮请求 - SplitLines 去尾空行, Summarize 计数 数据层 (internal/session/version.go) - DiffSessionHTML(fromSID, toSID): store.Get 两份 -> os.ReadFile 离盘 diff - 项目首个读 session 内容进内存的代码, 沿用 store.Get + StoredEntryFile 模式 - 文件缺失降级为空内容而非报错 (老 session 无文件) 服务端 (internal/server/server.go) - GET /api/sessions/{id}/diff?from=vN&to=vM: {id} 是链上任意 session - 返回 {fromVersion, toVersion, lines:[{kind,text,oldNo,newNo}], summary:{added,removed}} - 跨链/越界/from==to/缺参数 -> 400; 不存在/软删 -> 404 预览页注入 (internal/live/inject.go) - versionDrawer 每个 (有前驱的) 版本项加 "Show HTML diff" 按钮 - 点击懒加载 diff 接口, 红绿行内联展开 - 连续 equal 行折叠为 "⋯ N unchanged ⋯", 只保留改动行 - 前驱解析兼容软删空洞 (v1,v3 -> v3 diff vs v1) - 按钮旁显示 +a −b 摘要, 再点折叠 约束 - 不引入任何新依赖 (LCS 手写 ~60 行, 正面回应 version-chain Non-Goals 的"无 diff 库") - 不修改任何 DB schema (diff 纯计算, 结果不入库) - 现有 GET /chain 响应逐字段不变 (diff 走独立按需接口) - 老 session 文件缺失降级为空 diff OpenSpec: openspec/changes/html-content-diff/ (D19-D23, 修改 version-chain capability) 测试: go test ./... 全绿 (新增 ~30 个), go vet 无警告, openspec validate 通过, 端到端冒烟通过 (增删改行正确识别 + 预览页注入) --- internal/live/inject.go | 108 +++++++- internal/server/server.go | 149 +++++++++++ internal/server/server_test.go | 222 ++++++++++++++++ internal/session/htmldiff.go | 151 +++++++++++ internal/session/htmldiff_test.go | 250 ++++++++++++++++++ internal/session/version.go | 57 ++++ internal/session/version_test.go | 165 ++++++++++++ .../changes/html-content-diff/.openspec.yaml | 2 + openspec/changes/html-content-diff/design.md | 77 ++++++ .../changes/html-content-diff/proposal.md | 33 +++ .../specs/version-chain/spec.md | 79 ++++++ openspec/changes/html-content-diff/tasks.md | 35 +++ 12 files changed, 1326 insertions(+), 2 deletions(-) create mode 100644 internal/session/htmldiff.go create mode 100644 internal/session/htmldiff_test.go create mode 100644 openspec/changes/html-content-diff/.openspec.yaml create mode 100644 openspec/changes/html-content-diff/design.md create mode 100644 openspec/changes/html-content-diff/proposal.md create mode 100644 openspec/changes/html-content-diff/specs/version-chain/spec.md create mode 100644 openspec/changes/html-content-diff/tasks.md diff --git a/internal/live/inject.go b/internal/live/inject.go index 13152f2..134b950 100644 --- a/internal/live/inject.go +++ b/internal/live/inject.go @@ -170,6 +170,17 @@ const versionDrawerCSS = `` const versionDrawerHTML = ` @@ -239,12 +250,23 @@ const versionDrawerJS = `