fix(hashline-read-enhancer): support plain read output without content tags

🤖 Generated with assistance of [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
This commit is contained in:
YeonGyu-Kim
2026-02-21 03:33:26 +09:00
parent fb4530cafe
commit 6153a43c39
3 changed files with 51 additions and 8 deletions

View File

@@ -3208,6 +3208,9 @@
"disable_omo_env": {
"type": "boolean"
},
"hashline_edit": {
"type": "boolean"
},
"model_fallback_title": {
"type": "boolean"
}

View File

@@ -6,7 +6,7 @@ interface HashlineReadEnhancerConfig {
hashline_edit?: { enabled: boolean }
}
const READ_LINE_PATTERN = /^(\d+): (.*)$/
const READ_LINE_PATTERN = /^(\d+): ?(.*)$/
const CONTENT_OPEN_TAG = "<content>"
const CONTENT_CLOSE_TAG = "</content>"
@@ -47,25 +47,38 @@ function transformOutput(output: string): string {
const contentStart = lines.indexOf(CONTENT_OPEN_TAG)
const contentEnd = lines.indexOf(CONTENT_CLOSE_TAG)
if (contentStart === -1 || contentEnd === -1 || contentEnd <= contentStart + 1) {
return output
if (contentStart !== -1 && contentEnd !== -1 && contentEnd > contentStart + 1) {
const fileLines = lines.slice(contentStart + 1, contentEnd)
if (!isTextFile(fileLines[0] ?? "")) {
return output
}
const result: string[] = []
for (const line of fileLines) {
if (!READ_LINE_PATTERN.test(line)) {
result.push(...fileLines.slice(result.length))
break
}
result.push(transformLine(line))
}
return [...lines.slice(0, contentStart + 1), ...result, ...lines.slice(contentEnd)].join("\n")
}
const fileLines = lines.slice(contentStart + 1, contentEnd)
if (!isTextFile(fileLines[0] ?? "")) {
if (!isTextFile(lines[0] ?? "")) {
return output
}
const result: string[] = []
for (const line of fileLines) {
for (const line of lines) {
if (!READ_LINE_PATTERN.test(line)) {
result.push(...fileLines.slice(result.length))
result.push(...lines.slice(result.length))
break
}
result.push(transformLine(line))
}
return [...lines.slice(0, contentStart + 1), ...result, ...lines.slice(contentEnd)].join("\n")
return result.join("\n")
}
function extractFilePath(metadata: unknown): string | undefined {

View File

@@ -50,6 +50,33 @@ describe("hashline-read-enhancer", () => {
expect(lines[10]).toBe("1: keep this unchanged")
})
it("hashifies plain read output without content tags", async () => {
//#given
const hook = createHashlineReadEnhancerHook(mockCtx(), { hashline_edit: { enabled: true } })
const input = { tool: "read", sessionID: "s", callID: "c" }
const output = {
title: "README.md",
output: [
"1: # Oh-My-OpenCode Features",
"2:",
"3: Hashline test",
"",
"(End of file - total 3 lines)",
].join("\n"),
metadata: {},
}
//#when
await hook["tool.execute.after"](input, output)
//#then
const lines = output.output.split("\n")
expect(lines[0]).toMatch(/^1#[ZPMQVRWSNKTXJBYH]{2}:# Oh-My-OpenCode Features$/)
expect(lines[1]).toMatch(/^2#[ZPMQVRWSNKTXJBYH]{2}:$/)
expect(lines[2]).toMatch(/^3#[ZPMQVRWSNKTXJBYH]{2}:Hashline test$/)
expect(lines[4]).toBe("(End of file - total 3 lines)")
})
it("appends LINE#ID output for write tool using metadata filepath", async () => {
//#given
const hook = createHashlineReadEnhancerHook(mockCtx(), { hashline_edit: { enabled: true } })