// bookshelf's tools — ported from the shared hal `arr` sdk (novox/hq ADR 0039), importing // bookshelf's own client. They return structured data (not the pre-formatted text hal returned); the // mesh serves them through the sdk's tool harness. Bookshelf has no calendar endpoint, so there is // no calendar tool — matching hal, which excluded it from its calendar-capable apps. import { registerModuleTools, type ToolDefinition } from "@novox/mesh-sdk/tools"; import { BookshelfClient } from "../client.js"; export function getBookshelfTools(bookshelf: BookshelfClient): ToolDefinition[] { return [ { name: "bookshelf_status", description: "Bookshelf status overview: version, book count, monitored count, queue size.", input: {}, run: async () => { const [status, content, queue] = await Promise.all([ bookshelf.getStatus(), bookshelf.getContent(), bookshelf.getQueue(), ]); return { app: status.appName, version: status.version, books: content.length, monitored: content.filter((c) => c.monitored).length, queue: queue.totalRecords, }; }, }, { name: "bookshelf_library", description: "List books from the Bookshelf library.", input: { limit: { type: "number", description: "max items to return (default 50)" } }, run: async (args) => { const items = await bookshelf.getContent(args.limit ? Number(args.limit) : 50); return { count: items.length, books: items }; }, }, { name: "bookshelf_search", description: "Search the Bookshelf library for books by title or author (filters existing content, not indexers).", input: { query: { type: "string", description: "the search term" } }, run: async (args) => { const query = String(args.query); return { query, results: await bookshelf.searchContent(query) }; }, }, { name: "bookshelf_queue", description: "Show the Bookshelf download queue — what is downloading and how far along.", input: {}, run: async () => { const queue = await bookshelf.getQueue(); return { count: queue.totalRecords, items: queue.items }; }, }, ]; } // The tools exist only when Bookshelf is configured; without a URL and key, bookshelf contributes // none rather than failing the whole runtime. registerModuleTools("bookshelf", (env) => { try { return getBookshelfTools(BookshelfClient.fromEnv(env)); } catch { return []; } });