repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
extensions/horst/host.ts
Raw// 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<string | undefined> {
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<HostSnapshot> {
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<HostSnapshot> | undefined;
/** Lazy process-wide snapshot; loaded at most once. */
export function isHostSnapshotCached(): boolean {
return snapshot !== undefined;
}
export function getHostSnapshot(): Promise<HostSnapshot> {
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<string> {
return renderHostSection(await getHostSnapshot(), preferredShell);
}