/** * Pi auth storage — persistent credentials for the Bloby (pi) harness. * * Stored in ~/.bloby/pi-auth.json (separate from the main config.json so we * can wipe/rotate the LLM credentials without touching the rest of the bot * config). Iteration 1: a single active sub-provider at a time. */ import fs from 'fs'; import path from 'path'; import { DATA_DIR } from '../../../shared/paths.js'; export interface PiAuth { subProvider: string; apiKey?: string; baseUrl?: string; modelId?: string; savedAt: number; } const PI_AUTH_PATH = path.join(DATA_DIR, 'pi-auth.json'); export function readPiAuth(): PiAuth | null { try { if (!fs.existsSync(PI_AUTH_PATH)) return null; const raw = fs.readFileSync(PI_AUTH_PATH, 'utf-8'); const parsed = JSON.parse(raw); if (!parsed?.subProvider) return null; return parsed as PiAuth; } catch { return null; } } export function writePiAuth(auth: Omit): PiAuth { fs.mkdirSync(DATA_DIR, { recursive: true }); const full: PiAuth = { ...auth, savedAt: Date.now() }; fs.writeFileSync(PI_AUTH_PATH, JSON.stringify(full, null, 2), { mode: 0o600 }); return full; } export function clearPiAuth(): void { try { fs.rmSync(PI_AUTH_PATH, { force: true }); } catch {} } export function getPiAuthStatus(): { configured: boolean; subProvider?: string; modelId?: string; baseUrl?: string } { const auth = readPiAuth(); if (!auth) return { configured: false }; return { configured: true, subProvider: auth.subProvider, modelId: auth.modelId, baseUrl: auth.baseUrl, }; }