77 AIExplainQueryParams ,
88 AIRecommendChartParams ,
99 AITestConnectionParams ,
10+ AISettings ,
1011} from "../types/ai" ;
1112import {
1213 getOrCall ,
@@ -19,6 +20,9 @@ import { buildSchemaAnalysisPrompt } from "../ai/prompts/schema-analysis";
1920import { buildQueryExplanationPrompt } from "../ai/prompts/query-explanation" ;
2021import { buildChartRecommendationPrompt } from "../ai/prompts/chart-recommendation" ;
2122import { parseChartRecommendation } from "../ai/prompts/chart-recommendation" ;
23+ import fs from "fs/promises" ;
24+ import fsSync from "fs" ;
25+ import { AI_SETTINGS_FILE , CONFIG_FOLDER , ensureDir } from "../utils/config" ;
2226
2327export class AIHandlers {
2428 private aiService : AIService ;
@@ -219,4 +223,43 @@ export class AIHandlers {
219223 this . rpc . sendError ( id , { code : "HISTORY_ERROR" , message : err ?. message ?? String ( err ) } ) ;
220224 }
221225 }
226+
227+ // ── Settings persistence (reads/writes ai-settings.json) ──────────────
228+
229+ async handleLoadSettings ( _params : unknown , id : number | string ) {
230+ try {
231+ ensureDir ( CONFIG_FOLDER ) ;
232+ if ( ! fsSync . existsSync ( AI_SETTINGS_FILE ) ) {
233+ // Return empty object — frontend will fall back to defaults
234+ this . rpc . sendResponse ( id , { ok : true , data : { } } ) ;
235+ return ;
236+ }
237+ const raw = await fs . readFile ( AI_SETTINGS_FILE , "utf-8" ) ;
238+ const settings = JSON . parse ( raw ) as AISettings ;
239+ this . rpc . sendResponse ( id , { ok : true , data : settings } ) ;
240+ } catch ( err : any ) {
241+ this . logger ?. warn ( { err } , "ai.loadSettings failed — returning empty" ) ;
242+ // Non-fatal: return empty so the app still starts
243+ this . rpc . sendResponse ( id , { ok : true , data : { } } ) ;
244+ }
245+ }
246+
247+ async handleSaveSettings ( params : { settings : AISettings } , id : number | string ) {
248+ try {
249+ ensureDir ( CONFIG_FOLDER ) ;
250+ await fs . writeFile (
251+ AI_SETTINGS_FILE ,
252+ JSON . stringify ( params . settings , null , 2 ) ,
253+ "utf-8"
254+ ) ;
255+ // On non-Windows platforms, restrict file permissions (contains API keys)
256+ if ( process . platform !== "win32" ) {
257+ await fs . chmod ( AI_SETTINGS_FILE , 0o600 ) ;
258+ }
259+ this . rpc . sendResponse ( id , { ok : true , data : { saved : true } } ) ;
260+ } catch ( err : any ) {
261+ this . logger ?. error ( { err } , "ai.saveSettings failed" ) ;
262+ this . rpc . sendError ( id , { code : "SAVE_ERROR" , message : err ?. message ?? String ( err ) } ) ;
263+ }
264+ }
222265}
0 commit comments