// ponytail: preserve existing manually configured Brave keys in settings.json // (webAgent.braveApiKey). Upstream pi-web-agent reads only PI_WEB_AGENT_BRAVE_API_KEY. // Ceiling: if selesai moves web search config elsewhere, update this helper; upgrade path = // upstream pi-web-agent adopting a settings hook. import { existsSync, readFileSync } from 'node:fs'; import { join } from 'node:path'; import { getAgentDir, getSettingsPath } from '@selesai/code'; /** * True when tokenin-auth.json (written by the tokenin-onboarding extension) * has an active account. Used to decide whether the tokenin search provider is * usable. Never throws. */ export function hasActiveTokenInAccount(authPath: string = join(getAgentDir(), 'tokenin-auth.json')): boolean { try { if (!existsSync(authPath)) return false; const parsed = JSON.parse(readFileSync(authPath, 'utf-8')) as unknown; if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return false; const auth = parsed as { accounts?: unknown; activeId?: unknown }; if (!Array.isArray(auth.accounts) || typeof auth.activeId !== 'string') return false; return auth.accounts.some((a) => { if (!a || typeof a !== 'object' || Array.isArray(a)) return false; const account = a as { id?: unknown; apiKey?: unknown }; return account.id === auth.activeId && typeof account.apiKey === 'string' && account.apiKey.trim() !== ''; }); } catch { return false; } } /** * Read the Brave API key from selesai settings.json (webAgent.braveApiKey). * Returns undefined if settings.json or the key is absent. Never throws. */ export function readBraveKeyFromSettings(settingsPath: string = getSettingsPath()): string | undefined { try { if (!existsSync(settingsPath)) return undefined; const raw = readFileSync(settingsPath, 'utf-8'); const parsed = JSON.parse(raw) as Record; const webAgent = parsed.webAgent; if (!webAgent || typeof webAgent !== 'object' || Array.isArray(webAgent)) return undefined; const apiKey = (webAgent as Record).braveApiKey; return typeof apiKey === 'string' && apiKey.trim() !== '' ? apiKey : undefined; } catch { return undefined; } }