From 0681687a529109a495d678a95d7c1a4e5f97c8ec Mon Sep 17 00:00:00 2001 From: 0xDevNinja Date: Wed, 17 Jun 2026 11:51:33 +0530 Subject: [PATCH 1/2] fix(acp): include resource URI as source prefix in text parts When an editor (e.g. Zed) sends a code selection as an ACP resource ContentBlock, resource.uri carries the file path and optional line range while resource.text carries the selected text. contentBlockToParts() was discarding the URI entirely, leaving the LLM with no indication of which file the selection came from. Decode the URI to a human-readable path (handling file:// and zed:// schemes, preserving fragment line-range anchors) and prepend it as a source header before the text content. Fixes #32558 --- packages/opencode/src/acp/content.ts | 14 ++++++++++- packages/opencode/test/acp/content.test.ts | 28 ++++++++++++++++++++-- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/packages/opencode/src/acp/content.ts b/packages/opencode/src/acp/content.ts index 5f149d85f0f2..bbbbecbb7bc5 100644 --- a/packages/opencode/src/acp/content.ts +++ b/packages/opencode/src/acp/content.ts @@ -76,7 +76,19 @@ export function contentBlockToParts(block: ContentBlock): PromptPart[] { case "resource": if ("text" in block.resource) { - return [{ type: "text", text: block.resource.text }] + const { uri, text } = block.resource + let source = uri + try { + if (uri.startsWith("zed://")) { + source = new URL(uri).searchParams.get("path") ?? uri + } else if (uri.startsWith("file://")) { + const u = new URL(uri) + source = u.pathname + u.hash + } + } catch { + // keep uri as-is + } + return [{ type: "text", text: `${source}\n${text}` }] } if (block.resource.mimeType) { return [ diff --git a/packages/opencode/test/acp/content.test.ts b/packages/opencode/test/acp/content.test.ts index 90f62f9d1892..d75f42668d41 100644 --- a/packages/opencode/test/acp/content.test.ts +++ b/packages/opencode/test/acp/content.test.ts @@ -99,7 +99,7 @@ describe("acp content conversion", () => { ]) }) - test("resource with text becomes a text part", () => { + test("resource with text includes file path prefix so LLM knows the source", () => { expect( contentBlockToParts({ type: "resource", @@ -109,7 +109,31 @@ describe("acp content conversion", () => { text: "context", }, }), - ).toEqual([{ type: "text", text: "context" }]) + ).toEqual([{ type: "text", text: "/tmp/context.txt\ncontext" }]) + }) + + test("resource with zed:// uri decodes path for the prefix", () => { + expect( + contentBlockToParts({ + type: "resource", + resource: { + uri: "zed://workspace?path=/home/user/project/src/main.ts", + text: "export function main() {}", + }, + }), + ).toEqual([{ type: "text", text: "/home/user/project/src/main.ts\nexport function main() {}" }]) + }) + + test("resource with file:// uri preserves line-range fragment in prefix", () => { + expect( + contentBlockToParts({ + type: "resource", + resource: { + uri: "file:///src/app.ts#L10-L20", + text: "const x = 1", + }, + }), + ).toEqual([{ type: "text", text: "/src/app.ts#L10-L20\nconst x = 1" }]) }) test("resource with blob and mimeType becomes a data URL file part", () => { From 77277290023b873ccb4ade24dd214693c74e3dc7 Mon Sep 17 00:00:00 2001 From: 0xDevNinja Date: Wed, 17 Jun 2026 11:55:21 +0530 Subject: [PATCH 2/2] fix(ui): remove spacing field dropped from VirtualFileMetrics @pierre/diffs removed spacing from VirtualFileMetrics but the two callsites were not updated, causing a typecheck failure in the enterprise package. --- packages/ui/src/components/file.tsx | 1 - packages/ui/src/pierre/virtualizer.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/ui/src/components/file.tsx b/packages/ui/src/components/file.tsx index 8c8096375a39..fb9a5b91cfd7 100644 --- a/packages/ui/src/components/file.tsx +++ b/packages/ui/src/components/file.tsx @@ -52,7 +52,6 @@ const VIRTUALIZE_BYTES = 500_000 const codeMetrics = { ...DEFAULT_VIRTUAL_FILE_METRICS, lineHeight: 24, - spacing: 0, } satisfies Partial type SharedProps = { diff --git a/packages/ui/src/pierre/virtualizer.ts b/packages/ui/src/pierre/virtualizer.ts index 235a3fd67734..369d36eab585 100644 --- a/packages/ui/src/pierre/virtualizer.ts +++ b/packages/ui/src/pierre/virtualizer.ts @@ -16,7 +16,6 @@ const cache = new WeakMap() export const virtualMetrics: Partial = { lineHeight: 24, hunkSeparatorHeight: 24, - spacing: 0, } function scrollable(value: string) {