guideai-app 0.3.1 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,5 +13,5 @@ interface TranscriptBoxProps {
13
13
  onTextKeyPress?: (event: React.KeyboardEvent) => void;
14
14
  textPlaceholder?: string;
15
15
  }
16
- declare const TranscriptBox: React.FC<TranscriptBoxProps>;
16
+ declare const TranscriptBox: React.NamedExoticComponent<TranscriptBoxProps>;
17
17
  export default TranscriptBox;
@@ -33,18 +33,31 @@ declare class EventTracker {
33
33
  private pendingEvents;
34
34
  private currentUrl;
35
35
  private organizationKey?;
36
+ private lastEventTime;
37
+ private eventThrottleInterval;
38
+ private lastEventsByType;
39
+ private duplicateEventBuffer;
40
+ private maxDuplicateBuffer;
41
+ private isInitialized;
36
42
  private customerMetadata;
37
43
  constructor(options?: {
38
44
  customerId?: string;
39
45
  customerType?: string;
40
46
  organizationId?: string;
41
47
  organizationKey?: string;
48
+ batchSize?: number;
49
+ batchTimeout?: number;
50
+ eventThrottleInterval?: number;
42
51
  });
52
+ private init;
53
+ private loadEventsFromStorage;
54
+ private saveEventsToStorage;
43
55
  setCustomerMetadata(metadata: Partial<typeof this.customerMetadata>): void;
44
56
  getCustomerMetadata(): typeof this.customerMetadata;
45
57
  clearCustomerMetadata(): void;
46
58
  initialize(): void;
47
59
  private enrichEventData;
60
+ private sanitizeEventData;
48
61
  private getSessionId;
49
62
  private getDeviceType;
50
63
  startTracking(): void;
@@ -65,6 +78,12 @@ declare class EventTracker {
65
78
  private getSafeValue;
66
79
  private isFocusable;
67
80
  private isFormElement;
81
+ private generateEventKey;
82
+ private shouldThrottleEvent;
83
+ private isDuplicateEvent;
84
+ private isSignificantClickTarget;
85
+ private isSignificantFocusTarget;
86
+ private isSignificantRouteChange;
68
87
  private logEvent;
69
88
  private startBatchTimer;
70
89
  private emitBatch;
@@ -6,11 +6,18 @@ declare class UserMetadataTracker {
6
6
  private pendingUpdates;
7
7
  private isInitialized;
8
8
  private onError?;
9
+ private lastSyncTime;
10
+ private minSyncInterval;
11
+ private lastMetadataHash;
12
+ private pendingUpdateTypes;
9
13
  constructor(organizationKey: string, config?: MetadataConfig, onError?: (error: Error, context: string) => void);
10
- private init;
14
+ init(): void;
11
15
  updateUserInfo(userInfo: Partial<UserMetadata>): void;
12
16
  trackLogin(additionalInfo?: Partial<UserMetadata>): void;
17
+ private trackVisitOncePerSession;
13
18
  trackVisit(): void;
19
+ resetSessionVisitTracking(): void;
20
+ trackVisitManually(): void;
14
21
  trackCustomEvent(eventType: string, customData: Record<string, any>): void;
15
22
  getMetadata(): UserMetadata;
16
23
  getPendingUpdates(): MetadataUpdate[];
@@ -21,6 +28,10 @@ declare class UserMetadataTracker {
21
28
  private collectBrowserInfo;
22
29
  private parseBrowserInfo;
23
30
  private startSyncTimer;
31
+ private shouldSync;
32
+ private addPendingUpdate;
33
+ private isDataDuplicate;
34
+ private generateDataHash;
24
35
  private setupEventTrackerIntegration;
25
36
  private stopSyncTimer;
26
37
  private emitPendingUpdates;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Standardized logging utility for GuideAI package
3
+ * Provides consistent formatting and development gating across all components
4
+ */
5
+ type Component = 'GuideAI' | 'EventTracker' | 'UserMetadata' | 'API' | 'TranscriptBox' | 'Onboarding';
6
+ declare class Logger {
7
+ private static formatMessage;
8
+ /**
9
+ * Standard info logging - only in development
10
+ */
11
+ static log(component: Component, action: string, data?: any): void;
12
+ /**
13
+ * Warning logging - always shown
14
+ */
15
+ static warn(component: Component, action: string, data?: any): void;
16
+ /**
17
+ * Error logging - always shown
18
+ */
19
+ static error(component: Component, action: string, error?: any): void;
20
+ /**
21
+ * API call logging with method and endpoint
22
+ */
23
+ static apiCall(method: string, endpoint: string, data?: any): void;
24
+ /**
25
+ * API response logging
26
+ */
27
+ static apiResponse(method: string, endpoint: string, success: boolean, data?: any): void;
28
+ /**
29
+ * Conversation flow tracking
30
+ */
31
+ static conversation(action: string, data?: any): void;
32
+ /**
33
+ * Event tracking logging
34
+ */
35
+ static event(action: string, data?: any): void;
36
+ /**
37
+ * Metadata tracking logging
38
+ */
39
+ static metadata(action: string, data?: any): void;
40
+ }
41
+ export default Logger;
@@ -0,0 +1,62 @@
1
+ import { Workflow } from './api';
2
+ export interface WorkflowTrigger {
3
+ triggerWords: string[];
4
+ workflowKey: string;
5
+ description?: string;
6
+ }
7
+ export interface WorkflowLogEvent {
8
+ type: 'workflow_init' | 'trigger_detected' | 'workflow_activated';
9
+ timestamp: string;
10
+ data: any;
11
+ }
12
+ /**
13
+ * Format a workflow log message for console output
14
+ */
15
+ export declare const formatWorkflowLog: (event: WorkflowLogEvent) => string;
16
+ /**
17
+ * Log workflow event to console with formatting
18
+ */
19
+ export declare const logWorkflowEvent: (event: WorkflowLogEvent) => void;
20
+ /**
21
+ * Detect which workflows should be triggered based on a user message
22
+ * @param message The user's message
23
+ * @param workflows Array of available workflows
24
+ * @returns Array of workflows that should be triggered
25
+ */
26
+ export declare const detectWorkflowTriggers: (message: string, workflows: Workflow[]) => Workflow[];
27
+ /**
28
+ * Get trigger words from a message that match a specific workflow
29
+ * @param message The user's message
30
+ * @param workflow The workflow to check against
31
+ * @returns Array of detected trigger words for this workflow
32
+ */
33
+ export declare const getWorkflowTriggerWords: (message: string, workflow: Workflow) => string[];
34
+ /**
35
+ * Check if a message contains any trigger words for any workflow
36
+ * @param message The user's message
37
+ * @param workflows Array of available workflows
38
+ * @returns True if any workflow triggers are found
39
+ */
40
+ export declare const hasWorkflowTriggers: (message: string, workflows: Workflow[]) => boolean;
41
+ /**
42
+ * Get the most relevant workflow for a message
43
+ * @param message The user's message
44
+ * @param workflows Array of available workflows
45
+ * @returns The most relevant workflow or null if none found
46
+ */
47
+ export declare const getMostRelevantWorkflow: (message: string, workflows: Workflow[]) => Workflow | null;
48
+ /**
49
+ * Legacy function for backward compatibility
50
+ * @deprecated Use detectWorkflowTriggers instead
51
+ */
52
+ export declare const detectTriggerWords: (message: string, triggerWords: string[]) => string[];
53
+ /**
54
+ * Legacy function for backward compatibility
55
+ * @deprecated Use hasWorkflowTriggers instead
56
+ */
57
+ export declare const hasTriggerWords: (message: string, triggerWords: string[]) => boolean;
58
+ /**
59
+ * Legacy function for backward compatibility
60
+ * @deprecated Use getMostRelevantWorkflow instead
61
+ */
62
+ export declare const getMostRelevantTrigger: (message: string, triggerWords: string[]) => string | null;
@@ -0,0 +1,324 @@
1
+ # User Metadata Tracking - Implementation Guide
2
+
3
+ ## Overview
4
+
5
+ The GuideAI package now includes comprehensive user metadata tracking capabilities designed for integration with Overproof. This system tracks the following metadata:
6
+
7
+ - **User's First Visit** - Timestamp of the first time the user interacted with GuideAI
8
+ - **User's Last Visit** - Timestamp of the most recent user interaction
9
+ - **User Logins** - Count and timestamp of login events
10
+ - **User Type** - Classification of the user (agent, admin, manager, customer, guest, etc.)
11
+ - **Customer Type** - Type of customer (individual, business, enterprise, etc.)
12
+ - **Customer License** - License identifier for the customer
13
+
14
+ ## Basic Usage
15
+
16
+ ### 1. Basic Integration
17
+
18
+ ```typescript
19
+ import { GuideAI } from 'guide-ai-package';
20
+
21
+ function App() {
22
+ return (
23
+ <GuideAI
24
+ organizationKey="your-org-key"
25
+ metadata={{
26
+ config: {
27
+ trackVisits: true,
28
+ trackLogins: true,
29
+ syncInterval: 30000, // Sync every 30 seconds
30
+ storage: 'localStorage'
31
+ },
32
+ initialUserData: {
33
+ userType: 'agent',
34
+ customerType: 'business',
35
+ customerLicense: 'OVERPRF-12345'
36
+ },
37
+ onMetadataUpdate: (metadata) => {
38
+ console.log('Metadata updated:', metadata);
39
+ // Send to your analytics system
40
+ }
41
+ }}
42
+ />
43
+ );
44
+ }
45
+ ```
46
+
47
+ ### 2. Tracking User Login Events
48
+
49
+ ```typescript
50
+ import { useRef } from 'react';
51
+
52
+ function LoginComponent() {
53
+ const guideAIRef = useRef();
54
+
55
+ const handleLogin = async (userInfo) => {
56
+ // Your login logic here
57
+ const loginResult = await performLogin(userInfo);
58
+
59
+ if (loginResult.success) {
60
+ // Track the login with GuideAI
61
+ guideAIRef.current?.trackLogin({
62
+ userId: loginResult.userId,
63
+ userType: loginResult.userType,
64
+ customerType: loginResult.customerType,
65
+ customerLicense: loginResult.license
66
+ });
67
+ }
68
+ };
69
+
70
+ return (
71
+ <div>
72
+ <GuideAI
73
+ ref={guideAIRef}
74
+ organizationKey="your-org-key"
75
+ metadata={{
76
+ config: { trackLogins: true }
77
+ }}
78
+ />
79
+ <button onClick={handleLogin}>Login</button>
80
+ </div>
81
+ );
82
+ }
83
+ ```
84
+
85
+ ### 3. Updating User Information
86
+
87
+ ```typescript
88
+ function UserProfileComponent() {
89
+ const guideAIRef = useRef();
90
+
91
+ const updateUserProfile = (newUserData) => {
92
+ // Update user profile in your system
93
+ saveUserProfile(newUserData);
94
+
95
+ // Update GuideAI metadata
96
+ guideAIRef.current?.updateUserInfo({
97
+ userType: newUserData.role,
98
+ customerType: newUserData.accountType,
99
+ customerLicense: newUserData.license,
100
+ customFields: {
101
+ department: newUserData.department,
102
+ region: newUserData.region
103
+ }
104
+ });
105
+ };
106
+
107
+ return (
108
+ <GuideAI
109
+ ref={guideAIRef}
110
+ organizationKey="your-org-key"
111
+ metadata={{
112
+ config: {
113
+ customFields: ['department', 'region'],
114
+ collectBrowserInfo: true
115
+ }
116
+ }}
117
+ />
118
+ );
119
+ }
120
+ ```
121
+
122
+ ## Configuration Options
123
+
124
+ ### MetadataConfig
125
+
126
+ ```typescript
127
+ interface MetadataConfig {
128
+ // Whether to automatically track visits (default: true)
129
+ trackVisits?: boolean;
130
+
131
+ // Whether to automatically track logins (default: true)
132
+ trackLogins?: boolean;
133
+
134
+ // How often to sync metadata to backend in milliseconds (default: 30000)
135
+ syncInterval?: number;
136
+
137
+ // Storage strategy (default: 'localStorage')
138
+ storage?: 'localStorage' | 'sessionStorage' | 'memory';
139
+
140
+ // Custom metadata fields to collect
141
+ customFields?: string[];
142
+
143
+ // Whether to collect browser information (default: true)
144
+ collectBrowserInfo?: boolean;
145
+
146
+ // Whether to collect user agent (default: true)
147
+ collectUserAgent?: boolean;
148
+ }
149
+ ```
150
+
151
+ ### UserMetadata Structure
152
+
153
+ ```typescript
154
+ interface UserMetadata {
155
+ // Core identification
156
+ userId?: string;
157
+ userType?: 'agent' | 'admin' | 'manager' | 'customer' | 'guest' | string;
158
+
159
+ // Customer-specific metadata
160
+ customerType?: 'individual' | 'business' | 'enterprise' | string;
161
+ customerLicense?: string;
162
+
163
+ // Visit tracking (automatically managed)
164
+ firstVisit?: number; // timestamp
165
+ lastVisit?: number; // timestamp
166
+ visitCount?: number;
167
+
168
+ // Login tracking (requires manual tracking)
169
+ loginCount?: number;
170
+ lastLogin?: number; // timestamp
171
+
172
+ // Session metadata (automatically managed)
173
+ organizationKey: string;
174
+ sessionId?: string;
175
+
176
+ // Browser information (automatically collected if enabled)
177
+ userAgent?: string;
178
+ browserInfo?: {
179
+ name?: string;
180
+ version?: string;
181
+ platform?: string;
182
+ };
183
+
184
+ // Custom fields for Overproof-specific needs
185
+ customFields?: Record<string, string | number | boolean>;
186
+ }
187
+ ```
188
+
189
+ ## API Integration
190
+
191
+ The system automatically sends metadata updates to these endpoints:
192
+
193
+ ### POST `/user-metadata`
194
+ Sends complete user metadata object when initially collected.
195
+
196
+ ### POST `/metadata-updates`
197
+ Sends batched metadata updates periodically.
198
+
199
+ ### PATCH `/users/{userId}/metadata`
200
+ Updates specific user metadata when userId is available.
201
+
202
+ ## Backend Implementation
203
+
204
+ You'll need to implement these endpoints in your backend:
205
+
206
+ ```typescript
207
+ // Example Express.js implementation
208
+ app.post('/api/user-metadata', (req, res) => {
209
+ const { organizationKey, metadata, timestamp } = req.body;
210
+
211
+ // Store metadata in your database
212
+ await UserMetadata.upsert({
213
+ organizationKey,
214
+ userId: metadata.userId || 'anonymous',
215
+ ...metadata,
216
+ lastUpdated: new Date(timestamp)
217
+ });
218
+
219
+ res.json({ success: true });
220
+ });
221
+
222
+ app.post('/api/metadata-updates', (req, res) => {
223
+ const { organizationKey, updates, batchTimestamp } = req.body;
224
+
225
+ // Process batch updates
226
+ for (const update of updates) {
227
+ await processMetadataUpdate(organizationKey, update);
228
+ }
229
+
230
+ res.json({ success: true });
231
+ });
232
+ ```
233
+
234
+ ## Privacy Considerations
235
+
236
+ - **User Agent Collection**: Can be disabled via `collectUserAgent: false`
237
+ - **Browser Info Collection**: Can be disabled via `collectBrowserInfo: false`
238
+ - **Custom Fields**: Only fields specified in `customFields` array are collected
239
+ - **Storage**: Can be set to `'memory'` for session-only storage without persistence
240
+
241
+ ## Testing
242
+
243
+ ```typescript
244
+ // Get current metadata
245
+ const metadata = guideAIRef.current?.getMetadata();
246
+ console.log('Current metadata:', metadata);
247
+
248
+ // Force sync metadata now
249
+ await guideAIRef.current?.syncMetadata();
250
+
251
+ // Track custom events
252
+ guideAIRef.current?.trackCustomEvent('document_viewed', {
253
+ documentType: 'policy',
254
+ documentId: 'POL-12345'
255
+ });
256
+ ```
257
+
258
+ ## Overproof Integration Example
259
+
260
+ ```typescript
261
+ function OverproofApp() {
262
+ const guideAIRef = useRef();
263
+
264
+ // Track when user logs into Overproof
265
+ const handleOverproofLogin = (user) => {
266
+ guideAIRef.current?.trackLogin({
267
+ userId: user.id,
268
+ userType: user.role, // 'agent', 'admin', etc.
269
+ customerType: user.accountType,
270
+ customerLicense: user.licenseNumber,
271
+ customFields: {
272
+ agencyId: user.agencyId,
273
+ territory: user.territory,
274
+ permissions: user.permissions.join(',')
275
+ }
276
+ });
277
+ };
278
+
279
+ // Track when user profile is updated
280
+ const handleProfileUpdate = (updatedProfile) => {
281
+ guideAIRef.current?.updateUserInfo({
282
+ userType: updatedProfile.role,
283
+ customerLicense: updatedProfile.licenseNumber,
284
+ customFields: {
285
+ agencyId: updatedProfile.agencyId,
286
+ territory: updatedProfile.territory
287
+ }
288
+ });
289
+ };
290
+
291
+ return (
292
+ <GuideAI
293
+ ref={guideAIRef}
294
+ organizationKey="overproof-org-key"
295
+ metadata={{
296
+ config: {
297
+ trackVisits: true,
298
+ trackLogins: true,
299
+ syncInterval: 15000, // More frequent syncing for Overproof
300
+ customFields: ['agencyId', 'territory', 'permissions'],
301
+ collectBrowserInfo: true
302
+ },
303
+ onMetadataUpdate: (metadata) => {
304
+ // Send to Overproof analytics
305
+ window.OverproofAnalytics?.track('guideai_metadata_update', metadata);
306
+ }
307
+ }}
308
+ />
309
+ );
310
+ }
311
+ ```
312
+
313
+ ## Storage and Data Persistence
314
+
315
+ - **localStorage**: Persists across browser sessions (default)
316
+ - **sessionStorage**: Persists only for current session
317
+ - **memory**: No persistence, data lost on page refresh
318
+
319
+ Metadata is automatically:
320
+ - Saved locally based on storage configuration
321
+ - Synced to backend at configured intervals
322
+ - Restored when user returns (if using persistent storage)
323
+
324
+ This implementation provides a robust foundation for tracking user metadata in the Overproof environment while maintaining flexibility for other use cases.
package/obfuscate.js ADDED
@@ -0,0 +1,40 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const JavaScriptObfuscator = require('javascript-obfuscator');
4
+
5
+ // Files to obfuscate
6
+ const files = [
7
+ 'dist/index.js',
8
+ 'dist/index.esm.js'
9
+ ];
10
+
11
+ // Load obfuscator config
12
+ const config = JSON.parse(fs.readFileSync(path.resolve(__dirname, 'obfuscator.json'), 'utf8'));
13
+
14
+ // Process each file
15
+
16
+ files.forEach(file => {
17
+ const filePath = path.resolve(__dirname, file);
18
+
19
+ try {
20
+ // Check if file exists
21
+ if (!fs.existsSync(filePath)) {
22
+ console.warn(`Warning: ${file} does not exist, skipping obfuscation.`);
23
+ return;
24
+ }
25
+
26
+
27
+ // Read the file
28
+ const code = fs.readFileSync(filePath, 'utf8');
29
+
30
+ // Obfuscate the code
31
+ const obfuscationResult = JavaScriptObfuscator.obfuscate(code, config);
32
+
33
+ // Write the obfuscated code back to the file
34
+ fs.writeFileSync(filePath, obfuscationResult.getObfuscatedCode());
35
+
36
+ } catch (error) {
37
+ console.error(`Error obfuscating ${file}:`, error);
38
+ process.exit(1);
39
+ }
40
+ });
@@ -0,0 +1,24 @@
1
+ {
2
+ "compact": true,
3
+ "controlFlowFlattening": false,
4
+ "controlFlowFlatteningThreshold": 0.75,
5
+ "deadCodeInjection": false,
6
+ "deadCodeInjectionThreshold": 0.4,
7
+ "debugProtection": false,
8
+ "debugProtectionInterval": 0,
9
+ "disableConsoleOutput": true,
10
+ "identifierNamesGenerator": "hexadecimal",
11
+ "log": false,
12
+ "numbersToExpressions": false,
13
+ "renameGlobals": false,
14
+ "rotateStringArray": false,
15
+ "selfDefending": false,
16
+ "shuffleStringArray": false,
17
+ "splitStrings": false,
18
+ "splitStringsChunkLength": 10,
19
+ "stringArray": false,
20
+ "stringArrayEncoding": [],
21
+ "stringArrayThreshold": 0,
22
+ "transformObjectKeys": false,
23
+ "unicodeEscapeSequence": false
24
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "guideai-app",
3
- "version": "0.3.1",
3
+ "version": "0.3.4",
4
4
  "description": "AI-powered guide component for React applications",
5
5
  "main": "dist/GuideAI.js",
6
6
  "types": "dist/GuideAI.d.ts",