* fix(app): change the turn footer together with its messages The footer followed the agent directory while the messages followed the timeline catch-up, so a chat returning to a turn that ended in the background applied the idle snapshot first: the running footer vanished or a completed footer sat under stale messages until the catch-up landed. The timeline now holds the turn its messages were captured during, and releases it in the same store write as the rows that bring the chat current. While held, the footer shows an updating state in the running footer's slot. The sidebar, tab and composer keep reading the true status. Losing the connection does not release the hold. No catch-up can run or fail until the host returns, and releasing it would put a completed footer under messages known to be behind. * test(app): expect the updating flag on submission-only activity * fix(app): keep a failed catch-up from restoring the updating footer A subscription failure could land while the chat's cache read was still pending. The failure released the held turn, then the read restored the turn saved with the messages, and no catch-up remained to release it, so the chat showed a sync error beside "Updating...". The replica writes the held turn from the cache, so it now also hears when a catch-up settles or is owed again, and a read in flight respects it. * fix(app): keep the running footer until a chat's messages are current A separate catching-up footer added a visible state nobody asked for. A chat that is behind now keeps showing the running turn it already shows, so the idle status changes nothing on screen until the messages land with the completed footer. The held turn carries its start time, and saves it with the cached messages, so the elapsed timer keeps counting from the turn's real start through the hold and on first paint from cache. * fix(app): let a newer turn's timer replace a held one on hosts without turn ids Old hosts report a null turn id for every turn, so comparing ids alone kept the older turn's start time and the held footer counted from it until the chat caught up.
Welcome to your Expo app 👋
This is an Expo project created with create-expo-app.
Get started
-
Install dependencies
npm install -
Start the app
npx expo start
In the output, you'll find options to open the app in a
- development build
- Android emulator
- iOS simulator
- Expo Go, a limited sandbox for trying out app development with Expo
You can start developing by editing the files inside the app directory. This project uses file-based routing.
Get a fresh project
When you're ready, run:
npm run reset-project
This command will move the starter code to the app-example directory and create a blank app directory where you can start developing.
Learn more
To learn more about developing your project with Expo, look at the following resources:
- Expo documentation: Learn fundamentals, or go into advanced topics with our guides.
- Learn Expo tutorial: Follow a step-by-step tutorial where you'll create a project that runs on Android, iOS, and the web.
Join the community
Join our community of developers creating universal apps.
- Expo on GitHub: View our open source platform and contribute.
- Discord community: Chat with Expo users and ask questions.
Dictation debugging
Set EXPO_PUBLIC_ENABLE_AUDIO_DEBUG=1 before running npx expo start to render the in-app audio debug card. Pair it with the server-side STT_DEBUG_AUDIO_DIR flag so every dictation includes a copyable path to the saved raw audio file.