From a501a53ebe3cc9e97aa0c96371df0e56657550f0 Mon Sep 17 00:00:00 2001 From: Adam Leith Date: Tue, 2 Jun 2026 10:07:10 +0100 Subject: [PATCH] feat(code): introduce TanStack Router file-based routing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the Zustand-driven view switch in MainLayout with TanStack Router (hash history for Electron file:// compatibility). Routes nest under `/code/*` for task surfaces, leaving room for future verticals at the root. - 10 routes generated from `apps/code/src/renderer/routes/`: - `/` → redirect to `/code` - `/code` → TaskInput - `/code/tasks/$taskId` → TaskDetail - `/code/tasks/pending/$key` → TaskPendingView - `/code/inbox`, `/code/archived` - `/settings/$category` (+ `/settings` redirect to `general`) - `/command-center`, `/skills`, `/mcp-servers` - `/folders/$folderId` - `__root.tsx` keeps existing chrome (HeaderRow, MainSidebar, SpaceSwitcher, modals, deep-link hooks) and renders `` where the view-switch was. - `navigationStore` and `settingsDialogStore` kept as transitional shims that mirror their actions to `router.navigate(...)` via a new `syncToRouter` helper, so the ~35 nav-store and ~20 settings-dialog consumers keep working without per-call migration. - TanStack Router DevTools mounted in dev only. Follow-up PRs noted in the PR description. Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitignore | 3 + apps/code/package.json | 4 + apps/code/scripts/generate-routes.mjs | 20 + apps/code/src/renderer/App.tsx | 5 +- .../stores/settingsDialogStore.test.ts | 8 + .../settings/stores/settingsDialogStore.ts | 29 +- apps/code/src/renderer/router.ts | 18 + .../MainLayout.tsx => routes/__root.tsx} | 74 +--- .../src/renderer/routes/code/archived.tsx | 6 + apps/code/src/renderer/routes/code/inbox.tsx | 6 + apps/code/src/renderer/routes/code/index.tsx | 44 ++ .../renderer/routes/code/tasks/$taskId.tsx | 43 ++ .../routes/code/tasks/pending.$key.tsx | 11 + .../src/renderer/routes/command-center.tsx | 6 + .../src/renderer/routes/folders/$folderId.tsx | 6 + apps/code/src/renderer/routes/index.tsx | 7 + apps/code/src/renderer/routes/mcp-servers.tsx | 6 + .../renderer/routes/settings/$category.tsx | 54 +++ .../src/renderer/routes/settings/index.tsx | 10 + apps/code/src/renderer/routes/skills.tsx | 6 + .../src/renderer/stores/navigationStore.ts | 54 +++ apps/code/vite.renderer.config.mts | 10 + pnpm-lock.yaml | 394 +++++++++++++++--- 23 files changed, 705 insertions(+), 119 deletions(-) create mode 100644 apps/code/scripts/generate-routes.mjs create mode 100644 apps/code/src/renderer/router.ts rename apps/code/src/renderer/{components/MainLayout.tsx => routes/__root.tsx} (68%) create mode 100644 apps/code/src/renderer/routes/code/archived.tsx create mode 100644 apps/code/src/renderer/routes/code/inbox.tsx create mode 100644 apps/code/src/renderer/routes/code/index.tsx create mode 100644 apps/code/src/renderer/routes/code/tasks/$taskId.tsx create mode 100644 apps/code/src/renderer/routes/code/tasks/pending.$key.tsx create mode 100644 apps/code/src/renderer/routes/command-center.tsx create mode 100644 apps/code/src/renderer/routes/folders/$folderId.tsx create mode 100644 apps/code/src/renderer/routes/index.tsx create mode 100644 apps/code/src/renderer/routes/mcp-servers.tsx create mode 100644 apps/code/src/renderer/routes/settings/$category.tsx create mode 100644 apps/code/src/renderer/routes/settings/index.tsx create mode 100644 apps/code/src/renderer/routes/skills.tsx diff --git a/.gitignore b/.gitignore index 90dbc33161..85b203236b 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,9 @@ out/ storybook-static bin/ +# TanStack Router generated route tree +apps/code/src/renderer/routeTree.gen.ts + # Environment .env .env.local diff --git a/apps/code/package.json b/apps/code/package.json index 4fb9ab883c..5910321df0 100644 --- a/apps/code/package.json +++ b/apps/code/package.json @@ -23,6 +23,7 @@ "build-icons": "bash scripts/generate-icns.sh", "typecheck": "tsc -p tsconfig.node.json --noEmit && tsc -p tsconfig.web.json --noEmit", "generate-client": "tsx scripts/update-openapi-client.ts", + "generate-routes": "node scripts/generate-routes.mjs", "test": "vitest run", "test:e2e": "playwright test --config=tests/e2e/playwright.config.ts", "test:e2e:headed": "playwright test --config=tests/e2e/playwright.config.ts --headed", @@ -143,6 +144,9 @@ "@radix-ui/themes": "^3.2.1", "@tailwindcss/vite": "^4.2.2", "@tanstack/react-query": "^5.90.2", + "@tanstack/react-router": "^1.95.0", + "@tanstack/react-router-devtools": "^1.95.0", + "@tanstack/router-plugin": "^1.95.0", "@tiptap/core": "^3.13.0", "@tiptap/extension-mention": "^3.13.0", "@tiptap/extension-placeholder": "^3.13.0", diff --git a/apps/code/scripts/generate-routes.mjs b/apps/code/scripts/generate-routes.mjs new file mode 100644 index 0000000000..1f3e122615 --- /dev/null +++ b/apps/code/scripts/generate-routes.mjs @@ -0,0 +1,20 @@ +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { Generator, getConfig } from "@tanstack/router-generator"; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const root = path.resolve(__dirname, ".."); + +const config = getConfig( + { + target: "react", + autoCodeSplitting: true, + routesDirectory: path.resolve(root, "src/renderer/routes"), + generatedRouteTree: path.resolve(root, "src/renderer/routeTree.gen.ts"), + }, + root, +); + +const generator = new Generator({ config, root }); +await generator.run(); +console.log("Generated routeTree.gen.ts"); diff --git a/apps/code/src/renderer/App.tsx b/apps/code/src/renderer/App.tsx index a5748db25b..adda957201 100644 --- a/apps/code/src/renderer/App.tsx +++ b/apps/code/src/renderer/App.tsx @@ -1,6 +1,5 @@ import { ErrorBoundary } from "@components/ErrorBoundary"; import { LoginTransition } from "@components/LoginTransition"; -import { MainLayout } from "@components/MainLayout"; import { ScopeReauthPrompt } from "@components/ScopeReauthPrompt"; import { AiApprovalScreen } from "@features/ai-approval/components/AiApprovalScreen"; import { AuthScreen } from "@features/auth/components/AuthScreen"; @@ -18,6 +17,7 @@ import { OnboardingFlow } from "@features/onboarding/components/OnboardingFlow"; import { useOnboardingStore } from "@features/onboarding/stores/onboardingStore"; import { Flex, Spinner, Text } from "@radix-ui/themes"; import { initializeConnectivityToast } from "@renderer/features/connectivity/connectivityToast"; +import { router } from "@renderer/router"; import { initializeConnectivityStore } from "@renderer/stores/connectivityStore"; import { useFocusStore } from "@renderer/stores/focusStore"; import { useThemeStore } from "@renderer/stores/themeStore"; @@ -26,6 +26,7 @@ import { trpcClient, useTRPC } from "@renderer/trpc/client"; import { isNotAuthenticatedError } from "@shared/errors"; import { ANALYTICS_EVENTS } from "@shared/types/analytics"; import { useQueryClient } from "@tanstack/react-query"; +import { RouterProvider } from "@tanstack/react-router"; import { useSubscription } from "@trpc/tanstack-react-query"; import { initializePostHog, registerAppVersion, track } from "@utils/analytics"; import { logger } from "@utils/logger"; @@ -292,7 +293,7 @@ function App() { animate={{ opacity: 1 }} transition={{ duration: 0.5, delay: showTransition ? 0.5 : 0 }} > - + ); }; diff --git a/apps/code/src/renderer/features/settings/stores/settingsDialogStore.test.ts b/apps/code/src/renderer/features/settings/stores/settingsDialogStore.test.ts index 1751746cc0..d5166cfc92 100644 --- a/apps/code/src/renderer/features/settings/stores/settingsDialogStore.test.ts +++ b/apps/code/src/renderer/features/settings/stores/settingsDialogStore.test.ts @@ -1,4 +1,12 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; + +vi.mock("@renderer/router", () => ({ + router: { + navigate: vi.fn(), + state: { matches: [] }, + }, +})); + import { useSettingsDialogStore } from "./settingsDialogStore"; describe("settingsDialogStore", () => { diff --git a/apps/code/src/renderer/features/settings/stores/settingsDialogStore.ts b/apps/code/src/renderer/features/settings/stores/settingsDialogStore.ts index b3c1557cf0..7d673ff6f0 100644 --- a/apps/code/src/renderer/features/settings/stores/settingsDialogStore.ts +++ b/apps/code/src/renderer/features/settings/stores/settingsDialogStore.ts @@ -1,3 +1,4 @@ +import { router } from "@renderer/router"; import { create } from "zustand"; export type SettingsCategory = @@ -56,16 +57,22 @@ export const useSettingsDialogStore = create()( window.history.pushState({ settingsOpen: true }, ""); } const isAction = typeof contextOrAction === "string"; + const nextCategory = category ?? get().activeCategory; set({ isOpen: true, - activeCategory: category ?? get().activeCategory, + activeCategory: nextCategory, context: isAction ? {} : (contextOrAction ?? {}), initialAction: isAction ? contextOrAction : null, formMode: false, }); + void router.navigate({ + to: "/settings/$category", + params: { category: nextCategory }, + }); }, close: () => { - if (get().isOpen && window.history.state?.settingsOpen) { + const wasOpen = get().isOpen; + if (wasOpen && window.history.state?.settingsOpen) { window.history.back(); } set({ @@ -74,9 +81,23 @@ export const useSettingsDialogStore = create()( initialAction: null, formMode: false, }); + if (wasOpen) { + const matches = router.state.matches; + const onSettings = matches.some((m) => + m.routeId.startsWith("/settings"), + ); + if (onSettings) { + void router.navigate({ to: "/code" }); + } + } + }, + setCategory: (category) => { + set({ activeCategory: category, initialAction: null, formMode: false }); + void router.navigate({ + to: "/settings/$category", + params: { category }, + }); }, - setCategory: (category) => - set({ activeCategory: category, initialAction: null, formMode: false }), clearContext: () => set({ context: {} }), consumeInitialAction: () => { const action = get().initialAction; diff --git a/apps/code/src/renderer/router.ts b/apps/code/src/renderer/router.ts new file mode 100644 index 0000000000..2584c73894 --- /dev/null +++ b/apps/code/src/renderer/router.ts @@ -0,0 +1,18 @@ +import { + createHashHistory, + createRouter as createTanStackRouter, +} from "@tanstack/react-router"; +import { routeTree } from "./routeTree.gen"; + +export const router = createTanStackRouter({ + routeTree, + history: createHashHistory(), + defaultPreload: "intent", + scrollRestoration: false, +}); + +declare module "@tanstack/react-router" { + interface Register { + router: typeof router; + } +} diff --git a/apps/code/src/renderer/components/MainLayout.tsx b/apps/code/src/renderer/routes/__root.tsx similarity index 68% rename from apps/code/src/renderer/components/MainLayout.tsx rename to apps/code/src/renderer/routes/__root.tsx index ff1d04eecf..fb6b12e41a 100644 --- a/apps/code/src/renderer/components/MainLayout.tsx +++ b/apps/code/src/renderer/routes/__root.tsx @@ -2,24 +2,14 @@ import { HeaderRow } from "@components/HeaderRow"; import { HedgehogMode } from "@components/HedgehogMode"; import { KeyboardShortcutsSheet } from "@components/KeyboardShortcutsSheet"; import { SpaceSwitcher } from "@components/SpaceSwitcher"; - -import { ArchivedTasksView } from "@features/archive/components/ArchivedTasksView"; import { UsageLimitModal } from "@features/billing/components/UsageLimitModal"; import { CommandMenu } from "@features/command/components/CommandMenu"; -import { CommandCenterView } from "@features/command-center/components/CommandCenterView"; -import { InboxView } from "@features/inbox/components/InboxView"; import { useInboxDeepLink } from "@features/inbox/hooks/useInboxDeepLink"; -import { McpServersView } from "@features/mcp-servers/components/McpServersView"; -import { FolderSettingsView } from "@features/settings/components/FolderSettingsView"; import { SettingsDialog } from "@features/settings/components/SettingsDialog"; import { useSetupDiscovery } from "@features/setup/hooks/useSetupDiscovery"; import { MainSidebar } from "@features/sidebar/components/MainSidebar"; import { useSidebarData } from "@features/sidebar/hooks/useSidebarData"; import { useVisualTaskOrder } from "@features/sidebar/hooks/useVisualTaskOrder"; -import { SkillsView } from "@features/skills/components/SkillsView"; -import { TaskDetail } from "@features/task-detail/components/TaskDetail"; -import { TaskInput } from "@features/task-detail/components/TaskInput"; -import { TaskPendingView } from "@features/task-detail/components/TaskPendingView"; import { useTasks } from "@features/tasks/hooks/useTasks"; import { TourOverlay } from "@features/tour/components/TourOverlay"; import { @@ -35,23 +25,23 @@ import { useCommandMenuStore } from "@stores/commandMenuStore"; import { useNavigationStore } from "@stores/navigationStore"; import { useShortcutsSheetStore } from "@stores/shortcutsSheetStore"; import { useQueryClient } from "@tanstack/react-query"; +import { createRootRoute, Outlet } from "@tanstack/react-router"; +import { TanStackRouterDevtools } from "@tanstack/react-router-devtools"; import { logger } from "@utils/logger"; import { useCallback, useEffect, useRef } from "react"; +import { GlobalEventHandlers } from "../components/GlobalEventHandlers"; import { useNewTaskDeepLink } from "../hooks/useNewTaskDeepLink"; import { useTaskDeepLink } from "../hooks/useTaskDeepLink"; -import { GlobalEventHandlers } from "./GlobalEventHandlers"; -const log = logger.scope("main-layout"); +const log = logger.scope("root-route"); -export function MainLayout() { - const { - view, - hydrateTask, - navigateToTaskInput, - navigateToTask, - taskInputReportAssociation, - taskInputCloudRepository, - } = useNavigationStore(); +export const Route = createRootRoute({ + component: RootLayout, +}); + +function RootLayout() { + const { view, hydrateTask, navigateToTaskInput, navigateToTask } = + useNavigationStore(); const { isOpen: commandMenuOpen, setOpen: setCommandMenuOpen, @@ -70,7 +60,6 @@ export function MainLayout() { const billingEnabled = useFeatureFlag(BILLING_FLAG); const syncCloudTasksEnabled = useFeatureFlag(SYNC_CLOUD_TASKS_FLAG); - // Space switcher data const sidebarData = useSidebarData({ activeView: view }); const visualTaskOrder = useVisualTaskOrder(sidebarData); const activeTaskId = @@ -100,8 +89,6 @@ export function MainLayout() { if (missing.length === 0) return; const missingIds = missing.map((t) => t.id); for (const id of missingIds) reconcilingTaskIds.current.add(id); - // Single batched IPC instead of one mutation per task — with many cloud - // tasks the per-task pattern saturates the main thread at boot. workspaceApi .reconcileCloudWorkspaces(missingIds) .then((result) => { @@ -140,42 +127,8 @@ export function MainLayout() { - - {view.type === "task-input" && ( - - )} - - {view.type === "task-detail" && view.data && ( - - )} - - {view.type === "task-pending" && view.pendingTaskKey && ( - - )} - - {view.type === "folder-settings" && } - - {view.type === "inbox" && } - - {view.type === "archived" && } - - {view.type === "command-center" && } - - {view.type === "skills" && } - - {view.type === "mcp-servers" && } + @@ -200,6 +153,9 @@ export function MainLayout() { {billingEnabled && } + {import.meta.env.DEV && ( + + )} ); } diff --git a/apps/code/src/renderer/routes/code/archived.tsx b/apps/code/src/renderer/routes/code/archived.tsx new file mode 100644 index 0000000000..6b5978376b --- /dev/null +++ b/apps/code/src/renderer/routes/code/archived.tsx @@ -0,0 +1,6 @@ +import { ArchivedTasksView } from "@features/archive/components/ArchivedTasksView"; +import { createFileRoute } from "@tanstack/react-router"; + +export const Route = createFileRoute("/code/archived")({ + component: ArchivedTasksView, +}); diff --git a/apps/code/src/renderer/routes/code/inbox.tsx b/apps/code/src/renderer/routes/code/inbox.tsx new file mode 100644 index 0000000000..5294f31d60 --- /dev/null +++ b/apps/code/src/renderer/routes/code/inbox.tsx @@ -0,0 +1,6 @@ +import { InboxView } from "@features/inbox/components/InboxView"; +import { createFileRoute } from "@tanstack/react-router"; + +export const Route = createFileRoute("/code/inbox")({ + component: InboxView, +}); diff --git a/apps/code/src/renderer/routes/code/index.tsx b/apps/code/src/renderer/routes/code/index.tsx new file mode 100644 index 0000000000..49dffb87b0 --- /dev/null +++ b/apps/code/src/renderer/routes/code/index.tsx @@ -0,0 +1,44 @@ +import { TaskInput } from "@features/task-detail/components/TaskInput"; +import { useNavigationStore } from "@stores/navigationStore"; +import { createFileRoute } from "@tanstack/react-router"; + +export const Route = createFileRoute("/code/")({ + component: CodeIndexRoute, +}); + +function CodeIndexRoute() { + const view = useNavigationStore((s) => s.view); + const taskInputReportAssociation = useNavigationStore( + (s) => s.taskInputReportAssociation, + ); + const taskInputCloudRepository = useNavigationStore( + (s) => s.taskInputCloudRepository, + ); + + const initialPrompt = + view.type === "task-input" ? view.initialPrompt : undefined; + const initialPromptKey = + view.type === "task-input" ? view.taskInputRequestId : undefined; + const initialCloudRepository = + view.type === "task-input" + ? (view.initialCloudRepository ?? taskInputCloudRepository) + : taskInputCloudRepository; + const initialModel = + view.type === "task-input" ? view.initialModel : undefined; + const initialMode = view.type === "task-input" ? view.initialMode : undefined; + const reportAssociation = + view.type === "task-input" + ? (view.reportAssociation ?? taskInputReportAssociation) + : taskInputReportAssociation; + + return ( + + ); +} diff --git a/apps/code/src/renderer/routes/code/tasks/$taskId.tsx b/apps/code/src/renderer/routes/code/tasks/$taskId.tsx new file mode 100644 index 0000000000..1321b8a630 --- /dev/null +++ b/apps/code/src/renderer/routes/code/tasks/$taskId.tsx @@ -0,0 +1,43 @@ +import { TaskDetail } from "@features/task-detail/components/TaskDetail"; +import { useTasks } from "@features/tasks/hooks/useTasks"; +import { useNavigationStore } from "@stores/navigationStore"; +import { createFileRoute } from "@tanstack/react-router"; +import { useEffect } from "react"; + +export const Route = createFileRoute("/code/tasks/$taskId")({ + component: TaskDetailRoute, +}); + +function TaskDetailRoute() { + const { taskId } = Route.useParams(); + const { data: tasks } = useTasks(); + const taskFromList = tasks?.find((t) => t.id === taskId); + + // Silent sync of nav store to URL. Reads/writes via getState/setState so we + // don't trigger the store's navigate() helper, which would call + // router.navigate and fight with whatever navigation just landed us here. + useEffect(() => { + if (!taskFromList) return; + const state = useNavigationStore.getState(); + if ( + state.view.type === "task-detail" && + state.view.data?.id === taskFromList.id + ) { + return; + } + useNavigationStore.setState({ + view: { + type: "task-detail", + data: taskFromList, + taskId: taskFromList.id, + }, + }); + }, [taskFromList]); + + const task = taskFromList; + if (!task) { + return null; + } + + return ; +} diff --git a/apps/code/src/renderer/routes/code/tasks/pending.$key.tsx b/apps/code/src/renderer/routes/code/tasks/pending.$key.tsx new file mode 100644 index 0000000000..d976aeb87e --- /dev/null +++ b/apps/code/src/renderer/routes/code/tasks/pending.$key.tsx @@ -0,0 +1,11 @@ +import { TaskPendingView } from "@features/task-detail/components/TaskPendingView"; +import { createFileRoute } from "@tanstack/react-router"; + +export const Route = createFileRoute("/code/tasks/pending/$key")({ + component: TaskPendingRoute, +}); + +function TaskPendingRoute() { + const { key } = Route.useParams(); + return ; +} diff --git a/apps/code/src/renderer/routes/command-center.tsx b/apps/code/src/renderer/routes/command-center.tsx new file mode 100644 index 0000000000..2f9393958b --- /dev/null +++ b/apps/code/src/renderer/routes/command-center.tsx @@ -0,0 +1,6 @@ +import { CommandCenterView } from "@features/command-center/components/CommandCenterView"; +import { createFileRoute } from "@tanstack/react-router"; + +export const Route = createFileRoute("/command-center")({ + component: CommandCenterView, +}); diff --git a/apps/code/src/renderer/routes/folders/$folderId.tsx b/apps/code/src/renderer/routes/folders/$folderId.tsx new file mode 100644 index 0000000000..2a5b9e0884 --- /dev/null +++ b/apps/code/src/renderer/routes/folders/$folderId.tsx @@ -0,0 +1,6 @@ +import { FolderSettingsView } from "@features/settings/components/FolderSettingsView"; +import { createFileRoute } from "@tanstack/react-router"; + +export const Route = createFileRoute("/folders/$folderId")({ + component: FolderSettingsView, +}); diff --git a/apps/code/src/renderer/routes/index.tsx b/apps/code/src/renderer/routes/index.tsx new file mode 100644 index 0000000000..fef5274c32 --- /dev/null +++ b/apps/code/src/renderer/routes/index.tsx @@ -0,0 +1,7 @@ +import { createFileRoute, redirect } from "@tanstack/react-router"; + +export const Route = createFileRoute("/")({ + beforeLoad: () => { + throw redirect({ to: "/code" }); + }, +}); diff --git a/apps/code/src/renderer/routes/mcp-servers.tsx b/apps/code/src/renderer/routes/mcp-servers.tsx new file mode 100644 index 0000000000..38eedecbca --- /dev/null +++ b/apps/code/src/renderer/routes/mcp-servers.tsx @@ -0,0 +1,6 @@ +import { McpServersView } from "@features/mcp-servers/components/McpServersView"; +import { createFileRoute } from "@tanstack/react-router"; + +export const Route = createFileRoute("/mcp-servers")({ + component: McpServersView, +}); diff --git a/apps/code/src/renderer/routes/settings/$category.tsx b/apps/code/src/renderer/routes/settings/$category.tsx new file mode 100644 index 0000000000..8ed11cc9c5 --- /dev/null +++ b/apps/code/src/renderer/routes/settings/$category.tsx @@ -0,0 +1,54 @@ +import { + type SettingsCategory, + useSettingsDialogStore, +} from "@features/settings/stores/settingsDialogStore"; +import { createFileRoute } from "@tanstack/react-router"; +import { useEffect } from "react"; + +const VALID_CATEGORIES: SettingsCategory[] = [ + "general", + "plan-usage", + "workspaces", + "worktrees", + "environments", + "cloud-environments", + "personalization", + "terminal", + "claude-code", + "shortcuts", + "github", + "slack", + "signals", + "updates", + "advanced", +]; + +export const Route = createFileRoute("/settings/$category")({ + component: SettingsRoute, +}); + +function SettingsRoute() { + const { category } = Route.useParams(); + + useEffect(() => { + const cat = VALID_CATEGORIES.includes(category as SettingsCategory) + ? (category as SettingsCategory) + : "general"; + const store = useSettingsDialogStore.getState(); + if (!store.isOpen || store.activeCategory !== cat) { + store.open(cat); + } + return () => { + // Closing here would trigger close()'s navigate-to-/code, which is the + // desired behavior when the user navigates away from the settings URL. + // The dialog component closes itself on Escape; this cleanup only fires + // when the route is unmounted by router navigation. + const current = useSettingsDialogStore.getState(); + if (current.isOpen && current.activeCategory === cat) { + useSettingsDialogStore.setState({ isOpen: false }); + } + }; + }, [category]); + + return null; +} diff --git a/apps/code/src/renderer/routes/settings/index.tsx b/apps/code/src/renderer/routes/settings/index.tsx new file mode 100644 index 0000000000..e842724ca5 --- /dev/null +++ b/apps/code/src/renderer/routes/settings/index.tsx @@ -0,0 +1,10 @@ +import { createFileRoute, redirect } from "@tanstack/react-router"; + +export const Route = createFileRoute("/settings/")({ + beforeLoad: () => { + throw redirect({ + to: "/settings/$category", + params: { category: "general" }, + }); + }, +}); diff --git a/apps/code/src/renderer/routes/skills.tsx b/apps/code/src/renderer/routes/skills.tsx new file mode 100644 index 0000000000..1a10d4b74e --- /dev/null +++ b/apps/code/src/renderer/routes/skills.tsx @@ -0,0 +1,6 @@ +import { SkillsView } from "@features/skills/components/SkillsView"; +import { createFileRoute } from "@tanstack/react-router"; + +export const Route = createFileRoute("/skills")({ + component: SkillsView, +}); diff --git a/apps/code/src/renderer/stores/navigationStore.ts b/apps/code/src/renderer/stores/navigationStore.ts index 3bfb98fb3b..615fb41c02 100644 --- a/apps/code/src/renderer/stores/navigationStore.ts +++ b/apps/code/src/renderer/stores/navigationStore.ts @@ -1,6 +1,7 @@ import { foldersApi } from "@features/folders/hooks/useFolders"; import { workspaceApi } from "@features/workspace/hooks/useWorkspace"; import { getTaskDirectory } from "@hooks/useRepositoryDirectory"; +import { router } from "@renderer/router"; import type { Task } from "@shared/types"; import { ANALYTICS_EVENTS } from "@shared/types/analytics"; import { setActiveTaskAnalyticsContext, track } from "@utils/analytics"; @@ -12,6 +13,56 @@ import { persist } from "zustand/middleware"; const log = logger.scope("navigation-store"); +// Mirror nav store actions to the router URL so deep-links, back/forward, and +// future per-route logic stay coherent. This store is a transitional shim +// until consumers are ported to use router APIs directly. +const syncToRouter = (view: ViewState) => { + switch (view.type) { + case "task-input": + void router.navigate({ to: "/code" }); + return; + case "task-detail": + if (view.taskId || view.data?.id) { + void router.navigate({ + to: "/code/tasks/$taskId", + params: { taskId: view.taskId ?? (view.data?.id as string) }, + }); + } + return; + case "task-pending": + if (view.pendingTaskKey) { + void router.navigate({ + to: "/code/tasks/pending/$key", + params: { key: view.pendingTaskKey }, + }); + } + return; + case "folder-settings": + if (view.folderId) { + void router.navigate({ + to: "/folders/$folderId", + params: { folderId: view.folderId }, + }); + } + return; + case "inbox": + void router.navigate({ to: "/code/inbox" }); + return; + case "archived": + void router.navigate({ to: "/code/archived" }); + return; + case "command-center": + void router.navigate({ to: "/command-center" }); + return; + case "skills": + void router.navigate({ to: "/skills" }); + return; + case "mcp-servers": + void router.navigate({ to: "/mcp-servers" }); + return; + } +}; + type ViewType = | "task-detail" | "task-pending" @@ -135,6 +186,7 @@ export const useNavigationStore = create()( setActiveTaskAnalyticsContext( newView.type === "task-detail" ? (newView.data ?? null) : null, ); + syncToRouter(newView); }; return { @@ -317,6 +369,7 @@ export const useNavigationStore = create()( setActiveTaskAnalyticsContext( newView.type === "task-detail" ? (newView.data ?? null) : null, ); + syncToRouter(newView); } }, @@ -332,6 +385,7 @@ export const useNavigationStore = create()( setActiveTaskAnalyticsContext( newView.type === "task-detail" ? (newView.data ?? null) : null, ); + syncToRouter(newView); } }, diff --git a/apps/code/vite.renderer.config.mts b/apps/code/vite.renderer.config.mts index 93842e3cbc..2b285da606 100644 --- a/apps/code/vite.renderer.config.mts +++ b/apps/code/vite.renderer.config.mts @@ -2,6 +2,7 @@ import { readFileSync } from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; import tailwindcss from "@tailwindcss/vite"; +import { TanStackRouterVite } from "@tanstack/router-plugin/vite"; import react from "@vitejs/plugin-react"; import { defineConfig, loadEnv } from "vite"; import tsconfigPaths from "vite-tsconfig-paths"; @@ -21,6 +22,15 @@ export default defineConfig(({ mode }) => { return { plugins: [ + TanStackRouterVite({ + target: "react", + autoCodeSplitting: true, + routesDirectory: path.resolve(__dirname, "src/renderer/routes"), + generatedRouteTree: path.resolve( + __dirname, + "src/renderer/routeTree.gen.ts", + ), + }), tailwindcss(), react(), tsconfigPaths(), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7903846ae2..71f68fad34 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -192,10 +192,19 @@ importers: version: 3.3.0(@types/react-dom@19.2.3(@types/react@19.2.11))(@types/react@19.2.11)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@tailwindcss/vite': specifier: ^4.2.2 - version: 4.2.2(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 4.2.2(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@tanstack/react-query': specifier: ^5.90.2 version: 5.90.20(react@19.1.0) + '@tanstack/react-router': + specifier: ^1.95.0 + version: 1.170.8(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@tanstack/react-router-devtools': + specifier: ^1.95.0 + version: 1.167.0(@tanstack/react-router@1.170.8(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(@tanstack/router-core@1.171.6)(csstype@3.2.3)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@tanstack/router-plugin': + specifier: ^1.95.0 + version: 1.168.11(@tanstack/react-router@1.170.8(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.0(esbuild@0.25.12)) '@tiptap/core': specifier: ^3.13.0 version: 3.19.0(@tiptap/pm@3.19.0) @@ -430,10 +439,10 @@ importers: version: 10.2.0(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)) '@storybook/addon-docs': specifier: 10.2.0 - version: 10.2.0(@types/react@19.2.11)(esbuild@0.25.12)(rollup@4.57.1)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.0(esbuild@0.25.12)) + version: 10.2.0(@types/react@19.2.11)(esbuild@0.25.12)(rollup@4.57.1)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.0(esbuild@0.25.12)) '@storybook/react-vite': specifier: 10.2.0 - version: 10.2.0(esbuild@0.25.12)(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(rollup@4.57.1)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(typescript@5.9.3)(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.0(esbuild@0.25.12)) + version: 10.2.0(esbuild@0.25.12)(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(rollup@4.57.1)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(typescript@5.9.3)(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.0(esbuild@0.25.12)) '@testing-library/jest-dom': specifier: ^6.9.1 version: 6.9.1 @@ -463,7 +472,7 @@ importers: version: 7.7.1 '@vitejs/plugin-react': specifier: ^4.2.1 - version: 4.7.0(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 4.7.0(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/ui': specifier: ^4.0.10 version: 4.0.18(vitest@4.0.18) @@ -517,13 +526,13 @@ importers: version: 0.48.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) vite: specifier: ^6.0.7 - version: 6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.3)(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 5.1.4(typescript@5.9.3)(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) vitest: specifier: ^4.0.10 - version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(@vitest/ui@4.0.18)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.32.0)(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(@vitest/ui@4.0.18)(jiti@2.7.0)(jsdom@26.1.0)(lightningcss@1.32.0)(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) yaml: specifier: ^2.8.1 version: 2.8.2 @@ -535,10 +544,10 @@ importers: version: 0.2.0-beta.9(expo@54.0.33)(react-native@0.81.5(@babel/core@7.29.0)(@types/react@19.2.11)(react@19.1.0))(react@19.1.0) '@modelcontextprotocol/ext-apps': specifier: ^1.2.2 - version: 1.2.2(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(zod@4.3.6) + version: 1.2.2(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(zod@4.4.3) '@modelcontextprotocol/sdk': specifier: ^1.29.0 - version: 1.29.0(zod@4.3.6) + version: 1.29.0(zod@4.4.3) '@posthog/shared': specifier: workspace:* version: link:../../packages/shared @@ -789,7 +798,7 @@ importers: version: 2.12.8(@types/node@25.2.0)(typescript@5.9.3) tsup: specifier: ^8.5.1 - version: 8.5.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) + version: 8.5.1(jiti@2.7.0)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) tsx: specifier: ^4.20.6 version: 4.21.0 @@ -825,7 +834,7 @@ importers: version: 5.9.3 vite: specifier: ^6.0.7 - version: 6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + version: 6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) vitest: specifier: ^2.1.8 version: 2.1.9(@types/node@24.12.0)(jsdom@26.1.0)(lightningcss@1.32.0)(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(terser@5.46.0) @@ -844,7 +853,7 @@ importers: version: 0.26.8 tsup: specifier: ^8.5.1 - version: 8.5.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) + version: 8.5.1(jiti@2.7.0)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) typescript: specifier: ^5.5.0 version: 5.9.3 @@ -878,7 +887,7 @@ importers: devDependencies: tsup: specifier: ^8.5.1 - version: 8.5.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) + version: 8.5.1(jiti@2.7.0)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) typescript: specifier: ^5.5.0 version: 5.9.3 @@ -887,10 +896,10 @@ importers: devDependencies: '@agentclientprotocol/sdk': specifier: 0.19.0 - version: 0.19.0(zod@4.3.6) + version: 0.19.0(zod@4.4.3) tsup: specifier: ^8.5.1 - version: 8.5.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) + version: 8.5.1(jiti@2.7.0)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) typescript: specifier: ^5.5.0 version: 5.9.3 @@ -5034,6 +5043,10 @@ packages: peerDependencies: vite: ^5.2.0 || ^6 || ^7 || ^8 + '@tanstack/history@1.162.0': + resolution: {integrity: sha512-79pf/RkhteYZTRgcR4F9kbk84P2N8rugQJswxfIqovlbRiT3yI7eBE+5QorIrZaOKktsgzRlXh1l/du/xpl4iA==} + engines: {node: '>=20.19'} + '@tanstack/query-core@5.90.20': resolution: {integrity: sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==} @@ -5042,6 +5055,81 @@ packages: peerDependencies: react: ^18 || ^19 + '@tanstack/react-router-devtools@1.167.0': + resolution: {integrity: sha512-nGw095EG7IHx0h5NtlEmzf6vcCTaFNPWdTSuDKazajhN0ct/v/TkekJ9J6KYUCeV1a8/2ZmToc58M+0rrOyn7w==} + engines: {node: '>=20.19'} + peerDependencies: + '@tanstack/react-router': ^1.170.0 + '@tanstack/router-core': ^1.170.0 + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + peerDependenciesMeta: + '@tanstack/router-core': + optional: true + + '@tanstack/react-router@1.170.8': + resolution: {integrity: sha512-Qw2ju6jjnIsMpuW+VrnHZWHuugqs592PWsnI56sG28qNhg14CgRLahOcNajfuJR9P4MxKGP94WVzmFKSYUz/ig==} + engines: {node: '>=20.19'} + peerDependencies: + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + + '@tanstack/react-store@0.9.3': + resolution: {integrity: sha512-y2iHd/N9OkoQbFJLUX1T9vbc2O9tjH0pQRgTcx1/Nz4IlwLvkgpuglXUx+mXt0g5ZDFrEeDnONPqkbfxXJKwRg==} + 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 + + '@tanstack/router-core@1.171.6': + resolution: {integrity: sha512-Ol6DQ+j6rf/rPVELIzo8LHwOQV2KL+zry3b+39kL/GKrt7YId52WJRAFMzuseY4XceSW+PU7sG/Cc1QkwJr0hg==} + engines: {node: '>=20.19'} + + '@tanstack/router-devtools-core@1.168.0': + resolution: {integrity: sha512-wQoQhlBK7nlZgqzaqdYXKWNTpdHdsaREdaPhFZVH0/Ador+F+eM3/NF2i3f2LPeS0GgKraZUQXe1Q/1+KHyEYg==} + engines: {node: '>=20.19'} + peerDependencies: + '@tanstack/router-core': ^1.170.0 + csstype: ^3.0.10 + peerDependenciesMeta: + csstype: + optional: true + + '@tanstack/router-generator@1.167.10': + resolution: {integrity: sha512-CjbjWRSo6djLU/C7ncb9IbKUcf4IwpdqhLGngkwKkXaVFXGxEAafA/uhvOCv/UEUVR7NI3tJqqQmxYXGcJPbjw==} + engines: {node: '>=20.19'} + + '@tanstack/router-plugin@1.168.11': + resolution: {integrity: sha512-b2eom/8xCWL/OiWxKub8kYsr8p+kvmB/eXwYGqCWG8vilcJo+eQCSyp54nKt0AZ5k/ET1+eINc+4mwL3bVeAgg==} + engines: {node: '>=20.19'} + peerDependencies: + '@rsbuild/core': '>=1.0.2 || ^2.0.0' + '@tanstack/react-router': ^1.170.8 + vite: '>=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0' + vite-plugin-solid: ^2.11.10 || ^3.0.0-0 + webpack: '>=5.92.0' + peerDependenciesMeta: + '@rsbuild/core': + optional: true + '@tanstack/react-router': + optional: true + vite: + optional: true + vite-plugin-solid: + optional: true + webpack: + optional: true + + '@tanstack/router-utils@1.162.1': + resolution: {integrity: sha512-62layyTGmclHDQS/eidwKRfN1hhCKwViG7iEBcVmL0MXgcAB3OOucWCEcDDGd9Cu11H6b4QQ5oOo47MWIqwz0A==} + engines: {node: '>=20.19'} + + '@tanstack/store@0.9.3': + resolution: {integrity: sha512-8reSzl/qGWGGVKhBoxXPMWzATSbZLZFWhwBAFO9NAyp0TxzfBP0mIrGb8CP8KrQTmvzXlR/vFPPUrHTLBGyFyw==} + + '@tanstack/virtual-file-routes@1.162.0': + resolution: {integrity: sha512-uhOeFyxLcU41HzvrxsGpiWdcMbScY1EDgbZ5K7DVRMYInbLYWAC0EA/kx9wXAoSM8q82bUG2hRl8+EAjE6XAbA==} + engines: {node: '>=20.19'} + '@testing-library/dom@10.4.1': resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} @@ -5820,6 +5908,10 @@ packages: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} + ansis@4.3.0: + resolution: {integrity: sha512-44mvgtPvohuU/70DdY5Oz2AIrLJ9k6/5x4KmoSvPwO+5Moijo0+N9D0fKbbYZQWP1hNm5CpOf+E01jhxG/r8xg==} + engines: {node: '>=14'} + any-base@1.1.0: resolution: {integrity: sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==} @@ -5914,6 +6006,9 @@ packages: axios@1.15.0: resolution: {integrity: sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==} + babel-dead-code-elimination@1.0.12: + resolution: {integrity: sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==} + babel-jest@29.7.0: resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -6447,6 +6542,9 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie-es@3.1.1: + resolution: {integrity: sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==} + cookie-signature@1.2.2: resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} engines: {node: '>=6.6.0'} @@ -7839,6 +7937,11 @@ packages: globrex@0.1.2: resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + goober@2.1.19: + resolution: {integrity: sha512-U7veizMqxyKlM58+Z5j2ngJBH/r9siDmxpvNxSw0PylF6WQvrASJEZrxh1hidRBJc2jqoBVSyOban5u8m+6Rxg==} + peerDependencies: + csstype: ^3.0.10 + gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} @@ -8292,6 +8395,10 @@ packages: resolution: {integrity: sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==} engines: {node: '>= 8.0.0'} + isbot@5.1.40: + resolution: {integrity: sha512-yNeeynhhtIVRBk12tBV4eHNxwB42HzR4Q3Ea7vCOiJhImGaAIdIMrbJtacQlBizGLjUPw+akkFI5Dn9T70XoVQ==} + engines: {node: '>=18'} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -8392,6 +8499,10 @@ packages: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true + jiti@2.7.0: + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} + hasBin: true + jose@6.2.1: resolution: {integrity: sha512-jUaKr1yrbfaImV7R2TN/b3IcZzsw38/chqMpo2XJ7i2F8AfM/lA4G1goC3JVEwg0H7UldTmSt3P68nt31W7/mw==} @@ -10788,6 +10899,16 @@ packages: serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + seroval-plugins@1.5.4: + resolution: {integrity: sha512-S0xQPhUTefAhNvNWFg0c1J8qJArHt5KdtJ/cFAofo06KD1MVSeFWyl4iiu+ApDIuw0WhjpOfCdgConOfAnLgkw==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + + seroval@1.5.4: + resolution: {integrity: sha512-46uFvgrXTVxZcUorgSSRZ4y+ieqLLQRMlG4bnCZKW3qI6BZm7Rg4ntMW4p1mILEEBZWrFlcpp0AyIIlM6jD9iw==} + engines: {node: '>=10'} + serve-static@1.16.3: resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} engines: {node: '>= 0.8.0'} @@ -11703,6 +11824,10 @@ packages: resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} engines: {node: '>=18.12.0'} + unplugin@3.0.0: + resolution: {integrity: sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg==} + engines: {node: ^20.19.0 || >=22.12.0} + until-async@3.0.2: resolution: {integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==} @@ -12298,6 +12423,9 @@ packages: zod@4.3.6: resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + zod@4.4.3: + resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} + zustand@4.5.7: resolution: {integrity: sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==} engines: {node: '>=12.7.0'} @@ -12329,9 +12457,9 @@ snapshots: '@adobe/css-tools@4.4.4': {} - '@agentclientprotocol/sdk@0.19.0(zod@4.3.6)': + '@agentclientprotocol/sdk@0.19.0(zod@4.4.3)': dependencies: - zod: 4.3.6 + zod: 4.4.3 '@agentclientprotocol/sdk@0.22.1(zod@4.3.6)': dependencies: @@ -14957,11 +15085,11 @@ snapshots: '@jimp/types': 1.6.0 tinycolor2: 1.6.0 - '@joshwooding/vite-plugin-react-docgen-typescript@0.6.3(typescript@5.9.3)(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@joshwooding/vite-plugin-react-docgen-typescript@0.6.3(typescript@5.9.3)(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: glob: 11.1.0 react-docgen-typescript: 2.4.0(typescript@5.9.3) - vite: 6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) optionalDependencies: typescript: 5.9.3 @@ -15244,10 +15372,10 @@ snapshots: react: 19.1.0 react-dom: 19.1.0(react@19.1.0) - '@modelcontextprotocol/ext-apps@1.2.2(@modelcontextprotocol/sdk@1.29.0(zod@4.3.6))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(zod@4.3.6)': + '@modelcontextprotocol/ext-apps@1.2.2(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(zod@4.4.3)': dependencies: - '@modelcontextprotocol/sdk': 1.29.0(zod@4.3.6) - zod: 4.3.6 + '@modelcontextprotocol/sdk': 1.29.0(zod@4.4.3) + zod: 4.4.3 optionalDependencies: react: 19.1.0 react-dom: 19.1.0(react@19.1.0) @@ -15318,6 +15446,28 @@ snapshots: transitivePeerDependencies: - supports-color + '@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)': + dependencies: + '@hono/node-server': 1.19.9(hono@4.11.7) + ajv: 8.17.1 + ajv-formats: 3.0.1(ajv@8.17.1) + content-type: 1.0.5 + cors: 2.8.6 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.0.6 + express: 5.2.1 + express-rate-limit: 8.3.1(express@5.2.1) + hono: 4.11.7 + jose: 6.2.1 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 4.4.3 + zod-to-json-schema: 3.25.1(zod@4.4.3) + transitivePeerDependencies: + - supports-color + '@mswjs/interceptors@0.41.0': dependencies: '@open-draft/deferred-promise': 2.2.0 @@ -16929,10 +17079,10 @@ snapshots: axe-core: 4.11.1 storybook: 10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@storybook/addon-docs@10.2.0(@types/react@19.2.11)(esbuild@0.25.12)(rollup@4.57.1)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.0(esbuild@0.25.12))': + '@storybook/addon-docs@10.2.0(@types/react@19.2.11)(esbuild@0.25.12)(rollup@4.57.1)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.0(esbuild@0.25.12))': dependencies: '@mdx-js/react': 3.1.1(@types/react@19.2.11)(react@19.1.0) - '@storybook/csf-plugin': 10.2.0(esbuild@0.25.12)(rollup@4.57.1)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.0(esbuild@0.25.12)) + '@storybook/csf-plugin': 10.2.0(esbuild@0.25.12)(rollup@4.57.1)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.0(esbuild@0.25.12)) '@storybook/icons': 2.0.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@storybook/react-dom-shim': 10.2.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)) react: 19.1.0 @@ -16946,27 +17096,27 @@ snapshots: - vite - webpack - '@storybook/builder-vite@10.2.0(esbuild@0.25.12)(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(rollup@4.57.1)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.0(esbuild@0.25.12))': + '@storybook/builder-vite@10.2.0(esbuild@0.25.12)(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(rollup@4.57.1)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.0(esbuild@0.25.12))': dependencies: - '@storybook/csf-plugin': 10.2.0(esbuild@0.25.12)(rollup@4.57.1)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.0(esbuild@0.25.12)) - '@vitest/mocker': 3.2.4(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@storybook/csf-plugin': 10.2.0(esbuild@0.25.12)(rollup@4.57.1)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.0(esbuild@0.25.12)) + '@vitest/mocker': 3.2.4(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) storybook: 10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) ts-dedent: 2.2.0 - vite: 6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - esbuild - msw - rollup - webpack - '@storybook/csf-plugin@10.2.0(esbuild@0.25.12)(rollup@4.57.1)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.0(esbuild@0.25.12))': + '@storybook/csf-plugin@10.2.0(esbuild@0.25.12)(rollup@4.57.1)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.0(esbuild@0.25.12))': dependencies: storybook: 10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) unplugin: 2.3.11 optionalDependencies: esbuild: 0.25.12 rollup: 4.57.1 - vite: 6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) webpack: 5.105.0(esbuild@0.25.12) '@storybook/global@5.0.0': {} @@ -16982,11 +17132,11 @@ snapshots: react-dom: 19.1.0(react@19.1.0) storybook: 10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@storybook/react-vite@10.2.0(esbuild@0.25.12)(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(rollup@4.57.1)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(typescript@5.9.3)(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.0(esbuild@0.25.12))': + '@storybook/react-vite@10.2.0(esbuild@0.25.12)(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(rollup@4.57.1)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(typescript@5.9.3)(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.0(esbuild@0.25.12))': dependencies: - '@joshwooding/vite-plugin-react-docgen-typescript': 0.6.3(typescript@5.9.3)(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@joshwooding/vite-plugin-react-docgen-typescript': 0.6.3(typescript@5.9.3)(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@rollup/pluginutils': 5.3.0(rollup@4.57.1) - '@storybook/builder-vite': 10.2.0(esbuild@0.25.12)(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(rollup@4.57.1)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.0(esbuild@0.25.12)) + '@storybook/builder-vite': 10.2.0(esbuild@0.25.12)(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(rollup@4.57.1)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.0(esbuild@0.25.12)) '@storybook/react': 10.2.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(storybook@10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(typescript@5.9.3) empathic: 2.0.0 magic-string: 0.30.21 @@ -16996,7 +17146,7 @@ snapshots: resolve: 1.22.11 storybook: 10.2.0(@testing-library/dom@10.4.1)(prettier@3.8.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) tsconfig-paths: 4.2.0 - vite: 6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - esbuild - msw @@ -17162,12 +17312,14 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.2.2 '@tailwindcss/oxide-win32-x64-msvc': 4.2.2 - '@tailwindcss/vite@4.2.2(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@tailwindcss/vite@4.2.2(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@tailwindcss/node': 4.2.2 '@tailwindcss/oxide': 4.2.2 tailwindcss: 4.2.2 - vite: 6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + + '@tanstack/history@1.162.0': {} '@tanstack/query-core@5.90.20': {} @@ -17176,6 +17328,101 @@ snapshots: '@tanstack/query-core': 5.90.20 react: 19.1.0 + '@tanstack/react-router-devtools@1.167.0(@tanstack/react-router@1.170.8(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(@tanstack/router-core@1.171.6)(csstype@3.2.3)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@tanstack/react-router': 1.170.8(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@tanstack/router-devtools-core': 1.168.0(@tanstack/router-core@1.171.6)(csstype@3.2.3) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@tanstack/router-core': 1.171.6 + transitivePeerDependencies: + - csstype + + '@tanstack/react-router@1.170.8(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@tanstack/history': 1.162.0 + '@tanstack/react-store': 0.9.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@tanstack/router-core': 1.171.6 + isbot: 5.1.40 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + '@tanstack/react-store@0.9.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@tanstack/store': 0.9.3 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + use-sync-external-store: 1.6.0(react@19.1.0) + + '@tanstack/router-core@1.171.6': + dependencies: + '@tanstack/history': 1.162.0 + cookie-es: 3.1.1 + seroval: 1.5.4 + seroval-plugins: 1.5.4(seroval@1.5.4) + + '@tanstack/router-devtools-core@1.168.0(@tanstack/router-core@1.171.6)(csstype@3.2.3)': + dependencies: + '@tanstack/router-core': 1.171.6 + clsx: 2.1.1 + goober: 2.1.19(csstype@3.2.3) + optionalDependencies: + csstype: 3.2.3 + + '@tanstack/router-generator@1.167.10': + dependencies: + '@babel/types': 7.29.0 + '@tanstack/router-core': 1.171.6 + '@tanstack/router-utils': 1.162.1 + '@tanstack/virtual-file-routes': 1.162.0 + jiti: 2.7.0 + magic-string: 0.30.21 + prettier: 3.8.1 + zod: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@tanstack/router-plugin@1.168.11(@tanstack/react-router@1.170.8(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))(webpack@5.105.0(esbuild@0.25.12))': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@tanstack/router-core': 1.171.6 + '@tanstack/router-generator': 1.167.10 + '@tanstack/router-utils': 1.162.1 + '@tanstack/virtual-file-routes': 1.162.0 + chokidar: 5.0.0 + unplugin: 3.0.0 + zod: 4.4.3 + optionalDependencies: + '@tanstack/react-router': 1.170.8(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + vite: 6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + webpack: 5.105.0(esbuild@0.25.12) + transitivePeerDependencies: + - supports-color + + '@tanstack/router-utils@1.162.1': + dependencies: + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 + ansis: 4.3.0 + babel-dead-code-elimination: 1.0.12 + diff: 8.0.3 + pathe: 2.0.3 + tinyglobby: 0.2.15 + transitivePeerDependencies: + - supports-color + + '@tanstack/store@0.9.3': {} + + '@tanstack/virtual-file-routes@1.162.0': {} + '@testing-library/dom@10.4.1': dependencies: '@babel/code-frame': 7.29.0 @@ -17670,7 +17917,7 @@ snapshots: '@urql/core': 5.2.0(graphql@16.12.0) wonka: 6.3.5 - '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@babel/core': 7.29.0 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) @@ -17678,7 +17925,7 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 - vite: 6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color @@ -17762,23 +18009,23 @@ snapshots: msw: 2.12.8(@types/node@25.2.0)(typescript@5.9.3) vite: 5.4.21(@types/node@25.2.0)(lightningcss@1.32.0)(terser@5.46.0) - '@vitest/mocker@3.2.4(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@3.2.4(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: msw: 2.12.8(@types/node@24.12.0)(typescript@5.9.3) - vite: 6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - '@vitest/mocker@4.0.18(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/mocker@4.0.18(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@vitest/spy': 4.0.18 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: msw: 2.12.8(@types/node@24.12.0)(typescript@5.9.3) - vite: 6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) '@vitest/mocker@4.1.6(msw@2.12.8(@types/node@25.2.0)(typescript@5.9.3))(vite@6.4.1(@types/node@25.2.0)(jiti@1.21.7)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: @@ -17860,7 +18107,7 @@ snapshots: sirv: 3.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(@vitest/ui@4.0.18)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.32.0)(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(@vitest/ui@4.0.18)(jiti@2.7.0)(jsdom@26.1.0)(lightningcss@1.32.0)(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) '@vitest/utils@2.1.9': dependencies: @@ -18084,6 +18331,8 @@ snapshots: ansi-styles@6.2.3: {} + ansis@4.3.0: {} + any-base@1.1.0: {} any-promise@1.3.0: {} @@ -18185,6 +18434,15 @@ snapshots: transitivePeerDependencies: - debug + babel-dead-code-elimination@1.0.12: + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.0 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + babel-jest@29.7.0(@babel/core@7.29.0): dependencies: '@babel/core': 7.29.0 @@ -18818,6 +19076,8 @@ snapshots: convert-source-map@2.0.0: {} + cookie-es@3.1.1: {} + cookie-signature@1.2.2: {} cookie@0.7.2: {} @@ -20309,6 +20569,10 @@ snapshots: globrex@0.1.2: {} + goober@2.1.19(csstype@3.2.3): + dependencies: + csstype: 3.2.3 + gopd@1.2.0: {} got@11.8.6: @@ -20765,6 +21029,8 @@ snapshots: isbinaryfile@4.0.10: {} + isbot@5.1.40: {} + isexe@2.0.0: {} isexe@3.1.1: {} @@ -20940,6 +21206,8 @@ snapshots: jiti@2.6.1: {} + jiti@2.7.0: {} + jose@6.2.1: {} joycon@3.1.1: {} @@ -22826,11 +23094,11 @@ snapshots: tsx: 4.21.0 yaml: 2.8.2 - postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.2): + postcss-load-config@6.0.1(jiti@2.7.0)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.2): dependencies: lilconfig: 3.1.3 optionalDependencies: - jiti: 2.6.1 + jiti: 2.7.0 postcss: 8.5.6 tsx: 4.21.0 yaml: 2.8.2 @@ -23913,6 +24181,12 @@ snapshots: dependencies: randombytes: 2.1.0 + seroval-plugins@1.5.4(seroval@1.5.4): + dependencies: + seroval: 1.5.4 + + seroval@1.5.4: {} + serve-static@1.16.3: dependencies: encodeurl: 2.0.0 @@ -24651,7 +24925,7 @@ snapshots: tslib@2.8.1: {} - tsup@8.5.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2): + tsup@8.5.1(jiti@2.7.0)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2): dependencies: bundle-require: 5.1.0(esbuild@0.27.2) cac: 6.7.14 @@ -24662,7 +24936,7 @@ snapshots: fix-dts-default-cjs-exports: 1.0.1 joycon: 3.1.1 picocolors: 1.1.1 - postcss-load-config: 6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.2) + postcss-load-config: 6.0.1(jiti@2.7.0)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.2) resolve-from: 5.0.0 rollup: 4.57.1 source-map: 0.7.6 @@ -24869,6 +25143,12 @@ snapshots: picomatch: 4.0.3 webpack-virtual-modules: 0.6.2 + unplugin@3.0.0: + dependencies: + '@jridgewell/remapping': 2.3.5 + picomatch: 4.0.3 + webpack-virtual-modules: 0.6.2 + until-async@3.0.2: {} update-browserslist-db@1.2.3(browserslist@4.28.1): @@ -25009,13 +25289,13 @@ snapshots: - supports-color - terser - vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): dependencies: debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.9.3) optionalDependencies: - vite: 6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color - typescript @@ -25042,7 +25322,7 @@ snapshots: lightningcss: 1.32.0 terser: 5.46.0 - vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) @@ -25053,7 +25333,7 @@ snapshots: optionalDependencies: '@types/node': 24.12.0 fsevents: 2.3.3 - jiti: 2.6.1 + jiti: 2.7.0 lightningcss: 1.32.0 terser: 5.46.0 tsx: 4.21.0 @@ -25148,10 +25428,10 @@ snapshots: - supports-color - terser - vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(@vitest/ui@4.0.18)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.32.0)(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): + vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(@vitest/ui@4.0.18)(jiti@2.7.0)(jsdom@26.1.0)(lightningcss@1.32.0)(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@vitest/expect': 4.0.18 - '@vitest/mocker': 4.0.18(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(vite@6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/mocker': 4.0.18(msw@2.12.8(@types/node@24.12.0)(typescript@5.9.3))(vite@6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@vitest/pretty-format': 4.0.18 '@vitest/runner': 4.0.18 '@vitest/snapshot': 4.0.18 @@ -25168,7 +25448,7 @@ snapshots: tinyexec: 1.0.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 6.4.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vite: 6.4.1(@types/node@24.12.0)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.0 @@ -25478,10 +25758,16 @@ snapshots: dependencies: zod: 4.3.6 + zod-to-json-schema@3.25.1(zod@4.4.3): + dependencies: + zod: 4.4.3 + zod@3.25.76: {} zod@4.3.6: {} + zod@4.4.3: {} + zustand@4.5.7(@types/react@19.2.11)(immer@11.1.3)(react@19.1.0): dependencies: use-sync-external-store: 1.6.0(react@19.1.0)