UNPKG

akm-cli

Version:

akm (Agent Knowledge Manager) — a portable, local-first capability library for AI agents. Discover, load, share, and improve reusable skills, scripts, workflows, and knowledge across any shell-capable coding agent, including Claude Code, OpenCode, and Cur

82 lines (81 loc) • 3.03 kB
// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. /** * Return per-field search text for multi-column FTS5 indexing. * * Text keeps its case: FTS5's `unicode61` tokenizer folds case itself, and * `buildSearchText` feeds the embedder, where case carries meaning. * * Fields: * - name: entry name with hyphens/underscores replaced by spaces * - description: entry description * - tags: tags + aliases joined * - hints: searchHints + examples + usage + intent fields * - content: bounded native/adapter body projection + TOC headings + parameters * (lowest-weight catch-all) */ export function buildSearchFields(entry) { const name = entry.name.replace(/[-_]/g, " "); const description = entry.description ?? ""; const tagParts = []; if (entry.tags) tagParts.push(entry.tags.join(" ")); if (entry.aliases) tagParts.push(entry.aliases.join(" ")); const tags = tagParts.join(" "); const hintParts = []; if (entry.hints) hintParts.push(entry.hints.join(" ")); if (entry.searchHints) hintParts.push(entry.searchHints.join(" ")); if (entry.examples) hintParts.push(entry.examples.join(" ")); if (entry.usage) hintParts.push(entry.usage.join(" ")); if (entry.intent) { if (entry.intent.when) hintParts.push(entry.intent.when); if (entry.intent.input) hintParts.push(entry.intent.input); if (entry.intent.output) hintParts.push(entry.intent.output); } if (entry.xrefs) hintParts.push(entry.xrefs.join(" ")); if (entry.pageKind) hintParts.push(entry.pageKind); if (entry.whenToUse) hintParts.push(entry.whenToUse); const hints = hintParts.join(" "); const contentParts = []; if (entry.toc) { contentParts.push(entry.toc.map((h) => h.text).join(" ")); } if (entry.parameters) { for (const param of entry.parameters) { contentParts.push(param.name); if (param.description) contentParts.push(param.description); } } if (entry.content) contentParts.push(entry.content); const content = contentParts.join(" "); return { name, description, tags, hints, content }; } /** * Build a single concatenated search text string for an entry: the text its * vector is embedded from, derived from the stored document when the entry is * embedded (`entries.embed_hash` holds its hash). */ export function buildSearchText(entry) { const fields = buildSearchFields(entry); const structured = [fields.name, fields.description, fields.tags, fields.hints] .filter((field) => field.length > 0) .join(" "); if (!fields.content) return structured; const separator = structured ? " " : ""; return `${structured}${separator}${fields.content}`; }