From c9aabccd84b2832dd557e73377f220657b54c7f3 Mon Sep 17 00:00:00 2001 From: EthanShoeDev <13422990+EthanShoeDev@users.noreply.github.com> Date: Tue, 16 Sep 2025 19:23:08 -0400 Subject: [PATCH] inline styles --- apps/mobile/package.json | 6 +- apps/mobile/src/app/(modals)/key-manager.tsx | 3 - apps/mobile/src/app/(tabs)/index.tsx | 429 ++++++++---------- apps/mobile/src/app/(tabs)/settings/index.tsx | 167 +++---- apps/mobile/src/app/(tabs)/shell/detail.tsx | 207 ++++----- apps/mobile/src/app/(tabs)/shell/index.tsx | 324 ++++++------- apps/mobile/src/app/_layout.tsx | 10 + .../mobile/src/components/form-components.tsx | 165 ++++--- .../src/components/key-manager/KeyList.tsx | 171 +++---- pnpm-lock.yaml | 284 ++++++------ 10 files changed, 887 insertions(+), 879 deletions(-) diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 52e3473..568e352 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -36,9 +36,9 @@ "@tanstack/react-form": "^1.20.0", "@tanstack/react-query": "^5.87.4", "date-fns": "^4.1.0", - "expo": "54.0.7", + "expo": "54.0.8", "expo-clipboard": "~8.0.7", - "expo-constants": "~18.0.8", + "expo-constants": "~18.0.9", "expo-crypto": "~15.0.7", "expo-dev-client": "~6.0.12", "expo-document-picker": "~14.0.7", @@ -48,7 +48,7 @@ "expo-haptics": "~15.0.7", "expo-image": "~3.0.8", "expo-linking": "~8.0.8", - "expo-router": "6.0.5", + "expo-router": "6.0.6", "expo-secure-store": "~15.0.7", "expo-splash-screen": "~31.0.10", "expo-status-bar": "~3.0.8", diff --git a/apps/mobile/src/app/(modals)/key-manager.tsx b/apps/mobile/src/app/(modals)/key-manager.tsx index def48b8..8e8f264 100644 --- a/apps/mobile/src/app/(modals)/key-manager.tsx +++ b/apps/mobile/src/app/(modals)/key-manager.tsx @@ -28,6 +28,3 @@ export default function KeyManagerModalRoute() { ); } - -// // styles kept for potential future local additions -// const styles = StyleSheet.create({}); diff --git a/apps/mobile/src/app/(tabs)/index.tsx b/apps/mobile/src/app/(tabs)/index.tsx index 3acfa5b..298763b 100644 --- a/apps/mobile/src/app/(tabs)/index.tsx +++ b/apps/mobile/src/app/(tabs)/index.tsx @@ -2,14 +2,7 @@ import SegmentedControl from '@react-native-segmented-control/segmented-control' import { useStore } from '@tanstack/react-form'; import { useQuery } from '@tanstack/react-query'; import React from 'react'; -import { - Modal, - Pressable, - ScrollView, - StyleSheet, - Text, - View, -} from 'react-native'; +import { Modal, Pressable, ScrollView, Text, View } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { useAppForm, useFieldContext } from '@/components/form-components'; import { KeyList } from '@/components/key-manager/KeyList'; @@ -19,7 +12,7 @@ import { secretsManager, type InputConnectionDetails, } from '@/lib/secrets-manager'; -import { useTheme, type AppTheme } from '@/lib/theme'; +import { useTheme } from '@/lib/theme'; export default function TabsIndex() { return ; @@ -37,7 +30,6 @@ const defaultValues: InputConnectionDetails = { function Host() { const theme = useTheme(); - const styles = React.useMemo(() => makeStyles(theme), [theme]); // const insets = useSafeAreaInsets(); const sshConnMutation = useSshConnMutation(); const connectionForm = useAppForm({ @@ -62,23 +54,74 @@ function Host() { return ( - - fressh - A fast, friendly SSH client + + + fressh + + + A fast, friendly SSH client + - - Connect to SSH Server - Enter your server credentials + + + Connect to SSH Server + + + Enter your server credentials + @@ -114,7 +157,7 @@ function Host() { {(field) => ( - + )} - + makeStyles(theme), [theme]); const field = useFieldContext(); const [open, setOpen] = React.useState(false); @@ -216,10 +258,29 @@ function KeyIdPickerField() { return ( <> - - Private Key + + + Private Key + { void listPrivateKeysQuery.refetch(); setOpen(true); @@ -228,7 +289,7 @@ function KeyIdPickerField() { {display} {!selected && ( - + Open Key Manager to add/select a key )} @@ -239,15 +300,59 @@ function KeyIdPickerField() { animationType="slide" onRequestClose={() => setOpen(false)} > - - - - Select Key + + + + + Select Key + setOpen(false)} > - Close + + Close + void; }) { const theme = useTheme(); - const styles = React.useMemo(() => makeStyles(theme), [theme]); const listConnectionsQuery = useQuery(secretsManager.connections.query.list); return ( - - Previous Connections + + + Previous Connections + {listConnectionsQuery.isLoading ? ( - Loading connections... + + Loading connections... + ) : listConnectionsQuery.isError ? ( - Error loading connections + + Error loading connections + ) : listConnectionsQuery.data?.length ? ( - + {listConnectionsQuery.data?.map((conn) => ( ) : ( - No saved connections yet + + No saved connections yet + )} ); @@ -300,223 +421,51 @@ function ConnectionRow(props: { onSelect: (connection: InputConnectionDetails) => void; }) { const theme = useTheme(); - const styles = React.useMemo(() => makeStyles(theme), [theme]); const detailsQuery = useQuery(secretsManager.connections.query.get(props.id)); const details = detailsQuery.data?.value; return ( { if (details) props.onSelect(details); }} disabled={!details} > - - + + {details ? `${details.username}@${details.host}` : 'Loading...'} - + {details ? `Port ${details.port} • ${details.security.type}` : ''} - + + › + ); } - -function makeStyles(theme: AppTheme) { - return StyleSheet.create({ - container: { - flex: 1, - padding: 24, - backgroundColor: theme.colors.background, - justifyContent: 'center', - }, - scrollContent: { - paddingBottom: 32, - }, - header: { - marginBottom: 16, - alignItems: 'center', - }, - appName: { - fontSize: 28, - fontWeight: '800', - color: theme.colors.textPrimary, - letterSpacing: 1, - }, - appTagline: { - marginTop: 4, - fontSize: 13, - color: theme.colors.muted, - }, - card: { - backgroundColor: theme.colors.surface, - borderRadius: 20, - padding: 24, - marginHorizontal: 4, - shadowColor: theme.colors.shadow, - shadowOpacity: 0.3, - shadowRadius: 16, - shadowOffset: { width: 0, height: 4 }, - elevation: 8, - borderWidth: 1, - borderColor: theme.colors.borderStrong, - }, - title: { - fontSize: 24, - fontWeight: '700', - color: theme.colors.textPrimary, - marginBottom: 6, - letterSpacing: 0.5, - }, - subtitle: { - fontSize: 15, - color: theme.colors.muted, - marginBottom: 24, - lineHeight: 20, - }, - inputGroup: { - marginBottom: 12, - }, - label: { - marginBottom: 6, - fontSize: 14, - color: theme.colors.textSecondary, - fontWeight: '600', - }, - input: { - borderWidth: 1, - borderColor: theme.colors.border, - backgroundColor: theme.colors.inputBackground, - color: theme.colors.textPrimary, - borderRadius: 10, - paddingHorizontal: 12, - paddingVertical: 12, - fontSize: 16, - }, - errorText: { - marginTop: 6, - color: theme.colors.danger, - fontSize: 12, - }, - actions: { - marginTop: 20, - }, - mutedText: { - color: theme.colors.muted, - fontSize: 14, - }, - submitButton: { - backgroundColor: theme.colors.primary, - borderRadius: 12, - paddingVertical: 16, - alignItems: 'center', - shadowColor: theme.colors.primary, - shadowOpacity: 0.3, - shadowRadius: 8, - shadowOffset: { width: 0, height: 2 }, - elevation: 4, - }, - submitButtonText: { - color: theme.colors.buttonTextOnPrimary, - fontWeight: '700', - fontSize: 16, - letterSpacing: 0.5, - }, - buttonDisabled: { - backgroundColor: theme.colors.primaryDisabled, - opacity: 0.6, - }, - secondaryButton: { - backgroundColor: theme.colors.transparent, - borderWidth: 1, - borderColor: theme.colors.border, - borderRadius: 12, - paddingVertical: 14, - alignItems: 'center', - marginTop: 12, - }, - secondaryButtonText: { - color: theme.colors.textSecondary, - fontWeight: '600', - fontSize: 14, - letterSpacing: 0.3, - }, - listSection: { - marginTop: 20, - }, - listTitle: { - fontSize: 16, - fontWeight: '700', - color: theme.colors.textPrimary, - marginBottom: 8, - }, - listContainer: { - // Intentionally empty for RN compatibility - }, - row: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - backgroundColor: theme.colors.inputBackground, - borderWidth: 1, - borderColor: theme.colors.border, - borderRadius: 12, - paddingHorizontal: 12, - paddingVertical: 12, - marginBottom: 8, - }, - rowTextContainer: { - flex: 1, - marginRight: 12, - }, - rowTitle: { - color: theme.colors.textPrimary, - fontSize: 15, - fontWeight: '600', - }, - rowSubtitle: { - color: theme.colors.muted, - marginTop: 2, - fontSize: 12, - }, - rowChevron: { - color: theme.colors.muted, - fontSize: 22, - paddingHorizontal: 4, - }, - modalOverlay: { - flex: 1, - backgroundColor: theme.colors.overlay, - justifyContent: 'flex-end', - }, - modalSheet: { - backgroundColor: theme.colors.background, - borderTopLeftRadius: 16, - borderTopRightRadius: 16, - padding: 16, - borderColor: theme.colors.borderStrong, - borderWidth: 1, - maxHeight: '85%', - }, - modalHeader: { - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', - marginBottom: 8, - }, - modalCloseButton: { - paddingHorizontal: 8, - paddingVertical: 6, - borderRadius: 8, - borderWidth: 1, - borderColor: theme.colors.border, - }, - modalCloseText: { - color: theme.colors.textSecondary, - fontWeight: '600', - }, - }); -} diff --git a/apps/mobile/src/app/(tabs)/settings/index.tsx b/apps/mobile/src/app/(tabs)/settings/index.tsx index 4770f7d..d77b429 100644 --- a/apps/mobile/src/app/(tabs)/settings/index.tsx +++ b/apps/mobile/src/app/(tabs)/settings/index.tsx @@ -1,18 +1,27 @@ import { Link } from 'expo-router'; import React from 'react'; -import { Pressable, StyleSheet, Text, View } from 'react-native'; -import { useTheme, useThemeControls, type AppTheme } from '@/lib/theme'; +import { Pressable, Text, View } from 'react-native'; +import { useTheme, useThemeControls } from '@/lib/theme'; export default function Tab() { const theme = useTheme(); - const styles = React.useMemo(() => makeStyles(theme), [theme]); const { themeName, setThemeName } = useThemeControls(); return ( - - - Theme - + + + + Theme + + - - Security + + + Security + - - Manage Keys - + + + Manage Keys + + + › + @@ -49,81 +95,40 @@ function Row({ onPress: () => void; }) { const theme = useTheme(); - const styles = React.useMemo(() => makeStyles(theme), [theme]); return ( - {label} - {selected ? '✔' : ''} + + {label} + + + {selected ? '✔' : ''} + ); } - -function makeStyles(theme: AppTheme) { - return StyleSheet.create({ - container: { - flex: 1, - padding: 16, - backgroundColor: theme.colors.background, - }, - // Title removed; screen header provides the title - section: { - marginBottom: 24, - }, - sectionTitle: { - color: theme.colors.textSecondary, - fontSize: 14, - marginBottom: 8, - }, - rowGroup: { gap: 8 }, - row: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - backgroundColor: theme.colors.surface, - borderWidth: 1, - borderColor: theme.colors.border, - borderRadius: 10, - paddingHorizontal: 12, - paddingVertical: 12, - }, - rowSelected: { - borderColor: theme.colors.primary, - }, - rowLabel: { - color: theme.colors.textPrimary, - fontSize: 16, - fontWeight: '600', - }, - rowCheck: { - color: theme.colors.primary, - fontSize: 16, - fontWeight: '800', - }, - callout: { - backgroundColor: theme.colors.surface, - borderWidth: 1, - borderColor: theme.colors.border, - borderRadius: 12, - paddingHorizontal: 12, - paddingVertical: 14, - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - }, - calloutLabel: { - color: theme.colors.textPrimary, - fontSize: 16, - fontWeight: '600', - }, - calloutChevron: { - color: theme.colors.muted, - fontSize: 22, - paddingHorizontal: 4, - }, - }); -} diff --git a/apps/mobile/src/app/(tabs)/shell/detail.tsx b/apps/mobile/src/app/(tabs)/shell/detail.tsx index f93a7c3..39d3711 100644 --- a/apps/mobile/src/app/(tabs)/shell/detail.tsx +++ b/apps/mobile/src/app/(tabs)/shell/detail.tsx @@ -6,7 +6,6 @@ import { Platform, Pressable, ScrollView, - StyleSheet, Text, TextInput, View, @@ -36,8 +35,6 @@ function ShellDetail() { : undefined; const [shellData, setShellData] = useState(''); - const [inputValue, setInputValue] = useState(''); - const hiddenInputRef = useRef(null); useEffect(() => { if (!connection) return; @@ -61,42 +58,11 @@ function ShellDetail() { scrollViewRef.current?.scrollToEnd({ animated: true }); }, [shellData]); - useEffect(() => { - const focusTimeout = setTimeout(() => { - hiddenInputRef.current?.focus(); - }, 0); - return () => clearTimeout(focusTimeout); - }, []); - - async function sendChunk(chunk: string) { - if (!shell || !chunk) return; - const bytes = Uint8Array.from(new TextEncoder().encode(chunk)).buffer; - try { - await shell.sendData(bytes); - } catch {} - } - return ( ( - router.back()} - hitSlop={10} - style={{ paddingHorizontal: 4, paddingVertical: 4 }} - > - - - ) - : undefined, headerRight: () => ( { - hiddenInputRef.current?.focus(); - return false; + style={{ + flex: 1, + backgroundColor: '#0E172B', + borderRadius: 12, + height: 400, + borderWidth: 1, + borderColor: '#2A3655', + overflow: 'hidden', + marginBottom: 12, }} > - + {shellData || 'Connected. Output will appear here...'} - { - if (!text) return; - await sendChunk(text); - setInputValue(''); - }} - onKeyPress={async (e) => { - const key = e.nativeEvent.key; - if (key === 'Backspace') { - await sendChunk('\b'); - } - }} - onSubmitEditing={async () => { - await sendChunk('\n'); - }} - style={styles.hiddenInput} - autoFocus - multiline - caretHidden - autoCorrect={false} - autoCapitalize="none" - keyboardType="visible-password" - blurOnSubmit={false} - /> + { + await shell?.sendData( + Uint8Array.from(new TextEncoder().encode(command + '\n')).buffer, + ); + }} + /> ); } -const styles = StyleSheet.create({ - container: { - flex: 1, - backgroundColor: '#0B1324', - padding: 12, - }, - terminal: { - flex: 1, - backgroundColor: '#0E172B', - borderRadius: 12, - borderWidth: 1, - borderColor: '#2A3655', - overflow: 'hidden', - marginBottom: 12, - }, - terminalContent: { - paddingHorizontal: 12, - paddingTop: 4, - paddingBottom: 12, - }, - terminalText: { - color: '#D1D5DB', - fontSize: 14, - lineHeight: 18, - fontFamily: Platform.select({ - ios: 'Menlo', - android: 'monospace', - default: 'monospace', - }), - }, - hiddenInput: { - position: 'absolute', - top: 0, - left: 0, - right: 0, - bottom: 0, - opacity: 0, - color: 'transparent', - }, -}); +function CommandInput(props: { + executeCommand: (command: string) => Promise; +}) { + const [command, setCommand] = useState(''); + + async function handleExecute() { + if (!command.trim()) return; + await props.executeCommand(command); + setCommand(''); + } + + return ( + + + + + Execute + + + + ); +} diff --git a/apps/mobile/src/app/(tabs)/shell/index.tsx b/apps/mobile/src/app/(tabs)/shell/index.tsx index 512d29a..f364ff0 100644 --- a/apps/mobile/src/app/(tabs)/shell/index.tsx +++ b/apps/mobile/src/app/(tabs)/shell/index.tsx @@ -13,7 +13,6 @@ import { Modal, Platform, Pressable, - StyleSheet, Text, View, } from 'react-native'; @@ -25,7 +24,7 @@ import { listSshShellsQueryOptions, type ShellWithConnection, } from '@/lib/query-fns'; -import { useTheme, type AppTheme } from '@/lib/theme'; +import { useTheme } from '@/lib/theme'; export default function TabsShellList() { const theme = useTheme(); @@ -59,10 +58,16 @@ function ShellContent() { function LoadingState() { const theme = useTheme(); - const styles = React.useMemo(() => makeStyles(theme), [theme]); return ( - - Loading... + + Loading... ); } @@ -177,7 +182,6 @@ function GroupedView({ setActionTarget: (target: ActionTarget) => void; }) { const theme = useTheme(); - const styles = React.useMemo(() => makeStyles(theme), [theme]); const [expanded, setExpanded] = React.useState>({}); return ( item.connectionId} renderItem={({ item }) => ( - + setExpanded((prev) => ({ ...prev, @@ -196,15 +210,27 @@ function GroupedView({ } > - + {item.connectionDetails.username}@{item.connectionDetails.host} - + Port {item.connectionDetails.port} • {item.shells.length} shell {item.shells.length === 1 ? '' : 's'} - + {expanded[item.connectionId] ? '▾' : '▸'} @@ -237,13 +263,19 @@ function GroupedView({ function EmptyState() { const theme = useTheme(); - const styles = React.useMemo(() => makeStyles(theme), [theme]); return ( - - + + No active shells. Connect from Host tab. - + Go to Hosts @@ -258,14 +290,23 @@ function ShellCard({ onLongPress?: () => void; }) { const theme = useTheme(); - const styles = React.useMemo(() => makeStyles(theme), [theme]); const router = useRouter(); const since = formatDistanceToNow(new Date(shell.createdAtMs), { addSuffix: true, }); return ( router.push({ pathname: '/shell/detail', @@ -278,16 +319,40 @@ function ShellCard({ onLongPress={onLongPress} > - + {shell.connection.connectionDetails.username}@ {shell.connection.connectionDetails.host} - + Port {shell.connection.connectionDetails.port} • {shell.pty} - Started {since} + + Started {since} + - + + › + ); } @@ -304,7 +369,6 @@ function ActionsSheet({ onDisconnect: () => void; }) { const theme = useTheme(); - const styles = React.useMemo(() => makeStyles(theme), [theme]); const open = !!target; return ( - - - Shell Actions + + + + Shell Actions + - - Close Shell + + + Close Shell + - - + + Disconnect Connection - - Cancel + + + Cancel + @@ -382,125 +522,3 @@ function HeaderViewModeButton() { ); } - -function makeStyles(theme: AppTheme) { - return StyleSheet.create({ - centerContent: { - flex: 1, - alignItems: 'center', - justifyContent: 'center', - gap: 12, - }, - mutedText: { color: theme.colors.muted }, - link: { color: theme.colors.primary, fontWeight: '600' }, - - // headerBar/title removed in favor of TopBarToggle - - groupContainer: { - gap: 12, - }, - groupHeader: { - backgroundColor: theme.colors.surface, - borderWidth: 1, - borderColor: theme.colors.border, - borderRadius: 12, - paddingHorizontal: 12, - paddingVertical: 12, - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - }, - groupTitle: { - color: theme.colors.textPrimary, - fontSize: 16, - fontWeight: '700', - }, - groupSubtitle: { - color: theme.colors.muted, - fontSize: 12, - marginTop: 2, - }, - groupChevron: { - color: theme.colors.muted, - fontSize: 18, - }, - - card: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - backgroundColor: theme.colors.inputBackground, - borderWidth: 1, - borderColor: theme.colors.border, - borderRadius: 12, - paddingHorizontal: 12, - paddingVertical: 12, - }, - cardTitle: { - color: theme.colors.textPrimary, - fontSize: 15, - fontWeight: '600', - }, - cardSubtitle: { - color: theme.colors.textSecondary, - fontSize: 12, - marginTop: 2, - }, - cardMeta: { - color: theme.colors.muted, - fontSize: 12, - marginTop: 6, - }, - cardChevron: { - color: theme.colors.muted, - fontSize: 22, - paddingHorizontal: 4, - }, - - modalOverlay: { - flex: 1, - backgroundColor: theme.colors.overlay, - justifyContent: 'flex-end', - }, - modalSheet: { - backgroundColor: theme.colors.background, - borderTopLeftRadius: 16, - borderTopRightRadius: 16, - padding: 16, - borderColor: theme.colors.borderStrong, - borderWidth: 1, - }, - title: { - color: theme.colors.textPrimary, - fontSize: 18, - fontWeight: '700', - }, - - primaryButton: { - backgroundColor: theme.colors.primary, - borderRadius: 12, - paddingVertical: 14, - alignItems: 'center', - }, - primaryButtonText: { - color: theme.colors.buttonTextOnPrimary, - fontWeight: '700', - fontSize: 14, - letterSpacing: 0.3, - }, - secondaryButton: { - backgroundColor: theme.colors.transparent, - borderWidth: 1, - borderColor: theme.colors.border, - borderRadius: 12, - paddingVertical: 14, - alignItems: 'center', - }, - secondaryButtonText: { - color: theme.colors.textSecondary, - fontWeight: '600', - fontSize: 14, - letterSpacing: 0.3, - }, - }); -} diff --git a/apps/mobile/src/app/_layout.tsx b/apps/mobile/src/app/_layout.tsx index d5676fc..b821b86 100644 --- a/apps/mobile/src/app/_layout.tsx +++ b/apps/mobile/src/app/_layout.tsx @@ -1,4 +1,5 @@ import { QueryClientProvider } from '@tanstack/react-query'; +import * as DevClient from 'expo-dev-client'; import { isLiquidGlassAvailable } from 'expo-glass-effect'; import { Stack } from 'expo-router'; import React from 'react'; @@ -10,6 +11,15 @@ console.log('Fressh App Init', { isLiquidGlassAvailable: isLiquidGlassAvailable(), }); +void DevClient.registerDevMenuItems([ + { + callback: () => { + console.log('Hello from dev menu'); + }, + name: 'Hello from dev menu', + }, +]); + export default function RootLayout() { return ( diff --git a/apps/mobile/src/components/form-components.tsx b/apps/mobile/src/components/form-components.tsx index b063527..75928b0 100644 --- a/apps/mobile/src/components/form-components.tsx +++ b/apps/mobile/src/components/form-components.tsx @@ -3,14 +3,7 @@ import { createFormHookContexts, useStore, } from '@tanstack/react-form'; -import { - Pressable, - StyleSheet, - Switch, - Text, - TextInput, - View, -} from 'react-native'; +import { Pressable, Switch, Text, TextInput, View } from 'react-native'; function FieldInfo() { const field = useFieldContext(); @@ -18,9 +11,11 @@ function FieldInfo() { const errorMessage = meta?.errors?.[0]; // TODO: typesafe errors return ( - + {errorMessage ? ( - {String(errorMessage)} + + {String(errorMessage)} + ) : null} ); @@ -36,10 +31,33 @@ export function TextField( const field = useFieldContext(); return ( - - {label ? {label} : null} + + {label ? ( + + {label} + + ) : null} (); return ( - - {label ? {label} : null} + + {label ? ( + + {label} + + ) : null} field.handleChange(Number(text))} @@ -84,10 +125,31 @@ export function SwitchField( const field = useFieldContext(); return ( - - {label ? {label} : null} + + {label ? ( + + {label} + + ) : null} field.handleChange(event.nativeEvent.value)} onBlur={field.handleBlur} @@ -114,13 +176,18 @@ export function SubmitButton( - + {isSubmitting ? 'Connecting...' : title} @@ -145,56 +212,4 @@ export const { useAppForm, withForm, withFieldGroup } = createFormHook({ formContext, }); -const styles = StyleSheet.create({ - inputGroup: { - marginBottom: 16, - }, - label: { - marginBottom: 6, - fontSize: 14, - color: '#C6CBD3', - fontWeight: '600', - }, - input: { - borderWidth: 1, - borderColor: '#2A3655', - backgroundColor: '#0E172B', - color: '#E5E7EB', - borderRadius: 10, - paddingHorizontal: 12, - paddingVertical: 12, - fontSize: 16, - }, - errorText: { - marginTop: 6, - color: '#FCA5A5', - fontSize: 12, - }, - submitButton: { - backgroundColor: '#2563EB', - borderRadius: 10, - paddingVertical: 14, - alignItems: 'center', - }, - submitButtonText: { - color: '#FFFFFF', - fontWeight: '700', - fontSize: 16, - }, - buttonDisabled: { - backgroundColor: '#3B82F6', - opacity: 0.6, - }, - fieldInfo: { - marginTop: 6, - color: '#FCA5A5', - fontSize: 12, - }, - pickerContainer: { - paddingHorizontal: 8, - paddingVertical: 4, - }, - picker: { - color: '#E5E7EB', - }, -}); +// Styles inlined per component diff --git a/apps/mobile/src/components/key-manager/KeyList.tsx b/apps/mobile/src/components/key-manager/KeyList.tsx index c15db25..d5554dd 100644 --- a/apps/mobile/src/components/key-manager/KeyList.tsx +++ b/apps/mobile/src/components/key-manager/KeyList.tsx @@ -1,13 +1,6 @@ import { useMutation, useQuery } from '@tanstack/react-query'; import React from 'react'; -import { - Pressable, - ScrollView, - StyleSheet, - Text, - TextInput, - View, -} from 'react-native'; +import { Pressable, ScrollView, Text, TextInput, View } from 'react-native'; import { secretsManager } from '@/lib/secrets-manager'; export type KeyListMode = 'manage' | 'select'; @@ -38,13 +31,19 @@ export function KeyList(props: { generateMutation.mutate()} > - + {generateMutation.isPending ? 'Generating…' : 'Generate New RSA 4096 Key'} @@ -52,9 +51,9 @@ export function KeyList(props: { {listKeysQuery.isLoading ? ( - Loading keys… + Loading keys… ) : listKeysQuery.isError ? ( - Error loading keys + Error loading keys ) : listKeysQuery.data?.length ? ( {listKeysQuery.data.map((k) => ( @@ -67,7 +66,7 @@ export function KeyList(props: { ))} ) : ( - No keys yet + No keys yet )} ); @@ -135,16 +134,41 @@ function KeyRow(props: { if (!entry) return null; return ( - + - + {entry.manifestEntry.metadata?.label ?? entry.manifestEntry.id} {entry.manifestEntry.metadata?.isDefault ? ' • Default' : ''} - ID: {entry.manifestEntry.id} + + ID: {entry.manifestEntry.id} + {props.mode === 'manage' ? ( ) : null} - + {props.mode === 'select' ? ( setDefaultMutation.mutate()} - style={styles.primaryButton} + style={{ + backgroundColor: '#2563EB', + borderRadius: 10, + paddingVertical: 12, + paddingHorizontal: 10, + alignItems: 'center', + }} > - Select + + Select + ) : null} {props.mode === 'manage' ? ( renameMutation.mutate(label)} disabled={renameMutation.isPending} > - + {renameMutation.isPending ? 'Saving…' : 'Save'} ) : null} {!entry.manifestEntry.metadata?.isDefault ? ( setDefaultMutation.mutate()} > - Set Default + + Set Default + ) : null} deleteMutation.mutate()} > - Delete + + Delete + ); } - -const styles = StyleSheet.create({ - primaryButton: { - backgroundColor: '#2563EB', - borderRadius: 10, - paddingVertical: 12, - alignItems: 'center', - marginBottom: 12, - }, - primaryButtonText: { color: '#FFFFFF', fontWeight: '700', fontSize: 14 }, - muted: { color: '#9AA0A6' }, - error: { color: '#FCA5A5' }, - row: { - flexDirection: 'row', - alignItems: 'flex-start', - justifyContent: 'space-between', - backgroundColor: '#0E172B', - borderWidth: 1, - borderColor: '#2A3655', - borderRadius: 12, - paddingHorizontal: 12, - paddingVertical: 12, - marginBottom: 10, - }, - rowTitle: { color: '#E5E7EB', fontSize: 15, fontWeight: '600' }, - rowSub: { color: '#9AA0A6', fontSize: 12, marginTop: 2 }, - rowActions: { gap: 6, alignItems: 'flex-end' }, - secondaryButton: { - backgroundColor: 'transparent', - borderWidth: 1, - borderColor: '#2A3655', - borderRadius: 10, - paddingVertical: 8, - paddingHorizontal: 10, - alignItems: 'center', - }, - secondaryButtonText: { color: '#C6CBD3', fontWeight: '600', fontSize: 12 }, - dangerButton: { - backgroundColor: 'transparent', - borderWidth: 1, - borderColor: '#7F1D1D', - borderRadius: 10, - paddingVertical: 8, - paddingHorizontal: 10, - alignItems: 'center', - }, - dangerButtonText: { color: '#FCA5A5', fontWeight: '700', fontSize: 12 }, - input: { - borderWidth: 1, - borderColor: '#2A3655', - backgroundColor: '#0E172B', - color: '#E5E7EB', - borderRadius: 10, - paddingHorizontal: 12, - paddingVertical: 10, - fontSize: 16, - marginTop: 8, - }, -}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 23f831c..787a6e5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -42,7 +42,7 @@ importers: dependencies: '@expo/vector-icons': specifier: ^15.0.2 - version: 15.0.2(expo-font@14.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + version: 15.0.2(expo-font@14.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) '@fressh/assets': specifier: workspace:* version: link:../../packages/assets @@ -74,59 +74,59 @@ importers: specifier: ^4.1.0 version: 4.1.0 expo: - specifier: 54.0.7 - version: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + specifier: 54.0.8 + version: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) expo-clipboard: specifier: ~8.0.7 - version: 8.0.7(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + version: 8.0.7(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) expo-constants: - specifier: ~18.0.8 - version: 18.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + specifier: ~18.0.9 + version: 18.0.9(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) expo-crypto: specifier: ~15.0.7 - version: 15.0.7(expo@54.0.7) + version: 15.0.7(expo@54.0.8) expo-dev-client: specifier: ~6.0.12 - version: 6.0.12(expo@54.0.7) + version: 6.0.12(expo@54.0.8) expo-document-picker: specifier: ~14.0.7 - version: 14.0.7(expo@54.0.7) + version: 14.0.7(expo@54.0.8) expo-file-system: specifier: ~19.0.14 - version: 19.0.14(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + version: 19.0.14(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) expo-font: specifier: ~14.0.8 - version: 14.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + version: 14.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) expo-glass-effect: specifier: ^0.1.3 - version: 0.1.3(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + version: 0.1.3(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) expo-haptics: specifier: ~15.0.7 - version: 15.0.7(expo@54.0.7) + version: 15.0.7(expo@54.0.8) expo-image: specifier: ~3.0.8 - version: 3.0.8(expo@54.0.7)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + version: 3.0.8(expo@54.0.8)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) expo-linking: specifier: ~8.0.8 - version: 8.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + version: 8.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) expo-router: - specifier: 6.0.5 - version: 6.0.5(750b4158402c81723fe42a215de7942a) + specifier: 6.0.6 + version: 6.0.6(be6ce5c43438e2db372447bf3c6a78fa) expo-secure-store: specifier: ~15.0.7 - version: 15.0.7(expo@54.0.7) + version: 15.0.7(expo@54.0.8) expo-splash-screen: specifier: ~31.0.10 - version: 31.0.10(expo@54.0.7) + version: 31.0.10(expo@54.0.8) expo-status-bar: specifier: ~3.0.8 version: 3.0.8(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) expo-symbols: specifier: ~1.0.7 - version: 1.0.7(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + version: 1.0.7(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) expo-system-ui: specifier: ~6.0.7 - version: 6.0.7(expo@54.0.7)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + version: 6.0.7(expo@54.0.8)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) react: specifier: 19.1.0 version: 19.1.0 @@ -1297,8 +1297,8 @@ packages: resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@expo/cli@54.0.5': - resolution: {integrity: sha512-8MZOZKHfHRHTBQu2/PXBi7eCKc2aF1i1JsZweL/P7aX8nivhrP6KV6An5PtO1/rrdnS9z7pmX2KwMygvvaFNhg==} + '@expo/cli@54.0.6': + resolution: {integrity: sha512-BgxJshNqSODb4Rq4q4lHLBVWVL4683Q+PSJ2fd+m3D5Jqd8nu9zGvcq6I/H8AXV/Ux31eIuUgAojPCjW8LRyZA==} hasBin: true peerDependencies: expo: '*' @@ -1348,8 +1348,8 @@ packages: '@expo/env@2.0.7': resolution: {integrity: sha512-BNETbLEohk3HQ2LxwwezpG8pq+h7Fs7/vAMP3eAtFT1BCpprLYoBBFZH7gW4aqGfqOcVP4Lc91j014verrYNGg==} - '@expo/fingerprint@0.15.0': - resolution: {integrity: sha512-PrLA6fxScZfnLy7OHZ2GHXsDG9YbE7L5DbNhion6j/U/O+FQgz4VbxJarW5C00kMg1ll2u6EghB7ENAvL1T4qg==} + '@expo/fingerprint@0.15.1': + resolution: {integrity: sha512-U1S9DwiapCHQjHdHDDyO/oXsl/1oEHSHZRRkWDDrHgXRUDiAVIySw9Unvvcr118Ee6/x4NmKSZY1X0VagrqmFg==} hasBin: true '@expo/image-utils@0.8.7': @@ -1361,6 +1361,14 @@ packages: '@expo/json-file@10.0.7': resolution: {integrity: sha512-z2OTC0XNO6riZu98EjdNHC05l51ySeTto6GP7oSQrCvQgG9ARBwD1YvMQaVZ9wU7p/4LzSf1O7tckL3B45fPpw==} + '@expo/mcp-tunnel@0.0.7': + resolution: {integrity: sha512-ht8Q1nKtiHobZqkUqt/7awwjW2D59ardP6XDVmGceGjQtoZELVaJDHyMIX+aVG9SZ9aj8+uGlhQYeBi57SZPMA==} + peerDependencies: + '@modelcontextprotocol/sdk': ^1.13.2 + peerDependenciesMeta: + '@modelcontextprotocol/sdk': + optional: true + '@expo/metro-config@54.0.3': resolution: {integrity: sha512-TQ5MKSGFB6zJxi+Yr8VYXQFHzRXgvSJzNsHX1otTqnxjXbptwYiXhljAqGSjr3pByq4+sHX/GifMk6fGgAANmA==} peerDependencies: @@ -1387,8 +1395,8 @@ packages: resolution: {integrity: sha512-IClSOXxR0YUFxIriUJVqyYki7lLMIHrrzOaP01yxAL1G8pj2DWV5eW1y5jSzIcIfSCNhtGsshGd1tU/AYup5iQ==} engines: {node: '>=12'} - '@expo/package-manager@1.9.7': - resolution: {integrity: sha512-k3uky8Qzlv21rxuPvP2KUTAy8NI0b/LP7BSXcwJpS/rH7RmiAqUXgzPar3I1OmKGgxpod78Y9Mae//F8d3aiOQ==} + '@expo/package-manager@1.9.8': + resolution: {integrity: sha512-4/I6OWquKXYnzo38pkISHCOCOXxfeEmu4uDoERq1Ei/9Ur/s9y3kLbAamEkitUkDC7gHk1INxRWEfFNzGbmOrA==} '@expo/plist@0.4.6': resolution: {integrity: sha512-6yklhtUWohs1rBSC8dGyBBpElEbosjXN0zJN/+1/B121n7pPWvd9y/UGJm+2x7b81VnW3AHmWVnbU/u0INQsqA==} @@ -4704,8 +4712,8 @@ packages: react: '*' react-native: '*' - expo-constants@18.0.8: - resolution: {integrity: sha512-Tetphsx6RVImCTZeBAclRQMy0WOODY3y6qrUoc88YGUBVm8fAKkErCSWxLTCc6nFcJxdoOMYi62LgNIUFjZCLA==} + expo-constants@18.0.9: + resolution: {integrity: sha512-sqoXHAOGDcr+M9NlXzj1tGoZyd3zxYDy215W6E0Z0n8fgBaqce9FAYQE2bu5X4G629AYig5go7U6sQz7Pjcm8A==} peerDependencies: expo: '*' react-native: '*' @@ -4796,24 +4804,24 @@ packages: peerDependencies: expo: '*' - expo-modules-autolinking@3.0.10: - resolution: {integrity: sha512-6pwaz9H7aK/iYraHbX7zjg8QFTUuMfGEs8Vyc6bAoBd8Rovtb91WX955Kq5sazwNrQjs3WePwQ23LEAmls3u5g==} + expo-modules-autolinking@3.0.11: + resolution: {integrity: sha512-Sz1ptcSZ4mvWJ7Rf1aB6Pe1fuEeIkACPILg2tmXDo3wwLTxPqugitMOePjbBZyvacBDirtDZlMb2A6LQDPVFOg==} hasBin: true - expo-modules-core@3.0.15: - resolution: {integrity: sha512-vGI7osd0/IjprldD08k4bckWSu7ID4HhZNP68l/UtilONQ8XZig8mWJd/Fm7i7KGvE3HyuF+HOXE9l671no42Q==} + expo-modules-core@3.0.16: + resolution: {integrity: sha512-rCxzJiTdeSdqLVmDYYnogxqHS3NB65YTd76tAtSACujN2TQco08/toxCCov+9uULq1NGPxDJnfTkrtGaGWfatQ==} peerDependencies: react: '*' react-native: '*' - expo-router@6.0.5: - resolution: {integrity: sha512-FK5y/55ppv54WjW7W7X4g5J3r+hiMKHukRYjyS6KI4i92qOWtVF42yssD/Ty90EpjKuZ8N1F72FJGdx9A1UQNA==} + expo-router@6.0.6: + resolution: {integrity: sha512-uSuKQanivBI9RtwmAznLI7It5aPwQLVL2tVBPAOJ70tv6BzP62SpVCf0I8o0j9PmEzORPRLrU2LbQOL962yBHg==} peerDependencies: '@expo/metro-runtime': ^6.1.2 '@react-navigation/drawer': ^7.5.0 '@testing-library/react-native': '>= 12.0.0' expo: '*' - expo-constants: ^18.0.8 + expo-constants: ^18.0.9 expo-linking: ^8.0.8 react: '*' react-dom: '*' @@ -4877,8 +4885,8 @@ packages: peerDependencies: expo: '*' - expo@54.0.7: - resolution: {integrity: sha512-DftN6nMdpHYUCw5Xnh7+h7wnusjtly4JzQknvuD7MzIvqoyJL9uffQyMQrmZkXrUbgm+cKBm47vtooIz4qj0Qg==} + expo@54.0.8: + resolution: {integrity: sha512-H4nUVvAczd9ZPWrAR3oXxEr/EkLfPxXg5gBvFgZI4WnGNthehqEYB37urXgj9fvgSBxNaRUkySL4uwr9VB2J8Q==} hasBin: true peerDependencies: '@expo/dom-webview': '*' @@ -9908,7 +9916,7 @@ snapshots: '@eslint/core': 0.15.2 levn: 0.4.1 - '@expo/cli@54.0.5(expo-router@6.0.5)(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))': + '@expo/cli@54.0.6(expo-router@6.0.6)(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))': dependencies: '@0no-co/graphql.web': 1.2.0 '@expo/code-signing-certificates': 0.0.5 @@ -9918,12 +9926,13 @@ snapshots: '@expo/env': 2.0.7 '@expo/image-utils': 0.8.7 '@expo/json-file': 10.0.7 + '@expo/mcp-tunnel': 0.0.7 '@expo/metro': 0.1.1 - '@expo/metro-config': 54.0.3(expo@54.0.7) + '@expo/metro-config': 54.0.3(expo@54.0.8) '@expo/osascript': 2.3.7 - '@expo/package-manager': 1.9.7 + '@expo/package-manager': 1.9.8 '@expo/plist': 0.4.7 - '@expo/prebuild-config': 54.0.3(expo@54.0.7) + '@expo/prebuild-config': 54.0.3(expo@54.0.8) '@expo/schema-utils': 0.1.7 '@expo/server': 0.7.4 '@expo/spawn-async': 1.7.2 @@ -9943,7 +9952,7 @@ snapshots: connect: 3.7.0 debug: 4.4.1 env-editor: 0.4.2 - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) freeport-async: 2.0.0 getenv: 2.0.0 glob: 10.4.5 @@ -9975,9 +9984,10 @@ snapshots: wrap-ansi: 7.0.0 ws: 8.18.3 optionalDependencies: - expo-router: 6.0.5(750b4158402c81723fe42a215de7942a) + expo-router: 6.0.6(be6ce5c43438e2db372447bf3c6a78fa) react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) transitivePeerDependencies: + - '@modelcontextprotocol/sdk' - bufferutil - graphql - supports-color @@ -10091,7 +10101,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@expo/fingerprint@0.15.0': + '@expo/fingerprint@0.15.1': dependencies: '@expo/spawn-async': 1.7.2 arg: 5.0.2 @@ -10130,7 +10140,16 @@ snapshots: '@babel/code-frame': 7.10.4 json5: 2.2.3 - '@expo/metro-config@54.0.3(expo@54.0.7)': + '@expo/mcp-tunnel@0.0.7': + dependencies: + ws: 8.18.3 + zod: 3.25.76 + zod-to-json-schema: 3.24.6(zod@3.25.76) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@expo/metro-config@54.0.3(expo@54.0.8)': dependencies: '@babel/code-frame': 7.27.1 '@babel/core': 7.28.3 @@ -10154,16 +10173,16 @@ snapshots: postcss: 8.4.49 resolve-from: 5.0.0 optionalDependencies: - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - '@expo/metro-runtime@6.1.1(expo@54.0.7)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)': + '@expo/metro-runtime@6.1.1(expo@54.0.8)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)': dependencies: anser: 1.4.10 - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) pretty-format: 29.7.0 react: 19.1.0 react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) @@ -10196,7 +10215,7 @@ snapshots: '@expo/spawn-async': 1.7.2 exec-async: 2.2.0 - '@expo/package-manager@1.9.7': + '@expo/package-manager@1.9.8': dependencies: '@expo/json-file': 10.0.7 '@expo/spawn-async': 1.7.2 @@ -10217,7 +10236,7 @@ snapshots: base64-js: 1.5.1 xmlbuilder: 15.1.1 - '@expo/prebuild-config@54.0.3(expo@54.0.7)': + '@expo/prebuild-config@54.0.3(expo@54.0.8)': dependencies: '@expo/config': 12.0.9 '@expo/config-plugins': 54.0.1 @@ -10226,7 +10245,7 @@ snapshots: '@expo/json-file': 10.0.7 '@react-native/normalize-colors': 0.81.4 debug: 4.4.1 - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) resolve-from: 5.0.0 semver: 7.7.2 xml2js: 0.6.0 @@ -10250,9 +10269,9 @@ snapshots: '@expo/sudo-prompt@9.3.2': {} - '@expo/vector-icons@15.0.2(expo-font@14.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)': + '@expo/vector-icons@15.0.2(expo-font@14.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0)': dependencies: - expo-font: 14.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo-font: 14.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) react: 19.1.0 react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) @@ -12800,7 +12819,7 @@ snapshots: '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.3) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.3) - babel-preset-expo@54.0.1(@babel/core@7.28.3)(@babel/runtime@7.28.3)(expo@54.0.7)(react-refresh@0.14.2): + babel-preset-expo@54.0.1(@babel/core@7.28.3)(@babel/runtime@7.28.3)(expo@54.0.8)(react-refresh@0.14.2): dependencies: '@babel/helper-module-imports': 7.27.1 '@babel/plugin-proposal-decorators': 7.28.0(@babel/core@7.28.3) @@ -12827,7 +12846,7 @@ snapshots: resolve-from: 5.0.0 optionalDependencies: '@babel/runtime': 7.28.3 - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) transitivePeerDependencies: - '@babel/core' - supports-color @@ -14161,93 +14180,93 @@ snapshots: jest-mock: 30.0.5 jest-util: 30.0.5 - expo-asset@12.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): + expo-asset@12.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): dependencies: '@expo/image-utils': 0.8.7 - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-constants: 18.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo-constants: 18.0.9(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) react: 19.1.0 react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) transitivePeerDependencies: - supports-color - expo-clipboard@8.0.7(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): + expo-clipboard@8.0.7(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): dependencies: - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) react: 19.1.0 react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) - expo-constants@18.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)): + expo-constants@18.0.9(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)): dependencies: - '@expo/config': 12.0.8 + '@expo/config': 12.0.9 '@expo/env': 2.0.7 - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) transitivePeerDependencies: - supports-color - expo-crypto@15.0.7(expo@54.0.7): + expo-crypto@15.0.7(expo@54.0.8): dependencies: base64-js: 1.5.1 - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-dev-client@6.0.12(expo@54.0.7): + expo-dev-client@6.0.12(expo@54.0.8): dependencies: - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-dev-launcher: 6.0.11(expo@54.0.7) - expo-dev-menu: 7.0.11(expo@54.0.7) - expo-dev-menu-interface: 2.0.0(expo@54.0.7) - expo-manifests: 1.0.8(expo@54.0.7) - expo-updates-interface: 2.0.0(expo@54.0.7) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo-dev-launcher: 6.0.11(expo@54.0.8) + expo-dev-menu: 7.0.11(expo@54.0.8) + expo-dev-menu-interface: 2.0.0(expo@54.0.8) + expo-manifests: 1.0.8(expo@54.0.8) + expo-updates-interface: 2.0.0(expo@54.0.8) transitivePeerDependencies: - supports-color - expo-dev-launcher@6.0.11(expo@54.0.7): + expo-dev-launcher@6.0.11(expo@54.0.8): dependencies: - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-dev-menu: 7.0.11(expo@54.0.7) - expo-manifests: 1.0.8(expo@54.0.7) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo-dev-menu: 7.0.11(expo@54.0.8) + expo-manifests: 1.0.8(expo@54.0.8) transitivePeerDependencies: - supports-color - expo-dev-menu-interface@2.0.0(expo@54.0.7): + expo-dev-menu-interface@2.0.0(expo@54.0.8): dependencies: - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-dev-menu@7.0.11(expo@54.0.7): + expo-dev-menu@7.0.11(expo@54.0.8): dependencies: - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-dev-menu-interface: 2.0.0(expo@54.0.7) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo-dev-menu-interface: 2.0.0(expo@54.0.8) - expo-document-picker@14.0.7(expo@54.0.7): + expo-document-picker@14.0.7(expo@54.0.8): dependencies: - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-file-system@19.0.14(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)): + expo-file-system@19.0.14(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)): dependencies: - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) - expo-font@14.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): + expo-font@14.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): dependencies: - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) fontfaceobserver: 2.3.0 react: 19.1.0 react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) - expo-glass-effect@0.1.3(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): + expo-glass-effect@0.1.3(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): dependencies: - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) react: 19.1.0 react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) - expo-haptics@15.0.7(expo@54.0.7): + expo-haptics@15.0.7(expo@54.0.8): dependencies: - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-image@3.0.8(expo@54.0.7)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): + expo-image@3.0.8(expo@54.0.8)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): dependencies: - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) react: 19.1.0 react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) optionalDependencies: @@ -14255,14 +14274,14 @@ snapshots: expo-json-utils@0.15.0: {} - expo-keep-awake@15.0.7(expo@54.0.7)(react@19.1.0): + expo-keep-awake@15.0.7(expo@54.0.8)(react@19.1.0): dependencies: - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) react: 19.1.0 - expo-linking@8.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): + expo-linking@8.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): dependencies: - expo-constants: 18.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + expo-constants: 18.0.9(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) invariant: 2.2.4 react: 19.1.0 react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) @@ -14270,15 +14289,15 @@ snapshots: - expo - supports-color - expo-manifests@1.0.8(expo@54.0.7): + expo-manifests@1.0.8(expo@54.0.8): dependencies: '@expo/config': 12.0.8 - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) expo-json-utils: 0.15.0 transitivePeerDependencies: - supports-color - expo-modules-autolinking@3.0.10: + expo-modules-autolinking@3.0.11: dependencies: '@expo/spawn-async': 1.7.2 chalk: 4.1.2 @@ -14287,15 +14306,15 @@ snapshots: require-from-string: 2.0.2 resolve-from: 5.0.0 - expo-modules-core@3.0.15(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): + expo-modules-core@3.0.16(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): dependencies: invariant: 2.2.4 react: 19.1.0 react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) - expo-router@6.0.5(750b4158402c81723fe42a215de7942a): + expo-router@6.0.6(be6ce5c43438e2db372447bf3c6a78fa): dependencies: - '@expo/metro-runtime': 6.1.1(expo@54.0.7)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + '@expo/metro-runtime': 6.1.1(expo@54.0.8)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) '@expo/schema-utils': 0.1.7 '@expo/server': 0.7.4 '@radix-ui/react-slot': 1.2.0(@types/react@19.1.12)(react@19.1.0) @@ -14306,9 +14325,9 @@ snapshots: client-only: 0.0.1 debug: 4.4.1 escape-string-regexp: 4.0.0 - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-constants: 18.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) - expo-linking: 8.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo-constants: 18.0.9(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + expo-linking: 8.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) fast-deep-equal: 3.1.3 invariant: 2.2.4 nanoid: 3.3.11 @@ -14336,14 +14355,14 @@ snapshots: - '@types/react-dom' - supports-color - expo-secure-store@15.0.7(expo@54.0.7): + expo-secure-store@15.0.7(expo@54.0.8): dependencies: - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-splash-screen@31.0.10(expo@54.0.7): + expo-splash-screen@31.0.10(expo@54.0.8): dependencies: - '@expo/prebuild-config': 54.0.3(expo@54.0.7) - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + '@expo/prebuild-config': 54.0.3(expo@54.0.8) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) transitivePeerDependencies: - supports-color @@ -14353,56 +14372,57 @@ snapshots: react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) react-native-is-edge-to-edge: 1.2.1(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-symbols@1.0.7(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)): + expo-symbols@1.0.7(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)): dependencies: - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) sf-symbols-typescript: 2.1.0 - expo-system-ui@6.0.7(expo@54.0.7)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)): + expo-system-ui@6.0.7(expo@54.0.8)(react-native-web@0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)): dependencies: '@react-native/normalize-colors': 0.81.4 debug: 4.4.1 - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) optionalDependencies: react-native-web: 0.21.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0) transitivePeerDependencies: - supports-color - expo-updates-interface@2.0.0(expo@54.0.7): + expo-updates-interface@2.0.0(expo@54.0.8): dependencies: - expo: 54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo: 54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo@54.0.7(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.5)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): + expo@54.0.8(@babel/core@7.28.3)(@expo/metro-runtime@6.1.1)(expo-router@6.0.6)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0): dependencies: '@babel/runtime': 7.28.3 - '@expo/cli': 54.0.5(expo-router@6.0.5)(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + '@expo/cli': 54.0.6(expo-router@6.0.6)(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) '@expo/config': 12.0.9 '@expo/config-plugins': 54.0.1 '@expo/devtools': 0.1.7(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - '@expo/fingerprint': 0.15.0 + '@expo/fingerprint': 0.15.1 '@expo/metro': 0.1.1 - '@expo/metro-config': 54.0.3(expo@54.0.7) - '@expo/vector-icons': 15.0.2(expo-font@14.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + '@expo/metro-config': 54.0.3(expo@54.0.8) + '@expo/vector-icons': 15.0.2(expo-font@14.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) '@ungap/structured-clone': 1.3.0 - babel-preset-expo: 54.0.1(@babel/core@7.28.3)(@babel/runtime@7.28.3)(expo@54.0.7)(react-refresh@0.14.2) - expo-asset: 12.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-constants: 18.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) - expo-file-system: 19.0.14(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) - expo-font: 14.0.8(expo@54.0.7)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) - expo-keep-awake: 15.0.7(expo@54.0.7)(react@19.1.0) - expo-modules-autolinking: 3.0.10 - expo-modules-core: 3.0.15(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + babel-preset-expo: 54.0.1(@babel/core@7.28.3)(@babel/runtime@7.28.3)(expo@54.0.8)(react-refresh@0.14.2) + expo-asset: 12.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo-constants: 18.0.9(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + expo-file-system: 19.0.14(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0)) + expo-font: 14.0.8(expo@54.0.8)(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + expo-keep-awake: 15.0.7(expo@54.0.8)(react@19.1.0) + expo-modules-autolinking: 3.0.11 + expo-modules-core: 3.0.16(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) pretty-format: 29.7.0 react: 19.1.0 react-native: 0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0) react-refresh: 0.14.2 whatwg-url-without-unicode: 8.0.0-3 optionalDependencies: - '@expo/metro-runtime': 6.1.1(expo@54.0.7)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) + '@expo/metro-runtime': 6.1.1(expo@54.0.8)(react-dom@19.1.0(react@19.1.0))(react-native@0.81.4(@babel/core@7.28.3)(@react-native-community/cli@20.0.2(typescript@5.9.2))(@types/react@19.1.12)(react@19.1.0))(react@19.1.0) transitivePeerDependencies: - '@babel/core' + - '@modelcontextprotocol/sdk' - bufferutil - expo-router - graphql