@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.
- package/README.md +28 -16
- package/android/build.gradle +17 -0
- package/android/src/main/java/com/mobileai/overlay/FloatingOverlayDialogRootViewGroup.kt +243 -0
- package/android/src/main/java/com/mobileai/overlay/FloatingOverlayView.kt +281 -87
- package/android/src/newarch/com/mobileai/overlay/FloatingOverlayViewManager.kt +52 -17
- package/android/src/oldarch/com/mobileai/overlay/FloatingOverlayViewManager.kt +49 -2
- package/bin/generate-map.cjs +45 -6
- package/ios/MobileAIFloatingOverlayComponentView.h +8 -0
- package/ios/MobileAIFloatingOverlayComponentView.mm +12 -41
- package/ios/Podfile +63 -0
- package/ios/Podfile.lock +2290 -0
- package/ios/Podfile.properties.json +4 -0
- package/ios/mobileaireactnative/AppDelegate.swift +69 -0
- package/ios/mobileaireactnative/Images.xcassets/AppIcon.appiconset/Contents.json +13 -0
- package/ios/mobileaireactnative/Images.xcassets/Contents.json +6 -0
- package/ios/mobileaireactnative/Images.xcassets/SplashScreenLegacy.imageset/Contents.json +21 -0
- package/ios/mobileaireactnative/Images.xcassets/SplashScreenLegacy.imageset/SplashScreenLegacy.png +0 -0
- package/ios/mobileaireactnative/Info.plist +55 -0
- package/ios/mobileaireactnative/PrivacyInfo.xcprivacy +48 -0
- package/ios/mobileaireactnative/SplashScreen.storyboard +47 -0
- package/ios/mobileaireactnative/Supporting/Expo.plist +6 -0
- package/ios/mobileaireactnative/mobileaireactnative-Bridging-Header.h +3 -0
- package/ios/mobileaireactnative.xcodeproj/project.pbxproj +547 -0
- package/ios/mobileaireactnative.xcodeproj/xcshareddata/xcschemes/mobileaireactnative.xcscheme +88 -0
- package/ios/mobileaireactnative.xcworkspace/contents.xcworkspacedata +10 -0
- package/lib/module/components/AIAgent.js +501 -191
- package/lib/module/components/AgentChatBar.js +250 -59
- package/lib/module/components/FloatingOverlayWrapper.js +68 -32
- package/lib/module/config/endpoints.js +22 -1
- package/lib/module/core/AgentRuntime.js +110 -8
- package/lib/module/core/FiberTreeWalker.js +211 -10
- package/lib/module/core/OutcomeVerifier.js +149 -0
- package/lib/module/core/systemPrompt.js +96 -25
- package/lib/module/providers/GeminiProvider.js +9 -3
- package/lib/module/services/telemetry/TelemetryService.js +21 -2
- package/lib/module/services/telemetry/TouchAutoCapture.js +235 -38
- package/lib/module/services/telemetry/analyticsLabeling.js +187 -0
- package/lib/module/specs/FloatingOverlayNativeComponent.ts +7 -1
- package/lib/module/support/supportPrompt.js +22 -7
- package/lib/module/support/supportStyle.js +55 -0
- package/lib/module/support/types.js +2 -0
- package/lib/module/tools/typeTool.js +20 -0
- package/lib/module/utils/humanizeScreenName.js +49 -0
- package/lib/typescript/src/components/AIAgent.d.ts +6 -2
- package/lib/typescript/src/components/AgentChatBar.d.ts +15 -1
- package/lib/typescript/src/components/FloatingOverlayWrapper.d.ts +22 -10
- package/lib/typescript/src/config/endpoints.d.ts +4 -0
- package/lib/typescript/src/core/AgentRuntime.d.ts +12 -3
- package/lib/typescript/src/core/FiberTreeWalker.d.ts +12 -1
- package/lib/typescript/src/core/OutcomeVerifier.d.ts +46 -0
- package/lib/typescript/src/core/systemPrompt.d.ts +3 -10
- package/lib/typescript/src/core/types.d.ts +63 -0
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/services/telemetry/TelemetryService.d.ts +7 -1
- package/lib/typescript/src/services/telemetry/TouchAutoCapture.d.ts +6 -1
- package/lib/typescript/src/services/telemetry/analyticsLabeling.d.ts +20 -0
- package/lib/typescript/src/services/telemetry/types.d.ts +1 -1
- package/lib/typescript/src/specs/FloatingOverlayNativeComponent.d.ts +5 -0
- package/lib/typescript/src/support/index.d.ts +1 -0
- package/lib/typescript/src/support/supportStyle.d.ts +9 -0
- package/lib/typescript/src/support/types.d.ts +3 -0
- package/lib/typescript/src/utils/humanizeScreenName.d.ts +6 -0
- package/package.json +10 -10
- package/src/specs/FloatingOverlayNativeComponent.ts +7 -1
- package/ios/MobileAIPilotIntents.swift +0 -51
package/bin/generate-map.cjs
CHANGED
|
@@ -1539,14 +1539,52 @@ function detectFramework(projectRoot) {
|
|
|
1539
1539
|
}
|
|
1540
1540
|
|
|
1541
1541
|
function parseArgs(argv) {
|
|
1542
|
-
const args = {
|
|
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 ${
|
|
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(
|
|
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(
|
|
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
|
|
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 =
|
|
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`);
|
|
@@ -1,30 +1,23 @@
|
|
|
1
|
-
#
|
|
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
|
-
@
|
|
19
|
-
@end
|
|
11
|
+
@implementation MobileAIFloatingOverlayComponentView
|
|
20
12
|
|
|
21
|
-
|
|
22
|
-
|
|
13
|
+
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
|
14
|
+
{
|
|
15
|
+
return concreteComponentDescriptorProvider<MobileAIFloatingOverlayComponentDescriptor>();
|
|
23
16
|
}
|
|
24
17
|
|
|
25
|
-
+ (
|
|
18
|
+
+ (void)load
|
|
26
19
|
{
|
|
27
|
-
|
|
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
|
|
32
|
+
- (void)updateProps:(Props::Shared const&)props oldProps:(Props::Shared const&)oldProps
|
|
45
33
|
{
|
|
46
|
-
|
|
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
|
-
|
|
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
|