docs(audits): mobile app readiness audit + companion targets implementation prompt
This commit is contained in:
parent
fc12a8eaa2
commit
c1543e24fe
873
docs/audits/COMPANION_TARGETS_IMPLEMENTATION_PROMPT.md
Normal file
873
docs/audits/COMPANION_TARGETS_IMPLEMENTATION_PROMPT.md
Normal file
@ -0,0 +1,873 @@
|
|||||||
|
# Companion Targets — End-to-End Implementation Prompt
|
||||||
|
|
||||||
|
> **Purpose:** Delegatable prompt for an AI coding agent to bring all 7 watchOS and macOS companion targets from 15-30% stubs to 100% production-ready.
|
||||||
|
> **Date:** 2026-03-27
|
||||||
|
> **Scope:** 5 watchOS apps + 2 macOS apps across 5 product repos
|
||||||
|
> **Estimated effort:** ~8-12 focused agent sessions
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
1. [Global Rules](#1-global-rules)
|
||||||
|
2. [Target Inventory & Current State](#2-target-inventory--current-state)
|
||||||
|
3. [ChronoMind watchOS — 25% → 100%](#3-chronomind-watchos)
|
||||||
|
4. [ChronoMind macOS — 30% → 100%](#4-chronomind-macos)
|
||||||
|
5. [JarvisJr watchOS — 25% → 100%](#5-jarvisjr-watchos)
|
||||||
|
6. [JarvisJr macOS — 30% → 100%](#6-jarvisjr-macos)
|
||||||
|
7. [PeakPulse watchOS — 20% → 100%](#7-peakpulse-watchos)
|
||||||
|
8. [NomGap watchOS — 35% → 100%](#8-nomgap-watchos)
|
||||||
|
9. [ByteLyst Auth watchOS — 15% → 100%](#9-bytelyst-auth-watchos)
|
||||||
|
10. [Cross-Cutting Tasks](#10-cross-cutting-tasks)
|
||||||
|
11. [Acceptance Criteria](#11-acceptance-criteria)
|
||||||
|
12. [Build Verification Commands](#12-build-verification-commands)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Global Rules
|
||||||
|
|
||||||
|
### Coding conventions (MUST follow for ALL targets)
|
||||||
|
|
||||||
|
- All logging via `os.Logger` — never use `print()`
|
||||||
|
- All colors from product theme files — never hardcode hex values in views
|
||||||
|
- Use `#if canImport(WatchKit)` / `#if os(watchOS)` for platform-conditional code
|
||||||
|
- watchOS minimum: watchOS 10+. macOS minimum: macOS 14+
|
||||||
|
- Shared code lives in the iOS app's `Shared/` directory — companion targets import from there
|
||||||
|
- Data flow between iPhone ↔ Watch uses App Group (`UserDefaults(suiteName:)`) + `WCSession` (WatchConnectivity)
|
||||||
|
- Data flow between iPhone ↔ Mac uses App Group shared `UserDefaults`
|
||||||
|
- Commit messages: `feat(watch): description` or `feat(mac): description`
|
||||||
|
- Never add emojis to code unless the existing codebase already uses them in that file
|
||||||
|
- Every new file needs a one-line header comment describing its purpose
|
||||||
|
|
||||||
|
### Architecture pattern for ALL watchOS apps
|
||||||
|
|
||||||
|
```
|
||||||
|
ProductWatch/
|
||||||
|
├── ProductWatchApp.swift # @main entry point
|
||||||
|
├── Views/
|
||||||
|
│ ├── WatchContentView.swift # Main navigation hub
|
||||||
|
│ ├── Watch[Feature]View.swift # Feature-specific views
|
||||||
|
│ └── Components/ # Reusable watch components
|
||||||
|
├── Store/
|
||||||
|
│ └── WatchStore.swift # ObservableObject reading from App Group
|
||||||
|
├── Complications/
|
||||||
|
│ └── WatchComplications.swift # WidgetKit complications (4 families)
|
||||||
|
└── WatchSessionManager.swift # WCSession delegate (if bidirectional sync needed)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Architecture pattern for ALL macOS apps
|
||||||
|
|
||||||
|
```
|
||||||
|
ProductMac/
|
||||||
|
├── ProductMacApp.swift # @main, MenuBarExtra scene
|
||||||
|
├── Views/
|
||||||
|
│ ├── MenuBarPopover.swift # Main popover content
|
||||||
|
│ ├── MacSettingsView.swift # Settings window (TabView)
|
||||||
|
│ └── Components/ # Reusable mac components
|
||||||
|
├── Store/
|
||||||
|
│ └── MacStore.swift # ObservableObject, App Group sync
|
||||||
|
└── ProductMac.entitlements # App sandbox + App Group
|
||||||
|
```
|
||||||
|
|
||||||
|
### Shared code reuse rules
|
||||||
|
|
||||||
|
Each companion target should import types and engine logic from the iOS app's `Shared/` directory. The companion target should NEVER duplicate:
|
||||||
|
|
||||||
|
- Model types (timer states, agent configs, session models)
|
||||||
|
- Engine logic (timer calculations, stage computation)
|
||||||
|
- Theme colors
|
||||||
|
- App Group keys and data format
|
||||||
|
|
||||||
|
The companion target SHOULD have its own:
|
||||||
|
|
||||||
|
- Views (optimized for small/menu-bar screen)
|
||||||
|
- Store (lightweight, reads from shared data)
|
||||||
|
- Complications/Widgets (WidgetKit)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Target Inventory & Current State
|
||||||
|
|
||||||
|
| # | Product | Target | Repo | Directory | Current % | Files | Key Gap |
|
||||||
|
| --- | ---------- | ------- | ----------------------- | ------------------------ | --------- | ------------------------- | ------------------------------------------------------------------------------------------------- |
|
||||||
|
| 1 | ChronoMind | watchOS | `learning_ai_clock` | `ios/ChronoMindWatch/` | 50% | 7 files | Missing: WCSession sync, snooze/dismiss actions, haptic cascade, notifications |
|
||||||
|
| 2 | ChronoMind | macOS | `learning_ai_clock` | `ios/ChronoMindMac/` | 45% | 5 files | Missing: MenuBarPopover.swift, create-timer UI, live popover, keyboard shortcuts |
|
||||||
|
| 3 | JarvisJr | watchOS | `learning_ai_jarvis_jr` | `ios/JarvisJrWatch/` | 25% | 3 files (+2 in Watch dir) | Missing: QuickSessionView, WCSession, complications, voice stub, haptics |
|
||||||
|
| 4 | JarvisJr | macOS | `learning_ai_jarvis_jr` | `ios/JarvisJrMac/` | 40% | 5 files | Missing: MenuBarPopover.swift, text session UI, keyboard shortcut handler |
|
||||||
|
| 5 | PeakPulse | watchOS | `learning_ai_peakpulse` | `ios/PeakPulseWatch/` | 30% | 3 files | Missing: real sensors (CLLocation, CMAltimeter), HealthKit workout, WCSession, complications |
|
||||||
|
| 6 | NomGap | watchOS | `learning_ai_fastgap` | `watch/NomGapWatch/` | 55% | 9 files | Missing: StatsView body, WidgetKit migration, WCSession ↔ Expo bridge verification, notifications |
|
||||||
|
| 7 | Auth | watchOS | `learning_ai_auth_app` | `ios/ByteLystAuthWatch/` | 40% | 3 files | Missing: push notification handling, haptic feedback, complication, offline state |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. ChronoMind watchOS — 50% → 100%
|
||||||
|
|
||||||
|
**Repo:** `learning_ai_clock`
|
||||||
|
**Directory:** `ios/ChronoMindWatch/`
|
||||||
|
**Shared code:** `ios/ChronoMind/Shared/` (TimerEngine, Store, Theme, AppGroup, Haptics, Notifications)
|
||||||
|
|
||||||
|
### What EXISTS (7 files, ~660 lines)
|
||||||
|
|
||||||
|
| File | LOC | Status |
|
||||||
|
| ---------------------------------------- | --- | ----------------------------------------------------------------------------------------------- |
|
||||||
|
| `ChronoMindWatchApp.swift` | 16 | Complete |
|
||||||
|
| `Views/WatchContentView.swift` | 177 | Good — timer list, next-up card, empty state |
|
||||||
|
| `Views/WatchQuickTimerView.swift` | 56 | Good — 8 preset quick timers |
|
||||||
|
| `Views/WatchTimerDetailView.swift` | 99 | Good — countdown, urgency badge, pomodoro, cascade progress, snooze info |
|
||||||
|
| `WatchTimerStore.swift` | 125 | Good — reads from SharedTimerDataManager, quick timer creation, tick, haptic on fire |
|
||||||
|
| `Complications/WatchComplications.swift` | 243 | Complete — 4 families (circular, rectangular, inline, corner), AppIntentConfiguration, timeline |
|
||||||
|
| `ChronoMindWatch.entitlements` | — | Present |
|
||||||
|
|
||||||
|
### What's MISSING — implement these
|
||||||
|
|
||||||
|
#### 3.1 WatchConnectivity (WCSession) for real-time sync
|
||||||
|
|
||||||
|
**File:** `WatchSessionManager.swift` (~120 lines)
|
||||||
|
|
||||||
|
```
|
||||||
|
Purpose: Bidirectional WCSession so the iPhone app can push timer updates in real-time,
|
||||||
|
and the Watch can send commands back (snooze, dismiss, pause, resume).
|
||||||
|
|
||||||
|
Implementation:
|
||||||
|
- WCSessionDelegate with activationDidCompleteWith, didReceiveMessage, didReceiveApplicationContext
|
||||||
|
- On receive: decode [TimerSnapshot] and update WatchTimerStore
|
||||||
|
- sendCommand(_ command: WatchTimerCommand) method for: snooze, dismiss, pause, resume, complete
|
||||||
|
- WatchTimerCommand enum: snooze(id, minutes), dismiss(id), pause(id), resume(id), complete(id)
|
||||||
|
- Reachability tracking with fallback to App Group polling
|
||||||
|
- Wire into WatchTimerStore.init() — activate session
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3.2 Action buttons on WatchTimerDetailView
|
||||||
|
|
||||||
|
**File:** Update `Views/WatchTimerDetailView.swift`
|
||||||
|
|
||||||
|
```
|
||||||
|
Add action buttons at bottom of ScrollView:
|
||||||
|
- When state == .firing: "Snooze 5m" button + "Dismiss" button
|
||||||
|
- When state == .active: "Pause" button
|
||||||
|
- When state == .paused: "Resume" button
|
||||||
|
- When state == .snoozed: "Snooze again" + "Dismiss"
|
||||||
|
- All actions go through WatchSessionManager.sendCommand()
|
||||||
|
- Haptic feedback (WKInterfaceDevice.current().play()) on each action
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3.3 Haptic cascade warnings
|
||||||
|
|
||||||
|
**File:** Update `WatchTimerStore.swift`
|
||||||
|
|
||||||
|
```
|
||||||
|
In tick(), when a warning fires (nextWarningTime reached):
|
||||||
|
- Play .notification haptic
|
||||||
|
- If urgency == .critical: play 3x haptic sequence (notification + 0.3s delay + notification)
|
||||||
|
- Update the timer's firedWarnings count
|
||||||
|
- Schedule local notification via UNUserNotificationCenter
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3.4 Local notifications on Watch
|
||||||
|
|
||||||
|
**File:** `WatchNotificationHandler.swift` (~50 lines)
|
||||||
|
|
||||||
|
```
|
||||||
|
- UNUserNotificationCenter.requestAuthorization on app launch
|
||||||
|
- Schedule notification when timer is about to fire (from WatchTimerStore)
|
||||||
|
- Custom notification categories with "Snooze" and "Dismiss" actions
|
||||||
|
- UNNotificationCategoryIdentifier: "CHRONOMIND_TIMER_FIRED"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3.5 Routines view (optional, stretch)
|
||||||
|
|
||||||
|
**File:** `Views/WatchRoutineView.swift` (~80 lines)
|
||||||
|
|
||||||
|
```
|
||||||
|
- Read active routine from SharedTimerDataManager
|
||||||
|
- Show current step name + progress
|
||||||
|
- "Next Step" button to advance
|
||||||
|
```
|
||||||
|
|
||||||
|
### Estimated new code: ~350 lines across 3 new files + 2 updated files
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. ChronoMind macOS — 45% → 100%
|
||||||
|
|
||||||
|
**Repo:** `learning_ai_clock`
|
||||||
|
**Directory:** `ios/ChronoMindMac/`
|
||||||
|
**Shared code:** `ios/ChronoMind/Shared/` (same as iOS — TimerEngine functions are pure Swift)
|
||||||
|
|
||||||
|
### What EXISTS (5 files, ~520 lines)
|
||||||
|
|
||||||
|
| File | LOC | Status |
|
||||||
|
| ----------------------------- | --- | --------------------------------------------------------------------------------------------------- |
|
||||||
|
| `ChronoMindMacApp.swift` | 40 | Complete — MenuBarExtra with timer label |
|
||||||
|
| `MacTimerStore.swift` | 181 | Complete — CRUD, tick, notifications, App Group persistence. Uses Shared/ engine functions directly |
|
||||||
|
| `Views/MacSettingsView.swift` | 101 | Complete — General/Data/About tabs |
|
||||||
|
| `ChronoMindMac.entitlements` | — | Present |
|
||||||
|
|
||||||
|
### What's MISSING — implement these
|
||||||
|
|
||||||
|
#### 4.1 MenuBarPopover.swift (~200 lines)
|
||||||
|
|
||||||
|
**File:** `Views/MenuBarPopover.swift`
|
||||||
|
|
||||||
|
```
|
||||||
|
This is the main UI that appears when clicking the menu bar icon.
|
||||||
|
|
||||||
|
Layout:
|
||||||
|
- Header: "ChronoMind" + gear icon (opens Settings)
|
||||||
|
- If no timers: empty state with "Create Timer" button
|
||||||
|
- Next-up card: large countdown + urgency color + label + target time
|
||||||
|
- Timer list: compact rows for remaining active timers
|
||||||
|
- Quick actions row: preset buttons (5m, 10m, 25m Pomodoro, Custom)
|
||||||
|
- "Custom Timer" button opens CreateTimerSheet
|
||||||
|
|
||||||
|
Each timer row has:
|
||||||
|
- Urgency dot + label + countdown
|
||||||
|
- Right-click context menu: Pause, Resume, Snooze 5m, Dismiss, Delete
|
||||||
|
|
||||||
|
Footer:
|
||||||
|
- "x active timers" label + "Quit" button
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4.2 CreateTimerSheet.swift (~120 lines)
|
||||||
|
|
||||||
|
**File:** `Views/CreateTimerSheet.swift`
|
||||||
|
|
||||||
|
```
|
||||||
|
Sheet presented from MenuBarPopover:
|
||||||
|
- TextField for timer label
|
||||||
|
- Picker: Countdown / Alarm / Pomodoro
|
||||||
|
- If Countdown: duration picker (hours/minutes stepper)
|
||||||
|
- If Alarm: DatePicker for target time
|
||||||
|
- If Pomodoro: rounds stepper (default 4) + work/break duration
|
||||||
|
- Urgency picker (5 levels)
|
||||||
|
- Cascade preset picker
|
||||||
|
- "Create" button → store.addCountdown/addAlarm
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4.3 Keyboard shortcut handler (~40 lines)
|
||||||
|
|
||||||
|
**File:** Update `ChronoMindMacApp.swift`
|
||||||
|
|
||||||
|
```
|
||||||
|
Add .keyboardShortcut modifiers or NSEvent.addLocalMonitorForEvents:
|
||||||
|
- ⌘N: Create new timer (open CreateTimerSheet)
|
||||||
|
- ⌘,: Open Settings
|
||||||
|
- Space: Pause/resume next firing timer
|
||||||
|
- ⌘Q: Quit app
|
||||||
|
|
||||||
|
Add .commands { } modifier to the App scene.
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4.4 MenuBarState.swift (~30 lines)
|
||||||
|
|
||||||
|
**File:** `MenuBarState.swift`
|
||||||
|
|
||||||
|
```
|
||||||
|
@MainActor ObservableObject:
|
||||||
|
- @Published var showCreateSheet = false
|
||||||
|
- @Published var showTimerDetail: String? = nil // timer ID
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4.5 Launch at Login
|
||||||
|
|
||||||
|
**File:** Update `Views/MacSettingsView.swift`
|
||||||
|
|
||||||
|
```
|
||||||
|
Wire the "Launch at Login" toggle to SMAppService.mainApp:
|
||||||
|
- import ServiceManagement
|
||||||
|
- SMAppService.mainApp.register() / unregister()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Estimated new code: ~390 lines across 3 new files + 2 updated files
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. JarvisJr watchOS — 25% → 100%
|
||||||
|
|
||||||
|
**Repo:** `learning_ai_jarvis_jr`
|
||||||
|
**Directory:** `ios/JarvisJrWatch/`
|
||||||
|
**Shared code:** `ios/JarvisJr/Shared/` (Models, Store, Engine, Voice, Theme, AppGroup)
|
||||||
|
|
||||||
|
### What EXISTS (5 files, ~230 lines)
|
||||||
|
|
||||||
|
| File | LOC | Status |
|
||||||
|
| ---------------------------- | -------------------------- | --------------------------------------------------------------------------------- |
|
||||||
|
| `JarvisJrWatchApp.swift` | 13 | Minimal — no store injection |
|
||||||
|
| `WatchContentView.swift` | 85 | Basic — agent list from SharedAgentData, streak banner, links to QuickSessionView |
|
||||||
|
| `QuickSessionView.swift` | exists (in JarvisJrWatch/) | Referenced but need to verify |
|
||||||
|
| `ComplicationProvider.swift` | exists (in JarvisJrWatch/) | Referenced in AGENTS.md |
|
||||||
|
| `WatchTimerStore.swift` | — | NOT present |
|
||||||
|
|
||||||
|
### What's MISSING — implement these
|
||||||
|
|
||||||
|
#### 5.1 WatchAgentStore.swift (~80 lines)
|
||||||
|
|
||||||
|
```
|
||||||
|
@MainActor ObservableObject:
|
||||||
|
- @Published var agents: [WatchAgent] — read from SharedAgentData (App Group)
|
||||||
|
- @Published var streak: Int
|
||||||
|
- @Published var activeSession: WatchSession?
|
||||||
|
- struct WatchAgent: id, name, role, accentColor, sessionLength
|
||||||
|
- struct WatchSession: agentId, startedAt, messages: [(role, text)]
|
||||||
|
- loadFromSharedData() — decode from App Group UserDefaults
|
||||||
|
- Inject into WatchApp via @StateObject
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5.2 QuickSessionView.swift (~150 lines)
|
||||||
|
|
||||||
|
```
|
||||||
|
If this file doesn't exist or is a stub, implement:
|
||||||
|
- Agent name + role header
|
||||||
|
- "Start Session" button (text-based on Watch, voice is stretch)
|
||||||
|
- Once started:
|
||||||
|
- Scrollable message list (alternating user/agent bubbles)
|
||||||
|
- Text input via dictation (TextField with .watchDictation modifier or voice button)
|
||||||
|
- "End Session" button
|
||||||
|
- On end: summary card (duration, message count)
|
||||||
|
- Send session data back to iPhone via WCSession
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5.3 WatchSessionManager.swift (~100 lines)
|
||||||
|
|
||||||
|
```
|
||||||
|
WCSessionDelegate:
|
||||||
|
- Receive agent list updates from iPhone
|
||||||
|
- Receive streak updates
|
||||||
|
- Send session transcripts back to iPhone
|
||||||
|
- Reachability handling
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5.4 Complications (~120 lines)
|
||||||
|
|
||||||
|
**File:** `Complications/WatchComplications.swift`
|
||||||
|
|
||||||
|
```
|
||||||
|
WidgetKit complications (same pattern as ChronoMind):
|
||||||
|
- AppIntentTimelineProvider reading from SharedAgentData
|
||||||
|
- Circular: streak count or agent initial
|
||||||
|
- Rectangular: "Coach — 5-day streak" or "JarvisJr — Ready"
|
||||||
|
- Inline: "🔥 5 streak" or agent name
|
||||||
|
- Corner: streak number with "JarvisJr" label
|
||||||
|
- 4 supported families: accessoryCircular, accessoryRectangular, accessoryInline, accessoryCorner
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5.5 Update WatchApp entry point
|
||||||
|
|
||||||
|
```
|
||||||
|
Update JarvisJrWatchApp.swift:
|
||||||
|
- @StateObject var agentStore = WatchAgentStore()
|
||||||
|
- @StateObject var sessionManager = WatchSessionManager()
|
||||||
|
- Inject both as environmentObjects
|
||||||
|
- Activate WCSession in init()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Estimated new code: ~450 lines across 4 new files + 2 updated files
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. JarvisJr macOS — 40% → 100%
|
||||||
|
|
||||||
|
**Repo:** `learning_ai_jarvis_jr`
|
||||||
|
**Directory:** `ios/JarvisJrMac/`
|
||||||
|
**Shared code:** `ios/JarvisJr/Shared/`
|
||||||
|
|
||||||
|
### What EXISTS (5 files, ~340 lines)
|
||||||
|
|
||||||
|
| File | LOC | Status |
|
||||||
|
| ----------------------------- | --- | ------------------------------------------------------------------ |
|
||||||
|
| `JarvisJrMacApp.swift` | 39 | Complete — MenuBarExtra + Settings |
|
||||||
|
| `MacAgentStore.swift` | 119 | Good — agent CRUD, persistence, notifications, 6 default templates |
|
||||||
|
| `MacMenuBarState.swift` | 33 | Basic — isExpanded, showQuickSession, selectedAgentId |
|
||||||
|
| `Views/MacSettingsView.swift` | 111 | Complete — General/Agents/About tabs |
|
||||||
|
|
||||||
|
### What's MISSING — implement these
|
||||||
|
|
||||||
|
#### 6.1 MenuBarPopover.swift (~180 lines)
|
||||||
|
|
||||||
|
```
|
||||||
|
Main popover content (referenced in JarvisJrMacApp but not implemented):
|
||||||
|
- Agent card grid (2 columns): avatar circle + name + role
|
||||||
|
- Click agent → startQuickSession
|
||||||
|
- Streak banner at top
|
||||||
|
- "Talk to [Agent]" button for default agent
|
||||||
|
- If activeSession: show session view (text chat)
|
||||||
|
|
||||||
|
Agent card:
|
||||||
|
- Colored circle with initial
|
||||||
|
- Name (body bold)
|
||||||
|
- Role (caption)
|
||||||
|
- Total sessions badge (caption2)
|
||||||
|
|
||||||
|
Session view (inline, replaces agent grid):
|
||||||
|
- Agent name header
|
||||||
|
- Message scroll view
|
||||||
|
- TextField for text input
|
||||||
|
- End session button
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 6.2 MacTextSessionView.swift (~120 lines)
|
||||||
|
|
||||||
|
```
|
||||||
|
Text-based coaching session in the popover:
|
||||||
|
- Agent name + role header
|
||||||
|
- Scrollable message list (bubble style)
|
||||||
|
- TextField + Send button at bottom
|
||||||
|
- "End Session" button in toolbar
|
||||||
|
- On end: increment totalSessions, save via MacAgentStore
|
||||||
|
- Timer showing session duration
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 6.3 Keyboard shortcut
|
||||||
|
|
||||||
|
```
|
||||||
|
Update JarvisJrMacApp.swift:
|
||||||
|
- ⌥⇧J: Start session with default agent (already mentioned in settings)
|
||||||
|
- Register as NSEvent.addGlobalMonitorForEvents
|
||||||
|
- ⌘,: Settings
|
||||||
|
```
|
||||||
|
|
||||||
|
### Estimated new code: ~300 lines across 2 new files + 1 updated file
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. PeakPulse watchOS — 30% → 100%
|
||||||
|
|
||||||
|
**Repo:** `learning_ai_peakpulse`
|
||||||
|
**Directory:** `ios/PeakPulseWatch/`
|
||||||
|
**Shared code:** `ios/PeakPulse/` (Models, Services, Theme, Utils)
|
||||||
|
|
||||||
|
### What EXISTS (3 files, ~160 lines)
|
||||||
|
|
||||||
|
| File | LOC | Status |
|
||||||
|
| ----------------------------- | --- | ----------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| `PeakPulseWatchApp.swift` | 11 | Minimal stub |
|
||||||
|
| `WatchContentView.swift` | 145 | Functional — activity picker (hike/ski), tracking view with stats grid, start/stop. Uses local Timer (NOT real sensors) |
|
||||||
|
| `PeakPulseWatch.entitlements` | — | Present |
|
||||||
|
|
||||||
|
### What's MISSING — implement these
|
||||||
|
|
||||||
|
#### 7.1 Real sensor integration
|
||||||
|
|
||||||
|
**File:** `WatchLocationService.swift` (~100 lines)
|
||||||
|
|
||||||
|
```
|
||||||
|
CLLocationManager on watchOS:
|
||||||
|
- requestWhenInUseAuthorization()
|
||||||
|
- Start updating location (desiredAccuracy: .bestForNavigation)
|
||||||
|
- Publish: currentSpeed, currentElevation (altitude), totalDistance, elevationGain
|
||||||
|
- Calculate distance between consecutive CLLocations
|
||||||
|
- Track elevation gain (only count positive deltas)
|
||||||
|
- Wire into WatchContentView replacing the mock values
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 7.2 HealthKit workout session
|
||||||
|
|
||||||
|
**File:** `WatchWorkoutManager.swift` (~120 lines)
|
||||||
|
|
||||||
|
```
|
||||||
|
HKWorkoutSession + HKLiveWorkoutBuilder:
|
||||||
|
- Start workout session when tracking begins
|
||||||
|
- Activity type: .hiking or .downhillSkiing based on selection
|
||||||
|
- Collect: heart rate, active energy, distance
|
||||||
|
- End workout and save to HealthKit when tracking stops
|
||||||
|
- Request HealthKit authorization for: .heartRate, .activeEnergyBurned, .distanceWalkingRunning
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 7.3 WatchConnectivity sync
|
||||||
|
|
||||||
|
**File:** `WatchSessionManager.swift` (~80 lines)
|
||||||
|
|
||||||
|
```
|
||||||
|
- Send completed session data to iPhone via WCSession
|
||||||
|
- Receive recent session summaries from iPhone for display
|
||||||
|
- Transfer TrackPoint arrays via transferUserInfo (large data)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 7.4 WidgetKit complications
|
||||||
|
|
||||||
|
**File:** `Complications/WatchComplications.swift` (~120 lines)
|
||||||
|
|
||||||
|
```
|
||||||
|
Same pattern as ChronoMind:
|
||||||
|
- Circular: elevation or distance icon
|
||||||
|
- Rectangular: "Last hike: 5.2km, +450m" or "Tracking: 45min"
|
||||||
|
- Inline: "🥾 5.2km +450m"
|
||||||
|
- Corner: distance with "PeakPulse" label
|
||||||
|
- Read from App Group UserDefaults (last session summary)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 7.5 Session summary view
|
||||||
|
|
||||||
|
**File:** `Views/WatchSessionSummaryView.swift` (~80 lines)
|
||||||
|
|
||||||
|
```
|
||||||
|
Shown after stopping a session:
|
||||||
|
- Duration
|
||||||
|
- Distance
|
||||||
|
- Elevation gain/loss
|
||||||
|
- Average speed
|
||||||
|
- Max speed
|
||||||
|
- Activity type icon
|
||||||
|
- "Save" button (saves to HealthKit + syncs to iPhone)
|
||||||
|
- "Discard" button
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 7.6 Recent sessions list
|
||||||
|
|
||||||
|
**File:** `Views/WatchSessionListView.swift` (~60 lines)
|
||||||
|
|
||||||
|
```
|
||||||
|
Tab or navigation destination:
|
||||||
|
- List of recent sessions from App Group
|
||||||
|
- Each row: date, activity type, distance, duration
|
||||||
|
- Tap for detail view (read-only summary)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 7.7 Update WatchApp and ContentView
|
||||||
|
|
||||||
|
```
|
||||||
|
- Add @StateObject for WatchLocationService, WatchWorkoutManager
|
||||||
|
- Add tab navigation: Tracking | Sessions | (complications handled separately)
|
||||||
|
- Wire real sensor data into tracking stats grid
|
||||||
|
- Add heart rate display if workout session active
|
||||||
|
```
|
||||||
|
|
||||||
|
### Estimated new code: ~560 lines across 5 new files + 2 updated files
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. NomGap watchOS — 55% → 100%
|
||||||
|
|
||||||
|
**Repo:** `learning_ai_fastgap`
|
||||||
|
**Directory:** `watch/NomGapWatch/`
|
||||||
|
**Shared code:** `watch/Shared/` (FastingState, ColorExtension)
|
||||||
|
|
||||||
|
### What EXISTS (9 files, ~770 lines) — MOST COMPLETE
|
||||||
|
|
||||||
|
| File | LOC | Status |
|
||||||
|
| ----------------------------- | ------ | -------------------------------------------------------------------------------------------------- |
|
||||||
|
| `NomGapWatchApp.swift` | 20 | Complete |
|
||||||
|
| `ContentView.swift` | 17 | Complete — TabView with 3 pages |
|
||||||
|
| `FastingTimerView.swift` | 324 | Excellent — timer ring, stage badge, Digital Crown, haptic cascade, controls, next stage countdown |
|
||||||
|
| `HydrationView.swift` | 71 | Complete — water tracking with progress bar |
|
||||||
|
| `StatsView.swift` | exists | Need to verify content |
|
||||||
|
| `WatchSessionManager.swift` | 134 | Good — WCSession delegate, command queue, offline queue |
|
||||||
|
| `ComplicationProvider.swift` | 204 | Complete — CLKComplicationDataSource with 9 families |
|
||||||
|
| `Shared/FastingState.swift` | exists | Shared model |
|
||||||
|
| `Shared/ColorExtension.swift` | exists | Color init(hex:) |
|
||||||
|
|
||||||
|
### What's MISSING — implement these
|
||||||
|
|
||||||
|
#### 8.1 StatsView implementation
|
||||||
|
|
||||||
|
**File:** Update `StatsView.swift` (~80 lines)
|
||||||
|
|
||||||
|
```
|
||||||
|
Read from App Group (NomGapAppGroup):
|
||||||
|
- Current streak (days)
|
||||||
|
- Total fasts completed
|
||||||
|
- Average fast duration
|
||||||
|
- Longest fast
|
||||||
|
- Total fasting hours
|
||||||
|
|
||||||
|
Layout:
|
||||||
|
- Streak flame at top
|
||||||
|
- Stats in a 2-column grid (similar to PeakPulse)
|
||||||
|
- "Last 7 days" mini bar chart (optional)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 8.2 Migrate complications from ClockKit → WidgetKit
|
||||||
|
|
||||||
|
**File:** Update or replace `ComplicationProvider.swift` (~150 lines)
|
||||||
|
|
||||||
|
```
|
||||||
|
CLKComplicationDataSource is deprecated since watchOS 9.
|
||||||
|
Migrate to WidgetKit:
|
||||||
|
- AppIntentTimelineProvider (same pattern as ChronoMind)
|
||||||
|
- 4 accessory families: circular, rectangular, inline, corner
|
||||||
|
- Read from NomGapAppGroup.loadState()
|
||||||
|
- Show: stage emoji, elapsed time, progress gauge
|
||||||
|
- Keep backward compat: leave CLK version but add WidgetKit version
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 8.3 Local notifications
|
||||||
|
|
||||||
|
**File:** `WatchNotificationHandler.swift` (~50 lines)
|
||||||
|
|
||||||
|
```
|
||||||
|
- Stage transition notifications (entering ketosis, autophagy)
|
||||||
|
- Hydration reminders (every 2 hours during active fast)
|
||||||
|
- UNUserNotificationCenter on watchOS
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 8.4 WCSession ↔ Expo React Native bridge verification
|
||||||
|
|
||||||
|
```
|
||||||
|
The WatchSessionManager sends/receives via WCSession, but the iPhone side is React Native (Expo).
|
||||||
|
Verify that the Expo plugin (plugins/withWatchApp.js) properly:
|
||||||
|
1. Registers the WCSession delegate on the RN side
|
||||||
|
2. Handles incoming WatchCommand messages
|
||||||
|
3. Sends FastingState updates to the watch via updateApplicationContext
|
||||||
|
|
||||||
|
If the bridge doesn't exist, create:
|
||||||
|
- ios-extensions/NomGapWatchBridge/WatchBridge.swift — native module
|
||||||
|
- Expo config plugin to register the bridge
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 8.5 Fix print() usage
|
||||||
|
|
||||||
|
```
|
||||||
|
WatchSessionManager.swift line 43 uses print() — replace with os.Logger
|
||||||
|
```
|
||||||
|
|
||||||
|
### Estimated new code: ~280 lines across 2 new files + 3 updated files
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. ByteLyst Auth watchOS — 40% → 100%
|
||||||
|
|
||||||
|
**Repo:** `learning_ai_auth_app`
|
||||||
|
**Directory:** `ios/ByteLystAuthWatch/`
|
||||||
|
|
||||||
|
### What EXISTS (3 files, ~215 lines) — surprisingly functional
|
||||||
|
|
||||||
|
| File | LOC | Status |
|
||||||
|
| ---------------------------- | --- | ---------------------------------------------------------------------------------------------------- |
|
||||||
|
| `ByteLystAuthWatchApp.swift` | 17 | Complete — uses os.Logger |
|
||||||
|
| `WatchContentView.swift` | 196 | Good — polls `/auth/mfa/push/pending`, approve/deny UI, loading/error/empty states, 10s auto-refresh |
|
||||||
|
| `Info.plist` | — | Present |
|
||||||
|
|
||||||
|
### What's MISSING — implement these
|
||||||
|
|
||||||
|
#### 9.1 Push notification handling
|
||||||
|
|
||||||
|
**File:** `WatchNotificationHandler.swift` (~60 lines)
|
||||||
|
|
||||||
|
```
|
||||||
|
UNUserNotificationCenter for push MFA:
|
||||||
|
- Register for remote notifications in WatchApp init
|
||||||
|
- Handle incoming push with approval request data
|
||||||
|
- Create actionable notification with "Approve" and "Deny" buttons
|
||||||
|
- UNNotificationCategory: "MFA_APPROVAL"
|
||||||
|
- On action: call respond(to:approved:) API
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 9.2 Haptic feedback
|
||||||
|
|
||||||
|
**File:** Update `WatchContentView.swift`
|
||||||
|
|
||||||
|
```
|
||||||
|
Add haptics for:
|
||||||
|
- New approval received: .notification
|
||||||
|
- Approve action: .success
|
||||||
|
- Deny action: .failure
|
||||||
|
- Error state: .retry
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 9.3 WidgetKit complication
|
||||||
|
|
||||||
|
**File:** `Complications/AuthComplication.swift` (~100 lines)
|
||||||
|
|
||||||
|
```
|
||||||
|
AppIntentTimelineProvider:
|
||||||
|
- Circular: shield icon (green if no pending, orange if pending)
|
||||||
|
- Rectangular: "ByteLyst Auth — 2 pending" or "All clear"
|
||||||
|
- Inline: "🛡️ 2 pending" or "🛡️ All clear"
|
||||||
|
- Corner: pending count with shield label
|
||||||
|
- Read pending count from App Group (set by main app or watch polling)
|
||||||
|
- Timeline refresh: every 5 minutes, or .after(nextPoll)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 9.4 Offline/no-auth state improvement
|
||||||
|
|
||||||
|
**File:** Update `WatchContentView.swift`
|
||||||
|
|
||||||
|
```
|
||||||
|
When no token is available:
|
||||||
|
- Show QR code prompt: "Scan from iPhone to pair"
|
||||||
|
- Or: instruction to open ByteLyst Auth on iPhone
|
||||||
|
- Add a "Refresh" button that re-checks App Group keychain
|
||||||
|
|
||||||
|
When offline:
|
||||||
|
- Show last-known pending count from App Group cache
|
||||||
|
- Badge: "Last updated: X minutes ago"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 9.5 WCSession for token sync
|
||||||
|
|
||||||
|
**File:** `WatchSessionManager.swift` (~60 lines)
|
||||||
|
|
||||||
|
```
|
||||||
|
The main app should push the access token to the Watch via WCSession.
|
||||||
|
On the Watch side:
|
||||||
|
- Receive token via didReceiveApplicationContext
|
||||||
|
- Store in shared Keychain (App Group)
|
||||||
|
- Trigger approval refresh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Estimated new code: ~220 lines across 3 new files + 1 updated file
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Cross-Cutting Tasks
|
||||||
|
|
||||||
|
### 10.1 XcodeGen project.yml updates
|
||||||
|
|
||||||
|
For repos that use XcodeGen (`project.yml`), ensure the companion targets are properly declared:
|
||||||
|
|
||||||
|
- **ChronoMind:** `ios/project.yml` — verify ChronoMindWatch and ChronoMindMac targets include all new files
|
||||||
|
- **JarvisJr:** `ios/project.yml` — verify JarvisJrWatch and JarvisJrMac targets
|
||||||
|
- **PeakPulse:** `ios/project.yml` — verify PeakPulseWatch target
|
||||||
|
|
||||||
|
Each watchOS target needs:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
targets:
|
||||||
|
ProductWatch:
|
||||||
|
type: application
|
||||||
|
platform: watchOS
|
||||||
|
deploymentTarget: '10.0'
|
||||||
|
sources:
|
||||||
|
- path: ProductWatch
|
||||||
|
- path: Product/Shared # shared code from iOS app
|
||||||
|
settings:
|
||||||
|
INFOPLIST_FILE: ProductWatch/Info.plist
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER: com.saravana.product.watchkitapp
|
||||||
|
WATCHOS_DEPLOYMENT_TARGET: '10.0'
|
||||||
|
dependencies:
|
||||||
|
- target: ProductWidgets # if WidgetKit complications
|
||||||
|
```
|
||||||
|
|
||||||
|
### 10.2 App Group entitlements
|
||||||
|
|
||||||
|
Verify every companion target has the correct App Group in its entitlements:
|
||||||
|
|
||||||
|
| Product | App Group |
|
||||||
|
| ---------- | ------------------------------------------------- |
|
||||||
|
| ChronoMind | `group.com.chronomind.shared` |
|
||||||
|
| JarvisJr | `group.com.saravana.jarvisjr` |
|
||||||
|
| PeakPulse | `group.com.saravana.peakpulse` |
|
||||||
|
| NomGap | (defined in Expo app.json or withWatchApp plugin) |
|
||||||
|
| Auth | `group.com.bytelyst.auth` |
|
||||||
|
|
||||||
|
### 10.3 Shared helper: `formatTime()` global function
|
||||||
|
|
||||||
|
Several watch views reference a `formatTime(_:)` free function. Ensure it exists in a shared utility file accessible to the watchOS target:
|
||||||
|
|
||||||
|
```swift
|
||||||
|
func formatTime(_ date: Date) -> String {
|
||||||
|
let formatter = DateFormatter()
|
||||||
|
formatter.timeStyle = .short
|
||||||
|
return formatter.string(from: date)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 10.4 Theme color access from companion targets
|
||||||
|
|
||||||
|
Each companion target needs access to the product's theme colors. Options:
|
||||||
|
|
||||||
|
1. Add the theme file (e.g., `ChronoMindTheme.swift`) to the Watch target's sources in project.yml
|
||||||
|
2. Or create a lightweight `WatchTheme.swift` with just the needed colors
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. Acceptance Criteria
|
||||||
|
|
||||||
|
For EACH companion target, the implementation is 100% when:
|
||||||
|
|
||||||
|
### watchOS targets
|
||||||
|
|
||||||
|
- [ ] App launches in watchOS Simulator without crashes
|
||||||
|
- [ ] Main content view shows real data from App Group
|
||||||
|
- [ ] At least one bidirectional action works (Watch → iPhone command)
|
||||||
|
- [ ] WCSession activates and receives data
|
||||||
|
- [ ] WidgetKit complications render in all 4 accessory families
|
||||||
|
- [ ] Haptic feedback fires on key actions
|
||||||
|
- [ ] Local notifications schedule correctly
|
||||||
|
- [ ] No `print()` statements — all `os.Logger`
|
||||||
|
- [ ] All colors from theme — no hardcoded hex in views
|
||||||
|
- [ ] Builds clean with `xcodebuild -scheme ProductWatch -destination 'platform=watchOS Simulator,name=Apple Watch Series 10 (46mm)' build`
|
||||||
|
|
||||||
|
### macOS targets
|
||||||
|
|
||||||
|
- [ ] App launches as menu bar app
|
||||||
|
- [ ] Menu bar icon shows relevant live data (countdown / agent name)
|
||||||
|
- [ ] Popover opens with correct content
|
||||||
|
- [ ] Create/interact actions work (create timer / start session)
|
||||||
|
- [ ] Settings window opens with ⌘,
|
||||||
|
- [ ] Launch at Login toggle works via SMAppService
|
||||||
|
- [ ] App Group syncs data from iOS app
|
||||||
|
- [ ] Notifications fire correctly
|
||||||
|
- [ ] No `print()` statements
|
||||||
|
- [ ] Builds clean with `xcodebuild -scheme ProductMac -destination 'platform=macOS' CODE_SIGNING_ALLOWED=NO build`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. Build Verification Commands
|
||||||
|
|
||||||
|
Run after implementing each target:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# ── ChronoMind ─────────────────────────────────────
|
||||||
|
cd /path/to/learning_ai_clock/ios
|
||||||
|
|
||||||
|
# watchOS
|
||||||
|
xcodebuild -scheme ChronoMindWatch \
|
||||||
|
-destination 'platform=watchOS Simulator,name=Apple Watch Series 10 (46mm)' \
|
||||||
|
build
|
||||||
|
|
||||||
|
# macOS
|
||||||
|
xcodebuild -scheme ChronoMindMac \
|
||||||
|
-destination 'platform=macOS' \
|
||||||
|
CODE_SIGNING_ALLOWED=NO build
|
||||||
|
|
||||||
|
# ── JarvisJr ──────────────────────────────────────
|
||||||
|
cd /path/to/learning_ai_jarvis_jr/ios
|
||||||
|
|
||||||
|
xcodebuild -scheme JarvisJrWatch \
|
||||||
|
-destination 'platform=watchOS Simulator,name=Apple Watch Series 10 (46mm)' \
|
||||||
|
build
|
||||||
|
|
||||||
|
xcodebuild -scheme JarvisJrMac \
|
||||||
|
-destination 'platform=macOS' \
|
||||||
|
CODE_SIGNING_ALLOWED=NO build
|
||||||
|
|
||||||
|
# ── PeakPulse ─────────────────────────────────────
|
||||||
|
cd /path/to/learning_ai_peakpulse/ios
|
||||||
|
|
||||||
|
xcodebuild -scheme PeakPulseWatch \
|
||||||
|
-destination 'platform=watchOS Simulator,name=Apple Watch Series 10 (46mm)' \
|
||||||
|
build
|
||||||
|
|
||||||
|
# ── NomGap ────────────────────────────────────────
|
||||||
|
# NomGap watchOS requires an Xcode project (may need manual setup
|
||||||
|
# since the main app is React Native/Expo)
|
||||||
|
cd /path/to/learning_ai_fastgap
|
||||||
|
# Verify via Expo custom dev client or standalone Xcode project
|
||||||
|
|
||||||
|
# ── ByteLyst Auth ─────────────────────────────────
|
||||||
|
cd /path/to/learning_ai_auth_app/ios
|
||||||
|
|
||||||
|
xcodebuild -scheme ByteLystAuthWatch \
|
||||||
|
-destination 'platform=watchOS Simulator,name=Apple Watch Series 10 (46mm)' \
|
||||||
|
build
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Summary: Total New Code Estimate
|
||||||
|
|
||||||
|
| Target | New Files | New LOC | Updated Files |
|
||||||
|
| ------------------ | --------- | ---------- | ------------- |
|
||||||
|
| ChronoMind watchOS | 3 | ~350 | 2 |
|
||||||
|
| ChronoMind macOS | 3 | ~390 | 2 |
|
||||||
|
| JarvisJr watchOS | 4 | ~450 | 2 |
|
||||||
|
| JarvisJr macOS | 2 | ~300 | 1 |
|
||||||
|
| PeakPulse watchOS | 5 | ~560 | 2 |
|
||||||
|
| NomGap watchOS | 2 | ~280 | 3 |
|
||||||
|
| Auth watchOS | 3 | ~220 | 1 |
|
||||||
|
| **TOTAL** | **22** | **~2,550** | **13** |
|
||||||
|
|
||||||
|
**Recommended execution order:** ChronoMind (watch + mac) → PeakPulse (watch) → JarvisJr (watch + mac) → NomGap (watch) → Auth (watch)
|
||||||
|
|
||||||
|
This order prioritizes the most feature-complete iOS apps first, ensuring the Shared/ code they depend on is already proven.
|
||||||
586
docs/audits/MOBILE_APP_READINESS_AUDIT.md
Normal file
586
docs/audits/MOBILE_APP_READINESS_AUDIT.md
Normal file
@ -0,0 +1,586 @@
|
|||||||
|
# Mobile App Readiness Audit — ByteLyst Ecosystem
|
||||||
|
|
||||||
|
> **Date:** 2026-03-27
|
||||||
|
> **Scope:** All 7 products with mobile surfaces (18 app targets total)
|
||||||
|
> **Auditor:** Cascade AI
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
|
||||||
|
The ByteLyst ecosystem has **7 products** with mobile app code spanning **18 distinct app targets** across iOS, Android, watchOS, macOS, and React Native. The most mature mobile apps are **LysnrAI** and **PeakPulse** (iOS). Most Android apps and companion targets (watchOS, macOS) are scaffold-to-functional but not store-ready.
|
||||||
|
|
||||||
|
**Ecosystem-wide mobile readiness: ~58%**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Product Readiness Scorecard
|
||||||
|
|
||||||
|
| # | Product | iOS | Android | watchOS | macOS | RN/Expo | Overall | Store-Ready? |
|
||||||
|
| --- | ----------------- | --- | ------- | ------- | ----- | ------- | ------- | ------------ |
|
||||||
|
| 1 | **LysnrAI** | 82% | 65% | — | — | — | **74%** | iOS: Near |
|
||||||
|
| 2 | **MindLyst** | 55% | 40% | — | — | — | **48%** | No |
|
||||||
|
| 3 | **ChronoMind** | 78% | 60% | 25% | 30% | — | **58%** | No |
|
||||||
|
| 4 | **JarvisJr** | 72% | 55% | 25% | 30% | — | **52%** | No |
|
||||||
|
| 5 | **NomGap** | — | — | 35% | — | 70% | **62%** | No |
|
||||||
|
| 6 | **PeakPulse** | 85% | — | 20% | — | — | **65%** | iOS: Near |
|
||||||
|
| 7 | **ByteLyst Auth** | 50% | 45% | 15% | — | — | **40%** | No |
|
||||||
|
| 8 | **NoteLett** | — | — | — | — | 45% | **45%** | No |
|
||||||
|
| 9 | **FlowMonk** | — | — | — | — | 50% | **50%** | No |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Detailed Per-Product Breakdown
|
||||||
|
|
||||||
|
### 2.1 LysnrAI — Overall: 74%
|
||||||
|
|
||||||
|
**Stack:** Native Swift/SwiftUI (iOS) + Native Kotlin/Compose (Android)
|
||||||
|
|
||||||
|
#### iOS (82%)
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| ---------------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| **Code completeness** | 90% | 42 Swift files. Full app: auth, dictation, history, settings, calendar, cloud sync, speech routing, voice commands, LLM cleanup |
|
||||||
|
| **Platform SDK** | 95% | 9 Platform/ wrappers (Keychain, Telemetry, Auth, FeatureFlags, KillSwitch, Blob, License, Biometric, Audit) |
|
||||||
|
| **Keyboard extension** | 85% | LysnrKeyboard target with KeyboardViewController + VoiceCommands. Azure STT integrated |
|
||||||
|
| **Tests** | 60% | 5 XCTest files (Audio, KeyboardVoiceCommands, Logger, Telemetry, VoiceCommands) |
|
||||||
|
| **Build verified** | YES | Compiles via xcodebuild |
|
||||||
|
| **Store assets** | 90% | Full icon set (all sizes), screenshots (iOS + Android), feature graphic |
|
||||||
|
| **Entitlements** | YES | App Groups, Keychain sharing |
|
||||||
|
| **Siri/Intents** | YES | StartDictationIntent |
|
||||||
|
|
||||||
|
**Gaps to 100%:**
|
||||||
|
|
||||||
|
- [ ] More XCTest coverage (target: 15+ test files)
|
||||||
|
- [ ] TestFlight distribution pipeline tested end-to-end
|
||||||
|
- [ ] Privacy manifest (PrivacyInfo.xcprivacy) for App Store
|
||||||
|
- [ ] Onboarding flow for first launch
|
||||||
|
|
||||||
|
#### Android (65%)
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| ---------------------- | ----- | -------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| **Code completeness** | 75% | 32 Kotlin files. Full screens: nav, auth, dictation, history, settings. Room DB, Hilt DI, speech routing, sync |
|
||||||
|
| **Platform SDK** | 70% | kotlin-platform-sdk via includeBuild. Config + PlatformModule wired |
|
||||||
|
| **Keyboard extension** | 70% | LysnrInputMethodService exists but less mature than iOS |
|
||||||
|
| **Tests** | 55% | 7 unit tests + 2 e2e instrumented tests |
|
||||||
|
| **Build verified** | YES | compileDebugKotlin passes |
|
||||||
|
| **Store assets** | 80% | Android icons + screenshots in assets/store/ |
|
||||||
|
| **Widget** | YES | LysnrWidget (Glance) |
|
||||||
|
| **Notifications** | YES | LysnrNotificationService (Firebase) |
|
||||||
|
|
||||||
|
**Gaps to 100%:**
|
||||||
|
|
||||||
|
- [ ] More test coverage (target: 15+ test files)
|
||||||
|
- [ ] Firebase google-services.json setup
|
||||||
|
- [ ] Play Store listing metadata (description, categories)
|
||||||
|
- [ ] Adaptive icon foreground/background verified on device
|
||||||
|
- [ ] ProGuard/R8 rules for release build
|
||||||
|
- [ ] Keyboard extension feature parity with iOS
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2.2 MindLyst — Overall: 48%
|
||||||
|
|
||||||
|
**Stack:** KMP shared (19 Kotlin files) + SwiftUI (iOS) + Compose (Android)
|
||||||
|
|
||||||
|
#### KMP Shared Module (65%)
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| ------------------ | ----- | ------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| **Business logic** | 70% | 9 repositories (Triage, Brain, Memory, Streak, Notification, BrainInsight, Reflection, DailyBrief, ShareCard) |
|
||||||
|
| **Models** | 75% | Models.kt with Brain, MemoryItem, TriageResult |
|
||||||
|
| **ViewModels** | 50% | HomeViewModel + TriageViewModel only |
|
||||||
|
| **API clients** | 60% | OpenAIClient + PlatformApiClient + PlatformSyncManager |
|
||||||
|
| **DI** | YES | Koin SharedModule |
|
||||||
|
| **Build verified** | YES | :shared:compileKotlinIosSimulatorArm64 passes |
|
||||||
|
|
||||||
|
#### iOS (55%)
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| --------------------- | ----- | ------------------------------------------------------------------------------------------------- |
|
||||||
|
| **Code completeness** | 60% | 29 Swift files. 4 screens (Home, Capture, BrainDetail, Settings) + Login |
|
||||||
|
| **Platform SDK** | 80% | 7 Platform/ wrappers (Config, Keychain, Telemetry, Auth, FeatureFlags, KillSwitch, CrashReporter) |
|
||||||
|
| **Components** | 40% | CaptureOrb + BrainChipAndTriageCard only |
|
||||||
|
| **Services** | 50% | VoiceCaptureService, AzureSpeechTranscriber, PlatformServiceClient |
|
||||||
|
| **Tests** | 15% | 1 test file (MindLystBrainTests) |
|
||||||
|
| **Extensions** | 20% | ShareExtension (stub), Widget (stub) |
|
||||||
|
| **Store assets** | 0% | No icons, screenshots, or store metadata |
|
||||||
|
|
||||||
|
**Gaps to 100%:**
|
||||||
|
|
||||||
|
- [ ] 6+ more screens needed (Onboarding, Reflection, DailyBrief, Metrics, BrainPacks, Challenge)
|
||||||
|
- [ ] Widget and ShareExtension are stubs — need implementation
|
||||||
|
- [ ] Test coverage (target: 10+ test files)
|
||||||
|
- [ ] Store assets (icons, screenshots, feature graphic)
|
||||||
|
- [ ] Xcode project needs manual setup (no XcodeGen project.yml)
|
||||||
|
- [ ] Navigation needs completion (MainTabView exists but limited tabs)
|
||||||
|
|
||||||
|
#### Android (40%)
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| --------------------- | ----- | ------------------------------------------------------------- |
|
||||||
|
| **Code completeness** | 40% | 12 Kotlin files. MainActivity + Login + 2 UI components only |
|
||||||
|
| **Platform SDK** | 60% | Config + PlatformModule (Koin). Auth migrated to BLAuthClient |
|
||||||
|
| **Screens** | 15% | No dedicated screen files beyond MainActivity composition |
|
||||||
|
| **Tests** | 0% | No Android test files |
|
||||||
|
| **Store assets** | 0% | No icons or store metadata |
|
||||||
|
|
||||||
|
**Gaps to 100%:**
|
||||||
|
|
||||||
|
- [ ] All screens need implementation (Dashboard, Capture, BrainDetail, Settings, etc.)
|
||||||
|
- [ ] Room database for local persistence
|
||||||
|
- [ ] Test suite (target: 10+ test files)
|
||||||
|
- [ ] Store assets
|
||||||
|
- [ ] Notifications
|
||||||
|
- [ ] Widget (Glance)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2.3 ChronoMind — Overall: 58%
|
||||||
|
|
||||||
|
**Stack:** Native Swift/SwiftUI (iOS) + Native Kotlin/Compose (Android) + watchOS + macOS
|
||||||
|
|
||||||
|
#### iOS (78%)
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| --------------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| **Code completeness** | 85% | 44+ Swift files. Rich feature set: timer engine, cascade, urgency, NL parser, routines, gamification, haptics, location, calendar, sleep, wellness, sharing, reschedule |
|
||||||
|
| **Platform SDK** | 80% | Cloud/ wrappers (Config, Keychain, Telemetry, Auth, FeatureFlags, KillSwitch, PlatformSync, CloudKit) + Diagnostics/CrashReporter |
|
||||||
|
| **Tests** | 75% | 8 XCTest files (129 tests): Cascade, Format, TimerEngine, Urgency, Accessibility, Gamification, Reschedule, SharedTimerData |
|
||||||
|
| **Views** | 80% | Full view hierarchy: Components (5), CreateTimer, Focus, Gamification (5) |
|
||||||
|
| **LiveActivity** | YES | TimerActivityAttributes for Dynamic Island |
|
||||||
|
| **Siri** | YES | TimerAppIntents |
|
||||||
|
| **Widgets** | YES | 3 widgets (NextTimer, TimerList, LockScreen) |
|
||||||
|
| **Build verified** | YES | xcodebuild passes |
|
||||||
|
| **Store assets** | 0% | No icons or screenshots |
|
||||||
|
|
||||||
|
**Gaps to 100%:**
|
||||||
|
|
||||||
|
- [ ] Store assets (icons, screenshots)
|
||||||
|
- [ ] Privacy manifest
|
||||||
|
- [ ] Onboarding flow
|
||||||
|
- [ ] Settings view (exists in Android but not in iOS file list — may be in Views/)
|
||||||
|
|
||||||
|
#### Android (60%)
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| --------------------- | ----- | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| **Code completeness** | 65% | 29 Kotlin files. Engine, Room DB, Hilt DI, 5 screens (Timeline, Focus, History, Routine, Settings), sync, calendar, notifications |
|
||||||
|
| **Platform SDK** | 70% | Config + PlatformModule via kotlin-platform-sdk |
|
||||||
|
| **Tests** | 20% | 1 test file (TimerEngineTest) — 30 tests |
|
||||||
|
| **Widget** | YES | TimerWidget (Glance) |
|
||||||
|
| **Services** | YES | ForegroundService, QuickSettingsTile, AlarmManager |
|
||||||
|
| **Build verified** | YES | compileDebugKotlin passes |
|
||||||
|
| **Wear OS** | 10% | WearMainActivity stub only |
|
||||||
|
| **Store assets** | 0% | No icons or screenshots |
|
||||||
|
|
||||||
|
**Gaps to 100%:**
|
||||||
|
|
||||||
|
- [ ] Test coverage (target: 10+ test files)
|
||||||
|
- [ ] Store assets
|
||||||
|
- [ ] Login screen wired to real auth
|
||||||
|
- [ ] Wear OS companion (stub only)
|
||||||
|
|
||||||
|
#### watchOS (25%)
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| ----------------- | ----- | ----------------------------------------------------------------- |
|
||||||
|
| **Code** | 25% | 4 Swift files (App, ContentView, TimerView, ComplicationProvider) |
|
||||||
|
| **Functionality** | 20% | Basic timer display. No interaction beyond viewing |
|
||||||
|
| **Complications** | 25% | ComplicationProvider exists as stub |
|
||||||
|
|
||||||
|
#### macOS (30%)
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| ----------------- | ----- | --------------------------------------------------------------------------- |
|
||||||
|
| **Code** | 30% | 5 Swift files (App, MenuBarPopover, MacTimerStore, MacSettingsView, Views/) |
|
||||||
|
| **Functionality** | 25% | Menu bar popover, local timer store. Not wired to main app data |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2.4 JarvisJr — Overall: 52%
|
||||||
|
|
||||||
|
**Stack:** Native Swift/SwiftUI (iOS) + Native Kotlin/Compose (Android) + watchOS + macOS
|
||||||
|
|
||||||
|
#### iOS (72%)
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| --------------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
|
| **Code completeness** | 80% | 45+ Swift files. Dashboard, Agent builder, Session (live, history, summary), Progress, Store, Settings. Voice engine, memory manager, prompt builder, artifact extractor |
|
||||||
|
| **Platform SDK** | 85% | 7 Platform/ wrappers (Config, Keychain, Telemetry, Auth, FeatureFlags, KillSwitch, CrashReporter) |
|
||||||
|
| **Shared/ engine** | 80% | Engine (5), Models (3), Store (3), Voice (3), Cloud, Notifications, Accessibility, AppGroup, Theme |
|
||||||
|
| **Components** | 70% | 7 components (AgentCard, AddAgent, ProgressRing, SessionRow, ShareCard, StreakBadge, WaveformView) |
|
||||||
|
| **Tests** | 10% | 1 test file (JarvisJrTests.swift) |
|
||||||
|
| **Build verified** | YES | xcodebuild passes |
|
||||||
|
| **Store assets** | 0% | No icons or screenshots |
|
||||||
|
|
||||||
|
**Gaps to 100%:**
|
||||||
|
|
||||||
|
- [ ] Test coverage (target: 15+ test files — engine, voice, memory, store)
|
||||||
|
- [ ] Store assets
|
||||||
|
- [ ] OpenAI Realtime API integration (voice sessions are stub)
|
||||||
|
- [ ] Privacy manifest
|
||||||
|
- [ ] Onboarding flow
|
||||||
|
|
||||||
|
#### Android (55%)
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| --------------------- | ----- | ------------------------------------------------------------------------------------------------- |
|
||||||
|
| **Code completeness** | 60% | 26 Kotlin files. 6 screens, Room DB (Agent + Session), Hilt DI, engine, voice stub, notifications |
|
||||||
|
| **Platform SDK** | 60% | Config + PlatformModule |
|
||||||
|
| **Tests** | 15% | 1 test file (ModelsTest) — 30 JUnit5 tests |
|
||||||
|
| **Build verified** | YES | compileDebugKotlin passes |
|
||||||
|
| **Wear OS** | 10% | WearMainActivity stub |
|
||||||
|
| **Store assets** | 0% | No icons or screenshots |
|
||||||
|
|
||||||
|
**Gaps to 100%:**
|
||||||
|
|
||||||
|
- [ ] Test coverage (target: 10+ test files)
|
||||||
|
- [ ] Store assets
|
||||||
|
- [ ] Voice session implementation
|
||||||
|
- [ ] Widget
|
||||||
|
|
||||||
|
#### watchOS (25%) — QuickSession + Complications stubs (5 files)
|
||||||
|
|
||||||
|
#### macOS (30%) — Menu bar app (4 files), basic agent store + settings
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2.5 NomGap — Overall: 62%
|
||||||
|
|
||||||
|
**Stack:** React Native (Expo SDK 55) + watchOS companion (Swift)
|
||||||
|
|
||||||
|
#### React Native / Expo (70%)
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| --------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| **Code completeness** | 80% | 109+ TS/TSX files. Full feature set: fasting timer, body viz (Skia), protocols, coaching, gamification, safety, social, meals, hydration, insights |
|
||||||
|
| **Screens** | 85% | 5 tabs + onboarding + meal-log. Screens: Fast, Journey, Social, Learn, Profile, Protocol |
|
||||||
|
| **Lib/engine** | 90% | 20+ pure engine modules (timer, stages, science, safety, gamification, organ-data, molecule-flows, etc.) |
|
||||||
|
| **API clients** | 80% | 10 API modules (auth, billing, blob, fasting, meal, push, social, config, client, index) |
|
||||||
|
| **Tests** | 75% | 18 test files, 505 tests |
|
||||||
|
| **Platform SDK** | 60% | @bytelyst/feature-flag-client, kill-switch-client, platform-client, offline-queue wired |
|
||||||
|
| **Store assets** | 50% | Expo icon assets (favicon, adaptive icons) but no App/Play Store screenshots |
|
||||||
|
| **Build verified** | PARTIAL | TypeScript compiles. Expo build not verified end-to-end |
|
||||||
|
|
||||||
|
**Gaps to 100%:**
|
||||||
|
|
||||||
|
- [ ] EAS Build pipeline (Expo Application Services)
|
||||||
|
- [ ] App Store / Play Store screenshots
|
||||||
|
- [ ] Push notifications (expo-notifications wired but not tested with real push)
|
||||||
|
- [ ] HealthKit integration (hook exists but needs native module)
|
||||||
|
- [ ] @bytelyst/react-auth wired in app layout
|
||||||
|
- [ ] Deep linking / universal links
|
||||||
|
- [ ] Privacy policy / Terms page in app
|
||||||
|
|
||||||
|
#### watchOS Companion (35%)
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| ----------------- | ----- | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| **Code** | 40% | 9 Swift files: App, ContentView, FastingTimerView, HydrationView, StatsView, WatchSessionManager, ComplicationProvider + 2 Shared |
|
||||||
|
| **Functionality** | 30% | Views exist but WatchConnectivity not proven end-to-end |
|
||||||
|
|
||||||
|
#### iOS Native Extensions (40%)
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| --------------- | ----- | ---------------------------------------------------------------------------------------- |
|
||||||
|
| **Widgets** | 45% | 6 Swift files: LiveActivity, LockScreen, Medium, Timer, WidgetBundle |
|
||||||
|
| **Siri** | 30% | NomGapShortcuts.swift exists |
|
||||||
|
| **Integration** | 20% | Expo plugins exist (withAndroidWidget, withWatchApp, withWidgetExtension) but unverified |
|
||||||
|
|
||||||
|
**Gaps to 100%:**
|
||||||
|
|
||||||
|
- [ ] watchOS ↔ React Native WatchConnectivity bridge
|
||||||
|
- [ ] Widget data flow from Expo to native WidgetKit
|
||||||
|
- [ ] Siri Shortcuts wired to Expo
|
||||||
|
- [ ] Android Glance widget integration (files exist in android-extensions/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2.6 PeakPulse — Overall: 65%
|
||||||
|
|
||||||
|
**Stack:** Native Swift/SwiftUI (iOS only) + watchOS
|
||||||
|
|
||||||
|
#### iOS (85%)
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| --------------------- | ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| **Code completeness** | 90% | 45+ Swift files. Full MVVM: 5 ViewModels, 17 Services (Location, Altimeter, Haptics, Motion, SessionRecorder, Persistence, SkiIntelligence, HikerIntelligence, Export, GPXImport, Weather, Safety, Goals, Gamification, LiveActivity, HealthKit, Geocoding) |
|
||||||
|
| **Platform SDK** | 90% | 8 Platform/ wrappers (Config, Keychain, Telemetry, Auth, FeatureFlags, KillSwitch, CrashReporter, Diagnostics, PlatformSync) |
|
||||||
|
| **Models** | 90% | 5 model files (ActivitySession SwiftData, TrackPoint, HapticEvent, ActivityType, Units) |
|
||||||
|
| **Views** | 85% | 8 main views + 17 components |
|
||||||
|
| **Tests** | 85% | 16 XCTest files — comprehensive coverage of all services |
|
||||||
|
| **LiveActivity** | YES | Dynamic Island + Lock Screen |
|
||||||
|
| **Siri** | YES | PeakPulseShortcuts |
|
||||||
|
| **Widgets** | YES | 3 widgets (RecentSession, Streak, QuickStart) |
|
||||||
|
| **Build verified** | YES | xcodebuild passes |
|
||||||
|
| **Onboarding** | YES | OnboardingView (4-page flow) |
|
||||||
|
| **Store assets** | 0% | No icons or screenshots |
|
||||||
|
|
||||||
|
**Gaps to 100%:**
|
||||||
|
|
||||||
|
- [ ] Store assets (icons, screenshots, feature graphic)
|
||||||
|
- [ ] Privacy manifest (HealthKit, Location usage descriptions)
|
||||||
|
- [ ] TestFlight pipeline
|
||||||
|
- [ ] No Android app planned (iOS-only product)
|
||||||
|
|
||||||
|
#### watchOS (20%)
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| ----------------- | ----- | ------------------------------------------------ |
|
||||||
|
| **Code** | 20% | 2 Swift files: App + ContentView (minimal stubs) |
|
||||||
|
| **Functionality** | 15% | Basic shell, no sensor integration |
|
||||||
|
|
||||||
|
**Gaps to 100%:**
|
||||||
|
|
||||||
|
- [ ] CoreLocation + CMAltimeter on watchOS
|
||||||
|
- [ ] Workout session with HealthKit
|
||||||
|
- [ ] iPhone ↔ Watch data sync via WCSession
|
||||||
|
- [ ] Complications
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2.7 ByteLyst Auth — Overall: 40%
|
||||||
|
|
||||||
|
**Stack:** Native Swift/SwiftUI (iOS) + Kotlin/Compose (Android) + watchOS + App Clip
|
||||||
|
|
||||||
|
#### iOS (50%)
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| --------------------- | ----- | ----------------------------------------------------------------------------------------------- |
|
||||||
|
| **Code completeness** | 55% | 14 Swift files. 7 screens: Dashboard, Approvals, TOTP, Devices, MFA Settings, QR Scan, Settings |
|
||||||
|
| **Platform SDK** | 30% | No Platform/ wrapper directory — relies directly on BLAuthClient/BLAuthUI from SDK |
|
||||||
|
| **Tests** | 0% | No test files |
|
||||||
|
| **Widgets** | 30% | TotpWidget.swift exists |
|
||||||
|
| **App Clip** | 20% | ByteLystAuthClipApp.swift stub |
|
||||||
|
| **Build verified** | NO | Depends on ByteLystPlatformSDK (SPM local path) — not independently verified |
|
||||||
|
| **Store assets** | 0% | None |
|
||||||
|
|
||||||
|
#### Android (45%)
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| --------------------- | ----- | ----------------------------------------------------------------------------------------------------------- |
|
||||||
|
| **Code completeness** | 50% | 17 Kotlin files. Tabs: Dashboard, Codes, Approvals, Devices, Settings, QR Scan. MFA settings, notifications |
|
||||||
|
| **Platform SDK** | 40% | AppConfig exists but no kotlin-platform-sdk includeBuild |
|
||||||
|
| **TOTP** | YES | TotpGenerator.kt |
|
||||||
|
| **Widget** | 30% | TotpGlanceWidget.kt |
|
||||||
|
| **Tests** | 0% | No test files |
|
||||||
|
| **Build verified** | NO | Depends on kotlin-platform-sdk includeBuild — not independently verified |
|
||||||
|
| **Store assets** | 0% | None |
|
||||||
|
|
||||||
|
#### watchOS (15%)
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| ------------ | ----- | -------------------------------------------------- |
|
||||||
|
| **Code** | 15% | 2 files: App + ContentView |
|
||||||
|
| **Push MFA** | 0% | Designed for push approve/deny but not implemented |
|
||||||
|
|
||||||
|
**Gaps to 100%:**
|
||||||
|
|
||||||
|
- [ ] Both platforms: test suites (0 tests currently)
|
||||||
|
- [ ] Both platforms: store assets
|
||||||
|
- [ ] iOS: BLAuthUI integration (screens reference it but SDK not verified)
|
||||||
|
- [ ] Android: kotlin-platform-sdk wiring
|
||||||
|
- [ ] watchOS: push MFA approve/deny
|
||||||
|
- [ ] App Clip: QR code scanning implementation
|
||||||
|
- [ ] TOTP widget data flow (Keychain → WidgetKit / Glance)
|
||||||
|
- [ ] Depends on SmartAuth Phase 2+ backend features (many not built yet)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2.8 NoteLett — Overall: 45%
|
||||||
|
|
||||||
|
**Stack:** React Native (Expo) + TypeScript
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| ------------------ | ------- | ----------------------------------------------------------------------------------- |
|
||||||
|
| **Screens** | 55% | 4-tab navigator (Home, Inbox, Capture, Search) + Auth + Note detail. 9 screen files |
|
||||||
|
| **API clients** | 70% | 6 API files (auth, client, config, notes, workspaces, note-agent-actions) |
|
||||||
|
| **Stores** | 65% | 5 Zustand stores (auth, inbox, notes, workspace, mmkv-storage) |
|
||||||
|
| **Platform SDK** | 60% | platform.ts wired (telemetry, flags, kill-switch, blob) |
|
||||||
|
| **Tests** | 50% | 4 test files (auth-store, inbox-store, notes-store, workspace-store) — 23 tests |
|
||||||
|
| **Theme** | 40% | colors.ts + index.ts but limited token coverage |
|
||||||
|
| **Offline** | 40% | offline-queue.ts exists |
|
||||||
|
| **Build verified** | PARTIAL | TypeScript compiles |
|
||||||
|
| **Store assets** | 0% | None |
|
||||||
|
|
||||||
|
**Gaps to 100%:**
|
||||||
|
|
||||||
|
- [ ] More screens (Settings, Workspaces list, Saved views, Reviews)
|
||||||
|
- [ ] Rich text editor for notes
|
||||||
|
- [ ] Push notifications
|
||||||
|
- [ ] Offline sync with conflict resolution
|
||||||
|
- [ ] EAS Build pipeline
|
||||||
|
- [ ] Store assets
|
||||||
|
- [ ] Deep linking
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2.9 FlowMonk — Overall: 50%
|
||||||
|
|
||||||
|
**Stack:** React Native (Expo) + TypeScript
|
||||||
|
|
||||||
|
| Dimension | Score | Detail |
|
||||||
|
| ------------------ | ------- | --------------------------------------------------------------------------------------------- |
|
||||||
|
| **Screens** | 65% | 9 screens: Dashboard, Capture, Schedule, Tasks, Flows, Urgent, Recommendations, Login, Layout |
|
||||||
|
| **API client** | 60% | api.ts (typed fetch), types.ts, product-config.ts, clients.ts |
|
||||||
|
| **Offline** | 50% | offline-sync.ts + storage.ts |
|
||||||
|
| **Tests** | 40% | 5 test files (api, offline-sync, 3 screen tests) |
|
||||||
|
| **Platform SDK** | 50% | clients.ts references @bytelyst/\* but limited integration |
|
||||||
|
| **Build verified** | PARTIAL | TypeScript compiles |
|
||||||
|
| **Store assets** | 0% | None |
|
||||||
|
|
||||||
|
**Gaps to 100%:**
|
||||||
|
|
||||||
|
- [ ] Zustand stores (currently no state management layer)
|
||||||
|
- [ ] Settings screen
|
||||||
|
- [ ] Push notifications
|
||||||
|
- [ ] EAS Build pipeline
|
||||||
|
- [ ] Store assets
|
||||||
|
- [ ] More test coverage
|
||||||
|
- [ ] Theme tokens (no design system integration)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Cross-Cutting Gap Analysis
|
||||||
|
|
||||||
|
### 3.1 Store Readiness
|
||||||
|
|
||||||
|
| Product | iOS Icons | Android Icons | Screenshots | Store Metadata | Privacy Policy |
|
||||||
|
| ---------- | --------- | ------------- | ----------- | -------------- | -------------- |
|
||||||
|
| LysnrAI | YES | YES | YES | Partial | YES (web) |
|
||||||
|
| MindLyst | NO | NO | NO | NO | NO |
|
||||||
|
| ChronoMind | NO | NO | NO | NO | YES (web) |
|
||||||
|
| JarvisJr | NO | NO | NO | NO | YES (web) |
|
||||||
|
| NomGap | Expo only | Expo only | NO | NO | NO |
|
||||||
|
| PeakPulse | NO | N/A | NO | NO | NO |
|
||||||
|
| Auth App | NO | NO | NO | NO | NO |
|
||||||
|
| NoteLett | NO | N/A | NO | NO | NO |
|
||||||
|
| FlowMonk | NO | N/A | NO | NO | NO |
|
||||||
|
|
||||||
|
**Only LysnrAI has store assets.** All other products need icon generation + screenshots.
|
||||||
|
|
||||||
|
### 3.2 Platform SDK Integration
|
||||||
|
|
||||||
|
| Product | iOS SDK Wrappers | Android SDK (kotlin) | React Native SDK |
|
||||||
|
| ---------- | ---------------- | ------------------------ | ----------------- |
|
||||||
|
| LysnrAI | 9/13 (95%) | Via PlatformModule (70%) | N/A |
|
||||||
|
| MindLyst | 7/13 (80%) | Via PlatformModule (60%) | N/A |
|
||||||
|
| ChronoMind | 8/13 (80%) | Via PlatformModule (70%) | N/A |
|
||||||
|
| JarvisJr | 7/13 (85%) | Via PlatformModule (60%) | N/A |
|
||||||
|
| NomGap | N/A | N/A | 4/8 TS pkgs (60%) |
|
||||||
|
| PeakPulse | 8/13 (90%) | N/A | N/A |
|
||||||
|
| Auth App | 0/13 (30%\*) | 0 (40%\*) | N/A |
|
||||||
|
| NoteLett | N/A | N/A | 4/8 TS pkgs (60%) |
|
||||||
|
| FlowMonk | N/A | N/A | 3/8 TS pkgs (50%) |
|
||||||
|
|
||||||
|
\*Auth App uses BLAuthClient/BLAuthUI directly, not thin wrappers
|
||||||
|
|
||||||
|
### 3.3 Test Coverage
|
||||||
|
|
||||||
|
| Product | iOS Tests | Android Tests | RN/Expo Tests | Total Mobile Tests |
|
||||||
|
| ---------- | ------------- | --------------- | -------------- | ------------------ |
|
||||||
|
| LysnrAI | 5 files | 7 files + 2 e2e | N/A | ~14 |
|
||||||
|
| MindLyst | 1 file | 0 files | N/A | 1 |
|
||||||
|
| ChronoMind | 8 files (129) | 1 file (30) | N/A | 159 |
|
||||||
|
| JarvisJr | 1 file | 1 file (30) | N/A | ~35 |
|
||||||
|
| NomGap | N/A | N/A | 18 files (505) | 505 |
|
||||||
|
| PeakPulse | 16 files | N/A | N/A | ~80+ |
|
||||||
|
| Auth App | 0 files | 0 files | N/A | 0 |
|
||||||
|
| NoteLett | N/A | N/A | 4 files (23) | 23 |
|
||||||
|
| FlowMonk | N/A | N/A | 5 files | ~15 |
|
||||||
|
|
||||||
|
### 3.4 Build Verification Status
|
||||||
|
|
||||||
|
| Product | iOS Build | Android Build | RN Build | Watch Build | Mac Build |
|
||||||
|
| ---------- | --------- | ------------- | -------- | ----------- | --------- |
|
||||||
|
| LysnrAI | YES | YES | N/A | N/A | N/A |
|
||||||
|
| MindLyst | YES (KMP) | YES (APK) | N/A | N/A | N/A |
|
||||||
|
| ChronoMind | YES | YES | N/A | Untested | Untested |
|
||||||
|
| JarvisJr | YES | YES | N/A | Untested | Untested |
|
||||||
|
| NomGap | N/A | N/A | Partial | Untested | N/A |
|
||||||
|
| PeakPulse | YES | N/A | N/A | Untested | N/A |
|
||||||
|
| Auth App | Untested | Untested | N/A | Untested | N/A |
|
||||||
|
| NoteLett | N/A | N/A | Partial | N/A | N/A |
|
||||||
|
| FlowMonk | N/A | N/A | Partial | N/A | N/A |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Priority Action Plan — Path to 100%
|
||||||
|
|
||||||
|
### Tier 1: Nearest to Store-Ready (2-3 weeks each)
|
||||||
|
|
||||||
|
| # | Action | Product | Impact |
|
||||||
|
| --- | ------------------------------------------- | ------------------- | ---------- |
|
||||||
|
| 1 | Generate store assets (icons + screenshots) | **PeakPulse iOS** | 85% → 95% |
|
||||||
|
| 2 | Privacy manifest + TestFlight pipeline | **PeakPulse iOS** | 95% → 100% |
|
||||||
|
| 3 | Add onboarding flow + privacy manifest | **LysnrAI iOS** | 82% → 92% |
|
||||||
|
| 4 | TestFlight pipeline | **LysnrAI iOS** | 92% → 100% |
|
||||||
|
| 5 | Firebase setup + store listing | **LysnrAI Android** | 65% → 80% |
|
||||||
|
|
||||||
|
### Tier 2: Get to Beta-Quality (4-6 weeks each)
|
||||||
|
|
||||||
|
| # | Action | Product | Impact |
|
||||||
|
| --- | ------------------------------------------------ | ---------------------- | --------- |
|
||||||
|
| 6 | Store assets + test coverage + settings view | **ChronoMind iOS** | 78% → 90% |
|
||||||
|
| 7 | Test coverage + store assets | **ChronoMind Android** | 60% → 75% |
|
||||||
|
| 8 | Test coverage + voice integration + store assets | **JarvisJr iOS** | 72% → 85% |
|
||||||
|
| 9 | EAS Build pipeline + store assets | **NomGap RN** | 70% → 85% |
|
||||||
|
|
||||||
|
### Tier 3: Scaffold → Functional (6-10 weeks each)
|
||||||
|
|
||||||
|
| # | Action | Product | Impact |
|
||||||
|
| --- | ------------------------------------------------- | -------------------- | --------- |
|
||||||
|
| 10 | Complete 6 missing screens + tests + store assets | **MindLyst iOS** | 55% → 75% |
|
||||||
|
| 11 | All screens from scratch + Room DB + tests | **MindLyst Android** | 40% → 65% |
|
||||||
|
| 12 | Remaining screens + state management + tests | **FlowMonk RN** | 50% → 70% |
|
||||||
|
| 13 | More screens + editor + tests | **NoteLett RN** | 45% → 65% |
|
||||||
|
|
||||||
|
### Tier 4: Depends on Backend (10+ weeks)
|
||||||
|
|
||||||
|
| # | Action | Product | Impact |
|
||||||
|
| --- | -------------------------------------------- | -------------------- | --------- |
|
||||||
|
| 14 | SmartAuth Phase 2+ backend, then app screens | **Auth App iOS** | 50% → 75% |
|
||||||
|
| 15 | SmartAuth Phase 2+ backend, then app screens | **Auth App Android** | 45% → 70% |
|
||||||
|
|
||||||
|
### Tier 5: Companion Targets (Low Priority)
|
||||||
|
|
||||||
|
| # | Action | Product | Impact |
|
||||||
|
| --- | ------------------------------------- | ---------------------- | --------- |
|
||||||
|
| 16 | watchOS timer display + complications | **ChronoMind Watch** | 25% → 60% |
|
||||||
|
| 17 | watchOS quick session + complications | **JarvisJr Watch** | 25% → 60% |
|
||||||
|
| 18 | watchOS sensor integration | **PeakPulse Watch** | 20% → 60% |
|
||||||
|
| 19 | macOS menu bar data wiring | **ChronoMind Mac** | 30% → 60% |
|
||||||
|
| 20 | macOS menu bar data wiring | **JarvisJr Mac** | 30% → 60% |
|
||||||
|
| 21 | watchOS ↔ RN bridge | **NomGap Watch** | 35% → 60% |
|
||||||
|
| 22 | watchOS push MFA | **Auth Watch** | 15% → 50% |
|
||||||
|
| 23 | Android Glance widget integration | **NomGap Android ext** | 30% → 60% |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Effort Estimates
|
||||||
|
|
||||||
|
| Effort Level | Description | Items |
|
||||||
|
| ------------------ | ----------------------------------------------- | -------------------- |
|
||||||
|
| **S (1-2 days)** | Store asset generation, privacy manifest | #1, #2, #3 |
|
||||||
|
| **M (3-5 days)** | TestFlight pipeline, Firebase setup, onboarding | #4, #5, #6 |
|
||||||
|
| **L (1-2 weeks)** | Test suites, screen implementations, EAS Build | #7, #8, #9, #12, #13 |
|
||||||
|
| **XL (3-4 weeks)** | Full screen buildout, state management, tests | #10, #11, #14, #15 |
|
||||||
|
| **Ongoing** | Companion targets, feature parity | #16-#23 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Recommendations
|
||||||
|
|
||||||
|
1. **Focus on PeakPulse iOS and LysnrAI iOS first** — they're 85% and 82% respectively, closest to App Store submission. Generating store assets and adding privacy manifests gets them to 95%+.
|
||||||
|
|
||||||
|
2. **Run `/generate-store-assets` workflow** for all products — this is the single biggest gap across the ecosystem (only LysnrAI has assets).
|
||||||
|
|
||||||
|
3. **Android apps need test investment** — most have 0-1 test files. ChronoMind Android is the most feature-complete Android app and should be the first to get comprehensive tests.
|
||||||
|
|
||||||
|
4. **ByteLyst Auth App is blocked** on SmartAuth backend (Phase 2+ features not built). Don't invest in the auth app until platform-service auth module has TOTP, device management, and push MFA endpoints.
|
||||||
|
|
||||||
|
5. **React Native apps (NomGap, FlowMonk, NoteLett) need EAS Build pipeline** — none have been verified with actual device builds through Expo Application Services.
|
||||||
|
|
||||||
|
6. **Companion targets (watchOS, macOS, Wear OS) are all stubs** — deprioritize until primary platforms are store-ready.
|
||||||
Loading…
Reference in New Issue
Block a user