mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-16 13:03:31 +08:00
Normalize realpath results for Windows drive roots so D:\ does not round-trip to drive-relative D: and resolve back into the current repository. Also tighten Sidebar hidden-project matching so a drive root does not match every child project on the same drive. Tested: bun test src/server/__tests__/windows-drive-path.test.ts src/server/__tests__/sessions.test.ts src/server/__tests__/workspace-service.test.ts Tested: cd desktop && bun run test -- --run src/components/layout/Sidebar.test.tsx Tested: cd desktop && bun run build:windows-x64 Tested: bun run check:desktop Not-tested: bun run check:server (failed on existing/environment failures including the pre-existing untracked FileReadTool test) Confidence: high Scope-risk: narrow
78 lines
3.3 KiB
TypeScript
78 lines
3.3 KiB
TypeScript
import { describe, expect, it } from 'bun:test'
|
|
import * as fs from 'node:fs/promises'
|
|
import * as os from 'node:os'
|
|
import * as path from 'node:path'
|
|
import {
|
|
isSameOrInsidePathForPlatform,
|
|
normalizeDriveRootPathForPlatform,
|
|
} from '../services/windowsDrivePath.js'
|
|
import { getRepositoryContext } from '../services/repositoryLaunchService.js'
|
|
import { SessionService } from '../services/sessionService.js'
|
|
import { sanitizePath } from '../../utils/sessionStoragePortable.js'
|
|
|
|
describe('Windows drive root path handling', () => {
|
|
it('normalizes drive-relative root inputs to absolute drive roots on Windows', () => {
|
|
expect(normalizeDriveRootPathForPlatform('D:', 'win32')).toBe('D:\\')
|
|
expect(normalizeDriveRootPathForPlatform('d:', 'win32')).toBe('d:\\')
|
|
expect(normalizeDriveRootPathForPlatform('D:\\', 'win32')).toBe('D:\\')
|
|
expect(normalizeDriveRootPathForPlatform('D:\\project', 'win32')).toBe('D:\\project')
|
|
expect(normalizeDriveRootPathForPlatform('D:', 'darwin')).toBe('D:')
|
|
})
|
|
|
|
it('recovers sanitized Windows drive-root transcript directories', () => {
|
|
const service = new SessionService()
|
|
expect(service.desanitizePath('D--')).toBe('D:\\')
|
|
expect(service.desanitizePath('D--project')).toBe('D:\\project')
|
|
})
|
|
|
|
it('treats absolute Windows drive-root children as inside the selected root', () => {
|
|
expect(isSameOrInsidePathForPlatform('D:\\', 'D:', 'win32')).toBe(true)
|
|
expect(isSameOrInsidePathForPlatform('D:\\child', 'D:', 'win32')).toBe(true)
|
|
expect(isSameOrInsidePathForPlatform('D:\\child', 'D:\\', 'win32')).toBe(true)
|
|
expect(isSameOrInsidePathForPlatform('D:\\project-extra', 'D:\\project', 'win32')).toBe(false)
|
|
expect(isSameOrInsidePathForPlatform('E:\\child', 'D:\\', 'win32')).toBe(false)
|
|
})
|
|
|
|
it('keeps realpathed drive roots from resolving to the current drive directory', async () => {
|
|
if (process.platform !== 'win32') return
|
|
|
|
const originalConfigDir = process.env.CLAUDE_CONFIG_DIR
|
|
const configDir = await fs.mkdtemp(path.join(os.tmpdir(), 'drive-root-session-'))
|
|
const driveRoot = path.parse(process.cwd()).root
|
|
const sessionId = crypto.randomUUID()
|
|
|
|
try {
|
|
process.env.CLAUDE_CONFIG_DIR = configDir
|
|
const projectDir = path.join(configDir, 'projects', sanitizePath(driveRoot))
|
|
await fs.mkdir(projectDir, { recursive: true })
|
|
await fs.writeFile(
|
|
path.join(projectDir, `${sessionId}.jsonl`),
|
|
JSON.stringify({
|
|
type: 'session-meta',
|
|
isMeta: true,
|
|
workDir: driveRoot,
|
|
timestamp: new Date().toISOString(),
|
|
}) + '\n',
|
|
'utf-8',
|
|
)
|
|
|
|
const service = new SessionService()
|
|
const { sessions } = await service.listSessions({ limit: 5 })
|
|
const session = sessions.find((item) => item.id === sessionId)
|
|
expect(session?.workDir).toBe(driveRoot)
|
|
expect(session?.projectRoot).toBe(driveRoot)
|
|
|
|
const context = await getRepositoryContext(driveRoot)
|
|
expect(context.workDir).toBe(driveRoot)
|
|
expect(context.repoRoot).not.toBe(process.cwd())
|
|
} finally {
|
|
if (originalConfigDir === undefined) {
|
|
delete process.env.CLAUDE_CONFIG_DIR
|
|
} else {
|
|
process.env.CLAUDE_CONFIG_DIR = originalConfigDir
|
|
}
|
|
await fs.rm(configDir, { recursive: true, force: true })
|
|
}
|
|
})
|
|
})
|