Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

pi/agent/skills/mermaid/scripts/validate-pi.mjs

Raw
import { createRequire } from "node:module";
import { isAbsolute } from "node:path";
import { pathToFileURL } from "node:url";

const usage = "Usage: pipe raw Mermaid through stdin to node validate-pi.mjs --width <available-columns>";

async function main() {
	const args = process.argv.slice(2);
	if (args.length === 1 && args[0] === "--help") {
		console.log(usage);
		return;
	}
	if (
		args.length !== 2 ||
		args[0] !== "--width" ||
		!/^\d+$/.test(args[1]) ||
		!Number.isSafeInteger(Number(args[1])) ||
		Number(args[1]) < 1
	) {
		throw new Error(usage);
	}
	const availableColumns = Number(args[1]);
	if (process.stdin.isTTY) throw new Error("Pipe raw Mermaid source through stdin; file arguments are unsupported.");

	const packagePath = process.env.PI_CONTEXT_PACKAGE_JSON_PATH;
	if (!packagePath || !isAbsolute(packagePath)) {
		throw new Error("PI_CONTEXT_PACKAGE_JSON_PATH must identify the installed Pi package.json by absolute path.");
	}
	const require = createRequire(pathToFileURL(packagePath));
	let renderer;
	try {
		renderer = await import(pathToFileURL(require.resolve("grok-mermaid")).href);
	} catch (error) {
		throw new Error(`Cannot load Pi's installed grok-mermaid (${error.code ?? "load failure"}); do not install a substitute.`);
	}
	if (typeof renderer.render !== "function") throw new Error("Pi renderer no longer exposes render(); inspect its installed API.");

	process.stdin.setEncoding("utf8");
	let source = "";
	for await (const chunk of process.stdin) source += chunk;
	const art = renderer.render(source);
	if (!art) {
		console.log(JSON.stringify({
			ok: false,
			reason: "Renderer returned null: empty, unsupported, invalid, or oversized diagram.",
			availableColumns,
			requiredColumns: null,
		}));
		process.exitCode = 1;
		return;
	}
	const ok = art.warnings.length === 0 && art.width <= availableColumns;
	console.log(JSON.stringify({
		ok,
		availableColumns,
		requiredColumns: art.width,
		overflow: art.width > availableColumns,
		warnings: art.warnings,
		lines: art.plain,
	}));
	if (!ok) process.exitCode = 1;
}

main().catch((error) => {
	console.error(error.message);
	process.exitCode = 2;
});