/** * Repository ID generation utilities. */ /** * Parse a GitHub URL into a canonical repository ID. * Supports: * https://github.com/facebook/react * https://github.com/facebook/react.git * github.com/facebook/react */ export function resolveGitHubId(url: string): string { const match = url.match(/github\.com\/([^/]+)\/([^/\s.]+)/); if (!match) throw new Error('Invalid GitHub URL — expected github.com/owner/repo'); return `/${match[1]}/${match[2]}`; } /** * Generate a local repository ID from an absolute path. * Collision-resolves by appending -2, -3, etc. */ export function resolveLocalId(path: string, existingIds: string[]): string { const base = slugify(path.split('/').at(-1) ?? 'repo'); let id = `/local/${base}`; let counter = 2; while (existingIds.includes(id)) { id = `/local/${base}-${counter++}`; } return id; } /** * Slugify a string to be safe for use in IDs. */ function slugify(str: string): string { return str .toLowerCase() .replace(/[^a-z0-9-_]/g, '-') .replace(/-+/g, '-') .replace(/^-|-$/g, '') || 'repo'; }