Projektiraportti: HTML-dokumentaatio pipeline-vaiheista ja tiedostoista
Pipeline generoi HTML-raportin joka sisältää: - Pipeline-vaiheet prompteineen ja tuloksineen (avattavat details) - Staattisen analyysin tulokset - Kaikki generoidut tiedostot korostettuina - Raportti avautuu uuteen välilehteen linkistä terminaalissa - Projektikorttiin lisätty 📄 Raportti -nappi Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2191,7 +2191,7 @@ IMPORTANT: Include get_db() dependency for FastAPI` },
|
|||||||
// Globaali storage projektikorttien tiedostoille (välttää JSON data-attribuuttien ongelmat)
|
// Globaali storage projektikorttien tiedostoille (välttää JSON data-attribuuttien ongelmat)
|
||||||
const projectFiles = {};
|
const projectFiles = {};
|
||||||
|
|
||||||
function renderProjectCard(files, projectName) {
|
function renderProjectCard(files, projectName, reportUrl) {
|
||||||
const fileEntries = Object.entries(files);
|
const fileEntries = Object.entries(files);
|
||||||
if (fileEntries.length === 0) return;
|
if (fileEntries.length === 0) return;
|
||||||
|
|
||||||
@@ -2219,6 +2219,7 @@ IMPORTANT: Include get_db() dependency for FastAPI` },
|
|||||||
<span style="display:flex;gap:6px">
|
<span style="display:flex;gap:6px">
|
||||||
<button onclick="copyAllFiles('${cardId}')" style="background:none;border:1px solid #30363d;color:#8b949e;font-size:11px;padding:2px 8px;border-radius:3px;cursor:pointer" title="Kopioi kaikki tiedostot leikepöydälle">Kopioi kaikki</button>
|
<button onclick="copyAllFiles('${cardId}')" style="background:none;border:1px solid #30363d;color:#8b949e;font-size:11px;padding:2px 8px;border-radius:3px;cursor:pointer" title="Kopioi kaikki tiedostot leikepöydälle">Kopioi kaikki</button>
|
||||||
<button onclick="downloadZip('${cardId}')" style="background:none;border:1px solid #30363d;color:#58a6ff;font-size:11px;padding:2px 8px;border-radius:3px;cursor:pointer" title="Lataa projekti ZIP-tiedostona">Lataa ZIP</button>
|
<button onclick="downloadZip('${cardId}')" style="background:none;border:1px solid #30363d;color:#58a6ff;font-size:11px;padding:2px 8px;border-radius:3px;cursor:pointer" title="Lataa projekti ZIP-tiedostona">Lataa ZIP</button>
|
||||||
|
${reportUrl ? `<a href="${reportUrl}" target="_blank" style="background:none;border:1px solid #a371f7;color:#a371f7;font-size:11px;padding:2px 8px;border-radius:3px;cursor:pointer;text-decoration:none">📄 Raportti</a>` : ''}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex;gap:2px;padding:6px 8px 0;background:#0d1117">${tabsHtml}</div>
|
<div style="display:flex;gap:2px;padding:6px 8px 0;background:#0d1117">${tabsHtml}</div>
|
||||||
@@ -2736,8 +2737,83 @@ ${fixableFiles}`;
|
|||||||
pipelineStep('coder', 'Korjaukset', 'done', 'Korjaukset generoitu', fixedCode);
|
pipelineStep('coder', 'Korjaukset', 'done', 'Korjaukset generoitu', fixedCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generoidaan projektin dokumentaatio HTML-raporttina
|
||||||
|
const reportHtml = generateProjectReport(task, generatedFiles, pipelineSteps, staticIssues);
|
||||||
|
const reportBlob = new Blob([reportHtml], { type: 'text/html' });
|
||||||
|
const reportUrl = URL.createObjectURL(reportBlob);
|
||||||
|
|
||||||
termLog(`\n<span style="color:#a371f7;font-weight:bold">━━━ Pipeline valmis (${Object.keys(generatedFiles).length} tiedostoa) ━━━</span>`);
|
termLog(`\n<span style="color:#a371f7;font-weight:bold">━━━ Pipeline valmis (${Object.keys(generatedFiles).length} tiedostoa) ━━━</span>`);
|
||||||
renderProjectCard(generatedFiles, task);
|
termLog(` <a href="${reportUrl}" target="_blank" style="color:#58a6ff;text-decoration:underline;cursor:pointer">📄 Avaa projektiraportti</a>`);
|
||||||
|
renderProjectCard(generatedFiles, task, reportUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateProjectReport(task, files, steps, staticIssues) {
|
||||||
|
const fileEntries = Object.entries(files);
|
||||||
|
const agentNames = { manager: 'Manageri', coder: 'Koodari', tester: 'DevOps', qa: 'QA', data: 'Data' };
|
||||||
|
const agentColors = { manager: '#d29922', coder: '#3fb950', tester: '#58a6ff', qa: '#a371f7', data: '#d2a8ff' };
|
||||||
|
|
||||||
|
const stepsHtml = steps.map((s, i) => {
|
||||||
|
const color = agentColors[s.agent] || '#8b949e';
|
||||||
|
const icon = s.status === 'done' ? '✓' : '◷';
|
||||||
|
const outputPreview = (s.output || '').substring(0, 500);
|
||||||
|
return `
|
||||||
|
<div style="margin-bottom:16px;border:1px solid #30363d;border-radius:6px;overflow:hidden">
|
||||||
|
<div style="background:#161b22;padding:8px 12px;display:flex;justify-content:space-between;align-items:center">
|
||||||
|
<span><span style="color:${s.status === 'done' ? '#3fb950' : '#d29922'}">${icon}</span> <strong style="color:${color}">${agentNames[s.agent] || s.agent}</strong> — ${s.label}</span>
|
||||||
|
<span style="color:#8b949e;font-size:12px">Vaihe ${i + 1}</span>
|
||||||
|
</div>
|
||||||
|
${s.input ? `<details><summary style="padding:6px 12px;color:#8b949e;font-size:12px;cursor:pointer">Prompti</summary><pre style="margin:0;padding:8px 12px;background:#010409;font-size:11px;overflow-x:auto;white-space:pre-wrap;color:#8b949e">${s.input.replace(/</g,'<').substring(0, 1000)}</pre></details>` : ''}
|
||||||
|
${outputPreview ? `<pre style="margin:0;padding:8px 12px;background:#0d1117;font-size:12px;overflow-x:auto;white-space:pre-wrap;color:#c9d1d9">${outputPreview.replace(/</g,'<')}</pre>` : ''}
|
||||||
|
</div>`;
|
||||||
|
}).join('');
|
||||||
|
|
||||||
|
const filesHtml = fileEntries.map(([name, content]) => `
|
||||||
|
<div style="margin-bottom:16px;border:1px solid #30363d;border-radius:6px;overflow:hidden">
|
||||||
|
<div style="background:#161b22;padding:8px 12px;font-weight:600;color:#58a6ff">${name}</div>
|
||||||
|
<pre style="margin:0;padding:12px;background:#010409;font-size:12px;overflow-x:auto;white-space:pre-wrap;color:#c9d1d9">${(content || '').replace(/</g,'<')}</pre>
|
||||||
|
</div>`).join('');
|
||||||
|
|
||||||
|
const staticHtml = (staticIssues || []).length > 0
|
||||||
|
? `<div style="margin-bottom:16px;padding:12px;background:#1c1206;border:1px solid #d29922;border-radius:6px">
|
||||||
|
<strong style="color:#d29922">Staattinen analyysi (${staticIssues.length} huomautusta)</strong>
|
||||||
|
<ul style="margin:8px 0 0;padding-left:20px;color:#d29922">${staticIssues.map(i => `<li>${i}</li>`).join('')}</ul>
|
||||||
|
</div>`
|
||||||
|
: '<p style="color:#3fb950">✓ Staattinen analyysi: ei huomautuksia</p>';
|
||||||
|
|
||||||
|
return `<!DOCTYPE html>
|
||||||
|
<html lang="fi">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Kipinä Raportti — ${task}</title>
|
||||||
|
<style>
|
||||||
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: #0d1117; color: #c9d1d9; padding: 20px; max-width: 900px; margin: 0 auto; }
|
||||||
|
h1 { color: #58a6ff; margin-bottom: 4px; }
|
||||||
|
h2 { color: #c9d1d9; margin: 24px 0 12px; border-bottom: 1px solid #30363d; padding-bottom: 6px; }
|
||||||
|
h3 { color: #8b949e; margin: 16px 0 8px; }
|
||||||
|
pre { font-family: 'Courier New', monospace; }
|
||||||
|
a { color: #58a6ff; }
|
||||||
|
details summary { list-style: none; }
|
||||||
|
details summary::-webkit-details-marker { display: none; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>🔥 Kipinä Projektiraportti</h1>
|
||||||
|
<p style="color:#8b949e;margin-bottom:20px">${task} — ${new Date().toLocaleString('fi-FI')} — ${fileEntries.length} tiedostoa, ${steps.length} vaihetta</p>
|
||||||
|
|
||||||
|
<h2>📋 Pipeline-vaiheet</h2>
|
||||||
|
${stepsHtml}
|
||||||
|
|
||||||
|
<h2>🔍 Staattinen analyysi</h2>
|
||||||
|
${staticHtml}
|
||||||
|
|
||||||
|
<h2>📁 Tiedostot</h2>
|
||||||
|
${filesHtml}
|
||||||
|
|
||||||
|
<hr style="border-color:#30363d;margin:24px 0">
|
||||||
|
<p style="color:#8b949e;font-size:12px">Generoitu Kipinä Agentic Playground v0.2.2 — <a href="https://kipina.studio">kipina.studio</a></p>
|
||||||
|
</body></html>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Yksinkertainen pipeline (vanha: manageri → koodari → testaaja)
|
// Yksinkertainen pipeline (vanha: manageri → koodari → testaaja)
|
||||||
|
|||||||
Reference in New Issue
Block a user