import fs from "node:fs"; import path from "node:path"; import { z } from "zod"; import { resolvePaperclipInstanceRoot } from "../home-paths.js"; export const NEXUS_MODES = ["personal_ai", "project_builder", "both"] as const; export type NexusMode = (typeof NEXUS_MODES)[number]; const nexusSettingsSchema = z.object({ mode: z.enum(NEXUS_MODES).default("both"), voiceEnabled: z.boolean().default(false), }); type NexusSettings = z.infer; function resolveNexusSettingsPath(): string { return path.resolve(resolvePaperclipInstanceRoot(), "data", "nexus-settings.json"); } export function nexusSettingsService() { async function get(): Promise { const filePath = resolveNexusSettingsPath(); try { const raw = fs.readFileSync(filePath, "utf-8"); const parsed = nexusSettingsSchema.safeParse(JSON.parse(raw)); if (parsed.success) { return parsed.data; } return { mode: "both", voiceEnabled: false }; } catch { return { mode: "both", voiceEnabled: false }; } } async function set(patch: Partial): Promise { const current = await get(); const merged = { ...current, ...patch }; // Validate — will throw ZodError if invalid const validated = nexusSettingsSchema.parse(merged); const filePath = resolveNexusSettingsPath(); fs.mkdirSync(path.dirname(filePath), { recursive: true }); fs.writeFileSync(filePath, JSON.stringify(validated, null, 2), "utf-8"); return validated; } return { get, set }; }