@mobileai/react-native 0.9.27 → 0.9.29

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 (65) hide show
  1. package/README.md +28 -16
  2. package/android/build.gradle +17 -0
  3. package/android/src/main/java/com/mobileai/overlay/FloatingOverlayDialogRootViewGroup.kt +243 -0
  4. package/android/src/main/java/com/mobileai/overlay/FloatingOverlayView.kt +281 -87
  5. package/android/src/newarch/com/mobileai/overlay/FloatingOverlayViewManager.kt +52 -17
  6. package/android/src/oldarch/com/mobileai/overlay/FloatingOverlayViewManager.kt +49 -2
  7. package/bin/generate-map.cjs +45 -6
  8. package/ios/MobileAIFloatingOverlayComponentView.h +8 -0
  9. package/ios/MobileAIFloatingOverlayComponentView.mm +12 -41
  10. package/ios/Podfile +63 -0
  11. package/ios/Podfile.lock +2290 -0
  12. package/ios/Podfile.properties.json +4 -0
  13. package/ios/mobileaireactnative/AppDelegate.swift +69 -0
  14. package/ios/mobileaireactnative/Images.xcassets/AppIcon.appiconset/Contents.json +13 -0
  15. package/ios/mobileaireactnative/Images.xcassets/Contents.json +6 -0
  16. package/ios/mobileaireactnative/Images.xcassets/SplashScreenLegacy.imageset/Contents.json +21 -0
  17. package/ios/mobileaireactnative/Images.xcassets/SplashScreenLegacy.imageset/SplashScreenLegacy.png +0 -0
  18. package/ios/mobileaireactnative/Info.plist +55 -0
  19. package/ios/mobileaireactnative/PrivacyInfo.xcprivacy +48 -0
  20. package/ios/mobileaireactnative/SplashScreen.storyboard +47 -0
  21. package/ios/mobileaireactnative/Supporting/Expo.plist +6 -0
  22. package/ios/mobileaireactnative/mobileaireactnative-Bridging-Header.h +3 -0
  23. package/ios/mobileaireactnative.xcodeproj/project.pbxproj +547 -0
  24. package/ios/mobileaireactnative.xcodeproj/xcshareddata/xcschemes/mobileaireactnative.xcscheme +88 -0
  25. package/ios/mobileaireactnative.xcworkspace/contents.xcworkspacedata +10 -0
  26. package/lib/module/components/AIAgent.js +501 -191
  27. package/lib/module/components/AgentChatBar.js +250 -59
  28. package/lib/module/components/FloatingOverlayWrapper.js +68 -32
  29. package/lib/module/config/endpoints.js +22 -1
  30. package/lib/module/core/AgentRuntime.js +110 -8
  31. package/lib/module/core/FiberTreeWalker.js +211 -10
  32. package/lib/module/core/OutcomeVerifier.js +149 -0
  33. package/lib/module/core/systemPrompt.js +96 -25
  34. package/lib/module/providers/GeminiProvider.js +9 -3
  35. package/lib/module/services/telemetry/TelemetryService.js +21 -2
  36. package/lib/module/services/telemetry/TouchAutoCapture.js +235 -38
  37. package/lib/module/services/telemetry/analyticsLabeling.js +187 -0
  38. package/lib/module/specs/FloatingOverlayNativeComponent.ts +7 -1
  39. package/lib/module/support/supportPrompt.js +22 -7
  40. package/lib/module/support/supportStyle.js +55 -0
  41. package/lib/module/support/types.js +2 -0
  42. package/lib/module/tools/typeTool.js +20 -0
  43. package/lib/module/utils/humanizeScreenName.js +49 -0
  44. package/lib/typescript/src/components/AIAgent.d.ts +6 -2
  45. package/lib/typescript/src/components/AgentChatBar.d.ts +15 -1
  46. package/lib/typescript/src/components/FloatingOverlayWrapper.d.ts +22 -10
  47. package/lib/typescript/src/config/endpoints.d.ts +4 -0
  48. package/lib/typescript/src/core/AgentRuntime.d.ts +12 -3
  49. package/lib/typescript/src/core/FiberTreeWalker.d.ts +12 -1
  50. package/lib/typescript/src/core/OutcomeVerifier.d.ts +46 -0
  51. package/lib/typescript/src/core/systemPrompt.d.ts +3 -10
  52. package/lib/typescript/src/core/types.d.ts +63 -0
  53. package/lib/typescript/src/index.d.ts +1 -0
  54. package/lib/typescript/src/services/telemetry/TelemetryService.d.ts +7 -1
  55. package/lib/typescript/src/services/telemetry/TouchAutoCapture.d.ts +6 -1
  56. package/lib/typescript/src/services/telemetry/analyticsLabeling.d.ts +20 -0
  57. package/lib/typescript/src/services/telemetry/types.d.ts +1 -1
  58. package/lib/typescript/src/specs/FloatingOverlayNativeComponent.d.ts +5 -0
  59. package/lib/typescript/src/support/index.d.ts +1 -0
  60. package/lib/typescript/src/support/supportStyle.d.ts +9 -0
  61. package/lib/typescript/src/support/types.d.ts +3 -0
  62. package/lib/typescript/src/utils/humanizeScreenName.d.ts +6 -0
  63. package/package.json +10 -10
  64. package/src/specs/FloatingOverlayNativeComponent.ts +7 -1
  65. package/ios/MobileAIPilotIntents.swift +0 -51
@@ -1539,14 +1539,52 @@ function detectFramework(projectRoot) {
1539
1539
  }
1540
1540
 
1541
1541
  function parseArgs(argv) {
1542
- const args = { dir: '', watch: false };
1542
+ const args = {
1543
+ dir: '',
1544
+ watch: false,
1545
+ include: [],
1546
+ exclude: [],
1547
+ };
1543
1548
  for (const arg of argv) {
1544
1549
  if (arg === '--watch' || arg === '-w') args.watch = true;
1545
1550
  if (arg.startsWith('--dir=')) args.dir = arg.split('=')[1];
1551
+ if (arg.startsWith('--include=')) {
1552
+ args.include = arg.slice('--include='.length).split(',').map((entry) => entry.trim()).filter(Boolean);
1553
+ }
1554
+ if (arg.startsWith('--exclude=')) {
1555
+ args.exclude = arg.slice('--exclude='.length).split(',').map((entry) => entry.trim()).filter(Boolean);
1556
+ }
1546
1557
  }
1547
1558
  return args;
1548
1559
  }
1549
1560
 
1561
+ function routeMatchesPattern(routeName, pattern) {
1562
+ if (!pattern) return false;
1563
+ if (pattern === routeName) return true;
1564
+ if (!pattern.includes('*')) {
1565
+ return routeName === pattern;
1566
+ }
1567
+ const escaped = pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1568
+ const regex = new RegExp(`^${escaped.replace(/\\\*/g, '.*')}$`);
1569
+ return regex.test(routeName);
1570
+ }
1571
+
1572
+ function routeMatchesAnyPattern(routeName, patterns) {
1573
+ return patterns.some((pattern) => routeMatchesPattern(routeName, pattern));
1574
+ }
1575
+
1576
+ function filterScreensByRoutePatterns(screens, args) {
1577
+ return screens.filter((screen) => {
1578
+ if (args.include.length > 0 && !routeMatchesAnyPattern(screen.routeName, args.include)) {
1579
+ return false;
1580
+ }
1581
+ if (args.exclude.length > 0 && routeMatchesAnyPattern(screen.routeName, args.exclude)) {
1582
+ return false;
1583
+ }
1584
+ return true;
1585
+ });
1586
+ }
1587
+
1550
1588
  async function generate(args, projectRoot) {
1551
1589
  _projectRoot = projectRoot; // for module alias resolution in extractImportPaths
1552
1590
  _transitiveCache.clear(); // reset cache for fresh scan
@@ -1556,19 +1594,20 @@ async function generate(args, projectRoot) {
1556
1594
  const scannedScreens = framework === 'expo-router'
1557
1595
  ? scanExpoRouterApp(projectRoot)
1558
1596
  : scanReactNavigationApp(projectRoot);
1597
+ const filteredScreens = filterScreensByRoutePatterns(scannedScreens, args);
1559
1598
 
1560
- console.log(`📄 Found ${scannedScreens.length} screen(s)`);
1599
+ console.log(`📄 Found ${filteredScreens.length} screen(s)`);
1561
1600
 
1562
1601
  // Enrich navigation links with component-level navigation
1563
1602
  console.log('🔍 Scanning components for navigation calls...');
1564
1603
  const globalIndex = buildGlobalNavigateIndex(projectRoot);
1565
1604
  const navigatorFiles = framework === 'react-navigation' ? findNavigatorFiles(projectRoot) : [];
1566
- const added = enrichScreensWithComponentNavLinks(scannedScreens, globalIndex, navigatorFiles);
1605
+ const added = enrichScreensWithComponentNavLinks(filteredScreens, globalIndex, navigatorFiles);
1567
1606
  console.log(` Found ${globalIndex.size} component(s) with navigation, added ${added} link(s)`);
1568
1607
 
1569
1608
 
1570
1609
  // Build output — per-screen navigatesTo, filtered to known routes only
1571
- const allRouteSet = new Set(scannedScreens.map(s => s.routeName));
1610
+ const allRouteSet = new Set(filteredScreens.map(s => s.routeName));
1572
1611
 
1573
1612
  // Build basename lookup for fuzzy matching (e.g. "Chat" → "screens/Chat")
1574
1613
  const basenameMap = new Map(); // basename → full route (shortest path wins)
@@ -1592,7 +1631,7 @@ async function generate(args, projectRoot) {
1592
1631
  }
1593
1632
 
1594
1633
  const screenMap = { generatedAt: new Date().toISOString(), framework, screens: {} };
1595
- for (const screen of scannedScreens) {
1634
+ for (const screen of filteredScreens) {
1596
1635
  const validLinks = screen.navigationLinks.map(link => resolveNavLink(link)).filter(Boolean);
1597
1636
  // Deduplicate (two different raw links may resolve to the same route)
1598
1637
  const uniqueLinks = [...new Set(validLinks)];
@@ -1610,7 +1649,7 @@ async function generate(args, projectRoot) {
1610
1649
  const outputPath = path.join(projectRoot, 'ai-screen-map.json');
1611
1650
  fs.writeFileSync(outputPath, JSON.stringify(screenMap, null, 2));
1612
1651
 
1613
- const linkedCount = scannedScreens.filter(s => s.navigationLinks.map(l => resolveNavLink(l)).some(Boolean)).length;
1652
+ const linkedCount = filteredScreens.filter(s => s.navigationLinks.map(l => resolveNavLink(l)).some(Boolean)).length;
1614
1653
  console.log('━'.repeat(40));
1615
1654
  console.log(`✅ Generated ${outputPath}`);
1616
1655
  console.log(` ${Object.keys(screenMap.screens).length} screens, ${linkedCount} with navigation links`);
@@ -0,0 +1,8 @@
1
+ #import <React/RCTViewComponentView.h>
2
+
3
+ NS_ASSUME_NONNULL_BEGIN
4
+
5
+ @interface MobileAIFloatingOverlayComponentView : RCTViewComponentView
6
+ @end
7
+
8
+ NS_ASSUME_NONNULL_END
@@ -1,30 +1,23 @@
1
- #import <React/RCTViewComponentView.h>
2
- #import <UIKit/UIKit.h>
1
+ #ifdef RCT_NEW_ARCH_ENABLED
3
2
 
3
+ #import "MobileAIFloatingOverlayComponentView.h"
4
+ #import <React/RCTFabricComponentsPlugins.h>
4
5
  #import <react/renderer/components/RNMobileAIOverlaySpec/ComponentDescriptors.h>
5
- #import <react/renderer/components/RNMobileAIOverlaySpec/EventEmitters.h>
6
6
  #import <react/renderer/components/RNMobileAIOverlaySpec/Props.h>
7
7
  #import <react/renderer/components/RNMobileAIOverlaySpec/RCTComponentViewHelpers.h>
8
8
 
9
- #import "RCTFabricComponentsPlugins.h"
10
-
11
- NS_ASSUME_NONNULL_BEGIN
12
- @interface MobileAIFloatingOverlayComponentView : RCTViewComponentView
13
- @end
14
- NS_ASSUME_NONNULL_END
15
-
16
9
  using namespace facebook::react;
17
10
 
18
- @interface MobileAIFloatingOverlayComponentView () <RCTMobileAIFloatingOverlayViewProtocol>
19
- @end
11
+ @implementation MobileAIFloatingOverlayComponentView
20
12
 
21
- @implementation MobileAIFloatingOverlayComponentView {
22
- UIView * _view;
13
+ + (ComponentDescriptorProvider)componentDescriptorProvider
14
+ {
15
+ return concreteComponentDescriptorProvider<MobileAIFloatingOverlayComponentDescriptor>();
23
16
  }
24
17
 
25
- + (ComponentDescriptorProvider)componentDescriptorProvider
18
+ + (void)load
26
19
  {
27
- return concreteComponentDescriptorProvider<MobileAIFloatingOverlayComponentDescriptor>();
20
+ [super load];
28
21
  }
29
22
 
30
23
  - (instancetype)initWithFrame:(CGRect)frame
@@ -32,21 +25,13 @@ using namespace facebook::react;
32
25
  if (self = [super initWithFrame:frame]) {
33
26
  static const auto defaultProps = std::make_shared<const MobileAIFloatingOverlayProps>();
34
27
  _props = defaultProps;
35
-
36
- _view = [[UIView alloc] init];
37
-
38
- self.contentView = _view;
39
28
  }
40
-
41
29
  return self;
42
30
  }
43
31
 
44
- - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
32
+ - (void)updateProps:(Props::Shared const&)props oldProps:(Props::Shared const&)oldProps
45
33
  {
46
- const auto &oldViewProps = *std::static_pointer_cast<MobileAIFloatingOverlayProps const>(_props);
47
- const auto &newViewProps = *std::static_pointer_cast<MobileAIFloatingOverlayProps const>(props);
48
-
49
- [super updateProps:props oldProps:oldProps];
34
+ [super updateProps:props oldProps:oldProps];
50
35
  }
51
36
 
52
37
  @end
@@ -56,18 +41,4 @@ Class<RCTComponentViewProtocol> MobileAIFloatingOverlayCls(void)
56
41
  return MobileAIFloatingOverlayComponentView.class;
57
42
  }
58
43
 
59
- // ─── Linker Fix: Force inclusion of the library ────────────────
60
-
61
- #import <React/RCTViewManager.h>
62
-
63
- @interface MobileAIFloatingOverlayManager : RCTViewManager
64
- @end
65
-
66
- @implementation MobileAIFloatingOverlayManager
67
- RCT_EXPORT_MODULE(MobileAIFloatingOverlay)
68
-
69
- - (UIView *)view
70
- {
71
- return [[UIView alloc] init];
72
- }
73
- @end
44
+ #endif
package/ios/Podfile ADDED
@@ -0,0 +1,63 @@
1
+ require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking")
2
+ require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods")
3
+
4
+ require 'json'
5
+ podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {}
6
+
7
+ def ccache_enabled?(podfile_properties)
8
+ # Environment variable takes precedence
9
+ return ENV['USE_CCACHE'] == '1' if ENV['USE_CCACHE']
10
+
11
+ # Fall back to Podfile properties
12
+ podfile_properties['apple.ccacheEnabled'] == 'true'
13
+ end
14
+
15
+ ENV['EX_DEV_CLIENT_NETWORK_INSPECTOR'] ||= podfile_properties['EX_DEV_CLIENT_NETWORK_INSPECTOR']
16
+ ENV['RCT_USE_RN_DEP'] ||= '1' if podfile_properties['ios.buildReactNativeFromSource'] != 'true'
17
+ ENV['RCT_USE_PREBUILT_RNCORE'] ||= '1' if podfile_properties['ios.buildReactNativeFromSource'] != 'true'
18
+ ENV['RCT_HERMES_V1_ENABLED'] ||= '1' if podfile_properties['expo.useHermesV1'] == 'true'
19
+ platform :ios, podfile_properties['ios.deploymentTarget'] || '15.1'
20
+
21
+ prepare_react_native_project!
22
+
23
+ target 'mobileaireactnative' do
24
+ use_expo_modules!
25
+
26
+ if ENV['EXPO_USE_COMMUNITY_AUTOLINKING'] == '1'
27
+ config_command = ['node', '-e', "process.argv=['', '', 'config'];require('@react-native-community/cli').run()"];
28
+ else
29
+ config_command = [
30
+ 'node',
31
+ '--no-warnings',
32
+ '--eval',
33
+ 'require(\'expo/bin/autolinking\')',
34
+ 'expo-modules-autolinking',
35
+ 'react-native-config',
36
+ '--json',
37
+ '--platform',
38
+ 'ios'
39
+ ]
40
+ end
41
+
42
+ config = use_native_modules!(config_command)
43
+
44
+ use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks']
45
+ use_frameworks! :linkage => ENV['USE_FRAMEWORKS'].to_sym if ENV['USE_FRAMEWORKS']
46
+
47
+ use_react_native!(
48
+ :path => config[:reactNativePath],
49
+ :hermes_enabled => podfile_properties['expo.jsEngine'] == nil || podfile_properties['expo.jsEngine'] == 'hermes',
50
+ # An absolute path to your application root.
51
+ :app_path => "#{Pod::Config.instance.installation_root}/..",
52
+ :privacy_file_aggregation_enabled => podfile_properties['apple.privacyManifestAggregationEnabled'] != 'false',
53
+ )
54
+
55
+ post_install do |installer|
56
+ react_native_post_install(
57
+ installer,
58
+ config[:reactNativePath],
59
+ :mac_catalyst_enabled => false,
60
+ :ccache_enabled => ccache_enabled?(podfile_properties),
61
+ )
62
+ end
63
+ end