Skip to content

Commit 5f575cd

Browse files
committed
Release analyzer improve llms cross-check with slug index
1 parent 6c9ce21 commit 5f575cd

File tree

1 file changed

+54
-3
lines changed
  • docusaurus/scripts/strapi-release-analyzer

1 file changed

+54
-3
lines changed

docusaurus/scripts/strapi-release-analyzer/index.js

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ async function readLlmsFullIndex() {
8383
const pages = [];
8484
const byTitle = new Map();
8585
const byUrl = new Map();
86+
const bySlug = new Map();
8687

8788
// Heuristic parser:
8889
// - Treat lines starting with "# " or "## " as page/section titles
@@ -106,7 +107,7 @@ async function readLlmsFullIndex() {
106107
if (/^#\s+/.test(line)) {
107108
// Page title
108109
const title = line.replace(/^#\s+/, '').trim();
109-
current = { title, url: null, anchors: new Set() };
110+
current = { title, url: null, anchors: new Set(), text: '' };
110111
pages.push(current);
111112
byTitle.set(title.toLowerCase(), current);
112113
continue;
@@ -115,7 +116,7 @@ async function readLlmsFullIndex() {
115116
// Treat as page title too if no outer # title exists yet
116117
const title = line.replace(/^##\s+/, '').trim();
117118
if (!current) {
118-
current = { title, url: null, anchors: new Set() };
119+
current = { title, url: null, anchors: new Set(), text: '' };
119120
pages.push(current);
120121
byTitle.set(title.toLowerCase(), current);
121122
} else {
@@ -134,6 +135,17 @@ async function readLlmsFullIndex() {
134135
if (m && !current.url) {
135136
current.url = m[1];
136137
byUrl.set(current.url, current);
138+
try {
139+
const u = new URL(current.url);
140+
// take last non-empty segment as slug
141+
const segs = u.pathname.split('/').filter(Boolean);
142+
const last = segs[segs.length - 1] || '';
143+
if (last) bySlug.set(last.toLowerCase(), current);
144+
} catch {}
145+
}
146+
// Accumulate raw text for coverage checks
147+
if (current) {
148+
current.text += line + "\n";
137149
}
138150
}
139151

@@ -142,9 +154,17 @@ async function readLlmsFullIndex() {
142154
title: p.title,
143155
url: p.url || null,
144156
anchors: Array.from(p.anchors),
157+
text: p.text || ''
145158
}));
146159

147-
return { source, pages: normalized, byTitle, byUrl };
160+
// Re-link bySlug to normalized objects
161+
const bySlugNormalized = new Map();
162+
for (const [k, v] of bySlug.entries()) {
163+
const norm = normalized.find(p => p.title === v.title && p.url === v.url);
164+
if (norm) bySlugNormalized.set(k, norm);
165+
}
166+
167+
return { source, pages: normalized, byTitle, byUrl, bySlug: bySlugNormalized };
148168
}
149169

150170
function parseArgs(argv) {
@@ -923,6 +943,37 @@ async function main() {
923943
}
924944
}
925945

946+
// llms-full cross-check: if targets are present and the page text likely already
947+
// describes the expected behavior (and PR looks like a fix), downgrade to NO.
948+
if (claudeSuggestions && claudeSuggestions.needsDocs === 'yes' && Array.isArray(claudeSuggestions.targets) && claudeSuggestions.targets.length > 0) {
949+
const looksLikeFix = /fix|bug|regression|restore|correct|misleading|missing/i.test(prAnalysis.title || '') || /fix|bug|regression|restore|correct|misleading|missing/i.test(prAnalysis.body || '');
950+
if (looksLikeFix) {
951+
const coverageHit = claudeSuggestions.targets.some(t => {
952+
const wanted = (t.path || '').toLowerCase();
953+
let page = null;
954+
// prefer exact slug match from llmsIndex
955+
const slug = path.basename(wanted).replace(/\.mdx?$/i, '').toLowerCase();
956+
if (slug && llmsIndex.bySlug && llmsIndex.bySlug.has(slug)) {
957+
page = llmsIndex.bySlug.get(slug);
958+
}
959+
// fallback: any candidate containing the slug
960+
if (!page) {
961+
page = candidates.find(p => p.url && p.url.toLowerCase().includes(slug));
962+
}
963+
// last resort: first candidate
964+
if (!page) page = candidates[0];
965+
if (!page || !page.text) return false;
966+
const words = (summary || '').toLowerCase().split(/[^a-z0-9]+/).filter(w => w.length > 3).slice(0, 8);
967+
const body = page.text.toLowerCase();
968+
const hits = words.filter(w => body.includes(w));
969+
return hits.length >= Math.max(2, Math.floor(words.length / 2));
970+
});
971+
if (coverageHit) {
972+
claudeSuggestions = { ...claudeSuggestions, needsDocs: 'no' };
973+
}
974+
}
975+
}
976+
926977
analyses.push({
927978
...prAnalysis,
928979
summary,

0 commit comments

Comments
 (0)