import fs from "node:fs/promises"; import path from "node:path"; export async function resolveWorkspacePath(root, project = ".") { if (typeof project !== "string" || project.includes("\0")) { throw new Error("Invalid project path"); } const rootReal = await fs.realpath(root); const candidate = path.resolve(rootReal, project || "."); const candidateReal = await fs.realpath(candidate); if (candidateReal !== rootReal && !candidateReal.startsWith(`${rootReal}${path.sep}`)) { throw new Error("Project must be below /workspace"); } const stat = await fs.stat(candidateReal); if (!stat.isDirectory()) throw new Error("Project is not a directory"); return candidateReal; } export async function listProjects(root) { const rootReal = await fs.realpath(root); const entries = await fs.readdir(rootReal, { withFileTypes: true }); return entries .filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")) .map((entry) => entry.name) .sort((a, b) => a.localeCompare(b)); }