feat(stage-*): allow to connect remote ws server (#953)

This commit is contained in:
LemonNeko
2026-01-15 05:13:57 +08:00
committed by GitHub
parent ce56400b3e
commit 06b3451849
18 changed files with 165 additions and 23 deletions
+1
View File
@@ -60,6 +60,7 @@
"@proj-airi/server-runtime": "workspace:^",
"@proj-airi/server-sdk": "workspace:*",
"@proj-airi/stage-layouts": "workspace:^",
"@proj-airi/stage-pages": "workspace:^",
"@proj-airi/stage-ui": "workspace:^",
"@proj-airi/stage-ui-live2d": "workspace:^",
"@proj-airi/stage-ui-three": "workspace:^",
@@ -104,6 +104,10 @@ const routeHeaderMetadataMap = computed(() => {
subtitle: t('settings.title'),
title: t('settings.pages.data.title'),
},
'/settings/connection': {
subtitle: t('settings.title'),
title: t('settings.pages.connection.title'),
},
'/settings/scene': {
subtitle: t('settings.title'),
title: t('settings.pages.scene.title'),
@@ -0,0 +1,16 @@
<script setup lang="ts">
import ConnectionSettings from '@proj-airi/stage-pages/pages/settings/connection/ConnectionSettings.vue'
</script>
<template>
<ConnectionSettings>
<template #platform-specific />
</ConnectionSettings>
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -60,6 +60,12 @@ const settings = computed(() => [
icon: 'i-solar:box-minimalistic-bold-duotone',
to: '/settings/providers',
},
{
title: t('settings.pages.connection.title'),
description: t('settings.pages.connection.description'),
icon: 'i-solar:router-bold-duotone',
to: '/settings/connection',
},
{
title: t('settings.pages.system.title'),
description: t('settings.pages.system.description'),
@@ -722,6 +722,13 @@ pages:
playground:
title: Transcription Playground
title: Providers
connection:
description: Configure WebSocket server connection
title: Connection
websocket-url:
description: Full address of the WebSocket server (e.g., ws://localhost:6121/ws)
label: WebSocket Server Address
placeholder: ws://localhost:6121/ws
scene:
description: Configure the environment where the character lives
title: Scene
@@ -696,6 +696,12 @@ pages:
playground:
title: Playground de Transcripción
title: Proveedores
connection:
description: Configurar la conexión del servidor WebSocket
title: Conexión
websocket-url:
description: "Dirección completa del servidor WebSocket (ej.: ws://localhost:6121/ws)' label: Dirección del servidor WebSocket"
placeholder: ws://localhost:6121/ws
scene:
description: Configurar el entorno donde vive el personaje
title: Escena
@@ -696,6 +696,13 @@ pages:
playground:
title: 文字起こし実験場
title: プロバイダー
connection:
description: WebSocket サーバー接続を設定
title: 接続
websocket-url:
description: WebSocket サーバーの完全なアドレス(例:ws://localhost:6121/ws
label: WebSocket サーバーアドレス
placeholder: ws://localhost:6121/ws
scene:
description: キャラクターが過ごす環境を設定する
title: シーン
@@ -696,6 +696,13 @@ pages:
playground:
title: Transcription Playground
title: Providers
connection:
description: WebSocket 서버 연결 구성
title: 연결
websocket-url:
description: 'WebSocket 서버의 전체 주소 (예: ws://localhost:6121/ws)'
label: WebSocket 서버 주소
placeholder: ws://localhost:6121/ws
scene:
description: Configure the environment where the character lives
title: Scene
@@ -696,6 +696,13 @@ pages:
playground:
title: Песочница транскрипции
title: Провайдеры
connection:
description: Настроить подключение к WebSocket серверу
title: Подключение
websocket-url:
description: 'Полный адрес WebSocket сервера (например: ws://localhost:6121/ws)'
label: Адрес WebSocket сервера
placeholder: ws://localhost:6121/ws
scene:
description: Настройте окружение, в котором живёт персонаж
title: Сцена
@@ -696,6 +696,13 @@ pages:
playground:
title: Transcription Playground
title: Nhà cung cấp
connection:
description: Cấu hình kết nối máy chủ WebSocket
title: Kết nối
websocket-url:
description: 'Địa chỉ đầy đủ của máy chủ WebSocket (ví dụ: ws://localhost:6121/ws)'
label: Địa chỉ máy chủ WebSocket
placeholder: ws://localhost:6121/ws
scene:
description: Cấu hình môi trường nhân vật sinh sống
title: Bối cảnh
@@ -699,6 +699,13 @@ pages:
scene:
description: 配置角色所在环境
title: 场景
connection:
description: 配置 WebSocket 服务器连接
title: 连接
websocket-url:
description: WebSocket 服务器的完整地址(例如:ws://localhost:6121/ws
label: WebSocket 服务器地址
placeholder: ws://localhost:6121/ws
system:
color-scheme:
description: 更改舞台的配色方案
@@ -696,6 +696,13 @@ pages:
playground:
title: 實驗平台
title: 服務來源
connection:
description: 設定 WebSocket 伺服器連線
title: 連線
websocket-url:
description: WebSocket 伺服器的完整位址(例如:ws://localhost:6121/ws
label: WebSocket 伺服器位址
placeholder: ws://localhost:6121/ws
scene:
description: 設定角色所在環境
title: 場景
@@ -103,6 +103,10 @@ const routeHeaderMetadataMap = computed(() => {
subtitle: t('settings.title'),
title: t('settings.pages.data.title'),
},
'/settings/connection': {
subtitle: t('settings.title'),
title: t('settings.pages.connection.title'),
},
'/settings/scene': {
subtitle: t('settings.title'),
title: t('settings.pages.scene.title'),
@@ -0,0 +1,23 @@
<script setup lang="ts">
import { createResettableLocalStorage } from '@proj-airi/stage-ui/utils/resettable'
import { FieldInput } from '@proj-airi/ui'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const defaultWebSocketUrl = import.meta.env.VITE_AIRI_WS_URL || 'ws://localhost:6121/ws'
const [websocketUrl] = createResettableLocalStorage('settings/connection/websocket-url', defaultWebSocketUrl)
</script>
<template>
<div :class="['rounded-lg', 'bg-neutral-50', 'p-4', 'dark:bg-neutral-800', 'flex', '~', 'col', 'gap-4']">
<!-- // TODO: Make this array, support to connect to multiple WebSocket server -->
<FieldInput
v-model="websocketUrl"
:label="t('settings.pages.connection.websocket-url.label')"
:description="t('settings.pages.connection.websocket-url.description')"
:placeholder="t('settings.pages.connection.websocket-url.placeholder')"
/>
<slot name="platform-specific" />
</div>
</template>
@@ -0,0 +1,14 @@
<script setup lang="ts">
import ConnectionSettings from './ConnectionSettings.vue'
</script>
<template>
<ConnectionSettings />
</template>
<route lang="yaml">
meta:
layout: settings
stageTransition:
name: slide
</route>
@@ -69,6 +69,12 @@ const settings = computed(() => [
icon: 'i-solar:database-bold-duotone',
to: '/settings/data',
},
{
title: t('settings.pages.connection.title'),
description: t('settings.pages.connection.description'),
icon: 'i-solar:router-bold-duotone',
to: '/settings/connection',
},
{
title: t('settings.pages.system.title'),
description: t('settings.pages.system.description'),
@@ -2,9 +2,10 @@ import type { ContextUpdate, WebSocketBaseEvent, WebSocketEvent, WebSocketEventO
import { Client, WebSocketEventSource } from '@proj-airi/server-sdk'
import { isStageTamagotchi, isStageWeb } from '@proj-airi/stage-shared'
import { useLocalStorage } from '@vueuse/core'
import { nanoid } from 'nanoid'
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { ref, watch } from 'vue'
import { useWebSocketInspectorStore } from '../../devtools/websocket-inspector'
@@ -16,6 +17,9 @@ export const useModsServerChannelStore = defineStore('mods:channels:proj-airi:se
const listenersInitialized = ref(false)
const listenerDisposers = ref<Array<() => void>>([])
const defaultWebSocketUrl = import.meta.env.VITE_AIRI_WS_URL || 'ws://localhost:6121/ws'
const websocketUrl = useLocalStorage('settings/connection/websocket-url', defaultWebSocketUrl)
const basePossibleEvents: Array<keyof WebSocketEvents> = [
'context:update',
'error',
@@ -47,7 +51,7 @@ export const useModsServerChannelStore = defineStore('mods:channels:proj-airi:se
initializing.value = new Promise<void>((resolve) => {
client.value = new Client({
name: isStageWeb() ? WebSocketEventSource.StageWeb : isStageTamagotchi() ? WebSocketEventSource.StageTamagotchi : WebSocketEventSource.StageWeb,
url: import.meta.env.VITE_AIRI_WS_URL || 'ws://localhost:6121/ws',
url: websocketUrl.value || defaultWebSocketUrl,
token: options?.token,
possibleEvents,
onAnyMessage: (event) => {
@@ -173,12 +177,24 @@ export const useModsServerChannelStore = defineStore('mods:channels:proj-airi:se
flush()
clearListeners()
client.value?.close()
if (client.value) {
client.value.close()
client.value = undefined
}
connected.value = false
client.value = undefined
initializing.value = null
}
watch(websocketUrl, (newUrl, oldUrl) => {
if (newUrl === oldUrl)
return
if (client.value || initializing.value) {
dispose()
void initialize()
}
})
return {
connected,
ensureConnected,
+16 -19
View File
@@ -724,7 +724,7 @@ importers:
version: 1.2.37
'@intlify/unplugin-vue-i18n':
specifier: ^11.0.1
version: 11.0.3(@vue/compiler-dom@3.5.26)(eslint@9.39.2(jiti@2.6.1))(rollup@4.54.0)(typescript@5.9.3)(vue-i18n@11.2.7(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
version: 11.0.3(@vue/compiler-dom@3.5.26)(eslint@9.39.2(jiti@2.6.1))(rollup@2.79.2)(typescript@5.9.3)(vue-i18n@11.2.7(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
'@proj-airi/iconify-meteocons':
specifier: 'catalog:'
version: 0.1.4
@@ -784,19 +784,19 @@ importers:
version: 4.5.1
unplugin-info:
specifier: ^1.2.4
version: 1.2.4(esbuild@0.27.2)(rolldown-vite@7.3.0(@types/node@24.10.4)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(rollup@4.54.0)
version: 1.2.4(esbuild@0.27.2)(rolldown-vite@7.3.0(@types/node@24.10.4)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(rollup@2.79.2)
unplugin-vue-router:
specifier: ^0.19.0
version: 0.19.2(@vue/compiler-sfc@3.5.26)(vue-router@4.6.4(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
unplugin-yaml:
specifier: ^3.0.7
version: 3.0.7(esbuild@0.27.2)(rolldown-vite@7.3.0(@types/node@24.10.4)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(rolldown@1.0.0-beta.53)(rollup@4.54.0)
version: 3.0.7(esbuild@0.27.2)(rolldown-vite@7.3.0(@types/node@24.10.4)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(rolldown@1.0.0-beta.53)(rollup@2.79.2)
vite:
specifier: catalog:rolldown-vite
version: rolldown-vite@7.3.0(@types/node@24.10.4)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)
vite-bundle-visualizer:
specifier: ^1.2.1
version: 1.2.1(rolldown@1.0.0-beta.53)(rollup@4.54.0)
version: 1.2.1(rolldown@1.0.0-beta.53)(rollup@2.79.2)
vite-plugin-mkcert:
specifier: 'catalog:'
version: 1.17.9(rolldown-vite@7.3.0(@types/node@24.10.4)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))
@@ -811,7 +811,7 @@ importers:
version: 0.11.0(rolldown-vite@7.3.0(@types/node@24.10.4)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vue-router@4.6.4(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
vue-macros:
specifier: ^3.1.1
version: 3.1.1(@vueuse/core@14.1.0(vue@3.5.25(typescript@5.9.3)))(esbuild@0.27.2)(rolldown-vite@7.3.0(@types/node@24.10.4)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(rolldown@1.0.0-beta.53)(rollup@4.54.0)(typescript@5.9.3)(vue-tsc@3.2.1(typescript@5.9.3))(vue@3.5.25(typescript@5.9.3))
version: 3.1.1(@vueuse/core@14.1.0(vue@3.5.25(typescript@5.9.3)))(esbuild@0.27.2)(rolldown-vite@7.3.0(@types/node@24.10.4)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(rolldown@1.0.0-beta.53)(rollup@2.79.2)(typescript@5.9.3)(vue-tsc@3.2.1(typescript@5.9.3))(vue@3.5.25(typescript@5.9.3))
vue-tsc:
specifier: ^3.1.8
version: 3.2.1(typescript@5.9.3)
@@ -905,6 +905,9 @@ importers:
'@proj-airi/stage-layouts':
specifier: workspace:^
version: link:../../packages/stage-layouts
'@proj-airi/stage-pages':
specifier: workspace:^
version: link:../../packages/stage-pages
'@proj-airi/stage-ui':
specifier: workspace:^
version: link:../../packages/stage-ui
@@ -1536,7 +1539,7 @@ importers:
version: 1.2.37
'@intlify/unplugin-vue-i18n':
specifier: ^11.0.1
version: 11.0.3(@vue/compiler-dom@3.5.26)(eslint@9.39.2(jiti@2.6.1))(rollup@2.79.2)(typescript@5.9.3)(vue-i18n@11.2.7(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
version: 11.0.3(@vue/compiler-dom@3.5.26)(eslint@9.39.2(jiti@2.6.1))(rollup@4.54.0)(typescript@5.9.3)(vue-i18n@11.2.7(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
'@proj-airi/iconify-meteocons':
specifier: 'catalog:'
version: 0.1.4
@@ -1596,19 +1599,19 @@ importers:
version: 4.5.1
unplugin-info:
specifier: ^1.2.4
version: 1.2.4(esbuild@0.27.2)(rolldown-vite@7.3.0(@types/node@24.10.4)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(rollup@2.79.2)
version: 1.2.4(esbuild@0.27.2)(rolldown-vite@7.3.0(@types/node@24.10.4)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(rollup@4.54.0)
unplugin-vue-router:
specifier: ^0.19.0
version: 0.19.2(@vue/compiler-sfc@3.5.26)(vue-router@4.6.4(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
unplugin-yaml:
specifier: ^3.0.7
version: 3.0.7(esbuild@0.27.2)(rolldown-vite@7.3.0(@types/node@24.10.4)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(rolldown@1.0.0-beta.53)(rollup@2.79.2)
version: 3.0.7(esbuild@0.27.2)(rolldown-vite@7.3.0(@types/node@24.10.4)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(rolldown@1.0.0-beta.53)(rollup@4.54.0)
vite:
specifier: catalog:rolldown-vite
version: rolldown-vite@7.3.0(@types/node@24.10.4)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)
vite-bundle-visualizer:
specifier: ^1.2.1
version: 1.2.1(rolldown@1.0.0-beta.53)(rollup@2.79.2)
version: 1.2.1(rolldown@1.0.0-beta.53)(rollup@4.54.0)
vite-plugin-pwa:
specifier: ^1.2.0
version: 1.2.0(rolldown-vite@7.3.0(@types/node@24.10.4)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(workbox-build@7.4.0)(workbox-window@7.4.0)
@@ -1620,7 +1623,7 @@ importers:
version: 0.11.0(rolldown-vite@7.3.0(@types/node@24.10.4)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vue-router@4.6.4(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
vue-macros:
specifier: ^3.1.1
version: 3.1.1(@vueuse/core@14.1.0(vue@3.5.25(typescript@5.9.3)))(esbuild@0.27.2)(rolldown-vite@7.3.0(@types/node@24.10.4)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(rolldown@1.0.0-beta.53)(rollup@2.79.2)(typescript@5.9.3)(vue-tsc@3.2.1(typescript@5.9.3))(vue@3.5.25(typescript@5.9.3))
version: 3.1.1(@vueuse/core@14.1.0(vue@3.5.25(typescript@5.9.3)))(esbuild@0.27.2)(rolldown-vite@7.3.0(@types/node@24.10.4)(esbuild@0.27.2)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(rolldown@1.0.0-beta.53)(rollup@4.54.0)(typescript@5.9.3)(vue-tsc@3.2.1(typescript@5.9.3))(vue@3.5.25(typescript@5.9.3))
vue-tsc:
specifier: ^3.1.8
version: 3.2.1(typescript@5.9.3)
@@ -2988,7 +2991,7 @@ importers:
version: 66.5.11
'@wxt-dev/module-vue':
specifier: ^1.0.3
version: 1.0.3(vite@8.0.0-beta.5(@types/node@24.10.4)(esbuild@0.25.12)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))(wxt@0.20.13(@types/node@24.10.4)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(rollup@4.54.0)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))
version: 1.0.3(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))(wxt@0.20.13(@types/node@24.10.4)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(rollup@4.54.0)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))
vue-tsc:
specifier: ^3.1.8
version: 3.2.1(typescript@5.9.3)
@@ -22464,12 +22467,6 @@ snapshots:
vite: 7.3.0(@types/node@24.10.4)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)
vue: 3.5.25(typescript@5.9.3)
'@vitejs/plugin-vue@6.0.3(vite@8.0.0-beta.5(@types/node@24.10.4)(esbuild@0.25.12)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))':
dependencies:
'@rolldown/pluginutils': 1.0.0-beta.53
vite: 8.0.0-beta.5(@types/node@24.10.4)(esbuild@0.25.12)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)
vue: 3.5.25(typescript@5.9.3)
'@vitest/browser-playwright@4.0.16(bufferutil@4.1.0)(playwright@1.57.0)(utf-8-validate@5.0.10)(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.16)':
dependencies:
'@vitest/browser': 4.0.16(bufferutil@4.1.0)(utf-8-validate@5.0.10)(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.16)
@@ -23229,9 +23226,9 @@ snapshots:
'@types/filesystem': 0.0.36
'@types/har-format': 1.2.16
'@wxt-dev/module-vue@1.0.3(vite@8.0.0-beta.5(@types/node@24.10.4)(esbuild@0.25.12)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))(wxt@0.20.13(@types/node@24.10.4)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(rollup@4.54.0)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))':
'@wxt-dev/module-vue@1.0.3(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))(wxt@0.20.13(@types/node@24.10.4)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(rollup@4.54.0)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))':
dependencies:
'@vitejs/plugin-vue': 6.0.3(vite@8.0.0-beta.5(@types/node@24.10.4)(esbuild@0.25.12)(jiti@2.6.1)(less@4.5.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))
'@vitejs/plugin-vue': 6.0.3(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vue@3.5.25(typescript@5.9.3))
wxt: 0.20.13(@types/node@24.10.4)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.30.2)(rollup@4.54.0)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)
transitivePeerDependencies:
- vite