/** * Local analytics — privacy-respecting, offline-first usage telemetry. * * DESIGN PRINCIPLES: * 1. All data stays local by default (no phoning home without opt-in) * 2. No PII collected — only anonymous usage patterns * 3. Aggregated daily summaries, not individual request logs * 4. Users can disable entirely via GAMECODEX_ANALYTICS=false * 5. Data is human-readable JSON for transparency * * WHAT WE TRACK: * - Tool usage counts (which tools are most popular) * - Search query patterns (categories, modules — NOT query text) * - Doc access patterns (which docs are most read) * - Session duration and startup time * - Error rates by tool * - Cache hit rates (hybrid mode) * * WHAT WE NEVER TRACK: * - License keys or key hashes * - Search query text (only counts) * - Machine identifiers or usernames * - IP addresses or geo data * - File paths or system info * * FUTURE (opt-in only): * - Anonymous aggregate upload to Cloudflare Workers analytics endpoint * - Helps prioritize content creation (which docs are most read) * - Controlled by GAMECODEX_ANALYTICS=upload */ interface ToolUsage { calls: number; errors: number; avgDurationMs: number; totalDurationMs: number; } interface SearchStats { totalQueries: number; byModule: Record; byCategory: Record; avgResultCount: number; zeroResultQueries: number; } interface DocAccessStats { totalFetches: number; byDoc: Record; byModule: Record; sectionExtractions: number; maxLengthTruncations: number; } interface CacheStats { hits: number; misses: number; staleFallbacks: number; remoteFetches: number; } export interface DailySummary { date: string; version: string; sessionStartedAt: number; startupTimeMs: number; tools: Record; search: SearchStats; docs: DocAccessStats; cache: CacheStats; modules: { discovered: number; active: number; totalDocs: number; }; } export declare class Analytics { private summary; private dirty; private flushTimer; private enabled; constructor(); /** Record server startup */ recordStartup(options: { version: string; startupTimeMs: number; discoveredModules: number; activeModules: number; totalDocs: number; }): void; /** Record a tool call */ recordToolCall(tool: string, durationMs: number, error?: boolean): void; /** Record a search query */ recordSearch(options: { module?: string; category?: string; resultCount: number; }): void; /** Record a doc access */ recordDocAccess(options: { docId: string; module: string; usedSection?: boolean; usedMaxLength?: boolean; }): void; /** Record a cache event */ recordCacheEvent(event: "hit" | "miss" | "stale" | "remote"): void; /** Get current summary (for diagnostics or future upload) */ getSummary(): Readonly; /** Get recent daily summaries for trend analysis */ getRecentSummaries(days?: number): DailySummary[]; /** Flush current summary to disk */ flush(): void; /** Clean up old analytics files (keep last 30 days) */ cleanup(keepDays?: number): number; /** Shutdown — flush and stop timer */ shutdown(): void; private getFilePath; private loadOrCreate; /** Ensure we're still writing to today's file (handles midnight rollover) */ private ensureToday; } export declare function getAnalytics(): Analytics; export {};