diff --git a/.gitignore b/.gitignore index 398968c..30b87da 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,8 @@ docker-volumes/ .temp/ tmp/ .local-bin/ + +# OpenCode / Sisyphus +.opencode/ +.sisyphus/ +AGENTS.md diff --git a/apps/api/tests/test_routers/test_tool_definitions.py b/apps/api/tests/test_routers/test_tool_definitions.py index 9d1a622..0063eeb 100644 --- a/apps/api/tests/test_routers/test_tool_definitions.py +++ b/apps/api/tests/test_routers/test_tool_definitions.py @@ -6,7 +6,11 @@ from httpx import AsyncClient async def test_tool_definition_crud(auth_client: AsyncClient) -> None: resp = await auth_client.post( "/api/v1/tool-definitions", - json={"key": "runfusion", "name": "RunFusion", "image": "runfusion:latest"}, + json={ + "key": "opencode", + "name": "OpenCode", + "image": "ghcr.io/opencode-ai/opencode:latest", + }, ) assert resp.status_code == 201 td_id = resp.json()["id"] @@ -18,9 +22,9 @@ async def test_tool_definition_crud(auth_client: AsyncClient) -> None: resp = await auth_client.get(f"/api/v1/tool-definitions/{td_id}") assert resp.status_code == 200 - resp = await auth_client.put(f"/api/v1/tool-definitions/{td_id}", json={"name": "RunFusionV2"}) + resp = await auth_client.put(f"/api/v1/tool-definitions/{td_id}", json={"name": "OpenCodeV2"}) assert resp.status_code == 200 - assert resp.json()["name"] == "RunFusionV2" + assert resp.json()["name"] == "OpenCodeV2" resp = await auth_client.delete(f"/api/v1/tool-definitions/{td_id}") assert resp.status_code == 204 diff --git a/apps/api/tests/tools/test_models.py b/apps/api/tests/tools/test_models.py index e7b6fed..2823213 100644 --- a/apps/api/tests/tools/test_models.py +++ b/apps/api/tests/tools/test_models.py @@ -6,7 +6,6 @@ import pytest from pydantic import ValidationError from app.tools.models import ( - ExecutableConfig, HealthCheckConfig, MountConfig, PortConfig, @@ -36,33 +35,32 @@ def _minimal_manifest(**overrides: object) -> ToolManifest: # Valid construction # --------------------------------------------------------------------------- -def test_valid_runfusion_shape() -> None: +def test_valid_opencode_shape() -> None: manifest = ToolManifest( - id="runfusion", - name="RunFusion", - description="Executable Node.js environment.", - image="node:22-slim", + id="opencode", + name="OpenCode", + description="AI-powered terminal-based development environment.", + image="ghcr.io/opencode-ai/opencode:latest", runtime_working_dir="/workspace", - ports=[PortConfig(container_port=8080, name="http", primary=True)], + ports=[PortConfig(container_port=3000, name="http", primary=True)], workspace_mounts=[ MountConfig(source_pattern="{project_repo}", target="/workspace") ], config_mounts=[ MountConfig( - source_pattern="{user_config}/runfusion", target="/home/node/.config" + source_pattern="{user_config}/opencode", target="/root/.config/opencode" ) ], - env={"NODE_ENV": "development"}, + env={"TERM": "xterm-256color", "FORCE_COLOR": "1"}, health_check=HealthCheckConfig( - type="http", path="/", port=8080, start_period_seconds=10 + type="http", path="/", port=3000, start_period_seconds=15 ), - resource_limits=ResourceLimits(cpus=2.0, memory_mb=2048), - executable=ExecutableConfig(node_version="22", package_manager="npm"), + resource_limits=ResourceLimits(cpus=2.0, memory_mb=4096), traefik=TraefikConfig( - enabled=True, subdomain_prefix="runfusion", port=8080 + enabled=True, subdomain_prefix="opencode", port=3000 ), ) - assert manifest.id == "runfusion" + assert manifest.id == "opencode" assert manifest.ports[0].primary is True assert manifest.traefik is not None assert manifest.traefik.enabled is True @@ -102,13 +100,13 @@ def test_valid_code_server_shape() -> None: def test_invalid_id_uppercase() -> None: with pytest.raises(ValidationError) as exc_info: - _minimal_manifest(id="RunFusion") + _minimal_manifest(id="OpenCode") assert "id" in str(exc_info.value) def test_invalid_id_spaces() -> None: with pytest.raises(ValidationError) as exc_info: - _minimal_manifest(id="run fusion") + _minimal_manifest(id="open code") assert "id" in str(exc_info.value) diff --git a/apps/api/tests/tools/test_router.py b/apps/api/tests/tools/test_router.py index c46f912..39498ac 100644 --- a/apps/api/tests/tools/test_router.py +++ b/apps/api/tests/tools/test_router.py @@ -27,7 +27,7 @@ def test_list_tools_includes_builtins() -> None: assert response.status_code == 200 data = response.json() ids = {item["id"] for item in data} - assert "runfusion" in ids + assert "opencode" in ids assert "code-server" in ids @@ -36,12 +36,12 @@ def test_list_tools_includes_builtins() -> None: # --------------------------------------------------------------------------- -def test_get_tool_runfusion() -> None: - response = client.get("/api/v1/tools/runfusion") +def test_get_tool_opencode() -> None: + response = client.get("/api/v1/tools/opencode") assert response.status_code == 200 data = response.json() - assert data["id"] == "runfusion" - assert data["name"] == "RunFusion" + assert data["id"] == "opencode" + assert data["name"] == "OpenCode" def test_get_tool_not_found() -> None: @@ -71,7 +71,7 @@ def test_create_tool_success() -> None: def test_create_tool_duplicate() -> None: payload = { - "id": "runfusion", + "id": "opencode", "name": "Duplicate", "image": "dup:latest", "ports": [{"container_port": 3000, "primary": True}], diff --git a/apps/web/.env.example b/apps/web/.env.example index d5655aa..d74d16a 100644 --- a/apps/web/.env.example +++ b/apps/web/.env.example @@ -1,3 +1,8 @@ # Frontend runtime configuration VITE_API_URL=http://localhost:8000 VITE_APP_NAME=Headquarter + +# OIDC Authentication (Authentik) +VITE_OIDC_ISSUER=https://authentik.example.com/application/o/headquarter +VITE_OIDC_CLIENT_ID=headquarter-web +VITE_OIDC_REDIRECT_URI=http://localhost:5173/callback diff --git a/apps/web/package.json b/apps/web/package.json index a4d515b..9295ba0 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -4,7 +4,9 @@ "private": true, "type": "module", "pnpm": { - "onlyBuiltDependencies": ["esbuild"] + "onlyBuiltDependencies": [ + "esbuild" + ] }, "scripts": { "dev": "vite", @@ -14,22 +16,32 @@ "typecheck": "tsc -b --noEmit" }, "dependencies": { + "@headlessui/react": "^2.2.10", + "@heroicons/react": "^2.2.0", + "@tanstack/react-query": "^5.100.10", + "clsx": "^2.1.1", "react": "^19.0.0", - "react-dom": "^19.0.0" + "react-dom": "^19.0.0", + "react-router-dom": "^7.15.0", + "tailwind-merge": "^3.6.0", + "zustand": "^5.0.13" }, "devDependencies": { + "@eslint/js": "^9.24.0", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.3.0", + "@types/node": "^22.0.0", "@types/react": "^19.0.0", "@types/react-dom": "^19.0.0", "@vitejs/plugin-react": "^4.4.0", - "@eslint/js": "^9.24.0", + "autoprefixer": "^10.5.0", "eslint": "^9.24.0", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.19", "globals": "^16.0.0", "jsdom": "^26.0.0", - "@types/node": "^22.0.0", + "postcss": "^8.5.14", + "tailwindcss": "^4.3.0", "typescript": "~5.7.0", "typescript-eslint": "^8.29.0", "vite": "^6.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 707e929..ed953a6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,12 +12,33 @@ importers: apps/web: dependencies: + '@headlessui/react': + specifier: ^2.2.10 + version: 2.2.10(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@heroicons/react': + specifier: ^2.2.0 + version: 2.2.0(react@19.2.6) + '@tanstack/react-query': + specifier: ^5.100.10 + version: 5.100.10(react@19.2.6) + clsx: + specifier: ^2.1.1 + version: 2.1.1 react: specifier: ^19.0.0 version: 19.2.6 react-dom: specifier: ^19.0.0 version: 19.2.6(react@19.2.6) + react-router-dom: + specifier: ^7.15.0 + version: 7.15.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + tailwind-merge: + specifier: ^3.6.0 + version: 3.6.0 + zustand: + specifier: ^5.0.13 + version: 5.0.13(@types/react@19.2.14)(react@19.2.6)(use-sync-external-store@1.6.0(react@19.2.6)) devDependencies: '@eslint/js': specifier: ^9.24.0 @@ -40,6 +61,9 @@ importers: '@vitejs/plugin-react': specifier: ^4.4.0 version: 4.7.0(vite@6.4.2(@types/node@22.19.19)) + autoprefixer: + specifier: ^10.5.0 + version: 10.5.0(postcss@8.5.14) eslint: specifier: ^9.24.0 version: 9.39.4 @@ -55,6 +79,12 @@ importers: jsdom: specifier: ^26.0.0 version: 26.1.0 + postcss: + specifier: ^8.5.14 + version: 8.5.14 + tailwindcss: + specifier: ^4.3.0 + version: 4.3.0 typescript: specifier: ~5.7.0 version: 5.7.3 @@ -385,6 +415,39 @@ packages: resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@floating-ui/core@1.7.5': + resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} + + '@floating-ui/dom@1.7.6': + resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==} + + '@floating-ui/react-dom@2.1.8': + resolution: {integrity: sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/react@0.26.28': + resolution: {integrity: sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.11': + resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} + + '@headlessui/react@2.2.10': + resolution: {integrity: sha512-5pVLNK9wlpxTUTy9GpgbX/SdcRh+HBnPktjM2wbiLTH4p+2EPHBO1aoSryUCuKUIItdDWO9ITlhUL8UnUN/oIA==} + engines: {node: '>=10'} + peerDependencies: + react: ^18 || ^19 || ^19.0.0-rc + react-dom: ^18 || ^19 || ^19.0.0-rc + + '@heroicons/react@2.2.0': + resolution: {integrity: sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==} + peerDependencies: + react: '>= 16 || ^19.0.0-rc' + '@humanfs/core@0.19.2': resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} engines: {node: '>=18.18.0'} @@ -405,6 +468,15 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} + '@internationalized/date@3.12.1': + resolution: {integrity: sha512-6IedsVWXyq4P9Tj+TxuU8WGWM70hYLl12nbYU8jkikVpa6WXapFazPUcHUMDMoWftIDE2ILDkFFte6W2nFCkRQ==} + + '@internationalized/number@3.6.6': + resolution: {integrity: sha512-iFgmQaXHE0vytNfpLZWOC2mEJCBRzcUxt53Xf/yCXG93lRvqas237i3r7X4RKMwO3txiyZD4mQjKAByFv6UGSQ==} + + '@internationalized/string@3.2.8': + resolution: {integrity: sha512-NdbMQUSfXLYIQol5VyMtinm9pZDciiMfN7RtmSuSB78io1hqwJ0naYfxyW6vgxWBkzWymQa/3uLDlbfmshtCaA==} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -421,6 +493,23 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@react-aria/focus@3.22.0': + resolution: {integrity: sha512-ZfDOVuVhqDsM9mkNji3QUZ/d40JhlVgXrDkrfXylM1035QCrcTHN7m2DpbE95sU2A8EQb4wikvt5jM6K/73BPg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/interactions@3.28.0': + resolution: {integrity: sha512-OXwdU1EWFdMxmr/K1CXNGJzmNlCClByb+PuCaqUyzBymHPCGVhawirLIon/CrIN5psh3AiWpHSh4H0WeJdVpng==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-types/shared@3.34.0': + resolution: {integrity: sha512-gp6xo/s2lX54AlTjOiqwDnxA7UW79BNvI9dB9pr3LZTzRKCd1ZA+ZbgKw/ReIiWuvvVw/8QFJpnqeeFyLocMcQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + '@rolldown/pluginutils@1.0.0-beta.27': resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} @@ -562,6 +651,26 @@ packages: cpu: [x64] os: [win32] + '@swc/helpers@0.5.21': + resolution: {integrity: sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==} + + '@tanstack/query-core@5.100.10': + resolution: {integrity: sha512-8UR0yJR+GiQ40m3lPhUr0xbfAupe6GSQiksSBSa9SM2NjezFyxXCIA69/lz8cSoNKZLrw1/PktIyQBJcVeMi3w==} + + '@tanstack/react-query@5.100.10': + resolution: {integrity: sha512-FLaZf2RCrA/Zgp4aiu5tG3TyasTRO7aZ99skxQpr3Hg/zXOhu6yq5FZCYQ/tRaJtM9ylnoK8tFK7PolXQadv6Q==} + peerDependencies: + react: ^18 || ^19 + + '@tanstack/react-virtual@3.13.24': + resolution: {integrity: sha512-aIJvz5OSkhNIhZIpYivrxrPTKYsjW9Uzy+sP/mx0S3sev2HyvPb7xmjbYvokzEpfgYHy/HjzJ2zFAETuUfgCpg==} + 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/virtual-core@3.14.0': + resolution: {integrity: sha512-JLANqGy/D6k4Ujmh8Tr25lGimuOXNiaVyXaCAZS0W+1390sADdGnyUdSWNIfd49gebtIxGMij4IktRVzrdr12Q==} + '@testing-library/dom@10.4.1': resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} @@ -752,6 +861,10 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} @@ -763,6 +876,13 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + autoprefixer@10.5.0: + resolution: {integrity: sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -810,6 +930,10 @@ packages: resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} engines: {node: '>= 16'} + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -823,6 +947,10 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} + engines: {node: '>=18'} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -990,6 +1118,9 @@ packages: flatted@3.4.2: resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + fraction.js@5.3.4: + resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1202,6 +1333,9 @@ packages: resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + postcss@8.5.14: resolution: {integrity: sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==} engines: {node: ^10 || ^12 || >=14} @@ -1218,6 +1352,12 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + react-aria@3.48.0: + resolution: {integrity: sha512-jQjd4rBEIMqecBaAKYJbVGK6EqIHLa5znVQ7jwFyK5vCyljoj6KhgtiahmcIPsG5vG5vEDLw+ba+bEWn6A2P4w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom@19.2.6: resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==} peerDependencies: @@ -1230,6 +1370,28 @@ packages: resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} engines: {node: '>=0.10.0'} + react-router-dom@7.15.0: + resolution: {integrity: sha512-VcrVg64Fo8nwBvDscajG8gRTLIuTC6N50nb22l2HOOV4PTOHgoGp8mUjy9wLiHYoYTSYI36tUnXZgasSRFZorQ==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: '>=18' + react-dom: '>=18' + + react-router@7.15.0: + resolution: {integrity: sha512-HW9vYwuM8f4yx66Izy8xfrzCM+SBJluoZcCbww9A1TySax11S5Vgw6fi3ZjMONw9J4gQwngL7PzkyIpJJpJ7RQ==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: '>=18' + react-dom: '>=18' + peerDependenciesMeta: + react-dom: + optional: true + + react-stately@3.46.0: + resolution: {integrity: sha512-OdxhWvHgs2L4OJGIs7hnuTr5WjjMM6enhNEAMRqiekhF8+ITvA2LRwNftOZwcogaoCslGYq5S2VQTQwnm0GbCA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react@19.2.6: resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==} engines: {node: '>=0.10.0'} @@ -1269,6 +1431,9 @@ packages: engines: {node: '>=10'} hasBin: true + set-cookie-parser@2.7.2: + resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -1308,6 +1473,15 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + tabbable@6.4.0: + resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} + + tailwind-merge@3.6.0: + resolution: {integrity: sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==} + + tailwindcss@4.3.0: + resolution: {integrity: sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q==} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -1351,6 +1525,9 @@ packages: peerDependencies: typescript: '>=4.8.4' + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -1379,6 +1556,11 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + vite-node@3.2.4: resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} @@ -1513,6 +1695,24 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + zustand@5.0.13: + resolution: {integrity: sha512-efI2tVaVQPqtOh114loML/Z80Y4NP3yc+Ff0fYiZJPauNeWZeIp/bRFD7I9bfmCOYBh/PHxlglQ9+wvlwnPikQ==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=18.0.0' + immer: '>=9.0.6' + react: '>=18.0.0' + use-sync-external-store: '>=1.2.0' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + snapshots: '@adobe/css-tools@4.4.4': {} @@ -1783,6 +1983,45 @@ snapshots: '@eslint/core': 0.17.0 levn: 0.4.1 + '@floating-ui/core@1.7.5': + dependencies: + '@floating-ui/utils': 0.2.11 + + '@floating-ui/dom@1.7.6': + dependencies: + '@floating-ui/core': 1.7.5 + '@floating-ui/utils': 0.2.11 + + '@floating-ui/react-dom@2.1.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@floating-ui/dom': 1.7.6 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + + '@floating-ui/react@0.26.28(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@floating-ui/react-dom': 2.1.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@floating-ui/utils': 0.2.11 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + tabbable: 6.4.0 + + '@floating-ui/utils@0.2.11': {} + + '@headlessui/react@2.2.10(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@floating-ui/react': 0.26.28(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@react-aria/focus': 3.22.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@react-aria/interactions': 3.28.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@tanstack/react-virtual': 3.13.24(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + use-sync-external-store: 1.6.0(react@19.2.6) + + '@heroicons/react@2.2.0(react@19.2.6)': + dependencies: + react: 19.2.6 + '@humanfs/core@0.19.2': dependencies: '@humanfs/types': 0.15.0 @@ -1799,6 +2038,18 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} + '@internationalized/date@3.12.1': + dependencies: + '@swc/helpers': 0.5.21 + + '@internationalized/number@3.6.6': + dependencies: + '@swc/helpers': 0.5.21 + + '@internationalized/string@3.2.8': + dependencies: + '@swc/helpers': 0.5.21 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -1818,6 +2069,25 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@react-aria/focus@3.22.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@swc/helpers': 0.5.21 + react: 19.2.6 + react-aria: 3.48.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react-dom: 19.2.6(react@19.2.6) + + '@react-aria/interactions@3.28.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@react-types/shared': 3.34.0(react@19.2.6) + '@swc/helpers': 0.5.21 + react: 19.2.6 + react-aria: 3.48.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react-dom: 19.2.6(react@19.2.6) + + '@react-types/shared@3.34.0(react@19.2.6)': + dependencies: + react: 19.2.6 + '@rolldown/pluginutils@1.0.0-beta.27': {} '@rollup/rollup-android-arm-eabi@4.60.3': @@ -1895,6 +2165,25 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.60.3': optional: true + '@swc/helpers@0.5.21': + dependencies: + tslib: 2.8.1 + + '@tanstack/query-core@5.100.10': {} + + '@tanstack/react-query@5.100.10(react@19.2.6)': + dependencies: + '@tanstack/query-core': 5.100.10 + react: 19.2.6 + + '@tanstack/react-virtual@3.13.24(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@tanstack/virtual-core': 3.14.0 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + + '@tanstack/virtual-core@3.14.0': {} + '@testing-library/dom@10.4.1': dependencies: '@babel/code-frame': 7.29.0 @@ -2143,6 +2432,10 @@ snapshots: argparse@2.0.1: {} + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + aria-query@5.3.0: dependencies: dequal: 2.0.3 @@ -2151,6 +2444,15 @@ snapshots: assertion-error@2.0.1: {} + autoprefixer@10.5.0(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + caniuse-lite: 1.0.30001792 + fraction.js: 5.3.4 + picocolors: 1.1.1 + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + balanced-match@1.0.2: {} balanced-match@4.0.4: {} @@ -2195,6 +2497,8 @@ snapshots: check-error@2.1.3: {} + clsx@2.1.1: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -2205,6 +2509,8 @@ snapshots: convert-source-map@2.0.0: {} + cookie@1.1.1: {} + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -2388,6 +2694,8 @@ snapshots: flatted@3.4.2: {} + fraction.js@5.3.4: {} + fsevents@2.3.3: optional: true @@ -2579,6 +2887,8 @@ snapshots: picomatch@4.0.4: {} + postcss-value-parser@4.2.0: {} + postcss@8.5.14: dependencies: nanoid: 3.3.12 @@ -2595,6 +2905,20 @@ snapshots: punycode@2.3.1: {} + react-aria@3.48.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + dependencies: + '@internationalized/date': 3.12.1 + '@internationalized/number': 3.6.6 + '@internationalized/string': 3.2.8 + '@react-types/shared': 3.34.0(react@19.2.6) + '@swc/helpers': 0.5.21 + aria-hidden: 1.2.6 + clsx: 2.1.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-stately: 3.46.0(react@19.2.6) + use-sync-external-store: 1.6.0(react@19.2.6) + react-dom@19.2.6(react@19.2.6): dependencies: react: 19.2.6 @@ -2604,6 +2928,30 @@ snapshots: react-refresh@0.17.0: {} + react-router-dom@7.15.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + dependencies: + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-router: 7.15.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + + react-router@7.15.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + dependencies: + cookie: 1.1.1 + react: 19.2.6 + set-cookie-parser: 2.7.2 + optionalDependencies: + react-dom: 19.2.6(react@19.2.6) + + react-stately@3.46.0(react@19.2.6): + dependencies: + '@internationalized/date': 3.12.1 + '@internationalized/number': 3.6.6 + '@internationalized/string': 3.2.8 + '@react-types/shared': 3.34.0(react@19.2.6) + '@swc/helpers': 0.5.21 + react: 19.2.6 + use-sync-external-store: 1.6.0(react@19.2.6) + react@19.2.6: {} redent@3.0.0: @@ -2658,6 +3006,8 @@ snapshots: semver@7.8.0: {} + set-cookie-parser@2.7.2: {} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -2688,6 +3038,12 @@ snapshots: symbol-tree@3.2.4: {} + tabbable@6.4.0: {} + + tailwind-merge@3.6.0: {} + + tailwindcss@4.3.0: {} + tinybench@2.9.0: {} tinyexec@0.3.2: {} @@ -2721,6 +3077,8 @@ snapshots: dependencies: typescript: 5.7.3 + tslib@2.8.1: {} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -2750,6 +3108,10 @@ snapshots: dependencies: punycode: 2.3.1 + use-sync-external-store@1.6.0(react@19.2.6): + dependencies: + react: 19.2.6 + vite-node@3.2.4(@types/node@22.19.19): dependencies: cac: 6.7.14 @@ -2862,3 +3224,9 @@ snapshots: yallist@3.1.1: {} yocto-queue@0.1.0: {} + + zustand@5.0.13(@types/react@19.2.14)(react@19.2.6)(use-sync-external-store@1.6.0(react@19.2.6)): + optionalDependencies: + '@types/react': 19.2.14 + react: 19.2.6 + use-sync-external-store: 1.6.0(react@19.2.6) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index dac1824..d75bbb0 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,5 +1,7 @@ packages: - 'apps/*' - 'packages/*' +allowBuilds: + esbuild: set this to true or false onlyBuiltDependencies: - esbuild