Commit Graph

87 Commits

Author SHA1 Message Date
gsxdsm
26f22861fa FN-7637: port bundled-plugin auto-install into @fusion/core for the desktop runtime
Move the host-agnostic bundled-plugin auto-install logic (manifest loading, entry-path
resolution, install/update/enable flow) out of the CLI package into @fusion/core so the
desktop embedded runtime can auto-install bundled runtime plugins without depending on
the CLI package; the CLI module becomes a thin adapter that supplies its own bundle-dir
resolution to the shared helper.

- Add packages/core/src/plugins/bundled-plugin-install.ts with the shared, host-agnostic
  ensureBundledPluginInstalled / ensureBundledDependencyGraphPluginInstalled /
  ensureBundledCursorRuntimePluginInstalled implementation and BUNDLED_PLUGIN_IDS/
  isBundledPluginId/resolvePluginEntryPath, exported from @fusion/core's index.
- Slim packages/cli/src/plugins/bundled-plugin-install.ts to a CLI-specific
  candidate-bundle-dir resolver that delegates to @fusion/core and re-exports the same
  public surface dashboard.ts/serve.ts/daemon.ts already depend on.
- Remove the now-redundant packages/cli/src/plugins/__tests__/resolve-plugin-entry-path-sync.test.ts
  (coverage moved with the implementation to @fusion/core).
- Add packages/desktop/src/bundled-plugin-dirs.ts to resolve each bundled plugin's staged
  package directory via import.meta.resolve, mirroring the CLI's dist/plugins/<id> resolver.
- Wire local-runtime.ts and local-server.ts to call ensureBundledPluginInstalled before
  loadAllPlugins() and expose a lazy-install callback for PUT /api/plugins/:id/settings,
  mirroring the CLI dashboard command's startup auto-install pass.
- Update docs/PLUGIN_AUTHORING.md to describe the shared bundled-plugin-install location.

Files changed:
 docs/PLUGIN_AUTHORING.md                           |  11 +
 .../__tests__/bundled-plugin-install.test.ts       | 619 ++-------------------
 .../resolve-plugin-entry-path-sync.test.ts         |  97 ----
 packages/cli/src/plugins/bundled-plugin-install.ts | 250 +--------
 packages/core/src/index.ts                         |   8 +
 .../__tests__/bundled-plugin-install.test.ts       | 391 +++++++++++++
 .../core/src/plugins/bundled-plugin-install.ts     | 186 +++++++
 .../src/__tests__/bundled-plugin-dirs.test.ts      |  59 ++
 .../desktop/src/__tests__/local-runtime.test.ts    | 183 +++++-
 .../desktop/src/__tests__/local-server.test.ts     |  96 +++-
 packages/desktop/src/bundled-plugin-dirs.ts        |  61 ++
 packages/desktop/src/local-runtime.ts              |  66 ++-
 packages/desktop/src/local-server.ts               |  36 +-
 13 files changed, 1171 insertions(+), 892 deletions(-)

Fusion-Task-Id: FN-7637

Fusion-Task-Lineage: 953c5b82-a079-4600-b3af-45c974cd5014

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-07 22:06:16 -07:00
gsxdsm
d54ab80395 FN-7623: wire pluginStore/pluginLoader into desktop embedded dashboard server
Fixes the desktop app's plugin subsystem, which was never wired into createServer(), breaking Settings > Plugins Browse registry and plugin install.

- local-runtime.ts: construct a PluginStore + PluginLoader (mirroring the CLI dashboard command), load enabled plugins, run plugin schema-init hooks, and pass pluginStore/pluginLoader/pluginRunner into createServer()
- local-server.ts: apply the same wiring to the legacy desktop local server path for consistency
- Both paths fail soft: a broken plugin subsystem (e.g. corrupt manifest) is logged/traced but no longer blocks embedded dashboard startup
- Extend local-runtime.test.ts and local-server.test.ts to cover plugin wiring and the fail-soft path
- Add changeset (patch) documenting the fix

Files changed:
 .changeset/fn-7623-desktop-plugin-wiring.md        |   7 ++
 .../desktop/src/__tests__/local-runtime.test.ts    | 123 ++++++++++++++++++++-
 .../desktop/src/__tests__/local-server.test.ts     |  69 +++++++++++-
 packages/desktop/src/local-runtime.ts              |  50 ++++++++-
 packages/desktop/src/local-server.ts               |  41 ++++++-
 5 files changed, 286 insertions(+), 4 deletions(-)

Fusion-Task-Id: FN-7623

Fusion-Task-Lineage: c6f291fb-e6aa-4ac1-a3f3-4189fc831c60

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-07 22:04:53 -07:00
gsxdsm
fe5a595984 FN-7622: unify desktop and CLI provider seeding to fix truncated provider list
The Electron desktop app's in-process dashboard server skipped the CLI's provider seeding sequence, so /api/providers and /api/models returned a truncated catalog (missing built-in API-key providers and user customProviders[]) compared to the identical config on the web build.

- Move provider-auth.ts and custom-provider-registry.ts from @fusion/cli into @fusion/engine as the single shared implementation
- Add engine/src/provider-registration.ts exposing seedDashboardProviders(), mirroring the CLI's exact startup order (built-in Zai provider registration -> wrapAuthStorageWithApiKeyProviders -> model merge/refresh -> registerCustomProviders -> settings:updated resubscription)
- Update desktop/src/local-runtime.ts and local-server.ts to call the shared seedDashboardProviders() helper instead of constructing a raw authStorage/modelRegistry
- Convert packages/cli/src/commands/provider-auth.ts and custom-provider-registry.ts into re-export shims preserving unchanged observable behavior
- Add engine/src/__tests__/provider-registration.test.ts and expand desktop local-runtime/local-server tests to cover the shared seeding path
- Add changeset for @runfusion/fusion (patch)

Files changed:
 .changeset/fn-7622-desktop-provider-parity.md      |   7 +
 .../cli/src/commands/custom-provider-registry.ts   | 122 +----
 packages/cli/src/commands/provider-auth.ts         | 517 +--------------------
 .../desktop/src/__tests__/local-runtime.test.ts    |  93 ++++
 .../desktop/src/__tests__/local-server.test.ts     |  62 ++-
 packages/desktop/src/local-runtime.ts              |  33 +-
 packages/desktop/src/local-server.ts               |  21 +-
 .../src/__tests__/provider-registration.test.ts    | 192 ++++++++
 packages/engine/src/custom-provider-registry.ts    | 117 +++++
 packages/engine/src/index.ts                       |  18 +
 packages/engine/src/provider-auth.ts               | 513 ++++++++++++++++++++
 packages/engine/src/provider-registration.ts       | 105 +++++
 12 files changed, 1172 insertions(+), 628 deletions(-)

Fusion-Task-Id: FN-7622
Fusion-Task-Lineage: fb6fbbf3-745e-4623-b7af-11471e13f138
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-07 22:04:51 -07:00
gsxdsm
f87e11387f FN-7617: retry embedded desktop runtime startup to fix transient Windows launch failure
Adds bounded internal retry to the desktop embedded-start path so a transient first-attempt failure self-heals before the operator ever sees the "Couldn't start local Fusion" error screen.

- LocalRuntimeManager.startEmbedded() now retries startEmbeddedAttempt() up to startupRetries (default 3) total attempts with a startupRetryDelayMs (default 150ms) delay between attempts, both overridable via constructor options for deterministic zero-delay tests.
- status.state stays "starting" across retried attempts; only the final attempt's real error sets state "error" and is thrown/surfaced, so genuine failures still report their real message unchanged.
- Only affects the embedded-start path (never external-cli or already-running paths).
- Adds regression tests covering retry-then-success, exhausted-retries-surfaces-final-error, and status transitions across attempts.

Files changed:
 .../desktop/src/__tests__/local-runtime.test.ts    | 158 ++++++++++++++++++++-
 packages/desktop/src/local-runtime.ts              |  76 +++++++++-
 2 files changed, 228 insertions(+), 6 deletions(-)

Fusion-Task-Id: FN-7617

Fusion-Task-Lineage: 2baf90f0-052c-42ff-a5b1-bc0b802d0ddc

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-06 19:03:06 -07:00
gsxdsm
ced783ea79 FN-7473: open desktop Anthropic OAuth in browser
Route desktop OAuth popups to the system browser while preserving Anthropic subscription login polling.\n\n- Add Electron window-open handling that keeps internal Fusion navigation in-app and external http(s) OAuth URLs in the system browser.\n- Cover Anthropic Subscription polling so login-in-progress states do not show a false incomplete-login toast.\n- Document desktop OAuth browser handoff behavior and add a patch changeset.\n\nFiles changed:\n .../fn-7473-desktop-anthropic-oauth-browser.md     |  7 ++\n docs/dashboard-guide.md                            |  2 +-\n docs/settings-reference.md                         |  2 +-\n .../__tests__/SettingsModal.models-auth.test.tsx   | 76 ++++++++++++++++++++++\n .../desktop/src/__tests__/main-integration.test.ts |  2 +\n .../desktop/src/__tests__/main-local-mode.test.ts  |  3 +-\n .../desktop/src/__tests__/main.integration.test.ts |  2 +\n packages/desktop/src/__tests__/main.test.ts        | 54 ++++++++++++++-\n packages/desktop/src/main.ts                       | 60 +++++++++++++++++-\n 9 files changed, 203 insertions(+), 5 deletions(-)

Fusion-Task-Id: FN-7473

Fusion-Task-Lineage: 3d6b0acd-536c-4f7d-8c6b-35eb519b46bb

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-03 21:45:21 -07:00
gsxdsm
52dbc0e65e FN-7472: quit Windows desktop runtime on window close
Ensure Windows Desktop treats window close as application shutdown.

- Allow Windows BrowserWindow close events to proceed so Electron emits quit lifecycle hooks.
- Keep non-Windows close-to-tray behavior while documenting platform-specific close semantics.
- Cover native, renderer, tray, and runtime cleanup paths with desktop tests.

Files changed:
 .changeset/fn-7472-windows-desktop-close-quits.md |   7 ++
 packages/desktop/README.md                        |  10 +-
 packages/desktop/src/__tests__/ipc.test.ts        |   9 ++
 packages/desktop/src/__tests__/main.test.ts       |  76 ++++++++++++++-
 packages/desktop/src/__tests__/tray.test.ts       | 110 +++++++++++++++++++++-
 packages/desktop/src/main.ts                      |   8 ++
 packages/desktop/src/tray.ts                      |   4 +
 7 files changed, 214 insertions(+), 10 deletions(-)

Fusion-Task-Id: FN-7472
Fusion-Task-Lineage: c007e20f-37b9-435e-861d-1665e2691bc9
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-03 21:45:21 -07:00
gsxdsm
da662c41a7 fix(onboarding,desktop): don't error on duplicate first agent; wire Switch-server button
First-run project setup surfaced a blocking "Agent with this name already exists" error when creating
the default CEO. The default first agent can be created from more than one first-run surface (the
unified ModelOnboarding agent step and the project-setup SetupWizard sub-flow), and agent names are
unique per store, so the second create returned 409. The step's goal — a first agent exists — was
already satisfied, so both onboarding surfaces now treat a name collision as success and advance
instead of blocking. The user still creates the agent; they just aren't punished for the flow offering
it twice.

Separately, the desktop header "Desktop local mode / Switch server" button did nothing: main relays
the click as a `shell:open-connection-manager` IPC (webContents.send), but the preload never forwarded
it to the `window` DOM event ShellContext listens for, so the signal was dropped. Add the preload
bridge so the button opens NativeShellConnectionManager (Local/Remote toggle + remote-server profiles),
letting operators switch between running locally, connecting to a remote server, or a different remote.

Regression tests: SetupWizard advances on an already-exists agent; preload dispatches the window event
on the IPC.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 12:54:38 -07:00
gsxdsm
08e47d4f0d fix(desktop): migrate userData on relocation, verify packaged assets, harden Windows CI
- Add a one-time copy of the previous default Electron profile into
  ~/.fusion/desktop-user-data (user-data-migration.ts) so upgrading operators
  keep window geometry/session instead of starting fresh (report Issue 8).
- Verify main.js/preload.js/client assets in scripts/build.ts (pre-package
  staging) and in the packaged app.asar via desktop-windows.yml, so an
  incomplete package fails the build/CI instead of dead-ending at runtime with
  a silent missing preload (report Issue 5, recommendation #2).
- Fix two pre-existing stale workflow-assertion tests that expected a bare
  'electron-builder --win' after the scripts moved to '--projectDir deploy'.
- Update the field report with a per-issue resolution matrix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 08:49:43 -07:00
gsxdsm
d97e66a657 fix(desktop): sync lockfile, gate Windows GPU flags, document desktop hardening
- Regenerate pnpm-lock.yaml for the new electron@^33.4.11 CLI dependency so
  --frozen-lockfile stops failing every PR-check job.
- Gate the GPU/sandbox-disabling Electron flags (--no-sandbox, --disable-gpu,
  etc.) to Windows only via os.platform(); applying them on macOS/Linux was a
  security and rendering regression. This also resolves the unused os import
  that failed lint.
- Add FNXC comments for the Windows GPU flags, desktop user-data isolation, and
  CLI dashboard-server reuse per project comment convention.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 08:13:06 -07:00
gsxdsm
6d7715fe9e Merge branch 'main' into desktop-release-issues-report 2026-07-03 07:48:51 -07:00
gsxdsm
00afb22bcb FN-7458: default startup theme mode to system
Default fresh dashboard startup and appearance reset to System mode while keeping Shadcn Ember as the color theme.

- Set global themeMode defaults and Settings fallback props to system.
- Resolve pre-hydration web and desktop startup from prefers-color-scheme, including invalid cache and fallback paths.
- Update Appearance reset behavior, focused theme tests, docs, and the release changeset.

Files changed:
 .changeset/fn-7458-system-theme-default.md         |   7 ++
 docs/dashboard-guide.md                            |   3 +-
 docs/settings-reference.md                         |   4 +-
 .../core/src/__tests__/global-settings.test.ts     |  17 +++-
 packages/core/src/__tests__/store-settings.test.ts |   6 +-
 packages/core/src/settings-schema.ts               |   6 +-
 .../app/__tests__/index-html-theme-link.test.ts    |  18 ++++
 .../dashboard/app/components/SettingsModal.tsx     |   8 +-
 .../dashboard/app/components/ThemeSelector.tsx     |   6 +-
 .../components/__tests__/ThemeDropdown.test.tsx    |   9 +-
 .../components/__tests__/ThemeSelector.test.tsx    |   2 +-
 .../dashboard/app/hooks/__tests__/useTheme.test.ts | 111 ++++++++++++++++++++-
 packages/dashboard/app/hooks/useTheme.ts           |  21 +++-
 packages/dashboard/app/index.html                  |  13 ++-
 packages/desktop/src/renderer/index.html           |  13 ++-
 15 files changed, 211 insertions(+), 33 deletions(-)

Fusion-Task-Id: FN-7458
Fusion-Task-Lineage: fb6184b4-9a6a-4131-9f97-f8cd12ef904c
Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-03 07:47:03 -07:00
ddonaldson130
4bad0920e2 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.
2026-07-03 03:36:10 -04:00
gsxdsm
776df1ac25 fix(desktop): wire a ModelRegistry so onboarding shows models (not just "connected")
createServer's modelRegistry is optional and, when absent, the /api/models endpoint returns an
empty list — so after connecting a provider (e.g. Anthropic) the onboarding model picker showed
"no models". The desktop wired authStorage but no ModelRegistry.

Add a shared createFusionModelRegistry(authStorage) factory to @fusion/engine (which already depends
on @earendil-works/pi-coding-agent) so non-CLI hosts don't need that dep directly, and pass its
result as modelRegistry from both desktop server paths. Verified against a clean embedded server:
/api/models now returns 24 Claude models instead of an empty list.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 23:09:36 -07:00
gsxdsm
666adff1f7 test(desktop): mock createFusionAuthStorage in local-server engine mock
local-server now imports createFusionAuthStorage from @fusion/engine; add it to the test's engine
mock so the startup path resolves.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 22:41:24 -07:00
gsxdsm
98f46cb33a fix(desktop): wire auth storage so first-run onboarding (AI/GitHub) actually opens
The desktop embedded server called createServer WITHOUT an authStorage, so GET /api/auth/status
returned 500 "Authentication is not configured". The dashboard's first-run onboarding hook
(useAuthOnboarding -> fetchAuthStatus) catches that failure silently and never opens the model
onboarding wizard — so the desktop skipped straight to project creation with no AI/GitHub setup,
regardless of onboarding-completion flags (which is why clearing them did nothing). Providers also
couldn't be authenticated at all.

Wire createFusionAuthStorage() (the same storage the CLI dashboard/serve commands use) into both the
primary (local-runtime) and legacy (local-server) desktop server paths. Verified against a clean
embedded server: /api/auth/status now returns 200 with the provider list instead of 500. (Full
API-key provider wrapping stays CLI-only for now; OAuth + CLI providers are available on desktop.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 22:40:46 -07:00
gsxdsm
0c43ed42cf fix: address PR review feedback + typecheck failure
- DesktopLaunchGate: the chooser onPick("local") path still called the removed
  applyServerBaseUrl helper (broke Typecheck and the desktop local chooser flow) —
  call navigateToLocalRuntimeOrigin. Also re-read shell.getState() immediately before the
  self-healing start check so a stale mount snapshot doesn't fire a redundant
  setDesktopMode("local") on normal boots (Greptile).
- register-fn-binary-routes: on Windows the npm install runs under a shell, so a timeout's
  child.kill only stopped cmd.exe and left npm.cmd/node running — kill the whole process tree
  via taskkill /T on win32 (CodeRabbit).
- local-server.test: align with the new resolver contract — assert the runtime never
  auto-registers the root project and starts engine-less when no projects exist (CodeRabbit).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 20:57:25 -07:00
gsxdsm
b331f26f3d fix(desktop,cli): never auto-create a project in home/cwd; onboard instead
The desktop embedded runtime auto-registered its runtime root (the user's HOME directory) as a
project on first launch, and bare `fusion` / `fn` / `fn dashboard` / `fusion dashboard`
auto-registered the CWD as a project. Both silently created a "cwd-mode" project the operator
never chose and dropped them onto a board for it.

- Desktop: replace ensureDesktopRuntimeProject (which registered home) with
  resolveDesktopRuntimePrimaryProject, which only PICKS an already-registered project as the
  primary engine target and registers nothing. With no projects the server starts engine-less
  (createServer's engine is optional) and the dashboard shows its onboarding empty state.
  Applied to both the primary (local-runtime) and legacy (local-server) desktop server paths.
- CLI dashboard command: ensureCwdProjectRegistered now runs with autoRegister:false, so it uses
  the CWD project only if already registered, else starts with none and the dashboard onboards.
  (serve/daemon keep their existing --no-auto-register flag; the CLI `desktop` launcher unchanged.)

Verified: with zero projects the embedded server starts, /api/health -> 200, /api/projects -> [],
/ serves the client. Unit test asserts resolveDesktopRuntimePrimaryProject registers nothing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 20:16:42 -07:00
gsxdsm
78f0bc3190 fix(desktop): heal launch-mode/shell split-brain that hung local runtime on Windows
Desktop startup used two independent persisted sources of truth that could
disagree: desktop-launch-mode.json decided whether main STARTS the embedded
local runtime, while shell-connections.json (desktopMode) decided whether the
renderer launch gate WAITS for it. shell:setDesktopMode persists shell settings
before the fallible startLocalRuntimeOnce()/saveDesktopLaunchMode(), so a first
"local" selection whose runtime start failed or was interrupted left
shell=local / launch-mode=choose permanently. Every subsequent launch then sat
at "Starting local Fusion runtime…" polling a runtime nobody started, timing out
after 30s.

Fix (defense in depth):
- initializeApp reconciles: a completed shell "local" selection is authoritative;
  it heals the launch-mode file and starts the runtime.
- onDesktopModeChange/onDesktopLaunchModeChange persist launch-mode BEFORE the
  fallible start so an interrupted start cannot re-create the desync.
- DesktopLaunchGate no longer assumes main started the runtime; if it is not
  running/starting it actively (re)starts via setDesktopMode("local") before polling.
- Add env-gated startup trace (FUSION_STARTUP_TRACE) so packaged builds, which
  otherwise log nothing, can diagnose this class of stall.

Regression tests assert the invariant (split-brain -> runtime starts + file heals;
agreement-on-choose -> no start). flushPromises now drains via a macrotask so
run()-based tests observe a fully-initialized app regardless of async chain length.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 15:20:15 -07:00
gsxdsm
855061db5f fix: harden workflow graph cutover paths and migrate cutover-era tests
Production fixes:
- executor.ts: add safeLogEntry() wrapper so synchronous throws from
  store.logEntry don't abort pause/abort/finalize control flow.
- workflow-authoritative-driver.ts: pass built-in auxiliary custom nodes
  (task-summary nodes, bypassable optional-groups) through as success
  instead of throwing.

Test migrations for graph-native runtime (cherry-picked from closed PR #1869):
- executor-prompt: two-party barrier for global-pause disposal test.
- executor-task-done-invariant: assert merge-node boundary moveTask.
- workflow-graph-merge-region-collapse: updated for merge-region node shapes.
- executor-worktree/worktree-liveness/implicit-task-done-budget: graph-aware.
- CLI extension tests: shared engine-workflow-authoring-mock helper.
- Dashboard/desktop/reliability tests: cutover-aware assertion updates.
2026-07-02 07:32:47 -07:00
gsxdsm
a4049971e5 FN-7401: add Glass Silver dashboard theme
Adds a frosted silver/gray dashboard color theme across app, desktop, and release metadata.

- Register glass-silver in shared theme types, selector options, and startup validation hooks.
- Add Glass Silver CSS tokens, swatch styling, and dashboard/desktop stylesheet preload coverage.
- Cover theme registration, dropdown/selector rendering, theme persistence, and CSS token invariants with tests.
- Document the new dashboard theme and publish a minor changeset for @runfusion/fusion.

Files changed:
 .changeset/fn-7401-glass-silver-theme.md           |   7 +
 docs/dashboard-guide.md                            |   3 +-
 packages/core/src/types.ts                         |   2 +
 .../app/__tests__/glass-silver-theme.test.ts       | 155 ++++++++++++++++++++
 .../dashboard/app/components/ThemeSelector.css     |  14 ++
 .../components/__tests__/ThemeDropdown.test.tsx    |  13 ++
 .../components/__tests__/ThemeSelector.test.tsx    |  16 +++
 packages/dashboard/app/components/themeOptions.ts  |   1 +
 .../dashboard/app/hooks/__tests__/useTheme.test.ts |  15 ++
 packages/dashboard/app/index.html                  |   2 +-
 packages/dashboard/app/public/theme-data.css       | 156 +++++++++++++++++++++
 packages/desktop/src/renderer/index.html           |   1 +
 12 files changed, 383 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-7401

Fusion-Task-Lineage: e64f14cc-590e-458b-adf6-7c9baa488157

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 18:01:17 -07:00
gsxdsm
1f3a15ec1c FN-7360: fix Windows desktop runtime packaging
Fix packaged Windows desktop startup by preserving Node-safe runtime dependencies and dashboard registry assets.

- Externalize Electron main/preload npm packages so CommonJS updater dependencies load natively.
- Load the dashboard plugin registry manifest through file IO and copy it into dashboard server dist from all build paths.
- Split Windows NSIS and portable artifact names and verify required Electron runtime resources in CI.
- Cover the packaging/runtime invariants with desktop and dashboard regression tests.

Files changed:
 .changeset/fn-7360-desktop-windows.md              |  7 +++
 .github/workflows/desktop-windows.yml              | 21 ++++++++
 packages/dashboard/package.json                    |  2 +-
 .../src/__tests__/plugin-registry-dist.test.ts     | 32 ++++++++++++
 .../src/__tests__/routes-plugin-registry.test.ts   | 10 ++--
 packages/dashboard/src/plugin-routes.ts            | 27 +++++++++-
 packages/desktop/README.md                         |  5 +-
 packages/desktop/electron-builder.yml              |  9 ++++
 packages/desktop/scripts/build.ts                  | 29 ++++++++--
 packages/desktop/scripts/workspace-tools.ts        |  4 ++
 .../desktop/src/__tests__/build-bundling.test.ts   | 61 ++++++++++++++++++++++
 .../src/__tests__/electron-builder-config.test.ts  | 15 ++++++
 packages/desktop/src/__tests__/ipc.test.ts         | 15 ++++++
 .../desktop/src/__tests__/local-runtime.test.ts    | 20 +++++++
 14 files changed, 247 insertions(+), 10 deletions(-)

Fusion-Task-Id: FN-7360

Fusion-Task-Lineage: a2d88130-c24f-43e2-932a-1e174b6afa35

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-01 08:01:59 -07:00
gsxdsm
211b18b073 FN-7299: make Shadcn Ember the default dashboard theme
Set Shadcn Ember as the default dashboard theme while keeping Shadcn Gray available as an alternate.

- Add Shadcn Ember theme metadata, CSS variables, and boot-time defaults for dashboard and desktop shells.
- Update persisted settings types, schema defaults, and theme selection UI to prefer Ember.
- Cover Ember defaults and theme-option ordering with core, hook, and dashboard component tests.
- Add a published package changeset for the operator-facing default theme change.

Files changed:
 .changeset/fn-7299-shadcn-ember-default.md         |   7 ++
 .../core/src/__tests__/global-settings.test.ts     |  23 +++-
 packages/core/src/__tests__/store-settings.test.ts |  10 +-
 packages/core/src/settings-schema.ts               |   6 +-
 packages/core/src/types.ts                         |   4 +-
 .../app/__tests__/shadcn-ember-theme.test.ts       | 107 ++++++++++++++++
 .../app/__tests__/shadcn-gray-theme.test.ts        |   2 +-
 .../dashboard/app/components/ThemeSelector.css     |  15 +++
 .../dashboard/app/components/ThemeSelector.tsx     |   6 +-
 .../components/__tests__/ThemeDropdown.test.tsx    |  20 ++-
 .../components/__tests__/ThemeSelector.test.tsx    |  24 +++-
 packages/dashboard/app/components/themeOptions.ts  |   7 +-
 .../dashboard/app/hooks/__tests__/useTheme.test.ts |  18 ++-
 packages/dashboard/app/hooks/useTheme.ts           |   8 +-
 packages/dashboard/app/index.html                  |  10 +-
 packages/dashboard/app/public/theme-data.css       | 137 +++++++++++++++++++++
 packages/desktop/src/renderer/index.html           |  42 ++++++-
 17 files changed, 409 insertions(+), 37 deletions(-)

Fusion-Task-Id: FN-7299

Fusion-Task-Lineage: 7e175752-b8fc-4ba9-8534-cb485f6eb18a

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-06-30 13:43:28 -07:00
gsxdsm
4a4e389254 FN-7032: add signed Android release artifacts
Add secret-gated signed Android release packaging while preserving the unsigned fallback.

- Build signed Android release APK and AAB artifacts when keystore secrets are configured.
- Verify signed APKs, generate checksums for APK/AAB outputs, and include AABs in release aggregation.
- Document Android signing secrets, sideload verification, fallback artifacts, and Play upload scope.
- Cover the release and rehearsal workflow wiring with CLI and desktop workflow tests.

Files changed:
 .github/workflows/release.yml                      | 94 ++++++++++++++++++----
 .github/workflows/test-release.yml                 | 94 ++++++++++++++++++----
 MOBILE.md                                          | 18 ++++-
 RELEASING.md                                       | 34 ++++++--
 packages/cli/src/__tests__/ci-workflow.test.ts     | 24 ++++++
 packages/desktop/README.md                         |  2 +-
 .../desktop/src/__tests__/release-workflow.test.ts | 24 +++++-
 7 files changed, 251 insertions(+), 39 deletions(-)

Fusion-Task-Id: FN-7032
Fusion-Task-Lineage: 0334c026-384e-4531-a2b2-f8a0b5bb7ff0
2026-06-25 20:20:33 -07:00
gsxdsm
dba65933e5 FN-7014: publish Android APK release artifacts
Adds Android APK generation to binary release and rehearsal workflows so GitHub releases ship mobile assets.

- Add Android build jobs that sync Capacitor, assemble the debug APK, and upload APK/checksum artifacts.
- Include Android artifacts in release and test-release collection dependencies and file matching.
- Document Android release outputs and extend workflow shape tests for the new asset path.

Files changed:
 .github/workflows/release.yml                      | 86 +++++++++++++++++++++-
 .github/workflows/test-release.yml                 | 85 ++++++++++++++++++++-
 MOBILE.md                                          |  2 +-
 RELEASING.md                                       | 10 ++-
 packages/cli/src/__tests__/ci-workflow.test.ts     |  6 +-
 packages/desktop/README.md                         |  1 +
 .../desktop/src/__tests__/release-workflow.test.ts | 24 +++++-
 7 files changed, 201 insertions(+), 13 deletions(-)

Fusion-Task-Id: FN-7014
Fusion-Task-Lineage: 8ed94f64-399b-433f-add4-0294fc5722d1
2026-06-25 19:35:05 -07:00
gsxdsm
42a1346d6c fix: address engine startup review feedback 2026-06-21 02:15:24 -07:00
gsxdsm
7ef381762a feat: start engines by default 2026-06-20 23:57:37 -07:00
gsxdsm
fc0636fe90 FN-6748: add Air dashboard theme
Adds a minimal, borderless Air color theme across dashboard theme selection and bootstrap validation.

- Register Air in the core theme union, dashboard theme options, and browser/desktop bootstrap validators.
- Add dark and light Air token blocks with flattened chrome styling and matching swatch samples.
- Cover Air registration and CSS invariants with a focused dashboard test.
- Document the Air theme alongside the existing Shadcn theme in dashboard theming guidance.

Files changed:
 docs/dashboard-guide.md                            |   2 +-
 packages/core/src/types.ts                         |   2 +
 packages/dashboard/app/__tests__/air-theme.test.ts |  58 ++++++++++++
 .../dashboard/app/components/ThemeSelector.css     |  14 +++
 packages/dashboard/app/components/themeOptions.ts  |   1 +
 packages/dashboard/app/index.html                  |   2 +-
 packages/dashboard/app/public/theme-data.css       | 101 +++++++++++++++++++++
 packages/desktop/src/renderer/index.html           |   1 +
 8 files changed, 179 insertions(+), 2 deletions(-)

Fusion-Task-Id: FN-6748

Fusion-Task-Lineage: a0caf14f-673d-485c-8886-97e4b273b624
2026-06-19 16:47:34 -07:00
gsxdsm
63f1e097a2 FN-6366: fix desktop Vitest constructor mocks
Stabilize the desktop Vitest suite under Vitest 4.1.8 while keeping dashboard builds complete.

- Convert Electron constructor mocks to constructable function implementations for BrowserWindow, Tray, Notification, and LocalRuntimeManager.\n- Assert local runtime initialization uses the mocked home directory in desktop main-process tests.\n- Build dashboard runtime plugin packages before the desktop dashboard build.

Files changed:\n packages/desktop/scripts/workspace-tools.ts        | 15 ++++++++++++++\n packages/desktop/src/__tests__/deep-link.test.ts   |  4 +++-\n .../desktop/src/__tests__/main-integration.test.ts | 23 ++++++++++++++--------\n .../desktop/src/__tests__/main-local-mode.test.ts  | 19 ++++++++++++++----\n .../desktop/src/__tests__/main.integration.test.ts | 21 ++++++++++++--------\n packages/desktop/src/__tests__/main.test.ts        | 13 +++++++++---\n packages/desktop/src/__tests__/native.test.ts      |  6 ++++--\n 7 files changed, 75 insertions(+), 26 deletions(-)

Fusion-Task-Id: FN-6366

Fusion-Task-Lineage: 4e4ccdbc-845f-47d9-a565-cc5d659cf089
2026-06-13 09:01:39 -07:00
gsxdsm
199990bd5a Linux fixes 2026-06-12 21:50:49 -07:00
gsxdsm
b3fe830132 fix(FN-5988): include ms in desktop package runtime
Ensure packaged desktop apps include the transitive debug dependency needed by extract-zip during startup.

Fusion-Task-Id: FN-5988
2026-06-07 23:12:04 -07:00
Phil Larson
f8bda56716 fix(FN-166): bypass coordination-only overlap leases
Fusion-Task-Id: FN-166
2026-05-30 06:47:02 -07:00
gsxdsm
7d2cf330db feat(FN-5609): add macOS desktop signing configuration and entitlements
Adds macOS code signing and notarization infrastructure (FN-5609), introducing hardened runtime entitlements, electron-builder config for signed builds, and signing-enabled release workflows, with tests validating the configuration and docs covering the signing flow.

Fusion-Task-Id: FN-5609

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5609
2026-05-27 21:31:12 -07:00
gsxdsm
925a466043 feat(FN-5608): add linux arm64 dual-arch support to desktop release workflo
Adds Linux ARM64 as a target architecture to the desktop release pipeline, including dual-arch release and test-release workflows, electron-builder configuration updates, and corresponding tests and documentation.

Fusion-Task-Id: FN-5608

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5608
2026-05-27 21:31:12 -07:00
gsxdsm
9504c31a85 feat(FN-5607): add cross-platform updater feeds for desktop releases
Add multi-platform updater feed configuration for the desktop app, including Windows, Mac, and Linux feed files with a collector, wired into the release and test-release workflows, plus corresponding tests and documentation.

Fusion-Task-Id: FN-5607

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5607
2026-05-27 21:31:12 -07:00
gsxdsm
294efb02fd feat(FN-5605): add linux gpg signing for release artifacts
Implements Linux GPG signing for the release pipeline by adding a `sign-linux.sh` helper, wiring it into the release and test-release workflows, including `.asc` signature files in release collectors, and documenting the full signing workflow in CODE_SIGNING.md with a note in the desktop README.

Fusion-Task-Id: FN-5605

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5605
2026-05-27 21:31:12 -07:00
gsxdsm
0d0d07ded4 feat(FN-5603): add desktop release jobs for macOS and Linux with artifact a
Added GitHub Actions workflows for macOS and Linux desktop release artifacts (`release.yml` and `test-release.yml`), wired in new `dist` scripts across platforms, and extended test coverage for electron-builder config and release workflow logic, with updated documentation for the new artifacts.

Fusion-Task-Id: FN-5603

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5603
2026-05-27 21:31:12 -07:00
gsxdsm
d99cfaf51a feat(FN-5594): add Windows ARM64 build support and test assertions
Added Windows ARM64 support to the desktop build pipeline, introducing separate target architecture arrays for x64 and ARM64, configuring electron-builder to produce artifacts for both platforms, and adding tests to assert the correct architecture names.

Fusion-Task-Id: FN-5594

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5594
2026-05-26 17:19:35 -07:00
gsxdsm
202895c319 feat(FN-5593): add windows desktop build jobs to release workflows
Adds a Windows desktop build job to the release pipeline, wires the desktop artifacts into both release and test-release workflows, includes workflow shape assertions in tests, and documents the Windows release artifacts in the desktop README.

Fusion-Task-Id: FN-5593

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5593
2026-05-26 17:19:35 -07:00
gsxdsm
a4628c8649 feat(FN-5592): merge fusion/fn-5592 2026-05-26 17:19:35 -07:00
gsxdsm
40f7cad3e0 feat(FN-5587): add windows desktop packaging workflow, scripts, and tests
Adds Windows desktop packaging support for Fusion, including a new GitHub Actions workflow for building Windows desktop targets, matching build scripts in the root and desktop package, a test for electron-builder configuration, and documentation of the packaging path.

Fusion-Task-Id: FN-5587

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
Fusion-Task-Id: FN-5587
2026-05-26 17:19:34 -07:00
gsxdsm
dd0d4b74b7 feat(FN-5022): merge fusion/fn-5022 2026-05-18 05:46:37 -07:00
gsxdsm
8b50b754cd chore(desktop): drop debug console.logs from launch-mode reset flow
The console.log breadcrumbs added while diagnosing the menu also
caused an uncaught "write EPIPE" when the parent terminal pipe was
already closed by the time the user clicked Change Launch Mode.
Now that the flow is verified working, remove the chatter and keep
only the actual error-path logging.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 23:32:10 -07:00
gsxdsm
2e9c819dd5 fix(desktop): include onChangeLaunchMode in buildAppMenu assertion
The recently added "Change Launch Mode…" menu wiring made main.ts pass
an extra onChangeLaunchMode callback to buildAppMenu(). The
main-integration test still asserted the old exact-shape {mainWindow,
appName} payload, so it failed once concurrent test load made
ordering matter. Switched to expect.objectContaining so future
buildAppMenu props don't break this test.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 23:04:19 -07:00
gsxdsm
10d5afdb8e fix(desktop): Change Launch Mode menu performs reset entirely in main
Replace the renderer-event approach (which silently failed when the
renderer-side listener wasn't yet registered) with an onChangeLaunchMode
callback wired through AppMenuOptions. The callback runs
resetLaunchModeAndReload in main: writes shell settings to clear the
chosen mode, stops the embedded runtime, then navigates the window
directly to the renderer entrypoint with no cached query params so the
launch gate re-prompts.

Also surface the same flow from the dashboard's BackendConnectionErrorPage:
when running inside the desktop shell, the "Can't reach the Fusion backend"
page now offers a "Change Launch Mode…" button alongside Retry, so a user
who chose a broken backend isn't stuck without the Electron menubar.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 22:58:34 -07:00
gsxdsm
51e28fb7ca fix(desktop): re-show hidden window on dock/Finder activate + log gate flow
The close handler hides the BrowserWindow instead of destroying it, so
once closed, subsequent dock or Finder activations were no-ops because
the activate handler only created a new window when mainWindow === null.
Show + focus the existing window if it's hidden so relaunch behaves as
expected. Also add console.log breadcrumbs in DesktopLaunchGate so we
can diagnose why the chooser sometimes appears not to render.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 22:24:40 -07:00
gsxdsm
75a712771e feat(desktop): Connection → Change Launch Mode menu item
Adds a "Connection" submenu with a "Change Launch Mode…" item that lets
users switch between Run Locally and Connect to Remote after the initial
chooser. The menu sends shell:reset-desktop-mode-request to the renderer;
the dashboard's DesktopLaunchGate listens, calls the new
shell:resetDesktopMode IPC (clears hasCompletedModeSelection, stops the
embedded runtime), strips the cached serverBaseUrl/shellMode query params,
and reloads so the gate re-prompts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 22:16:27 -07:00
gsxdsm
e5af9c93ae fix(desktop): packaged macOS app launched with no window / blank white screen
In packaged Electron builds, `process.argv[1]` is undefined (Electron loads
the main script via package.json `main`, not via argv), so the bottom-of-file
guard never invoked `run()` and the app started without creating a window.
Also build the dashboard client with `--base ./` so its `file://`-loaded
index.html resolves `./assets/*` from inside the asar instead of the
filesystem root, which was producing a blank white window.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 22:01:51 -07:00
Fusion (runfusion.ai)
93e49b062a feat(FN-4939): complete Step 5 — add changeset and native helper re-export
Fusion-Task-Id: FN-4939
Fusion-Task-Lineage: b2a00edb-5245-4223-97e4-0a16dd2c3289
2026-05-17 11:49:10 -07:00
Fusion (runfusion.ai)
329b102eb2 fix(FN-4939): stabilize desktop test mocks and restore lint/type safety
Fusion-Task-Id: FN-4939
Fusion-Task-Lineage: b2a00edb-5245-4223-97e4-0a16dd2c3289
2026-05-17 11:49:09 -07:00
Fusion (runfusion.ai)
1f2b553079 feat(FN-4939): complete Step 2 — guard window position and force show
Fusion-Task-Id: FN-4939
Fusion-Task-Lineage: b2a00edb-5245-4223-97e4-0a16dd2c3289
2026-05-17 11:49:08 -07:00