cachePaths.ts
1 import envPaths from 'env-paths' 2 import { join } from 'path' 3 import { getFsImplementation } from './fsOperations.js' 4 import { djb2Hash } from './hash.js' 5 6 const paths = envPaths('claude-cli') 7 8 // Local sanitizePath using djb2Hash — NOT the shared version from 9 // sessionStoragePortable.ts which uses Bun.hash (wyhash) when available. 10 // Cache directory names must remain stable across upgrades so existing cache 11 // data (error logs, MCP logs) is not orphaned. 12 const MAX_SANITIZED_LENGTH = 200 13 function sanitizePath(name: string): string { 14 const sanitized = name.replace(/[^a-zA-Z0-9]/g, '-') 15 if (sanitized.length <= MAX_SANITIZED_LENGTH) { 16 return sanitized 17 } 18 return `${sanitized.slice(0, MAX_SANITIZED_LENGTH)}-${Math.abs(djb2Hash(name)).toString(36)}` 19 } 20 21 function getProjectDir(cwd: string): string { 22 return sanitizePath(cwd) 23 } 24 25 export const CACHE_PATHS = { 26 baseLogs: () => join(paths.cache, getProjectDir(getFsImplementation().cwd())), 27 errors: () => 28 join(paths.cache, getProjectDir(getFsImplementation().cwd()), 'errors'), 29 messages: () => 30 join(paths.cache, getProjectDir(getFsImplementation().cwd()), 'messages'), 31 mcpLogs: (serverName: string) => 32 join( 33 paths.cache, 34 getProjectDir(getFsImplementation().cwd()), 35 // Sanitize server name for Windows compatibility (colons are reserved for drive letters) 36 `mcp-logs-${sanitizePath(serverName)}`, 37 ), 38 }