diff --git a/.github/workflows/push-dev-kiloclaw.yml b/.github/workflows/push-dev-kiloclaw.yml index e934fc629..9014e92e9 100644 --- a/.github/workflows/push-dev-kiloclaw.yml +++ b/.github/workflows/push-dev-kiloclaw.yml @@ -5,6 +5,7 @@ on: permissions: contents: read + packages: write jobs: push-dev: @@ -28,6 +29,13 @@ jobs: username: x password: ${{ secrets.FLY_DEV_API_TOKEN }} + - name: Login to GHCR + uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Generate image tag and cache bust value id: tag run: | @@ -72,6 +80,8 @@ jobs: push: true tags: | registry.fly.io/kiloclaw-registry-dev:${{ steps.tag.outputs.tag }} + ghcr.io/kilo-org/kiloclaw:${{ steps.tag.outputs.tag }} + ghcr.io/kilo-org/kiloclaw:sha-${{ github.sha }} build-args: | CONTROLLER_COMMIT=${{ github.sha }} CONTROLLER_CACHE_BUST=${{ steps.tag.outputs.cache_bust }} @@ -115,7 +125,16 @@ jobs: echo "FLY_IMAGE_CONTENT_HASH=${CONTENT}" echo '```' echo "" - echo "**Image pushed to:** \`registry.fly.io/kiloclaw-registry-dev:${TAG}\`" + echo "**Images pushed to:**" + echo "- \`registry.fly.io/kiloclaw-registry-dev:${TAG}\`" + echo "- \`ghcr.io/kilo-org/kiloclaw:${TAG}\`" + echo "- \`ghcr.io/kilo-org/kiloclaw:sha-${{ github.sha }}\`" + echo "" + echo "For Northflank, use:" + echo "" + echo '```' + echo "NF_IMAGE_PATH_TEMPLATE=ghcr.io/kilo-org/kiloclaw:{tag}" + echo '```' echo "" } >> "$GITHUB_STEP_SUMMARY" @@ -127,4 +146,7 @@ jobs: fi echo "OPENCLAW_VERSION=${OPENCLAW}" echo "FLY_IMAGE_CONTENT_HASH=${CONTENT}" + echo "NF_IMAGE_PATH_TEMPLATE=ghcr.io/kilo-org/kiloclaw:{tag}" + echo "GHCR_IMAGE=ghcr.io/kilo-org/kiloclaw:${TAG}" + echo "GHCR_SHA_IMAGE=ghcr.io/kilo-org/kiloclaw:sha-${{ github.sha }}" echo "==========================" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 76a01012f..1eff11129 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -111,7 +111,7 @@ importers: version: 9.1.7 ink: specifier: ^6.8.0 - version: 6.8.0(@types/react@19.2.14)(react-devtools-core@6.1.5)(react@19.2.4) + version: 6.8.0(@types/react@19.2.14)(bufferutil@4.1.0)(react-devtools-core@6.1.5(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react@19.2.4)(utf-8-validate@6.0.6) oxfmt: specifier: ^0.40.0 version: 0.40.0 @@ -144,16 +144,16 @@ importers: version: link:../../packages/trpc '@react-native-community/netinfo': specifier: 11.5.2 - version: 11.5.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + version: 11.5.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) '@rn-primitives/portal': specifier: ^1.3.0 - version: 1.3.0(@types/react@19.2.14)(immer@11.1.4)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0)) + version: 1.3.0(@types/react@19.2.14)(immer@11.1.4)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0)) '@rn-primitives/slot': specifier: ^1.2.0 - version: 1.2.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + version: 1.2.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) '@sentry/react-native': specifier: ~7.11.0 - version: 7.11.0(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + version: 7.11.0(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) '@tailwindcss/postcss': specifier: ^4.2.2 version: 4.2.2 @@ -174,28 +174,28 @@ importers: version: 2.1.1 expo: specifier: ~55.0.12 - version: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + version: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-apple-authentication: specifier: ~55.0.12 - version: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)) + version: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) expo-application: specifier: ~55.0.13 version: 55.0.13(expo@55.0.12) expo-asset: specifier: ~55.0.13 - version: 55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + version: 55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3) expo-audio: specifier: ~55.0.12 - version: 55.0.12(expo-asset@55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3))(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + version: 55.0.12(expo-asset@55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3))(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) expo-build-properties: specifier: ~55.0.12 version: 55.0.12(expo@55.0.12) expo-clipboard: specifier: ~55.0.12 - version: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + version: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) expo-constants: specifier: ~55.0.12 - version: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) + version: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(typescript@5.9.3) expo-crypto: specifier: ~55.0.14 version: 55.0.14(expo@55.0.12) @@ -210,7 +210,7 @@ importers: version: 55.0.13(expo@55.0.12) expo-image: specifier: ~55.0.8 - version: 55.0.8(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + version: 55.0.8(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) expo-image-manipulator: specifier: ~55.0.14 version: 55.0.14(expo@55.0.12) @@ -222,82 +222,82 @@ importers: version: 55.0.15(expo@55.0.12) expo-linking: specifier: ~55.0.11 - version: 55.0.11(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + version: 55.0.11(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3) expo-notifications: specifier: ~55.0.17 - version: 55.0.17(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + version: 55.0.17(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3) expo-router: specifier: ~55.0.11 - version: 55.0.11(@expo/log-box@55.0.10)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-linking@55.0.11)(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native-gesture-handler@2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + version: 55.0.11(19d76ea0d0b88bce60b3b715cef8728d) expo-secure-store: specifier: ~55.0.12 version: 55.0.12(expo@55.0.12) expo-sharing: specifier: ~55.0.17 - version: 55.0.17(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + version: 55.0.17(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) expo-splash-screen: specifier: ~55.0.16 version: 55.0.16(expo@55.0.12)(typescript@5.9.3) expo-status-bar: specifier: ~55.0.5 - version: 55.0.5(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + version: 55.0.5(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) expo-tracking-transparency: specifier: ~55.0.12 - version: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)) + version: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) expo-video: specifier: ~55.0.14 - version: 55.0.14(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + version: 55.0.14(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) expo-web-browser: specifier: ~55.0.13 - version: 55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)) + version: 55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) jotai: specifier: ^2.18.1 version: 2.18.1(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@19.2.14)(react@19.2.0) lucide-react-native: specifier: ^1.7.0 - version: 1.7.0(react-native-svg@15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + version: 1.7.0(react-native-svg@15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) nativewind: specifier: 5.0.0-preview.3 - version: 5.0.0-preview.3(react-native-css@3.0.6(@expo/metro-config@55.0.14(expo@55.0.12)(typescript@5.9.3))(lightningcss@1.30.1)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(tailwindcss@4.2.2) + version: 5.0.0-preview.3(react-native-css@3.0.6(@expo/metro-config@55.0.14(bufferutil@4.1.0)(expo@55.0.12)(typescript@5.9.3)(utf-8-validate@6.0.6))(lightningcss@1.30.1)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(tailwindcss@4.2.2) react: specifier: 19.2.0 version: 19.2.0 react-native: specifier: 0.83.4 - version: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + version: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) react-native-appsflyer: specifier: ^6.17.9 version: 6.17.9 react-native-css: specifier: 3.0.6 - version: 3.0.6(@expo/metro-config@55.0.14(expo@55.0.12)(typescript@5.9.3))(lightningcss@1.30.1)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + version: 3.0.6(@expo/metro-config@55.0.14(bufferutil@4.1.0)(expo@55.0.12)(typescript@5.9.3)(utf-8-validate@6.0.6))(lightningcss@1.30.1)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) react-native-gesture-handler: specifier: ~2.30.0 - version: 2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + version: 2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) react-native-reanimated: specifier: 4.2.1 - version: 4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + version: 4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) react-native-safe-area-context: specifier: ~5.6.2 - version: 5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + version: 5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) react-native-screens: specifier: ~4.23.0 - version: 4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + version: 4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) react-native-svg: specifier: 15.15.3 - version: 15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + version: 15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) react-native-worklets: specifier: 0.7.2 - version: 0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + version: 0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) sonner-native: specifier: ^0.23.1 - version: 0.23.1(react-native-gesture-handler@2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-svg@15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + version: 0.23.1(53175ba88151f39b99a3b76a61c65c1d) stream-chat: specifier: 'catalog:' - version: 9.38.0 + version: 9.38.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) stream-chat-expo: specifier: ^8.13.7 - version: 8.13.7(1e63c802e7ba809d1a117ef902c76ac6) + version: 8.13.7(ca06b49660395c2e8a06a215cb1b2881) tailwind-merge: specifier: ^3.5.0 version: 3.5.0 @@ -362,25 +362,25 @@ importers: version: 3.14.0(@faker-js/faker@10.3.0)(zod@4.3.6) '@chromatic-com/storybook': specifier: ^4.1.3 - version: 4.1.3(@chromatic-com/playwright@0.12.8(@playwright/test@1.58.2)(@types/react@19.2.14)(esbuild@0.27.4)(typescript@5.9.3)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + version: 4.1.3(@chromatic-com/playwright@0.12.8(@playwright/test@1.58.2)(@types/react@19.2.14)(bufferutil@4.1.0)(esbuild@0.27.4)(typescript@5.9.3)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) '@faker-js/faker': specifier: ^10.3.0 version: 10.3.0 '@storybook/addon-docs': specifier: ^9.1.20 - version: 9.1.20(@types/react@19.2.14)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + version: 9.1.20(@types/react@19.2.14)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) '@storybook/addon-links': specifier: ^9.1.20 - version: 9.1.20(react@19.2.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + version: 9.1.20(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) '@storybook/addon-themes': specifier: ^9.1.20 - version: 9.1.20(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + version: 9.1.20(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) '@storybook/nextjs': specifier: ^9.1.20 - version: 9.1.20(patch_hash=e1857649664eed8f87877c352d277c90d4af5a58d0ad931105f033c8c08165c1)(esbuild@0.27.4)(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(type-fest@4.41.0)(typescript@5.9.3)(webpack-hot-middleware@2.26.1)(webpack@5.105.4(esbuild@0.27.4)) + version: 9.1.20(patch_hash=e1857649664eed8f87877c352d277c90d4af5a58d0ad931105f033c8c08165c1)(esbuild@0.27.4)(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(type-fest@4.41.0)(typescript@5.9.3)(webpack-hot-middleware@2.26.1)(webpack@5.105.4(esbuild@0.27.4)) '@storybook/test-runner': specifier: ^0.23.0 - version: 0.23.0(@types/node@25.5.0)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + version: 0.23.0(@types/node@25.5.0)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) '@tailwindcss/typography': specifier: ^0.5.19 version: 0.5.19(tailwindcss@4.2.2) @@ -395,7 +395,7 @@ importers: version: 7.0.0-dev.20260319.1 chromatic: specifier: ^13.3.5 - version: 13.3.5(@chromatic-com/playwright@0.12.8(@playwright/test@1.58.2)(@types/react@19.2.14)(esbuild@0.27.4)(typescript@5.9.3)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + version: 13.3.5(@chromatic-com/playwright@0.12.8(@playwright/test@1.58.2)(@types/react@19.2.14)(bufferutil@4.1.0)(esbuild@0.27.4)(typescript@5.9.3)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) dotenv: specifier: ^17.3.1 version: 17.3.1 @@ -413,7 +413,7 @@ importers: version: 3.0.5 storybook: specifier: ^9.1.17 - version: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) tailwindcss: specifier: ^4.2.1 version: 4.2.2 @@ -485,13 +485,13 @@ importers: version: 3.1.1(@types/react@19.2.14)(react@19.2.4) '@mistralai/mistralai': specifier: ^1.15.1 - version: 1.15.1 + version: 1.15.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@monaco-editor/react': specifier: ^4.7.0 version: 4.7.0(monaco-editor@0.55.1)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@next/bundle-analyzer': specifier: ^16.1.6 - version: 16.1.6 + version: 16.1.6(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@next/mdx': specifier: ^16.1.6 version: 16.1.6(@mdx-js/loader@3.1.1(webpack@5.105.4(@swc/core@1.15.18)(esbuild@0.27.4)))(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4)) @@ -662,7 +662,7 @@ importers: version: 4.4.0 discord.js: specifier: ^14.25.1 - version: 14.25.1 + version: 14.25.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) drizzle-orm: specifier: 'catalog:' version: 0.45.1(@cloudflare/workers-types@4.20260313.1)(@opentelemetry/api@1.9.0)(@types/pg@8.18.0)(bun-types@1.3.11)(pg@8.20.0) @@ -713,7 +713,7 @@ importers: version: 4.24.13(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) openai: specifier: ^6.29.0 - version: 6.29.0(ws@8.19.0)(zod@4.3.6) + version: 6.29.0(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(zod@4.3.6) posthog-js: specifier: ^1.360.2 version: 1.360.2 @@ -752,10 +752,10 @@ importers: version: 2.0.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4) stream-chat: specifier: ^9.38.0 - version: 9.38.0 + version: 9.38.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) stream-chat-react: specifier: ^13.14.2 - version: 13.14.2(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(stream-chat@9.38.0)(typescript@5.9.3) + version: 13.14.2(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(stream-chat@9.38.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(typescript@5.9.3) stripe: specifier: 'catalog:' version: 19.3.0(@types/node@24.12.0) @@ -780,7 +780,7 @@ importers: devDependencies: '@chromatic-com/playwright': specifier: ^0.12.8 - version: 0.12.8(@playwright/test@1.58.2)(@swc/core@1.15.18)(@types/react@19.2.14)(esbuild@0.27.4)(typescript@5.9.3) + version: 0.12.8(@playwright/test@1.58.2)(@swc/core@1.15.18)(@types/react@19.2.14)(bufferutil@4.1.0)(esbuild@0.27.4)(typescript@5.9.3)(utf-8-validate@6.0.6) '@jest/globals': specifier: ^30.3.0 version: 30.3.0 @@ -828,7 +828,7 @@ importers: version: 17.3.1 ink: specifier: ^6.8.0 - version: 6.8.0(@types/react@19.2.14)(react-devtools-core@6.1.5)(react@19.2.4) + version: 6.8.0(@types/react@19.2.14)(bufferutil@4.1.0)(react-devtools-core@6.1.5(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react@19.2.4)(utf-8-validate@6.0.6) jest: specifier: ^30.3.0 version: 30.3.0(@types/node@24.12.0)(esbuild-register@3.6.0(esbuild@0.27.4)) @@ -1031,7 +1031,7 @@ importers: version: 5.9.3 wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/app-builder: dependencies: @@ -1089,7 +1089,7 @@ importers: version: 4.1.0(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/auto-fix-infra: dependencies: @@ -1111,7 +1111,7 @@ importers: version: 5.9.3 wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/auto-triage-infra: dependencies: @@ -1136,7 +1136,7 @@ importers: version: 5.9.3 wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/cloud-agent: dependencies: @@ -1173,7 +1173,7 @@ importers: devDependencies: '@cloudflare/vitest-pool-workers': specifier: ^0.12.21 - version: 0.12.21(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(vitest@3.2.4) + version: 0.12.21(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vitest@3.2.4) '@cloudflare/workers-types': specifier: 'catalog:' version: 4.20260313.1 @@ -1200,7 +1200,7 @@ importers: version: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(@vitest/ui@3.2.4)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/cloud-agent-next: dependencies: @@ -1249,7 +1249,7 @@ importers: version: 0.3.0 '@cloudflare/vitest-pool-workers': specifier: ^0.12.21 - version: 0.12.21(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(vitest@3.2.4) + version: 0.12.21(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vitest@3.2.4) '@types/jsonwebtoken': specifier: 'catalog:' version: 9.0.10 @@ -1273,7 +1273,7 @@ importers: version: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(@vitest/ui@3.2.4)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/cloud-agent-next/wrapper: dependencies: @@ -1329,7 +1329,7 @@ importers: version: 5.9.3 wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/db-proxy: dependencies: @@ -1351,7 +1351,7 @@ importers: devDependencies: '@cloudflare/vitest-pool-workers': specifier: ^0.12.21 - version: 0.12.21(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + version: 0.12.21(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) '@types/jest': specifier: ^30.0.0 version: 30.0.0 @@ -1372,7 +1372,7 @@ importers: version: 5.9.3 wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/deploy-infra/builder: dependencies: @@ -1430,7 +1430,7 @@ importers: version: 5.9.3 wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/deploy-infra/dispatcher: dependencies: @@ -1467,7 +1467,7 @@ importers: version: 5.9.3 wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/gastown: dependencies: @@ -1516,7 +1516,7 @@ importers: devDependencies: '@cloudflare/vitest-pool-workers': specifier: ^0.12.8 - version: 0.12.21(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(vitest@3.2.4) + version: 0.12.21(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vitest@3.2.4) '@cloudflare/workers-types': specifier: 'catalog:' version: 4.20260313.1 @@ -1540,7 +1540,7 @@ importers: version: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(@vitest/ui@3.2.4)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/gastown/container: dependencies: @@ -1590,7 +1590,7 @@ importers: version: 5.9.3 wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/gmail-push: dependencies: @@ -1606,7 +1606,7 @@ importers: devDependencies: '@cloudflare/vitest-pool-workers': specifier: ^0.8.71 - version: 0.8.71(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(vitest@3.2.4) + version: 0.8.71(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vitest@3.2.4) '@typescript/native-preview': specifier: 'catalog:' version: 7.0.0-dev.20260319.1 @@ -1618,7 +1618,7 @@ importers: version: 3.2.4(@types/debug@4.1.12)(@types/node@25.5.0)(@vitest/ui@3.2.4)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/images-mcp: dependencies: @@ -1661,7 +1661,7 @@ importers: version: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(@vitest/ui@3.2.4)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/kiloclaw: dependencies: @@ -1677,6 +1677,9 @@ importers: '@kilocode/worker-utils': specifier: workspace:* version: link:../../packages/worker-utils + '@northflank/js-client': + specifier: ^0.9.3 + version: 0.9.3 drizzle-orm: specifier: 'catalog:' version: 0.45.1(@cloudflare/workers-types@4.20260313.1)(@opentelemetry/api@1.9.0)(@types/pg@8.18.0)(bun-types@1.3.11)(pg@8.20.0) @@ -1710,7 +1713,7 @@ importers: version: 4.1.0(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/kiloclaw-billing: dependencies: @@ -1747,7 +1750,7 @@ importers: version: 4.1.0(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/kiloclaw-inbound-email: dependencies: @@ -1775,7 +1778,7 @@ importers: version: 4.1.0(@opentelemetry/api@1.9.0)(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/notifications: dependencies: @@ -1796,14 +1799,14 @@ importers: version: 4.12.8 stream-chat: specifier: 'catalog:' - version: 9.38.0 + version: 9.38.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) zod: specifier: 'catalog:' version: 4.3.6 devDependencies: '@cloudflare/vitest-pool-workers': specifier: ^0.12.21 - version: 0.12.21(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(vitest@3.2.4) + version: 0.12.21(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vitest@3.2.4) '@types/node': specifier: ^25.5.0 version: 25.5.0 @@ -1821,7 +1824,7 @@ importers: version: 3.2.4(@types/debug@4.1.12)(@types/node@25.5.0)(@vitest/ui@3.2.4)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/o11y: dependencies: @@ -1840,7 +1843,7 @@ importers: devDependencies: '@cloudflare/vitest-pool-workers': specifier: ^0.12.21 - version: 0.12.21(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(vitest@3.2.4) + version: 0.12.21(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vitest@3.2.4) '@types/node': specifier: ^25.5.0 version: 25.5.0 @@ -1858,7 +1861,7 @@ importers: version: 3.2.4(@types/debug@4.1.12)(@types/node@25.5.0)(@vitest/ui@3.2.4)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/security-auto-analysis: dependencies: @@ -1889,7 +1892,7 @@ importers: version: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(@vitest/ui@3.2.4)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/security-sync: dependencies: @@ -1914,7 +1917,7 @@ importers: version: 5.9.3 wrangler: specifier: ^4.73.0 - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/session-ingest: dependencies: @@ -1939,7 +1942,7 @@ importers: devDependencies: '@cloudflare/vitest-pool-workers': specifier: ^0.12.21 - version: 0.12.21(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(vitest@3.2.4) + version: 0.12.21(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vitest@3.2.4) '@cloudflare/workers-types': specifier: 'catalog:' version: 4.20260313.1 @@ -1963,7 +1966,7 @@ importers: version: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(@vitest/ui@3.2.4)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) services/webhook-agent-ingest: dependencies: @@ -1994,7 +1997,7 @@ importers: devDependencies: '@cloudflare/vitest-pool-workers': specifier: ^0.12.21 - version: 0.12.21(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(vitest@3.2.4) + version: 0.12.21(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vitest@3.2.4) '@types/node': specifier: '>=24 <25' version: 24.12.0 @@ -2015,7 +2018,7 @@ importers: version: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(@vitest/ui@3.2.4)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) wrangler: specifier: 'catalog:' - version: 4.73.0(@cloudflare/workers-types@4.20260313.1) + version: 4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) packages: @@ -3939,6 +3942,10 @@ packages: cpu: [x64] os: [win32] + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + '@isaacs/ttlcache@1.4.1': resolution: {integrity: sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==} engines: {node: '>=12'} @@ -4287,6 +4294,10 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@northflank/js-client@0.9.3': + resolution: {integrity: sha512-2HaamEBmIOMypPhi51VmaFTNnKERJ8/YYCSVoBOUVlV7wTRy0IGrbLx3D0JnSgoA3QQ552I85HLUS9/P/NUBwQ==} + engines: {node: '>=18.0.0'} + '@octokit/auth-app@8.2.0': resolution: {integrity: sha512-vVjdtQQwomrZ4V46B9LaCsxsySxGoHsyw6IYBov/TqJVROrlYdyNgw5q6tQbB7KZt53v1l1W53RiqTvpzL907g==} engines: {node: '>= 20'} @@ -8514,6 +8525,10 @@ packages: buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + bufferutil@4.1.0: + resolution: {integrity: sha512-ZMANVnAixE6AWWnPzlW2KpUrxhm9woycYvPOo67jWHyFowASTEd9s+QN1EIMsSDtwhIxN4sWE1jotpuDUIgyIw==} + engines: {node: '>=6.14.2'} + builtin-modules@3.3.0: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} @@ -8624,6 +8639,10 @@ packages: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + chromatic@13.3.5: resolution: {integrity: sha512-MzPhxpl838qJUo0A55osCF2ifwPbjcIPeElr1d4SHcjnHoIcg7l1syJDrAYK/a+PcCBrOGi06jPNpQAln5hWgw==} hasBin: true @@ -9462,6 +9481,9 @@ packages: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + endent@2.1.0: resolution: {integrity: sha512-r8VyPX7XL8U01Xgnb1CjZ3XV+z90cXIJ9JPE/R9SEC9vpw2P6CfsRPJmp20DppC5N7ZAMCmjYkJIa744Iyg96w==} @@ -11893,6 +11915,10 @@ packages: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} + minizlib@3.1.0: + resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} + engines: {node: '>= 18'} + mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} @@ -12023,6 +12049,15 @@ packages: node-abort-controller@3.1.1: resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} + node-fetch@2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -12036,6 +12071,10 @@ packages: resolution: {integrity: sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==} engines: {node: '>= 6.13.0'} + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + node-html-markdown@2.0.0: resolution: {integrity: sha512-DqUC3GGP7pwSYxS93SwHoP+qCw78xcMP6C6H2DuC8rPD2AweJRjBzQb5SdXpKtDlqAQ7hVotJcfhgU7hU5Gthw==} engines: {node: '>=20.0.0'} @@ -12654,6 +12693,9 @@ packages: public-encrypt@4.0.3: resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + punycode@1.4.1: resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} @@ -13845,6 +13887,10 @@ packages: tar-stream@3.1.8: resolution: {integrity: sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ==} + tar@7.5.13: + resolution: {integrity: sha512-tOG/7GyXpFevhXVh8jOPJrmtRpOTsYqUIkVdVooZYJS/z8WhfQUX8RJILmeuJNinGAMSu1veBr4asSHFt5/hng==} + engines: {node: '>=18'} + teex@1.0.1: resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} @@ -13967,6 +14013,10 @@ packages: tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + tr46@5.1.1: + resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} + engines: {node: '>=18'} + tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -14274,6 +14324,10 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + utf-8-validate@6.0.6: + resolution: {integrity: sha512-q3l3P9UtEEiAHcsgsqTgf9PPjctrDWoIXW3NpOHFdRDbLvu4DLIcxHangJ4RLrWkBcKjmcs/6NkerI8T/rE4LA==} + engines: {node: '>=6.14.2'} + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -14495,6 +14549,10 @@ packages: resolution: {integrity: sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==} engines: {node: '>=8'} + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + webpack-bundle-analyzer@4.10.1: resolution: {integrity: sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ==} engines: {node: '>= 10.13.0'} @@ -14539,6 +14597,10 @@ packages: resolution: {integrity: sha512-HoKuzZrUlgpz35YO27XgD28uh/WJH4B0+3ttFqRo//lmq+9T/mIOJ6kqmINI9HpUpz1imRC/nR/lxKpJiv0uig==} engines: {node: '>=10'} + whatwg-url@14.2.0: + resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} + engines: {node: '>=18'} + whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} @@ -14716,6 +14778,10 @@ packages: yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + yaml-loader@0.8.1: resolution: {integrity: sha512-BCEndnUoi3BaZmePkwGGe93txRxLgMhBa/gE725v1/GHnura8QvNs7c4+4C1yyhhKoj3Dg63M7IqhA++15j6ww==} engines: {node: '>= 14'} @@ -16283,16 +16349,16 @@ snapshots: - '@node-rs/xxhash' - supports-color - '@chromatic-com/playwright@0.12.8(@playwright/test@1.58.2)(@swc/core@1.15.18)(@types/react@19.2.14)(esbuild@0.27.4)(typescript@5.9.3)': + '@chromatic-com/playwright@0.12.8(@playwright/test@1.58.2)(@swc/core@1.15.18)(@types/react@19.2.14)(bufferutil@4.1.0)(esbuild@0.27.4)(typescript@5.9.3)(utf-8-validate@6.0.6)': dependencies: '@chromaui/rrweb-snapshot': 2.0.0-alpha.18-noAbsolute '@playwright/test': 1.58.2 '@segment/analytics-node': 2.1.3 - '@storybook/addon-essentials': 8.5.8(@types/react@19.2.14)(storybook@9.1.20) + '@storybook/addon-essentials': 8.5.8(@types/react@19.2.14)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) '@storybook/csf': 0.1.13 - '@storybook/manager-api': 8.5.8(storybook@9.1.20) - '@storybook/server-webpack5': 8.5.8(@swc/core@1.15.18)(esbuild@0.27.4)(storybook@9.1.20)(typescript@5.9.3) - storybook: 9.1.20 + '@storybook/manager-api': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@storybook/server-webpack5': 8.5.8(@swc/core@1.15.18)(esbuild@0.27.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))(typescript@5.9.3) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) ts-dedent: 2.2.0 transitivePeerDependencies: - '@rspack/core' @@ -16311,16 +16377,16 @@ snapshots: - vite - webpack-cli - '@chromatic-com/playwright@0.12.8(@playwright/test@1.58.2)(@types/react@19.2.14)(esbuild@0.27.4)(typescript@5.9.3)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@chromatic-com/playwright@0.12.8(@playwright/test@1.58.2)(@types/react@19.2.14)(bufferutil@4.1.0)(esbuild@0.27.4)(typescript@5.9.3)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@chromaui/rrweb-snapshot': 2.0.0-alpha.18-noAbsolute '@playwright/test': 1.58.2 '@segment/analytics-node': 2.1.3 - '@storybook/addon-essentials': 8.5.8(@types/react@19.2.14)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/addon-essentials': 8.5.8(@types/react@19.2.14)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) '@storybook/csf': 0.1.13 - '@storybook/manager-api': 8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) - '@storybook/server-webpack5': 8.5.8(esbuild@0.27.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3) - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@storybook/manager-api': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/server-webpack5': 8.5.8(esbuild@0.27.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) ts-dedent: 2.2.0 transitivePeerDependencies: - '@rspack/core' @@ -16340,13 +16406,13 @@ snapshots: - webpack-cli optional: true - '@chromatic-com/storybook@4.1.3(@chromatic-com/playwright@0.12.8(@playwright/test@1.58.2)(@types/react@19.2.14)(esbuild@0.27.4)(typescript@5.9.3)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@chromatic-com/storybook@4.1.3(@chromatic-com/playwright@0.12.8(@playwright/test@1.58.2)(@types/react@19.2.14)(bufferutil@4.1.0)(esbuild@0.27.4)(typescript@5.9.3)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: '@neoconfetti/react': 1.0.0 - chromatic: 13.3.5(@chromatic-com/playwright@0.12.8(@playwright/test@1.58.2)(@types/react@19.2.14)(esbuild@0.27.4)(typescript@5.9.3)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + chromatic: 13.3.5(@chromatic-com/playwright@0.12.8(@playwright/test@1.58.2)(@types/react@19.2.14)(bufferutil@4.1.0)(esbuild@0.27.4)(typescript@5.9.3)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) filesize: 10.1.6 jsonfile: 6.2.0 - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) strip-ansi: 7.2.0 transitivePeerDependencies: - '@chromatic-com/cypress' @@ -16408,45 +16474,45 @@ snapshots: optionalDependencies: workerd: 1.20250906.0 - '@cloudflare/vitest-pool-workers@0.12.21(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(vitest@3.2.4)': + '@cloudflare/vitest-pool-workers@0.12.21(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vitest@3.2.4)': dependencies: '@vitest/runner': 4.1.0 '@vitest/snapshot': 4.1.0 cjs-module-lexer: 1.4.3 esbuild: 0.27.4 - miniflare: 4.20260310.0 + miniflare: 4.20260310.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(@vitest/ui@3.2.4)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - wrangler: 4.72.0(@cloudflare/workers-types@4.20260313.1) + wrangler: 4.72.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - '@cloudflare/workers-types' - bufferutil - utf-8-validate - '@cloudflare/vitest-pool-workers@0.12.21(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': + '@cloudflare/vitest-pool-workers@0.12.21(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vitest@4.1.0(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@vitest/runner': 4.1.0 '@vitest/snapshot': 4.1.0 cjs-module-lexer: 1.4.3 esbuild: 0.27.4 - miniflare: 4.20260310.0 + miniflare: 4.20260310.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) vitest: 4.1.0(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - wrangler: 4.72.0(@cloudflare/workers-types@4.20260313.1) + wrangler: 4.72.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - '@cloudflare/workers-types' - bufferutil - utf-8-validate - '@cloudflare/vitest-pool-workers@0.8.71(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(vitest@3.2.4)': + '@cloudflare/vitest-pool-workers@0.8.71(@cloudflare/workers-types@4.20260313.1)(@vitest/runner@4.1.0)(@vitest/snapshot@4.1.0)(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vitest@3.2.4)': dependencies: '@vitest/runner': 4.1.0 '@vitest/snapshot': 4.1.0 birpc: 0.2.14 cjs-module-lexer: 1.4.3 devalue: 5.6.4 - miniflare: 4.20250906.0 + miniflare: 4.20250906.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) semver: 7.7.4 vitest: 3.2.4(@types/debug@4.1.12)(@types/node@25.5.0)(@vitest/ui@3.2.4)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) - wrangler: 4.35.0(@cloudflare/workers-types@4.20260313.1) + wrangler: 4.35.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6) zod: 3.25.76 transitivePeerDependencies: - '@cloudflare/workers-types' @@ -16543,7 +16609,7 @@ snapshots: dependencies: discord-api-types: 0.38.42 - '@discordjs/ws@1.2.3': + '@discordjs/ws@1.2.3(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: '@discordjs/collection': 2.1.1 '@discordjs/rest': 2.6.0 @@ -16553,7 +16619,7 @@ snapshots: '@vladfrangu/async_event_emitter': 2.4.7 discord-api-types: 0.38.42 tslib: 2.8.1 - ws: 8.19.0 + ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -16680,7 +16746,7 @@ snapshots: '@expo-google-fonts/material-symbols@0.4.27': {} - '@expo/cli@55.0.22(@expo/metro-runtime@55.0.9)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-router@55.0.11)(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3)': + '@expo/cli@55.0.22(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-router@55.0.11)(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6)': dependencies: '@expo/code-signing-certificates': 0.0.6 '@expo/config': 55.0.13(typescript@5.9.3) @@ -16689,9 +16755,9 @@ snapshots: '@expo/env': 2.1.1 '@expo/image-utils': 0.8.12 '@expo/json-file': 10.0.13 - '@expo/log-box': 55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - '@expo/metro': 55.0.0 - '@expo/metro-config': 55.0.14(expo@55.0.12)(typescript@5.9.3) + '@expo/log-box': 55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@expo/metro': 55.0.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@expo/metro-config': 55.0.14(bufferutil@4.1.0)(expo@55.0.12)(typescript@5.9.3)(utf-8-validate@6.0.6) '@expo/osascript': 2.4.2 '@expo/package-manager': 1.10.4 '@expo/plist': 0.5.2 @@ -16702,7 +16768,7 @@ snapshots: '@expo/spawn-async': 1.7.2 '@expo/ws-tunnel': 1.0.6 '@expo/xcpretty': 4.4.1 - '@react-native/dev-middleware': 0.83.4 + '@react-native/dev-middleware': 0.83.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) accepts: 1.3.8 arg: 5.0.2 better-opn: 3.0.2 @@ -16714,7 +16780,7 @@ snapshots: connect: 3.7.0 debug: 4.4.3 dnssd-advertise: 1.1.3 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-server: 55.0.7 fetch-nodeshim: 0.4.9 getenv: 2.0.0 @@ -16738,11 +16804,11 @@ snapshots: terminal-link: 2.1.1 toqr: 0.1.1 wrap-ansi: 7.0.0 - ws: 8.19.0 + ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) zod: 3.25.76 optionalDependencies: - expo-router: 55.0.11(@expo/log-box@55.0.10)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-linking@55.0.11)(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native-gesture-handler@2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + expo-router: 55.0.11(19d76ea0d0b88bce60b3b715cef8728d) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - '@expo/metro-runtime' - bufferutil @@ -16803,18 +16869,18 @@ snapshots: transitivePeerDependencies: - supports-color - '@expo/devtools@55.0.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': + '@expo/devtools@55.0.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: chalk: 4.1.2 optionalDependencies: react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - '@expo/dom-webview@55.0.5(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': + '@expo/dom-webview@55.0.5(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) '@expo/env@2.1.1': dependencies: @@ -16863,16 +16929,16 @@ snapshots: - supports-color - typescript - '@expo/log-box@55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': + '@expo/log-box@55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: - '@expo/dom-webview': 55.0.5(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + '@expo/dom-webview': 55.0.5(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) anser: 1.4.10 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) stacktrace-parser: 0.1.11 - '@expo/metro-config@55.0.14(expo@55.0.12)(typescript@5.9.3)': + '@expo/metro-config@55.0.14(bufferutil@4.1.0)(expo@55.0.12)(typescript@5.9.3)(utf-8-validate@6.0.6)': dependencies: '@babel/code-frame': 7.29.0 '@babel/core': 7.29.0 @@ -16880,7 +16946,7 @@ snapshots: '@expo/config': 55.0.13(typescript@5.9.3) '@expo/env': 2.1.1 '@expo/json-file': 10.0.13 - '@expo/metro': 55.0.0 + '@expo/metro': 55.0.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@expo/spawn-async': 1.7.2 browserslist: 4.28.1 chalk: 4.1.2 @@ -16894,33 +16960,33 @@ snapshots: postcss: 8.4.49 resolve-from: 5.0.0 optionalDependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil - supports-color - typescript - utf-8-validate - '@expo/metro-runtime@55.0.9(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': + '@expo/metro-runtime@55.0.9(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: - '@expo/log-box': 55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + '@expo/log-box': 55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) anser: 1.4.10 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) pretty-format: 29.7.0 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) stacktrace-parser: 0.1.11 whatwg-fetch: 3.6.20 optionalDependencies: react-dom: 19.2.4(react@19.2.0) - '@expo/metro@55.0.0': + '@expo/metro@55.0.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: - metro: 0.83.5 + metro: 0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) metro-babel-transformer: 0.83.5 metro-cache: 0.83.5 metro-cache-key: 0.83.5 - metro-config: 0.83.5 + metro-config: 0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) metro-core: 0.83.5 metro-file-map: 0.83.5 metro-minify-terser: 0.83.5 @@ -16929,7 +16995,7 @@ snapshots: metro-source-map: 0.83.5 metro-symbolicate: 0.83.5 metro-transform-plugins: 0.83.5 - metro-transform-worker: 0.83.5 + metro-transform-worker: 0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil - supports-color @@ -16963,7 +17029,7 @@ snapshots: '@expo/json-file': 10.0.13 '@react-native/normalize-colors': 0.83.4 debug: 4.4.3 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) resolve-from: 5.0.0 semver: 7.7.4 xml2js: 0.6.0 @@ -16992,14 +17058,14 @@ snapshots: '@expo/router-server@55.0.13(@expo/metro-runtime@55.0.9)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-router@55.0.11)(expo-server@55.0.7)(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react@19.2.0)': dependencies: debug: 4.4.3 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - expo-constants: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) - expo-font: 55.0.6(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo-constants: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(typescript@5.9.3) + expo-font: 55.0.6(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) expo-server: 55.0.7 react: 19.2.0 optionalDependencies: - '@expo/metro-runtime': 55.0.9(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - expo-router: 55.0.11(@expo/log-box@55.0.10)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-linking@55.0.11)(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native-gesture-handler@2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + '@expo/metro-runtime': 55.0.9(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + expo-router: 55.0.11(19d76ea0d0b88bce60b3b715cef8728d) react-dom: 19.2.4(react@19.2.0) transitivePeerDependencies: - supports-color @@ -17014,11 +17080,11 @@ snapshots: '@expo/sudo-prompt@9.3.2': {} - '@expo/vector-icons@15.1.1(expo-font@55.0.6)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': + '@expo/vector-icons@15.1.1(expo-font@55.0.6)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: - expo-font: 55.0.6(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + expo-font: 55.0.6(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) '@expo/ws-tunnel@1.0.6': {} @@ -17065,22 +17131,22 @@ snapshots: '@floating-ui/utils@0.2.11': {} - '@gorhom/bottom-sheet@5.1.8(patch_hash=c5eaae9a28f5662f32d66e0129609680309eddc44720d6a2b1e02bbc2b5dd11f)(@types/react@19.2.14)(react-native-gesture-handler@2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': + '@gorhom/bottom-sheet@5.1.8(patch_hash=c5eaae9a28f5662f32d66e0129609680309eddc44720d6a2b1e02bbc2b5dd11f)(@types/react@19.2.14)(react-native-gesture-handler@2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: - '@gorhom/portal': 1.0.14(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + '@gorhom/portal': 1.0.14(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) invariant: 2.2.4 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) - react-native-gesture-handler: 2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - react-native-reanimated: 4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native-gesture-handler: 2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-reanimated: 4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) optionalDependencies: '@types/react': 19.2.14 - '@gorhom/portal@1.0.14(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': + '@gorhom/portal@1.0.14(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: nanoid: 3.3.11 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) '@hapi/hoek@9.3.0': {} @@ -17268,6 +17334,10 @@ snapshots: '@img/sharp-win32-x64@0.34.5': optional: true + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.3 + '@isaacs/ttlcache@1.4.1': {} '@istanbuljs/load-nyc-config@1.1.0': @@ -17721,9 +17791,9 @@ snapshots: '@types/react': 19.2.14 react: 19.2.4 - '@mistralai/mistralai@1.15.1': + '@mistralai/mistralai@1.15.1(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: - ws: 8.19.0 + ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) zod: 4.3.6 zod-to-json-schema: 3.25.1(zod@4.3.6) transitivePeerDependencies: @@ -17779,9 +17849,9 @@ snapshots: '@neoconfetti/react@1.0.0': {} - '@next/bundle-analyzer@16.1.6': + '@next/bundle-analyzer@16.1.6(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: - webpack-bundle-analyzer: 4.10.1 + webpack-bundle-analyzer: 4.10.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -17837,6 +17907,19 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 + '@northflank/js-client@0.9.3': + dependencies: + bufferutil: 4.1.0 + lodash-es: 4.17.23 + node-fetch: 2.6.7 + pump: 3.0.4 + tar: 7.5.13 + utf-8-validate: 6.0.6 + whatwg-url: 14.2.0 + ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - encoding + '@octokit/auth-app@8.2.0': dependencies: '@octokit/auth-oauth-app': 9.0.3 @@ -19363,10 +19446,10 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@react-native-community/netinfo@11.5.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': + '@react-native-community/netinfo@11.5.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) '@react-native/assets-registry@0.83.4': {} @@ -19439,13 +19522,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@react-native/community-cli-plugin@0.83.4': + '@react-native/community-cli-plugin@0.83.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: - '@react-native/dev-middleware': 0.83.4 + '@react-native/dev-middleware': 0.83.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) debug: 4.4.3 invariant: 2.2.4 - metro: 0.83.5 - metro-config: 0.83.5 + metro: 0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) + metro-config: 0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) metro-core: 0.83.5 semver: 7.7.4 transitivePeerDependencies: @@ -19460,7 +19543,7 @@ snapshots: cross-spawn: 7.0.6 fb-dotslash: 0.5.8 - '@react-native/dev-middleware@0.83.4': + '@react-native/dev-middleware@0.83.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)': dependencies: '@isaacs/ttlcache': 1.4.1 '@react-native/debugger-frontend': 0.83.4 @@ -19473,7 +19556,7 @@ snapshots: nullthrows: 1.1.1 open: 7.4.2 serve-static: 1.16.3 - ws: 7.5.10 + ws: 7.5.10(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil - supports-color @@ -19485,24 +19568,24 @@ snapshots: '@react-native/normalize-colors@0.83.4': {} - '@react-native/virtualized-lists@0.83.4(@types/react@19.2.14)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': + '@react-native/virtualized-lists@0.83.4(@types/react@19.2.14)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: invariant: 2.2.4 nullthrows: 1.1.1 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) optionalDependencies: '@types/react': 19.2.14 - '@react-navigation/bottom-tabs@7.15.8(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': + '@react-navigation/bottom-tabs@7.15.8(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: - '@react-navigation/elements': 2.9.13(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - '@react-navigation/native': 7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + '@react-navigation/elements': 2.9.13(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@react-navigation/native': 7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) color: 4.2.3 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) - react-native-safe-area-context: 5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - react-native-screens: 4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native-safe-area-context: 5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-screens: 4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) sf-symbols-typescript: 2.2.0 transitivePeerDependencies: - '@react-native-masked-view/masked-view' @@ -19519,38 +19602,38 @@ snapshots: use-latest-callback: 0.2.6(react@19.2.0) use-sync-external-store: 1.6.0(react@19.2.0) - '@react-navigation/elements@2.9.13(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': + '@react-navigation/elements@2.9.13(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: - '@react-navigation/native': 7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + '@react-navigation/native': 7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) color: 4.2.3 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) - react-native-safe-area-context: 5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native-safe-area-context: 5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) use-latest-callback: 0.2.6(react@19.2.0) use-sync-external-store: 1.6.0(react@19.2.0) - '@react-navigation/native-stack@7.14.5(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': + '@react-navigation/native-stack@7.14.5(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: - '@react-navigation/elements': 2.9.13(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - '@react-navigation/native': 7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + '@react-navigation/elements': 2.9.13(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@react-navigation/native': 7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) color: 4.2.3 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) - react-native-safe-area-context: 5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - react-native-screens: 4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native-safe-area-context: 5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-screens: 4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) sf-symbols-typescript: 2.2.0 warn-once: 0.1.1 transitivePeerDependencies: - '@react-native-masked-view/masked-view' - '@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': + '@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: '@react-navigation/core': 7.16.1(react@19.2.0) escape-string-regexp: 4.0.0 fast-deep-equal: 3.1.3 nanoid: 3.3.11 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) use-latest-callback: 0.2.6(react@19.2.0) '@react-navigation/routers@7.5.3': @@ -19602,22 +19685,22 @@ snapshots: react: 19.2.4 react-redux: 9.2.0(@types/react@19.2.14)(react@19.2.4)(redux@5.0.1) - '@rn-primitives/portal@1.3.0(@types/react@19.2.14)(immer@11.1.4)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0))': + '@rn-primitives/portal@1.3.0(@types/react@19.2.14)(immer@11.1.4)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0))': dependencies: react: 19.2.0 zustand: 5.0.12(@types/react@19.2.14)(immer@11.1.4)(react@19.2.0)(use-sync-external-store@1.6.0(react@19.2.0)) optionalDependencies: - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - '@types/react' - immer - use-sync-external-store - '@rn-primitives/slot@1.2.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': + '@rn-primitives/slot@1.2.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: react: 19.2.0 optionalDependencies: - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) '@rocicorp/resolver@1.0.2': {} @@ -20127,7 +20210,7 @@ snapshots: '@opentelemetry/semantic-conventions': 1.40.0 '@sentry/core': 10.43.0 - '@sentry/react-native@7.11.0(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)': + '@sentry/react-native@7.11.0(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)': dependencies: '@sentry/babel-plugin-component-annotate': 4.8.0 '@sentry/browser': 10.37.0 @@ -20136,9 +20219,9 @@ snapshots: '@sentry/react': 10.37.0(react@19.2.0) '@sentry/types': 10.37.0 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) optionalDependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) transitivePeerDependencies: - encoding - supports-color @@ -20587,221 +20670,221 @@ snapshots: '@standard-schema/utils@0.3.0': {} - '@storybook/addon-actions@8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/addon-actions@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: '@storybook/global': 5.0.0 '@types/uuid': 9.0.8 dequal: 2.0.3 polished: 4.3.1 - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) uuid: 9.0.1 optional: true - '@storybook/addon-actions@8.5.8(storybook@9.1.20)': + '@storybook/addon-actions@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: '@storybook/global': 5.0.0 '@types/uuid': 9.0.8 dequal: 2.0.3 polished: 4.3.1 - storybook: 9.1.20 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) uuid: 9.0.1 - '@storybook/addon-backgrounds@8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/addon-backgrounds@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: '@storybook/global': 5.0.0 memoizerific: 1.11.3 - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) ts-dedent: 2.2.0 optional: true - '@storybook/addon-backgrounds@8.5.8(storybook@9.1.20)': + '@storybook/addon-backgrounds@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: '@storybook/global': 5.0.0 memoizerific: 1.11.3 - storybook: 9.1.20 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) ts-dedent: 2.2.0 - '@storybook/addon-controls@8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/addon-controls@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: '@storybook/global': 5.0.0 dequal: 2.0.3 - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) ts-dedent: 2.2.0 optional: true - '@storybook/addon-controls@8.5.8(storybook@9.1.20)': + '@storybook/addon-controls@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: '@storybook/global': 5.0.0 dequal: 2.0.3 - storybook: 9.1.20 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) ts-dedent: 2.2.0 - '@storybook/addon-docs@8.5.8(@types/react@19.2.14)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/addon-docs@8.5.8(@types/react@19.2.14)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.4) - '@storybook/blocks': 8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) - '@storybook/csf-plugin': 8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) - '@storybook/react-dom-shim': 8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/blocks': 8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/csf-plugin': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/react-dom-shim': 8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) ts-dedent: 2.2.0 transitivePeerDependencies: - '@types/react' optional: true - '@storybook/addon-docs@8.5.8(@types/react@19.2.14)(storybook@9.1.20)': + '@storybook/addon-docs@8.5.8(@types/react@19.2.14)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.4) - '@storybook/blocks': 8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20) - '@storybook/csf-plugin': 8.5.8(storybook@9.1.20) - '@storybook/react-dom-shim': 8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20) + '@storybook/blocks': 8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@storybook/csf-plugin': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@storybook/react-dom-shim': 8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - storybook: 9.1.20 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) ts-dedent: 2.2.0 transitivePeerDependencies: - '@types/react' - '@storybook/addon-docs@9.1.20(@types/react@19.2.14)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/addon-docs@9.1.20(@types/react@19.2.14)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: '@mdx-js/react': 3.1.1(@types/react@19.2.14)(react@19.2.4) - '@storybook/csf-plugin': 9.1.20(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/csf-plugin': 9.1.20(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) '@storybook/icons': 1.6.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - '@storybook/react-dom-shim': 9.1.20(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/react-dom-shim': 9.1.20(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) ts-dedent: 2.2.0 transitivePeerDependencies: - '@types/react' - '@storybook/addon-essentials@8.5.8(@types/react@19.2.14)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': - dependencies: - '@storybook/addon-actions': 8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) - '@storybook/addon-backgrounds': 8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) - '@storybook/addon-controls': 8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) - '@storybook/addon-docs': 8.5.8(@types/react@19.2.14)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) - '@storybook/addon-highlight': 8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) - '@storybook/addon-measure': 8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) - '@storybook/addon-outline': 8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) - '@storybook/addon-toolbars': 8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) - '@storybook/addon-viewport': 8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@storybook/addon-essentials@8.5.8(@types/react@19.2.14)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + dependencies: + '@storybook/addon-actions': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/addon-backgrounds': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/addon-controls': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/addon-docs': 8.5.8(@types/react@19.2.14)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/addon-highlight': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/addon-measure': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/addon-outline': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/addon-toolbars': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/addon-viewport': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) ts-dedent: 2.2.0 transitivePeerDependencies: - '@types/react' optional: true - '@storybook/addon-essentials@8.5.8(@types/react@19.2.14)(storybook@9.1.20)': + '@storybook/addon-essentials@8.5.8(@types/react@19.2.14)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: - '@storybook/addon-actions': 8.5.8(storybook@9.1.20) - '@storybook/addon-backgrounds': 8.5.8(storybook@9.1.20) - '@storybook/addon-controls': 8.5.8(storybook@9.1.20) - '@storybook/addon-docs': 8.5.8(@types/react@19.2.14)(storybook@9.1.20) - '@storybook/addon-highlight': 8.5.8(storybook@9.1.20) - '@storybook/addon-measure': 8.5.8(storybook@9.1.20) - '@storybook/addon-outline': 8.5.8(storybook@9.1.20) - '@storybook/addon-toolbars': 8.5.8(storybook@9.1.20) - '@storybook/addon-viewport': 8.5.8(storybook@9.1.20) - storybook: 9.1.20 + '@storybook/addon-actions': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@storybook/addon-backgrounds': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@storybook/addon-controls': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@storybook/addon-docs': 8.5.8(@types/react@19.2.14)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@storybook/addon-highlight': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@storybook/addon-measure': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@storybook/addon-outline': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@storybook/addon-toolbars': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@storybook/addon-viewport': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) ts-dedent: 2.2.0 transitivePeerDependencies: - '@types/react' - '@storybook/addon-highlight@8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/addon-highlight@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: '@storybook/global': 5.0.0 - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) optional: true - '@storybook/addon-highlight@8.5.8(storybook@9.1.20)': + '@storybook/addon-highlight@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: '@storybook/global': 5.0.0 - storybook: 9.1.20 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) - '@storybook/addon-links@9.1.20(react@19.2.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/addon-links@9.1.20(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: '@storybook/global': 5.0.0 - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) optionalDependencies: react: 19.2.4 - '@storybook/addon-measure@8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/addon-measure@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: '@storybook/global': 5.0.0 - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) tiny-invariant: 1.3.3 optional: true - '@storybook/addon-measure@8.5.8(storybook@9.1.20)': + '@storybook/addon-measure@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: '@storybook/global': 5.0.0 - storybook: 9.1.20 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) tiny-invariant: 1.3.3 - '@storybook/addon-outline@8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/addon-outline@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: '@storybook/global': 5.0.0 - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) ts-dedent: 2.2.0 optional: true - '@storybook/addon-outline@8.5.8(storybook@9.1.20)': + '@storybook/addon-outline@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: '@storybook/global': 5.0.0 - storybook: 9.1.20 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) ts-dedent: 2.2.0 - '@storybook/addon-themes@9.1.20(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/addon-themes@9.1.20(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) ts-dedent: 2.2.0 - '@storybook/addon-toolbars@8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/addon-toolbars@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) optional: true - '@storybook/addon-toolbars@8.5.8(storybook@9.1.20)': + '@storybook/addon-toolbars@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: - storybook: 9.1.20 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) - '@storybook/addon-viewport@8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/addon-viewport@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: memoizerific: 1.11.3 - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) optional: true - '@storybook/addon-viewport@8.5.8(storybook@9.1.20)': + '@storybook/addon-viewport@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: memoizerific: 1.11.3 - storybook: 9.1.20 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) - '@storybook/blocks@8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/blocks@8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: '@storybook/csf': 0.1.12 '@storybook/icons': 1.6.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) ts-dedent: 2.2.0 optionalDependencies: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optional: true - '@storybook/blocks@8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20)': + '@storybook/blocks@8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: '@storybook/csf': 0.1.12 '@storybook/icons': 1.6.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) - storybook: 9.1.20 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) ts-dedent: 2.2.0 optionalDependencies: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@storybook/builder-webpack5@8.5.8(@swc/core@1.15.18)(esbuild@0.27.4)(storybook@9.1.20)(typescript@5.9.3)': + '@storybook/builder-webpack5@8.5.8(@swc/core@1.15.18)(esbuild@0.27.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))(typescript@5.9.3)': dependencies: - '@storybook/core-webpack': 8.5.8(storybook@9.1.20) + '@storybook/core-webpack': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) '@types/semver': 7.7.1 browser-assert: 1.2.1 case-sensitive-paths-webpack-plugin: 2.4.0 @@ -20815,7 +20898,7 @@ snapshots: path-browserify: 1.0.1 process: 0.11.10 semver: 7.7.4 - storybook: 9.1.20 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) style-loader: 3.3.4(webpack@5.105.4(@swc/core@1.15.18)(esbuild@0.27.4)) terser-webpack-plugin: 5.4.0(@swc/core@1.15.18)(esbuild@0.27.4)(webpack@5.105.4(@swc/core@1.15.18)(esbuild@0.27.4)) ts-dedent: 2.2.0 @@ -20835,9 +20918,9 @@ snapshots: - uglify-js - webpack-cli - '@storybook/builder-webpack5@8.5.8(esbuild@0.27.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3)': + '@storybook/builder-webpack5@8.5.8(esbuild@0.27.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3)': dependencies: - '@storybook/core-webpack': 8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/core-webpack': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) '@types/semver': 7.7.1 browser-assert: 1.2.1 case-sensitive-paths-webpack-plugin: 2.4.0 @@ -20851,7 +20934,7 @@ snapshots: path-browserify: 1.0.1 process: 0.11.10 semver: 7.7.4 - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) style-loader: 3.3.4(webpack@5.105.4(esbuild@0.27.4)) terser-webpack-plugin: 5.4.0(esbuild@0.27.4)(webpack@5.105.4(esbuild@0.27.4)) ts-dedent: 2.2.0 @@ -20872,9 +20955,9 @@ snapshots: - webpack-cli optional: true - '@storybook/builder-webpack5@9.1.20(esbuild@0.27.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3)': + '@storybook/builder-webpack5@9.1.20(esbuild@0.27.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3)': dependencies: - '@storybook/core-webpack': 9.1.20(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/core-webpack': 9.1.20(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) case-sensitive-paths-webpack-plugin: 2.4.0 cjs-module-lexer: 1.4.3 css-loader: 6.11.0(webpack@5.105.4(esbuild@0.27.4)) @@ -20882,7 +20965,7 @@ snapshots: fork-ts-checker-webpack-plugin: 8.0.0(typescript@5.9.3)(webpack@5.105.4(esbuild@0.27.4)) html-webpack-plugin: 5.6.6(webpack@5.105.4(esbuild@0.27.4)) magic-string: 0.30.21 - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) style-loader: 3.3.4(webpack@5.105.4(esbuild@0.27.4)) terser-webpack-plugin: 5.4.0(esbuild@0.27.4)(webpack@5.105.4(esbuild@0.27.4)) ts-dedent: 2.2.0 @@ -20899,45 +20982,45 @@ snapshots: - uglify-js - webpack-cli - '@storybook/components@8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/components@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) optional: true - '@storybook/components@8.5.8(storybook@9.1.20)': + '@storybook/components@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: - storybook: 9.1.20 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) - '@storybook/core-webpack@8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/core-webpack@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) ts-dedent: 2.2.0 optional: true - '@storybook/core-webpack@8.5.8(storybook@9.1.20)': + '@storybook/core-webpack@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: - storybook: 9.1.20 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) ts-dedent: 2.2.0 - '@storybook/core-webpack@9.1.20(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/core-webpack@9.1.20(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) ts-dedent: 2.2.0 - '@storybook/csf-plugin@8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/csf-plugin@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) unplugin: 1.16.1 optional: true - '@storybook/csf-plugin@8.5.8(storybook@9.1.20)': + '@storybook/csf-plugin@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: - storybook: 9.1.20 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) unplugin: 1.16.1 - '@storybook/csf-plugin@9.1.20(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/csf-plugin@9.1.20(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) unplugin: 1.16.1 '@storybook/csf@0.1.12': @@ -20955,16 +21038,16 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - '@storybook/manager-api@8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/manager-api@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) optional: true - '@storybook/manager-api@8.5.8(storybook@9.1.20)': + '@storybook/manager-api@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: - storybook: 9.1.20 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) - '@storybook/nextjs@9.1.20(patch_hash=e1857649664eed8f87877c352d277c90d4af5a58d0ad931105f033c8c08165c1)(esbuild@0.27.4)(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(type-fest@4.41.0)(typescript@5.9.3)(webpack-hot-middleware@2.26.1)(webpack@5.105.4(esbuild@0.27.4))': + '@storybook/nextjs@9.1.20(patch_hash=e1857649664eed8f87877c352d277c90d4af5a58d0ad931105f033c8c08165c1)(esbuild@0.27.4)(next@16.1.6(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(type-fest@4.41.0)(typescript@5.9.3)(webpack-hot-middleware@2.26.1)(webpack@5.105.4(esbuild@0.27.4))': dependencies: '@babel/core': 7.29.0 '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.29.0) @@ -20980,9 +21063,9 @@ snapshots: '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) '@babel/runtime': 7.29.2 '@pmmmwh/react-refresh-webpack-plugin': 0.5.17(react-refresh@0.14.2)(type-fest@4.41.0)(webpack-hot-middleware@2.26.1)(webpack@5.105.4(esbuild@0.27.4)) - '@storybook/builder-webpack5': 9.1.20(esbuild@0.27.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3) - '@storybook/preset-react-webpack': 9.1.20(esbuild@0.27.4)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3) - '@storybook/react': 9.1.20(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3) + '@storybook/builder-webpack5': 9.1.20(esbuild@0.27.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3) + '@storybook/preset-react-webpack': 9.1.20(esbuild@0.27.4)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3) + '@storybook/react': 9.1.20(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3) '@types/semver': 7.7.1 babel-loader: 9.2.1(@babel/core@7.29.0)(webpack@5.105.4(esbuild@0.27.4)) css-loader: 6.11.0(webpack@5.105.4(esbuild@0.27.4)) @@ -20998,7 +21081,7 @@ snapshots: resolve-url-loader: 5.0.0 sass-loader: 16.0.7(webpack@5.105.4(esbuild@0.27.4)) semver: 7.7.4 - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) style-loader: 3.3.4(webpack@5.105.4(esbuild@0.27.4)) styled-jsx: 5.1.7(@babel/core@7.29.0)(react@19.2.4) tsconfig-paths: 4.2.0 @@ -21024,9 +21107,9 @@ snapshots: - webpack-hot-middleware - webpack-plugin-serve - '@storybook/preset-react-webpack@9.1.20(esbuild@0.27.4)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3)': + '@storybook/preset-react-webpack@9.1.20(esbuild@0.27.4)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3)': dependencies: - '@storybook/core-webpack': 9.1.20(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/core-webpack': 9.1.20(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) '@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@5.9.3)(webpack@5.105.4(esbuild@0.27.4)) '@types/semver': 7.7.1 find-up: 7.0.0 @@ -21036,7 +21119,7 @@ snapshots: react-dom: 19.2.4(react@19.2.4) resolve: 1.22.11 semver: 7.7.4 - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) tsconfig-paths: 4.2.0 webpack: 5.105.4(esbuild@0.27.4) optionalDependencies: @@ -21048,35 +21131,35 @@ snapshots: - uglify-js - webpack-cli - '@storybook/preset-server-webpack@8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/preset-server-webpack@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: - '@storybook/core-webpack': 8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/core-webpack': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) '@storybook/global': 5.0.0 - '@storybook/server': 8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/server': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) safe-identifier: 0.4.2 - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) ts-dedent: 2.2.0 yaml-loader: 0.8.1 optional: true - '@storybook/preset-server-webpack@8.5.8(storybook@9.1.20)': + '@storybook/preset-server-webpack@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: - '@storybook/core-webpack': 8.5.8(storybook@9.1.20) + '@storybook/core-webpack': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) '@storybook/global': 5.0.0 - '@storybook/server': 8.5.8(storybook@9.1.20) + '@storybook/server': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) safe-identifier: 0.4.2 - storybook: 9.1.20 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) ts-dedent: 2.2.0 yaml-loader: 0.8.1 - '@storybook/preview-api@8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/preview-api@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) optional: true - '@storybook/preview-api@8.5.8(storybook@9.1.20)': + '@storybook/preview-api@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: - storybook: 9.1.20 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0(typescript@5.9.3)(webpack@5.105.4(esbuild@0.27.4))': dependencies: @@ -21092,41 +21175,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@storybook/react-dom-shim@8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/react-dom-shim@8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) optional: true - '@storybook/react-dom-shim@8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20)': + '@storybook/react-dom-shim@8.5.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - storybook: 9.1.20 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) - '@storybook/react-dom-shim@9.1.20(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/react-dom-shim@9.1.20(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) - '@storybook/react@9.1.20(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3)': + '@storybook/react@9.1.20(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3)': dependencies: '@storybook/global': 5.0.0 - '@storybook/react-dom-shim': 9.1.20(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/react-dom-shim': 9.1.20(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) optionalDependencies: typescript: 5.9.3 - '@storybook/server-webpack5@8.5.8(@swc/core@1.15.18)(esbuild@0.27.4)(storybook@9.1.20)(typescript@5.9.3)': + '@storybook/server-webpack5@8.5.8(@swc/core@1.15.18)(esbuild@0.27.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))(typescript@5.9.3)': dependencies: - '@storybook/builder-webpack5': 8.5.8(@swc/core@1.15.18)(esbuild@0.27.4)(storybook@9.1.20)(typescript@5.9.3) - '@storybook/preset-server-webpack': 8.5.8(storybook@9.1.20) - '@storybook/server': 8.5.8(storybook@9.1.20) - storybook: 9.1.20 + '@storybook/builder-webpack5': 8.5.8(@swc/core@1.15.18)(esbuild@0.27.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))(typescript@5.9.3) + '@storybook/preset-server-webpack': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@storybook/server': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - '@rspack/core' - '@swc/core' @@ -21135,12 +21218,12 @@ snapshots: - uglify-js - webpack-cli - '@storybook/server-webpack5@8.5.8(esbuild@0.27.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3)': + '@storybook/server-webpack5@8.5.8(esbuild@0.27.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3)': dependencies: - '@storybook/builder-webpack5': 8.5.8(esbuild@0.27.4)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3) - '@storybook/preset-server-webpack': 8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) - '@storybook/server': 8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@storybook/builder-webpack5': 8.5.8(esbuild@0.27.4)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))(typescript@5.9.3) + '@storybook/preset-server-webpack': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/server': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) transitivePeerDependencies: - '@rspack/core' - '@swc/core' @@ -21150,32 +21233,32 @@ snapshots: - webpack-cli optional: true - '@storybook/server@8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/server@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: - '@storybook/components': 8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/components': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) '@storybook/csf': 0.1.12 '@storybook/global': 5.0.0 - '@storybook/manager-api': 8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) - '@storybook/preview-api': 8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) - '@storybook/theming': 8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@storybook/manager-api': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/preview-api': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + '@storybook/theming': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) ts-dedent: 2.2.0 yaml: 2.8.2 optional: true - '@storybook/server@8.5.8(storybook@9.1.20)': + '@storybook/server@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: - '@storybook/components': 8.5.8(storybook@9.1.20) + '@storybook/components': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) '@storybook/csf': 0.1.12 '@storybook/global': 5.0.0 - '@storybook/manager-api': 8.5.8(storybook@9.1.20) - '@storybook/preview-api': 8.5.8(storybook@9.1.20) - '@storybook/theming': 8.5.8(storybook@9.1.20) - storybook: 9.1.20 + '@storybook/manager-api': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@storybook/preview-api': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@storybook/theming': 8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) ts-dedent: 2.2.0 yaml: 2.8.2 - '@storybook/test-runner@0.23.0(@types/node@25.5.0)(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/test-runner@0.23.0(@types/node@25.5.0)(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: '@babel/core': 7.29.0 '@babel/generator': 7.29.1 @@ -21195,7 +21278,7 @@ snapshots: jest-watch-typeahead: 2.2.2(jest@29.7.0(@types/node@25.5.0)) nyc: 15.1.0 playwright: 1.58.2 - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) transitivePeerDependencies: - '@swc/helpers' - '@types/node' @@ -21205,14 +21288,14 @@ snapshots: - supports-color - ts-node - '@storybook/theming@8.5.8(storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': + '@storybook/theming@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)))': dependencies: - storybook: 9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) optional: true - '@storybook/theming@8.5.8(storybook@9.1.20)': + '@storybook/theming@8.5.8(storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6))': dependencies: - storybook: 9.1.20 + storybook: 9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@stream-io/escape-string-regexp@5.0.1': optional: true @@ -21958,7 +22041,7 @@ snapshots: sirv: 3.0.2 tinyglobby: 0.2.15 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(@vitest/ui@3.2.4)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@25.5.0)(@vitest/ui@3.2.4)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2) '@vitest/utils@3.2.4': dependencies: @@ -22509,7 +22592,7 @@ snapshots: resolve-from: 5.0.0 optionalDependencies: '@babel/runtime': 7.29.2 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) transitivePeerDependencies: - '@babel/core' - supports-color @@ -22728,6 +22811,10 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 + bufferutil@4.1.0: + dependencies: + node-gyp-build: 4.8.4 + builtin-modules@3.3.0: {} builtin-status-codes@3.0.0: {} @@ -22842,9 +22929,11 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - chromatic@13.3.5(@chromatic-com/playwright@0.12.8(@playwright/test@1.58.2)(@types/react@19.2.14)(esbuild@0.27.4)(typescript@5.9.3)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))): + chownr@3.0.0: {} + + chromatic@13.3.5(@chromatic-com/playwright@0.12.8(@playwright/test@1.58.2)(@types/react@19.2.14)(bufferutil@4.1.0)(esbuild@0.27.4)(typescript@5.9.3)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2))): optionalDependencies: - '@chromatic-com/playwright': 0.12.8(@playwright/test@1.58.2)(@types/react@19.2.14)(esbuild@0.27.4)(typescript@5.9.3)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) + '@chromatic-com/playwright': 0.12.8(@playwright/test@1.58.2)(@types/react@19.2.14)(bufferutil@4.1.0)(esbuild@0.27.4)(typescript@5.9.3)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)) chrome-launcher@0.15.2: dependencies: @@ -23482,14 +23571,14 @@ snapshots: discord-interactions@4.4.0: {} - discord.js@14.25.1: + discord.js@14.25.1(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@discordjs/builders': 1.13.1 '@discordjs/collection': 1.5.3 '@discordjs/formatters': 0.6.2 '@discordjs/rest': 2.6.0 '@discordjs/util': 1.2.0 - '@discordjs/ws': 1.2.3 + '@discordjs/ws': 1.2.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@sapphire/snowflake': 3.5.3 discord-api-types: 0.38.42 fast-deep-equal: 3.1.3 @@ -23647,6 +23736,10 @@ snapshots: encodeurl@2.0.0: {} + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + endent@2.1.0: dependencies: dedent: 0.7.0 @@ -23916,63 +24009,63 @@ snapshots: jest-mock: 30.3.0 jest-util: 30.3.0 - expo-apple-authentication@55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)): + expo-apple-authentication@55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) expo-application@55.0.13(expo@55.0.12): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - expo-asset@55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3): + expo-asset@55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3): dependencies: '@expo/image-utils': 0.8.12 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - expo-constants: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo-constants: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(typescript@5.9.3) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - supports-color - typescript - expo-audio@55.0.12(expo-asset@55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3))(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + expo-audio@55.0.12(expo-asset@55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3))(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - expo-asset: 55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo-asset: 55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) expo-build-properties@55.0.12(expo@55.0.12): dependencies: '@expo/schema-utils': 55.0.3 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) resolve-from: 5.0.0 semver: 7.7.4 - expo-clipboard@55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + expo-clipboard@55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - expo-constants@55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3): + expo-constants@55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(typescript@5.9.3): dependencies: '@expo/config': 55.0.13(typescript@5.9.3) '@expo/env': 2.1.1 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - supports-color - typescript expo-crypto@55.0.14(expo@55.0.12): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-dev-client@55.0.23(expo@55.0.12)(typescript@5.9.3): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-dev-launcher: 55.0.24(expo@55.0.12)(typescript@5.9.3) expo-dev-menu: 55.0.20(expo@55.0.12) expo-dev-menu-interface: 55.0.2(expo@55.0.12) @@ -23985,7 +24078,7 @@ snapshots: expo-dev-launcher@55.0.24(expo@55.0.12)(typescript@5.9.3): dependencies: '@expo/schema-utils': 55.0.3 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-dev-menu: 55.0.20(expo@55.0.12) expo-manifests: 55.0.14(expo@55.0.12)(typescript@5.9.3) transitivePeerDependencies: @@ -23994,80 +24087,80 @@ snapshots: expo-dev-menu-interface@55.0.2(expo@55.0.12): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-dev-menu@55.0.20(expo@55.0.12): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-dev-menu-interface: 55.0.2(expo@55.0.12) expo-document-picker@55.0.12(expo@55.0.12): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-eas-client@55.0.5: {} - expo-file-system@55.0.15(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)): + expo-file-system@55.0.15(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - expo-font@55.0.6(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + expo-font@55.0.6(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) fontfaceobserver: 2.3.0 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - expo-glass-effect@55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + expo-glass-effect@55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) expo-haptics@55.0.13(expo@55.0.12): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-image-loader@55.0.0(expo@55.0.12): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-image-manipulator@55.0.14(expo@55.0.12): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-image-loader: 55.0.0(expo@55.0.12) expo-image-picker@55.0.17(expo@55.0.12): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-image-loader: 55.0.0(expo@55.0.12) - expo-image@55.0.8(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + expo-image@55.0.8(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) sf-symbols-typescript: 2.2.0 expo-insights@55.0.15(expo@55.0.12): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-eas-client: 55.0.5 expo-json-utils@55.0.2: {} expo-keep-awake@55.0.6(expo@55.0.12)(react@19.2.0): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) react: 19.2.0 - expo-linking@55.0.11(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3): + expo-linking@55.0.11(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3): dependencies: - expo-constants: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) + expo-constants: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(typescript@5.9.3) invariant: 2.2.4 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - expo - supports-color @@ -24076,7 +24169,7 @@ snapshots: expo-manifests@55.0.14(expo@55.0.12)(typescript@5.9.3): dependencies: '@expo/config': 55.0.13(typescript@5.9.3) - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-json-utils: 55.0.2 transitivePeerDependencies: - supports-color @@ -24092,56 +24185,56 @@ snapshots: - supports-color - typescript - expo-modules-core@55.0.21(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + expo-modules-core@55.0.21(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: invariant: 2.2.4 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - expo-notifications@55.0.17(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3): + expo-notifications@55.0.17(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3): dependencies: '@expo/image-utils': 0.8.12 abort-controller: 3.0.0 badgin: 1.2.3 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-application: 55.0.13(expo@55.0.12) - expo-constants: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) + expo-constants: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(typescript@5.9.3) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - supports-color - typescript - expo-router@55.0.11(@expo/log-box@55.0.10)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-linking@55.0.11)(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native-gesture-handler@2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + expo-router@55.0.11(19d76ea0d0b88bce60b3b715cef8728d): dependencies: - '@expo/log-box': 55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - '@expo/metro-runtime': 55.0.9(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + '@expo/log-box': 55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@expo/metro-runtime': 55.0.9(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) '@expo/schema-utils': 55.0.3 '@radix-ui/react-slot': 1.2.4(@types/react@19.2.14)(react@19.2.0) '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.0))(react@19.2.0) - '@react-navigation/bottom-tabs': 7.15.8(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - '@react-navigation/native': 7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - '@react-navigation/native-stack': 7.14.5(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + '@react-navigation/bottom-tabs': 7.15.8(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@react-navigation/native': 7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@react-navigation/native-stack': 7.14.5(@react-navigation/native@7.1.33(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) client-only: 0.0.1 debug: 4.4.3 escape-string-regexp: 4.0.0 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - expo-constants: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) - expo-glass-effect: 55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - expo-image: 55.0.8(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - expo-linking: 55.0.11(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo-constants: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(typescript@5.9.3) + expo-glass-effect: 55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + expo-image: 55.0.8(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + expo-linking: 55.0.11(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3) expo-server: 55.0.7 - expo-symbols: 55.0.7(expo-font@55.0.6)(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + expo-symbols: 55.0.7(expo-font@55.0.6)(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) fast-deep-equal: 3.1.3 invariant: 2.2.4 nanoid: 3.3.11 query-string: 7.1.3 react: 19.2.0 react-fast-compare: 3.2.2 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) - react-native-is-edge-to-edge: 1.3.1(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - react-native-safe-area-context: 5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - react-native-screens: 4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native-is-edge-to-edge: 1.3.1(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-safe-area-context: 5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-screens: 4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) semver: 7.6.3 server-only: 0.0.1 sf-symbols-typescript: 2.2.0 @@ -24150,8 +24243,8 @@ snapshots: vaul: 1.1.2(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.0))(react@19.2.0) optionalDependencies: react-dom: 19.2.4(react@19.2.0) - react-native-gesture-handler: 2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - react-native-reanimated: 4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + react-native-gesture-handler: 2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-reanimated: 4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) transitivePeerDependencies: - '@react-native-masked-view/masked-view' - '@types/react' @@ -24161,7 +24254,7 @@ snapshots: expo-secure-store@55.0.12(expo@55.0.12): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-server-sdk@6.1.0(patch_hash=7850520582b5b394397b35d1ea195192fe78589d8a6a748fe15177b818c4ed0b): dependencies: @@ -24171,90 +24264,90 @@ snapshots: expo-server@55.0.7: {} - expo-sharing@55.0.17(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + expo-sharing@55.0.17(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: '@expo/config-plugins': 55.0.8 '@expo/config-types': 55.0.5 '@expo/plist': 0.5.2 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - supports-color expo-splash-screen@55.0.16(expo@55.0.12)(typescript@5.9.3): dependencies: '@expo/prebuild-config': 55.0.13(expo@55.0.12)(typescript@5.9.3) - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) transitivePeerDependencies: - supports-color - typescript - expo-status-bar@55.0.5(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + expo-status-bar@55.0.5(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) - react-native-is-edge-to-edge: 1.3.1(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native-is-edge-to-edge: 1.3.1(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) - expo-symbols@55.0.7(expo-font@55.0.6)(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + expo-symbols@55.0.7(expo-font@55.0.6)(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: '@expo-google-fonts/material-symbols': 0.4.27 - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - expo-font: 55.0.6(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + expo-font: 55.0.6(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) sf-symbols-typescript: 2.2.0 - expo-tracking-transparency@55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)): + expo-tracking-transparency@55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) expo-updates-interface@55.1.5(expo@55.0.12): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) - expo-video@55.0.14(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + expo-video@55.0.14(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - expo-web-browser@55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)): + expo-web-browser@55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - expo@55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3): + expo@55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6): dependencies: '@babel/runtime': 7.29.2 - '@expo/cli': 55.0.22(@expo/metro-runtime@55.0.9)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-router@55.0.11)(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + '@expo/cli': 55.0.22(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-constants@55.0.12)(expo-font@55.0.6)(expo-router@55.0.11)(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) '@expo/config': 55.0.13(typescript@5.9.3) '@expo/config-plugins': 55.0.8 - '@expo/devtools': 55.0.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + '@expo/devtools': 55.0.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) '@expo/fingerprint': 0.16.6 '@expo/local-build-cache-provider': 55.0.9(typescript@5.9.3) - '@expo/log-box': 55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - '@expo/metro': 55.0.0 - '@expo/metro-config': 55.0.14(expo@55.0.12)(typescript@5.9.3) - '@expo/vector-icons': 15.1.1(expo-font@55.0.6)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + '@expo/log-box': 55.0.10(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@expo/metro': 55.0.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@expo/metro-config': 55.0.14(bufferutil@4.1.0)(expo@55.0.12)(typescript@5.9.3)(utf-8-validate@6.0.6) + '@expo/vector-icons': 15.1.1(expo-font@55.0.6)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) '@ungap/structured-clone': 1.3.0 babel-preset-expo: 55.0.16(@babel/core@7.29.0)(@babel/runtime@7.29.2)(expo@55.0.12)(react-refresh@0.14.2) - expo-asset: 55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) - expo-constants: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(typescript@5.9.3) - expo-file-system: 55.0.15(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)) - expo-font: 55.0.6(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + expo-asset: 55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3) + expo-constants: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(typescript@5.9.3) + expo-file-system: 55.0.15(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) + expo-font: 55.0.6(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) expo-keep-awake: 55.0.6(expo@55.0.12)(react@19.2.0) expo-modules-autolinking: 55.0.15(typescript@5.9.3) - expo-modules-core: 55.0.21(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + expo-modules-core: 55.0.21(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) pretty-format: 29.7.0 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) react-refresh: 0.14.2 whatwg-url-minimum: 0.1.1 optionalDependencies: - '@expo/dom-webview': 55.0.5(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - '@expo/metro-runtime': 55.0.9(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + '@expo/dom-webview': 55.0.5(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@expo/metro-runtime': 55.0.9(expo@55.0.12)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) transitivePeerDependencies: - '@babel/core' - bufferutil @@ -24956,7 +25049,7 @@ snapshots: ini@4.1.1: {} - ink@6.8.0(@types/react@19.2.14)(react-devtools-core@6.1.5)(react@19.2.4): + ink@6.8.0(@types/react@19.2.14)(bufferutil@4.1.0)(react-devtools-core@6.1.5(bufferutil@4.1.0)(utf-8-validate@6.0.6))(react@19.2.4)(utf-8-validate@6.0.6): dependencies: '@alcalzone/ansi-tokenize': 0.2.5 ansi-escapes: 7.3.0 @@ -24982,11 +25075,11 @@ snapshots: type-fest: 5.5.0 widest-line: 6.0.0 wrap-ansi: 9.0.2 - ws: 8.19.0 + ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) yoga-layout: 3.2.1 optionalDependencies: '@types/react': 19.2.14 - react-devtools-core: 6.1.5 + react-devtools-core: 6.1.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -25132,9 +25225,9 @@ snapshots: isexe@2.0.0: {} - isomorphic-ws@5.0.0(ws@8.19.0): + isomorphic-ws@5.0.0(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)): dependencies: - ws: 8.19.0 + ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) istanbul-lib-coverage@3.2.2: {} @@ -26307,11 +26400,11 @@ snapshots: dependencies: yallist: 4.0.0 - lucide-react-native@1.7.0(react-native-svg@15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + lucide-react-native@1.7.0(react-native-svg@15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) - react-native-svg: 15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native-svg: 15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) lucide-react@0.552.0(react@19.2.4): dependencies: @@ -26593,12 +26686,12 @@ snapshots: transitivePeerDependencies: - supports-color - metro-config@0.83.5: + metro-config@0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: connect: 3.7.0 flow-enums-runtime: 0.0.6 jest-validate: 29.7.0 - metro: 0.83.5 + metro: 0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) metro-cache: 0.83.5 metro-core: 0.83.5 metro-runtime: 0.83.5 @@ -26678,14 +26771,14 @@ snapshots: transitivePeerDependencies: - supports-color - metro-transform-worker@0.83.5: + metro-transform-worker@0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@babel/core': 7.29.0 '@babel/generator': 7.29.1 '@babel/parser': 7.29.0 '@babel/types': 7.29.0 flow-enums-runtime: 0.0.6 - metro: 0.83.5 + metro: 0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) metro-babel-transformer: 0.83.5 metro-cache: 0.83.5 metro-cache-key: 0.83.5 @@ -26698,7 +26791,7 @@ snapshots: - supports-color - utf-8-validate - metro@0.83.5: + metro@0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@babel/code-frame': 7.29.0 '@babel/core': 7.29.0 @@ -26724,7 +26817,7 @@ snapshots: metro-babel-transformer: 0.83.5 metro-cache: 0.83.5 metro-cache-key: 0.83.5 - metro-config: 0.83.5 + metro-config: 0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) metro-core: 0.83.5 metro-file-map: 0.83.5 metro-resolver: 0.83.5 @@ -26732,13 +26825,13 @@ snapshots: metro-source-map: 0.83.5 metro-symbolicate: 0.83.5 metro-transform-plugins: 0.83.5 - metro-transform-worker: 0.83.5 + metro-transform-worker: 0.83.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) mime-types: 3.0.2 nullthrows: 1.1.1 serialize-error: 2.1.0 source-map: 0.5.7 throat: 5.0.0 - ws: 7.5.10 + ws: 7.5.10(bufferutil@4.1.0)(utf-8-validate@6.0.6) yargs: 17.7.2 transitivePeerDependencies: - bufferutil @@ -27045,7 +27138,7 @@ snapshots: min-indent@1.0.1: {} - miniflare@4.20250906.0: + miniflare@4.20250906.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@cspotcode/source-map-support': 0.8.1 acorn: 8.14.0 @@ -27056,32 +27149,32 @@ snapshots: stoppable: 1.1.0 undici: 7.24.3 workerd: 1.20250906.0 - ws: 8.18.0 + ws: 8.18.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) youch: 4.1.0-beta.10 zod: 3.22.3 transitivePeerDependencies: - bufferutil - utf-8-validate - miniflare@4.20260310.0: + miniflare@4.20260310.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@cspotcode/source-map-support': 0.8.1 sharp: 0.34.5 undici: 7.18.2 workerd: 1.20260310.1 - ws: 8.18.0 + ws: 8.18.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) youch: 4.1.0-beta.10 transitivePeerDependencies: - bufferutil - utf-8-validate - miniflare@4.20260312.0: + miniflare@4.20260312.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@cspotcode/source-map-support': 0.8.1 sharp: 0.34.5 undici: 7.18.2 workerd: 1.20260312.1 - ws: 8.18.0 + ws: 8.18.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) youch: 4.1.0-beta.10 transitivePeerDependencies: - bufferutil @@ -27111,6 +27204,10 @@ snapshots: minipass@7.1.3: {} + minizlib@3.1.0: + dependencies: + minipass: 7.1.3 + mkdirp@1.0.4: {} module-definition@6.0.1: @@ -27158,9 +27255,9 @@ snapshots: napi-postinstall@0.3.4: {} - nativewind@5.0.0-preview.3(react-native-css@3.0.6(@expo/metro-config@55.0.14(expo@55.0.12)(typescript@5.9.3))(lightningcss@1.30.1)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(tailwindcss@4.2.2): + nativewind@5.0.0-preview.3(react-native-css@3.0.6(@expo/metro-config@55.0.14(bufferutil@4.1.0)(expo@55.0.12)(typescript@5.9.3)(utf-8-validate@6.0.6))(lightningcss@1.30.1)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(tailwindcss@4.2.2): dependencies: - react-native-css: 3.0.6(@expo/metro-config@55.0.14(expo@55.0.12)(typescript@5.9.3))(lightningcss@1.30.1)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + react-native-css: 3.0.6(@expo/metro-config@55.0.14(bufferutil@4.1.0)(expo@55.0.12)(typescript@5.9.3)(utf-8-validate@6.0.6))(lightningcss@1.30.1)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) tailwindcss: 4.2.2 tailwindcss-safe-area: 1.3.0(tailwindcss@4.2.2) @@ -27223,12 +27320,18 @@ snapshots: node-abort-controller@3.1.1: {} + node-fetch@2.6.7: + dependencies: + whatwg-url: 5.0.0 + node-fetch@2.7.0: dependencies: whatwg-url: 5.0.0 node-forge@1.3.3: {} + node-gyp-build@4.8.4: {} + node-html-markdown@2.0.0: dependencies: node-html-parser: 6.1.13 @@ -27399,9 +27502,9 @@ snapshots: is-docker: 2.2.1 is-wsl: 2.2.0 - openai@6.29.0(ws@8.19.0)(zod@4.3.6): + openai@6.29.0(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(zod@4.3.6): optionalDependencies: - ws: 8.19.0 + ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) zod: 4.3.6 opener@1.5.2: {} @@ -27999,6 +28102,11 @@ snapshots: randombytes: 2.1.0 safe-buffer: 5.2.1 + pump@3.0.4: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + punycode@1.4.1: {} punycode@2.3.1: {} @@ -28065,10 +28173,10 @@ snapshots: countup.js: 2.10.0 react: 19.2.4 - react-devtools-core@6.1.5: + react-devtools-core@6.1.5(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: shell-quote: 1.8.3 - ws: 7.5.10 + ws: 7.5.10(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -28163,9 +28271,9 @@ snapshots: react-native-appsflyer@6.17.9: {} - react-native-css@3.0.6(@expo/metro-config@55.0.14(expo@55.0.12)(typescript@5.9.3))(lightningcss@1.30.1)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + react-native-css@3.0.6(@expo/metro-config@55.0.14(bufferutil@4.1.0)(expo@55.0.12)(typescript@5.9.3)(utf-8-validate@6.0.6))(lightningcss@1.30.1)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: - '@expo/metro-config': 55.0.14(expo@55.0.12)(typescript@5.9.3) + '@expo/metro-config': 55.0.14(bufferutil@4.1.0)(expo@55.0.12)(typescript@5.9.3)(utf-8-validate@6.0.6) '@types/debug': 4.1.12 babel-plugin-react-compiler: 19.1.0-rc.3 colorjs.io: 0.6.0-alpha.1 @@ -28173,27 +28281,27 @@ snapshots: debug: 4.4.3 lightningcss: 1.30.1 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - supports-color - react-native-gesture-handler@2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + react-native-gesture-handler@2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: '@egjs/hammerjs': 2.0.17 hoist-non-react-statics: 3.3.2 invariant: 2.2.4 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - react-native-is-edge-to-edge@1.2.1(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + react-native-is-edge-to-edge@1.2.1(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - react-native-is-edge-to-edge@1.3.1(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + react-native-is-edge-to-edge@1.3.1(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) react-native-lightbox@0.7.0: dependencies: @@ -28205,40 +28313,40 @@ snapshots: react-native-lightbox: 0.7.0 simple-markdown: 0.7.3 - react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) - react-native-is-edge-to-edge: 1.2.1(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - react-native-worklets: 0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native-is-edge-to-edge: 1.2.1(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-worklets: 0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) semver: 7.7.3 - react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) - react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: react: 19.2.0 react-freeze: 1.0.4(react@19.2.0) - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) warn-once: 0.1.1 - react-native-svg@15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + react-native-svg@15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: css-select: 5.2.2 css-tree: 1.1.3 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) warn-once: 0.1.1 - react-native-url-polyfill@2.0.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)): + react-native-url-polyfill@2.0.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)): dependencies: - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) whatwg-url-without-unicode: 8.0.0-3 - react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0): dependencies: '@babel/core': 7.29.0 '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) @@ -28252,21 +28360,21 @@ snapshots: '@babel/preset-typescript': 7.27.1(@babel/core@7.29.0) convert-source-map: 2.0.0 react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) semver: 7.7.3 transitivePeerDependencies: - supports-color - react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0): + react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6): dependencies: '@jest/create-cache-key-function': 29.7.0 '@react-native/assets-registry': 0.83.4 '@react-native/codegen': 0.83.4 - '@react-native/community-cli-plugin': 0.83.4 + '@react-native/community-cli-plugin': 0.83.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) '@react-native/gradle-plugin': 0.83.4 '@react-native/js-polyfills': 0.83.4 '@react-native/normalize-colors': 0.83.4 - '@react-native/virtualized-lists': 0.83.4(@types/react@19.2.14)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + '@react-native/virtualized-lists': 0.83.4(@types/react@19.2.14)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) abort-controller: 3.0.0 anser: 1.4.10 ansi-regex: 5.0.1 @@ -28286,14 +28394,14 @@ snapshots: pretty-format: 29.7.0 promise: 8.3.0 react: 19.2.0 - react-devtools-core: 6.1.5 + react-devtools-core: 6.1.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) react-refresh: 0.14.2 regenerator-runtime: 0.13.11 scheduler: 0.27.0 semver: 7.7.4 stacktrace-parser: 0.1.11 whatwg-fetch: 3.6.20 - ws: 7.5.10 + ws: 7.5.10(bufferutil@4.1.0)(utf-8-validate@6.0.6) yargs: 17.7.2 optionalDependencies: '@types/react': 19.2.14 @@ -29090,15 +29198,15 @@ snapshots: smol-toml@1.6.0: {} - sonner-native@0.23.1(react-native-gesture-handler@2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-screens@4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-svg@15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0): + sonner-native@0.23.1(53175ba88151f39b99a3b76a61c65c1d): dependencies: react: 19.2.0 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) - react-native-gesture-handler: 2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - react-native-reanimated: 4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - react-native-safe-area-context: 5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - react-native-screens: 4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - react-native-svg: 15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native-gesture-handler: 2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-reanimated: 4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-safe-area-context: 5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-screens: 4.23.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-svg: 15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) sonner@2.0.7(react-dom@19.2.4(react@19.2.4))(react@19.2.4): dependencies: @@ -29173,7 +29281,7 @@ snapshots: stoppable@1.1.0: {} - storybook@9.1.20: + storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@storybook/global': 5.0.0 '@testing-library/jest-dom': 6.9.1 @@ -29186,7 +29294,7 @@ snapshots: esbuild-register: 3.6.0(esbuild@0.27.4) recast: 0.23.11 semver: 7.7.4 - ws: 8.19.0 + ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - '@testing-library/dom' - bufferutil @@ -29195,7 +29303,7 @@ snapshots: - utf-8-validate - vite - storybook@9.1.20(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): + storybook@9.1.20(bufferutil@4.1.0)(utf-8-validate@6.0.6)(vite@8.0.0(@types/node@25.5.0)(esbuild@0.27.4)(jiti@2.6.1)(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)): dependencies: '@storybook/global': 5.0.0 '@testing-library/jest-dom': 6.9.1 @@ -29208,7 +29316,7 @@ snapshots: esbuild-register: 3.6.0(esbuild@0.27.4) recast: 0.23.11 semver: 7.7.4 - ws: 8.19.0 + ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - '@testing-library/dom' - bufferutil @@ -29224,21 +29332,21 @@ snapshots: stream-buffers@2.2.0: {} - stream-chat-expo@8.13.7(1e63c802e7ba809d1a117ef902c76ac6): + stream-chat-expo@8.13.7(ca06b49660395c2e8a06a215cb1b2881): dependencies: - expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + expo: 55.0.12(@babel/core@7.29.0)(@expo/dom-webview@55.0.5)(@expo/metro-runtime@55.0.9)(bufferutil@4.1.0)(expo-router@55.0.11)(react-dom@19.2.4(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3)(utf-8-validate@6.0.6) expo-image-manipulator: 55.0.14(expo@55.0.12) mime: 4.1.0 - stream-chat-react-native-core: 8.13.7(patch_hash=6fa2fe7a3ddb0ab3312ee1adc4e07d3fc9c46f7bc5bb861675bef4078808b8c0)(@react-native-community/netinfo@11.5.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(@types/react@19.2.14)(react-native-gesture-handler@2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-svg@15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3) + stream-chat-react-native-core: 8.13.7(patch_hash=6fa2fe7a3ddb0ab3312ee1adc4e07d3fc9c46f7bc5bb861675bef4078808b8c0)(7fc602c903d0a1fdf12b0cea030ebc54) optionalDependencies: - expo-audio: 55.0.12(expo-asset@55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3))(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - expo-clipboard: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + expo-audio: 55.0.12(expo-asset@55.0.13(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0)(typescript@5.9.3))(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + expo-clipboard: 55.0.12(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) expo-document-picker: 55.0.12(expo@55.0.12) - expo-file-system: 55.0.15(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)) + expo-file-system: 55.0.15(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) expo-haptics: 55.0.13(expo@55.0.12) expo-image-picker: 55.0.17(expo@55.0.12) - expo-sharing: 55.0.17(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - expo-video: 55.0.14(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + expo-sharing: 55.0.17(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + expo-video: 55.0.14(expo@55.0.12)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) transitivePeerDependencies: - '@emoji-mart/data' - '@op-engineering/op-sqlite' @@ -29258,10 +29366,10 @@ snapshots: - typescript - utf-8-validate - stream-chat-react-native-core@8.13.7(patch_hash=6fa2fe7a3ddb0ab3312ee1adc4e07d3fc9c46f7bc5bb861675bef4078808b8c0)(@react-native-community/netinfo@11.5.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(@types/react@19.2.14)(react-native-gesture-handler@2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-safe-area-context@5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-svg@15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0)(typescript@5.9.3): + stream-chat-react-native-core@8.13.7(patch_hash=6fa2fe7a3ddb0ab3312ee1adc4e07d3fc9c46f7bc5bb861675bef4078808b8c0)(7fc602c903d0a1fdf12b0cea030ebc54): dependencies: - '@gorhom/bottom-sheet': 5.1.8(patch_hash=c5eaae9a28f5662f32d66e0129609680309eddc44720d6a2b1e02bbc2b5dd11f)(@types/react@19.2.14)(react-native-gesture-handler@2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - '@react-native-community/netinfo': 11.5.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + '@gorhom/bottom-sheet': 5.1.8(patch_hash=c5eaae9a28f5662f32d66e0129609680309eddc44720d6a2b1e02bbc2b5dd11f)(@types/react@19.2.14)(react-native-gesture-handler@2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native-reanimated@4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + '@react-native-community/netinfo': 11.5.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) '@ungap/structured-clone': 1.3.0 dayjs: 1.11.13 emoji-regex: 10.6.0 @@ -29271,14 +29379,14 @@ snapshots: lodash-es: 4.17.23 mime-types: 2.1.35 path: 0.12.7 - react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0) - react-native-gesture-handler: 2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) + react-native: 0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6) + react-native-gesture-handler: 2.30.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) react-native-markdown-package: 1.8.2 - react-native-reanimated: 4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - react-native-safe-area-context: 5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - react-native-svg: 15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0))(react@19.2.0) - react-native-url-polyfill: 2.0.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.0)) - stream-chat: 9.38.0 + react-native-reanimated: 4.2.1(react-native-worklets@0.7.2(@babel/core@7.29.0)(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0))(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-safe-area-context: 5.6.2(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-svg: 15.15.3(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6))(react@19.2.0) + react-native-url-polyfill: 2.0.0(react-native@0.83.4(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.0)(utf-8-validate@6.0.6)) + stream-chat: 9.38.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) use-sync-external-store: 1.6.0(react@19.2.0) transitivePeerDependencies: - '@types/react' @@ -29289,7 +29397,7 @@ snapshots: - typescript - utf-8-validate - stream-chat-react@13.14.2(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(stream-chat@9.38.0)(typescript@5.9.3): + stream-chat-react@13.14.2(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(stream-chat@9.38.0(bufferutil@4.1.0)(utf-8-validate@6.0.6))(typescript@5.9.3): dependencies: '@braintree/sanitize-url': 6.0.4 '@floating-ui/react': 0.27.19(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -29316,7 +29424,7 @@ snapshots: react-textarea-autosize: 8.5.9(@types/react@19.2.14)(react@19.2.4) react-virtuoso: 2.19.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) remark-gfm: 4.0.1 - stream-chat: 9.38.0 + stream-chat: 9.38.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) tslib: 2.8.1 unist-builder: 4.0.0 unist-util-visit: 5.1.0 @@ -29328,17 +29436,17 @@ snapshots: - supports-color - typescript - stream-chat@9.38.0: + stream-chat@9.38.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@types/jsonwebtoken': 9.0.10 '@types/ws': 8.18.1 axios: 1.15.0 base64-js: 1.5.1 form-data: 4.0.5 - isomorphic-ws: 5.0.0(ws@8.19.0) + isomorphic-ws: 5.0.0(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)) jsonwebtoken: 9.0.3 linkifyjs: 4.3.2 - ws: 8.19.0 + ws: 8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil - debug @@ -29555,6 +29663,14 @@ snapshots: - bare-buffer - react-native-b4a + tar@7.5.13: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.3 + minizlib: 3.1.0 + yallist: 5.0.0 + teex@1.0.1: dependencies: streamx: 2.23.0 @@ -29676,6 +29792,10 @@ snapshots: tr46@0.0.3: {} + tr46@5.1.1: + dependencies: + punycode: 2.3.1 + tree-kill@1.2.2: {} trim-lines@3.0.1: {} @@ -30004,6 +30124,10 @@ snapshots: dependencies: react: 19.2.4 + utf-8-validate@6.0.6: + dependencies: + node-gyp-build: 4.8.4 + util-deprecate@1.0.2: {} util@0.10.4: @@ -30378,7 +30502,9 @@ snapshots: webidl-conversions@5.0.0: {} - webpack-bundle-analyzer@4.10.1: + webidl-conversions@7.0.0: {} + + webpack-bundle-analyzer@4.10.1(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@discoveryjs/json-ext': 0.5.7 acorn: 8.16.0 @@ -30392,7 +30518,7 @@ snapshots: opener: 1.5.2 picocolors: 1.1.1 sirv: 2.0.4 - ws: 7.5.10 + ws: 7.5.10(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -30533,6 +30659,11 @@ snapshots: punycode: 2.3.1 webidl-conversions: 5.0.0 + whatwg-url@14.2.0: + dependencies: + tr46: 5.1.1 + webidl-conversions: 7.0.0 + whatwg-url@5.0.0: dependencies: tr46: 0.0.3 @@ -30599,13 +30730,13 @@ snapshots: optionalDependencies: hono: 4.12.8 - wrangler@4.35.0(@cloudflare/workers-types@4.20260313.1): + wrangler@4.35.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@cloudflare/kv-asset-handler': 0.4.0 '@cloudflare/unenv-preset': 2.7.3(unenv@2.0.0-rc.21)(workerd@1.20250906.0) blake3-wasm: 2.1.5 esbuild: 0.27.4 - miniflare: 4.20250906.0 + miniflare: 4.20250906.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) path-to-regexp: 6.3.0 unenv: 2.0.0-rc.21 workerd: 1.20250906.0 @@ -30616,13 +30747,13 @@ snapshots: - bufferutil - utf-8-validate - wrangler@4.72.0(@cloudflare/workers-types@4.20260313.1): + wrangler@4.72.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@cloudflare/kv-asset-handler': 0.4.2 '@cloudflare/unenv-preset': 2.15.0(unenv@2.0.0-rc.24)(workerd@1.20260310.1) blake3-wasm: 2.1.5 esbuild: 0.27.4 - miniflare: 4.20260310.0 + miniflare: 4.20260310.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) path-to-regexp: 6.3.0 unenv: 2.0.0-rc.24 workerd: 1.20260310.1 @@ -30633,13 +30764,13 @@ snapshots: - bufferutil - utf-8-validate - wrangler@4.73.0(@cloudflare/workers-types@4.20260313.1): + wrangler@4.73.0(@cloudflare/workers-types@4.20260313.1)(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@cloudflare/kv-asset-handler': 0.4.2 '@cloudflare/unenv-preset': 2.15.0(unenv@2.0.0-rc.24)(workerd@1.20260312.1) blake3-wasm: 2.1.5 esbuild: 0.27.4 - miniflare: 4.20260312.0 + miniflare: 4.20260312.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) path-to-regexp: 6.3.0 unenv: 2.0.0-rc.24 workerd: 1.20260312.1 @@ -30687,11 +30818,20 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 4.1.0 - ws@7.5.10: {} + ws@7.5.10(bufferutil@4.1.0)(utf-8-validate@6.0.6): + optionalDependencies: + bufferutil: 4.1.0 + utf-8-validate: 6.0.6 - ws@8.18.0: {} + ws@8.18.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + optionalDependencies: + bufferutil: 4.1.0 + utf-8-validate: 6.0.6 - ws@8.19.0: {} + ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + optionalDependencies: + bufferutil: 4.1.0 + utf-8-validate: 6.0.6 xcode@3.0.1: dependencies: @@ -30719,6 +30859,8 @@ snapshots: yallist@4.0.0: {} + yallist@5.0.0: {} + yaml-loader@0.8.1: dependencies: javascript-stringify: 2.1.0 diff --git a/services/kiloclaw/.dev.vars.example b/services/kiloclaw/.dev.vars.example index 3e9380f67..1784f9876 100644 --- a/services/kiloclaw/.dev.vars.example +++ b/services/kiloclaw/.dev.vars.example @@ -37,6 +37,22 @@ DOCKER_LOCAL_API_BASE=http://127.0.0.1:23750 DOCKER_LOCAL_IMAGE=kiloclaw:local DOCKER_LOCAL_PORT_RANGE=45000-45999 +# Northflank provider (disabled for rollout until Worker runtime support is smoke-tested). +# NF_API_TOKEN is always a secret; set production values with wrangler secret put. +NF_API_TOKEN= +NF_API_BASE=https://api.northflank.com/v1 +NF_TEAM_ID=kilo-dev +NF_REGION=us-central +NF_DEPLOYMENT_PLAN=nf-compute-200 +NF_STORAGE_CLASS_NAME=nf-multi-rw +NF_STORAGE_ACCESS_MODE=ReadWriteMany +NF_VOLUME_SIZE_MB=10240 +NF_EPHEMERAL_STORAGE_MB=2048 +NF_EDGE_HEADER_NAME=x-kiloclaw-northflank-edge-dev +NF_EDGE_HEADER_VALUE=dev-local-northflank-edge-secret +NF_IMAGE_PATH_TEMPLATE=ghcr.io/kilo-org/kiloclaw:{tag} +NF_IMAGE_CREDENTIALS_ID= + # Auto-populated by dev-start from `fly auth whoami`. # Tags Fly machines with developer identity for cleanup. # @exec fly auth whoami diff --git a/services/kiloclaw/package.json b/services/kiloclaw/package.json index e6389d767..28714284b 100644 --- a/services/kiloclaw/package.json +++ b/services/kiloclaw/package.json @@ -24,6 +24,7 @@ "@kilocode/encryption": "workspace:*", "@kilocode/kiloclaw-secret-catalog": "workspace:*", "@kilocode/worker-utils": "workspace:*", + "@northflank/js-client": "^0.9.3", "drizzle-orm": "catalog:", "hono": "catalog:", "jose": "^6.2.1", diff --git a/services/kiloclaw/src/db/index.ts b/services/kiloclaw/src/db/index.ts index 379839470..ac919bd42 100644 --- a/services/kiloclaw/src/db/index.ts +++ b/services/kiloclaw/src/db/index.ts @@ -95,6 +95,7 @@ export async function getInstanceBySandboxId(db: WorkerDb, sandboxId: string) { sandbox_id: kiloclaw_instances.sandbox_id, user_id: kiloclaw_instances.user_id, organization_id: kiloclaw_instances.organization_id, + provider: kiloclaw_instances.provider, }) .from(kiloclaw_instances) .where( @@ -109,6 +110,7 @@ export async function getInstanceBySandboxId(db: WorkerDb, sandboxId: string) { sandboxId: row.sandbox_id, userId: row.user_id, orgId: row.organization_id, + provider: row.provider, }; } @@ -136,6 +138,7 @@ export async function getInstanceByIdIncludingDestroyed( user_id: kiloclaw_instances.user_id, organization_id: kiloclaw_instances.organization_id, inbound_email_enabled: kiloclaw_instances.inbound_email_enabled, + provider: kiloclaw_instances.provider, }) .from(kiloclaw_instances) .where(where) @@ -149,6 +152,7 @@ export async function getInstanceByIdIncludingDestroyed( userId: row.user_id, orgId: row.organization_id, inboundEmailEnabled: row.inbound_email_enabled, + provider: row.provider, }; } diff --git a/services/kiloclaw/src/durable-objects/kiloclaw-instance/config.ts b/services/kiloclaw/src/durable-objects/kiloclaw-instance/config.ts index 2bb59879a..2dc3168a1 100644 --- a/services/kiloclaw/src/durable-objects/kiloclaw-instance/config.ts +++ b/services/kiloclaw/src/durable-objects/kiloclaw-instance/config.ts @@ -37,6 +37,13 @@ export function resolveRuntimeImageRef(state: InstanceMutableState, env: KiloCla if (state.provider === 'docker-local') { return env.DOCKER_LOCAL_IMAGE ?? 'kiloclaw:local'; } + if (state.provider === 'northflank') { + const template = env.NF_IMAGE_PATH_TEMPLATE; + if (!template) { + throw new Error('NF_IMAGE_PATH_TEMPLATE is not configured'); + } + return template.replaceAll('{tag}', resolveImageTag(state, env)); + } return resolveImageRef(state, env); } diff --git a/services/kiloclaw/src/durable-objects/kiloclaw-instance/postgres.ts b/services/kiloclaw/src/durable-objects/kiloclaw-instance/postgres.ts index 0576f081d..a327c3837 100644 --- a/services/kiloclaw/src/durable-objects/kiloclaw-instance/postgres.ts +++ b/services/kiloclaw/src/durable-objects/kiloclaw-instance/postgres.ts @@ -1,8 +1,13 @@ import type { KiloClawEnv } from '../../types'; -import type { EncryptedEnvelope } from '../../schemas/instance-config'; +import type { + EncryptedEnvelope, + FlyProviderState, + NorthflankProviderState, +} from '../../schemas/instance-config'; import { getWorkerDb, getActivePersonalInstance, + getInstanceById, getInstanceBySandboxId, markInstanceDestroyed, } from '../../db'; @@ -12,13 +17,76 @@ import { getAppKey, getFlyConfig } from './types'; import { applyProviderState, storageUpdate } from './state'; import { attemptMetadataRecovery } from './reconcile'; import { doError, doWarn, toLoggable, createReconcileContext } from './log'; -import { isInstanceKeyedSandboxId } from '@kilocode/worker-utils/instance-id'; +import { + isInstanceKeyedSandboxId, + instanceIdFromSandboxId, +} from '@kilocode/worker-utils/instance-id'; +import { getNorthflankConfig } from '../../northflank/config'; +import { + findProjectByName, + findProjectSecretByName, + findServiceByName, + findVolumeByName, +} from '../../northflank/client'; +import { northflankResourceNames } from '../../providers/northflank/names'; type RestoreOpts = { /** If the DO has a stored sandboxId, use it for precise lookup. */ sandboxId?: string | null; }; +type RestoredInstance = NonNullable>>; + +function firstNorthflankIngressHost(service: { + ports?: Array<{ dns?: string | null }>; +}): string | null { + return service.ports?.find(port => port.dns)?.dns ?? null; +} + +async function getRestoreInstance( + db: ReturnType, + userId: string, + opts?: RestoreOpts +): Promise { + if (opts?.sandboxId && isInstanceKeyedSandboxId(opts.sandboxId)) { + const byId = await getInstanceById(db, instanceIdFromSandboxId(opts.sandboxId)); + if (byId) return byId; + } + if (opts?.sandboxId) { + return await getInstanceBySandboxId(db, opts.sandboxId); + } + const personal = await getActivePersonalInstance(db, userId); + return personal ? await getInstanceBySandboxId(db, personal.sandboxId) : null; +} + +async function recoverNorthflankProviderState( + env: KiloClawEnv, + sandboxId: string +): Promise { + const config = getNorthflankConfig(env); + const names = await northflankResourceNames(sandboxId); + const project = await findProjectByName(config, names.projectName); + const volume = project ? await findVolumeByName(config, project.id, names.volumeName) : null; + const service = project ? await findServiceByName(config, project.id, names.serviceName) : null; + const secret = project + ? await findProjectSecretByName(config, project.id, names.secretName) + : null; + + return { + provider: 'northflank', + projectId: project?.id ?? null, + projectName: project?.name ?? names.projectName, + serviceId: service?.id ?? null, + serviceName: service?.name ?? names.serviceName, + volumeId: volume?.id ?? null, + volumeName: volume?.name ?? names.volumeName, + secretId: secret?.id ?? null, + secretName: secret?.name ?? names.secretName, + ingressHost: service ? firstNorthflankIngressHost(service) : null, + region: config.region, + }; +} + export async function fallbackAppNameForRestore( userId: string, sandboxId: string, @@ -30,6 +98,25 @@ export async function fallbackAppNameForRestore( : appNameFromUserId(appKey, prefix); } +async function recoverFlyProviderState( + env: KiloClawEnv, + userId: string, + sandboxId: string +): Promise { + const appKey = getAppKey({ userId, sandboxId }); + const appStub = env.KILOCLAW_APP.get(env.KILOCLAW_APP.idFromName(appKey)); + const prefix = env.WORKER_ENV === 'development' ? 'dev' : undefined; + const fallbackAppName = await fallbackAppNameForRestore(userId, sandboxId, prefix); + const recoveredAppName = (await appStub.getAppName()) ?? fallbackAppName; + return { + provider: 'fly', + appName: recoveredAppName, + machineId: null, + volumeId: null, + region: null, + }; +} + /** * Restore DO state from Postgres backup if SQLite was wiped. * @@ -53,44 +140,35 @@ export async function restoreFromPostgres( try { const db = getWorkerDb(connectionString); - // Prefer sandboxId lookup (multi-instance safe) over userId lookup (ambiguous). - const instance = opts?.sandboxId - ? await getInstanceBySandboxId(db, opts.sandboxId) - : await getActivePersonalInstance(db, userId); + const instance = await getRestoreInstance(db, userId, opts); if (!instance) { doWarn(state, 'No active instance found in Postgres', { userId }); return; } - console.log('[DO] Restoring state from Postgres backup for', userId); + const restoredUserId = instance.userId ?? userId; + console.log('[DO] Restoring state from Postgres backup for', restoredUserId); const envVars: Record | null = null; const encryptedSecrets: Record | null = null; const channels = null; - // Recover flyAppName from the App DO or derive deterministically. - // Instance-keyed DOs (ki_ sandboxId) have per-instance apps (inst-{hash}), - // legacy DOs have per-user apps (acct-{hash}). - const appKey = getAppKey({ userId, sandboxId: instance.sandboxId }); - const appStub = env.KILOCLAW_APP.get(env.KILOCLAW_APP.idFromName(appKey)); - const prefix = env.WORKER_ENV === 'development' ? 'dev' : undefined; - const fallbackAppName = await fallbackAppNameForRestore(userId, instance.sandboxId, prefix); - const recoveredAppName = (await appStub.getAppName()) ?? fallbackAppName; - const providerState = { - provider: 'fly', - appName: recoveredAppName, - machineId: null, - volumeId: null, - region: null, - } as const; + // docker-local is development-only and should not be restored from Postgres. + // Treat any non-Northflank persisted provider as Fly for legacy safety. + const provider = instance.provider === 'northflank' ? 'northflank' : 'fly'; + const providerState = + provider === 'northflank' + ? await recoverNorthflankProviderState(env, instance.sandboxId) + : await recoverFlyProviderState(env, restoredUserId, instance.sandboxId); + const recoveredAppName = providerState.provider === 'fly' ? providerState.appName : null; await ctx.storage.put( storageUpdate({ - userId, + userId: restoredUserId, sandboxId: instance.sandboxId, orgId: instance.orgId ?? null, - provider: 'fly', + provider, providerState, status: 'provisioned', envVars, @@ -116,7 +194,7 @@ export async function restoreFromPostgres( }) ); - state.userId = userId; + state.userId = restoredUserId; state.sandboxId = instance.sandboxId; state.orgId = instance.orgId ?? null; applyProviderState(state, providerState); @@ -143,19 +221,20 @@ export async function restoreFromPostgres( console.log('[DO] Restored from Postgres: sandboxId =', instance.sandboxId); - // Attempt to recover machine/volume IDs via Fly metadata. - try { - const flyConfig = getFlyConfig(env, state); - await attemptMetadataRecovery( - flyConfig, - ctx, - state, - createReconcileContext(state, env, 'postgres_restore') - ); - } catch (err) { - doWarn(state, 'Metadata recovery after Postgres restore failed', { - error: toLoggable(err), - }); + if (provider === 'fly') { + try { + const flyConfig = getFlyConfig(env, state); + await attemptMetadataRecovery( + flyConfig, + ctx, + state, + createReconcileContext(state, env, 'postgres_restore') + ); + } catch (err) { + doWarn(state, 'Metadata recovery after Postgres restore failed', { + error: toLoggable(err), + }); + } } } catch (err) { doError(state, 'Postgres restore failed', { error: toLoggable(err) }); diff --git a/services/kiloclaw/src/durable-objects/kiloclaw-instance/state.test.ts b/services/kiloclaw/src/durable-objects/kiloclaw-instance/state.test.ts index fc557d45d..575a47e8d 100644 --- a/services/kiloclaw/src/durable-objects/kiloclaw-instance/state.test.ts +++ b/services/kiloclaw/src/durable-objects/kiloclaw-instance/state.test.ts @@ -1,8 +1,11 @@ import { describe, expect, it } from 'vitest'; +import { ProviderStateSchema } from '../../schemas/instance-config'; import { createMutableState } from './state'; import { applyProviderState, getFlyProviderState, + getNorthflankProviderState, + getProviderRegion, getRuntimeId, getStorageId, syncProviderStateForStorage, @@ -170,4 +173,86 @@ describe('provider state helpers', () => { flyRegion: null, }); }); + + it('parses Northflank provider state with null defaults', () => { + expect(ProviderStateSchema.parse({ provider: 'northflank' })).toEqual({ + provider: 'northflank', + projectId: null, + projectName: null, + serviceId: null, + serviceName: null, + volumeId: null, + volumeName: null, + secretId: null, + secretName: null, + ingressHost: null, + region: null, + }); + }); + + it('builds Northflank providerState defaults when providerState is absent', () => { + const state = createMutableState(); + + expect(getNorthflankProviderState(state)).toEqual({ + provider: 'northflank', + projectId: null, + projectName: null, + serviceId: null, + serviceName: null, + volumeId: null, + volumeName: null, + secretId: null, + secretName: null, + ingressHost: null, + region: null, + }); + }); + + it('uses Northflank runtime, storage, and region identifiers', () => { + const state = createMutableState(); + + applyProviderState(state, { + provider: 'northflank', + projectId: 'project-1', + projectName: 'kc-ki-test', + serviceId: 'service-1', + serviceName: 'kc-ki-test', + volumeId: 'volume-1', + volumeName: 'kc-ki-test', + secretId: 'secret-1', + secretName: 'kc-ki-test', + ingressHost: 'kc-ki-test.code.run', + region: 'us-central', + }); + + expect(state.flyAppName).toBeNull(); + expect(state.flyMachineId).toBeNull(); + expect(state.flyVolumeId).toBeNull(); + expect(state.flyRegion).toBeNull(); + expect(getRuntimeId(state)).toBe('service-1'); + expect(getStorageId(state)).toBe('volume-1'); + expect(getProviderRegion(state)).toBe('us-central'); + }); + + it('falls back to Northflank names when IDs are not known yet', () => { + const state = createMutableState(); + + applyProviderState(state, { + provider: 'northflank', + projectId: null, + projectName: 'kc-ki-test', + serviceId: null, + serviceName: 'kc-ki-test', + volumeId: null, + volumeName: 'kc-ki-test', + secretId: null, + secretName: 'kc-ki-test', + ingressHost: null, + region: null, + }); + + expect(getRuntimeId(state)).toBe('kc-ki-test'); + expect(getStorageId(state)).toBe('kc-ki-test'); + expect(getProviderRegion(state)).toBeNull(); + }); }); diff --git a/services/kiloclaw/src/durable-objects/kiloclaw-instance/state.ts b/services/kiloclaw/src/durable-objects/kiloclaw-instance/state.ts index dd9d8907b..d3e6d3c73 100644 --- a/services/kiloclaw/src/durable-objects/kiloclaw-instance/state.ts +++ b/services/kiloclaw/src/durable-objects/kiloclaw-instance/state.ts @@ -4,6 +4,7 @@ import { type ProviderState, type FlyProviderState, type DockerLocalProviderState, + type NorthflankProviderState, } from '../../schemas/instance-config'; import type { InstanceMutableState } from './types'; @@ -98,6 +99,27 @@ export function getDockerLocalProviderState( }; } +export function getNorthflankProviderState( + source: Pick +): NorthflankProviderState { + if (source.providerState?.provider === 'northflank') { + return source.providerState; + } + return { + provider: 'northflank', + projectId: null, + projectName: null, + serviceId: null, + serviceName: null, + volumeId: null, + volumeName: null, + secretId: null, + secretName: null, + ingressHost: null, + region: null, + }; +} + export function getRuntimeId( source: Pick ): string | null { @@ -107,6 +129,9 @@ export function getRuntimeId( if (source.providerState?.provider === 'docker-local') { return source.providerState.containerName; } + if (source.providerState?.provider === 'northflank') { + return source.providerState.serviceId ?? source.providerState.serviceName; + } return source.flyMachineId; } @@ -119,6 +144,9 @@ export function getStorageId( if (source.providerState?.provider === 'docker-local') { return source.providerState.volumeName; } + if (source.providerState?.provider === 'northflank') { + return source.providerState.volumeId ?? source.providerState.volumeName; + } return source.flyVolumeId; } @@ -131,6 +159,9 @@ export function getProviderRegion( if (source.providerState?.provider === 'docker-local') { return null; } + if (source.providerState?.provider === 'northflank') { + return source.providerState.region; + } return source.flyRegion; } diff --git a/services/kiloclaw/src/northflank/client.test.ts b/services/kiloclaw/src/northflank/client.test.ts new file mode 100644 index 000000000..ae66ec9d6 --- /dev/null +++ b/services/kiloclaw/src/northflank/client.test.ts @@ -0,0 +1,288 @@ +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { + NorthflankApiError, + createProjectSecret, + createVolume, + deleteService, + findProjectByName, + getProjectSecretDetails, + isNorthflankConflict, + isNorthflankNotFound, + listServices, + putProjectSecret, +} from './client'; +import { getNorthflankConfig } from './config'; +import type { NorthflankClientConfig } from './client'; + +const config: NorthflankClientConfig = { + ...getNorthflankConfig({ + NF_API_TOKEN: 'nf-token', + NF_API_BASE: 'https://api.northflank.com/v1', + NF_REGION: 'us-central', + NF_DEPLOYMENT_PLAN: 'nf-compute-200', + NF_EDGE_HEADER_NAME: 'x-kiloclaw-edge', + NF_EDGE_HEADER_VALUE: 'edge-secret', + } as never), + redactValues: ['edge-secret', 'env-key-secret'], +}; + +function mockFetchSequence( + responses: Array<[number, unknown, HeadersInit?]> +): ReturnType { + const fetchMock = vi.fn(); + for (const [status, body, headers] of responses) { + const responseBody = typeof body === 'string' ? body : JSON.stringify(body); + fetchMock.mockResolvedValueOnce(new Response(responseBody, { status, headers })); + } + vi.stubGlobal('fetch', fetchMock); + return fetchMock; +} + +function firstFetchCall(fetchMock: ReturnType): [unknown, unknown] { + const firstCall = fetchMock.mock.calls[0]; + if (!firstCall) throw new Error('fetch was not called'); + return [firstCall[0], firstCall[1]]; +} + +function isRecord(value: unknown): value is Record { + return typeof value === 'object' && value !== null && !Array.isArray(value); +} + +function expectRequestInit(value: unknown): RequestInit { + if (!isRecord(value)) throw new Error('fetch init was not an object'); + return value; +} + +function expectHeaderRecord(value: HeadersInit | undefined): Record { + if (!isRecord(value)) throw new Error('headers were not a plain object'); + return value; +} + +function expectStringBody(value: BodyInit | null | undefined): string { + if (typeof value !== 'string') throw new Error('request body was not a string'); + return value; +} + +afterEach(() => { + vi.restoreAllMocks(); +}); + +describe('Northflank Worker fetch client', () => { + it('sends auth headers and creates volumes mounted at /root', async () => { + const fetchMock = mockFetchSequence([[201, { data: { id: 'volume-1', name: 'kc-ki-test' } }]]); + + const volume = await createVolume({ ...config, teamId: 'team-1' }, 'project-1', { + name: 'kc-ki-test', + mountPath: '/root', + storageSizeMb: 10240, + storageClassName: 'nf-multi-rw', + accessMode: 'ReadWriteMany', + }); + + expect(volume).toEqual({ id: 'volume-1', name: 'kc-ki-test' }); + const [url, init] = firstFetchCall(fetchMock); + expect(url).toBe('https://api.northflank.com/v1/teams/team-1/projects/project-1/volumes'); + const requestInit = expectRequestInit(init); + const headers = expectHeaderRecord(requestInit.headers); + expect(requestInit.method).toBe('POST'); + expect(headers.Authorization).toBe('Bearer nf-token'); + expect(headers['Content-Type']).toBe('application/json'); + expect(JSON.parse(expectStringBody(requestInit.body))).toEqual({ + name: 'kc-ki-test', + mounts: [{ containerMountPath: '/root' }], + spec: { + accessMode: 'ReadWriteMany', + storageClassName: 'nf-multi-rw', + storageSize: 10240, + }, + }); + }); + + it('finds projects by deterministic name', async () => { + mockFetchSequence([ + [ + 200, + { + data: { projects: [{ id: 'project-1', name: 'kc-ki-test' }] }, + pagination: { hasNextPage: false }, + }, + ], + ]); + + await expect(findProjectByName(config, 'kc-ki-test')).resolves.toEqual({ + id: 'project-1', + name: 'kc-ki-test', + }); + }); + + it('lists services with deployment status and ingress DNS', async () => { + mockFetchSequence([ + [ + 200, + { + data: { + services: [ + { + id: 'service-1', + name: 'kc-ki-test', + servicePaused: false, + deployment: { instances: 1 }, + status: { deployment: { status: 'COMPLETED' } }, + ports: [{ name: 'p01', dns: 'kc-ki-test.code.run' }], + }, + ], + }, + }, + ], + ]); + + const result = await listServices(config, 'project-1'); + + expect(result.hasNextPage).toBe(false); + const firstService = result.services[0]; + expect(firstService?.id).toBe('service-1'); + expect(firstService?.name).toBe('kc-ki-test'); + expect(firstService?.servicePaused).toBe(false); + expect(firstService?.deployment).toEqual({ instances: 1 }); + expect(firstService?.status?.deployment?.status).toBe('COMPLETED'); + expect(firstService?.ports).toEqual([{ name: 'p01', dns: 'kc-ki-test.code.run' }]); + }); + + it('encodes delete_child_objects as a query parameter', async () => { + const fetchMock = mockFetchSequence([[200, '']]); + + await deleteService(config, 'project-1', 'service-1', false); + + const [url, init] = firstFetchCall(fetchMock); + expect(url).toBe( + 'https://api.northflank.com/v1/projects/project-1/services/service-1?delete_child_objects=false' + ); + expect(expectRequestInit(init).method).toBe('DELETE'); + }); + + it('creates project secrets through Northflank project-scoped routes', async () => { + const fetchMock = mockFetchSequence([[201, { data: { id: 'secret-1', name: 'kc-ki-test' } }]]); + + await expect( + createProjectSecret({ ...config, teamId: 'team-1' }, 'project-1', { + name: 'kc-ki-test', + type: 'secret', + secretType: 'environment', + priority: 100, + restrictions: { + restricted: true, + nfObjects: [{ id: 'service-1', type: 'service' }], + }, + secrets: { variables: { KILOCLAW_ENV_KEY: 'env-key-secret' } }, + }) + ).resolves.toEqual({ id: 'secret-1', name: 'kc-ki-test' }); + + const [url] = firstFetchCall(fetchMock); + expect(url).toBe('https://api.northflank.com/v1/projects/project-1/secrets'); + }); + + it('updates project secrets with PATCH on the secret-specific route', async () => { + const fetchMock = mockFetchSequence([[200, { data: { id: 'secret-1', name: 'kc-ki-test' } }]]); + + await expect( + putProjectSecret(config, 'project-1', 'secret-1', { + name: 'kc-ki-test', + type: 'secret', + secretType: 'environment', + priority: 100, + restrictions: { + restricted: true, + nfObjects: [{ id: 'service-1', type: 'service' }], + }, + secrets: { variables: { KILOCLAW_ENV_KEY: 'env-key-secret' } }, + }) + ).resolves.toEqual({ id: 'secret-1', name: 'kc-ki-test' }); + + const [url, init] = firstFetchCall(fetchMock); + expect(url).toBe('https://api.northflank.com/v1/projects/project-1/secrets/secret-1'); + const requestInit = expectRequestInit(init); + expect(requestInit.method).toBe('PATCH'); + expect(JSON.parse(expectStringBody(requestInit.body))).toEqual({ + type: 'secret', + secretType: 'environment', + priority: 100, + restrictions: { + restricted: true, + nfObjects: [{ id: 'service-1', type: 'service' }], + }, + secrets: { variables: { KILOCLAW_ENV_KEY: 'env-key-secret' } }, + }); + }); + + it('redacts secret values from API errors', async () => { + mockFetchSequence([ + [ + 500, + { + error: 'failed with nf-token and edge-secret', + secrets: { variables: { KILOCLAW_ENV_KEY: 'env-key-secret' } }, + password: 'registry-password', + }, + { + 'x-request-id': 'req-1', + 'x-ratelimit-limit': '100', + 'x-ratelimit-remaining': '0', + 'x-ratelimit-reset': '123', + }, + ], + ]); + + let caught: unknown; + try { + await getProjectSecretDetails(config, 'project-1', 'secret-1'); + } catch (err) { + caught = err; + } + + expect(caught).toBeInstanceOf(NorthflankApiError); + if (!(caught instanceof NorthflankApiError)) throw new Error('expected NorthflankApiError'); + expect(caught.status).toBe(500); + expect(caught.requestId).toBe('req-1'); + expect(caught.rateLimit).toEqual({ limit: '100', remaining: '0', reset: '123' }); + expect(caught.body).not.toContain('nf-token'); + expect(caught.message).not.toContain('edge-secret'); + expect(caught.body).not.toContain('env-key-secret'); + expect(caught.body).not.toContain('registry-password'); + }); + + it('includes thrown fetch error messages without leaking secrets', async () => { + vi.stubGlobal( + 'fetch', + vi.fn(async () => { + throw new Error('failed with nf-token and edge-secret'); + }) + ); + + let caught: unknown; + try { + await getProjectSecretDetails(config, 'project-1', 'secret-1'); + } catch (err) { + caught = err; + } + + expect(caught).toBeInstanceOf(NorthflankApiError); + if (!(caught instanceof NorthflankApiError)) throw new Error('expected NorthflankApiError'); + expect(caught.status).toBe(503); + expect(caught.body).toContain('failed with [REDACTED] and [REDACTED]'); + }); +}); + +describe('Northflank error helpers', () => { + it('matches not-found and conflict API errors', () => { + const rateLimit = { limit: null, remaining: null, reset: null }; + + expect( + isNorthflankNotFound(new NorthflankApiError('not found', 404, '{}', null, rateLimit)) + ).toBe(true); + expect( + isNorthflankConflict(new NorthflankApiError('conflict', 409, '{}', null, rateLimit)) + ).toBe(true); + expect(isNorthflankNotFound(new Error('not found'))).toBe(false); + expect(isNorthflankConflict(new Error('conflict'))).toBe(false); + }); +}); diff --git a/services/kiloclaw/src/northflank/client.ts b/services/kiloclaw/src/northflank/client.ts new file mode 100644 index 000000000..b5b650db8 --- /dev/null +++ b/services/kiloclaw/src/northflank/client.ts @@ -0,0 +1,589 @@ +import { z } from 'zod'; +import type { + CreateSecretRequest, + CreateServiceDeploymentRequest, + PatchSecretRequest, + PatchServiceDeploymentRequest, +} from '@northflank/js-client'; +import type { NorthflankConfig } from './config'; + +export type NorthflankClientConfig = NorthflankConfig & { + redactValues?: string[]; +}; + +export type NorthflankRateLimitInfo = { + limit: string | null; + remaining: string | null; + reset: string | null; +}; + +export class NorthflankApiError extends Error { + constructor( + message: string, + readonly status: number, + readonly body: string, + readonly requestId: string | null, + readonly rateLimit: NorthflankRateLimitInfo + ) { + super(message); + this.name = 'NorthflankApiError'; + } +} + +const NorthflankProjectSchema = z.object({ id: z.string(), name: z.string() }).passthrough(); +const NorthflankVolumeSchema = z.object({ id: z.string(), name: z.string() }).passthrough(); +const NorthflankPortSchema = z + .object({ name: z.string().optional(), dns: z.string().nullable().optional() }) + .passthrough(); +const NorthflankServiceSchema = z + .object({ + id: z.string(), + name: z.string(), + servicePaused: z.boolean().optional(), + ports: z.array(NorthflankPortSchema).optional(), + deployment: z.object({ instances: z.number().int().optional() }).passthrough().optional(), + status: z + .object({ + deployment: z.object({ status: z.string().optional() }).passthrough().optional(), + }) + .passthrough() + .optional(), + }) + .passthrough(); +const NorthflankSecretDetailsSchema = z.object({ id: z.string(), name: z.string() }).passthrough(); + +const ProjectResponseSchema = z.object({ data: NorthflankProjectSchema }); +const ProjectListResponseSchema = z.object({ + data: z.object({ projects: z.array(NorthflankProjectSchema) }).passthrough(), + pagination: z.object({ hasNextPage: z.boolean().optional() }).passthrough().optional(), +}); +const VolumeResponseSchema = z.object({ data: NorthflankVolumeSchema }); +const VolumeListResponseSchema = z.object({ data: z.array(NorthflankVolumeSchema) }); +const ServiceResponseSchema = z.object({ data: NorthflankServiceSchema }); +const ServiceListResponseSchema = z.object({ + data: z.object({ services: z.array(NorthflankServiceSchema) }).passthrough(), +}); +const SecretDetailsResponseSchema = z.object({ data: NorthflankSecretDetailsSchema }); +const SecretListResponseSchema = z.object({ + data: z.object({ secrets: z.array(NorthflankSecretDetailsSchema) }).passthrough(), +}); + +export type NorthflankProject = z.infer; +export type NorthflankVolume = z.infer; +export type NorthflankService = z.infer; +export type NorthflankSecretDetails = z.infer; + +function isRecord(value: unknown): value is Record { + return typeof value === 'object' && value !== null && !Array.isArray(value); +} + +function isSensitiveKey(key: string): boolean { + return /(authorization|password|token|secret|api[_-]?key|credential)/i.test(key); +} + +function redactUnknown(value: unknown): unknown { + if (Array.isArray(value)) return value.map(item => redactUnknown(item)); + if (!isRecord(value)) return value; + + const redacted: Record = {}; + for (const [key, nestedValue] of Object.entries(value)) { + redacted[key] = isSensitiveKey(key) ? '[REDACTED]' : redactUnknown(nestedValue); + } + return redacted; +} + +function redactText(text: string, config: NorthflankClientConfig): string { + let redacted = text; + const values = [config.apiToken, ...(config.redactValues ?? [])].filter( + value => value.length > 0 + ); + for (const value of values) { + redacted = redacted.split(value).join('[REDACTED]'); + } + return redacted; +} + +function redactForError(value: unknown, config: NorthflankClientConfig): string { + if (value instanceof Error) { + return redactText( + JSON.stringify({ name: value.name, message: value.message, stack: value.stack }), + config + ); + } + try { + return redactText(JSON.stringify(redactUnknown(value)), config); + } catch { + return redactText(String(value), config); + } +} + +function rateLimitFromHeaders(headers: Headers): NorthflankRateLimitInfo { + return { + limit: headers.get('x-ratelimit-limit'), + remaining: headers.get('x-ratelimit-remaining'), + reset: headers.get('x-ratelimit-reset'), + }; +} + +function northflankPath(config: NorthflankClientConfig, path: string, teamScoped = true): string { + const base = config.apiBase.replace(/\/$/, ''); + const normalizedPath = path.startsWith('/') ? path : `/${path}`; + if (!teamScoped || !config.teamId || normalizedPath.startsWith('/teams/')) { + return `${base}${normalizedPath}`; + } + return `${base}/teams/${encodeURIComponent(config.teamId)}${normalizedPath}`; +} + +function pathWithQuery(path: string, params: Record) { + const search = new URLSearchParams(); + for (const [key, value] of Object.entries(params)) { + if (value !== null) search.set(key, String(value)); + } + const query = search.toString(); + return query ? `${path}?${query}` : path; +} + +async function requestJson( + config: NorthflankClientConfig, + path: string, + init: RequestInit | undefined, + schema: z.ZodType, + expectedStatuses: number[], + context: string, + options?: { teamScoped?: boolean } +): Promise { + let response: Response; + try { + response = await fetch(northflankPath(config, path, options?.teamScoped), { + ...init, + headers: { + Authorization: `Bearer ${config.apiToken}`, + 'Content-Type': 'application/json', + ...init?.headers, + }, + }); + } catch (err) { + const body = redactForError(err, config); + throw new NorthflankApiError( + `Northflank API ${context} failed before response: ${body}`, + 503, + body, + null, + { limit: null, remaining: null, reset: null } + ); + } + + const text = await response.text(); + let json: unknown = null; + if (text) { + try { + json = JSON.parse(text); + } catch { + json = text; + } + } + + if (!expectedStatuses.includes(response.status)) { + const body = redactForError(json, config); + throw new NorthflankApiError( + `Northflank API ${context} failed (${response.status}): ${body}`, + response.status, + body, + response.headers.get('x-request-id'), + rateLimitFromHeaders(response.headers) + ); + } + + try { + return schema.parse(json); + } catch (err) { + const body = redactForError({ response: json, parseError: err }, config); + throw new NorthflankApiError( + `Northflank API ${context} returned an unexpected response: ${body}`, + 502, + body, + response.headers.get('x-request-id'), + rateLimitFromHeaders(response.headers) + ); + } +} + +async function requestVoid( + config: NorthflankClientConfig, + path: string, + init: RequestInit | undefined, + expectedStatuses: number[], + context: string, + options?: { teamScoped?: boolean } +): Promise { + await requestJson(config, path, init, z.unknown(), expectedStatuses, context, options); +} + +function jsonInit(method: string, body: unknown): RequestInit { + return { method, body: JSON.stringify(body) }; +} + +export async function createProject( + config: NorthflankClientConfig, + input: { name: string; region: string; description?: string } +): Promise { + const response = await requestJson( + config, + '/projects', + jsonInit('POST', input), + ProjectResponseSchema, + [200, 201], + 'createProject' + ); + return response.data; +} + +export async function findProjectByName( + config: NorthflankClientConfig, + name: string +): Promise { + const response = await requestJson( + config, + '/projects', + undefined, + ProjectListResponseSchema, + [200], + 'findProjectByName' + ); + return response.data.projects.find(project => project.name === name) ?? null; +} + +export async function getProject( + config: NorthflankClientConfig, + projectId: string +): Promise { + const response = await requestJson( + config, + `/projects/${encodeURIComponent(projectId)}`, + undefined, + ProjectResponseSchema, + [200], + 'getProject' + ); + return response.data; +} + +export async function deleteProject( + config: NorthflankClientConfig, + projectId: string, + deleteChildObjects = false +): Promise { + await requestVoid( + config, + pathWithQuery(`/projects/${encodeURIComponent(projectId)}`, { + delete_child_objects: deleteChildObjects, + }), + { method: 'DELETE' }, + [200, 202, 204], + 'deleteProject' + ); +} + +export async function createVolume( + config: NorthflankClientConfig, + projectId: string, + input: { + name: string; + mountPath: '/root'; + storageSizeMb: number; + storageClassName: string; + accessMode: string; + } +): Promise { + const response = await requestJson( + config, + `/projects/${encodeURIComponent(projectId)}/volumes`, + jsonInit('POST', { + name: input.name, + mounts: [{ containerMountPath: input.mountPath }], + spec: { + accessMode: input.accessMode === 'ReadWriteOnce' ? 'ReadWriteOnce' : 'ReadWriteMany', + storageClassName: input.storageClassName, + storageSize: input.storageSizeMb, + }, + }), + VolumeResponseSchema, + [200, 201], + 'createVolume' + ); + return response.data; +} + +export async function listVolumes( + config: NorthflankClientConfig, + projectId: string +): Promise { + const response = await requestJson( + config, + `/projects/${encodeURIComponent(projectId)}/volumes`, + undefined, + VolumeListResponseSchema, + [200], + 'listVolumes' + ); + return response.data; +} + +export async function findVolumeByName( + config: NorthflankClientConfig, + projectId: string, + name: string +): Promise { + const volumes = await listVolumes(config, projectId); + return volumes.find(volume => volume.name === name) ?? null; +} + +export async function getVolume( + config: NorthflankClientConfig, + projectId: string, + volumeIdOrName: string +): Promise { + const response = await requestJson( + config, + `/projects/${encodeURIComponent(projectId)}/volumes/${encodeURIComponent(volumeIdOrName)}`, + undefined, + VolumeResponseSchema, + [200], + 'getVolume' + ); + return response.data; +} + +export async function deleteVolume( + config: NorthflankClientConfig, + projectId: string, + volumeIdOrName: string +): Promise { + await requestVoid( + config, + `/projects/${encodeURIComponent(projectId)}/volumes/${encodeURIComponent(volumeIdOrName)}`, + { method: 'DELETE' }, + [200, 202, 204], + 'deleteVolume' + ); +} + +export async function createDeploymentService( + config: NorthflankClientConfig, + projectId: string, + payload: CreateServiceDeploymentRequest['data'] +): Promise { + const response = await requestJson( + config, + `/projects/${encodeURIComponent(projectId)}/services/deployment`, + jsonInit('POST', payload), + ServiceResponseSchema, + [200, 201], + 'createDeploymentService' + ); + return response.data; +} + +export async function patchDeploymentService( + config: NorthflankClientConfig, + projectId: string, + serviceId: string, + payload: PatchServiceDeploymentRequest['data'] +): Promise { + const response = await requestJson( + config, + `/projects/${encodeURIComponent(projectId)}/services/deployment/${encodeURIComponent(serviceId)}`, + jsonInit('PATCH', payload), + ServiceResponseSchema, + [200], + 'patchDeploymentService' + ); + return response.data; +} + +export async function scaleService( + config: NorthflankClientConfig, + projectId: string, + serviceId: string, + instances: number +): Promise { + await requestVoid( + config, + `/projects/${encodeURIComponent(projectId)}/services/${encodeURIComponent(serviceId)}/scale`, + jsonInit('POST', { instances }), + [200, 202, 204], + 'scaleService' + ); +} + +export async function listServices( + config: NorthflankClientConfig, + projectId: string +): Promise<{ services: NorthflankService[]; hasNextPage: boolean }> { + const response = await requestJson( + config, + `/projects/${encodeURIComponent(projectId)}/services`, + undefined, + ServiceListResponseSchema, + [200], + 'listServices' + ); + return { services: response.data.services, hasNextPage: false }; +} + +export async function findServiceByName( + config: NorthflankClientConfig, + projectId: string, + name: string +): Promise { + const result = await listServices(config, projectId); + return result.services.find(service => service.name === name) ?? null; +} + +export async function getService( + config: NorthflankClientConfig, + projectId: string, + serviceId: string +): Promise { + const response = await requestJson( + config, + `/projects/${encodeURIComponent(projectId)}/services/${encodeURIComponent(serviceId)}`, + undefined, + ServiceResponseSchema, + [200], + 'getService' + ); + return response.data; +} + +export async function deleteService( + config: NorthflankClientConfig, + projectId: string, + serviceId: string, + deleteChildObjects = false +): Promise { + await requestVoid( + config, + pathWithQuery( + `/projects/${encodeURIComponent(projectId)}/services/${encodeURIComponent(serviceId)}`, + { + delete_child_objects: deleteChildObjects, + } + ), + { method: 'DELETE' }, + [200, 202, 204], + 'deleteService' + ); +} + +export async function waitForDeploymentCompleted( + config: NorthflankClientConfig, + projectId: string, + serviceId: string, + timeoutSeconds: number +): Promise { + const deadline = Date.now() + timeoutSeconds * 1000; + let lastService = await getService(config, projectId, serviceId); + while (Date.now() < deadline) { + const deploymentStatus = lastService.status?.deployment?.status; + if (deploymentStatus === 'COMPLETED') return lastService; + if (deploymentStatus === 'FAILED') + throw new Error(`Northflank deployment failed for service ${serviceId}`); + await new Promise(resolve => setTimeout(resolve, 2_000)); + lastService = await getService(config, projectId, serviceId); + } + throw new Error(`Timed out waiting for Northflank deployment ${serviceId} to complete`); +} + +export async function createProjectSecret( + config: NorthflankClientConfig, + projectId: string, + payload: CreateSecretRequest['data'] +): Promise { + const response = await requestJson( + config, + `/projects/${encodeURIComponent(projectId)}/secrets`, + jsonInit('POST', payload), + SecretDetailsResponseSchema, + [200, 201], + 'createProjectSecret', + { teamScoped: false } + ); + return response.data; +} + +export async function findProjectSecretByName( + config: NorthflankClientConfig, + projectId: string, + name: string +): Promise { + const response = await requestJson( + config, + `/projects/${encodeURIComponent(projectId)}/secrets`, + undefined, + SecretListResponseSchema, + [200], + 'findProjectSecretByName', + { teamScoped: false } + ); + return response.data.secrets.find(secret => secret.name === name) ?? null; +} + +export async function getProjectSecretDetails( + config: NorthflankClientConfig, + projectId: string, + secretId: string +): Promise { + const response = await requestJson( + config, + `/projects/${encodeURIComponent(projectId)}/secrets/${encodeURIComponent(secretId)}/details`, + undefined, + SecretDetailsResponseSchema, + [200], + 'getProjectSecretDetails', + { teamScoped: false } + ); + return response.data; +} + +export async function putProjectSecret( + config: NorthflankClientConfig, + projectId: string, + secretId: string, + payload: CreateSecretRequest['data'] +): Promise { + const { name: _name, ...patchPayload } = payload satisfies CreateSecretRequest['data']; + const response = await requestJson( + config, + `/projects/${encodeURIComponent(projectId)}/secrets/${encodeURIComponent(secretId)}`, + jsonInit('PATCH', patchPayload satisfies PatchSecretRequest['data']), + SecretDetailsResponseSchema, + [200], + 'putProjectSecret', + { teamScoped: false } + ); + return response.data; +} + +export async function deleteProjectSecret( + config: NorthflankClientConfig, + projectId: string, + secretId: string +): Promise { + await requestVoid( + config, + `/projects/${encodeURIComponent(projectId)}/secrets/${encodeURIComponent(secretId)}`, + { method: 'DELETE' }, + [200, 202, 204], + 'deleteProjectSecret', + { teamScoped: false } + ); +} + +export function isNorthflankNotFound(err: unknown): boolean { + return err instanceof NorthflankApiError && err.status === 404; +} + +export function isNorthflankConflict(err: unknown): boolean { + return err instanceof NorthflankApiError && err.status === 409; +} diff --git a/services/kiloclaw/src/northflank/config.test.ts b/services/kiloclaw/src/northflank/config.test.ts new file mode 100644 index 000000000..6cacaa513 --- /dev/null +++ b/services/kiloclaw/src/northflank/config.test.ts @@ -0,0 +1,72 @@ +import { describe, expect, it } from 'vitest'; +import { getNorthflankConfig, NORTHFLANK_API_BASE } from './config'; + +const baseEnv = { + NF_API_TOKEN: 'nf-token', + NF_REGION: 'us-central', + NF_DEPLOYMENT_PLAN: 'nf-compute-200', + NF_EDGE_HEADER_NAME: 'x-kiloclaw-edge', + NF_EDGE_HEADER_VALUE: 'edge-secret', +}; + +describe('getNorthflankConfig', () => { + it('reads required Northflank env and applies defaults', () => { + expect(getNorthflankConfig(baseEnv as never)).toEqual({ + apiToken: 'nf-token', + apiBase: NORTHFLANK_API_BASE, + teamId: null, + region: 'us-central', + deploymentPlan: 'nf-compute-200', + storageClassName: 'nf-multi-rw', + storageAccessMode: 'ReadWriteMany', + volumeSizeMb: 10240, + ephemeralStorageMb: 2048, + edgeHeaderName: 'x-kiloclaw-edge', + edgeHeaderValue: 'edge-secret', + imagePathTemplate: null, + imageCredentialsId: null, + }); + }); + + it('accepts optional Northflank overrides', () => { + expect( + getNorthflankConfig({ + ...baseEnv, + NF_API_BASE: 'https://northflank.test/v1', + NF_TEAM_ID: 'team-1', + NF_STORAGE_CLASS_NAME: 'nf-ssd-rwo', + NF_STORAGE_ACCESS_MODE: 'ReadWriteOnce', + NF_VOLUME_SIZE_MB: '20480', + NF_EPHEMERAL_STORAGE_MB: '4096', + NF_IMAGE_PATH_TEMPLATE: 'ghcr.io/kilo-org/kiloclaw:{tag}', + NF_IMAGE_CREDENTIALS_ID: 'credential-1', + } as never) + ).toEqual({ + apiToken: 'nf-token', + apiBase: 'https://northflank.test/v1', + teamId: 'team-1', + region: 'us-central', + deploymentPlan: 'nf-compute-200', + storageClassName: 'nf-ssd-rwo', + storageAccessMode: 'ReadWriteOnce', + volumeSizeMb: 20480, + ephemeralStorageMb: 4096, + edgeHeaderName: 'x-kiloclaw-edge', + edgeHeaderValue: 'edge-secret', + imagePathTemplate: 'ghcr.io/kilo-org/kiloclaw:{tag}', + imageCredentialsId: 'credential-1', + }); + }); + + it('rejects missing required Northflank env', () => { + expect(() => getNorthflankConfig({ ...baseEnv, NF_API_TOKEN: '' } as never)).toThrow( + 'NF_API_TOKEN is not configured' + ); + }); + + it('rejects invalid numeric overrides', () => { + expect(() => getNorthflankConfig({ ...baseEnv, NF_VOLUME_SIZE_MB: 'ten' } as never)).toThrow( + 'NF_VOLUME_SIZE_MB must be a positive integer' + ); + }); +}); diff --git a/services/kiloclaw/src/northflank/config.ts b/services/kiloclaw/src/northflank/config.ts new file mode 100644 index 000000000..d12fe93b2 --- /dev/null +++ b/services/kiloclaw/src/northflank/config.ts @@ -0,0 +1,66 @@ +import type { KiloClawEnv } from '../types'; + +export const NORTHFLANK_API_BASE = 'https://api.northflank.com/v1'; + +export type NorthflankConfig = { + apiToken: string; + apiBase: string; + teamId: string | null; + region: string; + deploymentPlan: string; + storageClassName: string; + storageAccessMode: string; + volumeSizeMb: number; + ephemeralStorageMb: number; + edgeHeaderName: string; + edgeHeaderValue: string; + imagePathTemplate: string | null; + imageCredentialsId: string | null; +}; + +function requiredEnv(env: KiloClawEnv, key: keyof KiloClawEnv): string { + const value = env[key]; + if (typeof value !== 'string' || value.trim() === '') { + throw new Error(`${String(key)} is not configured`); + } + return value; +} + +function optionalEnv(env: KiloClawEnv, key: keyof KiloClawEnv): string | null { + const value = env[key]; + if (typeof value !== 'string') return null; + const trimmed = value.trim(); + return trimmed === '' ? null : trimmed; +} + +function positiveIntegerEnv( + env: KiloClawEnv, + key: keyof KiloClawEnv, + defaultValue: number +): number { + const value = optionalEnv(env, key); + if (!value) return defaultValue; + const parsed = Number(value); + if (!Number.isInteger(parsed) || parsed <= 0) { + throw new Error(`${String(key)} must be a positive integer`); + } + return parsed; +} + +export function getNorthflankConfig(env: KiloClawEnv): NorthflankConfig { + return { + apiToken: requiredEnv(env, 'NF_API_TOKEN'), + apiBase: optionalEnv(env, 'NF_API_BASE') ?? NORTHFLANK_API_BASE, + teamId: optionalEnv(env, 'NF_TEAM_ID'), + region: requiredEnv(env, 'NF_REGION'), + deploymentPlan: requiredEnv(env, 'NF_DEPLOYMENT_PLAN'), + storageClassName: optionalEnv(env, 'NF_STORAGE_CLASS_NAME') ?? 'nf-multi-rw', + storageAccessMode: optionalEnv(env, 'NF_STORAGE_ACCESS_MODE') ?? 'ReadWriteMany', + volumeSizeMb: positiveIntegerEnv(env, 'NF_VOLUME_SIZE_MB', 10240), + ephemeralStorageMb: positiveIntegerEnv(env, 'NF_EPHEMERAL_STORAGE_MB', 2048), + edgeHeaderName: requiredEnv(env, 'NF_EDGE_HEADER_NAME'), + edgeHeaderValue: requiredEnv(env, 'NF_EDGE_HEADER_VALUE'), + imagePathTemplate: optionalEnv(env, 'NF_IMAGE_PATH_TEMPLATE'), + imageCredentialsId: optionalEnv(env, 'NF_IMAGE_CREDENTIALS_ID'), + }; +} diff --git a/services/kiloclaw/src/providers/index.test.ts b/services/kiloclaw/src/providers/index.test.ts index bd442cbee..b34cca507 100644 --- a/services/kiloclaw/src/providers/index.test.ts +++ b/services/kiloclaw/src/providers/index.test.ts @@ -32,4 +32,24 @@ describe('provider registry', () => { expect(adapter.id).toBe('docker-local'); }); + + it('rejects northflank when required configuration is missing', () => { + expect(() => assertAvailableProvider({} as never, 'northflank')).toThrow( + 'Provider northflank is not configured' + ); + }); + + it('returns the northflank adapter when configured', () => { + const env = { + NF_API_TOKEN: 'nf-token', + NF_REGION: 'us-central', + NF_DEPLOYMENT_PLAN: 'nf-compute-200', + NF_EDGE_HEADER_NAME: 'x-kiloclaw-edge', + NF_EDGE_HEADER_VALUE: 'edge-secret', + NF_IMAGE_PATH_TEMPLATE: 'ghcr.io/kilo-org/kiloclaw:{tag}', + } as never; + + expect(() => assertAvailableProvider(env, 'northflank')).not.toThrow(); + expect(getProviderAdapter(env, { provider: 'northflank' }).id).toBe('northflank'); + }); }); diff --git a/services/kiloclaw/src/providers/index.ts b/services/kiloclaw/src/providers/index.ts index 957251cfc..15e63fe76 100644 --- a/services/kiloclaw/src/providers/index.ts +++ b/services/kiloclaw/src/providers/index.ts @@ -4,22 +4,14 @@ import type { KiloClawEnv } from '../types'; import type { InstanceProviderAdapter } from './types'; import { flyProviderAdapter } from './fly'; import { dockerLocalProviderAdapter } from './docker-local'; - -function notImplementedProviderError( - provider: Exclude -): Error & { status: number } { - return Object.assign(new Error(`Provider ${provider} is not implemented yet`), { - status: 501, - }); -} +import { northflankProviderAdapter } from './northflank'; export function assertImplementedProvider(provider: ProviderId): void { switch (provider) { case 'fly': case 'docker-local': - return; case 'northflank': - throw notImplementedProviderError(provider); + return; } } @@ -36,6 +28,23 @@ export function assertAvailableProvider(env: KiloClawEnv, provider: ProviderId): if (provider === 'docker-local' && !isDevelopmentWorker(env)) { throw invalidProviderConfiguration('Provider docker-local is only available in development'); } + if (provider === 'northflank') { + const requiredNorthflankKeys = [ + 'NF_API_TOKEN', + 'NF_REGION', + 'NF_DEPLOYMENT_PLAN', + 'NF_EDGE_HEADER_NAME', + 'NF_EDGE_HEADER_VALUE', + 'NF_IMAGE_PATH_TEMPLATE', + ] satisfies Array; + const missing = requiredNorthflankKeys.filter(key => !env[key]); + if (missing.length > 0) { + throw invalidProviderConfiguration( + `Provider northflank is not configured; missing ${missing.join(', ')}`, + 503 + ); + } + } } export function resolveDefaultProvider( @@ -56,6 +65,6 @@ export function getProviderAdapter( case 'docker-local': return dockerLocalProviderAdapter; case 'northflank': - throw notImplementedProviderError(state.provider); + return northflankProviderAdapter; } } diff --git a/services/kiloclaw/src/providers/northflank/index.test.ts b/services/kiloclaw/src/providers/northflank/index.test.ts new file mode 100644 index 000000000..3f00e0bed --- /dev/null +++ b/services/kiloclaw/src/providers/northflank/index.test.ts @@ -0,0 +1,234 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { northflankProviderAdapter } from './index'; +import type { RuntimeSpec } from '../types'; +import { + createDeploymentService, + createProject, + createProjectSecret, + createVolume, + findProjectByName, + findServiceByName, + findVolumeByName, + getProject, + getService, + getVolume, + patchDeploymentService, + scaleService, + waitForDeploymentCompleted, +} from '../../northflank/client'; + +vi.mock('../../northflank/client', () => ({ + createDeploymentService: vi.fn(), + createProject: vi.fn(), + createProjectSecret: vi.fn(), + createVolume: vi.fn(), + deleteProject: vi.fn(), + deleteProjectSecret: vi.fn(), + deleteService: vi.fn(), + deleteVolume: vi.fn(), + findProjectByName: vi.fn(), + findProjectSecretByName: vi.fn(), + findServiceByName: vi.fn(), + findVolumeByName: vi.fn(), + getProject: vi.fn(), + getService: vi.fn(), + getVolume: vi.fn(), + isNorthflankConflict: vi.fn(() => false), + isNorthflankNotFound: vi.fn(() => false), + patchDeploymentService: vi.fn(), + putProjectSecret: vi.fn(), + scaleService: vi.fn(), + waitForDeploymentCompleted: vi.fn(), +})); + +const env = { + NF_API_TOKEN: 'nf-token', + NF_API_BASE: 'https://api.northflank.com/v1', + NF_REGION: 'us-central', + NF_DEPLOYMENT_PLAN: 'nf-compute-200', + NF_STORAGE_CLASS_NAME: 'nf-multi-rw', + NF_STORAGE_ACCESS_MODE: 'ReadWriteMany', + NF_VOLUME_SIZE_MB: '10240', + NF_EPHEMERAL_STORAGE_MB: '2048', + NF_EDGE_HEADER_NAME: 'x-kiloclaw-edge', + NF_EDGE_HEADER_VALUE: 'edge-secret', + NF_IMAGE_PATH_TEMPLATE: 'ghcr.io/kilo-org/kiloclaw:{tag}', +}; + +const runtimeSpec = { + imageRef: 'ghcr.io/kilo-org/kiloclaw:test', + env: { KILOCLAW_ENC_KILOCODE_API_KEY: 'enc:v1:value' }, + bootstrapEnv: { KILOCLAW_ENV_KEY: 'env-key' }, + machineSize: null, + rootMountPath: '/root', + controllerPort: 18789, + controllerHealthCheckPath: '/_kilo/health', + metadata: { kiloclaw_user_id: 'user-1', kiloclaw_sandbox_id: 'ki_123' }, +} satisfies RuntimeSpec; + +beforeEach(() => { + vi.clearAllMocks(); +}); + +describe('northflankProviderAdapter', () => { + it('returns routing target with configured trusted edge header', async () => { + const target = await northflankProviderAdapter.getRoutingTarget({ + env: env as never, + state: { + providerState: { + provider: 'northflank', + projectId: 'project-1', + projectName: 'kc-ki-123', + serviceId: 'service-1', + serviceName: 'kc-ki-123', + volumeId: 'volume-1', + volumeName: 'kc-ki-123', + secretId: 'secret-1', + secretName: 'kc-ki-123', + ingressHost: 'kc-ki-123.code.run', + region: 'us-central', + }, + } as never, + }); + + expect(target).toEqual({ + origin: 'https://kc-ki-123.code.run', + headers: { 'x-kiloclaw-edge': 'edge-secret' }, + }); + }); + + it('creates project and root volume during provisioning', async () => { + vi.mocked(findProjectByName).mockResolvedValue(null); + vi.mocked(createProject).mockResolvedValue({ id: 'project-1', name: 'kc-ki-123' }); + vi.mocked(findVolumeByName).mockResolvedValue(null); + vi.mocked(createVolume).mockResolvedValue({ id: 'volume-1', name: 'kc-ki-123' }); + + const result = await northflankProviderAdapter.ensureProvisioningResources({ + env: env as never, + state: { sandboxId: 'ki_123', providerState: null, status: null } as never, + orgId: null, + machineSize: null, + }); + + expect(createProject).toHaveBeenCalledWith( + expect.objectContaining({ apiToken: 'nf-token' }), + expect.objectContaining({ name: 'kc-ki-123', region: 'us-central' }) + ); + expect(createVolume).toHaveBeenCalledWith( + expect.objectContaining({ apiToken: 'nf-token' }), + 'project-1', + expect.objectContaining({ mountPath: '/root', storageSizeMb: 10240 }) + ); + expect(result.providerState).toEqual( + expect.objectContaining({ + provider: 'northflank', + projectId: 'project-1', + volumeId: 'volume-1', + region: 'us-central', + }) + ); + }); + + it('creates service at zero instances, writes restricted secret, then scales up', async () => { + vi.mocked(findServiceByName).mockResolvedValue(null); + vi.mocked(createDeploymentService).mockResolvedValue({ + id: 'service-1', + name: 'kc-ki-123', + ports: [{ name: 'p01', dns: 'kc-ki-123.code.run' }], + }); + vi.mocked(createProjectSecret).mockResolvedValue({ id: 'secret-1', name: 'kc-ki-123' }); + vi.mocked(patchDeploymentService).mockResolvedValue({ id: 'service-1', name: 'kc-ki-123' }); + vi.mocked(scaleService).mockResolvedValue(undefined); + vi.mocked(waitForDeploymentCompleted).mockResolvedValue({ + id: 'service-1', + name: 'kc-ki-123', + ports: [{ name: 'p01', dns: 'kc-ki-123.code.run' }], + }); + const onProviderResult = vi.fn(); + + const result = await northflankProviderAdapter.startRuntime({ + env: env as never, + state: { + sandboxId: 'ki_123', + providerState: { + provider: 'northflank', + projectId: 'project-1', + projectName: 'kc-ki-123', + serviceId: null, + serviceName: null, + volumeId: 'volume-1', + volumeName: 'kc-ki-123', + secretId: null, + secretName: null, + ingressHost: null, + region: 'us-central', + }, + } as never, + runtimeSpec, + onProviderResult, + }); + + const servicePayload = vi.mocked(createDeploymentService).mock.calls[0]?.[2]; + expect(servicePayload?.deployment.instances).toBe(0); + expect(servicePayload?.deployment.docker).toEqual({ configType: 'default' }); + expect(servicePayload?.createOptions?.volumesToAttach).toEqual(['kc-ki-123']); + expect(servicePayload?.runtimeEnvironment).toEqual(runtimeSpec.env); + expect(createProjectSecret).toHaveBeenCalledWith( + expect.objectContaining({ apiToken: 'nf-token' }), + 'project-1', + expect.objectContaining({ + restrictions: { restricted: true, nfObjects: [{ id: 'service-1', type: 'service' }] }, + secrets: { variables: runtimeSpec.bootstrapEnv }, + }) + ); + expect(scaleService).toHaveBeenCalledWith( + expect.objectContaining({ apiToken: 'nf-token' }), + 'project-1', + 'service-1', + 1 + ); + expect(result.providerState).toEqual( + expect.objectContaining({ + serviceId: 'service-1', + secretId: 'secret-1', + ingressHost: 'kc-ki-123.code.run', + }) + ); + expect(onProviderResult).toHaveBeenCalledTimes(2); + }); + + it('maps missing service IDs to missing runtime observation', async () => { + const result = await northflankProviderAdapter.inspectRuntime({ + env: env as never, + state: { providerState: { provider: 'northflank' } } as never, + }); + + expect(getService).not.toHaveBeenCalled(); + expect(result.observation?.runtimeState).toBe('missing'); + }); + + it('verifies persisted volumes without recreating active missing storage', async () => { + vi.mocked(getProject).mockResolvedValue({ id: 'project-1', name: 'kc-ki-123' }); + vi.mocked(findProjectByName).mockResolvedValue({ id: 'project-1', name: 'kc-ki-123' }); + vi.mocked(findVolumeByName).mockResolvedValue(null); + vi.mocked(getVolume).mockResolvedValue({ id: 'volume-1', name: 'kc-ki-123' }); + + await expect( + northflankProviderAdapter.ensureStorage({ + env: env as never, + state: { + sandboxId: 'ki_123', + status: 'running', + providerState: { + provider: 'northflank', + projectId: 'project-1', + projectName: 'kc-ki-123', + volumeId: 'volume-1', + volumeName: 'kc-ki-123', + }, + } as never, + reason: 'test', + }) + ).rejects.toThrow('Northflank volume is missing for an active instance'); + }); +}); diff --git a/services/kiloclaw/src/providers/northflank/index.ts b/services/kiloclaw/src/providers/northflank/index.ts new file mode 100644 index 000000000..b770bb9ad --- /dev/null +++ b/services/kiloclaw/src/providers/northflank/index.ts @@ -0,0 +1,642 @@ +import type { CreateSecretRequest, CreateServiceDeploymentRequest } from '@northflank/js-client'; +import type { NorthflankProviderState } from '../../schemas/instance-config'; +import { STARTUP_TIMEOUT_SECONDS } from '../../config'; +import { getNorthflankProviderState } from '../../durable-objects/kiloclaw-instance/state'; +import type { RuntimeSpec, InstanceProviderAdapter } from '../types'; +import { getNorthflankConfig } from '../../northflank/config'; +import { + createDeploymentService, + createProject, + createProjectSecret, + createVolume, + deleteProject, + deleteProjectSecret, + deleteService, + deleteVolume, + findProjectByName, + findProjectSecretByName, + findServiceByName, + findVolumeByName, + getProject, + getService, + getVolume, + isNorthflankConflict, + isNorthflankNotFound, + patchDeploymentService, + putProjectSecret, + scaleService, + waitForDeploymentCompleted, + type NorthflankClientConfig, + type NorthflankProject, + type NorthflankService, + type NorthflankVolume, +} from '../../northflank/client'; +import { northflankResourceNames } from './names'; + +const NORTHFLANK_PORT_NAME = 'p01'; + +type NorthflankProvisioningNames = Awaited>; + +function requireSandboxId(state: { sandboxId: string | null }): string { + if (!state.sandboxId) { + throw new Error('Provider northflank requires a sandboxId'); + } + return state.sandboxId; +} + +function northflankClientConfig( + env: Parameters[0] +): NorthflankClientConfig { + return getNorthflankConfig(env); +} + +async function getProvisioningNames(state: { + sandboxId: string | null; +}): Promise { + return northflankResourceNames(requireSandboxId(state)); +} + +async function ensureProject( + config: NorthflankClientConfig, + providerState: NorthflankProviderState, + names: NorthflankProvisioningNames, + region: string +): Promise { + if (providerState.projectId) { + try { + return await getProject(config, providerState.projectId); + } catch (err) { + if (!isNorthflankNotFound(err)) throw err; + } + } + + const existing = await findProjectByName(config, providerState.projectName ?? names.projectName); + if (existing) return existing; + + try { + return await createProject(config, { + name: names.projectName, + region, + description: 'KiloClaw Northflank sandbox project', + }); + } catch (err) { + if (!isNorthflankConflict(err)) throw err; + const recovered = await findProjectByName(config, names.projectName); + if (recovered) return recovered; + throw err; + } +} + +async function ensureVolumeResource( + config: NorthflankClientConfig, + projectId: string, + providerState: NorthflankProviderState, + names: NorthflankProvisioningNames, + options: { + storageSizeMb: number; + storageClassName: string; + accessMode: string; + } +): Promise { + if (providerState.volumeId) { + try { + return await getVolume(config, projectId, providerState.volumeId); + } catch (err) { + if (!isNorthflankNotFound(err)) throw err; + } + } + + const existing = await findVolumeByName( + config, + projectId, + providerState.volumeName ?? names.volumeName + ); + if (existing) return existing; + + try { + return await createVolume(config, projectId, { + name: names.volumeName, + mountPath: '/root', + storageSizeMb: options.storageSizeMb, + storageClassName: options.storageClassName, + accessMode: options.accessMode, + }); + } catch (err) { + if (!isNorthflankConflict(err)) throw err; + const recovered = await findVolumeByName(config, projectId, names.volumeName); + if (recovered) return recovered; + throw err; + } +} + +function mergeProviderState( + providerState: NorthflankProviderState, + names: NorthflankProvisioningNames, + project: NorthflankProject, + volume: NorthflankVolume, + region: string +): NorthflankProviderState { + return { + ...providerState, + projectId: project.id, + projectName: project.name || names.projectName, + volumeId: volume.id, + volumeName: volume.name || names.volumeName, + region, + }; +} + +function firstIngressHost(service: NorthflankService): string | null { + return service.ports?.find(port => port.dns)?.dns ?? null; +} + +function northflankOrigin(host: string): string { + return host.startsWith('http://') || host.startsWith('https://') ? host : `https://${host}`; +} + +function buildPortSecurity(config: NorthflankClientConfig) { + const nfConfig = config; + return { + verificationMode: 'and' as const, + securePathConfiguration: { + enabled: true, + skipSecurityPoliciesForInternalTrafficViaPublicDns: false, + rules: [ + { + paths: [], + accessMode: 'protected' as const, + securityPolicies: { + requiredPolicies: { + headers: [ + { + name: nfConfig.edgeHeaderName, + value: nfConfig.edgeHeaderValue, + regexMode: false, + }, + ], + }, + }, + }, + ], + }, + }; +} + +function deploymentImage(config: NorthflankClientConfig, imageRef: string) { + return config.imageCredentialsId + ? { imagePath: imageRef, credentials: config.imageCredentialsId } + : { imagePath: imageRef }; +} + +function buildServicePayload( + config: NorthflankClientConfig, + runtimeSpec: RuntimeSpec, + serviceName: string, + volumeName: string, + instances: number +): CreateServiceDeploymentRequest['data'] { + return { + name: serviceName, + billing: { + deploymentPlan: config.deploymentPlan, + }, + deployment: { + instances, + external: deploymentImage(config, runtimeSpec.imageRef), + docker: { + configType: 'default', + }, + storage: { + ephemeralStorage: { + storageSize: config.ephemeralStorageMb, + }, + }, + strategy: { + type: 'recreate', + }, + }, + ports: [ + { + name: NORTHFLANK_PORT_NAME, + internalPort: runtimeSpec.controllerPort, + protocol: 'HTTP', + public: true, + security: buildPortSecurity(config), + }, + ], + createOptions: { + volumesToAttach: [volumeName], + }, + runtimeEnvironment: runtimeSpec.env, + healthChecks: [ + { + protocol: 'HTTP', + type: 'readinessProbe', + path: runtimeSpec.controllerHealthCheckPath, + port: runtimeSpec.controllerPort, + initialDelaySeconds: 10, + periodSeconds: 30, + timeoutSeconds: 5, + failureThreshold: 10, + successThreshold: 1, + }, + ], + }; +} + +function buildSecretPayload( + serviceId: string, + secretName: string, + bootstrapEnv: Record +): CreateSecretRequest['data'] { + return { + name: secretName, + type: 'secret', + secretType: 'environment', + priority: 100, + restrictions: { + restricted: true, + nfObjects: [{ id: serviceId, type: 'service' }], + }, + secrets: { + variables: bootstrapEnv, + }, + }; +} + +async function ensureSecret( + config: NorthflankClientConfig, + projectId: string, + serviceId: string, + providerState: NorthflankProviderState, + names: NorthflankProvisioningNames, + runtimeSpec: RuntimeSpec +) { + const payload = buildSecretPayload(serviceId, names.secretName, runtimeSpec.bootstrapEnv); + + if (providerState.secretId) { + try { + const secret = await putProjectSecret(config, projectId, providerState.secretId, payload); + return secret; + } catch (err) { + if (!isNorthflankNotFound(err)) throw err; + } + } + + try { + return await createProjectSecret(config, projectId, payload); + } catch (err) { + if (!isNorthflankConflict(err)) throw err; + const recovered = await findProjectSecretByName(config, projectId, names.secretName); + if (recovered) { + return await putProjectSecret(config, projectId, recovered.id, payload); + } + throw err; + } +} + +function mapRuntimeState( + service: NorthflankService +): 'starting' | 'running' | 'stopped' | 'failed' { + if (service.servicePaused) return 'stopped'; + const instances = service.deployment?.instances; + if (instances === 0) return 'stopped'; + + const deploymentStatus = service.status?.deployment?.status; + if (deploymentStatus === 'FAILED') return 'failed'; + if (deploymentStatus === 'PENDING' || deploymentStatus === 'IN_PROGRESS') return 'starting'; + if (deploymentStatus === 'COMPLETED') + return instances === undefined || instances > 0 ? 'running' : 'stopped'; + return instances && instances > 0 ? 'starting' : 'stopped'; +} + +export const northflankProviderAdapter: InstanceProviderAdapter = { + id: 'northflank', + capabilities: { + volumeSnapshots: false, + candidateVolumes: false, + volumeReassociation: false, + snapshotRestore: false, + directMachineDestroy: false, + }, + + async getRoutingTarget({ env, state }) { + const config = northflankClientConfig(env); + const providerState = getNorthflankProviderState(state); + const ingressHost = providerState.ingressHost; + if (!ingressHost) { + throw new Error('No Northflank ingress host for this instance'); + } + + return { + origin: northflankOrigin(ingressHost), + headers: { + [config.edgeHeaderName]: config.edgeHeaderValue, + }, + }; + }, + + async ensureProvisioningResources({ env, state, region }) { + const config = northflankClientConfig(env); + const names = await getProvisioningNames(state); + const providerState = getNorthflankProviderState(state); + const targetRegion = region ?? providerState.region ?? config.region; + const project = await ensureProject(config, providerState, names, targetRegion); + const volume = await ensureVolumeResource(config, project.id, providerState, names, { + storageSizeMb: config.volumeSizeMb, + storageClassName: config.storageClassName, + accessMode: config.storageAccessMode, + }); + + return { + providerState: mergeProviderState(providerState, names, project, volume, targetRegion), + }; + }, + + async ensureStorage({ env, state }) { + const config = northflankClientConfig(env); + const names = await getProvisioningNames(state); + let providerState = getNorthflankProviderState(state); + const targetRegion = providerState.region ?? config.region; + const project = await ensureProject(config, providerState, names, targetRegion); + providerState = { ...providerState, projectId: project.id, projectName: project.name }; + + const existingVolume = await findVolumeByName( + config, + project.id, + providerState.volumeName ?? names.volumeName + ); + if ( + !existingVolume && + (state.status === 'running' || state.status === 'starting' || state.status === 'restarting') + ) { + throw new Error('Northflank volume is missing for an active instance'); + } + + const volume = + existingVolume ?? + (await ensureVolumeResource(config, project.id, providerState, names, { + storageSizeMb: config.volumeSizeMb, + storageClassName: config.storageClassName, + accessMode: config.storageAccessMode, + })); + + return { + providerState: mergeProviderState(providerState, names, project, volume, targetRegion), + }; + }, + + async startRuntime({ env, state, runtimeSpec, onProviderResult }) { + const config = northflankClientConfig(env); + const names = await getProvisioningNames(state); + let providerState = getNorthflankProviderState(state); + const projectId = providerState.projectId; + const volumeName = providerState.volumeName ?? names.volumeName; + if (!projectId || !providerState.volumeId) { + throw new Error('Northflank startRuntime requires project and volume provisioning first'); + } + + let service: NorthflankService; + if (providerState.serviceId) { + try { + service = await getService(config, projectId, providerState.serviceId); + } catch (err) { + if (!isNorthflankNotFound(err)) throw err; + const recovered = await findServiceByName(config, projectId, names.serviceName); + if (!recovered) throw err; + service = recovered; + } + } else { + const existing = await findServiceByName(config, projectId, names.serviceName); + service = + existing ?? + (await createDeploymentService( + config, + projectId, + buildServicePayload(config, runtimeSpec, names.serviceName, volumeName, 0) + )); + } + + providerState = { + ...providerState, + serviceId: service.id, + serviceName: service.name || names.serviceName, + ingressHost: firstIngressHost(service) ?? providerState.ingressHost, + }; + await onProviderResult?.({ providerState }); + + const secret = await ensureSecret( + config, + projectId, + service.id, + providerState, + names, + runtimeSpec + ); + providerState = { + ...providerState, + secretId: secret.id, + secretName: secret.name || names.secretName, + }; + await onProviderResult?.({ providerState }); + + await patchDeploymentService( + config, + projectId, + service.id, + buildServicePayload(config, runtimeSpec, names.serviceName, volumeName, 0) + ); + await scaleService(config, projectId, service.id, 1); + const started = await waitForDeploymentCompleted( + config, + projectId, + service.id, + STARTUP_TIMEOUT_SECONDS + ); + + return { + providerState: { + ...providerState, + ingressHost: firstIngressHost(started) ?? providerState.ingressHost, + }, + observation: { + runtimeState: 'running', + }, + }; + }, + + async stopRuntime({ env, state }) { + const config = northflankClientConfig(env); + const providerState = getNorthflankProviderState(state); + if (!providerState.projectId || !providerState.serviceId) { + return { providerState }; + } + + await scaleService(config, providerState.projectId, providerState.serviceId, 0); + return { + providerState, + observation: { + runtimeState: 'stopped', + }, + }; + }, + + async restartRuntime({ env, state, runtimeSpec, onProviderResult }) { + const config = northflankClientConfig(env); + const names = await getProvisioningNames(state); + let providerState = getNorthflankProviderState(state); + if (!providerState.projectId || !providerState.serviceId) { + throw new Error('No Northflank service exists'); + } + const projectId = providerState.projectId; + const serviceId = providerState.serviceId; + + const volumeName = providerState.volumeName ?? names.volumeName; + await patchDeploymentService( + config, + projectId, + serviceId, + buildServicePayload( + config, + runtimeSpec, + providerState.serviceName ?? names.serviceName, + volumeName, + 0 + ) + ); + await onProviderResult?.({ providerState, corePatch: { restartUpdateSent: true } }); + + const secret = await ensureSecret( + config, + projectId, + serviceId, + providerState, + names, + runtimeSpec + ); + providerState = { + ...providerState, + secretId: secret.id, + secretName: secret.name || names.secretName, + }; + await onProviderResult?.({ providerState }); + + await scaleService(config, projectId, serviceId, 1); + const restarted = await waitForDeploymentCompleted( + config, + projectId, + serviceId, + STARTUP_TIMEOUT_SECONDS + ); + + return { + providerState: { + ...providerState, + ingressHost: firstIngressHost(restarted) ?? providerState.ingressHost, + }, + observation: { + runtimeState: 'running', + }, + }; + }, + + async inspectRuntime({ env, state }) { + const config = northflankClientConfig(env); + const providerState = getNorthflankProviderState(state); + if (!providerState.projectId || !providerState.serviceId) { + return { + providerState, + observation: { + runtimeState: 'missing', + }, + }; + } + + try { + const service = await getService(config, providerState.projectId, providerState.serviceId); + return { + providerState: { + ...providerState, + ingressHost: firstIngressHost(service) ?? providerState.ingressHost, + }, + observation: { + runtimeState: mapRuntimeState(service), + }, + }; + } catch (err) { + if (isNorthflankNotFound(err)) { + return { + providerState, + observation: { + runtimeState: 'missing', + }, + }; + } + throw err; + } + }, + + async destroyRuntime({ env, state }) { + const config = northflankClientConfig(env); + const providerState = getNorthflankProviderState(state); + if (!providerState.projectId) return { providerState }; + + if (providerState.serviceId) { + try { + await deleteService(config, providerState.projectId, providerState.serviceId, false); + } catch (err) { + if (!isNorthflankNotFound(err)) throw err; + } + } + + if (providerState.secretId) { + try { + await deleteProjectSecret(config, providerState.projectId, providerState.secretId); + } catch (err) { + if (!isNorthflankNotFound(err)) throw err; + } + } + + return { + providerState: { + ...providerState, + serviceId: null, + serviceName: null, + secretId: null, + secretName: null, + ingressHost: null, + }, + }; + }, + + async destroyStorage({ env, state }) { + const config = northflankClientConfig(env); + const providerState = getNorthflankProviderState(state); + if (!providerState.projectId) return { providerState }; + + if (providerState.volumeId) { + try { + await deleteVolume(config, providerState.projectId, providerState.volumeId); + } catch (err) { + if (!isNorthflankNotFound(err)) throw err; + } + } + + try { + await deleteProject(config, providerState.projectId, true); + } catch (err) { + if (!isNorthflankNotFound(err)) throw err; + } + + return { + providerState: { + ...providerState, + projectId: null, + projectName: null, + volumeId: null, + volumeName: null, + region: null, + }, + }; + }, +}; diff --git a/services/kiloclaw/src/providers/northflank/names.test.ts b/services/kiloclaw/src/providers/northflank/names.test.ts new file mode 100644 index 000000000..2c1bc8b9d --- /dev/null +++ b/services/kiloclaw/src/providers/northflank/names.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, it } from 'vitest'; +import { northflankNameFromKey, northflankResourceNames } from './names'; + +describe('Northflank naming helpers', () => { + it('keeps instance-keyed sandbox IDs readable and within strict resource limits', async () => { + const name = await northflankNameFromKey('ki_1234567890abcdef1234567890abcdef'); + + expect(name).toBe('kc-ki-1234567890abcdef1234567890abcdef'); + expect(name).toHaveLength(38); + expect(name).toMatch(/^[a-z][a-z0-9-]*[a-z0-9]$/); + }); + + it('sanitizes unsupported characters without changing valid deterministic input', async () => { + await expect(northflankNameFromKey('KI_test.VALUE')).resolves.toBe('kc-ki-test-value'); + }); + + it('uses a stable hash fallback for overlong keys', async () => { + const key = 'legacy-user-id-that-is-far-too-long-for-northflank-project-and-volume-names'; + const name = await northflankNameFromKey(key); + + expect(name).toBe(await northflankNameFromKey(key)); + expect(name).toMatch(/^kc-[0-9a-f]{24}$/); + expect(name.length).toBeLessThanOrEqual(39); + }); + + it('uses one strict name for project, service, volume, and secret recovery', async () => { + await expect(northflankResourceNames('ki_1234567890abcdef1234567890abcdef')).resolves.toEqual({ + projectName: 'kc-ki-1234567890abcdef1234567890abcdef', + serviceName: 'kc-ki-1234567890abcdef1234567890abcdef', + volumeName: 'kc-ki-1234567890abcdef1234567890abcdef', + secretName: 'kc-ki-1234567890abcdef1234567890abcdef', + }); + }); +}); diff --git a/services/kiloclaw/src/providers/northflank/names.ts b/services/kiloclaw/src/providers/northflank/names.ts new file mode 100644 index 000000000..e983b4053 --- /dev/null +++ b/services/kiloclaw/src/providers/northflank/names.ts @@ -0,0 +1,53 @@ +const NORTHFLANK_NAME_PREFIX = 'kc'; +const NORTHFLANK_STRICT_MAX_LENGTH = 39; + +async function hashHex(input: string, bytes: number): Promise { + const data = new TextEncoder().encode(input); + const hashBuffer = await crypto.subtle.digest('SHA-256', data); + return Array.from(new Uint8Array(hashBuffer).slice(0, bytes)) + .map(byte => byte.toString(16).padStart(2, '0')) + .join(''); +} + +function sanitizeNameFragment(input: string): string { + return input + .toLowerCase() + .replace(/_/g, '-') + .replace(/[^a-z0-9-]+/g, '-') + .replace(/-+/g, '-') + .replace(/^-|-$/g, ''); +} + +function isValidNorthflankName(name: string, maxLength: number): boolean { + return name.length <= maxLength && /^[a-z][a-z0-9-]*[a-z0-9]$/.test(name); +} + +export async function northflankNameFromKey( + key: string, + maxLength = NORTHFLANK_STRICT_MAX_LENGTH +): Promise { + const sanitized = sanitizeNameFragment(key); + const readableName = sanitized ? `${NORTHFLANK_NAME_PREFIX}-${sanitized}` : ''; + if (readableName && isValidNorthflankName(readableName, maxLength)) { + return readableName; + } + + return `${NORTHFLANK_NAME_PREFIX}-${await hashHex(key, 12)}`; +} + +export type NorthflankResourceNames = { + projectName: string; + serviceName: string; + volumeName: string; + secretName: string; +}; + +export async function northflankResourceNames(key: string): Promise { + const name = await northflankNameFromKey(key); + return { + projectName: name, + serviceName: name, + volumeName: name, + secretName: name, + }; +} diff --git a/services/kiloclaw/src/providers/rollout.test.ts b/services/kiloclaw/src/providers/rollout.test.ts index ef98ab3d9..39a95b2b6 100644 --- a/services/kiloclaw/src/providers/rollout.test.ts +++ b/services/kiloclaw/src/providers/rollout.test.ts @@ -48,7 +48,7 @@ describe('provider rollout config', () => { }); }); - it('selects fly while Northflank rollout is unavailable', async () => { + it('selects Northflank when rollout is enabled at 100 percent', async () => { const kv = createKv( JSON.stringify({ northflank: { @@ -59,14 +59,14 @@ describe('provider rollout config', () => { }) ); - await expect(selectProviderForProvision({ kv, userId: 'user-1' })).resolves.toBe('fly'); + await expect(selectProviderForProvision({ kv, userId: 'user-1' })).resolves.toBe('northflank'); await expect( selectProviderForProvision({ kv, userId: 'user-1', orgId: '550e8400-e29b-41d4-a716-446655440001', }) - ).resolves.toBe('fly'); + ).resolves.toBe('northflank'); }); it('does not select Northflank for orgs that are not opted in', async () => { diff --git a/services/kiloclaw/src/providers/rollout.ts b/services/kiloclaw/src/providers/rollout.ts index a75bb9ad4..23c69adab 100644 --- a/services/kiloclaw/src/providers/rollout.ts +++ b/services/kiloclaw/src/providers/rollout.ts @@ -2,7 +2,7 @@ import { z } from 'zod'; import type { ProviderId } from '../schemas/instance-config'; export const PROVIDER_ROLLOUT_KV_KEY = 'provider-rollout'; -export const NORTHFLANK_ROLLOUT_AVAILABLE = false; +export const NORTHFLANK_ROLLOUT_AVAILABLE = true; const NorthflankRolloutSchema = z.object({ personalTrafficPercent: z.number().int().min(0).max(100), diff --git a/services/kiloclaw/src/routes/platform-inbound-email.test.ts b/services/kiloclaw/src/routes/platform-inbound-email.test.ts index a88a82f02..5ce577ba7 100644 --- a/services/kiloclaw/src/routes/platform-inbound-email.test.ts +++ b/services/kiloclaw/src/routes/platform-inbound-email.test.ts @@ -101,6 +101,7 @@ describe('POST /inbound-email', () => { sandboxId: SANDBOX_ID, orgId: null, inboundEmailEnabled: true, + provider: 'fly', }); }); @@ -230,6 +231,7 @@ describe('POST /inbound-email', () => { sandboxId: SANDBOX_ID, orgId: null, inboundEmailEnabled: false, + provider: 'fly', }); const { env } = makeEnv(); @@ -289,6 +291,7 @@ describe('POST /inbound-email', () => { sandboxId: SANDBOX_ID, orgId: '22222222-2222-4222-8222-222222222222', inboundEmailEnabled: true, + provider: 'fly', }); const { env, resolveDoKey } = makeEnv(); diff --git a/services/kiloclaw/src/routes/platform-legacy-routing.test.ts b/services/kiloclaw/src/routes/platform-legacy-routing.test.ts index 30e3ca63b..f7c4fcbc1 100644 --- a/services/kiloclaw/src/routes/platform-legacy-routing.test.ts +++ b/services/kiloclaw/src/routes/platform-legacy-routing.test.ts @@ -128,6 +128,7 @@ describe('legacy platform DO routing', () => { userId: currentUserId, orgId: null, inboundEmailEnabled: true, + provider: 'fly', }); await expect( @@ -211,6 +212,7 @@ describe('resolveInstanceDoKey with instanceId', () => { userId: currentUserId, orgId: null, inboundEmailEnabled: false, + provider: 'fly', }); await expect(resolveInstanceDoKey(env, currentUserId, instanceId)).resolves.toBe(legacyDoKey); @@ -223,6 +225,7 @@ describe('resolveInstanceDoKey with instanceId', () => { userId: currentUserId, orgId: null, inboundEmailEnabled: false, + provider: 'fly', }); await expect(resolveInstanceDoKey(env, currentUserId, instanceId)).resolves.toBe(instanceId); diff --git a/services/kiloclaw/src/schemas/instance-config.ts b/services/kiloclaw/src/schemas/instance-config.ts index 90f60678a..68f5e72d5 100644 --- a/services/kiloclaw/src/schemas/instance-config.ts +++ b/services/kiloclaw/src/schemas/instance-config.ts @@ -74,12 +74,28 @@ export const DockerLocalProviderStateSchema = z.object({ hostPort: z.number().int().nullable().default(null), }); +export const NorthflankProviderStateSchema = z.object({ + provider: z.literal('northflank'), + projectId: z.string().nullable().default(null), + projectName: z.string().nullable().default(null), + serviceId: z.string().nullable().default(null), + serviceName: z.string().nullable().default(null), + volumeId: z.string().nullable().default(null), + volumeName: z.string().nullable().default(null), + secretId: z.string().nullable().default(null), + secretName: z.string().nullable().default(null), + ingressHost: z.string().nullable().default(null), + region: z.string().nullable().default(null), +}); + export const ProviderStateSchema = z.discriminatedUnion('provider', [ FlyProviderStateSchema, DockerLocalProviderStateSchema, + NorthflankProviderStateSchema, ]); export type FlyProviderState = z.infer; export type DockerLocalProviderState = z.infer; +export type NorthflankProviderState = z.infer; export type ProviderState = z.infer; export const KiloExaSearchModeSchema = z.enum(['kilo-proxy', 'disabled']); diff --git a/services/kiloclaw/src/types.ts b/services/kiloclaw/src/types.ts index 67da49879..6de828be7 100644 --- a/services/kiloclaw/src/types.ts +++ b/services/kiloclaw/src/types.ts @@ -49,6 +49,22 @@ export type KiloClawEnv = { FLY_IMAGE_TAG?: string; FLY_IMAGE_DIGEST?: string; OPENCLAW_VERSION?: string; + + // Northflank configuration + NF_API_TOKEN?: string; + NF_API_BASE?: string; + NF_TEAM_ID?: string; + NF_REGION?: string; + NF_DEPLOYMENT_PLAN?: string; + NF_STORAGE_CLASS_NAME?: string; + NF_STORAGE_ACCESS_MODE?: string; + NF_VOLUME_SIZE_MB?: string; + NF_EPHEMERAL_STORAGE_MB?: string; + NF_EDGE_HEADER_NAME?: string; + NF_EDGE_HEADER_VALUE?: string; + NF_IMAGE_PATH_TEMPLATE?: string; + NF_IMAGE_CREDENTIALS_ID?: string; + DOCKER_LOCAL_API_BASE?: string; DOCKER_LOCAL_IMAGE?: string; DOCKER_LOCAL_PORT_RANGE?: string; diff --git a/services/kiloclaw/wrangler.jsonc b/services/kiloclaw/wrangler.jsonc index edb81110a..b83392dfb 100644 --- a/services/kiloclaw/wrangler.jsonc +++ b/services/kiloclaw/wrangler.jsonc @@ -113,6 +113,19 @@ "FLY_ORG_SLUG": "kilo-679", // Org for creating per-user Fly apps "FLY_IMAGE_TAG": "latest", "FLY_REGION": "eu,us", + // Northflank provider rollout remains disabled until runtime support is smoke-tested. + // Configure these non-secret vars before enabling Northflank: + // "NF_API_BASE": "https://api.northflank.com/v1", + // "NF_TEAM_ID": "...", + // "NF_REGION": "...", + // "NF_DEPLOYMENT_PLAN": "nf-compute-200", + // "NF_STORAGE_CLASS_NAME": "nf-multi-rw", + // "NF_STORAGE_ACCESS_MODE": "ReadWriteMany", + // "NF_VOLUME_SIZE_MB": "10240", + // "NF_EPHEMERAL_STORAGE_MB": "2048", + // "NF_EDGE_HEADER_NAME": "...", + // "NF_IMAGE_PATH_TEMPLATE": "ghcr.io/kilo-org/kiloclaw:{tag}", + // "NF_IMAGE_CREDENTIALS_ID": "...", "BACKEND_API_URL": "https://app.kilo.ai", "OPENCLAW_ALLOWED_ORIGINS": "https://claw.kilosessions.ai,https://kilo.ai,https://www.kilo.ai", "KILOCLAW_CHECKIN_URL": "https://claw.kilosessions.ai/api/controller/checkin", @@ -126,6 +139,7 @@ }, // Secrets (set via wrangler secret put): // FLY_API_TOKEN, + // NF_API_TOKEN, NF_EDGE_HEADER_VALUE, // NEXTAUTH_SECRET, INTERNAL_API_SECRET, GATEWAY_TOKEN_SECRET, // AGENT_ENV_VARS_PRIVATE_KEY }