// horst — stable host snapshot. // // One-time lazy load: node:os getters plus a single /etc/os-release read, // memoized for the whole process so the rendered section never changes. import { readFile } from "node:fs/promises"; import os from "node:os"; export interface HostSnapshot { hostname: string; osLabel: string; kernel: string; arch: string; cpuModel?: string; cpuCount: number; memGiB: number; loginShell?: string; } function osTypeLabel(): string { if (process.platform === "win32") return "Windows"; if (process.platform === "darwin") return "macOS"; return os.type(); } /** Read PRETTY_NAME from /etc/os-release; absent on other platforms. */ async function readPrettyName(): Promise { if (process.platform !== "linux") return undefined; try { const content = await readFile("/etc/os-release", "utf8"); const match = /^PRETTY_NAME=(?:"([^"]*)"|(.*?))\s*$/m.exec(content); return match?.[1] ?? match?.[2] ?? undefined; } catch { return undefined; } } function loginShell(): string | undefined { try { return os.userInfo().shell?.trim() || undefined; } catch { return undefined; } } async function loadHostSnapshot(): Promise { const cpus = os.cpus(); return { hostname: os.hostname(), osLabel: (await readPrettyName()) ?? osTypeLabel(), kernel: os.release(), arch: os.arch(), cpuModel: cpus[0]?.model.trim() || undefined, cpuCount: cpus.length, memGiB: Math.round(os.totalmem() / 2 ** 30), loginShell: loginShell(), }; } let snapshot: Promise | undefined; /** Lazy process-wide snapshot; loaded at most once. */ export function isHostSnapshotCached(): boolean { return snapshot !== undefined; } export function getHostSnapshot(): Promise { if (!snapshot) snapshot = loadHostSnapshot(); return snapshot; } export function renderHostSection( host: HostSnapshot, preferredShell?: string, ): string { const lines = [ `hostname: ${host.hostname}`, `os: ${host.osLabel}`, `kernel: ${host.kernel}`, `arch: ${host.arch}`, host.cpuModel ? `cpu: ${host.cpuModel} × ${host.cpuCount}` : `cpu: ${host.cpuCount} cores`, `mem: ${host.memGiB} GiB`, ]; if (host.loginShell) lines.push(`login shell: ${host.loginShell}`); if (preferredShell) lines.push(`preferred shell: ${preferredShell}`); return lines.join("\n"); } /** Render the cached host facts with the current session's shell preference. */ export async function getHostSection(preferredShell?: string): Promise { return renderHostSection(await getHostSnapshot(), preferredShell); }