From fb92babee7a4cb7ae7d1d32d1f24431ca07a8cc2 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Tue, 24 Feb 2026 15:31:43 +0900 Subject: [PATCH 1/5] refactor(hashline-edit): remove dead applyInsertBetween function This function is no longer called from edit-operations.ts after the op/pos/end/lines schema refactor in PR #2079. Remove the function definition and its 3 dedicated test cases. --- node_modules | 1 + .../edit-operation-primitives.ts | 26 ----------------- .../hashline-edit/edit-operations.test.ts | 28 +------------------ 3 files changed, 2 insertions(+), 53 deletions(-) create mode 120000 node_modules diff --git a/node_modules b/node_modules new file mode 120000 index 00000000..a930a206 --- /dev/null +++ b/node_modules @@ -0,0 +1 @@ +/Users/yeongyu/local-workspaces/oh-my-opencode/node_modules \ No newline at end of file diff --git a/src/tools/hashline-edit/edit-operation-primitives.ts b/src/tools/hashline-edit/edit-operation-primitives.ts index 43904011..43a23545 100644 --- a/src/tools/hashline-edit/edit-operation-primitives.ts +++ b/src/tools/hashline-edit/edit-operation-primitives.ts @@ -103,32 +103,6 @@ export function applyInsertBefore( return result } -export function applyInsertBetween( - lines: string[], - afterAnchor: string, - beforeAnchor: string, - text: string | string[], - options?: EditApplyOptions -): string[] { - if (shouldValidate(options)) { - validateLineRef(lines, afterAnchor) - validateLineRef(lines, beforeAnchor) - } - const { line: afterLine } = parseLineRef(afterAnchor) - const { line: beforeLine } = parseLineRef(beforeAnchor) - if (beforeLine <= afterLine) { - throw new Error(`insert_between requires after_line (${afterLine}) < before_line (${beforeLine})`) - } - - const result = [...lines] - const newLines = stripInsertBoundaryEcho(lines[afterLine - 1], lines[beforeLine - 1], toNewLines(text)) - if (newLines.length === 0) { - throw new Error(`insert_between requires non-empty text for ${afterAnchor}..${beforeAnchor}`) - } - result.splice(beforeLine - 1, 0, ...newLines) - return result -} - export function applyAppend(lines: string[], text: string | string[]): string[] { const normalized = toNewLines(text) if (normalized.length === 0) { diff --git a/src/tools/hashline-edit/edit-operations.test.ts b/src/tools/hashline-edit/edit-operations.test.ts index eb0adbaf..ce573da4 100644 --- a/src/tools/hashline-edit/edit-operations.test.ts +++ b/src/tools/hashline-edit/edit-operations.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "bun:test" import { applyHashlineEdits, applyInsertAfter, applyReplaceLines, applySetLine } from "./edit-operations" -import { applyAppend, applyInsertBetween, applyPrepend } from "./edit-operation-primitives" +import { applyAppend, applyPrepend } from "./edit-operation-primitives" import { computeLineHash } from "./hash-computation" import type { HashlineEdit } from "./types" @@ -56,16 +56,6 @@ describe("hashline edit operations", () => { expect(result).toEqual("line 1\nbefore 2\nline 2\nline 3") }) - it("applies insert_between with dual anchors", () => { - //#given - const lines = ["line 1", "line 2", "line 3"] - - //#when - const result = applyInsertBetween(lines, anchorFor(lines, 1), anchorFor(lines, 2), ["between"]).join("\n") - - //#then - expect(result).toEqual("line 1\nbetween\nline 2\nline 3") - }) it("throws when insert_after receives empty text array", () => { //#given @@ -85,13 +75,6 @@ describe("hashline edit operations", () => { ).toThrow(/non-empty/i) }) - it("throws when insert_between receives empty text array", () => { - //#given - const lines = ["line 1", "line 2"] - - //#when / #then - expect(() => applyInsertBetween(lines, anchorFor(lines, 1), anchorFor(lines, 2), [])).toThrow(/non-empty/i) - }) it("applies mixed edits in one pass", () => { //#given @@ -215,15 +198,6 @@ describe("hashline edit operations", () => { expect(result).toEqual(["before", "new 1", "new 2", "after"]) }) - it("throws when insert_between payload contains only boundary echoes", () => { - //#given - const lines = ["line 1", "line 2", "line 3"] - - //#when / #then - expect(() => applyInsertBetween(lines, anchorFor(lines, 1), anchorFor(lines, 2), ["line 1", "line 2"])).toThrow( - /non-empty/i - ) - }) it("restores indentation for first replace_lines entry", () => { //#given From d28ebd10c12443e02b021dfba44e8433b069a8d9 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Tue, 24 Feb 2026 15:32:24 +0900 Subject: [PATCH 2/5] refactor(hashline-edit): remove HASHLINE_LEGACY_REF_PATTERN and legacy ref compat Remove the old LINE:HEX (e.g. "42:ab") reference format support. All refs now use LINE#ID format exclusively (e.g. "42#VK"). Also fixes HASHLINE_OUTPUT_PATTERN to use | separator (was missed in PR #2079). --- src/tools/hashline-edit/constants.ts | 3 +- src/tools/hashline-edit/validation.test.ts | 43 ---------------------- src/tools/hashline-edit/validation.ts | 14 +------ 3 files changed, 3 insertions(+), 57 deletions(-) diff --git a/src/tools/hashline-edit/constants.ts b/src/tools/hashline-edit/constants.ts index 4ecf66c4..2eac4d9c 100644 --- a/src/tools/hashline-edit/constants.ts +++ b/src/tools/hashline-edit/constants.ts @@ -7,5 +7,4 @@ export const HASHLINE_DICT = Array.from({ length: 256 }, (_, i) => { }) export const HASHLINE_REF_PATTERN = /^([0-9]+)#([ZPMQVRWSNKTXJBYH]{2})$/ -export const HASHLINE_OUTPUT_PATTERN = /^([0-9]+)#([ZPMQVRWSNKTXJBYH]{2}):(.*)$/ -export const HASHLINE_LEGACY_REF_PATTERN = /^([0-9]+):([0-9a-fA-F]{2,})$/ +export const HASHLINE_OUTPUT_PATTERN = /^([0-9]+)#([ZPMQVRWSNKTXJBYH]{2})\|(.*)$/ diff --git a/src/tools/hashline-edit/validation.test.ts b/src/tools/hashline-edit/validation.test.ts index fc401cbf..cf2457ab 100644 --- a/src/tools/hashline-edit/validation.test.ts +++ b/src/tools/hashline-edit/validation.test.ts @@ -61,46 +61,3 @@ describe("validateLineRef", () => { .toThrow(/>>>\s+2#[ZPMQVRWSNKTXJBYH]{2}\|two/) }) }) - -describe("legacy LINE:HEX backward compatibility", () => { - it("parses legacy LINE:HEX ref", () => { - //#given - const ref = "42:ab" - - //#when - const result = parseLineRef(ref) - - //#then - expect(result).toEqual({ line: 42, hash: "ab" }) - }) - - it("parses legacy LINE:HEX ref with uppercase hex", () => { - //#given - const ref = "10:FF" - - //#when - const result = parseLineRef(ref) - - //#then - expect(result).toEqual({ line: 10, hash: "FF" }) - }) - - it("legacy ref fails validation with hash mismatch, not parse error", () => { - //#given - const lines = ["function hello() {"] - - //#when / #then - expect(() => validateLineRef(lines, "1:ab")).toThrow(/>>>\s+1#[ZPMQVRWSNKTXJBYH]{2}\|/) - }) - - it("extracts legacy ref from content with markers", () => { - //#given - const ref = ">>> 42:ab|const x = 1" - - //#when - const result = parseLineRef(ref) - - //#then - expect(result).toEqual({ line: 42, hash: "ab" }) - }) -}) diff --git a/src/tools/hashline-edit/validation.ts b/src/tools/hashline-edit/validation.ts index f81ccbaa..72a33286 100644 --- a/src/tools/hashline-edit/validation.ts +++ b/src/tools/hashline-edit/validation.ts @@ -1,5 +1,5 @@ import { computeLineHash } from "./hash-computation" -import { HASHLINE_REF_PATTERN, HASHLINE_LEGACY_REF_PATTERN } from "./constants" +import { HASHLINE_REF_PATTERN } from "./constants" export interface LineRef { line: number @@ -13,16 +13,13 @@ interface HashMismatch { const MISMATCH_CONTEXT = 2 -const LINE_REF_EXTRACT_PATTERN = /([0-9]+#[ZPMQVRWSNKTXJBYH]{2}|[0-9]+:[0-9a-fA-F]{2,})/ +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 } - if (HASHLINE_LEGACY_REF_PATTERN.test(trimmed)) { - return trimmed - } const extracted = trimmed.match(LINE_REF_EXTRACT_PATTERN) if (extracted) { @@ -41,13 +38,6 @@ export function parseLineRef(ref: string): LineRef { hash: match[2], } } - const legacyMatch = normalized.match(HASHLINE_LEGACY_REF_PATTERN) - if (legacyMatch) { - return { - line: Number.parseInt(legacyMatch[1], 10), - hash: legacyMatch[2], - } - } throw new Error( `Invalid line reference format: "${ref}". Expected format: "LINE#ID" (e.g., "42#VK")` ) From 9a2e0f1add9047c3ec86432ba32af15b9ef05527 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Tue, 24 Feb 2026 15:33:17 +0900 Subject: [PATCH 3/5] refactor(hashline-edit): remove unnecessary barrel re-exports of internal primitives MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit applySetLine, applyReplaceLines, applyInsertAfter, applyInsertBefore were re-exported from both edit-operations.ts and index.ts but have no external consumers — they are only used internally within the module. Only applyHashlineEdits (the public API) remains exported. --- src/tools/hashline-edit/edit-operations.test.ts | 4 ++-- src/tools/hashline-edit/edit-operations.ts | 6 ------ src/tools/hashline-edit/index.ts | 4 ---- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/tools/hashline-edit/edit-operations.test.ts b/src/tools/hashline-edit/edit-operations.test.ts index ce573da4..1940b9e4 100644 --- a/src/tools/hashline-edit/edit-operations.test.ts +++ b/src/tools/hashline-edit/edit-operations.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "bun:test" -import { applyHashlineEdits, applyInsertAfter, applyReplaceLines, applySetLine } from "./edit-operations" -import { applyAppend, applyPrepend } from "./edit-operation-primitives" +import { applyHashlineEdits } from "./edit-operations" +import { applyAppend, applyInsertAfter, applyPrepend, applyReplaceLines, applySetLine } from "./edit-operation-primitives" import { computeLineHash } from "./hash-computation" import type { HashlineEdit } from "./types" diff --git a/src/tools/hashline-edit/edit-operations.ts b/src/tools/hashline-edit/edit-operations.ts index 8558b51d..fae662d1 100644 --- a/src/tools/hashline-edit/edit-operations.ts +++ b/src/tools/hashline-edit/edit-operations.ts @@ -88,9 +88,3 @@ export function applyHashlineEdits(content: string, edits: HashlineEdit[]): stri return applyHashlineEditsWithReport(content, edits).content } -export { - applySetLine, - applyReplaceLines, - applyInsertAfter, - applyInsertBefore, -} from "./edit-operation-primitives" diff --git a/src/tools/hashline-edit/index.ts b/src/tools/hashline-edit/index.ts index 97a0ba7b..b38d63d3 100644 --- a/src/tools/hashline-edit/index.ts +++ b/src/tools/hashline-edit/index.ts @@ -16,9 +16,5 @@ export type { export { NIBBLE_STR, HASHLINE_DICT, HASHLINE_REF_PATTERN, HASHLINE_OUTPUT_PATTERN } from "./constants" export { applyHashlineEdits, - applyInsertAfter, - applyInsertBefore, - applyReplaceLines, - applySetLine, } from "./edit-operations" export { createHashlineEditTool } from "./tools" From 8c3a0ca2feb7f97c49a810c21192448830366358 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Tue, 24 Feb 2026 15:33:48 +0900 Subject: [PATCH 4/5] refactor(hashline-edit): rename legacy operation names in error messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update error messages to match current op schema: - insert_after → append (anchored) - insert_before → prepend (anchored) --- src/tools/hashline-edit/edit-operation-primitives.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/hashline-edit/edit-operation-primitives.ts b/src/tools/hashline-edit/edit-operation-primitives.ts index 43a23545..cd93e923 100644 --- a/src/tools/hashline-edit/edit-operation-primitives.ts +++ b/src/tools/hashline-edit/edit-operation-primitives.ts @@ -80,7 +80,7 @@ export function applyInsertAfter( const result = [...lines] const newLines = stripInsertAnchorEcho(lines[line - 1], toNewLines(text)) if (newLines.length === 0) { - throw new Error(`insert_after requires non-empty text for ${anchor}`) + throw new Error(`append (anchored) requires non-empty text for ${anchor}`) } result.splice(line, 0, ...newLines) return result @@ -97,7 +97,7 @@ export function applyInsertBefore( const result = [...lines] const newLines = stripInsertBeforeEcho(lines[line - 1], toNewLines(text)) if (newLines.length === 0) { - throw new Error(`insert_before requires non-empty text for ${anchor}`) + throw new Error(`prepend (anchored) requires non-empty text for ${anchor}`) } result.splice(line - 1, 0, ...newLines) return result From b03aae57f3d251cae0e8fed96090e6619316750c Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Tue, 24 Feb 2026 15:39:04 +0900 Subject: [PATCH 5/5] fix: remove accidentally committed node_modules symlink --- node_modules | 1 - 1 file changed, 1 deletion(-) delete mode 120000 node_modules diff --git a/node_modules b/node_modules deleted file mode 120000 index a930a206..00000000 --- a/node_modules +++ /dev/null @@ -1 +0,0 @@ -/Users/yeongyu/local-workspaces/oh-my-opencode/node_modules \ No newline at end of file