diff --git a/.env.local.sample b/.env.local.sample new file mode 100644 index 0000000..4ec2bbc --- /dev/null +++ b/.env.local.sample @@ -0,0 +1,2 @@ +DEV_FE_PORT=3400 +DEV_BE_PORT=3401 diff --git a/CLAUDE.md b/CLAUDE.md index e3c5b83..84d7675 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -21,11 +21,11 @@ ## Project Overview -Claude Code Viewer reads Claude Code session logs directly from JSONL files (`~/.claude/projects/`) with zero data loss. It's a web-based client built as a CLI tool serving a Next.js application. +Claude Code Viewer reads Claude Code session logs directly from JSONL files (`~/.claude/projects/`) with zero data loss. It's a web-based client built as a CLI tool serving a Vite application. **Core Architecture**: -- Frontend: Next.js 15 + React 19 + TanStack Query -- Backend: Hono + Effect-TS (all business logic) +- Frontend: Vite + TanStack Router + React 19 + TanStack Query +- Backend: Hono (standalone server) + Effect-TS (all business logic) - Data: Direct JSONL reads with strict Zod validation - Real-time: Server-Sent Events (SSE) for live updates @@ -54,10 +54,11 @@ pnpm test ## Key Directory Patterns -- `src/app/api/[[...route]]/` - Hono API entry point (all routes defined here) +- `src/server/hono/route.ts` - Hono API routes definition (all routes defined here) - `src/server/core/` - Effect-TS business logic (domain modules: session, project, git, etc.) - `src/lib/conversation-schema/` - Zod schemas for JSONL validation - `src/testing/layers/` - Reusable Effect test layers (`testPlatformLayer` is the foundation) +- `src/routes/` - TanStack Router routes ## Coding Standards diff --git a/biome.json b/biome.json index ea54ad9..1555cf0 100644 --- a/biome.json +++ b/biome.json @@ -15,7 +15,8 @@ "!**/*.css", "!dist", "!playwright.config.ts", - "!src/lib/i18n/locales/*/messages.ts" + "!src/lib/i18n/locales/*/messages.ts", + "!src/routeTree.gen.ts" ] }, "formatter": { @@ -51,6 +52,12 @@ "linter": { "enabled": false } + }, + { + "includes": ["**/*.config.ts"], + "linter": { + "enabled": false + } } ] } diff --git a/components.json b/components.json index 3289f23..1e6ea67 100644 --- a/components.json +++ b/components.json @@ -5,7 +5,7 @@ "tsx": true, "tailwind": { "config": "", - "css": "src/app/globals.css", + "css": "src/styles.css", "baseColor": "neutral", "cssVariables": true, "prefix": "" diff --git a/docs/dev.md b/docs/dev.md index 74bd67f..4cc99ed 100644 --- a/docs/dev.md +++ b/docs/dev.md @@ -6,13 +6,13 @@ This document provides technical details for developers contributing to Claude C ### Frontend -- **Framework**: Next.js 15 (App Router) +- **Framework**: Vite + TanStack Router - **UI Libraries**: React 19, Radix UI, Tailwind CSS - **State Management**: Jotai (global state), TanStack Query (server state) ### Backend -- **API Framework**: Hono integrated with Next.js API Routes +- **API Framework**: Hono (standalone server with @hono/node-server) - Type-safe communication via Hono RPC - Validation using `@hono/zod-validator` - **Effect-TS**: All backend business logic is implemented using Effect-TS @@ -61,27 +61,21 @@ pnpm install ## Starting the Development Server -### Development Mode (with limitations) +### Development Mode ```bash pnpm dev ``` -The development server will start, but **with the following limitations**: +This command starts: +- Frontend: Vite development server (port 3400 by default) +- Backend: Node server with tsx watch (port 3401 by default) -#### Next.js Development Server Constraints +Both servers run simultaneously using `npm-run-all2` for parallel execution. -The Next.js development server behaves like an Edge Runtime where API Routes don't share memory space. This causes: +### Production Mode -1. **Initialization runs on every request**: Initialization occurs for each API request, degrading performance -2. **Session process continuation unavailable**: Cannot resume Paused sessions across different requests -3. **SSE connection and process management inconsistencies**: Events that should be notified via SSE aren't shared between processes - -Therefore, **development mode is sufficient for UI verification and minor changes**, but **production build startup is essential for comprehensive testing of session process management and SSE integration**. - -### Production Mode (Recommended) - -For comprehensive functionality testing, build and run in production mode: +Build and run in production mode: ```bash # Build @@ -91,7 +85,12 @@ pnpm build pnpm start ``` -The built application is output to the `dist/` directory and started with `pnpm start`. +The built application is output to the `dist/` directory: +- `dist/static/` - Frontend static files (built by Vite) +- `dist/main.js` - Backend server (built by esbuild) +- `dist/index.js` - CLI entry point + +The production server serves static files and handles API requests on a single port (3000 by default). ## Quality Assurance @@ -164,25 +163,32 @@ When the `vrt` label is added to a PR, CI automatically captures and commits sna ``` src/ -├── app/ # Next.js App Router -│ ├── api/[[...route]]/ # Hono API Routes -│ ├── components/ # Page-specific components -│ ├── projects/ # Project-related pages -│ └── ... -├── components/ # Shared UI components -├── lib/ # Frontend common logic -│ ├── api/ # API client (Hono RPC) -│ ├── sse/ # SSE connection management +├── routes/ # TanStack Router routes +│ ├── __root.tsx # Root route with providers +│ ├── index.tsx # Home route +│ └── projects/ # Project-related routes +├── app/ # Shared components and hooks (legacy directory name) +│ ├── components/ # Shared components +│ ├── hooks/ # Custom hooks +│ └── projects/ # Project-related page components +├── components/ # UI components library +│ └── ui/ # shadcn/ui components +├── lib/ # Frontend common logic +│ ├── api/ # API client (Hono RPC) +│ ├── sse/ # SSE connection management │ └── conversation-schema/ # Zod schemas for conversation logs -├── server/ # Backend implementation -│ ├── core/ # Core domain logic (Effect-TS) -│ │ ├── claude-code/ # Claude Code integration -│ │ ├── events/ # SSE event management -│ │ ├── session/ # Session management +├── server/ # Backend implementation +│ ├── core/ # Core domain logic (Effect-TS) +│ │ ├── claude-code/ # Claude Code integration +│ │ ├── events/ # SSE event management +│ │ ├── session/ # Session management │ │ └── ... -│ ├── hono/ # Hono application -│ └── lib/ # Backend common utilities -└── testing/ # Test helpers and mocks +│ ├── hono/ # Hono application +│ │ ├── app.ts # Hono app instance +│ │ └── route.ts # API routes definition +│ ├── lib/ # Backend common utilities +│ └── main.ts # Server entry point +└── testing/ # Test helpers and mocks ``` ## Development Tips diff --git a/index.html b/index.html new file mode 100644 index 0000000..b1adfdf --- /dev/null +++ b/index.html @@ -0,0 +1,16 @@ + + + + + + + Claude Code Viewer + + +
+ + + \ No newline at end of file diff --git a/next.config.ts b/next.config.ts deleted file mode 100644 index e90a0cc..0000000 --- a/next.config.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { NextConfig } from "next"; - -const nextConfig: NextConfig = { - output: "standalone", - typescript: { - ignoreBuildErrors: true, // typechecking should be separeted by build - }, -}; - -export default nextConfig; diff --git a/package.json b/package.json index 6c7d031..f2763d1 100644 --- a/package.json +++ b/package.json @@ -23,9 +23,12 @@ }, "scripts": { "dev": "run-p 'dev:*'", - "dev:next": "next dev --turbopack", + "dev:frontend": "vite", + "dev:backend": "NODE_ENV=development tsx watch src/server/main.ts --env-file-if-exists=.env.local", "start": "node dist/index.js", "build": "./scripts/build.sh", + "build:frontend": "vite build", + "build:backend": "esbuild src/server/main.ts --format=esm --bundle --packages=external --sourcemap --platform=node --outfile=dist/main.js", "lint": "run-s 'lint:*'", "lint:biome-format": "biome format .", "lint:biome-lint": "biome check .", @@ -46,6 +49,7 @@ "@anthropic-ai/claude-code": "^2.0.24", "@effect/platform": "^0.92.1", "@effect/platform-node": "^0.98.4", + "@hono/node-server": "^1.19.5", "@hono/zod-validator": "^0.7.4", "@lingui/core": "^5.5.1", "@lingui/react": "^5.5.1", @@ -58,7 +62,11 @@ "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-tabs": "^1.1.13", "@radix-ui/react-tooltip": "^1.2.8", + "@tailwindcss/vite": "^4.1.16", + "@tanstack/react-devtools": "^0.7.8", "@tanstack/react-query": "^5.90.5", + "@tanstack/react-router": "^1.133.27", + "@tanstack/react-router-devtools": "^1.133.27", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "date-fns": "^4.1.0", @@ -67,8 +75,6 @@ "hono": "^4.10.1", "jotai": "^2.15.0", "lucide-react": "^0.546.0", - "next": "15.5.6", - "next-themes": "^0.4.6", "parse-git-diff": "^0.0.19", "prexit": "^2.3.0", "react": "^19.2.0", @@ -88,19 +94,26 @@ "@lingui/conf": "^5.5.1", "@lingui/format-json": "^5.5.1", "@lingui/loader": "^5.5.1", + "@lingui/vite-plugin": "^5.5.1", "@tailwindcss/postcss": "^4.1.15", + "@tanstack/router-plugin": "^1.133.27", "@tsconfig/strictest": "^2.0.6", "@types/node": "^24.9.1", "@types/react": "^19.2.2", "@types/react-dom": "^19.2.2", "@types/react-syntax-highlighter": "^15.5.13", + "@vitejs/plugin-react-swc": "^4.2.0", + "dotenv": "^17.2.3", + "esbuild": "^0.25.11", "npm-run-all2": "^8.0.4", "playwright": "^1.56.1", "release-it": "^19.0.5", "release-it-pnpm": "^4.6.6", "tailwindcss": "^4.1.15", + "tsx": "^4.20.6", "tw-animate-css": "^1.4.0", "typescript": "^5.9.3", + "vite": "^7.1.12", "vitest": "^3.2.4" }, "packageManager": "pnpm@10.18.3+sha512.bbd16e6d7286fd7e01f6b3c0b3c932cda2965c06a908328f74663f10a9aea51f1129eea615134bf992831b009eabe167ecb7008b597f40ff9bc75946aadfb08d" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c4d7a09..08b441a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,9 @@ importers: '@effect/platform-node': specifier: ^0.98.4 version: 0.98.4(@effect/cluster@0.50.4(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/sql@0.46.0(@effect/experimental@0.56.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/workflow@0.11.3(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(@effect/rpc@0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/sql@0.46.0(@effect/experimental@0.56.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4))(effect@3.18.4) + '@hono/node-server': + specifier: ^1.19.5 + version: 1.19.5(hono@4.10.1) '@hono/zod-validator': specifier: ^0.7.4 version: 0.7.4(hono@4.10.1)(zod@4.1.12) @@ -56,9 +59,21 @@ importers: '@radix-ui/react-tooltip': specifier: ^1.2.8 version: 1.2.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@tailwindcss/vite': + specifier: ^4.1.16 + version: 4.1.16(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + '@tanstack/react-devtools': + specifier: ^0.7.8 + version: 0.7.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(csstype@3.1.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(solid-js@1.9.9) '@tanstack/react-query': specifier: ^5.90.5 version: 5.90.5(react@19.2.0) + '@tanstack/react-router': + specifier: ^1.133.27 + version: 1.133.27(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@tanstack/react-router-devtools': + specifier: ^1.133.27 + version: 1.133.27(@tanstack/react-router@1.133.27(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@tanstack/router-core@1.133.27)(@types/node@24.9.1)(csstype@3.1.3)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(solid-js@1.9.9)(terser@5.44.0)(tiny-invariant@1.3.3)(tsx@4.20.6)(yaml@2.8.1) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -83,12 +98,6 @@ importers: lucide-react: specifier: ^0.546.0 version: 0.546.0(react@19.2.0) - next: - specifier: 15.5.6 - version: 15.5.6(@babel/core@7.28.4)(@playwright/test@1.55.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - next-themes: - specifier: ^0.4.6 - version: 0.4.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) parse-git-diff: specifier: ^0.0.19 version: 0.0.19 @@ -140,10 +149,16 @@ importers: version: 5.5.1(typescript@5.9.3) '@lingui/loader': specifier: ^5.5.1 - version: 5.5.1(typescript@5.9.3)(webpack@5.102.1) + version: 5.5.1(typescript@5.9.3)(webpack@5.102.1(esbuild@0.25.11)) + '@lingui/vite-plugin': + specifier: ^5.5.1 + version: 5.5.1(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) '@tailwindcss/postcss': specifier: ^4.1.15 version: 4.1.15 + '@tanstack/router-plugin': + specifier: ^1.133.27 + version: 1.133.27(@tanstack/react-router@1.133.27(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(webpack@5.102.1(esbuild@0.25.11)) '@tsconfig/strictest': specifier: ^2.0.6 version: 2.0.6 @@ -159,6 +174,15 @@ importers: '@types/react-syntax-highlighter': specifier: ^15.5.13 version: 15.5.13 + '@vitejs/plugin-react-swc': + specifier: ^4.2.0 + version: 4.2.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + dotenv: + specifier: ^17.2.3 + version: 17.2.3 + esbuild: + specifier: ^0.25.11 + version: 0.25.11 npm-run-all2: specifier: ^8.0.4 version: 8.0.4 @@ -174,15 +198,21 @@ importers: tailwindcss: specifier: ^4.1.15 version: 4.1.15 + tsx: + specifier: ^4.20.6 + version: 4.20.6 tw-animate-css: specifier: ^1.4.0 version: 1.4.0 typescript: specifier: ^5.9.3 version: 5.9.3 + vite: + specifier: ^7.1.12 + version: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) vitest: specifier: ^3.2.4 - version: 3.2.4(@types/debug@4.1.12)(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) packages: @@ -217,14 +247,32 @@ packages: resolution: {integrity: sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==} engines: {node: '>=6.9.0'} + '@babel/generator@7.28.5': + resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.27.2': resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} engines: {node: '>=6.9.0'} + '@babel/helper-create-class-features-plugin@7.28.5': + resolution: {integrity: sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/helper-globals@7.28.0': resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} engines: {node: '>=6.9.0'} + '@babel/helper-member-expression-to-functions@7.28.5': + resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.27.1': resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} @@ -235,6 +283,24 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-replace-supers@7.27.1': + resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -243,6 +309,10 @@ packages: resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.27.1': resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} @@ -256,6 +326,41 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.28.5': + resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-jsx@7.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.27.1': + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.27.1': + resolution: {integrity: sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.28.5': + resolution: {integrity: sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-typescript@7.28.5': + resolution: {integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/runtime@7.28.4': resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} engines: {node: '>=6.9.0'} @@ -268,10 +373,18 @@ packages: resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==} engines: {node: '>=6.9.0'} + '@babel/traverse@7.28.5': + resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} + engines: {node: '>=6.9.0'} + '@babel/types@7.28.4': resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} engines: {node: '>=6.9.0'} + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + engines: {node: '>=6.9.0'} + '@biomejs/biome@2.2.6': resolution: {integrity: sha512-yKTCNGhek0rL5OEW1jbLeZX8LHaM8yk7+3JRGv08my+gkpmtb5dDE+54r2ZjZx0ediFEn1pYBOJSmOdDP9xtFw==} engines: {node: '>=14.21.3'} @@ -402,9 +515,6 @@ packages: '@effect/rpc': ^0.71.0 effect: ^3.18.1 - '@emnapi/runtime@1.6.0': - resolution: {integrity: sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA==} - '@esbuild/aix-ppc64@0.25.11': resolution: {integrity: sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==} engines: {node: '>=18'} @@ -576,199 +686,79 @@ packages: '@floating-ui/utils@0.2.10': resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + '@hono/node-server@1.19.5': + resolution: {integrity: sha512-iBuhh+uaaggeAuf+TftcjZyWh2GEgZcVGXkNtskLVoWaXhnJtC5HLHrU8W1KHDoucqO1MswwglmkWLFyiDn4WQ==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 + '@hono/zod-validator@0.7.4': resolution: {integrity: sha512-biKGn3BRJVaftZlIPMyK+HCe/UHAjJ6sH0UyXe3+v0OcgVr9xfImDROTJFLtn9e3XEEAHGZIM9U6evu85abm8Q==} peerDependencies: hono: '>=3.9.0' zod: ^3.25.0 || ^4.0.0 - '@img/colour@1.0.0': - resolution: {integrity: sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==} - engines: {node: '>=18'} - '@img/sharp-darwin-arm64@0.33.5': resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [darwin] - '@img/sharp-darwin-arm64@0.34.4': - resolution: {integrity: sha512-sitdlPzDVyvmINUdJle3TNHl+AG9QcwiAMsXmccqsCOMZNIdW2/7S26w0LyU8euiLVzFBL3dXPwVCq/ODnf2vA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [darwin] - '@img/sharp-darwin-x64@0.33.5': resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [darwin] - '@img/sharp-darwin-x64@0.34.4': - resolution: {integrity: sha512-rZheupWIoa3+SOdF/IcUe1ah4ZDpKBGWcsPX6MT0lYniH9micvIU7HQkYTfrx5Xi8u+YqwLtxC/3vl8TQN6rMg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.0.4': resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.2.3': - resolution: {integrity: sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw==} - cpu: [arm64] - os: [darwin] - '@img/sharp-libvips-darwin-x64@1.0.4': resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} cpu: [x64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.2.3': - resolution: {integrity: sha512-Ju+g2xn1E2AKO6YBhxjj+ACcsPQRHT0bhpglxcEf+3uyPY+/gL8veniKoo96335ZaPo03bdDXMv0t+BBFAbmRA==} - cpu: [x64] - os: [darwin] - '@img/sharp-libvips-linux-arm64@1.0.4': resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linux-arm64@1.2.3': - resolution: {integrity: sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ==} - cpu: [arm64] - os: [linux] - '@img/sharp-libvips-linux-arm@1.0.5': resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} cpu: [arm] os: [linux] - '@img/sharp-libvips-linux-arm@1.2.3': - resolution: {integrity: sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA==} - cpu: [arm] - os: [linux] - - '@img/sharp-libvips-linux-ppc64@1.2.3': - resolution: {integrity: sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg==} - cpu: [ppc64] - os: [linux] - - '@img/sharp-libvips-linux-s390x@1.2.3': - resolution: {integrity: sha512-RgWrs/gVU7f+K7P+KeHFaBAJlNkD1nIZuVXdQv6S+fNA6syCcoboNjsV2Pou7zNlVdNQoQUpQTk8SWDHUA3y/w==} - cpu: [s390x] - os: [linux] - '@img/sharp-libvips-linux-x64@1.0.4': resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} cpu: [x64] os: [linux] - '@img/sharp-libvips-linux-x64@1.2.3': - resolution: {integrity: sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg==} - cpu: [x64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-arm64@1.2.3': - resolution: {integrity: sha512-F9q83RZ8yaCwENw1GieztSfj5msz7GGykG/BA+MOUefvER69K/ubgFHNeSyUu64amHIYKGDs4sRCMzXVj8sEyw==} - cpu: [arm64] - os: [linux] - - '@img/sharp-libvips-linuxmusl-x64@1.2.3': - resolution: {integrity: sha512-U5PUY5jbc45ANM6tSJpsgqmBF/VsL6LnxJmIf11kB7J5DctHgqm0SkuXzVWtIY90GnJxKnC/JT251TDnk1fu/g==} - cpu: [x64] - os: [linux] - '@img/sharp-linux-arm64@0.33.5': resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - '@img/sharp-linux-arm64@0.34.4': - resolution: {integrity: sha512-YXU1F/mN/Wu786tl72CyJjP/Ngl8mGHN1hST4BGl+hiW5jhCnV2uRVTNOcaYPs73NeT/H8Upm3y9582JVuZHrQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - '@img/sharp-linux-arm@0.33.5': resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] - '@img/sharp-linux-arm@0.34.4': - resolution: {integrity: sha512-Xyam4mlqM0KkTHYVSuc6wXRmM7LGN0P12li03jAnZ3EJWZqj83+hi8Y9UxZUbxsgsK1qOEwg7O0Bc0LjqQVtxA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm] - os: [linux] - - '@img/sharp-linux-ppc64@0.34.4': - resolution: {integrity: sha512-F4PDtF4Cy8L8hXA2p3TO6s4aDt93v+LKmpcYFLAVdkkD3hSxZzee0rh6/+94FpAynsuMpLX5h+LRsSG3rIciUQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ppc64] - os: [linux] - - '@img/sharp-linux-s390x@0.34.4': - resolution: {integrity: sha512-qVrZKE9Bsnzy+myf7lFKvng6bQzhNUAYcVORq2P7bDlvmF6u2sCmK2KyEQEBdYk+u3T01pVsPrkj943T1aJAsw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [s390x] - os: [linux] - '@img/sharp-linux-x64@0.33.5': resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - '@img/sharp-linux-x64@0.34.4': - resolution: {integrity: sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-linuxmusl-arm64@0.34.4': - resolution: {integrity: sha512-8hDVvW9eu4yHWnjaOOR8kHVrew1iIX+MUgwxSuH2XyYeNRtLUe4VNioSqbNkB7ZYQJj9rUTT4PyRscyk2PXFKA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - - '@img/sharp-linuxmusl-x64@0.34.4': - resolution: {integrity: sha512-lU0aA5L8QTlfKjpDCEFOZsTYGn3AEiO6db8W5aQDxj0nQkVrZWmN3ZP9sYKWJdtq3PWPhUNlqehWyXpYDcI9Sg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - - '@img/sharp-wasm32@0.34.4': - resolution: {integrity: sha512-33QL6ZO/qpRyG7woB/HUALz28WnTMI2W1jgX3Nu2bypqLIKx/QKMILLJzJjI+SIbvXdG9fUnmrxR7vbi1sTBeA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [wasm32] - - '@img/sharp-win32-arm64@0.34.4': - resolution: {integrity: sha512-2Q250do/5WXTwxW3zjsEuMSv5sUU4Tq9VThWKlU2EYLm4MB7ZeMwF+SFJutldYODXF6jzc6YEOC+VfX0SZQPqA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [win32] - - '@img/sharp-win32-ia32@0.34.4': - resolution: {integrity: sha512-3ZeLue5V82dT92CNL6rsal6I2weKw1cYu+rGKm8fOCCtJTR2gYeUfY3FqUnIJsMUPIH68oS5jmZ0NiJ508YpEw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ia32] - os: [win32] - '@img/sharp-win32-x64@0.33.5': resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [win32] - '@img/sharp-win32-x64@0.34.4': - resolution: {integrity: sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [win32] - '@inquirer/ansi@1.0.1': resolution: {integrity: sha512-yqq0aJW/5XPhi5xOAL1xRCpe1eh8UFVgYFpFsjEqmIR8rKLyP+HINvFXwUaxYICflJrVlxnp7lLN6As735kVpw==} engines: {node: '>=18'} @@ -1007,6 +997,12 @@ packages: babel-plugin-macros: optional: true + '@lingui/vite-plugin@5.5.1': + resolution: {integrity: sha512-Kb+5OtBiDqmiV+FS4YM4h+uGXSt0RzCjKCPJEoZgtLodblRwfZkxTqPON2B08B1ghq75VnFk5nOL44WW0dl7AQ==} + engines: {node: '>=20.0.0'} + peerDependencies: + vite: ^3 || ^4 || ^5.0.9 || ^6 || ^7 + '@messageformat/parser@5.1.1': resolution: {integrity: sha512-3p0YRGCcTUCYvBKLIxtDDyrJ0YijGIwrTRu1DT8gIviIDZru8H23+FkY6MJBzM1n9n20CiM4VeDYuBsrrwnLjg==} @@ -1040,57 +1036,6 @@ packages: cpu: [x64] os: [win32] - '@next/env@15.5.6': - resolution: {integrity: sha512-3qBGRW+sCGzgbpc5TS1a0p7eNxnOarGVQhZxfvTdnV0gFI61lX7QNtQ4V1TSREctXzYn5NetbUsLvyqwLFJM6Q==} - - '@next/swc-darwin-arm64@15.5.6': - resolution: {integrity: sha512-ES3nRz7N+L5Umz4KoGfZ4XX6gwHplwPhioVRc25+QNsDa7RtUF/z8wJcbuQ2Tffm5RZwuN2A063eapoJ1u4nPg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - - '@next/swc-darwin-x64@15.5.6': - resolution: {integrity: sha512-JIGcytAyk9LQp2/nuVZPAtj8uaJ/zZhsKOASTjxDug0SPU9LAM3wy6nPU735M1OqacR4U20LHVF5v5Wnl9ptTA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - - '@next/swc-linux-arm64-gnu@15.5.6': - resolution: {integrity: sha512-qvz4SVKQ0P3/Im9zcS2RmfFL/UCQnsJKJwQSkissbngnB/12c6bZTCB0gHTexz1s6d/mD0+egPKXAIRFVS7hQg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-arm64-musl@15.5.6': - resolution: {integrity: sha512-FsbGVw3SJz1hZlvnWD+T6GFgV9/NYDeLTNQB2MXoPN5u9VA9OEDy6fJEfePfsUKAhJufFbZLgp0cPxMuV6SV0w==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - - '@next/swc-linux-x64-gnu@15.5.6': - resolution: {integrity: sha512-3QnHGFWlnvAgyxFxt2Ny8PTpXtQD7kVEeaFat5oPAHHI192WKYB+VIKZijtHLGdBBvc16tiAkPTDmQNOQ0dyrA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-linux-x64-musl@15.5.6': - resolution: {integrity: sha512-OsGX148sL+TqMK9YFaPFPoIaJKbFJJxFzkXZljIgA9hjMjdruKht6xDCEv1HLtlLNfkx3c5w2GLKhj7veBQizQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - - '@next/swc-win32-arm64-msvc@15.5.6': - resolution: {integrity: sha512-ONOMrqWxdzXDJNh2n60H6gGyKed42Ieu6UTVPZteXpuKbLZTH4G4eBMsr5qWgOBA+s7F+uB4OJbZnrkEDnZ5Fg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@next/swc-win32-x64-msvc@15.5.6': - resolution: {integrity: sha512-pxK4VIjFRx1MY92UycLOOw7dTdvccWsNETQ0kDHkBlcFH1GrTLUjSiHU1ohrznnux6TqRHgv5oflhfIWZwVROQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - '@nodeutils/defaults-deep@1.1.0': resolution: {integrity: sha512-gG44cwQovaOFdSR02jR9IhVRpnDP64VN6JdjYJTfNz4J4fWn7TQnmrf22nSjRqlwlxPcW8PL/L3KbJg3tdwvpg==} @@ -1232,11 +1177,6 @@ packages: resolution: {integrity: sha512-oeQJs1aa8Ghke8JIK9yuq/+KjMiaYeDZ38jx7MhkXncXlUKjqQ3wEm2X3qCKyjo+ZZofZj+WsEEiqkTtRuE2xQ==} engines: {node: ^20.9.0 || >=22.0.0, npm: '>=10.8.2'} - '@playwright/test@1.55.0': - resolution: {integrity: sha512-04IXzPwHrW69XusN/SIdDdKZBzMfOT9UNT/YiJit/xpy2VuAoB8NHc8Aplb96zsWDddLnbkPL3TsmrS04ZU2xQ==} - engines: {node: '>=18'} - hasBin: true - '@radix-ui/number@1.1.1': resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} @@ -1615,6 +1555,9 @@ packages: '@radix-ui/rect@1.1.1': resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + '@rolldown/pluginutils@1.0.0-beta.43': + resolution: {integrity: sha512-5Uxg7fQUCmfhax7FJke2+8B6cqgeUJUD9o2uXIKXhD+mG0mL6NObmVoi9wXEU1tY89mZKgAYA6fTbftx3q2ZPQ==} + '@rollup/rollup-android-arm-eabi@4.52.5': resolution: {integrity: sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==} cpu: [arm] @@ -1743,69 +1686,228 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} + '@solid-primitives/event-listener@2.4.3': + resolution: {integrity: sha512-h4VqkYFv6Gf+L7SQj+Y6puigL/5DIi7x5q07VZET7AWcS+9/G3WfIE9WheniHWJs51OEkRB43w6lDys5YeFceg==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/keyboard@1.3.3': + resolution: {integrity: sha512-9dQHTTgLBqyAI7aavtO+HnpTVJgWQA1ghBSrmLtMu1SMxLPDuLfuNr+Tk5udb4AL4Ojg7h9JrKOGEEDqsJXWJA==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/resize-observer@2.1.3': + resolution: {integrity: sha512-zBLje5E06TgOg93S7rGPldmhDnouNGhvfZVKOp+oG2XU8snA+GoCSSCz1M+jpNAg5Ek2EakU5UVQqL152WmdXQ==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/rootless@1.5.2': + resolution: {integrity: sha512-9HULb0QAzL2r47CCad0M+NKFtQ+LrGGNHZfteX/ThdGvKIg2o2GYhBooZubTCd/RTu2l2+Nw4s+dEfiDGvdrrQ==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/static-store@0.1.2': + resolution: {integrity: sha512-ReK+5O38lJ7fT+L6mUFvUr6igFwHBESZF+2Ug842s7fvlVeBdIVEdTCErygff6w7uR6+jrr7J8jQo+cYrEq4Iw==} + peerDependencies: + solid-js: ^1.6.12 + + '@solid-primitives/utils@6.3.2': + resolution: {integrity: sha512-hZ/M/qr25QOCcwDPOHtGjxTD8w2mNyVAYvcfgwzBHq2RwNqHNdDNsMZYap20+ruRwW4A3Cdkczyoz0TSxLCAPQ==} + peerDependencies: + solid-js: ^1.6.12 + '@standard-schema/spec@1.0.0': resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} - '@swc/helpers@0.5.15': - resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + '@swc/core-darwin-arm64@1.13.5': + resolution: {integrity: sha512-lKNv7SujeXvKn16gvQqUQI5DdyY8v7xcoO3k06/FJbHJS90zEwZdQiMNRiqpYw/orU543tPaWgz7cIYWhbopiQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.13.5': + resolution: {integrity: sha512-ILd38Fg/w23vHb0yVjlWvQBoE37ZJTdlLHa8LRCFDdX4WKfnVBiblsCU9ar4QTMNdeTBEX9iUF4IrbNWhaF1Ng==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.13.5': + resolution: {integrity: sha512-Q6eS3Pt8GLkXxqz9TAw+AUk9HpVJt8Uzm54MvPsqp2yuGmY0/sNaPPNVqctCX9fu/Nu8eaWUen0si6iEiCsazQ==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.13.5': + resolution: {integrity: sha512-aNDfeN+9af+y+M2MYfxCzCy/VDq7Z5YIbMqRI739o8Ganz6ST+27kjQFd8Y/57JN/hcnUEa9xqdS3XY7WaVtSw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-arm64-musl@1.13.5': + resolution: {integrity: sha512-9+ZxFN5GJag4CnYnq6apKTnnezpfJhCumyz0504/JbHLo+Ue+ZtJnf3RhyA9W9TINtLE0bC4hKpWi8ZKoETyOQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + + '@swc/core-linux-x64-gnu@1.13.5': + resolution: {integrity: sha512-WD530qvHrki8Ywt/PloKUjaRKgstQqNGvmZl54g06kA+hqtSE2FTG9gngXr3UJxYu/cNAjJYiBifm7+w4nbHbA==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-linux-x64-musl@1.13.5': + resolution: {integrity: sha512-Luj8y4OFYx4DHNQTWjdIuKTq2f5k6uSXICqx+FSabnXptaOBAbJHNbHT/06JZh6NRUouaf0mYXN0mcsqvkhd7Q==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + + '@swc/core-win32-arm64-msvc@1.13.5': + resolution: {integrity: sha512-cZ6UpumhF9SDJvv4DA2fo9WIzlNFuKSkZpZmPG1c+4PFSEMy5DFOjBSllCvnqihCabzXzpn6ykCwBmHpy31vQw==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.13.5': + resolution: {integrity: sha512-C5Yi/xIikrFUzZcyGj9L3RpKljFvKiDMtyDzPKzlsDrKIw2EYY+bF88gB6oGY5RGmv4DAX8dbnpRAqgFD0FMEw==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.13.5': + resolution: {integrity: sha512-YrKdMVxbYmlfybCSbRtrilc6UA8GF5aPmGKBdPvjrarvsmf4i7ZHGCEnLtfOMd3Lwbs2WUZq3WdMbozYeLU93Q==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.13.5': + resolution: {integrity: sha512-WezcBo8a0Dg2rnR82zhwoR6aRNxeTGfK5QCD6TQ+kg3xx/zNT02s/0o+81h/3zhvFSB24NtqEr8FTw88O5W/JQ==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': '>=0.5.17' + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/types@0.1.25': + resolution: {integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==} '@tailwindcss/node@4.1.15': resolution: {integrity: sha512-HF4+7QxATZWY3Jr8OlZrBSXmwT3Watj0OogeDvdUY/ByXJHQ+LBtqA2brDb3sBxYslIFx6UP94BJ4X6a4L9Bmw==} + '@tailwindcss/node@4.1.16': + resolution: {integrity: sha512-BX5iaSsloNuvKNHRN3k2RcCuTEgASTo77mofW0vmeHkfrDWaoFAFvNHpEgtu0eqyypcyiBkDWzSMxJhp3AUVcw==} + '@tailwindcss/oxide-android-arm64@4.1.15': resolution: {integrity: sha512-TkUkUgAw8At4cBjCeVCRMc/guVLKOU1D+sBPrHt5uVcGhlbVKxrCaCW9OKUIBv1oWkjh4GbunD/u/Mf0ql6kEA==} engines: {node: '>= 10'} cpu: [arm64] os: [android] + '@tailwindcss/oxide-android-arm64@4.1.16': + resolution: {integrity: sha512-8+ctzkjHgwDJ5caq9IqRSgsP70xhdhJvm+oueS/yhD5ixLhqTw9fSL1OurzMUhBwE5zK26FXLCz2f/RtkISqHA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + '@tailwindcss/oxide-darwin-arm64@4.1.15': resolution: {integrity: sha512-xt5XEJpn2piMSfvd1UFN6jrWXyaKCwikP4Pidcf+yfHTSzSpYhG3dcMktjNkQO3JiLCp+0bG0HoWGvz97K162w==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] + '@tailwindcss/oxide-darwin-arm64@4.1.16': + resolution: {integrity: sha512-C3oZy5042v2FOALBZtY0JTDnGNdS6w7DxL/odvSny17ORUnaRKhyTse8xYi3yKGyfnTUOdavRCdmc8QqJYwFKA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + '@tailwindcss/oxide-darwin-x64@4.1.15': resolution: {integrity: sha512-TnWaxP6Bx2CojZEXAV2M01Yl13nYPpp0EtGpUrY+LMciKfIXiLL2r/SiSRpagE5Fp2gX+rflp/Os1VJDAyqymg==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] + '@tailwindcss/oxide-darwin-x64@4.1.16': + resolution: {integrity: sha512-vjrl/1Ub9+JwU6BP0emgipGjowzYZMjbWCDqwA2Z4vCa+HBSpP4v6U2ddejcHsolsYxwL5r4bPNoamlV0xDdLg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + '@tailwindcss/oxide-freebsd-x64@4.1.15': resolution: {integrity: sha512-quISQDWqiB6Cqhjc3iWptXVZHNVENsWoI77L1qgGEHNIdLDLFnw3/AfY7DidAiiCIkGX/MjIdB3bbBZR/G2aJg==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] + '@tailwindcss/oxide-freebsd-x64@4.1.16': + resolution: {integrity: sha512-TSMpPYpQLm+aR1wW5rKuUuEruc/oOX3C7H0BTnPDn7W/eMw8W+MRMpiypKMkXZfwH8wqPIRKppuZoedTtNj2tg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.15': resolution: {integrity: sha512-ObG76+vPlab65xzVUQbExmDU9FIeYLQ5k2LrQdR2Ud6hboR+ZobXpDoKEYXf/uOezOfIYmy2Ta3w0ejkTg9yxg==} engines: {node: '>= 10'} cpu: [arm] os: [linux] + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.16': + resolution: {integrity: sha512-p0GGfRg/w0sdsFKBjMYvvKIiKy/LNWLWgV/plR4lUgrsxFAoQBFrXkZ4C0w8IOXfslB9vHK/JGASWD2IefIpvw==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + '@tailwindcss/oxide-linux-arm64-gnu@4.1.15': resolution: {integrity: sha512-4WbBacRmk43pkb8/xts3wnOZMDKsPFyEH/oisCm2q3aLZND25ufvJKcDUpAu0cS+CBOL05dYa8D4U5OWECuH/Q==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + '@tailwindcss/oxide-linux-arm64-gnu@4.1.16': + resolution: {integrity: sha512-DoixyMmTNO19rwRPdqviTrG1rYzpxgyYJl8RgQvdAQUzxC1ToLRqtNJpU/ATURSKgIg6uerPw2feW0aS8SNr/w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + '@tailwindcss/oxide-linux-arm64-musl@4.1.15': resolution: {integrity: sha512-AbvmEiteEj1nf42nE8skdHv73NoR+EwXVSgPY6l39X12Ex8pzOwwfi3Kc8GAmjsnsaDEbk+aj9NyL3UeyHcTLg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] + '@tailwindcss/oxide-linux-arm64-musl@4.1.16': + resolution: {integrity: sha512-H81UXMa9hJhWhaAUca6bU2wm5RRFpuHImrwXBUvPbYb+3jo32I9VIwpOX6hms0fPmA6f2pGVlybO6qU8pF4fzQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + '@tailwindcss/oxide-linux-x64-gnu@4.1.15': resolution: {integrity: sha512-+rzMVlvVgrXtFiS+ES78yWgKqpThgV19ISKD58Ck+YO5pO5KjyxLt7AWKsWMbY0R9yBDC82w6QVGz837AKQcHg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + '@tailwindcss/oxide-linux-x64-gnu@4.1.16': + resolution: {integrity: sha512-ZGHQxDtFC2/ruo7t99Qo2TTIvOERULPl5l0K1g0oK6b5PGqjYMga+FcY1wIUnrUxY56h28FxybtDEla+ICOyew==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + '@tailwindcss/oxide-linux-x64-musl@4.1.15': resolution: {integrity: sha512-fPdEy7a8eQN9qOIK3Em9D3TO1z41JScJn8yxl/76mp4sAXFDfV4YXxsiptJcOwy6bGR+70ZSwFIZhTXzQeqwQg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] + '@tailwindcss/oxide-linux-x64-musl@4.1.16': + resolution: {integrity: sha512-Oi1tAaa0rcKf1Og9MzKeINZzMLPbhxvm7rno5/zuP1WYmpiG0bEHq4AcRUiG2165/WUzvxkW4XDYCscZWbTLZw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + '@tailwindcss/oxide-wasm32-wasi@4.1.15': resolution: {integrity: sha512-sJ4yd6iXXdlgIMfIBXuVGp/NvmviEoMVWMOAGxtxhzLPp9LOj5k0pMEMZdjeMCl4C6Up+RM8T3Zgk+BMQ0bGcQ==} engines: {node: '>=14.0.0'} @@ -1818,33 +1920,176 @@ packages: - '@emnapi/wasi-threads' - tslib + '@tailwindcss/oxide-wasm32-wasi@4.1.16': + resolution: {integrity: sha512-B01u/b8LteGRwucIBmCQ07FVXLzImWESAIMcUU6nvFt/tYsQ6IHz8DmZ5KtvmwxD+iTYBtM1xwoGXswnlu9v0Q==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + '@tailwindcss/oxide-win32-arm64-msvc@4.1.15': resolution: {integrity: sha512-sJGE5faXnNQ1iXeqmRin7Ds/ru2fgCiaQZQQz3ZGIDtvbkeV85rAZ0QJFMDg0FrqsffZG96H1U9AQlNBRLsHVg==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] + '@tailwindcss/oxide-win32-arm64-msvc@4.1.16': + resolution: {integrity: sha512-zX+Q8sSkGj6HKRTMJXuPvOcP8XfYON24zJBRPlszcH1Np7xuHXhWn8qfFjIujVzvH3BHU+16jBXwgpl20i+v9A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + '@tailwindcss/oxide-win32-x64-msvc@4.1.15': resolution: {integrity: sha512-NLeHE7jUV6HcFKS504bpOohyi01zPXi2PXmjFfkzTph8xRxDdxkRsXm/xDO5uV5K3brrE1cCwbUYmFUSHR3u1w==} engines: {node: '>= 10'} cpu: [x64] os: [win32] + '@tailwindcss/oxide-win32-x64-msvc@4.1.16': + resolution: {integrity: sha512-m5dDFJUEejbFqP+UXVstd4W/wnxA4F61q8SoL+mqTypId2T2ZpuxosNSgowiCnLp2+Z+rivdU0AqpfgiD7yCBg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + '@tailwindcss/oxide@4.1.15': resolution: {integrity: sha512-krhX+UOOgnsUuks2SR7hFafXmLQrKxB4YyRTERuCE59JlYL+FawgaAlSkOYmDRJdf1Q+IFNDMl9iRnBW7QBDfQ==} engines: {node: '>= 10'} + '@tailwindcss/oxide@4.1.16': + resolution: {integrity: sha512-2OSv52FRuhdlgyOQqgtQHuCgXnS8nFSYRp2tJ+4WZXKgTxqPy7SMSls8c3mPT5pkZ17SBToGM5LHEJBO7miEdg==} + engines: {node: '>= 10'} + '@tailwindcss/postcss@4.1.15': resolution: {integrity: sha512-IZh8IT76KujRz6d15wZw4eoeViT4TqmzVWNNfpuNCTKiaZUwgr5vtPqO4HjuYDyx3MgGR5qgPt1HMzTeLJyA3g==} + '@tailwindcss/vite@4.1.16': + resolution: {integrity: sha512-bbguNBcDxsRmi9nnlWJxhfDWamY3lmcyACHcdO1crxfzuLpOhHLLtEIN/nCbbAtj5rchUgQD17QVAKi1f7IsKg==} + peerDependencies: + vite: ^5.2.0 || ^6 || ^7 + + '@tanstack/devtools-client@0.0.3': + resolution: {integrity: sha512-kl0r6N5iIL3t9gGDRAv55VRM3UIyMKVH83esRGq7xBjYsRLe/BeCIN2HqrlJkObUXQMKhy7i8ejuGOn+bDqDBw==} + engines: {node: '>=18'} + + '@tanstack/devtools-event-bus@0.3.3': + resolution: {integrity: sha512-lWl88uLAz7ZhwNdLH6A3tBOSEuBCrvnY9Fzr5JPdzJRFdM5ZFdyNWz1Bf5l/F3GU57VodrN0KCFi9OA26H5Kpg==} + engines: {node: '>=18'} + + '@tanstack/devtools-event-client@0.3.3': + resolution: {integrity: sha512-RfV+OPV/M3CGryYqTue684u10jUt55PEqeBOnOtCe6tAmHI9Iqyc8nHeDhWPEV9715gShuauFVaMc9RiUVNdwg==} + engines: {node: '>=18'} + + '@tanstack/devtools-ui@0.4.3': + resolution: {integrity: sha512-7QshnQIHifURyMwl/qmYm4KDpsf8UJrJ8BUu+YvPx35RJBe2EO5qHPsefzWh6MlG/dUdVMBxP9nPqchESyuNFg==} + engines: {node: '>=18'} + peerDependencies: + solid-js: '>=1.9.7' + + '@tanstack/devtools@0.6.22': + resolution: {integrity: sha512-G7wZZiZD+pQ7OjN+lQaV7m2fhxHPUmYuOe9wM2d6QqzeI8QCDqjvKqDZLFdcNystyIw+Twf4X1jqJcR1S30ykw==} + engines: {node: '>=18'} + peerDependencies: + solid-js: '>=1.9.7' + + '@tanstack/history@1.133.19': + resolution: {integrity: sha512-Y866qBVVprdQkmO0/W1AFBI8tiQy398vFeIwP+VrRWCOzs3VecxSVzAvaOM4iHfkJz81fFAZMhLLjDVoPikD+w==} + engines: {node: '>=12'} + '@tanstack/query-core@5.90.5': resolution: {integrity: sha512-wLamYp7FaDq6ZnNehypKI5fNvxHPfTYylE0m/ZpuuzJfJqhR5Pxg9gvGBHZx4n7J+V5Rg5mZxHHTlv25Zt5u+w==} + '@tanstack/react-devtools@0.7.8': + resolution: {integrity: sha512-/G5Z6NOK5puJHpAykD0zEvmi+v53MfwsAbgSzrlLD1+UqKKh1BA63TdTqGz52mLxfQTfvW5jDRyCFV0fHZFqEw==} + engines: {node: '>=18'} + peerDependencies: + '@types/react': '>=16.8' + '@types/react-dom': '>=16.8' + react: '>=16.8' + react-dom: '>=16.8' + '@tanstack/react-query@5.90.5': resolution: {integrity: sha512-pN+8UWpxZkEJ/Rnnj2v2Sxpx1WFlaa9L6a4UO89p6tTQbeo+m0MS8oYDjbggrR8QcTyjKoYWKS3xJQGr3ExT8Q==} peerDependencies: react: ^18 || ^19 + '@tanstack/react-router-devtools@1.133.27': + resolution: {integrity: sha512-K1uDpqzvdB0bf5J00rH3pMHE0IOB0ke8Ej0VZ43loRACIY7YqqYlOFvKFVxQwI8GTGzxNs5J9uJ7Ms0+w0eH2A==} + engines: {node: '>=12'} + peerDependencies: + '@tanstack/react-router': ^1.133.27 + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + + '@tanstack/react-router@1.133.27': + resolution: {integrity: sha512-0q87mjJWhMsnP9SOD/v07lclCxrMuB20CdKi305cTZRIF858ETG0fThUF4LlstiKvxE49Wr+PBY0kwjfY4pUow==} + engines: {node: '>=12'} + peerDependencies: + react: '>=18.0.0 || >=19.0.0' + react-dom: '>=18.0.0 || >=19.0.0' + + '@tanstack/react-store@0.7.7': + resolution: {integrity: sha512-qqT0ufegFRDGSof9D/VqaZgjNgp4tRPHZIJq2+QIHkMUtHjaJ0lYrrXjeIUJvjnTbgPfSD1XgOMEt0lmANn6Zg==} + 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.133.27': + resolution: {integrity: sha512-1nb2CirHC0hZmFr8wEk0gxuExpvuk0jlKOY1+SQ7jcJCxBKHLGvAfhL6ycets3XetrTLzgBEvfuixFj3qYiFwA==} + engines: {node: '>=12'} + + '@tanstack/router-devtools-core@1.133.27': + resolution: {integrity: sha512-mYTQnZ8yQbIGNOmLcYv/V8q96qGH+wixgJUeNqUdbZ3/TrzVLaSENRId5ZXD8mx8o2Ljqy2BwZq5d+zDDaKseA==} + engines: {node: '>=12'} + peerDependencies: + '@tanstack/router-core': ^1.133.27 + csstype: ^3.0.10 + solid-js: '>=1.9.5' + tiny-invariant: ^1.3.3 + peerDependenciesMeta: + csstype: + optional: true + + '@tanstack/router-generator@1.133.27': + resolution: {integrity: sha512-+0dq0DlKzD5fk9vRKHv+vG4ANUNnwnqTqzqTMRiZfYJ16oIfcIQgIdrHRGLdsBLQ6yQIWFszY0d5ubRx0dOK8g==} + engines: {node: '>=12'} + + '@tanstack/router-plugin@1.133.27': + resolution: {integrity: sha512-E3WdABr7Vm9UijQKSjoP2Pvq5l1m8cIm/YZIDbcJ3zVQpTKMtSVgWzP1lQUtsUBrU21PBPHsOhc1+ERt832pKQ==} + engines: {node: '>=12'} + peerDependencies: + '@rsbuild/core': '>=1.0.2' + '@tanstack/react-router': ^1.133.27 + vite: '>=5.0.0 || >=6.0.0 || >=7.0.0' + vite-plugin-solid: ^2.11.10 + 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.133.19': + resolution: {integrity: sha512-WEp5D2gPxvlLDRXwD/fV7RXjYtqaqJNXKB/L6OyZEbT+9BG/Ib2d7oG9GSUZNNMGPGYAlhBUOi3xutySsk6rxA==} + engines: {node: '>=12'} + + '@tanstack/store@0.7.7': + resolution: {integrity: sha512-xa6pTan1bcaqYDS9BDpSiS63qa6EoDkPN9RsRaxHuDdVDNntzq3xNwR5YKTU/V3SkSyC9T4YVOPh2zRQN0nhIQ==} + + '@tanstack/virtual-file-routes@1.133.19': + resolution: {integrity: sha512-IKwZENsK7owmW1Lm5FhuHegY/SyQ8KqtL/7mTSnzoKJgfzhrrf9qwKB1rmkKkt+svUuy/Zw3uVEpZtUzQruWtA==} + engines: {node: '>=12'} + '@tootallnate/quickjs-emscripten@0.23.0': resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} @@ -1932,6 +2177,12 @@ packages: '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + '@vitejs/plugin-react-swc@4.2.0': + resolution: {integrity: sha512-/tesahXD1qpkGC6FzMoFOJj0RyZdw9xLELOL+6jbElwmWfwOnIVy+IfpY+o9JfD9PKaR/Eyb6DNrvbXpuvA+8Q==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^4 || ^5 || ^6 || ^7 + '@vitest/expect@3.2.4': resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} @@ -2092,9 +2343,16 @@ packages: resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} engines: {node: '>=4'} + ast-types@0.16.1: + resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} + engines: {node: '>=4'} + async-retry@1.3.3: resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} + babel-dead-code-elimination@1.0.10: + resolution: {integrity: sha512-DV5bdJZTzZ0zn0DC24v3jD7Mnidh6xhKa4GfKCbq3sfW8kaWhDdZjP3i81geA8T33tdYqWKw4D3fVv0CwEgKVA==} + bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} @@ -2288,9 +2546,6 @@ packages: resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} engines: {node: '>= 12'} - client-only@0.0.1: - resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} - clone@1.0.4: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} @@ -2367,6 +2622,9 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie-es@2.0.0: + resolution: {integrity: sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg==} + cosmiconfig@8.3.6: resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} engines: {node: '>=14'} @@ -2453,6 +2711,10 @@ packages: devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + diff@8.0.2: + resolution: {integrity: sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==} + engines: {node: '>=0.3.1'} + dot-prop@5.3.0: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} @@ -2650,6 +2912,9 @@ packages: resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} engines: {node: '>=18'} + get-tsconfig@4.13.0: + resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + get-uri@6.0.5: resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==} engines: {node: '>= 14'} @@ -2680,6 +2945,11 @@ packages: engines: {node: 20 || >=22} hasBin: true + goober@2.1.18: + resolution: {integrity: sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw==} + peerDependencies: + csstype: ^3.0.10 + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -2858,6 +3128,10 @@ packages: resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} engines: {node: '>=16'} + isbot@5.1.31: + resolution: {integrity: sha512-DPgQshehErHAqSCKDb3rNW03pa2wS/v5evvUqtxt6TTnHRqAG8FdzcSSJs9656pK6Y+NT7K9R4acEYXLHYfpUQ==} + engines: {node: '>=18'} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -3343,33 +3617,6 @@ packages: resolution: {integrity: sha512-NHDDGYudnvRutt/VhKFlX26IotXe1w0cmkDm6JGquh5bz/bDTw0LufSmH/GxTjEdpHEO+bVKFTwdrcGa/9XlKQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - next-themes@0.4.6: - resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} - peerDependencies: - react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc - react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc - - next@15.5.6: - resolution: {integrity: sha512-zTxsnI3LQo3c9HSdSf91O1jMNsEzIXDShXd4wVdg9y5shwLqBXi4ZtUUJyB86KGVSJLZx0PFONvO54aheGX8QQ==} - engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} - hasBin: true - peerDependencies: - '@opentelemetry/api': ^1.1.0 - '@playwright/test': ^1.51.1 - babel-plugin-react-compiler: '*' - react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - sass: ^1.3.0 - peerDependenciesMeta: - '@opentelemetry/api': - optional: true - '@playwright/test': - optional: true - babel-plugin-react-compiler: - optional: true - sass: - optional: true - node-addon-api@7.1.1: resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} @@ -3550,21 +3797,11 @@ packages: pkg-types@2.3.0: resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} - playwright-core@1.55.0: - resolution: {integrity: sha512-GvZs4vU3U5ro2nZpeiwyb0zuFaqb9sUiAJuyrWpcGouD8y9/HLgGbNRjIph7zU9D3hnPaisMl9zG9CgFi/biIg==} - engines: {node: '>=18'} - hasBin: true - playwright-core@1.56.1: resolution: {integrity: sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==} engines: {node: '>=18'} hasBin: true - playwright@1.55.0: - resolution: {integrity: sha512-sdCWStblvV1YU909Xqx0DhOjPZE4/5lJsIS84IfN9dAZfcl/CIZ5O8l3o0j7hPMjDvqoTF8ZUcc+i/GL5erstA==} - engines: {node: '>=18'} - hasBin: true - playwright@1.56.1: resolution: {integrity: sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==} engines: {node: '>=18'} @@ -3573,14 +3810,15 @@ packages: pofile@1.1.4: resolution: {integrity: sha512-r6Q21sKsY1AjTVVjOuU02VYKVNQGJNQHjTIvs4dEbeuuYfxgYk/DGD2mqqq4RDaVkwdSq0VEtmQUOPe/wH8X3g==} - postcss@8.4.31: - resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} - engines: {node: ^10 || ^12 || >=14} - postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} + prettier@3.6.2: + resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + engines: {node: '>=14'} + hasBin: true + pretty-format@29.7.0: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -3713,6 +3951,10 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + recast@0.23.11: + resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} + engines: {node: '>= 4'} + refractor@3.6.0: resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==} @@ -3746,6 +3988,9 @@ packages: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + restore-cursor@3.1.0: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} @@ -3807,9 +4052,15 @@ packages: serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - sharp@0.34.4: - resolution: {integrity: sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + seroval-plugins@1.3.3: + resolution: {integrity: sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w==} + engines: {node: '>=10'} + peerDependencies: + seroval: ^1.0 + + seroval@1.3.2: + resolution: {integrity: sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==} + engines: {node: '>=10'} shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} @@ -3845,6 +4096,9 @@ packages: resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==} engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + solid-js@1.9.9: + resolution: {integrity: sha512-A0ZBPJQldAeGCTW0YRYJmt7RCeh5rbFfPZ2aOttgYnctHE7HgKeHCBB/PVc2P7eOfmNXqMFFFoYYdm3S4dcbkA==} + sonner@2.0.7: resolution: {integrity: sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==} peerDependencies: @@ -3862,6 +4116,10 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + source-map@0.8.0-beta.0: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} engines: {node: '>= 8'} @@ -3926,19 +4184,6 @@ packages: style-to-object@1.0.11: resolution: {integrity: sha512-5A560JmXr7wDyGLK12Nq/EYS38VkGlglVzkis1JEdbGWSnbQIEhZzTJhzURXN5/8WwwFCs/f/VVcmkTppbXLow==} - styled-jsx@5.1.6: - resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} - engines: {node: '>= 12.0.0'} - peerDependencies: - '@babel/core': '*' - babel-plugin-macros: '*' - react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' - peerDependenciesMeta: - '@babel/core': - optional: true - babel-plugin-macros: - optional: true - supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -3953,6 +4198,9 @@ packages: tailwindcss@4.1.15: resolution: {integrity: sha512-k2WLnWkYFkdpRv+Oby3EBXIyQC8/s1HOFMBUViwtAh6Z5uAozeUSMQlIsn/c6Q2iJzqG6aJT3wdPaRNj70iYxQ==} + tailwindcss@4.1.16: + resolution: {integrity: sha512-pONL5awpaQX4LN5eiv7moSiSPd/DLDzKVRJz8Q9PgzmAdd1R4307GQS2ZpfiN7ZmekdQrfhZZiSE5jkLR4WNaA==} + tapable@2.3.0: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} @@ -3985,6 +4233,12 @@ packages: threads@1.7.0: resolution: {integrity: sha512-Mx5NBSHX3sQYR6iI9VYbgHKBLisyB+xROCBGjjWm1O9wb9vfLxdaGtmT/KCjUqMsSNW6nERzCW3T6H43LqjDZQ==} + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tiny-warning@1.0.3: + resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} + tiny-worker@2.3.0: resolution: {integrity: sha512-pJ70wq5EAqTAEl9IkGzA+fN0836rycEuz2Cn6yeZ6FRzlVS5IDOkFHpIoEsksPRQV34GDqXm65+OlnZqUSyK2g==} @@ -4029,6 +4283,11 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsx@4.20.6: + resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==} + engines: {node: '>=18.0.0'} + hasBin: true + tw-animate-css@1.4.0: resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==} @@ -4087,6 +4346,10 @@ packages: universal-user-agent@7.0.3: resolution: {integrity: sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==} + unplugin@2.3.10: + resolution: {integrity: sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw==} + engines: {node: '>=18.12.0'} + update-browserslist-db@1.1.3: resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} hasBin: true @@ -4140,8 +4403,8 @@ packages: engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true - vite@7.1.11: - resolution: {integrity: sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg==} + vite@7.1.12: + resolution: {integrity: sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -4222,6 +4485,9 @@ packages: resolution: {integrity: sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==} engines: {node: '>=10.13.0'} + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + webpack@5.102.1: resolution: {integrity: sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ==} engines: {node: '>=10.13.0'} @@ -4312,6 +4578,9 @@ packages: resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod@4.1.12: resolution: {integrity: sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==} @@ -4378,6 +4647,18 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 + '@babel/generator@7.28.5': + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.28.4 + '@babel/helper-compilation-targets@7.27.2': dependencies: '@babel/compat-data': 7.28.4 @@ -4386,8 +4667,28 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 + '@babel/helper-create-class-features-plugin@7.28.5(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.4) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.28.5 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + '@babel/helper-globals@7.28.0': {} + '@babel/helper-member-expression-to-functions@7.28.5': + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + '@babel/helper-module-imports@7.27.1': dependencies: '@babel/traverse': 7.28.4 @@ -4404,10 +4705,34 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.28.4 + + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.28.5 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 + transitivePeerDependencies: + - supports-color + '@babel/helper-string-parser@7.27.1': {} '@babel/helper-validator-identifier@7.27.1': {} + '@babel/helper-validator-identifier@7.28.5': {} + '@babel/helper-validator-option@7.27.1': {} '@babel/helpers@7.28.4': @@ -4419,6 +4744,50 @@ snapshots: dependencies: '@babel/types': 7.28.4 + '@babel/parser@7.28.5': + dependencies: + '@babel/types': 7.28.5 + + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-typescript@7.28.5(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.4) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.4) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.28.5(@babel/core@7.28.4)': + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-typescript': 7.28.5(@babel/core@7.28.4) + transitivePeerDependencies: + - supports-color + '@babel/runtime@7.28.4': {} '@babel/template@7.27.2': @@ -4439,11 +4808,28 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/traverse@7.28.5': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + '@babel/types@7.28.4': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@babel/types@7.28.5': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@biomejs/biome@2.2.6': optionalDependencies: '@biomejs/cli-darwin-arm64': 2.2.6 @@ -4557,11 +4943,6 @@ snapshots: '@effect/rpc': 0.71.0(@effect/platform@0.92.1(effect@3.18.4))(effect@3.18.4) effect: 3.18.4 - '@emnapi/runtime@1.6.0': - dependencies: - tslib: 2.8.1 - optional: true - '@esbuild/aix-ppc64@0.25.11': optional: true @@ -4657,143 +5038,58 @@ snapshots: '@floating-ui/utils@0.2.10': {} + '@hono/node-server@1.19.5(hono@4.10.1)': + dependencies: + hono: 4.10.1 + '@hono/zod-validator@0.7.4(hono@4.10.1)(zod@4.1.12)': dependencies: hono: 4.10.1 zod: 4.1.12 - '@img/colour@1.0.0': - optional: true - '@img/sharp-darwin-arm64@0.33.5': optionalDependencies: '@img/sharp-libvips-darwin-arm64': 1.0.4 optional: true - '@img/sharp-darwin-arm64@0.34.4': - optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.2.3 - optional: true - '@img/sharp-darwin-x64@0.33.5': optionalDependencies: '@img/sharp-libvips-darwin-x64': 1.0.4 optional: true - '@img/sharp-darwin-x64@0.34.4': - optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.2.3 - optional: true - '@img/sharp-libvips-darwin-arm64@1.0.4': optional: true - '@img/sharp-libvips-darwin-arm64@1.2.3': - optional: true - '@img/sharp-libvips-darwin-x64@1.0.4': optional: true - '@img/sharp-libvips-darwin-x64@1.2.3': - optional: true - '@img/sharp-libvips-linux-arm64@1.0.4': optional: true - '@img/sharp-libvips-linux-arm64@1.2.3': - optional: true - '@img/sharp-libvips-linux-arm@1.0.5': optional: true - '@img/sharp-libvips-linux-arm@1.2.3': - optional: true - - '@img/sharp-libvips-linux-ppc64@1.2.3': - optional: true - - '@img/sharp-libvips-linux-s390x@1.2.3': - optional: true - '@img/sharp-libvips-linux-x64@1.0.4': optional: true - '@img/sharp-libvips-linux-x64@1.2.3': - optional: true - - '@img/sharp-libvips-linuxmusl-arm64@1.2.3': - optional: true - - '@img/sharp-libvips-linuxmusl-x64@1.2.3': - optional: true - '@img/sharp-linux-arm64@0.33.5': optionalDependencies: '@img/sharp-libvips-linux-arm64': 1.0.4 optional: true - '@img/sharp-linux-arm64@0.34.4': - optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.2.3 - optional: true - '@img/sharp-linux-arm@0.33.5': optionalDependencies: '@img/sharp-libvips-linux-arm': 1.0.5 optional: true - '@img/sharp-linux-arm@0.34.4': - optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.2.3 - optional: true - - '@img/sharp-linux-ppc64@0.34.4': - optionalDependencies: - '@img/sharp-libvips-linux-ppc64': 1.2.3 - optional: true - - '@img/sharp-linux-s390x@0.34.4': - optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.2.3 - optional: true - '@img/sharp-linux-x64@0.33.5': optionalDependencies: '@img/sharp-libvips-linux-x64': 1.0.4 optional: true - '@img/sharp-linux-x64@0.34.4': - optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.2.3 - optional: true - - '@img/sharp-linuxmusl-arm64@0.34.4': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.2.3 - optional: true - - '@img/sharp-linuxmusl-x64@0.34.4': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.2.3 - optional: true - - '@img/sharp-wasm32@0.34.4': - dependencies: - '@emnapi/runtime': 1.6.0 - optional: true - - '@img/sharp-win32-arm64@0.34.4': - optional: true - - '@img/sharp-win32-ia32@0.34.4': - optional: true - '@img/sharp-win32-x64@0.33.5': optional: true - '@img/sharp-win32-x64@0.34.4': - optional: true - '@inquirer/ansi@1.0.1': {} '@inquirer/checkbox@4.3.0(@types/node@24.9.1)': @@ -5051,12 +5347,12 @@ snapshots: transitivePeerDependencies: - typescript - '@lingui/loader@5.5.1(typescript@5.9.3)(webpack@5.102.1)': + '@lingui/loader@5.5.1(typescript@5.9.3)(webpack@5.102.1(esbuild@0.25.11))': dependencies: '@babel/runtime': 7.28.4 '@lingui/cli': 5.5.1(typescript@5.9.3) '@lingui/conf': 5.5.1(typescript@5.9.3) - webpack: 5.102.1 + webpack: 5.102.1(esbuild@0.25.11) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -5075,6 +5371,16 @@ snapshots: optionalDependencies: '@lingui/babel-plugin-lingui-macro': 5.5.1(typescript@5.9.3) + '@lingui/vite-plugin@5.5.1(typescript@5.9.3)(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + dependencies: + '@lingui/cli': 5.5.1(typescript@5.9.3) + '@lingui/conf': 5.5.1(typescript@5.9.3) + vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - typescript + '@messageformat/parser@5.1.1': dependencies: moo: 0.5.2 @@ -5097,32 +5403,6 @@ snapshots: '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': optional: true - '@next/env@15.5.6': {} - - '@next/swc-darwin-arm64@15.5.6': - optional: true - - '@next/swc-darwin-x64@15.5.6': - optional: true - - '@next/swc-linux-arm64-gnu@15.5.6': - optional: true - - '@next/swc-linux-arm64-musl@15.5.6': - optional: true - - '@next/swc-linux-x64-gnu@15.5.6': - optional: true - - '@next/swc-linux-x64-musl@15.5.6': - optional: true - - '@next/swc-win32-arm64-msvc@15.5.6': - optional: true - - '@next/swc-win32-x64-msvc@15.5.6': - optional: true - '@nodeutils/defaults-deep@1.1.0': dependencies: lodash: 4.17.21 @@ -5251,11 +5531,6 @@ snapshots: '@phun-ky/typeof@2.0.3': {} - '@playwright/test@1.55.0': - dependencies: - playwright: 1.55.0 - optional: true - '@radix-ui/number@1.1.1': {} '@radix-ui/primitive@1.1.3': {} @@ -5628,6 +5903,8 @@ snapshots: '@radix-ui/rect@1.1.1': {} + '@rolldown/pluginutils@1.0.0-beta.43': {} + '@rollup/rollup-android-arm-eabi@4.52.5': optional: true @@ -5709,11 +5986,93 @@ snapshots: '@sindresorhus/merge-streams@4.0.0': {} + '@solid-primitives/event-listener@2.4.3(solid-js@1.9.9)': + dependencies: + '@solid-primitives/utils': 6.3.2(solid-js@1.9.9) + solid-js: 1.9.9 + + '@solid-primitives/keyboard@1.3.3(solid-js@1.9.9)': + dependencies: + '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.9) + '@solid-primitives/rootless': 1.5.2(solid-js@1.9.9) + '@solid-primitives/utils': 6.3.2(solid-js@1.9.9) + solid-js: 1.9.9 + + '@solid-primitives/resize-observer@2.1.3(solid-js@1.9.9)': + dependencies: + '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.9) + '@solid-primitives/rootless': 1.5.2(solid-js@1.9.9) + '@solid-primitives/static-store': 0.1.2(solid-js@1.9.9) + '@solid-primitives/utils': 6.3.2(solid-js@1.9.9) + solid-js: 1.9.9 + + '@solid-primitives/rootless@1.5.2(solid-js@1.9.9)': + dependencies: + '@solid-primitives/utils': 6.3.2(solid-js@1.9.9) + solid-js: 1.9.9 + + '@solid-primitives/static-store@0.1.2(solid-js@1.9.9)': + dependencies: + '@solid-primitives/utils': 6.3.2(solid-js@1.9.9) + solid-js: 1.9.9 + + '@solid-primitives/utils@6.3.2(solid-js@1.9.9)': + dependencies: + solid-js: 1.9.9 + '@standard-schema/spec@1.0.0': {} - '@swc/helpers@0.5.15': + '@swc/core-darwin-arm64@1.13.5': + optional: true + + '@swc/core-darwin-x64@1.13.5': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.13.5': + optional: true + + '@swc/core-linux-arm64-gnu@1.13.5': + optional: true + + '@swc/core-linux-arm64-musl@1.13.5': + optional: true + + '@swc/core-linux-x64-gnu@1.13.5': + optional: true + + '@swc/core-linux-x64-musl@1.13.5': + optional: true + + '@swc/core-win32-arm64-msvc@1.13.5': + optional: true + + '@swc/core-win32-ia32-msvc@1.13.5': + optional: true + + '@swc/core-win32-x64-msvc@1.13.5': + optional: true + + '@swc/core@1.13.5': dependencies: - tslib: 2.8.1 + '@swc/counter': 0.1.3 + '@swc/types': 0.1.25 + optionalDependencies: + '@swc/core-darwin-arm64': 1.13.5 + '@swc/core-darwin-x64': 1.13.5 + '@swc/core-linux-arm-gnueabihf': 1.13.5 + '@swc/core-linux-arm64-gnu': 1.13.5 + '@swc/core-linux-arm64-musl': 1.13.5 + '@swc/core-linux-x64-gnu': 1.13.5 + '@swc/core-linux-x64-musl': 1.13.5 + '@swc/core-win32-arm64-msvc': 1.13.5 + '@swc/core-win32-ia32-msvc': 1.13.5 + '@swc/core-win32-x64-msvc': 1.13.5 + + '@swc/counter@0.1.3': {} + + '@swc/types@0.1.25': + dependencies: + '@swc/counter': 0.1.3 '@tailwindcss/node@4.1.15': dependencies: @@ -5725,42 +6084,88 @@ snapshots: source-map-js: 1.2.1 tailwindcss: 4.1.15 + '@tailwindcss/node@4.1.16': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.18.3 + jiti: 2.6.1 + lightningcss: 1.30.2 + magic-string: 0.30.19 + source-map-js: 1.2.1 + tailwindcss: 4.1.16 + '@tailwindcss/oxide-android-arm64@4.1.15': optional: true + '@tailwindcss/oxide-android-arm64@4.1.16': + optional: true + '@tailwindcss/oxide-darwin-arm64@4.1.15': optional: true + '@tailwindcss/oxide-darwin-arm64@4.1.16': + optional: true + '@tailwindcss/oxide-darwin-x64@4.1.15': optional: true + '@tailwindcss/oxide-darwin-x64@4.1.16': + optional: true + '@tailwindcss/oxide-freebsd-x64@4.1.15': optional: true + '@tailwindcss/oxide-freebsd-x64@4.1.16': + optional: true + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.15': optional: true + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.16': + optional: true + '@tailwindcss/oxide-linux-arm64-gnu@4.1.15': optional: true + '@tailwindcss/oxide-linux-arm64-gnu@4.1.16': + optional: true + '@tailwindcss/oxide-linux-arm64-musl@4.1.15': optional: true + '@tailwindcss/oxide-linux-arm64-musl@4.1.16': + optional: true + '@tailwindcss/oxide-linux-x64-gnu@4.1.15': optional: true + '@tailwindcss/oxide-linux-x64-gnu@4.1.16': + optional: true + '@tailwindcss/oxide-linux-x64-musl@4.1.15': optional: true + '@tailwindcss/oxide-linux-x64-musl@4.1.16': + optional: true + '@tailwindcss/oxide-wasm32-wasi@4.1.15': optional: true + '@tailwindcss/oxide-wasm32-wasi@4.1.16': + optional: true + '@tailwindcss/oxide-win32-arm64-msvc@4.1.15': optional: true + '@tailwindcss/oxide-win32-arm64-msvc@4.1.16': + optional: true + '@tailwindcss/oxide-win32-x64-msvc@4.1.15': optional: true + '@tailwindcss/oxide-win32-x64-msvc@4.1.16': + optional: true + '@tailwindcss/oxide@4.1.15': optionalDependencies: '@tailwindcss/oxide-android-arm64': 4.1.15 @@ -5776,6 +6181,21 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.1.15 '@tailwindcss/oxide-win32-x64-msvc': 4.1.15 + '@tailwindcss/oxide@4.1.16': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.1.16 + '@tailwindcss/oxide-darwin-arm64': 4.1.16 + '@tailwindcss/oxide-darwin-x64': 4.1.16 + '@tailwindcss/oxide-freebsd-x64': 4.1.16 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.16 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.16 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.16 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.16 + '@tailwindcss/oxide-linux-x64-musl': 4.1.16 + '@tailwindcss/oxide-wasm32-wasi': 4.1.16 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.16 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.16 + '@tailwindcss/postcss@4.1.15': dependencies: '@alloc/quick-lru': 5.2.0 @@ -5784,13 +6204,200 @@ snapshots: postcss: 8.5.6 tailwindcss: 4.1.15 + '@tailwindcss/vite@4.1.16(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + dependencies: + '@tailwindcss/node': 4.1.16 + '@tailwindcss/oxide': 4.1.16 + tailwindcss: 4.1.16 + vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + + '@tanstack/devtools-client@0.0.3': + dependencies: + '@tanstack/devtools-event-client': 0.3.3 + + '@tanstack/devtools-event-bus@0.3.3': + dependencies: + ws: 8.18.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@tanstack/devtools-event-client@0.3.3': {} + + '@tanstack/devtools-ui@0.4.3(csstype@3.1.3)(solid-js@1.9.9)': + dependencies: + clsx: 2.1.1 + goober: 2.1.18(csstype@3.1.3) + solid-js: 1.9.9 + transitivePeerDependencies: + - csstype + + '@tanstack/devtools@0.6.22(csstype@3.1.3)(solid-js@1.9.9)': + dependencies: + '@solid-primitives/event-listener': 2.4.3(solid-js@1.9.9) + '@solid-primitives/keyboard': 1.3.3(solid-js@1.9.9) + '@solid-primitives/resize-observer': 2.1.3(solid-js@1.9.9) + '@tanstack/devtools-client': 0.0.3 + '@tanstack/devtools-event-bus': 0.3.3 + '@tanstack/devtools-ui': 0.4.3(csstype@3.1.3)(solid-js@1.9.9) + clsx: 2.1.1 + goober: 2.1.18(csstype@3.1.3) + solid-js: 1.9.9 + transitivePeerDependencies: + - bufferutil + - csstype + - utf-8-validate + + '@tanstack/history@1.133.19': {} + '@tanstack/query-core@5.90.5': {} + '@tanstack/react-devtools@0.7.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(csstype@3.1.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(solid-js@1.9.9)': + dependencies: + '@tanstack/devtools': 0.6.22(csstype@3.1.3)(solid-js@1.9.9) + '@types/react': 19.2.2 + '@types/react-dom': 19.2.2(@types/react@19.2.2) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + transitivePeerDependencies: + - bufferutil + - csstype + - solid-js + - utf-8-validate + '@tanstack/react-query@5.90.5(react@19.2.0)': dependencies: '@tanstack/query-core': 5.90.5 react: 19.2.0 + '@tanstack/react-router-devtools@1.133.27(@tanstack/react-router@1.133.27(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@tanstack/router-core@1.133.27)(@types/node@24.9.1)(csstype@3.1.3)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(solid-js@1.9.9)(terser@5.44.0)(tiny-invariant@1.3.3)(tsx@4.20.6)(yaml@2.8.1)': + dependencies: + '@tanstack/react-router': 1.133.27(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@tanstack/router-devtools-core': 1.133.27(@tanstack/router-core@1.133.27)(@types/node@24.9.1)(csstype@3.1.3)(jiti@2.6.1)(lightningcss@1.30.2)(solid-js@1.9.9)(terser@5.44.0)(tiny-invariant@1.3.3)(tsx@4.20.6)(yaml@2.8.1) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + transitivePeerDependencies: + - '@tanstack/router-core' + - '@types/node' + - csstype + - jiti + - less + - lightningcss + - sass + - sass-embedded + - solid-js + - stylus + - sugarss + - terser + - tiny-invariant + - tsx + - yaml + + '@tanstack/react-router@1.133.27(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@tanstack/history': 1.133.19 + '@tanstack/react-store': 0.7.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@tanstack/router-core': 1.133.27 + isbot: 5.1.31 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 + + '@tanstack/react-store@0.7.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@tanstack/store': 0.7.7 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + use-sync-external-store: 1.6.0(react@19.2.0) + + '@tanstack/router-core@1.133.27': + dependencies: + '@tanstack/history': 1.133.19 + '@tanstack/store': 0.7.7 + cookie-es: 2.0.0 + seroval: 1.3.2 + seroval-plugins: 1.3.3(seroval@1.3.2) + tiny-invariant: 1.3.3 + tiny-warning: 1.0.3 + + '@tanstack/router-devtools-core@1.133.27(@tanstack/router-core@1.133.27)(@types/node@24.9.1)(csstype@3.1.3)(jiti@2.6.1)(lightningcss@1.30.2)(solid-js@1.9.9)(terser@5.44.0)(tiny-invariant@1.3.3)(tsx@4.20.6)(yaml@2.8.1)': + dependencies: + '@tanstack/router-core': 1.133.27 + clsx: 2.1.1 + goober: 2.1.18(csstype@3.1.3) + solid-js: 1.9.9 + tiny-invariant: 1.3.3 + vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + optionalDependencies: + csstype: 3.1.3 + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + + '@tanstack/router-generator@1.133.27': + dependencies: + '@tanstack/router-core': 1.133.27 + '@tanstack/router-utils': 1.133.19 + '@tanstack/virtual-file-routes': 1.133.19 + prettier: 3.6.2 + recast: 0.23.11 + source-map: 0.7.6 + tsx: 4.20.6 + zod: 3.25.76 + transitivePeerDependencies: + - supports-color + + '@tanstack/router-plugin@1.133.27(@tanstack/react-router@1.133.27(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))(webpack@5.102.1(esbuild@0.25.11))': + dependencies: + '@babel/core': 7.28.4 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.4) + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 + '@tanstack/router-core': 1.133.27 + '@tanstack/router-generator': 1.133.27 + '@tanstack/router-utils': 1.133.19 + '@tanstack/virtual-file-routes': 1.133.19 + babel-dead-code-elimination: 1.0.10 + chokidar: 3.6.0 + unplugin: 2.3.10 + zod: 3.25.76 + optionalDependencies: + '@tanstack/react-router': 1.133.27(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + webpack: 5.102.1(esbuild@0.25.11) + transitivePeerDependencies: + - supports-color + + '@tanstack/router-utils@1.133.19': + dependencies: + '@babel/core': 7.28.4 + '@babel/generator': 7.28.3 + '@babel/parser': 7.28.4 + '@babel/preset-typescript': 7.28.5(@babel/core@7.28.4) + ansis: 4.2.0 + diff: 8.0.2 + pathe: 2.0.3 + tinyglobby: 0.2.15 + transitivePeerDependencies: + - supports-color + + '@tanstack/store@0.7.7': {} + + '@tanstack/virtual-file-routes@1.133.19': {} + '@tootallnate/quickjs-emscripten@0.23.0': {} '@tsconfig/strictest@2.0.6': {} @@ -5884,6 +6491,14 @@ snapshots: '@ungap/structured-clone@1.3.0': {} + '@vitejs/plugin-react-swc@4.2.0(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + dependencies: + '@rolldown/pluginutils': 1.0.0-beta.43 + '@swc/core': 1.13.5 + vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + transitivePeerDependencies: + - '@swc/helpers' + '@vitest/expect@3.2.4': dependencies: '@types/chai': 5.2.3 @@ -5892,13 +6507,13 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@7.1.11(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1))': + '@vitest/mocker@3.2.4(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.19 optionalDependencies: - vite: 7.1.11(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) '@vitest/pretty-format@3.2.4': dependencies: @@ -6065,10 +6680,23 @@ snapshots: dependencies: tslib: 2.8.1 + ast-types@0.16.1: + dependencies: + tslib: 2.8.1 + async-retry@1.3.3: dependencies: retry: 0.13.1 + babel-dead-code-elimination@1.0.10: + dependencies: + '@babel/core': 7.28.4 + '@babel/parser': 7.28.4 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 + transitivePeerDependencies: + - supports-color + bail@2.0.2: {} base64-js@1.5.1: {} @@ -6307,8 +6935,6 @@ snapshots: cli-width@4.1.0: {} - client-only@0.0.1: {} - clone@1.0.4: {} clsx@2.1.1: {} @@ -6366,6 +6992,8 @@ snapshots: convert-source-map@2.0.0: {} + cookie-es@2.0.0: {} + cosmiconfig@8.3.6(typescript@5.9.3): dependencies: import-fresh: 3.3.1 @@ -6434,6 +7062,8 @@ snapshots: dependencies: dequal: 2.0.3 + diff@8.0.2: {} + dot-prop@5.3.0: dependencies: is-obj: 2.0.0 @@ -6630,6 +7260,10 @@ snapshots: '@sec-ant/readable-stream': 0.4.1 is-stream: 4.0.1 + get-tsconfig@4.13.0: + dependencies: + resolve-pkg-maps: 1.0.0 + get-uri@6.0.5: dependencies: basic-ftp: 5.0.5 @@ -6681,6 +7315,10 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 2.0.0 + goober@2.1.18(csstype@3.1.3): + dependencies: + csstype: 3.1.3 + graceful-fs@4.2.11: {} has-flag@4.0.0: {} @@ -6844,6 +7482,8 @@ snapshots: dependencies: is-inside-container: 1.0.0 + isbot@5.1.31: {} + isexe@2.0.0: {} isexe@3.1.1: {} @@ -7459,35 +8099,6 @@ snapshots: dependencies: type-fest: 2.19.0 - next-themes@0.4.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0): - dependencies: - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - - next@15.5.6(@babel/core@7.28.4)(@playwright/test@1.55.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0): - dependencies: - '@next/env': 15.5.6 - '@swc/helpers': 0.5.15 - caniuse-lite: 1.0.30001751 - postcss: 8.4.31 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) - styled-jsx: 5.1.6(@babel/core@7.28.4)(react@19.2.0) - optionalDependencies: - '@next/swc-darwin-arm64': 15.5.6 - '@next/swc-darwin-x64': 15.5.6 - '@next/swc-linux-arm64-gnu': 15.5.6 - '@next/swc-linux-arm64-musl': 15.5.6 - '@next/swc-linux-x64-gnu': 15.5.6 - '@next/swc-linux-x64-musl': 15.5.6 - '@next/swc-win32-arm64-msvc': 15.5.6 - '@next/swc-win32-x64-msvc': 15.5.6 - '@playwright/test': 1.55.0 - sharp: 0.34.4 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - node-addon-api@7.1.1: {} node-fetch-native@1.6.7: {} @@ -7706,18 +8317,8 @@ snapshots: exsolve: 1.0.7 pathe: 2.0.3 - playwright-core@1.55.0: - optional: true - playwright-core@1.56.1: {} - playwright@1.55.0: - dependencies: - playwright-core: 1.55.0 - optionalDependencies: - fsevents: 2.3.2 - optional: true - playwright@1.56.1: dependencies: playwright-core: 1.56.1 @@ -7726,18 +8327,14 @@ snapshots: pofile@1.1.4: {} - postcss@8.4.31: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - postcss@8.5.6: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 + prettier@3.6.2: {} + pretty-format@29.7.0: dependencies: '@jest/schemas': 29.6.3 @@ -7884,6 +8481,14 @@ snapshots: readdirp@4.1.2: {} + recast@0.23.11: + dependencies: + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.8.1 + refractor@3.6.0: dependencies: hastscript: 6.0.0 @@ -7970,6 +8575,8 @@ snapshots: resolve-from@4.0.0: {} + resolve-pkg-maps@1.0.0: {} + restore-cursor@3.1.0: dependencies: onetime: 5.1.2 @@ -8043,35 +8650,11 @@ snapshots: dependencies: randombytes: 2.1.0 - sharp@0.34.4: + seroval-plugins@1.3.3(seroval@1.3.2): dependencies: - '@img/colour': 1.0.0 - detect-libc: 2.1.2 - semver: 7.7.3 - optionalDependencies: - '@img/sharp-darwin-arm64': 0.34.4 - '@img/sharp-darwin-x64': 0.34.4 - '@img/sharp-libvips-darwin-arm64': 1.2.3 - '@img/sharp-libvips-darwin-x64': 1.2.3 - '@img/sharp-libvips-linux-arm': 1.2.3 - '@img/sharp-libvips-linux-arm64': 1.2.3 - '@img/sharp-libvips-linux-ppc64': 1.2.3 - '@img/sharp-libvips-linux-s390x': 1.2.3 - '@img/sharp-libvips-linux-x64': 1.2.3 - '@img/sharp-libvips-linuxmusl-arm64': 1.2.3 - '@img/sharp-libvips-linuxmusl-x64': 1.2.3 - '@img/sharp-linux-arm': 0.34.4 - '@img/sharp-linux-arm64': 0.34.4 - '@img/sharp-linux-ppc64': 0.34.4 - '@img/sharp-linux-s390x': 0.34.4 - '@img/sharp-linux-x64': 0.34.4 - '@img/sharp-linuxmusl-arm64': 0.34.4 - '@img/sharp-linuxmusl-x64': 0.34.4 - '@img/sharp-wasm32': 0.34.4 - '@img/sharp-win32-arm64': 0.34.4 - '@img/sharp-win32-ia32': 0.34.4 - '@img/sharp-win32-x64': 0.34.4 - optional: true + seroval: 1.3.2 + + seroval@1.3.2: {} shebang-command@2.0.0: dependencies: @@ -8102,6 +8685,12 @@ snapshots: ip-address: 10.0.1 smart-buffer: 4.2.0 + solid-js@1.9.9: + dependencies: + csstype: 3.1.3 + seroval: 1.3.2 + seroval-plugins: 1.3.3(seroval@1.3.2) + sonner@2.0.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: react: 19.2.0 @@ -8116,6 +8705,8 @@ snapshots: source-map@0.6.1: {} + source-map@0.7.6: {} + source-map@0.8.0-beta.0: dependencies: whatwg-url: 7.1.0 @@ -8180,13 +8771,6 @@ snapshots: dependencies: inline-style-parser: 0.2.4 - styled-jsx@5.1.6(@babel/core@7.28.4)(react@19.2.0): - dependencies: - client-only: 0.0.1 - react: 19.2.0 - optionalDependencies: - '@babel/core': 7.28.4 - supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -8199,6 +8783,8 @@ snapshots: tailwindcss@4.1.15: {} + tailwindcss@4.1.16: {} + tapable@2.3.0: {} tar@6.2.1: @@ -8210,14 +8796,16 @@ snapshots: mkdirp: 1.0.4 yallist: 4.0.0 - terser-webpack-plugin@5.3.14(webpack@5.102.1): + terser-webpack-plugin@5.3.14(esbuild@0.25.11)(webpack@5.102.1(esbuild@0.25.11)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 serialize-javascript: 6.0.2 terser: 5.44.0 - webpack: 5.102.1 + webpack: 5.102.1(esbuild@0.25.11) + optionalDependencies: + esbuild: 0.25.11 terser@5.44.0: dependencies: @@ -8237,6 +8825,10 @@ snapshots: transitivePeerDependencies: - supports-color + tiny-invariant@1.3.3: {} + + tiny-warning@1.0.3: {} + tiny-worker@2.3.0: dependencies: esm: 3.2.25 @@ -8273,6 +8865,13 @@ snapshots: tslib@2.8.1: {} + tsx@4.20.6: + dependencies: + esbuild: 0.25.11 + get-tsconfig: 4.13.0 + optionalDependencies: + fsevents: 2.3.3 + tw-animate-css@1.4.0: {} type-fest@2.19.0: {} @@ -8328,6 +8927,13 @@ snapshots: universal-user-agent@7.0.3: {} + unplugin@2.3.10: + dependencies: + '@jridgewell/remapping': 2.3.5 + acorn: 8.15.0 + picomatch: 4.0.3 + webpack-virtual-modules: 0.6.2 + update-browserslist-db@1.1.3(browserslist@4.26.3): dependencies: browserslist: 4.26.3 @@ -8369,13 +8975,13 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite-node@3.2.4(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1): + vite-node@3.2.4(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.1.11(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - '@types/node' - jiti @@ -8390,7 +8996,7 @@ snapshots: - tsx - yaml - vite@7.1.11(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1): + vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: esbuild: 0.25.11 fdir: 6.5.0(picomatch@4.0.3) @@ -8404,13 +9010,14 @@ snapshots: jiti: 2.6.1 lightningcss: 1.30.2 terser: 5.44.0 + tsx: 4.20.6 yaml: 2.8.1 - vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.1.11(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1)) + '@vitest/mocker': 3.2.4(vite@7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -8428,8 +9035,8 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.1.11(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) - vite-node: 3.2.4(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(yaml@2.8.1) + vite: 7.1.12(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite-node: 3.2.4(@types/node@24.9.1)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 @@ -8461,7 +9068,9 @@ snapshots: webpack-sources@3.3.3: {} - webpack@5.102.1: + webpack-virtual-modules@0.6.2: {} + + webpack@5.102.1(esbuild@0.25.11): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -8485,7 +9094,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.0 - terser-webpack-plugin: 5.3.14(webpack@5.102.1) + terser-webpack-plugin: 5.3.14(esbuild@0.25.11)(webpack@5.102.1(esbuild@0.25.11)) watchpack: 2.4.4 webpack-sources: 3.3.3 transitivePeerDependencies: @@ -8556,6 +9165,8 @@ snapshots: yoctocolors@2.1.2: {} + zod@3.25.76: {} + zod@4.1.12: {} zwitch@2.0.4: {} diff --git a/postcss.config.json b/postcss.config.json new file mode 100644 index 0000000..7dd1e96 --- /dev/null +++ b/postcss.config.json @@ -0,0 +1,3 @@ +{ + "plugins": ["@tailwindcss/postcss"] +} diff --git a/postcss.config.mjs b/postcss.config.mjs deleted file mode 100644 index c7bcb4b..0000000 --- a/postcss.config.mjs +++ /dev/null @@ -1,5 +0,0 @@ -const config = { - plugins: ["@tailwindcss/postcss"], -}; - -export default config; diff --git a/src/@types/env.d.ts b/src/@types/env.d.ts new file mode 100644 index 0000000..4b052ca --- /dev/null +++ b/src/@types/env.d.ts @@ -0,0 +1,10 @@ +declare module "process" { + global { + namespace NodeJS { + interface ProcessEnv { + DEV_BE_PORT?: string; + PORT?: string; + } + } + } +} diff --git a/src/app/api/[[...route]]/route.ts b/src/app/api/[[...route]]/route.ts deleted file mode 100644 index 13072ff..0000000 --- a/src/app/api/[[...route]]/route.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { NodeContext } from "@effect/platform-node"; -import { Effect } from "effect"; -import { handle } from "hono/vercel"; -import { ClaudeCodeController } from "../../../server/core/claude-code/presentation/ClaudeCodeController"; -import { ClaudeCodePermissionController } from "../../../server/core/claude-code/presentation/ClaudeCodePermissionController"; -import { ClaudeCodeSessionProcessController } from "../../../server/core/claude-code/presentation/ClaudeCodeSessionProcessController"; -import { ClaudeCodeLifeCycleService } from "../../../server/core/claude-code/services/ClaudeCodeLifeCycleService"; -import { ClaudeCodePermissionService } from "../../../server/core/claude-code/services/ClaudeCodePermissionService"; -import { ClaudeCodeService } from "../../../server/core/claude-code/services/ClaudeCodeService"; -import { ClaudeCodeSessionProcessService } from "../../../server/core/claude-code/services/ClaudeCodeSessionProcessService"; -import { SSEController } from "../../../server/core/events/presentation/SSEController"; -import { FileWatcherService } from "../../../server/core/events/services/fileWatcher"; -import { FileSystemController } from "../../../server/core/file-system/presentation/FileSystemController"; -import { GitController } from "../../../server/core/git/presentation/GitController"; -import { GitService } from "../../../server/core/git/services/GitService"; -import { ProjectRepository } from "../../../server/core/project/infrastructure/ProjectRepository"; -import { ProjectController } from "../../../server/core/project/presentation/ProjectController"; -import { ProjectMetaService } from "../../../server/core/project/services/ProjectMetaService"; -import { SchedulerConfigBaseDir } from "../../../server/core/scheduler/config"; -import { SchedulerService } from "../../../server/core/scheduler/domain/Scheduler"; -import { SchedulerController } from "../../../server/core/scheduler/presentation/SchedulerController"; -import { SessionRepository } from "../../../server/core/session/infrastructure/SessionRepository"; -import { VirtualConversationDatabase } from "../../../server/core/session/infrastructure/VirtualConversationDatabase"; -import { SessionController } from "../../../server/core/session/presentation/SessionController"; -import { SessionMetaService } from "../../../server/core/session/services/SessionMetaService"; -import { honoApp } from "../../../server/hono/app"; -import { InitializeService } from "../../../server/hono/initialize"; -import { routes } from "../../../server/hono/route"; -import { platformLayer } from "../../../server/lib/effect/layers"; - -const program = routes(honoApp); - -await Effect.runPromise( - program - // 依存の浅い順にコンテナに pipe する必要がある - .pipe( - /** Presentation */ - Effect.provide(ProjectController.Live), - Effect.provide(SessionController.Live), - Effect.provide(GitController.Live), - Effect.provide(ClaudeCodeController.Live), - Effect.provide(ClaudeCodeSessionProcessController.Live), - Effect.provide(ClaudeCodePermissionController.Live), - Effect.provide(FileSystemController.Live), - Effect.provide(SSEController.Live), - Effect.provide(SchedulerController.Live), - ) - .pipe( - /** Application */ - Effect.provide(InitializeService.Live), - Effect.provide(FileWatcherService.Live), - ) - .pipe( - /** Domain */ - Effect.provide(ClaudeCodeLifeCycleService.Live), - Effect.provide(ClaudeCodePermissionService.Live), - Effect.provide(ClaudeCodeSessionProcessService.Live), - Effect.provide(ClaudeCodeService.Live), - Effect.provide(GitService.Live), - Effect.provide(SchedulerService.Live), - Effect.provide(SchedulerConfigBaseDir.Live), - ) - .pipe( - /** Infrastructure */ - Effect.provide(ProjectRepository.Live), - Effect.provide(SessionRepository.Live), - Effect.provide(ProjectMetaService.Live), - Effect.provide(SessionMetaService.Live), - Effect.provide(VirtualConversationDatabase.Live), - ) - .pipe( - /** Platform */ - Effect.provide(platformLayer), - Effect.provide(NodeContext.layer), - ), -); - -export const GET = handle(honoApp); -export const POST = handle(honoApp); -export const PUT = handle(honoApp); -export const PATCH = handle(honoApp); -export const DELETE = handle(honoApp); diff --git a/src/app/components/MarkdownContent.tsx b/src/app/components/MarkdownContent.tsx index faa038d..9235319 100644 --- a/src/app/components/MarkdownContent.tsx +++ b/src/app/components/MarkdownContent.tsx @@ -1,6 +1,3 @@ -"use client"; - -import { useTheme } from "next-themes"; import type { FC } from "react"; import Markdown from "react-markdown"; import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; @@ -19,7 +16,7 @@ export const MarkdownContent: FC = ({ content, className = "", }) => { - const { resolvedTheme } = useTheme(); + const resolvedTheme = "light" as "light" | "dark"; // TODO: 設定から取り出す const syntaxTheme = resolvedTheme === "dark" ? oneDark : oneLight; return ( diff --git a/src/app/components/RootErrorBoundary.tsx b/src/app/components/RootErrorBoundary.tsx index f18c9ac..628f9ba 100644 --- a/src/app/components/RootErrorBoundary.tsx +++ b/src/app/components/RootErrorBoundary.tsx @@ -1,5 +1,3 @@ -"use client"; - import { AlertCircle, Home, RefreshCw } from "lucide-react"; import type { FC, PropsWithChildren } from "react"; import { ErrorBoundary } from "react-error-boundary"; diff --git a/src/app/components/SSEEventListeners.tsx b/src/app/components/SSEEventListeners.tsx index 0d0b0c3..e77c067 100644 --- a/src/app/components/SSEEventListeners.tsx +++ b/src/app/components/SSEEventListeners.tsx @@ -1,5 +1,3 @@ -"use client"; - import { useQueryClient } from "@tanstack/react-query"; import { useSetAtom } from "jotai"; import type { FC, PropsWithChildren } from "react"; diff --git a/src/app/components/SyncSessionProcess.tsx b/src/app/components/SyncSessionProcess.tsx index e0ff79a..b3cb091 100644 --- a/src/app/components/SyncSessionProcess.tsx +++ b/src/app/components/SyncSessionProcess.tsx @@ -1,5 +1,3 @@ -"use client"; - import { useSetAtom } from "jotai"; import { type FC, type PropsWithChildren, useEffect } from "react"; import type { PublicSessionProcess } from "../../types/session-process"; diff --git a/src/app/error.tsx b/src/app/error.tsx deleted file mode 100644 index b52733a..0000000 --- a/src/app/error.tsx +++ /dev/null @@ -1,69 +0,0 @@ -"use client"; - -import { AlertCircle, Home, RefreshCw } from "lucide-react"; - -import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; -import { Button } from "@/components/ui/button"; -import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, -} from "@/components/ui/card"; - -export default function ErrorPage({ - error, - reset, -}: { - error: Error & { digest?: string }; - reset: () => void; -}) { - return ( -
- - -
- -
- Something went wrong - - An unexpected error occurred in the application - -
-
-
- - - - Error Details - - {error.message} - {error.digest && ( -
- Error ID: {error.digest} -
- )} -
-
- -
- - -
-
-
-
- ); -} diff --git a/src/app/layout.tsx b/src/app/layout.tsx deleted file mode 100644 index 80c6df0..0000000 --- a/src/app/layout.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import { QueryClient } from "@tanstack/react-query"; -import { Geist, Geist_Mono } from "next/font/google"; -import { ThemeProvider } from "next-themes"; - -import { Toaster } from "../components/ui/sonner"; -import { honoClient } from "../lib/api/client"; -import { QueryClientProviderWrapper } from "../lib/api/QueryClientProviderWrapper"; -import { configQuery } from "../lib/api/queries"; -import { LinguiServerProvider } from "../lib/i18n/LinguiServerProvider"; -import { SSEProvider } from "../lib/sse/components/SSEProvider"; -import { getUserConfigOnServerComponent } from "../server/lib/config/getUserConfigOnServerComponent"; -import { RootErrorBoundary } from "./components/RootErrorBoundary"; -import { SSEEventListeners } from "./components/SSEEventListeners"; -import { SyncSessionProcess } from "./components/SyncSessionProcess"; - -import "./globals.css"; - -export const dynamic = "force-dynamic"; -export const fetchCache = "force-no-store"; - -const geistSans = Geist({ - variable: "--font-geist-sans", - subsets: ["latin"], -}); - -const geistMono = Geist_Mono({ - variable: "--font-geist-mono", - subsets: ["latin"], -}); - -export const metadata = { - title: "Claude Code Viewer", - description: "Web Viewer for Claude Code history", -}; - -export default async function RootLayout({ - children, -}: Readonly<{ - children: React.ReactNode; -}>) { - const userConfig = await getUserConfigOnServerComponent(); - const queryClient = new QueryClient(); - - await queryClient.prefetchQuery({ - queryKey: configQuery.queryKey, - queryFn: configQuery.queryFn, - }); - - const initSessionProcesses = await honoClient.api.cc["session-processes"] - .$get({}) - .then((response) => response.json()); - - return ( - - - - - - - - - - {children} - - - - - - - - - - - ); -} diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx deleted file mode 100644 index 79097e7..0000000 --- a/src/app/not-found.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { FileQuestion, Home } from "lucide-react"; -import Link from "next/link"; - -import { Button } from "@/components/ui/button"; -import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, -} from "@/components/ui/card"; - -export default function NotFoundPage() { - return ( -
- - -
- -
- Page Not Found - - The page you are looking for does not exist - -
-
-
- -
- -
-
-
-
- ); -} diff --git a/src/app/page.tsx b/src/app/page.tsx deleted file mode 100644 index 10f2e4e..0000000 --- a/src/app/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { redirect } from "next/navigation"; - -export default function Home() { - redirect("/projects"); -} diff --git a/src/app/projects/[projectId]/components/chatForm/useChatMutations.ts b/src/app/projects/[projectId]/components/chatForm/useChatMutations.ts index e124182..4f4c803 100644 --- a/src/app/projects/[projectId]/components/chatForm/useChatMutations.ts +++ b/src/app/projects/[projectId]/components/chatForm/useChatMutations.ts @@ -1,12 +1,12 @@ import { useMutation } from "@tanstack/react-query"; -import { useRouter } from "next/navigation"; +import { useNavigate } from "@tanstack/react-router"; import { honoClient } from "../../../../../lib/api/client"; export const useCreateSessionProcessMutation = ( projectId: string, onSuccess?: () => void, ) => { - const router = useRouter(); + const navigate = useNavigate(); return useMutation({ mutationFn: async (options: { @@ -36,9 +36,13 @@ export const useCreateSessionProcessMutation = ( }, onSuccess: async (response) => { onSuccess?.(); - router.push( - `/projects/${projectId}/sessions/${response.sessionProcess.sessionId}`, - ); + navigate({ + to: "/projects/$projectId/sessions/$sessionId", + params: { + projectId: projectId, + sessionId: response.sessionProcess.sessionId, + }, + }); }, }); }; diff --git a/src/app/projects/[projectId]/error.tsx b/src/app/projects/[projectId]/error.tsx deleted file mode 100644 index dd51021..0000000 --- a/src/app/projects/[projectId]/error.tsx +++ /dev/null @@ -1,82 +0,0 @@ -"use client"; - -import { Trans } from "@lingui/react"; -import { AlertCircle, ArrowLeft, RefreshCw } from "lucide-react"; -import { useRouter } from "next/navigation"; - -import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; -import { Button } from "@/components/ui/button"; -import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, -} from "@/components/ui/card"; - -export default function ProjectErrorPage({ - error, - reset, -}: { - error: Error & { digest?: string }; - reset: () => void; -}) { - const router = useRouter(); - - return ( -
- - -
- -
- - - - - - -
-
-
- - - - - - - - {error.message} - {error.digest && ( -
- {" "} - {error.digest} -
- )} -
-
- -
- - -
-
-
-
- ); -} diff --git a/src/app/projects/[projectId]/latest/page.tsx b/src/app/projects/[projectId]/latest/page.tsx deleted file mode 100644 index b9c44d2..0000000 --- a/src/app/projects/[projectId]/latest/page.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { QueryClient } from "@tanstack/react-query"; -import { redirect } from "next/navigation"; -import { latestSessionQuery } from "../../../../lib/api/queries"; -import { initializeI18n } from "../../../../lib/i18n/initializeI18n"; - -interface LatestSessionPageProps { - params: Promise<{ projectId: string }>; -} - -export default async function LatestSessionPage({ - params, -}: LatestSessionPageProps) { - await initializeI18n(); - - const { projectId } = await params; - - const queryClient = new QueryClient(); - - const { latestSession } = await queryClient.fetchQuery( - latestSessionQuery(projectId), - ); - - if (!latestSession) { - redirect(`/projects`); - } - - redirect(`/projects/${projectId}/sessions/${latestSession.id}`); -} diff --git a/src/app/projects/[projectId]/not-found.tsx b/src/app/projects/[projectId]/not-found.tsx deleted file mode 100644 index 6d675b2..0000000 --- a/src/app/projects/[projectId]/not-found.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import { Trans } from "@lingui/react"; -import { FolderSearch, Home } from "lucide-react"; -import Link from "next/link"; - -import { Button } from "@/components/ui/button"; -import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, -} from "@/components/ui/card"; -import { initializeI18n } from "../../../lib/i18n/initializeI18n"; - -export default async function ProjectNotFoundPage() { - await initializeI18n(); - - return ( -
- - -
- -
- - - - - - -
-
-
- -
- -
-
-
-
- ); -} diff --git a/src/app/projects/[projectId]/sessions/[sessionId]/components/SessionPageContent.tsx b/src/app/projects/[projectId]/sessions/[sessionId]/components/SessionPageContent.tsx index c5c6cd0..3a7e180 100644 --- a/src/app/projects/[projectId]/sessions/[sessionId]/components/SessionPageContent.tsx +++ b/src/app/projects/[projectId]/sessions/[sessionId]/components/SessionPageContent.tsx @@ -1,5 +1,3 @@ -"use client"; - import { Trans } from "@lingui/react"; import { useMutation } from "@tanstack/react-query"; import { @@ -96,7 +94,7 @@ export const SessionPageContent: FC<{ ]); return ( - <> +
- +
); }; diff --git a/src/app/projects/[projectId]/sessions/[sessionId]/components/conversationList/AssistantConversationContent.tsx b/src/app/projects/[projectId]/sessions/[sessionId]/components/conversationList/AssistantConversationContent.tsx index dd9f0c7..cb8bbd6 100644 --- a/src/app/projects/[projectId]/sessions/[sessionId]/components/conversationList/AssistantConversationContent.tsx +++ b/src/app/projects/[projectId]/sessions/[sessionId]/components/conversationList/AssistantConversationContent.tsx @@ -1,9 +1,5 @@ -"use client"; - import { Trans } from "@lingui/react"; import { ChevronDown, Eye, Lightbulb, Wrench } from "lucide-react"; -import Image from "next/image"; -import { useTheme } from "next-themes"; import type { FC } from "react"; import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; import { @@ -42,7 +38,7 @@ export const AssistantConversationContent: FC<{ getSidechainConversationByPrompt, getSidechainConversations, }) => { - const { resolvedTheme } = useTheme(); + const resolvedTheme = "light" as "light" | "dark"; // TODO: 設定から取り出す const syntaxTheme = resolvedTheme === "dark" ? oneDark : oneLight; if (content.type === "text") { return ( @@ -195,7 +191,7 @@ export const AssistantConversationContent: FC<{ toolResult.content.map((item) => { if (item.type === "image") { return ( - Tool Result
- User uploaded content = ({ diff --git a/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SchedulerTab.tsx b/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SchedulerTab.tsx index d66bcfd..9015321 100644 --- a/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SchedulerTab.tsx +++ b/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SchedulerTab.tsx @@ -1,5 +1,3 @@ -"use client"; - import { Trans, useLingui } from "@lingui/react"; import { EditIcon, PlusIcon, RefreshCwIcon, TrashIcon } from "lucide-react"; import { type FC, useState } from "react"; diff --git a/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionSidebar.tsx b/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionSidebar.tsx index 2bf5eb2..29f1cf1 100644 --- a/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionSidebar.tsx +++ b/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionSidebar.tsx @@ -1,13 +1,11 @@ -"use client"; - import { Trans } from "@lingui/react"; +import { Link } from "@tanstack/react-router"; import { ArrowLeftIcon, CalendarClockIcon, MessageSquareIcon, PlugIcon, } from "lucide-react"; -import Link from "next/link"; import { type FC, useMemo } from "react"; import type { SidebarTab } from "@/components/GlobalSidebar"; import { GlobalSidebar } from "@/components/GlobalSidebar"; @@ -103,7 +101,7 @@ export const SessionSidebar: FC<{ diff --git a/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionsTab.tsx b/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionsTab.tsx index f6a389b..d7532e3 100644 --- a/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionsTab.tsx +++ b/src/app/projects/[projectId]/sessions/[sessionId]/components/sessionSidebar/SessionsTab.tsx @@ -1,9 +1,7 @@ -"use client"; - import { Trans } from "@lingui/react"; +import { Link } from "@tanstack/react-router"; import { useAtomValue } from "jotai"; import { MessageSquareIcon, PlusIcon } from "lucide-react"; -import Link from "next/link"; import type { FC } from "react"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; @@ -116,7 +114,8 @@ export const SessionsTab: FC<{ return ( void; -}) { - const router = useRouter(); - const params = useParams<{ projectId: string }>(); - const projectId = params.projectId; - - return ( -
- - -
- -
- Failed to load session - - We encountered an error while loading this conversation session - -
-
-
- - - - Error Details - - {error.message} - {error.digest && ( -
- Error ID: {error.digest} -
- )} -
-
- -
- - -
-
-
-
- ); -} diff --git a/src/app/projects/[projectId]/sessions/[sessionId]/layout.tsx b/src/app/projects/[projectId]/sessions/[sessionId]/layout.tsx deleted file mode 100644 index a54cd69..0000000 --- a/src/app/projects/[projectId]/sessions/[sessionId]/layout.tsx +++ /dev/null @@ -1,15 +0,0 @@ -"use client"; - -import type { FC, ReactNode } from "react"; - -interface SessionLayoutProps { - children: ReactNode; -} - -const SessionLayout: FC = ({ children }) => { - return ( -
{children}
- ); -}; - -export default SessionLayout; diff --git a/src/app/projects/[projectId]/sessions/[sessionId]/not-found.tsx b/src/app/projects/[projectId]/sessions/[sessionId]/not-found.tsx deleted file mode 100644 index 127b242..0000000 --- a/src/app/projects/[projectId]/sessions/[sessionId]/not-found.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { MessageCircleOff } from "lucide-react"; -import Link from "next/link"; - -import { Button } from "@/components/ui/button"; -import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, -} from "@/components/ui/card"; - -export default function SessionNotFoundPage() { - return ( -
- - -
- -
- Session Not Found - - The conversation session you are looking for does not exist or - has been removed - -
-
-
- -
- -
-
-
-
- ); -} diff --git a/src/app/projects/[projectId]/sessions/[sessionId]/page.tsx b/src/app/projects/[projectId]/sessions/[sessionId]/page.tsx deleted file mode 100644 index cd9137f..0000000 --- a/src/app/projects/[projectId]/sessions/[sessionId]/page.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { QueryClient } from "@tanstack/react-query"; -import type { Metadata } from "next"; -import { - projectDetailQuery, - sessionDetailQuery, -} from "../../../../../lib/api/queries"; -import { initializeI18n } from "../../../../../lib/i18n/initializeI18n"; -import { SessionPageContent } from "./components/SessionPageContent"; - -type PageParams = { - projectId: string; - sessionId: string; -}; - -export async function generateMetadata({ - params, -}: { - params: Promise; -}): Promise { - const { projectId, sessionId } = await params; - - const queryClient = new QueryClient(); - - await queryClient.prefetchQuery({ - ...sessionDetailQuery(projectId, sessionId), - }); - - await queryClient.prefetchQuery({ - queryKey: projectDetailQuery(projectId).queryKey, - queryFn: projectDetailQuery(projectId).queryFn, - }); - - return { - title: `Session: ${sessionId.slice(0, 8)}...`, - description: `View conversation session ${projectId}/${sessionId}`, - }; -} - -interface SessionPageProps { - params: Promise; -} - -export default async function SessionPage({ params }: SessionPageProps) { - const { projectId, sessionId } = await params; - await initializeI18n(); - - return ; -} diff --git a/src/app/projects/components/CreateProjectDialog.tsx b/src/app/projects/components/CreateProjectDialog.tsx index f6cf846..2ddee40 100644 --- a/src/app/projects/components/CreateProjectDialog.tsx +++ b/src/app/projects/components/CreateProjectDialog.tsx @@ -1,9 +1,7 @@ -"use client"; - import { Trans } from "@lingui/react"; import { useMutation } from "@tanstack/react-query"; +import { useNavigate } from "@tanstack/react-router"; import { Loader2, Plus } from "lucide-react"; -import { useRouter } from "next/navigation"; import { type FC, useState } from "react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; @@ -22,7 +20,7 @@ import { DirectoryPicker } from "./DirectoryPicker"; export const CreateProjectDialog: FC = () => { const [open, setOpen] = useState(false); const [selectedPath, setSelectedPath] = useState(""); - const router = useRouter(); + const navigate = useNavigate(); const createProjectMutation = useMutation({ mutationFn: async () => { @@ -40,7 +38,13 @@ export const CreateProjectDialog: FC = () => { onSuccess: (result) => { toast.success("Project created successfully"); setOpen(false); - router.push(`/projects/${result.projectId}/sessions/${result.sessionId}`); + navigate({ + to: "/projects/$projectId/sessions/$sessionId", + params: { + projectId: result.projectId, + sessionId: result.sessionId, + }, + }); }, onError: (error) => { diff --git a/src/app/projects/components/DirectoryPicker.tsx b/src/app/projects/components/DirectoryPicker.tsx index 667772d..78f4d90 100644 --- a/src/app/projects/components/DirectoryPicker.tsx +++ b/src/app/projects/components/DirectoryPicker.tsx @@ -1,5 +1,3 @@ -"use client"; - import { Trans } from "@lingui/react"; import { useQuery } from "@tanstack/react-query"; import { ChevronRight, Folder } from "lucide-react"; diff --git a/src/app/projects/components/ProjectList.tsx b/src/app/projects/components/ProjectList.tsx index 1a8c6a8..b4fde09 100644 --- a/src/app/projects/components/ProjectList.tsx +++ b/src/app/projects/components/ProjectList.tsx @@ -1,8 +1,6 @@ -"use client"; - import { Trans } from "@lingui/react"; +import { Link } from "@tanstack/react-router"; import { FolderIcon } from "lucide-react"; -import Link from "next/link"; import type { FC } from "react"; import { Button } from "@/components/ui/button"; import { @@ -74,7 +72,10 @@ export const ProjectList: FC = () => {
); -} +}; diff --git a/src/components/GlobalSidebar.tsx b/src/components/GlobalSidebar.tsx index f316f0b..84f524e 100644 --- a/src/components/GlobalSidebar.tsx +++ b/src/components/GlobalSidebar.tsx @@ -1,5 +1,3 @@ -"use client"; - import { Trans } from "@lingui/react"; import type { LucideIcon } from "lucide-react"; import { InfoIcon, SettingsIcon } from "lucide-react"; diff --git a/src/components/NotificationSettings.tsx b/src/components/NotificationSettings.tsx index 8712c00..98616cb 100644 --- a/src/components/NotificationSettings.tsx +++ b/src/components/NotificationSettings.tsx @@ -1,5 +1,3 @@ -"use client"; - import { Trans } from "@lingui/react"; import { useAtom } from "jotai"; import { type FC, useCallback, useId } from "react"; diff --git a/src/components/PermissionDialog.tsx b/src/components/PermissionDialog.tsx index c8a59c8..23b4384 100644 --- a/src/components/PermissionDialog.tsx +++ b/src/components/PermissionDialog.tsx @@ -1,5 +1,3 @@ -"use client"; - import { ChevronDown, ChevronRight, Copy } from "lucide-react"; import { useState } from "react"; import { Badge } from "@/components/ui/badge"; diff --git a/src/components/SettingsControls.tsx b/src/components/SettingsControls.tsx index e1204c3..df2e27d 100644 --- a/src/components/SettingsControls.tsx +++ b/src/components/SettingsControls.tsx @@ -1,8 +1,5 @@ -"use client"; - import { Trans, useLingui } from "@lingui/react"; import { useQueryClient } from "@tanstack/react-query"; -import { useTheme } from "next-themes"; import { type FC, useId } from "react"; import { useConfig } from "@/app/hooks/useConfig"; import { Checkbox } from "@/components/ui/checkbox"; @@ -35,7 +32,7 @@ export const SettingsControls: FC = ({ const themeId = useId(); const { config, updateConfig } = useConfig(); const queryClient = useQueryClient(); - const { theme, setTheme } = useTheme(); + const theme = "system"; // TODO: 設定から取り出す const { i18n } = useLingui(); const handleHideNoUserMessageChange = async () => { @@ -301,7 +298,12 @@ export const SettingsControls: FC = ({ )} - { + // TODO: 設定を更新する + }} + > diff --git a/src/components/SystemInfoCard.tsx b/src/components/SystemInfoCard.tsx index 621b245..2da9b72 100644 --- a/src/components/SystemInfoCard.tsx +++ b/src/components/SystemInfoCard.tsx @@ -1,5 +1,3 @@ -"use client"; - import { Trans } from "@lingui/react"; import { useSuspenseQuery } from "@tanstack/react-query"; import { CheckCircle2, ChevronDown, ChevronRight, XCircle } from "lucide-react"; diff --git a/src/components/scheduler/CronExpressionBuilder.tsx b/src/components/scheduler/CronExpressionBuilder.tsx index eb76cd0..b1ee90b 100644 --- a/src/components/scheduler/CronExpressionBuilder.tsx +++ b/src/components/scheduler/CronExpressionBuilder.tsx @@ -1,5 +1,3 @@ -"use client"; - import { Trans } from "@lingui/react"; import { useEffect, useState } from "react"; import { Input } from "@/components/ui/input"; diff --git a/src/components/scheduler/SchedulerJobDialog.tsx b/src/components/scheduler/SchedulerJobDialog.tsx index 03d1bd6..4fe4507 100644 --- a/src/components/scheduler/SchedulerJobDialog.tsx +++ b/src/components/scheduler/SchedulerJobDialog.tsx @@ -1,5 +1,3 @@ -"use client"; - import { Trans, useLingui } from "@lingui/react"; import { type FC, useEffect, useState } from "react"; import { InlineCompletion } from "@/app/projects/[projectId]/components/chatForm/InlineCompletion"; diff --git a/src/components/ui/avatar.tsx b/src/components/ui/avatar.tsx index 11c21d9..10f6822 100644 --- a/src/components/ui/avatar.tsx +++ b/src/components/ui/avatar.tsx @@ -1,5 +1,3 @@ -"use client"; - import * as AvatarPrimitive from "@radix-ui/react-avatar"; import type * as React from "react"; diff --git a/src/components/ui/checkbox.tsx b/src/components/ui/checkbox.tsx index 18924e1..d90d805 100644 --- a/src/components/ui/checkbox.tsx +++ b/src/components/ui/checkbox.tsx @@ -1,5 +1,3 @@ -"use client"; - import * as CheckboxPrimitive from "@radix-ui/react-checkbox"; import { CheckIcon } from "lucide-react"; import type * as React from "react"; diff --git a/src/components/ui/collapsible.tsx b/src/components/ui/collapsible.tsx index 90935c6..849e7b6 100644 --- a/src/components/ui/collapsible.tsx +++ b/src/components/ui/collapsible.tsx @@ -1,5 +1,3 @@ -"use client"; - import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"; function Collapsible({ diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx index 7b5ff19..8f8873c 100644 --- a/src/components/ui/dialog.tsx +++ b/src/components/ui/dialog.tsx @@ -1,5 +1,3 @@ -"use client"; - import * as DialogPrimitive from "@radix-ui/react-dialog"; import { XIcon } from "lucide-react"; import type * as React from "react"; diff --git a/src/components/ui/hover-card.tsx b/src/components/ui/hover-card.tsx index 0ef6109..c2758e1 100644 --- a/src/components/ui/hover-card.tsx +++ b/src/components/ui/hover-card.tsx @@ -1,5 +1,3 @@ -"use client"; - import * as HoverCardPrimitive from "@radix-ui/react-hover-card"; import type * as React from "react"; diff --git a/src/components/ui/select.tsx b/src/components/ui/select.tsx index 274e0d9..a98ffb9 100644 --- a/src/components/ui/select.tsx +++ b/src/components/ui/select.tsx @@ -1,5 +1,3 @@ -"use client"; - import * as SelectPrimitive from "@radix-ui/react-select"; import { Check, ChevronDown, ChevronUp } from "lucide-react"; import type * as React from "react"; diff --git a/src/components/ui/sonner.tsx b/src/components/ui/sonner.tsx index f96a98d..403bc73 100644 --- a/src/components/ui/sonner.tsx +++ b/src/components/ui/sonner.tsx @@ -1,10 +1,7 @@ -"use client"; - -import { useTheme } from "next-themes"; import { Toaster as Sonner, type ToasterProps } from "sonner"; const Toaster = ({ ...props }: ToasterProps) => { - const { theme = "system" } = useTheme(); + const theme = "system"; // TODO: 設定から取り出す return ( ( - typeof window === "undefined" - ? // biome-ignore lint/complexity/useLiteralKeys: allow here - // biome-ignore lint/style/noProcessEnv: allow here - `http://localhost:${process.env["PORT"]}/` - : "/", -); +export const honoClient = hc("/"); diff --git a/src/lib/i18n/LinguiClientProvider.tsx b/src/lib/i18n/LinguiClientProvider.tsx deleted file mode 100644 index 9e38c53..0000000 --- a/src/lib/i18n/LinguiClientProvider.tsx +++ /dev/null @@ -1,20 +0,0 @@ -"use client"; - -import { type Messages, setupI18n } from "@lingui/core"; -import { I18nProvider } from "@lingui/react"; -import { type FC, type PropsWithChildren, useState } from "react"; - -export const LinguiClientProvider: FC< - PropsWithChildren<{ - initialLocale: string; - initialMessages: Messages; - }> -> = ({ children, initialLocale, initialMessages }) => { - const [i18n] = useState(() => { - return setupI18n({ - locale: initialLocale, - messages: { [initialLocale]: initialMessages }, - }); - }); - return {children}; -}; diff --git a/src/lib/i18n/LinguiProvider.tsx b/src/lib/i18n/LinguiProvider.tsx new file mode 100644 index 0000000..8455f42 --- /dev/null +++ b/src/lib/i18n/LinguiProvider.tsx @@ -0,0 +1,14 @@ +import { i18n } from "@lingui/core"; +import { I18nProvider } from "@lingui/react"; +import type { FC, PropsWithChildren } from "react"; +import { i18nMessages } from "."; + +for (const { locale, messages } of i18nMessages) { + i18n.load(locale, messages); +} + +i18n.activate("en"); + +export const LinguiClientProvider: FC = ({ children }) => { + return {children}; +}; diff --git a/src/lib/i18n/LinguiServerProvider.tsx b/src/lib/i18n/LinguiServerProvider.tsx deleted file mode 100644 index adf9d64..0000000 --- a/src/lib/i18n/LinguiServerProvider.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { setI18n } from "@lingui/react/server"; -import { getI18nInstance } from "./index"; -import { LinguiClientProvider } from "./LinguiClientProvider"; -import type { SupportedLocale } from "./schema"; - -export async function LinguiServerProvider(props: { - locale: SupportedLocale; - children: React.ReactNode; -}) { - const { children, locale } = props; - - const i18n = getI18nInstance(locale); - setI18n(i18n); - - return ( - - {children} - - ); -} diff --git a/src/lib/i18n/index.ts b/src/lib/i18n/index.ts index b663fbb..78ff732 100644 --- a/src/lib/i18n/index.ts +++ b/src/lib/i18n/index.ts @@ -1,50 +1,20 @@ -import "server-only"; - -import { type I18n, type Messages, setupI18n } from "@lingui/core"; +import type { Messages } from "@lingui/core"; +import { messages as enMessages } from "./locales/en/messages"; +import { messages as jaMessages } from "./locales/ja/messages"; import type { SupportedLocale } from "./schema"; -const locales: SupportedLocale[] = ["ja", "en"]; +export const locales: SupportedLocale[] = ["ja", "en"]; -async function loadCatalog(locale: SupportedLocale): Promise<{ - [k: string]: Messages; -}> { - const { messages } = await import(`./locales/${locale}/messages`); - return { - [locale]: messages, - }; -} -const catalogs = await Promise.all(locales.map(loadCatalog)); - -export const allMessages = catalogs.reduce((acc, oneCatalog) => { - // biome-ignore lint/performance/noAccumulatingSpread: size is small - return { ...acc, ...oneCatalog }; -}, {}); - -type AllI18nInstances = { [K in SupportedLocale]: I18n }; - -export const allI18nInstances = locales.reduce( - (acc: Partial, locale) => { - const messages = allMessages[locale] ?? {}; - const i18n = setupI18n({ - locale, - messages: { [locale]: messages }, - }); - // biome-ignore lint/performance/noAccumulatingSpread: size is small - return { ...acc, [locale]: i18n }; +export const i18nMessages = [ + { + locale: "ja", + messages: jaMessages, }, - {}, -) as AllI18nInstances; - -export const getI18nInstance = (locale: SupportedLocale): I18n => { - if (!allI18nInstances[locale]) { - console.warn(`No i18n instance found for locale "${locale}"`); - } - - const instance = allI18nInstances[locale] ?? allI18nInstances.en; - - if (instance === undefined) { - throw new Error(`No i18n instance found for locale "${locale}"`); - } - - return instance; -}; + { + locale: "en", + messages: enMessages, + }, +] as const satisfies Array<{ + locale: SupportedLocale; + messages: Messages; +}>; diff --git a/src/lib/i18n/initializeI18n.ts b/src/lib/i18n/initializeI18n.ts deleted file mode 100644 index b9b9841..0000000 --- a/src/lib/i18n/initializeI18n.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { setI18n } from "@lingui/react/server"; -import { getUserConfigOnServerComponent } from "../../server/lib/config/getUserConfigOnServerComponent"; -import { getI18nInstance } from "."; - -export const initializeI18n = async () => { - const userConfig = await getUserConfigOnServerComponent(); - const i18n = getI18nInstance(userConfig.locale); - setI18n(i18n); -}; diff --git a/src/lib/sse/SSEContext.ts b/src/lib/sse/SSEContext.ts index 9ee9cd4..7802119 100644 --- a/src/lib/sse/SSEContext.ts +++ b/src/lib/sse/SSEContext.ts @@ -1,5 +1,3 @@ -"use client"; - import { createContext, useContext } from "react"; import type { SSEEvent } from "../../types/sse"; diff --git a/src/lib/sse/components/SSEProvider.tsx b/src/lib/sse/components/SSEProvider.tsx index f20d3e5..f47a724 100644 --- a/src/lib/sse/components/SSEProvider.tsx +++ b/src/lib/sse/components/SSEProvider.tsx @@ -1,5 +1,3 @@ -"use client"; - import type { FC, PropsWithChildren } from "react"; import { ServerEventsProvider } from "./ServerEventsProvider"; diff --git a/src/main.tsx b/src/main.tsx new file mode 100644 index 0000000..31fdac5 --- /dev/null +++ b/src/main.tsx @@ -0,0 +1,32 @@ +import { createRouter, RouterProvider } from "@tanstack/react-router"; +import { StrictMode } from "react"; +import ReactDOM from "react-dom/client"; + +import { routeTree } from "./routeTree.gen"; + +import "./styles.css"; + +const router = createRouter({ + routeTree, + context: {}, + defaultPreload: "intent", + scrollRestoration: true, + defaultStructuralSharing: true, + defaultPreloadStaleTime: 0, +}); + +declare module "@tanstack/react-router" { + interface Register { + router: typeof router; + } +} + +const rootElement = document.getElementById("app"); +if (rootElement && !rootElement.innerHTML) { + const root = ReactDOM.createRoot(rootElement); + root.render( + + + , + ); +} diff --git a/src/routeTree.gen.ts b/src/routeTree.gen.ts new file mode 100644 index 0000000..ed3f647 --- /dev/null +++ b/src/routeTree.gen.ts @@ -0,0 +1,129 @@ +/* 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 { Route as rootRouteImport } from "./routes/__root"; +import { Route as IndexRouteImport } from "./routes/index"; +import { Route as ProjectsProjectIdLatestIndexRouteImport } from "./routes/projects/$projectId/latest/index"; +import { Route as ProjectsProjectIdSessionsSessionIdIndexRouteImport } from "./routes/projects/$projectId/sessions/$sessionId/index"; +import { Route as ProjectsIndexRouteImport } from "./routes/projects/index"; + +const IndexRoute = IndexRouteImport.update({ + id: "/", + path: "/", + getParentRoute: () => rootRouteImport, +} as any); +const ProjectsIndexRoute = ProjectsIndexRouteImport.update({ + id: "/projects/", + path: "/projects/", + getParentRoute: () => rootRouteImport, +} as any); +const ProjectsProjectIdLatestIndexRoute = + ProjectsProjectIdLatestIndexRouteImport.update({ + id: "/projects/$projectId/latest/", + path: "/projects/$projectId/latest/", + getParentRoute: () => rootRouteImport, + } as any); +const ProjectsProjectIdSessionsSessionIdIndexRoute = + ProjectsProjectIdSessionsSessionIdIndexRouteImport.update({ + id: "/projects/$projectId/sessions/$sessionId/", + path: "/projects/$projectId/sessions/$sessionId/", + getParentRoute: () => rootRouteImport, + } as any); + +export interface FileRoutesByFullPath { + "/": typeof IndexRoute; + "/projects": typeof ProjectsIndexRoute; + "/projects/$projectId/latest": typeof ProjectsProjectIdLatestIndexRoute; + "/projects/$projectId/sessions/$sessionId": typeof ProjectsProjectIdSessionsSessionIdIndexRoute; +} +export interface FileRoutesByTo { + "/": typeof IndexRoute; + "/projects": typeof ProjectsIndexRoute; + "/projects/$projectId/latest": typeof ProjectsProjectIdLatestIndexRoute; + "/projects/$projectId/sessions/$sessionId": typeof ProjectsProjectIdSessionsSessionIdIndexRoute; +} +export interface FileRoutesById { + __root__: typeof rootRouteImport; + "/": typeof IndexRoute; + "/projects/": typeof ProjectsIndexRoute; + "/projects/$projectId/latest/": typeof ProjectsProjectIdLatestIndexRoute; + "/projects/$projectId/sessions/$sessionId/": typeof ProjectsProjectIdSessionsSessionIdIndexRoute; +} +export interface FileRouteTypes { + fileRoutesByFullPath: FileRoutesByFullPath; + fullPaths: + | "/" + | "/projects" + | "/projects/$projectId/latest" + | "/projects/$projectId/sessions/$sessionId"; + fileRoutesByTo: FileRoutesByTo; + to: + | "/" + | "/projects" + | "/projects/$projectId/latest" + | "/projects/$projectId/sessions/$sessionId"; + id: + | "__root__" + | "/" + | "/projects/" + | "/projects/$projectId/latest/" + | "/projects/$projectId/sessions/$sessionId/"; + fileRoutesById: FileRoutesById; +} +export interface RootRouteChildren { + IndexRoute: typeof IndexRoute; + ProjectsIndexRoute: typeof ProjectsIndexRoute; + ProjectsProjectIdLatestIndexRoute: typeof ProjectsProjectIdLatestIndexRoute; + ProjectsProjectIdSessionsSessionIdIndexRoute: typeof ProjectsProjectIdSessionsSessionIdIndexRoute; +} + +declare module "@tanstack/react-router" { + interface FileRoutesByPath { + "/": { + id: "/"; + path: "/"; + fullPath: "/"; + preLoaderRoute: typeof IndexRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/projects/": { + id: "/projects/"; + path: "/projects"; + fullPath: "/projects"; + preLoaderRoute: typeof ProjectsIndexRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/projects/$projectId/latest/": { + id: "/projects/$projectId/latest/"; + path: "/projects/$projectId/latest"; + fullPath: "/projects/$projectId/latest"; + preLoaderRoute: typeof ProjectsProjectIdLatestIndexRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/projects/$projectId/sessions/$sessionId/": { + id: "/projects/$projectId/sessions/$sessionId/"; + path: "/projects/$projectId/sessions/$sessionId"; + fullPath: "/projects/$projectId/sessions/$sessionId"; + preLoaderRoute: typeof ProjectsProjectIdSessionsSessionIdIndexRouteImport; + parentRoute: typeof rootRouteImport; + }; + } +} + +const rootRouteChildren: RootRouteChildren = { + IndexRoute: IndexRoute, + ProjectsIndexRoute: ProjectsIndexRoute, + ProjectsProjectIdLatestIndexRoute: ProjectsProjectIdLatestIndexRoute, + ProjectsProjectIdSessionsSessionIdIndexRoute: + ProjectsProjectIdSessionsSessionIdIndexRoute, +}; +export const routeTree = rootRouteImport + ._addFileChildren(rootRouteChildren) + ._addFileTypes(); diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx new file mode 100644 index 0000000..665999f --- /dev/null +++ b/src/routes/__root.tsx @@ -0,0 +1,37 @@ +import { TanStackDevtools } from "@tanstack/react-devtools"; +import { createRootRoute, Outlet } from "@tanstack/react-router"; +import { TanStackRouterDevtoolsPanel } from "@tanstack/react-router-devtools"; +import { RootErrorBoundary } from "../app/components/RootErrorBoundary"; +import { SSEEventListeners } from "../app/components/SSEEventListeners"; +import { Toaster } from "../components/ui/sonner"; +import { QueryClientProviderWrapper } from "../lib/api/QueryClientProviderWrapper"; +import { LinguiClientProvider } from "../lib/i18n/LinguiProvider"; +import { SSEProvider } from "../lib/sse/components/SSEProvider"; + +export const Route = createRootRoute({ + component: () => ( + + + + + + + , + }, + ]} + /> + + + + + + + ), +}); diff --git a/src/routes/index.tsx b/src/routes/index.tsx new file mode 100644 index 0000000..bc61c45 --- /dev/null +++ b/src/routes/index.tsx @@ -0,0 +1,10 @@ +import { createFileRoute, useRouter } from "@tanstack/react-router"; + +export const Route = createFileRoute("/")({ + component: RouteComponent, +}); + +function RouteComponent() { + const router = useRouter(); + router.navigate({ to: "/projects" }); +} diff --git a/src/routes/projects/$projectId/latest/index.tsx b/src/routes/projects/$projectId/latest/index.tsx new file mode 100644 index 0000000..b439853 --- /dev/null +++ b/src/routes/projects/$projectId/latest/index.tsx @@ -0,0 +1,55 @@ +import { + createFileRoute, + useLoaderData, + useRouter, +} from "@tanstack/react-router"; +import { honoClient } from "../../../../lib/api/client"; + +export const Route = createFileRoute("/projects/$projectId/latest/")({ + component: RouteComponent, + loader: async ({ params }) => { + const { projectId } = params; + const response = await honoClient.api.projects[":projectId"][ + "latest-session" + ].$get({ + param: { projectId }, + }); + + if (!response.ok) { + return { + success: false, + message: `Failed to fetch latest session: ${response.statusText}`, + } as const; + } + + return { + success: true, + projectId, + data: await response.json(), + } as const; + }, +}); + +function RouteComponent() { + const router = useRouter(); + const loaderData = useLoaderData({ from: "/projects/$projectId/latest/" }); + + if (!loaderData.success) { + return
{loaderData.message}
; + } + + const latestSession = loaderData.data.latestSession; + if (latestSession === null) { + router.navigate({ to: "/projects" }); + return null; + } + + router.navigate({ + to: "/projects/$projectId/sessions/$sessionId", + params: { + projectId: loaderData.projectId, + sessionId: latestSession.id, + }, + }); + return null; +} diff --git a/src/routes/projects/$projectId/sessions/$sessionId/index.tsx b/src/routes/projects/$projectId/sessions/$sessionId/index.tsx new file mode 100644 index 0000000..a74e048 --- /dev/null +++ b/src/routes/projects/$projectId/sessions/$sessionId/index.tsx @@ -0,0 +1,18 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { SessionPageContent } from "../../../../../app/projects/[projectId]/sessions/[sessionId]/components/SessionPageContent"; + +export const Route = createFileRoute( + "/projects/$projectId/sessions/$sessionId/", +)({ + component: RouteComponent, +}); + +function RouteComponent() { + const params = Route.useParams(); + return ( + + ); +} diff --git a/src/routes/projects/index.tsx b/src/routes/projects/index.tsx new file mode 100644 index 0000000..fd63d34 --- /dev/null +++ b/src/routes/projects/index.tsx @@ -0,0 +1,10 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { ProjectsPage } from "../../app/projects/page"; + +export const Route = createFileRoute("/projects/")({ + component: RouteComponent, +}); + +function RouteComponent() { + return ; +} diff --git a/src/server/hono/app.ts b/src/server/hono/app.ts index 4d77a14..41048c3 100644 --- a/src/server/hono/app.ts +++ b/src/server/hono/app.ts @@ -7,6 +7,6 @@ export type HonoContext = { }; }; -export const honoApp = new Hono().basePath("/api"); +export const honoApp = new Hono(); export type HonoAppType = typeof honoApp; diff --git a/src/server/hono/route.ts b/src/server/hono/route.ts index b7b3229..1970f3e 100644 --- a/src/server/hono/route.ts +++ b/src/server/hono/route.ts @@ -91,13 +91,13 @@ export const routes = (app: HonoAppType) => }) // routes - .get("/config", async (c) => { + .get("/api/config", async (c) => { return c.json({ config: c.get("userConfig"), }); }) - .put("/config", zValidator("json", userConfigSchema), async (c) => { + .put("/api/config", zValidator("json", userConfigSchema), async (c) => { const { ...config } = c.req.valid("json"); setCookie(c, "ccv-config", JSON.stringify(config)); @@ -107,7 +107,7 @@ export const routes = (app: HonoAppType) => }); }) - .get("/version", async (c) => { + .get("/api/version", async (c) => { return c.json({ version: packageJson.version, }); @@ -117,7 +117,7 @@ export const routes = (app: HonoAppType) => * ProjectController Routes */ - .get("/projects", async (c) => { + .get("/api/projects", async (c) => { const response = await effectToResponse( c, projectController.getProjects(), @@ -126,7 +126,7 @@ export const routes = (app: HonoAppType) => }) .get( - "/projects/:projectId", + "/api/projects/:projectId", zValidator("query", z.object({ cursor: z.string().optional() })), async (c) => { const response = await effectToResponse( @@ -143,7 +143,7 @@ export const routes = (app: HonoAppType) => ) .post( - "/projects", + "/api/projects", zValidator( "json", z.object({ @@ -163,7 +163,7 @@ export const routes = (app: HonoAppType) => }, ) - .get("/projects/:projectId/latest-session", async (c) => { + .get("/api/projects/:projectId/latest-session", async (c) => { const response = await effectToResponse( c, projectController @@ -179,7 +179,7 @@ export const routes = (app: HonoAppType) => * SessionController Routes */ - .get("/projects/:projectId/sessions/:sessionId", async (c) => { + .get("/api/projects/:projectId/sessions/:sessionId", async (c) => { const response = await effectToResponse( c, sessionController @@ -193,7 +193,7 @@ export const routes = (app: HonoAppType) => * GitController Routes */ - .get("/projects/:projectId/git/branches", async (c) => { + .get("/api/projects/:projectId/git/branches", async (c) => { const response = await effectToResponse( c, gitController @@ -205,7 +205,7 @@ export const routes = (app: HonoAppType) => return response; }) - .get("/projects/:projectId/git/commits", async (c) => { + .get("/api/projects/:projectId/git/commits", async (c) => { const response = await effectToResponse( c, gitController @@ -218,7 +218,7 @@ export const routes = (app: HonoAppType) => }) .post( - "/projects/:projectId/git/diff", + "/api/projects/:projectId/git/diff", zValidator( "json", z.object({ @@ -241,7 +241,7 @@ export const routes = (app: HonoAppType) => ) .post( - "/projects/:projectId/git/commit", + "/api/projects/:projectId/git/commit", zValidator("json", CommitRequestSchema), async (c) => { const response = await effectToResponse( @@ -258,7 +258,7 @@ export const routes = (app: HonoAppType) => ) .post( - "/projects/:projectId/git/push", + "/api/projects/:projectId/git/push", zValidator("json", PushRequestSchema), async (c) => { const response = await effectToResponse( @@ -275,7 +275,7 @@ export const routes = (app: HonoAppType) => ) .post( - "/projects/:projectId/git/commit-and-push", + "/api/projects/:projectId/git/commit-and-push", zValidator("json", CommitRequestSchema), async (c) => { const response = await effectToResponse( @@ -295,7 +295,7 @@ export const routes = (app: HonoAppType) => * ClaudeCodeController Routes */ - .get("/projects/:projectId/claude-commands", async (c) => { + .get("/api/projects/:projectId/claude-commands", async (c) => { const response = await effectToResponse( c, claudeCodeController.getClaudeCommands({ @@ -305,7 +305,7 @@ export const routes = (app: HonoAppType) => return response; }) - .get("/projects/:projectId/mcp/list", async (c) => { + .get("/api/projects/:projectId/mcp/list", async (c) => { const response = await effectToResponse( c, claudeCodeController @@ -317,7 +317,7 @@ export const routes = (app: HonoAppType) => return response; }) - .get("/cc/meta", async (c) => { + .get("/api/cc/meta", async (c) => { const response = await effectToResponse( c, claudeCodeController @@ -327,7 +327,7 @@ export const routes = (app: HonoAppType) => return response; }) - .get("/cc/features", async (c) => { + .get("/api/cc/features", async (c) => { const response = await effectToResponse( c, claudeCodeController @@ -341,7 +341,7 @@ export const routes = (app: HonoAppType) => * ClaudeCodeSessionProcessController Routes */ - .get("/cc/session-processes", async (c) => { + .get("/api/cc/session-processes", async (c) => { const response = await effectToResponse( c, claudeCodeSessionProcessController.getSessionProcesses(), @@ -351,7 +351,7 @@ export const routes = (app: HonoAppType) => // new or resume .post( - "/cc/session-processes", + "/api/cc/session-processes", zValidator( "json", z.object({ @@ -373,7 +373,7 @@ export const routes = (app: HonoAppType) => // continue .post( - "/cc/session-processes/:sessionProcessId/continue", + "/api/cc/session-processes/:sessionProcessId/continue", zValidator( "json", z.object({ @@ -397,7 +397,7 @@ export const routes = (app: HonoAppType) => ) .post( - "/cc/session-processes/:sessionProcessId/abort", + "/api/cc/session-processes/:sessionProcessId/abort", zValidator("json", z.object({ projectId: z.string() })), async (c) => { const { sessionProcessId } = c.req.param(); @@ -413,7 +413,7 @@ export const routes = (app: HonoAppType) => */ .post( - "/cc/permission-response", + "/api/cc/permission-response", zValidator( "json", z.object({ @@ -436,7 +436,7 @@ export const routes = (app: HonoAppType) => * SSEController Routes */ - .get("/sse", async (c) => { + .get("/api/sse", async (c) => { return streamSSE( c, async (rawStream) => { @@ -456,7 +456,7 @@ export const routes = (app: HonoAppType) => * SchedulerController Routes */ - .get("/scheduler/jobs", async (c) => { + .get("/api/scheduler/jobs", async (c) => { const response = await effectToResponse( c, schedulerController.getJobs().pipe(Effect.provide(runtime)), @@ -465,7 +465,7 @@ export const routes = (app: HonoAppType) => }) .post( - "/scheduler/jobs", + "/api/scheduler/jobs", zValidator("json", newSchedulerJobSchema), async (c) => { const response = await effectToResponse( @@ -481,7 +481,7 @@ export const routes = (app: HonoAppType) => ) .patch( - "/scheduler/jobs/:id", + "/api/scheduler/jobs/:id", zValidator("json", updateSchedulerJobSchema), async (c) => { const response = await effectToResponse( @@ -497,7 +497,7 @@ export const routes = (app: HonoAppType) => }, ) - .delete("/scheduler/jobs/:id", async (c) => { + .delete("/api/scheduler/jobs/:id", async (c) => { const response = await effectToResponse( c, schedulerController @@ -514,12 +514,12 @@ export const routes = (app: HonoAppType) => */ .get( - "/fs/file-completion", + "/api/fs/file-completion", zValidator( "query", z.object({ projectId: z.string(), - basePath: z.string().optional().default("/"), + basePath: z.string().optional().default("/api/"), }), ), async (c) => { @@ -535,7 +535,7 @@ export const routes = (app: HonoAppType) => ) .get( - "/fs/directory-browser", + "/api/fs/directory-browser", zValidator( "query", z.object({ diff --git a/src/server/lib/config/getUserConfigOnServerComponent.ts b/src/server/lib/config/getUserConfigOnServerComponent.ts deleted file mode 100644 index 8ab3555..0000000 --- a/src/server/lib/config/getUserConfigOnServerComponent.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { cookies } from "next/headers"; -import { parseUserConfig } from "./parseUserConfig"; - -export const getUserConfigOnServerComponent = async () => { - const cookie = await cookies(); - const userConfigJson = cookie.get("ccv-config")?.value; - return parseUserConfig(userConfigJson); -}; diff --git a/src/server/main.ts b/src/server/main.ts new file mode 100644 index 0000000..423a95b --- /dev/null +++ b/src/server/main.ts @@ -0,0 +1,117 @@ +import { readFile } from "node:fs/promises"; +import { resolve } from "node:path"; +import { NodeContext } from "@effect/platform-node"; +import { serve } from "@hono/node-server"; +import { serveStatic } from "@hono/node-server/serve-static"; +import { Effect } from "effect"; +import { ClaudeCodeController } from "./core/claude-code/presentation/ClaudeCodeController"; +import { ClaudeCodePermissionController } from "./core/claude-code/presentation/ClaudeCodePermissionController"; +import { ClaudeCodeSessionProcessController } from "./core/claude-code/presentation/ClaudeCodeSessionProcessController"; +import { ClaudeCodeLifeCycleService } from "./core/claude-code/services/ClaudeCodeLifeCycleService"; +import { ClaudeCodePermissionService } from "./core/claude-code/services/ClaudeCodePermissionService"; +import { ClaudeCodeService } from "./core/claude-code/services/ClaudeCodeService"; +import { ClaudeCodeSessionProcessService } from "./core/claude-code/services/ClaudeCodeSessionProcessService"; +import { SSEController } from "./core/events/presentation/SSEController"; +import { FileWatcherService } from "./core/events/services/fileWatcher"; +import { FileSystemController } from "./core/file-system/presentation/FileSystemController"; +import { GitController } from "./core/git/presentation/GitController"; +import { GitService } from "./core/git/services/GitService"; +import { ProjectRepository } from "./core/project/infrastructure/ProjectRepository"; +import { ProjectController } from "./core/project/presentation/ProjectController"; +import { ProjectMetaService } from "./core/project/services/ProjectMetaService"; +import { SchedulerConfigBaseDir } from "./core/scheduler/config"; +import { SchedulerService } from "./core/scheduler/domain/Scheduler"; +import { SchedulerController } from "./core/scheduler/presentation/SchedulerController"; +import { SessionRepository } from "./core/session/infrastructure/SessionRepository"; +import { VirtualConversationDatabase } from "./core/session/infrastructure/VirtualConversationDatabase"; +import { SessionController } from "./core/session/presentation/SessionController"; +import { SessionMetaService } from "./core/session/services/SessionMetaService"; +import { honoApp } from "./hono/app"; +import { InitializeService } from "./hono/initialize"; +import { routes } from "./hono/route"; +import { platformLayer } from "./lib/effect/layers"; + +// biome-ignore lint/style/noProcessEnv: allow only here +const isDevelopment = process.env.NODE_ENV === "development"; + +if (!isDevelopment) { + const staticPath = resolve(import.meta.dirname, "static"); + console.log("Serving static files from ", staticPath); + + honoApp.use( + "/assets/*", + serveStatic({ + root: staticPath, + }), + ); + + honoApp.use("*", async (c, next) => { + if (c.req.path.startsWith("/api")) { + return next(); + } + + const html = await readFile(resolve(staticPath, "index.html"), "utf-8"); + return c.html(html); + }); +} + +const program = routes(honoApp) + // 依存の浅い順にコンテナに pipe する必要がある + .pipe( + /** Presentation */ + Effect.provide(ProjectController.Live), + Effect.provide(SessionController.Live), + Effect.provide(GitController.Live), + Effect.provide(ClaudeCodeController.Live), + Effect.provide(ClaudeCodeSessionProcessController.Live), + Effect.provide(ClaudeCodePermissionController.Live), + Effect.provide(FileSystemController.Live), + Effect.provide(SSEController.Live), + Effect.provide(SchedulerController.Live), + ) + .pipe( + /** Application */ + Effect.provide(InitializeService.Live), + Effect.provide(FileWatcherService.Live), + ) + .pipe( + /** Domain */ + Effect.provide(ClaudeCodeLifeCycleService.Live), + Effect.provide(ClaudeCodePermissionService.Live), + Effect.provide(ClaudeCodeSessionProcessService.Live), + Effect.provide(ClaudeCodeService.Live), + Effect.provide(GitService.Live), + Effect.provide(SchedulerService.Live), + Effect.provide(SchedulerConfigBaseDir.Live), + ) + .pipe( + /** Infrastructure */ + Effect.provide(ProjectRepository.Live), + Effect.provide(SessionRepository.Live), + Effect.provide(ProjectMetaService.Live), + Effect.provide(SessionMetaService.Live), + Effect.provide(VirtualConversationDatabase.Live), + ) + .pipe( + /** Platform */ + Effect.provide(platformLayer), + Effect.provide(NodeContext.layer), + ); + +await Effect.runPromise(program); + +const port = isDevelopment + ? // biome-ignore lint/style/noProcessEnv: allow only here + (process.env.DEV_BE_PORT ?? "3401") + : // biome-ignore lint/style/noProcessEnv: allow only here + (process.env.PORT ?? "3000"); + +serve( + { + fetch: honoApp.fetch, + port: parseInt(port, 10), + }, + (info) => { + console.log(`Server is running on http://localhost:${info.port}`); + }, +); diff --git a/src/app/globals.css b/src/styles.css similarity index 100% rename from src/app/globals.css rename to src/styles.css diff --git a/tsconfig.json b/tsconfig.json index eac6513..e006aae 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,31 +9,17 @@ "module": "esnext", "moduleResolution": "bundler", "resolveJsonModule": true, - "isolatedModules": true, - "jsx": "preserve", - // build optimization - "incremental": true, - // plugins - "plugins": [ - { - "name": "next" - } - ], + "jsx": "react-jsx", // paths alias "paths": { "@/*": ["./src/*"] }, // typecheck - "types": ["node", "vitest/globals"], + "types": ["node", "vitest/globals", "vite/client"], "exactOptionalPropertyTypes": false, + "noPropertyAccessFromIndexSignature": false, "allowJs": true }, - "include": [ - "**/*.ts", - "**/*.tsx", - ".next/types/**/*.ts", - "next-env.d.ts", - "./.next/types/**/*.ts" - ], + "include": ["src"], "exclude": ["node_modules"] } diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..1e774d8 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,35 @@ +import { fileURLToPath, URL } from "node:url"; +import { lingui } from "@lingui/vite-plugin"; +import tailwindcss from "@tailwindcss/vite"; +import { tanstackRouter } from "@tanstack/router-plugin/vite"; +import viteReact from "@vitejs/plugin-react-swc"; +import dotenv from "dotenv"; +import { defineConfig } from "vite"; + +dotenv.config({ path: "../../.env.local" }); + +export default defineConfig({ + plugins: [ + tanstackRouter({ + target: "react", + autoCodeSplitting: true, + }), + viteReact(), + lingui(), + tailwindcss(), + ], + resolve: { + alias: { + "@": fileURLToPath(new URL("./src", import.meta.url)), + }, + }, + build: { + outDir: "dist/static", + }, + server: { + port: parseInt(process.env.DEV_FE_PORT ?? "3400", 10), + proxy: { + "/api": `http://localhost:${process.env.DEV_BE_PORT ?? "3401"}`, + }, + }, +});