/** A single searchable, citable unit of portfolio or docs content. */ export interface PortfolioDocument { /** Stable unique id (used as the citation key). */ id: string; title: string; /** Short, human-readable summary used in result rows and answers. */ summary: string; /** Optional longer text that is indexed but not shown verbatim. */ body?: string; /** Destination URL (absolute or site-relative). */ url?: string; /** Category badge, e.g. "Platform", "Role", "Writing", "Credential". */ category: string; /** Free-form tags that boost matching (skills, disciplines, stack). */ tags?: string[]; /** Verified, quotable facts. Answers are built only from these + summary. */ facts?: string[]; /** Optional preview key the host can map to a hover preview. */ previewKey?: string; /** Static ranking prior (default 1). */ weight?: number; /** Optional ISO date for sorting/recency hints. */ date?: string; } export interface SearchHit { doc: PortfolioDocument; score: number; /** Matched query terms (normalized). */ matched: string[]; } export interface SearchOptions { limit?: number; /** Restrict to these categories. */ categories?: string[]; /** Extra per-document score multiplier. */ boost?: (doc: PortfolioDocument) => number; } /** * A host-authored intent: when a question matches, the synthesizer answers with * the verified `lead` and cites the best documents matching `boostTerms`. */ export interface AnswerIntent { id: string; /** Matches the normalized question. */ match: RegExp; /** Verified lead sentence(s) — write these from facts you can prove. */ lead: string; /** Terms appended to the retrieval query for this intent. */ boostTerms?: string[]; /** Document ids that must be cited first when present. */ pin?: string[]; /** Max bullets (default 4). */ maxPoints?: number; } export interface Citation { id: string; title: string; url?: string; category: string; previewKey?: string; } export interface AskAnswer { question: string; /** Plain-text answer with [n] citation markers. */ answer: string; /** Supporting bullets, each ending with a [n] marker. */ points: string[]; citations: Citation[]; mode: "deterministic" | "llm"; intent?: string; /** Model id when mode === "llm". */ model?: string; tookMs: number; } export interface SearchResponse { query: string; hits: Array & { doc: PortfolioDocument }>; tookMs: number; }