Single-Instance Enforcement
OpenWork enforces a single-instance policy across the entire application. This prevents multiple instances from running simultaneously and ensures users always interact with the same application window.
Implementation
The single-instance enforcement is implemented at the Electron application level using app.requestSingleInstanceLock():
Source: /Users/nateb/openwork-repo/apps/desktop/src/main/index.ts
// Single instance lock
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {
console.log('[Main] Second instance attempted; quitting');
app.quit();
} else {
app.on('second-instance', () => {
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore();
mainWindow.focus();
console.log('[Main] Focused existing instance after second-instance event');
}
});
// ... rest of app initialization
}
Behavior
First Instance Launch
- Successfully acquires the single instance lock
- Proceeds with normal application initialization
- Creates the main window and loads the UI
Second Instance Attempt
- Fails to acquire the lock
- Automatically quits with exit code 0
- Logs diagnostic message: “Second instance attempted; quitting”
Existing Instance Reactivation
- When a second instance is launched, it triggers the
second-instanceevent - The existing window is restored (if minimized)
- The window is brought to focus
- User seamlessly transitions to the existing running instance
Benefits
- Resource Efficiency: Prevents duplicate memory usage and CPU consumption
- Data Consistency: Ensures settings, API keys, and task history remain consistent
- User Experience: No confusion between multiple application windows
- Clean State: Prevents conflicts during file operations and IPC communication
Technical Details
Platform Support
- macOS: Uses native OS-level single instance enforcement
- Windows: Uses Windows-specific single instance mechanisms
- Linux: Uses cross-platform Electron implementation
Integration with Protocol Handler
The single-instance enforcement works seamlessly with the custom protocol handler (accomplish://). When a deep link is opened:
- If no instance is running, a new instance is launched
- If an instance is running, it’s focused and the protocol URL is processed
Configuration
No configuration is required. The behavior is enabled by default in all builds.
Debugging
When debugging in development mode, you can observe the single instance behavior:
# Terminal 1 - Launch first instance
pnpm dev
# Terminal 2 - Attempt second instance
pnpm dev
# Output: [Main] Second instance attempted; quitting
Limitations
- The enforcement is application-level, not user-level (only one instance per user)
- Terminal-based invocations also respect the single instance lock
- The behavior is consistent across development and production builds