// Origin URL — builds a resolvable URL pointing to a TODO issue in the repo's web UI // Format varies by host: // Bitbucket: /src//# // GitHub: /blob//# // GitLab: /-/blob//# import { execSync } from "child_process" export function getGitRemoteUrl(cwd = process.cwd()): string { try { return execSync("git remote get-url origin", { cwd, encoding: "utf-8" }).trim() } catch { throw new Error("Could not determine git remote URL. Is this a git repository with an 'origin' remote?") } } export function getGitBranch(cwd = process.cwd()): string { try { return execSync("git rev-parse --abbrev-ref HEAD", { cwd, encoding: "utf-8" }).trim() } catch { return "main" } } export function normalizeRemoteUrl(url: string): string { let normalized = url const sshMatch = normalized.match(/^git@([^:]+):(.+?)(?:\.git)?$/) if (sshMatch) { normalized = `https://${sshMatch[1]}/${sshMatch[2]}` } normalized = normalized.replace(/\.git$/, "") normalized = normalized.replace(/\/+$/, "") return normalized } function detectHost(url: string): "bitbucket" | "github" | "gitlab" | "unknown" { if (url.includes("bitbucket.org")) return "bitbucket" if (url.includes("github.com")) return "github" if (url.includes("gitlab.com") || url.includes("gitlab")) return "gitlab" return "unknown" } export function buildOriginUrl( remoteUrl: string, branch: string, todoPath: string, issueId: number ): string { const base = normalizeRemoteUrl(remoteUrl) const host = detectHost(base) switch (host) { case "github": return `${base}/blob/${branch}/${todoPath}#${issueId}` case "gitlab": return `${base}/-/blob/${branch}/${todoPath}#${issueId}` case "bitbucket": default: return `${base}/src/${branch}/${todoPath}#${issueId}` } } export function buildCommitUrl(remoteUrl: string, commitHash: string): string { const base = normalizeRemoteUrl(remoteUrl) const host = detectHost(base) switch (host) { case "github": return `${base}/commit/${commitHash}` case "gitlab": return `${base}/-/commit/${commitHash}` case "bitbucket": default: return `${base}/commits/${commitHash}` } } export function shortHash(hash: string): string { return hash.slice(0, 7) }