Luigit
repositories / pi-ext

pi-ext

bugabingas pi extensions

owned by admin

extensions/klaus/src/runtime/standard.ts

Raw
import { execFile } from "node:child_process";
import { stat } from "node:fs/promises";
import { createRequire } from "node:module";
import { dirname, join } from "node:path";
import { promisify } from "node:util";
import { dbg, diagnosticKind } from "../debug.js";

const execFileAsync = promisify(execFile);
const require = createRequire(import.meta.url);

let resolution: Promise<string> | undefined;

function platformKey(): string {
	dbg?.("runtime.standard.platformKey.start");
	if (process.arch !== "arm64" && process.arch !== "x64") {
		throw new Error(
			`Klaus does not support ${process.platform} ${process.arch}.`,
		);
	}
	if (process.platform === "darwin" || process.platform === "win32") {
		return `${process.platform}-${process.arch}`;
	}
	if (process.platform !== "linux") {
		throw new Error(
			`Klaus does not support ${process.platform} ${process.arch}.`,
		);
	}
	const report = process.report?.getReport();
	const glibc =
		report && typeof report === "object"
			? (report as { header?: { glibcVersionRuntime?: string } }).header
					?.glibcVersionRuntime
			: undefined;
	return `linux-${process.arch}${glibc ? "" : "-musl"}`;
}

async function resolve(): Promise<string> {
	dbg?.("runtime.standard.resolve.start");
	const key = platformKey();
	const packageName = `@anthropic-ai/claude-agent-sdk-${key}`;
	let packageJson: string;
	try {
		packageJson = require.resolve(`${packageName}/package.json`);
	} catch {
		throw new Error(`Klaus runtime ${packageName} is missing.`);
	}
	const executable = join(
		dirname(packageJson),
		process.platform === "win32" ? "claude.exe" : "claude",
	);
	if (!(await stat(executable)).isFile()) {
		throw new Error(`Klaus runtime executable is missing from ${packageName}.`);
	}
	await execFileAsync(executable, ["--version"], {
		timeout: 30_000,
		maxBuffer: 64 * 1024,
	});
	dbg?.("runtime.standard.resolve.end");
	return executable;
}

export function resolveStandardRuntime(): Promise<string> {
	dbg?.("runtime.standard.resolveCached", { cached: Boolean(resolution) });
	resolution ??= resolve().catch((error) => {
		dbg?.("runtime.standard.resolve.error", {
			kind: diagnosticKind(error),
		});
		resolution = undefined;
		throw error;
	});
	return resolution;
}