From d08d2a8a715044758e76040f22d203c0360e869e Mon Sep 17 00:00:00 2001 From: Satya Patel Date: Tue, 13 Jan 2026 17:31:14 -0800 Subject: [PATCH 01/12] feat(desktop): add core auth infrastructure (renderer-based) --- apps/desktop/package.json | 1 + .../src/lib/trpc/routers/auth/index.ts | 121 +++++++++++++----- .../trpc/routers/auth/utils/auth-functions.ts | 99 ++++++++++++++ .../trpc/routers/auth/utils/crypto-storage.ts | 119 +++++++++++++++++ apps/desktop/src/lib/trpc/routers/index.ts | 4 - apps/desktop/src/main/index.ts | 12 +- apps/desktop/src/renderer/lib/auth-client.ts | 32 +++++ .../desktop/src/renderer/lib/electron-trpc.ts | 10 ++ apps/desktop/src/renderer/lib/trpc-client.ts | 10 +- .../providers/AuthProvider/AuthProvider.tsx | 88 +++++++++---- .../renderer/providers/AuthProvider/index.ts | 2 +- .../ElectronTRPCProvider.tsx | 39 ++++++ .../providers/ElectronTRPCProvider/index.ts | 1 + 13 files changed, 460 insertions(+), 78 deletions(-) create mode 100644 apps/desktop/src/lib/trpc/routers/auth/utils/auth-functions.ts create mode 100644 apps/desktop/src/lib/trpc/routers/auth/utils/crypto-storage.ts create mode 100644 apps/desktop/src/renderer/lib/auth-client.ts create mode 100644 apps/desktop/src/renderer/lib/electron-trpc.ts create mode 100644 apps/desktop/src/renderer/providers/ElectronTRPCProvider/ElectronTRPCProvider.tsx create mode 100644 apps/desktop/src/renderer/providers/ElectronTRPCProvider/index.ts diff --git a/apps/desktop/package.json b/apps/desktop/package.json index cb4d91355..a581d7728 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -70,6 +70,7 @@ "@xterm/addon-webgl": "^0.18.0", "@xterm/headless": "^5.5.0", "@xterm/xterm": "^5.5.0", + "better-auth": "^1.4.9", "better-sqlite3": "12.5.0", "bindings": "^1.5.0", "clsx": "^2.1.1", diff --git a/apps/desktop/src/lib/trpc/routers/auth/index.ts b/apps/desktop/src/lib/trpc/routers/auth/index.ts index 2b980cfb1..04fc4798c 100644 --- a/apps/desktop/src/lib/trpc/routers/auth/index.ts +++ b/apps/desktop/src/lib/trpc/routers/auth/index.ts @@ -1,62 +1,113 @@ +import crypto from "node:crypto"; +import fs from "node:fs/promises"; import { AUTH_PROVIDERS } from "@superset/shared/constants"; import { observable } from "@trpc/server/observable"; -import { type AuthSession, authService } from "main/lib/auth"; +import { shell } from "electron"; +import { env } from "main/env.main"; import { z } from "zod"; import { publicProcedure, router } from "../.."; - -/** Auth state emitted by onAuthState subscription */ -export type AuthState = (AuthSession & { token: string | null }) | null; +import { + authEvents, + loadToken, + saveToken, + stateStore, + TOKEN_FILE, +} from "./utils/auth-functions"; export const createAuthRouter = () => { return router({ - onAuthState: publicProcedure.subscription(() => { - return observable((emit) => { - const emitCurrent = () => { - const sessionData = authService.getSession(); - const token = authService.getAccessToken(); + /** + * Get initial token from encrypted disk storage. + * Called once on app startup for hydration. + */ + getStoredToken: publicProcedure.query(async () => { + return await loadToken(); + }), - if (!sessionData) { - emit.next(null); - return; + /** + * Persist token to encrypted disk storage. + * Called when renderer saves token to localStorage. + */ + persistToken: publicProcedure + .input( + z.object({ + token: z.string(), + expiresAt: z.string(), + }), + ) + .mutation(async ({ input }) => { + await saveToken(input); + return { success: true }; + }), + + /** + * Subscribe to token changes from deep link callbacks. + * CRITICAL: Notifies renderer when OAuth callback saves new token. + * Without this, renderer wouldn't know to update localStorage after OAuth. + */ + onTokenChanged: publicProcedure.subscription(() => { + return observable<{ token: string; expiresAt: string } | null>((emit) => { + // Emit initial token on subscription + loadToken().then((initial) => { + if (initial.token && initial.expiresAt) { + emit.next({ token: initial.token, expiresAt: initial.expiresAt }); } + }); - emit.next({ ...sessionData, token }); + const handler = (data: { token: string; expiresAt: string }) => { + emit.next(data); }; - emitCurrent(); - - const sessionHandler = () => { - emitCurrent(); - }; - const stateHandler = () => { - emitCurrent(); - }; - - authService.on("session-changed", sessionHandler); - authService.on("state-changed", stateHandler); + authEvents.on("token-saved", handler); return () => { - authService.off("session-changed", sessionHandler); - authService.off("state-changed", stateHandler); + authEvents.off("token-saved", handler); }; }); }), - setActiveOrganization: publicProcedure - .input(z.object({ organizationId: z.string() })) - .mutation(async ({ input }) => { - await authService.setActiveOrganization(input.organizationId); - return { success: true }; - }), - + /** + * Start OAuth sign-in flow. + * Opens browser for OAuth, token delivered via deep link callback. + */ signIn: publicProcedure .input(z.object({ provider: z.enum(AUTH_PROVIDERS) })) .mutation(async ({ input }) => { - return authService.signIn(input.provider); + try { + const state = crypto.randomBytes(32).toString("base64url"); + stateStore.set(state, Date.now()); + + // Clean up old states (older than 10 minutes) + const tenMinutesAgo = Date.now() - 10 * 60 * 1000; + for (const [s, ts] of stateStore) { + if (ts < tenMinutesAgo) stateStore.delete(s); + } + + const connectUrl = new URL( + `${env.NEXT_PUBLIC_API_URL}/api/auth/desktop/connect`, + ); + connectUrl.searchParams.set("provider", input.provider); + connectUrl.searchParams.set("state", state); + await shell.openExternal(connectUrl.toString()); + return { success: true }; + } catch (err) { + return { + success: false, + error: + err instanceof Error ? err.message : "Failed to open browser", + }; + } }), + /** + * Sign out - clears token from disk. + * Renderer should also clear localStorage and call authClient.signOut(). + */ signOut: publicProcedure.mutation(async () => { - await authService.signOut(); + console.log("[auth] Clearing token"); + try { + await fs.unlink(TOKEN_FILE); + } catch {} return { success: true }; }), }); diff --git a/apps/desktop/src/lib/trpc/routers/auth/utils/auth-functions.ts b/apps/desktop/src/lib/trpc/routers/auth/utils/auth-functions.ts new file mode 100644 index 000000000..8401e79b1 --- /dev/null +++ b/apps/desktop/src/lib/trpc/routers/auth/utils/auth-functions.ts @@ -0,0 +1,99 @@ +import { EventEmitter } from "node:events"; +import fs from "node:fs/promises"; +import { join } from "node:path"; +import { PROTOCOL_SCHEMES } from "@superset/shared/constants"; +import { SUPERSET_HOME_DIR } from "main/lib/app-environment"; +import { decrypt, encrypt } from "./crypto-storage"; + +interface StoredAuth { + token: string; + expiresAt: string; +} + +export const TOKEN_FILE = join(SUPERSET_HOME_DIR, "auth-token.enc"); +export const stateStore = new Map(); + +/** + * Event emitter for auth-related events. + * Used by tRPC subscription to notify renderer of token changes. + */ +export const authEvents = new EventEmitter(); + +/** + * Load token from encrypted disk storage. + */ +export async function loadToken(): Promise<{ + token: string | null; + expiresAt: string | null; +}> { + try { + const data = decrypt(await fs.readFile(TOKEN_FILE)); + const parsed: StoredAuth = JSON.parse(data); + console.log("[auth] Token loaded from disk"); + return { token: parsed.token, expiresAt: parsed.expiresAt }; + } catch { + return { token: null, expiresAt: null }; + } +} + +/** + * Persist token to encrypted disk storage and notify subscribers. + */ +export async function saveToken({ + token, + expiresAt, +}: { + token: string; + expiresAt: string; +}): Promise { + const storedAuth: StoredAuth = { token, expiresAt }; + await fs.writeFile(TOKEN_FILE, encrypt(JSON.stringify(storedAuth))); + console.log("[auth] Token saved to disk"); + + // Emit event for onTokenChanged subscription + authEvents.emit("token-saved", { token, expiresAt }); +} + +/** + * Handle OAuth callback from deep link. + * Validates CSRF state and saves token. + */ +export async function handleAuthCallback(params: { + token: string; + expiresAt: string; + state: string; +}): Promise<{ success: boolean; error?: string }> { + if (!stateStore.has(params.state)) { + return { success: false, error: "Invalid or expired auth session" }; + } + stateStore.delete(params.state); + + await saveToken({ token: params.token, expiresAt: params.expiresAt }); + + return { success: true }; +} + +/** + * Parse and validate auth deep link URL. + */ +export function parseAuthDeepLink( + url: string, +): { token: string; expiresAt: string; state: string } | null { + try { + const parsed = new URL(url); + const validProtocols = [ + `${PROTOCOL_SCHEMES.PROD}:`, + `${PROTOCOL_SCHEMES.DEV}:`, + ]; + if (!validProtocols.includes(parsed.protocol)) return null; + if (parsed.host !== "auth" || parsed.pathname !== "/callback") return null; + + const token = parsed.searchParams.get("token"); + const expiresAt = parsed.searchParams.get("expiresAt"); + const state = parsed.searchParams.get("state"); + if (!token || !expiresAt || !state) return null; + return { token, expiresAt, state }; + } catch { + return null; + } +} diff --git a/apps/desktop/src/lib/trpc/routers/auth/utils/crypto-storage.ts b/apps/desktop/src/lib/trpc/routers/auth/utils/crypto-storage.ts new file mode 100644 index 000000000..faeba16f7 --- /dev/null +++ b/apps/desktop/src/lib/trpc/routers/auth/utils/crypto-storage.ts @@ -0,0 +1,119 @@ +import { execFileSync } from "node:child_process"; +import { + createCipheriv, + createDecipheriv, + randomBytes, + scryptSync, +} from "node:crypto"; +import { readFileSync } from "node:fs"; +import { homedir, hostname, platform } from "node:os"; + +const ALGORITHM = "aes-256-gcm"; +const KEY_LENGTH = 32; +const SALT_LENGTH = 16; +const IV_LENGTH = 12; +const AUTH_TAG_LENGTH = 16; + +/** + * Gets a stable machine identifier for key derivation. + */ +function getMachineId(): string { + try { + const os = platform(); + + if (os === "darwin") { + // macOS: Use IOPlatformUUID (hardware UUID) + const output = execFileSync( + "ioreg", + ["-rd1", "-c", "IOPlatformExpertDevice"], + { encoding: "utf8" }, + ); + const match = output.match(/"IOPlatformUUID"\s*=\s*"([^"]+)"/); + if (match?.[1]) return match[1]; + } else if (os === "linux") { + // Linux: Use machine-id + try { + return readFileSync("/etc/machine-id", "utf8").trim(); + } catch { + return readFileSync("/var/lib/dbus/machine-id", "utf8").trim(); + } + } else if (os === "win32") { + // Windows: Use MachineGuid from registry + const output = execFileSync( + "reg", + [ + "query", + "HKLM\\SOFTWARE\\Microsoft\\Cryptography", + "/v", + "MachineGuid", + ], + { encoding: "utf8" }, + ); + const match = output.match(/MachineGuid\s+REG_SZ\s+(\S+)/); + if (match?.[1]) return match[1]; + } + } catch { + // Fallback if platform-specific method fails + } + + // Fallback: Use a combination of stable system properties + // This is less secure but ensures the app still works + return `${hostname()}-${homedir()}-superset-fallback`; +} + +/** + * Derives an encryption key from the machine ID and a salt. + */ +function deriveKey(salt: Buffer): Buffer { + const machineId = getMachineId(); + return scryptSync(machineId, salt, KEY_LENGTH); +} + +/** + * Encrypts a string using AES-256-GCM with a machine-derived key. + * Returns: salt (16) + iv (12) + authTag (16) + ciphertext + */ +export function encrypt(plaintext: string): Buffer { + const salt = randomBytes(SALT_LENGTH); + const key = deriveKey(salt); + const iv = randomBytes(IV_LENGTH); + + const cipher = createCipheriv(ALGORITHM, key, iv); + const encrypted = Buffer.concat([ + cipher.update(plaintext, "utf8"), + cipher.final(), + ]); + const authTag = cipher.getAuthTag(); + + // Combine all components: salt + iv + authTag + ciphertext + return Buffer.concat([salt, iv, authTag, encrypted]); +} + +const MIN_ENCRYPTED_LENGTH = SALT_LENGTH + IV_LENGTH + AUTH_TAG_LENGTH + 1; + +/** + * Decrypts data encrypted with the encrypt function. + */ +export function decrypt(data: Buffer): string { + if (data.length < MIN_ENCRYPTED_LENGTH) { + throw new Error("Encrypted data too short"); + } + + // Extract components + const salt = data.subarray(0, SALT_LENGTH); + const iv = data.subarray(SALT_LENGTH, SALT_LENGTH + IV_LENGTH); + const authTag = data.subarray( + SALT_LENGTH + IV_LENGTH, + SALT_LENGTH + IV_LENGTH + AUTH_TAG_LENGTH, + ); + const ciphertext = data.subarray(SALT_LENGTH + IV_LENGTH + AUTH_TAG_LENGTH); + + const key = deriveKey(salt); + const decipher = createDecipheriv(ALGORITHM, key, iv); + decipher.setAuthTag(authTag); + + return Buffer.concat([ + decipher.update(ciphertext), + decipher.final(), + ]).toString("utf8"); +} diff --git a/apps/desktop/src/lib/trpc/routers/index.ts b/apps/desktop/src/lib/trpc/routers/index.ts index 66ad3766f..7a59dad98 100644 --- a/apps/desktop/src/lib/trpc/routers/index.ts +++ b/apps/desktop/src/lib/trpc/routers/index.ts @@ -13,10 +13,8 @@ import { createPortsRouter } from "./ports"; import { createProjectsRouter } from "./projects"; import { createRingtoneRouter } from "./ringtone"; import { createSettingsRouter } from "./settings"; -import { createTasksRouter } from "./tasks"; import { createTerminalRouter } from "./terminal"; import { createUiStateRouter } from "./ui-state"; -import { createUserRouter } from "./user"; import { createWindowRouter } from "./window"; import { createWorkspacesRouter } from "./workspaces"; @@ -25,7 +23,6 @@ export const createAppRouter = (getWindow: () => BrowserWindow | null) => { analytics: createAnalyticsRouter(), auth: createAuthRouter(), autoUpdate: createAutoUpdateRouter(), - user: createUserRouter(), window: createWindowRouter(getWindow), projects: createProjectsRouter(getWindow), workspaces: createWorkspacesRouter(), @@ -40,7 +37,6 @@ export const createAppRouter = (getWindow: () => BrowserWindow | null) => { config: createConfigRouter(), uiState: createUiStateRouter(), ringtone: createRingtoneRouter(), - tasks: createTasksRouter(), }); }; diff --git a/apps/desktop/src/main/index.ts b/apps/desktop/src/main/index.ts index 156987bae..1c5b29f37 100644 --- a/apps/desktop/src/main/index.ts +++ b/apps/desktop/src/main/index.ts @@ -6,14 +6,16 @@ import path from "node:path"; import { settings } from "@superset/local-db"; import { app, BrowserWindow, dialog } from "electron"; import { makeAppSetup } from "lib/electron-app/factories/app/setup"; +import { + handleAuthCallback, + parseAuthDeepLink, +} from "lib/trpc/routers/auth/utils/auth-functions"; import { DEFAULT_CONFIRM_ON_QUIT, PROTOCOL_SCHEME } from "shared/constants"; import { setupAgentHooks } from "./lib/agent-setup"; import { posthog } from "./lib/analytics"; import { initAppState } from "./lib/app-state"; -import { authService, parseAuthDeepLink } from "./lib/auth"; import { setupAutoUpdater } from "./lib/auto-updater"; import { localDb } from "./lib/local-db"; -import { requestLocalNetworkAccess } from "./lib/local-network-permission"; import { ensureShellEnvVars } from "./lib/shell-env"; import { terminalManager } from "./lib/terminal"; import { MainWindow } from "./windows/main"; @@ -42,7 +44,7 @@ async function processDeepLink(url: string): Promise { const authParams = parseAuthDeepLink(url); if (!authParams) return; - const result = await authService.handleAuthCallback(authParams); + const result = await handleAuthCallback(authParams); if (result.success) { focusMainWindow(); } else { @@ -206,11 +208,7 @@ if (!gotTheLock) { (async () => { await app.whenReady(); - // Request local network access early to trigger the macOS permission prompt - requestLocalNetworkAccess(); - await initAppState(); - await authService.initialize(); // Resolve shell environment before setting up agent hooks // This ensures ZDOTDIR and PATH are available for terminal initialization diff --git a/apps/desktop/src/renderer/lib/auth-client.ts b/apps/desktop/src/renderer/lib/auth-client.ts new file mode 100644 index 000000000..d4a21c520 --- /dev/null +++ b/apps/desktop/src/renderer/lib/auth-client.ts @@ -0,0 +1,32 @@ +import { organizationClient } from "better-auth/client/plugins"; +import { createAuthClient } from "better-auth/react"; +import { env } from "renderer/env.renderer"; + +let authToken: string | null = null; + +export function setAuthToken(token: string | null) { + authToken = token; +} + +export function getAuthToken(): string | null { + return authToken; +} + +/** + * Better Auth client for Electron desktop app. + * + * Security: Token stored in memory only (not localStorage). + * - Better Auth reads token via getter function + * - AuthProvider manages token in React context + * - Token persisted only to encrypted disk storage (main process) + */ +export const authClient = createAuthClient({ + baseURL: env.NEXT_PUBLIC_API_URL, + plugins: [organizationClient()], + fetchOptions: { + auth: { + type: "Bearer", + token: () => authToken || "", + }, + }, +}); diff --git a/apps/desktop/src/renderer/lib/electron-trpc.ts b/apps/desktop/src/renderer/lib/electron-trpc.ts new file mode 100644 index 000000000..c7a4f24e7 --- /dev/null +++ b/apps/desktop/src/renderer/lib/electron-trpc.ts @@ -0,0 +1,10 @@ +import { createTRPCReact } from "@trpc/react-query"; +import type { inferRouterOutputs } from "@trpc/server"; +import type { AppRouter } from "lib/trpc/routers"; + +/** + * tRPC React client for Electron IPC communication with main process. + * For desktop-specific operations: workspaces, terminal, auth, etc. + */ +export const electronTrpc = createTRPCReact(); +export type ElectronRouterOutputs = inferRouterOutputs; diff --git a/apps/desktop/src/renderer/lib/trpc-client.ts b/apps/desktop/src/renderer/lib/trpc-client.ts index 8dc7cc2d0..c7b868b5c 100644 --- a/apps/desktop/src/renderer/lib/trpc-client.ts +++ b/apps/desktop/src/renderer/lib/trpc-client.ts @@ -2,15 +2,15 @@ import { createTRPCProxyClient } from "@trpc/client"; import type { AppRouter } from "lib/trpc/routers"; import superjson from "superjson"; import { ipcLink } from "trpc-electron/renderer"; +import { electronTrpc } from "./electron-trpc"; import { sessionIdLink } from "./session-id-link"; -import { trpc } from "./trpc"; -/** tRPC client for React hooks (used by TRPCProvider). */ -export const reactClient = trpc.createClient({ +/** Electron tRPC React client for React hooks (used by ElectronTRPCProvider). */ +export const electronReactClient = electronTrpc.createClient({ links: [sessionIdLink(), ipcLink({ transformer: superjson })], }); -/** tRPC proxy client for imperative calls from stores/utilities. */ -export const trpcClient = createTRPCProxyClient({ +/** Electron tRPC proxy client for imperative calls from stores/utilities. */ +export const electronTrpcClient = createTRPCProxyClient({ links: [sessionIdLink(), ipcLink({ transformer: superjson })], }); diff --git a/apps/desktop/src/renderer/providers/AuthProvider/AuthProvider.tsx b/apps/desktop/src/renderer/providers/AuthProvider/AuthProvider.tsx index 1af207f10..749ea41e2 100644 --- a/apps/desktop/src/renderer/providers/AuthProvider/AuthProvider.tsx +++ b/apps/desktop/src/renderer/providers/AuthProvider/AuthProvider.tsx @@ -5,38 +5,70 @@ import { useEffect, useState, } from "react"; -import type { RouterOutputs } from "../../lib/trpc"; -import { trpc } from "../../lib/trpc"; +import { authClient, setAuthToken } from "renderer/lib/auth-client"; +import { electronTrpc } from "../../lib/electron-trpc"; -type AuthState = RouterOutputs["auth"]["onAuthState"]; - -interface AuthContextValue { +interface AuthTokenContextValue { token: string | null; - session: AuthState; - isInitialized: boolean; } -const AuthContext = createContext(null); +const AuthTokenContext = createContext(null); export function AuthProvider({ children }: { children: ReactNode }) { - const { data: authState } = trpc.auth.onAuthState.useSubscription(); - const [isInitialized, setIsInitialized] = useState(false); + const [isHydrated, setIsHydrated] = useState(false); + const [token, setToken] = useState(null); + + const { data: session } = authClient.useSession(); + + const { data: storedToken } = electronTrpc.auth.getStoredToken.useQuery( + undefined, + { + refetchOnWindowFocus: false, + refetchOnReconnect: false, + }, + ); + + const persistMutation = electronTrpc.auth.persistToken.useMutation(); + + electronTrpc.auth.onTokenChanged.useSubscription(undefined, { + onData: (data) => { + if (data?.token && data?.expiresAt) { + setToken(data.token); + setAuthToken(data.token); + persistMutation.mutate({ + token: data.token, + expiresAt: data.expiresAt, + }); + } + }, + }); - // Mark as initialized once we receive the first auth state useEffect(() => { - if (authState !== undefined && !isInitialized) { - setIsInitialized(true); + if (storedToken && !isHydrated) { + if (storedToken.token && storedToken.expiresAt) { + setToken(storedToken.token); + setAuthToken(storedToken.token); + } + setIsHydrated(true); } - }, [authState, isInitialized]); + }, [storedToken, isHydrated]); - const value: AuthContextValue = { - token: authState?.token ?? null, - session: authState ?? null, - isInitialized, - }; + useEffect(() => { + if (token) { + setAuthToken(token); + } else { + setAuthToken(null); + } + }, [token]); + + useEffect(() => { + if (!session?.user && token) { + setToken(null); + setAuthToken(null); + } + }, [session, token]); - // Show loading spinner until auth state is initialized - if (!isInitialized) { + if (!isHydrated) { return (
@@ -44,13 +76,17 @@ export function AuthProvider({ children }: { children: ReactNode }) { ); } - return {children}; + return ( + + {children} + + ); } -export function useAuth(): AuthContextValue { - const context = useContext(AuthContext); +export function useAuthToken(): string | null { + const context = useContext(AuthTokenContext); if (!context) { - throw new Error("useAuth must be used within AuthProvider"); + throw new Error("useAuthToken must be used within AuthProvider"); } - return context; + return context.token; } diff --git a/apps/desktop/src/renderer/providers/AuthProvider/index.ts b/apps/desktop/src/renderer/providers/AuthProvider/index.ts index 487e3204b..8ec6b18fa 100644 --- a/apps/desktop/src/renderer/providers/AuthProvider/index.ts +++ b/apps/desktop/src/renderer/providers/AuthProvider/index.ts @@ -1 +1 @@ -export { AuthProvider, useAuth } from "./AuthProvider"; +export { AuthProvider, useAuthToken } from "./AuthProvider"; diff --git a/apps/desktop/src/renderer/providers/ElectronTRPCProvider/ElectronTRPCProvider.tsx b/apps/desktop/src/renderer/providers/ElectronTRPCProvider/ElectronTRPCProvider.tsx new file mode 100644 index 000000000..08972eed0 --- /dev/null +++ b/apps/desktop/src/renderer/providers/ElectronTRPCProvider/ElectronTRPCProvider.tsx @@ -0,0 +1,39 @@ +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { useState } from "react"; +import { electronTrpc } from "renderer/lib/electron-trpc"; +import { electronReactClient } from "../../lib/trpc-client"; + +/** + * Provider for Electron IPC tRPC client. + * For desktop-specific operations: workspaces, terminal, auth, etc. + */ +export function ElectronTRPCProvider({ + children, +}: { + children: React.ReactNode; +}) { + const [queryClient] = useState( + () => + new QueryClient({ + defaultOptions: { + queries: { + networkMode: "always", + retry: false, + }, + mutations: { + networkMode: "always", + retry: false, + }, + }, + }), + ); + + return ( + + {children} + + ); +} diff --git a/apps/desktop/src/renderer/providers/ElectronTRPCProvider/index.ts b/apps/desktop/src/renderer/providers/ElectronTRPCProvider/index.ts new file mode 100644 index 000000000..4483d5b6f --- /dev/null +++ b/apps/desktop/src/renderer/providers/ElectronTRPCProvider/index.ts @@ -0,0 +1 @@ +export { ElectronTRPCProvider } from "./ElectronTRPCProvider"; From 7533e7f6dea9d691c2748bb1b1434ac8022e75f5 Mon Sep 17 00:00:00 2001 From: Satya Patel Date: Tue, 13 Jan 2026 17:31:16 -0800 Subject: [PATCH 02/12] feat(desktop): update TRPCProvider with API client and auth providers --- .../providers/TRPCProvider/TRPCProvider.tsx | 47 ++++++++++++++-- .../renderer/routes/_authenticated/layout.tsx | 55 ++----------------- .../CollectionsProvider.tsx | 11 ++-- .../OrganizationsProvider.tsx | 7 ++- 4 files changed, 55 insertions(+), 65 deletions(-) diff --git a/apps/desktop/src/renderer/providers/TRPCProvider/TRPCProvider.tsx b/apps/desktop/src/renderer/providers/TRPCProvider/TRPCProvider.tsx index 1d4473a93..a784c06e2 100644 --- a/apps/desktop/src/renderer/providers/TRPCProvider/TRPCProvider.tsx +++ b/apps/desktop/src/renderer/providers/TRPCProvider/TRPCProvider.tsx @@ -1,11 +1,46 @@ -import { QueryClientProvider } from "@tanstack/react-query"; -import { trpc } from "lib/trpc"; -import { queryClient } from "../../lib/query-client"; -import { reactClient } from "../../lib/trpc-client"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { httpBatchLink } from "@trpc/client"; +import type { ReactNode } from "react"; +import { useMemo, useState } from "react"; +import { env } from "renderer/env.renderer"; +import { getAuthToken } from "renderer/lib/auth-client"; +import { trpc } from "renderer/lib/trpc"; +import superjson from "superjson"; + +export function TRPCProvider({ children }: { children: ReactNode }) { + const [queryClient] = useState( + () => + new QueryClient({ + defaultOptions: { + queries: { + networkMode: "always", + retry: false, + }, + mutations: { + networkMode: "always", + retry: false, + }, + }, + }), + ); + + const apiClient = useMemo(() => { + return trpc.createClient({ + links: [ + httpBatchLink({ + url: `${env.NEXT_PUBLIC_API_URL}/api/trpc`, + headers() { + const token = getAuthToken(); + return token ? { Authorization: `Bearer ${token}` } : {}; + }, + transformer: superjson, + }), + ], + }); + }, []); -export function TRPCProvider({ children }: { children: React.ReactNode }) { return ( - + {children} ); diff --git a/apps/desktop/src/renderer/routes/_authenticated/layout.tsx b/apps/desktop/src/renderer/routes/_authenticated/layout.tsx index dd01b09d6..d56b35a95 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/layout.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/layout.tsx @@ -1,19 +1,7 @@ -import { - createFileRoute, - Navigate, - Outlet, - useNavigate, -} from "@tanstack/react-router"; +import { createFileRoute, Navigate, Outlet } from "@tanstack/react-router"; import { DndProvider } from "react-dnd"; -import { NewWorkspaceModal } from "renderer/components/NewWorkspaceModal"; -import { useUpdateListener } from "renderer/components/UpdateToast"; +import { authClient } from "renderer/lib/auth-client"; import { dragDropManager } from "renderer/lib/dnd"; -import { trpc } from "renderer/lib/trpc"; -import { useAuth } from "renderer/providers/AuthProvider"; -import { WorkspaceInitEffects } from "renderer/screens/main/components/WorkspaceInitEffects"; -import { useHotkeysSync } from "renderer/stores/hotkeys"; -import { useAgentHookListener } from "renderer/stores/tabs/useAgentHookListener"; -import { useWorkspaceInitStore } from "renderer/stores/workspace-init"; import { CollectionsProvider } from "./providers/CollectionsProvider"; import { OrganizationsProvider } from "./providers/OrganizationsProvider"; @@ -22,41 +10,8 @@ export const Route = createFileRoute("/_authenticated")({ }); function AuthenticatedLayout() { - const { session, token } = useAuth(); - const isSignedIn = !!token && !!session?.user; - const navigate = useNavigate(); - const utils = trpc.useUtils(); - - // Global hooks and subscriptions - useAgentHookListener(); - useUpdateListener(); - useHotkeysSync(); - - // Workspace initialization progress subscription - const updateInitProgress = useWorkspaceInitStore((s) => s.updateProgress); - trpc.workspaces.onInitProgress.useSubscription(undefined, { - onData: (progress) => { - updateInitProgress(progress); - if (progress.step === "ready" || progress.step === "failed") { - // Invalidate both the grouped list AND the specific workspace - utils.workspaces.getAllGrouped.invalidate(); - utils.workspaces.get.invalidate({ id: progress.workspaceId }); - } - }, - onError: (error) => { - console.error("[workspace-init-subscription] Subscription error:", error); - }, - }); - - // Menu navigation subscription - trpc.menu.subscribe.useSubscription(undefined, { - onData: (event) => { - if (event.type === "open-settings") { - const section = event.data.section || "account"; - navigate({ to: `/settings/${section}` as "/settings/account" }); - } - }, - }); + const { data: session } = authClient.useSession(); + const isSignedIn = !!session?.user; if (!isSignedIn) { return ; @@ -67,8 +22,6 @@ function AuthenticatedLayout() { - - diff --git a/apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/CollectionsProvider.tsx b/apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/CollectionsProvider.tsx index 837c94385..f65a9a56a 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/CollectionsProvider.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/CollectionsProvider.tsx @@ -1,5 +1,6 @@ import { createContext, type ReactNode, useContext, useMemo } from "react"; -import { trpc } from "renderer/lib/trpc"; +import { authClient } from "renderer/lib/auth-client"; +import { useAuthToken } from "renderer/providers/AuthProvider"; import { getCollections } from "./collections"; type Collections = ReturnType; @@ -7,17 +8,15 @@ type Collections = ReturnType; const CollectionsContext = createContext(null); export function CollectionsProvider({ children }: { children: ReactNode }) { - const { data: authState } = trpc.auth.onAuthState.useSubscription(); - - const activeOrganizationId = authState?.session?.activeOrganizationId; - const token = authState?.token; + const { data: session } = authClient.useSession(); + const token = useAuthToken(); + const activeOrganizationId = session?.session?.activeOrganizationId; const collections = useMemo(() => { if (!token || !activeOrganizationId) { return null; } - // Get cached collections for this org (or create if first time) return getCollections(activeOrganizationId, token); }, [token, activeOrganizationId]); diff --git a/apps/desktop/src/renderer/routes/_authenticated/providers/OrganizationsProvider/OrganizationsProvider.tsx b/apps/desktop/src/renderer/routes/_authenticated/providers/OrganizationsProvider/OrganizationsProvider.tsx index c3956b004..0fa5d20b4 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/providers/OrganizationsProvider/OrganizationsProvider.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/providers/OrganizationsProvider/OrganizationsProvider.tsx @@ -1,7 +1,10 @@ +import type { AppRouter } from "@superset/trpc"; +import type { inferRouterOutputs } from "@trpc/server"; import { createContext, type ReactNode, useContext } from "react"; -import { type RouterOutputs, trpc } from "renderer/lib/trpc"; +import { trpc } from "renderer/lib/trpc"; -export type Organization = RouterOutputs["user"]["myOrganizations"][number]; +type ApiRouterOutputs = inferRouterOutputs; +export type Organization = ApiRouterOutputs["user"]["myOrganizations"][number]; interface OrganizationsContextValue { organizations: Organization[]; From fc39b065546c144a697cb02c5f0e3661cb86f338 Mon Sep 17 00:00:00 2001 From: Satya Patel Date: Tue, 13 Jan 2026 17:32:00 -0800 Subject: [PATCH 03/12] feat(desktop): update all components to use electronTrpc and authClient --- .../ConfigFilePreview/ConfigFilePreview.tsx | 4 +- .../NewWorkspaceModal/NewWorkspaceModal.tsx | 22 ++- .../ExistingWorktreesList.tsx | 4 +- .../components/OpenInButton/OpenInButton.tsx | 10 +- .../PostHogUserIdentifier.tsx | 3 +- .../SetupConfigModal/SetupConfigModal.tsx | 13 +- .../UpdateRequiredPage/UpdateRequiredPage.tsx | 10 +- .../components/UpdateToast/UpdateToast.tsx | 8 +- .../UpdateToast/useUpdateListener.tsx | 4 +- apps/desktop/src/renderer/lib/trpc-storage.ts | 18 +-- .../src/renderer/react-query/presets/index.ts | 33 ++-- .../react-query/projects/useOpenNew.ts | 8 +- .../react-query/projects/useUpdateProject.ts | 8 +- .../renderer/react-query/workspaces/index.ts | 1 + .../workspaces/useCloseWorkspace.ts | 121 ++++++++++----- .../workspaces/useCreateBranchWorkspace.ts | 15 +- .../workspaces/useCreateWorkspace.ts | 28 ++-- .../workspaces/useDeleteWorkspace.ts | 141 +++++++++++------- .../workspaces/useDeleteWorktree.ts | 10 +- .../react-query/workspaces/useOpenWorktree.ts | 21 ++- .../workspaces/useReorderWorkspaces.ts | 8 +- .../workspaces/useSetActiveWorkspace.ts | 62 ++++++++ .../workspaces/useUpdateWorkspace.ts | 8 +- .../_authenticated/settings/account/page.tsx | 3 +- .../_authenticated/settings/behavior/page.tsx | 12 +- .../ProjectsSettings/ProjectsSettings.tsx | 5 +- .../_authenticated/settings/keyboard/page.tsx | 6 +- .../routes/_authenticated/settings/layout.tsx | 4 +- .../settings/project/$projectId/page.tsx | 75 ++++------ .../settings/ringtones/page.tsx | 10 +- .../MemberActions/MemberActions.tsx | 2 +- .../_authenticated/settings/team/page.tsx | 4 +- .../settings/workspace/$workspaceId/page.tsx | 53 +++---- .../src/renderer/routes/sign-in/page.tsx | 10 +- .../OrganizationDropdown.tsx | 18 ++- apps/desktop/src/renderer/stores/app-state.ts | 54 +++++++ .../src/renderer/stores/hotkeys/store.ts | 8 +- apps/desktop/src/renderer/stores/index.ts | 1 + .../stores/tabs/useAgentHookListener.ts | 83 ++++++----- .../stores/tabs/utils/terminal-cleanup.ts | 4 +- 40 files changed, 549 insertions(+), 363 deletions(-) create mode 100644 apps/desktop/src/renderer/react-query/workspaces/useSetActiveWorkspace.ts create mode 100644 apps/desktop/src/renderer/stores/app-state.ts diff --git a/apps/desktop/src/renderer/components/ConfigFilePreview/ConfigFilePreview.tsx b/apps/desktop/src/renderer/components/ConfigFilePreview/ConfigFilePreview.tsx index 83c29d834..e70e44d40 100644 --- a/apps/desktop/src/renderer/components/ConfigFilePreview/ConfigFilePreview.tsx +++ b/apps/desktop/src/renderer/components/ConfigFilePreview/ConfigFilePreview.tsx @@ -3,7 +3,7 @@ import { Button } from "@superset/ui/button"; import { cn } from "@superset/ui/utils"; import { HiArrowTopRightOnSquare } from "react-icons/hi2"; import { OpenInButton } from "renderer/components/OpenInButton"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { CONFIG_FILE_NAME, CONFIG_TEMPLATE, @@ -23,7 +23,7 @@ export function ConfigFilePreview({ configFilePath, className, }: ConfigFilePreviewProps) { - const { data: configData } = trpc.config.getConfigContent.useQuery( + const { data: configData } = electronTrpc.config.getConfigContent.useQuery( { projectId }, { enabled: !!projectId }, ); diff --git a/apps/desktop/src/renderer/components/NewWorkspaceModal/NewWorkspaceModal.tsx b/apps/desktop/src/renderer/components/NewWorkspaceModal/NewWorkspaceModal.tsx index 7a1c97337..ec17f725c 100644 --- a/apps/desktop/src/renderer/components/NewWorkspaceModal/NewWorkspaceModal.tsx +++ b/apps/desktop/src/renderer/components/NewWorkspaceModal/NewWorkspaceModal.tsx @@ -31,8 +31,8 @@ import debounce from "lodash/debounce"; import { useEffect, useMemo, useRef, useState } from "react"; import { GoGitBranch } from "react-icons/go"; import { HiCheck, HiChevronDown, HiChevronUpDown } from "react-icons/hi2"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { formatRelativeTime } from "renderer/lib/formatRelativeTime"; -import { trpc } from "renderer/lib/trpc"; import { useCreateWorkspace } from "renderer/react-query/workspaces"; import { useCloseNewWorkspaceModal, @@ -94,17 +94,22 @@ export function NewWorkspaceModal() { debouncedSetTitle(value); // Debounced update for derived state }; - const { data: recentProjects = [] } = trpc.projects.getRecents.useQuery(); + const { data: activeWorkspace } = + electronTrpc.workspaces.getActive.useQuery(); + const { data: recentProjects = [] } = + electronTrpc.projects.getRecents.useQuery(); const { data: branchData, isLoading: isBranchesLoading, isError: isBranchesError, - } = trpc.projects.getBranches.useQuery( + } = electronTrpc.projects.getBranches.useQuery( { projectId: selectedProjectId ?? "" }, { enabled: !!selectedProjectId }, ); const createWorkspace = useCreateWorkspace(); + const currentProjectId = activeWorkspace?.projectId; + // Filter branches based on search const filteredBranches = useMemo(() => { if (!branchData?.branches) return []; @@ -115,12 +120,15 @@ export function NewWorkspaceModal() { ); }, [branchData?.branches, branchSearch]); - // Auto-select project when modal opens (use pre-selected from NewWorkspaceButton) + // Auto-select project when modal opens (prioritize pre-selected, then current) useEffect(() => { - if (isOpen && !selectedProjectId && preSelectedProjectId) { - setSelectedProjectId(preSelectedProjectId); + if (isOpen && !selectedProjectId) { + const projectToSelect = preSelectedProjectId ?? currentProjectId; + if (projectToSelect) { + setSelectedProjectId(projectToSelect); + } } - }, [isOpen, selectedProjectId, preSelectedProjectId]); + }, [isOpen, currentProjectId, selectedProjectId, preSelectedProjectId]); // Effective base branch - use explicit selection or fall back to default const effectiveBaseBranch = baseBranch ?? branchData?.defaultBranch ?? null; diff --git a/apps/desktop/src/renderer/components/NewWorkspaceModal/components/ExistingWorktreesList/ExistingWorktreesList.tsx b/apps/desktop/src/renderer/components/NewWorkspaceModal/components/ExistingWorktreesList/ExistingWorktreesList.tsx index cb9280161..5f85b5084 100644 --- a/apps/desktop/src/renderer/components/NewWorkspaceModal/components/ExistingWorktreesList/ExistingWorktreesList.tsx +++ b/apps/desktop/src/renderer/components/NewWorkspaceModal/components/ExistingWorktreesList/ExistingWorktreesList.tsx @@ -2,7 +2,7 @@ import { Button } from "@superset/ui/button"; import { toast } from "@superset/ui/sonner"; import { formatDistanceToNow } from "date-fns"; import { LuGitBranch } from "react-icons/lu"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useOpenWorktree } from "renderer/react-query/workspaces"; interface ExistingWorktreesListProps { @@ -15,7 +15,7 @@ export function ExistingWorktreesList({ onOpenSuccess, }: ExistingWorktreesListProps) { const { data: worktrees = [], isLoading } = - trpc.workspaces.getWorktreesByProject.useQuery({ projectId }); + electronTrpc.workspaces.getWorktreesByProject.useQuery({ projectId }); const openWorktree = useOpenWorktree(); const closedWorktrees = worktrees diff --git a/apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx b/apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx index 7804bc176..b635671b2 100644 --- a/apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx +++ b/apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx @@ -37,7 +37,7 @@ import vscodeInsidersIcon from "renderer/assets/app-icons/vscode-insiders.svg"; import warpIcon from "renderer/assets/app-icons/warp.png"; import webstormIcon from "renderer/assets/app-icons/webstorm.svg"; import xcodeIcon from "renderer/assets/app-icons/xcode.svg"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useHotkeyText } from "renderer/stores/hotkeys"; interface AppOption { @@ -110,7 +110,7 @@ export function OpenInButton({ showShortcuts = false, }: OpenInButtonProps) { const [isOpen, setIsOpen] = useState(false); - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); const openInShortcut = useHotkeyText("OPEN_IN_APP"); const copyPathShortcut = useHotkeyText("COPY_PATH"); const showOpenInShortcut = showShortcuts && openInShortcut !== "Unassigned"; @@ -118,12 +118,12 @@ export function OpenInButton({ showShortcuts && copyPathShortcut !== "Unassigned"; const { data: lastUsedApp = "cursor" } = - trpc.settings.getLastUsedApp.useQuery(); + electronTrpc.settings.getLastUsedApp.useQuery(); - const openInApp = trpc.external.openInApp.useMutation({ + const openInApp = electronTrpc.external.openInApp.useMutation({ onSuccess: () => utils.settings.getLastUsedApp.invalidate(), }); - const copyPath = trpc.external.copyPath.useMutation(); + const copyPath = electronTrpc.external.copyPath.useMutation(); const currentApp = getAppOption(lastUsedApp); diff --git a/apps/desktop/src/renderer/components/PostHogUserIdentifier/PostHogUserIdentifier.tsx b/apps/desktop/src/renderer/components/PostHogUserIdentifier/PostHogUserIdentifier.tsx index 04deabb0a..8178e22c4 100644 --- a/apps/desktop/src/renderer/components/PostHogUserIdentifier/PostHogUserIdentifier.tsx +++ b/apps/desktop/src/renderer/components/PostHogUserIdentifier/PostHogUserIdentifier.tsx @@ -1,4 +1,5 @@ import { useEffect } from "react"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { trpc } from "renderer/lib/trpc"; import { posthog } from "../../lib/posthog"; @@ -7,7 +8,7 @@ const AUTH_COMPLETED_KEY = "superset_auth_completed"; export function PostHogUserIdentifier() { const { data: user, isSuccess } = trpc.user.me.useQuery(); - const { mutate: setUserId } = trpc.analytics.setUserId.useMutation(); + const { mutate: setUserId } = electronTrpc.analytics.setUserId.useMutation(); useEffect(() => { if (user) { diff --git a/apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx b/apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx index f2b0e1cb7..177e09167 100644 --- a/apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx +++ b/apps/desktop/src/renderer/components/SetupConfigModal/SetupConfigModal.tsx @@ -9,7 +9,7 @@ import { } from "@superset/ui/dialog"; import { HiArrowTopRightOnSquare } from "react-icons/hi2"; import { OpenInButton } from "renderer/components/OpenInButton"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useCloseConfigModal, useConfigModalOpen, @@ -26,15 +26,16 @@ export function SetupConfigModal() { const projectId = useConfigModalProjectId(); const closeModal = useCloseConfigModal(); - const { data: project } = trpc.projects.get.useQuery( + const { data: project } = electronTrpc.projects.get.useQuery( { id: projectId ?? "" }, { enabled: !!projectId }, ); - const { data: configFilePath } = trpc.config.getConfigFilePath.useQuery( - { projectId: projectId ?? "" }, - { enabled: !!projectId }, - ); + const { data: configFilePath } = + electronTrpc.config.getConfigFilePath.useQuery( + { projectId: projectId ?? "" }, + { enabled: !!projectId }, + ); const projectName = project?.name ?? "your-project"; diff --git a/apps/desktop/src/renderer/components/UpdateRequiredPage/UpdateRequiredPage.tsx b/apps/desktop/src/renderer/components/UpdateRequiredPage/UpdateRequiredPage.tsx index a284e54fa..637ab3e52 100644 --- a/apps/desktop/src/renderer/components/UpdateRequiredPage/UpdateRequiredPage.tsx +++ b/apps/desktop/src/renderer/components/UpdateRequiredPage/UpdateRequiredPage.tsx @@ -1,7 +1,7 @@ import { Button } from "@superset/ui/button"; import { useState } from "react"; import { HiArrowPath, HiExclamationTriangle } from "react-icons/hi2"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { AppFrame } from "renderer/screens/main/components/AppFrame"; import { Background } from "renderer/screens/main/components/Background"; import { @@ -21,9 +21,9 @@ export function UpdateRequiredPage({ minimumVersion, message, }: UpdateRequiredPageProps) { - const openUrl = trpc.external.openUrl.useMutation(); - const checkMutation = trpc.autoUpdate.check.useMutation(); - const installMutation = trpc.autoUpdate.install.useMutation(); + const openUrl = electronTrpc.external.openUrl.useMutation(); + const checkMutation = electronTrpc.autoUpdate.check.useMutation(); + const installMutation = electronTrpc.autoUpdate.install.useMutation(); // Track update status via subscription for real-time updates const [updateStatus, setUpdateStatus] = useState<{ @@ -32,7 +32,7 @@ export function UpdateRequiredPage({ }>({ status: AUTO_UPDATE_STATUS.IDLE }); // Subscribe to auto-update status changes - trpc.autoUpdate.subscribe.useSubscription(undefined, { + electronTrpc.autoUpdate.subscribe.useSubscription(undefined, { onData: (event) => { setUpdateStatus({ status: event.status, error: event.error }); }, diff --git a/apps/desktop/src/renderer/components/UpdateToast/UpdateToast.tsx b/apps/desktop/src/renderer/components/UpdateToast/UpdateToast.tsx index 0d6f8946b..3bc173bec 100644 --- a/apps/desktop/src/renderer/components/UpdateToast/UpdateToast.tsx +++ b/apps/desktop/src/renderer/components/UpdateToast/UpdateToast.tsx @@ -1,7 +1,7 @@ import { Button } from "@superset/ui/button"; import { toast } from "@superset/ui/sonner"; import { HiMiniXMark } from "react-icons/hi2"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { AUTO_UPDATE_STATUS, RELEASES_URL } from "shared/auto-update"; interface UpdateToastProps { @@ -17,9 +17,9 @@ export function UpdateToast({ version, error, }: UpdateToastProps) { - const openUrl = trpc.external.openUrl.useMutation(); - const installMutation = trpc.autoUpdate.install.useMutation(); - const dismissMutation = trpc.autoUpdate.dismiss.useMutation({ + const openUrl = electronTrpc.external.openUrl.useMutation(); + const installMutation = electronTrpc.autoUpdate.install.useMutation(); + const dismissMutation = electronTrpc.autoUpdate.dismiss.useMutation({ onSuccess: () => { toast.dismiss(toastId); }, diff --git a/apps/desktop/src/renderer/components/UpdateToast/useUpdateListener.tsx b/apps/desktop/src/renderer/components/UpdateToast/useUpdateListener.tsx index 34c8584ce..a15131aa3 100644 --- a/apps/desktop/src/renderer/components/UpdateToast/useUpdateListener.tsx +++ b/apps/desktop/src/renderer/components/UpdateToast/useUpdateListener.tsx @@ -1,13 +1,13 @@ import { toast } from "@superset/ui/sonner"; import { useRef } from "react"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { AUTO_UPDATE_STATUS } from "shared/auto-update"; import { UpdateToast } from "./UpdateToast"; export function useUpdateListener() { const toastIdRef = useRef(null); - trpc.autoUpdate.subscribe.useSubscription(undefined, { + electronTrpc.autoUpdate.subscribe.useSubscription(undefined, { onData: (event) => { const { status, version, error } = event; diff --git a/apps/desktop/src/renderer/lib/trpc-storage.ts b/apps/desktop/src/renderer/lib/trpc-storage.ts index edefa71b0..1144ba44e 100644 --- a/apps/desktop/src/renderer/lib/trpc-storage.ts +++ b/apps/desktop/src/renderer/lib/trpc-storage.ts @@ -1,6 +1,6 @@ import type { HotkeysState } from "shared/hotkeys"; import { createJSONStorage, type StateStorage } from "zustand/middleware"; -import { trpcClient } from "./trpc-client"; +import { electronTrpcClient } from "./trpc-client"; /** * Flag to skip the next hotkeys persist operation. @@ -54,9 +54,9 @@ function createTrpcStorageAdapter(config: TrpcStorageConfig): StateStorage { */ export const trpcTabsStorage = createJSONStorage(() => createTrpcStorageAdapter({ - get: () => trpcClient.uiState.tabs.get.query(), + get: () => electronTrpcClient.uiState.tabs.get.query(), // biome-ignore lint/suspicious/noExplicitAny: Zustand persist passes unknown, tRPC expects typed input - set: (input) => trpcClient.uiState.tabs.set.mutate(input as any), + set: (input) => electronTrpcClient.uiState.tabs.set.mutate(input as any), }), ); @@ -65,9 +65,9 @@ export const trpcTabsStorage = createJSONStorage(() => */ export const trpcThemeStorage = createJSONStorage(() => createTrpcStorageAdapter({ - get: () => trpcClient.uiState.theme.get.query(), + get: () => electronTrpcClient.uiState.theme.get.query(), // biome-ignore lint/suspicious/noExplicitAny: Zustand persist passes unknown, tRPC expects typed input - set: (input) => trpcClient.uiState.theme.set.mutate(input as any), + set: (input) => electronTrpcClient.uiState.theme.set.mutate(input as any), }), ); @@ -77,7 +77,7 @@ export const trpcThemeStorage = createJSONStorage(() => export const trpcHotkeysStorage = createJSONStorage(() => createTrpcStorageAdapter({ get: async () => { - const hotkeysState = await trpcClient.uiState.hotkeys.get.query(); + const hotkeysState = await electronTrpcClient.uiState.hotkeys.get.query(); return { hotkeysState }; }, set: (input) => { @@ -87,7 +87,7 @@ export const trpcHotkeysStorage = createJSONStorage(() => return Promise.resolve(); } const state = input as { hotkeysState: HotkeysState }; - return trpcClient.uiState.hotkeys.set.mutate(state.hotkeysState); + return electronTrpcClient.uiState.hotkeys.set.mutate(state.hotkeysState); }, }), ); @@ -100,12 +100,12 @@ export const trpcRingtoneStorage = createJSONStorage(() => createTrpcStorageAdapter({ get: async () => { const ringtoneId = - await trpcClient.settings.getSelectedRingtoneId.query(); + await electronTrpcClient.settings.getSelectedRingtoneId.query(); return { selectedRingtoneId: ringtoneId }; }, set: async (input) => { const state = input as { selectedRingtoneId: string }; - await trpcClient.settings.setSelectedRingtoneId.mutate({ + await electronTrpcClient.settings.setSelectedRingtoneId.mutate({ ringtoneId: state.selectedRingtoneId, }); }, diff --git a/apps/desktop/src/renderer/react-query/presets/index.ts b/apps/desktop/src/renderer/react-query/presets/index.ts index c800e1286..97ace8013 100644 --- a/apps/desktop/src/renderer/react-query/presets/index.ts +++ b/apps/desktop/src/renderer/react-query/presets/index.ts @@ -1,13 +1,13 @@ -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; function useCreateTerminalPreset( options?: Parameters< - typeof trpc.settings.createTerminalPreset.useMutation + typeof electronTrpc.settings.createTerminalPreset.useMutation >[0], ) { - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); - return trpc.settings.createTerminalPreset.useMutation({ + return electronTrpc.settings.createTerminalPreset.useMutation({ ...options, onSuccess: async (...args) => { await utils.settings.getTerminalPresets.invalidate(); @@ -18,12 +18,12 @@ function useCreateTerminalPreset( function useUpdateTerminalPreset( options?: Parameters< - typeof trpc.settings.updateTerminalPreset.useMutation + typeof electronTrpc.settings.updateTerminalPreset.useMutation >[0], ) { - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); - return trpc.settings.updateTerminalPreset.useMutation({ + return electronTrpc.settings.updateTerminalPreset.useMutation({ ...options, onSuccess: async (...args) => { await utils.settings.getTerminalPresets.invalidate(); @@ -34,12 +34,12 @@ function useUpdateTerminalPreset( function useDeleteTerminalPreset( options?: Parameters< - typeof trpc.settings.deleteTerminalPreset.useMutation + typeof electronTrpc.settings.deleteTerminalPreset.useMutation >[0], ) { - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); - return trpc.settings.deleteTerminalPreset.useMutation({ + return electronTrpc.settings.deleteTerminalPreset.useMutation({ ...options, onSuccess: async (...args) => { await utils.settings.getTerminalPresets.invalidate(); @@ -49,11 +49,13 @@ function useDeleteTerminalPreset( } function useSetDefaultPreset( - options?: Parameters[0], + options?: Parameters< + typeof electronTrpc.settings.setDefaultPreset.useMutation + >[0], ) { - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); - return trpc.settings.setDefaultPreset.useMutation({ + return electronTrpc.settings.setDefaultPreset.useMutation({ ...options, onSuccess: async (...args) => { await utils.settings.getTerminalPresets.invalidate(); @@ -69,9 +71,10 @@ function useSetDefaultPreset( */ export function usePresets() { const { data: presets = [], isLoading } = - trpc.settings.getTerminalPresets.useQuery(); + electronTrpc.settings.getTerminalPresets.useQuery(); - const { data: defaultPreset } = trpc.settings.getDefaultPreset.useQuery(); + const { data: defaultPreset } = + electronTrpc.settings.getDefaultPreset.useQuery(); const createPreset = useCreateTerminalPreset(); const updatePreset = useUpdateTerminalPreset(); diff --git a/apps/desktop/src/renderer/react-query/projects/useOpenNew.ts b/apps/desktop/src/renderer/react-query/projects/useOpenNew.ts index 3dc7e1b92..8e2d26839 100644 --- a/apps/desktop/src/renderer/react-query/projects/useOpenNew.ts +++ b/apps/desktop/src/renderer/react-query/projects/useOpenNew.ts @@ -1,15 +1,15 @@ -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; /** * Mutation hook for opening a new project * Creates a Project record if it doesn't exist */ export function useOpenNew( - options?: Parameters[0], + options?: Parameters[0], ) { - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); - return trpc.projects.openNew.useMutation({ + return electronTrpc.projects.openNew.useMutation({ ...options, onSuccess: async (...args) => { // Auto-invalidate projects query diff --git a/apps/desktop/src/renderer/react-query/projects/useUpdateProject.ts b/apps/desktop/src/renderer/react-query/projects/useUpdateProject.ts index 716ff1c0c..46ba3b019 100644 --- a/apps/desktop/src/renderer/react-query/projects/useUpdateProject.ts +++ b/apps/desktop/src/renderer/react-query/projects/useUpdateProject.ts @@ -1,15 +1,15 @@ -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; /** * Mutation hook for updating a project (name, color, etc.) * Automatically invalidates project + workspace queries on success */ export function useUpdateProject( - options?: Parameters[0], + options?: Parameters[0], ) { - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); - return trpc.projects.update.useMutation({ + return electronTrpc.projects.update.useMutation({ ...options, onSuccess: async (...args) => { await Promise.all([ diff --git a/apps/desktop/src/renderer/react-query/workspaces/index.ts b/apps/desktop/src/renderer/react-query/workspaces/index.ts index 48be214e3..b109fc6d1 100644 --- a/apps/desktop/src/renderer/react-query/workspaces/index.ts +++ b/apps/desktop/src/renderer/react-query/workspaces/index.ts @@ -5,5 +5,6 @@ export { useDeleteWorkspace } from "./useDeleteWorkspace"; export { useDeleteWorktree } from "./useDeleteWorktree"; export { useOpenWorktree } from "./useOpenWorktree"; export { useReorderWorkspaces } from "./useReorderWorkspaces"; +export { useSetActiveWorkspace } from "./useSetActiveWorkspace"; export { useUpdateWorkspace } from "./useUpdateWorkspace"; export { useWorkspaceDeleteHandler } from "./useWorkspaceDeleteHandler"; diff --git a/apps/desktop/src/renderer/react-query/workspaces/useCloseWorkspace.ts b/apps/desktop/src/renderer/react-query/workspaces/useCloseWorkspace.ts index 4a77524cb..ccb175c32 100644 --- a/apps/desktop/src/renderer/react-query/workspaces/useCloseWorkspace.ts +++ b/apps/desktop/src/renderer/react-query/workspaces/useCloseWorkspace.ts @@ -1,45 +1,47 @@ -import { useNavigate, useParams } from "@tanstack/react-router"; -import { trpc } from "renderer/lib/trpc"; -import { navigateToWorkspace } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; +import { electronTrpc } from "renderer/lib/electron-trpc"; type CloseContext = { previousGrouped: ReturnType< - typeof trpc.useUtils + typeof electronTrpc.useUtils >["workspaces"]["getAllGrouped"]["getData"] extends () => infer R ? R : never; previousAll: ReturnType< - typeof trpc.useUtils + typeof electronTrpc.useUtils >["workspaces"]["getAll"]["getData"] extends () => infer R ? R : never; + previousActive: ReturnType< + typeof electronTrpc.useUtils + >["workspaces"]["getActive"]["getData"] extends () => infer R + ? R + : never; }; /** * Mutation hook for closing a workspace without deleting the worktree * Uses optimistic updates to immediately remove workspace from UI, * then performs actual close in background. - * Automatically navigates away if the closed workspace is currently being viewed. */ export function useCloseWorkspace( - options?: Parameters[0], + options?: Parameters[0], ) { - const utils = trpc.useUtils(); - const navigate = useNavigate(); - const params = useParams({ strict: false }); + const utils = electronTrpc.useUtils(); - return trpc.workspaces.close.useMutation({ + return electronTrpc.workspaces.close.useMutation({ ...options, onMutate: async ({ id }) => { // Cancel outgoing refetches to avoid overwriting optimistic update await Promise.all([ utils.workspaces.getAll.cancel(), utils.workspaces.getAllGrouped.cancel(), + utils.workspaces.getActive.cancel(), ]); // Snapshot previous values for rollback const previousGrouped = utils.workspaces.getAllGrouped.getData(); const previousAll = utils.workspaces.getAll.getData(); + const previousActive = utils.workspaces.getActive.getData(); // Optimistically remove workspace from getAllGrouped cache if (previousGrouped) { @@ -62,8 +64,75 @@ export function useCloseWorkspace( ); } + // Switch to next workspace to prevent "no workspace" flash + if (previousActive?.id === id) { + const remainingWorkspaces = previousAll + ?.filter((w) => w.id !== id) + .sort((a, b) => b.lastOpenedAt - a.lastOpenedAt); + + if (remainingWorkspaces && remainingWorkspaces.length > 0) { + // Find a workspace with full data available in previousGrouped + let selectedWorkspace = null; + let projectGroup = null; + let workspaceFromGrouped = null; + + for (const candidate of remainingWorkspaces) { + const group = previousGrouped?.find((g) => + g.workspaces.some((w) => w.id === candidate.id), + ); + if (group) { + selectedWorkspace = candidate; + projectGroup = group; + workspaceFromGrouped = group.workspaces.find( + (w) => w.id === candidate.id, + ); + break; + } + } + + if (selectedWorkspace && projectGroup && workspaceFromGrouped) { + const worktreeData = + workspaceFromGrouped.type === "worktree" + ? { + branch: selectedWorkspace.branch, + baseBranch: null, + gitStatus: { + branch: selectedWorkspace.branch, + needsRebase: false, + lastRefreshed: Date.now(), + }, + } + : null; + + utils.workspaces.getActive.setData(undefined, { + ...selectedWorkspace, + type: workspaceFromGrouped.type, + worktreePath: workspaceFromGrouped.worktreePath, + project: { + id: projectGroup.project.id, + name: projectGroup.project.name, + mainRepoPath: projectGroup.project.mainRepoPath, + }, + worktree: worktreeData, + }); + } else { + // Fallback: set minimal data to prevent StartView flash (refetch will populate full data) + const fallback = remainingWorkspaces[0]; + utils.workspaces.getActive.setData(undefined, { + ...fallback, + type: fallback.type === "branch" ? "branch" : "worktree", + worktreePath: "", + project: null, + worktree: null, + }); + } + } else { + utils.workspaces.getActive.setData(undefined, null); + } + } + // Return context for rollback - return { previousGrouped, previousAll } as CloseContext; + return { previousGrouped, previousAll, previousActive } as CloseContext; }, onError: (_err, _variables, context) => { // Rollback to previous state on error @@ -76,36 +145,18 @@ export function useCloseWorkspace( if (context?.previousAll !== undefined) { utils.workspaces.getAll.setData(undefined, context.previousAll); } + if (context?.previousActive !== undefined) { + utils.workspaces.getActive.setData(undefined, context.previousActive); + } }, - onSuccess: async (data, variables, ...rest) => { + onSuccess: async (...args) => { // Invalidate to ensure consistency with backend state await utils.workspaces.invalidate(); // Invalidate project queries since close updates project metadata await utils.projects.getRecents.invalidate(); - // If the closed workspace is currently being viewed, navigate away - if (params.workspaceId === variables.id) { - // Try to navigate to previous workspace first, then next - const prevWorkspaceId = - await utils.workspaces.getPreviousWorkspace.fetch({ - id: variables.id, - }); - const nextWorkspaceId = await utils.workspaces.getNextWorkspace.fetch({ - id: variables.id, - }); - - const targetWorkspaceId = prevWorkspaceId ?? nextWorkspaceId; - - if (targetWorkspaceId) { - navigateToWorkspace(targetWorkspaceId, navigate); - } else { - // No other workspaces, navigate to workspace index (shows StartView) - navigate({ to: "/workspace" }); - } - } - // Call user's onSuccess if provided - await options?.onSuccess?.(data, variables, ...rest); + await options?.onSuccess?.(...args); }, }); } diff --git a/apps/desktop/src/renderer/react-query/workspaces/useCreateBranchWorkspace.ts b/apps/desktop/src/renderer/react-query/workspaces/useCreateBranchWorkspace.ts index bf2701701..834a02f50 100644 --- a/apps/desktop/src/renderer/react-query/workspaces/useCreateBranchWorkspace.ts +++ b/apps/desktop/src/renderer/react-query/workspaces/useCreateBranchWorkspace.ts @@ -1,6 +1,4 @@ -import { useNavigate } from "@tanstack/react-router"; -import { trpc } from "renderer/lib/trpc"; -import { navigateToWorkspace } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useTabsStore } from "renderer/stores/tabs/store"; /** @@ -10,13 +8,12 @@ import { useTabsStore } from "renderer/stores/tabs/store"; */ export function useCreateBranchWorkspace( options?: Parameters< - typeof trpc.workspaces.createBranchWorkspace.useMutation + typeof electronTrpc.workspaces.createBranchWorkspace.useMutation >[0], ) { - const navigate = useNavigate(); - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); - return trpc.workspaces.createBranchWorkspace.useMutation({ + return electronTrpc.workspaces.createBranchWorkspace.useMutation({ ...options, onSuccess: async (data, ...rest) => { // Auto-invalidate all workspace queries @@ -28,10 +25,6 @@ export function useCreateBranchWorkspace( useTabsStore.getState().addTab(data.workspace.id); } - // Navigate to the workspace - // Branch workspaces don't need async initialization, so always navigate - navigateToWorkspace(data.workspace.id, navigate); - // Call user's onSuccess if provided await options?.onSuccess?.(data, ...rest); }, diff --git a/apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts b/apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts index 556e04a62..53af0a07c 100644 --- a/apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts +++ b/apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts @@ -1,6 +1,4 @@ -import { useNavigate } from "@tanstack/react-router"; -import { trpc } from "renderer/lib/trpc"; -import { navigateToWorkspace } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useWorkspaceInitStore } from "renderer/stores/workspace-init"; import type { WorkspaceInitProgress } from "shared/types/workspace-init"; @@ -19,21 +17,20 @@ import type { WorkspaceInitProgress } from "shared/types/workspace-init"; * to survive dialog unmounts. This hook just adds to the global pending store. */ export function useCreateWorkspace( - options?: Parameters[0], + options?: Parameters[0], ) { - const navigate = useNavigate(); - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); const addPendingTerminalSetup = useWorkspaceInitStore( (s) => s.addPendingTerminalSetup, ); const updateProgress = useWorkspaceInitStore((s) => s.updateProgress); - return trpc.workspaces.create.useMutation({ + return electronTrpc.workspaces.create.useMutation({ ...options, onSuccess: async (data, ...rest) => { - // CRITICAL: Set optimistic progress BEFORE invalidation AND navigation - // to ensure isInitializing is true when workspace page first renders, - // preventing the "Setup incomplete" flash. + // Optimistically set init progress BEFORE query invalidation to prevent + // the "interrupted" state flash. The subscription will update with real + // progress, but this ensures isInitializing is true immediately. if (data.isInitializing) { const optimisticProgress: WorkspaceInitProgress = { workspaceId: data.workspace.id, @@ -44,6 +41,9 @@ export function useCreateWorkspace( updateProgress(optimisticProgress); } + // Auto-invalidate all workspace queries + await utils.workspaces.invalidate(); + // Add to global pending store (WorkspaceInitEffects will handle terminal creation) // This survives dialog unmounts since it's stored in Zustand, not a hook-local ref addPendingTerminalSetup({ @@ -52,18 +52,10 @@ export function useCreateWorkspace( initialCommands: data.initialCommands, }); - // Auto-invalidate all workspace queries - await utils.workspaces.invalidate(); - // Handle race condition: if init already completed before we added to pending, // WorkspaceInitEffects will process it on next render when it sees the progress // is already "ready" and there's a matching pending setup. - // Navigate to the new workspace immediately - // The workspace exists in DB, so it's safe to navigate - // Git operations happen in background with progress shown via toast - navigateToWorkspace(data.workspace.id, navigate); - // Call user's onSuccess if provided await options?.onSuccess?.(data, ...rest); }, diff --git a/apps/desktop/src/renderer/react-query/workspaces/useDeleteWorkspace.ts b/apps/desktop/src/renderer/react-query/workspaces/useDeleteWorkspace.ts index f0fdaa215..c9a396508 100644 --- a/apps/desktop/src/renderer/react-query/workspaces/useDeleteWorkspace.ts +++ b/apps/desktop/src/renderer/react-query/workspaces/useDeleteWorkspace.ts @@ -1,70 +1,45 @@ -import { useNavigate, useParams } from "@tanstack/react-router"; -import { trpc } from "renderer/lib/trpc"; -import { navigateToWorkspace } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; +import { electronTrpc } from "renderer/lib/electron-trpc"; type DeleteContext = { previousGrouped: ReturnType< - typeof trpc.useUtils + typeof electronTrpc.useUtils >["workspaces"]["getAllGrouped"]["getData"] extends () => infer R ? R : never; previousAll: ReturnType< - typeof trpc.useUtils + typeof electronTrpc.useUtils >["workspaces"]["getAll"]["getData"] extends () => infer R ? R : never; - wasViewingDeleted: boolean; - navigatedTo: string | null; + previousActive: ReturnType< + typeof electronTrpc.useUtils + >["workspaces"]["getActive"]["getData"] extends () => infer R + ? R + : never; }; /** * Mutation hook for deleting a workspace with optimistic updates. * Server marks `deletingAt` immediately so refetches stay correct during slow git operations. - * Optimistically navigates away immediately if the deleted workspace is currently being viewed. - * Navigates back on error to restore the user to the original workspace. */ export function useDeleteWorkspace( - options?: Parameters[0], + options?: Parameters[0], ) { - const utils = trpc.useUtils(); - const navigate = useNavigate(); - const params = useParams({ strict: false }); + const utils = electronTrpc.useUtils(); - return trpc.workspaces.delete.useMutation({ + return electronTrpc.workspaces.delete.useMutation({ ...options, onMutate: async ({ id }) => { - // Check if we're viewing the workspace being deleted - const wasViewingDeleted = params.workspaceId === id; - let navigatedTo: string | null = null; - - // If viewing deleted workspace, get navigation target BEFORE optimistic update - if (wasViewingDeleted) { - const prevWorkspaceId = - await utils.workspaces.getPreviousWorkspace.fetch({ id }); - const nextWorkspaceId = await utils.workspaces.getNextWorkspace.fetch({ - id, - }); - const targetWorkspaceId = prevWorkspaceId ?? nextWorkspaceId; - - if (targetWorkspaceId) { - navigatedTo = targetWorkspaceId; - navigateToWorkspace(targetWorkspaceId, navigate); - } else { - navigatedTo = "/workspace"; - navigate({ to: "/workspace" }); - } - } - - // Cancel outgoing queries and get snapshots await Promise.all([ utils.workspaces.getAll.cancel(), utils.workspaces.getAllGrouped.cancel(), + utils.workspaces.getActive.cancel(), ]); const previousGrouped = utils.workspaces.getAllGrouped.getData(); const previousAll = utils.workspaces.getAll.getData(); + const previousActive = utils.workspaces.getActive.getData(); - // Optimistic update: remove workspace from cache if (previousGrouped) { utils.workspaces.getAllGrouped.setData( undefined, @@ -84,23 +59,83 @@ export function useDeleteWorkspace( ); } - return { - previousGrouped, - previousAll, - wasViewingDeleted, - navigatedTo, - } as DeleteContext; + // Switch to next workspace to prevent "no workspace" flash + if (previousActive?.id === id) { + const remainingWorkspaces = previousAll + ?.filter((w) => w.id !== id) + .sort((a, b) => b.lastOpenedAt - a.lastOpenedAt); + + if (remainingWorkspaces && remainingWorkspaces.length > 0) { + // Find a workspace with full data available in previousGrouped + let selectedWorkspace = null; + let projectGroup = null; + let workspaceFromGrouped = null; + + for (const candidate of remainingWorkspaces) { + const group = previousGrouped?.find((g) => + g.workspaces.some((w) => w.id === candidate.id), + ); + if (group) { + selectedWorkspace = candidate; + projectGroup = group; + workspaceFromGrouped = group.workspaces.find( + (w) => w.id === candidate.id, + ); + break; + } + } + + if (selectedWorkspace && projectGroup && workspaceFromGrouped) { + const worktreeData = + workspaceFromGrouped.type === "worktree" + ? { + branch: selectedWorkspace.branch, + baseBranch: null, + gitStatus: { + branch: selectedWorkspace.branch, + needsRebase: false, + lastRefreshed: Date.now(), + }, + } + : null; + + utils.workspaces.getActive.setData(undefined, { + ...selectedWorkspace, + type: workspaceFromGrouped.type, + worktreePath: workspaceFromGrouped.worktreePath, + project: { + id: projectGroup.project.id, + name: projectGroup.project.name, + mainRepoPath: projectGroup.project.mainRepoPath, + }, + worktree: worktreeData, + }); + } else { + // Fallback: set minimal data to prevent StartView flash (refetch will populate full data) + const fallback = remainingWorkspaces[0]; + utils.workspaces.getActive.setData(undefined, { + ...fallback, + type: fallback.type === "branch" ? "branch" : "worktree", + worktreePath: "", + project: null, + worktree: null, + }); + } + } else { + utils.workspaces.getActive.setData(undefined, null); + } + } + + return { previousGrouped, previousAll, previousActive } as DeleteContext; }, onSettled: async (...args) => { await utils.workspaces.invalidate(); await options?.onSettled?.(...args); }, - onSuccess: async (data, variables, ...rest) => { - // Navigation already handled in onMutate (optimistic) - await options?.onSuccess?.(data, variables, ...rest); + onSuccess: async (...args) => { + await options?.onSuccess?.(...args); }, - onError: async (_err, variables, context, ...rest) => { - // Rollback optimistic cache updates + onError: async (_err, _variables, context, ...rest) => { if (context?.previousGrouped !== undefined) { utils.workspaces.getAllGrouped.setData( undefined, @@ -110,13 +145,11 @@ export function useDeleteWorkspace( if (context?.previousAll !== undefined) { utils.workspaces.getAll.setData(undefined, context.previousAll); } - - // If we optimistically navigated away, navigate back to the deleted workspace - if (context?.wasViewingDeleted) { - navigateToWorkspace(variables.id, navigate); + if (context?.previousActive !== undefined) { + utils.workspaces.getActive.setData(undefined, context.previousActive); } - await options?.onError?.(_err, variables, context, ...rest); + await options?.onError?.(_err, _variables, context, ...rest); }, }); } diff --git a/apps/desktop/src/renderer/react-query/workspaces/useDeleteWorktree.ts b/apps/desktop/src/renderer/react-query/workspaces/useDeleteWorktree.ts index fd48f5ec3..a517073fd 100644 --- a/apps/desktop/src/renderer/react-query/workspaces/useDeleteWorktree.ts +++ b/apps/desktop/src/renderer/react-query/workspaces/useDeleteWorktree.ts @@ -1,15 +1,17 @@ -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; /** * Mutation hook for deleting a closed worktree (one without an active workspace). * Handles cache invalidation for worktree-related queries. */ export function useDeleteWorktree( - options?: Parameters[0], + options?: Parameters< + typeof electronTrpc.workspaces.deleteWorktree.useMutation + >[0], ) { - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); - return trpc.workspaces.deleteWorktree.useMutation({ + return electronTrpc.workspaces.deleteWorktree.useMutation({ ...options, onSettled: async (...args) => { // Invalidate worktree queries to refresh the list diff --git a/apps/desktop/src/renderer/react-query/workspaces/useOpenWorktree.ts b/apps/desktop/src/renderer/react-query/workspaces/useOpenWorktree.ts index a6b33fd73..1d22d0f07 100644 --- a/apps/desktop/src/renderer/react-query/workspaces/useOpenWorktree.ts +++ b/apps/desktop/src/renderer/react-query/workspaces/useOpenWorktree.ts @@ -1,7 +1,5 @@ import { toast } from "@superset/ui/sonner"; -import { useNavigate } from "@tanstack/react-router"; -import { trpc } from "renderer/lib/trpc"; -import { navigateToWorkspace } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useOpenConfigModal } from "renderer/stores/config-modal"; import { useTabsStore } from "renderer/stores/tabs/store"; @@ -12,17 +10,19 @@ import { useTabsStore } from "renderer/stores/tabs/store"; * Shows config toast if no setup commands are configured */ export function useOpenWorktree( - options?: Parameters[0], + options?: Parameters< + typeof electronTrpc.workspaces.openWorktree.useMutation + >[0], ) { - const navigate = useNavigate(); - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); const addTab = useTabsStore((state) => state.addTab); const setTabAutoTitle = useTabsStore((state) => state.setTabAutoTitle); - const createOrAttach = trpc.terminal.createOrAttach.useMutation(); + const createOrAttach = electronTrpc.terminal.createOrAttach.useMutation(); const openConfigModal = useOpenConfigModal(); - const dismissConfigToast = trpc.config.dismissConfigToast.useMutation(); + const dismissConfigToast = + electronTrpc.config.dismissConfigToast.useMutation(); - return trpc.workspaces.openWorktree.useMutation({ + return electronTrpc.workspaces.openWorktree.useMutation({ ...options, onSuccess: async (data, ...rest) => { // Auto-invalidate all workspace queries @@ -63,9 +63,6 @@ export function useOpenWorktree( }); } - // Navigate to the opened workspace - navigateToWorkspace(data.workspace.id, navigate); - // Call user's onSuccess if provided await options?.onSuccess?.(data, ...rest); }, diff --git a/apps/desktop/src/renderer/react-query/workspaces/useReorderWorkspaces.ts b/apps/desktop/src/renderer/react-query/workspaces/useReorderWorkspaces.ts index 35bbe675e..9666ffbd2 100644 --- a/apps/desktop/src/renderer/react-query/workspaces/useReorderWorkspaces.ts +++ b/apps/desktop/src/renderer/react-query/workspaces/useReorderWorkspaces.ts @@ -1,15 +1,15 @@ -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; /** * Mutation hook for reordering workspaces * Automatically invalidates workspace queries on success */ export function useReorderWorkspaces( - options?: Parameters[0], + options?: Parameters[0], ) { - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); - return trpc.workspaces.reorder.useMutation({ + return electronTrpc.workspaces.reorder.useMutation({ ...options, onSuccess: async (...args) => { await utils.workspaces.getAll.invalidate(); diff --git a/apps/desktop/src/renderer/react-query/workspaces/useSetActiveWorkspace.ts b/apps/desktop/src/renderer/react-query/workspaces/useSetActiveWorkspace.ts new file mode 100644 index 000000000..02b8cd758 --- /dev/null +++ b/apps/desktop/src/renderer/react-query/workspaces/useSetActiveWorkspace.ts @@ -0,0 +1,62 @@ +import { toast } from "@superset/ui/sonner"; +import { electronTrpc } from "renderer/lib/electron-trpc"; + +/** + * Mutation hook for setting the active workspace + * Automatically invalidates getActive and getAll queries on success + * Shows undo toast if workspace was marked as unread (auto-cleared on switch) + */ +export function useSetActiveWorkspace( + options?: Parameters[0], +) { + const utils = electronTrpc.useUtils(); + const setUnread = electronTrpc.workspaces.setUnread.useMutation({ + onSuccess: () => { + utils.workspaces.getAllGrouped.invalidate(); + }, + onError: (error) => { + console.error("[workspace/setUnread] Failed to update unread status:", { + error: error.message, + }); + toast.error(`Failed to undo: ${error.message}`); + }, + }); + + return electronTrpc.workspaces.setActive.useMutation({ + ...options, + onError: (error, variables, context, meta) => { + console.error("[workspace/setActive] Failed to set active workspace:", { + workspaceId: variables.id, + error: error.message, + }); + toast.error(`Failed to switch workspace: ${error.message}`); + options?.onError?.(error, variables, context, meta); + }, + onSuccess: async (data, variables, ...rest) => { + // Auto-invalidate active workspace and all workspaces queries + await Promise.all([ + utils.workspaces.getActive.invalidate(), + utils.workspaces.getAll.invalidate(), + utils.workspaces.getAllGrouped.invalidate(), + ]); + + // Show undo toast if workspace was marked as unread + if (data.wasUnread) { + toast("Marked as read", { + description: "Workspace unread marker cleared", + action: { + label: "Undo", + onClick: () => { + setUnread.mutate({ id: variables.id, isUnread: true }); + }, + }, + duration: 5000, + }); + } + + // Call user's onSuccess if provided + // biome-ignore lint/suspicious/noExplicitAny: spread args for compatibility + await (options?.onSuccess as any)?.(data, variables, ...rest); + }, + }); +} diff --git a/apps/desktop/src/renderer/react-query/workspaces/useUpdateWorkspace.ts b/apps/desktop/src/renderer/react-query/workspaces/useUpdateWorkspace.ts index d8e3ce650..d9a0e0a6e 100644 --- a/apps/desktop/src/renderer/react-query/workspaces/useUpdateWorkspace.ts +++ b/apps/desktop/src/renderer/react-query/workspaces/useUpdateWorkspace.ts @@ -1,15 +1,15 @@ -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; /** * Mutation hook for updating a workspace * Automatically invalidates all workspace queries on success */ export function useUpdateWorkspace( - options?: Parameters[0], + options?: Parameters[0], ) { - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); - return trpc.workspaces.update.useMutation({ + return electronTrpc.workspaces.update.useMutation({ ...options, onSuccess: async (...args) => { // Auto-invalidate all workspace queries diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/account/page.tsx b/apps/desktop/src/renderer/routes/_authenticated/settings/account/page.tsx index 59ef6fc09..bd8052cff 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/settings/account/page.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/account/page.tsx @@ -3,6 +3,7 @@ import { Button } from "@superset/ui/button"; import { Skeleton } from "@superset/ui/skeleton"; import { toast } from "@superset/ui/sonner"; import { createFileRoute } from "@tanstack/react-router"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { trpc } from "renderer/lib/trpc"; export const Route = createFileRoute("/_authenticated/settings/account/")({ @@ -11,7 +12,7 @@ export const Route = createFileRoute("/_authenticated/settings/account/")({ function AccountSettingsPage() { const { data: user, isLoading } = trpc.user.me.useQuery(); - const signOutMutation = trpc.auth.signOut.useMutation({ + const signOutMutation = electronTrpc.auth.signOut.useMutation({ onSuccess: () => toast.success("Signed out"), }); diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/behavior/page.tsx b/apps/desktop/src/renderer/routes/_authenticated/settings/behavior/page.tsx index ccba2afab..5da5289a6 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/settings/behavior/page.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/behavior/page.tsx @@ -9,19 +9,19 @@ import { } from "@superset/ui/select"; import { Switch } from "@superset/ui/switch"; import { createFileRoute } from "@tanstack/react-router"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; export const Route = createFileRoute("/_authenticated/settings/behavior/")({ component: BehaviorSettingsPage, }); function BehaviorSettingsPage() { - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); // Confirm on quit setting const { data: confirmOnQuit, isLoading: isConfirmLoading } = - trpc.settings.getConfirmOnQuit.useQuery(); - const setConfirmOnQuit = trpc.settings.setConfirmOnQuit.useMutation({ + electronTrpc.settings.getConfirmOnQuit.useQuery(); + const setConfirmOnQuit = electronTrpc.settings.setConfirmOnQuit.useMutation({ onMutate: async ({ enabled }) => { await utils.settings.getConfirmOnQuit.cancel(); const previous = utils.settings.getConfirmOnQuit.getData(); @@ -44,10 +44,10 @@ function BehaviorSettingsPage() { // Terminal link behavior setting const { data: terminalLinkBehavior, isLoading: isLoadingLinkBehavior } = - trpc.settings.getTerminalLinkBehavior.useQuery(); + electronTrpc.settings.getTerminalLinkBehavior.useQuery(); const setTerminalLinkBehavior = - trpc.settings.setTerminalLinkBehavior.useMutation({ + electronTrpc.settings.setTerminalLinkBehavior.useMutation({ onMutate: async ({ behavior }) => { await utils.settings.getTerminalLinkBehavior.cancel(); const previous = utils.settings.getTerminalLinkBehavior.getData(); diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/components/SettingsSidebar/components/ProjectsSettings/ProjectsSettings.tsx b/apps/desktop/src/renderer/routes/_authenticated/settings/components/SettingsSidebar/components/ProjectsSettings/ProjectsSettings.tsx index 3ee7cffa8..b0ecf3e98 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/settings/components/SettingsSidebar/components/ProjectsSettings/ProjectsSettings.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/components/SettingsSidebar/components/ProjectsSettings/ProjectsSettings.tsx @@ -2,10 +2,11 @@ import { cn } from "@superset/ui/utils"; import { Link, useMatchRoute } from "@tanstack/react-router"; import { useEffect, useState } from "react"; import { HiChevronDown, HiChevronRight } from "react-icons/hi2"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; export function ProjectsSettings() { - const { data: groups = [] } = trpc.workspaces.getAllGrouped.useQuery(); + const { data: groups = [] } = + electronTrpc.workspaces.getAllGrouped.useQuery(); const matchRoute = useMatchRoute(); const [expandedProjects, setExpandedProjects] = useState>( new Set(), diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/keyboard/page.tsx b/apps/desktop/src/renderer/routes/_authenticated/settings/keyboard/page.tsx index 7ae403a81..2d0a72f63 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/settings/keyboard/page.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/keyboard/page.tsx @@ -13,7 +13,7 @@ import { toast } from "@superset/ui/sonner"; import { createFileRoute } from "@tanstack/react-router"; import { useEffect, useMemo, useState } from "react"; import { HiMagnifyingGlass } from "react-icons/hi2"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { captureHotkeyFromEvent, getHotkeyConflict, @@ -116,8 +116,8 @@ function KeyboardShortcutsPage() { ); const hotkeysByCategory = useHotkeysByCategory(); - const exportMutation = trpc.hotkeys.export.useMutation(); - const importMutation = trpc.hotkeys.import.useMutation(); + const exportMutation = electronTrpc.hotkeys.export.useMutation(); + const importMutation = electronTrpc.hotkeys.import.useMutation(); const showHotkeysDisplay = useHotkeyDisplay("SHOW_HOTKEYS"); diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/layout.tsx b/apps/desktop/src/renderer/routes/_authenticated/settings/layout.tsx index d5cfec260..9eb7789d3 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/settings/layout.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/layout.tsx @@ -1,5 +1,5 @@ import { createFileRoute, Outlet } from "@tanstack/react-router"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { SettingsSidebar } from "./components/SettingsSidebar"; export const Route = createFileRoute("/_authenticated/settings")({ @@ -7,7 +7,7 @@ export const Route = createFileRoute("/_authenticated/settings")({ }); function SettingsLayout() { - const { data: platform } = trpc.window.getPlatform.useQuery(); + const { data: platform } = electronTrpc.window.getPlatform.useQuery(); const isMac = platform === undefined || platform === "darwin"; return ( diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/project/$projectId/page.tsx b/apps/desktop/src/renderer/routes/_authenticated/settings/project/$projectId/page.tsx index 531d4844c..0d199d365 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/settings/project/$projectId/page.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/project/$projectId/page.tsx @@ -1,66 +1,49 @@ -import { createFileRoute, notFound } from "@tanstack/react-router"; -import { trpcClient } from "renderer/lib/trpc-client"; -import { NotFound } from "renderer/routes/not-found"; +import { createFileRoute } from "@tanstack/react-router"; export const Route = createFileRoute( "/_authenticated/settings/project/$projectId/", )({ component: ProjectSettingsPage, - notFoundComponent: NotFound, - loader: async ({ params, context }) => { - const projectQueryKey = [ - ["projects", "get"], - { input: { id: params.projectId }, type: "query" }, - ]; - - const configQueryKey = [ - ["config", "getConfigFilePath"], - { input: { projectId: params.projectId }, type: "query" }, - ]; - - try { - await Promise.all([ - context.queryClient.ensureQueryData({ - queryKey: projectQueryKey, - queryFn: () => - trpcClient.projects.get.query({ id: params.projectId }), - }), - context.queryClient.ensureQueryData({ - queryKey: configQueryKey, - queryFn: () => - trpcClient.config.getConfigFilePath.query({ - projectId: params.projectId, - }), - }), - ]); - } catch (error) { - // If project not found, throw notFound() to render 404 page - if (error instanceof Error && error.message.includes("not found")) { - throw notFound(); - } - // Re-throw other errors - throw error; - } - }, }); import { HiOutlineCog6Tooth, HiOutlineFolder } from "react-icons/hi2"; import { ConfigFilePreview } from "renderer/components/ConfigFilePreview"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; function ProjectSettingsPage() { const { projectId } = Route.useParams(); - const { data: project } = trpc.projects.get.useQuery({ + const { data: project, isLoading } = electronTrpc.projects.get.useQuery({ id: projectId, }); - const { data: configFilePath } = trpc.config.getConfigFilePath.useQuery({ - projectId, - }); + const { data: configFilePath } = + electronTrpc.config.getConfigFilePath.useQuery( + { projectId }, + { enabled: !!projectId }, + ); + + if (isLoading) { + return ( +
+
+
+
+
+
+ ); + } - // Project is guaranteed to exist here because loader handles 404s if (!project) { - return null; + return ( +
+
+

Project

+

+ Project not found +

+
+
+ ); } return ( diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/ringtones/page.tsx b/apps/desktop/src/renderer/routes/_authenticated/settings/ringtones/page.tsx index df4941687..050811f2f 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/settings/ringtones/page.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/ringtones/page.tsx @@ -2,7 +2,7 @@ import { cn } from "@superset/ui/utils"; import { createFileRoute } from "@tanstack/react-router"; import { useCallback, useEffect, useRef, useState } from "react"; import { HiBellSlash, HiCheck, HiPlay, HiStop } from "react-icons/hi2"; -import { trpcClient } from "renderer/lib/trpc-client"; +import { electronTrpcClient } from "renderer/lib/trpc-client"; import { AVAILABLE_RINGTONES, type Ringtone, @@ -167,7 +167,7 @@ function RingtonesSettingsPage() { clearTimeout(previewTimerRef.current); } // Stop any in-progress preview when navigating away - trpcClient.ringtone.stop.mutate().catch(() => { + electronTrpcClient.ringtone.stop.mutate().catch(() => { // Ignore errors during cleanup }); }; @@ -188,7 +188,7 @@ function RingtonesSettingsPage() { // If this ringtone is already playing, stop it if (playingId === ringtone.id) { try { - await trpcClient.ringtone.stop.mutate(); + await electronTrpcClient.ringtone.stop.mutate(); } catch (error) { console.error("Failed to stop ringtone:", error); } @@ -198,7 +198,7 @@ function RingtonesSettingsPage() { // Stop any currently playing sound first try { - await trpcClient.ringtone.stop.mutate(); + await electronTrpcClient.ringtone.stop.mutate(); } catch (error) { console.error("Failed to stop ringtone:", error); } @@ -207,7 +207,7 @@ function RingtonesSettingsPage() { setPlayingId(ringtone.id); try { - await trpcClient.ringtone.preview.mutate({ + await electronTrpcClient.ringtone.preview.mutate({ filename: ringtone.filename, }); } catch (error) { diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/team/components/MemberActions/MemberActions.tsx b/apps/desktop/src/renderer/routes/_authenticated/settings/team/components/MemberActions/MemberActions.tsx index 526c67a0a..c2af99415 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/settings/team/components/MemberActions/MemberActions.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/team/components/MemberActions/MemberActions.tsx @@ -1,4 +1,3 @@ -import { authClient } from "@superset/auth/client"; import { Button } from "@superset/ui/button"; import { Dialog, @@ -17,6 +16,7 @@ import { import { toast } from "@superset/ui/sonner"; import { useState } from "react"; import { HiEllipsisVertical, HiOutlineTrash } from "react-icons/hi2"; +import { authClient } from "renderer/lib/auth-client"; export interface MemberDetails { memberId: string; diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/team/page.tsx b/apps/desktop/src/renderer/routes/_authenticated/settings/team/page.tsx index 8c2fc5ec9..da4483830 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/settings/team/page.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/team/page.tsx @@ -12,7 +12,7 @@ import { import { eq } from "@tanstack/db"; import { useLiveQuery } from "@tanstack/react-db"; import { createFileRoute } from "@tanstack/react-router"; -import { useAuth } from "renderer/providers/AuthProvider"; +import { authClient } from "renderer/lib/auth-client"; import { useCollections } from "renderer/routes/_authenticated/providers/CollectionsProvider"; import { InviteMemberButton } from "./components/InviteMemberButton"; import { MemberActions } from "./components/MemberActions"; @@ -22,7 +22,7 @@ export const Route = createFileRoute("/_authenticated/settings/team/")({ }); function TeamSettingsPage() { - const { session } = useAuth(); + const { data: session } = authClient.useSession(); const collections = useCollections(); const { data: membersData, isLoading } = useLiveQuery( diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/workspace/$workspaceId/page.tsx b/apps/desktop/src/renderer/routes/_authenticated/settings/workspace/$workspaceId/page.tsx index 39037373f..e5b80e094 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/settings/workspace/$workspaceId/page.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/workspace/$workspaceId/page.tsx @@ -1,52 +1,47 @@ -import { createFileRoute, notFound } from "@tanstack/react-router"; -import { trpcClient } from "renderer/lib/trpc-client"; -import { NotFound } from "renderer/routes/not-found"; +import { createFileRoute } from "@tanstack/react-router"; export const Route = createFileRoute( "/_authenticated/settings/workspace/$workspaceId/", )({ component: WorkspaceSettingsPage, - notFoundComponent: NotFound, - loader: async ({ params, context }) => { - const queryKey = [ - ["workspaces", "get"], - { input: { id: params.workspaceId }, type: "query" }, - ]; - - try { - await context.queryClient.ensureQueryData({ - queryKey, - queryFn: () => - trpcClient.workspaces.get.query({ id: params.workspaceId }), - }); - } catch (error) { - // If workspace not found, throw notFound() to render 404 page - if (error instanceof Error && error.message.includes("not found")) { - throw notFound(); - } - // Re-throw other errors - throw error; - } - }, }); import { Input } from "@superset/ui/input"; import { HiOutlineFolder, HiOutlinePencilSquare } from "react-icons/hi2"; import { LuGitBranch } from "react-icons/lu"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useWorkspaceRename } from "renderer/screens/main/hooks/useWorkspaceRename"; function WorkspaceSettingsPage() { const { workspaceId } = Route.useParams(); - const { data: workspace } = trpc.workspaces.get.useQuery({ + const { data: workspace, isLoading } = electronTrpc.workspaces.get.useQuery({ id: workspaceId, }); const rename = useWorkspaceRename(workspace?.id ?? "", workspace?.name ?? ""); - // Workspace is guaranteed to exist here because loader handles 404s + if (isLoading) { + return ( +
+
+
+
+
+
+ ); + } + if (!workspace) { - return null; + return ( +
+
+

Workspace

+

+ Workspace not found +

+
+
+ ); } return ( diff --git a/apps/desktop/src/renderer/routes/sign-in/page.tsx b/apps/desktop/src/renderer/routes/sign-in/page.tsx index 2cbddbcc7..dcdf3a2d7 100644 --- a/apps/desktop/src/renderer/routes/sign-in/page.tsx +++ b/apps/desktop/src/renderer/routes/sign-in/page.tsx @@ -4,9 +4,9 @@ import { createFileRoute, Navigate } from "@tanstack/react-router"; import { useEffect } from "react"; import { FaGithub } from "react-icons/fa"; import { FcGoogle } from "react-icons/fc"; +import { authClient } from "renderer/lib/auth-client"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { posthog } from "renderer/lib/posthog"; -import { trpc } from "renderer/lib/trpc"; -import { useAuth } from "renderer/providers/AuthProvider"; import { SupersetLogo } from "./components/SupersetLogo"; export const Route = createFileRoute("/sign-in/")({ @@ -14,14 +14,14 @@ export const Route = createFileRoute("/sign-in/")({ }); function SignInPage() { - const { session, token } = useAuth(); - const signInMutation = trpc.auth.signIn.useMutation(); + const { data: session } = authClient.useSession(); + const signInMutation = electronTrpc.auth.signIn.useMutation(); useEffect(() => { posthog.capture("desktop_opened"); }, []); - const isSignedIn = !!token && !!session?.user; + const isSignedIn = !!session?.user; if (isSignedIn) { return ; } diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceSidebarHeader/OrganizationDropdown.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceSidebarHeader/OrganizationDropdown.tsx index 82659eea0..91405aeb3 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceSidebarHeader/OrganizationDropdown.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceSidebarHeader/OrganizationDropdown.tsx @@ -18,8 +18,8 @@ import { HiChevronUpDown, HiOutlineArrowRightOnRectangle, } from "react-icons/hi2"; -import { trpc } from "renderer/lib/trpc"; -import { useAuth } from "renderer/providers/AuthProvider"; +import { authClient } from "renderer/lib/auth-client"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useCollections } from "renderer/routes/_authenticated/providers/CollectionsProvider"; interface OrganizationDropdownProps { @@ -29,10 +29,9 @@ interface OrganizationDropdownProps { export function OrganizationDropdown({ isCollapsed = false, }: OrganizationDropdownProps) { - const { session } = useAuth(); + const { data: session } = authClient.useSession(); const collections = useCollections(); - const setActiveOrg = trpc.auth.setActiveOrganization.useMutation(); - const signOut = trpc.auth.signOut.useMutation(); + const signOutMutation = electronTrpc.auth.signOut.useMutation(); const navigate = useNavigate(); const activeOrganizationId = session?.session?.activeOrganizationId; @@ -50,11 +49,14 @@ export function OrganizationDropdown({ const orgName = activeOrganization?.name ?? "No Organization"; const switchOrganization = async (newOrgId: string) => { - await setActiveOrg.mutateAsync({ organizationId: newOrgId }); + await authClient.organization.setActive({ + organizationId: newOrgId, + }); }; - const handleSignOut = () => { - signOut.mutate(); + const handleSignOut = async () => { + await authClient.signOut(); + signOutMutation.mutate(); }; const trigger = isCollapsed ? ( diff --git a/apps/desktop/src/renderer/stores/app-state.ts b/apps/desktop/src/renderer/stores/app-state.ts new file mode 100644 index 000000000..e1dd48435 --- /dev/null +++ b/apps/desktop/src/renderer/stores/app-state.ts @@ -0,0 +1,54 @@ +import { create } from "zustand"; +import { devtools } from "zustand/middleware"; + +export type AppView = "workspace" | "tasks" | "workspaces-list"; + +interface AppState { + currentView: AppView; + isTasksTabOpen: boolean; + isWorkspacesListOpen: boolean; + setView: (view: AppView) => void; + openTasks: () => void; + closeTasks: () => void; + openWorkspacesList: () => void; + closeWorkspacesList: () => void; +} + +export const useAppStore = create()( + devtools( + (set) => ({ + currentView: "workspace", + isTasksTabOpen: false, + isWorkspacesListOpen: false, + + setView: (view) => { + set({ currentView: view }); + }, + + openTasks: () => { + set({ currentView: "tasks", isTasksTabOpen: true }); + }, + + closeTasks: () => { + set({ currentView: "workspace", isTasksTabOpen: false }); + }, + + openWorkspacesList: () => { + set({ currentView: "workspaces-list", isWorkspacesListOpen: true }); + }, + + closeWorkspacesList: () => { + set({ currentView: "workspace", isWorkspacesListOpen: false }); + }, + }), + { name: "AppStore" }, + ), +); + +// Convenience hooks +export const useCurrentView = () => useAppStore((state) => state.currentView); +export const useOpenTasks = () => useAppStore((state) => state.openTasks); +export const useOpenWorkspacesList = () => + useAppStore((state) => state.openWorkspacesList); +export const useCloseWorkspacesList = () => + useAppStore((state) => state.closeWorkspacesList); diff --git a/apps/desktop/src/renderer/stores/hotkeys/store.ts b/apps/desktop/src/renderer/stores/hotkeys/store.ts index 7c481313e..c64f927b2 100644 --- a/apps/desktop/src/renderer/stores/hotkeys/store.ts +++ b/apps/desktop/src/renderer/stores/hotkeys/store.ts @@ -1,6 +1,6 @@ import { useEffect, useMemo, useRef } from "react"; -import { trpc } from "renderer/lib/trpc"; -import { trpcClient } from "renderer/lib/trpc-client"; +import { electronTrpc } from "renderer/lib/electron-trpc"; +import { electronTrpcClient } from "renderer/lib/trpc-client"; import { setSkipNextHotkeysPersist, trpcHotkeysStorage, @@ -278,9 +278,9 @@ export function useHotkeysSync() { const platform = useHotkeysStore((state) => state.platform); const replace = useHotkeysStore((state) => state.replaceHotkeysState); - trpc.uiState.hotkeys.subscribe.useSubscription(undefined, { + electronTrpc.uiState.hotkeys.subscribe.useSubscription(undefined, { onData: () => { - trpcClient.uiState.hotkeys.get + electronTrpcClient.uiState.hotkeys.get .query() .then((state: HotkeysState) => { const current = useHotkeysStore.getState().hotkeysState; diff --git a/apps/desktop/src/renderer/stores/index.ts b/apps/desktop/src/renderer/stores/index.ts index 82454b735..824bd5107 100644 --- a/apps/desktop/src/renderer/stores/index.ts +++ b/apps/desktop/src/renderer/stores/index.ts @@ -1,3 +1,4 @@ +export * from "./app-state"; export * from "./hotkeys"; export * from "./markdown-preferences"; export * from "./ports"; diff --git a/apps/desktop/src/renderer/stores/tabs/useAgentHookListener.ts b/apps/desktop/src/renderer/stores/tabs/useAgentHookListener.ts index e6390a24c..5fd87aa0f 100644 --- a/apps/desktop/src/renderer/stores/tabs/useAgentHookListener.ts +++ b/apps/desktop/src/renderer/stores/tabs/useAgentHookListener.ts @@ -1,9 +1,9 @@ -import { useNavigate } from "@tanstack/react-router"; import { useRef } from "react"; -import { trpc } from "renderer/lib/trpc"; -import { navigateToWorkspace } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; +import { electronTrpc } from "renderer/lib/electron-trpc"; +import { useSetActiveWorkspace } from "renderer/react-query/workspaces/useSetActiveWorkspace"; import { NOTIFICATION_EVENTS } from "shared/constants"; import { debugLog } from "shared/debug"; +import { useAppStore } from "../app-state"; import { useTabsStore } from "./store"; import { resolveNotificationTarget } from "./utils/resolve-notification-target"; @@ -33,23 +33,15 @@ import { resolveNotificationTarget } from "./utils/resolve-notification-target"; * for clearing stuck indicators when agent hooks fail to fire. */ export function useAgentHookListener() { - const navigate = useNavigate(); - - // Track current workspace from router to avoid stale closure - const currentWorkspaceIdRef = useRef(null); - - // We need to update this ref from the workspace page, but for now - // we'll use router state. This is called from _authenticated/layout - // so we check the current route - try { - const location = window.location; - const match = location.pathname.match(/\/workspace\/([^/]+)/); - currentWorkspaceIdRef.current = match ? match[1] : null; - } catch { - currentWorkspaceIdRef.current = null; - } - - trpc.notifications.subscribe.useSubscription(undefined, { + const setActiveWorkspace = useSetActiveWorkspace(); + const { data: activeWorkspace } = + electronTrpc.workspaces.getActive.useQuery(); + + // Use ref to avoid stale closure in subscription callback + const activeWorkspaceRef = useRef(activeWorkspace); + activeWorkspaceRef.current = activeWorkspace; + + electronTrpc.notifications.subscribe.useSubscription(undefined, { onData: (event) => { if (!event.data) return; @@ -64,7 +56,7 @@ export function useAgentHookListener() { eventType: event.data?.eventType, paneId, workspaceId, - currentWorkspace: currentWorkspaceIdRef.current, + activeWorkspace: activeWorkspaceRef.current?.id, }); if (!paneId) return; @@ -86,7 +78,7 @@ export function useAgentHookListener() { const focusedPaneId = activeTabId && state.focusedPaneIds[activeTabId]; const isAlreadyActive = - currentWorkspaceIdRef.current === workspaceId && + activeWorkspaceRef.current?.id === workspaceId && focusedPaneId === paneId; debugLog("agent-hooks", "Stop event:", { @@ -106,25 +98,38 @@ export function useAgentHookListener() { } } } else if (event.type === NOTIFICATION_EVENTS.FOCUS_TAB) { - // Navigate to the workspace and focus the tab/pane - navigateToWorkspace(workspaceId, navigate); - - // Set active tab and focused pane after navigation - // (router navigation is async, but state updates are immediate) - const freshState = useTabsStore.getState(); - const freshTarget = resolveNotificationTarget(event.data, freshState); - if (!freshTarget?.tabId) return; + const appState = useAppStore.getState(); + if (appState.currentView !== "workspace") { + appState.setView("workspace"); + } - const freshTab = freshState.tabs.find( - (t) => t.id === freshTarget.tabId, + setActiveWorkspace.mutate( + { id: workspaceId }, + { + onSuccess: () => { + const freshState = useTabsStore.getState(); + const freshTarget = resolveNotificationTarget( + event.data, + freshState, + ); + if (!freshTarget?.tabId) return; + + const freshTab = freshState.tabs.find( + (t) => t.id === freshTarget.tabId, + ); + if (!freshTab || freshTab.workspaceId !== workspaceId) return; + + freshState.setActiveTab(workspaceId, freshTarget.tabId); + + if (freshTarget.paneId && freshState.panes[freshTarget.paneId]) { + freshState.setFocusedPane( + freshTarget.tabId, + freshTarget.paneId, + ); + } + }, + }, ); - if (!freshTab || freshTab.workspaceId !== workspaceId) return; - - freshState.setActiveTab(workspaceId, freshTarget.tabId); - - if (freshTarget.paneId && freshState.panes[freshTarget.paneId]) { - freshState.setFocusedPane(freshTarget.tabId, freshTarget.paneId); - } } }, }); diff --git a/apps/desktop/src/renderer/stores/tabs/utils/terminal-cleanup.ts b/apps/desktop/src/renderer/stores/tabs/utils/terminal-cleanup.ts index 25e36afa3..741943df8 100644 --- a/apps/desktop/src/renderer/stores/tabs/utils/terminal-cleanup.ts +++ b/apps/desktop/src/renderer/stores/tabs/utils/terminal-cleanup.ts @@ -1,10 +1,10 @@ -import { trpcClient } from "../../../lib/trpc-client"; +import { electronTrpcClient } from "../../../lib/trpc-client"; /** * Uses standalone tRPC client to avoid React hook dependencies */ export const killTerminalForPane = (paneId: string): void => { - trpcClient.terminal.kill.mutate({ paneId }).catch((error) => { + electronTrpcClient.terminal.kill.mutate({ paneId }).catch((error) => { console.warn(`Failed to kill terminal for pane ${paneId}:`, error); }); }; From 848edce0767a540361ea56b3c95991525df59795 Mon Sep 17 00:00:00 2001 From: Satya Patel Date: Tue, 13 Jan 2026 17:33:14 -0800 Subject: [PATCH 04/12] fix(desktop): rename remaining trpcClient references to electronTrpcClient --- .../_authenticated/_dashboard/workspace/$workspaceId/page.tsx | 2 +- .../ContentView/TabsContent/Terminal/Terminal.tsx | 2 +- .../ContentView/TabsContent/Terminal/helpers.test.ts | 3 ++- .../WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/$workspaceId/page.tsx b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/$workspaceId/page.tsx index 261f37f6e..ca7109f1d 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/$workspaceId/page.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/$workspaceId/page.tsx @@ -1,7 +1,7 @@ import { createFileRoute, notFound, useNavigate } from "@tanstack/react-router"; import { useCallback, useMemo } from "react"; import { trpc } from "renderer/lib/trpc"; -import { trpcClient } from "renderer/lib/trpc-client"; +import { electronTrpcClient as trpcClient } from "renderer/lib/trpc-client"; import { navigateToWorkspace } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; import { NotFound } from "renderer/routes/not-found"; import { ContentView } from "renderer/screens/main/components/WorkspaceView/ContentView"; diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx index 03248c8f6..821413df8 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx @@ -6,7 +6,7 @@ import "@xterm/xterm/css/xterm.css"; import debounce from "lodash/debounce"; import { useCallback, useEffect, useRef, useState } from "react"; import { trpc } from "renderer/lib/trpc"; -import { trpcClient } from "renderer/lib/trpc-client"; +import { electronTrpcClient as trpcClient } from "renderer/lib/trpc-client"; import { useAppHotkey } from "renderer/stores/hotkeys"; import { useTabsStore } from "renderer/stores/tabs/store"; import { useTerminalCallbacksStore } from "renderer/stores/tabs/terminal-callbacks"; diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts index fe8d2e8e9..71bf3c3f1 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.test.ts @@ -14,7 +14,7 @@ globalThis.localStorage = mockLocalStorage; // Mock trpc-client to avoid electronTRPC dependency mock.module("renderer/lib/trpc-client", () => ({ - trpcClient: { + electronTrpcClient: { external: { openUrl: { mutate: mock(() => Promise.resolve()) }, openFileInEditor: { mutate: mock(() => Promise.resolve()) }, @@ -26,6 +26,7 @@ mock.module("renderer/lib/trpc-client", () => ({ }, }, }, + electronReactClient: {}, })); // Import after mocks are set up diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts index fbd1b980b..d1e9d7973 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/helpers.ts @@ -8,7 +8,7 @@ import { WebglAddon } from "@xterm/addon-webgl"; import type { ITheme } from "@xterm/xterm"; import { Terminal as XTerm } from "@xterm/xterm"; import { debounce } from "lodash"; -import { trpcClient } from "renderer/lib/trpc-client"; +import { electronTrpcClient as trpcClient } from "renderer/lib/trpc-client"; import { getHotkeyKeys, isAppHotkeyEvent } from "renderer/stores/hotkeys"; import { toXtermTheme } from "renderer/stores/theme/utils"; import { isTerminalReservedEvent, matchesHotkeyEvent } from "shared/hotkeys"; From ea633d96bfef9bcc27b50e7e7810db97b7420e72 Mon Sep 17 00:00:00 2001 From: Satya Patel Date: Wed, 14 Jan 2026 09:57:58 -0800 Subject: [PATCH 05/12] Huh --- .../NewWorkspaceModal/NewWorkspaceModal.tsx | 15 +- .../PostHogUserIdentifier.tsx | 10 +- .../renderer/hooks/useWorkspaceShortcuts.ts | 4 +- apps/desktop/src/renderer/lib/trpc.ts | 7 +- .../renderer/react-query/workspaces/index.ts | 1 - .../workspaces/useCloseWorkspace.ts | 109 ++++----------- .../workspaces/useDeleteWorkspace.ts | 132 ++++++------------ .../workspaces/useSetActiveWorkspace.ts | 62 -------- .../workspace/$workspaceId/page.tsx | 14 +- .../_dashboard/workspace/page.tsx | 4 +- .../_authenticated/settings/account/page.tsx | 5 +- .../SidebarControl/SidebarControl.tsx | 10 +- .../components/StartView/CloneRepoDialog.tsx | 6 +- .../components/StartView/InitGitDialog.tsx | 6 +- .../main/components/StartView/StartTopBar.tsx | 4 +- .../main/components/StartView/index.tsx | 6 +- .../components/TopBar/OpenInMenuButton.tsx | 10 +- .../main/components/TopBar/WindowControls.tsx | 8 +- .../screens/main/components/TopBar/index.tsx | 6 +- .../main/components/WorkspaceInitEffects.tsx | 8 +- .../PortsList/hooks/usePortsData.ts | 14 +- .../ProjectSection/ProjectHeader.tsx | 8 +- .../ProjectThumbnail/ProjectThumbnail.tsx | 4 +- .../WorkspaceListItem/WorkspaceListItem.tsx | 10 +- .../BranchSwitcher/BranchSwitcher.tsx | 8 +- .../DeleteWorkspaceDialog.tsx | 6 +- .../WorkspaceHoverCard/WorkspaceHoverCard.tsx | 4 +- .../NewWorkspaceButton.tsx | 4 +- .../hooks/useFileContent/useFileContent.ts | 8 +- .../hooks/useFileSave/useFileSave.ts | 6 +- .../ContentView/TabsContent/TabView/index.tsx | 4 +- .../DirectoryNavigator/DirectoryNavigator.tsx | 8 +- .../TabsContent/Terminal/Terminal.tsx | 18 +-- .../EditorContextMenu/EditorContextMenu.tsx | 4 +- .../Sidebar/ChangesView/ChangesView.tsx | 24 ++-- .../ChangesHeader/ChangesHeader.tsx | 4 +- .../components/CommitInput/CommitInput.tsx | 12 +- .../components/FileItem/FileItem.tsx | 6 +- .../WorkspaceView/Sidebar/index.tsx | 6 +- .../WorkspaceInitializingView.tsx | 8 +- .../WorkspaceRow/DeleteWorktreeDialog.tsx | 4 +- .../WorkspaceRow/WorkspaceRow.tsx | 4 +- .../WorkspacesListView/WorkspacesListView.tsx | 12 +- .../main/hooks/usePRStatus/usePRStatus.ts | 4 +- .../stores/tabs/useAgentHookListener.ts | 77 +++++----- 45 files changed, 266 insertions(+), 428 deletions(-) delete mode 100644 apps/desktop/src/renderer/react-query/workspaces/useSetActiveWorkspace.ts diff --git a/apps/desktop/src/renderer/components/NewWorkspaceModal/NewWorkspaceModal.tsx b/apps/desktop/src/renderer/components/NewWorkspaceModal/NewWorkspaceModal.tsx index ec17f725c..e644cd771 100644 --- a/apps/desktop/src/renderer/components/NewWorkspaceModal/NewWorkspaceModal.tsx +++ b/apps/desktop/src/renderer/components/NewWorkspaceModal/NewWorkspaceModal.tsx @@ -94,8 +94,6 @@ export function NewWorkspaceModal() { debouncedSetTitle(value); // Debounced update for derived state }; - const { data: activeWorkspace } = - electronTrpc.workspaces.getActive.useQuery(); const { data: recentProjects = [] } = electronTrpc.projects.getRecents.useQuery(); const { @@ -108,8 +106,6 @@ export function NewWorkspaceModal() { ); const createWorkspace = useCreateWorkspace(); - const currentProjectId = activeWorkspace?.projectId; - // Filter branches based on search const filteredBranches = useMemo(() => { if (!branchData?.branches) return []; @@ -120,15 +116,12 @@ export function NewWorkspaceModal() { ); }, [branchData?.branches, branchSearch]); - // Auto-select project when modal opens (prioritize pre-selected, then current) + // Auto-select project when modal opens (use pre-selected from NewWorkspaceButton) useEffect(() => { - if (isOpen && !selectedProjectId) { - const projectToSelect = preSelectedProjectId ?? currentProjectId; - if (projectToSelect) { - setSelectedProjectId(projectToSelect); - } + if (isOpen && !selectedProjectId && preSelectedProjectId) { + setSelectedProjectId(preSelectedProjectId); } - }, [isOpen, currentProjectId, selectedProjectId, preSelectedProjectId]); + }, [isOpen, selectedProjectId, preSelectedProjectId]); // Effective base branch - use explicit selection or fall back to default const effectiveBaseBranch = baseBranch ?? branchData?.defaultBranch ?? null; diff --git a/apps/desktop/src/renderer/components/PostHogUserIdentifier/PostHogUserIdentifier.tsx b/apps/desktop/src/renderer/components/PostHogUserIdentifier/PostHogUserIdentifier.tsx index 8178e22c4..a050a8611 100644 --- a/apps/desktop/src/renderer/components/PostHogUserIdentifier/PostHogUserIdentifier.tsx +++ b/apps/desktop/src/renderer/components/PostHogUserIdentifier/PostHogUserIdentifier.tsx @@ -1,13 +1,14 @@ import { useEffect } from "react"; +import { authClient } from "renderer/lib/auth-client"; import { electronTrpc } from "renderer/lib/electron-trpc"; -import { trpc } from "renderer/lib/trpc"; import { posthog } from "../../lib/posthog"; const AUTH_COMPLETED_KEY = "superset_auth_completed"; export function PostHogUserIdentifier() { - const { data: user, isSuccess } = trpc.user.me.useQuery(); + const { data: session } = authClient.useSession(); + const user = session?.user; const { mutate: setUserId } = electronTrpc.analytics.setUserId.useMutation(); useEffect(() => { @@ -25,12 +26,13 @@ export function PostHogUserIdentifier() { posthog.capture("auth_completed"); localStorage.setItem(AUTH_COMPLETED_KEY, user.id); } - } else if (isSuccess) { + } else if (session !== undefined && !user) { + // Session loaded but no user - user is signed out posthog.reset(); setUserId({ userId: null }); localStorage.removeItem(AUTH_COMPLETED_KEY); } - }, [user, isSuccess, setUserId]); + }, [user, session, setUserId]); return null; } diff --git a/apps/desktop/src/renderer/hooks/useWorkspaceShortcuts.ts b/apps/desktop/src/renderer/hooks/useWorkspaceShortcuts.ts index 48eb7c2ec..bdca47475 100644 --- a/apps/desktop/src/renderer/hooks/useWorkspaceShortcuts.ts +++ b/apps/desktop/src/renderer/hooks/useWorkspaceShortcuts.ts @@ -1,6 +1,6 @@ import { useNavigate } from "@tanstack/react-router"; import { useCallback } from "react"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { navigateToWorkspace } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; import { useAppHotkey } from "renderer/stores/hotkeys"; @@ -11,7 +11,7 @@ import { useAppHotkey } from "renderer/stores/hotkeys"; * Handles ⌘1-9 workspace switching shortcuts (global). */ export function useWorkspaceShortcuts() { - const { data: groups = [] } = trpc.workspaces.getAllGrouped.useQuery(); + const { data: groups = [] } = electronTrpc.workspaces.getAllGrouped.useQuery(); const navigate = useNavigate(); // Flatten workspaces for keyboard navigation diff --git a/apps/desktop/src/renderer/lib/trpc.ts b/apps/desktop/src/renderer/lib/trpc.ts index 12fd8fae8..34f612119 100644 --- a/apps/desktop/src/renderer/lib/trpc.ts +++ b/apps/desktop/src/renderer/lib/trpc.ts @@ -1,6 +1,11 @@ +import type { AppRouter } from "@superset/trpc"; import { createTRPCReact } from "@trpc/react-query"; import type { inferRouterOutputs } from "@trpc/server"; -import type { AppRouter } from "lib/trpc/routers"; +/** + * HTTP API tRPC client for communicating with the Superset API. + * Uses bearer auth and talks to NEXT_PUBLIC_API_URL. + * For Electron IPC communication, use `electronTrpc` instead. + */ export const trpc = createTRPCReact(); export type RouterOutputs = inferRouterOutputs; diff --git a/apps/desktop/src/renderer/react-query/workspaces/index.ts b/apps/desktop/src/renderer/react-query/workspaces/index.ts index b109fc6d1..48be214e3 100644 --- a/apps/desktop/src/renderer/react-query/workspaces/index.ts +++ b/apps/desktop/src/renderer/react-query/workspaces/index.ts @@ -5,6 +5,5 @@ export { useDeleteWorkspace } from "./useDeleteWorkspace"; export { useDeleteWorktree } from "./useDeleteWorktree"; export { useOpenWorktree } from "./useOpenWorktree"; export { useReorderWorkspaces } from "./useReorderWorkspaces"; -export { useSetActiveWorkspace } from "./useSetActiveWorkspace"; export { useUpdateWorkspace } from "./useUpdateWorkspace"; export { useWorkspaceDeleteHandler } from "./useWorkspaceDeleteHandler"; diff --git a/apps/desktop/src/renderer/react-query/workspaces/useCloseWorkspace.ts b/apps/desktop/src/renderer/react-query/workspaces/useCloseWorkspace.ts index ccb175c32..c6aea3bd5 100644 --- a/apps/desktop/src/renderer/react-query/workspaces/useCloseWorkspace.ts +++ b/apps/desktop/src/renderer/react-query/workspaces/useCloseWorkspace.ts @@ -1,4 +1,6 @@ +import { useNavigate, useParams } from "@tanstack/react-router"; import { electronTrpc } from "renderer/lib/electron-trpc"; +import { navigateToWorkspace } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; type CloseContext = { previousGrouped: ReturnType< @@ -11,22 +13,20 @@ type CloseContext = { >["workspaces"]["getAll"]["getData"] extends () => infer R ? R : never; - previousActive: ReturnType< - typeof electronTrpc.useUtils - >["workspaces"]["getActive"]["getData"] extends () => infer R - ? R - : never; }; /** * Mutation hook for closing a workspace without deleting the worktree * Uses optimistic updates to immediately remove workspace from UI, * then performs actual close in background. + * Automatically navigates away if the closed workspace is currently being viewed. */ export function useCloseWorkspace( options?: Parameters[0], ) { const utils = electronTrpc.useUtils(); + const navigate = useNavigate(); + const params = useParams({ strict: false }); return electronTrpc.workspaces.close.useMutation({ ...options, @@ -35,13 +35,11 @@ export function useCloseWorkspace( await Promise.all([ utils.workspaces.getAll.cancel(), utils.workspaces.getAllGrouped.cancel(), - utils.workspaces.getActive.cancel(), ]); // Snapshot previous values for rollback const previousGrouped = utils.workspaces.getAllGrouped.getData(); const previousAll = utils.workspaces.getAll.getData(); - const previousActive = utils.workspaces.getActive.getData(); // Optimistically remove workspace from getAllGrouped cache if (previousGrouped) { @@ -64,75 +62,8 @@ export function useCloseWorkspace( ); } - // Switch to next workspace to prevent "no workspace" flash - if (previousActive?.id === id) { - const remainingWorkspaces = previousAll - ?.filter((w) => w.id !== id) - .sort((a, b) => b.lastOpenedAt - a.lastOpenedAt); - - if (remainingWorkspaces && remainingWorkspaces.length > 0) { - // Find a workspace with full data available in previousGrouped - let selectedWorkspace = null; - let projectGroup = null; - let workspaceFromGrouped = null; - - for (const candidate of remainingWorkspaces) { - const group = previousGrouped?.find((g) => - g.workspaces.some((w) => w.id === candidate.id), - ); - if (group) { - selectedWorkspace = candidate; - projectGroup = group; - workspaceFromGrouped = group.workspaces.find( - (w) => w.id === candidate.id, - ); - break; - } - } - - if (selectedWorkspace && projectGroup && workspaceFromGrouped) { - const worktreeData = - workspaceFromGrouped.type === "worktree" - ? { - branch: selectedWorkspace.branch, - baseBranch: null, - gitStatus: { - branch: selectedWorkspace.branch, - needsRebase: false, - lastRefreshed: Date.now(), - }, - } - : null; - - utils.workspaces.getActive.setData(undefined, { - ...selectedWorkspace, - type: workspaceFromGrouped.type, - worktreePath: workspaceFromGrouped.worktreePath, - project: { - id: projectGroup.project.id, - name: projectGroup.project.name, - mainRepoPath: projectGroup.project.mainRepoPath, - }, - worktree: worktreeData, - }); - } else { - // Fallback: set minimal data to prevent StartView flash (refetch will populate full data) - const fallback = remainingWorkspaces[0]; - utils.workspaces.getActive.setData(undefined, { - ...fallback, - type: fallback.type === "branch" ? "branch" : "worktree", - worktreePath: "", - project: null, - worktree: null, - }); - } - } else { - utils.workspaces.getActive.setData(undefined, null); - } - } - // Return context for rollback - return { previousGrouped, previousAll, previousActive } as CloseContext; + return { previousGrouped, previousAll } as CloseContext; }, onError: (_err, _variables, context) => { // Rollback to previous state on error @@ -145,18 +76,36 @@ export function useCloseWorkspace( if (context?.previousAll !== undefined) { utils.workspaces.getAll.setData(undefined, context.previousAll); } - if (context?.previousActive !== undefined) { - utils.workspaces.getActive.setData(undefined, context.previousActive); - } }, - onSuccess: async (...args) => { + onSuccess: async (data, variables, ...rest) => { // Invalidate to ensure consistency with backend state await utils.workspaces.invalidate(); // Invalidate project queries since close updates project metadata await utils.projects.getRecents.invalidate(); + // If the closed workspace is currently being viewed, navigate away + if (params.workspaceId === variables.id) { + // Try to navigate to previous workspace first, then next + const prevWorkspaceId = + await utils.workspaces.getPreviousWorkspace.fetch({ + id: variables.id, + }); + const nextWorkspaceId = await utils.workspaces.getNextWorkspace.fetch({ + id: variables.id, + }); + + const targetWorkspaceId = prevWorkspaceId ?? nextWorkspaceId; + + if (targetWorkspaceId) { + navigateToWorkspace(targetWorkspaceId, navigate); + } else { + // No other workspaces, navigate to workspace index (shows StartView) + navigate({ to: "/workspace" }); + } + } + // Call user's onSuccess if provided - await options?.onSuccess?.(...args); + await options?.onSuccess?.(data, variables, ...rest); }, }); } diff --git a/apps/desktop/src/renderer/react-query/workspaces/useDeleteWorkspace.ts b/apps/desktop/src/renderer/react-query/workspaces/useDeleteWorkspace.ts index c9a396508..8cf467c4d 100644 --- a/apps/desktop/src/renderer/react-query/workspaces/useDeleteWorkspace.ts +++ b/apps/desktop/src/renderer/react-query/workspaces/useDeleteWorkspace.ts @@ -1,4 +1,6 @@ +import { useNavigate, useParams } from "@tanstack/react-router"; import { electronTrpc } from "renderer/lib/electron-trpc"; +import { navigateToWorkspace } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; type DeleteContext = { previousGrouped: ReturnType< @@ -11,35 +13,35 @@ type DeleteContext = { >["workspaces"]["getAll"]["getData"] extends () => infer R ? R : never; - previousActive: ReturnType< - typeof electronTrpc.useUtils - >["workspaces"]["getActive"]["getData"] extends () => infer R - ? R - : never; }; /** - * Mutation hook for deleting a workspace with optimistic updates. - * Server marks `deletingAt` immediately so refetches stay correct during slow git operations. + * Mutation hook for deleting a workspace and its worktree + * Uses optimistic updates to immediately remove workspace from UI, + * then performs actual deletion in background. + * Automatically navigates away if the deleted workspace is currently being viewed. */ export function useDeleteWorkspace( options?: Parameters[0], ) { const utils = electronTrpc.useUtils(); + const navigate = useNavigate(); + const params = useParams({ strict: false }); return electronTrpc.workspaces.delete.useMutation({ ...options, onMutate: async ({ id }) => { + // Cancel outgoing refetches to avoid overwriting optimistic update await Promise.all([ utils.workspaces.getAll.cancel(), utils.workspaces.getAllGrouped.cancel(), - utils.workspaces.getActive.cancel(), ]); + // Snapshot previous values for rollback const previousGrouped = utils.workspaces.getAllGrouped.getData(); const previousAll = utils.workspaces.getAll.getData(); - const previousActive = utils.workspaces.getActive.getData(); + // Optimistically remove workspace from getAllGrouped cache if (previousGrouped) { utils.workspaces.getAllGrouped.setData( undefined, @@ -52,6 +54,7 @@ export function useDeleteWorkspace( ); } + // Optimistically remove workspace from getAll cache if (previousAll) { utils.workspaces.getAll.setData( undefined, @@ -59,83 +62,11 @@ export function useDeleteWorkspace( ); } - // Switch to next workspace to prevent "no workspace" flash - if (previousActive?.id === id) { - const remainingWorkspaces = previousAll - ?.filter((w) => w.id !== id) - .sort((a, b) => b.lastOpenedAt - a.lastOpenedAt); - - if (remainingWorkspaces && remainingWorkspaces.length > 0) { - // Find a workspace with full data available in previousGrouped - let selectedWorkspace = null; - let projectGroup = null; - let workspaceFromGrouped = null; - - for (const candidate of remainingWorkspaces) { - const group = previousGrouped?.find((g) => - g.workspaces.some((w) => w.id === candidate.id), - ); - if (group) { - selectedWorkspace = candidate; - projectGroup = group; - workspaceFromGrouped = group.workspaces.find( - (w) => w.id === candidate.id, - ); - break; - } - } - - if (selectedWorkspace && projectGroup && workspaceFromGrouped) { - const worktreeData = - workspaceFromGrouped.type === "worktree" - ? { - branch: selectedWorkspace.branch, - baseBranch: null, - gitStatus: { - branch: selectedWorkspace.branch, - needsRebase: false, - lastRefreshed: Date.now(), - }, - } - : null; - - utils.workspaces.getActive.setData(undefined, { - ...selectedWorkspace, - type: workspaceFromGrouped.type, - worktreePath: workspaceFromGrouped.worktreePath, - project: { - id: projectGroup.project.id, - name: projectGroup.project.name, - mainRepoPath: projectGroup.project.mainRepoPath, - }, - worktree: worktreeData, - }); - } else { - // Fallback: set minimal data to prevent StartView flash (refetch will populate full data) - const fallback = remainingWorkspaces[0]; - utils.workspaces.getActive.setData(undefined, { - ...fallback, - type: fallback.type === "branch" ? "branch" : "worktree", - worktreePath: "", - project: null, - worktree: null, - }); - } - } else { - utils.workspaces.getActive.setData(undefined, null); - } - } - - return { previousGrouped, previousAll, previousActive } as DeleteContext; + // Return context for rollback + return { previousGrouped, previousAll } as DeleteContext; }, - onSettled: async (...args) => { - await utils.workspaces.invalidate(); - await options?.onSettled?.(...args); - }, - onSuccess: async (...args) => { - await options?.onSuccess?.(...args); - }, - onError: async (_err, _variables, context, ...rest) => { + onError: (_err, _variables, context) => { + // Rollback to previous state on error if (context?.previousGrouped !== undefined) { utils.workspaces.getAllGrouped.setData( undefined, @@ -145,11 +76,36 @@ export function useDeleteWorkspace( if (context?.previousAll !== undefined) { utils.workspaces.getAll.setData(undefined, context.previousAll); } - if (context?.previousActive !== undefined) { - utils.workspaces.getActive.setData(undefined, context.previousActive); + }, + onSuccess: async (data, variables, ...rest) => { + // Invalidate to ensure consistency with backend state + await utils.workspaces.invalidate(); + // Invalidate project queries since delete updates project metadata + await utils.projects.getRecents.invalidate(); + + // If the deleted workspace is currently being viewed, navigate away + if (params.workspaceId === variables.id) { + // Try to navigate to previous workspace first, then next + const prevWorkspaceId = + await utils.workspaces.getPreviousWorkspace.fetch({ + id: variables.id, + }); + const nextWorkspaceId = await utils.workspaces.getNextWorkspace.fetch({ + id: variables.id, + }); + + const targetWorkspaceId = prevWorkspaceId ?? nextWorkspaceId; + + if (targetWorkspaceId) { + navigateToWorkspace(targetWorkspaceId, navigate); + } else { + // No other workspaces, navigate to workspace index (shows StartView) + navigate({ to: "/workspace" }); + } } - await options?.onError?.(_err, _variables, context, ...rest); + // Call user's onSuccess if provided + await options?.onSuccess?.(data, variables, ...rest); }, }); } diff --git a/apps/desktop/src/renderer/react-query/workspaces/useSetActiveWorkspace.ts b/apps/desktop/src/renderer/react-query/workspaces/useSetActiveWorkspace.ts deleted file mode 100644 index 02b8cd758..000000000 --- a/apps/desktop/src/renderer/react-query/workspaces/useSetActiveWorkspace.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { toast } from "@superset/ui/sonner"; -import { electronTrpc } from "renderer/lib/electron-trpc"; - -/** - * Mutation hook for setting the active workspace - * Automatically invalidates getActive and getAll queries on success - * Shows undo toast if workspace was marked as unread (auto-cleared on switch) - */ -export function useSetActiveWorkspace( - options?: Parameters[0], -) { - const utils = electronTrpc.useUtils(); - const setUnread = electronTrpc.workspaces.setUnread.useMutation({ - onSuccess: () => { - utils.workspaces.getAllGrouped.invalidate(); - }, - onError: (error) => { - console.error("[workspace/setUnread] Failed to update unread status:", { - error: error.message, - }); - toast.error(`Failed to undo: ${error.message}`); - }, - }); - - return electronTrpc.workspaces.setActive.useMutation({ - ...options, - onError: (error, variables, context, meta) => { - console.error("[workspace/setActive] Failed to set active workspace:", { - workspaceId: variables.id, - error: error.message, - }); - toast.error(`Failed to switch workspace: ${error.message}`); - options?.onError?.(error, variables, context, meta); - }, - onSuccess: async (data, variables, ...rest) => { - // Auto-invalidate active workspace and all workspaces queries - await Promise.all([ - utils.workspaces.getActive.invalidate(), - utils.workspaces.getAll.invalidate(), - utils.workspaces.getAllGrouped.invalidate(), - ]); - - // Show undo toast if workspace was marked as unread - if (data.wasUnread) { - toast("Marked as read", { - description: "Workspace unread marker cleared", - action: { - label: "Undo", - onClick: () => { - setUnread.mutate({ id: variables.id, isUnread: true }); - }, - }, - duration: 5000, - }); - } - - // Call user's onSuccess if provided - // biome-ignore lint/suspicious/noExplicitAny: spread args for compatibility - await (options?.onSuccess as any)?.(data, variables, ...rest); - }, - }); -} diff --git a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/$workspaceId/page.tsx b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/$workspaceId/page.tsx index ca7109f1d..39e79ff3b 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/$workspaceId/page.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/$workspaceId/page.tsx @@ -1,6 +1,6 @@ import { createFileRoute, notFound, useNavigate } from "@tanstack/react-router"; import { useCallback, useMemo } from "react"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { electronTrpcClient as trpcClient } from "renderer/lib/trpc-client"; import { navigateToWorkspace } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; import { NotFound } from "renderer/routes/not-found"; @@ -53,7 +53,7 @@ export const Route = createFileRoute( function WorkspacePage() { const { workspaceId } = Route.useParams(); - const { data: workspace } = trpc.workspaces.get.useQuery({ id: workspaceId }); + const { data: workspace } = electronTrpc.workspaces.get.useQuery({ id: workspaceId }); const navigate = useNavigate(); // Check if workspace is initializing or failed @@ -173,8 +173,8 @@ function WorkspacePage() { // Open in last used app shortcut const { data: lastUsedApp = "cursor" } = - trpc.settings.getLastUsedApp.useQuery(); - const openInApp = trpc.external.openInApp.useMutation(); + electronTrpc.settings.getLastUsedApp.useQuery(); + const openInApp = electronTrpc.external.openInApp.useMutation(); useAppHotkey( "OPEN_IN_APP", () => { @@ -190,7 +190,7 @@ function WorkspacePage() { ); // Copy path shortcut - const copyPath = trpc.external.copyPath.useMutation(); + const copyPath = electronTrpc.external.copyPath.useMutation(); useAppHotkey( "COPY_PATH", () => { @@ -289,7 +289,7 @@ function WorkspacePage() { ); // Navigate to previous workspace (⌘↑) - const getPreviousWorkspace = trpc.workspaces.getPreviousWorkspace.useQuery( + const getPreviousWorkspace = electronTrpc.workspaces.getPreviousWorkspace.useQuery( { id: workspaceId }, { enabled: !!workspaceId }, ); @@ -306,7 +306,7 @@ function WorkspacePage() { ); // Navigate to next workspace (⌘↓) - const getNextWorkspace = trpc.workspaces.getNextWorkspace.useQuery( + const getNextWorkspace = electronTrpc.workspaces.getNextWorkspace.useQuery( { id: workspaceId }, { enabled: !!workspaceId }, ); diff --git a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/page.tsx b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/page.tsx index 64955567a..506a4727d 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/page.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/page.tsx @@ -1,6 +1,6 @@ import { createFileRoute, useNavigate } from "@tanstack/react-router"; import { useEffect } from "react"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { StartView } from "renderer/screens/main/components/StartView"; export const Route = createFileRoute("/_authenticated/_dashboard/workspace/")({ @@ -18,7 +18,7 @@ function LoadingSpinner() { function WorkspaceIndexPage() { const navigate = useNavigate(); const { data: workspaces, isLoading } = - trpc.workspaces.getAllGrouped.useQuery(); + electronTrpc.workspaces.getAllGrouped.useQuery(); const allWorkspaces = workspaces?.flatMap((group) => group.workspaces) ?? []; const hasNoWorkspaces = !isLoading && allWorkspaces.length === 0; diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/account/page.tsx b/apps/desktop/src/renderer/routes/_authenticated/settings/account/page.tsx index bd8052cff..ee9db36bd 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/settings/account/page.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/account/page.tsx @@ -1,17 +1,18 @@ +import { authClient } from "@superset/auth/client"; import { Avatar } from "@superset/ui/atoms/Avatar"; import { Button } from "@superset/ui/button"; import { Skeleton } from "@superset/ui/skeleton"; import { toast } from "@superset/ui/sonner"; import { createFileRoute } from "@tanstack/react-router"; import { electronTrpc } from "renderer/lib/electron-trpc"; -import { trpc } from "renderer/lib/trpc"; export const Route = createFileRoute("/_authenticated/settings/account/")({ component: AccountSettingsPage, }); function AccountSettingsPage() { - const { data: user, isLoading } = trpc.user.me.useQuery(); + const { data: session, isPending: isLoading } = authClient.useSession(); + const user = session?.user; const signOutMutation = electronTrpc.auth.signOut.useMutation({ onSuccess: () => toast.success("Signed out"), }); diff --git a/apps/desktop/src/renderer/screens/main/components/SidebarControl/SidebarControl.tsx b/apps/desktop/src/renderer/screens/main/components/SidebarControl/SidebarControl.tsx index bad10df45..b8ec3a5d4 100644 --- a/apps/desktop/src/renderer/screens/main/components/SidebarControl/SidebarControl.tsx +++ b/apps/desktop/src/renderer/screens/main/components/SidebarControl/SidebarControl.tsx @@ -5,7 +5,7 @@ import { useParams } from "@tanstack/react-router"; import { useCallback } from "react"; import { LuGitCompareArrows } from "react-icons/lu"; import { HotkeyTooltipContent } from "renderer/components/HotkeyTooltipContent"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useSidebarStore } from "renderer/stores"; import { useChangesStore } from "renderer/stores/changes"; import { useTabsStore } from "renderer/stores/tabs/store"; @@ -27,7 +27,7 @@ export function SidebarControl() { // Get active workspace for file opening const { workspaceId } = useParams({ strict: false }); - const { data: workspace } = trpc.workspaces.get.useQuery( + const { data: workspace } = electronTrpc.workspaces.get.useQuery( { id: workspaceId ?? "" }, { enabled: !!workspaceId }, ); @@ -35,21 +35,21 @@ export function SidebarControl() { // Get base branch for changes query const { baseBranch, selectFile } = useChangesStore(); - const { data: branchData } = trpc.changes.getBranches.useQuery( + const { data: branchData } = electronTrpc.changes.getBranches.useQuery( { worktreePath: worktreePath || "" }, { enabled: !!worktreePath && !isSidebarOpen }, ); const effectiveBaseBranch = baseBranch ?? branchData?.defaultBranch ?? "main"; // Get changes status - only query when sidebar is closed (we need it to open first file) - const { data: status } = trpc.changes.getStatus.useQuery( + const { data: status } = electronTrpc.changes.getStatus.useQuery( { worktreePath: worktreePath || "", defaultBranch: effectiveBaseBranch }, { enabled: !!worktreePath && !isSidebarOpen }, ); // Access tabs store for file opening const addFileViewerPane = useTabsStore((s) => s.addFileViewerPane); - const trpcUtils = trpc.useUtils(); + const trpcUtils = electronTrpc.useUtils(); const invalidateFileContent = useCallback( (filePath: string) => { diff --git a/apps/desktop/src/renderer/screens/main/components/StartView/CloneRepoDialog.tsx b/apps/desktop/src/renderer/screens/main/components/StartView/CloneRepoDialog.tsx index 2c0deffab..2babbe0ca 100644 --- a/apps/desktop/src/renderer/screens/main/components/StartView/CloneRepoDialog.tsx +++ b/apps/desktop/src/renderer/screens/main/components/StartView/CloneRepoDialog.tsx @@ -1,5 +1,5 @@ import { useState } from "react"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useCreateWorkspace } from "renderer/react-query/workspaces"; interface CloneRepoDialogProps { @@ -14,8 +14,8 @@ export function CloneRepoDialog({ onError, }: CloneRepoDialogProps) { const [url, setUrl] = useState(""); - const utils = trpc.useUtils(); - const cloneRepo = trpc.projects.cloneRepo.useMutation(); + const utils = electronTrpc.useUtils(); + const cloneRepo = electronTrpc.projects.cloneRepo.useMutation(); const createWorkspace = useCreateWorkspace(); const handleClone = async () => { diff --git a/apps/desktop/src/renderer/screens/main/components/StartView/InitGitDialog.tsx b/apps/desktop/src/renderer/screens/main/components/StartView/InitGitDialog.tsx index 0a9688fcf..8052610a5 100644 --- a/apps/desktop/src/renderer/screens/main/components/StartView/InitGitDialog.tsx +++ b/apps/desktop/src/renderer/screens/main/components/StartView/InitGitDialog.tsx @@ -1,6 +1,6 @@ import { Button } from "@superset/ui/button"; import { useCallback, useEffect, useId, useRef, useState } from "react"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useCreateWorkspace } from "renderer/react-query/workspaces"; function getBasename(path: string): string { @@ -30,8 +30,8 @@ export function InitGitDialog({ onClose, onError, }: InitGitDialogProps) { - const utils = trpc.useUtils(); - const initGitAndOpen = trpc.projects.initGitAndOpen.useMutation(); + const utils = electronTrpc.useUtils(); + const initGitAndOpen = electronTrpc.projects.initGitAndOpen.useMutation(); const createWorkspace = useCreateWorkspace(); // Track the entire async sequence to keep modal locked diff --git a/apps/desktop/src/renderer/screens/main/components/StartView/StartTopBar.tsx b/apps/desktop/src/renderer/screens/main/components/StartView/StartTopBar.tsx index d652ff67b..fbd328895 100644 --- a/apps/desktop/src/renderer/screens/main/components/StartView/StartTopBar.tsx +++ b/apps/desktop/src/renderer/screens/main/components/StartView/StartTopBar.tsx @@ -1,9 +1,9 @@ -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { SettingsButton } from "../SettingsButton"; import { WindowControls } from "../TopBar/WindowControls"; export function StartTopBar() { - const { data: platform, isLoading } = trpc.window.getPlatform.useQuery(); + const { data: platform, isLoading } = electronTrpc.window.getPlatform.useQuery(); const isMac = !isLoading && platform === "darwin"; const showWindowControls = !isLoading && !isMac; diff --git a/apps/desktop/src/renderer/screens/main/components/StartView/index.tsx b/apps/desktop/src/renderer/screens/main/components/StartView/index.tsx index 8f72eed14..6ea9bdeb6 100644 --- a/apps/desktop/src/renderer/screens/main/components/StartView/index.tsx +++ b/apps/desktop/src/renderer/screens/main/components/StartView/index.tsx @@ -3,7 +3,7 @@ import { useState } from "react"; import { HiExclamationTriangle } from "react-icons/hi2"; import { LuChevronUp, LuFolderGit, LuFolderOpen, LuX } from "react-icons/lu"; import { formatPathWithProject } from "renderer/lib/formatPath"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useOpenNew } from "renderer/react-query/projects"; import { useCreateBranchWorkspace } from "renderer/react-query/workspaces"; import { ActionCard } from "./ActionCard"; @@ -12,8 +12,8 @@ import { InitGitDialog } from "./InitGitDialog"; import { StartTopBar } from "./StartTopBar"; export function StartView() { - const { data: recentProjects = [] } = trpc.projects.getRecents.useQuery(); - const { data: homeDir } = trpc.window.getHomeDir.useQuery(); + const { data: recentProjects = [] } = electronTrpc.projects.getRecents.useQuery(); + const { data: homeDir } = electronTrpc.window.getHomeDir.useQuery(); const openNew = useOpenNew(); const createBranchWorkspace = useCreateBranchWorkspace(); const [error, setError] = useState(null); diff --git a/apps/desktop/src/renderer/screens/main/components/TopBar/OpenInMenuButton.tsx b/apps/desktop/src/renderer/screens/main/components/TopBar/OpenInMenuButton.tsx index 698e7d366..e152554b3 100644 --- a/apps/desktop/src/renderer/screens/main/components/TopBar/OpenInMenuButton.tsx +++ b/apps/desktop/src/renderer/screens/main/components/TopBar/OpenInMenuButton.tsx @@ -24,7 +24,7 @@ import { JETBRAINS_OPTIONS, VSCODE_OPTIONS, } from "renderer/components/OpenInButton"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useHotkeyText } from "renderer/stores/hotkeys"; interface OpenInMenuButtonProps { @@ -36,16 +36,16 @@ export const OpenInMenuButton = memo(function OpenInMenuButton({ worktreePath, branch, }: OpenInMenuButtonProps) { - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); const { data: lastUsedApp = "cursor" } = - trpc.settings.getLastUsedApp.useQuery(undefined, { + electronTrpc.settings.getLastUsedApp.useQuery(undefined, { staleTime: 30000, }); - const openInApp = trpc.external.openInApp.useMutation({ + const openInApp = electronTrpc.external.openInApp.useMutation({ onSuccess: () => utils.settings.getLastUsedApp.invalidate(), onError: (error) => toast.error(`Failed to open: ${error.message}`), }); - const copyPath = trpc.external.copyPath.useMutation({ + const copyPath = electronTrpc.external.copyPath.useMutation({ onSuccess: () => toast.success("Path copied to clipboard"), onError: (error) => toast.error(`Failed to copy path: ${error.message}`), }); diff --git a/apps/desktop/src/renderer/screens/main/components/TopBar/WindowControls.tsx b/apps/desktop/src/renderer/screens/main/components/TopBar/WindowControls.tsx index 272bdd77a..a7f0a36fb 100644 --- a/apps/desktop/src/renderer/screens/main/components/TopBar/WindowControls.tsx +++ b/apps/desktop/src/renderer/screens/main/components/TopBar/WindowControls.tsx @@ -1,10 +1,10 @@ import { HiMiniMinus, HiMiniStop, HiMiniXMark } from "react-icons/hi2"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; export function WindowControls() { - const minimizeMutation = trpc.window.minimize.useMutation(); - const maximizeMutation = trpc.window.maximize.useMutation(); - const closeMutation = trpc.window.close.useMutation(); + const minimizeMutation = electronTrpc.window.minimize.useMutation(); + const maximizeMutation = electronTrpc.window.maximize.useMutation(); + const closeMutation = electronTrpc.window.close.useMutation(); const handleMinimize = () => { minimizeMutation.mutate(); diff --git a/apps/desktop/src/renderer/screens/main/components/TopBar/index.tsx b/apps/desktop/src/renderer/screens/main/components/TopBar/index.tsx index 1e8e24ddc..2cadd9827 100644 --- a/apps/desktop/src/renderer/screens/main/components/TopBar/index.tsx +++ b/apps/desktop/src/renderer/screens/main/components/TopBar/index.tsx @@ -1,13 +1,13 @@ import { useParams } from "@tanstack/react-router"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { OpenInMenuButton } from "./OpenInMenuButton"; import { SupportMenu } from "./SupportMenu"; import { WindowControls } from "./WindowControls"; export function TopBar() { - const { data: platform } = trpc.window.getPlatform.useQuery(); + const { data: platform } = electronTrpc.window.getPlatform.useQuery(); const { workspaceId } = useParams({ strict: false }); - const { data: workspace } = trpc.workspaces.get.useQuery( + const { data: workspace } = electronTrpc.workspaces.get.useQuery( { id: workspaceId ?? "" }, { enabled: !!workspaceId }, ); diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceInitEffects.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceInitEffects.tsx index 3cce23d23..da1620f8d 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceInitEffects.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceInitEffects.tsx @@ -1,6 +1,6 @@ import { toast } from "@superset/ui/sonner"; import { useCallback, useEffect, useRef } from "react"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useOpenConfigModal } from "renderer/stores/config-modal"; import { useTabsStore } from "renderer/stores/tabs/store"; import { @@ -35,10 +35,10 @@ export function WorkspaceInitEffects() { const addTab = useTabsStore((state) => state.addTab); const setTabAutoTitle = useTabsStore((state) => state.setTabAutoTitle); - const createOrAttach = trpc.terminal.createOrAttach.useMutation(); + const createOrAttach = electronTrpc.terminal.createOrAttach.useMutation(); const openConfigModal = useOpenConfigModal(); - const dismissConfigToast = trpc.config.dismissConfigToast.useMutation(); - const utils = trpc.useUtils(); + const dismissConfigToast = electronTrpc.config.dismissConfigToast.useMutation(); + const utils = electronTrpc.useUtils(); // Helper to create terminal with setup commands const handleTerminalSetup = useCallback( diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/PortsList/hooks/usePortsData.ts b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/PortsList/hooks/usePortsData.ts index f87e17c03..d21f69d36 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/PortsList/hooks/usePortsData.ts +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/PortsList/hooks/usePortsData.ts @@ -1,6 +1,6 @@ import { toast } from "@superset/ui/sonner"; import { useEffect, useMemo, useRef } from "react"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { usePortsStore } from "renderer/stores"; import type { MergedPort } from "shared/types"; import { mergePorts } from "../utils"; @@ -12,18 +12,18 @@ export interface MergedWorkspaceGroup { } export function usePortsData() { - const { data: allWorkspaces } = trpc.workspaces.getAll.useQuery(); + const { data: allWorkspaces } = electronTrpc.workspaces.getAll.useQuery(); const ports = usePortsStore((s) => s.ports); const setPorts = usePortsStore((s) => s.setPorts); const addPort = usePortsStore((s) => s.addPort); const removePort = usePortsStore((s) => s.removePort); - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); - const { data: allStaticPortsData } = trpc.ports.getAllStatic.useQuery(); + const { data: allStaticPortsData } = electronTrpc.ports.getAllStatic.useQuery(); // Subscribe to all static port changes - trpc.ports.subscribeStatic.useSubscription( + electronTrpc.ports.subscribeStatic.useSubscription( { workspaceId: "" }, { onData: () => { @@ -32,7 +32,7 @@ export function usePortsData() { }, ); - const { data: initialPorts } = trpc.ports.getAll.useQuery(); + const { data: initialPorts } = electronTrpc.ports.getAll.useQuery(); useEffect(() => { if (initialPorts) { @@ -40,7 +40,7 @@ export function usePortsData() { } }, [initialPorts, setPorts]); - trpc.ports.subscribe.useSubscription(undefined, { + electronTrpc.ports.subscribe.useSubscription(undefined, { onData: (event) => { if (event.type === "add") { addPort(event.port); diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/ProjectSection/ProjectHeader.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/ProjectSection/ProjectHeader.tsx index 27f8e850a..16d34c523 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/ProjectSection/ProjectHeader.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/ProjectSection/ProjectHeader.tsx @@ -15,7 +15,7 @@ import { useNavigate, useParams } from "@tanstack/react-router"; import { useState } from "react"; import { HiChevronRight, HiMiniPlus } from "react-icons/hi2"; import { LuFolderOpen, LuPalette, LuSettings, LuX } from "react-icons/lu"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useUpdateProject } from "renderer/react-query/projects/useUpdateProject"; import { navigateToWorkspace } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; import { @@ -53,12 +53,12 @@ export function ProjectHeader({ workspaceCount, onNewWorkspace, }: ProjectHeaderProps) { - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); const navigate = useNavigate(); const params = useParams({ strict: false }) as { workspaceId?: string }; const [isCloseDialogOpen, setIsCloseDialogOpen] = useState(false); - const closeProject = trpc.projects.close.useMutation({ + const closeProject = electronTrpc.projects.close.useMutation({ onMutate: async ({ id }) => { // Check if we're viewing a workspace from this project BEFORE closing let shouldNavigate = false; @@ -105,7 +105,7 @@ export function ProjectHeader({ }, }); - const openInFinder = trpc.external.openInFinder.useMutation({ + const openInFinder = electronTrpc.external.openInFinder.useMutation({ onError: (error) => toast.error(`Failed to open: ${error.message}`), }); diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/ProjectSection/ProjectThumbnail/ProjectThumbnail.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/ProjectSection/ProjectThumbnail/ProjectThumbnail.tsx index af7a94231..9dcc8f2b3 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/ProjectSection/ProjectThumbnail/ProjectThumbnail.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/ProjectSection/ProjectThumbnail/ProjectThumbnail.tsx @@ -1,6 +1,6 @@ import { cn } from "@superset/ui/utils"; import { useState } from "react"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { PROJECT_COLOR_DEFAULT } from "shared/constants/project-colors"; interface ProjectThumbnailProps { @@ -41,7 +41,7 @@ export function ProjectThumbnail({ }: ProjectThumbnailProps) { const [imageError, setImageError] = useState(false); - const { data: avatarData } = trpc.projects.getGitHubAvatar.useQuery( + const { data: avatarData } = electronTrpc.projects.getGitHubAvatar.useQuery( { id: projectId }, { staleTime: 1000 * 60 * 5, diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx index c593b2bc6..ce411518f 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx @@ -20,7 +20,7 @@ import { useMemo, useState } from "react"; import { useDrag, useDrop } from "react-dnd"; import { HiMiniXMark } from "react-icons/hi2"; import { LuEye, LuEyeOff, LuFolder, LuFolderGit2 } from "react-icons/lu"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useReorderWorkspaces, useWorkspaceDeleteHandler, @@ -86,17 +86,17 @@ export function WorkspaceListItem({ const clearWorkspaceAttentionStatus = useTabsStore( (s) => s.clearWorkspaceAttentionStatus, ); - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); // Derive isActive from route const isActive = !!matchRoute({ to: "/workspace/$workspaceId", params: { workspaceId: id }, }); - const openInFinder = trpc.external.openInFinder.useMutation({ + const openInFinder = electronTrpc.external.openInFinder.useMutation({ onError: (error) => toast.error(`Failed to open: ${error.message}`), }); - const setUnread = trpc.workspaces.setUnread.useMutation({ + const setUnread = electronTrpc.workspaces.setUnread.useMutation({ onSuccess: () => { utils.workspaces.getAllGrouped.invalidate(); }, @@ -109,7 +109,7 @@ export function WorkspaceListItem({ useWorkspaceDeleteHandler(); // Lazy-load GitHub status on hover to avoid N+1 queries - const { data: githubStatus } = trpc.workspaces.getGitHubStatus.useQuery( + const { data: githubStatus } = electronTrpc.workspaces.getGitHubStatus.useQuery( { workspaceId: id }, { enabled: hasHovered && type === "worktree", diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/BranchSwitcher/BranchSwitcher.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/BranchSwitcher/BranchSwitcher.tsx index a8848c8cd..22b7d877f 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/BranchSwitcher/BranchSwitcher.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/BranchSwitcher/BranchSwitcher.tsx @@ -12,7 +12,7 @@ import { useNavigate } from "@tanstack/react-router"; import { useMemo, useState } from "react"; import { HiCheck, HiChevronUpDown } from "react-icons/hi2"; import { LuGitBranch, LuGitFork, LuLoader } from "react-icons/lu"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { navigateToWorkspace } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; import { STROKE_WIDTH } from "../../../constants"; @@ -30,17 +30,17 @@ export function BranchSwitcher({ const [isOpen, setIsOpen] = useState(false); const [search, setSearch] = useState(""); - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); const navigate = useNavigate(); // Fetch branches when dropdown opens const { data: branchesData, isLoading } = - trpc.workspaces.getBranches.useQuery( + electronTrpc.workspaces.getBranches.useQuery( { projectId, fetch: false }, { enabled: isOpen }, ); - const switchBranch = trpc.workspaces.switchBranchWorkspace.useMutation({ + const switchBranch = electronTrpc.workspaces.switchBranchWorkspace.useMutation({ onSuccess: () => { utils.workspaces.invalidate(); }, diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/DeleteWorkspaceDialog/DeleteWorkspaceDialog.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/DeleteWorkspaceDialog/DeleteWorkspaceDialog.tsx index dd36f6cad..03920c103 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/DeleteWorkspaceDialog/DeleteWorkspaceDialog.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/DeleteWorkspaceDialog/DeleteWorkspaceDialog.tsx @@ -9,7 +9,7 @@ import { import { Button } from "@superset/ui/button"; import { toast } from "@superset/ui/sonner"; import { Tooltip, TooltipContent, TooltipTrigger } from "@superset/ui/tooltip"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useCloseWorkspace, useDeleteWorkspace, @@ -35,7 +35,7 @@ export function DeleteWorkspaceDialog({ const closeWorkspace = useCloseWorkspace(); const { data: gitStatusData, isLoading: isLoadingGitStatus } = - trpc.workspaces.canDelete.useQuery( + electronTrpc.workspaces.canDelete.useQuery( { id: workspaceId }, { enabled: open, @@ -43,7 +43,7 @@ export function DeleteWorkspaceDialog({ }, ); - const { data: terminalCountData } = trpc.workspaces.canDelete.useQuery( + const { data: terminalCountData } = electronTrpc.workspaces.canDelete.useQuery( { id: workspaceId, skipGitChecks: true }, { enabled: open, diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/WorkspaceHoverCard/WorkspaceHoverCard.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/WorkspaceHoverCard/WorkspaceHoverCard.tsx index 2e80d967e..304ec4a05 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/WorkspaceHoverCard/WorkspaceHoverCard.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/WorkspaceHoverCard/WorkspaceHoverCard.tsx @@ -6,7 +6,7 @@ import { LuLoaderCircle, LuTriangleAlert, } from "react-icons/lu"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { usePRStatus } from "renderer/screens/main/hooks"; import { STROKE_WIDTH } from "../../../constants"; import { ChecksList } from "./components/ChecksList"; @@ -23,7 +23,7 @@ export function WorkspaceHoverCardContent({ workspaceId, workspaceAlias, }: WorkspaceHoverCardContentProps) { - const { data: worktreeInfo } = trpc.workspaces.getWorktreeInfo.useQuery( + const { data: worktreeInfo } = electronTrpc.workspaces.getWorktreeInfo.useQuery( { workspaceId }, { enabled: !!workspaceId }, ); diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceSidebarHeader/NewWorkspaceButton.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceSidebarHeader/NewWorkspaceButton.tsx index adefae76c..2e3b77fe3 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceSidebarHeader/NewWorkspaceButton.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceSidebarHeader/NewWorkspaceButton.tsx @@ -1,7 +1,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "@superset/ui/tooltip"; import { useMatchRoute } from "@tanstack/react-router"; import { LuPlus } from "react-icons/lu"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useOpenNewWorkspaceModal } from "renderer/stores/new-workspace-modal"; import { STROKE_WIDTH_THICK } from "../constants"; @@ -24,7 +24,7 @@ export function NewWorkspaceButton({ ? currentWorkspaceMatch.workspaceId : null; - const { data: currentWorkspace } = trpc.workspaces.get.useQuery( + const { data: currentWorkspace } = electronTrpc.workspaces.get.useQuery( { id: currentWorkspaceId ?? "" }, { enabled: !!currentWorkspaceId }, ); diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/hooks/useFileContent/useFileContent.ts b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/hooks/useFileContent/useFileContent.ts index 2c4bbd68f..0eca02940 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/hooks/useFileContent/useFileContent.ts +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/hooks/useFileContent/useFileContent.ts @@ -1,5 +1,5 @@ import { useEffect } from "react"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import type { ChangeCategory } from "shared/changes-types"; interface UseFileContentParams { @@ -25,14 +25,14 @@ export function useFileContent({ originalContentRef, originalDiffContentRef, }: UseFileContentParams) { - const { data: branchData } = trpc.changes.getBranches.useQuery( + const { data: branchData } = electronTrpc.changes.getBranches.useQuery( { worktreePath }, { enabled: !!worktreePath && diffCategory === "against-base" }, ); const effectiveBaseBranch = branchData?.defaultBranch ?? "main"; const { data: rawFileData, isLoading: isLoadingRaw } = - trpc.changes.readWorkingFile.useQuery( + electronTrpc.changes.readWorkingFile.useQuery( { worktreePath, filePath }, { enabled: viewMode !== "diff" && !!filePath && !!worktreePath, @@ -40,7 +40,7 @@ export function useFileContent({ ); const { data: diffData, isLoading: isLoadingDiff } = - trpc.changes.getFileContents.useQuery( + electronTrpc.changes.getFileContents.useQuery( { worktreePath, filePath, diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/hooks/useFileSave/useFileSave.ts b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/hooks/useFileSave/useFileSave.ts index 074553ac2..247326417 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/hooks/useFileSave/useFileSave.ts +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/FileViewerPane/hooks/useFileSave/useFileSave.ts @@ -1,6 +1,6 @@ import type * as Monaco from "monaco-editor"; import { type MutableRefObject, useCallback, useRef } from "react"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useTabsStore } from "renderer/stores/tabs/store"; import type { ChangeCategory } from "shared/changes-types"; @@ -29,9 +29,9 @@ export function useFileSave({ }: UseFileSaveParams) { const savingFromRawRef = useRef(false); const savingDiffContentRef = useRef(null); - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); - const saveFileMutation = trpc.changes.saveFile.useMutation({ + const saveFileMutation = electronTrpc.changes.saveFile.useMutation({ onSuccess: () => { setIsDirty(false); if (editorRef.current) { diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/index.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/index.tsx index fcaabb67c..697b3bc09 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/index.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/TabView/index.tsx @@ -9,7 +9,7 @@ import { type MosaicNode, } from "react-mosaic-component"; import { dragDropManager } from "renderer/lib/dnd"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useTabsStore } from "renderer/stores/tabs/store"; import type { Tab } from "renderer/stores/tabs/types"; import { useTabsWithPresets } from "renderer/stores/tabs/useTabsWithPresets"; @@ -39,7 +39,7 @@ export function TabView({ tab }: TabViewProps) { // Get workspace path for file viewer panes const { workspaceId } = useParams({ strict: false }); - const { data: workspace } = trpc.workspaces.get.useQuery( + const { data: workspace } = electronTrpc.workspaces.get.useQuery( { id: workspaceId ?? "" }, { enabled: !!workspaceId }, ); diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/DirectoryNavigator/DirectoryNavigator.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/DirectoryNavigator/DirectoryNavigator.tsx index 8b492b38e..e7c08d017 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/DirectoryNavigator/DirectoryNavigator.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/DirectoryNavigator/DirectoryNavigator.tsx @@ -2,7 +2,7 @@ import { Popover, PopoverContent, PopoverTrigger } from "@superset/ui/popover"; import { Tooltip, TooltipContent, TooltipTrigger } from "@superset/ui/tooltip"; import { useCallback, useState } from "react"; import { HiChevronRight, HiFolder, HiFolderOpen } from "react-icons/hi2"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; interface DirectoryNavigatorProps { paneId: string; @@ -18,15 +18,15 @@ export function DirectoryNavigator({ const [isOpen, setIsOpen] = useState(false); const [browsePath, setBrowsePath] = useState(null); - const { data: homeDir } = trpc.window.getHomeDir.useQuery(); - const writeMutation = trpc.terminal.write.useMutation(); + const { data: homeDir } = electronTrpc.window.getHomeDir.useQuery(); + const writeMutation = electronTrpc.terminal.write.useMutation(); // Navigation enabled when we have any cwd (seeded or confirmed) const hasCwd = !!currentCwd; const displayPath = browsePath || currentCwd; const { data: directoryData, isLoading } = - trpc.terminal.listDirectory.useQuery( + electronTrpc.terminal.listDirectory.useQuery( { dirPath: displayPath || "/" }, { enabled: isOpen && hasCwd && !!displayPath }, ); diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx index 821413df8..466c99455 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx @@ -5,7 +5,7 @@ import type { Terminal as XTerm } from "@xterm/xterm"; import "@xterm/xterm/css/xterm.css"; import debounce from "lodash/debounce"; import { useCallback, useEffect, useRef, useState } from "react"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { electronTrpcClient as trpcClient } from "renderer/lib/trpc-client"; import { useAppHotkey } from "renderer/stores/hotkeys"; import { useTabsStore } from "renderer/stores/tabs/store"; @@ -75,11 +75,11 @@ export const Terminal = ({ tabId, workspaceId }: TerminalProps) => { clearPaneInitialDataRef.current = clearPaneInitialData; const { data: workspaceCwd } = - trpc.terminal.getWorkspaceCwd.useQuery(workspaceId); + electronTrpc.terminal.getWorkspaceCwd.useQuery(workspaceId); // Query terminal link behavior setting const { data: terminalLinkBehavior } = - trpc.settings.getTerminalLinkBehavior.useQuery(); + electronTrpc.settings.getTerminalLinkBehavior.useQuery(); // Handler for file link clicks - uses current setting value const handleFileLinkClick = useCallback( @@ -197,11 +197,11 @@ export const Terminal = ({ tabId, workspaceId }: TerminalProps) => { const updateCwdRef = useRef(updateCwdFromData); updateCwdRef.current = updateCwdFromData; - const createOrAttachMutation = trpc.terminal.createOrAttach.useMutation(); - const writeMutation = trpc.terminal.write.useMutation(); - const resizeMutation = trpc.terminal.resize.useMutation(); - const detachMutation = trpc.terminal.detach.useMutation(); - const clearScrollbackMutation = trpc.terminal.clearScrollback.useMutation(); + const createOrAttachMutation = electronTrpc.terminal.createOrAttach.useMutation(); + const writeMutation = electronTrpc.terminal.write.useMutation(); + const resizeMutation = electronTrpc.terminal.resize.useMutation(); + const detachMutation = electronTrpc.terminal.detach.useMutation(); + const clearScrollbackMutation = electronTrpc.terminal.clearScrollback.useMutation(); const createOrAttachRef = useRef(createOrAttachMutation.mutate); const writeRef = useRef(writeMutation.mutate); @@ -271,7 +271,7 @@ export const Terminal = ({ tabId, workspaceId }: TerminalProps) => { } }; - trpc.terminal.stream.useSubscription(paneId, { + electronTrpc.terminal.stream.useSubscription(paneId, { onData: handleStreamData, enabled: true, }); diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx index 482891153..d26f0fec0 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/components/EditorContextMenu/EditorContextMenu.tsx @@ -25,7 +25,7 @@ import { LuSearch, LuX, } from "react-icons/lu"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import type { Tab } from "renderer/stores/tabs/types"; export interface EditorActions { @@ -64,7 +64,7 @@ export function EditorContextMenu({ (t) => t.id !== paneActions.currentTabId, ); - const { data: platform } = trpc.window.getPlatform.useQuery(); + const { data: platform } = electronTrpc.window.getPlatform.useQuery(); const isMac = platform === "darwin"; const cmdKey = isMac ? "Cmd" : "Ctrl"; diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx index 567c683e2..8b15e4f35 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx @@ -4,7 +4,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "@superset/ui/tooltip"; import { useParams } from "@tanstack/react-router"; import { useEffect, useState } from "react"; import { HiMiniMinus, HiMiniPlus } from "react-icons/hi2"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useChangesStore } from "renderer/stores/changes"; import type { ChangeCategory, ChangedFile } from "shared/changes-types"; @@ -34,14 +34,14 @@ export function ChangesView({ onFileOpenPinned, }: ChangesViewProps) { const { workspaceId } = useParams({ strict: false }); - const { data: workspace } = trpc.workspaces.get.useQuery( + const { data: workspace } = electronTrpc.workspaces.get.useQuery( { id: workspaceId ?? "" }, { enabled: !!workspaceId }, ); const worktreePath = workspace?.worktreePath; const { baseBranch } = useChangesStore(); - const { data: branchData } = trpc.changes.getBranches.useQuery( + const { data: branchData } = electronTrpc.changes.getBranches.useQuery( { worktreePath: worktreePath || "" }, { enabled: !!worktreePath }, ); @@ -52,7 +52,7 @@ export function ChangesView({ data: status, isLoading, refetch, - } = trpc.changes.getStatus.useQuery( + } = electronTrpc.changes.getStatus.useQuery( { worktreePath: worktreePath || "", defaultBranch: effectiveBaseBranch }, { enabled: !!worktreePath, @@ -62,7 +62,7 @@ export function ChangesView({ ); const { data: githubStatus, refetch: refetchGithubStatus } = - trpc.workspaces.getGitHubStatus.useQuery( + electronTrpc.workspaces.getGitHubStatus.useQuery( { workspaceId: workspaceId ?? "" }, { enabled: !!workspaceId, @@ -75,7 +75,7 @@ export function ChangesView({ refetchGithubStatus(); }; - const stageAllMutation = trpc.changes.stageAll.useMutation({ + const stageAllMutation = electronTrpc.changes.stageAll.useMutation({ onSuccess: () => refetch(), onError: (error) => { console.error("Failed to stage all files:", error); @@ -83,7 +83,7 @@ export function ChangesView({ }, }); - const unstageAllMutation = trpc.changes.unstageAll.useMutation({ + const unstageAllMutation = electronTrpc.changes.unstageAll.useMutation({ onSuccess: () => refetch(), onError: (error) => { console.error("Failed to unstage all files:", error); @@ -91,7 +91,7 @@ export function ChangesView({ }, }); - const stageFileMutation = trpc.changes.stageFile.useMutation({ + const stageFileMutation = electronTrpc.changes.stageFile.useMutation({ onSuccess: () => refetch(), onError: (error, variables) => { console.error(`Failed to stage file ${variables.filePath}:`, error); @@ -99,7 +99,7 @@ export function ChangesView({ }, }); - const unstageFileMutation = trpc.changes.unstageFile.useMutation({ + const unstageFileMutation = electronTrpc.changes.unstageFile.useMutation({ onSuccess: () => refetch(), onError: (error, variables) => { console.error(`Failed to unstage file ${variables.filePath}:`, error); @@ -107,7 +107,7 @@ export function ChangesView({ }, }); - const discardChangesMutation = trpc.changes.discardChanges.useMutation({ + const discardChangesMutation = electronTrpc.changes.discardChanges.useMutation({ onSuccess: () => refetch(), onError: (error, variables) => { console.error( @@ -118,7 +118,7 @@ export function ChangesView({ }, }); - const deleteUntrackedMutation = trpc.changes.deleteUntracked.useMutation({ + const deleteUntrackedMutation = electronTrpc.changes.deleteUntracked.useMutation({ onSuccess: () => refetch(), onError: (error, variables) => { console.error(`Failed to delete ${variables.filePath}:`, error); @@ -165,7 +165,7 @@ export function ChangesView({ setExpandedCommits(new Set()); }, [worktreePath]); - const commitFilesQueries = trpc.useQueries((t) => + const commitFilesQueries = electronTrpc.useQueries((t) => Array.from(expandedCommits).map((hash) => t.changes.getCommitFiles({ worktreePath: worktreePath || "", diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/ChangesHeader/ChangesHeader.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/ChangesHeader/ChangesHeader.tsx index d29454f00..f703ce9ba 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/ChangesHeader/ChangesHeader.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/ChangesHeader/ChangesHeader.tsx @@ -10,7 +10,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "@superset/ui/tooltip"; import { useEffect, useRef, useState } from "react"; import { HiArrowPath } from "react-icons/hi2"; import { LuLoaderCircle } from "react-icons/lu"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { PRIcon } from "renderer/screens/main/components/PRIcon"; import { usePRStatus } from "renderer/screens/main/hooks"; import { useChangesStore } from "renderer/stores/changes"; @@ -60,7 +60,7 @@ export function ChangesHeader({ const { baseBranch, setBaseBranch } = useChangesStore(); - const { data: branchData, isLoading } = trpc.changes.getBranches.useQuery( + const { data: branchData, isLoading } = electronTrpc.changes.getBranches.useQuery( { worktreePath }, { enabled: !!worktreePath }, ); diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/CommitInput/CommitInput.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/CommitInput/CommitInput.tsx index 61deca284..5ffa60369 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/CommitInput/CommitInput.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/CommitInput/CommitInput.tsx @@ -19,7 +19,7 @@ import { HiCheck, HiChevronDown, } from "react-icons/hi2"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; interface CommitInputProps { worktreePath: string; @@ -47,7 +47,7 @@ export function CommitInput({ const [commitMessage, setCommitMessage] = useState(""); const [isOpen, setIsOpen] = useState(false); - const commitMutation = trpc.changes.commit.useMutation({ + const commitMutation = electronTrpc.changes.commit.useMutation({ onSuccess: () => { toast.success("Committed"); setCommitMessage(""); @@ -56,7 +56,7 @@ export function CommitInput({ onError: (error) => toast.error(`Commit failed: ${error.message}`), }); - const pushMutation = trpc.changes.push.useMutation({ + const pushMutation = electronTrpc.changes.push.useMutation({ onSuccess: () => { toast.success("Pushed"); onRefresh(); @@ -64,7 +64,7 @@ export function CommitInput({ onError: (error) => toast.error(`Push failed: ${error.message}`), }); - const pullMutation = trpc.changes.pull.useMutation({ + const pullMutation = electronTrpc.changes.pull.useMutation({ onSuccess: () => { toast.success("Pulled"); onRefresh(); @@ -72,7 +72,7 @@ export function CommitInput({ onError: (error) => toast.error(`Pull failed: ${error.message}`), }); - const syncMutation = trpc.changes.sync.useMutation({ + const syncMutation = electronTrpc.changes.sync.useMutation({ onSuccess: () => { toast.success("Synced"); onRefresh(); @@ -80,7 +80,7 @@ export function CommitInput({ onError: (error) => toast.error(`Sync failed: ${error.message}`), }); - const createPRMutation = trpc.changes.createPR.useMutation({ + const createPRMutation = electronTrpc.changes.createPR.useMutation({ onSuccess: () => { toast.success("Opening GitHub..."); onRefresh(); diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileItem/FileItem.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileItem/FileItem.tsx index 90dacb7dc..9e97de092 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileItem/FileItem.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileItem/FileItem.tsx @@ -27,7 +27,7 @@ import { LuTrash2, LuUndo2, } from "react-icons/lu"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import type { ChangedFile } from "shared/changes-types"; import { getStatusColor, getStatusIndicator } from "../../utils"; @@ -93,8 +93,8 @@ export function FileItem({ const hasIndent = level > 0; const hasAction = onStage || onUnstage; - const openInFinderMutation = trpc.external.openInFinder.useMutation(); - const openInEditorMutation = trpc.external.openFileInEditor.useMutation(); + const openInFinderMutation = electronTrpc.external.openInFinder.useMutation(); + const openInEditorMutation = electronTrpc.external.openFileInEditor.useMutation(); const absolutePath = worktreePath ? `${worktreePath}/${file.path}` : null; diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/index.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/index.tsx index 383f848f8..c55cda655 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/index.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/index.tsx @@ -1,19 +1,19 @@ import { useParams } from "@tanstack/react-router"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useTabsStore } from "renderer/stores/tabs/store"; import type { ChangeCategory, ChangedFile } from "shared/changes-types"; import { ChangesView } from "./ChangesView"; export function Sidebar() { const { workspaceId } = useParams({ strict: false }); - const { data: workspace } = trpc.workspaces.get.useQuery( + const { data: workspace } = electronTrpc.workspaces.get.useQuery( { id: workspaceId ?? "" }, { enabled: !!workspaceId }, ); const worktreePath = workspace?.worktreePath; const addFileViewerPane = useTabsStore((s) => s.addFileViewerPane); - const trpcUtils = trpc.useUtils(); + const trpcUtils = electronTrpc.useUtils(); // Invalidate file content queries to ensure fresh data when clicking a file const invalidateFileContent = (filePath: string) => { diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceInitializingView/WorkspaceInitializingView.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceInitializingView/WorkspaceInitializingView.tsx index 703d24edc..2e0a09aac 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceInitializingView/WorkspaceInitializingView.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceInitializingView/WorkspaceInitializingView.tsx @@ -11,7 +11,7 @@ import { cn } from "@superset/ui/utils"; import { useEffect, useState } from "react"; import { HiExclamationTriangle } from "react-icons/hi2"; import { LuCheck, LuCircle, LuGitBranch, LuLoader } from "react-icons/lu"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useHasWorkspaceFailed, useWorkspaceInitProgress, @@ -55,9 +55,9 @@ export function WorkspaceInitializingView({ setShowInterruptedUI(false); }, [isInterrupted, progress]); - const retryMutation = trpc.workspaces.retryInit.useMutation(); - const deleteMutation = trpc.workspaces.delete.useMutation(); - const utils = trpc.useUtils(); + const retryMutation = electronTrpc.workspaces.retryInit.useMutation(); + const deleteMutation = electronTrpc.workspaces.delete.useMutation(); + const utils = electronTrpc.useUtils(); const handleRetry = () => { retryMutation.mutate( diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspacesListView/WorkspaceRow/DeleteWorktreeDialog.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspacesListView/WorkspaceRow/DeleteWorktreeDialog.tsx index e25b2beef..d99554ecd 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspacesListView/WorkspaceRow/DeleteWorktreeDialog.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspacesListView/WorkspaceRow/DeleteWorktreeDialog.tsx @@ -9,7 +9,7 @@ import { import { Button } from "@superset/ui/button"; import { toast } from "@superset/ui/sonner"; import { Tooltip, TooltipContent, TooltipTrigger } from "@superset/ui/tooltip"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useDeleteWorktree } from "renderer/react-query/workspaces/useDeleteWorktree"; interface DeleteWorktreeDialogProps { @@ -28,7 +28,7 @@ export function DeleteWorktreeDialog({ const deleteWorktree = useDeleteWorktree(); const { data: canDeleteData, isLoading } = - trpc.workspaces.canDeleteWorktree.useQuery( + electronTrpc.workspaces.canDeleteWorktree.useQuery( { worktreeId }, { enabled: open, diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspacesListView/WorkspaceRow/WorkspaceRow.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspacesListView/WorkspaceRow/WorkspaceRow.tsx index a80c6fc22..0f8399526 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspacesListView/WorkspaceRow/WorkspaceRow.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspacesListView/WorkspaceRow/WorkspaceRow.tsx @@ -13,7 +13,7 @@ import { LuFolderGit2, LuRotateCw, } from "react-icons/lu"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useWorkspaceDeleteHandler } from "renderer/react-query/workspaces/useWorkspaceDeleteHandler"; import { STROKE_WIDTH } from "../../WorkspaceSidebar/constants"; import { DeleteWorkspaceDialog } from "../../WorkspaceSidebar/WorkspaceListItem/components/DeleteWorkspaceDialog/DeleteWorkspaceDialog"; @@ -42,7 +42,7 @@ export function WorkspaceRow({ useWorkspaceDeleteHandler(); // Lazy-load GitHub status on hover to avoid N+1 queries - const { data: githubStatus } = trpc.workspaces.getGitHubStatus.useQuery( + const { data: githubStatus } = electronTrpc.workspaces.getGitHubStatus.useQuery( { workspaceId: workspace.workspaceId ?? "" }, { enabled: diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspacesListView/WorkspacesListView.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspacesListView/WorkspacesListView.tsx index e3ee94c94..593238ccf 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspacesListView/WorkspacesListView.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspacesListView/WorkspacesListView.tsx @@ -5,7 +5,7 @@ import { cn } from "@superset/ui/utils"; import { useNavigate } from "@tanstack/react-router"; import { useMemo, useState } from "react"; import { LuSearch, LuX } from "react-icons/lu"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { navigateToWorkspace } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; import type { FilterMode, ProjectGroup, WorkspaceItem } from "./types"; import { WorkspaceRow } from "./WorkspaceRow"; @@ -20,20 +20,20 @@ export function WorkspacesListView() { const [searchQuery, setSearchQuery] = useState(""); const [filterMode, setFilterMode] = useState("all"); const navigate = useNavigate(); - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); // Fetch all data - const { data: groups = [] } = trpc.workspaces.getAllGrouped.useQuery(); - const { data: allProjects = [] } = trpc.projects.getRecents.useQuery(); + const { data: groups = [] } = electronTrpc.workspaces.getAllGrouped.useQuery(); + const { data: allProjects = [] } = electronTrpc.projects.getRecents.useQuery(); // Fetch worktrees for all projects - const worktreeQueries = trpc.useQueries((t) => + const worktreeQueries = electronTrpc.useQueries((t) => allProjects.map((project) => t.workspaces.getWorktreesByProject({ projectId: project.id }), ), ); - const openWorktree = trpc.workspaces.openWorktree.useMutation({ + const openWorktree = electronTrpc.workspaces.openWorktree.useMutation({ onSuccess: (data) => { utils.workspaces.getAllGrouped.invalidate(); // Navigate to the newly opened workspace diff --git a/apps/desktop/src/renderer/screens/main/hooks/usePRStatus/usePRStatus.ts b/apps/desktop/src/renderer/screens/main/hooks/usePRStatus/usePRStatus.ts index 713d7ff91..6e6ae9d9a 100644 --- a/apps/desktop/src/renderer/screens/main/hooks/usePRStatus/usePRStatus.ts +++ b/apps/desktop/src/renderer/screens/main/hooks/usePRStatus/usePRStatus.ts @@ -1,5 +1,5 @@ import type { GitHubStatus } from "@superset/local-db"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; interface UsePRStatusOptions { workspaceId: string | undefined; @@ -28,7 +28,7 @@ export function usePRStatus({ data: githubStatus, isLoading, refetch, - } = trpc.workspaces.getGitHubStatus.useQuery( + } = electronTrpc.workspaces.getGitHubStatus.useQuery( { workspaceId: workspaceId ?? "" }, { enabled: enabled && !!workspaceId, diff --git a/apps/desktop/src/renderer/stores/tabs/useAgentHookListener.ts b/apps/desktop/src/renderer/stores/tabs/useAgentHookListener.ts index 5fd87aa0f..befbca5bc 100644 --- a/apps/desktop/src/renderer/stores/tabs/useAgentHookListener.ts +++ b/apps/desktop/src/renderer/stores/tabs/useAgentHookListener.ts @@ -1,9 +1,9 @@ +import { useNavigate } from "@tanstack/react-router"; import { useRef } from "react"; import { electronTrpc } from "renderer/lib/electron-trpc"; -import { useSetActiveWorkspace } from "renderer/react-query/workspaces/useSetActiveWorkspace"; +import { navigateToWorkspace } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; import { NOTIFICATION_EVENTS } from "shared/constants"; import { debugLog } from "shared/debug"; -import { useAppStore } from "../app-state"; import { useTabsStore } from "./store"; import { resolveNotificationTarget } from "./utils/resolve-notification-target"; @@ -33,13 +33,21 @@ import { resolveNotificationTarget } from "./utils/resolve-notification-target"; * for clearing stuck indicators when agent hooks fail to fire. */ export function useAgentHookListener() { - const setActiveWorkspace = useSetActiveWorkspace(); - const { data: activeWorkspace } = - electronTrpc.workspaces.getActive.useQuery(); - - // Use ref to avoid stale closure in subscription callback - const activeWorkspaceRef = useRef(activeWorkspace); - activeWorkspaceRef.current = activeWorkspace; + const navigate = useNavigate(); + + // Track current workspace from router to avoid stale closure + const currentWorkspaceIdRef = useRef(null); + + // We need to update this ref from the workspace page, but for now + // we'll use router state. This is called from _authenticated/layout + // so we check the current route + try { + const location = window.location; + const match = location.pathname.match(/\/workspace\/([^/]+)/); + currentWorkspaceIdRef.current = match ? match[1] : null; + } catch { + currentWorkspaceIdRef.current = null; + } electronTrpc.notifications.subscribe.useSubscription(undefined, { onData: (event) => { @@ -56,7 +64,7 @@ export function useAgentHookListener() { eventType: event.data?.eventType, paneId, workspaceId, - activeWorkspace: activeWorkspaceRef.current?.id, + currentWorkspace: currentWorkspaceIdRef.current, }); if (!paneId) return; @@ -78,7 +86,7 @@ export function useAgentHookListener() { const focusedPaneId = activeTabId && state.focusedPaneIds[activeTabId]; const isAlreadyActive = - activeWorkspaceRef.current?.id === workspaceId && + currentWorkspaceIdRef.current === workspaceId && focusedPaneId === paneId; debugLog("agent-hooks", "Stop event:", { @@ -98,38 +106,25 @@ export function useAgentHookListener() { } } } else if (event.type === NOTIFICATION_EVENTS.FOCUS_TAB) { - const appState = useAppStore.getState(); - if (appState.currentView !== "workspace") { - appState.setView("workspace"); - } + // Navigate to the workspace and focus the tab/pane + navigateToWorkspace(workspaceId, navigate); + + // Set active tab and focused pane after navigation + // (router navigation is async, but state updates are immediate) + const freshState = useTabsStore.getState(); + const freshTarget = resolveNotificationTarget(event.data, freshState); + if (!freshTarget?.tabId) return; - setActiveWorkspace.mutate( - { id: workspaceId }, - { - onSuccess: () => { - const freshState = useTabsStore.getState(); - const freshTarget = resolveNotificationTarget( - event.data, - freshState, - ); - if (!freshTarget?.tabId) return; - - const freshTab = freshState.tabs.find( - (t) => t.id === freshTarget.tabId, - ); - if (!freshTab || freshTab.workspaceId !== workspaceId) return; - - freshState.setActiveTab(workspaceId, freshTarget.tabId); - - if (freshTarget.paneId && freshState.panes[freshTarget.paneId]) { - freshState.setFocusedPane( - freshTarget.tabId, - freshTarget.paneId, - ); - } - }, - }, + const freshTab = freshState.tabs.find( + (t) => t.id === freshTarget.tabId, ); + if (!freshTab || freshTab.workspaceId !== workspaceId) return; + + freshState.setActiveTab(workspaceId, freshTarget.tabId); + + if (freshTarget.paneId && freshState.panes[freshTarget.paneId]) { + freshState.setFocusedPane(freshTarget.tabId, freshTarget.paneId); + } } }, }); From 6de8c91392f25e320960cb915bcd15b20cf0a9aa Mon Sep 17 00:00:00 2001 From: Satya Patel Date: Wed, 14 Jan 2026 10:01:26 -0800 Subject: [PATCH 06/12] WIP --- .../src/lib/trpc/routers/auth/index.ts | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/apps/desktop/src/lib/trpc/routers/auth/index.ts b/apps/desktop/src/lib/trpc/routers/auth/index.ts index 04fc4798c..515fcc556 100644 --- a/apps/desktop/src/lib/trpc/routers/auth/index.ts +++ b/apps/desktop/src/lib/trpc/routers/auth/index.ts @@ -16,18 +16,10 @@ import { export const createAuthRouter = () => { return router({ - /** - * Get initial token from encrypted disk storage. - * Called once on app startup for hydration. - */ getStoredToken: publicProcedure.query(async () => { return await loadToken(); }), - /** - * Persist token to encrypted disk storage. - * Called when renderer saves token to localStorage. - */ persistToken: publicProcedure .input( z.object({ @@ -40,14 +32,8 @@ export const createAuthRouter = () => { return { success: true }; }), - /** - * Subscribe to token changes from deep link callbacks. - * CRITICAL: Notifies renderer when OAuth callback saves new token. - * Without this, renderer wouldn't know to update localStorage after OAuth. - */ onTokenChanged: publicProcedure.subscription(() => { return observable<{ token: string; expiresAt: string } | null>((emit) => { - // Emit initial token on subscription loadToken().then((initial) => { if (initial.token && initial.expiresAt) { emit.next({ token: initial.token, expiresAt: initial.expiresAt }); @@ -99,12 +85,7 @@ export const createAuthRouter = () => { } }), - /** - * Sign out - clears token from disk. - * Renderer should also clear localStorage and call authClient.signOut(). - */ signOut: publicProcedure.mutation(async () => { - console.log("[auth] Clearing token"); try { await fs.unlink(TOKEN_FILE); } catch {} From 692bccd3f73f499f82246854c4d39ab0766e7630 Mon Sep 17 00:00:00 2001 From: Satya Patel Date: Wed, 14 Jan 2026 10:14:13 -0800 Subject: [PATCH 07/12] WIP --- .../renderer/react-query/projects/useReorderProjects.ts | 8 ++++---- .../WorkspaceSidebar/ProjectSection/ProjectSection.tsx | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/desktop/src/renderer/react-query/projects/useReorderProjects.ts b/apps/desktop/src/renderer/react-query/projects/useReorderProjects.ts index 964d7947d..be95d9bbe 100644 --- a/apps/desktop/src/renderer/react-query/projects/useReorderProjects.ts +++ b/apps/desktop/src/renderer/react-query/projects/useReorderProjects.ts @@ -1,15 +1,15 @@ -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; /** * Mutation hook for reordering projects * Automatically invalidates workspace and project queries on success */ export function useReorderProjects( - options?: Parameters[0], + options?: Parameters[0], ) { - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); - return trpc.projects.reorder.useMutation({ + return electronTrpc.projects.reorder.useMutation({ ...options, onSuccess: async (...args) => { await utils.workspaces.getAllGrouped.invalidate(); diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/ProjectSection/ProjectSection.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/ProjectSection/ProjectSection.tsx index f2749bdad..3a28eac2a 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/ProjectSection/ProjectSection.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/ProjectSection/ProjectSection.tsx @@ -2,7 +2,7 @@ import { toast } from "@superset/ui/sonner"; import { cn } from "@superset/ui/utils"; import { AnimatePresence, motion } from "framer-motion"; import { useDrag, useDrop } from "react-dnd"; -import { trpc } from "renderer/lib/trpc"; +import { electronTrpc } from "renderer/lib/electron-trpc"; import { useReorderProjects } from "renderer/react-query/projects"; import { useWorkspaceSidebarStore } from "renderer/stores"; import { useOpenNewWorkspaceModal } from "renderer/stores/new-workspace-modal"; @@ -52,7 +52,7 @@ export function ProjectSection({ useWorkspaceSidebarStore(); const openModal = useOpenNewWorkspaceModal(); const reorderProjects = useReorderProjects(); - const utils = trpc.useUtils(); + const utils = electronTrpc.useUtils(); const isCollapsed = isProjectCollapsed(projectId); From 5f452a96cd2307b3bb9b271b47175ec454219e6e Mon Sep 17 00:00:00 2001 From: Satya Patel Date: Wed, 14 Jan 2026 13:44:55 -0800 Subject: [PATCH 08/12] WIP --- apps/desktop/docs/ROUTING_REFACTOR_PLAN.md | 4 +- .../trpc/routers/auth/utils/auth-functions.ts | 4 - apps/desktop/src/lib/window-loader.ts | 17 +- apps/desktop/src/main/index.ts | 12 +- apps/desktop/src/main/lib/auth/auth.ts | 34 +- apps/desktop/src/renderer/index.tsx | 4 +- apps/desktop/src/renderer/lib/auth-client.ts | 15 +- .../desktop/src/renderer/lib/electron-trpc.ts | 5 +- apps/desktop/src/renderer/lib/query-client.ts | 15 - apps/desktop/src/renderer/lib/trpc.ts | 11 - .../providers/AuthProvider/AuthProvider.tsx | 86 +- .../renderer/providers/AuthProvider/index.ts | 2 +- .../ElectronTRPCProvider.tsx | 45 +- .../providers/ElectronTRPCProvider/index.ts | 5 +- .../providers/TRPCProvider/TRPCProvider.tsx | 47 -- .../renderer/providers/TRPCProvider/index.ts | 1 - .../renderer/routes/_authenticated/layout.tsx | 20 +- .../CollectionsProvider.tsx | 9 +- .../CollectionsProvider/collections.ts | 97 ++- .../OrganizationsProvider.tsx | 56 -- .../providers/OrganizationsProvider/index.ts | 5 - apps/desktop/src/renderer/routes/layout.tsx | 6 +- .../src/renderer/routes/sign-in/page.tsx | 15 +- bun.lock | 745 ++++++++---------- packages/auth/src/env.ts | 1 + packages/auth/src/server.ts | 4 + 26 files changed, 524 insertions(+), 741 deletions(-) delete mode 100644 apps/desktop/src/renderer/lib/query-client.ts delete mode 100644 apps/desktop/src/renderer/lib/trpc.ts delete mode 100644 apps/desktop/src/renderer/providers/TRPCProvider/TRPCProvider.tsx delete mode 100644 apps/desktop/src/renderer/providers/TRPCProvider/index.ts delete mode 100644 apps/desktop/src/renderer/routes/_authenticated/providers/OrganizationsProvider/OrganizationsProvider.tsx delete mode 100644 apps/desktop/src/renderer/routes/_authenticated/providers/OrganizationsProvider/index.ts diff --git a/apps/desktop/docs/ROUTING_REFACTOR_PLAN.md b/apps/desktop/docs/ROUTING_REFACTOR_PLAN.md index 30a23bb04..5e110f3c4 100644 --- a/apps/desktop/docs/ROUTING_REFACTOR_PLAN.md +++ b/apps/desktop/docs/ROUTING_REFACTOR_PLAN.md @@ -443,7 +443,7 @@ function AuthenticatedLayout() { return ( - + {/* workspace, tasks, workspaces, settings render here */} @@ -451,7 +451,7 @@ function AuthenticatedLayout() { - + ); } diff --git a/apps/desktop/src/lib/trpc/routers/auth/utils/auth-functions.ts b/apps/desktop/src/lib/trpc/routers/auth/utils/auth-functions.ts index 8401e79b1..d114d0d6a 100644 --- a/apps/desktop/src/lib/trpc/routers/auth/utils/auth-functions.ts +++ b/apps/desktop/src/lib/trpc/routers/auth/utils/auth-functions.ts @@ -29,7 +29,6 @@ export async function loadToken(): Promise<{ try { const data = decrypt(await fs.readFile(TOKEN_FILE)); const parsed: StoredAuth = JSON.parse(data); - console.log("[auth] Token loaded from disk"); return { token: parsed.token, expiresAt: parsed.expiresAt }; } catch { return { token: null, expiresAt: null }; @@ -48,9 +47,6 @@ export async function saveToken({ }): Promise { const storedAuth: StoredAuth = { token, expiresAt }; await fs.writeFile(TOKEN_FILE, encrypt(JSON.stringify(storedAuth))); - console.log("[auth] Token saved to disk"); - - // Emit event for onTokenChanged subscription authEvents.emit("token-saved", { token, expiresAt }); } diff --git a/apps/desktop/src/lib/window-loader.ts b/apps/desktop/src/lib/window-loader.ts index 596791618..9ab01aed1 100644 --- a/apps/desktop/src/lib/window-loader.ts +++ b/apps/desktop/src/lib/window-loader.ts @@ -1,5 +1,5 @@ import type { BrowserWindow } from "electron"; -import { PORTS } from "shared/constants"; +import { PORTS, PROTOCOL_SCHEME } from "shared/constants"; import { env } from "shared/env.shared"; /** Window IDs defined in the router configuration */ @@ -7,10 +7,11 @@ type WindowId = "main" | "about"; /** * Load an Electron window with the appropriate URL for TanStack Router. - * Uses hash-based routing for compatibility with Electron's file:// protocol. + * Uses hash-based routing for compatibility with Electron's custom protocol. * - * - Development (NODE_ENV=development): loads from Vite dev server at http://localhost:PORT/#/ - * - Preview/Production: loads from built HTML file with hash routing (#/) + * - Development: loads from Vite dev server at http://localhost:PORT/#/ + * - Production: loads from custom protocol at superset://app/index.html#/ + * (provides stable origin for Better Auth CORS) */ export function registerRoute(props: { id: WindowId; @@ -25,8 +26,10 @@ export function registerRoute(props: { const url = `http://localhost:${PORTS.VITE_DEV_SERVER}/#/`; props.browserWindow.loadURL(url); } else { - // Preview or Production: load from file with hash routing - // TanStack Router uses hash-based routing, so we always start at #/ - props.browserWindow.loadFile(props.htmlFile, { hash: "/" }); + // Production: load from custom protocol with hash routing + // Origin becomes: superset://app (trusted by Better Auth) + const fileName = props.htmlFile.split("/").pop() || "index.html"; + const url = `${PROTOCOL_SCHEME}://app/${fileName}#/`; + props.browserWindow.loadURL(url); } } diff --git a/apps/desktop/src/main/index.ts b/apps/desktop/src/main/index.ts index 1c5b29f37..16f8ab410 100644 --- a/apps/desktop/src/main/index.ts +++ b/apps/desktop/src/main/index.ts @@ -4,7 +4,7 @@ initSentry(); import path from "node:path"; import { settings } from "@superset/local-db"; -import { app, BrowserWindow, dialog } from "electron"; +import { app, BrowserWindow, dialog, net, protocol } from "electron"; import { makeAppSetup } from "lib/electron-app/factories/app/setup"; import { handleAuthCallback, @@ -208,6 +208,16 @@ if (!gotTheLock) { (async () => { await app.whenReady(); + // Register custom protocol to serve app files in production + // This provides a stable origin (superset://app or superset-dev://app) for Better Auth CORS + if (process.env.NODE_ENV !== "development") { + protocol.handle(PROTOCOL_SCHEME, (request) => { + const url = request.url.replace(`${PROTOCOL_SCHEME}://`, ""); + const filePath = path.normalize(path.join(__dirname, "../renderer", url)); + return net.fetch(`file://${filePath}`); + }); + } + await initAppState(); // Resolve shell environment before setting up agent hooks diff --git a/apps/desktop/src/main/lib/auth/auth.ts b/apps/desktop/src/main/lib/auth/auth.ts index ae7aabac8..1228b79a2 100644 --- a/apps/desktop/src/main/lib/auth/auth.ts +++ b/apps/desktop/src/main/lib/auth/auth.ts @@ -63,11 +63,8 @@ class AuthService extends EventEmitter { this.expiresAt = new Date(parsed.expiresAt); if (this.isExpired()) { - console.log("[auth] Session expired, clearing"); await this.signOut(); } else { - console.log("[auth] Session restored"); - // Fetch session data from API await this.refreshSession(); } } catch { @@ -84,27 +81,14 @@ class AuthService extends EventEmitter { } getState() { - const state = { + return { isSignedIn: !!this.token && !this.isExpired(), expiresAt: this.expiresAt?.toISOString() ?? null, }; - console.log("[auth] getState called:", { - hasToken: !!this.token, - isExpired: this.isExpired(), - isSignedIn: state.isSignedIn, - }); - return state; } getAccessToken(): string | null { - const expired = this.isExpired(); - const token = expired ? null : this.token; - console.log("[auth] getAccessToken called:", { - hasToken: !!this.token, - isExpired: expired, - returning: token ? "token" : "null", - }); - return token; + return this.isExpired() ? null : this.token; } getSession(): Session | null { @@ -206,30 +190,20 @@ class AuthService extends EventEmitter { }; await fs.writeFile(TOKEN_FILE, encrypt(JSON.stringify(storedAuth))); - console.log("[auth] Token saved, fetching session..."); - - // Fetch session data from API before emitting state change await this.refreshSession(); - - console.log("[auth] Session fetched, emitting state change"); - const state = this.getState(); - console.log("[auth] EMIT state-changed from handleAuthCallback:", state); - this.emit("state-changed", state); + this.emit("state-changed", this.getState()); return { success: true }; } async signOut(): Promise { - console.log("[auth] signOut called"); this.token = null; this.expiresAt = null; this.session = null; try { await fs.unlink(TOKEN_FILE); } catch {} - const state = this.getState(); - console.log("[auth] EMIT state-changed from signOut:", state); - this.emit("state-changed", state); + this.emit("state-changed", this.getState()); } } diff --git a/apps/desktop/src/renderer/index.tsx b/apps/desktop/src/renderer/index.tsx index a49d4e649..d5e95c194 100644 --- a/apps/desktop/src/renderer/index.tsx +++ b/apps/desktop/src/renderer/index.tsx @@ -9,7 +9,7 @@ import { RouterProvider, } from "@tanstack/react-router"; import ReactDom from "react-dom/client"; -import { queryClient } from "./lib/query-client"; +import { electronQueryClient } from "./providers/ElectronTRPCProvider"; import { routeTree } from "./routeTree.gen"; import "./globals.css"; @@ -21,7 +21,7 @@ const router = createRouter({ history: hashHistory as RouterHistory, defaultPreload: "intent", context: { - queryClient, + queryClient: electronQueryClient, }, }); diff --git a/apps/desktop/src/renderer/lib/auth-client.ts b/apps/desktop/src/renderer/lib/auth-client.ts index d4a21c520..122625f59 100644 --- a/apps/desktop/src/renderer/lib/auth-client.ts +++ b/apps/desktop/src/renderer/lib/auth-client.ts @@ -15,18 +15,19 @@ export function getAuthToken(): string | null { /** * Better Auth client for Electron desktop app. * - * Security: Token stored in memory only (not localStorage). - * - Better Auth reads token via getter function - * - AuthProvider manages token in React context - * - Token persisted only to encrypted disk storage (main process) + * Bearer authentication configured via onRequest hook. + * Server has bearer() plugin enabled to accept bearer tokens. */ export const authClient = createAuthClient({ baseURL: env.NEXT_PUBLIC_API_URL, plugins: [organizationClient()], fetchOptions: { - auth: { - type: "Bearer", - token: () => authToken || "", + credentials: "include", + onRequest: async (context) => { + const token = getAuthToken(); + if (token) { + context.headers.set("Authorization", `Bearer ${token}`); + } }, }, }); diff --git a/apps/desktop/src/renderer/lib/electron-trpc.ts b/apps/desktop/src/renderer/lib/electron-trpc.ts index c7a4f24e7..f351980e4 100644 --- a/apps/desktop/src/renderer/lib/electron-trpc.ts +++ b/apps/desktop/src/renderer/lib/electron-trpc.ts @@ -6,5 +6,8 @@ import type { AppRouter } from "lib/trpc/routers"; * tRPC React client for Electron IPC communication with main process. * For desktop-specific operations: workspaces, terminal, auth, etc. */ -export const electronTrpc = createTRPCReact(); +export const electronTrpc = createTRPCReact({ + abortOnUnmount: true, +}); + export type ElectronRouterOutputs = inferRouterOutputs; diff --git a/apps/desktop/src/renderer/lib/query-client.ts b/apps/desktop/src/renderer/lib/query-client.ts deleted file mode 100644 index 59023ff2f..000000000 --- a/apps/desktop/src/renderer/lib/query-client.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { QueryClient } from "@tanstack/react-query"; - -// Shared QueryClient instance for both TRPCProvider and router loaders -export const queryClient = new QueryClient({ - defaultOptions: { - queries: { - networkMode: "always", - retry: false, - }, - mutations: { - networkMode: "always", - retry: false, - }, - }, -}); diff --git a/apps/desktop/src/renderer/lib/trpc.ts b/apps/desktop/src/renderer/lib/trpc.ts deleted file mode 100644 index 34f612119..000000000 --- a/apps/desktop/src/renderer/lib/trpc.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { AppRouter } from "@superset/trpc"; -import { createTRPCReact } from "@trpc/react-query"; -import type { inferRouterOutputs } from "@trpc/server"; - -/** - * HTTP API tRPC client for communicating with the Superset API. - * Uses bearer auth and talks to NEXT_PUBLIC_API_URL. - * For Electron IPC communication, use `electronTrpc` instead. - */ -export const trpc = createTRPCReact(); -export type RouterOutputs = inferRouterOutputs; diff --git a/apps/desktop/src/renderer/providers/AuthProvider/AuthProvider.tsx b/apps/desktop/src/renderer/providers/AuthProvider/AuthProvider.tsx index 749ea41e2..4a24e41b1 100644 --- a/apps/desktop/src/renderer/providers/AuthProvider/AuthProvider.tsx +++ b/apps/desktop/src/renderer/providers/AuthProvider/AuthProvider.tsx @@ -1,25 +1,23 @@ -import { - createContext, - type ReactNode, - useContext, - useEffect, - useState, -} from "react"; +import { type ReactNode, useEffect, useState } from "react"; import { authClient, setAuthToken } from "renderer/lib/auth-client"; import { electronTrpc } from "../../lib/electron-trpc"; -interface AuthTokenContextValue { - token: string | null; -} - -const AuthTokenContext = createContext(null); - +/** + * AuthProvider: Manages token synchronization between memory and encrypted disk storage. + * + * Simple flow: + * 1. Load token from disk on mount + * 2. Listen for OAuth callback tokens + * 3. Set in memory via setAuthToken() + * 4. Layouts handle session checks naturally via authClient.useSession() + */ export function AuthProvider({ children }: { children: ReactNode }) { const [isHydrated, setIsHydrated] = useState(false); - const [token, setToken] = useState(null); - const { data: session } = authClient.useSession(); + // Get session refetch to bust cache when token changes + const { refetch: refetchSession } = authClient.useSession(); + // Initial hydration: Load token from disk const { data: storedToken } = electronTrpc.auth.getStoredToken.useQuery( undefined, { @@ -28,46 +26,28 @@ export function AuthProvider({ children }: { children: ReactNode }) { }, ); - const persistMutation = electronTrpc.auth.persistToken.useMutation(); - - electronTrpc.auth.onTokenChanged.useSubscription(undefined, { - onData: (data) => { - if (data?.token && data?.expiresAt) { - setToken(data.token); - setAuthToken(data.token); - persistMutation.mutate({ - token: data.token, - expiresAt: data.expiresAt, - }); - } - }, - }); - useEffect(() => { if (storedToken && !isHydrated) { if (storedToken.token && storedToken.expiresAt) { - setToken(storedToken.token); setAuthToken(storedToken.token); + refetchSession(); } setIsHydrated(true); } - }, [storedToken, isHydrated]); - - useEffect(() => { - if (token) { - setAuthToken(token); - } else { - setAuthToken(null); - } - }, [token]); + }, [storedToken, isHydrated, refetchSession]); - useEffect(() => { - if (!session?.user && token) { - setToken(null); - setAuthToken(null); - } - }, [session, token]); + // Listen for token changes from main process (OAuth callback) + electronTrpc.auth.onTokenChanged.useSubscription(undefined, { + onData: (data) => { + if (data?.token && data?.expiresAt) { + setAuthToken(data.token); + setIsHydrated(true); + refetchSession(); + } + }, + }); + // Show loading spinner until initial hydration completes if (!isHydrated) { return (
@@ -76,17 +56,5 @@ export function AuthProvider({ children }: { children: ReactNode }) { ); } - return ( - - {children} - - ); -} - -export function useAuthToken(): string | null { - const context = useContext(AuthTokenContext); - if (!context) { - throw new Error("useAuthToken must be used within AuthProvider"); - } - return context.token; + return <>{children}; } diff --git a/apps/desktop/src/renderer/providers/AuthProvider/index.ts b/apps/desktop/src/renderer/providers/AuthProvider/index.ts index 8ec6b18fa..842d0c19c 100644 --- a/apps/desktop/src/renderer/providers/AuthProvider/index.ts +++ b/apps/desktop/src/renderer/providers/AuthProvider/index.ts @@ -1 +1 @@ -export { AuthProvider, useAuthToken } from "./AuthProvider"; +export { AuthProvider } from "./AuthProvider"; diff --git a/apps/desktop/src/renderer/providers/ElectronTRPCProvider/ElectronTRPCProvider.tsx b/apps/desktop/src/renderer/providers/ElectronTRPCProvider/ElectronTRPCProvider.tsx index 08972eed0..9cda54afa 100644 --- a/apps/desktop/src/renderer/providers/ElectronTRPCProvider/ElectronTRPCProvider.tsx +++ b/apps/desktop/src/renderer/providers/ElectronTRPCProvider/ElectronTRPCProvider.tsx @@ -1,39 +1,38 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { useState } from "react"; import { electronTrpc } from "renderer/lib/electron-trpc"; import { electronReactClient } from "../../lib/trpc-client"; +// Shared QueryClient for tRPC hooks and router loaders +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + networkMode: "always", + retry: false, + }, + mutations: { + networkMode: "always", + retry: false, + }, + }, +}); + /** * Provider for Electron IPC tRPC client. - * For desktop-specific operations: workspaces, terminal, auth, etc. + * QueryClient is shared with router context for loader prefetching. */ export function ElectronTRPCProvider({ children, }: { children: React.ReactNode; }) { - const [queryClient] = useState( - () => - new QueryClient({ - defaultOptions: { - queries: { - networkMode: "always", - retry: false, - }, - mutations: { - networkMode: "always", - retry: false, - }, - }, - }), - ); - return ( - - {children} + + + {children} + ); } + +// Export for router context +export { queryClient as electronQueryClient }; diff --git a/apps/desktop/src/renderer/providers/ElectronTRPCProvider/index.ts b/apps/desktop/src/renderer/providers/ElectronTRPCProvider/index.ts index 4483d5b6f..f8ca85599 100644 --- a/apps/desktop/src/renderer/providers/ElectronTRPCProvider/index.ts +++ b/apps/desktop/src/renderer/providers/ElectronTRPCProvider/index.ts @@ -1 +1,4 @@ -export { ElectronTRPCProvider } from "./ElectronTRPCProvider"; +export { + ElectronTRPCProvider, + electronQueryClient, +} from "./ElectronTRPCProvider"; diff --git a/apps/desktop/src/renderer/providers/TRPCProvider/TRPCProvider.tsx b/apps/desktop/src/renderer/providers/TRPCProvider/TRPCProvider.tsx deleted file mode 100644 index a784c06e2..000000000 --- a/apps/desktop/src/renderer/providers/TRPCProvider/TRPCProvider.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { httpBatchLink } from "@trpc/client"; -import type { ReactNode } from "react"; -import { useMemo, useState } from "react"; -import { env } from "renderer/env.renderer"; -import { getAuthToken } from "renderer/lib/auth-client"; -import { trpc } from "renderer/lib/trpc"; -import superjson from "superjson"; - -export function TRPCProvider({ children }: { children: ReactNode }) { - const [queryClient] = useState( - () => - new QueryClient({ - defaultOptions: { - queries: { - networkMode: "always", - retry: false, - }, - mutations: { - networkMode: "always", - retry: false, - }, - }, - }), - ); - - const apiClient = useMemo(() => { - return trpc.createClient({ - links: [ - httpBatchLink({ - url: `${env.NEXT_PUBLIC_API_URL}/api/trpc`, - headers() { - const token = getAuthToken(); - return token ? { Authorization: `Bearer ${token}` } : {}; - }, - transformer: superjson, - }), - ], - }); - }, []); - - return ( - - {children} - - ); -} diff --git a/apps/desktop/src/renderer/providers/TRPCProvider/index.ts b/apps/desktop/src/renderer/providers/TRPCProvider/index.ts deleted file mode 100644 index 080c22d76..000000000 --- a/apps/desktop/src/renderer/providers/TRPCProvider/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { TRPCProvider } from "./TRPCProvider"; diff --git a/apps/desktop/src/renderer/routes/_authenticated/layout.tsx b/apps/desktop/src/renderer/routes/_authenticated/layout.tsx index d56b35a95..5890b297c 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/layout.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/layout.tsx @@ -3,26 +3,32 @@ import { DndProvider } from "react-dnd"; import { authClient } from "renderer/lib/auth-client"; import { dragDropManager } from "renderer/lib/dnd"; import { CollectionsProvider } from "./providers/CollectionsProvider"; -import { OrganizationsProvider } from "./providers/OrganizationsProvider"; export const Route = createFileRoute("/_authenticated")({ component: AuthenticatedLayout, }); function AuthenticatedLayout() { - const { data: session } = authClient.useSession(); - const isSignedIn = !!session?.user; + const { data: session, isPending, error } = authClient.useSession(); - if (!isSignedIn) { + // Session still loading - show spinner + if (isPending) { + return ( +
+
+
+ ); + } + + // Error or no user - not authenticated, redirect to sign-in + if (error || !session?.user) { return ; } return ( - - - + ); diff --git a/apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/CollectionsProvider.tsx b/apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/CollectionsProvider.tsx index f65a9a56a..c9704bc6e 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/CollectionsProvider.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/CollectionsProvider.tsx @@ -1,6 +1,5 @@ import { createContext, type ReactNode, useContext, useMemo } from "react"; import { authClient } from "renderer/lib/auth-client"; -import { useAuthToken } from "renderer/providers/AuthProvider"; import { getCollections } from "./collections"; type Collections = ReturnType; @@ -9,18 +8,16 @@ const CollectionsContext = createContext(null); export function CollectionsProvider({ children }: { children: ReactNode }) { const { data: session } = authClient.useSession(); - const token = useAuthToken(); const activeOrganizationId = session?.session?.activeOrganizationId; const collections = useMemo(() => { - if (!token || !activeOrganizationId) { + if (!activeOrganizationId) { return null; } - return getCollections(activeOrganizationId, token); - }, [token, activeOrganizationId]); + return getCollections(activeOrganizationId); + }, [activeOrganizationId]); - // Show loading only on initial mount if (!collections) { return (
diff --git a/apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/collections.ts b/apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/collections.ts index c06e64438..a40aa19f5 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/collections.ts +++ b/apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/collections.ts @@ -13,6 +13,7 @@ import type { Collection } from "@tanstack/react-db"; import { createCollection } from "@tanstack/react-db"; import { createTRPCProxyClient, httpBatchLink } from "@trpc/client"; import { env } from "renderer/env.renderer"; +import { getAuthToken } from "renderer/lib/auth-client"; import superjson from "superjson"; const columnMapper = snakeCamelMapper(); @@ -29,27 +30,45 @@ interface OrgCollections { // Per-org collections cache const collectionsCache = new Map(); -// Shared organizations collection (same for all orgs) -let organizationsCollection: Collection | null = null; - -function createApiClient(token: string) { - return createTRPCProxyClient({ - links: [ - httpBatchLink({ - url: `${env.NEXT_PUBLIC_API_URL}/api/trpc`, - headers: { Authorization: `Bearer ${token}` }, - transformer: superjson, - }), - ], - }); -} - -function createOrgCollections( - organizationId: string, - token: string, -): OrgCollections { - const headers = { Authorization: `Bearer ${token}` }; - const apiClient = createApiClient(token); +// Singleton API client with dynamic auth headers +const apiClient = createTRPCProxyClient({ + links: [ + httpBatchLink({ + url: `${env.NEXT_PUBLIC_API_URL}/api/trpc`, + headers: () => { + const token = getAuthToken(); + return token ? { Authorization: `Bearer ${token}` } : {}; + }, + transformer: superjson, + }), + ], +}); + +const organizationsCollection = createCollection( + electricCollectionOptions({ + id: "organizations", + shapeOptions: { + url: electricUrl, + params: { table: "auth.organizations" }, + headers: { + Authorization: () => { + const token = getAuthToken(); + return token ? `Bearer ${token}` : ""; + }, + }, + columnMapper, + }, + getKey: (item) => item.id, + }), +); + +function createOrgCollections(organizationId: string): OrgCollections { + const headers = { + Authorization: () => { + const token = getAuthToken(); + return token ? `Bearer ${token}` : ""; + }, + }; const tasks = createCollection( electricCollectionOptions({ @@ -162,41 +181,15 @@ function createOrgCollections( return { tasks, taskStatuses, repositories, members, users }; } -function getOrCreateOrganizationsCollection( - token: string, -): Collection { - if (!organizationsCollection) { - organizationsCollection = createCollection( - electricCollectionOptions({ - id: "organizations", - shapeOptions: { - url: electricUrl, - params: { table: "auth.organizations" }, - headers: { Authorization: `Bearer ${token}` }, - columnMapper, - }, - getKey: (item) => item.id, - }), - ); - } - return organizationsCollection; -} - /** * Get collections for an organization, creating them if needed. * Collections are cached per org for instant switching. + * Auth token is read dynamically via getAuthToken() - no need to pass it. */ -export function getCollections(organizationId: string, token: string) { +export function getCollections(organizationId: string) { // Get or create org-specific collections if (!collectionsCache.has(organizationId)) { - console.log( - "[collections] Creating new collections for org:", - organizationId, - ); - collectionsCache.set( - organizationId, - createOrgCollections(organizationId, token), - ); + collectionsCache.set(organizationId, createOrgCollections(organizationId)); } const orgCollections = collectionsCache.get(organizationId); @@ -204,10 +197,8 @@ export function getCollections(organizationId: string, token: string) { throw new Error(`Collections not found for org: ${organizationId}`); } - const organizations = getOrCreateOrganizationsCollection(token); - return { ...orgCollections, - organizations, + organizations: organizationsCollection, }; } diff --git a/apps/desktop/src/renderer/routes/_authenticated/providers/OrganizationsProvider/OrganizationsProvider.tsx b/apps/desktop/src/renderer/routes/_authenticated/providers/OrganizationsProvider/OrganizationsProvider.tsx deleted file mode 100644 index 0fa5d20b4..000000000 --- a/apps/desktop/src/renderer/routes/_authenticated/providers/OrganizationsProvider/OrganizationsProvider.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import type { AppRouter } from "@superset/trpc"; -import type { inferRouterOutputs } from "@trpc/server"; -import { createContext, type ReactNode, useContext } from "react"; -import { trpc } from "renderer/lib/trpc"; - -type ApiRouterOutputs = inferRouterOutputs; -export type Organization = ApiRouterOutputs["user"]["myOrganizations"][number]; - -interface OrganizationsContextValue { - organizations: Organization[]; -} - -const OrganizationsContext = createContext( - null, -); - -export function useOrganizations(): Organization[] { - const ctx = useContext(OrganizationsContext); - if (!ctx) - throw new Error( - "useOrganizations must be used within OrganizationsProvider", - ); - return ctx.organizations; -} - -export function OrganizationsProvider({ children }: { children: ReactNode }) { - const { - data: organizations, - isLoading, - error, - } = trpc.user.myOrganizations.useQuery(); - - if (isLoading) { - return null; - } - - if (error) { - console.error( - "[OrganizationsProvider] Error loading organizations:", - error, - ); - return ( -
Failed to load organizations
- ); - } - - if (!organizations?.length) { - return
No organizations found
; - } - - return ( - - {children} - - ); -} diff --git a/apps/desktop/src/renderer/routes/_authenticated/providers/OrganizationsProvider/index.ts b/apps/desktop/src/renderer/routes/_authenticated/providers/OrganizationsProvider/index.ts deleted file mode 100644 index ef167b375..000000000 --- a/apps/desktop/src/renderer/routes/_authenticated/providers/OrganizationsProvider/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export { - type Organization, - OrganizationsProvider, - useOrganizations, -} from "./OrganizationsProvider"; diff --git a/apps/desktop/src/renderer/routes/layout.tsx b/apps/desktop/src/renderer/routes/layout.tsx index 517874222..92982e221 100644 --- a/apps/desktop/src/renderer/routes/layout.tsx +++ b/apps/desktop/src/renderer/routes/layout.tsx @@ -2,14 +2,14 @@ import type { ReactNode } from "react"; import { PostHogUserIdentifier } from "renderer/components/PostHogUserIdentifier"; import { ThemedToaster } from "renderer/components/ThemedToaster"; import { AuthProvider } from "renderer/providers/AuthProvider"; +import { ElectronTRPCProvider } from "renderer/providers/ElectronTRPCProvider"; import { MonacoProvider } from "renderer/providers/MonacoProvider"; import { PostHogProvider } from "renderer/providers/PostHogProvider"; -import { TRPCProvider } from "renderer/providers/TRPCProvider"; export function RootLayout({ children }: { children: ReactNode }) { return ( - + @@ -17,7 +17,7 @@ export function RootLayout({ children }: { children: ReactNode }) { - + ); } diff --git a/apps/desktop/src/renderer/routes/sign-in/page.tsx b/apps/desktop/src/renderer/routes/sign-in/page.tsx index dcdf3a2d7..cd2ddc481 100644 --- a/apps/desktop/src/renderer/routes/sign-in/page.tsx +++ b/apps/desktop/src/renderer/routes/sign-in/page.tsx @@ -14,15 +14,24 @@ export const Route = createFileRoute("/sign-in/")({ }); function SignInPage() { - const { data: session } = authClient.useSession(); + const { data: session, isPending } = authClient.useSession(); const signInMutation = electronTrpc.auth.signIn.useMutation(); useEffect(() => { posthog.capture("desktop_opened"); }, []); - const isSignedIn = !!session?.user; - if (isSignedIn) { + // Show loading while session is being fetched + if (isPending) { + return ( +
+
+
+ ); + } + + // If already signed in, redirect to workspace + if (session?.user) { return ; } diff --git a/bun.lock b/bun.lock index 77e056908..9223cefb0 100644 --- a/bun.lock +++ b/bun.lock @@ -122,7 +122,7 @@ }, "apps/desktop": { "name": "@superset/desktop", - "version": "0.0.54", + "version": "0.0.56", "dependencies": { "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", @@ -161,6 +161,7 @@ "@xterm/addon-webgl": "^0.18.0", "@xterm/headless": "^5.5.0", "@xterm/xterm": "^5.5.0", + "better-auth": "^1.4.9", "better-sqlite3": "12.5.0", "bindings": "^1.5.0", "clsx": "^2.1.1", @@ -552,13 +553,13 @@ "packages": { "7zip-bin": ["7zip-bin@5.2.0", "", {}, "sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A=="], - "@ai-sdk/gateway": ["@ai-sdk/gateway@2.0.21", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@ai-sdk/provider-utils": "3.0.19", "@vercel/oidc": "3.0.5" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-BwV7DU/lAm3Xn6iyyvZdWgVxgLu3SNXzl5y57gMvkW4nGhAOV5269IrJzQwGt03bb107sa6H6uJwWxc77zXoGA=="], + "@ai-sdk/gateway": ["@ai-sdk/gateway@2.0.27", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20", "@vercel/oidc": "3.1.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-8hbezMsGa0crSt7/DKjkYL1UbbJJW/UFxTfhmf5qcIeYeeWG4dTNmm+DWbUdIsTaWvp59KC4eeC9gYXBbTHd7w=="], - "@ai-sdk/provider": ["@ai-sdk/provider@2.0.0", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA=="], + "@ai-sdk/provider": ["@ai-sdk/provider@2.0.1", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-KCUwswvsC5VsW2PWFqF8eJgSCu5Ysj7m1TxiHTVA6g7k360bk0RNQENT8KTMAYEs+8fWPD3Uu4dEmzGHc+jGng=="], - "@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.19", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-W41Wc9/jbUVXVwCN/7bWa4IKe8MtxO3EyA0Hfhx6grnmiYlCvpI8neSYWFE0zScXJkgA/YK3BRybzgyiXuu6JA=="], + "@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.20", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-iXHVe0apM2zUEzauqJwqmpC37A5rihrStAih5Ks+JE32iTe4LZ58y17UGBjpQQTCRw9YxMeo2UFLxLpBluyvLQ=="], - "@alcalzone/ansi-tokenize": ["@alcalzone/ansi-tokenize@0.2.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-mkOh+Wwawzuf5wa30bvc4nA+Qb6DIrGWgBhRR/Pw4T9nsgYait8izvXkNyU78D6Wcu3Z+KUdwCmLCxlWjEotYA=="], + "@alcalzone/ansi-tokenize": ["@alcalzone/ansi-tokenize@0.2.3", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-jsElTJ0sQ4wHRz+C45tfect76BwbTbgkgKByOzpCN9xG61N5V6u/glvg1CsNJhq2xJIFpKHSwG3D2wPPuEYOrQ=="], "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], @@ -568,21 +569,21 @@ "@apm-js-collab/tracing-hooks": ["@apm-js-collab/tracing-hooks@0.3.1", "", { "dependencies": { "@apm-js-collab/code-transformer": "^0.8.0", "debug": "^4.4.1", "module-details-from-path": "^1.0.4" } }, "sha512-Vu1CbmPURlN5fTboVuKMoJjbO5qcq9fA5YXpskx3dXe/zTBvjODFoerw+69rVBlRLrJpwPqSDqEuJDEKIrTldw=="], - "@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], + "@babel/code-frame": ["@babel/code-frame@7.28.6", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q=="], - "@babel/compat-data": ["@babel/compat-data@7.28.5", "", {}, "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA=="], + "@babel/compat-data": ["@babel/compat-data@7.28.6", "", {}, "sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg=="], - "@babel/core": ["@babel/core@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw=="], + "@babel/core": ["@babel/core@7.28.6", "", { "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/generator": "^7.28.6", "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-module-transforms": "^7.28.6", "@babel/helpers": "^7.28.6", "@babel/parser": "^7.28.6", "@babel/template": "^7.28.6", "@babel/traverse": "^7.28.6", "@babel/types": "^7.28.6", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw=="], - "@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="], + "@babel/generator": ["@babel/generator@7.28.6", "", { "dependencies": { "@babel/parser": "^7.28.6", "@babel/types": "^7.28.6", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw=="], - "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.27.2", "", { "dependencies": { "@babel/compat-data": "^7.27.2", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ=="], + "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.28.6", "", { "dependencies": { "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA=="], "@babel/helper-globals": ["@babel/helper-globals@7.28.0", "", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="], - "@babel/helper-module-imports": ["@babel/helper-module-imports@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w=="], + "@babel/helper-module-imports": ["@babel/helper-module-imports@7.28.6", "", { "dependencies": { "@babel/traverse": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw=="], - "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw=="], + "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.6", "", { "dependencies": { "@babel/helper-module-imports": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", "@babel/traverse": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA=="], "@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.28.6", "", {}, "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug=="], @@ -592,9 +593,9 @@ "@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="], - "@babel/helpers": ["@babel/helpers@7.28.4", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.4" } }, "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w=="], + "@babel/helpers": ["@babel/helpers@7.28.6", "", { "dependencies": { "@babel/template": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw=="], - "@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": "./bin/babel-parser.js" }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], + "@babel/parser": ["@babel/parser@7.28.6", "", { "dependencies": { "@babel/types": "^7.28.6" }, "bin": "./bin/babel-parser.js" }, "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ=="], "@babel/plugin-syntax-jsx": ["@babel/plugin-syntax-jsx@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w=="], @@ -606,17 +607,17 @@ "@babel/plugin-transform-react-jsx-source": ["@babel/plugin-transform-react-jsx-source@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw=="], - "@babel/runtime": ["@babel/runtime@7.28.4", "", {}, "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ=="], + "@babel/runtime": ["@babel/runtime@7.28.6", "", {}, "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA=="], - "@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], + "@babel/template": ["@babel/template@7.28.6", "", { "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/parser": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ=="], - "@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], + "@babel/traverse": ["@babel/traverse@7.28.6", "", { "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/generator": "^7.28.6", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.6", "@babel/template": "^7.28.6", "@babel/types": "^7.28.6", "debug": "^4.3.1" } }, "sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg=="], - "@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], + "@babel/types": ["@babel/types@7.28.6", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg=="], - "@better-auth/core": ["@better-auth/core@1.4.9", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "zod": "^4.1.12" }, "peerDependencies": { "@better-auth/utils": "0.3.0", "@better-fetch/fetch": "1.1.21", "better-call": "1.1.7", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1" } }, "sha512-JT2q4NDkQzN22KclUEoZ7qU6tl9HUTfK1ctg2oWlT87SEagkwJcnrUwS9VznL+u9ziOIfY27P0f7/jSnmvLcoQ=="], + "@better-auth/core": ["@better-auth/core@1.4.12", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "zod": "^4.1.12" }, "peerDependencies": { "@better-auth/utils": "0.3.0", "@better-fetch/fetch": "1.1.21", "better-call": "1.1.7", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1" } }, "sha512-VfqZwMAEl9rnGx092BIZ2Q5z8rt7jjN2OAbvPqehufSKZGmh8JsdtZRBMl/CHQir9bwi2Ev0UF4+7TQp+DXEMg=="], - "@better-auth/telemetry": ["@better-auth/telemetry@1.4.9", "", { "dependencies": { "@better-auth/utils": "0.3.0", "@better-fetch/fetch": "1.1.21" }, "peerDependencies": { "@better-auth/core": "1.4.9" } }, "sha512-Tthy1/Gmx+pYlbvRQPBTKfVei8+pJwvH1NZp+5SbhwA6K2EXIaoonx/K6N/AXYs2aKUpyR4/gzqDesDjL7zd6A=="], + "@better-auth/telemetry": ["@better-auth/telemetry@1.4.12", "", { "dependencies": { "@better-auth/utils": "0.3.0", "@better-fetch/fetch": "1.1.21" }, "peerDependencies": { "@better-auth/core": "1.4.12" } }, "sha512-4q504Og42PzkUbZjXDt+FyeYaS0WZmAlEOC3nbBCZDObTVCRUnGgJW52B2maJ7BCVvAQgBGLEeQmQzU5+63J0A=="], "@better-auth/utils": ["@better-auth/utils@0.3.0", "", {}, "sha512-W+Adw6ZA6mgvnSnhOki270rwJ42t4XzSK6YWGF//BbVXL6SwCLWfyzBc1lN2m/4RM28KubdBKQ4X5VMoLRNPQw=="], @@ -652,17 +653,17 @@ "@chevrotain/utils": ["@chevrotain/utils@11.0.3", "", {}, "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ=="], - "@code-inspector/core": ["@code-inspector/core@1.3.2", "", { "dependencies": { "@vue/compiler-dom": "^3.5.13", "chalk": "^4.1.1", "dotenv": "^16.1.4", "launch-ide": "1.3.0", "portfinder": "^1.0.28" } }, "sha512-6bwCW7AbX/gYaoiZPFqkHAP5f/C0nXj29AixqBUNl1sRrsWFPHHfiaWH8WPmjx9IXI/nln109GvMiFHUpm2Mvg=="], + "@code-inspector/core": ["@code-inspector/core@1.3.4", "", { "dependencies": { "@vue/compiler-dom": "^3.5.13", "chalk": "^4.1.1", "dotenv": "^16.1.4", "launch-ide": "1.3.1", "portfinder": "^1.0.28" } }, "sha512-AUFtDH/hngBHrNVwW1z44ogZkaGhfmFQJZjyQrSCp+mERVQqa4QNGQpRqiIEWVCwJ2e3GCuwxeAr/k48r1nscA=="], - "@code-inspector/esbuild": ["@code-inspector/esbuild@1.3.2", "", { "dependencies": { "@code-inspector/core": "1.3.2" } }, "sha512-AlcMO+pfwvh+m9L7bOeonTjgeJKaUsfEJxJIjyqUZMjk+F+ujhxFUKtZZU7RUvuQLr4e/flPdN+yxvWKfymr+g=="], + "@code-inspector/esbuild": ["@code-inspector/esbuild@1.3.4", "", { "dependencies": { "@code-inspector/core": "1.3.4" } }, "sha512-VVZLPnaUNtX4fm07bKBkdIn2t1H0jPzah3fHd/CtNO82mnT1H3hZCuvtlO4jQZnErWC1KYJUEDrEe4T5TA5giQ=="], - "@code-inspector/mako": ["@code-inspector/mako@1.3.2", "", { "dependencies": { "@code-inspector/core": "1.3.2" } }, "sha512-WAeCAruJ5N73jqPWQgnsqyLp4Fn9hrn5vHohxhqqXyjD+qqCUKZNLrZeuD5kyku8k51LRJWQUe6MblW3IWyUJA=="], + "@code-inspector/mako": ["@code-inspector/mako@1.3.4", "", { "dependencies": { "@code-inspector/core": "1.3.4" } }, "sha512-SvjZSfLXgiWDMmJ9+YfPqbE2WVbXCNPjREclEJfqkM2qS/oRPmHw/O81p5wh6dN48gzVadLKEOPtSE0+FURJgQ=="], - "@code-inspector/turbopack": ["@code-inspector/turbopack@1.3.2", "", { "dependencies": { "@code-inspector/core": "1.3.2", "@code-inspector/webpack": "1.3.2" } }, "sha512-e7HJIwgGInSHLpHv1ZdAaILnJsREiwDL5363Gs6H0ZB2JvdHvLTpYFc6wlPLrZG4fp53FwsnULFhHtXDrjVYRg=="], + "@code-inspector/turbopack": ["@code-inspector/turbopack@1.3.4", "", { "dependencies": { "@code-inspector/core": "1.3.4", "@code-inspector/webpack": "1.3.4" } }, "sha512-zsv2ppMFedNZetrlN4PEW4B2vAheu3yUfrmSKfZlXEb8YT378sq+49+57aP/E1Q8cHRzowy4GItuPKwAy7TTVQ=="], - "@code-inspector/vite": ["@code-inspector/vite@1.3.2", "", { "dependencies": { "@code-inspector/core": "1.3.2", "chalk": "4.1.1" } }, "sha512-uwtZ2JTA7eh19LUWhwsngwhgn7S1K8y9cqHK4vu2tEDbmahiQkQM/XytzPrsdAPxGu4M7huBJoGKXn32Tjrvgg=="], + "@code-inspector/vite": ["@code-inspector/vite@1.3.4", "", { "dependencies": { "@code-inspector/core": "1.3.4", "chalk": "4.1.1" } }, "sha512-BcRnQFwt8yQ4CcbN7yPf/Vmon3yfS5lPpcH0QAcjD03r61if5fmix29f65Rf/WxzlVyBkk7148xaIVQ3iT2Yjg=="], - "@code-inspector/webpack": ["@code-inspector/webpack@1.3.2", "", { "dependencies": { "@code-inspector/core": "1.3.2" } }, "sha512-P9jrU7Hpca4y+ukaHRVP7w1rOIcNTPQONb5uITkt/dHDmI6/KDW5FfydcDI6Jc8HFRHLkTVZsZyUcllItA2VVQ=="], + "@code-inspector/webpack": ["@code-inspector/webpack@1.3.4", "", { "dependencies": { "@code-inspector/core": "1.3.4" } }, "sha512-lqsDOSmKXgOYvlurWL4SHaNItNCNZDVbFJlroM4ECnOGt/iNUI0UwaFxn9U5NeKff7fnTmdH8Hrz2IaMR4FVTg=="], "@date-fns/tz": ["@date-fns/tz@1.4.1", "", {}, "sha512-P5LUNhtbj6YfI3iJjw5EL9eUAG6OitD0W3fWQcpQjDRc/QIsL0tRNuO1PcDvPccWL1fSTXXdE1ds+l95DV/OFA=="], @@ -682,27 +683,23 @@ "@electric-sql/client": ["@electric-sql/client@1.4.0", "", { "dependencies": { "@microsoft/fetch-event-source": "^2.0.1" }, "optionalDependencies": { "@rollup/rollup-darwin-arm64": "^4.18.1" } }, "sha512-JTJxm3r5KXhpSEJ+C89gWbGzIH+UnPlzD92iNdtkXYx2gkoJcgd2h0YfaBF2Tu1k3yVG/pje/6CeFlHI9JrsCQ=="], - "@electric-sql/pglite": ["@electric-sql/pglite@0.3.14", "", {}, "sha512-3DB258dhqdsArOI1fIt7cb9RpUOgcDg5hXWVgVHAeqVQ/qxtFy605QKs4gx6mFq3jWsSPqDN8TgSEsqC3OfV9Q=="], - - "@electron/asar": ["@electron/asar@3.2.18", "", { "dependencies": { "commander": "^5.0.0", "glob": "^7.1.6", "minimatch": "^3.0.4" }, "bin": { "asar": "bin/asar.js" } }, "sha512-2XyvMe3N3Nrs8cV39IKELRHTYUWFKrmqqSY1U+GMlc0jvqjIVnoxhNd2H4JolWQncbJi1DCvb5TNxZuI2fEjWg=="], + "@electron/asar": ["@electron/asar@3.4.1", "", { "dependencies": { "commander": "^5.0.0", "glob": "^7.1.6", "minimatch": "^3.0.4" }, "bin": { "asar": "bin/asar.js" } }, "sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA=="], "@electron/fuses": ["@electron/fuses@1.8.0", "", { "dependencies": { "chalk": "^4.1.1", "fs-extra": "^9.0.1", "minimist": "^1.2.5" }, "bin": { "electron-fuses": "dist/bin.js" } }, "sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw=="], "@electron/get": ["@electron/get@2.0.3", "", { "dependencies": { "debug": "^4.1.1", "env-paths": "^2.2.0", "fs-extra": "^8.1.0", "got": "^11.8.5", "progress": "^2.0.3", "semver": "^6.2.0", "sumchecker": "^3.0.1" }, "optionalDependencies": { "global-agent": "^3.0.0" } }, "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ=="], - "@electron/node-gyp": ["@electron/node-gyp@github:electron/node-gyp#06b29aa", { "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "glob": "^8.1.0", "graceful-fs": "^4.2.6", "make-fetch-happen": "^10.2.1", "nopt": "^6.0.0", "proc-log": "^2.0.1", "semver": "^7.3.5", "tar": "^6.2.1", "which": "^2.0.2" }, "bin": "./bin/node-gyp.js" }, "electron-node-gyp-06b29aa"], - "@electron/notarize": ["@electron/notarize@2.5.0", "", { "dependencies": { "debug": "^4.1.1", "fs-extra": "^9.0.1", "promise-retry": "^2.0.1" } }, "sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A=="], - "@electron/osx-sign": ["@electron/osx-sign@1.3.1", "", { "dependencies": { "compare-version": "^0.1.2", "debug": "^4.3.4", "fs-extra": "^10.0.0", "isbinaryfile": "^4.0.8", "minimist": "^1.2.6", "plist": "^3.0.5" }, "bin": { "electron-osx-flat": "bin/electron-osx-flat.js", "electron-osx-sign": "bin/electron-osx-sign.js" } }, "sha512-BAfviURMHpmb1Yb50YbCxnOY0wfwaLXH5KJ4+80zS0gUkzDX3ec23naTlEqKsN+PwYn+a1cCzM7BJ4Wcd3sGzw=="], + "@electron/osx-sign": ["@electron/osx-sign@1.3.3", "", { "dependencies": { "compare-version": "^0.1.2", "debug": "^4.3.4", "fs-extra": "^10.0.0", "isbinaryfile": "^4.0.8", "minimist": "^1.2.6", "plist": "^3.0.5" }, "bin": { "electron-osx-flat": "bin/electron-osx-flat.js", "electron-osx-sign": "bin/electron-osx-sign.js" } }, "sha512-KZ8mhXvWv2rIEgMbWZ4y33bDHyUKMXnx4M0sTyPNK/vcB81ImdeY9Ggdqy0SWbMDgmbqyQ+phgejh6V3R2QuSg=="], - "@electron/rebuild": ["@electron/rebuild@3.7.0", "", { "dependencies": { "@electron/node-gyp": "git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", "@malept/cross-spawn-promise": "^2.0.0", "chalk": "^4.0.0", "debug": "^4.1.1", "detect-libc": "^2.0.1", "fs-extra": "^10.0.0", "got": "^11.7.0", "node-abi": "^3.45.0", "node-api-version": "^0.2.0", "ora": "^5.1.0", "read-binary-file-arch": "^1.0.6", "semver": "^7.3.5", "tar": "^6.0.5", "yargs": "^17.0.1" }, "bin": { "electron-rebuild": "lib/cli.js" } }, "sha512-VW++CNSlZwMYP7MyXEbrKjpzEwhB5kDNbzGtiPEjwYysqyTCF+YbNJ210Dj3AjWsGSV4iEEwNkmJN9yGZmVvmw=="], + "@electron/rebuild": ["@electron/rebuild@4.0.1", "", { "dependencies": { "@malept/cross-spawn-promise": "^2.0.0", "chalk": "^4.0.0", "debug": "^4.1.1", "detect-libc": "^2.0.1", "got": "^11.7.0", "graceful-fs": "^4.2.11", "node-abi": "^4.2.0", "node-api-version": "^0.2.1", "node-gyp": "^11.2.0", "ora": "^5.1.0", "read-binary-file-arch": "^1.0.6", "semver": "^7.3.5", "tar": "^6.0.5", "yargs": "^17.0.1" }, "bin": { "electron-rebuild": "lib/cli.js" } }, "sha512-iMGXb6Ib7H/Q3v+BKZJoETgF9g6KMNZVbsO4b7Dmpgb5qTFqyFTzqW9F3TOSHdybv2vKYKzSS9OiZL+dcJb+1Q=="], - "@electron/universal": ["@electron/universal@2.0.1", "", { "dependencies": { "@electron/asar": "^3.2.7", "@malept/cross-spawn-promise": "^2.0.0", "debug": "^4.3.1", "dir-compare": "^4.2.0", "fs-extra": "^11.1.1", "minimatch": "^9.0.3", "plist": "^3.1.0" } }, "sha512-fKpv9kg4SPmt+hY7SVBnIYULE9QJl8L3sCfcBsnqbJwwBwAeTLokJ9TRt9y7bK0JAzIW2y78TVVjvnQEms/yyA=="], + "@electron/universal": ["@electron/universal@2.0.3", "", { "dependencies": { "@electron/asar": "^3.3.1", "@malept/cross-spawn-promise": "^2.0.0", "debug": "^4.3.1", "dir-compare": "^4.2.0", "fs-extra": "^11.1.1", "minimatch": "^9.0.3", "plist": "^3.1.0" } }, "sha512-Wn9sPYIVFRFl5HmwMJkARCCf7rqK/EurkfQ/rJZ14mHP3iYTjZSIOSVonEAnhWeAXwtw7zOekGRlc6yTtZ0t+g=="], "@electron/windows-sign": ["@electron/windows-sign@1.2.2", "", { "dependencies": { "cross-dirname": "^0.1.0", "debug": "^4.3.4", "fs-extra": "^11.1.1", "minimist": "^1.2.8", "postject": "^1.0.0-alpha.6" }, "bin": { "electron-windows-sign": "bin/electron-windows-sign.js" } }, "sha512-dfZeox66AvdPtb2lD8OsIIQh12Tp0GNCRUDfBHIKGpbmopZto2/A8nSpYYLoedPIHpqkeblZ/k8OV0Gy7PYuyQ=="], - "@emnapi/runtime": ["@emnapi/runtime@1.7.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA=="], + "@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="], "@epic-web/invariant": ["@epic-web/invariant@1.0.0", "", {}, "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA=="], @@ -778,8 +775,6 @@ "@fumadocs/ui": ["@fumadocs/ui@16.4.7", "", { "dependencies": { "next-themes": "^0.4.6", "postcss-selector-parser": "^7.1.1", "tailwind-merge": "^3.4.0" }, "peerDependencies": { "@types/react": "*", "fumadocs-core": "16.4.7", "next": "16.x.x", "react": "^19.2.0", "react-dom": "^19.2.0", "tailwindcss": "^4.0.0" }, "optionalPeers": ["@types/react", "next", "tailwindcss"] }, "sha512-NnkMIN5BzBRh2OzA9rp2SgbGEkEwfCfq0sE4vq2n+GkIDIggicGYUNgSl2gtIBQsKYKP/a4/0wrkQKdq4eUJlw=="], - "@gar/promisify": ["@gar/promisify@1.1.3", "", {}, "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw=="], - "@graphql-typed-document-node/core": ["@graphql-typed-document-node/core@3.2.0", "", { "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ=="], "@hookform/resolvers": ["@hookform/resolvers@5.2.2", "", { "dependencies": { "@standard-schema/utils": "^0.3.0" }, "peerDependencies": { "react-hook-form": "^7.55.0" } }, "sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA=="], @@ -844,6 +839,8 @@ "@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="], + "@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], @@ -860,7 +857,7 @@ "@kwsites/promise-deferred": ["@kwsites/promise-deferred@1.1.1", "", {}, "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw=="], - "@linear/sdk": ["@linear/sdk@68.1.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.0", "graphql": "^15.4.0" } }, "sha512-I6MMle0hXR8SC2KVaDHt+vQvGDSQQwhfA9eq17hAL1y1Sf+7aGpaCXzMx3S4wcD9fLS5LZxd7aY8nAiTYHjoEg=="], + "@linear/sdk": ["@linear/sdk@68.1.1", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.0", "graphql": "^15.4.0" } }, "sha512-6IDbyEGsOFORRrG9fL9oQkZ1FAbdtV4W1qfT82gYPVh4UzefXQwNpljgR3Nsm1Tb11cZyf3reoJpPFqGcj01zw=="], "@malept/cross-spawn-promise": ["@malept/cross-spawn-promise@2.0.0", "", { "dependencies": { "cross-spawn": "^7.0.1" } }, "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg=="], @@ -882,23 +879,23 @@ "@neondatabase/serverless": ["@neondatabase/serverless@1.0.2", "", { "dependencies": { "@types/node": "^22.15.30", "@types/pg": "^8.8.0" } }, "sha512-I5sbpSIAHiB+b6UttofhrN/UJXII+4tZPAq1qugzwCwLIL8EZLV7F/JyHUrEIiGgQpEXzpnjlJ+zwcEhheGvCw=="], - "@next/env": ["@next/env@16.0.10", "", {}, "sha512-8tuaQkyDVgeONQ1MeT9Mkk8pQmZapMKFh5B+OrFUlG3rVmYTXcXlBetBgTurKXGaIZvkoqRT9JL5K3phXcgang=="], + "@next/env": ["@next/env@16.1.1", "", {}, "sha512-3oxyM97Sr2PqiVyMyrZUtrtM3jqqFxOQJVuKclDsgj/L728iZt/GyslkN4NwarledZATCenbk4Offjk1hQmaAA=="], - "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.0.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-4XgdKtdVsaflErz+B5XeG0T5PeXKDdruDf3CRpnhN+8UebNa5N2H58+3GDgpn/9GBurrQ1uWW768FfscwYkJRg=="], + "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.1.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-JS3m42ifsVSJjSTzh27nW+Igfha3NdBOFScr9C80hHGrWx55pTrVL23RJbqir7k7/15SKlrLHhh/MQzqBBYrQA=="], - "@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.0.10", "", { "os": "darwin", "cpu": "x64" }, "sha512-spbEObMvRKkQ3CkYVOME+ocPDFo5UqHb8EMTS78/0mQ+O1nqE8toHJVioZo4TvebATxgA8XMTHHrScPrn68OGw=="], + "@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.1.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-hbyKtrDGUkgkyQi1m1IyD3q4I/3m9ngr+V93z4oKHrPcmxwNL5iMWORvLSGAf2YujL+6HxgVvZuCYZfLfb4bGw=="], - "@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.0.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-uQtWE3X0iGB8apTIskOMi2w/MKONrPOUCi5yLO+v3O8Mb5c7K4Q5KD1jvTpTF5gJKa3VH/ijKjKUq9O9UhwOYw=="], + "@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.1.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-/fvHet+EYckFvRLQ0jPHJCUI5/B56+2DpI1xDSvi80r/3Ez+Eaa2Yq4tJcRTaB1kqj/HrYKn8Yplm9bNoMJpwQ=="], - "@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.0.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-llA+hiDTrYvyWI21Z0L1GiXwjQaanPVQQwru5peOgtooeJ8qx3tlqRV2P7uH2pKQaUfHxI/WVarvI5oYgGxaTw=="], + "@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.1.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-MFHrgL4TXNQbBPzkKKur4Fb5ICEJa87HM7fczFs2+HWblM7mMLdco3dvyTI+QmLBU9xgns/EeeINSZD6Ar+oLg=="], - "@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.0.10", "", { "os": "linux", "cpu": "x64" }, "sha512-AK2q5H0+a9nsXbeZ3FZdMtbtu9jxW4R/NgzZ6+lrTm3d6Zb7jYrWcgjcpM1k8uuqlSy4xIyPR2YiuUr+wXsavA=="], + "@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.1.1", "", { "os": "linux", "cpu": "x64" }, "sha512-20bYDfgOQAPUkkKBnyP9PTuHiJGM7HzNBbuqmD0jiFVZ0aOldz+VnJhbxzjcSabYsnNjMPsE0cyzEudpYxsrUQ=="], - "@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.0.10", "", { "os": "linux", "cpu": "x64" }, "sha512-1TDG9PDKivNw5550S111gsO4RGennLVl9cipPhtkXIFVwo31YZ73nEbLjNC8qG3SgTz/QZyYyaFYMeY4BKZR/g=="], + "@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.1.1", "", { "os": "linux", "cpu": "x64" }, "sha512-9pRbK3M4asAHQRkwaXwu601oPZHghuSC8IXNENgbBSyImHv/zY4K5udBusgdHkvJ/Tcr96jJwQYOll0qU8+fPA=="], - "@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.0.10", "", { "os": "win32", "cpu": "arm64" }, "sha512-aEZIS4Hh32xdJQbHz121pyuVZniSNoqDVx1yIr2hy+ZwJGipeqnMZBJHyMxv2tiuAXGx6/xpTcQJ6btIiBjgmg=="], + "@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.1.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-bdfQkggaLgnmYrFkSQfsHfOhk/mCYmjnrbRCGgkMcoOBZ4n+TRRSLmT/CU5SATzlBJ9TpioUyBW/vWFXTqQRiA=="], - "@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.0.10", "", { "os": "win32", "cpu": "x64" }, "sha512-E+njfCoFLb01RAFEnGZn6ERoOqhK1Gl3Lfz1Kjnj0Ulfu7oJbuMyvBKNj/bw8XZnenHDASlygTjZICQW+rYW1Q=="], + "@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.1.1", "", { "os": "win32", "cpu": "x64" }, "sha512-Ncwbw2WJ57Al5OX0k4chM68DKhEPlrXBaSXDCi2kPi5f4d8b3ejr3RRJGfKBLrn2YJL5ezNS7w2TZLHSti8CMw=="], "@noble/ciphers": ["@noble/ciphers@2.1.1", "", {}, "sha512-bysYuiVfhxNJuldNXlFEitTVdNnYUc+XNJZd7Qm2a5j1vZHgY+fazadNFWFaMK/2vye0JVlxV3gHmC0WDfAOQw=="], @@ -910,17 +907,17 @@ "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], - "@npmcli/fs": ["@npmcli/fs@2.1.2", "", { "dependencies": { "@gar/promisify": "^1.1.3", "semver": "^7.3.5" } }, "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ=="], + "@npmcli/agent": ["@npmcli/agent@3.0.0", "", { "dependencies": { "agent-base": "^7.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.1", "lru-cache": "^10.0.1", "socks-proxy-agent": "^8.0.3" } }, "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q=="], - "@npmcli/move-file": ["@npmcli/move-file@2.0.1", "", { "dependencies": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" } }, "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ=="], + "@npmcli/fs": ["@npmcli/fs@4.0.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q=="], "@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="], "@opentelemetry/api-logs": ["@opentelemetry/api-logs@0.208.0", "", { "dependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg=="], - "@opentelemetry/context-async-hooks": ["@opentelemetry/context-async-hooks@2.2.0", "", { "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-qRkLWiUEZNAmYapZ7KGS5C4OmBLcP/H2foXeOEaowYCR0wi89fHejrfYfbuLVCMLp/dWZXKvQusdbUEZjERfwQ=="], + "@opentelemetry/context-async-hooks": ["@opentelemetry/context-async-hooks@2.4.0", "", { "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-jn0phJ+hU7ZuvaoZE/8/Euw3gvHJrn2yi+kXrymwObEPVPjtwCmkvXDRQCWli+fCTTF/aSOtXaLr7CLIvv3LQg=="], - "@opentelemetry/core": ["@opentelemetry/core@2.2.0", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw=="], + "@opentelemetry/core": ["@opentelemetry/core@2.4.0", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-KtcyFHssTn5ZgDu6SXmUznS80OFs/wN7y6MyFRRcKU6TOw8hNcGxKvt8hsdaLJfhzUszNSjURetq5Qpkad14Gw=="], "@opentelemetry/instrumentation": ["@opentelemetry/instrumentation@0.208.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.208.0", "import-in-the-middle": "^2.0.0", "require-in-the-middle": "^8.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-Eju0L4qWcQS+oXxi6pgh7zvE2byogAkcsVv0OjHF/97iOz1N/aKE6etSGowYkie+YA1uo6DNwdSxaaNnLvcRlA=="], @@ -970,9 +967,9 @@ "@opentelemetry/redis-common": ["@opentelemetry/redis-common@0.38.2", "", {}, "sha512-1BCcU93iwSRZvDAgwUxC/DV4T/406SkMfxGqu5ojc3AvNI+I9GhV7v0J1HljsczuuhcnFLYqD5VmwVXfCGHzxA=="], - "@opentelemetry/resources": ["@opentelemetry/resources@2.2.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A=="], + "@opentelemetry/resources": ["@opentelemetry/resources@2.4.0", "", { "dependencies": { "@opentelemetry/core": "2.4.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-RWvGLj2lMDZd7M/5tjkI/2VHMpXebLgPKvBUd9LRasEWR2xAynDwEYZuLvY9P2NGG73HF07jbbgWX2C9oavcQg=="], - "@opentelemetry/sdk-trace-base": ["@opentelemetry/sdk-trace-base@2.2.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-xWQgL0Bmctsalg6PaXExmzdedSp3gyKV8mQBwK/j9VGdCDu2fmXIb2gAehBKbkXCpJ4HPkgv3QfoJWRT4dHWbw=="], + "@opentelemetry/sdk-trace-base": ["@opentelemetry/sdk-trace-base@2.4.0", "", { "dependencies": { "@opentelemetry/core": "2.4.0", "@opentelemetry/resources": "2.4.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-WH0xXkz/OHORDLKqaxcUZS0X+t1s7gGlumr2ebiEgNZQl2b0upK2cdoD0tatf7l8iP74woGJ/Kmxe82jdvcWRw=="], "@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.38.0", "", {}, "sha512-kocjix+/sSggfJhwXqClZ3i9Y/MI0fp7b+g7kCRm6psy2dsf8uApTRclwG18h8Avm7C9+fnt+O36PspJ/OzoWg=="], @@ -1146,7 +1143,7 @@ "@react-three/drei": ["@react-three/drei@10.7.7", "", { "dependencies": { "@babel/runtime": "^7.26.0", "@mediapipe/tasks-vision": "0.10.17", "@monogrid/gainmap-js": "^3.0.6", "@use-gesture/react": "^10.3.1", "camera-controls": "^3.1.0", "cross-env": "^7.0.3", "detect-gpu": "^5.0.56", "glsl-noise": "^0.0.0", "hls.js": "^1.5.17", "maath": "^0.10.8", "meshline": "^3.3.1", "stats-gl": "^2.2.8", "stats.js": "^0.17.0", "suspend-react": "^0.1.3", "three-mesh-bvh": "^0.8.3", "three-stdlib": "^2.35.6", "troika-three-text": "^0.52.4", "tunnel-rat": "^0.1.2", "use-sync-external-store": "^1.4.0", "utility-types": "^3.11.0", "zustand": "^5.0.1" }, "peerDependencies": { "@react-three/fiber": "^9.0.0", "react": "^19", "react-dom": "^19", "three": ">=0.159" }, "optionalPeers": ["react-dom"] }, "sha512-ff+J5iloR0k4tC++QtD/j9u3w5fzfgFAWDtAGQah9pF2B1YgOq/5JxqY0/aVoQG5r3xSZz0cv5tk2YuBob4xEQ=="], - "@react-three/fiber": ["@react-three/fiber@9.4.2", "", { "dependencies": { "@babel/runtime": "^7.17.8", "@types/react-reconciler": "^0.32.0", "@types/webxr": "*", "base64-js": "^1.5.1", "buffer": "^6.0.3", "its-fine": "^2.0.0", "react-reconciler": "^0.31.0", "react-use-measure": "^2.1.7", "scheduler": "^0.25.0", "suspend-react": "^0.1.3", "use-sync-external-store": "^1.4.0", "zustand": "^5.0.3" }, "peerDependencies": { "expo": ">=43.0", "expo-asset": ">=8.4", "expo-file-system": ">=11.0", "expo-gl": ">=11.0", "react": "^19.0.0", "react-dom": "^19.0.0", "react-native": ">=0.78", "three": ">=0.156" }, "optionalPeers": ["expo", "expo-asset", "expo-file-system", "expo-gl", "react-dom", "react-native"] }, "sha512-H4B4+FDNHpvIb4FmphH4ubxOfX5bxmfOw0+3pkQwR9u9wFiyMS7wUDkNn0m4RqQuiLWeia9jfN1eBvtyAVGEog=="], + "@react-three/fiber": ["@react-three/fiber@9.5.0", "", { "dependencies": { "@babel/runtime": "^7.17.8", "@types/webxr": "*", "base64-js": "^1.5.1", "buffer": "^6.0.3", "its-fine": "^2.0.0", "react-use-measure": "^2.1.7", "scheduler": "^0.27.0", "suspend-react": "^0.1.3", "use-sync-external-store": "^1.4.0", "zustand": "^5.0.3" }, "peerDependencies": { "expo": ">=43.0", "expo-asset": ">=8.4", "expo-file-system": ">=11.0", "expo-gl": ">=11.0", "react": ">=19 <19.3", "react-dom": ">=19 <19.3", "react-native": ">=0.78", "three": ">=0.156" }, "optionalPeers": ["expo", "expo-asset", "expo-file-system", "expo-gl", "react-dom", "react-native"] }, "sha512-FiUzfYW4wB1+PpmsE47UM+mCads7j2+giRBltfwH7SNhah95rqJs3ltEs9V3pP8rYdS0QlNne+9Aj8dS/SiaIA=="], "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.53", "", {}, "sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ=="], @@ -1154,55 +1151,61 @@ "@rollup/pluginutils": ["@rollup/pluginutils@5.3.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q=="], - "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.53.3", "", { "os": "android", "cpu": "arm" }, "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w=="], + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.55.1", "", { "os": "android", "cpu": "arm" }, "sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg=="], + + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.55.1", "", { "os": "android", "cpu": "arm64" }, "sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg=="], + + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.55.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg=="], + + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.55.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ=="], - "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.53.3", "", { "os": "android", "cpu": "arm64" }, "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w=="], + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.55.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg=="], - "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.53.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA=="], + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.55.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw=="], - "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.53.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ=="], + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.55.1", "", { "os": "linux", "cpu": "arm" }, "sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ=="], - "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.53.3", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w=="], + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.55.1", "", { "os": "linux", "cpu": "arm" }, "sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg=="], - "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.53.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q=="], + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.55.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ=="], - "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.53.3", "", { "os": "linux", "cpu": "arm" }, "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw=="], + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.55.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA=="], - "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.53.3", "", { "os": "linux", "cpu": "arm" }, "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg=="], + "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.55.1", "", { "os": "linux", "cpu": "none" }, "sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g=="], - "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.53.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w=="], + "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.55.1", "", { "os": "linux", "cpu": "none" }, "sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw=="], - "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.53.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A=="], + "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.55.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw=="], - "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.53.3", "", { "os": "linux", "cpu": "none" }, "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g=="], + "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.55.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw=="], - "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.53.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw=="], + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.55.1", "", { "os": "linux", "cpu": "none" }, "sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw=="], - "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.53.3", "", { "os": "linux", "cpu": "none" }, "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g=="], + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.55.1", "", { "os": "linux", "cpu": "none" }, "sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg=="], - "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.53.3", "", { "os": "linux", "cpu": "none" }, "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A=="], + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.55.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg=="], - "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.53.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg=="], + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.55.1", "", { "os": "linux", "cpu": "x64" }, "sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg=="], - "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.53.3", "", { "os": "linux", "cpu": "x64" }, "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w=="], + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.55.1", "", { "os": "linux", "cpu": "x64" }, "sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w=="], - "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.53.3", "", { "os": "linux", "cpu": "x64" }, "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q=="], + "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.55.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg=="], - "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.53.3", "", { "os": "none", "cpu": "arm64" }, "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw=="], + "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.55.1", "", { "os": "none", "cpu": "arm64" }, "sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw=="], - "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.53.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw=="], + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.55.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g=="], - "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.53.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA=="], + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.55.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA=="], - "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.53.3", "", { "os": "win32", "cpu": "x64" }, "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg=="], + "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.55.1", "", { "os": "win32", "cpu": "x64" }, "sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg=="], - "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.53.3", "", { "os": "win32", "cpu": "x64" }, "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ=="], + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.55.1", "", { "os": "win32", "cpu": "x64" }, "sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw=="], "@sec-ant/readable-stream": ["@sec-ant/readable-stream@0.4.1", "", {}, "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg=="], "@selderee/plugin-htmlparser2": ["@selderee/plugin-htmlparser2@0.11.0", "", { "dependencies": { "domhandler": "^5.0.3", "selderee": "^0.11.0" } }, "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ=="], - "@sentry-internal/browser-utils": ["@sentry-internal/browser-utils@10.32.1", "", { "dependencies": { "@sentry/core": "10.32.1" } }, "sha512-sjLLep1es3rTkbtAdTtdpc/a6g7v7bK5YJiZJsUigoJ4NTiFeMI5uIDCxbH/tjJ1q23YE1LzVn7T96I+qBRjHA=="], + "@sentry-internal/browser-utils": ["@sentry-internal/browser-utils@10.34.0", "", { "dependencies": { "@sentry/core": "10.34.0" } }, "sha512-0YNr60rGHyedmwkO0lbDBjNx2KAmT3kWamjaqu7Aw+jsESoPLgt+fzaTVvUBvkftBDui2PeTSzXm/nqzssctYg=="], "@sentry-internal/feedback": ["@sentry-internal/feedback@10.29.0", "", { "dependencies": { "@sentry/core": "10.29.0" } }, "sha512-Y7IRsNeS99cEONu1mZWZc3HvbjNnu59Hgymm0swFFKbdgbCgdT6l85kn2oLsuq4Ew8Dw/pL/Sgpwsl9UgYFpUg=="], @@ -1210,11 +1213,11 @@ "@sentry-internal/replay-canvas": ["@sentry-internal/replay-canvas@10.29.0", "", { "dependencies": { "@sentry-internal/replay": "10.29.0", "@sentry/core": "10.29.0" } }, "sha512-typY4JrpAQQGPuSyd/BD8+nNCbvTV2UVvKzr+iKgI0m1qc4Dz8tHZ4Nfais2Z8eYn/pL1kqVQN5ERTmJoYFdIw=="], - "@sentry/babel-plugin-component-annotate": ["@sentry/babel-plugin-component-annotate@4.6.1", "", {}, "sha512-aSIk0vgBqv7PhX6/Eov+vlI4puCE0bRXzUG5HdCsHBpAfeMkI8Hva6kSOusnzKqs8bf04hU7s3Sf0XxGTj/1AA=="], + "@sentry/babel-plugin-component-annotate": ["@sentry/babel-plugin-component-annotate@4.6.2", "", {}, "sha512-6VTjLJXtIHKwxMmThtZKwi1+hdklLNzlbYH98NhbH22/Vzb/c6BlSD2b5A0NGN9vFB807rD4x4tuP+Su7BxQXQ=="], "@sentry/browser": ["@sentry/browser@10.29.0", "", { "dependencies": { "@sentry-internal/browser-utils": "10.29.0", "@sentry-internal/feedback": "10.29.0", "@sentry-internal/replay": "10.29.0", "@sentry-internal/replay-canvas": "10.29.0", "@sentry/core": "10.29.0" } }, "sha512-XdbyIR6F4qoR9Z1JCWTgunVcTJjS9p2Th+v4wYs4ME+ZdLC4tuKKmRgYg3YdSIWCn1CBfIgdI6wqETSf7H6Njw=="], - "@sentry/bundler-plugin-core": ["@sentry/bundler-plugin-core@4.6.1", "", { "dependencies": { "@babel/core": "^7.18.5", "@sentry/babel-plugin-component-annotate": "4.6.1", "@sentry/cli": "^2.57.0", "dotenv": "^16.3.1", "find-up": "^5.0.0", "glob": "^10.5.0", "magic-string": "0.30.8", "unplugin": "1.0.1" } }, "sha512-WPeRbnMXm927m4Kr69NTArPfI+p5/34FHftdCRI3LFPMyhZDzz6J3wLy4hzaVUgmMf10eLzmq2HGEMvpQmdynA=="], + "@sentry/bundler-plugin-core": ["@sentry/bundler-plugin-core@4.6.2", "", { "dependencies": { "@babel/core": "^7.18.5", "@sentry/babel-plugin-component-annotate": "4.6.2", "@sentry/cli": "^2.57.0", "dotenv": "^16.3.1", "find-up": "^5.0.0", "glob": "^10.5.0", "magic-string": "0.30.8", "unplugin": "1.0.1" } }, "sha512-JkOc3JkVzi/fbXsFp8R9uxNKmBrPRaU4Yu4y1i3ihWfugqymsIYaN0ixLENZbGk2j4xGHIk20PAJzBJqBMTHew=="], "@sentry/cli": ["@sentry/cli@2.58.4", "", { "dependencies": { "https-proxy-agent": "^5.0.0", "node-fetch": "^2.6.7", "progress": "^2.0.3", "proxy-from-env": "^1.1.0", "which": "^2.0.2" }, "optionalDependencies": { "@sentry/cli-darwin": "2.58.4", "@sentry/cli-linux-arm": "2.58.4", "@sentry/cli-linux-arm64": "2.58.4", "@sentry/cli-linux-i686": "2.58.4", "@sentry/cli-linux-x64": "2.58.4", "@sentry/cli-win32-arm64": "2.58.4", "@sentry/cli-win32-i686": "2.58.4", "@sentry/cli-win32-x64": "2.58.4" }, "bin": { "sentry-cli": "bin/sentry-cli" } }, "sha512-ArDrpuS8JtDYEvwGleVE+FgR+qHaOp77IgdGSacz6SZy6Lv90uX0Nu4UrHCQJz8/xwIcNxSqnN22lq0dH4IqTg=="], @@ -1234,39 +1237,39 @@ "@sentry/cli-win32-x64": ["@sentry/cli-win32-x64@2.58.4", "", { "os": "win32", "cpu": "x64" }, "sha512-cSzN4PjM1RsCZ4pxMjI0VI7yNCkxiJ5jmWncyiwHXGiXrV1eXYdQ3n1LhUYLZ91CafyprR0OhDcE+RVZ26Qb5w=="], - "@sentry/core": ["@sentry/core@10.32.1", "", {}, "sha512-PH2ldpSJlhqsMj2vCTyU0BI2Fx1oIDhm7Izo5xFALvjVCS0gmlqHt1udu6YlKn8BtpGH6bGzssvv5APrk+OdPQ=="], + "@sentry/core": ["@sentry/core@10.34.0", "", {}, "sha512-4FFpYBMf0VFdPcsr4grDYDOR87mRu6oCfb51oQjU/Pndmty7UgYo0Bst3LEC/8v0SpytBtzXq+Wx/fkwulBesg=="], "@sentry/electron": ["@sentry/electron@7.5.0", "", { "dependencies": { "@sentry/browser": "10.29.0", "@sentry/core": "10.29.0", "@sentry/node": "10.29.0" }, "peerDependencies": { "@sentry/node-native": "10.29.0" }, "optionalPeers": ["@sentry/node-native"] }, "sha512-88t/YsB5iO75faKdd7lIuJkwp9FGKgFlkDuaSJhsJiVcjlywkn8CwUbctAbS0gu6Suc0raHCF4ULvGyksKAoww=="], - "@sentry/nextjs": ["@sentry/nextjs@10.32.1", "", { "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/semantic-conventions": "^1.37.0", "@rollup/plugin-commonjs": "28.0.1", "@sentry-internal/browser-utils": "10.32.1", "@sentry/bundler-plugin-core": "^4.6.1", "@sentry/core": "10.32.1", "@sentry/node": "10.32.1", "@sentry/opentelemetry": "10.32.1", "@sentry/react": "10.32.1", "@sentry/vercel-edge": "10.32.1", "@sentry/webpack-plugin": "^4.6.1", "resolve": "1.22.8", "rollup": "^4.35.0", "stacktrace-parser": "^0.1.10" }, "peerDependencies": { "next": "^13.2.0 || ^14.0 || ^15.0.0-rc.0 || ^16.0.0-0" } }, "sha512-MlgQiKg9P2clKeyH+ZLdmNiMNfTMs/2DBK9V/enLZvYJd1sy5hmrkAV/NiLxVP0uXAeMEVtrgFMIb64cH7ZcXQ=="], + "@sentry/nextjs": ["@sentry/nextjs@10.34.0", "", { "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/semantic-conventions": "^1.37.0", "@rollup/plugin-commonjs": "28.0.1", "@sentry-internal/browser-utils": "10.34.0", "@sentry/bundler-plugin-core": "^4.6.1", "@sentry/core": "10.34.0", "@sentry/node": "10.34.0", "@sentry/opentelemetry": "10.34.0", "@sentry/react": "10.34.0", "@sentry/vercel-edge": "10.34.0", "@sentry/webpack-plugin": "^4.6.1", "rollup": "^4.35.0", "stacktrace-parser": "^0.1.10" }, "peerDependencies": { "next": "^13.2.0 || ^14.0 || ^15.0.0-rc.0 || ^16.0.0-0" } }, "sha512-Dozk4j2WSJkDy1phsdzFtPBaCzHuj1ESAMOhXim8/RVPGusxSc3z68+Sf3qjDKYjVK+8TsMQZHr+8j2WCTAKgQ=="], - "@sentry/node": ["@sentry/node@10.32.1", "", { "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-async-hooks": "^2.2.0", "@opentelemetry/core": "^2.2.0", "@opentelemetry/instrumentation": "^0.208.0", "@opentelemetry/instrumentation-amqplib": "0.55.0", "@opentelemetry/instrumentation-connect": "0.52.0", "@opentelemetry/instrumentation-dataloader": "0.26.0", "@opentelemetry/instrumentation-express": "0.57.0", "@opentelemetry/instrumentation-fs": "0.28.0", "@opentelemetry/instrumentation-generic-pool": "0.52.0", "@opentelemetry/instrumentation-graphql": "0.56.0", "@opentelemetry/instrumentation-hapi": "0.55.0", "@opentelemetry/instrumentation-http": "0.208.0", "@opentelemetry/instrumentation-ioredis": "0.56.0", "@opentelemetry/instrumentation-kafkajs": "0.18.0", "@opentelemetry/instrumentation-knex": "0.53.0", "@opentelemetry/instrumentation-koa": "0.57.0", "@opentelemetry/instrumentation-lru-memoizer": "0.53.0", "@opentelemetry/instrumentation-mongodb": "0.61.0", "@opentelemetry/instrumentation-mongoose": "0.55.0", "@opentelemetry/instrumentation-mysql": "0.54.0", "@opentelemetry/instrumentation-mysql2": "0.55.0", "@opentelemetry/instrumentation-pg": "0.61.0", "@opentelemetry/instrumentation-redis": "0.57.0", "@opentelemetry/instrumentation-tedious": "0.27.0", "@opentelemetry/instrumentation-undici": "0.19.0", "@opentelemetry/resources": "^2.2.0", "@opentelemetry/sdk-trace-base": "^2.2.0", "@opentelemetry/semantic-conventions": "^1.37.0", "@prisma/instrumentation": "6.19.0", "@sentry/core": "10.32.1", "@sentry/node-core": "10.32.1", "@sentry/opentelemetry": "10.32.1", "import-in-the-middle": "^2", "minimatch": "^9.0.0" } }, "sha512-oxlybzt8QW0lx/QaEj1DcvZDRXkgouewFelu/10dyUwv5So3YvipfvWInda+yMLmn25OggbloDQ0gyScA2jU3g=="], + "@sentry/node": ["@sentry/node@10.34.0", "", { "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-async-hooks": "^2.2.0", "@opentelemetry/core": "^2.2.0", "@opentelemetry/instrumentation": "^0.208.0", "@opentelemetry/instrumentation-amqplib": "0.55.0", "@opentelemetry/instrumentation-connect": "0.52.0", "@opentelemetry/instrumentation-dataloader": "0.26.0", "@opentelemetry/instrumentation-express": "0.57.0", "@opentelemetry/instrumentation-fs": "0.28.0", "@opentelemetry/instrumentation-generic-pool": "0.52.0", "@opentelemetry/instrumentation-graphql": "0.56.0", "@opentelemetry/instrumentation-hapi": "0.55.0", "@opentelemetry/instrumentation-http": "0.208.0", "@opentelemetry/instrumentation-ioredis": "0.56.0", "@opentelemetry/instrumentation-kafkajs": "0.18.0", "@opentelemetry/instrumentation-knex": "0.53.0", "@opentelemetry/instrumentation-koa": "0.57.0", "@opentelemetry/instrumentation-lru-memoizer": "0.53.0", "@opentelemetry/instrumentation-mongodb": "0.61.0", "@opentelemetry/instrumentation-mongoose": "0.55.0", "@opentelemetry/instrumentation-mysql": "0.54.0", "@opentelemetry/instrumentation-mysql2": "0.55.0", "@opentelemetry/instrumentation-pg": "0.61.0", "@opentelemetry/instrumentation-redis": "0.57.0", "@opentelemetry/instrumentation-tedious": "0.27.0", "@opentelemetry/instrumentation-undici": "0.19.0", "@opentelemetry/resources": "^2.2.0", "@opentelemetry/sdk-trace-base": "^2.2.0", "@opentelemetry/semantic-conventions": "^1.37.0", "@prisma/instrumentation": "6.19.0", "@sentry/core": "10.34.0", "@sentry/node-core": "10.34.0", "@sentry/opentelemetry": "10.34.0", "import-in-the-middle": "^2.0.1", "minimatch": "^9.0.0" } }, "sha512-bEOyH97HuVtWZYAZ5mp0NhYNc+n6QCfiKuLee2P75n2kt4cIPTGvLOSdUwwjllf795uOdKZJuM1IUN0W+YMcVg=="], - "@sentry/node-core": ["@sentry/node-core@10.32.1", "", { "dependencies": { "@apm-js-collab/tracing-hooks": "^0.3.1", "@sentry/core": "10.32.1", "@sentry/opentelemetry": "10.32.1", "import-in-the-middle": "^2" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.1.0 || ^2.2.0", "@opentelemetry/core": "^1.30.1 || ^2.1.0 || ^2.2.0", "@opentelemetry/instrumentation": ">=0.57.1 <1", "@opentelemetry/resources": "^1.30.1 || ^2.1.0 || ^2.2.0", "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0 || ^2.2.0", "@opentelemetry/semantic-conventions": "^1.37.0" } }, "sha512-w56rxdBanBKc832zuwnE+zNzUQ19fPxfHEtOhK8JGPu3aSwQYcIxwz9z52lOx3HN7k/8Fj5694qlT3x/PokhRw=="], + "@sentry/node-core": ["@sentry/node-core@10.34.0", "", { "dependencies": { "@apm-js-collab/tracing-hooks": "^0.3.1", "@sentry/core": "10.34.0", "@sentry/opentelemetry": "10.34.0", "import-in-the-middle": "^2.0.1" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.1.0 || ^2.2.0", "@opentelemetry/core": "^1.30.1 || ^2.1.0 || ^2.2.0", "@opentelemetry/instrumentation": ">=0.57.1 <1", "@opentelemetry/resources": "^1.30.1 || ^2.1.0 || ^2.2.0", "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0 || ^2.2.0", "@opentelemetry/semantic-conventions": "^1.37.0" } }, "sha512-FrGfC8GzD1cnZDO3zwQ4cjyoY1ZwNHvZbXSvXRYxpjhXidZhvaPurjgLRSB0xGaFgoemmOp1ufsx/w6fQOGA6Q=="], - "@sentry/opentelemetry": ["@sentry/opentelemetry@10.32.1", "", { "dependencies": { "@sentry/core": "10.32.1" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.1.0 || ^2.2.0", "@opentelemetry/core": "^1.30.1 || ^2.1.0 || ^2.2.0", "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0 || ^2.2.0", "@opentelemetry/semantic-conventions": "^1.37.0" } }, "sha512-YLssSz5Y+qPvufrh2cDaTXDoXU8aceOhB+YTjT8/DLF6SOj7Tzen52aAcjNaifawaxEsLCC8O+B+A2iA+BllvA=="], + "@sentry/opentelemetry": ["@sentry/opentelemetry@10.34.0", "", { "dependencies": { "@sentry/core": "10.34.0" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.1.0 || ^2.2.0", "@opentelemetry/core": "^1.30.1 || ^2.1.0 || ^2.2.0", "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0 || ^2.2.0", "@opentelemetry/semantic-conventions": "^1.37.0" } }, "sha512-uKuULBOmdVu3bYdD8doMLqKgN0PP3WWtI7Shu11P9PVrhSNT4U9yM9Z6v1aFlQcbrgyg3LynZuXs8lyjt90UbA=="], - "@sentry/react": ["@sentry/react@10.32.1", "", { "dependencies": { "@sentry/browser": "10.32.1", "@sentry/core": "10.32.1", "hoist-non-react-statics": "^3.3.2" }, "peerDependencies": { "react": "^16.14.0 || 17.x || 18.x || 19.x" } }, "sha512-/tX0HeACbAmVP57x8txTrGk/U3fa9pDBaoAtlOrnPv5VS/aC5SGkehXWeTGSAa+ahlOWwp3IF8ILVXRiOoG/Vg=="], + "@sentry/react": ["@sentry/react@10.34.0", "", { "dependencies": { "@sentry/browser": "10.34.0", "@sentry/core": "10.34.0" }, "peerDependencies": { "react": "^16.14.0 || 17.x || 18.x || 19.x" } }, "sha512-LDpg9WDrEwo6lr/YOAA54id/g5D1PGKEIiOGxqRZbBVyjzrsquwzhSG2CMqnp+YO6lz/r96LWuqm2cvfpht2zA=="], - "@sentry/vercel-edge": ["@sentry/vercel-edge@10.32.1", "", { "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/resources": "^2.2.0", "@sentry/core": "10.32.1" } }, "sha512-3hrc7TVs4ZeYSCOZdgmv9D1Bke2osnImfupceW8THecNv3uEUjYbrC2UkS/TFMiVHc9qpYzUnKbsGezMp3Bcaw=="], + "@sentry/vercel-edge": ["@sentry/vercel-edge@10.34.0", "", { "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/resources": "^2.2.0", "@sentry/core": "10.34.0" } }, "sha512-yphK7YX8zR1Gbt51AVakCfNHMjsrXdNNCjRrnhxKIfVnx7OrVmmG7iFFnOCqNRttCxA1HN+2KiM8TSSFE6a98Q=="], - "@sentry/webpack-plugin": ["@sentry/webpack-plugin@4.6.1", "", { "dependencies": { "@sentry/bundler-plugin-core": "4.6.1", "unplugin": "1.0.1", "uuid": "^9.0.0" }, "peerDependencies": { "webpack": ">=4.40.0" } }, "sha512-CJgT/t2pQWsPsMx9VJ86goU/orCQhL2HhDj5ZYBol6fPPoEGeTqKOPCnv/xsbCAfGSp1uHpyRLTA/Gx96u7VVA=="], + "@sentry/webpack-plugin": ["@sentry/webpack-plugin@4.6.2", "", { "dependencies": { "@sentry/bundler-plugin-core": "4.6.2", "unplugin": "1.0.1", "uuid": "^9.0.0" }, "peerDependencies": { "webpack": ">=4.40.0" } }, "sha512-uyb4nAqstVvO6ep86TQRlSxuynYhFec/HYfrA8wN5qYLx31gJQsOiuAeEzocJ2GGrhJq/ySH9nYfcnpjgk4J2w=="], - "@shikijs/core": ["@shikijs/core@3.19.0", "", { "dependencies": { "@shikijs/types": "3.19.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-L7SrRibU7ZoYi1/TrZsJOFAnnHyLTE1SwHG1yNWjZIVCqjOEmCSuK2ZO9thnRbJG6TOkPp+Z963JmpCNw5nzvA=="], + "@shikijs/core": ["@shikijs/core@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-AXSQu/2n1UIQekY8euBJlvFYZIw0PHY63jUzGbrOma4wPxzznJXTXkri+QcHeBNaFxiiOljKxxJkVSoB3PjbyA=="], - "@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.19.0", "", { "dependencies": { "@shikijs/types": "3.19.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-ZfWJNm2VMhKkQIKT9qXbs76RRcT0SF/CAvEz0+RkpUDAoDaCx0uFdCGzSRiD9gSlhm6AHkjdieOBJMaO2eC1rQ=="], + "@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-ATwv86xlbmfD9n9gKRiwuPpWgPENAWCLwYCGz9ugTJlsO2kOzhOkvoyV/UD+tJ0uT7YRyD530x6ugNSffmvIiQ=="], - "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.19.0", "", { "dependencies": { "@shikijs/types": "3.19.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-1hRxtYIJfJSZeM5ivbUXv9hcJP3PWRo5prG/V2sWwiubUKTa+7P62d2qxCW8jiVFX4pgRHhnHNp+qeR7Xl+6kg=="], + "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-OYknTCct6qiwpQDqDdf3iedRdzj6hFlOPv5hMvI+hkWfCKs5mlJ4TXziBG9nyabLwGulrUjHiCq3xCspSzErYQ=="], - "@shikijs/langs": ["@shikijs/langs@3.19.0", "", { "dependencies": { "@shikijs/types": "3.19.0" } }, "sha512-dBMFzzg1QiXqCVQ5ONc0z2ebyoi5BKz+MtfByLm0o5/nbUu3Iz8uaTCa5uzGiscQKm7lVShfZHU1+OG3t5hgwg=="], + "@shikijs/langs": ["@shikijs/langs@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0" } }, "sha512-g6mn5m+Y6GBJ4wxmBYqalK9Sp0CFkUqfNzUy2pJglUginz6ZpWbaWjDB4fbQ/8SHzFjYbtU6Ddlp1pc+PPNDVA=="], "@shikijs/rehype": ["@shikijs/rehype@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0", "@types/hast": "^3.0.4", "hast-util-to-string": "^3.0.1", "shiki": "3.21.0", "unified": "^11.0.5", "unist-util-visit": "^5.0.0" } }, "sha512-fTQvwsZL67QdosMFdTgQ5SNjW3nxaPplRy//312hqOctRbIwviTV0nAbhv3NfnztHXvFli2zLYNKsTz/f9tbpQ=="], - "@shikijs/themes": ["@shikijs/themes@3.19.0", "", { "dependencies": { "@shikijs/types": "3.19.0" } }, "sha512-H36qw+oh91Y0s6OlFfdSuQ0Ld+5CgB/VE6gNPK+Hk4VRbVG/XQgkjnt4KzfnnoO6tZPtKJKHPjwebOCfjd6F8A=="], + "@shikijs/themes": ["@shikijs/themes@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0" } }, "sha512-BAE4cr9EDiZyYzwIHEk7JTBJ9CzlPuM4PchfcA5ao1dWXb25nv6hYsoDiBq2aZK9E3dlt3WB78uI96UESD+8Mw=="], "@shikijs/transformers": ["@shikijs/transformers@3.21.0", "", { "dependencies": { "@shikijs/core": "3.21.0", "@shikijs/types": "3.21.0" } }, "sha512-CZwvCWWIiRRiFk9/JKzdEooakAP8mQDtBOQ1TKiCaS2E1bYtyBCOkUzS8akO34/7ufICQ29oeSfkb3tT5KtrhA=="], - "@shikijs/types": ["@shikijs/types@3.19.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-Z2hdeEQlzuntf/BZpFG8a+Fsw9UVXdML7w0o3TgSXV3yNESGon+bs9ITkQb3Ki7zxoXOOu5oJWqZ2uto06V9iQ=="], + "@shikijs/types": ["@shikijs/types@3.21.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA=="], "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="], @@ -1276,7 +1279,7 @@ "@socket.io/component-emitter": ["@socket.io/component-emitter@3.1.2", "", {}, "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA=="], - "@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="], + "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], "@standard-schema/utils": ["@standard-schema/utils@0.3.0", "", {}, "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g=="], @@ -1314,9 +1317,9 @@ "@szmarczak/http-timer": ["@szmarczak/http-timer@4.0.6", "", { "dependencies": { "defer-to-connect": "^2.0.0" } }, "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w=="], - "@t3-oss/env-core": ["@t3-oss/env-core@0.13.8", "", { "peerDependencies": { "arktype": "^2.1.0", "typescript": ">=5.0.0", "valibot": "^1.0.0-beta.7 || ^1.0.0", "zod": "^3.24.0 || ^4.0.0-beta.0" }, "optionalPeers": ["arktype", "typescript", "valibot", "zod"] }, "sha512-L1inmpzLQyYu4+Q1DyrXsGJYCXbtXjC4cICw1uAKv0ppYPQv656lhZPU91Qd1VS6SO/bou1/q5ufVzBGbNsUpw=="], + "@t3-oss/env-core": ["@t3-oss/env-core@0.13.10", "", { "peerDependencies": { "arktype": "^2.1.0", "typescript": ">=5.0.0", "valibot": "^1.0.0-beta.7 || ^1.0.0", "zod": "^3.24.0 || ^4.0.0" }, "optionalPeers": ["arktype", "typescript", "valibot", "zod"] }, "sha512-NNFfdlJ+HmPHkLi2HKy7nwuat9SIYOxei9K10lO2YlcSObDILY7mHZNSHsieIM3A0/5OOzw/P/b+yLvPdaG52g=="], - "@t3-oss/env-nextjs": ["@t3-oss/env-nextjs@0.13.8", "", { "dependencies": { "@t3-oss/env-core": "0.13.8" }, "peerDependencies": { "arktype": "^2.1.0", "typescript": ">=5.0.0", "valibot": "^1.0.0-beta.7 || ^1.0.0", "zod": "^3.24.0 || ^4.0.0-beta.0" }, "optionalPeers": ["arktype", "typescript", "valibot", "zod"] }, "sha512-QmTLnsdQJ8BiQad2W2nvV6oUpH4oMZMqnFEjhVpzU0h3sI9hn8zb8crjWJ1Amq453mGZs6A4v4ihIeBFDOrLeQ=="], + "@t3-oss/env-nextjs": ["@t3-oss/env-nextjs@0.13.10", "", { "dependencies": { "@t3-oss/env-core": "0.13.10" }, "peerDependencies": { "arktype": "^2.1.0", "typescript": ">=5.0.0", "valibot": "^1.0.0-beta.7 || ^1.0.0", "zod": "^3.24.0 || ^4.0.0" }, "optionalPeers": ["arktype", "typescript", "valibot", "zod"] }, "sha512-JfSA2WXOnvcc/uMdp31paMsfbYhhdvLLRxlwvrnlPE9bwM/n0Z+Qb9xRv48nPpvfMhOrkrTYw1I5Yc06WIKBJQ=="], "@tailwindcss/node": ["@tailwindcss/node@4.1.18", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.1.18" } }, "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ=="], @@ -1350,39 +1353,39 @@ "@tailwindcss/vite": ["@tailwindcss/vite@4.1.18", "", { "dependencies": { "@tailwindcss/node": "4.1.18", "@tailwindcss/oxide": "4.1.18", "tailwindcss": "4.1.18" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" } }, "sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA=="], - "@tanstack/db": ["@tanstack/db@0.5.16", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@tanstack/db-ivm": "0.1.14", "@tanstack/pacer-lite": "^0.1.1" }, "peerDependencies": { "typescript": ">=4.7" } }, "sha512-V4oCsGlighwgKGWldw1umaXaVYiDR0sK/1fCWictrx2lqxqmBMUEfmNtWnt0CFJXEbyRA/LF8TyFn1ooXtyZ3w=="], + "@tanstack/db": ["@tanstack/db@0.5.20", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "@tanstack/db-ivm": "0.1.16", "@tanstack/pacer-lite": "^0.2.0" }, "peerDependencies": { "typescript": ">=4.7" } }, "sha512-vpN2JlqxdkvLQq2Uc5H0+JXfVTKaAxArOZATCbiDt+NaTw1kriA20rgJRJTPBA8RxQwNmZEUWKEYfjAn7+YI+g=="], - "@tanstack/db-ivm": ["@tanstack/db-ivm@0.1.14", "", { "dependencies": { "fractional-indexing": "^3.2.0", "sorted-btree": "^1.8.1" }, "peerDependencies": { "typescript": ">=4.7" } }, "sha512-GluhFsd/Z1E/MZTf60l9dZpKNpmdxtV4izPRnj1RK6TYrhC9LMndN+ywk1VDFBrjtBq/CTShz4CilECLwVlTGg=="], + "@tanstack/db-ivm": ["@tanstack/db-ivm@0.1.16", "", { "dependencies": { "fractional-indexing": "^3.2.0", "sorted-btree": "^1.8.1" }, "peerDependencies": { "typescript": ">=4.7" } }, "sha512-DIMfUoHtAcQ1IYghU+XqprDdzToy2d6qg3R5h0DJH60XPsmRTt0qOnlu/HVZqwCP7XL/b2UhRvyR5utz/N4KGg=="], - "@tanstack/electric-db-collection": ["@tanstack/electric-db-collection@0.2.20", "", { "dependencies": { "@electric-sql/client": "^1.3.0", "@standard-schema/spec": "^1.0.0", "@tanstack/db": "0.5.16", "@tanstack/store": "^0.8.0", "debug": "^4.4.3" } }, "sha512-a11wLNiOKd187EFqwrQBbGmuyEVCbJcFoB2J2ErmANGpRC7uADvbV+1o5523W8ptT76H7exRCxTF646z98psyg=="], + "@tanstack/electric-db-collection": ["@tanstack/electric-db-collection@0.2.24", "", { "dependencies": { "@electric-sql/client": "^1.3.1", "@standard-schema/spec": "^1.1.0", "@tanstack/db": "0.5.20", "@tanstack/store": "^0.8.0", "debug": "^4.4.3" } }, "sha512-Zp758uXGAMW4D45WMAf38tilun8F5iI06G75sCT7nkqZI4gyi4t/j44FaslLjiFQrZ4VspY5YFuBGk9Iy+Ph0w=="], "@tanstack/history": ["@tanstack/history@1.145.7", "", {}, "sha512-gMo/ReTUp0a3IOcZoI3hH6PLDC2R/5ELQ7P2yu9F6aEkA0wSQh+Q4qzMrtcKvF2ut0oE+16xWCGDo/TdYd6cEQ=="], - "@tanstack/pacer-lite": ["@tanstack/pacer-lite@0.1.1", "", {}, "sha512-y/xtNPNt/YeyoVxE/JCx+T7yjEzpezmbb+toK8DDD1P4m7Kzs5YR956+7OKexG3f8aXgC3rLZl7b1V+yNUSy5w=="], + "@tanstack/pacer-lite": ["@tanstack/pacer-lite@0.2.1", "", {}, "sha512-3PouiFjR4B6x1c969/Pl4ZIJleof1M0n6fNX8NRiC9Sqv1g06CVDlEaXUR4212ycGFyfq4q+t8Gi37Xy+z34iQ=="], - "@tanstack/query-core": ["@tanstack/query-core@5.90.12", "", {}, "sha512-T1/8t5DhV/SisWjDnaiU2drl6ySvsHj1bHBCWNXd+/T+Hh1cf6JodyEYMd5sgwm+b/mETT4EV3H+zCVczCU5hg=="], + "@tanstack/query-core": ["@tanstack/query-core@5.90.17", "", {}, "sha512-hDww+RyyYhjhUfoYQ4es6pbgxY7LNiPWxt4l1nJqhByjndxJ7HIjDxTBtfvMr5HwjYavMrd+ids5g4Rfev3lVQ=="], - "@tanstack/query-devtools": ["@tanstack/query-devtools@5.91.1", "", {}, "sha512-l8bxjk6BMsCaVQH6NzQEE/bEgFy1hAs5qbgXl0xhzezlaQbPk6Mgz9BqEg2vTLPOHD8N4k+w/gdgCbEzecGyNg=="], + "@tanstack/query-devtools": ["@tanstack/query-devtools@5.92.0", "", {}, "sha512-N8D27KH1vEpVacvZgJL27xC6yPFUy0Zkezn5gnB3L3gRCxlDeSuiya7fKge8Y91uMTnC8aSxBQhcK6ocY7alpQ=="], - "@tanstack/react-db": ["@tanstack/react-db@0.1.60", "", { "dependencies": { "@tanstack/db": "0.5.16", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-Pz3pwH4vgRxlS/L3+BszINjNlIUXahJ6EqSEsYBMBT19G36GzTzyd5Qq98JaOXuu8V0dkiFWEoyEoTv3BiHcrg=="], + "@tanstack/react-db": ["@tanstack/react-db@0.1.64", "", { "dependencies": { "@tanstack/db": "0.5.20", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-XT5Z0pimU4KfRgsVb0OIX83hgEU8NE0XZRwRRYtWDzZCvlZJjMwegWMKDOS1lzRtYvj7PDoZa7zyTyGXEgi2Wg=="], - "@tanstack/react-query": ["@tanstack/react-query@5.90.12", "", { "dependencies": { "@tanstack/query-core": "5.90.12" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-graRZspg7EoEaw0a8faiUASCyJrqjKPdqJ9EwuDRUF9mEYJ1YPczI9H+/agJ0mOJkPCJDk0lsz5QTrLZ/jQ2rg=="], + "@tanstack/react-query": ["@tanstack/react-query@5.90.17", "", { "dependencies": { "@tanstack/query-core": "5.90.17" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-PGc2u9KLwohDUSchjW9MZqeDQJfJDON7y4W7REdNBgiFKxQy+Pf7eGjiFWEj5xPqKzAeHYdAb62IWI1a9UJyGQ=="], - "@tanstack/react-query-devtools": ["@tanstack/react-query-devtools@5.91.1", "", { "dependencies": { "@tanstack/query-devtools": "5.91.1" }, "peerDependencies": { "@tanstack/react-query": "^5.90.10", "react": "^18 || ^19" } }, "sha512-tRnJYwEbH0kAOuToy8Ew7bJw1lX3AjkkgSlf/vzb+NpnqmHPdWM+lA2DSdGQSLi1SU0PDRrrCI1vnZnci96CsQ=="], + "@tanstack/react-query-devtools": ["@tanstack/react-query-devtools@5.91.2", "", { "dependencies": { "@tanstack/query-devtools": "5.92.0" }, "peerDependencies": { "@tanstack/react-query": "^5.90.14", "react": "^18 || ^19" } }, "sha512-ZJ1503ay5fFeEYFUdo7LMNFzZryi6B0Cacrgr2h1JRkvikK1khgIq6Nq2EcblqEdIlgB/r7XDW8f8DQ89RuUgg=="], - "@tanstack/react-router": ["@tanstack/react-router@1.147.3", "", { "dependencies": { "@tanstack/history": "1.145.7", "@tanstack/react-store": "^0.8.0", "@tanstack/router-core": "1.147.1", "isbot": "^5.1.22", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-Fp9DoszYiIJclwxU43kyP/cqcWD418DPmV6yhmIOuVedsSMnfh2g7uRQ+bOoaWn996JjuU9yt/x48h66aCQSQA=="], + "@tanstack/react-router": ["@tanstack/react-router@1.150.0", "", { "dependencies": { "@tanstack/history": "1.145.7", "@tanstack/react-store": "^0.8.0", "@tanstack/router-core": "1.150.0", "isbot": "^5.1.22", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-k/oycTCpBT2XoEk9dNd/nNYhF0X9fLSB10lT40+NVX1TjOtBq5whksk8MT6oRnSoQ8KWeb7La3G9kFaAeSULkA=="], "@tanstack/react-store": ["@tanstack/react-store@0.8.0", "", { "dependencies": { "@tanstack/store": "0.8.0", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-1vG9beLIuB7q69skxK9r5xiLN3ztzIPfSQSs0GfeqWGO2tGIyInZx0x1COhpx97RKaONSoAb8C3dxacWksm1ow=="], "@tanstack/react-table": ["@tanstack/react-table@8.21.3", "", { "dependencies": { "@tanstack/table-core": "8.21.3" }, "peerDependencies": { "react": ">=16.8", "react-dom": ">=16.8" } }, "sha512-5nNMTSETP4ykGegmVkhjcS8tTLW6Vl4axfEGQN3v0zdHYbK4UfoqfPChclTrJ4EoK9QynqAu9oUf8VEmrpZ5Ww=="], - "@tanstack/router-cli": ["@tanstack/router-cli@1.149.0", "", { "dependencies": { "@tanstack/router-generator": "1.149.0", "chokidar": "^3.6.0", "yargs": "^17.7.2" }, "bin": { "tsr": "bin/tsr.cjs" } }, "sha512-exben9/p0nyjAlNt08xTYyK4qf1u/Ghs5zH2JPNQdkDFZn39d6j1blAWI7agoJV7799UnfEyf2ASa0fbgtwBSA=="], + "@tanstack/router-cli": ["@tanstack/router-cli@1.150.0", "", { "dependencies": { "@tanstack/router-generator": "1.150.0", "chokidar": "^3.6.0", "yargs": "^17.7.2" }, "bin": { "tsr": "bin/tsr.cjs" } }, "sha512-qzdaoYMhoi1mX7fSfev9lGkjIKmeU49dQrlgvBVnAOKjGGE8h+nOh4kSQS4L68RXp90D05jnUVG1Jj+Jd56Z6w=="], - "@tanstack/router-core": ["@tanstack/router-core@1.147.1", "", { "dependencies": { "@tanstack/history": "1.145.7", "@tanstack/store": "^0.8.0", "cookie-es": "^2.0.0", "seroval": "^1.4.1", "seroval-plugins": "^1.4.0", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" } }, "sha512-yf8o3CNgJVGO5JnIqiTe0y2eChxEM0w7TrEs1VSumL/zz2bQroYGNr1mOXJ2VeN+7YfJJwjEqq71P5CzWwMzRg=="], + "@tanstack/router-core": ["@tanstack/router-core@1.150.0", "", { "dependencies": { "@tanstack/history": "1.145.7", "@tanstack/store": "^0.8.0", "cookie-es": "^2.0.0", "seroval": "^1.4.1", "seroval-plugins": "^1.4.0", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" } }, "sha512-cAm44t/tUbfyzaDH+rE/WO4u3AgaZdpJp00xjQ4gNkC2O95ntVHq5fx+4fhtrkKpgdXoKldgk8OK66djiWpuGQ=="], - "@tanstack/router-generator": ["@tanstack/router-generator@1.149.0", "", { "dependencies": { "@tanstack/router-core": "1.147.1", "@tanstack/router-utils": "1.143.11", "@tanstack/virtual-file-routes": "1.145.4", "prettier": "^3.5.0", "recast": "^0.23.11", "source-map": "^0.7.4", "tsx": "^4.19.2", "zod": "^3.24.2" } }, "sha512-H+SZbJ9j4G+y/329LlRLb//4sBdPNQpuMddb/rgkfoRZpdztm9Ejm9EEbMJB0rkNDrSgfSPOZ6VtJbndYH/AQA=="], + "@tanstack/router-generator": ["@tanstack/router-generator@1.150.0", "", { "dependencies": { "@tanstack/router-core": "1.150.0", "@tanstack/router-utils": "1.143.11", "@tanstack/virtual-file-routes": "1.145.4", "prettier": "^3.5.0", "recast": "^0.23.11", "source-map": "^0.7.4", "tsx": "^4.19.2", "zod": "^3.24.2" } }, "sha512-WsA1bN5/I+cxE6V1DkU5ABIPBQxZLlxszElYgnIhs884tzukv76rYMFOy6Xqd51YIFdYtjDrxZbp4/vfkrVCug=="], - "@tanstack/router-plugin": ["@tanstack/router-plugin@1.149.0", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@tanstack/router-core": "1.147.1", "@tanstack/router-generator": "1.149.0", "@tanstack/router-utils": "1.143.11", "@tanstack/virtual-file-routes": "1.145.4", "babel-dead-code-elimination": "^1.0.11", "chokidar": "^3.6.0", "unplugin": "^2.1.2", "zod": "^3.24.2" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2", "@tanstack/react-router": "^1.147.3", "vite": ">=5.0.0 || >=6.0.0 || >=7.0.0", "vite-plugin-solid": "^2.11.10", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "vite-plugin-solid", "webpack"] }, "sha512-DYPScneHZ0fm3FJyDhkUCW0w0dOopAKvep57n/Ft2b3RrHSeSeJB/cJWgsUvpcYJfpywkyOLyqVLMoiDvLoG/A=="], + "@tanstack/router-plugin": ["@tanstack/router-plugin@1.150.0", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@tanstack/router-core": "1.150.0", "@tanstack/router-generator": "1.150.0", "@tanstack/router-utils": "1.143.11", "@tanstack/virtual-file-routes": "1.145.4", "babel-dead-code-elimination": "^1.0.11", "chokidar": "^3.6.0", "unplugin": "^2.1.2", "zod": "^3.24.2" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2", "@tanstack/react-router": "^1.150.0", "vite": ">=5.0.0 || >=6.0.0 || >=7.0.0", "vite-plugin-solid": "^2.11.10", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "vite-plugin-solid", "webpack"] }, "sha512-k2NLysBXO4Wpt4Oo0xeBhNtFsMwHOU8ud48/cWNWbV89QAjlk0XU5CGNj2JEaFMT0zlF3H/aM5/h0+vYnDjFFA=="], "@tanstack/router-utils": ["@tanstack/router-utils@1.143.11", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/generator": "^7.28.5", "@babel/parser": "^7.28.5", "ansis": "^4.1.0", "diff": "^8.0.2", "pathe": "^2.0.3", "tinyglobby": "^0.2.15" } }, "sha512-N24G4LpfyK8dOlnP8BvNdkuxg1xQljkyl6PcrdiPSA301pOjatRT1y8wuCCJZKVVD8gkd0MpCZ0VEjRMGILOtA=="], @@ -1400,15 +1403,13 @@ "@tokenlens/models": ["@tokenlens/models@1.3.0", "", { "dependencies": { "@tokenlens/core": "1.3.0" } }, "sha512-9mx7ZGeewW4ndXAiD7AT1bbCk4OpJeortbjHHyNkgap+pMPPn1chY6R5zqe1ggXIUzZ2l8VOAKfPqOvpcrisJw=="], - "@tootallnate/once": ["@tootallnate/once@2.0.0", "", {}, "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A=="], + "@trpc/client": ["@trpc/client@11.8.1", "", { "peerDependencies": { "@trpc/server": "11.8.1", "typescript": ">=5.7.2" } }, "sha512-L/SJFGanr9xGABmuDoeXR4xAdHJmsXsiF9OuH+apecJ+8sUITzVT1EPeqp0ebqA6lBhEl5pPfg3rngVhi/h60Q=="], - "@trpc/client": ["@trpc/client@11.7.2", "", { "peerDependencies": { "@trpc/server": "11.7.2", "typescript": ">=5.7.2" } }, "sha512-OQxqUMfpDvjcszo9dbnqWQXnW2L5IbrKSz2H7l8s+mVM3EvYw7ztQ/gjFIN3iy0NcamiQfd4eE6qjcb9Lm+63A=="], + "@trpc/react-query": ["@trpc/react-query@11.8.1", "", { "peerDependencies": { "@tanstack/react-query": "^5.80.3", "@trpc/client": "11.8.1", "@trpc/server": "11.8.1", "react": ">=18.2.0", "react-dom": ">=18.2.0", "typescript": ">=5.7.2" } }, "sha512-0Vu55ld/oINb4U6nIPPi7eZMhxUop6K+4QUK90RVsfSD5r+957sM80M4c8bjh/JBZUxMFv9JOhxxlWcrgHxHow=="], - "@trpc/react-query": ["@trpc/react-query@11.7.2", "", { "peerDependencies": { "@tanstack/react-query": "^5.80.3", "@trpc/client": "11.7.2", "@trpc/server": "11.7.2", "react": ">=18.2.0", "react-dom": ">=18.2.0", "typescript": ">=5.7.2" } }, "sha512-IcLDMqx2mvlGRxkr0/m37TtPvRQ8nonITH3EwYv436x0Igx8eduR9z4tdgGBsjJY9e5W1G7cZ4zKCwrizSimFQ=="], + "@trpc/server": ["@trpc/server@11.8.1", "", { "peerDependencies": { "typescript": ">=5.7.2" } }, "sha512-P4rzZRpEL7zDFgjxK65IdyH0e41FMFfTkQkuq0BA5tKcr7E6v9/v38DEklCpoDN6sPiB1Sigy/PUEzHENhswDA=="], - "@trpc/server": ["@trpc/server@11.7.2", "", { "peerDependencies": { "typescript": ">=5.7.2" } }, "sha512-AgB26PXY69sckherIhCacKLY49rxE2XP5h38vr/KMZTbLCL1p8IuIoKPjALTcugC2kbyQ7Lbqo2JDVfRSmPmfQ=="], - - "@trpc/tanstack-react-query": ["@trpc/tanstack-react-query@11.7.2", "", { "peerDependencies": { "@tanstack/react-query": "^5.80.3", "@trpc/client": "11.7.2", "@trpc/server": "11.7.2", "react": ">=18.2.0", "react-dom": ">=18.2.0", "typescript": ">=5.7.2" } }, "sha512-3XrY0b8lV0Fhj4Z2hVn1d1ZJzq2/stbc2F1e9Y6RrUWOfLmOKHlEVHYO1QfDGM6rqj66DkUj7eA593hAI0VTkQ=="], + "@trpc/tanstack-react-query": ["@trpc/tanstack-react-query@11.8.1", "", { "peerDependencies": { "@tanstack/react-query": "^5.80.3", "@trpc/client": "11.8.1", "@trpc/server": "11.8.1", "react": ">=18.2.0", "react-dom": ">=18.2.0", "typescript": ">=5.7.2" } }, "sha512-0gBbRmRuU9/IVZgNFJuzY7k6ktnkmqjyP78PtcUBO7EgPlBu1y2MA2TdI5GT/VtNNOOhzkVeQpJqtt+0xQ8TOQ=="], "@tweenjs/tween.js": ["@tweenjs/tween.js@23.1.3", "", {}, "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA=="], @@ -1482,7 +1483,7 @@ "@types/d3-selection": ["@types/d3-selection@3.0.11", "", {}, "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w=="], - "@types/d3-shape": ["@types/d3-shape@3.1.7", "", { "dependencies": { "@types/d3-path": "*" } }, "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg=="], + "@types/d3-shape": ["@types/d3-shape@3.1.8", "", { "dependencies": { "@types/d3-path": "*" } }, "sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w=="], "@types/d3-time": ["@types/d3-time@3.0.4", "", {}, "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g=="], @@ -1508,7 +1509,7 @@ "@types/express": ["@types/express@5.0.6", "", { "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^5.0.0", "@types/serve-static": "^2" } }, "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA=="], - "@types/express-serve-static-core": ["@types/express-serve-static-core@5.1.0", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA=="], + "@types/express-serve-static-core": ["@types/express-serve-static-core@5.1.1", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A=="], "@types/fs-extra": ["@types/fs-extra@9.0.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA=="], @@ -1524,11 +1525,11 @@ "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], - "@types/katex": ["@types/katex@0.16.7", "", {}, "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ=="], + "@types/katex": ["@types/katex@0.16.8", "", {}, "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg=="], "@types/keyv": ["@types/keyv@3.1.4", "", { "dependencies": { "@types/node": "*" } }, "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg=="], - "@types/lodash": ["@types/lodash@4.17.21", "", {}, "sha512-FOvQ0YPD5NOfPgMzJihoT+Za5pdkDJWcbpuj1DjaKZIr/gxodQjY/uWEFlTNqW2ugXHUiL8lRQgw63dzKHZdeQ=="], + "@types/lodash": ["@types/lodash@4.17.23", "", {}, "sha512-RDvF6wTulMPjrNdCoYRC8gNR880JNGT8uB+REUpC2Ns4pRqQJhGz90wh7rgdXDPpCczF3VGktDuFGVnz8zP7HA=="], "@types/lodash.chunk": ["@types/lodash.chunk@4.2.9", "", { "dependencies": { "@types/lodash": "*" } }, "sha512-Z9VtFUSnmT0No/QymqfG9AGbfOA4O5qB/uyP89xeZBqDAsKsB4gQFTqt7d0pHjbsTwtQ4yZObQVHuKlSOhIJ5Q=="], @@ -1542,7 +1543,7 @@ "@types/mysql": ["@types/mysql@2.15.27", "", { "dependencies": { "@types/node": "*" } }, "sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA=="], - "@types/node": ["@types/node@24.10.3", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-gqkrWUsS8hcm0r44yn7/xZeV1ERva/nLgrLxFRUGb7aoNMIJfZJ3AC261zDQuOAKC7MiXai1WCpYc48jAHoShQ=="], + "@types/node": ["@types/node@24.10.8", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-r0bBaXu5Swb05doFYO2kTWHMovJnNVbCsII0fhesM8bNRlLhXIuckley4a2DaD+vOdmm5G+zGkQZAPZsF80+YQ=="], "@types/normalize-package-data": ["@types/normalize-package-data@2.4.4", "", {}, "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA=="], @@ -1560,11 +1561,11 @@ "@types/range-parser": ["@types/range-parser@1.2.7", "", {}, "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ=="], - "@types/react": ["@types/react@19.2.7", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg=="], + "@types/react": ["@types/react@19.2.8", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-3MbSL37jEchWZz2p2mjntRZtPt837ij10ApxKfgmXCTuHWagYg7iA5bqPw6C8BMPfwidlvfPI/fxOc42HLhcyg=="], "@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="], - "@types/react-reconciler": ["@types/react-reconciler@0.32.3", "", { "peerDependencies": { "@types/react": "*" } }, "sha512-cMi5ZrLG7UtbL7LTK6hq9w/EZIRk4Mf1Z5qHoI+qBh7/WkYkFXQ7gOto2yfUvPzF5ERMAhaXS5eTQ2SAnHjLzA=="], + "@types/react-reconciler": ["@types/react-reconciler@0.28.9", "", { "peerDependencies": { "@types/react": "*" } }, "sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg=="], "@types/react-syntax-highlighter": ["@types/react-syntax-highlighter@15.5.13", "", { "dependencies": { "@types/react": "*" } }, "sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA=="], @@ -1606,7 +1607,7 @@ "@upstash/qstash": ["@upstash/qstash@2.8.4", "", { "dependencies": { "crypto-js": ">=4.2.0", "jose": "^5.2.3", "neverthrow": "^7.0.1" } }, "sha512-iojHWUlRoC3M2e4XQ1NFEgC+7Orurrm5uIrPn5WilU7LvWQoocyjYBXR0VUalXkeMAmFyk4blF0EOYZY4igdIQ=="], - "@upstash/redis": ["@upstash/redis@1.35.8", "", { "dependencies": { "uncrypto": "^0.1.3" } }, "sha512-QqLpVCD9PCPE6hlRzOkz864nfijSdazxtyJLIy9ZeTh6kU2nBIKKfjT5HMHjIRD4BCm6TK1dbUT9pxhFjcvpng=="], + "@upstash/redis": ["@upstash/redis@1.36.1", "", { "dependencies": { "uncrypto": "^0.1.3" } }, "sha512-N6SjDcgXdOcTAF+7uNoY69o7hCspe9BcA7YjQdxVu5d25avljTwyLaHBW3krWjrP0FfocgMk94qyVtQbeDp39A=="], "@use-gesture/core": ["@use-gesture/core@10.3.1", "", {}, "sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw=="], @@ -1616,15 +1617,15 @@ "@vercel/kv": ["@vercel/kv@3.0.0", "", { "dependencies": { "@upstash/redis": "^1.34.0" } }, "sha512-pKT8fRnfyYk2MgvyB6fn6ipJPCdfZwiKDdw7vB+HL50rjboEBHDVBEcnwfkEpVSp2AjNtoaOUH7zG+bVC/rvSg=="], - "@vercel/oidc": ["@vercel/oidc@3.0.5", "", {}, "sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw=="], + "@vercel/oidc": ["@vercel/oidc@3.1.0", "", {}, "sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w=="], "@vitejs/plugin-react": ["@vitejs/plugin-react@5.1.2", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.53", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-EcA07pHJouywpzsoTUqNh5NwGayl2PPVEJKUSinGGSxFGYn+shYbqMGBg6FXDqgXum9Ou/ecb+411ssw8HImJQ=="], - "@vue/compiler-core": ["@vue/compiler-core@3.5.25", "", { "dependencies": { "@babel/parser": "^7.28.5", "@vue/shared": "3.5.25", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw=="], + "@vue/compiler-core": ["@vue/compiler-core@3.5.26", "", { "dependencies": { "@babel/parser": "^7.28.5", "@vue/shared": "3.5.26", "entities": "^7.0.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-vXyI5GMfuoBCnv5ucIT7jhHKl55Y477yxP6fc4eUswjP8FG3FFVFd41eNDArR+Uk3QKn2Z85NavjaxLxOC19/w=="], - "@vue/compiler-dom": ["@vue/compiler-dom@3.5.25", "", { "dependencies": { "@vue/compiler-core": "3.5.25", "@vue/shared": "3.5.25" } }, "sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q=="], + "@vue/compiler-dom": ["@vue/compiler-dom@3.5.26", "", { "dependencies": { "@vue/compiler-core": "3.5.26", "@vue/shared": "3.5.26" } }, "sha512-y1Tcd3eXs834QjswshSilCBnKGeQjQXB6PqFn/1nxcQw4pmG42G8lwz+FZPAZAby6gZeHSt/8LMPfZ4Rb+Bd/A=="], - "@vue/shared": ["@vue/shared@3.5.25", "", {}, "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg=="], + "@vue/shared": ["@vue/shared@3.5.26", "", {}, "sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A=="], "@webassemblyjs/ast": ["@webassemblyjs/ast@1.14.1", "", { "dependencies": { "@webassemblyjs/helper-numbers": "1.13.2", "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ=="], @@ -1656,7 +1657,7 @@ "@webassemblyjs/wast-printer": ["@webassemblyjs/wast-printer@1.14.1", "", { "dependencies": { "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw=="], - "@webgpu/types": ["@webgpu/types@0.1.67", "", {}, "sha512-uk53+2ECGUkWoDFez/hymwpRfdgdIn6y1ref70fEecGMe5607f4sozNFgBk0oxlr7j2CRGWBEc3IBYMmFdGGTQ=="], + "@webgpu/types": ["@webgpu/types@0.1.69", "", {}, "sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ=="], "@xmldom/xmldom": ["@xmldom/xmldom@0.8.11", "", {}, "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw=="], @@ -1692,7 +1693,7 @@ "@xyflow/system": ["@xyflow/system@0.0.74", "", { "dependencies": { "@types/d3-drag": "^3.0.7", "@types/d3-interpolate": "^3.0.4", "@types/d3-selection": "^3.0.10", "@types/d3-transition": "^3.0.8", "@types/d3-zoom": "^3.0.8", "d3-drag": "^3.0.0", "d3-interpolate": "^3.0.1", "d3-selection": "^3.0.0", "d3-zoom": "^3.0.0" } }, "sha512-7v7B/PkiVrkdZzSbL+inGAo6tkR/WQHHG0/jhSvLQToCsfa8YubOGmBYd1s08tpKpihdHDZFwzQZeR69QSBb4Q=="], - "abbrev": ["abbrev@1.1.1", "", {}, "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="], + "abbrev": ["abbrev@3.0.1", "", {}, "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg=="], "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], @@ -1706,17 +1707,13 @@ "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], - "agentkeepalive": ["agentkeepalive@4.6.0", "", { "dependencies": { "humanize-ms": "^1.2.1" } }, "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ=="], - - "aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="], - - "ai": ["ai@5.0.112", "", { "dependencies": { "@ai-sdk/gateway": "2.0.21", "@ai-sdk/provider": "2.0.0", "@ai-sdk/provider-utils": "3.0.19", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Y0dluYpe5wn81UkfHbZL78mH6CsceUfMiu4oPRaWZvjlmcoXSPdEAsPcYbOjvX8ZPvQc6m4kNZhkcEXmT2ln4w=="], + "ai": ["ai@5.0.121", "", { "dependencies": { "@ai-sdk/gateway": "2.0.27", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-3iYPdARKGLryC/7OA9RgBUaym1gynvWS7UPy8NwoRNCKP52lshldtHB5xcEfVviw7liWH2zJlW9yEzsDglcIEQ=="], "ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], "ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="], - "ajv-keywords": ["ajv-keywords@5.1.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3" }, "peerDependencies": { "ajv": "^8.8.2" } }, "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw=="], + "ajv-keywords": ["ajv-keywords@3.5.2", "", { "peerDependencies": { "ajv": "^6.9.1" } }, "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="], "ansi-escapes": ["ansi-escapes@7.2.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw=="], @@ -1730,7 +1727,7 @@ "app-builder-bin": ["app-builder-bin@5.0.0-alpha.12", "", {}, "sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w=="], - "app-builder-lib": ["app-builder-lib@26.0.12", "", { "dependencies": { "@develar/schema-utils": "~2.6.5", "@electron/asar": "3.2.18", "@electron/fuses": "^1.8.0", "@electron/notarize": "2.5.0", "@electron/osx-sign": "1.3.1", "@electron/rebuild": "3.7.0", "@electron/universal": "2.0.1", "@malept/flatpak-bundler": "^0.4.0", "@types/fs-extra": "9.0.13", "async-exit-hook": "^2.0.1", "builder-util": "26.0.11", "builder-util-runtime": "9.3.1", "chromium-pickle-js": "^0.2.0", "config-file-ts": "0.2.8-rc1", "debug": "^4.3.4", "dotenv": "^16.4.5", "dotenv-expand": "^11.0.6", "ejs": "^3.1.8", "electron-publish": "26.0.11", "fs-extra": "^10.1.0", "hosted-git-info": "^4.1.0", "is-ci": "^3.0.0", "isbinaryfile": "^5.0.0", "js-yaml": "^4.1.0", "json5": "^2.2.3", "lazy-val": "^1.0.5", "minimatch": "^10.0.0", "plist": "3.1.0", "resedit": "^1.7.0", "semver": "^7.3.8", "tar": "^6.1.12", "temp-file": "^3.4.0", "tiny-async-pool": "1.3.0" }, "peerDependencies": { "dmg-builder": "26.0.12", "electron-builder-squirrel-windows": "26.0.12" } }, "sha512-+/CEPH1fVKf6HowBUs6LcAIoRcjeqgvAeoSE+cl7Y7LndyQ9ViGPYibNk7wmhMHzNgHIuIbw4nWADPO+4mjgWw=="], + "app-builder-lib": ["app-builder-lib@26.4.0", "", { "dependencies": { "@develar/schema-utils": "~2.6.5", "@electron/asar": "3.4.1", "@electron/fuses": "^1.8.0", "@electron/notarize": "2.5.0", "@electron/osx-sign": "1.3.3", "@electron/rebuild": "4.0.1", "@electron/universal": "2.0.3", "@malept/flatpak-bundler": "^0.4.0", "@types/fs-extra": "9.0.13", "async-exit-hook": "^2.0.1", "builder-util": "26.3.4", "builder-util-runtime": "9.5.1", "chromium-pickle-js": "^0.2.0", "ci-info": "4.3.1", "debug": "^4.3.4", "dotenv": "^16.4.5", "dotenv-expand": "^11.0.6", "ejs": "^3.1.8", "electron-publish": "26.3.4", "fs-extra": "^10.1.0", "hosted-git-info": "^4.1.0", "isbinaryfile": "^5.0.0", "jiti": "^2.4.2", "js-yaml": "^4.1.0", "json5": "^2.2.3", "lazy-val": "^1.0.5", "minimatch": "^10.0.3", "plist": "3.1.0", "resedit": "^1.7.0", "semver": "~7.7.3", "tar": "^6.1.12", "temp-file": "^3.4.0", "tiny-async-pool": "1.3.0", "which": "^5.0.0" }, "peerDependencies": { "dmg-builder": "26.4.0", "electron-builder-squirrel-windows": "26.4.0" } }, "sha512-Uas6hNe99KzP3xPWxh5LGlH8kWIVjZixzmMJHNB9+6hPyDpjc7NQMkVgi16rQDdpCFy22ZU5sp8ow7tvjeMgYQ=="], "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], @@ -1760,7 +1757,7 @@ "auto-bind": ["auto-bind@5.0.1", "", {}, "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg=="], - "babel-dead-code-elimination": ["babel-dead-code-elimination@1.0.11", "", { "dependencies": { "@babel/core": "^7.23.7", "@babel/parser": "^7.23.6", "@babel/traverse": "^7.23.7", "@babel/types": "^7.23.6" } }, "sha512-mwq3W3e/pKSI6TG8lXMiDWvEi1VXYlSBlJlB3l+I0bAb5u1RNUl88udos85eOPNK3m5EXK9uO7d2g08pesTySQ=="], + "babel-dead-code-elimination": ["babel-dead-code-elimination@1.0.12", "", { "dependencies": { "@babel/core": "^7.23.7", "@babel/parser": "^7.23.6", "@babel/traverse": "^7.23.7", "@babel/types": "^7.23.6" } }, "sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig=="], "babel-plugin-react-compiler": ["babel-plugin-react-compiler@1.0.0", "", { "dependencies": { "@babel/types": "^7.26.0" } }, "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw=="], @@ -1772,11 +1769,11 @@ "base64id": ["base64id@2.0.0", "", {}, "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="], - "baseline-browser-mapping": ["baseline-browser-mapping@2.9.6", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-v9BVVpOTLB59C9E7aSnmIF8h7qRsFpx+A2nugVMTszEOMcfjlZMsXRm4LF23I3Z9AJxc8ANpIvzbzONoX9VJlg=="], + "baseline-browser-mapping": ["baseline-browser-mapping@2.9.14", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg=="], "bcp-47-match": ["bcp-47-match@2.0.3", "", {}, "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ=="], - "better-auth": ["better-auth@1.4.9", "", { "dependencies": { "@better-auth/core": "1.4.9", "@better-auth/telemetry": "1.4.9", "@better-auth/utils": "0.3.0", "@better-fetch/fetch": "1.1.21", "@noble/ciphers": "^2.0.0", "@noble/hashes": "^2.0.0", "better-call": "1.1.7", "defu": "^6.1.4", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1", "zod": "^4.1.12" }, "peerDependencies": { "@lynx-js/react": "*", "@prisma/client": "^5.0.0 || ^6.0.0 || ^7.0.0", "@sveltejs/kit": "^2.0.0", "@tanstack/react-start": "^1.0.0", "better-sqlite3": "^12.0.0", "drizzle-kit": ">=0.31.4", "drizzle-orm": ">=0.41.0", "mongodb": "^6.0.0 || ^7.0.0", "mysql2": "^3.0.0", "next": "^14.0.0 || ^15.0.0 || ^16.0.0", "pg": "^8.0.0", "prisma": "^5.0.0 || ^6.0.0 || ^7.0.0", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0", "solid-js": "^1.0.0", "svelte": "^4.0.0 || ^5.0.0", "vitest": "^2.0.0 || ^3.0.0 || ^4.0.0", "vue": "^3.0.0" }, "optionalPeers": ["@lynx-js/react", "@prisma/client", "@sveltejs/kit", "@tanstack/react-start", "better-sqlite3", "drizzle-kit", "drizzle-orm", "mongodb", "mysql2", "next", "pg", "prisma", "react", "react-dom", "solid-js", "svelte", "vitest", "vue"] }, "sha512-usSdjuyTzZwIvM8fjF8YGhPncxV3MAg3dHUO9uPUnf0yklXUSYISiH1+imk6/Z+UBqsscyyPRnbIyjyK97p7YA=="], + "better-auth": ["better-auth@1.4.12", "", { "dependencies": { "@better-auth/core": "1.4.12", "@better-auth/telemetry": "1.4.12", "@better-auth/utils": "0.3.0", "@better-fetch/fetch": "1.1.21", "@noble/ciphers": "^2.0.0", "@noble/hashes": "^2.0.0", "better-call": "1.1.7", "defu": "^6.1.4", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1", "zod": "^4.1.12" }, "peerDependencies": { "@lynx-js/react": "*", "@prisma/client": "^5.0.0 || ^6.0.0 || ^7.0.0", "@sveltejs/kit": "^2.0.0", "@tanstack/react-start": "^1.0.0", "better-sqlite3": "^12.0.0", "drizzle-kit": ">=0.31.4", "drizzle-orm": ">=0.41.0", "mongodb": "^6.0.0 || ^7.0.0", "mysql2": "^3.0.0", "next": "^14.0.0 || ^15.0.0 || ^16.0.0", "pg": "^8.0.0", "prisma": "^5.0.0 || ^6.0.0 || ^7.0.0", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0", "solid-js": "^1.0.0", "svelte": "^4.0.0 || ^5.0.0", "vitest": "^2.0.0 || ^3.0.0 || ^4.0.0", "vue": "^3.0.0" }, "optionalPeers": ["@lynx-js/react", "@prisma/client", "@sveltejs/kit", "@tanstack/react-start", "better-sqlite3", "drizzle-kit", "drizzle-orm", "mongodb", "mysql2", "next", "pg", "prisma", "react", "react-dom", "solid-js", "svelte", "vitest", "vue"] }, "sha512-FsFMnWgk+AGrxsIGbpWLCibgYcbm6uNhPHln3ohXFDXSRa0gk39Beuh54Q+x6ml2qYodF0snxf/tPtDpBI/JiA=="], "better-call": ["better-call@1.1.7", "", { "dependencies": { "@better-auth/utils": "^0.3.0", "@better-fetch/fetch": "^1.1.4", "rou3": "^0.7.10", "set-cookie-parser": "^2.7.1" }, "peerDependencies": { "zod": "^4.0.0" }, "optionalPeers": ["zod"] }, "sha512-6gaJe1bBIEgVebQu/7q9saahVzvBsGaByEnE8aDVncZEDiJO7sdNB28ot9I6iXSbR25egGmmZ6aIURXyQHRraQ=="], @@ -1790,7 +1787,7 @@ "bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="], - "body-parser": ["body-parser@2.2.1", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.0", "raw-body": "^3.0.1", "type-is": "^2.0.1" } }, "sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw=="], + "body-parser": ["body-parser@2.2.2", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" } }, "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA=="], "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], @@ -1808,17 +1805,17 @@ "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], - "builder-util": ["builder-util@26.0.11", "", { "dependencies": { "7zip-bin": "~5.2.0", "@types/debug": "^4.1.6", "app-builder-bin": "5.0.0-alpha.12", "builder-util-runtime": "9.3.1", "chalk": "^4.1.2", "cross-spawn": "^7.0.6", "debug": "^4.3.4", "fs-extra": "^10.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", "is-ci": "^3.0.0", "js-yaml": "^4.1.0", "sanitize-filename": "^1.6.3", "source-map-support": "^0.5.19", "stat-mode": "^1.0.0", "temp-file": "^3.4.0", "tiny-async-pool": "1.3.0" } }, "sha512-xNjXfsldUEe153h1DraD0XvDOpqGR0L5eKFkdReB7eFW5HqysDZFfly4rckda6y9dF39N3pkPlOblcfHKGw+uA=="], + "builder-util": ["builder-util@26.3.4", "", { "dependencies": { "7zip-bin": "~5.2.0", "@types/debug": "^4.1.6", "app-builder-bin": "5.0.0-alpha.12", "builder-util-runtime": "9.5.1", "chalk": "^4.1.2", "cross-spawn": "^7.0.6", "debug": "^4.3.4", "fs-extra": "^10.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", "js-yaml": "^4.1.0", "sanitize-filename": "^1.6.3", "source-map-support": "^0.5.19", "stat-mode": "^1.0.0", "temp-file": "^3.4.0", "tiny-async-pool": "1.3.0" } }, "sha512-aRn88mYMktHxzdqDMF6Ayj0rKoX+ZogJ75Ck7RrIqbY/ad0HBvnS2xA4uHfzrGr5D2aLL3vU6OBEH4p0KMV2XQ=="], - "builder-util-runtime": ["builder-util-runtime@9.3.1", "", { "dependencies": { "debug": "^4.3.4", "sax": "^1.2.4" } }, "sha512-2/egrNDDnRaxVwK3A+cJq6UOlqOdedGA7JPqCeJjN2Zjk1/QB/6QUi3b714ScIGS7HafFXTyzJEOr5b44I3kvQ=="], + "builder-util-runtime": ["builder-util-runtime@9.5.1", "", { "dependencies": { "debug": "^4.3.4", "sax": "^1.2.4" } }, "sha512-qt41tMfgHTllhResqM5DcnHyDIWNgzHvuY2jDcYP9iaGpkWxTUzV6GQjDeLnlR1/DtdlcsWQbA7sByMpmJFTLQ=="], - "bun-types": ["bun-types@1.3.4", "", { "dependencies": { "@types/node": "*" } }, "sha512-5ua817+BZPZOlNaRgGBpZJOSAQ9RQ17pkwPD0yR7CfJg+r8DgIILByFifDTa+IPDDxzf5VNhtNlcKqFzDgJvlQ=="], + "bun-types": ["bun-types@1.3.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ=="], "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], "cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="], - "cacache": ["cacache@16.1.3", "", { "dependencies": { "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^2.0.0", "chownr": "^2.0.0", "fs-minipass": "^2.1.0", "glob": "^8.0.1", "infer-owner": "^1.0.4", "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "mkdirp": "^1.0.4", "p-map": "^4.0.0", "promise-inflight": "^1.0.1", "rimraf": "^3.0.2", "ssri": "^9.0.0", "tar": "^6.1.11", "unique-filename": "^2.0.0" } }, "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ=="], + "cacache": ["cacache@19.0.1", "", { "dependencies": { "@npmcli/fs": "^4.0.0", "fs-minipass": "^3.0.0", "glob": "^10.2.2", "lru-cache": "^10.0.1", "minipass": "^7.0.3", "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^7.0.2", "ssri": "^12.0.0", "tar": "^7.4.3", "unique-filename": "^4.0.0" } }, "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ=="], "cacheable-lookup": ["cacheable-lookup@5.0.4", "", {}, "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA=="], @@ -1834,7 +1831,7 @@ "camera-controls": ["camera-controls@3.1.2", "", { "peerDependencies": { "three": ">=0.126.1" } }, "sha512-xkxfpG2ECZ6Ww5/9+kf4mfg1VEYAoe9aDSY+IwF0UEs7qEzwy0aVRfs2grImIECs/PoBtWFrh7RXsQkwG922JA=="], - "caniuse-lite": ["caniuse-lite@1.0.30001760", "", {}, "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw=="], + "caniuse-lite": ["caniuse-lite@1.0.30001764", "", {}, "sha512-9JGuzl2M+vPL+pz70gtMF9sHdMFbY9FJaQBi186cHKH3pSzDvzoUJUPV6fqiKIMyXbud9ZLg4F3Yza1vJ1+93g=="], "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], @@ -1860,7 +1857,7 @@ "chromium-pickle-js": ["chromium-pickle-js@0.2.0", "", {}, "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw=="], - "ci-info": ["ci-info@3.9.0", "", {}, "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ=="], + "ci-info": ["ci-info@4.3.1", "", {}, "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA=="], "citty": ["citty@0.1.6", "", { "dependencies": { "consola": "^3.2.3" } }, "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ=="], @@ -1872,8 +1869,6 @@ "classnames": ["classnames@2.5.1", "", {}, "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="], - "clean-stack": ["clean-stack@2.2.0", "", {}, "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A=="], - "cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="], "cli-cursor": ["cli-cursor@4.0.0", "", { "dependencies": { "restore-cursor": "^4.0.0" } }, "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg=="], @@ -1896,7 +1891,7 @@ "code-excerpt": ["code-excerpt@4.0.0", "", { "dependencies": { "convert-to-spaces": "^2.0.1" } }, "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA=="], - "code-inspector-plugin": ["code-inspector-plugin@1.3.2", "", { "dependencies": { "@code-inspector/core": "1.3.2", "@code-inspector/esbuild": "1.3.2", "@code-inspector/mako": "1.3.2", "@code-inspector/turbopack": "1.3.2", "@code-inspector/vite": "1.3.2", "@code-inspector/webpack": "1.3.2", "chalk": "4.1.1" } }, "sha512-cnS4OlrHPI1xEj8H2efWVBsV9i8pJJYHHjZdjz/qSt6BVyJjvVkkTXI5Hl4I7vTgoAam1h4xTuEDkwisDQy2Xg=="], + "code-inspector-plugin": ["code-inspector-plugin@1.3.4", "", { "dependencies": { "@code-inspector/core": "1.3.4", "@code-inspector/esbuild": "1.3.4", "@code-inspector/mako": "1.3.4", "@code-inspector/turbopack": "1.3.4", "@code-inspector/vite": "1.3.4", "@code-inspector/webpack": "1.3.4", "chalk": "4.1.1" } }, "sha512-735rAAc655oSAMd/6+PIsjpgB5jwugDISom9WFwhNUbOuFHiL2PYwshMmfIhAtOgECl+7g6o50rBIIYwCEa8xg=="], "collapse-white-space": ["collapse-white-space@2.1.0", "", {}, "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw=="], @@ -1922,8 +1917,6 @@ "confbox": ["confbox@0.2.2", "", {}, "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ=="], - "config-file-ts": ["config-file-ts@0.2.8-rc1", "", { "dependencies": { "glob": "^10.3.12", "typescript": "^5.4.3" } }, "sha512-GtNECbVI82bT4RiDIzBSVuTKoSHufnU7Ce7/42bkWZJZFLjmDF2WBpVsvRkhKCfKBnTBb3qZrBwPpFBU/Myvhg=="], - "consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="], "content-disposition": ["content-disposition@1.0.1", "", {}, "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q=="], @@ -2002,7 +1995,7 @@ "d3-force": ["d3-force@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-quadtree": "1 - 3", "d3-timer": "1 - 3" } }, "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg=="], - "d3-format": ["d3-format@3.1.0", "", {}, "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA=="], + "d3-format": ["d3-format@3.1.2", "", {}, "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg=="], "d3-geo": ["d3-geo@3.1.1", "", { "dependencies": { "d3-array": "2.5.0 - 3" } }, "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q=="], @@ -2102,7 +2095,7 @@ "direction": ["direction@2.0.1", "", { "bin": { "direction": "cli.js" } }, "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA=="], - "dmg-builder": ["dmg-builder@26.0.12", "", { "dependencies": { "app-builder-lib": "26.0.12", "builder-util": "26.0.11", "builder-util-runtime": "9.3.1", "fs-extra": "^10.1.0", "iconv-lite": "^0.6.2", "js-yaml": "^4.1.0" }, "optionalDependencies": { "dmg-license": "^1.0.11" } }, "sha512-59CAAjAhTaIMCN8y9kD573vDkxbs1uhDcrFLHSgutYdPcGOU35Rf95725snvzEOy4BFB7+eLJ8djCNPmGwG67w=="], + "dmg-builder": ["dmg-builder@26.4.0", "", { "dependencies": { "app-builder-lib": "26.4.0", "builder-util": "26.3.4", "fs-extra": "^10.1.0", "iconv-lite": "^0.6.2", "js-yaml": "^4.1.0" }, "optionalDependencies": { "dmg-license": "^1.0.11" } }, "sha512-ce4Ogns4VMeisIuCSK0C62umG0lFy012jd8LMZ6w/veHUeX4fqfDrGe+HTWALAEwK6JwKP+dhPvizhArSOsFbg=="], "dmg-license": ["dmg-license@1.0.11", "", { "dependencies": { "@types/plist": "^3.0.1", "@types/verror": "^1.10.3", "ajv": "^6.10.0", "crc": "^3.8.0", "iconv-corefoundation": "^1.1.7", "plist": "^3.0.4", "smart-buffer": "^4.0.2", "verror": "^1.10.0" }, "os": "darwin", "bin": { "dmg-license": "bin/dmg-license.js" } }, "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q=="], @@ -2144,17 +2137,17 @@ "electron": ["electron@39.1.2", "", { "dependencies": { "@electron/get": "^2.0.0", "@types/node": "^22.7.7", "extract-zip": "^2.0.1" }, "bin": { "electron": "cli.js" } }, "sha512-+/TwT9NWxyQGTm5WemJEJy+bWCpnKJ4PLPswI1yn1P63bzM0/8yAeG05yS+NfFaWH4yNQtGXZmAv87Bxa5RlLg=="], - "electron-builder": ["electron-builder@26.0.12", "", { "dependencies": { "app-builder-lib": "26.0.12", "builder-util": "26.0.11", "builder-util-runtime": "9.3.1", "chalk": "^4.1.2", "dmg-builder": "26.0.12", "fs-extra": "^10.1.0", "is-ci": "^3.0.0", "lazy-val": "^1.0.5", "simple-update-notifier": "2.0.0", "yargs": "^17.6.2" }, "bin": { "electron-builder": "cli.js", "install-app-deps": "install-app-deps.js" } }, "sha512-cD1kz5g2sgPTMFHjLxfMjUK5JABq3//J4jPswi93tOPFz6btzXYtK5NrDt717NRbukCUDOrrvmYVOWERlqoiXA=="], + "electron-builder": ["electron-builder@26.4.0", "", { "dependencies": { "app-builder-lib": "26.4.0", "builder-util": "26.3.4", "builder-util-runtime": "9.5.1", "chalk": "^4.1.2", "ci-info": "^4.2.0", "dmg-builder": "26.4.0", "fs-extra": "^10.1.0", "lazy-val": "^1.0.5", "simple-update-notifier": "2.0.0", "yargs": "^17.6.2" }, "bin": { "electron-builder": "cli.js", "install-app-deps": "install-app-deps.js" } }, "sha512-FCUqvdq2AULL+Db2SUGgjOYTbrgkPxZtCjqIZGnjH9p29pTWyesQqBIfvQBKa6ewqde87aWl49n/WyI/NyUBog=="], - "electron-builder-squirrel-windows": ["electron-builder-squirrel-windows@26.0.12", "", { "dependencies": { "app-builder-lib": "26.0.12", "builder-util": "26.0.11", "electron-winstaller": "5.4.0" } }, "sha512-kpwXM7c/ayRUbYVErQbsZ0nQZX4aLHQrPEG9C4h9vuJCXylwFH8a7Jgi2VpKIObzCXO7LKHiCw4KdioFLFOgqA=="], + "electron-builder-squirrel-windows": ["electron-builder-squirrel-windows@26.4.0", "", { "dependencies": { "app-builder-lib": "26.4.0", "builder-util": "26.3.4", "electron-winstaller": "5.4.0" } }, "sha512-7dvalY38xBzWNaoOJ4sqy2aGIEpl2S1gLPkkB0MHu1Hu5xKQ82il1mKSFlXs6fLpXUso/NmyjdHGlSHDRoG8/w=="], "electron-extension-installer": ["electron-extension-installer@2.0.1", "", { "dependencies": { "jszip": "^3.10.1" }, "peerDependencies": { "electron": ">=36.0.0" } }, "sha512-pFdtmilltpZrjt568an4cwRZ0NPPLSiC0noZ3Bj9dE2O07jvDhFLNQZop4BudNJBhVSnlDHj4LznV3Y+9Q+tug=="], - "electron-publish": ["electron-publish@26.0.11", "", { "dependencies": { "@types/fs-extra": "^9.0.11", "builder-util": "26.0.11", "builder-util-runtime": "9.3.1", "chalk": "^4.1.2", "form-data": "^4.0.0", "fs-extra": "^10.1.0", "lazy-val": "^1.0.5", "mime": "^2.5.2" } }, "sha512-a8QRH0rAPIWH9WyyS5LbNvW9Ark6qe63/LqDB7vu2JXYpi0Gma5Q60Dh4tmTqhOBQt0xsrzD8qE7C+D7j+B24A=="], + "electron-publish": ["electron-publish@26.3.4", "", { "dependencies": { "@types/fs-extra": "^9.0.11", "builder-util": "26.3.4", "builder-util-runtime": "9.5.1", "chalk": "^4.1.2", "form-data": "^4.0.0", "fs-extra": "^10.1.0", "lazy-val": "^1.0.5", "mime": "^2.5.2" } }, "sha512-5/ouDPb73SkKuay2EXisPG60LTFTMNHWo2WLrK5GDphnWK9UC+yzYrzVeydj078Yk4WUXi0+TaaZsNd6Zt5k/A=="], "electron-to-chromium": ["electron-to-chromium@1.5.267", "", {}, "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw=="], - "electron-updater": ["electron-updater@6.6.2", "", { "dependencies": { "builder-util-runtime": "9.3.1", "fs-extra": "^10.1.0", "js-yaml": "^4.1.0", "lazy-val": "^1.0.5", "lodash.escaperegexp": "^4.1.2", "lodash.isequal": "^4.5.0", "semver": "^7.6.3", "tiny-typed-emitter": "^2.1.0" } }, "sha512-Cr4GDOkbAUqRHP5/oeOmH/L2Bn6+FQPxVLZtPbcmKZC63a1F3uu5EefYOssgZXG3u/zBlubbJ5PJdITdMVggbw=="], + "electron-updater": ["electron-updater@6.7.3", "", { "dependencies": { "builder-util-runtime": "9.5.1", "fs-extra": "^10.1.0", "js-yaml": "^4.1.0", "lazy-val": "^1.0.5", "lodash.escaperegexp": "^4.1.2", "lodash.isequal": "^4.5.0", "semver": "~7.7.3", "tiny-typed-emitter": "^2.1.0" } }, "sha512-EgkT8Z9noqXKbwc3u5FkJA+r48jwZ5DTUiOkJMOTEEH//n5Am6wfQGz7nvSFEA2oIAMv9jRzn5JKTyWeSKOPgg=="], "electron-vite": ["electron-vite@4.0.1", "", { "dependencies": { "@babel/core": "^7.27.7", "@babel/plugin-transform-arrow-functions": "^7.27.1", "cac": "^6.7.14", "esbuild": "^0.25.5", "magic-string": "^0.30.17", "picocolors": "^1.1.1" }, "peerDependencies": { "@swc/core": "^1.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["@swc/core"], "bin": { "electron-vite": "bin/electron-vite.js" } }, "sha512-QqacJbA8f1pmwUTqki1qLL5vIBaOQmeq13CZZefZ3r3vKVaIoC7cpoTgE+KPKxJDFTax+iFZV0VYvLVWPiQ8Aw=="], @@ -2200,7 +2193,7 @@ "es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="], - "es-toolkit": ["es-toolkit@1.42.0", "", {}, "sha512-SLHIyY7VfDJBM8clz4+T2oquwTQxEzu263AyhVK4jREOAwJ+8eebaa4wM3nlvnAqhDrMm2EsA6hWHaQsMPQ1nA=="], + "es-toolkit": ["es-toolkit@1.43.0", "", {}, "sha512-SKCT8AsWvYzBBuUqMk4NPwFlSdqLpJwmy6AP322ERn8W2YLIB6JBXnwMI2Qsh2gfphT3q7EKAxKb23cvFHFwKA=="], "es6-error": ["es6-error@4.1.1", "", {}, "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg=="], @@ -2268,7 +2261,7 @@ "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], - "fast-equals": ["fast-equals@5.3.3", "", {}, "sha512-/boTcHZeIAQ2r/tL11voclBHDeP9WPxLt+tyAbVSyyXuUFyh0Tne7gJZTqGbxnvj79TjLdCXLOY7UIPhyG5MTw=="], + "fast-equals": ["fast-equals@5.4.0", "", {}, "sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw=="], "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], @@ -2276,7 +2269,7 @@ "fast-uri": ["fast-uri@3.1.0", "", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="], - "fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="], + "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="], "fault": ["fault@1.0.4", "", { "dependencies": { "format": "^0.2.0" } }, "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA=="], @@ -2316,7 +2309,7 @@ "fractional-indexing": ["fractional-indexing@3.2.0", "", {}, "sha512-PcOxmqwYCW7O2ovKRU8OoQQj2yqTfEB/yeTYk4gPid6dN5ODRfU1hXd9tTVZzax/0NkO7AxpHykvZnT1aYp/BQ=="], - "framer-motion": ["framer-motion@12.23.26", "", { "dependencies": { "motion-dom": "^12.23.23", "motion-utils": "^12.23.6", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-cPcIhgR42xBn1Uj+PzOyheMtZ73H927+uWPDVhUMqxy8UHt6Okavb6xIz9J/phFUHUj0OncR6UvMfJTXoc/LKA=="], + "framer-motion": ["framer-motion@12.26.2", "", { "dependencies": { "motion-dom": "^12.26.2", "motion-utils": "^12.24.10", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-lflOQEdjquUi9sCg5Y1LrsZDlsjrHw7m0T9Yedvnk7Bnhqfkc89/Uha10J3CFhkL+TCZVCRw9eUGyM/lyYhXQA=="], "fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], @@ -2472,8 +2465,6 @@ "human-signals": ["human-signals@8.0.1", "", {}, "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ=="], - "humanize-ms": ["humanize-ms@1.2.1", "", { "dependencies": { "ms": "^2.0.0" } }, "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ=="], - "iconv-corefoundation": ["iconv-corefoundation@1.1.7", "", { "dependencies": { "cli-truncate": "^2.1.0", "node-addon-api": "^1.6.3" }, "os": "darwin" }, "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ=="], "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], @@ -2496,15 +2487,13 @@ "indent-string": ["indent-string@5.0.0", "", {}, "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg=="], - "infer-owner": ["infer-owner@1.0.4", "", {}, "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A=="], - "inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="], "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], "ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="], - "ink": ["ink@6.5.1", "", { "dependencies": { "@alcalzone/ansi-tokenize": "^0.2.1", "ansi-escapes": "^7.2.0", "ansi-styles": "^6.2.1", "auto-bind": "^5.0.1", "chalk": "^5.6.0", "cli-boxes": "^3.0.0", "cli-cursor": "^4.0.0", "cli-truncate": "^5.1.1", "code-excerpt": "^4.0.0", "es-toolkit": "^1.39.10", "indent-string": "^5.0.0", "is-in-ci": "^2.0.0", "patch-console": "^2.0.0", "react-reconciler": "^0.33.0", "signal-exit": "^3.0.7", "slice-ansi": "^7.1.0", "stack-utils": "^2.0.6", "string-width": "^8.1.0", "type-fest": "^4.27.0", "widest-line": "^5.0.0", "wrap-ansi": "^9.0.0", "ws": "^8.18.0", "yoga-layout": "~3.2.1" }, "peerDependencies": { "@types/react": ">=19.0.0", "react": ">=19.0.0", "react-devtools-core": "^6.1.2" }, "optionalPeers": ["@types/react", "react-devtools-core"] }, "sha512-wF3j/DmkM8q5E+OtfdQhCRw8/0ahkc8CUTgEddxZzpEWPslu7YPL3t64MWRoI9m6upVGpfAg4ms2BBvxCdKRLQ=="], + "ink": ["ink@6.6.0", "", { "dependencies": { "@alcalzone/ansi-tokenize": "^0.2.1", "ansi-escapes": "^7.2.0", "ansi-styles": "^6.2.1", "auto-bind": "^5.0.1", "chalk": "^5.6.0", "cli-boxes": "^3.0.0", "cli-cursor": "^4.0.0", "cli-truncate": "^5.1.1", "code-excerpt": "^4.0.0", "es-toolkit": "^1.39.10", "indent-string": "^5.0.0", "is-in-ci": "^2.0.0", "patch-console": "^2.0.0", "react-reconciler": "^0.33.0", "signal-exit": "^3.0.7", "slice-ansi": "^7.1.0", "stack-utils": "^2.0.6", "string-width": "^8.1.0", "type-fest": "^4.27.0", "widest-line": "^5.0.0", "wrap-ansi": "^9.0.0", "ws": "^8.18.0", "yoga-layout": "~3.2.1" }, "peerDependencies": { "@types/react": ">=19.0.0", "react": ">=19.0.0", "react-devtools-core": "^6.1.2" }, "optionalPeers": ["@types/react", "react-devtools-core"] }, "sha512-QDt6FgJxgmSxAelcOvOHUvFxbIUjVpCH5bx+Slvc5m7IEcpGt3dYwbz/L+oRnqEGeRvwy1tineKK4ect3nW1vQ=="], "ink-select-input": ["ink-select-input@6.2.0", "", { "dependencies": { "figures": "^6.1.0", "to-rotated": "^1.0.0" }, "peerDependencies": { "ink": ">=5.0.0", "react": ">=18.0.0" } }, "sha512-304fZXxkpYxJ9si5lxRCaX01GNlmPBgOZumXXRnPYbHW/iI31cgQynqk2tRypGLOF1cMIwPUzL2LSm6q4I5rQQ=="], @@ -2536,8 +2525,6 @@ "is-buffer": ["is-buffer@2.0.5", "", {}, "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ=="], - "is-ci": ["is-ci@3.0.1", "", { "dependencies": { "ci-info": "^3.2.0" }, "bin": { "is-ci": "bin.js" } }, "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ=="], - "is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="], "is-decimal": ["is-decimal@2.0.1", "", {}, "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A=="], @@ -2554,8 +2541,6 @@ "is-interactive": ["is-interactive@2.0.0", "", {}, "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ=="], - "is-lambda": ["is-lambda@1.0.1", "", {}, "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ=="], - "is-node-process": ["is-node-process@1.2.0", "", {}, "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw=="], "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], @@ -2588,7 +2573,7 @@ "jest-worker": ["jest-worker@27.5.1", "", { "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" } }, "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg=="], - "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], + "jiti": ["jiti@2.4.2", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A=="], "jose": ["jose@6.1.3", "", {}, "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ=="], @@ -2632,7 +2617,7 @@ "langium": ["langium@3.3.1", "", { "dependencies": { "chevrotain": "~11.0.3", "chevrotain-allstar": "~0.3.0", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.11", "vscode-uri": "~3.0.8" } }, "sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w=="], - "launch-ide": ["launch-ide@1.3.0", "", { "dependencies": { "chalk": "^4.1.1", "dotenv": "^16.1.4" } }, "sha512-pxiF+HVNMV0dDc6Z0q89RDmzMF9XmSGaOn4ueTegjMy3cUkezc3zrki5PCiz68zZIqAuhW7iwoWX7JO4Kn6B0A=="], + "launch-ide": ["launch-ide@1.3.1", "", { "dependencies": { "chalk": "^4.1.1", "dotenv": "^16.1.4" } }, "sha512-opTthrpkuhi1Y8yFn6TWUeycyiI1aiZpVuTV4HQFUfVut7nMYGr5nQ8heYHrRJH2KYISLVYwz+QFRNZxFlbQmA=="], "layout-base": ["layout-base@1.0.2", "", {}, "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg=="], @@ -2678,7 +2663,7 @@ "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="], - "lodash-es": ["lodash-es@4.17.21", "", {}, "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="], + "lodash-es": ["lodash-es@4.17.22", "", {}, "sha512-XEawp1t0gxSi9x01glktRZ5HDy0HXqrM0x5pXQM98EaI0NxO6jVM7omDOxsuEo5UIASAnm2bRp1Jt/e0a2XU8Q=="], "lodash.chunk": ["lodash.chunk@4.2.0", "", {}, "sha512-ZzydJKfUHJwHa+hF5X66zLFCBrWn5GeF28OHEr4WVWtNDXlQ/IjWKPBiikqKo2ne0+v6JgCgJ0GzJp8k8bHC7w=="], @@ -2706,7 +2691,7 @@ "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], - "make-fetch-happen": ["make-fetch-happen@10.2.1", "", { "dependencies": { "agentkeepalive": "^4.2.1", "cacache": "^16.1.0", "http-cache-semantics": "^4.1.0", "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", "lru-cache": "^7.7.1", "minipass": "^3.1.6", "minipass-collect": "^1.0.2", "minipass-fetch": "^2.0.3", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^0.6.3", "promise-retry": "^2.0.1", "socks-proxy-agent": "^7.0.0", "ssri": "^9.0.0" } }, "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w=="], + "make-fetch-happen": ["make-fetch-happen@14.0.3", "", { "dependencies": { "@npmcli/agent": "^3.0.0", "cacache": "^19.0.1", "http-cache-semantics": "^4.1.1", "minipass": "^7.0.2", "minipass-fetch": "^4.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^1.0.0", "proc-log": "^5.0.0", "promise-retry": "^2.0.1", "ssri": "^12.0.0" } }, "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ=="], "map-obj": ["map-obj@4.3.0", "", {}, "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ=="], @@ -2872,9 +2857,9 @@ "minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], - "minipass-collect": ["minipass-collect@1.0.2", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA=="], + "minipass-collect": ["minipass-collect@2.0.1", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw=="], - "minipass-fetch": ["minipass-fetch@2.1.2", "", { "dependencies": { "minipass": "^3.1.6", "minipass-sized": "^1.0.3", "minizlib": "^2.1.2" }, "optionalDependencies": { "encoding": "^0.1.13" } }, "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA=="], + "minipass-fetch": ["minipass-fetch@4.0.1", "", { "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", "minizlib": "^3.0.1" }, "optionalDependencies": { "encoding": "^0.1.13" } }, "sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ=="], "minipass-flush": ["minipass-flush@1.0.5", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw=="], @@ -2894,11 +2879,11 @@ "monaco-editor": ["monaco-editor@0.55.1", "", { "dependencies": { "dompurify": "3.2.7", "marked": "14.0.0" } }, "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A=="], - "motion": ["motion@12.23.26", "", { "dependencies": { "framer-motion": "^12.23.26", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-Ll8XhVxY8LXMVYTCfme27WH2GjBrCIzY4+ndr5QKxsK+YwCtOi2B/oBi5jcIbik5doXuWT/4KKDOVAZJkeY5VQ=="], + "motion": ["motion@12.26.2", "", { "dependencies": { "framer-motion": "^12.26.2", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-2Q6g0zK1gUJKhGT742DAe42LgietcdiJ3L3OcYAHCQaC1UkLnn6aC8S/obe4CxYTLAgid2asS1QdQ/blYfo5dw=="], - "motion-dom": ["motion-dom@12.23.23", "", { "dependencies": { "motion-utils": "^12.23.6" } }, "sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA=="], + "motion-dom": ["motion-dom@12.26.2", "", { "dependencies": { "motion-utils": "^12.24.10" } }, "sha512-KLMT1BroY8oKNeliA3JMNJ+nbCIsTKg6hJpDb4jtRAJ7nCKnnpg/LTq/NGqG90Limitz3kdAnAVXecdFVGlWTw=="], - "motion-utils": ["motion-utils@12.23.6", "", {}, "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ=="], + "motion-utils": ["motion-utils@12.24.10", "", {}, "sha512-x5TFgkCIP4pPsRLpKoI86jv/q8t8FQOiM/0E8QKBzfMozWHfkKap2gA1hOki+B5g3IsBNpxbUnfOum1+dgvYww=="], "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], @@ -2914,7 +2899,7 @@ "neverthrow": ["neverthrow@7.2.0", "", {}, "sha512-iGBUfFB7yPczHHtA8dksKTJ9E8TESNTAx1UQWW6TzMF280vo9jdPYpLUXrMN1BCkPdHFdNG3fxOt2CUad8KhAw=="], - "next": ["next@16.0.10", "", { "dependencies": { "@next/env": "16.0.10", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.0.10", "@next/swc-darwin-x64": "16.0.10", "@next/swc-linux-arm64-gnu": "16.0.10", "@next/swc-linux-arm64-musl": "16.0.10", "@next/swc-linux-x64-gnu": "16.0.10", "@next/swc-linux-x64-musl": "16.0.10", "@next/swc-win32-arm64-msvc": "16.0.10", "@next/swc-win32-x64-msvc": "16.0.10", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-RtWh5PUgI+vxlV3HdR+IfWA1UUHu0+Ram/JBO4vWB54cVPentCD0e+lxyAYEsDTqGGMg7qpjhKh6dc6aW7W/sA=="], + "next": ["next@16.1.1", "", { "dependencies": { "@next/env": "16.1.1", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.1.1", "@next/swc-darwin-x64": "16.1.1", "@next/swc-linux-arm64-gnu": "16.1.1", "@next/swc-linux-arm64-musl": "16.1.1", "@next/swc-linux-x64-gnu": "16.1.1", "@next/swc-linux-x64-musl": "16.1.1", "@next/swc-win32-arm64-msvc": "16.1.1", "@next/swc-win32-x64-msvc": "16.1.1", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-QI+T7xrxt1pF6SQ/JYFz95ro/mg/1Znk5vBebsWwbpejj1T0A23hO7GYEaVac9QUOT2BIMiuzm0L99ooq7k0/w=="], "next-themes": ["next-themes@0.4.6", "", { "peerDependencies": { "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA=="], @@ -2926,11 +2911,13 @@ "node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], + "node-gyp": ["node-gyp@11.5.0", "", { "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", "make-fetch-happen": "^14.0.3", "nopt": "^8.0.0", "proc-log": "^5.0.0", "semver": "^7.3.5", "tar": "^7.4.3", "tinyglobby": "^0.2.12", "which": "^5.0.0" }, "bin": { "node-gyp": "bin/node-gyp.js" } }, "sha512-ra7Kvlhxn5V9Slyus0ygMa2h+UqExPqUIkfk7Pc8QTLT956JLSy51uWFwHtIYy0vI8cB4BDhc/S03+880My/LQ=="], + "node-pty": ["node-pty@1.1.0-beta30", "", { "dependencies": { "node-addon-api": "^7.1.0" } }, "sha512-cmNYVWfbf961aOqnxIFXssvw6Fp6/78BQBNlwYRWUHBenJjUhCJ1wMZpJy+SegoLC07P9D6HTtq39Kd89rpv/w=="], "node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="], - "nopt": ["nopt@6.0.0", "", { "dependencies": { "abbrev": "^1.0.0" }, "bin": { "nopt": "bin/nopt.js" } }, "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g=="], + "nopt": ["nopt@8.1.0", "", { "dependencies": { "abbrev": "^3.0.0" }, "bin": { "nopt": "bin/nopt.js" } }, "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A=="], "normalize-package-data": ["normalize-package-data@4.0.1", "", { "dependencies": { "hosted-git-info": "^5.0.0", "is-core-module": "^2.8.1", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4" } }, "sha512-EBk5QKKuocMJhB3BILuKhmaPjI8vNRSpIfO9woLC6NyHVkKKdVEdAO1mrT0ZfxNR1lKwCcTkuZfmGIFdizZ8Pg=="], @@ -2976,7 +2963,7 @@ "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], - "p-map": ["p-map@4.0.0", "", { "dependencies": { "aggregate-error": "^3.0.0" } }, "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ=="], + "p-map": ["p-map@7.0.4", "", {}, "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ=="], "package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], @@ -3008,8 +2995,6 @@ "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], - "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], - "path-scurry": ["path-scurry@2.0.1", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA=="], "path-to-regexp": ["path-to-regexp@8.3.0", "", {}, "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA=="], @@ -3024,7 +3009,7 @@ "pg-int8": ["pg-int8@1.0.1", "", {}, "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="], - "pg-protocol": ["pg-protocol@1.10.3", "", {}, "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ=="], + "pg-protocol": ["pg-protocol@1.11.0", "", {}, "sha512-pfsxk2M9M3BuGgDOfuy37VNRRX3jmKgMjcvAcWqNDpZSf4cUmv8HSOl5ViRQFsfARFn0KuUQTgLxVMbNq5NW3g=="], "pg-types": ["pg-types@2.2.0", "", { "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", "postgres-bytea": "~1.0.0", "postgres-date": "~1.0.4", "postgres-interval": "^1.1.0" } }, "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA=="], @@ -3050,7 +3035,7 @@ "postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="], - "postgres-bytea": ["postgres-bytea@1.0.0", "", {}, "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w=="], + "postgres-bytea": ["postgres-bytea@1.0.1", "", {}, "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ=="], "postgres-date": ["postgres-date@1.0.7", "", {}, "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="], @@ -3058,13 +3043,13 @@ "posthog-js": ["posthog-js@1.310.1", "", { "dependencies": { "@posthog/core": "1.9.0", "core-js": "^3.38.1", "fflate": "^0.4.8", "preact": "^10.19.3", "web-vitals": "^4.2.4" } }, "sha512-UkR6zzlWNtqHDXHJl2Yk062DOmZyVKTPL5mX4j4V+u3RiYbMHJe47+PpMMUsvK1R2e1r/m9uSlHaJMJRzyUjGg=="], - "posthog-node": ["posthog-node@5.18.0", "", { "dependencies": { "@posthog/core": "1.9.0" } }, "sha512-SLBEs+sCThxzTGSSDEe97nZHuFFYh6DupObR1yQdvQND3CJh0ogZ0Sa1Vb+Tbrnf0cWbfBC9XNkm44yhaWf3aA=="], + "posthog-node": ["posthog-node@5.21.0", "", { "dependencies": { "@posthog/core": "1.9.1" } }, "sha512-M7v/+Zyz/z3ZDC4u896K2Lb/pLbPA1Czo6Tp/WeQ1vuBsJtJajqWO3vRev3BHFTP92nao5YCrU0aIM+Flwbv1A=="], "postject": ["postject@1.0.0-alpha.6", "", { "dependencies": { "commander": "^9.4.0" }, "bin": { "postject": "dist/cli.js" } }, "sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A=="], "potpack": ["potpack@1.0.2", "", {}, "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ=="], - "preact": ["preact@10.28.0", "", {}, "sha512-rytDAoiXr3+t6OIP3WGlDd0ouCUG1iCWzkcY3++Nreuoi17y6T5i/zRhe6uYfoVcxq6YU+sBtJouuRDsq8vvqA=="], + "preact": ["preact@10.28.2", "", {}, "sha512-lbteaWGzGHdlIuiJ0l2Jq454m6kcpI1zNje6d8MlGAFlYvP2GO4ibnat7P74Esfz4sPTdM6UxtTwh/d3pwM9JA=="], "prebuild-install": ["prebuild-install@7.1.3", "", { "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^2.0.0", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" } }, "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug=="], @@ -3074,14 +3059,12 @@ "prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="], - "proc-log": ["proc-log@2.0.1", "", {}, "sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw=="], + "proc-log": ["proc-log@5.0.0", "", {}, "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ=="], "process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="], "progress": ["progress@2.0.3", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="], - "promise-inflight": ["promise-inflight@1.0.1", "", {}, "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g=="], - "promise-retry": ["promise-retry@2.0.1", "", { "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" } }, "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g=="], "promise-stream-reader": ["promise-stream-reader@1.0.1", "", {}, "sha512-Tnxit5trUjBAqqZCGWwjyxhmgMN4hGrtpW3Oc/tRI4bpm/O2+ej72BB08l6JBnGQgVDGCLvHFGjGgQS6vzhwXg=="], @@ -3102,7 +3085,7 @@ "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], - "qs": ["qs@6.14.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w=="], + "qs": ["qs@6.14.1", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ=="], "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], @@ -3122,7 +3105,7 @@ "react-arborist": ["react-arborist@3.4.3", "", { "dependencies": { "react-dnd": "^14.0.3", "react-dnd-html5-backend": "^14.0.3", "react-window": "^1.8.11", "redux": "^5.0.0", "use-sync-external-store": "^1.2.0" }, "peerDependencies": { "react": ">= 16.14", "react-dom": ">= 16.14" } }, "sha512-yFnq1nIQhT2uJY4TZVz2tgAiBb9lxSyvF4vC3S8POCK8xLzjGIxVv3/4dmYquQJ7AHxaZZArRGHiHKsEewKdTQ=="], - "react-day-picker": ["react-day-picker@9.12.0", "", { "dependencies": { "@date-fns/tz": "^1.4.1", "date-fns": "^4.1.0", "date-fns-jalali": "^4.1.0-0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-t8OvG/Zrciso5CQJu5b1A7yzEmebvST+S3pOVQJWxwjjVngyG/CA2htN/D15dLI4uTEuLLkbZyS4YYt480FAtA=="], + "react-day-picker": ["react-day-picker@9.13.0", "", { "dependencies": { "@date-fns/tz": "^1.4.1", "date-fns": "^4.1.0", "date-fns-jalali": "^4.1.0-0" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-euzj5Hlq+lOHqI53NiuNhCP8HWgsPf/bBAVijR50hNaY1XwjKjShAnIe8jm8RD2W9IJUvihDIZ+KrmqfFzNhFQ=="], "react-devtools-core": ["react-devtools-core@7.0.1", "", { "dependencies": { "shell-quote": "^1.6.1", "ws": "^7" } }, "sha512-C3yNvRHaizlpiASzy7b9vbnBGLrhvdhl1CbdU6EnZgxPNbai60szdLtl+VL76UNOt5bOoVTOz5rNWZxgGt+Gsw=="], @@ -3142,7 +3125,7 @@ "react-fast-marquee": ["react-fast-marquee@1.6.5", "", { "peerDependencies": { "react": ">= 16.8.0 || ^18.0.0", "react-dom": ">= 16.8.0 || ^18.0.0" } }, "sha512-swDnPqrT2XISAih0o74zQVE2wQJFMvkx+9VZXYYNSLb/CUcAzU9pNj637Ar2+hyRw6b4tP6xh4GQZip2ZCpQpg=="], - "react-hook-form": ["react-hook-form@7.68.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "sha512-oNN3fjrZ/Xo40SWlHf1yCjlMK417JxoSJVUXQjGdvdRCU07NTFei1i1f8ApUAts+IVh14e4EdakeLEA+BEAs/Q=="], + "react-hook-form": ["react-hook-form@7.71.1", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "sha512-9SUJKCGKo8HUSsCO+y0CtqkqI5nNuaDqTxyqPsZPqIwudpj4rCrAz/jZV+jn57bx5gtZKOh3neQu94DXMc+w5w=="], "react-icons": ["react-icons@5.5.0", "", { "peerDependencies": { "react": "*" } }, "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw=="], @@ -3272,8 +3255,6 @@ "resedit": ["resedit@1.7.2", "", { "dependencies": { "pe-library": "^0.4.1" } }, "sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA=="], - "resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="], - "resolve-alpn": ["resolve-alpn@1.2.1", "", {}, "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g=="], "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], @@ -3292,7 +3273,7 @@ "robust-predicates": ["robust-predicates@3.0.2", "", {}, "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg=="], - "rollup": ["rollup@4.53.3", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.53.3", "@rollup/rollup-android-arm64": "4.53.3", "@rollup/rollup-darwin-arm64": "4.53.3", "@rollup/rollup-darwin-x64": "4.53.3", "@rollup/rollup-freebsd-arm64": "4.53.3", "@rollup/rollup-freebsd-x64": "4.53.3", "@rollup/rollup-linux-arm-gnueabihf": "4.53.3", "@rollup/rollup-linux-arm-musleabihf": "4.53.3", "@rollup/rollup-linux-arm64-gnu": "4.53.3", "@rollup/rollup-linux-arm64-musl": "4.53.3", "@rollup/rollup-linux-loong64-gnu": "4.53.3", "@rollup/rollup-linux-ppc64-gnu": "4.53.3", "@rollup/rollup-linux-riscv64-gnu": "4.53.3", "@rollup/rollup-linux-riscv64-musl": "4.53.3", "@rollup/rollup-linux-s390x-gnu": "4.53.3", "@rollup/rollup-linux-x64-gnu": "4.53.3", "@rollup/rollup-linux-x64-musl": "4.53.3", "@rollup/rollup-openharmony-arm64": "4.53.3", "@rollup/rollup-win32-arm64-msvc": "4.53.3", "@rollup/rollup-win32-ia32-msvc": "4.53.3", "@rollup/rollup-win32-x64-gnu": "4.53.3", "@rollup/rollup-win32-x64-msvc": "4.53.3", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA=="], + "rollup": ["rollup@4.55.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.55.1", "@rollup/rollup-android-arm64": "4.55.1", "@rollup/rollup-darwin-arm64": "4.55.1", "@rollup/rollup-darwin-x64": "4.55.1", "@rollup/rollup-freebsd-arm64": "4.55.1", "@rollup/rollup-freebsd-x64": "4.55.1", "@rollup/rollup-linux-arm-gnueabihf": "4.55.1", "@rollup/rollup-linux-arm-musleabihf": "4.55.1", "@rollup/rollup-linux-arm64-gnu": "4.55.1", "@rollup/rollup-linux-arm64-musl": "4.55.1", "@rollup/rollup-linux-loong64-gnu": "4.55.1", "@rollup/rollup-linux-loong64-musl": "4.55.1", "@rollup/rollup-linux-ppc64-gnu": "4.55.1", "@rollup/rollup-linux-ppc64-musl": "4.55.1", "@rollup/rollup-linux-riscv64-gnu": "4.55.1", "@rollup/rollup-linux-riscv64-musl": "4.55.1", "@rollup/rollup-linux-s390x-gnu": "4.55.1", "@rollup/rollup-linux-x64-gnu": "4.55.1", "@rollup/rollup-linux-x64-musl": "4.55.1", "@rollup/rollup-openbsd-x64": "4.55.1", "@rollup/rollup-openharmony-arm64": "4.55.1", "@rollup/rollup-win32-arm64-msvc": "4.55.1", "@rollup/rollup-win32-ia32-msvc": "4.55.1", "@rollup/rollup-win32-x64-gnu": "4.55.1", "@rollup/rollup-win32-x64-msvc": "4.55.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A=="], "rollup-plugin-inject-process-env": ["rollup-plugin-inject-process-env@1.3.1", "", { "dependencies": { "magic-string": "^0.25.7" } }, "sha512-kKDoL30IZr0wxbNVJjq+OS92RJSKRbKV6B5eNW4q3mZTFqoWDh6lHy+mPDYuuGuERFNKXkG+AKxvYqC9+DRpKQ=="], @@ -3312,7 +3293,7 @@ "sanitize-filename": ["sanitize-filename@1.6.3", "", { "dependencies": { "truncate-utf8-bytes": "^1.0.0" } }, "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg=="], - "sax": ["sax@1.4.3", "", {}, "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ=="], + "sax": ["sax@1.4.4", "", {}, "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw=="], "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], @@ -3326,7 +3307,7 @@ "semver-compare": ["semver-compare@1.0.0", "", {}, "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow=="], - "send": ["send@1.2.0", "", { "dependencies": { "debug": "^4.3.5", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.0", "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.1" } }, "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw=="], + "send": ["send@1.2.1", "", { "dependencies": { "debug": "^4.4.3", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "fresh": "^2.0.0", "http-errors": "^2.0.1", "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", "statuses": "^2.0.2" } }, "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ=="], "serialize-error": ["serialize-error@7.0.1", "", { "dependencies": { "type-fest": "^0.13.1" } }, "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw=="], @@ -3336,7 +3317,7 @@ "seroval-plugins": ["seroval-plugins@1.4.2", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-X7p4MEDTi+60o2sXZ4bnDBhgsUYDSkQEvzYZuJyFqWg9jcoPsHts5nrg5O956py2wyt28lUrBxk0M0/wU8URpA=="], - "serve-static": ["serve-static@2.2.0", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ=="], + "serve-static": ["serve-static@2.2.1", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="], "server-only": ["server-only@0.0.1", "", {}, "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA=="], @@ -3352,7 +3333,7 @@ "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], - "shell-env": ["shell-env@4.0.1", "", { "dependencies": { "default-shell": "^2.0.0", "execa": "^5.1.1", "strip-ansi": "^7.0.1" } }, "sha512-w3oeZ9qg/P6Lu6qqwavvMnB/bwfsz67gPB3WXmLd/n6zuh7TWQZtGa3iMEdmua0kj8rivkwl+vUjgLWlqZOMPw=="], + "shell-env": ["shell-env@4.0.2", "", { "dependencies": { "default-shell": "^2.0.0", "execa": "^5.1.1", "strip-ansi": "^7.0.1" } }, "sha512-8VJLnsyY//uoDJYl7hBcPdX54x0LaKbbfo5htiv8v/jrR4MD7uRUEom6Cb+S54ugMM9GkBbQJSwlLNCI3VXAHQ=="], "shell-quote": ["shell-quote@1.8.3", "", {}, "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw=="], @@ -3374,7 +3355,7 @@ "sherif-windows-x64": ["sherif-windows-x64@1.9.0", "", { "os": "win32", "cpu": "x64" }, "sha512-3cL+XVGLpmyLC3UOZYiPr4vY2OFBQqPZnCoCwoRKN+ONm8VfGMirO9iqI0OckgFBUtJoG4AQY/MWxoPhNmzD8A=="], - "shiki": ["shiki@3.19.0", "", { "dependencies": { "@shikijs/core": "3.19.0", "@shikijs/engine-javascript": "3.19.0", "@shikijs/engine-oniguruma": "3.19.0", "@shikijs/langs": "3.19.0", "@shikijs/themes": "3.19.0", "@shikijs/types": "3.19.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-77VJr3OR/VUZzPiStyRhADmO2jApMM0V2b1qf0RpfWya8Zr1PeZev5AEpPGAAKWdiYUtcZGBE4F5QvJml1PvWA=="], + "shiki": ["shiki@3.21.0", "", { "dependencies": { "@shikijs/core": "3.21.0", "@shikijs/engine-javascript": "3.21.0", "@shikijs/engine-oniguruma": "3.21.0", "@shikijs/langs": "3.21.0", "@shikijs/themes": "3.21.0", "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-N65B/3bqL/TI2crrXr+4UivctrAGEjmsib5rPMMPpFp1xAx/w03v8WZ9RDDFYteXoEgY7qZ4HGgl5KBIu1153w=="], "side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="], @@ -3408,7 +3389,7 @@ "socks": ["socks@2.8.7", "", { "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" } }, "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A=="], - "socks-proxy-agent": ["socks-proxy-agent@7.0.0", "", { "dependencies": { "agent-base": "^6.0.2", "debug": "^4.3.3", "socks": "^2.6.2" } }, "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww=="], + "socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="], "sonner": ["sonner@2.0.7", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w=="], @@ -3434,7 +3415,7 @@ "sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="], - "ssri": ["ssri@9.0.1", "", { "dependencies": { "minipass": "^3.1.1" } }, "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q=="], + "ssri": ["ssri@12.0.0", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ=="], "stack-utils": ["stack-utils@2.0.6", "", { "dependencies": { "escape-string-regexp": "^2.0.0" } }, "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ=="], @@ -3454,7 +3435,7 @@ "steno": ["steno@4.0.2", "", {}, "sha512-yhPIQXjrlt1xv7dyPQg2P17URmXbuM5pdGkpiMB3RenprfiBlvK415Lctfe0eshk90oA7/tNq7WEiMK8RSP39A=="], - "streamdown": ["streamdown@1.6.10", "", { "dependencies": { "clsx": "^2.1.1", "hast": "^1.0.0", "hast-util-to-jsx-runtime": "^2.3.6", "html-url-attributes": "^3.0.1", "katex": "^0.16.22", "lucide-react": "^0.542.0", "marked": "^16.2.1", "mermaid": "^11.11.0", "rehype-harden": "^1.1.6", "rehype-katex": "^7.0.1", "rehype-raw": "^7.0.0", "remark-cjk-friendly": "^1.2.3", "remark-cjk-friendly-gfm-strikethrough": "^1.2.3", "remark-gfm": "^4.0.1", "remark-math": "^6.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remend": "1.0.1", "shiki": "^3.12.2", "tailwind-merge": "^3.3.1", "unified": "^11.0.5", "unist-util-visit": "^5.0.0" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0" } }, "sha512-B4Y3Z/qiXl1Dc+LzAB5c52Cd1QGRiFjaDwP+ERoj1JtCykdRDM8X6HwQnn3YkpkSk0x3R7S/6LrGe1nQiElHQQ=="], + "streamdown": ["streamdown@1.6.11", "", { "dependencies": { "clsx": "^2.1.1", "hast": "^1.0.0", "hast-util-to-jsx-runtime": "^2.3.6", "html-url-attributes": "^3.0.1", "katex": "^0.16.22", "lucide-react": "^0.542.0", "marked": "^16.2.1", "mermaid": "^11.11.0", "rehype-harden": "^1.1.6", "rehype-katex": "^7.0.1", "rehype-raw": "^7.0.0", "rehype-sanitize": "^6.0.0", "remark-cjk-friendly": "^1.2.3", "remark-cjk-friendly-gfm-strikethrough": "^1.2.3", "remark-gfm": "^4.0.1", "remark-math": "^6.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remend": "1.0.1", "shiki": "^3.12.2", "tailwind-merge": "^3.3.1", "unified": "^11.0.5", "unist-util-visit": "^5.0.0" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0" } }, "sha512-Y38fwRx5kCKTluwM+Gf27jbbi9q6Qy+WC9YrC1YbCpMkktT3PsRBJHMWiqYeF8y/JzLpB1IzDoeaB6qkQEDnAA=="], "string-width": ["string-width@8.1.0", "", { "dependencies": { "get-east-asian-width": "^1.3.0", "strip-ansi": "^7.1.0" } }, "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg=="], @@ -3496,8 +3477,6 @@ "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], - "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], - "suspend-react": ["suspend-react@0.1.3", "", { "peerDependencies": { "react": ">=17.0" } }, "sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ=="], "tagged-tag": ["tagged-tag@1.0.0", "", {}, "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng=="], @@ -3588,19 +3567,19 @@ "tunnel-rat": ["tunnel-rat@0.1.2", "", { "dependencies": { "zustand": "^4.3.2" } }, "sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ=="], - "turbo": ["turbo@2.6.3", "", { "optionalDependencies": { "turbo-darwin-64": "2.6.3", "turbo-darwin-arm64": "2.6.3", "turbo-linux-64": "2.6.3", "turbo-linux-arm64": "2.6.3", "turbo-windows-64": "2.6.3", "turbo-windows-arm64": "2.6.3" }, "bin": { "turbo": "bin/turbo" } }, "sha512-bf6YKUv11l5Xfcmg76PyWoy/e2vbkkxFNBGJSnfdSXQC33ZiUfutYh6IXidc5MhsnrFkWfdNNLyaRk+kHMLlwA=="], + "turbo": ["turbo@2.7.4", "", { "optionalDependencies": { "turbo-darwin-64": "2.7.4", "turbo-darwin-arm64": "2.7.4", "turbo-linux-64": "2.7.4", "turbo-linux-arm64": "2.7.4", "turbo-windows-64": "2.7.4", "turbo-windows-arm64": "2.7.4" }, "bin": { "turbo": "bin/turbo" } }, "sha512-bkO4AddmDishzJB2ze7aYYPaejMoJVfS0XnaR6RCdXFOY8JGJfQE+l9fKiV7uDPa5Ut44gmOWJL3894CIMeH9g=="], - "turbo-darwin-64": ["turbo-darwin-64@2.6.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-BlJJDc1CQ7SK5Y5qnl7AzpkvKSnpkfPmnA+HeU/sgny3oHZckPV2776ebO2M33CYDSor7+8HQwaodY++IINhYg=="], + "turbo-darwin-64": ["turbo-darwin-64@2.7.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-xDR30ltfkSsRfGzABBckvl1nz1cZ3ssTujvdj+TPwOweeDRvZ0e06t5DS0rmRBvyKpgGs42K/EK6Mn2qLlFY9A=="], - "turbo-darwin-arm64": ["turbo-darwin-arm64@2.6.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-MwVt7rBKiOK7zdYerenfCRTypefw4kZCue35IJga9CH1+S50+KTiCkT6LBqo0hHeoH2iKuI0ldTF2a0aB72z3w=="], + "turbo-darwin-arm64": ["turbo-darwin-arm64@2.7.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-P7sjqXtOL/+nYWPvcDGWhi8wf8M8mZHHB8XEzw2VX7VJrS8IGHyJHGD1AYfDvhAEcr7pnk3gGifz3/xyhI655w=="], - "turbo-linux-64": ["turbo-linux-64@2.6.3", "", { "os": "linux", "cpu": "x64" }, "sha512-cqpcw+dXxbnPtNnzeeSyWprjmuFVpHJqKcs7Jym5oXlu/ZcovEASUIUZVN3OGEM6Y/OTyyw0z09tOHNt5yBAVg=="], + "turbo-linux-64": ["turbo-linux-64@2.7.4", "", { "os": "linux", "cpu": "x64" }, "sha512-GofFOxRO/IhG8BcPyMSSB3Y2+oKQotsaYbHxL9yD6JPb20/o35eo+zUSyazOtilAwDHnak5dorAJFoFU8MIg2A=="], - "turbo-linux-arm64": ["turbo-linux-arm64@2.6.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-MterpZQmjXyr4uM7zOgFSFL3oRdNKeflY7nsjxJb2TklsYqiu3Z9pQ4zRVFFH8n0mLGna7MbQMZuKoWqqHb45w=="], + "turbo-linux-arm64": ["turbo-linux-arm64@2.7.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-+RQKgNjksVPxYAyAgmDV7w/1qj++qca+nSNTAOKGOfJiDtSvRKoci89oftJ6anGs00uamLKVEQ712TI/tfNAIw=="], - "turbo-windows-64": ["turbo-windows-64@2.6.3", "", { "os": "win32", "cpu": "x64" }, "sha512-biDU70v9dLwnBdLf+daoDlNJVvqOOP8YEjqNipBHzgclbQlXbsi6Gqqelp5er81Qo3BiRgmTNx79oaZQTPb07Q=="], + "turbo-windows-64": ["turbo-windows-64@2.7.4", "", { "os": "win32", "cpu": "x64" }, "sha512-rfak1+g+ON3czs1mDYsCS4X74ZmK6gOgRQTXjDICtzvR4o61paqtgAYtNPofcVsMWeF4wvCajSeoAkkeAnQ1kg=="], - "turbo-windows-arm64": ["turbo-windows-arm64@2.6.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-dDHVKpSeukah3VsI/xMEKeTnV9V9cjlpFSUs4bmsUiLu3Yv2ENlgVEZv65wxbeE0bh0jjpmElDT+P1KaCxArQQ=="], + "turbo-windows-arm64": ["turbo-windows-arm64@2.7.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-1ZgBNjNRbDu/fPeqXuX9i26x3CJ/Y1gcwUpQ+Vp7kN9Un6RZ9kzs164f/knrjcu5E+szCRexVjRSJay1k5jApA=="], "tw-animate-css": ["tw-animate-css@1.4.0", "", {}, "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ=="], @@ -3610,7 +3589,7 @@ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], - "ufo": ["ufo@1.6.1", "", {}, "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA=="], + "ufo": ["ufo@1.6.2", "", {}, "sha512-heMioaxBcG9+Znsda5Q8sQbWnLJSl98AFDXTO80wELWEzX3hordXsTdxrIfMQoO9IY1MEnoGoPjpoKpMj+Yx0Q=="], "uint8array-extras": ["uint8array-extras@1.5.0", "", {}, "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A=="], @@ -3624,11 +3603,11 @@ "unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="], - "unique-filename": ["unique-filename@2.0.1", "", { "dependencies": { "unique-slug": "^3.0.0" } }, "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A=="], + "unique-filename": ["unique-filename@4.0.0", "", { "dependencies": { "unique-slug": "^5.0.0" } }, "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ=="], "unique-names-generator": ["unique-names-generator@4.7.1", "", {}, "sha512-lMx9dX+KRmG8sq6gulYYpKWZc9RlGsgBR6aoO8Qsm3qvkSJ+3rAymr+TnV8EDMrIrwuFJ4kruzMWM/OpYzPoow=="], - "unique-slug": ["unique-slug@3.0.0", "", { "dependencies": { "imurmurhash": "^0.1.4" } }, "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w=="], + "unique-slug": ["unique-slug@5.0.0", "", { "dependencies": { "imurmurhash": "^0.1.4" } }, "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg=="], "unist-util-filter": ["unist-util-filter@5.0.1", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-pHx7D4Zt6+TsfwylH9+lYhBhzyhEnCXs/lbq/Hstxno5z4gVdyc2WEW0asfjGKPyG4pEKrnBv5hdkO6+aRnQJw=="], @@ -3654,7 +3633,7 @@ "unplugin": ["unplugin@2.3.11", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "acorn": "^8.15.0", "picomatch": "^4.0.3", "webpack-virtual-modules": "^0.6.2" } }, "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww=="], - "update-browserslist-db": ["update-browserslist-db@1.2.2", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA=="], + "update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="], "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], @@ -3690,7 +3669,7 @@ "victory-vendor": ["victory-vendor@36.9.2", "", { "dependencies": { "@types/d3-array": "^3.0.3", "@types/d3-ease": "^3.0.0", "@types/d3-interpolate": "^3.0.1", "@types/d3-scale": "^4.0.2", "@types/d3-shape": "^3.1.0", "@types/d3-time": "^3.0.0", "@types/d3-timer": "^3.0.0", "d3-array": "^3.1.6", "d3-ease": "^3.0.1", "d3-interpolate": "^3.0.1", "d3-scale": "^4.0.2", "d3-shape": "^3.1.0", "d3-time": "^3.0.0", "d3-timer": "^3.0.1" } }, "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ=="], - "vite": ["vite@7.2.7", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-ITcnkFeR3+fI8P1wMgItjGrR10170d8auB4EpMLPqmx6uxElH3a/hHGQabSHKdqd4FXWO1nFIp9rRn7JQ34ACQ=="], + "vite": ["vite@7.3.1", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA=="], "vite-tsconfig-paths": ["vite-tsconfig-paths@5.1.4", "", { "dependencies": { "debug": "^4.1.1", "globrex": "^0.1.2", "tsconfck": "^3.0.3" }, "peerDependencies": { "vite": "*" }, "optionalPeers": ["vite"] }, "sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w=="], @@ -3706,7 +3685,7 @@ "vscode-uri": ["vscode-uri@3.0.8", "", {}, "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw=="], - "watchpack": ["watchpack@2.4.4", "", { "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" } }, "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA=="], + "watchpack": ["watchpack@2.5.0", "", { "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" } }, "sha512-e6vZvY6xboSwLz2GD36c16+O/2Z6fKvIf4pOXptw2rY9MVwE/TXc6RGqxD3I3x0a28lwBY7DE+76uTPSsBrrCA=="], "wcwidth": ["wcwidth@1.0.1", "", { "dependencies": { "defaults": "^1.0.3" } }, "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg=="], @@ -3740,7 +3719,7 @@ "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], - "ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="], + "ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="], "xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="], @@ -3750,8 +3729,6 @@ "yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], - "yaml": ["yaml@2.8.2", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A=="], - "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], @@ -3764,9 +3741,9 @@ "yoga-layout": ["yoga-layout@3.2.1", "", {}, "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ=="], - "zod": ["zod@4.1.13", "", {}, "sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig=="], + "zod": ["zod@4.3.5", "", {}, "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g=="], - "zustand": ["zustand@5.0.9", "", { "peerDependencies": { "@types/react": ">=18.0.0", "immer": ">=9.0.6", "react": ">=18.0.0", "use-sync-external-store": ">=1.2.0" }, "optionalPeers": ["@types/react", "immer", "react", "use-sync-external-store"] }, "sha512-ALBtUj0AfjJt3uNRQoL1tL2tMvj6Gp/6e39dnfT6uzpelGru8v1tPOGBzayOWbPJvujM8JojDk3E1LxeFisBNg=="], + "zustand": ["zustand@5.0.10", "", { "peerDependencies": { "@types/react": ">=18.0.0", "immer": ">=9.0.6", "react": ">=18.0.0", "use-sync-external-store": ">=1.2.0" }, "optionalPeers": ["@types/react", "immer", "react", "use-sync-external-store"] }, "sha512-U1AiltS1O9hSy3rul+Ub82ut2fqIAefiSuwECWt6jlMVUGejvf+5omLcRBSzqbRagSM3hQZbtzdeRc6QVScXTg=="], "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], @@ -3776,11 +3753,9 @@ "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "@babel/plugin-transform-arrow-functions/@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.27.1", "", {}, "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw=="], - - "@babel/plugin-transform-react-jsx-self/@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.27.1", "", {}, "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw=="], + "@chevrotain/cst-dts-gen/lodash-es": ["lodash-es@4.17.21", "", {}, "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="], - "@babel/plugin-transform-react-jsx-source/@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.27.1", "", {}, "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw=="], + "@chevrotain/gast/lodash-es": ["lodash-es@4.17.21", "", {}, "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="], "@code-inspector/core/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], @@ -3790,8 +3765,6 @@ "@develar/schema-utils/ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], - "@develar/schema-utils/ajv-keywords": ["ajv-keywords@3.5.2", "", { "peerDependencies": { "ajv": "^6.9.1" } }, "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="], - "@electron/asar/commander": ["commander@5.1.0", "", {}, "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg=="], "@electron/asar/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], @@ -3806,19 +3779,19 @@ "@electron/get/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "@electron/node-gyp/glob": ["glob@8.1.0", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^5.0.1", "once": "^1.3.0" } }, "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ=="], - "@electron/notarize/fs-extra": ["fs-extra@9.1.0", "", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="], "@electron/osx-sign/isbinaryfile": ["isbinaryfile@4.0.10", "", {}, "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw=="], "@electron/rebuild/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + "@electron/rebuild/node-abi": ["node-abi@4.24.0", "", { "dependencies": { "semver": "^7.6.3" } }, "sha512-u2EC1CeNe25uVtX3EZbdQ275c74zdZmmpzrHEQh2aIYqoVjlglfUpOX9YY85x1nlBydEKDVaSmMNhR7N82Qj8A=="], + "@electron/rebuild/ora": ["ora@5.4.1", "", { "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", "cli-cursor": "^3.1.0", "cli-spinners": "^2.5.0", "is-interactive": "^1.0.0", "is-unicode-supported": "^0.1.0", "log-symbols": "^4.1.0", "strip-ansi": "^6.0.0", "wcwidth": "^1.0.1" } }, "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ=="], - "@electron/universal/fs-extra": ["fs-extra@11.3.2", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A=="], + "@electron/universal/fs-extra": ["fs-extra@11.3.3", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg=="], - "@electron/windows-sign/fs-extra": ["fs-extra@11.3.2", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A=="], + "@electron/windows-sign/fs-extra": ["fs-extra@11.3.3", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg=="], "@esbuild-kit/core-utils/esbuild": ["esbuild@0.18.20", "", { "optionalDependencies": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", "@esbuild/android-x64": "0.18.20", "@esbuild/darwin-arm64": "0.18.20", "@esbuild/darwin-x64": "0.18.20", "@esbuild/freebsd-arm64": "0.18.20", "@esbuild/freebsd-x64": "0.18.20", "@esbuild/linux-arm": "0.18.20", "@esbuild/linux-arm64": "0.18.20", "@esbuild/linux-ia32": "0.18.20", "@esbuild/linux-loong64": "0.18.20", "@esbuild/linux-mips64el": "0.18.20", "@esbuild/linux-ppc64": "0.18.20", "@esbuild/linux-riscv64": "0.18.20", "@esbuild/linux-s390x": "0.18.20", "@esbuild/linux-x64": "0.18.20", "@esbuild/netbsd-x64": "0.18.20", "@esbuild/openbsd-x64": "0.18.20", "@esbuild/sunos-x64": "0.18.20", "@esbuild/win32-arm64": "0.18.20", "@esbuild/win32-ia32": "0.18.20", "@esbuild/win32-x64": "0.18.20" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA=="], @@ -3830,9 +3803,11 @@ "@mdx-js/mdx/estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], - "@neondatabase/serverless/@types/node": ["@types/node@22.19.2", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-LPM2G3Syo1GLzXLGJAKdqoU35XvrWzGJ21/7sgZTUpbkBaOasTj8tjwn6w+hCkqaa1TfJ/w67rJSwYItlJ2mYw=="], + "@neondatabase/serverless/@types/node": ["@types/node@22.19.6", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-qm+G8HuG6hOHQigsi7VGuLjUVu6TtBo/F05zvX04Mw2uCg9Dv0Qxy3Qw7j41SidlTcl5D/5yg0SEZqOB+EqZnQ=="], + + "@npmcli/agent/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], - "@npmcli/move-file/rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="], + "@opentelemetry/instrumentation-http/@opentelemetry/core": ["@opentelemetry/core@2.2.0", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw=="], "@opentelemetry/instrumentation-pg/@types/pg": ["@types/pg@8.15.6", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ=="], @@ -3874,10 +3849,6 @@ "@react-three/drei/cross-env": ["cross-env@7.0.3", "", { "dependencies": { "cross-spawn": "^7.0.1" }, "bin": { "cross-env": "src/bin/cross-env.js", "cross-env-shell": "src/bin/cross-env-shell.js" } }, "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw=="], - "@react-three/fiber/react-reconciler": ["react-reconciler@0.31.0", "", { "dependencies": { "scheduler": "^0.25.0" }, "peerDependencies": { "react": "^19.0.0" } }, "sha512-7Ob7Z+URmesIsIVRjnLoDGwBEG/tVitidU0nMsqX/eeJaLY89RISO/10ERe0MqmzuKUUB1rmY+h1itMbUHg9BQ=="], - - "@react-three/fiber/scheduler": ["scheduler@0.25.0", "", {}, "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA=="], - "@sentry-internal/feedback/@sentry/core": ["@sentry/core@10.29.0", "", {}, "sha512-olQ2DU9dA/Bwsz3PtA9KNXRMqBWRQSkPw+MxwWEoU1K1qtiM9L0j6lbEFb5iSY3d7WYD5MB+1d5COugjSBrHtw=="], "@sentry-internal/replay/@sentry-internal/browser-utils": ["@sentry-internal/browser-utils@10.29.0", "", { "dependencies": { "@sentry/core": "10.29.0" } }, "sha512-M3kycMY6f3KY9a8jDYac+yG0E3ZgWVWSxlOEC5MhYyX+g7mqxkwrb3LFQyuxSm/m+CCgMTCaPOOaB2twXP6EQg=="], @@ -3904,42 +3875,26 @@ "@sentry/electron/@sentry/node": ["@sentry/node@10.29.0", "", { "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-async-hooks": "^2.2.0", "@opentelemetry/core": "^2.2.0", "@opentelemetry/instrumentation": "^0.208.0", "@opentelemetry/instrumentation-amqplib": "0.55.0", "@opentelemetry/instrumentation-connect": "0.52.0", "@opentelemetry/instrumentation-dataloader": "0.26.0", "@opentelemetry/instrumentation-express": "0.57.0", "@opentelemetry/instrumentation-fs": "0.28.0", "@opentelemetry/instrumentation-generic-pool": "0.52.0", "@opentelemetry/instrumentation-graphql": "0.56.0", "@opentelemetry/instrumentation-hapi": "0.55.0", "@opentelemetry/instrumentation-http": "0.208.0", "@opentelemetry/instrumentation-ioredis": "0.56.0", "@opentelemetry/instrumentation-kafkajs": "0.18.0", "@opentelemetry/instrumentation-knex": "0.53.0", "@opentelemetry/instrumentation-koa": "0.57.0", "@opentelemetry/instrumentation-lru-memoizer": "0.53.0", "@opentelemetry/instrumentation-mongodb": "0.61.0", "@opentelemetry/instrumentation-mongoose": "0.55.0", "@opentelemetry/instrumentation-mysql": "0.54.0", "@opentelemetry/instrumentation-mysql2": "0.55.0", "@opentelemetry/instrumentation-pg": "0.61.0", "@opentelemetry/instrumentation-redis": "0.57.0", "@opentelemetry/instrumentation-tedious": "0.27.0", "@opentelemetry/instrumentation-undici": "0.19.0", "@opentelemetry/resources": "^2.2.0", "@opentelemetry/sdk-trace-base": "^2.2.0", "@opentelemetry/semantic-conventions": "^1.37.0", "@prisma/instrumentation": "6.19.0", "@sentry/core": "10.29.0", "@sentry/node-core": "10.29.0", "@sentry/opentelemetry": "10.29.0", "import-in-the-middle": "^2", "minimatch": "^9.0.0" } }, "sha512-9j8VzV06VCj+H8tlxpfa7BNN4HzH5exv68WOufdMTXzzWLOXnzrdNDoYplm1G2S3LMvWsc1SVI3a8A0yBY7oWg=="], - "@sentry/react/@sentry/browser": ["@sentry/browser@10.32.1", "", { "dependencies": { "@sentry-internal/browser-utils": "10.32.1", "@sentry-internal/feedback": "10.32.1", "@sentry-internal/replay": "10.32.1", "@sentry-internal/replay-canvas": "10.32.1", "@sentry/core": "10.32.1" } }, "sha512-NPNCXTZ05ZGTFyJdKNqjykpFm+urem0ebosILQiw3C4BxNVNGH4vfYZexyl6prRhmg91oB6GjVNiVDuJiap1gg=="], + "@sentry/react/@sentry/browser": ["@sentry/browser@10.34.0", "", { "dependencies": { "@sentry-internal/browser-utils": "10.34.0", "@sentry-internal/feedback": "10.34.0", "@sentry-internal/replay": "10.34.0", "@sentry-internal/replay-canvas": "10.34.0", "@sentry/core": "10.34.0" } }, "sha512-8WCsAXli5Z+eIN8dMY8KGQjrS3XgUp1np/pjdeWNrVPVR8q8XpS34qc+f+y/LFrYQC9bs2Of5aIBwRtDCIvRsg=="], "@sentry/webpack-plugin/unplugin": ["unplugin@1.0.1", "", { "dependencies": { "acorn": "^8.8.1", "chokidar": "^3.5.3", "webpack-sources": "^3.2.3", "webpack-virtual-modules": "^0.5.0" } }, "sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA=="], "@sentry/webpack-plugin/uuid": ["uuid@9.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="], - "@shikijs/rehype/@shikijs/types": ["@shikijs/types@3.21.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA=="], - - "@shikijs/rehype/shiki": ["shiki@3.21.0", "", { "dependencies": { "@shikijs/core": "3.21.0", "@shikijs/engine-javascript": "3.21.0", "@shikijs/engine-oniguruma": "3.21.0", "@shikijs/langs": "3.21.0", "@shikijs/themes": "3.21.0", "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-N65B/3bqL/TI2crrXr+4UivctrAGEjmsib5rPMMPpFp1xAx/w03v8WZ9RDDFYteXoEgY7qZ4HGgl5KBIu1153w=="], + "@tailwindcss/node/jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], - "@shikijs/transformers/@shikijs/core": ["@shikijs/core@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-AXSQu/2n1UIQekY8euBJlvFYZIw0PHY63jUzGbrOma4wPxzznJXTXkri+QcHeBNaFxiiOljKxxJkVSoB3PjbyA=="], + "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.8.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg=="], - "@shikijs/transformers/@shikijs/types": ["@shikijs/types@3.21.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA=="], - - "@superset/docs/@types/react": ["@types/react@19.2.8", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-3MbSL37jEchWZz2p2mjntRZtPt837ij10ApxKfgmXCTuHWagYg7iA5bqPw6C8BMPfwidlvfPI/fxOc42HLhcyg=="], - - "@superset/docs/next": ["next@16.1.1", "", { "dependencies": { "@next/env": "16.1.1", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.1.1", "@next/swc-darwin-x64": "16.1.1", "@next/swc-linux-arm64-gnu": "16.1.1", "@next/swc-linux-arm64-musl": "16.1.1", "@next/swc-linux-x64-gnu": "16.1.1", "@next/swc-linux-x64-musl": "16.1.1", "@next/swc-win32-arm64-msvc": "16.1.1", "@next/swc-win32-x64-msvc": "16.1.1", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-QI+T7xrxt1pF6SQ/JYFz95ro/mg/1Znk5vBebsWwbpejj1T0A23hO7GYEaVac9QUOT2BIMiuzm0L99ooq7k0/w=="], - - "@superset/docs/zod": ["zod@4.3.5", "", {}, "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g=="], - - "@superset/shared/zod": ["zod@4.3.5", "", {}, "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g=="], - - "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.7.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg=="], - - "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.7.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA=="], + "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="], - "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.0", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" }, "bundled": true }, "sha512-Fq6DJW+Bb5jaWE69/qOE0D1TUN9+6uWhCeZpdnSBk14pjLcCWR7Q8n49PTSPHazM37JqrsdpEthXy2xn6jWWiA=="], + "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" }, "bundled": true }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="], "@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "@tanstack/electric-db-collection/@electric-sql/client": ["@electric-sql/client@1.3.1", "", { "dependencies": { "@microsoft/fetch-event-source": "^2.0.1" }, "optionalDependencies": { "@rollup/rollup-darwin-arm64": "^4.18.1" } }, "sha512-Tr7jY60acKfxuODOzGcJYzEXtTJyiE8l237hMpCPHjflr+qSGYVZ0NkOnFgAE2xIPFgP1zn05nQb3+mkUu8qUQ=="], - "@tanstack/router-generator/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], "@tanstack/router-plugin/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], @@ -3952,11 +3907,11 @@ "@upstash/qstash/jose": ["jose@5.10.0", "", {}, "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg=="], - "@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + "@vue/compiler-core/entities": ["entities@7.0.0", "", {}, "sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ=="], "@xyflow/react/zustand": ["zustand@4.5.7", "", { "dependencies": { "use-sync-external-store": "^1.2.2" }, "peerDependencies": { "@types/react": ">=16.8", "immer": ">=9.0.6", "react": ">=16.8" }, "optionalPeers": ["@types/react", "immer", "react"] }, "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw=="], - "aggregate-error/indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="], + "ajv-keywords/ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], @@ -3966,26 +3921,30 @@ "app-builder-lib/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="], + "app-builder-lib/which": ["which@5.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ=="], + "bl/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="], "bl/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], - "body-parser/iconv-lite": ["iconv-lite@0.7.1", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw=="], + "body-parser/iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], "builder-util/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], - "cacache/glob": ["glob@8.1.0", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^5.0.1", "once": "^1.3.0" } }, "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ=="], + "cacache/fs-minipass": ["fs-minipass@3.0.3", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw=="], - "cacache/lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="], + "cacache/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="], - "cacache/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + "cacache/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], - "cacache/rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="], + "cacache/tar": ["tar@7.5.2", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg=="], "cacheable-request/get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="], "camelcase-keys/type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="], + "chevrotain/lodash-es": ["lodash-es@4.17.21", "", {}, "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="], + "cliui/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], "cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], @@ -4000,8 +3959,6 @@ "conf/env-paths": ["env-paths@3.0.0", "", {}, "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A=="], - "config-file-ts/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="], - "crc/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="], "cytoscape-fcose/cose-base": ["cose-base@2.2.0", "", { "dependencies": { "layout-base": "^2.0.0" } }, "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g=="], @@ -4022,11 +3979,11 @@ "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], - "dot-prop/type-fest": ["type-fest@5.4.0", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-wfkA6r0tBpVfGiyO+zbf9e10QkRQSlK9F2UvyfnjoCmrvH2bjHyhPzhugSBOuq1dog3P0+FKckqe+Xf6WKVjwg=="], + "dot-prop/type-fest": ["type-fest@5.4.1", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-xygQcmneDyzsEuKZrFbRMne5HDqMs++aFzefrJTgEIKjQ3rekM+RPfFCVq2Gp1VIDqddoYeppCj4Pcb+RZW0GQ=="], "dotenv-expand/dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="], - "electron/@types/node": ["@types/node@22.19.2", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-LPM2G3Syo1GLzXLGJAKdqoU35XvrWzGJ21/7sgZTUpbkBaOasTj8tjwn6w+hCkqaa1TfJ/w67rJSwYItlJ2mYw=="], + "electron/@types/node": ["@types/node@22.19.6", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-qm+G8HuG6hOHQigsi7VGuLjUVu6TtBo/F05zvX04Mw2uCg9Dv0Qxy3Qw7j41SidlTcl5D/5yg0SEZqOB+EqZnQ=="], "electron-builder/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], @@ -4036,6 +3993,8 @@ "engine.io/accepts": ["accepts@1.3.8", "", { "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" } }, "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw=="], + "engine.io/ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="], + "esrecurse/estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="], "estree-util-build-jsx/estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], @@ -4052,16 +4011,10 @@ "fs-minipass/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], - "fumadocs-core/shiki": ["shiki@3.21.0", "", { "dependencies": { "@shikijs/core": "3.21.0", "@shikijs/engine-javascript": "3.21.0", "@shikijs/engine-oniguruma": "3.21.0", "@shikijs/langs": "3.21.0", "@shikijs/themes": "3.21.0", "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-N65B/3bqL/TI2crrXr+4UivctrAGEjmsib5rPMMPpFp1xAx/w03v8WZ9RDDFYteXoEgY7qZ4HGgl5KBIu1153w=="], - - "fumadocs-mdx/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - "fumadocs-mdx/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], "fumadocs-mdx/esbuild": ["esbuild@0.27.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.2", "@esbuild/android-arm": "0.27.2", "@esbuild/android-arm64": "0.27.2", "@esbuild/android-x64": "0.27.2", "@esbuild/darwin-arm64": "0.27.2", "@esbuild/darwin-x64": "0.27.2", "@esbuild/freebsd-arm64": "0.27.2", "@esbuild/freebsd-x64": "0.27.2", "@esbuild/linux-arm": "0.27.2", "@esbuild/linux-arm64": "0.27.2", "@esbuild/linux-ia32": "0.27.2", "@esbuild/linux-loong64": "0.27.2", "@esbuild/linux-mips64el": "0.27.2", "@esbuild/linux-ppc64": "0.27.2", "@esbuild/linux-riscv64": "0.27.2", "@esbuild/linux-s390x": "0.27.2", "@esbuild/linux-x64": "0.27.2", "@esbuild/netbsd-arm64": "0.27.2", "@esbuild/netbsd-x64": "0.27.2", "@esbuild/openbsd-arm64": "0.27.2", "@esbuild/openbsd-x64": "0.27.2", "@esbuild/openharmony-arm64": "0.27.2", "@esbuild/sunos-x64": "0.27.2", "@esbuild/win32-arm64": "0.27.2", "@esbuild/win32-ia32": "0.27.2", "@esbuild/win32-x64": "0.27.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw=="], - "fumadocs-mdx/zod": ["zod@4.3.5", "", {}, "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g=="], - "fumadocs-ui/lucide-react": ["lucide-react@0.562.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-82hOAu7y0dbVuFfmO4bYF1XEwYk/mEbM5E+b1jgci/udUBEE/R7LF5Ip0CCEmXe8AybRM8L+04eP+LGZeDvkiw=="], "glob/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="], @@ -4078,8 +4031,6 @@ "iconv-corefoundation/node-addon-api": ["node-addon-api@1.7.2", "", {}, "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg=="], - "its-fine/@types/react-reconciler": ["@types/react-reconciler@0.28.9", "", { "peerDependencies": { "@types/react": "*" } }, "sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg=="], - "jest-worker/supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="], "katex/commander": ["commander@8.3.0", "", {}, "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="], @@ -4090,16 +4041,6 @@ "line-column-path/type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="], - "make-fetch-happen/http-proxy-agent": ["http-proxy-agent@5.0.0", "", { "dependencies": { "@tootallnate/once": "2", "agent-base": "6", "debug": "4" } }, "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w=="], - - "make-fetch-happen/https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="], - - "make-fetch-happen/lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="], - - "make-fetch-happen/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], - - "make-fetch-happen/negotiator": ["negotiator@0.6.4", "", {}, "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w=="], - "matcher/escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], "mdast-util-find-and-replace/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], @@ -4114,9 +4055,7 @@ "minimist-options/is-plain-obj": ["is-plain-obj@1.1.0", "", {}, "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg=="], - "minipass-collect/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], - - "minipass-fetch/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + "minipass-fetch/minizlib": ["minizlib@3.1.0", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw=="], "minipass-flush/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], @@ -4130,6 +4069,10 @@ "next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="], + "node-gyp/tar": ["tar@7.5.2", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.1.0", "yallist": "^5.0.0" } }, "sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg=="], + + "node-gyp/which": ["which@5.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ=="], + "npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], "nypm/tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], @@ -4146,6 +4089,8 @@ "postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + "posthog-node/@posthog/core": ["@posthog/core@1.9.1", "", { "dependencies": { "cross-spawn": "^7.0.6" } }, "sha512-kRb1ch2dhQjsAapZmu6V66551IF2LnCbc1rnrQqnR7ArooVyJN9KOPXre16AJ3ObJz2eTfuP7x25BMyS2Y5Exw=="], + "postject/commander": ["commander@9.5.0", "", {}, "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="], "promise-retry/retry": ["retry@0.12.0", "", {}, "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow=="], @@ -4154,7 +4099,9 @@ "prop-types/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], - "raw-body/iconv-lite": ["iconv-lite@0.7.1", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw=="], + "randombytes/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], + + "raw-body/iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], "react-arborist/react-dnd": ["react-dnd@14.0.5", "", { "dependencies": { "@react-dnd/invariant": "^2.0.0", "@react-dnd/shallowequal": "^2.0.0", "dnd-core": "14.0.1", "fast-deep-equal": "^3.1.3", "hoist-non-react-statics": "^3.3.2" }, "peerDependencies": { "@types/hoist-non-react-statics": ">= 3.3.1", "@types/node": ">= 12", "@types/react": ">= 16", "react": ">= 16.14" }, "optionalPeers": ["@types/hoist-non-react-statics", "@types/node", "@types/react"] }, "sha512-9i1jSgbyVw0ELlEVt/NkCUkxy1hmhJOkePoCH713u75vzHGyXhPDm28oLfc2NMSBjZRM1Y+wRjHXJT3sPrTy+A=="], @@ -4170,8 +4117,6 @@ "react-email/glob": ["glob@11.1.0", "", { "dependencies": { "foreground-child": "^3.3.1", "jackspeak": "^4.1.1", "minimatch": "^10.1.1", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw=="], - "react-email/jiti": ["jiti@2.4.2", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A=="], - "react-mosaic-component/uuid": ["uuid@9.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="], "read-pkg/normalize-package-data": ["normalize-package-data@3.0.3", "", { "dependencies": { "hosted-git-info": "^4.0.1", "is-core-module": "^2.5.0", "semver": "^7.3.4", "validate-npm-package-license": "^3.0.1" } }, "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA=="], @@ -4192,18 +4137,18 @@ "schema-utils/ajv-formats": ["ajv-formats@2.1.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA=="], + "schema-utils/ajv-keywords": ["ajv-keywords@5.1.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3" }, "peerDependencies": { "ajv": "^8.8.2" } }, "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw=="], + "serialize-error/type-fest": ["type-fest@0.13.1", "", {}, "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg=="], "shell-env/execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="], "socket.io/accepts": ["accepts@1.3.8", "", { "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" } }, "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw=="], - "socks-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], + "socket.io-adapter/ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="], "source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], - "ssri/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], - "stacktrace-parser/type-fest": ["type-fest@0.7.1", "", {}, "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg=="], "stats-gl/three": ["three@0.170.0", "", {}, "sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ=="], @@ -4236,10 +4181,14 @@ "tiny-async-pool/semver": ["semver@5.7.2", "", { "bin": { "semver": "bin/semver" } }, "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="], - "tsx/esbuild": ["esbuild@0.27.1", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.1", "@esbuild/android-arm": "0.27.1", "@esbuild/android-arm64": "0.27.1", "@esbuild/android-x64": "0.27.1", "@esbuild/darwin-arm64": "0.27.1", "@esbuild/darwin-x64": "0.27.1", "@esbuild/freebsd-arm64": "0.27.1", "@esbuild/freebsd-x64": "0.27.1", "@esbuild/linux-arm": "0.27.1", "@esbuild/linux-arm64": "0.27.1", "@esbuild/linux-ia32": "0.27.1", "@esbuild/linux-loong64": "0.27.1", "@esbuild/linux-mips64el": "0.27.1", "@esbuild/linux-ppc64": "0.27.1", "@esbuild/linux-riscv64": "0.27.1", "@esbuild/linux-s390x": "0.27.1", "@esbuild/linux-x64": "0.27.1", "@esbuild/netbsd-arm64": "0.27.1", "@esbuild/netbsd-x64": "0.27.1", "@esbuild/openbsd-arm64": "0.27.1", "@esbuild/openbsd-x64": "0.27.1", "@esbuild/openharmony-arm64": "0.27.1", "@esbuild/sunos-x64": "0.27.1", "@esbuild/win32-arm64": "0.27.1", "@esbuild/win32-ia32": "0.27.1", "@esbuild/win32-x64": "0.27.1" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-yY35KZckJJuVVPXpvjgxiCuVEJT67F6zDeVTv4rizyPrfGBUpZQsvmxnN+C371c2esD/hNMjj4tpBhuueLN7aA=="], + "tsx/esbuild": ["esbuild@0.27.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.2", "@esbuild/android-arm": "0.27.2", "@esbuild/android-arm64": "0.27.2", "@esbuild/android-x64": "0.27.2", "@esbuild/darwin-arm64": "0.27.2", "@esbuild/darwin-x64": "0.27.2", "@esbuild/freebsd-arm64": "0.27.2", "@esbuild/freebsd-x64": "0.27.2", "@esbuild/linux-arm": "0.27.2", "@esbuild/linux-arm64": "0.27.2", "@esbuild/linux-ia32": "0.27.2", "@esbuild/linux-loong64": "0.27.2", "@esbuild/linux-mips64el": "0.27.2", "@esbuild/linux-ppc64": "0.27.2", "@esbuild/linux-riscv64": "0.27.2", "@esbuild/linux-s390x": "0.27.2", "@esbuild/linux-x64": "0.27.2", "@esbuild/netbsd-arm64": "0.27.2", "@esbuild/netbsd-x64": "0.27.2", "@esbuild/openbsd-arm64": "0.27.2", "@esbuild/openbsd-x64": "0.27.2", "@esbuild/openharmony-arm64": "0.27.2", "@esbuild/sunos-x64": "0.27.2", "@esbuild/win32-arm64": "0.27.2", "@esbuild/win32-ia32": "0.27.2", "@esbuild/win32-x64": "0.27.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw=="], + + "tunnel-agent/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], "tunnel-rat/zustand": ["zustand@4.5.7", "", { "dependencies": { "use-sync-external-store": "^1.2.2" }, "peerDependencies": { "@types/react": ">=16.8", "immer": ">=9.0.6", "react": ">=16.8" }, "optionalPeers": ["@types/react", "immer", "react"] }, "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw=="], + "vite/esbuild": ["esbuild@0.27.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.2", "@esbuild/android-arm": "0.27.2", "@esbuild/android-arm64": "0.27.2", "@esbuild/android-x64": "0.27.2", "@esbuild/darwin-arm64": "0.27.2", "@esbuild/darwin-x64": "0.27.2", "@esbuild/freebsd-arm64": "0.27.2", "@esbuild/freebsd-x64": "0.27.2", "@esbuild/linux-arm": "0.27.2", "@esbuild/linux-arm64": "0.27.2", "@esbuild/linux-ia32": "0.27.2", "@esbuild/linux-loong64": "0.27.2", "@esbuild/linux-mips64el": "0.27.2", "@esbuild/linux-ppc64": "0.27.2", "@esbuild/linux-riscv64": "0.27.2", "@esbuild/linux-s390x": "0.27.2", "@esbuild/linux-x64": "0.27.2", "@esbuild/netbsd-arm64": "0.27.2", "@esbuild/netbsd-x64": "0.27.2", "@esbuild/openbsd-arm64": "0.27.2", "@esbuild/openbsd-x64": "0.27.2", "@esbuild/openharmony-arm64": "0.27.2", "@esbuild/sunos-x64": "0.27.2", "@esbuild/win32-arm64": "0.27.2", "@esbuild/win32-ia32": "0.27.2", "@esbuild/win32-x64": "0.27.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw=="], + "webpack/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], "widest-line/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], @@ -4270,8 +4219,6 @@ "@electron/get/fs-extra/universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], - "@electron/node-gyp/glob/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="], - "@electron/rebuild/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], "@electron/rebuild/ora/cli-cursor": ["cli-cursor@3.1.0", "", { "dependencies": { "restore-cursor": "^3.1.0" } }, "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw=="], @@ -4332,8 +4279,6 @@ "@neondatabase/serverless/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], - "@npmcli/move-file/rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], - "@react-email/preview-server/next/@next/env": ["@next/env@16.0.7", "", {}, "sha512-gpaNgUh5nftFKRkRQGnVi5dpcYSKGcZZkQffZ172OrG/XkrnS7UBTQ648YY+8ME92cC4IojpI2LqTC8sTDhAaw=="], "@react-email/preview-server/next/@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.0.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-LlDtCYOEj/rfSnEn/Idi+j1QKHxY9BJFmxx7108A6D8K0SB+bNgfYQATPk/4LqOl4C0Wo3LACg2ie6s7xqMpJg=="], @@ -4366,51 +4311,31 @@ "@sentry/electron/@sentry/node/@sentry/opentelemetry": ["@sentry/opentelemetry@10.29.0", "", { "dependencies": { "@sentry/core": "10.29.0" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-async-hooks": "^1.30.1 || ^2.1.0 || ^2.2.0", "@opentelemetry/core": "^1.30.1 || ^2.1.0 || ^2.2.0", "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0 || ^2.2.0", "@opentelemetry/semantic-conventions": "^1.37.0" } }, "sha512-5QvtAwS73HlI/+OTF1poAFELzsc0se+PHmMsXGGrOeNBvjCr3ZE8qvke09aeMn7uRImf3Nc9J6i2KtSHJnbKPA=="], - "@sentry/react/@sentry/browser/@sentry-internal/feedback": ["@sentry-internal/feedback@10.32.1", "", { "dependencies": { "@sentry/core": "10.32.1" } }, "sha512-O24G8jxbfBY1RE/v2qFikPJISVMOrd/zk8FKyl+oUVYdOxU2Ucjk2cR3EQruBFlc7irnL6rT3GPfRZ/kBgLkmQ=="], + "@sentry/react/@sentry/browser/@sentry-internal/feedback": ["@sentry-internal/feedback@10.34.0", "", { "dependencies": { "@sentry/core": "10.34.0" } }, "sha512-wgGnq+iNxsFSOe9WX/FOvtoItSTjgLJJ4dQkVYtcVM6WGBVIg4wgNYfECCnRNztUTPzpZHLjC9r+4Pym451DDQ=="], - "@sentry/react/@sentry/browser/@sentry-internal/replay": ["@sentry-internal/replay@10.32.1", "", { "dependencies": { "@sentry-internal/browser-utils": "10.32.1", "@sentry/core": "10.32.1" } }, "sha512-KKmLUgIaLRM0VjrMA1ByQTawZyRDYSkG2evvEOVpEtR9F0sumidAQdi7UY71QEKE1RYe/Jcp/3WoaqsMh8tbnQ=="], + "@sentry/react/@sentry/browser/@sentry-internal/replay": ["@sentry-internal/replay@10.34.0", "", { "dependencies": { "@sentry-internal/browser-utils": "10.34.0", "@sentry/core": "10.34.0" } }, "sha512-Vmea0GcOg57z/S1bVSj3saFcRvDqdLzdy4wd9fQMpMgy5OCbTlo7lxVUndKzbcZnanma6zF6VxwnWER1WuN9RA=="], - "@sentry/react/@sentry/browser/@sentry-internal/replay-canvas": ["@sentry-internal/replay-canvas@10.32.1", "", { "dependencies": { "@sentry-internal/replay": "10.32.1", "@sentry/core": "10.32.1" } }, "sha512-/XGTzWNWVc+B691fIVekV2KeoHFEDA5KftrLFAhEAW7uWOwk/xy3aQX4TYM0LcPm2PBKvoumlAD+Sd/aXk63oA=="], + "@sentry/react/@sentry/browser/@sentry-internal/replay-canvas": ["@sentry-internal/replay-canvas@10.34.0", "", { "dependencies": { "@sentry-internal/replay": "10.34.0", "@sentry/core": "10.34.0" } }, "sha512-XWH/9njtgMD+LLWjc4KKgBpb+dTCkoUEIFDxcvzG/87d+jirmzf0+r8EfpLwKG+GrqNiiGRV39zIqu0SfPl+cw=="], "@sentry/webpack-plugin/unplugin/webpack-virtual-modules": ["webpack-virtual-modules@0.5.0", "", {}, "sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw=="], - "@shikijs/rehype/shiki/@shikijs/core": ["@shikijs/core@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-AXSQu/2n1UIQekY8euBJlvFYZIw0PHY63jUzGbrOma4wPxzznJXTXkri+QcHeBNaFxiiOljKxxJkVSoB3PjbyA=="], - - "@shikijs/rehype/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-ATwv86xlbmfD9n9gKRiwuPpWgPENAWCLwYCGz9ugTJlsO2kOzhOkvoyV/UD+tJ0uT7YRyD530x6ugNSffmvIiQ=="], - - "@shikijs/rehype/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-OYknTCct6qiwpQDqDdf3iedRdzj6hFlOPv5hMvI+hkWfCKs5mlJ4TXziBG9nyabLwGulrUjHiCq3xCspSzErYQ=="], - - "@shikijs/rehype/shiki/@shikijs/langs": ["@shikijs/langs@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0" } }, "sha512-g6mn5m+Y6GBJ4wxmBYqalK9Sp0CFkUqfNzUy2pJglUginz6ZpWbaWjDB4fbQ/8SHzFjYbtU6Ddlp1pc+PPNDVA=="], - - "@shikijs/rehype/shiki/@shikijs/themes": ["@shikijs/themes@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0" } }, "sha512-BAE4cr9EDiZyYzwIHEk7JTBJ9CzlPuM4PchfcA5ao1dWXb25nv6hYsoDiBq2aZK9E3dlt3WB78uI96UESD+8Mw=="], - - "@superset/docs/next/@next/env": ["@next/env@16.1.1", "", {}, "sha512-3oxyM97Sr2PqiVyMyrZUtrtM3jqqFxOQJVuKclDsgj/L728iZt/GyslkN4NwarledZATCenbk4Offjk1hQmaAA=="], - - "@superset/docs/next/@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.1.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-JS3m42ifsVSJjSTzh27nW+Igfha3NdBOFScr9C80hHGrWx55pTrVL23RJbqir7k7/15SKlrLHhh/MQzqBBYrQA=="], - - "@superset/docs/next/@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.1.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-hbyKtrDGUkgkyQi1m1IyD3q4I/3m9ngr+V93z4oKHrPcmxwNL5iMWORvLSGAf2YujL+6HxgVvZuCYZfLfb4bGw=="], - - "@superset/docs/next/@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.1.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-/fvHet+EYckFvRLQ0jPHJCUI5/B56+2DpI1xDSvi80r/3Ez+Eaa2Yq4tJcRTaB1kqj/HrYKn8Yplm9bNoMJpwQ=="], - - "@superset/docs/next/@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.1.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-MFHrgL4TXNQbBPzkKKur4Fb5ICEJa87HM7fczFs2+HWblM7mMLdco3dvyTI+QmLBU9xgns/EeeINSZD6Ar+oLg=="], - - "@superset/docs/next/@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.1.1", "", { "os": "linux", "cpu": "x64" }, "sha512-20bYDfgOQAPUkkKBnyP9PTuHiJGM7HzNBbuqmD0jiFVZ0aOldz+VnJhbxzjcSabYsnNjMPsE0cyzEudpYxsrUQ=="], + "@uiw/react-markdown-preview/rehype-prism-plus/refractor": ["refractor@4.9.0", "", { "dependencies": { "@types/hast": "^2.0.0", "@types/prismjs": "^1.0.0", "hastscript": "^7.0.0", "parse-entities": "^4.0.0" } }, "sha512-nEG1SPXFoGGx+dcjftjv8cAjEusIh6ED1xhf5DG3C0x/k+rmZ2duKnc3QLpt6qeHv5fPb8uwN3VWN2BT7fr3Og=="], - "@superset/docs/next/@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.1.1", "", { "os": "linux", "cpu": "x64" }, "sha512-9pRbK3M4asAHQRkwaXwu601oPZHghuSC8IXNENgbBSyImHv/zY4K5udBusgdHkvJ/Tcr96jJwQYOll0qU8+fPA=="], + "ajv-keywords/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], - "@superset/docs/next/@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.1.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-bdfQkggaLgnmYrFkSQfsHfOhk/mCYmjnrbRCGgkMcoOBZ4n+TRRSLmT/CU5SATzlBJ9TpioUyBW/vWFXTqQRiA=="], + "app-builder-lib/which/isexe": ["isexe@3.1.1", "", {}, "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ=="], - "@superset/docs/next/@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.1.1", "", { "os": "win32", "cpu": "x64" }, "sha512-Ncwbw2WJ57Al5OX0k4chM68DKhEPlrXBaSXDCi2kPi5f4d8b3ejr3RRJGfKBLrn2YJL5ezNS7w2TZLHSti8CMw=="], + "builder-util/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], - "@superset/docs/next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="], + "cacache/glob/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], - "@uiw/react-markdown-preview/rehype-prism-plus/refractor": ["refractor@4.9.0", "", { "dependencies": { "@types/hast": "^2.0.0", "@types/prismjs": "^1.0.0", "hastscript": "^7.0.0", "parse-entities": "^4.0.0" } }, "sha512-nEG1SPXFoGGx+dcjftjv8cAjEusIh6ED1xhf5DG3C0x/k+rmZ2duKnc3QLpt6qeHv5fPb8uwN3VWN2BT7fr3Og=="], + "cacache/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], - "builder-util/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + "cacache/tar/chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], - "cacache/glob/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="], + "cacache/tar/minizlib": ["minizlib@3.1.0", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw=="], - "cacache/rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], + "cacache/tar/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], "cliui/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], @@ -4422,10 +4347,6 @@ "code-inspector-plugin/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], - "config-file-ts/glob/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], - - "config-file-ts/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], - "cytoscape-fcose/cose-base/layout-base": ["layout-base@2.0.1", "", {}, "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg=="], "d3-sankey/d3-array/internmap": ["internmap@1.0.1", "", {}, "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="], @@ -4452,18 +4373,6 @@ "form-data/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], - "fumadocs-core/shiki/@shikijs/core": ["@shikijs/core@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-AXSQu/2n1UIQekY8euBJlvFYZIw0PHY63jUzGbrOma4wPxzznJXTXkri+QcHeBNaFxiiOljKxxJkVSoB3PjbyA=="], - - "fumadocs-core/shiki/@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-ATwv86xlbmfD9n9gKRiwuPpWgPENAWCLwYCGz9ugTJlsO2kOzhOkvoyV/UD+tJ0uT7YRyD530x6ugNSffmvIiQ=="], - - "fumadocs-core/shiki/@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-OYknTCct6qiwpQDqDdf3iedRdzj6hFlOPv5hMvI+hkWfCKs5mlJ4TXziBG9nyabLwGulrUjHiCq3xCspSzErYQ=="], - - "fumadocs-core/shiki/@shikijs/langs": ["@shikijs/langs@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0" } }, "sha512-g6mn5m+Y6GBJ4wxmBYqalK9Sp0CFkUqfNzUy2pJglUginz6ZpWbaWjDB4fbQ/8SHzFjYbtU6Ddlp1pc+PPNDVA=="], - - "fumadocs-core/shiki/@shikijs/themes": ["@shikijs/themes@3.21.0", "", { "dependencies": { "@shikijs/types": "3.21.0" } }, "sha512-BAE4cr9EDiZyYzwIHEk7JTBJ9CzlPuM4PchfcA5ao1dWXb25nv6hYsoDiBq2aZK9E3dlt3WB78uI96UESD+8Mw=="], - - "fumadocs-core/shiki/@shikijs/types": ["@shikijs/types@3.21.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA=="], - "fumadocs-mdx/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], "fumadocs-mdx/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw=="], @@ -4524,14 +4433,18 @@ "launch-ide/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], - "make-fetch-happen/http-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], - - "make-fetch-happen/https-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], - "mlly/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], "next/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + "node-gyp/tar/chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], + + "node-gyp/tar/minizlib": ["minizlib@3.1.0", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw=="], + + "node-gyp/tar/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], + + "node-gyp/which/isexe": ["isexe@3.1.1", "", {}, "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ=="], + "ora/cli-cursor/restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="], "ora/log-symbols/is-unicode-supported": ["is-unicode-supported@1.3.0", "", {}, "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ=="], @@ -4576,57 +4489,109 @@ "temp/rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], - "tsx/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.1", "", { "os": "aix", "cpu": "ppc64" }, "sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA=="], + "tsx/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw=="], + + "tsx/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.2", "", { "os": "android", "cpu": "arm" }, "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA=="], + + "tsx/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.2", "", { "os": "android", "cpu": "arm64" }, "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA=="], - "tsx/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.1", "", { "os": "android", "cpu": "arm" }, "sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg=="], + "tsx/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.27.2", "", { "os": "android", "cpu": "x64" }, "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A=="], - "tsx/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.1", "", { "os": "android", "cpu": "arm64" }, "sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ=="], + "tsx/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg=="], - "tsx/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.27.1", "", { "os": "android", "cpu": "x64" }, "sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ=="], + "tsx/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA=="], - "tsx/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ=="], + "tsx/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g=="], - "tsx/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ=="], + "tsx/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA=="], - "tsx/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg=="], + "tsx/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.2", "", { "os": "linux", "cpu": "arm" }, "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw=="], - "tsx/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ=="], + "tsx/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw=="], - "tsx/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.1", "", { "os": "linux", "cpu": "arm" }, "sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA=="], + "tsx/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.2", "", { "os": "linux", "cpu": "ia32" }, "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w=="], - "tsx/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q=="], + "tsx/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.2", "", { "os": "linux", "cpu": "none" }, "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg=="], - "tsx/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.1", "", { "os": "linux", "cpu": "ia32" }, "sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw=="], + "tsx/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.2", "", { "os": "linux", "cpu": "none" }, "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw=="], - "tsx/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.1", "", { "os": "linux", "cpu": "none" }, "sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg=="], + "tsx/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ=="], - "tsx/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.1", "", { "os": "linux", "cpu": "none" }, "sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA=="], + "tsx/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.2", "", { "os": "linux", "cpu": "none" }, "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA=="], - "tsx/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ=="], + "tsx/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w=="], - "tsx/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.1", "", { "os": "linux", "cpu": "none" }, "sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ=="], + "tsx/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.2", "", { "os": "linux", "cpu": "x64" }, "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA=="], - "tsx/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw=="], + "tsx/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.2", "", { "os": "none", "cpu": "arm64" }, "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw=="], - "tsx/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.1", "", { "os": "linux", "cpu": "x64" }, "sha512-z3H/HYI9MM0HTv3hQZ81f+AKb+yEoCRlUby1F80vbQ5XdzEMyY/9iNlAmhqiBKw4MJXwfgsh7ERGEOhrM1niMA=="], + "tsx/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.2", "", { "os": "none", "cpu": "x64" }, "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA=="], - "tsx/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.1", "", { "os": "none", "cpu": "arm64" }, "sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ=="], + "tsx/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA=="], - "tsx/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.1", "", { "os": "none", "cpu": "x64" }, "sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg=="], + "tsx/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg=="], - "tsx/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.1", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g=="], + "tsx/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.2", "", { "os": "none", "cpu": "arm64" }, "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag=="], - "tsx/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg=="], + "tsx/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg=="], - "tsx/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.1", "", { "os": "none", "cpu": "arm64" }, "sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg=="], + "tsx/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg=="], - "tsx/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.1", "", { "os": "sunos", "cpu": "x64" }, "sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA=="], + "tsx/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ=="], - "tsx/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg=="], + "tsx/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.2", "", { "os": "win32", "cpu": "x64" }, "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ=="], - "tsx/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ=="], + "vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw=="], - "tsx/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.1", "", { "os": "win32", "cpu": "x64" }, "sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw=="], + "vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.2", "", { "os": "android", "cpu": "arm" }, "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA=="], + + "vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.2", "", { "os": "android", "cpu": "arm64" }, "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA=="], + + "vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.27.2", "", { "os": "android", "cpu": "x64" }, "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A=="], + + "vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg=="], + + "vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA=="], + + "vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g=="], + + "vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA=="], + + "vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.2", "", { "os": "linux", "cpu": "arm" }, "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw=="], + + "vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw=="], + + "vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.2", "", { "os": "linux", "cpu": "ia32" }, "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w=="], + + "vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.2", "", { "os": "linux", "cpu": "none" }, "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg=="], + + "vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.2", "", { "os": "linux", "cpu": "none" }, "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw=="], + + "vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ=="], + + "vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.2", "", { "os": "linux", "cpu": "none" }, "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA=="], + + "vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w=="], + + "vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.2", "", { "os": "linux", "cpu": "x64" }, "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA=="], + + "vite/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.2", "", { "os": "none", "cpu": "arm64" }, "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw=="], + + "vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.2", "", { "os": "none", "cpu": "x64" }, "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA=="], + + "vite/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA=="], + + "vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg=="], + + "vite/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.2", "", { "os": "none", "cpu": "arm64" }, "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag=="], + + "vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg=="], + + "vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg=="], + + "vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ=="], + + "vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.2", "", { "os": "win32", "cpu": "x64" }, "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ=="], "webpack/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], @@ -4646,22 +4611,14 @@ "@electron/rebuild/ora/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "@npmcli/move-file/rimraf/glob/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], - "@react-email/preview-server/next/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], "@sentry/bundler-plugin-core/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], - "@superset/docs/next/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], - "@uiw/react-markdown-preview/rehype-prism-plus/refractor/@types/hast": ["@types/hast@2.3.10", "", { "dependencies": { "@types/unist": "^2" } }, "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw=="], "@uiw/react-markdown-preview/rehype-prism-plus/refractor/hastscript": ["hastscript@7.2.0", "", { "dependencies": { "@types/hast": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-parse-selector": "^3.0.0", "property-information": "^6.0.0", "space-separated-tokens": "^2.0.0" } }, "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw=="], - "cacache/rimraf/glob/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], - - "config-file-ts/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], - "engine.io/accepts/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], "iconv-corefoundation/cli-truncate/slice-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], @@ -4702,16 +4659,12 @@ "yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "@npmcli/move-file/rimraf/glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="], - "@uiw/react-markdown-preview/rehype-prism-plus/refractor/@types/hast/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], "@uiw/react-markdown-preview/rehype-prism-plus/refractor/hastscript/hast-util-parse-selector": ["hast-util-parse-selector@3.1.1", "", { "dependencies": { "@types/hast": "^2.0.0" } }, "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA=="], "@uiw/react-markdown-preview/rehype-prism-plus/refractor/hastscript/property-information": ["property-information@6.5.0", "", {}, "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig=="], - "cacache/rimraf/glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="], - "iconv-corefoundation/cli-truncate/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], "read-pkg-up/find-up/locate-path/p-locate/p-limit": ["p-limit@4.0.0", "", { "dependencies": { "yocto-queue": "^1.0.0" } }, "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ=="], diff --git a/packages/auth/src/env.ts b/packages/auth/src/env.ts index 3f47ba0f5..c0859ae38 100644 --- a/packages/auth/src/env.ts +++ b/packages/auth/src/env.ts @@ -20,6 +20,7 @@ export const env = createEnv({ NEXT_PUBLIC_WEB_URL: z.string().url(), NEXT_PUBLIC_ADMIN_URL: z.string().url(), NEXT_PUBLIC_MARKETING_URL: z.string().url(), + NEXT_PUBLIC_DESKTOP_URL: z.string().url().optional(), }, runtimeEnv: process.env, emptyStringAsUndefined: true, diff --git a/packages/auth/src/server.ts b/packages/auth/src/server.ts index 6a5482bb0..d56d75286 100644 --- a/packages/auth/src/server.ts +++ b/packages/auth/src/server.ts @@ -21,6 +21,10 @@ export const auth = betterAuth({ env.NEXT_PUBLIC_API_URL, env.NEXT_PUBLIC_MARKETING_URL, env.NEXT_PUBLIC_ADMIN_URL, + // Electron desktop app origins + ...(env.NEXT_PUBLIC_DESKTOP_URL ? [env.NEXT_PUBLIC_DESKTOP_URL] : []), + "superset://app", // Production Electron app + "superset-dev://app", // Development Electron app (if using custom protocol) ], session: { expiresIn: 60 * 60 * 24 * 30, // 30 days From 92a194e7702f685c0e035d0eb4ff7c90b026dc73 Mon Sep 17 00:00:00 2001 From: Satya Patel Date: Wed, 14 Jan 2026 13:48:02 -0800 Subject: [PATCH 09/12] WIP --- apps/desktop/src/renderer/index.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/desktop/src/renderer/index.tsx b/apps/desktop/src/renderer/index.tsx index d5e95c194..1a330e0e8 100644 --- a/apps/desktop/src/renderer/index.tsx +++ b/apps/desktop/src/renderer/index.tsx @@ -9,6 +9,7 @@ import { RouterProvider, } from "@tanstack/react-router"; import ReactDom from "react-dom/client"; +import { posthog } from "./lib/posthog"; import { electronQueryClient } from "./providers/ElectronTRPCProvider"; import { routeTree } from "./routeTree.gen"; @@ -25,6 +26,12 @@ const router = createRouter({ }, }); +router.subscribe("onResolved", () => { + posthog.capture("$pageview", { + $current_url: window.location.href, + }); +}); + declare module "@tanstack/react-router" { interface Register { router: typeof router; From 8c4a431187961a3815d06236de51f0ad24617b83 Mon Sep 17 00:00:00 2001 From: Satya Patel Date: Wed, 14 Jan 2026 14:26:08 -0800 Subject: [PATCH 10/12] Hopefully done --- apps/desktop/src/main/index.ts | 6 +- .../providers/AuthProvider/AuthProvider.tsx | 3 +- .../workspaces/useCreateBranchWorkspace.ts | 7 ++ .../workspaces/useCreateWorkspace.ts | 20 +++-- .../workspaces/useDeleteWorkspace.ts | 89 +++++++++++-------- .../react-query/workspaces/useOpenWorktree.ts | 13 +-- .../_dashboard/workspace/page.tsx | 3 +- .../renderer/routes/_authenticated/layout.tsx | 62 ++++++++++--- .../CollectionsProvider.tsx | 3 +- .../settings/project/$projectId/page.tsx | 73 +++++++++------ .../settings/workspace/$workspaceId/page.tsx | 51 ++++++----- .../src/renderer/routes/sign-in/page.tsx | 3 +- .../main/components/TasksView/TasksView.tsx | 3 +- apps/desktop/src/renderer/stores/app-state.ts | 54 ----------- apps/desktop/src/renderer/stores/index.ts | 1 - packages/auth/src/server.ts | 3 +- 16 files changed, 217 insertions(+), 177 deletions(-) delete mode 100644 apps/desktop/src/renderer/stores/app-state.ts diff --git a/apps/desktop/src/main/index.ts b/apps/desktop/src/main/index.ts index 16f8ab410..32ea00e45 100644 --- a/apps/desktop/src/main/index.ts +++ b/apps/desktop/src/main/index.ts @@ -212,8 +212,10 @@ if (!gotTheLock) { // This provides a stable origin (superset://app or superset-dev://app) for Better Auth CORS if (process.env.NODE_ENV !== "development") { protocol.handle(PROTOCOL_SCHEME, (request) => { - const url = request.url.replace(`${PROTOCOL_SCHEME}://`, ""); - const filePath = path.normalize(path.join(__dirname, "../renderer", url)); + // Parse URL to extract pathname (e.g., superset://app/index.html#/ -> /index.html) + const parsedUrl = new URL(request.url); + const pathname = parsedUrl.pathname; + const filePath = path.normalize(path.join(__dirname, "../renderer", pathname)); return net.fetch(`file://${filePath}`); }); } diff --git a/apps/desktop/src/renderer/providers/AuthProvider/AuthProvider.tsx b/apps/desktop/src/renderer/providers/AuthProvider/AuthProvider.tsx index 4a24e41b1..96e7f25b6 100644 --- a/apps/desktop/src/renderer/providers/AuthProvider/AuthProvider.tsx +++ b/apps/desktop/src/renderer/providers/AuthProvider/AuthProvider.tsx @@ -1,3 +1,4 @@ +import { Spinner } from "@superset/ui/spinner"; import { type ReactNode, useEffect, useState } from "react"; import { authClient, setAuthToken } from "renderer/lib/auth-client"; import { electronTrpc } from "../../lib/electron-trpc"; @@ -51,7 +52,7 @@ export function AuthProvider({ children }: { children: ReactNode }) { if (!isHydrated) { return (
-
+
); } diff --git a/apps/desktop/src/renderer/react-query/workspaces/useCreateBranchWorkspace.ts b/apps/desktop/src/renderer/react-query/workspaces/useCreateBranchWorkspace.ts index 834a02f50..18575c3c5 100644 --- a/apps/desktop/src/renderer/react-query/workspaces/useCreateBranchWorkspace.ts +++ b/apps/desktop/src/renderer/react-query/workspaces/useCreateBranchWorkspace.ts @@ -1,4 +1,6 @@ +import { useNavigate } from "@tanstack/react-router"; import { electronTrpc } from "renderer/lib/electron-trpc"; +import { navigateToWorkspace } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; import { useTabsStore } from "renderer/stores/tabs/store"; /** @@ -11,6 +13,7 @@ export function useCreateBranchWorkspace( typeof electronTrpc.workspaces.createBranchWorkspace.useMutation >[0], ) { + const navigate = useNavigate(); const utils = electronTrpc.useUtils(); return electronTrpc.workspaces.createBranchWorkspace.useMutation({ @@ -25,6 +28,10 @@ export function useCreateBranchWorkspace( useTabsStore.getState().addTab(data.workspace.id); } + // Navigate to the workspace + // Branch workspaces don't need async initialization, so always navigate + navigateToWorkspace(data.workspace.id, navigate); + // Call user's onSuccess if provided await options?.onSuccess?.(data, ...rest); }, diff --git a/apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts b/apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts index 53af0a07c..c8b920db9 100644 --- a/apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts +++ b/apps/desktop/src/renderer/react-query/workspaces/useCreateWorkspace.ts @@ -1,4 +1,6 @@ +import { useNavigate } from "@tanstack/react-router"; import { electronTrpc } from "renderer/lib/electron-trpc"; +import { navigateToWorkspace } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; import { useWorkspaceInitStore } from "renderer/stores/workspace-init"; import type { WorkspaceInitProgress } from "shared/types/workspace-init"; @@ -19,6 +21,7 @@ import type { WorkspaceInitProgress } from "shared/types/workspace-init"; export function useCreateWorkspace( options?: Parameters[0], ) { + const navigate = useNavigate(); const utils = electronTrpc.useUtils(); const addPendingTerminalSetup = useWorkspaceInitStore( (s) => s.addPendingTerminalSetup, @@ -28,9 +31,9 @@ export function useCreateWorkspace( return electronTrpc.workspaces.create.useMutation({ ...options, onSuccess: async (data, ...rest) => { - // Optimistically set init progress BEFORE query invalidation to prevent - // the "interrupted" state flash. The subscription will update with real - // progress, but this ensures isInitializing is true immediately. + // CRITICAL: Set optimistic progress BEFORE invalidation AND navigation + // to ensure isInitializing is true when workspace page first renders, + // preventing the "Setup incomplete" flash. if (data.isInitializing) { const optimisticProgress: WorkspaceInitProgress = { workspaceId: data.workspace.id, @@ -41,9 +44,6 @@ export function useCreateWorkspace( updateProgress(optimisticProgress); } - // Auto-invalidate all workspace queries - await utils.workspaces.invalidate(); - // Add to global pending store (WorkspaceInitEffects will handle terminal creation) // This survives dialog unmounts since it's stored in Zustand, not a hook-local ref addPendingTerminalSetup({ @@ -52,10 +52,18 @@ export function useCreateWorkspace( initialCommands: data.initialCommands, }); + // Auto-invalidate all workspace queries + await utils.workspaces.invalidate(); + // Handle race condition: if init already completed before we added to pending, // WorkspaceInitEffects will process it on next render when it sees the progress // is already "ready" and there's a matching pending setup. + // Navigate to the new workspace immediately + // The workspace exists in DB, so it's safe to navigate + // Git operations happen in background with progress shown via toast + navigateToWorkspace(data.workspace.id, navigate); + // Call user's onSuccess if provided await options?.onSuccess?.(data, ...rest); }, diff --git a/apps/desktop/src/renderer/react-query/workspaces/useDeleteWorkspace.ts b/apps/desktop/src/renderer/react-query/workspaces/useDeleteWorkspace.ts index 8cf467c4d..ef03a33a2 100644 --- a/apps/desktop/src/renderer/react-query/workspaces/useDeleteWorkspace.ts +++ b/apps/desktop/src/renderer/react-query/workspaces/useDeleteWorkspace.ts @@ -13,13 +13,15 @@ type DeleteContext = { >["workspaces"]["getAll"]["getData"] extends () => infer R ? R : never; + wasViewingDeleted: boolean; + navigatedTo: string | null; }; /** - * Mutation hook for deleting a workspace and its worktree - * Uses optimistic updates to immediately remove workspace from UI, - * then performs actual deletion in background. - * Automatically navigates away if the deleted workspace is currently being viewed. + * Mutation hook for deleting a workspace with optimistic updates. + * Server marks `deletingAt` immediately so refetches stay correct during slow git operations. + * Optimistically navigates away immediately if the deleted workspace is currently being viewed. + * Navigates back on error to restore the user to the original workspace. */ export function useDeleteWorkspace( options?: Parameters[0], @@ -31,17 +33,38 @@ export function useDeleteWorkspace( return electronTrpc.workspaces.delete.useMutation({ ...options, onMutate: async ({ id }) => { - // Cancel outgoing refetches to avoid overwriting optimistic update + // Check if we're viewing the workspace being deleted + const wasViewingDeleted = params.workspaceId === id; + let navigatedTo: string | null = null; + + // If viewing deleted workspace, get navigation target BEFORE optimistic update + if (wasViewingDeleted) { + const prevWorkspaceId = + await utils.workspaces.getPreviousWorkspace.fetch({ id }); + const nextWorkspaceId = await utils.workspaces.getNextWorkspace.fetch({ + id, + }); + const targetWorkspaceId = prevWorkspaceId ?? nextWorkspaceId; + + if (targetWorkspaceId) { + navigatedTo = targetWorkspaceId; + navigateToWorkspace(targetWorkspaceId, navigate); + } else { + navigatedTo = "/workspace"; + navigate({ to: "/workspace" }); + } + } + + // Cancel outgoing queries and get snapshots await Promise.all([ utils.workspaces.getAll.cancel(), utils.workspaces.getAllGrouped.cancel(), ]); - // Snapshot previous values for rollback const previousGrouped = utils.workspaces.getAllGrouped.getData(); const previousAll = utils.workspaces.getAll.getData(); - // Optimistically remove workspace from getAllGrouped cache + // Optimistic update: remove workspace from cache if (previousGrouped) { utils.workspaces.getAllGrouped.setData( undefined, @@ -54,7 +77,6 @@ export function useDeleteWorkspace( ); } - // Optimistically remove workspace from getAll cache if (previousAll) { utils.workspaces.getAll.setData( undefined, @@ -62,11 +84,23 @@ export function useDeleteWorkspace( ); } - // Return context for rollback - return { previousGrouped, previousAll } as DeleteContext; + return { + previousGrouped, + previousAll, + wasViewingDeleted, + navigatedTo, + } as DeleteContext; }, - onError: (_err, _variables, context) => { - // Rollback to previous state on error + onSettled: async (...args) => { + await utils.workspaces.invalidate(); + await options?.onSettled?.(...args); + }, + onSuccess: async (data, variables, ...rest) => { + // Navigation already handled in onMutate (optimistic) + await options?.onSuccess?.(data, variables, ...rest); + }, + onError: async (_err, variables, context, ...rest) => { + // Rollback optimistic cache updates if (context?.previousGrouped !== undefined) { utils.workspaces.getAllGrouped.setData( undefined, @@ -76,36 +110,13 @@ export function useDeleteWorkspace( if (context?.previousAll !== undefined) { utils.workspaces.getAll.setData(undefined, context.previousAll); } - }, - onSuccess: async (data, variables, ...rest) => { - // Invalidate to ensure consistency with backend state - await utils.workspaces.invalidate(); - // Invalidate project queries since delete updates project metadata - await utils.projects.getRecents.invalidate(); - - // If the deleted workspace is currently being viewed, navigate away - if (params.workspaceId === variables.id) { - // Try to navigate to previous workspace first, then next - const prevWorkspaceId = - await utils.workspaces.getPreviousWorkspace.fetch({ - id: variables.id, - }); - const nextWorkspaceId = await utils.workspaces.getNextWorkspace.fetch({ - id: variables.id, - }); - const targetWorkspaceId = prevWorkspaceId ?? nextWorkspaceId; - - if (targetWorkspaceId) { - navigateToWorkspace(targetWorkspaceId, navigate); - } else { - // No other workspaces, navigate to workspace index (shows StartView) - navigate({ to: "/workspace" }); - } + // If we optimistically navigated away, navigate back to the deleted workspace + if (context?.wasViewingDeleted) { + navigateToWorkspace(variables.id, navigate); } - // Call user's onSuccess if provided - await options?.onSuccess?.(data, variables, ...rest); + await options?.onError?.(_err, variables, context, ...rest); }, }); } diff --git a/apps/desktop/src/renderer/react-query/workspaces/useOpenWorktree.ts b/apps/desktop/src/renderer/react-query/workspaces/useOpenWorktree.ts index 1d22d0f07..98f870fe7 100644 --- a/apps/desktop/src/renderer/react-query/workspaces/useOpenWorktree.ts +++ b/apps/desktop/src/renderer/react-query/workspaces/useOpenWorktree.ts @@ -1,5 +1,7 @@ import { toast } from "@superset/ui/sonner"; +import { useNavigate } from "@tanstack/react-router"; import { electronTrpc } from "renderer/lib/electron-trpc"; +import { navigateToWorkspace } from "renderer/routes/_authenticated/_dashboard/utils/workspace-navigation"; import { useOpenConfigModal } from "renderer/stores/config-modal"; import { useTabsStore } from "renderer/stores/tabs/store"; @@ -10,17 +12,15 @@ import { useTabsStore } from "renderer/stores/tabs/store"; * Shows config toast if no setup commands are configured */ export function useOpenWorktree( - options?: Parameters< - typeof electronTrpc.workspaces.openWorktree.useMutation - >[0], + options?: Parameters[0], ) { + const navigate = useNavigate(); const utils = electronTrpc.useUtils(); const addTab = useTabsStore((state) => state.addTab); const setTabAutoTitle = useTabsStore((state) => state.setTabAutoTitle); const createOrAttach = electronTrpc.terminal.createOrAttach.useMutation(); const openConfigModal = useOpenConfigModal(); - const dismissConfigToast = - electronTrpc.config.dismissConfigToast.useMutation(); + const dismissConfigToast = electronTrpc.config.dismissConfigToast.useMutation(); return electronTrpc.workspaces.openWorktree.useMutation({ ...options, @@ -63,6 +63,9 @@ export function useOpenWorktree( }); } + // Navigate to the opened workspace + navigateToWorkspace(data.workspace.id, navigate); + // Call user's onSuccess if provided await options?.onSuccess?.(data, ...rest); }, diff --git a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/page.tsx b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/page.tsx index 506a4727d..bcff6cb93 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/page.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/page.tsx @@ -1,3 +1,4 @@ +import { Spinner } from "@superset/ui/spinner"; import { createFileRoute, useNavigate } from "@tanstack/react-router"; import { useEffect } from "react"; import { electronTrpc } from "renderer/lib/electron-trpc"; @@ -10,7 +11,7 @@ export const Route = createFileRoute("/_authenticated/_dashboard/workspace/")({ function LoadingSpinner() { return (
-
+
); } diff --git a/apps/desktop/src/renderer/routes/_authenticated/layout.tsx b/apps/desktop/src/renderer/routes/_authenticated/layout.tsx index 5890b297c..4522b8ed1 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/layout.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/layout.tsx @@ -1,7 +1,19 @@ -import { createFileRoute, Navigate, Outlet } from "@tanstack/react-router"; +import { + createFileRoute, + Navigate, + Outlet, + useNavigate, +} from "@tanstack/react-router"; import { DndProvider } from "react-dnd"; +import { NewWorkspaceModal } from "renderer/components/NewWorkspaceModal"; +import { useUpdateListener } from "renderer/components/UpdateToast"; import { authClient } from "renderer/lib/auth-client"; import { dragDropManager } from "renderer/lib/dnd"; +import { electronTrpc } from "renderer/lib/electron-trpc"; +import { WorkspaceInitEffects } from "renderer/screens/main/components/WorkspaceInitEffects"; +import { useHotkeysSync } from "renderer/stores/hotkeys"; +import { useAgentHookListener } from "renderer/stores/tabs/useAgentHookListener"; +import { useWorkspaceInitStore } from "renderer/stores/workspace-init"; import { CollectionsProvider } from "./providers/CollectionsProvider"; export const Route = createFileRoute("/_authenticated")({ @@ -9,19 +21,43 @@ export const Route = createFileRoute("/_authenticated")({ }); function AuthenticatedLayout() { - const { data: session, isPending, error } = authClient.useSession(); + const { data: session } = authClient.useSession(); + const isSignedIn = !!session?.user; + const navigate = useNavigate(); + const utils = electronTrpc.useUtils(); - // Session still loading - show spinner - if (isPending) { - return ( -
-
-
- ); - } + // Global hooks and subscriptions + useAgentHookListener(); + useUpdateListener(); + useHotkeysSync(); + + // Workspace initialization progress subscription + const updateInitProgress = useWorkspaceInitStore((s) => s.updateProgress); + electronTrpc.workspaces.onInitProgress.useSubscription(undefined, { + onData: (progress) => { + updateInitProgress(progress); + if (progress.step === "ready" || progress.step === "failed") { + // Invalidate both the grouped list AND the specific workspace + utils.workspaces.getAllGrouped.invalidate(); + utils.workspaces.get.invalidate({ id: progress.workspaceId }); + } + }, + onError: (error) => { + console.error("[workspace-init-subscription] Subscription error:", error); + }, + }); + + // Menu navigation subscription + electronTrpc.menu.subscribe.useSubscription(undefined, { + onData: (event) => { + if (event.type === "open-settings") { + const section = event.data.section || "account"; + navigate({ to: `/settings/${section}` as "/settings/account" }); + } + }, + }); - // Error or no user - not authenticated, redirect to sign-in - if (error || !session?.user) { + if (!isSignedIn) { return ; } @@ -29,6 +65,8 @@ function AuthenticatedLayout() { + + ); diff --git a/apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/CollectionsProvider.tsx b/apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/CollectionsProvider.tsx index c9704bc6e..f0963c46e 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/CollectionsProvider.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/CollectionsProvider.tsx @@ -1,3 +1,4 @@ +import { Spinner } from "@superset/ui/spinner"; import { createContext, type ReactNode, useContext, useMemo } from "react"; import { authClient } from "renderer/lib/auth-client"; import { getCollections } from "./collections"; @@ -21,7 +22,7 @@ export function CollectionsProvider({ children }: { children: ReactNode }) { if (!collections) { return (
-
+
); } diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/project/$projectId/page.tsx b/apps/desktop/src/renderer/routes/_authenticated/settings/project/$projectId/page.tsx index 0d199d365..c99d119c7 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/settings/project/$projectId/page.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/project/$projectId/page.tsx @@ -1,9 +1,47 @@ -import { createFileRoute } from "@tanstack/react-router"; +import { createFileRoute, notFound } from "@tanstack/react-router"; +import { electronTrpcClient } from "renderer/lib/trpc-client"; +import { NotFound } from "renderer/routes/not-found"; export const Route = createFileRoute( "/_authenticated/settings/project/$projectId/", )({ component: ProjectSettingsPage, + notFoundComponent: NotFound, + loader: async ({ params, context }) => { + const projectQueryKey = [ + ["projects", "get"], + { input: { id: params.projectId }, type: "query" }, + ]; + + const configQueryKey = [ + ["config", "getConfigFilePath"], + { input: { projectId: params.projectId }, type: "query" }, + ]; + + try { + await Promise.all([ + context.queryClient.ensureQueryData({ + queryKey: projectQueryKey, + queryFn: () => + electronTrpcClient.projects.get.query({ id: params.projectId }), + }), + context.queryClient.ensureQueryData({ + queryKey: configQueryKey, + queryFn: () => + electronTrpcClient.config.getConfigFilePath.query({ + projectId: params.projectId, + }), + }), + ]); + } catch (error) { + // If project not found, throw notFound() to render 404 page + if (error instanceof Error && error.message.includes("not found")) { + throw notFound(); + } + // Re-throw other errors + throw error; + } + }, }); import { HiOutlineCog6Tooth, HiOutlineFolder } from "react-icons/hi2"; @@ -12,38 +50,17 @@ import { electronTrpc } from "renderer/lib/electron-trpc"; function ProjectSettingsPage() { const { projectId } = Route.useParams(); - const { data: project, isLoading } = electronTrpc.projects.get.useQuery({ + const { data: project } = electronTrpc.projects.get.useQuery({ id: projectId, }); - const { data: configFilePath } = - electronTrpc.config.getConfigFilePath.useQuery( - { projectId }, - { enabled: !!projectId }, - ); - - if (isLoading) { - return ( -
-
-
-
-
-
- ); - } + const { data: configFilePath } = electronTrpc.config.getConfigFilePath.useQuery({ + projectId, + }); + // Project is guaranteed to exist here because loader handles 404s if (!project) { - return ( -
-
-

Project

-

- Project not found -

-
-
- ); + return null; } return ( diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/workspace/$workspaceId/page.tsx b/apps/desktop/src/renderer/routes/_authenticated/settings/workspace/$workspaceId/page.tsx index e5b80e094..5a806c710 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/settings/workspace/$workspaceId/page.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/workspace/$workspaceId/page.tsx @@ -1,9 +1,33 @@ -import { createFileRoute } from "@tanstack/react-router"; +import { createFileRoute, notFound } from "@tanstack/react-router"; +import { electronTrpcClient } from "renderer/lib/trpc-client"; +import { NotFound } from "renderer/routes/not-found"; export const Route = createFileRoute( "/_authenticated/settings/workspace/$workspaceId/", )({ component: WorkspaceSettingsPage, + notFoundComponent: NotFound, + loader: async ({ params, context }) => { + const queryKey = [ + ["workspaces", "get"], + { input: { id: params.workspaceId }, type: "query" }, + ]; + + try { + await context.queryClient.ensureQueryData({ + queryKey, + queryFn: () => + electronTrpcClient.workspaces.get.query({ id: params.workspaceId }), + }); + } catch (error) { + // If workspace not found, throw notFound() to render 404 page + if (error instanceof Error && error.message.includes("not found")) { + throw notFound(); + } + // Re-throw other errors + throw error; + } + }, }); import { Input } from "@superset/ui/input"; @@ -14,34 +38,15 @@ import { useWorkspaceRename } from "renderer/screens/main/hooks/useWorkspaceRena function WorkspaceSettingsPage() { const { workspaceId } = Route.useParams(); - const { data: workspace, isLoading } = electronTrpc.workspaces.get.useQuery({ + const { data: workspace } = electronTrpc.workspaces.get.useQuery({ id: workspaceId, }); const rename = useWorkspaceRename(workspace?.id ?? "", workspace?.name ?? ""); - if (isLoading) { - return ( -
-
-
-
-
-
- ); - } - + // Workspace is guaranteed to exist here because loader handles 404s if (!workspace) { - return ( -
-
-

Workspace

-

- Workspace not found -

-
-
- ); + return null; } return ( diff --git a/apps/desktop/src/renderer/routes/sign-in/page.tsx b/apps/desktop/src/renderer/routes/sign-in/page.tsx index cd2ddc481..5a56528d7 100644 --- a/apps/desktop/src/renderer/routes/sign-in/page.tsx +++ b/apps/desktop/src/renderer/routes/sign-in/page.tsx @@ -1,5 +1,6 @@ import { type AuthProvider, COMPANY } from "@superset/shared/constants"; import { Button } from "@superset/ui/button"; +import { Spinner } from "@superset/ui/spinner"; import { createFileRoute, Navigate } from "@tanstack/react-router"; import { useEffect } from "react"; import { FaGithub } from "react-icons/fa"; @@ -25,7 +26,7 @@ function SignInPage() { if (isPending) { return (
-
+
); } diff --git a/apps/desktop/src/renderer/screens/main/components/TasksView/TasksView.tsx b/apps/desktop/src/renderer/screens/main/components/TasksView/TasksView.tsx index dc8410297..ffaace16f 100644 --- a/apps/desktop/src/renderer/screens/main/components/TasksView/TasksView.tsx +++ b/apps/desktop/src/renderer/screens/main/components/TasksView/TasksView.tsx @@ -1,4 +1,5 @@ import { ScrollArea } from "@superset/ui/scroll-area"; +import { Spinner } from "@superset/ui/spinner"; import { useState } from "react"; import { HiCheckCircle } from "react-icons/hi2"; import { TasksTableView } from "./components/TasksTableView"; @@ -25,7 +26,7 @@ export function TasksView() { {isLoading ? (
-
+
) : table.getRowModel().rows.length === 0 ? (
diff --git a/apps/desktop/src/renderer/stores/app-state.ts b/apps/desktop/src/renderer/stores/app-state.ts deleted file mode 100644 index e1dd48435..000000000 --- a/apps/desktop/src/renderer/stores/app-state.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { create } from "zustand"; -import { devtools } from "zustand/middleware"; - -export type AppView = "workspace" | "tasks" | "workspaces-list"; - -interface AppState { - currentView: AppView; - isTasksTabOpen: boolean; - isWorkspacesListOpen: boolean; - setView: (view: AppView) => void; - openTasks: () => void; - closeTasks: () => void; - openWorkspacesList: () => void; - closeWorkspacesList: () => void; -} - -export const useAppStore = create()( - devtools( - (set) => ({ - currentView: "workspace", - isTasksTabOpen: false, - isWorkspacesListOpen: false, - - setView: (view) => { - set({ currentView: view }); - }, - - openTasks: () => { - set({ currentView: "tasks", isTasksTabOpen: true }); - }, - - closeTasks: () => { - set({ currentView: "workspace", isTasksTabOpen: false }); - }, - - openWorkspacesList: () => { - set({ currentView: "workspaces-list", isWorkspacesListOpen: true }); - }, - - closeWorkspacesList: () => { - set({ currentView: "workspace", isWorkspacesListOpen: false }); - }, - }), - { name: "AppStore" }, - ), -); - -// Convenience hooks -export const useCurrentView = () => useAppStore((state) => state.currentView); -export const useOpenTasks = () => useAppStore((state) => state.openTasks); -export const useOpenWorkspacesList = () => - useAppStore((state) => state.openWorkspacesList); -export const useCloseWorkspacesList = () => - useAppStore((state) => state.closeWorkspacesList); diff --git a/apps/desktop/src/renderer/stores/index.ts b/apps/desktop/src/renderer/stores/index.ts index 824bd5107..82454b735 100644 --- a/apps/desktop/src/renderer/stores/index.ts +++ b/apps/desktop/src/renderer/stores/index.ts @@ -1,4 +1,3 @@ -export * from "./app-state"; export * from "./hotkeys"; export * from "./markdown-preferences"; export * from "./ports"; diff --git a/packages/auth/src/server.ts b/packages/auth/src/server.ts index d56d75286..539c0edec 100644 --- a/packages/auth/src/server.ts +++ b/packages/auth/src/server.ts @@ -22,9 +22,8 @@ export const auth = betterAuth({ env.NEXT_PUBLIC_MARKETING_URL, env.NEXT_PUBLIC_ADMIN_URL, // Electron desktop app origins - ...(env.NEXT_PUBLIC_DESKTOP_URL ? [env.NEXT_PUBLIC_DESKTOP_URL] : []), + ...(env.NEXT_PUBLIC_DESKTOP_URL ? [env.NEXT_PUBLIC_DESKTOP_URL] : []), // Dev: http://localhost:5927 "superset://app", // Production Electron app - "superset-dev://app", // Development Electron app (if using custom protocol) ], session: { expiresIn: 60 * 60 * 24 * 30, // 30 days From 42f40d4b439c7143b1b5d75eabfd8ecbaf07a864 Mon Sep 17 00:00:00 2001 From: Satya Patel Date: Wed, 14 Jan 2026 14:37:07 -0800 Subject: [PATCH 11/12] Hopefully done --- .../src/lib/trpc/routers/tasks/index.ts | 31 --- .../src/lib/trpc/routers/user/index.ts | 22 -- apps/desktop/src/main/index.ts | 4 +- apps/desktop/src/main/lib/api-client.ts | 42 ---- apps/desktop/src/main/lib/auth/auth.ts | 210 ------------------ .../src/main/lib/auth/crypto-storage.ts | 119 ---------- apps/desktop/src/main/lib/auth/index.ts | 2 - .../renderer/hooks/useWorkspaceShortcuts.ts | 3 +- .../providers/AuthProvider/AuthProvider.tsx | 26 ++- .../ElectronTRPCProvider.tsx | 9 +- .../react-query/workspaces/useOpenWorktree.ts | 7 +- .../workspace/$workspaceId/page.tsx | 13 +- .../settings/project/$projectId/page.tsx | 7 +- .../main/components/StartView/StartTopBar.tsx | 3 +- .../main/components/StartView/index.tsx | 5 +- .../main/components/WorkspaceInitEffects.tsx | 3 +- .../PortsList/hooks/usePortsData.ts | 3 +- .../WorkspaceListItem/WorkspaceListItem.tsx | 15 +- .../BranchSwitcher/BranchSwitcher.tsx | 11 +- .../DeleteWorkspaceDialog.tsx | 15 +- .../WorkspaceHoverCard/WorkspaceHoverCard.tsx | 9 +- .../TabsContent/Terminal/Terminal.tsx | 6 +- .../Sidebar/ChangesView/ChangesView.tsx | 36 +-- .../ChangesHeader/ChangesHeader.tsx | 9 +- .../components/FileItem/FileItem.tsx | 3 +- .../WorkspaceRow/WorkspaceRow.tsx | 19 +- .../WorkspacesListView/WorkspacesListView.tsx | 6 +- 27 files changed, 122 insertions(+), 516 deletions(-) delete mode 100644 apps/desktop/src/lib/trpc/routers/tasks/index.ts delete mode 100644 apps/desktop/src/lib/trpc/routers/user/index.ts delete mode 100644 apps/desktop/src/main/lib/api-client.ts delete mode 100644 apps/desktop/src/main/lib/auth/auth.ts delete mode 100644 apps/desktop/src/main/lib/auth/crypto-storage.ts delete mode 100644 apps/desktop/src/main/lib/auth/index.ts diff --git a/apps/desktop/src/lib/trpc/routers/tasks/index.ts b/apps/desktop/src/lib/trpc/routers/tasks/index.ts deleted file mode 100644 index 1bc27a9bd..000000000 --- a/apps/desktop/src/lib/trpc/routers/tasks/index.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { apiClient } from "main/lib/api-client"; -import { z } from "zod"; -import { publicProcedure, router } from "../.."; - -const taskPriorityValues = ["urgent", "high", "medium", "low", "none"] as const; - -const updateTaskSchema = z.object({ - id: z.string().uuid(), - title: z.string().min(1).optional(), - description: z.string().nullable().optional(), - status: z.string().optional(), - priority: z.enum(taskPriorityValues).optional(), - repositoryId: z.string().uuid().optional(), - assigneeId: z.string().uuid().nullable().optional(), - branch: z.string().nullable().optional(), - prUrl: z.string().url().nullable().optional(), - estimate: z.number().int().positive().nullable().optional(), - dueDate: z.coerce.date().nullable().optional(), - labels: z.array(z.string()).optional(), -}); - -export const createTasksRouter = () => { - return router({ - update: publicProcedure - .input(updateTaskSchema) - .mutation(async ({ input }) => { - const result = await apiClient.task.update.mutate(input); - return result; - }), - }); -}; diff --git a/apps/desktop/src/lib/trpc/routers/user/index.ts b/apps/desktop/src/lib/trpc/routers/user/index.ts deleted file mode 100644 index e93d1e0f0..000000000 --- a/apps/desktop/src/lib/trpc/routers/user/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { apiClient } from "main/lib/api-client"; -import { publicProcedure, router } from "../.."; - -/** - * User router - proxies to API tRPC endpoints - */ -export const createUserRouter = () => { - return router({ - /** - * Get current user info - */ - me: publicProcedure.query(async () => { - return apiClient.user.me.query(); - }), - - myOrganizations: publicProcedure.query(async () => { - return apiClient.user.myOrganizations.query(); - }), - }); -}; - -export type UserRouter = ReturnType; diff --git a/apps/desktop/src/main/index.ts b/apps/desktop/src/main/index.ts index 32ea00e45..f679d4504 100644 --- a/apps/desktop/src/main/index.ts +++ b/apps/desktop/src/main/index.ts @@ -215,7 +215,9 @@ if (!gotTheLock) { // Parse URL to extract pathname (e.g., superset://app/index.html#/ -> /index.html) const parsedUrl = new URL(request.url); const pathname = parsedUrl.pathname; - const filePath = path.normalize(path.join(__dirname, "../renderer", pathname)); + const filePath = path.normalize( + path.join(__dirname, "../renderer", pathname), + ); return net.fetch(`file://${filePath}`); }); } diff --git a/apps/desktop/src/main/lib/api-client.ts b/apps/desktop/src/main/lib/api-client.ts deleted file mode 100644 index 1eac6a438..000000000 --- a/apps/desktop/src/main/lib/api-client.ts +++ /dev/null @@ -1,42 +0,0 @@ -import type { AppRouter } from "@superset/trpc"; -import { createTRPCClient, httpBatchLink } from "@trpc/client"; -import { env } from "main/env.main"; -import superjson from "superjson"; -import { authService } from "./auth"; - -/** - * tRPC client for calling the Superset API - * Automatically includes the access token in requests - */ -export const apiClient = createTRPCClient({ - links: [ - httpBatchLink({ - url: `${env.NEXT_PUBLIC_API_URL}/api/trpc`, - transformer: superjson, - async headers() { - const token = authService.getAccessToken(); - if (token) { - return { - Authorization: `Bearer ${token}`, - }; - } - return {}; - }, - async fetch(url, options) { - try { - const response = await globalThis.fetch(url, options); - - if (response.status === 401 || response.status === 403) { - console.log("[api-client] Auth error, clearing session"); - await authService.signOut(); - } - - return response; - } catch (error) { - console.log("[api-client] Network error, preserving session", error); - throw error; - } - }, - }), - ], -}); diff --git a/apps/desktop/src/main/lib/auth/auth.ts b/apps/desktop/src/main/lib/auth/auth.ts deleted file mode 100644 index 1228b79a2..000000000 --- a/apps/desktop/src/main/lib/auth/auth.ts +++ /dev/null @@ -1,210 +0,0 @@ -import crypto from "node:crypto"; -import { EventEmitter } from "node:events"; -import fs from "node:fs/promises"; -import { join } from "node:path"; -import { authClient } from "@superset/auth/client"; -import type { AuthProvider } from "@superset/shared/constants"; -import { PROTOCOL_SCHEMES } from "@superset/shared/constants"; -import { shell } from "electron"; -import { env } from "main/env.main"; -import { SUPERSET_HOME_DIR } from "../app-environment"; -import { decrypt, encrypt } from "./crypto-storage"; - -export interface SignInResult { - success: boolean; - error?: string; -} - -const TOKEN_FILE = join(SUPERSET_HOME_DIR, "auth-token.enc"); -const stateStore = new Map(); - -export function parseAuthDeepLink( - url: string, -): { token: string; expiresAt: string; state: string } | null { - try { - const parsed = new URL(url); - const validProtocols = [ - `${PROTOCOL_SCHEMES.PROD}:`, - `${PROTOCOL_SCHEMES.DEV}:`, - ]; - if (!validProtocols.includes(parsed.protocol)) return null; - if (parsed.host !== "auth" || parsed.pathname !== "/callback") return null; - - const token = parsed.searchParams.get("token"); - const expiresAt = parsed.searchParams.get("expiresAt"); - const state = parsed.searchParams.get("state"); - if (!token || !expiresAt || !state) return null; - return { token, expiresAt, state }; - } catch { - return null; - } -} - -interface StoredAuth { - token: string; - expiresAt: string; -} - -type SessionResponse = Awaited>; -/** Session data from the auth API */ -export type AuthSession = NonNullable; -type Session = AuthSession; - -class AuthService extends EventEmitter { - private token: string | null = null; - private expiresAt: Date | null = null; - private session: Session | null = null; - - async initialize(): Promise { - try { - const data = decrypt(await fs.readFile(TOKEN_FILE)); - const parsed: StoredAuth = JSON.parse(data); - this.token = parsed.token; - this.expiresAt = new Date(parsed.expiresAt); - - if (this.isExpired()) { - await this.signOut(); - } else { - await this.refreshSession(); - } - } catch { - this.token = null; - this.expiresAt = null; - } - } - - private isExpired(): boolean { - if (!this.expiresAt) return true; - // Consider expired 5 minutes before actual expiry for safety - const bufferMs = 5 * 60 * 1000; - return Date.now() > this.expiresAt.getTime() - bufferMs; - } - - getState() { - return { - isSignedIn: !!this.token && !this.isExpired(), - expiresAt: this.expiresAt?.toISOString() ?? null, - }; - } - - getAccessToken(): string | null { - return this.isExpired() ? null : this.token; - } - - getSession(): Session | null { - return this.session; - } - - private async refreshSession(): Promise { - const token = this.getAccessToken(); - if (!token) { - this.session = null; - return; - } - - try { - const { data: session, error } = await authClient.getSession({ - fetchOptions: { - headers: { - Authorization: `Bearer ${token}`, - }, - }, - }); - - if (error) { - console.error("[auth] Failed to refresh session:", error); - this.session = null; - return; - } - - this.session = session; - this.emit("session-changed", this.session); - } catch (error) { - console.error("[auth] Failed to refresh session:", error); - this.session = null; - } - } - - async setActiveOrganization(organizationId: string): Promise { - const token = this.getAccessToken(); - if (!token) throw new Error("Not authenticated"); - - const { error } = await authClient.organization.setActive({ - organizationId, - fetchOptions: { - headers: { - Authorization: `Bearer ${token}`, - }, - }, - }); - - if (error) { - throw new Error(`Failed to set active organization: ${error.message}`); - } - - // Refresh session to get updated activeOrganizationId - await this.refreshSession(); - } - - async signIn(provider: AuthProvider): Promise { - try { - const state = crypto.randomBytes(32).toString("base64url"); - stateStore.set(state, Date.now()); - - const tenMinutesAgo = Date.now() - 10 * 60 * 1000; - for (const [s, ts] of stateStore) { - if (ts < tenMinutesAgo) stateStore.delete(s); - } - - const connectUrl = new URL( - `${env.NEXT_PUBLIC_API_URL}/api/auth/desktop/connect`, - ); - connectUrl.searchParams.set("provider", provider); - connectUrl.searchParams.set("state", state); - await shell.openExternal(connectUrl.toString()); - return { success: true }; - } catch (err) { - return { - success: false, - error: err instanceof Error ? err.message : "Failed to open browser", - }; - } - } - - async handleAuthCallback(params: { - token: string; - expiresAt: string; - state: string; - }): Promise { - if (!stateStore.has(params.state)) { - return { success: false, error: "Invalid or expired auth session" }; - } - stateStore.delete(params.state); - - this.token = params.token; - this.expiresAt = new Date(params.expiresAt); - - const storedAuth: StoredAuth = { - token: this.token, - expiresAt: params.expiresAt, - }; - await fs.writeFile(TOKEN_FILE, encrypt(JSON.stringify(storedAuth))); - - await this.refreshSession(); - this.emit("state-changed", this.getState()); - - return { success: true }; - } - - async signOut(): Promise { - this.token = null; - this.expiresAt = null; - this.session = null; - try { - await fs.unlink(TOKEN_FILE); - } catch {} - this.emit("state-changed", this.getState()); - } -} - -export const authService = new AuthService(); diff --git a/apps/desktop/src/main/lib/auth/crypto-storage.ts b/apps/desktop/src/main/lib/auth/crypto-storage.ts deleted file mode 100644 index faeba16f7..000000000 --- a/apps/desktop/src/main/lib/auth/crypto-storage.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { execFileSync } from "node:child_process"; -import { - createCipheriv, - createDecipheriv, - randomBytes, - scryptSync, -} from "node:crypto"; -import { readFileSync } from "node:fs"; -import { homedir, hostname, platform } from "node:os"; - -const ALGORITHM = "aes-256-gcm"; -const KEY_LENGTH = 32; -const SALT_LENGTH = 16; -const IV_LENGTH = 12; -const AUTH_TAG_LENGTH = 16; - -/** - * Gets a stable machine identifier for key derivation. - */ -function getMachineId(): string { - try { - const os = platform(); - - if (os === "darwin") { - // macOS: Use IOPlatformUUID (hardware UUID) - const output = execFileSync( - "ioreg", - ["-rd1", "-c", "IOPlatformExpertDevice"], - { encoding: "utf8" }, - ); - const match = output.match(/"IOPlatformUUID"\s*=\s*"([^"]+)"/); - if (match?.[1]) return match[1]; - } else if (os === "linux") { - // Linux: Use machine-id - try { - return readFileSync("/etc/machine-id", "utf8").trim(); - } catch { - return readFileSync("/var/lib/dbus/machine-id", "utf8").trim(); - } - } else if (os === "win32") { - // Windows: Use MachineGuid from registry - const output = execFileSync( - "reg", - [ - "query", - "HKLM\\SOFTWARE\\Microsoft\\Cryptography", - "/v", - "MachineGuid", - ], - { encoding: "utf8" }, - ); - const match = output.match(/MachineGuid\s+REG_SZ\s+(\S+)/); - if (match?.[1]) return match[1]; - } - } catch { - // Fallback if platform-specific method fails - } - - // Fallback: Use a combination of stable system properties - // This is less secure but ensures the app still works - return `${hostname()}-${homedir()}-superset-fallback`; -} - -/** - * Derives an encryption key from the machine ID and a salt. - */ -function deriveKey(salt: Buffer): Buffer { - const machineId = getMachineId(); - return scryptSync(machineId, salt, KEY_LENGTH); -} - -/** - * Encrypts a string using AES-256-GCM with a machine-derived key. - * Returns: salt (16) + iv (12) + authTag (16) + ciphertext - */ -export function encrypt(plaintext: string): Buffer { - const salt = randomBytes(SALT_LENGTH); - const key = deriveKey(salt); - const iv = randomBytes(IV_LENGTH); - - const cipher = createCipheriv(ALGORITHM, key, iv); - const encrypted = Buffer.concat([ - cipher.update(plaintext, "utf8"), - cipher.final(), - ]); - const authTag = cipher.getAuthTag(); - - // Combine all components: salt + iv + authTag + ciphertext - return Buffer.concat([salt, iv, authTag, encrypted]); -} - -const MIN_ENCRYPTED_LENGTH = SALT_LENGTH + IV_LENGTH + AUTH_TAG_LENGTH + 1; - -/** - * Decrypts data encrypted with the encrypt function. - */ -export function decrypt(data: Buffer): string { - if (data.length < MIN_ENCRYPTED_LENGTH) { - throw new Error("Encrypted data too short"); - } - - // Extract components - const salt = data.subarray(0, SALT_LENGTH); - const iv = data.subarray(SALT_LENGTH, SALT_LENGTH + IV_LENGTH); - const authTag = data.subarray( - SALT_LENGTH + IV_LENGTH, - SALT_LENGTH + IV_LENGTH + AUTH_TAG_LENGTH, - ); - const ciphertext = data.subarray(SALT_LENGTH + IV_LENGTH + AUTH_TAG_LENGTH); - - const key = deriveKey(salt); - const decipher = createDecipheriv(ALGORITHM, key, iv); - decipher.setAuthTag(authTag); - - return Buffer.concat([ - decipher.update(ciphertext), - decipher.final(), - ]).toString("utf8"); -} diff --git a/apps/desktop/src/main/lib/auth/index.ts b/apps/desktop/src/main/lib/auth/index.ts deleted file mode 100644 index 7741ad341..000000000 --- a/apps/desktop/src/main/lib/auth/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export type { AuthSession, SignInResult } from "./auth"; -export { authService, parseAuthDeepLink } from "./auth"; diff --git a/apps/desktop/src/renderer/hooks/useWorkspaceShortcuts.ts b/apps/desktop/src/renderer/hooks/useWorkspaceShortcuts.ts index bdca47475..6b78f9062 100644 --- a/apps/desktop/src/renderer/hooks/useWorkspaceShortcuts.ts +++ b/apps/desktop/src/renderer/hooks/useWorkspaceShortcuts.ts @@ -11,7 +11,8 @@ import { useAppHotkey } from "renderer/stores/hotkeys"; * Handles ⌘1-9 workspace switching shortcuts (global). */ export function useWorkspaceShortcuts() { - const { data: groups = [] } = electronTrpc.workspaces.getAllGrouped.useQuery(); + const { data: groups = [] } = + electronTrpc.workspaces.getAllGrouped.useQuery(); const navigate = useNavigate(); // Flatten workspaces for keyboard navigation diff --git a/apps/desktop/src/renderer/providers/AuthProvider/AuthProvider.tsx b/apps/desktop/src/renderer/providers/AuthProvider/AuthProvider.tsx index 96e7f25b6..35cc4cada 100644 --- a/apps/desktop/src/renderer/providers/AuthProvider/AuthProvider.tsx +++ b/apps/desktop/src/renderer/providers/AuthProvider/AuthProvider.tsx @@ -19,23 +19,25 @@ export function AuthProvider({ children }: { children: ReactNode }) { const { refetch: refetchSession } = authClient.useSession(); // Initial hydration: Load token from disk - const { data: storedToken } = electronTrpc.auth.getStoredToken.useQuery( - undefined, - { + const { data: storedToken, isSuccess } = + electronTrpc.auth.getStoredToken.useQuery(undefined, { refetchOnWindowFocus: false, refetchOnReconnect: false, - }, - ); + }); useEffect(() => { - if (storedToken && !isHydrated) { - if (storedToken.token && storedToken.expiresAt) { - setAuthToken(storedToken.token); - refetchSession(); - } - setIsHydrated(true); + // Wait for query to complete before hydrating + if (!isSuccess || isHydrated) return; + + // If token exists, set it in memory and refetch session + if (storedToken?.token && storedToken?.expiresAt) { + setAuthToken(storedToken.token); + refetchSession(); } - }, [storedToken, isHydrated, refetchSession]); + + // Always mark as hydrated once query completes (even if no token) + setIsHydrated(true); + }, [storedToken, isSuccess, isHydrated, refetchSession]); // Listen for token changes from main process (OAuth callback) electronTrpc.auth.onTokenChanged.useSubscription(undefined, { diff --git a/apps/desktop/src/renderer/providers/ElectronTRPCProvider/ElectronTRPCProvider.tsx b/apps/desktop/src/renderer/providers/ElectronTRPCProvider/ElectronTRPCProvider.tsx index 9cda54afa..58cc75aa1 100644 --- a/apps/desktop/src/renderer/providers/ElectronTRPCProvider/ElectronTRPCProvider.tsx +++ b/apps/desktop/src/renderer/providers/ElectronTRPCProvider/ElectronTRPCProvider.tsx @@ -26,10 +26,11 @@ export function ElectronTRPCProvider({ children: React.ReactNode; }) { return ( - - - {children} - + + {children} ); } diff --git a/apps/desktop/src/renderer/react-query/workspaces/useOpenWorktree.ts b/apps/desktop/src/renderer/react-query/workspaces/useOpenWorktree.ts index 98f870fe7..f040663a6 100644 --- a/apps/desktop/src/renderer/react-query/workspaces/useOpenWorktree.ts +++ b/apps/desktop/src/renderer/react-query/workspaces/useOpenWorktree.ts @@ -12,7 +12,9 @@ import { useTabsStore } from "renderer/stores/tabs/store"; * Shows config toast if no setup commands are configured */ export function useOpenWorktree( - options?: Parameters[0], + options?: Parameters< + typeof electronTrpc.workspaces.openWorktree.useMutation + >[0], ) { const navigate = useNavigate(); const utils = electronTrpc.useUtils(); @@ -20,7 +22,8 @@ export function useOpenWorktree( const setTabAutoTitle = useTabsStore((state) => state.setTabAutoTitle); const createOrAttach = electronTrpc.terminal.createOrAttach.useMutation(); const openConfigModal = useOpenConfigModal(); - const dismissConfigToast = electronTrpc.config.dismissConfigToast.useMutation(); + const dismissConfigToast = + electronTrpc.config.dismissConfigToast.useMutation(); return electronTrpc.workspaces.openWorktree.useMutation({ ...options, diff --git a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/$workspaceId/page.tsx b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/$workspaceId/page.tsx index 39e79ff3b..dcbca503e 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/$workspaceId/page.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/_dashboard/workspace/$workspaceId/page.tsx @@ -53,7 +53,9 @@ export const Route = createFileRoute( function WorkspacePage() { const { workspaceId } = Route.useParams(); - const { data: workspace } = electronTrpc.workspaces.get.useQuery({ id: workspaceId }); + const { data: workspace } = electronTrpc.workspaces.get.useQuery({ + id: workspaceId, + }); const navigate = useNavigate(); // Check if workspace is initializing or failed @@ -289,10 +291,11 @@ function WorkspacePage() { ); // Navigate to previous workspace (⌘↑) - const getPreviousWorkspace = electronTrpc.workspaces.getPreviousWorkspace.useQuery( - { id: workspaceId }, - { enabled: !!workspaceId }, - ); + const getPreviousWorkspace = + electronTrpc.workspaces.getPreviousWorkspace.useQuery( + { id: workspaceId }, + { enabled: !!workspaceId }, + ); useAppHotkey( "PREV_WORKSPACE", () => { diff --git a/apps/desktop/src/renderer/routes/_authenticated/settings/project/$projectId/page.tsx b/apps/desktop/src/renderer/routes/_authenticated/settings/project/$projectId/page.tsx index c99d119c7..082d7dc18 100644 --- a/apps/desktop/src/renderer/routes/_authenticated/settings/project/$projectId/page.tsx +++ b/apps/desktop/src/renderer/routes/_authenticated/settings/project/$projectId/page.tsx @@ -54,9 +54,10 @@ function ProjectSettingsPage() { id: projectId, }); - const { data: configFilePath } = electronTrpc.config.getConfigFilePath.useQuery({ - projectId, - }); + const { data: configFilePath } = + electronTrpc.config.getConfigFilePath.useQuery({ + projectId, + }); // Project is guaranteed to exist here because loader handles 404s if (!project) { diff --git a/apps/desktop/src/renderer/screens/main/components/StartView/StartTopBar.tsx b/apps/desktop/src/renderer/screens/main/components/StartView/StartTopBar.tsx index fbd328895..aa9d2f762 100644 --- a/apps/desktop/src/renderer/screens/main/components/StartView/StartTopBar.tsx +++ b/apps/desktop/src/renderer/screens/main/components/StartView/StartTopBar.tsx @@ -3,7 +3,8 @@ import { SettingsButton } from "../SettingsButton"; import { WindowControls } from "../TopBar/WindowControls"; export function StartTopBar() { - const { data: platform, isLoading } = electronTrpc.window.getPlatform.useQuery(); + const { data: platform, isLoading } = + electronTrpc.window.getPlatform.useQuery(); const isMac = !isLoading && platform === "darwin"; const showWindowControls = !isLoading && !isMac; diff --git a/apps/desktop/src/renderer/screens/main/components/StartView/index.tsx b/apps/desktop/src/renderer/screens/main/components/StartView/index.tsx index 6ea9bdeb6..f3ccd2d99 100644 --- a/apps/desktop/src/renderer/screens/main/components/StartView/index.tsx +++ b/apps/desktop/src/renderer/screens/main/components/StartView/index.tsx @@ -2,8 +2,8 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "@superset/ui/tooltip"; import { useState } from "react"; import { HiExclamationTriangle } from "react-icons/hi2"; import { LuChevronUp, LuFolderGit, LuFolderOpen, LuX } from "react-icons/lu"; -import { formatPathWithProject } from "renderer/lib/formatPath"; import { electronTrpc } from "renderer/lib/electron-trpc"; +import { formatPathWithProject } from "renderer/lib/formatPath"; import { useOpenNew } from "renderer/react-query/projects"; import { useCreateBranchWorkspace } from "renderer/react-query/workspaces"; import { ActionCard } from "./ActionCard"; @@ -12,7 +12,8 @@ import { InitGitDialog } from "./InitGitDialog"; import { StartTopBar } from "./StartTopBar"; export function StartView() { - const { data: recentProjects = [] } = electronTrpc.projects.getRecents.useQuery(); + const { data: recentProjects = [] } = + electronTrpc.projects.getRecents.useQuery(); const { data: homeDir } = electronTrpc.window.getHomeDir.useQuery(); const openNew = useOpenNew(); const createBranchWorkspace = useCreateBranchWorkspace(); diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceInitEffects.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceInitEffects.tsx index da1620f8d..4480d91e6 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceInitEffects.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceInitEffects.tsx @@ -37,7 +37,8 @@ export function WorkspaceInitEffects() { const setTabAutoTitle = useTabsStore((state) => state.setTabAutoTitle); const createOrAttach = electronTrpc.terminal.createOrAttach.useMutation(); const openConfigModal = useOpenConfigModal(); - const dismissConfigToast = electronTrpc.config.dismissConfigToast.useMutation(); + const dismissConfigToast = + electronTrpc.config.dismissConfigToast.useMutation(); const utils = electronTrpc.useUtils(); // Helper to create terminal with setup commands diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/PortsList/hooks/usePortsData.ts b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/PortsList/hooks/usePortsData.ts index d21f69d36..22510c658 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/PortsList/hooks/usePortsData.ts +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/PortsList/hooks/usePortsData.ts @@ -20,7 +20,8 @@ export function usePortsData() { const utils = electronTrpc.useUtils(); - const { data: allStaticPortsData } = electronTrpc.ports.getAllStatic.useQuery(); + const { data: allStaticPortsData } = + electronTrpc.ports.getAllStatic.useQuery(); // Subscribe to all static port changes electronTrpc.ports.subscribeStatic.useSubscription( diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx index ce411518f..0c1078743 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/WorkspaceListItem.tsx @@ -109,13 +109,14 @@ export function WorkspaceListItem({ useWorkspaceDeleteHandler(); // Lazy-load GitHub status on hover to avoid N+1 queries - const { data: githubStatus } = electronTrpc.workspaces.getGitHubStatus.useQuery( - { workspaceId: id }, - { - enabled: hasHovered && type === "worktree", - staleTime: GITHUB_STATUS_STALE_TIME, - }, - ); + const { data: githubStatus } = + electronTrpc.workspaces.getGitHubStatus.useQuery( + { workspaceId: id }, + { + enabled: hasHovered && type === "worktree", + staleTime: GITHUB_STATUS_STALE_TIME, + }, + ); // Memoize workspace pane IDs to avoid recalculating on every render const workspacePaneIds = useMemo(() => { diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/BranchSwitcher/BranchSwitcher.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/BranchSwitcher/BranchSwitcher.tsx index 22b7d877f..3230eaa38 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/BranchSwitcher/BranchSwitcher.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/BranchSwitcher/BranchSwitcher.tsx @@ -40,11 +40,12 @@ export function BranchSwitcher({ { enabled: isOpen }, ); - const switchBranch = electronTrpc.workspaces.switchBranchWorkspace.useMutation({ - onSuccess: () => { - utils.workspaces.invalidate(); - }, - }); + const switchBranch = + electronTrpc.workspaces.switchBranchWorkspace.useMutation({ + onSuccess: () => { + utils.workspaces.invalidate(); + }, + }); // Branches in use by worktrees (branch -> workspaceId) const inUseWorkspaces = useMemo(() => { diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/DeleteWorkspaceDialog/DeleteWorkspaceDialog.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/DeleteWorkspaceDialog/DeleteWorkspaceDialog.tsx index 03920c103..7398cb993 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/DeleteWorkspaceDialog/DeleteWorkspaceDialog.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/DeleteWorkspaceDialog/DeleteWorkspaceDialog.tsx @@ -43,13 +43,14 @@ export function DeleteWorkspaceDialog({ }, ); - const { data: terminalCountData } = electronTrpc.workspaces.canDelete.useQuery( - { id: workspaceId, skipGitChecks: true }, - { - enabled: open, - refetchInterval: open ? 2000 : false, - }, - ); + const { data: terminalCountData } = + electronTrpc.workspaces.canDelete.useQuery( + { id: workspaceId, skipGitChecks: true }, + { + enabled: open, + refetchInterval: open ? 2000 : false, + }, + ); const canDeleteData = gitStatusData ? { diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/WorkspaceHoverCard/WorkspaceHoverCard.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/WorkspaceHoverCard/WorkspaceHoverCard.tsx index 304ec4a05..76942c2ac 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/WorkspaceHoverCard/WorkspaceHoverCard.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceSidebar/WorkspaceListItem/components/WorkspaceHoverCard/WorkspaceHoverCard.tsx @@ -23,10 +23,11 @@ export function WorkspaceHoverCardContent({ workspaceId, workspaceAlias, }: WorkspaceHoverCardContentProps) { - const { data: worktreeInfo } = electronTrpc.workspaces.getWorktreeInfo.useQuery( - { workspaceId }, - { enabled: !!workspaceId }, - ); + const { data: worktreeInfo } = + electronTrpc.workspaces.getWorktreeInfo.useQuery( + { workspaceId }, + { enabled: !!workspaceId }, + ); const { pr, diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx index 466c99455..3093c70e3 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/Terminal/Terminal.tsx @@ -197,11 +197,13 @@ export const Terminal = ({ tabId, workspaceId }: TerminalProps) => { const updateCwdRef = useRef(updateCwdFromData); updateCwdRef.current = updateCwdFromData; - const createOrAttachMutation = electronTrpc.terminal.createOrAttach.useMutation(); + const createOrAttachMutation = + electronTrpc.terminal.createOrAttach.useMutation(); const writeMutation = electronTrpc.terminal.write.useMutation(); const resizeMutation = electronTrpc.terminal.resize.useMutation(); const detachMutation = electronTrpc.terminal.detach.useMutation(); - const clearScrollbackMutation = electronTrpc.terminal.clearScrollback.useMutation(); + const clearScrollbackMutation = + electronTrpc.terminal.clearScrollback.useMutation(); const createOrAttachRef = useRef(createOrAttachMutation.mutate); const writeRef = useRef(writeMutation.mutate); diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx index 8b15e4f35..9c598663b 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/ChangesView.tsx @@ -107,24 +107,26 @@ export function ChangesView({ }, }); - const discardChangesMutation = electronTrpc.changes.discardChanges.useMutation({ - onSuccess: () => refetch(), - onError: (error, variables) => { - console.error( - `Failed to discard changes for ${variables.filePath}:`, - error, - ); - toast.error(`Failed to discard changes: ${error.message}`); - }, - }); + const discardChangesMutation = + electronTrpc.changes.discardChanges.useMutation({ + onSuccess: () => refetch(), + onError: (error, variables) => { + console.error( + `Failed to discard changes for ${variables.filePath}:`, + error, + ); + toast.error(`Failed to discard changes: ${error.message}`); + }, + }); - const deleteUntrackedMutation = electronTrpc.changes.deleteUntracked.useMutation({ - onSuccess: () => refetch(), - onError: (error, variables) => { - console.error(`Failed to delete ${variables.filePath}:`, error); - toast.error(`Failed to delete file: ${error.message}`); - }, - }); + const deleteUntrackedMutation = + electronTrpc.changes.deleteUntracked.useMutation({ + onSuccess: () => refetch(), + onError: (error, variables) => { + console.error(`Failed to delete ${variables.filePath}:`, error); + toast.error(`Failed to delete file: ${error.message}`); + }, + }); const handleDiscard = (file: ChangedFile) => { if (!worktreePath) return; diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/ChangesHeader/ChangesHeader.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/ChangesHeader/ChangesHeader.tsx index f703ce9ba..172baed40 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/ChangesHeader/ChangesHeader.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/ChangesHeader/ChangesHeader.tsx @@ -60,10 +60,11 @@ export function ChangesHeader({ const { baseBranch, setBaseBranch } = useChangesStore(); - const { data: branchData, isLoading } = electronTrpc.changes.getBranches.useQuery( - { worktreePath }, - { enabled: !!worktreePath }, - ); + const { data: branchData, isLoading } = + electronTrpc.changes.getBranches.useQuery( + { worktreePath }, + { enabled: !!worktreePath }, + ); const { pr, isLoading: isPRLoading } = usePRStatus({ workspaceId, diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileItem/FileItem.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileItem/FileItem.tsx index 9e97de092..9b5aa6a39 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileItem/FileItem.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/ChangesView/components/FileItem/FileItem.tsx @@ -94,7 +94,8 @@ export function FileItem({ const hasAction = onStage || onUnstage; const openInFinderMutation = electronTrpc.external.openInFinder.useMutation(); - const openInEditorMutation = electronTrpc.external.openFileInEditor.useMutation(); + const openInEditorMutation = + electronTrpc.external.openFileInEditor.useMutation(); const absolutePath = worktreePath ? `${worktreePath}/${file.path}` : null; diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspacesListView/WorkspaceRow/WorkspaceRow.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspacesListView/WorkspaceRow/WorkspaceRow.tsx index 0f8399526..2f529e397 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspacesListView/WorkspaceRow/WorkspaceRow.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspacesListView/WorkspaceRow/WorkspaceRow.tsx @@ -42,14 +42,17 @@ export function WorkspaceRow({ useWorkspaceDeleteHandler(); // Lazy-load GitHub status on hover to avoid N+1 queries - const { data: githubStatus } = electronTrpc.workspaces.getGitHubStatus.useQuery( - { workspaceId: workspace.workspaceId ?? "" }, - { - enabled: - hasHovered && workspace.type === "worktree" && !!workspace.workspaceId, - staleTime: GITHUB_STATUS_STALE_TIME, - }, - ); + const { data: githubStatus } = + electronTrpc.workspaces.getGitHubStatus.useQuery( + { workspaceId: workspace.workspaceId ?? "" }, + { + enabled: + hasHovered && + workspace.type === "worktree" && + !!workspace.workspaceId, + staleTime: GITHUB_STATUS_STALE_TIME, + }, + ); const pr = githubStatus?.pr; const showDiffStats = pr && (pr.additions > 0 || pr.deletions > 0); diff --git a/apps/desktop/src/renderer/screens/main/components/WorkspacesListView/WorkspacesListView.tsx b/apps/desktop/src/renderer/screens/main/components/WorkspacesListView/WorkspacesListView.tsx index 593238ccf..791ce5a34 100644 --- a/apps/desktop/src/renderer/screens/main/components/WorkspacesListView/WorkspacesListView.tsx +++ b/apps/desktop/src/renderer/screens/main/components/WorkspacesListView/WorkspacesListView.tsx @@ -23,8 +23,10 @@ export function WorkspacesListView() { const utils = electronTrpc.useUtils(); // Fetch all data - const { data: groups = [] } = electronTrpc.workspaces.getAllGrouped.useQuery(); - const { data: allProjects = [] } = electronTrpc.projects.getRecents.useQuery(); + const { data: groups = [] } = + electronTrpc.workspaces.getAllGrouped.useQuery(); + const { data: allProjects = [] } = + electronTrpc.projects.getRecents.useQuery(); // Fetch worktrees for all projects const worktreeQueries = electronTrpc.useQueries((t) => From d3c5bbc0836982498fb886a9f1f4e41f10425385 Mon Sep 17 00:00:00 2001 From: Satya Patel Date: Wed, 14 Jan 2026 14:42:16 -0800 Subject: [PATCH 12/12] Hopefully done --- apps/desktop/src/renderer/index.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/desktop/src/renderer/index.tsx b/apps/desktop/src/renderer/index.tsx index 1a330e0e8..d7acfcf71 100644 --- a/apps/desktop/src/renderer/index.tsx +++ b/apps/desktop/src/renderer/index.tsx @@ -26,12 +26,20 @@ const router = createRouter({ }, }); -router.subscribe("onResolved", () => { +// Track pageviews on navigation +const unsubscribe = router.subscribe("onResolved", (event) => { posthog.capture("$pageview", { - $current_url: window.location.href, + $current_url: event.toLocation.pathname, }); }); +// Clean up subscription on HMR +if (import.meta.hot) { + import.meta.hot.dispose(() => { + unsubscribe(); + }); +} + declare module "@tanstack/react-router" { interface Register { router: typeof router;