import { access, readFile } from "node:fs/promises"; import { join } from "node:path"; import type { Mode, PrivacyProfile } from "../types.js"; export const FREE_UNAVAILABLE_MARKER = "ultrapi-free-unavailable"; export const PROFILE_MARKER = "ultrapi-profile.json"; export interface ProfileMarkerStatus { valid: boolean; profile?: PrivacyProfile; reason: "ok" | "missing" | "invalid" | "free-unavailable" } function object(value: unknown): Record | undefined { return value && typeof value === "object" && !Array.isArray(value) ? value as Record : undefined; } export async function inspectProfileMarker(agentDir: string): Promise { let value: unknown; try { value = JSON.parse(await readFile(join(agentDir, PROFILE_MARKER), "utf8")); } catch (error) { if ((error as NodeJS.ErrnoException).code === "ENOENT") return { valid: false, reason: "missing" }; if (error instanceof SyntaxError) return { valid: false, reason: "invalid" }; throw error; } const profile = object(value)?.profile; if (profile !== "private" && profile !== "free") return { valid: false, reason: "invalid" }; if (profile === "free") { try { await access(join(agentDir, FREE_UNAVAILABLE_MARKER)); return { valid: false, profile, reason: "free-unavailable" }; } catch (error) { if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error; } } return { valid: true, profile, reason: "ok" }; } export async function assertAutoModeProfile(agentDir: string, mode: Mode): Promise { if (mode !== "auto") return; const marker = await inspectProfileMarker(agentDir); if (!marker.valid) throw new Error(`UltraPi auto mode requires a valid profile marker for ${agentDir} (${marker.reason})`); }