Skip to content

Commit 40d306e

Browse files
committed
feat: Introduce isolated session management through a CLI flag and session-prefixed storage keys.
1 parent 5152762 commit 40d306e

8 files changed

Lines changed: 697 additions & 658 deletions

File tree

electron/main.cjs

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ function startAgentServer() {
1818
}
1919

2020
const agentServerPath = path.join(__dirname, '..', 'agent-server.js');
21-
21+
2222
// Check if agent-server.js exists
2323
if (!fsSync.existsSync(agentServerPath)) {
2424
console.error('[Electron] Agent server not found at:', agentServerPath);
2525
return;
2626
}
2727

2828
console.log('[Electron] Starting agent server...');
29-
29+
3030
// Fork the agent server as a child process
3131
// Using fork with execArgv to handle ES modules
3232
agentServerProcess = fork(agentServerPath, [], {
@@ -76,6 +76,13 @@ if (isTestMode) {
7676
console.log('[Electron] Test mode enabled via --test flag');
7777
}
7878

79+
// Check for --session flag in command-line arguments (e.g. --session=mySession)
80+
const sessionArg = process.argv.find(arg => arg.startsWith('--session='));
81+
const sessionName = sessionArg ? sessionArg.split('=')[1] : null;
82+
if (sessionName) {
83+
console.log(`[Electron] Starting with isolated session: ${sessionName}`);
84+
}
85+
7986
let mainWindow = null;
8087

8188
// ============================================================
@@ -96,7 +103,7 @@ const getRedstringDocumentsPath = () => {
96103
const ensureDirectories = async () => {
97104
const dataPath = getRedstringDataPath();
98105
const docsPath = getRedstringDocumentsPath();
99-
106+
100107
try {
101108
await fs.mkdir(dataPath, { recursive: true });
102109
await fs.mkdir(docsPath, { recursive: true });
@@ -169,17 +176,25 @@ function createWindow() {
169176
if (isDev) {
170177
// Wait for Vite to be ready (handled by script usually, but good to have fallback)
171178
// The port 4001 is from the existing vite.config.js
172-
const devUrl = isTestMode ? 'http://localhost:4001?test=true' : 'http://localhost:4001';
179+
let devUrl = 'http://localhost:4001';
180+
const params = [];
181+
if (isTestMode) params.push('test=true');
182+
if (sessionName) params.push(`session=${encodeURIComponent(sessionName)}`);
183+
184+
if (params.length > 0) {
185+
devUrl += '?' + params.join('&');
186+
}
187+
173188
mainWindow.loadURL(devUrl);
174189
mainWindow.webContents.openDevTools();
175190
} else {
176191
// In production, load the built index.html
177192
const indexPath = path.join(__dirname, '../dist/index.html');
178-
if (isTestMode) {
179-
mainWindow.loadFile(indexPath, { query: { test: 'true' } });
180-
} else {
181-
mainWindow.loadFile(indexPath);
182-
}
193+
const query = {};
194+
if (isTestMode) query.test = 'true';
195+
if (sessionName) query.session = sessionName;
196+
197+
mainWindow.loadFile(indexPath, { query });
183198
}
184199
}
185200

@@ -288,7 +303,7 @@ function createMenu() {
288303
ipcMain.handle('file:pick', async (event, options = {}) => {
289304
// Default to Redstring documents folder
290305
const defaultPath = options.defaultPath || getRedstringDocumentsPath();
291-
306+
292307
const result = await dialog.showOpenDialog(mainWindow, {
293308
properties: ['openFile'],
294309
defaultPath: defaultPath,
@@ -310,9 +325,9 @@ ipcMain.handle('file:pick', async (event, options = {}) => {
310325
ipcMain.handle('file:saveAs', async (event, options = {}) => {
311326
const { suggestedName } = options;
312327
// Default to Redstring documents folder with suggested name
313-
const defaultPath = options.defaultPath ||
328+
const defaultPath = options.defaultPath ||
314329
path.join(getRedstringDocumentsPath(), suggestedName || 'untitled.redstring');
315-
330+
316331
const result = await dialog.showSaveDialog(mainWindow, {
317332
defaultPath: defaultPath,
318333
filters: [
@@ -442,11 +457,11 @@ function handleOAuthCallback(url) {
442457
const code = urlObj.searchParams.get('code');
443458
const state = urlObj.searchParams.get('state');
444459
const error = urlObj.searchParams.get('error');
445-
460+
446461
if (mainWindow && !mainWindow.isDestroyed()) {
447462
mainWindow.webContents.send('oauth:callback', { code, state, error });
448463
}
449-
464+
450465
if (oauthCallbackResolve) {
451466
oauthCallbackResolve({ code, state, error });
452467
oauthCallbackResolve = null;

0 commit comments

Comments
 (0)