Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
e7c3fbe
feat(storage): inspect and reset app data
lauridskern Oct 20, 2026
d8f5d48
chore(release): bump version to 0.1.172
lauridskern Oct 20, 2026
0a809a2
fix(storage): keep clearing app data in the panel
lauridskern Oct 20, 2026
df1f92b
feat(storage): redesign panel with search and a changes feed
lauridskern Oct 20, 2026
0435138
chore(release): bump version to 0.1.173
lauridskern Oct 20, 2026
d2c4a13
feat(storage): mark changes with plus, tilde, and minus icons
lauridskern Oct 20, 2026
9bf71e0
chore(release): bump version to 0.1.174
lauridskern Oct 20, 2026
25a0f67
feat(storage): lead change rows with a plain change icon
lauridskern Oct 20, 2026
deef96a
chore(release): bump version to 0.1.175
lauridskern Oct 20, 2026
ed0ddd3
feat(storage): mark changed keys with swap arrows
lauridskern Oct 20, 2026
f660603
chore(release): bump version to 0.1.176
lauridskern Oct 20, 2026
6a787f2
test(storage): add an Expo app that writes to every store
lauridskern Oct 20, 2026
126e472
feat(storage): build the header from shadcn components
lauridskern Oct 20, 2026
5757146
chore(release): bump version to 0.1.177
lauridskern Oct 20, 2026
04edfe5
style(storage): blend store icon tints into row backgrounds
lauridskern Oct 20, 2026
b9b6058
chore(release): bump version to 0.1.178
lauridskern Oct 20, 2026
d0d1960
fix(storage): blend only the icon tint so icons keep their color in d…
lauridskern Oct 20, 2026
3b9ca75
chore(release): bump version to 0.1.179
lauridskern Oct 20, 2026
d26b197
feat(ui): add small Tabs and InputGroup sizes and use them in the sto…
lauridskern Oct 20, 2026
c2ef80f
chore(release): bump version to 0.1.180
lauridskern Oct 20, 2026
db80e1c
feat(ui): share app icons across panels and show them in the storage …
lauridskern Oct 20, 2026
4d1b81f
chore(release): bump version to 0.1.181
lauridskern Oct 20, 2026
04ca183
style(storage): enlarge sidebar text and store icons one step
lauridskern Oct 20, 2026
d7e11b7
chore(release): bump version to 0.1.182
lauridskern Oct 20, 2026
5235054
fix(workspace): avoid a double border when the simulator area is coll…
lauridskern Oct 20, 2026
dc2ff81
chore(release): bump version to 0.1.183
lauridskern Oct 20, 2026
416825c
fix(ui): center select item content and show bundle IDs under app names
lauridskern Oct 20, 2026
9230530
chore(release): bump version to 0.1.184
lauridskern Oct 20, 2026
3b8281f
style(storage): show Files as a sidebar row and top-align row icons
lauridskern Oct 20, 2026
9d204a7
chore(release): bump version to 0.1.185
lauridskern Oct 20, 2026
c789b52
style(ui): blend app avatars into rows and offset top-aligned icons
lauridskern Oct 20, 2026
1f6cec2
chore(release): bump version to 0.1.186
lauridskern Oct 20, 2026
1e5de66
style(ui): nest small tab corners and outline the store Clear button
lauridskern Oct 20, 2026
4ba929f
chore(release): bump version to 0.1.187
lauridskern Oct 20, 2026
b7350ea
style(storage): tighten the gap between Copy as JSON and Clear
lauridskern Oct 20, 2026
482ada5
chore(release): bump version to 0.1.188
lauridskern Oct 20, 2026
b0a2039
style(storage): ring store icon tints for contrast on grey rows
lauridskern Oct 20, 2026
f7f6ad4
chore(release): bump version to 0.1.189
lauridskern Oct 20, 2026
92b2576
style(storage): give the Files icon the same tinted ring chip
lauridskern Oct 20, 2026
51d6827
chore(release): bump version to 0.1.190
lauridskern Oct 20, 2026
dc66d34
style(storage): use pastel tints with rings for icon chips
lauridskern Oct 20, 2026
588fc9b
chore(release): bump version to 0.1.191
lauridskern Oct 20, 2026
286563a
feat(storage): add a toggle to show SDK changes in the feed
lauridskern Oct 20, 2026
e9721ae
chore(release): bump version to 0.1.192
lauridskern Oct 20, 2026
9a3271c
feat(storage): browse SQLite tables as a paged grid
lauridskern Oct 20, 2026
a611c0a
chore(release): bump version to 0.1.193
lauridskern Oct 20, 2026
72aa466
style(storage): left-align numbers in the table grid
lauridskern Oct 20, 2026
a65dcb8
chore(release): bump version to 0.1.194
lauridskern Oct 20, 2026
7e4ef15
style(storage): show an open table in the store header
lauridskern Oct 20, 2026
649d61f
chore(release): bump version to 0.1.195
lauridskern Oct 20, 2026
42fbce3
style(storage): swap the database icon for the back button when a tab…
lauridskern Oct 20, 2026
36413bc
chore(release): bump version to 0.1.196
lauridskern Oct 20, 2026
f26a863
style(storage): drop the Your app label from the sidebar
lauridskern Oct 20, 2026
de6ddcd
chore(release): bump version to 0.1.197
lauridskern Oct 20, 2026
d704328
refactor(storage): decompose the storage UI and deduplicate its serve…
lauridskern Oct 20, 2026
c0e2731
chore(release): bump version to 0.1.198
lauridskern Oct 20, 2026
ac866f3
chore(release): bump version to 0.1.161
lauridskern Oct 20, 2026
2d4de7d
docs(telemetry): date storage telemetry to the release that ships it
lauridskern Oct 20, 2026
4ed2fef
fix(budget): apply Codex's tool size limits only to Agent Plugins
lauridskern Oct 21, 2026
6370c7e
Merge remote-tracking branch 'origin/main' into feat/app-storage
lauridskern Oct 21, 2026
dbfc49f
fix(workspace): keep tool menu IDs literal for the package smoke check
lauridskern Oct 21, 2026
43c736b
fix(storage): skip XML comments while tokenizing instead of stripping…
lauridskern Oct 21, 2026
8073a7f
fix(storage): show Android app labels and tidy Android store names
lauridskern Oct 21, 2026
df846c4
feat(storage): let the model read database tables and clear app data
lauridskern Oct 21, 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
2 changes: 1 addition & 1 deletion .codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mobile-dev",
"version": "0.1.160",
"version": "0.1.161",
"description": "Keep a simulator beside the chat while building, running, or debugging iOS and Android apps. Stream devices, read native and Metro logs, analyze CPU and React profiles with TraceSift, render interactive CPU, memory, and FPS recordings, and control apps with Mobile Dev tools.",
"author": {
"name": "Callstack"
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ Track app CPU and memory, expand individual thread charts, and view device-wide

![](/img/screenshot_performance.png)

### App storage
See what an app has saved without adding code to it: MMKV, AsyncStorage, UserDefaults, SharedPreferences, DataStore, SQLite databases, and the largest files in its data directory. Open SQLite tables as a paged grid, search across every store at once, and open the Changes tab to watch keys being added, changed, and removed while you use the app, with only the changed part of JSON values highlighted. SDK data from Firebase, Google Analytics and similar libraries is grouped separately. Clear one store or reset all app data. Works on iOS simulators and debuggable Android builds; MMKV value types are guessed from the stored bytes, and encrypted MMKV instances show as locked.


## Requirements

Expand Down Expand Up @@ -87,7 +90,7 @@ Ask Codex to work with your app, for example:
- “Record CPU and memory for 30 seconds while I scroll checkout.”
- “Compare these two performance recordings.”

Open Logs or Performance to inspect the selected device. Use Screenshot to attach
Open Logs, Performance, or Storage to inspect the selected device. Use Screenshot to attach
an image to your next message, or Select to annotate an element or region with an
instruction. Physical iOS supports taps and drags; keyboard and hardware-button
controls are unavailable.
Expand Down
2 changes: 1 addition & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ The retained, currently inactive Agent Device entry point is `dist/agent-device-

The wrapper uses an explicit empty package config and a private temporary state directory. Default platform and form selectors would bypass the native session's device binding, so those are set only through device setup commands. It clears inherited agent-device settings so a global or cloud daemon cannot take over this connection. Commands start its local daemon as needed. On MCP shutdown, the wrapper runs the bundled `daemon stop --state-dir <own-directory> --clean` command, which checks the daemon's PID identity and releases its runner leases. It keeps logs and artifacts in that state directory for later reads. Call agent-device `session` with `action: "state-dir"` to find it.

`npm run check:mcp-budget` reads the packaged servers' catalogs and estimates their model-visible specifications, including repeated namespace instructions and plugin attribution, before the host applies lossy schema compaction. With Agent Device deactivated, the current estimate is 45,315 bytes for 38 model-visible tools, below [Codex's shared 64,000-byte plugin budget](https://github.com/openai/codex/blob/main/codex-rs/core/src/mcp_tool_exposure.rs). The schema cleanup in 0.1.68 reduced the combined catalog from 238,784 to 99,568 bytes; temporarily removing its Agent Device entry makes room for the recording tools. Other enabled plugins also consume the shared budget. Splitting the same tools into more enabled MCP servers does not avoid it.
`npm run check:mcp-budget` reads the packaged servers' catalogs, estimates their model-visible specifications, and checks them against [Codex's tool limits](https://github.com/openai/codex/blob/main/codex-rs/core/src/mcp_tool_exposure.rs). Codex compacts any MCP tool input schema over 5,000 bytes, dropping descriptions, so the check fails when one exceeds it. Codex's 8,000-byte per-tool and 64,000-byte combined limits apply only to Agent Plugins, whose manifest is `plugin.json` at the plugin root; tools past them are hidden from the model. This plugin uses `.codex-plugin/plugin.json`, the legacy format, so those limits do not apply. Moving to the Agent Plugin format would hide part of the catalog, which is about 64 KB. On models that support tool search, Codex defers MCP tools from every plugin: they leave the initial tool list but stay discoverable and callable.

Use the panel's UDID and a named agent-device session for agent work. Refs belong to the latest snapshot or settled diff in that session. `press` and `fill` take a target such as `{ "kind": "ref", "ref": "@e12" }` or `{ "kind": "selector", "selector": "label=\"Search\"" }`. Use actual refs from the current result. Closing a session can close its app; leave `shutdown` unset to keep the simulator running. Another live agent-device daemon can own a runner lease. End that owner's work or choose another simulator instead of releasing its live claim.

Expand Down
20 changes: 19 additions & 1 deletion docs/telemetry.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,28 @@ memory cache and are returned only to the panel.

The device popover's App tab records `ui.app_tools.list`, `.icons`, `.launch`,
`.stop`, `.open_url`, `.permission`, `.push`, and `.language` round trips in
milliseconds with bounded aggregate windows, and counts `ui.app_tools.failure`.
milliseconds with bounded aggregate windows, and counts `ui.app_tools.failure`. Since 0.1.161 app icons come from a cache shared by
every panel in the view, so an icon requested by one panel is not fetched again by
another; each caller keeps its own timing name (`ui.app_tools.icons`, `ui.storage.icons`).
Results that finish after a surface or device change are not recorded. Recent URLs
and the last picked app stay in the panel's local storage and are never sent.

The Storage tool (`mobile_app_storage`, `mobile_app_storage_table`, `mobile_clear_app_storage`) uses the `storage`
surface. The server records `app_storage.operation.duration` in milliseconds and
`app_storage.operation.samples` per operation (`read`, `clear`, `reset`, `table`) with the device
platform and a success or failure outcome. The duration covers listing the data
directory, reading and decoding every recognized store, and for clears stopping the
app first. Unexpected failures report under `app_storage.<operation>` with a fixed
message; a release Android build, a missing app, or a stopped device counts only
through `server.error.outcome`. The panel records `ui.storage.list_apps`, `.icons`, `.read`, `.table`,
`.clear`, `.reset`, and `.launch` round trips, `ui.storage.process` for validating
a snapshot and computing the Changes feed, gauges `ui.storage.stores` and `ui.storage.entries`,
and counts `ui.storage.failure`. Bundle IDs, store names, paths, keys, values, and
file names are never sent; table names and cell values from `mobile_app_storage_table`
stay local too. Since 0.1.161 the Changes tab reads storage again every
5 seconds while it is open and the page is visible; each read is one `ui.storage.read`
sample, and the interval stops when the tab, panel, or page is hidden.

Since 0.1.152, `mobile_app_language` and `mobile_set_app_language` use the same
app control coverage under `app_control.language` and `app_control.set_language`.
Language tags are not sent. The device settings tools report unexpected Baguette or
Expand Down
46 changes: 46 additions & 0 deletions examples/storage-test-app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files

# dependencies
node_modules/

# Expo
.expo/
dist/
web-build/
expo-env.d.ts

# Native
.kotlin/
*.orig.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision

# Metro
.metro-health-check*

# debug
npm-debug.*
yarn-debug.*
yarn-error.*

# macOS
.DS_Store
*.pem

# local env files
.env*.local

# typescript
*.tsbuildinfo

# generated native folders
/ios
/android

# Generated native projects (npx expo prebuild)
/ios
/android
/.build
41 changes: 41 additions & 0 deletions examples/storage-test-app/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
This is an Expo/React Native mobile application. Prioritize mobile-first patterns, performance, and cross-platform compatibility.

## Expo has changed — do not trust your training data

Expo ships breaking changes every SDK release. APIs you remember are likely renamed, moved, or removed. Before writing any code that touches an Expo, EAS, or React Native API:

1. Read the major version of the `expo` package in `package.json`.
2. Fetch the matching versioned docs: `https://docs.expo.dev/versions/v<major>.0.0/`
3. For anything else, fetch https://docs.expo.dev/llms.txt — an index of all Expo docs with corrections to common LLM misconceptions. Follow its links to the specific page you need; never answer from memory.

## Commands

Use `bunx` instead of `npx` if the project uses bun (`bun.lock` present).

```bash
npx expo install <package> # ALWAYS use instead of npm/yarn/pnpm/bun add — resolves SDK-compatible versions
npx expo start # start the dev server
npx expo lint # lint
npx tsc --noEmit # typecheck
npx expo-doctor # diagnose dependency and config issues
npx expo install --fix # fix incompatible package versions
```

Run lint and typecheck before declaring any task done.

## Navigation & Routing

- Use **Expo Router** for all navigation. Routes live in `src/app/` — every file there is a screen, `_layout.tsx` files define navigators. Keep non-route code (components, hooks, utils) outside `src/app/`.
- Import `Link`, `router`, and `useLocalSearchParams` from `expo-router`.
- Docs: https://docs.expo.dev/router/introduction.md

## Building with EAS

Use EAS to build, sign, and submit the app in the cloud (`eas build`, `eas submit`) and to ship over-the-air updates (`eas update`) — no local Xcode or Android Studio required. Run EAS CLI as `bunx eas-cli <command>` in Bun projects, or `npx eas-cli@latest <command>` otherwise; substitute that for bare `eas` in docs examples.
Docs: https://docs.expo.dev/eas/index.md

## Rules

- If `ios/` and `android/` directories do not exist, they are generated (Continuous Native Generation). Never create or edit them by hand — configure native behavior in `app.json` and config plugins.
- Expo Go only includes its bundled native modules. After adding a library with native code, the app needs a development build: `npx expo run:ios|android` locally, or `eas build --profile development`.
- Prefer recommended Expo modules over third-party libraries, and check your available skills before adding dependencies. Docs: https://docs.expo.dev/versions/latest/index.md
87 changes: 87 additions & 0 deletions examples/storage-test-app/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { StatusBar } from "expo-status-bar";
import { useCallback, useEffect, useState } from "react";
import { AppState, Pressable, ScrollView, StyleSheet, Text, View } from "react-native";
import { SafeAreaProvider, SafeAreaView } from "react-native-safe-area-context";
import * as storage from "./src/storage";

type Action = { title: string; detail: string; run: () => unknown; destructive?: boolean };

const actions: Action[] = [
{ title: "Sign in", detail: "MMKV user + session, encrypted token, AsyncStorage user, lastLogin preference", run: storage.signIn },
{ title: "Sign out", detail: "Removes the sign-in keys", run: storage.signOut },
{ title: "Finish onboarding", detail: "Preference flag, MMKV step, typed iOS UserDefaults", run: storage.finishOnboarding },
{ title: "Reset onboarding", detail: "Removes or flips the onboarding keys", run: storage.resetOnboarding },
{ title: "Toggle theme", detail: "MMKV instance \"settings\" and a theme preference", run: storage.toggleTheme },
{ title: "Add todo", detail: "SQLite row in todos.db and an AsyncStorage draft", run: storage.addTodo },
{ title: "Save bytes", detail: "Binary MMKV value (shown as bytes)", run: storage.saveBytes },
{ title: "Write files", detail: "Documents/notes.txt and a 512 KB cache file", run: storage.writeFiles },
{ title: "Clear everything in the app", detail: "Wipes all stores from inside the app", run: storage.clearAll, destructive: true },
];

export default function App() {
const [readout, setReadout] = useState<storage.Readout>([]);
const [error, setError] = useState("");
const refresh = useCallback(() => { storage.readAll().then(setReadout, (reason: unknown) => setError(String(reason))); }, []);

useEffect(() => {
storage.recordLaunch().then(refresh, (reason: unknown) => setError(String(reason)));
// Re-read when the app returns to the foreground, for example after the tool cleared a store.
const subscription = AppState.addEventListener("change", state => { if (state === "active") refresh(); });
return () => subscription.remove();
}, [refresh]);

const run = async (action: Action) => {
setError("");
try { await action.run(); }
catch (reason) { setError(`${action.title} failed: ${String(reason)}`); }
refresh();
};

return <SafeAreaProvider><SafeAreaView style={styles.screen}>
<StatusBar style="dark" />
<ScrollView contentContainerStyle={styles.content}>
<Text style={styles.title}>Storage Test</Text>
<Text style={styles.subtitle}>Each button writes to real stores. Open Mobile Dev → Tools → Storage to watch them, ideally on the Changes tab.</Text>

<Text style={styles.section}>Actions</Text>
{actions.map(action => <Pressable key={action.title} testID={`action-${action.title}`} accessibilityRole="button" onPress={() => void run(action)}
style={({ pressed }) => [styles.action, pressed && styles.pressed]}>
<Text style={[styles.actionTitle, action.destructive && styles.destructive]}>{action.title}</Text>
<Text style={styles.actionDetail}>{action.detail}</Text>
</Pressable>)}

{error ? <Text style={styles.error}>{error}</Text> : null}

<View style={styles.sectionRow}>
<Text style={styles.section}>What the app reads</Text>
<Pressable accessibilityRole="button" onPress={refresh}><Text style={styles.link}>Refresh</Text></Pressable>
</View>
<View style={styles.card}>
{readout.map(row => <View key={row.label} style={styles.row}>
<Text style={styles.rowLabel}>{row.label}</Text>
<Text style={styles.rowValue} numberOfLines={2}>{row.value}</Text>
</View>)}
</View>
</ScrollView>
</SafeAreaView></SafeAreaProvider>;
}

const styles = StyleSheet.create({
screen: { flex: 1, backgroundColor: "#f6f6f7" },
content: { padding: 20, paddingBottom: 48 },
title: { fontSize: 28, fontWeight: "700", marginTop: 8 },
subtitle: { fontSize: 14, color: "#6b6b70", marginTop: 6, lineHeight: 20 },
section: { fontSize: 13, fontWeight: "600", color: "#6b6b70", textTransform: "uppercase", marginTop: 24, marginBottom: 8 },
sectionRow: { flexDirection: "row", justifyContent: "space-between", alignItems: "flex-end" },
link: { color: "#2563eb", fontSize: 14, marginBottom: 8 },
action: { backgroundColor: "white", borderRadius: 12, paddingVertical: 12, paddingHorizontal: 14, marginBottom: 8, borderWidth: StyleSheet.hairlineWidth, borderColor: "#d4d4d8" },
pressed: { opacity: 0.6 },
actionTitle: { fontSize: 16, fontWeight: "600" },
destructive: { color: "#dc2626" },
actionDetail: { fontSize: 13, color: "#6b6b70", marginTop: 2 },
error: { color: "#dc2626", marginTop: 8 },
card: { backgroundColor: "white", borderRadius: 12, borderWidth: StyleSheet.hairlineWidth, borderColor: "#d4d4d8" },
row: { flexDirection: "row", justifyContent: "space-between", gap: 12, paddingVertical: 10, paddingHorizontal: 14, borderBottomWidth: StyleSheet.hairlineWidth, borderBottomColor: "#e4e4e7" },
rowLabel: { fontSize: 14, color: "#3f3f46", flexShrink: 0 },
rowValue: { fontSize: 14, fontWeight: "500", flex: 1, textAlign: "right" },
});
50 changes: 50 additions & 0 deletions examples/storage-test-app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Storage test app

A small Expo app for testing the plugin's **Storage** tool. Each button writes
realistic data to every store the tool reads, and the app shows what it reads
back, so you can confirm that the tool's Clear and Reset reached the app.

| Store | Written by |
| --- | --- |
| MMKV `mmkv.default` | Sign in, Finish onboarding, Save bytes, launch counter |
| MMKV `settings` (custom ID) | Toggle theme |
| MMKV `secure` (encrypted) | Sign in; the tool should show it as locked |
| AsyncStorage | Sign in, Add todo, launch stats |
| UserDefaults (iOS) / SharedPreferences (Android) | Sign in, Finish onboarding, Toggle theme |
| Typed UserDefaults (iOS only) | Finish onboarding |
| SQLite `todos.db` | Add todo |
| Files | Write files: `notes.txt` and a 512 KB cache file |

- Bundle ID / package: `dev.mobile.storagetest`
- Display name: **Storage Test**

## Run

Boot a simulator or emulator in the Mobile Dev panel, then from the repository root:

```sh
./examples/storage-test-app/run.sh ios <booted-simulator-UDID>
./examples/storage-test-app/run.sh android <device-serial> # e.g. emulator-5554
```

The script installs npm dependencies on first run, builds a Release app with the
JavaScript bundle embedded, installs it and launches it. Metro is not needed. The
first build takes several minutes. Native projects are generated into the ignored
`ios/` and `android/` folders; `npx expo prebuild --clean` regenerates them.

Android release builds are normally not debuggable, and Android only lets the tool
read app data of debuggable builds. `plugins/debuggable-release.js` marks this app's
release build debuggable so it can be read without Metro.

## Things to try

1. Open **Tools → Storage**, pick **Storage Test**, and switch to **Changes**.
2. Tap **Sign in**, **Finish onboarding**, and **Add todo** in the app. Within about
five seconds each change appears, with only the changed part of JSON values highlighted.
3. On **Browse**, check that `secure` shows as locked, `avatar.header` shows as bytes,
and `todos.db` lists the `todos` table.
4. Search for `ada` to find the user across MMKV and AsyncStorage at once.
5. **Clear** one store or **Reset** all app data, relaunch the app, and check that
**What the app reads** shows the cleared values.

This app is a local test fixture and is not part of the plugin package.
28 changes: 28 additions & 0 deletions examples/storage-test-app/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"expo": {
"name": "Storage Test",
"slug": "storage-test-app",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",
"ios": {
"supportsTablet": true,
"bundleIdentifier": "dev.mobile.storagetest"
},
"android": {
"adaptiveIcon": {
"backgroundColor": "#E6F4FE",
"foregroundImage": "./assets/android-icon-foreground.png",
"backgroundImage": "./assets/android-icon-background.png",
"monochromeImage": "./assets/android-icon-monochrome.png"
},
"predictiveBackGestureEnabled": false,
"package": "dev.mobile.storagetest"
},
"plugins": [
"expo-sqlite",
"./plugins/debuggable-release"
]
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/storage-test-app/assets/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/storage-test-app/assets/splash-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions examples/storage-test-app/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { registerRootComponent } from 'expo';

import App from './App';

// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
// It also ensures that whether you load the app in Expo Go or in a native build,
// the environment is set up appropriately
registerRootComponent(App);
Loading
Loading