From fe188f87224200f67fd76c7a587b4fba65afd58c Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Fri, 28 Aug 2026 13:29:41 -0400 Subject: [PATCH] fix(core): normalize directory page headings (#45641) --- .changeset/directory-page-heading.md | 5 ++++ packages/core/src/tool/plugin/read.ts | 2 +- packages/core/test/tool-read.test.ts | 34 +++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 .changeset/directory-page-heading.md diff --git a/.changeset/directory-page-heading.md b/.changeset/directory-page-heading.md new file mode 100644 index 00000000000..f23be6e7d76 --- /dev/null +++ b/.changeset/directory-page-heading.md @@ -0,0 +1,5 @@ +--- +"@opencode-ai/core": patch +--- + +Correct directory page headings when the read offset is zero. diff --git a/packages/core/src/tool/plugin/read.ts b/packages/core/src/tool/plugin/read.ts index ea1643fe564..ee4d488c61b 100644 --- a/packages/core/src/tool/plugin/read.ts +++ b/packages/core/src/tool/plugin/read.ts @@ -169,7 +169,7 @@ export const toModelContent = (path: string, offset: number | undefined, output: ] as const if (output.type === "list-page") { - const start = offset ?? 1 + const start = offset || 1 const content = [ output.entries.length === 0 ? `Read directory ${path}, 0 entries` diff --git a/packages/core/test/tool-read.test.ts b/packages/core/test/tool-read.test.ts index 107b62ea319..391129672fa 100644 --- a/packages/core/test/tool-read.test.ts +++ b/packages/core/test/tool-read.test.ts @@ -678,6 +678,40 @@ describe("ReadTool", () => { }), ) + it.effect("normalizes a zero directory offset in the model heading", () => + Effect.gen(function* () { + readResult = new ReadToolFileSystem.ListPage({ + type: "list-page", + entries: [FileSystem.Entry.make({ path: RelativePath.make("index.ts"), type: "file" })], + truncated: true, + next: 2, + }) + const registry = yield* Tool.Service + + const result = yield* executeTool(registry, { + sessionID, + ...toolIdentity, + call: { + type: "tool-call", + id: "call-read-directory-zero", + name: "read", + input: { path: "src", offset: 0, limit: 1 }, + }, + }) + expect(result.status).toBe("completed") + if (result.status !== "completed") return + expect(result.content).toEqual([ + { + type: "text", + text: "Read directory src, entries 1-1\nindex.ts\n[Output truncated. Continue reading with offset: 2]", + }, + ]) + expect(readCalls).toEqual([ + { input: AbsolutePath.make(path.join(process.cwd(), "src")), page: { offset: 0, limit: 1 } }, + ]) + }), + ) + it.effect("does not list a directory when permission is denied", () => Effect.gen(function* () { allow = false