Files
fusion/packages/dashboard/app/utils/open-external.ts
gsxdsm 68ce5c31da fix: harden onboarding/git/desktop batch per multi-agent review findings
- uninstaller: taskkill only the first, digits-only postmaster.pid line
  (the for /f loop ran taskkill on the port/epoch lines — potential
  unrelated-process kill)
- git-missing dialogs use new ConfirmOptions.alwaysAsk so global
  skip-confirmations cannot silently pick an unseen choice
- Windows quit prompt: embedded-local runtimes only, skipped during OS
  session end (sync dialog blocked Windows shutdown)
- 'leave it running' detaches the embedded lifecycle (disarms its
  process shutdown hook) so Electron exit cannot kill the postmaster
  the operator chose to keep (new detachKeepingEmbedded)
- wizard: ref-based double-submit guard around the async git preflight
- clone route: ENOENT invalidate-and-retry matching runGitCommand
- openExternalUrl: drop the async window.open fallback (always
  popup-blocked); log bridge failures instead
- DirectoryPicker: close the panel when listing the created folder
  fails so Select cannot re-commit the parent
- git status probe bounded to two spawns (PATH + first candidate)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 00:33:14 -07:00

41 lines
1.6 KiB
TypeScript

/*
FNXC:DesktopOAuth 2026-07-18-04:00:
OAuth login handlers call window.open AFTER awaiting POST /auth/login. When
the round trip outlives Chromium's transient user activation (~5s — observed
with the OpenAI Codex flow while the Anthropic flow, being faster, worked),
the popup is silently blocked in the desktop app and the system browser never
opens. On desktop, prefer the activation-free shell:openExternal IPC bridge;
in the web app fall back to window.open.
*/
interface DesktopShellApi {
openExternal?: (url: string) => Promise<boolean>;
}
function desktopShellApi(): DesktopShellApi | undefined {
const w = window as unknown as { fusionAPI?: DesktopShellApi; electronAPI?: DesktopShellApi };
return w.fusionAPI ?? w.electronAPI;
}
/*
FNXC:DesktopOAuth 2026-07-18-06:00:
Review finding: the old "fall back to window.open when the IPC declines" ran
window.open from an async continuation — exactly the activation-less context
this module exists to avoid, so the fallback was always popup-blocked. On
desktop the IPC is the ONLY viable opener; a failure is logged instead of
pretending a blocked fallback helped.
*/
/** Open a URL in the user's browser: desktop IPC when available, window.open otherwise. */
export function openExternalUrl(url: string): void {
const api = desktopShellApi();
if (typeof api?.openExternal === "function") {
void api.openExternal(url).then((opened) => {
if (!opened) console.error(`openExternalUrl: desktop shell declined to open ${url}`);
}).catch((error: unknown) => {
console.error(`openExternalUrl: desktop shell failed to open ${url}`, error);
});
return;
}
window.open(url, "_blank");
}