chore: add feedback survey, pass custom vocav to cloud endpoints
This commit is contained in:
parent
3be8306820
commit
423568a127
17 changed files with 205 additions and 17 deletions
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
|
|
@ -133,6 +133,7 @@ jobs:
|
|||
POSTHOG_HOST: https://app.posthog.com
|
||||
TELEMETRY_ENABLED: true
|
||||
POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }}
|
||||
FEEDBACK_SURVEY_ID: ${{ secrets.FEEDBACK_SURVEY_ID }}
|
||||
AUTH_CLIENT_ID: ${{ secrets.AUTH_CLIENT_ID }}
|
||||
AUTHORIZATION_ENDPOINT: ${{ secrets.AUTHORIZATION_ENDPOINT }}
|
||||
AUTH_TOKEN_ENDPOINT: ${{ secrets.AUTH_TOKEN_ENDPOINT }}
|
||||
|
|
@ -148,6 +149,7 @@ jobs:
|
|||
POSTHOG_HOST: https://app.posthog.com
|
||||
TELEMETRY_ENABLED: true
|
||||
POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }}
|
||||
FEEDBACK_SURVEY_ID: ${{ secrets.FEEDBACK_SURVEY_ID }}
|
||||
AUTH_CLIENT_ID: ${{ secrets.AUTH_CLIENT_ID }}
|
||||
AUTHORIZATION_ENDPOINT: ${{ secrets.AUTHORIZATION_ENDPOINT }}
|
||||
AUTH_TOKEN_ENDPOINT: ${{ secrets.AUTH_TOKEN_ENDPOINT }}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ LOG_LEVEL=info
|
|||
TELEMETRY_ENABLED=true
|
||||
POSTHOG_HOST=https://app.posthog.com
|
||||
POSTHOG_API_KEY=your-posthog-api-key
|
||||
FEEDBACK_SURVEY_ID=your-posthog-survey-id
|
||||
|
||||
# OAuth Configuration
|
||||
# Required for Amical Cloud transcription
|
||||
|
|
|
|||
20
apps/desktop/src/components/feedback-button.tsx
Normal file
20
apps/desktop/src/components/feedback-button.tsx
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import { IconMessageHeart } from "@tabler/icons-react";
|
||||
import { SidebarMenuButton, SidebarMenuItem } from "@/components/ui/sidebar";
|
||||
import { usePostHog } from "@/renderer/main/lib/posthog";
|
||||
|
||||
export function FeedbackButton() {
|
||||
const { enabled, hasSurvey, showFeedbackSurvey } = usePostHog();
|
||||
|
||||
if (!enabled || !hasSurvey) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<SidebarMenuItem>
|
||||
<SidebarMenuButton onClick={showFeedbackSurvey}>
|
||||
<IconMessageHeart />
|
||||
<span>Feedback</span>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
);
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ import {
|
|||
SidebarMenuItem,
|
||||
} from "@/components/ui/sidebar";
|
||||
import { AuthButton } from "@/components/auth-button";
|
||||
import { FeedbackButton } from "@/components/feedback-button";
|
||||
|
||||
export function NavSecondary({
|
||||
items,
|
||||
|
|
@ -39,6 +40,7 @@ export function NavSecondary({
|
|||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
))}
|
||||
<FeedbackButton />
|
||||
<AuthButton />
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ export interface PipelineContext {
|
|||
import { GetAccessibilityContextResult } from "@amical/types";
|
||||
|
||||
export interface SharedPipelineData {
|
||||
vocabulary: Map<string, string>;
|
||||
vocabulary: string[]; // Custom vocab
|
||||
replacements: Map<string, string>; // Custom replacements
|
||||
userPreferences: {
|
||||
language?: string; // Optional - undefined means auto-detect
|
||||
formattingStyle: "formal" | "casual" | "technical";
|
||||
|
|
@ -31,7 +32,8 @@ export function createDefaultContext(sessionId: string): PipelineContext {
|
|||
return {
|
||||
sessionId,
|
||||
sharedData: {
|
||||
vocabulary: new Map(),
|
||||
vocabulary: [],
|
||||
replacements: new Map(),
|
||||
userPreferences: {
|
||||
language: "en",
|
||||
formattingStyle: "formal",
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export { PipelineContext, SharedPipelineData } from "./context";
|
|||
|
||||
// Context for transcription operations (shared between transcribe and flush)
|
||||
export interface TranscribeContext {
|
||||
vocabulary?: Map<string, string>;
|
||||
vocabulary?: string[];
|
||||
accessibilityContext?: GetAccessibilityContextResult | null;
|
||||
previousChunk?: string;
|
||||
aggregatedTranscription?: string;
|
||||
|
|
@ -28,7 +28,7 @@ export interface FormatParams {
|
|||
text: string;
|
||||
context: {
|
||||
style?: string;
|
||||
vocabulary?: Map<string, string>;
|
||||
vocabulary?: string[];
|
||||
accessibilityContext?: GetAccessibilityContextResult | null;
|
||||
previousChunk?: string;
|
||||
aggregatedTranscription?: string;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ export class AmicalCloudProvider implements TranscriptionProvider {
|
|||
private currentAccessibilityContext: GetAccessibilityContextResult | null =
|
||||
null;
|
||||
private currentAggregatedTranscription: string | undefined;
|
||||
private currentVocabulary: string[] = [];
|
||||
|
||||
// Configuration
|
||||
private readonly FRAME_SIZE = 512; // 32ms at 16kHz
|
||||
|
|
@ -63,6 +64,7 @@ export class AmicalCloudProvider implements TranscriptionProvider {
|
|||
this.currentLanguage = context.language;
|
||||
this.currentAccessibilityContext = context?.accessibilityContext ?? null;
|
||||
this.currentAggregatedTranscription = context?.aggregatedTranscription;
|
||||
this.currentVocabulary = context?.vocabulary ?? [];
|
||||
|
||||
// Check authentication
|
||||
if (!(await this.authService.isAuthenticated())) {
|
||||
|
|
@ -107,6 +109,7 @@ export class AmicalCloudProvider implements TranscriptionProvider {
|
|||
this.currentLanguage = context.language;
|
||||
this.currentAccessibilityContext = context?.accessibilityContext ?? null;
|
||||
this.currentAggregatedTranscription = context?.aggregatedTranscription;
|
||||
this.currentVocabulary = context?.vocabulary ?? [];
|
||||
|
||||
// Check authentication
|
||||
if (!(await this.authService.isAuthenticated())) {
|
||||
|
|
@ -222,6 +225,7 @@ export class AmicalCloudProvider implements TranscriptionProvider {
|
|||
audioData: Array.from(audioData),
|
||||
vadProbs,
|
||||
language: this.currentLanguage,
|
||||
vocabulary: this.currentVocabulary,
|
||||
previousTranscription: this.currentAggregatedTranscription,
|
||||
formatting: {
|
||||
enabled: enableFormatting,
|
||||
|
|
|
|||
|
|
@ -294,17 +294,14 @@ export class WhisperProvider implements TranscriptionProvider {
|
|||
}
|
||||
|
||||
private generateInitialPrompt(
|
||||
vocabulary?: Map<string, string>,
|
||||
vocabulary?: string[],
|
||||
aggregatedTranscription?: string,
|
||||
): string {
|
||||
const promptParts: string[] = [];
|
||||
|
||||
// Add vocabulary terms if available
|
||||
if (vocabulary && vocabulary.size > 0) {
|
||||
// Extract vocabulary keys (the actual terms) and join with commas
|
||||
const vocabularyTerms = Array.from(vocabulary.keys());
|
||||
const vocabularyText = vocabularyTerms.join(", ");
|
||||
promptParts.push(vocabularyText);
|
||||
if (vocabulary && vocabulary.length > 0) {
|
||||
promptParts.push(vocabulary.join(", "));
|
||||
}
|
||||
|
||||
// Add last 8 words from aggregated transcription if available
|
||||
|
|
|
|||
66
apps/desktop/src/renderer/main/lib/posthog.ts
Normal file
66
apps/desktop/src/renderer/main/lib/posthog.ts
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
import { useEffect } from "react";
|
||||
import posthog from "posthog-js";
|
||||
import { api } from "@/trpc/react";
|
||||
|
||||
let initialized = false;
|
||||
|
||||
function initPostHog(apiKey: string, host: string, machineId: string): void {
|
||||
if (initialized) return;
|
||||
|
||||
posthog.init(apiKey, {
|
||||
api_host: host,
|
||||
opt_out_capturing_by_default: true,
|
||||
autocapture: false,
|
||||
capture_pageview: false,
|
||||
capture_pageleave: false,
|
||||
disable_session_recording: true,
|
||||
persistence: "memory",
|
||||
bootstrap: {
|
||||
distinctID: machineId,
|
||||
},
|
||||
});
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
function setTelemetryEnabled(enabled: boolean): void {
|
||||
if (!initialized) return;
|
||||
if (enabled) {
|
||||
posthog.opt_in_capturing();
|
||||
} else {
|
||||
posthog.opt_out_capturing();
|
||||
}
|
||||
}
|
||||
|
||||
export function usePostHog() {
|
||||
const { data: config } = api.settings.getTelemetryConfig.useQuery();
|
||||
|
||||
// Initialize PostHog when config is available
|
||||
useEffect(() => {
|
||||
if (config?.apiKey) {
|
||||
initPostHog(config.apiKey, config.host, config.machineId);
|
||||
}
|
||||
}, [config?.apiKey, config?.host, config?.machineId]);
|
||||
|
||||
// Sync opt-in/opt-out state when enabled changes
|
||||
useEffect(() => {
|
||||
if (config?.enabled !== undefined) {
|
||||
setTelemetryEnabled(config.enabled);
|
||||
}
|
||||
}, [config?.enabled]);
|
||||
|
||||
const showFeedbackSurvey = () => {
|
||||
if (!initialized || !config?.feedbackSurveyId) return;
|
||||
posthog.onSurveysLoaded(() => {
|
||||
posthog.displaySurvey(config.feedbackSurveyId);
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
enabled: config?.enabled ?? false,
|
||||
hasSurvey: !!config?.feedbackSurveyId,
|
||||
showFeedbackSurvey,
|
||||
};
|
||||
}
|
||||
|
||||
export { posthog };
|
||||
|
|
@ -52,6 +52,7 @@ export default function AdvancedSettingsPage() {
|
|||
api.settings.updateTelemetrySettings.useMutation({
|
||||
onSuccess: () => {
|
||||
utils.settings.getTelemetrySettings.invalidate();
|
||||
utils.settings.getTelemetryConfig.invalidate();
|
||||
toast.success("Telemetry settings updated");
|
||||
},
|
||||
onError: (error) => {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { createRootRoute, Outlet } from "@tanstack/react-router";
|
|||
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { api, trpcClient } from "@/trpc/react";
|
||||
import { usePostHog } from "../lib/posthog";
|
||||
|
||||
// Create a client
|
||||
const queryClient = new QueryClient({
|
||||
|
|
@ -17,14 +18,25 @@ export const Route = createRootRoute({
|
|||
component: RootComponent,
|
||||
});
|
||||
|
||||
function RootComponent() {
|
||||
// Inner component that uses hooks requiring provider context
|
||||
function AppShell() {
|
||||
usePostHog(); // Initialize and sync telemetry
|
||||
|
||||
return (
|
||||
<api.Provider client={trpcClient} queryClient={queryClient}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<>
|
||||
<Outlet />
|
||||
{process.env.NODE_ENV === "development" && (
|
||||
<TanStackRouterDevtools position="bottom-right" />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function RootComponent() {
|
||||
return (
|
||||
<api.Provider client={trpcClient} queryClient={queryClient}>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<AppShell />
|
||||
</QueryClientProvider>
|
||||
</api.Provider>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -132,9 +132,11 @@ export class TelemetryService {
|
|||
},
|
||||
};
|
||||
|
||||
this.enabled = true;
|
||||
this.enabled = telemetrySettings?.enabled !== false;
|
||||
this.initialized = true;
|
||||
logger.main.info("Telemetry service initialized successfully");
|
||||
logger.main.info("Telemetry service initialized successfully", {
|
||||
enabled: this.enabled,
|
||||
});
|
||||
}
|
||||
|
||||
private async collectSystemInfo(): Promise<SystemInfo> {
|
||||
|
|
@ -232,6 +234,7 @@ export class TelemetryService {
|
|||
|
||||
async optIn(): Promise<void> {
|
||||
await this.settingsService.setTelemetrySettings({ enabled: true });
|
||||
this.enabled = true;
|
||||
if (!this.posthog) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -243,6 +246,7 @@ export class TelemetryService {
|
|||
|
||||
async optOut(): Promise<void> {
|
||||
await this.settingsService.setTelemetrySettings({ enabled: false });
|
||||
this.enabled = false;
|
||||
if (!this.posthog) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import { TelemetryService } from "../services/telemetry-service";
|
|||
import type { NativeBridge } from "./platform/native-bridge-service";
|
||||
import type { OnboardingService } from "./onboarding-service";
|
||||
import { createTranscription } from "../db/transcriptions";
|
||||
import { getVocabulary } from "../db/vocabulary";
|
||||
import { logger } from "../main/logger";
|
||||
import { v4 as uuid } from "uuid";
|
||||
import { VADService } from "./vad-service";
|
||||
|
|
@ -609,7 +610,19 @@ export class TranscriptionService {
|
|||
: dictationSettings.selectedLanguage || "en";
|
||||
}
|
||||
|
||||
// TODO: Load actual vocabulary
|
||||
// Load vocabulary and replacements
|
||||
const vocabEntries = await getVocabulary({ limit: 50 });
|
||||
for (const entry of vocabEntries) {
|
||||
if (entry.isReplacement) {
|
||||
context.sharedData.replacements.set(
|
||||
entry.word,
|
||||
entry.replacementWord || "",
|
||||
);
|
||||
} else {
|
||||
context.sharedData.vocabulary.push(entry.word);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Load formatter config from settings
|
||||
|
||||
return context;
|
||||
|
|
|
|||
|
|
@ -495,6 +495,19 @@ export const settingsRouter = createRouter({
|
|||
return telemetryService?.getMachineId() ?? "";
|
||||
}),
|
||||
|
||||
// Get telemetry config for renderer (PostHog surveys)
|
||||
getTelemetryConfig: procedure.query(async ({ ctx }) => {
|
||||
const telemetryService = ctx.serviceManager.getService("telemetryService");
|
||||
return {
|
||||
apiKey: process.env.POSTHOG_API_KEY || __BUNDLED_POSTHOG_API_KEY,
|
||||
host: process.env.POSTHOG_HOST || __BUNDLED_POSTHOG_HOST,
|
||||
machineId: telemetryService?.getMachineId() ?? "",
|
||||
enabled: telemetryService?.isEnabled() ?? false,
|
||||
feedbackSurveyId:
|
||||
process.env.FEEDBACK_SURVEY_ID || __BUNDLED_FEEDBACK_SURVEY_ID,
|
||||
};
|
||||
}),
|
||||
|
||||
// Download log file via save dialog
|
||||
downloadLogFile: procedure.mutation(async () => {
|
||||
const { dialog, BrowserWindow } = await import("electron");
|
||||
|
|
|
|||
1
apps/desktop/src/types/bundled-env.d.ts
vendored
1
apps/desktop/src/types/bundled-env.d.ts
vendored
|
|
@ -5,3 +5,4 @@ declare const __BUNDLED_AUTH_CLIENT_ID: string;
|
|||
declare const __BUNDLED_AUTH_AUTHORIZATION_ENDPOINT: string;
|
||||
declare const __BUNDLED_AUTH_TOKEN_ENDPOINT: string;
|
||||
declare const __BUNDLED_API_ENDPOINT: string;
|
||||
declare const __BUNDLED_FEEDBACK_SURVEY_ID: string;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ export default defineConfig({
|
|||
process.env.AUTH_TOKEN_ENDPOINT || "",
|
||||
),
|
||||
__BUNDLED_API_ENDPOINT: JSON.stringify(process.env.API_ENDPOINT || ""),
|
||||
__BUNDLED_FEEDBACK_SURVEY_ID: JSON.stringify(
|
||||
process.env.FEEDBACK_SURVEY_ID || "",
|
||||
),
|
||||
},
|
||||
build: {
|
||||
rollupOptions: {
|
||||
|
|
|
|||
47
pnpm-lock.yaml
generated
47
pnpm-lock.yaml
generated
|
|
@ -250,6 +250,9 @@ importers:
|
|||
openai:
|
||||
specifier: ^4.98.0
|
||||
version: 4.104.0(encoding@0.1.13)(ws@8.18.3)(zod@3.25.76)
|
||||
posthog-js:
|
||||
specifier: ^1.315.1
|
||||
version: 1.315.1
|
||||
posthog-node:
|
||||
specifier: ^5.8.1
|
||||
version: 5.8.1
|
||||
|
|
@ -1537,6 +1540,12 @@ packages:
|
|||
'@posthog/core@1.0.2':
|
||||
resolution: {integrity: sha512-hWk3rUtJl2crQK0WNmwg13n82hnTwB99BT99/XI5gZSvIlYZ1TPmMZE8H2dhJJ98J/rm9vYJ/UXNzw3RV5HTpQ==}
|
||||
|
||||
'@posthog/core@1.9.0':
|
||||
resolution: {integrity: sha512-j7KSWxJTUtNyKynLt/p0hfip/3I46dWU2dk+pt7dKRoz2l5CYueHuHK4EO7Wlgno5yo1HO4sc4s30MXMTICHJw==}
|
||||
|
||||
'@posthog/types@1.315.1':
|
||||
resolution: {integrity: sha512-m2NggfJRYby3AkAES6yHMLURvTeK+rxN+5nmkuaCbOXQPdtWacSFIG5ZwN8d3crSx+WpiFauCDdr1sc3ZFkTHg==}
|
||||
|
||||
'@radix-ui/number@1.1.1':
|
||||
resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==}
|
||||
|
||||
|
|
@ -3311,6 +3320,9 @@ packages:
|
|||
core-js-pure@3.45.1:
|
||||
resolution: {integrity: sha512-OHnWFKgTUshEU8MK+lOs1H8kC8GkTi9Z1tvNkxrCcw9wl3MJIO7q2ld77wjWn4/xuGrVu2X+nME1iIIPBSdyEQ==}
|
||||
|
||||
core-js@3.47.0:
|
||||
resolution: {integrity: sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==}
|
||||
|
||||
create-require@1.1.1:
|
||||
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
|
||||
|
||||
|
|
@ -4038,6 +4050,9 @@ packages:
|
|||
resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
|
||||
engines: {node: ^12.20 || >= 14.13}
|
||||
|
||||
fflate@0.4.8:
|
||||
resolution: {integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==}
|
||||
|
||||
fflate@0.8.2:
|
||||
resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==}
|
||||
|
||||
|
|
@ -5457,6 +5472,9 @@ packages:
|
|||
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
|
||||
posthog-js@1.315.1:
|
||||
resolution: {integrity: sha512-ambT1azidu4hKhSmB95KdLY6yHfj9vvz1XNn68syh8DtkQ0uSdjpRY6tjMp96EQtPqCrDKr+8QpcusT1KQEZSA==}
|
||||
|
||||
posthog-node@5.8.1:
|
||||
resolution: {integrity: sha512-YJYlYnlpItVjHqM9IhvZx8TzK8gnx2nU+0uhiog4RN47NnV0Z0K1AdC4ul+O8VuvS/jHqKCQvL8iAONRA37+0A==}
|
||||
engines: {node: '>=20'}
|
||||
|
|
@ -5466,6 +5484,9 @@ packages:
|
|||
engines: {node: '>=14.0.0'}
|
||||
hasBin: true
|
||||
|
||||
preact@10.28.2:
|
||||
resolution: {integrity: sha512-lbteaWGzGHdlIuiJ0l2Jq454m6kcpI1zNje6d8MlGAFlYvP2GO4ibnat7P74Esfz4sPTdM6UxtTwh/d3pwM9JA==}
|
||||
|
||||
prebuild-install@7.1.3:
|
||||
resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==}
|
||||
engines: {node: '>=10'}
|
||||
|
|
@ -6596,6 +6617,9 @@ packages:
|
|||
resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==}
|
||||
engines: {node: '>= 14'}
|
||||
|
||||
web-vitals@4.2.4:
|
||||
resolution: {integrity: sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==}
|
||||
|
||||
webidl-conversions@3.0.1:
|
||||
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
||||
|
||||
|
|
@ -7935,6 +7959,12 @@ snapshots:
|
|||
|
||||
'@posthog/core@1.0.2': {}
|
||||
|
||||
'@posthog/core@1.9.0':
|
||||
dependencies:
|
||||
cross-spawn: 7.0.6
|
||||
|
||||
'@posthog/types@1.315.1': {}
|
||||
|
||||
'@radix-ui/number@1.1.1': {}
|
||||
|
||||
'@radix-ui/primitive@1.1.3': {}
|
||||
|
|
@ -9888,6 +9918,8 @@ snapshots:
|
|||
|
||||
core-js-pure@3.45.1: {}
|
||||
|
||||
core-js@3.47.0: {}
|
||||
|
||||
create-require@1.1.1: {}
|
||||
|
||||
cross-dirname@0.1.0: {}
|
||||
|
|
@ -10715,6 +10747,8 @@ snapshots:
|
|||
node-domexception: 1.0.0
|
||||
web-streams-polyfill: 3.3.3
|
||||
|
||||
fflate@0.4.8: {}
|
||||
|
||||
fflate@0.8.2: {}
|
||||
|
||||
figures@3.2.0:
|
||||
|
|
@ -12216,6 +12250,15 @@ snapshots:
|
|||
picocolors: 1.1.1
|
||||
source-map-js: 1.2.1
|
||||
|
||||
posthog-js@1.315.1:
|
||||
dependencies:
|
||||
'@posthog/core': 1.9.0
|
||||
'@posthog/types': 1.315.1
|
||||
core-js: 3.47.0
|
||||
fflate: 0.4.8
|
||||
preact: 10.28.2
|
||||
web-vitals: 4.2.4
|
||||
|
||||
posthog-node@5.8.1:
|
||||
dependencies:
|
||||
'@posthog/core': 1.0.2
|
||||
|
|
@ -12224,6 +12267,8 @@ snapshots:
|
|||
dependencies:
|
||||
commander: 9.5.0
|
||||
|
||||
preact@10.28.2: {}
|
||||
|
||||
prebuild-install@7.1.3:
|
||||
dependencies:
|
||||
detect-libc: 2.0.4
|
||||
|
|
@ -13503,6 +13548,8 @@ snapshots:
|
|||
|
||||
web-streams-polyfill@4.0.0-beta.3: {}
|
||||
|
||||
web-vitals@4.2.4: {}
|
||||
|
||||
webidl-conversions@3.0.1: {}
|
||||
|
||||
webpack-virtual-modules@0.6.2: {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue