Changelog¶
The canonical changelog is
CHANGELOG.md
in the repo root; it ships with every PyPI release. This page mirrors
its content for convenience.
Changelog¶
All notable changes to BookReader are documented in this file.
Format follows Keep a Changelog; the project adheres to Semantic Versioning.
1.0.0 — 2026-06-10¶
Stable 1.0. Same code surface as 0.4.0 — this release ships the polish pass that grew up around the project after the first PyPI upload.
Added¶
- README rewrite geared at first-time users —
pipx/uv tool/pip-in-venvinstall paths with a PEP 668 note, terminal × graphics- protocol compatibility matrix, Quick Start, Troubleshooting, and aWhy bookreader-tui?comparison vs Calibre /epy/mdcat. - mkdocs-material documentation site at
https://prajwalmahajan101.github.io/BookReader/ — auto-deployed on
every push to
mainthat touchesdocs/site/,mkdocs.yml, or the README/CHANGELOG. - Real screenshots — library, scroll-mode reader, and two-page
reader captured via a Textual SVG pilot
(
scripts/capture_screenshots.py); embedded in the README, PyPI long-description, and the docs site. SECURITY.md— vulnerability-reporting policy via GitHub Private Vulnerability Reporting.CONTRIBUTING.md— distilled commit / branching / architectural conventions for outside contributors.docs/demo.tape— vhs script for an animated README hero. Render withvhs docs/demo.tape(requiresvhs/ffmpeg/ttyd).- GitHub repo metadata — description, homepage URL, and topics
(
tui,textual,epub,kitty,sixel, …) so the project shows up in topical searches.
Changed¶
- Project name remains
bookreader-tuion PyPI; import path remainsbookreader. License remains Apache-2.0.
0.4.0 — 2026-06-10¶
First PyPI release as bookreader-tui. Bundles every change from
the post-0.3.0 cleanup waves plus the Phase 4 / 5.0 polish work.
Added¶
- Phase 4 — Library curation.
Copens a Collections overview (every book grouped by collection);Wopens a Wishlist overview with in-place removal viad. - Reader-side library actions.
ctoggles completion,CandWpush the collection / wishlist overviews from inside the reader — no more "quit to library first" round-trip. - Inline images in two-page mode.
PagedViewwas rewritten from Static-render to widget-mount: each spread isHorizontal[Vertical, Vertical]with mountedStatic+Imagewidgets per page. Images render at natural EPUB size withwidth: auto; max-width: 100%. - Auto-enable inline images in graphics-capable terminals
(
xterm-kitty, iTerm2, WezTerm). ExplicitBOOKREADER_IMAGES_ENABLEDstill wins. NewIkey toggles at runtime. - Configurable reading width.
BOOKREADER_READING_WIDTH(60–200) overrides the column max. Default raised 84 → 110. - Library UX polish. Empty-state hints when a filter has 0 books;
filter-aware status strip (
showing 0 of 1 · filter: Want to Read); sidebar + table get accent-coloured focus borders; book table has explicit column widths. - RepositoryError at the SQLite boundary so UI code can route
through the central
BookReaderErrorhandler. - Lowercase
whint on the library — instead of silently doing nothing, surfaces "Press Shift+W to open the wishlist". - Dark theme contrast — Tokyo-Night-adjacent palette replaces the muted Catppuccin Mocha values (brighter foreground, punchier accent).
Ctrl+Ptheme picker scoped to bookreader-* — the 20+ Textual built-in themes no longer pollute the picker.- CI on every push / PR — ruff format + check, mypy --strict, pytest across Python 3.11 and 3.12.
Fixed¶
- Bare
except Exceptionin UI handlers replaced withexcept BookReaderError; programming bugs (KeyError, AttributeError) no longer get silently rendered as "Add failed" notifications. qtyped inside a modalInputcan no longer quit the app (verified with a pilot regression test).Ttheme cycle now snaps back to the bookreader theme set after the user picks a Textual built-in via the palette.- Inline
Imagewidget no longer eats all vertical space — explicitheight: autokeeps the text below the figure visible. PagedViewre-renders use class selectors instead of static IDs; the asyncremove_children()race no longer raisesDuplicateIdson resize / chapter jump (regression test added).
Changed¶
- Versioning:
__version__andpyproject.tomlbumped 0.1.0 → 0.4.0 (matches the actual shipped surface — Phase 4 was onmainlong before the version field caught up). - PyPI package name:
bookreader-tui(the barebookreadername was already taken). The Python import path is stillbookreader. - License declaration in
pyproject.tomlcorrected fromMITtoApache-2.0to match the actual LICENSE file.
0.3.0 — 2026-04-05¶
Phase 3 — Polish.
Added¶
- Phantom (wishlist) books. Add a TBR entry by title + author with
no file (
bookreader add --wishlist --title "T" --author "A"); promote withbookreader attach <id> path.epub. - Bookmarks.
madds a bookmark with optional note;'lists bookmarks for the current book, Enter jumps. - Reading-session stats. Per-book minutes-read accrue
automatically;
bookreader statsprints totals; library "Time" column shows running totals. - Inline images.
BOOKREADER_IMAGES_ENABLED=1enables kitty / iTerm / sixel rendering viatextual-image; otherwise figures fall back to[image: alt]placeholders. - ADR-0004 records the Phase 3 data-model decisions.
0.2.2 — 2026-03-15¶
Fixed¶
- Two-page reading column widened from 84 → 140 cells so each page carries ~68 cells of prose instead of the squeezed ~40 each.
0.2.1 — 2026-03-12¶
Added / Changed¶
- Migrated to Textual's first-class theme system (
App.register_theme) so the command palette, header, footer, and notifications all adapt with the bookreader themes. ADR-0003 records the migration.
Fixed¶
- Two-column pagination produced visibly unequal column widths because the math ignored Rich's grid padding. Now stitches columns line-by-line with exact widths.
0.2.0 — 2026-03-05¶
Phase 2 — Library.
Added¶
- SQLite library with
books,collections,bookmarks,positions, andbook_collectionstables. Hand-rolled migrations underlibrary/migrations/. bookreader(no args) lands on the library home screen.bookreader open <path>keeps the Phase-1 reader flow.- CLI subcommands:
add,list. LibraryServicemediates between UI and repositories. Position saves mirror through the service to the DB.- One-shot migration: Phase-1
positions.jsonentries that match books in the library are imported, then the JSON is renamed. - ADR-0002 records the Phase 2 schema and layering decisions.
0.1.1 — 2026-02-22¶
Added¶
- Two-page reading mode toggled with
2. Wraps the chapter into two side-by-side columns;space/badvance one spread.
0.1.0 — 2026-02-15¶
Initial release. Phase 1 — Reader Core.
Added¶
- EPUB parsing + chapter iteration via
ebooklib+beautifulsoup4. - Textual reader screen: TOC sidebar, centered ≤ 84-cell reading column, status bar with chapter progress.
- Keyboard navigation:
j/kscroll,space/bpage,n/pchapter,tTOC,g/Gtop/bottom,Ttheme,?help,qquit. - Auto-flow into next/prev chapter at boundaries.
- Three themes (dark, light, sepia) with focus-tinted borders.
- Position persistence keyed by EPUB
dc:identifier(JSON store). - 12 unit tests; ruff clean; mypy strict.
- ADR-0001 records the stack choice (Textual + ebooklib + SQLite).