An iOS reader for people who read to think — not just to finish books.
Local-first. BYOK. Your words are the product; the book is the evidence.
Why · What you get · Hard lines · Status · Build · Architecture · Contributing
Elsepage is a native iOS EPUB reader with a personal thinking loop: read, end a session, say what it made you think — text or voice — keep the words on-device, and when you want, get a grounded AI response that cites the book instead of generic ChatGPT glow.
It does not own your progress bar and call it a day. It does not summarize the book for you by default. It does not phone home.
Bring your own key (BYOK). Provider-agnostic — OpenAI, DeepSeek, Gemini-compatible, or Anthropic behind one small
ModelClientcontract. The key lives only in Keychain. No Elsepage backend, no account, no cloud vector database.
Reading apps fail in two boring ways:
- Finish the book, get nothing. The app tracks progress, streaks, and "completed" — and the two minutes after closing the book, the part that actually makes a book yours, is left to evaporate.
- AI summary machines. The book gets digested before you've formed a view, so the reading is outsourced and your own thoughts never get to exist.
Elsepage is built so both stay rare:
| Pillar | What it means in practice |
|---|---|
| Your words are first-class | The raw reflection is saved before any AI touch and is never overwritten (PRD P2). |
| Local-first to the core | EPUB, highlights, reflections and the SQLite store live on your device. Reading and reflecting work with no network. |
| Grounded AI | Agent replies carry clickable citations that jump back to the exact passage — not "trust me, I read it". |
| BYOK, provider-agnostic | One ModelClient interface; swap OpenAI / DeepSeek / Gemini / Anthropic without touching the loop. |
| Voice that's actually usable | Tap-to-talk or hold-to-talk, live editable transcription, optional MP3, and one-tap AI polish that keeps your meaning. |
| Thinking is the product | Session context, same-book past thoughts, and a structured Journal — the book is evidence, not the end. |
If you want an iOS reader that treats what you thought as the deliverable, you're in the right repo.
- Real EPUB reading — Readium engine; stable position, highlights, notes, search.
- Explicit session end — "这一段约 N 分钟", then an invitation to leave something behind.
- Reflection that saves first — raw text/voice is persisted locally before any network work; an AI failure never loses your words.
- A grounded Agent — knows what you just read (session context), can retrieve the current book, connects past thoughts from the same book, and cites evidence you can tap back to the page.
- Tap-to-talk or hold-to-talk, with live (partial) transcription you can edit.
- Optional audio file — MP3 on device, AAC fallback on the simulator.
- One-tap AI polish — tidies your spoken words without changing meaning; the raw words stay stored.
- Structured Journal — session duration, chapters, linked highlights, what you think, open questions, citations.
- Router transparency — every reply records the proposed vs validated context plan, fallback cause, and per-stage timing; the UI tells you "this used N passages of what you've read".
- No Elsepage backend, account, or cloud vector database
- No default "summarize the whole book" behavior
- No overwriting your original expression with AI output
- No API keys outside Keychain
- No reflection leaves your device except to the provider you explicitly chose
A real product loop, not a demo: read → reflect → save → grounded reply → Journal work end-to-end, 356 tests green, and an unsigned iOS build gate passes.
| Area | State |
|---|---|
| Reader foundation | ~85% |
| Reflection loop | ~80% |
| Book context / Agent | ~90% — citations grounded; small-to-big child retrieval (≈350-char retrieval units → parent-anchored evidence windows), hybrid lexical + semantic recall for reflections/memories, cross-encoder rerank gate |
| Context engineering | planner-grade context plan (dense/lexical split) → source-specific retrieval → candidate ranking/dedup/budget → ContextBundle; anti-spoiler enforced at retrieval and expansion |
| Voice reflection | shipped: hold/tap, MP3, AI polish |
| Memory / personal context | 0.3 core shipped: memory store, My Mind, cross-book recall, semantic memory matching |
| Habit / onboarding / release polish | early (Reading/Thinking streak live; onboarding/achievements pending) |
Open backlog and ideas: Issues.
| Tool | Notes |
|---|---|
| Xcode 16+ | iOS 18 SDK |
| XcodeGen | brew install xcodegen |
| Readium | resolved as an Xcode package (swift-toolkit 3.3.0) |
xcodegen generate
open ReadLoop.xcodeproj # resolve packages, run the ReadLoop schemeThe portable suite needs no Xcode:
swift test # 207 testsA device/simulator run needs the full Xcode install — Readium's navigator is UIKit-based. Manual-device checks are tracked in docs/READER_FOUNDATION_XCODE_GATE.md.
One loop. One owner per concern.
EPUB
→ Readium book rendering, positions, highlights, search
→ ReadingSessionService explicit session lifecycle ("这一段约 N 分钟")
→ Reflection + Evidence your words, saved first (locator / session / highlights)
→ Context Planning planner-grade plan: sources, dense/lexical split, budgets
→ Context Engineering deterministic: source retrieval → rank/dedup/budget → bundle
→ ReaderAgent grounded reply, locally verified citations, disclosure
→ Journal / Thoughts what survives the two minutes after the book
| Concern | Owner |
|---|---|
| EPUB / reading | ReaderCore + Readium |
| Session lifecycle | ReadingSessionCore |
| Reflection & evidence | ReflectionCore + Persistence |
| Local book retrieval | RetrievalCore — child retrieval (FTS5 trigram + BYOK semantic embeddings), RRF fusion, rerank gate, small-to-big expansion |
| Context planning | ContextRouting — planner-grade plan (dense/lexical split, retrieval knobs), proposed vs validated, deterministic fallback |
| Context engineering | ContextEngineering — candidate ranking/dedup/budget, ContextBundle, reflection/memory hybrid retrieval |
| Agent runtime | AgentRuntime / ReaderAgent |
| Voice | SpeechCore (system Speech, MP3/AAC) |
| AI polish | TranscriptPolishService (standalone, BYOK) |
| Providers | ModelProviders (one ModelClient contract) |
Sources/
ReaderCore / ReadingSessionCore / ReflectionCore domain
RetrievalCore child retrieval + small-to-big
ContextRouting / ContextEngineering planning + context assembly
ReaderAgent / AgentRuntime the thinking loop
ModelProviders / SpeechCore BYOK providers & voice
Persistence / LibraryCore / AppInfrastructure storage & app plumbing
App/ SwiftUI: Reader, Today, Thoughts (Journal), My Mind, Settings
Tests/ swift-testing (207 tests)
Contributions are welcome — from a repro for a reader edge case to the Memory phase.
| You care about… | Jump in on… |
|---|---|
| Reader reliability | Long-book performance, rotation, VoiceOver, background restore |
| The reflection loop | Journal structure, voice flow, polish quality |
| Grounded AI | Citation UX, session context, router transparency |
| Memory (next phase) | Evidence-backed personal context — not bolted onto ReflectionRepository |
| Docs & onboarding | The honest gaps in this README, build tips, screenshots |
swift test # portable suite
xcodegen generate && xcodebuild … # App-layer changesIn the description: user-visible behavior, layer touched, how you verified (portable tests vs device gate). Commits: Conventional Commits.
- Issues — bugs & ideas
- ⭐ Star the repo if Elsepage is your thinking reader — it helps the next person find it.
License file not yet published. Engineering codename: ReadLoop · App title: Reader · Product: Elsepage.
Swift 6 · Readium · local-first · made for the two minutes after the book
中文界面 · English docs for the global community
