diff --git a/ui-v2/package-lock.json b/ui-v2/package-lock.json index 0dce47f4e3..fbde466228 100644 --- a/ui-v2/package-lock.json +++ b/ui-v2/package-lock.json @@ -8,6 +8,8 @@ "name": "goose-v2", "version": "1.0.0", "dependencies": { + "@tanstack/react-router": "^1.120.5", + "@tanstack/router": "^0.0.1-beta.53", "react": "^19.1.0", "react-dom": "^19.1.0" }, @@ -358,7 +360,6 @@ "version": "7.27.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz", "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", - "dev": true, "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -2965,6 +2966,124 @@ "tailwindcss": "4.1.7" } }, + "node_modules/@tanstack/history": { + "version": "1.115.0", + "resolved": "https://registry.npmjs.org/@tanstack/history/-/history-1.115.0.tgz", + "integrity": "sha512-K7JJNrRVvyjAVnbXOH2XLRhFXDkeP54Kt2P4FR1Kl2KDGlIbkua5VqZQD2rot3qaDrpufyUa63nuLai1kOLTsQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-router": { + "version": "1.120.5", + "resolved": "https://registry.npmjs.org/@tanstack/react-router/-/react-router-1.120.5.tgz", + "integrity": "sha512-A+YRftGwAeFBxa8DF5ujNYqkSEbjCa1KjxDNYr+jWj16jjTxrz/XqgOJCv5ZfbAqqqOa3yLYoQbWa7OGz5jHuA==", + "license": "MIT", + "dependencies": { + "@tanstack/history": "1.115.0", + "@tanstack/react-store": "^0.7.0", + "@tanstack/router-core": "1.120.5", + "jsesc": "^3.1.0", + "tiny-invariant": "^1.3.3", + "tiny-warning": "^1.0.3" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=18.0.0 || >=19.0.0", + "react-dom": ">=18.0.0 || >=19.0.0" + } + }, + "node_modules/@tanstack/react-store": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@tanstack/react-store/-/react-store-0.7.0.tgz", + "integrity": "sha512-S/Rq17HaGOk+tQHV/yrePMnG1xbsKZIl/VsNWnNXt4XW+tTY8dTlvpJH2ZQ3GRALsusG5K6Q3unAGJ2pd9W/Ng==", + "license": "MIT", + "dependencies": { + "@tanstack/store": "0.7.0", + "use-sync-external-store": "^1.4.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "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" + } + }, + "node_modules/@tanstack/router": { + "version": "0.0.1-beta.53", + "resolved": "https://registry.npmjs.org/@tanstack/router/-/router-0.0.1-beta.53.tgz", + "integrity": "sha512-nX1avh939ufOCoXhJ5wihX/ft6sn50ARrj4FAhRYn50KKzo9fXsYSmPyVgqVdW0hJ4n9XXKIMkwwpzEhLQmqrA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.16.7", + "@tanstack/store": "0.0.1-beta.52", + "tiny-invariant": "^1.3.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/router-core": { + "version": "1.120.5", + "resolved": "https://registry.npmjs.org/@tanstack/router-core/-/router-core-1.120.5.tgz", + "integrity": "sha512-IXLNv3j7rpTL/YNCWHijZgrnxFuvD4Nz/nUiGSak4x5BKzlnuZEso81xFcIuczVrEW72NxZv8IfzpR5M5Tuc0A==", + "license": "MIT", + "dependencies": { + "@tanstack/history": "1.115.0", + "@tanstack/store": "^0.7.0", + "tiny-invariant": "^1.3.3" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/router/node_modules/@tanstack/store": { + "version": "0.0.1-beta.52", + "resolved": "https://registry.npmjs.org/@tanstack/store/-/store-0.0.1-beta.52.tgz", + "integrity": "sha512-3/5XqeG09sCJnakHpq8qgXjdVpm97aITbi1wfbjLGXdVsss62zpJAvc4vL8ccHf+J/OmoS4dJTNuEZ0alywZtg==", + "license": "MIT", + "dependencies": { + "immer": "^9.0.15" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/store": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@tanstack/store/-/store-0.7.0.tgz", + "integrity": "sha512-CNIhdoUsmD2NolYuaIs8VfWM467RK6oIBAW4nPEKZhg1smZ+/CwtCdpURgp7nxSqOaV9oKkzdWD80+bC66F/Jg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@testing-library/dom": { "version": "10.4.0", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", @@ -8200,6 +8319,16 @@ "node": ">= 4" } }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", @@ -8995,7 +9124,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -11808,7 +11936,6 @@ "version": "0.14.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true, "license": "MIT" }, "node_modules/regexp.prototype.flags": { @@ -13581,6 +13708,18 @@ "license": "MIT", "optional": true }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", + "license": "MIT" + }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", @@ -14139,6 +14278,15 @@ "punycode": "^2.1.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz", + "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/username": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/username/-/username-5.1.0.tgz", diff --git a/ui-v2/package.json b/ui-v2/package.json index 7c82046e96..5e9eeda7ba 100644 --- a/ui-v2/package.json +++ b/ui-v2/package.json @@ -32,6 +32,8 @@ "prepare": "cd ../.. && husky install" }, "dependencies": { + "@tanstack/react-router": "^1.120.5", + "@tanstack/router": "^0.0.1-beta.53", "react": "^19.1.0", "react-dom": "^19.1.0" }, diff --git a/ui-v2/playwright.config.ts b/ui-v2/playwright.config.ts index 0c7e3a3148..ce73727bd9 100644 --- a/ui-v2/playwright.config.ts +++ b/ui-v2/playwright.config.ts @@ -25,4 +25,4 @@ export default defineConfig({ timeout: 15000, // Increase expect timeout }, reporter: [['html'], ['list']], -}); \ No newline at end of file +}); diff --git a/ui-v2/src/App.tsx b/ui-v2/src/App.tsx index 456645634e..fc11393ec7 100644 --- a/ui-v2/src/App.tsx +++ b/ui-v2/src/App.tsx @@ -1,5 +1,7 @@ import React, { Suspense } from 'react'; +import { Outlet } from '@tanstack/react-router'; + import GooseLogo from './components/GooseLogo'; import SuspenseLoader from './components/SuspenseLoader'; @@ -7,13 +9,14 @@ const App: React.FC = (): React.ReactElement => { return ( }>
-
+

Goose v2

+
); }; -export default App; \ No newline at end of file +export default App; diff --git a/ui-v2/src/components/Button.tsx b/ui-v2/src/components/Button.tsx index 764768f208..8a8bbf4ad3 100644 --- a/ui-v2/src/components/Button.tsx +++ b/ui-v2/src/components/Button.tsx @@ -65,4 +65,4 @@ export const Button: React.FC = ({ {children} ); -}; \ No newline at end of file +}; diff --git a/ui-v2/src/main.tsx b/ui-v2/src/main.tsx index 9b00bd858d..0baa8cf32c 100644 --- a/ui-v2/src/main.tsx +++ b/ui-v2/src/main.tsx @@ -1,11 +1,17 @@ import React from 'react'; +import { RouterProvider } from '@tanstack/react-router'; import ReactDOM from 'react-dom/client'; -import App from './App'; +import { router } from './routeTree'; + +import './index.css'; + +// Initialize the router +await router.load(); ReactDOM.createRoot(document.getElementById('root')!).render( - + ); diff --git a/ui-v2/src/routeTree.gen.ts b/ui-v2/src/routeTree.gen.ts new file mode 100644 index 0000000000..5e682936ba --- /dev/null +++ b/ui-v2/src/routeTree.gen.ts @@ -0,0 +1,88 @@ +/* eslint-disable */ + +// @ts-nocheck + +// noinspection JSUnusedGlobalSymbols + +// This file was automatically generated by TanStack Router. +// You should NOT make any changes in this file as it will be overwritten. +// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. + +// Import Routes + +import { Route as rootRoute } from './routes/__root' +import { Route as IndexImport } from './routes/index' + +// Create/Update Routes + +const IndexRoute = IndexImport.update({ + id: '/', + path: '/', + getParentRoute: () => rootRoute, +} as any) + +// Populate the FileRoutesByPath interface + +declare module '@tanstack/react-router' { + interface FileRoutesByPath { + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexImport + parentRoute: typeof rootRoute + } + } +} + +// Create and export the route tree + +export interface FileRoutesByFullPath { + '/': typeof IndexRoute +} + +export interface FileRoutesByTo { + '/': typeof IndexRoute +} + +export interface FileRoutesById { + __root__: typeof rootRoute + '/': typeof IndexRoute +} + +export interface FileRouteTypes { + fileRoutesByFullPath: FileRoutesByFullPath + fullPaths: '/' + fileRoutesByTo: FileRoutesByTo + to: '/' + id: '__root__' | '/' + fileRoutesById: FileRoutesById +} + +export interface RootRouteChildren { + IndexRoute: typeof IndexRoute +} + +const rootRouteChildren: RootRouteChildren = { + IndexRoute: IndexRoute, +} + +export const routeTree = rootRoute + ._addFileChildren(rootRouteChildren) + ._addFileTypes() + +/* ROUTE_MANIFEST_START +{ + "routes": { + "__root__": { + "filePath": "__root.tsx", + "children": [ + "/" + ] + }, + "/": { + "filePath": "index.tsx" + } + } +} +ROUTE_MANIFEST_END */ diff --git a/ui-v2/src/routeTree.ts b/ui-v2/src/routeTree.ts new file mode 100644 index 0000000000..dd3ba914ee --- /dev/null +++ b/ui-v2/src/routeTree.ts @@ -0,0 +1,14 @@ +import { createRouter } from '@tanstack/react-router'; + +import { rootRoute, indexRoute, aboutRoute } from './routes'; + +const routeTree = rootRoute.addChildren([indexRoute, aboutRoute]); + +export const router = createRouter({ routeTree }); + +// Register the router instance for type safety +declare module '@tanstack/react-router' { + interface Register { + router: typeof router; + } +} diff --git a/ui-v2/src/routes/__root.tsx b/ui-v2/src/routes/__root.tsx new file mode 100644 index 0000000000..9b5d54b86d --- /dev/null +++ b/ui-v2/src/routes/__root.tsx @@ -0,0 +1,20 @@ +import { createRootRoute, Link, Outlet } from '@tanstack/react-router'; +import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'; + +export const Route = createRootRoute({ + component: () => ( + <> +
+ + Home + {' '} + + About + +
+
+ + + + ), +}); diff --git a/ui-v2/src/routes/index.tsx b/ui-v2/src/routes/index.tsx new file mode 100644 index 0000000000..6308b9ab65 --- /dev/null +++ b/ui-v2/src/routes/index.tsx @@ -0,0 +1,28 @@ +import { createRootRoute, createRoute } from '@tanstack/react-router'; + +import App from '../App'; + +export const rootRoute = createRootRoute({ + component: App, +}); + +export const indexRoute = createRoute({ + getParentRoute: () => rootRoute, + path: '/', + component: () => ( +
+

Welcome to Goose v2

+
+ ), +}); + +export const aboutRoute = createRoute({ + getParentRoute: () => rootRoute, + path: '/about', + component: () => ( +
+

About Goose v2

+

An AI assistant for developers

+
+ ), +}); diff --git a/ui-v2/src/services/electron.ts b/ui-v2/src/services/electron.ts index 9a15d089a7..09a1b9e72d 100644 --- a/ui-v2/src/services/electron.ts +++ b/ui-v2/src/services/electron.ts @@ -12,4 +12,4 @@ export class ElectronService { } } -export const electronService = new ElectronService(); \ No newline at end of file +export const electronService = new ElectronService(); diff --git a/ui-v2/vite.config.ts b/ui-v2/vite.config.ts index 14362d00b2..57e7dc7ecd 100644 --- a/ui-v2/vite.config.ts +++ b/ui-v2/vite.config.ts @@ -20,4 +20,4 @@ export default defineConfig({ outDir: '.vite/build', emptyOutDir: true, }, -}); \ No newline at end of file +});