diff --git a/apps/ui/scripts/prepare-server.mjs b/apps/ui/scripts/prepare-server.mjs index 82309574..db92b385 100644 --- a/apps/ui/scripts/prepare-server.mjs +++ b/apps/ui/scripts/prepare-server.mjs @@ -7,8 +7,8 @@ */ import { execSync } from 'child_process'; -import { cpSync, existsSync, mkdirSync, rmSync, writeFileSync, readFileSync } from 'fs'; -import { join, dirname } from 'path'; +import { cpSync, existsSync, mkdirSync, rmSync, writeFileSync, readFileSync, lstatSync } from 'fs'; +import { join, dirname, resolve } from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); @@ -112,6 +112,29 @@ execSync('npm install --omit=dev', { }, }); +// Step 6b: Replace symlinks for local packages with real copies +// npm install creates symlinks for file: references, but these break when packaged by electron-builder +console.log('🔗 Replacing symlinks with real directory copies...'); +const nodeModulesAutomaker = join(BUNDLE_DIR, 'node_modules', '@automaker'); +for (const pkgName of LOCAL_PACKAGES) { + const pkgDir = pkgName.replace('@automaker/', ''); + const nmPkgPath = join(nodeModulesAutomaker, pkgDir); + try { + // lstatSync does not follow symlinks, allowing us to check for broken ones + if (lstatSync(nmPkgPath).isSymbolicLink()) { + const realPath = resolve(BUNDLE_DIR, 'libs', pkgDir); + rmSync(nmPkgPath); + cpSync(realPath, nmPkgPath, { recursive: true }); + console.log(` ✓ Replaced symlink: ${pkgName}`); + } + } catch (error) { + // If the path doesn't exist, lstatSync throws ENOENT. We can safely ignore this. + if (error.code !== 'ENOENT') { + throw error; + } + } +} + // Step 7: Rebuild native modules for current architecture // This is critical for modules like node-pty that have native bindings console.log('🔨 Rebuilding native modules for current architecture...'); diff --git a/libs/platform/src/system-paths.ts b/libs/platform/src/system-paths.ts index 8c212561..0d900dfa 100644 --- a/libs/platform/src/system-paths.ts +++ b/libs/platform/src/system-paths.ts @@ -750,6 +750,9 @@ export function electronUserDataWriteFileSync( throw new Error('[SystemPaths] Electron userData path not initialized'); } const fullPath = path.join(electronUserDataPath, relativePath); + // Ensure parent directory exists (may not exist on first launch) + const dir = path.dirname(fullPath); + fsSync.mkdirSync(dir, { recursive: true }); fsSync.writeFileSync(fullPath, data, options); }