---
title: "Library Hub API: rules for coding agents"
built: 2026-10-30
source: api/AGENTS.md
html: https://insurgently.com/projects/library-hub/technical/agents/AGENTS
---
# Library Hub API: rules for coding agents

> Index of these files: https://insurgently.com/projects/library-hub/technical/agents/llms.txt

You're in a plugin that calls Library Hub through `@insurgently/library-hub-api`. The contract is `dist/index.d.ts` in this package. Follow these rules:

1. **Use the getter.** Reach Library Hub with `getLibraryHub(app, wanted, { by })` or `onLibraryHubReady(app, plugin, wanted, cb)`. Never `app.plugins.getPlugin('library-hub')` yourself.
2. **Gate on the lowest minor you need.** `wanted` is a version like `'0.8.0'`. Don't raise it just because the types are newer.
3. **Feature-detect anything newer than the gate.** A method tagged `@since` a later minor than your gate may be missing: `if (hasMethod(api, 'bookText'))`.
4. **Re-register on the ready event.** Library Hub can be turned off and on. `onLibraryHubReady` calls you again with the new API object; drop the old one.
5. **Treat the error `code` as the contract.** Branch on `e.code` (`server-off`, `book-missing`, `needs-conversion`…), never on the message. Show the message to the user as it is.
6. **Never import plugin source.** Only this package. Its runtime part is a few helpers with no dependencies.

Also: a `BookRef` can be a number, a string or `{ isbn: … }`; pass what you have. `bookText` only converts an AZW3 or MOBI with `{ convert: true }`, and the user is asked first. A chapter's `location` goes to `openBook` unchanged.
