diff --git a/src/services/acp/bridge/paths.ts b/src/services/acp/bridge/paths.ts index fb04ef3d8..95bcd5a23 100644 --- a/src/services/acp/bridge/paths.ts +++ b/src/services/acp/bridge/paths.ts @@ -1,5 +1,12 @@ // Pure path-normalisation helper used by toolInfo / toolResults / forwarding. -import { isAbsolute, resolve } from 'node:path' +// +// POSIX semantics are used so that emitted paths are platform-independent: +// ACP v1 spec (tool-calls.mdx:304-306) requires ToolCallLocation.path / +// Diff.path to be absolute, and the wire format is POSIX-style regardless of +// the host OS. Using the platform-specific `node:path` here would prepend the +// Windows drive letter (e.g. "D:\...") to POSIX-style inputs like +// "/Users/test/project" — silently corrupting paths emitted to ACP clients. +import { isAbsolute, resolve } from 'node:path/posix' /** * Normalises an emitted file path against the session cwd so that diff --git a/src/services/acp/utils.ts b/src/services/acp/utils.ts index 9e7ab92df..47979d089 100644 --- a/src/services/acp/utils.ts +++ b/src/services/acp/utils.ts @@ -172,7 +172,9 @@ export function sanitizeTitle(text: string): string { // ── Path display helpers ────────────────────────────────────────── -import * as path from 'node:path' +// POSIX semantics so paths are normalised consistently regardless of host OS. +// ACP paths are always POSIX-style (see bridge/paths.ts for the same rationale). +import * as path from 'node:path/posix' /** * Convert an absolute file path to a project-relative path for display. @@ -186,7 +188,7 @@ export function toDisplayPath(filePath: string, cwd?: string): string { resolvedFile.startsWith(resolvedCwd + path.sep) || resolvedFile === resolvedCwd ) { - return path.relative(resolvedCwd, resolvedFile).replaceAll('\\', '/') + return path.relative(resolvedCwd, resolvedFile) } return filePath }