/ src / utils / cachePaths.ts
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  }