Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
d34c09e
fix(antigravity): link only existing skill directories
Oct 18, 2026
69e3236
fix(antigravity): verify the browser helper once per server process
Oct 18, 2026
59cc61a
fix(antigravity): remove conversation sidecars left without a database
Oct 18, 2026
c0703c4
fix(providers): report failures after sign-in truthfully and log thei…
Oct 18, 2026
dd00893
fix(antigravity): link skills installed after the first sign-in
Oct 18, 2026
a82c6ae
fix(providers): open the sign-in page for the client that started it
Oct 18, 2026
e3cf7b6
feat(providers): sign in from the provider row in one click
Oct 18, 2026
237c013
docs(providers): record sign-in page opening and Antigravity seams
Oct 18, 2026
c3ec108
style(antigravity): keep the sidecar seam to its marked lines
Oct 18, 2026
7b88f19
fix(antigravity): key the helper check on its startup settings; never…
Oct 18, 2026
80dff32
feat(providers): carry the client's sign-in request id on its operation
Oct 18, 2026
d4e571b
fix(providers): open the sign-in page even when the start reply is lost
Oct 18, 2026
a6fa414
feat(providers): open the setup card for one-click sign-in on another…
Oct 18, 2026
a65677e
docs(providers): record request-id ownership, remote sign-in and trac…
Oct 18, 2026
b8c21b9
fix(providers): keep an accepted sign-in startup when its client goes…
Oct 18, 2026
1ed632e
fix(antigravity): sanitize failed-request diagnostics deny-by-default
Oct 18, 2026
80b0409
fix(antigravity): key the helper check on every variable spelling; bo…
Oct 18, 2026
2d1eb76
fix(providers): detect blocked sign-in popups; claim openings across …
Oct 18, 2026
bf2d559
fix(providers): keep a Scient Agent sign-in recoverable after a faile…
Oct 18, 2026
ee06987
fix(providers): count only the desktop app's own backends as on this …
Oct 18, 2026
d003840
docs(providers): record startup ownership, window claims, popup block…
Oct 18, 2026
6e8d050
fix(antigravity): record failed-request diagnostics from an allowlist…
Oct 18, 2026
692bccc
fix(providers): open sign-in pages only on an atomic claim, without a…
Oct 18, 2026
b0cd420
fix(providers): recover a sign-in page whose claiming window gave up
Oct 18, 2026
df65790
fix(providers): withdraw sign-in page claims whose operation moved on
Oct 19, 2026
990ede2
fix(providers): show one-click sign-in as starting from the click; cl…
Oct 19, 2026
b7779f3
feat(providers): grant the opening of a sign-in page once, on the server
Oct 19, 2026
24c1ca8
fix(providers): open a sign-in page only on the server's grant
Oct 19, 2026
37ce18e
fix(providers): sign-in copy from the v2 screenshots
Oct 19, 2026
3778ebf
refactor(providers): keep the sign-in page claim command in Scient's …
Oct 19, 2026
51f6bdf
fix(providers): never open a page granted too late, or miss one at mount
Oct 19, 2026
4482134
fix(providers): let snapshots alone say which sign-in operation is cu…
Oct 19, 2026
5cbd3de
chore(providers): mark the sign-in page claim entries as Scient diver…
Oct 19, 2026
5a670f2
fix(providers): let the server decide whether a sign-in page is current
Oct 19, 2026
4fca9f6
fix(providers): a sign-in page opened by hand is not opened again by …
Oct 19, 2026
d115b35
refactor(providers): split the sign-in page store by responsibility
Oct 19, 2026
d82e838
refactor(providers): derive the sign-in page state once for every set…
Oct 19, 2026
0a0c68a
refactor(providers): describe the server sign-in helpers as they are now
Oct 19, 2026
cb0b1d2
docs(providers): describe only the final sign-in page design
Oct 19, 2026
719d337
fix(providers): release an id whose page was already opened here, wit…
Oct 19, 2026
0d0c893
Merge main into the Antigravity sign-in fix
Oct 19, 2026
f47fffc
ci(antigravity): guard the managed ACP publication on the new sign-in…
Oct 19, 2026
86b1c0b
Merge main into the Antigravity sign-in fix
Oct 19, 2026
84e819e
fix(providers): shorten the sign-in failure notification title
Oct 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,8 @@ jobs:
apps/server/src/provider/antigravityAuthSupport.ts \
apps/server/src/provider/acp \
apps/server/src/scient/skills/antigravityPluginSkillProjection.ts \
apps/server/src/scient/skills/antigravityUserSkillLinks.ts \
apps/server/src/scient/providerLifecycle/antigravityBrowserHelperPreflight.ts \
apps/server/scripts/qualify-antigravity-acp-catalog.ts \
apps/server/src/scient/providerLifecycle/antigravityAcpCatalog.ts \
apps/server/package.json \
Expand Down
41 changes: 41 additions & 0 deletions UPSTREAM.md
Original file line number Diff line number Diff line change
Expand Up @@ -1061,6 +1061,47 @@ Legacy CLI owners are named explicitly and remain active for explicit `agy` path
and targets outside the qualified native set; removing a fallback requires native
replacement qualification, not merely an available Google archive.

Antigravity sign-in carries four marked seams into upstream-owned files. Three fix upstream bugs
worth proposing to T3:

- `linkAntigravityUserSkills` (`provider/antigravityAuthSupport.ts`) linked the private profile's
`config/skills` and `antigravity-cli/skills` to `~/.gemini` even when those directories did not
exist; on `session/new` the agent then fails every session with -32603. The seam calls
`scient/skills/antigravityUserSkillLinks.ts`: link only an existing directory, remove a dangling
link, and replace an empty directory the agent created once the target exists; a directory with
content is never touched. One marked fixture line in `antigravityAuthSupport.test.ts` creates
the CLI skill directory that upstream's test expected to be linked while missing.
- `prepareAntigravityProfile`'s browser-helper preflight ran on every launch, and its
`timeoutOrElse` waited for the helper's teardown (`taskkill`, then an unbounded exit wait on
Windows). The seam (`scient/providerLifecycle/antigravityBrowserHelperPreflight.ts`) keeps a
success per helper executable and Node/Electron startup variables for the server process, and
lets a timed-out teardown finish in the background, bounded by one forced kill of the helper,
which a second marked line records as it starts. Creating the helper process is synchronous in
Node on Windows and can still block the event loop once.
- `removeAntigravitySessionFiles` (`provider/acp/AntigravitySessionFiles.ts`) could not clean up
after a failed `session/new`, which leaves `<session>.db-wal`/`-shm` and never reports the
session id. The seam sweeps SQLite sidecars without their database
(`scient/providerLifecycle/antigravityConversationSidecars.ts`).

The fourth stays inside `AntigravityAuth.ts`'s existing marked failure block, which takes its
post-authentication message from `scient/providerLifecycle/antigravityAuthDiagnostics.ts` so the
lifecycle bridge can mark the failure `failedAfterSignIn`; the same module records the failed
ACP request in the local trace. Opening sign-in pages for the client that started them, and the
Settings row's one-click sign-in, live in Scient-owned web modules
(`scient/providerConnection/providerSignIn*.ts` and `oneClickSignIn.ts`), with one marked mount of
`ProviderSignInPageCoordinator` in each authenticated shell of `routes/__root.tsx`.
The server-side claim of a sign-in page adds one Scient RPC,
`server.claimProviderSignInPage`, declared in `contracts/src/scient/providerConnectionRpcs.ts` and
imported in its existing marked block of `contracts/src/rpc.ts`; its group entry, scope
(`server/src/auth/RpcAuthorization.ts`) and aggregate (`server/src/observability/RpcInstrumentation.ts`)
are each one marked line beside the existing provider-connection entries. Those existing
provider-connection entries in the three files are earlier unmarked Scient additions, to be marked in a follow-up.
The web defines its command in `scient/providerConnection/providerSignInCommands.ts`.
`components/settings/ProviderInstanceCard.tsx` carries three marked blocks: its lifecycle
presentation comes from a Scient hook (its import and its call), so a sign-in started here reads
as starting from the click, and a failed sign-in or setup takes the error status dot. See
[provider lifecycle](docs/internals/provider-lifecycle.md#opening-sign-in-pages).

Antigravity reasoning presentation is a narrow client-side divergence. The shared
`packages/client-runtime/src/antigravityModelPresentation.ts` groups recognized
Google Gemini effort variants for the existing model and reasoning controls.
Expand Down
3 changes: 3 additions & 0 deletions apps/server/src/auth/RpcAuthorization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ export const RPC_REQUIRED_SCOPES = {

[WS_METHODS.serverStartProviderConnection]: AuthProvidersManageScope,
[WS_METHODS.serverCancelProviderConnection]: AuthProvidersManageScope,
// SCIENT-FORK:START — claiming a sign-in page needs the scope that starts the sign-in.
[WS_METHODS.serverClaimProviderSignInPage]: AuthProvidersManageScope,
// SCIENT-FORK:END
[WS_METHODS.serverSubmitProviderAuthorizationCode]: AuthProvidersManageScope,
[WS_METHODS.serverDisconnectProvider]: AuthProvidersManageScope,
[WS_METHODS.serverPlanProviderRuntime]: AuthProvidersManageScope,
Expand Down
3 changes: 3 additions & 0 deletions apps/server/src/observability/RpcInstrumentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,9 @@ const RPC_AGGREGATES = {
[WS_METHODS.documentsReleaseDocumentPdf]: "documents",
[WS_METHODS.serverStartProviderConnection]: "server",
[WS_METHODS.serverCancelProviderConnection]: "server",
// SCIENT-FORK:START — sign-in page claims count with the other server RPCs.
[WS_METHODS.serverClaimProviderSignInPage]: "server",
// SCIENT-FORK:END
[WS_METHODS.serverSubmitProviderAuthorizationCode]: "server",
[WS_METHODS.serverDisconnectProvider]: "server",
[WS_METHODS.serverPlanProviderRuntime]: "server",
Expand Down
9 changes: 6 additions & 3 deletions apps/server/src/provider/AntigravityAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ import * as SubscriptionRef from "effect/SubscriptionRef";
import * as AcpErrors from "effect-acp/errors";

import type * as AcpSessionRuntime from "@t3tools/provider-acp/server/AcpSessionRuntime";
// SCIENT-FORK:START — bounded native failure metadata, without provider payloads.
import { recordAntigravityAuthFailure } from "../scient/providerLifecycle/antigravityAuthDiagnostics.ts";
// SCIENT-FORK:START — bounded local failure diagnostics and the shared setup-failure message.
import {
ANTIGRAVITY_SESSION_SETUP_FAILED_MESSAGE,
recordAntigravityAuthFailure,
} from "../scient/providerLifecycle/antigravityAuthDiagnostics.ts";
// SCIENT-FORK:END
import {
antigravityAuthStageFailure,
Expand Down Expand Up @@ -125,7 +128,7 @@ function safeAuthFailure(
return "Google sign-in was not approved. Start sign-in again.";
}
if (error.value.method === "session/new" && error.value.code === -32603) {
return "Antigravity authenticated, but could not initialize a session or load models.";
return ANTIGRAVITY_SESSION_SETUP_FAILED_MESSAGE;
}
if (!usesBrowser && error.value.code === -32602) {
return "Antigravity rejected the configured credentials. Check the provider settings.";
Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/provider/Drivers/ScientAntigravityDriver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import * as Cause from "effect/Cause";
import * as Effect from "effect/Effect";

import {
ANTIGRAVITY_STARTING_MESSAGE,
antigravityConnectionMethod,
makeAntigravityConnectionActionsFromController,
makeAntigravityManagedRuntimeActions,
Expand Down Expand Up @@ -111,6 +112,7 @@ export function makeAntigravityRuntimeIdentity<E>(input: {
methods: [antigravityConnectionMethod(input.authMethod)],
canDisconnect: provider.auth.status === "authenticated",
operation: null,
startingMessage: ANTIGRAVITY_STARTING_MESSAGE,
runtime,
},
};
Expand Down
4 changes: 4 additions & 0 deletions apps/server/src/provider/ScientProviderInstanceSeams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ export interface ProviderConnectionActionFailure {
* the sign-in as possibly removed.
*/
readonly signInMayBeRemoved?: boolean | undefined;
/** The provider accepted the sign-in; the failure came while finishing its setup. */
readonly afterSignIn?: boolean | undefined;
}

export interface ProviderConnectionAttempt {
Expand Down Expand Up @@ -96,6 +98,8 @@ export interface ProviderConnectionAttempt {
*/
export interface ProviderConnectionActions {
readonly methods: ReadonlyArray<ProviderConnectionMethod>;
/** Shown while `start` runs, for a provider whose start can take noticeably long. */
readonly startingMessage?: string | undefined;
/**
* `account` names an entry of the provider's own sign-in list. The manager
* passes it only for a provider whose snapshot lists accounts, and only an
Expand Down
6 changes: 6 additions & 0 deletions apps/server/src/provider/acp/AntigravitySessionFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import * as Effect from "effect/Effect";
import * as FileSystem from "effect/FileSystem";
import * as Path from "effect/Path";
import * as Schema from "effect/Schema";
// SCIENT-FORK:START — sidecars left without their database are swept on every cleanup.
import { removeOrphanedAntigravityConversationSidecars } from "../../scient/providerLifecycle/antigravityConversationSidecars.ts";
// SCIENT-FORK:END

const isNativeSessionId = Schema.is(Schema.String.check(Schema.isUUID(4)));
const decodeSessionMetadata = Schema.decodeEffect(
Expand All @@ -15,6 +18,9 @@ export const removeAntigravitySessionFiles = Effect.fn("removeAntigravitySession
readonly sessionId: string | undefined;
readonly cwd: string;
}) {
// SCIENT-FORK:START — also covers a session/new that failed before reporting its id.
yield* removeOrphanedAntigravityConversationSidecars(input.profileDirectory);
// SCIENT-FORK:END
if (input.sessionId === undefined || !isNativeSessionId(input.sessionId)) {
return;
}
Expand Down
3 changes: 3 additions & 0 deletions apps/server/src/provider/antigravityAuthSupport.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,9 @@ it.layer(NodeServices.layer)("Antigravity profile preparation", (it) => {
const cliSkills = path.join(userHome, ".gemini", "antigravity-cli", "skills");
const sourcePlugin = path.join(userHome, ".gemini", "config", "plugins", "science");
yield* fs.makeDirectory(path.join(configSkills, "review"), { recursive: true });
// SCIENT-FORK:START — only an existing skill directory is linked.
yield* fs.makeDirectory(cliSkills, { recursive: true });
// SCIENT-FORK:END
yield* fs.makeDirectory(path.join(sourcePlugin, "skills", "literature"), {
recursive: true,
});
Expand Down
26 changes: 21 additions & 5 deletions apps/server/src/provider/antigravityAuthSupport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ import { collectUint8StreamText } from "@t3tools/provider-core/server/collectStr
// SCIENT-FORK:START — plugin skills are projected without their other components.
import { projectAntigravityPluginSkills } from "../scient/skills/antigravityPluginSkillProjection.ts";
// SCIENT-FORK:END
// SCIENT-FORK:START — safe skill links and a once-per-helper browser preflight.
import {
recordAntigravityPreflightChild,
verifyAntigravityBrowserHelperOnce,
} from "../scient/providerLifecycle/antigravityBrowserHelperPreflight.ts";
import { prepareAntigravitySkillLink } from "../scient/skills/antigravityUserSkillLinks.ts";
// SCIENT-FORK:END
import type * as AcpSessionRuntime from "@t3tools/provider-acp/server/AcpSessionRuntime";
import {
antigravityUserSkillDirectories,
Expand Down Expand Up @@ -368,6 +375,9 @@ const linkAntigravityUserSkills = Effect.fn("linkAntigravityUserSkills")(functio
[links[1], targets[1]],
] as const) {
yield* Effect.gen(function* () {
// SCIENT-FORK:START — link only an existing directory; never leave a dangling link.
if (yield* prepareAntigravitySkillLink({ link, target })) return;
// SCIENT-FORK:END
const existing = yield* fs.readLink(link).pipe(
Effect.map((value): string | undefined => path.resolve(path.dirname(link), value)),
Effect.catchReason("PlatformError", "NotFound", () => Effect.undefined),
Expand Down Expand Up @@ -460,6 +470,9 @@ export const prepareAntigravityProfile = Effect.fn("prepareAntigravityProfile")(
shell: false,
}),
);
// SCIENT-FORK:START — a timed-out preflight can force-kill this helper.
yield* recordAntigravityPreflightChild(child);
// SCIENT-FORK:END
const [stdout, stderr, exitCode] = yield* Effect.all(
[
collectUint8StreamText({ stream: child.stdout, maxBytes: 4_096 }),
Expand All @@ -478,12 +491,15 @@ export const prepareAntigravityProfile = Effect.fn("prepareAntigravityProfile")(
return yield* authSupportError("Antigravity browser suppression could not be verified.");
}
}).pipe(
Effect.scoped,
Effect.timeoutOrElse({
duration: "5 seconds",
orElse: () =>
Effect.fail(authSupportError("Antigravity browser suppression verification timed out.")),
// SCIENT-FORK:START — verified once per helper; a timeout does not wait for its teardown.
verifyAntigravityBrowserHelperOnce({
spawner,
helperExecutable,
environment,
timeout: "5 seconds",
onTimeout: () => authSupportError("Antigravity browser suppression verification timed out."),
}),
// SCIENT-FORK:END
Effect.mapError((error) =>
error._tag === "AcpTransportError"
? error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
import { ANTIGRAVITY_RELEASE_VERSION } from "../../provider/antigravityRelease.ts";
import type { ProviderAuthController } from "../../provider/ProviderAuthService.ts";
import { bundledAntigravityAcpAsset } from "./antigravityAcpCatalog.ts";
import { ANTIGRAVITY_SESSION_SETUP_FAILED_MESSAGE } from "./antigravityAuthDiagnostics.ts";

const instanceId = ProviderInstanceId.make("antigravity-lifecycle-test");
const driver = ProviderDriverKind.make("antigravity");
Expand Down Expand Up @@ -353,3 +354,58 @@ it.effect("never removes a managed runtime when its repair download or verificat
expect(refreshes).toBe(1);
}),
);

it.effect("tells a session failure after Google accepted the sign-in from a failed sign-in", () =>
Effect.gen(function* () {
const controllerWith = (states: ReadonlyArray<ProviderAuthState>): ProviderAuthController => ({
start: () => Effect.succeed(authState("starting", { flowId: "flow" })),
complete: () => Effect.die("No callback in this test."),
cancel: (_owner, flowId) => Effect.succeed(authState("cancelled", { flowId })),
logout: () => Effect.succeed(authState("idle")),
subscribe: () => Stream.fromIterable(states),
});
const startWith = (states: ReadonlyArray<ProviderAuthState>) =>
makeAntigravityConnectionActionsFromController({
instanceId,
authMethod: "oauth-personal",
controller: controllerWith(states),
stopSessions: Effect.void,
randomOwnerId: Effect.succeed("owner"),
});

const actions = startWith([]);
expect(actions.startingMessage).toBe("Antigravity can take up to a minute to start.");

// A stored sign-in: authentication passes at once and session/new fails before any link.
const beforeLink = yield* startWith([
authState("failed", { flowId: "flow", message: ANTIGRAVITY_SESSION_SETUP_FAILED_MESSAGE }),
])
.start("antigravity_google")
.pipe(Effect.scoped, Effect.flip);
expect(beforeLink).toMatchObject({
message: ANTIGRAVITY_SESSION_SETUP_FAILED_MESSAGE,
afterSignIn: true,
});

// A browser sign-in that Google accepted, followed by the same failure.
const attempt = yield* startWith([
authState("waiting", { flowId: "flow", authorizationUrl }),
authState("failed", { flowId: "flow", message: ANTIGRAVITY_SESSION_SETUP_FAILED_MESSAGE }),
]).start("antigravity_google");
expect(yield* attempt.waitForCompletion.pipe(Effect.flip)).toMatchObject({
message: ANTIGRAVITY_SESSION_SETUP_FAILED_MESSAGE,
afterSignIn: true,
});

const declined = yield* startWith([
authState("waiting", { flowId: "flow", authorizationUrl }),
authState("failed", {
flowId: "flow",
message: "Google sign-in failed. Start sign-in again.",
}),
]).start("antigravity_google");
const plain = yield* declined.waitForCompletion.pipe(Effect.flip);
expect(plain.message).toBe("Google sign-in failed. Start sign-in again.");
expect(plain.afterSignIn).toBeUndefined();
}).pipe(Effect.scoped),
);
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { ANTIGRAVITY_ACP_REGISTRY_VERSION } from "./antigravityAcpCatalog.ts";
import { ManagedRuntimeCatalog } from "./ManagedRuntimeCatalog.ts";
import { antigravityAuthUsesBrowser } from "../../provider/antigravityAuthSupport.ts";
import type { ProviderAuthController } from "../../provider/ProviderAuthService.ts";
import { ANTIGRAVITY_SESSION_SETUP_FAILED_MESSAGE } from "./antigravityAuthDiagnostics.ts";

function isTerminalAuthPhase(
phase: ProviderAuthState["phase"],
Expand All @@ -45,22 +46,24 @@ const failure = (message: string, cause?: unknown) =>
...(cause === undefined ? {} : { cause }),
});

export const ANTIGRAVITY_STARTING_MESSAGE = "Antigravity can take up to a minute to start.";

export function antigravityConnectionMethod(method: AntigravityAuthMethod) {
return antigravityAuthUsesBrowser(method)
? ("antigravity_google" as const)
: ("antigravity_credentials" as const);
}

function authFailureMessage(state: {
readonly phase: string;
readonly message: string | null;
}): string {
return (
function authFailure(state: { readonly phase: string; readonly message: string | null }) {
const message =
state.message?.trim() ||
(state.phase === "cancelled"
? "Antigravity sign-in was cancelled."
: "Antigravity sign-in did not finish.")
);
: "Antigravity sign-in did not finish.");
return new ProviderConnectionActionError({
message,
...(message === ANTIGRAVITY_SESSION_SETUP_FAILED_MESSAGE ? { afterSignIn: true } : {}),
});
}

/** Expose the official ACP auth controller through Scient's compact lifecycle UI. */
Expand All @@ -80,6 +83,7 @@ export function makeAntigravityConnectionActionsFromController(input: {
);
return {
methods: [antigravityConnectionMethod(input.authMethod)],
startingMessage: ANTIGRAVITY_STARTING_MESSAGE,
start: (method) =>
Effect.gen(function* () {
if (method !== antigravityConnectionMethod(input.authMethod)) {
Expand Down Expand Up @@ -111,7 +115,7 @@ export function makeAntigravityConnectionActionsFromController(input: {
)
: started;
if (isTerminalAuthPhase(initial.phase) && initial.phase !== "succeeded") {
return yield* failure(authFailureMessage(initial));
return yield* authFailure(initial);
}
const flowId = initial.flowId ?? started.flowId;
if (!flowId) {
Expand All @@ -124,9 +128,7 @@ export function makeAntigravityConnectionActionsFromController(input: {
Option.match({
onNone: () => Effect.fail(failure("Antigravity sign-in stopped unexpectedly.")),
onSome: (state) =>
state.phase === "succeeded"
? Effect.void
: Effect.fail(failure(authFailureMessage(state))),
state.phase === "succeeded" ? Effect.void : Effect.fail(authFailure(state)),
}),
),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,5 @@ export class ProviderConnectionActionError extends Data.TaggedError(
readonly message: string;
readonly cause?: unknown;
readonly signInMayBeRemoved?: boolean;
readonly afterSignIn?: boolean;
}> {}
Loading
Loading