v2.1.0 "Palimpsest"
A palimpsest is a manuscript page scraped clean and written over - the older
text still faintly visible underneath. That is this release: your reading
history stops being an append-only artifact and becomes something you can
inspect, correct, and rewrite - while nothing is ever silently lost.
Highlights
Your KOReader history is now part of the session log. Reading synced from
KOReader's statistics - including everything from before Tome existed - used
to count toward your totals but never appear anywhere: a book could claim
"1 session" over an empty list, and an accidental open was stuck in your
timeline forever. Imported reading now shows up as individual sittings in
Recent Sessions and on every book page, grouped the way KOReader itself
thinks about sessions, each deletable on its own - even a 7-second
accidental page flip. A small info icon next to every session list explains
the labels in place, and nothing is ever counted twice: on books with
imported history, the plugin's duplicate live sessions stay visible with a
"not counted" tag instead of quietly disappearing.
Click a day, fix a day. Every bar in a book's Activity chart is now a
button: it opens that day's sittings with the same trim and delete actions,
so removing one stray entry no longer means scrolling the full session log.
Runaway sessions are over. A device that never actually slept - a cover
that failed to suspend it, a reader who fell asleep mid-chapter - used to
book the whole night as reading (#150). The plugin now counts active reading
the way KOReader's own statistics do, with a configurable idle cap per page
turn. For sessions already on the books, there's trim: a scissors button
that shortens a session to what you actually read, pre-filled with a
suggestion computed from that session's page turns at your own reading pace.
Implausible sessions are flagged, and arriving runaways from older plugin
builds raise a notification instead of silently distorting your numbers.
History lands on the right volume - and heals itself. Imported history
could confidently attach a missing volume's entire reading log to a sibling
volume (#152): hours of sessions on a book never opened. The matcher now
treats volume numbers as authoritative, and on your first start after
upgrading, a one-time repair re-verifies every stored match under the fixed
rules - ghost data is removed, the device re-syncs clean history on its next
connection, and a notification tells you if anything was fixed. Books mixing
wrong and genuine history are deliberately left untouched and flagged; a new
per-book "clear imported history" action is the manual escape hatch.
KOSync clients pick up your Tome position. The KOSync-compatible endpoint
(stock KOReader sync, Readest, and friends) used to be an island. Now the
sync pull answers with the newer of the two positions - the client's own last
push or Tome's (web reader or TomeSync device) - and documents auto-link to
their books by file hash, no OPDS heuristic required. A "Link KOReader sync"
picker on the book page covers the rest. Pushes remain deliberately isolated:
a KOSync client never moves positions on devices running the TomeSync plugin.
Thanks @sn0opy for the request and the hash-parity verification (#156).
KOReader plugin
This release ships plugin build 37 (1.11.0) - one build since 2.0.0:
idle-capped session accounting (configurable in TomeSync settings, including
off).
Upgrade note: the plugin updates gracefully in-app - TomeSync → Settings →
"Check for updates" (or enable auto-check). No breaking changes; existing
installs keep working untouched until you update.
Upgrade
docker pull ghcr.io/bndct-devops/tome:latest && docker compose up -d
No migrations, no config changes, no new env vars. One one-time behavior: on
the first start after upgrading, the server re-verifies imported KOReader
history matches (see Highlights) - it runs in the background, is idempotent,
and notifies you only if it changed anything.
Full changelog
Added
- KOSync clients now pick up your Tome reading position (#156). The
KOSync-compatible endpoint (stock KOReader sync, Readest, and friends)
used to be an island: it only ever served what a KOSync client itself had
pushed, so progress from the web reader never reached those apps. The sync
pull now answers with the newer of the two - the last KOSync push or
Tome's own position (web reader or TomeSync device) - at percentage
precision, since KOSync locators and web CFIs aren't convertible. The
bridge is strictly read-only: KOSync pushes still never move positions on
devices running the TomeSync plugin. - KOSync documents auto-link by file hash. Linking a synced document to
its Tome book no longer depends on the OPDS-download heuristic: any file
that came from Tome is recognised by its KOReader partial-MD5 and linked
automatically on the first push or pull. The OPDS heuristic remains as a
fallback for files Tome has never seen. - Manual sync linking in the UI. When a KOSync client has synced a
document that isn't attached to any book, the book page offers a small
"Link KOReader sync" picker - no more calling the API by hand. - Imported KOReader history shows up as sessions - and single sittings can
be deleted. Reading synced from KOReader's statistics (including history
from before Tome existed) used to count toward the totals but never appear
in Recent Sessions or the per-book session list, so a book could claim "1
session" over an empty list and an accidental open was impossible to remove
without wiping the book's whole imported history. The session lists now
include imported sittings (marked "imported", grouped the same way KOReader
groups sessions), each deletable on its own; the book page's session count
matches the sittings that count. Imported sittings can't be trimmed -
KOReader's own idle-capping already applies. On books with imported
history, the plugin's live device sessions describe the same reading a
second time, so they are excluded from the totals - but they stay in the
list with a "not counted" label rather than disappearing. An info popover
next to the session lists explains all of this in place. - Click a day in the book page's Activity chart to manage that day's
sessions. Each bar opens a popup with the sittings that started on that
day - trim or delete right there instead of scrolling the full session
log to find the one stray entry. - The Habits tab's session timeline now draws imported KOReader sittings
too, so device reading on stats-synced books appears in the ribbon
instead of leaving those days blank. The superseded live device sessions
are left out of the drawing - the same reading would otherwise paint
twice. - Clear imported history per book. The Reading intensity panel on a book
page grows a small trash action that removes the current user's imported
KOReader page data for that book - the manual escape hatch for mixed cases
the automatic repair deliberately leaves alone. Web and manual sessions are
unaffected, and reading the book on a device again re-imports from there on. - Runaway reading sessions are over (KOReader plugin, build 37). A device
that never actually sleeps - a cover that fails to suspend it, or a reader
who fell asleep mid-chapter - used to book the whole wall-clock span as
reading, turning a 15-minute evening into an 8-hour session (#150). The
plugin now counts active reading the way KOReader's own statistics do:
each gap between page turns is credited at most an idle cap (10 minutes by
default, configurable in TomeSync settings, including off), and the session
ends at the last page turn rather than whenever the device finally slept. - Trim a session instead of deleting it. Sessions that idled - real
reading followed by hours of nothing - can now be shortened from the
Recent Sessions list: a scissors button opens a small editor, pre-filled
with a suggested duration computed from the session's page turns at your
own median reading pace, so the reading stays and the idle tail goes.
Suspicious sessions (implausibly long, or minutes per page turn) are
marked with a warning icon and the list can sort longest-first. The same
session list lives in two more places: the per-book time table on the
Library stats tab expands per book, and every book page grows a
collapsible "Sessions" section under Reading Stats - so sessions stay
editable even on a stats dashboard with those tiles removed. - A heads-up when a runaway session syncs. Sessions arriving from older
plugin builds still get sanity-checked on the server: an implausibly long
one raises a bell notification pointing at Reading Stats, so a bad night
never silently distorts your numbers.
Fixed
- A seconds-long accidental open synced from KOReader history now shows up
in the session lists and the Activity day popup so it can be deleted.
Such blips are below the noise floor for session counting (a 7-second
page flip is not a sitting) and were filtered out of the lists entirely -
but their seconds still drew an Activity bar and set "last read", so the
one entry people most want to remove was the one entry that never
appeared, and its day popup claimed "No sessions recorded". - KOSync progress pushes now follow the same read-status rules as every
other sync path: finishing requires 99% (was 95%), completion is sticky
(a re-read no longer drags a finished book back to "reading"), and the
finish date is recorded. - Imported KOReader reading history can no longer land on the wrong volume of
a series (#152). When a volume read on the device was missing from the Tome
library, the history importer's title matching could confidently attribute
its entire reading log to a sibling volume - hours of sessions and page
data on a book never opened. The matcher now treats a parsed volume number
as authoritative: a candidate claiming a different volume is never matched,
half-volumes (2.5) resolve exactly instead of truncating, and French-style
"T2" tome numbering is understood. History for a volume Tome doesn't own is
parked until the book exists rather than guessed onto a lookalike. - On update, previously mis-imported history heals itself: stored matches are
re-verified against the fixed rules on startup, ghost page data whose book
has no other import source is removed, the device re-syncs its history on
the next connection, and a notification explains what happened. Books where
wrong and genuine history are mixed are left untouched and flagged instead. - Chart tooltips on Reading Stats no longer detach from the cursor or hide
behind neighbouring tiles (#151). The activity heatmap, the hour-by-day
heatmap, and the timeline ribbon all rendered their hover tooltip inside
the dashboard tile, where the grid's CSS transform re-anchored it and
clipped it under adjacent cards; tooltips now render at the document root
and follow the mouse everywhere.