From 3c23285b87abf2b8bc713862628a4018e369e0dc Mon Sep 17 00:00:00 2001 From: Hubert Zub Date: Fri, 20 Mar 2026 10:59:46 +0100 Subject: [PATCH 01/16] Agent plugin Move agent plugin source code into src/agent-plugin/ subfolder for better organization when hosting multiple plugins. --- .github/workflows/appkit-agent.yml | 131 + .github/workflows/release-appkit-agent.yml | 115 + .gitignore | 2 + integrations/appkit-agent/package.json | 108 + integrations/appkit-agent/pnpm-lock.yaml | 5355 +++++++++++++++++ .../src/agent-plugin/agent-interface.ts | 121 + .../appkit-agent/src/agent-plugin/agent.ts | 275 + .../src/agent-plugin/function-tool.ts | 142 + .../src/agent-plugin/hosted-tools.ts | 107 + .../src/agent-plugin/invoke-handler.ts | 160 + .../src/agent-plugin/manifest.json | 23 + .../src/agent-plugin/standard-agent.ts | 231 + .../appkit-agent/src/agent-plugin/types.ts | 41 + integrations/appkit-agent/src/index.ts | 23 + integrations/appkit-agent/src/logger.ts | 14 + .../src/tests/agent-plugin/agent.intg.test.ts | 298 + .../src/tests/agent-plugin/agent.test.ts | 195 + .../tests/agent-plugin/function-tool.test.ts | 260 + .../tests/agent-plugin/hosted-tools.test.ts | 197 + .../tests/agent-plugin/invoke-handler.test.ts | 322 + .../tests/agent-plugin/standard-agent.test.ts | 411 ++ .../src/tests/agent-plugin/stub-agent.ts | 71 + .../src/tests/agent-plugin/test-helpers.ts | 88 + integrations/appkit-agent/tsconfig.json | 29 + integrations/appkit-agent/tsdown.config.ts | 24 + integrations/appkit-agent/vitest.config.ts | 7 + 26 files changed, 8750 insertions(+) create mode 100644 .github/workflows/appkit-agent.yml create mode 100644 .github/workflows/release-appkit-agent.yml create mode 100644 integrations/appkit-agent/package.json create mode 100644 integrations/appkit-agent/pnpm-lock.yaml create mode 100644 integrations/appkit-agent/src/agent-plugin/agent-interface.ts create mode 100644 integrations/appkit-agent/src/agent-plugin/agent.ts create mode 100644 integrations/appkit-agent/src/agent-plugin/function-tool.ts create mode 100644 integrations/appkit-agent/src/agent-plugin/hosted-tools.ts create mode 100644 integrations/appkit-agent/src/agent-plugin/invoke-handler.ts create mode 100644 integrations/appkit-agent/src/agent-plugin/manifest.json create mode 100644 integrations/appkit-agent/src/agent-plugin/standard-agent.ts create mode 100644 integrations/appkit-agent/src/agent-plugin/types.ts create mode 100644 integrations/appkit-agent/src/index.ts create mode 100644 integrations/appkit-agent/src/logger.ts create mode 100644 integrations/appkit-agent/src/tests/agent-plugin/agent.intg.test.ts create mode 100644 integrations/appkit-agent/src/tests/agent-plugin/agent.test.ts create mode 100644 integrations/appkit-agent/src/tests/agent-plugin/function-tool.test.ts create mode 100644 integrations/appkit-agent/src/tests/agent-plugin/hosted-tools.test.ts create mode 100644 integrations/appkit-agent/src/tests/agent-plugin/invoke-handler.test.ts create mode 100644 integrations/appkit-agent/src/tests/agent-plugin/standard-agent.test.ts create mode 100644 integrations/appkit-agent/src/tests/agent-plugin/stub-agent.ts create mode 100644 integrations/appkit-agent/src/tests/agent-plugin/test-helpers.ts create mode 100644 integrations/appkit-agent/tsconfig.json create mode 100644 integrations/appkit-agent/tsdown.config.ts create mode 100644 integrations/appkit-agent/vitest.config.ts diff --git a/.github/workflows/appkit-agent.yml b/.github/workflows/appkit-agent.yml new file mode 100644 index 000000000..556a4afd1 --- /dev/null +++ b/.github/workflows/appkit-agent.yml @@ -0,0 +1,131 @@ +name: appkit-agent + +on: + push: + branches: + - main + paths: + - "integrations/appkit-agent/**" + - ".github/workflows/appkit-agent.yml" + pull_request: + types: + - opened + - synchronize + - reopened + - ready_for_review + paths: + - "integrations/appkit-agent/**" + - ".github/workflows/appkit-agent.yml" + workflow_dispatch: + +defaults: + run: + working-directory: integrations/appkit-agent + +jobs: + test: + runs-on: ubuntu-latest + name: "test (node: ${{ matrix.node-version }})" + strategy: + matrix: + node-version: ["20", "22"] + timeout-minutes: 10 + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: "pnpm" + cache-dependency-path: integrations/appkit-agent/pnpm-lock.yaml + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Run tests + run: pnpm run test + + typecheck: + runs-on: ubuntu-latest + name: typecheck + timeout-minutes: 10 + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "pnpm" + cache-dependency-path: integrations/appkit-agent/pnpm-lock.yaml + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Run typecheck + run: pnpm run typecheck + + format: + runs-on: ubuntu-latest + name: format + timeout-minutes: 10 + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "pnpm" + cache-dependency-path: integrations/appkit-agent/pnpm-lock.yaml + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Check formatting + run: pnpm run format:check + + build: + runs-on: ubuntu-latest + name: build + timeout-minutes: 10 + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "pnpm" + cache-dependency-path: integrations/appkit-agent/pnpm-lock.yaml + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build package + run: pnpm run build diff --git a/.github/workflows/release-appkit-agent.yml b/.github/workflows/release-appkit-agent.yml new file mode 100644 index 000000000..ea9b41a13 --- /dev/null +++ b/.github/workflows/release-appkit-agent.yml @@ -0,0 +1,115 @@ +name: Release @databricks/appkit-agent + +on: + workflow_dispatch: + inputs: + production: + description: "Publish to npm? (If unchecked, will publish with --tag next)" + required: true + default: false + type: boolean + +jobs: + release: + runs-on: ubuntu-latest + + permissions: + id-token: write + contents: write + environment: + name: ${{ inputs.production && 'npm' || 'npm-next' }} + url: https://www.npmjs.com/package/@databricks/appkit-agent + defaults: + run: + working-directory: integrations/appkit-agent + steps: + - uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - uses: actions/setup-node@v4 + with: + node-version: "20" + registry-url: "https://registry.npmjs.org" + cache: "pnpm" + cache-dependency-path: integrations/appkit-agent/pnpm-lock.yaml + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Get package version + id: get-version + run: | + PKG_VERSION=$(node -p "require('./package.json').version") + echo "version=$PKG_VERSION" >> $GITHUB_OUTPUT + + - name: Clean + run: pnpm run clean + + - name: Build + run: pnpm run build + + - name: Test + run: pnpm run test + + - name: Typecheck + run: pnpm run typecheck + + - name: Publish to npm + if: inputs.production + run: pnpm publish --access public --provenance --no-git-checks + + - name: Publish to npm (next tag) + if: ${{ !inputs.production }} + run: pnpm publish --access public --tag next --provenance --no-git-checks + + - name: Wait for registry propagation + run: sleep 15 + + - name: Smoke test (production) + if: inputs.production + run: | + PKG_VERSION=${{ steps.get-version.outputs.version }} + mkdir -p /tmp/smoke-test + cd /tmp/smoke-test + npm install @databricks/appkit-agent@$PKG_VERSION + INSTALLED_VERSION=$(node -p "require('./node_modules/@databricks/appkit-agent/package.json').version") + echo "Expected: $PKG_VERSION" + echo "Installed: $INSTALLED_VERSION" + if [ "$PKG_VERSION" != "$INSTALLED_VERSION" ]; then + echo "Version mismatch!" + exit 1 + fi + echo "Smoke test passed!" + + - name: Smoke test (next tag) + if: ${{ !inputs.production }} + run: | + mkdir -p /tmp/smoke-test + cd /tmp/smoke-test + npm install @databricks/appkit-agent@next + INSTALLED_VERSION=$(node -p "require('./node_modules/@databricks/appkit-agent/package.json').version") + echo "Installed @next version: $INSTALLED_VERSION" + echo "Smoke test passed!" + + - name: Generate package link + run: | + PKG_VERSION=${{ steps.get-version.outputs.version }} + if [ "${{ inputs.production }}" == "true" ]; then + LINK="https://www.npmjs.com/package/@databricks/appkit-agent/v/$PKG_VERSION" + echo "## :rocket: Package Released" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**@databricks/appkit-agent v$PKG_VERSION** has been published to npm!" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo ":link: [$LINK]($LINK)" >> $GITHUB_STEP_SUMMARY + else + LINK="https://www.npmjs.com/package/@databricks/appkit-agent?activeTab=versions" + echo "## :test_tube: Package Released (next tag)" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**@databricks/appkit-agent v$PKG_VERSION** has been published to npm with --tag next!" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo ":link: [$LINK]($LINK)" >> $GITHUB_STEP_SUMMARY + fi diff --git a/.gitignore b/.gitignore index 0794ac439..1f648e196 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ Pipfile docs/build **/uv.lock + +node_modules/ diff --git a/integrations/appkit-agent/package.json b/integrations/appkit-agent/package.json new file mode 100644 index 000000000..7924db820 --- /dev/null +++ b/integrations/appkit-agent/package.json @@ -0,0 +1,108 @@ +{ + "name": "@databricks/appkit-agent", + "version": "0.1.0", + "description": "Agent plugin for Databricks AppKit — LangGraph AI agent with streaming Responses API and MCP tool support", + "type": "module", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.cts", + "exports": { + ".": { + "import": { + "types": "./dist/index.d.mts", + "default": "./dist/index.mjs" + }, + "require": { + "types": "./dist/index.d.cts", + "default": "./dist/index.cjs" + } + } + }, + "files": [ + "dist", + "README.md", + "LICENSE", + "NOTICE" + ], + "scripts": { + "build": "tsdown", + "dev": "tsdown --watch", + "clean": "rm -rf dist", + "test": "vitest run", + "test:watch": "vitest", + "typecheck": "tsc --noEmit", + "lint": "eslint 'src/**/*.ts'", + "format": "prettier --write 'src/**/*.ts'", + "format:check": "prettier --check 'src/**/*.ts'" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@databricks/appkit": ">=0.21.0", + "@databricks/langchainjs": ">=0.1.0", + "@langchain/core": ">=1.0.0", + "@langchain/langgraph": ">=1.0.0", + "@langchain/mcp-adapters": ">=1.0.0", + "express": ">=4.0.0" + }, + "peerDependenciesMeta": { + "@databricks/langchainjs": { + "optional": true + }, + "@langchain/core": { + "optional": true + }, + "@langchain/langgraph": { + "optional": true + }, + "@langchain/mcp-adapters": { + "optional": true + } + }, + "dependencies": { + "zod": "^4.3.5" + }, + "devDependencies": { + "@databricks/appkit": "^0.21.0", + "@langchain/core": "^1.1.8", + "@types/express": "^4.17.25", + "@types/node": "^22.0.0", + "prettier": "^3.0.0", + "tsdown": "^0.9.0", + "typescript": "^5.4.0", + "vitest": "^4.0.18" + }, + "author": { + "name": "Databricks", + "email": "agent-feedback@databricks.com" + }, + "repository": { + "type": "git", + "url": "https://github.com/databricks/databricks-ai-bridge.git", + "directory": "integrations/appkit-agent" + }, + "homepage": "https://github.com/databricks/databricks-ai-bridge/tree/main/integrations/appkit-agent", + "bugs": { + "url": "https://github.com/databricks/databricks-ai-bridge/issues" + }, + "keywords": [ + "databricks", + "appkit", + "agent", + "ai", + "langchain", + "langgraph", + "mcp", + "llm" + ], + "license": "Databricks License", + "pnpm": { + "onlyBuiltDependencies": [ + "@databricks/appkit", + "esbuild", + "protobufjs", + "rolldown" + ] + } +} diff --git a/integrations/appkit-agent/pnpm-lock.yaml b/integrations/appkit-agent/pnpm-lock.yaml new file mode 100644 index 000000000..d297f78e0 --- /dev/null +++ b/integrations/appkit-agent/pnpm-lock.yaml @@ -0,0 +1,5355 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@databricks/langchainjs': + specifier: '>=0.1.0' + version: 0.1.0(@cfworker/json-schema@4.1.1)(@langchain/langgraph@1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0) + '@langchain/langgraph': + specifier: '>=1.0.0' + version: 1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) + '@langchain/mcp-adapters': + specifier: '>=1.0.0' + version: 1.1.3(@cfworker/json-schema@4.1.1)(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(@langchain/langgraph@1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6)) + express: + specifier: '>=4.0.0' + version: 5.2.1 + zod: + specifier: ^4.3.5 + version: 4.3.6 + devDependencies: + '@databricks/appkit': + specifier: ^0.21.0 + version: 0.21.0(@opentelemetry/core@2.6.0(@opentelemetry/api@1.9.0))(@types/node@22.19.15)(jiti@2.6.1) + '@langchain/core': + specifier: ^1.1.8 + version: 1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0) + '@types/express': + specifier: ^4.17.25 + version: 4.17.25 + '@types/node': + specifier: ^22.0.0 + version: 22.19.15 + prettier: + specifier: ^3.0.0 + version: 3.8.1 + tsdown: + specifier: ^0.9.0 + version: 0.9.9(typescript@5.9.3) + typescript: + specifier: ^5.4.0 + version: 5.9.3 + vitest: + specifier: ^4.0.18 + version: 4.1.0(@opentelemetry/api@1.9.0)(@types/node@22.19.15)(vite@8.0.1(@types/node@22.19.15)(jiti@2.6.1)) + +packages: + + '@ai-sdk/gateway@3.0.66': + resolution: {integrity: sha512-SIQ0YY0iMuv+07HLsZ+bB990zUJ6S4ujORAh+Jv1V2KGNn73qQKnGO0JBk+w+Res8YqOFSycwDoWcFlQrVxS4A==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider-utils@4.0.19': + resolution: {integrity: sha512-3eG55CrSWCu2SXlqq2QCsFjo3+E7+Gmg7i/oRVoSZzIodTuDSfLb3MRje67xE9RFea73Zao7Lm4mADIfUETKGg==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider@3.0.8': + resolution: {integrity: sha512-oGMAgGoQdBXbZqNG0Ze56CHjDZ1IDYOwGYxYjO5KLSlz5HiNQ9udIXsPZ61VWaHGZ5XW/jyjmr6t2xz2jGVwbQ==} + engines: {node: '>=18'} + + '@ast-grep/napi-darwin-arm64@0.37.0': + resolution: {integrity: sha512-QAiIiaAbLvMEg/yBbyKn+p1gX2/FuaC0SMf7D7capm/oG4xGMzdeaQIcSosF4TCxxV+hIH4Bz9e4/u7w6Bnk3Q==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@ast-grep/napi-darwin-x64@0.37.0': + resolution: {integrity: sha512-zvcvdgekd4ySV3zUbUp8HF5nk5zqwiMXTuVzTUdl/w08O7JjM6XPOIVT+d2o/MqwM9rsXdzdergY5oY2RdhSPA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@ast-grep/napi-linux-arm64-gnu@0.37.0': + resolution: {integrity: sha512-L7Sj0lXy8X+BqSMgr1LB8cCoWk0rericdeu+dC8/c8zpsav5Oo2IQKY1PmiZ7H8IHoFBbURLf8iklY9wsD+cyA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@ast-grep/napi-linux-arm64-musl@0.37.0': + resolution: {integrity: sha512-LF9sAvYy6es/OdyJDO3RwkX3I82Vkfsng1sqUBcoWC1jVb1wX5YVzHtpQox9JrEhGl+bNp7FYxB4Qba9OdA5GA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@ast-grep/napi-linux-x64-gnu@0.37.0': + resolution: {integrity: sha512-TViz5/klqre6aSmJzswEIjApnGjJzstG/SE8VDWsrftMBMYt2PTu3MeluZVwzSqDao8doT/P+6U11dU05UOgxw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@ast-grep/napi-linux-x64-musl@0.37.0': + resolution: {integrity: sha512-/BcCH33S9E3ovOAEoxYngUNXgb+JLg991sdyiNP2bSoYd30a9RHrG7CYwW6fMgua3ijQ474eV6cq9yZO1bCpXg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@ast-grep/napi-win32-arm64-msvc@0.37.0': + resolution: {integrity: sha512-TjQA4cFoIEW2bgjLkaL9yqT4XWuuLa5MCNd0VCDhGRDMNQ9+rhwi9eLOWRaap3xzT7g+nlbcEHL3AkVCD2+b3A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@ast-grep/napi-win32-ia32-msvc@0.37.0': + resolution: {integrity: sha512-uNmVka8fJCdYsyOlF9aZqQMLTatEYBynjChVTzUfFMDfmZ0bihs/YTqJVbkSm8TZM7CUX82apvn50z/dX5iWRA==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@ast-grep/napi-win32-x64-msvc@0.37.0': + resolution: {integrity: sha512-vCiFOT3hSCQuHHfZ933GAwnPzmL0G04JxQEsBRfqONywyT8bSdDc/ECpAfr3S9VcS4JZ9/F6tkePKW/Om2Dq2g==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@ast-grep/napi@0.37.0': + resolution: {integrity: sha512-Hb4o6h1Pf6yRUAX07DR4JVY7dmQw+RVQMW5/m55GoiAT/VRoKCWBtIUPPOnqDVhbx1Cjfil9b6EDrgJsUAujEQ==} + engines: {node: '>= 10'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + + '@cfworker/json-schema@4.1.1': + resolution: {integrity: sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og==} + + '@clack/core@1.1.0': + resolution: {integrity: sha512-SVcm4Dqm2ukn64/8Gub2wnlA5nS2iWJyCkdNHcvNHPIeBTGojpdJ+9cZKwLfmqy7irD4N5qLteSilJlE0WLAtA==} + + '@clack/prompts@1.1.0': + resolution: {integrity: sha512-pkqbPGtohJAvm4Dphs2M8xE29ggupihHdy1x84HNojZuMtFsHiUlRvqD24tM2+XmI+61LlfNceM3Wr7U5QES5g==} + + '@databricks/ai-sdk-provider@0.3.0': + resolution: {integrity: sha512-KKSeF/vvTeN/YEIzbpPl0tC0uWqXbCU3bjzAlX90aIUdyLjhD+8PviEXuh2g7YYpsDsBdWClu33Z7K+ooudfCA==} + engines: {node: '>=18.0.0'} + peerDependencies: + '@ai-sdk/provider': ^3.0.5 + '@ai-sdk/provider-utils': ^4.0.10 + + '@databricks/appkit@0.21.0': + resolution: {integrity: sha512-F6+P5mSxFsE5YbKwmcDbyphGkMTgHDtN4+JJYkhJqHFAEU2slEagkM0bDbGJ8LNZBO1TX1DjhFpDNKdkaaKIlA==} + hasBin: true + + '@databricks/lakebase@0.2.0': + resolution: {integrity: sha512-dlLav/bLEbfpqdazcStbPk/8VYocXU/6KGyFhYsuNeUYbl8txrmEdSUB81N5D/kz41xEwuGkngu5BIUj1zcHZQ==} + + '@databricks/langchainjs@0.1.0': + resolution: {integrity: sha512-pCAsmoqBxoBOrHP9pxAxWj+jNbqqaD2WfYtnk61xpBpCbgfak1NA5MOZrc56TokidT8kam/f2RNKlFHjsok9aA==} + engines: {node: '>=18.0.0'} + + '@databricks/sdk-experimental@0.15.0': + resolution: {integrity: sha512-HkoMiF7dNDt6WRW0xhi7oPlBJQfxJ9suJhEZRFt08VwLMaWcw2PiF8monfHlkD4lkufEYV6CTxi5njQkciqiHA==} + engines: {node: '>=22.0', npm: '>=10.0.0'} + + '@databricks/sdk-experimental@0.16.0': + resolution: {integrity: sha512-9c2RxWYoRDFupdt4ZnBc1IPE1XaXgN+/wyV4DVcEqOnIa31ep51OnwAD/3014BImfKdyXg32nmgrB9dwvB6+lg==} + engines: {node: '>=22.0', npm: '>=10.0.0'} + + '@emnapi/core@1.9.1': + resolution: {integrity: sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==} + + '@emnapi/runtime@1.9.1': + resolution: {integrity: sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==} + + '@emnapi/wasi-threads@1.2.0': + resolution: {integrity: sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==} + + '@grpc/grpc-js@1.14.3': + resolution: {integrity: sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==} + engines: {node: '>=12.10.0'} + + '@grpc/proto-loader@0.8.0': + resolution: {integrity: sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==} + engines: {node: '>=6'} + hasBin: true + + '@hono/node-server@1.19.11': + resolution: {integrity: sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@js-sdsl/ordered-map@4.4.2': + resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} + + '@langchain/core@1.1.34': + resolution: {integrity: sha512-IDlZES5Vexo5meLQRCGkAU7NM0tPGPfPP5wcUzBd7Ot+JoFBmSXutC4gGzvZod5AKRVn3I0Qy5k8vkTraY21jA==} + engines: {node: '>=20'} + + '@langchain/langgraph-checkpoint@1.0.1': + resolution: {integrity: sha512-HM0cJLRpIsSlWBQ/xuDC67l52SqZ62Bh2Y61DX+Xorqwoh5e1KxYvfCD7GnSTbWWhjBOutvnR0vPhu4orFkZfw==} + engines: {node: '>=18'} + peerDependencies: + '@langchain/core': ^1.0.1 + + '@langchain/langgraph-sdk@1.7.5': + resolution: {integrity: sha512-j6MjD5btOfVSj2nVKVTu28YPHA9vzBuDbOFnzzfa5q4F6Tbt2Dwg+EiGhJptUz/3XKmU0OKp/3gCWk0ZTHHD1Q==} + peerDependencies: + '@langchain/core': ^1.1.16 + react: ^18 || ^19 + react-dom: ^18 || ^19 + svelte: ^4.0.0 || ^5.0.0 + vue: ^3.0.0 + peerDependenciesMeta: + '@langchain/core': + optional: true + react: + optional: true + react-dom: + optional: true + svelte: + optional: true + vue: + optional: true + + '@langchain/langgraph@1.2.4': + resolution: {integrity: sha512-opUmulmIkQFwFP/JpsXl8K7vqfzeNjuZObeQ1ASu4ZjUcQdyaY1Vm11g9fxH/pXJFeIWy+6BLVJcLUxQ1DRhcA==} + engines: {node: '>=18'} + peerDependencies: + '@langchain/core': ^1.1.16 + zod: ^3.25.32 || ^4.2.0 + zod-to-json-schema: ^3.x + peerDependenciesMeta: + zod-to-json-schema: + optional: true + + '@langchain/mcp-adapters@1.1.3': + resolution: {integrity: sha512-OPHIQNkTUJjnRj1pr+cp2nguMBZeF3Q1pVT1hCbgU7BrHgV7lov99wbU8po8Cm4zZzmeRtVO/T9X1SrDD1ogtQ==} + engines: {node: '>=20.10.0'} + peerDependencies: + '@langchain/core': ^1.0.0 + '@langchain/langgraph': ^1.0.0 + + '@modelcontextprotocol/sdk@1.27.1': + resolution: {integrity: sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==} + engines: {node: '>=18'} + peerDependencies: + '@cfworker/json-schema': ^4.1.1 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + '@cfworker/json-schema': + optional: true + + '@napi-rs/wasm-runtime@0.2.12': + resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + + '@napi-rs/wasm-runtime@1.1.1': + resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} + + '@opentelemetry/api-logs@0.208.0': + resolution: {integrity: sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg==} + engines: {node: '>=8.0.0'} + + '@opentelemetry/api@1.9.0': + resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} + engines: {node: '>=8.0.0'} + + '@opentelemetry/auto-instrumentations-node@0.67.3': + resolution: {integrity: sha512-sRzw/T1JU7CCATGxnnKhHbWMlwMH1qO62+4/znfsJTg24ATP5qNKFkt8B/JD7HAQ/0ceMeyQin9KOBnjkLkCvA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.4.1 + '@opentelemetry/core': ^2.0.0 + + '@opentelemetry/context-async-hooks@2.2.0': + resolution: {integrity: sha512-qRkLWiUEZNAmYapZ7KGS5C4OmBLcP/H2foXeOEaowYCR0wi89fHejrfYfbuLVCMLp/dWZXKvQusdbUEZjERfwQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/core@2.2.0': + resolution: {integrity: sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/core@2.6.0': + resolution: {integrity: sha512-HLM1v2cbZ4TgYN6KEOj+Bbj8rAKriOdkF9Ed3tG25FoprSiQl7kYc+RRT6fUZGOvx0oMi5U67GoFdT+XUn8zEg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/exporter-logs-otlp-grpc@0.208.0': + resolution: {integrity: sha512-AmZDKFzbq/idME/yq68M155CJW1y056MNBekH9OZewiZKaqgwYN4VYfn3mXVPftYsfrCM2r4V6tS8H2LmfiDCg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-logs-otlp-http@0.208.0': + resolution: {integrity: sha512-jOv40Bs9jy9bZVLo/i8FwUiuCvbjWDI+ZW13wimJm4LjnlwJxGgB+N/VWOZUTpM+ah/awXeQqKdNlpLf2EjvYg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-logs-otlp-proto@0.208.0': + resolution: {integrity: sha512-Wy8dZm16AOfM7yddEzSFzutHZDZ6HspKUODSUJVjyhnZFMBojWDjSNgduyCMlw6qaxJYz0dlb0OEcb4Eme+BfQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-metrics-otlp-grpc@0.208.0': + resolution: {integrity: sha512-YbEnk7jjYmvhIwp2xJGkEvdgnayrA2QSr28R1LR1klDPvCxsoQPxE6TokDbQpoCEhD3+KmJVEXfb4EeEQxjymg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-metrics-otlp-http@0.208.0': + resolution: {integrity: sha512-QZ3TrI90Y0i1ezWQdvreryjY0a5TK4J9gyDLIyhLBwV+EQUvyp5wR7TFPKCAexD4TDSWM0t3ulQDbYYjVtzTyA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-metrics-otlp-proto@0.208.0': + resolution: {integrity: sha512-CvvVD5kRDmRB/uSMalvEF6kiamY02pB46YAqclHtfjJccNZFxbkkXkMMmcJ7NgBFa5THmQBNVQ2AHyX29nRxOw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-prometheus@0.208.0': + resolution: {integrity: sha512-Rgws8GfIfq2iNWCD3G1dTD9xwYsCof1+tc5S5X0Ahdb5CrAPE+k5P70XCWHqrFFurVCcKaHLJ/6DjIBHWVfLiw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-trace-otlp-grpc@0.208.0': + resolution: {integrity: sha512-E/eNdcqVUTAT7BC+e8VOw/krqb+5rjzYkztMZ/o+eyJl+iEY6PfczPXpwWuICwvsm0SIhBoh9hmYED5Vh5RwIw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-trace-otlp-http@0.208.0': + resolution: {integrity: sha512-jbzDw1q+BkwKFq9yxhjAJ9rjKldbt5AgIy1gmEIJjEV/WRxQ3B6HcLVkwbjJ3RcMif86BDNKR846KJ0tY0aOJA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-trace-otlp-proto@0.208.0': + resolution: {integrity: sha512-q844Jc3ApkZVdWYd5OAl+an3n1XXf3RWHa3Zgmnhw3HpsM3VluEKHckUUEqHPzbwDUx2lhPRVkqK7LsJ/CbDzA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-zipkin@2.2.0': + resolution: {integrity: sha512-VV4QzhGCT7cWrGasBWxelBjqbNBbyHicWWS/66KoZoe9BzYwFB72SH2/kkc4uAviQlO8iwv2okIJy+/jqqEHTg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/instrumentation-amqplib@0.56.0': + resolution: {integrity: sha512-/orV2zO2K7iGa1TR6lbs170LNNDbeTC6E3JF1EeB+okJ3rB5tl1gHFSjoqEDkQYFprNs5CPitqU8Y4l4S2Pkmg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-aws-lambda@0.61.1': + resolution: {integrity: sha512-leISmqN7/KSCYAKEVOAnQ0NUCa3rigB7ShCVLnYrHr6+7CXPef7C+nvowElMcYTid8egiHKgApR/FaNdlBda3A==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-aws-sdk@0.64.1': + resolution: {integrity: sha512-A8joPAuHwvwrkG5UpH7OYhzkeYznNBiG3o1TKoZ7yvyXU/q4CNxnZ7vzZBEpt9OocptCe6X/YyBENFSa0axqiw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-bunyan@0.54.0': + resolution: {integrity: sha512-DnPoHSLcKwQmueW+7OOaXFD/cj1M6hqwTm6P88QdMbln/dqEatLxzt/ACPk4Yb5x4aU3ZLyeLyKxtzfhp76+aw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-cassandra-driver@0.54.1': + resolution: {integrity: sha512-wVGI4YrWmaNNtNjg84KTl8sHebG7jm3PHvmZxPl2V/aSskAyQMSxgJZpnv1dmBmJuISc+a8H8daporljbscCcQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-connect@0.52.0': + resolution: {integrity: sha512-GXPxfNB5szMbV3I9b7kNWSmQBoBzw7MT0ui6iU/p+NIzVx3a06Ri2cdQO7tG9EKb4aKSLmfX9Cw5cKxXqX6Ohg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-cucumber@0.24.0': + resolution: {integrity: sha512-ICHrmax9PwU/Z+fehD0uIjM8W0cEvdToglV1+o76Mgw51HZBVp2Y3mkga1qMPIN5tPMoWUYoYtI4U85rea5HYg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/instrumentation-dataloader@0.26.1': + resolution: {integrity: sha512-S2JAM6lV16tMravuPLd3tJCC6ySb5a//5KgJeXutbTVb/UbSTXcnHSdEtMaAvE2KbazVWyWzcoytLRy6AUOwsw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-dns@0.52.0': + resolution: {integrity: sha512-XJvS8PkZec+X6HhOi1xldJydTpmIUAW14+1vyqwAK97LWKXlxmiWst8/fjZ709+CHgshz8i5V37yCHlr6o3pxw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-express@0.57.1': + resolution: {integrity: sha512-r+ulPbvgG8rGgFFWbJWJpTh7nMzsEYH7rBFNWdFs7ZfVAtgpFijMkRtU7DecIo6ItF8Op+RxogSuk/083W8HKw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-fastify@0.53.1': + resolution: {integrity: sha512-tTa84J9rcrl4iTHdJDwirrNbM4prgJH+MF0iMlVLu++6gZg8TTfmYYqDiKPWBgdXB4M+bnlCkvgag36uV34uwA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-fs@0.28.0': + resolution: {integrity: sha512-FFvg8fq53RRXVBRHZViP+EMxMR03tqzEGpuq55lHNbVPyFklSVfQBN50syPhK5UYYwaStx0eyCtHtbRreusc5g==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-generic-pool@0.52.0': + resolution: {integrity: sha512-ISkNcv5CM2IwvsMVL31Tl61/p2Zm2I2NAsYq5SSBgOsOndT0TjnptjufYVScCnD5ZLD1tpl4T3GEYULLYOdIdQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-graphql@0.56.0': + resolution: {integrity: sha512-IPvNk8AFoVzTAM0Z399t34VDmGDgwT6rIqCUug8P9oAGerl2/PEIYMPOl/rerPGu+q8gSWdmbFSjgg7PDVRd3Q==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-grpc@0.208.0': + resolution: {integrity: sha512-8hFEQRAiOyIWO6LYj7tUfdAgNCuQUdYjLYMItRYlOLGJhshGdGYD7aeNzt2H+HPMDEWnKWqldIHfLTqM7ep7gg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-hapi@0.55.1': + resolution: {integrity: sha512-Pm1HCHnnijUOGXd+nyJp96CfU8Lb6XdT6H6YvvmXO/NHMb6tV+EjzDRBr9sZ/XQjka9zLCz7jR0js7ut0IJAyg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-http@0.208.0': + resolution: {integrity: sha512-rhmK46DRWEbQQB77RxmVXGyjs6783crXCnFjYQj+4tDH/Kpv9Rbg3h2kaNyp5Vz2emF1f9HOQQvZoHzwMWOFZQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-ioredis@0.57.0': + resolution: {integrity: sha512-o/PYGPbfFbS0Sq8EEQC8YUgDMiTGvwoMejPjV2d466yJoii+BUpffGejVQN0hC5V5/GT29m1B1jL+3yruNxwDw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-kafkajs@0.18.1': + resolution: {integrity: sha512-qM9hk7BIsVWqWJsrCa1fAEcEfutVvwhHO9kk4vpwaTGYR+lPWRk2r5+nEPcM+sIiYBmQNJCef5tEjQpKxTpP0A==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-knex@0.53.1': + resolution: {integrity: sha512-tIW3gqVC8d9CCE+oxPO63WNvC+5PKC/LrPrYWFobii5afUpHJV+0pfyt08okAFBHztzT0voMOEPGkLKoacZRXQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-koa@0.57.1': + resolution: {integrity: sha512-XPjdzgXvMG3YSZvsSgOj0Je0fsmlaBYIFFGJqUn1HRpbrVjdpP45eXI+6yUp48J8N5Qss32WDD5f+2tmV7Xvsg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.9.0 + + '@opentelemetry/instrumentation-lru-memoizer@0.53.1': + resolution: {integrity: sha512-L93bPJKFzrObD4FvKpsavYEFTzXFKMmAeRHz7J4lUFc7TPZLouxX3PYW1+YGr/bT1y24H9NLNX66l7BW1s75QA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-memcached@0.52.1': + resolution: {integrity: sha512-qg92SyWAypSZmX3Lhm2wz4BsovKarkWg9OHm4DPW6fGzmk40eB5voQIuctrBAfsml6gr+vbg4VEBcC1AKRvzzQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-mongodb@0.62.0': + resolution: {integrity: sha512-hcEEW26ToGVpQGblXk9m3p2cXkBu9j2bcyeevS/ahujr1WodfrItmMldWCEJkmN4+4uMo9pb6jAMhm6bZIMnig==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-mongoose@0.55.1': + resolution: {integrity: sha512-M2MusLn/31YOt176Y6qXJQcpDuZPmq/fqQ9vIaKb4x/qIJ3oYO2lT45SUMFmZpODEhrpYXgGaEKwG6TGXhlosA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-mysql2@0.55.1': + resolution: {integrity: sha512-/cw7TzEmeaCQ5xi+FwrCWQUlY8v9RXjN5tqtb0D1sgBedfiV6DvW+dlMl1jo6Nkx9eSHmGcDy9IjyR0frHpKLg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-mysql@0.55.0': + resolution: {integrity: sha512-tEGaVMzqAlwhoDomaUWOP2H4KkK16m18qq+TZoyvcSe9O21UxnYFWQa87a4kmc7N4Q6Q70L/YhwDt+fC+NDRBA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-nestjs-core@0.55.0': + resolution: {integrity: sha512-JFLNhbbEGnnQrMKOYoXx0nNk5N9cPeghu4xP/oup40a7VaSeYruyOiFbg9nkbS4ZQiI8aMuRqUT3Mo4lQjKEKg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-net@0.53.0': + resolution: {integrity: sha512-d8tU5z0fx28z622RwVwU4zfNt40EKxzEcQcaPzch/CqpkKNAlvBOW/1K9OkjNdydpsKqxpMkbjvo3tY6PD1EMA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-openai@0.7.1': + resolution: {integrity: sha512-QDnnAYxByJoJ3jMly/EwRbXhnfZpGigfBcHyPcgWEMR4bfawJZhdOdFi1GVcC4ImdS7fGaYQOTX1WW24mftISg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-oracledb@0.34.1': + resolution: {integrity: sha512-RI5EV3ZIkHA748dPm4hwLkUnqYU/rrBcq+qA5cNks0dZaAgsu46XMA/MEPcubrBSsgaG1NAIG78P9NLZs2gN/A==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-pg@0.61.2': + resolution: {integrity: sha512-l1tN4dX8Ig1bKzMu81Q1EBXWFRy9wqchXbeHDRniJsXYND5dC8u1Uhah7wz1zZta3fbBWflP2mJZcDPWNsAMRg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-pino@0.55.1': + resolution: {integrity: sha512-rt35H5vvP9KA1xrMrJGsnqwcVxyt8dher04pR64gvX4rxLwsmijUF1cEMbPZ2O8jXpeV8nAIzGHBnWEYp5ILNA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-redis@0.57.2': + resolution: {integrity: sha512-vD1nzOUDOPjnvDCny7fmRSX/hMTFzPUCZKADF5tQ5DvBqlOEV/de/tOkwvIwo9YX956EBMT+8qSjhd7qPXFkRw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-restify@0.54.0': + resolution: {integrity: sha512-V6kCoAtU8jLuUi9hr3IEWVTHr8d8s4wObV1DlI/A+VzYToK1W4Zv1SI8x3hiF0yR1poRjOY6rl91Q427HHTMww==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-router@0.53.0': + resolution: {integrity: sha512-3gF9jJ7C3lwlCOer1KzKKdpLr6/c7yOZBP44KI+Xi/TqiZjhsfUlHjetzC6BLDjkSk1DnIGyf+YzJR4aF5dJBQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-runtime-node@0.22.0': + resolution: {integrity: sha512-27aodhzdWqPuPVWM2UsLYz2gl6yLRqLP7Z6Kn6ukUx/I+9oruaztJkLtYg4SqCrm/7Nsv9FIly7gO3/ZyDIMPg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-socket.io@0.55.1': + resolution: {integrity: sha512-KQaOvZlw7NpA/VDRJdm45FIdzt4hXrDhvtmLU5a2AttcTI9e/VpVg4Y/LPOXM+o29VkKxETZzJfRlOJEIHl+uQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-tedious@0.28.0': + resolution: {integrity: sha512-nQ9k1Bdk2yG4SPRuHZ+QVcc3YMm2sfsBV1MQIc/Y/OcN83Q+jA7gXgYgYIblQ1wI+/RtKlJpdl6hobAXuj+pSA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation-undici@0.19.0': + resolution: {integrity: sha512-Pst/RhR61A2OoZQZkn6OLpdVpXp6qn3Y92wXa6umfJe9rV640r4bc6SWvw4pPN6DiQqPu2c8gnSSZPDtC6JlpQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.7.0 + + '@opentelemetry/instrumentation-winston@0.53.0': + resolution: {integrity: sha512-yF9v0DphyG715er1HG1pbweNUSygvc22xw2s2Y8E8oaEMJo2/nH3Ww/8c4K6gdI/6xvi2unla1KQBCYN4uCo8w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/instrumentation@0.208.0': + resolution: {integrity: sha512-Eju0L4qWcQS+oXxi6pgh7zvE2byogAkcsVv0OjHF/97iOz1N/aKE6etSGowYkie+YA1uo6DNwdSxaaNnLvcRlA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/otlp-exporter-base@0.208.0': + resolution: {integrity: sha512-gMd39gIfVb2OgxldxUtOwGJYSH8P1kVFFlJLuut32L6KgUC4gl1dMhn+YC2mGn0bDOiQYSk/uHOdSjuKp58vvA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/otlp-grpc-exporter-base@0.208.0': + resolution: {integrity: sha512-fGvAg3zb8fC0oJAzfz7PQppADI2HYB7TSt/XoCaBJFi1mSquNUjtHXEoviMgObLAa1NRIgOC1lsV1OUKi+9+lQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/otlp-transformer@0.208.0': + resolution: {integrity: sha512-DCFPY8C6lAQHUNkzcNT9R+qYExvsk6C5Bto2pbNxgicpcSWbe2WHShLxkOxIdNcBiYPdVHv/e7vH7K6TI+C+fQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/propagator-b3@2.2.0': + resolution: {integrity: sha512-9CrbTLFi5Ee4uepxg2qlpQIozoJuoAZU5sKMx0Mn7Oh+p7UrgCiEV6C02FOxxdYVRRFQVCinYR8Kf6eMSQsIsw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/propagator-jaeger@2.2.0': + resolution: {integrity: sha512-FfeOHOrdhiNzecoB1jZKp2fybqmqMPJUXe2ZOydP7QzmTPYcfPeuaclTLYVhK3HyJf71kt8sTl92nV4YIaLaKA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/redis-common@0.38.2': + resolution: {integrity: sha512-1BCcU93iwSRZvDAgwUxC/DV4T/406SkMfxGqu5ojc3AvNI+I9GhV7v0J1HljsczuuhcnFLYqD5VmwVXfCGHzxA==} + engines: {node: ^18.19.0 || >=20.6.0} + + '@opentelemetry/resource-detector-alibaba-cloud@0.32.0': + resolution: {integrity: sha512-W+n4ZIbNndOaW6xlGeW7afKQeCMNlOHsSflGRLkzjnSfAl2tWJU5Mhr6hf/t6m8uhic71psHx/CoFQMsRQKnvQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/resource-detector-aws@2.13.0': + resolution: {integrity: sha512-ZPCn7gZhGqUYUoD+RCHIlayoHBMaJaEjfqlgz2EPKoXJ4y7Ru7CUm+Tm3yJVMKF92cN9xUQR0j5KALyF0fg9aw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/resource-detector-azure@0.17.0': + resolution: {integrity: sha512-JGNPW+Om8MNiVOK1Jl5jg3znGJQP7YeGsgRQiegftqEZj0th8e1Uf6U5s6H672KBT442WDGOG0a4du5xJgJB5w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/resource-detector-container@0.8.4': + resolution: {integrity: sha512-kIvGHkMSacp+kb7btTuXbOAIWLyOCO+P/h/8xxaeLcp5ptmHRZ67uEdLAQo61ApdayFB/uqjJ9gY4x2/i/KsoA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/resource-detector-gcp@0.44.0': + resolution: {integrity: sha512-sj9WSSjMyZJDP7DSmfQpsfivM2sQECwhjAmK6V97uVAeJiXSMiPhfo3fZi0Hpu+GQQ1Wb09qQIkwkMjwr0MH/g==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/resources@2.2.0': + resolution: {integrity: sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + + '@opentelemetry/resources@2.6.0': + resolution: {integrity: sha512-D4y/+OGe3JSuYUCBxtH5T9DSAWNcvCb/nQWIga8HNtXTVPQn59j0nTBAgaAXxUVBDl40mG3Tc76b46wPlZaiJQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + + '@opentelemetry/sdk-logs@0.208.0': + resolution: {integrity: sha512-QlAyL1jRpOeaqx7/leG1vJMp84g0xKP6gJmfELBpnI4O/9xPX+Hu5m1POk9Kl+veNkyth5t19hRlN6tNY1sjbA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.4.0 <1.10.0' + + '@opentelemetry/sdk-metrics@2.2.0': + resolution: {integrity: sha512-G5KYP6+VJMZzpGipQw7Giif48h6SGQ2PFKEYCybeXJsOCB4fp8azqMAAzE5lnnHK3ZVwYQrgmFbsUJO/zOnwGw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.9.0 <1.10.0' + + '@opentelemetry/sdk-metrics@2.6.0': + resolution: {integrity: sha512-CicxWZxX6z35HR83jl+PLgtFgUrKRQ9LCXyxgenMnz5A1lgYWfAog7VtdOvGkJYyQgMNPhXQwkYrDLujk7z1Iw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.9.0 <1.10.0' + + '@opentelemetry/sdk-node@0.208.0': + resolution: {integrity: sha512-pbAqpZ7zTMFuTf3YecYsecsto/mheuvnK2a/jgstsE5ynWotBjgF5bnz5500W9Xl2LeUfg04WMt63TWtAgzRMw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + + '@opentelemetry/sdk-trace-base@2.2.0': + resolution: {integrity: sha512-xWQgL0Bmctsalg6PaXExmzdedSp3gyKV8mQBwK/j9VGdCDu2fmXIb2gAehBKbkXCpJ4HPkgv3QfoJWRT4dHWbw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + + '@opentelemetry/sdk-trace-base@2.6.0': + resolution: {integrity: sha512-g/OZVkqlxllgFM7qMKqbPV9c1DUPhQ7d4n3pgZFcrnrNft9eJXZM2TNHTPYREJBrtNdRytYyvwjgL5geDKl3EQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + + '@opentelemetry/sdk-trace-node@2.2.0': + resolution: {integrity: sha512-+OaRja3f0IqGG2kptVeYsrZQK9nKRSpfFrKtRBq4uh6nIB8bTBgaGvYQrQoRrQWQMA5dK5yLhDMDc0dvYvCOIQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/semantic-conventions@1.40.0': + resolution: {integrity: sha512-cifvXDhcqMwwTlTK04GBNeIe7yyo28Mfby85QXFe1Yk8nmi36Ab/5UQwptOx84SsoGNRg+EVSjwzfSZMy6pmlw==} + engines: {node: '>=14'} + + '@opentelemetry/sql-common@0.41.2': + resolution: {integrity: sha512-4mhWm3Z8z+i508zQJ7r6Xi7y4mmoJpdvH0fZPFRkWrdp5fq7hhZ2HhYokEOLkfqSMgPR4Z9EyB3DBkbKGOqZiQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.1.0 + + '@oxc-project/runtime@0.92.0': + resolution: {integrity: sha512-Z7x2dZOmznihvdvCvLKMl+nswtOSVxS2H2ocar+U9xx6iMfTp0VGIrX6a4xB1v80IwOPC7dT1LXIJrY70Xu3Jw==} + engines: {node: ^20.19.0 || >=22.12.0} + + '@oxc-project/types@0.120.0': + resolution: {integrity: sha512-k1YNu55DuvAip/MGE1FTsIuU3FUCn6v/ujG9V7Nq5Df/kX2CWb13hhwD0lmJGMGqE+bE1MXvv9SZVnMzEXlWcg==} + + '@oxc-project/types@0.66.0': + resolution: {integrity: sha512-KF5Wlo2KzQ+jmuCtrGISZoUfdHom7qHavNfPLW2KkeYJfYMGwtiia8KjwtsvNJ49qRiXImOCkPeVPd4bMlbR7w==} + + '@oxc-project/types@0.93.0': + resolution: {integrity: sha512-yNtwmWZIBtJsMr5TEfoZFDxIWV6OdScOpza/f5YxbqUMJk+j6QX3Cf3jgZShGEFYWQJ5j9mJ6jM0tZHu2J9Yrg==} + + '@oxc-resolver/binding-darwin-arm64@9.0.2': + resolution: {integrity: sha512-MVyRgP2gzJJtAowjG/cHN3VQXwNLWnY+FpOEsyvDepJki1SdAX/8XDijM1yN6ESD1kr9uhBKjGelC6h3qtT+rA==} + cpu: [arm64] + os: [darwin] + + '@oxc-resolver/binding-darwin-x64@9.0.2': + resolution: {integrity: sha512-7kV0EOFEZ3sk5Hjy4+bfA6XOQpCwbDiDkkHN4BHHyrBHsXxUR05EcEJPPL1WjItefg+9+8hrBmoK0xRoDs41+A==} + cpu: [x64] + os: [darwin] + + '@oxc-resolver/binding-freebsd-x64@9.0.2': + resolution: {integrity: sha512-6OvkEtRXrt8sJ4aVfxHRikjain9nV1clIsWtJ1J3J8NG1ZhjyJFgT00SCvqxbK+pzeWJq6XzHyTCN78ML+lY2w==} + cpu: [x64] + os: [freebsd] + + '@oxc-resolver/binding-linux-arm-gnueabihf@9.0.2': + resolution: {integrity: sha512-aYpNL6o5IRAUIdoweW21TyLt54Hy/ZS9tvzNzF6ya1ckOQ8DLaGVPjGpmzxdNja9j/bbV6aIzBH7lNcBtiOTkQ==} + cpu: [arm] + os: [linux] + + '@oxc-resolver/binding-linux-arm64-gnu@9.0.2': + resolution: {integrity: sha512-RGFW4vCfKMFEIzb9VCY0oWyyY9tR1/o+wDdNePhiUXZU4SVniRPQaZ1SJ0sUFI1k25pXZmzQmIP6cBmazi/Dew==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-arm64-musl@9.0.2': + resolution: {integrity: sha512-lxx/PibBfzqYvut2Y8N2D0Ritg9H8pKO+7NUSJb9YjR/bfk2KRmP8iaUz3zB0JhPtf/W3REs65oKpWxgflGToA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-linux-riscv64-gnu@9.0.2': + resolution: {integrity: sha512-yD28ptS/OuNhwkpXRPNf+/FvrO7lwURLsEbRVcL1kIE0GxNJNMtKgIE4xQvtKDzkhk6ZRpLho5VSrkkF+3ARTQ==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-s390x-gnu@9.0.2': + resolution: {integrity: sha512-WBwEJdspoga2w+aly6JVZeHnxuPVuztw3fPfWrei2P6rNM5hcKxBGWKKT6zO1fPMCB4sdDkFohGKkMHVV1eryQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-x64-gnu@9.0.2': + resolution: {integrity: sha512-a2z3/cbOOTUq0UTBG8f3EO/usFcdwwXnCejfXv42HmV/G8GjrT4fp5+5mVDoMByH3Ce3iVPxj1LmS6OvItKMYQ==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-x64-musl@9.0.2': + resolution: {integrity: sha512-bHZF+WShYQWpuswB9fyxcgMIWVk4sZQT0wnwpnZgQuvGTZLkYJ1JTCXJMtaX5mIFHf69ngvawnwPIUA4Feil0g==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-wasm32-wasi@9.0.2': + resolution: {integrity: sha512-I5cSgCCh5nFozGSHz+PjIOfrqW99eUszlxKLgoNNzQ1xQ2ou9ZJGzcZ94BHsM9SpyYHLtgHljmOZxCT9bgxYNA==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@oxc-resolver/binding-win32-arm64-msvc@9.0.2': + resolution: {integrity: sha512-5IhoOpPr38YWDWRCA5kP30xlUxbIJyLAEsAK7EMyUgqygBHEYLkElaKGgS0X5jRXUQ6l5yNxuW73caogb2FYaw==} + cpu: [arm64] + os: [win32] + + '@oxc-resolver/binding-win32-x64-msvc@9.0.2': + resolution: {integrity: sha512-Qc40GDkaad9rZksSQr2l/V9UubigIHsW69g94Gswc2sKYB3XfJXfIfyV8WTJ67u6ZMXsZ7BH1msSC6Aen75mCg==} + cpu: [x64] + os: [win32] + + '@oxc-transform/binding-darwin-arm64@0.67.0': + resolution: {integrity: sha512-P3zBMhpOQceNSys3/ZqvrjuRvcIbVzfGFN/tH34HlVkOjOmfGK1mOWjORsGAZtbgh1muXrF6mQETLzFjfYndXQ==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [darwin] + + '@oxc-transform/binding-darwin-x64@0.67.0': + resolution: {integrity: sha512-B52aeo/C3spYHcwFQ4nAbDkwbMKf0K6ncWM8GrVUgGu8PPECLBhjPCW11kPW/lt9FxwrdgVYVzPYlZ6wmJmpEA==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [darwin] + + '@oxc-transform/binding-linux-arm-gnueabihf@0.67.0': + resolution: {integrity: sha512-5Ir1eQrC9lvj/rR1TJVGwOR4yLgXTLmfKHIfpVH7GGSQrzK7VMUfHWX+dAsX1VutaeE8puXIqtYvf9cHLw78dw==} + engines: {node: '>=14.0.0'} + cpu: [arm] + os: [linux] + + '@oxc-transform/binding-linux-arm64-gnu@0.67.0': + resolution: {integrity: sha512-zTqfPET5+hZfJ3/dMqJboKxrpXMXk+j2HVdvX0wVhW2MI7n7hwELl+In6Yu20nXuEyJkNQlWHbNPCUfpM+cBWw==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-transform/binding-linux-arm64-musl@0.67.0': + resolution: {integrity: sha512-jzz/ATUhZ8wetb4gm5GwzheZns3Qj1CZ+DIMmD8nBxQXszmTS/fqnAPpgzruyLqkXBUuUfF3pHv5f/UmuHReuQ==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-transform/binding-linux-x64-gnu@0.67.0': + resolution: {integrity: sha512-Qy2+tfglJ8yX6guC1EDAnuuzRZIXciXO9UwOewxyiahLxwuTpj/wvvZN3Cb1SA3c14zrwb2TNMZvaXS1/OS5Pg==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-transform/binding-linux-x64-musl@0.67.0': + resolution: {integrity: sha512-tHoYgDIRhgvh+/wIrzAk3cUoj/LSSoJAdsZW9XRlaixFW/TF2puxRyaS1hRco0bcKTwotXl/eDYqZmhIfUyGRQ==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-transform/binding-wasm32-wasi@0.67.0': + resolution: {integrity: sha512-ZPT+1HECf7WUnotodIuS8tvSkwaiCdC2DDw8HVRmlerbS6iPYIPKyBCvkSM4RyUx0kljZtB9AciLCkEbwy5/zA==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@oxc-transform/binding-win32-arm64-msvc@0.67.0': + resolution: {integrity: sha512-+E3lOHCk4EuIk6IjshBAARknAUpgH+gHTtZxCPqK4AWYA+Tls2J6C0FVM48uZ4m3rZpAq8ZszM9JZVAkOaynBQ==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [win32] + + '@oxc-transform/binding-win32-x64-msvc@0.67.0': + resolution: {integrity: sha512-3pIIFb9g5aFrAODTQVJYitq+ONHgDJ4IYk/7pk+jsG6JpKUkURd0auUlxvriO11fFit5hdwy+wIbU4kBvyRUkg==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [win32] + + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.4': + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + + '@protobufjs/eventemitter@1.1.0': + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + + '@protobufjs/fetch@1.1.0': + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/inquire@1.1.0': + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.0': + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + + '@quansync/fs@1.0.0': + resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} + + '@rolldown/binding-android-arm64@1.0.0-beta.41': + resolution: {integrity: sha512-Edflndd9lU7JVhVIvJlZhdCj5DkhYDJPIRn4Dx0RUdfc8asP9xHOI5gMd8MesDDx+BJpdIT/uAmVTearteU/mQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-android-arm64@1.0.0-rc.10': + resolution: {integrity: sha512-jOHxwXhxmFKuXztiu1ORieJeTbx5vrTkcOkkkn2d35726+iwhrY1w/+nYY/AGgF12thg33qC3R1LMBF5tHTZHg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.0.0-beta.41': + resolution: {integrity: sha512-XGCzqfjdk7550PlyZRTBKbypXrB7ATtXhw/+bjtxnklLQs0mKP/XkQVOKyn9qGKSlvH8I56JLYryVxl0PCvSNw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-arm64@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-2F4bhDtV6CHBx7JMiT9xvmxkcZLHFmonfbli36RyfvgThDOAu92bis28zDTdguDY85lN/jBRKX/eOvX+T5hMkg==} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-arm64@1.0.0-rc.10': + resolution: {integrity: sha512-gED05Teg/vtTZbIJBc4VNMAxAFDUPkuO/rAIyyxZjTj1a1/s6z5TII/5yMGZ0uLRCifEtwUQn8OlYzuYc0m70w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.0-beta.41': + resolution: {integrity: sha512-Ho6lIwGJed98zub7n0xcRKuEtnZgbxevAmO4x3zn3C3N4GVXZD5xvCvTVxSMoeBJwTcIYzkVDRTIhylQNsTgLQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-8VMChhFLeD/oOAQUspFtxZaV7ctDob63w626kwvBBIHtlpY2Ohw4rsfjjtGckyrTCI/RROgZv/TVVEsG3GkgLw==} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.0-rc.10': + resolution: {integrity: sha512-rI15NcM1mA48lqrIxVkHfAqcyFLcQwyXWThy+BQ5+mkKKPvSO26ir+ZDp36AgYoYVkqvMcdS8zOE6SeBsR9e8A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.0.0-beta.41': + resolution: {integrity: sha512-ijAZETywvL+gACjbT4zBnCp5ez1JhTRs6OxRN4J+D6AzDRbU2zb01Esl51RP5/8ZOlvB37xxsRQ3X4YRVyYb3g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-freebsd-x64@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-4W28EgaIidbWIpwB3hESMBfiOSs7LBFpJGa8JIV488qLEnTR/pqzxDEoOPobhRSJ1lJlv0vUgA8+DKBIldo2gw==} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-freebsd-x64@1.0.0-rc.10': + resolution: {integrity: sha512-XZRXHdTa+4ME1MuDVp021+doQ+z6Ei4CCFmNc5/sKbqb8YmkiJdj8QKlV3rCI0AJtAeSB5n0WGPuJWNL9p/L2w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.41': + resolution: {integrity: sha512-EgIOZt7UildXKFEFvaiLNBXm+4ggQyGe3E5Z1QP9uRcJJs9omihOnm897FwOBQdCuMvI49iBgjFrkhH+wMJ2MA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-1ECtyzIKlAHikR7BhS4hk7Hxw8xCH6W3S+Sb74EM0vy5AqPvWSbgLfAwagYC7gNDcMMby3I757X7qih5fIrGiw==} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.10': + resolution: {integrity: sha512-R0SQMRluISSLzFE20sPWYHVmJdDQnRyc/FzSCN72BqQmh2SOZUFG+N3/vBZpR4C6WpEUVYJLrYUXaj43sJsNLA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.41': + resolution: {integrity: sha512-F8bUwJq8v/JAU8HSwgF4dztoqJ+FjdyjuvX4//3+Fbe2we9UktFeZ27U4lRMXF1vxWtdV4ey6oCSqI7yUrSEeg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-wU1kp8qPRUKC8N82dNs3F5+UyKRww9TUEO5dQ5mxCb0cG+y4l5rVaXpMgvL0VuQahPVvTMs577QPhJGb4iDONw==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.10': + resolution: {integrity: sha512-Y1reMrV/o+cwpduYhJuOE3OMKx32RMYCidf14y+HssARRmhDuWXJ4yVguDg2R/8SyyGNo+auzz64LnPK9Hq6jg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.41': + resolution: {integrity: sha512-MioXcCIX/wB1pBnBoJx8q4OGucUAfC1+/X1ilKFsjDK05VwbLZGRgOVD5OJJpUQPK86DhQciNBrfOKDiatxNmg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-odDjO2UtEEMAzwmLHEOKylJjQa+em1REAO9H19PA+O+lPu6evVbre5bqu8qCjEtHG1Q034LpZR86imCP2arb/w==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.10': + resolution: {integrity: sha512-vELN+HNb2IzuzSBUOD4NHmP9yrGwl1DVM29wlQvx1OLSclL0NgVWnVDKl/8tEks79EFek/kebQKnNJkIAA4W2g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.10': + resolution: {integrity: sha512-ZqrufYTgzxbHwpqOjzSsb0UV/aV2TFIY5rP8HdsiPTv/CuAgCRjM6s9cYFwQ4CNH+hf9Y4erHW1GjZuZ7WoI7w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.10': + resolution: {integrity: sha512-gSlmVS1FZJSRicA6IyjoRoKAFK7IIHBs7xJuHRSmjImqk3mPPWbR7RhbnfH2G6bcmMEllCt2vQ/7u9e6bBnByg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.41': + resolution: {integrity: sha512-m66M61fizvRCwt5pOEiZQMiwBL9/y0bwU/+Kc4Ce/Pef6YfoEkR28y+DzN9rMdjo8Z28NXjsDPq9nH4mXnAP0g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-Ty2T67t2Oj1lg417ATRENxdk8Jkkksc/YQdCJyvkGqteHe60pSU2GGP/tLWGB+I0Ox+u387bzU/SmfmrHZk9aw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.10': + resolution: {integrity: sha512-eOCKUpluKgfObT2pHjztnaWEIbUabWzk3qPZ5PuacuPmr4+JtQG4k2vGTY0H15edaTnicgU428XW/IH6AimcQw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.0.0-beta.41': + resolution: {integrity: sha512-yRxlSfBvWnnfrdtJfvi9lg8xfG5mPuyoSHm0X01oiE8ArmLRvoJGHUTJydCYz+wbK2esbq5J4B4Tq9WAsOlP1Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-x64-musl@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-Fm1TxyeVE+gy74HM26CwbEOUndIoWAMgWkVDxYBD64tayvp5JvltpGHaqCg6x5i+X2F5XCDCItqwVlC7/mTxIw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.10': + resolution: {integrity: sha512-Xdf2jQbfQowJnLcgYfD/m0Uu0Qj5OdxKallD78/IPPfzaiaI4KRAwZzHcKQ4ig1gtg1SuzC7jovNiM2TzQsBXA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.0.0-beta.41': + resolution: {integrity: sha512-PHVxYhBpi8UViS3/hcvQQb9RFqCtvFmFU1PvUoTRiUdBtgHA6fONNHU4x796lgzNlVSD3DO/MZNk1s5/ozSMQg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.10': + resolution: {integrity: sha512-o1hYe8hLi1EY6jgPFyxQgQ1wcycX+qz8eEbVmot2hFkgUzPxy9+kF0u0NIQBeDq+Mko47AkaFFaChcvZa9UX9Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.41': + resolution: {integrity: sha512-OAfcO37ME6GGWmj9qTaDT7jY4rM0T2z0/8ujdQIJQ2x2nl+ztO32EIwURfmXOK0U1tzkyuaKYvE34Pug/ucXlQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-AEZzTyGerfkffXmtv7kFJbHWkryNeolk0Br+yhH1wZyN6Tt6aebqICDL8KNRO2iExoEWzyYS6dPxh0QmvNTfUQ==} + engines: {node: '>=14.21.3'} + cpu: [wasm32] + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.10': + resolution: {integrity: sha512-Ugv9o7qYJudqQO5Y5y2N2SOo6S4WiqiNOpuQyoPInnhVzCY+wi/GHltcLHypG9DEUYMB0iTB/huJrpadiAcNcA==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.41': + resolution: {integrity: sha512-NIYGuCcuXaq5BC4Q3upbiMBvmZsTsEPG9k/8QKQdmrch+ocSy5Jv9tdpdmXJyighKqm182nh/zBt+tSJkYoNlg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-0lskDFKQwf5PMjl17qHAroU6oVU0Zn8NbAH/PdM9QB1emOzyFDGa20d4kESGeo3Uq7xOKXcTORJV/JwKIBORqw==} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.10': + resolution: {integrity: sha512-7UODQb4fQUNT/vmgDZBl3XOBAIOutP5R3O/rkxg0aLfEGQ4opbCgU5vOw/scPe4xOqBwL9fw7/RP1vAMZ6QlAQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.41': + resolution: {integrity: sha512-kANdsDbE5FkEOb5NrCGBJBCaZ2Sabp3D7d4PRqMYJqyLljwh9mDyYyYSv5+QNvdAmifj+f3lviNEUUuUZPEFPw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-DfG1S0zGKnUfr95cNCmR4YPiZ/moS7Tob5eV+9r5JGeHZVWFHWwvJdR0jArj6Ty0LbBFDTVVB3iAvqRSji+l0Q==} + cpu: [ia32] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.41': + resolution: {integrity: sha512-UlpxKmFdik0Y2VjZrgUCgoYArZJiZllXgIipdBRV1hw6uK45UbQabSTW6Kp6enuOu7vouYWftwhuxfpE8J2JAg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-5HZEtc8U2I1O903hXBynWtWaf+qzAFj66h5B7gOtVcvqIk+lKRVSupA85OdIvR7emrsYU25ikpfiU5Jhg9kTbQ==} + cpu: [x64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.10': + resolution: {integrity: sha512-PYxKHMVHOb5NJuDL53vBUl1VwUjymDcYI6rzpIni0C9+9mTiJedvUxSk7/RPp7OOAm3v+EjgMu9bIy3N6b408w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.0-beta.41': + resolution: {integrity: sha512-ycMEPrS3StOIeb87BT3/+bu+blEtyvwQ4zmo2IcJQy0Rd1DAAhKksA0iUZ3MYSpJtjlPhg0Eo6mvVS6ggPhRbw==} + + '@rolldown/pluginutils@1.0.0-rc.10': + resolution: {integrity: sha512-UkVDEFk1w3mveXeKgaTuYfKWtPbvgck1dT8TUG3bnccrH0XtLTuAyfCoks4Q/M5ZGToSVJTIQYCzy2g/atAOeg==} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + + '@types/aws-lambda@8.10.161': + resolution: {integrity: sha512-rUYdp+MQwSFocxIOcSsYSF3YYYC/uUpMbCY/mbO21vGqfrEYvNSoPyKYDj6RhXXpPfS0KstW9RwG3qXh9sL7FQ==} + + '@types/body-parser@1.19.6': + resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} + + '@types/bunyan@1.8.11': + resolution: {integrity: sha512-758fRH7umIMk5qt5ELmRMff4mLDlN+xyYzC+dkPTdKwbSkJFvz6xwyScrytPU0QIBbRRwbiE8/BIg8bpajerNQ==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/express-serve-static-core@4.19.8': + resolution: {integrity: sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==} + + '@types/express@4.17.25': + resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} + + '@types/http-errors@2.0.5': + resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/memcached@2.2.10': + resolution: {integrity: sha512-AM9smvZN55Gzs2wRrqeMHVP7KE8KWgCJO/XL5yCly2xF6EKa4YlbpK+cLSAH4NG/Ah64HrlegmGqW8kYws7Vxg==} + + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + + '@types/mysql@2.15.27': + resolution: {integrity: sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==} + + '@types/node@22.19.15': + resolution: {integrity: sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==} + + '@types/oracledb@6.5.2': + resolution: {integrity: sha512-kK1eBS/Adeyis+3OlBDMeQQuasIDLUYXsi2T15ccNJ0iyUpQ4xDF7svFu3+bGVrI0CMBUclPciz+lsQR3JX3TQ==} + + '@types/pg-pool@2.0.6': + resolution: {integrity: sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ==} + + '@types/pg@8.15.6': + resolution: {integrity: sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==} + + '@types/qs@6.15.0': + resolution: {integrity: sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + + '@types/semver@7.7.1': + resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} + + '@types/send@0.17.6': + resolution: {integrity: sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==} + + '@types/send@1.2.1': + resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} + + '@types/serve-static@1.15.10': + resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} + + '@types/tedious@4.0.14': + resolution: {integrity: sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==} + + '@types/uuid@10.0.0': + resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} + + '@valibot/to-json-schema@1.0.0': + resolution: {integrity: sha512-/9crJgPptVsGCL6X+JPDQyaJwkalSZ/52WuF8DiRUxJgcmpNdzYRfZ+gqMEP8W3CTVfuMWPqqvIgfwJ97f9Etw==} + peerDependencies: + valibot: ^1.0.0 + + '@vercel/oidc@3.1.0': + resolution: {integrity: sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==} + engines: {node: '>= 20'} + + '@vitest/expect@4.1.0': + resolution: {integrity: sha512-EIxG7k4wlWweuCLG9Y5InKFwpMEOyrMb6ZJ1ihYu02LVj/bzUwn2VMU+13PinsjRW75XnITeFrQBMH5+dLvCDA==} + + '@vitest/mocker@4.1.0': + resolution: {integrity: sha512-evxREh+Hork43+Y4IOhTo+h5lGmVRyjqI739Rz4RlUPqwrkFFDF6EMvOOYjTx4E8Tl6gyCLRL8Mu7Ry12a13Tw==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@4.1.0': + resolution: {integrity: sha512-3RZLZlh88Ib0J7NQTRATfc/3ZPOnSUn2uDBUoGNn5T36+bALixmzphN26OUD3LRXWkJu4H0s5vvUeqBiw+kS0A==} + + '@vitest/runner@4.1.0': + resolution: {integrity: sha512-Duvx2OzQ7d6OjchL+trw+aSrb9idh7pnNfxrklo14p3zmNL4qPCDeIJAK+eBKYjkIwG96Bc6vYuxhqDXQOWpoQ==} + + '@vitest/snapshot@4.1.0': + resolution: {integrity: sha512-0Vy9euT1kgsnj1CHttwi9i9o+4rRLEaPRSOJ5gyv579GJkNpgJK+B4HSv/rAWixx2wdAFci1X4CEPjiu2bXIMg==} + + '@vitest/spy@4.1.0': + resolution: {integrity: sha512-pz77k+PgNpyMDv2FV6qmk5ZVau6c3R8HC8v342T2xlFxQKTrSeYw9waIJG8KgV9fFwAtTu4ceRzMivPTH6wSxw==} + + '@vitest/utils@4.1.0': + resolution: {integrity: sha512-XfPXT6a8TZY3dcGY8EdwsBulFCIw+BeeX0RZn2x/BtiY/75YGh8FeWGG8QISN/WhaqSrE2OrlDgtF8q5uhOTmw==} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + + acorn-import-attributes@1.9.5: + resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} + peerDependencies: + acorn: ^8 + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + ai@6.0.116: + resolution: {integrity: sha512-7yM+cTmyRLeNIXwt4Vj+mrrJgVQ9RMIW5WO0ydoLoYkewIvsMcvUmqS4j2RJTUXaF1HphwmSKUMQ/HypNRGOmA==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@8.18.0: + resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansis@3.17.0: + resolution: {integrity: sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==} + engines: {node: '>=14'} + + ansis@4.2.0: + resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} + engines: {node: '>=14'} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + ast-kit@1.4.3: + resolution: {integrity: sha512-MdJqjpodkS5J149zN0Po+HPshkTdUyrvF7CKTafUgv69vBSPtncrj+3IiUgqdd7ElIEkbeXCsEouBUwLrw9Ilg==} + engines: {node: '>=16.14.0'} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + bignumber.js@9.3.1: + resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + + body-parser@1.20.4: + resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + body-parser@2.2.2: + resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} + engines: {node: '>=18'} + + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + cjs-module-lexer@2.2.0: + resolution: {integrity: sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + console-table-printer@2.15.0: + resolution: {integrity: sha512-SrhBq4hYVjLCkBVOWaTzceJalvn5K1Zq5aQA6wXC/cYjI3frKWNPEMK3sZsJfNNQApvCQmgBcc13ZKmFj8qExw==} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-disposition@1.0.1: + resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} + engines: {node: '>=18'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-signature@1.0.7: + resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} + + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + cors@2.8.6: + resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} + engines: {node: '>= 0.10'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + diff@7.0.0: + resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} + engines: {node: '>=0.3.1'} + + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + + dts-resolver@1.2.0: + resolution: {integrity: sha512-+xNF7raXYI1E3IFB+f3JqvoKYFI8R+1Mh9mpI75yNm3F5XuiC6ErEXe2Lqh9ach+4MQ1tOefzjxulhWGVclYbg==} + engines: {node: '>=20.18.0'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + empathic@1.1.0: + resolution: {integrity: sha512-rsPft6CK3eHtrlp9Y5ALBb+hfK+DWnA4WFebbazxjWyx8vSm3rZeoM3z9irsjcqO3PYRzlfv27XIB4tz2DV7RA==} + engines: {node: '>=14'} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@2.0.0: + resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + + eventsource-parser@3.0.6: + resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} + engines: {node: '>=18.0.0'} + + eventsource@3.0.7: + resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} + engines: {node: '>=18.0.0'} + + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + + express-rate-limit@8.3.1: + resolution: {integrity: sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==} + engines: {node: '>= 16'} + peerDependencies: + express: '>= 4.11' + + express@4.22.1: + resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==} + engines: {node: '>= 0.10.0'} + + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} + engines: {node: '>= 18'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + extended-eventsource@1.7.0: + resolution: {integrity: sha512-s8rtvZuYcKBpzytHb5g95cHbZ1J99WeMnV18oKc5wKoxkHzlzpPc/bNAm7Da2Db0BDw0CAu1z3LpH+7UsyzIpw==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + + finalhandler@1.3.2: + resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} + engines: {node: '>= 0.8'} + + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} + + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + + forwarded-parse@2.1.2: + resolution: {integrity: sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gaxios@6.7.1: + resolution: {integrity: sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==} + engines: {node: '>=14'} + + gaxios@7.1.4: + resolution: {integrity: sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==} + engines: {node: '>=18'} + + gcp-metadata@6.1.1: + resolution: {integrity: sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==} + engines: {node: '>=14'} + + gcp-metadata@8.1.2: + resolution: {integrity: sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==} + engines: {node: '>=18'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.13.6: + resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==} + + google-auth-library@10.6.2: + resolution: {integrity: sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==} + engines: {node: '>=18'} + + google-logging-utils@0.0.2: + resolution: {integrity: sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==} + engines: {node: '>=14'} + + google-logging-utils@1.1.3: + resolution: {integrity: sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==} + engines: {node: '>=14'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hono@4.12.8: + resolution: {integrity: sha512-VJCEvtrezO1IAR+kqEYnxUOoStaQPGrCmX3j4wDTNOcD1uRPFpGlwQUIW8niPuvHXaTUxeOUl5MMDGrl+tmO9A==} + engines: {node: '>=16.9.0'} + + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + + import-in-the-middle@2.0.6: + resolution: {integrity: sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@6.0.0: + resolution: {integrity: sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==} + engines: {node: ^20.17.0 || >=22.9.0} + + ip-address@10.1.0: + resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} + engines: {node: '>= 12'} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-network-error@1.3.1: + resolution: {integrity: sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==} + engines: {node: '>=16'} + + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + + jose@6.2.2: + resolution: {integrity: sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==} + + js-tiktoken@1.0.21: + resolution: {integrity: sha512-biOj/6M5qdgx5TKjDnFT1ymSpM5tbd3ylwDtrQvFQSu0Z7bBYko2dF+W/aUkXUPuk6IVpRxk/3Q2sHOzGlS36g==} + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-bigint@1.0.0: + resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema-typed@8.0.2: + resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + + jwa@2.0.1: + resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} + + jws@4.0.1: + resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} + + langsmith@0.5.11: + resolution: {integrity: sha512-Yio502Ow2vbVt16P1sybNMNpMsr5BMqoeonoi4flrcDsP55No/aCe2zydtBNOv0+kjKQw4WSKAzTsNwenDeD5w==} + peerDependencies: + '@opentelemetry/api': '*' + '@opentelemetry/exporter-trace-otlp-proto': '*' + '@opentelemetry/sdk-trace-base': '*' + openai: '*' + ws: '>=7' + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@opentelemetry/exporter-trace-otlp-proto': + optional: true + '@opentelemetry/sdk-trace-base': + optional: true + openai: + optional: true + ws: + optional: true + + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + + long@5.3.2: + resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + module-details-from-path@1.0.4: + resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mustache@4.2.0: + resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} + hasBin: true + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + oxc-resolver@9.0.2: + resolution: {integrity: sha512-w838ygc1p7rF+7+h5vR9A+Y9Fc4imy6C3xPthCMkdFUgFvUWkmABeNB8RBDQ6+afk44Q60/UMMQ+gfDUW99fBA==} + + oxc-transform@0.67.0: + resolution: {integrity: sha512-QXwmpLfNrXZoHgIjEtDEf6lhwmvHouNtstNgg/UveczVIjo8VSzd5h25Ea96PoX9KzReJUY/qYa4QSNkJpZGfA==} + engines: {node: '>=14.0.0'} + + p-finally@1.0.0: + resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} + engines: {node: '>=4'} + + p-queue@6.6.2: + resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} + engines: {node: '>=8'} + + p-queue@9.1.0: + resolution: {integrity: sha512-O/ZPaXuQV29uSLbxWBGGZO1mCQXV2BLIwUr59JUU9SoH76mnYvtms7aafH/isNSNGwuEfP6W/4xD0/TJXxrizw==} + engines: {node: '>=20'} + + p-retry@7.1.1: + resolution: {integrity: sha512-J5ApzjyRkkf601HpEeykoiCvzHQjWxPAHhyjFcEUP2SWq0+35NKh8TLhpLw+Dkq5TZBFvUM6UigdE9hIVYTl5w==} + engines: {node: '>=20'} + + p-timeout@3.2.0: + resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} + engines: {node: '>=8'} + + p-timeout@7.0.1: + resolution: {integrity: sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==} + engines: {node: '>=20'} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-to-regexp@0.1.12: + resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} + + path-to-regexp@8.3.0: + resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + pg-cloudflare@1.3.0: + resolution: {integrity: sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==} + + pg-connection-string@2.12.0: + resolution: {integrity: sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==} + + pg-int8@1.0.1: + resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} + engines: {node: '>=4.0.0'} + + pg-pool@3.13.0: + resolution: {integrity: sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA==} + peerDependencies: + pg: '>=8.0' + + pg-protocol@1.13.0: + resolution: {integrity: sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==} + + pg-types@2.2.0: + resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} + engines: {node: '>=4'} + + pg@8.20.0: + resolution: {integrity: sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==} + engines: {node: '>= 16.0.0'} + peerDependencies: + pg-native: '>=3.0.1' + peerDependenciesMeta: + pg-native: + optional: true + + pgpass@1.0.5: + resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pkce-challenge@5.0.1: + resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} + engines: {node: '>=16.20.0'} + + postcss@8.5.8: + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + engines: {node: ^10 || ^12 || >=14} + + postgres-array@2.0.0: + resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} + engines: {node: '>=4'} + + postgres-bytea@1.0.1: + resolution: {integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==} + engines: {node: '>=0.10.0'} + + postgres-date@1.0.7: + resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} + engines: {node: '>=0.10.0'} + + postgres-interval@1.2.0: + resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} + engines: {node: '>=0.10.0'} + + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} + engines: {node: '>=14'} + hasBin: true + + protobufjs@7.5.4: + resolution: {integrity: sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==} + engines: {node: '>=12.0.0'} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + qs@6.14.2: + resolution: {integrity: sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==} + engines: {node: '>=0.6'} + + qs@6.15.0: + resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==} + engines: {node: '>=0.6'} + + quansync@1.0.0: + resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.3: + resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} + engines: {node: '>= 0.8'} + + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + reflect-metadata@0.2.2: + resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + require-in-the-middle@8.0.1: + resolution: {integrity: sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==} + engines: {node: '>=9.3.0 || >=8.10.0 <9.0.0'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + rolldown-plugin-dts@0.9.11: + resolution: {integrity: sha512-iCIRKmvPLwRV4UKSxhaBo+5wDkvc3+MFiqYYvu7sGLSohzxoDn9WEsjN3y7A6xg3aCuxHh6rlRp8xbX98r1rSg==} + engines: {node: '>=20.18.0'} + peerDependencies: + rolldown: ^1.0.0-beta.7 + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + rolldown-vite@7.1.14: + resolution: {integrity: sha512-eSiiRJmovt8qDJkGyZuLnbxAOAdie6NCmmd0NkTC0RJI9duiSBTfr8X2mBYJOUFzxQa2USaHmL99J9uMxkjCyw==} + engines: {node: ^20.19.0 || >=22.12.0} + deprecated: Use 7.3.1 for migration purposes. For the most recent updates, migrate to Vite 8 once you're ready. + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + esbuild: ^0.25.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + rolldown@1.0.0-beta.41: + resolution: {integrity: sha512-U+NPR0Bkg3wm61dteD2L4nAM1U9dtaqVrpDXwC36IKRHpEO/Ubpid4Nijpa2imPchcVNHfxVFwSSMJdwdGFUbg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + rolldown@1.0.0-beta.8-commit.151352b: + resolution: {integrity: sha512-TCb6GVaFBk4wB0LERofFDxTO5X1/Sgahr7Yn5UA9XjuFtCwL1CyEhUHX5lUIstcMxjbkLjn2z4TAGwisr6Blvw==} + hasBin: true + peerDependencies: + '@oxc-project/runtime': 0.66.0 + peerDependenciesMeta: + '@oxc-project/runtime': + optional: true + + rolldown@1.0.0-rc.10: + resolution: {integrity: sha512-q7j6vvarRFmKpgJUT8HCAUljkgzEp4LAhPlJUvQhA5LA1SUL36s5QCysMutErzL3EbNOZOkoziSx9iZC4FddKA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + send@0.19.2: + resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} + engines: {node: '>= 0.8.0'} + + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + + serve-static@1.16.3: + resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} + engines: {node: '>= 0.8.0'} + + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + simple-wcswidth@1.1.2: + resolution: {integrity: sha512-j7piyCjAeTDSjzTSQ7DokZtMNwNlEAyxqSZeCS+CXH7fJ4jx3FuJ/mTW3mE+6JLs4VJBbcll0Kjn+KXI5t21Iw==} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + std-env@4.0.0: + resolution: {integrity: sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@1.0.4: + resolution: {integrity: sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==} + engines: {node: '>=18'} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tinyrainbow@3.1.0: + resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} + engines: {node: '>=14.0.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + tsdown@0.9.9: + resolution: {integrity: sha512-IIGX55rkhaPomNSVrIbA58DRBwTO4ehlDTsw20XSooGqoEZbwpunDc1dRE73wKb1rHdwwBO6NMLOcgV2n1qhpA==} + engines: {node: '>=18.0.0'} + hasBin: true + peerDependencies: + publint: ^0.3.0 + unplugin-unused: ^0.4.0 + peerDependenciesMeta: + publint: + optional: true + unplugin-unused: + optional: true + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + type-is@2.0.1: + resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} + engines: {node: '>= 0.6'} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + unconfig-core@7.5.0: + resolution: {integrity: sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==} + + unconfig@7.5.0: + resolution: {integrity: sha512-oi8Qy2JV4D3UQ0PsopR28CzdQ3S/5A1zwsUwp/rosSbfhJ5z7b90bIyTwi/F7hCLD4SGcZVjDzd4XoUQcEanvA==} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + unplugin-lightningcss@0.3.3: + resolution: {integrity: sha512-mMNRCNIcxc/3410w7sJdXcPxn0IGZdEpq42OBDyckdGkhOeWYZCG9RkHs72TFyBsS82a4agFDOFU8VrFKF2ZvA==} + engines: {node: '>=18.12.0'} + + unplugin@2.3.11: + resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} + engines: {node: '>=18.12.0'} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid@10.0.0: + resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + hasBin: true + + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + + uuid@13.0.0: + resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==} + hasBin: true + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + + valibot@1.0.0: + resolution: {integrity: sha512-1Hc0ihzWxBar6NGeZv7fPLY0QuxFMyxwYR2sF1Blu7Wq7EnremwY2W02tit2ij2VJT8HcSkHAQqmFfl77f73Yw==} + peerDependencies: + typescript: '>=5' + peerDependenciesMeta: + typescript: + optional: true + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vite@8.0.1: + resolution: {integrity: sha512-wt+Z2qIhfFt85uiyRt5LPU4oVEJBXj8hZNWKeqFG4gRG/0RaRGJ7njQCwzFVjO+v4+Ipmf5CY7VdmZRAYYBPHw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.1.0 + esbuild: ^0.27.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@4.1.0: + resolution: {integrity: sha512-YbDrMF9jM2Lqc++2530UourxZHmkKLxrs4+mYhEwqWS97WJ7wOYEkcr+QfRgJ3PW9wz3odRijLZjHEaRLTNbqw==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.1.0 + '@vitest/browser-preview': 4.1.0 + '@vitest/browser-webdriverio': 4.1.0 + '@vitest/ui': 4.1.0 + happy-dom: '*' + jsdom: '*' + vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0 + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + 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==} + + ws@8.19.0: + resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + 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'} + + zod-to-json-schema@3.25.1: + resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} + peerDependencies: + zod: ^3.25 || ^4 + + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + +snapshots: + + '@ai-sdk/gateway@3.0.66(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 3.0.8 + '@ai-sdk/provider-utils': 4.0.19(zod@4.3.6) + '@vercel/oidc': 3.1.0 + zod: 4.3.6 + + '@ai-sdk/provider-utils@4.0.19(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 3.0.8 + '@standard-schema/spec': 1.1.0 + eventsource-parser: 3.0.6 + zod: 4.3.6 + + '@ai-sdk/provider@3.0.8': + dependencies: + json-schema: 0.4.0 + + '@ast-grep/napi-darwin-arm64@0.37.0': + optional: true + + '@ast-grep/napi-darwin-x64@0.37.0': + optional: true + + '@ast-grep/napi-linux-arm64-gnu@0.37.0': + optional: true + + '@ast-grep/napi-linux-arm64-musl@0.37.0': + optional: true + + '@ast-grep/napi-linux-x64-gnu@0.37.0': + optional: true + + '@ast-grep/napi-linux-x64-musl@0.37.0': + optional: true + + '@ast-grep/napi-win32-arm64-msvc@0.37.0': + optional: true + + '@ast-grep/napi-win32-ia32-msvc@0.37.0': + optional: true + + '@ast-grep/napi-win32-x64-msvc@0.37.0': + optional: true + + '@ast-grep/napi@0.37.0': + optionalDependencies: + '@ast-grep/napi-darwin-arm64': 0.37.0 + '@ast-grep/napi-darwin-x64': 0.37.0 + '@ast-grep/napi-linux-arm64-gnu': 0.37.0 + '@ast-grep/napi-linux-arm64-musl': 0.37.0 + '@ast-grep/napi-linux-x64-gnu': 0.37.0 + '@ast-grep/napi-linux-x64-musl': 0.37.0 + '@ast-grep/napi-win32-arm64-msvc': 0.37.0 + '@ast-grep/napi-win32-ia32-msvc': 0.37.0 + '@ast-grep/napi-win32-x64-msvc': 0.37.0 + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/parser@7.29.2': + dependencies: + '@babel/types': 7.29.0 + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@cfworker/json-schema@4.1.1': {} + + '@clack/core@1.1.0': + dependencies: + sisteransi: 1.0.5 + + '@clack/prompts@1.1.0': + dependencies: + '@clack/core': 1.1.0 + sisteransi: 1.0.5 + + '@databricks/ai-sdk-provider@0.3.0(@ai-sdk/provider-utils@4.0.19(zod@4.3.6))(@ai-sdk/provider@3.0.8)': + dependencies: + '@ai-sdk/provider': 3.0.8 + '@ai-sdk/provider-utils': 4.0.19(zod@4.3.6) + zod: 4.3.6 + + '@databricks/appkit@0.21.0(@opentelemetry/core@2.6.0(@opentelemetry/api@1.9.0))(@types/node@22.19.15)(jiti@2.6.1)': + dependencies: + '@ast-grep/napi': 0.37.0 + '@clack/prompts': 1.1.0 + '@databricks/lakebase': 0.2.0 + '@databricks/sdk-experimental': 0.16.0 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.208.0 + '@opentelemetry/auto-instrumentations-node': 0.67.3(@opentelemetry/api@1.9.0)(@opentelemetry/core@2.6.0(@opentelemetry/api@1.9.0)) + '@opentelemetry/exporter-logs-otlp-proto': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-proto': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-proto': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-express': 0.57.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-http': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-node': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + '@types/semver': 7.7.1 + ajv: 8.18.0 + ajv-formats: 3.0.1(ajv@8.18.0) + commander: 12.1.0 + dotenv: 16.6.1 + express: 4.22.1 + obug: 2.1.1 + pg: 8.20.0 + picocolors: 1.1.1 + semver: 7.7.4 + vite: rolldown-vite@7.1.14(@types/node@22.19.15)(jiti@2.6.1) + ws: 8.19.0 + transitivePeerDependencies: + - '@opentelemetry/core' + - '@types/node' + - bufferutil + - encoding + - esbuild + - jiti + - less + - pg-native + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - utf-8-validate + - yaml + + '@databricks/lakebase@0.2.0': + dependencies: + '@databricks/sdk-experimental': 0.16.0 + '@opentelemetry/api': 1.9.0 + pg: 8.20.0 + transitivePeerDependencies: + - pg-native + - supports-color + + '@databricks/langchainjs@0.1.0(@cfworker/json-schema@4.1.1)(@langchain/langgraph@1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0)': + dependencies: + '@ai-sdk/provider': 3.0.8 + '@ai-sdk/provider-utils': 4.0.19(zod@4.3.6) + '@databricks/ai-sdk-provider': 0.3.0(@ai-sdk/provider-utils@4.0.19(zod@4.3.6))(@ai-sdk/provider@3.0.8) + '@databricks/sdk-experimental': 0.15.0 + '@langchain/core': 1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0) + '@langchain/mcp-adapters': 1.1.3(@cfworker/json-schema@4.1.1)(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(@langchain/langgraph@1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6)) + ai: 6.0.116(zod@4.3.6) + zod: 4.3.6 + transitivePeerDependencies: + - '@cfworker/json-schema' + - '@langchain/langgraph' + - '@opentelemetry/api' + - '@opentelemetry/exporter-trace-otlp-proto' + - '@opentelemetry/sdk-trace-base' + - openai + - supports-color + - ws + + '@databricks/sdk-experimental@0.15.0': + dependencies: + google-auth-library: 10.6.2 + ini: 6.0.0 + reflect-metadata: 0.2.2 + semver: 7.7.4 + transitivePeerDependencies: + - supports-color + + '@databricks/sdk-experimental@0.16.0': + dependencies: + google-auth-library: 10.6.2 + ini: 6.0.0 + reflect-metadata: 0.2.2 + semver: 7.7.4 + transitivePeerDependencies: + - supports-color + + '@emnapi/core@1.9.1': + dependencies: + '@emnapi/wasi-threads': 1.2.0 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.9.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@grpc/grpc-js@1.14.3': + dependencies: + '@grpc/proto-loader': 0.8.0 + '@js-sdsl/ordered-map': 4.4.2 + + '@grpc/proto-loader@0.8.0': + dependencies: + lodash.camelcase: 4.3.0 + long: 5.3.2 + protobufjs: 7.5.4 + yargs: 17.7.2 + + '@hono/node-server@1.19.11(hono@4.12.8)': + dependencies: + hono: 4.12.8 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@js-sdsl/ordered-map@4.4.2': {} + + '@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0)': + dependencies: + '@cfworker/json-schema': 4.1.1 + '@standard-schema/spec': 1.1.0 + ansi-styles: 5.2.0 + camelcase: 6.3.0 + decamelize: 1.2.0 + js-tiktoken: 1.0.21 + langsmith: 0.5.11(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0) + mustache: 4.2.0 + p-queue: 6.6.2 + uuid: 11.1.0 + zod: 4.3.6 + transitivePeerDependencies: + - '@opentelemetry/api' + - '@opentelemetry/exporter-trace-otlp-proto' + - '@opentelemetry/sdk-trace-base' + - openai + - ws + + '@langchain/langgraph-checkpoint@1.0.1(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))': + dependencies: + '@langchain/core': 1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0) + uuid: 10.0.0 + + '@langchain/langgraph-sdk@1.7.5(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))': + dependencies: + '@types/json-schema': 7.0.15 + p-queue: 9.1.0 + p-retry: 7.1.1 + uuid: 13.0.0 + optionalDependencies: + '@langchain/core': 1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0) + + '@langchain/langgraph@1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6)': + dependencies: + '@langchain/core': 1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0) + '@langchain/langgraph-checkpoint': 1.0.1(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0)) + '@langchain/langgraph-sdk': 1.7.5(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0)) + '@standard-schema/spec': 1.1.0 + uuid: 10.0.0 + zod: 4.3.6 + optionalDependencies: + zod-to-json-schema: 3.25.1(zod@4.3.6) + transitivePeerDependencies: + - react + - react-dom + - svelte + - vue + + '@langchain/mcp-adapters@1.1.3(@cfworker/json-schema@4.1.1)(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(@langchain/langgraph@1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6))': + dependencies: + '@langchain/core': 1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0) + '@langchain/langgraph': 1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) + '@modelcontextprotocol/sdk': 1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6) + debug: 4.4.3 + zod: 4.3.6 + optionalDependencies: + extended-eventsource: 1.7.0 + transitivePeerDependencies: + - '@cfworker/json-schema' + - supports-color + + '@modelcontextprotocol/sdk@1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6)': + dependencies: + '@hono/node-server': 1.19.11(hono@4.12.8) + ajv: 8.18.0 + ajv-formats: 3.0.1(ajv@8.18.0) + content-type: 1.0.5 + cors: 2.8.6 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.0.6 + express: 5.2.1 + express-rate-limit: 8.3.1(express@5.2.1) + hono: 4.12.8 + jose: 6.2.2 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 4.3.6 + zod-to-json-schema: 3.25.1(zod@4.3.6) + optionalDependencies: + '@cfworker/json-schema': 4.1.1 + transitivePeerDependencies: + - supports-color + + '@napi-rs/wasm-runtime@0.2.12': + dependencies: + '@emnapi/core': 1.9.1 + '@emnapi/runtime': 1.9.1 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@napi-rs/wasm-runtime@1.1.1': + dependencies: + '@emnapi/core': 1.9.1 + '@emnapi/runtime': 1.9.1 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@opentelemetry/api-logs@0.208.0': + dependencies: + '@opentelemetry/api': 1.9.0 + + '@opentelemetry/api@1.9.0': {} + + '@opentelemetry/auto-instrumentations-node@0.67.3(@opentelemetry/api@1.9.0)(@opentelemetry/core@2.6.0(@opentelemetry/api@1.9.0))': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-amqplib': 0.56.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-aws-lambda': 0.61.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-aws-sdk': 0.64.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-bunyan': 0.54.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-cassandra-driver': 0.54.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-connect': 0.52.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-cucumber': 0.24.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-dataloader': 0.26.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-dns': 0.52.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-express': 0.57.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-fastify': 0.53.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-fs': 0.28.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-generic-pool': 0.52.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-graphql': 0.56.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-grpc': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-hapi': 0.55.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-http': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-ioredis': 0.57.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-kafkajs': 0.18.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-knex': 0.53.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-koa': 0.57.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-lru-memoizer': 0.53.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-memcached': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mongodb': 0.62.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mongoose': 0.55.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mysql': 0.55.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mysql2': 0.55.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-nestjs-core': 0.55.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-net': 0.53.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-openai': 0.7.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-oracledb': 0.34.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-pg': 0.61.2(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-pino': 0.55.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-redis': 0.57.2(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-restify': 0.54.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-router': 0.53.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-runtime-node': 0.22.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-socket.io': 0.55.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-tedious': 0.28.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-undici': 0.19.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-winston': 0.53.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resource-detector-alibaba-cloud': 0.32.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resource-detector-aws': 2.13.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resource-detector-azure': 0.17.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resource-detector-container': 0.8.4(@opentelemetry/api@1.9.0) + '@opentelemetry/resource-detector-gcp': 0.44.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-node': 0.208.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - encoding + - supports-color + + '@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + + '@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/semantic-conventions': 1.40.0 + + '@opentelemetry/core@2.6.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/semantic-conventions': 1.40.0 + + '@opentelemetry/exporter-logs-otlp-grpc@0.208.0(@opentelemetry/api@1.9.0)': + dependencies: + '@grpc/grpc-js': 1.14.3 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-logs-otlp-http@0.208.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.208.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-logs-otlp-proto@0.208.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.208.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-metrics-otlp-grpc@0.208.0(@opentelemetry/api@1.9.0)': + dependencies: + '@grpc/grpc-js': 1.14.3 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.2.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-metrics-otlp-http@0.208.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.2.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-metrics-otlp-proto@0.208.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.2.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-prometheus@0.208.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.2.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-trace-otlp-grpc@0.208.0(@opentelemetry/api@1.9.0)': + dependencies: + '@grpc/grpc-js': 1.14.3 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-trace-otlp-http@0.208.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-zipkin@2.2.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + + '@opentelemetry/instrumentation-amqplib@0.56.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-aws-lambda@0.61.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + '@types/aws-lambda': 8.10.161 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-aws-sdk@0.64.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-bunyan@0.54.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.208.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@types/bunyan': 1.8.11 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-cassandra-driver@0.54.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-connect@0.52.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + '@types/connect': 3.4.38 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-cucumber@0.24.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-dataloader@0.26.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-dns@0.52.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-express@0.57.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-fastify@0.53.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-fs@0.28.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-generic-pool@0.52.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-graphql@0.56.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-grpc@0.208.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-hapi@0.55.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-http@0.208.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + forwarded-parse: 2.1.2 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-ioredis@0.57.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/redis-common': 0.38.2 + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-kafkajs@0.18.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-knex@0.53.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-koa@0.57.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-lru-memoizer@0.53.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-memcached@0.52.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + '@types/memcached': 2.2.10 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-mongodb@0.62.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-mongoose@0.55.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-mysql2@0.55.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-mysql@0.55.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + '@types/mysql': 2.15.27 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-nestjs-core@0.55.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-net@0.53.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-openai@0.7.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.208.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-oracledb@0.34.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + '@types/oracledb': 6.5.2 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-pg@0.61.2(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.0) + '@types/pg': 8.15.6 + '@types/pg-pool': 2.0.6 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-pino@0.55.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.208.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-redis@0.57.2(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/redis-common': 0.38.2 + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-restify@0.54.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-router@0.53.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-runtime-node@0.22.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-socket.io@0.55.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-tedious@0.28.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + '@types/tedious': 4.0.14 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-undici@0.19.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation-winston@0.53.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.208.0 + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + + '@opentelemetry/instrumentation@0.208.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.208.0 + import-in-the-middle: 2.0.6 + require-in-the-middle: 8.0.1 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/otlp-exporter-base@0.208.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/otlp-grpc-exporter-base@0.208.0(@opentelemetry/api@1.9.0)': + dependencies: + '@grpc/grpc-js': 1.14.3 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.208.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/otlp-transformer@0.208.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.208.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) + protobufjs: 7.5.4 + + '@opentelemetry/propagator-b3@2.2.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/propagator-jaeger@2.2.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/redis-common@0.38.2': {} + + '@opentelemetry/resource-detector-alibaba-cloud@0.32.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/resource-detector-aws@2.13.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + + '@opentelemetry/resource-detector-azure@0.17.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + + '@opentelemetry/resource-detector-container@0.8.4(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/resource-detector-gcp@0.44.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + gcp-metadata: 6.1.1 + transitivePeerDependencies: + - encoding + - supports-color + + '@opentelemetry/resources@2.2.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + + '@opentelemetry/resources@2.6.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + + '@opentelemetry/sdk-logs@0.208.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.208.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/sdk-metrics@2.2.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/sdk-metrics@2.6.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/sdk-node@0.208.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.208.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-grpc': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-http': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-proto': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-grpc': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-proto': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-prometheus': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-grpc': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-http': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-proto': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-zipkin': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/propagator-b3': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/propagator-jaeger': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-node': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + + '@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.6.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.40.0 + + '@opentelemetry/sdk-trace-node@2.2.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/context-async-hooks': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.2.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.2.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/semantic-conventions@1.40.0': {} + + '@opentelemetry/sql-common@0.41.2(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) + + '@oxc-project/runtime@0.92.0': {} + + '@oxc-project/types@0.120.0': {} + + '@oxc-project/types@0.66.0': {} + + '@oxc-project/types@0.93.0': {} + + '@oxc-resolver/binding-darwin-arm64@9.0.2': + optional: true + + '@oxc-resolver/binding-darwin-x64@9.0.2': + optional: true + + '@oxc-resolver/binding-freebsd-x64@9.0.2': + optional: true + + '@oxc-resolver/binding-linux-arm-gnueabihf@9.0.2': + optional: true + + '@oxc-resolver/binding-linux-arm64-gnu@9.0.2': + optional: true + + '@oxc-resolver/binding-linux-arm64-musl@9.0.2': + optional: true + + '@oxc-resolver/binding-linux-riscv64-gnu@9.0.2': + optional: true + + '@oxc-resolver/binding-linux-s390x-gnu@9.0.2': + optional: true + + '@oxc-resolver/binding-linux-x64-gnu@9.0.2': + optional: true + + '@oxc-resolver/binding-linux-x64-musl@9.0.2': + optional: true + + '@oxc-resolver/binding-wasm32-wasi@9.0.2': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@oxc-resolver/binding-win32-arm64-msvc@9.0.2': + optional: true + + '@oxc-resolver/binding-win32-x64-msvc@9.0.2': + optional: true + + '@oxc-transform/binding-darwin-arm64@0.67.0': + optional: true + + '@oxc-transform/binding-darwin-x64@0.67.0': + optional: true + + '@oxc-transform/binding-linux-arm-gnueabihf@0.67.0': + optional: true + + '@oxc-transform/binding-linux-arm64-gnu@0.67.0': + optional: true + + '@oxc-transform/binding-linux-arm64-musl@0.67.0': + optional: true + + '@oxc-transform/binding-linux-x64-gnu@0.67.0': + optional: true + + '@oxc-transform/binding-linux-x64-musl@0.67.0': + optional: true + + '@oxc-transform/binding-wasm32-wasi@0.67.0': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@oxc-transform/binding-win32-arm64-msvc@0.67.0': + optional: true + + '@oxc-transform/binding-win32-x64-msvc@0.67.0': + optional: true + + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.4': {} + + '@protobufjs/eventemitter@1.1.0': {} + + '@protobufjs/fetch@1.1.0': + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/inquire@1.1.0': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.0': {} + + '@quansync/fs@1.0.0': + dependencies: + quansync: 1.0.0 + + '@rolldown/binding-android-arm64@1.0.0-beta.41': + optional: true + + '@rolldown/binding-android-arm64@1.0.0-rc.10': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-beta.41': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-rc.10': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-beta.41': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-rc.10': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-beta.41': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-rc.10': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.41': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.10': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.41': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.10': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.41': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.10': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.10': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.10': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.41': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.10': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-beta.41': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.10': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-beta.41': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.10': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.41': + dependencies: + '@napi-rs/wasm-runtime': 1.1.1 + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.8-commit.151352b': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.10': + dependencies: + '@napi-rs/wasm-runtime': 1.1.1 + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.41': + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.10': + optional: true + + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.41': + optional: true + + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.41': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.10': + optional: true + + '@rolldown/pluginutils@1.0.0-beta.41': {} + + '@rolldown/pluginutils@1.0.0-rc.10': {} + + '@standard-schema/spec@1.1.0': {} + + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/aws-lambda@8.10.161': {} + + '@types/body-parser@1.19.6': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 22.19.15 + + '@types/bunyan@1.8.11': + dependencies: + '@types/node': 22.19.15 + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/connect@3.4.38': + dependencies: + '@types/node': 22.19.15 + + '@types/deep-eql@4.0.2': {} + + '@types/estree@1.0.8': {} + + '@types/express-serve-static-core@4.19.8': + dependencies: + '@types/node': 22.19.15 + '@types/qs': 6.15.0 + '@types/range-parser': 1.2.7 + '@types/send': 1.2.1 + + '@types/express@4.17.25': + dependencies: + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 4.19.8 + '@types/qs': 6.15.0 + '@types/serve-static': 1.15.10 + + '@types/http-errors@2.0.5': {} + + '@types/json-schema@7.0.15': {} + + '@types/memcached@2.2.10': + dependencies: + '@types/node': 22.19.15 + + '@types/mime@1.3.5': {} + + '@types/mysql@2.15.27': + dependencies: + '@types/node': 22.19.15 + + '@types/node@22.19.15': + dependencies: + undici-types: 6.21.0 + + '@types/oracledb@6.5.2': + dependencies: + '@types/node': 22.19.15 + + '@types/pg-pool@2.0.6': + dependencies: + '@types/pg': 8.15.6 + + '@types/pg@8.15.6': + dependencies: + '@types/node': 22.19.15 + pg-protocol: 1.13.0 + pg-types: 2.2.0 + + '@types/qs@6.15.0': {} + + '@types/range-parser@1.2.7': {} + + '@types/semver@7.7.1': {} + + '@types/send@0.17.6': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 22.19.15 + + '@types/send@1.2.1': + dependencies: + '@types/node': 22.19.15 + + '@types/serve-static@1.15.10': + dependencies: + '@types/http-errors': 2.0.5 + '@types/node': 22.19.15 + '@types/send': 0.17.6 + + '@types/tedious@4.0.14': + dependencies: + '@types/node': 22.19.15 + + '@types/uuid@10.0.0': {} + + '@valibot/to-json-schema@1.0.0(valibot@1.0.0(typescript@5.9.3))': + dependencies: + valibot: 1.0.0(typescript@5.9.3) + + '@vercel/oidc@3.1.0': {} + + '@vitest/expect@4.1.0': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.1.0 + '@vitest/utils': 4.1.0 + chai: 6.2.2 + tinyrainbow: 3.1.0 + + '@vitest/mocker@4.1.0(vite@8.0.1(@types/node@22.19.15)(jiti@2.6.1))': + dependencies: + '@vitest/spy': 4.1.0 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 8.0.1(@types/node@22.19.15)(jiti@2.6.1) + + '@vitest/pretty-format@4.1.0': + dependencies: + tinyrainbow: 3.1.0 + + '@vitest/runner@4.1.0': + dependencies: + '@vitest/utils': 4.1.0 + pathe: 2.0.3 + + '@vitest/snapshot@4.1.0': + dependencies: + '@vitest/pretty-format': 4.1.0 + '@vitest/utils': 4.1.0 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@4.1.0': {} + + '@vitest/utils@4.1.0': + dependencies: + '@vitest/pretty-format': 4.1.0 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.0 + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + accepts@2.0.0: + dependencies: + mime-types: 3.0.2 + negotiator: 1.0.0 + + acorn-import-attributes@1.9.5(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + + agent-base@7.1.4: {} + + ai@6.0.116(zod@4.3.6): + dependencies: + '@ai-sdk/gateway': 3.0.66(zod@4.3.6) + '@ai-sdk/provider': 3.0.8 + '@ai-sdk/provider-utils': 4.0.19(zod@4.3.6) + '@opentelemetry/api': 1.9.0 + zod: 4.3.6 + + ajv-formats@3.0.1(ajv@8.18.0): + optionalDependencies: + ajv: 8.18.0 + + ajv@8.18.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansis@3.17.0: {} + + ansis@4.2.0: {} + + array-flatten@1.1.1: {} + + assertion-error@2.0.1: {} + + ast-kit@1.4.3: + dependencies: + '@babel/parser': 7.29.2 + pathe: 2.0.3 + + base64-js@1.5.1: {} + + bignumber.js@9.3.1: {} + + body-parser@1.20.4: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.14.2 + raw-body: 2.5.3 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + body-parser@2.2.2: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 4.4.3 + http-errors: 2.0.1 + iconv-lite: 0.7.2 + on-finished: 2.4.1 + qs: 6.15.0 + raw-body: 3.0.2 + type-is: 2.0.1 + transitivePeerDependencies: + - supports-color + + buffer-equal-constant-time@1.0.1: {} + + bytes@3.1.2: {} + + cac@6.7.14: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + camelcase@6.3.0: {} + + chai@6.2.2: {} + + chalk@5.6.2: {} + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + cjs-module-lexer@2.2.0: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + commander@12.1.0: {} + + consola@3.4.2: {} + + console-table-printer@2.15.0: + dependencies: + simple-wcswidth: 1.1.2 + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-disposition@1.0.1: {} + + content-type@1.0.5: {} + + convert-source-map@2.0.0: {} + + cookie-signature@1.0.7: {} + + cookie-signature@1.2.2: {} + + cookie@0.7.2: {} + + cors@2.8.6: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + data-uri-to-buffer@4.0.1: {} + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decamelize@1.2.0: {} + + defu@6.1.4: {} + + depd@2.0.0: {} + + destroy@1.2.0: {} + + detect-libc@2.1.2: {} + + diff@7.0.0: {} + + dotenv@16.6.1: {} + + dts-resolver@1.2.0: + dependencies: + oxc-resolver: 9.0.2 + pathe: 2.0.3 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + ecdsa-sig-formatter@1.0.11: + dependencies: + safe-buffer: 5.2.1 + + ee-first@1.1.1: {} + + emoji-regex@8.0.0: {} + + empathic@1.1.0: {} + + encodeurl@2.0.0: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-module-lexer@2.0.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + etag@1.8.1: {} + + eventemitter3@4.0.7: {} + + eventemitter3@5.0.4: {} + + eventsource-parser@3.0.6: {} + + eventsource@3.0.7: + dependencies: + eventsource-parser: 3.0.6 + + expect-type@1.3.0: {} + + express-rate-limit@8.3.1(express@5.2.1): + dependencies: + express: 5.2.1 + ip-address: 10.1.0 + + express@4.22.1: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.4 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.0.7 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.2 + fresh: 0.5.2 + http-errors: 2.0.1 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.12 + proxy-addr: 2.0.7 + qs: 6.14.2 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.2 + serve-static: 1.16.3 + setprototypeof: 1.2.0 + statuses: 2.0.2 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + express@5.2.1: + dependencies: + accepts: 2.0.0 + body-parser: 2.2.2 + content-disposition: 1.0.1 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.1 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.15.0 + range-parser: 1.2.1 + router: 2.2.0 + send: 1.2.1 + serve-static: 2.2.1 + statuses: 2.0.2 + type-is: 2.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + extend@3.0.2: {} + + extended-eventsource@1.7.0: + optional: true + + fast-deep-equal@3.1.3: {} + + fast-uri@3.1.0: {} + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + + finalhandler@1.3.2: + dependencies: + debug: 2.6.9 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + finalhandler@2.1.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + + forwarded-parse@2.1.2: {} + + forwarded@0.2.0: {} + + fresh@0.5.2: {} + + fresh@2.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gaxios@6.7.1: + dependencies: + extend: 3.0.2 + https-proxy-agent: 7.0.6 + is-stream: 2.0.1 + node-fetch: 2.7.0 + uuid: 9.0.1 + transitivePeerDependencies: + - encoding + - supports-color + + gaxios@7.1.4: + dependencies: + extend: 3.0.2 + https-proxy-agent: 7.0.6 + node-fetch: 3.3.2 + transitivePeerDependencies: + - supports-color + + gcp-metadata@6.1.1: + dependencies: + gaxios: 6.7.1 + google-logging-utils: 0.0.2 + json-bigint: 1.0.0 + transitivePeerDependencies: + - encoding + - supports-color + + gcp-metadata@8.1.2: + dependencies: + gaxios: 7.1.4 + google-logging-utils: 1.1.3 + json-bigint: 1.0.0 + transitivePeerDependencies: + - supports-color + + get-caller-file@2.0.5: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-tsconfig@4.13.6: + dependencies: + resolve-pkg-maps: 1.0.0 + + google-auth-library@10.6.2: + dependencies: + base64-js: 1.5.1 + ecdsa-sig-formatter: 1.0.11 + gaxios: 7.1.4 + gcp-metadata: 8.1.2 + google-logging-utils: 1.1.3 + jws: 4.0.1 + transitivePeerDependencies: + - supports-color + + google-logging-utils@0.0.2: {} + + google-logging-utils@1.1.3: {} + + gopd@1.2.0: {} + + has-symbols@1.1.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hono@4.12.8: {} + + hookable@5.5.3: {} + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + + import-in-the-middle@2.0.6: + dependencies: + acorn: 8.16.0 + acorn-import-attributes: 1.9.5(acorn@8.16.0) + cjs-module-lexer: 2.2.0 + module-details-from-path: 1.0.4 + + inherits@2.0.4: {} + + ini@6.0.0: {} + + ip-address@10.1.0: {} + + ipaddr.js@1.9.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-network-error@1.3.1: {} + + is-promise@4.0.0: {} + + is-stream@2.0.1: {} + + isexe@2.0.0: {} + + jiti@2.6.1: {} + + jose@6.2.2: {} + + js-tiktoken@1.0.21: + dependencies: + base64-js: 1.5.1 + + jsesc@3.1.0: {} + + json-bigint@1.0.0: + dependencies: + bignumber.js: 9.3.1 + + json-schema-traverse@1.0.0: {} + + json-schema-typed@8.0.2: {} + + json-schema@0.4.0: {} + + jwa@2.0.1: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + + jws@4.0.1: + dependencies: + jwa: 2.0.1 + safe-buffer: 5.2.1 + + langsmith@0.5.11(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0): + dependencies: + '@types/uuid': 10.0.0 + chalk: 5.6.2 + console-table-printer: 2.15.0 + p-queue: 6.6.2 + semver: 7.7.4 + uuid: 10.0.0 + optionalDependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/exporter-trace-otlp-proto': 0.208.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.6.0(@opentelemetry/api@1.9.0) + ws: 8.19.0 + + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + + lodash.camelcase@4.3.0: {} + + long@5.3.2: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + math-intrinsics@1.1.0: {} + + media-typer@0.3.0: {} + + media-typer@1.1.0: {} + + merge-descriptors@1.0.3: {} + + merge-descriptors@2.0.0: {} + + methods@1.1.2: {} + + mime-db@1.52.0: {} + + mime-db@1.54.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + + mime@1.6.0: {} + + module-details-from-path@1.0.4: {} + + ms@2.0.0: {} + + ms@2.1.3: {} + + mustache@4.2.0: {} + + nanoid@3.3.11: {} + + negotiator@0.6.3: {} + + negotiator@1.0.0: {} + + node-domexception@1.0.0: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + obug@2.1.1: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + oxc-resolver@9.0.2: + optionalDependencies: + '@oxc-resolver/binding-darwin-arm64': 9.0.2 + '@oxc-resolver/binding-darwin-x64': 9.0.2 + '@oxc-resolver/binding-freebsd-x64': 9.0.2 + '@oxc-resolver/binding-linux-arm-gnueabihf': 9.0.2 + '@oxc-resolver/binding-linux-arm64-gnu': 9.0.2 + '@oxc-resolver/binding-linux-arm64-musl': 9.0.2 + '@oxc-resolver/binding-linux-riscv64-gnu': 9.0.2 + '@oxc-resolver/binding-linux-s390x-gnu': 9.0.2 + '@oxc-resolver/binding-linux-x64-gnu': 9.0.2 + '@oxc-resolver/binding-linux-x64-musl': 9.0.2 + '@oxc-resolver/binding-wasm32-wasi': 9.0.2 + '@oxc-resolver/binding-win32-arm64-msvc': 9.0.2 + '@oxc-resolver/binding-win32-x64-msvc': 9.0.2 + + oxc-transform@0.67.0: + optionalDependencies: + '@oxc-transform/binding-darwin-arm64': 0.67.0 + '@oxc-transform/binding-darwin-x64': 0.67.0 + '@oxc-transform/binding-linux-arm-gnueabihf': 0.67.0 + '@oxc-transform/binding-linux-arm64-gnu': 0.67.0 + '@oxc-transform/binding-linux-arm64-musl': 0.67.0 + '@oxc-transform/binding-linux-x64-gnu': 0.67.0 + '@oxc-transform/binding-linux-x64-musl': 0.67.0 + '@oxc-transform/binding-wasm32-wasi': 0.67.0 + '@oxc-transform/binding-win32-arm64-msvc': 0.67.0 + '@oxc-transform/binding-win32-x64-msvc': 0.67.0 + + p-finally@1.0.0: {} + + p-queue@6.6.2: + dependencies: + eventemitter3: 4.0.7 + p-timeout: 3.2.0 + + p-queue@9.1.0: + dependencies: + eventemitter3: 5.0.4 + p-timeout: 7.0.1 + + p-retry@7.1.1: + dependencies: + is-network-error: 1.3.1 + + p-timeout@3.2.0: + dependencies: + p-finally: 1.0.0 + + p-timeout@7.0.1: {} + + parseurl@1.3.3: {} + + path-key@3.1.1: {} + + path-to-regexp@0.1.12: {} + + path-to-regexp@8.3.0: {} + + pathe@2.0.3: {} + + pg-cloudflare@1.3.0: + optional: true + + pg-connection-string@2.12.0: {} + + pg-int8@1.0.1: {} + + pg-pool@3.13.0(pg@8.20.0): + dependencies: + pg: 8.20.0 + + pg-protocol@1.13.0: {} + + pg-types@2.2.0: + dependencies: + pg-int8: 1.0.1 + postgres-array: 2.0.0 + postgres-bytea: 1.0.1 + postgres-date: 1.0.7 + postgres-interval: 1.2.0 + + pg@8.20.0: + dependencies: + pg-connection-string: 2.12.0 + pg-pool: 3.13.0(pg@8.20.0) + pg-protocol: 1.13.0 + pg-types: 2.2.0 + pgpass: 1.0.5 + optionalDependencies: + pg-cloudflare: 1.3.0 + + pgpass@1.0.5: + dependencies: + split2: 4.2.0 + + picocolors@1.1.1: {} + + picomatch@4.0.3: {} + + pkce-challenge@5.0.1: {} + + postcss@8.5.8: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postgres-array@2.0.0: {} + + postgres-bytea@1.0.1: {} + + postgres-date@1.0.7: {} + + postgres-interval@1.2.0: + dependencies: + xtend: 4.0.2 + + prettier@3.8.1: {} + + protobufjs@7.5.4: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/node': 22.19.15 + long: 5.3.2 + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + qs@6.14.2: + dependencies: + side-channel: 1.1.0 + + qs@6.15.0: + dependencies: + side-channel: 1.1.0 + + quansync@1.0.0: {} + + range-parser@1.2.1: {} + + raw-body@2.5.3: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.2 + unpipe: 1.0.0 + + readdirp@4.1.2: {} + + reflect-metadata@0.2.2: {} + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + require-in-the-middle@8.0.1: + dependencies: + debug: 4.4.3 + module-details-from-path: 1.0.4 + transitivePeerDependencies: + - supports-color + + resolve-pkg-maps@1.0.0: {} + + rolldown-plugin-dts@0.9.11(rolldown@1.0.0-beta.8-commit.151352b(typescript@5.9.3))(typescript@5.9.3): + dependencies: + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + ast-kit: 1.4.3 + debug: 4.4.3 + dts-resolver: 1.2.0 + get-tsconfig: 4.13.6 + oxc-transform: 0.67.0 + rolldown: 1.0.0-beta.8-commit.151352b(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + rolldown-vite@7.1.14(@types/node@22.19.15)(jiti@2.6.1): + dependencies: + '@oxc-project/runtime': 0.92.0 + fdir: 6.5.0(picomatch@4.0.3) + lightningcss: 1.32.0 + picomatch: 4.0.3 + postcss: 8.5.8 + rolldown: 1.0.0-beta.41 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 22.19.15 + fsevents: 2.3.3 + jiti: 2.6.1 + + rolldown@1.0.0-beta.41: + dependencies: + '@oxc-project/types': 0.93.0 + '@rolldown/pluginutils': 1.0.0-beta.41 + ansis: 4.2.0 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-beta.41 + '@rolldown/binding-darwin-arm64': 1.0.0-beta.41 + '@rolldown/binding-darwin-x64': 1.0.0-beta.41 + '@rolldown/binding-freebsd-x64': 1.0.0-beta.41 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.41 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.41 + '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.41 + '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.41 + '@rolldown/binding-linux-x64-musl': 1.0.0-beta.41 + '@rolldown/binding-openharmony-arm64': 1.0.0-beta.41 + '@rolldown/binding-wasm32-wasi': 1.0.0-beta.41 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.41 + '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.41 + '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.41 + + rolldown@1.0.0-beta.8-commit.151352b(typescript@5.9.3): + dependencies: + '@oxc-project/types': 0.66.0 + '@valibot/to-json-schema': 1.0.0(valibot@1.0.0(typescript@5.9.3)) + ansis: 3.17.0 + valibot: 1.0.0(typescript@5.9.3) + optionalDependencies: + '@rolldown/binding-darwin-arm64': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-darwin-x64': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-freebsd-x64': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-linux-x64-musl': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-wasm32-wasi': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.8-commit.151352b + transitivePeerDependencies: + - typescript + + rolldown@1.0.0-rc.10: + dependencies: + '@oxc-project/types': 0.120.0 + '@rolldown/pluginutils': 1.0.0-rc.10 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-rc.10 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.10 + '@rolldown/binding-darwin-x64': 1.0.0-rc.10 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.10 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.10 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.10 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.10 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.10 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.10 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.10 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.10 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.10 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.10 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.10 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.10 + + router@2.2.0: + dependencies: + debug: 4.4.3 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.3.0 + transitivePeerDependencies: + - supports-color + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + semver@7.7.4: {} + + send@0.19.2: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.1 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serve-static@1.16.3: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.2 + transitivePeerDependencies: + - supports-color + + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color + + setprototypeof@1.2.0: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + siginfo@2.0.0: {} + + simple-wcswidth@1.1.2: {} + + sisteransi@1.0.5: {} + + source-map-js@1.2.1: {} + + split2@4.2.0: {} + + stackback@0.0.2: {} + + statuses@2.0.2: {} + + std-env@4.0.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + tinybench@2.9.0: {} + + tinyexec@1.0.4: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tinyrainbow@3.1.0: {} + + toidentifier@1.0.1: {} + + tr46@0.0.3: {} + + tsdown@0.9.9(typescript@5.9.3): + dependencies: + ansis: 3.17.0 + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.4.2 + debug: 4.4.3 + diff: 7.0.0 + empathic: 1.1.0 + hookable: 5.5.3 + lightningcss: 1.32.0 + rolldown: 1.0.0-beta.8-commit.151352b(typescript@5.9.3) + rolldown-plugin-dts: 0.9.11(rolldown@1.0.0-beta.8-commit.151352b(typescript@5.9.3))(typescript@5.9.3) + tinyexec: 1.0.4 + tinyglobby: 0.2.15 + unconfig: 7.5.0 + unplugin-lightningcss: 0.3.3 + transitivePeerDependencies: + - '@oxc-project/runtime' + - supports-color + - typescript + + tslib@2.8.1: + optional: true + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + type-is@2.0.1: + dependencies: + content-type: 1.0.5 + media-typer: 1.1.0 + mime-types: 3.0.2 + + typescript@5.9.3: {} + + unconfig-core@7.5.0: + dependencies: + '@quansync/fs': 1.0.0 + quansync: 1.0.0 + + unconfig@7.5.0: + dependencies: + '@quansync/fs': 1.0.0 + defu: 6.1.4 + jiti: 2.6.1 + quansync: 1.0.0 + unconfig-core: 7.5.0 + + undici-types@6.21.0: {} + + unpipe@1.0.0: {} + + unplugin-lightningcss@0.3.3: + dependencies: + lightningcss: 1.32.0 + magic-string: 0.30.21 + unplugin: 2.3.11 + + unplugin@2.3.11: + dependencies: + '@jridgewell/remapping': 2.3.5 + acorn: 8.16.0 + picomatch: 4.0.3 + webpack-virtual-modules: 0.6.2 + + utils-merge@1.0.1: {} + + uuid@10.0.0: {} + + uuid@11.1.0: {} + + uuid@13.0.0: {} + + uuid@9.0.1: {} + + valibot@1.0.0(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + + vary@1.1.2: {} + + vite@8.0.1(@types/node@22.19.15)(jiti@2.6.1): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.3 + postcss: 8.5.8 + rolldown: 1.0.0-rc.10 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 22.19.15 + fsevents: 2.3.3 + jiti: 2.6.1 + + vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@22.19.15)(vite@8.0.1(@types/node@22.19.15)(jiti@2.6.1)): + dependencies: + '@vitest/expect': 4.1.0 + '@vitest/mocker': 4.1.0(vite@8.0.1(@types/node@22.19.15)(jiti@2.6.1)) + '@vitest/pretty-format': 4.1.0 + '@vitest/runner': 4.1.0 + '@vitest/snapshot': 4.1.0 + '@vitest/spy': 4.1.0 + '@vitest/utils': 4.1.0 + es-module-lexer: 2.0.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 4.0.0 + tinybench: 2.9.0 + tinyexec: 1.0.4 + tinyglobby: 0.2.15 + tinyrainbow: 3.1.0 + vite: 8.0.1(@types/node@22.19.15)(jiti@2.6.1) + why-is-node-running: 2.3.0 + optionalDependencies: + '@opentelemetry/api': 1.9.0 + '@types/node': 22.19.15 + transitivePeerDependencies: + - msw + + web-streams-polyfill@3.3.3: {} + + webidl-conversions@3.0.1: {} + + webpack-virtual-modules@0.6.2: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + + ws@8.19.0: {} + + xtend@4.0.2: {} + + y18n@5.0.8: {} + + 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: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + zod-to-json-schema@3.25.1(zod@4.3.6): + dependencies: + zod: 4.3.6 + + zod@4.3.6: {} diff --git a/integrations/appkit-agent/src/agent-plugin/agent-interface.ts b/integrations/appkit-agent/src/agent-plugin/agent-interface.ts new file mode 100644 index 000000000..2e8a65bcd --- /dev/null +++ b/integrations/appkit-agent/src/agent-plugin/agent-interface.ts @@ -0,0 +1,121 @@ +/** + * Agent interface types for the AppKit Agent Plugin. + * + * These types define the contract between the plugin framework and agent + * implementations. They mirror the OpenAI Responses API SSE format without + * requiring the `openai` package as a dependency. + */ + +// --------------------------------------------------------------------------- +// Invoke params +// --------------------------------------------------------------------------- + +export interface InvokeParams { + input: string; + chat_history?: Array<{ role: string; content: string }>; +} + +// --------------------------------------------------------------------------- +// Responses API output types (minimal subset) +// --------------------------------------------------------------------------- + +export interface ResponseOutputTextContent { + type: "output_text"; + text: string; + annotations: unknown[]; +} + +export interface ResponseOutputMessage { + id: string; + type: "message"; + role: "assistant"; + status: "in_progress" | "completed"; + content: ResponseOutputTextContent[]; +} + +export interface ResponseFunctionToolCall { + id: string; + type: "function_call"; + call_id: string; + name: string; + arguments: string; + status: "completed"; +} + +export interface ResponseFunctionCallOutput { + id: string; + type: "function_call_output"; + call_id: string; + output: string; +} + +export type ResponseOutputItem = + | ResponseOutputMessage + | ResponseFunctionToolCall + | ResponseFunctionCallOutput; + +// --------------------------------------------------------------------------- +// Responses API SSE event types +// --------------------------------------------------------------------------- + +export interface ResponseOutputItemAddedEvent { + type: "response.output_item.added"; + item: ResponseOutputItem; + output_index: number; + sequence_number: number; +} + +export interface ResponseOutputItemDoneEvent { + type: "response.output_item.done"; + item: ResponseOutputItem; + output_index: number; + sequence_number: number; +} + +export interface ResponseTextDeltaEvent { + type: "response.output_text.delta"; + item_id: string; + output_index: number; + content_index: number; + delta: string; + sequence_number: number; +} + +export interface ResponseCompletedEvent { + type: "response.completed"; + sequence_number: number; + response: Record; +} + +export interface ResponseErrorEvent { + type: "error"; + error: string; +} + +export interface ResponseFailedEvent { + type: "response.failed"; +} + +export type ResponseStreamEvent = + | ResponseOutputItemAddedEvent + | ResponseOutputItemDoneEvent + | ResponseTextDeltaEvent + | ResponseCompletedEvent + | ResponseErrorEvent + | ResponseFailedEvent; + +// --------------------------------------------------------------------------- +// Agent interface +// --------------------------------------------------------------------------- + +/** + * Contract that agent implementations must fulfil. + * + * The plugin calls `invoke()` for non-streaming requests and `stream()` for + * SSE streaming. Implementations are responsible for translating their SDK's + * output into Responses API types. + */ +export interface AgentInterface { + invoke(params: InvokeParams): Promise; + stream(params: InvokeParams): AsyncGenerator; +} diff --git a/integrations/appkit-agent/src/agent-plugin/agent.ts b/integrations/appkit-agent/src/agent-plugin/agent.ts new file mode 100644 index 000000000..f64b560d3 --- /dev/null +++ b/integrations/appkit-agent/src/agent-plugin/agent.ts @@ -0,0 +1,275 @@ +/** + * AgentPlugin — first-class AppKit plugin for building AI agents. + * + * Provides: + * - POST /api/agent (standard AppKit namespaced route) + * + * Supports two modes: + * 1. Bring-your-own agent via `config.agentInstance` + * 2. Auto-build a ReAct agent from config (model, tools) + * + * Tools can be local (FunctionTool with an execute handler) or hosted on + * Databricks (genie, vector_search_index, custom_mcp_server, external_mcp_server). + * Hosted tools are resolved to managed MCP servers transparently. + */ + +import type express from "express"; +import { Plugin, toPlugin, type PluginManifest } from "@databricks/appkit"; +import { createLogger } from "../logger"; +import type { AgentInterface } from "./agent-interface"; +import type { FunctionTool } from "./function-tool"; +import { functionToolToStructuredTool } from "./function-tool"; +import type { HostedTool } from "./hosted-tools"; +import { isHostedTool, resolveHostedTools } from "./hosted-tools"; +import { createInvokeHandler } from "./invoke-handler"; +import manifest from "./manifest.json"; +import { StandardAgent } from "./standard-agent"; +import type { AgentTool, IAgentConfig } from "./types"; + +const logger = createLogger("agent"); + +const DEFAULT_SYSTEM_PROMPT = + "You are a helpful AI assistant with access to various tools."; + +type ChatDatabricksInstance = InstanceType< + Awaited["ChatDatabricks"] +>; + +export class AgentPlugin extends Plugin { + public name = "agent" as const; + + static manifest = manifest as PluginManifest<"agent">; + + declare protected config: IAgentConfig; + + private agentImpl: AgentInterface | null = null; + private systemPrompt = DEFAULT_SYSTEM_PROMPT; + private mcpClient: { + getTools(): Promise; + close(): Promise; + } | null = null; + + /** Only set when building from config (not agentInstance). */ + private model: ChatDatabricksInstance | null = null; + /** Mutable list of all tools (config + added). Only used when building from config. */ + private toolsList: AgentTool[] = []; + + async setup() { + this.systemPrompt = this.config.systemPrompt ?? DEFAULT_SYSTEM_PROMPT; + + if (this.config.agentInstance) { + this.agentImpl = this.config.agentInstance; + logger.info("AgentPlugin initialized with provided agentInstance"); + return; + } + + const modelName = this.config.model ?? process.env.DATABRICKS_MODEL; + + if (!modelName) { + throw new Error( + "AgentPlugin: model name is required. Set config.model or DATABRICKS_MODEL env var.", + ); + } + + const { ChatDatabricks } = await import("@databricks/langchainjs"); + + this.model = new ChatDatabricks({ + model: modelName, + maxRetries: 3, + }); + + this.toolsList = [...(this.config.tools ?? [])]; + + await this.buildStandardAgent(); + + const { localTools, hostedTools } = AgentPlugin.partitionTools( + this.toolsList, + ); + logger.info( + "AgentPlugin initialized: model=%s localTools=%d hostedTools=%d", + modelName, + localTools.length, + hostedTools.length, + ); + } + + /** + * Partition the tools list into local FunctionTools and hosted tools + * (Databricks-managed MCP services). + */ + private static partitionTools(tools: AgentTool[]): { + localTools: FunctionTool[]; + hostedTools: HostedTool[]; + } { + const localTools: FunctionTool[] = []; + const hostedTools: HostedTool[] = []; + + for (const tool of tools) { + if (isHostedTool(tool)) { + hostedTools.push(tool); + } else { + localTools.push(tool); + } + } + + return { localTools, hostedTools }; + } + + /** + * Builds or rebuilds the ReAct agent from current model and toolsList. + * FunctionTools are converted to the internal tool format; hosted tools + * are resolved to MCP server connections. + */ + private async buildStandardAgent(): Promise { + if (!this.model) return; + + if (this.mcpClient) { + try { + await this.mcpClient.close(); + } catch (err) { + logger.warn("Error closing MCP client during rebuild: %O", err); + } + this.mcpClient = null; + } + + const { localTools, hostedTools } = AgentPlugin.partitionTools( + this.toolsList, + ); + + const tools: unknown[] = []; + + if (hostedTools.length > 0) { + try { + const mcpServers = await resolveHostedTools(hostedTools); + const { buildMCPServerConfig } = + await import("@databricks/langchainjs"); + const mcpServerConfigs = await buildMCPServerConfig(mcpServers); + const { MultiServerMCPClient } = + await import("@langchain/mcp-adapters"); + this.mcpClient = new MultiServerMCPClient({ + mcpServers: mcpServerConfigs, + throwOnLoadError: false, + prefixToolNameWithServerName: true, + }); + const mcpTools = await this.mcpClient.getTools(); + tools.push(...mcpTools); + logger.info( + "Loaded %d MCP tools from %d hosted tool(s)", + mcpTools.length, + hostedTools.length, + ); + } catch (err) { + logger.warn( + "Failed to load hosted tools — continuing without them: %O", + err, + ); + } + } + + tools.push(...localTools.map(functionToolToStructuredTool)); + + const { createReactAgent } = await import("@langchain/langgraph/prebuilt"); + const langGraphAgent = createReactAgent({ + llm: this.model, + tools: tools as any, + }); + + this.agentImpl = new StandardAgent( + langGraphAgent as any, + this.systemPrompt, + ); + } + + /** + * Add tools to the agent after app creation. Only supported when the plugin + * was initialized from config (not when using agentInstance). Rebuilds the + * underlying agent with the new tool set. + * + * Accepts FunctionTool or hosted tool definitions. + */ + async addTools(tools: AgentTool[]): Promise { + if (this.config.agentInstance) { + throw new Error( + "addTools() is not supported when using a custom agentInstance", + ); + } + if (!this.model) { + throw new Error("AgentPlugin not initialized — call setup() first"); + } + + this.toolsList.push(...tools); + await this.buildStandardAgent(); + + logger.info( + "Added %d tool(s); total tools=%d", + tools.length, + this.toolsList.length, + ); + } + + private getAgentImpl(): AgentInterface { + if (!this.agentImpl) { + throw new Error("AgentPlugin not initialized — call setup() first"); + } + return this.agentImpl; + } + + injectRoutes(router: express.Router) { + const handler = createInvokeHandler(() => this.getAgentImpl()); + router.post("/", handler); + this.registerEndpoint("invoke", `/api/${this.name}`); + } + + async abortActiveOperations() { + await super.abortActiveOperations(); + if (this.mcpClient) { + try { + await this.mcpClient.close(); + } catch (err) { + logger.warn("Error closing MCP client: %O", err); + } + } + } + + exports() { + return { + invoke: async ( + messages: { role: string; content: string }[], + ): Promise => { + if (!this.agentImpl) { + throw new Error("AgentPlugin not initialized"); + } + const lastUser = [...messages].reverse().find((m) => m.role === "user"); + const input = lastUser?.content ?? ""; + const chatHistory = messages.slice(0, -1); + const items = await this.agentImpl.invoke({ + input, + chat_history: chatHistory, + }); + const msg = items.find((i) => i.type === "message") as any; + const text = msg?.content?.[0]?.text ?? ""; + return text; + }, + + stream: async function* ( + this: AgentPlugin, + messages: { role: string; content: string }[], + ) { + if (!this.agentImpl) { + throw new Error("AgentPlugin not initialized"); + } + const lastUser = [...messages].reverse().find((m) => m.role === "user"); + const input = lastUser?.content ?? ""; + const chatHistory = messages.slice(0, -1); + yield* this.agentImpl.stream({ + input, + chat_history: chatHistory, + }); + }.bind(this), + + addTools: (tools: AgentTool[]) => this.addTools(tools), + }; + } +} + +export const agent = toPlugin(AgentPlugin); diff --git a/integrations/appkit-agent/src/agent-plugin/function-tool.ts b/integrations/appkit-agent/src/agent-plugin/function-tool.ts new file mode 100644 index 000000000..a1b99ca73 --- /dev/null +++ b/integrations/appkit-agent/src/agent-plugin/function-tool.ts @@ -0,0 +1,142 @@ +/** + * OpenResponses-aligned function tool definition and converter. + * + * Users define tools as plain objects matching the OpenResponses FunctionTool + * schema (type, name, description, parameters as JSON Schema). Internally we + * convert them to LangChain StructuredTool instances for LangGraph. + */ + +import type { StructuredToolInterface } from "@langchain/core/tools"; +import { DynamicStructuredTool } from "@langchain/core/tools"; +import { z } from "zod"; + +// --------------------------------------------------------------------------- +// Public type — matches OpenResponses FunctionToolParam + execute handler +// --------------------------------------------------------------------------- + +export interface FunctionTool { + type: "function"; + name: string; + description?: string | null; + /** JSON Schema object describing the tool's parameters. */ + parameters?: Record | null; + strict?: boolean | null; + /** Handler invoked when the model calls this tool. */ + execute: (args: Record) => Promise | string; +} + +// --------------------------------------------------------------------------- +// Type guard +// --------------------------------------------------------------------------- + +export function isFunctionTool(t: unknown): t is FunctionTool { + return ( + typeof t === "object" && + t !== null && + (t as any).type === "function" && + typeof (t as any).name === "string" && + typeof (t as any).execute === "function" + ); +} + +// --------------------------------------------------------------------------- +// Converter: FunctionTool → LangChain StructuredToolInterface +// --------------------------------------------------------------------------- + +/** + * Converts a JSON Schema properties object to a Zod schema. + * + * Supports the primitive types models actually use for tool parameters: + * string, number, integer, boolean, array, and object. Anything else falls + * back to z.any(). + */ +function jsonSchemaPropertiesToZod( + properties: Record, + required: string[] = [], +): z.ZodObject { + const shape: Record = {}; + + for (const [key, prop] of Object.entries(properties)) { + let field: z.ZodTypeAny; + + switch (prop.type) { + case "string": + field = z.string(); + break; + case "number": + field = z.number(); + break; + case "integer": + field = z.number().int(); + break; + case "boolean": + field = z.boolean(); + break; + case "array": + field = z.array(z.any()); + break; + case "object": + if (prop.properties) { + field = jsonSchemaPropertiesToZod( + prop.properties, + prop.required ?? [], + ); + } else { + field = z.record(z.string(), z.any()); + } + break; + default: + field = z.any(); + } + + if (prop.description) { + field = field.describe(prop.description); + } + + if (prop.enum && Array.isArray(prop.enum) && prop.enum.length > 0) { + field = z.enum(prop.enum as [string, ...string[]]); + if (prop.description) { + field = field.describe(prop.description); + } + } + + if (!required.includes(key)) { + field = field.optional(); + } + + shape[key] = field; + } + + return z.object(shape); +} + +/** + * Convert a single FunctionTool to a LangChain DynamicStructuredTool. + */ +export function functionToolToStructuredTool( + tool: FunctionTool, +): StructuredToolInterface { + const params = tool.parameters as Record | null | undefined; + const schema = params?.properties + ? jsonSchemaPropertiesToZod(params.properties, params.required ?? []) + : z.object({}); + + return new DynamicStructuredTool({ + name: tool.name, + description: tool.description ?? "", + schema, + func: async (args: Record) => { + const result = await tool.execute(args); + return result; + }, + }); +} + +/** + * Convert an array of FunctionTool definitions to LangChain StructuredToolInterface[]. + */ +export function functionToolsToStructuredTools( + tools: FunctionTool[], +): StructuredToolInterface[] { + return tools.map(functionToolToStructuredTool); +} diff --git a/integrations/appkit-agent/src/agent-plugin/hosted-tools.ts b/integrations/appkit-agent/src/agent-plugin/hosted-tools.ts new file mode 100644 index 000000000..af230803b --- /dev/null +++ b/integrations/appkit-agent/src/agent-plugin/hosted-tools.ts @@ -0,0 +1,107 @@ +/** + * OpenResponses-style hosted tool definitions for Databricks services. + * + * These types follow the OpenResponses convention of discriminating on `type`. + * Internally, each hosted tool is resolved to a DatabricksMCPServer instance + * so the agent can call managed MCP endpoints on the workspace. + */ + +// --------------------------------------------------------------------------- +// Hosted tool type definitions +// --------------------------------------------------------------------------- + +export interface GenieTool { + type: "genie-space"; + genie_space: { id: string }; +} + +export interface VectorSearchIndexTool { + type: "vector_search_index"; + vector_search_index: { name: string }; +} + +export interface CustomMcpServerTool { + type: "custom_mcp_server"; + custom_mcp_server: { app_name: string; app_url: string }; +} + +export interface ExternalMcpServerTool { + type: "external_mcp_server"; + external_mcp_server: { connection_name: string }; +} + +export type HostedTool = + | GenieTool + | VectorSearchIndexTool + | CustomMcpServerTool + | ExternalMcpServerTool; + +// --------------------------------------------------------------------------- +// Type guard +// --------------------------------------------------------------------------- + +const HOSTED_TOOL_TYPES = new Set([ + "genie-space", + "vector_search_index", + "custom_mcp_server", + "external_mcp_server", +]); + +export function isHostedTool(t: unknown): t is HostedTool { + return ( + typeof t === "object" && + t !== null && + HOSTED_TOOL_TYPES.has((t as any).type) + ); +} + +// --------------------------------------------------------------------------- +// Resolver: HostedTool → DatabricksMCPServer +// --------------------------------------------------------------------------- + +/** + * Resolve an array of HostedTool definitions into DatabricksMCPServer instances. + * + * Uses factory methods from `@databricks/langchainjs` where available, and + * falls back to raw DatabricksMCPServer construction for tool types that + * map to known managed MCP API paths. + */ +export async function resolveHostedTools( + tools: HostedTool[], +): Promise[]> { + const { DatabricksMCPServer } = await import("@databricks/langchainjs"); + + return tools.map((tool) => { + switch (tool.type) { + case "genie-space": + return DatabricksMCPServer.fromGenieSpace(tool.genie_space.id); + + case "vector_search_index": { + const parts = tool.vector_search_index.name.split("."); + if (parts.length !== 3) { + throw new Error( + `vector_search_index name must be "catalog.schema.index", got "${tool.vector_search_index.name}"`, + ); + } + const [catalog, schema, index] = parts; + return DatabricksMCPServer.fromVectorSearch(catalog, schema, index); + } + + case "custom_mcp_server": + return new DatabricksMCPServer({ + name: `mcp-app-${tool.custom_mcp_server.app_name}`, + path: `/apps/${tool.custom_mcp_server.app_url}`, + }); + + case "external_mcp_server": + return new DatabricksMCPServer({ + name: `mcp-ext-${tool.external_mcp_server.connection_name}`, + path: `/api/2.0/mcp/connections/${tool.external_mcp_server.connection_name}`, + }); + + default: { + throw new Error(`Unknown hosted tool type: ${(tool as any).type}`); + } + } + }); +} diff --git a/integrations/appkit-agent/src/agent-plugin/invoke-handler.ts b/integrations/appkit-agent/src/agent-plugin/invoke-handler.ts new file mode 100644 index 000000000..20af57983 --- /dev/null +++ b/integrations/appkit-agent/src/agent-plugin/invoke-handler.ts @@ -0,0 +1,160 @@ +/** + * Responses API invoke handler for the agent plugin. + * + * Accepts Responses API request format, parses it into InvokeParams, then + * delegates to AgentInterface.stream() / AgentInterface.invoke(). The handler + * is a pure pass-through — all SSE event shaping happens inside the agent. + */ + +import type express from "express"; +import { z } from "zod"; +import type { AgentInterface } from "./agent-interface"; + +const responsesRequestSchema = z.object({ + input: z.union([ + z.string(), + z.array( + z.union([ + z.object({ + role: z.enum(["user", "assistant", "system"]), + content: z.union([ + z.string(), + z.array( + z.union([ + z.object({ type: z.string(), text: z.string() }).passthrough(), + z.object({ type: z.string() }).passthrough(), + ]), + ), + ]), + }), + z.object({ type: z.string() }).passthrough(), + ]), + ), + ]), + stream: z.boolean().optional().default(true), + model: z.string().optional(), +}); + +/** + * Flatten a Responses API message to a plain `{ role, content }` object. + * Handles function_call / function_call_output items and array content. + */ +function flattenHistoryItem(item: any): { role: string; content: string } { + if (item.type === "function_call") { + return { + role: "assistant", + content: `[Tool Call: ${item.name}(${item.arguments})]`, + }; + } + if (item.type === "function_call_output") { + return { role: "assistant", content: `[Tool Result: ${item.output}]` }; + } + + if (Array.isArray(item.content)) { + const textParts = item.content + .filter( + (p: any) => + p.type === "input_text" || + p.type === "output_text" || + p.type === "text", + ) + .map((p: any) => p.text); + + const toolParts = item.content + .filter( + (p: any) => + p.type === "function_call" || p.type === "function_call_output", + ) + .map((p: any) => + p.type === "function_call" + ? `[Tool Call: ${p.name}(${JSON.stringify(p.arguments)})]` + : `[Tool Result: ${p.output}]`, + ); + + const allParts = [...textParts, ...toolParts].filter((p) => p.length > 0); + return { ...item, content: allParts.join("\n") }; + } + + return { role: item.role ?? "user", content: item.content ?? "" }; +} + +/** + * Create an Express handler that invokes the agent via the AgentInterface + * and streams/returns the response in Responses API format. + */ +export function createInvokeHandler( + getAgent: () => AgentInterface, +): express.RequestHandler { + return async (req: express.Request, res: express.Response) => { + try { + const parsed = responsesRequestSchema.safeParse(req.body); + if (!parsed.success) { + res.status(400).json({ + error: "Invalid request format", + details: parsed.error.format(), + }); + return; + } + + const { stream } = parsed.data; + + const input = + typeof parsed.data.input === "string" + ? [{ role: "user" as const, content: parsed.data.input }] + : parsed.data.input; + + const userMessages = input.filter((msg: any) => msg.role === "user"); + if (userMessages.length === 0) { + res.status(400).json({ error: "No user message found in input" }); + return; + } + + const lastUserMessage = userMessages[userMessages.length - 1]; + + let userInput: string; + if (Array.isArray(lastUserMessage.content)) { + userInput = lastUserMessage.content + .filter( + (part: any) => part.type === "input_text" || part.type === "text", + ) + .map((part: any) => part.text) + .join("\n"); + } else { + userInput = lastUserMessage.content as string; + } + + const chatHistory = input.slice(0, -1).map(flattenHistoryItem); + + const agentParams = { input: userInput, chat_history: chatHistory }; + const agent = getAgent(); + + if (stream) { + res.setHeader("Content-Type", "text/event-stream"); + res.setHeader("Cache-Control", "no-cache"); + res.setHeader("Connection", "keep-alive"); + + try { + for await (const event of agent.stream(agentParams)) { + res.write(`data: ${JSON.stringify(event)}\n\n`); + } + res.write("data: [DONE]\n\n"); + res.end(); + } catch (err: unknown) { + const message = err instanceof Error ? err.message : String(err); + res.write( + `data: ${JSON.stringify({ type: "error", error: message })}\n\n`, + ); + res.write(`data: ${JSON.stringify({ type: "response.failed" })}\n\n`); + res.write("data: [DONE]\n\n"); + res.end(); + } + } else { + const items = await agent.invoke(agentParams); + res.json({ output: items }); + } + } catch (err: unknown) { + const message = err instanceof Error ? err.message : String(err); + res.status(500).json({ error: "Internal server error", message }); + } + }; +} diff --git a/integrations/appkit-agent/src/agent-plugin/manifest.json b/integrations/appkit-agent/src/agent-plugin/manifest.json new file mode 100644 index 000000000..ee10116ef --- /dev/null +++ b/integrations/appkit-agent/src/agent-plugin/manifest.json @@ -0,0 +1,23 @@ +{ + "name": "agent", + "displayName": "Agent Plugin", + "description": "LangChain/LangGraph AI agent with streaming Responses API and MCP tool support", + "resources": { + "required": [ + { + "type": "serving_endpoint", + "alias": "Model Endpoint", + "resourceKey": "agent-model-endpoint", + "description": "Databricks model serving endpoint for the agent LLM", + "permission": "CAN_QUERY", + "fields": { + "name": { + "env": "DATABRICKS_MODEL", + "description": "Model serving endpoint name" + } + } + } + ], + "optional": [] + } +} diff --git a/integrations/appkit-agent/src/agent-plugin/standard-agent.ts b/integrations/appkit-agent/src/agent-plugin/standard-agent.ts new file mode 100644 index 000000000..44335245e --- /dev/null +++ b/integrations/appkit-agent/src/agent-plugin/standard-agent.ts @@ -0,0 +1,231 @@ +/** + * StandardAgent — LangGraph wrapper implementing AgentInterface. + * + * Wraps a LangGraph `createReactAgent` instance and translates its stream + * events into Responses API SSE format. If you swap LangGraph for another + * SDK, provide your own AgentInterface implementation instead. + */ + +import { randomUUID } from "node:crypto"; +import type { BaseMessage } from "@langchain/core/messages"; +import { HumanMessage, SystemMessage } from "@langchain/core/messages"; +import type { + AgentInterface, + InvokeParams, + ResponseFunctionToolCall, + ResponseOutputItem, + ResponseOutputMessage, + ResponseStreamEvent, +} from "./agent-interface"; + +/** + * Minimal interface for the LangGraph agent returned by createReactAgent. + */ +interface LangGraphAgent { + invoke(input: { + messages: BaseMessage[]; + }): Promise<{ messages: BaseMessage[] }>; + streamEvents( + input: { messages: BaseMessage[] }, + options: { version: "v1" | "v2" }, + ): AsyncIterable<{ + event: string; + name: string; + run_id: string; + data?: any; + }>; +} + +function convertToBaseMessages(messages: any[]): BaseMessage[] { + return messages.map((msg) => { + if (msg instanceof HumanMessage || msg instanceof SystemMessage) { + return msg; + } + const content = msg.content || ""; + switch (msg.role) { + case "user": + return new HumanMessage(content); + case "assistant": + return { role: "assistant", content } as any; + case "system": + return new SystemMessage(content); + default: + return new HumanMessage(content); + } + }); +} + +/** + * Built-in {@link AgentInterface} implementation that wraps a LangGraph + * `createReactAgent` and translates its stream events into Responses API + * SSE format. Use this as the default agent unless you need a custom + * implementation for a different LLM SDK. + */ +export class StandardAgent implements AgentInterface { + constructor( + private agent: LangGraphAgent, + private systemPrompt: string, + ) {} + + async invoke(params: InvokeParams): Promise { + const { input, chat_history = [] } = params; + + const messages: BaseMessage[] = [ + new SystemMessage(this.systemPrompt), + ...convertToBaseMessages(chat_history), + new HumanMessage(input), + ]; + + const result = await this.agent.invoke({ messages }); + const finalMessages = result.messages || []; + const lastMessage = finalMessages[finalMessages.length - 1]; + const text = + typeof lastMessage?.content === "string" ? lastMessage.content : ""; + + const outputMessage: ResponseOutputMessage = { + id: `msg_${randomUUID()}`, + type: "message", + role: "assistant", + status: "completed", + content: [{ type: "output_text", text, annotations: [] }], + }; + + return [outputMessage]; + } + + async *stream(params: InvokeParams): AsyncGenerator { + const { input, chat_history = [] } = params; + + const messages: BaseMessage[] = [ + new SystemMessage(this.systemPrompt), + ...convertToBaseMessages(chat_history), + new HumanMessage(input), + ]; + + const toolCallIds = new Map(); + let seqNum = 0; + let outputIndex = 0; + const textItemId = `msg_${randomUUID()}`; + let textOutputIndex = -1; + + const eventStream = this.agent.streamEvents( + { messages }, + { version: "v2" }, + ); + + for await (const event of eventStream) { + if (event.event === "on_tool_start") { + const callId = `call_${randomUUID()}`; + toolCallIds.set(`${event.name}_${event.run_id}`, callId); + + const fcItem: ResponseFunctionToolCall = { + id: `fc_${randomUUID()}`, + call_id: callId, + name: event.name, + arguments: JSON.stringify(event.data?.input || {}), + type: "function_call", + status: "completed", + }; + + const currentIndex = outputIndex++; + + yield { + type: "response.output_item.added", + item: fcItem, + output_index: currentIndex, + sequence_number: seqNum++, + }; + + yield { + type: "response.output_item.done", + item: fcItem, + output_index: currentIndex, + sequence_number: seqNum++, + }; + } + + if (event.event === "on_tool_end") { + const toolKey = `${event.name}_${event.run_id}`; + const callId = toolCallIds.get(toolKey) || `call_${randomUUID()}`; + toolCallIds.delete(toolKey); + + const outputItem = { + id: `fco_${randomUUID()}`, + call_id: callId, + output: JSON.stringify(event.data?.output || ""), + type: "function_call_output" as const, + }; + + const currentIndex = outputIndex++; + + yield { + type: "response.output_item.added", + item: outputItem, + output_index: currentIndex, + sequence_number: seqNum++, + }; + + yield { + type: "response.output_item.done", + item: outputItem, + output_index: currentIndex, + sequence_number: seqNum++, + }; + } + + if (event.event === "on_chat_model_stream") { + const content = event.data?.chunk?.content; + if (content && typeof content === "string") { + if (textOutputIndex === -1) { + textOutputIndex = outputIndex++; + + const msgItem: ResponseOutputMessage = { + id: textItemId, + type: "message", + role: "assistant", + status: "in_progress", + content: [], + }; + yield { + type: "response.output_item.added", + item: msgItem, + output_index: textOutputIndex, + sequence_number: seqNum++, + }; + } + + yield { + type: "response.output_text.delta", + item_id: textItemId, + output_index: textOutputIndex, + content_index: 0, + delta: content, + sequence_number: seqNum++, + }; + } + } + } + + if (textOutputIndex !== -1) { + const msgItem: ResponseOutputMessage = { + id: textItemId, + type: "message", + role: "assistant", + status: "completed", + content: [], + }; + yield { + type: "response.output_item.done", + item: msgItem, + output_index: textOutputIndex, + sequence_number: seqNum++, + }; + } + + yield { + type: "response.completed", + sequence_number: seqNum++, + response: {}, + }; + } +} diff --git a/integrations/appkit-agent/src/agent-plugin/types.ts b/integrations/appkit-agent/src/agent-plugin/types.ts new file mode 100644 index 000000000..b8fc1eb2d --- /dev/null +++ b/integrations/appkit-agent/src/agent-plugin/types.ts @@ -0,0 +1,41 @@ +import type { BasePluginConfig } from "@databricks/appkit"; +import type { AgentInterface } from "./agent-interface"; +import type { FunctionTool } from "./function-tool"; +import type { HostedTool } from "./hosted-tools"; + +/** + * A tool that can be registered with the agent plugin. + * + * - `FunctionTool`: OpenResponses-aligned plain object with JSON Schema parameters and an execute handler. + * - `HostedTool`: Databricks-hosted tool (genie, vector_search_index, custom_mcp_server, external_mcp_server). + */ +export type AgentTool = FunctionTool | HostedTool; + +export interface IAgentConfig extends BasePluginConfig { + /** + * Pre-built agent implementing AgentInterface. + * When provided the plugin skips internal LangGraph setup and delegates + * directly to this instance. Use this to bring your own agent + * implementation or a different LangChain variant. + */ + agentInstance?: AgentInterface; + + /** + * Databricks model serving endpoint name (e.g. "databricks-claude-sonnet-4-5"). + * Falls back to DATABRICKS_MODEL env var. + * Ignored when `agentInstance` is provided. + */ + model?: string; + + /** System prompt injected at the start of every conversation */ + systemPrompt?: string; + + /** + * Tools to register with the agent. Accepts: + * - OpenResponses-aligned `FunctionTool` objects (local tool with execute handler) + * - Databricks hosted tools (`genie`, `vector_search_index`, `custom_mcp_server`, `external_mcp_server`) + * + * Ignored when `agentInstance` is provided. + */ + tools?: AgentTool[]; +} diff --git a/integrations/appkit-agent/src/index.ts b/integrations/appkit-agent/src/index.ts new file mode 100644 index 000000000..016c89a2c --- /dev/null +++ b/integrations/appkit-agent/src/index.ts @@ -0,0 +1,23 @@ +export { agent } from "./agent-plugin/agent"; +export type { + AgentInterface, + InvokeParams, + ResponseFunctionCallOutput, + ResponseFunctionToolCall, + ResponseOutputItem, + ResponseOutputMessage, + ResponseStreamEvent, +} from "./agent-plugin/agent-interface"; +export type { FunctionTool } from "./agent-plugin/function-tool"; +export { isFunctionTool } from "./agent-plugin/function-tool"; +export type { + CustomMcpServerTool, + ExternalMcpServerTool, + GenieTool, + HostedTool, + VectorSearchIndexTool, +} from "./agent-plugin/hosted-tools"; +export { isHostedTool } from "./agent-plugin/hosted-tools"; +export { createInvokeHandler } from "./agent-plugin/invoke-handler"; +export { StandardAgent } from "./agent-plugin/standard-agent"; +export type { AgentTool, IAgentConfig } from "./agent-plugin/types"; diff --git a/integrations/appkit-agent/src/logger.ts b/integrations/appkit-agent/src/logger.ts new file mode 100644 index 000000000..4835c2cad --- /dev/null +++ b/integrations/appkit-agent/src/logger.ts @@ -0,0 +1,14 @@ +interface Logger { + info(message: string, ...args: unknown[]): void; + warn(message: string, ...args: unknown[]): void; + error(message: string, ...args: unknown[]): void; +} + +export function createLogger(scope: string): Logger { + const prefix = `[${scope}]`; + return { + info: (message, ...args) => console.log(prefix, message, ...args), + warn: (message, ...args) => console.warn(prefix, message, ...args), + error: (message, ...args) => console.error(prefix, message, ...args), + }; +} diff --git a/integrations/appkit-agent/src/tests/agent-plugin/agent.intg.test.ts b/integrations/appkit-agent/src/tests/agent-plugin/agent.intg.test.ts new file mode 100644 index 000000000..0aeec05a4 --- /dev/null +++ b/integrations/appkit-agent/src/tests/agent-plugin/agent.intg.test.ts @@ -0,0 +1,298 @@ +/** + * Integration test: boots the plugin with a StubAgent, mounts the route + * handler, and drives it end-to-end through the HTTP layer — verifying + * the full lifecycle from request parsing through SSE streaming to the + * exports() convenience API. + */ + +import { describe, expect, test, vi, beforeEach } from "vitest"; +import type { + AgentInterface, + InvokeParams, + ResponseStreamEvent, + ResponseOutputItem, + ResponseOutputItemAddedEvent, +} from "../../agent-plugin/agent-interface"; +import { StubAgent } from "./stub-agent"; +import { + createMockRequest, + createMockResponse, + createMockRouter, +} from "./test-helpers"; + +vi.mock("@databricks/appkit", () => { + class Plugin { + protected config: T; + constructor(config: T) { + this.config = config; + } + registerEndpoint(_name: string, _path: string) {} + async abortActiveOperations() {} + } + + function toPlugin(PluginClass: new (config: unknown) => unknown) { + return (config: unknown) => { + const instance = new PluginClass(config) as Record; + return { name: instance.name, instance }; + }; + } + + return { Plugin, toPlugin }; +}); + +import { AgentPlugin } from "../../agent-plugin/agent"; + +function makeRes() { + const res = createMockResponse() as Record; + const chunks: string[] = []; + (res.write as ReturnType).mockImplementation( + (chunk: string) => { + chunks.push(chunk); + return true; + }, + ); + (res as Record).__chunks = chunks; + return res; +} + +function parseSSE(res: Record): { + events: ResponseStreamEvent[]; + fullText: string; +} { + const chunks = res.__chunks as string[]; + const events: ResponseStreamEvent[] = []; + let fullText = ""; + + for (const chunk of chunks) { + for (const line of chunk.split("\n")) { + if (line.startsWith("data: ") && line !== "data: [DONE]") { + try { + const data = JSON.parse(line.slice(6)); + events.push(data); + if (data.type === "response.output_text.delta") { + fullText += data.delta; + } + } catch { + /* skip non-JSON */ + } + } + } + } + return { events, fullText }; +} + +describe("Agent plugin integration", () => { + let plugin: AgentPlugin; + let handler: (...args: unknown[]) => Promise; + + beforeEach(async () => { + plugin = new AgentPlugin({ agentInstance: new StubAgent() }); + await plugin.setup(); + + const { router, getHandler } = createMockRouter(); + plugin.injectRoutes(router as never); + handler = getHandler("POST", "/") as (...args: unknown[]) => Promise; + expect(handler).toBeDefined(); + }); + + test("full streaming round-trip: request → SSE events → [DONE]", async () => { + const req = createMockRequest({ + body: { + input: [{ role: "user", content: "What is 2+2?" }], + stream: true, + }, + }); + const res = makeRes(); + + await handler(req, res, vi.fn()); + + expect(res.setHeader).toHaveBeenCalledWith( + "Content-Type", + "text/event-stream", + ); + + const { events, fullText } = parseSSE(res); + + expect(fullText).toBe("Echo: What is 2+2?"); + + const types = events.map((e) => e.type); + expect(types).toContain("response.output_item.added"); + expect(types).toContain("response.output_text.delta"); + expect(types).toContain("response.output_item.done"); + expect(types).toContain("response.completed"); + + const lastChunk = (res.__chunks as string[]).at(-1); + expect(lastChunk).toContain("[DONE]"); + expect(res.end).toHaveBeenCalled(); + + const addedEvt = events.find( + (e) => e.type === "response.output_item.added", + ) as ResponseOutputItemAddedEvent | undefined; + expect(addedEvt).toBeDefined(); + expect(addedEvt?.item).toMatchObject({ + type: "message", + role: "assistant", + }); + }); + + test("non-streaming round-trip returns JSON with output items", async () => { + const req = createMockRequest({ + body: { + input: [{ role: "user", content: "Hello" }], + stream: false, + }, + }); + const res = makeRes(); + + await handler(req, res, vi.fn()); + + const callArgs = (res.json as ReturnType).mock.calls[0][0]; + expect(callArgs.output).toHaveLength(1); + expect(callArgs.output[0].type).toBe("message"); + expect(callArgs.output[0].content[0].text).toBe("Echo: Hello"); + }); + + test("multi-turn conversation preserves chat history", async () => { + const invokeSpy = vi.fn( + async (params: InvokeParams): Promise => { + return [ + { + id: "msg_1", + type: "message", + role: "assistant", + status: "completed", + content: [ + { + type: "output_text", + text: `got ${params.chat_history?.length ?? 0} history items`, + annotations: [], + }, + ], + }, + ]; + }, + ); + + const spyAgent: AgentInterface = { + invoke: invokeSpy, + stream: new StubAgent().stream, + }; + + const p = new AgentPlugin({ agentInstance: spyAgent }); + await p.setup(); + const { router, getHandler } = createMockRouter(); + p.injectRoutes(router as never); + const h = getHandler("POST", "/") as typeof handler; + + const req = createMockRequest({ + body: { + input: [ + { role: "user", content: "First" }, + { role: "assistant", content: "Reply 1" }, + { role: "user", content: "Second" }, + { role: "assistant", content: "Reply 2" }, + { role: "user", content: "Third" }, + ], + stream: false, + }, + }); + const res = makeRes(); + + await h(req, res, vi.fn()); + + expect(invokeSpy).toHaveBeenCalledOnce(); + const [params] = invokeSpy.mock.calls[0]; + expect(params.input).toBe("Third"); + expect(params.chat_history).toHaveLength(4); + + const callArgs = (res.json as ReturnType).mock.calls[0][0]; + expect(callArgs.output[0].content[0].text).toBe("got 4 history items"); + }); + + test("exports().invoke and exports().stream agree on output", async () => { + const exported = plugin.exports(); + + const invokeResult = await exported.invoke([ + { role: "user", content: "sync test" }, + ]); + + const streamEvents: ResponseStreamEvent[] = []; + let streamedText = ""; + for await (const event of exported.stream([ + { role: "user", content: "sync test" }, + ])) { + streamEvents.push(event); + if (event.type === "response.output_text.delta") { + streamedText += event.delta; + } + } + + expect(invokeResult).toBe("Echo: sync test"); + expect(streamedText).toBe("Echo: sync test"); + expect(streamEvents.some((e) => e.type === "response.completed")).toBe( + true, + ); + }); + + test("streaming error mid-flight emits error + failed events", async () => { + let callCount = 0; + const failingAgent: AgentInterface = { + invoke: vi.fn(), + async *stream(_params) { + callCount++; + yield { + type: "response.output_item.added" as const, + item: { + id: "msg_err", + type: "message" as const, + role: "assistant" as const, + status: "in_progress" as const, + content: [], + }, + output_index: 0, + sequence_number: 0, + }; + throw new Error("Simulated LLM failure"); + }, + }; + + const plugin = new AgentPlugin({ agentInstance: failingAgent }); + await plugin.setup(); + const { router, getHandler } = createMockRouter(); + plugin.injectRoutes(router as never); + const h = getHandler("POST", "/") as typeof handler; + + const req = createMockRequest({ + body: { + input: [{ role: "user", content: "trigger error" }], + stream: true, + }, + }); + const res = makeRes(); + + await h(req, res, vi.fn()); + + const { events } = parseSSE(res); + const errorEvt = events.find((e) => e.type === "error"); + const failedEvt = events.find((e) => e.type === "response.failed"); + expect(errorEvt).toBeDefined(); + expect(errorEvt?.type === "error" ? errorEvt.error : undefined).toContain( + "Simulated LLM failure", + ); + expect(failedEvt).toBeDefined(); + expect(res.end).toHaveBeenCalled(); + expect(callCount).toBe(1); + }); + + test("invalid request returns 400 without crashing the handler", async () => { + const req = createMockRequest({ body: { garbage: true } }); + const res = makeRes(); + + await handler(req, res, vi.fn()); + + expect(res.status).toHaveBeenCalledWith(400); + expect(res.json).toHaveBeenCalledWith( + expect.objectContaining({ error: expect.any(String) }), + ); + }); +}); diff --git a/integrations/appkit-agent/src/tests/agent-plugin/agent.test.ts b/integrations/appkit-agent/src/tests/agent-plugin/agent.test.ts new file mode 100644 index 000000000..98dd669b6 --- /dev/null +++ b/integrations/appkit-agent/src/tests/agent-plugin/agent.test.ts @@ -0,0 +1,195 @@ +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; +import type { IAgentConfig } from "../../agent-plugin/types"; +import { StubAgent } from "./stub-agent"; +import { createMockRouter } from "./test-helpers"; + +// --------------------------------------------------------------------------- +// Mock @databricks/appkit — provide minimal Plugin base class + toPlugin +// --------------------------------------------------------------------------- + +vi.mock("@databricks/appkit", () => { + class Plugin { + protected config: T; + constructor(config: T) { + this.config = config; + } + registerEndpoint(_name: string, _path: string) {} + async abortActiveOperations() {} + } + + function toPlugin(PluginClass: any) { + return (config: any) => { + const instance = new PluginClass(config); + return { name: instance.name, PluginClass, config }; + }; + } + + return { Plugin, toPlugin }; +}); + +import { AgentPlugin, agent } from "../../agent-plugin/agent"; + +describe("AgentPlugin", () => { + const savedEnv = { ...process.env }; + + beforeEach(() => { + delete process.env.DATABRICKS_MODEL; + }); + + afterEach(() => { + process.env = { ...savedEnv }; + }); + + test("agent factory produces correct plugin data", () => { + const pluginData = agent({ agentInstance: new StubAgent() }); + expect(pluginData.name).toBe("agent"); + }); + + test("plugin has correct manifest", () => { + expect(AgentPlugin.manifest).toBeDefined(); + expect(AgentPlugin.manifest.name).toBe("agent"); + expect(AgentPlugin.manifest.resources.required).toHaveLength(1); + expect(AgentPlugin.manifest.resources.required[0].type).toBe( + "serving_endpoint", + ); + }); + + test("plugin instance has correct name", () => { + const config: IAgentConfig = { agentInstance: new StubAgent() }; + const plugin = new AgentPlugin(config); + expect(plugin.name).toBe("agent"); + }); + + describe("setup()", () => { + test("uses provided agentInstance", async () => { + const stub = new StubAgent(); + const config: IAgentConfig = { agentInstance: stub }; + const plugin = new AgentPlugin(config); + + await plugin.setup(); + + const exported = plugin.exports(); + const result = await exported.invoke([{ role: "user", content: "hi" }]); + expect(result).toContain("Echo: hi"); + }); + + test("throws when no model and no agentInstance", async () => { + const config: IAgentConfig = {}; + const plugin = new AgentPlugin(config); + + await expect(plugin.setup()).rejects.toThrow("model name is required"); + }); + + test("resolves model from env var when not in config", async () => { + process.env.DATABRICKS_MODEL = "test-model"; + + const config: IAgentConfig = {}; + const plugin = new AgentPlugin(config); + + // Will fail at dynamic import of @databricks/langchainjs, but should + // get past the model name check + try { + await plugin.setup(); + } catch (e: any) { + expect(e.message).not.toContain("model name is required"); + } + + delete process.env.DATABRICKS_MODEL; + }); + }); + + describe("injectRoutes()", () => { + test("registers POST handler on router", () => { + const stub = new StubAgent(); + const config: IAgentConfig = { agentInstance: stub }; + const plugin = new AgentPlugin(config); + + const { router } = createMockRouter(); + plugin.injectRoutes(router as any); + + expect(router.post).toHaveBeenCalledWith("/", expect.any(Function)); + }); + }); + + describe("exports()", () => { + test("returns invoke, stream, and addTools methods", async () => { + const stub = new StubAgent(); + const config: IAgentConfig = { agentInstance: stub }; + const plugin = new AgentPlugin(config); + await plugin.setup(); + + const exported = plugin.exports(); + + expect(typeof exported.invoke).toBe("function"); + expect(typeof exported.stream).toBe("function"); + expect(typeof exported.addTools).toBe("function"); + }); + + test("invoke returns text from agent response", async () => { + const stub = new StubAgent(); + const config: IAgentConfig = { agentInstance: stub }; + const plugin = new AgentPlugin(config); + await plugin.setup(); + + const result = await plugin + .exports() + .invoke([{ role: "user", content: "test message" }]); + + expect(result).toBe("Echo: test message"); + }); + + test("stream yields ResponseStreamEvents", async () => { + const stub = new StubAgent(); + const config: IAgentConfig = { agentInstance: stub }; + const plugin = new AgentPlugin(config); + await plugin.setup(); + + const events: any[] = []; + for await (const event of plugin + .exports() + .stream([{ role: "user", content: "hello" }])) { + events.push(event); + } + + expect(events.length).toBeGreaterThan(0); + const deltaEvent = events.find( + (e) => e.type === "response.output_text.delta", + ); + expect(deltaEvent).toBeDefined(); + expect(deltaEvent.delta).toContain("Echo: hello"); + + const completedEvent = events.find( + (e) => e.type === "response.completed", + ); + expect(completedEvent).toBeDefined(); + }); + + test("throws when not initialized", async () => { + const config: IAgentConfig = { agentInstance: new StubAgent() }; + const plugin = new AgentPlugin(config); + + await expect( + plugin.exports().invoke([{ role: "user", content: "hi" }]), + ).rejects.toThrow("not initialized"); + }); + }); + + describe("addTools()", () => { + test("throws when using agentInstance mode", async () => { + const stub = new StubAgent(); + const config: IAgentConfig = { agentInstance: stub }; + const plugin = new AgentPlugin(config); + await plugin.setup(); + + await expect( + plugin.exports().addTools([ + { + type: "function", + name: "test", + execute: async () => "result", + }, + ]), + ).rejects.toThrow("not supported when using a custom agentInstance"); + }); + }); +}); diff --git a/integrations/appkit-agent/src/tests/agent-plugin/function-tool.test.ts b/integrations/appkit-agent/src/tests/agent-plugin/function-tool.test.ts new file mode 100644 index 000000000..3fed263c0 --- /dev/null +++ b/integrations/appkit-agent/src/tests/agent-plugin/function-tool.test.ts @@ -0,0 +1,260 @@ +import { describe, expect, test } from "vitest"; +import type { FunctionTool } from "../../agent-plugin/function-tool"; +import { + functionToolsToStructuredTools, + functionToolToStructuredTool, + isFunctionTool, +} from "../../agent-plugin/function-tool"; + +const weatherTool: FunctionTool = { + type: "function", + name: "get_weather", + description: "Get the current weather for a location", + parameters: { + type: "object", + properties: { + location: { type: "string", description: "City name" }, + }, + required: ["location"], + }, + execute: async ({ location }) => `Sunny in ${location}`, +}; + +const noParamsTool: FunctionTool = { + type: "function", + name: "get_time", + description: "Get current time", + execute: async () => new Date().toISOString(), +}; + +describe("isFunctionTool", () => { + test("returns true for valid FunctionTool", () => { + expect(isFunctionTool(weatherTool)).toBe(true); + }); + + test("returns true for minimal FunctionTool (no parameters)", () => { + expect(isFunctionTool(noParamsTool)).toBe(true); + }); + + test("returns false for null/undefined", () => { + expect(isFunctionTool(null)).toBe(false); + expect(isFunctionTool(undefined)).toBe(false); + }); + + test("returns false for object missing type", () => { + expect(isFunctionTool({ name: "foo", execute: () => "" })).toBe(false); + }); + + test("returns false for object missing execute", () => { + expect(isFunctionTool({ type: "function", name: "foo" })).toBe(false); + }); + + test("returns false for hosted tool object", () => { + expect( + isFunctionTool({ type: "genie-space", genie_space: { id: "123" } }), + ).toBe(false); + }); + + test("returns false for LangChain StructuredTool-like object", () => { + const lcTool = { + name: "lc_tool", + description: "a langchain tool", + invoke: async () => "result", + }; + expect(isFunctionTool(lcTool)).toBe(false); + }); + + test("returns false for non-objects", () => { + expect(isFunctionTool("function")).toBe(false); + expect(isFunctionTool(42)).toBe(false); + expect(isFunctionTool(true)).toBe(false); + }); +}); + +describe("functionToolToStructuredTool", () => { + test("converts FunctionTool to StructuredToolInterface", async () => { + const converted = functionToolToStructuredTool(weatherTool); + + expect(converted.name).toBe("get_weather"); + expect(converted.description).toBe( + "Get the current weather for a location", + ); + + const result = await converted.invoke({ location: "Paris" }); + expect(result).toBe("Sunny in Paris"); + }); + + test("handles tool with no parameters", async () => { + const converted = functionToolToStructuredTool(noParamsTool); + + expect(converted.name).toBe("get_time"); + const result = await converted.invoke({}); + expect(result).toBeTruthy(); + }); + + test("handles tool with null parameters", async () => { + const tool: FunctionTool = { + type: "function", + name: "ping", + parameters: null, + execute: async () => "pong", + }; + const converted = functionToolToStructuredTool(tool); + const result = await converted.invoke({}); + expect(result).toBe("pong"); + }); + + test("defaults description to empty string when not provided", async () => { + const tool: FunctionTool = { + type: "function", + name: "noop", + execute: async () => "done", + }; + const converted = functionToolToStructuredTool(tool); + expect(converted.description).toBe(""); + }); + + test("handles nested object parameters", async () => { + const tool: FunctionTool = { + type: "function", + name: "search", + description: "Search for items", + parameters: { + type: "object", + properties: { + query: { type: "string", description: "Search query" }, + options: { + type: "object", + properties: { + limit: { type: "integer", description: "Max results" }, + }, + }, + }, + required: ["query"], + }, + execute: async (args) => JSON.stringify(args), + }; + + const converted = functionToolToStructuredTool(tool); + expect(converted.name).toBe("search"); + + const result = await converted.invoke({ + query: "test", + options: { limit: 10 }, + }); + expect(JSON.parse(result)).toEqual({ + query: "test", + options: { limit: 10 }, + }); + }); + + test("handles enum parameters", async () => { + const tool: FunctionTool = { + type: "function", + name: "set_mode", + parameters: { + type: "object", + properties: { + mode: { + type: "string", + enum: ["fast", "slow"], + description: "Speed mode", + }, + }, + required: ["mode"], + }, + execute: async ({ mode }) => `Mode: ${mode}`, + }; + + const converted = functionToolToStructuredTool(tool); + const result = await converted.invoke({ mode: "fast" }); + expect(result).toBe("Mode: fast"); + }); + + test("handles optional parameters", async () => { + const tool: FunctionTool = { + type: "function", + name: "greet", + parameters: { + type: "object", + properties: { + name: { type: "string" }, + greeting: { type: "string" }, + }, + required: ["name"], + }, + execute: async ({ name, greeting }) => `${greeting ?? "Hello"}, ${name}!`, + }; + + const converted = functionToolToStructuredTool(tool); + const result = await converted.invoke({ name: "Alice" }); + expect(result).toBe("Hello, Alice!"); + }); + + test("handles boolean parameter type", async () => { + const tool: FunctionTool = { + type: "function", + name: "toggle", + parameters: { + type: "object", + properties: { + enabled: { type: "boolean" }, + }, + required: ["enabled"], + }, + execute: async ({ enabled }) => `enabled=${enabled}`, + }; + + const converted = functionToolToStructuredTool(tool); + const result = await converted.invoke({ enabled: true }); + expect(result).toBe("enabled=true"); + }); + + test("handles array parameter type", async () => { + const tool: FunctionTool = { + type: "function", + name: "batch", + parameters: { + type: "object", + properties: { + items: { type: "array" }, + }, + required: ["items"], + }, + execute: async ({ items }) => `count=${(items as any[]).length}`, + }; + + const converted = functionToolToStructuredTool(tool); + const result = await converted.invoke({ items: [1, 2, 3] }); + expect(result).toBe("count=3"); + }); + + test("handles sync execute handler", async () => { + const tool: FunctionTool = { + type: "function", + name: "sync_tool", + execute: () => "sync result", + }; + + const converted = functionToolToStructuredTool(tool); + const result = await converted.invoke({}); + expect(result).toBe("sync result"); + }); +}); + +describe("functionToolsToStructuredTools", () => { + test("converts array of FunctionTools", () => { + const converted = functionToolsToStructuredTools([ + weatherTool, + noParamsTool, + ]); + + expect(converted).toHaveLength(2); + expect(converted[0].name).toBe("get_weather"); + expect(converted[1].name).toBe("get_time"); + }); + + test("handles empty array", () => { + expect(functionToolsToStructuredTools([])).toEqual([]); + }); +}); diff --git a/integrations/appkit-agent/src/tests/agent-plugin/hosted-tools.test.ts b/integrations/appkit-agent/src/tests/agent-plugin/hosted-tools.test.ts new file mode 100644 index 000000000..c08c9877e --- /dev/null +++ b/integrations/appkit-agent/src/tests/agent-plugin/hosted-tools.test.ts @@ -0,0 +1,197 @@ +import { beforeEach, describe, expect, test, vi } from "vitest"; +import type { + CustomMcpServerTool, + ExternalMcpServerTool, + GenieTool, + HostedTool, + VectorSearchIndexTool, +} from "../../agent-plugin/hosted-tools"; +import { + isHostedTool, + resolveHostedTools, +} from "../../agent-plugin/hosted-tools"; + +const genieTool: GenieTool = { + type: "genie-space", + genie_space: { id: "space-123" }, +}; + +const vectorSearchTool: VectorSearchIndexTool = { + type: "vector_search_index", + vector_search_index: { name: "catalog.schema.my_index" }, +}; + +const customMcpTool: CustomMcpServerTool = { + type: "custom_mcp_server", + custom_mcp_server: { app_name: "my-mcp-app", app_url: "my-mcp-app" }, +}; + +const externalMcpTool: ExternalMcpServerTool = { + type: "external_mcp_server", + external_mcp_server: { connection_name: "my-connection" }, +}; + +// --------------------------------------------------------------------------- +// isHostedTool +// --------------------------------------------------------------------------- + +describe("isHostedTool", () => { + test("returns true for GenieTool", () => { + expect(isHostedTool(genieTool)).toBe(true); + }); + + test("returns true for VectorSearchIndexTool", () => { + expect(isHostedTool(vectorSearchTool)).toBe(true); + }); + + test("returns true for CustomMcpServerTool", () => { + expect(isHostedTool(customMcpTool)).toBe(true); + }); + + test("returns true for ExternalMcpServerTool", () => { + expect(isHostedTool(externalMcpTool)).toBe(true); + }); + + test("returns false for FunctionTool", () => { + const functionTool = { + type: "function", + name: "test", + execute: async () => "result", + }; + expect(isHostedTool(functionTool)).toBe(false); + }); + + test("returns false for null/undefined", () => { + expect(isHostedTool(null)).toBe(false); + expect(isHostedTool(undefined)).toBe(false); + }); + + test("returns false for object with unknown type", () => { + expect(isHostedTool({ type: "unknown_tool" })).toBe(false); + }); + + test("returns false for non-object", () => { + expect(isHostedTool("genie")).toBe(false); + expect(isHostedTool(42)).toBe(false); + }); +}); + +describe("hosted tool types", () => { + test("all hosted tools satisfy HostedTool union", () => { + const tools: HostedTool[] = [ + genieTool, + vectorSearchTool, + customMcpTool, + externalMcpTool, + ]; + + expect(tools).toHaveLength(4); + for (const tool of tools) { + expect(isHostedTool(tool)).toBe(true); + } + }); + + test("can be mixed in an array with discriminator", () => { + const tools: HostedTool[] = [genieTool, vectorSearchTool]; + const types = tools.map((t) => t.type); + expect(types).toEqual(["genie-space", "vector_search_index"]); + }); +}); + +// --------------------------------------------------------------------------- +// resolveHostedTools +// --------------------------------------------------------------------------- + +const { mockFromGenieSpace, mockFromVectorSearch, MockDatabricksMCPServer } = + vi.hoisted(() => { + const mockFromGenieSpace = vi.fn().mockReturnValue({ _type: "genie" }); + const mockFromVectorSearch = vi.fn().mockReturnValue({ _type: "vector" }); + const constructorSpy = vi.fn(); + class MockDatabricksMCPServer { + name: string; + path: string; + constructor(opts: any) { + constructorSpy(opts); + this.name = opts.name; + this.path = opts.path; + } + static fromGenieSpace = mockFromGenieSpace; + static fromVectorSearch = mockFromVectorSearch; + } + return { + mockFromGenieSpace, + mockFromVectorSearch, + MockDatabricksMCPServer: Object.assign(MockDatabricksMCPServer, { + _constructorSpy: constructorSpy, + }), + }; + }); + +vi.mock("@databricks/langchainjs", () => ({ + DatabricksMCPServer: MockDatabricksMCPServer, +})); + +describe("resolveHostedTools", () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + + test("resolves genie-space tool via fromGenieSpace", async () => { + const result = await resolveHostedTools([genieTool]); + + expect(mockFromGenieSpace).toHaveBeenCalledWith("space-123"); + expect(result).toHaveLength(1); + expect(result[0]._type).toBe("genie"); + }); + + test("resolves vector_search_index via fromVectorSearch", async () => { + const result = await resolveHostedTools([vectorSearchTool]); + + expect(mockFromVectorSearch).toHaveBeenCalledWith( + "catalog", + "schema", + "my_index", + ); + expect(result).toHaveLength(1); + expect(result[0]._type).toBe("vector"); + }); + + test("throws for vector_search_index with wrong part count", async () => { + const badTool: VectorSearchIndexTool = { + type: "vector_search_index", + vector_search_index: { name: "just.two" }, + }; + + await expect(resolveHostedTools([badTool])).rejects.toThrow( + 'vector_search_index name must be "catalog.schema.index"', + ); + }); + + test("resolves custom_mcp_server via constructor", async () => { + const result = await resolveHostedTools([customMcpTool]); + + expect(MockDatabricksMCPServer._constructorSpy).toHaveBeenCalledWith({ + name: "mcp-app-my-mcp-app", + path: "/apps/my-mcp-app", + }); + expect(result).toHaveLength(1); + }); + + test("resolves external_mcp_server via constructor", async () => { + const result = await resolveHostedTools([externalMcpTool]); + + expect(MockDatabricksMCPServer._constructorSpy).toHaveBeenCalledWith({ + name: "mcp-ext-my-connection", + path: "/api/2.0/mcp/connections/my-connection", + }); + expect(result).toHaveLength(1); + }); + + test("resolves multiple tools in order", async () => { + const result = await resolveHostedTools([genieTool, customMcpTool]); + + expect(result).toHaveLength(2); + expect(mockFromGenieSpace).toHaveBeenCalled(); + expect(MockDatabricksMCPServer._constructorSpy).toHaveBeenCalled(); + }); +}); diff --git a/integrations/appkit-agent/src/tests/agent-plugin/invoke-handler.test.ts b/integrations/appkit-agent/src/tests/agent-plugin/invoke-handler.test.ts new file mode 100644 index 000000000..112e3c90b --- /dev/null +++ b/integrations/appkit-agent/src/tests/agent-plugin/invoke-handler.test.ts @@ -0,0 +1,322 @@ +import { describe, expect, test, vi } from "vitest"; +import { createInvokeHandler } from "../../agent-plugin/invoke-handler"; +import { StubAgent } from "./stub-agent"; +import { createMockRequest, createMockResponse } from "./test-helpers"; + +function makeReq(body: any) { + return createMockRequest({ body }) as any; +} + +function makeRes() { + const res = createMockResponse() as any; + const chunks: string[] = []; + res.write.mockImplementation((chunk: string) => { + chunks.push(chunk); + return true; + }); + (res as any).__chunks = chunks; + return res; +} + +function parseSSE(res: any): { events: any[]; fullOutput: string } { + const chunks: string[] = res.__chunks; + const events: any[] = []; + let fullOutput = ""; + + for (const chunk of chunks) { + const lines = chunk.split("\n"); + for (const line of lines) { + if (line.startsWith("data: ") && line !== "data: [DONE]") { + try { + const data = JSON.parse(line.slice(6)); + events.push(data); + if (data.type === "response.output_text.delta") { + fullOutput += data.delta; + } + } catch {} + } + } + } + return { events, fullOutput }; +} + +describe("createInvokeHandler", () => { + const stubAgent = new StubAgent(); + const handler = createInvokeHandler(() => stubAgent); + + describe("streaming mode", () => { + test("streams SSE events with correct format", async () => { + const req = makeReq({ + input: [{ role: "user", content: "Hello" }], + stream: true, + }); + const res = makeRes(); + + await handler(req, res, vi.fn()); + + expect(res.setHeader).toHaveBeenCalledWith( + "Content-Type", + "text/event-stream", + ); + + const { events, fullOutput } = parseSSE(res); + + expect(fullOutput).toContain("Echo: Hello"); + + const hasCompleted = events.some((e) => e.type === "response.completed"); + expect(hasCompleted).toBe(true); + + const lastChunk = res.__chunks[res.__chunks.length - 1]; + expect(lastChunk).toContain("[DONE]"); + + expect(res.end).toHaveBeenCalled(); + }); + + test("emits output_item.added and output_item.done events", async () => { + const req = makeReq({ + input: [{ role: "user", content: "Test" }], + stream: true, + }); + const res = makeRes(); + + await handler(req, res, vi.fn()); + + const { events } = parseSSE(res); + const addedEvent = events.find( + (e) => e.type === "response.output_item.added", + ); + const doneEvent = events.find( + (e) => e.type === "response.output_item.done", + ); + + expect(addedEvent).toBeDefined(); + expect(addedEvent.item.type).toBe("message"); + expect(doneEvent).toBeDefined(); + }); + }); + + describe("non-streaming mode", () => { + test("returns JSON with output items", async () => { + const req = makeReq({ + input: [{ role: "user", content: "Hello" }], + stream: false, + }); + const res = makeRes(); + + await handler(req, res, vi.fn()); + + expect(res.json).toHaveBeenCalledWith( + expect.objectContaining({ + output: expect.arrayContaining([ + expect.objectContaining({ + type: "message", + content: expect.arrayContaining([ + expect.objectContaining({ + type: "output_text", + text: "Echo: Hello", + }), + ]), + }), + ]), + }), + ); + }); + }); + + describe("input parsing", () => { + test("accepts string input", async () => { + const req = makeReq({ + input: "Hello string", + stream: true, + }); + const res = makeRes(); + + await handler(req, res, vi.fn()); + + const { fullOutput } = parseSSE(res); + expect(fullOutput).toContain("Echo: Hello string"); + }); + + test("accepts array input with multipart content", async () => { + const req = makeReq({ + input: [ + { + role: "user", + content: [ + { type: "input_text", text: "Part one" }, + { type: "input_text", text: "Part two" }, + ], + }, + ], + stream: true, + }); + const res = makeRes(); + + await handler(req, res, vi.fn()); + + const { fullOutput } = parseSSE(res); + expect(fullOutput).toContain("Echo: Part one\nPart two"); + }); + }); + + describe("chat history", () => { + test("passes chat history to agent", async () => { + const spyAgent = { + invoke: vi.fn().mockResolvedValue([ + { + id: "msg_1", + type: "message", + role: "assistant", + status: "completed", + content: [ + { type: "output_text", text: "response", annotations: [] }, + ], + }, + ]), + stream: vi.fn(), + }; + const historyHandler = createInvokeHandler(() => spyAgent as any); + + const req = makeReq({ + input: [ + { role: "user", content: "First message" }, + { role: "assistant", content: "First reply" }, + { role: "user", content: "Second message" }, + ], + stream: false, + }); + const res = makeRes(); + + await historyHandler(req, res, vi.fn()); + + expect(spyAgent.invoke).toHaveBeenCalledWith( + expect.objectContaining({ + input: "Second message", + chat_history: expect.arrayContaining([ + expect.objectContaining({ + role: "user", + content: "First message", + }), + expect.objectContaining({ + role: "assistant", + content: "First reply", + }), + ]), + }), + ); + }); + + test("handles function_call items in history", async () => { + const spyAgent = { + invoke: vi.fn().mockResolvedValue([ + { + id: "msg_1", + type: "message", + role: "assistant", + status: "completed", + content: [{ type: "output_text", text: "done", annotations: [] }], + }, + ]), + stream: vi.fn(), + }; + const historyHandler = createInvokeHandler(() => spyAgent as any); + + const req = makeReq({ + input: [ + { role: "user", content: "Look up the answer" }, + { + type: "function_call", + name: "search", + arguments: '{"q":"test"}', + }, + { + type: "function_call_output", + output: '"42"', + }, + { role: "user", content: "What did you find?" }, + ], + stream: false, + }); + const res = makeRes(); + + await historyHandler(req, res, vi.fn()); + + const calledHistory = spyAgent.invoke.mock.calls[0][0].chat_history; + expect(calledHistory).toHaveLength(3); + expect(calledHistory[1].content).toContain("[Tool Call:"); + expect(calledHistory[2].content).toContain("[Tool Result:"); + }); + }); + + describe("error handling", () => { + test("returns 400 for missing input", async () => { + const req = makeReq({ stream: true }); + const res = makeRes(); + + await handler(req, res, vi.fn()); + + expect(res.status).toHaveBeenCalledWith(400); + expect(res.json).toHaveBeenCalledWith( + expect.objectContaining({ error: "Invalid request format" }), + ); + }); + + test("returns 400 when no user message is present", async () => { + const req = makeReq({ + input: [{ role: "assistant", content: "I am assistant" }], + stream: true, + }); + const res = makeRes(); + + await handler(req, res, vi.fn()); + + expect(res.status).toHaveBeenCalledWith(400); + expect(res.json).toHaveBeenCalledWith( + expect.objectContaining({ + error: "No user message found in input", + }), + ); + }); + + test("handles agent errors gracefully in streaming mode", async () => { + const errorAgent = { + invoke: vi.fn(), + stream: (_params: any) => { + return { + async next() { + throw new Error("Agent exploded"); + }, + async return() { + return { done: true, value: undefined }; + }, + async throw(e: unknown) { + throw e; + }, + [Symbol.asyncIterator]() { + return this; + }, + [Symbol.asyncDispose]: undefined, + } as unknown as AsyncGenerator; + }, + }; + const errorHandler = createInvokeHandler(() => errorAgent as any); + + const req = makeReq({ + input: [{ role: "user", content: "boom" }], + stream: true, + }); + const res = makeRes(); + + await errorHandler(req, res, vi.fn()); + + const { events } = parseSSE(res); + const errorEvent = events.find((e) => e.type === "error"); + const failedEvent = events.find((e) => e.type === "response.failed"); + + expect(errorEvent).toBeDefined(); + expect(errorEvent.error).toContain("Agent exploded"); + expect(failedEvent).toBeDefined(); + expect(res.end).toHaveBeenCalled(); + }); + }); +}); diff --git a/integrations/appkit-agent/src/tests/agent-plugin/standard-agent.test.ts b/integrations/appkit-agent/src/tests/agent-plugin/standard-agent.test.ts new file mode 100644 index 000000000..a7e80a625 --- /dev/null +++ b/integrations/appkit-agent/src/tests/agent-plugin/standard-agent.test.ts @@ -0,0 +1,411 @@ +import { describe, expect, test } from "vitest"; +import { HumanMessage, SystemMessage } from "@langchain/core/messages"; +import { StandardAgent } from "../../agent-plugin/standard-agent"; +import type { ResponseStreamEvent } from "../../agent-plugin/agent-interface"; + +/** + * Mock LangGraph agent with controllable invoke/streamEvents results. + */ +class MockLangGraphAgent { + invokeResult: any; + streamEventsData: any[]; + + /** Captured messages from the last invoke/streamEvents call. */ + lastMessages: any[] = []; + + constructor(options: { invokeResult?: any; streamEvents?: any[] } = {}) { + this.invokeResult = options.invokeResult ?? { + messages: [{ content: "Hello from agent" }], + }; + this.streamEventsData = options.streamEvents ?? []; + } + + async invoke(input: any) { + this.lastMessages = input.messages; + return this.invokeResult; + } + + async *streamEvents(input: any, _options: any) { + this.lastMessages = input.messages; + for (const event of this.streamEventsData) { + yield event; + } + } +} + +const SYSTEM_PROMPT = "You are a test assistant."; + +describe("StandardAgent", () => { + describe("invoke", () => { + test("returns a completed ResponseOutputMessage", async () => { + const mock = new MockLangGraphAgent(); + const agent = new StandardAgent(mock as any, SYSTEM_PROMPT); + + const items = await agent.invoke({ input: "hello" }); + + expect(items).toHaveLength(1); + expect(items[0].type).toBe("message"); + + const msg = items[0] as any; + expect(msg.role).toBe("assistant"); + expect(msg.status).toBe("completed"); + expect(msg.content[0].type).toBe("output_text"); + expect(msg.content[0].text).toBe("Hello from agent"); + }); + + test("prepends system prompt and appends user input", async () => { + const mock = new MockLangGraphAgent(); + const agent = new StandardAgent(mock as any, SYSTEM_PROMPT); + + await agent.invoke({ input: "hello" }); + + const messages = mock.lastMessages; + expect(messages[0]).toBeInstanceOf(SystemMessage); + expect(messages[0].content).toBe(SYSTEM_PROMPT); + expect(messages[messages.length - 1]).toBeInstanceOf(HumanMessage); + expect(messages[messages.length - 1].content).toBe("hello"); + }); + + test("includes chat history as base messages", async () => { + const mock = new MockLangGraphAgent(); + const agent = new StandardAgent(mock as any, SYSTEM_PROMPT); + + await agent.invoke({ + input: "follow-up", + chat_history: [ + { role: "user", content: "hi" }, + { role: "assistant", content: "hello" }, + ], + }); + + const messages = mock.lastMessages; + // system + 2 history + user input + expect(messages).toHaveLength(4); + expect(messages[1]).toBeInstanceOf(HumanMessage); + expect(messages[1].content).toBe("hi"); + }); + + test("returns empty text when last message content is not a string", async () => { + const mock = new MockLangGraphAgent({ + invokeResult: { messages: [{ content: [{ type: "tool_use" }] }] }, + }); + const agent = new StandardAgent(mock as any, SYSTEM_PROMPT); + + const items = await agent.invoke({ input: "test" }); + const msg = items[0] as any; + expect(msg.content[0].text).toBe(""); + }); + + test("returns empty text when messages array is empty", async () => { + const mock = new MockLangGraphAgent({ + invokeResult: { messages: [] }, + }); + const agent = new StandardAgent(mock as any, SYSTEM_PROMPT); + + const items = await agent.invoke({ input: "test" }); + const msg = items[0] as any; + expect(msg.content[0].text).toBe(""); + }); + }); + + describe("stream", () => { + test("emits function_call events for on_tool_start", async () => { + const mock = new MockLangGraphAgent({ + streamEvents: [ + { + event: "on_tool_start", + name: "get_weather", + run_id: "run-1", + data: { input: { location: "Paris" } }, + }, + ], + }); + const agent = new StandardAgent(mock as any, SYSTEM_PROMPT); + + const events: ResponseStreamEvent[] = []; + for await (const e of agent.stream({ input: "weather?" })) { + events.push(e); + } + + const addedEvent = events.find( + (e) => e.type === "response.output_item.added", + ); + expect(addedEvent).toBeDefined(); + const item = (addedEvent as any).item; + expect(item.type).toBe("function_call"); + expect(item.name).toBe("get_weather"); + expect(JSON.parse(item.arguments)).toEqual({ location: "Paris" }); + + const doneEvent = events.find( + (e) => + e.type === "response.output_item.done" && + (e as any).item.type === "function_call", + ); + expect(doneEvent).toBeDefined(); + }); + + test("emits function_call_output events for on_tool_end", async () => { + const mock = new MockLangGraphAgent({ + streamEvents: [ + { + event: "on_tool_start", + name: "search", + run_id: "run-2", + data: { input: { q: "test" } }, + }, + { + event: "on_tool_end", + name: "search", + run_id: "run-2", + data: { output: "42" }, + }, + ], + }); + const agent = new StandardAgent(mock as any, SYSTEM_PROMPT); + + const events: ResponseStreamEvent[] = []; + for await (const e of agent.stream({ input: "search" })) { + events.push(e); + } + + const outputEvents = events.filter( + (e) => + e.type === "response.output_item.added" && + (e as any).item.type === "function_call_output", + ); + expect(outputEvents).toHaveLength(1); + + const output = (outputEvents[0] as any).item; + expect(output.type).toBe("function_call_output"); + expect(JSON.parse(output.output)).toBe("42"); + }); + + test("correlates tool_end call_id with tool_start", async () => { + const mock = new MockLangGraphAgent({ + streamEvents: [ + { + event: "on_tool_start", + name: "calc", + run_id: "run-3", + data: { input: {} }, + }, + { + event: "on_tool_end", + name: "calc", + run_id: "run-3", + data: { output: "done" }, + }, + ], + }); + const agent = new StandardAgent(mock as any, SYSTEM_PROMPT); + + const events: ResponseStreamEvent[] = []; + for await (const e of agent.stream({ input: "calc" })) { + events.push(e); + } + + const fcAdded = events.find( + (e) => + e.type === "response.output_item.added" && + (e as any).item.type === "function_call", + ); + const fcoAdded = events.find( + (e) => + e.type === "response.output_item.added" && + (e as any).item.type === "function_call_output", + ); + + expect((fcAdded as any).item.call_id).toBe( + (fcoAdded as any).item.call_id, + ); + }); + + test("emits text delta events for on_chat_model_stream", async () => { + const mock = new MockLangGraphAgent({ + streamEvents: [ + { + event: "on_chat_model_stream", + name: "model", + run_id: "run-4", + data: { chunk: { content: "Hello " } }, + }, + { + event: "on_chat_model_stream", + name: "model", + run_id: "run-4", + data: { chunk: { content: "World" } }, + }, + ], + }); + const agent = new StandardAgent(mock as any, SYSTEM_PROMPT); + + const events: ResponseStreamEvent[] = []; + for await (const e of agent.stream({ input: "greet" })) { + events.push(e); + } + + const msgAdded = events.find( + (e) => + e.type === "response.output_item.added" && + (e as any).item.type === "message", + ); + expect(msgAdded).toBeDefined(); + expect((msgAdded as any).item.status).toBe("in_progress"); + + const deltas = events.filter( + (e) => e.type === "response.output_text.delta", + ); + expect(deltas).toHaveLength(2); + expect((deltas[0] as any).delta).toBe("Hello "); + expect((deltas[1] as any).delta).toBe("World"); + }); + + test("emits response.completed as final event", async () => { + const mock = new MockLangGraphAgent({ streamEvents: [] }); + const agent = new StandardAgent(mock as any, SYSTEM_PROMPT); + + const events: ResponseStreamEvent[] = []; + for await (const e of agent.stream({ input: "test" })) { + events.push(e); + } + + const last = events[events.length - 1]; + expect(last.type).toBe("response.completed"); + }); + + test("sequence numbers increment monotonically", async () => { + const mock = new MockLangGraphAgent({ + streamEvents: [ + { + event: "on_tool_start", + name: "t", + run_id: "r1", + data: { input: {} }, + }, + { + event: "on_tool_end", + name: "t", + run_id: "r1", + data: { output: "ok" }, + }, + { + event: "on_chat_model_stream", + name: "m", + run_id: "r2", + data: { chunk: { content: "hi" } }, + }, + ], + }); + const agent = new StandardAgent(mock as any, SYSTEM_PROMPT); + + const events: ResponseStreamEvent[] = []; + for await (const e of agent.stream({ input: "test" })) { + events.push(e); + } + + const seqNums = events.map((e) => (e as any).sequence_number); + for (let i = 1; i < seqNums.length; i++) { + expect(seqNums[i]).toBeGreaterThan(seqNums[i - 1]); + } + }); + + test("output_index increments across items", async () => { + const mock = new MockLangGraphAgent({ + streamEvents: [ + { + event: "on_tool_start", + name: "t", + run_id: "r1", + data: { input: {} }, + }, + { + event: "on_tool_end", + name: "t", + run_id: "r1", + data: { output: "ok" }, + }, + { + event: "on_chat_model_stream", + name: "m", + run_id: "r2", + data: { chunk: { content: "result" } }, + }, + ], + }); + const agent = new StandardAgent(mock as any, SYSTEM_PROMPT); + + const events: ResponseStreamEvent[] = []; + for await (const e of agent.stream({ input: "test" })) { + events.push(e); + } + + const addedEvents = events.filter( + (e) => e.type === "response.output_item.added", + ); + const indices = addedEvents.map((e) => (e as any).output_index); + expect(indices).toEqual([0, 1, 2]); + }); + + test("handles stream with only text (no tool calls)", async () => { + const mock = new MockLangGraphAgent({ + streamEvents: [ + { + event: "on_chat_model_stream", + name: "m", + run_id: "r1", + data: { chunk: { content: "just text" } }, + }, + ], + }); + const agent = new StandardAgent(mock as any, SYSTEM_PROMPT); + + const events: ResponseStreamEvent[] = []; + for await (const e of agent.stream({ input: "test" })) { + events.push(e); + } + + const types = events.map((e) => e.type); + expect(types).not.toContain(expect.stringMatching(/function_call/)); + expect(events.some((e) => e.type === "response.output_text.delta")).toBe( + true, + ); + expect(events.some((e) => e.type === "response.completed")).toBe(true); + }); + + test("handles stream with only tool calls (no text)", async () => { + const mock = new MockLangGraphAgent({ + streamEvents: [ + { + event: "on_tool_start", + name: "t", + run_id: "r1", + data: { input: {} }, + }, + { + event: "on_tool_end", + name: "t", + run_id: "r1", + data: { output: "ok" }, + }, + ], + }); + const agent = new StandardAgent(mock as any, SYSTEM_PROMPT); + + const events: ResponseStreamEvent[] = []; + for await (const e of agent.stream({ input: "test" })) { + events.push(e); + } + + const types = events.map((e) => e.type); + expect(types).not.toContain("response.output_text.delta"); + expect(types).toContain("response.completed"); + // No output_item.done for text message since no text was emitted + const textDone = events.find( + (e) => + e.type === "response.output_item.done" && + (e as any).item.type === "message", + ); + expect(textDone).toBeUndefined(); + }); + }); +}); diff --git a/integrations/appkit-agent/src/tests/agent-plugin/stub-agent.ts b/integrations/appkit-agent/src/tests/agent-plugin/stub-agent.ts new file mode 100644 index 000000000..44b15057b --- /dev/null +++ b/integrations/appkit-agent/src/tests/agent-plugin/stub-agent.ts @@ -0,0 +1,71 @@ +/** + * Deterministic stub AgentInterface for framework tests. + * + * Echoes user input as "Echo: {input}" — no LLM or network required. + */ + +import { randomUUID } from "node:crypto"; +import type { + AgentInterface, + InvokeParams, + ResponseOutputItem, + ResponseOutputMessage, + ResponseStreamEvent, +} from "../../agent-plugin/agent-interface"; + +export class StubAgent implements AgentInterface { + async invoke(params: InvokeParams): Promise { + const text = `Echo: ${params.input}`; + const message: ResponseOutputMessage = { + id: `msg_${randomUUID()}`, + type: "message", + role: "assistant", + status: "completed", + content: [{ type: "output_text", text, annotations: [] }], + }; + return [message]; + } + + async *stream(params: InvokeParams): AsyncGenerator { + const text = `Echo: ${params.input}`; + const itemId = `msg_${randomUUID()}`; + let seqNum = 0; + + const msgItem: ResponseOutputMessage = { + id: itemId, + type: "message", + role: "assistant", + status: "in_progress", + content: [], + }; + + yield { + type: "response.output_item.added", + item: msgItem, + output_index: 0, + sequence_number: seqNum++, + }; + + yield { + type: "response.output_text.delta", + item_id: itemId, + output_index: 0, + content_index: 0, + delta: text, + sequence_number: seqNum++, + }; + + yield { + type: "response.output_item.done", + item: { ...msgItem, status: "completed" }, + output_index: 0, + sequence_number: seqNum++, + }; + + yield { + type: "response.completed", + sequence_number: seqNum++, + response: {}, + }; + } +} diff --git a/integrations/appkit-agent/src/tests/agent-plugin/test-helpers.ts b/integrations/appkit-agent/src/tests/agent-plugin/test-helpers.ts new file mode 100644 index 000000000..dcaa9c378 --- /dev/null +++ b/integrations/appkit-agent/src/tests/agent-plugin/test-helpers.ts @@ -0,0 +1,88 @@ +import { vi } from "vitest"; + +/** + * Creates a mock Express request object. + */ +export function createMockRequest(overrides: any = {}) { + return { + params: {}, + query: {}, + body: {}, + headers: {}, + header(name: string) { + return (this as any).headers[name.toLowerCase()]; + }, + ...overrides, + }; +} + +/** + * Creates a mock Express response object with chainable methods. + */ +export function createMockResponse(): Record { + const eventListeners: Record void>> = {}; + + const res = { + status: vi.fn().mockReturnThis(), + json: vi.fn().mockReturnThis(), + send: vi.fn().mockReturnThis(), + sendStatus: vi.fn().mockReturnThis(), + end: vi.fn(function (this: any) { + this.writableEnded = true; + if (eventListeners.close) { + for (const handler of eventListeners.close) { + handler(); + } + } + return this; + }), + write: vi.fn().mockReturnThis(), + setHeader: vi.fn().mockReturnThis(), + flushHeaders: vi.fn().mockReturnThis(), + on: vi.fn(function ( + this: any, + event: string, + handler: (...args: any[]) => void, + ) { + if (!eventListeners[event]) { + eventListeners[event] = []; + } + eventListeners[event].push(handler); + return this; + }), + writableEnded: false, + }; + return res; +} + +/** + * Creates a mock Express router with route handler capturing. + */ +export function createMockRouter(): Record { + const handlers: Record = {}; + + const mockRouter = { + get: vi.fn((path: string, handler: any) => { + handlers[`GET:${path}`] = handler; + }), + post: vi.fn((path: string, handler: any) => { + handlers[`POST:${path}`] = handler; + }), + put: vi.fn((path: string, handler: any) => { + handlers[`PUT:${path}`] = handler; + }), + delete: vi.fn((path: string, handler: any) => { + handlers[`DELETE:${path}`] = handler; + }), + patch: vi.fn((path: string, handler: any) => { + handlers[`PATCH:${path}`] = handler; + }), + }; + + return { + router: mockRouter, + handlers, + getHandler: (method: string, path: string) => + handlers[`${method.toUpperCase()}:${path}`], + }; +} diff --git a/integrations/appkit-agent/tsconfig.json b/integrations/appkit-agent/tsconfig.json new file mode 100644 index 000000000..5518bdb15 --- /dev/null +++ b/integrations/appkit-agent/tsconfig.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "module": "ES2022", + "moduleResolution": "Bundler", + "target": "ES2022", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "outDir": "./dist", + "lib": ["ES2023"], + "baseUrl": ".", + "noEmit": true, + "isolatedModules": true, + "allowSyntheticDefaultImports": true, + "verbatimModuleSyntax": false + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "node_modules", + "dist" + ] +} diff --git a/integrations/appkit-agent/tsdown.config.ts b/integrations/appkit-agent/tsdown.config.ts new file mode 100644 index 000000000..5dc19c46d --- /dev/null +++ b/integrations/appkit-agent/tsdown.config.ts @@ -0,0 +1,24 @@ +import { defineConfig } from "tsdown"; + +export default defineConfig({ + entry: { + index: "./src/index.ts", + }, + format: ["esm", "cjs"], + fixedExtension: true, + dts: true, + outDir: "./dist", + target: "esnext", + clean: true, + sourcemap: true, + external: [ + "@databricks/appkit", + "@databricks/langchainjs", + "@langchain/core", + "@langchain/langgraph", + "@langchain/mcp-adapters", + "express", + ], + platform: "node", + treeshake: true, +}); diff --git a/integrations/appkit-agent/vitest.config.ts b/integrations/appkit-agent/vitest.config.ts new file mode 100644 index 000000000..e2ec33294 --- /dev/null +++ b/integrations/appkit-agent/vitest.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + globals: true, + }, +}); From a36b8f876acad7fc9b096cbcf824d1373dccd30b Mon Sep 17 00:00:00 2001 From: Hubert Zub Date: Tue, 24 Mar 2026 11:42:40 +0100 Subject: [PATCH 02/16] CR feedback Signed-off-by: Hubert Zub --- .../appkit-agent/src/agent-plugin/agent.ts | 18 +++-- .../src/agent-plugin/invoke-handler.ts | 5 +- .../src/tests/agent-plugin/agent.test.ts | 54 +++++++++++++++ .../tests/agent-plugin/invoke-handler.test.ts | 66 +++++++++++++++++++ 4 files changed, 136 insertions(+), 7 deletions(-) diff --git a/integrations/appkit-agent/src/agent-plugin/agent.ts b/integrations/appkit-agent/src/agent-plugin/agent.ts index f64b560d3..d40cf614c 100644 --- a/integrations/appkit-agent/src/agent-plugin/agent.ts +++ b/integrations/appkit-agent/src/agent-plugin/agent.ts @@ -239,9 +239,12 @@ export class AgentPlugin extends Plugin { if (!this.agentImpl) { throw new Error("AgentPlugin not initialized"); } - const lastUser = [...messages].reverse().find((m) => m.role === "user"); - const input = lastUser?.content ?? ""; - const chatHistory = messages.slice(0, -1); + const lastUserIdx = messages.findLastIndex((m) => m.role === "user"); + if (lastUserIdx < 0) { + throw new Error("No user message found in input"); + } + const input = messages[lastUserIdx].content; + const chatHistory = messages.slice(0, lastUserIdx); const items = await this.agentImpl.invoke({ input, chat_history: chatHistory, @@ -258,9 +261,12 @@ export class AgentPlugin extends Plugin { if (!this.agentImpl) { throw new Error("AgentPlugin not initialized"); } - const lastUser = [...messages].reverse().find((m) => m.role === "user"); - const input = lastUser?.content ?? ""; - const chatHistory = messages.slice(0, -1); + const lastUserIdx = messages.findLastIndex((m) => m.role === "user"); + if (lastUserIdx < 0) { + throw new Error("No user message found in input"); + } + const input = messages[lastUserIdx].content; + const chatHistory = messages.slice(0, lastUserIdx); yield* this.agentImpl.stream({ input, chat_history: chatHistory, diff --git a/integrations/appkit-agent/src/agent-plugin/invoke-handler.ts b/integrations/appkit-agent/src/agent-plugin/invoke-handler.ts index 20af57983..2db9dd6a8 100644 --- a/integrations/appkit-agent/src/agent-plugin/invoke-handler.ts +++ b/integrations/appkit-agent/src/agent-plugin/invoke-handler.ts @@ -123,7 +123,10 @@ export function createInvokeHandler( userInput = lastUserMessage.content as string; } - const chatHistory = input.slice(0, -1).map(flattenHistoryItem); + const lastUserIdx = input.findLastIndex( + (msg: any) => msg.role === "user", + ); + const chatHistory = input.slice(0, lastUserIdx).map(flattenHistoryItem); const agentParams = { input: userInput, chat_history: chatHistory }; const agent = getAgent(); diff --git a/integrations/appkit-agent/src/tests/agent-plugin/agent.test.ts b/integrations/appkit-agent/src/tests/agent-plugin/agent.test.ts index 98dd669b6..8a93620be 100644 --- a/integrations/appkit-agent/src/tests/agent-plugin/agent.test.ts +++ b/integrations/appkit-agent/src/tests/agent-plugin/agent.test.ts @@ -164,6 +164,37 @@ describe("AgentPlugin", () => { expect(completedEvent).toBeDefined(); }); + test("invoke history contains only messages before the last user message", async () => { + const spyAgent = { + invoke: vi.fn().mockResolvedValue([ + { + id: "msg_1", + type: "message", + role: "assistant", + status: "completed", + content: [{ type: "output_text", text: "ok", annotations: [] }], + }, + ]), + stream: vi.fn(), + }; + const config: IAgentConfig = { agentInstance: spyAgent as any }; + const plugin = new AgentPlugin(config); + await plugin.setup(); + + await plugin.exports().invoke([ + { role: "user", content: "first" }, + { role: "user", content: "second" }, + { role: "assistant", content: "interrupted" }, + ]); + + expect(spyAgent.invoke).toHaveBeenCalledWith( + expect.objectContaining({ + input: "second", + chat_history: [{ role: "user", content: "first" }], + }), + ); + }); + test("throws when not initialized", async () => { const config: IAgentConfig = { agentInstance: new StubAgent() }; const plugin = new AgentPlugin(config); @@ -174,6 +205,29 @@ describe("AgentPlugin", () => { }); }); + describe("abortActiveOperations()", () => { + function injectMcpClient( + plugin: AgentPlugin, + close: ReturnType, + ) { + Reflect.set(plugin, "mcpClient", { getTools: vi.fn(), close }); + } + + test("closes MCP client when present", async () => { + const stub = new StubAgent(); + const config: IAgentConfig = { agentInstance: stub }; + const plugin = new AgentPlugin(config); + await plugin.setup(); + + const closeFn = vi.fn().mockResolvedValue(undefined); + injectMcpClient(plugin, closeFn); + + await plugin.abortActiveOperations(); + + expect(closeFn).toHaveBeenCalledOnce(); + }); + }); + describe("addTools()", () => { test("throws when using agentInstance mode", async () => { const stub = new StubAgent(); diff --git a/integrations/appkit-agent/src/tests/agent-plugin/invoke-handler.test.ts b/integrations/appkit-agent/src/tests/agent-plugin/invoke-handler.test.ts index 112e3c90b..b23699970 100644 --- a/integrations/appkit-agent/src/tests/agent-plugin/invoke-handler.test.ts +++ b/integrations/appkit-agent/src/tests/agent-plugin/invoke-handler.test.ts @@ -206,6 +206,48 @@ describe("createInvokeHandler", () => { ); }); + test("history contains only messages before the last user message", async () => { + const spyAgent = { + invoke: vi.fn().mockResolvedValue([ + { + id: "msg_1", + type: "message", + role: "assistant", + status: "completed", + content: [ + { type: "output_text", text: "response", annotations: [] }, + ], + }, + ]), + stream: vi.fn(), + }; + const historyHandler = createInvokeHandler(() => spyAgent as any); + + const req = makeReq({ + input: [ + { role: "user", content: "First message" }, + { role: "user", content: "Second message" }, + { role: "assistant", content: "Interrupted reply" }, + ], + stream: false, + }); + const res = makeRes(); + + await historyHandler(req, res, vi.fn()); + + expect(spyAgent.invoke).toHaveBeenCalledWith( + expect.objectContaining({ + input: "Second message", + chat_history: [ + expect.objectContaining({ + role: "user", + content: "First message", + }), + ], + }), + ); + }); + test("handles function_call items in history", async () => { const spyAgent = { invoke: vi.fn().mockResolvedValue([ @@ -278,6 +320,30 @@ describe("createInvokeHandler", () => { ); }); + test("returns 500 when non-streaming agent invoke throws", async () => { + const errorAgent = { + invoke: vi.fn().mockRejectedValue(new Error("invoke exploded")), + stream: vi.fn(), + }; + const errorHandler = createInvokeHandler(() => errorAgent as any); + + const req = makeReq({ + input: [{ role: "user", content: "boom" }], + stream: false, + }); + const res = makeRes(); + + await errorHandler(req, res, vi.fn()); + + expect(res.status).toHaveBeenCalledWith(500); + expect(res.json).toHaveBeenCalledWith( + expect.objectContaining({ + error: "Internal server error", + message: "invoke exploded", + }), + ); + }); + test("handles agent errors gracefully in streaming mode", async () => { const errorAgent = { invoke: vi.fn(), From 8c02856e0811c9626d5051958957835450eb2214 Mon Sep 17 00:00:00 2001 From: Hubert Zub Date: Tue, 24 Mar 2026 15:57:37 +0100 Subject: [PATCH 03/16] Responses Signed-off-by: Hubert Zub --- integrations/appkit-agent/src/agent-plugin/agent.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/integrations/appkit-agent/src/agent-plugin/agent.ts b/integrations/appkit-agent/src/agent-plugin/agent.ts index d40cf614c..d6e9234cc 100644 --- a/integrations/appkit-agent/src/agent-plugin/agent.ts +++ b/integrations/appkit-agent/src/agent-plugin/agent.ts @@ -217,6 +217,7 @@ export class AgentPlugin extends Plugin { injectRoutes(router: express.Router) { const handler = createInvokeHandler(() => this.getAgentImpl()); router.post("/", handler); + router.post("/responses", handler); this.registerEndpoint("invoke", `/api/${this.name}`); } From 2099b652187b813ccdbc6eb49b63bda968affd3c Mon Sep 17 00:00:00 2001 From: Hubert Zub Date: Thu, 19 Mar 2026 13:40:47 +0100 Subject: [PATCH 04/16] docs Signed-off-by: Hubert Zub --- integrations/appkit-agent/README.md | 246 ++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 integrations/appkit-agent/README.md diff --git a/integrations/appkit-agent/README.md b/integrations/appkit-agent/README.md new file mode 100644 index 000000000..da88d213d --- /dev/null +++ b/integrations/appkit-agent/README.md @@ -0,0 +1,246 @@ +# @databricks/appkit-agent + +Agent plugin for [Databricks AppKit](https://github.com/databricks/appkit). Provides two things: + +1. **`AgentInterface`** — a contract for writing custom agent implementations that speak the OpenAI Responses API format (streaming + non-streaming). +2. **`StandardAgent`** — a ready-to-use LangGraph-based ReAct agent that implements `AgentInterface`, with streaming Responses API support, function tools, and Databricks-hosted tool integration (Genie, Vector Search, MCP servers). + +## Installation + +```bash +npm install @databricks/appkit-agent +``` + +The LangChain peer dependencies are required when using the built-in ReAct agent (not needed if you provide a custom `agentInstance`): + +```bash +npm install @databricks/langchainjs @langchain/core @langchain/langgraph +``` + +If you use hosted MCP tools (Genie, Vector Search, custom/external MCP servers): + +```bash +npm install @langchain/mcp-adapters +``` + +## Quick Start + +```typescript +import { createApp, server } from "@databricks/appkit"; +import { agent } from "@databricks/appkit-agent"; + +const app = await createApp({ + plugins: [ + server(), + agent({ + model: "databricks-claude-sonnet-4-5", + systemPrompt: "You are a helpful assistant.", + }), + ], +}); + +app.server.start(); +``` + +The plugin registers `POST /api/agent` which accepts the [OpenAI Responses API](https://platform.openai.com/docs/api-reference/responses) request format with SSE streaming. + +## Environment Variables + +| Variable | Description | +| ------------------ | ------------------------------------------------------------------ | +| `DATABRICKS_MODEL` | Default model serving endpoint name. Overridden by `config.model`. | + +## Configuration + +```typescript +agent({ + // Model serving endpoint (or set DATABRICKS_MODEL env var) + model: "databricks-claude-sonnet-4-5", + + // System prompt injected at the start of every conversation + systemPrompt: "You are a helpful assistant.", + + // Tools available to the agent (see Tools section below) + tools: [myTool, genieTool], + + // Or bring your own AgentInterface implementation (skips LangGraph setup) + agentInstance: myCustomAgent, +}); +``` + +## Tools + +The agent supports two kinds of tools: **function tools** (local code) and **hosted tools** (Databricks-managed services). + +### Function Tools + +Define tools as plain objects following the OpenResponses FunctionTool schema: + +```typescript +import type { FunctionTool } from "@databricks/appkit-agent"; + +const weatherTool: FunctionTool = { + type: "function", + name: "get_weather", + description: "Get the current weather for a location", + parameters: { + type: "object", + properties: { + location: { + type: "string", + description: "City name, e.g. 'San Francisco'", + }, + }, + required: ["location"], + }, + execute: async ({ location }) => { + // Call your weather API here + return `Weather in ${location}: sunny, 72°F`; + }, +}; + +agent({ model: "databricks-claude-sonnet-4-5", tools: [weatherTool] }); +``` + +### Hosted Tools + +Connect to Databricks-managed services without writing tool handlers: + +```typescript +// Genie Space — natural-language queries over your data +const genie = { + type: "genie-space" as const, + genie_space: { id: "01efg..." }, +}; + +// Vector Search Index — semantic search over indexed documents +const vectorSearch = { + type: "vector_search_index" as const, + vector_search_index: { name: "catalog.schema.my_index" }, +}; + +// Custom MCP Server — a Databricks App running an MCP server +const customMcp = { + type: "custom_mcp_server" as const, + custom_mcp_server: { app_name: "my-app", app_url: "my-app-url" }, +}; + +// External MCP Server — a Unity Catalog connection to an external MCP endpoint +const externalMcp = { + type: "external_mcp_server" as const, + external_mcp_server: { connection_name: "my-connection" }, +}; + +agent({ + model: "databricks-claude-sonnet-4-5", + tools: [genie, vectorSearch, customMcp, externalMcp], +}); +``` + +### Adding Tools After Creation + +```typescript +const app = await createApp({ + plugins: [ + server(), + agent({ model: "databricks-claude-sonnet-4-5", tools: [weatherTool] }), + ], +}); + +// Add more tools after the app is running +await app.agent.addTools([timeTool]); +``` + +## Programmatic API + +After `createApp`, the plugin exposes methods on `app.agent`: + +```typescript +// Non-streaming invoke — returns the assistant's text reply +const reply = await app.agent.invoke([ + { role: "user", content: "What's the weather in SF?" }, +]); + +// Streaming — yields Responses API SSE events +for await (const event of app.agent.stream([ + { role: "user", content: "Tell me a story" }, +])) { + if (event.type === "response.output_text.delta") { + process.stdout.write(event.delta); + } +} + +// Add tools dynamically +await app.agent.addTools([myNewTool]); +``` + +## Databricks Apps Deployment + +Databricks product UIs (AI Playground, Agent Evaluation, the built-in chat UI) interact with agents via the `/invocations` endpoint by convention. Since the AppKit agent plugin mounts at `/api/agent` by default, add a redirect so these UIs can chat with your agent: + +```typescript +app.server.extend((expressApp) => { + expressApp.post("/invocations", (req, res) => { + req.url = "/api/agent"; + expressApp(req, res); + }); +}); + +app.server.start(); +``` + +## Custom Agent Implementation + +To bring your own agent logic, implement the `AgentInterface` and pass it as `agentInstance`: + +```typescript +import type { + AgentInterface, + InvokeParams, + ResponseOutputItem, + ResponseStreamEvent, +} from "@databricks/appkit-agent"; + +class MyAgent implements AgentInterface { + async invoke(params: InvokeParams): Promise { + // Your invoke logic — return Responses API output items + } + + async *stream(params: InvokeParams): AsyncGenerator { + // Your streaming logic — yield Responses API SSE events + } +} + +agent({ agentInstance: new MyAgent() }); +``` + +The `StandardAgent` class (exported from this package) is the built-in implementation that wraps a LangGraph `createReactAgent` and translates its stream events into Responses API format. When you pass `model` instead of `agentInstance`, the plugin uses `StandardAgent` under the hood. + +## API Reference + +### Exports + +| Export | Kind | Description | +| --------------------- | -------------- | -------------------------------------------------------- | +| `agent` | Plugin factory | Main entry point — call with config, pass to `createApp` | +| `StandardAgent` | Class | LangGraph-backed `AgentInterface` implementation | +| `createInvokeHandler` | Function | Express handler factory for the `/api/agent` endpoint | +| `isFunctionTool` | Function | Type guard for `FunctionTool` | +| `isHostedTool` | Function | Type guard for `HostedTool` | + +### Types + +| Type | Description | +| --------------------- | ------------------------------------------------------------- | +| `IAgentConfig` | Plugin configuration options | +| `AgentInterface` | Contract for custom agent implementations | +| `AgentTool` | Union of `FunctionTool \| HostedTool` | +| `FunctionTool` | Local tool with JSON Schema parameters and `execute` handler | +| `HostedTool` | Union of Genie, Vector Search, Custom MCP, External MCP tools | +| `InvokeParams` | Input to `invoke()` / `stream()` | +| `ResponseOutputItem` | Output item (message, function call, or function call output) | +| `ResponseStreamEvent` | SSE event types for streaming responses | + +## License + +See [LICENSE](./LICENSE). From 25dfdc7c4b41f533484dcba6d7743af4a3ff678c Mon Sep 17 00:00:00 2001 From: Hubert Zub Date: Tue, 24 Mar 2026 12:30:02 +0100 Subject: [PATCH 05/16] CR feedback Signed-off-by: Hubert Zub --- integrations/appkit-agent/README.md | 18 +++++++++--------- .../src/agent-plugin/hosted-tools.ts | 6 +++--- .../tests/agent-plugin/function-tool.test.ts | 2 +- .../tests/agent-plugin/hosted-tools.test.ts | 6 +++--- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/integrations/appkit-agent/README.md b/integrations/appkit-agent/README.md index da88d213d..cda438758 100644 --- a/integrations/appkit-agent/README.md +++ b/integrations/appkit-agent/README.md @@ -1,9 +1,9 @@ # @databricks/appkit-agent -Agent plugin for [Databricks AppKit](https://github.com/databricks/appkit). Provides two things: +Agent plugin for [Databricks AppKit](https://github.com/databricks/appkit). You can define an agent using one of the following approaches: -1. **`AgentInterface`** — a contract for writing custom agent implementations that speak the OpenAI Responses API format (streaming + non-streaming). -2. **`StandardAgent`** — a ready-to-use LangGraph-based ReAct agent that implements `AgentInterface`, with streaming Responses API support, function tools, and Databricks-hosted tool integration (Genie, Vector Search, MCP servers). +1. Declaratively define an agent by specifying `model`, `tools,` and `instructions` +2. Implement a custom agent loop using **`AgentInterface`** — a contract for writing custom agent implementations that speak the OpenAI Responses API format (streaming + non-streaming). ## Installation @@ -11,13 +11,13 @@ Agent plugin for [Databricks AppKit](https://github.com/databricks/appkit). Prov npm install @databricks/appkit-agent ``` -The LangChain peer dependencies are required when using the built-in ReAct agent (not needed if you provide a custom `agentInstance`): +The following peer dependencies are required when using the built-in agent (not needed if you provide a custom `agentInstance`): ```bash npm install @databricks/langchainjs @langchain/core @langchain/langgraph ``` -If you use hosted MCP tools (Genie, Vector Search, custom/external MCP servers): +If you use hosted tools (Genie, Vector Search, custom/external MCP servers): ```bash npm install @langchain/mcp-adapters @@ -63,7 +63,7 @@ agent({ // Tools available to the agent (see Tools section below) tools: [myTool, genieTool], - // Or bring your own AgentInterface implementation (skips LangGraph setup) + // Or bring your own AgentInterface implementation agentInstance: myCustomAgent, }); ``` @@ -109,7 +109,7 @@ Connect to Databricks-managed services without writing tool handlers: ```typescript // Genie Space — natural-language queries over your data const genie = { - type: "genie-space" as const, + type: "genie_space" as const, genie_space: { id: "01efg..." }, }; @@ -214,7 +214,7 @@ class MyAgent implements AgentInterface { agent({ agentInstance: new MyAgent() }); ``` -The `StandardAgent` class (exported from this package) is the built-in implementation that wraps a LangGraph `createReactAgent` and translates its stream events into Responses API format. When you pass `model` instead of `agentInstance`, the plugin uses `StandardAgent` under the hood. +The `StandardAgent` class (exported from this package) is the built-in implementation used when you pass `model` instead of `agentInstance`. It translates the underlying agent's stream events into Responses API format. ## API Reference @@ -223,7 +223,7 @@ The `StandardAgent` class (exported from this package) is the built-in implement | Export | Kind | Description | | --------------------- | -------------- | -------------------------------------------------------- | | `agent` | Plugin factory | Main entry point — call with config, pass to `createApp` | -| `StandardAgent` | Class | LangGraph-backed `AgentInterface` implementation | +| `StandardAgent` | Class | Built-in `AgentInterface` implementation | | `createInvokeHandler` | Function | Express handler factory for the `/api/agent` endpoint | | `isFunctionTool` | Function | Type guard for `FunctionTool` | | `isHostedTool` | Function | Type guard for `HostedTool` | diff --git a/integrations/appkit-agent/src/agent-plugin/hosted-tools.ts b/integrations/appkit-agent/src/agent-plugin/hosted-tools.ts index af230803b..727886fcf 100644 --- a/integrations/appkit-agent/src/agent-plugin/hosted-tools.ts +++ b/integrations/appkit-agent/src/agent-plugin/hosted-tools.ts @@ -11,7 +11,7 @@ // --------------------------------------------------------------------------- export interface GenieTool { - type: "genie-space"; + type: "genie_space"; genie_space: { id: string }; } @@ -41,7 +41,7 @@ export type HostedTool = // --------------------------------------------------------------------------- const HOSTED_TOOL_TYPES = new Set([ - "genie-space", + "genie_space", "vector_search_index", "custom_mcp_server", "external_mcp_server", @@ -73,7 +73,7 @@ export async function resolveHostedTools( return tools.map((tool) => { switch (tool.type) { - case "genie-space": + case "genie_space": return DatabricksMCPServer.fromGenieSpace(tool.genie_space.id); case "vector_search_index": { diff --git a/integrations/appkit-agent/src/tests/agent-plugin/function-tool.test.ts b/integrations/appkit-agent/src/tests/agent-plugin/function-tool.test.ts index 3fed263c0..b4970cf3d 100644 --- a/integrations/appkit-agent/src/tests/agent-plugin/function-tool.test.ts +++ b/integrations/appkit-agent/src/tests/agent-plugin/function-tool.test.ts @@ -51,7 +51,7 @@ describe("isFunctionTool", () => { test("returns false for hosted tool object", () => { expect( - isFunctionTool({ type: "genie-space", genie_space: { id: "123" } }), + isFunctionTool({ type: "genie_space", genie_space: { id: "123" } }), ).toBe(false); }); diff --git a/integrations/appkit-agent/src/tests/agent-plugin/hosted-tools.test.ts b/integrations/appkit-agent/src/tests/agent-plugin/hosted-tools.test.ts index c08c9877e..18f93047a 100644 --- a/integrations/appkit-agent/src/tests/agent-plugin/hosted-tools.test.ts +++ b/integrations/appkit-agent/src/tests/agent-plugin/hosted-tools.test.ts @@ -12,7 +12,7 @@ import { } from "../../agent-plugin/hosted-tools"; const genieTool: GenieTool = { - type: "genie-space", + type: "genie_space", genie_space: { id: "space-123" }, }; @@ -94,7 +94,7 @@ describe("hosted tool types", () => { test("can be mixed in an array with discriminator", () => { const tools: HostedTool[] = [genieTool, vectorSearchTool]; const types = tools.map((t) => t.type); - expect(types).toEqual(["genie-space", "vector_search_index"]); + expect(types).toEqual(["genie_space", "vector_search_index"]); }); }); @@ -136,7 +136,7 @@ describe("resolveHostedTools", () => { vi.clearAllMocks(); }); - test("resolves genie-space tool via fromGenieSpace", async () => { + test("resolves genie_space tool via fromGenieSpace", async () => { const result = await resolveHostedTools([genieTool]); expect(mockFromGenieSpace).toHaveBeenCalledWith("space-123"); From 880ee1243e2aeebe8817ce538c7f312fc8df633c Mon Sep 17 00:00:00 2001 From: Hubert Zub Date: Thu, 19 Mar 2026 14:11:19 +0100 Subject: [PATCH 06/16] simple chatui Signed-off-by: Hubert Zub --- integrations/chat-ui/package.json | 85 +++++++++ integrations/chat-ui/src/index.ts | 18 ++ .../simple-agent-chat/agent-chat-message.tsx | 45 +++++ .../src/simple-agent-chat/agent-chat-part.tsx | 46 +++++ .../chat-ui/src/simple-agent-chat/index.ts | 15 ++ .../simple-agent-chat/primitives/button.tsx | 59 ++++++ .../src/simple-agent-chat/primitives/card.tsx | 15 ++ .../src/simple-agent-chat/primitives/cn.ts | 6 + .../simple-agent-chat/simple-agent-chat.tsx | 86 +++++++++ .../chat-ui/src/simple-agent-chat/types.ts | 66 +++++++ .../src/simple-agent-chat/use-agent-chat.ts | 174 ++++++++++++++++++ .../chat-ui/src/simple-agent-chat/utils.ts | 32 ++++ integrations/chat-ui/src/styles.css | 57 ++++++ integrations/chat-ui/tailwind.config.js | 49 +++++ integrations/chat-ui/tsconfig.json | 30 +++ integrations/chat-ui/tsdown.config.ts | 17 ++ integrations/chat-ui/vitest.config.ts | 8 + 17 files changed, 808 insertions(+) create mode 100644 integrations/chat-ui/package.json create mode 100644 integrations/chat-ui/src/index.ts create mode 100644 integrations/chat-ui/src/simple-agent-chat/agent-chat-message.tsx create mode 100644 integrations/chat-ui/src/simple-agent-chat/agent-chat-part.tsx create mode 100644 integrations/chat-ui/src/simple-agent-chat/index.ts create mode 100644 integrations/chat-ui/src/simple-agent-chat/primitives/button.tsx create mode 100644 integrations/chat-ui/src/simple-agent-chat/primitives/card.tsx create mode 100644 integrations/chat-ui/src/simple-agent-chat/primitives/cn.ts create mode 100644 integrations/chat-ui/src/simple-agent-chat/simple-agent-chat.tsx create mode 100644 integrations/chat-ui/src/simple-agent-chat/types.ts create mode 100644 integrations/chat-ui/src/simple-agent-chat/use-agent-chat.ts create mode 100644 integrations/chat-ui/src/simple-agent-chat/utils.ts create mode 100644 integrations/chat-ui/src/styles.css create mode 100644 integrations/chat-ui/tailwind.config.js create mode 100644 integrations/chat-ui/tsconfig.json create mode 100644 integrations/chat-ui/tsdown.config.ts create mode 100644 integrations/chat-ui/vitest.config.ts diff --git a/integrations/chat-ui/package.json b/integrations/chat-ui/package.json new file mode 100644 index 000000000..8e198fa3b --- /dev/null +++ b/integrations/chat-ui/package.json @@ -0,0 +1,85 @@ +{ + "name": "@databricks/chat-ui", + "version": "0.1.0", + "description": "React chat UI components for Databricks AI agents", + "type": "module", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/index.d.cts", + "exports": { + ".": { + "import": { + "types": "./dist/index.d.mts", + "default": "./dist/index.mjs" + }, + "require": { + "types": "./dist/index.d.cts", + "default": "./dist/index.cjs" + } + }, + "./styles.css": "./dist/styles.css" + }, + "files": [ + "dist", + "README.md", + "LICENSE", + "NOTICE" + ], + "scripts": { + "build": "tsdown && tailwindcss -i src/styles.css -o dist/styles.css --minify", + "dev": "tsdown --watch", + "clean": "rm -rf dist", + "test": "vitest run", + "test:watch": "vitest", + "typecheck": "tsc --noEmit", + "format": "prettier --write 'src/**/*.{ts,tsx}'", + "format:check": "prettier --check 'src/**/*.{ts,tsx}'" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "dependencies": { + "@radix-ui/react-slot": "^1.2.4", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "tailwind-merge": "^3.4.0" + }, + "devDependencies": { + "@types/node": "^22.0.0", + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", + "prettier": "^3.0.0", + "tailwindcss": "^3.4.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "tsdown": "^0.9.0", + "typescript": "^5.4.0", + "vitest": "^4.0.18" + }, + "author": { + "name": "Databricks", + "email": "agent-feedback@databricks.com" + }, + "repository": { + "type": "git", + "url": "https://github.com/databricks/databricks-ai-bridge.git", + "directory": "integrations/chat-ui" + }, + "homepage": "https://github.com/databricks/databricks-ai-bridge/tree/main/integrations/chat-ui", + "bugs": { + "url": "https://github.com/databricks/databricks-ai-bridge/issues" + }, + "keywords": [ + "databricks", + "chat", + "agent", + "react", + "ui", + "components" + ], + "license": "Databricks License" +} diff --git a/integrations/chat-ui/src/index.ts b/integrations/chat-ui/src/index.ts new file mode 100644 index 000000000..3843d4bae --- /dev/null +++ b/integrations/chat-ui/src/index.ts @@ -0,0 +1,18 @@ +export { + SimpleAgentChat, + AgentChatMessage, + AgentChatPart, + useAgentChat, + serializeForApi, + tryFormatJson, +} from "./simple-agent-chat"; +export type { + SimpleAgentChatProps, + ChatMessage, + AssistantPart, + TextPart, + FunctionCallPart, + FunctionCallOutputPart, + UseAgentChatOptions, + UseAgentChatReturn, +} from "./simple-agent-chat"; diff --git a/integrations/chat-ui/src/simple-agent-chat/agent-chat-message.tsx b/integrations/chat-ui/src/simple-agent-chat/agent-chat-message.tsx new file mode 100644 index 000000000..1b4853026 --- /dev/null +++ b/integrations/chat-ui/src/simple-agent-chat/agent-chat-message.tsx @@ -0,0 +1,45 @@ +import { AgentChatPart } from "./agent-chat-part"; +import type { ChatMessage } from "./types"; + +interface AgentChatMessageProps { + message: ChatMessage; + isLast?: boolean; + isStreaming?: boolean; +} + +/** Renders a single chat message bubble (user or assistant with parts). */ +export function AgentChatMessage({ + message, + isLast = false, + isStreaming = false, +}: AgentChatMessageProps) { + if (message.role === "user") { + return ( +
+ + You + +
+ {message.content} +
+
+ ); + } + + return ( +
+ + Agent + +
+ {message.parts.map((part, j) => ( + + ))} +
+
+ ); +} diff --git a/integrations/chat-ui/src/simple-agent-chat/agent-chat-part.tsx b/integrations/chat-ui/src/simple-agent-chat/agent-chat-part.tsx new file mode 100644 index 000000000..9646372d6 --- /dev/null +++ b/integrations/chat-ui/src/simple-agent-chat/agent-chat-part.tsx @@ -0,0 +1,46 @@ +import type { AssistantPart } from "./types"; +import { tryFormatJson } from "./utils"; + +interface AgentChatPartProps { + part: AssistantPart; + showCursor?: boolean; +} + +/** Renders a single assistant part: text, function_call, or function_call_output. */ +export function AgentChatPart({ + part, + showCursor = false, +}: AgentChatPartProps) { + if (part.type === "text") { + return ( +
+ {part.content} + {showCursor && |} +
+ ); + } + + if (part.type === "function_call") { + return ( +
+
+ Tool: {part.name} +
+
+          {tryFormatJson(part.arguments)}
+        
+
+ ); + } + + return ( +
+
+ Result +
+
+        {tryFormatJson(part.output)}
+      
+
+ ); +} diff --git a/integrations/chat-ui/src/simple-agent-chat/index.ts b/integrations/chat-ui/src/simple-agent-chat/index.ts new file mode 100644 index 000000000..a7c417218 --- /dev/null +++ b/integrations/chat-ui/src/simple-agent-chat/index.ts @@ -0,0 +1,15 @@ +export { SimpleAgentChat } from "./simple-agent-chat"; +export { AgentChatMessage } from "./agent-chat-message"; +export { AgentChatPart } from "./agent-chat-part"; +export type { + SimpleAgentChatProps, + ChatMessage, + AssistantPart, + TextPart, + FunctionCallPart, + FunctionCallOutputPart, + UseAgentChatOptions, + UseAgentChatReturn, +} from "./types"; +export { useAgentChat } from "./use-agent-chat"; +export { serializeForApi, tryFormatJson } from "./utils"; diff --git a/integrations/chat-ui/src/simple-agent-chat/primitives/button.tsx b/integrations/chat-ui/src/simple-agent-chat/primitives/button.tsx new file mode 100644 index 000000000..ca4810b44 --- /dev/null +++ b/integrations/chat-ui/src/simple-agent-chat/primitives/button.tsx @@ -0,0 +1,59 @@ +import type * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { cva, type VariantProps } from "class-variance-authority"; +import { cn } from "./cn"; + +const buttonVariants = cva( + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive hover:cursor-pointer", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60", + outline: + "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: + "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-9 px-4 py-2 has-[>svg]:px-3", + sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5", + lg: "h-10 rounded-md px-6 has-[>svg]:px-4", + icon: "size-9", + "icon-sm": "size-8", + "icon-lg": "size-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + }, +); + +export function Button({ + className, + variant, + size, + asChild = false, + ...props +}: React.ComponentProps<"button"> & + VariantProps & { + asChild?: boolean; + }) { + const Comp = asChild ? Slot : "button"; + + return ( + + ); +} + +export { buttonVariants }; diff --git a/integrations/chat-ui/src/simple-agent-chat/primitives/card.tsx b/integrations/chat-ui/src/simple-agent-chat/primitives/card.tsx new file mode 100644 index 000000000..3dbf165f0 --- /dev/null +++ b/integrations/chat-ui/src/simple-agent-chat/primitives/card.tsx @@ -0,0 +1,15 @@ +import type * as React from "react"; +import { cn } from "./cn"; + +export function Card({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} diff --git a/integrations/chat-ui/src/simple-agent-chat/primitives/cn.ts b/integrations/chat-ui/src/simple-agent-chat/primitives/cn.ts new file mode 100644 index 000000000..365058ceb --- /dev/null +++ b/integrations/chat-ui/src/simple-agent-chat/primitives/cn.ts @@ -0,0 +1,6 @@ +import { type ClassValue, clsx } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/integrations/chat-ui/src/simple-agent-chat/simple-agent-chat.tsx b/integrations/chat-ui/src/simple-agent-chat/simple-agent-chat.tsx new file mode 100644 index 000000000..7251bdb9b --- /dev/null +++ b/integrations/chat-ui/src/simple-agent-chat/simple-agent-chat.tsx @@ -0,0 +1,86 @@ +import { useEffect, useRef } from "react"; +import { cn } from "./primitives/cn"; +import { Button } from "./primitives/button"; +import { Card } from "./primitives/card"; +import { AgentChatMessage } from "./agent-chat-message"; +import type { SimpleAgentChatProps, ChatMessage } from "./types"; +import { useAgentChat } from "./use-agent-chat"; + +/** Agent chat UI: message list + input, wired to POST /invocations SSE streaming. */ +export function SimpleAgentChat({ + invokeUrl = "/invocations", + placeholder = "Type a message...", + emptyMessage = "Send a message to start.", + className, +}: SimpleAgentChatProps) { + const scrollRef = useRef(null); + const { + displayMessages, + loading, + input, + setInput, + handleSubmit, + isStreamingText, + } = useAgentChat({ invokeUrl }); + + const contentLength = displayMessages.length; + // biome-ignore lint/correctness/useExhaustiveDependencies: deps used as triggers for auto-scroll + useEffect(() => { + scrollRef.current?.scrollTo({ + top: scrollRef.current.scrollHeight, + behavior: "smooth", + }); + }, [contentLength, isStreamingText]); + + return ( +
+ +
+ {displayMessages.length === 0 && ( +

{emptyMessage}

+ )} + {displayMessages.map((msg, i) => ( + + ))} +
+ +
+ setInput(e.target.value)} + placeholder={placeholder} + className="flex-1 rounded-lg border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring" + disabled={loading} + /> + +
+
+
+ ); +} + +function MessageItem({ + message, + isLast, + isStreaming, +}: { + message: ChatMessage; + isLast: boolean; + isStreaming: boolean; +}) { + return ( + + ); +} diff --git a/integrations/chat-ui/src/simple-agent-chat/types.ts b/integrations/chat-ui/src/simple-agent-chat/types.ts new file mode 100644 index 000000000..d3c714e5f --- /dev/null +++ b/integrations/chat-ui/src/simple-agent-chat/types.ts @@ -0,0 +1,66 @@ +export type TextPart = { type: "text"; content: string }; +export type FunctionCallPart = { + type: "function_call"; + id: string; + callId: string; + name: string; + arguments: string; +}; +export type FunctionCallOutputPart = { + type: "function_call_output"; + id: string; + callId: string; + output: string; +}; +export type AssistantPart = + | TextPart + | FunctionCallPart + | FunctionCallOutputPart; + +export type ChatMessage = + | { role: "user"; content: string } + | { role: "assistant"; parts: AssistantPart[] }; + +export interface SSEItem { + type?: string; + id?: string; + call_id?: string; + name?: string; + arguments?: string; + output?: string; +} + +export interface SSEEvent { + type?: string; + delta?: string; + error?: string; + item?: SSEItem; +} + +export interface UseAgentChatOptions { + /** POST URL for invocations (Responses API). Default: "/invocations" */ + invokeUrl?: string; +} + +export interface UseAgentChatReturn { + messages: ChatMessage[]; + loading: boolean; + input: string; + setInput: (value: string) => void; + handleSubmit: (e: React.FormEvent) => void; + /** Messages + current streaming state for display */ + displayMessages: ChatMessage[]; + /** True when the last message is still streaming text */ + isStreamingText: boolean; +} + +export interface SimpleAgentChatProps { + /** POST URL for invocations. Default: "/invocations" */ + invokeUrl?: string; + /** Placeholder for the message input */ + placeholder?: string; + /** Empty state text when there are no messages */ + emptyMessage?: string; + /** Additional CSS class for the root container */ + className?: string; +} diff --git a/integrations/chat-ui/src/simple-agent-chat/use-agent-chat.ts b/integrations/chat-ui/src/simple-agent-chat/use-agent-chat.ts new file mode 100644 index 000000000..0e3ba0f74 --- /dev/null +++ b/integrations/chat-ui/src/simple-agent-chat/use-agent-chat.ts @@ -0,0 +1,174 @@ +import { useCallback, useMemo, useState } from "react"; +import type { + AssistantPart, + ChatMessage, + SSEEvent, + UseAgentChatOptions, + UseAgentChatReturn, +} from "./types"; +import { serializeForApi } from "./utils"; + +/** + * Manages agent chat state and streaming via POST /invocations (Responses API SSE). + * Returns messages, loading state, input state, submit handler, and derived display list. + */ +export function useAgentChat( + options: UseAgentChatOptions = {}, +): UseAgentChatReturn { + const { invokeUrl = "/invocations" } = options; + const [messages, setMessages] = useState([]); + const [streamingParts, setStreamingParts] = useState([]); + const [streamingText, setStreamingText] = useState(""); + const [loading, setLoading] = useState(false); + const [input, setInput] = useState(""); + + const handleSubmit = useCallback( + async (e: React.FormEvent) => { + e.preventDefault(); + const text = input.trim(); + if (!text || loading) return; + + const userMessage: ChatMessage = { role: "user", content: text }; + setInput(""); + setMessages((prev) => [...prev, userMessage]); + setLoading(true); + setStreamingParts([]); + setStreamingText(""); + + try { + const response = await fetch(invokeUrl, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + input: [...messages, userMessage].map(serializeForApi), + stream: true, + }), + }); + + if (!response.ok) { + const err = await response.json().catch(() => ({})); + throw new Error( + (err as { error?: string }).error ?? `HTTP ${response.status}`, + ); + } + + const reader = response.body?.getReader(); + if (!reader) throw new Error("No response body"); + + const decoder = new TextDecoder(); + let buffer = ""; + let fullText = ""; + const parts: AssistantPart[] = []; + const seenItemIds = new Set(); + + for (;;) { + const { done, value } = await reader.read(); + if (done) break; + buffer += decoder.decode(value, { stream: true }); + const lines = buffer.split("\n"); + buffer = lines.pop() ?? ""; + + for (const line of lines) { + if (!line.startsWith("data: ")) continue; + const payload = line.slice(6); + if (payload === "[DONE]") continue; + + let data: SSEEvent; + try { + data = JSON.parse(payload); + } catch { + continue; + } + + if (data.type === "response.output_item.added" && data.item) { + const item = data.item; + const id = + item.id ?? `${item.type}_${Date.now()}_${Math.random()}`; + if (seenItemIds.has(id)) continue; + seenItemIds.add(id); + + if (item.type === "function_call" && item.name != null) { + parts.push({ + type: "function_call", + id, + callId: item.call_id ?? id, + name: item.name, + arguments: item.arguments ?? "{}", + }); + } else if ( + item.type === "function_call_output" && + item.call_id != null + ) { + parts.push({ + type: "function_call_output", + id, + callId: item.call_id, + output: item.output ?? "", + }); + } + setStreamingParts([...parts]); + } + + if (data.type === "response.output_text.delta" && data.delta) { + fullText += data.delta; + setStreamingText(fullText); + } + } + } + + const finalParts: AssistantPart[] = [...parts]; + if (fullText) { + finalParts.push({ type: "text", content: fullText }); + } + + setMessages((prev) => [ + ...prev, + { role: "assistant", parts: finalParts }, + ]); + setStreamingParts([]); + setStreamingText(""); + } catch (err) { + const errorText = + err instanceof Error ? err.message : "Something went wrong"; + setMessages((prev) => [ + ...prev, + { + role: "assistant", + parts: [{ type: "text", content: `Error: ${errorText}` }], + }, + ]); + setStreamingParts([]); + setStreamingText(""); + } finally { + setLoading(false); + } + }, + [input, loading, messages, invokeUrl], + ); + + const displayMessages = useMemo(() => { + if (loading && (streamingParts.length > 0 || streamingText)) { + const streamingPartList: AssistantPart[] = [...streamingParts]; + if (streamingText) { + streamingPartList.push({ type: "text", content: streamingText }); + } + return [ + ...messages, + { role: "assistant" as const, parts: streamingPartList }, + ]; + } + return messages; + }, [messages, streamingParts, streamingText, loading]); + + const isStreamingText = Boolean(loading && streamingText); + + return { + messages, + loading, + input, + setInput, + handleSubmit, + displayMessages, + isStreamingText, + }; +} diff --git a/integrations/chat-ui/src/simple-agent-chat/utils.ts b/integrations/chat-ui/src/simple-agent-chat/utils.ts new file mode 100644 index 000000000..497423f75 --- /dev/null +++ b/integrations/chat-ui/src/simple-agent-chat/utils.ts @@ -0,0 +1,32 @@ +import type { ChatMessage } from "./types"; + +/** Serialize chat message for the Responses API request body. */ +export function serializeForApi(msg: ChatMessage): Record { + if (msg.role === "user") { + return { role: "user", content: msg.content }; + } + const content = msg.parts.map((p) => { + if (p.type === "text") + return { type: "output_text" as const, text: p.content }; + if (p.type === "function_call") + return { + type: "function_call" as const, + name: p.name, + arguments: p.arguments, + }; + return { + type: "function_call_output" as const, + call_id: p.callId, + output: p.output, + }; + }); + return { role: "assistant", content }; +} + +export function tryFormatJson(s: string): string { + try { + return JSON.stringify(JSON.parse(s), null, 2); + } catch { + return s; + } +} diff --git a/integrations/chat-ui/src/styles.css b/integrations/chat-ui/src/styles.css new file mode 100644 index 000000000..c832122f7 --- /dev/null +++ b/integrations/chat-ui/src/styles.css @@ -0,0 +1,57 @@ +/* + * @databricks/chat-ui — compiled stylesheet + * + * Import this file to use the styled components without your own Tailwind setup: + * import "@databricks/chat-ui/styles.css"; + * + * If you already use Tailwind with a Shadcn-compatible theme, you can skip this + * import and let your own Tailwind config handle the utility classes. Just ensure + * your content paths include this package's dist files. + * + * Theme customization: override the CSS variables below on :root or any ancestor. + */ + +/* Tailwind CSS variable defaults (--tw-ring-*, --tw-shadow, etc.) */ +@tailwind base; + +/* Utility classes extracted from the component source */ +@tailwind utilities; + +/* ── Default theme (Shadcn-compatible) ─────────────────────────── */ + +:root { + --background: 0 0% 100%; + --foreground: 222.2 84% 4.9%; + --card: 0 0% 100%; + --card-foreground: 222.2 84% 4.9%; + --primary: 222.2 47.4% 11.2%; + --primary-foreground: 210 40% 98%; + --secondary: 210 40% 96.1%; + --secondary-foreground: 222.2 47.4% 11.2%; + --muted: 210 40% 96.1%; + --muted-foreground: 215.4 16.3% 46.9%; + --accent: 210 40% 96.1%; + --accent-foreground: 222.2 47.4% 11.2%; + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 210 40% 98%; + --border: 214.3 31.8% 91.4%; + --input: 214.3 31.8% 91.4%; + --ring: 222.2 84% 4.9%; + --radius: 0.5rem; +} + +/* ── Scoped reset ──────────────────────────────────────────────── */ +/* Tailwind's border/ring utilities assume preflight has set */ +/* border-style: solid and box-sizing: border-box. Since we don't */ +/* ship preflight (too invasive for a library), scope the reset to */ +/* our component tree via the [data-chat-ui] attribute. */ + +[data-chat-ui], +[data-chat-ui] *, +[data-chat-ui] *::before, +[data-chat-ui] *::after { + box-sizing: border-box; + border-style: solid; + border-width: 0; + border-color: hsl(var(--border)); +} diff --git a/integrations/chat-ui/tailwind.config.js b/integrations/chat-ui/tailwind.config.js new file mode 100644 index 000000000..226876de4 --- /dev/null +++ b/integrations/chat-ui/tailwind.config.js @@ -0,0 +1,49 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: ["./src/**/*.{ts,tsx}"], + darkMode: "class", + corePlugins: { + preflight: false, + }, + theme: { + extend: { + colors: { + border: "hsl(var(--border))", + input: "hsl(var(--input))", + ring: "hsl(var(--ring))", + background: "hsl(var(--background))", + foreground: "hsl(var(--foreground))", + primary: { + DEFAULT: "hsl(var(--primary))", + foreground: "hsl(var(--primary-foreground))", + }, + secondary: { + DEFAULT: "hsl(var(--secondary))", + foreground: "hsl(var(--secondary-foreground))", + }, + destructive: { + DEFAULT: "hsl(var(--destructive))", + foreground: "hsl(var(--destructive-foreground))", + }, + muted: { + DEFAULT: "hsl(var(--muted))", + foreground: "hsl(var(--muted-foreground))", + }, + accent: { + DEFAULT: "hsl(var(--accent))", + foreground: "hsl(var(--accent-foreground))", + }, + card: { + DEFAULT: "hsl(var(--card))", + foreground: "hsl(var(--card-foreground))", + }, + }, + borderRadius: { + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)", + }, + }, + }, + plugins: [], +}; diff --git a/integrations/chat-ui/tsconfig.json b/integrations/chat-ui/tsconfig.json new file mode 100644 index 000000000..6e98de79f --- /dev/null +++ b/integrations/chat-ui/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "module": "ES2022", + "moduleResolution": "Bundler", + "target": "ES2022", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "outDir": "./dist", + "lib": ["ES2023", "DOM", "DOM.Iterable"], + "jsx": "react-jsx", + "baseUrl": ".", + "noEmit": true, + "isolatedModules": true, + "allowSyntheticDefaultImports": true, + "verbatimModuleSyntax": false + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "node_modules", + "dist" + ] +} diff --git a/integrations/chat-ui/tsdown.config.ts b/integrations/chat-ui/tsdown.config.ts new file mode 100644 index 000000000..7372b5836 --- /dev/null +++ b/integrations/chat-ui/tsdown.config.ts @@ -0,0 +1,17 @@ +import { defineConfig } from "tsdown"; + +export default defineConfig({ + entry: { + index: "./src/index.ts", + }, + format: ["esm", "cjs"], + fixedExtension: true, + dts: true, + outDir: "./dist", + target: "esnext", + clean: true, + sourcemap: true, + external: ["react", "react-dom", "react/jsx-runtime"], + platform: "browser", + treeshake: true, +}); diff --git a/integrations/chat-ui/vitest.config.ts b/integrations/chat-ui/vitest.config.ts new file mode 100644 index 000000000..8b312569e --- /dev/null +++ b/integrations/chat-ui/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + globals: true, + environment: "jsdom", + }, +}); From 02d80633c0f79a2c54b32bc3e64b03dfc555bbae Mon Sep 17 00:00:00 2001 From: Hubert Zub Date: Fri, 20 Mar 2026 10:24:58 +0100 Subject: [PATCH 07/16] Standalone pnpm for chat-ui Add per-package pnpm-lock.yaml and CI/release workflows with explicit pnpm version and cache-dependency-path. --- .github/workflows/chat-ui.yml | 131 ++ .github/workflows/release-chat-ui.yml | 115 ++ integrations/chat-ui/package.json | 8 +- integrations/chat-ui/pnpm-lock.yaml | 2114 +++++++++++++++++++++++++ 4 files changed, 2367 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/chat-ui.yml create mode 100644 .github/workflows/release-chat-ui.yml create mode 100644 integrations/chat-ui/pnpm-lock.yaml diff --git a/.github/workflows/chat-ui.yml b/.github/workflows/chat-ui.yml new file mode 100644 index 000000000..24aa31281 --- /dev/null +++ b/.github/workflows/chat-ui.yml @@ -0,0 +1,131 @@ +name: chat-ui + +on: + push: + branches: + - main + paths: + - "integrations/chat-ui/**" + - ".github/workflows/chat-ui.yml" + pull_request: + types: + - opened + - synchronize + - reopened + - ready_for_review + paths: + - "integrations/chat-ui/**" + - ".github/workflows/chat-ui.yml" + workflow_dispatch: + +defaults: + run: + working-directory: integrations/chat-ui + +jobs: + test: + runs-on: ubuntu-latest + name: "test (node: ${{ matrix.node-version }})" + strategy: + matrix: + node-version: ["18", "20", "22"] + timeout-minutes: 10 + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: "pnpm" + cache-dependency-path: integrations/chat-ui/pnpm-lock.yaml + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Run tests + run: pnpm run test + + typecheck: + runs-on: ubuntu-latest + name: typecheck + timeout-minutes: 10 + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "pnpm" + cache-dependency-path: integrations/chat-ui/pnpm-lock.yaml + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Run typecheck + run: pnpm run typecheck + + format: + runs-on: ubuntu-latest + name: format + timeout-minutes: 10 + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "pnpm" + cache-dependency-path: integrations/chat-ui/pnpm-lock.yaml + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Check formatting + run: pnpm run format:check + + build: + runs-on: ubuntu-latest + name: build + timeout-minutes: 10 + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "pnpm" + cache-dependency-path: integrations/chat-ui/pnpm-lock.yaml + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build package + run: pnpm run build diff --git a/.github/workflows/release-chat-ui.yml b/.github/workflows/release-chat-ui.yml new file mode 100644 index 000000000..edb49cd2f --- /dev/null +++ b/.github/workflows/release-chat-ui.yml @@ -0,0 +1,115 @@ +name: Release @databricks/chat-ui + +on: + workflow_dispatch: + inputs: + production: + description: "Publish to npm? (If unchecked, will publish with --tag next)" + required: true + default: false + type: boolean + +jobs: + release: + runs-on: ubuntu-latest + + permissions: + id-token: write + contents: write + environment: + name: ${{ inputs.production && 'npm' || 'npm-next' }} + url: https://www.npmjs.com/package/@databricks/chat-ui + defaults: + run: + working-directory: integrations/chat-ui + steps: + - uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - uses: actions/setup-node@v4 + with: + node-version: "20" + registry-url: "https://registry.npmjs.org" + cache: "pnpm" + cache-dependency-path: integrations/chat-ui/pnpm-lock.yaml + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Get package version + id: get-version + run: | + PKG_VERSION=$(node -p "require('./package.json').version") + echo "version=$PKG_VERSION" >> $GITHUB_OUTPUT + + - name: Clean + run: pnpm run clean + + - name: Build + run: pnpm run build + + - name: Test + run: pnpm run test + + - name: Typecheck + run: pnpm run typecheck + + - name: Publish to npm + if: inputs.production + run: pnpm publish --access public --provenance --no-git-checks + + - name: Publish to npm (next tag) + if: ${{ !inputs.production }} + run: pnpm publish --access public --tag next --provenance --no-git-checks + + - name: Wait for registry propagation + run: sleep 15 + + - name: Smoke test (production) + if: inputs.production + run: | + PKG_VERSION=${{ steps.get-version.outputs.version }} + mkdir -p /tmp/smoke-test + cd /tmp/smoke-test + npm install @databricks/chat-ui@$PKG_VERSION + INSTALLED_VERSION=$(node -p "require('./node_modules/@databricks/chat-ui/package.json').version") + echo "Expected: $PKG_VERSION" + echo "Installed: $INSTALLED_VERSION" + if [ "$PKG_VERSION" != "$INSTALLED_VERSION" ]; then + echo "Version mismatch!" + exit 1 + fi + echo "Smoke test passed!" + + - name: Smoke test (next tag) + if: ${{ !inputs.production }} + run: | + mkdir -p /tmp/smoke-test + cd /tmp/smoke-test + npm install @databricks/chat-ui@next + INSTALLED_VERSION=$(node -p "require('./node_modules/@databricks/chat-ui/package.json').version") + echo "Installed @next version: $INSTALLED_VERSION" + echo "Smoke test passed!" + + - name: Generate package link + run: | + PKG_VERSION=${{ steps.get-version.outputs.version }} + if [ "${{ inputs.production }}" == "true" ]; then + LINK="https://www.npmjs.com/package/@databricks/chat-ui/v/$PKG_VERSION" + echo "## :rocket: Package Released" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**@databricks/chat-ui v$PKG_VERSION** has been published to npm!" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo ":link: [$LINK]($LINK)" >> $GITHUB_STEP_SUMMARY + else + LINK="https://www.npmjs.com/package/@databricks/chat-ui?activeTab=versions" + echo "## :test_tube: Package Released (next tag)" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**@databricks/chat-ui v$PKG_VERSION** has been published to npm with --tag next!" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo ":link: [$LINK]($LINK)" >> $GITHUB_STEP_SUMMARY + fi diff --git a/integrations/chat-ui/package.json b/integrations/chat-ui/package.json index 8e198fa3b..6a2735537 100644 --- a/integrations/chat-ui/package.json +++ b/integrations/chat-ui/package.json @@ -81,5 +81,11 @@ "ui", "components" ], - "license": "Databricks License" + "license": "Databricks License", + "pnpm": { + "onlyBuiltDependencies": [ + "esbuild", + "rolldown" + ] + } } diff --git a/integrations/chat-ui/pnpm-lock.yaml b/integrations/chat-ui/pnpm-lock.yaml new file mode 100644 index 000000000..ead6f8f20 --- /dev/null +++ b/integrations/chat-ui/pnpm-lock.yaml @@ -0,0 +1,2114 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@radix-ui/react-slot': + specifier: ^1.2.4 + version: 1.2.4(@types/react@19.2.14)(react@19.2.4) + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + tailwind-merge: + specifier: ^3.4.0 + version: 3.5.0 + devDependencies: + '@types/node': + specifier: ^22.0.0 + version: 22.19.15 + '@types/react': + specifier: ^19.0.0 + version: 19.2.14 + '@types/react-dom': + specifier: ^19.0.0 + version: 19.2.3(@types/react@19.2.14) + prettier: + specifier: ^3.0.0 + version: 3.8.1 + react: + specifier: ^19.0.0 + version: 19.2.4 + react-dom: + specifier: ^19.0.0 + version: 19.2.4(react@19.2.4) + tailwindcss: + specifier: ^3.4.0 + version: 3.4.19 + tsdown: + specifier: ^0.9.0 + version: 0.9.9(typescript@5.9.3) + typescript: + specifier: ^5.4.0 + version: 5.9.3 + vitest: + specifier: ^4.0.18 + version: 4.1.0(@types/node@22.19.15)(vite@8.0.1(@types/node@22.19.15)(jiti@1.21.7)) + +packages: + + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + + '@emnapi/core@1.9.1': + resolution: {integrity: sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==} + + '@emnapi/runtime@1.9.1': + resolution: {integrity: sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==} + + '@emnapi/wasi-threads@1.2.0': + resolution: {integrity: sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@napi-rs/wasm-runtime@0.2.12': + resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + + '@napi-rs/wasm-runtime@1.1.1': + resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@oxc-project/types@0.120.0': + resolution: {integrity: sha512-k1YNu55DuvAip/MGE1FTsIuU3FUCn6v/ujG9V7Nq5Df/kX2CWb13hhwD0lmJGMGqE+bE1MXvv9SZVnMzEXlWcg==} + + '@oxc-project/types@0.66.0': + resolution: {integrity: sha512-KF5Wlo2KzQ+jmuCtrGISZoUfdHom7qHavNfPLW2KkeYJfYMGwtiia8KjwtsvNJ49qRiXImOCkPeVPd4bMlbR7w==} + + '@oxc-resolver/binding-darwin-arm64@9.0.2': + resolution: {integrity: sha512-MVyRgP2gzJJtAowjG/cHN3VQXwNLWnY+FpOEsyvDepJki1SdAX/8XDijM1yN6ESD1kr9uhBKjGelC6h3qtT+rA==} + cpu: [arm64] + os: [darwin] + + '@oxc-resolver/binding-darwin-x64@9.0.2': + resolution: {integrity: sha512-7kV0EOFEZ3sk5Hjy4+bfA6XOQpCwbDiDkkHN4BHHyrBHsXxUR05EcEJPPL1WjItefg+9+8hrBmoK0xRoDs41+A==} + cpu: [x64] + os: [darwin] + + '@oxc-resolver/binding-freebsd-x64@9.0.2': + resolution: {integrity: sha512-6OvkEtRXrt8sJ4aVfxHRikjain9nV1clIsWtJ1J3J8NG1ZhjyJFgT00SCvqxbK+pzeWJq6XzHyTCN78ML+lY2w==} + cpu: [x64] + os: [freebsd] + + '@oxc-resolver/binding-linux-arm-gnueabihf@9.0.2': + resolution: {integrity: sha512-aYpNL6o5IRAUIdoweW21TyLt54Hy/ZS9tvzNzF6ya1ckOQ8DLaGVPjGpmzxdNja9j/bbV6aIzBH7lNcBtiOTkQ==} + cpu: [arm] + os: [linux] + + '@oxc-resolver/binding-linux-arm64-gnu@9.0.2': + resolution: {integrity: sha512-RGFW4vCfKMFEIzb9VCY0oWyyY9tR1/o+wDdNePhiUXZU4SVniRPQaZ1SJ0sUFI1k25pXZmzQmIP6cBmazi/Dew==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-arm64-musl@9.0.2': + resolution: {integrity: sha512-lxx/PibBfzqYvut2Y8N2D0Ritg9H8pKO+7NUSJb9YjR/bfk2KRmP8iaUz3zB0JhPtf/W3REs65oKpWxgflGToA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-linux-riscv64-gnu@9.0.2': + resolution: {integrity: sha512-yD28ptS/OuNhwkpXRPNf+/FvrO7lwURLsEbRVcL1kIE0GxNJNMtKgIE4xQvtKDzkhk6ZRpLho5VSrkkF+3ARTQ==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-s390x-gnu@9.0.2': + resolution: {integrity: sha512-WBwEJdspoga2w+aly6JVZeHnxuPVuztw3fPfWrei2P6rNM5hcKxBGWKKT6zO1fPMCB4sdDkFohGKkMHVV1eryQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-x64-gnu@9.0.2': + resolution: {integrity: sha512-a2z3/cbOOTUq0UTBG8f3EO/usFcdwwXnCejfXv42HmV/G8GjrT4fp5+5mVDoMByH3Ce3iVPxj1LmS6OvItKMYQ==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-resolver/binding-linux-x64-musl@9.0.2': + resolution: {integrity: sha512-bHZF+WShYQWpuswB9fyxcgMIWVk4sZQT0wnwpnZgQuvGTZLkYJ1JTCXJMtaX5mIFHf69ngvawnwPIUA4Feil0g==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-resolver/binding-wasm32-wasi@9.0.2': + resolution: {integrity: sha512-I5cSgCCh5nFozGSHz+PjIOfrqW99eUszlxKLgoNNzQ1xQ2ou9ZJGzcZ94BHsM9SpyYHLtgHljmOZxCT9bgxYNA==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@oxc-resolver/binding-win32-arm64-msvc@9.0.2': + resolution: {integrity: sha512-5IhoOpPr38YWDWRCA5kP30xlUxbIJyLAEsAK7EMyUgqygBHEYLkElaKGgS0X5jRXUQ6l5yNxuW73caogb2FYaw==} + cpu: [arm64] + os: [win32] + + '@oxc-resolver/binding-win32-x64-msvc@9.0.2': + resolution: {integrity: sha512-Qc40GDkaad9rZksSQr2l/V9UubigIHsW69g94Gswc2sKYB3XfJXfIfyV8WTJ67u6ZMXsZ7BH1msSC6Aen75mCg==} + cpu: [x64] + os: [win32] + + '@oxc-transform/binding-darwin-arm64@0.67.0': + resolution: {integrity: sha512-P3zBMhpOQceNSys3/ZqvrjuRvcIbVzfGFN/tH34HlVkOjOmfGK1mOWjORsGAZtbgh1muXrF6mQETLzFjfYndXQ==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [darwin] + + '@oxc-transform/binding-darwin-x64@0.67.0': + resolution: {integrity: sha512-B52aeo/C3spYHcwFQ4nAbDkwbMKf0K6ncWM8GrVUgGu8PPECLBhjPCW11kPW/lt9FxwrdgVYVzPYlZ6wmJmpEA==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [darwin] + + '@oxc-transform/binding-linux-arm-gnueabihf@0.67.0': + resolution: {integrity: sha512-5Ir1eQrC9lvj/rR1TJVGwOR4yLgXTLmfKHIfpVH7GGSQrzK7VMUfHWX+dAsX1VutaeE8puXIqtYvf9cHLw78dw==} + engines: {node: '>=14.0.0'} + cpu: [arm] + os: [linux] + + '@oxc-transform/binding-linux-arm64-gnu@0.67.0': + resolution: {integrity: sha512-zTqfPET5+hZfJ3/dMqJboKxrpXMXk+j2HVdvX0wVhW2MI7n7hwELl+In6Yu20nXuEyJkNQlWHbNPCUfpM+cBWw==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxc-transform/binding-linux-arm64-musl@0.67.0': + resolution: {integrity: sha512-jzz/ATUhZ8wetb4gm5GwzheZns3Qj1CZ+DIMmD8nBxQXszmTS/fqnAPpgzruyLqkXBUuUfF3pHv5f/UmuHReuQ==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxc-transform/binding-linux-x64-gnu@0.67.0': + resolution: {integrity: sha512-Qy2+tfglJ8yX6guC1EDAnuuzRZIXciXO9UwOewxyiahLxwuTpj/wvvZN3Cb1SA3c14zrwb2TNMZvaXS1/OS5Pg==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxc-transform/binding-linux-x64-musl@0.67.0': + resolution: {integrity: sha512-tHoYgDIRhgvh+/wIrzAk3cUoj/LSSoJAdsZW9XRlaixFW/TF2puxRyaS1hRco0bcKTwotXl/eDYqZmhIfUyGRQ==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxc-transform/binding-wasm32-wasi@0.67.0': + resolution: {integrity: sha512-ZPT+1HECf7WUnotodIuS8tvSkwaiCdC2DDw8HVRmlerbS6iPYIPKyBCvkSM4RyUx0kljZtB9AciLCkEbwy5/zA==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@oxc-transform/binding-win32-arm64-msvc@0.67.0': + resolution: {integrity: sha512-+E3lOHCk4EuIk6IjshBAARknAUpgH+gHTtZxCPqK4AWYA+Tls2J6C0FVM48uZ4m3rZpAq8ZszM9JZVAkOaynBQ==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [win32] + + '@oxc-transform/binding-win32-x64-msvc@0.67.0': + resolution: {integrity: sha512-3pIIFb9g5aFrAODTQVJYitq+ONHgDJ4IYk/7pk+jsG6JpKUkURd0auUlxvriO11fFit5hdwy+wIbU4kBvyRUkg==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [win32] + + '@quansync/fs@1.0.0': + resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} + + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-slot@1.2.4': + resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@rolldown/binding-android-arm64@1.0.0-rc.10': + resolution: {integrity: sha512-jOHxwXhxmFKuXztiu1ORieJeTbx5vrTkcOkkkn2d35726+iwhrY1w/+nYY/AGgF12thg33qC3R1LMBF5tHTZHg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-2F4bhDtV6CHBx7JMiT9xvmxkcZLHFmonfbli36RyfvgThDOAu92bis28zDTdguDY85lN/jBRKX/eOvX+T5hMkg==} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-arm64@1.0.0-rc.10': + resolution: {integrity: sha512-gED05Teg/vtTZbIJBc4VNMAxAFDUPkuO/rAIyyxZjTj1a1/s6z5TII/5yMGZ0uLRCifEtwUQn8OlYzuYc0m70w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-8VMChhFLeD/oOAQUspFtxZaV7ctDob63w626kwvBBIHtlpY2Ohw4rsfjjtGckyrTCI/RROgZv/TVVEsG3GkgLw==} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.0-rc.10': + resolution: {integrity: sha512-rI15NcM1mA48lqrIxVkHfAqcyFLcQwyXWThy+BQ5+mkKKPvSO26ir+ZDp36AgYoYVkqvMcdS8zOE6SeBsR9e8A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-4W28EgaIidbWIpwB3hESMBfiOSs7LBFpJGa8JIV488qLEnTR/pqzxDEoOPobhRSJ1lJlv0vUgA8+DKBIldo2gw==} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-freebsd-x64@1.0.0-rc.10': + resolution: {integrity: sha512-XZRXHdTa+4ME1MuDVp021+doQ+z6Ei4CCFmNc5/sKbqb8YmkiJdj8QKlV3rCI0AJtAeSB5n0WGPuJWNL9p/L2w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-1ECtyzIKlAHikR7BhS4hk7Hxw8xCH6W3S+Sb74EM0vy5AqPvWSbgLfAwagYC7gNDcMMby3I757X7qih5fIrGiw==} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.10': + resolution: {integrity: sha512-R0SQMRluISSLzFE20sPWYHVmJdDQnRyc/FzSCN72BqQmh2SOZUFG+N3/vBZpR4C6WpEUVYJLrYUXaj43sJsNLA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-wU1kp8qPRUKC8N82dNs3F5+UyKRww9TUEO5dQ5mxCb0cG+y4l5rVaXpMgvL0VuQahPVvTMs577QPhJGb4iDONw==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.10': + resolution: {integrity: sha512-Y1reMrV/o+cwpduYhJuOE3OMKx32RMYCidf14y+HssARRmhDuWXJ4yVguDg2R/8SyyGNo+auzz64LnPK9Hq6jg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-odDjO2UtEEMAzwmLHEOKylJjQa+em1REAO9H19PA+O+lPu6evVbre5bqu8qCjEtHG1Q034LpZR86imCP2arb/w==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.10': + resolution: {integrity: sha512-vELN+HNb2IzuzSBUOD4NHmP9yrGwl1DVM29wlQvx1OLSclL0NgVWnVDKl/8tEks79EFek/kebQKnNJkIAA4W2g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.10': + resolution: {integrity: sha512-ZqrufYTgzxbHwpqOjzSsb0UV/aV2TFIY5rP8HdsiPTv/CuAgCRjM6s9cYFwQ4CNH+hf9Y4erHW1GjZuZ7WoI7w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.10': + resolution: {integrity: sha512-gSlmVS1FZJSRicA6IyjoRoKAFK7IIHBs7xJuHRSmjImqk3mPPWbR7RhbnfH2G6bcmMEllCt2vQ/7u9e6bBnByg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-Ty2T67t2Oj1lg417ATRENxdk8Jkkksc/YQdCJyvkGqteHe60pSU2GGP/tLWGB+I0Ox+u387bzU/SmfmrHZk9aw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.10': + resolution: {integrity: sha512-eOCKUpluKgfObT2pHjztnaWEIbUabWzk3qPZ5PuacuPmr4+JtQG4k2vGTY0H15edaTnicgU428XW/IH6AimcQw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-Fm1TxyeVE+gy74HM26CwbEOUndIoWAMgWkVDxYBD64tayvp5JvltpGHaqCg6x5i+X2F5XCDCItqwVlC7/mTxIw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.10': + resolution: {integrity: sha512-Xdf2jQbfQowJnLcgYfD/m0Uu0Qj5OdxKallD78/IPPfzaiaI4KRAwZzHcKQ4ig1gtg1SuzC7jovNiM2TzQsBXA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.10': + resolution: {integrity: sha512-o1hYe8hLi1EY6jgPFyxQgQ1wcycX+qz8eEbVmot2hFkgUzPxy9+kF0u0NIQBeDq+Mko47AkaFFaChcvZa9UX9Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-AEZzTyGerfkffXmtv7kFJbHWkryNeolk0Br+yhH1wZyN6Tt6aebqICDL8KNRO2iExoEWzyYS6dPxh0QmvNTfUQ==} + engines: {node: '>=14.21.3'} + cpu: [wasm32] + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.10': + resolution: {integrity: sha512-Ugv9o7qYJudqQO5Y5y2N2SOo6S4WiqiNOpuQyoPInnhVzCY+wi/GHltcLHypG9DEUYMB0iTB/huJrpadiAcNcA==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-0lskDFKQwf5PMjl17qHAroU6oVU0Zn8NbAH/PdM9QB1emOzyFDGa20d4kESGeo3Uq7xOKXcTORJV/JwKIBORqw==} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.10': + resolution: {integrity: sha512-7UODQb4fQUNT/vmgDZBl3XOBAIOutP5R3O/rkxg0aLfEGQ4opbCgU5vOw/scPe4xOqBwL9fw7/RP1vAMZ6QlAQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-DfG1S0zGKnUfr95cNCmR4YPiZ/moS7Tob5eV+9r5JGeHZVWFHWwvJdR0jArj6Ty0LbBFDTVVB3iAvqRSji+l0Q==} + cpu: [ia32] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.8-commit.151352b': + resolution: {integrity: sha512-5HZEtc8U2I1O903hXBynWtWaf+qzAFj66h5B7gOtVcvqIk+lKRVSupA85OdIvR7emrsYU25ikpfiU5Jhg9kTbQ==} + cpu: [x64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.10': + resolution: {integrity: sha512-PYxKHMVHOb5NJuDL53vBUl1VwUjymDcYI6rzpIni0C9+9mTiJedvUxSk7/RPp7OOAm3v+EjgMu9bIy3N6b408w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.0-rc.10': + resolution: {integrity: sha512-UkVDEFk1w3mveXeKgaTuYfKWtPbvgck1dT8TUG3bnccrH0XtLTuAyfCoks4Q/M5ZGToSVJTIQYCzy2g/atAOeg==} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/node@22.19.15': + resolution: {integrity: sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==} + + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.14': + resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + + '@valibot/to-json-schema@1.0.0': + resolution: {integrity: sha512-/9crJgPptVsGCL6X+JPDQyaJwkalSZ/52WuF8DiRUxJgcmpNdzYRfZ+gqMEP8W3CTVfuMWPqqvIgfwJ97f9Etw==} + peerDependencies: + valibot: ^1.0.0 + + '@vitest/expect@4.1.0': + resolution: {integrity: sha512-EIxG7k4wlWweuCLG9Y5InKFwpMEOyrMb6ZJ1ihYu02LVj/bzUwn2VMU+13PinsjRW75XnITeFrQBMH5+dLvCDA==} + + '@vitest/mocker@4.1.0': + resolution: {integrity: sha512-evxREh+Hork43+Y4IOhTo+h5lGmVRyjqI739Rz4RlUPqwrkFFDF6EMvOOYjTx4E8Tl6gyCLRL8Mu7Ry12a13Tw==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@4.1.0': + resolution: {integrity: sha512-3RZLZlh88Ib0J7NQTRATfc/3ZPOnSUn2uDBUoGNn5T36+bALixmzphN26OUD3LRXWkJu4H0s5vvUeqBiw+kS0A==} + + '@vitest/runner@4.1.0': + resolution: {integrity: sha512-Duvx2OzQ7d6OjchL+trw+aSrb9idh7pnNfxrklo14p3zmNL4qPCDeIJAK+eBKYjkIwG96Bc6vYuxhqDXQOWpoQ==} + + '@vitest/snapshot@4.1.0': + resolution: {integrity: sha512-0Vy9euT1kgsnj1CHttwi9i9o+4rRLEaPRSOJ5gyv579GJkNpgJK+B4HSv/rAWixx2wdAFci1X4CEPjiu2bXIMg==} + + '@vitest/spy@4.1.0': + resolution: {integrity: sha512-pz77k+PgNpyMDv2FV6qmk5ZVau6c3R8HC8v342T2xlFxQKTrSeYw9waIJG8KgV9fFwAtTu4ceRzMivPTH6wSxw==} + + '@vitest/utils@4.1.0': + resolution: {integrity: sha512-XfPXT6a8TZY3dcGY8EdwsBulFCIw+BeeX0RZn2x/BtiY/75YGh8FeWGG8QISN/WhaqSrE2OrlDgtF8q5uhOTmw==} + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + ansis@3.17.0: + resolution: {integrity: sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==} + engines: {node: '>=14'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + ast-kit@1.4.3: + resolution: {integrity: sha512-MdJqjpodkS5J149zN0Po+HPshkTdUyrvF7CKTafUgv69vBSPtncrj+3IiUgqdd7ElIEkbeXCsEouBUwLrw9Ilg==} + engines: {node: '>=16.14.0'} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + + diff@7.0.0: + resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} + engines: {node: '>=0.3.1'} + + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + + dts-resolver@1.2.0: + resolution: {integrity: sha512-+xNF7raXYI1E3IFB+f3JqvoKYFI8R+1Mh9mpI75yNm3F5XuiC6ErEXe2Lqh9ach+4MQ1tOefzjxulhWGVclYbg==} + engines: {node: '>=20.18.0'} + + empathic@1.1.0: + resolution: {integrity: sha512-rsPft6CK3eHtrlp9Y5ALBb+hfK+DWnA4WFebbazxjWyx8vSm3rZeoM3z9irsjcqO3PYRzlfv27XIB4tz2DV7RA==} + engines: {node: '>=14'} + + es-module-lexer@2.0.0: + resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-tsconfig@4.13.6: + resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + + obug@2.1.1: + resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + + oxc-resolver@9.0.2: + resolution: {integrity: sha512-w838ygc1p7rF+7+h5vR9A+Y9Fc4imy6C3xPthCMkdFUgFvUWkmABeNB8RBDQ6+afk44Q60/UMMQ+gfDUW99fBA==} + + oxc-transform@0.67.0: + resolution: {integrity: sha512-QXwmpLfNrXZoHgIjEtDEf6lhwmvHouNtstNgg/UveczVIjo8VSzd5h25Ea96PoX9KzReJUY/qYa4QSNkJpZGfA==} + engines: {node: '>=14.0.0'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + postcss-import@15.1.0: + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + + postcss-js@4.1.0: + resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.5.8: + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + engines: {node: ^10 || ^12 || >=14} + + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} + engines: {node: '>=14'} + hasBin: true + + quansync@1.0.0: + resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + react-dom@19.2.4: + resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} + peerDependencies: + react: ^19.2.4 + + react@19.2.4: + resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} + engines: {node: '>=0.10.0'} + + read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rolldown-plugin-dts@0.9.11: + resolution: {integrity: sha512-iCIRKmvPLwRV4UKSxhaBo+5wDkvc3+MFiqYYvu7sGLSohzxoDn9WEsjN3y7A6xg3aCuxHh6rlRp8xbX98r1rSg==} + engines: {node: '>=20.18.0'} + peerDependencies: + rolldown: ^1.0.0-beta.7 + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + rolldown@1.0.0-beta.8-commit.151352b: + resolution: {integrity: sha512-TCb6GVaFBk4wB0LERofFDxTO5X1/Sgahr7Yn5UA9XjuFtCwL1CyEhUHX5lUIstcMxjbkLjn2z4TAGwisr6Blvw==} + hasBin: true + peerDependencies: + '@oxc-project/runtime': 0.66.0 + peerDependenciesMeta: + '@oxc-project/runtime': + optional: true + + rolldown@1.0.0-rc.10: + resolution: {integrity: sha512-q7j6vvarRFmKpgJUT8HCAUljkgzEp4LAhPlJUvQhA5LA1SUL36s5QCysMutErzL3EbNOZOkoziSx9iZC4FddKA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@4.0.0: + resolution: {integrity: sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==} + + sucrase@3.35.1: + resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tailwind-merge@3.5.0: + resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==} + + tailwindcss@3.4.19: + resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==} + engines: {node: '>=14.0.0'} + hasBin: true + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@1.0.4: + resolution: {integrity: sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==} + engines: {node: '>=18'} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tinyrainbow@3.1.0: + resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} + engines: {node: '>=14.0.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + tsdown@0.9.9: + resolution: {integrity: sha512-IIGX55rkhaPomNSVrIbA58DRBwTO4ehlDTsw20XSooGqoEZbwpunDc1dRE73wKb1rHdwwBO6NMLOcgV2n1qhpA==} + engines: {node: '>=18.0.0'} + hasBin: true + peerDependencies: + publint: ^0.3.0 + unplugin-unused: ^0.4.0 + peerDependenciesMeta: + publint: + optional: true + unplugin-unused: + optional: true + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + unconfig-core@7.5.0: + resolution: {integrity: sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==} + + unconfig@7.5.0: + resolution: {integrity: sha512-oi8Qy2JV4D3UQ0PsopR28CzdQ3S/5A1zwsUwp/rosSbfhJ5z7b90bIyTwi/F7hCLD4SGcZVjDzd4XoUQcEanvA==} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + unplugin-lightningcss@0.3.3: + resolution: {integrity: sha512-mMNRCNIcxc/3410w7sJdXcPxn0IGZdEpq42OBDyckdGkhOeWYZCG9RkHs72TFyBsS82a4agFDOFU8VrFKF2ZvA==} + engines: {node: '>=18.12.0'} + + unplugin@2.3.11: + resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} + engines: {node: '>=18.12.0'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + valibot@1.0.0: + resolution: {integrity: sha512-1Hc0ihzWxBar6NGeZv7fPLY0QuxFMyxwYR2sF1Blu7Wq7EnremwY2W02tit2ij2VJT8HcSkHAQqmFfl77f73Yw==} + peerDependencies: + typescript: '>=5' + peerDependenciesMeta: + typescript: + optional: true + + vite@8.0.1: + resolution: {integrity: sha512-wt+Z2qIhfFt85uiyRt5LPU4oVEJBXj8hZNWKeqFG4gRG/0RaRGJ7njQCwzFVjO+v4+Ipmf5CY7VdmZRAYYBPHw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.1.0 + esbuild: ^0.27.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@4.1.0: + resolution: {integrity: sha512-YbDrMF9jM2Lqc++2530UourxZHmkKLxrs4+mYhEwqWS97WJ7wOYEkcr+QfRgJ3PW9wz3odRijLZjHEaRLTNbqw==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.1.0 + '@vitest/browser-preview': 4.1.0 + '@vitest/browser-webdriverio': 4.1.0 + '@vitest/ui': 4.1.0 + happy-dom: '*' + jsdom: '*' + vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0 + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + +snapshots: + + '@alloc/quick-lru@5.2.0': {} + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/parser@7.29.2': + dependencies: + '@babel/types': 7.29.0 + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@emnapi/core@1.9.1': + dependencies: + '@emnapi/wasi-threads': 1.2.0 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.9.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@napi-rs/wasm-runtime@0.2.12': + dependencies: + '@emnapi/core': 1.9.1 + '@emnapi/runtime': 1.9.1 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@napi-rs/wasm-runtime@1.1.1': + dependencies: + '@emnapi/core': 1.9.1 + '@emnapi/runtime': 1.9.1 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@oxc-project/types@0.120.0': {} + + '@oxc-project/types@0.66.0': {} + + '@oxc-resolver/binding-darwin-arm64@9.0.2': + optional: true + + '@oxc-resolver/binding-darwin-x64@9.0.2': + optional: true + + '@oxc-resolver/binding-freebsd-x64@9.0.2': + optional: true + + '@oxc-resolver/binding-linux-arm-gnueabihf@9.0.2': + optional: true + + '@oxc-resolver/binding-linux-arm64-gnu@9.0.2': + optional: true + + '@oxc-resolver/binding-linux-arm64-musl@9.0.2': + optional: true + + '@oxc-resolver/binding-linux-riscv64-gnu@9.0.2': + optional: true + + '@oxc-resolver/binding-linux-s390x-gnu@9.0.2': + optional: true + + '@oxc-resolver/binding-linux-x64-gnu@9.0.2': + optional: true + + '@oxc-resolver/binding-linux-x64-musl@9.0.2': + optional: true + + '@oxc-resolver/binding-wasm32-wasi@9.0.2': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@oxc-resolver/binding-win32-arm64-msvc@9.0.2': + optional: true + + '@oxc-resolver/binding-win32-x64-msvc@9.0.2': + optional: true + + '@oxc-transform/binding-darwin-arm64@0.67.0': + optional: true + + '@oxc-transform/binding-darwin-x64@0.67.0': + optional: true + + '@oxc-transform/binding-linux-arm-gnueabihf@0.67.0': + optional: true + + '@oxc-transform/binding-linux-arm64-gnu@0.67.0': + optional: true + + '@oxc-transform/binding-linux-arm64-musl@0.67.0': + optional: true + + '@oxc-transform/binding-linux-x64-gnu@0.67.0': + optional: true + + '@oxc-transform/binding-linux-x64-musl@0.67.0': + optional: true + + '@oxc-transform/binding-wasm32-wasi@0.67.0': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@oxc-transform/binding-win32-arm64-msvc@0.67.0': + optional: true + + '@oxc-transform/binding-win32-x64-msvc@0.67.0': + optional: true + + '@quansync/fs@1.0.0': + dependencies: + quansync: 1.0.0 + + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.14)(react@19.2.4)': + dependencies: + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@radix-ui/react-slot@1.2.4(@types/react@19.2.14)(react@19.2.4)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 + + '@rolldown/binding-android-arm64@1.0.0-rc.10': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-rc.10': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-rc.10': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-rc.10': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.10': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.10': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.10': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.10': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.10': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.10': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.10': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.10': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.8-commit.151352b': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.10': + dependencies: + '@napi-rs/wasm-runtime': 1.1.1 + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.10': + optional: true + + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.8-commit.151352b': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.10': + optional: true + + '@rolldown/pluginutils@1.0.0-rc.10': {} + + '@standard-schema/spec@1.1.0': {} + + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/deep-eql@4.0.2': {} + + '@types/estree@1.0.8': {} + + '@types/node@22.19.15': + dependencies: + undici-types: 6.21.0 + + '@types/react-dom@19.2.3(@types/react@19.2.14)': + dependencies: + '@types/react': 19.2.14 + + '@types/react@19.2.14': + dependencies: + csstype: 3.2.3 + + '@valibot/to-json-schema@1.0.0(valibot@1.0.0(typescript@5.9.3))': + dependencies: + valibot: 1.0.0(typescript@5.9.3) + + '@vitest/expect@4.1.0': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.1.0 + '@vitest/utils': 4.1.0 + chai: 6.2.2 + tinyrainbow: 3.1.0 + + '@vitest/mocker@4.1.0(vite@8.0.1(@types/node@22.19.15)(jiti@1.21.7))': + dependencies: + '@vitest/spy': 4.1.0 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 8.0.1(@types/node@22.19.15)(jiti@1.21.7) + + '@vitest/pretty-format@4.1.0': + dependencies: + tinyrainbow: 3.1.0 + + '@vitest/runner@4.1.0': + dependencies: + '@vitest/utils': 4.1.0 + pathe: 2.0.3 + + '@vitest/snapshot@4.1.0': + dependencies: + '@vitest/pretty-format': 4.1.0 + '@vitest/utils': 4.1.0 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@4.1.0': {} + + '@vitest/utils@4.1.0': + dependencies: + '@vitest/pretty-format': 4.1.0 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.0 + + acorn@8.16.0: {} + + ansis@3.17.0: {} + + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@5.0.2: {} + + assertion-error@2.0.1: {} + + ast-kit@1.4.3: + dependencies: + '@babel/parser': 7.29.2 + pathe: 2.0.3 + + binary-extensions@2.3.0: {} + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + cac@6.7.14: {} + + camelcase-css@2.0.1: {} + + chai@6.2.2: {} + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + + clsx@2.1.1: {} + + commander@4.1.1: {} + + consola@3.4.2: {} + + convert-source-map@2.0.0: {} + + cssesc@3.0.0: {} + + csstype@3.2.3: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + defu@6.1.4: {} + + detect-libc@2.1.2: {} + + didyoumean@1.2.2: {} + + diff@7.0.0: {} + + dlv@1.1.3: {} + + dts-resolver@1.2.0: + dependencies: + oxc-resolver: 9.0.2 + pathe: 2.0.3 + + empathic@1.1.0: {} + + es-module-lexer@2.0.0: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + expect-type@1.3.0: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + get-tsconfig@4.13.6: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hookable@5.5.3: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + jiti@1.21.7: {} + + jiti@2.6.1: {} + + jsesc@3.1.0: {} + + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + ms@2.1.3: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanoid@3.3.11: {} + + normalize-path@3.0.0: {} + + object-assign@4.1.1: {} + + object-hash@3.0.0: {} + + obug@2.1.1: {} + + oxc-resolver@9.0.2: + optionalDependencies: + '@oxc-resolver/binding-darwin-arm64': 9.0.2 + '@oxc-resolver/binding-darwin-x64': 9.0.2 + '@oxc-resolver/binding-freebsd-x64': 9.0.2 + '@oxc-resolver/binding-linux-arm-gnueabihf': 9.0.2 + '@oxc-resolver/binding-linux-arm64-gnu': 9.0.2 + '@oxc-resolver/binding-linux-arm64-musl': 9.0.2 + '@oxc-resolver/binding-linux-riscv64-gnu': 9.0.2 + '@oxc-resolver/binding-linux-s390x-gnu': 9.0.2 + '@oxc-resolver/binding-linux-x64-gnu': 9.0.2 + '@oxc-resolver/binding-linux-x64-musl': 9.0.2 + '@oxc-resolver/binding-wasm32-wasi': 9.0.2 + '@oxc-resolver/binding-win32-arm64-msvc': 9.0.2 + '@oxc-resolver/binding-win32-x64-msvc': 9.0.2 + + oxc-transform@0.67.0: + optionalDependencies: + '@oxc-transform/binding-darwin-arm64': 0.67.0 + '@oxc-transform/binding-darwin-x64': 0.67.0 + '@oxc-transform/binding-linux-arm-gnueabihf': 0.67.0 + '@oxc-transform/binding-linux-arm64-gnu': 0.67.0 + '@oxc-transform/binding-linux-arm64-musl': 0.67.0 + '@oxc-transform/binding-linux-x64-gnu': 0.67.0 + '@oxc-transform/binding-linux-x64-musl': 0.67.0 + '@oxc-transform/binding-wasm32-wasi': 0.67.0 + '@oxc-transform/binding-win32-arm64-msvc': 0.67.0 + '@oxc-transform/binding-win32-x64-msvc': 0.67.0 + + path-parse@1.0.7: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.3: {} + + pify@2.3.0: {} + + pirates@4.0.7: {} + + postcss-import@15.1.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.11 + + postcss-js@4.1.0(postcss@8.5.8): + dependencies: + camelcase-css: 2.0.1 + postcss: 8.5.8 + + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.8): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + jiti: 1.21.7 + postcss: 8.5.8 + + postcss-nested@6.2.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-selector-parser: 6.1.2 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-value-parser@4.2.0: {} + + postcss@8.5.8: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prettier@3.8.1: {} + + quansync@1.0.0: {} + + queue-microtask@1.2.3: {} + + react-dom@19.2.4(react@19.2.4): + dependencies: + react: 19.2.4 + scheduler: 0.27.0 + + react@19.2.4: {} + + read-cache@1.0.0: + dependencies: + pify: 2.3.0 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + readdirp@4.1.2: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.1.0: {} + + rolldown-plugin-dts@0.9.11(rolldown@1.0.0-beta.8-commit.151352b(typescript@5.9.3))(typescript@5.9.3): + dependencies: + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + ast-kit: 1.4.3 + debug: 4.4.3 + dts-resolver: 1.2.0 + get-tsconfig: 4.13.6 + oxc-transform: 0.67.0 + rolldown: 1.0.0-beta.8-commit.151352b(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + rolldown@1.0.0-beta.8-commit.151352b(typescript@5.9.3): + dependencies: + '@oxc-project/types': 0.66.0 + '@valibot/to-json-schema': 1.0.0(valibot@1.0.0(typescript@5.9.3)) + ansis: 3.17.0 + valibot: 1.0.0(typescript@5.9.3) + optionalDependencies: + '@rolldown/binding-darwin-arm64': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-darwin-x64': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-freebsd-x64': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-linux-x64-musl': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-wasm32-wasi': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.8-commit.151352b + '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.8-commit.151352b + transitivePeerDependencies: + - typescript + + rolldown@1.0.0-rc.10: + dependencies: + '@oxc-project/types': 0.120.0 + '@rolldown/pluginutils': 1.0.0-rc.10 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-rc.10 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.10 + '@rolldown/binding-darwin-x64': 1.0.0-rc.10 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.10 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.10 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.10 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.10 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.10 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.10 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.10 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.10 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.10 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.10 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.10 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.10 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + scheduler@0.27.0: {} + + siginfo@2.0.0: {} + + source-map-js@1.2.1: {} + + stackback@0.0.2: {} + + std-env@4.0.0: {} + + sucrase@3.35.1: + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + commander: 4.1.1 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + tinyglobby: 0.2.15 + ts-interface-checker: 0.1.13 + + supports-preserve-symlinks-flag@1.0.0: {} + + tailwind-merge@3.5.0: {} + + tailwindcss@3.4.19: + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.3 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.7 + lilconfig: 3.1.3 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.5.8 + postcss-import: 15.1.0(postcss@8.5.8) + postcss-js: 4.1.0(postcss@8.5.8) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.8) + postcss-nested: 6.2.0(postcss@8.5.8) + postcss-selector-parser: 6.1.2 + resolve: 1.22.11 + sucrase: 3.35.1 + transitivePeerDependencies: + - tsx + - yaml + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + tinybench@2.9.0: {} + + tinyexec@1.0.4: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tinyrainbow@3.1.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + ts-interface-checker@0.1.13: {} + + tsdown@0.9.9(typescript@5.9.3): + dependencies: + ansis: 3.17.0 + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.4.2 + debug: 4.4.3 + diff: 7.0.0 + empathic: 1.1.0 + hookable: 5.5.3 + lightningcss: 1.32.0 + rolldown: 1.0.0-beta.8-commit.151352b(typescript@5.9.3) + rolldown-plugin-dts: 0.9.11(rolldown@1.0.0-beta.8-commit.151352b(typescript@5.9.3))(typescript@5.9.3) + tinyexec: 1.0.4 + tinyglobby: 0.2.15 + unconfig: 7.5.0 + unplugin-lightningcss: 0.3.3 + transitivePeerDependencies: + - '@oxc-project/runtime' + - supports-color + - typescript + + tslib@2.8.1: + optional: true + + typescript@5.9.3: {} + + unconfig-core@7.5.0: + dependencies: + '@quansync/fs': 1.0.0 + quansync: 1.0.0 + + unconfig@7.5.0: + dependencies: + '@quansync/fs': 1.0.0 + defu: 6.1.4 + jiti: 2.6.1 + quansync: 1.0.0 + unconfig-core: 7.5.0 + + undici-types@6.21.0: {} + + unplugin-lightningcss@0.3.3: + dependencies: + lightningcss: 1.32.0 + magic-string: 0.30.21 + unplugin: 2.3.11 + + unplugin@2.3.11: + dependencies: + '@jridgewell/remapping': 2.3.5 + acorn: 8.16.0 + picomatch: 4.0.3 + webpack-virtual-modules: 0.6.2 + + util-deprecate@1.0.2: {} + + valibot@1.0.0(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + + vite@8.0.1(@types/node@22.19.15)(jiti@1.21.7): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.3 + postcss: 8.5.8 + rolldown: 1.0.0-rc.10 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 22.19.15 + fsevents: 2.3.3 + jiti: 1.21.7 + + vitest@4.1.0(@types/node@22.19.15)(vite@8.0.1(@types/node@22.19.15)(jiti@1.21.7)): + dependencies: + '@vitest/expect': 4.1.0 + '@vitest/mocker': 4.1.0(vite@8.0.1(@types/node@22.19.15)(jiti@1.21.7)) + '@vitest/pretty-format': 4.1.0 + '@vitest/runner': 4.1.0 + '@vitest/snapshot': 4.1.0 + '@vitest/spy': 4.1.0 + '@vitest/utils': 4.1.0 + es-module-lexer: 2.0.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 4.0.0 + tinybench: 2.9.0 + tinyexec: 1.0.4 + tinyglobby: 0.2.15 + tinyrainbow: 3.1.0 + vite: 8.0.1(@types/node@22.19.15)(jiti@1.21.7) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.19.15 + transitivePeerDependencies: + - msw + + webpack-virtual-modules@0.6.2: {} + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 From b49eed77a0cc45ea65e6018c55419a5725b31c0a Mon Sep 17 00:00:00 2001 From: Hubert Zub Date: Tue, 24 Mar 2026 13:02:29 +0100 Subject: [PATCH 08/16] Move to appkit-agent Signed-off-by: Hubert Zub --- .github/workflows/chat-ui.yml | 131 - .github/workflows/release-chat-ui.yml | 115 - integrations/appkit-agent/package.json | 39 +- integrations/appkit-agent/pnpm-lock.yaml | 1042 +++++--- .../chat-ui/simple}/agent-chat-message.tsx | 0 .../src/chat-ui/simple}/agent-chat-part.tsx | 0 .../src/chat-ui/simple}/index.ts | 0 .../src/chat-ui/simple}/primitives/button.tsx | 0 .../src/chat-ui/simple}/primitives/card.tsx | 0 .../src/chat-ui/simple}/primitives/cn.ts | 0 .../src/chat-ui/simple}/simple-agent-chat.tsx | 0 .../src/chat-ui/simple}/styles.css | 6 +- .../src/chat-ui/simple}/types.ts | 0 .../src/chat-ui/simple}/use-agent-chat.ts | 0 .../src/chat-ui/simple}/utils.ts | 0 .../tailwind.chat-ui.config.js} | 2 +- integrations/appkit-agent/tsconfig.json | 3 +- integrations/appkit-agent/tsdown.config.ts | 67 +- integrations/chat-ui/package.json | 91 - integrations/chat-ui/pnpm-lock.yaml | 2114 ----------------- integrations/chat-ui/src/index.ts | 18 - integrations/chat-ui/tsconfig.json | 30 - integrations/chat-ui/tsdown.config.ts | 17 - integrations/chat-ui/vitest.config.ts | 8 - 24 files changed, 793 insertions(+), 2890 deletions(-) delete mode 100644 .github/workflows/chat-ui.yml delete mode 100644 .github/workflows/release-chat-ui.yml rename integrations/{chat-ui/src/simple-agent-chat => appkit-agent/src/chat-ui/simple}/agent-chat-message.tsx (100%) rename integrations/{chat-ui/src/simple-agent-chat => appkit-agent/src/chat-ui/simple}/agent-chat-part.tsx (100%) rename integrations/{chat-ui/src/simple-agent-chat => appkit-agent/src/chat-ui/simple}/index.ts (100%) rename integrations/{chat-ui/src/simple-agent-chat => appkit-agent/src/chat-ui/simple}/primitives/button.tsx (100%) rename integrations/{chat-ui/src/simple-agent-chat => appkit-agent/src/chat-ui/simple}/primitives/card.tsx (100%) rename integrations/{chat-ui/src/simple-agent-chat => appkit-agent/src/chat-ui/simple}/primitives/cn.ts (100%) rename integrations/{chat-ui/src/simple-agent-chat => appkit-agent/src/chat-ui/simple}/simple-agent-chat.tsx (100%) rename integrations/{chat-ui/src => appkit-agent/src/chat-ui/simple}/styles.css (89%) rename integrations/{chat-ui/src/simple-agent-chat => appkit-agent/src/chat-ui/simple}/types.ts (100%) rename integrations/{chat-ui/src/simple-agent-chat => appkit-agent/src/chat-ui/simple}/use-agent-chat.ts (100%) rename integrations/{chat-ui/src/simple-agent-chat => appkit-agent/src/chat-ui/simple}/utils.ts (100%) rename integrations/{chat-ui/tailwind.config.js => appkit-agent/tailwind.chat-ui.config.js} (96%) delete mode 100644 integrations/chat-ui/package.json delete mode 100644 integrations/chat-ui/pnpm-lock.yaml delete mode 100644 integrations/chat-ui/src/index.ts delete mode 100644 integrations/chat-ui/tsconfig.json delete mode 100644 integrations/chat-ui/tsdown.config.ts delete mode 100644 integrations/chat-ui/vitest.config.ts diff --git a/.github/workflows/chat-ui.yml b/.github/workflows/chat-ui.yml deleted file mode 100644 index 24aa31281..000000000 --- a/.github/workflows/chat-ui.yml +++ /dev/null @@ -1,131 +0,0 @@ -name: chat-ui - -on: - push: - branches: - - main - paths: - - "integrations/chat-ui/**" - - ".github/workflows/chat-ui.yml" - pull_request: - types: - - opened - - synchronize - - reopened - - ready_for_review - paths: - - "integrations/chat-ui/**" - - ".github/workflows/chat-ui.yml" - workflow_dispatch: - -defaults: - run: - working-directory: integrations/chat-ui - -jobs: - test: - runs-on: ubuntu-latest - name: "test (node: ${{ matrix.node-version }})" - strategy: - matrix: - node-version: ["18", "20", "22"] - timeout-minutes: 10 - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - version: 10 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - cache: "pnpm" - cache-dependency-path: integrations/chat-ui/pnpm-lock.yaml - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Run tests - run: pnpm run test - - typecheck: - runs-on: ubuntu-latest - name: typecheck - timeout-minutes: 10 - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - version: 10 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "20" - cache: "pnpm" - cache-dependency-path: integrations/chat-ui/pnpm-lock.yaml - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Run typecheck - run: pnpm run typecheck - - format: - runs-on: ubuntu-latest - name: format - timeout-minutes: 10 - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - version: 10 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "20" - cache: "pnpm" - cache-dependency-path: integrations/chat-ui/pnpm-lock.yaml - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Check formatting - run: pnpm run format:check - - build: - runs-on: ubuntu-latest - name: build - timeout-minutes: 10 - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - version: 10 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: "20" - cache: "pnpm" - cache-dependency-path: integrations/chat-ui/pnpm-lock.yaml - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Build package - run: pnpm run build diff --git a/.github/workflows/release-chat-ui.yml b/.github/workflows/release-chat-ui.yml deleted file mode 100644 index edb49cd2f..000000000 --- a/.github/workflows/release-chat-ui.yml +++ /dev/null @@ -1,115 +0,0 @@ -name: Release @databricks/chat-ui - -on: - workflow_dispatch: - inputs: - production: - description: "Publish to npm? (If unchecked, will publish with --tag next)" - required: true - default: false - type: boolean - -jobs: - release: - runs-on: ubuntu-latest - - permissions: - id-token: write - contents: write - environment: - name: ${{ inputs.production && 'npm' || 'npm-next' }} - url: https://www.npmjs.com/package/@databricks/chat-ui - defaults: - run: - working-directory: integrations/chat-ui - steps: - - uses: actions/checkout@v4 - - - name: Install pnpm - uses: pnpm/action-setup@v4 - with: - version: 10 - - - uses: actions/setup-node@v4 - with: - node-version: "20" - registry-url: "https://registry.npmjs.org" - cache: "pnpm" - cache-dependency-path: integrations/chat-ui/pnpm-lock.yaml - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Get package version - id: get-version - run: | - PKG_VERSION=$(node -p "require('./package.json').version") - echo "version=$PKG_VERSION" >> $GITHUB_OUTPUT - - - name: Clean - run: pnpm run clean - - - name: Build - run: pnpm run build - - - name: Test - run: pnpm run test - - - name: Typecheck - run: pnpm run typecheck - - - name: Publish to npm - if: inputs.production - run: pnpm publish --access public --provenance --no-git-checks - - - name: Publish to npm (next tag) - if: ${{ !inputs.production }} - run: pnpm publish --access public --tag next --provenance --no-git-checks - - - name: Wait for registry propagation - run: sleep 15 - - - name: Smoke test (production) - if: inputs.production - run: | - PKG_VERSION=${{ steps.get-version.outputs.version }} - mkdir -p /tmp/smoke-test - cd /tmp/smoke-test - npm install @databricks/chat-ui@$PKG_VERSION - INSTALLED_VERSION=$(node -p "require('./node_modules/@databricks/chat-ui/package.json').version") - echo "Expected: $PKG_VERSION" - echo "Installed: $INSTALLED_VERSION" - if [ "$PKG_VERSION" != "$INSTALLED_VERSION" ]; then - echo "Version mismatch!" - exit 1 - fi - echo "Smoke test passed!" - - - name: Smoke test (next tag) - if: ${{ !inputs.production }} - run: | - mkdir -p /tmp/smoke-test - cd /tmp/smoke-test - npm install @databricks/chat-ui@next - INSTALLED_VERSION=$(node -p "require('./node_modules/@databricks/chat-ui/package.json').version") - echo "Installed @next version: $INSTALLED_VERSION" - echo "Smoke test passed!" - - - name: Generate package link - run: | - PKG_VERSION=${{ steps.get-version.outputs.version }} - if [ "${{ inputs.production }}" == "true" ]; then - LINK="https://www.npmjs.com/package/@databricks/chat-ui/v/$PKG_VERSION" - echo "## :rocket: Package Released" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "**@databricks/chat-ui v$PKG_VERSION** has been published to npm!" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo ":link: [$LINK]($LINK)" >> $GITHUB_STEP_SUMMARY - else - LINK="https://www.npmjs.com/package/@databricks/chat-ui?activeTab=versions" - echo "## :test_tube: Package Released (next tag)" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "**@databricks/chat-ui v$PKG_VERSION** has been published to npm with --tag next!" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo ":link: [$LINK]($LINK)" >> $GITHUB_STEP_SUMMARY - fi diff --git a/integrations/appkit-agent/package.json b/integrations/appkit-agent/package.json index 7924db820..19d9f3b9c 100644 --- a/integrations/appkit-agent/package.json +++ b/integrations/appkit-agent/package.json @@ -16,7 +16,18 @@ "types": "./dist/index.d.cts", "default": "./dist/index.cjs" } - } + }, + "./chat-ui/simple": { + "import": { + "types": "./dist/chat-ui/simple.d.mts", + "default": "./dist/chat-ui/simple.mjs" + }, + "require": { + "types": "./dist/chat-ui/simple.d.cts", + "default": "./dist/chat-ui/simple.cjs" + } + }, + "./chat-ui/simple/styles.css": "./dist/chat-ui/styles.css" }, "files": [ "dist", @@ -25,7 +36,7 @@ "NOTICE" ], "scripts": { - "build": "tsdown", + "build": "rm -rf dist && tsdown && tailwindcss -c tailwind.chat-ui.config.js -i src/chat-ui/simple/styles.css -o dist/chat-ui/styles.css --minify", "dev": "tsdown --watch", "clean": "rm -rf dist", "test": "vitest run", @@ -44,7 +55,9 @@ "@langchain/core": ">=1.0.0", "@langchain/langgraph": ">=1.0.0", "@langchain/mcp-adapters": ">=1.0.0", - "express": ">=4.0.0" + "express": ">=4.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" }, "peerDependenciesMeta": { "@databricks/langchainjs": { @@ -58,9 +71,19 @@ }, "@langchain/mcp-adapters": { "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true } }, "dependencies": { + "@radix-ui/react-slot": "^1.2.4", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "tailwind-merge": "^3.4.0", "zod": "^4.3.5" }, "devDependencies": { @@ -68,7 +91,12 @@ "@langchain/core": "^1.1.8", "@types/express": "^4.17.25", "@types/node": "^22.0.0", + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", "prettier": "^3.0.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "tailwindcss": "^3.4.0", "tsdown": "^0.9.0", "typescript": "^5.4.0", "vitest": "^4.0.18" @@ -103,6 +131,9 @@ "esbuild", "protobufjs", "rolldown" - ] + ], + "overrides": { + "vite": "8.0.0" + } } } diff --git a/integrations/appkit-agent/pnpm-lock.yaml b/integrations/appkit-agent/pnpm-lock.yaml index d297f78e0..05115c994 100644 --- a/integrations/appkit-agent/pnpm-lock.yaml +++ b/integrations/appkit-agent/pnpm-lock.yaml @@ -4,29 +4,44 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + vite: 8.0.0 + importers: .: dependencies: '@databricks/langchainjs': specifier: '>=0.1.0' - version: 0.1.0(@cfworker/json-schema@4.1.1)(@langchain/langgraph@1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0) + version: 0.1.0(@cfworker/json-schema@4.1.1)(@langchain/langgraph@1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0) '@langchain/langgraph': specifier: '>=1.0.0' - version: 1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) + version: 1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) '@langchain/mcp-adapters': specifier: '>=1.0.0' - version: 1.1.3(@cfworker/json-schema@4.1.1)(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(@langchain/langgraph@1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6)) + version: 1.1.3(@cfworker/json-schema@4.1.1)(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(@langchain/langgraph@1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6)) + '@radix-ui/react-slot': + specifier: ^1.2.4 + version: 1.2.4(@types/react@19.2.14)(react@19.2.4) + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 express: specifier: '>=4.0.0' version: 5.2.1 + tailwind-merge: + specifier: ^3.4.0 + version: 3.5.0 zod: specifier: ^4.3.5 version: 4.3.6 devDependencies: '@databricks/appkit': specifier: ^0.21.0 - version: 0.21.0(@opentelemetry/core@2.6.0(@opentelemetry/api@1.9.0))(@types/node@22.19.15)(jiti@2.6.1) + version: 0.21.0(@opentelemetry/core@2.6.0(@opentelemetry/api@1.9.0))(@types/node@22.19.15)(jiti@1.21.7) '@langchain/core': specifier: ^1.1.8 version: 1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0) @@ -36,9 +51,24 @@ importers: '@types/node': specifier: ^22.0.0 version: 22.19.15 + '@types/react': + specifier: ^19.0.0 + version: 19.2.14 + '@types/react-dom': + specifier: ^19.0.0 + version: 19.2.3(@types/react@19.2.14) prettier: specifier: ^3.0.0 version: 3.8.1 + react: + specifier: ^19.0.0 + version: 19.2.4 + react-dom: + specifier: ^19.0.0 + version: 19.2.4(react@19.2.4) + tailwindcss: + specifier: ^3.4.0 + version: 3.4.19 tsdown: specifier: ^0.9.0 version: 0.9.9(typescript@5.9.3) @@ -47,7 +77,7 @@ importers: version: 5.9.3 vitest: specifier: ^4.0.18 - version: 4.1.0(@opentelemetry/api@1.9.0)(@types/node@22.19.15)(vite@8.0.1(@types/node@22.19.15)(jiti@2.6.1)) + version: 4.1.0(@opentelemetry/api@1.9.0)(@types/node@22.19.15)(vite@8.0.0(@types/node@22.19.15)(jiti@1.21.7)) packages: @@ -67,6 +97,10 @@ packages: resolution: {integrity: sha512-oGMAgGoQdBXbZqNG0Ze56CHjDZ1IDYOwGYxYjO5KLSlz5HiNQ9udIXsPZ61VWaHGZ5XW/jyjmr6t2xz2jGVwbQ==} engines: {node: '>=18'} + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + '@ast-grep/napi-darwin-arm64@0.37.0': resolution: {integrity: sha512-QAiIiaAbLvMEg/yBbyKn+p1gX2/FuaC0SMf7D7capm/oG4xGMzdeaQIcSosF4TCxxV+hIH4Bz9e4/u7w6Bnk3Q==} engines: {node: '>= 10'} @@ -185,11 +219,11 @@ packages: resolution: {integrity: sha512-9c2RxWYoRDFupdt4ZnBc1IPE1XaXgN+/wyV4DVcEqOnIa31ep51OnwAD/3014BImfKdyXg32nmgrB9dwvB6+lg==} engines: {node: '>=22.0', npm: '>=10.0.0'} - '@emnapi/core@1.9.1': - resolution: {integrity: sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==} + '@emnapi/core@1.9.0': + resolution: {integrity: sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w==} - '@emnapi/runtime@1.9.1': - resolution: {integrity: sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==} + '@emnapi/runtime@1.9.0': + resolution: {integrity: sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw==} '@emnapi/wasi-threads@1.2.0': resolution: {integrity: sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==} @@ -292,6 +326,18 @@ packages: '@napi-rs/wasm-runtime@1.1.1': resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + '@opentelemetry/api-logs@0.208.0': resolution: {integrity: sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg==} engines: {node: '>=8.0.0'} @@ -771,19 +817,16 @@ packages: peerDependencies: '@opentelemetry/api': ^1.1.0 - '@oxc-project/runtime@0.92.0': - resolution: {integrity: sha512-Z7x2dZOmznihvdvCvLKMl+nswtOSVxS2H2ocar+U9xx6iMfTp0VGIrX6a4xB1v80IwOPC7dT1LXIJrY70Xu3Jw==} + '@oxc-project/runtime@0.115.0': + resolution: {integrity: sha512-Rg8Wlt5dCbXhQnsXPrkOjL1DTSvXLgb2R/KYfnf1/K+R0k6UMLEmbQXPM+kwrWqSmWA2t0B1EtHy2/3zikQpvQ==} engines: {node: ^20.19.0 || >=22.12.0} - '@oxc-project/types@0.120.0': - resolution: {integrity: sha512-k1YNu55DuvAip/MGE1FTsIuU3FUCn6v/ujG9V7Nq5Df/kX2CWb13hhwD0lmJGMGqE+bE1MXvv9SZVnMzEXlWcg==} + '@oxc-project/types@0.115.0': + resolution: {integrity: sha512-4n91DKnebUS4yjUHl2g3/b2T+IUdCfmoZGhmwsovZCDaJSs+QkVAM+0AqqTxHSsHfeiMuueT75cZaZcT/m0pSw==} '@oxc-project/types@0.66.0': resolution: {integrity: sha512-KF5Wlo2KzQ+jmuCtrGISZoUfdHom7qHavNfPLW2KkeYJfYMGwtiia8KjwtsvNJ49qRiXImOCkPeVPd4bMlbR7w==} - '@oxc-project/types@0.93.0': - resolution: {integrity: sha512-yNtwmWZIBtJsMr5TEfoZFDxIWV6OdScOpza/f5YxbqUMJk+j6QX3Cf3jgZShGEFYWQJ5j9mJ6jM0tZHu2J9Yrg==} - '@oxc-resolver/binding-darwin-arm64@9.0.2': resolution: {integrity: sha512-MVyRgP2gzJJtAowjG/cHN3VQXwNLWnY+FpOEsyvDepJki1SdAX/8XDijM1yN6ESD1kr9uhBKjGelC6h3qtT+rA==} cpu: [arm64] @@ -951,257 +994,185 @@ packages: '@quansync/fs@1.0.0': resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} - '@rolldown/binding-android-arm64@1.0.0-beta.41': - resolution: {integrity: sha512-Edflndd9lU7JVhVIvJlZhdCj5DkhYDJPIRn4Dx0RUdfc8asP9xHOI5gMd8MesDDx+BJpdIT/uAmVTearteU/mQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@rolldown/binding-android-arm64@1.0.0-rc.10': - resolution: {integrity: sha512-jOHxwXhxmFKuXztiu1ORieJeTbx5vrTkcOkkkn2d35726+iwhrY1w/+nYY/AGgF12thg33qC3R1LMBF5tHTZHg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] + '@radix-ui/react-slot@1.2.4': + resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@rolldown/binding-darwin-arm64@1.0.0-beta.41': - resolution: {integrity: sha512-XGCzqfjdk7550PlyZRTBKbypXrB7ATtXhw/+bjtxnklLQs0mKP/XkQVOKyn9qGKSlvH8I56JLYryVxl0PCvSNw==} + '@rolldown/binding-android-arm64@1.0.0-rc.9': + resolution: {integrity: sha512-lcJL0bN5hpgJfSIz/8PIf02irmyL43P+j1pTCfbD1DbLkmGRuFIA4DD3B3ZOvGqG0XiVvRznbKtN0COQVaKUTg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] - os: [darwin] + os: [android] '@rolldown/binding-darwin-arm64@1.0.0-beta.8-commit.151352b': resolution: {integrity: sha512-2F4bhDtV6CHBx7JMiT9xvmxkcZLHFmonfbli36RyfvgThDOAu92bis28zDTdguDY85lN/jBRKX/eOvX+T5hMkg==} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-arm64@1.0.0-rc.10': - resolution: {integrity: sha512-gED05Teg/vtTZbIJBc4VNMAxAFDUPkuO/rAIyyxZjTj1a1/s6z5TII/5yMGZ0uLRCifEtwUQn8OlYzuYc0m70w==} + '@rolldown/binding-darwin-arm64@1.0.0-rc.9': + resolution: {integrity: sha512-J7Zk3kLYFsLtuH6U+F4pS2sYVzac0qkjcO5QxHS7OS7yZu2LRs+IXo+uvJ/mvpyUljDJ3LROZPoQfgBIpCMhdQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-beta.41': - resolution: {integrity: sha512-Ho6lIwGJed98zub7n0xcRKuEtnZgbxevAmO4x3zn3C3N4GVXZD5xvCvTVxSMoeBJwTcIYzkVDRTIhylQNsTgLQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-beta.8-commit.151352b': resolution: {integrity: sha512-8VMChhFLeD/oOAQUspFtxZaV7ctDob63w626kwvBBIHtlpY2Ohw4rsfjjtGckyrTCI/RROgZv/TVVEsG3GkgLw==} cpu: [x64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-rc.10': - resolution: {integrity: sha512-rI15NcM1mA48lqrIxVkHfAqcyFLcQwyXWThy+BQ5+mkKKPvSO26ir+ZDp36AgYoYVkqvMcdS8zOE6SeBsR9e8A==} + '@rolldown/binding-darwin-x64@1.0.0-rc.9': + resolution: {integrity: sha512-iwtmmghy8nhfRGeNAIltcNXzD0QMNaaA5U/NyZc1Ia4bxrzFByNMDoppoC+hl7cDiUq5/1CnFthpT9n+UtfFyg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.0-beta.41': - resolution: {integrity: sha512-ijAZETywvL+gACjbT4zBnCp5ez1JhTRs6OxRN4J+D6AzDRbU2zb01Esl51RP5/8ZOlvB37xxsRQ3X4YRVyYb3g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - '@rolldown/binding-freebsd-x64@1.0.0-beta.8-commit.151352b': resolution: {integrity: sha512-4W28EgaIidbWIpwB3hESMBfiOSs7LBFpJGa8JIV488qLEnTR/pqzxDEoOPobhRSJ1lJlv0vUgA8+DKBIldo2gw==} cpu: [x64] os: [freebsd] - '@rolldown/binding-freebsd-x64@1.0.0-rc.10': - resolution: {integrity: sha512-XZRXHdTa+4ME1MuDVp021+doQ+z6Ei4CCFmNc5/sKbqb8YmkiJdj8QKlV3rCI0AJtAeSB5n0WGPuJWNL9p/L2w==} + '@rolldown/binding-freebsd-x64@1.0.0-rc.9': + resolution: {integrity: sha512-DLFYI78SCiZr5VvdEplsVC2Vx53lnA4/Ga5C65iyldMVaErr86aiqCoNBLl92PXPfDtUYjUh+xFFor40ueNs4Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.41': - resolution: {integrity: sha512-EgIOZt7UildXKFEFvaiLNBXm+4ggQyGe3E5Z1QP9uRcJJs9omihOnm897FwOBQdCuMvI49iBgjFrkhH+wMJ2MA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.8-commit.151352b': resolution: {integrity: sha512-1ECtyzIKlAHikR7BhS4hk7Hxw8xCH6W3S+Sb74EM0vy5AqPvWSbgLfAwagYC7gNDcMMby3I757X7qih5fIrGiw==} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.10': - resolution: {integrity: sha512-R0SQMRluISSLzFE20sPWYHVmJdDQnRyc/FzSCN72BqQmh2SOZUFG+N3/vBZpR4C6WpEUVYJLrYUXaj43sJsNLA==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.9': + resolution: {integrity: sha512-CsjTmTwd0Hri6iTw/DRMK7kOZ7FwAkrO4h8YWKoX/kcj833e4coqo2wzIFywtch/8Eb5enQ/lwLM7w6JX1W5RQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.41': - resolution: {integrity: sha512-F8bUwJq8v/JAU8HSwgF4dztoqJ+FjdyjuvX4//3+Fbe2we9UktFeZ27U4lRMXF1vxWtdV4ey6oCSqI7yUrSEeg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [glibc] - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.8-commit.151352b': resolution: {integrity: sha512-wU1kp8qPRUKC8N82dNs3F5+UyKRww9TUEO5dQ5mxCb0cG+y4l5rVaXpMgvL0VuQahPVvTMs577QPhJGb4iDONw==} cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.10': - resolution: {integrity: sha512-Y1reMrV/o+cwpduYhJuOE3OMKx32RMYCidf14y+HssARRmhDuWXJ4yVguDg2R/8SyyGNo+auzz64LnPK9Hq6jg==} + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.9': + resolution: {integrity: sha512-2x9O2JbSPxpxMDhP9Z74mahAStibTlrBMW0520+epJH5sac7/LwZW5Bmg/E6CXuEF53JJFW509uP+lSedaUNxg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.41': - resolution: {integrity: sha512-MioXcCIX/wB1pBnBoJx8q4OGucUAfC1+/X1ilKFsjDK05VwbLZGRgOVD5OJJpUQPK86DhQciNBrfOKDiatxNmg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [musl] - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.8-commit.151352b': resolution: {integrity: sha512-odDjO2UtEEMAzwmLHEOKylJjQa+em1REAO9H19PA+O+lPu6evVbre5bqu8qCjEtHG1Q034LpZR86imCP2arb/w==} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.10': - resolution: {integrity: sha512-vELN+HNb2IzuzSBUOD4NHmP9yrGwl1DVM29wlQvx1OLSclL0NgVWnVDKl/8tEks79EFek/kebQKnNJkIAA4W2g==} + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.9': + resolution: {integrity: sha512-JA1QRW31ogheAIRhIg9tjMfsYbglXXYGNPLdPEYrwFxdbkQCAzvpSCSHCDWNl4hTtrol8WeboCSEpjdZK8qrCg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.10': - resolution: {integrity: sha512-ZqrufYTgzxbHwpqOjzSsb0UV/aV2TFIY5rP8HdsiPTv/CuAgCRjM6s9cYFwQ4CNH+hf9Y4erHW1GjZuZ7WoI7w==} + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.9': + resolution: {integrity: sha512-aOKU9dJheda8Kj8Y3w9gnt9QFOO+qKPAl8SWd7JPHP+Cu0EuDAE5wokQubLzIDQWg2myXq2XhTpOVS07qqvT+w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.10': - resolution: {integrity: sha512-gSlmVS1FZJSRicA6IyjoRoKAFK7IIHBs7xJuHRSmjImqk3mPPWbR7RhbnfH2G6bcmMEllCt2vQ/7u9e6bBnByg==} + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.9': + resolution: {integrity: sha512-OalO94fqj7IWRn3VdXWty75jC5dk4C197AWEuMhIpvVv2lw9fiPhud0+bW2ctCxb3YoBZor71QHbY+9/WToadA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.41': - resolution: {integrity: sha512-m66M61fizvRCwt5pOEiZQMiwBL9/y0bwU/+Kc4Ce/Pef6YfoEkR28y+DzN9rMdjo8Z28NXjsDPq9nH4mXnAP0g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.8-commit.151352b': resolution: {integrity: sha512-Ty2T67t2Oj1lg417ATRENxdk8Jkkksc/YQdCJyvkGqteHe60pSU2GGP/tLWGB+I0Ox+u387bzU/SmfmrHZk9aw==} cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.10': - resolution: {integrity: sha512-eOCKUpluKgfObT2pHjztnaWEIbUabWzk3qPZ5PuacuPmr4+JtQG4k2vGTY0H15edaTnicgU428XW/IH6AimcQw==} + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.9': + resolution: {integrity: sha512-cVEl1vZtBsBZna3YMjGXNvnYYrOJ7RzuWvZU0ffvJUexWkukMaDuGhUXn0rjnV0ptzGVkvc+vW9Yqy6h8YX4pg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.0.0-beta.41': - resolution: {integrity: sha512-yRxlSfBvWnnfrdtJfvi9lg8xfG5mPuyoSHm0X01oiE8ArmLRvoJGHUTJydCYz+wbK2esbq5J4B4Tq9WAsOlP1Q==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [musl] - '@rolldown/binding-linux-x64-musl@1.0.0-beta.8-commit.151352b': resolution: {integrity: sha512-Fm1TxyeVE+gy74HM26CwbEOUndIoWAMgWkVDxYBD64tayvp5JvltpGHaqCg6x5i+X2F5XCDCItqwVlC7/mTxIw==} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-linux-x64-musl@1.0.0-rc.10': - resolution: {integrity: sha512-Xdf2jQbfQowJnLcgYfD/m0Uu0Qj5OdxKallD78/IPPfzaiaI4KRAwZzHcKQ4ig1gtg1SuzC7jovNiM2TzQsBXA==} + '@rolldown/binding-linux-x64-musl@1.0.0-rc.9': + resolution: {integrity: sha512-UzYnKCIIc4heAKgI4PZ3dfBGUZefGCJ1TPDuLHoCzgrMYPb5Rv6TLFuYtyM4rWyHM7hymNdsg5ik2C+UD9VDbA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.0-beta.41': - resolution: {integrity: sha512-PHVxYhBpi8UViS3/hcvQQb9RFqCtvFmFU1PvUoTRiUdBtgHA6fONNHU4x796lgzNlVSD3DO/MZNk1s5/ozSMQg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@rolldown/binding-openharmony-arm64@1.0.0-rc.10': - resolution: {integrity: sha512-o1hYe8hLi1EY6jgPFyxQgQ1wcycX+qz8eEbVmot2hFkgUzPxy9+kF0u0NIQBeDq+Mko47AkaFFaChcvZa9UX9Q==} + '@rolldown/binding-openharmony-arm64@1.0.0-rc.9': + resolution: {integrity: sha512-+6zoiF+RRyf5cdlFQP7nm58mq7+/2PFaY2DNQeD4B87N36JzfF/l9mdBkkmTvSYcYPE8tMh/o3cRlsx1ldLfog==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.0-beta.41': - resolution: {integrity: sha512-OAfcO37ME6GGWmj9qTaDT7jY4rM0T2z0/8ujdQIJQ2x2nl+ztO32EIwURfmXOK0U1tzkyuaKYvE34Pug/ucXlQ==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - '@rolldown/binding-wasm32-wasi@1.0.0-beta.8-commit.151352b': resolution: {integrity: sha512-AEZzTyGerfkffXmtv7kFJbHWkryNeolk0Br+yhH1wZyN6Tt6aebqICDL8KNRO2iExoEWzyYS6dPxh0QmvNTfUQ==} engines: {node: '>=14.21.3'} cpu: [wasm32] - '@rolldown/binding-wasm32-wasi@1.0.0-rc.10': - resolution: {integrity: sha512-Ugv9o7qYJudqQO5Y5y2N2SOo6S4WiqiNOpuQyoPInnhVzCY+wi/GHltcLHypG9DEUYMB0iTB/huJrpadiAcNcA==} + '@rolldown/binding-wasm32-wasi@1.0.0-rc.9': + resolution: {integrity: sha512-rgFN6sA/dyebil3YTlL2evvi/M+ivhfnyxec7AccTpRPccno/rPoNlqybEZQBkcbZu8Hy+eqNJCqfBR8P7Pg8g==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.41': - resolution: {integrity: sha512-NIYGuCcuXaq5BC4Q3upbiMBvmZsTsEPG9k/8QKQdmrch+ocSy5Jv9tdpdmXJyighKqm182nh/zBt+tSJkYoNlg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.8-commit.151352b': resolution: {integrity: sha512-0lskDFKQwf5PMjl17qHAroU6oVU0Zn8NbAH/PdM9QB1emOzyFDGa20d4kESGeo3Uq7xOKXcTORJV/JwKIBORqw==} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.10': - resolution: {integrity: sha512-7UODQb4fQUNT/vmgDZBl3XOBAIOutP5R3O/rkxg0aLfEGQ4opbCgU5vOw/scPe4xOqBwL9fw7/RP1vAMZ6QlAQ==} + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.9': + resolution: {integrity: sha512-lHVNUG/8nlF1IQk1C0Ci574qKYyty2goMiPlRqkC5R+3LkXDkL5Dhx8ytbxq35m+pkHVIvIxviD+TWLdfeuadA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.41': - resolution: {integrity: sha512-kANdsDbE5FkEOb5NrCGBJBCaZ2Sabp3D7d4PRqMYJqyLljwh9mDyYyYSv5+QNvdAmifj+f3lviNEUUuUZPEFPw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ia32] - os: [win32] - '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.8-commit.151352b': resolution: {integrity: sha512-DfG1S0zGKnUfr95cNCmR4YPiZ/moS7Tob5eV+9r5JGeHZVWFHWwvJdR0jArj6Ty0LbBFDTVVB3iAvqRSji+l0Q==} cpu: [ia32] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.41': - resolution: {integrity: sha512-UlpxKmFdik0Y2VjZrgUCgoYArZJiZllXgIipdBRV1hw6uK45UbQabSTW6Kp6enuOu7vouYWftwhuxfpE8J2JAg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.8-commit.151352b': resolution: {integrity: sha512-5HZEtc8U2I1O903hXBynWtWaf+qzAFj66h5B7gOtVcvqIk+lKRVSupA85OdIvR7emrsYU25ikpfiU5Jhg9kTbQ==} cpu: [x64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.10': - resolution: {integrity: sha512-PYxKHMVHOb5NJuDL53vBUl1VwUjymDcYI6rzpIni0C9+9mTiJedvUxSk7/RPp7OOAm3v+EjgMu9bIy3N6b408w==} + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.9': + resolution: {integrity: sha512-G0oA4+w1iY5AGi5HcDTxWsoxF509hrFIPB2rduV5aDqS9FtDg1CAfa7V34qImbjfhIcA8C+RekocJZA96EarwQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@rolldown/pluginutils@1.0.0-beta.41': - resolution: {integrity: sha512-ycMEPrS3StOIeb87BT3/+bu+blEtyvwQ4zmo2IcJQy0Rd1DAAhKksA0iUZ3MYSpJtjlPhg0Eo6mvVS6ggPhRbw==} - - '@rolldown/pluginutils@1.0.0-rc.10': - resolution: {integrity: sha512-UkVDEFk1w3mveXeKgaTuYfKWtPbvgck1dT8TUG3bnccrH0XtLTuAyfCoks4Q/M5ZGToSVJTIQYCzy2g/atAOeg==} + '@rolldown/pluginutils@1.0.0-rc.9': + resolution: {integrity: sha512-w6oiRWgEBl04QkFZgmW+jnU1EC9b57Oihi2ot3HNWIQRqgHp5PnYDia5iZ5FF7rpa4EQdiqMDXjlqKGXBhsoXw==} '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} @@ -1263,12 +1234,23 @@ packages: '@types/pg@8.15.6': resolution: {integrity: sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==} + '@types/pg@8.18.0': + resolution: {integrity: sha512-gT+oueVQkqnj6ajGJXblFR4iavIXWsGAFCk3dP4Kki5+a9R4NMt0JARdk6s8cUKcfUoqP5dAtDSLU8xYUTFV+Q==} + '@types/qs@6.15.0': resolution: {integrity: sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow==} '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.14': + resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + '@types/semver@7.7.1': resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} @@ -1303,7 +1285,7 @@ packages: resolution: {integrity: sha512-evxREh+Hork43+Y4IOhTo+h5lGmVRyjqI739Rz4RlUPqwrkFFDF6EMvOOYjTx4E8Tl6gyCLRL8Mu7Ry12a13Tw==} peerDependencies: msw: ^2.4.9 - vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0 + vite: 8.0.0 peerDependenciesMeta: msw: optional: true @@ -1380,9 +1362,15 @@ packages: resolution: {integrity: sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==} engines: {node: '>=14'} - ansis@4.2.0: - resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} - engines: {node: '>=14'} + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} @@ -1401,6 +1389,10 @@ packages: bignumber.js@9.3.1: resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + body-parser@1.20.4: resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -1409,6 +1401,10 @@ packages: resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} engines: {node: '>=18'} + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + buffer-equal-constant-time@1.0.1: resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} @@ -1428,6 +1424,10 @@ packages: resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} engines: {node: '>= 0.4'} + camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + camelcase@6.3.0: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} @@ -1440,6 +1440,10 @@ packages: resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} @@ -1447,10 +1451,17 @@ packages: cjs-module-lexer@2.2.0: resolution: {integrity: sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==} + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + 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'} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -1462,6 +1473,10 @@ packages: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + consola@3.4.2: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} @@ -1503,6 +1518,14 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + data-uri-to-buffer@4.0.1: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} @@ -1543,10 +1566,16 @@ packages: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} + didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + diff@7.0.0: resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} engines: {node: '>=0.3.1'} + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + dotenv@16.6.1: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} @@ -1646,9 +1675,16 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + fast-uri@3.1.0: resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -1662,6 +1698,10 @@ packages: resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} engines: {node: ^12.20 || >= 14.13} + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + finalhandler@1.3.2: resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} engines: {node: '>= 0.8'} @@ -1728,6 +1768,14 @@ packages: get-tsconfig@4.13.6: resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==} + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + google-auth-library@10.6.2: resolution: {integrity: sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==} engines: {node: '>=18'} @@ -1793,14 +1841,34 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + is-network-error@1.3.1: resolution: {integrity: sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==} engines: {node: '>=16'} + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + is-promise@4.0.0: resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} @@ -1811,6 +1879,10 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + jiti@2.6.1: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true @@ -1938,6 +2010,13 @@ packages: resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} engines: {node: '>= 12.0.0'} + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} @@ -1966,10 +2045,18 @@ packages: resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} engines: {node: '>=18'} + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} @@ -2004,6 +2091,9 @@ packages: resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} hasBin: true + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -2035,10 +2125,18 @@ packages: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + object-inspect@1.13.4: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} @@ -2092,6 +2190,9 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-to-regexp@0.1.12: resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} @@ -2138,14 +2239,69 @@ packages: picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + picomatch@4.0.3: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + pkce-challenge@5.0.1: resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} engines: {node: '>=16.20.0'} + postcss-import@15.1.0: + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + + postcss-js@4.1.0: + resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + postcss@8.5.8: resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} engines: {node: ^10 || ^12 || >=14} @@ -2190,6 +2346,9 @@ packages: quansync@1.0.0: resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -2202,6 +2361,22 @@ packages: resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} engines: {node: '>= 0.10'} + react-dom@19.2.4: + resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} + peerDependencies: + react: ^19.2.4 + + react@19.2.4: + resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} + engines: {node: '>=0.10.0'} + + read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + readdirp@4.1.2: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} @@ -2224,6 +2399,15 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rolldown-plugin-dts@0.9.11: resolution: {integrity: sha512-iCIRKmvPLwRV4UKSxhaBo+5wDkvc3+MFiqYYvu7sGLSohzxoDn9WEsjN3y7A6xg3aCuxHh6rlRp8xbX98r1rSg==} engines: {node: '>=20.18.0'} @@ -2234,52 +2418,6 @@ packages: typescript: optional: true - rolldown-vite@7.1.14: - resolution: {integrity: sha512-eSiiRJmovt8qDJkGyZuLnbxAOAdie6NCmmd0NkTC0RJI9duiSBTfr8X2mBYJOUFzxQa2USaHmL99J9uMxkjCyw==} - engines: {node: ^20.19.0 || >=22.12.0} - deprecated: Use 7.3.1 for migration purposes. For the most recent updates, migrate to Vite 8 once you're ready. - hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - esbuild: ^0.25.0 - jiti: '>=1.21.0' - less: ^4.0.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: '>=0.54.8' - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - esbuild: - optional: true - jiti: - optional: true - less: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - - rolldown@1.0.0-beta.41: - resolution: {integrity: sha512-U+NPR0Bkg3wm61dteD2L4nAM1U9dtaqVrpDXwC36IKRHpEO/Ubpid4Nijpa2imPchcVNHfxVFwSSMJdwdGFUbg==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - rolldown@1.0.0-beta.8-commit.151352b: resolution: {integrity: sha512-TCb6GVaFBk4wB0LERofFDxTO5X1/Sgahr7Yn5UA9XjuFtCwL1CyEhUHX5lUIstcMxjbkLjn2z4TAGwisr6Blvw==} hasBin: true @@ -2289,8 +2427,8 @@ packages: '@oxc-project/runtime': optional: true - rolldown@1.0.0-rc.10: - resolution: {integrity: sha512-q7j6vvarRFmKpgJUT8HCAUljkgzEp4LAhPlJUvQhA5LA1SUL36s5QCysMutErzL3EbNOZOkoziSx9iZC4FddKA==} + rolldown@1.0.0-rc.9: + resolution: {integrity: sha512-9EbgWge7ZH+yqb4d2EnELAntgPTWbfL8ajiTW+SyhJEC4qhBbkCKbqFV4Ge4zmu5ziQuVbWxb/XwLZ+RIO7E8Q==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -2298,12 +2436,18 @@ packages: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + semver@7.7.4: resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} engines: {node: '>=10'} @@ -2387,6 +2531,30 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} + sucrase@3.35.1: + resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tailwind-merge@3.5.0: + resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==} + + tailwindcss@3.4.19: + resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==} + engines: {node: '>=14.0.0'} + hasBin: true + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -2402,6 +2570,10 @@ packages: resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} engines: {node: '>=14.0.0'} + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + toidentifier@1.0.1: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} @@ -2409,6 +2581,9 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + tsdown@0.9.9: resolution: {integrity: sha512-IIGX55rkhaPomNSVrIbA58DRBwTO4ehlDTsw20XSooGqoEZbwpunDc1dRE73wKb1rHdwwBO6NMLOcgV2n1qhpA==} engines: {node: '>=18.0.0'} @@ -2459,6 +2634,9 @@ packages: resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} engines: {node: '>=18.12.0'} + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + utils-merge@1.0.1: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} @@ -2491,13 +2669,13 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - vite@8.0.1: - resolution: {integrity: sha512-wt+Z2qIhfFt85uiyRt5LPU4oVEJBXj8hZNWKeqFG4gRG/0RaRGJ7njQCwzFVjO+v4+Ipmf5CY7VdmZRAYYBPHw==} + vite@8.0.0: + resolution: {integrity: sha512-fPGaRNj9Zytaf8LEiBhY7Z6ijnFKdzU/+mL8EFBaKr7Vw1/FWcTBAMW0wLPJAGMPX38ZPVCVgLceWiEqeoqL2Q==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.1.0 + '@vitejs/devtools': ^0.0.0-alpha.31 esbuild: ^0.27.0 jiti: '>=1.21.0' less: ^4.0.0 @@ -2548,7 +2726,7 @@ packages: '@vitest/ui': 4.1.0 happy-dom: '*' jsdom: '*' - vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0 + vite: 8.0.0 peerDependenciesMeta: '@edge-runtime/vm': optional: true @@ -2655,6 +2833,8 @@ snapshots: dependencies: json-schema: 0.4.0 + '@alloc/quick-lru@5.2.0': {} + '@ast-grep/napi-darwin-arm64@0.37.0': optional: true @@ -2732,7 +2912,7 @@ snapshots: '@ai-sdk/provider-utils': 4.0.19(zod@4.3.6) zod: 4.3.6 - '@databricks/appkit@0.21.0(@opentelemetry/core@2.6.0(@opentelemetry/api@1.9.0))(@types/node@22.19.15)(jiti@2.6.1)': + '@databricks/appkit@0.21.0(@opentelemetry/core@2.6.0(@opentelemetry/api@1.9.0))(@types/node@22.19.15)(jiti@1.21.7)': dependencies: '@ast-grep/napi': 0.37.0 '@clack/prompts': 1.1.0 @@ -2763,11 +2943,12 @@ snapshots: pg: 8.20.0 picocolors: 1.1.1 semver: 7.7.4 - vite: rolldown-vite@7.1.14(@types/node@22.19.15)(jiti@2.6.1) + vite: 8.0.0(@types/node@22.19.15)(jiti@1.21.7) ws: 8.19.0 transitivePeerDependencies: - '@opentelemetry/core' - '@types/node' + - '@vitejs/devtools' - bufferutil - encoding - esbuild @@ -2793,14 +2974,14 @@ snapshots: - pg-native - supports-color - '@databricks/langchainjs@0.1.0(@cfworker/json-schema@4.1.1)(@langchain/langgraph@1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0)': + '@databricks/langchainjs@0.1.0(@cfworker/json-schema@4.1.1)(@langchain/langgraph@1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0)': dependencies: '@ai-sdk/provider': 3.0.8 '@ai-sdk/provider-utils': 4.0.19(zod@4.3.6) '@databricks/ai-sdk-provider': 0.3.0(@ai-sdk/provider-utils@4.0.19(zod@4.3.6))(@ai-sdk/provider@3.0.8) '@databricks/sdk-experimental': 0.15.0 '@langchain/core': 1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0) - '@langchain/mcp-adapters': 1.1.3(@cfworker/json-schema@4.1.1)(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(@langchain/langgraph@1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6)) + '@langchain/mcp-adapters': 1.1.3(@cfworker/json-schema@4.1.1)(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(@langchain/langgraph@1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6)) ai: 6.0.116(zod@4.3.6) zod: 4.3.6 transitivePeerDependencies: @@ -2831,13 +3012,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@emnapi/core@1.9.1': + '@emnapi/core@1.9.0': dependencies: '@emnapi/wasi-threads': 1.2.0 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.9.1': + '@emnapi/runtime@1.9.0': dependencies: tslib: 2.8.1 optional: true @@ -2909,7 +3090,7 @@ snapshots: '@langchain/core': 1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0) uuid: 10.0.0 - '@langchain/langgraph-sdk@1.7.5(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))': + '@langchain/langgraph-sdk@1.7.5(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': dependencies: '@types/json-schema': 7.0.15 p-queue: 9.1.0 @@ -2917,12 +3098,14 @@ snapshots: uuid: 13.0.0 optionalDependencies: '@langchain/core': 1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) - '@langchain/langgraph@1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6)': + '@langchain/langgraph@1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6)': dependencies: '@langchain/core': 1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0) '@langchain/langgraph-checkpoint': 1.0.1(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0)) - '@langchain/langgraph-sdk': 1.7.5(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0)) + '@langchain/langgraph-sdk': 1.7.5(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@standard-schema/spec': 1.1.0 uuid: 10.0.0 zod: 4.3.6 @@ -2934,10 +3117,10 @@ snapshots: - svelte - vue - '@langchain/mcp-adapters@1.1.3(@cfworker/json-schema@4.1.1)(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(@langchain/langgraph@1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6))': + '@langchain/mcp-adapters@1.1.3(@cfworker/json-schema@4.1.1)(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(@langchain/langgraph@1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6))': dependencies: '@langchain/core': 1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0) - '@langchain/langgraph': 1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) + '@langchain/langgraph': 1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) '@modelcontextprotocol/sdk': 1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6) debug: 4.4.3 zod: 4.3.6 @@ -2973,18 +3156,28 @@ snapshots: '@napi-rs/wasm-runtime@0.2.12': dependencies: - '@emnapi/core': 1.9.1 - '@emnapi/runtime': 1.9.1 '@tybys/wasm-util': 0.10.1 optional: true '@napi-rs/wasm-runtime@1.1.1': dependencies: - '@emnapi/core': 1.9.1 - '@emnapi/runtime': 1.9.1 + '@emnapi/core': 1.9.0 + '@emnapi/runtime': 1.9.0 '@tybys/wasm-util': 0.10.1 optional: true + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + '@opentelemetry/api-logs@0.208.0': dependencies: '@opentelemetry/api': 1.9.0 @@ -3682,14 +3875,12 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 2.6.0(@opentelemetry/api@1.9.0) - '@oxc-project/runtime@0.92.0': {} + '@oxc-project/runtime@0.115.0': {} - '@oxc-project/types@0.120.0': {} + '@oxc-project/types@0.115.0': {} '@oxc-project/types@0.66.0': {} - '@oxc-project/types@0.93.0': {} - '@oxc-resolver/binding-darwin-arm64@9.0.2': optional: true @@ -3790,99 +3981,77 @@ snapshots: dependencies: quansync: 1.0.0 - '@rolldown/binding-android-arm64@1.0.0-beta.41': - optional: true + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.14)(react@19.2.4)': + dependencies: + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 - '@rolldown/binding-android-arm64@1.0.0-rc.10': - optional: true + '@radix-ui/react-slot@1.2.4(@types/react@19.2.14)(react@19.2.4)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.14 - '@rolldown/binding-darwin-arm64@1.0.0-beta.41': + '@rolldown/binding-android-arm64@1.0.0-rc.9': optional: true '@rolldown/binding-darwin-arm64@1.0.0-beta.8-commit.151352b': optional: true - '@rolldown/binding-darwin-arm64@1.0.0-rc.10': - optional: true - - '@rolldown/binding-darwin-x64@1.0.0-beta.41': + '@rolldown/binding-darwin-arm64@1.0.0-rc.9': optional: true '@rolldown/binding-darwin-x64@1.0.0-beta.8-commit.151352b': optional: true - '@rolldown/binding-darwin-x64@1.0.0-rc.10': - optional: true - - '@rolldown/binding-freebsd-x64@1.0.0-beta.41': + '@rolldown/binding-darwin-x64@1.0.0-rc.9': optional: true '@rolldown/binding-freebsd-x64@1.0.0-beta.8-commit.151352b': optional: true - '@rolldown/binding-freebsd-x64@1.0.0-rc.10': - optional: true - - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.41': + '@rolldown/binding-freebsd-x64@1.0.0-rc.9': optional: true '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.8-commit.151352b': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.10': - optional: true - - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.41': + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.9': optional: true '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.8-commit.151352b': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.10': - optional: true - - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.41': + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.9': optional: true '@rolldown/binding-linux-arm64-musl@1.0.0-beta.8-commit.151352b': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.10': + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.9': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.10': + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.9': optional: true - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.10': - optional: true - - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.41': + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.9': optional: true '@rolldown/binding-linux-x64-gnu@1.0.0-beta.8-commit.151352b': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.10': - optional: true - - '@rolldown/binding-linux-x64-musl@1.0.0-beta.41': + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.9': optional: true '@rolldown/binding-linux-x64-musl@1.0.0-beta.8-commit.151352b': optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-rc.10': - optional: true - - '@rolldown/binding-openharmony-arm64@1.0.0-beta.41': + '@rolldown/binding-linux-x64-musl@1.0.0-rc.9': optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-rc.10': - optional: true - - '@rolldown/binding-wasm32-wasi@1.0.0-beta.41': - dependencies: - '@napi-rs/wasm-runtime': 1.1.1 + '@rolldown/binding-openharmony-arm64@1.0.0-rc.9': optional: true '@rolldown/binding-wasm32-wasi@1.0.0-beta.8-commit.151352b': @@ -3890,38 +4059,27 @@ snapshots: '@napi-rs/wasm-runtime': 0.2.12 optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-rc.10': + '@rolldown/binding-wasm32-wasi@1.0.0-rc.9': dependencies: '@napi-rs/wasm-runtime': 1.1.1 optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.41': - optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.8-commit.151352b': optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.10': - optional: true - - '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.41': + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.9': optional: true '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.8-commit.151352b': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.41': - optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.8-commit.151352b': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.10': + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.9': optional: true - '@rolldown/pluginutils@1.0.0-beta.41': {} - - '@rolldown/pluginutils@1.0.0-rc.10': {} + '@rolldown/pluginutils@1.0.0-rc.9': {} '@standard-schema/spec@1.1.0': {} @@ -3992,7 +4150,7 @@ snapshots: '@types/pg-pool@2.0.6': dependencies: - '@types/pg': 8.15.6 + '@types/pg': 8.18.0 '@types/pg@8.15.6': dependencies: @@ -4000,10 +4158,24 @@ snapshots: pg-protocol: 1.13.0 pg-types: 2.2.0 + '@types/pg@8.18.0': + dependencies: + '@types/node': 22.19.15 + pg-protocol: 1.13.0 + pg-types: 2.2.0 + '@types/qs@6.15.0': {} '@types/range-parser@1.2.7': {} + '@types/react-dom@19.2.3(@types/react@19.2.14)': + dependencies: + '@types/react': 19.2.14 + + '@types/react@19.2.14': + dependencies: + csstype: 3.2.3 + '@types/semver@7.7.1': {} '@types/send@0.17.6': @@ -4042,13 +4214,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.0(vite@8.0.1(@types/node@22.19.15)(jiti@2.6.1))': + '@vitest/mocker@4.1.0(vite@8.0.0(@types/node@22.19.15)(jiti@1.21.7))': dependencies: '@vitest/spy': 4.1.0 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.0.1(@types/node@22.19.15)(jiti@2.6.1) + vite: 8.0.0(@types/node@22.19.15)(jiti@1.21.7) '@vitest/pretty-format@4.1.0': dependencies: @@ -4121,7 +4293,14 @@ snapshots: ansis@3.17.0: {} - ansis@4.2.0: {} + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@5.0.2: {} array-flatten@1.1.1: {} @@ -4136,6 +4315,8 @@ snapshots: bignumber.js@9.3.1: {} + binary-extensions@2.3.0: {} + body-parser@1.20.4: dependencies: bytes: 3.1.2 @@ -4167,6 +4348,10 @@ snapshots: transitivePeerDependencies: - supports-color + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + buffer-equal-constant-time@1.0.1: {} bytes@3.1.2: {} @@ -4183,24 +4368,44 @@ snapshots: call-bind-apply-helpers: 1.0.2 get-intrinsic: 1.3.0 + camelcase-css@2.0.1: {} + camelcase@6.3.0: {} chai@6.2.2: {} chalk@5.6.2: {} + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + chokidar@4.0.3: dependencies: readdirp: 4.1.2 cjs-module-lexer@2.2.0: {} + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + cliui@8.0.1: dependencies: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + clsx@2.1.1: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -4209,6 +4414,8 @@ snapshots: commander@12.1.0: {} + commander@4.1.1: {} + consola@3.4.2: {} console-table-printer@2.15.0: @@ -4242,6 +4449,10 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + cssesc@3.0.0: {} + + csstype@3.2.3: {} + data-uri-to-buffer@4.0.1: {} debug@2.6.9: @@ -4262,8 +4473,12 @@ snapshots: detect-libc@2.1.2: {} + didyoumean@1.2.2: {} + diff@7.0.0: {} + dlv@1.1.3: {} + dotenv@16.6.1: {} dts-resolver@1.2.0: @@ -4402,8 +4617,20 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + fast-uri@3.1.0: {} + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + fdir@6.5.0(picomatch@4.0.3): optionalDependencies: picomatch: 4.0.3 @@ -4413,6 +4640,10 @@ snapshots: node-domexception: 1.0.0 web-streams-polyfill: 3.3.3 + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + finalhandler@1.3.2: dependencies: debug: 2.6.9 @@ -4513,6 +4744,14 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + google-auth-library@10.6.2: dependencies: base64-js: 1.5.1 @@ -4578,16 +4817,34 @@ snapshots: ipaddr.js@1.9.1: {} + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + is-network-error@1.3.1: {} + is-number@7.0.0: {} + is-promise@4.0.0: {} is-stream@2.0.1: {} isexe@2.0.0: {} + jiti@1.21.7: {} + jiti@2.6.1: {} jose@6.2.2: {} @@ -4682,6 +4939,10 @@ snapshots: lightningcss-win32-arm64-msvc: 1.32.0 lightningcss-win32-x64-msvc: 1.32.0 + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + lodash.camelcase@4.3.0: {} long@5.3.2: {} @@ -4700,8 +4961,15 @@ snapshots: merge-descriptors@2.0.0: {} + merge2@1.4.1: {} + methods@1.1.2: {} + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + mime-db@1.52.0: {} mime-db@1.54.0: {} @@ -4724,6 +4992,12 @@ snapshots: mustache@4.2.0: {} + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + nanoid@3.3.11: {} negotiator@0.6.3: {} @@ -4742,8 +5016,12 @@ snapshots: fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 + normalize-path@3.0.0: {} + object-assign@4.1.1: {} + object-hash@3.0.0: {} + object-inspect@1.13.4: {} obug@2.1.1: {} @@ -4811,6 +5089,8 @@ snapshots: path-key@3.1.1: {} + path-parse@1.0.7: {} + path-to-regexp@0.1.12: {} path-to-regexp@8.3.0: {} @@ -4854,10 +5134,47 @@ snapshots: picocolors@1.1.1: {} + picomatch@2.3.1: {} + picomatch@4.0.3: {} + pify@2.3.0: {} + + pirates@4.0.7: {} + pkce-challenge@5.0.1: {} + postcss-import@15.1.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.11 + + postcss-js@4.1.0(postcss@8.5.8): + dependencies: + camelcase-css: 2.0.1 + postcss: 8.5.8 + + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.8): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + jiti: 1.21.7 + postcss: 8.5.8 + + postcss-nested@6.2.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-selector-parser: 6.1.2 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-value-parser@4.2.0: {} + postcss@8.5.8: dependencies: nanoid: 3.3.11 @@ -4906,6 +5223,8 @@ snapshots: quansync@1.0.0: {} + queue-microtask@1.2.3: {} + range-parser@1.2.1: {} raw-body@2.5.3: @@ -4922,6 +5241,21 @@ snapshots: iconv-lite: 0.7.2 unpipe: 1.0.0 + react-dom@19.2.4(react@19.2.4): + dependencies: + react: 19.2.4 + scheduler: 0.27.0 + + react@19.2.4: {} + + read-cache@1.0.0: + dependencies: + pify: 2.3.0 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + readdirp@4.1.2: {} reflect-metadata@0.2.2: {} @@ -4939,6 +5273,14 @@ snapshots: resolve-pkg-maps@1.0.0: {} + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.1.0: {} + rolldown-plugin-dts@0.9.11(rolldown@1.0.0-beta.8-commit.151352b(typescript@5.9.3))(typescript@5.9.3): dependencies: '@babel/generator': 7.29.1 @@ -4955,41 +5297,6 @@ snapshots: transitivePeerDependencies: - supports-color - rolldown-vite@7.1.14(@types/node@22.19.15)(jiti@2.6.1): - dependencies: - '@oxc-project/runtime': 0.92.0 - fdir: 6.5.0(picomatch@4.0.3) - lightningcss: 1.32.0 - picomatch: 4.0.3 - postcss: 8.5.8 - rolldown: 1.0.0-beta.41 - tinyglobby: 0.2.15 - optionalDependencies: - '@types/node': 22.19.15 - fsevents: 2.3.3 - jiti: 2.6.1 - - rolldown@1.0.0-beta.41: - dependencies: - '@oxc-project/types': 0.93.0 - '@rolldown/pluginutils': 1.0.0-beta.41 - ansis: 4.2.0 - optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-beta.41 - '@rolldown/binding-darwin-arm64': 1.0.0-beta.41 - '@rolldown/binding-darwin-x64': 1.0.0-beta.41 - '@rolldown/binding-freebsd-x64': 1.0.0-beta.41 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.41 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.41 - '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.41 - '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.41 - '@rolldown/binding-linux-x64-musl': 1.0.0-beta.41 - '@rolldown/binding-openharmony-arm64': 1.0.0-beta.41 - '@rolldown/binding-wasm32-wasi': 1.0.0-beta.41 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.41 - '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.41 - '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.41 - rolldown@1.0.0-beta.8-commit.151352b(typescript@5.9.3): dependencies: '@oxc-project/types': 0.66.0 @@ -5012,26 +5319,26 @@ snapshots: transitivePeerDependencies: - typescript - rolldown@1.0.0-rc.10: + rolldown@1.0.0-rc.9: dependencies: - '@oxc-project/types': 0.120.0 - '@rolldown/pluginutils': 1.0.0-rc.10 + '@oxc-project/types': 0.115.0 + '@rolldown/pluginutils': 1.0.0-rc.9 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-rc.10 - '@rolldown/binding-darwin-arm64': 1.0.0-rc.10 - '@rolldown/binding-darwin-x64': 1.0.0-rc.10 - '@rolldown/binding-freebsd-x64': 1.0.0-rc.10 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.10 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.10 - '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.10 - '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.10 - '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.10 - '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.10 - '@rolldown/binding-linux-x64-musl': 1.0.0-rc.10 - '@rolldown/binding-openharmony-arm64': 1.0.0-rc.10 - '@rolldown/binding-wasm32-wasi': 1.0.0-rc.10 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.10 - '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.10 + '@rolldown/binding-android-arm64': 1.0.0-rc.9 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.9 + '@rolldown/binding-darwin-x64': 1.0.0-rc.9 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.9 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.9 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.9 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.9 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.9 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.9 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.9 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.9 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.9 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.9 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.9 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.9 router@2.2.0: dependencies: @@ -5043,10 +5350,16 @@ snapshots: transitivePeerDependencies: - supports-color + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + safe-buffer@5.2.1: {} safer-buffer@2.1.2: {} + scheduler@0.27.0: {} + semver@7.7.4: {} send@0.19.2: @@ -5163,6 +5476,56 @@ snapshots: dependencies: ansi-regex: 5.0.1 + sucrase@3.35.1: + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + commander: 4.1.1 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + tinyglobby: 0.2.15 + ts-interface-checker: 0.1.13 + + supports-preserve-symlinks-flag@1.0.0: {} + + tailwind-merge@3.5.0: {} + + tailwindcss@3.4.19: + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.3 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.7 + lilconfig: 3.1.3 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.5.8 + postcss-import: 15.1.0(postcss@8.5.8) + postcss-js: 4.1.0(postcss@8.5.8) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.8) + postcss-nested: 6.2.0(postcss@8.5.8) + postcss-selector-parser: 6.1.2 + resolve: 1.22.11 + sucrase: 3.35.1 + transitivePeerDependencies: + - tsx + - yaml + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + tinybench@2.9.0: {} tinyexec@1.0.4: {} @@ -5174,10 +5537,16 @@ snapshots: tinyrainbow@3.1.0: {} + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + toidentifier@1.0.1: {} tr46@0.0.3: {} + ts-interface-checker@0.1.13: {} + tsdown@0.9.9(typescript@5.9.3): dependencies: ansis: 3.17.0 @@ -5246,6 +5615,8 @@ snapshots: picomatch: 4.0.3 webpack-virtual-modules: 0.6.2 + util-deprecate@1.0.2: {} + utils-merge@1.0.1: {} uuid@10.0.0: {} @@ -5262,22 +5633,23 @@ snapshots: vary@1.1.2: {} - vite@8.0.1(@types/node@22.19.15)(jiti@2.6.1): + vite@8.0.0(@types/node@22.19.15)(jiti@1.21.7): dependencies: + '@oxc-project/runtime': 0.115.0 lightningcss: 1.32.0 picomatch: 4.0.3 postcss: 8.5.8 - rolldown: 1.0.0-rc.10 + rolldown: 1.0.0-rc.9 tinyglobby: 0.2.15 optionalDependencies: '@types/node': 22.19.15 fsevents: 2.3.3 - jiti: 2.6.1 + jiti: 1.21.7 - vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@22.19.15)(vite@8.0.1(@types/node@22.19.15)(jiti@2.6.1)): + vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@22.19.15)(vite@8.0.0(@types/node@22.19.15)(jiti@1.21.7)): dependencies: '@vitest/expect': 4.1.0 - '@vitest/mocker': 4.1.0(vite@8.0.1(@types/node@22.19.15)(jiti@2.6.1)) + '@vitest/mocker': 4.1.0(vite@8.0.0(@types/node@22.19.15)(jiti@1.21.7)) '@vitest/pretty-format': 4.1.0 '@vitest/runner': 4.1.0 '@vitest/snapshot': 4.1.0 @@ -5294,7 +5666,7 @@ snapshots: tinyexec: 1.0.4 tinyglobby: 0.2.15 tinyrainbow: 3.1.0 - vite: 8.0.1(@types/node@22.19.15)(jiti@2.6.1) + vite: 8.0.0(@types/node@22.19.15)(jiti@1.21.7) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.0 diff --git a/integrations/chat-ui/src/simple-agent-chat/agent-chat-message.tsx b/integrations/appkit-agent/src/chat-ui/simple/agent-chat-message.tsx similarity index 100% rename from integrations/chat-ui/src/simple-agent-chat/agent-chat-message.tsx rename to integrations/appkit-agent/src/chat-ui/simple/agent-chat-message.tsx diff --git a/integrations/chat-ui/src/simple-agent-chat/agent-chat-part.tsx b/integrations/appkit-agent/src/chat-ui/simple/agent-chat-part.tsx similarity index 100% rename from integrations/chat-ui/src/simple-agent-chat/agent-chat-part.tsx rename to integrations/appkit-agent/src/chat-ui/simple/agent-chat-part.tsx diff --git a/integrations/chat-ui/src/simple-agent-chat/index.ts b/integrations/appkit-agent/src/chat-ui/simple/index.ts similarity index 100% rename from integrations/chat-ui/src/simple-agent-chat/index.ts rename to integrations/appkit-agent/src/chat-ui/simple/index.ts diff --git a/integrations/chat-ui/src/simple-agent-chat/primitives/button.tsx b/integrations/appkit-agent/src/chat-ui/simple/primitives/button.tsx similarity index 100% rename from integrations/chat-ui/src/simple-agent-chat/primitives/button.tsx rename to integrations/appkit-agent/src/chat-ui/simple/primitives/button.tsx diff --git a/integrations/chat-ui/src/simple-agent-chat/primitives/card.tsx b/integrations/appkit-agent/src/chat-ui/simple/primitives/card.tsx similarity index 100% rename from integrations/chat-ui/src/simple-agent-chat/primitives/card.tsx rename to integrations/appkit-agent/src/chat-ui/simple/primitives/card.tsx diff --git a/integrations/chat-ui/src/simple-agent-chat/primitives/cn.ts b/integrations/appkit-agent/src/chat-ui/simple/primitives/cn.ts similarity index 100% rename from integrations/chat-ui/src/simple-agent-chat/primitives/cn.ts rename to integrations/appkit-agent/src/chat-ui/simple/primitives/cn.ts diff --git a/integrations/chat-ui/src/simple-agent-chat/simple-agent-chat.tsx b/integrations/appkit-agent/src/chat-ui/simple/simple-agent-chat.tsx similarity index 100% rename from integrations/chat-ui/src/simple-agent-chat/simple-agent-chat.tsx rename to integrations/appkit-agent/src/chat-ui/simple/simple-agent-chat.tsx diff --git a/integrations/chat-ui/src/styles.css b/integrations/appkit-agent/src/chat-ui/simple/styles.css similarity index 89% rename from integrations/chat-ui/src/styles.css rename to integrations/appkit-agent/src/chat-ui/simple/styles.css index c832122f7..567a5f65a 100644 --- a/integrations/chat-ui/src/styles.css +++ b/integrations/appkit-agent/src/chat-ui/simple/styles.css @@ -1,8 +1,8 @@ /* - * @databricks/chat-ui — compiled stylesheet + * @databricks/appkit-agent/chat-ui/simple — compiled stylesheet * * Import this file to use the styled components without your own Tailwind setup: - * import "@databricks/chat-ui/styles.css"; + * import "@databricks/appkit-agent/chat-ui/simple/styles.css"; * * If you already use Tailwind with a Shadcn-compatible theme, you can skip this * import and let your own Tailwind config handle the utility classes. Just ensure @@ -11,10 +11,8 @@ * Theme customization: override the CSS variables below on :root or any ancestor. */ -/* Tailwind CSS variable defaults (--tw-ring-*, --tw-shadow, etc.) */ @tailwind base; -/* Utility classes extracted from the component source */ @tailwind utilities; /* ── Default theme (Shadcn-compatible) ─────────────────────────── */ diff --git a/integrations/chat-ui/src/simple-agent-chat/types.ts b/integrations/appkit-agent/src/chat-ui/simple/types.ts similarity index 100% rename from integrations/chat-ui/src/simple-agent-chat/types.ts rename to integrations/appkit-agent/src/chat-ui/simple/types.ts diff --git a/integrations/chat-ui/src/simple-agent-chat/use-agent-chat.ts b/integrations/appkit-agent/src/chat-ui/simple/use-agent-chat.ts similarity index 100% rename from integrations/chat-ui/src/simple-agent-chat/use-agent-chat.ts rename to integrations/appkit-agent/src/chat-ui/simple/use-agent-chat.ts diff --git a/integrations/chat-ui/src/simple-agent-chat/utils.ts b/integrations/appkit-agent/src/chat-ui/simple/utils.ts similarity index 100% rename from integrations/chat-ui/src/simple-agent-chat/utils.ts rename to integrations/appkit-agent/src/chat-ui/simple/utils.ts diff --git a/integrations/chat-ui/tailwind.config.js b/integrations/appkit-agent/tailwind.chat-ui.config.js similarity index 96% rename from integrations/chat-ui/tailwind.config.js rename to integrations/appkit-agent/tailwind.chat-ui.config.js index 226876de4..7f1874a37 100644 --- a/integrations/chat-ui/tailwind.config.js +++ b/integrations/appkit-agent/tailwind.chat-ui.config.js @@ -1,6 +1,6 @@ /** @type {import('tailwindcss').Config} */ export default { - content: ["./src/**/*.{ts,tsx}"], + content: ["./src/chat-ui/simple/**/*.{ts,tsx}"], darkMode: "class", corePlugins: { preflight: false, diff --git a/integrations/appkit-agent/tsconfig.json b/integrations/appkit-agent/tsconfig.json index 5518bdb15..75fe87c4b 100644 --- a/integrations/appkit-agent/tsconfig.json +++ b/integrations/appkit-agent/tsconfig.json @@ -12,7 +12,8 @@ "declarationMap": true, "sourceMap": true, "outDir": "./dist", - "lib": ["ES2023"], + "jsx": "react-jsx", + "lib": ["ES2023", "DOM", "DOM.Iterable"], "baseUrl": ".", "noEmit": true, "isolatedModules": true, diff --git a/integrations/appkit-agent/tsdown.config.ts b/integrations/appkit-agent/tsdown.config.ts index 5dc19c46d..fddfd27e6 100644 --- a/integrations/appkit-agent/tsdown.config.ts +++ b/integrations/appkit-agent/tsdown.config.ts @@ -1,24 +1,49 @@ import { defineConfig } from "tsdown"; -export default defineConfig({ - entry: { - index: "./src/index.ts", +export default defineConfig([ + { + entry: { + index: "./src/index.ts", + }, + format: ["esm", "cjs"], + fixedExtension: true, + dts: true, + outDir: "./dist", + target: "esnext", + clean: false, + sourcemap: true, + external: [ + "@databricks/appkit", + "@databricks/langchainjs", + "@langchain/core", + "@langchain/langgraph", + "@langchain/mcp-adapters", + "express", + ], + platform: "node", + treeshake: true, }, - format: ["esm", "cjs"], - fixedExtension: true, - dts: true, - outDir: "./dist", - target: "esnext", - clean: true, - sourcemap: true, - external: [ - "@databricks/appkit", - "@databricks/langchainjs", - "@langchain/core", - "@langchain/langgraph", - "@langchain/mcp-adapters", - "express", - ], - platform: "node", - treeshake: true, -}); + { + entry: { + "chat-ui/simple": "./src/chat-ui/simple/index.ts", + }, + format: ["esm", "cjs"], + fixedExtension: true, + dts: true, + outDir: "./dist", + target: "esnext", + clean: false, + sourcemap: true, + external: [ + "react", + "react-dom", + "react/jsx-runtime", + "@radix-ui/react-slot", + "class-variance-authority", + "clsx", + "tailwind-merge", + ], + platform: "browser", + treeshake: true, + }, +]); diff --git a/integrations/chat-ui/package.json b/integrations/chat-ui/package.json deleted file mode 100644 index 6a2735537..000000000 --- a/integrations/chat-ui/package.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "name": "@databricks/chat-ui", - "version": "0.1.0", - "description": "React chat UI components for Databricks AI agents", - "type": "module", - "main": "./dist/index.cjs", - "module": "./dist/index.mjs", - "types": "./dist/index.d.cts", - "exports": { - ".": { - "import": { - "types": "./dist/index.d.mts", - "default": "./dist/index.mjs" - }, - "require": { - "types": "./dist/index.d.cts", - "default": "./dist/index.cjs" - } - }, - "./styles.css": "./dist/styles.css" - }, - "files": [ - "dist", - "README.md", - "LICENSE", - "NOTICE" - ], - "scripts": { - "build": "tsdown && tailwindcss -i src/styles.css -o dist/styles.css --minify", - "dev": "tsdown --watch", - "clean": "rm -rf dist", - "test": "vitest run", - "test:watch": "vitest", - "typecheck": "tsc --noEmit", - "format": "prettier --write 'src/**/*.{ts,tsx}'", - "format:check": "prettier --check 'src/**/*.{ts,tsx}'" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - }, - "dependencies": { - "@radix-ui/react-slot": "^1.2.4", - "class-variance-authority": "^0.7.1", - "clsx": "^2.1.1", - "tailwind-merge": "^3.4.0" - }, - "devDependencies": { - "@types/node": "^22.0.0", - "@types/react": "^19.0.0", - "@types/react-dom": "^19.0.0", - "prettier": "^3.0.0", - "tailwindcss": "^3.4.0", - "react": "^19.0.0", - "react-dom": "^19.0.0", - "tsdown": "^0.9.0", - "typescript": "^5.4.0", - "vitest": "^4.0.18" - }, - "author": { - "name": "Databricks", - "email": "agent-feedback@databricks.com" - }, - "repository": { - "type": "git", - "url": "https://github.com/databricks/databricks-ai-bridge.git", - "directory": "integrations/chat-ui" - }, - "homepage": "https://github.com/databricks/databricks-ai-bridge/tree/main/integrations/chat-ui", - "bugs": { - "url": "https://github.com/databricks/databricks-ai-bridge/issues" - }, - "keywords": [ - "databricks", - "chat", - "agent", - "react", - "ui", - "components" - ], - "license": "Databricks License", - "pnpm": { - "onlyBuiltDependencies": [ - "esbuild", - "rolldown" - ] - } -} diff --git a/integrations/chat-ui/pnpm-lock.yaml b/integrations/chat-ui/pnpm-lock.yaml deleted file mode 100644 index ead6f8f20..000000000 --- a/integrations/chat-ui/pnpm-lock.yaml +++ /dev/null @@ -1,2114 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@radix-ui/react-slot': - specifier: ^1.2.4 - version: 1.2.4(@types/react@19.2.14)(react@19.2.4) - class-variance-authority: - specifier: ^0.7.1 - version: 0.7.1 - clsx: - specifier: ^2.1.1 - version: 2.1.1 - tailwind-merge: - specifier: ^3.4.0 - version: 3.5.0 - devDependencies: - '@types/node': - specifier: ^22.0.0 - version: 22.19.15 - '@types/react': - specifier: ^19.0.0 - version: 19.2.14 - '@types/react-dom': - specifier: ^19.0.0 - version: 19.2.3(@types/react@19.2.14) - prettier: - specifier: ^3.0.0 - version: 3.8.1 - react: - specifier: ^19.0.0 - version: 19.2.4 - react-dom: - specifier: ^19.0.0 - version: 19.2.4(react@19.2.4) - tailwindcss: - specifier: ^3.4.0 - version: 3.4.19 - tsdown: - specifier: ^0.9.0 - version: 0.9.9(typescript@5.9.3) - typescript: - specifier: ^5.4.0 - version: 5.9.3 - vitest: - specifier: ^4.0.18 - version: 4.1.0(@types/node@22.19.15)(vite@8.0.1(@types/node@22.19.15)(jiti@1.21.7)) - -packages: - - '@alloc/quick-lru@5.2.0': - resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} - engines: {node: '>=10'} - - '@babel/generator@7.29.1': - resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.28.5': - resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.29.2': - resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/types@7.29.0': - resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} - engines: {node: '>=6.9.0'} - - '@emnapi/core@1.9.1': - resolution: {integrity: sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==} - - '@emnapi/runtime@1.9.1': - resolution: {integrity: sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==} - - '@emnapi/wasi-threads@1.2.0': - resolution: {integrity: sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==} - - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - - '@napi-rs/wasm-runtime@0.2.12': - resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} - - '@napi-rs/wasm-runtime@1.1.1': - resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} - - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@oxc-project/types@0.120.0': - resolution: {integrity: sha512-k1YNu55DuvAip/MGE1FTsIuU3FUCn6v/ujG9V7Nq5Df/kX2CWb13hhwD0lmJGMGqE+bE1MXvv9SZVnMzEXlWcg==} - - '@oxc-project/types@0.66.0': - resolution: {integrity: sha512-KF5Wlo2KzQ+jmuCtrGISZoUfdHom7qHavNfPLW2KkeYJfYMGwtiia8KjwtsvNJ49qRiXImOCkPeVPd4bMlbR7w==} - - '@oxc-resolver/binding-darwin-arm64@9.0.2': - resolution: {integrity: sha512-MVyRgP2gzJJtAowjG/cHN3VQXwNLWnY+FpOEsyvDepJki1SdAX/8XDijM1yN6ESD1kr9uhBKjGelC6h3qtT+rA==} - cpu: [arm64] - os: [darwin] - - '@oxc-resolver/binding-darwin-x64@9.0.2': - resolution: {integrity: sha512-7kV0EOFEZ3sk5Hjy4+bfA6XOQpCwbDiDkkHN4BHHyrBHsXxUR05EcEJPPL1WjItefg+9+8hrBmoK0xRoDs41+A==} - cpu: [x64] - os: [darwin] - - '@oxc-resolver/binding-freebsd-x64@9.0.2': - resolution: {integrity: sha512-6OvkEtRXrt8sJ4aVfxHRikjain9nV1clIsWtJ1J3J8NG1ZhjyJFgT00SCvqxbK+pzeWJq6XzHyTCN78ML+lY2w==} - cpu: [x64] - os: [freebsd] - - '@oxc-resolver/binding-linux-arm-gnueabihf@9.0.2': - resolution: {integrity: sha512-aYpNL6o5IRAUIdoweW21TyLt54Hy/ZS9tvzNzF6ya1ckOQ8DLaGVPjGpmzxdNja9j/bbV6aIzBH7lNcBtiOTkQ==} - cpu: [arm] - os: [linux] - - '@oxc-resolver/binding-linux-arm64-gnu@9.0.2': - resolution: {integrity: sha512-RGFW4vCfKMFEIzb9VCY0oWyyY9tR1/o+wDdNePhiUXZU4SVniRPQaZ1SJ0sUFI1k25pXZmzQmIP6cBmazi/Dew==} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@oxc-resolver/binding-linux-arm64-musl@9.0.2': - resolution: {integrity: sha512-lxx/PibBfzqYvut2Y8N2D0Ritg9H8pKO+7NUSJb9YjR/bfk2KRmP8iaUz3zB0JhPtf/W3REs65oKpWxgflGToA==} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@oxc-resolver/binding-linux-riscv64-gnu@9.0.2': - resolution: {integrity: sha512-yD28ptS/OuNhwkpXRPNf+/FvrO7lwURLsEbRVcL1kIE0GxNJNMtKgIE4xQvtKDzkhk6ZRpLho5VSrkkF+3ARTQ==} - cpu: [riscv64] - os: [linux] - libc: [glibc] - - '@oxc-resolver/binding-linux-s390x-gnu@9.0.2': - resolution: {integrity: sha512-WBwEJdspoga2w+aly6JVZeHnxuPVuztw3fPfWrei2P6rNM5hcKxBGWKKT6zO1fPMCB4sdDkFohGKkMHVV1eryQ==} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@oxc-resolver/binding-linux-x64-gnu@9.0.2': - resolution: {integrity: sha512-a2z3/cbOOTUq0UTBG8f3EO/usFcdwwXnCejfXv42HmV/G8GjrT4fp5+5mVDoMByH3Ce3iVPxj1LmS6OvItKMYQ==} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@oxc-resolver/binding-linux-x64-musl@9.0.2': - resolution: {integrity: sha512-bHZF+WShYQWpuswB9fyxcgMIWVk4sZQT0wnwpnZgQuvGTZLkYJ1JTCXJMtaX5mIFHf69ngvawnwPIUA4Feil0g==} - cpu: [x64] - os: [linux] - libc: [musl] - - '@oxc-resolver/binding-wasm32-wasi@9.0.2': - resolution: {integrity: sha512-I5cSgCCh5nFozGSHz+PjIOfrqW99eUszlxKLgoNNzQ1xQ2ou9ZJGzcZ94BHsM9SpyYHLtgHljmOZxCT9bgxYNA==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@oxc-resolver/binding-win32-arm64-msvc@9.0.2': - resolution: {integrity: sha512-5IhoOpPr38YWDWRCA5kP30xlUxbIJyLAEsAK7EMyUgqygBHEYLkElaKGgS0X5jRXUQ6l5yNxuW73caogb2FYaw==} - cpu: [arm64] - os: [win32] - - '@oxc-resolver/binding-win32-x64-msvc@9.0.2': - resolution: {integrity: sha512-Qc40GDkaad9rZksSQr2l/V9UubigIHsW69g94Gswc2sKYB3XfJXfIfyV8WTJ67u6ZMXsZ7BH1msSC6Aen75mCg==} - cpu: [x64] - os: [win32] - - '@oxc-transform/binding-darwin-arm64@0.67.0': - resolution: {integrity: sha512-P3zBMhpOQceNSys3/ZqvrjuRvcIbVzfGFN/tH34HlVkOjOmfGK1mOWjORsGAZtbgh1muXrF6mQETLzFjfYndXQ==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [darwin] - - '@oxc-transform/binding-darwin-x64@0.67.0': - resolution: {integrity: sha512-B52aeo/C3spYHcwFQ4nAbDkwbMKf0K6ncWM8GrVUgGu8PPECLBhjPCW11kPW/lt9FxwrdgVYVzPYlZ6wmJmpEA==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [darwin] - - '@oxc-transform/binding-linux-arm-gnueabihf@0.67.0': - resolution: {integrity: sha512-5Ir1eQrC9lvj/rR1TJVGwOR4yLgXTLmfKHIfpVH7GGSQrzK7VMUfHWX+dAsX1VutaeE8puXIqtYvf9cHLw78dw==} - engines: {node: '>=14.0.0'} - cpu: [arm] - os: [linux] - - '@oxc-transform/binding-linux-arm64-gnu@0.67.0': - resolution: {integrity: sha512-zTqfPET5+hZfJ3/dMqJboKxrpXMXk+j2HVdvX0wVhW2MI7n7hwELl+In6Yu20nXuEyJkNQlWHbNPCUfpM+cBWw==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@oxc-transform/binding-linux-arm64-musl@0.67.0': - resolution: {integrity: sha512-jzz/ATUhZ8wetb4gm5GwzheZns3Qj1CZ+DIMmD8nBxQXszmTS/fqnAPpgzruyLqkXBUuUfF3pHv5f/UmuHReuQ==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@oxc-transform/binding-linux-x64-gnu@0.67.0': - resolution: {integrity: sha512-Qy2+tfglJ8yX6guC1EDAnuuzRZIXciXO9UwOewxyiahLxwuTpj/wvvZN3Cb1SA3c14zrwb2TNMZvaXS1/OS5Pg==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@oxc-transform/binding-linux-x64-musl@0.67.0': - resolution: {integrity: sha512-tHoYgDIRhgvh+/wIrzAk3cUoj/LSSoJAdsZW9XRlaixFW/TF2puxRyaS1hRco0bcKTwotXl/eDYqZmhIfUyGRQ==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [linux] - libc: [musl] - - '@oxc-transform/binding-wasm32-wasi@0.67.0': - resolution: {integrity: sha512-ZPT+1HECf7WUnotodIuS8tvSkwaiCdC2DDw8HVRmlerbS6iPYIPKyBCvkSM4RyUx0kljZtB9AciLCkEbwy5/zA==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@oxc-transform/binding-win32-arm64-msvc@0.67.0': - resolution: {integrity: sha512-+E3lOHCk4EuIk6IjshBAARknAUpgH+gHTtZxCPqK4AWYA+Tls2J6C0FVM48uZ4m3rZpAq8ZszM9JZVAkOaynBQ==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [win32] - - '@oxc-transform/binding-win32-x64-msvc@0.67.0': - resolution: {integrity: sha512-3pIIFb9g5aFrAODTQVJYitq+ONHgDJ4IYk/7pk+jsG6JpKUkURd0auUlxvriO11fFit5hdwy+wIbU4kBvyRUkg==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [win32] - - '@quansync/fs@1.0.0': - resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} - - '@radix-ui/react-compose-refs@1.1.2': - resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@radix-ui/react-slot@1.2.4': - resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==} - peerDependencies: - '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc - peerDependenciesMeta: - '@types/react': - optional: true - - '@rolldown/binding-android-arm64@1.0.0-rc.10': - resolution: {integrity: sha512-jOHxwXhxmFKuXztiu1ORieJeTbx5vrTkcOkkkn2d35726+iwhrY1w/+nYY/AGgF12thg33qC3R1LMBF5tHTZHg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@rolldown/binding-darwin-arm64@1.0.0-beta.8-commit.151352b': - resolution: {integrity: sha512-2F4bhDtV6CHBx7JMiT9xvmxkcZLHFmonfbli36RyfvgThDOAu92bis28zDTdguDY85lN/jBRKX/eOvX+T5hMkg==} - cpu: [arm64] - os: [darwin] - - '@rolldown/binding-darwin-arm64@1.0.0-rc.10': - resolution: {integrity: sha512-gED05Teg/vtTZbIJBc4VNMAxAFDUPkuO/rAIyyxZjTj1a1/s6z5TII/5yMGZ0uLRCifEtwUQn8OlYzuYc0m70w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@rolldown/binding-darwin-x64@1.0.0-beta.8-commit.151352b': - resolution: {integrity: sha512-8VMChhFLeD/oOAQUspFtxZaV7ctDob63w626kwvBBIHtlpY2Ohw4rsfjjtGckyrTCI/RROgZv/TVVEsG3GkgLw==} - cpu: [x64] - os: [darwin] - - '@rolldown/binding-darwin-x64@1.0.0-rc.10': - resolution: {integrity: sha512-rI15NcM1mA48lqrIxVkHfAqcyFLcQwyXWThy+BQ5+mkKKPvSO26ir+ZDp36AgYoYVkqvMcdS8zOE6SeBsR9e8A==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@rolldown/binding-freebsd-x64@1.0.0-beta.8-commit.151352b': - resolution: {integrity: sha512-4W28EgaIidbWIpwB3hESMBfiOSs7LBFpJGa8JIV488qLEnTR/pqzxDEoOPobhRSJ1lJlv0vUgA8+DKBIldo2gw==} - cpu: [x64] - os: [freebsd] - - '@rolldown/binding-freebsd-x64@1.0.0-rc.10': - resolution: {integrity: sha512-XZRXHdTa+4ME1MuDVp021+doQ+z6Ei4CCFmNc5/sKbqb8YmkiJdj8QKlV3rCI0AJtAeSB5n0WGPuJWNL9p/L2w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.8-commit.151352b': - resolution: {integrity: sha512-1ECtyzIKlAHikR7BhS4hk7Hxw8xCH6W3S+Sb74EM0vy5AqPvWSbgLfAwagYC7gNDcMMby3I757X7qih5fIrGiw==} - cpu: [arm] - os: [linux] - - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.10': - resolution: {integrity: sha512-R0SQMRluISSLzFE20sPWYHVmJdDQnRyc/FzSCN72BqQmh2SOZUFG+N3/vBZpR4C6WpEUVYJLrYUXaj43sJsNLA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.8-commit.151352b': - resolution: {integrity: sha512-wU1kp8qPRUKC8N82dNs3F5+UyKRww9TUEO5dQ5mxCb0cG+y4l5rVaXpMgvL0VuQahPVvTMs577QPhJGb4iDONw==} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.10': - resolution: {integrity: sha512-Y1reMrV/o+cwpduYhJuOE3OMKx32RMYCidf14y+HssARRmhDuWXJ4yVguDg2R/8SyyGNo+auzz64LnPK9Hq6jg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.8-commit.151352b': - resolution: {integrity: sha512-odDjO2UtEEMAzwmLHEOKylJjQa+em1REAO9H19PA+O+lPu6evVbre5bqu8qCjEtHG1Q034LpZR86imCP2arb/w==} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.10': - resolution: {integrity: sha512-vELN+HNb2IzuzSBUOD4NHmP9yrGwl1DVM29wlQvx1OLSclL0NgVWnVDKl/8tEks79EFek/kebQKnNJkIAA4W2g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.10': - resolution: {integrity: sha512-ZqrufYTgzxbHwpqOjzSsb0UV/aV2TFIY5rP8HdsiPTv/CuAgCRjM6s9cYFwQ4CNH+hf9Y4erHW1GjZuZ7WoI7w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.10': - resolution: {integrity: sha512-gSlmVS1FZJSRicA6IyjoRoKAFK7IIHBs7xJuHRSmjImqk3mPPWbR7RhbnfH2G6bcmMEllCt2vQ/7u9e6bBnByg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.8-commit.151352b': - resolution: {integrity: sha512-Ty2T67t2Oj1lg417ATRENxdk8Jkkksc/YQdCJyvkGqteHe60pSU2GGP/tLWGB+I0Ox+u387bzU/SmfmrHZk9aw==} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.10': - resolution: {integrity: sha512-eOCKUpluKgfObT2pHjztnaWEIbUabWzk3qPZ5PuacuPmr4+JtQG4k2vGTY0H15edaTnicgU428XW/IH6AimcQw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@rolldown/binding-linux-x64-musl@1.0.0-beta.8-commit.151352b': - resolution: {integrity: sha512-Fm1TxyeVE+gy74HM26CwbEOUndIoWAMgWkVDxYBD64tayvp5JvltpGHaqCg6x5i+X2F5XCDCItqwVlC7/mTxIw==} - cpu: [x64] - os: [linux] - libc: [musl] - - '@rolldown/binding-linux-x64-musl@1.0.0-rc.10': - resolution: {integrity: sha512-Xdf2jQbfQowJnLcgYfD/m0Uu0Qj5OdxKallD78/IPPfzaiaI4KRAwZzHcKQ4ig1gtg1SuzC7jovNiM2TzQsBXA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [musl] - - '@rolldown/binding-openharmony-arm64@1.0.0-rc.10': - resolution: {integrity: sha512-o1hYe8hLi1EY6jgPFyxQgQ1wcycX+qz8eEbVmot2hFkgUzPxy9+kF0u0NIQBeDq+Mko47AkaFFaChcvZa9UX9Q==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@rolldown/binding-wasm32-wasi@1.0.0-beta.8-commit.151352b': - resolution: {integrity: sha512-AEZzTyGerfkffXmtv7kFJbHWkryNeolk0Br+yhH1wZyN6Tt6aebqICDL8KNRO2iExoEWzyYS6dPxh0QmvNTfUQ==} - engines: {node: '>=14.21.3'} - cpu: [wasm32] - - '@rolldown/binding-wasm32-wasi@1.0.0-rc.10': - resolution: {integrity: sha512-Ugv9o7qYJudqQO5Y5y2N2SOo6S4WiqiNOpuQyoPInnhVzCY+wi/GHltcLHypG9DEUYMB0iTB/huJrpadiAcNcA==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.8-commit.151352b': - resolution: {integrity: sha512-0lskDFKQwf5PMjl17qHAroU6oVU0Zn8NbAH/PdM9QB1emOzyFDGa20d4kESGeo3Uq7xOKXcTORJV/JwKIBORqw==} - cpu: [arm64] - os: [win32] - - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.10': - resolution: {integrity: sha512-7UODQb4fQUNT/vmgDZBl3XOBAIOutP5R3O/rkxg0aLfEGQ4opbCgU5vOw/scPe4xOqBwL9fw7/RP1vAMZ6QlAQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - - '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.8-commit.151352b': - resolution: {integrity: sha512-DfG1S0zGKnUfr95cNCmR4YPiZ/moS7Tob5eV+9r5JGeHZVWFHWwvJdR0jArj6Ty0LbBFDTVVB3iAvqRSji+l0Q==} - cpu: [ia32] - os: [win32] - - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.8-commit.151352b': - resolution: {integrity: sha512-5HZEtc8U2I1O903hXBynWtWaf+qzAFj66h5B7gOtVcvqIk+lKRVSupA85OdIvR7emrsYU25ikpfiU5Jhg9kTbQ==} - cpu: [x64] - os: [win32] - - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.10': - resolution: {integrity: sha512-PYxKHMVHOb5NJuDL53vBUl1VwUjymDcYI6rzpIni0C9+9mTiJedvUxSk7/RPp7OOAm3v+EjgMu9bIy3N6b408w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - - '@rolldown/pluginutils@1.0.0-rc.10': - resolution: {integrity: sha512-UkVDEFk1w3mveXeKgaTuYfKWtPbvgck1dT8TUG3bnccrH0XtLTuAyfCoks4Q/M5ZGToSVJTIQYCzy2g/atAOeg==} - - '@standard-schema/spec@1.1.0': - resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - - '@tybys/wasm-util@0.10.1': - resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} - - '@types/chai@5.2.3': - resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} - - '@types/deep-eql@4.0.2': - resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/node@22.19.15': - resolution: {integrity: sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==} - - '@types/react-dom@19.2.3': - resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} - peerDependencies: - '@types/react': ^19.2.0 - - '@types/react@19.2.14': - resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} - - '@valibot/to-json-schema@1.0.0': - resolution: {integrity: sha512-/9crJgPptVsGCL6X+JPDQyaJwkalSZ/52WuF8DiRUxJgcmpNdzYRfZ+gqMEP8W3CTVfuMWPqqvIgfwJ97f9Etw==} - peerDependencies: - valibot: ^1.0.0 - - '@vitest/expect@4.1.0': - resolution: {integrity: sha512-EIxG7k4wlWweuCLG9Y5InKFwpMEOyrMb6ZJ1ihYu02LVj/bzUwn2VMU+13PinsjRW75XnITeFrQBMH5+dLvCDA==} - - '@vitest/mocker@4.1.0': - resolution: {integrity: sha512-evxREh+Hork43+Y4IOhTo+h5lGmVRyjqI739Rz4RlUPqwrkFFDF6EMvOOYjTx4E8Tl6gyCLRL8Mu7Ry12a13Tw==} - peerDependencies: - msw: ^2.4.9 - vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true - - '@vitest/pretty-format@4.1.0': - resolution: {integrity: sha512-3RZLZlh88Ib0J7NQTRATfc/3ZPOnSUn2uDBUoGNn5T36+bALixmzphN26OUD3LRXWkJu4H0s5vvUeqBiw+kS0A==} - - '@vitest/runner@4.1.0': - resolution: {integrity: sha512-Duvx2OzQ7d6OjchL+trw+aSrb9idh7pnNfxrklo14p3zmNL4qPCDeIJAK+eBKYjkIwG96Bc6vYuxhqDXQOWpoQ==} - - '@vitest/snapshot@4.1.0': - resolution: {integrity: sha512-0Vy9euT1kgsnj1CHttwi9i9o+4rRLEaPRSOJ5gyv579GJkNpgJK+B4HSv/rAWixx2wdAFci1X4CEPjiu2bXIMg==} - - '@vitest/spy@4.1.0': - resolution: {integrity: sha512-pz77k+PgNpyMDv2FV6qmk5ZVau6c3R8HC8v342T2xlFxQKTrSeYw9waIJG8KgV9fFwAtTu4ceRzMivPTH6wSxw==} - - '@vitest/utils@4.1.0': - resolution: {integrity: sha512-XfPXT6a8TZY3dcGY8EdwsBulFCIw+BeeX0RZn2x/BtiY/75YGh8FeWGG8QISN/WhaqSrE2OrlDgtF8q5uhOTmw==} - - acorn@8.16.0: - resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} - engines: {node: '>=0.4.0'} - hasBin: true - - ansis@3.17.0: - resolution: {integrity: sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==} - engines: {node: '>=14'} - - any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - - arg@5.0.2: - resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} - - assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} - - ast-kit@1.4.3: - resolution: {integrity: sha512-MdJqjpodkS5J149zN0Po+HPshkTdUyrvF7CKTafUgv69vBSPtncrj+3IiUgqdd7ElIEkbeXCsEouBUwLrw9Ilg==} - engines: {node: '>=16.14.0'} - - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - - cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} - - camelcase-css@2.0.1: - resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} - engines: {node: '>= 6'} - - chai@6.2.2: - resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} - engines: {node: '>=18'} - - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} - - chokidar@4.0.3: - resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} - engines: {node: '>= 14.16.0'} - - class-variance-authority@0.7.1: - resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} - - clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} - engines: {node: '>=6'} - - commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} - - consola@3.4.2: - resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} - engines: {node: ^14.18.0 || >=16.10.0} - - convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - - cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} - hasBin: true - - csstype@3.2.3: - resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} - - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - defu@6.1.4: - resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - - detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} - - didyoumean@1.2.2: - resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} - - diff@7.0.0: - resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} - engines: {node: '>=0.3.1'} - - dlv@1.1.3: - resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} - - dts-resolver@1.2.0: - resolution: {integrity: sha512-+xNF7raXYI1E3IFB+f3JqvoKYFI8R+1Mh9mpI75yNm3F5XuiC6ErEXe2Lqh9ach+4MQ1tOefzjxulhWGVclYbg==} - engines: {node: '>=20.18.0'} - - empathic@1.1.0: - resolution: {integrity: sha512-rsPft6CK3eHtrlp9Y5ALBb+hfK+DWnA4WFebbazxjWyx8vSm3rZeoM3z9irsjcqO3PYRzlfv27XIB4tz2DV7RA==} - engines: {node: '>=14'} - - es-module-lexer@2.0.0: - resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} - - estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - - expect-type@1.3.0: - resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} - engines: {node: '>=12.0.0'} - - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} - - fastq@1.20.1: - resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} - - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} - peerDependencies: - picomatch: ^3 || ^4 - peerDependenciesMeta: - picomatch: - optional: true - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - get-tsconfig@4.13.6: - resolution: {integrity: sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==} - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - - hookable@5.5.3: - resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} - - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - - is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} - engines: {node: '>= 0.4'} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - jiti@1.21.7: - resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} - hasBin: true - - jiti@2.6.1: - resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} - hasBin: true - - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true - - lightningcss-android-arm64@1.32.0: - resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [android] - - lightningcss-darwin-arm64@1.32.0: - resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [darwin] - - lightningcss-darwin-x64@1.32.0: - resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [darwin] - - lightningcss-freebsd-x64@1.32.0: - resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [freebsd] - - lightningcss-linux-arm-gnueabihf@1.32.0: - resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} - engines: {node: '>= 12.0.0'} - cpu: [arm] - os: [linux] - - lightningcss-linux-arm64-gnu@1.32.0: - resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - libc: [glibc] - - lightningcss-linux-arm64-musl@1.32.0: - resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [linux] - libc: [musl] - - lightningcss-linux-x64-gnu@1.32.0: - resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - libc: [glibc] - - lightningcss-linux-x64-musl@1.32.0: - resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [linux] - libc: [musl] - - lightningcss-win32-arm64-msvc@1.32.0: - resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] - os: [win32] - - lightningcss-win32-x64-msvc@1.32.0: - resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} - engines: {node: '>= 12.0.0'} - cpu: [x64] - os: [win32] - - lightningcss@1.32.0: - resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} - engines: {node: '>= 12.0.0'} - - lilconfig@3.1.3: - resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} - engines: {node: '>=14'} - - lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - - magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - mz@2.7.0: - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - object-hash@3.0.0: - resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} - engines: {node: '>= 6'} - - obug@2.1.1: - resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} - - oxc-resolver@9.0.2: - resolution: {integrity: sha512-w838ygc1p7rF+7+h5vR9A+Y9Fc4imy6C3xPthCMkdFUgFvUWkmABeNB8RBDQ6+afk44Q60/UMMQ+gfDUW99fBA==} - - oxc-transform@0.67.0: - resolution: {integrity: sha512-QXwmpLfNrXZoHgIjEtDEf6lhwmvHouNtstNgg/UveczVIjo8VSzd5h25Ea96PoX9KzReJUY/qYa4QSNkJpZGfA==} - engines: {node: '>=14.0.0'} - - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} - engines: {node: '>=12'} - - pify@2.3.0: - resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} - engines: {node: '>=0.10.0'} - - pirates@4.0.7: - resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} - engines: {node: '>= 6'} - - postcss-import@15.1.0: - resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} - engines: {node: '>=14.0.0'} - peerDependencies: - postcss: ^8.0.0 - - postcss-js@4.1.0: - resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} - engines: {node: ^12 || ^14 || >= 16} - peerDependencies: - postcss: ^8.4.21 - - postcss-load-config@6.0.1: - resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} - engines: {node: '>= 18'} - peerDependencies: - jiti: '>=1.21.0' - postcss: '>=8.0.9' - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - jiti: - optional: true - postcss: - optional: true - tsx: - optional: true - yaml: - optional: true - - postcss-nested@6.2.0: - resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} - engines: {node: '>=12.0'} - peerDependencies: - postcss: ^8.2.14 - - postcss-selector-parser@6.1.2: - resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} - engines: {node: '>=4'} - - postcss-value-parser@4.2.0: - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - - postcss@8.5.8: - resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} - engines: {node: ^10 || ^12 || >=14} - - prettier@3.8.1: - resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} - engines: {node: '>=14'} - hasBin: true - - quansync@1.0.0: - resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - react-dom@19.2.4: - resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} - peerDependencies: - react: ^19.2.4 - - react@19.2.4: - resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} - engines: {node: '>=0.10.0'} - - read-cache@1.0.0: - resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} - - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - - readdirp@4.1.2: - resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} - engines: {node: '>= 14.18.0'} - - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - - resolve@1.22.11: - resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} - engines: {node: '>= 0.4'} - hasBin: true - - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - rolldown-plugin-dts@0.9.11: - resolution: {integrity: sha512-iCIRKmvPLwRV4UKSxhaBo+5wDkvc3+MFiqYYvu7sGLSohzxoDn9WEsjN3y7A6xg3aCuxHh6rlRp8xbX98r1rSg==} - engines: {node: '>=20.18.0'} - peerDependencies: - rolldown: ^1.0.0-beta.7 - typescript: ^5.0.0 - peerDependenciesMeta: - typescript: - optional: true - - rolldown@1.0.0-beta.8-commit.151352b: - resolution: {integrity: sha512-TCb6GVaFBk4wB0LERofFDxTO5X1/Sgahr7Yn5UA9XjuFtCwL1CyEhUHX5lUIstcMxjbkLjn2z4TAGwisr6Blvw==} - hasBin: true - peerDependencies: - '@oxc-project/runtime': 0.66.0 - peerDependenciesMeta: - '@oxc-project/runtime': - optional: true - - rolldown@1.0.0-rc.10: - resolution: {integrity: sha512-q7j6vvarRFmKpgJUT8HCAUljkgzEp4LAhPlJUvQhA5LA1SUL36s5QCysMutErzL3EbNOZOkoziSx9iZC4FddKA==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - scheduler@0.27.0: - resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} - - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} - - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - - std-env@4.0.0: - resolution: {integrity: sha512-zUMPtQ/HBY3/50VbpkupYHbRroTRZJPRLvreamgErJVys0ceuzMkD44J/QjqhHjOzK42GQ3QZIeFG1OYfOtKqQ==} - - sucrase@3.35.1: - resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - - tailwind-merge@3.5.0: - resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==} - - tailwindcss@3.4.19: - resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==} - engines: {node: '>=14.0.0'} - hasBin: true - - thenify-all@1.6.0: - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} - engines: {node: '>=0.8'} - - thenify@3.3.1: - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - - tinyexec@1.0.4: - resolution: {integrity: sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==} - engines: {node: '>=18'} - - tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} - engines: {node: '>=12.0.0'} - - tinyrainbow@3.1.0: - resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} - engines: {node: '>=14.0.0'} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - ts-interface-checker@0.1.13: - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - - tsdown@0.9.9: - resolution: {integrity: sha512-IIGX55rkhaPomNSVrIbA58DRBwTO4ehlDTsw20XSooGqoEZbwpunDc1dRE73wKb1rHdwwBO6NMLOcgV2n1qhpA==} - engines: {node: '>=18.0.0'} - hasBin: true - peerDependencies: - publint: ^0.3.0 - unplugin-unused: ^0.4.0 - peerDependenciesMeta: - publint: - optional: true - unplugin-unused: - optional: true - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - - typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} - engines: {node: '>=14.17'} - hasBin: true - - unconfig-core@7.5.0: - resolution: {integrity: sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==} - - unconfig@7.5.0: - resolution: {integrity: sha512-oi8Qy2JV4D3UQ0PsopR28CzdQ3S/5A1zwsUwp/rosSbfhJ5z7b90bIyTwi/F7hCLD4SGcZVjDzd4XoUQcEanvA==} - - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - - unplugin-lightningcss@0.3.3: - resolution: {integrity: sha512-mMNRCNIcxc/3410w7sJdXcPxn0IGZdEpq42OBDyckdGkhOeWYZCG9RkHs72TFyBsS82a4agFDOFU8VrFKF2ZvA==} - engines: {node: '>=18.12.0'} - - unplugin@2.3.11: - resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} - engines: {node: '>=18.12.0'} - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - valibot@1.0.0: - resolution: {integrity: sha512-1Hc0ihzWxBar6NGeZv7fPLY0QuxFMyxwYR2sF1Blu7Wq7EnremwY2W02tit2ij2VJT8HcSkHAQqmFfl77f73Yw==} - peerDependencies: - typescript: '>=5' - peerDependenciesMeta: - typescript: - optional: true - - vite@8.0.1: - resolution: {integrity: sha512-wt+Z2qIhfFt85uiyRt5LPU4oVEJBXj8hZNWKeqFG4gRG/0RaRGJ7njQCwzFVjO+v4+Ipmf5CY7VdmZRAYYBPHw==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.1.0 - esbuild: ^0.27.0 - jiti: '>=1.21.0' - less: ^4.0.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: '>=0.54.8' - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - '@vitejs/devtools': - optional: true - esbuild: - optional: true - jiti: - optional: true - less: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - - vitest@4.1.0: - resolution: {integrity: sha512-YbDrMF9jM2Lqc++2530UourxZHmkKLxrs4+mYhEwqWS97WJ7wOYEkcr+QfRgJ3PW9wz3odRijLZjHEaRLTNbqw==} - engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@opentelemetry/api': ^1.9.0 - '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.0 - '@vitest/browser-preview': 4.1.0 - '@vitest/browser-webdriverio': 4.1.0 - '@vitest/ui': 4.1.0 - happy-dom: '*' - jsdom: '*' - vite: ^6.0.0 || ^7.0.0 || ^8.0.0-0 - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@opentelemetry/api': - optional: true - '@types/node': - optional: true - '@vitest/browser-playwright': - optional: true - '@vitest/browser-preview': - optional: true - '@vitest/browser-webdriverio': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - - webpack-virtual-modules@0.6.2: - resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} - - why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} - hasBin: true - -snapshots: - - '@alloc/quick-lru@5.2.0': {} - - '@babel/generator@7.29.1': - dependencies: - '@babel/parser': 7.29.2 - '@babel/types': 7.29.0 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - jsesc: 3.1.0 - - '@babel/helper-string-parser@7.27.1': {} - - '@babel/helper-validator-identifier@7.28.5': {} - - '@babel/parser@7.29.2': - dependencies: - '@babel/types': 7.29.0 - - '@babel/types@7.29.0': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 - - '@emnapi/core@1.9.1': - dependencies: - '@emnapi/wasi-threads': 1.2.0 - tslib: 2.8.1 - optional: true - - '@emnapi/runtime@1.9.1': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/wasi-threads@1.2.0': - dependencies: - tslib: 2.8.1 - optional: true - - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/remapping@2.3.5': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/sourcemap-codec@1.5.5': {} - - '@jridgewell/trace-mapping@0.3.31': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - - '@napi-rs/wasm-runtime@0.2.12': - dependencies: - '@emnapi/core': 1.9.1 - '@emnapi/runtime': 1.9.1 - '@tybys/wasm-util': 0.10.1 - optional: true - - '@napi-rs/wasm-runtime@1.1.1': - dependencies: - '@emnapi/core': 1.9.1 - '@emnapi/runtime': 1.9.1 - '@tybys/wasm-util': 0.10.1 - optional: true - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.20.1 - - '@oxc-project/types@0.120.0': {} - - '@oxc-project/types@0.66.0': {} - - '@oxc-resolver/binding-darwin-arm64@9.0.2': - optional: true - - '@oxc-resolver/binding-darwin-x64@9.0.2': - optional: true - - '@oxc-resolver/binding-freebsd-x64@9.0.2': - optional: true - - '@oxc-resolver/binding-linux-arm-gnueabihf@9.0.2': - optional: true - - '@oxc-resolver/binding-linux-arm64-gnu@9.0.2': - optional: true - - '@oxc-resolver/binding-linux-arm64-musl@9.0.2': - optional: true - - '@oxc-resolver/binding-linux-riscv64-gnu@9.0.2': - optional: true - - '@oxc-resolver/binding-linux-s390x-gnu@9.0.2': - optional: true - - '@oxc-resolver/binding-linux-x64-gnu@9.0.2': - optional: true - - '@oxc-resolver/binding-linux-x64-musl@9.0.2': - optional: true - - '@oxc-resolver/binding-wasm32-wasi@9.0.2': - dependencies: - '@napi-rs/wasm-runtime': 0.2.12 - optional: true - - '@oxc-resolver/binding-win32-arm64-msvc@9.0.2': - optional: true - - '@oxc-resolver/binding-win32-x64-msvc@9.0.2': - optional: true - - '@oxc-transform/binding-darwin-arm64@0.67.0': - optional: true - - '@oxc-transform/binding-darwin-x64@0.67.0': - optional: true - - '@oxc-transform/binding-linux-arm-gnueabihf@0.67.0': - optional: true - - '@oxc-transform/binding-linux-arm64-gnu@0.67.0': - optional: true - - '@oxc-transform/binding-linux-arm64-musl@0.67.0': - optional: true - - '@oxc-transform/binding-linux-x64-gnu@0.67.0': - optional: true - - '@oxc-transform/binding-linux-x64-musl@0.67.0': - optional: true - - '@oxc-transform/binding-wasm32-wasi@0.67.0': - dependencies: - '@napi-rs/wasm-runtime': 0.2.12 - optional: true - - '@oxc-transform/binding-win32-arm64-msvc@0.67.0': - optional: true - - '@oxc-transform/binding-win32-x64-msvc@0.67.0': - optional: true - - '@quansync/fs@1.0.0': - dependencies: - quansync: 1.0.0 - - '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.14)(react@19.2.4)': - dependencies: - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - '@radix-ui/react-slot@1.2.4(@types/react@19.2.14)(react@19.2.4)': - dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4) - react: 19.2.4 - optionalDependencies: - '@types/react': 19.2.14 - - '@rolldown/binding-android-arm64@1.0.0-rc.10': - optional: true - - '@rolldown/binding-darwin-arm64@1.0.0-beta.8-commit.151352b': - optional: true - - '@rolldown/binding-darwin-arm64@1.0.0-rc.10': - optional: true - - '@rolldown/binding-darwin-x64@1.0.0-beta.8-commit.151352b': - optional: true - - '@rolldown/binding-darwin-x64@1.0.0-rc.10': - optional: true - - '@rolldown/binding-freebsd-x64@1.0.0-beta.8-commit.151352b': - optional: true - - '@rolldown/binding-freebsd-x64@1.0.0-rc.10': - optional: true - - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.8-commit.151352b': - optional: true - - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.10': - optional: true - - '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.8-commit.151352b': - optional: true - - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.10': - optional: true - - '@rolldown/binding-linux-arm64-musl@1.0.0-beta.8-commit.151352b': - optional: true - - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.10': - optional: true - - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.10': - optional: true - - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.10': - optional: true - - '@rolldown/binding-linux-x64-gnu@1.0.0-beta.8-commit.151352b': - optional: true - - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.10': - optional: true - - '@rolldown/binding-linux-x64-musl@1.0.0-beta.8-commit.151352b': - optional: true - - '@rolldown/binding-linux-x64-musl@1.0.0-rc.10': - optional: true - - '@rolldown/binding-openharmony-arm64@1.0.0-rc.10': - optional: true - - '@rolldown/binding-wasm32-wasi@1.0.0-beta.8-commit.151352b': - dependencies: - '@napi-rs/wasm-runtime': 0.2.12 - optional: true - - '@rolldown/binding-wasm32-wasi@1.0.0-rc.10': - dependencies: - '@napi-rs/wasm-runtime': 1.1.1 - optional: true - - '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.8-commit.151352b': - optional: true - - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.10': - optional: true - - '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.8-commit.151352b': - optional: true - - '@rolldown/binding-win32-x64-msvc@1.0.0-beta.8-commit.151352b': - optional: true - - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.10': - optional: true - - '@rolldown/pluginutils@1.0.0-rc.10': {} - - '@standard-schema/spec@1.1.0': {} - - '@tybys/wasm-util@0.10.1': - dependencies: - tslib: 2.8.1 - optional: true - - '@types/chai@5.2.3': - dependencies: - '@types/deep-eql': 4.0.2 - assertion-error: 2.0.1 - - '@types/deep-eql@4.0.2': {} - - '@types/estree@1.0.8': {} - - '@types/node@22.19.15': - dependencies: - undici-types: 6.21.0 - - '@types/react-dom@19.2.3(@types/react@19.2.14)': - dependencies: - '@types/react': 19.2.14 - - '@types/react@19.2.14': - dependencies: - csstype: 3.2.3 - - '@valibot/to-json-schema@1.0.0(valibot@1.0.0(typescript@5.9.3))': - dependencies: - valibot: 1.0.0(typescript@5.9.3) - - '@vitest/expect@4.1.0': - dependencies: - '@standard-schema/spec': 1.1.0 - '@types/chai': 5.2.3 - '@vitest/spy': 4.1.0 - '@vitest/utils': 4.1.0 - chai: 6.2.2 - tinyrainbow: 3.1.0 - - '@vitest/mocker@4.1.0(vite@8.0.1(@types/node@22.19.15)(jiti@1.21.7))': - dependencies: - '@vitest/spy': 4.1.0 - estree-walker: 3.0.3 - magic-string: 0.30.21 - optionalDependencies: - vite: 8.0.1(@types/node@22.19.15)(jiti@1.21.7) - - '@vitest/pretty-format@4.1.0': - dependencies: - tinyrainbow: 3.1.0 - - '@vitest/runner@4.1.0': - dependencies: - '@vitest/utils': 4.1.0 - pathe: 2.0.3 - - '@vitest/snapshot@4.1.0': - dependencies: - '@vitest/pretty-format': 4.1.0 - '@vitest/utils': 4.1.0 - magic-string: 0.30.21 - pathe: 2.0.3 - - '@vitest/spy@4.1.0': {} - - '@vitest/utils@4.1.0': - dependencies: - '@vitest/pretty-format': 4.1.0 - convert-source-map: 2.0.0 - tinyrainbow: 3.1.0 - - acorn@8.16.0: {} - - ansis@3.17.0: {} - - any-promise@1.3.0: {} - - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - - arg@5.0.2: {} - - assertion-error@2.0.1: {} - - ast-kit@1.4.3: - dependencies: - '@babel/parser': 7.29.2 - pathe: 2.0.3 - - binary-extensions@2.3.0: {} - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - cac@6.7.14: {} - - camelcase-css@2.0.1: {} - - chai@6.2.2: {} - - chokidar@3.6.0: - dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - - chokidar@4.0.3: - dependencies: - readdirp: 4.1.2 - - class-variance-authority@0.7.1: - dependencies: - clsx: 2.1.1 - - clsx@2.1.1: {} - - commander@4.1.1: {} - - consola@3.4.2: {} - - convert-source-map@2.0.0: {} - - cssesc@3.0.0: {} - - csstype@3.2.3: {} - - debug@4.4.3: - dependencies: - ms: 2.1.3 - - defu@6.1.4: {} - - detect-libc@2.1.2: {} - - didyoumean@1.2.2: {} - - diff@7.0.0: {} - - dlv@1.1.3: {} - - dts-resolver@1.2.0: - dependencies: - oxc-resolver: 9.0.2 - pathe: 2.0.3 - - empathic@1.1.0: {} - - es-module-lexer@2.0.0: {} - - estree-walker@3.0.3: - dependencies: - '@types/estree': 1.0.8 - - expect-type@1.3.0: {} - - fast-glob@3.3.3: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fastq@1.20.1: - dependencies: - reusify: 1.1.0 - - fdir@6.5.0(picomatch@4.0.3): - optionalDependencies: - picomatch: 4.0.3 - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - get-tsconfig@4.13.6: - dependencies: - resolve-pkg-maps: 1.0.0 - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - - hookable@5.5.3: {} - - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - - is-core-module@2.16.1: - dependencies: - hasown: 2.0.2 - - is-extglob@2.1.1: {} - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-number@7.0.0: {} - - jiti@1.21.7: {} - - jiti@2.6.1: {} - - jsesc@3.1.0: {} - - lightningcss-android-arm64@1.32.0: - optional: true - - lightningcss-darwin-arm64@1.32.0: - optional: true - - lightningcss-darwin-x64@1.32.0: - optional: true - - lightningcss-freebsd-x64@1.32.0: - optional: true - - lightningcss-linux-arm-gnueabihf@1.32.0: - optional: true - - lightningcss-linux-arm64-gnu@1.32.0: - optional: true - - lightningcss-linux-arm64-musl@1.32.0: - optional: true - - lightningcss-linux-x64-gnu@1.32.0: - optional: true - - lightningcss-linux-x64-musl@1.32.0: - optional: true - - lightningcss-win32-arm64-msvc@1.32.0: - optional: true - - lightningcss-win32-x64-msvc@1.32.0: - optional: true - - lightningcss@1.32.0: - dependencies: - detect-libc: 2.1.2 - optionalDependencies: - lightningcss-android-arm64: 1.32.0 - lightningcss-darwin-arm64: 1.32.0 - lightningcss-darwin-x64: 1.32.0 - lightningcss-freebsd-x64: 1.32.0 - lightningcss-linux-arm-gnueabihf: 1.32.0 - lightningcss-linux-arm64-gnu: 1.32.0 - lightningcss-linux-arm64-musl: 1.32.0 - lightningcss-linux-x64-gnu: 1.32.0 - lightningcss-linux-x64-musl: 1.32.0 - lightningcss-win32-arm64-msvc: 1.32.0 - lightningcss-win32-x64-msvc: 1.32.0 - - lilconfig@3.1.3: {} - - lines-and-columns@1.2.4: {} - - magic-string@0.30.21: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - - merge2@1.4.1: {} - - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - - ms@2.1.3: {} - - mz@2.7.0: - dependencies: - any-promise: 1.3.0 - object-assign: 4.1.1 - thenify-all: 1.6.0 - - nanoid@3.3.11: {} - - normalize-path@3.0.0: {} - - object-assign@4.1.1: {} - - object-hash@3.0.0: {} - - obug@2.1.1: {} - - oxc-resolver@9.0.2: - optionalDependencies: - '@oxc-resolver/binding-darwin-arm64': 9.0.2 - '@oxc-resolver/binding-darwin-x64': 9.0.2 - '@oxc-resolver/binding-freebsd-x64': 9.0.2 - '@oxc-resolver/binding-linux-arm-gnueabihf': 9.0.2 - '@oxc-resolver/binding-linux-arm64-gnu': 9.0.2 - '@oxc-resolver/binding-linux-arm64-musl': 9.0.2 - '@oxc-resolver/binding-linux-riscv64-gnu': 9.0.2 - '@oxc-resolver/binding-linux-s390x-gnu': 9.0.2 - '@oxc-resolver/binding-linux-x64-gnu': 9.0.2 - '@oxc-resolver/binding-linux-x64-musl': 9.0.2 - '@oxc-resolver/binding-wasm32-wasi': 9.0.2 - '@oxc-resolver/binding-win32-arm64-msvc': 9.0.2 - '@oxc-resolver/binding-win32-x64-msvc': 9.0.2 - - oxc-transform@0.67.0: - optionalDependencies: - '@oxc-transform/binding-darwin-arm64': 0.67.0 - '@oxc-transform/binding-darwin-x64': 0.67.0 - '@oxc-transform/binding-linux-arm-gnueabihf': 0.67.0 - '@oxc-transform/binding-linux-arm64-gnu': 0.67.0 - '@oxc-transform/binding-linux-arm64-musl': 0.67.0 - '@oxc-transform/binding-linux-x64-gnu': 0.67.0 - '@oxc-transform/binding-linux-x64-musl': 0.67.0 - '@oxc-transform/binding-wasm32-wasi': 0.67.0 - '@oxc-transform/binding-win32-arm64-msvc': 0.67.0 - '@oxc-transform/binding-win32-x64-msvc': 0.67.0 - - path-parse@1.0.7: {} - - pathe@2.0.3: {} - - picocolors@1.1.1: {} - - picomatch@2.3.1: {} - - picomatch@4.0.3: {} - - pify@2.3.0: {} - - pirates@4.0.7: {} - - postcss-import@15.1.0(postcss@8.5.8): - dependencies: - postcss: 8.5.8 - postcss-value-parser: 4.2.0 - read-cache: 1.0.0 - resolve: 1.22.11 - - postcss-js@4.1.0(postcss@8.5.8): - dependencies: - camelcase-css: 2.0.1 - postcss: 8.5.8 - - postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.8): - dependencies: - lilconfig: 3.1.3 - optionalDependencies: - jiti: 1.21.7 - postcss: 8.5.8 - - postcss-nested@6.2.0(postcss@8.5.8): - dependencies: - postcss: 8.5.8 - postcss-selector-parser: 6.1.2 - - postcss-selector-parser@6.1.2: - dependencies: - cssesc: 3.0.0 - util-deprecate: 1.0.2 - - postcss-value-parser@4.2.0: {} - - postcss@8.5.8: - dependencies: - nanoid: 3.3.11 - picocolors: 1.1.1 - source-map-js: 1.2.1 - - prettier@3.8.1: {} - - quansync@1.0.0: {} - - queue-microtask@1.2.3: {} - - react-dom@19.2.4(react@19.2.4): - dependencies: - react: 19.2.4 - scheduler: 0.27.0 - - react@19.2.4: {} - - read-cache@1.0.0: - dependencies: - pify: 2.3.0 - - readdirp@3.6.0: - dependencies: - picomatch: 2.3.1 - - readdirp@4.1.2: {} - - resolve-pkg-maps@1.0.0: {} - - resolve@1.22.11: - dependencies: - is-core-module: 2.16.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - reusify@1.1.0: {} - - rolldown-plugin-dts@0.9.11(rolldown@1.0.0-beta.8-commit.151352b(typescript@5.9.3))(typescript@5.9.3): - dependencies: - '@babel/generator': 7.29.1 - '@babel/parser': 7.29.2 - '@babel/types': 7.29.0 - ast-kit: 1.4.3 - debug: 4.4.3 - dts-resolver: 1.2.0 - get-tsconfig: 4.13.6 - oxc-transform: 0.67.0 - rolldown: 1.0.0-beta.8-commit.151352b(typescript@5.9.3) - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - rolldown@1.0.0-beta.8-commit.151352b(typescript@5.9.3): - dependencies: - '@oxc-project/types': 0.66.0 - '@valibot/to-json-schema': 1.0.0(valibot@1.0.0(typescript@5.9.3)) - ansis: 3.17.0 - valibot: 1.0.0(typescript@5.9.3) - optionalDependencies: - '@rolldown/binding-darwin-arm64': 1.0.0-beta.8-commit.151352b - '@rolldown/binding-darwin-x64': 1.0.0-beta.8-commit.151352b - '@rolldown/binding-freebsd-x64': 1.0.0-beta.8-commit.151352b - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.8-commit.151352b - '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.8-commit.151352b - '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.8-commit.151352b - '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.8-commit.151352b - '@rolldown/binding-linux-x64-musl': 1.0.0-beta.8-commit.151352b - '@rolldown/binding-wasm32-wasi': 1.0.0-beta.8-commit.151352b - '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.8-commit.151352b - '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.8-commit.151352b - '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.8-commit.151352b - transitivePeerDependencies: - - typescript - - rolldown@1.0.0-rc.10: - dependencies: - '@oxc-project/types': 0.120.0 - '@rolldown/pluginutils': 1.0.0-rc.10 - optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-rc.10 - '@rolldown/binding-darwin-arm64': 1.0.0-rc.10 - '@rolldown/binding-darwin-x64': 1.0.0-rc.10 - '@rolldown/binding-freebsd-x64': 1.0.0-rc.10 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.10 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.10 - '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.10 - '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.10 - '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.10 - '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.10 - '@rolldown/binding-linux-x64-musl': 1.0.0-rc.10 - '@rolldown/binding-openharmony-arm64': 1.0.0-rc.10 - '@rolldown/binding-wasm32-wasi': 1.0.0-rc.10 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.10 - '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.10 - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - scheduler@0.27.0: {} - - siginfo@2.0.0: {} - - source-map-js@1.2.1: {} - - stackback@0.0.2: {} - - std-env@4.0.0: {} - - sucrase@3.35.1: - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - commander: 4.1.1 - lines-and-columns: 1.2.4 - mz: 2.7.0 - pirates: 4.0.7 - tinyglobby: 0.2.15 - ts-interface-checker: 0.1.13 - - supports-preserve-symlinks-flag@1.0.0: {} - - tailwind-merge@3.5.0: {} - - tailwindcss@3.4.19: - dependencies: - '@alloc/quick-lru': 5.2.0 - arg: 5.0.2 - chokidar: 3.6.0 - didyoumean: 1.2.2 - dlv: 1.1.3 - fast-glob: 3.3.3 - glob-parent: 6.0.2 - is-glob: 4.0.3 - jiti: 1.21.7 - lilconfig: 3.1.3 - micromatch: 4.0.8 - normalize-path: 3.0.0 - object-hash: 3.0.0 - picocolors: 1.1.1 - postcss: 8.5.8 - postcss-import: 15.1.0(postcss@8.5.8) - postcss-js: 4.1.0(postcss@8.5.8) - postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.8) - postcss-nested: 6.2.0(postcss@8.5.8) - postcss-selector-parser: 6.1.2 - resolve: 1.22.11 - sucrase: 3.35.1 - transitivePeerDependencies: - - tsx - - yaml - - thenify-all@1.6.0: - dependencies: - thenify: 3.3.1 - - thenify@3.3.1: - dependencies: - any-promise: 1.3.0 - - tinybench@2.9.0: {} - - tinyexec@1.0.4: {} - - tinyglobby@0.2.15: - dependencies: - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - - tinyrainbow@3.1.0: {} - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - ts-interface-checker@0.1.13: {} - - tsdown@0.9.9(typescript@5.9.3): - dependencies: - ansis: 3.17.0 - cac: 6.7.14 - chokidar: 4.0.3 - consola: 3.4.2 - debug: 4.4.3 - diff: 7.0.0 - empathic: 1.1.0 - hookable: 5.5.3 - lightningcss: 1.32.0 - rolldown: 1.0.0-beta.8-commit.151352b(typescript@5.9.3) - rolldown-plugin-dts: 0.9.11(rolldown@1.0.0-beta.8-commit.151352b(typescript@5.9.3))(typescript@5.9.3) - tinyexec: 1.0.4 - tinyglobby: 0.2.15 - unconfig: 7.5.0 - unplugin-lightningcss: 0.3.3 - transitivePeerDependencies: - - '@oxc-project/runtime' - - supports-color - - typescript - - tslib@2.8.1: - optional: true - - typescript@5.9.3: {} - - unconfig-core@7.5.0: - dependencies: - '@quansync/fs': 1.0.0 - quansync: 1.0.0 - - unconfig@7.5.0: - dependencies: - '@quansync/fs': 1.0.0 - defu: 6.1.4 - jiti: 2.6.1 - quansync: 1.0.0 - unconfig-core: 7.5.0 - - undici-types@6.21.0: {} - - unplugin-lightningcss@0.3.3: - dependencies: - lightningcss: 1.32.0 - magic-string: 0.30.21 - unplugin: 2.3.11 - - unplugin@2.3.11: - dependencies: - '@jridgewell/remapping': 2.3.5 - acorn: 8.16.0 - picomatch: 4.0.3 - webpack-virtual-modules: 0.6.2 - - util-deprecate@1.0.2: {} - - valibot@1.0.0(typescript@5.9.3): - optionalDependencies: - typescript: 5.9.3 - - vite@8.0.1(@types/node@22.19.15)(jiti@1.21.7): - dependencies: - lightningcss: 1.32.0 - picomatch: 4.0.3 - postcss: 8.5.8 - rolldown: 1.0.0-rc.10 - tinyglobby: 0.2.15 - optionalDependencies: - '@types/node': 22.19.15 - fsevents: 2.3.3 - jiti: 1.21.7 - - vitest@4.1.0(@types/node@22.19.15)(vite@8.0.1(@types/node@22.19.15)(jiti@1.21.7)): - dependencies: - '@vitest/expect': 4.1.0 - '@vitest/mocker': 4.1.0(vite@8.0.1(@types/node@22.19.15)(jiti@1.21.7)) - '@vitest/pretty-format': 4.1.0 - '@vitest/runner': 4.1.0 - '@vitest/snapshot': 4.1.0 - '@vitest/spy': 4.1.0 - '@vitest/utils': 4.1.0 - es-module-lexer: 2.0.0 - expect-type: 1.3.0 - magic-string: 0.30.21 - obug: 2.1.1 - pathe: 2.0.3 - picomatch: 4.0.3 - std-env: 4.0.0 - tinybench: 2.9.0 - tinyexec: 1.0.4 - tinyglobby: 0.2.15 - tinyrainbow: 3.1.0 - vite: 8.0.1(@types/node@22.19.15)(jiti@1.21.7) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 22.19.15 - transitivePeerDependencies: - - msw - - webpack-virtual-modules@0.6.2: {} - - why-is-node-running@2.3.0: - dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 diff --git a/integrations/chat-ui/src/index.ts b/integrations/chat-ui/src/index.ts deleted file mode 100644 index 3843d4bae..000000000 --- a/integrations/chat-ui/src/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -export { - SimpleAgentChat, - AgentChatMessage, - AgentChatPart, - useAgentChat, - serializeForApi, - tryFormatJson, -} from "./simple-agent-chat"; -export type { - SimpleAgentChatProps, - ChatMessage, - AssistantPart, - TextPart, - FunctionCallPart, - FunctionCallOutputPart, - UseAgentChatOptions, - UseAgentChatReturn, -} from "./simple-agent-chat"; diff --git a/integrations/chat-ui/tsconfig.json b/integrations/chat-ui/tsconfig.json deleted file mode 100644 index 6e98de79f..000000000 --- a/integrations/chat-ui/tsconfig.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "compilerOptions": { - "module": "ES2022", - "moduleResolution": "Bundler", - "target": "ES2022", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "outDir": "./dist", - "lib": ["ES2023", "DOM", "DOM.Iterable"], - "jsx": "react-jsx", - "baseUrl": ".", - "noEmit": true, - "isolatedModules": true, - "allowSyntheticDefaultImports": true, - "verbatimModuleSyntax": false - }, - "include": [ - "src/**/*" - ], - "exclude": [ - "node_modules", - "dist" - ] -} diff --git a/integrations/chat-ui/tsdown.config.ts b/integrations/chat-ui/tsdown.config.ts deleted file mode 100644 index 7372b5836..000000000 --- a/integrations/chat-ui/tsdown.config.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { defineConfig } from "tsdown"; - -export default defineConfig({ - entry: { - index: "./src/index.ts", - }, - format: ["esm", "cjs"], - fixedExtension: true, - dts: true, - outDir: "./dist", - target: "esnext", - clean: true, - sourcemap: true, - external: ["react", "react-dom", "react/jsx-runtime"], - platform: "browser", - treeshake: true, -}); diff --git a/integrations/chat-ui/vitest.config.ts b/integrations/chat-ui/vitest.config.ts deleted file mode 100644 index 8b312569e..000000000 --- a/integrations/chat-ui/vitest.config.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { defineConfig } from "vitest/config"; - -export default defineConfig({ - test: { - globals: true, - environment: "jsdom", - }, -}); From b074ca743df74d86a29938c605760e779d50299d Mon Sep 17 00:00:00 2001 From: Hubert Zub Date: Wed, 25 Mar 2026 10:23:47 +0100 Subject: [PATCH 09/16] Chat plugin Signed-off-by: Hubert Zub --- integrations/appkit-agent/README.md | 136 ++- integrations/appkit-agent/drizzle.config.ts | 7 + .../drizzle/0000_lying_bill_hollister.sql | 31 + .../drizzle/meta/0000_snapshot.json | 209 ++++ .../appkit-agent/drizzle/meta/_journal.json | 13 + integrations/appkit-agent/package.json | 22 +- integrations/appkit-agent/pnpm-lock.yaml | 1005 ++++++++++++++++- .../appkit-agent/src/agent-plugin/agent.ts | 2 + .../appkit-agent/src/chat-plugin/auth.ts | 299 +++++ .../appkit-agent/src/chat-plugin/chat-acl.ts | 28 + .../appkit-agent/src/chat-plugin/errors.ts | 25 + .../appkit-agent/src/chat-plugin/index.ts | 932 +++++++++++++++ .../src/chat-plugin/manifest.json | 9 + .../src/chat-plugin/message-meta.ts | 52 + .../appkit-agent/src/chat-plugin/migrate.ts | 34 + .../src/chat-plugin/persistence.ts | 240 ++++ .../appkit-agent/src/chat-plugin/provider.ts | 94 ++ .../appkit-agent/src/chat-plugin/schema.ts | 61 + .../appkit-agent/src/chat-plugin/session.ts | 52 + .../src/chat-plugin/stream-cache.ts | 178 +++ .../src/chat-plugin/stream-fallback.ts | 171 +++ .../appkit-agent/src/chat-plugin/types.ts | 69 ++ .../appkit-agent/src/chat-plugin/utils.ts | 35 + integrations/appkit-agent/src/index.ts | 8 + .../src/tests/chat-plugin/chat-acl.test.ts | 48 + .../src/tests/chat-plugin/errors.test.ts | 34 + .../tests/chat-plugin/message-meta.test.ts | 34 + .../src/tests/chat-plugin/migrate.test.ts | 34 + .../src/tests/chat-plugin/plugin.test.ts | 101 ++ .../tests/chat-plugin/stream-cache.test.ts | 69 ++ .../src/tests/chat-plugin/test-helpers.ts | 88 ++ .../src/tests/chat-plugin/utils.test.ts | 33 + integrations/appkit-agent/tsdown.config.ts | 3 + 33 files changed, 4121 insertions(+), 35 deletions(-) create mode 100644 integrations/appkit-agent/drizzle.config.ts create mode 100644 integrations/appkit-agent/drizzle/0000_lying_bill_hollister.sql create mode 100644 integrations/appkit-agent/drizzle/meta/0000_snapshot.json create mode 100644 integrations/appkit-agent/drizzle/meta/_journal.json create mode 100644 integrations/appkit-agent/src/chat-plugin/auth.ts create mode 100644 integrations/appkit-agent/src/chat-plugin/chat-acl.ts create mode 100644 integrations/appkit-agent/src/chat-plugin/errors.ts create mode 100644 integrations/appkit-agent/src/chat-plugin/index.ts create mode 100644 integrations/appkit-agent/src/chat-plugin/manifest.json create mode 100644 integrations/appkit-agent/src/chat-plugin/message-meta.ts create mode 100644 integrations/appkit-agent/src/chat-plugin/migrate.ts create mode 100644 integrations/appkit-agent/src/chat-plugin/persistence.ts create mode 100644 integrations/appkit-agent/src/chat-plugin/provider.ts create mode 100644 integrations/appkit-agent/src/chat-plugin/schema.ts create mode 100644 integrations/appkit-agent/src/chat-plugin/session.ts create mode 100644 integrations/appkit-agent/src/chat-plugin/stream-cache.ts create mode 100644 integrations/appkit-agent/src/chat-plugin/stream-fallback.ts create mode 100644 integrations/appkit-agent/src/chat-plugin/types.ts create mode 100644 integrations/appkit-agent/src/chat-plugin/utils.ts create mode 100644 integrations/appkit-agent/src/tests/chat-plugin/chat-acl.test.ts create mode 100644 integrations/appkit-agent/src/tests/chat-plugin/errors.test.ts create mode 100644 integrations/appkit-agent/src/tests/chat-plugin/message-meta.test.ts create mode 100644 integrations/appkit-agent/src/tests/chat-plugin/migrate.test.ts create mode 100644 integrations/appkit-agent/src/tests/chat-plugin/plugin.test.ts create mode 100644 integrations/appkit-agent/src/tests/chat-plugin/stream-cache.test.ts create mode 100644 integrations/appkit-agent/src/tests/chat-plugin/test-helpers.ts create mode 100644 integrations/appkit-agent/src/tests/chat-plugin/utils.test.ts diff --git a/integrations/appkit-agent/README.md b/integrations/appkit-agent/README.md index cda438758..16e59670b 100644 --- a/integrations/appkit-agent/README.md +++ b/integrations/appkit-agent/README.md @@ -1,9 +1,9 @@ # @databricks/appkit-agent -Agent plugin for [Databricks AppKit](https://github.com/databricks/appkit). You can define an agent using one of the following approaches: +Plugins for [Databricks AppKit](https://github.com/databricks/appkit): -1. Declaratively define an agent by specifying `model`, `tools,` and `instructions` -2. Implement a custom agent loop using **`AgentInterface`** — a contract for writing custom agent implementations that speak the OpenAI Responses API format (streaming + non-streaming). +- **Agent plugin** — define an AI agent declaratively (model + tools + instructions) or bring a custom `AgentInterface` implementation. Speaks the OpenAI Responses API format with streaming. +- **Chat plugin** — full-featured chat server with streaming, session management, optional PostgreSQL persistence, feedback via MLflow Traces, and stream resumption. ## Installation @@ -23,26 +23,52 @@ If you use hosted tools (Genie, Vector Search, custom/external MCP servers): npm install @langchain/mcp-adapters ``` +For chat persistence (optional — without it the chat plugin runs in ephemeral mode): + +```bash +npm install pg +``` + ## Quick Start +### Agent only + ```typescript import { createApp, server } from "@databricks/appkit"; import { agent } from "@databricks/appkit-agent"; const app = await createApp({ plugins: [ - server(), + server({ autoStart: true }), agent({ model: "databricks-claude-sonnet-4-5", systemPrompt: "You are a helpful assistant.", }), ], }); +``` -app.server.start(); +### Agent + Chat + +```typescript +import { createApp, server } from "@databricks/appkit"; +import { agent, chat } from "@databricks/appkit-agent"; + +await createApp({ + plugins: [ + server({ autoStart: true }), + agent({ + model: "databricks-claude-sonnet-4-5", + systemPrompt: "You are a helpful assistant.", + }), + chat({ + backend: "agent", + }), + ], +}); ``` -The plugin registers `POST /api/agent` which accepts the [OpenAI Responses API](https://platform.openai.com/docs/api-reference/responses) request format with SSE streaming. +The agent plugin registers `POST /api/agent` (OpenAI Responses API format with SSE streaming). The chat plugin registers routes under `/api/chat/` for streaming chat, history, feedback, and more. ## Environment Variables @@ -216,23 +242,105 @@ agent({ agentInstance: new MyAgent() }); The `StandardAgent` class (exported from this package) is the built-in implementation used when you pass `model` instead of `agentInstance`. It translates the underlying agent's stream events into Responses API format. +## Chat Plugin + +The chat plugin provides a streaming chat server that can be wired to the agent plugin or to a remote Databricks serving endpoint. + +### Configuration + +```typescript +import { chat } from "@databricks/appkit-agent"; + +chat({ + // Route chat through the local agent plugin + backend: "agent", + + // Or point to a remote proxy / serving endpoint: + // backend: { proxy: "http://localhost:8000/invocations" }, + // backend: { endpoint: "databricks-claude-sonnet-4-5" }, + + // Optional: PostgreSQL pool for persistent chat history + // pool: new Pool(), + + // Auto-create the ai_chatbot schema and tables on startup (default: false) + // autoMigrate: true, + + // Enable thumbs up/down feedback (default: !!process.env.MLFLOW_EXPERIMENT_ID) + // feedbackEnabled: true, + + // Custom session resolver (default: x-forwarded-user headers → SCIM → env) + // getSession: (req) => ({ user: { id: req.headers["x-user-id"] } }), +}); +``` + +### Persistence + +Without a `pool`, the chat plugin runs in **ephemeral mode** — conversations are not saved. To enable persistent chat history, pass a `pg.Pool`: + +```typescript +import { Pool } from "pg"; + +chat({ + backend: "agent", + pool: new Pool({ connectionString: "postgres://..." }), + autoMigrate: true, +}); +``` + +When `autoMigrate: true` is set, the plugin creates the `ai_chatbot` schema and tables (`Chat`, `Message`, `Vote`) on startup using [Drizzle migrations](https://orm.drizzle.team/docs/migrations). Migration SQL is generated from the Drizzle schema definition, so it stays in sync automatically. + +### Session Resolution + +In production on Databricks Apps, sessions are resolved from headers set by the platform proxy (`x-forwarded-user`, `x-forwarded-email`). In local development, the plugin falls back to the SCIM `/Me` API (if Databricks auth is configured) or `process.env.USER`. + +You can override this entirely with a custom `getSession` callback. + +### Feedback + +When feedback is enabled, thumbs up/down votes are submitted as assessments to the [MLflow Traces API](https://docs.databricks.com/en/mlflow/llm-tracing.html). Votes are also persisted in the database when a pool is configured. + +### Chat API Routes + +All routes are mounted under `/api/chat/`. + +| Method | Path | Auth | Description | +| -------- | ------------------------ | ------------ | ---------------------------------- | +| `GET` | `/config` | — | Feature flags (history, feedback) | +| `GET` | `/session` | — | Current user session | +| `GET` | `/history` | required | Paginated chat list | +| `GET` | `/messages/:id` | required+ACL | Messages for a chat | +| `DELETE` | `/messages/:id/trailing` | required | Delete messages after a given one | +| `POST` | `/feedback` | required | Submit thumbs up/down | +| `GET` | `/feedback/chat/:chatId` | required+ACL | Votes for a chat | +| `POST` | `/title` | required | Auto-generate title from message | +| `PATCH` | `/:id/visibility` | required+ACL | Toggle public/private | +| `GET` | `/:id/stream` | required | Resume an active stream | +| `GET` | `/:id` | required+ACL | Get single chat | +| `DELETE` | `/:id` | required+ACL | Delete a chat | +| `POST` | `/` | required | Main chat handler (streaming) | + ## API Reference ### Exports -| Export | Kind | Description | -| --------------------- | -------------- | -------------------------------------------------------- | -| `agent` | Plugin factory | Main entry point — call with config, pass to `createApp` | -| `StandardAgent` | Class | Built-in `AgentInterface` implementation | -| `createInvokeHandler` | Function | Express handler factory for the `/api/agent` endpoint | -| `isFunctionTool` | Function | Type guard for `FunctionTool` | -| `isHostedTool` | Function | Type guard for `HostedTool` | +| Export | Kind | Description | +| --------------------- | -------------- | ---------------------------------------------------------- | +| `agent` | Plugin factory | Agent plugin — call with config, pass to `createApp` | +| `chat` | Plugin factory | Chat plugin — call with config, pass to `createApp` | +| `ChatPlugin` | Class | Chat plugin class (for `ChatPlugin.staticAssetsPath`, etc) | +| `StandardAgent` | Class | Built-in `AgentInterface` implementation | +| `createInvokeHandler` | Function | Express handler factory for the `/api/agent` endpoint | +| `isFunctionTool` | Function | Type guard for `FunctionTool` | +| `isHostedTool` | Function | Type guard for `HostedTool` | ### Types | Type | Description | | --------------------- | ------------------------------------------------------------- | -| `IAgentConfig` | Plugin configuration options | +| `IAgentConfig` | Agent plugin configuration options | +| `ChatConfig` | Chat plugin configuration options | +| `ChatSession` | Session object with user info | +| `GetSession` | Custom session resolver function type | | `AgentInterface` | Contract for custom agent implementations | | `AgentTool` | Union of `FunctionTool \| HostedTool` | | `FunctionTool` | Local tool with JSON Schema parameters and `execute` handler | diff --git a/integrations/appkit-agent/drizzle.config.ts b/integrations/appkit-agent/drizzle.config.ts new file mode 100644 index 000000000..1af6cb8ca --- /dev/null +++ b/integrations/appkit-agent/drizzle.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "drizzle-kit"; + +export default defineConfig({ + schema: "./src/chat-plugin/schema.ts", + out: "./drizzle", + dialect: "postgresql", +}); diff --git a/integrations/appkit-agent/drizzle/0000_lying_bill_hollister.sql b/integrations/appkit-agent/drizzle/0000_lying_bill_hollister.sql new file mode 100644 index 000000000..af0bbacb1 --- /dev/null +++ b/integrations/appkit-agent/drizzle/0000_lying_bill_hollister.sql @@ -0,0 +1,31 @@ +CREATE SCHEMA IF NOT EXISTS "ai_chatbot"; +--> statement-breakpoint +CREATE TABLE "ai_chatbot"."Chat" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "createdAt" timestamp NOT NULL, + "title" text NOT NULL, + "userId" text NOT NULL, + "visibility" varchar DEFAULT 'private' NOT NULL, + "lastContext" jsonb +); +--> statement-breakpoint +CREATE TABLE "ai_chatbot"."Message" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "chatId" uuid NOT NULL, + "role" varchar NOT NULL, + "parts" json NOT NULL, + "attachments" json NOT NULL, + "createdAt" timestamp NOT NULL, + "traceId" text +); +--> statement-breakpoint +CREATE TABLE "ai_chatbot"."Vote" ( + "chatId" uuid NOT NULL, + "messageId" uuid NOT NULL, + "isUpvoted" boolean NOT NULL, + CONSTRAINT "Vote_chatId_messageId_pk" PRIMARY KEY("chatId","messageId") +); +--> statement-breakpoint +ALTER TABLE "ai_chatbot"."Message" ADD CONSTRAINT "Message_chatId_Chat_id_fk" FOREIGN KEY ("chatId") REFERENCES "ai_chatbot"."Chat"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "ai_chatbot"."Vote" ADD CONSTRAINT "Vote_chatId_Chat_id_fk" FOREIGN KEY ("chatId") REFERENCES "ai_chatbot"."Chat"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint +ALTER TABLE "ai_chatbot"."Vote" ADD CONSTRAINT "Vote_messageId_Message_id_fk" FOREIGN KEY ("messageId") REFERENCES "ai_chatbot"."Message"("id") ON DELETE no action ON UPDATE no action; \ No newline at end of file diff --git a/integrations/appkit-agent/drizzle/meta/0000_snapshot.json b/integrations/appkit-agent/drizzle/meta/0000_snapshot.json new file mode 100644 index 000000000..08e5b6733 --- /dev/null +++ b/integrations/appkit-agent/drizzle/meta/0000_snapshot.json @@ -0,0 +1,209 @@ +{ + "id": "e4170b9c-f66a-4ebf-bf8a-365378173224", + "prevId": "00000000-0000-0000-0000-000000000000", + "version": "7", + "dialect": "postgresql", + "tables": { + "ai_chatbot.Chat": { + "name": "Chat", + "schema": "ai_chatbot", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "visibility": { + "name": "visibility", + "type": "varchar", + "primaryKey": false, + "notNull": true, + "default": "'private'" + }, + "lastContext": { + "name": "lastContext", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "ai_chatbot.Message": { + "name": "Message", + "schema": "ai_chatbot", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "chatId": { + "name": "chatId", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "varchar", + "primaryKey": false, + "notNull": true + }, + "parts": { + "name": "parts", + "type": "json", + "primaryKey": false, + "notNull": true + }, + "attachments": { + "name": "attachments", + "type": "json", + "primaryKey": false, + "notNull": true + }, + "createdAt": { + "name": "createdAt", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "traceId": { + "name": "traceId", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "Message_chatId_Chat_id_fk": { + "name": "Message_chatId_Chat_id_fk", + "tableFrom": "Message", + "tableTo": "Chat", + "schemaTo": "ai_chatbot", + "columnsFrom": [ + "chatId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "ai_chatbot.Vote": { + "name": "Vote", + "schema": "ai_chatbot", + "columns": { + "chatId": { + "name": "chatId", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "messageId": { + "name": "messageId", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "isUpvoted": { + "name": "isUpvoted", + "type": "boolean", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "Vote_chatId_Chat_id_fk": { + "name": "Vote_chatId_Chat_id_fk", + "tableFrom": "Vote", + "tableTo": "Chat", + "schemaTo": "ai_chatbot", + "columnsFrom": [ + "chatId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "Vote_messageId_Message_id_fk": { + "name": "Vote_messageId_Message_id_fk", + "tableFrom": "Vote", + "tableTo": "Message", + "schemaTo": "ai_chatbot", + "columnsFrom": [ + "messageId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "Vote_chatId_messageId_pk": { + "name": "Vote_chatId_messageId_pk", + "columns": [ + "chatId", + "messageId" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/integrations/appkit-agent/drizzle/meta/_journal.json b/integrations/appkit-agent/drizzle/meta/_journal.json new file mode 100644 index 000000000..1552e4327 --- /dev/null +++ b/integrations/appkit-agent/drizzle/meta/_journal.json @@ -0,0 +1,13 @@ +{ + "version": "7", + "dialect": "postgresql", + "entries": [ + { + "idx": 0, + "version": "7", + "when": 1774365591071, + "tag": "0000_lying_bill_hollister", + "breakpoints": true + } + ] +} \ No newline at end of file diff --git a/integrations/appkit-agent/package.json b/integrations/appkit-agent/package.json index 19d9f3b9c..1c479d1ae 100644 --- a/integrations/appkit-agent/package.json +++ b/integrations/appkit-agent/package.json @@ -17,6 +17,16 @@ "default": "./dist/index.cjs" } }, + "./chat": { + "import": { + "types": "./dist/chat/index.d.mts", + "default": "./dist/chat/index.mjs" + }, + "require": { + "types": "./dist/chat/index.d.cts", + "default": "./dist/chat/index.cjs" + } + }, "./chat-ui/simple": { "import": { "types": "./dist/chat-ui/simple.d.mts", @@ -31,6 +41,7 @@ }, "files": [ "dist", + "drizzle", "README.md", "LICENSE", "NOTICE" @@ -47,7 +58,7 @@ "format:check": "prettier --check 'src/**/*.ts'" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" }, "peerDependencies": { "@databricks/appkit": ">=0.21.0", @@ -56,6 +67,7 @@ "@langchain/langgraph": ">=1.0.0", "@langchain/mcp-adapters": ">=1.0.0", "express": ">=4.0.0", + "pg": ">=8.0.0", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, @@ -72,6 +84,9 @@ "@langchain/mcp-adapters": { "optional": true }, + "pg": { + "optional": true + }, "react": { "optional": true }, @@ -80,9 +95,12 @@ } }, "dependencies": { + "@databricks/ai-sdk-provider": "^0.5.1", "@radix-ui/react-slot": "^1.2.4", + "ai": "^6.0.70", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "drizzle-orm": "^0.38.0", "tailwind-merge": "^3.4.0", "zod": "^4.3.5" }, @@ -91,8 +109,10 @@ "@langchain/core": "^1.1.8", "@types/express": "^4.17.25", "@types/node": "^22.0.0", + "@types/pg": "^8.16.0", "@types/react": "^19.0.0", "@types/react-dom": "^19.0.0", + "drizzle-kit": "^0.31.10", "prettier": "^3.0.0", "react": "^19.0.0", "react-dom": "^19.0.0", diff --git a/integrations/appkit-agent/pnpm-lock.yaml b/integrations/appkit-agent/pnpm-lock.yaml index 05115c994..42fe472a3 100644 --- a/integrations/appkit-agent/pnpm-lock.yaml +++ b/integrations/appkit-agent/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: .: dependencies: + '@databricks/ai-sdk-provider': + specifier: ^0.5.1 + version: 0.5.1(@ai-sdk/provider-utils@4.0.19(zod@4.3.6))(@ai-sdk/provider@3.0.8) '@databricks/langchainjs': specifier: '>=0.1.0' version: 0.1.0(@cfworker/json-schema@4.1.1)(@langchain/langgraph@1.2.4(@langchain/core@1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0) @@ -23,15 +26,24 @@ importers: '@radix-ui/react-slot': specifier: ^1.2.4 version: 1.2.4(@types/react@19.2.14)(react@19.2.4) + ai: + specifier: ^6.0.70 + version: 6.0.116(zod@4.3.6) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 clsx: specifier: ^2.1.1 version: 2.1.1 + drizzle-orm: + specifier: ^0.38.0 + version: 0.38.4(@opentelemetry/api@1.9.0)(@types/pg@8.18.0)(@types/react@19.2.14)(pg@8.20.0)(react@19.2.4) express: specifier: '>=4.0.0' version: 5.2.1 + pg: + specifier: '>=8.0.0' + version: 8.20.0 tailwind-merge: specifier: ^3.4.0 version: 3.5.0 @@ -41,7 +53,7 @@ importers: devDependencies: '@databricks/appkit': specifier: ^0.21.0 - version: 0.21.0(@opentelemetry/core@2.6.0(@opentelemetry/api@1.9.0))(@types/node@22.19.15)(jiti@1.21.7) + version: 0.21.0(@opentelemetry/core@2.6.0(@opentelemetry/api@1.9.0))(@types/node@22.19.15)(esbuild@0.27.4)(jiti@1.21.7)(tsx@4.21.0) '@langchain/core': specifier: ^1.1.8 version: 1.1.34(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.6.0(@opentelemetry/api@1.9.0))(ws@8.19.0) @@ -51,12 +63,18 @@ importers: '@types/node': specifier: ^22.0.0 version: 22.19.15 + '@types/pg': + specifier: ^8.16.0 + version: 8.18.0 '@types/react': specifier: ^19.0.0 version: 19.2.14 '@types/react-dom': specifier: ^19.0.0 version: 19.2.3(@types/react@19.2.14) + drizzle-kit: + specifier: ^0.31.10 + version: 0.31.10 prettier: specifier: ^3.0.0 version: 3.8.1 @@ -68,7 +86,7 @@ importers: version: 19.2.4(react@19.2.4) tailwindcss: specifier: ^3.4.0 - version: 3.4.19 + version: 3.4.19(tsx@4.21.0) tsdown: specifier: ^0.9.0 version: 0.9.9(typescript@5.9.3) @@ -77,7 +95,7 @@ importers: version: 5.9.3 vitest: specifier: ^4.0.18 - version: 4.1.0(@opentelemetry/api@1.9.0)(@types/node@22.19.15)(vite@8.0.0(@types/node@22.19.15)(jiti@1.21.7)) + version: 4.1.0(@opentelemetry/api@1.9.0)(@types/node@22.19.15)(vite@8.0.0(@types/node@22.19.15)(esbuild@0.27.4)(jiti@1.21.7)(tsx@4.21.0)) packages: @@ -200,6 +218,13 @@ packages: '@ai-sdk/provider': ^3.0.5 '@ai-sdk/provider-utils': ^4.0.10 + '@databricks/ai-sdk-provider@0.5.1': + resolution: {integrity: sha512-xzslYAHgpb8q5lS8N5s3Q+LzgCKSYE++G6TTp5FwpkA3I3238IyT9tJKxcKT2OzPtoMr8FlzUMHuf6noNWaFJA==} + engines: {node: '>=18.0.0'} + peerDependencies: + '@ai-sdk/provider': ^3.0.5 + '@ai-sdk/provider-utils': ^4.0.10 + '@databricks/appkit@0.21.0': resolution: {integrity: sha512-F6+P5mSxFsE5YbKwmcDbyphGkMTgHDtN4+JJYkhJqHFAEU2slEagkM0bDbGJ8LNZBO1TX1DjhFpDNKdkaaKIlA==} hasBin: true @@ -219,14 +244,469 @@ packages: resolution: {integrity: sha512-9c2RxWYoRDFupdt4ZnBc1IPE1XaXgN+/wyV4DVcEqOnIa31ep51OnwAD/3014BImfKdyXg32nmgrB9dwvB6+lg==} engines: {node: '>=22.0', npm: '>=10.0.0'} - '@emnapi/core@1.9.0': - resolution: {integrity: sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w==} + '@drizzle-team/brocli@0.10.2': + resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==} + + '@emnapi/core@1.9.0': + resolution: {integrity: sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w==} + + '@emnapi/runtime@1.9.0': + resolution: {integrity: sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw==} + + '@emnapi/wasi-threads@1.2.0': + resolution: {integrity: sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==} + + '@esbuild-kit/core-utils@3.3.2': + resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} + deprecated: 'Merged into tsx: https://tsx.is' + + '@esbuild-kit/esm-loader@2.6.5': + resolution: {integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==} + deprecated: 'Merged into tsx: https://tsx.is' + + '@esbuild/aix-ppc64@0.25.12': + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.27.4': + resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.18.20': + resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.25.12': + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.27.4': + resolution: {integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.18.20': + resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.25.12': + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.27.4': + resolution: {integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.18.20': + resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.25.12': + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.27.4': + resolution: {integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.18.20': + resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.25.12': + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.27.4': + resolution: {integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.18.20': + resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.12': + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.4': + resolution: {integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.18.20': + resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.25.12': + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.27.4': + resolution: {integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.18.20': + resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.12': + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.4': + resolution: {integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.18.20': + resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.25.12': + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.27.4': + resolution: {integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.18.20': + resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.25.12': + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.27.4': + resolution: {integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.18.20': + resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.25.12': + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.27.4': + resolution: {integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.18.20': + resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.25.12': + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.27.4': + resolution: {integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.18.20': + resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.25.12': + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.27.4': + resolution: {integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.18.20': + resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.25.12': + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.27.4': + resolution: {integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.18.20': + resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.12': + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.4': + resolution: {integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.18.20': + resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.25.12': + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.27.4': + resolution: {integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.18.20': + resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.25.12': + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.27.4': + resolution: {integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.12': + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-arm64@0.27.4': + resolution: {integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.18.20': + resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.12': + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.4': + resolution: {integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.12': + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-arm64@0.27.4': + resolution: {integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.18.20': + resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.12': + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.4': + resolution: {integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.12': + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/openharmony-arm64@0.27.4': + resolution: {integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.18.20': + resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.25.12': + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.27.4': + resolution: {integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.18.20': + resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.25.12': + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.27.4': + resolution: {integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.18.20': + resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.25.12': + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.27.4': + resolution: {integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.18.20': + resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] - '@emnapi/runtime@1.9.0': - resolution: {integrity: sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw==} + '@esbuild/win32-x64@0.25.12': + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] - '@emnapi/wasi-threads@1.2.0': - resolution: {integrity: sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==} + '@esbuild/win32-x64@0.27.4': + resolution: {integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] '@grpc/grpc-js@1.14.3': resolution: {integrity: sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==} @@ -1408,6 +1888,9 @@ packages: buffer-equal-constant-time@1.0.1: resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} @@ -1580,6 +2063,102 @@ packages: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} + drizzle-kit@0.31.10: + resolution: {integrity: sha512-7OZcmQUrdGI+DUNNsKBn1aW8qSoKuTH7d0mYgSP8bAzdFzKoovxEFnoGQp2dVs82EOJeYycqRtciopszwUf8bw==} + hasBin: true + + drizzle-orm@0.38.4: + resolution: {integrity: sha512-s7/5BpLKO+WJRHspvpqTydxFob8i1vo2rEx4pY6TGY7QSMuUfWUuzaY0DIpXCkgHOo37BaFC+SJQb99dDUXT3Q==} + peerDependencies: + '@aws-sdk/client-rds-data': '>=3' + '@cloudflare/workers-types': '>=4' + '@electric-sql/pglite': '>=0.2.0' + '@libsql/client': '>=0.10.0' + '@libsql/client-wasm': '>=0.10.0' + '@neondatabase/serverless': '>=0.10.0' + '@op-engineering/op-sqlite': '>=2' + '@opentelemetry/api': ^1.4.1 + '@planetscale/database': '>=1' + '@prisma/client': '*' + '@tidbcloud/serverless': '*' + '@types/better-sqlite3': '*' + '@types/pg': '*' + '@types/react': '>=18' + '@types/sql.js': '*' + '@vercel/postgres': '>=0.8.0' + '@xata.io/client': '*' + better-sqlite3: '>=7' + bun-types: '*' + expo-sqlite: '>=14.0.0' + knex: '*' + kysely: '*' + mysql2: '>=2' + pg: '>=8' + postgres: '>=3' + prisma: '*' + react: '>=18' + sql.js: '>=1' + sqlite3: '>=5' + peerDependenciesMeta: + '@aws-sdk/client-rds-data': + optional: true + '@cloudflare/workers-types': + optional: true + '@electric-sql/pglite': + optional: true + '@libsql/client': + optional: true + '@libsql/client-wasm': + optional: true + '@neondatabase/serverless': + optional: true + '@op-engineering/op-sqlite': + optional: true + '@opentelemetry/api': + optional: true + '@planetscale/database': + optional: true + '@prisma/client': + optional: true + '@tidbcloud/serverless': + optional: true + '@types/better-sqlite3': + optional: true + '@types/pg': + optional: true + '@types/react': + optional: true + '@types/sql.js': + optional: true + '@vercel/postgres': + optional: true + '@xata.io/client': + optional: true + better-sqlite3: + optional: true + bun-types: + optional: true + expo-sqlite: + optional: true + knex: + optional: true + kysely: + optional: true + mysql2: + optional: true + pg: + optional: true + postgres: + optional: true + prisma: + optional: true + react: + optional: true + sql.js: + optional: true + sqlite3: + optional: true + dts-resolver@1.2.0: resolution: {integrity: sha512-+xNF7raXYI1E3IFB+f3JqvoKYFI8R+1Mh9mpI75yNm3F5XuiC6ErEXe2Lqh9ach+4MQ1tOefzjxulhWGVclYbg==} engines: {node: '>=20.18.0'} @@ -1620,6 +2199,21 @@ packages: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} + esbuild@0.18.20: + resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} + engines: {node: '>=12'} + hasBin: true + + esbuild@0.25.12: + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + engines: {node: '>=18'} + hasBin: true + + esbuild@0.27.4: + resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -2509,6 +3103,13 @@ packages: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} @@ -2600,6 +3201,11 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} + engines: {node: '>=18.0.0'} + hasBin: true + type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} @@ -2912,7 +3518,13 @@ snapshots: '@ai-sdk/provider-utils': 4.0.19(zod@4.3.6) zod: 4.3.6 - '@databricks/appkit@0.21.0(@opentelemetry/core@2.6.0(@opentelemetry/api@1.9.0))(@types/node@22.19.15)(jiti@1.21.7)': + '@databricks/ai-sdk-provider@0.5.1(@ai-sdk/provider-utils@4.0.19(zod@4.3.6))(@ai-sdk/provider@3.0.8)': + dependencies: + '@ai-sdk/provider': 3.0.8 + '@ai-sdk/provider-utils': 4.0.19(zod@4.3.6) + zod: 4.3.6 + + '@databricks/appkit@0.21.0(@opentelemetry/core@2.6.0(@opentelemetry/api@1.9.0))(@types/node@22.19.15)(esbuild@0.27.4)(jiti@1.21.7)(tsx@4.21.0)': dependencies: '@ast-grep/napi': 0.37.0 '@clack/prompts': 1.1.0 @@ -2943,7 +3555,7 @@ snapshots: pg: 8.20.0 picocolors: 1.1.1 semver: 7.7.4 - vite: 8.0.0(@types/node@22.19.15)(jiti@1.21.7) + vite: 8.0.0(@types/node@22.19.15)(esbuild@0.27.4)(jiti@1.21.7)(tsx@4.21.0) ws: 8.19.0 transitivePeerDependencies: - '@opentelemetry/core' @@ -3012,6 +3624,8 @@ snapshots: transitivePeerDependencies: - supports-color + '@drizzle-team/brocli@0.10.2': {} + '@emnapi/core@1.9.0': dependencies: '@emnapi/wasi-threads': 1.2.0 @@ -3028,6 +3642,238 @@ snapshots: tslib: 2.8.1 optional: true + '@esbuild-kit/core-utils@3.3.2': + dependencies: + esbuild: 0.18.20 + source-map-support: 0.5.21 + + '@esbuild-kit/esm-loader@2.6.5': + dependencies: + '@esbuild-kit/core-utils': 3.3.2 + get-tsconfig: 4.13.6 + + '@esbuild/aix-ppc64@0.25.12': + optional: true + + '@esbuild/aix-ppc64@0.27.4': + optional: true + + '@esbuild/android-arm64@0.18.20': + optional: true + + '@esbuild/android-arm64@0.25.12': + optional: true + + '@esbuild/android-arm64@0.27.4': + optional: true + + '@esbuild/android-arm@0.18.20': + optional: true + + '@esbuild/android-arm@0.25.12': + optional: true + + '@esbuild/android-arm@0.27.4': + optional: true + + '@esbuild/android-x64@0.18.20': + optional: true + + '@esbuild/android-x64@0.25.12': + optional: true + + '@esbuild/android-x64@0.27.4': + optional: true + + '@esbuild/darwin-arm64@0.18.20': + optional: true + + '@esbuild/darwin-arm64@0.25.12': + optional: true + + '@esbuild/darwin-arm64@0.27.4': + optional: true + + '@esbuild/darwin-x64@0.18.20': + optional: true + + '@esbuild/darwin-x64@0.25.12': + optional: true + + '@esbuild/darwin-x64@0.27.4': + optional: true + + '@esbuild/freebsd-arm64@0.18.20': + optional: true + + '@esbuild/freebsd-arm64@0.25.12': + optional: true + + '@esbuild/freebsd-arm64@0.27.4': + optional: true + + '@esbuild/freebsd-x64@0.18.20': + optional: true + + '@esbuild/freebsd-x64@0.25.12': + optional: true + + '@esbuild/freebsd-x64@0.27.4': + optional: true + + '@esbuild/linux-arm64@0.18.20': + optional: true + + '@esbuild/linux-arm64@0.25.12': + optional: true + + '@esbuild/linux-arm64@0.27.4': + optional: true + + '@esbuild/linux-arm@0.18.20': + optional: true + + '@esbuild/linux-arm@0.25.12': + optional: true + + '@esbuild/linux-arm@0.27.4': + optional: true + + '@esbuild/linux-ia32@0.18.20': + optional: true + + '@esbuild/linux-ia32@0.25.12': + optional: true + + '@esbuild/linux-ia32@0.27.4': + optional: true + + '@esbuild/linux-loong64@0.18.20': + optional: true + + '@esbuild/linux-loong64@0.25.12': + optional: true + + '@esbuild/linux-loong64@0.27.4': + optional: true + + '@esbuild/linux-mips64el@0.18.20': + optional: true + + '@esbuild/linux-mips64el@0.25.12': + optional: true + + '@esbuild/linux-mips64el@0.27.4': + optional: true + + '@esbuild/linux-ppc64@0.18.20': + optional: true + + '@esbuild/linux-ppc64@0.25.12': + optional: true + + '@esbuild/linux-ppc64@0.27.4': + optional: true + + '@esbuild/linux-riscv64@0.18.20': + optional: true + + '@esbuild/linux-riscv64@0.25.12': + optional: true + + '@esbuild/linux-riscv64@0.27.4': + optional: true + + '@esbuild/linux-s390x@0.18.20': + optional: true + + '@esbuild/linux-s390x@0.25.12': + optional: true + + '@esbuild/linux-s390x@0.27.4': + optional: true + + '@esbuild/linux-x64@0.18.20': + optional: true + + '@esbuild/linux-x64@0.25.12': + optional: true + + '@esbuild/linux-x64@0.27.4': + optional: true + + '@esbuild/netbsd-arm64@0.25.12': + optional: true + + '@esbuild/netbsd-arm64@0.27.4': + optional: true + + '@esbuild/netbsd-x64@0.18.20': + optional: true + + '@esbuild/netbsd-x64@0.25.12': + optional: true + + '@esbuild/netbsd-x64@0.27.4': + optional: true + + '@esbuild/openbsd-arm64@0.25.12': + optional: true + + '@esbuild/openbsd-arm64@0.27.4': + optional: true + + '@esbuild/openbsd-x64@0.18.20': + optional: true + + '@esbuild/openbsd-x64@0.25.12': + optional: true + + '@esbuild/openbsd-x64@0.27.4': + optional: true + + '@esbuild/openharmony-arm64@0.25.12': + optional: true + + '@esbuild/openharmony-arm64@0.27.4': + optional: true + + '@esbuild/sunos-x64@0.18.20': + optional: true + + '@esbuild/sunos-x64@0.25.12': + optional: true + + '@esbuild/sunos-x64@0.27.4': + optional: true + + '@esbuild/win32-arm64@0.18.20': + optional: true + + '@esbuild/win32-arm64@0.25.12': + optional: true + + '@esbuild/win32-arm64@0.27.4': + optional: true + + '@esbuild/win32-ia32@0.18.20': + optional: true + + '@esbuild/win32-ia32@0.25.12': + optional: true + + '@esbuild/win32-ia32@0.27.4': + optional: true + + '@esbuild/win32-x64@0.18.20': + optional: true + + '@esbuild/win32-x64@0.25.12': + optional: true + + '@esbuild/win32-x64@0.27.4': + optional: true + '@grpc/grpc-js@1.14.3': dependencies: '@grpc/proto-loader': 0.8.0 @@ -3156,6 +4002,8 @@ snapshots: '@napi-rs/wasm-runtime@0.2.12': dependencies: + '@emnapi/core': 1.9.0 + '@emnapi/runtime': 1.9.0 '@tybys/wasm-util': 0.10.1 optional: true @@ -4214,13 +5062,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.0(vite@8.0.0(@types/node@22.19.15)(jiti@1.21.7))': + '@vitest/mocker@4.1.0(vite@8.0.0(@types/node@22.19.15)(esbuild@0.27.4)(jiti@1.21.7)(tsx@4.21.0))': dependencies: '@vitest/spy': 4.1.0 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.0.0(@types/node@22.19.15)(jiti@1.21.7) + vite: 8.0.0(@types/node@22.19.15)(esbuild@0.27.4)(jiti@1.21.7)(tsx@4.21.0) '@vitest/pretty-format@4.1.0': dependencies: @@ -4354,6 +5202,8 @@ snapshots: buffer-equal-constant-time@1.0.1: {} + buffer-from@1.1.2: {} + bytes@3.1.2: {} cac@6.7.14: {} @@ -4481,6 +5331,21 @@ snapshots: dotenv@16.6.1: {} + drizzle-kit@0.31.10: + dependencies: + '@drizzle-team/brocli': 0.10.2 + '@esbuild-kit/esm-loader': 2.6.5 + esbuild: 0.25.12 + tsx: 4.21.0 + + drizzle-orm@0.38.4(@opentelemetry/api@1.9.0)(@types/pg@8.18.0)(@types/react@19.2.14)(pg@8.20.0)(react@19.2.4): + optionalDependencies: + '@opentelemetry/api': 1.9.0 + '@types/pg': 8.18.0 + '@types/react': 19.2.14 + pg: 8.20.0 + react: 19.2.4 + dts-resolver@1.2.0: dependencies: oxc-resolver: 9.0.2 @@ -4514,6 +5379,89 @@ snapshots: dependencies: es-errors: 1.3.0 + esbuild@0.18.20: + optionalDependencies: + '@esbuild/android-arm': 0.18.20 + '@esbuild/android-arm64': 0.18.20 + '@esbuild/android-x64': 0.18.20 + '@esbuild/darwin-arm64': 0.18.20 + '@esbuild/darwin-x64': 0.18.20 + '@esbuild/freebsd-arm64': 0.18.20 + '@esbuild/freebsd-x64': 0.18.20 + '@esbuild/linux-arm': 0.18.20 + '@esbuild/linux-arm64': 0.18.20 + '@esbuild/linux-ia32': 0.18.20 + '@esbuild/linux-loong64': 0.18.20 + '@esbuild/linux-mips64el': 0.18.20 + '@esbuild/linux-ppc64': 0.18.20 + '@esbuild/linux-riscv64': 0.18.20 + '@esbuild/linux-s390x': 0.18.20 + '@esbuild/linux-x64': 0.18.20 + '@esbuild/netbsd-x64': 0.18.20 + '@esbuild/openbsd-x64': 0.18.20 + '@esbuild/sunos-x64': 0.18.20 + '@esbuild/win32-arm64': 0.18.20 + '@esbuild/win32-ia32': 0.18.20 + '@esbuild/win32-x64': 0.18.20 + + esbuild@0.25.12: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.12 + '@esbuild/android-arm': 0.25.12 + '@esbuild/android-arm64': 0.25.12 + '@esbuild/android-x64': 0.25.12 + '@esbuild/darwin-arm64': 0.25.12 + '@esbuild/darwin-x64': 0.25.12 + '@esbuild/freebsd-arm64': 0.25.12 + '@esbuild/freebsd-x64': 0.25.12 + '@esbuild/linux-arm': 0.25.12 + '@esbuild/linux-arm64': 0.25.12 + '@esbuild/linux-ia32': 0.25.12 + '@esbuild/linux-loong64': 0.25.12 + '@esbuild/linux-mips64el': 0.25.12 + '@esbuild/linux-ppc64': 0.25.12 + '@esbuild/linux-riscv64': 0.25.12 + '@esbuild/linux-s390x': 0.25.12 + '@esbuild/linux-x64': 0.25.12 + '@esbuild/netbsd-arm64': 0.25.12 + '@esbuild/netbsd-x64': 0.25.12 + '@esbuild/openbsd-arm64': 0.25.12 + '@esbuild/openbsd-x64': 0.25.12 + '@esbuild/openharmony-arm64': 0.25.12 + '@esbuild/sunos-x64': 0.25.12 + '@esbuild/win32-arm64': 0.25.12 + '@esbuild/win32-ia32': 0.25.12 + '@esbuild/win32-x64': 0.25.12 + + esbuild@0.27.4: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.4 + '@esbuild/android-arm': 0.27.4 + '@esbuild/android-arm64': 0.27.4 + '@esbuild/android-x64': 0.27.4 + '@esbuild/darwin-arm64': 0.27.4 + '@esbuild/darwin-x64': 0.27.4 + '@esbuild/freebsd-arm64': 0.27.4 + '@esbuild/freebsd-x64': 0.27.4 + '@esbuild/linux-arm': 0.27.4 + '@esbuild/linux-arm64': 0.27.4 + '@esbuild/linux-ia32': 0.27.4 + '@esbuild/linux-loong64': 0.27.4 + '@esbuild/linux-mips64el': 0.27.4 + '@esbuild/linux-ppc64': 0.27.4 + '@esbuild/linux-riscv64': 0.27.4 + '@esbuild/linux-s390x': 0.27.4 + '@esbuild/linux-x64': 0.27.4 + '@esbuild/netbsd-arm64': 0.27.4 + '@esbuild/netbsd-x64': 0.27.4 + '@esbuild/openbsd-arm64': 0.27.4 + '@esbuild/openbsd-x64': 0.27.4 + '@esbuild/openharmony-arm64': 0.27.4 + '@esbuild/sunos-x64': 0.27.4 + '@esbuild/win32-arm64': 0.27.4 + '@esbuild/win32-ia32': 0.27.4 + '@esbuild/win32-x64': 0.27.4 + escalade@3.2.0: {} escape-html@1.0.3: {} @@ -5156,12 +6104,13 @@ snapshots: camelcase-css: 2.0.1 postcss: 8.5.8 - postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.8): + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.8)(tsx@4.21.0): dependencies: lilconfig: 3.1.3 optionalDependencies: jiti: 1.21.7 postcss: 8.5.8 + tsx: 4.21.0 postcss-nested@6.2.0(postcss@8.5.8): dependencies: @@ -5458,6 +6407,13 @@ snapshots: source-map-js@1.2.1: {} + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + split2@4.2.0: {} stackback@0.0.2: {} @@ -5490,7 +6446,7 @@ snapshots: tailwind-merge@3.5.0: {} - tailwindcss@3.4.19: + tailwindcss@3.4.19(tsx@4.21.0): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -5509,7 +6465,7 @@ snapshots: postcss: 8.5.8 postcss-import: 15.1.0(postcss@8.5.8) postcss-js: 4.1.0(postcss@8.5.8) - postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.8) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.8)(tsx@4.21.0) postcss-nested: 6.2.0(postcss@8.5.8) postcss-selector-parser: 6.1.2 resolve: 1.22.11 @@ -5572,6 +6528,13 @@ snapshots: tslib@2.8.1: optional: true + tsx@4.21.0: + dependencies: + esbuild: 0.27.4 + get-tsconfig: 4.13.6 + optionalDependencies: + fsevents: 2.3.3 + type-is@1.6.18: dependencies: media-typer: 0.3.0 @@ -5633,7 +6596,7 @@ snapshots: vary@1.1.2: {} - vite@8.0.0(@types/node@22.19.15)(jiti@1.21.7): + vite@8.0.0(@types/node@22.19.15)(esbuild@0.27.4)(jiti@1.21.7)(tsx@4.21.0): dependencies: '@oxc-project/runtime': 0.115.0 lightningcss: 1.32.0 @@ -5643,13 +6606,15 @@ snapshots: tinyglobby: 0.2.15 optionalDependencies: '@types/node': 22.19.15 + esbuild: 0.27.4 fsevents: 2.3.3 jiti: 1.21.7 + tsx: 4.21.0 - vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@22.19.15)(vite@8.0.0(@types/node@22.19.15)(jiti@1.21.7)): + vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@22.19.15)(vite@8.0.0(@types/node@22.19.15)(esbuild@0.27.4)(jiti@1.21.7)(tsx@4.21.0)): dependencies: '@vitest/expect': 4.1.0 - '@vitest/mocker': 4.1.0(vite@8.0.0(@types/node@22.19.15)(jiti@1.21.7)) + '@vitest/mocker': 4.1.0(vite@8.0.0(@types/node@22.19.15)(esbuild@0.27.4)(jiti@1.21.7)(tsx@4.21.0)) '@vitest/pretty-format': 4.1.0 '@vitest/runner': 4.1.0 '@vitest/snapshot': 4.1.0 @@ -5666,7 +6631,7 @@ snapshots: tinyexec: 1.0.4 tinyglobby: 0.2.15 tinyrainbow: 3.1.0 - vite: 8.0.0(@types/node@22.19.15)(jiti@1.21.7) + vite: 8.0.0(@types/node@22.19.15)(esbuild@0.27.4)(jiti@1.21.7)(tsx@4.21.0) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.0 diff --git a/integrations/appkit-agent/src/agent-plugin/agent.ts b/integrations/appkit-agent/src/agent-plugin/agent.ts index d6e9234cc..7d2417e3d 100644 --- a/integrations/appkit-agent/src/agent-plugin/agent.ts +++ b/integrations/appkit-agent/src/agent-plugin/agent.ts @@ -234,6 +234,8 @@ export class AgentPlugin extends Plugin { exports() { return { + endpointPath: `/api/${this.name}`, + invoke: async ( messages: { role: string; content: string }[], ): Promise => { diff --git a/integrations/appkit-agent/src/chat-plugin/auth.ts b/integrations/appkit-agent/src/chat-plugin/auth.ts new file mode 100644 index 000000000..7401b757f --- /dev/null +++ b/integrations/appkit-agent/src/chat-plugin/auth.ts @@ -0,0 +1,299 @@ +/** + * Consolidated Databricks authentication module. + * + * Supported auth methods (checked in priority order): + * 1. PAT — DATABRICKS_TOKEN env var + * 2. OAuth (SP) — DATABRICKS_CLIENT_ID + DATABRICKS_CLIENT_SECRET + DATABRICKS_HOST + * 3. CLI (OAuth U2M)— DATABRICKS_CONFIG_PROFILE or DATABRICKS_HOST + * (requires `databricks auth login`) + */ + +import { execFile } from "node:child_process"; + +// ── Types ────────────────────────────────────────────────────────── + +export type AuthMethod = "pat" | "oauth" | "cli" | "none"; + +export interface ScimUser { + id: string; + email: string; + name?: string; + preferredUsername?: string; +} + +// ── Caches ───────────────────────────────────────────────────────── + +let oauthToken: string | null = null; +let oauthTokenExpiresAt = 0; + +let cliToken: string | null = null; +let cliTokenExpiresAt = 0; + +let cachedCliHost: string | null = null; +let cliHostTime = 0; +const CLI_HOST_CACHE_MS = 10 * 60 * 1000; + +let cachedScimUser: ScimUser | null = null; +let scimCacheExpiry = 0; +const SCIM_CACHE_MS = 30 * 60 * 1000; + +// ── Auth method detection ────────────────────────────────────────── + +export function getAuthMethod(): AuthMethod { + if (process.env.DATABRICKS_TOKEN) return "pat"; + if ( + process.env.DATABRICKS_CLIENT_ID && + process.env.DATABRICKS_CLIENT_SECRET && + process.env.DATABRICKS_HOST + ) { + return "oauth"; + } + if (process.env.DATABRICKS_CONFIG_PROFILE || process.env.DATABRICKS_HOST) { + return "cli"; + } + return "none"; +} + +// ── Host resolution ──────────────────────────────────────────────── + +function normalizeHost(host: string): string { + return host.replace(/^https?:\/\//, "").replace(/\/$/, ""); +} + +/** + * Get the Databricks workspace URL (`https://…`). + * + * Resolution order: + * 1. `DATABRICKS_HOST` env var + * 2. Host cached from a previous CLI call + * 3. `databricks auth describe` (derives host from profile) + */ +export async function getHostUrl(): Promise { + const envHost = process.env.DATABRICKS_HOST; + if (envHost) { + return `https://${normalizeHost(envHost)}`; + } + + if (cachedCliHost && Date.now() < cliHostTime + CLI_HOST_CACHE_MS) { + return `https://${normalizeHost(cachedCliHost)}`; + } + + const profile = process.env.DATABRICKS_CONFIG_PROFILE; + if (!profile) { + throw new Error( + "Chat plugin: set DATABRICKS_HOST or DATABRICKS_CONFIG_PROFILE.", + ); + } + + const stdout = await runCli([ + "auth", + "describe", + "--output", + "json", + "--profile", + profile, + ]); + const data = JSON.parse(stdout) as { details?: { host?: string } }; + const host = data.details?.host; + if (!host) { + throw new Error( + "Could not resolve workspace host from `databricks auth describe`. " + + "Set DATABRICKS_HOST explicitly.", + ); + } + + cachedCliHost = host; + cliHostTime = Date.now(); + return `https://${normalizeHost(host)}`; +} + +/** + * Get the workspace hostname without protocol. + */ +export async function getHostDomain(): Promise { + const url = await getHostUrl(); + return normalizeHost(url); +} + +// ── Token acquisition ────────────────────────────────────────────── + +/** + * Get a Databricks auth token using the best available method. + */ +export async function getToken(): Promise { + const method = getAuthMethod(); + switch (method) { + case "pat": + return process.env.DATABRICKS_TOKEN!; + case "oauth": + return getOAuthToken(); + case "cli": + return getCliToken(); + case "none": + throw new Error( + "No Databricks auth configured. Set one of:\n" + + " • DATABRICKS_TOKEN (PAT)\n" + + " • DATABRICKS_CLIENT_ID + DATABRICKS_CLIENT_SECRET + DATABRICKS_HOST (OAuth SP)\n" + + " • DATABRICKS_CONFIG_PROFILE or DATABRICKS_HOST (CLI — run `databricks auth login` first)", + ); + } +} + +/** + * OAuth client-credentials flow for service principals. + */ +async function getOAuthToken(): Promise { + if (oauthToken && Date.now() < oauthTokenExpiresAt) return oauthToken; + + const clientId = process.env.DATABRICKS_CLIENT_ID!; + const clientSecret = process.env.DATABRICKS_CLIENT_SECRET!; + const hostUrl = await getHostUrl(); + + const response = await fetch( + `${hostUrl}/oidc/v1/token`, + { + method: "POST", + headers: { + Authorization: `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString("base64")}`, + "Content-Type": "application/x-www-form-urlencoded", + }, + body: "grant_type=client_credentials&scope=all-apis", + }, + ); + + if (!response.ok) { + const text = await response.text(); + throw new Error(`OAuth token request failed: ${response.status} ${text}`); + } + + const data = (await response.json()) as { + access_token: string; + expires_in?: number; + }; + if (!data.access_token) { + throw new Error("No access_token in OAuth response"); + } + + oauthToken = data.access_token; + const expiresIn = data.expires_in ?? 3600; + const buffer = Math.min(600, Math.floor(expiresIn * 0.2)); + oauthTokenExpiresAt = Date.now() + (expiresIn - buffer) * 1000; + + return oauthToken; +} + +/** + * CLI-based token acquisition (`databricks auth token`). + * Supports OAuth U2M with automatic refresh. + */ +async function getCliToken(): Promise { + if (cliToken && Date.now() < cliTokenExpiresAt) return cliToken; + + const stdout = await runCli([ + "auth", + "token", + "--output", + "json", + ...cliProfileArgs(), + ]); + + const data = JSON.parse(stdout) as { + access_token?: string; + expiry?: string; + }; + if (!data.access_token) { + throw new Error("No access_token in `databricks auth token` output"); + } + + cliToken = data.access_token; + const bufferMs = 5 * 60 * 1000; + cliTokenExpiresAt = data.expiry + ? new Date(data.expiry).getTime() - bufferMs + : Date.now() + 55 * 60 * 1000; + + return cliToken; +} + +// ── SCIM (/Me) ───────────────────────────────────────────────────── + +/** + * Fetch the current user from the Databricks SCIM `/Me` endpoint. + * Useful in local development to resolve a real Databricks identity + * instead of falling back to the OS username. + * + * Returns `null` on any failure (network, auth, missing config). + */ +export async function getScimUser(): Promise { + if (cachedScimUser && Date.now() < scimCacheExpiry) return cachedScimUser; + + let token: string; + let host: string; + try { + token = await getToken(); + host = await getHostUrl(); + } catch { + return null; + } + + try { + const resp = await fetch(`${host}/api/2.0/preview/scim/v2/Me`, { + headers: { + Authorization: `Bearer ${token}`, + "Content-Type": "application/json", + }, + }); + + if (!resp.ok) return null; + + const data = (await resp.json()) as { + id?: string; + userName?: string; + displayName?: string; + emails?: Array<{ value: string; primary?: boolean }>; + }; + + const primaryEmail = + data.emails?.find((e) => e.primary)?.value ?? + data.emails?.[0]?.value ?? + (data.userName ? `${data.userName}@databricks.com` : undefined); + + cachedScimUser = { + id: data.id ?? data.userName ?? "unknown", + email: primaryEmail ?? `${data.userName ?? "user"}@databricks.com`, + name: data.displayName ?? data.userName, + preferredUsername: data.userName, + }; + scimCacheExpiry = Date.now() + SCIM_CACHE_MS; + return cachedScimUser; + } catch { + return null; + } +} + +// ── CLI helpers ──────────────────────────────────────────────────── + +function cliProfileArgs(): string[] { + const args: string[] = []; + const profile = process.env.DATABRICKS_CONFIG_PROFILE; + const host = process.env.DATABRICKS_HOST; + if (profile) args.push("--profile", profile); + if (host) args.push("--host", normalizeHost(host)); + return args; +} + +function runCli(args: string[]): Promise { + return new Promise((resolve, reject) => { + execFile("databricks", args, { timeout: 15_000 }, (err, stdout, stderr) => { + if (err) { + reject( + new Error( + `\`databricks ${args.slice(0, 2).join(" ")}\` failed: ${stderr || err.message}\n` + + 'Ensure the Databricks CLI is installed and you have run "databricks auth login".', + ), + ); + return; + } + resolve(stdout); + }); + }); +} diff --git a/integrations/appkit-agent/src/chat-plugin/chat-acl.ts b/integrations/appkit-agent/src/chat-plugin/chat-acl.ts new file mode 100644 index 000000000..f0ec7135b --- /dev/null +++ b/integrations/appkit-agent/src/chat-plugin/chat-acl.ts @@ -0,0 +1,28 @@ +import type { ChatRow } from "./schema"; + +export interface ChatAccessResult { + allowed: boolean; + chat: ChatRow | null; + reason?: "not_found" | "private_chat" | "forbidden"; +} + +export async function checkChatAccess( + getChat: (id: string) => Promise, + chatId: string, + userId?: string, +): Promise { + const chat = await getChat(chatId); + if (!chat) { + return { allowed: false, chat: null, reason: "not_found" }; + } + if (chat.visibility === "public") { + return { allowed: true, chat }; + } + if (chat.visibility === "private") { + if (chat.userId !== userId) { + return { allowed: false, chat, reason: "forbidden" }; + } + return { allowed: true, chat }; + } + return { allowed: true, chat }; +} diff --git a/integrations/appkit-agent/src/chat-plugin/errors.ts b/integrations/appkit-agent/src/chat-plugin/errors.ts new file mode 100644 index 000000000..06cb5bf57 --- /dev/null +++ b/integrations/appkit-agent/src/chat-plugin/errors.ts @@ -0,0 +1,25 @@ +export class ChatServerError extends Error { + constructor( + readonly code: string, + message?: string, + ) { + super(message ?? code); + this.name = "ChatServerError"; + } + + toResponse(): { status: number; json: { error: string; code: string } } { + const statusByCode: Record = { + "bad_request:api": 400, + "unauthorized:chat": 401, + "forbidden:chat": 403, + "not_found:database": 404, + "empty:stream": 404, + "offline:chat": 503, + "bad_request:database": 500, + }; + return { + status: statusByCode[this.code] ?? 500, + json: { error: this.message, code: this.code }, + }; + } +} diff --git a/integrations/appkit-agent/src/chat-plugin/index.ts b/integrations/appkit-agent/src/chat-plugin/index.ts new file mode 100644 index 000000000..a60ab12d4 --- /dev/null +++ b/integrations/appkit-agent/src/chat-plugin/index.ts @@ -0,0 +1,932 @@ +import { + convertToModelMessages, + createUIMessageStream, + generateText, + type LanguageModelUsage, + pipeUIMessageStreamToResponse, + streamText, +} from "ai"; +import type express from "express"; +import { Plugin, toPlugin, type PluginManifest } from "@databricks/appkit"; +import { createLogger } from "../logger"; +import { checkChatAccess } from "./chat-acl"; +import { ChatServerError } from "./errors"; +import manifest from "./manifest.json"; +import { + getAssessmentId, + getMessageMetadata, + storeAssessmentId, + storeMessageMeta, +} from "./message-meta"; +import { + createDb, + deleteChatById, + deleteMessagesAfter, + getChatById, + getChatsByUserId, + getMessageById, + getMessagesByChatId, + getVotesByChatId, + saveChat, + saveMessages, + updateChatLastContextById, + updateChatTitleById, + updateChatVisibilityById, + voteMessage, +} from "./persistence"; +import { getToken, getHostUrl } from "./auth"; +import { + CONTEXT_HEADER_CONVERSATION_ID, + CONTEXT_HEADER_USER_ID, + createChatProvider, +} from "./provider"; +import { resolveSession } from "./session"; +import { ensureSchema } from "./migrate"; +import { drainStreamToWriter, fallbackToGenerateText } from "./stream-fallback"; +import { StreamCache } from "./stream-cache"; +import { + type ChatConfig, + type PostRequestBody, + postRequestBodySchema, +} from "./types"; + +export type { ChatConfig } from "./types"; +export type { ChatSession, GetSession } from "./types"; + +import { + convertToUIMessages, + generateUUID, + truncatePreserveWords, +} from "./utils"; + +const logger = createLogger("chat"); + +/** Agent backend shape expected by `useAgentBackend`. */ +export type ChatAgentBackend = { + endpointPath: string; +}; + +type ChatMessage = NonNullable[number]; + +/** + * Convert ai's LanguageModelUsage to the nested V3 format expected by + * the chat history's lastContext column. + */ +function toV3Usage(usage: LanguageModelUsage) { + return { + inputTokens: { + total: usage.inputTokens, + noCache: undefined, + cacheRead: undefined, + cacheWrite: undefined, + }, + outputTokens: { + total: usage.outputTokens, + text: undefined, + reasoning: undefined, + }, + }; +} + +export class ChatPlugin extends Plugin { + public name = "chat" as const; + static manifest = manifest as PluginManifest<"chat">; + declare protected config: ChatConfig; + + private provider: ReturnType | null = null; + private streamCache: StreamCache | null = null; + private getChat: (id: string) => Promise = + async () => null; + private agentEndpointPath: string | null = null; + + /** + * Wire the agent plugin as the chat backend. When set, chat POST requests + * are routed through the agent's local HTTP endpoint using the same + * `streamText` path as a remote serving endpoint — no custom adapter needed. + */ + useAgentBackend(agent: ChatAgentBackend): void { + this.agentEndpointPath = agent.endpointPath; + logger.info("Chat backend set to local agent at %s", agent.endpointPath); + } + + async setup() { + this.provider = createChatProvider({ + apiProxy: this.config.apiProxy ?? process.env.API_PROXY, + }); + this.streamCache = new StreamCache(); + if (this.config.pool) { + if (this.config.autoMigrate) { + await ensureSchema(this.config.pool); + logger.info("Database schema ensured (autoMigrate)"); + } + const db = createDb(this.config.pool); + this.getChat = (id) => getChatById(db, id); + } + logger.info( + "Chat plugin initialized (persistence: %s)", + this.config.pool ? "enabled" : "ephemeral", + ); + } + + injectRoutes(router: express.Router) { + const pool = this.config.pool; + const db = pool ? createDb(pool) : null; + const getSessionFn = this.config.getSession; + const cache = this.streamCache!; + const prov = this.provider!; + + const requireAuth = async ( + req: express.Request, + res: express.Response, + next: express.NextFunction, + ) => { + const session = await resolveSession(req, getSessionFn); + if (!session?.user) { + const err = new ChatServerError("unauthorized:chat"); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } + (req as express.Request & { session?: typeof session }).session = session; + next(); + }; + + const requireChatAccess = (paramName: "id" | "chatId") => { + return async ( + req: express.Request, + res: express.Response, + next: express.NextFunction, + ) => { + const session = ( + req as express.Request & { + session?: Awaited>; + } + ).session; + const id = paramName === "id" ? req.params.id : req.params.chatId; + if (!id) { + const err = new ChatServerError("bad_request:api"); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } + const { allowed, reason } = await checkChatAccess( + this.getChat, + id, + session?.user?.id, + ); + if (!allowed && reason !== "not_found") { + const err = new ChatServerError("forbidden:chat", reason); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } + next(); + }; + }; + + // ── GET /config ────────────────────────────────────────────────────── + router.get("/config", (_req, res) => { + res.json({ + features: { + chatHistory: !!pool, + feedback: + this.config.feedbackEnabled ?? !!process.env.MLFLOW_EXPERIMENT_ID, + }, + }); + }); + this.registerEndpoint("config", `/api/${this.name}/config`); + + // ── GET /session ───────────────────────────────────────────────────── + router.get("/session", async (req, res) => { + const session = await resolveSession(req, getSessionFn); + if (!session?.user) { + return res.json({ user: null }); + } + res.json({ + user: { + id: session.user.id, + email: session.user.email, + name: session.user.name, + preferredUsername: session.user.preferredUsername, + }, + }); + }); + this.registerEndpoint("session", `/api/${this.name}/session`); + + // ── GET /history ───────────────────────────────────────────────────── + router.get("/history", requireAuth, async (req, res) => { + if (!pool) { + return res.status(204).end(); + } + const session = ( + req as express.Request & { + session?: Awaited>; + } + ).session; + if (!session?.user) return; + const limit = Number.parseInt((req.query.limit as string) || "10", 10); + const startingAfter = (req.query.starting_after as string) || null; + const endingBefore = (req.query.ending_before as string) || null; + if (startingAfter && endingBefore) { + const err = new ChatServerError( + "bad_request:api", + "Only one of starting_after or ending_before can be provided.", + ); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } + try { + const { chats, hasMore } = await getChatsByUserId(db!, { + id: session.user.id, + limit, + startingAfter, + endingBefore, + }); + return res.json({ chats, hasMore }); + } catch (e) { + logger.error("getChatsByUserId failed: %O", e); + const err = new ChatServerError("bad_request:database"); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } + }); + this.registerEndpoint("history", `/api/${this.name}/history`); + + // ── GET /messages/:id ──────────────────────────────────────────────── + router.get( + "/messages/:id", + requireAuth, + requireChatAccess("id"), + async (req, res) => { + const chatId = req.params.id; + if (!pool) return res.status(204).end(); + try { + const messages = await getMessagesByChatId(db!, chatId); + return res.json(messages); + } catch (e) { + logger.error("getMessagesByChatId failed: %O", e); + return res.status(500).json({ error: "Failed to get messages" }); + } + }, + ); + this.registerEndpoint("messages", `/api/${this.name}/messages/:id`); + + // ── DELETE /messages/:id/trailing ───────────────────────────────────── + router.delete("/messages/:id/trailing", requireAuth, async (req, res) => { + if (!pool) return res.status(204).end(); + const messageId = req.params.id; + const msg = await getMessageById(db!, messageId); + if (!msg) { + const err = new ChatServerError("not_found:database"); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } + const session = ( + req as express.Request & { + session?: Awaited>; + } + ).session; + const { allowed } = await checkChatAccess( + this.getChat, + msg.chatId, + session?.user?.id, + ); + if (!allowed) { + const err = new ChatServerError("forbidden:chat"); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } + await deleteMessagesAfter(db!, { + chatId: msg.chatId, + afterCreatedAt: msg.createdAt, + }); + return res.json({ success: true }); + }); + this.registerEndpoint( + "messagesTrailing", + `/api/${this.name}/messages/:id/trailing`, + ); + + // ── POST /feedback (with MLflow traces API integration) ────────────── + router.post("/feedback", requireAuth, async (req, res) => { + try { + const { messageId, feedbackType } = req.body; + if ( + !messageId || + (feedbackType !== "thumbs_up" && feedbackType !== "thumbs_down") + ) { + const err = new ChatServerError("bad_request:api"); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } + const session = ( + req as express.Request & { + session?: Awaited>; + } + ).session; + if (!session?.user) return; + + let traceId: string | null = null; + let chatId: string | undefined; + + if (pool) { + const msg = await getMessageById(db!, messageId); + if (msg) { + traceId = msg.traceId; + chatId = msg.chatId; + } + } + + if (!chatId) { + const metadata = getMessageMetadata(messageId); + if (!metadata) { + const err = new ChatServerError("not_found:database"); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } + traceId = metadata.traceId; + chatId = metadata.chatId; + } + + if (chatId) { + const { allowed } = await checkChatAccess( + this.getChat, + chatId, + session.user.id, + ); + if (!allowed) { + const err = new ChatServerError("forbidden:chat"); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } + } + + let mlflowAssessmentId: string | undefined; + + if (traceId) { + try { + const token = await getToken(); + const hostUrl = await getHostUrl(); + const userId = session.user.email ?? session.user.id; + const existingAssessmentId = getAssessmentId( + messageId, + session.user.id, + ); + + let mlflowResponse: Response; + if (existingAssessmentId) { + mlflowResponse = await fetch( + `${hostUrl}/api/3.0/mlflow/traces/${traceId}/assessments/${existingAssessmentId}`, + { + method: "PATCH", + headers: { + Authorization: `Bearer ${token}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + assessment: { + trace_id: traceId, + assessment_name: "user_feedback", + feedback: { value: feedbackType === "thumbs_up" }, + }, + update_mask: "feedback", + }), + }, + ); + } else { + mlflowResponse = await fetch( + `${hostUrl}/api/3.0/mlflow/traces/${traceId}/assessments`, + { + method: "POST", + headers: { + Authorization: `Bearer ${token}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + assessment: { + trace_id: traceId, + assessment_name: "user_feedback", + source: { source_type: "HUMAN", source_id: userId }, + feedback: { value: feedbackType === "thumbs_up" }, + }, + }), + }, + ); + } + + if (!mlflowResponse.ok) { + const errorText = await mlflowResponse.text(); + logger.error("MLflow feedback submission failed: %s", errorText); + return res + .status(mlflowResponse.status) + .json({ error: "Failed to submit feedback" }); + } + + const mlflowResult = (await mlflowResponse.json()) as { + assessment?: { assessment_id?: string }; + }; + mlflowAssessmentId = mlflowResult.assessment?.assessment_id; + if (mlflowAssessmentId) { + storeAssessmentId(messageId, session.user.id, mlflowAssessmentId); + } + } catch (error) { + logger.error("MLflow feedback error: %O", error); + const err = new ChatServerError("offline:chat"); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } + } + + if (pool && chatId) { + try { + await voteMessage(db!, { + chatId, + messageId, + isUpvoted: feedbackType === "thumbs_up", + }); + } catch (err) { + logger.warn("DB vote save failed: %O", err); + } + } + + return res.json({ success: true, mlflowAssessmentId }); + } catch (error) { + logger.error("Feedback error: %O", error); + const err = new ChatServerError("offline:chat"); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } + }); + this.registerEndpoint("feedback", `/api/${this.name}/feedback`); + + // ── GET /feedback/chat/:chatId ─────────────────────────────────────── + router.get( + "/feedback/chat/:chatId", + requireAuth, + requireChatAccess("chatId"), + async (req, res) => { + if (!pool) return res.json({}); + const votes = await getVotesByChatId(db!, req.params.chatId); + const map: Record< + string, + { + messageId: string; + feedbackType: "thumbs_up" | "thumbs_down"; + assessmentId: null; + } + > = {}; + for (const v of votes) { + map[v.messageId] = { + messageId: v.messageId, + feedbackType: v.isUpvoted ? "thumbs_up" : "thumbs_down", + assessmentId: null, + }; + } + return res.json(map); + }, + ); + this.registerEndpoint( + "feedbackByChat", + `/api/${this.name}/feedback/chat/:chatId`, + ); + + // ── POST /title ────────────────────────────────────────────────────── + router.post("/title", requireAuth, async (req, res) => { + try { + const { message } = req.body; + const model = await prov.languageModel("title-model"); + const truncated = + message?.parts?.map((p: { type: string; text?: string }) => + p.type === "text" + ? { ...p, text: (p.text ?? "").slice(0, 256) } + : p, + ) ?? []; + const { text: title } = await generateText({ + model, + system: `Generate a short title (max 80 chars) for the user's first message. No quotes or colons.`, + prompt: JSON.stringify({ ...message, parts: truncated }), + }); + return res.json({ title: title ?? "New chat" }); + } catch (e) { + logger.error("generate title failed: %O", e); + return res.status(500).json({ error: "Failed to generate title" }); + } + }); + this.registerEndpoint("title", `/api/${this.name}/title`); + + // ── PATCH /:id/visibility ──────────────────────────────────────────── + router.patch( + "/:id/visibility", + requireAuth, + requireChatAccess("id"), + async (req, res) => { + const id = req.params.id; + const { visibility } = req.body; + if (!visibility || !["public", "private"].includes(visibility)) { + return res.status(400).json({ error: "Invalid visibility type" }); + } + if (!pool) return res.json({ success: true }); + await updateChatVisibilityById(db!, { chatId: id, visibility }); + return res.json({ success: true }); + }, + ); + this.registerEndpoint("visibility", `/api/${this.name}/:id/visibility`); + + // ── GET /:id/stream ────────────────────────────────────────────────── + router.get("/:id/stream", requireAuth, async (req, res) => { + const chatId = req.params.id; + const cursor = req.headers["x-resume-stream-cursor"] as + | string + | undefined; + const streamId = cache.getActiveStreamId(chatId); + if (!streamId) { + const err = new ChatServerError("empty:stream"); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } + const session = ( + req as express.Request & { + session?: Awaited>; + } + ).session; + const { allowed, reason } = await checkChatAccess( + this.getChat, + chatId, + session?.user?.id, + ); + if (!allowed && reason !== "not_found") { + const err = new ChatServerError("forbidden:chat", reason); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } + const stream = cache.getStream(streamId, { + cursor: cursor ? Number.parseInt(cursor, 10) : undefined, + }); + if (!stream) { + const err = new ChatServerError("empty:stream"); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } + res.setHeader("Content-Type", "text/event-stream"); + res.setHeader("Cache-Control", "no-cache"); + res.setHeader("Connection", "keep-alive"); + stream.pipe(res); + stream.on("error", (err) => { + logger.error("stream resume error: %O", err); + if (!res.headersSent) res.status(500).end(); + }); + }); + this.registerEndpoint("stream", `/api/${this.name}/:id/stream`); + + // ── GET /:id ───────────────────────────────────────────────────────── + router.get( + "/:id", + requireAuth, + requireChatAccess("id"), + async (req, res) => { + const id = req.params.id; + const row = await this.getChat(id); + if (!row) { + const err = new ChatServerError("not_found:database"); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } + return res.json(row); + }, + ); + this.registerEndpoint("getChat", `/api/${this.name}/:id`); + + // ── DELETE /:id ────────────────────────────────────────────────────── + router.delete( + "/:id", + requireAuth, + requireChatAccess("id"), + async (req, res) => { + const id = req.params.id; + if (pool) await deleteChatById(db!, id); + return res.status(200).json({}); + }, + ); + this.registerEndpoint("deleteChat", `/api/${this.name}/:id`); + + // ── POST / (main chat handler) ─────────────────────────────────────── + router.post("/", requireAuth, async (req, res) => { + let body: PostRequestBody; + try { + body = postRequestBodySchema.parse(req.body); + } catch { + const err = new ChatServerError("bad_request:api"); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } + + try { + const session = ( + req as express.Request & { + session?: Awaited>; + } + ).session; + if (!session?.user) return; + + const { + id, + message, + selectedChatModel, + selectedVisibilityType, + previousMessages = [], + } = body; + + const { allowed, reason } = await checkChatAccess( + this.getChat, + id, + session.user.id, + ); + if (reason !== "not_found" && !allowed) { + const err = new ChatServerError("forbidden:chat"); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } + + const dbAvailable = !!pool; + const messagesFromDb = dbAvailable + ? await getMessagesByChatId(db!, id) + : []; + const useClientMessages = + !dbAvailable || (!message && previousMessages.length > 0); + const previousMessagesResolved = useClientMessages + ? previousMessages + : convertToUIMessages(messagesFromDb); + + let titlePromise: Promise | undefined; + + const isNewChat = reason === "not_found"; + + let uiMessages: ChatMessage[]; + if (message) { + uiMessages = [...previousMessagesResolved, message] as ChatMessage[]; + if (dbAvailable) { + if (isNewChat) { + await saveChat(db!, { + id, + userId: session.user.id, + title: "New chat", + visibility: selectedVisibilityType, + }); + titlePromise = generateTitleFromUserMessage(prov, message) + .then(async (title) => { + await updateChatTitleById(db!, { chatId: id, title }); + return title; + }) + .catch(async (error) => { + logger.warn("title generation failed: %O", error); + const textPart = message.parts?.find( + (p: { type: string }) => p.type === "text", + ) as { text?: string } | undefined; + if (textPart?.text) { + const fallback = truncatePreserveWords( + textPart.text, + 128, + ); + await updateChatTitleById(db!, { + chatId: id, + title: fallback, + }); + return fallback; + } + return null; + }); + } + await saveMessages(db!, [ + { + id: message.id, + chatId: id, + role: "user", + parts: message.parts, + attachments: [], + createdAt: new Date(), + traceId: null, + }, + ]); + } + } else { + uiMessages = previousMessagesResolved as ChatMessage[]; + + if (dbAvailable && previousMessages.length > 0) { + const assistantMessages = previousMessages.filter( + (m: ChatMessage) => m.role === "assistant", + ); + if (assistantMessages.length > 0) { + await saveMessages( + db!, + assistantMessages.map((m: ChatMessage) => ({ + chatId: id, + id: m.id, + role: m.role, + parts: m.parts, + attachments: [], + createdAt: new Date(), + traceId: null, + })), + ); + } + + const hasMcpDenial = previousMessages.some( + (m: ChatMessage) => + Array.isArray(m.parts) && + m.parts.some( + (p: Record) => + p.type === "dynamic-tool" && + (p.state === "output-denied" || + (typeof p.approval === "object" && + p.approval !== null && + (p.approval as Record).approved === + false)), + ), + ); + + if (hasMcpDenial) { + res.end(); + return; + } + } + } + + cache.clearActiveStream(id); + const streamId = generateUUID(); + let finalUsage: LanguageModelUsage | undefined; + let traceId: string | null = null; + + const activeProv = this.agentEndpointPath + ? createChatProvider({ + apiProxy: `${req.protocol}://${req.get("host")}${this.agentEndpointPath}`, + }) + : prov; + + const model = await activeProv.languageModel(selectedChatModel); + const modelMessages = await convertToModelMessages( + uiMessages as Parameters[0], + ); + + const requestHeaders: Record = { + [CONTEXT_HEADER_CONVERSATION_ID]: id, + [CONTEXT_HEADER_USER_ID]: session.user.email ?? session.user.id, + }; + const oboToken = req.headers["x-forwarded-access-token"]; + if (typeof oboToken === "string") { + requestHeaders["x-forwarded-access-token"] = oboToken; + } + + const result = streamText({ + model, + messages: modelMessages, + providerOptions: { + databricks: { includeTrace: true }, + }, + includeRawChunks: true, + headers: requestHeaders, + onChunk: ({ chunk }) => { + if (chunk.type === "raw") { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const raw = chunk.rawValue as any; + if (raw?.type === "response.output_item.done") { + const tid = raw?.databricks_output?.trace?.info?.trace_id as + | string + | undefined; + if (tid) traceId = tid; + } + if (!traceId && typeof raw?.trace_id === "string") { + traceId = raw.trace_id; + } + } + }, + onFinish: ({ usage }) => { + finalUsage = usage; + }, + }); + + const stream = createUIMessageStream({ + originalMessages: uiMessages as Parameters< + typeof createUIMessageStream + >[0]["originalMessages"], + generateId: generateUUID, + execute: async ({ writer }) => { + const aiStream = result.toUIMessageStream({ + sendReasoning: true, + sendSources: true, + sendFinish: false, + onError: (error) => { + const msg = + error instanceof Error ? error.message : String(error); + writer.onError?.(error); + return msg; + }, + }); + + const { failed } = await drainStreamToWriter(aiStream, writer); + + if (failed) { + logger.info("Streaming failed, falling back to generateText"); + const fallbackResult = await fallbackToGenerateText( + { model, messages: modelMessages, headers: requestHeaders }, + writer, + ); + if (fallbackResult) { + finalUsage = fallbackResult.usage; + if (fallbackResult.traceId) traceId = fallbackResult.traceId; + } + } + + if (titlePromise) { + const generatedTitle = await titlePromise; + if (generatedTitle) { + writer.write({ + type: "data-title", + data: generatedTitle, + } as Parameters[0]); + } + } + + writer.write({ type: "data-traceId", data: traceId }); + }, + onFinish: async ({ responseMessage }) => { + storeMessageMeta(responseMessage.id, id, traceId); + + if (dbAvailable) { + try { + await saveMessages(db!, [ + { + id: responseMessage.id, + chatId: id, + role: responseMessage.role, + parts: responseMessage.parts, + attachments: [], + createdAt: new Date(), + traceId, + }, + ]); + } catch (err) { + logger.error("Failed to save assistant message: %O", err); + } + + if (finalUsage) { + try { + await updateChatLastContextById(db!, { + chatId: id, + context: toV3Usage(finalUsage) as unknown as Record< + string, + unknown + >, + }); + } catch (err) { + logger.warn("Failed to persist usage: %O", err); + } + } + } + + cache.clearActiveStream(id); + }, + }); + + pipeUIMessageStreamToResponse({ + stream, + response: res, + consumeSseStream: ({ stream: sseStream }) => { + cache.storeStream({ streamId, chatId: id, stream: sseStream }); + }, + }); + } catch (error) { + logger.error("Chat handler error: %O", error); + if (error instanceof ChatServerError) { + const { status, json } = error.toResponse(); + return res.status(status).json(json); + } + const err = new ChatServerError("offline:chat"); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } + }); + this.registerEndpoint("chat", `/api/${this.name}`); + } + + exports() { + return { + useAgentBackend: (agent: ChatAgentBackend) => this.useAgentBackend(agent), + }; + } +} + +async function generateTitleFromUserMessage( + prov: ReturnType, + message: { parts?: Array<{ type: string; text?: string }> }, +): Promise { + const model = await prov.languageModel("title-model"); + const textPart = message.parts?.find((p) => p.type === "text"); + const text = (textPart && "text" in textPart ? textPart.text : "") ?? ""; + const truncated = truncatePreserveWords(text, 256); + const { text: title } = await generateText({ + model, + system: + "Generate a short title (max 80 chars) for this message. No quotes or colons.", + prompt: truncated, + }); + return title ?? "New chat"; +} + +export const chat = toPlugin(ChatPlugin); diff --git a/integrations/appkit-agent/src/chat-plugin/manifest.json b/integrations/appkit-agent/src/chat-plugin/manifest.json new file mode 100644 index 000000000..85918bc73 --- /dev/null +++ b/integrations/appkit-agent/src/chat-plugin/manifest.json @@ -0,0 +1,9 @@ +{ + "name": "chat", + "displayName": "Chat Plugin", + "description": "Full-stack chat server with streaming, history, session, and optional persistence", + "resources": { + "required": [], + "optional": [] + } +} diff --git a/integrations/appkit-agent/src/chat-plugin/message-meta.ts b/integrations/appkit-agent/src/chat-plugin/message-meta.ts new file mode 100644 index 000000000..58475897b --- /dev/null +++ b/integrations/appkit-agent/src/chat-plugin/message-meta.ts @@ -0,0 +1,52 @@ +const MAX_ENTRIES = 10_000; + +function setBounded(map: Map, key: K, value: V): void { + if (map.size >= MAX_ENTRIES) { + const oldest = map.keys().next().value as K; + map.delete(oldest); + } + map.set(key, value); +} + +const store = new Map(); + +export function storeMessageMeta( + messageId: string, + chatId: string, + traceId: string | null, +) { + setBounded(store, messageId, { traceId, chatId }); +} + +export function getMessageMetadata(messageId: string) { + return store.get(messageId) ?? null; +} + +export function getMessageMetasByChatId( + chatId: string, +): Array<{ messageId: string; traceId: string }> { + const results: Array<{ messageId: string; traceId: string }> = []; + for (const [messageId, meta] of store) { + if (meta.chatId === chatId && meta.traceId != null) { + results.push({ messageId, traceId: meta.traceId }); + } + } + return results; +} + +const assessmentStore = new Map(); + +export function storeAssessmentId( + messageId: string, + userId: string, + assessmentId: string, +) { + setBounded(assessmentStore, `${messageId}:${userId}`, assessmentId); +} + +export function getAssessmentId( + messageId: string, + userId: string, +): string | null { + return assessmentStore.get(`${messageId}:${userId}`) ?? null; +} diff --git a/integrations/appkit-agent/src/chat-plugin/migrate.ts b/integrations/appkit-agent/src/chat-plugin/migrate.ts new file mode 100644 index 000000000..b52cfbece --- /dev/null +++ b/integrations/appkit-agent/src/chat-plugin/migrate.ts @@ -0,0 +1,34 @@ +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { drizzle } from "drizzle-orm/node-postgres"; +import { migrate } from "drizzle-orm/node-postgres/migrator"; +import type { Pool } from "pg"; + +function getMigrationsFolder(): string { + const currentDir = path.dirname(fileURLToPath(import.meta.url)); + const candidates = [ + path.resolve(currentDir, "../../drizzle"), + path.resolve(currentDir, "../drizzle"), + path.resolve(currentDir, "../../../drizzle"), + ]; + for (const dir of candidates) { + if (fs.existsSync(path.join(dir, "meta"))) { + return dir; + } + } + throw new Error( + "Could not locate drizzle migrations folder. " + + `Searched: ${candidates.join(", ")}`, + ); +} + +/** + * Apply Drizzle migrations to create/update the `ai_chatbot` schema and tables. + * Uses migration files generated by `drizzle-kit generate` from `schema.ts`, + * so the DDL is always in sync with the Drizzle schema definition. + */ +export async function ensureSchema(pool: Pool): Promise { + const db = drizzle(pool); + await migrate(db, { migrationsFolder: getMigrationsFolder() }); +} diff --git a/integrations/appkit-agent/src/chat-plugin/persistence.ts b/integrations/appkit-agent/src/chat-plugin/persistence.ts new file mode 100644 index 000000000..64dff7021 --- /dev/null +++ b/integrations/appkit-agent/src/chat-plugin/persistence.ts @@ -0,0 +1,240 @@ +import { and, asc, desc, eq, gt, gte, inArray, lt, sql } from "drizzle-orm"; +import { drizzle } from "drizzle-orm/node-postgres"; +import type { Pool } from "pg"; +import { type ChatRow, chat, type MessageRow, message, vote } from "./schema"; +import type { VisibilityType } from "./types"; + +export type { ChatRow, MessageRow }; + +export function createDb(pool: Pool) { + return drizzle(pool); +} + +export async function saveChat( + db: ReturnType, + params: { + id: string; + userId: string; + title: string; + visibility: VisibilityType; + }, +) { + await db.insert(chat).values({ + id: params.id, + createdAt: new Date(), + userId: params.userId, + title: params.title, + visibility: params.visibility, + }); +} + +export async function getChatById( + db: ReturnType, + id: string, +): Promise { + const [row] = await db.select().from(chat).where(eq(chat.id, id)); + return row ?? null; +} + +export async function deleteChatById( + db: ReturnType, + id: string, +) { + await db.delete(message).where(eq(message.chatId, id)); + const [deleted] = await db.delete(chat).where(eq(chat.id, id)).returning(); + return deleted ?? null; +} + +export async function getChatsByUserId( + db: ReturnType, + params: { + id: string; + limit: number; + startingAfter: string | null; + endingBefore: string | null; + }, +): Promise<{ chats: ChatRow[]; hasMore: boolean }> { + const { id, limit, startingAfter, endingBefore } = params; + const extendedLimit = limit + 1; + + if (startingAfter) { + const [anchor] = await db + .select() + .from(chat) + .where(eq(chat.id, startingAfter)) + .limit(1); + if (!anchor) return { chats: [], hasMore: false }; + const rows = await db + .select() + .from(chat) + .where(and(eq(chat.userId, id), gt(chat.createdAt, anchor.createdAt))) + .orderBy(desc(chat.createdAt)) + .limit(extendedLimit); + const hasMore = rows.length > limit; + return { chats: hasMore ? rows.slice(0, limit) : rows, hasMore }; + } + if (endingBefore) { + const [anchor] = await db + .select() + .from(chat) + .where(eq(chat.id, endingBefore)) + .limit(1); + if (!anchor) return { chats: [], hasMore: false }; + const rows = await db + .select() + .from(chat) + .where(and(eq(chat.userId, id), lt(chat.createdAt, anchor.createdAt))) + .orderBy(desc(chat.createdAt)) + .limit(extendedLimit); + const hasMore = rows.length > limit; + return { chats: hasMore ? rows.slice(0, limit) : rows, hasMore }; + } + + const rows = await db + .select() + .from(chat) + .where(eq(chat.userId, id)) + .orderBy(desc(chat.createdAt)) + .limit(extendedLimit); + const hasMore = rows.length > limit; + return { + chats: hasMore ? rows.slice(0, limit) : rows, + hasMore, + }; +} + +export async function saveMessages( + db: ReturnType, + messages: Array<{ + id: string; + chatId: string; + role: string; + parts: unknown; + attachments: unknown; + createdAt: Date; + traceId?: string | null; + }>, +) { + if (messages.length === 0) return; + await db + .insert(message) + .values( + messages.map((m) => ({ + id: m.id, + chatId: m.chatId, + role: m.role, + parts: m.parts, + attachments: m.attachments ?? [], + createdAt: m.createdAt, + traceId: m.traceId ?? null, + })), + ) + .onConflictDoUpdate({ + target: message.id, + set: { + parts: sql`excluded.parts`, + attachments: sql`excluded.attachments`, + traceId: sql`excluded."traceId"`, + }, + }); +} + +export async function getMessagesByChatId( + db: ReturnType, + chatId: string, +): Promise { + return db + .select() + .from(message) + .where(eq(message.chatId, chatId)) + .orderBy(asc(message.createdAt)); +} + +export async function getMessageById( + db: ReturnType, + id: string, +): Promise { + const [row] = await db.select().from(message).where(eq(message.id, id)); + return row ?? null; +} + +export async function updateChatTitleById( + db: ReturnType, + params: { chatId: string; title: string }, +) { + await db + .update(chat) + .set({ title: params.title }) + .where(eq(chat.id, params.chatId)); +} + +export async function updateChatVisibilityById( + db: ReturnType, + params: { chatId: string; visibility: VisibilityType }, +) { + await db + .update(chat) + .set({ visibility: params.visibility }) + .where(eq(chat.id, params.chatId)); +} + +export async function updateChatLastContextById( + db: ReturnType, + params: { chatId: string; context: Record }, +) { + await db + .update(chat) + .set({ lastContext: params.context }) + .where(eq(chat.id, params.chatId)); +} + +export async function deleteMessagesAfter( + db: ReturnType, + params: { chatId: string; afterCreatedAt: Date }, +) { + const toDelete = await db + .select({ id: message.id }) + .from(message) + .where( + and( + eq(message.chatId, params.chatId), + gte(message.createdAt, params.afterCreatedAt), + ), + ); + const ids = toDelete.map((r) => r.id); + if (ids.length > 0) { + await db.delete(vote).where(inArray(vote.messageId, ids)); + await db + .delete(message) + .where( + and( + eq(message.chatId, params.chatId), + gte(message.createdAt, params.afterCreatedAt), + ), + ); + } +} + +export async function getVotesByChatId( + db: ReturnType, + chatId: string, +) { + return db.select().from(vote).where(eq(vote.chatId, chatId)); +} + +export async function voteMessage( + db: ReturnType, + params: { chatId: string; messageId: string; isUpvoted: boolean }, +) { + await db + .insert(vote) + .values({ + chatId: params.chatId, + messageId: params.messageId, + isUpvoted: params.isUpvoted, + }) + .onConflictDoUpdate({ + target: [vote.chatId, vote.messageId], + set: { isUpvoted: params.isUpvoted }, + }); +} diff --git a/integrations/appkit-agent/src/chat-plugin/provider.ts b/integrations/appkit-agent/src/chat-plugin/provider.ts new file mode 100644 index 000000000..1f1e8fd17 --- /dev/null +++ b/integrations/appkit-agent/src/chat-plugin/provider.ts @@ -0,0 +1,94 @@ +import { createDatabricksProvider } from "@databricks/ai-sdk-provider"; +import { extractReasoningMiddleware, wrapLanguageModel } from "ai"; +import { getToken, getHostUrl } from "./auth"; + +export const CONTEXT_HEADER_CONVERSATION_ID = "x-databricks-conversation-id"; +export const CONTEXT_HEADER_USER_ID = "x-databricks-user-id"; + +type CachedProvider = ReturnType; + +const providerCache = new Map< + string, + { provider: CachedProvider; time: number } +>(); +const activePromise = new Map>(); +const PROVIDER_CACHE_MS = 5 * 60 * 1000; + +export interface CreateChatProviderOptions { + apiProxy?: string; +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type LanguageModel = any; + +const UTILITY_MODEL = "databricks-meta-llama-3-3-70b-instruct"; + +/** + * Returns a provider that can resolve language models for chat. + * Auth is delegated to `./auth.ts` (PAT → OAuth → CLI). + */ +export function createChatProvider(options: CreateChatProviderOptions = {}): { + languageModel(id: string): Promise; +} { + const apiProxy = options.apiProxy ?? process.env.API_PROXY; + const cacheKey = apiProxy ?? "__default__"; + + async function getOrCreate(): Promise { + const cached = providerCache.get(cacheKey); + if (cached && Date.now() - cached.time < PROVIDER_CACHE_MS) { + return cached.provider; + } + const pending = activePromise.get(cacheKey); + if (pending) return pending; + + const promise = (async (): Promise => { + const host = await getHostUrl(); + const baseURL = `${host.replace(/\/$/, "")}/serving-endpoints`; + return createDatabricksProvider({ + useRemoteToolCalling: true, + baseURL, + formatUrl: ({ baseUrl, path }) => + apiProxy + ? `${apiProxy.replace(/\/$/, "")}${path}` + : `${baseUrl}${path}`, + fetch: async (input, init) => { + const freshToken = await getToken(); + const headers = new Headers(init?.headers); + headers.set("Authorization", `Bearer ${freshToken}`); + if (apiProxy) { + headers.set("x-mlflow-return-trace-id", "true"); + } + return fetch(input, { ...init, headers }); + }, + }); + })(); + + activePromise.set(cacheKey, promise); + const provider = await promise; + providerCache.set(cacheKey, { provider, time: Date.now() }); + activePromise.delete(cacheKey); + return provider; + } + + return { + async languageModel(id: string): Promise { + const provider = await getOrCreate(); + let model: LanguageModel; + if (id === "title-model" || id === "artifact-model") { + model = provider.chatCompletions(UTILITY_MODEL); + } else if (apiProxy) { + model = provider.responses(id); + } else { + const endpoint = + id === "chat-model-reasoning" || id === "chat-model" + ? (process.env.DATABRICKS_SERVING_ENDPOINT ?? id) + : id; + model = provider.chatCompletions(endpoint); + } + return wrapLanguageModel({ + model, + middleware: [extractReasoningMiddleware({ tagName: "think" })], + }); + }, + }; +} diff --git a/integrations/appkit-agent/src/chat-plugin/schema.ts b/integrations/appkit-agent/src/chat-plugin/schema.ts new file mode 100644 index 000000000..5bb4c1e0c --- /dev/null +++ b/integrations/appkit-agent/src/chat-plugin/schema.ts @@ -0,0 +1,61 @@ +import { + boolean, + json, + jsonb, + pgSchema, + primaryKey, + text, + timestamp, + uuid, + varchar, +} from "drizzle-orm/pg-core"; + +const schemaName = "ai_chatbot"; +const customSchema = pgSchema(schemaName); + +export type ChatLastContext = Record | null; + +export const chat = customSchema.table("Chat", { + id: uuid("id").primaryKey().notNull().defaultRandom(), + createdAt: timestamp("createdAt").notNull(), + title: text("title").notNull(), + userId: text("userId").notNull(), + visibility: varchar("visibility", { + enum: ["public", "private"], + }) + .notNull() + .default("private"), + lastContext: jsonb("lastContext").$type(), +}); + +export const message = customSchema.table("Message", { + id: uuid("id").primaryKey().notNull().defaultRandom(), + chatId: uuid("chatId") + .notNull() + .references(() => chat.id), + role: varchar("role").notNull(), + parts: json("parts").notNull(), + attachments: json("attachments").notNull(), + createdAt: timestamp("createdAt").notNull(), + traceId: text("traceId"), +}); + +export const vote = customSchema.table( + "Vote", + { + chatId: uuid("chatId") + .notNull() + .references(() => chat.id), + messageId: uuid("messageId") + .notNull() + .references(() => message.id), + isUpvoted: boolean("isUpvoted").notNull(), + }, + (table) => ({ + pk: primaryKey({ columns: [table.chatId, table.messageId] }), + }), +); + +export type ChatRow = typeof chat.$inferSelect; +export type MessageRow = typeof message.$inferSelect; +export type VoteRow = typeof vote.$inferSelect; diff --git a/integrations/appkit-agent/src/chat-plugin/session.ts b/integrations/appkit-agent/src/chat-plugin/session.ts new file mode 100644 index 000000000..80b991434 --- /dev/null +++ b/integrations/appkit-agent/src/chat-plugin/session.ts @@ -0,0 +1,52 @@ +import type { Request } from "express"; +import type { ChatSession, GetSession } from "./types"; +import { getScimUser } from "./auth"; + +/** + * Resolve session for the request. + * + * Resolution order: + * 1. Custom getSession callback (if provided in plugin config) + * 2. x-forwarded-user headers (set by the Databricks Apps proxy in production) + * 3. SCIM API /Me (local dev with Databricks auth available) + * 4. process.env.USER fallback (bare local dev) + */ +export async function resolveSession( + req: Request, + getSession?: GetSession, +): Promise { + if (getSession) { + return Promise.resolve(getSession(req)); + } + + const forwardedUser = req.header("x-forwarded-user"); + if (forwardedUser) { + return { + user: { + id: forwardedUser, + email: req.header("x-forwarded-email") ?? undefined, + name: req.header("x-forwarded-preferred-username") ?? undefined, + preferredUsername: + req.header("x-forwarded-preferred-username") ?? undefined, + }, + }; + } + + const scimUser = await getScimUser(); + if (scimUser) { + return { user: scimUser }; + } + + const localUser = process.env.USER || process.env.USERNAME; + if (localUser) { + return { + user: { + id: localUser, + email: `${localUser}@localhost`, + name: localUser, + }, + }; + } + + return null; +} diff --git a/integrations/appkit-agent/src/chat-plugin/stream-cache.ts b/integrations/appkit-agent/src/chat-plugin/stream-cache.ts new file mode 100644 index 000000000..e51808116 --- /dev/null +++ b/integrations/appkit-agent/src/chat-plugin/stream-cache.ts @@ -0,0 +1,178 @@ +import { Readable } from "node:stream"; + +interface CachedStreamEntry { + chatId: string; + streamId: string; + cache: CacheableStream; + createdAt: number; + lastAccessedAt: number; +} + +interface CacheableStream { + readonly chunks: readonly T[]; + read(opts: { cursor?: number }): AsyncIterableIterator; + close(): void; +} + +function makeCacheableStream(source: ReadableStream): CacheableStream { + const chunks: T[] = []; + let done = false; + const waiters: (() => void)[] = []; + + const notify = () => { + const current = [...waiters]; + waiters.length = 0; + for (const resolve of current) resolve(); + }; + + (async () => { + const reader = source.getReader(); + try { + while (true) { + const { value, done: srcDone } = await reader.read(); + if (srcDone) break; + chunks.push(value); + notify(); + } + } catch { + // treat as early termination + } finally { + done = true; + notify(); + reader.releaseLock(); + } + })(); + + return { + get chunks() { + return chunks as readonly T[]; + }, + async *read({ cursor }: { cursor?: number } = {}) { + let idx = cursor ?? 0; + while (true) { + while (idx < chunks.length) { + yield chunks[idx++]; + } + if (done) return; + await new Promise((resolve) => waiters.push(resolve)); + } + }, + close() { + done = true; + notify(); + }, + }; +} + +function cacheableToReadable( + cache: CacheableStream, + opts: { cursor?: number } = {}, +): Readable { + const { cursor } = opts; + let iterator: AsyncIterableIterator | undefined; + let pendingRead: Promise> | null = null; + let isReading = false; + + return new Readable({ + highWaterMark: 16 * 1024, + read() { + if (isReading) return; + isReading = true; + if (!iterator) iterator = cache.read({ cursor }); + const processNext = async () => { + try { + for (;;) { + if (!pendingRead) pendingRead = iterator?.next() ?? null; + if (!pendingRead) break; + const { value, done } = await pendingRead; + pendingRead = null; + if (done) { + this.push(null); + break; + } + const canContinue = this.push(value); + if (!canContinue) break; + pendingRead = iterator?.next() ?? null; + } + } catch (err) { + this.destroy(err as Error); + } finally { + isReading = false; + } + }; + processNext(); + }, + destroy(error, callback) { + callback(error); + }, + }); +} + +export class StreamCache { + private cache = new Map(); + private activeStreams = new Map(); + private readonly TTL_MS = 5 * 60 * 1000; + private cleanupInterval: ReturnType | null = null; + + constructor() { + this.startCleanup(); + } + + private startCleanup() { + if (this.cleanupInterval) return; + this.cleanupInterval = setInterval(() => { + const now = Date.now(); + for (const [streamId, entry] of this.cache.entries()) { + if (now - entry.lastAccessedAt > this.TTL_MS) { + this.activeStreams.delete(entry.chatId); + entry.cache.close(); + this.cache.delete(streamId); + } + } + }, 60 * 1000); + } + + storeStream({ + streamId, + chatId, + stream, + }: { + streamId: string; + chatId: string; + stream: ReadableStream; + }) { + this.activeStreams.set(chatId, streamId); + const entry: CachedStreamEntry = { + chatId, + streamId, + cache: makeCacheableStream(stream), + createdAt: Date.now(), + lastAccessedAt: Date.now(), + }; + this.cache.set(streamId, entry); + } + + getStream(streamId: string, opts: { cursor?: number } = {}): Readable | null { + const entry = this.cache.get(streamId); + if (!entry) return null; + entry.lastAccessedAt = Date.now(); + return cacheableToReadable(entry.cache, opts); + } + + getActiveStreamId(chatId: string): string | null { + return this.activeStreams.get(chatId) ?? null; + } + + clearActiveStream(chatId: string) { + this.activeStreams.delete(chatId); + } + + clearStream(streamId: string) { + const entry = this.cache.get(streamId); + if (entry) { + entry.cache.close(); + this.cache.delete(streamId); + this.activeStreams.delete(entry.chatId); + } + } +} diff --git a/integrations/appkit-agent/src/chat-plugin/stream-fallback.ts b/integrations/appkit-agent/src/chat-plugin/stream-fallback.ts new file mode 100644 index 000000000..235020ca4 --- /dev/null +++ b/integrations/appkit-agent/src/chat-plugin/stream-fallback.ts @@ -0,0 +1,171 @@ +import { + generateText, + type LanguageModelUsage, + type UIMessageStreamWriter, +} from "ai"; +import { generateUUID } from "./utils"; + +/** + * Reads all chunks from a UI message stream, forwarding non-error parts to the + * writer. Returns whether the stream encountered any errors. + * + * Pre-first-chunk errors trigger a fallback; mid-stream errors are forwarded. + */ +export async function drainStreamToWriter( + uiStream: ReadableStream, + writer: UIMessageStreamWriter, +): Promise<{ failed: boolean; errorText?: string }> { + const reader = uiStream.getReader(); + let receivedTextChunk = false; + + try { + for ( + let chunk = await reader.read(); + !chunk.done; + chunk = await reader.read() + ) { + if (chunk.value.type === "error") { + if (!receivedTextChunk) { + return { failed: true, errorText: chunk.value.errorText }; + } + writer.write(chunk.value); + } else { + if (!receivedTextChunk && chunk.value.type.startsWith("text-")) { + receivedTextChunk = true; + } + writer.write(chunk.value); + } + } + } catch (readError) { + if (!receivedTextChunk) { + return { failed: true }; + } + } finally { + reader.releaseLock(); + } + + return { failed: false }; +} + +/** + * Converts a generateText result's content array into UIMessageChunks and + * writes them to the stream writer. Mirrors the transform in the AI SDK's + * streamText().toUIMessageStream(). + */ +function writeGenerateTextResultToStream( + result: Awaited>, + writer: UIMessageStreamWriter, +) { + for (const part of result.content) { + const id = generateUUID(); + + switch (part.type) { + case "text": { + if (part.text.length > 0) { + writer.write({ type: "text-start", id }); + writer.write({ type: "text-delta", id, delta: part.text }); + writer.write({ type: "text-end", id }); + } + break; + } + case "reasoning": { + if (part.text.length > 0) { + writer.write({ type: "reasoning-start" as "text-start", id }); + writer.write({ + type: "reasoning-delta" as "text-delta", + id, + delta: part.text, + }); + writer.write({ type: "reasoning-end" as "text-end", id }); + } + break; + } + case "file": { + writer.write({ + type: "file", + mediaType: part.file.mediaType, + url: `data:${part.file.mediaType};base64,${part.file.base64}`, + } as Parameters[0]); + break; + } + case "tool-call": { + writer.write({ + type: "tool-input-available", + toolCallId: part.toolCallId, + toolName: part.toolName, + input: part.input, + dynamic: part.dynamic, + } as Parameters[0]); + break; + } + case "tool-result": { + writer.write({ + type: "tool-output-available", + toolCallId: part.toolCallId, + output: part.output, + } as Parameters[0]); + break; + } + case "source": { + if (part.sourceType === "url") { + writer.write({ + type: "source-url", + sourceId: part.id, + url: part.url, + title: part.title, + ...(part.providerMetadata != null + ? { providerMetadata: part.providerMetadata } + : {}), + } as Parameters[0]); + } else if (part.sourceType === "document") { + writer.write({ + type: "source-document", + sourceId: part.id, + mediaType: part.mediaType, + title: part.title, + filename: part.filename, + ...(part.providerMetadata != null + ? { providerMetadata: part.providerMetadata } + : {}), + } as Parameters[0]); + } + break; + } + default: + break; + } + } + + writer.write({ type: "finish", finishReason: result.finishReason }); +} + +/** + * Falls back to a non-streaming generateText call and writes the result as + * stream parts. Returns usage on success, undefined on failure. + */ +export async function fallbackToGenerateText( + params: Parameters[0], + writer: UIMessageStreamWriter, +): Promise<{ usage: LanguageModelUsage; traceId?: string } | undefined> { + try { + const fallback = await generateText(params); + + const traceId = ( + fallback?.response?.body as { + metadata?: { trace_id?: string }; + } + )?.metadata?.trace_id; + + writeGenerateTextResultToStream(fallback, writer); + return { usage: fallback.usage, traceId }; + } catch (fallbackError) { + const errorMessage = + fallbackError instanceof Error + ? fallbackError.message + : String(fallbackError); + writer.write({ type: "data-error", data: errorMessage } as Parameters< + typeof writer.write + >[0]); + return undefined; + } +} diff --git a/integrations/appkit-agent/src/chat-plugin/types.ts b/integrations/appkit-agent/src/chat-plugin/types.ts new file mode 100644 index 000000000..c55e83dd8 --- /dev/null +++ b/integrations/appkit-agent/src/chat-plugin/types.ts @@ -0,0 +1,69 @@ +import type { Request } from "express"; +import type { BasePluginConfig } from "@databricks/appkit"; +import { z as zod } from "zod"; + +export interface ChatSession { + user: { + id: string; + email?: string; + name?: string; + preferredUsername?: string; + } | null; +} + +export type GetSession = ( + req: Request, +) => Promise | ChatSession | null; + +export interface ChatConfig extends BasePluginConfig { + /** Resolve session from request. If not set, session is derived from x-forwarded-user headers. */ + getSession?: GetSession; + /** pg Pool for persistence. When not set, runs in ephemeral mode (no history). */ + pool?: import("pg").Pool; + /** Model / endpoint id. Defaults to process.env.DATABRICKS_SERVING_ENDPOINT or "chat-model". */ + modelId?: string; + /** Proxy URL for model requests (e.g. MLflow Agent Server). Defaults to process.env.API_PROXY. */ + apiProxy?: string; + /** Enable feedback feature (thumbs up/down). Defaults to !!process.env.MLFLOW_EXPERIMENT_ID. */ + feedbackEnabled?: boolean; + /** Auto-create the ai_chatbot schema and tables on startup. Defaults to false. */ + autoMigrate?: boolean; +} + +const textPartSchema = zod.object({ + type: zod.enum(["text"]), + text: zod.string().min(1), +}); + +const filePartSchema = zod.object({ + type: zod.enum(["file"]), + mediaType: zod.enum(["image/jpeg", "image/png"]), + name: zod.string().min(1), + url: zod.string().url(), +}); + +const partSchema = zod.union([textPartSchema, filePartSchema]); + +const previousMessageSchema = zod.object({ + id: zod.string(), + role: zod.enum(["user", "assistant", "system"]), + parts: zod.array(zod.any()), +}); + +export const postRequestBodySchema = zod.object({ + id: zod.string().min(1), + message: zod + .object({ + id: zod.string().min(1), + role: zod.enum(["user"]), + parts: zod.array(partSchema), + }) + .optional(), + selectedChatModel: zod.enum(["chat-model", "chat-model-reasoning"]), + selectedVisibilityType: zod.enum(["public", "private"]), + previousMessages: zod.array(previousMessageSchema).optional(), +}); + +export type PostRequestBody = zod.infer; + +export type VisibilityType = "public" | "private"; diff --git a/integrations/appkit-agent/src/chat-plugin/utils.ts b/integrations/appkit-agent/src/chat-plugin/utils.ts new file mode 100644 index 000000000..bce573ce3 --- /dev/null +++ b/integrations/appkit-agent/src/chat-plugin/utils.ts @@ -0,0 +1,35 @@ +import type { MessageRow } from "./schema"; + +export function generateUUID(): string { + return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => { + const r = (Math.random() * 16) | 0; + const v = c === "x" ? r : (r & 0x3) | 0x8; + return v.toString(16); + }); +} + +export function convertToUIMessages(messages: MessageRow[]): Array<{ + id: string; + role: "user" | "assistant" | "system"; + parts: unknown[]; + metadata?: { createdAt: string }; +}> { + return messages.map((m) => ({ + id: m.id, + role: m.role as "user" | "assistant" | "system", + parts: m.parts as unknown[], + metadata: { createdAt: m.createdAt.toISOString() }, + })); +} + +export function truncatePreserveWords( + input: string, + maxLength: number, +): string { + if (maxLength <= 0) return ""; + if (input.length <= maxLength) return input; + const slice = input.slice(0, maxLength); + const lastSpaceIndex = slice.lastIndexOf(" "); + if (lastSpaceIndex <= 0) return slice; + return slice.slice(0, lastSpaceIndex); +} diff --git a/integrations/appkit-agent/src/index.ts b/integrations/appkit-agent/src/index.ts index 016c89a2c..e92ebc60e 100644 --- a/integrations/appkit-agent/src/index.ts +++ b/integrations/appkit-agent/src/index.ts @@ -21,3 +21,11 @@ export { isHostedTool } from "./agent-plugin/hosted-tools"; export { createInvokeHandler } from "./agent-plugin/invoke-handler"; export { StandardAgent } from "./agent-plugin/standard-agent"; export type { AgentTool, IAgentConfig } from "./agent-plugin/types"; + +export { chat, ChatPlugin } from "./chat-plugin/index"; +export type { + ChatConfig, + ChatSession, + GetSession, + ChatAgentBackend, +} from "./chat-plugin/index"; diff --git a/integrations/appkit-agent/src/tests/chat-plugin/chat-acl.test.ts b/integrations/appkit-agent/src/tests/chat-plugin/chat-acl.test.ts new file mode 100644 index 000000000..2e014f48b --- /dev/null +++ b/integrations/appkit-agent/src/tests/chat-plugin/chat-acl.test.ts @@ -0,0 +1,48 @@ +import { describe, expect, test } from "vitest"; +import { checkChatAccess } from "../../chat-plugin/chat-acl"; + +const makeChat = ( + overrides: Partial<{ + id: string; + userId: string; + visibility: "public" | "private"; + title: string; + createdAt: Date; + lastContext: null; + }> = {}, +) => ({ + id: "chat-1", + userId: "user-1", + visibility: "private" as const, + title: "Test", + createdAt: new Date(), + lastContext: null, + ...overrides, +}); + +describe("checkChatAccess", () => { + test("returns not_found when chat does not exist", async () => { + const result = await checkChatAccess(async () => null, "chat-1", "user-1"); + expect(result.allowed).toBe(false); + expect(result.reason).toBe("not_found"); + }); + + test("allows owner of private chat", async () => { + const chat = makeChat({ userId: "user-1", visibility: "private" }); + const result = await checkChatAccess(async () => chat, "chat-1", "user-1"); + expect(result.allowed).toBe(true); + }); + + test("denies non-owner of private chat", async () => { + const chat = makeChat({ userId: "user-1", visibility: "private" }); + const result = await checkChatAccess(async () => chat, "chat-1", "user-2"); + expect(result.allowed).toBe(false); + expect(result.reason).toBe("forbidden"); + }); + + test("allows anyone for public chat", async () => { + const chat = makeChat({ userId: "user-1", visibility: "public" }); + const result = await checkChatAccess(async () => chat, "chat-1", "user-2"); + expect(result.allowed).toBe(true); + }); +}); diff --git a/integrations/appkit-agent/src/tests/chat-plugin/errors.test.ts b/integrations/appkit-agent/src/tests/chat-plugin/errors.test.ts new file mode 100644 index 000000000..767fd2101 --- /dev/null +++ b/integrations/appkit-agent/src/tests/chat-plugin/errors.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, test } from "vitest"; +import { ChatServerError } from "../../chat-plugin/errors"; + +describe("ChatServerError", () => { + test("returns correct status for known codes", () => { + const cases: Array<[string, number]> = [ + ["bad_request:api", 400], + ["unauthorized:chat", 401], + ["forbidden:chat", 403], + ["not_found:database", 404], + ["empty:stream", 404], + ["offline:chat", 503], + ["bad_request:database", 500], + ]; + for (const [code, expectedStatus] of cases) { + const err = new ChatServerError(code); + const { status } = err.toResponse(); + expect(status).toBe(expectedStatus); + } + }); + + test("returns 500 for unknown codes", () => { + const err = new ChatServerError("unknown:code"); + const { status } = err.toResponse(); + expect(status).toBe(500); + }); + + test("uses custom message in response", () => { + const err = new ChatServerError("forbidden:chat", "Not your chat"); + const { json } = err.toResponse(); + expect(json.error).toBe("Not your chat"); + expect(json.code).toBe("forbidden:chat"); + }); +}); diff --git a/integrations/appkit-agent/src/tests/chat-plugin/message-meta.test.ts b/integrations/appkit-agent/src/tests/chat-plugin/message-meta.test.ts new file mode 100644 index 000000000..ab39e372e --- /dev/null +++ b/integrations/appkit-agent/src/tests/chat-plugin/message-meta.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, test } from "vitest"; +import { + getMessageMetadata, + getMessageMetasByChatId, + storeMessageMeta, +} from "../../chat-plugin/message-meta"; + +describe("message-meta", () => { + test("stores and retrieves metadata", () => { + storeMessageMeta("msg-1", "chat-1", "trace-abc"); + const meta = getMessageMetadata("msg-1"); + expect(meta).toEqual({ traceId: "trace-abc", chatId: "chat-1" }); + }); + + test("returns null for unknown message", () => { + expect(getMessageMetadata("nonexistent")).toBeNull(); + }); + + test("getMessageMetasByChatId filters by chatId", () => { + storeMessageMeta("msg-a", "chat-x", "trace-1"); + storeMessageMeta("msg-b", "chat-x", "trace-2"); + storeMessageMeta("msg-c", "chat-y", "trace-3"); + + const metas = getMessageMetasByChatId("chat-x"); + expect(metas.length).toBeGreaterThanOrEqual(2); + expect(metas.every((m) => m.traceId !== undefined)).toBe(true); + }); + + test("skips entries with null traceId", () => { + storeMessageMeta("msg-null", "chat-null", null); + const metas = getMessageMetasByChatId("chat-null"); + expect(metas.find((m) => m.messageId === "msg-null")).toBeUndefined(); + }); +}); diff --git a/integrations/appkit-agent/src/tests/chat-plugin/migrate.test.ts b/integrations/appkit-agent/src/tests/chat-plugin/migrate.test.ts new file mode 100644 index 000000000..97135e93d --- /dev/null +++ b/integrations/appkit-agent/src/tests/chat-plugin/migrate.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, test, vi } from "vitest"; + +vi.mock("drizzle-orm/node-postgres", () => ({ + drizzle: vi.fn(() => "__mock_db__"), +})); + +vi.mock("drizzle-orm/node-postgres/migrator", () => ({ + migrate: vi.fn().mockResolvedValue(undefined), +})); + +import { ensureSchema } from "../../chat-plugin/migrate"; +import { drizzle } from "drizzle-orm/node-postgres"; +import { migrate } from "drizzle-orm/node-postgres/migrator"; + +describe("ensureSchema", () => { + test("calls drizzle migrate with the pool and migrations folder", async () => { + const pool = { query: vi.fn() }; + await ensureSchema(pool as never); + + expect(drizzle).toHaveBeenCalledWith(pool); + expect(migrate).toHaveBeenCalledTimes(1); + expect(migrate).toHaveBeenCalledWith("__mock_db__", { + migrationsFolder: expect.stringContaining("drizzle"), + }); + }); + + test("propagates migration errors", async () => { + vi.mocked(migrate).mockRejectedValueOnce(new Error("connection refused")); + const pool = { query: vi.fn() }; + await expect(ensureSchema(pool as never)).rejects.toThrow( + "connection refused", + ); + }); +}); diff --git a/integrations/appkit-agent/src/tests/chat-plugin/plugin.test.ts b/integrations/appkit-agent/src/tests/chat-plugin/plugin.test.ts new file mode 100644 index 000000000..b30d0e7c4 --- /dev/null +++ b/integrations/appkit-agent/src/tests/chat-plugin/plugin.test.ts @@ -0,0 +1,101 @@ +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; +import { ChatPlugin, chat } from "../../chat-plugin/index"; +import type { ChatConfig } from "../../chat-plugin/types"; +import { createMockRouter } from "./test-helpers"; + +vi.mock("@databricks/appkit", () => { + class MockPlugin { + protected config: T; + private endpoints = new Map(); + + constructor(config: T) { + this.config = config; + } + + registerEndpoint(name: string, path: string) { + this.endpoints.set(name, path); + } + + setup(): Promise { + return Promise.resolve(); + } + + injectRoutes(_router: unknown) {} + exports() { + return {}; + } + } + + return { + Plugin: MockPlugin, + toPlugin: (Ctor: new (config: unknown) => unknown) => { + return (config: unknown) => { + const instance = new Ctor(config) as Record; + return { + name: instance.name, + instance, + }; + }; + }, + }; +}); + +describe("ChatPlugin", () => { + beforeEach(() => { + process.env.DATABRICKS_HOST = "https://test.databricks.com"; + process.env.DATABRICKS_TOKEN = "test-token"; + }); + + afterEach(() => { + delete process.env.DATABRICKS_HOST; + delete process.env.DATABRICKS_TOKEN; + }); + + test("chat factory produces plugin with name chat", () => { + const pluginData = chat({}); + expect(pluginData.name).toBe("chat"); + }); + + test("plugin has correct manifest", () => { + expect(ChatPlugin.manifest).toBeDefined(); + expect(ChatPlugin.manifest.name).toBe("chat"); + }); + + test("plugin instance has correct name", () => { + const config: ChatConfig = {}; + const plugin = new ChatPlugin(config); + expect(plugin.name).toBe("chat"); + }); + + describe("setup()", () => { + test("initializes without pool (ephemeral mode)", async () => { + const plugin = new ChatPlugin({}); + await expect(plugin.setup()).resolves.toBeUndefined(); + }); + }); + + describe("injectRoutes()", () => { + test("registers config, session, history, and chat routes", async () => { + const plugin = new ChatPlugin({}); + await plugin.setup(); + + const { router } = createMockRouter() as { + router: Record>; + }; + plugin.injectRoutes(router as never); + + expect(router.get).toHaveBeenCalledWith("/config", expect.any(Function)); + expect(router.get).toHaveBeenCalledWith("/session", expect.any(Function)); + expect(router.get).toHaveBeenCalledWith( + "/history", + expect.any(Function), + expect.any(Function), + ); + expect(router.post).toHaveBeenCalledWith( + "/", + expect.any(Function), + expect.any(Function), + ); + }); + }); +}); diff --git a/integrations/appkit-agent/src/tests/chat-plugin/stream-cache.test.ts b/integrations/appkit-agent/src/tests/chat-plugin/stream-cache.test.ts new file mode 100644 index 000000000..978cda78d --- /dev/null +++ b/integrations/appkit-agent/src/tests/chat-plugin/stream-cache.test.ts @@ -0,0 +1,69 @@ +import { afterEach, describe, expect, test, vi } from "vitest"; +import { StreamCache } from "../../chat-plugin/stream-cache"; + +function makeReadableStream(chunks: string[]): ReadableStream { + return new ReadableStream({ + start(controller) { + for (const chunk of chunks) { + controller.enqueue(chunk); + } + controller.close(); + }, + }); +} + +describe("StreamCache", () => { + afterEach(() => { + vi.restoreAllMocks(); + }); + + test("stores and retrieves active stream id", () => { + const cache = new StreamCache(); + const stream = makeReadableStream(["hello"]); + cache.storeStream({ streamId: "s1", chatId: "c1", stream }); + expect(cache.getActiveStreamId("c1")).toBe("s1"); + }); + + test("returns null for unknown stream", () => { + const cache = new StreamCache(); + expect(cache.getStream("nonexistent")).toBeNull(); + }); + + test("clears active stream", () => { + const cache = new StreamCache(); + const stream = makeReadableStream(["data"]); + cache.storeStream({ streamId: "s1", chatId: "c1", stream }); + cache.clearActiveStream("c1"); + expect(cache.getActiveStreamId("c1")).toBeNull(); + }); + + test("clears specific stream", () => { + const cache = new StreamCache(); + const stream = makeReadableStream(["data"]); + cache.storeStream({ streamId: "s1", chatId: "c1", stream }); + cache.clearStream("s1"); + expect(cache.getStream("s1")).toBeNull(); + expect(cache.getActiveStreamId("c1")).toBeNull(); + }); + + test("getStream returns a Readable", async () => { + const cache = new StreamCache(); + const stream = makeReadableStream(["chunk1", "chunk2"]); + cache.storeStream({ streamId: "s1", chatId: "c1", stream }); + + await new Promise((r) => setTimeout(r, 50)); + + const readable = cache.getStream("s1"); + expect(readable).not.toBeNull(); + + const collected: string[] = []; + await new Promise((resolve, reject) => { + readable!.on("data", (chunk: Buffer | string) => { + collected.push(typeof chunk === "string" ? chunk : chunk.toString()); + }); + readable!.on("end", resolve); + readable!.on("error", reject); + }); + expect(collected).toEqual(["chunk1", "chunk2"]); + }); +}); diff --git a/integrations/appkit-agent/src/tests/chat-plugin/test-helpers.ts b/integrations/appkit-agent/src/tests/chat-plugin/test-helpers.ts new file mode 100644 index 000000000..319babe1c --- /dev/null +++ b/integrations/appkit-agent/src/tests/chat-plugin/test-helpers.ts @@ -0,0 +1,88 @@ +import { vi } from "vitest"; + +export function createMockRequest( + overrides: Record = {}, +): Record { + return { + params: {}, + query: {}, + body: {}, + headers: {}, + header(name: string) { + return (this as Record).headers + ? ((this as Record).headers as Record)[ + name.toLowerCase() + ] + : undefined; + }, + ...overrides, + }; +} + +export function createMockResponse(): Record { + const eventListeners: Record< + string, + Array<(...args: unknown[]) => void> + > = {}; + + const res = { + status: vi.fn().mockReturnThis(), + json: vi.fn().mockReturnThis(), + send: vi.fn().mockReturnThis(), + sendStatus: vi.fn().mockReturnThis(), + end: vi.fn(function (this: Record) { + this.writableEnded = true; + if (eventListeners.close) { + for (const handler of eventListeners.close) { + handler(); + } + } + return this; + }), + write: vi.fn().mockReturnThis(), + setHeader: vi.fn().mockReturnThis(), + flushHeaders: vi.fn().mockReturnThis(), + on: vi.fn(function ( + this: Record, + event: string, + handler: (...args: unknown[]) => void, + ) { + if (!eventListeners[event]) { + eventListeners[event] = []; + } + eventListeners[event].push(handler); + return this; + }), + writableEnded: false, + }; + return res; +} + +export function createMockRouter(): Record { + const handlers: Record = {}; + + const mockRouter = { + get: vi.fn((path: string, ...args: unknown[]) => { + handlers[`GET:${path}`] = args[args.length - 1]; + }), + post: vi.fn((path: string, ...args: unknown[]) => { + handlers[`POST:${path}`] = args[args.length - 1]; + }), + put: vi.fn((path: string, ...args: unknown[]) => { + handlers[`PUT:${path}`] = args[args.length - 1]; + }), + delete: vi.fn((path: string, ...args: unknown[]) => { + handlers[`DELETE:${path}`] = args[args.length - 1]; + }), + patch: vi.fn((path: string, ...args: unknown[]) => { + handlers[`PATCH:${path}`] = args[args.length - 1]; + }), + }; + + return { + router: mockRouter, + handlers, + getHandler: (method: string, path: string) => + handlers[`${method.toUpperCase()}:${path}`], + }; +} diff --git a/integrations/appkit-agent/src/tests/chat-plugin/utils.test.ts b/integrations/appkit-agent/src/tests/chat-plugin/utils.test.ts new file mode 100644 index 000000000..7a59da158 --- /dev/null +++ b/integrations/appkit-agent/src/tests/chat-plugin/utils.test.ts @@ -0,0 +1,33 @@ +import { describe, expect, test } from "vitest"; +import { generateUUID, truncatePreserveWords } from "../../chat-plugin/utils"; + +describe("generateUUID", () => { + test("returns a v4 UUID-shaped string", () => { + const uuid = generateUUID(); + expect(uuid).toMatch( + /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/, + ); + }); + + test("returns unique values", () => { + const ids = new Set(Array.from({ length: 100 }, () => generateUUID())); + expect(ids.size).toBe(100); + }); +}); + +describe("truncatePreserveWords", () => { + test("returns input unchanged if shorter than maxLength", () => { + expect(truncatePreserveWords("hello world", 100)).toBe("hello world"); + }); + + test("truncates at word boundary", () => { + expect(truncatePreserveWords("hello wonderful world", 14)).toBe("hello"); + expect(truncatePreserveWords("hello wonderful world", 16)).toBe( + "hello wonderful", + ); + }); + + test("returns empty for maxLength 0", () => { + expect(truncatePreserveWords("hello", 0)).toBe(""); + }); +}); diff --git a/integrations/appkit-agent/tsdown.config.ts b/integrations/appkit-agent/tsdown.config.ts index fddfd27e6..a2e7e4df4 100644 --- a/integrations/appkit-agent/tsdown.config.ts +++ b/integrations/appkit-agent/tsdown.config.ts @@ -4,6 +4,7 @@ export default defineConfig([ { entry: { index: "./src/index.ts", + "chat/index": "./src/chat-plugin/index.ts", }, format: ["esm", "cjs"], fixedExtension: true, @@ -14,11 +15,13 @@ export default defineConfig([ sourcemap: true, external: [ "@databricks/appkit", + "@databricks/ai-sdk-provider", "@databricks/langchainjs", "@langchain/core", "@langchain/langgraph", "@langchain/mcp-adapters", "express", + "pg", ], platform: "node", treeshake: true, From ff9b66b3a4549c78f1b72d697b60a68de091c61d Mon Sep 17 00:00:00 2001 From: Hubert Zub Date: Wed, 25 Mar 2026 10:37:16 +0100 Subject: [PATCH 10/16] bugfixes Signed-off-by: Hubert Zub --- .../appkit-agent/src/chat-plugin/index.ts | 25 ++++++++++++++----- .../src/chat-plugin/persistence.ts | 8 ++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/integrations/appkit-agent/src/chat-plugin/index.ts b/integrations/appkit-agent/src/chat-plugin/index.ts index a60ab12d4..e7cb418af 100644 --- a/integrations/appkit-agent/src/chat-plugin/index.ts +++ b/integrations/appkit-agent/src/chat-plugin/index.ts @@ -95,6 +95,7 @@ export class ChatPlugin extends Plugin { private provider: ReturnType | null = null; private streamCache: StreamCache | null = null; + private db: ReturnType | null = null; private getChat: (id: string) => Promise = async () => null; private agentEndpointPath: string | null = null; @@ -119,8 +120,8 @@ export class ChatPlugin extends Plugin { await ensureSchema(this.config.pool); logger.info("Database schema ensured (autoMigrate)"); } - const db = createDb(this.config.pool); - this.getChat = (id) => getChatById(db, id); + this.db = createDb(this.config.pool); + this.getChat = (id) => getChatById(this.db!, id); } logger.info( "Chat plugin initialized (persistence: %s)", @@ -130,7 +131,7 @@ export class ChatPlugin extends Plugin { injectRoutes(router: express.Router) { const pool = this.config.pool; - const db = pool ? createDb(pool) : null; + const db = this.db; const getSessionFn = this.config.getSession; const cache = this.streamCache!; const prov = this.provider!; @@ -220,7 +221,11 @@ export class ChatPlugin extends Plugin { session?: Awaited>; } ).session; - if (!session?.user) return; + if (!session?.user) { + const err = new ChatServerError("unauthorized:chat"); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } const limit = Number.parseInt((req.query.limit as string) || "10", 10); const startingAfter = (req.query.starting_after as string) || null; const endingBefore = (req.query.ending_before as string) || null; @@ -321,7 +326,11 @@ export class ChatPlugin extends Plugin { session?: Awaited>; } ).session; - if (!session?.user) return; + if (!session?.user) { + const err = new ChatServerError("unauthorized:chat"); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } let traceId: string | null = null; let chatId: string | undefined; @@ -623,7 +632,11 @@ export class ChatPlugin extends Plugin { session?: Awaited>; } ).session; - if (!session?.user) return; + if (!session?.user) { + const err = new ChatServerError("unauthorized:chat"); + const { status, json } = err.toResponse(); + return res.status(status).json(json); + } const { id, diff --git a/integrations/appkit-agent/src/chat-plugin/persistence.ts b/integrations/appkit-agent/src/chat-plugin/persistence.ts index 64dff7021..613269134 100644 --- a/integrations/appkit-agent/src/chat-plugin/persistence.ts +++ b/integrations/appkit-agent/src/chat-plugin/persistence.ts @@ -40,6 +40,14 @@ export async function deleteChatById( db: ReturnType, id: string, ) { + const msgIds = await db + .select({ id: message.id }) + .from(message) + .where(eq(message.chatId, id)); + const ids = msgIds.map((r) => r.id); + if (ids.length > 0) { + await db.delete(vote).where(inArray(vote.messageId, ids)); + } await db.delete(message).where(eq(message.chatId, id)); const [deleted] = await db.delete(chat).where(eq(chat.id, id)).returning(); return deleted ?? null; From c4d0cb8fdfb2089b288d11711ce293ff3e0cc70c Mon Sep 17 00:00:00 2001 From: Hubert Zub Date: Wed, 25 Mar 2026 11:06:05 +0100 Subject: [PATCH 11/16] Backend option Signed-off-by: Hubert Zub --- integrations/appkit-agent/README.md | 1 + .../appkit-agent/src/chat-plugin/errors.ts | 2 +- .../appkit-agent/src/chat-plugin/index.ts | 61 ++++++++++--------- .../appkit-agent/src/chat-plugin/types.ts | 22 +++++-- integrations/appkit-agent/src/index.ts | 2 +- .../src/tests/chat-plugin/errors.test.ts | 2 +- 6 files changed, 55 insertions(+), 35 deletions(-) diff --git a/integrations/appkit-agent/README.md b/integrations/appkit-agent/README.md index 16e59670b..8b8e06e74 100644 --- a/integrations/appkit-agent/README.md +++ b/integrations/appkit-agent/README.md @@ -339,6 +339,7 @@ All routes are mounted under `/api/chat/`. | --------------------- | ------------------------------------------------------------- | | `IAgentConfig` | Agent plugin configuration options | | `ChatConfig` | Chat plugin configuration options | +| `ChatBackend` | Backend target: plugin name, `{ proxy }`, or `{ endpoint }` | | `ChatSession` | Session object with user info | | `GetSession` | Custom session resolver function type | | `AgentInterface` | Contract for custom agent implementations | diff --git a/integrations/appkit-agent/src/chat-plugin/errors.ts b/integrations/appkit-agent/src/chat-plugin/errors.ts index 06cb5bf57..4637bddf3 100644 --- a/integrations/appkit-agent/src/chat-plugin/errors.ts +++ b/integrations/appkit-agent/src/chat-plugin/errors.ts @@ -13,7 +13,7 @@ export class ChatServerError extends Error { "unauthorized:chat": 401, "forbidden:chat": 403, "not_found:database": 404, - "empty:stream": 404, + "empty:stream": 204, "offline:chat": 503, "bad_request:database": 500, }; diff --git a/integrations/appkit-agent/src/chat-plugin/index.ts b/integrations/appkit-agent/src/chat-plugin/index.ts index e7cb418af..0f9708ded 100644 --- a/integrations/appkit-agent/src/chat-plugin/index.ts +++ b/integrations/appkit-agent/src/chat-plugin/index.ts @@ -52,6 +52,7 @@ import { export type { ChatConfig } from "./types"; export type { ChatSession, GetSession } from "./types"; +export type { ChatBackend } from "./types"; import { convertToUIMessages, @@ -61,11 +62,6 @@ import { const logger = createLogger("chat"); -/** Agent backend shape expected by `useAgentBackend`. */ -export type ChatAgentBackend = { - endpointPath: string; -}; - type ChatMessage = NonNullable[number]; /** @@ -98,22 +94,9 @@ export class ChatPlugin extends Plugin { private db: ReturnType | null = null; private getChat: (id: string) => Promise = async () => null; - private agentEndpointPath: string | null = null; - - /** - * Wire the agent plugin as the chat backend. When set, chat POST requests - * are routed through the agent's local HTTP endpoint using the same - * `streamText` path as a remote serving endpoint — no custom adapter needed. - */ - useAgentBackend(agent: ChatAgentBackend): void { - this.agentEndpointPath = agent.endpointPath; - logger.info("Chat backend set to local agent at %s", agent.endpointPath); - } async setup() { - this.provider = createChatProvider({ - apiProxy: this.config.apiProxy ?? process.env.API_PROXY, - }); + this.provider = createChatProvider(); this.streamCache = new StreamCache(); if (this.config.pool) { if (this.config.autoMigrate) { @@ -766,13 +749,12 @@ export class ChatPlugin extends Plugin { let finalUsage: LanguageModelUsage | undefined; let traceId: string | null = null; - const activeProv = this.agentEndpointPath - ? createChatProvider({ - apiProxy: `${req.protocol}://${req.get("host")}${this.agentEndpointPath}`, - }) - : prov; + const { provider: activeProv, modelId: resolvedModelId } = + this.resolveBackend(req); - const model = await activeProv.languageModel(selectedChatModel); + const model = await activeProv.languageModel( + resolvedModelId ?? selectedChatModel, + ); const modelMessages = await convertToModelMessages( uiMessages as Parameters[0], ); @@ -918,10 +900,33 @@ export class ChatPlugin extends Plugin { this.registerEndpoint("chat", `/api/${this.name}`); } + private resolveBackend(req: express.Request): { + provider: ReturnType; + modelId: string | null; + } { + const backend = this.config.backend; + if (!backend) { + return { provider: this.provider!, modelId: null }; + } + if (typeof backend === "string") { + return { + provider: createChatProvider({ + apiProxy: `${req.protocol}://${req.get("host")}/api/${backend}`, + }), + modelId: null, + }; + } + if ("proxy" in backend) { + return { + provider: createChatProvider({ apiProxy: backend.proxy }), + modelId: null, + }; + } + return { provider: this.provider!, modelId: backend.endpoint }; + } + exports() { - return { - useAgentBackend: (agent: ChatAgentBackend) => this.useAgentBackend(agent), - }; + return {}; } } diff --git a/integrations/appkit-agent/src/chat-plugin/types.ts b/integrations/appkit-agent/src/chat-plugin/types.ts index c55e83dd8..645504644 100644 --- a/integrations/appkit-agent/src/chat-plugin/types.ts +++ b/integrations/appkit-agent/src/chat-plugin/types.ts @@ -15,15 +15,29 @@ export type GetSession = ( req: Request, ) => Promise | ChatSession | null; +/** + * Chat backend target. + * + * - `string` — name of a local AppKit plugin (e.g. `'agent'`). Requests are + * proxied to `/api/` on the same server at request time. + * - `{ proxy: string }` — arbitrary proxy URL (e.g. `{ proxy: 'http://localhost:8000/invocations' }`). + * - `{ endpoint: string }` — Databricks serving endpoint name + * (e.g. `{ endpoint: 'databricks-claude-sonnet-4-5' }`). + * + * When omitted, defaults to `process.env.DATABRICKS_SERVING_ENDPOINT` or `'chat-model'`. + */ +export type ChatBackend = + | string + | { proxy: string } + | { endpoint: string }; + export interface ChatConfig extends BasePluginConfig { /** Resolve session from request. If not set, session is derived from x-forwarded-user headers. */ getSession?: GetSession; /** pg Pool for persistence. When not set, runs in ephemeral mode (no history). */ pool?: import("pg").Pool; - /** Model / endpoint id. Defaults to process.env.DATABRICKS_SERVING_ENDPOINT or "chat-model". */ - modelId?: string; - /** Proxy URL for model requests (e.g. MLflow Agent Server). Defaults to process.env.API_PROXY. */ - apiProxy?: string; + /** Chat backend target. See {@link ChatBackend}. */ + backend?: ChatBackend; /** Enable feedback feature (thumbs up/down). Defaults to !!process.env.MLFLOW_EXPERIMENT_ID. */ feedbackEnabled?: boolean; /** Auto-create the ai_chatbot schema and tables on startup. Defaults to false. */ diff --git a/integrations/appkit-agent/src/index.ts b/integrations/appkit-agent/src/index.ts index e92ebc60e..7997aba5e 100644 --- a/integrations/appkit-agent/src/index.ts +++ b/integrations/appkit-agent/src/index.ts @@ -25,7 +25,7 @@ export type { AgentTool, IAgentConfig } from "./agent-plugin/types"; export { chat, ChatPlugin } from "./chat-plugin/index"; export type { ChatConfig, + ChatBackend, ChatSession, GetSession, - ChatAgentBackend, } from "./chat-plugin/index"; diff --git a/integrations/appkit-agent/src/tests/chat-plugin/errors.test.ts b/integrations/appkit-agent/src/tests/chat-plugin/errors.test.ts index 767fd2101..3c5c930c5 100644 --- a/integrations/appkit-agent/src/tests/chat-plugin/errors.test.ts +++ b/integrations/appkit-agent/src/tests/chat-plugin/errors.test.ts @@ -8,7 +8,7 @@ describe("ChatServerError", () => { ["unauthorized:chat", 401], ["forbidden:chat", 403], ["not_found:database", 404], - ["empty:stream", 404], + ["empty:stream", 204], ["offline:chat", 503], ["bad_request:database", 500], ]; From a312c6214c1ab2b7f6583c834d24ebfdeb0ac4b7 Mon Sep 17 00:00:00 2001 From: Hubert Zub Date: Tue, 24 Mar 2026 17:07:14 +0100 Subject: [PATCH 12/16] UI Signed-off-by: Hubert Zub --- integrations/appkit-agent/README.md | 20 +- integrations/appkit-agent/client/index.html | 16 + integrations/appkit-agent/client/package.json | 64 + .../appkit-agent/client/pnpm-lock.yaml | 4952 +++++++++++++++++ .../appkit-agent/client/postcss.config.js | 5 + integrations/appkit-agent/client/src/App.tsx | 25 + .../client/src/components/ChatApp.tsx | 289 + .../client/src/components/ChatComposer.tsx | 48 + .../client/src/components/ChatPanel.tsx | 124 + .../client/src/components/ChatSidebar.tsx | 203 + .../client/src/components/ChatSidebarItem.tsx | 103 + .../client/src/components/DatabricksLogo.tsx | 47 + .../components/animation-assistant-icon.tsx | 222 + .../client/src/components/app-sidebar.tsx | 111 + .../client/src/components/chat-header.tsx | 115 + .../client/src/components/chat.tsx | 337 ++ .../src/components/data-stream-provider.tsx | 38 + .../databricks-message-citation.tsx | 109 + .../databricks-message-part-transformers.ts | 84 + .../src/components/elements/actions.tsx | 66 + .../src/components/elements/code-block.tsx | 102 + .../src/components/elements/conversation.tsx | 27 + .../client/src/components/elements/loader.tsx | 96 + .../src/components/elements/mcp-tool.tsx | 246 + .../src/components/elements/message.tsx | 23 + .../src/components/elements/prompt-input.tsx | 159 + .../src/components/elements/reasoning.tsx | 166 + .../src/components/elements/response.tsx | 22 + .../src/components/elements/suggestion.tsx | 35 + .../client/src/components/elements/tool.tsx | 197 + .../client/src/components/greeting.tsx | 19 + .../src/components/icons/ArrowUpIcon.tsx | 36 + .../src/components/icons/CheckCircleIcon.tsx | 37 + .../client/src/components/icons/CheckIcon.tsx | 36 + .../src/components/icons/ChevronDownIcon.tsx | 36 + .../src/components/icons/ChevronUpIcon.tsx | 36 + .../components/icons/CircleOutlineIcon.tsx | 36 + .../client/src/components/icons/ClockIcon.tsx | 37 + .../src/components/icons/CloudOffIcon.tsx | 40 + .../client/src/components/icons/CopyIcon.tsx | 36 + .../src/components/icons/LightbulbIcon.tsx | 40 + .../src/components/icons/NewChatIcon.tsx | 40 + .../src/components/icons/OverflowIcon.tsx | 34 + .../src/components/icons/PencilIcon.tsx | 36 + .../client/src/components/icons/PlusIcon.tsx | 36 + .../client/src/components/icons/ShareIcon.tsx | 35 + .../src/components/icons/ShieldCheckIcon.tsx | 36 + .../src/components/icons/ShieldOffIcon.tsx | 40 + .../components/icons/SidebarCollapseIcon.tsx | 37 + .../components/icons/SidebarExpandIcon.tsx | 37 + .../client/src/components/icons/StopIcon.tsx | 31 + .../src/components/icons/ThumbsDownIcon.tsx | 43 + .../src/components/icons/ThumbsUpIcon.tsx | 43 + .../client/src/components/icons/TrashIcon.tsx | 36 + .../src/components/icons/UserKeyIconIcon.tsx | 40 + .../src/components/icons/WarningIcon.tsx | 37 + .../src/components/icons/WrenchIcon.tsx | 36 + .../src/components/icons/XCircleIcon.tsx | 40 + .../client/src/components/icons/index.ts | 27 + .../client/src/components/message-actions.tsx | 196 + .../client/src/components/message-editor.tsx | 106 + .../client/src/components/message-error.tsx | 44 + .../src/components/message-oauth-error.tsx | 118 + .../src/components/message-reasoning.tsx | 26 + .../client/src/components/message.tsx | 450 ++ .../client/src/components/messages.tsx | 148 + .../src/components/multimodal-input.tsx | 382 ++ .../src/components/preview-attachment.tsx | 56 + .../src/components/sidebar-history-item.tsx | 110 + .../client/src/components/sidebar-history.tsx | 391 ++ .../client/src/components/sidebar-toggle.tsx | 38 + .../src/components/sidebar-user-nav.tsx | 108 + .../src/components/suggested-actions.tsx | 68 + .../client/src/components/theme-provider.tsx | 8 + .../client/src/components/toast.tsx | 71 + .../client/src/components/ui/alert-dialog.tsx | 134 + .../client/src/components/ui/badge.tsx | 36 + .../client/src/components/ui/button.tsx | 59 + .../client/src/components/ui/collapsible.tsx | 9 + .../client/src/components/ui/db-icon.tsx | 83 + .../src/components/ui/dropdown-menu.tsx | 188 + .../client/src/components/ui/input.tsx | 22 + .../client/src/components/ui/separator.tsx | 29 + .../client/src/components/ui/sheet.tsx | 123 + .../client/src/components/ui/shimmer.tsx | 25 + .../client/src/components/ui/sidebar.tsx | 770 +++ .../client/src/components/ui/skeleton.tsx | 15 + .../client/src/components/ui/textarea.tsx | 22 + .../client/src/components/ui/tooltip.tsx | 43 + .../src/components/visibility-selector.tsx | 1 + .../client/src/contexts/AppConfigContext.tsx | 75 + .../client/src/contexts/ChatProvider.tsx | 133 + .../client/src/contexts/SessionContext.tsx | 83 + .../client/src/hooks/use-approval.ts | 65 + .../client/src/hooks/use-chat-history.ts | 102 + .../client/src/hooks/use-chat-stream.ts | 221 + .../client/src/hooks/use-chat-visibility.ts | 48 + .../client/src/hooks/use-config.ts | 20 + .../client/src/hooks/use-messages.tsx | 37 + .../client/src/hooks/use-mobile.tsx | 21 + .../client/src/hooks/use-scroll-to-bottom.tsx | 69 + .../client/src/hooks/use-session.ts | 13 + .../client/src/hooks/useChatData.ts | 99 + .../appkit-agent/client/src/index.css | 586 ++ .../client/src/layouts/ChatLayout.tsx | 55 + .../client/src/layouts/RootLayout.tsx | 31 + .../client/src/lib/ChatTransport.ts | 40 + .../appkit-agent/client/src/lib/actions.ts | 51 + .../appkit-agent/client/src/lib/config.ts | 25 + .../appkit-agent/client/src/lib/navigation.ts | 34 + .../client/src/lib/oauth-error-utils.ts | 47 + .../appkit-agent/client/src/lib/utils.ts | 86 + integrations/appkit-agent/client/src/main.tsx | 15 + .../client/src/pages/ChatPage.tsx | 93 + .../client/src/pages/NewChatPage.tsx | 47 + .../appkit-agent/client/src/types/index.ts | 194 + .../src/types/react-syntax-highlighter.d.ts | 12 + .../appkit-agent/client/tsconfig.json | 25 + .../appkit-agent/client/tsconfig.node.json | 10 + .../appkit-agent/client/vite.config.ts | 18 + integrations/appkit-agent/package.json | 37 +- integrations/appkit-agent/pnpm-lock.yaml | 589 +- .../appkit-agent/src/chat-plugin/index.ts | 63 +- .../src/chat-ui/simple/agent-chat-message.tsx | 45 - .../src/chat-ui/simple/agent-chat-part.tsx | 46 - .../appkit-agent/src/chat-ui/simple/index.ts | 15 - .../src/chat-ui/simple/primitives/button.tsx | 59 - .../src/chat-ui/simple/primitives/card.tsx | 15 - .../src/chat-ui/simple/primitives/cn.ts | 6 - .../src/chat-ui/simple/simple-agent-chat.tsx | 86 - .../src/chat-ui/simple/styles.css | 55 - .../appkit-agent/src/chat-ui/simple/types.ts | 66 - .../src/chat-ui/simple/use-agent-chat.ts | 174 - .../appkit-agent/src/chat-ui/simple/utils.ts | 32 - .../appkit-agent/tailwind.chat-ui.config.js | 49 - integrations/appkit-agent/tsconfig.json | 6 +- integrations/appkit-agent/tsdown.config.ts | 73 +- 137 files changed, 15468 insertions(+), 1286 deletions(-) create mode 100644 integrations/appkit-agent/client/index.html create mode 100644 integrations/appkit-agent/client/package.json create mode 100644 integrations/appkit-agent/client/pnpm-lock.yaml create mode 100644 integrations/appkit-agent/client/postcss.config.js create mode 100644 integrations/appkit-agent/client/src/App.tsx create mode 100644 integrations/appkit-agent/client/src/components/ChatApp.tsx create mode 100644 integrations/appkit-agent/client/src/components/ChatComposer.tsx create mode 100644 integrations/appkit-agent/client/src/components/ChatPanel.tsx create mode 100644 integrations/appkit-agent/client/src/components/ChatSidebar.tsx create mode 100644 integrations/appkit-agent/client/src/components/ChatSidebarItem.tsx create mode 100644 integrations/appkit-agent/client/src/components/DatabricksLogo.tsx create mode 100644 integrations/appkit-agent/client/src/components/animation-assistant-icon.tsx create mode 100644 integrations/appkit-agent/client/src/components/app-sidebar.tsx create mode 100644 integrations/appkit-agent/client/src/components/chat-header.tsx create mode 100644 integrations/appkit-agent/client/src/components/chat.tsx create mode 100644 integrations/appkit-agent/client/src/components/data-stream-provider.tsx create mode 100644 integrations/appkit-agent/client/src/components/databricks-message-citation.tsx create mode 100644 integrations/appkit-agent/client/src/components/databricks-message-part-transformers.ts create mode 100644 integrations/appkit-agent/client/src/components/elements/actions.tsx create mode 100644 integrations/appkit-agent/client/src/components/elements/code-block.tsx create mode 100644 integrations/appkit-agent/client/src/components/elements/conversation.tsx create mode 100644 integrations/appkit-agent/client/src/components/elements/loader.tsx create mode 100644 integrations/appkit-agent/client/src/components/elements/mcp-tool.tsx create mode 100644 integrations/appkit-agent/client/src/components/elements/message.tsx create mode 100644 integrations/appkit-agent/client/src/components/elements/prompt-input.tsx create mode 100644 integrations/appkit-agent/client/src/components/elements/reasoning.tsx create mode 100644 integrations/appkit-agent/client/src/components/elements/response.tsx create mode 100644 integrations/appkit-agent/client/src/components/elements/suggestion.tsx create mode 100644 integrations/appkit-agent/client/src/components/elements/tool.tsx create mode 100644 integrations/appkit-agent/client/src/components/greeting.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/ArrowUpIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/CheckCircleIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/CheckIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/ChevronDownIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/ChevronUpIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/CircleOutlineIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/ClockIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/CloudOffIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/CopyIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/LightbulbIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/NewChatIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/OverflowIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/PencilIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/PlusIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/ShareIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/ShieldCheckIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/ShieldOffIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/SidebarCollapseIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/SidebarExpandIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/StopIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/ThumbsDownIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/ThumbsUpIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/TrashIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/UserKeyIconIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/WarningIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/WrenchIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/XCircleIcon.tsx create mode 100644 integrations/appkit-agent/client/src/components/icons/index.ts create mode 100644 integrations/appkit-agent/client/src/components/message-actions.tsx create mode 100644 integrations/appkit-agent/client/src/components/message-editor.tsx create mode 100644 integrations/appkit-agent/client/src/components/message-error.tsx create mode 100644 integrations/appkit-agent/client/src/components/message-oauth-error.tsx create mode 100644 integrations/appkit-agent/client/src/components/message-reasoning.tsx create mode 100644 integrations/appkit-agent/client/src/components/message.tsx create mode 100644 integrations/appkit-agent/client/src/components/messages.tsx create mode 100644 integrations/appkit-agent/client/src/components/multimodal-input.tsx create mode 100644 integrations/appkit-agent/client/src/components/preview-attachment.tsx create mode 100644 integrations/appkit-agent/client/src/components/sidebar-history-item.tsx create mode 100644 integrations/appkit-agent/client/src/components/sidebar-history.tsx create mode 100644 integrations/appkit-agent/client/src/components/sidebar-toggle.tsx create mode 100644 integrations/appkit-agent/client/src/components/sidebar-user-nav.tsx create mode 100644 integrations/appkit-agent/client/src/components/suggested-actions.tsx create mode 100644 integrations/appkit-agent/client/src/components/theme-provider.tsx create mode 100644 integrations/appkit-agent/client/src/components/toast.tsx create mode 100644 integrations/appkit-agent/client/src/components/ui/alert-dialog.tsx create mode 100644 integrations/appkit-agent/client/src/components/ui/badge.tsx create mode 100644 integrations/appkit-agent/client/src/components/ui/button.tsx create mode 100644 integrations/appkit-agent/client/src/components/ui/collapsible.tsx create mode 100644 integrations/appkit-agent/client/src/components/ui/db-icon.tsx create mode 100644 integrations/appkit-agent/client/src/components/ui/dropdown-menu.tsx create mode 100644 integrations/appkit-agent/client/src/components/ui/input.tsx create mode 100644 integrations/appkit-agent/client/src/components/ui/separator.tsx create mode 100644 integrations/appkit-agent/client/src/components/ui/sheet.tsx create mode 100644 integrations/appkit-agent/client/src/components/ui/shimmer.tsx create mode 100644 integrations/appkit-agent/client/src/components/ui/sidebar.tsx create mode 100644 integrations/appkit-agent/client/src/components/ui/skeleton.tsx create mode 100644 integrations/appkit-agent/client/src/components/ui/textarea.tsx create mode 100644 integrations/appkit-agent/client/src/components/ui/tooltip.tsx create mode 100644 integrations/appkit-agent/client/src/components/visibility-selector.tsx create mode 100644 integrations/appkit-agent/client/src/contexts/AppConfigContext.tsx create mode 100644 integrations/appkit-agent/client/src/contexts/ChatProvider.tsx create mode 100644 integrations/appkit-agent/client/src/contexts/SessionContext.tsx create mode 100644 integrations/appkit-agent/client/src/hooks/use-approval.ts create mode 100644 integrations/appkit-agent/client/src/hooks/use-chat-history.ts create mode 100644 integrations/appkit-agent/client/src/hooks/use-chat-stream.ts create mode 100644 integrations/appkit-agent/client/src/hooks/use-chat-visibility.ts create mode 100644 integrations/appkit-agent/client/src/hooks/use-config.ts create mode 100644 integrations/appkit-agent/client/src/hooks/use-messages.tsx create mode 100644 integrations/appkit-agent/client/src/hooks/use-mobile.tsx create mode 100644 integrations/appkit-agent/client/src/hooks/use-scroll-to-bottom.tsx create mode 100644 integrations/appkit-agent/client/src/hooks/use-session.ts create mode 100644 integrations/appkit-agent/client/src/hooks/useChatData.ts create mode 100644 integrations/appkit-agent/client/src/index.css create mode 100644 integrations/appkit-agent/client/src/layouts/ChatLayout.tsx create mode 100644 integrations/appkit-agent/client/src/layouts/RootLayout.tsx create mode 100644 integrations/appkit-agent/client/src/lib/ChatTransport.ts create mode 100644 integrations/appkit-agent/client/src/lib/actions.ts create mode 100644 integrations/appkit-agent/client/src/lib/config.ts create mode 100644 integrations/appkit-agent/client/src/lib/navigation.ts create mode 100644 integrations/appkit-agent/client/src/lib/oauth-error-utils.ts create mode 100644 integrations/appkit-agent/client/src/lib/utils.ts create mode 100644 integrations/appkit-agent/client/src/main.tsx create mode 100644 integrations/appkit-agent/client/src/pages/ChatPage.tsx create mode 100644 integrations/appkit-agent/client/src/pages/NewChatPage.tsx create mode 100644 integrations/appkit-agent/client/src/types/index.ts create mode 100644 integrations/appkit-agent/client/src/types/react-syntax-highlighter.d.ts create mode 100644 integrations/appkit-agent/client/tsconfig.json create mode 100644 integrations/appkit-agent/client/tsconfig.node.json create mode 100644 integrations/appkit-agent/client/vite.config.ts delete mode 100644 integrations/appkit-agent/src/chat-ui/simple/agent-chat-message.tsx delete mode 100644 integrations/appkit-agent/src/chat-ui/simple/agent-chat-part.tsx delete mode 100644 integrations/appkit-agent/src/chat-ui/simple/index.ts delete mode 100644 integrations/appkit-agent/src/chat-ui/simple/primitives/button.tsx delete mode 100644 integrations/appkit-agent/src/chat-ui/simple/primitives/card.tsx delete mode 100644 integrations/appkit-agent/src/chat-ui/simple/primitives/cn.ts delete mode 100644 integrations/appkit-agent/src/chat-ui/simple/simple-agent-chat.tsx delete mode 100644 integrations/appkit-agent/src/chat-ui/simple/styles.css delete mode 100644 integrations/appkit-agent/src/chat-ui/simple/types.ts delete mode 100644 integrations/appkit-agent/src/chat-ui/simple/use-agent-chat.ts delete mode 100644 integrations/appkit-agent/src/chat-ui/simple/utils.ts delete mode 100644 integrations/appkit-agent/tailwind.chat-ui.config.js diff --git a/integrations/appkit-agent/README.md b/integrations/appkit-agent/README.md index 8b8e06e74..edf985040 100644 --- a/integrations/appkit-agent/README.md +++ b/integrations/appkit-agent/README.md @@ -48,7 +48,7 @@ const app = await createApp({ }); ``` -### Agent + Chat +### Agent + Chat with bundled UI ```typescript import { createApp, server } from "@databricks/appkit"; @@ -56,7 +56,7 @@ import { agent, chat } from "@databricks/appkit-agent"; await createApp({ plugins: [ - server({ autoStart: true }), + server({ autoStart: true, staticPath: chat.staticAssetsPath }), agent({ model: "databricks-claude-sonnet-4-5", systemPrompt: "You are a helpful assistant.", @@ -68,7 +68,7 @@ await createApp({ }); ``` -The agent plugin registers `POST /api/agent` (OpenAI Responses API format with SSE streaming). The chat plugin registers routes under `/api/chat/` for streaming chat, history, feedback, and more. +This starts a server with the agent backend, chat API, and a pre-built chat UI served at `/`. The agent plugin registers `POST /api/agent` (OpenAI Responses API format with SSE streaming). The chat plugin registers routes under `/api/chat/` for streaming chat, history, feedback, and more. ## Environment Variables @@ -319,6 +319,20 @@ All routes are mounted under `/api/chat/`. | `DELETE` | `/:id` | required+ACL | Delete a chat | | `POST` | `/` | required | Main chat handler (streaming) | +## Bundled Chat UI + +The package includes a pre-built React chat application in `dist/chat-client/`. It provides a full-featured chat experience with conversation history sidebar, message editing, code syntax highlighting, MCP tool approval, file attachments, reasoning display, and theme toggle. + +### Serving the UI + +Pass `chat.staticAssetsPath` to the server plugin's `staticPath` option: + +```typescript +server({ staticPath: chat.staticAssetsPath }) +``` + +The chat UI communicates with the chat plugin's `/api/chat/` endpoints automatically. No additional configuration is needed. + ## API Reference ### Exports diff --git a/integrations/appkit-agent/client/index.html b/integrations/appkit-agent/client/index.html new file mode 100644 index 000000000..3a38736b1 --- /dev/null +++ b/integrations/appkit-agent/client/index.html @@ -0,0 +1,16 @@ + + + + + + + + Databricks Chat + + + + +
+ + + diff --git a/integrations/appkit-agent/client/package.json b/integrations/appkit-agent/client/package.json new file mode 100644 index 000000000..14f160eb9 --- /dev/null +++ b/integrations/appkit-agent/client/package.json @@ -0,0 +1,64 @@ +{ + "name": "@databricks/chat-client", + "version": "0.1.0", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "browser": { + "child_process": false, + "crypto": false, + "fs": false, + "fs/promises": false, + "path": false, + "url": false, + "vm": false, + "ws": false + }, + "dependencies": { + "@ai-sdk/react": "^3.0.59", + "@radix-ui/react-alert-dialog": "^1.1.2", + "@radix-ui/react-collapsible": "^1.1.12", + "@radix-ui/react-dialog": "^1.1.2", + "@radix-ui/react-dropdown-menu": "^2.1.2", + "@radix-ui/react-separator": "^1.1.0", + "@radix-ui/react-slot": "^1.1.2", + "@radix-ui/react-tooltip": "^1.1.3", + "@radix-ui/react-use-controllable-state": "^1.2.2", + "ai": "^6.0.70", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "date-fns": "^4.1.0", + "fast-deep-equal": "^3.1.3", + "framer-motion": "^11.3.19", + "lucide-react": "^0.446.0", + "next-themes": "^0.4.6", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.22.0", + "react-syntax-highlighter": "^15.6.6", + "sonner": "^1.5.0", + "streamdown": "^1.4.0", + "swr": "^2.2.5", + "tailwind-merge": "^2.5.2", + "use-stick-to-bottom": "^1.1.1", + "usehooks-ts": "^3.1.0", + "zod": "^4.3.5" + }, + "devDependencies": { + "@tailwindcss/postcss": "^4.1.13", + "@tailwindcss/typography": "^0.5.19", + "@types/react": "^18", + "@types/react-dom": "^18", + "@types/react-syntax-highlighter": "^15.5.13", + "@vitejs/plugin-react": "^4.2.1", + "postcss": "^8", + "tailwindcss": "^4.1.13", + "tailwindcss-animate": "^1.0.7", + "typescript": "^5.9.3", + "vite": "npm:rolldown-vite@latest" + } +} diff --git a/integrations/appkit-agent/client/pnpm-lock.yaml b/integrations/appkit-agent/client/pnpm-lock.yaml new file mode 100644 index 000000000..b379d34cd --- /dev/null +++ b/integrations/appkit-agent/client/pnpm-lock.yaml @@ -0,0 +1,4952 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@ai-sdk/react': + specifier: ^3.0.59 + version: 3.0.136(react@18.3.1)(zod@4.3.6) + '@radix-ui/react-alert-dialog': + specifier: ^1.1.2 + version: 1.1.15(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collapsible': + specifier: ^1.1.12 + version: 1.1.12(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dialog': + specifier: ^1.1.2 + version: 1.1.15(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dropdown-menu': + specifier: ^2.1.2 + version: 2.1.16(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-separator': + specifier: ^1.1.0 + version: 1.1.8(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': + specifier: ^1.1.2 + version: 1.2.4(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-tooltip': + specifier: ^1.1.3 + version: 1.2.8(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': + specifier: ^1.2.2 + version: 1.2.2(@types/react@18.3.28)(react@18.3.1) + ai: + specifier: ^6.0.70 + version: 6.0.134(zod@4.3.6) + class-variance-authority: + specifier: ^0.7.0 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + date-fns: + specifier: ^4.1.0 + version: 4.1.0 + fast-deep-equal: + specifier: ^3.1.3 + version: 3.1.3 + framer-motion: + specifier: ^11.3.19 + version: 11.18.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + lucide-react: + specifier: ^0.446.0 + version: 0.446.0(react@18.3.1) + next-themes: + specifier: ^0.4.6 + version: 0.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: + specifier: ^18.2.0 + version: 18.3.1 + react-dom: + specifier: ^18.2.0 + version: 18.3.1(react@18.3.1) + react-router-dom: + specifier: ^6.22.0 + version: 6.30.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-syntax-highlighter: + specifier: ^15.6.6 + version: 15.6.6(react@18.3.1) + sonner: + specifier: ^1.5.0 + version: 1.7.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + streamdown: + specifier: ^1.4.0 + version: 1.6.11(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(react@18.3.1) + swr: + specifier: ^2.2.5 + version: 2.4.1(react@18.3.1) + tailwind-merge: + specifier: ^2.5.2 + version: 2.6.1 + use-stick-to-bottom: + specifier: ^1.1.1 + version: 1.1.3(react@18.3.1) + usehooks-ts: + specifier: ^3.1.0 + version: 3.1.1(react@18.3.1) + zod: + specifier: ^4.3.5 + version: 4.3.6 + devDependencies: + '@tailwindcss/postcss': + specifier: ^4.1.13 + version: 4.2.2 + '@tailwindcss/typography': + specifier: ^0.5.19 + version: 0.5.19(tailwindcss@4.2.2) + '@types/react': + specifier: ^18 + version: 18.3.28 + '@types/react-dom': + specifier: ^18 + version: 18.3.7(@types/react@18.3.28) + '@types/react-syntax-highlighter': + specifier: ^15.5.13 + version: 15.5.13 + '@vitejs/plugin-react': + specifier: ^4.2.1 + version: 4.7.0(rolldown-vite@7.3.1(jiti@2.6.1)) + postcss: + specifier: ^8 + version: 8.5.8 + tailwindcss: + specifier: ^4.1.13 + version: 4.2.2 + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@4.2.2) + typescript: + specifier: ^5.9.3 + version: 5.9.3 + vite: + specifier: npm:rolldown-vite@latest + version: rolldown-vite@7.3.1(jiti@2.6.1) + +packages: + + '@ai-sdk/gateway@3.0.77': + resolution: {integrity: sha512-UdwIG2H2YMuntJQ5L+EmED5XiwnlvDT3HOmKfVFxR4Nq/RSLFA/HcchhwfNXHZ5UJjyuL2VO0huLbWSZ9ijemQ==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider-utils@4.0.21': + resolution: {integrity: sha512-MtFUYI1/8mgDvRmaBDjbLJPFFrMG777AvSgyIFQtZHIMzm88R/12vYBBpnk7pfiWLFE1DSZzY4WDYzGbKAcmiw==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + '@ai-sdk/provider@3.0.8': + resolution: {integrity: sha512-oGMAgGoQdBXbZqNG0Ze56CHjDZ1IDYOwGYxYjO5KLSlz5HiNQ9udIXsPZ61VWaHGZ5XW/jyjmr6t2xz2jGVwbQ==} + engines: {node: '>=18'} + + '@ai-sdk/react@3.0.136': + resolution: {integrity: sha512-9+KEgtLeOJZCqAW0s7HqiuXs17d6iZ4QKE4z1Bl1QR6V+gjtsq4Dp+Al8mcx76XkaB1vjtGjDg8lLtbJ4X+OEw==} + engines: {node: '>=18'} + peerDependencies: + react: ^18 || ~19.0.1 || ~19.1.2 || ^19.2.1 + + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + + '@antfu/install-pkg@1.1.0': + resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} + + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-transform-react-jsx-self@7.27.1': + resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.27.1': + resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + + '@braintree/sanitize-url@7.1.2': + resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==} + + '@chevrotain/cst-dts-gen@11.1.2': + resolution: {integrity: sha512-XTsjvDVB5nDZBQB8o0o/0ozNelQtn2KrUVteIHSlPd2VAV2utEb6JzyCJaJ8tGxACR4RiBNWy5uYUHX2eji88Q==} + + '@chevrotain/gast@11.1.2': + resolution: {integrity: sha512-Z9zfXR5jNZb1Hlsd/p+4XWeUFugrHirq36bKzPWDSIacV+GPSVXdk+ahVWZTwjhNwofAWg/sZg58fyucKSQx5g==} + + '@chevrotain/regexp-to-ast@11.1.2': + resolution: {integrity: sha512-nMU3Uj8naWer7xpZTYJdxbAs6RIv/dxYzkYU8GSwgUtcAAlzjcPfX1w+RKRcYG8POlzMeayOQ/znfwxEGo5ulw==} + + '@chevrotain/types@11.1.2': + resolution: {integrity: sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw==} + + '@chevrotain/utils@11.1.2': + resolution: {integrity: sha512-4mudFAQ6H+MqBTfqLmU7G1ZwRzCLfJEooL/fsF6rCX5eePMbGhoy5n4g+G4vlh2muDcsCTJtL+uKbOzWxs5LHA==} + + '@emnapi/core@1.9.1': + resolution: {integrity: sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==} + + '@emnapi/runtime@1.9.1': + resolution: {integrity: sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==} + + '@emnapi/wasi-threads@1.2.0': + resolution: {integrity: sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==} + + '@floating-ui/core@1.7.5': + resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} + + '@floating-ui/dom@1.7.6': + resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==} + + '@floating-ui/react-dom@2.1.8': + resolution: {integrity: sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.11': + resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@3.1.0': + resolution: {integrity: sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@mermaid-js/parser@1.0.1': + resolution: {integrity: sha512-opmV19kN1JsK0T6HhhokHpcVkqKpF+x2pPDKKM2ThHtZAB5F4PROopk0amuVYK5qMrIA4erzpNm8gmPNJgMDxQ==} + + '@napi-rs/wasm-runtime@1.1.1': + resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} + + '@opentelemetry/api@1.9.0': + resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} + engines: {node: '>=8.0.0'} + + '@oxc-project/runtime@0.101.0': + resolution: {integrity: sha512-t3qpfVZIqSiLQ5Kqt/MC4Ge/WCOGrrcagAdzTcDaggupjiGxUx4nJF2v6wUCXWSzWHn5Ns7XLv13fCJEwCOERQ==} + engines: {node: ^20.19.0 || >=22.12.0} + + '@oxc-project/types@0.101.0': + resolution: {integrity: sha512-nuFhqlUzJX+gVIPPfuE6xurd4lST3mdcWOhyK/rZO0B9XWMKm79SuszIQEnSMmmDhq1DC8WWVYGVd+6F93o1gQ==} + + '@radix-ui/primitive@1.1.3': + resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} + + '@radix-ui/react-alert-dialog@1.1.15': + resolution: {integrity: sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-arrow@1.1.7': + resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-collapsible@1.1.12': + resolution: {integrity: sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-collection@1.1.7': + resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context@1.1.2': + resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dialog@1.1.15': + resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-direction@1.1.1': + resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dismissable-layer@1.1.11': + resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-dropdown-menu@2.1.16': + resolution: {integrity: sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-focus-guards@1.1.3': + resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.1.7': + resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-id@1.1.1': + resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-menu@2.1.16': + resolution: {integrity: sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-popper@1.2.8': + resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-portal@1.1.9': + resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-presence@1.1.5': + resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.1.3': + resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-primitive@2.1.4': + resolution: {integrity: sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-roving-focus@1.1.11': + resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-separator@1.1.8': + resolution: {integrity: sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.2.3': + resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-slot@1.2.4': + resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-tooltip@1.2.8': + resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.1': + resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.2.2': + resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-effect-event@0.0.2': + resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-escape-keydown@1.1.1': + resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.1': + resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-rect@1.1.1': + resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-size@1.1.1': + resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-visually-hidden@1.2.3': + resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/rect@1.1.1': + resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + + '@remix-run/router@1.23.2': + resolution: {integrity: sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==} + engines: {node: '>=14.0.0'} + + '@rolldown/binding-android-arm64@1.0.0-beta.53': + resolution: {integrity: sha512-Ok9V8o7o6YfSdTTYA/uHH30r3YtOxLD6G3wih/U9DO0ucBBFq8WPt/DslU53OgfteLRHITZny9N/qCUxMf9kjQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.0.0-beta.53': + resolution: {integrity: sha512-yIsKqMz0CtRnVa6x3Pa+mzTihr4Ty+Z6HfPbZ7RVbk1Uxnco4+CUn7Qbm/5SBol1JD/7nvY8rphAgyAi7Lj6Vg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.0-beta.53': + resolution: {integrity: sha512-GTXe+mxsCGUnJOFMhfGWmefP7Q9TpYUseHvhAhr21nCTgdS8jPsvirb0tJwM3lN0/u/cg7bpFNa16fQrjKrCjQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.0.0-beta.53': + resolution: {integrity: sha512-9Tmp7bBvKqyDkMcL4e089pH3RsjD3SUungjmqWtyhNOxoQMh0fSmINTyYV8KXtE+JkxYMPWvnEt+/mfpVCkk8w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.53': + resolution: {integrity: sha512-a1y5fiB0iovuzdbjUxa7+Zcvgv+mTmlGGC4XydVIsyl48eoxgaYkA3l9079hyTyhECsPq+mbr0gVQsFU11OJAQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.53': + resolution: {integrity: sha512-bpIGX+ov9PhJYV+wHNXl9rzq4F0QvILiURn0y0oepbQx+7stmQsKA0DhPGwmhfvF856wq+gbM8L92SAa/CBcLg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.53': + resolution: {integrity: sha512-bGe5EBB8FVjHBR1mOLOPEFg1Lp3//7geqWkU5NIhxe+yH0W8FVrQ6WRYOap4SUTKdklD/dC4qPLREkMMQ855FA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.53': + resolution: {integrity: sha512-qL+63WKVQs1CMvFedlPt0U9PiEKJOAL/bsHMKUDS6Vp2Q+YAv/QLPu8rcvkfIMvQ0FPU2WL0aX4eWwF6e/GAnA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.0.0-beta.53': + resolution: {integrity: sha512-VGl9JIGjoJh3H8Mb+7xnVqODajBmrdOOb9lxWXdcmxyI+zjB2sux69br0hZJDTyLJfvBoYm439zPACYbCjGRmw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.0.0-beta.53': + resolution: {integrity: sha512-B4iIserJXuSnNzA5xBLFUIjTfhNy7d9sq4FUMQY3GhQWGVhS2RWWzzDnkSU6MUt7/aHUrep0CdQfXUJI9D3W7A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.53': + resolution: {integrity: sha512-BUjAEgpABEJXilGq/BPh7jeU3WAJ5o15c1ZEgHaDWSz3LB881LQZnbNJHmUiM4d1JQWMYYyR1Y490IBHi2FPJg==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.53': + resolution: {integrity: sha512-s27uU7tpCWSjHBnxyVXHt3rMrQdJq5MHNv3BzsewCIroIw3DJFjMH1dzCPPMUFxnh1r52Nf9IJ/eWp6LDoyGcw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.53': + resolution: {integrity: sha512-cjWL/USPJ1g0en2htb4ssMjIycc36RvdQAx1WlXnS6DpULswiUTVXPDesTifSKYSyvx24E0YqQkEm0K/M2Z/AA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.0-beta.27': + resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} + + '@rolldown/pluginutils@1.0.0-beta.53': + resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==} + + '@shikijs/core@3.23.0': + resolution: {integrity: sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA==} + + '@shikijs/engine-javascript@3.23.0': + resolution: {integrity: sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA==} + + '@shikijs/engine-oniguruma@3.23.0': + resolution: {integrity: sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==} + + '@shikijs/langs@3.23.0': + resolution: {integrity: sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==} + + '@shikijs/themes@3.23.0': + resolution: {integrity: sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==} + + '@shikijs/types@3.23.0': + resolution: {integrity: sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@tailwindcss/node@4.2.2': + resolution: {integrity: sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==} + + '@tailwindcss/oxide-android-arm64@4.2.2': + resolution: {integrity: sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.2.2': + resolution: {integrity: sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.2.2': + resolution: {integrity: sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.2.2': + resolution: {integrity: sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2': + resolution: {integrity: sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==} + engines: {node: '>= 20'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.2.2': + resolution: {integrity: sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@tailwindcss/oxide-linux-arm64-musl@4.2.2': + resolution: {integrity: sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@tailwindcss/oxide-linux-x64-gnu@4.2.2': + resolution: {integrity: sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@tailwindcss/oxide-linux-x64-musl@4.2.2': + resolution: {integrity: sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@tailwindcss/oxide-wasm32-wasi@4.2.2': + resolution: {integrity: sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.2.2': + resolution: {integrity: sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.2.2': + resolution: {integrity: sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==} + engines: {node: '>= 20'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.2.2': + resolution: {integrity: sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==} + engines: {node: '>= 20'} + + '@tailwindcss/postcss@4.2.2': + resolution: {integrity: sha512-n4goKQbW8RVXIbNKRB/45LzyUqN451deQK0nzIeauVEqjlI49slUlgKYJM2QyUzap/PcpnS7kzSUmPb1sCRvYQ==} + + '@tailwindcss/typography@0.5.19': + resolution: {integrity: sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1' + + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + + '@types/d3-array@3.2.2': + resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} + + '@types/d3-axis@3.0.6': + resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==} + + '@types/d3-brush@3.0.6': + resolution: {integrity: sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==} + + '@types/d3-chord@3.0.6': + resolution: {integrity: sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==} + + '@types/d3-color@3.1.3': + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + + '@types/d3-contour@3.0.6': + resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==} + + '@types/d3-delaunay@6.0.4': + resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==} + + '@types/d3-dispatch@3.0.7': + resolution: {integrity: sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==} + + '@types/d3-drag@3.0.7': + resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==} + + '@types/d3-dsv@3.0.7': + resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==} + + '@types/d3-ease@3.0.2': + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + + '@types/d3-fetch@3.0.7': + resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==} + + '@types/d3-force@3.0.10': + resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==} + + '@types/d3-format@3.0.4': + resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==} + + '@types/d3-geo@3.1.0': + resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==} + + '@types/d3-hierarchy@3.1.7': + resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==} + + '@types/d3-interpolate@3.0.4': + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + + '@types/d3-path@3.1.1': + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} + + '@types/d3-polygon@3.0.2': + resolution: {integrity: sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==} + + '@types/d3-quadtree@3.0.6': + resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==} + + '@types/d3-random@3.0.3': + resolution: {integrity: sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==} + + '@types/d3-scale-chromatic@3.1.0': + resolution: {integrity: sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==} + + '@types/d3-scale@4.0.9': + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} + + '@types/d3-selection@3.0.11': + resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==} + + '@types/d3-shape@3.1.8': + resolution: {integrity: sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==} + + '@types/d3-time-format@4.0.3': + resolution: {integrity: sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==} + + '@types/d3-time@3.0.4': + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + + '@types/d3-timer@3.0.2': + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + + '@types/d3-transition@3.0.9': + resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==} + + '@types/d3-zoom@3.0.8': + resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==} + + '@types/d3@7.4.3': + resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==} + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/geojson@7946.0.16': + resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==} + + '@types/hast@2.3.10': + resolution: {integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/katex@0.16.8': + resolution: {integrity: sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/prop-types@15.7.15': + resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} + + '@types/react-dom@18.3.7': + resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==} + peerDependencies: + '@types/react': ^18.0.0 + + '@types/react-syntax-highlighter@15.5.13': + resolution: {integrity: sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA==} + + '@types/react@18.3.28': + resolution: {integrity: sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==} + + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + '@upsetjs/venn.js@2.0.0': + resolution: {integrity: sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==} + + '@vercel/oidc@3.1.0': + resolution: {integrity: sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w==} + engines: {node: '>= 20'} + + '@vitejs/plugin-react@4.7.0': + resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + ai@6.0.134: + resolution: {integrity: sha512-YalNEaavld/kE444gOcsMKXdVVRGEe0SK77fAFcWYcqLg+a7xKnEet8bdfrEAJTfnMjj01rhgrIL10903w1a5Q==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4.1.8 + + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + baseline-browser-mapping@2.10.10: + resolution: {integrity: sha512-sUoJ3IMxx4AyRqO4MLeHlnGDkyXRoUG0/AI9fjK+vS72ekpV0yWVY7O0BVjmBcRtkNcsAO2QDZ4tdKKGoI6YaQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + caniuse-lite@1.0.30001781: + resolution: {integrity: sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@1.1.4: + resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@1.2.4: + resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@1.1.4: + resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + chevrotain-allstar@0.3.1: + resolution: {integrity: sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==} + peerDependencies: + chevrotain: ^11.0.0 + + chevrotain@11.1.2: + resolution: {integrity: sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==} + + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + comma-separated-tokens@1.0.8: + resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cose-base@1.0.3: + resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} + + cose-base@2.2.0: + resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + cytoscape-cose-bilkent@4.1.0: + resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape-fcose@2.2.0: + resolution: {integrity: sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape@3.33.1: + resolution: {integrity: sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==} + engines: {node: '>=0.10'} + + d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-axis@3.0.0: + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + engines: {node: '>=12'} + + d3-brush@3.0.0: + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} + engines: {node: '>=12'} + + d3-chord@3.0.1: + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-contour@4.0.2: + resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} + engines: {node: '>=12'} + + d3-delaunay@6.0.4: + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + engines: {node: '>=12'} + + d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + + d3-drag@3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + engines: {node: '>=12'} + + d3-dsv@3.0.1: + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + engines: {node: '>=12'} + hasBin: true + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-fetch@3.0.1: + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + engines: {node: '>=12'} + + d3-force@3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + engines: {node: '>=12'} + + d3-format@3.1.2: + resolution: {integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==} + engines: {node: '>=12'} + + d3-geo@3.1.1: + resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} + engines: {node: '>=12'} + + d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@1.0.9: + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-polygon@3.0.1: + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} + engines: {node: '>=12'} + + d3-quadtree@3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + engines: {node: '>=12'} + + d3-random@3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + + d3-sankey@0.12.3: + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} + + d3-scale-chromatic@3.1.0: + resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + + d3-shape@1.3.7: + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + + d3-transition@3.0.1: + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 + + d3-zoom@3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + engines: {node: '>=12'} + + d3@7.9.0: + resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} + engines: {node: '>=12'} + + dagre-d3-es@7.0.14: + resolution: {integrity: sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg==} + + date-fns@4.1.0: + resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} + + dayjs@1.11.20: + resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + + delaunator@5.1.0: + resolution: {integrity: sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + dompurify@3.3.3: + resolution: {integrity: sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA==} + + electron-to-chromium@1.5.321: + resolution: {integrity: sha512-L2C7Q279W2D/J4PLZLk7sebOILDSWos7bMsMNN06rK482umHUrh/3lM8G7IlHFOYip2oAg5nha1rCMxr/rs6ZQ==} + + enhanced-resolve@5.20.1: + resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} + engines: {node: '>=10.13.0'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + eventsource-parser@3.0.6: + resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} + engines: {node: '>=18.0.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fault@1.0.4: + resolution: {integrity: sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + format@0.2.2: + resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} + engines: {node: '>=0.4.x'} + + framer-motion@11.18.2: + resolution: {integrity: sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-east-asian-width@1.5.0: + resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} + engines: {node: '>=18'} + + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + hachure-fill@0.5.2: + resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} + + hast-util-from-dom@5.0.1: + resolution: {integrity: sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==} + + hast-util-from-html-isomorphic@2.0.0: + resolution: {integrity: sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==} + + hast-util-from-html@2.0.3: + resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} + + hast-util-from-parse5@8.0.3: + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + + hast-util-is-element@3.0.0: + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + + hast-util-parse-selector@2.2.5: + resolution: {integrity: sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==} + + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + + hast-util-raw@9.1.0: + resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} + + hast-util-sanitize@5.0.2: + resolution: {integrity: sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==} + + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-to-parse5@8.0.1: + resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==} + + hast-util-to-text@4.0.2: + resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hast@1.0.0: + resolution: {integrity: sha512-vFUqlRV5C+xqP76Wwq2SrM0kipnmpxJm7OfvVXpB35Fp+Fn4MV+ozr+JZr5qFvyR1q/U+Foim2x+3P+x9S1PLA==} + deprecated: Renamed to rehype + + hastscript@6.0.0: + resolution: {integrity: sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==} + + hastscript@9.0.1: + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + + highlight.js@10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + + highlightjs-vue@1.0.0: + resolution: {integrity: sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA==} + + html-url-attributes@3.0.1: + resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + inline-style-parser@0.2.7: + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + + internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + + is-alphabetical@1.0.4: + resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@1.0.4: + resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-decimal@1.0.4: + resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-hexadecimal@1.0.4: + resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + katex@0.16.40: + resolution: {integrity: sha512-1DJcK/L05k1Y9Gf7wMcyuqFOL6BiY3vY0CFcAM/LPRN04NALxcl6u7lOWNsp3f/bCHWxigzQl6FbR95XJ4R84Q==} + hasBin: true + + khroma@2.1.0: + resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} + + langium@4.2.1: + resolution: {integrity: sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ==} + engines: {node: '>=20.10.0', npm: '>=10.2.3'} + + layout-base@1.0.2: + resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} + + layout-base@2.0.1: + resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} + + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + + lodash-es@4.17.23: + resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==} + + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lowlight@1.20.0: + resolution: {integrity: sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lucide-react@0.446.0: + resolution: {integrity: sha512-BU7gy8MfBMqvEdDPH79VhOXSEgyG8TSPOKWaExWGCQVqnGH7wGgDngPbofu+KdtVjPQBWbEmnfMTq90CTiiDRg==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc + + lucide-react@0.542.0: + resolution: {integrity: sha512-w3hD8/SQB7+lzU2r4VdFyzzOzKnUjTZIF/MQJGSSvni7Llewni4vuViRppfRAa2guOsY5k4jZyxw/i9DQHv+dw==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + marked@16.4.2: + resolution: {integrity: sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==} + engines: {node: '>= 20'} + hasBin: true + + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.3: + resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-math@3.0.0: + resolution: {integrity: sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mermaid@11.13.0: + resolution: {integrity: sha512-fEnci+Immw6lKMFI8sqzjlATTyjLkRa6axrEgLV2yHTfv8r+h1wjFbV6xeRtd4rUV1cS4EpR9rwp3Rci7TRWDw==} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-cjk-friendly-gfm-strikethrough@1.2.3: + resolution: {integrity: sha512-gSPnxgHDDqXYOBvQRq6lerrq9mjDhdtKn+7XETuXjxWcL62yZEfUdA28Ml1I2vDIPfAOIKLa0h2XDSGkInGHFQ==} + engines: {node: '>=16'} + peerDependencies: + micromark: ^4.0.0 + micromark-util-types: ^2.0.0 + peerDependenciesMeta: + micromark-util-types: + optional: true + + micromark-extension-cjk-friendly-util@2.1.1: + resolution: {integrity: sha512-egs6+12JU2yutskHY55FyR48ZiEcFOJFyk9rsiyIhcJ6IvWB6ABBqVrBw8IobqJTDZ/wdSr9eoXDPb5S2nW1bg==} + engines: {node: '>=16'} + peerDependencies: + micromark-util-types: '*' + peerDependenciesMeta: + micromark-util-types: + optional: true + + micromark-extension-cjk-friendly@1.2.3: + resolution: {integrity: sha512-gRzVLUdjXBLX6zNPSnHGDoo+ZTp5zy+MZm0g3sv+3chPXY7l9gW+DnrcHcZh/jiPR6MjPKO4AEJNp4Aw6V9z5Q==} + engines: {node: '>=16'} + peerDependencies: + micromark: ^4.0.0 + micromark-util-types: ^2.0.0 + peerDependenciesMeta: + micromark-util-types: + optional: true + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-extension-math@3.1.0: + resolution: {integrity: sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + mlly@1.8.2: + resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} + + motion-dom@11.18.1: + resolution: {integrity: sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw==} + + motion-utils@11.18.1: + resolution: {integrity: sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + next-themes@0.4.6: + resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} + peerDependencies: + react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + + node-releases@2.0.36: + resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==} + + oniguruma-parser@0.12.1: + resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} + + oniguruma-to-es@4.3.5: + resolution: {integrity: sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ==} + + package-manager-detector@1.6.0: + resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + + parse-entities@2.0.0: + resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + + path-data-parser@0.1.0: + resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pkg-types@1.3.1: + resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + + points-on-curve@0.2.0: + resolution: {integrity: sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==} + + points-on-path@0.2.1: + resolution: {integrity: sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==} + + postcss-selector-parser@6.0.10: + resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} + engines: {node: '>=4'} + + postcss@8.5.8: + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + engines: {node: ^10 || ^12 || >=14} + + prismjs@1.27.0: + resolution: {integrity: sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==} + engines: {node: '>=6'} + + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} + engines: {node: '>=6'} + + property-information@5.6.0: + resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==} + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react-refresh@0.17.0: + resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} + engines: {node: '>=0.10.0'} + + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.7.2: + resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-router-dom@6.30.3: + resolution: {integrity: sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + + react-router@6.30.3: + resolution: {integrity: sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-syntax-highlighter@15.6.6: + resolution: {integrity: sha512-DgXrc+AZF47+HvAPEmn7Ua/1p10jNoVZVI/LoPiYdtY+OM+/nG5yefLHKJwdKqY1adMuHFbeyBaG9j64ML7vTw==} + peerDependencies: + react: '>= 0.14.0' + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + refractor@3.6.0: + resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==} + + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@6.1.0: + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} + + rehype-harden@1.1.8: + resolution: {integrity: sha512-Qn7vR1xrf6fZCrkm9TDWi/AB4ylrHy+jqsNm1EHOAmbARYA6gsnVJBq/sdBh6kmT4NEZxH5vgIjrscefJAOXcw==} + + rehype-katex@7.0.1: + resolution: {integrity: sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==} + + rehype-raw@7.0.0: + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + + rehype-sanitize@6.0.0: + resolution: {integrity: sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==} + + remark-cjk-friendly-gfm-strikethrough@1.2.3: + resolution: {integrity: sha512-bXfMZtsaomK6ysNN/UGRIcasQAYkC10NtPmP0oOHOV8YOhA2TXmwRXCku4qOzjIFxAPfish5+XS0eIug2PzNZA==} + engines: {node: '>=16'} + peerDependencies: + '@types/mdast': ^4.0.0 + unified: ^11.0.0 + peerDependenciesMeta: + '@types/mdast': + optional: true + + remark-cjk-friendly@1.2.3: + resolution: {integrity: sha512-UvAgxwlNk+l9Oqgl/9MWK2eWRS7zgBW/nXX9AthV7nd/3lNejF138E7Xbmk9Zs4WjTJGs721r7fAEc7tNFoH7g==} + engines: {node: '>=16'} + peerDependencies: + '@types/mdast': ^4.0.0 + unified: ^11.0.0 + peerDependenciesMeta: + '@types/mdast': + optional: true + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-math@6.0.0: + resolution: {integrity: sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + remend@1.0.1: + resolution: {integrity: sha512-152puVH0qMoRJQFnaMG+rVDdf01Jq/CaED+MBuXExurJgdbkLp0c3TIe4R12o28Klx8uyGsjvFNG05aFG69G9w==} + + robust-predicates@3.0.3: + resolution: {integrity: sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==} + + rolldown-vite@7.3.1: + resolution: {integrity: sha512-LYzdNAjRHhF2yA4JUQm/QyARyi216N2rpJ0lJZb8E9FU2y5v6Vk+xq/U4XBOxMefpWixT5H3TslmAHm1rqIq2w==} + engines: {node: ^20.19.0 || >=22.12.0} + deprecated: Use this package to migrate from Vite 7 to Vite 8. For the most recent updates, migrate to Vite 8 once you're ready. + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + esbuild: ^0.27.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + rolldown@1.0.0-beta.53: + resolution: {integrity: sha512-Qd9c2p0XKZdgT5AYd+KgAMggJ8ZmCs3JnS9PTMWkyUfteKlfmKtxJbWTHkVakxwXs1Ub7jrRYVeFeF7N0sQxyw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + roughjs@4.6.6: + resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==} + + rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + shiki@3.23.0: + resolution: {integrity: sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==} + + sonner@1.7.4: + resolution: {integrity: sha512-DIS8z4PfJRbIyfVFDVnK9rO3eYDtse4Omcm6bt0oEr5/jtLgysmjuBl1frJ9E/EQZrFmKx2A8m/s5s9CRXIzhw==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc + react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + space-separated-tokens@1.1.5: + resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + streamdown@1.6.11: + resolution: {integrity: sha512-Y38fwRx5kCKTluwM+Gf27jbbi9q6Qy+WC9YrC1YbCpMkktT3PsRBJHMWiqYeF8y/JzLpB1IzDoeaB6qkQEDnAA==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + style-to-js@1.1.21: + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + + style-to-object@1.0.14: + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + + stylis@4.3.6: + resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==} + + swr@2.4.1: + resolution: {integrity: sha512-2CC6CiKQtEwaEeNiqWTAw9PGykW8SR5zZX8MZk6TeAvEAnVS7Visz8WzphqgtQ8v2xz/4Q5K+j+SeMaKXeeQIA==} + peerDependencies: + react: ^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + tailwind-merge@2.6.1: + resolution: {integrity: sha512-Oo6tHdpZsGpkKG88HJ8RR1rg/RdnEkQEfMoEk2x1XRI3F1AxeU+ijRXpiVUF4UbLfcxxRGw6TbUINKYdWVsQTQ==} + + tailwind-merge@3.5.0: + resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==} + + tailwindcss-animate@1.0.7: + resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + + tailwindcss@4.2.2: + resolution: {integrity: sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==} + + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + engines: {node: '>=6'} + + throttleit@2.1.0: + resolution: {integrity: sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==} + engines: {node: '>=18'} + + tinyexec@1.0.4: + resolution: {integrity: sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw==} + engines: {node: '>=18'} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.6.3: + resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unist-util-find-after@5.0.0: + resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-remove-position@5.0.0: + resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-stick-to-bottom@1.1.3: + resolution: {integrity: sha512-GgRLdeGhxBxpcbrBbEIEoOKUQ9d46/eaSII+wyv1r9Du+NbCn1W/OE+VddefvRP4+5w/1kATN/6g2/BAC/yowQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + usehooks-ts@3.1.1: + resolution: {integrity: sha512-I4diPp9Cq6ieSUH2wu+fDAVQO43xwtulo+fKEidHUwZPnYImbtkTjzIJYcDcJqxgmX31GVqNFURodvcgHcW0pA==} + engines: {node: '>=16.15.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 || ^19.0.0-rc + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vscode-jsonrpc@8.2.0: + resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} + engines: {node: '>=14.0.0'} + + vscode-languageserver-protocol@3.17.5: + resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} + + vscode-languageserver-textdocument@1.0.12: + resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} + + vscode-languageserver-types@3.17.5: + resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} + + vscode-languageserver@9.0.1: + resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} + hasBin: true + + vscode-uri@3.1.0: + resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@ai-sdk/gateway@3.0.77(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 3.0.8 + '@ai-sdk/provider-utils': 4.0.21(zod@4.3.6) + '@vercel/oidc': 3.1.0 + zod: 4.3.6 + + '@ai-sdk/provider-utils@4.0.21(zod@4.3.6)': + dependencies: + '@ai-sdk/provider': 3.0.8 + '@standard-schema/spec': 1.1.0 + eventsource-parser: 3.0.6 + zod: 4.3.6 + + '@ai-sdk/provider@3.0.8': + dependencies: + json-schema: 0.4.0 + + '@ai-sdk/react@3.0.136(react@18.3.1)(zod@4.3.6)': + dependencies: + '@ai-sdk/provider-utils': 4.0.21(zod@4.3.6) + ai: 6.0.134(zod@4.3.6) + react: 18.3.1 + swr: 2.4.1(react@18.3.1) + throttleit: 2.1.0 + transitivePeerDependencies: + - zod + + '@alloc/quick-lru@5.2.0': {} + + '@antfu/install-pkg@1.1.0': + dependencies: + package-manager-detector: 1.6.0 + tinyexec: 1.0.4 + + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.0': {} + + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.1 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.28.6': {} + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.29.2': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + + '@babel/parser@7.29.2': + dependencies: + '@babel/types': 7.29.0 + + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/runtime@7.29.2': {} + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@braintree/sanitize-url@7.1.2': {} + + '@chevrotain/cst-dts-gen@11.1.2': + dependencies: + '@chevrotain/gast': 11.1.2 + '@chevrotain/types': 11.1.2 + lodash-es: 4.17.23 + + '@chevrotain/gast@11.1.2': + dependencies: + '@chevrotain/types': 11.1.2 + lodash-es: 4.17.23 + + '@chevrotain/regexp-to-ast@11.1.2': {} + + '@chevrotain/types@11.1.2': {} + + '@chevrotain/utils@11.1.2': {} + + '@emnapi/core@1.9.1': + dependencies: + '@emnapi/wasi-threads': 1.2.0 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.9.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@floating-ui/core@1.7.5': + dependencies: + '@floating-ui/utils': 0.2.11 + + '@floating-ui/dom@1.7.6': + dependencies: + '@floating-ui/core': 1.7.5 + '@floating-ui/utils': 0.2.11 + + '@floating-ui/react-dom@2.1.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/dom': 1.7.6 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@floating-ui/utils@0.2.11': {} + + '@iconify/types@2.0.0': {} + + '@iconify/utils@3.1.0': + dependencies: + '@antfu/install-pkg': 1.1.0 + '@iconify/types': 2.0.0 + mlly: 1.8.2 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@mermaid-js/parser@1.0.1': + dependencies: + langium: 4.2.1 + + '@napi-rs/wasm-runtime@1.1.1': + dependencies: + '@emnapi/core': 1.9.1 + '@emnapi/runtime': 1.9.1 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@opentelemetry/api@1.9.0': {} + + '@oxc-project/runtime@0.101.0': {} + + '@oxc-project/types@0.101.0': {} + + '@radix-ui/primitive@1.1.3': {} + + '@radix-ui/react-alert-dialog@1.1.15(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.28)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + + '@radix-ui/react-arrow@1.1.7(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + + '@radix-ui/react-collapsible@1.1.12(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.28)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + + '@radix-ui/react-collection@1.1.7(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.28)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + + '@radix-ui/react-compose-refs@1.1.2(@types/react@18.3.28)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + '@radix-ui/react-context@1.1.2(@types/react@18.3.28)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + '@radix-ui/react-dialog@1.1.15(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.28)(react@18.3.1) + aria-hidden: 1.2.6 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.7.2(@types/react@18.3.28)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + + '@radix-ui/react-direction@1.1.1(@types/react@18.3.28)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@18.3.28)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + + '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.28)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + + '@radix-ui/react-focus-guards@1.1.3(@types/react@18.3.28)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.28)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + + '@radix-ui/react-id@1.1.1(@types/react@18.3.28)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.28)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + '@radix-ui/react-menu@2.1.16(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.28)(react@18.3.1) + aria-hidden: 1.2.6 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.7.2(@types/react@18.3.28)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + + '@radix-ui/react-popper@1.2.8(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/react-dom': 2.1.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-use-rect': 1.1.1(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/rect': 1.1.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + + '@radix-ui/react-portal@1.1.9(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.28)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + + '@radix-ui/react-presence@1.1.5(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.28)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + + '@radix-ui/react-primitive@2.1.3(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.28)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + + '@radix-ui/react-primitive@2.1.4(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-slot': 1.2.4(@types/react@18.3.28)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + + '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.28)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + + '@radix-ui/react-separator@1.1.8(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + + '@radix-ui/react-slot@1.2.3(@types/react@18.3.28)(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.28)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + '@radix-ui/react-slot@1.2.4(@types/react@18.3.28)(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.28)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + '@radix-ui/react-tooltip@1.2.8(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@18.3.28)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@18.3.28)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@18.3.28)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.28)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + '@radix-ui/react-use-effect-event@0.0.2(@types/react@18.3.28)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.28)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@18.3.28)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.28)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@18.3.28)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + '@radix-ui/react-use-rect@1.1.1(@types/react@18.3.28)(react@18.3.1)': + dependencies: + '@radix-ui/rect': 1.1.1 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + '@radix-ui/react-use-size@1.1.1(@types/react@18.3.28)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.28)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.28 + + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + + '@radix-ui/rect@1.1.1': {} + + '@remix-run/router@1.23.2': {} + + '@rolldown/binding-android-arm64@1.0.0-beta.53': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-beta.53': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-beta.53': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-beta.53': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.53': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.53': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.53': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.53': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-beta.53': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-beta.53': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-beta.53': + dependencies: + '@napi-rs/wasm-runtime': 1.1.1 + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.53': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.53': + optional: true + + '@rolldown/pluginutils@1.0.0-beta.27': {} + + '@rolldown/pluginutils@1.0.0-beta.53': {} + + '@shikijs/core@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 4.3.5 + + '@shikijs/engine-oniguruma@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + + '@shikijs/themes@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + + '@shikijs/types@3.23.0': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@standard-schema/spec@1.1.0': {} + + '@tailwindcss/node@4.2.2': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.20.1 + jiti: 2.6.1 + lightningcss: 1.32.0 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.2.2 + + '@tailwindcss/oxide-android-arm64@4.2.2': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.2.2': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.2.2': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.2.2': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.2.2': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.2.2': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.2.2': + optional: true + + '@tailwindcss/oxide@4.2.2': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.2.2 + '@tailwindcss/oxide-darwin-arm64': 4.2.2 + '@tailwindcss/oxide-darwin-x64': 4.2.2 + '@tailwindcss/oxide-freebsd-x64': 4.2.2 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.2 + '@tailwindcss/oxide-linux-arm64-gnu': 4.2.2 + '@tailwindcss/oxide-linux-arm64-musl': 4.2.2 + '@tailwindcss/oxide-linux-x64-gnu': 4.2.2 + '@tailwindcss/oxide-linux-x64-musl': 4.2.2 + '@tailwindcss/oxide-wasm32-wasi': 4.2.2 + '@tailwindcss/oxide-win32-arm64-msvc': 4.2.2 + '@tailwindcss/oxide-win32-x64-msvc': 4.2.2 + + '@tailwindcss/postcss@4.2.2': + dependencies: + '@alloc/quick-lru': 5.2.0 + '@tailwindcss/node': 4.2.2 + '@tailwindcss/oxide': 4.2.2 + postcss: 8.5.8 + tailwindcss: 4.2.2 + + '@tailwindcss/typography@0.5.19(tailwindcss@4.2.2)': + dependencies: + postcss-selector-parser: 6.0.10 + tailwindcss: 4.2.2 + + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.29.0 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.29.0 + + '@types/d3-array@3.2.2': {} + + '@types/d3-axis@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-brush@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-chord@3.0.6': {} + + '@types/d3-color@3.1.3': {} + + '@types/d3-contour@3.0.6': + dependencies: + '@types/d3-array': 3.2.2 + '@types/geojson': 7946.0.16 + + '@types/d3-delaunay@6.0.4': {} + + '@types/d3-dispatch@3.0.7': {} + + '@types/d3-drag@3.0.7': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-dsv@3.0.7': {} + + '@types/d3-ease@3.0.2': {} + + '@types/d3-fetch@3.0.7': + dependencies: + '@types/d3-dsv': 3.0.7 + + '@types/d3-force@3.0.10': {} + + '@types/d3-format@3.0.4': {} + + '@types/d3-geo@3.1.0': + dependencies: + '@types/geojson': 7946.0.16 + + '@types/d3-hierarchy@3.1.7': {} + + '@types/d3-interpolate@3.0.4': + dependencies: + '@types/d3-color': 3.1.3 + + '@types/d3-path@3.1.1': {} + + '@types/d3-polygon@3.0.2': {} + + '@types/d3-quadtree@3.0.6': {} + + '@types/d3-random@3.0.3': {} + + '@types/d3-scale-chromatic@3.1.0': {} + + '@types/d3-scale@4.0.9': + dependencies: + '@types/d3-time': 3.0.4 + + '@types/d3-selection@3.0.11': {} + + '@types/d3-shape@3.1.8': + dependencies: + '@types/d3-path': 3.1.1 + + '@types/d3-time-format@4.0.3': {} + + '@types/d3-time@3.0.4': {} + + '@types/d3-timer@3.0.2': {} + + '@types/d3-transition@3.0.9': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-zoom@3.0.8': + dependencies: + '@types/d3-interpolate': 3.0.4 + '@types/d3-selection': 3.0.11 + + '@types/d3@7.4.3': + dependencies: + '@types/d3-array': 3.2.2 + '@types/d3-axis': 3.0.6 + '@types/d3-brush': 3.0.6 + '@types/d3-chord': 3.0.6 + '@types/d3-color': 3.1.3 + '@types/d3-contour': 3.0.6 + '@types/d3-delaunay': 6.0.4 + '@types/d3-dispatch': 3.0.7 + '@types/d3-drag': 3.0.7 + '@types/d3-dsv': 3.0.7 + '@types/d3-ease': 3.0.2 + '@types/d3-fetch': 3.0.7 + '@types/d3-force': 3.0.10 + '@types/d3-format': 3.0.4 + '@types/d3-geo': 3.1.0 + '@types/d3-hierarchy': 3.1.7 + '@types/d3-interpolate': 3.0.4 + '@types/d3-path': 3.1.1 + '@types/d3-polygon': 3.0.2 + '@types/d3-quadtree': 3.0.6 + '@types/d3-random': 3.0.3 + '@types/d3-scale': 4.0.9 + '@types/d3-scale-chromatic': 3.1.0 + '@types/d3-selection': 3.0.11 + '@types/d3-shape': 3.1.8 + '@types/d3-time': 3.0.4 + '@types/d3-time-format': 4.0.3 + '@types/d3-timer': 3.0.2 + '@types/d3-transition': 3.0.9 + '@types/d3-zoom': 3.0.8 + + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.8 + + '@types/estree@1.0.8': {} + + '@types/geojson@7946.0.16': {} + + '@types/hast@2.3.10': + dependencies: + '@types/unist': 2.0.11 + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/katex@0.16.8': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/ms@2.1.0': {} + + '@types/prop-types@15.7.15': {} + + '@types/react-dom@18.3.7(@types/react@18.3.28)': + dependencies: + '@types/react': 18.3.28 + + '@types/react-syntax-highlighter@15.5.13': + dependencies: + '@types/react': 18.3.28 + + '@types/react@18.3.28': + dependencies: + '@types/prop-types': 15.7.15 + csstype: 3.2.3 + + '@types/trusted-types@2.0.7': + optional: true + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + + '@ungap/structured-clone@1.3.0': {} + + '@upsetjs/venn.js@2.0.0': + optionalDependencies: + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + '@vercel/oidc@3.1.0': {} + + '@vitejs/plugin-react@4.7.0(rolldown-vite@7.3.1(jiti@2.6.1))': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) + '@rolldown/pluginutils': 1.0.0-beta.27 + '@types/babel__core': 7.20.5 + react-refresh: 0.17.0 + vite: rolldown-vite@7.3.1(jiti@2.6.1) + transitivePeerDependencies: + - supports-color + + acorn@8.16.0: {} + + ai@6.0.134(zod@4.3.6): + dependencies: + '@ai-sdk/gateway': 3.0.77(zod@4.3.6) + '@ai-sdk/provider': 3.0.8 + '@ai-sdk/provider-utils': 4.0.21(zod@4.3.6) + '@opentelemetry/api': 1.9.0 + zod: 4.3.6 + + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + + bail@2.0.2: {} + + baseline-browser-mapping@2.10.10: {} + + browserslist@4.28.1: + dependencies: + baseline-browser-mapping: 2.10.10 + caniuse-lite: 1.0.30001781 + electron-to-chromium: 1.5.321 + node-releases: 2.0.36 + update-browserslist-db: 1.2.3(browserslist@4.28.1) + + caniuse-lite@1.0.30001781: {} + + ccount@2.0.1: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@1.1.4: {} + + character-entities-legacy@3.0.0: {} + + character-entities@1.2.4: {} + + character-entities@2.0.2: {} + + character-reference-invalid@1.1.4: {} + + character-reference-invalid@2.0.1: {} + + chevrotain-allstar@0.3.1(chevrotain@11.1.2): + dependencies: + chevrotain: 11.1.2 + lodash-es: 4.17.23 + + chevrotain@11.1.2: + dependencies: + '@chevrotain/cst-dts-gen': 11.1.2 + '@chevrotain/gast': 11.1.2 + '@chevrotain/regexp-to-ast': 11.1.2 + '@chevrotain/types': 11.1.2 + '@chevrotain/utils': 11.1.2 + lodash-es: 4.17.23 + + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + + clsx@2.1.1: {} + + comma-separated-tokens@1.0.8: {} + + comma-separated-tokens@2.0.3: {} + + commander@7.2.0: {} + + commander@8.3.0: {} + + confbox@0.1.8: {} + + convert-source-map@2.0.0: {} + + cose-base@1.0.3: + dependencies: + layout-base: 1.0.2 + + cose-base@2.2.0: + dependencies: + layout-base: 2.0.1 + + cssesc@3.0.0: {} + + csstype@3.2.3: {} + + cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.1): + dependencies: + cose-base: 1.0.3 + cytoscape: 3.33.1 + + cytoscape-fcose@2.2.0(cytoscape@3.33.1): + dependencies: + cose-base: 2.2.0 + cytoscape: 3.33.1 + + cytoscape@3.33.1: {} + + d3-array@2.12.1: + dependencies: + internmap: 1.0.1 + + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-axis@3.0.0: {} + + d3-brush@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3-chord@3.0.1: + dependencies: + d3-path: 3.1.0 + + d3-color@3.1.0: {} + + d3-contour@4.0.2: + dependencies: + d3-array: 3.2.4 + + d3-delaunay@6.0.4: + dependencies: + delaunator: 5.1.0 + + d3-dispatch@3.0.1: {} + + d3-drag@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + + d3-dsv@3.0.1: + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 + + d3-ease@3.0.1: {} + + d3-fetch@3.0.1: + dependencies: + d3-dsv: 3.0.1 + + d3-force@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + + d3-format@3.1.2: {} + + d3-geo@3.1.1: + dependencies: + d3-array: 3.2.4 + + d3-hierarchy@3.1.2: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@1.0.9: {} + + d3-path@3.1.0: {} + + d3-polygon@3.0.1: {} + + d3-quadtree@3.0.1: {} + + d3-random@3.0.1: {} + + d3-sankey@0.12.3: + dependencies: + d3-array: 2.12.1 + d3-shape: 1.3.7 + + d3-scale-chromatic@3.1.0: + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.2 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + + d3-selection@3.0.0: {} + + d3-shape@1.3.7: + dependencies: + d3-path: 1.0.9 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-time-format@4.1.0: + dependencies: + d3-time: 3.1.0 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + + d3-timer@3.0.1: {} + + d3-transition@3.0.1(d3-selection@3.0.0): + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + + d3-zoom@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3@7.9.0: + dependencies: + d3-array: 3.2.4 + d3-axis: 3.0.0 + d3-brush: 3.0.0 + d3-chord: 3.0.1 + d3-color: 3.1.0 + d3-contour: 4.0.2 + d3-delaunay: 6.0.4 + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-format: 3.1.2 + d3-geo: 3.1.1 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.1.0 + d3-polygon: 3.0.1 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.1.0 + d3-selection: 3.0.0 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + d3-timer: 3.0.1 + d3-transition: 3.0.1(d3-selection@3.0.0) + d3-zoom: 3.0.0 + + dagre-d3-es@7.0.14: + dependencies: + d3: 7.9.0 + lodash-es: 4.17.23 + + date-fns@4.1.0: {} + + dayjs@1.11.20: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + + delaunator@5.1.0: + dependencies: + robust-predicates: 3.0.3 + + dequal@2.0.3: {} + + detect-libc@2.1.2: {} + + detect-node-es@1.1.0: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + dompurify@3.3.3: + optionalDependencies: + '@types/trusted-types': 2.0.7 + + electron-to-chromium@1.5.321: {} + + enhanced-resolve@5.20.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.0 + + entities@6.0.1: {} + + escalade@3.2.0: {} + + escape-string-regexp@5.0.0: {} + + estree-util-is-identifier-name@3.0.0: {} + + eventsource-parser@3.0.6: {} + + extend@3.0.2: {} + + fast-deep-equal@3.1.3: {} + + fault@1.0.4: + dependencies: + format: 0.2.2 + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + format@0.2.2: {} + + framer-motion@11.18.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + motion-dom: 11.18.1 + motion-utils: 11.18.1 + tslib: 2.8.1 + optionalDependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + fsevents@2.3.3: + optional: true + + gensync@1.0.0-beta.2: {} + + get-east-asian-width@1.5.0: {} + + get-nonce@1.0.1: {} + + graceful-fs@4.2.11: {} + + hachure-fill@0.5.2: {} + + hast-util-from-dom@5.0.1: + dependencies: + '@types/hast': 3.0.4 + hastscript: 9.0.1 + web-namespaces: 2.0.1 + + hast-util-from-html-isomorphic@2.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-from-dom: 5.0.1 + hast-util-from-html: 2.0.3 + unist-util-remove-position: 5.0.0 + + hast-util-from-html@2.0.3: + dependencies: + '@types/hast': 3.0.4 + devlop: 1.1.0 + hast-util-from-parse5: 8.0.3 + parse5: 7.3.0 + vfile: 6.0.3 + vfile-message: 4.0.3 + + hast-util-from-parse5@8.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + devlop: 1.1.0 + hastscript: 9.0.1 + property-information: 7.1.0 + vfile: 6.0.3 + vfile-location: 5.0.3 + web-namespaces: 2.0.1 + + hast-util-is-element@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-parse-selector@2.2.5: {} + + hast-util-parse-selector@4.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-raw@9.1.0: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + '@ungap/structured-clone': 1.3.0 + hast-util-from-parse5: 8.0.3 + hast-util-to-parse5: 8.0.1 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + parse5: 7.3.0 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-sanitize@5.0.2: + dependencies: + '@types/hast': 3.0.4 + '@ungap/structured-clone': 1.3.0 + unist-util-position: 5.0.0 + + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + hast-util-to-parse5@8.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-to-text@4.0.2: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + hast-util-is-element: 3.0.0 + unist-util-find-after: 5.0.0 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast@1.0.0: {} + + hastscript@6.0.0: + dependencies: + '@types/hast': 2.3.10 + comma-separated-tokens: 1.0.8 + hast-util-parse-selector: 2.2.5 + property-information: 5.6.0 + space-separated-tokens: 1.1.5 + + hastscript@9.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + + highlight.js@10.7.3: {} + + highlightjs-vue@1.0.0: {} + + html-url-attributes@3.0.1: {} + + html-void-elements@3.0.0: {} + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + inline-style-parser@0.2.7: {} + + internmap@1.0.1: {} + + internmap@2.0.3: {} + + is-alphabetical@1.0.4: {} + + is-alphabetical@2.0.1: {} + + is-alphanumerical@1.0.4: + dependencies: + is-alphabetical: 1.0.4 + is-decimal: 1.0.4 + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-decimal@1.0.4: {} + + is-decimal@2.0.1: {} + + is-hexadecimal@1.0.4: {} + + is-hexadecimal@2.0.1: {} + + is-plain-obj@4.1.0: {} + + jiti@2.6.1: {} + + js-tokens@4.0.0: {} + + jsesc@3.1.0: {} + + json-schema@0.4.0: {} + + json5@2.2.3: {} + + katex@0.16.40: + dependencies: + commander: 8.3.0 + + khroma@2.1.0: {} + + langium@4.2.1: + dependencies: + chevrotain: 11.1.2 + chevrotain-allstar: 0.3.1(chevrotain@11.1.2) + vscode-languageserver: 9.0.1 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.1.0 + + layout-base@1.0.2: {} + + layout-base@2.0.1: {} + + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + + lodash-es@4.17.23: {} + + lodash.debounce@4.0.8: {} + + longest-streak@3.1.0: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lowlight@1.20.0: + dependencies: + fault: 1.0.4 + highlight.js: 10.7.3 + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lucide-react@0.446.0(react@18.3.1): + dependencies: + react: 18.3.1 + + lucide-react@0.542.0(react@18.3.1): + dependencies: + react: 18.3.1 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + markdown-table@3.0.4: {} + + marked@16.4.2: {} + + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.0.3: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.3 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-math@3.0.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + longest-streak: 3.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + unist-util-remove-position: 5.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-hast@13.2.1: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + mermaid@11.13.0: + dependencies: + '@braintree/sanitize-url': 7.1.2 + '@iconify/utils': 3.1.0 + '@mermaid-js/parser': 1.0.1 + '@types/d3': 7.4.3 + '@upsetjs/venn.js': 2.0.0 + cytoscape: 3.33.1 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.33.1) + cytoscape-fcose: 2.2.0(cytoscape@3.33.1) + d3: 7.9.0 + d3-sankey: 0.12.3 + dagre-d3-es: 7.0.14 + dayjs: 1.11.20 + dompurify: 3.3.3 + katex: 0.16.40 + khroma: 2.1.0 + lodash-es: 4.17.23 + marked: 16.4.2 + roughjs: 4.6.6 + stylis: 4.3.6 + ts-dedent: 2.2.0 + uuid: 11.1.0 + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-cjk-friendly-gfm-strikethrough@1.2.3(micromark-util-types@2.0.2)(micromark@4.0.2): + dependencies: + devlop: 1.1.0 + get-east-asian-width: 1.5.0 + micromark: 4.0.2 + micromark-extension-cjk-friendly-util: 2.1.1(micromark-util-types@2.0.2) + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + optionalDependencies: + micromark-util-types: 2.0.2 + + micromark-extension-cjk-friendly-util@2.1.1(micromark-util-types@2.0.2): + dependencies: + get-east-asian-width: 1.5.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + optionalDependencies: + micromark-util-types: 2.0.2 + + micromark-extension-cjk-friendly@1.2.3(micromark-util-types@2.0.2)(micromark@4.0.2): + dependencies: + devlop: 1.1.0 + micromark: 4.0.2 + micromark-extension-cjk-friendly-util: 2.1.1(micromark-util-types@2.0.2) + micromark-util-chunked: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + optionalDependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-math@3.1.0: + dependencies: + '@types/katex': 0.16.8 + devlop: 1.1.0 + katex: 0.16.40 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + mlly@1.8.2: + dependencies: + acorn: 8.16.0 + pathe: 2.0.3 + pkg-types: 1.3.1 + ufo: 1.6.3 + + motion-dom@11.18.1: + dependencies: + motion-utils: 11.18.1 + + motion-utils@11.18.1: {} + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + next-themes@0.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + node-releases@2.0.36: {} + + oniguruma-parser@0.12.1: {} + + oniguruma-to-es@4.3.5: + dependencies: + oniguruma-parser: 0.12.1 + regex: 6.1.0 + regex-recursion: 6.0.2 + + package-manager-detector@1.6.0: {} + + parse-entities@2.0.0: + dependencies: + character-entities: 1.2.4 + character-entities-legacy: 1.1.4 + character-reference-invalid: 1.1.4 + is-alphanumerical: 1.0.4 + is-decimal: 1.0.4 + is-hexadecimal: 1.0.4 + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.3.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + + path-data-parser@0.1.0: {} + + pathe@2.0.3: {} + + picocolors@1.1.1: {} + + picomatch@4.0.3: {} + + pkg-types@1.3.1: + dependencies: + confbox: 0.1.8 + mlly: 1.8.2 + pathe: 2.0.3 + + points-on-curve@0.2.0: {} + + points-on-path@0.2.1: + dependencies: + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + + postcss-selector-parser@6.0.10: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss@8.5.8: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prismjs@1.27.0: {} + + prismjs@1.30.0: {} + + property-information@5.6.0: + dependencies: + xtend: 4.0.2 + + property-information@7.1.0: {} + + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react-refresh@0.17.0: {} + + react-remove-scroll-bar@2.3.8(@types/react@18.3.28)(react@18.3.1): + dependencies: + react: 18.3.1 + react-style-singleton: 2.2.3(@types/react@18.3.28)(react@18.3.1) + tslib: 2.8.1 + optionalDependencies: + '@types/react': 18.3.28 + + react-remove-scroll@2.7.2(@types/react@18.3.28)(react@18.3.1): + dependencies: + react: 18.3.1 + react-remove-scroll-bar: 2.3.8(@types/react@18.3.28)(react@18.3.1) + react-style-singleton: 2.2.3(@types/react@18.3.28)(react@18.3.1) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@18.3.28)(react@18.3.1) + use-sidecar: 1.1.3(@types/react@18.3.28)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + + react-router-dom@6.30.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@remix-run/router': 1.23.2 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-router: 6.30.3(react@18.3.1) + + react-router@6.30.3(react@18.3.1): + dependencies: + '@remix-run/router': 1.23.2 + react: 18.3.1 + + react-style-singleton@2.2.3(@types/react@18.3.28)(react@18.3.1): + dependencies: + get-nonce: 1.0.1 + react: 18.3.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 18.3.28 + + react-syntax-highlighter@15.6.6(react@18.3.1): + dependencies: + '@babel/runtime': 7.29.2 + highlight.js: 10.7.3 + highlightjs-vue: 1.0.0 + lowlight: 1.20.0 + prismjs: 1.30.0 + react: 18.3.1 + refractor: 3.6.0 + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + refractor@3.6.0: + dependencies: + hastscript: 6.0.0 + parse-entities: 2.0.0 + prismjs: 1.27.0 + + regex-recursion@6.0.2: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@6.1.0: + dependencies: + regex-utilities: 2.3.0 + + rehype-harden@1.1.8: + dependencies: + unist-util-visit: 5.1.0 + + rehype-katex@7.0.1: + dependencies: + '@types/hast': 3.0.4 + '@types/katex': 0.16.8 + hast-util-from-html-isomorphic: 2.0.0 + hast-util-to-text: 4.0.2 + katex: 0.16.40 + unist-util-visit-parents: 6.0.2 + vfile: 6.0.3 + + rehype-raw@7.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-raw: 9.1.0 + vfile: 6.0.3 + + rehype-sanitize@6.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-sanitize: 5.0.2 + + remark-cjk-friendly-gfm-strikethrough@1.2.3(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(unified@11.0.5): + dependencies: + micromark-extension-cjk-friendly-gfm-strikethrough: 1.2.3(micromark-util-types@2.0.2)(micromark@4.0.2) + unified: 11.0.5 + optionalDependencies: + '@types/mdast': 4.0.4 + transitivePeerDependencies: + - micromark + - micromark-util-types + + remark-cjk-friendly@1.2.3(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(unified@11.0.5): + dependencies: + micromark-extension-cjk-friendly: 1.2.3(micromark-util-types@2.0.2)(micromark@4.0.2) + unified: 11.0.5 + optionalDependencies: + '@types/mdast': 4.0.4 + transitivePeerDependencies: + - micromark + - micromark-util-types + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-math@6.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-math: 3.0.0 + micromark-extension-math: 3.1.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.1 + unified: 11.0.5 + vfile: 6.0.3 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + + remend@1.0.1: {} + + robust-predicates@3.0.3: {} + + rolldown-vite@7.3.1(jiti@2.6.1): + dependencies: + '@oxc-project/runtime': 0.101.0 + fdir: 6.5.0(picomatch@4.0.3) + lightningcss: 1.32.0 + picomatch: 4.0.3 + postcss: 8.5.8 + rolldown: 1.0.0-beta.53 + tinyglobby: 0.2.15 + optionalDependencies: + fsevents: 2.3.3 + jiti: 2.6.1 + + rolldown@1.0.0-beta.53: + dependencies: + '@oxc-project/types': 0.101.0 + '@rolldown/pluginutils': 1.0.0-beta.53 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-beta.53 + '@rolldown/binding-darwin-arm64': 1.0.0-beta.53 + '@rolldown/binding-darwin-x64': 1.0.0-beta.53 + '@rolldown/binding-freebsd-x64': 1.0.0-beta.53 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.53 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.53 + '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.53 + '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.53 + '@rolldown/binding-linux-x64-musl': 1.0.0-beta.53 + '@rolldown/binding-openharmony-arm64': 1.0.0-beta.53 + '@rolldown/binding-wasm32-wasi': 1.0.0-beta.53 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.53 + '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.53 + + roughjs@4.6.6: + dependencies: + hachure-fill: 0.5.2 + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + points-on-path: 0.2.1 + + rw@1.3.3: {} + + safer-buffer@2.1.2: {} + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + semver@6.3.1: {} + + shiki@3.23.0: + dependencies: + '@shikijs/core': 3.23.0 + '@shikijs/engine-javascript': 3.23.0 + '@shikijs/engine-oniguruma': 3.23.0 + '@shikijs/langs': 3.23.0 + '@shikijs/themes': 3.23.0 + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + sonner@1.7.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + source-map-js@1.2.1: {} + + space-separated-tokens@1.1.5: {} + + space-separated-tokens@2.0.2: {} + + streamdown@1.6.11(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(react@18.3.1): + dependencies: + clsx: 2.1.1 + hast: 1.0.0 + hast-util-to-jsx-runtime: 2.3.6 + html-url-attributes: 3.0.1 + katex: 0.16.40 + lucide-react: 0.542.0(react@18.3.1) + marked: 16.4.2 + mermaid: 11.13.0 + react: 18.3.1 + rehype-harden: 1.1.8 + rehype-katex: 7.0.1 + rehype-raw: 7.0.0 + rehype-sanitize: 6.0.0 + remark-cjk-friendly: 1.2.3(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(unified@11.0.5) + remark-cjk-friendly-gfm-strikethrough: 1.2.3(@types/mdast@4.0.4)(micromark-util-types@2.0.2)(micromark@4.0.2)(unified@11.0.5) + remark-gfm: 4.0.1 + remark-math: 6.0.0 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + remend: 1.0.1 + shiki: 3.23.0 + tailwind-merge: 3.5.0 + unified: 11.0.5 + unist-util-visit: 5.1.0 + transitivePeerDependencies: + - '@types/mdast' + - micromark + - micromark-util-types + - supports-color + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + style-to-js@1.1.21: + dependencies: + style-to-object: 1.0.14 + + style-to-object@1.0.14: + dependencies: + inline-style-parser: 0.2.7 + + stylis@4.3.6: {} + + swr@2.4.1(react@18.3.1): + dependencies: + dequal: 2.0.3 + react: 18.3.1 + use-sync-external-store: 1.6.0(react@18.3.1) + + tailwind-merge@2.6.1: {} + + tailwind-merge@3.5.0: {} + + tailwindcss-animate@1.0.7(tailwindcss@4.2.2): + dependencies: + tailwindcss: 4.2.2 + + tailwindcss@4.2.2: {} + + tapable@2.3.0: {} + + throttleit@2.1.0: {} + + tinyexec@1.0.4: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + trim-lines@3.0.1: {} + + trough@2.2.0: {} + + ts-dedent@2.2.0: {} + + tslib@2.8.1: {} + + typescript@5.9.3: {} + + ufo@1.6.3: {} + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unist-util-find-after@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-remove-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-visit: 5.1.0 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + update-browserslist-db@1.2.3(browserslist@4.28.1): + dependencies: + browserslist: 4.28.1 + escalade: 3.2.0 + picocolors: 1.1.1 + + use-callback-ref@1.3.3(@types/react@18.3.28)(react@18.3.1): + dependencies: + react: 18.3.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 18.3.28 + + use-sidecar@1.1.3(@types/react@18.3.28)(react@18.3.1): + dependencies: + detect-node-es: 1.1.0 + react: 18.3.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 18.3.28 + + use-stick-to-bottom@1.1.3(react@18.3.1): + dependencies: + react: 18.3.1 + + use-sync-external-store@1.6.0(react@18.3.1): + dependencies: + react: 18.3.1 + + usehooks-ts@3.1.1(react@18.3.1): + dependencies: + lodash.debounce: 4.0.8 + react: 18.3.1 + + util-deprecate@1.0.2: {} + + uuid@11.1.0: {} + + vfile-location@5.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile: 6.0.3 + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + vscode-jsonrpc@8.2.0: {} + + vscode-languageserver-protocol@3.17.5: + dependencies: + vscode-jsonrpc: 8.2.0 + vscode-languageserver-types: 3.17.5 + + vscode-languageserver-textdocument@1.0.12: {} + + vscode-languageserver-types@3.17.5: {} + + vscode-languageserver@9.0.1: + dependencies: + vscode-languageserver-protocol: 3.17.5 + + vscode-uri@3.1.0: {} + + web-namespaces@2.0.1: {} + + xtend@4.0.2: {} + + yallist@3.1.1: {} + + zod@4.3.6: {} + + zwitch@2.0.4: {} diff --git a/integrations/appkit-agent/client/postcss.config.js b/integrations/appkit-agent/client/postcss.config.js new file mode 100644 index 000000000..a34a3d560 --- /dev/null +++ b/integrations/appkit-agent/client/postcss.config.js @@ -0,0 +1,5 @@ +export default { + plugins: { + '@tailwindcss/postcss': {}, + }, +}; diff --git a/integrations/appkit-agent/client/src/App.tsx b/integrations/appkit-agent/client/src/App.tsx new file mode 100644 index 000000000..d7336c5bb --- /dev/null +++ b/integrations/appkit-agent/client/src/App.tsx @@ -0,0 +1,25 @@ +import { Routes, Route } from 'react-router-dom'; +import { ChatProvider } from '@/contexts/ChatProvider'; +import { Toaster } from 'sonner'; +import RootLayout from '@/layouts/RootLayout'; +import ChatLayout from '@/layouts/ChatLayout'; +import NewChatPage from '@/pages/NewChatPage'; +import ChatPage from '@/pages/ChatPage'; + +function App() { + return ( + + + + }> + }> + } /> + } /> + + + + + ); +} + +export default App; diff --git a/integrations/appkit-agent/client/src/components/ChatApp.tsx b/integrations/appkit-agent/client/src/components/ChatApp.tsx new file mode 100644 index 000000000..5c20e4ceb --- /dev/null +++ b/integrations/appkit-agent/client/src/components/ChatApp.tsx @@ -0,0 +1,289 @@ +import { BrowserRouter, Routes, Route, useNavigate, useParams, useLocation } from 'react-router-dom'; +import { useState, useEffect } from 'react'; +import { Toaster } from 'sonner'; + +const LIGHT_THEME_COLOR = 'hsl(0 0% 100%)'; +const DARK_THEME_COLOR = 'hsl(240deg 10% 3.92%)'; +import { ChatProvider, type ChatProviderProps, useChatContext } from '@/contexts/ChatProvider'; +import { ChatPanel } from './ChatPanel'; +import { ChatSidebar } from './ChatSidebar'; +import { DatabricksLogo } from './DatabricksLogo'; +import { DbIcon } from './ui/db-icon'; +import { UserKeyIconIcon } from '../components/icons'; +import { + Sidebar, + SidebarContent, + SidebarFooter, + SidebarHeader, + SidebarInset, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + SidebarProvider, + useSidebar, +} from './ui/sidebar'; +import { Tooltip, TooltipContent, TooltipTrigger } from './ui/tooltip'; +import { SidebarUserNav } from './sidebar-user-nav'; +import { NewChatIcon, SidebarCollapseIcon, SidebarExpandIcon } from './icons'; +import { cn } from '@/lib/utils'; +import { Action } from './elements/actions'; +import { useChatData } from '@/hooks/useChatData'; +import type { LanguageModelUsage } from 'ai'; +import type { Chat as ChatRecord } from '@/types'; +import { generateUUID } from '@/lib/utils'; +import { getChatIdFromPathname } from '@/lib/navigation'; +import { useChatHistory } from '@/hooks/use-chat-history'; + +export interface ChatAppProps extends Omit { + /** Base path for client-side routing (default: "/chat") */ + basePath?: string; +} + +/** + * Full drop-in chat application — includes ChatProvider, BrowserRouter, + * sidebar, routing, and the complete chat experience. Renders a standalone + * SPA that can be mounted into any container. + */ +export function ChatApp({ + basePath = '/', + ...providerProps +}: ChatAppProps) { + return ( + + + + + + + ); +} + +function ChatAppLayout() { + const { session, isLoading } = useChatContext(); + const isCollapsed = localStorage.getItem('sidebar:state') !== 'true'; + + // Keep theme-color meta tag in sync with dark/light mode + useEffect(() => { + const html = document.documentElement; + const meta = document.getElementById('theme-color-meta'); + if (!meta) return; + + const update = () => { + meta.setAttribute( + 'content', + html.classList.contains('dark') ? DARK_THEME_COLOR : LIGHT_THEME_COLOR, + ); + }; + + const observer = new MutationObserver(update); + observer.observe(html, { attributes: true, attributeFilter: ['class'] }); + update(); + return () => observer.disconnect(); + }, []); + + if (isLoading) { + return ( +
+
Loading...
+
+ ); + } + + if (!session?.user) { + return ( +
+
+ +
+ +
+

Authentication Required

+

+ Please authenticate using Databricks to access this application. +

+
+
+
+
+ ); + } + + return ( + + + +
+ + } /> + } /> + +
+
+
+ ); +} + +function ChatAppSidebar() { + const navigate = useNavigate(); + useLocation(); // re-render on real navigation (route changes) + // Subscribe to the same SWR history cache that ChatSidebar uses. + // When useChatStream mutates history (after new chat creation), + // this triggers a re-render here too, so getChatIdFromPathname() + // picks up the URL that softNavigateToChatId already updated. + // SWR deduplicates — no extra network requests. + useChatHistory(); + const activeChatId = getChatIdFromPathname(); + const { session } = useChatContext(); + const { open, openMobile, isMobile, toggleSidebar, setOpenMobile } = useSidebar(); + const effectiveOpen = open || (isMobile && openMobile); + + return ( + + + {effectiveOpen && ( + + )} + + + + + +
+ + + + + { setOpenMobile(false); navigate('/'); }} + > + + New chat + + + New chat + + + +
+ + + {effectiveOpen && ( + { setOpenMobile(false); navigate(`/chat/${chatId}`); }} + user={session?.user} + /> + )} + + + + {session?.user && ( + + )} + +
+ ); +} + +function fromV3Usage( + usage: ChatRecord['lastContext'] | undefined, +): LanguageModelUsage | undefined { + if (!usage) return undefined; + return { + inputTokens: usage.inputTokens?.total, + outputTokens: usage.outputTokens?.total, + totalTokens: (usage.inputTokens?.total ?? 0) + (usage.outputTokens?.total ?? 0), + inputTokenDetails: { + noCacheTokens: usage.inputTokens?.noCache, + cacheReadTokens: usage.inputTokens?.cacheRead, + cacheWriteTokens: usage.inputTokens?.cacheWrite, + }, + outputTokenDetails: { + textTokens: usage.outputTokens?.text, + reasoningTokens: usage.outputTokens?.reasoning, + }, + }; +} + +function NewChatView() { + const { session } = useChatContext(); + const [id, setId] = useState(() => generateUUID()); + const [modelId] = useState(() => localStorage.getItem('chat-model') ?? 'chat-model'); + const location = useLocation(); + + useEffect(() => { + setId(generateUUID()); + }, [location.key]); + + if (!session?.user) return null; + + return ( + + ); +} + +function ExistingChatView() { + const { id } = useParams<{ id: string }>(); + const { session } = useChatContext(); + const [modelId] = useState(() => localStorage.getItem('chat-model') ?? 'chat-model'); + const { chatData, error } = useChatData(id, !!session?.user); + + if (!session?.user) return null; + + if (error) { + return ( +
+
+

Error

+

{error}

+
+
+ ); + } + + if (!chatData || chatData.chat.id !== id) { + return ( +
+
+ Loading chat... +
+
+ ); + } + + const { chat, messages, feedback } = chatData; + + return ( + + ); +} diff --git a/integrations/appkit-agent/client/src/components/ChatComposer.tsx b/integrations/appkit-agent/client/src/components/ChatComposer.tsx new file mode 100644 index 000000000..94e4e0930 --- /dev/null +++ b/integrations/appkit-agent/client/src/components/ChatComposer.tsx @@ -0,0 +1,48 @@ +import { useState } from 'react'; +import { MultimodalInput } from './multimodal-input'; +import type { UseChatHelpers } from '@ai-sdk/react'; +import type { Attachment, ChatMessage, VisibilityType } from '@/types'; +import type { UIMessage } from 'ai'; + +export interface ChatComposerProps { + chatId: string; + status: UseChatHelpers['status']; + messages: Array; + setMessages: UseChatHelpers['setMessages']; + sendMessage: UseChatHelpers['sendMessage']; + stop: () => void; + visibilityType?: VisibilityType; +} + +/** + * Composable chat input area — wraps MultimodalInput with a clean, + * self-contained API. Manages its own input text and attachment state. + */ +export function ChatComposer({ + chatId, + status, + messages, + setMessages, + sendMessage, + stop, + visibilityType = 'private', +}: ChatComposerProps) { + const [input, setInput] = useState(''); + const [attachments, setAttachments] = useState>([]); + + return ( + + ); +} diff --git a/integrations/appkit-agent/client/src/components/ChatPanel.tsx b/integrations/appkit-agent/client/src/components/ChatPanel.tsx new file mode 100644 index 000000000..89c707de6 --- /dev/null +++ b/integrations/appkit-agent/client/src/components/ChatPanel.tsx @@ -0,0 +1,124 @@ +import { useEffect, useState } from 'react'; +import { useSearchParams } from 'react-router-dom'; +import type { ReactNode } from 'react'; +import { useChatStream, type UseChatStreamOptions } from '@/hooks/use-chat-stream'; +import { ChatHeader, type ChatHeaderProps } from './chat-header'; +import { Messages } from './messages'; +import { ChatComposer } from './ChatComposer'; +import { Greeting } from './greeting'; +import { softNavigateToChatId } from '@/lib/navigation'; +import { useChatContext } from '@/contexts/ChatProvider'; +import type { ChatMessage, FeedbackMap, VisibilityType, ClientSession } from '@/types'; + +export interface ChatPanelProps extends UseChatStreamOptions { + /** Render a custom header. Receives default props so you can spread or override. */ + renderHeader?: (props: ChatHeaderProps) => ReactNode; + /** Render a custom composer. Receives the chat state so you can build your own input. */ + renderComposer?: (props: { + chatId: string; + status: string; + messages: ChatMessage[]; + setMessages: any; + sendMessage: any; + stop: () => void; + visibilityType: VisibilityType; + }) => ReactNode; + /** @deprecated Legacy prop — pass session via ChatProvider instead */ + session?: ClientSession; +} + +/** + * Pre-assembled chat panel that wires useChatStream with ChatHeader, + * Messages, and ChatComposer. Drop this into a ChatProvider and you + * get a fully functional chat. Supports render-prop slots for header + * and composer customization. + */ +export function ChatPanel({ + renderHeader, + renderComposer, + ...streamOptions +}: ChatPanelProps) { + const { chatHistoryEnabled } = useChatContext(); + + const chat = useChatStream(streamOptions); + + // Handle query param auto-send (for ?query=... deep-links) + let searchParams: URLSearchParams | undefined; + try { + [searchParams] = useSearchParams(); + } catch { + // Not inside a router — skip query param handling + } + + const query = searchParams?.get('query'); + const [hasAppendedQuery, setHasAppendedQuery] = useState(false); + + useEffect(() => { + if (query && !hasAppendedQuery) { + chat.sendMessage({ + role: 'user' as const, + parts: [{ type: 'text', text: query }], + }); + setHasAppendedQuery(true); + softNavigateToChatId(chat.id, chatHistoryEnabled); + } + }, [query, chat.sendMessage, hasAppendedQuery, chat.id, chatHistoryEnabled]); + + const headerProps: ChatHeaderProps = { + title: chat.title, + isLoadingTitle: chat.isTitleLoading, + empty: chat.messages.length === 0, + }; + + const header = renderHeader ? renderHeader(headerProps) : ; + + const composerProps = { + chatId: chat.id, + status: chat.status, + messages: chat.messages, + setMessages: chat.setMessages, + sendMessage: chat.sendMessage, + stop: chat.stop, + visibilityType: chat.visibilityType, + }; + + const composer = renderComposer + ? renderComposer(composerProps) + : ; + + if (chat.messages.length === 0) { + return ( +
+ +
+
+ + {composer} +
+
+
+ ); + } + + return ( +
+ {header} + + + +
+ {!chat.isReadonly && composer} +
+
+ ); +} diff --git a/integrations/appkit-agent/client/src/components/ChatSidebar.tsx b/integrations/appkit-agent/client/src/components/ChatSidebar.tsx new file mode 100644 index 000000000..d065ba978 --- /dev/null +++ b/integrations/appkit-agent/client/src/components/ChatSidebar.tsx @@ -0,0 +1,203 @@ +import { isToday, isYesterday, subMonths, subWeeks } from 'date-fns'; +import { useState } from 'react'; +import { motion } from 'framer-motion'; +import { LoaderIcon } from 'lucide-react'; +import { useChatHistory } from '@/hooks/use-chat-history'; +import { useChatContext } from '@/contexts/ChatProvider'; +import type { Chat } from '@/types'; +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, +} from '@/components/ui/alert-dialog'; +import { + SidebarGroup, + SidebarGroupContent, + SidebarGroupContentHeader, + SidebarMenu, +} from '@/components/ui/sidebar'; +import { ChatSidebarItem } from './ChatSidebarItem'; + +type GroupedChats = { + today: Chat[]; + yesterday: Chat[]; + lastWeek: Chat[]; + lastMonth: Chat[]; + older: Chat[]; +}; + +const groupChatsByDate = (chats: Chat[]): GroupedChats => { + const now = new Date(); + const oneWeekAgo = subWeeks(now, 1); + const oneMonthAgo = subMonths(now, 1); + + return chats.reduce( + (groups, chat) => { + const chatDate = new Date(chat.createdAt); + if (isToday(chatDate)) groups.today.push(chat); + else if (isYesterday(chatDate)) groups.yesterday.push(chat); + else if (chatDate > oneWeekAgo) groups.lastWeek.push(chat); + else if (chatDate > oneMonthAgo) groups.lastMonth.push(chat); + else groups.older.push(chat); + return groups; + }, + { today: [], yesterday: [], lastWeek: [], lastMonth: [], older: [] } as GroupedChats, + ); +}; + +export interface ChatSidebarProps { + activeChatId?: string; + onSelectChat: (chatId: string) => void; + onNewChat?: () => void; + user?: { email: string; name?: string; preferredUsername?: string } | null; +} + +/** + * Composable sidebar for chat history — uses useChatHistory internally + * and calls back to the consumer for navigation. + */ +export function ChatSidebar({ + activeChatId, + onSelectChat, + user, +}: ChatSidebarProps) { + const { chatHistoryEnabled } = useChatContext(); + const { chats, isLoading, isValidating, hasMore, isEmpty, loadMore, deleteChat } = + useChatHistory(); + + const [deleteId, setDeleteId] = useState(null); + const [showDeleteDialog, setShowDeleteDialog] = useState(false); + + const handleDelete = async () => { + if (!deleteId) return; + await deleteChat(deleteId); + setShowDeleteDialog(false); + if (deleteId === activeChatId) { + // Consumer handles navigation via callbacks + } + }; + + if (!user) { + return ( + + +
+ Login to save and revisit previous chats! +
+
+
+ ); + } + + if (isLoading) { + return ( + + Today + +
+ {[44, 32, 28, 64, 52].map((item) => ( +
+
+
+ ))} +
+ + + ); + } + + if (isEmpty) { + return ( + + +
+ {chatHistoryEnabled + ? 'Your conversations will appear here once you start chatting!' + : 'Chat history is disabled - conversations are not saved'} +
+
+
+ ); + } + + const grouped = groupChatsByDate(chats); + const sections: { label: string; items: Chat[] }[] = [ + { label: 'Today', items: grouped.today }, + { label: 'Yesterday', items: grouped.yesterday }, + { label: 'Last 7 days', items: grouped.lastWeek }, + { label: 'Last 30 days', items: grouped.lastMonth }, + { label: 'Older than last month', items: grouped.older }, + ].filter((s) => s.items.length > 0); + + return ( + <> + + + +
+ {sections.map((section) => ( +
+ {section.label} + {section.items.map((chat) => ( + onSelectChat(chat.id)} + onDelete={(chatId) => { + setDeleteId(chatId); + setShowDeleteDialog(true); + }} + /> + ))} +
+ ))} +
+
+ + { + if (!isValidating && !hasMore) return; + loadMore(); + }} + /> + + {!hasMore ? ( +
+ You have reached the end of your chat history. +
+ ) : ( +
+
+
Loading Chats...
+
+ )} +
+
+ + + + + Are you absolutely sure? + + This action cannot be undone. This will permanently delete your + chat and remove it from our servers. + + + + Cancel + Continue + + + + + ); +} diff --git a/integrations/appkit-agent/client/src/components/ChatSidebarItem.tsx b/integrations/appkit-agent/client/src/components/ChatSidebarItem.tsx new file mode 100644 index 000000000..45f0d1bd8 --- /dev/null +++ b/integrations/appkit-agent/client/src/components/ChatSidebarItem.tsx @@ -0,0 +1,103 @@ +import type { Chat } from '@/types'; +import { + SidebarMenuAction, + SidebarMenuButton, + SidebarMenuItem, +} from './ui/sidebar'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuPortal, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuTrigger, +} from './ui/dropdown-menu'; +import { memo } from 'react'; +import { useChatVisibility } from '@/hooks/use-chat-visibility'; +import { OverflowIcon, CheckIcon, ShareIcon, TrashIcon } from './icons'; + +const PureChatSidebarItem = ({ + chat, + isActive, + onSelect, + onDelete, +}: { + chat: Chat; + isActive: boolean; + onSelect: () => void; + onDelete: (chatId: string) => void; +}) => { + const { visibilityType, setVisibilityType } = useChatVisibility({ + chatId: chat.id, + initialVisibilityType: chat.visibility, + }); + + return ( + + + {chat.title} + + + + + + + More + + + + + + + + Share + + + + setVisibilityType('private')} + > +
+ {visibilityType === 'private' ? :
} + Private +
+ + setVisibilityType('public')} + > +
+ {visibilityType === 'public' ? :
} + Public +
+ + + + + + onDelete(chat.id)} + > + + Delete + + + + + ); +}; + +export const ChatSidebarItem = memo(PureChatSidebarItem, (prev, next) => { + if (prev.isActive !== next.isActive) return false; + if (prev.chat.title !== next.chat.title) return false; + if (prev.chat.visibility !== next.chat.visibility) return false; + return true; +}); diff --git a/integrations/appkit-agent/client/src/components/DatabricksLogo.tsx b/integrations/appkit-agent/client/src/components/DatabricksLogo.tsx new file mode 100644 index 000000000..81b760d9c --- /dev/null +++ b/integrations/appkit-agent/client/src/components/DatabricksLogo.tsx @@ -0,0 +1,47 @@ +import * as React from "react" +import { cn } from "@/lib/utils" + +interface DatabricksLogoProps { + /** Height in px. Width scales proportionally (713:113 ratio). */ + height?: number + className?: string +} + +/** + * Full Databricks primary lockup. + * - Brickwork icon: always #FF3621 + * - Wordmark text: currentColor — inherits dark-mode text color from parent + */ +export function DatabricksLogo({ height = 20, className }: DatabricksLogoProps) { + const width = Math.round((713 / 113) * height) + return ( + + {/* Brickwork icon — always brand red */} + + {/* Wordmark text — currentColor for dark mode support */} + + + + + + + + + + + + + ) +} diff --git a/integrations/appkit-agent/client/src/components/animation-assistant-icon.tsx b/integrations/appkit-agent/client/src/components/animation-assistant-icon.tsx new file mode 100644 index 000000000..195504426 --- /dev/null +++ b/integrations/appkit-agent/client/src/components/animation-assistant-icon.tsx @@ -0,0 +1,222 @@ +import { cn } from '@/lib/utils'; +import { motion, useAnimation } from 'framer-motion'; +import { SparklesIcon } from 'lucide-react'; +import { useEffect } from 'react'; + +type AnimatedAssistantIconProps = { + /** Diameter of the inner SparklesIcon */ + size?: number; + /** Run the pulse / rotate animation while true */ + isLoading?: boolean; + // If true, the component will appear muted and animate at more slow and subtle + muted?: boolean; +}; + +export const AnimatedAssistantIcon = ({ + size = 20, + isLoading = false, + muted = false, +}: AnimatedAssistantIconProps) => { + /* ----------------------------------------------------------------- + * Gradient colours – we keep the original helper so the gradients + * stay exactly the same as before. + * ----------------------------------------------------------------- */ + const { bottomGradient, solidGradient, topGradient } = getAiGradientStyle(); + + /* ----------------------------------------------------------------- + * Motion controls – we split the three animated layers in separate + * animation objects so each can have its own timing / easing. + * ----------------------------------------------------------------- */ + const scaleControls = useAnimation(); // “pulse‑scale‑up” + const rotateControls = useAnimation(); // “pulse‑rotate” + + useEffect(() => { + if (isLoading) { + // 1️⃣ Scale – grows from 0.9 → 1.1 and back (alternate) + if (!muted) { + scaleControls.start({ + scale: [0.9, 1.1], + transition: { + repeat: Number.POSITIVE_INFINITY, + repeatType: 'reverse', + duration: 1, + ease: 'easeInOut', + }, + }); + } + + // 3️⃣ Rotating gradient – full spin every 2 seconds (continuous) + rotateControls.start({ + rotate: [0, 1800], + transition: { + repeat: Number.POSITIVE_INFINITY, + duration: 2, + ease: 'easeInOut', + }, + }); + } else { + // Stop all animations instantly – the circles stay at their “rest” + scaleControls.stop(); + rotateControls.stop(); + + /* ---------- SMOOTHLY RETURN TO RESTING STATE ------------- */ + scaleControls.start({ + scale: 1, + transition: { duration: 0.5, ease: 'easeOut' }, + }); + rotateControls.start({ + rotate: 0, + transition: { duration: 0.5, ease: 'easeOut' }, + }); + } + }, [isLoading, muted, scaleControls, rotateControls]); + + /* ----------------------------------------------------------------- + * Component markup – three stacked s: + * + * • outer – pulsating scale & gradient rotation + * • middle – solid gradient that also pulsates (scale down) + * • top – static gradient that holds the SparklesIcon + * ----------------------------------------------------------------- */ + return ( +
+ {/* ---------- 1️⃣ OUTER GRADIENT (rotates + pulses) ---------- */} + + + + + {/* ---------- 2️⃣ MIDDLE SOLID GRADIENT (pulses down) ---------- */} + + + {/* ---------- 3️⃣ TOP ICON (static) -------------------------- */} +
+ +
+
+ ); +}; + +/** + * Since we cannot use gradient colors for borders, we instead use composite background colors to achieve the same effect. + * + * Composite background colors are built from the top down, so the last one is also the one bottom one in the paint order. + * + * To achieve the design with gradient border colors, we use the following background colors: + * [ON TOP] A transparent gradient color that is used as a background + * [MIDDLE] A solid color that is used to back the next transparent background color + * [BOTTOM] A gradient color that is used as a border + * + * We also make use of padding-box to create an "inset" effect controlled by the border-width. + * This is what creates the illusion of a gradient border. + */ +export const getAiGradientStyle = () => { + // Currently these are the same for both light and dark mode, but we may want to change this in the future. + const branded = { + ai: { + /** For AI components, the top-left-oriented start color of gradient treatments. */ + gradientStart: '#4299E0', + /** For AI components, the mid color of gradient treatments. */ + gradientMid: '#CA42E0', + /** For AI components, the bottom-right-oriented end color of gradient treatments. */ + gradientEnd: '#FF5F46', + }, + }; + + const createGradient = (...colors: string[]) => + `linear-gradient(135deg, ${colors.join(', ')})`; + + const gradientColors = [ + branded.ai.gradientStart, + branded.ai.gradientMid, + branded.ai.gradientEnd, + ]; + + const topGradient = createGradient( + ...gradientColors.map((color) => hexToRGBA(color, 0.08) ?? ''), + ); + const solidGradient = createGradient( + 'var(--background)', + 'var(--background)', + ); + const bottomGradient = createGradient(...gradientColors); + + return { + topGradient, + solidGradient, + bottomGradient, + styling: { + border: '1px solid transparent', + background: [ + `${topGradient} padding-box`, + `${solidGradient} padding-box`, + `${bottomGradient} border-box`, + ].join(', '), + }, + }; +}; + +const hexToRGB = (hex: string): { r: number; g: number; b: number } | null => { + try { + const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); + if (!result) return null; + return { + r: Number.parseInt(result[1], 16), + g: Number.parseInt(result[2], 16), + b: Number.parseInt(result[3], 16), + }; + } catch { + return null; + } +}; + +/** + * Converts a hex color to an RGBA string. + * Useful if you need to add an alpha channel to a hex color. + */ +const hexToRGBA = (hex: string, alpha: number): string | null => { + const rgb = hexToRGB(hex); + if (rgb) return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha})`; + return null; +}; diff --git a/integrations/appkit-agent/client/src/components/app-sidebar.tsx b/integrations/appkit-agent/client/src/components/app-sidebar.tsx new file mode 100644 index 000000000..0d46f6615 --- /dev/null +++ b/integrations/appkit-agent/client/src/components/app-sidebar.tsx @@ -0,0 +1,111 @@ +import { useNavigate } from 'react-router-dom'; +import { Link } from 'react-router-dom'; + +import { SidebarHistory } from '@/components/sidebar-history'; +import { SidebarUserNav } from '@/components/sidebar-user-nav'; +import { + Sidebar, + SidebarContent, + SidebarFooter, + SidebarHeader, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + useSidebar, +} from '@/components/ui/sidebar'; +import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'; +import { DbIcon } from '@/components/ui/db-icon'; +import { NewChatIcon, SidebarCollapseIcon, SidebarExpandIcon } from '@/components/icons'; +import { cn } from '@/lib/utils'; +import type { ClientSession } from '@/types'; +import { Button } from './ui/button'; +import { Action } from './elements/actions'; + +export function AppSidebar({ + user, + preferredUsername, +}: { + user: ClientSession['user'] | undefined; + preferredUsername: string | null; +}) { + const navigate = useNavigate(); + const { setOpenMobile, open, openMobile, isMobile, toggleSidebar } = useSidebar(); + + const effectiveOpen = open || (isMobile && openMobile); + + return ( + + {/* ── Header: app title + collapse toggle ────────────────────────── */} + + {effectiveOpen && ( + setOpenMobile(false)} + className="flex items-center overflow-hidden px-1" + > + + Chatbot + + + )} + + + + + + + {/* ── Nav: New Chat item ───────────────────────────────────────────── */} +
+ + + + + { + setOpenMobile(false); + navigate('/'); + }} + > + + + New chat + + + + New chat + + + +
+ + {/* ── Chat history ────────────────────────────────────────────────── */} + + {effectiveOpen && } + + + {/* ── User nav ────────────────────────────────────────────────────── */} + + {user && ( + + )} + +
+ ); +} diff --git a/integrations/appkit-agent/client/src/components/chat-header.tsx b/integrations/appkit-agent/client/src/components/chat-header.tsx new file mode 100644 index 000000000..828dbc3da --- /dev/null +++ b/integrations/appkit-agent/client/src/components/chat-header.tsx @@ -0,0 +1,115 @@ +import { useNavigate } from 'react-router-dom'; + +import { SidebarToggle } from '@/components/sidebar-toggle'; +import { Button } from '@/components/ui/button'; +import { MessageSquareOff } from 'lucide-react'; +import { useAppConfig } from '@/contexts/AppConfigContext'; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from '@/components/ui/tooltip'; +import { PlusIcon, CloudOffIcon } from './icons'; +import { cn } from '../lib/utils'; +import { Skeleton } from './ui/skeleton'; +import type { ReactNode } from 'react'; + +const DOCS_URL = + 'https://docs.databricks.com/aws/en/generative-ai/agent-framework/chat-app'; + +export interface ChatHeaderProps { + title?: string; + empty?: boolean; + isLoadingTitle?: boolean; + /** Callback when user clicks "New Chat". Falls back to react-router navigate('/') when omitted. */ + onNewChat?: () => void; + /** Slot for extra action buttons rendered after the built-in ones */ + actions?: ReactNode; +} + +export function ChatHeader({ title, empty, isLoadingTitle, onNewChat, actions }: ChatHeaderProps) { + let navigateFallback: (() => void) | undefined; + try { + const navigate = useNavigate(); + navigateFallback = () => navigate('/'); + } catch { + // react-router not available — onNewChat prop is required + } + const handleNewChat = onNewChat ?? navigateFallback; + + const { chatHistoryEnabled, feedbackEnabled } = useAppConfig(); + + return ( +
+
+ +
+ + {(title || isLoadingTitle) && +

+ {isLoadingTitle ? + : + title + } +

+ } + +
+ {!chatHistoryEnabled && ( + + + + + + Ephemeral + + + +

Chat history disabled — conversations are not saved. Click to learn more.

+
+
+
+ )} + {!feedbackEnabled && ( + + + + + + Feedback disabled + + + +

Feedback submission disabled. Click to learn more.

+
+
+
+ )} + {actions} + {handleNewChat && ( + + )} +
+
+ ); +} diff --git a/integrations/appkit-agent/client/src/components/chat.tsx b/integrations/appkit-agent/client/src/components/chat.tsx new file mode 100644 index 000000000..6dde25227 --- /dev/null +++ b/integrations/appkit-agent/client/src/components/chat.tsx @@ -0,0 +1,337 @@ +import type { LanguageModelUsage, UIMessageChunk } from 'ai'; +import { useChat } from '@ai-sdk/react'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { useSWRConfig } from 'swr'; +import { ChatHeader } from '@/components/chat-header'; +import { fetchWithErrorHandlers, generateUUID } from '@/lib/utils'; +import { MultimodalInput } from './multimodal-input'; +import { Messages } from './messages'; +import type { + Attachment, + ChatMessage, + FeedbackMap, + VisibilityType, + ClientSession, +} from '@/types'; +import { ChatSDKError } from '@/types'; +import { apiUrl } from '@/lib/config'; +import { unstable_serialize } from 'swr/infinite'; +import { getChatHistoryPaginationKey } from './sidebar-history'; +import { toast } from './toast'; +import { useSearchParams } from 'react-router-dom'; +import { useChatVisibility } from '@/hooks/use-chat-visibility'; +import { isCredentialErrorMessage } from '@/lib/oauth-error-utils'; +import { ChatTransport } from '../lib/ChatTransport'; +import { softNavigateToChatId } from '@/lib/navigation'; +import { useAppConfig } from '@/contexts/AppConfigContext'; +import { Greeting } from './greeting'; + +export function Chat({ + id, + initialMessages, + initialChatModel, + initialVisibilityType, + isReadonly, + initialLastContext, + feedback = {}, + title, +}: { + id: string; + initialMessages: ChatMessage[]; + initialChatModel: string; + initialVisibilityType: VisibilityType; + isReadonly: boolean; + session: ClientSession; + initialLastContext?: LanguageModelUsage; + feedback?: FeedbackMap; + title?: string; +}) { + const { visibilityType } = useChatVisibility({ + chatId: id, + initialVisibilityType, + }); + + const { mutate } = useSWRConfig(); + const { chatHistoryEnabled } = useAppConfig(); + + const [input, setInput] = useState(''); + const [_usage, setUsage] = useState( + initialLastContext, + ); + + const [lastPart, setLastPart] = useState(); + const lastPartRef = useRef(lastPart); + lastPartRef.current = lastPart; + + // Single counter for resume attempts - reset when stream parts are received + const resumeAttemptCountRef = useRef(0); + const maxResumeAttempts = 3; + + const abortController = useRef(new AbortController()); + useEffect(() => { + return () => { + abortController.current?.abort('ABORT_SIGNAL'); + }; + }, []); + + const fetchWithAbort = useMemo(() => { + return async (input: RequestInfo | URL, init?: RequestInit) => { + // useChat does not cancel /stream requests when the component is unmounted + const signal = abortController.current?.signal; + return fetchWithErrorHandlers(input, { ...init, signal }); + }; + }, []); + + const stop = useCallback(() => { + abortController.current?.abort('USER_ABORT_SIGNAL'); + }, []); + + const isNewChat = initialMessages.length === 0; + const didFetchHistoryOnNewChat = useRef(false); + const fetchChatHistory = useCallback(() => { + mutate(unstable_serialize(getChatHistoryPaginationKey)); + }, [mutate]); + + // For new chats, the title arrives via a `data-title` stream part + // once backend title generation completes — no separate fetch needed. + const [streamTitle, setStreamTitle] = useState(); + const [titlePending, setTitlePending] = useState(false); + const displayTitle = title ?? streamTitle; + + const { + messages, + setMessages, + sendMessage, + status, + resumeStream, + clearError, + addToolApprovalResponse, + regenerate, + } = useChat({ + id, + messages: initialMessages, + experimental_throttle: 100, + generateId: generateUUID, + resume: id !== undefined && initialMessages.length > 0, // Enable automatic stream resumption + transport: new ChatTransport({ + onStreamPart: (part) => { + if (isNewChat && !didFetchHistoryOnNewChat.current) { + fetchChatHistory(); + if (chatHistoryEnabled) { + setTitlePending(true); + } + didFetchHistoryOnNewChat.current = true; + } + // Reset resume attempts when we successfully receive stream parts + resumeAttemptCountRef.current = 0; + setLastPart(part); + }, + api: apiUrl('/'), + fetch: fetchWithAbort, + prepareSendMessagesRequest({ messages, id, body }) { + const lastMessage = messages.at(-1); + const isUserMessage = lastMessage?.role === 'user'; + + // For continuations (non-user messages like tool results), we must always + // send previousMessages because the tool result only exists client-side + // and hasn't been saved to the database yet. + const needsPreviousMessages = !chatHistoryEnabled || !isUserMessage; + + return { + body: { + id, + // Only include message field for user messages (new messages) + // For continuation (assistant messages with tool results), omit message field + ...(isUserMessage ? { message: lastMessage } : {}), + selectedChatModel: initialChatModel, + selectedVisibilityType: visibilityType, + nextMessageId: generateUUID(), + // Send previous messages when: + // 1. Database is disabled (ephemeral mode) - always need client-side messages + // 2. Continuation request (tool results) - tool result only exists client-side + ...(needsPreviousMessages + ? { + previousMessages: isUserMessage + ? messages.slice(0, -1) + : messages, + } + : {}), + ...body, + }, + }; + }, + prepareReconnectToStreamRequest({ id }) { + return { + api: apiUrl(`/${id}/stream`), + credentials: 'include', + }; + }, + }), + onData: (dataPart) => { + if (dataPart.type === 'data-usage') { + setUsage(dataPart.data as LanguageModelUsage); + } + if (dataPart.type === 'data-title') { + setStreamTitle(dataPart.data as string); + setTitlePending(false); + fetchChatHistory(); + } + }, + onFinish: ({ + isAbort, + isDisconnect, + isError, + messages: finishedMessages, + }) => { + didFetchHistoryOnNewChat.current = false; + setTitlePending(false); + + // If user aborted, don't try to resume + if (isAbort) { + console.log('[Chat onFinish] Stream was aborted by user, not resuming'); + fetchChatHistory(); + return; + } + + // Check if the last message contains an OAuth credential error + // If so, don't try to resume - the user needs to authenticate first + const lastMessage = finishedMessages?.at(-1); + const hasOAuthError = lastMessage?.parts?.some( + (part) => + part.type === 'data-error' && + typeof part.data === 'string' && + isCredentialErrorMessage(part.data), + ); + + if (hasOAuthError) { + console.log( + '[Chat onFinish] OAuth credential error detected, not resuming', + ); + fetchChatHistory(); + clearError(); + return; + } + + // Determine if we should attempt to resume: + // 1. Stream didn't end with a 'finish' part (incomplete) + // 2. It was a disconnect/error that terminated the stream + // 3. We haven't exceeded max resume attempts + const streamIncomplete = lastPartRef.current?.type !== 'finish'; + const shouldResume = + streamIncomplete && + (isDisconnect || isError || lastPartRef.current === undefined); + + if (shouldResume && resumeAttemptCountRef.current < maxResumeAttempts) { + console.log( + '[Chat onFinish] Resuming stream. Attempt:', + resumeAttemptCountRef.current + 1, + ); + resumeAttemptCountRef.current++; + // Ref: https://github.com/vercel/ai/issues/8477#issuecomment-3603209884 + queueMicrotask(() => { + resumeStream(); + }) + } else { + // Stream completed normally or we've exhausted resume attempts + if (resumeAttemptCountRef.current >= maxResumeAttempts) { + console.warn('[Chat onFinish] Max resume attempts reached'); + } + fetchChatHistory(); + } + }, + onError: (error) => { + console.log('[Chat onError] Error occurred:', error); + + // Only show toast for explicit ChatSDKError (backend validation errors) + // Other errors (network, schema validation) are handled silently or in message parts + if (error instanceof ChatSDKError) { + toast({ + type: 'error', + description: error.message, + }); + } else { + // Non-ChatSDKError: Could be network error or in-stream error + // Log but don't toast - errors during streaming may be informational + console.warn('[Chat onError] Error during streaming:', error.message); + } + // Note: We don't call resumeStream here because onError can be called + // while the stream is still active (e.g., for data-error parts). + // Resume logic is handled exclusively in onFinish. + }, + }); + + const [searchParams] = useSearchParams(); + const query = searchParams.get('query'); + + const [hasAppendedQuery, setHasAppendedQuery] = useState(false); + + useEffect(() => { + if (query && !hasAppendedQuery) { + sendMessage({ + role: 'user' as const, + parts: [{ type: 'text', text: query }], + }); + + setHasAppendedQuery(true); + softNavigateToChatId(id, chatHistoryEnabled); + } + }, [query, sendMessage, hasAppendedQuery, id, chatHistoryEnabled]); + + const [attachments, setAttachments] = useState>([]); + + const inputElement = + + if (messages.length === 0) { + return ( +
+ +
+
+ + {inputElement} +
+
+
+ ); + } + + return ( + <> +
+ + + + + + +
+ {!isReadonly && ( + inputElement + )} +
+
+ + ); +} diff --git a/integrations/appkit-agent/client/src/components/data-stream-provider.tsx b/integrations/appkit-agent/client/src/components/data-stream-provider.tsx new file mode 100644 index 000000000..d214364c3 --- /dev/null +++ b/integrations/appkit-agent/client/src/components/data-stream-provider.tsx @@ -0,0 +1,38 @@ +import React, { createContext, useContext, useMemo, useState } from 'react'; +import type { DataUIPart } from 'ai'; +import type { CustomUIDataTypes } from '@/types'; + +interface DataStreamContextValue { + dataStream: DataUIPart[]; + setDataStream: React.Dispatch< + React.SetStateAction[]> + >; +} + +const DataStreamContext = createContext(null); + +export function DataStreamProvider({ + children, +}: { + children: React.ReactNode; +}) { + const [dataStream, setDataStream] = useState[]>( + [], + ); + + const value = useMemo(() => ({ dataStream, setDataStream }), [dataStream]); + + return ( + + {children} + + ); +} + +export function useDataStream() { + const context = useContext(DataStreamContext); + if (!context) { + throw new Error('useDataStream must be used within a DataStreamProvider'); + } + return context; +} diff --git a/integrations/appkit-agent/client/src/components/databricks-message-citation.tsx b/integrations/appkit-agent/client/src/components/databricks-message-citation.tsx new file mode 100644 index 000000000..349101687 --- /dev/null +++ b/integrations/appkit-agent/client/src/components/databricks-message-citation.tsx @@ -0,0 +1,109 @@ +import type { ChatMessage } from '@/types'; +import type { + AnchorHTMLAttributes, + ComponentType, + PropsWithChildren, +} from 'react'; +import { Tooltip, TooltipContent, TooltipTrigger } from './ui/tooltip'; +import { cn } from '@/lib/utils'; + +/** + * ReactMarkdown/Streamdown component that handles Databricks message citations. + * + * @example + * + */ +export const DatabricksMessageCitationStreamdownIntegration: ComponentType< + AnchorHTMLAttributes +> = (props) => { + if (isDatabricksMessageCitationLink(props.href)) { + return ( + + ); + } + return ; +}; + +// const isFootnoteLink + +type SourcePart = Extract; + +// Adds a unique suffix to the link to indicate that it is a Databricks message citation. +const encodeDatabricksMessageCitationLink = (part: SourcePart) => + `${part.url}::databricks_citation`; + +// Removes the unique suffix from the link to get the original link. +const decodeDatabricksMessageCitationLink = (link: string) => + link.replace('::databricks_citation', ''); + +// Creates a markdown link to the Databricks message citation. +export const createDatabricksMessageCitationMarkdown = (part: SourcePart) => + `[${part.title || part.url}](${encodeDatabricksMessageCitationLink(part)})`; + +// Checks if the link is a Databricks message citation. +const isDatabricksMessageCitationLink = ( + link?: string, +): link is `${string}::databricks_citation` => + link?.endsWith('::databricks_citation') ?? false; + +// Renders the Databricks message citation. +const DatabricksMessageCitationRenderer = ( + props: PropsWithChildren<{ + href: string; + }>, +) => { + return ( + + + + {props.children} + + + + {props.href} + + + ); +}; + +// Copied from streamdown +// https://github.com/vercel/streamdown/blob/dc5bd12e5709afce09814e47cf80884f8c665b3d/packages/streamdown/lib/components.tsx#L157-L181 +const DefaultAnchor: ComponentType> = ( + props, +) => { + const isIncomplete = props.href === 'streamdown:incomplete-link'; + const isFootnoteLink = props.href?.startsWith('#'); + + return ( + + {props.children} + + ); +}; diff --git a/integrations/appkit-agent/client/src/components/databricks-message-part-transformers.ts b/integrations/appkit-agent/client/src/components/databricks-message-part-transformers.ts new file mode 100644 index 000000000..4fc60f5ea --- /dev/null +++ b/integrations/appkit-agent/client/src/components/databricks-message-part-transformers.ts @@ -0,0 +1,84 @@ +import type { ChatMessage } from '@/types'; +import { createDatabricksMessageCitationMarkdown } from './databricks-message-citation'; +import type { TextUIPart } from 'ai'; + +/** + * Creates segments of parts that can be rendered as a single component. + * Used to render citations as part of the associated text. + */ +export const createMessagePartSegments = (parts: ChatMessage['parts']) => { + // An array of arrays of parts + // Allows us to render multiple parts as a single component + const out: ChatMessage['parts'][] = []; + for (const part of parts) { + const lastBlock = out[out.length - 1] || null; + const previousPart = lastBlock?.[lastBlock.length - 1] || null; + + // If the previous part is a text part and the current part is a source part, add it to the current block + if (previousPart?.type === 'text' && part.type === 'source-url') { + lastBlock.push(part); + } + // If the previous part is a source-url part and the current part is a source part, add it to the current block + else if ( + previousPart?.type === 'source-url' && + part.type === 'source-url' + ) { + lastBlock.push(part); + } else if ( + lastBlock?.[0]?.type === 'text' && + part.type === 'text' && + !isNamePart(part) && + !isNamePart(lastBlock[0]) + ) { + // If the text part, or the previous part contains a tag, add it to a new block + // Otherwise, append sequential text parts to the same block + lastBlock.push(part); + // } + } + // Otherwise, add the current part to a new block + else { + out.push([part]); + } + } + + return out; +}; + +export const isNamePart = ( + part: ChatMessage['parts'][number], +): part is TextUIPart => { + return ( + part.type === 'text' && + part.text?.startsWith('') && + part.text?.endsWith('') + ); +}; +export const formatNamePart = (part: ChatMessage['parts'][number]) => { + if (!isNamePart(part)) return null; + return part.text?.replace('', '').replace('', ''); +}; + +/** + * Takes a segment of parts and joins them into a markdown-formatted string. + * Used to render citations as part of the associated text. + */ +export const joinMessagePartSegments = (parts: ChatMessage['parts']) => { + return parts.reduce((acc, part) => { + switch (part.type) { + case 'text': + return acc + part.text; + case 'source-url': + console.log("acc.endsWith('|')", acc.endsWith('|')); + // Special case for markdown tables + if (acc.endsWith('|')) { + // 1. Remove the last pipe + // 2. Insert the citation markdown + // 3. Add the pipe back + return `${acc.slice(0, -1)} ${createDatabricksMessageCitationMarkdown(part)}|`; + } + return `${acc} ${createDatabricksMessageCitationMarkdown(part)}`; + default: + return acc; + } + }, ''); +}; diff --git a/integrations/appkit-agent/client/src/components/elements/actions.tsx b/integrations/appkit-agent/client/src/components/elements/actions.tsx new file mode 100644 index 000000000..9684d3487 --- /dev/null +++ b/integrations/appkit-agent/client/src/components/elements/actions.tsx @@ -0,0 +1,66 @@ +import { Button } from '@/components/ui/button'; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from '@/components/ui/tooltip'; +import { cn } from '@/lib/utils'; +import type { ComponentProps } from 'react'; + +type ActionsProps = ComponentProps<'div'>; + +export const Actions = ({ className, children, ...props }: ActionsProps) => ( +
+ {children} +
+); + +type ActionProps = ComponentProps & { + tooltip?: string; + label?: string; + iconOnly?: boolean; +}; + +export const Action = ({ + tooltip, + children, + label, + className, + variant = 'tertiary', + size = 'sm', + iconOnly = true, + ...props +}: ActionProps) => { + const button = ( + + ); + + if (tooltip) { + return ( + + + {button} + +

{tooltip}

+
+
+
+ ); + } + + return button; +}; diff --git a/integrations/appkit-agent/client/src/components/elements/code-block.tsx b/integrations/appkit-agent/client/src/components/elements/code-block.tsx new file mode 100644 index 000000000..2efc92e4f --- /dev/null +++ b/integrations/appkit-agent/client/src/components/elements/code-block.tsx @@ -0,0 +1,102 @@ +import { cn } from '@/lib/utils'; +import type { HTMLAttributes, ReactNode } from 'react'; +import { createContext } from 'react'; +import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; +import { + oneDark, + oneLight, +} from 'react-syntax-highlighter/dist/esm/styles/prism'; + +type CodeBlockContextType = { + code: string; +}; + +const CodeBlockContext = createContext({ + code: '', +}); + +type CodeBlockProps = HTMLAttributes & { + code: string; + language: string; + showLineNumbers?: boolean; + children?: ReactNode; +}; + +export const CodeBlock = ({ + code, + language, + showLineNumbers = false, + className, + children, + ...props +}: CodeBlockProps) => ( + +
+
+ + {code} + + + {code} + + {children && ( +
+ {children} +
+ )} +
+
+
+); diff --git a/integrations/appkit-agent/client/src/components/elements/conversation.tsx b/integrations/appkit-agent/client/src/components/elements/conversation.tsx new file mode 100644 index 000000000..0c6b4f125 --- /dev/null +++ b/integrations/appkit-agent/client/src/components/elements/conversation.tsx @@ -0,0 +1,27 @@ +import { cn } from '@/lib/utils'; +import type { ComponentProps } from 'react'; +import { StickToBottom } from 'use-stick-to-bottom'; + +type ConversationProps = ComponentProps; + +export const Conversation = ({ className, ...props }: ConversationProps) => ( + +); + +type ConversationContentProps = ComponentProps; + +export const ConversationContent = ({ + className, + ...props +}: ConversationContentProps) => ( + +); diff --git a/integrations/appkit-agent/client/src/components/elements/loader.tsx b/integrations/appkit-agent/client/src/components/elements/loader.tsx new file mode 100644 index 000000000..bb83e3e18 --- /dev/null +++ b/integrations/appkit-agent/client/src/components/elements/loader.tsx @@ -0,0 +1,96 @@ +import { cn } from '@/lib/utils'; +import type { HTMLAttributes } from 'react'; + +type LoaderIconProps = { + size?: number; +}; + +const LoaderIcon = ({ size = 16 }: LoaderIconProps) => ( + + Loader + + + + + + + + + + + + + + + + + + +); + +type LoaderProps = HTMLAttributes & { + size?: number; +}; + +export const Loader = ({ className, size = 16, ...props }: LoaderProps) => ( +
+ +
+); diff --git a/integrations/appkit-agent/client/src/components/elements/mcp-tool.tsx b/integrations/appkit-agent/client/src/components/elements/mcp-tool.tsx new file mode 100644 index 000000000..7360f10d3 --- /dev/null +++ b/integrations/appkit-agent/client/src/components/elements/mcp-tool.tsx @@ -0,0 +1,246 @@ +import { Button } from '@/components/ui/button'; +import { CollapsibleTrigger } from '@/components/ui/collapsible'; +import { cn } from '@/lib/utils'; +import { + ChevronDownIcon, + ServerIcon, + ShieldAlertIcon, + ShieldCheckIcon, + ShieldXIcon, +} from 'lucide-react'; +import { + ToolContainer, + ToolContent, + ToolInput, + ToolOutput, + ToolStatusBadge, + type ToolState, +} from './tool'; + +// MCP-specific container with distinct styling +type McpToolProps = Parameters[0]; + +export const McpTool = ({ className, ...props }: McpToolProps) => ( + +); + +// Re-export shared components for convenience +export { + ToolContent as McpToolContent, + ToolInput as McpToolInput, + ToolOutput as McpToolOutput, +}; + +// MCP-specific header with banner +type McpToolHeaderProps = { + serverName?: string; + toolName: string; + state: ToolState; + // Used when state is 'approval-responded' to determine approval outcome + approved?: boolean; + className?: string; +}; + +// Badge component for approval status in the banner +// Uses AI SDK native tool states directly +type ApprovalStatusBadgeProps = { + state: ToolState; + // Used when state is 'approval-responded' to determine approval outcome + approved?: boolean; +}; + +const ApprovalStatusBadge = ({ state, approved }: ApprovalStatusBadgeProps) => { + // Pending: waiting for user approval + if (state === 'approval-requested') { + return ( + + + Pending + + ); + } + + // Allowed: tool executed successfully or user approved (waiting for execution) + if ( + state === 'output-available' || + (state === 'approval-responded' && approved === true) + ) { + return ( + + + Allowed + + ); + } + + // Denied: user explicitly denied the tool + if ( + state === 'output-denied' || + (state === 'approval-responded' && approved === false) + ) { + return ( + + + Denied + + ); + } + + // Fallback for any other state - show as pending + return ( + + + Pending + + ); +}; + +export const McpToolHeader = ({ + className, + serverName, + toolName, + state, + approved, +}: McpToolHeaderProps) => ( +
+ {/* MCP Banner */} +
+ + + Tool Call Request + + {serverName && ( + <> + + {serverName} + + )} + + +
+ {/* Tool header */} + +
+ {toolName} +
+
+ {/* Only show tool status badge when tool is running/completed (approved) */} + {(state === 'output-available' || + (state === 'approval-responded' && approved === true)) && ( + + )} + +
+
+
+); + +// MCP-specific approval actions +type McpApprovalActionsProps = { + onApprove: () => void; + onDeny: () => void; + isSubmitting: boolean; +}; + +export const McpApprovalActions = ({ + onApprove, + onDeny, + isSubmitting, +}: McpApprovalActionsProps) => ( +
+
+ +

+ This tool requires your permission to run. +

+
+
+ + +
+
+); + +// MCP-specific approval status display +type McpApprovalStatusProps = { + approved: boolean; + reason?: string; +}; + +export const McpApprovalStatus = ({ + approved, + reason, +}: McpApprovalStatusProps) => ( +
+ {approved ? ( + + ) : ( + + )} + + {approved ? 'Allowed' : 'Denied'} + + {reason && ( + <> + + {reason} + + )} +
+); diff --git a/integrations/appkit-agent/client/src/components/elements/message.tsx b/integrations/appkit-agent/client/src/components/elements/message.tsx new file mode 100644 index 000000000..4801f443f --- /dev/null +++ b/integrations/appkit-agent/client/src/components/elements/message.tsx @@ -0,0 +1,23 @@ +import { cn } from '@/lib/utils'; +import type { HTMLAttributes } from 'react'; + +type MessageContentProps = HTMLAttributes; + +export const MessageContent = ({ + children, + className, + ...props +}: MessageContentProps) => ( +
+ {children} +
+); diff --git a/integrations/appkit-agent/client/src/components/elements/prompt-input.tsx b/integrations/appkit-agent/client/src/components/elements/prompt-input.tsx new file mode 100644 index 000000000..36a2ee605 --- /dev/null +++ b/integrations/appkit-agent/client/src/components/elements/prompt-input.tsx @@ -0,0 +1,159 @@ +import { Button } from '@/components/ui/button'; +import { Textarea } from '@/components/ui/textarea'; +import { cn } from '@/lib/utils'; +import type { ChatStatus } from 'ai'; +import { Loader2Icon, SendIcon, SquareIcon, XIcon } from 'lucide-react'; +import { + forwardRef, + type ComponentProps, + type HTMLAttributes, + type KeyboardEventHandler, +} from 'react'; +import { DbIcon } from '../ui/db-icon'; +import { ChevronDownIcon, ChevronUpIcon } from '../icons'; + +type PromptInputProps = HTMLAttributes; + +export const PromptInput = ({ className, ...props }: PromptInputProps) => ( +
+); + +type PromptInputTextareaProps = ComponentProps & { + minHeight?: number; + maxHeight?: number; + disableAutoResize?: boolean; + resizeOnNewLinesOnly?: boolean; +}; + +export const PromptInputTextarea = forwardRef< + HTMLTextAreaElement, + PromptInputTextareaProps +>( + ( + { + onChange, + className, + placeholder = 'What would you like to know?', + minHeight = 48, + maxHeight = 164, + disableAutoResize = false, + resizeOnNewLinesOnly = false, + ...props + }, + ref, + ) => { + const handleKeyDown: KeyboardEventHandler = (e) => { + if (e.key === 'Enter') { + // Don't submit if IME composition is in progress + if (e.nativeEvent.isComposing) { + return; + } + + if (e.shiftKey) { + // Allow newline + return; + } + + // Submit on Enter (without Shift) + e.preventDefault(); + const form = e.currentTarget.form; + if (form) { + form.requestSubmit(); + } + } + }; + + return ( +