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>
This commit is contained in:
gsxdsm
2026-07-02 22:40:46 -07:00
parent c976d75d8d
commit 98f46cb33a
2 changed files with 16 additions and 2 deletions

View File

@@ -67,7 +67,7 @@ async function createStoreDefault(rootDir: string): Promise<TaskStoreLike> {
async function createDashboardServerDefault(store: TaskStoreLike, rootDir: string): Promise<{ server: Server; cleanup: RuntimeCleanup }> {
const { CentralCore } = await import("@fusion/core");
const { createServer } = await import("@fusion/dashboard");
const { ProjectEngineManager } = await import("@fusion/engine");
const { ProjectEngineManager, createFusionAuthStorage } = await import("@fusion/engine");
/*
* FNXC:DesktopRuntime 2026-06-20-23:39:
@@ -99,11 +99,22 @@ async function createDashboardServerDefault(store: TaskStoreLike, rootDir: strin
const rootProject = await resolveDesktopRuntimePrimaryProject(centralCore);
strace(`createDashboardServer: primaryProject=${rootProject?.id ?? "none"}`);
const primaryEngine = rootProject ? await engineManager.ensureEngine(rootProject.id) : undefined;
/*
* FNXC:DesktopRuntime 2026-07-03-06:20:
* Wire an auth storage into the embedded server. Without it, GET /api/auth/status throws 500
* "Authentication is not configured", the dashboard's first-run onboarding hook (useAuthOnboarding
* -> fetchAuthStatus) hits its silent catch and NEVER opens the AI/GitHub onboarding wizard, and
* providers can't be authenticated at all. The CLI wires the same storage (createFusionAuthStorage);
* the desktop must too so operators can set up AI accounts. (API-key provider wrapping remains
* CLI-only for now; OAuth + CLI providers are available here.)
*/
const authStorage = createFusionAuthStorage();
strace("createDashboardServer: createServer");
const app = createServer(store as never, {
...(primaryEngine ? { engine: primaryEngine } : {}),
engineManager,
centralCore,
authStorage,
onProjectFirstAccessed: (projectId: string) => engineManager.onProjectAccessed(projectId),
});

View File

@@ -55,7 +55,7 @@ export class DesktopLocalServerManager {
const { TaskStore } = await import("@fusion/core");
const { CentralCore } = await import("@fusion/core");
const { createServer } = await import("@fusion/dashboard");
const { ProjectEngineManager } = await import("@fusion/engine");
const { ProjectEngineManager, createFusionAuthStorage } = await import("@fusion/engine");
store = new TaskStore(this.rootDir) as TaskStoreLike;
await store.init();
await store.watch();
@@ -75,10 +75,13 @@ export class DesktopLocalServerManager {
engineManager.startReconciliation();
const rootProject = await resolveDesktopRuntimePrimaryProject(centralCore);
const primaryEngine = rootProject ? await engineManager.ensureEngine(rootProject.id) : undefined;
// FNXC:DesktopRuntime 2026-07-03-06:20: wire auth storage so /api/auth/status works and first-run onboarding can open (see local-runtime.ts).
const authStorage = createFusionAuthStorage();
const app = createServer(store as never, {
...(primaryEngine ? { engine: primaryEngine } : {}),
engineManager,
centralCore,
authStorage,
onProjectFirstAccessed: (projectId: string) => engineManager.onProjectAccessed(projectId),
});
server = app.listen(0);