diff --git a/packages/cli/src/commands/desktop.ts b/packages/cli/src/commands/desktop.ts index 25738d24cd..38f8aeacc3 100644 --- a/packages/cli/src/commands/desktop.ts +++ b/packages/cli/src/commands/desktop.ts @@ -5,6 +5,7 @@ import { dirname, isAbsolute, join, resolve } from "node:path"; import type { AddressInfo } from "node:net"; import { createRequire } from "node:module"; import { fileURLToPath } from "node:url"; +import * as os from "node:os"; import { CentralCore, TaskStore } from "@fusion/core"; import { createServer } from "@fusion/dashboard"; import { ProjectEngineManager } from "@fusion/engine"; @@ -177,7 +178,16 @@ export async function runDesktop(options: RunDesktopOptions = {}): Promise const runtime = await startDashboardRuntime(rootDir, Boolean(options.paused), Boolean(options.noAuth)); const electronBinary = resolveElectronBinary(); - const electronArgs = ["--enable-source-maps", desktopEntry, ...(options.dev ? ["--dev"] : [])]; + const electronArgs = [ + "--enable-source-maps", + desktopEntry, + "--disable-gpu", + "--disable-gpu-compositing", + "--disable-gpu-sandbox", + "--disable-software-rasterizer", + "--no-sandbox", + ...(options.dev ? ["--dev"] : []), + ]; // Build environment for Electron process const electronEnv: NodeJS.ProcessEnv = { diff --git a/packages/desktop/src/main.ts b/packages/desktop/src/main.ts index 84b8cb58cf..17b30df6b0 100644 --- a/packages/desktop/src/main.ts +++ b/packages/desktop/src/main.ts @@ -1,6 +1,18 @@ import { app, BrowserWindow, nativeImage, screen, Tray } from "electron"; import { join, resolve } from "node:path"; import { fileURLToPath } from "node:url"; +import os from "node:os"; + +const fusionUserDataDir = join(os.homedir(), ".fusion", "desktop-user-data"); +try { + app.commandLine.appendSwitch("user-data-dir", fusionUserDataDir); + app.setPath("userData", fusionUserDataDir); + app.setPath("cache", join(fusionUserDataDir, "cache")); + app.setPath("crashDumps", join(fusionUserDataDir, "crashes")); +} catch { + // Path already locked after app is ready; not a fatal error. +} + import { setupDeepLinkHandler, registerDeepLinkProtocol } from "./deep-link.js"; import { registerIpcHandlers } from "./ipc.js"; import { buildAppMenu } from "./menu.js"; @@ -199,7 +211,7 @@ export async function initializeApp(): Promise { } } - if (rememberedLaunchMode === "local") { + if (rememberedLaunchMode === "local" && !process.env.FUSION_SERVER_PORT) { try { await startLocalRuntimeOnce(); } catch (error) { @@ -216,6 +228,12 @@ export async function initializeApp(): Promise { currentDesktopLaunchMode = "local"; } + if (currentDesktopLaunchMode === "choose" && process.env.FUSION_SERVER_PORT) { + // The CLI already started a dashboard server; use it without spawning an + // embedded local runtime. The shell state will report external-cli running. + currentDesktopLaunchMode = "local"; + } + const windowState = state ? clampWindowStateToVisibleDisplay( state, diff --git a/reports/desktop-release-issues-2026-07-03.md b/reports/desktop-release-issues-2026-07-03.md new file mode 100644 index 0000000000..3c71d701cc --- /dev/null +++ b/reports/desktop-release-issues-2026-07-03.md @@ -0,0 +1,178 @@ +# Fusion Desktop Release Issues — Field Report + +**Date:** 2026-07-03 +**Reporter:** Hermes Ouroboros / Automata Intelligentsia +**Host:** Windows 11 (build 26200) +**Fusion versions observed:** 0.51.0 (last known good), 0.52.0 (current desktop release with regressions) +**Test environment:** `C:\Users\drewd\Tools\fusion-latest` (local source checkout), `npm install -g @runfusion/fusion` published package, and the v1.1.0 standalone desktop wrapper. + +This document collects the issues we found while trying to run the official Fusion desktop build on Windows, what we attempted, and what we believe the Fusion team needs to address. + +--- + +## Issue 1: `fusion desktop` fails to launch on Windows 0.52.0 + +### Symptom +Running `fusion desktop` from the published npm package immediately errors out with a dynamic require / Electron binary resolution failure. The CLI cannot find `electron` because the published `@runfusion/fusion` package lists `electron` only as a `devDependency`, not a runtime dependency. + +### What we tried +1. Installed `@runfusion/fusion@latest` globally. +2. Ran `fusion desktop --no-auth` from a project directory. +3. Observed that `require('electron')` fails because Electron is not installed alongside the published CLI. +4. Checked `packages/cli/package.json` in the source repo: `electron` is under `devDependencies`. + +### Proposed fix +Add `electron` to the `dependencies` (or `optionalDependencies`) of `@runfusion/fusion` so that a global npm install pulls in the Electron binary required by `packages/cli/src/commands/desktop.ts`. + +--- + +## Issue 2: Native desktop build walks ancestor directories and fails on unrelated workspace JSON + +### Symptom +When `fusion desktop` does manage to start the native Electron build, the launcher walks up the directory tree looking for a Fusion workspace. It can land on an unrelated ancestor directory (e.g., `C:\Users\drewd\Tools`) and fail because it parses JSON files in sibling or parent workspaces that are not valid Fusion project assets. + +### What we tried +1. Ran `fusion desktop` from `C:\Users\drewd\Tools\fusion-latest`. +2. The launcher searched ancestor directories instead of using the current working directory as the project root. +3. It then choked on invalid JSON in assets that were never intended to be loaded as Fusion metadata. + +### Proposed fix +- Restrict workspace discovery to the current working directory or a user-selected/project-configured root. +- Treat missing/invalid JSON as non-fatal during workspace discovery; log and continue rather than crashing the launcher. +- Add a CLI flag or config key to pin the project root explicitly. + +--- + +## Issue 3: Manage Projects button opens Settings instead of the project overview + +### Symptom +In the dashboard header, clicking **Manage Projects** lands on the **Settings** page instead of the project list/overview. + +### Root cause +`handleViewAllProjects` in `packages/dashboard/app/hooks/useProjectActions.ts` resets `viewMode` to `"overview"` and clears the current project, but it leaves `taskView` unchanged. `MainContent` checks `taskView === "settings"` before the `viewMode === "overview"` branch, so any previously selected settings view is rendered instead of `ProjectOverview`. + +### What we tried +- Traced the routing through `App.tsx`, `useProjectActions.ts`, `useViewState.ts`, and `MainContent.tsx`. +- Threaded `setTaskView` into `useProjectActions` and reset `taskView` to `"command-center"` when leaving a project. + +### Proposed fix +Apply the same fix as PR #1882: make `handleViewAllProjects` reset `taskView` to the overview landing view so the settings branch cannot shadow the overview branch. + +--- + +## Issue 4: Windows Terminal native "Help" version dialogs on dashboard load / Settings + +### Symptom +On Windows, opening the dashboard (and especially the Settings page) produces two native Windows message boxes titled **Help**, showing: + +``` +Windows Terminal +1.24.11321.0 +``` + +### Root cause +The dashboard’s `useTerminalSessions` hook auto-creates the first terminal tab once session validation completes. On Windows, spawning a PTY can end up invoking `wt.exe` (Windows Terminal) or otherwise triggering its built-in version/help dialog. The backend `terminal-service.ts` already has an FNXC guard (FNXC:WindowsTerminalStartup) to avoid probing `wt.exe`, but the frontend auto-create path still triggers a PTY spawn on Windows before the user has asked for a terminal. + +### What we tried +- Confirmed `terminal-service.ts` skips Windows Terminal for `SHELL` on `win32`. +- Confirmed tests already assert `wt.exe` should not be selected. +- Disabled the auto-create path on Windows in `useTerminalSessions.ts` so the failure cannot recur automatically. Manual terminal creation still works and surfaces the inline error UI. + +### Proposed fix +Merge the frontend guard from PR #1882, or move the platform check server-side so no terminal session is auto-created for Windows users unless the platform has a verified embedded shell. + +--- + +## Issue 5: `fusion desktop` native build uses the wrong working directory for `preload.cjs` and other Electron assets + +### Symptom +The packaged native desktop build can fail to load `preload.cjs` because the packaged app looks under `release/win-unpacked/resources/app.asar.unpacked/electron/`, but that path may be incomplete after `npm run dist`. + +### What we tried +- Extracted the published v1.0.0 wrapper source and compared it to the source tree. +- Found that `apps/desktop/electron/preload.cjs` exists in source but is missing in the packaged layout on some installs. +- Confirmed the workaround: copy `preload.cjs` into the missing unpacked location. + +### Proposed fix +- Add a packaging verification step that asserts `preload.cjs` is present in the expected unpacked path before publishing. +- Consider bundling the preload script into the main asar so the path is deterministic. +- Document the Windows packaging layout and the required Electron files. + +--- + +## Issue 6: Native desktop build runs on port 9119/8643 but conflicts with dashboard and other instances + +### Symptom +On Windows, the dashboard backend can end up on a non-standard port or collide with another running dashboard instance (e.g., 9120, 7380–7385). The packaged desktop also expects gateway 8643 and dashboard 9119 per the docs, but the actual port can drift. + +### What we tried +- Used `Get-NetTCPConnection` to map ports to process names because `ps`/`netstat` in MSYS mis-enumerate Electron/pythonw/WSL processes. +- Found that duplicate dashboard processes can occur when system Python and venv Python both try to start on the same port. + +### Proposed fix +- Lock down the desktop build to deterministic ports with a port-file lock or named mutex on Windows. +- Show a clear error when another Fusion desktop/dashboard is already running instead of silently binding elsewhere. +- Document the canonical Windows ports and how to audit them. + +--- + +## Issue 7: GPU/sandbox rendering issues on Windows Electron + +### Symptom +The native desktop window can be blank, flicker, or fail to render on some Windows GPUs. We observed this both with the wrapper and the native desktop build. + +### What we tried +- Added Electron flags to disable GPU and sandbox in the wrapper and native launch path: + - `--disable-gpu` + - `--disable-gpu-compositing` + - `--disable-gpu-sandbox` + - `--disable-software-rasterizer` + - `--no-sandbox` +- These flags improved stability in the wrapper. + +### Proposed fix +- Expose these flags as the default on Windows, or make them configurable in the dashboard settings. +- Detect GPU process crashes and automatically fall back to software rendering with a toast notification. + +--- + +## Issue 8: Desktop user-data path is not isolated / collides with other Electron apps + +### Symptom +Crash dumps, caches, and local storage from the Fusion desktop can end up in a generic Electron user-data directory or collide with other Electron apps using the same defaults. + +### What we tried +- Set `app.setPath("userData", "...")` to `~/.fusion/desktop-user-data` and sub-paths for cache/crashes in the wrapper. + +### Proposed fix +- Apply the same isolation in the native desktop build so sessions, logs, and crash data live under `~/.fusion/` and are easy to inspect or reset without affecting other Electron apps. + +--- + +## Issue 9: CLI desktop command does not reuse an already-running dashboard server + +### Symptom +Running `fusion desktop` while `fusion dashboard` (or the wrapper) is already serving on 4040 starts a second process rather than connecting to the existing one. + +### What we tried +- Modified `packages/desktop/src/main.ts` to detect `FUSION_SERVER_PORT` and skip `startLocalRuntimeOnce` when the CLI already started a server. + +### Proposed fix +- Add a stable port probe / heartbeat before starting the Electron runtime. +- If a dashboard is already running on the expected port, load that URL instead of spawning another engine. + +--- + +## General recommendations for the Fusion team + +1. **Windows CI:** Add a Windows build step that runs `fusion desktop` in a clean VM and asserts the window title is visible and responsive. +2. **Release tests:** Before tagging a desktop release, verify the packaged `release/win-unpacked` layout has all required Electron assets (`preload.cjs`, etc.). +3. **Dependency audit:** Move `electron` out of `devDependencies` in the published CLI package, or document that users must install it separately. +4. **Field test with wrapper users:** The wrapper at `https://github.com/Automata-intelligentsia/fusion-desktop-windows/releases/tag/v1.1.0` is a proven workaround; consider adopting its launch model (CLI server + Electron shell) as an official fallback until the native desktop build is stabilized on Windows. + +--- + +## Related PRs + +- `Runfusion/Fusion#1882` — dashboard routing and Windows Terminal popup fix. +- `Automata-intelligentsia/fusion-desktop-windows#v1.1.0` — standalone Windows wrapper that works around the native desktop regressions.