feat(core): isolate dev and production environments

- Add IS_DEV_ENVIRONMENT flag to paths.ts for automatic detection
- Dev uses 'Gemini Nexus Dev' app data dir and '.geminiNexus-agent-dev' agent dir
- Dev proxy defaults to port 8046, production stays on 8045
- Move app.setName() before packetLogPath to ensure correct userData path
- Config, DB, logs, and ORPC packets fully isolated between dev and prod
This commit is contained in:
Gemini Nexus Bot committed 2026-05-02 00:28:22 -03:00
1 parent bf5a42c03e
commit 5c44a622a8
4 files changed
+38 -22

No files matched your search

+8 -6
View File
@@ -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();
+5 -6
View File
@@ -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');
+6 -1
View File
@@ -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<boolean> {
const port = config.port || 8045;
const port = config.port || DEFAULT_PORT;
if (app) {
logger.info('NestJS server already running.');
return true;
+19 -9
View File
@@ -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 {