import type { AssetCatalogEntry, DemandEvidenceStrength, RecommendationBasis, RecommendationScoreBreakdown, RecommendationSignalMatch, RecommendationSignalType } from "../types.js"; import type { RecommendationHost } from "./hosts.js"; /** * Describes demand term context data exchanged by the lifecycle pipeline. */ export interface DemandTermContext { key: string; canonicalTerm: string; signalType: RecommendationSignalType; evidenceCount: number; evidenceStrengthCounts: Record; matchTerms: Set; /** * Distinctive identity tokens of a declared dependency when this term was * registered from a package-manifest entry (npm:…, pypi:…, cargo:…): * the bare package name's tokens minus generic package-noise tokens * (node, api, cli, …) plus the scope name for `@scope/pkg`. Undefined for * terms that are not package declarations (#444). */ packageIdentityTokens?: ReadonlySet; } /** * Describes demand context data exchanged by the lifecycle pipeline. */ export interface DemandContext { terms: DemandTermContext[]; hasSignals: boolean; activeDomainGroups: Set; packageManifestEntries: Set; /** * Maps a demand term's canonical form to the distinctive identity tokens * of the declared package it came from (see DemandTermContext. * packageIdentityTokens). Used by match-quality analysis to require * asset-side package identity before awarding exact-stack (#444). */ packageIdentityByTerm: Map>; demandKeywords: Set; /** * Normalised set of package-manager family names detected in the workspace * demand profile (e.g. "npm", "pip", "composer"). Used for ecosystem-affinity * penalty computation. Empty when no demand profile is available. */ packageManagers: Set; } /** * Describes candidate recommendation data exchanged by the lifecycle pipeline. */ export interface CandidateRecommendation { entry: AssetCatalogEntry; host: RecommendationHost; sourceFamily: string; availableLocally: boolean; recommendationBasis: RecommendationBasis; coverageTags: string[]; taskModes: string[]; matchedSignals: RecommendationSignalMatch[]; duplicateGroup?: string; reasons: string[]; breakdown: RecommendationScoreBreakdown; /** See `RecommendationEntry.coincidentalMatchOnly`. */ coincidentalMatchOnly: boolean; } /** * Describes host-independent recommendation analysis shared across all host * ranking passes for one report build. */ export interface CandidateRecommendationBase { entry: AssetCatalogEntry; sourceFamily: string; availableLocally: boolean; recommendationBasis: RecommendationBasis; coverageTags: string[]; taskModes: string[]; matchedSignals: RecommendationSignalMatch[]; duplicateGroup?: string; reasons: string[]; searchTerms: Set; breakdown: RecommendationScoreBreakdown; /** See `RecommendationEntry.coincidentalMatchOnly`. */ coincidentalMatchOnly: boolean; } /** * Describes precomputed policy search sets shared across all candidates for one * recommendation host run, avoiding per-candidate policy-map rebuilds. */ export interface PolicySearchContext { genericToolingTerms: Set; wrapperLikeTerms: Set; concernTermSets: Map>; taskModeTermSets: Map>; domainGroupTermSets: Map>; } /** * Describes one candidate's dynamic score after host-selection adjustments. */ export interface DynamicScore { total: number; coverage: number; diversity: number; assetKindDiversityPenalty: number; redundancyPenalty: number; budgetPenalty: number; }