authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-07-31 00:06:49+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-07-31 00:06:49+02:00
logfbecb7365ede9892045dec4d03805d20ef9859f8
treeaf8de2f552b92d6ebde3ea611e91ad1e24ff2b92
parent4029b858eaaa3f029d30a02a930f887853239169
signature Signed by PGP key B5690EEEBB952194

fix(desktop): bump Clerk Electron SDK to 0.0.24 and register t3code:// scheme on Linux (#5015)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

13 files changed, 210 insertions(+), 95 deletions(-)

apps/desktop/src/app/DesktopAppIdentity.test.ts-1
...@@ -54,7 +54,6 @@ const makeElectronAppLayer = (calls: ElectronAppCalls) =>...@@ -54,7 +54,6 @@ const makeElectronAppLayer = (calls: ElectronAppCalls) =>
54 calls.setAboutPanelOptions.push(options);54 calls.setAboutPanelOptions.push(options);
55 }),55 }),
56 setAppUserModelId: () => Effect.void,56 setAppUserModelId: () => Effect.void,
57 requestSingleInstanceLock: Effect.succeed(true),
58 getAppMetrics: Effect.succeed([]),57 getAppMetrics: Effect.succeed([]),
59 isDefaultProtocolClient: () => Effect.succeed(false),58 isDefaultProtocolClient: () => Effect.succeed(false),
60 setAsDefaultProtocolClient: () => Effect.succeed(true),59 setAsDefaultProtocolClient: () => Effect.succeed(true),
apps/desktop/src/app/DesktopAppIdentity.ts+27-19
...@@ -45,6 +45,27 @@ const normalizeCommitHash = (value: string): Option.Option<string> => {...@@ -45,6 +45,27 @@ const normalizeCommitHash = (value: string): Option.Option<string> => {
45 : Option.none();45 : Option.none();
46};46};
4747
48export const resolveUserDataPath = Effect.gen(function* () {
49 const environment = yield* DesktopEnvironment.DesktopEnvironment;
50 const fileSystem = yield* FileSystem.FileSystem;
51 const legacyPath = environment.path.join(
52 environment.appDataDirectory,
53 environment.legacyUserDataDirName,
54 );
55 const legacyPathExists = yield* fileSystem.exists(legacyPath).pipe(
56 Effect.mapError(
57 (cause) =>
58 new DesktopUserDataPathResolutionError({
59 legacyPath,
60 cause,
61 }),
62 ),
63 );
64 return legacyPathExists
65 ? legacyPath
66 : environment.path.join(environment.appDataDirectory, environment.userDataDirName);
67}).pipe(Effect.withSpan("desktop.appIdentity.resolveUserDataPath"));
68
48export const make = Effect.gen(function* () {69export const make = Effect.gen(function* () {
49 const assets = yield* DesktopAssets.DesktopAssets;70 const assets = yield* DesktopAssets.DesktopAssets;
50 const electronApp = yield* ElectronApp.ElectronApp;71 const electronApp = yield* ElectronApp.ElectronApp;
...@@ -90,24 +111,11 @@ export const make = Effect.gen(function* () {...@@ -90,24 +111,11 @@ export const make = Effect.gen(function* () {
90 return commitHash;111 return commitHash;
91 });112 });
92113
93 const resolveUserDataPath = Effect.gen(function* () {114 const userDataPath = resolveUserDataPath.pipe(
94 const legacyPath = environment.path.join(115 Effect.provide(
95 environment.appDataDirectory,116 yield* Effect.context<DesktopEnvironment.DesktopEnvironment | FileSystem.FileSystem>(),
96 environment.legacyUserDataDirName,117 ),
97 );118 );
98 const legacyPathExists = yield* fileSystem.exists(legacyPath).pipe(
99 Effect.mapError(
100 (cause) =>
101 new DesktopUserDataPathResolutionError({
102 legacyPath,
103 cause,
104 }),
105 ),
106 );
107 return legacyPathExists
108 ? legacyPath
109 : environment.path.join(environment.appDataDirectory, environment.userDataDirName);
110 }).pipe(Effect.withSpan("desktop.appIdentity.resolveUserDataPath"));
111119
112 const configure = Effect.gen(function* () {120 const configure = Effect.gen(function* () {
113 const commitHash = yield* resolveAboutCommitHash;121 const commitHash = yield* resolveAboutCommitHash;
...@@ -136,7 +144,7 @@ export const make = Effect.gen(function* () {...@@ -136,7 +144,7 @@ export const make = Effect.gen(function* () {
136 }).pipe(Effect.withSpan("desktop.appIdentity.configure"));144 }).pipe(Effect.withSpan("desktop.appIdentity.configure"));
137145
138 return DesktopAppIdentity.of({146 return DesktopAppIdentity.of({
139 resolveUserDataPath,147 resolveUserDataPath: userDataPath,
140 configure,148 configure,
141 });149 });
142});150});
apps/desktop/src/app/DesktopClerk.test.ts+90-5
...@@ -22,17 +22,38 @@ vi.mock("@clerk/electron/storage", () => ({...@@ -22,17 +22,38 @@ vi.mock("@clerk/electron/storage", () => ({
22 storage: storageMock,22 storage: storageMock,
23}));23}));
2424
25import * as Exit from "effect/Exit";
26import * as FileSystem from "effect/FileSystem";
27import * as ElectronApp from "../electron/ElectronApp.ts";
28import * as ElectronWindow from "../electron/ElectronWindow.ts";
25import * as DesktopClerk from "./DesktopClerk.ts";29import * as DesktopClerk from "./DesktopClerk.ts";
26import * as DesktopEnvironment from "./DesktopEnvironment.ts";30import * as DesktopEnvironment from "./DesktopEnvironment.ts";
2731
28const makeDesktopClerkLayer = (isDevelopment = true) => {32const makeDesktopClerkLayer = (isDevelopment = true, events: string[] = []) => {
29 const environment = DesktopEnvironment.DesktopEnvironment.of({33 const environment = DesktopEnvironment.DesktopEnvironment.of({
30 stateDir: "/tmp/t3-state",34 stateDir: "/tmp/t3-state",
31 isDevelopment,35 isDevelopment,
36 appDataDirectory: "/tmp/app-data",
37 userDataDirName: isDevelopment ? "t3code-dev" : "t3code",
38 legacyUserDataDirName: isDevelopment ? "T3 Code (Dev)" : "T3 Code (Alpha)",
39 path: { join: (...parts: ReadonlyArray<string>) => parts.join("/") },
32 } as unknown as DesktopEnvironment.DesktopEnvironment["Service"]);40 } as unknown as DesktopEnvironment.DesktopEnvironment["Service"]);
3341
42 const electronApp = {
43 setPath: (name: string, value: string) =>
44 Effect.sync(() => {
45 events.push(`setPath:${name}:${value}`);
46 }),
47 } as unknown as ElectronApp.ElectronApp["Service"];
48
34 return DesktopClerk.layer.pipe(49 return DesktopClerk.layer.pipe(
35 Layer.provide(Layer.succeed(DesktopEnvironment.DesktopEnvironment, environment)),50 Layer.provide(
51 Layer.mergeAll(
52 Layer.succeed(DesktopEnvironment.DesktopEnvironment, environment),
53 Layer.succeed(ElectronApp.ElectronApp, electronApp),
54 FileSystem.layerNoop({ exists: () => Effect.succeed(false) }),
55 ),
56 ),
36 );57 );
37};58};
3859
...@@ -55,11 +76,15 @@ describe("DesktopClerk", () => {...@@ -55,11 +76,15 @@ describe("DesktopClerk", () => {
5576
56 it.effect("acquires and releases the SDK bridge with the layer", () => {77 it.effect("acquires and releases the SDK bridge with the layer", () => {
57 const cleanup = vi.fn();78 const cleanup = vi.fn();
79 const events: string[] = [];
58 storageMock.mockReturnValue(storageAdapter);80 storageMock.mockReturnValue(storageAdapter);
59 createClerkBridgeMock.mockReturnValue({ cleanup });81 createClerkBridgeMock.mockImplementation(() => {
82 events.push("createClerkBridge");
83 return { cleanup, isPrimaryInstance: true };
84 });
6085
61 return Effect.gen(function* () {86 return Effect.gen(function* () {
62 yield* Effect.scoped(Layer.build(makeDesktopClerkLayer()));87 yield* Effect.scoped(Layer.build(makeDesktopClerkLayer(true, events)));
6388
64 assert.deepEqual(createClerkBridgeMock.mock.calls, [89 assert.deepEqual(createClerkBridgeMock.mock.calls, [
65 [90 [
...@@ -71,6 +96,10 @@ describe("DesktopClerk", () => {...@@ -71,6 +96,10 @@ describe("DesktopClerk", () => {
71 ],96 ],
72 ]);97 ]);
73 assert.equal(cleanup.mock.calls.length, 1);98 assert.equal(cleanup.mock.calls.length, 1);
99 // The bridge acquires Electron's single-instance lock at creation, and
100 // the lock both lives in and creates the userData directory — so the
101 // real path must be set before the bridge exists.
102 assert.deepEqual(events, ["setPath:userData:/tmp/app-data/t3code-dev", "createClerkBridge"]);
74 storageMock.mockClear();103 storageMock.mockClear();
75 createClerkBridgeMock.mockClear();104 createClerkBridgeMock.mockClear();
76 });105 });
...@@ -124,11 +153,67 @@ describe("DesktopClerk", () => {...@@ -124,11 +153,67 @@ describe("DesktopClerk", () => {
124 });153 });
125 });154 });
126155
156 it.effect("registers the second-instance handler in the primary instance", () => {
157 storageMock.mockReturnValue(storageAdapter);
158 createClerkBridgeMock.mockReturnValue({ cleanup: vi.fn(), isPrimaryInstance: true });
159 const quit = vi.fn();
160 const registeredEvents: string[] = [];
161 const electronApp = {
162 quit: Effect.sync(quit),
163 on: (eventName: string) =>
164 Effect.sync(() => {
165 registeredEvents.push(eventName);
166 }),
167 } as unknown as ElectronApp.ElectronApp["Service"];
168 const electronWindow = {} as ElectronWindow.ElectronWindow["Service"];
169
170 return Effect.gen(function* () {
171 const clerk = yield* DesktopClerk.DesktopClerk;
172 const exit = yield* Effect.exit(Effect.scoped(clerk.configure));
173
174 assert.isTrue(Exit.isSuccess(exit));
175 assert.equal(quit.mock.calls.length, 0);
176 assert.deepEqual(registeredEvents, ["second-instance"]);
177 }).pipe(
178 Effect.provide(makeDesktopClerkLayer()),
179 Effect.provideService(ElectronApp.ElectronApp, electronApp),
180 Effect.provideService(ElectronWindow.ElectronWindow, electronWindow),
181 );
182 });
183
184 it.effect("quits and interrupts startup in a secondary instance", () => {
185 storageMock.mockReturnValue(storageAdapter);
186 createClerkBridgeMock.mockReturnValue({ cleanup: vi.fn(), isPrimaryInstance: false });
187 const quit = vi.fn();
188 const registeredEvents: string[] = [];
189 const electronApp = {
190 quit: Effect.sync(quit),
191 on: (eventName: string) =>
192 Effect.sync(() => {
193 registeredEvents.push(eventName);
194 }),
195 } as unknown as ElectronApp.ElectronApp["Service"];
196 const electronWindow = {} as ElectronWindow.ElectronWindow["Service"];
197
198 return Effect.gen(function* () {
199 const clerk = yield* DesktopClerk.DesktopClerk;
200 const exit = yield* Effect.exit(Effect.scoped(clerk.configure));
201
202 assert.isTrue(Exit.hasInterrupts(exit));
203 assert.equal(quit.mock.calls.length, 1);
204 assert.deepEqual(registeredEvents, []);
205 }).pipe(
206 Effect.provide(makeDesktopClerkLayer()),
207 Effect.provideService(ElectronApp.ElectronApp, electronApp),
208 Effect.provideService(ElectronWindow.ElectronWindow, electronWindow),
209 );
210 });
211
127 it.each([212 it.each([
128 { isDevelopment: true, scheme: "t3code-dev" },213 { isDevelopment: true, scheme: "t3code-dev" },
129 { isDevelopment: false, scheme: "t3code" },214 { isDevelopment: false, scheme: "t3code" },
130 ])("configures the SDK with the $scheme renderer origin", ({ isDevelopment, scheme }) => {215 ])("configures the SDK with the $scheme renderer origin", ({ isDevelopment, scheme }) => {
131 const bridge = { cleanup: vi.fn() };216 const bridge = { cleanup: vi.fn(), isPrimaryInstance: true };
132 storageMock.mockReturnValue(storageAdapter);217 storageMock.mockReturnValue(storageAdapter);
133 createClerkBridgeMock.mockReturnValue(bridge);218 createClerkBridgeMock.mockReturnValue(bridge);
134219
apps/desktop/src/app/DesktopClerk.ts+19-2
...@@ -11,6 +11,7 @@ import { clerkFrontendApiHostnameFromPublishableKey } from "@t3tools/shared/rela...@@ -11,6 +11,7 @@ import { clerkFrontendApiHostnameFromPublishableKey } from "@t3tools/shared/rela
11import * as ElectronApp from "../electron/ElectronApp.ts";11import * as ElectronApp from "../electron/ElectronApp.ts";
12import * as ElectronProtocol from "../electron/ElectronProtocol.ts";12import * as ElectronProtocol from "../electron/ElectronProtocol.ts";
13import * as ElectronWindow from "../electron/ElectronWindow.ts";13import * as ElectronWindow from "../electron/ElectronWindow.ts";
14import * as DesktopAppIdentity from "./DesktopAppIdentity.ts";
14import * as DesktopEnvironment from "./DesktopEnvironment.ts";15import * as DesktopEnvironment from "./DesktopEnvironment.ts";
1516
16declare const __T3CODE_BUILD_CLERK_PUBLISHABLE_KEY__: string | undefined;17declare const __T3CODE_BUILD_CLERK_PUBLISHABLE_KEY__: string | undefined;
...@@ -84,7 +85,18 @@ export function createDesktopClerkBridge(stateDir: string, isDevelopment: boolea...@@ -84,7 +85,18 @@ export function createDesktopClerkBridge(stateDir: string, isDevelopment: boolea
8485
85export const make = Effect.gen(function* () {86export const make = Effect.gen(function* () {
86 const environment = yield* DesktopEnvironment.DesktopEnvironment;87 const environment = yield* DesktopEnvironment.DesktopEnvironment;
87 yield* Effect.acquireRelease(88 const electronApp = yield* ElectronApp.ElectronApp;
89
90 // Electron scopes the single-instance lock to the userData directory and
91 // creates that directory when the lock is acquired. The SDK bridge takes
92 // the lock at creation, so userData must already point at the real
93 // directory here — under the default productName-derived path, acquiring
94 // the lock would create "T3 Code (Alpha)" and make the legacy-install
95 // detection in resolveUserDataPath match on fresh installs.
96 const userDataPath = yield* DesktopAppIdentity.resolveUserDataPath;
97 yield* electronApp.setPath("userData", userDataPath);
98
99 const bridge = yield* Effect.acquireRelease(
88 Effect.try({100 Effect.try({
89 try: () => createDesktopClerkBridge(environment.stateDir, environment.isDevelopment),101 try: () => createDesktopClerkBridge(environment.stateDir, environment.isDevelopment),
90 catch: (cause) =>102 catch: (cause) =>
...@@ -113,7 +125,12 @@ export const make = Effect.gen(function* () {...@@ -113,7 +125,12 @@ export const make = Effect.gen(function* () {
113 const context = yield* Effect.context<ElectronWindow.ElectronWindow>();125 const context = yield* Effect.context<ElectronWindow.ElectronWindow>();
114 const runPromise = Effect.runPromiseWith(context);126 const runPromise = Effect.runPromiseWith(context);
115127
116 if (!(yield* electronApp.requestSingleInstanceLock)) {128 // The SDK bridge holds Electron's single-instance lock (acquired at
129 // bridge creation) so OAuth deep-link callbacks on Windows/Linux are
130 // forwarded to the running app. In a secondary instance the bridge has
131 // already begun quitting the app; app.quit() is asynchronous, so stop
132 // bootstrap here before whenReady can fire.
133 if (!bridge.isPrimaryInstance) {
117 yield* electronApp.quit;134 yield* electronApp.quit;
118 return yield* Effect.interrupt;135 return yield* Effect.interrupt;
119 }136 }
apps/desktop/src/app/DesktopLifecycle.test.ts-1
...@@ -29,7 +29,6 @@ describe("DesktopLifecycle", () => {...@@ -29,7 +29,6 @@ describe("DesktopLifecycle", () => {
29 setName: () => Effect.void,29 setName: () => Effect.void,
30 setAboutPanelOptions: () => Effect.void,30 setAboutPanelOptions: () => Effect.void,
31 setAppUserModelId: () => Effect.void,31 setAppUserModelId: () => Effect.void,
32 requestSingleInstanceLock: Effect.succeed(true),
33 getAppMetrics: Effect.succeed([]),32 getAppMetrics: Effect.succeed([]),
34 isDefaultProtocolClient: () => Effect.succeed(false),33 isDefaultProtocolClient: () => Effect.succeed(false),
35 setAsDefaultProtocolClient: () => Effect.succeed(true),34 setAsDefaultProtocolClient: () => Effect.succeed(true),
apps/desktop/src/electron/ElectronApp.test.ts-3
...@@ -14,7 +14,6 @@ const {...@@ -14,7 +14,6 @@ const {
14 quitMock,14 quitMock,
15 relaunchMock,15 relaunchMock,
16 removeListenerMock,16 removeListenerMock,
17 requestSingleInstanceLockMock,
18 setAboutPanelOptionsMock,17 setAboutPanelOptionsMock,
19 setAppUserModelIdMock,18 setAppUserModelIdMock,
20 setAsDefaultProtocolClientMock,19 setAsDefaultProtocolClientMock,
...@@ -35,7 +34,6 @@ const {...@@ -35,7 +34,6 @@ const {
35 quitMock: vi.fn(),34 quitMock: vi.fn(),
36 relaunchMock: vi.fn(),35 relaunchMock: vi.fn(),
37 removeListenerMock: vi.fn(),36 removeListenerMock: vi.fn(),
38 requestSingleInstanceLockMock: vi.fn(() => true),
39 setAboutPanelOptionsMock: vi.fn(),37 setAboutPanelOptionsMock: vi.fn(),
40 setAppUserModelIdMock: vi.fn(),38 setAppUserModelIdMock: vi.fn(),
41 setAsDefaultProtocolClientMock: vi.fn(() => true),39 setAsDefaultProtocolClientMock: vi.fn(() => true),
...@@ -67,7 +65,6 @@ vi.mock("electron", () => ({...@@ -67,7 +65,6 @@ vi.mock("electron", () => ({
67 quit: quitMock,65 quit: quitMock,
68 relaunch: relaunchMock,66 relaunch: relaunchMock,
69 removeListener: removeListenerMock,67 removeListener: removeListenerMock,
70 requestSingleInstanceLock: requestSingleInstanceLockMock,
71 runningUnderARM64Translation: false,68 runningUnderARM64Translation: false,
72 setAboutPanelOptions: setAboutPanelOptionsMock,69 setAboutPanelOptions: setAboutPanelOptionsMock,
73 setAsDefaultProtocolClient: setAsDefaultProtocolClientMock,70 setAsDefaultProtocolClient: setAsDefaultProtocolClientMock,
apps/desktop/src/electron/ElectronApp.ts-2
...@@ -56,7 +56,6 @@ export class ElectronApp extends Context.Service<...@@ -56,7 +56,6 @@ export class ElectronApp extends Context.Service<
56 options: Electron.AboutPanelOptionsOptions,56 options: Electron.AboutPanelOptionsOptions,
57 ) => Effect.Effect<void>;57 ) => Effect.Effect<void>;
58 readonly setAppUserModelId: (id: string) => Effect.Effect<void>;58 readonly setAppUserModelId: (id: string) => Effect.Effect<void>;
59 readonly requestSingleInstanceLock: Effect.Effect<boolean>;
60 readonly getAppMetrics: Effect.Effect<ReadonlyArray<Electron.ProcessMetric>>;59 readonly getAppMetrics: Effect.Effect<ReadonlyArray<Electron.ProcessMetric>>;
61 readonly isDefaultProtocolClient: (protocol: string) => Effect.Effect<boolean>;60 readonly isDefaultProtocolClient: (protocol: string) => Effect.Effect<boolean>;
62 readonly setAsDefaultProtocolClient: (61 readonly setAsDefaultProtocolClient: (
...@@ -153,7 +152,6 @@ export const make = ElectronApp.of({...@@ -153,7 +152,6 @@ export const make = ElectronApp.of({
153 Effect.sync(() => {152 Effect.sync(() => {
154 Electron.app.setAppUserModelId(id);153 Electron.app.setAppUserModelId(id);
155 }),154 }),
156 requestSingleInstanceLock: Effect.sync(() => Electron.app.requestSingleInstanceLock()),
157 getAppMetrics: Effect.sync(() => Electron.app.getAppMetrics()),155 getAppMetrics: Effect.sync(() => Electron.app.getAppMetrics()),
158 isDefaultProtocolClient: (protocol) =>156 isDefaultProtocolClient: (protocol) =>
159 Effect.sync(() => Electron.app.isDefaultProtocolClient(protocol)),157 Effect.sync(() => Electron.app.isDefaultProtocolClient(protocol)),
apps/desktop/src/telemetry/DesktopTelemetryPublisher.test.ts-1
...@@ -34,7 +34,6 @@ function makeElectronAppLayer(...@@ -34,7 +34,6 @@ function makeElectronAppLayer(
34 setName: () => Effect.void,34 setName: () => Effect.void,
35 setAboutPanelOptions: () => Effect.void,35 setAboutPanelOptions: () => Effect.void,
36 setAppUserModelId: () => Effect.void,36 setAppUserModelId: () => Effect.void,
37 requestSingleInstanceLock: Effect.succeed(true),
38 getAppMetrics: Effect.sync(() => {37 getAppMetrics: Effect.sync(() => {
39 onMetricsRead();38 onMetricsRead();
40 return metrics;39 return metrics;
apps/desktop/src/window/DesktopApplicationMenu.test.ts-1
...@@ -39,7 +39,6 @@ const electronAppLayer = Layer.succeed(ElectronApp.ElectronApp, {...@@ -39,7 +39,6 @@ const electronAppLayer = Layer.succeed(ElectronApp.ElectronApp, {
39 setName: () => Effect.void,39 setName: () => Effect.void,
40 setAboutPanelOptions: () => Effect.void,40 setAboutPanelOptions: () => Effect.void,
41 setAppUserModelId: () => Effect.void,41 setAppUserModelId: () => Effect.void,
42 requestSingleInstanceLock: Effect.succeed(true),
43 getAppMetrics: Effect.succeed([]),42 getAppMetrics: Effect.succeed([]),
44 isDefaultProtocolClient: () => Effect.succeed(false),43 isDefaultProtocolClient: () => Effect.succeed(false),
45 setAsDefaultProtocolClient: () => Effect.succeed(true),44 setAsDefaultProtocolClient: () => Effect.succeed(true),
pnpm-lock.yaml+48-48
...@@ -35,19 +35,19 @@ catalogs:...@@ -35,19 +35,19 @@ catalogs:
35 version: 0.2.235 version: 0.2.2
3636
37overrides:37overrides:
38 '@clerk/backend': 3.13.038 '@clerk/backend': 3.14.0
39 '@clerk/clerk-js': 6.25.739 '@clerk/clerk-js': 6.25.12
40 '@clerk/clerk-js>@base-org/account': '-'40 '@clerk/clerk-js>@base-org/account': '-'
41 '@clerk/clerk-js>@coinbase/wallet-sdk': '-'41 '@clerk/clerk-js>@coinbase/wallet-sdk': '-'
42 '@clerk/clerk-js>@solana/wallet-adapter-base': '-'42 '@clerk/clerk-js>@solana/wallet-adapter-base': '-'
43 '@clerk/clerk-js>@solana/wallet-adapter-react': '-'43 '@clerk/clerk-js>@solana/wallet-adapter-react': '-'
44 '@clerk/clerk-js>@solana/wallet-standard': '-'44 '@clerk/clerk-js>@solana/wallet-standard': '-'
45 '@clerk/clerk-js>@wallet-standard/core': '-'45 '@clerk/clerk-js>@wallet-standard/core': '-'
46 '@clerk/electron': 0.0.1846 '@clerk/electron': 0.0.24
47 '@clerk/electron-passkeys': 0.0.347 '@clerk/electron-passkeys': 0.0.3
48 '@clerk/expo': 4.0.248 '@clerk/expo': 4.1.2
49 '@clerk/react': 6.12.749 '@clerk/react': 6.12.9
50 '@clerk/shared': 4.25.750 '@clerk/shared': 4.25.9
51 '@effect/atom-react': 4.0.0-beta.10251 '@effect/atom-react': 4.0.0-beta.102
52 '@effect/platform-bun': 4.0.0-beta.10252 '@effect/platform-bun': 4.0.0-beta.102
53 '@effect/platform-node': 4.0.0-beta.10253 '@effect/platform-node': 4.0.0-beta.102
...@@ -111,8 +111,8 @@ importers:...@@ -111,8 +111,8 @@ importers:
111 apps/desktop:111 apps/desktop:
112 dependencies:112 dependencies:
113 '@clerk/electron':113 '@clerk/electron':
114 specifier: 0.0.18114 specifier: 0.0.24
115 version: 0.0.18(@clerk/electron-passkeys@0.0.3)(electron-store@8.2.0)(electron@41.5.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)115 version: 0.0.24(@clerk/electron-passkeys@0.0.3)(electron-store@8.2.0)(electron@41.5.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
116 '@clerk/electron-passkeys':116 '@clerk/electron-passkeys':
117 specifier: 0.0.3117 specifier: 0.0.3
118 version: 0.0.3118 version: 0.0.3
...@@ -197,8 +197,8 @@ importers:...@@ -197,8 +197,8 @@ importers:
197 specifier: ^0.7.1197 specifier: ^0.7.1
198 version: 0.7.1(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)198 version: 0.7.1(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)
199 '@clerk/expo':199 '@clerk/expo':
200 specifier: 4.0.2200 specifier: 4.1.2
201 version: 4.0.2(expo-auth-session@56.0.14(expo@56.0.12)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(expo-constants@56.0.18)(expo-crypto@56.0.4(expo@56.0.12))(expo-secure-store@56.0.4(expo@56.0.12))(expo-web-browser@56.0.5(expo@56.0.12)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)))(expo@56.0.12)(react-dom@19.2.3(react@19.2.3))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(typescript@6.0.3)201 version: 4.1.2(expo-auth-session@56.0.14(expo@56.0.12)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(expo-constants@56.0.18)(expo-crypto@56.0.4(expo@56.0.12))(expo-secure-store@56.0.4(expo@56.0.12))(expo-web-browser@56.0.5(expo@56.0.12)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)))(expo@56.0.12)(react-dom@19.2.3(react@19.2.3))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(typescript@6.0.3)
202 '@effect/atom-react':202 '@effect/atom-react':
203 specifier: 4.0.0-beta.102203 specifier: 4.0.0-beta.102
204 version: 4.0.0-beta.102(effect@4.0.0-beta.102(patch_hash=71215759e1ac0a7f65d7b75d816986687ae6c3a6cba02d928d184ca71790d488))(react@19.2.3)(scheduler@0.27.0)204 version: 4.0.0-beta.102(effect@4.0.0-beta.102(patch_hash=71215759e1ac0a7f65d7b75d816986687ae6c3a6cba02d928d184ca71790d488))(react@19.2.3)(scheduler@0.27.0)
...@@ -514,11 +514,11 @@ importers:...@@ -514,11 +514,11 @@ importers:
514 specifier: ^1.4.1514 specifier: ^1.4.1
515 version: 1.5.0(@types/react@19.2.16)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)515 version: 1.5.0(@types/react@19.2.16)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
516 '@clerk/electron':516 '@clerk/electron':
517 specifier: 0.0.18517 specifier: 0.0.24
518 version: 0.0.18(@clerk/electron-passkeys@0.0.3)(electron-store@8.2.0)(electron@41.5.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)518 version: 0.0.24(@clerk/electron-passkeys@0.0.3)(electron-store@8.2.0)(electron@41.5.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
519 '@clerk/react':519 '@clerk/react':
520 specifier: 6.12.7520 specifier: 6.12.9
521 version: 6.12.7(react-dom@19.2.6(react@19.2.6))(react@19.2.6)521 version: 6.12.9(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
522 '@dnd-kit/core':522 '@dnd-kit/core':
523 specifier: ^6.3.1523 specifier: ^6.3.1
524 version: 6.3.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6)524 version: 6.3.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
...@@ -668,8 +668,8 @@ importers:...@@ -668,8 +668,8 @@ importers:
668 infra/relay:668 infra/relay:
669 dependencies:669 dependencies:
670 '@clerk/backend':670 '@clerk/backend':
671 specifier: 3.13.0671 specifier: 3.14.0
672 version: 3.13.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)672 version: 3.14.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
673 '@effect/sql-pg':673 '@effect/sql-pg':
674 specifier: 4.0.0-beta.102674 specifier: 4.0.0-beta.102
675 version: 4.0.0-beta.102(effect@4.0.0-beta.102(patch_hash=71215759e1ac0a7f65d7b75d816986687ae6c3a6cba02d928d184ca71790d488))675 version: 4.0.0-beta.102(effect@4.0.0-beta.102(patch_hash=71215759e1ac0a7f65d7b75d816986687ae6c3a6cba02d928d184ca71790d488))
...@@ -1695,12 +1695,12 @@ packages:...@@ -1695,12 +1695,12 @@ packages:
1695 resolution: {integrity: sha512-EYlRokl8szrP9Z25qT5aepMdBjzBvHF9ZEhzIiUBc9guz/T31EqRgvD0QSgZcpE93xiwrr+OkB4nz0BZyF6fSA==}1695 resolution: {integrity: sha512-EYlRokl8szrP9Z25qT5aepMdBjzBvHF9ZEhzIiUBc9guz/T31EqRgvD0QSgZcpE93xiwrr+OkB4nz0BZyF6fSA==}
1696 engines: {node: '>= 20.12.0'}1696 engines: {node: '>= 20.12.0'}
16971697
1698 '@clerk/backend@3.13.0':1698 '@clerk/backend@3.14.0':
1699 resolution: {integrity: sha512-kYOgeR48iXYypudpYITE0L2yxi4TeFXU+ISAOULlVgOcurw8qnm1/JEuK6Mr2IFUbRS9hcHk1HVO0Ceo0XmL8Q==}1699 resolution: {integrity: sha512-WsphTvDFHDuQilKI7dyVE5qmt7USu8qSrujAq6SqpEHbVFfNBfINDNuzxlF9M2skOTfHFfgiTE8Jjb1egIBGLg==}
1700 engines: {node: '>=20.9.0'}1700 engines: {node: '>=20.9.0'}
17011701
1702 '@clerk/clerk-js@6.25.7':1702 '@clerk/clerk-js@6.25.12':
1703 resolution: {integrity: sha512-GOnbEUzPKAdsdCodZsHhku2YloBBuwLGx5UP0VeezUj73wKLwlSYMlVPuntsJoY7c8+lVrMCY9LQWYVZ7VMLBw==}1703 resolution: {integrity: sha512-N91mFKenMF5e+LRQ0NsqFb8bw+icbwnF8MzjzS4cux72xG4Gekh772tiLIetbURe44Srgjw5lj8jkWbt+yH/FA==}
1704 engines: {node: '>=20.9.0'}1704 engines: {node: '>=20.9.0'}
17051705
1706 '@clerk/electron-passkeys-darwin-arm64@0.0.3':1706 '@clerk/electron-passkeys-darwin-arm64@0.0.3':
...@@ -1727,8 +1727,8 @@ packages:...@@ -1727,8 +1727,8 @@ packages:
1727 resolution: {integrity: sha512-OHhIe88qDL+FxyBalXdXNHAS5eEramr6Rerp+6iNkfkjqT8rx4hHNmfpmjg5/T1/am8QfknbOBZkqoXZlCrjPg==}1727 resolution: {integrity: sha512-OHhIe88qDL+FxyBalXdXNHAS5eEramr6Rerp+6iNkfkjqT8rx4hHNmfpmjg5/T1/am8QfknbOBZkqoXZlCrjPg==}
1728 engines: {node: '>=20.9.0'}1728 engines: {node: '>=20.9.0'}
17291729
1730 '@clerk/electron@0.0.18':1730 '@clerk/electron@0.0.24':
1731 resolution: {integrity: sha512-0lWiITlTxCviglPfPSu+uhERnQyXroiWrSMRpZcEO3FgBt3bnrpfgZUrXW8iaLoUYJrFP2byF7bHJPRwEPVXEw==}1731 resolution: {integrity: sha512-xORO51KLzCqmRQ4IVsa+Amp1M5NjG28QnvsaRBq1v4CUEjH8vAXDKCPiPBKAE+HuQB6HUhzYmzUkyTw2FcDonw==}
1732 engines: {node: '>=20.9.0'}1732 engines: {node: '>=20.9.0'}
1733 peerDependencies:1733 peerDependencies:
1734 '@clerk/electron-passkeys': 0.0.31734 '@clerk/electron-passkeys': 0.0.3
...@@ -1744,8 +1744,8 @@ packages:...@@ -1744,8 +1744,8 @@ packages:
1744 react-dom:1744 react-dom:
1745 optional: true1745 optional: true
17461746
1747 '@clerk/expo@4.0.2':1747 '@clerk/expo@4.1.2':
1748 resolution: {integrity: sha512-afBdV2bLRM55p5L7FoAGV/wCamLxXusjIBPmNo+TwAYabU0oUokMsm+0++xWDA0nxzMt/O08Oj+xAGEtE+Qvxg==}1748 resolution: {integrity: sha512-ZyGozbbizcGwEyK0CEXsPHnHnQoaa2CbTsXAqWBygzKEZyFjLjCHwQsQBKj6WgjAgn8mtw2ByIP9qLpItZffgw==}
1749 engines: {node: '>=20.9.0'}1749 engines: {node: '>=20.9.0'}
1750 peerDependencies:1750 peerDependencies:
1751 '@clerk/expo-google-signin': '>=0.1.0'1751 '@clerk/expo-google-signin': '>=0.1.0'
...@@ -1783,15 +1783,15 @@ packages:...@@ -1783,15 +1783,15 @@ packages:
1783 react-dom:1783 react-dom:
1784 optional: true1784 optional: true
17851785
1786 '@clerk/react@6.12.7':1786 '@clerk/react@6.12.9':
1787 resolution: {integrity: sha512-K8CK0tS7My/3RT5sAIJTjYgnH0xU+K4Jdnhi76xQdAY4agD/M07BbrBMWXEE0xUEDst2PqPfX660V1LRLOsxOQ==}1787 resolution: {integrity: sha512-lQ1UOJhHGDweLCDf4IgT5r3rgkch1Gx21hNqK2/kOohJrJd/XM89fq2F7VK9Kg/Byc14TsfCh64Dm8ej2MyRWw==}
1788 engines: {node: '>=20.9.0'}1788 engines: {node: '>=20.9.0'}
1789 peerDependencies:1789 peerDependencies:
1790 react: ^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-01790 react: ^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0
1791 react-dom: ^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-01791 react-dom: ^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0
17921792
1793 '@clerk/shared@4.25.7':1793 '@clerk/shared@4.25.9':
1794 resolution: {integrity: sha512-FfBbDeFkxwDuz/2YcVs4DhyZ0VxnqNtdbO0Tn/lkLAiDvFFspWw+PDYqo7LQiBymEQaOQkb094dX21WWnZbmlA==}1794 resolution: {integrity: sha512-nw3maGzqPrwmUKjGffOM9Zvw24IyOllq0TkQGzsTfQX312WLu2u5CNvjKntMb6Ok6kXa1Zdc77zmPLn1/EAIFA==}
1795 engines: {node: '>=20.9.0'}1795 engines: {node: '>=20.9.0'}
1796 peerDependencies:1796 peerDependencies:
1797 react: ^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-01797 react: ^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0
...@@ -11512,18 +11512,18 @@ snapshots:...@@ -11512,18 +11512,18 @@ snapshots:
11512 fast-wrap-ansi: 0.2.211512 fast-wrap-ansi: 0.2.2
11513 sisteransi: 1.0.511513 sisteransi: 1.0.5
1151411514
11515 '@clerk/backend@3.13.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':11515 '@clerk/backend@3.14.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
11516 dependencies:11516 dependencies:
11517 '@clerk/shared': 4.25.7(react-dom@19.2.6(react@19.2.6))(react@19.2.6)11517 '@clerk/shared': 4.25.9(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
11518 standardwebhooks: 1.0.011518 standardwebhooks: 1.0.0
11519 tslib: 2.8.111519 tslib: 2.8.1
11520 transitivePeerDependencies:11520 transitivePeerDependencies:
11521 - react11521 - react
11522 - react-dom11522 - react-dom
1152311523
11524 '@clerk/clerk-js@6.25.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':11524 '@clerk/clerk-js@6.25.12(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
11525 dependencies:11525 dependencies:
11526 '@clerk/shared': 4.25.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3)11526 '@clerk/shared': 4.25.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
11527 '@stripe/stripe-js': 5.6.011527 '@stripe/stripe-js': 5.6.0
11528 '@swc/helpers': 0.5.2111528 '@swc/helpers': 0.5.21
11529 '@tanstack/query-core': 5.100.1411529 '@tanstack/query-core': 5.100.14
...@@ -11538,9 +11538,9 @@ snapshots:...@@ -11538,9 +11538,9 @@ snapshots:
11538 - react11538 - react
11539 - react-dom11539 - react-dom
1154011540
11541 '@clerk/clerk-js@6.25.7(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':11541 '@clerk/clerk-js@6.25.12(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
11542 dependencies:11542 dependencies:
11543 '@clerk/shared': 4.25.7(react-dom@19.2.6(react@19.2.6))(react@19.2.6)11543 '@clerk/shared': 4.25.9(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
11544 '@stripe/stripe-js': 5.6.011544 '@stripe/stripe-js': 5.6.0
11545 '@swc/helpers': 0.5.2111545 '@swc/helpers': 0.5.21
11546 '@tanstack/query-core': 5.100.1411546 '@tanstack/query-core': 5.100.14
...@@ -11574,11 +11574,11 @@ snapshots:...@@ -11574,11 +11574,11 @@ snapshots:
11574 '@clerk/electron-passkeys-win32-arm64-msvc': 0.0.311574 '@clerk/electron-passkeys-win32-arm64-msvc': 0.0.3
11575 '@clerk/electron-passkeys-win32-x64-msvc': 0.0.311575 '@clerk/electron-passkeys-win32-x64-msvc': 0.0.3
1157611576
11577 '@clerk/electron@0.0.18(@clerk/electron-passkeys@0.0.3)(electron-store@8.2.0)(electron@41.5.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':11577 '@clerk/electron@0.0.24(@clerk/electron-passkeys@0.0.3)(electron-store@8.2.0)(electron@41.5.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
11578 dependencies:11578 dependencies:
11579 '@clerk/clerk-js': 6.25.7(react-dom@19.2.6(react@19.2.6))(react@19.2.6)11579 '@clerk/clerk-js': 6.25.12(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
11580 '@clerk/react': 6.12.7(react-dom@19.2.6(react@19.2.6))(react@19.2.6)11580 '@clerk/react': 6.12.9(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
11581 '@clerk/shared': 4.25.7(react-dom@19.2.6(react@19.2.6))(react@19.2.6)11581 '@clerk/shared': 4.25.9(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
11582 electron: 41.5.011582 electron: 41.5.0
11583 react: 19.2.611583 react: 19.2.6
11584 tslib: 2.8.111584 tslib: 2.8.1
...@@ -11587,11 +11587,11 @@ snapshots:...@@ -11587,11 +11587,11 @@ snapshots:
11587 electron-store: 8.2.011587 electron-store: 8.2.0
11588 react-dom: 19.2.6(react@19.2.6)11588 react-dom: 19.2.6(react@19.2.6)
1158911589
11590 '@clerk/expo@4.0.2(expo-auth-session@56.0.14(expo@56.0.12)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(expo-constants@56.0.18)(expo-crypto@56.0.4(expo@56.0.12))(expo-secure-store@56.0.4(expo@56.0.12))(expo-web-browser@56.0.5(expo@56.0.12)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)))(expo@56.0.12)(react-dom@19.2.3(react@19.2.3))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(typescript@6.0.3)':11590 '@clerk/expo@4.1.2(expo-auth-session@56.0.14(expo@56.0.12)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3))(expo-constants@56.0.18)(expo-crypto@56.0.4(expo@56.0.12))(expo-secure-store@56.0.4(expo@56.0.12))(expo-web-browser@56.0.5(expo@56.0.12)(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6)))(expo@56.0.12)(react-dom@19.2.3(react@19.2.3))(react-native@0.85.3(@babel/core@7.29.7)(@react-native/metro-config@0.85.3(@babel/core@7.29.7)(bufferutil@4.1.0)(utf-8-validate@6.0.6))(@types/react@19.2.16)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@6.0.6))(react@19.2.3)(typescript@6.0.3)':
11591 dependencies:11591 dependencies:
11592 '@clerk/clerk-js': 6.25.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3)11592 '@clerk/clerk-js': 6.25.12(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
11593 '@clerk/react': 6.12.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3)11593 '@clerk/react': 6.12.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
11594 '@clerk/shared': 4.25.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3)11594 '@clerk/shared': 4.25.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
11595 '@expo/config-plugins': 56.0.9(typescript@6.0.3)11595 '@expo/config-plugins': 56.0.9(typescript@6.0.3)
11596 base-64: 1.0.011596 base-64: 1.0.0
11597 expo: 56.0.12(8895228379997a2a064f9644cda56ed0)11597 expo: 56.0.12(8895228379997a2a064f9644cda56ed0)
...@@ -11610,21 +11610,21 @@ snapshots:...@@ -11610,21 +11610,21 @@ snapshots:
11610 - supports-color11610 - supports-color
11611 - typescript11611 - typescript
1161211612
11613 '@clerk/react@6.12.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':11613 '@clerk/react@6.12.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
11614 dependencies:11614 dependencies:
11615 '@clerk/shared': 4.25.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3)11615 '@clerk/shared': 4.25.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
11616 react: 19.2.311616 react: 19.2.3
11617 react-dom: 19.2.3(react@19.2.3)11617 react-dom: 19.2.3(react@19.2.3)
11618 tslib: 2.8.111618 tslib: 2.8.1
1161911619
11620 '@clerk/react@6.12.7(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':11620 '@clerk/react@6.12.9(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
11621 dependencies:11621 dependencies:
11622 '@clerk/shared': 4.25.7(react-dom@19.2.6(react@19.2.6))(react@19.2.6)11622 '@clerk/shared': 4.25.9(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
11623 react: 19.2.611623 react: 19.2.6
11624 react-dom: 19.2.6(react@19.2.6)11624 react-dom: 19.2.6(react@19.2.6)
11625 tslib: 2.8.111625 tslib: 2.8.1
1162611626
11627 '@clerk/shared@4.25.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':11627 '@clerk/shared@4.25.9(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
11628 dependencies:11628 dependencies:
11629 '@tanstack/query-core': 5.100.1411629 '@tanstack/query-core': 5.100.14
11630 dequal: 2.0.311630 dequal: 2.0.3
...@@ -11634,7 +11634,7 @@ snapshots:...@@ -11634,7 +11634,7 @@ snapshots:
11634 react: 19.2.311634 react: 19.2.3
11635 react-dom: 19.2.3(react@19.2.3)11635 react-dom: 19.2.3(react@19.2.3)
1163611636
11637 '@clerk/shared@4.25.7(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':11637 '@clerk/shared@4.25.9(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
11638 dependencies:11638 dependencies:
11639 '@tanstack/query-core': 5.100.1411639 '@tanstack/query-core': 5.100.14
11640 dequal: 2.0.311640 dequal: 2.0.3
pnpm-workspace.yaml+12-12
...@@ -23,13 +23,13 @@ allowBuilds:...@@ -23,13 +23,13 @@ allowBuilds:
23 workerd: false23 workerd: false
2424
25catalog:25catalog:
26 "@clerk/backend": 3.13.026 "@clerk/backend": 3.14.0
27 "@clerk/clerk-js": 6.25.727 "@clerk/clerk-js": 6.25.12
28 "@clerk/electron": 0.0.1828 "@clerk/electron": 0.0.24
29 "@clerk/electron-passkeys": 0.0.329 "@clerk/electron-passkeys": 0.0.3
30 "@clerk/expo": 4.0.230 "@clerk/expo": 4.1.2
31 "@clerk/react": 6.12.731 "@clerk/react": 6.12.9
32 "@clerk/shared": 4.25.732 "@clerk/shared": 4.25.9
33 "@effect/atom-react": 4.0.0-beta.10233 "@effect/atom-react": 4.0.0-beta.102
34 "@effect/openapi-generator": 4.0.0-beta.10234 "@effect/openapi-generator": 4.0.0-beta.102
35 "@effect/platform-bun": 4.0.0-beta.10235 "@effect/platform-bun": 4.0.0-beta.102
...@@ -52,12 +52,12 @@ catalog:...@@ -52,12 +52,12 @@ catalog:
52 yaml: ^2.9.052 yaml: ^2.9.0
5353
54minimumReleaseAgeExclude:54minimumReleaseAgeExclude:
55 - "@clerk/backend@3.13.0"55 - "@clerk/backend@3.14.0"
56 - "@clerk/clerk-js@6.25.7"56 - "@clerk/clerk-js@6.25.12"
57 - "@clerk/electron@0.0.18"57 - "@clerk/electron@0.0.24"
58 - "@clerk/expo@4.0.2"58 - "@clerk/expo@4.1.2"
59 - "@clerk/react@6.12.7"59 - "@clerk/react@6.12.9"
60 - "@clerk/shared@4.25.7"60 - "@clerk/shared@4.25.9"
61 - "@distilled.cloud/aws@0.30.2"61 - "@distilled.cloud/aws@0.30.2"
62 - "@distilled.cloud/axiom@0.30.2"62 - "@distilled.cloud/axiom@0.30.2"
63 - "@distilled.cloud/cloudflare@0.30.2"63 - "@distilled.cloud/cloudflare@0.30.2"
scripts/build-desktop-artifact.test.ts+5
...@@ -349,6 +349,11 @@ it.layer(NodeServices.layer)("build-desktop-artifact", (it) => {...@@ -349,6 +349,11 @@ it.layer(NodeServices.layer)("build-desktop-artifact", (it) => {
349 assert.notProperty(mac, "asarUnpack");349 assert.notProperty(mac, "asarUnpack");
350 assert.notProperty(linux, "asarUnpack");350 assert.notProperty(linux, "asarUnpack");
351 assert.deepStrictEqual(win.asarUnpack, WINDOWS_ASAR_UNPACK);351 assert.deepStrictEqual(win.asarUnpack, WINDOWS_ASAR_UNPACK);
352 // Linux must register the renderer schemes so the generated .desktop
353 // entry advertises MimeType=x-scheme-handler/t3code; for OAuth deep links.
354 assert.deepStrictEqual((linux.linux as Record<string, unknown>).protocols, [
355 { name: "T3 Code", schemes: ["t3code", "t3code-dev"] },
356 ]);
352 for (const config of [mac, linux, win]) {357 for (const config of [mac, linux, win]) {
353 assert.deepStrictEqual(config.electronLanguages, DESKTOP_ELECTRON_LANGUAGES);358 assert.deepStrictEqual(config.electronLanguages, DESKTOP_ELECTRON_LANGUAGES);
354 assert.deepStrictEqual(config.files, DESKTOP_FILE_EXCLUSIONS);359 assert.deepStrictEqual(config.files, DESKTOP_FILE_EXCLUSIONS);
scripts/build-desktop-artifact.ts+9
...@@ -1589,6 +1589,15 @@ export const createBuildConfig = Effect.fn("createBuildConfig")(function* (...@@ -1589,6 +1589,15 @@ export const createBuildConfig = Effect.fn("createBuildConfig")(function* (
1589 executableName: "t3code",1589 executableName: "t3code",
1590 icon: "icons",1590 icon: "icons",
1591 category: "Development",1591 category: "Development",
1592 // electron-builder turns these into MimeType=x-scheme-handler/<scheme>;
1593 // in the .desktop entry (Exec already gets %U), so browsers can hand
1594 // t3code:// OAuth callbacks to the app.
1595 protocols: [
1596 {
1597 name: "T3 Code",
1598 schemes: ["t3code", "t3code-dev"],
1599 },
1600 ],
1592 desktop: {1601 desktop: {
1593 entry: {1602 entry: {
1594 StartupWMClass: "t3code",1603 StartupWMClass: "t3code",