@@ -157,6 +157,24 @@ jobs:
157157 .filter(Boolean);
158158 }
159159
160+ function findGamesFromText(text, gameAliasToLabel, gameAliasToScript) {
161+ const labels = new Set();
162+ const scripts = new Set();
163+ const normalizedText = normalizeName(text);
164+ if (!normalizedText) return { labels, scripts };
165+
166+ const paddedText = ` ${normalizedText} `;
167+ for (const [alias, label] of gameAliasToLabel.entries()) {
168+ if (alias.length < 3) continue;
169+ if (!paddedText.includes(` ${alias} `)) continue;
170+ labels.add(label);
171+ const mappedScript = gameAliasToScript.get(alias);
172+ if (mappedScript) scripts.add(mappedScript);
173+ }
174+
175+ return { labels, scripts };
176+ }
177+
160178 function parseServerlistCsv(csvText) {
161179 const rows = [];
162180 const lines = (csvText || '').split(/\r?\n/);
@@ -418,6 +436,13 @@ jobs:
418436 if (mappedScript) desiredServerScripts.add(mappedScript);
419437 }
420438
439+ // Legacy issues often have no form section; fall back to deterministic text matching.
440+ if (desiredGames.size === 0) {
441+ const fromText = findGamesFromText(`${title}\n${body}`, gameAliasToLabel, gameAliasToScript);
442+ for (const label of fromText.labels) desiredGames.add(label);
443+ for (const scriptName of fromText.scripts) desiredServerScripts.add(scriptName);
444+ }
445+
421446 // AI advisory is only needed on issue opened/edited.
422447 let triage = {};
423448 let ranAi = false;
@@ -900,6 +925,24 @@ jobs:
900925 .filter(Boolean);
901926 }
902927
928+ function findGamesFromText(text, gameAliasToLabel, gameAliasToScript) {
929+ const labels = new Set();
930+ const scripts = new Set();
931+ const normalizedText = normalizeName(text);
932+ if (!normalizedText) return { labels, scripts };
933+
934+ const paddedText = ` ${normalizedText} `;
935+ for (const [alias, label] of gameAliasToLabel.entries()) {
936+ if (alias.length < 3) continue;
937+ if (!paddedText.includes(` ${alias} `)) continue;
938+ labels.add(label);
939+ const mappedScript = gameAliasToScript.get(alias);
940+ if (mappedScript) scripts.add(mappedScript);
941+ }
942+
943+ return { labels, scripts };
944+ }
945+
903946 function parseServerlistCsv(csvText) {
904947 const rows = [];
905948 const lines = (csvText || '').split(/\r?\n/);
@@ -1203,6 +1246,14 @@ jobs:
12031246 const mappedScript = gameAliasToScript.get(normalizedCandidate);
12041247 if (mappedScript) desiredServerScripts.add(mappedScript);
12051248 }
1249+
1250+ // Legacy issues often have no form section; fall back to deterministic text matching.
1251+ if (desiredGames.size === 0) {
1252+ const fromText = findGamesFromText(`${title}\n${body}`, gameAliasToLabel, gameAliasToScript);
1253+ for (const label of fromText.labels) desiredGames.add(label);
1254+ for (const scriptName of fromText.scripts) desiredServerScripts.add(scriptName);
1255+ }
1256+
12061257 for (const gameLabel of desiredGames) {
12071258 const mappedScript = gameAliasToScript.get(normalizeName(gameLabel.slice(6)));
12081259 if (mappedScript) desiredServerScripts.add(mappedScript);
0 commit comments