Skip to content

Releases: Einstellung/Reading-Partner

v0.8.0 — Reading Partner on your phone

Choose a tag to compare

@github-actions github-actions released this 30 Jul 00:38

Reading Partner runs on a phone. It is not the desktop app squeezed narrow — it is a second shell that carries today's briefing, the articles you kept, and a chat about either, and carries nothing else. No reader, no PDF, no marking: those stay where a large screen and a stylus are. Navigation is a stack you swipe out of from the left edge, and pulling down on the briefing or an article opens its chat. Underneath, two things that only mattered once a second device existed got fixed: a phone no longer downloads a library it cannot open, and sync now runs the moment the app comes back instead of on a timer that a locked phone stops. Sync also stopped picking a winner when two devices edited the same file — it merges them, record by record. And every AI turn is now sized against the model's context window before it is sent, so a long book answers or says why it cannot, rather than failing as if the network were down.

New

  • The phone shell. Below the sm breakpoint with a coarse pointer the app mounts a different shell: a launch screen with today's briefing above the articles you have kept, the briefing and article screens, the kept list, and the chat. It holds no reading state and never loads the PDF engine, so the phone bundle is a fraction of the desktop one. The form factor is decided from the screen's shorter side and the pointer type, never from the operating system, and ?shell=phone forces it for development on a desktop.
  • Back, three ways, one definition. The phone keeps a navigation stack; back is a pop. Swiping in from the left edge follows your finger and commits past a third of the screen, the Android system back button is the same action, and a chat that is open closes before anything navigates.
  • Pull down to ask. On the briefing or an article, pulling down from the top grows a band with a labelled pill — "Ask about today's briefing", "Ask about this article" — that turns solid past the threshold. Release and the chat for that content opens. It is not pull-to-refresh: nothing regenerates, and speed alone never commits, because a fast downward flick is what arriving at the top looks like.
  • Keep an article under a topic. The star on a briefing card files the article into a topic, stripped of inlined images and sanitised, with its publication date and whether only a summary was available. The topic page lists what you kept and opens it for reading. Identity is the article's URL, so keeping it again updates rather than duplicates.
  • A briefing run survives being interrupted. Collection now checkpoints after every source, so a run cut off by a phone going to sleep, or by the system reclaiming the app, resumes on the next launch and fetches only the sources still outstanding — the expensive half is never repeated. Only the same day's run resumes; anything older is discarded. The screen is held awake while a run is in flight.
  • Two devices that edited the same file both keep their edits. Sync merges instead of choosing: records are matched by id and merged individually, prose files line by line, settings field by field, against the last state both sides agreed on. What a merge drops is kept locally for thirty days.
  • Every AI turn is measured against the model's context window before it is sent, and reduced to fit — history first, then the material. A turn that still will not fit says so in a sentence about the reading rather than a sentence about tokens, and a run that spends its whole round budget looking things up says that instead of failing silently.

Changed

  • Sync runs on the app's lifecycle, not only on a clock. Coming back to the front runs a full pass immediately; leaving pushes whatever is not yet uploaded. The five-minute timer remains as a backstop, but it never ran on a phone in your pocket.
  • A phone does not mirror the book library. The books channel is off there — no download, no upload — while library.json still syncs, so the phone knows what exists without storing hundreds of megabytes it has no way to open.
  • Change detection is by content, not by clock. A file that was rewritten with the same bytes is unchanged, so a device that merely re-saved no longer wins the file.
  • Each file on Drive carries its own revision in its metadata, and the remote state comes from one directory listing. manifest.json is no longer maintained, only read once to migrate older devices.
  • A book uploads in 1 MB chunks instead of one request for the whole file, so a slow or lossy connection makes progress rather than starting over.
  • Only models with a 1M-token context window are offered.
  • The trace list drops the star; a row is deleted by swiping it.
  • Reaching for a colour reaches for the pen: picking a colour selects the marking tool with it.
  • Past days' derived briefing files are deleted when a new briefing generates. One article cache measured 4.3 MB; conversations are untouched.
  • The microphone appears only where something can record. Voice input is a desktop feature and stays one — a phone keyboard already dictates, and better.

Fixes

  • A phone launched in landscape is still a phone. The shell is chosen once at mount, and measuring width alone put a phone held sideways into the desktop shell for the rest of the session.
  • Paged mode saves the page you are looking at, not the one at the edge of the viewport, and opening a book in paged mode lands on one whole page. Switching to vertical keeps the page you were on, and a rotation settles the way a layout switch does.
  • Opening a book never flashes page 1 on the way to where you were.
  • A book that will not open says so instead of showing an empty reader.
  • A finished stroke no longer selects the mark it just drew, and switching tools no longer opens the annotation editor.
  • The colour palette leaves the band that scrolls the tool rack, so scrolling the rack no longer drags the palette with it.
  • One unreadable or rejected file no longer stops the whole sync pass; a cached Drive id that has gone missing heals instead of poisoning every later pass; a manifest that failed to download no longer reads as an empty remote and wipes local data; a device that has never synced is told that rather than shown an invented date; a stopped sync reads as stopped rather than as broken.
  • A token refresh cannot hang forever, and the watchdog stops retrying failures that cannot improve — a refusal is answered once, not four times.
  • A tap that lands on a button it cannot focus no longer cancels a pending delete.

Internal

  • App.tsx gave up four more responsibilities: lesson prep, book notes, the settings cards, and the info call's React-free half. The phone shell reuses the info screens rather than copying them; the briefing card is one component both launch screens mount.
  • The gestures are state machines in plain TypeScript with unit tests, apart from the DOM: the edge-back machine, the pull-to-ask machine, the navigation stack, the shell choice, the call layout.
  • Two measured surprises are written down. A window that merely loses focus fires no visibilitychange, so "in front of the user" has to be tracked as a state across four events. And the threshold at which a browser hands a touch to a scroll container is not a distance you can tune — it withholds the first move until its own slop is passed, so a gesture must claim the very first move it is given.
  • The pitfall index is grouped by subject with a lookup table at the top, so a change to one area scans one group instead of the whole list. Seven entries whose code no longer exists were deleted and the engine-migration leftovers marked historical.
  • Handwriting was removed from the roadmap; the strategic decision against ink annotation was already on the record and the roadmap entry contradicted it.

v0.7.0 — Touch reading, paged flip, safer data writes

Choose a tag to compare

@Einstellung Einstellung released this 25 Jul 11:06

This release is mostly touch. A finger now scrolls the page with momentum and a rubber band at either end, a stylus marks it, and which one does what is a setting rather than a guess. The reader's chrome was rebuilt around that: a three-section top bar with the low-frequency controls behind a More menu, the side panel as an overlay drawer, and the first button in the tool rack turned into a navigation lock. Paged horizontal flip is a new opt-in layout and the two-page spread is gone. Underneath, data files are written atomically and a token-refresh race that signed you out mid-session is fixed.

New

  • Finger scrolling with momentum. A drag follows the finger, a flick coasts and settles, pushing past either end stretches and springs back, and a finger landing on moving content picks it up where it is. A thin indicator fades in while the page moves and out when it stops, so a long book gives some sense of position.
  • Draw with your finger, in Settings under Reader input. Off by default: the finger only moves the page and the stylus does the marking, whatever tool is selected. Turn it on for a device with no stylus.
  • Navigate only, in the tool rack: a latch rather than a tool. While it is down every pointer, stylus included, only moves the page, and nothing draws or selects. Press it again for the ordinary mode where the stylus marks and the finger scrolls.
  • Paged flip, an opt-in layout in the More menu: one whole page per screen, in either orientation. A horizontal swipe turns the page and follows the finger; a vertical swipe, or a swipe past the first or last page, bands and springs back. A pinch magnifies to read detail and pans; the next turn comes back to fit-page. The choice persists per book.
  • Sign in with a code, on the Claude and ChatGPT cards. ChatGPT runs the device-code flow (user code, verification link, polling, cancel, with a paste-the-URL fallback), Claude the paste-the-code flow. Neither needs a local callback listener; the usual browser sign-in stays the primary button on desktop.
  • Touch sizing throughout: 44px hit areas under a coarse pointer, hover-only controls that stay visible where there is no hover, safe-area insets, and a chat composer that rises above the soft keyboard. The home, briefing and reading call surfaces have narrow-screen layouts. All of it inert on desktop.
  • An iPad build, not on this page: CI now produces a sideloadable .ipa with an install manual, and the TestFlight workflow was brought up to match it. This release page carries the Linux, macOS and Windows builds.

Changed

  • The reader top bar is three sections: drawer and library on the left, the annotation tools and page indicator in the middle, the AI thread entry and a More overflow on the right. Zoom, fit width, paged flip and settings moved into More, every icon shares one neutral line style, and the open book's title is no longer repeated in the bar.
  • The reader's side panel is a left overlay drawer, closed by default, opened from the top bar and dismissed by a backdrop tap or Esc. Its toggle carries a status dot while prep or note generation runs, so background progress is visible with the drawer shut. The five tabs moved into a row along the drawer's top.
  • The two-page spread is gone; the reader lays out one page per row. Reading positions saved with it still open.

Fixes

  • Data files are written atomically — a temp file in the same directory, fsynced, renamed over the target — so a process killed mid-write can no longer leave a half file that the next save makes permanent. An unreadable library or settings file is quarantined and reported instead of being silently replaced by an empty shelf or default settings.
  • An expired AI token is refreshed once rather than once per running pipeline. Both providers rotate the refresh token, so the losing refreshes came back invalid_grant and signed you out mid-session. Credential writes are serialized as well: a refresh no longer writes back a snapshot taken before you saved an API key.
  • Marks pulled from another device survive. A sync pull now drops the book's cached annotations; before, the next mark made here wrote the stale cache back over them.
  • A book opens with no tool selected, so the previous book's pen no longer marks the page the moment a finger lands on it.
  • Signing in to Claude by pasting a code opens the page that actually displays the code.
  • The reader top bar no longer pushes the page wider than a phone viewport, and the reading call bubble fits a narrow screen.
  • On an iPad the app asks the system what platform it is on instead of trusting a user-agent string that claims to be a Mac.

Internal

  • src/ is regrouped by layer — platform, ai, memory, fulltext, reading, info, ui — and a test walks every import to enforce the dependency direction. Five directory cycles that had accumulated under convention alone are gone.
  • The touch logic is pure and unit-tested apart from the DOM: the table that decides draw versus scroll, the vertical scroll and fling machine, the rubber band, and the paged flip machine.
  • Duplicated code merged: model resolution across five wirings, the PKCE helpers, the pipeline observable shell, the streaming tool-trace reducer, the shared button classes. App.tsx handed off the library screen, the info home, the reader top bar and reading-turn assembly.

v0.6.1 — Delete conversations, toolbar polish

Choose a tag to compare

@github-actions github-actions released this 23 Jul 11:17

A small follow-up to v0.6.0.

New

  • Delete a conversation: reading-side chat threads now have a delete button in the chat header — two-step inline confirm, and deleting a highlight-anchored thread removes the highlight with it. Deletions sync across devices.

Changed

  • The AI pen's active state now matches the other tools in the pen toolbar (same size, light tint), and the color well stays in place as a disabled slot for tools without a color — the toolbar no longer shifts when switching tools.
  • The README now documents the briefing side in full: triage tiers, subscribing by conversation, and the briefing companion.

License

  • Starting with this release the project is licensed under PolyForm Noncommercial 1.0.0 (free for personal use and academic research; commercial use requires a separate license). Releases up to v0.6.0 remain AGPL-3.0.

v0.6.0 — Subscribe to your own sources

Choose a tag to compare

@github-actions github-actions released this 23 Jul 09:56

The daily briefing is now yours to shape. Instead of a fixed pair of sources, you subscribe to whatever you follow by talking to the AI: name an outlet or paste a link, it probes for a feed, trials three articles, and subscribes once you confirm — no built-in defaults, so first run opens with a guided conversation to help you add your first few. Every briefing carries a companion chat: ask what came in today, get per-source or filtered breakdowns, refine the reading profile that steers triage, and regenerate or re-triage the day's briefing without leaving the conversation. Alongside it: Sign in with ChatGPT, one shared reading profile across briefing and books, and a new app icon.

New

  • Subscribe to your own sources: chat with the AI to add any site — it probes for a feed, trials three articles, and subscribes only after you confirm. Each source is a small declarative JSON descriptor the AI writes and proves by actually fetching, so it can connect a site with no obvious feed. There are no built-in sources; the first run starts a guided conversation to seed them.
  • Briefing companion: every briefing has a chat. Ask about today's items, get per-source or filtered-out breakdowns, and voice a standing preference to update your reading profile (four sections, applied from a confirm card). Ask it to redo the briefing and it re-triages today's items against the updated profile, or re-collects every source from scratch — a progress card tracks the run.
  • Cross-scenario reading profile: one user-profile.md — interests, taste, background, what you're reading now — shared by the briefing's triage and the reading companion. What you have open and the questions you got stuck on feed into how relevant the briefing judges each item. Nothing is preset; the AI drafts it only from what you actually say.
  • Sign in with ChatGPT: OpenAI now authenticates through your ChatGPT subscription over OAuth, the same as Claude — no API key. One provider is active at a time; connecting one signs the others out.
  • New app icon.

Fixes

  • The briefing is written in your configured AI output language.
  • Lazy-loaded article images are no longer stripped during extraction, so they render in-app.
  • Article and briefing toolbars stay sticky while you scroll.
  • A briefing progress card tracks generation and reports the result.

v0.5.0 — Daily AI briefing, voice input, slides, auto notes

Choose a tag to compare

@github-actions github-actions released this 21 Jul 13:38

Reading Partner now opens to a daily AI briefing. Instead of a blank start, the Today home greets you with cards to continue the book you were reading and a triaged rundown of the day's AI news: the AI reads 机器之心 and 量子位 in full, weighs every item against a profile of what you care about — seeded automatically, taught by your reactions — and sorts them into worth-reading (each with a one-line reason it's for you), one-liners, and filtered-out (appealable when it gets one wrong). Read articles in-app with their images, chat about any item, and your open/dismiss/appeal actions teach the next day's triage. Alongside it: voice input everywhere, slide decks from your notes, and notes that write themselves as you read.

New

  • Daily AI briefing: a Today home with continue-reading cards and a personalized news briefing. Sources in this release are 机器之心 and 量子位, read in full and triaged against your profile. Feedback (open, dismiss, appeal) feeds future triage; profile and feedback sync across devices.
  • Voice input: a push-to-talk mic on every chat composer. Recording runs in Rust, speech-to-text goes through any OpenAI-compatible endpoint, and an LLM pass cleans up the transcript. Defaults to SiliconFlow's free SenseVoice tier — add a SiliconFlow key in Settings to use it.
  • Slides from notes: turn your book notes into a self-contained HTML slide deck for a talk, across multiple books, with optional AI-drawn illustrations. Opens in any browser with everything inlined.
  • Highlight-driven auto notes: chapters distill into notes as your highlights advance past them, chapters you never marked are skipped, and a final pass runs when you close the book. The notes overview is part of the context each conversation opens with.
  • AI output language setting: nine languages, or match the book.
  • Classroom toggle is remembered per book.

Fixes

  • Article images inline as data URLs so they render under the app's CSP/COEP.
  • Figure cards render block-centered.
  • Chat-endorsed explanations get absorbed into chapter notes.

Reading Partner v0.4.0

Choose a tag to compare

@github-actions github-actions released this 19 Jul 03:29

Your library now follows you across machines, and every book can hand you a set of lecture notes on demand.

Sync across devices

Sign in with Google in Settings and your reading moves with you — backend-free, no accounts on our side.

  • Everything syncs: books (the PDFs themselves), reading positions, marks and highlights, conversations, and notes.
  • Storage is your own Google Drive, in a visible "Reading Partner" folder you can open and inspect. Your data stays in your Drive.
  • Uses the drive.file scope: the app only ever sees the files it created.
  • Books are content-addressed, so the same PDF opened on two devices lines up.
  • Auto-sync is on by default after sign-in; a manual toggle and a Sync now button live in Settings. Per-file last-writer-wins.
  • AI provider credentials never sync — they stay on the device.

Whole-book notes

A new Notes tab in the sidebar generates chapter-by-chapter lecture notes for the whole book in one click.

  • Chapter plan from the PDF outline, or the model reads the table of contents when there is none.
  • Notes carry [p.N] and [fig:N] anchors that jump into the book.
  • Regenerate any chapter on its own, with an optional instruction to steer it.
  • Your highlights and conversations steer how deep each chapter's note goes, and explanations you endorsed in chat get absorbed into the note.

Building from source

Drive sync needs your own Google OAuth Desktop client. Copy .env.example to .env and set VITE_GOOGLE_CLIENT_ID / VITE_GOOGLE_CLIENT_SECRET. Without it the app runs fine, with sync disabled.

Reading Partner v0.3.0

Choose a tag to compare

@github-actions github-actions released this 18 Jul 07:07
Reading Partner 0.3.0

EmbedPDF is the only reading engine (AGPL-free codebase). Classroom mode
with an AI-built lesson-prep pipeline (arXiv / OpenAlex / Semantic Scholar).
Per-topic memory with silent distillation and an opening snapshot. Figure
cards and view_figure vision tool. Quote-anchored page citations with
transient highlights. Book-level AI thread from the top bar. Paste a URL in
chat to ingest papers and articles. Adaptive thinking levels. iOS/TestFlight
pipeline prepared.

Reading Partner v0.2.0

Choose a tag to compare

@github-actions github-actions released this 16 Jul 12:25
Reading-engine layer refactor: an EmbedPDF engine adapter now lands on main.

- EmbedPDF engine adapter for PDF, experimental and behind the VITE_ENGINE=embedpdf flag; the default engine remains zotero/reader.
- Performance fixes: tile-based zoom rendering, engine subtree isolation to contain popup re-renders, and load-time pass (engine singleton, trimmed render buffer).
- New pitfall docs and EmbedPDF replacement research under docs/.