diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 94e857f93a..98b7e9f119 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -6,6 +6,9 @@ * @crazywoola @laipz8200 @Yeuoly +# ESLint suppression file is maintained by autofix.ci pruning. +/eslint-suppressions.json + # CODEOWNERS file /.github/CODEOWNERS @laipz8200 @crazywoola diff --git a/.github/actions/setup-web/action.yml b/.github/actions/setup-web/action.yml index 673155bcf7..085b39ebfb 100644 --- a/.github/actions/setup-web/action.yml +++ b/.github/actions/setup-web/action.yml @@ -4,7 +4,7 @@ runs: using: composite steps: - name: Setup Vite+ - uses: voidzero-dev/setup-vp@20553a7a7429c429a74894104a2835d7fed28a72 # v1.3.0 + uses: voidzero-dev/setup-vp@4f5aa3e38c781f1b01e78fb9255527cee8a6efa6 # v1.8.0 with: node-version-file: .nvmrc cache: true diff --git a/.github/labeler.yml b/.github/labeler.yml index 3b9dc24749..e226bafccc 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -6,5 +6,4 @@ web: - 'package.json' - 'pnpm-lock.yaml' - 'pnpm-workspace.yaml' - - '.npmrc' - '.nvmrc' diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml index 8a1719da3c..96425b47ac 100644 --- a/.github/workflows/autofix.yml +++ b/.github/workflows/autofix.yml @@ -43,7 +43,6 @@ jobs: package.json pnpm-lock.yaml pnpm-workspace.yaml - .npmrc .nvmrc - name: Check api inputs if: github.event_name != 'merge_group' diff --git a/.github/workflows/build-push.yml b/.github/workflows/build-push.yml index 2d8bde8080..915ed6cfe8 100644 --- a/.github/workflows/build-push.yml +++ b/.github/workflows/build-push.yml @@ -74,7 +74,7 @@ jobs: password: ${{ env.DOCKERHUB_TOKEN }} - name: Set up Depot CLI - uses: depot/setup-action@v1 + uses: depot/setup-action@15c09a5f77a0840ad4bce955686522a257853461 # v1.7.1 - name: Extract metadata for Docker id: meta @@ -84,7 +84,7 @@ jobs: - name: Build Docker image id: build - uses: depot/build-push-action@v1 + uses: depot/build-push-action@5f3b3c2e5a00f0093de47f657aeaefcedff27d18 # v1.17.0 with: project: ${{ vars.DEPOT_PROJECT_ID }} context: ${{ matrix.build_context }} @@ -124,10 +124,10 @@ jobs: file: "web/Dockerfile" steps: - name: Set up Docker Buildx - uses: docker/setup-buildx-action@98e3b2c9eab4f4f98a95c0c0a3ea5e5e672fd2a8 # v3.10.0 + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - name: Validate Docker image - uses: docker/build-push-action@5cd29d66b4a8d8e6f4d5dfe2e9329f0b1d446289 # v6.18.0 + uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0 with: push: false context: ${{ matrix.build_context }} diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index b0022b863b..5144510be5 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -44,10 +44,10 @@ jobs: file: "web/Dockerfile" steps: - name: Set up Depot CLI - uses: depot/setup-action@v1 + uses: depot/setup-action@15c09a5f77a0840ad4bce955686522a257853461 # v1.7.1 - name: Build Docker Image - uses: depot/build-push-action@v1 + uses: depot/build-push-action@5f3b3c2e5a00f0093de47f657aeaefcedff27d18 # v1.17.0 with: project: ${{ vars.DEPOT_PROJECT_ID }} push: false @@ -71,10 +71,10 @@ jobs: file: "web/Dockerfile" steps: - name: Set up Docker Buildx - uses: docker/setup-buildx-action@98e3b2c9eab4f4f98a95c0c0a3ea5e5e672fd2a8 # v3.10.0 + uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0 - name: Build Docker Image - uses: docker/build-push-action@5cd29d66b4a8d8e6f4d5dfe2e9329f0b1d446289 # v6.18.0 + uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0 with: push: false context: ${{ matrix.context }} diff --git a/.github/workflows/main-ci.yml b/.github/workflows/main-ci.yml index 278f2ed8d1..8071d6204d 100644 --- a/.github/workflows/main-ci.yml +++ b/.github/workflows/main-ci.yml @@ -69,7 +69,6 @@ jobs: - 'package.json' - 'pnpm-lock.yaml' - 'pnpm-workspace.yaml' - - '.npmrc' - '.nvmrc' - '.github/workflows/web-tests.yml' - '.github/actions/setup-web/**' @@ -83,7 +82,6 @@ jobs: - 'package.json' - 'pnpm-lock.yaml' - 'pnpm-workspace.yaml' - - '.npmrc' - '.nvmrc' - 'docker/docker-compose.middleware.yaml' - 'docker/middleware.env.example' diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index b2d515c6b3..3428516b60 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -81,7 +81,6 @@ jobs: package.json pnpm-lock.yaml pnpm-workspace.yaml - .npmrc .nvmrc .github/workflows/style.yml .github/actions/setup-web/** @@ -108,8 +107,6 @@ jobs: - name: Web tsslint if: steps.changed-files.outputs.any_changed == 'true' working-directory: ./web - env: - NODE_OPTIONS: --max-old-space-size=4096 run: vp run lint:tss - name: Web type check diff --git a/.github/workflows/tool-test-sdks.yaml b/.github/workflows/tool-test-sdks.yaml index 79fddb1853..adaf99f33a 100644 --- a/.github/workflows/tool-test-sdks.yaml +++ b/.github/workflows/tool-test-sdks.yaml @@ -9,7 +9,6 @@ on: - package.json - pnpm-lock.yaml - pnpm-workspace.yaml - - .npmrc concurrency: group: sdk-tests-${{ github.head_ref || github.run_id }} diff --git a/.github/workflows/translate-i18n-claude.yml b/.github/workflows/translate-i18n-claude.yml index 5f48c22c56..5f244f1144 100644 --- a/.github/workflows/translate-i18n-claude.yml +++ b/.github/workflows/translate-i18n-claude.yml @@ -158,7 +158,7 @@ jobs: - name: Run Claude Code for Translation Sync if: steps.context.outputs.CHANGED_FILES != '' - uses: anthropics/claude-code-action@567fe954a4527e81f132d87d1bdbcc94f7737434 # v1.0.107 + uses: anthropics/claude-code-action@ef50f123a3a9be95b60040d042717517407c7256 # v1.0.110 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.npmrc b/.npmrc deleted file mode 100644 index cffe8cdef1..0000000000 --- a/.npmrc +++ /dev/null @@ -1 +0,0 @@ -save-exact=true diff --git a/api/commands/account.py b/api/commands/account.py index 761323a73d..0d99ce7a0f 100644 --- a/api/commands/account.py +++ b/api/commands/account.py @@ -113,8 +113,18 @@ def create_tenant(email: str, language: str | None = None, name: str | None = No # Validates name encoding for non-Latin characters. name = name.strip().encode("utf-8").decode("utf-8") if name else None - # generate random password - new_password = secrets.token_urlsafe(16) + # Generate a random password that satisfies the password policy. + # The iteration limit guards against infinite loops caused by unexpected bugs in valid_password. + for _ in range(100): + new_password = secrets.token_urlsafe(16) + try: + valid_password(new_password) + break + except Exception: + continue + else: + click.echo(click.style("Failed to generate a valid password. Please try again.", fg="red")) + return # register account account = RegisterService.register( diff --git a/api/controllers/console/datasets/hit_testing_base.py b/api/controllers/console/datasets/hit_testing_base.py index 8fb3699849..6335e00bf7 100644 --- a/api/controllers/console/datasets/hit_testing_base.py +++ b/api/controllers/console/datasets/hit_testing_base.py @@ -38,6 +38,48 @@ class HitTestingPayload(BaseModel): class DatasetsHitTestingBase: + @staticmethod + def _normalize_hit_testing_query(query: Any) -> str: + """Return the user-visible query string from legacy and current response shapes.""" + if isinstance(query, str): + return query + + if isinstance(query, dict): + content = query.get("content") + if isinstance(content, str): + return content + + raise ValueError("Invalid hit testing query response") + + @staticmethod + def _normalize_hit_testing_records(records: Any) -> list[dict[str, Any]]: + """Coerce nullable collection fields into lists before response validation.""" + if not isinstance(records, list): + return [] + + normalized_records: list[dict[str, Any]] = [] + for record in records: + if not isinstance(record, dict): + continue + + normalized_record = dict(record) + segment = normalized_record.get("segment") + if isinstance(segment, dict): + normalized_segment = dict(segment) + if normalized_segment.get("keywords") is None: + normalized_segment["keywords"] = [] + normalized_record["segment"] = normalized_segment + + if normalized_record.get("child_chunks") is None: + normalized_record["child_chunks"] = [] + + if normalized_record.get("files") is None: + normalized_record["files"] = [] + + normalized_records.append(normalized_record) + + return normalized_records + @staticmethod def get_and_validate_dataset(dataset_id: str): assert isinstance(current_user, Account) @@ -75,7 +117,12 @@ class DatasetsHitTestingBase: attachment_ids=args.get("attachment_ids"), limit=10, ) - return {"query": response["query"], "records": marshal(response["records"], hit_testing_record_fields)} + return { + "query": DatasetsHitTestingBase._normalize_hit_testing_query(response.get("query")), + "records": DatasetsHitTestingBase._normalize_hit_testing_records( + marshal(response.get("records", []), hit_testing_record_fields) + ), + } except services.errors.index.IndexNotInitializedError: raise DatasetNotInitializedError() except ProviderTokenNotInitError as ex: diff --git a/api/pyproject.toml b/api/pyproject.toml index 4c59f8424c..0c5f9f95b1 100644 --- a/api/pyproject.toml +++ b/api/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "dify-api" -version = "1.13.3" +version = "1.14.0" requires-python = "~=3.12.0" dependencies = [ diff --git a/api/tests/test_containers_integration_tests/services/test_app_dsl_service.py b/api/tests/test_containers_integration_tests/services/test_app_dsl_service.py index 6c15587058..9c21880aab 100644 --- a/api/tests/test_containers_integration_tests/services/test_app_dsl_service.py +++ b/api/tests/test_containers_integration_tests/services/test_app_dsl_service.py @@ -3,21 +3,21 @@ from __future__ import annotations import base64 import json from types import SimpleNamespace +from typing import Any, cast from unittest.mock import MagicMock, patch from uuid import uuid4 import pytest import yaml from faker import Faker -from graphon.enums import BuiltinNodeTypes - from core.trigger.constants import ( TRIGGER_PLUGIN_NODE_TYPE, TRIGGER_SCHEDULE_NODE_TYPE, TRIGGER_WEBHOOK_NODE_TYPE, ) from extensions.ext_redis import redis_client -from models import Account, AppMode +from graphon.enums import BuiltinNodeTypes +from models import Account, App, AppMode from models.model import AppModelConfig, IconType from services import app_dsl_service from services.account_service import AccountService, TenantService @@ -67,6 +67,22 @@ def _pending_yaml_content(version: str = "99.0.0") -> bytes: return (f'version: "{version}"\nkind: app\napp:\n name: Loop Test\n mode: workflow\n').encode() +def _app_stub(**overrides: Any) -> App: + defaults = { + "id": str(uuid4()), + "tenant_id": _DEFAULT_TENANT_ID, + "mode": AppMode.WORKFLOW.value, + "name": "n", + "description": "d", + "icon_type": IconType.EMOJI, + "icon": "i", + "icon_background": "#fff", + "use_icon_as_answer_icon": False, + "app_model_config": None, + } + return cast(App, SimpleNamespace(**(defaults | overrides))) + + class TestAppDslService: """Integration tests for AppDslService using testcontainers.""" @@ -585,7 +601,7 @@ class TestAppDslService: def test_check_dependencies_returns_empty_when_no_redis_data(self, db_session_with_containers): service = AppDslService(db_session_with_containers) - app_model = SimpleNamespace(id=str(uuid4()), tenant_id=_DEFAULT_TENANT_ID) + app_model = _app_stub() result = service.check_dependencies(app_model=app_model) assert result.leaked_dependencies == [] @@ -614,7 +630,7 @@ class TestAppDslService: ) service = AppDslService(db_session_with_containers) - result = service.check_dependencies(app_model=SimpleNamespace(id=app_id, tenant_id=_DEFAULT_TENANT_ID)) + result = service.check_dependencies(app_model=_app_stub(id=app_id)) assert len(result.leaked_dependencies) == 1 def test_check_dependencies_with_real_app(self, db_session_with_containers, mock_external_service_dependencies): @@ -656,9 +672,7 @@ class TestAppDslService: lambda _m: SimpleNamespace(kind="conv"), ) - app = SimpleNamespace( - id=str(uuid4()), - tenant_id=_DEFAULT_TENANT_ID, + app = _app_stub( mode=AppMode.WORKFLOW.value, name="old", description="old-desc", @@ -667,7 +681,6 @@ class TestAppDslService: icon_background="#111111", updated_by=None, updated_at=None, - app_model_config=None, ) service = AppDslService(db_session_with_containers) updated = service._create_or_update_app( @@ -745,15 +758,7 @@ class TestAppDslService: service = AppDslService(db_session_with_containers) with pytest.raises(ValueError, match="Missing workflow data"): service._create_or_update_app( - app=SimpleNamespace( - id=str(uuid4()), - tenant_id=_DEFAULT_TENANT_ID, - mode=AppMode.WORKFLOW.value, - name="n", - description="d", - icon_background="#fff", - app_model_config=None, - ), + app=_app_stub(mode=AppMode.WORKFLOW.value), data={"app": {"mode": AppMode.WORKFLOW.value}}, account=_account_mock(), ) @@ -762,15 +767,7 @@ class TestAppDslService: service = AppDslService(db_session_with_containers) with pytest.raises(ValueError, match="Missing model_config"): service._create_or_update_app( - app=SimpleNamespace( - id=str(uuid4()), - tenant_id=_DEFAULT_TENANT_ID, - mode=AppMode.CHAT.value, - name="n", - description="d", - icon_background="#fff", - app_model_config=None, - ), + app=_app_stub(mode=AppMode.CHAT.value), data={"app": {"mode": AppMode.CHAT.value}}, account=_account_mock(), ) @@ -799,15 +796,7 @@ class TestAppDslService: service = AppDslService(db_session_with_containers) with pytest.raises(ValueError, match="Invalid app mode"): service._create_or_update_app( - app=SimpleNamespace( - id=str(uuid4()), - tenant_id=_DEFAULT_TENANT_ID, - mode=AppMode.RAG_PIPELINE.value, - name="n", - description="d", - icon_background="#fff", - app_model_config=None, - ), + app=_app_stub(mode=AppMode.RAG_PIPELINE.value), data={"app": {"mode": AppMode.RAG_PIPELINE.value}}, account=_account_mock(), ) @@ -828,29 +817,16 @@ class TestAppDslService: lambda *_args, **_kwargs: model_calls.append(True), ) - workflow_app = SimpleNamespace( + workflow_app = _app_stub( mode=AppMode.WORKFLOW.value, - tenant_id=_DEFAULT_TENANT_ID, - name="n", - icon="i", icon_type="emoji", - icon_background="#fff", - description="d", - use_icon_as_answer_icon=False, - app_model_config=None, ) AppDslService.export_dsl(workflow_app) assert workflow_calls == [True] - chat_app = SimpleNamespace( + chat_app = _app_stub( mode=AppMode.CHAT.value, - tenant_id=_DEFAULT_TENANT_ID, - name="n", - icon="i", icon_type="emoji", - icon_background="#fff", - description="d", - use_icon_as_answer_icon=False, app_model_config=SimpleNamespace(to_dict=lambda: {"agent_mode": {"tools": []}}), ) AppDslService.export_dsl(chat_app) @@ -863,16 +839,14 @@ class TestAppDslService: lambda **_kwargs: None, ) - emoji_app = SimpleNamespace( + emoji_app = _app_stub( mode=AppMode.WORKFLOW.value, - tenant_id=_DEFAULT_TENANT_ID, name="Emoji App", icon="🎨", icon_type=IconType.EMOJI, icon_background="#FF5733", description="App with emoji icon", use_icon_as_answer_icon=True, - app_model_config=None, ) yaml_output = AppDslService.export_dsl(emoji_app) data = yaml.safe_load(yaml_output) @@ -880,16 +854,14 @@ class TestAppDslService: assert data["app"]["icon_type"] == "emoji" assert data["app"]["icon_background"] == "#FF5733" - image_app = SimpleNamespace( + image_app = _app_stub( mode=AppMode.WORKFLOW.value, - tenant_id=_DEFAULT_TENANT_ID, name="Image App", icon="https://example.com/icon.png", icon_type=IconType.IMAGE, icon_background="#FFEAD5", description="App with image icon", use_icon_as_answer_icon=False, - app_model_config=None, ) yaml_output = AppDslService.export_dsl(image_app) data = yaml.safe_load(yaml_output) @@ -1106,7 +1078,7 @@ class TestAppDslService: export_data: dict = {} AppDslService._append_workflow_export_data( export_data=export_data, - app_model=SimpleNamespace(tenant_id=_DEFAULT_TENANT_ID), + app_model=_app_stub(), include_secret=False, workflow_id=None, ) @@ -1132,7 +1104,7 @@ class TestAppDslService: with pytest.raises(ValueError, match="Missing draft workflow configuration"): AppDslService._append_workflow_export_data( export_data={}, - app_model=SimpleNamespace(tenant_id=_DEFAULT_TENANT_ID), + app_model=_app_stub(), include_secret=False, workflow_id=None, ) @@ -1160,7 +1132,7 @@ class TestAppDslService: monkeypatch.setattr(app_dsl_service, "jsonable_encoder", lambda x: x) app_model_config = SimpleNamespace(to_dict=lambda: {"agent_mode": {"tools": [{"credential_id": "secret"}]}}) - app_model = SimpleNamespace(tenant_id=_DEFAULT_TENANT_ID, app_model_config=app_model_config) + app_model = _app_stub(app_model_config=app_model_config) export_data: dict = {} AppDslService._append_model_config_export_data(export_data, app_model) @@ -1169,7 +1141,7 @@ class TestAppDslService: def test_append_model_config_export_data_requires_app_config(self): with pytest.raises(ValueError, match="Missing app configuration"): - AppDslService._append_model_config_export_data({}, SimpleNamespace(app_model_config=None)) + AppDslService._append_model_config_export_data({}, _app_stub(app_model_config=None)) # ── Dependency Extraction ───────────────────────────────────────── diff --git a/api/tests/unit_tests/controllers/console/datasets/test_hit_testing_base.py b/api/tests/unit_tests/controllers/console/datasets/test_hit_testing_base.py index e4acd91b76..d29b34beb2 100644 --- a/api/tests/unit_tests/controllers/console/datasets/test_hit_testing_base.py +++ b/api/tests/unit_tests/controllers/console/datasets/test_hit_testing_base.py @@ -134,6 +134,42 @@ class TestPerformHitTesting: assert result["query"] == "hello" assert result["records"] == [] + def test_success_normalizes_legacy_query_and_nullable_list_fields(self, dataset): + response = { + "query": {"content": "hello"}, + "records": [ + { + "segment": {"id": "segment-1", "keywords": None}, + "child_chunks": None, + "files": None, + "score": 0.8, + } + ], + } + + with ( + patch.object( + HitTestingService, + "retrieve", + return_value=response, + ), + patch( + "controllers.console.datasets.hit_testing_base.marshal", + return_value=response["records"], + ), + ): + result = DatasetsHitTestingBase.perform_hit_testing(dataset, {"query": "hello"}) + + assert result["query"] == "hello" + assert result["records"] == [ + { + "segment": {"id": "segment-1", "keywords": []}, + "child_chunks": [], + "files": [], + "score": 0.8, + } + ] + def test_index_not_initialized(self, dataset): with patch.object( HitTestingService, diff --git a/api/tests/unit_tests/controllers/service_api/dataset/test_hit_testing.py b/api/tests/unit_tests/controllers/service_api/dataset/test_hit_testing.py index 95c2f5cf92..9be8e56f56 100644 --- a/api/tests/unit_tests/controllers/service_api/dataset/test_hit_testing.py +++ b/api/tests/unit_tests/controllers/service_api/dataset/test_hit_testing.py @@ -171,6 +171,57 @@ class TestHitTestingApiPost: assert passed_retrieval_model["search_method"] == "semantic_search" assert passed_retrieval_model["top_k"] == 10 + @patch("controllers.service_api.dataset.hit_testing.service_api_ns") + @patch("controllers.console.datasets.hit_testing_base.marshal") + @patch("controllers.console.datasets.hit_testing_base.HitTestingService") + @patch("controllers.console.datasets.hit_testing_base.DatasetService") + @patch("controllers.console.datasets.hit_testing_base.current_user", new_callable=lambda: Mock(spec=Account)) + def test_post_normalizes_legacy_query_and_nullable_list_fields( + self, + mock_current_user, + mock_dataset_svc, + mock_hit_svc, + mock_marshal, + mock_ns, + app, + ): + """Test service API normalizes legacy query shape and nullable list fields.""" + dataset_id = str(uuid.uuid4()) + tenant_id = str(uuid.uuid4()) + + mock_dataset = Mock() + mock_dataset.id = dataset_id + + mock_dataset_svc.get_dataset.return_value = mock_dataset + mock_dataset_svc.check_dataset_permission.return_value = None + + mock_hit_svc.retrieve.return_value = {"query": {"content": "legacy query"}, "records": ["placeholder"]} + mock_hit_svc.hit_testing_args_check.return_value = None + mock_marshal.return_value = [ + { + "segment": {"id": "segment-1", "keywords": None}, + "child_chunks": None, + "files": None, + "score": 0.9, + } + ] + + mock_ns.payload = {"query": "legacy query"} + + with app.test_request_context(): + api = HitTestingApi() + response = HitTestingApi.post.__wrapped__(api, tenant_id, dataset_id) + + assert response["query"] == "legacy query" + assert response["records"] == [ + { + "segment": {"id": "segment-1", "keywords": []}, + "child_chunks": [], + "files": [], + "score": 0.9, + } + ] + @patch("controllers.service_api.dataset.hit_testing.service_api_ns") @patch("controllers.console.datasets.hit_testing_base.DatasetService") @patch("controllers.console.datasets.hit_testing_base.current_user", new_callable=lambda: Mock(spec=Account)) diff --git a/api/tests/unit_tests/core/rag/extractor/test_word_extractor.py b/api/tests/unit_tests/core/rag/extractor/test_word_extractor.py index 0220fb6d4a..b9f2449cfb 100644 --- a/api/tests/unit_tests/core/rag/extractor/test_word_extractor.py +++ b/api/tests/unit_tests/core/rag/extractor/test_word_extractor.py @@ -1,14 +1,12 @@ """Primarily used for testing merged cell scenarios""" -import gc import io import os import tempfile -import warnings from collections import UserDict from pathlib import Path from types import SimpleNamespace -from unittest.mock import AsyncMock, MagicMock +from unittest.mock import MagicMock import pytest from docx import Document @@ -377,23 +375,21 @@ def test_close_is_idempotent(): extractor.temp_file.close.assert_called_once() -def test_close_handles_async_close_mock(): +async def _async_close() -> None: + return None + + +def test_close_closes_awaitable_close_result(): extractor = object.__new__(WordExtractor) extractor._closed = False extractor.temp_file = MagicMock() - extractor.temp_file.close = AsyncMock() + close_result = _async_close() + extractor.temp_file.close = MagicMock(return_value=close_result) - with warnings.catch_warnings(record=True) as caught: - warnings.simplefilter("always") - extractor.close() - gc.collect() + extractor.close() + assert close_result.cr_frame is None extractor.temp_file.close.assert_called_once() - assert not [ - warning - for warning in caught - if issubclass(warning.category, RuntimeWarning) and "AsyncMockMixin._execute_mock_call" in str(warning.message) - ] def test_extract_images_handles_invalid_external_cases(monkeypatch): diff --git a/api/uv.lock b/api/uv.lock index 6b2da24994..fdce6fe309 100644 --- a/api/uv.lock +++ b/api/uv.lock @@ -1376,7 +1376,7 @@ wheels = [ [[package]] name = "dify-api" -version = "1.13.3" +version = "1.14.0" source = { virtual = "." } dependencies = [ { name = "aliyun-log-python-sdk" }, diff --git a/docker/docker-compose-template.yaml b/docker/docker-compose-template.yaml index 888f96332c..87fa01f671 100644 --- a/docker/docker-compose-template.yaml +++ b/docker/docker-compose-template.yaml @@ -21,7 +21,7 @@ services: # API service api: - image: langgenius/dify-api:1.13.3 + image: langgenius/dify-api:1.14.0 restart: always environment: # Use the shared environment variables. @@ -69,7 +69,7 @@ services: # worker service # The Celery worker for processing all queues (dataset, workflow, mail, etc.) worker: - image: langgenius/dify-api:1.13.3 + image: langgenius/dify-api:1.14.0 restart: always environment: # Use the shared environment variables. @@ -115,7 +115,7 @@ services: # worker_beat service # Celery beat for scheduling periodic tasks. worker_beat: - image: langgenius/dify-api:1.13.3 + image: langgenius/dify-api:1.14.0 restart: always environment: # Use the shared environment variables. @@ -152,7 +152,7 @@ services: # Frontend web application. web: - image: langgenius/dify-web:1.13.3 + image: langgenius/dify-web:1.14.0 restart: always environment: CONSOLE_API_URL: ${CONSOLE_API_URL:-} @@ -268,7 +268,7 @@ services: # The DifySandbox sandbox: - image: langgenius/dify-sandbox:0.2.14 + image: langgenius/dify-sandbox:0.2.15 restart: always environment: # The DifySandbox configurations @@ -292,7 +292,7 @@ services: # plugin daemon plugin_daemon: - image: langgenius/dify-plugin-daemon:0.5.3-local + image: langgenius/dify-plugin-daemon:0.6.0-local restart: always environment: # Use the shared environment variables. diff --git a/docker/docker-compose.middleware.yaml b/docker/docker-compose.middleware.yaml index af3d54dfb3..23c26c6695 100644 --- a/docker/docker-compose.middleware.yaml +++ b/docker/docker-compose.middleware.yaml @@ -103,7 +103,7 @@ services: # The DifySandbox sandbox: - image: langgenius/dify-sandbox:0.2.14 + image: langgenius/dify-sandbox:0.2.15 restart: always env_file: - ./middleware.env @@ -129,7 +129,7 @@ services: # plugin daemon plugin_daemon: - image: langgenius/dify-plugin-daemon:0.5.3-local + image: langgenius/dify-plugin-daemon:0.6.0-local restart: always env_file: - ./middleware.env diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index 60ba510f44..a72136049d 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -745,7 +745,7 @@ services: # API service api: - image: langgenius/dify-api:1.13.3 + image: langgenius/dify-api:1.14.0 restart: always environment: # Use the shared environment variables. @@ -793,7 +793,7 @@ services: # worker service # The Celery worker for processing all queues (dataset, workflow, mail, etc.) worker: - image: langgenius/dify-api:1.13.3 + image: langgenius/dify-api:1.14.0 restart: always environment: # Use the shared environment variables. @@ -839,7 +839,7 @@ services: # worker_beat service # Celery beat for scheduling periodic tasks. worker_beat: - image: langgenius/dify-api:1.13.3 + image: langgenius/dify-api:1.14.0 restart: always environment: # Use the shared environment variables. @@ -876,7 +876,7 @@ services: # Frontend web application. web: - image: langgenius/dify-web:1.13.3 + image: langgenius/dify-web:1.14.0 restart: always environment: CONSOLE_API_URL: ${CONSOLE_API_URL:-} @@ -992,7 +992,7 @@ services: # The DifySandbox sandbox: - image: langgenius/dify-sandbox:0.2.14 + image: langgenius/dify-sandbox:0.2.15 restart: always environment: # The DifySandbox configurations @@ -1016,7 +1016,7 @@ services: # plugin daemon plugin_daemon: - image: langgenius/dify-plugin-daemon:0.5.3-local + image: langgenius/dify-plugin-daemon:0.6.0-local restart: always environment: # Use the shared environment variables. diff --git a/eslint-suppressions.json b/eslint-suppressions.json index beb49b7d5f..d8161bc27b 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -385,9 +385,6 @@ } }, "web/app/components/app/configuration/config/agent/agent-tools/index.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 9 } @@ -641,11 +638,6 @@ "count": 2 } }, - "web/app/components/app/overview/app-card.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/app/overview/customize/index.tsx": { "no-restricted-imports": { "count": 1 @@ -2607,14 +2599,6 @@ "count": 1 } }, - "web/app/components/datasets/external-api/external-api-modal/index.tsx": { - "no-restricted-imports": { - "count": 2 - }, - "react/set-state-in-effect": { - "count": 1 - } - }, "web/app/components/datasets/external-knowledge-base/create/ExternalApiSelect.tsx": { "react/set-state-in-effect": { "count": 1 @@ -2625,11 +2609,6 @@ "count": 1 } }, - "web/app/components/datasets/extra-info/statistics.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/datasets/formatted-text/flavours/type.ts": { "ts/no-empty-object-type": { "count": 1 @@ -3299,9 +3278,6 @@ } }, "web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 2 } @@ -3764,11 +3740,6 @@ "count": 1 } }, - "web/app/components/tools/mcp/detail/tool-item.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/tools/mcp/mcp-server-modal.tsx": { "no-restricted-imports": { "count": 1 @@ -3782,11 +3753,6 @@ "count": 1 } }, - "web/app/components/tools/mcp/mcp-service-card.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/tools/mcp/modal.tsx": { "no-restricted-imports": { "count": 1 @@ -3820,21 +3786,6 @@ "count": 4 } }, - "web/app/components/tools/workflow-tool/confirm-modal/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/tools/workflow-tool/index.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, - "web/app/components/tools/workflow-tool/method-selector.tsx": { - "no-restricted-imports": { - "count": 1 - } - }, "web/app/components/workflow-app/components/workflow-children.tsx": { "ts/no-explicit-any": { "count": 3 @@ -4266,9 +4217,6 @@ } }, "web/app/components/workflow/nodes/_base/components/prompt/editor.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 4 } @@ -5736,9 +5684,6 @@ } }, "web/app/signin/one-more-step.tsx": { - "no-restricted-imports": { - "count": 1 - }, "ts/no-explicit-any": { "count": 1 } diff --git a/package.json b/package.json index 42d6961f5f..a563b574f7 100644 --- a/package.json +++ b/package.json @@ -2,11 +2,12 @@ "name": "dify", "type": "module", "private": true, - "packageManager": "pnpm@10.33.2", + "packageManager": "pnpm@11.0.0", "engines": { "node": "^22.22.1" }, "scripts": { + "dev": "concurrently -k -n vinext,proxy \"vp run dify-web#dev:vinext\" \"vp run dify-web#dev:proxy\"", "prepare": "vp config", "type-check": "vp run -r type-check", "lint": "eslint --cache --concurrency=auto", @@ -16,6 +17,7 @@ }, "devDependencies": { "@antfu/eslint-config": "catalog:", + "concurrently": "catalog:", "eslint": "catalog:", "eslint-markdown": "catalog:", "eslint-plugin-markdown-preferences": "catalog:", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c802698100..76e3a023f1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,11 +7,11 @@ settings: catalogs: default: '@amplitude/analytics-browser': - specifier: 2.41.1 - version: 2.41.1 + specifier: 2.42.0 + version: 2.42.0 '@amplitude/plugin-session-replay-browser': - specifier: 1.28.0 - version: 1.28.0 + specifier: 1.28.1 + version: 1.28.1 '@antfu/eslint-config': specifier: 8.2.0 version: 8.2.0 @@ -49,8 +49,8 @@ catalogs: specifier: 2.2.0 version: 2.2.0 '@hono/node-server': - specifier: 1.19.14 - version: 1.19.14 + specifier: 2.0.0 + version: 2.0.0 '@iconify-json/heroicons': specifier: 1.2.3 version: 1.2.3 @@ -58,23 +58,23 @@ catalogs: specifier: 1.2.10 version: 1.2.10 '@lexical/link': - specifier: 0.43.0 - version: 0.43.0 + specifier: 0.44.0 + version: 0.44.0 '@lexical/list': - specifier: 0.43.0 - version: 0.43.0 + specifier: 0.44.0 + version: 0.44.0 '@lexical/react': - specifier: 0.43.0 - version: 0.43.0 + specifier: 0.44.0 + version: 0.44.0 '@lexical/selection': - specifier: 0.43.0 - version: 0.43.0 + specifier: 0.44.0 + version: 0.44.0 '@lexical/text': - specifier: 0.43.0 - version: 0.43.0 + specifier: 0.44.0 + version: 0.44.0 '@lexical/utils': - specifier: 0.43.0 - version: 0.43.0 + specifier: 0.44.0 + version: 0.44.0 '@mdx-js/loader': specifier: 3.1.1 version: 3.1.1 @@ -157,8 +157,8 @@ catalogs: specifier: 4.2.4 version: 4.2.4 '@tanstack/eslint-plugin-query': - specifier: 5.100.5 - version: 5.100.5 + specifier: 5.100.6 + version: 5.100.6 '@tanstack/react-devtools': specifier: 0.10.2 version: 0.10.2 @@ -169,11 +169,11 @@ catalogs: specifier: 0.2.22 version: 0.2.22 '@tanstack/react-query': - specifier: 5.100.5 - version: 5.100.5 + specifier: 5.100.6 + version: 5.100.6 '@tanstack/react-query-devtools': - specifier: 5.100.5 - version: 5.100.5 + specifier: 5.100.6 + version: 5.100.6 '@tanstack/react-virtual': specifier: 3.13.24 version: 3.13.24 @@ -190,14 +190,14 @@ catalogs: specifier: 14.6.1 version: 14.6.1 '@tsslint/cli': - specifier: 3.0.4 - version: 3.0.4 + specifier: 3.1.0 + version: 3.1.0 '@tsslint/compat-eslint': - specifier: 3.0.4 - version: 3.0.4 + specifier: 3.1.0 + version: 3.1.0 '@tsslint/config': - specifier: 3.0.4 - version: 3.0.4 + specifier: 3.1.0 + version: 3.1.0 '@types/js-cookie': specifier: 3.0.6 version: 3.0.6 @@ -223,14 +223,14 @@ catalogs: specifier: 1.15.9 version: 1.15.9 '@typescript-eslint/eslint-plugin': - specifier: 8.59.0 - version: 8.59.0 + specifier: 8.59.1 + version: 8.59.1 '@typescript-eslint/parser': - specifier: 8.59.0 - version: 8.59.0 + specifier: 8.59.1 + version: 8.59.1 '@typescript/native-preview': - specifier: 7.0.0-dev.20260426.1 - version: 7.0.0-dev.20260426.1 + specifier: 7.0.0-dev.20260428.1 + version: 7.0.0-dev.20260428.1 '@vitejs/plugin-react': specifier: 6.0.1 version: 6.0.1 @@ -264,9 +264,12 @@ catalogs: code-inspector-plugin: specifier: 1.5.1 version: 1.5.1 + concurrently: + specifier: ^9.2.1 + version: 9.2.1 copy-to-clipboard: - specifier: 3.3.3 - version: 3.3.3 + specifier: 4.0.2 + version: 4.0.2 cron-parser: specifier: 5.5.0 version: 5.5.0 @@ -304,11 +307,11 @@ catalogs: specifier: 10.2.1 version: 10.2.1 eslint-markdown: - specifier: 0.6.1 - version: 0.6.1 + specifier: 0.7.0 + version: 0.7.0 eslint-plugin-better-tailwindcss: - specifier: 4.4.1 - version: 4.4.1 + specifier: 4.5.0 + version: 4.5.0 eslint-plugin-hyoban: specifier: 0.14.1 version: 0.14.1 @@ -346,8 +349,8 @@ catalogs: specifier: 1.11.13 version: 1.11.13 i18next: - specifier: 26.0.6 - version: 26.0.6 + specifier: 26.0.8 + version: 26.0.8 i18next-resources-to-backend: specifier: 1.2.1 version: 1.2.1 @@ -385,8 +388,8 @@ catalogs: specifier: 1.2.1 version: 1.2.1 lexical: - specifier: 0.43.0 - version: 0.43.0 + specifier: 0.44.0 + version: 0.44.0 loro-crdt: specifier: 1.12.0 version: 1.12.0 @@ -505,8 +508,8 @@ catalogs: specifier: 4.2.4 version: 4.2.4 tldts: - specifier: 7.0.28 - version: 7.0.28 + specifier: 7.0.29 + version: 7.0.29 tsx: specifier: 4.21.0 version: 4.21.0 @@ -523,17 +526,17 @@ catalogs: specifier: 2.0.0 version: 2.0.0 uuid: - specifier: 13.0.0 - version: 13.0.0 + specifier: 14.0.0 + version: 14.0.0 vinext: - specifier: 0.0.41 - version: 0.0.41 + specifier: 0.0.45 + version: 0.0.45 vite-plugin-inspect: specifier: 12.0.0-beta.1 version: 12.0.0-beta.1 vite-plus: - specifier: 0.1.19 - version: 0.1.19 + specifier: 0.1.20 + version: 0.1.20 vitest-browser-react: specifier: 2.2.0 version: 2.2.0 @@ -574,8 +577,8 @@ overrides: svgo@>=3.0.0 <3.3.3: 3.3.3 tar@<=7.5.10: 7.5.11 undici@>=7.0.0 <7.24.0: 7.24.0 - vite: npm:@voidzero-dev/vite-plus-core@0.1.19 - vitest: npm:@voidzero-dev/vite-plus-test@0.1.19 + vite: npm:@voidzero-dev/vite-plus-core@0.1.20 + vitest: npm:@voidzero-dev/vite-plus-test@0.1.20 yaml@>=2.0.0 <2.8.3: 2.8.3 yauzl@<3.2.1: 3.2.1 @@ -585,13 +588,16 @@ importers: devDependencies: '@antfu/eslint-config': specifier: 'catalog:' - version: 8.2.0(@eslint-react/eslint-plugin@3.0.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(@next/eslint-plugin-next@16.2.4)(@types/node@25.6.0)(@typescript-eslint/typescript-estree@8.59.0(typescript@6.0.3))(@typescript-eslint/utils@8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(eslint-plugin-react-refresh@0.5.2(eslint@10.2.1(jiti@2.6.1)))(eslint@10.2.1(jiti@2.6.1))(happy-dom@20.9.0)(jiti@2.6.1)(oxlint@1.60.0(oxlint-tsgolint@0.21.1))(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) + version: 8.2.0(@eslint-react/eslint-plugin@3.0.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(@next/eslint-plugin-next@16.2.4)(@types/node@25.6.0)(@typescript-eslint/typescript-estree@8.59.1(typescript@6.0.3))(@typescript-eslint/utils@8.59.1(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(eslint-plugin-react-refresh@0.5.2(eslint@10.2.1(jiti@2.6.1)))(eslint@10.2.1(jiti@2.6.1))(happy-dom@20.9.0)(jiti@2.6.1)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) + concurrently: + specifier: 'catalog:' + version: 9.2.1 eslint: specifier: 'catalog:' version: 10.2.1(jiti@2.6.1) eslint-markdown: specifier: 'catalog:' - version: 0.6.1(eslint@10.2.1(jiti@2.6.1)) + version: 0.7.0(eslint@10.2.1(jiti@2.6.1)) eslint-plugin-markdown-preferences: specifier: 'catalog:' version: 0.41.1(@eslint/markdown@8.0.1)(eslint@10.2.1(jiti@2.6.1)) @@ -599,11 +605,11 @@ importers: specifier: 'catalog:' version: 1.3.1(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) vite: - specifier: npm:@voidzero-dev/vite-plus-core@0.1.19 - version: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + specifier: npm:@voidzero-dev/vite-plus-core@0.1.20 + version: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' vite-plus: specifier: 'catalog:' - version: 0.1.19(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) + version: 0.1.20(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) e2e: devDependencies: @@ -621,7 +627,7 @@ importers: version: 25.6.0 '@typescript/native-preview': specifier: 'catalog:' - version: 7.0.0-dev.20260426.1 + version: 7.0.0-dev.20260428.1 tsx: specifier: 'catalog:' version: 4.21.0 @@ -629,11 +635,11 @@ importers: specifier: 'catalog:' version: 6.0.3 vite: - specifier: npm:@voidzero-dev/vite-plus-core@0.1.19 - version: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + specifier: npm:@voidzero-dev/vite-plus-core@0.1.20 + version: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' vite-plus: specifier: 'catalog:' - version: 0.1.19(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) + version: 0.1.20(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) packages/dify-ui: dependencies: @@ -661,7 +667,7 @@ importers: version: 1.2.10 '@storybook/addon-docs': specifier: 'catalog:' - version: 10.3.5(@types/react@19.2.14)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) + version: 10.3.5(@types/react@19.2.14)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) '@storybook/addon-links': specifier: 'catalog:' version: 10.3.5(react@19.2.5)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) @@ -670,10 +676,10 @@ importers: version: 10.3.5(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) '@storybook/react-vite': specifier: 'catalog:' - version: 10.3.5(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.3) + version: 10.3.5(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.3) '@tailwindcss/vite': specifier: 'catalog:' - version: 4.2.4(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)) + version: 4.2.4(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)) '@types/react': specifier: 'catalog:' version: 19.2.14 @@ -682,13 +688,13 @@ importers: version: 19.2.3(@types/react@19.2.14) '@typescript/native-preview': specifier: 'catalog:' - version: 7.0.0-dev.20260426.1 + version: 7.0.0-dev.20260428.1 '@vitejs/plugin-react': specifier: 'catalog:' - version: 6.0.1(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)) + version: 6.0.1(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)) '@vitest/coverage-v8': specifier: 'catalog:' - version: 4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) + version: 4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) class-variance-authority: specifier: 'catalog:' version: 0.7.1 @@ -711,14 +717,14 @@ importers: specifier: 'catalog:' version: 6.0.3 vite: - specifier: npm:@voidzero-dev/vite-plus-core@0.1.19 - version: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + specifier: npm:@voidzero-dev/vite-plus-core@0.1.20 + version: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' vite-plus: specifier: 'catalog:' - version: 0.1.19(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) + version: 0.1.20(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) vitest-browser-react: specifier: 'catalog:' - version: 2.2.0(@types/node@25.6.0)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) + version: 2.2.0(@types/node@25.6.0)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) packages/iconify-collections: devDependencies: @@ -733,7 +739,7 @@ importers: dependencies: '@typescript/native-preview': specifier: 'catalog:' - version: 7.0.0-dev.20260426.1 + version: 7.0.0-dev.20260428.1 typescript: specifier: 'catalog:' version: 6.0.3 @@ -745,11 +751,11 @@ importers: specifier: 'catalog:' version: 25.6.0 vite: - specifier: npm:@voidzero-dev/vite-plus-core@0.1.19 - version: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + specifier: npm:@voidzero-dev/vite-plus-core@0.1.20 + version: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' vite-plus: specifier: 'catalog:' - version: 0.1.19(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) + version: 0.1.20(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) packages/tsconfig: {} @@ -766,16 +772,16 @@ importers: version: 25.6.0 '@typescript-eslint/eslint-plugin': specifier: 'catalog:' - version: 8.59.0(@typescript-eslint/parser@8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) + version: 8.59.1(@typescript-eslint/parser@8.59.1(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) '@typescript-eslint/parser': specifier: 'catalog:' - version: 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) + version: 8.59.1(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) '@typescript/native-preview': specifier: 'catalog:' - version: 7.0.0-dev.20260426.1 + version: 7.0.0-dev.20260428.1 '@vitest/coverage-v8': specifier: 'catalog:' - version: 4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) + version: 4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) eslint: specifier: 'catalog:' version: 10.2.1(jiti@2.6.1) @@ -783,23 +789,23 @@ importers: specifier: 'catalog:' version: 6.0.3 vite: - specifier: npm:@voidzero-dev/vite-plus-core@0.1.19 - version: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + specifier: npm:@voidzero-dev/vite-plus-core@0.1.20 + version: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' vite-plus: specifier: 'catalog:' - version: 0.1.19(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) + version: 0.1.20(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) vitest: - specifier: npm:@voidzero-dev/vite-plus-test@0.1.19 - version: '@voidzero-dev/vite-plus-test@0.1.19(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + specifier: npm:@voidzero-dev/vite-plus-test@0.1.20 + version: '@voidzero-dev/vite-plus-test@0.1.20(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' web: dependencies: '@amplitude/analytics-browser': specifier: 'catalog:' - version: 2.41.1 + version: 2.42.0 '@amplitude/plugin-session-replay-browser': specifier: 'catalog:' - version: 1.28.0(@amplitude/rrweb@2.0.0-alpha.37) + version: 1.28.1(@amplitude/rrweb@2.0.0-alpha.37) '@base-ui/react': specifier: 'catalog:' version: 1.4.1(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) @@ -820,25 +826,25 @@ importers: version: 2.2.0(react@19.2.5) '@lexical/code': specifier: npm:lexical-code-no-prism@0.41.0 - version: lexical-code-no-prism@0.41.0(@lexical/utils@0.43.0)(lexical@0.43.0) + version: lexical-code-no-prism@0.41.0(@lexical/utils@0.44.0)(lexical@0.44.0) '@lexical/link': specifier: 'catalog:' - version: 0.43.0 + version: 0.44.0 '@lexical/list': specifier: 'catalog:' - version: 0.43.0 + version: 0.44.0 '@lexical/react': specifier: 'catalog:' - version: 0.43.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + version: 0.44.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@lexical/selection': specifier: 'catalog:' - version: 0.43.0 + version: 0.44.0 '@lexical/text': specifier: 'catalog:' - version: 0.43.0 + version: 0.44.0 '@lexical/utils': specifier: 'catalog:' - version: 0.43.0 + version: 0.44.0 '@monaco-editor/react': specifier: 'catalog:' version: 4.7.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) @@ -853,7 +859,7 @@ importers: version: 1.14.0 '@orpc/tanstack-query': specifier: 'catalog:' - version: 1.14.0(@orpc/client@1.14.0)(@tanstack/query-core@5.100.5) + version: 1.14.0(@orpc/client@1.14.0)(@tanstack/query-core@5.100.6) '@remixicon/react': specifier: 'catalog:' version: 4.9.0(react@19.2.5) @@ -877,7 +883,7 @@ importers: version: 1.29.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@tanstack/react-query': specifier: 'catalog:' - version: 5.100.5(react@19.2.5) + version: 5.100.6(react@19.2.5) '@tanstack/react-virtual': specifier: 'catalog:' version: 3.13.24(react-dom@19.2.5(react@19.2.5))(react@19.2.5) @@ -898,7 +904,7 @@ importers: version: 1.1.1(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) copy-to-clipboard: specifier: 'catalog:' - version: 3.3.3 + version: 4.0.2 cron-parser: specifier: 'catalog:' version: 5.5.0 @@ -946,7 +952,7 @@ importers: version: 1.11.13 i18next: specifier: 'catalog:' - version: 26.0.6(typescript@6.0.3) + version: 26.0.8(typescript@6.0.3) i18next-resources-to-backend: specifier: 'catalog:' version: 1.2.1 @@ -979,7 +985,7 @@ importers: version: 1.2.1 lexical: specifier: 'catalog:' - version: 0.43.0 + version: 0.44.0 loro-crdt: specifier: 'catalog:' version: 1.12.0 @@ -1030,7 +1036,7 @@ importers: version: 5.2.4(react-dom@19.2.5(react@19.2.5))(react@19.2.5) react-i18next: specifier: 'catalog:' - version: 16.5.8(i18next@26.0.6(typescript@6.0.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) + version: 16.5.8(i18next@26.0.8(typescript@6.0.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3) react-multi-email: specifier: 'catalog:' version: 1.0.25(react-dom@19.2.5(react@19.2.5))(react@19.2.5) @@ -1081,7 +1087,7 @@ importers: version: 2.3.1 tldts: specifier: 'catalog:' - version: 7.0.28 + version: 7.0.29 unist-util-visit: specifier: 'catalog:' version: 5.1.0 @@ -1090,7 +1096,7 @@ importers: version: 2.0.0(react@19.2.5)(scheduler@0.27.0) uuid: specifier: 'catalog:' - version: 13.0.0 + version: 14.0.0 zod: specifier: 'catalog:' version: 4.3.6 @@ -1103,7 +1109,7 @@ importers: devDependencies: '@antfu/eslint-config': specifier: 'catalog:' - version: 8.2.0(@eslint-react/eslint-plugin@3.0.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(@next/eslint-plugin-next@16.2.4)(@types/node@25.6.0)(@typescript-eslint/typescript-estree@8.59.0(typescript@6.0.3))(@typescript-eslint/utils@8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(eslint-plugin-react-refresh@0.5.2(eslint@10.2.1(jiti@2.6.1)))(eslint@10.2.1(jiti@2.6.1))(happy-dom@20.9.0)(jiti@2.6.1)(oxlint@1.60.0(oxlint-tsgolint@0.21.1))(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) + version: 8.2.0(@eslint-react/eslint-plugin@3.0.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(@next/eslint-plugin-next@16.2.4)(@types/node@25.6.0)(@typescript-eslint/typescript-estree@8.59.1(typescript@6.0.3))(@typescript-eslint/utils@8.59.1(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(eslint-plugin-react-refresh@0.5.2(eslint@10.2.1(jiti@2.6.1)))(eslint@10.2.1(jiti@2.6.1))(happy-dom@20.9.0)(jiti@2.6.1)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) '@chromatic-com/storybook': specifier: 'catalog:' version: 5.1.2(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) @@ -1121,7 +1127,7 @@ importers: version: 3.0.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) '@hono/node-server': specifier: 'catalog:' - version: 1.19.14(hono@4.12.15) + version: 2.0.0(hono@4.12.15) '@iconify-json/heroicons': specifier: 'catalog:' version: 1.2.3 @@ -1151,7 +1157,7 @@ importers: version: 4.2.0 '@storybook/addon-docs': specifier: 'catalog:' - version: 10.3.5(@types/react@19.2.14)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) + version: 10.3.5(@types/react@19.2.14)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) '@storybook/addon-links': specifier: 'catalog:' version: 10.3.5(react@19.2.5)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) @@ -1163,7 +1169,7 @@ importers: version: 10.3.5(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) '@storybook/nextjs-vite': specifier: 'catalog:' - version: 10.3.5(@babel/core@7.29.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(next@16.2.4(@babel/core@7.29.0)(@playwright/test@1.59.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.3) + version: 10.3.5(@babel/core@7.29.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(next@16.2.4(@babel/core@7.29.0)(@playwright/test@1.59.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.3) '@storybook/react': specifier: 'catalog:' version: 10.3.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.3) @@ -1172,10 +1178,10 @@ importers: version: 4.2.4 '@tailwindcss/vite': specifier: 'catalog:' - version: 4.2.4(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)) + version: 4.2.4(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)) '@tanstack/eslint-plugin-query': specifier: 'catalog:' - version: 5.100.5(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) + version: 5.100.6(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) '@tanstack/react-devtools': specifier: 'catalog:' version: 0.10.2(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(csstype@3.2.3)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) @@ -1184,7 +1190,7 @@ importers: version: 0.2.22(@types/react@19.2.14)(csstype@3.2.3)(react@19.2.5)(solid-js@1.9.11) '@tanstack/react-query-devtools': specifier: 'catalog:' - version: 5.100.5(@tanstack/react-query@5.100.5(react@19.2.5))(react@19.2.5) + version: 5.100.6(@tanstack/react-query@5.100.6(react@19.2.5))(react@19.2.5) '@testing-library/dom': specifier: 'catalog:' version: 10.4.1 @@ -1199,13 +1205,13 @@ importers: version: 14.6.1(@testing-library/dom@10.4.1) '@tsslint/cli': specifier: 'catalog:' - version: 3.0.4(@tsslint/compat-eslint@3.0.4(jiti@2.6.1)(typescript@6.0.3))(typescript@6.0.3) + version: 3.1.0(@tsslint/compat-eslint@3.1.0(typescript@6.0.3))(typescript@6.0.3) '@tsslint/compat-eslint': specifier: 'catalog:' - version: 3.0.4(jiti@2.6.1)(typescript@6.0.3) + version: 3.1.0(typescript@6.0.3) '@tsslint/config': specifier: 'catalog:' - version: 3.0.4(@tsslint/compat-eslint@3.0.4(jiti@2.6.1)(typescript@6.0.3))(typescript@6.0.3) + version: 3.1.0(@tsslint/compat-eslint@3.1.0(typescript@6.0.3))(typescript@6.0.3) '@types/js-cookie': specifier: 'catalog:' version: 3.0.6 @@ -1232,19 +1238,19 @@ importers: version: 1.15.9 '@typescript-eslint/parser': specifier: 'catalog:' - version: 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) + version: 8.59.1(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) '@typescript/native-preview': specifier: 'catalog:' - version: 7.0.0-dev.20260426.1 + version: 7.0.0-dev.20260428.1 '@vitejs/plugin-react': specifier: 'catalog:' - version: 6.0.1(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)) + version: 6.0.1(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)) '@vitejs/plugin-rsc': specifier: 'catalog:' - version: 0.5.25(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(react-dom@19.2.5(react@19.2.5))(react-server-dom-webpack@19.2.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react@19.2.5) + version: 0.5.25(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(react-dom@19.2.5(react@19.2.5))(react-server-dom-webpack@19.2.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react@19.2.5) '@vitest/coverage-v8': specifier: 'catalog:' - version: 4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) + version: 4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) agentation: specifier: 'catalog:' version: 3.0.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) @@ -1256,10 +1262,10 @@ importers: version: 10.2.1(jiti@2.6.1) eslint-markdown: specifier: 'catalog:' - version: 0.6.1(eslint@10.2.1(jiti@2.6.1)) + version: 0.7.0(eslint@10.2.1(jiti@2.6.1)) eslint-plugin-better-tailwindcss: specifier: 'catalog:' - version: 4.4.1(eslint@10.2.1(jiti@2.6.1))(oxlint@1.60.0(oxlint-tsgolint@0.21.1))(tailwindcss@4.2.4)(typescript@6.0.3) + version: 4.5.0(eslint@10.2.1(jiti@2.6.1))(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(tailwindcss@4.2.4)(typescript@6.0.3) eslint-plugin-hyoban: specifier: 'catalog:' version: 0.14.1(eslint@10.2.1(jiti@2.6.1)) @@ -1310,22 +1316,22 @@ importers: version: 3.19.3 vinext: specifier: 'catalog:' - version: 0.0.41(@mdx-js/rollup@3.1.1)(@vitejs/plugin-react@6.0.1(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)))(@vitejs/plugin-rsc@0.5.25(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(react-dom@19.2.5(react@19.2.5))(react-server-dom-webpack@19.2.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react@19.2.5))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(next@16.2.4(@babel/core@7.29.0)(@playwright/test@1.59.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react-server-dom-webpack@19.2.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react@19.2.5)(typescript@6.0.3) + version: 0.0.45(@mdx-js/rollup@3.1.1)(@vitejs/plugin-react@6.0.1(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)))(@vitejs/plugin-rsc@0.5.25(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(react-dom@19.2.5(react@19.2.5))(react-server-dom-webpack@19.2.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react@19.2.5))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(next@16.2.4(@babel/core@7.29.0)(@playwright/test@1.59.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react-server-dom-webpack@19.2.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react@19.2.5)(typescript@6.0.3) vite: - specifier: npm:@voidzero-dev/vite-plus-core@0.1.19 - version: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + specifier: npm:@voidzero-dev/vite-plus-core@0.1.20 + version: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' vite-plugin-inspect: specifier: 'catalog:' - version: 12.0.0-beta.1(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3)(ws@8.20.0) + version: 12.0.0-beta.1(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3)(ws@8.20.0) vite-plus: specifier: 'catalog:' - version: 0.1.19(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) + version: 0.1.20(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) vitest: - specifier: npm:@voidzero-dev/vite-plus-test@0.1.19 - version: '@voidzero-dev/vite-plus-test@0.1.19(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + specifier: npm:@voidzero-dev/vite-plus-test@0.1.20 + version: '@voidzero-dev/vite-plus-test@0.1.20(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' vitest-canvas-mock: specifier: 'catalog:' - version: 1.1.4(@voidzero-dev/vite-plus-test@0.1.19(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)) + version: 1.1.4(@voidzero-dev/vite-plus-test@0.1.20(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)) packages: @@ -1336,47 +1342,53 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} - '@amplitude/analytics-browser@2.41.1': - resolution: {integrity: sha512-qSUFBtln+VY6XIki/Ym3adUlnBvb3TrfFHhXFp5TVi9rz/8p/vKWmQ9Htsf4I0H70xZCe+sNHv53NOyTt1VzUA==} + '@amplitude/analytics-browser@2.42.0': + resolution: {integrity: sha512-xG1CU3M8kYjmQmxxvy8c8m1ww7wqp+kuttpVxWsItyKABBIZNofRo4E0UzENBu8PuXRcwKrLq99DdceVKtsL0g==} '@amplitude/analytics-client-common@2.4.46': resolution: {integrity: sha512-cvNzR7GY+PqvdT7b1jjs+LhLjkLr/raS8C6Jo4nTD/hDzWI+b73u12atttbgWKGJMCmki+xs+X0oyMt207+qtQ==} + '@amplitude/analytics-client-common@2.4.47': + resolution: {integrity: sha512-AFmZK3e3mytXtwyLeNqF85T8bGMcw4slYP8mRu9Fm5B9OZEnEqjhKYzNDEMOKtwBkEQbusHCWWYGfZT5sY2+tg==} + '@amplitude/analytics-connector@1.6.4': resolution: {integrity: sha512-SpIv0IQMNIq6SH3UqFGiaZyGSc7PBZwRdq7lvP0pBxW8i4Ny+8zwI0pV+VMfMHQwWY3wdIbWw5WQphNjpdq1/Q==} '@amplitude/analytics-core@2.47.1': resolution: {integrity: sha512-ZdtAx5syGZBQpbZVLnc/zp7sMlq7+b1dxo/5gCG/4thNW0vOHfN4nYGlV2+k/VEEw4/hW893t5EPUCbxUJM+OQ==} + '@amplitude/analytics-core@2.48.0': + resolution: {integrity: sha512-6ckWWL60LiJJEQQ5V3Veviq0Gl5Lcvy1dFaRDKA/SwLT3cgiBrEFZXZPcri4wDGjchPmJXFCYcE55nr7rP6Wjg==} + '@amplitude/analytics-types@2.11.1': resolution: {integrity: sha512-wFEgb0t99ly2uJKm5oZ28Lti0Kh5RecR5XBkwfUpDzn84IoCIZ8GJTsMw/nThu8FZFc7xFDA4UAt76zhZKrs9A==} '@amplitude/experiment-core@0.7.2': resolution: {integrity: sha512-Wc2NWvgQ+bLJLeF0A9wBSPIaw0XuqqgkPKsoNFQrmS7r5Djd56um75In05tqmVntPJZRvGKU46pAp8o5tdf4mA==} - '@amplitude/plugin-autocapture-browser@1.26.1': - resolution: {integrity: sha512-5Lge/azo8/+JC2YAnX/2YoNYfhKp00MtyAjiZFmFkG5pQUguXnSqTJw0UaUu/gzIZo5VaDAIGFZIk0b++ayTyA==} + '@amplitude/plugin-autocapture-browser@1.27.0': + resolution: {integrity: sha512-iSQJQA2nMftjJ+MtB/ndrLRkSWqsTrGUwia9f+bRodWEQbLw36o/JVD6aHqm5rTvXYvsK/oK9Qv6PAv1lKIL5A==} - '@amplitude/plugin-custom-enrichment-browser@0.1.7': - resolution: {integrity: sha512-r4hoD38mbtXH91glpxI0EIslwWMrVuupWar2mp/OrbKEHfxdXrOsXfIc17fxYnQHqWpGuBghNMwh0oppRzJtAw==} + '@amplitude/plugin-custom-enrichment-browser@0.1.8': + resolution: {integrity: sha512-PVg56GfQID/UKLZx7imbg6Tmlj2AX/euyG7nnouKpowgGJ7jz/t4o2u3csSgrKbLSrTjxdbXVdPyz/+CecJ4Zg==} - '@amplitude/plugin-event-property-attribution-browser@0.1.2': - resolution: {integrity: sha512-Zd0EioWcm+UhrkJMls2mn+9AXpA/H9TeuULZOFbggRhfZ3rLtJMF3LqGLRs8UyA7vHXiqKsE7DXLur2Ya8sBzA==} + '@amplitude/plugin-event-property-attribution-browser@0.2.0': + resolution: {integrity: sha512-7GmAvpOf7CbdIL++9PrdNB8GeyUvL5/yRrv1hnVC7rv19MKumbYK9Oq1utOUr6nddPfQU3w3sz9YK5A8cUVrlQ==} - '@amplitude/plugin-network-capture-browser@1.9.16': - resolution: {integrity: sha512-VzY6OzWM3p6hYWZcOh/Ex+j/OgCfMfKO94wK71vgRL8+U3RTBr8bAw36i2twjL1jvAkSXv/PxTmzied1SEdKqQ==} + '@amplitude/plugin-network-capture-browser@1.10.0': + resolution: {integrity: sha512-wDTxpeDCst+pKyfRnVH1RYV93ctQtfuAQuCaUHqSO/TYcHnidGFWLl/UVbMvJ6EkrPoDXOCCTk5gTSPVMKSp0w==} - '@amplitude/plugin-page-url-enrichment-browser@0.7.8': - resolution: {integrity: sha512-/6FevlSaB7a5+R7Pph6I/Hc412JbNOy4z7g4JvzImeTtmmN8xMpg7Shu17Aum2mi2sK7sofHE1UMAXEoULpJEA==} + '@amplitude/plugin-page-url-enrichment-browser@0.7.9': + resolution: {integrity: sha512-3hMP05h8+wbEwrJQm/1Di4XkGskGEeSTI7lnMYwAwsSXIQkmP0bM8G8MAWYwoA1cGAh5Z3cUxp2xGJ/7IacvlA==} - '@amplitude/plugin-page-view-tracking-browser@2.10.2': - resolution: {integrity: sha512-1H/3YAXi5bVLZ0YNRbnHEne2J9c7kXvwmppSOZgQ21LIdxBo9A4WJhWPAJIZKqn9W2BbgrpxI/BjwOUMf5gYQw==} + '@amplitude/plugin-page-view-tracking-browser@2.11.0': + resolution: {integrity: sha512-ZI/1kTQID0yXileGjvseMoFZ9zUbLG5r+MsznmT0Br+x91LdCrPHXdpU7lq53UAwIhgREXk9S/o/AwUZfFSgzg==} - '@amplitude/plugin-session-replay-browser@1.28.0': - resolution: {integrity: sha512-alWW4czF7gINNaJAwCO+HXGkAgam7HjixNt/j5fCk/LGfWyHru8Yg1G5TKjOugrWEeZEqaDAVYGz+KcqbX3RVQ==} + '@amplitude/plugin-session-replay-browser@1.28.1': + resolution: {integrity: sha512-gSRIZUgUKEb4OvYcGYJZ553YVftq8lIzYkV9BsIQqUxFn3MVFygdQj+ZJCz75lJeyJZI7r9VhLTIzIcuIJ0KFg==} - '@amplitude/plugin-web-vitals-browser@1.1.31': - resolution: {integrity: sha512-zIGLyfb9I1rgdJQtRVir5d97spEe1er1vrPDzfHbrcwCgrLR8CGEzx1LQQcHCB6vg5tjrHsi7LdvZCLYRj+lCA==} + '@amplitude/plugin-web-vitals-browser@1.1.32': + resolution: {integrity: sha512-cf/MR5WTJ5iwCjxdy9f7vK8zy2nD1iXPwu8eKHiRxWR7Eoqx7bT30n9dar8kWDV8kraV0sglA5pVrP3b33m/pw==} '@amplitude/rrdom@2.0.0-alpha.37': resolution: {integrity: sha512-u4dSnBtlbJ8oU5P/Ywl2RLqvjqWbkl4ScMUbvQA7in4pWcx+0NRN+VVjLZXQcd8Fn7E/rcxjeUh7e7HfwvdasQ==} @@ -1410,8 +1422,8 @@ packages: '@amplitude/rrweb@2.0.0-alpha.37': resolution: {integrity: sha512-jJkSpPYiVgOZB422pb2jOJJn3pvb5E5f9vKK8CEmUlk2mVAl6kPQzW98mb05M65OJFj5nn9tSe9h5r5+Cl93ag==} - '@amplitude/session-replay-browser@1.38.0': - resolution: {integrity: sha512-SwOdPb/pB7A1ysQico62cwAQ02Y6E8FMN0BNg8KtMC8wXpUxaGKaL952mpNqrvPZs+kwTDYS6dKHA7pg2TfX4w==} + '@amplitude/session-replay-browser@1.39.0': + resolution: {integrity: sha512-JUVrzBNFbZKvA3QFls5fVLRvpr8F369omyIQzF5qkIpB9ExpAXqRvSXpwX+64oXlugQfW0oR9iAgRu10C66ygg==} '@amplitude/targeting@0.2.0': resolution: {integrity: sha512-/50ywTrC4hfcfJVBbh5DFbqMPPfaIOivZeb5Gb+OGM03QrA+lsUqdvtnKLNuWtceD4H6QQ2KFzPJ5aAJLyzVDA==} @@ -1609,15 +1621,9 @@ packages: peerDependencies: storybook: ^0.0.0-0 || ^10.1.0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0 || ^10.4.0-0 - '@clack/core@0.3.5': - resolution: {integrity: sha512-5cfhQNH+1VQ2xLQlmzXMqUoiaH0lRBq9/CLW9lTyMbuKLC3+xEK01tHVvyut++mLOn5urSHmkm6I0Lg9MaJSTQ==} - '@clack/core@1.2.0': resolution: {integrity: sha512-qfxof/3T3t9DPU/Rj3OmcFyZInceqj/NVtO9rwIuJqCUgh32gwPjpFQQp/ben07qKlhpwq7GzfWpST4qdJ5Drg==} - '@clack/prompts@0.8.2': - resolution: {integrity: sha512-6b9Ab2UiZwJYA9iMyboYyW9yJvAO9V753ZhS+DHKEjZRKAxPPOb7MXXu84lsPFG+vZt6FRFniZ8rXi+zCIw4yQ==} - '@clack/prompts@1.2.0': resolution: {integrity: sha512-4jmztR9fMqPMjz6H/UZXj0zEmE43ha1euENwkckKKel4XpSfokExPo5AiVStdHSAlHekz4d0CA/r45Ok1E4D3w==} @@ -1960,18 +1966,10 @@ packages: eslint: optional: true - '@eslint/config-array@0.20.1': - resolution: {integrity: sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/config-array@0.23.5': resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/config-helpers@0.2.3': - resolution: {integrity: sha512-u180qk2Um1le4yf0ruXH3PYFeEZeYC3p/4wCTKrr2U1CmGdzGi3KtY0nuPDH48UJxlKCC5RDzbcbh4X0XlqgHg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/config-helpers@0.5.4': resolution: {integrity: sha512-jJhqiY3wPMlWWO3370M86CPJ7pt8GmEwSLglMfQhjXal07RCvhmU0as4IuUEW5SJeunfItiEetHmSxCCe9lDBg==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} @@ -1980,14 +1978,6 @@ packages: resolution: {integrity: sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/core@0.14.0': - resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/core@0.15.2': - resolution: {integrity: sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.17.0': resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2004,10 +1994,6 @@ packages: resolution: {integrity: sha512-2fCSKRwoUHntYq9J1Lm28s2zeoCSNh1Cbk6Tg7k7ViwOnveIfZwPRFGwBglz+dzw2MHe5w5Fo9+VJfqL9nco2w==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/eslintrc@3.3.5': - resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@10.0.1': resolution: {integrity: sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} @@ -2017,10 +2003,6 @@ packages: eslint: optional: true - '@eslint/js@9.27.0': - resolution: {integrity: sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/markdown@7.5.1': resolution: {integrity: sha512-R8uZemG9dKTbru/DQRPblbJyXpObwKzo8rv1KYGGuPUPtjM4LXBYM9q5CIZAComzZupws3tWbDwam5AFpPLyJQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2029,18 +2011,10 @@ packages: resolution: {integrity: sha512-WWKmld/EyNdEB8GMq7JMPX1SDWgyJAM1uhtCi5ySrqYQM4HQjmg11EX/q3ZpnpRXHfdccFtli3NBvvGaYjWyQw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/object-schema@2.1.7': - resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/object-schema@3.0.5': resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/plugin-kit@0.3.5': - resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.4.1': resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2098,9 +2072,9 @@ packages: peerDependencies: react: '>= 16 || ^19.0.0-rc' - '@hono/node-server@1.19.14': - resolution: {integrity: sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==} - engines: {node: '>=18.14.1'} + '@hono/node-server@2.0.0': + resolution: {integrity: sha512-n3GfHwwCvHCkGmOwKfxUPOlbfzuO64Sbc5XC4NGPIXxkuOnJrdgExdRKmHfF924r914WRJPT397GdqLvdYTeyQ==} + engines: {node: '>=20'} peerDependencies: hono: ^4 @@ -2320,77 +2294,78 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@lexical/clipboard@0.43.0': - resolution: {integrity: sha512-3dWDusVyM9EosBt4/n/ERyPIGOyuWuECj9zbvJdzGUdvu/VsqCdlyDsU5M7NxTUNQn2Fhkdj2o00UeB6bagX5Q==} + '@lexical/clipboard@0.44.0': + resolution: {integrity: sha512-nfmNIs7uENqlDI7cm2E4I1Yp8mDJGMhEQIrIV2rNWnL1oeHVXQ7yuYdyoPdcY1zuj/9nvkYBQYUEh0QiGwpETA==} - '@lexical/code-core@0.43.0': - resolution: {integrity: sha512-8NtEOI4+hM688Pmd0Qh/aTCS5uovps902V53LGB15DUUwwL+Z5U+Hz7ZYozhyM6W755FQ3x15qtEGIIbDHE5bQ==} + '@lexical/code-core@0.44.0': + resolution: {integrity: sha512-m57JyXTIvW1tsqw/Vuogk8jqWCZZIeFQbWybRc46ytR8ReDgzPRODpN8+dacIIeRH5yC5UC3lAa743mtdNkxqg==} - '@lexical/devtools-core@0.43.0': - resolution: {integrity: sha512-Hyz8vxvmo0aThXjq3+t0mabozmQeb6U+pxKceAgBSxE9oLWbQmP7RW8jYPZW20bYqEcX1Kgmu+CdW8e3eSF7Kw==} + '@lexical/devtools-core@0.44.0': + resolution: {integrity: sha512-X3uNG3P1vOsdzmEcy+7m9DxAcIVtVUZnvskmLqqLs6VluVVwH9xy7h1bPsvlDKvj1Nj73tWJ3TW0qXQWDTo5tw==} peerDependencies: react: '>=17.x' react-dom: '>=17.x' - '@lexical/dragon@0.43.0': - resolution: {integrity: sha512-wB2s8uO9DFwS5err1wM+7Yoz3cixtEXy1ZiU8RoJJ7tmjSEmQsLIflAQq8Lic291tCNPs+lSHKjdw+52vi0Z7Q==} + '@lexical/dragon@0.44.0': + resolution: {integrity: sha512-RhlsjVDket9k1+YFEkDE0/7Qyrh2BI0vxBMzrWwPJTXX/4YFanYN9su8RSabkIukBBJ3QiNOOoC8FKK4Lkr4qg==} - '@lexical/extension@0.43.0': - resolution: {integrity: sha512-hCFj//3RhsPrCmx8VRTTLIsWtC2n5GG03ZDdyrgmeLzXNuknwDqhzaGAfQi9LSYn+NU+j3yCUROu8pZqaedtvw==} + '@lexical/extension@0.44.0': + resolution: {integrity: sha512-BsYtoc+0EU0pqcOpf/lIUDU6LQVO6zX2AawZoUWJzT3Wzfov23qsqZWvl2WGM9dnRTN5iISJL3Fl53bQVxiXxw==} - '@lexical/hashtag@0.43.0': - resolution: {integrity: sha512-oCKjY8/jkxJuu8iBnNX0WSLA6ZIYTn+v3NLpJxDqnAFZJCnJ2i/nM8GKzPMzHCDzJVNxbQB08fOptdXf8eN0Fg==} + '@lexical/hashtag@0.44.0': + resolution: {integrity: sha512-0WATahDSqYKVTudQv3KpFbLeCpmrCpRptPFbjxOMckAX2MRpYlrExlqKfgfpri5BSQPtG49EPSGeNfSx/Faavw==} - '@lexical/history@0.43.0': - resolution: {integrity: sha512-SdrH3xgtUcolVRLihbQwiANQIiwSLdkKBon9oSsZNNnzVgEb7DUQUtJQGf33oW8HHWObIuWkh72W0fN1dZixOw==} + '@lexical/history@0.44.0': + resolution: {integrity: sha512-RGXcbFTgYL1GIWaReBI26mNSsJTfiA9EAtDY4LBeZ14NrIQhYNokKgNiOxq5Bn8xXrl2+mawQEqoMfgpWp/5YA==} - '@lexical/html@0.43.0': - resolution: {integrity: sha512-C6LpUQlRl9J8Hqpm/C8LCX1ZxFHyD/gvOdV+NuNGnXN06uo0jDDm9SNh/HI3VWvFu9ec4OuzUkQRCafW8WC8fQ==} + '@lexical/html@0.44.0': + resolution: {integrity: sha512-5X6eGsgwtqPxABsuShUxF7ZfyB/U4GwSEyeonvwH1Vc/5Q2uQVjlB+FAYd+MNwWMHMh4d4+yZ3l70AtIuhr5eg==} - '@lexical/link@0.43.0': - resolution: {integrity: sha512-jjU9PVWWBA2yEssbVkLQpu1ZIpXi3JwYb+JO20R47hzUm7T8SAPDd/VwU+2tcjqz065YntSGIaQ79dCft7WOJw==} + '@lexical/link@0.44.0': + resolution: {integrity: sha512-uvEqEol/mLEzGVQd8Rok9I48RgYPKokM/nsclI9nYcEdccVOM2Nri4ntoRwodhbccFLtjMPl8OBldwXbfc77tQ==} - '@lexical/list@0.43.0': - resolution: {integrity: sha512-WyYVeQa2x1LrI8Emr9AiWTjSMiZw77Zy7MRnohPTdX/4fu3Njfw61lpoonCNHlv/r5Mb/RHkIAwWjtjcSzwA+g==} + '@lexical/list@0.44.0': + resolution: {integrity: sha512-ZTCWxDz1okPrC9FBXi1yV3W5fbQQeMUlFIcSVF9HibcVPmCsPa900IxthuiQbGiTycUyXDTOB3IUYRtlJNtpjw==} - '@lexical/mark@0.43.0': - resolution: {integrity: sha512-pgwR5ia2ECDS0pyQxIrFvMOKjffI6fo2cGwqYg+Jz+ANMqE5zD4PoOUs7FEuZYAKPOAQR9GrETB7YAVSzKjk3Q==} + '@lexical/mark@0.44.0': + resolution: {integrity: sha512-bWMowllwe6BcgYMAkrsZx6Z+CX/72qCQpFKhlkR4ael92yOWSBkz68xp1wxxkSnQX9zoI1gYTeWBofVsSDKcsQ==} - '@lexical/markdown@0.43.0': - resolution: {integrity: sha512-bJYhISQkdRo6XxcajgP9T+c8XAGfkJ/DHnSvM5nyJnHD0vZSH/2RZd2Lgt0eAnMVEt9ECG8cUkR557QSaPeJBA==} + '@lexical/markdown@0.44.0': + resolution: {integrity: sha512-DwlXdp85pYMo3exDF6W3iz8plpuP+RQ4Me4Iljm7O5aPDp0SSrIoZxyX4zS668mVAoz5HHj1Ka0kQkft8mq26Q==} - '@lexical/offset@0.43.0': - resolution: {integrity: sha512-SYNF16Hk17ePaxFtPcBx3rzSM8yxDYSAzkSOdnUUePSzfTW3DUDzvUfe7q/7QCe/UlZd+4ULI0VjNgYRlR8Uiw==} + '@lexical/overflow@0.44.0': + resolution: {integrity: sha512-5GYaYjSxn27pqHRfU+tQ2STF10wgJvI+MUnwTnUFSzy3dko1b+oV94K/Yx0TuEewPbwDibfoFA8CwqUvOLHAyw==} - '@lexical/overflow@0.43.0': - resolution: {integrity: sha512-Usm7UfIwydhsg+qMbkBav79AOKqYa32zXY+TXveTqbaA+IAoIl3vFYP9x9ie4cHz/kgrmt/QuQs66cwPefRakg==} + '@lexical/plain-text@0.44.0': + resolution: {integrity: sha512-bIV4Lljk0x70zFhkZIwzSPK5q3m9FpDisjGm2/3Q/chb+5BW3Tv8QJmqnpCiSO6S2KXO7gfSy81ZfkQ1dcd4EQ==} - '@lexical/plain-text@0.43.0': - resolution: {integrity: sha512-wza2z2+OSsq3UPsFseqsVvnAWvW9s3W/rjQuf6Bk2/Xde2F3R7fvu3kArsaaVPzUKTVeOPCD8hUKIUpxP5OT2g==} - - '@lexical/react@0.43.0': - resolution: {integrity: sha512-Ov9PCS7Ghm83fmjSDr6CafDLsuMhf7A7FFfEr4DmDM/6Lw2w0a0QQJP+KqxPqaVaRgeQMJAVg38Zgrvuk3v7tw==} + '@lexical/react@0.44.0': + resolution: {integrity: sha512-p/NQd/fMh3pXb1XqegE2ruvWDcUmfB12OidQ9nwtMtj5VfcUjQu2I+trUhgGRIADxSYxMWmw+8PPj5YSf4m5oA==} peerDependencies: react: '>=17.x' react-dom: '>=17.x' + yjs: '>=13.5.22' + peerDependenciesMeta: + yjs: + optional: true - '@lexical/rich-text@0.43.0': - resolution: {integrity: sha512-y6uhY5X+PBLg8LSCDazSMAkUfA1RwBW6DFOuUKW5SI1DaB/oc/vpQhkR1DYGqXnytMx7hfiK+7lL51ZC0ydeWg==} + '@lexical/rich-text@0.44.0': + resolution: {integrity: sha512-IIdrutK5GY47ITjPlZB7KzUi9dBDwygsyFOwolnrYSL7m6TtGhAqrYiFg/YNOTT/nBzK3KQeCJRbnxpjJAVZtQ==} - '@lexical/selection@0.43.0': - resolution: {integrity: sha512-sdKdXIFggtHxTctvXjTyx2RgWuKOOP3PhrzRJF+COGfckrr/YzDtQCOfyvktElyKEeYXa3t9sx/R6Ep3n074fA==} + '@lexical/selection@0.44.0': + resolution: {integrity: sha512-AEyeZJFFr5YRLeqVR+X0QAW19c4Fk4MFAQu52z2gxAyDGTj9xwVJxjfepVpfUp4P9K+sPtJ/yaqfMXH506ksSQ==} - '@lexical/table@0.43.0': - resolution: {integrity: sha512-oLrOBzRwpmdHDpGVRgwBVgO1ro0w50rMdtOVQ6KsL53ijZ6OiI1YE2ZNOy4qfJvjub+2dgp83gKpB7YcmXAP3w==} + '@lexical/table@0.44.0': + resolution: {integrity: sha512-5Uq0O/fBCxcZp9y17fXUONY7dU9lVo/mB5JHy23laIiKzBKP5IzzTLMU9ikZTppIXbMNxYXd+R2pmy7PYTLyvw==} - '@lexical/text@0.43.0': - resolution: {integrity: sha512-dtUZ79WaAv3nEYBIWPBZIrjwCUPONN8HcgtReY3qku7WQkzqy3FaMwT/lBa92cUhqsn4ChLIBO3lPFhWRALyvg==} + '@lexical/text@0.44.0': + resolution: {integrity: sha512-1XJD8ZbwaXljTl8k4+jjiopdhnYZm26IJw9Gv8+cIThVC0b6B3JZ/WxH97BMDcSloKvWHFkGiPztxRwNwA29Rw==} - '@lexical/utils@0.43.0': - resolution: {integrity: sha512-Y9wzFwoeI9KLDJsztTz45Aobp6sACHSRqUtyjxpCsU0jwL60Tt9rD71QVz7SvpmzxjtnBb040s6LHa6vP0gY+A==} + '@lexical/utils@0.44.0': + resolution: {integrity: sha512-/D2ptztNevfBJgtkj4uaiYBeRcvSy+1mQj6pNYaCFZIoPJIwl6H5fXwWAvpvr11vcQKP9DEEoXR+V4qkMOA+EA==} - '@lexical/yjs@0.43.0': - resolution: {integrity: sha512-3ghY9BYZVo3Hg2TmY2+H3Q6+AhhGwNIhnr6mvCbdLBEsnSTXr4VZSPMXN2ae5phCPrI19eHrx4MvFNYodQcqrA==} + '@lexical/yjs@0.44.0': + resolution: {integrity: sha512-b3QTub9J/3LuwSSdooynb6GbMHBRyBT4xUbXzXqNPbDHgYe6CDrqf/uJIHRihIjAhOnPaHYqo9XUzitl++N1DQ==} peerDependencies: yjs: '>=13.5.22' @@ -2697,13 +2672,10 @@ packages: cpu: [x64] os: [win32] - '@oxc-project/runtime@0.126.0': - resolution: {integrity: sha512-oksjxfqDNmIYMGlIgLzYgnz5YjZax27RtQezsPpKEGo9AC5LOaIGHsivCCeaAWdCtPnRyjZXM/7svreCC8kZVQ==} + '@oxc-project/runtime@0.127.0': + resolution: {integrity: sha512-UQYLxAhDDPHm++szfa4z0RTdcPq5vaywrAoEA2n1YaAKeanXQdjHsoT6x1gP3U97RN8LZ7yHsSOrKPCcA6mCqw==} engines: {node: ^20.19.0 || >=22.12.0} - '@oxc-project/types@0.126.0': - resolution: {integrity: sha512-oGfVtjAgwQVVpfBrbtk4e1XDyWHRFta6BS3GWVzrF8xYBT2VGQAk39yJS/wFSMrZqoiCU4oghT3Ch0HaHGIHcQ==} - '@oxc-project/types@0.127.0': resolution: {integrity: sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==} @@ -2815,276 +2787,276 @@ packages: cpu: [x64] os: [win32] - '@oxfmt/binding-android-arm-eabi@0.45.0': - resolution: {integrity: sha512-A/UMxFob1fefCuMeGxQBulGfFE38g2Gm23ynr3u6b+b7fY7/ajGbNsa3ikMIkGMLJW/TRoQaMoP1kME7S+815w==} + '@oxfmt/binding-android-arm-eabi@0.46.0': + resolution: {integrity: sha512-b1doV4WRcJU+BESSlCvCjV+5CEr/T6h0frArAdV26Nir+gGNFNaylvDiiMPfF1pxeV0txZEs38ojzJaxBYg+ng==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxfmt/binding-android-arm64@0.45.0': - resolution: {integrity: sha512-L63z4uZmHjgvvqvMJD7mwff8aSBkM0+X4uFr6l6U5t6+Qc9DCLVZWIunJ7Gm4fn4zHPdSq6FFQnhu9yqqobxIg==} + '@oxfmt/binding-android-arm64@0.46.0': + resolution: {integrity: sha512-v6+HhjsoV3GO0u2u9jLSAZrvWfTraDxKofUIQ7/ktS7tzS+epVsxdHmeM+XxuNcAY/nWxxU1Sg4JcGTNRXraBA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxfmt/binding-darwin-arm64@0.45.0': - resolution: {integrity: sha512-UV34dd623FzqT+outIGndsCA/RBB+qgB3XVQhgmmJ9PJwa37NzPC9qzgKeOhPKxVk2HW+JKldQrVL54zs4Noww==} + '@oxfmt/binding-darwin-arm64@0.46.0': + resolution: {integrity: sha512-3eeooJGrqGIlI5MyryDZsAcKXSmKIgAD4yYtfRrRJzXZ0UTFZtiSveIur56YPrGMYZwT4XyVhHsMqrNwr1XeFA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxfmt/binding-darwin-x64@0.45.0': - resolution: {integrity: sha512-pMNJv0CMa1pDefVPeNbuQxibh8ITpWDFEhMC/IBB9Zlu76EbgzYwrzI4Cb11mqX2+rIYN70UTrh3z06TM59ptQ==} + '@oxfmt/binding-darwin-x64@0.46.0': + resolution: {integrity: sha512-QG8BDM0CXWbu84k2SKmCqfEddPQPFiBicwtYnLqHRWZZl57HbtOLRMac/KTq2NO4AEc4ICCBpFxJIV9zcqYfkQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxfmt/binding-freebsd-x64@0.45.0': - resolution: {integrity: sha512-xTcRoxbbo61sW2+ZRPeH+vp/o9G8gkdhiVumFU+TpneiPm14c79l6GFlxPXlCE9bNWikigbsrvJw46zCVAQFfg==} + '@oxfmt/binding-freebsd-x64@0.46.0': + resolution: {integrity: sha512-9DdCqS/n2ncu/Chazvt3cpgAjAmIGQDz7hFKSrNItMApyV/Ja9mz3hD4JakIE3nS8PW9smEbPWnb389QLBY4nw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxfmt/binding-linux-arm-gnueabihf@0.45.0': - resolution: {integrity: sha512-hWL8Hdni+3U1mPFx1UtWeGp3tNb6EhBAUHRMbKUxVkOp3WwoJbpVO2bfUVbS4PfpledviXXNHSTl1veTa6FhkQ==} + '@oxfmt/binding-linux-arm-gnueabihf@0.46.0': + resolution: {integrity: sha512-Dgs7VeE2jT0LHMhw6tPEt0xQYe54kBqHEovmWsv4FVQlegCOvlIJNx0S8n4vj8WUtpT+Z6BD2HhKJPLglLxvZg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxfmt/binding-linux-arm-musleabihf@0.45.0': - resolution: {integrity: sha512-6Blt/0OBT7vvfQpqYuYbpbFLPqSiaYpEJzUUWhinPEuADypDbtV1+LdjM0vYBNGPvnj85ex7lTerEX6JGcPt9w==} + '@oxfmt/binding-linux-arm-musleabihf@0.46.0': + resolution: {integrity: sha512-Zxn3adhTH13JKnU4xXJj8FeEfF680XjXh3gSShKl57HCMBRde2tUJTgogV/1MSHA80PJEVrDa7r66TLVq3Ia7Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxfmt/binding-linux-arm64-gnu@0.45.0': - resolution: {integrity: sha512-jLjoLfe+hGfjhA8hNBSdw85yCA8ePKq7ME4T+g6P9caQXvmt6IhE2X7iVjnVdkmYUWEzZrxlh4p6RkDmAMJY/A==} + '@oxfmt/binding-linux-arm64-gnu@0.46.0': + resolution: {integrity: sha512-+TWipjrgVM8D7aIdDD0tlr3teLTTvQTn7QTE5BpT10H1Fj82gfdn9X6nn2sDgx/MepuSCfSnzFNJq2paLL0OiA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-arm64-musl@0.45.0': - resolution: {integrity: sha512-XQKXZIKYJC3GQJ8FnD3iMntpw69Wd9kDDK/Xt79p6xnFYlGGxSNv2vIBvRTDg5CKByWFWWZLCRDOXoP/m6YN4g==} + '@oxfmt/binding-linux-arm64-musl@0.46.0': + resolution: {integrity: sha512-aAUPBWJ1lGwwnxZUEDLJ94+Iy6MuwJwPxUgO4sCA5mEEyDk7b+cDQ+JpX1VR150Zoyd+D49gsrUzpUK5h587Eg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@oxfmt/binding-linux-ppc64-gnu@0.45.0': - resolution: {integrity: sha512-+g5RiG+xOkdrCWkKodv407nTvMq4vYM18Uox2MhZBm/YoqFxxJpWKsloskFFG5NU13HGPw1wzYjjOVcyd9moCA==} + '@oxfmt/binding-linux-ppc64-gnu@0.46.0': + resolution: {integrity: sha512-ufBCJukyFX/UDrokP/r6BGDoTInnsDs7bxyzKAgMiZlt2Qu8GPJSJ6Zm6whIiJzKk0naxA8ilwmbO1LMw6Htxw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-riscv64-gnu@0.45.0': - resolution: {integrity: sha512-V7dXKoSyEbWAkkSF4JJNtF+NJZDmJoSarSoP30WCsB3X636Rehd3CvxBj49FIJxEBFWhvcUjGSHVeU8Erck1bQ==} + '@oxfmt/binding-linux-riscv64-gnu@0.46.0': + resolution: {integrity: sha512-eqtlC2YmPqjun76R1gVfGLuKWx7NuEnLEAudZ7n6ipSKbCZTqIKSs1b5Y8K/JHZsRpLkeSmAAjig5HOIg8fQzQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-riscv64-musl@0.45.0': - resolution: {integrity: sha512-Vdelft1sAEYojVGgcODEFXSWYQYlIvoyIGWebKCuUibd1tvS1TjTx413xG2ZLuHpYj45CkN/ztMLMX6jrgqpgg==} + '@oxfmt/binding-linux-riscv64-musl@0.46.0': + resolution: {integrity: sha512-yccVOO2nMXkQLGgy0He3EQEwKD7NF0zEk+/OWmroznkqXyJdN6bfK0LtNnr6/14Bh3FjpYq7bP33l/VloCnxpA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] - '@oxfmt/binding-linux-s390x-gnu@0.45.0': - resolution: {integrity: sha512-RR7xKgNpqwENnK0aYCGYg0JycY2n93J0reNjHyes+I9Gq52dH95x+CBlnlAQHCPfz6FGnKA9HirgUl14WO6o7w==} + '@oxfmt/binding-linux-s390x-gnu@0.46.0': + resolution: {integrity: sha512-aAf7fG23OQCey6VRPj9IeCraoYtpgtx0ZyJ1CXkPyT1wjzBE7c3xtuxHe/AdHaJfVVb/SXpSk8Gl1LzyQupSqw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-x64-gnu@0.45.0': - resolution: {integrity: sha512-U/QQ0+BQNSHxjuXR/utvXnQ50Vu5kUuqEomZvQ1/3mhgbBiMc2WU9q5kZ5WwLp3gnFIx9ibkveoRSe2EZubkqg==} + '@oxfmt/binding-linux-x64-gnu@0.46.0': + resolution: {integrity: sha512-q0JPsTMyJNjYrBvYFDz4WbVsafNZaPCZv4RnFypRotLqpKROtBZcEaXQW4eb9YmvLU3NckVemLJnzkSZSdmOxw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-x64-musl@0.45.0': - resolution: {integrity: sha512-o5TLOUCF0RWQjsIS06yVC+kFgp092/yLe6qBGSUvtnmTVw9gxjpdQSXc3VN5Cnive4K11HNstEZF8ROKHfDFSw==} + '@oxfmt/binding-linux-x64-musl@0.46.0': + resolution: {integrity: sha512-7LsLY9Cw57GPkhSR+duI3mt9baRczK/DtHYSldQ4BEU92da9igBQNl4z7Vq5U9NNPsh1FmpKvv1q9WDtiUQR1A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@oxfmt/binding-openharmony-arm64@0.45.0': - resolution: {integrity: sha512-RnGcV3HgPuOjsGx/k9oyRNKmOp+NBLGzZTdPDYbc19r7NGeYPplnUU/BfU35bX2Y/O4ejvHxcfkvW2WoYL/gsg==} + '@oxfmt/binding-openharmony-arm64@0.46.0': + resolution: {integrity: sha512-lHiBOz8Duaku7JtRNLlps3j++eOaICPZSd8FCVmTDM4DFOPT71Bjn7g6iar1z7StXlKRweUKxWUs4sA+zWGDXg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxfmt/binding-win32-arm64-msvc@0.45.0': - resolution: {integrity: sha512-v3Vj7iKKsUFwt9w5hsqIIoErKVoENC6LoqfDlteOQ5QMDCXihlqLoxpmviUhXnNncg4zV6U9BPwlBbwa+qm4wg==} + '@oxfmt/binding-win32-arm64-msvc@0.46.0': + resolution: {integrity: sha512-/5ktYUliP89RhgC37DBH1x20U5zPSZMy3cMEcO0j3793rbHP9MWsknBwQB6eozRzWmYrh0IFM/p20EbPvDlYlg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxfmt/binding-win32-ia32-msvc@0.45.0': - resolution: {integrity: sha512-N8yotPBX6ph0H3toF4AEpdCeVPrdcSetj+8eGiZGsrLsng3bs/Q5HPu4bbSxip5GBPx5hGbGHrZwH4+rcrjhHA==} + '@oxfmt/binding-win32-ia32-msvc@0.46.0': + resolution: {integrity: sha512-3WTnoiuIr8XvV0DIY7SN+1uJSwKf4sPpcbHfobcRT9JutGcLaef/miyBB87jxd3aqH+mS0+G5lsgHuXLUwjjpQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxfmt/binding-win32-x64-msvc@0.45.0': - resolution: {integrity: sha512-w5MMTRCK1dpQeRA+HHqXQXyN33DlG/N2LOYxJmaT4fJjcmZrbNnqw7SmIk7I2/a2493PPLZ+2E/Ar6t2iKVMug==} + '@oxfmt/binding-win32-x64-msvc@0.46.0': + resolution: {integrity: sha512-IXxiQpkYnOwNfP23vzwSfhdpxJzyiPTY7eTn6dn3DsriKddESzM8i6kfq9R7CD/PUJwCvQT22NgtygBeug3KoA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@oxlint-tsgolint/darwin-arm64@0.21.1': - resolution: {integrity: sha512-7TLjyWe4wG9saJc992VWmaHq2hwKfOEEVTjheReXJXaDhavMZI4X9a6nKhbEng4IVkYtzjD2jw16vw2WFXLYLw==} + '@oxlint-tsgolint/darwin-arm64@0.22.0': + resolution: {integrity: sha512-/exgXceakHbQrzaHTtKOe7MuDATaWMCCWpsCDQCZKeYhLGXzComipTrCYnHzAXrdnNBb5r5K+RRf5A6ormrhMA==} cpu: [arm64] os: [darwin] - '@oxlint-tsgolint/darwin-x64@0.21.1': - resolution: {integrity: sha512-7wf9Wf75nTzA7zpL9myhFe2RKvfuqGUOADNvUooCjEWvh7hmPz3lSEqTMh5Z/VQhzsG04mM9ACyghxhRzq7zFw==} + '@oxlint-tsgolint/darwin-x64@0.22.0': + resolution: {integrity: sha512-xFGdIahlmUbK+/MpZ5y08D0ewMGLDbd2Vki5wxVFYg50lSrtgPAtdDl+kqKZLNaFu0zpMar8n9wv1le05sL/jw==} cpu: [x64] os: [darwin] - '@oxlint-tsgolint/linux-arm64@0.21.1': - resolution: {integrity: sha512-IPuQN/Vd0Rjklg/cCGBbQyUuRBp2f6LQXpZYwk5ivOR6V/+CgiYsv8pn/PVY7gjeyoNvPQrXB7xMjHUO2YZbdw==} + '@oxlint-tsgolint/linux-arm64@0.22.0': + resolution: {integrity: sha512-53RvC9f77eUo+V1dfQNwGVnsIfPJFMibRR0ee128EUpYNDOZe/ojmCfuXJeU7cY91V7r7fZSm42KPJocXUX8og==} cpu: [arm64] os: [linux] - '@oxlint-tsgolint/linux-x64@0.21.1': - resolution: {integrity: sha512-d1niGuTbh2qiv7dR7tqkbOcM5cIR63of0lMBFdEQavL1KrJV8zuRdwdi68K7MNGdgoR+J5A9ajpGGvsHwp1bPg==} + '@oxlint-tsgolint/linux-x64@0.22.0': + resolution: {integrity: sha512-evZcJAZ9hjNyuN69RnXwbt+U2pAOcYt+yvqukgugiCkRm4iBZ0R0CvpY1tgfG2XcGUhEPh8dljO+nPZTEVGpCQ==} cpu: [x64] os: [linux] - '@oxlint-tsgolint/win32-arm64@0.21.1': - resolution: {integrity: sha512-ICu9y2JLnFPvFqstnWPPNqBM8LK8BWw2OTeaR0UgEMm4hOSbrZAKv1/hwZYyiLqnCNjBL87AGSQIgTHCYlsipw==} + '@oxlint-tsgolint/win32-arm64@0.22.0': + resolution: {integrity: sha512-7jTO+k1mr5BxRAI2fxc1NRcE3MAbHNZ0Vef9SD1yAR6d1E6qEv5D/D7yuHpQpw6AO3qoecSVo2Jzr+JirN61+w==} cpu: [arm64] os: [win32] - '@oxlint-tsgolint/win32-x64@0.21.1': - resolution: {integrity: sha512-cTEFCFjCj6iXfrSHcvajSPNqhEA4TxSzU3gFxbdGSAUTNXGToU99IbdhWAPSbhcucoym0XE4Zl7E41NiSkNTug==} + '@oxlint-tsgolint/win32-x64@0.22.0': + resolution: {integrity: sha512-7lbl9XFcqO+scsynxMzTQdl0XUe6sBUCyY/oGWvCB+JmV4U+70vzSyZJdTEzzxtkZiNnUVFFh9RJLmoiQSne+w==} cpu: [x64] os: [win32] - '@oxlint/binding-android-arm-eabi@1.60.0': - resolution: {integrity: sha512-YdeJKaZckDQL1qa62a1aKq/goyq48aX3yOxaaWqWb4sau4Ee4IiLbamftNLU3zbePky6QsDj6thnSSzHRBjDfA==} + '@oxlint/binding-android-arm-eabi@1.61.0': + resolution: {integrity: sha512-6eZBPgiigK5txqoVgRqxbaxiom4lM8AP8CyKPPvpzKnQ3iFRFOIDc+0AapF+qsUSwjOzr5SGk4SxQDpQhkSJMQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxlint/binding-android-arm64@1.60.0': - resolution: {integrity: sha512-7ANS7PpXCfq84xZQ8E5WPs14gwcuPcl+/8TFNXfpSu0CQBXz3cUo2fDpHT8v8HJN+Ut02eacvMAzTnc9s6X4tw==} + '@oxlint/binding-android-arm64@1.61.0': + resolution: {integrity: sha512-CkwLR69MUnyv5wjzebvbbtTSUwqLxM35CXE79bHqDIK+NtKmPEUpStTcLQRZMCo4MP0qRT6TXIQVpK0ZVScnMA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxlint/binding-darwin-arm64@1.60.0': - resolution: {integrity: sha512-pJsgd9AfplLGBm1fIr25V6V14vMrayhx4uIQvlfH7jWs2SZwSrvi3TfgfJySB8T+hvyEH8K2zXljQiUnkgUnfQ==} + '@oxlint/binding-darwin-arm64@1.61.0': + resolution: {integrity: sha512-8JbefTkbmvqkqWjmQrHke+MdpgT2UghhD/ktM4FOQSpGeCgbMToJEKdl9zwhr/YWTl92i4QI1KiTwVExpcUN8A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxlint/binding-darwin-x64@1.60.0': - resolution: {integrity: sha512-Ue1aXHX49ivwflKqGJc7zcd/LeLgbhaTcDCQStgx5x06AXgjEAZmvrlMuIkWd4AL4FHQe6QJ9f33z04Cg448VQ==} + '@oxlint/binding-darwin-x64@1.61.0': + resolution: {integrity: sha512-uWpoxDT47hTnDLcdEh5jVbso8rlTTu5o0zuqa9J8E0JAKmIWn7kGFEIB03Pycn2hd2vKxybPGLhjURy/9We5FQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxlint/binding-freebsd-x64@1.60.0': - resolution: {integrity: sha512-YCyQzsQtusQw+gNRW9rRTifSO+Dt/+dtCl2NHoDMZqJlRTEZ/Oht9YnuporI9yiTx7+cB+eqzX3MtHHVHGIWhg==} + '@oxlint/binding-freebsd-x64@1.61.0': + resolution: {integrity: sha512-K/o4hEyW7flfMel0iBVznmMBt7VIMHGdjADocHKpK1DUF9erpWnJ+BSSWd2W0c8K3mPtpph+CuHzRU6CI3l9jQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxlint/binding-linux-arm-gnueabihf@1.60.0': - resolution: {integrity: sha512-c7dxM2Zksa45Qw16i2iGY3Fti2NirJ38FrsBsKw+qcJ0OtqTsBgKJLF0xV+yLG56UH01Z8WRPgsw31e0MoRoGQ==} + '@oxlint/binding-linux-arm-gnueabihf@1.61.0': + resolution: {integrity: sha512-P6040ZkcyweJ0Po9yEFqJCdvZnf3VNCGs1SIHgXDf8AAQNC6ID/heXQs9iSgo2FH7gKaKq32VWc59XZwL34C5Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm-musleabihf@1.60.0': - resolution: {integrity: sha512-ZWALoA42UYqBEP1Tbw9OWURgFGS1nWj2AAvLdY6ZcGx/Gj93qVCBKjcvwXMupZibYwFbi9s/rzqkZseb/6gVtQ==} + '@oxlint/binding-linux-arm-musleabihf@1.61.0': + resolution: {integrity: sha512-bwxrGCzTZkuB+THv2TQ1aTkVEfv5oz8sl+0XZZCpoYzErJD8OhPQOTA0ENPd1zJz8QsVdSzSrS2umKtPq4/JXg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm64-gnu@1.60.0': - resolution: {integrity: sha512-tpy+1w4p9hN5CicMCxqNy6ymfRtV5ayE573vFNjp1k1TN/qhLFgflveZoE/0++RlkHikBz2vY545NWm/hp7big==} + '@oxlint/binding-linux-arm64-gnu@1.61.0': + resolution: {integrity: sha512-vkhb9/wKguMkLlrm3FoJW/Xmdv31GgYAE+x8lxxQ+7HeOxXUySI0q36a3NTVIuQUdLzxCI1zzMGsk1o37FOe3w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-arm64-musl@1.60.0': - resolution: {integrity: sha512-eDYDXZGhQAXyn6GwtwiX/qcLS0HlOLPJ/+iiIY8RYr+3P8oKBmgKxADLlniL6FtWfE7pPk7IGN9/xvDEvDvFeg==} + '@oxlint/binding-linux-arm64-musl@1.61.0': + resolution: {integrity: sha512-bl1dQh8LnVqsj6oOQAcxwbuOmNJkwc4p6o//HTBZhNTzJy21TLDwAviMqUFNUxDHkPGpmdKTSN4tWTjLryP8xg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@oxlint/binding-linux-ppc64-gnu@1.60.0': - resolution: {integrity: sha512-nxehly5XYBHUWI9VJX1bqCf9j/B43DaK/aS/T1fcxCpX3PA4Rm9BB54nPD1CKayT8xg6REN1ao+01hSRNgy8OA==} + '@oxlint/binding-linux-ppc64-gnu@1.61.0': + resolution: {integrity: sha512-QoOX6KB2IiEpyOj/HKqaxi+NQHPnOgNgnr22n9N4ANJCzXkUlj1UmeAbFb4PpqdlHIzvGDM5xZ0OKtcLq9RhiQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-riscv64-gnu@1.60.0': - resolution: {integrity: sha512-j1qf/NaUfOWQutjeoooNG1Q0zsK0XGmSu1uDLq3cctquRF3j7t9Hxqf/76ehCc5GEUAanth2W4Fa+XT1RFg/nw==} + '@oxlint/binding-linux-riscv64-gnu@1.61.0': + resolution: {integrity: sha512-1TGcTerjY6p152wCof3oKElccq3xHljS/Mucp04gV/4ATpP6nO7YNnp7opEg6SHkv2a57/b4b8Ndm9znJ1/qAw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-riscv64-musl@1.60.0': - resolution: {integrity: sha512-YELKPRefQ/q/h3RUmeRfPCUhh2wBvgV1RyZ/F9M9u8cDyXsQW2ojv1DeWQTt466yczDITjZnIOg/s05pk7Ve2A==} + '@oxlint/binding-linux-riscv64-musl@1.61.0': + resolution: {integrity: sha512-65wXEmZIrX2ADwC8i/qFL4EWLSbeuBpAm3suuX1vu4IQkKd+wLT/HU/BOl84kp91u2SxPkPDyQgu4yrqp8vwVA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] - '@oxlint/binding-linux-s390x-gnu@1.60.0': - resolution: {integrity: sha512-JkO3C6Gki7Y6h/MiIkFKvHFOz98/YWvQ4WYbK9DLXACMP2rjULzkeGyAzorJE5S1dzLQGFgeqvN779kSFwoV1g==} + '@oxlint/binding-linux-s390x-gnu@1.61.0': + resolution: {integrity: sha512-TVvhgMvor7Qa6COeXxCJ7ENOM+lcAOGsQ0iUdPSCv2hxb9qSHLQ4XF1h50S6RE1gBOJ0WV3rNukg4JJJP1LWRA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@oxlint/binding-linux-x64-gnu@1.60.0': - resolution: {integrity: sha512-XjKHdFVCpZZZSWBCKyyqCq65s2AKXykMXkjLoKYODrD+f5toLhlwsMESscu8FbgnJQ4Y/dpR/zdazsahmgBJIA==} + '@oxlint/binding-linux-x64-gnu@1.61.0': + resolution: {integrity: sha512-SjpS5uYuFoDnDdZPwZE59ndF95AsY47R5MliuneTWR1pDm2CxGJaYXbKULI71t5TVfLQUWmrHEGRL9xvuq6dnA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-x64-musl@1.60.0': - resolution: {integrity: sha512-js29ZWIuPhNWzY8NC7KoffEMEeWG105vbmm+8EOJsC+T/jHBiKIJEUF78+F/IrgEWMMP9N0kRND4Pp75+xAhKg==} + '@oxlint/binding-linux-x64-musl@1.61.0': + resolution: {integrity: sha512-gGfAeGD4sNJGILZbc/yKcIimO9wQnPMoYp9swAaKeEtwsSQAbU+rsdQze5SBtIP6j0QDzeYd4XSSUCRCF+LIeQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@oxlint/binding-openharmony-arm64@1.60.0': - resolution: {integrity: sha512-H+PUITKHk04stFpWj3x3Kg08Afp/bcXSBi0EhasR5a0Vw7StXHTzdl655PUI0fB4qdh2Wsu6Dsi+3ACxPoyQnA==} + '@oxlint/binding-openharmony-arm64@1.61.0': + resolution: {integrity: sha512-OlVT0LrG/ct33EVtWRyR+B/othwmDWeRxfi13wUdPeb3lAT5TgTcFDcfLfarZtzB4W1nWF/zICMgYdkggX2WmQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxlint/binding-win32-arm64-msvc@1.60.0': - resolution: {integrity: sha512-WA/yc7f7ZfCefBXVzNHn1Ztulb1EFwNBb4jMZ6pjML0zz6pHujlF3Q3jySluz3XHl/GNeMTntG1seUBWVMlMag==} + '@oxlint/binding-win32-arm64-msvc@1.61.0': + resolution: {integrity: sha512-vI//NZPJk6DToiovPtaiwD4iQ7kO1r5ReWQD0sOOyKRtP3E2f6jxin4uvwi3OvDzHA2EFfd7DcZl5dtkQh7g1w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxlint/binding-win32-ia32-msvc@1.60.0': - resolution: {integrity: sha512-33YxL1sqwYNZXtn3MD/4dno6s0xeedXOJlT1WohkVD565WvohClZUr7vwKdAk954n4xiEWJkewiCr+zLeq7AeA==} + '@oxlint/binding-win32-ia32-msvc@1.61.0': + resolution: {integrity: sha512-0ySj4/4zd2XjePs3XAQq7IigIstN4LPQZgCyigX5/ERMLjdWAJfnxcTsrtxZxuij8guJW8foXuHmhGxW0H4dDA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxlint/binding-win32-x64-msvc@1.60.0': - resolution: {integrity: sha512-JOro4ZcfBLamJCyfURQmOQByoorgOdx3ZjAkSqnb/CyG/i+lN3KoV5LAgk5ZAW6DPq7/Cx7n23f8DuTWXTWgyQ==} + '@oxlint/binding-win32-x64-msvc@1.61.0': + resolution: {integrity: sha512-0xgSiyeqDLDZxXoe9CVJrOx3TUVsfyoOY7cNi03JbItNcC9WCZqrSNdrAbHONxhSPaVh/lzfnDcON1RqSUMhHw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -3812,8 +3784,8 @@ packages: engines: {node: '>=18'} hasBin: true - '@tanstack/eslint-plugin-query@5.100.5': - resolution: {integrity: sha512-WKt+xyxvMQkUL4sqMQ8l3gzCplNi9HedVQN32WmBJYKITJ9a5r3H5cpICp8y96V8ZL5rZH0EZRgpO6sy8fAgrQ==} + '@tanstack/eslint-plugin-query@5.100.6': + resolution: {integrity: sha512-dZ2cUFe4OTTf2hLWa7la8oyj7AivK7JDecCDhUnxdAAedkn1YOL2PDr+IFF93h43zwUG2BvnFXiO59shwijyIg==} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: ^5.4.0 || ^6.0.0 @@ -3833,11 +3805,11 @@ packages: resolution: {integrity: sha512-y/xtNPNt/YeyoVxE/JCx+T7yjEzpezmbb+toK8DDD1P4m7Kzs5YR956+7OKexG3f8aXgC3rLZl7b1V+yNUSy5w==} engines: {node: '>=18'} - '@tanstack/query-core@5.100.5': - resolution: {integrity: sha512-t20KrhKkf0HXzqQkPbJ5erhFesup68BAbwFgYmTrS7bxMF7O5MdmL8jUkik4thsG7Hg00fblz30h6yF1d5TxGg==} + '@tanstack/query-core@5.100.6': + resolution: {integrity: sha512-Os2CPUr98to98RYm+D4qGqGkiffn7MGSyl2547a4MljVkHE30AMJRqTiyCqBfMwzAx/I91vCkAxp5tHSla6Twg==} - '@tanstack/query-devtools@5.100.5': - resolution: {integrity: sha512-SuCkVCqqliRYJvm+LEL2U/TcFv92zTnHj6OGrJFHp1v/RsiwamI+ZDgQzbeUrLsJb8/Nj/52aIw0NyDMcVHl4A==} + '@tanstack/query-devtools@5.100.6': + resolution: {integrity: sha512-2SiNwlOiAdTbqktCSmwlXZH8x8mckSbES2O0bdr3qZNhdQl5DCtImZx0S3HGeNHWTIkzTaHx2Isg+bD4M3WRIg==} '@tanstack/react-devtools@0.10.2': resolution: {integrity: sha512-1BmZyxOrI5SqmRJ5MgkYZNNdnlLsJxQRI2YgorrAvcF2MxK6x5RcuStvD8+YlXoMw3JtNukPxoITirKAnKYDQA==} @@ -3862,14 +3834,14 @@ packages: '@tanstack/react-start': optional: true - '@tanstack/react-query-devtools@5.100.5': - resolution: {integrity: sha512-bItQERx7dJoiI0WEoS4tIrvNnmk4kUYsaQLdIpm4o9Kttmsi5B6xlY6JBDkavstR3hH/R2+VT5dr3L5LBFPW4g==} + '@tanstack/react-query-devtools@5.100.6': + resolution: {integrity: sha512-sz3ksMKA2t1rx0+Odzb0x1A3pXH/SVf7fzlzd3sKXzwXz8980f5sbOwfQD6+UfTG8G4Y2KaIg9e3sBn+uC4VTg==} peerDependencies: - '@tanstack/react-query': ^5.100.5 + '@tanstack/react-query': ^5.100.6 react: ^18 || ^19 - '@tanstack/react-query@5.100.5': - resolution: {integrity: sha512-aNwj1mi2v2bQ9IxkyR1grLOUkv3BYWoykHy9KDyLNbjC3tsahbOHJibK+Wjtr1wRhG59/AvJhiJG5OlthaCgJA==} + '@tanstack/react-query@5.100.6': + resolution: {integrity: sha512-uVSrps0PV16Cxmcn2rvL+dUhwTpTUtiRW347AEeYxMZXO2pZe9ja7E24PAMGoQ5u2g89DD8u4QhOviBk+RN8RA==} peerDependencies: react: ^18 || ^19 @@ -3924,18 +3896,20 @@ packages: peerDependencies: '@testing-library/dom': '>=7.21.4' - '@tsslint/cli@3.0.4': - resolution: {integrity: sha512-jvSYZEJKhDp02CyvLe7thGYp/uMW860kC8hDIMnZAGp3JMDkM2dU1kl550li4qiYXFkS8v5AU1nR2RyIn3khvw==} + '@tsslint/cli@3.1.0': + resolution: {integrity: sha512-SbcBbjRyRTXWjuyXccSLjIx2TWdhQFOMPDaqdLbW8dvh/A53pAWkimENKTvEL5gpGc0aulQ2Qt0icd+TxJQiRA==} engines: {node: '>=22.6.0'} hasBin: true peerDependencies: typescript: '*' - '@tsslint/compat-eslint@3.0.4': - resolution: {integrity: sha512-zWurlYWaSfK62uf5n7GMa0C7pcYOXbYjMeBfd3w0RmCZzk5gBhNSJdSNXNmbDXUuM/3RH03PpqHuUIktCGB52g==} + '@tsslint/compat-eslint@3.1.0': + resolution: {integrity: sha512-1gD9G9WH/KlSW3JVG6ahoMoWUy5GZqhFU2RqBOIpjw2vdDwhF+4v1PC6uMJW6LDem/FVoULiMMF9V8vKiX9Uuw==} + peerDependencies: + typescript: '*' - '@tsslint/config@3.0.4': - resolution: {integrity: sha512-2VfGdG35wrcosUxxsoUD46LOI1lEJWhQFpDROhos2JOwwVPIQqp66hl9MOYjkBpt8zYVWvdcDWIOIT9QIpDL3A==} + '@tsslint/config@3.1.0': + resolution: {integrity: sha512-FVoIycFczf1mccZrxOpkknciSpjoWD1o5Yw5CVvsddXz4/A5q6RbWU/QD7kcXpm8Yukw+3eMSKb1/NNKZ0Mmzw==} engines: {node: '>=22.6.0'} hasBin: true peerDependencies: @@ -3947,12 +3921,12 @@ packages: tsl: optional: true - '@tsslint/core@3.0.4': - resolution: {integrity: sha512-hzvO/8zZfds9k7ZREyE5h2pnKkukZsAD81F7rq/k9AOv//Wmi2OxXyxmhmv98/ZoieOK5nSrrzh8+mh7GtkrEw==} + '@tsslint/core@3.1.0': + resolution: {integrity: sha512-WO9sL4nfYme+3u27DLMHG/abooGMTJb54b8CVS8YSJj6ldMax764mHpiaNHf48jGjWN/pbAoC47pnErwFL022w==} engines: {node: '>=22.6.0'} - '@tsslint/types@3.0.4': - resolution: {integrity: sha512-z/LXFUSGCxrh/WfkVmlyRwCVjAr2H1/v6EDvVTuXX/3ZEO+Ss9UqgEGgnTnQn3TLSLJa2pEaIY3Hsz0Y9TsuyA==} + '@tsslint/types@3.1.0': + resolution: {integrity: sha512-y21o32pnDktikkRAfYCHu3bYplxyMo8dwhbBVgSyvFXJfvnc0S7K4c6gZypqSWYPzBRXHQ+sQnJ8oM9xGcwWUw==} '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} @@ -4174,11 +4148,11 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/eslint-plugin@8.59.0': - resolution: {integrity: sha512-HyAZtpdkgZwpq8Sz3FSUvCR4c+ScbuWa9AksK2Jweub7w4M3yTz4O11AqVJzLYjy/B9ZWPyc81I+mOdJU/bDQw==} + '@typescript-eslint/eslint-plugin@8.59.1': + resolution: {integrity: sha512-BOziFIfE+6osHO9FoJG4zjoHUcvI7fTNBSpdAwrNH0/TLvzjsk2oo8XSSOT2HhqUyhZPfHv4UOffoJ9oEEQ7Ag==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.59.0 + '@typescript-eslint/parser': ^8.59.1 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' @@ -4189,8 +4163,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.59.0': - resolution: {integrity: sha512-TI1XGwKbDpo9tRW8UDIXCOeLk55qe9ZFGs8MTKU6/M08HWTw52DD/IYhfQtOEhEdPhLMT26Ka/x7p70nd3dzDg==} + '@typescript-eslint/parser@8.59.1': + resolution: {integrity: sha512-HDQH9O/47Dxi1ceDhBXdaldtf/WV9yRYMjbjCuNk3qnaTD564qwv61Y7+gTxwxRKzSrgO5uhtw584igXVuuZkA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -4208,6 +4182,12 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/project-service@8.59.1': + resolution: {integrity: sha512-+MuHQlHiEr00Of/IQbE/MmEoi44znZHbR/Pz7Opq4HryUOlRi+/44dro9Ycy8Fyo+/024IWtw8m4JUMCGTYxDg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/scope-manager@8.58.2': resolution: {integrity: sha512-SgmyvDPexWETQek+qzZnrG6844IaO02UVyOLhI4wpo82dpZJY9+6YZCKAMFzXb7qhx37mFK1QcPQ18tud+vo6Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4216,6 +4196,10 @@ packages: resolution: {integrity: sha512-UzR16Ut8IpA3Mc4DbgAShlPPkVm8xXMWafXxB0BocaVRHs8ZGakAxGRskF7FId3sdk9lgGD73GSFaWmWFDE4dg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/scope-manager@8.59.1': + resolution: {integrity: sha512-LwuHQI4pDOYVKvmH2dkaJo6YZCSgouVgnS/z7yBPKBMvgtBvyLqiLy9Z6b7+m/TRcX1NFYUqZetI5Y+aT4GEfg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/tsconfig-utils@8.58.2': resolution: {integrity: sha512-3SR+RukipDvkkKp/d0jP0dyzuls3DbGmwDpVEc5wqk5f38KFThakqAAO0XMirWAE+kT00oTauTbzMFGPoAzB0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4228,6 +4212,12 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/tsconfig-utils@8.59.1': + resolution: {integrity: sha512-/0nEyPbX7gRsk0Uwfe4ALwwgxuA66d/l2mhRDNlAvaj4U3juhUtJNq0DsY8M2AYwwb9rEq2hrC3IcIcEt++iJA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/type-utils@8.58.2': resolution: {integrity: sha512-Z7EloNR/B389FvabdGeTo2XMs4W9TjtPiO9DAsmT0yom0bwlPyRjkJ1uCdW1DvrrrYP50AJZ9Xc3sByZA9+dcg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4235,8 +4225,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.59.0': - resolution: {integrity: sha512-3TRiZaQSltGqGeNrJzzr1+8YcEobKH9rHnqIp/1psfKFmhRQDNMGP5hBufanYTGznwShzVLs3Mz+gDN7HkWfXg==} + '@typescript-eslint/type-utils@8.59.1': + resolution: {integrity: sha512-klWPBR2ciQHS3f++ug/mVnWKPjBUo7icEL3FAO1lhAR1Z1i5NQYZ1EannMSRYcq5qCv5wNALlXr6fksRHyYl7w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -4250,6 +4240,10 @@ packages: resolution: {integrity: sha512-nLzdsT1gdOgFxxxwrlNVUBzSNBEEHJ86bblmk4QAS6stfig7rcJzWKqCyxFy3YRRHXDWEkb2NralA1nOYkkm/A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.59.1': + resolution: {integrity: sha512-ZDCjgccSdYPw5Bxh+my4Z0lJU96ZDN7jbBzvmEn0FZx3RtU1C7VWl6NbDx94bwY3V5YsgwRzJPOgeY2Q/nLG8A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@8.58.2': resolution: {integrity: sha512-ELGuoofuhhoCvNbQjFFiobFcGgcDCEm0ThWdmO4Z0UzLqPXS3KFvnEZ+SHewwOYHjM09tkzOWXNTv9u6Gqtyuw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4262,6 +4256,12 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/typescript-estree@8.59.1': + resolution: {integrity: sha512-OUd+vJS05sSkOip+BkZ/2NS8RMxrAAJemsC6vU3kmfLyeaJT0TftHkV9mcx2107MmsBVXXexhVu4F0TZXyMl4g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/utils@8.58.2': resolution: {integrity: sha512-QZfjHNEzPY8+l0+fIXMvuQ2sJlplB4zgDZvA+NmvZsZv3EQwOcc1DuIU1VJUTWZ/RKouBMhDyNaBMx4sWvrzRA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4276,6 +4276,13 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/utils@8.59.1': + resolution: {integrity: sha512-3pIeoXhCeYH9FSCBI8P3iNwJlGuzPlYKkTlen2O9T1DSeeg8UG8jstq6BLk+Mda0qup7mgk4z4XL4OzRaxZ8LA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + '@typescript-eslint/visitor-keys@8.58.2': resolution: {integrity: sha512-f1WO2Lx8a9t8DARmcWAUPJbu0G20bJlj8L4z72K00TMeJAoyLr/tHhI/pzYBLrR4dXWkcxO1cWYZEOX8DKHTqA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4284,50 +4291,54 @@ packages: resolution: {integrity: sha512-/uejZt4dSere1bx12WLlPfv8GktzcaDtuJ7s42/HEZ5zGj9oxRaD4bj7qwSunXkf+pbAhFt2zjpHYUiT5lHf0Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260426.1': - resolution: {integrity: sha512-HzGvERpIFO7p6pMljPN1fIOHqAv2oMeVIqYLSt27TKILkTRpe7fANW3R2OAM+/A+pLtYNNXGDbKl/wR+DHz9KA==} + '@typescript-eslint/visitor-keys@8.59.1': + resolution: {integrity: sha512-LdDNl6C5iJExcM0Yh0PwAIBb9PrSiCsWamF/JyEZawm3kFDnRoaq3LGE4bpyRao/fWeGKKyw7icx0YxrLFC5Cg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260428.1': + resolution: {integrity: sha512-Lll6WmXfgTEj1G3QBIoHlabQwUtJiyhlRgSLksa06QFL5BoA7V+Lu1waa9PtPNZbGsXLDMHodtk/bRQABKuPiw==} engines: {node: '>=16.20.0'} cpu: [arm64] os: [darwin] - '@typescript/native-preview-darwin-x64@7.0.0-dev.20260426.1': - resolution: {integrity: sha512-aE17wCPNQ09K4jV7TQYYRYF/Q/6nFS9jLpbyTYHtS+i+0yV1Rrs4VsqboisS1R/iSWsq3m1Yhh3uS4x3/9KUkg==} + '@typescript/native-preview-darwin-x64@7.0.0-dev.20260428.1': + resolution: {integrity: sha512-WbsBNSHlo+4sGrTxDWdmI7r8x48tCtSCuKdmK62FvVOq58UWAs6sL13Z4Rev4ohLcGHdXC5E/8AIdpLPqDYQpw==} engines: {node: '>=16.20.0'} cpu: [x64] os: [darwin] - '@typescript/native-preview-linux-arm64@7.0.0-dev.20260426.1': - resolution: {integrity: sha512-6OfhODChD1N6FX+ITzA1lny3WX6uew/Nw9kN7uWhymXlM3/vE0qtaAfsMpgdHdCbTPgcdpGaNFhbcMieju9Vdg==} + '@typescript/native-preview-linux-arm64@7.0.0-dev.20260428.1': + resolution: {integrity: sha512-cgcBX/ZBMdepkamLT8g8jQdHe7DZS/s6zTZRof6mvcrnJHlMeUnKoC9UO8/c22IrUMV3n0XPh7R8FYjUP0ll+Q==} engines: {node: '>=16.20.0'} cpu: [arm64] os: [linux] - '@typescript/native-preview-linux-arm@7.0.0-dev.20260426.1': - resolution: {integrity: sha512-/XJRC8B6JeOOb2/iek/BrzW4r5Nut+fkucG7ntEOQn63IRTsfP+AfJdJodG1VIwXOleNlFgG4RtYTUsvcbDJhg==} + '@typescript/native-preview-linux-arm@7.0.0-dev.20260428.1': + resolution: {integrity: sha512-/d/NnZFvEJU67L5mHh+cO3gsfwNCvJ9HGtxGq1KGz1VwTabOIcwLdpTpfsAR39WXzzfh9GJHL28n6GSGZInPow==} engines: {node: '>=16.20.0'} cpu: [arm] os: [linux] - '@typescript/native-preview-linux-x64@7.0.0-dev.20260426.1': - resolution: {integrity: sha512-KPDpjmLo/4xY8ugfMGFm7Ona/1igPzZveLt/C0rb6/jNPYuShumRfKYnItGDRXBlmecJY/04lrqkWqQjhtSSPg==} + '@typescript/native-preview-linux-x64@7.0.0-dev.20260428.1': + resolution: {integrity: sha512-4gJCE7wzenx1BH2Vtx2uKWUo8rFxnhGkxNEH1zxbYy/6ASwo+PnOPYmKHAzNE1C3yB5lzw71/vR5p5zyO57Y4A==} engines: {node: '>=16.20.0'} cpu: [x64] os: [linux] - '@typescript/native-preview-win32-arm64@7.0.0-dev.20260426.1': - resolution: {integrity: sha512-I7ThiopxuNKX/iAcwgMwsm6L32GOwmwLOyPwQmXjh5c3VD2acq3FYyZRDJVk0aUUy1w6bTbODlo5ZHoPnlZtvw==} + '@typescript/native-preview-win32-arm64@7.0.0-dev.20260428.1': + resolution: {integrity: sha512-yn6Rzbn62L4QTWrp0QgG8al6l/VG7PCPRdbE0vuGDSlKhInlC+Flo4QSc1qA8KHTbpHgl+nEsq9DymiitI4G4g==} engines: {node: '>=16.20.0'} cpu: [arm64] os: [win32] - '@typescript/native-preview-win32-x64@7.0.0-dev.20260426.1': - resolution: {integrity: sha512-4624MJq72vN4H1msiWVBqAIyerJRi5Ni/U6eeE1A1Opqg4c4QoalYQQ+5h5RIuaZ6rY+9kvUn+SjsvbZwyLbjQ==} + '@typescript/native-preview-win32-x64@7.0.0-dev.20260428.1': + resolution: {integrity: sha512-T9z13mcMowXmwGjprA2FIR2EEdYZxgqH8+qk7dFZVBlo5vfk41AN/qJfAdN7IsAhEb640MJ8cMN/aiczweZKmA==} engines: {node: '>=16.20.0'} cpu: [x64] os: [win32] - '@typescript/native-preview@7.0.0-dev.20260426.1': - resolution: {integrity: sha512-zE7B6TIG4XDYr4Your5E2Bxm1vD2YiPyD8OFG4nD5Odt/uN6gO0Y+T4TIbtGUBmOftMRqEV2Jw1ZC4ka0my1yw==} + '@typescript/native-preview@7.0.0-dev.20260428.1': + resolution: {integrity: sha512-JiM4PYWDGs57TT0mV2KArmaW7BnTkk3XRid79NdG17tfvDbRyg4hBCpKI7vARiQPtxjKrHlxyzxOGDpv5W5T7Q==} engines: {node: '>=16.20.0'} hasBin: true @@ -4435,13 +4446,13 @@ packages: '@vitest/utils@4.1.5': resolution: {integrity: sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug==} - '@voidzero-dev/vite-plus-core@0.1.19': - resolution: {integrity: sha512-BTmz50juSDolIN4Vtu5iVaPONV1XSrMB5V+9IoBhhxdogfvp7PBhaHuAcPjTN2RTVowhLZXoo8mn+aHjq//bkw==} + '@voidzero-dev/vite-plus-core@0.1.20': + resolution: {integrity: sha512-4KmzRfzwTeG3JuvDijrdqWusSgRvLMKDPrVsDdtbDVVjEMq0VnM8lSH+Nvepd6Pg+SuSVUP212OIfH/3Yn1bfA==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: '@arethetypeswrong/core': ^0.18.1 - '@tsdown/css': 0.21.9 - '@tsdown/exe': 0.21.9 + '@tsdown/css': 0.21.10 + '@tsdown/exe': 0.21.10 '@types/node': ^20.19.0 || >=22.12.0 '@vitejs/devtools': ^0.1.0 esbuild: 0.27.2 @@ -4495,56 +4506,56 @@ packages: yaml: optional: true - '@voidzero-dev/vite-plus-darwin-arm64@0.1.19': - resolution: {integrity: sha512-6MY/RiaRXKJ6wD/ftZnf+ohEqU68zHp3bVWetIw9dakcPL7TXoiIkDoechmZXCh+5eqxehvap4eh2eNEvWSM1Q==} + '@voidzero-dev/vite-plus-darwin-arm64@0.1.20': + resolution: {integrity: sha512-ykCOJk91h0IEMvljYGTauI4Svxr/CatZAitofvtEFqaTCLE3n06QCHD8qWphMM784VnPz1G/J2xuewxbQduNlg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@voidzero-dev/vite-plus-darwin-x64@0.1.19': - resolution: {integrity: sha512-jV6ygWCarMFW5DRqRyFkB2jpRDiAlLYzyQu0HZfYNoxfdNyO7isfuR5X6gV+ji7J3Kp0RZOiGrQUCjxTPqZg5w==} + '@voidzero-dev/vite-plus-darwin-x64@0.1.20': + resolution: {integrity: sha512-5XxNW9cYEh85Z4BErALyWh/tLP/NZmxNXzUQ0FanhHreI2Zq7FfgbSqQNvC7/sYsPYTWf74RlxmIjzV7R/Lb5Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@voidzero-dev/vite-plus-linux-arm64-gnu@0.1.19': - resolution: {integrity: sha512-jIWMgAok77aDuTK2kCQXn4Zp7pnUM56BvKhHCvnAmsF4yrs1KLQfH6YOdQMnVbNjQDneQgqdwHVDnkOfJRokYw==} + '@voidzero-dev/vite-plus-linux-arm64-gnu@0.1.20': + resolution: {integrity: sha512-Mc7npPBd9t/h0haURVCZGae+TfB0Yx2Ex8HbPKOVA4hnN9ynlMhMpLRFfTQAicDKYbEGDhfBcbCIX0vVv4vacA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@voidzero-dev/vite-plus-linux-arm64-musl@0.1.19': - resolution: {integrity: sha512-fUuXUqCl3zMbS5QpMJzewVjrpbtzlwuzYQSh5q59CMq65uCXT07amJzmuAFReDEMrwEAmjGgbamJ1ctLAYCxrA==} + '@voidzero-dev/vite-plus-linux-arm64-musl@0.1.20': + resolution: {integrity: sha512-Oh/pxMdTLR/wsDl/OONjItjLOeTewFBLuKkH5RQmcI9g3AVqKzLj1/uawujgysBI5E25tonRRK7I2q/zu8Uqvg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@voidzero-dev/vite-plus-linux-x64-gnu@0.1.19': - resolution: {integrity: sha512-xFVGMo1Yo5p9gABpOSSGgu5LhhMQs6qVXU7xL+NAGnaVViAYujNuOhCpBk2yK4Cy98KiNOjwnR5jG0TnRd22xg==} + '@voidzero-dev/vite-plus-linux-x64-gnu@0.1.20': + resolution: {integrity: sha512-msO1ZoUX5aSK8L6kN1C3XQO4CcH9aFsNPRSNcO1cjk1kTnaLyVYzkVxgvbh3vk7nzZAAMkmyZ4SlMpqJrdahrg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@voidzero-dev/vite-plus-linux-x64-musl@0.1.19': - resolution: {integrity: sha512-iEDxL85v/C01yF2EJKknkjDhKbgY10NL9/sZ4HxezWykePK6QpYY5ClWGL7gIi+YFp8rtAdRPKlrf0mTlYMvxw==} + '@voidzero-dev/vite-plus-linux-x64-musl@0.1.20': + resolution: {integrity: sha512-U93urREvg23ZFDkxKkkfWWIOI4GI9erhbWAZpXG+GeYqygWKrVC6PUTXiuexVg3/CFg2sSMTdm1W6V7TFG5hYA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@voidzero-dev/vite-plus-test@0.1.19': - resolution: {integrity: sha512-KK0lfqyiEOEykp3hrcHT49f1j3M3t15ZKCuO+e9KbDRambU7tdz70xoHCKkRXcFgnds9gqi09PSLVy1k8XN+Hg==} + '@voidzero-dev/vite-plus-test@0.1.20': + resolution: {integrity: sha512-vy2dJYw1bhgQ/+BrQrfwPlSKzQ2mm3YLJ9kGF7Yo0UJ2P3XKpshtgFIWLjSg/IASnC93OAx0c/7j3NM0I1RMuA==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/coverage-istanbul': 4.1.4 - '@vitest/coverage-v8': 4.1.4 - '@vitest/ui': 4.1.4 + '@vitest/coverage-istanbul': 4.1.5 + '@vitest/coverage-v8': 4.1.5 + '@vitest/ui': 4.1.5 happy-dom: '*' jsdom: '*' vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -4566,14 +4577,14 @@ packages: jsdom: optional: true - '@voidzero-dev/vite-plus-win32-arm64-msvc@0.1.19': - resolution: {integrity: sha512-2GGeGr2mtXLjV9O8CXEEZkV6O8q8rMBhq8fj5fyaSuBe5FQ1OxGYYMDqNBxvbg+hSUw0ThKK6qmirj5fF2e/iw==} + '@voidzero-dev/vite-plus-win32-arm64-msvc@0.1.20': + resolution: {integrity: sha512-deXfe3h2OpzKV88s1PMUgVOJfN9LlnDDpIEVH6y2+YAXwlTSO7YeKBj2QmyS6ALZCI4Rfp4HOsB0OKMVBfEqww==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@voidzero-dev/vite-plus-win32-x64-msvc@0.1.19': - resolution: {integrity: sha512-//xUNHQnd+p4Xd4rlObAvum3DW1ugbWZ+kfaqD7biHQ9HQwHF28WSpJ3+d31vLUHj4o3DXYSA67g1Bq2d4tVgg==} + '@voidzero-dev/vite-plus-win32-x64-msvc@0.1.20': + resolution: {integrity: sha512-ygdgQgo0N9oUI1Q2IdYBcvr+KLY6riaqLY/bkWNYtvHS4uk8a4GuEd0F08znWt2E8sFm29i35bYIzI6fFY2EBg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -4711,9 +4722,6 @@ packages: bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - balanced-match@4.0.4: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} @@ -4746,9 +4754,6 @@ packages: boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - brace-expansion@1.1.13: - resolution: {integrity: sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==} - brace-expansion@5.0.5: resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} engines: {node: 18 || 20 || >=22} @@ -4791,10 +4796,6 @@ packages: resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} engines: {node: '>=20.19.0'} - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - camelize@1.0.1: resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} @@ -4903,6 +4904,10 @@ packages: client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -4960,8 +4965,10 @@ packages: compare-versions@6.1.1: resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + concurrently@9.2.1: + resolution: {integrity: sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==} + engines: {node: '>=18'} + hasBin: true confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} @@ -4972,8 +4979,8 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - copy-to-clipboard@3.3.3: - resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} + copy-to-clipboard@4.0.2: + resolution: {integrity: sha512-gklSft7IuhriZKHKpuoA1fpJSLPNgvUMWMo5BlnzAJm0zNKnznoSv23IjtNqclx8eKi6ZcdvFFzYEER/+U1LoQ==} core-js-compat@3.49.0: resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} @@ -5375,6 +5382,10 @@ packages: resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} engines: {node: '>=0.12'} + entities@8.0.0: + resolution: {integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==} + engines: {node: '>=20.19.0'} + error-stack-parser-es@1.0.5: resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} @@ -5445,8 +5456,8 @@ packages: '@eslint/json': optional: true - eslint-markdown@0.6.1: - resolution: {integrity: sha512-eiHSRFnzcPWN/0YDrtELW/+GnGylAoyXVBDh0iVAttyC5rWAaZfgSrzlFUTlS7Jz4XEL36PFLsoEcXlbvl5qPQ==} + eslint-markdown@0.7.0: + resolution: {integrity: sha512-cqnr3BWOC7EdexODdtuKIZ4Sbot78x1PZUrdIREp1v25PXgAhz+GRyZjxhSczLnEnf/oj49IyoiBjGAmcLNCQA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24.0.0} peerDependencies: eslint: ^9.31.0 || ^10.0.0-rc.0 @@ -5464,8 +5475,8 @@ packages: peerDependencies: eslint: '*' - eslint-plugin-better-tailwindcss@4.4.1: - resolution: {integrity: sha512-ueFciTgj2M+4YklYdtvpbMA3Nn22z60sQoSA4bnctOP4h0daUhJKAsDaGi888N00qWtIUqeK5Ikt6xnNnHPg2g==} + eslint-plugin-better-tailwindcss@4.5.0: + resolution: {integrity: sha512-EBNTx6OJYaWv7uUxHWTy1fhiNz2rZVkoeOHZzAJFwWaEPideBf04CMshrJ7YntG0KQzadlbRhHKYr32q5aBX4w==} engines: {node: ^20.19.0 || ^22.12.0 || >=23.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 @@ -5656,10 +5667,6 @@ packages: '@vue/compiler-sfc': ^3.3.0 eslint: '>=9.0.0' - eslint-scope@8.4.0: - resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint-scope@9.1.2: resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} @@ -5686,16 +5693,6 @@ packages: jiti: optional: true - eslint@9.27.0: - resolution: {integrity: sha512-ixRawFQuMB9DZ7fjU3iGGganFDp3+45bPOdaRurcFHSXO1e/sYwUX/FtQZpLZJR6SjMoJH8hR2pPEAfDyCoU2Q==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true - peerDependencies: - jiti: '*' - peerDependenciesMeta: - jiti: - optional: true - espree@10.4.0: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -5874,6 +5871,10 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + get-east-asian-width@1.5.0: resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} engines: {node: '>=18'} @@ -5914,10 +5915,6 @@ packages: resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} engines: {node: '>=10'} - globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} - engines: {node: '>=18'} - globals@15.15.0: resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} engines: {node: '>=18'} @@ -6033,8 +6030,8 @@ packages: i18next-resources-to-backend@1.2.1: resolution: {integrity: sha512-okHbVA+HZ7n1/76MsfhPqDou0fptl2dAlhRDu2ideXloRRduzHsqDOznJBef+R3DFZnbvWoBW+KxJ7fnFjd6Yw==} - i18next@26.0.6: - resolution: {integrity: sha512-A4U6eCXodIbrhf8EarRurB9/4ebyaurH4+fu4gig9bqxmpSt+fCAFm/GpRQDcN1Xzu/LdFCx4nYHsnM1edIIbg==} + i18next@26.0.8: + resolution: {integrity: sha512-BRzLom0mhDhV9v0QhgUUHWQJuwFmnr1194xEcNLYD6ym8y8s542n4jXUvRLnhNTbh9PmpU6kGZamyuGHQMsGjw==} peerDependencies: typescript: ^5 || ^6 peerDependenciesMeta: @@ -6073,10 +6070,6 @@ packages: immer@11.1.4: resolution: {integrity: sha512-XREFCPo6ksxVzP4E0ekD5aMdf8WMwmdNaz6vuvxgI40UaEiu6q3p8X52aU6GdyvLY3XXX/8R7JOTXStz/nBbRw==} - import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} - engines: {node: '>=6'} - imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} @@ -6331,8 +6324,8 @@ packages: '@lexical/utils': '>=0.28.0' lexical: '>=0.28.0' - lexical@0.43.0: - resolution: {integrity: sha512-waSeXyt1HxTFpU8KNRA3IQcvjvpw0lZNaSbGopfOi4bLV0FF9zYpqiScTnEUMP/b1W7qWmD4Z2Detw43XICxqQ==} + lexical@0.44.0: + resolution: {integrity: sha512-ReDUjRlFgkGoPWzvdjr7s16PUVpHATN+2NH2NiZs+PLlISTaIFFgKil2P467oP3Vg+XgmpDsUgmWZsFJTztYjg==} lightningcss-android-arm64@1.32.0: resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} @@ -6714,9 +6707,6 @@ packages: resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} engines: {node: 18 || 20 || >=22} - minimatch@3.1.5: - resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} - minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -6898,17 +6888,17 @@ packages: oxc-resolver@11.19.1: resolution: {integrity: sha512-qE/CIg/spwrTBFt5aKmwe3ifeDdLfA2NESN30E42X/lII5ClF8V7Wt6WIJhcGZjp0/Q+nQ+9vgxGk//xZNX2hg==} - oxfmt@0.45.0: - resolution: {integrity: sha512-0o/COoN9fY50bjVeM7PQsNgbhndKurBIeTIcspW033OumksjJJmIVDKjAk5HMwU/GHTxSOdGDdhJ6BRzGPmsHg==} + oxfmt@0.46.0: + resolution: {integrity: sha512-CopwJOwPAjZ9p76fCvz+mSOJTw9/NY3cSksZK3VO/bUQ8UoEcketNgUuYS0UB3p+R9XnXe7wGGXUmyFxc7QxJA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - oxlint-tsgolint@0.21.1: - resolution: {integrity: sha512-O2hxiT14C2HJkwzBU6CQBFPoagSd/IcV+Tt3e3UUaXFwbW4BO5DSDPSSboc3UM5MIDY+MLyepvtQwBQafNxWdw==} + oxlint-tsgolint@0.22.0: + resolution: {integrity: sha512-ku4MecLmCQIj1ScCtzNAqTuyl0BJQ02B36fJT+c5XQihHpYSFak+FC3GYO5fPyYk4oDwi0w0S7hTvrpNzuZhig==} hasBin: true - oxlint@1.60.0: - resolution: {integrity: sha512-tnRzTWiWJ9pg3ftRWnD0+Oqh78L6ZSwcEudvCZaER0PIqiAnNyXj5N1dPwjmNpDalkKS9m/WMLN1CTPUBPmsgw==} + oxlint@1.61.0: + resolution: {integrity: sha512-ZC0ALuhDZ6ivOFG+sy0D0pEDN49EvsId98zVlmYdkcXHsEM14m/qTNUEsUpiFiCVbpIxYtVBmmLE87nsbUHohQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -6942,10 +6932,6 @@ packages: papaparse@5.5.3: resolution: {integrity: sha512-5QvjGxYVjxO59MGU2lHVYpRWBBtKHnlIAcSe1uNFCkkptUh63NFRj0FJQm7nR67puEruUci/ZkjmEFrjCAyP4A==} - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - parse-css-color@0.2.1: resolution: {integrity: sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg==} @@ -6975,8 +6961,8 @@ packages: parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} - parse5@8.0.0: - resolution: {integrity: sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==} + parse5@8.0.1: + resolution: {integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==} path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} @@ -7094,10 +7080,6 @@ packages: resolution: {integrity: sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA==} engines: {node: ^10 || ^12 || >=14} - postcss@8.5.9: - resolution: {integrity: sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==} - engines: {node: ^10 || ^12 || >=14} - powershell-utils@0.1.0: resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} engines: {node: '>=20'} @@ -7427,6 +7409,10 @@ packages: resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} engines: {node: '>=0.10'} + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + reselect@5.1.1: resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==} @@ -7437,10 +7423,6 @@ packages: resize-observer-polyfill@1.5.1: resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} @@ -7469,6 +7451,9 @@ packages: rw@1.3.3: resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -7528,6 +7513,10 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + shell-quote@1.8.3: + resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} + engines: {node: '>= 0.4'} + shiki@4.0.2: resolution: {integrity: sha512-eAVKTMedR5ckPo4xne/PjYQYrU3qx78gtJZ+sHlXEg5IHhhoQhMfZVzetTYuaJS0L2Ef3AcCRzCHV8T0WI6nIQ==} engines: {node: '>=20'} @@ -7652,6 +7641,10 @@ packages: stringify-entities@4.0.4: resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + strip-ansi@7.2.0: resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} engines: {node: '>=12'} @@ -7672,10 +7665,6 @@ packages: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - strip-json-comments@5.0.3: resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} engines: {node: '>=14.16'} @@ -7792,10 +7781,6 @@ packages: resolution: {integrity: sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==} engines: {node: '>=18'} - tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} - engines: {node: '>=12.0.0'} - tinyglobby@0.2.16: resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} engines: {node: '>=12.0.0'} @@ -7816,11 +7801,11 @@ packages: resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} engines: {node: '>=14.0.0'} - tldts-core@7.0.28: - resolution: {integrity: sha512-7W5Efjhsc3chVdFhqtaU0KtK32J37Zcr9RKtID54nG+tIpcY79CQK/veYPODxtD/LJ4Lue66jvrQzIX2Z2/pUQ==} + tldts-core@7.0.29: + resolution: {integrity: sha512-W99NuU7b1DcG3uJ3v9k9VztCH3WialNbBkBft5wCs8V8mexu0XQqaZEYb9l9RNNzK8+3EJ9PKWB0/RUtTQ/o+Q==} - tldts@7.0.28: - resolution: {integrity: sha512-+Zg3vWhRUv8B1maGSTFdev9mjoo8Etn2Ayfs4cnjlD3CsGkxXX4QyW3j2WJ0wdjYcYmy7Lx2RDsZMhgCWafKIw==} + tldts@7.0.29: + resolution: {integrity: sha512-JIXCerhudr/N6OWLwLF1HVsTTUo7ry6qHa5eWZEkiMuxsIiAACL55tGLfqfHfoH7QaMQUW8fngD7u7TxWexYQg==} hasBin: true to-regex-range@5.0.1: @@ -7831,9 +7816,6 @@ packages: resolution: {integrity: sha512-41wJyvKep3yT2tyPqX/4blcfybknGB4D+oETKLs7Q76UiPqRpUJK3hr1nxelyYO0PHKVzJwlu0aCeEAsGI6rpw==} engines: {node: '>=20'} - toggle-selection@1.0.6: - resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} - toml-eslint-parser@1.0.3: resolution: {integrity: sha512-A5F0cM6+mDleacLIEUkmfpkBbnHJFV1d2rprHU2MXNk7mlxHq2zGojA+SRvQD1RoMo9gqjZPWEaKG4v1BQ48lw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} @@ -7845,6 +7827,10 @@ packages: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} @@ -8082,8 +8068,8 @@ packages: resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} hasBin: true - uuid@13.0.0: - resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==} + uuid@14.0.0: + resolution: {integrity: sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==} hasBin: true valibot@1.3.1: @@ -8106,8 +8092,8 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - vinext@0.0.41: - resolution: {integrity: sha512-fpQjNp6cIqjYGH2/kbhN2SdIYHEu79RdlII23SWsY1Qp7LM+je8GfTJH1sxw6dASxPhZKZB/jCmTm5d2/D25zw==} + vinext@0.0.45: + resolution: {integrity: sha512-iXXRR5IMO5bZHgN9xEIzwt/+jushkoJgmWNenR++x6Tw1XnJGTEY9D5GAKMGewHl+HJ1z2GPO4fpNkT+2UowRA==} engines: {node: '>=22'} hasBin: true peerDependencies: @@ -8149,8 +8135,8 @@ packages: storybook: ^0.0.0-0 || ^9.0.0 || ^10.0.0 || ^10.0.0-0 || ^10.1.0-0 || ^10.2.0-0 || ^10.3.0-0 || ^10.4.0-0 vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 - vite-plus@0.1.19: - resolution: {integrity: sha512-QWuTqkO/a8Q7I3hHnYdvwlJa7mcc6hgh99/8CHoRb27pgo+z1ux+NGYYCZPJHKVtatAtVRaQQvy4cEQBHyB87A==} + vite-plus@0.1.20: + resolution: {integrity: sha512-hxJqXTxiiFhszwAeD0MvKlztVuXE4TztTdJ64BPxGqgY67F0PDa5eZkUsrN91Ae8aYUMfweW6V/J57OUO9/0zw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -8262,6 +8248,10 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -8309,6 +8299,10 @@ packages: resolution: {integrity: sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==} engines: {node: '>=0.4.0'} + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} @@ -8325,6 +8319,14 @@ packages: engines: {node: '>= 14.6'} hasBin: true + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + yauzl@3.2.1: resolution: {integrity: sha512-k1isifdbpNSFEHFJ1ZY4YDewv0IH9FR61lDetaRMD3j2ae3bIXGV+7c+LHCqtQGofSd8PIyV4X6+dHMAnSr60A==} engines: {node: '>=12'} @@ -8399,16 +8401,16 @@ snapshots: '@alloc/quick-lru@5.2.0': {} - '@amplitude/analytics-browser@2.41.1': + '@amplitude/analytics-browser@2.42.0': dependencies: - '@amplitude/analytics-core': 2.47.1 - '@amplitude/plugin-autocapture-browser': 1.26.1 - '@amplitude/plugin-custom-enrichment-browser': 0.1.7 - '@amplitude/plugin-event-property-attribution-browser': 0.1.2 - '@amplitude/plugin-network-capture-browser': 1.9.16 - '@amplitude/plugin-page-url-enrichment-browser': 0.7.8 - '@amplitude/plugin-page-view-tracking-browser': 2.10.2 - '@amplitude/plugin-web-vitals-browser': 1.1.31 + '@amplitude/analytics-core': 2.48.0 + '@amplitude/plugin-autocapture-browser': 1.27.0 + '@amplitude/plugin-custom-enrichment-browser': 0.1.8 + '@amplitude/plugin-event-property-attribution-browser': 0.2.0 + '@amplitude/plugin-network-capture-browser': 1.10.0 + '@amplitude/plugin-page-url-enrichment-browser': 0.7.9 + '@amplitude/plugin-page-view-tracking-browser': 2.11.0 + '@amplitude/plugin-web-vitals-browser': 1.1.32 tslib: 2.8.1 '@amplitude/analytics-client-common@2.4.46': @@ -8418,6 +8420,13 @@ snapshots: '@amplitude/analytics-types': 2.11.1 tslib: 2.8.1 + '@amplitude/analytics-client-common@2.4.47': + dependencies: + '@amplitude/analytics-connector': 1.6.4 + '@amplitude/analytics-core': 2.48.0 + '@amplitude/analytics-types': 2.11.1 + tslib: 2.8.1 + '@amplitude/analytics-connector@1.6.4': {} '@amplitude/analytics-core@2.47.1': @@ -8428,59 +8437,67 @@ snapshots: tslib: 2.8.1 zen-observable: 0.10.0 + '@amplitude/analytics-core@2.48.0': + dependencies: + '@amplitude/analytics-connector': 1.6.4 + '@types/zen-observable': 0.8.3 + safe-json-stringify: 1.2.0 + tslib: 2.8.1 + zen-observable: 0.10.0 + '@amplitude/analytics-types@2.11.1': {} '@amplitude/experiment-core@0.7.2': dependencies: js-base64: 3.7.8 - '@amplitude/plugin-autocapture-browser@1.26.1': + '@amplitude/plugin-autocapture-browser@1.27.0': dependencies: - '@amplitude/analytics-core': 2.47.1 + '@amplitude/analytics-core': 2.48.0 tslib: 2.8.1 - '@amplitude/plugin-custom-enrichment-browser@0.1.7': + '@amplitude/plugin-custom-enrichment-browser@0.1.8': dependencies: - '@amplitude/analytics-core': 2.47.1 + '@amplitude/analytics-core': 2.48.0 tslib: 2.8.1 - '@amplitude/plugin-event-property-attribution-browser@0.1.2': + '@amplitude/plugin-event-property-attribution-browser@0.2.0': dependencies: - '@amplitude/analytics-core': 2.47.1 + '@amplitude/analytics-core': 2.48.0 tslib: 2.8.1 - '@amplitude/plugin-network-capture-browser@1.9.16': + '@amplitude/plugin-network-capture-browser@1.10.0': dependencies: - '@amplitude/analytics-core': 2.47.1 + '@amplitude/analytics-core': 2.48.0 tslib: 2.8.1 - '@amplitude/plugin-page-url-enrichment-browser@0.7.8': + '@amplitude/plugin-page-url-enrichment-browser@0.7.9': dependencies: - '@amplitude/analytics-core': 2.47.1 + '@amplitude/analytics-core': 2.48.0 tslib: 2.8.1 - '@amplitude/plugin-page-view-tracking-browser@2.10.2': + '@amplitude/plugin-page-view-tracking-browser@2.11.0': dependencies: - '@amplitude/analytics-core': 2.47.1 + '@amplitude/analytics-core': 2.48.0 tslib: 2.8.1 - '@amplitude/plugin-session-replay-browser@1.28.0(@amplitude/rrweb@2.0.0-alpha.37)': + '@amplitude/plugin-session-replay-browser@1.28.1(@amplitude/rrweb@2.0.0-alpha.37)': dependencies: - '@amplitude/analytics-client-common': 2.4.46 - '@amplitude/analytics-core': 2.47.1 + '@amplitude/analytics-client-common': 2.4.47 + '@amplitude/analytics-core': 2.48.0 '@amplitude/analytics-types': 2.11.1 '@amplitude/rrweb-plugin-console-record': 2.0.0-alpha.36(@amplitude/rrweb@2.0.0-alpha.37) '@amplitude/rrweb-record': 2.0.0-alpha.36 - '@amplitude/session-replay-browser': 1.38.0(@amplitude/rrweb@2.0.0-alpha.37) + '@amplitude/session-replay-browser': 1.39.0(@amplitude/rrweb@2.0.0-alpha.37) idb-keyval: 6.2.2 tslib: 2.8.1 transitivePeerDependencies: - '@amplitude/rrweb' - rollup - '@amplitude/plugin-web-vitals-browser@1.1.31': + '@amplitude/plugin-web-vitals-browser@1.1.32': dependencies: - '@amplitude/analytics-core': 2.47.1 + '@amplitude/analytics-core': 2.48.0 tslib: 2.8.1 web-vitals: 5.1.0 @@ -8525,10 +8542,10 @@ snapshots: base64-arraybuffer: 1.0.2 mitt: 3.0.1 - '@amplitude/session-replay-browser@1.38.0(@amplitude/rrweb@2.0.0-alpha.37)': + '@amplitude/session-replay-browser@1.39.0(@amplitude/rrweb@2.0.0-alpha.37)': dependencies: - '@amplitude/analytics-client-common': 2.4.46 - '@amplitude/analytics-core': 2.47.1 + '@amplitude/analytics-client-common': 2.4.47 + '@amplitude/analytics-core': 2.48.0 '@amplitude/analytics-types': 2.11.1 '@amplitude/experiment-core': 0.7.2 '@amplitude/rrweb-packer': 2.0.0-alpha.36 @@ -8553,17 +8570,17 @@ snapshots: idb: 8.0.0 tslib: 2.8.1 - '@antfu/eslint-config@8.2.0(@eslint-react/eslint-plugin@3.0.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(@next/eslint-plugin-next@16.2.4)(@types/node@25.6.0)(@typescript-eslint/typescript-estree@8.59.0(typescript@6.0.3))(@typescript-eslint/utils@8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(eslint-plugin-react-refresh@0.5.2(eslint@10.2.1(jiti@2.6.1)))(eslint@10.2.1(jiti@2.6.1))(happy-dom@20.9.0)(jiti@2.6.1)(oxlint@1.60.0(oxlint-tsgolint@0.21.1))(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)': + '@antfu/eslint-config@8.2.0(@eslint-react/eslint-plugin@3.0.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(@next/eslint-plugin-next@16.2.4)(@types/node@25.6.0)(@typescript-eslint/typescript-estree@8.59.1(typescript@6.0.3))(@typescript-eslint/utils@8.59.1(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(eslint-plugin-react-refresh@0.5.2(eslint@10.2.1(jiti@2.6.1)))(eslint@10.2.1(jiti@2.6.1))(happy-dom@20.9.0)(jiti@2.6.1)(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)': dependencies: '@antfu/install-pkg': 1.1.0 '@clack/prompts': 1.2.0 - '@e18e/eslint-plugin': 0.3.0(eslint@10.2.1(jiti@2.6.1))(oxlint@1.60.0(oxlint-tsgolint@0.21.1)) + '@e18e/eslint-plugin': 0.3.0(eslint@10.2.1(jiti@2.6.1))(oxlint@1.61.0(oxlint-tsgolint@0.22.0)) '@eslint-community/eslint-plugin-eslint-comments': 4.7.1(eslint@10.2.1(jiti@2.6.1)) '@eslint/markdown': 8.0.1 '@stylistic/eslint-plugin': 5.10.0(eslint@10.2.1(jiti@2.6.1)) '@typescript-eslint/eslint-plugin': 8.58.2(@typescript-eslint/parser@8.58.2(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) '@typescript-eslint/parser': 8.58.2(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) - '@vitest/eslint-plugin': 1.6.15(@types/node@25.6.0)(@typescript-eslint/eslint-plugin@8.58.2(@typescript-eslint/parser@8.58.2(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(eslint@10.2.1(jiti@2.6.1))(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) + '@vitest/eslint-plugin': 1.6.15(@types/node@25.6.0)(@typescript-eslint/eslint-plugin@8.58.2(@typescript-eslint/parser@8.58.2(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(eslint@10.2.1(jiti@2.6.1))(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) ansis: 4.2.0 cac: 7.0.0 eslint: 10.2.1(jiti@2.6.1) @@ -8571,7 +8588,7 @@ snapshots: eslint-flat-config-utils: 3.1.0 eslint-merge-processors: 2.0.0(eslint@10.2.1(jiti@2.6.1)) eslint-plugin-antfu: 3.2.2(eslint@10.2.1(jiti@2.6.1)) - eslint-plugin-command: 3.5.2(@typescript-eslint/typescript-estree@8.59.0(typescript@6.0.3))(@typescript-eslint/utils@8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(eslint@10.2.1(jiti@2.6.1)) + eslint-plugin-command: 3.5.2(@typescript-eslint/typescript-estree@8.59.1(typescript@6.0.3))(@typescript-eslint/utils@8.59.1(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(eslint@10.2.1(jiti@2.6.1)) eslint-plugin-import-lite: 0.6.0(eslint@10.2.1(jiti@2.6.1)) eslint-plugin-jsdoc: 62.9.0(eslint@10.2.1(jiti@2.6.1)) eslint-plugin-jsonc: 3.1.2(eslint@10.2.1(jiti@2.6.1)) @@ -8798,22 +8815,11 @@ snapshots: - '@chromatic-com/cypress' - '@chromatic-com/playwright' - '@clack/core@0.3.5': - dependencies: - picocolors: 1.1.1 - sisteransi: 1.0.5 - '@clack/core@1.2.0': dependencies: fast-wrap-ansi: 0.1.6 sisteransi: 1.0.5 - '@clack/prompts@0.8.2': - dependencies: - '@clack/core': 0.3.5 - picocolors: 1.1.1 - sisteransi: 1.0.5 - '@clack/prompts@1.2.0': dependencies: '@clack/core': 1.2.0 @@ -8973,12 +8979,12 @@ snapshots: '@cucumber/tag-expressions@9.1.0': {} - '@e18e/eslint-plugin@0.3.0(eslint@10.2.1(jiti@2.6.1))(oxlint@1.60.0(oxlint-tsgolint@0.21.1))': + '@e18e/eslint-plugin@0.3.0(eslint@10.2.1(jiti@2.6.1))(oxlint@1.61.0(oxlint-tsgolint@0.22.0))': dependencies: eslint-plugin-depend: 1.5.0(eslint@10.2.1(jiti@2.6.1)) optionalDependencies: eslint: 10.2.1(jiti@2.6.1) - oxlint: 1.60.0(oxlint-tsgolint@0.21.1) + oxlint: 1.61.0(oxlint-tsgolint@0.22.0) '@egoist/tailwindcss-icons@1.9.2(tailwindcss@4.2.4)': dependencies: @@ -9115,18 +9121,13 @@ snapshots: eslint: 10.2.1(jiti@2.6.1) eslint-visitor-keys: 3.4.3 - '@eslint-community/eslint-utils@4.9.1(eslint@9.27.0(jiti@2.6.1))': - dependencies: - eslint: 9.27.0(jiti@2.6.1) - eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.12.2': {} '@eslint-react/ast@3.0.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.58.2 - '@typescript-eslint/typescript-estree': 8.58.2(typescript@6.0.3) - '@typescript-eslint/utils': 8.58.2(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) + '@typescript-eslint/types': 8.59.0 + '@typescript-eslint/typescript-estree': 8.59.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) eslint: 10.2.1(jiti@2.6.1) string-ts: 2.3.1 typescript: 6.0.3 @@ -9138,9 +9139,9 @@ snapshots: '@eslint-react/ast': 3.0.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) '@eslint-react/shared': 3.0.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) '@eslint-react/var': 3.0.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.58.2 - '@typescript-eslint/types': 8.58.2 - '@typescript-eslint/utils': 8.58.2(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.59.0 + '@typescript-eslint/types': 8.59.0 + '@typescript-eslint/utils': 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) eslint: 10.2.1(jiti@2.6.1) ts-pattern: 5.9.0 typescript: 6.0.3 @@ -9179,9 +9180,9 @@ snapshots: dependencies: '@eslint-react/ast': 3.0.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) '@eslint-react/shared': 3.0.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.58.2 - '@typescript-eslint/types': 8.58.2 - '@typescript-eslint/utils': 8.58.2(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.59.0 + '@typescript-eslint/types': 8.59.0 + '@typescript-eslint/utils': 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) eslint: 10.2.1(jiti@2.6.1) ts-pattern: 5.9.0 typescript: 6.0.3 @@ -9194,14 +9195,6 @@ snapshots: optionalDependencies: eslint: 10.2.1(jiti@2.6.1) - '@eslint/config-array@0.20.1': - dependencies: - '@eslint/object-schema': 2.1.7 - debug: 4.4.3(supports-color@8.1.1) - minimatch: 3.1.5 - transitivePeerDependencies: - - supports-color - '@eslint/config-array@0.23.5': dependencies: '@eslint/object-schema': 3.0.5 @@ -9210,8 +9203,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.2.3': {} - '@eslint/config-helpers@0.5.4': dependencies: '@eslint/core': 1.2.0 @@ -9220,14 +9211,6 @@ snapshots: dependencies: '@eslint/core': 1.2.1 - '@eslint/core@0.14.0': - dependencies: - '@types/json-schema': 7.0.15 - - '@eslint/core@0.15.2': - dependencies: - '@types/json-schema': 7.0.15 - '@eslint/core@0.17.0': dependencies: '@types/json-schema': 7.0.15 @@ -9245,26 +9228,10 @@ snapshots: mdn-data: 2.27.1 source-map-js: 1.2.1 - '@eslint/eslintrc@3.3.5': - dependencies: - ajv: 6.14.0 - debug: 4.4.3(supports-color@8.1.1) - espree: 10.4.0 - globals: 14.0.0 - ignore: 5.3.2 - import-fresh: 3.3.1 - js-yaml: 4.1.1 - minimatch: 3.1.5 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - '@eslint/js@10.0.1(eslint@10.2.1(jiti@2.6.1))': optionalDependencies: eslint: 10.2.1(jiti@2.6.1) - '@eslint/js@9.27.0': {} - '@eslint/markdown@7.5.1': dependencies: '@eslint/core': 0.17.0 @@ -9295,15 +9262,8 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/object-schema@2.1.7': {} - '@eslint/object-schema@3.0.5': {} - '@eslint/plugin-kit@0.3.5': - dependencies: - '@eslint/core': 0.15.2 - levn: 0.4.1 - '@eslint/plugin-kit@0.4.1': dependencies: '@eslint/core': 0.17.0 @@ -9372,7 +9332,7 @@ snapshots: dependencies: react: 19.2.5 - '@hono/node-server@1.19.14(hono@4.12.15)': + '@hono/node-server@2.0.0(hono@4.12.15)': dependencies: hono: 4.12.15 @@ -9530,11 +9490,11 @@ snapshots: dependencies: minipass: 7.1.3 - '@joshwooding/vite-plugin-react-docgen-typescript@0.7.0(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3)': + '@joshwooding/vite-plugin-react-docgen-typescript@0.7.0(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3)': dependencies: glob: 13.0.6 react-docgen-typescript: 2.4.0(typescript@6.0.3) - vite: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' optionalDependencies: typescript: 6.0.3 @@ -9557,161 +9517,157 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@lexical/clipboard@0.43.0': + '@lexical/clipboard@0.44.0': dependencies: - '@lexical/html': 0.43.0 - '@lexical/list': 0.43.0 - '@lexical/selection': 0.43.0 - '@lexical/utils': 0.43.0 - lexical: 0.43.0 + '@lexical/extension': 0.44.0 + '@lexical/html': 0.44.0 + '@lexical/list': 0.44.0 + '@lexical/selection': 0.44.0 + '@lexical/utils': 0.44.0 + '@types/trusted-types': 2.0.7 + lexical: 0.44.0 - '@lexical/code-core@0.43.0': + '@lexical/code-core@0.44.0': dependencies: - lexical: 0.43.0 + '@lexical/extension': 0.44.0 + lexical: 0.44.0 - '@lexical/devtools-core@0.43.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@lexical/devtools-core@0.44.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': dependencies: - '@lexical/html': 0.43.0 - '@lexical/link': 0.43.0 - '@lexical/mark': 0.43.0 - '@lexical/table': 0.43.0 - '@lexical/utils': 0.43.0 - lexical: 0.43.0 + '@lexical/html': 0.44.0 + '@lexical/link': 0.44.0 + '@lexical/mark': 0.44.0 + '@lexical/table': 0.44.0 + '@lexical/utils': 0.44.0 + lexical: 0.44.0 react: 19.2.5 react-dom: 19.2.5(react@19.2.5) - '@lexical/dragon@0.43.0': + '@lexical/dragon@0.44.0': dependencies: - '@lexical/extension': 0.43.0 - lexical: 0.43.0 + '@lexical/extension': 0.44.0 + lexical: 0.44.0 - '@lexical/extension@0.43.0': + '@lexical/extension@0.44.0': dependencies: - '@lexical/utils': 0.43.0 + '@lexical/utils': 0.44.0 '@preact/signals-core': 1.14.1 - lexical: 0.43.0 + lexical: 0.44.0 - '@lexical/hashtag@0.43.0': + '@lexical/hashtag@0.44.0': dependencies: - '@lexical/text': 0.43.0 - '@lexical/utils': 0.43.0 - lexical: 0.43.0 + '@lexical/text': 0.44.0 + '@lexical/utils': 0.44.0 + lexical: 0.44.0 - '@lexical/history@0.43.0': + '@lexical/history@0.44.0': dependencies: - '@lexical/extension': 0.43.0 - '@lexical/utils': 0.43.0 - lexical: 0.43.0 + '@lexical/extension': 0.44.0 + '@lexical/utils': 0.44.0 + lexical: 0.44.0 - '@lexical/html@0.43.0': + '@lexical/html@0.44.0': dependencies: - '@lexical/selection': 0.43.0 - '@lexical/utils': 0.43.0 - lexical: 0.43.0 + '@lexical/extension': 0.44.0 + '@lexical/selection': 0.44.0 + '@lexical/utils': 0.44.0 + lexical: 0.44.0 - '@lexical/link@0.43.0': + '@lexical/link@0.44.0': dependencies: - '@lexical/extension': 0.43.0 - '@lexical/utils': 0.43.0 - lexical: 0.43.0 + '@lexical/extension': 0.44.0 + '@lexical/utils': 0.44.0 + lexical: 0.44.0 - '@lexical/list@0.43.0': + '@lexical/list@0.44.0': dependencies: - '@lexical/extension': 0.43.0 - '@lexical/selection': 0.43.0 - '@lexical/utils': 0.43.0 - lexical: 0.43.0 + '@lexical/extension': 0.44.0 + '@lexical/utils': 0.44.0 + lexical: 0.44.0 - '@lexical/mark@0.43.0': + '@lexical/mark@0.44.0': dependencies: - '@lexical/utils': 0.43.0 - lexical: 0.43.0 + '@lexical/utils': 0.44.0 + lexical: 0.44.0 - '@lexical/markdown@0.43.0': + '@lexical/markdown@0.44.0': dependencies: - '@lexical/code-core': 0.43.0 - '@lexical/link': 0.43.0 - '@lexical/list': 0.43.0 - '@lexical/rich-text': 0.43.0 - '@lexical/text': 0.43.0 - '@lexical/utils': 0.43.0 - lexical: 0.43.0 + '@lexical/code-core': 0.44.0 + '@lexical/link': 0.44.0 + '@lexical/list': 0.44.0 + '@lexical/rich-text': 0.44.0 + '@lexical/text': 0.44.0 + '@lexical/utils': 0.44.0 + lexical: 0.44.0 - '@lexical/offset@0.43.0': + '@lexical/overflow@0.44.0': dependencies: - lexical: 0.43.0 + lexical: 0.44.0 - '@lexical/overflow@0.43.0': + '@lexical/plain-text@0.44.0': dependencies: - lexical: 0.43.0 + '@lexical/clipboard': 0.44.0 + '@lexical/dragon': 0.44.0 + '@lexical/selection': 0.44.0 + '@lexical/utils': 0.44.0 + lexical: 0.44.0 - '@lexical/plain-text@0.43.0': - dependencies: - '@lexical/clipboard': 0.43.0 - '@lexical/dragon': 0.43.0 - '@lexical/selection': 0.43.0 - '@lexical/utils': 0.43.0 - lexical: 0.43.0 - - '@lexical/react@0.43.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': + '@lexical/react@0.44.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': dependencies: '@floating-ui/react': 0.27.19(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@lexical/devtools-core': 0.43.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@lexical/dragon': 0.43.0 - '@lexical/extension': 0.43.0 - '@lexical/hashtag': 0.43.0 - '@lexical/history': 0.43.0 - '@lexical/link': 0.43.0 - '@lexical/list': 0.43.0 - '@lexical/mark': 0.43.0 - '@lexical/markdown': 0.43.0 - '@lexical/overflow': 0.43.0 - '@lexical/plain-text': 0.43.0 - '@lexical/rich-text': 0.43.0 - '@lexical/table': 0.43.0 - '@lexical/text': 0.43.0 - '@lexical/utils': 0.43.0 - '@lexical/yjs': 0.43.0 - lexical: 0.43.0 + '@lexical/devtools-core': 0.44.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) + '@lexical/dragon': 0.44.0 + '@lexical/extension': 0.44.0 + '@lexical/hashtag': 0.44.0 + '@lexical/history': 0.44.0 + '@lexical/link': 0.44.0 + '@lexical/list': 0.44.0 + '@lexical/mark': 0.44.0 + '@lexical/markdown': 0.44.0 + '@lexical/overflow': 0.44.0 + '@lexical/plain-text': 0.44.0 + '@lexical/rich-text': 0.44.0 + '@lexical/table': 0.44.0 + '@lexical/text': 0.44.0 + '@lexical/utils': 0.44.0 + '@lexical/yjs': 0.44.0 + lexical: 0.44.0 react: 19.2.5 react-dom: 19.2.5(react@19.2.5) react-error-boundary: 6.1.1(react@19.2.5) - transitivePeerDependencies: - - yjs - '@lexical/rich-text@0.43.0': + '@lexical/rich-text@0.44.0': dependencies: - '@lexical/clipboard': 0.43.0 - '@lexical/dragon': 0.43.0 - '@lexical/selection': 0.43.0 - '@lexical/utils': 0.43.0 - lexical: 0.43.0 + '@lexical/clipboard': 0.44.0 + '@lexical/dragon': 0.44.0 + '@lexical/selection': 0.44.0 + '@lexical/utils': 0.44.0 + lexical: 0.44.0 - '@lexical/selection@0.43.0': + '@lexical/selection@0.44.0': dependencies: - lexical: 0.43.0 + lexical: 0.44.0 - '@lexical/table@0.43.0': + '@lexical/table@0.44.0': dependencies: - '@lexical/clipboard': 0.43.0 - '@lexical/extension': 0.43.0 - '@lexical/utils': 0.43.0 - lexical: 0.43.0 + '@lexical/clipboard': 0.44.0 + '@lexical/extension': 0.44.0 + '@lexical/utils': 0.44.0 + lexical: 0.44.0 - '@lexical/text@0.43.0': + '@lexical/text@0.44.0': dependencies: - lexical: 0.43.0 + lexical: 0.44.0 - '@lexical/utils@0.43.0': + '@lexical/utils@0.44.0': dependencies: - '@lexical/selection': 0.43.0 - lexical: 0.43.0 + '@lexical/selection': 0.44.0 + lexical: 0.44.0 - '@lexical/yjs@0.43.0': + '@lexical/yjs@0.44.0': dependencies: - '@lexical/offset': 0.43.0 - '@lexical/selection': 0.43.0 - lexical: 0.43.0 + '@lexical/selection': 0.44.0 + lexical: 0.44.0 '@mdx-js/loader@3.1.1': dependencies: @@ -9897,11 +9853,11 @@ snapshots: transitivePeerDependencies: - '@opentelemetry/api' - '@orpc/tanstack-query@1.14.0(@orpc/client@1.14.0)(@tanstack/query-core@5.100.5)': + '@orpc/tanstack-query@1.14.0(@orpc/client@1.14.0)(@tanstack/query-core@5.100.6)': dependencies: '@orpc/client': 1.14.0 '@orpc/shared': 1.14.0 - '@tanstack/query-core': 5.100.5 + '@tanstack/query-core': 5.100.6 transitivePeerDependencies: - '@opentelemetry/api' @@ -9971,9 +9927,7 @@ snapshots: '@oxc-parser/binding-win32-x64-msvc@0.127.0': optional: true - '@oxc-project/runtime@0.126.0': {} - - '@oxc-project/types@0.126.0': {} + '@oxc-project/runtime@0.127.0': {} '@oxc-project/types@0.127.0': {} @@ -10042,136 +9996,136 @@ snapshots: '@oxc-resolver/binding-win32-x64-msvc@11.19.1': optional: true - '@oxfmt/binding-android-arm-eabi@0.45.0': + '@oxfmt/binding-android-arm-eabi@0.46.0': optional: true - '@oxfmt/binding-android-arm64@0.45.0': + '@oxfmt/binding-android-arm64@0.46.0': optional: true - '@oxfmt/binding-darwin-arm64@0.45.0': + '@oxfmt/binding-darwin-arm64@0.46.0': optional: true - '@oxfmt/binding-darwin-x64@0.45.0': + '@oxfmt/binding-darwin-x64@0.46.0': optional: true - '@oxfmt/binding-freebsd-x64@0.45.0': + '@oxfmt/binding-freebsd-x64@0.46.0': optional: true - '@oxfmt/binding-linux-arm-gnueabihf@0.45.0': + '@oxfmt/binding-linux-arm-gnueabihf@0.46.0': optional: true - '@oxfmt/binding-linux-arm-musleabihf@0.45.0': + '@oxfmt/binding-linux-arm-musleabihf@0.46.0': optional: true - '@oxfmt/binding-linux-arm64-gnu@0.45.0': + '@oxfmt/binding-linux-arm64-gnu@0.46.0': optional: true - '@oxfmt/binding-linux-arm64-musl@0.45.0': + '@oxfmt/binding-linux-arm64-musl@0.46.0': optional: true - '@oxfmt/binding-linux-ppc64-gnu@0.45.0': + '@oxfmt/binding-linux-ppc64-gnu@0.46.0': optional: true - '@oxfmt/binding-linux-riscv64-gnu@0.45.0': + '@oxfmt/binding-linux-riscv64-gnu@0.46.0': optional: true - '@oxfmt/binding-linux-riscv64-musl@0.45.0': + '@oxfmt/binding-linux-riscv64-musl@0.46.0': optional: true - '@oxfmt/binding-linux-s390x-gnu@0.45.0': + '@oxfmt/binding-linux-s390x-gnu@0.46.0': optional: true - '@oxfmt/binding-linux-x64-gnu@0.45.0': + '@oxfmt/binding-linux-x64-gnu@0.46.0': optional: true - '@oxfmt/binding-linux-x64-musl@0.45.0': + '@oxfmt/binding-linux-x64-musl@0.46.0': optional: true - '@oxfmt/binding-openharmony-arm64@0.45.0': + '@oxfmt/binding-openharmony-arm64@0.46.0': optional: true - '@oxfmt/binding-win32-arm64-msvc@0.45.0': + '@oxfmt/binding-win32-arm64-msvc@0.46.0': optional: true - '@oxfmt/binding-win32-ia32-msvc@0.45.0': + '@oxfmt/binding-win32-ia32-msvc@0.46.0': optional: true - '@oxfmt/binding-win32-x64-msvc@0.45.0': + '@oxfmt/binding-win32-x64-msvc@0.46.0': optional: true - '@oxlint-tsgolint/darwin-arm64@0.21.1': + '@oxlint-tsgolint/darwin-arm64@0.22.0': optional: true - '@oxlint-tsgolint/darwin-x64@0.21.1': + '@oxlint-tsgolint/darwin-x64@0.22.0': optional: true - '@oxlint-tsgolint/linux-arm64@0.21.1': + '@oxlint-tsgolint/linux-arm64@0.22.0': optional: true - '@oxlint-tsgolint/linux-x64@0.21.1': + '@oxlint-tsgolint/linux-x64@0.22.0': optional: true - '@oxlint-tsgolint/win32-arm64@0.21.1': + '@oxlint-tsgolint/win32-arm64@0.22.0': optional: true - '@oxlint-tsgolint/win32-x64@0.21.1': + '@oxlint-tsgolint/win32-x64@0.22.0': optional: true - '@oxlint/binding-android-arm-eabi@1.60.0': + '@oxlint/binding-android-arm-eabi@1.61.0': optional: true - '@oxlint/binding-android-arm64@1.60.0': + '@oxlint/binding-android-arm64@1.61.0': optional: true - '@oxlint/binding-darwin-arm64@1.60.0': + '@oxlint/binding-darwin-arm64@1.61.0': optional: true - '@oxlint/binding-darwin-x64@1.60.0': + '@oxlint/binding-darwin-x64@1.61.0': optional: true - '@oxlint/binding-freebsd-x64@1.60.0': + '@oxlint/binding-freebsd-x64@1.61.0': optional: true - '@oxlint/binding-linux-arm-gnueabihf@1.60.0': + '@oxlint/binding-linux-arm-gnueabihf@1.61.0': optional: true - '@oxlint/binding-linux-arm-musleabihf@1.60.0': + '@oxlint/binding-linux-arm-musleabihf@1.61.0': optional: true - '@oxlint/binding-linux-arm64-gnu@1.60.0': + '@oxlint/binding-linux-arm64-gnu@1.61.0': optional: true - '@oxlint/binding-linux-arm64-musl@1.60.0': + '@oxlint/binding-linux-arm64-musl@1.61.0': optional: true - '@oxlint/binding-linux-ppc64-gnu@1.60.0': + '@oxlint/binding-linux-ppc64-gnu@1.61.0': optional: true - '@oxlint/binding-linux-riscv64-gnu@1.60.0': + '@oxlint/binding-linux-riscv64-gnu@1.61.0': optional: true - '@oxlint/binding-linux-riscv64-musl@1.60.0': + '@oxlint/binding-linux-riscv64-musl@1.61.0': optional: true - '@oxlint/binding-linux-s390x-gnu@1.60.0': + '@oxlint/binding-linux-s390x-gnu@1.61.0': optional: true - '@oxlint/binding-linux-x64-gnu@1.60.0': + '@oxlint/binding-linux-x64-gnu@1.61.0': optional: true - '@oxlint/binding-linux-x64-musl@1.60.0': + '@oxlint/binding-linux-x64-musl@1.61.0': optional: true - '@oxlint/binding-openharmony-arm64@1.60.0': + '@oxlint/binding-openharmony-arm64@1.61.0': optional: true - '@oxlint/binding-win32-arm64-msvc@1.60.0': + '@oxlint/binding-win32-arm64-msvc@1.61.0': optional: true - '@oxlint/binding-win32-ia32-msvc@1.60.0': + '@oxlint/binding-win32-ia32-msvc@1.61.0': optional: true - '@oxlint/binding-win32-x64-msvc@1.60.0': + '@oxlint/binding-win32-x64-msvc@1.61.0': optional: true '@pkgr/core@0.2.9': {} @@ -10614,10 +10568,10 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@storybook/addon-docs@10.3.5(@types/react@19.2.14)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))': + '@storybook/addon-docs@10.3.5(@types/react@19.2.14)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))': dependencies: '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.5) - '@storybook/csf-plugin': 10.3.5(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) + '@storybook/csf-plugin': 10.3.5(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) '@storybook/icons': 2.0.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@storybook/react-dom-shim': 10.3.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) react: 19.2.5 @@ -10647,24 +10601,24 @@ snapshots: storybook: 10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) ts-dedent: 2.2.0 - '@storybook/builder-vite@10.3.5(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))': + '@storybook/builder-vite@10.3.5(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))': dependencies: - '@storybook/csf-plugin': 10.3.5(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) + '@storybook/csf-plugin': 10.3.5(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) storybook: 10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) ts-dedent: 2.2.0 - vite: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' transitivePeerDependencies: - esbuild - rollup - webpack - '@storybook/csf-plugin@10.3.5(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))': + '@storybook/csf-plugin@10.3.5(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))': dependencies: storybook: 10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) unplugin: 2.3.11 optionalDependencies: esbuild: 0.27.2 - vite: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' '@storybook/global@5.0.0': {} @@ -10673,18 +10627,18 @@ snapshots: react: 19.2.5 react-dom: 19.2.5(react@19.2.5) - '@storybook/nextjs-vite@10.3.5(@babel/core@7.29.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(next@16.2.4(@babel/core@7.29.0)(@playwright/test@1.59.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.3)': + '@storybook/nextjs-vite@10.3.5(@babel/core@7.29.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(next@16.2.4(@babel/core@7.29.0)(@playwright/test@1.59.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.3)': dependencies: - '@storybook/builder-vite': 10.3.5(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) + '@storybook/builder-vite': 10.3.5(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) '@storybook/react': 10.3.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.3) - '@storybook/react-vite': 10.3.5(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.3) + '@storybook/react-vite': 10.3.5(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.3) next: 16.2.4(@babel/core@7.29.0)(@playwright/test@1.59.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) react: 19.2.5 react-dom: 19.2.5(react@19.2.5) storybook: 10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) styled-jsx: 5.1.6(@babel/core@7.29.0)(react@19.2.5) - vite: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' - vite-plugin-storybook-nextjs: 3.2.4(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(next@16.2.4(@babel/core@7.29.0)(@playwright/test@1.59.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.3) + vite: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + vite-plugin-storybook-nextjs: 3.2.4(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(next@16.2.4(@babel/core@7.29.0)(@playwright/test@1.59.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.3) optionalDependencies: typescript: 6.0.3 transitivePeerDependencies: @@ -10701,11 +10655,11 @@ snapshots: react-dom: 19.2.5(react@19.2.5) storybook: 10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@storybook/react-vite@10.3.5(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.3)': + '@storybook/react-vite@10.3.5(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.3)': dependencies: - '@joshwooding/vite-plugin-react-docgen-typescript': 0.7.0(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3) + '@joshwooding/vite-plugin-react-docgen-typescript': 0.7.0(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3) '@rollup/pluginutils': 5.3.0 - '@storybook/builder-vite': 10.3.5(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) + '@storybook/builder-vite': 10.3.5(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)) '@storybook/react': 10.3.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.3) empathic: 2.0.0 magic-string: 0.30.21 @@ -10715,7 +10669,7 @@ snapshots: resolve: 1.22.11 storybook: 10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) tsconfig-paths: 4.2.0 - vite: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' transitivePeerDependencies: - esbuild - rollup @@ -10854,12 +10808,12 @@ snapshots: postcss-selector-parser: 6.0.10 tailwindcss: 4.2.4 - '@tailwindcss/vite@4.2.4(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))': + '@tailwindcss/vite@4.2.4(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))': dependencies: '@tailwindcss/node': 4.2.4 '@tailwindcss/oxide': 4.2.4 tailwindcss: 4.2.4 - vite: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' '@tanstack/devtools-client@0.0.6': dependencies: @@ -10905,7 +10859,7 @@ snapshots: - csstype - utf-8-validate - '@tanstack/eslint-plugin-query@5.100.5(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3)': + '@tanstack/eslint-plugin-query@5.100.6(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3)': dependencies: '@typescript-eslint/utils': 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) eslint: 10.2.1(jiti@2.6.1) @@ -10938,9 +10892,9 @@ snapshots: '@tanstack/pacer-lite@0.1.1': {} - '@tanstack/query-core@5.100.5': {} + '@tanstack/query-core@5.100.6': {} - '@tanstack/query-devtools@5.100.5': {} + '@tanstack/query-devtools@5.100.6': {} '@tanstack/react-devtools@0.10.2(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(csstype@3.2.3)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': dependencies: @@ -10974,15 +10928,15 @@ snapshots: transitivePeerDependencies: - react-dom - '@tanstack/react-query-devtools@5.100.5(@tanstack/react-query@5.100.5(react@19.2.5))(react@19.2.5)': + '@tanstack/react-query-devtools@5.100.6(@tanstack/react-query@5.100.6(react@19.2.5))(react@19.2.5)': dependencies: - '@tanstack/query-devtools': 5.100.5 - '@tanstack/react-query': 5.100.5(react@19.2.5) + '@tanstack/query-devtools': 5.100.6 + '@tanstack/react-query': 5.100.6(react@19.2.5) react: 19.2.5 - '@tanstack/react-query@5.100.5(react@19.2.5)': + '@tanstack/react-query@5.100.6(react@19.2.5)': dependencies: - '@tanstack/query-core': 5.100.5 + '@tanstack/query-core': 5.100.6 react: 19.2.5 '@tanstack/react-store@0.9.3(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': @@ -11038,46 +10992,41 @@ snapshots: dependencies: '@testing-library/dom': 10.4.1 - '@tsslint/cli@3.0.4(@tsslint/compat-eslint@3.0.4(jiti@2.6.1)(typescript@6.0.3))(typescript@6.0.3)': + '@tsslint/cli@3.1.0(@tsslint/compat-eslint@3.1.0(typescript@6.0.3))(typescript@6.0.3)': dependencies: - '@clack/prompts': 0.8.2 - '@tsslint/config': 3.0.4(@tsslint/compat-eslint@3.0.4(jiti@2.6.1)(typescript@6.0.3))(typescript@6.0.3) - '@tsslint/core': 3.0.4 + '@tsslint/config': 3.1.0(@tsslint/compat-eslint@3.1.0(typescript@6.0.3))(typescript@6.0.3) + '@tsslint/core': 3.1.0 '@volar/language-core': 2.4.28 '@volar/language-hub': 0.0.1 '@volar/typescript': 2.4.28 - minimatch: 10.2.4 + minimatch: 10.2.5 typescript: 6.0.3 transitivePeerDependencies: - '@tsslint/compat-eslint' - tsl - '@tsslint/compat-eslint@3.0.4(jiti@2.6.1)(typescript@6.0.3)': + '@tsslint/compat-eslint@3.1.0(typescript@6.0.3)': dependencies: - '@tsslint/types': 3.0.4 - '@typescript-eslint/parser': 8.59.0(eslint@9.27.0(jiti@2.6.1))(typescript@6.0.3) - eslint: 9.27.0(jiti@2.6.1) - transitivePeerDependencies: - - jiti - - supports-color - - typescript + '@tsslint/types': 3.1.0 + esquery: 1.7.0 + typescript: 6.0.3 - '@tsslint/config@3.0.4(@tsslint/compat-eslint@3.0.4(jiti@2.6.1)(typescript@6.0.3))(typescript@6.0.3)': + '@tsslint/config@3.1.0(@tsslint/compat-eslint@3.1.0(typescript@6.0.3))(typescript@6.0.3)': dependencies: - '@tsslint/types': 3.0.4 - minimatch: 10.2.4 + '@tsslint/types': 3.1.0 + minimatch: 10.2.5 ts-api-utils: 2.5.0(typescript@6.0.3) optionalDependencies: - '@tsslint/compat-eslint': 3.0.4(jiti@2.6.1)(typescript@6.0.3) + '@tsslint/compat-eslint': 3.1.0(typescript@6.0.3) transitivePeerDependencies: - typescript - '@tsslint/core@3.0.4': + '@tsslint/core@3.1.0': dependencies: - '@tsslint/types': 3.0.4 - minimatch: 10.2.4 + '@tsslint/types': 3.1.0 + minimatch: 10.2.5 - '@tsslint/types@3.0.4': {} + '@tsslint/types@3.1.0': {} '@tybys/wasm-util@0.10.1': dependencies: @@ -11295,8 +11244,7 @@ snapshots: '@types/sortablejs@1.15.9': {} - '@types/trusted-types@2.0.7': - optional: true + '@types/trusted-types@2.0.7': {} '@types/unist@2.0.11': {} @@ -11331,14 +11279,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.59.0(@typescript-eslint/parser@8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.59.1(@typescript-eslint/parser@8.59.1(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.59.0 - '@typescript-eslint/type-utils': 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) - '@typescript-eslint/utils': 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.59.0 + '@typescript-eslint/parser': 8.59.1(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.59.1 + '@typescript-eslint/type-utils': 8.59.1(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) + '@typescript-eslint/utils': 8.59.1(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.59.1 eslint: 10.2.1(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 @@ -11359,34 +11307,22 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3)': + '@typescript-eslint/parser@8.59.1(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3)': dependencies: - '@typescript-eslint/scope-manager': 8.59.0 - '@typescript-eslint/types': 8.59.0 - '@typescript-eslint/typescript-estree': 8.59.0(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.59.0 + '@typescript-eslint/scope-manager': 8.59.1 + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/typescript-estree': 8.59.1(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.59.1 debug: 4.4.3(supports-color@8.1.1) eslint: 10.2.1(jiti@2.6.1) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.59.0(eslint@9.27.0(jiti@2.6.1))(typescript@6.0.3)': - dependencies: - '@typescript-eslint/scope-manager': 8.59.0 - '@typescript-eslint/types': 8.59.0 - '@typescript-eslint/typescript-estree': 8.59.0(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.59.0 - debug: 4.4.3(supports-color@8.1.1) - eslint: 9.27.0(jiti@2.6.1) - typescript: 6.0.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/project-service@8.58.2(typescript@6.0.3)': dependencies: '@typescript-eslint/tsconfig-utils': 8.58.2(typescript@6.0.3) - '@typescript-eslint/types': 8.58.2 + '@typescript-eslint/types': 8.59.0 debug: 4.4.3(supports-color@8.1.1) typescript: 6.0.3 transitivePeerDependencies: @@ -11401,6 +11337,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/project-service@8.59.1(typescript@6.0.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.59.1(typescript@6.0.3) + '@typescript-eslint/types': 8.59.1 + debug: 4.4.3(supports-color@8.1.1) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/scope-manager@8.58.2': dependencies: '@typescript-eslint/types': 8.58.2 @@ -11411,6 +11356,11 @@ snapshots: '@typescript-eslint/types': 8.59.0 '@typescript-eslint/visitor-keys': 8.59.0 + '@typescript-eslint/scope-manager@8.59.1': + dependencies: + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/visitor-keys': 8.59.1 + '@typescript-eslint/tsconfig-utils@8.58.2(typescript@6.0.3)': dependencies: typescript: 6.0.3 @@ -11419,6 +11369,10 @@ snapshots: dependencies: typescript: 6.0.3 + '@typescript-eslint/tsconfig-utils@8.59.1(typescript@6.0.3)': + dependencies: + typescript: 6.0.3 + '@typescript-eslint/type-utils@8.58.2(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3)': dependencies: '@typescript-eslint/types': 8.58.2 @@ -11431,11 +11385,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.59.1(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.59.0 - '@typescript-eslint/typescript-estree': 8.59.0(typescript@6.0.3) - '@typescript-eslint/utils': 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/typescript-estree': 8.59.1(typescript@6.0.3) + '@typescript-eslint/utils': 8.59.1(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) debug: 4.4.3(supports-color@8.1.1) eslint: 10.2.1(jiti@2.6.1) ts-api-utils: 2.5.0(typescript@6.0.3) @@ -11447,6 +11401,8 @@ snapshots: '@typescript-eslint/types@8.59.0': {} + '@typescript-eslint/types@8.59.1': {} + '@typescript-eslint/typescript-estree@8.58.2(typescript@6.0.3)': dependencies: '@typescript-eslint/project-service': 8.58.2(typescript@6.0.3) @@ -11454,9 +11410,9 @@ snapshots: '@typescript-eslint/types': 8.58.2 '@typescript-eslint/visitor-keys': 8.58.2 debug: 4.4.3(supports-color@8.1.1) - minimatch: 10.2.4 + minimatch: 10.2.5 semver: 7.7.4 - tinyglobby: 0.2.15 + tinyglobby: 0.2.16 ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: @@ -11469,7 +11425,22 @@ snapshots: '@typescript-eslint/types': 8.59.0 '@typescript-eslint/visitor-keys': 8.59.0 debug: 4.4.3(supports-color@8.1.1) - minimatch: 10.2.4 + minimatch: 10.2.5 + semver: 7.7.4 + tinyglobby: 0.2.16 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/typescript-estree@8.59.1(typescript@6.0.3)': + dependencies: + '@typescript-eslint/project-service': 8.59.1(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.59.1(typescript@6.0.3) + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/visitor-keys': 8.59.1 + debug: 4.4.3(supports-color@8.1.1) + minimatch: 10.2.5 semver: 7.7.4 tinyglobby: 0.2.16 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -11499,6 +11470,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/utils@8.59.1(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@10.2.1(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.59.1 + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/typescript-estree': 8.59.1(typescript@6.0.3) + eslint: 10.2.1(jiti@2.6.1) + typescript: 6.0.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/visitor-keys@8.58.2': dependencies: '@typescript-eslint/types': 8.58.2 @@ -11509,36 +11491,41 @@ snapshots: '@typescript-eslint/types': 8.59.0 eslint-visitor-keys: 5.0.1 - '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260426.1': + '@typescript-eslint/visitor-keys@8.59.1': + dependencies: + '@typescript-eslint/types': 8.59.1 + eslint-visitor-keys: 5.0.1 + + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260428.1': optional: true - '@typescript/native-preview-darwin-x64@7.0.0-dev.20260426.1': + '@typescript/native-preview-darwin-x64@7.0.0-dev.20260428.1': optional: true - '@typescript/native-preview-linux-arm64@7.0.0-dev.20260426.1': + '@typescript/native-preview-linux-arm64@7.0.0-dev.20260428.1': optional: true - '@typescript/native-preview-linux-arm@7.0.0-dev.20260426.1': + '@typescript/native-preview-linux-arm@7.0.0-dev.20260428.1': optional: true - '@typescript/native-preview-linux-x64@7.0.0-dev.20260426.1': + '@typescript/native-preview-linux-x64@7.0.0-dev.20260428.1': optional: true - '@typescript/native-preview-win32-arm64@7.0.0-dev.20260426.1': + '@typescript/native-preview-win32-arm64@7.0.0-dev.20260428.1': optional: true - '@typescript/native-preview-win32-x64@7.0.0-dev.20260426.1': + '@typescript/native-preview-win32-x64@7.0.0-dev.20260428.1': optional: true - '@typescript/native-preview@7.0.0-dev.20260426.1': + '@typescript/native-preview@7.0.0-dev.20260428.1': optionalDependencies: - '@typescript/native-preview-darwin-arm64': 7.0.0-dev.20260426.1 - '@typescript/native-preview-darwin-x64': 7.0.0-dev.20260426.1 - '@typescript/native-preview-linux-arm': 7.0.0-dev.20260426.1 - '@typescript/native-preview-linux-arm64': 7.0.0-dev.20260426.1 - '@typescript/native-preview-linux-x64': 7.0.0-dev.20260426.1 - '@typescript/native-preview-win32-arm64': 7.0.0-dev.20260426.1 - '@typescript/native-preview-win32-x64': 7.0.0-dev.20260426.1 + '@typescript/native-preview-darwin-arm64': 7.0.0-dev.20260428.1 + '@typescript/native-preview-darwin-x64': 7.0.0-dev.20260428.1 + '@typescript/native-preview-linux-arm': 7.0.0-dev.20260428.1 + '@typescript/native-preview-linux-arm64': 7.0.0-dev.20260428.1 + '@typescript/native-preview-linux-x64': 7.0.0-dev.20260428.1 + '@typescript/native-preview-win32-arm64': 7.0.0-dev.20260428.1 + '@typescript/native-preview-win32-x64': 7.0.0-dev.20260428.1 '@ungap/structured-clone@1.3.0': {} @@ -11568,12 +11555,12 @@ snapshots: '@resvg/resvg-wasm': 2.4.0 satori: 0.16.0 - '@vitejs/devtools-kit@0.1.11(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3)(ws@8.20.0)': + '@vitejs/devtools-kit@0.1.11(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3)(ws@8.20.0)': dependencies: '@vitejs/devtools-rpc': 0.1.11(typescript@6.0.3)(ws@8.20.0) birpc: 4.0.0 ohash: 2.0.11 - vite: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' transitivePeerDependencies: - typescript - ws @@ -11590,12 +11577,12 @@ snapshots: transitivePeerDependencies: - typescript - '@vitejs/plugin-react@6.0.1(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))': + '@vitejs/plugin-react@6.0.1(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.7 - vite: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' - '@vitejs/plugin-rsc@0.5.25(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(react-dom@19.2.5(react@19.2.5))(react-server-dom-webpack@19.2.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react@19.2.5)': + '@vitejs/plugin-rsc@0.5.25(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(react-dom@19.2.5(react@19.2.5))(react-server-dom-webpack@19.2.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react@19.2.5)': dependencies: '@rolldown/pluginutils': 1.0.0-rc.17 es-module-lexer: 2.0.0 @@ -11606,12 +11593,12 @@ snapshots: srvx: 0.11.15 strip-literal: 3.1.0 turbo-stream: 3.2.0 - vite: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' - vitefu: 1.1.3(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)) + vite: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + vitefu: 1.1.3(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)) optionalDependencies: react-server-dom-webpack: 19.2.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5) - '@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)': + '@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.1.5 @@ -11623,7 +11610,7 @@ snapshots: obug: 2.1.1 std-env: 4.0.0 tinyrainbow: 3.1.0 - vitest: '@voidzero-dev/vite-plus-test@0.1.19(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + vitest: '@voidzero-dev/vite-plus-test@0.1.20(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' transitivePeerDependencies: - '@arethetypeswrong/core' - '@edge-runtime/vm' @@ -11653,12 +11640,12 @@ snapshots: - vite - yaml - '@vitest/eslint-plugin@1.6.15(@types/node@25.6.0)(@typescript-eslint/eslint-plugin@8.58.2(@typescript-eslint/parser@8.58.2(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(eslint@10.2.1(jiti@2.6.1))(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)': + '@vitest/eslint-plugin@1.6.15(@types/node@25.6.0)(@typescript-eslint/eslint-plugin@8.58.2(@typescript-eslint/parser@8.58.2(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(eslint@10.2.1(jiti@2.6.1))(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)': dependencies: '@typescript-eslint/scope-manager': 8.59.0 '@typescript-eslint/utils': 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) eslint: 10.2.1(jiti@2.6.1) - vitest: '@voidzero-dev/vite-plus-test@0.1.19(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + vitest: '@voidzero-dev/vite-plus-test@0.1.20(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' optionalDependencies: '@typescript-eslint/eslint-plugin': 8.58.2(@typescript-eslint/parser@8.58.2(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) typescript: 6.0.3 @@ -11724,12 +11711,12 @@ snapshots: convert-source-map: 2.0.0 tinyrainbow: 3.1.0 - '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)': + '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)': dependencies: - '@oxc-project/runtime': 0.126.0 - '@oxc-project/types': 0.126.0 + '@oxc-project/runtime': 0.127.0 + '@oxc-project/types': 0.127.0 lightningcss: 1.32.0 - postcss: 8.5.9 + postcss: 8.5.12 optionalDependencies: '@types/node': 25.6.0 esbuild: 0.27.2 @@ -11739,29 +11726,29 @@ snapshots: typescript: 6.0.3 yaml: 2.8.3 - '@voidzero-dev/vite-plus-darwin-arm64@0.1.19': + '@voidzero-dev/vite-plus-darwin-arm64@0.1.20': optional: true - '@voidzero-dev/vite-plus-darwin-x64@0.1.19': + '@voidzero-dev/vite-plus-darwin-x64@0.1.20': optional: true - '@voidzero-dev/vite-plus-linux-arm64-gnu@0.1.19': + '@voidzero-dev/vite-plus-linux-arm64-gnu@0.1.20': optional: true - '@voidzero-dev/vite-plus-linux-arm64-musl@0.1.19': + '@voidzero-dev/vite-plus-linux-arm64-musl@0.1.20': optional: true - '@voidzero-dev/vite-plus-linux-x64-gnu@0.1.19': + '@voidzero-dev/vite-plus-linux-x64-gnu@0.1.20': optional: true - '@voidzero-dev/vite-plus-linux-x64-musl@0.1.19': + '@voidzero-dev/vite-plus-linux-x64-musl@0.1.20': optional: true - '@voidzero-dev/vite-plus-test@0.1.19(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)': + '@voidzero-dev/vite-plus-test@0.1.20(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 - '@voidzero-dev/vite-plus-core': 0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) + '@voidzero-dev/vite-plus-core': 0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) es-module-lexer: 1.7.0 obug: 2.1.1 pixelmatch: 7.1.0 @@ -11771,11 +11758,11 @@ snapshots: tinybench: 2.9.0 tinyexec: 1.0.4 tinyglobby: 0.2.16 - vite: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' ws: 8.20.0 optionalDependencies: '@types/node': 25.6.0 - '@vitest/coverage-v8': 4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) + '@vitest/coverage-v8': 4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) happy-dom: 20.9.0 transitivePeerDependencies: - '@arethetypeswrong/core' @@ -11798,10 +11785,10 @@ snapshots: - utf-8-validate - yaml - '@voidzero-dev/vite-plus-win32-arm64-msvc@0.1.19': + '@voidzero-dev/vite-plus-win32-arm64-msvc@0.1.20': optional: true - '@voidzero-dev/vite-plus-win32-x64-msvc@0.1.19': + '@voidzero-dev/vite-plus-win32-x64-msvc@0.1.20': optional: true '@volar/language-core@2.4.28': @@ -11930,8 +11917,6 @@ snapshots: bail@2.0.2: {} - balanced-match@1.0.2: {} - balanced-match@4.0.4: {} base64-arraybuffer@1.0.2: {} @@ -11956,11 +11941,6 @@ snapshots: boolbase@1.0.0: {} - brace-expansion@1.1.13: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - brace-expansion@5.0.5: dependencies: balanced-match: 4.0.4 @@ -11999,8 +11979,6 @@ snapshots: cac@7.0.0: {} - callsites@3.1.0: {} - camelize@1.0.1: {} caniuse-lite@1.0.30001781: {} @@ -12117,6 +12095,12 @@ snapshots: client-only@0.0.1: {} + cliui@8.0.1: + dependencies: + string-width: 8.2.1 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + clsx@2.1.1: {} cmdk@1.1.1(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5): @@ -12169,7 +12153,14 @@ snapshots: compare-versions@6.1.1: {} - concat-map@0.0.1: {} + concurrently@9.2.1: + dependencies: + chalk: 4.1.2 + rxjs: 7.8.2 + shell-quote: 1.8.3 + supports-color: 8.1.1 + tree-kill: 1.2.2 + yargs: 17.7.2 confbox@0.1.8: {} @@ -12177,9 +12168,7 @@ snapshots: convert-source-map@2.0.0: {} - copy-to-clipboard@3.3.3: - dependencies: - toggle-selection: 1.0.6 + copy-to-clipboard@4.0.2: {} core-js-compat@3.49.0: dependencies: @@ -12594,6 +12583,8 @@ snapshots: entities@7.0.1: {} + entities@8.0.0: {} + error-stack-parser-es@1.0.5: {} error-stack-parser@2.1.4: @@ -12680,11 +12671,11 @@ snapshots: esquery: 1.7.0 jsonc-eslint-parser: 3.1.0 - eslint-markdown@0.6.1(eslint@10.2.1(jiti@2.6.1)): + eslint-markdown@0.7.0(eslint@10.2.1(jiti@2.6.1)): dependencies: '@eslint/markdown': 7.5.1 micromark-util-normalize-identifier: 2.0.1 - parse5: 8.0.0 + parse5: 8.0.1 optionalDependencies: eslint: 10.2.1(jiti@2.6.1) transitivePeerDependencies: @@ -12698,7 +12689,7 @@ snapshots: dependencies: eslint: 10.2.1(jiti@2.6.1) - eslint-plugin-better-tailwindcss@4.4.1(eslint@10.2.1(jiti@2.6.1))(oxlint@1.60.0(oxlint-tsgolint@0.21.1))(tailwindcss@4.2.4)(typescript@6.0.3): + eslint-plugin-better-tailwindcss@4.5.0(eslint@10.2.1(jiti@2.6.1))(oxlint@1.61.0(oxlint-tsgolint@0.22.0))(tailwindcss@4.2.4)(typescript@6.0.3): dependencies: '@eslint/css-tree': 4.0.1 '@valibot/to-json-schema': 1.6.0(valibot@1.3.1(typescript@6.0.3)) @@ -12711,16 +12702,16 @@ snapshots: valibot: 1.3.1(typescript@6.0.3) optionalDependencies: eslint: 10.2.1(jiti@2.6.1) - oxlint: 1.60.0(oxlint-tsgolint@0.21.1) + oxlint: 1.61.0(oxlint-tsgolint@0.22.0) transitivePeerDependencies: - '@eslint/css' - typescript - eslint-plugin-command@3.5.2(@typescript-eslint/typescript-estree@8.59.0(typescript@6.0.3))(@typescript-eslint/utils@8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(eslint@10.2.1(jiti@2.6.1)): + eslint-plugin-command@3.5.2(@typescript-eslint/typescript-estree@8.59.1(typescript@6.0.3))(@typescript-eslint/utils@8.59.1(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3))(eslint@10.2.1(jiti@2.6.1)): dependencies: '@es-joy/jsdoccomment': 0.84.0 - '@typescript-eslint/typescript-estree': 8.59.0(typescript@6.0.3) - '@typescript-eslint/utils': 8.59.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.59.1(typescript@6.0.3) + '@typescript-eslint/utils': 8.59.1(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) eslint: 10.2.1(jiti@2.6.1) eslint-plugin-depend@1.5.0(eslint@10.2.1(jiti@2.6.1)): @@ -13038,11 +13029,6 @@ snapshots: dependencies: eslint: 10.2.1(jiti@2.6.1) - eslint-scope@8.4.0: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - eslint-scope@9.1.2: dependencies: '@types/esrecurse': 4.3.1 @@ -13093,48 +13079,6 @@ snapshots: transitivePeerDependencies: - supports-color - eslint@9.27.0(jiti@2.6.1): - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.27.0(jiti@2.6.1)) - '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.20.1 - '@eslint/config-helpers': 0.2.3 - '@eslint/core': 0.14.0 - '@eslint/eslintrc': 3.3.5 - '@eslint/js': 9.27.0 - '@eslint/plugin-kit': 0.3.5 - '@humanfs/node': 0.16.7 - '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.3 - '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 - ajv: 6.14.0 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.3(supports-color@8.1.1) - escape-string-regexp: 4.0.0 - eslint-scope: 8.4.0 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - esquery: 1.7.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 8.0.0 - find-up: 5.0.0 - glob-parent: 6.0.2 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - json-stable-stringify-without-jsonify: 1.0.1 - lodash.merge: 4.6.2 - minimatch: 3.1.5 - natural-compare: 1.4.0 - optionator: 0.9.4 - optionalDependencies: - jiti: 2.6.1 - transitivePeerDependencies: - - supports-color - espree@10.4.0: dependencies: acorn: 8.16.0 @@ -13312,6 +13256,8 @@ snapshots: gensync@1.0.0-beta.2: {} + get-caller-file@2.0.5: {} + get-east-asian-width@1.5.0: {} get-nonce@1.0.1: {} @@ -13351,8 +13297,6 @@ snapshots: dependencies: ini: 2.0.0 - globals@14.0.0: {} - globals@15.15.0: {} globals@17.5.0: {} @@ -13565,9 +13509,7 @@ snapshots: dependencies: '@babel/runtime': 7.29.2 - i18next@26.0.6(typescript@6.0.3): - dependencies: - '@babel/runtime': 7.29.2 + i18next@26.0.8(typescript@6.0.3): optionalDependencies: typescript: 6.0.3 @@ -13598,11 +13540,6 @@ snapshots: immer@11.1.4: {} - import-fresh@3.3.1: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - imurmurhash@0.1.4: {} indent-string@4.0.0: {} @@ -13807,12 +13744,12 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - lexical-code-no-prism@0.41.0(@lexical/utils@0.43.0)(lexical@0.43.0): + lexical-code-no-prism@0.41.0(@lexical/utils@0.44.0)(lexical@0.44.0): dependencies: - '@lexical/utils': 0.43.0 - lexical: 0.43.0 + '@lexical/utils': 0.44.0 + lexical: 0.44.0 - lexical@0.43.0: {} + lexical@0.44.0: {} lightningcss-android-arm64@1.32.0: optional: true @@ -14484,10 +14421,6 @@ snapshots: dependencies: brace-expansion: 5.0.5 - minimatch@3.1.5: - dependencies: - brace-expansion: 1.1.13 - minimist@1.2.8: {} minipass@7.1.3: {} @@ -14703,61 +14636,61 @@ snapshots: - '@emnapi/core' - '@emnapi/runtime' - oxfmt@0.45.0: + oxfmt@0.46.0: dependencies: tinypool: 2.1.0 optionalDependencies: - '@oxfmt/binding-android-arm-eabi': 0.45.0 - '@oxfmt/binding-android-arm64': 0.45.0 - '@oxfmt/binding-darwin-arm64': 0.45.0 - '@oxfmt/binding-darwin-x64': 0.45.0 - '@oxfmt/binding-freebsd-x64': 0.45.0 - '@oxfmt/binding-linux-arm-gnueabihf': 0.45.0 - '@oxfmt/binding-linux-arm-musleabihf': 0.45.0 - '@oxfmt/binding-linux-arm64-gnu': 0.45.0 - '@oxfmt/binding-linux-arm64-musl': 0.45.0 - '@oxfmt/binding-linux-ppc64-gnu': 0.45.0 - '@oxfmt/binding-linux-riscv64-gnu': 0.45.0 - '@oxfmt/binding-linux-riscv64-musl': 0.45.0 - '@oxfmt/binding-linux-s390x-gnu': 0.45.0 - '@oxfmt/binding-linux-x64-gnu': 0.45.0 - '@oxfmt/binding-linux-x64-musl': 0.45.0 - '@oxfmt/binding-openharmony-arm64': 0.45.0 - '@oxfmt/binding-win32-arm64-msvc': 0.45.0 - '@oxfmt/binding-win32-ia32-msvc': 0.45.0 - '@oxfmt/binding-win32-x64-msvc': 0.45.0 + '@oxfmt/binding-android-arm-eabi': 0.46.0 + '@oxfmt/binding-android-arm64': 0.46.0 + '@oxfmt/binding-darwin-arm64': 0.46.0 + '@oxfmt/binding-darwin-x64': 0.46.0 + '@oxfmt/binding-freebsd-x64': 0.46.0 + '@oxfmt/binding-linux-arm-gnueabihf': 0.46.0 + '@oxfmt/binding-linux-arm-musleabihf': 0.46.0 + '@oxfmt/binding-linux-arm64-gnu': 0.46.0 + '@oxfmt/binding-linux-arm64-musl': 0.46.0 + '@oxfmt/binding-linux-ppc64-gnu': 0.46.0 + '@oxfmt/binding-linux-riscv64-gnu': 0.46.0 + '@oxfmt/binding-linux-riscv64-musl': 0.46.0 + '@oxfmt/binding-linux-s390x-gnu': 0.46.0 + '@oxfmt/binding-linux-x64-gnu': 0.46.0 + '@oxfmt/binding-linux-x64-musl': 0.46.0 + '@oxfmt/binding-openharmony-arm64': 0.46.0 + '@oxfmt/binding-win32-arm64-msvc': 0.46.0 + '@oxfmt/binding-win32-ia32-msvc': 0.46.0 + '@oxfmt/binding-win32-x64-msvc': 0.46.0 - oxlint-tsgolint@0.21.1: + oxlint-tsgolint@0.22.0: optionalDependencies: - '@oxlint-tsgolint/darwin-arm64': 0.21.1 - '@oxlint-tsgolint/darwin-x64': 0.21.1 - '@oxlint-tsgolint/linux-arm64': 0.21.1 - '@oxlint-tsgolint/linux-x64': 0.21.1 - '@oxlint-tsgolint/win32-arm64': 0.21.1 - '@oxlint-tsgolint/win32-x64': 0.21.1 + '@oxlint-tsgolint/darwin-arm64': 0.22.0 + '@oxlint-tsgolint/darwin-x64': 0.22.0 + '@oxlint-tsgolint/linux-arm64': 0.22.0 + '@oxlint-tsgolint/linux-x64': 0.22.0 + '@oxlint-tsgolint/win32-arm64': 0.22.0 + '@oxlint-tsgolint/win32-x64': 0.22.0 - oxlint@1.60.0(oxlint-tsgolint@0.21.1): + oxlint@1.61.0(oxlint-tsgolint@0.22.0): optionalDependencies: - '@oxlint/binding-android-arm-eabi': 1.60.0 - '@oxlint/binding-android-arm64': 1.60.0 - '@oxlint/binding-darwin-arm64': 1.60.0 - '@oxlint/binding-darwin-x64': 1.60.0 - '@oxlint/binding-freebsd-x64': 1.60.0 - '@oxlint/binding-linux-arm-gnueabihf': 1.60.0 - '@oxlint/binding-linux-arm-musleabihf': 1.60.0 - '@oxlint/binding-linux-arm64-gnu': 1.60.0 - '@oxlint/binding-linux-arm64-musl': 1.60.0 - '@oxlint/binding-linux-ppc64-gnu': 1.60.0 - '@oxlint/binding-linux-riscv64-gnu': 1.60.0 - '@oxlint/binding-linux-riscv64-musl': 1.60.0 - '@oxlint/binding-linux-s390x-gnu': 1.60.0 - '@oxlint/binding-linux-x64-gnu': 1.60.0 - '@oxlint/binding-linux-x64-musl': 1.60.0 - '@oxlint/binding-openharmony-arm64': 1.60.0 - '@oxlint/binding-win32-arm64-msvc': 1.60.0 - '@oxlint/binding-win32-ia32-msvc': 1.60.0 - '@oxlint/binding-win32-x64-msvc': 1.60.0 - oxlint-tsgolint: 0.21.1 + '@oxlint/binding-android-arm-eabi': 1.61.0 + '@oxlint/binding-android-arm64': 1.61.0 + '@oxlint/binding-darwin-arm64': 1.61.0 + '@oxlint/binding-darwin-x64': 1.61.0 + '@oxlint/binding-freebsd-x64': 1.61.0 + '@oxlint/binding-linux-arm-gnueabihf': 1.61.0 + '@oxlint/binding-linux-arm-musleabihf': 1.61.0 + '@oxlint/binding-linux-arm64-gnu': 1.61.0 + '@oxlint/binding-linux-arm64-musl': 1.61.0 + '@oxlint/binding-linux-ppc64-gnu': 1.61.0 + '@oxlint/binding-linux-riscv64-gnu': 1.61.0 + '@oxlint/binding-linux-riscv64-musl': 1.61.0 + '@oxlint/binding-linux-s390x-gnu': 1.61.0 + '@oxlint/binding-linux-x64-gnu': 1.61.0 + '@oxlint/binding-linux-x64-musl': 1.61.0 + '@oxlint/binding-openharmony-arm64': 1.61.0 + '@oxlint/binding-win32-arm64-msvc': 1.61.0 + '@oxlint/binding-win32-ia32-msvc': 1.61.0 + '@oxlint/binding-win32-x64-msvc': 1.61.0 + oxlint-tsgolint: 0.22.0 p-limit@3.1.0: dependencies: @@ -14781,10 +14714,6 @@ snapshots: papaparse@5.5.3: {} - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - parse-css-color@0.2.1: dependencies: color-name: 1.1.4 @@ -14827,9 +14756,9 @@ snapshots: dependencies: entities: 6.0.1 - parse5@8.0.0: + parse5@8.0.1: dependencies: - entities: 6.0.1 + entities: 8.0.0 path-browserify@1.0.1: {} @@ -14940,12 +14869,6 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - postcss@8.5.9: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - powershell-utils@0.1.0: {} prebuild-install@7.1.3: @@ -15072,11 +14995,11 @@ snapshots: react: 19.2.5 react-dom: 19.2.5(react@19.2.5) - react-i18next@16.5.8(i18next@26.0.6(typescript@6.0.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3): + react-i18next@16.5.8(i18next@26.0.8(typescript@6.0.3))(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@6.0.3): dependencies: '@babel/runtime': 7.29.2 html-parse-stringify: 3.0.1 - i18next: 26.0.6(typescript@6.0.3) + i18next: 26.0.8(typescript@6.0.3) react: 19.2.5 use-sync-external-store: 1.6.0(react@19.2.5) optionalDependencies: @@ -15378,14 +15301,14 @@ snapshots: repeat-string@1.6.1: {} + require-directory@2.1.1: {} + reselect@5.1.1: {} reserved-identifiers@1.2.0: {} resize-observer-polyfill@1.5.1: {} - resolve-from@4.0.0: {} - resolve-pkg-maps@1.0.0: {} resolve@1.22.11: @@ -15413,6 +15336,10 @@ snapshots: rw@1.3.3: {} + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + safe-buffer@5.2.1: optional: true @@ -15493,6 +15420,8 @@ snapshots: shebang-regex@3.0.0: {} + shell-quote@1.8.3: {} + shiki@4.0.2: dependencies: '@shikijs/core': 4.0.2 @@ -15660,6 +15589,10 @@ snapshots: character-entities-html4: 2.1.0 character-entities-legacy: 3.0.0 + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + strip-ansi@7.2.0: dependencies: ansi-regex: 6.2.2 @@ -15675,8 +15608,6 @@ snapshots: strip-json-comments@2.0.1: optional: true - strip-json-comments@3.1.1: {} - strip-json-comments@5.0.3: {} strip-literal@3.1.0: @@ -15783,11 +15714,6 @@ snapshots: tinyexec@1.0.4: {} - tinyglobby@0.2.15: - dependencies: - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 - tinyglobby@0.2.16: dependencies: fdir: 6.5.0(picomatch@4.0.4) @@ -15801,11 +15727,11 @@ snapshots: tinyspy@4.0.4: {} - tldts-core@7.0.28: {} + tldts-core@7.0.29: {} - tldts@7.0.28: + tldts@7.0.29: dependencies: - tldts-core: 7.0.28 + tldts-core: 7.0.29 to-regex-range@5.0.1: dependencies: @@ -15816,8 +15742,6 @@ snapshots: '@sindresorhus/base62': 1.0.0 reserved-identifiers: 1.2.0 - toggle-selection@1.0.6: {} - toml-eslint-parser@1.0.3: dependencies: eslint-visitor-keys: 5.0.1 @@ -15826,6 +15750,8 @@ snapshots: totalist@3.0.1: {} + tree-kill@1.2.2: {} + trim-lines@3.0.1: {} trough@2.2.0: {} @@ -16041,7 +15967,7 @@ snapshots: uuid@11.1.0: {} - uuid@13.0.0: {} + uuid@14.0.0: {} valibot@1.3.1(typescript@6.0.3): optionalDependencies: @@ -16067,20 +15993,20 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vinext@0.0.41(@mdx-js/rollup@3.1.1)(@vitejs/plugin-react@6.0.1(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)))(@vitejs/plugin-rsc@0.5.25(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(react-dom@19.2.5(react@19.2.5))(react-server-dom-webpack@19.2.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react@19.2.5))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(next@16.2.4(@babel/core@7.29.0)(@playwright/test@1.59.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react-server-dom-webpack@19.2.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react@19.2.5)(typescript@6.0.3): + vinext@0.0.45(@mdx-js/rollup@3.1.1)(@vitejs/plugin-react@6.0.1(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)))(@vitejs/plugin-rsc@0.5.25(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(react-dom@19.2.5(react@19.2.5))(react-server-dom-webpack@19.2.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react@19.2.5))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(next@16.2.4(@babel/core@7.29.0)(@playwright/test@1.59.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react-server-dom-webpack@19.2.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react@19.2.5)(typescript@6.0.3): dependencies: '@unpic/react': 1.0.2(next@16.2.4(@babel/core@7.29.0)(@playwright/test@1.59.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@vercel/og': 0.8.6 - '@vitejs/plugin-react': 6.0.1(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)) + '@vitejs/plugin-react': 6.0.1(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)) magic-string: 0.30.21 react: 19.2.5 react-dom: 19.2.5(react@19.2.5) - vite: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' vite-plugin-commonjs: 0.10.4 - vite-tsconfig-paths: 6.1.1(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3) + vite-tsconfig-paths: 6.1.1(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3) optionalDependencies: '@mdx-js/rollup': 3.1.1 - '@vitejs/plugin-rsc': 0.5.25(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(react-dom@19.2.5(react@19.2.5))(react-server-dom-webpack@19.2.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react@19.2.5) + '@vitejs/plugin-rsc': 0.5.25(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(react-dom@19.2.5(react@19.2.5))(react-server-dom-webpack@19.2.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(react@19.2.5) react-server-dom-webpack: 19.2.5(react-dom@19.2.5(react@19.2.5))(react@19.2.5) transitivePeerDependencies: - next @@ -16100,9 +16026,9 @@ snapshots: fast-glob: 3.3.3 magic-string: 0.30.21 - vite-plugin-inspect@12.0.0-beta.1(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3)(ws@8.20.0): + vite-plugin-inspect@12.0.0-beta.1(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3)(ws@8.20.0): dependencies: - '@vitejs/devtools-kit': 0.1.11(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3)(ws@8.20.0) + '@vitejs/devtools-kit': 0.1.11(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3)(ws@8.20.0) ansis: 4.2.0 error-stack-parser-es: 1.0.5 obug: 2.1.1 @@ -16111,12 +16037,12 @@ snapshots: perfect-debounce: 2.1.0 sirv: 3.0.2 unplugin-utils: 0.3.1 - vite: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' transitivePeerDependencies: - typescript - ws - vite-plugin-storybook-nextjs@3.2.4(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(next@16.2.4(@babel/core@7.29.0)(@playwright/test@1.59.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.3): + vite-plugin-storybook-nextjs@3.2.4(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(next@16.2.4(@babel/core@7.29.0)(@playwright/test@1.59.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(storybook@10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5))(typescript@6.0.3): dependencies: '@next/env': 16.0.0 image-size: 2.0.2 @@ -16125,29 +16051,29 @@ snapshots: next: 16.2.4(@babel/core@7.29.0)(@playwright/test@1.59.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) storybook: 10.3.5(@testing-library/dom@10.4.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5) ts-dedent: 2.2.0 - vite: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' - vite-tsconfig-paths: 5.1.4(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3) + vite: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + vite-tsconfig-paths: 5.1.4(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3) transitivePeerDependencies: - supports-color - typescript - vite-plus@0.1.19(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3): + vite-plus@0.1.20(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3): dependencies: - '@oxc-project/types': 0.126.0 - '@voidzero-dev/vite-plus-core': 0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) - '@voidzero-dev/vite-plus-test': 0.1.19(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) - oxfmt: 0.45.0 - oxlint: 1.60.0(oxlint-tsgolint@0.21.1) - oxlint-tsgolint: 0.21.1 + '@oxc-project/types': 0.127.0 + '@voidzero-dev/vite-plus-core': 0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) + '@voidzero-dev/vite-plus-test': 0.1.20(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3) + oxfmt: 0.46.0 + oxlint: 1.61.0(oxlint-tsgolint@0.22.0) + oxlint-tsgolint: 0.22.0 optionalDependencies: - '@voidzero-dev/vite-plus-darwin-arm64': 0.1.19 - '@voidzero-dev/vite-plus-darwin-x64': 0.1.19 - '@voidzero-dev/vite-plus-linux-arm64-gnu': 0.1.19 - '@voidzero-dev/vite-plus-linux-arm64-musl': 0.1.19 - '@voidzero-dev/vite-plus-linux-x64-gnu': 0.1.19 - '@voidzero-dev/vite-plus-linux-x64-musl': 0.1.19 - '@voidzero-dev/vite-plus-win32-arm64-msvc': 0.1.19 - '@voidzero-dev/vite-plus-win32-x64-msvc': 0.1.19 + '@voidzero-dev/vite-plus-darwin-arm64': 0.1.20 + '@voidzero-dev/vite-plus-darwin-x64': 0.1.20 + '@voidzero-dev/vite-plus-linux-arm64-gnu': 0.1.20 + '@voidzero-dev/vite-plus-linux-arm64-musl': 0.1.20 + '@voidzero-dev/vite-plus-linux-x64-gnu': 0.1.20 + '@voidzero-dev/vite-plus-linux-x64-musl': 0.1.20 + '@voidzero-dev/vite-plus-win32-arm64-msvc': 0.1.20 + '@voidzero-dev/vite-plus-win32-x64-msvc': 0.1.20 transitivePeerDependencies: - '@arethetypeswrong/core' - '@edge-runtime/vm' @@ -16178,36 +16104,36 @@ snapshots: - vite - yaml - vite-tsconfig-paths@5.1.4(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3): + vite-tsconfig-paths@5.1.4(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3): dependencies: debug: 4.4.3(supports-color@8.1.1) globrex: 0.1.2 tsconfck: 3.1.6(typescript@6.0.3) optionalDependencies: - vite: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' transitivePeerDependencies: - supports-color - typescript - vite-tsconfig-paths@6.1.1(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3): + vite-tsconfig-paths@6.1.1(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3): dependencies: debug: 4.4.3(supports-color@8.1.1) globrex: 0.1.2 tsconfck: 3.1.6(typescript@6.0.3) - vite: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' transitivePeerDependencies: - supports-color - typescript - vitefu@1.1.3(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)): + vitefu@1.1.3(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)): optionalDependencies: - vite: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + vite: '@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' - vitest-browser-react@2.2.0(@types/node@25.6.0)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3): + vitest-browser-react@2.2.0(@types/node@25.6.0)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3): dependencies: react: 19.2.5 react-dom: 19.2.5(react@19.2.5) - vitest: '@voidzero-dev/vite-plus-test@0.1.19(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + vitest: '@voidzero-dev/vite-plus-test@0.1.20(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' optionalDependencies: '@types/react': 19.2.14 '@types/react-dom': 19.2.3(@types/react@19.2.14) @@ -16241,11 +16167,11 @@ snapshots: - vite - yaml - vitest-canvas-mock@1.1.4(@voidzero-dev/vite-plus-test@0.1.19(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)): + vitest-canvas-mock@1.1.4(@voidzero-dev/vite-plus-test@0.1.20(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)): dependencies: cssfontparser: 1.2.1 moo-color: 1.0.3 - vitest: '@voidzero-dev/vite-plus-test@0.1.19(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' + vitest: '@voidzero-dev/vite-plus-test@0.1.20(@types/node@25.6.0)(@vitest/coverage-v8@4.1.5(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(@voidzero-dev/vite-plus-core@0.1.20(@types/node@25.6.0)(esbuild@0.27.2)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3))(esbuild@0.27.2)(happy-dom@20.9.0)(jiti@2.6.1)(tsx@4.21.0)(typescript@6.0.3)(yaml@2.8.3)' void-elements@3.1.0: {} @@ -16302,6 +16228,12 @@ snapshots: word-wrap@1.2.5: {} + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 8.2.1 + strip-ansi: 6.0.1 + wrappy@1.0.2: {} ws@8.18.3: {} @@ -16323,6 +16255,8 @@ snapshots: xmlhttprequest-ssl@2.1.2: {} + y18n@5.0.8: {} + yallist@3.1.1: {} yallist@5.0.0: {} @@ -16334,6 +16268,18 @@ snapshots: yaml@2.8.3: {} + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 8.2.1 + y18n: 5.0.8 + yargs-parser: 21.1.1 + yauzl@3.2.1: dependencies: buffer-crc32: 0.2.13 @@ -16380,3 +16326,35 @@ snapshots: use-sync-external-store: 1.6.0(react@19.2.5) zwitch@2.0.4: {} + +time: + '@amplitude/analytics-browser@2.42.0': '2026-04-28T17:01:08.442Z' + '@amplitude/plugin-session-replay-browser@1.28.1': '2026-04-28T17:01:37.145Z' + '@hono/node-server@2.0.0': '2026-04-21T00:25:40.852Z' + '@lexical/link@0.44.0': '2026-04-27T14:47:45.477Z' + '@lexical/list@0.44.0': '2026-04-27T14:47:48.463Z' + '@lexical/react@0.44.0': '2026-04-27T14:48:07.316Z' + '@lexical/selection@0.44.0': '2026-04-27T14:48:15.054Z' + '@lexical/text@0.44.0': '2026-04-27T14:48:23.958Z' + '@lexical/utils@0.44.0': '2026-04-27T14:48:26.689Z' + '@tanstack/eslint-plugin-query@5.100.6': '2026-04-28T16:39:45.129Z' + '@tanstack/react-query-devtools@5.100.6': '2026-04-28T16:39:51.334Z' + '@tanstack/react-query@5.100.6': '2026-04-28T16:39:52.105Z' + '@tsslint/cli@3.1.0': '2026-04-29T04:57:38.423Z' + '@tsslint/compat-eslint@3.1.0': '2026-04-29T04:57:34.593Z' + '@tsslint/config@3.1.0': '2026-04-29T04:57:36.446Z' + '@typescript-eslint/eslint-plugin@8.59.1': '2026-04-27T17:31:50.020Z' + '@typescript-eslint/parser@8.59.1': '2026-04-27T17:31:29.147Z' + '@typescript/native-preview@7.0.0-dev.20260428.1': '2026-04-28T08:09:51.266Z' + '@voidzero-dev/vite-plus-core@0.1.20': '2026-04-29T03:08:39.629Z' + '@voidzero-dev/vite-plus-test@0.1.20': '2026-04-29T03:08:45.501Z' + concurrently@9.2.1: '2025-08-25T09:50:49.138Z' + copy-to-clipboard@4.0.2: '2026-04-24T22:15:18.933Z' + eslint-markdown@0.7.0: '2026-04-25T11:31:20.226Z' + eslint-plugin-better-tailwindcss@4.5.0: '2026-04-28T06:24:47.281Z' + i18next@26.0.8: '2026-04-24T19:20:14.685Z' + lexical@0.44.0: '2026-04-27T14:47:00.970Z' + tldts@7.0.29: '2026-04-28T12:21:32.710Z' + uuid@14.0.0: '2026-04-19T15:15:42.302Z' + vinext@0.0.45: '2026-04-28T11:43:03.463Z' + vite-plus@0.1.20: '2026-04-29T03:08:50.317Z' diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 3b994ee27a..bba9b50682 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,11 @@ +saveExact: true +catalogMode: prefer +dedupeDirectDeps: true +engineStrict: true +minimumReleaseAge: 1440 +optimisticRepeatInstall: true +verifyDepsBeforeRun: install +resolutionMode: time-based allowBuilds: '@parcel/watcher': false canvas: false @@ -5,7 +13,6 @@ allowBuilds: sharp: false autoInstallPeers: false blockExoticSubdeps: true -catalogMode: prefer shellEmulator: true strictDepBuilds: true trustPolicy: no-downgrade @@ -42,13 +49,13 @@ overrides: svgo@>=3.0.0 <3.3.3: 3.3.3 tar@<=7.5.10: 7.5.11 undici@>=7.0.0 <7.24.0: 7.24.0 - vite: npm:@voidzero-dev/vite-plus-core@0.1.19 - vitest: npm:@voidzero-dev/vite-plus-test@0.1.19 + vite: npm:@voidzero-dev/vite-plus-core@0.1.20 + vitest: npm:@voidzero-dev/vite-plus-test@0.1.20 yaml@>=2.0.0 <2.8.3: 2.8.3 yauzl@<3.2.1: 3.2.1 catalog: - '@amplitude/analytics-browser': 2.41.1 - '@amplitude/plugin-session-replay-browser': 1.28.0 + '@amplitude/analytics-browser': 2.42.0 + '@amplitude/plugin-session-replay-browser': 1.28.1 '@antfu/eslint-config': 8.2.0 '@base-ui/react': 1.4.1 '@chromatic-com/storybook': 5.1.2 @@ -61,16 +68,16 @@ catalog: '@formatjs/intl-localematcher': 0.8.4 '@headlessui/react': 2.2.10 '@heroicons/react': 2.2.0 - '@hono/node-server': 1.19.14 + '@hono/node-server': 2.0.0 '@iconify-json/heroicons': 1.2.3 '@iconify-json/ri': 1.2.10 - '@lexical/code': 0.43.0 - '@lexical/link': 0.43.0 - '@lexical/list': 0.43.0 - '@lexical/react': 0.43.0 - '@lexical/selection': 0.43.0 - '@lexical/text': 0.43.0 - '@lexical/utils': 0.43.0 + '@lexical/code': 0.44.0 + '@lexical/link': 0.44.0 + '@lexical/list': 0.44.0 + '@lexical/react': 0.44.0 + '@lexical/selection': 0.44.0 + '@lexical/text': 0.44.0 + '@lexical/utils': 0.44.0 '@mdx-js/loader': 3.1.1 '@mdx-js/react': 3.1.1 '@mdx-js/rollup': 3.1.1 @@ -98,20 +105,20 @@ catalog: '@tailwindcss/postcss': 4.2.4 '@tailwindcss/typography': 0.5.19 '@tailwindcss/vite': 4.2.4 - '@tanstack/eslint-plugin-query': 5.100.5 + '@tanstack/eslint-plugin-query': 5.100.6 '@tanstack/react-devtools': 0.10.2 '@tanstack/react-form': 1.29.1 '@tanstack/react-form-devtools': 0.2.22 - '@tanstack/react-query': 5.100.5 - '@tanstack/react-query-devtools': 5.100.5 + '@tanstack/react-query': 5.100.6 + '@tanstack/react-query-devtools': 5.100.6 '@tanstack/react-virtual': 3.13.24 '@testing-library/dom': 10.4.1 '@testing-library/jest-dom': 6.9.1 '@testing-library/react': 16.3.2 '@testing-library/user-event': 14.6.1 - '@tsslint/cli': 3.0.4 - '@tsslint/compat-eslint': 3.0.4 - '@tsslint/config': 3.0.4 + '@tsslint/cli': 3.1.0 + '@tsslint/compat-eslint': 3.1.0 + '@tsslint/config': 3.1.0 '@types/js-cookie': 3.0.6 '@types/js-yaml': 4.0.9 '@types/negotiator': 0.6.4 @@ -120,9 +127,9 @@ catalog: '@types/react': 19.2.14 '@types/react-dom': 19.2.3 '@types/sortablejs': 1.15.9 - '@typescript-eslint/eslint-plugin': 8.59.0 - '@typescript-eslint/parser': 8.59.0 - '@typescript/native-preview': 7.0.0-dev.20260426.1 + '@typescript-eslint/eslint-plugin': 8.59.1 + '@typescript-eslint/parser': 8.59.1 + '@typescript/native-preview': 7.0.0-dev.20260428.1 '@vitejs/plugin-react': 6.0.1 '@vitejs/plugin-rsc': 0.5.25 '@vitest/coverage-v8': 4.1.5 @@ -134,7 +141,8 @@ catalog: clsx: 2.1.1 cmdk: 1.1.1 code-inspector-plugin: 1.5.1 - copy-to-clipboard: 3.3.3 + concurrently: ^9.2.1 + copy-to-clipboard: 4.0.2 cron-parser: 5.5.0 dayjs: 1.11.20 decimal.js: 10.6.0 @@ -147,8 +155,8 @@ catalog: emoji-mart: 5.6.0 es-toolkit: 1.46.0 eslint: 10.2.1 - eslint-markdown: 0.6.1 - eslint-plugin-better-tailwindcss: 4.4.1 + eslint-markdown: 0.7.0 + eslint-plugin-better-tailwindcss: 4.5.0 eslint-plugin-hyoban: 0.14.1 eslint-plugin-markdown-preferences: 0.41.1 eslint-plugin-no-barrel-files: 1.3.1 @@ -161,7 +169,7 @@ catalog: hono: 4.12.15 html-entities: 2.6.0 html-to-image: 1.11.13 - i18next: 26.0.6 + i18next: 26.0.8 i18next-resources-to-backend: 1.2.1 iconify-import-svg: 0.2.0 immer: 11.1.4 @@ -174,7 +182,7 @@ catalog: knip: 6.7.0 ky: 2.0.2 lamejs: 1.2.1 - lexical: 0.43.0 + lexical: 0.44.0 loro-crdt: 1.12.0 mermaid: 11.14.0 mime: 4.1.0 @@ -214,18 +222,18 @@ catalog: string-ts: 2.3.1 tailwind-merge: 3.5.0 tailwindcss: 4.2.4 - tldts: 7.0.28 + tldts: 7.0.29 tsx: 4.21.0 typescript: 6.0.3 uglify-js: 3.19.3 unist-util-visit: 5.1.0 use-context-selector: 2.0.0 - uuid: 13.0.0 - vinext: 0.0.41 - vite: npm:@voidzero-dev/vite-plus-core@0.1.19 + uuid: 14.0.0 + vinext: 0.0.45 + vite: npm:@voidzero-dev/vite-plus-core@0.1.20 vite-plugin-inspect: 12.0.0-beta.1 - vite-plus: 0.1.19 - vitest: npm:@voidzero-dev/vite-plus-test@0.1.19 + vite-plus: 0.1.20 + vitest: npm:@voidzero-dev/vite-plus-test@0.1.20 vitest-browser-react: 2.2.0 vitest-canvas-mock: 1.1.4 zod: 4.3.6 diff --git a/web/.npmrc b/web/.npmrc deleted file mode 100644 index cffe8cdef1..0000000000 --- a/web/.npmrc +++ /dev/null @@ -1 +0,0 @@ -save-exact=true diff --git a/web/__tests__/header/nav-flow.test.tsx b/web/__tests__/header/nav-flow.test.tsx index 05955a6c83..667f1e36b7 100644 --- a/web/__tests__/header/nav-flow.test.tsx +++ b/web/__tests__/header/nav-flow.test.tsx @@ -195,9 +195,19 @@ describe('Header Nav Flow', () => { renderNav() fireEvent.click(screen.getByRole('button', { name: /Alpha/i })) - fireEvent.click(await screen.findByText('menus.newApp')) + + const openCreateMenu = async () => { + fireEvent.click(await screen.findByText('menus.newApp')) + return screen.findByText('newApp.startFromBlank') + } + + await openCreateMenu() fireEvent.click(await screen.findByText('newApp.startFromBlank')) + + await openCreateMenu() fireEvent.click(await screen.findByText('newApp.startFromTemplate')) + + await openCreateMenu() fireEvent.click(await screen.findByText('importDSL')) expect(mockOnCreate).toHaveBeenNthCalledWith(1, 'blank') diff --git a/web/app/components/app/configuration/config/agent/agent-tools/index.tsx b/web/app/components/app/configuration/config/agent/agent-tools/index.tsx index 6100e415cc..3242bcdcf8 100644 --- a/web/app/components/app/configuration/config/agent/agent-tools/index.tsx +++ b/web/app/components/app/configuration/config/agent/agent-tools/index.tsx @@ -6,7 +6,9 @@ import type { ToolWithProvider } from '@/app/components/workflow/types' import type { AgentTool } from '@/types/app' import { Button } from '@langgenius/dify-ui/button' import { cn } from '@langgenius/dify-ui/cn' +import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover' import { Switch } from '@langgenius/dify-ui/switch' +import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip' import { RiDeleteBinLine, RiEqualizer2Line, @@ -23,7 +25,6 @@ import OperationBtn from '@/app/components/app/configuration/base/operation-btn' import AppIcon from '@/app/components/base/app-icon' import { DefaultToolIcon } from '@/app/components/base/icons/src/public/other' import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback' -import Tooltip from '@/app/components/base/tooltip' import Indicator from '@/app/components/header/indicator' import { CollectionType } from '@/app/components/tools/types' import { addDefaultValue, toolParametersToFormSchemas } from '@/app/components/tools/utils/to-form-schema' @@ -154,13 +155,23 @@ const AgentTools: FC = () => { title={(
{t('agent.tools.name', { ns: 'appDebug' })}
- - {t('agent.tools.description', { ns: 'appDebug' })} -
- )} - /> + + + + + )} + /> + + {t('agent.tools.description', { ns: 'appDebug' })} + + )} headerRight={( @@ -216,34 +227,59 @@ const AgentTools: FC = () => { {getProviderShowName(item)} {item.tool_label} {!item.isDeleted && !readonly && ( - + + + + + )} + /> + +
{item.tool_name}
{t('toolNameUsageTip', { ns: 'tools' })}
-
copy(item.tool_name)}>{t('copyToolName', { ns: 'tools' })}
+
- )} - > -
-
- -
-
-
+ + )}
{item.isDeleted && (
- -
- -
-
+ + + + + )} + /> + + {t('toolRemoved', { ns: 'tools' })} + +
{ @@ -263,19 +299,25 @@ const AgentTools: FC = () => { {!item.isDeleted && !readonly && (
{!item.notAuthor && ( - -
{ - setCurrentTool(item) - setIsShowSettingTool(true) - }} - > - -
+ + { + setCurrentTool(item) + setIsShowSettingTool(true) + }} + > + + + )} + /> + + {t('setBuiltInTools.infoAndSetting', { ns: 'tools' })} + )}
{ />, ) + fireEvent.click(screen.getByRole('button', { name: 'overview.appInfo.enableTooltip.description' })) fireEvent.click(screen.getByText('overview.appInfo.enableTooltip.learnMore')) expect(mockWindowOpen).toHaveBeenCalledWith('https://docs.example.com/use-dify/nodes/user-input', '_blank') diff --git a/web/app/components/app/overview/app-card.tsx b/web/app/components/app/overview/app-card.tsx index 09495bb659..9b1fc3a032 100644 --- a/web/app/components/app/overview/app-card.tsx +++ b/web/app/components/app/overview/app-card.tsx @@ -3,6 +3,7 @@ import type { WorkflowLaunchInputValue } from './app-card-utils' import type { ConfigParams } from './settings' import type { AppDetailResponse } from '@/models/app' import type { AppSSO } from '@/types/app' +import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover' import { Switch } from '@langgenius/dify-ui/switch' import { useSuspenseQuery } from '@tanstack/react-query' import * as React from 'react' @@ -10,7 +11,6 @@ import { useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import AppBasic from '@/app/components/app-sidebar/basic' import { useStore as useAppStore } from '@/app/components/app/store' -import Tooltip from '@/app/components/base/tooltip' import SecretKeyButton from '@/app/components/develop/secret-key/secret-key-button' import Indicator from '@/app/components/header/indicator' import { useAppContext } from '@/context/app-context' @@ -232,6 +232,31 @@ function AppCard({ triggerModeDisabled, ]) + const missingStartNodeContent = cardState.appUnpublished || cardState.missingStartNode + ? ( + <> +
+ {t('overview.appInfo.enableTooltip.description', { ns: 'appOverview' })} +
+ + + ) + : '' + + const statusPopoverContent = cardState.toggleDisabled + ? ( + triggerModeDisabled && triggerModeMessage + ? triggerModeMessage + : missingStartNodeContent + ) + : '' + return (
- - -
- {t('overview.appInfo.enableTooltip.description', { ns: 'appOverview' })} -
-
window.open(docLink('/use-dify/nodes/user-input'), '_blank')} - > - {t('overview.appInfo.enableTooltip.learnMore', { ns: 'appOverview' })} -
- - ) - : '' - ) - : '' - } - position="right" - popupClassName="w-58 max-w-60 rounded-xl bg-components-panel-bg px-3.5 py-3 shadow-lg" - offset={24} - > -
- -
-
+ {cardState.toggleDisabled && statusPopoverContent + ? ( + + + +
+ )} + /> + + {statusPopoverContent} + + + ) + : ( + + )}
{!cardState.isMinimalState && (
- {evaluation.map((item, index) => { - const nodeVisual = item.nodeInfo ? getNodeVisual(item.nodeInfo) : null - const nodeToneClasses = nodeVisual ? getToneClasses(nodeVisual.tone) : null - - return ( -
( +
+
+
{item.name}
+ {item.nodeInfo && ( +
+ + + {item.nodeInfo.title} + +
)} - > -
-
{item.name}
- {item.nodeInfo && nodeVisual && nodeToneClasses && ( -
-
-
- - {item.nodeInfo.title} - -
- )} -
-
- {formatEvaluationValue(item.value)} -
- ) - })} +
+ {formatEvaluationValue(item.value)} +
+
+ ))}
diff --git a/web/app/components/datasets/external-api/external-api-modal/index.tsx b/web/app/components/datasets/external-api/external-api-modal/index.tsx index cb2176b2a1..0179a31b89 100644 --- a/web/app/components/datasets/external-api/external-api-modal/index.tsx +++ b/web/app/components/datasets/external-api/external-api-modal/index.tsx @@ -10,13 +10,13 @@ import { AlertDialogTitle, } from '@langgenius/dify-ui/alert-dialog' import { Button } from '@langgenius/dify-ui/button' +import { Dialog, DialogContent, DialogTitle } from '@langgenius/dify-ui/dialog' +import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover' import { toast } from '@langgenius/dify-ui/toast' import { RiBook2Line, RiCloseLine, RiInformation2Line, RiLock2Fill } from '@remixicon/react' -import { memo, useEffect, useState } from 'react' +import { memo, useState } from 'react' import { useTranslation } from 'react-i18next' import ActionButton from '@/app/components/base/action-button' -import { PortalToFollowElem, PortalToFollowElemContent } from '@/app/components/base/portal-to-follow-elem' -import Tooltip from '@/app/components/base/tooltip' import { createExternalAPI } from '@/service/datasets' import Form from './Form' @@ -57,15 +57,20 @@ const formSchemas: FormSchema[] = [ required: true, }, ] + +const emptyExternalAPIFormData: CreateExternalAPIReq = { + name: '', + settings: { + endpoint: '', + api_key: '', + }, +} + const AddExternalAPIModal: FC = ({ data, onSave, onCancel, datasetBindings, isEditMode, onEdit }) => { const { t } = useTranslation() const [loading, setLoading] = useState(false) const [showConfirm, setShowConfirm] = useState(false) - const [formData, setFormData] = useState({ name: '', settings: { endpoint: '', api_key: '' } }) - useEffect(() => { - if (isEditMode && data) - setFormData(data) - }, [isEditMode, data]) + const [formData, setFormData] = useState(() => isEditMode && data ? data : emptyExternalAPIFormData) const hasEmptyInputs = Object.values(formData).some(value => typeof value === 'string' ? value.trim() === '' : Object.values(value).some(v => v.trim() === '')) const handleDataChange = (val: CreateExternalAPIReq) => { setFormData(val) @@ -108,106 +113,121 @@ const AddExternalAPIModal: FC = ({ data, onSave, onCan } } return ( - - -
-
-
-
- {isEditMode ? t('editExternalAPIFormTitle', { ns: 'dataset' }) : t('createExternalAPI', { ns: 'dataset' })} -
- {isEditMode && (datasetBindings?.length ?? 0) > 0 && ( -
- {t('editExternalAPIFormWarning.front', { ns: 'dataset' })} - -   - {datasetBindings?.length} - {' '} - {t('editExternalAPIFormWarning.end', { ns: 'dataset' })} + { + if (!open) + onCancel() + }} + > + +
+
+ + {isEditMode ? t('editExternalAPIFormTitle', { ns: 'dataset' }) : t('createExternalAPI', { ns: 'dataset' })} + + {isEditMode && (datasetBindings?.length ?? 0) > 0 && ( +
+ {t('editExternalAPIFormWarning.front', { ns: 'dataset' })} + +   + {datasetBindings?.length} + {' '} + {t('editExternalAPIFormWarning.end', { ns: 'dataset' })}   - -
-
{`${datasetBindings?.length} ${t('editExternalAPITooltipTitle', { ns: 'dataset' })}`}
-
- {datasetBindings?.map(binding => ( -
- -
{binding.name}
-
- ))} -
+ + + + )} - asChild={false} - position="bottom" + /> + - - - -
- )} -
- - - -
-
- - -
-
- - {t('externalAPIForm.encrypted.front', { ns: 'dataset' })} - - PKCS1_OAEP - - {t('externalAPIForm.encrypted.end', { ns: 'dataset' })} -
-
- 0} - onOpenChange={open => !open && setShowConfirm(false)} - > - -
- - Warning - - - {`${t('editExternalAPIConfirmWarningContent.front', { ns: 'dataset' })} ${datasetBindings?.length} ${t('editExternalAPIConfirmWarningContent.end', { ns: 'dataset' })}`} - +
+
+
{`${datasetBindings?.length} ${t('editExternalAPITooltipTitle', { ns: 'dataset' })}`}
+
+ {datasetBindings?.map(binding => ( +
+ +
{binding.name}
+
+ ))} +
+ + +
- - {t('operation.cancel', { ns: 'common' })} - - {t('operation.confirm', { ns: 'common' })} - - -
-
+ )} +
+ + + + +
+ + +
+
+ + {t('externalAPIForm.encrypted.front', { ns: 'dataset' })} + + PKCS1_OAEP + + {t('externalAPIForm.encrypted.end', { ns: 'dataset' })} +
- - + 0} + onOpenChange={open => !open && setShowConfirm(false)} + > + +
+ + Warning + + + {`${t('editExternalAPIConfirmWarningContent.front', { ns: 'dataset' })} ${datasetBindings?.length} ${t('editExternalAPIConfirmWarningContent.end', { ns: 'dataset' })}`} + +
+ + {t('operation.cancel', { ns: 'common' })} + + {t('operation.confirm', { ns: 'common' })} + + +
+
+ + ) } export default memo(AddExternalAPIModal) diff --git a/web/app/components/datasets/extra-info/statistics.tsx b/web/app/components/datasets/extra-info/statistics.tsx index f02db4c5dc..4adf71cc57 100644 --- a/web/app/components/datasets/extra-info/statistics.tsx +++ b/web/app/components/datasets/extra-info/statistics.tsx @@ -1,10 +1,10 @@ import type { RelatedAppResponse } from '@/models/datasets' +import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover' import { RiInformation2Line } from '@remixicon/react' import * as React from 'react' import { useTranslation } from 'react-i18next' import Divider from '@/app/components/base/divider' import LinkedAppsPanel from '@/app/components/base/linked-apps-panel' -import Tooltip from '@/app/components/base/tooltip' import NoLinkedAppsPanel from '../no-linked-apps-panel' type StatisticsProps = { @@ -40,26 +40,34 @@ const Statistics = ({
{relatedAppsTotal ?? '--'}
- + + {t('datasetMenus.relatedApp', { ns: 'common' })} + + + )} + /> + + {hasRelatedApps ? ( ) - : - } - > -
- {t('datasetMenus.relatedApp', { ns: 'common' })} - -
-
+ : } + +
) diff --git a/web/app/components/evaluation/__tests__/index.spec.tsx b/web/app/components/evaluation/__tests__/index.spec.tsx index 4f8db5a32d..b451223390 100644 --- a/web/app/components/evaluation/__tests__/index.spec.tsx +++ b/web/app/components/evaluation/__tests__/index.spec.tsx @@ -7,8 +7,8 @@ import { useEvaluationStore } from '../store' const mockUpload = vi.hoisted(() => vi.fn()) const mockUseAvailableEvaluationMetrics = vi.hoisted(() => vi.fn()) +const mockUseDefaultEvaluationMetrics = vi.hoisted(() => vi.fn()) const mockUseEvaluationConfig = vi.hoisted(() => vi.fn()) -const mockUseEvaluationNodeInfoMutation = vi.hoisted(() => vi.fn()) const mockUseSaveEvaluationConfigMutation = vi.hoisted(() => vi.fn()) const mockUseStartEvaluationRunMutation = vi.hoisted(() => vi.fn()) const mockUsePublishedPipelineInfo = vi.hoisted(() => vi.fn()) @@ -51,7 +51,7 @@ vi.mock('@/service/base', () => ({ vi.mock('@/service/use-evaluation', () => ({ useEvaluationConfig: (...args: unknown[]) => mockUseEvaluationConfig(...args), useAvailableEvaluationMetrics: (...args: unknown[]) => mockUseAvailableEvaluationMetrics(...args), - useEvaluationNodeInfoMutation: (...args: unknown[]) => mockUseEvaluationNodeInfoMutation(...args), + useDefaultEvaluationMetrics: (...args: unknown[]) => mockUseDefaultEvaluationMetrics(...args), useSaveEvaluationConfigMutation: (...args: unknown[]) => mockUseSaveEvaluationConfigMutation(...args), useStartEvaluationRunMutation: (...args: unknown[]) => mockUseStartEvaluationRunMutation(...args), })) @@ -128,7 +128,7 @@ const renderWithQueryClient = (ui: ReactNode) => { describe('Evaluation', () => { beforeEach(() => { - useEvaluationStore.setState({ resources: {} }) + useEvaluationStore.setState({ resources: {}, initialResources: {} }) vi.clearAllMocks() mockUseEvaluationConfig.mockReturnValue({ data: null, @@ -141,18 +141,41 @@ describe('Evaluation', () => { isLoading: false, }) - mockUseEvaluationNodeInfoMutation.mockReturnValue({ - isPending: false, - mutate: (_input: unknown, options?: { onSuccess?: (data: Record>) => void }) => { - options?.onSuccess?.({ - 'answer-correctness': [ - { node_id: 'node-answer', title: 'Answer Node', type: 'llm' }, - ], - 'faithfulness': [ - { node_id: 'node-faithfulness', title: 'Retriever Node', type: 'retriever' }, - ], - }) + mockUseDefaultEvaluationMetrics.mockReturnValue({ + data: { + default_metrics: [ + { + metric: 'answer-correctness', + value_type: 'number', + node_info_list: [ + { node_id: 'node-answer', title: 'Answer Node', type: 'llm' }, + ], + }, + { + metric: 'faithfulness', + value_type: 'number', + node_info_list: [ + { node_id: 'node-faithfulness', title: 'Retriever Node', type: 'retriever' }, + ], + }, + { + metric: 'context-precision', + value_type: 'number', + node_info_list: [], + }, + { + metric: 'context-recall', + value_type: 'number', + node_info_list: [], + }, + { + metric: 'context-relevance', + value_type: 'number', + node_info_list: [], + }, + ], }, + isLoading: false, }) mockUseSaveEvaluationConfigMutation.mockReturnValue({ isPending: false, @@ -251,6 +274,37 @@ describe('Evaluation', () => { }) }) + it('should reset unsaved non-pipeline config changes to the hydrated config', () => { + mockUseEvaluationConfig.mockReturnValue({ + data: { + evaluation_model: 'gpt-4o-mini', + evaluation_model_provider: 'openai', + default_metrics: [], + customized_metrics: null, + judgment_config: null, + }, + }) + + renderWithQueryClient() + + const resetButton = screen.getByRole('button', { name: 'common.operation.reset' }) + expect(resetButton).toBeDisabled() + + fireEvent.click(screen.getByRole('button', { name: 'evaluation.metrics.add' })) + fireEvent.change(screen.getByPlaceholderText('evaluation.metrics.searchNodeOrMetrics'), { + target: { value: 'faith' }, + }) + fireEvent.click(screen.getByTestId('evaluation-metric-node-faithfulness-node-faithfulness')) + + expect(useEvaluationStore.getState().resources['apps:app-reset']!.metrics).toHaveLength(1) + expect(resetButton).toBeEnabled() + + fireEvent.click(resetButton) + + expect(useEvaluationStore.getState().resources['apps:app-reset']!.metrics).toHaveLength(0) + expect(resetButton).toBeDisabled() + }) + it('should hide the value row for empty operators', () => { const resourceType = 'apps' const resourceId = 'app-2' @@ -330,22 +384,19 @@ describe('Evaluation', () => { }) it('should render the metric no-node empty state', () => { - mockUseAvailableEvaluationMetrics.mockReturnValue({ + mockUseDefaultEvaluationMetrics.mockReturnValue({ data: { - metrics: ['context-precision'], + default_metrics: [ + { + metric: 'context-precision', + value_type: 'number', + node_info_list: [], + }, + ], }, isLoading: false, }) - mockUseEvaluationNodeInfoMutation.mockReturnValue({ - isPending: false, - mutate: (_input: unknown, options?: { onSuccess?: (data: Record>) => void }) => { - options?.onSuccess?.({ - 'context-precision': [], - }) - }, - }) - renderWithQueryClient() fireEvent.click(screen.getByRole('button', { name: 'evaluation.metrics.add' })) @@ -353,10 +404,49 @@ describe('Evaluation', () => { expect(screen.getByText('evaluation.metrics.noNodesInWorkflow')).toBeInTheDocument() }) - it('should render the global empty state when no metrics are available', () => { - mockUseAvailableEvaluationMetrics.mockReturnValue({ + it('should add a node from a dynamically returned metric option', () => { + mockUseDefaultEvaluationMetrics.mockReturnValue({ data: { - metrics: [], + default_metrics: [ + { + metric: 'answer-correctness', + value_type: 'number', + node_info_list: [ + { node_id: 'node-answer', title: 'Answer Node', type: 'llm' }, + ], + }, + { + metric: 'context-precision', + value_type: 'number', + node_info_list: [ + { node_id: 'node-context', title: 'Context Node', type: 'knowledge-retrieval' }, + ], + }, + ], + }, + isLoading: false, + }) + + renderWithQueryClient() + + fireEvent.click(screen.getByRole('button', { name: 'evaluation.metrics.add' })) + fireEvent.click(screen.getByTestId('evaluation-metric-node-context-precision-node-context')) + + const metrics = useEvaluationStore.getState().resources['apps:app-dynamic-metric']!.metrics + expect(metrics).toHaveLength(1) + expect(metrics[0]).toMatchObject({ + optionId: 'context-precision', + label: 'Context Precision', + nodeInfoList: [ + { node_id: 'node-context', title: 'Context Node', type: 'knowledge-retrieval' }, + ], + }) + }) + + it('should render the global empty state when no metrics are available', () => { + mockUseDefaultEvaluationMetrics.mockReturnValue({ + data: { + default_metrics: [], }, isLoading: false, }) @@ -369,27 +459,24 @@ describe('Evaluation', () => { }) it('should show more nodes when a metric has more than three nodes', () => { - mockUseAvailableEvaluationMetrics.mockReturnValue({ + mockUseDefaultEvaluationMetrics.mockReturnValue({ data: { - metrics: ['answer-correctness'], + default_metrics: [ + { + metric: 'answer-correctness', + value_type: 'number', + node_info_list: [ + { node_id: 'node-1', title: 'LLM 1', type: 'llm' }, + { node_id: 'node-2', title: 'LLM 2', type: 'llm' }, + { node_id: 'node-3', title: 'LLM 3', type: 'llm' }, + { node_id: 'node-4', title: 'LLM 4', type: 'llm' }, + ], + }, + ], }, isLoading: false, }) - mockUseEvaluationNodeInfoMutation.mockReturnValue({ - isPending: false, - mutate: (_input: unknown, options?: { onSuccess?: (data: Record>) => void }) => { - options?.onSuccess?.({ - 'answer-correctness': [ - { node_id: 'node-1', title: 'LLM 1', type: 'llm' }, - { node_id: 'node-2', title: 'LLM 2', type: 'llm' }, - { node_id: 'node-3', title: 'LLM 3', type: 'llm' }, - { node_id: 'node-4', title: 'LLM 4', type: 'llm' }, - ], - }) - }, - }) - renderWithQueryClient() fireEvent.click(screen.getByRole('button', { name: 'evaluation.metrics.add' })) diff --git a/web/app/components/evaluation/__tests__/store.spec.ts b/web/app/components/evaluation/__tests__/store.spec.ts index 150f285b52..0557f52945 100644 --- a/web/app/components/evaluation/__tests__/store.spec.ts +++ b/web/app/components/evaluation/__tests__/store.spec.ts @@ -1,5 +1,4 @@ import type { EvaluationConfig } from '@/types/evaluation' -import { getEvaluationMockConfig } from '../mock' import { getAllowedOperators, isCustomMetricConfigured, @@ -8,16 +7,21 @@ import { } from '../store' import { buildEvaluationConfigPayload, buildEvaluationRunRequest } from '../store-utils' +const customWorkflow = { + id: 'workflow-precision-review', + appId: 'custom-workflow-app-id', + name: 'Precision Review Workflow', +} + describe('evaluation store', () => { beforeEach(() => { - useEvaluationStore.setState({ resources: {} }) + useEvaluationStore.setState({ resources: {}, initialResources: {} }) }) it('should configure a custom metric mapping to a valid state', () => { const resourceType = 'apps' const resourceId = 'app-1' const store = useEvaluationStore.getState() - const config = getEvaluationMockConfig(resourceType) store.ensureResource(resourceType, resourceId) store.addCustomMetric(resourceType, resourceId) @@ -27,9 +31,9 @@ describe('evaluation store', () => { expect(isCustomMetricConfigured(initialMetric!)).toBe(false) store.setCustomMetricWorkflow(resourceType, resourceId, initialMetric!.id, { - workflowId: config.workflowOptions[0].id, - workflowAppId: 'custom-workflow-app-id', - workflowName: config.workflowOptions[0].label, + workflowId: customWorkflow.id, + workflowAppId: customWorkflow.appId, + workflowName: customWorkflow.name, }) store.syncCustomMetricMappings(resourceType, resourceId, initialMetric!.id, ['query']) store.syncCustomMetricOutputs(resourceType, resourceId, initialMetric!.id, [{ @@ -44,8 +48,8 @@ describe('evaluation store', () => { const configuredMetric = useEvaluationStore.getState().resources['apps:app-1'].metrics.find(metric => metric.id === initialMetric!.id) expect(isCustomMetricConfigured(configuredMetric!)).toBe(true) - expect(configuredMetric!.customConfig!.workflowAppId).toBe('custom-workflow-app-id') - expect(configuredMetric!.customConfig!.workflowName).toBe(config.workflowOptions[0].label) + expect(configuredMetric!.customConfig!.workflowAppId).toBe(customWorkflow.appId) + expect(configuredMetric!.customConfig!.workflowName).toBe(customWorkflow.name) expect(configuredMetric!.customConfig!.outputs).toEqual([{ id: 'score', valueType: 'number' }]) }) @@ -71,12 +75,11 @@ describe('evaluation store', () => { const resourceType = 'apps' const resourceId = 'app-2' const store = useEvaluationStore.getState() - const config = getEvaluationMockConfig(resourceType) store.ensureResource(resourceType, resourceId) - store.addBuiltinMetric(resourceType, resourceId, config.builtinMetrics[1].id) + store.addBuiltinMetric(resourceType, resourceId, 'faithfulness') - const addedMetric = useEvaluationStore.getState().resources['apps:app-2'].metrics.find(metric => metric.optionId === config.builtinMetrics[1].id) + const addedMetric = useEvaluationStore.getState().resources['apps:app-2'].metrics.find(metric => metric.optionId === 'faithfulness') expect(addedMetric).toBeDefined() store.removeMetric(resourceType, resourceId, addedMetric!.id) @@ -88,8 +91,7 @@ describe('evaluation store', () => { const resourceType = 'apps' const resourceId = 'app-4' const store = useEvaluationStore.getState() - const config = getEvaluationMockConfig(resourceType) - const metricId = config.builtinMetrics[0].id + const metricId = 'answer-correctness' store.ensureResource(resourceType, resourceId) store.addBuiltinMetric(resourceType, resourceId, metricId, [ @@ -115,10 +117,9 @@ describe('evaluation store', () => { const resourceType = 'apps' const resourceId = 'app-conditions' const store = useEvaluationStore.getState() - const config = getEvaluationMockConfig(resourceType) store.ensureResource(resourceType, resourceId) - store.addBuiltinMetric(resourceType, resourceId, config.builtinMetrics[0].id, [ + store.addBuiltinMetric(resourceType, resourceId, 'answer-correctness', [ { node_id: 'node-answer', title: 'Answer Node', type: 'llm' }, ]) store.setConditionLogicalOperator(resourceType, resourceId, 'or') @@ -137,27 +138,26 @@ describe('evaluation store', () => { const resourceType = 'apps' const resourceId = 'app-condition-selector' const store = useEvaluationStore.getState() - const config = getEvaluationMockConfig(resourceType) store.ensureResource(resourceType, resourceId) store.addCustomMetric(resourceType, resourceId) const customMetric = useEvaluationStore.getState().resources['apps:app-condition-selector'].metrics.find(metric => metric.kind === 'custom-workflow')! store.setCustomMetricWorkflow(resourceType, resourceId, customMetric.id, { - workflowId: config.workflowOptions[0].id, - workflowAppId: 'custom-workflow-app-id', - workflowName: config.workflowOptions[0].label, + workflowId: customWorkflow.id, + workflowAppId: customWorkflow.appId, + workflowName: customWorkflow.name, }) store.syncCustomMetricOutputs(resourceType, resourceId, customMetric.id, [{ id: 'reason', valueType: 'string', }]) - store.addCondition(resourceType, resourceId, [config.workflowOptions[0].id, 'reason']) + store.addCondition(resourceType, resourceId, [customWorkflow.id, 'reason']) const condition = useEvaluationStore.getState().resources['apps:app-condition-selector'].judgmentConfig.conditions[0] - expect(condition.variableSelector).toEqual([config.workflowOptions[0].id, 'reason']) + expect(condition.variableSelector).toEqual([customWorkflow.id, 'reason']) expect(condition.comparisonOperator).toBe('contains') expect(condition.value).toBeNull() }) @@ -166,16 +166,15 @@ describe('evaluation store', () => { const resourceType = 'apps' const resourceId = 'app-3' const store = useEvaluationStore.getState() - const config = getEvaluationMockConfig(resourceType) store.ensureResource(resourceType, resourceId) store.addCustomMetric(resourceType, resourceId) const customMetric = useEvaluationStore.getState().resources['apps:app-3'].metrics.find(metric => metric.kind === 'custom-workflow')! store.setCustomMetricWorkflow(resourceType, resourceId, customMetric.id, { - workflowId: config.workflowOptions[0].id, - workflowAppId: 'custom-workflow-app-id', - workflowName: config.workflowOptions[0].label, + workflowId: customWorkflow.id, + workflowAppId: customWorkflow.appId, + workflowName: customWorkflow.name, }) store.syncCustomMetricOutputs(resourceType, resourceId, customMetric.id, [{ id: 'reason', @@ -185,7 +184,7 @@ describe('evaluation store', () => { const condition = useEvaluationStore.getState().resources['apps:app-3'].judgmentConfig.conditions[0] - store.updateConditionMetric(resourceType, resourceId, condition.id, [config.workflowOptions[0].id, 'reason']) + store.updateConditionMetric(resourceType, resourceId, condition.id, [customWorkflow.id, 'reason']) store.updateConditionValue(resourceType, resourceId, condition.id, 'needs follow-up') store.updateConditionOperator(resourceType, resourceId, condition.id, 'empty') diff --git a/web/app/components/evaluation/components/batch-test-panel/index.tsx b/web/app/components/evaluation/components/batch-test-panel/index.tsx index ce3ace9ef5..8b4d9ca98a 100644 --- a/web/app/components/evaluation/components/batch-test-panel/index.tsx +++ b/web/app/components/evaluation/components/batch-test-panel/index.tsx @@ -1,13 +1,9 @@ 'use client' import type { BatchTestTab, EvaluationResourceProps } from '../../types' -import { Button } from '@langgenius/dify-ui/button' import { cn } from '@langgenius/dify-ui/cn' -import { toast } from '@langgenius/dify-ui/toast' import { useTranslation } from 'react-i18next' -import { useSaveEvaluationConfigMutation } from '@/service/use-evaluation' import { isEvaluationRunnable, useEvaluationResource, useEvaluationStore } from '../../store' -import { buildEvaluationConfigPayload } from '../../store-utils' import { TAB_CLASS_NAME } from '../../utils' import HistoryTab from './history-tab' import InputFieldsTab from './input-fields-tab' @@ -19,63 +15,21 @@ const BatchTestPanel = ({ resourceId, }: EvaluationResourceProps) => { const { t } = useTranslation('evaluation') - const { t: tCommon } = useTranslation('common') const tabLabels: Record = { 'input-fields': t('batch.tabs.input-fields'), 'history': t('batch.tabs.history'), } const resource = useEvaluationResource(resourceType, resourceId) const setBatchTab = useEvaluationStore(state => state.setBatchTab) - const saveConfigMutation = useSaveEvaluationConfigMutation() const isRunnable = isEvaluationRunnable(resource) const isPanelReady = !!resource.judgeModelId && resource.metrics.length > 0 - const handleSave = () => { - if (!isRunnable) { - toast.warning(t('batch.validation')) - return - } - - const body = buildEvaluationConfigPayload(resource, resourceType) - - if (!body) { - toast.warning(t('batch.validation')) - return - } - - saveConfigMutation.mutate({ - params: { - targetType: resourceType, - targetId: resourceId, - }, - body, - }, { - onSuccess: () => { - toast.success(tCommon('api.saved')) - }, - onError: () => { - toast.error(t('config.saveFailed')) - }, - }) - } - return (
-
-
-
{t('batch.title')}
-
{t('batch.description')}
-
- +
+
{t('batch.title')}
+
{t('batch.description')}
diff --git a/web/app/components/evaluation/components/batch-test-panel/input-fields-tab.tsx b/web/app/components/evaluation/components/batch-test-panel/input-fields-tab.tsx index c3bc295081..5cff6e3dc0 100644 --- a/web/app/components/evaluation/components/batch-test-panel/input-fields-tab.tsx +++ b/web/app/components/evaluation/components/batch-test-panel/input-fields-tab.tsx @@ -1,7 +1,7 @@ import type { EvaluationResourceProps } from '../../types' import { Button } from '@langgenius/dify-ui/button' import { useTranslation } from 'react-i18next' -import { getEvaluationMockConfig } from '../../mock' +import { EVALUATION_TEMPLATE_FILE_NAMES } from '../../store-utils' import InputFieldsRequirements from './input-fields/input-fields-requirements' import UploadRunPopover from './input-fields/upload-run-popover' import { useInputFieldsActions } from './input-fields/use-input-fields-actions' @@ -19,7 +19,6 @@ const InputFieldsTab = ({ isRunnable, }: InputFieldsTabProps) => { const { t } = useTranslation('evaluation') - const config = getEvaluationMockConfig(resourceType) const { inputFields, isInputFieldsLoading } = usePublishedInputFields(resourceType, resourceId) const actions = useInputFieldsActions({ resourceType, @@ -28,7 +27,7 @@ const InputFieldsTab = ({ isInputFieldsLoading, isPanelReady, isRunnable, - templateFileName: config.templateFileName, + templateFileName: EVALUATION_TEMPLATE_FILE_NAMES[resourceType], }) return ( diff --git a/web/app/components/evaluation/components/config-actions.tsx b/web/app/components/evaluation/components/config-actions.tsx new file mode 100644 index 0000000000..8c1e769045 --- /dev/null +++ b/web/app/components/evaluation/components/config-actions.tsx @@ -0,0 +1,80 @@ +'use client' + +import type { EvaluationResourceProps } from '../types' +import { Button } from '@langgenius/dify-ui/button' +import { toast } from '@langgenius/dify-ui/toast' +import { useTranslation } from 'react-i18next' +import { useSaveEvaluationConfigMutation } from '@/service/use-evaluation' +import { + isEvaluationRunnable, + useEvaluationResource, + useEvaluationStore, + useIsEvaluationConfigDirty, +} from '../store' +import { buildEvaluationConfigPayload } from '../store-utils' + +const EvaluationConfigActions = ({ + resourceType, + resourceId, +}: EvaluationResourceProps) => { + const { t } = useTranslation('evaluation') + const { t: tCommon } = useTranslation('common') + const resource = useEvaluationResource(resourceType, resourceId) + const isDirty = useIsEvaluationConfigDirty(resourceType, resourceId) + const resetResourceConfig = useEvaluationStore(state => state.resetResourceConfig) + const markResourceConfigSaved = useEvaluationStore(state => state.markResourceConfigSaved) + const saveConfigMutation = useSaveEvaluationConfigMutation() + const isRunnable = isEvaluationRunnable(resource) + + const handleSave = () => { + if (!isRunnable) { + toast.warning(t('batch.validation')) + return + } + + const body = buildEvaluationConfigPayload(resource, resourceType) + + if (!body) { + toast.warning(t('batch.validation')) + return + } + + saveConfigMutation.mutate({ + params: { + targetType: resourceType, + targetId: resourceId, + }, + body, + }, { + onSuccess: () => { + markResourceConfigSaved(resourceType, resourceId) + toast.success(tCommon('api.saved')) + }, + onError: () => { + toast.error(t('config.saveFailed')) + }, + }) + } + + return ( +
+ + +
+ ) +} + +export default EvaluationConfigActions diff --git a/web/app/components/evaluation/components/layout/non-pipeline-evaluation.tsx b/web/app/components/evaluation/components/layout/non-pipeline-evaluation.tsx index 5d47a754ff..69444beaa9 100644 --- a/web/app/components/evaluation/components/layout/non-pipeline-evaluation.tsx +++ b/web/app/components/evaluation/components/layout/non-pipeline-evaluation.tsx @@ -1,10 +1,11 @@ 'use client' -import type { EvaluationResourceProps } from '../../types' +import type { NonPipelineEvaluationResourceProps } from '../../types' import { useTranslation } from 'react-i18next' import { useDocLink } from '@/context/i18n' import BatchTestPanel from '../batch-test-panel' import ConditionsSection from '../conditions-section' +import EvaluationConfigActions from '../config-actions' import JudgeModelSelector from '../judge-model-selector' import MetricSection from '../metric-section' import SectionHeader, { InlineSectionHeader } from '../section-header' @@ -12,7 +13,7 @@ import SectionHeader, { InlineSectionHeader } from '../section-header' const NonPipelineEvaluation = ({ resourceType, resourceId, -}: EvaluationResourceProps) => { +}: NonPipelineEvaluationResourceProps) => { const { t } = useTranslation('evaluation') const { t: tCommon } = useTranslation('common') const docLink = useDocLink() @@ -38,6 +39,7 @@ const NonPipelineEvaluation = ({ )} descriptionClassName="max-w-[700px]" + action={} />
diff --git a/web/app/components/evaluation/components/layout/pipeline-evaluation.tsx b/web/app/components/evaluation/components/layout/pipeline-evaluation.tsx index 9fb6c70a90..102360f526 100644 --- a/web/app/components/evaluation/components/layout/pipeline-evaluation.tsx +++ b/web/app/components/evaluation/components/layout/pipeline-evaluation.tsx @@ -6,6 +6,7 @@ import { useTranslation } from 'react-i18next' import { useDocLink } from '@/context/i18n' import { useEvaluationStore } from '../../store' import HistoryTab from '../batch-test-panel/history-tab' +import EvaluationConfigActions from '../config-actions' import JudgeModelSelector from '../judge-model-selector' import PipelineBatchActions from '../pipeline/pipeline-batch-actions' import PipelineMetricsSection from '../pipeline/pipeline-metrics-section' @@ -45,6 +46,7 @@ const PipelineEvaluation = ({ )} + action={} />
diff --git a/web/app/components/evaluation/components/metric-section/__tests__/index.spec.tsx b/web/app/components/evaluation/components/metric-section/__tests__/index.spec.tsx index a234635c50..6b240966bf 100644 --- a/web/app/components/evaluation/components/metric-section/__tests__/index.spec.tsx +++ b/web/app/components/evaluation/components/metric-section/__tests__/index.spec.tsx @@ -4,13 +4,11 @@ import MetricSection from '..' import { useEvaluationStore } from '../../../store' const mockUseAvailableEvaluationWorkflows = vi.hoisted(() => vi.fn()) -const mockUseAvailableEvaluationMetrics = vi.hoisted(() => vi.fn()) -const mockUseEvaluationNodeInfoMutation = vi.hoisted(() => vi.fn()) +const mockUseDefaultEvaluationMetrics = vi.hoisted(() => vi.fn()) vi.mock('@/service/use-evaluation', () => ({ useAvailableEvaluationWorkflows: (...args: unknown[]) => mockUseAvailableEvaluationWorkflows(...args), - useAvailableEvaluationMetrics: (...args: unknown[]) => mockUseAvailableEvaluationMetrics(...args), - useEvaluationNodeInfoMutation: (...args: unknown[]) => mockUseEvaluationNodeInfoMutation(...args), + useDefaultEvaluationMetrics: (...args: unknown[]) => mockUseDefaultEvaluationMetrics(...args), })) const resourceType = 'apps' as const @@ -37,9 +35,17 @@ describe('MetricSection', () => { vi.clearAllMocks() useEvaluationStore.setState({ resources: {} }) - mockUseAvailableEvaluationMetrics.mockReturnValue({ + mockUseDefaultEvaluationMetrics.mockReturnValue({ data: { - metrics: ['answer-correctness'], + default_metrics: [ + { + metric: 'answer-correctness', + value_type: 'number', + node_info_list: [ + { node_id: 'node-answer', title: 'Answer Node', type: 'llm' }, + ], + }, + ], }, isLoading: false, }) @@ -54,17 +60,6 @@ describe('MetricSection', () => { isFetchingNextPage: false, isLoading: false, }) - - mockUseEvaluationNodeInfoMutation.mockReturnValue({ - isPending: false, - mutate: (_input: unknown, options?: { onSuccess?: (data: Record>) => void }) => { - options?.onSuccess?.({ - 'answer-correctness': [ - { node_id: 'node-answer', title: 'Answer Node', type: 'llm' }, - ], - }) - }, - }) }) // Verify the empty state block extracted from MetricSection. @@ -138,16 +133,20 @@ describe('MetricSection', () => { it('should show only unselected nodes in the add-node dropdown and append the selected node', () => { // Arrange - mockUseEvaluationNodeInfoMutation.mockReturnValue({ - isPending: false, - mutate: (_input: unknown, options?: { onSuccess?: (data: Record>) => void }) => { - options?.onSuccess?.({ - 'answer-correctness': [ - { node_id: 'node-1', title: 'LLM 1', type: 'llm' }, - { node_id: 'node-2', title: 'LLM 2', type: 'llm' }, - ], - }) + mockUseDefaultEvaluationMetrics.mockReturnValue({ + data: { + default_metrics: [ + { + metric: 'answer-correctness', + value_type: 'number', + node_info_list: [ + { node_id: 'node-1', title: 'LLM 1', type: 'llm' }, + { node_id: 'node-2', title: 'LLM 2', type: 'llm' }, + ], + }, + ], }, + isLoading: false, }) act(() => { @@ -171,16 +170,20 @@ describe('MetricSection', () => { it('should hide the add-node button when the builtin metric already targets all nodes', () => { // Arrange - mockUseEvaluationNodeInfoMutation.mockReturnValue({ - isPending: false, - mutate: (_input: unknown, options?: { onSuccess?: (data: Record>) => void }) => { - options?.onSuccess?.({ - 'answer-correctness': [ - { node_id: 'node-1', title: 'LLM 1', type: 'llm' }, - { node_id: 'node-2', title: 'LLM 2', type: 'llm' }, - ], - }) + mockUseDefaultEvaluationMetrics.mockReturnValue({ + data: { + default_metrics: [ + { + metric: 'answer-correctness', + value_type: 'number', + node_info_list: [ + { node_id: 'node-1', title: 'LLM 1', type: 'llm' }, + { node_id: 'node-2', title: 'LLM 2', type: 'llm' }, + ], + }, + ], }, + isLoading: false, }) act(() => { diff --git a/web/app/components/evaluation/components/metric-section/builtin-metric-card.tsx b/web/app/components/evaluation/components/metric-section/builtin-metric-card.tsx index b8a4992b65..ed1ec8f4bf 100644 --- a/web/app/components/evaluation/components/metric-section/builtin-metric-card.tsx +++ b/web/app/components/evaluation/components/metric-section/builtin-metric-card.tsx @@ -12,8 +12,9 @@ import { } from '@langgenius/dify-ui/dropdown-menu' import { useState } from 'react' import { useTranslation } from 'react-i18next' +import BlockIcon from '@/app/components/workflow/block-icon' import { useEvaluationStore } from '../../store' -import { dedupeNodeInfoList, getMetricVisual, getNodeVisual, getToneClasses } from '../metric-selector/utils' +import { dedupeNodeInfoList, getEvaluationNodeBlockType, getMetricVisual, getToneClasses } from '../metric-selector/utils' type BuiltinMetricCardProps = EvaluationResourceProps & { metric: EvaluationMetric @@ -41,7 +42,7 @@ const BuiltinMetricCard = ({ return (
-
+
) @@ -126,9 +126,6 @@ const BuiltinMetricCard = ({ popupClassName="w-[252px] rounded-md border-[0.5px] border-components-panel-border py-1 shadow-[0px_12px_16px_-4px_rgba(9,9,11,0.08),0px_4px_6px_-2px_rgba(9,9,11,0.03)]" > {selectableNodeInfoList.map((nodeInfo) => { - const nodeVisual = getNodeVisual(nodeInfo) - const nodeToneClasses = getToneClasses(nodeVisual.tone) - return (
-
-
+ {nodeInfo.title}
diff --git a/web/app/components/evaluation/components/metric-section/index.tsx b/web/app/components/evaluation/components/metric-section/index.tsx index 7887b2733b..be7f0cc8cc 100644 --- a/web/app/components/evaluation/components/metric-section/index.tsx +++ b/web/app/components/evaluation/components/metric-section/index.tsx @@ -1,13 +1,11 @@ 'use client' -import type { EvaluationResourceProps } from '../../types' -import type { NodeInfo } from '@/types/evaluation' -import { useEffect, useMemo, useState } from 'react' +import type { NonPipelineEvaluationResourceProps } from '../../types' import { useTranslation } from 'react-i18next' -import { useAvailableEvaluationMetrics, useEvaluationNodeInfoMutation } from '@/service/use-evaluation' +import { useDefaultEvaluationMetrics } from '@/service/use-evaluation' import { useEvaluationResource } from '../../store' import MetricSelector from '../metric-selector' -import { toEvaluationTargetType } from '../metric-selector/utils' +import { getDefaultMetricNodeInfoMap } from '../metric-selector/utils' import { InlineSectionHeader } from '../section-header' import MetricCard from './metric-card' import MetricSectionEmptyState from './metric-section-empty-state' @@ -15,55 +13,13 @@ import MetricSectionEmptyState from './metric-section-empty-state' const MetricSection = ({ resourceType, resourceId, -}: EvaluationResourceProps) => { +}: NonPipelineEvaluationResourceProps) => { const { t } = useTranslation('evaluation') const resource = useEvaluationResource(resourceType, resourceId) - const [nodeInfoMap, setNodeInfoMap] = useState>({}) const hasMetrics = resource.metrics.length > 0 const hasBuiltinMetrics = resource.metrics.some(metric => metric.kind === 'builtin') - const shouldLoadNodeInfo = resourceType !== 'datasets' && !!resourceId && hasBuiltinMetrics - const { data: availableMetricsData } = useAvailableEvaluationMetrics(shouldLoadNodeInfo) - const { mutate: loadNodeInfo } = useEvaluationNodeInfoMutation() - const availableMetricIds = useMemo(() => availableMetricsData?.metrics ?? [], [availableMetricsData?.metrics]) - const availableMetricIdsKey = availableMetricIds.join(',') - const resolvedNodeInfoMap = shouldLoadNodeInfo ? nodeInfoMap : {} - - useEffect(() => { - if (!shouldLoadNodeInfo || availableMetricIds.length === 0) - return - - let isActive = true - - loadNodeInfo( - { - params: { - targetType: toEvaluationTargetType(resourceType), - targetId: resourceId, - }, - body: { - metrics: availableMetricIds, - }, - }, - { - onSuccess: (data) => { - if (!isActive) - return - - setNodeInfoMap(data) - }, - onError: () => { - if (!isActive) - return - - setNodeInfoMap({}) - }, - }, - ) - - return () => { - isActive = false - } - }, [availableMetricIds, availableMetricIdsKey, loadNodeInfo, resourceId, resourceType, shouldLoadNodeInfo]) + const { data: defaultMetricsData } = useDefaultEvaluationMetrics(resourceType, resourceId, hasBuiltinMetrics) + const nodeInfoMap = getDefaultMetricNodeInfoMap(defaultMetricsData?.default_metrics ?? []) return (
@@ -79,7 +35,7 @@ const MetricSection = ({ resourceType={resourceType} resourceId={resourceId} metric={metric} - availableNodeInfoList={metric.kind === 'builtin' ? (resolvedNodeInfoMap[metric.optionId] ?? []) : undefined} + availableNodeInfoList={metric.kind === 'builtin' ? (nodeInfoMap[metric.optionId] ?? []) : undefined} /> ))} state.addCustomMetric) const [open, setOpen] = useState(false) const [query, setQuery] = useState('') - const [nodeInfoMap, setNodeInfoMap] = useState>>({}) const [collapsedMetricMap, setCollapsedMetricMap] = useState>({}) const [expandedMetricNodesMap, setExpandedMetricNodesMap] = useState>({}) const hasCustomMetric = resource.metrics.some(metric => metric.kind === 'custom-workflow') @@ -44,8 +43,6 @@ const MetricSelector = ({ query, resourceType, resourceId, - nodeInfoMap, - setNodeInfoMap, }) const handleOpenChange = (nextOpen: boolean) => { diff --git a/web/app/components/evaluation/components/metric-selector/selector-empty-state.tsx b/web/app/components/evaluation/components/metric-selector/selector-empty-state.tsx index d93a8b84e3..9228788bd2 100644 --- a/web/app/components/evaluation/components/metric-selector/selector-empty-state.tsx +++ b/web/app/components/evaluation/components/metric-selector/selector-empty-state.tsx @@ -5,9 +5,9 @@ type SelectorEmptyStateProps = { const EmptySearchStateIcon = () => { return (
-
) } @@ -18,7 +18,7 @@ const SelectorEmptyState = ({ return (
-
{message}
+
{message}
) } diff --git a/web/app/components/evaluation/components/metric-selector/selector-footer.tsx b/web/app/components/evaluation/components/metric-selector/selector-footer.tsx index 74163c275d..f7b5a12efc 100644 --- a/web/app/components/evaluation/components/metric-selector/selector-footer.tsx +++ b/web/app/components/evaluation/components/metric-selector/selector-footer.tsx @@ -18,13 +18,13 @@ const SelectorFooter = ({ className="relative flex items-center gap-3 overflow-hidden border-t border-divider-subtle bg-background-default-subtle px-4 py-5 text-left enabled:hover:bg-state-base-hover-alt disabled:cursor-not-allowed disabled:opacity-60" onClick={onClick} > -
+
-
{title}
-
{description}
+
{title}
+
{description}
) diff --git a/web/app/components/evaluation/components/metric-selector/selector-metric-section.tsx b/web/app/components/evaluation/components/metric-selector/selector-metric-section.tsx index 9b4a0826a7..e53ec69f8d 100644 --- a/web/app/components/evaluation/components/metric-selector/selector-metric-section.tsx +++ b/web/app/components/evaluation/components/metric-selector/selector-metric-section.tsx @@ -2,7 +2,9 @@ import type { TFunction } from 'i18next' import type { EvaluationMetric } from '../../types' import type { MetricSelectorSection } from './types' import { cn } from '@langgenius/dify-ui/cn' -import { getMetricVisual, getNodeVisual, getToneClasses } from './utils' +import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip' +import BlockIcon from '@/app/components/workflow/block-icon' +import { getEvaluationNodeBlockType, getMetricVisual, getToneClasses } from './utils' type SelectorMetricSectionProps = { section: MetricSelectorSection @@ -12,7 +14,7 @@ type SelectorMetricSectionProps = { isShowingAllNodes: boolean onToggleExpanded: () => void onToggleShowAllNodes: () => void - onToggleNodeSelection: (metricId: string, nodeInfo: MetricSelectorSection['visibleNodes'][number]) => void + onToggleNodeSelection: (metric: MetricSelectorSection['metric'], nodeInfo: MetricSelectorSection['visibleNodes'][number]) => void t: TFunction<'evaluation'> } @@ -56,7 +58,7 @@ const SelectorMetricSection = ({
- {metric.label} + {metric.label}
{isExpanded && (
{hasNoNodeInfo && ( -
+
{t('metrics.noNodesInWorkflow')}
)} {shownNodes.map((nodeInfo) => { - const nodeVisual = getNodeVisual(nodeInfo) - const nodeToneClasses = getToneClasses(nodeVisual.tone) const isAdded = addedMetric ? addedMetric.nodeInfoList?.length ? selectedNodeIds.has(nodeInfo.node_id) @@ -91,21 +106,23 @@ const SelectorMetricSection = ({ data-testid={`evaluation-metric-node-${metric.id}-${nodeInfo.node_id}`} type="button" className={cn( - 'flex w-full items-center gap-1 rounded-md px-2 py-1.5 text-left transition-colors hover:bg-state-base-hover-alt', + 'flex w-full items-center gap-1 rounded-md px-3 py-1.5 text-left transition-colors hover:bg-state-base-hover-alt', isAdded && 'opacity-50', )} - onClick={() => onToggleNodeSelection(metric.id, nodeInfo)} + onClick={() => onToggleNodeSelection(metric, nodeInfo)} >
-
-
+ {nodeInfo.title}
{isAdded && ( - {t('metrics.added')} + {t('metrics.added')} )} ) @@ -120,7 +137,7 @@ const SelectorMetricSection = ({
- + {isShowingAllNodes ? t('metrics.showLess') : t('metrics.showMore')}
diff --git a/web/app/components/evaluation/components/metric-selector/types.ts b/web/app/components/evaluation/components/metric-selector/types.ts index 102329701e..11f7518257 100644 --- a/web/app/components/evaluation/components/metric-selector/types.ts +++ b/web/app/components/evaluation/components/metric-selector/types.ts @@ -1,7 +1,7 @@ -import type { EvaluationMetric, EvaluationResourceProps, MetricOption } from '../../types' +import type { EvaluationMetric, MetricOption, NonPipelineEvaluationResourceProps } from '../../types' import type { NodeInfo } from '@/types/evaluation' -export type MetricSelectorProps = EvaluationResourceProps & { +export type MetricSelectorProps = NonPipelineEvaluationResourceProps & { triggerClassName?: string triggerStyle?: 'button' | 'text' } diff --git a/web/app/components/evaluation/components/metric-selector/use-metric-selector-data.ts b/web/app/components/evaluation/components/metric-selector/use-metric-selector-data.ts index 24e1b494bc..964df4fec4 100644 --- a/web/app/components/evaluation/components/metric-selector/use-metric-selector-data.ts +++ b/web/app/components/evaluation/components/metric-selector/use-metric-selector-data.ts @@ -1,31 +1,29 @@ +import type { MetricOption, NonPipelineEvaluationResourceType } from '../../types' import type { BuiltinMetricMap, MetricSelectorSection } from './types' import type { NodeInfo } from '@/types/evaluation' -import { useEffect, useMemo } from 'react' +import { useMemo } from 'react' import { useTranslation } from 'react-i18next' -import { useAvailableEvaluationMetrics, useEvaluationNodeInfoMutation } from '@/service/use-evaluation' +import { useDefaultEvaluationMetrics } from '@/service/use-evaluation' import { getTranslatedMetricDescription } from '../../default-metric-descriptions' -import { getEvaluationMockConfig } from '../../mock' import { useEvaluationResource, useEvaluationStore } from '../../store' import { buildMetricOption, dedupeNodeInfoList, - toEvaluationTargetType, + getDefaultMetricNodeInfoMap, } from './utils' type UseMetricSelectorDataOptions = { open: boolean query: string - resourceType: 'apps' | 'datasets' | 'snippets' + resourceType: NonPipelineEvaluationResourceType resourceId: string - nodeInfoMap: Record - setNodeInfoMap: (value: Record) => void } type UseMetricSelectorDataResult = { builtinMetricMap: BuiltinMetricMap filteredSections: MetricSelectorSection[] isRemoteLoading: boolean - toggleNodeSelection: (metricId: string, nodeInfo: NodeInfo) => void + toggleNodeSelection: (metric: MetricOption, nodeInfo: NodeInfo) => void } export const useMetricSelectorData = ({ @@ -33,16 +31,12 @@ export const useMetricSelectorData = ({ query, resourceType, resourceId, - nodeInfoMap, - setNodeInfoMap, }: UseMetricSelectorDataOptions): UseMetricSelectorDataResult => { const { t } = useTranslation('evaluation') - const config = getEvaluationMockConfig(resourceType) const metrics = useEvaluationResource(resourceType, resourceId).metrics const addBuiltinMetric = useEvaluationStore(state => state.addBuiltinMetric) const removeMetric = useEvaluationStore(state => state.removeMetric) - const { data: availableMetricsData, isLoading: isAvailableMetricsLoading } = useAvailableEvaluationMetrics(open) - const { mutate: loadNodeInfo, isPending: isNodeInfoLoading } = useEvaluationNodeInfoMutation() + const { data: defaultMetricsData, isLoading: isDefaultMetricsLoading } = useDefaultEvaluationMetrics(resourceType, resourceId, open) const builtinMetrics = useMemo(() => { return metrics.filter(metric => metric.kind === 'builtin') @@ -52,54 +46,19 @@ export const useMetricSelectorData = ({ return new Map(builtinMetrics.map(metric => [metric.optionId, metric] as const)) }, [builtinMetrics]) - const availableMetricIds = useMemo(() => availableMetricsData?.metrics ?? [], [availableMetricsData?.metrics]) - const availableMetricIdsKey = availableMetricIds.join(',') + const defaultMetrics = useMemo(() => defaultMetricsData?.default_metrics ?? [], [defaultMetricsData?.default_metrics]) + const nodeInfoMap = useMemo(() => getDefaultMetricNodeInfoMap(defaultMetrics), [defaultMetrics]) const resolvedMetrics = useMemo(() => { - const metricsMap = new Map(config.builtinMetrics.map(metric => [metric.id, metric] as const)) + return defaultMetrics + .map((defaultMetric) => { + if (!defaultMetric.metric) + return null - return availableMetricIds.map(metricId => metricsMap.get(metricId) ?? buildMetricOption(metricId)) - }, [availableMetricIds, config.builtinMetrics]) - - useEffect(() => { - if (!open) - return - - if (resourceType === 'datasets' || !resourceId || availableMetricIds.length === 0) - return - - let isActive = true - - loadNodeInfo( - { - params: { - targetType: toEvaluationTargetType(resourceType), - targetId: resourceId, - }, - body: { - metrics: availableMetricIds, - }, - }, - { - onSuccess: (data) => { - if (!isActive) - return - - setNodeInfoMap(data) - }, - onError: () => { - if (!isActive) - return - - setNodeInfoMap({}) - }, - }, - ) - - return () => { - isActive = false - } - }, [availableMetricIds, availableMetricIdsKey, loadNodeInfo, open, resourceId, resourceType, setNodeInfoMap]) + return buildMetricOption(defaultMetric.metric, defaultMetric.value_type) + }) + .filter((metric): metric is MetricOption => !!metric) + }, [defaultMetrics]) const filteredSections = useMemo(() => { const keyword = query.trim().toLowerCase() @@ -110,8 +69,7 @@ export const useMetricSelectorData = ({ || metric.label.toLowerCase().includes(keyword) || metricDescription.toLowerCase().includes(keyword) const metricNodes = nodeInfoMap[metric.id] ?? [] - const supportsNodeSelection = resourceType !== 'datasets' - const hasNoNodeInfo = supportsNodeSelection && metricNodes.length === 0 + const hasNoNodeInfo = metricNodes.length === 0 if (hasNoNodeInfo) { if (!metricMatches) @@ -146,10 +104,11 @@ export const useMetricSelectorData = ({ hasNoNodeInfo: false, visibleNodes, } - }).filter(section => !!section) - }, [nodeInfoMap, query, resolvedMetrics, resourceType, t]) + }).filter((section): section is MetricSelectorSection => !!section) + }, [nodeInfoMap, query, resolvedMetrics, t]) - const toggleNodeSelection = (metricId: string, nodeInfo: NodeInfo) => { + const toggleNodeSelection = (metric: MetricOption, nodeInfo: NodeInfo) => { + const metricId = metric.id const addedMetric = builtinMetricMap.get(metricId) const currentSelectedNodes = addedMetric?.nodeInfoList ?? [] @@ -164,13 +123,13 @@ export const useMetricSelectorData = ({ return } - addBuiltinMetric(resourceType, resourceId, metricId, nextSelectedNodes) + addBuiltinMetric(resourceType, resourceId, metricId, nextSelectedNodes, metric) } return { builtinMetricMap, filteredSections, - isRemoteLoading: isAvailableMetricsLoading || isNodeInfoLoading, + isRemoteLoading: isDefaultMetricsLoading, toggleNodeSelection, } } diff --git a/web/app/components/evaluation/components/metric-selector/utils.ts b/web/app/components/evaluation/components/metric-selector/utils.ts index 2a6ca53158..515a989964 100644 --- a/web/app/components/evaluation/components/metric-selector/utils.ts +++ b/web/app/components/evaluation/components/metric-selector/utils.ts @@ -1,10 +1,16 @@ -import type { MetricOption } from '../../types' +import type { ConditionMetricValueType, MetricOption } from '../../types' import type { MetricVisualTone } from './types' -import type { EvaluationTargetType, NodeInfo } from '@/types/evaluation' +import type { EvaluationDefaultMetric, NodeInfo } from '@/types/evaluation' +import { BlockEnum } from '@/app/components/workflow/types' import { getDefaultMetricDescription } from '../../default-metric-descriptions' -export const toEvaluationTargetType = (resourceType: 'apps' | 'snippets'): EvaluationTargetType => { - return resourceType === 'snippets' ? 'snippets' : 'apps' +const defaultConditionMetricValueType: ConditionMetricValueType = 'number' + +export const normalizeMetricValueType = (valueType: string | undefined): ConditionMetricValueType => { + if (valueType === 'string' || valueType === 'number' || valueType === 'boolean') + return valueType + + return defaultConditionMetricValueType } const humanizeMetricId = (metricId: string) => { @@ -15,17 +21,37 @@ const humanizeMetricId = (metricId: string) => { .join(' ') } -export const buildMetricOption = (metricId: string): MetricOption => ({ +export const buildMetricOption = (metricId: string, valueType?: string): MetricOption => ({ id: metricId, label: humanizeMetricId(metricId), description: getDefaultMetricDescription(metricId), - valueType: 'number', + valueType: normalizeMetricValueType(valueType), }) +export const dedupeNodeInfoList = (nodeInfoList: NodeInfo[]) => { + return Array.from(new Map(nodeInfoList.map(nodeInfo => [nodeInfo.node_id, nodeInfo])).values()) +} + +export const getDefaultMetricNodeInfoMap = (defaultMetrics: EvaluationDefaultMetric[]) => { + const nodeInfoMap: Record = {} + + defaultMetrics.forEach((defaultMetric) => { + if (!defaultMetric.metric) + return + + nodeInfoMap[defaultMetric.metric] = dedupeNodeInfoList([ + ...(nodeInfoMap[defaultMetric.metric] ?? []), + ...(defaultMetric.node_info_list ?? []), + ]) + }) + + return nodeInfoMap +} + export const getMetricVisual = (metricId: string): { icon: string, tone: MetricVisualTone } => { - if (['context-precision', 'context-recall'].includes(metricId)) { + if (['context_precision', 'context_recall'].includes(metricId)) { return { - icon: metricId === 'context-recall' ? 'i-ri-arrow-go-back-line' : 'i-ri-focus-2-line', + icon: metricId === 'context_recall' ? 'i-ri-arrow-go-back-line' : 'i-ri-focus-2-line', tone: 'green', } } @@ -33,29 +59,25 @@ export const getMetricVisual = (metricId: string): { icon: string, tone: MetricV if (metricId === 'faithfulness') return { icon: 'i-ri-anchor-line', tone: 'indigo' } - if (metricId === 'tool-correctness') + if (metricId === 'tool_correctness') return { icon: 'i-ri-tools-line', tone: 'indigo' } - if (metricId === 'task-completion') + if (metricId === 'task_completion') return { icon: 'i-ri-task-line', tone: 'indigo' } - if (metricId === 'argument-correctness') + if (metricId === 'argument_correctness') return { icon: 'i-ri-scales-3-line', tone: 'indigo' } return { icon: 'i-ri-checkbox-circle-line', tone: 'indigo' } } -export const getNodeVisual = (nodeInfo: NodeInfo): { icon: string, tone: MetricVisualTone } => { - const normalizedType = nodeInfo.type.toLowerCase() - const normalizedTitle = nodeInfo.title.toLowerCase() +const workflowBlockTypeSet = new Set(Object.values(BlockEnum)) - if (normalizedType.includes('retriev') || normalizedTitle.includes('retriev') || normalizedTitle.includes('knowledge')) - return { icon: 'i-ri-book-open-line', tone: 'green' } +export const getEvaluationNodeBlockType = (nodeInfo: Pick): BlockEnum => { + if (workflowBlockTypeSet.has(nodeInfo.type)) + return nodeInfo.type as BlockEnum - if (normalizedType.includes('agent') || normalizedTitle.includes('agent')) - return { icon: 'i-ri-user-star-line', tone: 'indigo' } - - return { icon: 'i-ri-ai-generate-2', tone: 'indigo' } + return BlockEnum.LLM } export const getToneClasses = (tone: MetricVisualTone) => { @@ -71,7 +93,3 @@ export const getToneClasses = (tone: MetricVisualTone) => { solid: 'bg-util-colors-indigo-indigo-500 text-white', } } - -export const dedupeNodeInfoList = (nodeInfoList: NodeInfo[]) => { - return Array.from(new Map(nodeInfoList.map(nodeInfo => [nodeInfo.node_id, nodeInfo])).values()) -} diff --git a/web/app/components/evaluation/components/pipeline/pipeline-batch-actions.tsx b/web/app/components/evaluation/components/pipeline/pipeline-batch-actions.tsx index cc1c415bde..cad35dc31b 100644 --- a/web/app/components/evaluation/components/pipeline/pipeline-batch-actions.tsx +++ b/web/app/components/evaluation/components/pipeline/pipeline-batch-actions.tsx @@ -4,8 +4,8 @@ import type { EvaluationResourceProps } from '../../types' import type { InputField } from '../batch-test-panel/input-fields/input-fields-utils' import { Button } from '@langgenius/dify-ui/button' import { useTranslation } from 'react-i18next' -import { getEvaluationMockConfig } from '../../mock' import { isEvaluationRunnable, useEvaluationResource } from '../../store' +import { EVALUATION_TEMPLATE_FILE_NAMES } from '../../store-utils' import UploadRunPopover from '../batch-test-panel/input-fields/upload-run-popover' import { useInputFieldsActions } from '../batch-test-panel/input-fields/use-input-fields-actions' @@ -20,7 +20,6 @@ const PipelineBatchActions = ({ }: EvaluationResourceProps) => { const { t } = useTranslation('evaluation') const resource = useEvaluationResource(resourceType, resourceId) - const config = getEvaluationMockConfig(resourceType) const isConfigReady = !!resource.judgeModelId && resource.metrics.some(metric => metric.kind === 'builtin') const isRunnable = isEvaluationRunnable(resource) const actions = useInputFieldsActions({ @@ -30,7 +29,7 @@ const PipelineBatchActions = ({ isInputFieldsLoading: false, isPanelReady: isConfigReady, isRunnable, - templateFileName: config.templateFileName, + templateFileName: EVALUATION_TEMPLATE_FILE_NAMES[resourceType], }) return ( diff --git a/web/app/components/evaluation/components/pipeline/pipeline-metrics-section.tsx b/web/app/components/evaluation/components/pipeline/pipeline-metrics-section.tsx index 2457b081c3..553083f867 100644 --- a/web/app/components/evaluation/components/pipeline/pipeline-metrics-section.tsx +++ b/web/app/components/evaluation/components/pipeline/pipeline-metrics-section.tsx @@ -9,8 +9,8 @@ import { BlockEnum } from '@/app/components/workflow/types' import { useDatasetDetailContextWithSelector } from '@/context/dataset-detail' import { useAvailableEvaluationMetrics } from '@/service/use-evaluation' import { usePublishedPipelineInfo } from '@/service/use-pipeline' -import { getEvaluationMockConfig } from '../../mock' import { useEvaluationResource, useEvaluationStore } from '../../store' +import { buildMetricOption } from '../metric-selector/utils' import { InlineSectionHeader } from '../section-header' import PipelineMetricItem from './pipeline-metric-item' @@ -52,7 +52,6 @@ const PipelineMetricsSection = ({ const { data: availableMetricsData } = useAvailableEvaluationMetrics() const { data: publishedPipeline } = usePublishedPipelineInfo(pipelineId || '') const resource = useEvaluationResource(resourceType, resourceId) - const config = getEvaluationMockConfig(resourceType) const knowledgeIndexNodeInfoList = useMemo( () => getKnowledgeIndexNodeInfo(publishedPipeline?.graph.nodes), [publishedPipeline?.graph.nodes], @@ -62,12 +61,14 @@ const PipelineMetricsSection = ({ .filter(metric => metric.kind === 'builtin') .map(metric => [metric.optionId, metric]), ), [resource.metrics]) - const availableMetricIds = useMemo(() => new Set(availableMetricsData?.metrics ?? []), [availableMetricsData?.metrics]) const availableBuiltinMetrics = useMemo(() => { - return config.builtinMetrics.filter(metric => - availableMetricIds.has(metric.id) || builtinMetricMap.has(metric.id), - ) - }, [availableMetricIds, builtinMetricMap, config.builtinMetrics]) + const metricIds = new Set([ + ...(availableMetricsData?.metrics ?? []), + ...builtinMetricMap.keys(), + ]) + + return Array.from(metricIds).map(metricId => buildMetricOption(metricId)) + }, [availableMetricsData?.metrics, builtinMetricMap]) useEffect(() => { if (!knowledgeIndexNodeInfoList.length) @@ -77,7 +78,7 @@ const PipelineMetricsSection = ({ if (metric.kind !== 'builtin' || isSameNodeInfoList(metric.nodeInfoList, knowledgeIndexNodeInfoList)) return - addBuiltinMetric(resourceType, resourceId, metric.optionId, knowledgeIndexNodeInfoList) + addBuiltinMetric(resourceType, resourceId, metric.optionId, knowledgeIndexNodeInfoList, metric) }) }, [addBuiltinMetric, knowledgeIndexNodeInfoList, resource.metrics, resourceId, resourceType]) @@ -88,7 +89,8 @@ const PipelineMetricsSection = ({ return } - addBuiltinMetric(resourceType, resourceId, metricId, knowledgeIndexNodeInfoList) + const metricOption = availableBuiltinMetrics.find(metric => metric.id === metricId) + addBuiltinMetric(resourceType, resourceId, metricId, knowledgeIndexNodeInfoList, metricOption) } return ( diff --git a/web/app/components/evaluation/mock.ts b/web/app/components/evaluation/mock.ts deleted file mode 100644 index 61f6d57b39..0000000000 --- a/web/app/components/evaluation/mock.ts +++ /dev/null @@ -1,179 +0,0 @@ -import type { - EvaluationFieldOption, - EvaluationMockConfig, - EvaluationResourceType, - MetricOption, -} from './types' -import { getDefaultMetricDescription } from './default-metric-descriptions' - -const judgeModels = [ - { - id: 'gpt-4.1-mini', - label: 'GPT-4.1 mini', - provider: 'OpenAI', - }, - { - id: 'claude-3-7-sonnet', - label: 'Claude 3.7 Sonnet', - provider: 'Anthropic', - }, - { - id: 'gemini-2.0-flash', - label: 'Gemini 2.0 Flash', - provider: 'Google', - }, -] - -const builtinMetrics: MetricOption[] = [ - { - id: 'answer-correctness', - label: 'Answer Correctness', - description: getDefaultMetricDescription('answer-correctness'), - valueType: 'number', - }, - { - id: 'faithfulness', - label: 'Faithfulness', - description: getDefaultMetricDescription('faithfulness'), - valueType: 'number', - }, - { - id: 'relevance', - label: 'Relevance', - description: getDefaultMetricDescription('relevance'), - valueType: 'number', - }, - { - id: 'latency', - label: 'Latency', - description: 'Captures runtime responsiveness for the full execution path.', - valueType: 'number', - }, - { - id: 'token-usage', - label: 'Token Usage', - description: 'Tracks prompt and completion token consumption for the run.', - valueType: 'number', - }, - { - id: 'tool-success-rate', - label: 'Tool Success Rate', - description: 'Measures whether each required tool invocation finishes without failure.', - valueType: 'number', - }, -] - -const pipelineBuiltinMetrics: MetricOption[] = [ - { - id: 'context-precision', - label: 'Context Precision', - description: getDefaultMetricDescription('context-precision'), - valueType: 'number', - }, - { - id: 'context-recall', - label: 'Context Recall', - description: getDefaultMetricDescription('context-recall'), - valueType: 'number', - }, - { - id: 'context-relevance', - label: 'Context Relevance', - description: getDefaultMetricDescription('context-relevance'), - valueType: 'number', - }, -] - -const workflowOptions = [ - { - id: 'workflow-precision-review', - label: 'Precision Review Workflow', - description: 'Custom evaluator for nuanced quality review.', - targetVariables: [ - { id: 'query', label: 'query' }, - { id: 'answer', label: 'answer' }, - { id: 'reference', label: 'reference' }, - ], - }, - { - id: 'workflow-risk-review', - label: 'Risk Review Workflow', - description: 'Custom evaluator for policy and escalation checks.', - targetVariables: [ - { id: 'input', label: 'input' }, - { id: 'output', label: 'output' }, - ], - }, -] - -const workflowFields: EvaluationFieldOption[] = [ - { id: 'app.input.query', label: 'Query', group: 'App Input', type: 'string' }, - { id: 'app.input.locale', label: 'Locale', group: 'App Input', type: 'enum', options: [{ value: 'en-US', label: 'en-US' }, { value: 'zh-Hans', label: 'zh-Hans' }] }, - { id: 'app.output.answer', label: 'Answer', group: 'App Output', type: 'string' }, - { id: 'app.output.score', label: 'Score', group: 'App Output', type: 'number' }, - { id: 'system.has_context', label: 'Has Context', group: 'System', type: 'boolean' }, -] - -const pipelineFields: EvaluationFieldOption[] = [ - { id: 'dataset.input.document_id', label: 'Document ID', group: 'Dataset', type: 'string' }, - { id: 'dataset.input.chunk_count', label: 'Chunk Count', group: 'Dataset', type: 'number' }, - { id: 'retrieval.output.hit_rate', label: 'Hit Rate', group: 'Retrieval', type: 'number' }, - { id: 'retrieval.output.source', label: 'Source', group: 'Retrieval', type: 'enum', options: [{ value: 'bm25', label: 'BM25' }, { value: 'hybrid', label: 'Hybrid' }] }, - { id: 'pipeline.output.published', label: 'Published', group: 'Output', type: 'boolean' }, -] - -const snippetFields: EvaluationFieldOption[] = [ - { id: 'snippet.input.blog_url', label: 'Blog URL', group: 'Snippet Input', type: 'string' }, - { id: 'snippet.input.platforms', label: 'Platforms', group: 'Snippet Input', type: 'string' }, - { id: 'snippet.output.content', label: 'Generated Content', group: 'Snippet Output', type: 'string' }, - { id: 'snippet.output.length', label: 'Output Length', group: 'Snippet Output', type: 'number' }, - { id: 'system.requires_review', label: 'Requires Review', group: 'System', type: 'boolean' }, -] - -export const getEvaluationMockConfig = (resourceType: EvaluationResourceType): EvaluationMockConfig => { - if (resourceType === 'datasets') { - return { - judgeModels, - builtinMetrics: pipelineBuiltinMetrics, - workflowOptions, - fieldOptions: pipelineFields, - templateFileName: 'pipeline-evaluation-template.csv', - batchRequirements: [ - 'Include one row per retrieval scenario.', - 'Provide the expected source or target chunk for each case.', - 'Keep numeric metrics in plain number format.', - ], - historySummaryLabel: 'Pipeline evaluation batch', - } - } - - if (resourceType === 'snippets') { - return { - judgeModels, - builtinMetrics, - workflowOptions, - fieldOptions: snippetFields, - templateFileName: 'snippet-evaluation-template.csv', - batchRequirements: [ - 'Include one row per snippet execution case.', - 'Provide the expected final content or acceptance rule.', - 'Keep optional fields empty when not used.', - ], - historySummaryLabel: 'Snippet evaluation batch', - } - } - - return { - judgeModels, - builtinMetrics, - workflowOptions, - fieldOptions: workflowFields, - templateFileName: 'workflow-evaluation-template.csv', - batchRequirements: [ - 'Include one row per workflow test case.', - 'Provide both user input and expected answer when available.', - 'Keep boolean columns as true or false.', - ], - historySummaryLabel: 'Workflow evaluation batch', - } -} diff --git a/web/app/components/evaluation/store-utils.ts b/web/app/components/evaluation/store-utils.ts index b8903442d8..ce2ecf7f18 100644 --- a/web/app/components/evaluation/store-utils.ts +++ b/web/app/components/evaluation/store-utils.ts @@ -21,7 +21,6 @@ import type { NodeInfo, } from '@/types/evaluation' import { getDefaultMetricDescription } from './default-metric-descriptions' -import { getEvaluationMockConfig } from './mock' import { buildConditionMetricOptions, decodeModelSelection, @@ -34,6 +33,19 @@ import { type EvaluationStoreResources = Record export const DEFAULT_PIPELINE_METRIC_THRESHOLD = 0.85 +export const EVALUATION_TEMPLATE_FILE_NAMES: Record = { + apps: 'workflow-evaluation-template.csv', + snippets: 'snippet-evaluation-template.csv', + datasets: 'pipeline-evaluation-template.csv', +} + +const BATCH_HISTORY_SUMMARY_LABELS: Record = { + apps: 'Workflow evaluation batch', + snippets: 'Snippet evaluation batch', + datasets: 'Pipeline evaluation batch', +} + +const PIPELINE_METRIC_IDS = new Set(['context-precision', 'context-recall', 'context-relevance']) const PIPELINE_LOGICAL_OPERATOR: JudgmentConfig['logicalOperator'] = 'and' @@ -47,9 +59,8 @@ const humanizeMetricId = (metricId: string) => { .join(' ') } -const resolveMetricOption = (resourceType: EvaluationResourceType, metricId: string): MetricOption => { - const config = getEvaluationMockConfig(resourceType) - return config.builtinMetrics.find(metric => metric.id === metricId) ?? { +export const resolveMetricOption = (metricId: string): MetricOption => { + return { id: metricId, label: humanizeMetricId(metricId), description: getDefaultMetricDescription(metricId), @@ -57,13 +68,11 @@ const resolveMetricOption = (resourceType: EvaluationResourceType, metricId: str } } -const pipelineMetricIds = new Set(getEvaluationMockConfig('datasets').builtinMetrics.map(metric => metric.id)) - const isPipelineResourceType = (resourceType: EvaluationResourceType) => resourceType === 'datasets' const isPipelineResourceState = (resource: EvaluationResourceState) => { return resource.metrics.length > 0 - && resource.metrics.every(metric => metric.kind === 'builtin' && pipelineMetricIds.has(metric.optionId)) + && resource.metrics.every(metric => metric.kind === 'builtin' && PIPELINE_METRIC_IDS.has(metric.optionId)) } const normalizeNodeInfoList = (value: NodeInfo[] | undefined): NodeInfo[] => { @@ -88,10 +97,7 @@ const normalizeNodeInfoList = (value: NodeInfo[] | undefined): NodeInfo[] => { .filter((item): item is NodeInfo => !!item) } -const normalizeDefaultMetrics = ( - resourceType: EvaluationResourceType, - value: EvaluationDefaultMetric[] | null | undefined, -): EvaluationMetric[] => { +const normalizeDefaultMetrics = (value: EvaluationDefaultMetric[] | null | undefined): EvaluationMetric[] => { if (!value?.length) return [] @@ -101,7 +107,7 @@ const normalizeDefaultMetrics = ( if (!metricId) return null - const metricOption = resolveMetricOption(resourceType, metricId) + const metricOption = resolveMetricOption(metricId) return createBuiltinMetric(metricOption, normalizeNodeInfoList(item.node_info_list ?? [])) }) .filter((item): item is EvaluationMetric => !!item) @@ -455,7 +461,7 @@ export const buildStateFromEvaluationConfig = ( resourceType: EvaluationResourceType, config: EvaluationConfig, ): EvaluationResourceState => { - const defaultMetrics = normalizeDefaultMetrics(resourceType, config.default_metrics) + const defaultMetrics = normalizeDefaultMetrics(config.default_metrics) const customMetrics = isPipelineResourceType(resourceType) ? [] : normalizeCustomMetric(config.customized_metrics) const metrics = isPipelineResourceType(resourceType) ? normalizePipelineMetrics(config, defaultMetrics) @@ -652,14 +658,12 @@ export const createBatchTestRecord = ( resourceType: EvaluationResourceType, uploadedFileName: string | null | undefined, ): BatchTestRecord => { - const config = getEvaluationMockConfig(resourceType) - return { id: createId('batch'), - fileName: uploadedFileName ?? config.templateFileName, + fileName: uploadedFileName ?? EVALUATION_TEMPLATE_FILE_NAMES[resourceType], status: 'running', startedAt: new Date().toLocaleTimeString(), - summary: config.historySummaryLabel, + summary: BATCH_HISTORY_SUMMARY_LABELS[resourceType], } } diff --git a/web/app/components/evaluation/store.ts b/web/app/components/evaluation/store.ts index 4e2df1bb00..c0ba492891 100644 --- a/web/app/components/evaluation/store.ts +++ b/web/app/components/evaluation/store.ts @@ -2,10 +2,11 @@ import type { ComparisonOperator, EvaluationResourceState, EvaluationResourceType, + MetricOption, } from './types' import type { EvaluationConfig, NodeInfo } from '@/types/evaluation' +import { isEqual } from 'es-toolkit/predicate' import { create } from 'zustand' -import { getEvaluationMockConfig } from './mock' import { buildConditionItem, buildInitialState, @@ -19,6 +20,7 @@ import { isCustomMetricConfigured as isCustomMetricConfiguredFromUtils, isEvaluationRunnable as isEvaluationRunnableFromUtils, requiresConditionValue as requiresConditionValueFromUtils, + resolveMetricOption, syncCustomMetricMappings as syncCustomMetricMappingsFromUtils, syncJudgmentConfigWithMetrics, updateMetric, @@ -28,10 +30,13 @@ import { buildConditionMetricOptions } from './utils' type EvaluationStore = { resources: Record + initialResources: Record ensureResource: (resourceType: EvaluationResourceType, resourceId: string) => void hydrateResource: (resourceType: EvaluationResourceType, resourceId: string, config: EvaluationConfig) => void + resetResourceConfig: (resourceType: EvaluationResourceType, resourceId: string) => void + markResourceConfigSaved: (resourceType: EvaluationResourceType, resourceId: string) => void setJudgeModel: (resourceType: EvaluationResourceType, resourceId: string, judgeModelId: string) => void - addBuiltinMetric: (resourceType: EvaluationResourceType, resourceId: string, optionId: string, nodeInfoList?: NodeInfo[]) => void + addBuiltinMetric: (resourceType: EvaluationResourceType, resourceId: string, optionId: string, nodeInfoList?: NodeInfo[], metricOption?: MetricOption) => void updateMetricThreshold: (resourceType: EvaluationResourceType, resourceId: string, metricId: string, threshold: number) => void addCustomMetric: (resourceType: EvaluationResourceType, resourceId: string) => void removeMetric: (resourceType: EvaluationResourceType, resourceId: string, metricId: string) => void @@ -88,8 +93,68 @@ type EvaluationStore = { const initialResourceCache: Record = {} +const cloneEvaluationResourceState = (resource: EvaluationResourceState): EvaluationResourceState => ({ + ...resource, + metrics: resource.metrics.map(metric => ({ + ...metric, + nodeInfoList: metric.nodeInfoList?.map(nodeInfo => ({ ...nodeInfo })), + customConfig: metric.customConfig + ? { + ...metric.customConfig, + mappings: metric.customConfig.mappings.map(mapping => ({ ...mapping })), + outputs: metric.customConfig.outputs.map(output => ({ ...output })), + } + : undefined, + })), + judgmentConfig: { + ...resource.judgmentConfig, + conditions: resource.judgmentConfig.conditions.map(condition => ({ ...condition })), + }, + batchRecords: resource.batchRecords.map(record => ({ ...record })), +}) + +const preserveBatchState = ( + configState: EvaluationResourceState, + currentResource: EvaluationResourceState | undefined, + resourceType: EvaluationResourceType, +): EvaluationResourceState => { + const initialState = buildInitialState(resourceType) + + return { + ...cloneEvaluationResourceState(configState), + activeBatchTab: currentResource?.activeBatchTab ?? initialState.activeBatchTab, + uploadedFileId: currentResource?.uploadedFileId ?? initialState.uploadedFileId, + uploadedFileName: currentResource?.uploadedFileName ?? initialState.uploadedFileName, + selectedRunId: currentResource?.selectedRunId ?? initialState.selectedRunId, + batchRecords: currentResource?.batchRecords.map(record => ({ ...record })) ?? initialState.batchRecords, + } +} + +const createConfigSnapshot = ( + resourceType: EvaluationResourceType, + resource: EvaluationResourceState, +): EvaluationResourceState => { + const initialState = buildInitialState(resourceType) + + return { + ...cloneEvaluationResourceState(resource), + activeBatchTab: initialState.activeBatchTab, + uploadedFileId: initialState.uploadedFileId, + uploadedFileName: initialState.uploadedFileName, + selectedRunId: initialState.selectedRunId, + batchRecords: initialState.batchRecords, + } +} + +const pickConfigComparableState = (resource: EvaluationResourceState) => ({ + judgeModelId: resource.judgeModelId, + metrics: resource.metrics, + judgmentConfig: resource.judgmentConfig, +}) + export const useEvaluationStore = create((set, get) => ({ resources: {}, + initialResources: {}, ensureResource: (resourceType, resourceId) => { const resourceKey = buildResourceKey(resourceType, resourceId) if (get().resources[resourceKey]) @@ -103,17 +168,42 @@ export const useEvaluationStore = create((set, get) => ({ })) }, hydrateResource: (resourceType, resourceId, config) => { + const resourceKey = buildResourceKey(resourceType, resourceId) + const configState = buildStateFromEvaluationConfig(resourceType, config) + set(state => ({ resources: { ...state.resources, - [buildResourceKey(resourceType, resourceId)]: { - ...buildStateFromEvaluationConfig(resourceType, config), - activeBatchTab: state.resources[buildResourceKey(resourceType, resourceId)]?.activeBatchTab ?? 'input-fields', - uploadedFileId: state.resources[buildResourceKey(resourceType, resourceId)]?.uploadedFileId ?? null, - uploadedFileName: state.resources[buildResourceKey(resourceType, resourceId)]?.uploadedFileName ?? null, - selectedRunId: state.resources[buildResourceKey(resourceType, resourceId)]?.selectedRunId ?? null, - batchRecords: state.resources[buildResourceKey(resourceType, resourceId)]?.batchRecords ?? [], - }, + [resourceKey]: preserveBatchState(configState, state.resources[resourceKey], resourceType), + }, + initialResources: { + ...state.initialResources, + [resourceKey]: createConfigSnapshot(resourceType, configState), + }, + })) + }, + resetResourceConfig: (resourceType, resourceId) => { + const resourceKey = buildResourceKey(resourceType, resourceId) + + set(state => ({ + resources: { + ...state.resources, + [resourceKey]: preserveBatchState( + state.initialResources[resourceKey] ?? buildInitialState(resourceType), + state.resources[resourceKey], + resourceType, + ), + }, + })) + }, + markResourceConfigSaved: (resourceType, resourceId) => { + const resourceKey = buildResourceKey(resourceType, resourceId) + const resource = get().resources[resourceKey] ?? buildInitialState(resourceType) + + set(state => ({ + initialResources: { + ...state.initialResources, + [resourceKey]: createConfigSnapshot(resourceType, resource), }, })) }, @@ -125,11 +215,8 @@ export const useEvaluationStore = create((set, get) => ({ })), })) }, - addBuiltinMetric: (resourceType, resourceId, optionId, nodeInfoList = []) => { - const option = getEvaluationMockConfig(resourceType).builtinMetrics.find(metric => metric.id === optionId) - if (!option) - return - + addBuiltinMetric: (resourceType, resourceId, optionId, nodeInfoList = [], metricOption) => { + const option = metricOption ?? resolveMetricOption(optionId) set((state) => { return { resources: updateResourceState(state.resources, resourceType, resourceId, (currentResource) => { @@ -436,6 +523,20 @@ export const useEvaluationResource = (resourceType: EvaluationResourceType, reso return useEvaluationStore(state => state.resources[resourceKey] ?? (initialResourceCache[resourceKey] ??= buildInitialState(resourceType))) } +export const useIsEvaluationConfigDirty = (resourceType: EvaluationResourceType, resourceId: string) => { + const resourceKey = buildResourceKey(resourceType, resourceId) + + return useEvaluationStore((state) => { + const resource = state.resources[resourceKey] ?? (initialResourceCache[resourceKey] ??= buildInitialState(resourceType)) + const initialResource = state.initialResources[resourceKey] ?? buildInitialState(resourceType) + + return !isEqual( + pickConfigComparableState(resource), + pickConfigComparableState(initialResource), + ) + }) +} + export const getAllowedOperators = ( metrics: EvaluationResourceState['metrics'], variableSelector: [string, string] | null, diff --git a/web/app/components/evaluation/types.ts b/web/app/components/evaluation/types.ts index c0a1574cf8..c57d696b79 100644 --- a/web/app/components/evaluation/types.ts +++ b/web/app/components/evaluation/types.ts @@ -1,18 +1,22 @@ import type { NodeInfo } from '@/types/evaluation' export type EvaluationResourceType = 'apps' | 'datasets' | 'snippets' +export type NonPipelineEvaluationResourceType = Exclude export type EvaluationResourceProps = { resourceType: EvaluationResourceType resourceId: string } +export type NonPipelineEvaluationResourceProps = { + resourceType: NonPipelineEvaluationResourceType + resourceId: string +} + export type MetricKind = 'builtin' | 'custom-workflow' export type BatchTestTab = 'input-fields' | 'history' -export type FieldType = 'string' | 'number' | 'boolean' | 'enum' - export type ConditionMetricValueType = 'string' | 'number' | 'boolean' export type ComparisonOperator @@ -35,12 +39,6 @@ export type ComparisonOperator | 'is null' | 'is not null' -export type JudgeModelOption = { - id: string - label: string - provider: string -} - export type MetricOption = { id: string label: string @@ -48,27 +46,6 @@ export type MetricOption = { valueType: ConditionMetricValueType } -export type EvaluationWorkflowOption = { - id: string - label: string - description: string - targetVariables: Array<{ - id: string - label: string - }> -} - -export type EvaluationFieldOption = { - id: string - label: string - group: string - type: FieldType - options?: Array<{ - value: string - label: string - }> -} - export type CustomMetricMapping = { id: string inputVariableId: string | null @@ -141,13 +118,3 @@ export type EvaluationResourceState = { selectedRunId: string | null batchRecords: BatchTestRecord[] } - -export type EvaluationMockConfig = { - judgeModels: JudgeModelOption[] - builtinMetrics: MetricOption[] - workflowOptions: EvaluationWorkflowOption[] - fieldOptions: EvaluationFieldOption[] - templateFileName: string - batchRequirements: string[] - historySummaryLabel: string -} diff --git a/web/app/components/header/nav/__tests__/index.spec.tsx b/web/app/components/header/nav/__tests__/index.spec.tsx index 90d4cc4f73..3615a9a2c9 100644 --- a/web/app/components/header/nav/__tests__/index.spec.tsx +++ b/web/app/components/header/nav/__tests__/index.spec.tsx @@ -307,11 +307,15 @@ describe('Nav Component', () => { fireEvent.click(selectorButton) }) - const createButton = await screen.findByText('Create New') - await act(async () => { - fireEvent.click(createButton) - }) + const openCreateMenu = async () => { + const createButton = await screen.findByText('Create New') + await act(async () => { + fireEvent.click(createButton) + }) + return screen.findByText(/app\.newApp\.startFromBlank/i) + } + await openCreateMenu() const blankOption = await screen.findByText( /app\.newApp\.startFromBlank/i, ) @@ -320,6 +324,7 @@ describe('Nav Component', () => { }) expect(mockOnCreate).toHaveBeenCalledWith('blank') + await openCreateMenu() const templateOption = await screen.findByText( /app\.newApp\.startFromTemplate/i, ) @@ -328,6 +333,7 @@ describe('Nav Component', () => { }) expect(mockOnCreate).toHaveBeenCalledWith('template') + await openCreateMenu() const dslOption = await screen.findByText(/app\.importDSL/i) await act(async () => { fireEvent.click(dslOption) diff --git a/web/app/components/header/nav/nav-selector/__tests__/index.spec.tsx b/web/app/components/header/nav/nav-selector/__tests__/index.spec.tsx index 97443bb759..b1de3ab5e3 100644 --- a/web/app/components/header/nav/nav-selector/__tests__/index.spec.tsx +++ b/web/app/components/header/nav/nav-selector/__tests__/index.spec.tsx @@ -203,23 +203,30 @@ describe('NavSelector Component', () => { await act(async () => { fireEvent.click(button) }) - const createBtn = screen.getByText('Create New') - await act(async () => { - fireEvent.click(createBtn) - }) + const openCreateMenu = async () => { + const createBtn = screen.getByText('Create New') + await act(async () => { + fireEvent.click(createBtn) + }) + return screen.findByText(/app\.newApp\.startFromBlank/i) + } + + await openCreateMenu() const blank = await screen.findByText(/app\.newApp\.startFromBlank/i) await act(async () => { fireEvent.click(blank) }) expect(mockOnCreate).toHaveBeenCalledWith('blank') + await openCreateMenu() const template = await screen.findByText(/app\.newApp\.startFromTemplate/i) await act(async () => { fireEvent.click(template) }) expect(mockOnCreate).toHaveBeenCalledWith('template') + await openCreateMenu() const dsl = await screen.findByText(/app\.importDSL/i) await act(async () => { fireEvent.click(dsl) @@ -227,6 +234,21 @@ describe('NavSelector Component', () => { expect(mockOnCreate).toHaveBeenCalledWith('dsl') }) + it('should open extended create menu on hover in app mode', async () => { + render() + const button = screen.getByRole('button') + await act(async () => { + fireEvent.click(button) + }) + + const createBtn = screen.getByText('Create New') + await act(async () => { + fireEvent.mouseEnter(createBtn) + }) + + expect(await screen.findByText(/app\.newApp\.startFromBlank/i))!.toBeInTheDocument() + }) + it('should not show create button for non-editors', async () => { vi.mocked(useAppContext).mockReturnValue({ isCurrentWorkspaceEditor: false, diff --git a/web/app/components/header/nav/nav-selector/index.tsx b/web/app/components/header/nav/nav-selector/index.tsx index 285639adf7..a46c200e3d 100644 --- a/web/app/components/header/nav/nav-selector/index.tsx +++ b/web/app/components/header/nav/nav-selector/index.tsx @@ -1,6 +1,6 @@ 'use client' import type { AppIconType, AppModeEnum } from '@/types/app' -import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react' +import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/react' import { cn } from '@langgenius/dify-ui/cn' import { RiAddLine, @@ -8,7 +8,7 @@ import { RiArrowRightSLine, } from '@remixicon/react' import { debounce } from 'es-toolkit/compat' -import { Fragment, useCallback } from 'react' +import { useCallback, useState } from 'react' import { useTranslation } from 'react-i18next' import { useStore as useAppStore } from '@/app/components/app/store' import { AppTypeIcon } from '@/app/components/app/type-selector' @@ -38,6 +38,75 @@ export type INavSelectorProps = { isLoadingMore?: boolean } +type AppCreateMenuProps = { + createText: string + startFromBlankText: string + startFromTemplateText: string + importDSLText: string + onCreate: (state: string) => void +} + +const AppCreateMenu = ({ + createText, + startFromBlankText, + startFromTemplateText, + importDSLText, + onCreate, +}: AppCreateMenuProps) => { + const [open, setOpen] = useState(false) + + const handleCreate = (state: string) => { + setOpen(false) + onCreate(state) + } + + return ( +
setOpen(false)}> + + {open && ( +
setOpen(true)} + > +
+ + +
+
+ +
+
+ )} +
+ ) +} + const NavSelector = ({ curNav, navigationItems, createText, isApp, onCreate, onLoadMore, isLoadingMore }: INavSelectorProps) => { const { t } = useTranslation() const router = useRouter() @@ -72,7 +141,7 @@ const NavSelector = ({ curNav, navigationItems, createText, isApp, onCreate, onL className=" absolute right-0 -left-11 mt-1.5 w-60 max-w-80 origin-top-right divide-y divide-divider-regular rounded-lg bg-components-panel-bg-blur - shadow-lg + shadow-lg outline-none " >
@@ -130,56 +199,13 @@ const NavSelector = ({ curNav, navigationItems, createText, isApp, onCreate, onL )} {isApp && isCurrentWorkspaceEditor && ( - - {({ open }) => ( - <> - -
-
- -
-
{createText}
- -
-
- - -
-
onCreate('blank')}> - - {t('newApp.startFromBlank', { ns: 'app' })} -
-
onCreate('template')}> - - {t('newApp.startFromTemplate', { ns: 'app' })} -
-
-
-
onCreate('dsl')}> - - {t('importDSL', { ns: 'app' })} -
-
-
-
- - )} -
+ )} diff --git a/web/app/components/plugins/plugin-detail-panel/__tests__/endpoint-list.spec.tsx b/web/app/components/plugins/plugin-detail-panel/__tests__/endpoint-list.spec.tsx index e31afc7cb2..ec9a8eeccf 100644 --- a/web/app/components/plugins/plugin-detail-panel/__tests__/endpoint-list.spec.tsx +++ b/web/app/components/plugins/plugin-detail-panel/__tests__/endpoint-list.spec.tsx @@ -76,6 +76,8 @@ const createPluginDetail = (): PluginDetail => ({ }) describe('EndpointList', () => { + const getAddButton = () => screen.getByRole('button', { name: 'plugin.detailPanel.endpointModalTitle' }) + beforeEach(() => { vi.clearAllMocks() mockEndpointListData = { endpoints: mockEndpoints } @@ -112,7 +114,7 @@ describe('EndpointList', () => { it('should render add button', () => { render() - expect(screen.getAllByRole('button').length).toBeGreaterThan(0) + expect(getAddButton()).toBeInTheDocument() }) }) @@ -120,8 +122,7 @@ describe('EndpointList', () => { it('should show modal when add button clicked', () => { render() - const addButton = screen.getAllByRole('button')[0] - fireEvent.click(addButton!) + fireEvent.click(getAddButton()) expect(screen.getByTestId('endpoint-modal'))!.toBeInTheDocument() }) @@ -129,8 +130,7 @@ describe('EndpointList', () => { it('should hide modal when cancel clicked', () => { render() - const addButton = screen.getAllByRole('button')[0] - fireEvent.click(addButton!) + fireEvent.click(getAddButton()) expect(screen.getByTestId('endpoint-modal'))!.toBeInTheDocument() fireEvent.click(screen.getByTestId('modal-cancel')) @@ -140,8 +140,7 @@ describe('EndpointList', () => { it('should call createEndpoint when save clicked', () => { render() - const addButton = screen.getAllByRole('button')[0] - fireEvent.click(addButton!) + fireEvent.click(getAddButton()) fireEvent.click(screen.getByTestId('modal-save')) expect(mockCreateEndpoint).toHaveBeenCalled() @@ -176,8 +175,7 @@ describe('EndpointList', () => { it('should invalidate endpoint list after successful create', () => { render() - const addButton = screen.getAllByRole('button')[0] - fireEvent.click(addButton!) + fireEvent.click(getAddButton()) fireEvent.click(screen.getByTestId('modal-save')) expect(mockInvalidateEndpointList).toHaveBeenCalledWith('test-plugin') @@ -186,8 +184,7 @@ describe('EndpointList', () => { it('should pass correct params to createEndpoint', () => { render() - const addButton = screen.getAllByRole('button')[0] - fireEvent.click(addButton!) + fireEvent.click(getAddButton()) fireEvent.click(screen.getByTestId('modal-save')) expect(mockCreateEndpoint).toHaveBeenCalledWith({ diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx index 2d11305f6e..d50ab4c4ea 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx @@ -1,5 +1,6 @@ import type { PluginDetail } from '@/app/components/plugins/types' import { cn } from '@langgenius/dify-ui/cn' +import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover' import { toast } from '@langgenius/dify-ui/toast' import { RiAddLine, @@ -11,7 +12,6 @@ import * as React from 'react' import { useMemo } from 'react' import { useTranslation } from 'react-i18next' import ActionButton from '@/app/components/base/action-button' -import Tooltip from '@/app/components/base/tooltip' import { toolCredentialToFormSchemas } from '@/app/components/tools/utils/to-form-schema' import { useDocLink } from '@/context/i18n' import { @@ -67,10 +67,23 @@ const EndpointList = ({ detail }: Props) => {
{t('detailPanel.endpoints', { ns: 'plugin' })} - + + + + )} + /> +
@@ -80,17 +93,19 @@ const EndpointList = ({ detail }: Props) => { href={docLink('/develop-plugin/getting-started/getting-started-dify-plugin')} target="_blank" rel="noopener noreferrer" + className="inline-flex cursor-pointer items-center gap-1 system-xs-regular text-text-accent" > -
- - {t('detailPanel.endpointsDocLink', { ns: 'plugin' })} -
+ + {t('detailPanel.endpointsDocLink', { ns: 'plugin' })}
- )} - /> + +
- +
diff --git a/web/app/components/snippets/__tests__/snippet-evaluation-page.spec.tsx b/web/app/components/snippets/__tests__/snippet-evaluation-page.spec.tsx index 1c30cab2c9..b3962c8792 100644 --- a/web/app/components/snippets/__tests__/snippet-evaluation-page.spec.tsx +++ b/web/app/components/snippets/__tests__/snippet-evaluation-page.spec.tsx @@ -1,10 +1,11 @@ import type { SnippetDetailPayload } from '@/models/snippet' +import type { Snippet } from '@/types/snippet' import { render, screen } from '@testing-library/react' import SnippetEvaluationPage from '../snippet-evaluation-page' const mockUseSnippetApiDetail = vi.fn() -const mockGetSnippetDetailMock = vi.fn() const mockSetAppSidebarExpand = vi.fn() +const mockUseDocumentTitle = vi.fn() vi.mock('@/service/use-snippets', async (importOriginal) => { const actual = await importOriginal() @@ -34,15 +35,15 @@ vi.mock('@/next/navigation', () => ({ }), })) -vi.mock('@/service/use-snippets.mock', () => ({ - getSnippetDetailMock: (snippetId: string) => mockGetSnippetDetailMock(snippetId), -})) - vi.mock('@/hooks/use-breakpoints', () => ({ default: () => 'desktop', MediaType: { mobile: 'mobile', desktop: 'desktop' }, })) +vi.mock('@/hooks/use-document-title', () => ({ + default: (title: string) => mockUseDocumentTitle(title), +})) + vi.mock('@/app/components/app/store', () => ({ useStore: (selector: (state: { setAppSidebarExpand: typeof mockSetAppSidebarExpand }) => unknown) => selector({ setAppSidebarExpand: mockSetAppSidebarExpand, @@ -101,21 +102,39 @@ const mockSnippetDetail: SnippetDetailPayload = { }, } +const mockSnippetApiDetail: Snippet = { + id: mockSnippetDetail.snippet.id, + name: mockSnippetDetail.snippet.name, + description: mockSnippetDetail.snippet.description, + type: 'node', + version: '1', + use_count: 19, + icon_info: { + icon: mockSnippetDetail.snippet.icon, + icon_background: mockSnippetDetail.snippet.iconBackground, + icon_type: 'emoji', + }, + input_fields: [], + created_at: 1711267200, + created_by: 'user-1', + updated_at: 1711267200, + updated_by: 'user-1', + is_published: true, +} + describe('SnippetEvaluationPage', () => { beforeEach(() => { vi.clearAllMocks() mockUseSnippetApiDetail.mockReturnValue({ - data: undefined, + data: mockSnippetApiDetail, isLoading: false, }) - mockGetSnippetDetailMock.mockReturnValue(mockSnippetDetail) }) - it('should render evaluation with mock snippet detail data', () => { + it('should render evaluation with snippet detail data from api', () => { render() - expect(mockGetSnippetDetailMock).toHaveBeenCalledWith('snippet-1') - expect(mockUseSnippetApiDetail).not.toHaveBeenCalled() + expect(mockUseSnippetApiDetail).toHaveBeenCalledWith('snippet-1') expect(screen.getByTestId('app-sidebar')).toBeInTheDocument() expect(screen.getByTestId('evaluation')).toHaveTextContent('snippet-1') }) diff --git a/web/app/components/snippets/snippet-evaluation-page.tsx b/web/app/components/snippets/snippet-evaluation-page.tsx index f6aeeef335..c0585cef25 100644 --- a/web/app/components/snippets/snippet-evaluation-page.tsx +++ b/web/app/components/snippets/snippet-evaluation-page.tsx @@ -1,9 +1,13 @@ 'use client' import { useMemo } from 'react' +import Loading from '@/app/components/base/loading' import SnippetAndEvaluationPlanGuard from '@/app/components/billing/snippet-and-evaluation-plan-guard' import Evaluation from '@/app/components/evaluation' -import { getSnippetDetailMock } from '@/service/use-snippets.mock' +import { + buildSnippetDetailPayload, + useSnippetApiDetail, +} from '@/service/use-snippets' import SnippetLayout from './components/snippet-layout' type SnippetEvaluationPageProps = { @@ -11,8 +15,21 @@ type SnippetEvaluationPageProps = { } const SnippetEvaluationPage = ({ snippetId }: SnippetEvaluationPageProps) => { - const mockSnippet = useMemo(() => getSnippetDetailMock(snippetId)?.snippet, [snippetId]) - const snippet = mockSnippet + const { data, isLoading } = useSnippetApiDetail(snippetId) + const snippet = useMemo(() => { + if (!data) + return undefined + + return buildSnippetDetailPayload(data).snippet + }, [data]) + + if (isLoading) { + return ( +
+ +
+ ) + } if (!snippet) return null diff --git a/web/app/components/tools/mcp/detail/__tests__/content.spec.tsx b/web/app/components/tools/mcp/detail/__tests__/content.spec.tsx index c2835c992b..261781f8c0 100644 --- a/web/app/components/tools/mcp/detail/__tests__/content.spec.tsx +++ b/web/app/components/tools/mcp/detail/__tests__/content.spec.tsx @@ -12,6 +12,7 @@ const mockAuthorizeMcp = vi.fn().mockResolvedValue({ result: 'success' }) const mockUpdateMCP = vi.fn().mockResolvedValue({ result: 'success' }) const mockDeleteMCP = vi.fn().mockResolvedValue({ result: 'success' }) const mockInvalidateMCPTools = vi.fn() +const mockInvalidateAllMCPTools = vi.fn() const mockOpenOAuthPopup = vi.fn() // Mutable mock state @@ -33,6 +34,7 @@ vi.mock('@/service/use-tools', () => ({ isFetching: mockIsFetching, }), useInvalidateMCPTools: () => mockInvalidateMCPTools, + useInvalidateAllMCPTools: () => mockInvalidateAllMCPTools, useUpdateMCPTools: () => ({ mutateAsync: mockUpdateTools, isPending: mockIsUpdating, @@ -180,6 +182,7 @@ describe('MCPDetailContent', () => { mockUpdateMCP.mockClear() mockDeleteMCP.mockClear() mockInvalidateMCPTools.mockClear() + mockInvalidateAllMCPTools.mockClear() mockOpenOAuthPopup.mockClear() // Reset mock return values @@ -512,6 +515,7 @@ describe('MCPDetailContent', () => { await waitFor(() => { expect(mockUpdateTools).toHaveBeenCalledWith('mcp-1') expect(mockInvalidateMCPTools).toHaveBeenCalledWith('mcp-1') + expect(mockInvalidateAllMCPTools).toHaveBeenCalled() expect(onUpdate).toHaveBeenCalled() }) }) @@ -529,6 +533,7 @@ describe('MCPDetailContent', () => { await waitFor(() => { expect(mockUpdateTools).toHaveBeenCalledWith('mcp-1') + expect(mockInvalidateAllMCPTools).toHaveBeenCalled() }) }) }) diff --git a/web/app/components/tools/mcp/detail/content.tsx b/web/app/components/tools/mcp/detail/content.tsx index 35c8a35a6f..c785516eee 100644 --- a/web/app/components/tools/mcp/detail/content.tsx +++ b/web/app/components/tools/mcp/detail/content.tsx @@ -26,6 +26,7 @@ import { openOAuthPopup } from '@/hooks/use-oauth' import { useAuthorizeMCP, useDeleteMCP, + useInvalidateAllMCPTools, useInvalidateMCPTools, useMCPTools, useUpdateMCP, @@ -61,6 +62,7 @@ const MCPDetailContent: FC = ({ const { data, isFetching: isGettingTools } = useMCPTools(detail.is_team_authorization ? detail.id : '') const invalidateMCPTools = useInvalidateMCPTools() + const invalidateAllMCPTools = useInvalidateAllMCPTools() const { mutateAsync: updateTools, isPending: isUpdating } = useUpdateMCPTools() const { mutateAsync: authorizeMcp, isPending: isAuthorizing } = useAuthorizeMCP() const toolList = data?.tools || [] @@ -76,8 +78,9 @@ const MCPDetailContent: FC = ({ return await updateTools(detail.id) invalidateMCPTools(detail.id) + invalidateAllMCPTools() onUpdate() - }, [detail, hideUpdateConfirm, invalidateMCPTools, onUpdate, updateTools]) + }, [detail, hideUpdateConfirm, invalidateAllMCPTools, invalidateMCPTools, onUpdate, updateTools]) const { mutateAsync: updateMCP } = useUpdateMCP({}) const { mutateAsync: deleteMCP } = useDeleteMCP({}) diff --git a/web/app/components/tools/mcp/detail/tool-item.tsx b/web/app/components/tools/mcp/detail/tool-item.tsx index 4101fa2078..f05890aee2 100644 --- a/web/app/components/tools/mcp/detail/tool-item.tsx +++ b/web/app/components/tools/mcp/detail/tool-item.tsx @@ -1,9 +1,9 @@ 'use client' import type { Tool } from '@/app/components/tools/types' import { cn } from '@langgenius/dify-ui/cn' +import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover' import * as React from 'react' import { useTranslation } from 'react-i18next' -import Tooltip from '@/app/components/base/tooltip' import { useLocale } from '@/context/i18n' import { getLanguage } from '@/i18n-config/language' @@ -51,25 +51,31 @@ const MCPToolItem = ({ } return ( - + +
{tool.label[language]}
+
{tool.description[language]}
+ + )} + /> +
{tool.label[language]}
{tool.description[language]}
{renderParameters()}
- )} - > -
-
{tool.label[language]}
-
{tool.description[language]}
-
-
+ + ) } export default MCPToolItem diff --git a/web/app/components/tools/mcp/mcp-service-card.tsx b/web/app/components/tools/mcp/mcp-service-card.tsx index 67beb9b3ee..3810e5b4c2 100644 --- a/web/app/components/tools/mcp/mcp-service-card.tsx +++ b/web/app/components/tools/mcp/mcp-service-card.tsx @@ -15,14 +15,15 @@ import { } from '@langgenius/dify-ui/alert-dialog' import { Button } from '@langgenius/dify-ui/button' import { cn } from '@langgenius/dify-ui/cn' +import { Popover, PopoverContent, PopoverTrigger } from '@langgenius/dify-ui/popover' import { Switch } from '@langgenius/dify-ui/switch' +import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip' import { RiEditLine, RiLoopLeftLine } from '@remixicon/react' import { useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import CopyFeedback from '@/app/components/base/copy-feedback' import Divider from '@/app/components/base/divider' import { Mcp } from '@/app/components/base/icons/src/vender/other' -import Tooltip from '@/app/components/base/tooltip' import Indicator from '@/app/components/header/indicator' import MCPServerModal from '@/app/components/tools/mcp/mcp-server-modal' import { collaborationManager } from '@/app/components/workflow/collaboration/core/collaboration-manager' @@ -81,13 +82,22 @@ const ServerURLSection: FC = ({ {isCurrentWorkspaceManager && ( - -
- -
+ + + + + )} + /> + + {t('overview.appInfo.regenerate', { ns: 'appOverview' })} + )} @@ -104,13 +114,19 @@ type TriggerModeOverlayProps = { const TriggerModeOverlay: FC = ({ triggerModeMessage }) => { if (triggerModeMessage) { return ( - - - + + } + /> + + {triggerModeMessage} + + ) } return @@ -146,12 +162,13 @@ function getTooltipContent({
{t('overview.appInfo.enableTooltip.description', { ns: 'appOverview' })}
-
window.open(docLink('/use-dify/nodes/user-input'), '_blank')} > {t('overview.appInfo.enableTooltip.learnMore', { ns: 'appOverview' })} -
+ ) } @@ -316,16 +333,31 @@ const MCPServiceCard: FC = ({
- -
- -
-
+ {toggleDisabled && tooltipContent + ? ( + + + +
+ )} + /> + + {tooltipContent} + + + ) + : ( + + )}
{!isMinimalState && ( import('@/__mocks__/base-ui-popover')) + // Mock Next.js navigation const mockPush = vi.fn() vi.mock('@/next/navigation', () => ({ @@ -83,12 +85,11 @@ vi.mock('@/app/components/base/drawer-plus', () => ({ }, })) -// Mock EmojiPicker - simplified for testing -vi.mock('@/app/components/base/emoji-picker', () => ({ - default: ({ onSelect, onClose }: { onSelect: (icon: string, background: string) => void, onClose: () => void }) => ( +// Mock EmojiPickerInner - simplified for testing +vi.mock('@/app/components/base/emoji-picker/Inner', () => ({ + default: ({ onSelect }: { onSelect: (icon: string, background: string) => void }) => (
-
), })) @@ -978,6 +979,7 @@ describe('WorkflowToolAsModal', () => { // Select emoji await user.click(screen.getByTestId('select-emoji')) + await user.click(screen.getByRole('button', { name: 'app.iconPicker.ok' })) // Assert const updatedIcon = screen.getByTestId('app-icon') @@ -1002,7 +1004,7 @@ describe('WorkflowToolAsModal', () => { expect(screen.getByTestId('emoji-picker'))!.toBeInTheDocument() - await user.click(screen.getByTestId('close-emoji-picker')) + await user.click(screen.getByRole('button', { name: 'app.iconPicker.cancel' })) // Assert // Assert @@ -1501,7 +1503,7 @@ describe('MethodSelector', () => { // Assert // Assert - expect(screen.getByTestId('portal-trigger'))!.toBeInTheDocument() + expect(screen.getByTestId('popover-trigger'))!.toBeInTheDocument() }) it('should display parameter method text when value is llm', () => { @@ -1562,11 +1564,11 @@ describe('MethodSelector', () => { // Act render() - await user.click(screen.getByTestId('portal-trigger')) + await user.click(screen.getByTestId('popover-trigger')) // Assert // Assert - expect(screen.getByTestId('portal-content'))!.toBeInTheDocument() + expect(screen.getByTestId('popover-content'))!.toBeInTheDocument() }) it('should call onChange with llm when parameter option clicked', async () => { @@ -1580,7 +1582,7 @@ describe('MethodSelector', () => { // Act render() - await user.click(screen.getByTestId('portal-trigger')) + await user.click(screen.getByTestId('popover-trigger')) const paramOption = screen.getAllByText('tools.createTool.toolInput.methodParameter')[0] await user.click(paramOption!) @@ -1600,7 +1602,7 @@ describe('MethodSelector', () => { // Act render() - await user.click(screen.getByTestId('portal-trigger')) + await user.click(screen.getByTestId('popover-trigger')) const settingOption = screen.getByText('tools.createTool.toolInput.methodSetting') await user.click(settingOption) @@ -1621,12 +1623,12 @@ describe('MethodSelector', () => { render() // First click - open - await user.click(screen.getByTestId('portal-trigger')) - expect(screen.getByTestId('portal-content'))!.toBeInTheDocument() + await user.click(screen.getByTestId('popover-trigger')) + expect(screen.getByTestId('popover-content'))!.toBeInTheDocument() // Second click - close - await user.click(screen.getByTestId('portal-trigger')) - expect(screen.queryByTestId('portal-content')).not.toBeInTheDocument() + await user.click(screen.getByTestId('popover-trigger')) + expect(screen.queryByTestId('popover-content')).not.toBeInTheDocument() }) }) @@ -1642,10 +1644,10 @@ describe('MethodSelector', () => { // Act render() - await user.click(screen.getByTestId('portal-trigger')) + await user.click(screen.getByTestId('popover-trigger')) // Assert - the first option (llm) should have a check icon container - const content = screen.getByTestId('portal-content') + const content = screen.getByTestId('popover-content') expect(content)!.toBeInTheDocument() }) @@ -1659,10 +1661,10 @@ describe('MethodSelector', () => { // Act render() - await user.click(screen.getByTestId('portal-trigger')) + await user.click(screen.getByTestId('popover-trigger')) // Assert - const content = screen.getByTestId('portal-content') + const content = screen.getByTestId('popover-content') expect(content)!.toBeInTheDocument() }) }) diff --git a/web/app/components/tools/workflow-tool/__tests__/index.spec.tsx b/web/app/components/tools/workflow-tool/__tests__/index.spec.tsx index 2ec289fcf6..9f5532f1f7 100644 --- a/web/app/components/tools/workflow-tool/__tests__/index.spec.tsx +++ b/web/app/components/tools/workflow-tool/__tests__/index.spec.tsx @@ -18,11 +18,10 @@ vi.mock('@/app/components/base/drawer-plus', () => ({ ), })) -vi.mock('@/app/components/base/emoji-picker', () => ({ - default: ({ onSelect, onClose }: { onSelect: (icon: string, background: string) => void, onClose: () => void }) => ( +vi.mock('@/app/components/base/emoji-picker/Inner', () => ({ + default: ({ onSelect }: { onSelect: (icon: string, background: string) => void }) => (
-
), })) @@ -129,6 +128,7 @@ describe('WorkflowToolAsModal', () => { await user.click(screen.getByTestId('append-label')) await user.click(screen.getByTestId('app-icon')) await user.click(screen.getByTestId('select-emoji')) + await user.click(screen.getByRole('button', { name: 'app.iconPicker.ok' })) await user.click(screen.getByRole('button', { name: 'common.operation.save' })) expect(onCreate).toHaveBeenCalledWith(expect.objectContaining({ @@ -195,6 +195,6 @@ describe('WorkflowToolAsModal', () => { />, ) - expect(screen.getAllByText('tools.createTool.toolOutput.reservedParameterDuplicateTip').length).toBeGreaterThan(0) + expect(screen.getAllByTestId('reserved-output-warning').length).toBeGreaterThan(0) }) }) diff --git a/web/app/components/tools/workflow-tool/__tests__/method-selector.spec.tsx b/web/app/components/tools/workflow-tool/__tests__/method-selector.spec.tsx index 4379bec035..4a0574f61b 100644 --- a/web/app/components/tools/workflow-tool/__tests__/method-selector.spec.tsx +++ b/web/app/components/tools/workflow-tool/__tests__/method-selector.spec.tsx @@ -4,6 +4,8 @@ import userEvent from '@testing-library/user-event' import { beforeEach, describe, expect, it, vi } from 'vitest' import MethodSelector from '../method-selector' +vi.mock('@langgenius/dify-ui/popover', () => import('@/__mocks__/base-ui-popover')) + // Test utilities const defaultProps: ComponentProps = { value: 'llm', @@ -137,6 +139,24 @@ describe('MethodSelector', () => { expect(onChange).toHaveBeenCalledWith('form') }) + it('should close dropdown after an option is clicked', async () => { + const user = userEvent.setup() + renderComponent({ value: 'llm' }) + + const trigger = screen.getByText('tools.createTool.toolInput.methodParameter') + await user.click(trigger) + + await waitFor(() => { + expect(screen.getByText('tools.createTool.toolInput.methodSettingTip'))!.toBeInTheDocument() + }) + + await user.click(screen.getByText('tools.createTool.toolInput.methodSettingTip')) + + await waitFor(() => { + expect(screen.queryByText('tools.createTool.toolInput.methodSettingTip')).not.toBeInTheDocument() + }) + }) + it('should toggle dropdown open state', async () => { const user = userEvent.setup() renderComponent() @@ -232,10 +252,9 @@ describe('MethodSelector', () => { await user.click(trigger) await waitFor(() => { + expect(screen.getByTestId('popover-content')).toBeInTheDocument() const dropdown = document.querySelector('.w-\\[320px\\]') - expect(dropdown).toBeInTheDocument() - expect(dropdown).toHaveClass('rounded-lg') - expect(dropdown).toHaveClass('shadow-lg') + expect(dropdown)!.toBeInTheDocument() }) }) diff --git a/web/app/components/tools/workflow-tool/confirm-modal/__tests__/index.spec.tsx b/web/app/components/tools/workflow-tool/confirm-modal/__tests__/index.spec.tsx index c5bce8b663..6535564a32 100644 --- a/web/app/components/tools/workflow-tool/confirm-modal/__tests__/index.spec.tsx +++ b/web/app/components/tools/workflow-tool/confirm-modal/__tests__/index.spec.tsx @@ -93,13 +93,12 @@ describe('ConfirmModal', () => { // Arrange & Act renderComponent() - // Assert - Check for the dialog panel with modal content - // The real modal structure has nested divs, we need to find the one with our classes - const dialogContent = document.querySelector('.relative.rounded-2xl') + // Assert + const dialogContent = screen.getByRole('dialog') expect(dialogContent).toBeInTheDocument() - expect(dialogContent).toHaveClass('w-[600px]') - expect(dialogContent).toHaveClass('max-w-[600px]') - expect(dialogContent).toHaveClass('p-8') + expect(dialogContent).toHaveClass('w-[600px]!') + expect(dialogContent).toHaveClass('max-w-[600px]!') + expect(dialogContent).toHaveClass('p-8!') }) }) diff --git a/web/app/components/tools/workflow-tool/confirm-modal/index.tsx b/web/app/components/tools/workflow-tool/confirm-modal/index.tsx index ba45387731..4f17862c1a 100644 --- a/web/app/components/tools/workflow-tool/confirm-modal/index.tsx +++ b/web/app/components/tools/workflow-tool/confirm-modal/index.tsx @@ -2,11 +2,9 @@ import { Button } from '@langgenius/dify-ui/button' import { cn } from '@langgenius/dify-ui/cn' -import { RiCloseLine } from '@remixicon/react' -import { noop } from 'es-toolkit/function' +import { Dialog, DialogContent, DialogTitle } from '@langgenius/dify-ui/dialog' import { useTranslation } from 'react-i18next' import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback' -import Modal from '@/app/components/base/modal' type ConfirmModalProps = { show: boolean @@ -18,28 +16,29 @@ const ConfirmModal = ({ show, onConfirm, onClose }: ConfirmModalProps) => { const { t } = useTranslation() return ( - -
- -
-
- -
-
{t('createTool.confirmTitle', { ns: 'tools' })}
-
- {t('createTool.confirmTip', { ns: 'tools' })} -
-
-
- - + + +
+
-
- +
+ +
+ {t('createTool.confirmTitle', { ns: 'tools' })} +
+ {t('createTool.confirmTip', { ns: 'tools' })} +
+
+
+ + +
+
+ + ) } diff --git a/web/app/components/tools/workflow-tool/hooks/__tests__/use-configure-button.spec.ts b/web/app/components/tools/workflow-tool/hooks/__tests__/use-configure-button.spec.ts index efbf16d590..8bc3db95da 100644 --- a/web/app/components/tools/workflow-tool/hooks/__tests__/use-configure-button.spec.ts +++ b/web/app/components/tools/workflow-tool/hooks/__tests__/use-configure-button.spec.ts @@ -437,7 +437,6 @@ describe('useConfigureButton', () => { expect(onRefreshData).toHaveBeenCalled() expect(mockInvalidateAllWorkflowTools).toHaveBeenCalled() expect(mockInvalidateWorkflowToolDetailByAppID).toHaveBeenCalledWith('app-123') - expect(mockToastNotify).toHaveBeenCalledWith({ type: 'success', message: expect.any(String) }) expect(result.current.showModal).toBe(false) }) diff --git a/web/app/components/tools/workflow-tool/hooks/use-configure-button.ts b/web/app/components/tools/workflow-tool/hooks/use-configure-button.ts index 9f0a43635c..33965aa5ee 100644 --- a/web/app/components/tools/workflow-tool/hooks/use-configure-button.ts +++ b/web/app/components/tools/workflow-tool/hooks/use-configure-button.ts @@ -206,7 +206,6 @@ export function useConfigureButton(options: UseConfigureButtonOptions) { onRefreshData?.() invalidateAllWorkflowTools() invalidateDetail(workflowAppId) - toast.success(t('api.actionSuccess', { ns: 'common' })) setShowModal(false) } catch (e) { diff --git a/web/app/components/tools/workflow-tool/index.tsx b/web/app/components/tools/workflow-tool/index.tsx index 353e85beba..6f8258f185 100644 --- a/web/app/components/tools/workflow-tool/index.tsx +++ b/web/app/components/tools/workflow-tool/index.tsx @@ -3,18 +3,18 @@ import type { FC } from 'react' import type { Emoji, WorkflowToolProviderOutputParameter, WorkflowToolProviderOutputSchema, WorkflowToolProviderParameter, WorkflowToolProviderRequest } from '../types' import { Button } from '@langgenius/dify-ui/button' import { cn } from '@langgenius/dify-ui/cn' +import { Dialog, DialogContent, DialogTitle } from '@langgenius/dify-ui/dialog' import { toast } from '@langgenius/dify-ui/toast' -import { RiErrorWarningLine } from '@remixicon/react' +import { Tooltip, TooltipContent, TooltipTrigger } from '@langgenius/dify-ui/tooltip' import { produce } from 'immer' import * as React from 'react' import { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import AppIcon from '@/app/components/base/app-icon' -import Drawer from '@/app/components/base/drawer-plus' -import EmojiPicker from '@/app/components/base/emoji-picker' +import Divider from '@/app/components/base/divider' +import EmojiPickerInner from '@/app/components/base/emoji-picker/Inner' import Input from '@/app/components/base/input' import Textarea from '@/app/components/base/textarea' -import Tooltip from '@/app/components/base/tooltip' import LabelSelector from '@/app/components/tools/labels/selector' import ConfirmModal from '@/app/components/tools/workflow-tool/confirm-modal' import MethodSelector from '@/app/components/tools/workflow-tool/method-selector' @@ -53,6 +53,111 @@ type Props = { workflow_tool_id: string }>) => void } + +type WorkflowToolDrawerProps = { + title: string + onHide: () => void + children: React.ReactNode +} + +const InfoTooltip = ({ children }: { children: React.ReactNode }) => { + return ( + + + )} + /> + +
+ {children} +
+
+
+ ) +} + +const WorkflowToolDrawer = ({ title, onHide, children }: WorkflowToolDrawerProps) => { + return ( + + +
+
+
+ + {title} + + +
+
+
+ {children} +
+
+
+
+ ) +} + +type WorkflowToolEmojiPickerProps = { + onSelect: (icon: string, background: string) => void + onClose: () => void +} + +const WorkflowToolEmojiPicker = ({ onSelect, onClose }: WorkflowToolEmojiPickerProps) => { + const { t } = useTranslation() + const [selectedEmoji, setSelectedEmoji] = useState('') + const [selectedBackground, setSelectedBackground] = useState() + + return ( + + + + {t('iconPicker.emoji', { ns: 'app' })} + + { + setSelectedEmoji(emoji) + setSelectedBackground(background) + }} + /> + +
+ + +
+
+
+ ) +} + // Add and Edit const WorkflowToolAsModal: FC = ({ isAdd, @@ -138,210 +243,201 @@ const WorkflowToolAsModal: FC = ({ return ( <> - -
- {/* name & icon */} -
-
- {t('createTool.name', { ns: 'tools' })} - {' '} - * -
-
- { setShowEmojiPicker(true) }} className="cursor-pointer" iconType="emoji" icon={emoji.content} background={emoji.background} /> - setLabel(e.target.value)} - /> -
+ > +
+
+ {/* name & icon */} +
+
+ {t('createTool.name', { ns: 'tools' })} + {' '} + *
- {/* name for tool call */} -
-
- {t('createTool.nameForToolCall', { ns: 'tools' })} - {' '} - * - - {t('createTool.nameForToolCallPlaceHolder', { ns: 'tools' })} -
- )} - /> -
+
+ { setShowEmojiPicker(true) }} className="cursor-pointer" iconType="emoji" icon={emoji.content} background={emoji.background} /> setName(e.target.value)} - /> - {!isWorkflowToolNameValid(name) && ( -
{t('createTool.nameForToolCallTip', { ns: 'tools' })}
- )} -
- {/* description */} -
-
{t('createTool.description', { ns: 'tools' })}
-