config.ts
1 import { showNotification } from '../utils//notification' 2 import fs from 'node:fs' 3 import path from 'node:path' 4 import { McpServerConfig } from './types' 5 import { shell } from 'electron' 6 import { debounce } from 'lodash' 7 8 let mcpConfig 9 10 let timeoutId 11 12 const DEBOUNCE_DELAY = 500 13 14 function handleFileChange(configPath) { 15 try { 16 const parsedConfig = readConfig(configPath) 17 if (mcpConfig !== parsedConfig) { 18 console.log(`${configPath} changed`) 19 } 20 } catch {} 21 } 22 23 const debouncedHandleFileChange = debounce(handleFileChange, DEBOUNCE_DELAY) 24 25 function readConfig(configPath: string) { 26 const fileString = fs.readFileSync(configPath, 'utf8') 27 if (fileString) { 28 return JSON.parse(fileString) 29 } else { 30 return {} 31 } 32 } 33 34 export function loadConfigFile(configPath: string): Record<string, McpServerConfig> { 35 const resolvedConfigPath = path.isAbsolute(configPath) 36 ? configPath 37 : path.resolve(process.cwd(), configPath) 38 39 try { 40 if (!fs.existsSync(resolvedConfigPath)) { 41 showNotification({ 42 body: `MCP Config Not Found.` 43 }) 44 return {} 45 } 46 const parsedConfig = readConfig(resolvedConfigPath) 47 mcpConfig = parsedConfig 48 fs.watch(resolvedConfigPath, () => { 49 if (timeoutId) clearTimeout(timeoutId) 50 timeoutId = setTimeout(() => debouncedHandleFileChange(resolvedConfigPath), DEBOUNCE_DELAY) 51 }) 52 if (!parsedConfig.mcpServers) { 53 return {} 54 } else { 55 return parsedConfig.mcpServers 56 } 57 } catch (err) { 58 showNotification( 59 { 60 body: `MCP Config JSON parse failure` 61 }, 62 63 { 64 onClick: () => { 65 shell.showItemInFolder(resolvedConfigPath) 66 } 67 } 68 ) 69 if (err instanceof SyntaxError) { 70 throw new Error(`Invalid JSON in config file: ${err.message}`) 71 } 72 throw err 73 } 74 } 75 76 export function loadLlmFile(llmPath: string) { 77 const resolvedConfigPath = path.isAbsolute(llmPath) 78 ? llmPath 79 : path.resolve(process.cwd(), llmPath) 80 try { 81 if (!fs.existsSync(resolvedConfigPath)) { 82 throw new Error(`Config file not found: ${resolvedConfigPath}`) 83 } 84 const configContent = fs.readFileSync(resolvedConfigPath, 'utf8') 85 const parsedConfig = JSON.parse(configContent) 86 if (!parsedConfig) { 87 return {} 88 } else { 89 return parsedConfig 90 } 91 } catch (err) { 92 showNotification( 93 { 94 body: 'LLM Config JSON parse failure' 95 }, 96 97 { 98 onClick: () => { 99 shell.showItemInFolder(resolvedConfigPath) 100 } 101 } 102 ) 103 if (err instanceof SyntaxError) { 104 throw new Error(`Invalid JSON in llm file: ${err.message}`) 105 } 106 throw err 107 } 108 }