fix(hashline): add autocorrect, batch mismatch reporting, and write anchors

This commit is contained in:
YeonGyu-Kim
2026-02-20 11:02:07 +09:00
parent f3e6cab2f8
commit 40dccd6118
8 changed files with 518 additions and 1168 deletions
+45 -2
View File
@@ -1,15 +1,33 @@
import { computeLineHash } from "./hash-computation"
import { HASHLINE_REF_PATTERN } from "./constants"
export interface LineRef {
line: number
hash: string
}
const LINE_REF_EXTRACT_PATTERN = /([0-9]+#[ZPMQVRWSNKTXJBYH]{2})/
function normalizeLineRef(ref: string): string {
const trimmed = ref.trim()
if (HASHLINE_REF_PATTERN.test(trimmed)) {
return trimmed
}
const extracted = trimmed.match(LINE_REF_EXTRACT_PATTERN)
if (extracted) {
return extracted[1]
}
return trimmed
}
export function parseLineRef(ref: string): LineRef {
const match = ref.match(/^(\d+):([0-9a-f]{2})$/)
const normalized = normalizeLineRef(ref)
const match = normalized.match(HASHLINE_REF_PATTERN)
if (!match) {
throw new Error(
`Invalid line reference format: "${ref}". Expected format: "LINE:HASH" (e.g., "42:a3")`
`Invalid line reference format: "${ref}". Expected format: "LINE#ID" (e.g., "42#VK")`
)
}
return {
@@ -37,3 +55,28 @@ export function validateLineRef(lines: string[], ref: string): void {
)
}
}
export function validateLineRefs(lines: string[], refs: string[]): void {
const mismatches: string[] = []
for (const ref of refs) {
const { line, hash } = parseLineRef(ref)
if (line < 1 || line > lines.length) {
mismatches.push(`Line number ${line} out of bounds (file has ${lines.length} lines)`)
continue
}
const content = lines[line - 1]
const currentHash = computeLineHash(line, content)
if (currentHash !== hash) {
mismatches.push(
`line ${line}: expected ${hash}, current ${currentHash} (${line}#${currentHash}) content: "${content}"`
)
}
}
if (mismatches.length > 0) {
throw new Error(`Hash mismatches:\n- ${mismatches.join("\n- ")}`)
}
}