diff --git a/src/routes/cli/auth.tsx b/src/routes/cli/auth.tsx index 59b922e19..0b769d34f 100644 --- a/src/routes/cli/auth.tsx +++ b/src/routes/cli/auth.tsx @@ -2,6 +2,7 @@ import { useAuthActions } from "@convex-dev/auth/react"; import { createFileRoute } from "@tanstack/react-router"; import { useMutation } from "convex/react"; import { useEffect, useMemo, useRef, useState } from "react"; +import { flushSync } from "react-dom"; import { api } from "../../../convex/_generated/api"; import { getUserFacingConvexError } from "../../lib/convexError"; import { getClawHubSiteUrl, normalizeClawHubSiteOrigin } from "../../lib/site"; @@ -26,6 +27,7 @@ function CliAuth() { }; const [status, setStatus] = useState("Preparing…"); const [token, setToken] = useState(null); + const [callbackUrl, setCallbackUrl] = useState(null); const hasRun = useRef(false); const redirectUri = search.redirect_uri ?? ""; @@ -52,13 +54,21 @@ function CliAuth() { const run = async () => { setStatus("Creating token…"); const result = await createToken({ label }); - setToken(result.token); - setStatus("Redirecting to CLI…"); const hash = new URLSearchParams(); hash.set("token", result.token); hash.set("registry", registry); hash.set("state", state); - window.location.assign(`${redirectUri}#${hash.toString()}`); + const callbackUrl = `${redirectUri}#${hash.toString()}`; + // Render the fallback token before attempting navigation so it is + // always visible if the browser blocks or fails the http:// redirect + // (e.g. ERR_CONNECTION_REFUSED when the CLI server has already shut + // down, or Chrome's HTTPS-first mode interfering with localhost). + flushSync(() => { + setToken(result.token); + setCallbackUrl(callbackUrl); + setStatus("Redirecting to CLI…"); + }); + window.location.assign(callbackUrl); }; void run().catch((error) => { @@ -157,8 +167,16 @@ function CliAuth() {

{status}

{token ? (
-
If redirect fails, copy this token:
+
+ If the redirect did not complete, copy this token and run{" "} + clawhub login --token <token>: +
{token} + {callbackUrl ? ( +
+ Retry redirect to CLI +
+ ) : null}
) : null}