UNPKG

@puls-atlas/cli

Version:

The Puls Atlas CLI tool for managing Atlas projects

265 lines 11.8 kB
import { normalizeOptionalString } from '../../utils/value.js'; import { collectResolveMatchedTokens } from './resolveTokens.js'; const createResolveReason = (code, matchedTokens, score) => ({ code, matchedTokens: [...new Set(Array.isArray(matchedTokens) ? matchedTokens : [])], score }); const createResolveReasonCodes = reasons => [...new Set((Array.isArray(reasons) ? reasons : []).map(reason => reason.code))]; const appendResolveReason = (reasons, queryTokens, fragments, weight, code) => { const matchedTokens = collectResolveMatchedTokens(queryTokens, fragments); if (matchedTokens.length === 0) { return 0; } const score = matchedTokens.length * weight; reasons.push(createResolveReason(code, matchedTokens, score)); return score; }; const appendResolvePenalty = (reasons, queryTokens, fragments, weight, code) => { const matchedTokens = collectResolveMatchedTokens(queryTokens, fragments); if (matchedTokens.length === 0) { return 0; } const score = matchedTokens.length * weight * -1; reasons.push(createResolveReason(code, matchedTokens, score)); return score; }; const getResolveGuideTrustBonus = guide => { let trustBonus = 0; if (normalizeOptionalString(guide?.reviewStatus) === 'reviewed') { trustBonus += 3; } if (normalizeOptionalString(guide?.status) === 'stable') { trustBonus += 2; } return trustBonus; }; const getResolveSymbolTrustBonus = symbol => { let trustBonus = 0; if (normalizeOptionalString(symbol?.status) === 'stable') { trustBonus += 2; } return trustBonus; }; const getResolvePackageMaturityBonus = maturity => { if (normalizeOptionalString(maturity) === 'guide-enriched') { return 3; } if (normalizeOptionalString(maturity) === 'symbol-enriched') { return 1; } return 0; }; const hasResolveReasonCode = (reasons, code) => (Array.isArray(reasons) ? reasons : []).some(reason => reason?.code === code); const getResolveInventoryDirectMatchBonus = (snapshotPackage, reasons, topGuide, topSymbol) => { if (topGuide || topSymbol) { return 0; } if (normalizeOptionalString(snapshotPackage?.maturity) !== 'inventory-only') { return 0; } return hasResolveReasonCode(reasons, 'package-name-match') ? 3 : 0; }; const normalizeResolveReferenceList = values => [...new Set((Array.isArray(values) ? values : []).map(value => normalizeOptionalString(value)).filter(Boolean))]; const getResolveSymbolReferenceNames = symbol => { const symbolId = normalizeOptionalString(symbol?.id); const symbolName = normalizeOptionalString(symbol?.name); const referenceNames = new Set([symbolId, symbolName].filter(Boolean)); if (symbolId?.includes(':')) { referenceNames.add(symbolId.split(':').at(-1)); } return referenceNames; }; const doesResolveGuideReferenceSymbol = (guide, symbol) => { const symbolReferenceNames = getResolveSymbolReferenceNames(symbol); const guideReferences = normalizeResolveReferenceList([...(Array.isArray(guide?.appliesToSymbols) ? guide.appliesToSymbols : []), ...(Array.isArray(guide?.relatedSymbols) ? guide.relatedSymbols : [])]); return guideReferences.some(reference => { if (symbolReferenceNames.has(reference)) { return true; } if (reference.includes(':')) { return symbolReferenceNames.has(reference.split(':').at(-1)); } return false; }); }; export const needsResolveNestedPrecisionDrillDown = packageCandidate => { if (normalizeOptionalString(packageCandidate?.maturity) !== 'guide-enriched') { return false; } const topSymbol = packageCandidate?.topSymbol ?? null; if (!topSymbol) { return false; } const topGuide = packageCandidate?.topGuide ?? null; return !doesResolveGuideReferenceSymbol(topGuide, topSymbol); }; export const compareResolveCandidates = (left, right, leftKey, rightKey) => { if (right.score !== left.score) { return right.score - left.score; } return leftKey.localeCompare(rightKey); }; const getResolveGuideSymbolAlignmentBonus = (guideCandidate, symbolCandidate) => { if (!doesResolveGuideReferenceSymbol(guideCandidate, symbolCandidate)) { return 0; } return 14; }; const createResolveGuideCandidateWithSymbolAlignment = (guideCandidate, symbolCandidate) => { const alignmentBonus = getResolveGuideSymbolAlignmentBonus(guideCandidate, symbolCandidate); if (alignmentBonus <= 0) { return guideCandidate; } const reasons = [...guideCandidate.reasons, createResolveReason('guide-top-symbol-alignment', [symbolCandidate?.id, symbolCandidate?.name].filter(Boolean), alignmentBonus)]; return { ...guideCandidate, reasons, reasonCodes: createResolveReasonCodes(reasons), score: guideCandidate.score + alignmentBonus }; }; export const createResolvePresentationPackageCandidate = packageCandidate => { const topSymbol = packageCandidate?.topSymbol ?? null; if (!topSymbol || !Array.isArray(packageCandidate?.guideCandidates)) { return packageCandidate; } const guideCandidates = packageCandidate.guideCandidates.map(guideCandidate => createResolveGuideCandidateWithSymbolAlignment(guideCandidate, topSymbol)).sort((left, right) => compareResolveCandidates(left, right, left.id, right.id)); return { ...packageCandidate, guideCandidates, topGuide: guideCandidates[0] ?? null }; }; const createResolveGuideCandidate = (packageCandidate, guide, queryTokens) => { const reasons = []; let score = 0; score += appendResolveReason(reasons, queryTokens, guide?.tasks, 7, 'guide-task-match'); score += appendResolveReason(reasons, queryTokens, [guide?.title, guide?.summary], 3, 'guide-summary-match'); score += appendResolvePenalty(reasons, queryTokens, guide?.antiPatterns, 3, 'guide-antipattern-penalty'); if (score > 0) { const trustBonus = getResolveGuideTrustBonus(guide); if (trustBonus > 0) { score += trustBonus; reasons.push(createResolveReason('guide-trust-bonus', [], trustBonus)); } } return { appliesToSymbols: normalizeResolveReferenceList(guide?.appliesTo?.symbols), id: normalizeOptionalString(guide?.id) ?? normalizeOptionalString(guide?.title), packageName: packageCandidate.name, relatedSymbols: normalizeResolveReferenceList(guide?.relatedSymbols), reasons, reasonCodes: createResolveReasonCodes(reasons), reviewStatus: normalizeOptionalString(guide?.reviewStatus) ?? null, score, status: normalizeOptionalString(guide?.status) ?? null, summary: normalizeOptionalString(guide?.summary) ?? null, title: normalizeOptionalString(guide?.title) ?? null }; }; const createResolveSymbolCandidate = (packageCandidate, symbol, queryTokens) => { const reasons = []; let score = 0; score += appendResolveReason(reasons, queryTokens, symbol?.name, 4, 'symbol-name-match'); score += appendResolveReason(reasons, queryTokens, [symbol?.purpose, symbol?.summary], 4, 'symbol-purpose-match'); score += appendResolveReason(reasons, queryTokens, [...(Array.isArray(symbol?.useWhen) ? symbol.useWhen : []), ...(Array.isArray(symbol?.preferredFor) ? symbol.preferredFor : [])], 5, 'symbol-usage-match'); score += appendResolvePenalty(reasons, queryTokens, [...(Array.isArray(symbol?.avoidWhen) ? symbol.avoidWhen : []), ...(Array.isArray(symbol?.notFor) ? symbol.notFor : [])], 6, 'symbol-avoidance-penalty'); score += appendResolveReason(reasons, queryTokens, symbol?.kind, 2, 'symbol-kind-match'); if (score > 0) { const trustBonus = getResolveSymbolTrustBonus(symbol); if (trustBonus > 0) { score += trustBonus; reasons.push(createResolveReason('symbol-trust-bonus', [], trustBonus)); } } return { id: normalizeOptionalString(symbol?.id) ?? normalizeOptionalString(symbol?.name), kind: normalizeOptionalString(symbol?.kind) ?? null, name: normalizeOptionalString(symbol?.name) ?? null, packageName: packageCandidate.name, reasons, reasonCodes: createResolveReasonCodes(reasons), score, status: normalizeOptionalString(symbol?.status) ?? null, summary: normalizeOptionalString(symbol?.summary) ?? null }; }; export const createResolvePackageCandidate = (snapshotPackage, queryTokens) => { const reasons = []; let score = 0; score += appendResolveReason(reasons, queryTokens, snapshotPackage?.name, 2, 'package-name-match'); score += appendResolveReason(reasons, queryTokens, snapshotPackage?.role, 4, 'package-role-match'); score += appendResolveReason(reasons, queryTokens, snapshotPackage?.responsibility, 3, 'responsibility-match'); score += appendResolveReason(reasons, queryTokens, snapshotPackage?.ownedSurface, 5, 'owned-surface-match'); score += appendResolveReason(reasons, queryTokens, (Array.isArray(snapshotPackage?.entrypoints) ? snapshotPackage.entrypoints : []).map(entrypoint => entrypoint?.purpose), 2, 'entrypoint-purpose-match'); const symbolCandidates = (Array.isArray(snapshotPackage?.selectedSymbols) ? snapshotPackage.selectedSymbols : []).map(symbol => createResolveSymbolCandidate(snapshotPackage, symbol, queryTokens)).filter(candidate => candidate.score > 0).sort((left, right) => compareResolveCandidates(left, right, left.id, right.id)); const topSymbol = symbolCandidates[0] ?? null; const guideCandidates = (Array.isArray(snapshotPackage?.selectedGuides) ? snapshotPackage.selectedGuides : []).map(guide => createResolveGuideCandidate(snapshotPackage, guide, queryTokens)).filter(candidate => candidate.score > 0).sort((left, right) => compareResolveCandidates(left, right, left.id, right.id)); const topGuide = guideCandidates[0] ?? null; if (topGuide) { score += topGuide.score; reasons.push(createResolveReason('guide-candidate-bonus', [topGuide.id], topGuide.score)); } if (topSymbol) { score += topSymbol.score; reasons.push(createResolveReason('symbol-candidate-bonus', [topSymbol.id], topSymbol.score)); } if (score > 0) { const inventoryDirectMatchBonus = getResolveInventoryDirectMatchBonus(snapshotPackage, reasons, topGuide, topSymbol); if (inventoryDirectMatchBonus > 0) { score += inventoryDirectMatchBonus; reasons.push(createResolveReason('inventory-direct-match-bonus', [snapshotPackage?.name].filter(Boolean), inventoryDirectMatchBonus)); } } if (score > 0) { const maturityBonus = getResolvePackageMaturityBonus(snapshotPackage?.maturity); if (maturityBonus > 0) { score += maturityBonus; reasons.push(createResolveReason('maturity-bonus', [], maturityBonus)); } } return { guideCandidates, maturity: normalizeOptionalString(snapshotPackage?.maturity) ?? null, name: snapshotPackage?.name, reasons, reasonCodes: createResolveReasonCodes(reasons), role: normalizeOptionalString(snapshotPackage?.role) ?? null, score, symbolCandidates, topGuide, topSymbol }; }; export const createResolveConfidence = packageCandidates => { if (!Array.isArray(packageCandidates) || packageCandidates.length === 0) { return 'none'; } const topCandidate = packageCandidates[0]; const secondCandidate = packageCandidates[1] ?? null; const scoreGap = secondCandidate === null ? topCandidate.score : topCandidate.score - secondCandidate.score; if (topCandidate.score >= 24 && scoreGap >= 4) { return 'high'; } if (topCandidate.score >= 10) { return 'medium'; } return 'low'; }; export const createResolveAmbiguity = packageCandidates => { if (!Array.isArray(packageCandidates) || packageCandidates.length < 2) { return null; } const topCandidate = packageCandidates[0]; const secondCandidate = packageCandidates[1]; const scoreGap = topCandidate.score - secondCandidate.score; if (scoreGap > 3) { return null; } return { kind: 'close-score', packageNames: [topCandidate.name, secondCandidate.name], scoreGap }; };