mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
fix(native-chat): resolve /D:/ chat file links to the drive in Windows workspaces (#34367)
In a drive-letter workspace, strip the leading slash from URL-style /X:/ file hrefs before resolving, so links like /D:/Temp/report.txt open D:/Temp/report.txt. POSIX, WSL UNC, and UNC hrefs are unchanged. Fixes #34310
This commit is contained in:
@@ -299,4 +299,25 @@ describe('resolveNativeChatFileLink', () => {
|
||||
it('ignores http links so normal markdown navigation can handle them', () => {
|
||||
expect(resolveNativeChatFileLink('https://example.com/docs/guide.md', context)).toBeNull()
|
||||
})
|
||||
|
||||
it('reads URL-style /D:/ targets as the drive only in a Windows workspace', () => {
|
||||
const windowsContext = { ...context, worktreePath: 'D:/repo' }
|
||||
for (const href of ['/D:/Temp/report.txt', createNativeChatFileHref('/D:/Temp/report.txt')]) {
|
||||
expect(resolveNativeChatFileLink(href, windowsContext)?.absolutePath).toBe(
|
||||
'D:/Temp/report.txt'
|
||||
)
|
||||
}
|
||||
expect(
|
||||
resolveNativeChatFileLink(
|
||||
createNativeChatFileHref('/D:/Temp/report.txt', 'literal'),
|
||||
windowsContext
|
||||
)?.absolutePath
|
||||
).toBe('D:/Temp/report.txt')
|
||||
expect(
|
||||
resolveNativeChatFileLink('//server/share/report.txt', windowsContext)?.absolutePath
|
||||
).toBe('//server/share/report.txt')
|
||||
expect(resolveNativeChatFileLink('/D:/Temp/report.txt', context)?.absolutePath).toBe(
|
||||
'/D:/Temp/report.txt'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import { chatWorkspaceByTabId } from '@/lib/structured-chat-tab-index'
|
||||
import { routeNativeChatHref } from '../../../../shared/native-chat-href-routing'
|
||||
import {
|
||||
routeNativeChatHref,
|
||||
type NativeChatHrefRoute
|
||||
} from '../../../../shared/native-chat-href-routing'
|
||||
import { WINDOWS_DRIVE_PATH_PREFIX } from '../../../../shared/file-uri-path'
|
||||
import { normalizeAbsolutePath } from '../../../../shared/terminal-path-normalization'
|
||||
import {
|
||||
parseExplicitFileLinkTarget,
|
||||
resolveExplicitFileLinkTarget,
|
||||
@@ -130,6 +135,19 @@ function resolvePathText(
|
||||
}
|
||||
}
|
||||
|
||||
// Chats open a drive-letter workspace as native Windows (no WSL mapping), so URL-style /D:/… there is D:.
|
||||
function routeNativeChatFileHref(
|
||||
href: string | undefined,
|
||||
worktreePath: string
|
||||
): NativeChatHrefRoute {
|
||||
const route = routeNativeChatHref(href)
|
||||
return route.kind === 'file' &&
|
||||
WINDOWS_DRIVE_PATH_PREFIX.test(route.pathText) &&
|
||||
normalizeAbsolutePath(worktreePath)?.rootKind === 'windows'
|
||||
? { ...route, pathText: route.pathText.slice(1) }
|
||||
: route
|
||||
}
|
||||
|
||||
export function resolveNativeChatFileLink(
|
||||
href: string | undefined,
|
||||
context: NativeChatFileLinkContext | null
|
||||
@@ -137,7 +155,7 @@ export function resolveNativeChatFileLink(
|
||||
if (!context) {
|
||||
return null
|
||||
}
|
||||
const route = routeNativeChatHref(href)
|
||||
const route = routeNativeChatFileHref(href, context.worktreePath)
|
||||
if (route.kind !== 'file') {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const WINDOWS_DRIVE_PATH_PREFIX = /^\/[A-Za-z]:\//
|
||||
export const WINDOWS_DRIVE_PATH_PREFIX = /^\/[A-Za-z]:\//
|
||||
const UNC_PATH_PREFIX = /^(?:\\\\|\/\/)([^\\/]+)[\\/]+([^\\/]+)(?:[\\/](.*))?$/
|
||||
|
||||
function encodePathSegments(path: string): string {
|
||||
|
||||
Reference in New Issue
Block a user