From 262b295f63277faead24a88adf44593c4fa2ef79 Mon Sep 17 00:00:00 2001 From: 7418 <7418@openclaw.ai> Date: Sat, 7 Feb 2026 13:07:08 +0800 Subject: [PATCH] fix: use stable ~/.codepilot/ data directory to persist across updates Previously the database path depended on app.getPath('userData') which varies with app name changes (CodePilot vs codepilot vs Claude GUI). Now uses a fixed ~/.codepilot/ directory for both dev and production. Includes automatic migration: on first launch, if the DB doesn't exist at the new path, it checks old locations (Application Support variants and the old dev-mode data/ folder) and copies the database over. Co-Authored-By: Claude Opus 4.6 --- electron/main.ts | 2 +- src/lib/db.ts | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/electron/main.ts b/electron/main.ts index c13e150..4bbf332 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -116,7 +116,7 @@ function startServer(port: number): ChildProcess { ...userShellEnv, PORT: String(port), HOSTNAME: '127.0.0.1', - CLAUDE_GUI_DATA_DIR: app.getPath('userData'), + CLAUDE_GUI_DATA_DIR: path.join(home, '.codepilot'), ELECTRON_RUN_AS_NODE: '1', HOME: home, PATH: `${basePath}:${home}/.npm-global/bin:${home}/.local/bin:${home}/.claude/bin:${shellPath}`, diff --git a/src/lib/db.ts b/src/lib/db.ts index c4baaeb..b16c934 100644 --- a/src/lib/db.ts +++ b/src/lib/db.ts @@ -3,7 +3,7 @@ import path from 'path'; import crypto from 'crypto'; import type { ChatSession, Message, SettingsMap, TaskItem, TaskStatus } from '@/types'; -const dataDir = process.env.CLAUDE_GUI_DATA_DIR || path.join(process.cwd(), 'data'); +const dataDir = process.env.CLAUDE_GUI_DATA_DIR || path.join(require('os').homedir(), '.codepilot'); const DB_PATH = path.join(dataDir, 'codepilot.db'); let db: Database.Database | null = null; @@ -11,11 +11,42 @@ let db: Database.Database | null = null; export function getDb(): Database.Database { if (!db) { const fs = require('fs'); + const os = require('os'); const dir = path.dirname(DB_PATH); if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } + // Migrate from old locations if the new DB doesn't exist yet + if (!fs.existsSync(DB_PATH)) { + const home = os.homedir(); + const oldPaths = [ + // Old Electron userData paths (app.getPath('userData')) + path.join(home, 'Library', 'Application Support', 'CodePilot', 'codepilot.db'), + path.join(home, 'Library', 'Application Support', 'codepilot', 'codepilot.db'), + path.join(home, 'Library', 'Application Support', 'Claude GUI', 'codepilot.db'), + // Old dev-mode fallback + path.join(process.cwd(), 'data', 'codepilot.db'), + // Legacy name + path.join(home, 'Library', 'Application Support', 'CodePilot', 'claude-gui.db'), + path.join(home, 'Library', 'Application Support', 'codepilot', 'claude-gui.db'), + ]; + for (const oldPath of oldPaths) { + if (fs.existsSync(oldPath)) { + try { + fs.copyFileSync(oldPath, DB_PATH); + // Also copy WAL/SHM if they exist + if (fs.existsSync(oldPath + '-wal')) fs.copyFileSync(oldPath + '-wal', DB_PATH + '-wal'); + if (fs.existsSync(oldPath + '-shm')) fs.copyFileSync(oldPath + '-shm', DB_PATH + '-shm'); + console.log(`[db] Migrated database from ${oldPath}`); + break; + } catch (err) { + console.warn(`[db] Failed to migrate from ${oldPath}:`, err); + } + } + } + } + db = new Database(DB_PATH); db.pragma('journal_mode = WAL'); db.pragma('foreign_keys = ON');