import { sep } from "node:path"; /** POSIX-style path relative to repository root (e.g. `plans/Plan-a/Task-b.md`). */ export function toRepoPathPosix(relativeFromRepoRoot: string): string { return relativeFromRepoRoot.split(sep).join("/"); } /** * Whether this repo-relative path should be imported as backlog markdown. * Expects POSIX `plans/...` paths. */ export function isTrackedBacklogMarkdown(repoPathPosix: string): boolean { if (!repoPathPosix.startsWith("plans/")) return false; if (repoPathPosix === "plans/README.md") return false; const base = repoPathPosix.split("/").pop() ?? ""; return ( base.startsWith("Plan-") || base.startsWith("Epic-") || base.startsWith("Task-") ); } /** * Parent document path for hierarchy links, or `null` for plan roots. */ export function parentRepoPath(repoPathPosix: string): string | null { const parts = repoPathPosix.split("/").filter(Boolean); if (parts.length < 3 || parts[0] !== "plans") return null; const planDir = parts[1]; if (!planDir.startsWith("Plan-")) return null; if (parts.length === 3) { const file = parts[2]; if (file.startsWith("Plan-") && file.endsWith(".md")) return null; } if (parts.length === 4) { const file = parts[3]; if (file.startsWith("Epic-") && file.endsWith(".md")) { return `plans/${planDir}/${planDir}.md`; } } if (parts.length === 5) { const epicDir = parts[2]; const file = parts[4]; if (epicDir.startsWith("Epic-") && file.startsWith("Task-") && file.endsWith(".md")) { return `plans/${planDir}/${epicDir}/${epicDir}.md`; } } return null; } export function planSlugFromPath(repoPathPosix: string): string | null { const parts = repoPathPosix.split("/").filter(Boolean); if (parts.length < 2 || parts[0] !== "plans") return null; const planDir = parts[1]; return planDir.startsWith("Plan-") ? planDir.replace(/^Plan-/, "") : null; } export function epicFolderFromPath(repoPathPosix: string): string | null { const parts = repoPathPosix.split("/").filter(Boolean); if (parts.length < 3 || parts[0] !== "plans") return null; const epicDir = parts[2]; if (parts.length >= 4 && epicDir.startsWith("Epic-")) return epicDir.replace(/^Epic-/, ""); return null; }