import { type EngineAnswer, type MentionResult, type ProductEntity } from '../types.js'; /** * The ordered list of products an answer recommends, first-mentioned first. * * Engines format recommendations in several ways and all of them are real * (lesson #4): numbered lists, bullets, markdown headings, and bold lead-in * paragraphs. Anything with no such structure yields an empty shelf, which is a * signal in itself - `analyzeProductAnswer` sends those to the judge rather * than reading them as "recommends nothing". * * What a candidate must survive to reach the shelf is `isPlausibleName`: real * answers bullet a product's FEATURES underneath its name, and those bullets * are structurally identical to a list of products. Live runs on 2026-07-23 put * "Automatic milk steaming with adjustable temp and texture", "Compact" and * "Height" on merchants' shelves as if they were rival products, which is what * those filters exist to stop. */ export declare function extractRecommendations(text: string): string[]; /** * One product's analysis of one engine answer. * * Structurally a {@link MentionResult}, so M7's scoring aggregation * (`scoreEngine`, `compositeScore`) applies unchanged - one formula, one * `SCORING_VERSION`, no forked maths (rule #6). */ export interface ProductMention extends MentionResult { /** The MERCHANT's name for this product, never an engine-echoed variant. */ product: string; /** The answer's recommendation list, in the order it presented them. */ shelf: string[]; } /** Every name this product answers to. */ export declare function productTerms(product: ProductEntity): string[]; /** Whether a shelf entry refers to this product (boundary-aware, folded). */ export declare function shelfEntryIsProduct(entry: string, terms: string[]): boolean; /** Analyze one engine answer for one product (deterministic pass 1). */ export declare function analyzeProductAnswer(answer: EngineAnswer, product: ProductEntity): ProductMention;