Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
3fa458a
build: create script for PGO builds
chrispader Aug 4, 2026
3295d38
build: configure PGO build
chrispader Aug 4, 2026
e1747b5
build: add `verify-instrumented` tool
chrispader Aug 4, 2026
96518ea
chore: update RN patch
chrispader Aug 4, 2026
27c7035
chore: add `.pgo` dir to `.gitignore`
chrispader Aug 4, 2026
e8d1104
fix: PGO merging
chrispader Aug 4, 2026
2b114fd
build: add `install-instrumented` command
chrispader Aug 4, 2026
9322dba
Update README.md
chrispader Aug 4, 2026
47f9d5b
Update android-local-proof.sh
chrispader Aug 4, 2026
6ba45d6
build: create record-startups command
chrispader Aug 4, 2026
62808e8
fix: prevent startup profile merge scope error
chrispader Aug 4, 2026
0da014a
build: add dedicated PGO build variants
chrispader Aug 4, 2026
ea4b7fb
Wait for native app-ready signal during PGO startup recording
chrispader Aug 4, 2026
151f4f1
chore: improve script
chrispader Aug 4, 2026
1921255
chore: add PGO benchmarking suite
chrispader Aug 4, 2026
13df28a
build: add dedicated PGO build variants
chrispader Aug 4, 2026
f906d1a
Merge branch '@chrispader/perf/pgo' into @chrispader/perf/pgo-startup…
chrispader Aug 4, 2026
7bf73a0
revert: separate build variants for PGO
chrispader Aug 4, 2026
4ce4248
chore: move apk outputs to `.pgo` folder
chrispader Aug 4, 2026
c267adb
chore: archive release build
chrispader Aug 4, 2026
43425ff
chore: copy generated release file instead of moving it
chrispader Aug 4, 2026
aa96634
chore: extend PGO benchmark suite
chrispader Aug 4, 2026
dfceb96
chore: reformat benchmark output
chrispader Aug 4, 2026
e25759f
refactor: migrate script to TypeScript
chrispader Aug 5, 2026
04f20ae
refactor: use CLI tool in the PGO tool
chrispader Aug 5, 2026
7f56cfb
Merge branch 'main' into @chrispader/perf/pgo
chrispader Aug 5, 2026
c68accc
feat: implement iOS PGO
chrispader Aug 5, 2026
fa69456
fix: ios optimized build
chrispader Aug 5, 2026
5ddd179
fix: benchmark release first
chrispader Aug 5, 2026
22a19cd
feat: allow defining device
chrispader Aug 6, 2026
d35b7f5
Update README.md
chrispader Aug 6, 2026
b143c0f
perf: merge main and refresh native PGO workflow
chrispader Sep 21, 2026
9befe34
chore: allow native PGO terminology in spelling checks
chrispader Sep 21, 2026
169f09f
docs: clarify PGO scenario isolation and artifact matching
chrispader Sep 21, 2026
66a65c1
fix: support Xcode 27 benchmark process discovery
chrispader Sep 21, 2026
f44192d
chore: merge latest main into PGO work
chrispader Sep 21, 2026
d94d768
docs: clarify iOS PGO profile coverage
chrispader Sep 21, 2026
2beedd0
Merge remote-tracking branch 'origin/main' into @chrispader/perf/pgo
chrispader Sep 22, 2026
72c97bd
Merge remote-tracking branch 'origin/main' into @chrispader/perf/pgo
chrispader Sep 22, 2026
c4bd27d
refactor: share PGO script utilities
chrispader Sep 22, 2026
6aa1031
fix: allow partial iOS PGO profiles
chrispader Sep 23, 2026
f6978f1
perf: automate native PGO journeys
chrispader Sep 23, 2026
a9cae54
fix: match iOS PGO tab status labels
chrispader Sep 23, 2026
394ac25
fix: complete iOS PGO journey on physical device
chrispader Sep 23, 2026
b7b4105
fix(pgo): handle mobile navigation tree edge cases
chrispader Sep 23, 2026
7673df9
perf(pgo): benchmark short signed-in journeys
chrispader Sep 24, 2026
21f2d6c
perf(pgo): add heavy report benchmark
chrispader Sep 24, 2026
e83fa48
fix(pgo): reset heavy benchmark navigation between runs
chrispader Sep 25, 2026
d0cfd6a
fix(pgo): wait for navigation after Android relaunch
chrispader Sep 25, 2026
f9b823c
chore(pgo): merge main into PGO branch
chrispader Sep 28, 2026
5e0a7d1
feat(pgo): add native evaluation tooling
chrispader Oct 12, 2026
932b1a7
ci(pgo): enable report-only native evaluation
chrispader Oct 12, 2026
e2cf575
chore(pgo): merge latest App main
chrispader Oct 12, 2026
2b09283
chore(pgo): merge main into evaluation tooling
chrispader Oct 12, 2026
754cfd7
chore(pgo): merge main into evaluation CI
chrispader Oct 12, 2026
13943b7
chore(pgo): refresh latest App main
chrispader Oct 12, 2026
129c65f
chore(pgo): refresh main in evaluation tooling
chrispader Oct 12, 2026
bd587b8
chore(pgo): refresh main in evaluation CI
chrispader Oct 12, 2026
69a8d67
fix(pgo): align iOS IR profiling and Rock builds
chrispader Oct 12, 2026
c4f2c5e
fix(pgo): require executed Swift profiles in evaluation
chrispader Oct 12, 2026
514e599
chore(pgo): sync iOS foundation into evaluation tooling
chrispader Oct 12, 2026
f65a078
chore(pgo): inherit iOS fixes in report-only evaluation CI
chrispader Oct 12, 2026
83c7263
chore(pgo): merge latest App main
chrispader Oct 12, 2026
e9dec6c
fix(pgo): resolve foundation validation failures
chrispader Oct 12, 2026
5192ecb
chore(pgo): merge updated foundation into evaluation tools
chrispader Oct 12, 2026
e3334f1
chore(pgo): merge updated evaluation tools into CI
chrispader Oct 12, 2026
e7ce342
fix(pgo): use built-in YAML parser in workflow tests
chrispader Oct 12, 2026
0e6f454
chore(pgo): sync latest App main
chrispader Oct 12, 2026
6ff79a8
chore(pgo): sync latest foundation in evaluation tools
chrispader Oct 12, 2026
a5b5d72
chore(pgo): sync latest evaluation tools in CI
chrispader Oct 12, 2026
74f329c
chore(pgo): include latest upstream test fix
chrispader Oct 12, 2026
64481ca
chore(pgo): update evaluation tools foundation
chrispader Oct 12, 2026
d116ce2
chore(pgo): update CI evaluation tools
chrispader Oct 12, 2026
16db894
fix(pgo): reject partial Android profiles and resolve Linux NDK paths
chrispader Oct 13, 2026
22428da
chore(pgo): carry Android review fixes into evaluation tools
chrispader Oct 13, 2026
1545a38
chore(pgo): carry Android review fixes into CI evaluation
chrispader Oct 13, 2026
c5f87f5
chore(pgo): combine evaluation flow with current main
chrispader Oct 21, 2026
83339c5
fix(pgo): skip Gradle lookup for explicit Android app IDs
chrispader Oct 13, 2026
4e5abf7
feat(pgo): prepare combined CI verification and runner handoff
chrispader Oct 21, 2026
7cd178a
feat(pgo): verify CI flow on hosted emulators
chrispader Oct 21, 2026
05a029b
fix(pgo): prepare hosted runner capacity for native builds
chrispader Oct 21, 2026
ff9418b
fix(pgo): correct emulator CI dependency setup
chrispader Oct 22, 2026
9660293
fix(pgo): pin emulator runner to its v2.38.0 release
chrispader Oct 22, 2026
ae47c36
fix(pgo): resolve emulator build dependencies from Maven Central
chrispader Oct 22, 2026
e0628be
fix(pgo): skip R8 in emulator verification builds
chrispader Oct 22, 2026
c919a31
fix(pgo): skip the APK listing redirect when FullStory is excluded
chrispader Oct 22, 2026
fd35e23
fix(pgo): bundle OldDot shared JS in Android PGO builds
chrispader Oct 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 123 additions & 0 deletions .github/workflows/pgoEvaluation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
name: Verify native PGO on emulators

on:
push:
branches: ['@chrispader/perf/pgo-ci-verification']
workflow_dispatch:
inputs:
platform:
description: Platforms to verify
type: choice
default: both
options: [both, android, ios]

permissions:
contents: read

concurrency:
group: pgo-emulator-${{ github.ref }}
cancel-in-progress: true

env:
STANDALONE_NEW_DOT: 'false'
IS_HYBRID_APP: 'true'
BUNDLER: metro
SENTRY_DISABLE_AUTO_UPLOAD: 'true'
CMAKE_BUILD_PARALLEL_LEVEL: '2'

jobs:
verify:
# Only the copied, reviewed branch in App receives private dependency access.
if: github.repository == 'Expensify/App' && github.ref == 'refs/heads/@chrispader/perf/pgo-ci-verification'
runs-on: ${{ matrix.platform == 'android' && 'ubuntu-24.04' || 'blacksmith-12vcpu-macos-latest' }}
timeout-minutes: 360
strategy:
fail-fast: false
matrix:
platform: ${{ fromJSON(inputs.platform == 'android' && '["android"]' || inputs.platform == 'ios' && '["ios"]' || '["android","ios"]') }}
steps:
- name: Check existing repository secrets
env:
CHECKOUT_TOKEN: ${{ secrets.OS_BOTIFY_TOKEN }}
MAPBOX_TOKEN: ${{ secrets.MAPBOX_SDK_DOWNLOAD_TOKEN }}
run: |
test -n "$CHECKOUT_TOKEN" || { echo '::error::Add the existing OS_BOTIFY_TOKEN repository secret with access to Mobile-Expensify.'; exit 1; }
test -n "$MAPBOX_TOKEN" || { echo '::error::Add the existing MAPBOX_SDK_DOWNLOAD_TOKEN repository secret.'; exit 1; }
- name: Checkout the candidate and its pinned native sources
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
submodules: recursive
token: ${{ secrets.OS_BOTIFY_TOKEN }}
persist-credentials: false
- name: Verify native checkout
run: |
test "$(git -C Mobile-Expensify rev-parse HEAD)" = "$(git ls-tree HEAD Mobile-Expensify | awk '{print $3}')"
test "$(./scripts/is-hybrid-app.sh)" = true
- name: Free space for Android source builds
if: matrix.platform == 'android'
run: sudo rm -rf /usr/share/dotnet /usr/local/.ghcup /opt/ghc /usr/local/share/powershell
- name: Setup HybridApp dependencies
uses: ./.github/actions/composite/setupNode
with:
IS_HYBRID_BUILD: 'true'
- name: Setup private SDK downloads
env:
MAPBOX_TOKEN: ${{ secrets.MAPBOX_SDK_DOWNLOAD_TOKEN }}
run: ./scripts/setup-mapbox-sdk.sh "$MAPBOX_TOKEN"

- name: Read repository Java version
if: matrix.platform == 'android'
id: java
uses: ./.github/actions/composite/getJavaVersion
- name: Setup Java
if: matrix.platform == 'android'
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654
with:
distribution: temurin
java-version: ${{ steps.java.outputs.version }}
- name: Setup Android build tools and emulator access
if: matrix.platform == 'android'
run: |
"$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" 'platforms;android-37.0' 'build-tools;36.0.0' 'ndk;27.1.12297006' 'cmake;3.22.1'
echo "ANDROID_NDK_HOME=$ANDROID_HOME/ndk/27.1.12297006" >> "$GITHUB_ENV"
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Verify Android PGO on a disposable emulator
if: matrix.platform == 'android'
uses: ReactiveCircus/android-emulator-runner@a421e43855164a8197daf9d8d40fe71c6996bb0d # v2.38.0
with:
api-level: 36
arch: x86_64
target: google_apis
profile: pixel_7
disable-animations: true
script: npm run pgo:verify-ci -- android

- name: Select repository Xcode
if: matrix.platform == 'ios'
uses: ./.github/actions/composite/getXcodeVersion
- name: Setup Ruby and CocoaPods
if: matrix.platform == 'ios'
id: ruby
uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f
with:
ruby-version: .ruby-version
bundler-cache: true
- name: Verify iOS PGO on a disposable simulator
if: matrix.platform == 'ios'
env:
BUNDLE_GEMFILE: ${{ github.workspace }}/Gemfile
run: |
export PATH="${{ steps.ruby.outputs.ruby-prefix }}/bin:$PATH"
npm run pgo:verify-ci -- ios

- name: Upload verification profiles and report
if: always()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f
with:
name: pgo-emulator-${{ matrix.platform }}
path: .pgo/ci/${{ matrix.platform }}
include-hidden-files: true
if-no-files-found: warn
retention-days: 7
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ config/certificatePinning/roots/
# Rspack build profiling output (RSPACK_PROFILE=OVERVIEW|ALL)
.rspack-profile-*/

# Local native PGO profiles
.pgo/

# Expo
.expo
dist/
Expand Down
2 changes: 1 addition & 1 deletion Mobile-Expensify
11 changes: 11 additions & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,16 @@ project.ext.envConfigFiles = [
* Set this to true to Run Proguard on Release builds to minify the Java bytecode.
*/
def enableProguardInReleaseBuilds = true
def pgoMode = providers.gradleProperty('pgoMode').getOrElse('off')
def pgoProfile = providers.gradleProperty('pgoProfile').orNull

if (!(pgoMode in ['off', 'generate', 'use'])) {
throw new GradleException("Unsupported pgoMode '${pgoMode}'. Use off, generate, or use.")
}

if (pgoMode == 'use' && !pgoProfile) {
throw new GradleException('pgoProfile is required when pgoMode=use.')
}

/**
* The preferred build flavor of JavaScriptCore (JSC)
Expand Down Expand Up @@ -119,6 +129,7 @@ android {
// Supported language variants must be declared here to avoid from being removed during the compilation.
// This also helps us to not include unnecessary language variants in the APK.
resConfigs "en", "es"
buildConfigField 'boolean', 'PGO_PROFILE_GENERATION', (pgoMode == 'generate').toString()
}

flavorDimensions "default"
Expand Down
8 changes: 8 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@
android:theme="@style/AppTheme"
tools:replace="android:supportsRtl">

<receiver
android:name=".PgoProfileReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.expensify.chat.action.WRITE_PGO_PROFILES" />
</intent-filter>
</receiver>

<service
android:name="com.expensify.reactnativebackgroundtask.BackgroundJobService"
android:permission="android.permission.BIND_JOB_SERVICE"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.expensify.chat;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

/**
* Receives an explicit adb broadcast at the end of a local PGO collection run.
*
* The receiver is inert in ordinary builds. It deliberately lives outside the JS surface so a
* manual profiling journey can finish before its native counters are persisted.
*/
public final class PgoProfileReceiver extends BroadcastReceiver {
private static final String TAG = "PgoProfileReceiver";

@Override
public void onReceive(Context context, Intent intent) {
if (!BuildConfig.PGO_PROFILE_GENERATION) {
Log.w(TAG, "Ignoring PGO profile request in a non-instrumented build.");
return;
}

final int writtenProfiles = PgoProfileWriter.writeProfiles(context);
Log.i(TAG, "Wrote " + writtenProfiles + " LLVM PGO profile(s).");
}
}
19 changes: 19 additions & 0 deletions android/app/src/main/java/com/expensify/chat/PgoProfileWriter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.expensify.chat;

import android.content.Context;

/** Development-only bridge for persisting LLVM PGO counters before Android kills the process. */
public final class PgoProfileWriter {
private PgoProfileWriter() {}

private static native int writeProfiles(String directory);

public static int writeProfiles(Context context) {
if (!BuildConfig.PGO_PROFILE_GENERATION) {
return 0;
}

System.loadLibrary("ExpensifyNitroUtils");
return writeProfiles(context.getCacheDir().getAbsolutePath());
}
}
1 change: 1 addition & 0 deletions ios/NewExpensify/RCTBootSplash.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

+ (void)initWithStoryboard:(NSString * _Nonnull)storyboardName
rootView:(UIView * _Nullable)rootView;
+ (void)initializePGOProfileCollection;
+ (void)hide:(BOOL)fade;
+ (void)bringSubviewToFrontIfInitialized;

Expand Down
124 changes: 124 additions & 0 deletions ios/NewExpensify/RCTBootSplash.mm
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,62 @@
#import <React/RCTSurfaceHostingView.h>
#import <React/RCTRootView.h>

#ifndef EXPENSIFY_PGO_GENERATE
#define EXPENSIFY_PGO_GENERATE 0
#endif

#if EXPENSIFY_PGO_GENERATE
#include <dlfcn.h>

extern "C" void __llvm_profile_set_filename(const char *FilenamePat);
extern "C" int __llvm_profile_write_file(void);
extern "C" void __llvm_profile_reset_counters(void);

using PGOSetFilename = void (*)(const char *);
using PGOWriteFile = int (*)();
using PGOResetCounters = void (*)();

template <typename Function>
static Function HermesPGOFunction(const char *symbol) {
return reinterpret_cast<Function>(dlsym(RTLD_DEFAULT, symbol));
}
#endif

static NSString *const PGO_DIRECTORY_NAME = @"ExpensifyPGO";
static NSString *const PGO_STATUS_MARKER = @"profile-status.txt";
static CFStringRef const PGO_WRITE_NOTIFICATION = CFSTR("com.expensify.pgo.write-profiles");
static CFStringRef const PGO_CLEAR_NOTIFICATION = CFSTR("com.expensify.pgo.clear-profiles");

static RCTSurfaceHostingProxyRootView *_rootView = nil;

static UIView *_loadingView = nil;
static NSMutableArray<RCTPromiseResolveBlock> *_resolveQueue = [[NSMutableArray alloc] init];
static bool _fade = false;
static bool _nativeHidden = false;

static long long CurrentTimeMilliseconds(void) {
return (long long)([[NSDate date] timeIntervalSince1970] * 1000);
}

@interface RCTBootSplash ()
+ (NSURL *)pgoDirectoryURL;
+ (void)writePGOStatus:(NSString *)status result:(int)result;
+ (void)writePGOProfiles;
+ (void)clearPGOProfiles;
@end

static void HandlePGONotification(__unused CFNotificationCenterRef center,
__unused void *observer,
CFStringRef name,
__unused const void *object,
__unused CFDictionaryRef userInfo) {
if (CFEqual(name, PGO_WRITE_NOTIFICATION)) {
[RCTBootSplash writePGOProfiles];
} else if (CFEqual(name, PGO_CLEAR_NOTIFICATION)) {
[RCTBootSplash clearPGOProfiles];
}
}

@implementation RCTBootSplash

RCT_EXPORT_MODULE();
Expand All @@ -32,6 +81,81 @@ + (BOOL)requiresMainQueueSetup {
return NO;
}

+ (NSURL *)pgoDirectoryURL {
NSURL *cachesURL = [[[NSFileManager defaultManager] URLsForDirectory:NSCachesDirectory
inDomains:NSUserDomainMask] firstObject];
NSURL *directoryURL = [cachesURL URLByAppendingPathComponent:PGO_DIRECTORY_NAME isDirectory:YES];
[[NSFileManager defaultManager] createDirectoryAtURL:directoryURL
withIntermediateDirectories:YES
attributes:nil
error:nil];
return directoryURL;
}

+ (void)writePGOStatus:(NSString *)status result:(int)result {
NSString *contents = [NSString stringWithFormat:@"%lld,%@,%d", CurrentTimeMilliseconds(), status, result];
NSURL *statusURL = [[self pgoDirectoryURL] URLByAppendingPathComponent:PGO_STATUS_MARKER];
[contents writeToURL:statusURL atomically:YES encoding:NSUTF8StringEncoding error:nil];
}

+ (void)initializePGOProfileCollection {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
CFNotificationCenterRef notificationCenter = CFNotificationCenterGetDarwinNotifyCenter();
CFNotificationCenterAddObserver(notificationCenter, NULL, HandlePGONotification, PGO_WRITE_NOTIFICATION, NULL, CFNotificationSuspensionBehaviorDeliverImmediately);
CFNotificationCenterAddObserver(notificationCenter, NULL, HandlePGONotification, PGO_CLEAR_NOTIFICATION, NULL, CFNotificationSuspensionBehaviorDeliverImmediately);

#if EXPENSIFY_PGO_GENERATE
NSString *profilePattern = [[[self pgoDirectoryURL] URLByAppendingPathComponent:@"newdot-%m.profraw"] path];
__llvm_profile_set_filename(profilePattern.fileSystemRepresentation);
PGOSetFilename setHermesFilename = HermesPGOFunction<PGOSetFilename>("expensify_llvm_profile_set_filename");
if (setHermesFilename != nullptr) {
setHermesFilename(profilePattern.fileSystemRepresentation);
}
#endif
});
}

+ (void)writePGOProfiles {
#if EXPENSIFY_PGO_GENERATE
int appResult = __llvm_profile_write_file();
PGOWriteFile writeHermesFile = HermesPGOFunction<PGOWriteFile>("expensify_llvm_profile_write_file");
int hermesResult = writeHermesFile != nullptr ? writeHermesFile() : 1;
int result = appResult == 0 && hermesResult == 0 ? 0 : 1;
[self writePGOStatus:@"written" result:result];
NSLog(@"ExpensifyPGO: wrote LLVM profile with result=%d appResult=%d hermesResult=%d", result, appResult, hermesResult);
#else
[self writePGOStatus:@"not-instrumented" result:1];
NSLog(@"ExpensifyPGO: ignored profile write in a non-instrumented build");
#endif
}

+ (void)clearPGOProfiles {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *directoryURL = [self pgoDirectoryURL];
NSArray<NSURL *> *files = [fileManager contentsOfDirectoryAtURL:directoryURL
includingPropertiesForKeys:nil
options:0
error:nil];
for (NSURL *fileURL in files) {
if ([fileURL.lastPathComponent hasSuffix:@".profraw"] || [fileURL.lastPathComponent isEqualToString:PGO_STATUS_MARKER]) {
[fileManager removeItemAtURL:fileURL error:nil];
}
}

#if EXPENSIFY_PGO_GENERATE
__llvm_profile_reset_counters();
PGOResetCounters resetHermesCounters = HermesPGOFunction<PGOResetCounters>("expensify_llvm_profile_reset_counters");
int result = resetHermesCounters != nullptr ? 0 : 1;
if (resetHermesCounters != nullptr) {
resetHermesCounters();
}
[self writePGOStatus:@"cleared" result:result];
#else
[self writePGOStatus:@"not-instrumented" result:1];
#endif
}

+ (bool)isLoadingViewVisible {
return _loadingView != nil && ![_loadingView isHidden];
}
Expand Down
2 changes: 1 addition & 1 deletion knip.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,5 @@
"diff-so-fancy",
"@babel/plugin-proposal-class-properties"
],
"ignoreBinaries": ["metro-symbolicate", "mkcert", "openssl"]
"ignoreBinaries": ["metro-symbolicate", "mkcert", "openssl", "agent-device"]
}
Loading