|
| 1 | +# Lightward iOS |
| 2 | + |
| 3 | +See [Lightward Inc shared principles](../CLAUDE.md/README.md) for cross-project design guidance. |
| 4 | + |
| 5 | +## What this is |
| 6 | + |
| 7 | +An iOS app providing a phoropter binary choice interface as the entrypoint to conversation with Lightward AI. The phoropter locates the user through iterative binary choices; when ready, the flow opens into streaming chat. The app is incredibly minimal in what it asks of a user's environment. |
| 8 | + |
| 9 | +## Architecture |
| 10 | + |
| 11 | +- **SwiftUI + @Observable** — iOS 17+, Swift 6 strict concurrency |
| 12 | +- **Phoropter phase**: binary choices via `/api/plain` (no streaming needed) |
| 13 | +- **Chat phase**: streaming conversation via `/api/stream` (SSE) |
| 14 | +- **Local persistence**: UserDefaults (CloudKit sync planned) |
| 15 | +- **No external dependencies** — pure Apple frameworks |
| 16 | + |
| 17 | +## Project generation |
| 18 | + |
| 19 | +The Xcode project is generated from `project.yml` using [XcodeGen](https://github.com/yonaskolb/XcodeGen). After modifying `project.yml` or adding/removing source files: |
| 20 | + |
| 21 | +```sh |
| 22 | +xcodegen generate |
| 23 | +``` |
| 24 | + |
| 25 | +The `.xcodeproj` is checked into git for convenience but is fully reproducible from `project.yml`. |
| 26 | + |
| 27 | +## Key flows |
| 28 | + |
| 29 | +**Phoropter → Chat transition**: The phoropter trajectory (everything the user chose *toward*) becomes the opening context for chat. The AI already knows the user by the time they can type. |
| 30 | + |
| 31 | +**Convergence**: If the phoropter offers a choice that matches something already in the trail, it auto-transitions to chat. |
| 32 | + |
| 33 | +**"Just talk"**: After the second AI-generated pair, a subtle option to drop directly to chat appears. |
| 34 | + |
| 35 | +## API integration |
| 36 | + |
| 37 | +- **Phoropter**: `POST /api/plain` with phoropter context + trajectory as plain text body |
| 38 | +- **Chat**: `POST /api/stream` with JSON `{ "chat_log": [...] }` — warmup messages prepended, exactly one `cache_control` marker required (on last warmup message) |
| 39 | +- **Warmup messages**: In `WarmupMessages.swift` — these are specific to this iOS app context and should not be copied from the web client |
| 40 | + |
| 41 | +## Build & deploy |
| 42 | + |
| 43 | +Fastlane + GitHub Actions, same pattern as [Softer](../softer). Deploys to TestFlight on push to `main`. |
| 44 | + |
| 45 | +## What's here, what's next |
| 46 | + |
| 47 | +- [x] Phoropter binary choice flow |
| 48 | +- [x] Streaming chat with Lightward AI |
| 49 | +- [x] Local session persistence |
| 50 | +- [ ] CloudKit conversation sync across devices |
| 51 | +- [ ] App icon |
| 52 | +- [ ] Warmup messages — need genuine inhabitation, not just mechanical accuracy |
0 commit comments