diff --git a/src/main.ts b/src/main.ts index c67e540..8cf52dc 100644 --- a/src/main.ts +++ b/src/main.ts @@ -30,6 +30,12 @@ import { ConfigManager } from './ipc/config/manager'; import { AppConfig } from './types/config'; import { isAutoStartLaunch, syncAutoStart } from './utils/autoStart'; import { safeStringifyPacket } from './utils/sensitiveDataMasking'; +import { IS_DEV_ENVIRONMENT } from './utils/paths'; + +// Set app name early so Electron's userData path reflects the environment +if (IS_DEV_ENVIRONMENT) { + app.setName('Gemini Nexus Dev'); +} const packetLogPath = path.join(app.getPath('userData'), 'orpc_packets.log'); @@ -63,7 +69,7 @@ if (squirrelStartup) { process.exit(0); } -const inDevelopment = process.env.NODE_ENV === 'development'; +const inDevelopment = IS_DEV_ENVIRONMENT; const debugHttpProxy = process.env.http_proxy?.trim() || process.env.HTTP_PROXY?.trim(); const debugHttpsProxy = process.env.https_proxy?.trim() || process.env.HTTPS_PROXY?.trim(); const debugNoProxy = process.env.no_proxy?.trim() || process.env.NO_PROXY?.trim(); @@ -167,11 +173,7 @@ function showWindowsInstallNoticeIfNeeded() { }); } -const isDev = process.env.NODE_ENV === 'development' || !app.isPackaged; - -if (isDev) { - app.setName('Gemini Nexus Dev'); -} +const isDev = IS_DEV_ENVIRONMENT; const gotSingleInstanceLock = app.requestSingleInstanceLock(); diff --git a/src/preload.ts b/src/preload.ts index fbc32a1..d971d91 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -10,16 +10,15 @@ import os from 'os'; let sentryEnabled = false; try { const home = os.homedir(); + const isDev = process.env.NODE_ENV === 'development'; + const appName = isDev ? 'Gemini Nexus Dev' : 'Gemini Nexus'; let appDataPath = ''; if (process.platform === 'win32') { - appDataPath = path.join( - process.env.APPDATA || path.join(home, 'AppData', 'Roaming'), - 'Gemini Nexus', - ); + appDataPath = path.join(process.env.APPDATA || path.join(home, 'AppData', 'Roaming'), appName); } else if (process.platform === 'darwin') { - appDataPath = path.join(home, 'Library', 'Application Support', 'Gemini Nexus'); + appDataPath = path.join(home, 'Library', 'Application Support', appName); } else { - appDataPath = path.join(home, '.config', 'Gemini Nexus'); + appDataPath = path.join(home, '.config', appName); } const configPath = path.join(appDataPath, 'gui_config.json'); diff --git a/src/server/main.ts b/src/server/main.ts index af0ea2a..2ecfef6 100644 --- a/src/server/main.ts +++ b/src/server/main.ts @@ -9,11 +9,16 @@ import { ProxyConfig } from '../types/config'; import { setServerConfig } from './server-config'; import { registerApiLogging } from './logging/api-logging.plugin'; +import { IS_DEV_ENVIRONMENT } from '../utils/paths'; + let app: NestFastifyApplication | null = null; let currentPort: number = 0; +/** Default port: 8046 in development, 8045 in production */ +const DEFAULT_PORT = IS_DEV_ENVIRONMENT ? 8046 : 8045; + export async function bootstrapNestServer(config: ProxyConfig): Promise { - const port = config.port || 8045; + const port = config.port || DEFAULT_PORT; if (app) { logger.info('NestJS server already running.'); return true; diff --git a/src/utils/paths.ts b/src/utils/paths.ts index bcd0dd2..5c73067 100644 --- a/src/utils/paths.ts +++ b/src/utils/paths.ts @@ -3,6 +3,16 @@ import os from 'os'; import fs from 'fs'; import { execSync } from 'child_process'; +/** + * Detects whether the app is running in development mode. + * Uses NODE_ENV as the single source of truth. This is evaluated once + * at module load time so every consumer gets a consistent answer. + */ +export const IS_DEV_ENVIRONMENT = process.env.NODE_ENV === 'development'; + +/** Directory name suffix applied in development to isolate from production data. */ +const DEV_SUFFIX = ' Dev'; + /** * Checks if the current platform is WSL. * @returns {boolean} True if the current platform is WSL, false otherwise. @@ -75,29 +85,29 @@ function getWindowsUser(): string { export function getAppDataDir(): string { const home = os.homedir(); + const appName = IS_DEV_ENVIRONMENT ? `Gemini Nexus${DEV_SUFFIX}` : 'Gemini Nexus'; if (isWsl()) { const winUser = getWindowsUser(); - return `/mnt/c/Users/${winUser}/AppData/Roaming/GeminiNexus`; + const wslName = IS_DEV_ENVIRONMENT ? 'GeminiNexusDev' : 'GeminiNexus'; + return `/mnt/c/Users/${winUser}/AppData/Roaming/${wslName}`; } switch (process.platform) { case 'darwin': - return path.join(home, 'Library', 'Application Support', 'Gemini Nexus'); + return path.join(home, 'Library', 'Application Support', appName); case 'win32': - return path.join( - process.env.APPDATA || path.join(home, 'AppData', 'Roaming'), - 'Gemini Nexus', - ); + return path.join(process.env.APPDATA || path.join(home, 'AppData', 'Roaming'), appName); case 'linux': - return path.join(home, '.config', 'Gemini Nexus'); + return path.join(home, '.config', appName); default: - return path.join(home, '.geminiNexus'); + return path.join(home, IS_DEV_ENVIRONMENT ? '.geminiNexusDev' : '.geminiNexus'); } } export function getAgentDir(): string { - return path.join(os.homedir(), '.geminiNexus-agent'); + const dirName = IS_DEV_ENVIRONMENT ? '.geminiNexus-agent-dev' : '.geminiNexus-agent'; + return path.join(os.homedir(), dirName); } export function getAccountsFilePath(): string {