# AGENTS.md (iOS)

## Scope
Instructions for work under `/Users/buzzert/src/sybil-2/ios`.

## Build + Run
- Preferred build command: `just build`
- `just build` will:
  1. generate `Sybil.xcodeproj` with `xcodegen` if missing,
  2. build scheme `Sybil` for `iPhone 16e` simulator.
- Preferred test command: `just test`
- `just test` runs the Swift package tests through `xcodebuild test` on the `iPhone 16e` iOS simulator from `ios/Packages/Sybil`.
- `just test` disables Xcode parallel testing because the current async view-model tests use timing-sensitive selection tasks.
- Do not use plain `swift test` for this package; it runs as host macOS and hits a deployment mismatch with `MarkdownUI`.
- If `xcbeautify` is installed it is used automatically; otherwise raw `xcodebuild` output is used.

## Simulator Workflow
- Run the app in the simulator with `just run` from `/Users/buzzert/src/sybil-2/ios`.
- `just run` boots the `iPhone 16e` simulator if needed, builds with a stable derived data path, installs `Sybil.app`, and launches bundle id `net.buzzert.sybil2`.
- Capture a simulator screenshot with `just screenshot` from `/Users/buzzert/src/sybil-2/ios`; it writes `build/sybil-screenshot.png` by default.
- To choose a screenshot path, run `just screenshot path=build/name.png`.
- The underlying screenshot command is `xcrun simctl io booted screenshot <path>` and requires a booted simulator.

## Release Workflow
- iOS release tags use the annotated tag namespace `release/ios/vX.Y.Z`; increment from the latest existing `release/ios/v*` tag.
- Tag message convention is `ios: X.Y.Z`, for example `git tag -a release/ios/v1.13.5 -m "ios: 1.13.5"`.
- Push the release commit and tag together with `git push origin <branch> release/ios/vX.Y.Z`.
- Fastlane derives the marketing version from the release tag and stamps `ios/Apps/Sybil/project.yml` during CI, so do not manually bump `MARKETING_VERSION` for normal tagged releases unless explicitly requested.

## App Structure
- App target entry: `/Users/buzzert/src/sybil-2/ios/Apps/Sybil/Sources/SybilApp.swift`
- Shared iOS app code lives in Swift package:
  - `/Users/buzzert/src/sybil-2/ios/Packages/Sybil/Sources/Sybil`
- Main UI root: `SplitView.swift`
- Networking + SSE client: `SybilAPIClient.swift`
- State coordinator: `SybilViewModel.swift`

## Product Expectations
- Keep the iOS design aligned to the web app dark aesthetic (no light mode support required).
- Preserve these core features:
  - conversation/search list,
  - streaming chat transcript,
  - streaming search results + answer,
  - settings screen for API URL and token.
- Markdown rendering currently uses `MarkdownUI` via SwiftPM.

## API Contract
- iOS client must follow docs in:
  - `/Users/buzzert/src/sybil-2/docs/api/rest.md`
  - `/Users/buzzert/src/sybil-2/docs/api/streaming-chat.md`
- If backend contract changes (request/response shapes, SSE events, auth semantics), update docs in the same change.

## Practical Notes
- Default API URL is `http://127.0.0.1:8787` (configurable in-app).
- The iOS client preserves an explicit `/api` base path for proxied deployments.
- Provider fallback models:
  - OpenAI: `gpt-4.1-mini`
  - Anthropic: `claude-3-5-sonnet-latest`
  - xAI: `grok-3-mini`
  - Gemini: `gemini-3.5-flash`
  - Hermes Agent: `hermes-agent`
