- Cloud app uses TanStack Start with SPA mode for unified dev/prod - File-based routes: pages, /v1/* API catch-all, /auth/* catch-all - Root route with auth gate + ExecutorProvider - Cloud-specific auth API group (CloudAuthApi) with typed atom - Upgrade Vite to v8, @vitejs/plugin-react to v6 across workspace - Catalog shared deps (vite, react, typescript, tanstack, tailwind) - Fix Tailwind @source paths for new package structure - Cloud shell with user footer, no version check
Unified · Split
| @@ -42,4 +42,4 @@ executor.har · 41 unmodified lines | ||
| 42 | 42 | apps/desktop/resources/ |
| 43 | 43 | |
| 44 | 44 | # cloud local dev database |
| 45 | −.pglite | |
| 45 | +.pglite | |
| @@ -0,0 +1,9 @@ | ||
| 1 | +[submodule ".reference/effect-atom"] | |
| 2 | + path = .reference/effect-atom | |
| 3 | + url = https://github.com/tim-smart/effect-atom.git | |
| 4 | +[submodule ".reference/tanstack-router"] | |
| 5 | + path = .reference/tanstack-router | |
| 6 | + url = https://github.com/TanStack/router.git | |
| 7 | +[submodule ".reference/effect"] | |
| 8 | + path = .reference/effect | |
| 9 | + url = https://github.com/Effect-TS/effect.git | |
| @@ -1 +0,0 @@ | ||
| 1 | −Subproject commit 2d532f8322368eedc835fa09dc9223a9ddef9e1d | |
| @@ -0,0 +1 @@ | ||
| 1 | +Subproject commit 5a81726f0a2f819fae0763896cef784aa10ddc9f | |
| @@ -30,6 +30,6 @@ · 29 unmodified lines | ||
| 30 | 30 | }, |
| 31 | 31 | "devDependencies": { |
| 32 | 32 | "bun-types": "catalog:", |
| 33 | − "typescript": "^5.9.3" | |
| 33 | + "typescript": "catalog:" | |
| 34 | 34 | } |
| 35 | 35 | } |
| @@ -1,15 +0,0 @@ | ||
| 1 | −<!doctype html> | |
| 2 | −<html lang="en"> | |
| 3 | − <head> | |
| 4 | − <meta charset="UTF-8" /> | |
| 5 | − <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| 6 | − <title>Executor Cloud</title> | |
| 7 | − <link rel="preconnect" href="https://fonts.googleapis.com" /> | |
| 8 | − <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> | |
| 9 | − <link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300..700;1,9..40,300..700&family=Instrument+Serif&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" /> | |
| 10 | − </head> | |
| 11 | − <body> | |
| 12 | − <div id="root"></div> | |
| 13 | − <script type="module" src="/src/web/main.tsx"></script> | |
| 14 | − </body> | |
| 15 | −</html> | |
| @@ -15,30 +15,30 @@ · 14 unmodified lines | ||
| 15 | 15 | "@executor/react": "workspace:*", |
| 16 | 16 | "@executor/sdk": "workspace:*", |
| 17 | 17 | "@executor/storage-postgres": "workspace:*", |
| 18 | − "@tanstack/react-router": "^1.168.10", | |
| 18 | + "@tanstack/react-router": "catalog:", | |
| 19 | + "@tanstack/react-start": "catalog:", | |
| 19 | 20 | "@workos-inc/node": "^7.0.0", |
| 20 | 21 | "drizzle-orm": "catalog:", |
| 21 | 22 | "effect": "catalog:", |
| 22 | 23 | "pg": "^8.16.0", |
| 23 | − "react": "^19.1.0", | |
| 24 | − "react-dom": "^19.1.0" | |
| 24 | + "react": "catalog:", | |
| 25 | + "react-dom": "catalog:" | |
| 25 | 26 | }, |
| 26 | 27 | "devDependencies": { |
| 27 | 28 | "@electric-sql/pglite": "^0.4.3", |
| 29 | + "@tailwindcss/vite": "catalog:", | |
| 28 | 30 | "@types/pg": "^8.15.4", |
| 29 | − "@tailwindcss/vite": "^4.1.10", | |
| 30 | − "@types/react": "^19.1.0", | |
| 31 | − "@types/react-dom": "^19.1.0", | |
| 32 | − "@vitejs/plugin-react": "^4.5.2", | |
| 31 | + "@types/react": "catalog:", | |
| 32 | + "@types/react-dom": "catalog:", | |
| 33 | + "@vitejs/plugin-react": "catalog:", | |
| 33 | 34 | "portless": "^0.3.0", |
| 34 | − "typescript": "^5.9.3", | |
| 35 | − "vite": "^6.3.5" | |
| 35 | + "typescript": "catalog:", | |
| 36 | + "vite": "catalog:" | |
| 36 | 37 | }, |
| 37 | 38 | "scripts": { |
| 38 | − "dev": "op run --env-file=.env -- portless executor-cloud bun --hot ./src/main.ts", | |
| 39 | − "dev:web": "vite", | |
| 40 | − "start": "bun ./src/main.ts", | |
| 41 | − "build:web": "vite build", | |
| 39 | + "dev": "portless executor-cloud op run --env-file=.env -- vite dev", | |
| 40 | + "build": "vite build", | |
| 41 | + "start": "bun ./server.ts", | |
| 42 | 42 | "typecheck": "tsc --noEmit" |
| 43 | 43 | } |
| 44 | 44 | } |
| @@ -12,17 +12,16 @@ import { Effect, Layer } from "effect"; · 11 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | import { addGroup, CoreHandlers, ExecutorService, ExecutionEngineService } from "@executor/api"; |
| 14 | 14 | import { createExecutionEngine } from "@executor/execution"; |
| 15 | −import { makeUserStore } from "@executor/storage-postgres"; | |
| 16 | 15 | import { OpenApiGroup, OpenApiExtensionService, OpenApiHandlers } from "@executor/plugin-openapi/api"; |
| 17 | 16 | import { McpGroup, McpExtensionService, McpHandlers } from "@executor/plugin-mcp/api"; |
| 18 | 17 | import { GoogleDiscoveryGroup, GoogleDiscoveryExtensionService, GoogleDiscoveryHandlers } from "@executor/plugin-google-discovery/api"; |
| 19 | 18 | import { GraphqlGroup, GraphqlExtensionService, GraphqlHandlers } from "@executor/plugin-graphql/api"; |
| 20 | 19 | |
| 21 | 20 | import { createTeamExecutor } from "./services/executor"; |
| 22 | −import { authenticateRequest } from "./auth/workos"; | |
| 23 | 21 | import { CloudAuthApi } from "./auth/api"; |
| 24 | 22 | import { CloudAuthHandlers } from "./auth/handlers"; |
| 25 | 23 | import { AuthContext, UserStoreService } from "./auth/context"; |
| 24 | +import { WorkOSAuth } from "./auth/workos"; | |
| 26 | 25 | import type { DrizzleDb } from "./services/db"; |
| 27 | 26 | |
| 28 | 27 | // --------------------------------------------------------------------------- |
| @@ -65,10 +64,15 @@ const parseCookie = (cookieHeader: string | null, name: string): string | null = · 36 unmodified lines | ||
| 65 | 64 | // --------------------------------------------------------------------------- |
| 66 | 65 | |
| 67 | 66 | export const createCloudApiHandler = (db: DrizzleDb, encryptionKey: string) => { |
| 68 | − const userStore = makeUserStore(db); | |
| 69 | − | |
| 70 | 67 | return async (request: Request): Promise<Response> => { |
| 71 | − const auth = await authenticateRequest(request); | |
| 68 | + // Authenticate via WorkOS sealed session | |
| 69 | + const auth = await Effect.runPromise( | |
| 70 | + Effect.gen(function* () { | |
| 71 | + const workos = yield* WorkOSAuth; | |
| 72 | + return yield* workos.authenticateRequest(request); | |
| 73 | + }).pipe(Effect.provide(WorkOSAuth.Default)), | |
| 74 | + ); | |
| 75 | + | |
| 72 | 76 | if (!auth) { |
| 73 | 77 | return Response.json({ error: "Unauthorized" }, { status: 401 }); |
| 74 | 78 | } |
| @@ -78,7 +82,14 @@ export const createCloudApiHandler = (db: DrizzleDb, encryptionKey: string) => { · 3 unmodified lines | ||
| 78 | 82 | return Response.json({ error: "No team selected" }, { status: 401 }); |
| 79 | 83 | } |
| 80 | 84 | |
| 81 | − const team = await userStore.getTeam(teamId); | |
| 85 | + // Resolve team name | |
| 86 | + const userStore = UserStoreService.layer(db); | |
| 87 | + const team = await Effect.runPromise( | |
| 88 | + Effect.gen(function* () { | |
| 89 | + const users = yield* UserStoreService; | |
| 90 | + return yield* users.use((s) => s.getTeam(teamId)); | |
| 91 | + }).pipe(Effect.provide(userStore)), | |
| 92 | + ); | |
| 82 | 93 | const teamName = team?.name ?? "Unknown Team"; |
| 83 | 94 | |
| 84 | 95 | const executor = await Effect.runPromise( |
| @@ -108,7 +119,8 @@ export const createCloudApiHandler = (db: DrizzleDb, encryptionKey: string) => { · 23 unmodified lines | ||
| 108 | 119 | name: `${auth.firstName ?? ""} ${auth.lastName ?? ""}`.trim() || null, |
| 109 | 120 | avatarUrl: auth.avatarUrl, |
| 110 | 121 | })), |
| 111 | − Layer.provideMerge(Layer.succeed(UserStoreService, userStore)), | |
| 122 | + Layer.provideMerge(UserStoreService.layer(db)), | |
| 123 | + Layer.provideMerge(WorkOSAuth.Default), | |
| 112 | 124 | Layer.provideMerge(HttpServer.layerContext), |
| 113 | 125 | ), |
| 114 | 126 | { middleware: HttpMiddleware.logger }, |
| @@ -1,5 +1,6 @@ | ||
| 1 | 1 | import { HttpApiEndpoint, HttpApiGroup } from "@effect/platform"; |
| 2 | 2 | import { Schema } from "effect"; |
| 3 | +import { UserStoreError, WorkOSError } from "./context"; | |
| 3 | 4 | |
| 4 | 5 | const AuthUser = Schema.Struct({ |
| 5 | 6 | id: Schema.String, |
| @@ -18,8 +19,25 @@ const AuthMeResponse = Schema.Struct({ · 12 unmodified lines | ||
| 18 | 19 | team: Schema.NullOr(AuthTeam), |
| 19 | 20 | }); |
| 20 | 21 | |
| 22 | +const AuthCallbackSearch = Schema.Struct({ | |
| 23 | + code: Schema.String, | |
| 24 | +}); | |
| 25 | + | |
| 21 | 26 | export class CloudAuthApi extends HttpApiGroup.make("cloudAuth") |
| 22 | 27 | .add( |
| 23 | 28 | HttpApiEndpoint.get("me")`/auth/me` |
| 24 | − .addSuccess(AuthMeResponse), | |
| 29 | + .addSuccess(AuthMeResponse) | |
| 30 | + .addError(UserStoreError), | |
| 31 | + ) | |
| 32 | + .add( | |
| 33 | + HttpApiEndpoint.get("login")`/auth/login`, | |
| 34 | + ) | |
| 35 | + .add( | |
| 36 | + HttpApiEndpoint.get("callback")`/auth/callback` | |
| 37 | + .setUrlParams(AuthCallbackSearch) | |
| 38 | + .addError(UserStoreError) | |
| 39 | + .addError(WorkOSError), | |
| 40 | + ) | |
| 41 | + .add( | |
| 42 | + HttpApiEndpoint.post("logout")`/auth/logout`, | |
| 25 | 43 | ) {} |
| @@ -1,5 +1,24 @@ | ||
| 1 | −import { Context } from "effect"; | |
| 2 | −import type { makeUserStore } from "@executor/storage-postgres"; | |
| 1 | +import { Context, Effect, Layer, Schema } from "effect"; | |
| 2 | +import { makeUserStore } from "@executor/storage-postgres"; | |
| 3 | +import type { DrizzleDb } from "../services/db"; | |
| 4 | + | |
| 5 | +// --------------------------------------------------------------------------- | |
| 6 | +// Errors | |
| 7 | +// --------------------------------------------------------------------------- | |
| 8 | + | |
| 9 | +export class UserStoreError extends Schema.TaggedError<UserStoreError>()( | |
| 10 | + "UserStoreError", | |
| 11 | + { cause: Schema.Unknown }, | |
| 12 | +) {} | |
| 13 | + | |
| 14 | +export class WorkOSError extends Schema.TaggedError<WorkOSError>()( | |
| 15 | + "WorkOSError", | |
| 16 | + { cause: Schema.Unknown }, | |
| 17 | +) {} | |
| 18 | + | |
| 19 | +// --------------------------------------------------------------------------- | |
| 20 | +// AuthContext — resolved per-request from sealed session | |
| 21 | +// --------------------------------------------------------------------------- | |
| 3 | 22 | |
| 4 | 23 | export class AuthContext extends Context.Tag("@executor/cloud/AuthContext")< |
| 5 | 24 | AuthContext, |
| @@ -12,7 +31,30 @@ export class AuthContext extends Context.Tag("@executor/cloud/AuthContext")< · 6 unmodified lines | ||
| 12 | 31 | } |
| 13 | 32 | >() {} |
| 14 | 33 | |
| 34 | +// --------------------------------------------------------------------------- | |
| 35 | +// UserStoreService — wraps the Drizzle-backed user store with Effect | |
| 36 | +// --------------------------------------------------------------------------- | |
| 37 | + | |
| 38 | +type RawStore = ReturnType<typeof makeUserStore>; | |
| 39 | + | |
| 40 | +const makeService = (db: DrizzleDb) => { | |
| 41 | + const store = makeUserStore(db); | |
| 42 | + | |
| 43 | + const use = <A>(fn: (s: RawStore) => Promise<A>) => | |
| 44 | + Effect.tryPromise({ | |
| 45 | + try: () => fn(store), | |
| 46 | + catch: (cause) => new UserStoreError({ cause }), | |
| 47 | + }).pipe(Effect.withSpan("user_store")); | |
| 48 | + | |
| 49 | + return { use }; | |
| 50 | +}; | |
| 51 | + | |
| 52 | +type UserStoreServiceType = ReturnType<typeof makeService>; | |
| 53 | + | |
| 15 | 54 | export class UserStoreService extends Context.Tag("@executor/cloud/UserStoreService")< |
| 16 | 55 | UserStoreService, |
| 17 | − ReturnType<typeof makeUserStore> | |
| 18 | −>() {} | |
| 56 | + UserStoreServiceType | |
| 57 | +>() { | |
| 58 | + static layer = (db: DrizzleDb) => | |
| 59 | + Layer.succeed(this, makeService(db)); | |
| 60 | +} | |
| @@ -1,9 +1,10 @@ | ||
| 1 | −import { HttpApiBuilder } from "@effect/platform"; | |
| 1 | +import { HttpApiBuilder, HttpServerResponse } from "@effect/platform"; | |
| 2 | 2 | import { Effect } from "effect"; |
| 3 | 3 | |
| 4 | 4 | import { addGroup } from "@executor/api"; |
| 5 | 5 | import { CloudAuthApi } from "./api"; |
| 6 | 6 | import { AuthContext, UserStoreService } from "./context"; |
| 7 | +import { WorkOSAuth, makeSessionCookie, clearSessionCookie } from "./workos"; | |
| 7 | 8 | |
| 8 | 9 | const ApiWithCloudAuth = addGroup(CloudAuthApi); |
| 9 | 10 | |
| @@ -11,24 +12,97 @@ export const CloudAuthHandlers = HttpApiBuilder.group( · 1 unmodified line | ||
| 11 | 12 | ApiWithCloudAuth, |
| 12 | 13 | "cloudAuth", |
| 13 | 14 | (handlers) => |
| 14 | − handlers.handle("me", () => | |
| 15 | − Effect.gen(function* () { | |
| 16 | − const auth = yield* AuthContext; | |
| 17 | − const userStore = yield* UserStoreService; | |
| 18 | − | |
| 19 | − const team = yield* Effect.tryPromise(() => | |
| 20 | − userStore.getTeam(auth.teamId), | |
| 21 | − ).pipe(Effect.orDie); | |
| 22 | − | |
| 23 | − return { | |
| 24 | − user: { | |
| 25 | − id: auth.userId, | |
| 26 | − email: auth.email, | |
| 27 | − name: auth.name, | |
| 28 | − avatarUrl: auth.avatarUrl, | |
| 29 | − }, | |
| 30 | − team: team ? { id: team.id, name: team.name } : null, | |
| 31 | − }; | |
| 32 | − }), | |
| 33 | − ), | |
| 15 | + handlers | |
| 16 | + .handle("me", () => | |
| 17 | + Effect.gen(function* () { | |
| 18 | + const auth = yield* AuthContext; | |
| 19 | + const users = yield* UserStoreService; | |
| 20 | + const team = yield* users.use((s) => s.getTeam(auth.teamId)); | |
| 21 | + | |
| 22 | + return { | |
| 23 | + user: { | |
| 24 | + id: auth.userId, | |
| 25 | + email: auth.email, | |
| 26 | + name: auth.name, | |
| 27 | + avatarUrl: auth.avatarUrl, | |
| 28 | + }, | |
| 29 | + team: team ? { id: team.id, name: team.name } : null, | |
| 30 | + }; | |
| 31 | + }), | |
| 32 | + ) | |
| 33 | + .handleRaw("login", () => | |
| 34 | + Effect.gen(function* () { | |
| 35 | + const workos = yield* WorkOSAuth; | |
| 36 | + const baseUrl = process.env.APP_URL ?? `http://localhost:${process.env.PORT ?? "3000"}`; | |
| 37 | + const url = workos.getAuthorizationUrl(`${baseUrl}/auth/callback`); | |
| 38 | + return HttpServerResponse.redirect(url, { status: 302 }); | |
| 39 | + }), | |
| 40 | + ) | |
| 41 | + .handleRaw("callback", ({ urlParams }) => | |
| 42 | + Effect.gen(function* () { | |
| 43 | + const workos = yield* WorkOSAuth; | |
| 44 | + const users = yield* UserStoreService; | |
| 45 | + | |
| 46 | + const result = yield* workos.authenticateWithCode(urlParams.code); | |
| 47 | + const workosUser = result.user; | |
| 48 | + | |
| 49 | + const user = yield* users.use((s) => | |
| 50 | + s.upsertUser({ | |
| 51 | + id: workosUser.id, | |
| 52 | + email: workosUser.email, | |
| 53 | + name: `${workosUser.firstName ?? ""} ${workosUser.lastName ?? ""}`.trim() || undefined, | |
| 54 | + avatarUrl: workosUser.profilePictureUrl ?? undefined, | |
| 55 | + }), | |
| 56 | + ); | |
| 57 | + | |
| 58 | + const resolveTeam = Effect.gen(function* () { | |
| 59 | + const pending = yield* users.use((s) => s.getPendingInvitations(user.email)); | |
| 60 | + if (pending.length > 0) { | |
| 61 | + const invitation = pending[0]!; | |
| 62 | + yield* users.use((s) => s.acceptInvitation(invitation.id)); | |
| 63 | + yield* users.use((s) => s.addMember(invitation.teamId, user.id, "member")); | |
| 64 | + return invitation.teamId; | |
| 65 | + } | |
| 66 | + | |
| 67 | + const teams = yield* users.use((s) => s.getTeamsForUser(user.id)); | |
| 68 | + if (teams.length > 0) return teams[0]!.teamId; | |
| 69 | + | |
| 70 | + const team = yield* users.use((s) => | |
| 71 | + s.createTeam(`${user.name ?? user.email}'s Team`), | |
| 72 | + ); | |
| 73 | + yield* users.use((s) => s.addMember(team.id, user.id, "owner")); | |
| 74 | + return team.id; | |
| 75 | + }); | |
| 76 | + | |
| 77 | + const teamId = yield* resolveTeam; | |
| 78 | + | |
| 79 | + const sealedSession = result.sealedSession; | |
| 80 | + if (!sealedSession) { | |
| 81 | + return HttpServerResponse.text("Failed to create session", { status: 500 }); | |
| 82 | + } | |
| 83 | + | |
| 84 | + return HttpServerResponse.redirect("/", { | |
| 85 | + status: 302, | |
| 86 | + headers: { | |
| 87 | + "Set-Cookie": [ | |
| 88 | + makeSessionCookie(sealedSession), | |
| 89 | + `executor_team=${teamId}; Path=/; HttpOnly; SameSite=Lax; Max-Age=604800`, | |
| 90 | + ].join(", "), | |
| 91 | + }, | |
| 92 | + }); | |
| 93 | + }), | |
| 94 | + ) | |
| 95 | + .handleRaw("logout", () => | |
| 96 | + Effect.succeed( | |
| 97 | + HttpServerResponse.redirect("/", { | |
| 98 | + status: 302, | |
| 99 | + headers: { | |
| 100 | + "Set-Cookie": [ | |
| 101 | + clearSessionCookie(), | |
| 102 | + "executor_team=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0", | |
| 103 | + ].join(", "), | |
| 104 | + }, | |
| 105 | + }), | |
| 106 | + ), | |
| 107 | + ), | |
| 34 | 108 | ); |
| @@ -1,119 +1,108 @@ | ||
| 1 | 1 | // --------------------------------------------------------------------------- |
| 2 | −// WorkOS AuthKit integration — sealed sessions, no server-side session store | |
| 2 | +// WorkOS AuthKit — Effect-native sealed session management | |
| 3 | 3 | // --------------------------------------------------------------------------- |
| 4 | 4 | |
| 5 | +import { Context, Effect, Layer } from "effect"; | |
| 5 | 6 | import { WorkOS } from "@workos-inc/node"; |
| 7 | +import { WorkOSError } from "./context"; | |
| 6 | 8 | |
| 7 | 9 | const COOKIE_NAME = "wos-session"; |
| 8 | 10 | |
| 9 | −let workos: WorkOS | null = null; | |
| 10 | − | |
| 11 | −export const getWorkOS = (): WorkOS => { | |
| 12 | − if (!workos) { | |
| 13 | − workos = new WorkOS(process.env.WORKOS_API_KEY!); | |
| 14 | − } | |
| 15 | − return workos; | |
| 16 | −}; | |
| 17 | − | |
| 18 | −const getCookiePassword = (): string => { | |
| 19 | − const password = process.env.WORKOS_COOKIE_PASSWORD; | |
| 20 | − if (!password || password.length < 32) { | |
| 21 | − throw new Error("WORKOS_COOKIE_PASSWORD must be at least 32 characters"); | |
| 22 | − } | |
| 23 | − return password; | |
| 24 | −}; | |
| 25 | − | |
| 26 | −export const getAuthorizationUrl = (redirectUri: string): string => { | |
| 27 | − const wos = getWorkOS(); | |
| 28 | − return wos.userManagement.getAuthorizationUrl({ | |
| 29 | − provider: "authkit", | |
| 30 | − redirectUri, | |
| 31 | − clientId: process.env.WORKOS_CLIENT_ID!, | |
| 32 | − }); | |
| 33 | −}; | |
| 11 | +// --------------------------------------------------------------------------- | |
| 12 | +// Service | |
| 13 | +// --------------------------------------------------------------------------- | |
| 34 | 14 | |
| 35 | −export const authenticateWithCode = async (code: string) => { | |
| 36 | − const wos = getWorkOS(); | |
| 37 | − return wos.userManagement.authenticateWithCode({ | |
| 38 | − code, | |
| 39 | − clientId: process.env.WORKOS_CLIENT_ID!, | |
| 40 | − session: { | |
| 41 | − sealSession: true, | |
| 42 | − cookiePassword: getCookiePassword(), | |
| 43 | − }, | |
| 44 | − }); | |
| 45 | −}; | |
| 46 | 15 | |
| 47 | −/** | |
| 48 | − * Authenticate a request using the sealed session cookie. | |
| 49 | − * Returns user info or null if not authenticated. | |
| 50 | − */ | |
| 51 | −/** | |
| 52 | − * Authenticate a request using the sealed session cookie. | |
| 53 | − * Automatically refreshes expired tokens and returns a new cookie if needed. | |
| 54 | − */ | |
| 55 | −export const authenticateRequest = async (request: Request) => { | |
| 56 | − const cookieHeader = request.headers.get("cookie"); | |
| 57 | − const sessionData = parseCookie(cookieHeader, COOKIE_NAME); | |
| 58 | − if (!sessionData) return null; | |
| 59 | − | |
| 60 | − const wos = getWorkOS(); | |
| 61 | − const session = wos.userManagement.loadSealedSession({ | |
| 62 | − sessionData, | |
| 63 | − cookiePassword: getCookiePassword(), | |
| 64 | − }); | |
| 65 | − | |
| 66 | − const result = await session.authenticate(); | |
| 67 | − | |
| 68 | − if (result.authenticated) { | |
| 69 | − return { | |
| 70 | − userId: result.user.id, | |
| 71 | − email: result.user.email, | |
| 72 | − firstName: result.user.firstName, | |
| 73 | − lastName: result.user.lastName, | |
| 74 | − avatarUrl: result.user.profilePictureUrl, | |
| 75 | − sessionId: result.sessionId, | |
| 76 | − refreshedCookie: undefined as string | undefined, | |
| 77 | − }; | |
| 78 | − } | |
| 16 | +const make = Effect.gen(function* () { | |
| 17 | + const apiKey = process.env.WORKOS_API_KEY!; | |
| 18 | + const clientId = process.env.WORKOS_CLIENT_ID!; | |
| 19 | + const cookiePassword = process.env.WORKOS_COOKIE_PASSWORD!; | |
| 79 | 20 | |
| 80 | − // Token expired — try refreshing | |
| 81 | − if (result.reason === "no_session_cookie_provided") return null; | |
| 82 | − | |
| 83 | − try { | |
| 84 | − const refreshed = await session.refresh(); | |
| 85 | − if (!refreshed.authenticated || !refreshed.sealedSession) return null; | |
| 86 | − | |
| 87 | − return { | |
| 88 | − userId: refreshed.user.id, | |
| 89 | − email: refreshed.user.email, | |
| 90 | − firstName: refreshed.user.firstName, | |
| 91 | − lastName: refreshed.user.lastName, | |
| 92 | − avatarUrl: refreshed.user.profilePictureUrl, | |
| 93 | − sessionId: refreshed.sessionId, | |
| 94 | − refreshedCookie: makeSessionCookie(refreshed.sealedSession), | |
| 95 | − }; | |
| 96 | − } catch { | |
| 97 | − return null; | |
| 21 | + if (!cookiePassword || cookiePassword.length < 32) { | |
| 22 | + return yield* Effect.die(new Error("WORKOS_COOKIE_PASSWORD must be at least 32 characters")); | |
| 98 | 23 | } |
| 99 | −}; | |
| 100 | 24 | |
| 101 | −/** | |
| 102 | − * Get logout URL for the current session. | |
| 103 | − */ | |
| 104 | −export const getLogoutUrl = async (request: Request) => { | |
| 105 | − const cookieHeader = request.headers.get("cookie"); | |
| 106 | − const sessionData = parseCookie(cookieHeader, COOKIE_NAME); | |
| 107 | − if (!sessionData) return null; | |
| 108 | − | |
| 109 | − const wos = getWorkOS(); | |
| 110 | − const session = wos.userManagement.loadSealedSession({ | |
| 111 | − sessionData, | |
| 112 | − cookiePassword: getCookiePassword(), | |
| 113 | − }); | |
| 114 | − | |
| 115 | − return session.getLogoutUrl(); | |
| 116 | −}; | |
| 25 | + const workos = new WorkOS(apiKey, { clientId }); | |
| 26 | + | |
| 27 | + const use = <A>(fn: (wos: WorkOS) => Promise<A>) => | |
| 28 | + Effect.tryPromise({ | |
| 29 | + try: () => fn(workos), | |
| 30 | + catch: (cause) => new WorkOSError({ cause }), | |
| 31 | + }).pipe(Effect.withSpan("workos")); | |
| 32 | + | |
| 33 | + return { | |
| 34 | + getAuthorizationUrl: (redirectUri: string) => | |
| 35 | + workos.userManagement.getAuthorizationUrl({ | |
| 36 | + provider: "authkit", | |
| 37 | + redirectUri, | |
| 38 | + clientId, | |
| 39 | + }), | |
| 40 | + | |
| 41 | + authenticateWithCode: (code: string) => | |
| 42 | + use((wos) => | |
| 43 | + wos.userManagement.authenticateWithCode({ | |
| 44 | + code, | |
| 45 | + clientId, | |
| 46 | + session: { sealSession: true, cookiePassword }, | |
| 47 | + }), | |
| 48 | + ), | |
| 49 | + | |
| 50 | + authenticateRequest: (request: Request) => | |
| 51 | + Effect.gen(function* () { | |
| 52 | + const sessionData = parseCookie(request.headers.get("cookie"), COOKIE_NAME); | |
| 53 | + if (!sessionData) return null; | |
| 54 | + | |
| 55 | + const session = workos.userManagement.loadSealedSession({ | |
| 56 | + sessionData, | |
| 57 | + cookiePassword, | |
| 58 | + }); | |
| 59 | + | |
| 60 | + const result = yield* use((wos) => session.authenticate()); | |
| 61 | + | |
| 62 | + if (result.authenticated) { | |
| 63 | + return { | |
| 64 | + userId: result.user.id, | |
| 65 | + email: result.user.email, | |
| 66 | + firstName: result.user.firstName, | |
| 67 | + lastName: result.user.lastName, | |
| 68 | + avatarUrl: result.user.profilePictureUrl, | |
| 69 | + sessionId: result.sessionId, | |
| 70 | + refreshedCookie: undefined as string | undefined, | |
| 71 | + }; | |
| 72 | + } | |
| 73 | + | |
| 74 | + if (result.reason === "no_session_cookie_provided") return null; | |
| 75 | + | |
| 76 | + // Try refreshing | |
| 77 | + const refreshed = yield* use((wos) => session.refresh()).pipe( | |
| 78 | + Effect.orElseSucceed(() => ({ authenticated: false as const })), | |
| 79 | + ); | |
| 80 | + | |
| 81 | + if (!refreshed.authenticated || !("sealedSession" in refreshed) || !refreshed.sealedSession) return null; | |
| 82 | + | |
| 83 | + return { | |
| 84 | + userId: refreshed.user.id, | |
| 85 | + email: refreshed.user.email, | |
| 86 | + firstName: refreshed.user.firstName, | |
| 87 | + lastName: refreshed.user.lastName, | |
| 88 | + avatarUrl: refreshed.user.profilePictureUrl, | |
| 89 | + sessionId: refreshed.sessionId, | |
| 90 | + refreshedCookie: makeSessionCookie(refreshed.sealedSession), | |
| 91 | + }; | |
| 92 | + }), | |
| 93 | + }; | |
| 94 | +}); | |
| 95 | + | |
| 96 | +type WorkOSAuthService = Effect.Effect.Success<typeof make>; | |
| 97 | + | |
| 98 | +export class WorkOSAuth extends Context.Tag("@executor/cloud/WorkOSAuth")< | |
| 99 | + WorkOSAuth, | |
| 100 | + WorkOSAuthService | |
| 101 | +>() { | |
| 102 | + static Default = Layer.effect(this, make).pipe( | |
| 103 | + Layer.annotateSpans({ module: "WorkOSAuth" }), | |
| 104 | + ); | |
| 105 | +} | |
| 117 | 106 | |
| 118 | 107 | // --------------------------------------------------------------------------- |
| 119 | 108 | // Cookie helpers |
| @@ -125,7 +114,7 @@ export const makeSessionCookie = (sealedSession: string): string => { · 5 unmodified lines | ||
| 125 | 114 | "Path=/", |
| 126 | 115 | "HttpOnly", |
| 127 | 116 | "SameSite=Lax", |
| 128 | − "Max-Age=604800", // 7 days | |
| 117 | + "Max-Age=604800", | |
| 129 | 118 | ]; |
| 130 | 119 | if (process.env.NODE_ENV === "production") parts.push("Secure"); |
| 131 | 120 | return parts.join("; "); |
| @@ -1,143 +0,0 @@ | ||
| 1 | −// --------------------------------------------------------------------------- | |
| 2 | −// Auth handlers — login, callback, logout, me | |
| 3 | −// --------------------------------------------------------------------------- | |
| 4 | − | |
| 5 | −import { makeUserStore } from "@executor/storage-postgres"; | |
| 6 | −import { | |
| 7 | − getAuthorizationUrl, | |
| 8 | − authenticateWithCode, | |
| 9 | − authenticateRequest, | |
| 10 | − getLogoutUrl, | |
| 11 | − makeSessionCookie, | |
| 12 | − clearSessionCookie, | |
| 13 | −} from "../auth/workos"; | |
| 14 | −import type { DrizzleDb } from "../services/db"; | |
| 15 | − | |
| 16 | −export const createAuthHandlers = (db: DrizzleDb) => { | |
| 17 | − const userStore = makeUserStore(db); | |
| 18 | − | |
| 19 | − const getBaseUrl = (): string => { | |
| 20 | − if (process.env.APP_URL) return process.env.APP_URL; | |
| 21 | − const port = process.env.PORT ?? "3000"; | |
| 22 | − return `http://localhost:${port}`; | |
| 23 | − }; | |
| 24 | − | |
| 25 | − return { | |
| 26 | − login: async (_request: Request): Promise<Response> => { | |
| 27 | − const redirectUri = `${getBaseUrl()}/auth/callback`; | |
| 28 | − const url = getAuthorizationUrl(redirectUri); | |
| 29 | − return Response.redirect(url, 302); | |
| 30 | − }, | |
| 31 | − | |
| 32 | − callback: async (request: Request): Promise<Response> => { | |
| 33 | − const url = new URL(request.url); | |
| 34 | − const code = url.searchParams.get("code"); | |
| 35 | − if (!code) { | |
| 36 | − return new Response("Missing code parameter", { status: 400 }); | |
| 37 | − } | |
| 38 | − | |
| 39 | − try { | |
| 40 | − const result = await authenticateWithCode(code); | |
| 41 | − const workosUser = result.user; | |
| 42 | − | |
| 43 | − // Upsert user | |
| 44 | − const user = await userStore.upsertUser({ | |
| 45 | − id: workosUser.id, | |
| 46 | − email: workosUser.email, | |
| 47 | − name: `${workosUser.firstName ?? ""} ${workosUser.lastName ?? ""}`.trim() || undefined, | |
| 48 | − avatarUrl: workosUser.profilePictureUrl ?? undefined, | |
| 49 | − }); | |
| 50 | − | |
| 51 | − // Check for pending invitations | |
| 52 | − const pendingInvitations = await userStore.getPendingInvitations(user.email); | |
| 53 | − let teamId: string; | |
| 54 | − | |
| 55 | − if (pendingInvitations.length > 0) { | |
| 56 | − const invitation = pendingInvitations[0]!; | |
| 57 | − await userStore.acceptInvitation(invitation.id); | |
| 58 | − await userStore.addMember(invitation.teamId, user.id, "member"); | |
| 59 | − teamId = invitation.teamId; | |
| 60 | − } else { | |
| 61 | − const teams = await userStore.getTeamsForUser(user.id); | |
| 62 | − if (teams.length > 0) { | |
| 63 | − teamId = teams[0]!.teamId; | |
| 64 | − } else { | |
| 65 | − const team = await userStore.createTeam(`${user.name ?? user.email}'s Team`); | |
| 66 | − await userStore.addMember(team.id, user.id, "owner"); | |
| 67 | − teamId = team.id; | |
| 68 | − } | |
| 69 | − } | |
| 70 | − | |
| 71 | − // Store teamId in a separate cookie (WorkOS sealed session doesn't carry app-specific data) | |
| 72 | − const sealedSession = result.sealedSession; | |
| 73 | − if (!sealedSession) { | |
| 74 | − return new Response("Failed to create session", { status: 500 }); | |
| 75 | − } | |
| 76 | − | |
| 77 | − return new Response(null, { | |
| 78 | − status: 302, | |
| 79 | − headers: [ | |
| 80 | − ["Location", "/"], | |
| 81 | − ["Set-Cookie", makeSessionCookie(sealedSession)], | |
| 82 | − ["Set-Cookie", `executor_team=${teamId}; Path=/; HttpOnly; SameSite=Lax; Max-Age=604800`], | |
| 83 | − ], | |
| 84 | − }); | |
| 85 | − } catch (error) { | |
| 86 | − console.error("Auth callback error:", error); | |
| 87 | − return new Response("Authentication failed", { status: 500 }); | |
| 88 | − } | |
| 89 | − }, | |
| 90 | − | |
| 91 | − logout: async (request: Request): Promise<Response> => { | |
| 92 | − const logoutUrl = await getLogoutUrl(request); | |
| 93 | − const headers: [string, string][] = [ | |
| 94 | − ["Set-Cookie", clearSessionCookie()], | |
| 95 | − ["Set-Cookie", "executor_team=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0"], | |
| 96 | − ]; | |
| 97 | − | |
| 98 | − if (logoutUrl) { | |
| 99 | − headers.push(["Location", logoutUrl]); | |
| 100 | − return new Response(null, { status: 302, headers }); | |
| 101 | − } | |
| 102 | − | |
| 103 | − headers.push(["Location", "/login"]); | |
| 104 | − return new Response(null, { status: 302, headers }); | |
| 105 | − }, | |
| 106 | − | |
| 107 | − me: async (request: Request): Promise<Response> => { | |
| 108 | − const auth = await authenticateRequest(request); | |
| 109 | − if (!auth) { | |
| 110 | − return Response.json({ error: "Not authenticated" }, { status: 401 }); | |
| 111 | − } | |
| 112 | − | |
| 113 | − const user = await userStore.getUser(auth.userId); | |
| 114 | − if (!user) { | |
| 115 | − return Response.json({ error: "User not found" }, { status: 401 }); | |
| 116 | − } | |
| 117 | − | |
| 118 | − // Read teamId from cookie | |
| 119 | − const teamId = parseCookie(request.headers.get("cookie"), "executor_team"); | |
| 120 | − const team = teamId ? await userStore.getTeam(teamId) : null; | |
| 121 | − | |
| 122 | − return Response.json({ | |
| 123 | − user: { | |
| 124 | − id: user.id, | |
| 125 | − email: user.email, | |
| 126 | − name: user.name, | |
| 127 | − avatarUrl: user.avatarUrl, | |
| 128 | − }, | |
| 129 | − team: team ? { id: team.id, name: team.name } : null, | |
| 130 | − }); | |
| 131 | − }, | |
| 132 | − }; | |
| 133 | −}; | |
| 134 | − | |
| 135 | −const parseCookie = (cookieHeader: string | null, name: string): string | null => { | |
| 136 | − if (!cookieHeader) return null; | |
| 137 | − const match = cookieHeader | |
| 138 | − .split(";") | |
| 139 | − .map((c) => c.trim()) | |
| 140 | − .find((c) => c.startsWith(`${name}=`)); | |
| 141 | − if (!match) return null; | |
| 142 | − return match.slice(name.length + 1) || null; | |
| 143 | −}; | |
| @@ -1,81 +0,0 @@ | ||
| 1 | −// --------------------------------------------------------------------------- | |
| 2 | −// Team handlers — members, invitations | |
| 3 | −// --------------------------------------------------------------------------- | |
| 4 | − | |
| 5 | −import { makeUserStore } from "@executor/storage-postgres"; | |
| 6 | −import { authenticateRequest } from "../auth/workos"; | |
| 7 | −import type { DrizzleDb } from "../services/db"; | |
| 8 | − | |
| 9 | −const parseCookie = (cookieHeader: string | null, name: string): string | null => { | |
| 10 | − if (!cookieHeader) return null; | |
| 11 | − const match = cookieHeader | |
| 12 | − .split(";") | |
| 13 | − .map((c) => c.trim()) | |
| 14 | − .find((c) => c.startsWith(`${name}=`)); | |
| 15 | − if (!match) return null; | |
| 16 | − return match.slice(name.length + 1) || null; | |
| 17 | −}; | |
| 18 | − | |
| 19 | −export const createTeamHandlers = (db: DrizzleDb) => { | |
| 20 | − const userStore = makeUserStore(db); | |
| 21 | − | |
| 22 | − const requireAuth = async (request: Request) => { | |
| 23 | − const auth = await authenticateRequest(request); | |
| 24 | − if (!auth) return null; | |
| 25 | − const teamId = parseCookie(request.headers.get("cookie"), "executor_team"); | |
| 26 | − if (!teamId) return null; | |
| 27 | − return { ...auth, teamId }; | |
| 28 | − }; | |
| 29 | − | |
| 30 | − return { | |
| 31 | − listMembers: async (request: Request): Promise<Response> => { | |
| 32 | − const auth = await requireAuth(request); | |
| 33 | − if (!auth) return Response.json({ error: "Unauthorized" }, { status: 401 }); | |
| 34 | − | |
| 35 | − const members = await userStore.listMembers(auth.teamId); | |
| 36 | − return Response.json({ members }); | |
| 37 | − }, | |
| 38 | − | |
| 39 | − invite: async (request: Request): Promise<Response> => { | |
| 40 | − const auth = await requireAuth(request); | |
| 41 | − if (!auth) return Response.json({ error: "Unauthorized" }, { status: 401 }); | |
| 42 | − | |
| 43 | − const body = await request.json() as { email: string }; | |
| 44 | − if (!body.email) { | |
| 45 | − return Response.json({ error: "Email required" }, { status: 400 }); | |
| 46 | − } | |
| 47 | − | |
| 48 | − const invitation = await userStore.createInvitation( | |
| 49 | − auth.teamId, | |
| 50 | − body.email, | |
| 51 | − auth.userId, | |
| 52 | − ); | |
| 53 | − return Response.json({ invitation }); | |
| 54 | − }, | |
| 55 | − | |
| 56 | − listInvitations: async (request: Request): Promise<Response> => { | |
| 57 | − const auth = await requireAuth(request); | |
| 58 | − if (!auth) return Response.json({ error: "Unauthorized" }, { status: 401 }); | |
| 59 | − | |
| 60 | − const invitations = await userStore.getTeamInvitations(auth.teamId); | |
| 61 | − return Response.json({ invitations }); | |
| 62 | − }, | |
| 63 | − | |
| 64 | − removeMember: async (request: Request): Promise<Response> => { | |
| 65 | − const auth = await requireAuth(request); | |
| 66 | − if (!auth) return Response.json({ error: "Unauthorized" }, { status: 401 }); | |
| 67 | − | |
| 68 | − const body = await request.json() as { userId: string }; | |
| 69 | − if (!body.userId) { | |
| 70 | − return Response.json({ error: "userId required" }, { status: 400 }); | |
| 71 | − } | |
| 72 | − | |
| 73 | − if (body.userId === auth.userId) { | |
| 74 | − return Response.json({ error: "Cannot remove yourself" }, { status: 400 }); | |
| 75 | − } | |
| 76 | − | |
| 77 | − await userStore.removeMember(auth.teamId, body.userId); | |
| 78 | − return Response.json({ removed: true }); | |
| 79 | − }, | |
| 80 | − }; | |
| 81 | −}; | |
| @@ -1,99 +0,0 @@ | ||
| 1 | −// --------------------------------------------------------------------------- | |
| 2 | −// Executor Cloud — main entry point | |
| 3 | −// | |
| 4 | −// Single Bun.serve() routing: | |
| 5 | −// /auth/* → Auth handlers (login, callback, logout, me) | |
| 6 | −// /api/team/* → Team handlers (members, invitations) | |
| 7 | −// /v1/* → Effect HTTP API (tools, sources, secrets, executions) | |
| 8 | −// /docs → OpenAPI docs | |
| 9 | −// /* → Static frontend (SPA) | |
| 10 | −// --------------------------------------------------------------------------- | |
| 11 | − | |
| 12 | −import { resolve } from "node:path"; | |
| 13 | −import { getDb } from "./services/db"; | |
| 14 | −import { createAuthHandlers } from "./handlers/auth"; | |
| 15 | −import { createTeamHandlers } from "./handlers/teams"; | |
| 16 | −import { createCloudApiHandler } from "./api"; | |
| 17 | − | |
| 18 | −const PORT = parseInt(process.env.PORT ?? "3000", 10); | |
| 19 | −const ENCRYPTION_KEY = process.env.ENCRYPTION_KEY ?? "local-dev-encryption-key"; | |
| 20 | − | |
| 21 | −// --------------------------------------------------------------------------- | |
| 22 | −// Initialize services | |
| 23 | −// --------------------------------------------------------------------------- | |
| 24 | − | |
| 25 | −const db = await getDb(); | |
| 26 | −const authHandlers = createAuthHandlers(db); | |
| 27 | −const teamHandlers = createTeamHandlers(db); | |
| 28 | −const apiHandler = createCloudApiHandler(db, ENCRYPTION_KEY); | |
| 29 | − | |
| 30 | −// --------------------------------------------------------------------------- | |
| 31 | −// Static file serving (frontend) | |
| 32 | −// --------------------------------------------------------------------------- | |
| 33 | − | |
| 34 | −const WEB_DIST_DIR = resolve(import.meta.dirname, "../dist"); | |
| 35 | − | |
| 36 | −const serveStatic = async (pathname: string): Promise<Response | null> => { | |
| 37 | − const key = pathname.replace(/^\//, ""); | |
| 38 | − const filePath = resolve(WEB_DIST_DIR, key); | |
| 39 | − if (!filePath.startsWith(WEB_DIST_DIR)) return null; | |
| 40 | − | |
| 41 | − const file = Bun.file(filePath); | |
| 42 | − if (await file.exists()) { | |
| 43 | − return new Response(file, { | |
| 44 | − headers: { "content-type": file.type || "application/octet-stream" }, | |
| 45 | − }); | |
| 46 | − } | |
| 47 | − | |
| 48 | − // SPA fallback | |
| 49 | − const index = Bun.file(resolve(WEB_DIST_DIR, "index.html")); | |
| 50 | − if (await index.exists()) { | |
| 51 | − return new Response(index, { headers: { "content-type": "text/html" } }); | |
| 52 | − } | |
| 53 | − | |
| 54 | − return null; | |
| 55 | −}; | |
| 56 | − | |
| 57 | −// --------------------------------------------------------------------------- | |
| 58 | −// Main server | |
| 59 | −// --------------------------------------------------------------------------- | |
| 60 | − | |
| 61 | −const server = Bun.serve({ | |
| 62 | − port: PORT, | |
| 63 | − fetch: async (request: Request): Promise<Response> => { | |
| 64 | − const url = new URL(request.url); | |
| 65 | − | |
| 66 | − // --- Auth routes (public) --- | |
| 67 | − if (url.pathname === "/auth/login") return authHandlers.login(request); | |
| 68 | − if (url.pathname === "/auth/callback") return authHandlers.callback(request); | |
| 69 | − if (url.pathname === "/auth/logout") return authHandlers.logout(request); | |
| 70 | − if (url.pathname === "/auth/me") return authHandlers.me(request); | |
| 71 | − | |
| 72 | − // --- Team routes (authenticated) --- | |
| 73 | − if (url.pathname === "/api/team/members" && request.method === "GET") | |
| 74 | − return teamHandlers.listMembers(request); | |
| 75 | − if (url.pathname === "/api/team/members" && request.method === "DELETE") | |
| 76 | − return teamHandlers.removeMember(request); | |
| 77 | − if (url.pathname === "/api/team/invite" && request.method === "POST") | |
| 78 | − return teamHandlers.invite(request); | |
| 79 | − if (url.pathname === "/api/team/invitations" && request.method === "GET") | |
| 80 | − return teamHandlers.listInvitations(request); | |
| 81 | − | |
| 82 | − // --- Effect HTTP API (authenticated) --- | |
| 83 | − if ( | |
| 84 | − url.pathname.startsWith("/v1/") || | |
| 85 | − url.pathname.startsWith("/docs") || | |
| 86 | − url.pathname === "/openapi.json" | |
| 87 | − ) { | |
| 88 | − return apiHandler(request); | |
| 89 | − } | |
| 90 | − | |
| 91 | − // --- Static frontend --- | |
| 92 | − const staticResponse = await serveStatic(url.pathname); | |
| 93 | − if (staticResponse) return staticResponse; | |
| 94 | − | |
| 95 | − return new Response("Not Found", { status: 404 }); | |
| 96 | − }, | |
| 97 | −}); | |
| 98 | − | |
| 99 | −console.log(`Executor Cloud running on http://localhost:${server.port}`); | |
| @@ -0,0 +1,198 @@ | ||
| 1 | +/* eslint-disable */ | |
| 2 | + | |
| 3 | +// @ts-nocheck | |
| 4 | + | |
| 5 | +// noinspection JSUnusedGlobalSymbols | |
| 6 | + | |
| 7 | +// This file was automatically generated by TanStack Router. | |
| 8 | +// You should NOT make any changes in this file as it will be overwritten. | |
| 9 | +// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. | |
| 10 | + | |
| 11 | +import { Route as rootRouteImport } from './routes/__root' | |
| 12 | +import { Route as ToolsRouteImport } from './routes/tools' | |
| 13 | +import { Route as SecretsRouteImport } from './routes/secrets' | |
| 14 | +import { Route as IndexRouteImport } from './routes/index' | |
| 15 | +import { Route as V1SplatRouteImport } from './routes/v1.$' | |
| 16 | +import { Route as SourcesNamespaceRouteImport } from './routes/sources.$namespace' | |
| 17 | +import { Route as AuthSplatRouteImport } from './routes/auth.$' | |
| 18 | +import { Route as SourcesAddPluginKeyRouteImport } from './routes/sources.add.$pluginKey' | |
| 19 | + | |
| 20 | +const ToolsRoute = ToolsRouteImport.update({ | |
| 21 | + id: '/tools', | |
| 22 | + path: '/tools', | |
| 23 | + getParentRoute: () => rootRouteImport, | |
| 24 | +} as any) | |
| 25 | +const SecretsRoute = SecretsRouteImport.update({ | |
| 26 | + id: '/secrets', | |
| 27 | + path: '/secrets', | |
| 28 | + getParentRoute: () => rootRouteImport, | |
| 29 | +} as any) | |
| 30 | +const IndexRoute = IndexRouteImport.update({ | |
| 31 | + id: '/', | |
| 32 | + path: '/', | |
| 33 | + getParentRoute: () => rootRouteImport, | |
| 34 | +} as any) | |
| 35 | +const V1SplatRoute = V1SplatRouteImport.update({ | |
| 36 | + id: '/v1/$', | |
| 37 | + path: '/v1/$', | |
| 38 | + getParentRoute: () => rootRouteImport, | |
| 39 | +} as any) | |
| 40 | +const SourcesNamespaceRoute = SourcesNamespaceRouteImport.update({ | |
| 41 | + id: '/sources/$namespace', | |
| 42 | + path: '/sources/$namespace', | |
| 43 | + getParentRoute: () => rootRouteImport, | |
| 44 | +} as any) | |
| 45 | +const AuthSplatRoute = AuthSplatRouteImport.update({ | |
| 46 | + id: '/auth/$', | |
| 47 | + path: '/auth/$', | |
| 48 | + getParentRoute: () => rootRouteImport, | |
| 49 | +} as any) | |
| 50 | +const SourcesAddPluginKeyRoute = SourcesAddPluginKeyRouteImport.update({ | |
| 51 | + id: '/sources/add/$pluginKey', | |
| 52 | + path: '/sources/add/$pluginKey', | |
| 53 | + getParentRoute: () => rootRouteImport, | |
| 54 | +} as any) | |
| 55 | + | |
| 56 | +export interface FileRoutesByFullPath { | |
| 57 | + '/': typeof IndexRoute | |
| 58 | + '/secrets': typeof SecretsRoute | |
| 59 | + '/tools': typeof ToolsRoute | |
| 60 | + '/auth/$': typeof AuthSplatRoute | |
| 61 | + '/sources/$namespace': typeof SourcesNamespaceRoute | |
| 62 | + '/v1/$': typeof V1SplatRoute | |
| 63 | + '/sources/add/$pluginKey': typeof SourcesAddPluginKeyRoute | |
| 64 | +} | |
| 65 | +export interface FileRoutesByTo { | |
| 66 | + '/': typeof IndexRoute | |
| 67 | + '/secrets': typeof SecretsRoute | |
| 68 | + '/tools': typeof ToolsRoute | |
| 69 | + '/auth/$': typeof AuthSplatRoute | |
| 70 | + '/sources/$namespace': typeof SourcesNamespaceRoute | |
| 71 | + '/v1/$': typeof V1SplatRoute | |
| 72 | + '/sources/add/$pluginKey': typeof SourcesAddPluginKeyRoute | |
| 73 | +} | |
| 74 | +export interface FileRoutesById { | |
| 75 | + __root__: typeof rootRouteImport | |
| 76 | + '/': typeof IndexRoute | |
| 77 | + '/secrets': typeof SecretsRoute | |
| 78 | + '/tools': typeof ToolsRoute | |
| 79 | + '/auth/$': typeof AuthSplatRoute | |
| 80 | + '/sources/$namespace': typeof SourcesNamespaceRoute | |
| 81 | + '/v1/$': typeof V1SplatRoute | |
| 82 | + '/sources/add/$pluginKey': typeof SourcesAddPluginKeyRoute | |
| 83 | +} | |
| 84 | +export interface FileRouteTypes { | |
| 85 | + fileRoutesByFullPath: FileRoutesByFullPath | |
| 86 | + fullPaths: | |
| 87 | + | '/' | |
| 88 | + | '/secrets' | |
| 89 | + | '/tools' | |
| 90 | + | '/auth/$' | |
| 91 | + | '/sources/$namespace' | |
| 92 | + | '/v1/$' | |
| 93 | + | '/sources/add/$pluginKey' | |
| 94 | + fileRoutesByTo: FileRoutesByTo | |
| 95 | + to: | |
| 96 | + | '/' | |
| 97 | + | '/secrets' | |
| 98 | + | '/tools' | |
| 99 | + | '/auth/$' | |
| 100 | + | '/sources/$namespace' | |
| 101 | + | '/v1/$' | |
| 102 | + | '/sources/add/$pluginKey' | |
| 103 | + id: | |
| 104 | + | '__root__' | |
| 105 | + | '/' | |
| 106 | + | '/secrets' | |
| 107 | + | '/tools' | |
| 108 | + | '/auth/$' | |
| 109 | + | '/sources/$namespace' | |
| 110 | + | '/v1/$' | |
| 111 | + | '/sources/add/$pluginKey' | |
| 112 | + fileRoutesById: FileRoutesById | |
| 113 | +} | |
| 114 | +export interface RootRouteChildren { | |
| 115 | + IndexRoute: typeof IndexRoute | |
| 116 | + SecretsRoute: typeof SecretsRoute | |
| 117 | + ToolsRoute: typeof ToolsRoute | |
| 118 | + AuthSplatRoute: typeof AuthSplatRoute | |
| 119 | + SourcesNamespaceRoute: typeof SourcesNamespaceRoute | |
| 120 | + V1SplatRoute: typeof V1SplatRoute | |
| 121 | + SourcesAddPluginKeyRoute: typeof SourcesAddPluginKeyRoute | |
| 122 | +} | |
| 123 | + | |
| 124 | +declare module '@tanstack/react-router' { | |
| 125 | + interface FileRoutesByPath { | |
| 126 | + '/tools': { | |
| 127 | + id: '/tools' | |
| 128 | + path: '/tools' | |
| 129 | + fullPath: '/tools' | |
| 130 | + preLoaderRoute: typeof ToolsRouteImport | |
| 131 | + parentRoute: typeof rootRouteImport | |
| 132 | + } | |
| 133 | + '/secrets': { | |
| 134 | + id: '/secrets' | |
| 135 | + path: '/secrets' | |
| 136 | + fullPath: '/secrets' | |
| 137 | + preLoaderRoute: typeof SecretsRouteImport | |
| 138 | + parentRoute: typeof rootRouteImport | |
| 139 | + } | |
| 140 | + '/': { | |
| 141 | + id: '/' | |
| 142 | + path: '/' | |
| 143 | + fullPath: '/' | |
| 144 | + preLoaderRoute: typeof IndexRouteImport | |
| 145 | + parentRoute: typeof rootRouteImport | |
| 146 | + } | |
| 147 | + '/v1/$': { | |
| 148 | + id: '/v1/$' | |
| 149 | + path: '/v1/$' | |
| 150 | + fullPath: '/v1/$' | |
| 151 | + preLoaderRoute: typeof V1SplatRouteImport | |
| 152 | + parentRoute: typeof rootRouteImport | |
| 153 | + } | |
| 154 | + '/sources/$namespace': { | |
| 155 | + id: '/sources/$namespace' | |
| 156 | + path: '/sources/$namespace' | |
| 157 | + fullPath: '/sources/$namespace' | |
| 158 | + preLoaderRoute: typeof SourcesNamespaceRouteImport | |
| 159 | + parentRoute: typeof rootRouteImport | |
| 160 | + } | |
| 161 | + '/auth/$': { | |
| 162 | + id: '/auth/$' | |
| 163 | + path: '/auth/$' | |
| 164 | + fullPath: '/auth/$' | |
| 165 | + preLoaderRoute: typeof AuthSplatRouteImport | |
| 166 | + parentRoute: typeof rootRouteImport | |
| 167 | + } | |
| 168 | + '/sources/add/$pluginKey': { | |
| 169 | + id: '/sources/add/$pluginKey' | |
| 170 | + path: '/sources/add/$pluginKey' | |
| 171 | + fullPath: '/sources/add/$pluginKey' | |
| 172 | + preLoaderRoute: typeof SourcesAddPluginKeyRouteImport | |
| 173 | + parentRoute: typeof rootRouteImport | |
| 174 | + } | |
| 175 | + } | |
| 176 | +} | |
| 177 | + | |
| 178 | +const rootRouteChildren: RootRouteChildren = { | |
| 179 | + IndexRoute: IndexRoute, | |
| 180 | + SecretsRoute: SecretsRoute, | |
| 181 | + ToolsRoute: ToolsRoute, | |
| 182 | + AuthSplatRoute: AuthSplatRoute, | |
| 183 | + SourcesNamespaceRoute: SourcesNamespaceRoute, | |
| 184 | + V1SplatRoute: V1SplatRoute, | |
| 185 | + SourcesAddPluginKeyRoute: SourcesAddPluginKeyRoute, | |
| 186 | +} | |
| 187 | +export const routeTree = rootRouteImport | |
| 188 | + ._addFileChildren(rootRouteChildren) | |
| 189 | + ._addFileTypes<FileRouteTypes>() | |
| 190 | + | |
| 191 | +import type { getRouter } from './router.tsx' | |
| 192 | +import type { createStart } from '@tanstack/react-start' | |
| 193 | +declare module '@tanstack/react-start' { | |
| 194 | + interface Register { | |
| 195 | + ssr: true | |
| 196 | + router: Awaited<ReturnType<typeof getRouter>> | |
| 197 | + } | |
| 198 | +} | |
| @@ -0,0 +1,10 @@ | ||
| 1 | +import { createRouter } from "@tanstack/react-router"; | |
| 2 | +import { routeTree } from "./routeTree.gen"; | |
| 3 | + | |
| 4 | +export const getRouter = () => { | |
| 5 | + return createRouter({ | |
| 6 | + routeTree, | |
| 7 | + scrollRestoration: true, | |
| 8 | + defaultPreloadStaleTime: 0, | |
| 9 | + }); | |
| 10 | +}; | |
| @@ -0,0 +1,69 @@ | ||
| 1 | +import React from "react"; | |
| 2 | +import { HeadContent, Outlet, Scripts, createRootRoute } from "@tanstack/react-router"; | |
| 3 | +import { ExecutorProvider } from "@executor/react/api/provider"; | |
| 4 | +import { AuthProvider, useAuth } from "../web/auth"; | |
| 5 | +import { LoginPage } from "../web/pages/login"; | |
| 6 | +import { Shell } from "../web/shell"; | |
| 7 | +import appCss from "@executor/react/globals.css?url"; | |
| 8 | + | |
| 9 | +export const Route = createRootRoute({ | |
| 10 | + head: () => ({ | |
| 11 | + meta: [ | |
| 12 | + { charSet: "utf-8" }, | |
| 13 | + { name: "viewport", content: "width=device-width, initial-scale=1" }, | |
| 14 | + { title: "Executor Cloud" }, | |
| 15 | + ], | |
| 16 | + links: [ | |
| 17 | + { rel: "preconnect", href: "https://fonts.googleapis.com" }, | |
| 18 | + { rel: "preconnect", href: "https://fonts.gstatic.com", crossOrigin: "anonymous" }, | |
| 19 | + { rel: "stylesheet", href: "https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300..700;1,9..40,300..700&family=Instrument+Serif&family=JetBrains+Mono:wght@400;500&display=swap" }, | |
| 20 | + { rel: "stylesheet", href: appCss }, | |
| 21 | + ], | |
| 22 | + }), | |
| 23 | + component: RootComponent, | |
| 24 | + shellComponent: RootDocument, | |
| 25 | +}); | |
| 26 | + | |
| 27 | +function RootDocument({ children }: { children: React.ReactNode }) { | |
| 28 | + return ( | |
| 29 | + <html lang="en"> | |
| 30 | + <head> | |
| 31 | + <HeadContent /> | |
| 32 | + </head> | |
| 33 | + <body> | |
| 34 | + {children} | |
| 35 | + <Scripts /> | |
| 36 | + </body> | |
| 37 | + </html> | |
| 38 | + ); | |
| 39 | +} | |
| 40 | + | |
| 41 | +function RootComponent() { | |
| 42 | + return ( | |
| 43 | + <AuthProvider> | |
| 44 | + <AuthGate /> | |
| 45 | + </AuthProvider> | |
| 46 | + ); | |
| 47 | +} | |
| 48 | + | |
| 49 | +function AuthGate() { | |
| 50 | + const auth = useAuth(); | |
| 51 | + | |
| 52 | + if (auth.status === "loading") { | |
| 53 | + return ( | |
| 54 | + <div className="flex min-h-screen items-center justify-center bg-background"> | |
| 55 | + <p className="text-sm text-muted-foreground">Loading...</p> | |
| 56 | + </div> | |
| 57 | + ); | |
| 58 | + } | |
| 59 | + | |
| 60 | + if (auth.status === "unauthenticated") { | |
| 61 | + return <LoginPage />; | |
| 62 | + } | |
| 63 | + | |
| 64 | + return ( | |
| 65 | + <ExecutorProvider> | |
| 66 | + <Shell /> | |
| 67 | + </ExecutorProvider> | |
| 68 | + ); | |
| 69 | +} | |
| @@ -0,0 +1,6 @@ | ||
| 1 | +import { createFileRoute } from "@tanstack/react-router"; | |
| 2 | +import { SourcesPage } from "@executor/react/pages/sources"; | |
| 3 | + | |
| 4 | +export const Route = createFileRoute("/")({ | |
| 5 | + component: SourcesPage, | |
| 6 | +}); | |
| @@ -0,0 +1,6 @@ | ||
| 1 | +import { createFileRoute } from "@tanstack/react-router"; | |
| 2 | +import { SecretsPage } from "@executor/react/pages/secrets"; | |
| 3 | + | |
| 4 | +export const Route = createFileRoute("/secrets")({ | |
| 5 | + component: SecretsPage, | |
| 6 | +}); | |
| @@ -0,0 +1,9 @@ | ||
| 1 | +import { createFileRoute } from "@tanstack/react-router"; | |
| 2 | +import { SourceDetailPage } from "@executor/react/pages/source-detail"; | |
| 3 | + | |
| 4 | +export const Route = createFileRoute("/sources/$namespace")({ | |
| 5 | + component: () => { | |
| 6 | + const { namespace } = Route.useParams(); | |
| 7 | + return <SourceDetailPage namespace={namespace} />; | |
| 8 | + }, | |
| 9 | +}); | |
| @@ -0,0 +1,19 @@ | ||
| 1 | +import { Schema } from "effect"; | |
| 2 | +import { createFileRoute } from "@tanstack/react-router"; | |
| 3 | +import { SourcesAddPage } from "@executor/react/pages/sources-add"; | |
| 4 | + | |
| 5 | +const SearchParams = Schema.standardSchemaV1( | |
| 6 | + Schema.Struct({ | |
| 7 | + url: Schema.optional(Schema.String), | |
| 8 | + preset: Schema.optional(Schema.String), | |
| 9 | + }), | |
| 10 | +); | |
| 11 | + | |
| 12 | +export const Route = createFileRoute("/sources/add/$pluginKey")({ | |
| 13 | + validateSearch: SearchParams, | |
| 14 | + component: () => { | |
| 15 | + const { pluginKey } = Route.useParams(); | |
| 16 | + const { url, preset } = Route.useSearch(); | |
| 17 | + return <SourcesAddPage pluginKey={pluginKey} url={url} preset={preset} />; | |
| 18 | + }, | |
| 19 | +}); | |
| @@ -0,0 +1,6 @@ | ||
| 1 | +import { createFileRoute } from "@tanstack/react-router"; | |
| 2 | +import { ToolsPage } from "@executor/react/pages/tools"; | |
| 3 | + | |
| 4 | +export const Route = createFileRoute("/tools")({ | |
| 5 | + component: ToolsPage, | |
| 6 | +}); | |
| @@ -0,0 +1,14 @@ | ||
| 1 | +import { createFileRoute } from "@tanstack/react-router"; | |
| 2 | +import { handleApiRequest } from "../server/api-handler"; | |
| 3 | + | |
| 4 | +export const Route = createFileRoute("/v1/$")({ | |
| 5 | + server: { | |
| 6 | + handlers: { | |
| 7 | + GET: ({ request }) => handleApiRequest(request), | |
| 8 | + POST: ({ request }) => handleApiRequest(request), | |
| 9 | + PUT: ({ request }) => handleApiRequest(request), | |
| 10 | + DELETE: ({ request }) => handleApiRequest(request), | |
| 11 | + PATCH: ({ request }) => handleApiRequest(request), | |
| 12 | + }, | |
| 13 | + }, | |
| 14 | +}); | |
| @@ -0,0 +1,9 @@ | ||
| 1 | +import { createCloudApiHandler } from "../api"; | |
| 2 | +import { getDb } from "../services/db"; | |
| 3 | + | |
| 4 | +const handlerPromise = getDb().then((db) => | |
| 5 | + createCloudApiHandler(db, process.env.ENCRYPTION_KEY ?? "local-dev-encryption-key"), | |
| 6 | +); | |
| 7 | + | |
| 8 | +export const handleApiRequest = async (request: Request) => | |
| 9 | + (await handlerPromise)(request); | |
| @@ -0,0 +1 @@ | ||
| 1 | +/// <reference types="vite/client" /> | |
| @@ -1,29 +0,0 @@ | ||
| 1 | −import React from "react"; | |
| 2 | −import { RouterProvider } from "@tanstack/react-router"; | |
| 3 | −import { AuthProvider, useAuth } from "./auth"; | |
| 4 | −import { LoginPage } from "./pages/login"; | |
| 5 | −import { router } from "./router"; | |
| 6 | − | |
| 7 | −const AuthGate = () => { | |
| 8 | − const auth = useAuth(); | |
| 9 | − | |
| 10 | − if (auth.status === "loading") { | |
| 11 | − return ( | |
| 12 | − <div className="flex min-h-screen items-center justify-center bg-background"> | |
| 13 | − <p className="text-sm text-muted-foreground">Loading...</p> | |
| 14 | − </div> | |
| 15 | − ); | |
| 16 | − } | |
| 17 | − | |
| 18 | − if (auth.status === "unauthenticated") { | |
| 19 | − return <LoginPage />; | |
| 20 | − } | |
| 21 | − | |
| 22 | − return <RouterProvider router={router} />; | |
| 23 | −}; | |
| 24 | − | |
| 25 | −export const App = () => ( | |
| 26 | − <AuthProvider> | |
| 27 | − <AuthGate /> | |
| 28 | − </AuthProvider> | |
| 29 | −); | |
| @@ -1,7 +0,0 @@ | ||
| 1 | −import React from "react"; | |
| 2 | −import { createRoot } from "react-dom/client"; | |
| 3 | −import "@executor/react/globals.css"; | |
| 4 | −import { App } from "./App"; | |
| 5 | − | |
| 6 | −const root = createRoot(document.getElementById("root")!); | |
| 7 | −root.render(<App />); | |
| @@ -1,93 +0,0 @@ | ||
| 1 | −import { | |
| 2 | − createRouter, | |
| 3 | − createRootRoute, | |
| 4 | − createRoute, | |
| 5 | −} from "@tanstack/react-router"; | |
| 6 | −import { ExecutorProvider } from "@executor/react/api/provider"; | |
| 7 | −import { ToolsPage } from "@executor/react/pages/tools"; | |
| 8 | −import { SourcesPage } from "@executor/react/pages/sources"; | |
| 9 | −import { SourcesAddPage } from "@executor/react/pages/sources-add"; | |
| 10 | −import { SourceDetailPage } from "@executor/react/pages/source-detail"; | |
| 11 | −import { SecretsPage } from "@executor/react/pages/secrets"; | |
| 12 | −import { Shell } from "./shell"; | |
| 13 | − | |
| 14 | −// --------------------------------------------------------------------------- | |
| 15 | −// Root layout — Shell renders <Outlet /> directly | |
| 16 | −// --------------------------------------------------------------------------- | |
| 17 | − | |
| 18 | −const rootRoute = createRootRoute({ | |
| 19 | − component: () => ( | |
| 20 | − <ExecutorProvider> | |
| 21 | − <Shell /> | |
| 22 | − </ExecutorProvider> | |
| 23 | − ), | |
| 24 | −}); | |
| 25 | − | |
| 26 | −// --------------------------------------------------------------------------- | |
| 27 | −// Routes — same as apps/web | |
| 28 | −// --------------------------------------------------------------------------- | |
| 29 | − | |
| 30 | −const indexRoute = createRoute({ | |
| 31 | − getParentRoute: () => rootRoute, | |
| 32 | − path: "/", | |
| 33 | − component: SourcesPage, | |
| 34 | −}); | |
| 35 | − | |
| 36 | −const toolsRoute = createRoute({ | |
| 37 | − getParentRoute: () => rootRoute, | |
| 38 | − path: "/tools", | |
| 39 | − component: ToolsPage, | |
| 40 | −}); | |
| 41 | − | |
| 42 | −const sourcesAddRoute = createRoute({ | |
| 43 | − getParentRoute: () => rootRoute, | |
| 44 | − path: "/sources/add/$pluginKey", | |
| 45 | − validateSearch: ( | |
| 46 | − search: Record<string, unknown>, | |
| 47 | − ): { url?: string; preset?: string } => ({ | |
| 48 | − url: typeof search.url === "string" ? search.url : undefined, | |
| 49 | − preset: typeof search.preset === "string" ? search.preset : undefined, | |
| 50 | − }), | |
| 51 | − component: () => { | |
| 52 | − const { pluginKey } = sourcesAddRoute.useParams(); | |
| 53 | − const { url, preset } = sourcesAddRoute.useSearch(); | |
| 54 | − return ( | |
| 55 | − <SourcesAddPage pluginKey={pluginKey} url={url} preset={preset} /> | |
| 56 | − ); | |
| 57 | − }, | |
| 58 | −}); | |
| 59 | − | |
| 60 | −const sourceDetailRoute = createRoute({ | |
| 61 | − getParentRoute: () => rootRoute, | |
| 62 | − path: "/sources/$namespace", | |
| 63 | − component: () => { | |
| 64 | − const { namespace } = sourceDetailRoute.useParams(); | |
| 65 | − return <SourceDetailPage namespace={namespace} />; | |
| 66 | − }, | |
| 67 | −}); | |
| 68 | − | |
| 69 | −const secretsRoute = createRoute({ | |
| 70 | − getParentRoute: () => rootRoute, | |
| 71 | − path: "/secrets", | |
| 72 | − component: SecretsPage, | |
| 73 | −}); | |
| 74 | − | |
| 75 | −// --------------------------------------------------------------------------- | |
| 76 | −// Router | |
| 77 | −// --------------------------------------------------------------------------- | |
| 78 | − | |
| 79 | −const routeTree = rootRoute.addChildren([ | |
| 80 | − indexRoute, | |
| 81 | − toolsRoute, | |
| 82 | − sourcesAddRoute, | |
| 83 | − sourceDetailRoute, | |
| 84 | − secretsRoute, | |
| 85 | −]); | |
| 86 | − | |
| 87 | −export const router = createRouter({ routeTree }); | |
| 88 | − | |
| 89 | −declare module "@tanstack/react-router" { | |
| 90 | − interface Register { | |
| 91 | − router: typeof router; | |
| 92 | − } | |
| 93 | −} | |
| @@ -1,169 +1,11 @@ | ||
| 1 | 1 | import { Link, Outlet, useLocation } from "@tanstack/react-router"; |
| 2 | −import { useCallback, useEffect, useRef, useState } from "react"; | |
| 2 | +import { useEffect, useRef, useState } from "react"; | |
| 3 | 3 | import { useAtomRefresh, useAtomValue, Result } from "@effect-atom/atom-react"; |
| 4 | 4 | import { sourcesAtom, toolsAtom } from "@executor/react/api/atoms"; |
| 5 | −import { useScope, useScopeInfo } from "@executor/react/api/scope-context"; | |
| 5 | +import { useScope } from "@executor/react/api/scope-context"; | |
| 6 | 6 | import { Button } from "@executor/react/components/button"; |
| 7 | 7 | import { useAuth } from "./auth"; |
| 8 | 8 | |
| 9 | −// ── Env ───────────────────────────────────────────────────────────────── | |
| 10 | − | |
| 11 | −type AppMetaEnv = { | |
| 12 | − readonly VITE_APP_VERSION: string; | |
| 13 | − readonly VITE_GITHUB_URL: string; | |
| 14 | −}; | |
| 15 | − | |
| 16 | −const { VITE_APP_VERSION, VITE_GITHUB_URL } = (import.meta as ImportMeta & { | |
| 17 | − readonly env: AppMetaEnv; | |
| 18 | −}).env; | |
| 19 | − | |
| 20 | −// ── Version helpers ───────────────────────────────────────────────────── | |
| 21 | − | |
| 22 | −type UpdateChannel = "latest" | "beta"; | |
| 23 | − | |
| 24 | −const EXECUTOR_DIST_TAGS_PATH = "/v1/app/npm/dist-tags"; | |
| 25 | − | |
| 26 | −type ParsedVersion = { | |
| 27 | − readonly major: number; | |
| 28 | − readonly minor: number; | |
| 29 | − readonly patch: number; | |
| 30 | − readonly prerelease: ReadonlyArray<string | number> | null; | |
| 31 | −}; | |
| 32 | − | |
| 33 | −const semverPattern = | |
| 34 | − /^(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)(?:-(?<prerelease>[0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/; | |
| 35 | − | |
| 36 | −const resolveUpdateChannel = (version: string): UpdateChannel => | |
| 37 | − version.includes("-beta.") ? "beta" : "latest"; | |
| 38 | − | |
| 39 | −const parseVersion = (version: string): ParsedVersion | null => { | |
| 40 | − const match = version.trim().match(semverPattern); | |
| 41 | − if (!match?.groups) return null; | |
| 42 | − return { | |
| 43 | − major: Number(match.groups.major), | |
| 44 | − minor: Number(match.groups.minor), | |
| 45 | − patch: Number(match.groups.patch), | |
| 46 | − prerelease: match.groups.prerelease | |
| 47 | − ? match.groups.prerelease.split(".").map((id) => | |
| 48 | − /^\d+$/.test(id) ? Number(id) : id, | |
| 49 | − ) | |
| 50 | − : null, | |
| 51 | − }; | |
| 52 | −}; | |
| 53 | − | |
| 54 | −const comparePrereleaseIdentifiers = ( | |
| 55 | − left: ReadonlyArray<string | number> | null, | |
| 56 | − right: ReadonlyArray<string | number> | null, | |
| 57 | −): number => { | |
| 58 | − if (left === null && right === null) return 0; | |
| 59 | − if (left === null) return 1; | |
| 60 | − if (right === null) return -1; | |
| 61 | − const max = Math.max(left.length, right.length); | |
| 62 | − for (let i = 0; i < max; i++) { | |
| 63 | − const l = left[i]; | |
| 64 | − const r = right[i]; | |
| 65 | − if (l === undefined) return -1; | |
| 66 | − if (r === undefined) return 1; | |
| 67 | − if (l === r) continue; | |
| 68 | − if (typeof l === "number" && typeof r === "number") return l < r ? -1 : 1; | |
| 69 | − if (typeof l === "number") return -1; | |
| 70 | − if (typeof r === "number") return 1; | |
| 71 | − return l < r ? -1 : 1; | |
| 72 | − } | |
| 73 | − return 0; | |
| 74 | −}; | |
| 75 | − | |
| 76 | −const compareVersions = (left: string, right: string): number | null => { | |
| 77 | − const lv = parseVersion(left); | |
| 78 | − const rv = parseVersion(right); | |
| 79 | − if (!lv || !rv) return null; | |
| 80 | − if (lv.major !== rv.major) return lv.major < rv.major ? -1 : 1; | |
| 81 | − if (lv.minor !== rv.minor) return lv.minor < rv.minor ? -1 : 1; | |
| 82 | − if (lv.patch !== rv.patch) return lv.patch < rv.patch ? -1 : 1; | |
| 83 | − return comparePrereleaseIdentifiers(lv.prerelease, rv.prerelease); | |
| 84 | −}; | |
| 85 | − | |
| 86 | −// ── useLatestVersion ──────────────────────────────────────────────────── | |
| 87 | − | |
| 88 | −function useLatestVersion(currentVersion: string) { | |
| 89 | − const channel = resolveUpdateChannel(currentVersion); | |
| 90 | − const [latestVersion, setLatestVersion] = useState<string | null>(null); | |
| 91 | − | |
| 92 | − useEffect(() => { | |
| 93 | − let cancelled = false; | |
| 94 | − fetch(EXECUTOR_DIST_TAGS_PATH) | |
| 95 | − .then(async (res) => { | |
| 96 | − if (!res.ok) throw new Error(`Failed to load dist tags: ${res.status}`); | |
| 97 | − return res.json() as Promise<Partial<Record<UpdateChannel, string>>>; | |
| 98 | − }) | |
| 99 | − .then((data) => { | |
| 100 | − if (!cancelled) setLatestVersion(data[channel] ?? null); | |
| 101 | − }) | |
| 102 | − .catch(() => {}); | |
| 103 | − return () => { cancelled = true; }; | |
| 104 | − }, [channel]); | |
| 105 | − | |
| 106 | − const updateAvailable = | |
| 107 | − latestVersion !== null && compareVersions(currentVersion, latestVersion) === -1; | |
| 108 | − | |
| 109 | − return { latestVersion, updateAvailable, channel }; | |
| 110 | −} | |
| 111 | − | |
| 112 | −// ── UpdateCard ────────────────────────────────────────────────────────── | |
| 113 | − | |
| 114 | −function UpdateCard(props: { latestVersion: string; channel: UpdateChannel }) { | |
| 115 | − const command = `npm i -g executor@${props.channel}`; | |
| 116 | − const [copied, setCopied] = useState(false); | |
| 117 | − | |
| 118 | − const handleCopy = useCallback(() => { | |
| 119 | − void navigator.clipboard.writeText(command).then(() => { | |
| 120 | − setCopied(true); | |
| 121 | − setTimeout(() => setCopied(false), 1500); | |
| 122 | − }); | |
| 123 | − }, [command]); | |
| 124 | − | |
| 125 | − return ( | |
| 126 | − <div className="mx-2 mb-2 rounded-xl border border-primary/25 bg-primary/[0.06] p-3"> | |
| 127 | − <div className="flex items-center gap-2"> | |
| 128 | − <div className="flex size-5 shrink-0 items-center justify-center rounded-full bg-primary/15"> | |
| 129 | − <svg viewBox="0 0 16 16" fill="none" className="size-3 text-primary"> | |
| 130 | − <path d="M8 3v7M5 7l3 3 3-3" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round" /> | |
| 131 | − <path d="M3 12h10" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" /> | |
| 132 | − </svg> | |
| 133 | − </div> | |
| 134 | − <div className="min-w-0"> | |
| 135 | − <p className="text-[11px] font-semibold text-foreground">Update available</p> | |
| 136 | − <p className="text-[10px] text-muted-foreground"> | |
| 137 | − v{props.latestVersion} | |
| 138 | − </p> | |
| 139 | − </div> | |
| 140 | − </div> | |
| 141 | − <Button | |
| 142 | − type="button" | |
| 143 | − variant="outline" | |
| 144 | − onClick={handleCopy} | |
| 145 | − className="mt-2.5 flex w-full items-center justify-between gap-2 rounded-lg border-border/60 bg-background/50 px-2.5 py-1.5 text-left hover:bg-background/80" | |
| 146 | − > | |
| 147 | − <code className="truncate font-mono text-[10px] text-sidebar-foreground"> | |
| 148 | − {command} | |
| 149 | − </code> | |
| 150 | − <span className="shrink-0 text-muted-foreground transition-colors group-hover:text-foreground"> | |
| 151 | − {copied ? ( | |
| 152 | − <svg viewBox="0 0 16 16" fill="none" className="size-3 text-primary"> | |
| 153 | − <path d="M3 8.5l3.5 3.5L13 4" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round" /> | |
| 154 | − </svg> | |
| 155 | − ) : ( | |
| 156 | − <svg viewBox="0 0 16 16" fill="none" className="size-3"> | |
| 157 | − <rect x="5" y="5" width="8" height="8" rx="1.5" stroke="currentColor" strokeWidth="1.2" /> | |
| 158 | − <path d="M3 11V3.5A.5.5 0 013.5 3H11" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" /> | |
| 159 | − </svg> | |
| 160 | − )} | |
| 161 | − </span> | |
| 162 | − </Button> | |
| 163 | − </div> | |
| 164 | − ); | |
| 165 | −} | |
| 166 | − | |
| 167 | 9 | // ── NavItem ────────────────────────────────────────────────────────────── |
| 168 | 10 | |
| 169 | 11 | function NavItem(props: { to: string; label: string; active: boolean; onNavigate?: () => void }) { |
| @@ -233,30 +75,6 @@ function SourceList(props: { pathname: string; onNavigate?: () => void }) { · 63 unmodified lines | ||
| 233 | 75 | }); |
| 234 | 76 | } |
| 235 | 77 | |
| 236 | −// ── ScopeLabel ─────────────────────────────────────────────────────────── | |
| 237 | − | |
| 238 | −function ScopeLabel() { | |
| 239 | − const { name } = useScopeInfo(); | |
| 240 | − // Show just the last folder name, with full path as tooltip | |
| 241 | − const parts = name.replace(/\/+$/, "").split("/"); | |
| 242 | − const folder = parts[parts.length - 1] || name; | |
| 243 | − | |
| 244 | − return ( | |
| 245 | − <div className="mb-1.5 flex items-center gap-1.5 rounded-md px-2.5 py-1.5" title={name}> | |
| 246 | − <svg viewBox="0 0 16 16" fill="none" className="size-3.5 shrink-0 text-muted-foreground/50"> | |
| 247 | − <path | |
| 248 | − d="M2 4.5C2 3.67 2.67 3 3.5 3h3.09a1 1 0 0 1 .7.29l1.42 1.42a1 1 0 0 0 .7.29H12.5c.83 0 1.5.67 1.5 1.5v5.5c0 .83-.67 1.5-1.5 1.5h-9A1.5 1.5 0 0 1 2 12V4.5z" | |
| 249 | − stroke="currentColor" | |
| 250 | − strokeWidth="1.2" | |
| 251 | − /> | |
| 252 | − </svg> | |
| 253 | − <span className="truncate text-[12px] font-medium text-foreground/80"> | |
| 254 | − {folder} | |
| 255 | − </span> | |
| 256 | − </div> | |
| 257 | − ); | |
| 258 | −} | |
| 259 | − | |
| 260 | 78 | // ── UserFooter ────────────────────────────────────────────────────────── |
| 261 | 79 | |
| 262 | 80 | function UserFooter() { |
| @@ -291,15 +109,17 @@ function UserFooter() { · 28 unmodified lines | ||
| 291 | 109 | </p> |
| 292 | 110 | )} |
| 293 | 111 | </div> |
| 294 | − <a | |
| 295 | − href="/auth/logout" | |
| 296 | − className="shrink-0 rounded-md p-1 text-muted-foreground/50 transition-colors hover:bg-sidebar-active hover:text-foreground" | |
| 297 | − title="Sign out" | |
| 298 | − > | |
| 299 | − <svg viewBox="0 0 16 16" fill="none" className="size-3.5"> | |
| 300 | − <path d="M6 2H3.5A1.5 1.5 0 002 3.5v9A1.5 1.5 0 003.5 14H6M10.5 11.5L14 8l-3.5-3.5M14 8H6" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round" /> | |
| 301 | − </svg> | |
| 302 | − </a> | |
| 112 | + <form action="/auth/logout" method="post"> | |
| 113 | + <button | |
| 114 | + type="submit" | |
| 115 | + className="shrink-0 rounded-md p-1 text-muted-foreground/50 transition-colors hover:bg-sidebar-active hover:text-foreground" | |
| 116 | + title="Sign out" | |
| 117 | + > | |
| 118 | + <svg viewBox="0 0 16 16" fill="none" className="size-3.5"> | |
| 119 | + <path d="M6 2H3.5A1.5 1.5 0 002 3.5v9A1.5 1.5 0 003.5 14H6M10.5 11.5L14 8l-3.5-3.5M14 8H6" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round" /> | |
| 120 | + </svg> | |
| 121 | + </button> | |
| 122 | + </form> | |
| 303 | 123 | </div> |
| 304 | 124 | </div> |
| 305 | 125 | ); |
| @@ -311,9 +131,6 @@ function SidebarContent(props: { · 5 unmodified lines | ||
| 311 | 131 | pathname: string; |
| 312 | 132 | onNavigate?: () => void; |
| 313 | 133 | showBrand?: boolean; |
| 314 | − updateAvailable: boolean; | |
| 315 | − latestVersion: string | null; | |
| 316 | − channel: UpdateChannel; | |
| 317 | 134 | }) { |
| 318 | 135 | const isHome = props.pathname === "/"; |
| 319 | 136 | const isSecrets = props.pathname === "/secrets"; |
| @@ -331,7 +148,6 @@ function SidebarContent(props: { · 11 unmodified lines | ||
| 331 | 148 | )} |
| 332 | 149 | |
| 333 | 150 | <nav className="flex flex-1 flex-col overflow-y-auto p-2"> |
| 334 | − <ScopeLabel /> | |
| 335 | 151 | <NavItem |
| 336 | 152 | to="/" |
| 337 | 153 | label="Sources" |
| @@ -345,7 +161,6 @@ function SidebarContent(props: { · 7 unmodified lines | ||
| 345 | 161 | onNavigate={props.onNavigate} |
| 346 | 162 | /> |
| 347 | 163 | |
| 348 | − {/* Sources list */} | |
| 349 | 164 | <div className="mt-5 mb-1 px-2.5 text-[10px] font-medium uppercase tracking-widest text-muted-foreground/50"> |
| 350 | 165 | <span>Configured</span> |
| 351 | 166 | </div> |
| @@ -353,7 +168,6 @@ function SidebarContent(props: { · 1 unmodified line | ||
| 353 | 168 | <SourceList pathname={props.pathname} onNavigate={props.onNavigate} /> |
| 354 | 169 | </nav> |
| 355 | 170 | |
| 356 | − {/* User */} | |
| 357 | 171 | <UserFooter /> |
| 358 | 172 | </> |
| 359 | 173 | ); |
| @@ -367,7 +181,6 @@ export function Shell() { · 7 unmodified lines | ||
| 367 | 181 | const scopeId = useScope(); |
| 368 | 182 | const refreshSources = useAtomRefresh(sourcesAtom(scopeId)); |
| 369 | 183 | const refreshTools = useAtomRefresh(toolsAtom(scopeId)); |
| 370 | − const { latestVersion, updateAvailable, channel } = useLatestVersion(VITE_APP_VERSION); | |
| 371 | 184 | const lastPathname = useRef(pathname); |
| 372 | 185 | const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false); |
| 373 | 186 | if (lastPathname.current !== pathname) { |
| @@ -385,33 +198,11 @@ export function Shell() { · 11 unmodified lines | ||
| 385 | 198 | }; |
| 386 | 199 | }, [mobileSidebarOpen]); |
| 387 | 200 | |
| 388 | − useEffect(() => { | |
| 389 | − if (!import.meta.hot) { | |
| 390 | − return; | |
| 391 | − } | |
| 392 | − | |
| 393 | − const refreshBackendData = () => { | |
| 394 | − refreshSources(); | |
| 395 | − refreshTools(); | |
| 396 | − }; | |
| 397 | − | |
| 398 | − import.meta.hot.on("executor:backend-updated", refreshBackendData); | |
| 399 | − | |
| 400 | − return () => { | |
| 401 | − import.meta.hot?.off("executor:backend-updated", refreshBackendData); | |
| 402 | − }; | |
| 403 | − }, [refreshSources, refreshTools]); | |
| 404 | − | |
| 405 | 201 | return ( |
| 406 | 202 | <div className="flex h-screen overflow-hidden"> |
| 407 | 203 | {/* Desktop sidebar */} |
| 408 | 204 | <aside className="hidden w-52 shrink-0 border-r border-sidebar-border bg-sidebar md:flex md:flex-col lg:w-56"> |
| 409 | − <SidebarContent | |
| 410 | − pathname={pathname} | |
| 411 | − updateAvailable={updateAvailable} | |
| 412 | − latestVersion={latestVersion} | |
| 413 | − channel={channel} | |
| 414 | − /> | |
| 205 | + <SidebarContent pathname={pathname} /> | |
| 415 | 206 | </aside> |
| 416 | 207 | |
| 417 | 208 | {/* Mobile sidebar overlay */} |
| @@ -445,9 +236,6 @@ export function Shell() { · 27 unmodified lines | ||
| 445 | 236 | pathname={pathname} |
| 446 | 237 | onNavigate={() => setMobileSidebarOpen(false)} |
| 447 | 238 | showBrand={false} |
| 448 | − updateAvailable={updateAvailable} | |
| 449 | − latestVersion={latestVersion} | |
| 450 | − channel={channel} | |
| 451 | 239 | /> |
| 452 | 240 | </div> |
| 453 | 241 | </div> |
| @@ -475,7 +263,6 @@ export function Shell() { · 21 unmodified lines | ||
| 475 | 263 | <div className="w-8 shrink-0" /> |
| 476 | 264 | </div> |
| 477 | 265 | |
| 478 | − {/* Outlet — pages control their own padding/scroll */} | |
| 479 | 266 | <Outlet /> |
| 480 | 267 | </main> |
| 481 | 268 | </div> |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | "esModuleInterop": true, |
| 8 | 8 | "skipLibCheck": true, |
| 9 | 9 | "outDir": "dist", |
| 10 | − "rootDir": "src", | |
| 10 | + "rootDir": ".", | |
| 11 | 11 | "declaration": true, |
| 12 | 12 | "declarationMap": true, |
| 13 | 13 | "sourceMap": true, |
| @@ -19,5 +19,5 @@ · 5 unmodified lines | ||
| 19 | 19 | } |
| 20 | 20 | ] |
| 21 | 21 | }, |
| 22 | − "include": ["src"] | |
| 22 | + "include": ["src", "vite.config.ts"] | |
| 23 | 23 | } |
| @@ -1,22 +1,19 @@ | ||
| 1 | 1 | import { defineConfig } from "vite"; |
| 2 | +import { tanstackStart } from "@tanstack/react-start/plugin/vite"; | |
| 2 | 3 | import react from "@vitejs/plugin-react"; |
| 3 | 4 | import tailwindcss from "@tailwindcss/vite"; |
| 4 | 5 | |
| 5 | −const API_PORT = process.env.API_PORT ?? "3001"; | |
| 6 | − | |
| 7 | 6 | export default defineConfig({ |
| 8 | − plugins: [react(), tailwindcss()], | |
| 9 | − define: { | |
| 10 | − "import.meta.env.VITE_APP_VERSION": JSON.stringify("0.0.0"), | |
| 11 | − "import.meta.env.VITE_GITHUB_URL": JSON.stringify("https://github.com/RhysSullivan/executor"), | |
| 12 | − }, | |
| 13 | 7 | server: { |
| 14 | − proxy: { | |
| 15 | − "/v1": `http://localhost:${API_PORT}`, | |
| 16 | − "/auth": `http://localhost:${API_PORT}`, | |
| 17 | − "/api": `http://localhost:${API_PORT}`, | |
| 18 | − "/docs": `http://localhost:${API_PORT}`, | |
| 19 | − "/openapi.json": `http://localhost:${API_PORT}`, | |
| 20 | − }, | |
| 8 | + port: parseInt(process.env.PORT ?? "5173", 10), | |
| 9 | + host: "127.0.0.1", | |
| 21 | 10 | }, |
| 11 | + resolve: { tsconfigPaths: true }, | |
| 12 | + plugins: [ | |
| 13 | + tailwindcss(), | |
| 14 | + tanstackStart({ | |
| 15 | + spa: { enabled: true }, | |
| 16 | + }), | |
| 17 | + react(), | |
| 18 | + ], | |
| 22 | 19 | }); |
| @@ -24,7 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | "@types/node": "catalog:", |
| 25 | 25 | "electron": "35.7.5", |
| 26 | 26 | "electron-builder": "^26.0.12", |
| 27 | − "typescript": "^5.9.3" | |
| 27 | + "typescript": "catalog:" | |
| 28 | 28 | }, |
| 29 | 29 | "build": { |
| 30 | 30 | "appId": "com.executor.desktop", |
| @@ -1,15 +0,0 @@ | ||
| 1 | −<!doctype html> | |
| 2 | −<html lang="en"> | |
| 3 | − <head> | |
| 4 | − <meta charset="UTF-8" /> | |
| 5 | − <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| 6 | − <title>Executor</title> | |
| 7 | − <link rel="preconnect" href="https://fonts.googleapis.com" /> | |
| 8 | − <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> | |
| 9 | − <link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300..700;1,9..40,300..700&family=Instrument+Serif&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" /> | |
| 10 | − </head> | |
| 11 | − <body> | |
| 12 | − <div id="root"></div> | |
| 13 | − <script type="module" src="/src/web/main.tsx"></script> | |
| 14 | − </body> | |
| 15 | −</html> | |
| @@ -28,26 +28,27 @@ · 27 unmodified lines | ||
| 28 | 28 | "@modelcontextprotocol/sdk": "^1.12.1", |
| 29 | 29 | "@shikijs/langs": "^4.0.2", |
| 30 | 30 | "@shikijs/themes": "^4.0.2", |
| 31 | − "@tanstack/react-router": "^1.168.10", | |
| 31 | + "@tanstack/react-router": "catalog:", | |
| 32 | + "@tanstack/react-start": "catalog:", | |
| 32 | 33 | "effect": "catalog:", |
| 33 | − "react": "^19.1.0", | |
| 34 | − "react-dom": "^19.1.0", | |
| 34 | + "react": "catalog:", | |
| 35 | + "react-dom": "catalog:", | |
| 35 | 36 | "shiki": "^4.0.2", |
| 36 | 37 | "streamdown": "^2.5.0", |
| 37 | − "tailwindcss": "^4.1.10" | |
| 38 | + "tailwindcss": "catalog:" | |
| 38 | 39 | }, |
| 39 | 40 | "devDependencies": { |
| 40 | − "@tailwindcss/vite": "^4.1.10", | |
| 41 | + "@tailwindcss/vite": "catalog:", | |
| 41 | 42 | "@types/node": "catalog:", |
| 42 | − "@types/react": "^19.1.0", | |
| 43 | − "@types/react-dom": "^19.1.0", | |
| 44 | − "@vitejs/plugin-react": "^4.5.2", | |
| 43 | + "@types/react": "catalog:", | |
| 44 | + "@types/react-dom": "catalog:", | |
| 45 | + "@vitejs/plugin-react": "catalog:", | |
| 45 | 46 | "bun-types": "catalog:", |
| 46 | − "typescript": "^5.9.3", | |
| 47 | − "vite": "^6.3.5" | |
| 47 | + "typescript": "catalog:", | |
| 48 | + "vite": "catalog:" | |
| 48 | 49 | }, |
| 49 | 50 | "scripts": { |
| 50 | − "dev": "bunx --bun vite", | |
| 51 | + "dev": "bunx --bun vite dev", | |
| 51 | 52 | "build": "vite build", |
| 52 | 53 | "typecheck": "tsc --noEmit" |
| 53 | 54 | } |
| @@ -0,0 +1,198 @@ | ||
| 1 | +/* eslint-disable */ | |
| 2 | + | |
| 3 | +// @ts-nocheck | |
| 4 | + | |
| 5 | +// noinspection JSUnusedGlobalSymbols | |
| 6 | + | |
| 7 | +// This file was automatically generated by TanStack Router. | |
| 8 | +// You should NOT make any changes in this file as it will be overwritten. | |
| 9 | +// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. | |
| 10 | + | |
| 11 | +import { Route as rootRouteImport } from './routes/__root' | |
| 12 | +import { Route as ToolsRouteImport } from './routes/tools' | |
| 13 | +import { Route as SecretsRouteImport } from './routes/secrets' | |
| 14 | +import { Route as IndexRouteImport } from './routes/index' | |
| 15 | +import { Route as V1SplatRouteImport } from './routes/v1.$' | |
| 16 | +import { Route as SourcesNamespaceRouteImport } from './routes/sources.$namespace' | |
| 17 | +import { Route as McpSplatRouteImport } from './routes/mcp.$' | |
| 18 | +import { Route as SourcesAddPluginKeyRouteImport } from './routes/sources.add.$pluginKey' | |
| 19 | + | |
| 20 | +const ToolsRoute = ToolsRouteImport.update({ | |
| 21 | + id: '/tools', | |
| 22 | + path: '/tools', | |
| 23 | + getParentRoute: () => rootRouteImport, | |
| 24 | +} as any) | |
| 25 | +const SecretsRoute = SecretsRouteImport.update({ | |
| 26 | + id: '/secrets', | |
| 27 | + path: '/secrets', | |
| 28 | + getParentRoute: () => rootRouteImport, | |
| 29 | +} as any) | |
| 30 | +const IndexRoute = IndexRouteImport.update({ | |
| 31 | + id: '/', | |
| 32 | + path: '/', | |
| 33 | + getParentRoute: () => rootRouteImport, | |
| 34 | +} as any) | |
| 35 | +const V1SplatRoute = V1SplatRouteImport.update({ | |
| 36 | + id: '/v1/$', | |
| 37 | + path: '/v1/$', | |
| 38 | + getParentRoute: () => rootRouteImport, | |
| 39 | +} as any) | |
| 40 | +const SourcesNamespaceRoute = SourcesNamespaceRouteImport.update({ | |
| 41 | + id: '/sources/$namespace', | |
| 42 | + path: '/sources/$namespace', | |
| 43 | + getParentRoute: () => rootRouteImport, | |
| 44 | +} as any) | |
| 45 | +const McpSplatRoute = McpSplatRouteImport.update({ | |
| 46 | + id: '/mcp/$', | |
| 47 | + path: '/mcp/$', | |
| 48 | + getParentRoute: () => rootRouteImport, | |
| 49 | +} as any) | |
| 50 | +const SourcesAddPluginKeyRoute = SourcesAddPluginKeyRouteImport.update({ | |
| 51 | + id: '/sources/add/$pluginKey', | |
| 52 | + path: '/sources/add/$pluginKey', | |
| 53 | + getParentRoute: () => rootRouteImport, | |
| 54 | +} as any) | |
| 55 | + | |
| 56 | +export interface FileRoutesByFullPath { | |
| 57 | + '/': typeof IndexRoute | |
| 58 | + '/secrets': typeof SecretsRoute | |
| 59 | + '/tools': typeof ToolsRoute | |
| 60 | + '/mcp/$': typeof McpSplatRoute | |
| 61 | + '/sources/$namespace': typeof SourcesNamespaceRoute | |
| 62 | + '/v1/$': typeof V1SplatRoute | |
| 63 | + '/sources/add/$pluginKey': typeof SourcesAddPluginKeyRoute | |
| 64 | +} | |
| 65 | +export interface FileRoutesByTo { | |
| 66 | + '/': typeof IndexRoute | |
| 67 | + '/secrets': typeof SecretsRoute | |
| 68 | + '/tools': typeof ToolsRoute | |
| 69 | + '/mcp/$': typeof McpSplatRoute | |
| 70 | + '/sources/$namespace': typeof SourcesNamespaceRoute | |
| 71 | + '/v1/$': typeof V1SplatRoute | |
| 72 | + '/sources/add/$pluginKey': typeof SourcesAddPluginKeyRoute | |
| 73 | +} | |
| 74 | +export interface FileRoutesById { | |
| 75 | + __root__: typeof rootRouteImport | |
| 76 | + '/': typeof IndexRoute | |
| 77 | + '/secrets': typeof SecretsRoute | |
| 78 | + '/tools': typeof ToolsRoute | |
| 79 | + '/mcp/$': typeof McpSplatRoute | |
| 80 | + '/sources/$namespace': typeof SourcesNamespaceRoute | |
| 81 | + '/v1/$': typeof V1SplatRoute | |
| 82 | + '/sources/add/$pluginKey': typeof SourcesAddPluginKeyRoute | |
| 83 | +} | |
| 84 | +export interface FileRouteTypes { | |
| 85 | + fileRoutesByFullPath: FileRoutesByFullPath | |
| 86 | + fullPaths: | |
| 87 | + | '/' | |
| 88 | + | '/secrets' | |
| 89 | + | '/tools' | |
| 90 | + | '/mcp/$' | |
| 91 | + | '/sources/$namespace' | |
| 92 | + | '/v1/$' | |
| 93 | + | '/sources/add/$pluginKey' | |
| 94 | + fileRoutesByTo: FileRoutesByTo | |
| 95 | + to: | |
| 96 | + | '/' | |
| 97 | + | '/secrets' | |
| 98 | + | '/tools' | |
| 99 | + | '/mcp/$' | |
| 100 | + | '/sources/$namespace' | |
| 101 | + | '/v1/$' | |
| 102 | + | '/sources/add/$pluginKey' | |
| 103 | + id: | |
| 104 | + | '__root__' | |
| 105 | + | '/' | |
| 106 | + | '/secrets' | |
| 107 | + | '/tools' | |
| 108 | + | '/mcp/$' | |
| 109 | + | '/sources/$namespace' | |
| 110 | + | '/v1/$' | |
| 111 | + | '/sources/add/$pluginKey' | |
| 112 | + fileRoutesById: FileRoutesById | |
| 113 | +} | |
| 114 | +export interface RootRouteChildren { | |
| 115 | + IndexRoute: typeof IndexRoute | |
| 116 | + SecretsRoute: typeof SecretsRoute | |
| 117 | + ToolsRoute: typeof ToolsRoute | |
| 118 | + McpSplatRoute: typeof McpSplatRoute | |
| 119 | + SourcesNamespaceRoute: typeof SourcesNamespaceRoute | |
| 120 | + V1SplatRoute: typeof V1SplatRoute | |
| 121 | + SourcesAddPluginKeyRoute: typeof SourcesAddPluginKeyRoute | |
| 122 | +} | |
| 123 | + | |
| 124 | +declare module '@tanstack/react-router' { | |
| 125 | + interface FileRoutesByPath { | |
| 126 | + '/tools': { | |
| 127 | + id: '/tools' | |
| 128 | + path: '/tools' | |
| 129 | + fullPath: '/tools' | |
| 130 | + preLoaderRoute: typeof ToolsRouteImport | |
| 131 | + parentRoute: typeof rootRouteImport | |
| 132 | + } | |
| 133 | + '/secrets': { | |
| 134 | + id: '/secrets' | |
| 135 | + path: '/secrets' | |
| 136 | + fullPath: '/secrets' | |
| 137 | + preLoaderRoute: typeof SecretsRouteImport | |
| 138 | + parentRoute: typeof rootRouteImport | |
| 139 | + } | |
| 140 | + '/': { | |
| 141 | + id: '/' | |
| 142 | + path: '/' | |
| 143 | + fullPath: '/' | |
| 144 | + preLoaderRoute: typeof IndexRouteImport | |
| 145 | + parentRoute: typeof rootRouteImport | |
| 146 | + } | |
| 147 | + '/v1/$': { | |
| 148 | + id: '/v1/$' | |
| 149 | + path: '/v1/$' | |
| 150 | + fullPath: '/v1/$' | |
| 151 | + preLoaderRoute: typeof V1SplatRouteImport | |
| 152 | + parentRoute: typeof rootRouteImport | |
| 153 | + } | |
| 154 | + '/sources/$namespace': { | |
| 155 | + id: '/sources/$namespace' | |
| 156 | + path: '/sources/$namespace' | |
| 157 | + fullPath: '/sources/$namespace' | |
| 158 | + preLoaderRoute: typeof SourcesNamespaceRouteImport | |
| 159 | + parentRoute: typeof rootRouteImport | |
| 160 | + } | |
| 161 | + '/mcp/$': { | |
| 162 | + id: '/mcp/$' | |
| 163 | + path: '/mcp/$' | |
| 164 | + fullPath: '/mcp/$' | |
| 165 | + preLoaderRoute: typeof McpSplatRouteImport | |
| 166 | + parentRoute: typeof rootRouteImport | |
| 167 | + } | |
| 168 | + '/sources/add/$pluginKey': { | |
| 169 | + id: '/sources/add/$pluginKey' | |
| 170 | + path: '/sources/add/$pluginKey' | |
| 171 | + fullPath: '/sources/add/$pluginKey' | |
| 172 | + preLoaderRoute: typeof SourcesAddPluginKeyRouteImport | |
| 173 | + parentRoute: typeof rootRouteImport | |
| 174 | + } | |
| 175 | + } | |
| 176 | +} | |
| 177 | + | |
| 178 | +const rootRouteChildren: RootRouteChildren = { | |
| 179 | + IndexRoute: IndexRoute, | |
| 180 | + SecretsRoute: SecretsRoute, | |
| 181 | + ToolsRoute: ToolsRoute, | |
| 182 | + McpSplatRoute: McpSplatRoute, | |
| 183 | + SourcesNamespaceRoute: SourcesNamespaceRoute, | |
| 184 | + V1SplatRoute: V1SplatRoute, | |
| 185 | + SourcesAddPluginKeyRoute: SourcesAddPluginKeyRoute, | |
| 186 | +} | |
| 187 | +export const routeTree = rootRouteImport | |
| 188 | + ._addFileChildren(rootRouteChildren) | |
| 189 | + ._addFileTypes<FileRouteTypes>() | |
| 190 | + | |
| 191 | +import type { getRouter } from './router.tsx' | |
| 192 | +import type { createStart } from '@tanstack/react-start' | |
| 193 | +declare module '@tanstack/react-start' { | |
| 194 | + interface Register { | |
| 195 | + ssr: true | |
| 196 | + router: Awaited<ReturnType<typeof getRouter>> | |
| 197 | + } | |
| 198 | +} | |
| @@ -0,0 +1,10 @@ | ||
| 1 | +import { createRouter } from "@tanstack/react-router"; | |
| 2 | +import { routeTree } from "./routeTree.gen"; | |
| 3 | + | |
| 4 | +export const getRouter = () => { | |
| 5 | + return createRouter({ | |
| 6 | + routeTree, | |
| 7 | + scrollRestoration: true, | |
| 8 | + defaultPreloadStaleTime: 0, | |
| 9 | + }); | |
| 10 | +}; | |
| @@ -0,0 +1,45 @@ | ||
| 1 | +import React from "react"; | |
| 2 | +import { HeadContent, Outlet, Scripts, createRootRoute } from "@tanstack/react-router"; | |
| 3 | +import { ExecutorProvider } from "@executor/react/api/provider"; | |
| 4 | +import { Shell } from "../web/shell"; | |
| 5 | +import appCss from "@executor/react/globals.css?url"; | |
| 6 | + | |
| 7 | +export const Route = createRootRoute({ | |
| 8 | + head: () => ({ | |
| 9 | + meta: [ | |
| 10 | + { charSet: "utf-8" }, | |
| 11 | + { name: "viewport", content: "width=device-width, initial-scale=1" }, | |
| 12 | + { title: "Executor" }, | |
| 13 | + ], | |
| 14 | + links: [ | |
| 15 | + { rel: "preconnect", href: "https://fonts.googleapis.com" }, | |
| 16 | + { rel: "preconnect", href: "https://fonts.gstatic.com", crossOrigin: "anonymous" }, | |
| 17 | + { rel: "stylesheet", href: "https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300..700;1,9..40,300..700&family=Instrument+Serif&family=JetBrains+Mono:wght@400;500&display=swap" }, | |
| 18 | + { rel: "stylesheet", href: appCss }, | |
| 19 | + ], | |
| 20 | + }), | |
| 21 | + component: RootComponent, | |
| 22 | + shellComponent: RootDocument, | |
| 23 | +}); | |
| 24 | + | |
| 25 | +function RootDocument({ children }: { children: React.ReactNode }) { | |
| 26 | + return ( | |
| 27 | + <html lang="en"> | |
| 28 | + <head> | |
| 29 | + <HeadContent /> | |
| 30 | + </head> | |
| 31 | + <body> | |
| 32 | + {children} | |
| 33 | + <Scripts /> | |
| 34 | + </body> | |
| 35 | + </html> | |
| 36 | + ); | |
| 37 | +} | |
| 38 | + | |
| 39 | +function RootComponent() { | |
| 40 | + return ( | |
| 41 | + <ExecutorProvider> | |
| 42 | + <Shell /> | |
| 43 | + </ExecutorProvider> | |
| 44 | + ); | |
| 45 | +} | |
| @@ -0,0 +1,6 @@ | ||
| 1 | +import { createFileRoute } from "@tanstack/react-router"; | |
| 2 | +import { SourcesPage } from "@executor/react/pages/sources"; | |
| 3 | + | |
| 4 | +export const Route = createFileRoute("/")({ | |
| 5 | + component: SourcesPage, | |
| 6 | +}); | |
| @@ -0,0 +1,13 @@ | ||
| 1 | +import { createFileRoute } from "@tanstack/react-router"; | |
| 2 | +import { handleMcpRequest } from "../server/api-handler"; | |
| 3 | + | |
| 4 | +export const Route = createFileRoute("/mcp/$")({ | |
| 5 | + server: { | |
| 6 | + handlers: { | |
| 7 | + GET: ({ request }) => handleMcpRequest(request), | |
| 8 | + POST: ({ request }) => handleMcpRequest(request), | |
| 9 | + PUT: ({ request }) => handleMcpRequest(request), | |
| 10 | + DELETE: ({ request }) => handleMcpRequest(request), | |
| 11 | + }, | |
| 12 | + }, | |
| 13 | +}); | |
| @@ -0,0 +1,6 @@ | ||
| 1 | +import { createFileRoute } from "@tanstack/react-router"; | |
| 2 | +import { SecretsPage } from "@executor/react/pages/secrets"; | |
| 3 | + | |
| 4 | +export const Route = createFileRoute("/secrets")({ | |
| 5 | + component: SecretsPage, | |
| 6 | +}); | |
| @@ -0,0 +1,9 @@ | ||
| 1 | +import { createFileRoute } from "@tanstack/react-router"; | |
| 2 | +import { SourceDetailPage } from "@executor/react/pages/source-detail"; | |
| 3 | + | |
| 4 | +export const Route = createFileRoute("/sources/$namespace")({ | |
| 5 | + component: () => { | |
| 6 | + const { namespace } = Route.useParams(); | |
| 7 | + return <SourceDetailPage namespace={namespace} />; | |
| 8 | + }, | |
| 9 | +}); | |
| @@ -0,0 +1,19 @@ | ||
| 1 | +import { Schema } from "effect"; | |
| 2 | +import { createFileRoute } from "@tanstack/react-router"; | |
| 3 | +import { SourcesAddPage } from "@executor/react/pages/sources-add"; | |
| 4 | + | |
| 5 | +const SearchParams = Schema.standardSchemaV1( | |
| 6 | + Schema.Struct({ | |
| 7 | + url: Schema.optional(Schema.String), | |
| 8 | + preset: Schema.optional(Schema.String), | |
| 9 | + }), | |
| 10 | +); | |
| 11 | + | |
| 12 | +export const Route = createFileRoute("/sources/add/$pluginKey")({ | |
| 13 | + validateSearch: SearchParams, | |
| 14 | + component: () => { | |
| 15 | + const { pluginKey } = Route.useParams(); | |
| 16 | + const { url, preset } = Route.useSearch(); | |
| 17 | + return <SourcesAddPage pluginKey={pluginKey} url={url} preset={preset} />; | |
| 18 | + }, | |
| 19 | +}); | |
| @@ -0,0 +1,6 @@ | ||
| 1 | +import { createFileRoute } from "@tanstack/react-router"; | |
| 2 | +import { ToolsPage } from "@executor/react/pages/tools"; | |
| 3 | + | |
| 4 | +export const Route = createFileRoute("/tools")({ | |
| 5 | + component: ToolsPage, | |
| 6 | +}); | |
| @@ -0,0 +1,14 @@ | ||
| 1 | +import { createFileRoute } from "@tanstack/react-router"; | |
| 2 | +import { handleApiRequest } from "../server/api-handler"; | |
| 3 | + | |
| 4 | +export const Route = createFileRoute("/v1/$")({ | |
| 5 | + server: { | |
| 6 | + handlers: { | |
| 7 | + GET: ({ request }) => handleApiRequest(request), | |
| 8 | + POST: ({ request }) => handleApiRequest(request), | |
| 9 | + PUT: ({ request }) => handleApiRequest(request), | |
| 10 | + DELETE: ({ request }) => handleApiRequest(request), | |
| 11 | + PATCH: ({ request }) => handleApiRequest(request), | |
| 12 | + }, | |
| 13 | + }, | |
| 14 | +}); | |
| @@ -0,0 +1,29 @@ | ||
| 1 | +type ServerHandlers = { | |
| 2 | + readonly api: { | |
| 3 | + readonly handler: (request: Request) => Promise<Response>; | |
| 4 | + readonly dispose: () => Promise<void>; | |
| 5 | + }; | |
| 6 | + readonly mcp: { | |
| 7 | + readonly handleRequest: (request: Request) => Promise<Response>; | |
| 8 | + readonly close: () => Promise<void>; | |
| 9 | + }; | |
| 10 | +}; | |
| 11 | + | |
| 12 | +let handlersPromise: Promise<ServerHandlers> | null = null; | |
| 13 | + | |
| 14 | +const getHandlers = () => { | |
| 15 | + if (!handlersPromise) { | |
| 16 | + handlersPromise = import("./main").then((mod) => mod.createServerHandlers()); | |
| 17 | + } | |
| 18 | + return handlersPromise; | |
| 19 | +}; | |
| 20 | + | |
| 21 | +export const handleApiRequest = async (request: Request): Promise<Response> => { | |
| 22 | + const handlers = await getHandlers(); | |
| 23 | + return handlers.api.handler(request); | |
| 24 | +}; | |
| 25 | + | |
| 26 | +export const handleMcpRequest = async (request: Request): Promise<Response> => { | |
| 27 | + const handlers = await getHandlers(); | |
| 28 | + return handlers.mcp.handleRequest(request); | |
| 29 | +}; | |
| @@ -1,17 +0,0 @@ | ||
| 1 | −import { createServerHandlers, type ServerHandlers } from "./main"; | |
| 2 | − | |
| 3 | −export type HotBackend = ServerHandlers & { | |
| 4 | − readonly dispose: () => Promise<void>; | |
| 5 | −}; | |
| 6 | − | |
| 7 | −export const createHotBackend = async (): Promise<HotBackend> => { | |
| 8 | − const handlers = await createServerHandlers(); | |
| 9 | − | |
| 10 | − return { | |
| 11 | − ...handlers, | |
| 12 | − dispose: async () => { | |
| 13 | − await handlers.api.dispose().catch(() => undefined); | |
| 14 | − await handlers.mcp.close().catch(() => undefined); | |
| 15 | − }, | |
| 16 | − }; | |
| 17 | −}; | |
| @@ -0,0 +1 @@ | ||
| 1 | +/// <reference types="vite/client" /> | |
| @@ -1,6 +0,0 @@ | ||
| 1 | −import { RouterProvider } from "@tanstack/react-router"; | |
| 2 | −import { router } from "./router"; | |
| 3 | − | |
| 4 | −export function App() { | |
| 5 | − return <RouterProvider router={router} />; | |
| 6 | −} | |
| @@ -1,7 +0,0 @@ | ||
| 1 | −import React from "react"; | |
| 2 | −import { createRoot } from "react-dom/client"; | |
| 3 | −import "@executor/react/globals.css"; | |
| 4 | −import { App } from "./App"; | |
| 5 | − | |
| 6 | −const root = createRoot(document.getElementById("root")!); | |
| 7 | −root.render(<App />); | |
| @@ -1,93 +0,0 @@ | ||
| 1 | −import { | |
| 2 | − createRouter, | |
| 3 | − createRootRoute, | |
| 4 | − createRoute, | |
| 5 | −} from "@tanstack/react-router"; | |
| 6 | −import { ExecutorProvider } from "@executor/react/api/provider"; | |
| 7 | −import { ToolsPage } from "@executor/react/pages/tools"; | |
| 8 | −import { SourcesPage } from "@executor/react/pages/sources"; | |
| 9 | −import { SourcesAddPage } from "@executor/react/pages/sources-add"; | |
| 10 | −import { SourceDetailPage } from "@executor/react/pages/source-detail"; | |
| 11 | −import { SecretsPage } from "@executor/react/pages/secrets"; | |
| 12 | −import { Shell } from "./shell"; | |
| 13 | − | |
| 14 | −// --------------------------------------------------------------------------- | |
| 15 | −// Root layout — Shell renders <Outlet /> directly | |
| 16 | −// --------------------------------------------------------------------------- | |
| 17 | − | |
| 18 | −const rootRoute = createRootRoute({ | |
| 19 | − component: () => ( | |
| 20 | − <ExecutorProvider> | |
| 21 | − <Shell /> | |
| 22 | − </ExecutorProvider> | |
| 23 | − ), | |
| 24 | −}); | |
| 25 | − | |
| 26 | −// --------------------------------------------------------------------------- | |
| 27 | −// Routes | |
| 28 | −// --------------------------------------------------------------------------- | |
| 29 | − | |
| 30 | −const indexRoute = createRoute({ | |
| 31 | − getParentRoute: () => rootRoute, | |
| 32 | − path: "/", | |
| 33 | − component: SourcesPage, | |
| 34 | −}); | |
| 35 | − | |
| 36 | −const toolsRoute = createRoute({ | |
| 37 | − getParentRoute: () => rootRoute, | |
| 38 | − path: "/tools", | |
| 39 | − component: ToolsPage, | |
| 40 | −}); | |
| 41 | − | |
| 42 | −const sourcesAddRoute = createRoute({ | |
| 43 | − getParentRoute: () => rootRoute, | |
| 44 | − path: "/sources/add/$pluginKey", | |
| 45 | − validateSearch: ( | |
| 46 | − search: Record<string, unknown>, | |
| 47 | − ): { url?: string; preset?: string } => ({ | |
| 48 | − url: typeof search.url === "string" ? search.url : undefined, | |
| 49 | − preset: typeof search.preset === "string" ? search.preset : undefined, | |
| 50 | − }), | |
| 51 | − component: () => { | |
| 52 | − const { pluginKey } = sourcesAddRoute.useParams(); | |
| 53 | − const { url, preset } = sourcesAddRoute.useSearch(); | |
| 54 | − return ( | |
| 55 | − <SourcesAddPage pluginKey={pluginKey} url={url} preset={preset} /> | |
| 56 | − ); | |
| 57 | − }, | |
| 58 | −}); | |
| 59 | − | |
| 60 | −const sourceDetailRoute = createRoute({ | |
| 61 | − getParentRoute: () => rootRoute, | |
| 62 | − path: "/sources/$namespace", | |
| 63 | − component: () => { | |
| 64 | − const { namespace } = sourceDetailRoute.useParams(); | |
| 65 | − return <SourceDetailPage namespace={namespace} />; | |
| 66 | − }, | |
| 67 | −}); | |
| 68 | − | |
| 69 | −const secretsRoute = createRoute({ | |
| 70 | − getParentRoute: () => rootRoute, | |
| 71 | − path: "/secrets", | |
| 72 | − component: SecretsPage, | |
| 73 | −}); | |
| 74 | − | |
| 75 | −// --------------------------------------------------------------------------- | |
| 76 | −// Router | |
| 77 | −// --------------------------------------------------------------------------- | |
| 78 | − | |
| 79 | −const routeTree = rootRoute.addChildren([ | |
| 80 | − indexRoute, | |
| 81 | − toolsRoute, | |
| 82 | − sourcesAddRoute, | |
| 83 | − sourceDetailRoute, | |
| 84 | − secretsRoute, | |
| 85 | −]); | |
| 86 | − | |
| 87 | −export const router = createRouter({ routeTree }); | |
| 88 | − | |
| 89 | −declare module "@tanstack/react-router" { | |
| 90 | − interface Register { | |
| 91 | − router: typeof router; | |
| 92 | − } | |
| 93 | −} | |
| @@ -450,7 +450,6 @@ export function Shell() { · 449 unmodified lines | ||
| 450 | 450 | <div className="w-8 shrink-0" /> |
| 451 | 451 | </div> |
| 452 | 452 | |
| 453 | − {/* Outlet — pages control their own padding/scroll */} | |
| 454 | 453 | <Outlet /> |
| 455 | 454 | </main> |
| 456 | 455 | </div> |
| @@ -1,86 +1,9 @@ | ||
| 1 | 1 | import { readFileSync } from "node:fs"; |
| 2 | −import { resolve } from "node:path"; | |
| 3 | 2 | import { defineConfig } from "vite"; |
| 3 | +import { tanstackStart } from "@tanstack/react-start/plugin/vite"; | |
| 4 | 4 | import react from "@vitejs/plugin-react"; |
| 5 | 5 | import tailwindcss from "@tailwindcss/vite"; |
| 6 | 6 | |
| 7 | −type HotBackend = { | |
| 8 | − readonly api: { | |
| 9 | − readonly handler: (request: Request) => Promise<Response>; | |
| 10 | − readonly dispose: () => Promise<void>; | |
| 11 | − }; | |
| 12 | − readonly mcp: { | |
| 13 | − readonly handleRequest: (request: Request) => Promise<Response>; | |
| 14 | − readonly close: () => Promise<void>; | |
| 15 | − }; | |
| 16 | − readonly dispose: () => Promise<void>; | |
| 17 | −}; | |
| 18 | − | |
| 19 | −const DEV_BACKEND_MODULE_ID = `/@fs/${resolve( | |
| 20 | − process.cwd(), | |
| 21 | − "src/server/dev-backend.ts", | |
| 22 | −).replace(/\\/g, "/")}`; | |
| 23 | − | |
| 24 | −// Build a Web Request from a Node IncomingMessage | |
| 25 | −const toWebRequest = async ( | |
| 26 | − req: import("http").IncomingMessage, | |
| 27 | −): Promise<Request> => { | |
| 28 | − const headers = new Headers(); | |
| 29 | − for (const [key, value] of Object.entries(req.headers)) { | |
| 30 | − if (value === undefined) continue; | |
| 31 | − if (Array.isArray(value)) { | |
| 32 | − for (const v of value) headers.append(key, v); | |
| 33 | − } else { | |
| 34 | − headers.set(key, value); | |
| 35 | − } | |
| 36 | − } | |
| 37 | − | |
| 38 | − const host = req.headers.host ?? "localhost"; | |
| 39 | − const url = `http://${host}${req.url}`; | |
| 40 | − | |
| 41 | − return new Request( | |
| 42 | − url, | |
| 43 | − { | |
| 44 | − method: req.method, | |
| 45 | − headers, | |
| 46 | − body: | |
| 47 | − req.method !== "GET" && req.method !== "HEAD" | |
| 48 | − ? (await new Promise<Buffer>((resolve) => { | |
| 49 | − const chunks: Buffer[] = []; | |
| 50 | − req.on("data", (c: Buffer) => chunks.push(c)); | |
| 51 | − req.on("end", () => resolve(Buffer.concat(chunks))); | |
| 52 | − }) as unknown as BodyInit) | |
| 53 | − : undefined, | |
| 54 | − duplex: "half" as const, | |
| 55 | − } as RequestInit & { duplex: "half" }, | |
| 56 | − ); | |
| 57 | −}; | |
| 58 | − | |
| 59 | −// Pipe a Web Response back to a Node ServerResponse, streaming if needed | |
| 60 | −const sendWebResponse = async ( | |
| 61 | − webRes: Response, | |
| 62 | − nodeRes: import("http").ServerResponse, | |
| 63 | −) => { | |
| 64 | − nodeRes.statusCode = webRes.status; | |
| 65 | − webRes.headers.forEach((value, key) => nodeRes.setHeader(key, value)); | |
| 66 | − | |
| 67 | − if (!webRes.body) { | |
| 68 | − nodeRes.end(); | |
| 69 | − return; | |
| 70 | − } | |
| 71 | − | |
| 72 | − const reader = webRes.body.getReader(); | |
| 73 | − try { | |
| 74 | − for (;;) { | |
| 75 | − const { done, value } = await reader.read(); | |
| 76 | − if (done) break; | |
| 77 | − nodeRes.write(value); | |
| 78 | − } | |
| 79 | − } finally { | |
| 80 | − nodeRes.end(); | |
| 81 | − } | |
| 82 | −}; | |
| 83 | − | |
| 84 | 7 | const rootPackage = JSON.parse( |
| 85 | 8 | readFileSync(new URL("../../package.json", import.meta.url), "utf8"), |
| 86 | 9 | ) as { version: string; homepage?: string; repository?: string | { url?: string } }; |
| @@ -106,111 +29,25 @@ export default defineConfig({ · 19 unmodified lines | ||
| 106 | 29 | }, |
| 107 | 30 | resolve: { |
| 108 | 31 | dedupe: ["react", "react-dom"], |
| 32 | + tsconfigPaths: true, | |
| 33 | + }, | |
| 34 | + server: { | |
| 35 | + port: parseInt(process.env.PORT ?? "5173", 10), | |
| 36 | + host: "127.0.0.1", | |
| 37 | + }, | |
| 38 | + ssr: { | |
| 39 | + external: true, | |
| 40 | + }, | |
| 41 | + optimizeDeps: { | |
| 42 | + rolldownOptions: { | |
| 43 | + external: [/^@napi-rs\//], | |
| 44 | + }, | |
| 109 | 45 | }, |
| 110 | 46 | plugins: [ |
| 111 | − react(), | |
| 112 | 47 | tailwindcss(), |
| 113 | − { | |
| 114 | − name: "executor-api", | |
| 115 | − configureServer(server) { | |
| 116 | − let backendPromise: Promise<HotBackend> | null = null; | |
| 117 | − let reloadPromise: Promise<void> | null = null; | |
| 118 | − | |
| 119 | − const loadBackend = () => | |
| 120 | − server | |
| 121 | − .ssrLoadModule(DEV_BACKEND_MODULE_ID) | |
| 122 | − .then((mod) => mod.createHotBackend() as Promise<HotBackend>); | |
| 123 | − | |
| 124 | − const getBackend = () => { | |
| 125 | − if (!backendPromise) { | |
| 126 | − backendPromise = loadBackend(); | |
| 127 | − } | |
| 128 | − return backendPromise; | |
| 129 | − }; | |
| 130 | − | |
| 131 | − const shouldReloadBackend = (file: string) => | |
| 132 | − /\.(ts|tsx)$/.test(file) && | |
| 133 | − !file.includes("/src/web/") && | |
| 134 | − ( | |
| 135 | − file.includes("/src/server/") || | |
| 136 | − file.includes("/packages/core/") || | |
| 137 | − file.includes("/packages/plugins/") || | |
| 138 | − file.includes("/packages/hosts/") | |
| 139 | − ); | |
| 140 | − | |
| 141 | − server.httpServer?.once("close", () => { | |
| 142 | − const pending = backendPromise; | |
| 143 | − backendPromise = null; | |
| 144 | − void pending?.then((backend) => backend.dispose()).catch(() => undefined); | |
| 145 | − }); | |
| 146 | − | |
| 147 | − server.watcher.on("change", (file) => { | |
| 148 | − if (!shouldReloadBackend(file) || reloadPromise) { | |
| 149 | − return; | |
| 150 | − } | |
| 151 | − | |
| 152 | − reloadPromise = (async () => { | |
| 153 | − server.config.logger.info(`[executor-api] hot reloading backend: ${file}`); | |
| 154 | − | |
| 155 | − const previous = await getBackend().catch(() => null); | |
| 156 | − | |
| 157 | − server.moduleGraph.invalidateAll(); | |
| 158 | − backendPromise = loadBackend(); | |
| 159 | − | |
| 160 | − await backendPromise; | |
| 161 | − await previous?.dispose().catch(() => undefined); | |
| 162 | − | |
| 163 | − server.ws.send({ | |
| 164 | − type: "custom", | |
| 165 | − event: "executor:backend-updated", | |
| 166 | − data: { file }, | |
| 167 | − }); | |
| 168 | − })() | |
| 169 | − .catch((error) => { | |
| 170 | − server.config.logger.error( | |
| 171 | − `[executor-api] backend reload failed: ${error instanceof Error ? error.message : String(error)}`, | |
| 172 | − ); | |
| 173 | − }) | |
| 174 | − .finally(() => { | |
| 175 | − reloadPromise = null; | |
| 176 | − }); | |
| 177 | − }); | |
| 178 | − | |
| 179 | − // Host-header allowlist — blocks DNS rebinding attacks | |
| 180 | − const ALLOWED_HOSTS = new Set(["localhost", "127.0.0.1", "[::1]", "::1"]); | |
| 181 | − | |
| 182 | − server.middlewares.use(async (req, res, next) => { | |
| 183 | − const url = req.url ?? "/"; | |
| 184 | − | |
| 185 | − const isApi = | |
| 186 | − url.startsWith("/v1/") || | |
| 187 | − url.startsWith("/docs") || | |
| 188 | − url === "/openapi.json"; | |
| 189 | − const isMcp = url.startsWith("/mcp"); | |
| 190 | − | |
| 191 | − if (!isApi && !isMcp) return next(); | |
| 192 | − | |
| 193 | − // Validate host header to prevent DNS rebinding | |
| 194 | − const host = req.headers.host; | |
| 195 | − if (host) { | |
| 196 | − const hostname = host.replace(/:\d+$/, ""); | |
| 197 | − if (!ALLOWED_HOSTS.has(hostname)) { | |
| 198 | − res.statusCode = 403; | |
| 199 | − res.end("Forbidden"); | |
| 200 | − return; | |
| 201 | − } | |
| 202 | − } | |
| 203 | − | |
| 204 | − const backend = await getBackend(); | |
| 205 | − const request = await toWebRequest(req); | |
| 206 | − | |
| 207 | − const response = isMcp | |
| 208 | − ? await backend.mcp.handleRequest(request) | |
| 209 | − : await backend.api.handler(request); | |
| 210 | − | |
| 211 | − await sendWebResponse(response, res); | |
| 212 | − }); | |
| 213 | − }, | |
| 214 | − }, | |
| 48 | + tanstackStart({ | |
| 49 | + spa: { enabled: true }, | |
| 50 | + }), | |
| 51 | + ...react(), | |
| 215 | 52 | ], |
| 216 | 53 | }); |
| @@ -18,7 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | }, |
| 19 | 19 | "apps/cli": { |
| 20 | 20 | "name": "executor", |
| 21 | − "version": "1.4.1", | |
| 21 | + "version": "1.4.2", | |
| 22 | 22 | "bin": { |
| 23 | 23 | "executor": "./bin/executor.ts", |
| 24 | 24 | }, |
| @@ -35,7 +35,7 @@ · 10 unmodified lines | ||
| 35 | 35 | }, |
| 36 | 36 | "devDependencies": { |
| 37 | 37 | "bun-types": "catalog:", |
| 38 | − "typescript": "^5.9.3", | |
| 38 | + "typescript": "catalog:", | |
| 39 | 39 | }, |
| 40 | 40 | }, |
| 41 | 41 | "apps/cloud": { |
| @@ -53,24 +53,25 @@ · 11 unmodified lines | ||
| 53 | 53 | "@executor/react": "workspace:*", |
| 54 | 54 | "@executor/sdk": "workspace:*", |
| 55 | 55 | "@executor/storage-postgres": "workspace:*", |
| 56 | − "@tanstack/react-router": "^1.168.10", | |
| 56 | + "@tanstack/react-router": "catalog:", | |
| 57 | + "@tanstack/react-start": "catalog:", | |
| 57 | 58 | "@workos-inc/node": "^7.0.0", |
| 58 | 59 | "drizzle-orm": "catalog:", |
| 59 | 60 | "effect": "catalog:", |
| 60 | 61 | "pg": "^8.16.0", |
| 61 | − "react": "^19.1.0", | |
| 62 | − "react-dom": "^19.1.0", | |
| 62 | + "react": "catalog:", | |
| 63 | + "react-dom": "catalog:", | |
| 63 | 64 | }, |
| 64 | 65 | "devDependencies": { |
| 65 | 66 | "@electric-sql/pglite": "^0.4.3", |
| 66 | − "@tailwindcss/vite": "^4.1.10", | |
| 67 | + "@tailwindcss/vite": "catalog:", | |
| 67 | 68 | "@types/pg": "^8.15.4", |
| 68 | − "@types/react": "^19.1.0", | |
| 69 | − "@types/react-dom": "^19.1.0", | |
| 70 | − "@vitejs/plugin-react": "^4.5.2", | |
| 69 | + "@types/react": "catalog:", | |
| 70 | + "@types/react-dom": "catalog:", | |
| 71 | + "@vitejs/plugin-react": "catalog:", | |
| 71 | 72 | "portless": "^0.3.0", |
| 72 | − "typescript": "^5.9.3", | |
| 73 | − "vite": "^6.3.5", | |
| 73 | + "typescript": "catalog:", | |
| 74 | + "vite": "catalog:", | |
| 74 | 75 | }, |
| 75 | 76 | }, |
| 76 | 77 | "apps/desktop": { |
| @@ -80,7 +81,7 @@ · 3 unmodified lines | ||
| 80 | 81 | "@types/node": "catalog:", |
| 81 | 82 | "electron": "35.7.5", |
| 82 | 83 | "electron-builder": "^26.0.12", |
| 83 | − "typescript": "^5.9.3", | |
| 84 | + "typescript": "catalog:", | |
| 84 | 85 | }, |
| 85 | 86 | }, |
| 86 | 87 | "apps/local": { |
| @@ -108,23 +109,24 @@ · 21 unmodified lines | ||
| 108 | 109 | "@modelcontextprotocol/sdk": "^1.12.1", |
| 109 | 110 | "@shikijs/langs": "^4.0.2", |
| 110 | 111 | "@shikijs/themes": "^4.0.2", |
| 111 | − "@tanstack/react-router": "^1.168.10", | |
| 112 | + "@tanstack/react-router": "catalog:", | |
| 113 | + "@tanstack/react-start": "catalog:", | |
| 112 | 114 | "effect": "catalog:", |
| 113 | − "react": "^19.1.0", | |
| 114 | − "react-dom": "^19.1.0", | |
| 115 | + "react": "catalog:", | |
| 116 | + "react-dom": "catalog:", | |
| 115 | 117 | "shiki": "^4.0.2", |
| 116 | 118 | "streamdown": "^2.5.0", |
| 117 | − "tailwindcss": "^4.1.10", | |
| 119 | + "tailwindcss": "catalog:", | |
| 118 | 120 | }, |
| 119 | 121 | "devDependencies": { |
| 120 | − "@tailwindcss/vite": "^4.1.10", | |
| 122 | + "@tailwindcss/vite": "catalog:", | |
| 121 | 123 | "@types/node": "catalog:", |
| 122 | − "@types/react": "^19.1.0", | |
| 123 | − "@types/react-dom": "^19.1.0", | |
| 124 | − "@vitejs/plugin-react": "^4.5.2", | |
| 124 | + "@types/react": "catalog:", | |
| 125 | + "@types/react-dom": "catalog:", | |
| 126 | + "@vitejs/plugin-react": "catalog:", | |
| 125 | 127 | "bun-types": "catalog:", |
| 126 | − "typescript": "^5.9.3", | |
| 127 | − "vite": "^6.3.5", | |
| 128 | + "typescript": "catalog:", | |
| 129 | + "vite": "catalog:", | |
| 128 | 130 | }, |
| 129 | 131 | }, |
| 130 | 132 | "apps/marketing": { |
| @@ -133,8 +135,13 @@ · 2 unmodified lines | ||
| 133 | 135 | "dependencies": { |
| 134 | 136 | "@astrojs/tailwind": "^6.0.2", |
| 135 | 137 | "@astrojs/vercel": "^10.0.4", |
| 138 | + "@executor/plugin-google-discovery": "workspace:*", | |
| 139 | + "@executor/plugin-graphql": "workspace:*", | |
| 140 | + "@executor/plugin-openapi": "workspace:*", | |
| 141 | + "@executor/sdk": "workspace:*", | |
| 136 | 142 | "@tailwindcss/vite": "^4.2.2", |
| 137 | 143 | "astro": "^6.1.3", |
| 144 | + "effect": "^3.14.16", | |
| 138 | 145 | "tailwindcss": "^4.2.2", |
| 139 | 146 | }, |
| 140 | 147 | }, |
| @@ -150,7 +157,7 @@ · 9 unmodified lines | ||
| 150 | 157 | "devDependencies": { |
| 151 | 158 | "@types/node": "catalog:", |
| 152 | 159 | "bun-types": "catalog:", |
| 153 | − "typescript": "^5.9.3", | |
| 160 | + "typescript": "catalog:", | |
| 154 | 161 | }, |
| 155 | 162 | }, |
| 156 | 163 | "packages/core/config": { |
| @@ -165,7 +172,7 @@ · 8 unmodified lines | ||
| 165 | 172 | "devDependencies": { |
| 166 | 173 | "@effect/platform-node": "catalog:", |
| 167 | 174 | "@effect/vitest": "catalog:", |
| 168 | − "typescript": "latest", | |
| 175 | + "typescript": "catalog:", | |
| 169 | 176 | "vitest": "catalog:", |
| 170 | 177 | }, |
| 171 | 178 | }, |
| @@ -193,7 +200,7 @@ · 21 unmodified lines | ||
| 193 | 200 | }, |
| 194 | 201 | "devDependencies": { |
| 195 | 202 | "@effect/vitest": "catalog:", |
| 196 | − "typescript": "latest", | |
| 203 | + "typescript": "catalog:", | |
| 197 | 204 | "vitest": "catalog:", |
| 198 | 205 | }, |
| 199 | 206 | }, |
| @@ -209,7 +216,7 @@ · 9 unmodified lines | ||
| 209 | 216 | "@effect/experimental": "catalog:", |
| 210 | 217 | "@effect/sql-sqlite-node": "catalog:", |
| 211 | 218 | "@effect/vitest": "catalog:", |
| 212 | − "typescript": "^5.9.3", | |
| 219 | + "typescript": "catalog:", | |
| 213 | 220 | "vitest": "catalog:", |
| 214 | 221 | }, |
| 215 | 222 | }, |
| @@ -229,7 +236,7 @@ · 13 unmodified lines | ||
| 229 | 236 | "@electric-sql/pglite": "^0.4.3", |
| 230 | 237 | "@types/pg": "^8.15.4", |
| 231 | 238 | "drizzle-kit": "^0.31.0", |
| 232 | − "typescript": "^5.9.3", | |
| 239 | + "typescript": "catalog:", | |
| 233 | 240 | "vitest": "catalog:", |
| 234 | 241 | }, |
| 235 | 242 | }, |
| @@ -337,16 +344,16 @@ · 101 unmodified lines | ||
| 337 | 344 | "@effect/vitest": "catalog:", |
| 338 | 345 | "@executor/react": "workspace:*", |
| 339 | 346 | "@types/node": "catalog:", |
| 340 | − "@types/react": "^19.1.0", | |
| 347 | + "@types/react": "catalog:", | |
| 341 | 348 | "bun-types": "catalog:", |
| 342 | − "react": "^19.1.0", | |
| 349 | + "react": "catalog:", | |
| 343 | 350 | "vitest": "catalog:", |
| 344 | 351 | }, |
| 345 | 352 | "peerDependencies": { |
| 346 | 353 | "@effect-atom/atom-react": "^0.5.0", |
| 347 | 354 | "@executor/react": "workspace:*", |
| 348 | − "@tanstack/react-router": "^1.168.10", | |
| 349 | − "react": "^19.1.0", | |
| 355 | + "@tanstack/react-router": "catalog:", | |
| 356 | + "react": "catalog:", | |
| 350 | 357 | }, |
| 351 | 358 | "optionalPeers": [ |
| 352 | 359 | "@effect-atom/atom-react", |
| @@ -370,17 +377,17 @@ · 17 unmodified lines | ||
| 370 | 377 | "@executor/api": "workspace:*", |
| 371 | 378 | "@executor/react": "workspace:*", |
| 372 | 379 | "@types/node": "catalog:", |
| 373 | − "@types/react": "^19.1.0", | |
| 380 | + "@types/react": "catalog:", | |
| 374 | 381 | "bun-types": "catalog:", |
| 375 | − "react": "^19.1.0", | |
| 382 | + "react": "catalog:", | |
| 376 | 383 | "vitest": "catalog:", |
| 377 | 384 | }, |
| 378 | 385 | "peerDependencies": { |
| 379 | 386 | "@effect-atom/atom-react": "^0.5.0", |
| 380 | 387 | "@executor/api": "workspace:*", |
| 381 | 388 | "@executor/react": "workspace:*", |
| 382 | − "@tanstack/react-router": "^1.168.10", | |
| 383 | − "react": "^19.1.0", | |
| 389 | + "@tanstack/react-router": "catalog:", | |
| 390 | + "react": "catalog:", | |
| 384 | 391 | }, |
| 385 | 392 | "optionalPeers": [ |
| 386 | 393 | "@effect-atom/atom-react", |
| @@ -421,9 +428,9 @@ · 34 unmodified lines | ||
| 421 | 428 | "@executor/api": "workspace:*", |
| 422 | 429 | "@executor/react": "workspace:*", |
| 423 | 430 | "@types/node": "catalog:", |
| 424 | − "@types/react": "^19.1.0", | |
| 431 | + "@types/react": "catalog:", | |
| 425 | 432 | "bun-types": "catalog:", |
| 426 | − "react": "^19.1.0", | |
| 433 | + "react": "catalog:", | |
| 427 | 434 | "vitest": "catalog:", |
| 428 | 435 | "zod": "^4.3.6", |
| 429 | 436 | }, |
| @@ -431,8 +438,8 @@ · 1 unmodified line | ||
| 431 | 438 | "@effect-atom/atom-react": "^0.5.0", |
| 432 | 439 | "@executor/api": "workspace:*", |
| 433 | 440 | "@executor/react": "workspace:*", |
| 434 | − "@tanstack/react-router": "^1.168.10", | |
| 435 | − "react": "^19.1.0", | |
| 441 | + "@tanstack/react-router": "catalog:", | |
| 442 | + "react": "catalog:", | |
| 436 | 443 | }, |
| 437 | 444 | "optionalPeers": [ |
| 438 | 445 | "@effect-atom/atom-react", |
| @@ -457,9 +464,9 @@ · 18 unmodified lines | ||
| 457 | 464 | "devDependencies": { |
| 458 | 465 | "@effect/vitest": "catalog:", |
| 459 | 466 | "@types/node": "catalog:", |
| 460 | − "@types/react": "^19.1.0", | |
| 467 | + "@types/react": "catalog:", | |
| 461 | 468 | "bun-types": "catalog:", |
| 462 | − "react": "^19.1.0", | |
| 469 | + "react": "catalog:", | |
| 463 | 470 | "vitest": "catalog:", |
| 464 | 471 | }, |
| 465 | 472 | "peerDependencies": { |
| @@ -491,17 +498,17 @@ · 25 unmodified lines | ||
| 491 | 498 | "@executor/api": "workspace:*", |
| 492 | 499 | "@executor/react": "workspace:*", |
| 493 | 500 | "@types/node": "catalog:", |
| 494 | − "@types/react": "^19.1.0", | |
| 501 | + "@types/react": "catalog:", | |
| 495 | 502 | "bun-types": "catalog:", |
| 496 | − "react": "^19.1.0", | |
| 503 | + "react": "catalog:", | |
| 497 | 504 | "vitest": "catalog:", |
| 498 | 505 | }, |
| 499 | 506 | "peerDependencies": { |
| 500 | 507 | "@effect-atom/atom-react": "^0.5.0", |
| 501 | 508 | "@executor/api": "workspace:*", |
| 502 | 509 | "@executor/react": "workspace:*", |
| 503 | − "@tanstack/react-router": "^1.168.10", | |
| 504 | − "react": "^19.1.0", | |
| 510 | + "@tanstack/react-router": "catalog:", | |
| 511 | + "react": "catalog:", | |
| 505 | 512 | }, |
| 506 | 513 | "optionalPeers": [ |
| 507 | 514 | "@effect-atom/atom-react", |
| @@ -534,7 +541,7 @@ · 26 unmodified lines | ||
| 534 | 541 | "lucide-react": "^1.7.0", |
| 535 | 542 | "next-themes": "^0.4.6", |
| 536 | 543 | "radix-ui": "^1.4.3", |
| 537 | − "react": "^19.1.0", | |
| 544 | + "react": "catalog:", | |
| 538 | 545 | "react-day-picker": "^9.14.0", |
| 539 | 546 | "react-hook-form": "^7.72.0", |
| 540 | 547 | "react-resizable-panels": "^4", |
| @@ -548,10 +555,10 @@ · 7 unmodified lines | ||
| 548 | 555 | }, |
| 549 | 556 | "devDependencies": { |
| 550 | 557 | "@types/node": "catalog:", |
| 551 | − "@types/react": "^19.1.0", | |
| 558 | + "@types/react": "catalog:", | |
| 552 | 559 | "hast-util-to-jsx-runtime": "^2.3.6", |
| 553 | − "tailwindcss": "^4.1.10", | |
| 554 | − "typescript": "^5.9.3", | |
| 560 | + "tailwindcss": "catalog:", | |
| 561 | + "typescript": "catalog:", | |
| 555 | 562 | }, |
| 556 | 563 | }, |
| 557 | 564 | }, |
| @@ -566,10 +573,21 @@ · 8 unmodified lines | ||
| 566 | 573 | "@effect/sql-sqlite-bun": "^0.52.0", |
| 567 | 574 | "@effect/sql-sqlite-node": "^0.52.0", |
| 568 | 575 | "@effect/vitest": "^0.27.0", |
| 576 | + "@tailwindcss/vite": "^4.2.2", | |
| 577 | + "@tanstack/react-router": "^1.168.10", | |
| 578 | + "@tanstack/react-start": "^1.167.16", | |
| 569 | 579 | "@types/node": "^24.3.1", |
| 580 | + "@types/react": "^19.1.0", | |
| 581 | + "@types/react-dom": "^19.1.0", | |
| 582 | + "@vitejs/plugin-react": "^6.0.1", | |
| 570 | 583 | "bun-types": "^1.2.22", |
| 571 | 584 | "drizzle-orm": "^0.44.0", |
| 572 | 585 | "effect": "^3.21.0", |
| 586 | + "react": "^19.1.0", | |
| 587 | + "react-dom": "^19.1.0", | |
| 588 | + "tailwindcss": "^4.2.2", | |
| 589 | + "typescript": "^5.9.3", | |
| 590 | + "vite": "^8.0.0", | |
| 573 | 591 | "vitest": "^3.2.4", |
| 574 | 592 | }, |
| 575 | 593 | "packages": { |
| @@ -605,7 +623,7 @@ · 29 unmodified lines | ||
| 605 | 623 | |
| 606 | 624 | "@astrojs/vercel": ["@astrojs/vercel@10.0.4", "", { "dependencies": { "@astrojs/internal-helpers": "0.8.0", "@vercel/analytics": "^1.6.1", "@vercel/functions": "^3.4.3", "@vercel/nft": "^1.3.2", "@vercel/routing-utils": "^5.3.3", "esbuild": "^0.27.3", "tinyglobby": "^0.2.15" }, "peerDependencies": { "astro": "^6.0.0" } }, "sha512-+kxbLKCimr9ivqXTldE3JyXB6Ks7WU6C8jcZGt+CLM9N1IVCWck9ustz3Hd/OGROQpzRATLVvrlbwyeM7Gycpw=="], |
| 607 | 625 | |
| 608 | − "@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="], | |
| 626 | + "@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=="], | |
| 609 | 627 | |
| 610 | 628 | "@babel/compat-data": ["@babel/compat-data@7.29.0", "", {}, "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg=="], |
| 611 | 629 | |
| @@ -633,9 +651,9 @@ · 21 unmodified lines | ||
| 633 | 651 | |
| 634 | 652 | "@babel/parser": ["@babel/parser@7.29.2", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA=="], |
| 635 | 653 | |
| 636 | − "@babel/plugin-transform-react-jsx-self": ["@babel/plugin-transform-react-jsx-self@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw=="], | |
| 654 | + "@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=="], | |
| 637 | 655 | |
| 638 | − "@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=="], | |
| 656 | + "@babel/plugin-syntax-typescript": ["@babel/plugin-syntax-typescript@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A=="], | |
| 639 | 657 | |
| 640 | 658 | "@babel/runtime": ["@babel/runtime@7.29.2", "", {}, "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g=="], |
| 641 | 659 | |
| @@ -765,8 +783,12 @@ · 123 unmodified lines | ||
| 765 | 783 | |
| 766 | 784 | "@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=="], |
| 767 | 785 | |
| 786 | + "@emnapi/core": ["@emnapi/core@1.9.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" } }, "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA=="], | |
| 787 | + | |
| 768 | 788 | "@emnapi/runtime": ["@emnapi/runtime@1.9.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA=="], |
| 769 | 789 | |
| 790 | + "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg=="], | |
| 791 | + | |
| 770 | 792 | "@esbuild-kit/core-utils": ["@esbuild-kit/core-utils@3.3.2", "", { "dependencies": { "esbuild": "~0.18.20", "source-map-support": "^0.5.21" } }, "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ=="], |
| 771 | 793 | |
| 772 | 794 | "@esbuild-kit/esm-loader": ["@esbuild-kit/esm-loader@2.6.5", "", { "dependencies": { "@esbuild-kit/core-utils": "^3.3.2", "get-tsconfig": "^4.7.0" } }, "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA=="], |
| @@ -1013,6 +1035,8 @@ · 240 unmodified lines | ||
| 1013 | 1035 | |
| 1014 | 1036 | "@napi-rs/keyring-win32-x64-msvc": ["@napi-rs/keyring-win32-x64-msvc@1.2.0", "", { "os": "win32", "cpu": "x64" }, "sha512-xFlx/TsmqmCwNU9v+AVnEJgoEAlBYgzFF5Ihz1rMpPAt4qQWWkMd4sCyM1gMJ1A/GnRqRegDiQpwaxGUHFtFbA=="], |
| 1015 | 1037 | |
| 1038 | + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.2", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw=="], | |
| 1039 | + | |
| 1016 | 1040 | "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], |
| 1017 | 1041 | |
| 1018 | 1042 | "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], |
| @@ -1023,10 +1047,20 @@ · 4 unmodified lines | ||
| 1023 | 1047 | |
| 1024 | 1048 | "@npmcli/fs": ["@npmcli/fs@4.0.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q=="], |
| 1025 | 1049 | |
| 1050 | + "@oozcitak/dom": ["@oozcitak/dom@2.0.2", "", { "dependencies": { "@oozcitak/infra": "^2.0.2", "@oozcitak/url": "^3.0.0", "@oozcitak/util": "^10.0.0" } }, "sha512-GjpKhkSYC3Mj4+lfwEyI1dqnsKTgwGy48ytZEhm4A/xnH/8z9M3ZVXKr/YGQi3uCLs1AEBS+x5T2JPiueEDW8w=="], | |
| 1051 | + | |
| 1052 | + "@oozcitak/infra": ["@oozcitak/infra@2.0.2", "", { "dependencies": { "@oozcitak/util": "^10.0.0" } }, "sha512-2g+E7hoE2dgCz/APPOEK5s3rMhJvNxSMBrP+U+j1OWsIbtSpWxxlUjq1lU8RIsFJNYv7NMlnVsCuHcUzJW+8vA=="], | |
| 1053 | + | |
| 1054 | + "@oozcitak/url": ["@oozcitak/url@3.0.0", "", { "dependencies": { "@oozcitak/infra": "^2.0.2", "@oozcitak/util": "^10.0.0" } }, "sha512-ZKfET8Ak1wsLAiLWNfFkZc/BraDccuTJKR6svTYc7sVjbR+Iu0vtXdiDMY4o6jaFl5TW2TlS7jbLl4VovtAJWQ=="], | |
| 1055 | + | |
| 1056 | + "@oozcitak/util": ["@oozcitak/util@10.0.0", "", {}, "sha512-hAX0pT/73190NLqBPPWSdBVGtbY6VOhWYK3qqHqtXQ1gK7kS2yz4+ivsN07hpJ6I3aeMtKP6J6npsEKOAzuTLA=="], | |
| 1057 | + | |
| 1026 | 1058 | "@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.40.0", "", {}, "sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw=="], |
| 1027 | 1059 | |
| 1028 | 1060 | "@oslojs/encoding": ["@oslojs/encoding@1.1.0", "", {}, "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ=="], |
| 1029 | 1061 | |
| 1062 | + "@oxc-project/types": ["@oxc-project/types@0.122.0", "", {}, "sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA=="], | |
| 1063 | + | |
| 1030 | 1064 | "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.58.0", "", { "os": "android", "cpu": "arm" }, "sha512-1T7UN3SsWWxpWyWGn1cT3ASNJOo+pI3eUkmEl7HgtowapcV8kslYpFQcYn431VuxghXakPNlbjRwhqmR37PFOg=="], |
| 1031 | 1065 | |
| 1032 | 1066 | "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.58.0", "", { "os": "android", "cpu": "arm64" }, "sha512-GryzujxuiRv2YFF7bRy8mKcxlbuAN+euVUtGJt9KKbLT8JBUIosamVhcthLh+VEr6KE6cjeVMAQxKAzJcoN7dg=="], |
| @@ -1223,7 +1257,37 @@ · 190 unmodified lines | ||
| 1223 | 1257 | |
| 1224 | 1258 | "@reduxjs/toolkit": ["@reduxjs/toolkit@2.11.2", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@standard-schema/utils": "^0.3.0", "immer": "^11.0.0", "redux": "^5.0.1", "redux-thunk": "^3.1.0", "reselect": "^5.1.0" }, "peerDependencies": { "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" }, "optionalPeers": ["react", "react-redux"] }, "sha512-Kd6kAHTA6/nUpp8mySPqj3en3dm0tdMIgbttnQ1xFMVpufoj+ADi8pXLBsd4xzTRHQa7t/Jv8W5UnCuW4kuWMQ=="], |
| 1225 | 1259 | |
| 1226 | − "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.27", "", {}, "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA=="], | |
| 1260 | + "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0-rc.12", "", { "os": "android", "cpu": "arm64" }, "sha512-pv1y2Fv0JybcykuiiD3qBOBdz6RteYojRFY1d+b95WVuzx211CRh+ytI/+9iVyWQ6koTh5dawe4S/yRfOFjgaA=="], | |
| 1261 | + | |
| 1262 | + "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0-rc.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-cFYr6zTG/3PXXF3pUO+umXxt1wkRK/0AYT8lDwuqvRC+LuKYWSAQAQZjCWDQpAH172ZV6ieYrNnFzVVcnSflAg=="], | |
| 1263 | + | |
| 1264 | + "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0-rc.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZCsYknnHzeXYps0lGBz8JrF37GpE9bFVefrlmDrAQhOEi4IOIlcoU1+FwHEtyXGx2VkYAvhu7dyBf75EJQffBw=="], | |
| 1265 | + | |
| 1266 | + "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0-rc.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-dMLeprcVsyJsKolRXyoTH3NL6qtsT0Y2xeuEA8WQJquWFXkEC4bcu1rLZZSnZRMtAqwtrF/Ib9Ddtpa/Gkge9Q=="], | |
| 1267 | + | |
| 1268 | + "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.12", "", { "os": "linux", "cpu": "arm" }, "sha512-YqWjAgGC/9M1lz3GR1r1rP79nMgo3mQiiA+Hfo+pvKFK1fAJ1bCi0ZQVh8noOqNacuY1qIcfyVfP6HoyBRZ85Q=="], | |
| 1269 | + | |
| 1270 | + "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0-rc.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-/I5AS4cIroLpslsmzXfwbe5OmWvSsrFuEw3mwvbQ1kDxJ822hFHIx+vsN/TAzNVyepI/j/GSzrtCIwQPeKCLIg=="], | |
| 1271 | + | |
| 1272 | + "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0-rc.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw=="], | |
| 1273 | + | |
| 1274 | + "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g=="], | |
| 1275 | + | |
| 1276 | + "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.0-rc.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og=="], | |
| 1277 | + | |
| 1278 | + "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0-rc.12", "", { "os": "linux", "cpu": "x64" }, "sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg=="], | |
| 1279 | + | |
| 1280 | + "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0-rc.12", "", { "os": "linux", "cpu": "x64" }, "sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig=="], | |
| 1281 | + | |
| 1282 | + "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0-rc.12", "", { "os": "none", "cpu": "arm64" }, "sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA=="], | |
| 1283 | + | |
| 1284 | + "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0-rc.12", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-ykGiLr/6kkiHc0XnBfmFJuCjr5ZYKKofkx+chJWDjitX+KsJuAmrzWhwyOMSHzPhzOHOy7u9HlFoa5MoAOJ/Zg=="], | |
| 1285 | + | |
| 1286 | + "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0-rc.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-5eOND4duWkwx1AzCxadcOrNeighiLwMInEADT0YM7xeEOOFcovWZCq8dadXgcRHSf3Ulh1kFo/qvzoFiCLOL1Q=="], | |
| 1287 | + | |
| 1288 | + "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0-rc.12", "", { "os": "win32", "cpu": "x64" }, "sha512-PyqoipaswDLAZtot351MLhrlrh6lcZPo2LSYE+VDxbVk24LVKAGOuE4hb8xZQmrPAuEtTZW8E6D2zc5EUZX4Lw=="], | |
| 1289 | + | |
| 1290 | + "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.7", "", {}, "sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA=="], | |
| 1227 | 1291 | |
| 1228 | 1292 | "@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=="], |
| 1229 | 1293 | |
| @@ -1337,12 +1401,36 @@ · 107 unmodified lines | ||
| 1337 | 1401 | |
| 1338 | 1402 | "@tanstack/react-router": ["@tanstack/react-router@1.168.10", "", { "dependencies": { "@tanstack/history": "1.161.6", "@tanstack/react-store": "^0.9.3", "@tanstack/router-core": "1.168.9", "isbot": "^5.1.22" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-/RmDlOwDkCug609KdPB3U+U1zmrtadJpvsmRg2zEn8TRCKRNri7dYZIjQZbNg8PgUiRL4T6njrZBV1ChzblNaA=="], |
| 1339 | 1403 | |
| 1404 | + "@tanstack/react-start": ["@tanstack/react-start@1.167.16", "", { "dependencies": { "@tanstack/react-router": "1.168.10", "@tanstack/react-start-client": "1.166.25", "@tanstack/react-start-server": "1.166.25", "@tanstack/router-utils": "^1.161.6", "@tanstack/start-client-core": "1.167.9", "@tanstack/start-plugin-core": "1.167.17", "@tanstack/start-server-core": "1.167.9", "pathe": "^2.0.3" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0", "vite": ">=7.0.0" }, "bin": { "intent": "bin/intent.js" } }, "sha512-vHIhn+FTWfAVhRus1BZEaBZPhnYL+StDuMlShslIBPEGGTCRt11BxNUfV/iDpr7zbxw36Snj7zGfI7DwfjjlDQ=="], | |
| 1405 | + | |
| 1406 | + "@tanstack/react-start-client": ["@tanstack/react-start-client@1.166.25", "", { "dependencies": { "@tanstack/react-router": "1.168.10", "@tanstack/router-core": "1.168.9", "@tanstack/start-client-core": "1.167.9" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-FvD279zzneUtsfhaTv2c29qhE1Z3wHy3dt3cCjn9LzWZehOgn5Ij78s0YpmQaQ8lSF3YL7CySE3pDk9XHE6YeA=="], | |
| 1407 | + | |
| 1408 | + "@tanstack/react-start-server": ["@tanstack/react-start-server@1.166.25", "", { "dependencies": { "@tanstack/history": "1.161.6", "@tanstack/react-router": "1.168.10", "@tanstack/router-core": "1.168.9", "@tanstack/start-client-core": "1.167.9", "@tanstack/start-server-core": "1.167.9" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-bPLADxlplvcnAcnZvBjJl2MzgUnB85d7Mu5aEkYoOFxhz0WiG6mZp7BDadIJuCd33NYMirsd3XrjfCHNzrMTyg=="], | |
| 1409 | + | |
| 1340 | 1410 | "@tanstack/react-store": ["@tanstack/react-store@0.9.3", "", { "dependencies": { "@tanstack/store": "0.9.3", "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-y2iHd/N9OkoQbFJLUX1T9vbc2O9tjH0pQRgTcx1/Nz4IlwLvkgpuglXUx+mXt0g5ZDFrEeDnONPqkbfxXJKwRg=="], |
| 1341 | 1411 | |
| 1342 | 1412 | "@tanstack/router-core": ["@tanstack/router-core@1.168.9", "", { "dependencies": { "@tanstack/history": "1.161.6", "cookie-es": "^2.0.0", "seroval": "^1.4.2", "seroval-plugins": "^1.4.2" }, "bin": { "intent": "bin/intent.js" } }, "sha512-18oeEwEDyXOIuO1VBP9ACaK7tYHZUjynGDCoUh/5c/BNhia9vCJCp9O0LfhZXOorDc/PmLSgvmweFhVmIxF10g=="], |
| 1343 | 1413 | |
| 1414 | + "@tanstack/router-generator": ["@tanstack/router-generator@1.166.24", "", { "dependencies": { "@tanstack/router-core": "1.168.9", "@tanstack/router-utils": "1.161.6", "@tanstack/virtual-file-routes": "1.161.7", "prettier": "^3.5.0", "recast": "^0.23.11", "source-map": "^0.7.4", "tsx": "^4.19.2", "zod": "^3.24.2" } }, "sha512-vdaGKwuH+r+DPe6R1mjk+TDDmDH6NTG7QqwxHqGEvOH4aGf9sPjhmRKNJZqQr8cPIbfp6u5lXyZ1TeDcSNMVEA=="], | |
| 1415 | + | |
| 1416 | + "@tanstack/router-plugin": ["@tanstack/router-plugin@1.167.12", "", { "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.168.9", "@tanstack/router-generator": "1.166.24", "@tanstack/router-utils": "1.161.6", "@tanstack/virtual-file-routes": "1.161.7", "chokidar": "^3.6.0", "unplugin": "^2.1.2", "zod": "^3.24.2" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2", "@tanstack/react-router": "^1.168.10", "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"], "bin": { "intent": "bin/intent.js" } }, "sha512-StEHcctCuFI5taSjO+lhR/yQ+EK63BdyYa+ne6FoNQPB3MMrOUrz2ZVnbqILRLkh2b+p2EfBKt65sgAKdKygPQ=="], | |
| 1417 | + | |
| 1418 | + "@tanstack/router-utils": ["@tanstack/router-utils@1.161.6", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/generator": "^7.28.5", "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "ansis": "^4.1.0", "babel-dead-code-elimination": "^1.0.12", "diff": "^8.0.2", "pathe": "^2.0.3", "tinyglobby": "^0.2.15" } }, "sha512-nRcYw+w2OEgK6VfjirYvGyPLOK+tZQz1jkYcmH5AjMamQ9PycnlxZF2aEZtPpNoUsaceX2bHptn6Ub5hGXqNvw=="], | |
| 1419 | + | |
| 1420 | + "@tanstack/start-client-core": ["@tanstack/start-client-core@1.167.9", "", { "dependencies": { "@tanstack/router-core": "1.168.9", "@tanstack/start-fn-stubs": "1.161.6", "@tanstack/start-storage-context": "1.166.23", "seroval": "^1.4.2" }, "bin": { "intent": "bin/intent.js" } }, "sha512-2ETQO/bxiZGsoTdPxZb7xR8YqCy5l4kv/QPkwIXuvx/A4BjufngXfgISjXUicXsFRIBZeiFnBzp9A38UMsS2iA=="], | |
| 1421 | + | |
| 1422 | + "@tanstack/start-fn-stubs": ["@tanstack/start-fn-stubs@1.161.6", "", {}, "sha512-Y6QSlGiLga8cHfvxGGaonXIlt2bIUTVdH6AMjmpMp7+ANNCp+N96GQbjjhLye3JkaxDfP68x5iZA8NK4imgRig=="], | |
| 1423 | + | |
| 1424 | + "@tanstack/start-plugin-core": ["@tanstack/start-plugin-core@1.167.17", "", { "dependencies": { "@babel/code-frame": "7.27.1", "@babel/core": "^7.28.5", "@babel/types": "^7.28.5", "@rolldown/pluginutils": "1.0.0-beta.40", "@tanstack/router-core": "1.168.9", "@tanstack/router-generator": "1.166.24", "@tanstack/router-plugin": "1.167.12", "@tanstack/router-utils": "1.161.6", "@tanstack/start-client-core": "1.167.9", "@tanstack/start-server-core": "1.167.9", "cheerio": "^1.0.0", "exsolve": "^1.0.7", "pathe": "^2.0.3", "picomatch": "^4.0.3", "source-map": "^0.7.6", "srvx": "^0.11.9", "tinyglobby": "^0.2.15", "ufo": "^1.5.4", "vitefu": "^1.1.1", "xmlbuilder2": "^4.0.3", "zod": "^3.24.2" }, "peerDependencies": { "vite": ">=7.0.0" } }, "sha512-OkorpOobGOEDVr72QUmkzKjbawKC05CSz+1B3OObB/AxBIIw+lLLhTXbV45QkX2LZA7dcRvPJYZGOH1pkFqA1g=="], | |
| 1425 | + | |
| 1426 | + "@tanstack/start-server-core": ["@tanstack/start-server-core@1.167.9", "", { "dependencies": { "@tanstack/history": "1.161.6", "@tanstack/router-core": "1.168.9", "@tanstack/start-client-core": "1.167.9", "@tanstack/start-storage-context": "1.166.23", "h3-v2": "npm:h3@2.0.1-rc.16", "seroval": "^1.4.2" }, "bin": { "intent": "bin/intent.js" } }, "sha512-vKkslQIihoDDVumF73VXT7PVFmN7Nea0nKhZx7gMbc0m09yPQYYR1dn86/dz14k6/7cDkJ+qKXa09rlVlN/i9Q=="], | |
| 1427 | + | |
| 1428 | + "@tanstack/start-storage-context": ["@tanstack/start-storage-context@1.166.23", "", { "dependencies": { "@tanstack/router-core": "1.168.9" } }, "sha512-3vEdiYRMx+r+Q7Xqxj3YmADPIpMm7fkKxDa8ITwodGXiw+SBJCGkpBXGUWjOXyXkIyqGHKM5UrReTcVUTkmaug=="], | |
| 1429 | + | |
| 1344 | 1430 | "@tanstack/store": ["@tanstack/store@0.9.3", "", {}, "sha512-8reSzl/qGWGGVKhBoxXPMWzATSbZLZFWhwBAFO9NAyp0TxzfBP0mIrGb8CP8KrQTmvzXlR/vFPPUrHTLBGyFyw=="], |
| 1345 | 1431 | |
| 1432 | + "@tanstack/virtual-file-routes": ["@tanstack/virtual-file-routes@1.161.7", "", { "bin": { "intent": "bin/intent.js" } }, "sha512-olW33+Cn+bsCsZKPwEGhlkqS6w3M2slFv11JIobdnCFKMLG97oAI2kWKdx5/zsywTL8flpnoIgaZZPlQTFYhdQ=="], | |
| 1433 | + | |
| 1346 | 1434 | "@turbo/darwin-64": ["@turbo/darwin-64@2.9.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-yg0qdthTUuV/K0oJB9t8YGweW1hOefQ+NTiSA6gw/mwAqqifCvAXH/kDkvVj/fFP9+wzoQ4WjyAF5/syDbCIHA=="], |
| 1347 | 1435 | |
| 1348 | 1436 | "@turbo/darwin-arm64": ["@turbo/darwin-arm64@2.9.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-x4H9U8cXZob3oqTleKOEdY89OCWwLX3qVRpW0NeZg+CHDXemYD+PhACjwjvh7orIlhmmq2Lk+7iO7b34kphFig=="], |
| @@ -1355,15 +1443,9 @@ · 6 unmodified lines | ||
| 1355 | 1443 | |
| 1356 | 1444 | "@turbo/windows-arm64": ["@turbo/windows-arm64@2.9.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-qPFjErR4MrKo71lNfqgUNaajftZN2nyaOsSxMSb2NI+5r/zlB26yjXUKYvADGg4EWvaLTJPIzgZDT9ZX+WN9bw=="], |
| 1357 | 1445 | |
| 1358 | − "@types/accepts": ["@types/accepts@1.3.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ=="], | |
| 1359 | − | |
| 1360 | − "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], | |
| 1361 | − | |
| 1362 | − "@types/babel__generator": ["@types/babel__generator@7.27.0", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="], | |
| 1446 | + "@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="], | |
| 1363 | 1447 | |
| 1364 | − "@types/babel__template": ["@types/babel__template@7.4.4", "", { "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A=="], | |
| 1365 | − | |
| 1366 | − "@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="], | |
| 1448 | + "@types/accepts": ["@types/accepts@1.3.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ=="], | |
| 1367 | 1449 | |
| 1368 | 1450 | "@types/body-parser": ["@types/body-parser@1.19.6", "", { "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g=="], |
| 1369 | 1451 | |
| @@ -1527,7 +1609,7 @@ · 157 unmodified lines | ||
| 1527 | 1609 | |
| 1528 | 1610 | "@vercel/routing-utils": ["@vercel/routing-utils@5.3.3", "", { "dependencies": { "path-to-regexp": "6.1.0", "path-to-regexp-updated": "npm:path-to-regexp@6.3.0" }, "optionalDependencies": { "ajv": "^6.12.3" } }, "sha512-KYm2sLNUD48gDScv8ob4ejc3Gww2jcJyW80hTdYlenAPz/5BQar1Gyh38xrUuZ532TUwSb5mV1uRbAuiykq0EQ=="], |
| 1529 | 1611 | |
| 1530 | − "@vitejs/plugin-react": ["@vitejs/plugin-react@4.7.0", "", { "dependencies": { "@babel/core": "^7.28.0", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.27", "@types/babel__core": "^7.20.5", "react-refresh": "^0.17.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA=="], | |
| 1612 | + "@vitejs/plugin-react": ["@vitejs/plugin-react@6.0.1", "", { "dependencies": { "@rolldown/pluginutils": "1.0.0-rc.7" }, "peerDependencies": { "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", "babel-plugin-react-compiler": "^1.0.0", "vite": "^8.0.0" }, "optionalPeers": ["@rolldown/plugin-babel", "babel-plugin-react-compiler"] }, "sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ=="], | |
| 1531 | 1613 | |
| 1532 | 1614 | "@vitest/expect": ["@vitest/expect@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig=="], |
| 1533 | 1615 | |
| @@ -1571,6 +1653,8 @@ · 37 unmodified lines | ||
| 1571 | 1653 | |
| 1572 | 1654 | "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], |
| 1573 | 1655 | |
| 1656 | + "ansis": ["ansis@4.2.0", "", {}, "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig=="], | |
| 1657 | + | |
| 1574 | 1658 | "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], |
| 1575 | 1659 | |
| 1576 | 1660 | "app-builder-bin": ["app-builder-bin@5.0.0-alpha.12", "", {}, "sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w=="], |
| @@ -1593,6 +1677,8 @@ · 16 unmodified lines | ||
| 1593 | 1677 | |
| 1594 | 1678 | "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="], |
| 1595 | 1679 | |
| 1680 | + "ast-types": ["ast-types@0.16.1", "", { "dependencies": { "tslib": "^2.0.1" } }, "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg=="], | |
| 1681 | + | |
| 1596 | 1682 | "astral-regex": ["astral-regex@2.0.0", "", {}, "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ=="], |
| 1597 | 1683 | |
| 1598 | 1684 | "astro": ["astro@6.1.3", "", { "dependencies": { "@astrojs/compiler": "^3.0.1", "@astrojs/internal-helpers": "0.8.0", "@astrojs/markdown-remark": "7.1.0", "@astrojs/telemetry": "3.3.0", "@capsizecss/unpack": "^4.0.0", "@clack/prompts": "^1.1.0", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.3.0", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "ci-info": "^4.4.0", "clsx": "^2.1.1", "common-ancestor-path": "^2.0.0", "cookie": "^1.1.1", "devalue": "^5.6.3", "diff": "^8.0.3", "dlv": "^1.1.3", "dset": "^3.1.4", "es-module-lexer": "^2.0.0", "esbuild": "^0.27.3", "flattie": "^1.1.1", "fontace": "~0.4.1", "github-slugger": "^2.0.0", "html-escaper": "3.0.3", "http-cache-semantics": "^4.2.0", "js-yaml": "^4.1.1", "magic-string": "^0.30.21", "magicast": "^0.5.2", "mrmime": "^2.0.1", "neotraverse": "^0.6.18", "obug": "^2.1.1", "p-limit": "^7.3.0", "p-queue": "^9.1.0", "package-manager-detector": "^1.6.0", "piccolore": "^0.1.3", "picomatch": "^4.0.3", "rehype": "^13.0.2", "semver": "^7.7.4", "shiki": "^4.0.2", "smol-toml": "^1.6.0", "svgo": "^4.0.1", "tinyclip": "^0.1.12", "tinyexec": "^1.0.4", "tinyglobby": "^0.2.15", "tsconfck": "^3.1.6", "ultrahtml": "^1.6.0", "unifont": "~0.7.4", "unist-util-visit": "^5.1.0", "unstorage": "^1.17.4", "vfile": "^6.0.3", "vite": "^7.3.1", "vitefu": "^1.1.2", "xxhash-wasm": "^1.1.0", "yargs-parser": "^22.0.0", "zod": "^4.3.6" }, "optionalDependencies": { "sharp": "^0.34.0" }, "bin": { "astro": "bin/astro.mjs" } }, "sha512-FUKbBYOdYYrRNZwDd9I5CVSfR6Nj9aZeNzcjcvh1FgHwR0uXawkYFR3HiGxmdmAB2m8fs0iIkDdsiUfwGeO8qA=="], |
| @@ -1611,6 +1697,8 @@ · 12 unmodified lines | ||
| 1611 | 1697 | |
| 1612 | 1698 | "axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="], |
| 1613 | 1699 | |
| 1700 | + "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=="], | |
| 1701 | + | |
| 1614 | 1702 | "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], |
| 1615 | 1703 | |
| 1616 | 1704 | "balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], |
| @@ -1623,6 +1711,8 @@ · 6 unmodified lines | ||
| 1623 | 1711 | |
| 1624 | 1712 | "better-sqlite3": ["better-sqlite3@12.8.0", "", { "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" } }, "sha512-RxD2Vd96sQDjQr20kdP+F+dK/1OUNiVOl200vKBZY8u0vTwysfolF6Hq+3ZK2+h8My9YvZhHsF+RSGZW2VYrPQ=="], |
| 1625 | 1713 | |
| 1714 | + "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], | |
| 1715 | + | |
| 1626 | 1716 | "bindings": ["bindings@1.5.0", "", { "dependencies": { "file-uri-to-path": "1.0.0" } }, "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ=="], |
| 1627 | 1717 | |
| 1628 | 1718 | "bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="], |
| @@ -1687,6 +1777,10 @@ · 58 unmodified lines | ||
| 1687 | 1777 | |
| 1688 | 1778 | "check-error": ["check-error@2.1.3", "", {}, "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA=="], |
| 1689 | 1779 | |
| 1780 | + "cheerio": ["cheerio@1.2.0", "", { "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", "domutils": "^3.2.2", "encoding-sniffer": "^0.2.1", "htmlparser2": "^10.1.0", "parse5": "^7.3.0", "parse5-htmlparser2-tree-adapter": "^7.1.0", "parse5-parser-stream": "^7.1.2", "undici": "^7.19.0", "whatwg-mimetype": "^4.0.0" } }, "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg=="], | |
| 1781 | + | |
| 1782 | + "cheerio-select": ["cheerio-select@2.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", "css-what": "^6.1.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1" } }, "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g=="], | |
| 1783 | + | |
| 1690 | 1784 | "chevrotain": ["chevrotain@11.1.2", "", { "dependencies": { "@chevrotain/cst-dts-gen": "11.1.2", "@chevrotain/gast": "11.1.2", "@chevrotain/regexp-to-ast": "11.1.2", "@chevrotain/types": "11.1.2", "@chevrotain/utils": "11.1.2", "lodash-es": "4.17.23" } }, "sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg=="], |
| 1691 | 1785 | |
| 1692 | 1786 | "chevrotain-allstar": ["chevrotain-allstar@0.3.1", "", { "dependencies": { "lodash-es": "^4.17.21" }, "peerDependencies": { "chevrotain": "^11.0.0" } }, "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw=="], |
| @@ -1961,13 +2055,15 @@ · 268 unmodified lines | ||
| 1961 | 2055 | |
| 1962 | 2056 | "encoding": ["encoding@0.1.13", "", { "dependencies": { "iconv-lite": "^0.6.2" } }, "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A=="], |
| 1963 | 2057 | |
| 2058 | + "encoding-sniffer": ["encoding-sniffer@0.2.1", "", { "dependencies": { "iconv-lite": "^0.6.3", "whatwg-encoding": "^3.1.1" } }, "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw=="], | |
| 2059 | + | |
| 1964 | 2060 | "end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="], |
| 1965 | 2061 | |
| 1966 | 2062 | "enhanced-resolve": ["enhanced-resolve@5.20.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.0" } }, "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA=="], |
| 1967 | 2063 | |
| 1968 | 2064 | "enquirer": ["enquirer@2.4.1", "", { "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" } }, "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ=="], |
| 1969 | 2065 | |
| 1970 | − "entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], | |
| 2066 | + "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], | |
| 1971 | 2067 | |
| 1972 | 2068 | "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], |
| 1973 | 2069 | |
| @@ -2021,6 +2117,8 @@ · 47 unmodified lines | ||
| 2021 | 2117 | |
| 2022 | 2118 | "express-rate-limit": ["express-rate-limit@8.3.2", "", { "dependencies": { "ip-address": "10.1.0" }, "peerDependencies": { "express": ">= 4.11" } }, "sha512-77VmFeJkO0/rvimEDuUC5H30oqUC4EyOhyGccfqoLebB0oiEYfM7nwPrsDsBL1gsTpwfzX8SFy2MT3TDyRq+bg=="], |
| 2023 | 2119 | |
| 2120 | + "exsolve": ["exsolve@1.0.8", "", {}, "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA=="], | |
| 2121 | + | |
| 2024 | 2122 | "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], |
| 2025 | 2123 | |
| 2026 | 2124 | "extendable-error": ["extendable-error@0.1.7", "", {}, "sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg=="], |
| @@ -2127,6 +2225,8 @@ · 100 unmodified lines | ||
| 2127 | 2225 | |
| 2128 | 2226 | "h3": ["h3@1.15.11", "", { "dependencies": { "cookie-es": "^1.2.3", "crossws": "^0.3.5", "defu": "^6.1.6", "destr": "^2.0.5", "iron-webcrypto": "^1.2.1", "node-mock-http": "^1.0.4", "radix3": "^1.1.2", "ufo": "^1.6.3", "uncrypto": "^0.1.3" } }, "sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg=="], |
| 2129 | 2227 | |
| 2228 | + "h3-v2": ["h3@2.0.1-rc.16", "", { "dependencies": { "rou3": "^0.8.0", "srvx": "^0.11.9" }, "peerDependencies": { "crossws": "^0.4.1" }, "optionalPeers": ["crossws"], "bin": { "h3": "bin/h3.mjs" } }, "sha512-h+pjvyujdo9way8qj6FUbhaQcHlR8FEq65EhTX9ViT5pK8aLj68uFl4hBkF+hsTJAH+H1END2Yv6hTIsabGfag=="], | |
| 2229 | + | |
| 2130 | 2230 | "hachure-fill": ["hachure-fill@0.5.2", "", {}, "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg=="], |
| 2131 | 2231 | |
| 2132 | 2232 | "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], |
| @@ -2173,6 +2273,8 @@ · 40 unmodified lines | ||
| 2173 | 2273 | |
| 2174 | 2274 | "html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="], |
| 2175 | 2275 | |
| 2276 | + "htmlparser2": ["htmlparser2@10.1.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.2.2", "entities": "^7.0.1" } }, "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ=="], | |
| 2277 | + | |
| 2176 | 2278 | "http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="], |
| 2177 | 2279 | |
| 2178 | 2280 | "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], |
| @@ -2221,6 +2323,8 @@ · 42 unmodified lines | ||
| 2221 | 2323 | |
| 2222 | 2324 | "is-alphanumerical": ["is-alphanumerical@2.0.1", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw=="], |
| 2223 | 2325 | |
| 2326 | + "is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="], | |
| 2327 | + | |
| 2224 | 2328 | "is-decimal": ["is-decimal@2.0.1", "", {}, "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A=="], |
| 2225 | 2329 | |
| 2226 | 2330 | "is-docker": ["is-docker@3.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="], |
| @@ -2605,6 +2709,10 @@ · 378 unmodified lines | ||
| 2605 | 2709 | |
| 2606 | 2710 | "parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="], |
| 2607 | 2711 | |
| 2712 | + "parse5-htmlparser2-tree-adapter": ["parse5-htmlparser2-tree-adapter@7.1.0", "", { "dependencies": { "domhandler": "^5.0.3", "parse5": "^7.0.0" } }, "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g=="], | |
| 2713 | + | |
| 2714 | + "parse5-parser-stream": ["parse5-parser-stream@7.1.2", "", { "dependencies": { "parse5": "^7.0.0" } }, "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow=="], | |
| 2715 | + | |
| 2608 | 2716 | "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], |
| 2609 | 2717 | |
| 2610 | 2718 | "path-data-parser": ["path-data-parser@0.1.0", "", {}, "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w=="], |
| @@ -2747,8 +2855,6 @@ · 136 unmodified lines | ||
| 2747 | 2855 | |
| 2748 | 2856 | "react-redux": ["react-redux@9.2.0", "", { "dependencies": { "@types/use-sync-external-store": "^0.0.6", "use-sync-external-store": "^1.4.0" }, "peerDependencies": { "@types/react": "^18.2.25 || ^19", "react": "^18.0 || ^19", "redux": "^5.0.0" }, "optionalPeers": ["@types/react", "redux"] }, "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g=="], |
| 2749 | 2857 | |
| 2750 | − "react-refresh": ["react-refresh@0.17.0", "", {}, "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ=="], | |
| 2751 | − | |
| 2752 | 2858 | "react-remove-scroll": ["react-remove-scroll@2.7.2", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q=="], |
| 2753 | 2859 | |
| 2754 | 2860 | "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="], |
| @@ -2765,6 +2871,8 @@ · 10 unmodified lines | ||
| 2765 | 2871 | |
| 2766 | 2872 | "readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], |
| 2767 | 2873 | |
| 2874 | + "recast": ["recast@0.23.11", "", { "dependencies": { "ast-types": "^0.16.1", "esprima": "~4.0.0", "source-map": "~0.6.1", "tiny-invariant": "^1.3.3", "tslib": "^2.0.1" } }, "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA=="], | |
| 2875 | + | |
| 2768 | 2876 | "recharts": ["recharts@3.8.0", "", { "dependencies": { "@reduxjs/toolkit": "^1.9.0 || 2.x.x", "clsx": "^2.1.1", "decimal.js-light": "^2.5.1", "es-toolkit": "^1.39.3", "eventemitter3": "^5.0.1", "immer": "^10.1.1", "react-redux": "8.x.x || 9.x.x", "reselect": "5.1.1", "tiny-invariant": "^1.3.3", "use-sync-external-store": "^1.2.2", "victory-vendor": "^37.0.2" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Z/m38DX3L73ExO4Tpc9/iZWHmHnlzWG4njQbxsF5aSjwqmHNDDIm0rdEBArkwsBvR8U6EirlEHiQNYWCVh9sGQ=="], |
| 2769 | 2877 | |
| 2770 | 2878 | "redux": ["redux@5.0.1", "", {}, "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w=="], |
| @@ -2837,8 +2945,12 @@ · 66 unmodified lines | ||
| 2837 | 2945 | |
| 2838 | 2946 | "robust-predicates": ["robust-predicates@3.0.3", "", {}, "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA=="], |
| 2839 | 2947 | |
| 2948 | + "rolldown": ["rolldown@1.0.0-rc.12", "", { "dependencies": { "@oxc-project/types": "=0.122.0", "@rolldown/pluginutils": "1.0.0-rc.12" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0-rc.12", "@rolldown/binding-darwin-arm64": "1.0.0-rc.12", "@rolldown/binding-darwin-x64": "1.0.0-rc.12", "@rolldown/binding-freebsd-x64": "1.0.0-rc.12", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.12", "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.12", "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.12", "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.12", "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.12", "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.12", "@rolldown/binding-linux-x64-musl": "1.0.0-rc.12", "@rolldown/binding-openharmony-arm64": "1.0.0-rc.12", "@rolldown/binding-wasm32-wasi": "1.0.0-rc.12", "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.12", "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.12" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A=="], | |
| 2949 | + | |
| 2840 | 2950 | "rollup": ["rollup@4.60.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.60.1", "@rollup/rollup-android-arm64": "4.60.1", "@rollup/rollup-darwin-arm64": "4.60.1", "@rollup/rollup-darwin-x64": "4.60.1", "@rollup/rollup-freebsd-arm64": "4.60.1", "@rollup/rollup-freebsd-x64": "4.60.1", "@rollup/rollup-linux-arm-gnueabihf": "4.60.1", "@rollup/rollup-linux-arm-musleabihf": "4.60.1", "@rollup/rollup-linux-arm64-gnu": "4.60.1", "@rollup/rollup-linux-arm64-musl": "4.60.1", "@rollup/rollup-linux-loong64-gnu": "4.60.1", "@rollup/rollup-linux-loong64-musl": "4.60.1", "@rollup/rollup-linux-ppc64-gnu": "4.60.1", "@rollup/rollup-linux-ppc64-musl": "4.60.1", "@rollup/rollup-linux-riscv64-gnu": "4.60.1", "@rollup/rollup-linux-riscv64-musl": "4.60.1", "@rollup/rollup-linux-s390x-gnu": "4.60.1", "@rollup/rollup-linux-x64-gnu": "4.60.1", "@rollup/rollup-linux-x64-musl": "4.60.1", "@rollup/rollup-openbsd-x64": "4.60.1", "@rollup/rollup-openharmony-arm64": "4.60.1", "@rollup/rollup-win32-arm64-msvc": "4.60.1", "@rollup/rollup-win32-ia32-msvc": "4.60.1", "@rollup/rollup-win32-x64-gnu": "4.60.1", "@rollup/rollup-win32-x64-msvc": "4.60.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w=="], |
| 2841 | 2951 | |
| 2952 | + "rou3": ["rou3@0.8.1", "", {}, "sha512-ePa+XGk00/3HuCqrEnK3LxJW7I0SdNg6EFzKUJG73hMAdDcOUC/i/aSz7LSDwLrGr33kal/rqOGydzwl6U7zBA=="], | |
| 2953 | + | |
| 2842 | 2954 | "roughjs": ["roughjs@4.6.6", "", { "dependencies": { "hachure-fill": "^0.5.2", "path-data-parser": "^0.1.0", "points-on-curve": "^0.2.0", "points-on-path": "^0.2.1" } }, "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ=="], |
| 2843 | 2955 | |
| 2844 | 2956 | "router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="], |
| @@ -2915,7 +3027,7 @@ · 70 unmodified lines | ||
| 2915 | 3027 | |
| 2916 | 3028 | "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=="], |
| 2917 | 3029 | |
| 2918 | − "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], | |
| 3030 | + "source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="], | |
| 2919 | 3031 | |
| 2920 | 3032 | "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], |
| 2921 | 3033 | |
| @@ -2929,6 +3041,8 @@ · 7 unmodified lines | ||
| 2929 | 3041 | |
| 2930 | 3042 | "sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="], |
| 2931 | 3043 | |
| 3044 | + "srvx": ["srvx@0.11.15", "", { "bin": { "srvx": "bin/srvx.mjs" } }, "sha512-iXsux0UcOjdvs0LCMa2Ws3WwcDUozA3JN3BquNXkaFPP7TpRqgunKdEgoZ/uwb1J6xaYHfxtz9Twlh6yzwM6Tg=="], | |
| 3045 | + | |
| 2932 | 3046 | "ssri": ["ssri@12.0.0", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ=="], |
| 2933 | 3047 | |
| 2934 | 3048 | "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], |
| @@ -3087,6 +3201,8 @@ · 152 unmodified lines | ||
| 3087 | 3201 | |
| 3088 | 3202 | "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], |
| 3089 | 3203 | |
| 3204 | + "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=="], | |
| 3205 | + | |
| 3090 | 3206 | "unstorage": ["unstorage@1.17.5", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^5.0.0", "destr": "^2.0.5", "h3": "^1.15.10", "lru-cache": "^11.2.7", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg=="], |
| 3091 | 3207 | |
| 3092 | 3208 | "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=="], |
| @@ -3119,7 +3235,7 @@ · 26 unmodified lines | ||
| 3119 | 3235 | |
| 3120 | 3236 | "victory-vendor": ["victory-vendor@37.3.6", "", { "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-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ=="], |
| 3121 | 3237 | |
| 3122 | − "vite": ["vite@6.4.1", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "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-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g=="], | |
| 3238 | + "vite": ["vite@8.0.5", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.8", "rolldown": "1.0.0-rc.12", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.1.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.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", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-nmu43Qvq9UopTRfMx2jOYW5l16pb3iDC1JH6yMuPkpVbzK0k+L7dfsEDH4jRgYFmsg0sTAqkojoZgzLMlwHsCQ=="], | |
| 3123 | 3239 | |
| 3124 | 3240 | "vite-node": ["vite-node@3.2.4", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.4.1", "es-module-lexer": "^1.7.0", "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg=="], |
| 3125 | 3241 | |
| @@ -3147,6 +3263,12 @@ · 21 unmodified lines | ||
| 3147 | 3263 | |
| 3148 | 3264 | "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], |
| 3149 | 3265 | |
| 3266 | + "webpack-virtual-modules": ["webpack-virtual-modules@0.6.2", "", {}, "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="], | |
| 3267 | + | |
| 3268 | + "whatwg-encoding": ["whatwg-encoding@3.1.1", "", { "dependencies": { "iconv-lite": "0.6.3" } }, "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ=="], | |
| 3269 | + | |
| 3270 | + "whatwg-mimetype": ["whatwg-mimetype@4.0.0", "", {}, "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg=="], | |
| 3271 | + | |
| 3150 | 3272 | "whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], |
| 3151 | 3273 | |
| 3152 | 3274 | "which": ["which@5.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ=="], |
| @@ -3165,6 +3287,8 @@ · 12 unmodified lines | ||
| 3165 | 3287 | |
| 3166 | 3288 | "xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="], |
| 3167 | 3289 | |
| 3290 | + "xmlbuilder2": ["xmlbuilder2@4.0.3", "", { "dependencies": { "@oozcitak/dom": "^2.0.2", "@oozcitak/infra": "^2.0.2", "@oozcitak/util": "^10.0.0", "js-yaml": "^4.1.1" } }, "sha512-bx8Q1STctnNaaDymWnkfQLKofs0mGNN7rLLapJlGuV3VlvegD7Ls4ggMjE3aUSWItCCzU0PEv45lI87iSigiCA=="], | |
| 3291 | + | |
| 3168 | 3292 | "xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="], |
| 3169 | 3293 | |
| 3170 | 3294 | "xxhash-wasm": ["xxhash-wasm@1.1.0", "", {}, "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA=="], |
| @@ -3197,12 +3321,18 @@ · 26 unmodified lines | ||
| 3197 | 3321 | |
| 3198 | 3322 | "@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], |
| 3199 | 3323 | |
| 3324 | + "@babel/core/@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="], | |
| 3325 | + | |
| 3200 | 3326 | "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], |
| 3201 | 3327 | |
| 3202 | 3328 | "@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], |
| 3203 | 3329 | |
| 3204 | 3330 | "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], |
| 3205 | 3331 | |
| 3332 | + "@babel/template/@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="], | |
| 3333 | + | |
| 3334 | + "@babel/traverse/@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="], | |
| 3335 | + | |
| 3206 | 3336 | "@develar/schema-utils/ajv": ["ajv@6.14.0", "", { "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-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="], |
| 3207 | 3337 | |
| 3208 | 3338 | "@electron/asar/commander": ["commander@5.1.0", "", {}, "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg=="], |
| @@ -3235,10 +3365,6 @@ · 26 unmodified lines | ||
| 3235 | 3365 | |
| 3236 | 3366 | "@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=="], |
| 3237 | 3367 | |
| 3238 | − "@executor/config/typescript": ["typescript@6.0.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ=="], | |
| 3239 | − | |
| 3240 | − "@executor/sdk/typescript": ["typescript@6.0.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ=="], | |
| 3241 | − | |
| 3242 | 3368 | "@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], |
| 3243 | 3369 | |
| 3244 | 3370 | "@isaacs/cliui/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], |
| @@ -3275,6 +3401,18 @@ · 30 unmodified lines | ||
| 3275 | 3401 | |
| 3276 | 3402 | "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], |
| 3277 | 3403 | |
| 3404 | + "@tanstack/router-generator/prettier": ["prettier@3.8.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg=="], | |
| 3405 | + | |
| 3406 | + "@tanstack/router-generator/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], | |
| 3407 | + | |
| 3408 | + "@tanstack/router-plugin/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], | |
| 3409 | + | |
| 3410 | + "@tanstack/router-plugin/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], | |
| 3411 | + | |
| 3412 | + "@tanstack/start-plugin-core/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.40", "", {}, "sha512-s3GeJKSQOwBlzdUrj4ISjJj5SfSh+aqn0wjOar4Bx95iV1ETI7F6S/5hLcfAxZ9kXDcyrAkxPlqmd1ZITttf+w=="], | |
| 3413 | + | |
| 3414 | + "@tanstack/start-plugin-core/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], | |
| 3415 | + | |
| 3278 | 3416 | "@types/accepts/@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="], |
| 3279 | 3417 | |
| 3280 | 3418 | "@types/body-parser/@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="], |
| @@ -3309,6 +3447,8 @@ · 28 unmodified lines | ||
| 3309 | 3447 | |
| 3310 | 3448 | "@vercel/routing-utils/ajv": ["ajv@6.14.0", "", { "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-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="], |
| 3311 | 3449 | |
| 3450 | + "@vitest/mocker/vite": ["vite@6.4.1", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "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-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g=="], | |
| 3451 | + | |
| 3312 | 3452 | "ajv-keywords/ajv": ["ajv@6.14.0", "", { "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-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="], |
| 3313 | 3453 | |
| 3314 | 3454 | "anymatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], |
| @@ -3371,8 +3511,6 @@ · 56 unmodified lines | ||
| 3371 | 3511 | |
| 3372 | 3512 | "dmg-license/ajv": ["ajv@6.14.0", "", { "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-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="], |
| 3373 | 3513 | |
| 3374 | − "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], | |
| 3375 | − | |
| 3376 | 3514 | "electron/@types/node": ["@types/node@22.19.17", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q=="], |
| 3377 | 3515 | |
| 3378 | 3516 | "electron-builder/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], |
| @@ -3387,6 +3525,8 @@ · 8 unmodified lines | ||
| 3387 | 3525 | |
| 3388 | 3526 | "encoding/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], |
| 3389 | 3527 | |
| 3528 | + "encoding-sniffer/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], | |
| 3529 | + | |
| 3390 | 3530 | "express/cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], |
| 3391 | 3531 | |
| 3392 | 3532 | "express/qs": ["qs@6.15.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ=="], |
| @@ -3401,6 +3541,8 @@ · 8 unmodified lines | ||
| 3401 | 3541 | |
| 3402 | 3542 | "hosted-git-info/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], |
| 3403 | 3543 | |
| 3544 | + "htmlparser2/entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], | |
| 3545 | + | |
| 3404 | 3546 | "iconv-corefoundation/node-addon-api": ["node-addon-api@1.7.2", "", {}, "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg=="], |
| 3405 | 3547 | |
| 3406 | 3548 | "iron-session/@types/node": ["@types/node@17.0.45", "", {}, "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw=="], |
| @@ -3429,6 +3571,8 @@ · 22 unmodified lines | ||
| 3429 | 3571 | |
| 3430 | 3572 | "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], |
| 3431 | 3573 | |
| 3574 | + "parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], | |
| 3575 | + | |
| 3432 | 3576 | "postject/commander": ["commander@9.5.0", "", {}, "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="], |
| 3433 | 3577 | |
| 3434 | 3578 | "proper-lockfile/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], |
| @@ -3437,12 +3581,18 @@ · 2 unmodified lines | ||
| 3437 | 3581 | |
| 3438 | 3582 | "read-yaml-file/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], |
| 3439 | 3583 | |
| 3584 | + "recast/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], | |
| 3585 | + | |
| 3440 | 3586 | "restore-cursor/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], |
| 3441 | 3587 | |
| 3442 | 3588 | "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=="], |
| 3443 | 3589 | |
| 3590 | + "rolldown/@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-rc.12", "", {}, "sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw=="], | |
| 3591 | + | |
| 3444 | 3592 | "router/path-to-regexp": ["path-to-regexp@8.4.2", "", {}, "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA=="], |
| 3445 | 3593 | |
| 3594 | + "source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], | |
| 3595 | + | |
| 3446 | 3596 | "tar-fs/chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="], |
| 3447 | 3597 | |
| 3448 | 3598 | "temp-file/fs-extra": ["fs-extra@10.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ=="], |
| @@ -3457,6 +3607,8 @@ · 8 unmodified lines | ||
| 3457 | 3607 | |
| 3458 | 3608 | "vitest/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=="], |
| 3459 | 3609 | |
| 3610 | + "whatwg-encoding/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], | |
| 3611 | + | |
| 3460 | 3612 | "yargs/yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], |
| 3461 | 3613 | |
| 3462 | 3614 | "@astrojs/vercel/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q=="], |
| @@ -3511,8 +3663,14 @@ · 48 unmodified lines | ||
| 3511 | 3663 | |
| 3512 | 3664 | "@astrojs/vercel/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.4", "", { "os": "win32", "cpu": "x64" }, "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg=="], |
| 3513 | 3665 | |
| 3666 | + "@babel/core/@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], | |
| 3667 | + | |
| 3514 | 3668 | "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], |
| 3515 | 3669 | |
| 3670 | + "@babel/template/@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], | |
| 3671 | + | |
| 3672 | + "@babel/traverse/@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], | |
| 3673 | + | |
| 3516 | 3674 | "@develar/schema-utils/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], |
| 3517 | 3675 | |
| 3518 | 3676 | "@electron/asar/minimatch/brace-expansion": ["brace-expansion@1.1.13", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w=="], |
| @@ -3593,6 +3751,8 @@ · 74 unmodified lines | ||
| 3593 | 3751 | |
| 3594 | 3752 | "@malept/flatpak-bundler/fs-extra/universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], |
| 3595 | 3753 | |
| 3754 | + "@tanstack/router-plugin/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], | |
| 3755 | + | |
| 3596 | 3756 | "@types/accepts/@types/node/undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], |
| 3597 | 3757 | |
| 3598 | 3758 | "@types/body-parser/@types/node/undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], |
| @@ -3807,6 +3967,8 @@ · 208 unmodified lines | ||
| 3807 | 3967 | |
| 3808 | 3968 | "@electron/universal/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], |
| 3809 | 3969 | |
| 3970 | + "@tanstack/router-plugin/chokidar/readdirp/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], | |
| 3971 | + | |
| 3810 | 3972 | "cacache/glob/minimatch/brace-expansion": ["brace-expansion@2.0.3", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA=="], |
| 3811 | 3973 | |
| 3812 | 3974 | "dir-compare/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], |
| @@ -42,7 +42,18 @@ · 41 unmodified lines | ||
| 42 | 42 | "@types/node": "^24.3.1", |
| 43 | 43 | "bun-types": "^1.2.22", |
| 44 | 44 | "drizzle-orm": "^0.44.0", |
| 45 | − "vitest": "^3.2.4" | |
| 45 | + "vitest": "^3.2.4", | |
| 46 | + "vite": "^8.0.0", | |
| 47 | + "@vitejs/plugin-react": "^6.0.1", | |
| 48 | + "@tailwindcss/vite": "^4.2.2", | |
| 49 | + "@tanstack/react-router": "^1.168.10", | |
| 50 | + "@tanstack/react-start": "^1.167.16", | |
| 51 | + "react": "^19.1.0", | |
| 52 | + "react-dom": "^19.1.0", | |
| 53 | + "@types/react": "^19.1.0", | |
| 54 | + "@types/react-dom": "^19.1.0", | |
| 55 | + "typescript": "^5.9.3", | |
| 56 | + "tailwindcss": "^4.2.2" | |
| 46 | 57 | }, |
| 47 | 58 | "scripts": { |
| 48 | 59 | "dev": "turbo run dev --filter='!@executor/desktop'", |
| @@ -15,7 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | "devDependencies": { |
| 16 | 16 | "@types/node": "catalog:", |
| 17 | 17 | "bun-types": "catalog:", |
| 18 | − "typescript": "^5.9.3" | |
| 18 | + "typescript": "catalog:" | |
| 19 | 19 | }, |
| 20 | 20 | "scripts": { |
| 21 | 21 | "typecheck": "tsc --noEmit" |
| @@ -20,6 +20,6 @@ · 19 unmodified lines | ||
| 20 | 20 | "@effect/platform-node": "catalog:", |
| 21 | 21 | "@effect/vitest": "catalog:", |
| 22 | 22 | "vitest": "catalog:", |
| 23 | − "typescript": "latest" | |
| 23 | + "typescript": "catalog:" | |
| 24 | 24 | } |
| 25 | 25 | } |
| @@ -16,6 +16,6 @@ · 15 unmodified lines | ||
| 16 | 16 | "devDependencies": { |
| 17 | 17 | "@effect/vitest": "catalog:", |
| 18 | 18 | "vitest": "catalog:", |
| 19 | − "typescript": "latest" | |
| 19 | + "typescript": "catalog:" | |
| 20 | 20 | } |
| 21 | 21 | } |
| @@ -15,7 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | "@effect/experimental": "catalog:", |
| 16 | 16 | "@effect/sql-sqlite-node": "catalog:", |
| 17 | 17 | "@effect/vitest": "catalog:", |
| 18 | − "typescript": "^5.9.3", | |
| 18 | + "typescript": "catalog:", | |
| 19 | 19 | "vitest": "catalog:" |
| 20 | 20 | }, |
| 21 | 21 | "scripts": { |
| @@ -19,7 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | "@electric-sql/pglite": "^0.4.3", |
| 20 | 20 | "@types/pg": "^8.15.4", |
| 21 | 21 | "drizzle-kit": "^0.31.0", |
| 22 | − "typescript": "^5.9.3", | |
| 22 | + "typescript": "catalog:", | |
| 23 | 23 | "vitest": "catalog:" |
| 24 | 24 | }, |
| 25 | 25 | "scripts": { |
| @@ -21,9 +21,9 @@ · 20 unmodified lines | ||
| 21 | 21 | "effect": "catalog:" |
| 22 | 22 | }, |
| 23 | 23 | "peerDependencies": { |
| 24 | − "react": "^19.1.0", | |
| 24 | + "react": "catalog:", | |
| 25 | 25 | "@effect-atom/atom-react": "^0.5.0", |
| 26 | − "@tanstack/react-router": "^1.168.10", | |
| 26 | + "@tanstack/react-router": "catalog:", | |
| 27 | 27 | "@executor/react": "workspace:*" |
| 28 | 28 | }, |
| 29 | 29 | "peerDependenciesMeta": { |
| @@ -45,9 +45,9 @@ · 15 unmodified lines | ||
| 45 | 45 | "@effect/vitest": "catalog:", |
| 46 | 46 | "@executor/react": "workspace:*", |
| 47 | 47 | "@types/node": "catalog:", |
| 48 | − "@types/react": "^19.1.0", | |
| 48 | + "@types/react": "catalog:", | |
| 49 | 49 | "bun-types": "catalog:", |
| 50 | − "react": "^19.1.0", | |
| 50 | + "react": "catalog:", | |
| 51 | 51 | "vitest": "catalog:" |
| 52 | 52 | } |
| 53 | 53 | } |
| @@ -21,9 +21,9 @@ · 20 unmodified lines | ||
| 21 | 21 | "effect": "catalog:" |
| 22 | 22 | }, |
| 23 | 23 | "peerDependencies": { |
| 24 | − "react": "^19.1.0", | |
| 24 | + "react": "catalog:", | |
| 25 | 25 | "@effect-atom/atom-react": "^0.5.0", |
| 26 | − "@tanstack/react-router": "^1.168.10", | |
| 26 | + "@tanstack/react-router": "catalog:", | |
| 27 | 27 | "@executor/api": "workspace:*", |
| 28 | 28 | "@executor/react": "workspace:*" |
| 29 | 29 | }, |
| @@ -45,11 +45,11 @@ · 15 unmodified lines | ||
| 45 | 45 | } |
| 46 | 46 | }, |
| 47 | 47 | "devDependencies": { |
| 48 | − "react": "^19.1.0", | |
| 48 | + "react": "catalog:", | |
| 49 | 49 | "@effect-atom/atom-react": "^0.5.0", |
| 50 | 50 | "@executor/api": "workspace:*", |
| 51 | 51 | "@executor/react": "workspace:*", |
| 52 | − "@types/react": "^19.1.0", | |
| 52 | + "@types/react": "catalog:", | |
| 53 | 53 | "@effect/vitest": "catalog:", |
| 54 | 54 | "@types/node": "catalog:", |
| 55 | 55 | "bun-types": "catalog:", |
| @@ -22,9 +22,9 @@ · 21 unmodified lines | ||
| 22 | 22 | "effect": "catalog:" |
| 23 | 23 | }, |
| 24 | 24 | "peerDependencies": { |
| 25 | − "react": "^19.1.0", | |
| 25 | + "react": "catalog:", | |
| 26 | 26 | "@effect-atom/atom-react": "^0.5.0", |
| 27 | − "@tanstack/react-router": "^1.168.10", | |
| 27 | + "@tanstack/react-router": "catalog:", | |
| 28 | 28 | "@executor/api": "workspace:*", |
| 29 | 29 | "@executor/react": "workspace:*" |
| 30 | 30 | }, |
| @@ -46,11 +46,11 @@ · 15 unmodified lines | ||
| 46 | 46 | } |
| 47 | 47 | }, |
| 48 | 48 | "devDependencies": { |
| 49 | − "react": "^19.1.0", | |
| 49 | + "react": "catalog:", | |
| 50 | 50 | "@effect-atom/atom-react": "^0.5.0", |
| 51 | 51 | "@executor/api": "workspace:*", |
| 52 | 52 | "@executor/react": "workspace:*", |
| 53 | − "@types/react": "^19.1.0", | |
| 53 | + "@types/react": "catalog:", | |
| 54 | 54 | "@effect/vitest": "catalog:", |
| 55 | 55 | "@types/node": "catalog:", |
| 56 | 56 | "bun-types": "catalog:", |
| @@ -25,9 +25,9 @@ · 24 unmodified lines | ||
| 25 | 25 | "devDependencies": { |
| 26 | 26 | "@effect/vitest": "catalog:", |
| 27 | 27 | "@types/node": "catalog:", |
| 28 | − "@types/react": "^19.1.0", | |
| 28 | + "@types/react": "catalog:", | |
| 29 | 29 | "bun-types": "catalog:", |
| 30 | − "react": "^19.1.0", | |
| 30 | + "react": "catalog:", | |
| 31 | 31 | "vitest": "catalog:" |
| 32 | 32 | }, |
| 33 | 33 | "peerDependencies": { |
| @@ -24,9 +24,9 @@ · 23 unmodified lines | ||
| 24 | 24 | "yaml": "^2.7.1" |
| 25 | 25 | }, |
| 26 | 26 | "peerDependencies": { |
| 27 | − "react": "^19.1.0", | |
| 27 | + "react": "catalog:", | |
| 28 | 28 | "@effect-atom/atom-react": "^0.5.0", |
| 29 | − "@tanstack/react-router": "^1.168.10", | |
| 29 | + "@tanstack/react-router": "catalog:", | |
| 30 | 30 | "@executor/api": "workspace:*", |
| 31 | 31 | "@executor/react": "workspace:*" |
| 32 | 32 | }, |
| @@ -48,11 +48,11 @@ · 15 unmodified lines | ||
| 48 | 48 | } |
| 49 | 49 | }, |
| 50 | 50 | "devDependencies": { |
| 51 | − "react": "^19.1.0", | |
| 51 | + "react": "catalog:", | |
| 52 | 52 | "@effect-atom/atom-react": "^0.5.0", |
| 53 | 53 | "@executor/api": "workspace:*", |
| 54 | 54 | "@executor/react": "workspace:*", |
| 55 | − "@types/react": "^19.1.0", | |
| 55 | + "@types/react": "catalog:", | |
| 56 | 56 | "@effect/vitest": "catalog:", |
| 57 | 57 | "@types/node": "catalog:", |
| 58 | 58 | "bun-types": "catalog:", |
| @@ -32,7 +32,7 @@ · 31 unmodified lines | ||
| 32 | 32 | "lucide-react": "^1.7.0", |
| 33 | 33 | "next-themes": "^0.4.6", |
| 34 | 34 | "radix-ui": "^1.4.3", |
| 35 | − "react": "^19.1.0", | |
| 35 | + "react": "catalog:", | |
| 36 | 36 | "react-day-picker": "^9.14.0", |
| 37 | 37 | "react-hook-form": "^7.72.0", |
| 38 | 38 | "react-resizable-panels": "^4", |
| @@ -45,11 +45,11 @@ · 6 unmodified lines | ||
| 45 | 45 | "zod": "^4.3.6" |
| 46 | 46 | }, |
| 47 | 47 | "devDependencies": { |
| 48 | − "@types/react": "^19.1.0", | |
| 48 | + "@types/react": "catalog:", | |
| 49 | 49 | "@types/node": "catalog:", |
| 50 | 50 | "hast-util-to-jsx-runtime": "^2.3.6", |
| 51 | − "tailwindcss": "^4.1.10", | |
| 52 | − "typescript": "^5.9.3" | |
| 51 | + "tailwindcss": "catalog:", | |
| 52 | + "typescript": "catalog:" | |
| 53 | 53 | }, |
| 54 | 54 | "scripts": { |
| 55 | 55 | "typecheck": "tsc --noEmit" |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | import { useEffect, useState } from "react"; |
| 2 | −import { Button } from "@executor/ui/components/button"; | |
| 3 | −import { CodeBlock } from "@executor/ui/components/code-block"; | |
| 4 | −import { useScopeInfo } from "@executor/react"; | |
| 2 | +import { Button } from "./button"; | |
| 3 | +import { CodeBlock } from "./code-block"; | |
| 4 | +import { useScopeInfo } from "../api/scope-context"; | |
| 5 | 5 | |
| 6 | 6 | type TransportMode = "stdio" | "http"; |
| 7 | 7 | |
| @@ -2,11 +2,10 @@ · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | @custom-variant dark (&:is(.dark *)); |
| 4 | 4 | |
| 5 | −@source "../components/**/*.{ts,tsx}"; | |
| 6 | −@source "../../../../apps/web/src/**/*.{ts,tsx}"; | |
| 7 | −@source "../../../clients/react/src/**/*.{ts,tsx}"; | |
| 8 | −@source "../../../plugins/openapi/src/react/**/*.{ts,tsx}"; | |
| 9 | −@source "../../../plugins/onepassword/src/react/**/*.{ts,tsx}"; | |
| 5 | +@source "../**/*.{ts,tsx}"; | |
| 6 | +@source "../../../../apps/local/src/**/*.{ts,tsx}"; | |
| 7 | +@source "../../../../apps/cloud/src/**/*.{ts,tsx}"; | |
| 8 | +@source "../../../plugins/*/src/react/**/*.{ts,tsx}"; | |
| 10 | 9 | |
| 11 | 10 | @theme inline { |
| 12 | 11 | --font-sans: "DM Sans", ui-sans-serif, system-ui, sans-serif; |