mirror of
https://github.com/stablyai/orca.git
synced 2026-10-22 00:03:47 +00:00
Three follow-ups from review of the WSL Codex transcript fix: - The UNC translation was retried on every fast resolve-poll tick (measured 10 sync UNC stats per 100ms) because only a successful result was memoized. Gate the retry to the slow fallback cadence. - A non-empty WSL home list was cached for the process lifetime, so a distro that was still booting during the first probe stayed excluded forever. Expire both branches; getWslHomeAsync caches successes, so a refresh only re-spawns wsl.exe for the distros that actually failed. - codexSessionsDirs enumerated every distro's home eagerly, waking distros the user left stopped even for native-Windows panes. Make the WSL roots a lazy tier consulted only after the host's own Codex roots miss. The resolve-poll suite became platform-dependent and only passed off Windows; pin the platform and add explicit win32 coverage.
187 lines
6.7 KiB
TypeScript
187 lines
6.7 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
import {
|
|
isGuestAbsoluteLinuxPath,
|
|
needsWslHostTranslation,
|
|
resetHostReadableTranscriptPathCacheForTests,
|
|
toHostReadableTranscriptPath,
|
|
wslCodexSessionsDirs
|
|
} from './host-readable-transcript-path'
|
|
|
|
const UBUNTU_HOME = '\\\\wsl.localhost\\Ubuntu\\home\\ada'
|
|
const DEBIAN_HOME = '\\\\wsl.localhost\\Debian\\home\\other'
|
|
const ROLLOUT_LINUX =
|
|
'/home/ada/.local/share/orca/codex-runtime-home/home/sessions/2026/07/24/rollout-sess.jsonl'
|
|
const ROLLOUT_UNC =
|
|
'\\\\wsl.localhost\\Ubuntu\\home\\ada\\.local\\share\\orca\\codex-runtime-home\\home\\sessions\\2026\\07\\24\\rollout-sess.jsonl'
|
|
|
|
beforeEach(() => {
|
|
resetHostReadableTranscriptPathCacheForTests()
|
|
})
|
|
|
|
describe('isGuestAbsoluteLinuxPath', () => {
|
|
it('accepts absolute POSIX guest paths', () => {
|
|
expect(isGuestAbsoluteLinuxPath('/home/ada/.codex/sessions/rollout.jsonl')).toBe(true)
|
|
})
|
|
|
|
it('rejects UNC, relative, and drive-letter forms', () => {
|
|
expect(isGuestAbsoluteLinuxPath('\\\\wsl.localhost\\Ubuntu\\home\\ada\\x.jsonl')).toBe(false)
|
|
expect(isGuestAbsoluteLinuxPath('//wsl.localhost/Ubuntu/home/ada/x.jsonl')).toBe(false)
|
|
expect(isGuestAbsoluteLinuxPath('relative/path.jsonl')).toBe(false)
|
|
expect(isGuestAbsoluteLinuxPath('C:\\Users\\ada\\x.jsonl')).toBe(false)
|
|
expect(isGuestAbsoluteLinuxPath('/C:/Users/ada/x.jsonl')).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('needsWslHostTranslation', () => {
|
|
it('is win32-only', () => {
|
|
expect(needsWslHostTranslation(ROLLOUT_LINUX, 'win32')).toBe(true)
|
|
expect(needsWslHostTranslation(ROLLOUT_LINUX, 'darwin')).toBe(false)
|
|
expect(needsWslHostTranslation(ROLLOUT_UNC, 'win32')).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('toHostReadableTranscriptPath', () => {
|
|
it('translates a WSL guest path to its UNC twin on Windows (#10326)', async () => {
|
|
await expect(
|
|
toHostReadableTranscriptPath(ROLLOUT_LINUX, {
|
|
platform: 'win32',
|
|
pathExists: (candidate) => candidate === ROLLOUT_UNC,
|
|
listWslHomeDirs: async () => [UBUNTU_HOME]
|
|
})
|
|
).resolves.toBe(ROLLOUT_UNC)
|
|
})
|
|
|
|
it('never probes the bare guest path on Windows', async () => {
|
|
// Why: Win32 resolves `/home/...` against the current drive (`C:\home\...`),
|
|
// so probing first could bind chat to a local look-alike file.
|
|
const seen: string[] = []
|
|
await expect(
|
|
toHostReadableTranscriptPath('/home/ada/x.jsonl', {
|
|
platform: 'win32',
|
|
pathExists: (candidate) => {
|
|
seen.push(candidate)
|
|
return true
|
|
},
|
|
listWslHomeDirs: async () => [UBUNTU_HOME]
|
|
})
|
|
).resolves.toBe('\\\\wsl.localhost\\Ubuntu\\home\\ada\\x.jsonl')
|
|
expect(seen).not.toContain('/home/ada/x.jsonl')
|
|
})
|
|
|
|
it('leaves drive-letter and UNC paths untranslated', async () => {
|
|
const existing = ['C:/home/ada/x.jsonl', ROLLOUT_UNC]
|
|
for (const path of existing) {
|
|
await expect(
|
|
toHostReadableTranscriptPath(path, {
|
|
platform: 'win32',
|
|
pathExists: (candidate) => candidate === path,
|
|
listWslHomeDirs: async () => {
|
|
throw new Error('should not enumerate distros')
|
|
}
|
|
})
|
|
).resolves.toBe(path)
|
|
}
|
|
})
|
|
|
|
it('tries the distro whose $HOME prefixes the guest path first', async () => {
|
|
const seen: string[] = []
|
|
await expect(
|
|
toHostReadableTranscriptPath('/home/ada/.codex/sessions/rollout.jsonl', {
|
|
platform: 'win32',
|
|
pathExists: (candidate) => {
|
|
seen.push(candidate)
|
|
return true
|
|
},
|
|
listWslHomeDirs: async () => [DEBIAN_HOME, UBUNTU_HOME]
|
|
})
|
|
).resolves.toBe('\\\\wsl.localhost\\Ubuntu\\home\\ada\\.codex\\sessions\\rollout.jsonl')
|
|
expect(seen).toHaveLength(1)
|
|
})
|
|
|
|
it('returns null when no distro maps to an existing file', async () => {
|
|
await expect(
|
|
toHostReadableTranscriptPath(ROLLOUT_LINUX, {
|
|
platform: 'win32',
|
|
pathExists: () => false,
|
|
listWslHomeDirs: async () => [UBUNTU_HOME]
|
|
})
|
|
).resolves.toBeNull()
|
|
})
|
|
|
|
it('does not translate guest paths off Windows', async () => {
|
|
await expect(
|
|
toHostReadableTranscriptPath('/home/ada/rollout.jsonl', {
|
|
platform: 'darwin',
|
|
pathExists: (candidate) => candidate === '/home/ada/rollout.jsonl',
|
|
listWslHomeDirs: async () => {
|
|
throw new Error('should not enumerate distros')
|
|
}
|
|
})
|
|
).resolves.toBe('/home/ada/rollout.jsonl')
|
|
})
|
|
|
|
it('enumerates WSL homes once across repeated resolve-poll ticks', async () => {
|
|
// Why: getWslHomeAsync does not cache failures; re-spawning wsl.exe on every
|
|
// 500ms poll tick would hammer the main process.
|
|
const listWslHomeDirs = vi.fn(async () => [UBUNTU_HOME])
|
|
for (let tick = 0; tick < 5; tick += 1) {
|
|
await toHostReadableTranscriptPath(ROLLOUT_LINUX, {
|
|
platform: 'win32',
|
|
pathExists: () => false,
|
|
listWslHomeDirs
|
|
})
|
|
}
|
|
await wslCodexSessionsDirs({ platform: 'win32', listWslHomeDirs })
|
|
expect(listWslHomeDirs).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('re-probes after the TTL so a distro that was booting is not excluded forever', async () => {
|
|
// Why: getWslHomeAsync returns null for a distro whose 5s $HOME probe timed
|
|
// out on a cold boot. Latching that partial list for the process lifetime
|
|
// would leave that distro's transcripts permanently unresolvable (#10326).
|
|
vi.useFakeTimers()
|
|
try {
|
|
const listWslHomeDirs = vi
|
|
.fn<() => Promise<string[]>>()
|
|
.mockResolvedValueOnce([UBUNTU_HOME])
|
|
.mockResolvedValue([UBUNTU_HOME, DEBIAN_HOME])
|
|
|
|
const debianRollout = '\\\\wsl.localhost\\Debian\\home\\other\\x.jsonl'
|
|
const call = (): Promise<string | null> =>
|
|
toHostReadableTranscriptPath('/home/other/x.jsonl', {
|
|
platform: 'win32',
|
|
pathExists: (candidate) => candidate === debianRollout,
|
|
listWslHomeDirs
|
|
})
|
|
|
|
await expect(call()).resolves.toBeNull()
|
|
await expect(call()).resolves.toBeNull()
|
|
expect(listWslHomeDirs).toHaveBeenCalledTimes(1)
|
|
|
|
vi.setSystemTime(Date.now() + 6 * 60_000)
|
|
await expect(call()).resolves.toBe(debianRollout)
|
|
expect(listWslHomeDirs).toHaveBeenCalledTimes(2)
|
|
} finally {
|
|
vi.useRealTimers()
|
|
}
|
|
})
|
|
})
|
|
|
|
describe('wslCodexSessionsDirs', () => {
|
|
it('returns nothing off Windows', async () => {
|
|
await expect(
|
|
wslCodexSessionsDirs({ platform: 'darwin', listWslHomeDirs: async () => [UBUNTU_HOME] })
|
|
).resolves.toEqual([])
|
|
})
|
|
|
|
it('lists the managed and system Codex roots per distro home', async () => {
|
|
await expect(
|
|
wslCodexSessionsDirs({ platform: 'win32', listWslHomeDirs: async () => [UBUNTU_HOME] })
|
|
).resolves.toEqual([
|
|
`${UBUNTU_HOME}\\.local\\share\\orca\\codex-runtime-home\\home\\sessions`,
|
|
`${UBUNTU_HOME}\\.codex\\sessions`
|
|
])
|
|
})
|
|
})
|