# 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.
