Terminaalin autokorjaus: knp→kpn, kpn rnu→kpn run jne.

Typo-taulukko yleisimmille kirjoitusvirheille + Levenshtein-etäisyys
tuntemattomille ensimmäisille sanoille (max 2 merkin ero → kpn).
Korjaus näytetään terminaalissa keltaisella.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-07 06:35:30 +03:00
parent 01d8b597e1
commit b70cdbd24d

View File

@@ -2242,11 +2242,58 @@ Files: ${Object.keys(generatedFiles).join(', ')}`;
termLog(`\n<span style="color:#a371f7;font-weight:bold">━━━ Pipeline valmis ━━━</span>`); termLog(`\n<span style="color:#a371f7;font-weight:bold">━━━ Pipeline valmis ━━━</span>`);
} }
// Autokorjaus: tunnetut kirjoitusvirheet ja lähimmän komennon ehdotus
function autocorrect(input) {
const typos = {
'knp': 'kpn', 'kpb': 'kpn', 'kpm': 'kpn', 'kn': 'kpn', 'kp': 'kpn',
'kpn rnu': 'kpn run', 'kpn rn': 'kpn run', 'kpn ru': 'kpn run',
'kpn laod': 'kpn load', 'kpn lod': 'kpn load', 'kpn loa': 'kpn load',
'kpn porject': 'kpn project', 'kpn projcet': 'kpn project', 'kpn proejct': 'kpn project',
'kpn pipelien': 'kpn pipeline', 'kpn pipline': 'kpn pipeline',
'kpn staus': 'kpn status', 'kpn stauts': 'kpn status',
'kpn modles': 'kpn models', 'kpn mdoels': 'kpn models',
'kpn hlep': 'kpn help', 'kpn hep': 'kpn help',
'kpn clera': 'kpn clear', 'kpn claer': 'kpn clear',
'kpn helo': 'kpn hello', 'kpn hell': 'kpn hello',
};
// Tarkista koko komento ja ensimmäinen sana + alikomento
const lower = input.toLowerCase();
for (const [typo, fix] of Object.entries(typos)) {
if (lower === typo || lower.startsWith(typo + ' ')) {
return fix + input.slice(typo.length);
}
}
// Levenshtein-etäisyys ensimmäiselle sanalle
const firstWord = input.trim().split(/\s+/)[0].toLowerCase();
if (firstWord !== 'kpn' && firstWord.length >= 2 && firstWord.length <= 5) {
const dist = levenshtein(firstWord, 'kpn');
if (dist <= 2) return 'kpn' + input.slice(firstWord.length);
}
return null;
}
function levenshtein(a, b) {
const m = a.length, n = b.length;
const d = Array.from({length: m + 1}, (_, i) => [i]);
for (let j = 1; j <= n; j++) d[0][j] = j;
for (let i = 1; i <= m; i++)
for (let j = 1; j <= n; j++)
d[i][j] = Math.min(d[i-1][j] + 1, d[i][j-1] + 1, d[i-1][j-1] + (a[i-1] !== b[j-1] ? 1 : 0));
return d[m][n];
}
function termExec(cmd) { function termExec(cmd) {
termLog(`<span class="terminal-prompt">$</span> ${esc(cmd)}`); termLog(`<span class="terminal-prompt">$</span> ${esc(cmd)}`);
termHistory.unshift(cmd); termHistory.unshift(cmd);
termHistIdx = -1; termHistIdx = -1;
// Autokorjaus
const corrected = autocorrect(cmd.trim());
if (corrected && corrected !== cmd.trim()) {
cmd = corrected;
termLog(` <span style="color:#d29922">→ korjattu: ${esc(cmd)}</span>`);
}
const parts = cmd.trim().split(/\s+/); const parts = cmd.trim().split(/\s+/);
if (parts[0] !== 'kpn') { if (parts[0] !== 'kpn') {
termLog('kpn: tuntematon komento. Kokeile: kpn help', '#f85149'); termLog('kpn: tuntematon komento. Kokeile: kpn help', '#f85149');