6.4 KiB
6.4 KiB
mobile-voice Agent Guide
This file defines package-specific guidance for agents working in packages/mobile-voice.
Scope And Precedence
- Follow root
AGENTS.mdfirst. - This file overrides root guidance for this package when rules conflict.
- If additional local guides are added later, treat the closest guide as highest priority.
Project Overview
- Expo + React Native app for voice dictation and OpenCode session monitoring.
- Uses native/device-heavy modules such as
whisper.rn,react-native-audio-api,expo-notifications, andexpo-camera. - Development builds are required for native module changes.
Commands
Run all commands from packages/mobile-voice.
- Install deps:
bun install - Start Metro:
bun run start - Start dev client server (recommended):
bunx expo start --dev-client --clear --host lan - iOS run:
bun run ios - Android run:
bun run android - Lint:
bun run lint - Typecheck:
bun run typecheck - Expo doctor:
bunx expo-doctor - Dependency compatibility check:
bunx expo install --check - Export bundle smoke test:
bunx expo export --platform ios --clear
Build / Verification Expectations
- For JS-only changes: run
bun run lintand verify app behavior via dev client. - For TS-heavy refactors: run
bun run typecheckin addition to lint. - For native dependency/config/plugin changes: rebuild dev client via EAS before validation.
- If notifications, camera, microphone, or audio-session behavior changes, verify on a physical iOS device.
- Do not claim a fix unless you validated in Metro logs and app runtime behavior.
Single-Test Guidance
- This package currently has no dedicated unit test script.
- Use targeted validation commands instead:
bun run lintbun run typecheckbunx expo export --platform ios --clear- manual runtime test in dev client
Architecture Priorities
- Keep screens focused on composition and orchestration. Once a screen owns multiple workflows, extract hooks/components before adding more local state.
- Prefer extracting pure helpers and config objects before introducing new stores or abstractions.
- Treat
src/app/index.tsxas a composition root, not as the permanent home for onboarding, dictation, monitoring, pairing, persistence, and all UI details. - Avoid mirrored
state + refpairs unless they are needed for imperative native APIs, race cancellation, or subscription callbacks.
Code Style And Patterns
Formatting / Structure
- Preserve existing style (
semi: false, concise JSX, stable import grouping). - Keep UI changes localized and behavior-preserving; avoid unrelated formatting churn.
- Prefer feature-adjacent hooks/components over growing a single screen file.
React State / Effects
- Effects are for subscriptions, timers, persistence, network I/O, and native bridge setup/cleanup.
- Do not add
useEffectjust to derive render data from props or state. Derive during render instead. - Prefer one source of truth. If a value can be computed from existing state, do not store it separately.
- Use
useMemoonly when computation is expensive or stable identity actually matters. - Use
useCallbackonly when stable function identity matters for dependencies, cleanup, or memoized children. - When UI branches are driven by a small finite state, prefer config tables/objects over long nested ternaries.
Types
- Avoid
any; prefer local type aliases for component state and network payloads. - Keep exported/shared boundaries typed explicitly.
- Parse persisted and network payloads as
unknownfirst, then validate before use. - Use discriminated unions for UI modes/status where practical.
Naming
- Prefer short, readable names consistent with nearby code.
- Keep naming aligned with existing app state keys (
monitorStatus,activeSessionId, etc.).
Error Handling / Logging
- Fail gracefully in UI (alerts, disabled actions, fallback text).
- Avoid bare
catch {}or.catch(() => {})for meaningful work. If failure is intentionally best-effort, leave a short comment or use a helper that makes that explicit. - Log actionable diagnostics for runtime workflows such as server health checks, relay registration, and notification token lifecycle.
- Never log secrets or full APNs tokens.
- Keep hot-path logging behind
__DEV__when possible.
Network / Relay Integration
- Normalize and validate URLs before storing server configs.
- Use
AbortControlleror request IDs for overlapping requests, streams, and polling. - Keep relay registration idempotent.
- Guard duplicate scan/add flows to avoid repeated server entries.
Notifications / APNs
- This package currently assumes APNs relay registration uses the
productionenvironment only. Do not add environment switching unless explicitly requested. - On registration changes, ensure old token unregister flow remains intact.
- Treat permission failures as non-fatal and degrade to foreground monitoring when needed.
Performance / RN
- Validate performance-sensitive changes in a dev client or release build, not only Metro dev mode.
- During recording and monitoring flows, keep JS-thread work light.
- Prefer Reanimated/native-thread-friendly animations for motion.
- For small menus a
ScrollViewis fine; if a list grows beyond a small bounded menu, move toFlatListorFlashList.
Lint / Quality Bar
- Keep hooks lint warnings clean before finishing.
- Treat
any,no-console, complexity, and max-lines warnings as refactor prompts, not noise to suppress. - Do not disable React Hooks lint rules inline unless there is a documented native-interop reason.
- When introducing new persistence or network payloads, add or reuse a parser instead of scattering casts.
Native-Module Safety
- If adding a native module, ensure it is in
package.jsonwith an SDK-compatible version. - Rebuild the dev client after native module additions or changes.
- For optional native capability usage, prefer runtime fallback paths instead of hard crashes.
Common Pitfalls
- Black screen + "No script URL provided" often means a stale dev client binary.
expo-doctorduplicate module warnings may appear in Bun workspaces; prioritize runtime verification.expo lintmay auto-generateeslint.config.js; do not commit accidental generated config unless requested.
Before Finishing
- Run
bun run lint. - If behavior could break startup, run
bunx expo export --platform ios --clear. - Confirm no accidental config side effects were introduced.
- Summarize what was verified on-device vs only in tooling.