Skip to content

Building and Running

Yakiv Kovalskyi edited this page Jul 14, 2026 · 1 revision

Building & Running

Requirements

  • A full Xcode 15+ install (iOS 17 deployment target) — not just the Command Line Tools; ./run.sh checks for this and tells you if it can't find one.
  • XcodeGen (brew install xcodegen)
  • jq (brew install jq) — used by ./run.sh to pick a simulator and read project.yml.
  • A real iPhone, not the Simulator, if you want to see THE EYE actually work — the front camera does nothing in the Simulator.

Quickest path — ./run.sh

From the repo root, one command builds, installs, and launches THE EYE on an iOS Simulator:

./run.sh

It checks for xcodegen and jq, finds a full Xcode install (a bare Command Line Tools install can't build iOS apps or run the Simulator), runs xcodegen generate, boots an available iPhone simulator, builds, installs, and launches the app. It only generates app/LULL.xcodeproj (already gitignored) and builds into a temp derived-data directory outside the repo — it doesn't touch LULLKit or app/Sources.

The front camera is a no-op in the SimulatorTHE EYE opens but sees nothing there. This is genuinely useful for reviewing the vignette, copy, and phase transitions without a device (see the README's "Screens" section for what that looks like), but to see it actually watch you need a real device (below).

Generate and open the app project (real device)

The .xcodeproj is not committed — it's generated from app/project.yml, the same way the rest of the repo treats derived artifacts:

brew install xcodegen        # once
cd app
xcodegen                     # generates LULL.xcodeproj
open LULL.xcodeproj          # then build + run on a real device

No XcodeGen available? Per app/README.md: create a new iOS App target in Xcode 15+, add the files under app/Sources/, and add the local LULLKit package as a dependency. The sources are plain SwiftUI — nothing exotic.

app/project.yml sets the important App-Review-facing bits directly:

  • PRODUCT_BUNDLE_IDENTIFIER: io.github.testtest126.lull
  • INFOPLIST_KEY_NSCameraUsageDescription: the honest camera rationale string shown by the OS
  • Deployment target: iOS 17.0

What running it does

From app/README.md, in order:

  1. Asks in-app first. Sensor.camera.rationale is shown before the OS prompt. A "no" at either level is final — nothing watches.
  2. Opens the front camera, degraded and never shown clean. No frame is recorded; nothing leaves the device.
  3. Runs the clock: EyeSession moves calm → noticing → awake on a timer.
  4. "Close the eye" is always present — it revokes consent and stops the camera immediately (the panic switch).

Testing LULLKit

LULLKit is a standalone Swift package and builds/tests independent of the iOS app or a simulator:

cd LULLKit
swift test

As of this writing that's 16 tests across three files — ConsentTests, EyeSessionTests, AtmosphereTests — covering the consent invariants (see The Safety Invariant), the EyeSession phase machine (including the anti-fast-forward clamp), and the Atmosphere narration layer. Per the README and CLAUDE.md, this suite is meant to stay green from commit one and every commit after — it's the project's "perft," the executable proof that consent and the dread clock behave as designed.

swift test requires a full Swift toolchain with XCTest available (ships with Xcode's command-line tools). A bare Swift toolchain without Xcode may not have XCTest on its module search path.

Clone this wiki locally