react-native-agentic-ai 0.0.2 → 0.3.0

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 (70) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +252 -14
  3. package/lib/module/components/AIAgent.js +185 -0
  4. package/lib/module/components/AIAgent.js.map +1 -0
  5. package/lib/module/components/AgentChatBar.js +268 -0
  6. package/lib/module/components/AgentChatBar.js.map +1 -0
  7. package/lib/module/components/AgentOverlay.js +53 -0
  8. package/lib/module/components/AgentOverlay.js.map +1 -0
  9. package/lib/module/core/AgentRuntime.js +640 -0
  10. package/lib/module/core/AgentRuntime.js.map +1 -0
  11. package/lib/module/core/FiberTreeWalker.js +362 -0
  12. package/lib/module/core/FiberTreeWalker.js.map +1 -0
  13. package/lib/module/core/MCPBridge.js +98 -0
  14. package/lib/module/core/MCPBridge.js.map +1 -0
  15. package/lib/module/core/ScreenDehydrator.js +46 -0
  16. package/lib/module/core/ScreenDehydrator.js.map +1 -0
  17. package/lib/module/core/systemPrompt.js +164 -0
  18. package/lib/module/core/systemPrompt.js.map +1 -0
  19. package/lib/module/core/types.js +2 -0
  20. package/lib/module/core/types.js.map +1 -0
  21. package/lib/module/hooks/useAction.js +32 -0
  22. package/lib/module/hooks/useAction.js.map +1 -0
  23. package/lib/module/index.js +17 -0
  24. package/lib/module/index.js.map +1 -0
  25. package/lib/module/package.json +1 -0
  26. package/lib/module/providers/GeminiProvider.js +294 -0
  27. package/lib/module/providers/GeminiProvider.js.map +1 -0
  28. package/lib/module/utils/logger.js +17 -0
  29. package/lib/module/utils/logger.js.map +1 -0
  30. package/lib/typescript/package.json +1 -0
  31. package/lib/typescript/src/components/AIAgent.d.ts +65 -0
  32. package/lib/typescript/src/components/AIAgent.d.ts.map +1 -0
  33. package/lib/typescript/src/components/AgentChatBar.d.ts +15 -0
  34. package/lib/typescript/src/components/AgentChatBar.d.ts.map +1 -0
  35. package/lib/typescript/src/components/AgentOverlay.d.ts +10 -0
  36. package/lib/typescript/src/components/AgentOverlay.d.ts.map +1 -0
  37. package/lib/typescript/src/core/AgentRuntime.d.ts +53 -0
  38. package/lib/typescript/src/core/AgentRuntime.d.ts.map +1 -0
  39. package/lib/typescript/src/core/FiberTreeWalker.d.ts +31 -0
  40. package/lib/typescript/src/core/FiberTreeWalker.d.ts.map +1 -0
  41. package/lib/typescript/src/core/MCPBridge.d.ts +23 -0
  42. package/lib/typescript/src/core/MCPBridge.d.ts.map +1 -0
  43. package/lib/typescript/src/core/ScreenDehydrator.d.ts +20 -0
  44. package/lib/typescript/src/core/ScreenDehydrator.d.ts.map +1 -0
  45. package/lib/typescript/src/core/systemPrompt.d.ts +9 -0
  46. package/lib/typescript/src/core/systemPrompt.d.ts.map +1 -0
  47. package/lib/typescript/src/core/types.d.ts +176 -0
  48. package/lib/typescript/src/core/types.d.ts.map +1 -0
  49. package/lib/typescript/src/hooks/useAction.d.ts +13 -0
  50. package/lib/typescript/src/hooks/useAction.d.ts.map +1 -0
  51. package/lib/typescript/src/index.d.ts +10 -0
  52. package/lib/typescript/src/index.d.ts.map +1 -0
  53. package/lib/typescript/src/providers/GeminiProvider.d.ts +43 -0
  54. package/lib/typescript/src/providers/GeminiProvider.d.ts.map +1 -0
  55. package/lib/typescript/src/utils/logger.d.ts +7 -0
  56. package/lib/typescript/src/utils/logger.d.ts.map +1 -0
  57. package/package.json +135 -12
  58. package/src/components/AIAgent.tsx +262 -0
  59. package/src/components/AgentChatBar.tsx +258 -0
  60. package/src/components/AgentOverlay.tsx +48 -0
  61. package/src/core/AgentRuntime.ts +661 -0
  62. package/src/core/FiberTreeWalker.ts +404 -0
  63. package/src/core/MCPBridge.ts +110 -0
  64. package/src/core/ScreenDehydrator.ts +53 -0
  65. package/src/core/systemPrompt.ts +162 -0
  66. package/src/core/types.ts +233 -0
  67. package/src/hooks/useAction.ts +40 -0
  68. package/src/index.ts +22 -0
  69. package/src/providers/GeminiProvider.ts +283 -0
  70. package/src/utils/logger.ts +21 -0
@@ -0,0 +1,362 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * FiberTreeWalker — Traverses React's Fiber tree to discover interactive elements.
5
+ *
6
+ * This is the React Native equivalent of page-agent.js reading the DOM.
7
+ * Instead of traversing HTML nodes, we traverse React Fiber nodes and detect
8
+ * interactive elements by their type and props (onPress, onChangeText, etc.).
9
+ *
10
+ * Architecture inspired by: https://github.com/alibaba/page-agent
11
+ */
12
+
13
+ import { logger } from "../utils/logger.js";
14
+
15
+ // ─── Walk Configuration (mirrors page-agent DomConfig) ─────────
16
+
17
+ // ─── Fiber Node Type Detection ─────────────────────────────────
18
+
19
+ /** React Native component names that are inherently interactive */
20
+ const PRESSABLE_TYPES = new Set(['Pressable', 'TouchableOpacity', 'TouchableHighlight', 'TouchableWithoutFeedback', 'TouchableNativeFeedback', 'Button']);
21
+ const TEXT_INPUT_TYPES = new Set(['TextInput', 'RCTSinglelineTextInputView', 'RCTMultilineTextInputView']);
22
+ const SWITCH_TYPES = new Set(['Switch', 'RCTSwitch']);
23
+ const TEXT_TYPES = new Set(['Text', 'RCTText']);
24
+ // ScrollView/FlatList/SectionList detection can be added later for scroll tool
25
+
26
+ // ─── State Extraction (mirrors page-agent DEFAULT_INCLUDE_ATTRIBUTES) ──
27
+
28
+ /** Props to extract as state attributes — covers lazy devs who skip accessibility */
29
+ const STATE_PROPS = ['value', 'checked', 'selected', 'active', 'on', 'isOn', 'toggled', 'enabled'];
30
+
31
+ /**
32
+ * Extract state attributes from a fiber node's props.
33
+ * Mirrors page-agent's DEFAULT_INCLUDE_ATTRIBUTES extraction.
34
+ * Priority: accessibilityState > accessibilityRole > direct scalar props.
35
+ */
36
+ function extractStateAttributes(props) {
37
+ const parts = [];
38
+
39
+ // Priority 1: accessibilityState (proper ARIA equivalent)
40
+ if (props.accessibilityState && typeof props.accessibilityState === 'object') {
41
+ for (const [k, v] of Object.entries(props.accessibilityState)) {
42
+ if (v !== undefined) parts.push(`${k}="${v}"`);
43
+ }
44
+ }
45
+
46
+ // Priority 2: accessibilityRole
47
+ if (props.accessibilityRole) {
48
+ parts.push(`role="${props.accessibilityRole}"`);
49
+ }
50
+
51
+ // Priority 3: Direct scalar props fallback (lazy developer support)
52
+ for (const key of STATE_PROPS) {
53
+ if (props[key] !== undefined && typeof props[key] !== 'function' && typeof props[key] !== 'object') {
54
+ parts.push(`${key}="${props[key]}"`);
55
+ }
56
+ }
57
+ return parts.join(' ');
58
+ }
59
+
60
+ /**
61
+ * Check if a node has ANY event handler prop (on* function).
62
+ * Mirrors RNTL's getEventHandlerFromProps pattern.
63
+ */
64
+ export function hasAnyEventHandler(props) {
65
+ if (!props || typeof props !== 'object') return false;
66
+ for (const key of Object.keys(props)) {
67
+ if (key.startsWith('on') && typeof props[key] === 'function') {
68
+ return true;
69
+ }
70
+ }
71
+ return false;
72
+ }
73
+
74
+ // ─── Fiber Node Helpers ────────────────────────────────────────
75
+
76
+ /**
77
+ * Get the display name of a Fiber node's component type.
78
+ */
79
+ function getComponentName(fiber) {
80
+ if (!fiber || !fiber.type) return null;
81
+
82
+ // Host components (View, Text, etc.) — type is a string
83
+ if (typeof fiber.type === 'string') return fiber.type;
84
+
85
+ // Function/Class components — type has displayName or name
86
+ if (fiber.type.displayName) return fiber.type.displayName;
87
+ if (fiber.type.name) return fiber.type.name;
88
+
89
+ // ForwardRef components
90
+ if (fiber.type.render?.displayName) return fiber.type.render.displayName;
91
+ if (fiber.type.render?.name) return fiber.type.render.name;
92
+ return null;
93
+ }
94
+
95
+ /**
96
+ * Check if a fiber node represents an interactive element.
97
+ */
98
+ function getElementType(fiber) {
99
+ const name = getComponentName(fiber);
100
+ const props = fiber.memoizedProps || {};
101
+
102
+ // Check by component name (known React Native types)
103
+ if (name && PRESSABLE_TYPES.has(name)) return 'pressable';
104
+ if (name && TEXT_INPUT_TYPES.has(name)) return 'text-input';
105
+ if (name && SWITCH_TYPES.has(name)) return 'switch';
106
+
107
+ // Check by accessibilityRole (covers custom components with proper ARIA)
108
+ const role = props.accessibilityRole || props.role;
109
+ if (role === 'switch') return 'switch';
110
+ if (role === 'button' || role === 'link' || role === 'checkbox' || role === 'radio') {
111
+ return 'pressable';
112
+ }
113
+
114
+ // Check by props — any component with onPress is interactive
115
+ if (props.onPress && typeof props.onPress === 'function') return 'pressable';
116
+
117
+ // TextInput detection by props
118
+ if (props.onChangeText && typeof props.onChangeText === 'function') return 'text-input';
119
+
120
+ // Switch detection by props (custom switches with onValueChange)
121
+ if (props.onValueChange && typeof props.onValueChange === 'function') return 'switch';
122
+ return null;
123
+ }
124
+
125
+ /**
126
+ * Check if element is disabled.
127
+ */
128
+ function isDisabled(fiber) {
129
+ const props = fiber.memoizedProps || {};
130
+ return props.disabled === true || props.editable === false;
131
+ }
132
+
133
+ // ─── Text Extraction ───────────────────────────────────────────
134
+
135
+ /**
136
+ * Recursively extract text content from a fiber's children.
137
+ * Stops at the next interactive element to avoid capturing text from nested buttons.
138
+ */
139
+ function extractTextContent(fiber, maxDepth = 10) {
140
+ if (!fiber || maxDepth <= 0) return '';
141
+ const parts = [];
142
+ let child = fiber.child;
143
+ while (child) {
144
+ const childName = getComponentName(child);
145
+ const childProps = child.memoizedProps || {};
146
+
147
+ // Stop at nested interactive elements
148
+ if (getElementType(child) !== null && child !== fiber) {
149
+ child = child.sibling;
150
+ continue;
151
+ }
152
+
153
+ // Text node — extract content
154
+ if (childName && TEXT_TYPES.has(childName)) {
155
+ const text = extractRawText(childProps.children);
156
+ if (text) parts.push(text);
157
+ } else {
158
+ // Recurse into non-interactive children
159
+ const nestedText = extractTextContent(child, maxDepth - 1);
160
+ if (nestedText) parts.push(nestedText);
161
+ }
162
+ child = child.sibling;
163
+ }
164
+ return parts.join(' ').trim();
165
+ }
166
+
167
+ /**
168
+ * Extract raw text from React children prop.
169
+ * Handles strings, numbers, arrays, and nested structures.
170
+ */
171
+ function extractRawText(children) {
172
+ if (children == null) return '';
173
+ if (typeof children === 'string') return children;
174
+ if (typeof children === 'number') return String(children);
175
+ if (Array.isArray(children)) {
176
+ return children.map(child => extractRawText(child)).filter(Boolean).join(' ');
177
+ }
178
+
179
+ // React element — try to extract text from its props
180
+ if (children && typeof children === 'object' && children.props) {
181
+ return extractRawText(children.props.children);
182
+ }
183
+ return '';
184
+ }
185
+
186
+ /**
187
+ * Get the Fiber root node.
188
+ *
189
+ * In React Native, a View ref gives a native node, NOT a Fiber node.
190
+ * We use __REACT_DEVTOOLS_GLOBAL_HOOK__ (available in dev builds) to
191
+ * access getFiberRoots(), which is the same API React DevTools uses.
192
+ *
193
+ * Falls back to probing the ref's internal keys for Fiber references.
194
+ */
195
+ function getFiberRoot() {
196
+ // Strategy 1: __REACT_DEVTOOLS_GLOBAL_HOOK__ (most reliable in dev)
197
+ try {
198
+ const hook = globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__;
199
+ if (hook) {
200
+ // hook.renderers is a Map of renderer ID → renderer
201
+ // hook.getFiberRoots(rendererId) returns a Set of FiberRoot objects
202
+ const renderers = hook.renderers;
203
+ if (renderers && renderers.size > 0) {
204
+ for (const [rendererId] of renderers) {
205
+ const roots = hook.getFiberRoots(rendererId);
206
+ if (roots && roots.size > 0) {
207
+ // Get the first (and usually only) root
208
+ const fiberRoot = roots.values().next().value;
209
+ if (fiberRoot && fiberRoot.current) {
210
+ logger.debug('FiberTreeWalker', 'Accessed Fiber tree via DevTools hook');
211
+ return fiberRoot.current; // This is the root Fiber node
212
+ }
213
+ }
214
+ }
215
+ }
216
+ }
217
+ } catch (e) {
218
+ logger.debug('FiberTreeWalker', 'DevTools hook not available:', e);
219
+ }
220
+ return null;
221
+ }
222
+ function getFiberFromRef(ref) {
223
+ // First try the DevTools hook (works regardless of what ref is)
224
+ const rootFiber = getFiberRoot();
225
+ if (rootFiber) return rootFiber;
226
+ if (!ref) return null;
227
+
228
+ // Fallback: Try known internal Fiber access patterns on the ref itself
229
+
230
+ // Pattern 1: _reactInternals (class components)
231
+ if (ref._reactInternals) return ref._reactInternals;
232
+
233
+ // Pattern 2: _reactInternalInstance (older React)
234
+ if (ref._reactInternalInstance) return ref._reactInternalInstance;
235
+
236
+ // Pattern 3: __reactFiber$ keys (React DOM/RN style)
237
+ try {
238
+ const keys = Object.keys(ref);
239
+ const fiberKey = keys.find(key => key.startsWith('__reactFiber$') || key.startsWith('__reactInternalInstance$'));
240
+ if (fiberKey) return ref[fiberKey];
241
+ } catch {
242
+ // Object.keys may fail on some native nodes
243
+ }
244
+
245
+ // Pattern 4: Direct fiber node properties
246
+ if (ref.child || ref.memoizedProps) return ref;
247
+ logger.warn('FiberTreeWalker', 'All Fiber access strategies failed');
248
+ return null;
249
+ }
250
+
251
+ // ─── Blacklist/Whitelist Matching ──────────────────────────────
252
+
253
+ /**
254
+ * Check if a Fiber node matches any ref in the given list.
255
+ * Mirrors page-agent.js: `interactiveBlacklist.includes(element)`
256
+ * We compare the Fiber's stateNode (native instance) against ref.current.
257
+ */
258
+ function matchesRefList(node, refs) {
259
+ if (!refs || refs.length === 0) return false;
260
+ const stateNode = node.stateNode;
261
+ if (!stateNode) return false;
262
+ for (const ref of refs) {
263
+ if (ref.current && ref.current === stateNode) return true;
264
+ }
265
+ return false;
266
+ }
267
+ // ─── Main Tree Walker ──────────────────────────────────────────
268
+
269
+ /**
270
+ * Walk the React Fiber tree from a root and collect all interactive elements
271
+ * as well as a hierarchical layout representation for the LLM.
272
+ */
273
+ export function walkFiberTree(rootRef, config) {
274
+ const fiber = getFiberFromRef(rootRef);
275
+ if (!fiber) {
276
+ logger.warn('FiberTreeWalker', 'Could not access Fiber tree from ref');
277
+ return {
278
+ elementsText: '',
279
+ interactives: []
280
+ };
281
+ }
282
+ const interactives = [];
283
+ let currentIndex = 0;
284
+ const hasWhitelist = config?.interactiveWhitelist && (config.interactiveWhitelist.length ?? 0) > 0;
285
+ function processNode(node, depth = 0, isInsideInteractive = false) {
286
+ if (!node) return '';
287
+ const props = node.memoizedProps || {};
288
+
289
+ // ── Security Constraints ──
290
+ if (props.aiIgnore === true) return '';
291
+ if (matchesRefList(node, config?.interactiveBlacklist)) {
292
+ let childText = '';
293
+ let currentChild = node.child;
294
+ while (currentChild) {
295
+ childText += processNode(currentChild, depth, isInsideInteractive);
296
+ currentChild = currentChild.sibling;
297
+ }
298
+ return childText;
299
+ }
300
+
301
+ // Interactive check — skip if already inside an interactive ancestor (dedup nested TextInput layers)
302
+ const isWhitelisted = matchesRefList(node, config?.interactiveWhitelist);
303
+ const elementType = getElementType(node);
304
+ const shouldInclude = !isInsideInteractive && (hasWhitelist ? isWhitelisted : elementType && !isDisabled(node));
305
+
306
+ // Process children — if this node IS interactive, children won't register as separate interactives
307
+ let childrenText = '';
308
+ let currentChild = node.child;
309
+ while (currentChild) {
310
+ childrenText += processNode(currentChild, depth + 1, isInsideInteractive || !!shouldInclude);
311
+ currentChild = currentChild.sibling;
312
+ }
313
+ const indent = ' '.repeat(depth);
314
+ if (shouldInclude) {
315
+ const resolvedType = elementType || 'pressable';
316
+ let label = props.accessibilityLabel || extractTextContent(node);
317
+ if (!label && resolvedType === 'text-input' && props.placeholder) {
318
+ label = props.placeholder;
319
+ }
320
+ interactives.push({
321
+ index: currentIndex,
322
+ type: resolvedType,
323
+ label: label || `[${resolvedType}]`,
324
+ fiberNode: node,
325
+ props: {
326
+ ...props
327
+ }
328
+ });
329
+
330
+ // Build output tag with state attributes (mirrors page-agent format)
331
+ const stateAttrs = extractStateAttributes(props);
332
+ const attrStr = stateAttrs ? ` ${stateAttrs}` : '';
333
+ const textContent = label || '';
334
+ const elementOutput = `${indent}[${currentIndex}]<${resolvedType}${attrStr}>${textContent} />${childrenText.trim() ? '\n' + childrenText : ''}\n`;
335
+ currentIndex++;
336
+ return elementOutput;
337
+ }
338
+
339
+ // Non-interactive structural nodes
340
+ const typeStr = node.type && typeof node.type === 'string' ? node.type : node.elementType && typeof node.elementType === 'string' ? node.elementType : null;
341
+ if (typeStr === 'RCTText' || typeStr === 'Text') {
342
+ const textContent = extractRawText(props.children);
343
+ if (textContent && textContent.trim() !== '') {
344
+ return `${indent}<text>${textContent.trim()}</text>\n`;
345
+ }
346
+ }
347
+ if (childrenText.trim() !== '') {
348
+ return `${indent}<view>\n${childrenText}${indent}</view>\n`;
349
+ }
350
+ return '';
351
+ }
352
+ let elementsText = processNode(fiber, 0);
353
+
354
+ // Clean up empty views and excessive newlines
355
+ elementsText = elementsText.replace(/<view>\s*<\/view>\n?/g, '');
356
+ logger.info('FiberTreeWalker', `Found ${interactives.length} interactive elements`);
357
+ return {
358
+ elementsText: elementsText.trim(),
359
+ interactives
360
+ };
361
+ }
362
+ //# sourceMappingURL=FiberTreeWalker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["logger","PRESSABLE_TYPES","Set","TEXT_INPUT_TYPES","SWITCH_TYPES","TEXT_TYPES","STATE_PROPS","extractStateAttributes","props","parts","accessibilityState","k","v","Object","entries","undefined","push","accessibilityRole","key","join","hasAnyEventHandler","keys","startsWith","getComponentName","fiber","type","displayName","name","render","getElementType","memoizedProps","has","role","onPress","onChangeText","onValueChange","isDisabled","disabled","editable","extractTextContent","maxDepth","child","childName","childProps","sibling","text","extractRawText","children","nestedText","trim","String","Array","isArray","map","filter","Boolean","getFiberRoot","hook","globalThis","__REACT_DEVTOOLS_GLOBAL_HOOK__","renderers","size","rendererId","roots","getFiberRoots","fiberRoot","values","next","value","current","debug","e","getFiberFromRef","ref","rootFiber","_reactInternals","_reactInternalInstance","fiberKey","find","warn","matchesRefList","node","refs","length","stateNode","walkFiberTree","rootRef","config","elementsText","interactives","currentIndex","hasWhitelist","interactiveWhitelist","processNode","depth","isInsideInteractive","aiIgnore","interactiveBlacklist","childText","currentChild","isWhitelisted","elementType","shouldInclude","childrenText","indent","repeat","resolvedType","label","accessibilityLabel","placeholder","index","fiberNode","stateAttrs","attrStr","textContent","elementOutput","typeStr","replace","info"],"sourceRoot":"../../../src","sources":["core/FiberTreeWalker.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * MCPBridge — Connects the React Native app to the local MCP Server bridge.
5
+ *
6
+ * Flow:
7
+ * - Connects via WebSocket to the Node.js MCP server
8
+ * - Listens for 'request' messages containing an MCP command
9
+ * - Forwards the command to AgentRuntime.execute()
10
+ * - Sends the ExecutionResult back via WebSocket as a 'response'
11
+ */
12
+
13
+ import { logger } from "../utils/logger.js";
14
+ export class MCPBridge {
15
+ ws = null;
16
+ reconnectTimer = null;
17
+ isDestroyed = false;
18
+ constructor(url, runtime) {
19
+ this.url = url;
20
+ this.runtime = runtime;
21
+ this.connect();
22
+ }
23
+ connect() {
24
+ if (this.isDestroyed) return;
25
+ logger.info('MCPBridge', `Connecting to MCP bridge at ${this.url}...`);
26
+ this.ws = new WebSocket(this.url);
27
+ this.ws.onopen = () => {
28
+ logger.info('MCPBridge', '✅ Connected to MCP bridge.');
29
+ if (this.reconnectTimer) {
30
+ clearTimeout(this.reconnectTimer);
31
+ this.reconnectTimer = null;
32
+ }
33
+ };
34
+ this.ws.onmessage = async event => {
35
+ try {
36
+ const data = JSON.parse(event.data);
37
+ if (data.type === 'request' && data.command && data.requestId) {
38
+ logger.info('MCPBridge', `Received task from MCP: "${data.command}"`);
39
+ if (this.runtime.getIsRunning()) {
40
+ this.sendResponse(data.requestId, {
41
+ success: false,
42
+ message: 'Agent is already running a task. Please wait.',
43
+ steps: []
44
+ });
45
+ return;
46
+ }
47
+
48
+ // Execute the task using the SDK's existing runtime loop
49
+ const result = await this.runtime.execute(data.command);
50
+
51
+ // Send result back to MCP server
52
+ this.sendResponse(data.requestId, result);
53
+ }
54
+ } catch (err) {
55
+ logger.error('MCPBridge', 'Error handling message:', err);
56
+ }
57
+ };
58
+ this.ws.onclose = () => {
59
+ if (!this.isDestroyed) {
60
+ logger.warn('MCPBridge', 'Disconnected from MCP bridge. Reconnecting in 5s...');
61
+ this.ws = null;
62
+ this.scheduleReconnect();
63
+ }
64
+ };
65
+ this.ws.onerror = e => {
66
+ logger.warn('MCPBridge', 'WebSocket error:', e);
67
+ // onclose will handle reconnect
68
+ };
69
+ }
70
+ sendResponse(requestId, payload) {
71
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
72
+ this.ws.send(JSON.stringify({
73
+ type: 'response',
74
+ requestId,
75
+ payload
76
+ }));
77
+ }
78
+ }
79
+ scheduleReconnect() {
80
+ if (!this.reconnectTimer) {
81
+ this.reconnectTimer = setTimeout(() => {
82
+ this.connect();
83
+ }, 5000);
84
+ }
85
+ }
86
+ destroy() {
87
+ this.isDestroyed = true;
88
+ if (this.reconnectTimer) {
89
+ clearTimeout(this.reconnectTimer);
90
+ this.reconnectTimer = null;
91
+ }
92
+ if (this.ws) {
93
+ this.ws.close();
94
+ this.ws = null;
95
+ }
96
+ }
97
+ }
98
+ //# sourceMappingURL=MCPBridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["logger","MCPBridge","ws","reconnectTimer","isDestroyed","constructor","url","runtime","connect","info","WebSocket","onopen","clearTimeout","onmessage","event","data","JSON","parse","type","command","requestId","getIsRunning","sendResponse","success","message","steps","result","execute","err","error","onclose","warn","scheduleReconnect","onerror","e","payload","readyState","OPEN","send","stringify","setTimeout","destroy","close"],"sourceRoot":"../../../src","sources":["core/MCPBridge.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * ScreenDehydrator — Converts discovered interactive elements into
5
+ * a text representation for the LLM, matching page-agent.js format.
6
+ *
7
+ * Output example:
8
+ * ```
9
+ * Screen: Home | Available screens: Home, Menu, Cart
10
+ * Interactive elements:
11
+ * [0]<pressable>🍕 Pizzas</>
12
+ * [1]<pressable>🍔 Burgers</>
13
+ * [2]<pressable>🥤 Drinks</>
14
+ * [3]<pressable>🛒 View Cart</>
15
+ * ```
16
+ */
17
+
18
+ /**
19
+ * Dehydrate the current screen state into a text format for the LLM.
20
+ */
21
+ export function dehydrateScreen(screenName, availableScreens, elementsText, elements) {
22
+ const lines = [];
23
+
24
+ // Header
25
+ lines.push(`Screen: ${screenName} | Available screens: ${availableScreens.join(', ')}`);
26
+ lines.push('');
27
+ if (!elementsText || elementsText.trim().length === 0) {
28
+ if (elements.length === 0) {
29
+ lines.push('No interactive elements or visible text detected on this screen.');
30
+ } else {
31
+ lines.push('Interactive elements:');
32
+ lines.push(elementsText);
33
+ }
34
+ } else {
35
+ lines.push('Screen Layout & Elements:');
36
+ lines.push(elementsText);
37
+ }
38
+ const finalElementsText = lines.join('\n');
39
+ return {
40
+ screenName,
41
+ availableScreens,
42
+ elementsText: finalElementsText,
43
+ elements
44
+ };
45
+ }
46
+ //# sourceMappingURL=ScreenDehydrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["dehydrateScreen","screenName","availableScreens","elementsText","elements","lines","push","join","trim","length","finalElementsText"],"sourceRoot":"../../../src","sources":["core/ScreenDehydrator.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA;AACA;AACA;AACA,OAAO,SAASA,eAAeA,CAC7BC,UAAkB,EAClBC,gBAA0B,EAC1BC,YAAoB,EACpBC,QAA8B,EACZ;EAClB,MAAMC,KAAe,GAAG,EAAE;;EAE1B;EACAA,KAAK,CAACC,IAAI,CAAC,WAAWL,UAAU,yBAAyBC,gBAAgB,CAACK,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;EACvFF,KAAK,CAACC,IAAI,CAAC,EAAE,CAAC;EAEd,IAAI,CAACH,YAAY,IAAIA,YAAY,CAACK,IAAI,CAAC,CAAC,CAACC,MAAM,KAAK,CAAC,EAAE;IACrD,IAAIL,QAAQ,CAACK,MAAM,KAAK,CAAC,EAAE;MACzBJ,KAAK,CAACC,IAAI,CAAC,kEAAkE,CAAC;IAChF,CAAC,MAAM;MACLD,KAAK,CAACC,IAAI,CAAC,uBAAuB,CAAC;MACnCD,KAAK,CAACC,IAAI,CAACH,YAAY,CAAC;IAC1B;EACF,CAAC,MAAM;IACLE,KAAK,CAACC,IAAI,CAAC,2BAA2B,CAAC;IACvCD,KAAK,CAACC,IAAI,CAACH,YAAY,CAAC;EAC1B;EAEA,MAAMO,iBAAiB,GAAGL,KAAK,CAACE,IAAI,CAAC,IAAI,CAAC;EAE1C,OAAO;IACLN,UAAU;IACVC,gBAAgB;IAChBC,YAAY,EAAEO,iBAAiB;IAC/BN;EACF,CAAC;AACH","ignoreList":[]}