diff --git a/src/cli/bds-mcp.ts b/src/cli/bds-mcp.ts index a61790a..b5ca864 100644 --- a/src/cli/bds-mcp.ts +++ b/src/cli/bds-mcp.ts @@ -9,6 +9,7 @@ */ import * as path from 'path'; +import * as fs from 'fs'; import { eq } from 'drizzle-orm'; import { platformConfigPath } from './platform'; import { initDatabase } from '../main/database/connection'; @@ -28,10 +29,15 @@ import { MCPServer } from '../main/engine/MCPServer'; const userData = platformConfigPath(); const dbPath = path.join(userData, 'bds.db'); -// __dirname points to Contents/Resources/ in the packaged app (bds-mcp.cjs -// is placed there by extraResources). The drizzle/ migrations folder is also -// shipped to Contents/Resources/drizzle/ via extraResources. -const migrationsFolder = path.join(__dirname, 'drizzle'); +// __dirname points to Contents/Resources/ in the packaged app (bds-mcp.cjs is +// placed there by extraResources, alongside drizzle/). +// In development it points to dist/cli/ — drizzle/ lives at the project root. +const migrationsFolder = (() => { + const adjacent = path.join(__dirname, 'drizzle'); + if (fs.existsSync(adjacent)) return adjacent; + // dev: dist/cli/ → ../../drizzle + return path.join(__dirname, '..', '..', 'drizzle'); +})(); const db = initDatabase({ dbPath, migrationsFolder }); diff --git a/src/main/ipc/handlers.ts b/src/main/ipc/handlers.ts index 97b6de9..5006a03 100644 --- a/src/main/ipc/handlers.ts +++ b/src/main/ipc/handlers.ts @@ -131,6 +131,20 @@ function buildMcpUrl(bundle: EngineBundle): string { } } +function buildMcpAgentConfigOptions(bundle: EngineBundle): import('../engine/MCPAgentConfigEngine').MCPAgentConfigOptions { + const os = require('os') as typeof import('os'); + const scriptPath = app.isPackaged + ? path.join(process.resourcesPath, 'bds-mcp.cjs') + : path.join(app.getAppPath(), 'dist', 'cli', 'bds-mcp.cjs'); + return { + homeDir: os.homedir(), + platform: process.platform, + mcpUrl: buildMcpUrl(bundle), + execPath: process.execPath, + scriptPath, + }; +} + export function registerIpcHandlers(bundle: EngineBundle): void { // ============ Git Handlers ============ @@ -1577,31 +1591,19 @@ export function registerIpcHandlers(bundle: EngineBundle): void { safeHandle('mcp:getAgents', async () => { const { MCPAgentConfigEngine } = await import('../engine/MCPAgentConfigEngine'); - const engine = new MCPAgentConfigEngine({ - homeDir: require('os').homedir(), - platform: process.platform, - mcpUrl: buildMcpUrl(bundle), - }); + const engine = new MCPAgentConfigEngine(buildMcpAgentConfigOptions(bundle)); return engine.getAgents(); }); safeHandle('mcp:addToAgentConfig', async (_event: unknown, agentId: string) => { const { MCPAgentConfigEngine } = await import('../engine/MCPAgentConfigEngine'); - const engine = new MCPAgentConfigEngine({ - homeDir: require('os').homedir(), - platform: process.platform, - mcpUrl: buildMcpUrl(bundle), - }); + const engine = new MCPAgentConfigEngine(buildMcpAgentConfigOptions(bundle)); return engine.addToConfig(agentId as import('../engine/MCPAgentConfigEngine').MCPAgentId); }); safeHandle('mcp:isConfigured', async (_event: unknown, agentId: string) => { const { MCPAgentConfigEngine } = await import('../engine/MCPAgentConfigEngine'); - const engine = new MCPAgentConfigEngine({ - homeDir: require('os').homedir(), - platform: process.platform, - mcpUrl: buildMcpUrl(bundle), - }); + const engine = new MCPAgentConfigEngine(buildMcpAgentConfigOptions(bundle)); return engine.isConfigured(agentId as import('../engine/MCPAgentConfigEngine').MCPAgentId); }); diff --git a/src/main/main.ts b/src/main/main.ts index 1521ffe..9cb92af 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -1,7 +1,7 @@ import { app, BrowserWindow, Menu, MenuItemConstructorOptions, ipcMain, protocol, net, shell, screen } from 'electron'; import * as path from 'path'; import * as fs from 'fs'; -import { getDatabase } from './database'; +import { getDatabase, initDatabase } from './database'; import { registerIpcHandlers, registerEventForwarding, registerChatHandlers, initializeChatHandlers, cleanupChatHandlers } from './ipc'; import { media } from './database/schema'; import { eq } from 'drizzle-orm'; @@ -901,6 +901,14 @@ app.on('open-url', (event, deepLink) => { // App lifecycle app.whenReady().then(async () => { + // Initialise the database before constructing any engines. + const userData = app.getPath('userData'); + const migrationsFolder = app.isPackaged + ? path.join(process.resourcesPath, 'drizzle') + : path.join(__dirname, '..', '..', 'drizzle'); + const db = initDatabase({ dbPath: path.join(userData, 'bds.db'), migrationsFolder }); + await db.initializeLocal(); + // Construct all engines and build EngineBundle before any initialization const noopNotifier = new NoopNotifier(); const projectEngine = new ProjectEngine(); diff --git a/src/renderer/components/SettingsView/SettingsView.tsx b/src/renderer/components/SettingsView/SettingsView.tsx index a5a0183..ec776a2 100644 --- a/src/renderer/components/SettingsView/SettingsView.tsx +++ b/src/renderer/components/SettingsView/SettingsView.tsx @@ -1257,6 +1257,7 @@ export const SettingsView: React.FC = () => { const renderMCPSettings = () => { const agents = [ { id: 'claude-code', label: 'Claude Code' }, + { id: 'claude-desktop', label: 'Claude Desktop' }, { id: 'github-copilot', label: 'GitHub Copilot' }, { id: 'gemini-cli', label: 'Gemini CLI' }, { id: 'opencode', label: 'OpenCode' },