| 33 | }; |
| 34 | |
| 35 | const sanitizePath = (pathStr: string, repoName?: string): string => { |
| 36 | if (!pathStr) return ''; |
| 37 | |
| 38 | // Normalize Windows slashes |
| 39 | let p = pathStr.replace(/\\/g, '/'); |
| 40 | |
| 41 | // If it's already relative, just return it |
| 42 | if (p.startsWith('.') || (!p.startsWith('/') && !p.match(/^[a-zA-Z]:\//))) { |
| 43 | return p.startsWith('./') ? p : './' + p; |
| 44 | } |
| 45 | |
| 46 | // Detect if we can make it relative using the repoName |
| 47 | if (repoName) { |
| 48 | const parts = p.split('/'); |
| 49 | const repoIndex = parts.lastIndexOf(repoName); |
| 50 | if (repoIndex !== -1) { |
| 51 | return './' + parts.slice(repoIndex).join('/'); |
| 52 | } |
| 53 | } |
| 54 | |
| 55 | // Generic cleanup for absolute paths |
| 56 | const segments = p.split('/').filter(Boolean); |
| 57 | if (segments.length > 3) { |
| 58 | if (p.startsWith('/home/') || p.startsWith('/Users/') || p.includes('/runner/work/')) { |
| 59 | return './' + segments.slice(-3).join('/'); |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | return p; |
| 64 | }; |
| 65 | |
| 66 | // ============================================================================ |
| 67 | // INDEXEDDB GRAPH CACHE SERVICE |