feat(stage-*): track provider card clicks and time-to-first-message (#832)
This commit is contained in:
@@ -2,9 +2,13 @@ import type { Plugin } from 'vue'
|
||||
import type { RouteRecordRaw } from 'vue-router'
|
||||
|
||||
import Tres from '@tresjs/core'
|
||||
import buildTime from '~build/time'
|
||||
|
||||
import { autoAnimatePlugin } from '@formkit/auto-animate/vue'
|
||||
import { useSharedAnalyticsStore } from '@proj-airi/stage-ui/stores/analytics'
|
||||
import { MotionPlugin } from '@vueuse/motion'
|
||||
import { abbreviatedSha, branch } from '~build/git'
|
||||
import { version } from '~build/package'
|
||||
import { createPinia } from 'pinia'
|
||||
import { setupLayouts } from 'virtual:generated-layouts'
|
||||
import { createApp } from 'vue'
|
||||
@@ -38,6 +42,15 @@ import '@fontsource/sniglet'
|
||||
|
||||
const pinia = createPinia()
|
||||
|
||||
// Initialize analytics
|
||||
const analyticsStore = useSharedAnalyticsStore(pinia)
|
||||
analyticsStore.initialize({
|
||||
version: version ?? 'dev',
|
||||
commit: abbreviatedSha,
|
||||
branch,
|
||||
builtOn: buildTime.toISOString(),
|
||||
})
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
// TODO: vite-plugin-vue-layouts is long deprecated, replace with another layout solution
|
||||
|
||||
@@ -1,16 +1,6 @@
|
||||
import buildTime from '~build/time'
|
||||
import posthog from 'posthog-js'
|
||||
|
||||
import { abbreviatedSha } from '~build/git'
|
||||
import { version } from '~build/package'
|
||||
|
||||
posthog.init('phc_rljw376z5gt6vXJlc3sTr7hFbXodciY9THEQXIRnW53', {
|
||||
api_host: 'https://us.i.posthog.com',
|
||||
person_profiles: 'identified_only', // or 'always' to create profiles for anonymous users as well
|
||||
})
|
||||
|
||||
posthog.register({
|
||||
app_version: version ?? 'dev',
|
||||
app_commit: abbreviatedSha,
|
||||
app_build_time: buildTime,
|
||||
})
|
||||
|
||||
@@ -1,24 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import { UTCDate } from '@date-fns/utc'
|
||||
import { MarkdownRenderer, Progress } from '@proj-airi/stage-ui/components'
|
||||
import { useSharedAnalyticsStore } from '@proj-airi/stage-ui/stores/analytics/index'
|
||||
import { Button, DoubleCheckButton } from '@proj-airi/ui'
|
||||
import { useMediaQuery } from '@vueuse/core'
|
||||
import { abbreviatedSha, branch, committerDate } from '~build/git'
|
||||
import { formatISO9075 } from 'date-fns'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { DialogContent, DialogDescription, DialogOverlay, DialogPortal, DialogRoot, DialogTitle } from 'reka-ui'
|
||||
import { DrawerContent, DrawerDescription, DrawerHandle, DrawerOverlay, DrawerPortal, DrawerRoot, DrawerTitle } from 'vaul-vue'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import packageJson from '../../../package.json'
|
||||
|
||||
import { useElectronAutoUpdater } from '../composables/electron-vueuse'
|
||||
|
||||
const buildInfo = computed(() => ({
|
||||
version: packageJson.version,
|
||||
branch,
|
||||
commit: abbreviatedSha.substring(0, 7),
|
||||
builtOn: formatISO9075(new UTCDate(committerDate)),
|
||||
}))
|
||||
const analyticsStore = useSharedAnalyticsStore()
|
||||
const { buildInfo } = storeToRefs(analyticsStore)
|
||||
|
||||
const {
|
||||
state: updateState,
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { UTCDate } from '@date-fns/utc'
|
||||
import { AboutContent, AboutDialog } from '@proj-airi/stage-ui/components'
|
||||
import { abbreviatedSha, branch, committerDate } from '~build/git'
|
||||
import { formatISO9075 } from 'date-fns'
|
||||
import { computed, ref } from 'vue'
|
||||
import { useSharedAnalyticsStore } from '@proj-airi/stage-ui/stores/analytics/index'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const show = ref(false)
|
||||
const localDate = formatISO9075(new UTCDate(committerDate))
|
||||
const buildInfo = computed(() => ({
|
||||
branch,
|
||||
commit: abbreviatedSha.substring(0, 7),
|
||||
builtOn: localDate,
|
||||
}))
|
||||
const analyticsStore = useSharedAnalyticsStore()
|
||||
const { buildInfo } = storeToRefs(analyticsStore)
|
||||
|
||||
const aboutLinks = [
|
||||
{ label: 'Home', href: 'https://airi.moeru.ai/docs/', icon: 'i-solar:home-smile-outline' },
|
||||
{ label: 'Documentations', href: 'https://airi.moeru.ai/docs/en/docs/overview/', icon: 'i-solar:document-add-outline' },
|
||||
|
||||
@@ -2,10 +2,14 @@ import type { Plugin } from 'vue'
|
||||
import type { Router, RouteRecordRaw } from 'vue-router'
|
||||
|
||||
import Tres from '@tresjs/core'
|
||||
import buildTime from '~build/time'
|
||||
import NProgress from 'nprogress'
|
||||
|
||||
import { autoAnimatePlugin } from '@formkit/auto-animate/vue'
|
||||
import { useSharedAnalyticsStore } from '@proj-airi/stage-ui/stores/analytics'
|
||||
import { MotionPlugin } from '@vueuse/motion'
|
||||
import { abbreviatedSha, branch } from '~build/git'
|
||||
import { version } from '~build/package'
|
||||
import { createPinia } from 'pinia'
|
||||
import { setupLayouts } from 'virtual:generated-layouts'
|
||||
import { createApp } from 'vue'
|
||||
@@ -26,6 +30,16 @@ import './styles/main.css'
|
||||
import 'uno.css'
|
||||
|
||||
const pinia = createPinia()
|
||||
|
||||
// Initialize analytics
|
||||
const analyticsStore = useSharedAnalyticsStore(pinia)
|
||||
analyticsStore.initialize({
|
||||
version: version ?? 'dev',
|
||||
commit: abbreviatedSha,
|
||||
branch,
|
||||
builtOn: buildTime.toISOString(),
|
||||
})
|
||||
|
||||
// TODO: vite-plugin-vue-layouts is long deprecated, replace with another layout solution
|
||||
const routeRecords = setupLayouts(routes as RouteRecordRaw[])
|
||||
|
||||
|
||||
@@ -1,16 +1,6 @@
|
||||
import buildTime from '~build/time'
|
||||
import posthog from 'posthog-js'
|
||||
|
||||
import { abbreviatedSha } from '~build/git'
|
||||
import { version } from '~build/package'
|
||||
|
||||
posthog.init('phc_pzjziJjrVZpa9SqnQqq0QEKvkmuCPH7GDTA6TbRTEf9', {
|
||||
api_host: 'https://us.i.posthog.com',
|
||||
person_profiles: 'identified_only', // or 'always' to create profiles for anonymous users as well
|
||||
})
|
||||
|
||||
posthog.register({
|
||||
app_version: version ?? 'dev',
|
||||
app_commit: abbreviatedSha,
|
||||
app_build_time: buildTime,
|
||||
})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { Alert, ErrorContainer, RadioCardManySelect, RadioCardSimple } from '@proj-airi/stage-ui/components'
|
||||
import { useAnalytics } from '@proj-airi/stage-ui/composables'
|
||||
import { useConsciousnessStore } from '@proj-airi/stage-ui/stores/modules/consciousness'
|
||||
import { useProvidersStore } from '@proj-airi/stage-ui/stores/providers'
|
||||
import { storeToRefs } from 'pinia'
|
||||
@@ -22,6 +23,7 @@ const {
|
||||
} = storeToRefs(consciousnessStore)
|
||||
|
||||
const { t } = useI18n()
|
||||
const { trackProviderClick } = useAnalytics()
|
||||
|
||||
watch(activeProvider, async (provider) => {
|
||||
if (!provider)
|
||||
@@ -76,6 +78,7 @@ function handleDeleteProvider(providerId: string) {
|
||||
:value="metadata.id"
|
||||
:title="metadata.localizedName || 'Unknown'"
|
||||
:description="metadata.localizedDescription"
|
||||
@click="trackProviderClick(metadata.id, 'consciousness')"
|
||||
>
|
||||
<template #topRight>
|
||||
<button
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import workletUrl from '@proj-airi/stage-ui/workers/vad/process.worklet?worker&url'
|
||||
|
||||
import { Alert, ErrorContainer, LevelMeter, RadioCardManySelect, RadioCardSimple, TestDummyMarker, ThresholdMeter, TimeSeriesChart } from '@proj-airi/stage-ui/components'
|
||||
import { useAudioAnalyzer, useAudioRecorder } from '@proj-airi/stage-ui/composables'
|
||||
import { useAnalytics, useAudioAnalyzer, useAudioRecorder } from '@proj-airi/stage-ui/composables'
|
||||
import { useVAD } from '@proj-airi/stage-ui/stores/ai/models/vad'
|
||||
import { useAudioContext } from '@proj-airi/stage-ui/stores/audio'
|
||||
import { useHearingSpeechInputPipeline, useHearingStore } from '@proj-airi/stage-ui/stores/modules/hearing'
|
||||
@@ -29,6 +29,7 @@ const {
|
||||
const providersStore = useProvidersStore()
|
||||
const { configuredTranscriptionProvidersMetadata } = storeToRefs(providersStore)
|
||||
|
||||
const { trackProviderClick } = useAnalytics()
|
||||
const { stopStream, startStream } = useSettingsAudioDevice()
|
||||
const { audioInputs, selectedAudioInput, stream } = storeToRefs(useSettingsAudioDevice())
|
||||
const { startRecord, stopRecord, onStopRecord } = useAudioRecorder(stream)
|
||||
@@ -290,6 +291,7 @@ onUnmounted(() => {
|
||||
:value="metadata.id"
|
||||
:title="metadata.localizedName || 'Unknown'"
|
||||
:description="metadata.localizedDescription"
|
||||
@click="trackProviderClick(metadata.id, 'hearing')"
|
||||
/>
|
||||
<RouterLink
|
||||
to="/settings/providers#transcription"
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
TestDummyMarker,
|
||||
VoiceCardManySelect,
|
||||
} from '@proj-airi/stage-ui/components'
|
||||
import { useAnalytics } from '@proj-airi/stage-ui/composables'
|
||||
import { useSpeechStore } from '@proj-airi/stage-ui/stores/modules/speech'
|
||||
import { useProvidersStore } from '@proj-airi/stage-ui/stores/providers'
|
||||
import {
|
||||
@@ -45,6 +46,8 @@ const {
|
||||
availableVoices,
|
||||
} = storeToRefs(speechStore)
|
||||
|
||||
const { trackProviderClick } = useAnalytics()
|
||||
|
||||
const voiceSearchQuery = ref('')
|
||||
const useSSML = ref(false)
|
||||
const testText = ref('Hello, my name is AI Assistant')
|
||||
@@ -198,6 +201,7 @@ function updateCustomModelName(value: string) {
|
||||
:value="metadata.id"
|
||||
:title="metadata.localizedName || 'Unknown'"
|
||||
:description="metadata.localizedDescription"
|
||||
@click="trackProviderClick(metadata.id, 'speech')"
|
||||
/>
|
||||
<RouterLink
|
||||
to="/settings/providers#speech"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { IconStatusItem, RippleGrid } from '@proj-airi/stage-ui/components'
|
||||
import { useAnalytics } from '@proj-airi/stage-ui/composables'
|
||||
import { useRippleGridState } from '@proj-airi/stage-ui/composables/use-ripple-grid-state'
|
||||
import { useScrollToHash } from '@proj-airi/stage-ui/composables/useScrollToHash'
|
||||
import { useProvidersStore } from '@proj-airi/stage-ui/stores/providers'
|
||||
@@ -10,6 +11,7 @@ import { useRoute } from 'vue-router'
|
||||
const route = useRoute()
|
||||
const providersStore = useProvidersStore()
|
||||
const { lastClickedIndex, setLastClickedIndex } = useRippleGridState()
|
||||
const { trackProviderClick } = useAnalytics()
|
||||
|
||||
const {
|
||||
allChatProvidersMetadata,
|
||||
@@ -114,6 +116,7 @@ useScrollToHash(() => route.hash, {
|
||||
:icon-image="provider.iconImage"
|
||||
:to="`/settings/providers/${provider.category}/${provider.id}`"
|
||||
:configured="provider.configured"
|
||||
@click="trackProviderClick(provider.id, provider.category)"
|
||||
/>
|
||||
</template>
|
||||
</RippleGrid>
|
||||
|
||||
@@ -4,5 +4,6 @@ export * from './llmmarkerParser'
|
||||
export * from './markdown'
|
||||
export * from './micvad'
|
||||
export * from './queues'
|
||||
export * from './use-analytics'
|
||||
export * from './use-context-bridge'
|
||||
export * from './whisper'
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import posthog from 'posthog-js'
|
||||
|
||||
import { useSharedAnalyticsStore } from '../stores/analytics'
|
||||
|
||||
export function useAnalytics() {
|
||||
const analyticsStore = useSharedAnalyticsStore()
|
||||
|
||||
function trackProviderClick(providerId: string, module: string) {
|
||||
posthog.capture('provider_card_clicked', {
|
||||
provider_id: providerId,
|
||||
module,
|
||||
})
|
||||
}
|
||||
|
||||
function trackFirstMessage() {
|
||||
// Only track the first message once
|
||||
if (analyticsStore.firstMessageTracked)
|
||||
return
|
||||
|
||||
analyticsStore.markFirstMessageTracked()
|
||||
|
||||
// Calculate time from app start to message sent
|
||||
const timeToFirstMessageMs = analyticsStore.appStartTime
|
||||
? Date.now() - analyticsStore.appStartTime
|
||||
: null
|
||||
|
||||
posthog.capture('first_message_sent', {
|
||||
time_to_first_message_ms: timeToFirstMessageMs,
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
trackProviderClick,
|
||||
trackFirstMessage,
|
||||
}
|
||||
}
|
||||
@@ -36,48 +36,39 @@ export function useContextBridge() {
|
||||
broadcastContext(event.data as ContextMessage)
|
||||
}))
|
||||
|
||||
disposeHookFns.push(...[
|
||||
chatStore.onBeforeMessageComposed(async (message) => {
|
||||
if (isProcessingRemoteStream)
|
||||
return
|
||||
broadcastStreamEvent({ type: 'before-compose', message, sessionId: chatStore.activeSessionId })
|
||||
}),
|
||||
chatStore.onAfterMessageComposed(async (message) => {
|
||||
if (isProcessingRemoteStream)
|
||||
return
|
||||
broadcastStreamEvent({ type: 'after-compose', message, sessionId: chatStore.activeSessionId })
|
||||
}),
|
||||
chatStore.onBeforeSend(async (message) => {
|
||||
if (isProcessingRemoteStream)
|
||||
return
|
||||
broadcastStreamEvent({ type: 'before-send', message, sessionId: chatStore.activeSessionId })
|
||||
}),
|
||||
chatStore.onAfterSend(async (message) => {
|
||||
if (isProcessingRemoteStream)
|
||||
return
|
||||
broadcastStreamEvent({ type: 'after-send', message, sessionId: chatStore.activeSessionId })
|
||||
}),
|
||||
chatStore.onTokenLiteral(async (literal) => {
|
||||
if (isProcessingRemoteStream)
|
||||
return
|
||||
broadcastStreamEvent({ type: 'token-literal', literal, sessionId: chatStore.activeSessionId })
|
||||
}),
|
||||
chatStore.onTokenSpecial(async (special) => {
|
||||
if (isProcessingRemoteStream)
|
||||
return
|
||||
broadcastStreamEvent({ type: 'token-special', special, sessionId: chatStore.activeSessionId })
|
||||
}),
|
||||
chatStore.onStreamEnd(async () => {
|
||||
if (isProcessingRemoteStream)
|
||||
return
|
||||
broadcastStreamEvent({ type: 'stream-end', sessionId: chatStore.activeSessionId })
|
||||
}),
|
||||
chatStore.onAssistantResponseEnd(async (message) => {
|
||||
if (isProcessingRemoteStream)
|
||||
return
|
||||
broadcastStreamEvent({ type: 'assistant-end', message, sessionId: chatStore.activeSessionId })
|
||||
}),
|
||||
])
|
||||
disposeHookFns.push(chatStore.onBeforeMessageComposed(async (message) => {
|
||||
if (isProcessingRemoteStream)
|
||||
return
|
||||
broadcastStreamEvent({ type: 'before-compose', message, sessionId: chatStore.activeSessionId })
|
||||
}), chatStore.onAfterMessageComposed(async (message) => {
|
||||
if (isProcessingRemoteStream)
|
||||
return
|
||||
broadcastStreamEvent({ type: 'after-compose', message, sessionId: chatStore.activeSessionId })
|
||||
}), chatStore.onBeforeSend(async (message) => {
|
||||
if (isProcessingRemoteStream)
|
||||
return
|
||||
broadcastStreamEvent({ type: 'before-send', message, sessionId: chatStore.activeSessionId })
|
||||
}), chatStore.onAfterSend(async (message) => {
|
||||
if (isProcessingRemoteStream)
|
||||
return
|
||||
broadcastStreamEvent({ type: 'after-send', message, sessionId: chatStore.activeSessionId })
|
||||
}), chatStore.onTokenLiteral(async (literal) => {
|
||||
if (isProcessingRemoteStream)
|
||||
return
|
||||
broadcastStreamEvent({ type: 'token-literal', literal, sessionId: chatStore.activeSessionId })
|
||||
}), chatStore.onTokenSpecial(async (special) => {
|
||||
if (isProcessingRemoteStream)
|
||||
return
|
||||
broadcastStreamEvent({ type: 'token-special', special, sessionId: chatStore.activeSessionId })
|
||||
}), chatStore.onStreamEnd(async () => {
|
||||
if (isProcessingRemoteStream)
|
||||
return
|
||||
broadcastStreamEvent({ type: 'stream-end', sessionId: chatStore.activeSessionId })
|
||||
}), chatStore.onAssistantResponseEnd(async (message) => {
|
||||
if (isProcessingRemoteStream)
|
||||
return
|
||||
broadcastStreamEvent({ type: 'assistant-end', message, sessionId: chatStore.activeSessionId })
|
||||
}))
|
||||
|
||||
const { stop: stopIncomingStreamWatch } = watch(incomingStreamEvent, async (event) => {
|
||||
if (!event)
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import type { AboutBuildInfo } from '../../components/scenarios/about/types'
|
||||
|
||||
import posthog from 'posthog-js'
|
||||
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
|
||||
export const useSharedAnalyticsStore = defineStore('analytics-shared', () => {
|
||||
const isInitialized = ref(false)
|
||||
const buildInfo = ref<AboutBuildInfo>({
|
||||
version: '',
|
||||
commit: '',
|
||||
branch: '',
|
||||
builtOn: '',
|
||||
})
|
||||
const appStartTime = ref<number | null>(null)
|
||||
const firstMessageTracked = ref(false)
|
||||
|
||||
function initialize(info: AboutBuildInfo) {
|
||||
if (isInitialized.value)
|
||||
return
|
||||
|
||||
buildInfo.value = info
|
||||
appStartTime.value = Date.now()
|
||||
|
||||
// Register metadata with PostHog after buildInfo is set
|
||||
posthog.register({
|
||||
app_version: (buildInfo.value.version && buildInfo.value.version !== '0.0.0') ? buildInfo.value.version : 'dev',
|
||||
app_commit: buildInfo.value.commit,
|
||||
app_branch: buildInfo.value.branch,
|
||||
app_build_time: buildInfo.value.builtOn,
|
||||
})
|
||||
|
||||
isInitialized.value = true
|
||||
}
|
||||
|
||||
function markFirstMessageTracked() {
|
||||
firstMessageTracked.value = true
|
||||
}
|
||||
|
||||
return {
|
||||
buildInfo,
|
||||
appStartTime,
|
||||
firstMessageTracked,
|
||||
initialize,
|
||||
markFirstMessageTracked,
|
||||
}
|
||||
})
|
||||
@@ -9,6 +9,7 @@ import { useLocalStorage } from '@vueuse/core'
|
||||
import { defineStore, storeToRefs } from 'pinia'
|
||||
import { computed, ref, toRaw, watch } from 'vue'
|
||||
|
||||
import { useAnalytics } from '../composables'
|
||||
import { useLlmmarkerParser } from '../composables/llmmarkerParser'
|
||||
import { useLLM } from '../stores/llm'
|
||||
import { createQueue } from '../utils/queue'
|
||||
@@ -23,6 +24,7 @@ export const CHAT_STREAM_CHANNEL_NAME = 'airi-chat-stream'
|
||||
export const useChatStore = defineStore('chat', () => {
|
||||
const { stream, discoverToolsCompatibility } = useLLM()
|
||||
const { systemPrompt } = storeToRefs(useAiriCardStore())
|
||||
const { trackFirstMessage } = useAnalytics()
|
||||
|
||||
const activeSessionId = useLocalStorage<string>(ACTIVE_SESSION_STORAGE_KEY, 'default')
|
||||
const sessionMessages = useLocalStorage<Record<string, ChatHistoryItem[]>>(CHAT_STORAGE_KEY, {})
|
||||
@@ -332,6 +334,7 @@ export const useChatStore = defineStore('chat', () => {
|
||||
|
||||
streamingMessage.value = { role: 'assistant', content: '', slices: [], tool_results: [], createdAt: Date.now() }
|
||||
|
||||
trackFirstMessage()
|
||||
try {
|
||||
await emitBeforeMessageComposedHooks(sendingMessage)
|
||||
|
||||
|
||||
Generated
+3
-9
@@ -2114,7 +2114,7 @@ importers:
|
||||
version: 66.5.11
|
||||
'@wxt-dev/module-vue':
|
||||
specifier: ^1.0.3
|
||||
version: 1.0.3(vite@8.0.0-beta.1(@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.1.8(typescript@5.9.3)
|
||||
@@ -22852,12 +22852,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.1(@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.1(@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.0.9)(msw@2.7.3(@types/node@24.10.4)(typescript@5.9.3))(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.0.9)(msw@2.7.3(@types/node@24.10.4)(typescript@5.9.3))(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)
|
||||
@@ -23777,9 +23771,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.1(@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.1(@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
|
||||
|
||||
Reference in New Issue
Block a user