@mobileai/react-native 0.9.0 → 0.9.1

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.
Files changed (173) hide show
  1. package/README.md +121 -0
  2. package/lib/module/components/AIAgent.js +248 -53
  3. package/lib/module/components/AIAgent.js.map +1 -1
  4. package/lib/module/components/AIZone.js +140 -0
  5. package/lib/module/components/AIZone.js.map +1 -0
  6. package/lib/module/components/AgentErrorBoundary.js +9 -0
  7. package/lib/module/components/AgentErrorBoundary.js.map +1 -1
  8. package/lib/module/components/HighlightOverlay.js +138 -0
  9. package/lib/module/components/HighlightOverlay.js.map +1 -0
  10. package/lib/module/components/ProactiveHint.js +138 -0
  11. package/lib/module/components/ProactiveHint.js.map +1 -0
  12. package/lib/module/components/cards/InfoCard.js +65 -0
  13. package/lib/module/components/cards/InfoCard.js.map +1 -0
  14. package/lib/module/components/cards/ReviewSummary.js +74 -0
  15. package/lib/module/components/cards/ReviewSummary.js.map +1 -0
  16. package/lib/module/core/AgentRuntime.js +16 -3
  17. package/lib/module/core/AgentRuntime.js.map +1 -1
  18. package/lib/module/core/FiberTreeWalker.js +62 -85
  19. package/lib/module/core/FiberTreeWalker.js.map +1 -1
  20. package/lib/module/core/IdleDetector.js +51 -0
  21. package/lib/module/core/IdleDetector.js.map +1 -0
  22. package/lib/module/core/ZoneRegistry.js +47 -0
  23. package/lib/module/core/ZoneRegistry.js.map +1 -0
  24. package/lib/module/core/systemPrompt.js +2 -0
  25. package/lib/module/core/systemPrompt.js.map +1 -1
  26. package/lib/module/index.js +21 -0
  27. package/lib/module/index.js.map +1 -1
  28. package/lib/module/services/AudioOutputService.js +10 -0
  29. package/lib/module/services/AudioOutputService.js.map +1 -1
  30. package/lib/module/services/flags/FlagService.js +117 -0
  31. package/lib/module/services/flags/FlagService.js.map +1 -0
  32. package/lib/module/services/telemetry/MobileAI.js +66 -0
  33. package/lib/module/services/telemetry/MobileAI.js.map +1 -0
  34. package/lib/module/services/telemetry/PiiScrubber.js +17 -0
  35. package/lib/module/services/telemetry/PiiScrubber.js.map +1 -0
  36. package/lib/module/services/telemetry/TelemetryService.js +260 -0
  37. package/lib/module/services/telemetry/TelemetryService.js.map +1 -0
  38. package/lib/module/services/telemetry/TouchAutoCapture.js +159 -0
  39. package/lib/module/services/telemetry/TouchAutoCapture.js.map +1 -0
  40. package/lib/module/services/telemetry/device.js +19 -0
  41. package/lib/module/services/telemetry/device.js.map +1 -0
  42. package/lib/module/services/telemetry/index.js +9 -0
  43. package/lib/module/services/telemetry/index.js.map +1 -0
  44. package/lib/module/services/telemetry/types.js +2 -0
  45. package/lib/module/services/telemetry/types.js.map +1 -0
  46. package/lib/module/support/CSATSurvey.js +273 -0
  47. package/lib/module/support/CSATSurvey.js.map +1 -0
  48. package/lib/module/support/EscalationSocket.js +92 -0
  49. package/lib/module/support/EscalationSocket.js.map +1 -0
  50. package/lib/module/support/SupportGreeting.js +142 -0
  51. package/lib/module/support/SupportGreeting.js.map +1 -0
  52. package/lib/module/support/escalateTool.js +120 -0
  53. package/lib/module/support/escalateTool.js.map +1 -0
  54. package/lib/module/support/index.js +18 -0
  55. package/lib/module/support/index.js.map +1 -0
  56. package/lib/module/support/supportPrompt.js +47 -0
  57. package/lib/module/support/supportPrompt.js.map +1 -0
  58. package/lib/module/support/types.js +2 -0
  59. package/lib/module/support/types.js.map +1 -0
  60. package/lib/module/tools/guideTool.js +61 -0
  61. package/lib/module/tools/guideTool.js.map +1 -0
  62. package/lib/module/tools/index.js +3 -0
  63. package/lib/module/tools/index.js.map +1 -1
  64. package/lib/module/tools/restoreTool.js +31 -0
  65. package/lib/module/tools/restoreTool.js.map +1 -0
  66. package/lib/module/tools/simplifyTool.js +31 -0
  67. package/lib/module/tools/simplifyTool.js.map +1 -0
  68. package/lib/module/types/jsx.d.js +4 -0
  69. package/lib/module/types/jsx.d.js.map +1 -0
  70. package/lib/typescript/src/components/AIAgent.d.ts +21 -2
  71. package/lib/typescript/src/components/AIAgent.d.ts.map +1 -1
  72. package/lib/typescript/src/components/AIZone.d.ts +16 -0
  73. package/lib/typescript/src/components/AIZone.d.ts.map +1 -0
  74. package/lib/typescript/src/components/AgentErrorBoundary.d.ts +1 -0
  75. package/lib/typescript/src/components/AgentErrorBoundary.d.ts.map +1 -1
  76. package/lib/typescript/src/components/HighlightOverlay.d.ts +10 -0
  77. package/lib/typescript/src/components/HighlightOverlay.d.ts.map +1 -0
  78. package/lib/typescript/src/components/ProactiveHint.d.ts +10 -0
  79. package/lib/typescript/src/components/ProactiveHint.d.ts.map +1 -0
  80. package/lib/typescript/src/components/cards/InfoCard.d.ts +19 -0
  81. package/lib/typescript/src/components/cards/InfoCard.d.ts.map +1 -0
  82. package/lib/typescript/src/components/cards/ReviewSummary.d.ts +19 -0
  83. package/lib/typescript/src/components/cards/ReviewSummary.d.ts.map +1 -0
  84. package/lib/typescript/src/core/AgentRuntime.d.ts +1 -0
  85. package/lib/typescript/src/core/AgentRuntime.d.ts.map +1 -1
  86. package/lib/typescript/src/core/FiberTreeWalker.d.ts.map +1 -1
  87. package/lib/typescript/src/core/IdleDetector.d.ts +27 -0
  88. package/lib/typescript/src/core/IdleDetector.d.ts.map +1 -0
  89. package/lib/typescript/src/core/ZoneRegistry.d.ts +13 -0
  90. package/lib/typescript/src/core/ZoneRegistry.d.ts.map +1 -0
  91. package/lib/typescript/src/core/systemPrompt.d.ts.map +1 -1
  92. package/lib/typescript/src/core/types.d.ts +54 -0
  93. package/lib/typescript/src/core/types.d.ts.map +1 -1
  94. package/lib/typescript/src/index.d.ts +5 -0
  95. package/lib/typescript/src/index.d.ts.map +1 -1
  96. package/lib/typescript/src/services/AudioOutputService.d.ts.map +1 -1
  97. package/lib/typescript/src/services/flags/FlagService.d.ts +25 -0
  98. package/lib/typescript/src/services/flags/FlagService.d.ts.map +1 -0
  99. package/lib/typescript/src/services/telemetry/MobileAI.d.ts +38 -0
  100. package/lib/typescript/src/services/telemetry/MobileAI.d.ts.map +1 -0
  101. package/lib/typescript/src/services/telemetry/PiiScrubber.d.ts +6 -0
  102. package/lib/typescript/src/services/telemetry/PiiScrubber.d.ts.map +1 -0
  103. package/lib/typescript/src/services/telemetry/TelemetryService.d.ts +49 -0
  104. package/lib/typescript/src/services/telemetry/TelemetryService.d.ts.map +1 -0
  105. package/lib/typescript/src/services/telemetry/TouchAutoCapture.d.ts +28 -0
  106. package/lib/typescript/src/services/telemetry/TouchAutoCapture.d.ts.map +1 -0
  107. package/lib/typescript/src/services/telemetry/device.d.ts +7 -0
  108. package/lib/typescript/src/services/telemetry/device.d.ts.map +1 -0
  109. package/lib/typescript/src/services/telemetry/index.d.ts +7 -0
  110. package/lib/typescript/src/services/telemetry/index.d.ts.map +1 -0
  111. package/lib/typescript/src/services/telemetry/types.d.ts +50 -0
  112. package/lib/typescript/src/services/telemetry/types.d.ts.map +1 -0
  113. package/lib/typescript/src/support/CSATSurvey.d.ts +20 -0
  114. package/lib/typescript/src/support/CSATSurvey.d.ts.map +1 -0
  115. package/lib/typescript/src/support/EscalationSocket.d.ts +38 -0
  116. package/lib/typescript/src/support/EscalationSocket.d.ts.map +1 -0
  117. package/lib/typescript/src/support/SupportGreeting.d.ts +19 -0
  118. package/lib/typescript/src/support/SupportGreeting.d.ts.map +1 -0
  119. package/lib/typescript/src/support/escalateTool.d.ts +25 -0
  120. package/lib/typescript/src/support/escalateTool.d.ts.map +1 -0
  121. package/lib/typescript/src/support/index.d.ts +11 -0
  122. package/lib/typescript/src/support/index.d.ts.map +1 -0
  123. package/lib/typescript/src/support/supportPrompt.d.ts +12 -0
  124. package/lib/typescript/src/support/supportPrompt.d.ts.map +1 -0
  125. package/lib/typescript/src/support/types.d.ts +114 -0
  126. package/lib/typescript/src/support/types.d.ts.map +1 -0
  127. package/lib/typescript/src/tools/guideTool.d.ts +4 -0
  128. package/lib/typescript/src/tools/guideTool.d.ts.map +1 -0
  129. package/lib/typescript/src/tools/index.d.ts +3 -0
  130. package/lib/typescript/src/tools/index.d.ts.map +1 -1
  131. package/lib/typescript/src/tools/restoreTool.d.ts +3 -0
  132. package/lib/typescript/src/tools/restoreTool.d.ts.map +1 -0
  133. package/lib/typescript/src/tools/simplifyTool.d.ts +3 -0
  134. package/lib/typescript/src/tools/simplifyTool.d.ts.map +1 -0
  135. package/lib/typescript/src/tools/types.d.ts +2 -0
  136. package/lib/typescript/src/tools/types.d.ts.map +1 -1
  137. package/package.json +5 -1
  138. package/src/components/AIAgent.tsx +253 -15
  139. package/src/components/AIZone.tsx +147 -0
  140. package/src/components/AgentErrorBoundary.tsx +10 -0
  141. package/src/components/HighlightOverlay.tsx +136 -0
  142. package/src/components/ProactiveHint.tsx +145 -0
  143. package/src/components/cards/InfoCard.tsx +58 -0
  144. package/src/components/cards/ReviewSummary.tsx +76 -0
  145. package/src/core/AgentRuntime.ts +18 -0
  146. package/src/core/FiberTreeWalker.ts +71 -93
  147. package/src/core/IdleDetector.ts +72 -0
  148. package/src/core/ZoneRegistry.ts +44 -0
  149. package/src/core/systemPrompt.ts +2 -0
  150. package/src/core/types.ts +60 -0
  151. package/src/index.ts +31 -0
  152. package/src/services/AudioOutputService.ts +13 -0
  153. package/src/services/flags/FlagService.ts +137 -0
  154. package/src/services/telemetry/MobileAI.ts +66 -0
  155. package/src/services/telemetry/PiiScrubber.ts +17 -0
  156. package/src/services/telemetry/TelemetryService.ts +291 -0
  157. package/src/services/telemetry/TouchAutoCapture.ts +165 -0
  158. package/src/services/telemetry/device.ts +16 -0
  159. package/src/services/telemetry/index.ts +13 -0
  160. package/src/services/telemetry/types.ts +75 -0
  161. package/src/support/CSATSurvey.tsx +304 -0
  162. package/src/support/EscalationSocket.ts +113 -0
  163. package/src/support/SupportGreeting.tsx +161 -0
  164. package/src/support/escalateTool.ts +134 -0
  165. package/src/support/index.ts +27 -0
  166. package/src/support/supportPrompt.ts +55 -0
  167. package/src/support/types.ts +141 -0
  168. package/src/tools/guideTool.ts +67 -0
  169. package/src/tools/index.ts +3 -0
  170. package/src/tools/restoreTool.ts +33 -0
  171. package/src/tools/simplifyTool.ts +33 -0
  172. package/src/tools/types.ts +2 -0
  173. package/src/types/jsx.d.ts +20 -0
@@ -0,0 +1,260 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * TelemetryService — Batches and sends analytics events to MobileAI Cloud.
5
+ *
6
+ * Features:
7
+ * - Event batching (flush every N seconds or N events)
8
+ * - Offline queue with retry on reconnect
9
+ * - Lightweight — no native dependencies
10
+ * - Opt-in only (requires analyticsKey or analyticsProxyUrl)
11
+ */
12
+
13
+ import { AppState, Platform } from 'react-native';
14
+ import { logger } from "../../utils/logger.js";
15
+ import { scrubPII } from "./PiiScrubber.js";
16
+ import { FlagService } from "../flags/FlagService.js";
17
+
18
+ // Optional: AsyncStorage for offline event persistence
19
+ // SDK works without it — just loses crash recovery for queued events
20
+ let AsyncStorageModule = null;
21
+ try {
22
+ AsyncStorageModule = require('@react-native-async-storage/async-storage').default;
23
+ } catch {
24
+ // Not installed — offline queue persistence disabled
25
+ }
26
+
27
+ // ─── Constants ─────────────────────────────────────────────────
28
+
29
+ const CLOUD_API_URL = 'https://api.maiagent.dev/v1/events';
30
+ const STORAGE_KEY = '@mobileai/telemetry_queue';
31
+ const DEFAULT_FLUSH_INTERVAL_MS = 30_000;
32
+ const DEFAULT_MAX_BATCH_SIZE = 50;
33
+ const SDK_VERSION = '0.10.0';
34
+ const LOG_TAG = 'Telemetry';
35
+
36
+ // ─── Utility ───────────────────────────────────────────────────
37
+
38
+ function generateSessionId() {
39
+ return `${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
40
+ }
41
+ import { getDeviceId } from "./device.js";
42
+
43
+ // ─── Service ───────────────────────────────────────────────────
44
+
45
+ export class TelemetryService {
46
+ queue = [];
47
+ currentScreen = 'Unknown';
48
+ flushTimer = null;
49
+ isFlushing = false;
50
+ appStateSubscription = null;
51
+
52
+ /** Public getter for the current screen, used by auto-capture utilities */
53
+ get screen() {
54
+ return this.currentScreen;
55
+ }
56
+
57
+ /**
58
+ * True while the AI agent is executing a tool (tap, type, navigate, etc.).
59
+ * The touch interceptor checks this flag to avoid double-counting AI actions
60
+ * as human interactions. Agent steps are already tracked as agent_step events.
61
+ */
62
+ isAgentActing = false;
63
+ /** Set by AgentRuntime before/after each tool execution. */
64
+ setAgentActing(active) {
65
+ this.isAgentActing = active;
66
+ }
67
+ constructor(config) {
68
+ this.config = config;
69
+ this.sessionId = generateSessionId();
70
+
71
+ // Extract base URL for flags API (e.g. drop /v1/events)
72
+ let baseUrl = 'https://api.maiagent.dev';
73
+ try {
74
+ if (config.analyticsProxyUrl) {
75
+ baseUrl = new URL(config.analyticsProxyUrl).origin;
76
+ }
77
+ } catch {}
78
+ this.flags = new FlagService(baseUrl);
79
+ }
80
+
81
+ // ─── Lifecycle ──────────────────────────────────────────────
82
+
83
+ /** Start the telemetry service (call on mount) */
84
+ async start() {
85
+ if (!this.isEnabled()) {
86
+ logger.debug(LOG_TAG, 'Disabled — no analyticsKey or proxyUrl');
87
+ return;
88
+ }
89
+
90
+ // Restore queued events from previous session
91
+ await this.restoreQueue();
92
+
93
+ // Fetch feature flags asynchronously (do not block startup)
94
+ if (this.config.analyticsKey) {
95
+ this.flags.fetch(this.config.analyticsKey).catch(e => logger.warn(LOG_TAG, `Could not sync flags: ${e.message}`));
96
+ }
97
+
98
+ // Start periodic flush
99
+ const interval = this.config.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS;
100
+ this.flushTimer = setInterval(() => this.flush(), interval);
101
+
102
+ // Flush on app background
103
+ this.appStateSubscription = AppState.addEventListener('change', state => {
104
+ if (state === 'background' || state === 'inactive') {
105
+ this.flush();
106
+ }
107
+ });
108
+
109
+ // Track session start
110
+ this.track('session_start', {
111
+ device: Platform.OS,
112
+ os: String(Platform.Version),
113
+ sdk_version: SDK_VERSION
114
+ });
115
+ logger.info(LOG_TAG, `Started (session: ${this.sessionId})`);
116
+ }
117
+
118
+ /** Stop the telemetry service (call on unmount) */
119
+ async stop() {
120
+ if (!this.isEnabled()) return;
121
+
122
+ // Track session end
123
+ this.track('session_end', {
124
+ events_count: this.queue.length
125
+ });
126
+
127
+ // Final flush
128
+ await this.flush();
129
+
130
+ // Cleanup
131
+ if (this.flushTimer) {
132
+ clearInterval(this.flushTimer);
133
+ this.flushTimer = null;
134
+ }
135
+ if (this.appStateSubscription) {
136
+ this.appStateSubscription.remove();
137
+ this.appStateSubscription = null;
138
+ }
139
+ logger.info(LOG_TAG, 'Stopped');
140
+ }
141
+
142
+ // ─── Public API ─────────────────────────────────────────────
143
+
144
+ /** Track an event (auto or custom) */
145
+ track(type, data = {}) {
146
+ if (!this.isEnabled()) return;
147
+
148
+ // Sanitize any string values in the data payload to remove PII
149
+ const sanitizedData = Object.fromEntries(Object.entries(data).map(([k, v]) => [k, typeof v === 'string' ? scrubPII(v) : v]));
150
+
151
+ // Auto-append active feature flags
152
+ sanitizedData.$flags = this.flags.getAllFlags();
153
+ const event = {
154
+ type,
155
+ data: sanitizedData,
156
+ timestamp: new Date().toISOString(),
157
+ screen: this.currentScreen,
158
+ sessionId: this.sessionId
159
+ };
160
+ this.queue.push(event);
161
+ if (this.config.debug) {
162
+ logger.debug(LOG_TAG, `→ ${type}`, data);
163
+ }
164
+
165
+ // Auto-flush if batch is full
166
+ const maxSize = this.config.maxBatchSize ?? DEFAULT_MAX_BATCH_SIZE;
167
+ if (this.queue.length >= maxSize) {
168
+ this.flush();
169
+ }
170
+ }
171
+
172
+ /** Update current screen (called by AIAgent on navigation) */
173
+ setScreen(screenName) {
174
+ if (this.currentScreen !== screenName) {
175
+ const prevScreen = this.currentScreen;
176
+ this.currentScreen = screenName;
177
+ this.track('screen_view', {
178
+ screen: screenName,
179
+ prev_screen: prevScreen
180
+ });
181
+ }
182
+ }
183
+
184
+ // ─── Flush ──────────────────────────────────────────────────
185
+
186
+ /** Send queued events to the cloud API */
187
+ async flush() {
188
+ if (!this.isEnabled() || this.queue.length === 0 || this.isFlushing) return;
189
+ this.isFlushing = true;
190
+ const eventsToSend = [...this.queue];
191
+ this.queue = [];
192
+ try {
193
+ const url = this.config.analyticsProxyUrl ?? CLOUD_API_URL;
194
+ const headers = {
195
+ 'Content-Type': 'application/json',
196
+ ...(this.config.analyticsProxyHeaders ?? {})
197
+ };
198
+ const batch = {
199
+ analyticsKey: this.config.analyticsKey ?? '',
200
+ appId: Platform.OS,
201
+ // Consumer can override via config later
202
+ deviceId: getDeviceId(),
203
+ sdkVersion: SDK_VERSION,
204
+ events: eventsToSend
205
+ };
206
+ const response = await fetch(url, {
207
+ method: 'POST',
208
+ headers,
209
+ body: JSON.stringify(batch)
210
+ });
211
+ if (!response.ok) {
212
+ throw new Error(`HTTP ${response.status}`);
213
+ }
214
+ logger.info(LOG_TAG, `Flushed ${eventsToSend.length} events`);
215
+ } catch (error) {
216
+ // Re-queue failed events for retry
217
+ this.queue = [...eventsToSend, ...this.queue];
218
+ await this.persistQueue();
219
+ logger.warn(LOG_TAG, `Flush failed (${eventsToSend.length} events re-queued): ${error.message}`);
220
+ } finally {
221
+ this.isFlushing = false;
222
+ }
223
+ }
224
+
225
+ // ─── Persistence (offline support) ──────────────────────────
226
+
227
+ /** Save queued events to AsyncStorage for crash/restart recovery */
228
+ async persistQueue() {
229
+ if (!AsyncStorageModule) return;
230
+ try {
231
+ await AsyncStorageModule.setItem(STORAGE_KEY, JSON.stringify(this.queue));
232
+ } catch {
233
+ // AsyncStorage may not be available in all environments
234
+ }
235
+ }
236
+
237
+ /** Restore queued events from previous session */
238
+ async restoreQueue() {
239
+ if (!AsyncStorageModule) return;
240
+ try {
241
+ const stored = await AsyncStorageModule.getItem(STORAGE_KEY);
242
+ if (stored) {
243
+ const events = JSON.parse(stored);
244
+ this.queue = [...events, ...this.queue];
245
+ await AsyncStorageModule.removeItem(STORAGE_KEY);
246
+ logger.info(LOG_TAG, `Restored ${events.length} events from previous session`);
247
+ }
248
+ } catch {
249
+ // Silently fail — telemetry is non-critical
250
+ }
251
+ }
252
+
253
+ // ─── Helpers ────────────────────────────────────────────────
254
+
255
+ /** Check if telemetry is configured */
256
+ isEnabled() {
257
+ return !!(this.config.analyticsKey || this.config.analyticsProxyUrl);
258
+ }
259
+ }
260
+ //# sourceMappingURL=TelemetryService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["AppState","Platform","logger","scrubPII","FlagService","AsyncStorageModule","require","default","CLOUD_API_URL","STORAGE_KEY","DEFAULT_FLUSH_INTERVAL_MS","DEFAULT_MAX_BATCH_SIZE","SDK_VERSION","LOG_TAG","generateSessionId","Date","now","Math","random","toString","slice","getDeviceId","TelemetryService","queue","currentScreen","flushTimer","isFlushing","appStateSubscription","screen","isAgentActing","setAgentActing","active","constructor","config","sessionId","baseUrl","analyticsProxyUrl","URL","origin","flags","start","isEnabled","debug","restoreQueue","analyticsKey","fetch","catch","e","warn","message","interval","flushIntervalMs","setInterval","flush","addEventListener","state","track","device","OS","os","String","Version","sdk_version","info","stop","events_count","length","clearInterval","remove","type","data","sanitizedData","Object","fromEntries","entries","map","k","v","$flags","getAllFlags","event","timestamp","toISOString","push","maxSize","maxBatchSize","setScreen","screenName","prevScreen","prev_screen","eventsToSend","url","headers","analyticsProxyHeaders","batch","appId","deviceId","sdkVersion","events","response","method","body","JSON","stringify","ok","Error","status","error","persistQueue","setItem","stored","getItem","parse","removeItem"],"sourceRoot":"../../../../src","sources":["services/telemetry/TelemetryService.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,QAAQ,EAAEC,QAAQ,QAAQ,cAAc;AACjD,SAASC,MAAM,QAAQ,uBAAoB;AAM3C,SAASC,QAAQ,QAAQ,kBAAe;AACxC,SAASC,WAAW,QAAQ,yBAAsB;;AAElD;AACA;AACA,IAAIC,kBAAuB,GAAG,IAAI;AAClC,IAAI;EACFA,kBAAkB,GAAGC,OAAO,CAAC,2CAA2C,CAAC,CAACC,OAAO;AACnF,CAAC,CAAC,MAAM;EACN;AAAA;;AAGF;;AAEA,MAAMC,aAAa,GAAG,oCAAoC;AAC1D,MAAMC,WAAW,GAAG,2BAA2B;AAC/C,MAAMC,yBAAyB,GAAG,MAAM;AACxC,MAAMC,sBAAsB,GAAG,EAAE;AACjC,MAAMC,WAAW,GAAG,QAAQ;AAC5B,MAAMC,OAAO,GAAG,WAAW;;AAE3B;;AAEA,SAASC,iBAAiBA,CAAA,EAAW;EACnC,OAAO,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC,IAAIC,IAAI,CAACC,MAAM,CAAC,CAAC,CAACC,QAAQ,CAAC,EAAE,CAAC,CAACC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE;AACnE;AAEA,SAASC,WAAW,QAAQ,aAAU;;AAEtC;;AAEA,OAAO,MAAMC,gBAAgB,CAAC;EACpBC,KAAK,GAAqB,EAAE;EAG5BC,aAAa,GAAG,SAAS;EACzBC,UAAU,GAA0C,IAAI;EACxDC,UAAU,GAAG,KAAK;EAClBC,oBAAoB,GAAwD,IAAI;;EAExF;EACA,IAAIC,MAAMA,CAAA,EAAW;IACnB,OAAO,IAAI,CAACJ,aAAa;EAC3B;;EAEA;AACF;AACA;AACA;AACA;EACEK,aAAa,GAAG,KAAK;EAIrB;EACAC,cAAcA,CAACC,MAAe,EAAQ;IACpC,IAAI,CAACF,aAAa,GAAGE,MAAM;EAC7B;EAEAC,WAAWA,CAACC,MAAuB,EAAE;IACnC,IAAI,CAACA,MAAM,GAAGA,MAAM;IACpB,IAAI,CAACC,SAAS,GAAGpB,iBAAiB,CAAC,CAAC;;IAEpC;IACA,IAAIqB,OAAO,GAAG,0BAA0B;IACxC,IAAI;MACF,IAAIF,MAAM,CAACG,iBAAiB,EAAE;QAC5BD,OAAO,GAAG,IAAIE,GAAG,CAACJ,MAAM,CAACG,iBAAiB,CAAC,CAACE,MAAM;MACpD;IACF,CAAC,CAAC,MAAM,CAAC;IACT,IAAI,CAACC,KAAK,GAAG,IAAInC,WAAW,CAAC+B,OAAO,CAAC;EACvC;;EAEA;;EAEA;EACA,MAAMK,KAAKA,CAAA,EAAkB;IAC3B,IAAI,CAAC,IAAI,CAACC,SAAS,CAAC,CAAC,EAAE;MACrBvC,MAAM,CAACwC,KAAK,CAAC7B,OAAO,EAAE,wCAAwC,CAAC;MAC/D;IACF;;IAEA;IACA,MAAM,IAAI,CAAC8B,YAAY,CAAC,CAAC;;IAEzB;IACA,IAAI,IAAI,CAACV,MAAM,CAACW,YAAY,EAAE;MAC5B,IAAI,CAACL,KAAK,CAACM,KAAK,CAAC,IAAI,CAACZ,MAAM,CAACW,YAAY,CAAC,CAACE,KAAK,CAAEC,CAAC,IACjD7C,MAAM,CAAC8C,IAAI,CAACnC,OAAO,EAAE,yBAAyBkC,CAAC,CAACE,OAAO,EAAE,CAC3D,CAAC;IACH;;IAEA;IACA,MAAMC,QAAQ,GAAG,IAAI,CAACjB,MAAM,CAACkB,eAAe,IAAIzC,yBAAyB;IACzE,IAAI,CAACe,UAAU,GAAG2B,WAAW,CAAC,MAAM,IAAI,CAACC,KAAK,CAAC,CAAC,EAAEH,QAAQ,CAAC;;IAE3D;IACA,IAAI,CAACvB,oBAAoB,GAAG3B,QAAQ,CAACsD,gBAAgB,CACnD,QAAQ,EACPC,KAAK,IAAK;MACT,IAAIA,KAAK,KAAK,YAAY,IAAIA,KAAK,KAAK,UAAU,EAAE;QAClD,IAAI,CAACF,KAAK,CAAC,CAAC;MACd;IACF,CACF,CAAC;;IAED;IACA,IAAI,CAACG,KAAK,CAAC,eAAe,EAAE;MAC1BC,MAAM,EAAExD,QAAQ,CAACyD,EAAE;MACnBC,EAAE,EAAEC,MAAM,CAAC3D,QAAQ,CAAC4D,OAAO,CAAC;MAC5BC,WAAW,EAAElD;IACf,CAAC,CAAC;IAEFV,MAAM,CAAC6D,IAAI,CAAClD,OAAO,EAAE,qBAAqB,IAAI,CAACqB,SAAS,GAAG,CAAC;EAC9D;;EAEA;EACA,MAAM8B,IAAIA,CAAA,EAAkB;IAC1B,IAAI,CAAC,IAAI,CAACvB,SAAS,CAAC,CAAC,EAAE;;IAEvB;IACA,IAAI,CAACe,KAAK,CAAC,aAAa,EAAE;MACxBS,YAAY,EAAE,IAAI,CAAC1C,KAAK,CAAC2C;IAC3B,CAAC,CAAC;;IAEF;IACA,MAAM,IAAI,CAACb,KAAK,CAAC,CAAC;;IAElB;IACA,IAAI,IAAI,CAAC5B,UAAU,EAAE;MACnB0C,aAAa,CAAC,IAAI,CAAC1C,UAAU,CAAC;MAC9B,IAAI,CAACA,UAAU,GAAG,IAAI;IACxB;IACA,IAAI,IAAI,CAACE,oBAAoB,EAAE;MAC7B,IAAI,CAACA,oBAAoB,CAACyC,MAAM,CAAC,CAAC;MAClC,IAAI,CAACzC,oBAAoB,GAAG,IAAI;IAClC;IAEAzB,MAAM,CAAC6D,IAAI,CAAClD,OAAO,EAAE,SAAS,CAAC;EACjC;;EAEA;;EAEA;EACA2C,KAAKA,CAACa,IAAY,EAAEC,IAA6B,GAAG,CAAC,CAAC,EAAQ;IAC5D,IAAI,CAAC,IAAI,CAAC7B,SAAS,CAAC,CAAC,EAAE;;IAEvB;IACA,MAAM8B,aAAa,GAAGC,MAAM,CAACC,WAAW,CACtCD,MAAM,CAACE,OAAO,CAACJ,IAAI,CAAC,CAACK,GAAG,CAAC,CAAC,CAACC,CAAC,EAAEC,CAAC,CAAC,KAAK,CACnCD,CAAC,EACD,OAAOC,CAAC,KAAK,QAAQ,GAAG1E,QAAQ,CAAC0E,CAAC,CAAC,GAAGA,CAAC,CACxC,CACH,CAAC;;IAED;IACAN,aAAa,CAACO,MAAM,GAAG,IAAI,CAACvC,KAAK,CAACwC,WAAW,CAAC,CAAC;IAE/C,MAAMC,KAAqB,GAAG;MAC5BX,IAAI;MACJC,IAAI,EAAEC,aAAa;MACnBU,SAAS,EAAE,IAAIlE,IAAI,CAAC,CAAC,CAACmE,WAAW,CAAC,CAAC;MACnCtD,MAAM,EAAE,IAAI,CAACJ,aAAa;MAC1BU,SAAS,EAAE,IAAI,CAACA;IAClB,CAAC;IAED,IAAI,CAACX,KAAK,CAAC4D,IAAI,CAACH,KAAK,CAAC;IAEtB,IAAI,IAAI,CAAC/C,MAAM,CAACS,KAAK,EAAE;MACrBxC,MAAM,CAACwC,KAAK,CAAC7B,OAAO,EAAE,KAAKwD,IAAI,EAAE,EAAEC,IAAI,CAAC;IAC1C;;IAEA;IACA,MAAMc,OAAO,GAAG,IAAI,CAACnD,MAAM,CAACoD,YAAY,IAAI1E,sBAAsB;IAClE,IAAI,IAAI,CAACY,KAAK,CAAC2C,MAAM,IAAIkB,OAAO,EAAE;MAChC,IAAI,CAAC/B,KAAK,CAAC,CAAC;IACd;EACF;;EAEA;EACAiC,SAASA,CAACC,UAAkB,EAAQ;IAClC,IAAI,IAAI,CAAC/D,aAAa,KAAK+D,UAAU,EAAE;MACrC,MAAMC,UAAU,GAAG,IAAI,CAAChE,aAAa;MACrC,IAAI,CAACA,aAAa,GAAG+D,UAAU;MAE/B,IAAI,CAAC/B,KAAK,CAAC,aAAa,EAAE;QACxB5B,MAAM,EAAE2D,UAAU;QAClBE,WAAW,EAAED;MACf,CAAC,CAAC;IACJ;EACF;;EAEA;;EAEA;EACA,MAAMnC,KAAKA,CAAA,EAAkB;IAC3B,IAAI,CAAC,IAAI,CAACZ,SAAS,CAAC,CAAC,IAAI,IAAI,CAAClB,KAAK,CAAC2C,MAAM,KAAK,CAAC,IAAI,IAAI,CAACxC,UAAU,EAAE;IAErE,IAAI,CAACA,UAAU,GAAG,IAAI;IACtB,MAAMgE,YAAY,GAAG,CAAC,GAAG,IAAI,CAACnE,KAAK,CAAC;IACpC,IAAI,CAACA,KAAK,GAAG,EAAE;IAEf,IAAI;MACF,MAAMoE,GAAG,GAAG,IAAI,CAAC1D,MAAM,CAACG,iBAAiB,IAAI5B,aAAa;MAC1D,MAAMoF,OAA+B,GAAG;QACtC,cAAc,EAAE,kBAAkB;QAClC,IAAI,IAAI,CAAC3D,MAAM,CAAC4D,qBAAqB,IAAI,CAAC,CAAC;MAC7C,CAAC;MAED,MAAMC,KAAqB,GAAG;QAC5BlD,YAAY,EAAE,IAAI,CAACX,MAAM,CAACW,YAAY,IAAI,EAAE;QAC5CmD,KAAK,EAAE9F,QAAQ,CAACyD,EAAE;QAAE;QACpBsC,QAAQ,EAAE3E,WAAW,CAAC,CAAC;QACvB4E,UAAU,EAAErF,WAAW;QACvBsF,MAAM,EAAER;MACV,CAAC;MAED,MAAMS,QAAQ,GAAG,MAAMtD,KAAK,CAAC8C,GAAG,EAAE;QAChCS,MAAM,EAAE,MAAM;QACdR,OAAO;QACPS,IAAI,EAAEC,IAAI,CAACC,SAAS,CAACT,KAAK;MAC5B,CAAC,CAAC;MAEF,IAAI,CAACK,QAAQ,CAACK,EAAE,EAAE;QAChB,MAAM,IAAIC,KAAK,CAAC,QAAQN,QAAQ,CAACO,MAAM,EAAE,CAAC;MAC5C;MAEAxG,MAAM,CAAC6D,IAAI,CAAClD,OAAO,EAAE,WAAW6E,YAAY,CAACxB,MAAM,SAAS,CAAC;IAC/D,CAAC,CAAC,OAAOyC,KAAU,EAAE;MACnB;MACA,IAAI,CAACpF,KAAK,GAAG,CAAC,GAAGmE,YAAY,EAAE,GAAG,IAAI,CAACnE,KAAK,CAAC;MAC7C,MAAM,IAAI,CAACqF,YAAY,CAAC,CAAC;MAEzB1G,MAAM,CAAC8C,IAAI,CAACnC,OAAO,EAAE,iBAAiB6E,YAAY,CAACxB,MAAM,uBAAuByC,KAAK,CAAC1D,OAAO,EAAE,CAAC;IAClG,CAAC,SAAS;MACR,IAAI,CAACvB,UAAU,GAAG,KAAK;IACzB;EACF;;EAEA;;EAEA;EACA,MAAckF,YAAYA,CAAA,EAAkB;IAC1C,IAAI,CAACvG,kBAAkB,EAAE;IACzB,IAAI;MACF,MAAMA,kBAAkB,CAACwG,OAAO,CAACpG,WAAW,EAAE6F,IAAI,CAACC,SAAS,CAAC,IAAI,CAAChF,KAAK,CAAC,CAAC;IAC3E,CAAC,CAAC,MAAM;MACN;IAAA;EAEJ;;EAEA;EACA,MAAcoB,YAAYA,CAAA,EAAkB;IAC1C,IAAI,CAACtC,kBAAkB,EAAE;IACzB,IAAI;MACF,MAAMyG,MAAM,GAAG,MAAMzG,kBAAkB,CAAC0G,OAAO,CAACtG,WAAW,CAAC;MAC5D,IAAIqG,MAAM,EAAE;QACV,MAAMZ,MAAwB,GAAGI,IAAI,CAACU,KAAK,CAACF,MAAM,CAAC;QACnD,IAAI,CAACvF,KAAK,GAAG,CAAC,GAAG2E,MAAM,EAAE,GAAG,IAAI,CAAC3E,KAAK,CAAC;QACvC,MAAMlB,kBAAkB,CAAC4G,UAAU,CAACxG,WAAW,CAAC;QAChDP,MAAM,CAAC6D,IAAI,CAAClD,OAAO,EAAE,YAAYqF,MAAM,CAAChC,MAAM,+BAA+B,CAAC;MAChF;IACF,CAAC,CAAC,MAAM;MACN;IAAA;EAEJ;;EAEA;;EAEA;EACQzB,SAASA,CAAA,EAAY;IAC3B,OAAO,CAAC,EAAE,IAAI,CAACR,MAAM,CAACW,YAAY,IAAI,IAAI,CAACX,MAAM,CAACG,iBAAiB,CAAC;EACtE;AACF","ignoreList":[]}
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * TouchAutoCapture — Extracts a human-readable label from a React Native
5
+ * touch event target by walking up the native view hierarchy.
6
+ *
7
+ * Used by AIAgent to auto-track every tap in the app without
8
+ * any developer code changes (zero-config analytics).
9
+ *
10
+ * Strategy:
11
+ * 1. Read the touched element's accessibilityLabel (best signal).
12
+ * 2. If none, use React Native's internal _children to find nested text.
13
+ * 3. Fallback to the component's testID.
14
+ * 4. Last resort: "Unknown Element".
15
+ */
16
+
17
+ // React Native imports not needed — we use Fiber internals directly
18
+
19
+ const recentTaps = [];
20
+ const RAGE_WINDOW_MS = 2000;
21
+ const RAGE_THRESHOLD = 3;
22
+
23
+ /**
24
+ * Checks if the user is repeatedly tapping the same element in frustration.
25
+ * If rage click detected, emits 'rage_click' event to telemetry.
26
+ */
27
+ export function checkRageClick(label, telemetry) {
28
+ const now = Date.now();
29
+ recentTaps.push({
30
+ label,
31
+ ts: now
32
+ });
33
+
34
+ // Keep buffer unbounded size of 5
35
+ if (recentTaps.length > 5) recentTaps.shift();
36
+ const recent = recentTaps.filter(t => t.label === label && now - t.ts < RAGE_WINDOW_MS);
37
+ if (recent.length >= RAGE_THRESHOLD) {
38
+ telemetry.track('rage_click', {
39
+ label,
40
+ count: recent.length,
41
+ screen: telemetry.screen
42
+ });
43
+ recentTaps.length = 0; // reset buffer after emitting to avoid spam
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Extract a label from a GestureResponderEvent's native target.
49
+ *
50
+ * @param nativeEvent - The nativeEvent from onStartShouldSetResponderCapture
51
+ * @param rootRef - The root View ref (to resolve relative positions)
52
+ * @returns A descriptive label string for the tapped element
53
+ */
54
+ export function extractTouchLabel(nativeEvent) {
55
+ // Try accessible properties first (most reliable)
56
+ const target = nativeEvent?.target;
57
+ if (!target) return 'Unknown Element';
58
+
59
+ // React Native internal: _internalFiberInstanceHandleDEV or _nativeTag
60
+ // We can walk the Fiber tree from the target to find text
61
+ try {
62
+ // Strategy 1: Walk up the Fiber tree from the touched element
63
+ let fiber = getFiberFromNativeTag(target);
64
+ if (fiber) {
65
+ // Walk up looking for text content or accessibility labels
66
+ let current = fiber;
67
+ let depth = 0;
68
+ const MAX_DEPTH = 10;
69
+ while (current && depth < MAX_DEPTH) {
70
+ // Check for accessibilityLabel
71
+ if (current.memoizedProps?.accessibilityLabel) {
72
+ return current.memoizedProps.accessibilityLabel;
73
+ }
74
+
75
+ // Check for testID
76
+ if (current.memoizedProps?.testID) {
77
+ return current.memoizedProps.testID;
78
+ }
79
+
80
+ // Check for title (Button component)
81
+ if (current.memoizedProps?.title) {
82
+ return current.memoizedProps.title;
83
+ }
84
+
85
+ // Check for placeholder (TextInput)
86
+ if (current.memoizedProps?.placeholder) {
87
+ return `Input: ${current.memoizedProps.placeholder}`;
88
+ }
89
+
90
+ // Check if this is a Text node with children string
91
+ if (typeof current.memoizedProps?.children === 'string' && current.memoizedProps.children.trim()) {
92
+ return current.memoizedProps.children.trim();
93
+ }
94
+
95
+ // Check for nested text in children array
96
+ if (Array.isArray(current.memoizedProps?.children)) {
97
+ const textChild = findTextInChildren(current.memoizedProps.children);
98
+ if (textChild) return textChild;
99
+ }
100
+ current = current.return;
101
+ depth++;
102
+ }
103
+ }
104
+ } catch {
105
+ // Fiber access failed — fall back gracefully
106
+ }
107
+ return 'Unknown Element';
108
+ }
109
+
110
+ /**
111
+ * Find the first string text in a React children tree (recursive, max 3 levels).
112
+ */
113
+ function findTextInChildren(children, depth = 0) {
114
+ if (depth > 3) return null;
115
+ for (const child of children) {
116
+ if (typeof child === 'string' && child.trim()) {
117
+ return child.trim();
118
+ }
119
+ if (typeof child === 'number') {
120
+ return String(child);
121
+ }
122
+ // React element with props.children
123
+ if (child?.props?.children) {
124
+ if (typeof child.props.children === 'string' && child.props.children.trim()) {
125
+ return child.props.children.trim();
126
+ }
127
+ if (Array.isArray(child.props.children)) {
128
+ const found = findTextInChildren(child.props.children, depth + 1);
129
+ if (found) return found;
130
+ }
131
+ }
132
+ }
133
+ return null;
134
+ }
135
+
136
+ /**
137
+ * Attempt to get the Fiber node from a native tag (React Native internal).
138
+ * This uses the same technique as React DevTools and testing libraries.
139
+ */
140
+ function getFiberFromNativeTag(nativeTag) {
141
+ try {
142
+ // React Native stores a reference from native tag → Fiber
143
+ // via the __internalInstanceHandle on the native node
144
+ const instance = globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__;
145
+ if (instance?.renderers) {
146
+ for (const [, renderer] of instance.renderers) {
147
+ if (renderer?.findFiberByHostInstance) {
148
+ // Try to find via the devtools hook
149
+ const fiber = renderer.findFiberByHostInstance(nativeTag);
150
+ if (fiber) return fiber;
151
+ }
152
+ }
153
+ }
154
+ } catch {
155
+ // DevTools hook not available — expected in production
156
+ }
157
+ return null;
158
+ }
159
+ //# sourceMappingURL=TouchAutoCapture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["recentTaps","RAGE_WINDOW_MS","RAGE_THRESHOLD","checkRageClick","label","telemetry","now","Date","push","ts","length","shift","recent","filter","t","track","count","screen","extractTouchLabel","nativeEvent","target","fiber","getFiberFromNativeTag","current","depth","MAX_DEPTH","memoizedProps","accessibilityLabel","testID","title","placeholder","children","trim","Array","isArray","textChild","findTextInChildren","return","child","String","props","found","nativeTag","instance","globalThis","__REACT_DEVTOOLS_GLOBAL_HOOK__","renderers","renderer","findFiberByHostInstance"],"sourceRoot":"../../../../src","sources":["services/telemetry/TouchAutoCapture.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ import { Platform } from 'react-native';
4
+
5
+ /**
6
+ * Deterministic device ID based on platform info.
7
+ * This ensures analytics and flags remain consistent across sessions
8
+ * without collecting PII hardware identifiers.
9
+ */
10
+ export function getDeviceId() {
11
+ const raw = `${Platform.OS}_${Platform.Version}`;
12
+ let hash = 0;
13
+ for (let i = 0; i < raw.length; i++) {
14
+ hash = (hash << 5) - hash + raw.charCodeAt(i);
15
+ hash |= 0;
16
+ }
17
+ return `dev_${Math.abs(hash).toString(36)}`;
18
+ }
19
+ //# sourceMappingURL=device.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Platform","getDeviceId","raw","OS","Version","hash","i","length","charCodeAt","Math","abs","toString"],"sourceRoot":"../../../../src","sources":["services/telemetry/device.ts"],"mappings":";;AAAA,SAASA,QAAQ,QAAQ,cAAc;;AAEvC;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,WAAWA,CAAA,EAAW;EACpC,MAAMC,GAAG,GAAG,GAAGF,QAAQ,CAACG,EAAE,IAAIH,QAAQ,CAACI,OAAO,EAAE;EAChD,IAAIC,IAAI,GAAG,CAAC;EACZ,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGJ,GAAG,CAACK,MAAM,EAAED,CAAC,EAAE,EAAE;IACnCD,IAAI,GAAG,CAACA,IAAI,IAAI,CAAC,IAAIA,IAAI,GAAGH,GAAG,CAACM,UAAU,CAACF,CAAC,CAAC;IAC7CD,IAAI,IAAI,CAAC;EACX;EACA,OAAO,OAAOI,IAAI,CAACC,GAAG,CAACL,IAAI,CAAC,CAACM,QAAQ,CAAC,EAAE,CAAC,EAAE;AAC7C","ignoreList":[]}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Telemetry module barrel export.
5
+ */
6
+
7
+ export { TelemetryService } from "./TelemetryService.js";
8
+ export { MobileAI, bindTelemetryService } from "./MobileAI.js";
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["TelemetryService","MobileAI","bindTelemetryService"],"sourceRoot":"../../../../src","sources":["services/telemetry/index.ts"],"mappings":";;AAAA;AACA;AACA;;AAEA,SAASA,gBAAgB,QAAQ,uBAAoB;AACrD,SAASC,QAAQ,EAAEC,oBAAoB,QAAQ,eAAY","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"../../../../src","sources":["services/telemetry/types.ts"],"mappings":"","ignoreList":[]}