2026-07-14 Hashline Edit Extension

Hashline:用内容锚点,而不是脆弱行号,改代码

默认编辑从「猜行号」变成「凭读过的版本改」:更少静默写错,代价是偶发 re-read。

导语

装上 @piex-dev/hashline 后,默认编辑从「猜行号」变成「凭读过的版本改」:更少静默写错,代价是偶发 re-read。这是值得付的税。

问题背景

AI 编码助手的 edit 工具有一个根本矛盾:模型用行号描述改哪里,但行号在真实世界里极不稳定。用户随手改文件、上一轮 edit 插入删除、未读全文件却对「以为存在」的行号下手,都会造成静默写错。

@piex-dev/hashline 用内容锚点覆盖 pi 内置 edit:读时打 tag、改时校验,拒绝未见过的行。

技术原理

读文件时注入 [path#TAG] 并记录 seen-lines;编辑必须携带同一 tag。全文件 4-hex tag 像乐观锁:任意外部改动即失效,强制 re-read。相对逐行哈希更严,但换来 tree-sitter 块操作与 boundary repair。

hashline
[src/main.ts#A3F2]
SWAP 2.=2:
+const x = 2;

Phase 1 容错:连续 3 次 byte-identical noop → [E_NOOP_LOOP];成功后同 payload 且文件未变 → [E_DUPLICATE_EDIT];CRLF / 代码块围栏等方言归一化。

实现方案

封装 @oh-my-pi/hashlinehashline.ts 覆盖 edit 并 hook read;PiexNodeFilesystem 直连 node:fs + realpath;EditGuard 管 noop/duplicate;Bun polyfill 只补 xxHash32

能力状态
tree-sitter block / REM·MV✅ 继承引擎
Noop / Duplicate / 归一化✅ Phase 1
Stale 自动恢复 / 多版本快照❌ 待 Phase 2

设计参考

项目机制piex 取舍
oh-my-pi hashline全文件 tag + tree-sitter 块语法 + boundary repair 引擎采纳:封装 @oh-my-pi/hashline,继承 tag、SWAP.BLK、REM/MV 与引擎。不采纳:内建集成、Bun FS、LSP writethrough;改为 Node + 外层 EditGuard
pi-hashline-edit逐行上下文哈希 + 3-way merge 恢复 + JSON DSL不采纳核心算法(路线分歧),借鉴容错意图(noop/dup guard)。ADR 留作 Phase 2 Stale 恢复参考
pi-hashline-edit-pro逐行内容哈希 + stable mapping不采纳算法,借鉴「尽量少 re-read」作为远期目标

核心取舍:选择整体文件 tag(严格简单),放弃逐行 tag(局部可用),用封装层补容错。三个阶段:Phase 1 容错(done)→ Phase 2 恢复 → Phase 3 undo/LSP 联动。

优化计划

冲突策略偏拒绝(安全但贵)→ 接 3-way merge / Recovery;快照偏薄 → 多版本 LRU + 锚点 Grep;duplicate 按 section 细化;封装层单测与可选 LSP 联动。

Phase 1 已完成;Phase 2 可靠性;Phase 3 体验(Undo / Auto-Read / 测试网)。

附录:实现对比

行业三条路线:oh-my-pi 全文件 tag、pi-hashline-edit 上下文逐行哈希、pi-hashline-edit-pro stable mapping。piex 选前者做引擎,容错借鉴后者。完整对照见源稿。