@puls-atlas/cli
Version:
The Puls Atlas CLI tool for managing Atlas projects
265 lines • 11.8 kB
JavaScript
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
};
};