diff --git a/.npmrc b/.npmrc
new file mode 100644
index 00000000..b6f27f13
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1 @@
+engine-strict=true
diff --git a/docs/installation.md b/docs/installation.md
index 24091423..07e16af8 100644
--- a/docs/installation.md
+++ b/docs/installation.md
@@ -20,3 +20,49 @@ Download the latest release for your platform from the [Releases](https://github
- [OpenAI Codex](https://github.com/openai/codex) - OpenAI's coding agent
- [OpenCode](https://github.com/sst/opencode) - Open-source AI coding assistant
- Git (optional, for git-aware features)
+
+## WSL2 Users (Windows Subsystem for Linux)
+
+
+When developing or running Maestro with WSL2, always clone and run from the **native Linux filesystem** (e.g., `/home/username/maestro`), NOT from Windows-mounted paths (`/mnt/c/...`, `/mnt/d/...`).
+
+
+Using Windows mounts causes several critical issues:
+
+| Issue | Symptom |
+|-------|---------|
+| Socket binding failures | `EPERM: operation not permitted` when starting dev server |
+| Electron sandbox crashes | `FATAL:sandbox_host_linux.cc` errors |
+| npm install failures | Timeouts, `ENOTEMPTY` rename errors |
+| Git corruption | Missing index files, spurious lock files |
+
+### Recommended WSL2 Setup
+
+```bash
+# Clone to Linux filesystem (not /mnt/...)
+cd ~
+git clone https://github.com/pedramamini/maestro.git
+cd maestro
+
+# Install dependencies
+npm install
+
+# Run in development mode
+npm run dev
+```
+
+### Accessing Files from Windows
+
+You can browse your WSL2 files from Windows Explorer using:
+```
+\\wsl$\Ubuntu\home\\maestro
+```
+
+### Troubleshooting WSL2
+
+If you encounter `electron-rebuild` failures, try setting the temp directory:
+```bash
+TMPDIR=/tmp npm run rebuild
+```
+
+For persistent issues, see [Troubleshooting](./troubleshooting) for additional WSL-specific guidance
diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md
index 7e1384de..953d973c 100644
--- a/docs/troubleshooting.md
+++ b/docs/troubleshooting.md
@@ -78,6 +78,63 @@ The debug package is designed to be **safe to share publicly**:
- Before: `/Users/johndoe/Projects/MyApp`
- After: `~/Projects/MyApp`
+## WSL2 Issues (Windows)
+
+If you're running Maestro through WSL2, most issues stem from using Windows-mounted paths. See the [WSL2 installation guide](./installation#wsl2-users-windows-subsystem-for-linux) for the recommended setup.
+
+### Common WSL2 Problems
+
+**"EPERM: operation not permitted" on socket binding**
+
+The Vite dev server or Electron cannot bind to ports when running from `/mnt/...` paths.
+
+**Solution:** Move your project to the native Linux filesystem:
+```bash
+mv /mnt/c/projects/maestro ~/maestro
+cd ~/maestro
+npm install
+npm run dev
+```
+
+**"FATAL:sandbox_host_linux.cc" Electron crash**
+
+The Electron sandbox cannot operate correctly on Windows-mounted filesystems.
+
+**Solution:** Run from the Linux filesystem (`/home/...`), not from `/mnt/...`.
+
+**npm install timeouts or ENOTEMPTY errors**
+
+Cross-filesystem operations between WSL and Windows are unreliable for npm's file operations.
+
+**Solution:** Clone and install from the Linux filesystem:
+```bash
+cd ~
+git clone https://github.com/pedramamini/maestro.git
+cd maestro
+npm install
+```
+
+**electron-rebuild failures**
+
+The Windows temp directory may be inaccessible from WSL.
+
+**Solution:** Override the temp directory:
+```bash
+TMPDIR=/tmp npm run rebuild
+```
+
+**Git index corruption or lock file errors**
+
+NTFS and Linux inode handling are incompatible, causing git metadata issues.
+
+**Solution:** If you see "missing index" or spurious `.git/index.lock` errors:
+```bash
+rm -f .git/index.lock
+git checkout -f
+```
+
+For new projects, always clone to the Linux filesystem from the start.
+
## Getting Help
- **GitHub Issues**: [Report bugs or request features](https://github.com/pedramamini/Maestro/issues)
diff --git a/package.json b/package.json
index 6dbc85c4..05b5ffbb 100644
--- a/package.json
+++ b/package.json
@@ -289,5 +289,8 @@
"vite": "^5.0.11",
"vite-plugin-electron": "^0.28.2",
"vitest": "^4.0.15"
+ },
+ "engines": {
+ "node": ">=20.0.0"
}
}
diff --git a/src/main/index.ts b/src/main/index.ts
index 4aebd209..084a377e 100644
--- a/src/main/index.ts
+++ b/src/main/index.ts
@@ -24,6 +24,7 @@ import { DEMO_MODE, DEMO_DATA_PATH } from './constants';
import type { SshRemoteConfig } from '../shared/types';
import { initAutoUpdater } from './auto-updater';
import { readDirRemote, readFileRemote, statRemote, directorySizeRemote } from './utils/remote-fs';
+import { checkWslEnvironment } from './utils/wslDetector';
// ============================================================================
// Custom Storage Location Configuration
@@ -738,6 +739,9 @@ app.whenReady().then(async () => {
logLevel
});
+ // Check for WSL + Windows mount issues early
+ checkWslEnvironment(process.cwd());
+
// Initialize core services
logger.info('Initializing core services', 'Startup');
processManager = new ProcessManager();
diff --git a/src/main/utils/wslDetector.ts b/src/main/utils/wslDetector.ts
new file mode 100644
index 00000000..93ef5359
--- /dev/null
+++ b/src/main/utils/wslDetector.ts
@@ -0,0 +1,93 @@
+import * as fs from 'fs';
+import { logger } from './logger';
+
+/**
+ * WSL (Windows Subsystem for Linux) environment detection utilities.
+ *
+ * When running in WSL2, using Windows-mounted paths (/mnt/c, /mnt/d, etc.)
+ * causes critical issues with Electron, socket binding, npm, and git.
+ * These utilities help detect and warn about such configurations.
+ */
+
+let wslDetectionCache: boolean | null = null;
+
+/**
+ * Detect if the current environment is WSL (Windows Subsystem for Linux).
+ * Result is cached after first call.
+ */
+export function isWsl(): boolean {
+ if (wslDetectionCache !== null) {
+ return wslDetectionCache;
+ }
+
+ if (process.platform !== 'linux') {
+ wslDetectionCache = false;
+ return false;
+ }
+
+ try {
+ if (fs.existsSync('/proc/version')) {
+ const version = fs.readFileSync('/proc/version', 'utf8').toLowerCase();
+ wslDetectionCache = version.includes('microsoft') || version.includes('wsl');
+ return wslDetectionCache;
+ }
+ } catch {
+ // Ignore read errors
+ }
+
+ wslDetectionCache = false;
+ return false;
+}
+
+/**
+ * Check if a path is on a Windows-mounted filesystem in WSL.
+ * Windows mounts are typically at /mnt/c, /mnt/d, etc.
+ */
+export function isWindowsMountPath(filepath: string): boolean {
+ return /^\/mnt\/[a-zA-Z](\/|$)/.test(filepath);
+}
+
+/**
+ * Check if running from a Windows mount in WSL and log a warning.
+ * This should be called early in the application lifecycle.
+ *
+ * @param cwd - The current working directory to check
+ * @returns true if running from a problematic Windows mount path
+ */
+export function checkWslEnvironment(cwd: string): boolean {
+ if (!isWsl()) {
+ return false;
+ }
+
+ if (isWindowsMountPath(cwd)) {
+ logger.warn(
+ '[WSL] Running from Windows mount path - this may cause socket binding failures, ' +
+ 'Electron sandbox crashes, npm install issues, and git corruption. ' +
+ 'Consider moving your project to the Linux filesystem (e.g., ~/projects/maestro).',
+ 'WSLDetector',
+ { cwd }
+ );
+ return true;
+ }
+
+ logger.debug('[WSL] Running from Linux filesystem - OK', 'WSLDetector', { cwd });
+ return false;
+}
+
+/**
+ * Get a user-friendly warning message for WSL + Windows mount issues.
+ */
+export function getWslWarningMessage(): string {
+ return (
+ 'You appear to be running Maestro from a Windows-mounted path in WSL2. ' +
+ 'This configuration causes critical issues including:\n\n' +
+ '• Socket binding failures (dev server won\'t start)\n' +
+ '• Electron sandbox crashes\n' +
+ '• npm install failures\n' +
+ '• Git index corruption\n\n' +
+ 'Please move your project to the Linux filesystem:\n' +
+ ' mv /mnt/c/projects/maestro ~/maestro\n' +
+ ' cd ~/maestro && npm install\n\n' +
+ 'See: https://docs.runmaestro.ai/installation#wsl2-users-windows-subsystem-for-linux'
+ );
+}
diff --git a/src/renderer/components/FileExplorerPanel.tsx b/src/renderer/components/FileExplorerPanel.tsx
index 7d664fd8..eededd73 100644
--- a/src/renderer/components/FileExplorerPanel.tsx
+++ b/src/renderer/components/FileExplorerPanel.tsx
@@ -650,10 +650,10 @@ function FileExplorerPanelInner(props: FileExplorerPanelProps) {
{/* Status bar at bottom */}
{session.fileTreeStats && (