The Command Center tested the whole trimmed query as one substring against one concatenated haystack, so a query only matched when its words appeared consecutively, in that order, with that spacing. Typing `shortcuts` found "Keyboard shortcuts"; typing `short key` found nothing. Survivors were then ordered by a fixed group rank, so the best match was rarely first. Route both through `scoreTextFields`, the matcher the combobox, provider selection, directory suggestions and the daemon's history search already share. It splits on whitespace, scores each token against each field on its own, and requires every token to land somewhere. `short key`, `key short`, `workspace new` and `project add` all find their row now. The score is the filter: `scoreSearchFields` returns null when a token finds no home, so filtering and ranking are one pass rather than a boolean predicate that throws the scan away. Workspaces and agents are scored too, not just filtered, with each row's own ordering kept as the tiebreak. Fields are split into visible and hidden, so a match on an agent's `cwd` — which is never rendered — cannot outrank a match on its title. Subsequence matching is deliberately off here, unlike the composer's slash-command list where it makes `/pasbab` find `/paseo-babysit`. It widens far enough that three-letter typos hit several rows each, and this list preselects its first row, so a query that should find nothing would put an unrelated action under Enter. `MatchOptions.subsequence` defaults to on, leaving every other caller unchanged. The tier has to be suppressed during scoring rather than filtered afterwards, because a two-token total of tier 5 is either 0+5 or 4+1. Sections carry a band so the ones that reorder by relevance are compared before the pinned ones, which keeps the comparator total: file rows are matched by the daemon and carry no client-side score, so they cannot be relevance-compared against rows that do. Contiguous per-token matching is a strict widening of the old test. Tokens hold no whitespace and the old haystack joined fields with a space, so any token found there lay entirely within one field and is still found. Verified across a query set at zero rows lost, and pinned by a test.
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.