title: Changelog
built: 2026-10-30
source: api/CHANGELOG.md
html: https://insurgently.com/projects/library-hub/technical/agents/CHANGELOGIndex of these files: llms.txt
Changes to Library Hub's API, by version. Within 0.x the API only adds and deprecates, and removes at 1.0; a change in behavior is marked.
0.9.0
Served by Library Hub 0.1.0 and later; the first version published as a package (0.8.0 was never published). Everything new is an addition, except the changes marked below.
listBooks('all'): every book in Calibre, by id.BookSummary.context: what the book is about, as plain text, from the note'scontextfield, else Calibre's comments.BookChapters.outline(and soBookText.outline): whether the chapters follow the book's own structure, an EPUB's files or a PDF's outline. False for a PDF cut into even parts. Before, only the warning text said so.- Changed:
bookTextandbookChaptersgive every chapter of an EPUB: past 30 they're no longer merged into their parts (the chapter notes still merge them, andopenBook'schapternumber counts the notes' chapters, so open a chapter at itslocation). A file several contents entries point into is split at their anchors, each such chapter locatedfile#anchor; a file no entry claims, with more than a page heading's text, is a chapter of its own; and contents entries are found when the NCX sits in another folder than the OPF. These chapter rules don't change the whole text (reading it with foliate-js, below, does, once). - Changed:
bookTextandbookChaptersread EPUB, AZW3 and MOBI files with foliate-js, the parser Library Hub's reader already shows them with, instead of Library Hub's own EPUB reading. An EPUB's contents come from its nav document or its NCX, as foliate-js gives them; HTML entities in a contents file no longer lose the contents. The whole text keeps its paragraphs and blocks as blank lines, and a line break (<br>) is now a single line break; spaces next to a paragraph break are gone and every HTML entity is decoded. So every EPUB'shashchanges once, and offsets may move a little; a corpus re-reads the passages whose words changed. - Changed: a book with only an AZW3 or MOBI has its text read from that file as it is, with no conversion, with or without the Content Server:
formatisAZW3orMOBI(BookChapters.formattakes those two), and each chapter'slocationis the reader's own (kindle:pos:…,filepos:…, or a section'sepubcfi(…)), whichopenBookopens.needs-conversionand{ convert: true }now only matter for an AZW3 or MOBI that can't be read (DRM, a damaged file), and the message names the cause.openBookopens a book's AZW3 or MOBI when it has no EPUB, before its PDF.bookFile(book, 'EPUB', { convert: true })still asks Calibre to make an EPUB. - Changed: with Calibre's Content Server off and a library folder set,
bookFile,pdfText,bookTextandbookChaptersread a Calibre book's files straight from the library folder, read-only, instead of rejecting withserver-off. Converting an AZW3 or MOBI still needs the server:bookFilewith{ convert: true }rejects withserver-off, andbookText/bookChaptersreject withneeds-conversionwhen the book has a PDF (withconvert, the PDF is read, with a warning) and withserver-offwhen it has none. A file in a cloud-synced folder that isn't downloaded on this computer, or takes too long to download, rejects withserver-errornaming the file; a library file caught while Calibre is writing it is read again a few times, then rejects withbusy.status().calibrein file mode now hasfiles: trueand says files and text are read from the library folder. - Changed:
openBookat aquote, and a highlight finding its text again, match through@insurgently/text'sfold: decomposed and precomposed accents, curly and straight quotes and apostrophes (with ʼ, ʻ, backticks and guillemets), soft hyphens, zero-width characters, Greek final sigma, Turkish İ, German ß, and hyphenated, closed or line-split words (well-known,well-\nknown,wellknown, OCR's¬) now match each other; a quote never matches half a letter. Whitespace and quote marks are still ignored altogether.summarizeBook's chapter notes keep a quote found word for word by the same rules, so a quote a model typed with straight quotes is no longer dropped. - Changed: with Model Hub 0.13 or later,
estimateSummaryandestimateShelfFromDescriptionare priced by Model Hub'sestimate(), each call as it would be sent with its reply cap:usdis the high end of its range (every call with a full reply), andtextgives the range, "about $0.02–$0.09". When Model Hub can't price a call,usdis null andtextsays why. With Model Hub 0.12, both work as before: the input at the role's first model's listed price.
0.8.0
Never published as a package on its own: it ships inside 0.9.0.
bookText(book, { convert? })andbookChapters(book, { convert? }): a book's text as chapters. Each chapter hasn,title, alocationthatopenBooklands on (OEBPS/c3.xhtmlin an EPUB,chars a-bin a PDF),startandendin code points, and (frombookText) itstext. A SHA-256hashof the whole text changes only when the text does. EPUBs, AZW3 and MOBI through Calibre's conversion (asked first), and PDFs laid out, with their outline as chapters.status(): whether Calibre's Content Server and the other providers answer, and what the library holds.- A
BookRefwherever a book is named:listBooks,bookFile,pdfText,shelvesOf,addToShelf,removeFromShelf,createShelf'sbooks,suggestShelves,estimateSummary,summarizeBook. Numbers work as before.bookFileandpdfTextalso read a book file in the vault. - New error codes:
needs-conversion,declined,not-calibre,busy. hasMethod(api, name), andgetLibraryHub'sopts.byandopts.forto name your plugin, and what it needs books for, in its messages.LIBRARY_HUB_TOOLSis also at@insurgently/library-hub-api/tools. Import it from there: at the root it's deprecated, and goes at 1.0.- New error code
needs-topic-map: the call works from what books are about (book vectors), which Library Hub no longer keeps; the Topic Map plugin serves it. - Changed:
suggestShelvesis served by Topic Map: with Topic Map'srankGroupsit ranks the shelves by what the book and their books are about (scoreandmatchare Topic Map's score,becausesays it in words); without Topic Map, or with one that doesn't offerrankGroupsyet, it rejects withneeds-topic-mapafter checking its arguments, and withno-vectorswhen Topic Map hasn't indexed the book. Thelibrary-hub.suggest_shelvestool is offered to Model Hub only while Topic Map serves it. - Changed:
shelfFromDescriptionandestimateShelfFromDescriptionfind the books to read by their words: those that best match the description and its terms (title, authors and context, by a keyword ranking), and any naming a term. Before, the books nearest it by meaning. Neither rejects withno-vectors. With Topic Map'srankGroupsthere, the books it finds closest to the description in meaning are read too (Topic Map embeds the description); without it, no embedding is asked. - Changed: the shelf keys have new names. A shelf note's id is
shelf_id(wascollection_id); a book note's shelves are inshelvesand its exclusions inshelves_exclude(werecollectionsandcollections_exclude);clustersandauto_shelvesare gone, and rule shelves with them: the plugin moves old notes once, putting every book a rule shelf held inshelves.listShelves,shelfMembers,shelvesOfand the write operations name shelves byshelf_idas before and keep the keys to themselves; a plugin that reads book notes' frontmatter itself reads the new keys. - Changed:
shelfBaseQuerygiveslist(shelves).contains(…)and theshelves_excludetest, with no rule and no older keys. - Changed:
createShelfwith arulerejects withneeds-topic-map.NewShelf.ruleandShelfInfo.ruleare deprecated (ruleis never set), until 1.0. - Changed:
no-vectorsnow means Topic Map hasn't indexed the library, or the book, yet. - Changed:
pdfTextlays the page out: a line on its own line, a wider gap a blank line, a word broken at a line's end joined. Before, a page's pieces were joined by spaces.chars a-boffsets count in the new text. - The names from before the rename (
getBooks,onBooksReady,BooksApi,BooksErrorCode,BooksTool,GetBooksResultand theBOOKS_*constants) still work, deprecated. Within 0.x the API only adds and deprecates; they go at 1.0.
0.7.0 and before
Not published as a package. Plugins copied api/index.ts from the repo; the plugin's own CHANGELOG lists what each version added.