import { readFile, writeFile, chmod } from 'node:fs/promises'; import { fileURLToPath } from 'node:url'; import { dirname, join } from 'node:path'; const HERE = dirname(fileURLToPath(import.meta.url)); const REGISTRY_PATH = join(HERE, 'registry.json'); export async function loadRegistry() { try { const raw = await readFile(REGISTRY_PATH, 'utf8'); const parsed = JSON.parse(raw); if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) { return {}; } return parsed; } catch { return {}; } } export async function saveRegistry(registry) { const data = registry && typeof registry === 'object' ? registry : {}; await writeFile(REGISTRY_PATH, JSON.stringify(data, null, 2) + '\n', { encoding: 'utf8', mode: 0o600 }); try { await chmod(REGISTRY_PATH, 0o600); } catch {} } export async function upsertEntry(entry) { if (!entry || typeof entry.label !== 'string' || entry.label.length === 0) { throw new Error('upsertEntry: entry.label is required'); } const registry = await loadRegistry(); registry[entry.label] = { host: entry.host, port: entry.port, token: entry.token, fp: entry.fp, label: entry.label, version: entry.version, lastConnectedAt: entry.lastConnectedAt ?? new Date().toISOString(), }; await saveRegistry(registry); return registry[entry.label]; } export async function getEntry(label) { if (typeof label !== 'string' || label.length === 0) return null; const registry = await loadRegistry(); return registry[label] ?? null; } export { REGISTRY_PATH };