@@ -4,7 +4,7 @@ import fs from "fs/promises";
44import path from "path" ;
55import os from "os" ;
66import json5 from "json5" ;
7-
7+ import logger from "./logger.js" ;
88const modelSchema = z . object ( {
99 name : z . string ( ) . describe ( "A user-friendly nickname for the model." ) ,
1010 provider : z
@@ -81,37 +81,50 @@ const defaultConfig: Config = {
8181 mcpServers : { } ,
8282} ;
8383
84- export const CONFIG_DIR = path . join ( os . homedir ( ) , ".config" , "tobi" ) ;
85- export const HISTORY_PATH = path . join ( CONFIG_DIR , "history" ) ;
86- const CONFIG_PATH = path . join ( CONFIG_DIR , "config.json5" ) ;
84+ export function getConfigDir ( ) : string {
85+ return path . join ( os . homedir ( ) , ".config" , "tobi" ) ;
86+ }
87+ export const HISTORY_PATH = path . join ( getConfigDir ( ) , "history" ) ;
88+ const CONFIG_PATH = path . join ( getConfigDir ( ) , "config.json5" ) ;
8789
8890export async function loadConfig ( ) : Promise < Config > {
91+ logger . debug ( "Attempting to load configuration." ) ;
8992 try {
9093 const configContent = await fs . readFile ( CONFIG_PATH , "utf-8" ) ;
9194 const parsedConfig = json5 . parse ( configContent ) ;
9295
9396 // Merge user's config over defaults. This makes adding new keys in updates non-breaking.
9497 const mergedConfig = { ...defaultConfig , ...parsedConfig } ;
95- return configSchema . parse ( mergedConfig ) ;
98+ const finalConfig = configSchema . parse ( mergedConfig ) ;
99+ logger . info ( "Configuration loaded successfully." ) ;
100+ return finalConfig ;
96101 } catch ( error : unknown ) {
97102 if ( error instanceof Error && ( error as NodeJS . ErrnoException ) . code === "ENOENT" ) {
103+ logger . warn ( `Configuration file not found. Creating a default one at: ${ CONFIG_PATH } ` ) ;
98104 console . warn ( `Configuration file not found. Creating a default one at: ${ CONFIG_PATH } ` ) ;
99105 console . warn (
100106 `Please open this file and update your environment variables (.env) with your API keys.` ,
101107 ) ;
102- await fs . mkdir ( CONFIG_DIR , { recursive : true } ) ;
108+ await fs . mkdir ( getConfigDir ( ) , { recursive : true } ) ;
109+ // Also create the logs directory
110+ const LOGS_DIR = path . join ( getConfigDir ( ) , "logs" ) ;
111+ await fs . mkdir ( LOGS_DIR , { recursive : true } ) ;
103112 await fs . writeFile ( CONFIG_PATH , json5 . stringify ( defaultConfig , null , 2 ) ) ;
113+ logger . info ( "Default configuration file created." ) ;
104114 return defaultConfig ;
105115 } else if ( error instanceof z . ZodError ) {
116+ logger . error ( "Configuration file is invalid:" , { error : error . issues } ) ;
106117 console . error ( "Configuration file is invalid:" , error . issues ) ;
107118 } else {
119+ logger . error ( "Failed to load configuration:" , { error } ) ;
108120 console . error ( "Failed to load configuration:" , error ) ;
109121 }
110122 process . exit ( 1 ) ;
111123 }
112124}
113125
114126export async function saveConfig ( config : Config ) : Promise < void > {
127+ logger . debug ( "Attempting to save configuration." ) ;
115128 try {
116129 // We only want to save the fields that are user-configurable, not the derived ones.
117130 const configToSave : Partial < Config > = {
@@ -123,7 +136,9 @@ export async function saveConfig(config: Config): Promise<void> {
123136 mcpServers : config . mcpServers ,
124137 } ;
125138 await fs . writeFile ( CONFIG_PATH , json5 . stringify ( configToSave , null , 2 ) ) ;
139+ logger . info ( "Configuration saved successfully." ) ;
126140 } catch ( error ) {
141+ logger . error ( "Failed to save configuration:" , { error } ) ;
127142 console . error ( "Failed to save configuration:" , error ) ;
128143 // We don't want to exit the app if saving fails, but we should let the user know.
129144 }
0 commit comments