docs(desktop): field report for Windows desktop release issues

Add reports/desktop-release-issues-2026-07-03.md documenting the
regressions observed in the Fusion 0.52.0 Windows desktop release,
including:

- fusion desktop fails to launch because electron is a devDependency
- native launcher walks ancestor dirs and fails on unrelated workspace JSON
- Manage Projects opens Settings instead of overview
- Windows Terminal Help version dialogs on dashboard load
- packaged preload.cjs missing in unpacked release layout
- port collisions and dashboard/gateway drift on Windows
- GPU/sandbox rendering instability on Windows Electron
- isolated user-data path needed
- CLI desktop command not reusing an already-running dashboard server

Also include the two experimental mitigations we applied locally:
- disable GPU/sandbox Electron flags in desktop.ts
- skip embedded local runtime when FUSION_SERVER_PORT is already set

These changes are intended as supporting evidence and starting points
for the Fusion team, not as a final fix.
This commit is contained in:
ddonaldson130
2026-07-03 03:36:10 -04:00
parent fd94f7a191
commit 4bad0920e2
3 changed files with 208 additions and 2 deletions

View File

@@ -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<void>
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 = {

View File

@@ -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<void> {
}
}
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<void> {
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,

View File

@@ -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.