// records' tools — how the record is asked (novox/hq ADR 0025, ADR 0153). // // Five questions, each answered from the checkout at the commit it names: where does a phrase // appear, what does one document say, what does a folder hold, where does the checkout stand, and // bring it up to date now. The reasoning stays in the documents; the tools only find them. import { registerModuleTools, type ToolDefinition } from "@novox/mesh-sdk/tools"; import { recordsFromEnv, type Records } from "../records.js"; export function getRecordsTools(records: Records): ToolDefinition[] { return [ { name: "records_search", description: "Where a phrase appears in the decisions, designs and issues, as written: document, line, nearest heading. " + "Search the literal words of a symptom or a term before forming a hypothesis; the answer names the commit it was read at.", input: { query: { type: "string", description: "the phrase, matched case-insensitively as written" }, limit: { type: "number", description: "at most this many places (default 50)" }, }, run: async (args) => records.search(String(args.query ?? ""), args.limit ? Number(args.limit) : undefined), }, { name: "records_read", description: "One document, whole, by its path in the repository — a decision record, a design document, an issue report.", input: { path: { type: "string", description: "the document's path, e.g. 02-DECISIONS/0025-....md" } }, run: async (args) => records.read(String(args.path ?? "")), }, { name: "records_list", description: "What a folder of the repository holds: its sub-folders and its documents. The root when no folder is named.", input: { folder: { type: "string", description: "a folder inside the repository (optional)" } }, run: async (args) => records.list(args.folder ? String(args.folder) : ""), }, { name: "records_status", description: "Where the checkout stands: the repository, the forge it is read from, the commit and its date, when it was last brought up to date.", input: {}, run: async () => records.standing(), }, { name: "records_sync", description: "Bring the checkout up to date now, and say where it stands.", input: {}, run: async () => { await records.sync(); return records.standing(); }, }, ]; } // The reader is made once, at load, from the environment the runtime resolves; the contributor is // synchronous and is called at every collection. Without a repository to read there is nothing to // answer, and the module exposes no tools rather than five that fail — the sdk's contract: a // contributor returning [] is normal. let reader: Records | null = null; try { reader = await recordsFromEnv(); } catch (err) { console.log(`[records] no tools — ${err instanceof Error ? err.message : String(err)}`); } registerModuleTools("records", () => (reader ? getRecordsTools(reader) : []));