/** * Config management — persists agent config to ~/.tip-agent/config.json */ import * as fs from "fs"; import * as path from "path"; import * as os from "os"; const CONFIG_DIR = path.join(os.homedir(), ".tip-agent"); const CONFIG_FILE = path.join(CONFIG_DIR, "config.json"); export interface AgentConfig { token: string; port: number; maxGb: number; name: string; serverUrl: string; pid?: number; startedAt?: string; } const DEFAULTS: Partial = { port: 1080, maxGb: 10, name: os.hostname(), serverUrl: "https://transceiver-db.context-x.org", }; export function loadConfig(): AgentConfig | null { if (!fs.existsSync(CONFIG_FILE)) return null; try { const raw = fs.readFileSync(CONFIG_FILE, "utf8"); return JSON.parse(raw) as AgentConfig; } catch { return null; } } export function saveConfig(cfg: Partial): AgentConfig { if (!fs.existsSync(CONFIG_DIR)) { fs.mkdirSync(CONFIG_DIR, { recursive: true }); } const existing = loadConfig() ?? {}; const merged = { ...DEFAULTS, ...existing, ...cfg } as AgentConfig; fs.writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2), "utf8"); return merged; } export function clearConfig(): void { if (fs.existsSync(CONFIG_FILE)) { fs.unlinkSync(CONFIG_FILE); } } export function getPidFile(): string { return path.join(CONFIG_DIR, "agent.pid"); } export function savePid(pid: number): void { if (!fs.existsSync(CONFIG_DIR)) { fs.mkdirSync(CONFIG_DIR, { recursive: true }); } fs.writeFileSync(getPidFile(), String(pid), "utf8"); } export function loadPid(): number | null { const pidFile = getPidFile(); if (!fs.existsSync(pidFile)) return null; const raw = fs.readFileSync(pidFile, "utf8").trim(); const pid = parseInt(raw, 10); return isNaN(pid) ? null : pid; } export function clearPid(): void { const pidFile = getPidFile(); if (fs.existsSync(pidFile)) fs.unlinkSync(pidFile); }