Raportti: Mermaid → custom swimlane (kompakti, tooltipsit)

Agenteittain ryhmitelty visualisointi:
  Manageri  ✓ Suunnittelu
  Koodari   ✓ models.py → ✓ main.py → ✓ index.html
  DevOps    ✓ Review → ✓ Dockerfile → ✓ Compose → ✓ README
  QA        ✓ Testit → ✓ Validointi
Hover näyttää selityksen + output-esikatselun.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-07 11:39:23 +03:00
parent 01622a960f
commit 1b75c89320

View File

@@ -2828,9 +2828,7 @@ ${fixableFiles}`;
<p style="color:#8b949e;margin-bottom:20px">${task}${new Date().toLocaleString('fi-FI')}${fileEntries.length} tiedostoa, ${steps.length} vaihetta</p>
<h2>🔄 Agenttien workflow</h2>
<div class="mermaid">
${generateMermaidDiagram(steps)}
</div>
${generateWorkflowSwimlane(steps)}
<h2>📋 Pipeline-vaiheet</h2>
${stepsHtml}
@@ -2843,41 +2841,44 @@ ${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>
<` + `script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true, theme: 'dark', themeVariables: { primaryColor: '#58a6ff', primaryTextColor: '#c9d1d9', lineColor: '#30363d', primaryBorderColor: '#30363d' } });
</` + `script>
</body></html>`;
}
function generateMermaidDiagram(steps) {
function generateWorkflowSwimlane(steps) {
const agentLabels = { manager: 'Manageri', coder: 'Koodari', tester: 'DevOps', qa: 'QA', data: 'Data' };
const agentStyles = { manager: 'fill:#1c1206,stroke:#d29922,color:#d29922', coder: 'fill:#0d1a0d,stroke:#3fb950,color:#3fb950', tester: 'fill:#0d1117,stroke:#58a6ff,color:#58a6ff', qa: 'fill:#170d22,stroke:#a371f7,color:#a371f7', data: 'fill:#1a0d22,stroke:#d2a8ff,color:#d2a8ff' };
const agentColors = { manager: '#d29922', coder: '#3fb950', tester: '#58a6ff', qa: '#a371f7', data: '#d2a8ff' };
const agentBgs = { manager: '#1c1206', coder: '#0d1a0d', tester: '#0d1520', qa: '#170d22', data: '#1a0d22' };
const stepDescs = { 'Suunnittelu': 'Jakaa projektin tiedostoiksi', 'Review': 'Tarkistaa koodin laadun', 'Testit': 'Kirjoittaa pytest-testit', 'Dockerfile': 'Generoi Docker-imagen', 'Compose': 'Palvelumääritys', 'README': 'Käyttöohjeet', 'Validointi': 'Tarkistaa yhteensopivuuden', 'Korjaukset': 'Korjaa löydetyt ongelmat' };
let lines = ['graph LR'];
let prevId = null;
steps.forEach((s, i) => {
const id = `S${i}`;
const agent = agentLabels[s.agent] || s.agent;
const label = s.label.replace(/"/g, "'").replace(/[<>]/g, '');
const desc = stepDescs[s.label] || s.label;
const outputPreview = (s.output || '').substring(0, 80).replace(/"/g, "'").replace(/\n/g, ' ').replace(/[<>]/g, '');
lines.push(` ${id}["${agent}<br/>${label}"]`);
// Mermaid tooltip: click event + title
lines.push(` click ${id} callback "${desc}${outputPreview ? ' — ' + outputPreview : ''}"`);
if (prevId) {
lines.push(` ${prevId} --> ${id}`);
var agents = [];
var agentMap = {};
for (var si = 0; si < steps.length; si++) {
var s = steps[si];
if (!agentMap[s.agent]) { agentMap[s.agent] = []; agents.push(s.agent); }
agentMap[s.agent].push(s);
}
if (agentStyles[s.agent]) {
lines.push(` style ${id} ${agentStyles[s.agent]}`);
}
prevId = id;
});
return lines.join('\n');
var rows = '';
for (var ai = 0; ai < agents.length; ai++) {
var agent = agents[ai];
var color = agentColors[agent] || '#8b949e';
var bg = agentBgs[agent] || '#161b22';
var label = agentLabels[agent] || agent;
var badges = '';
var aSteps = agentMap[agent];
for (var bi = 0; bi < aSteps.length; bi++) {
var st = aSteps[bi];
var desc = stepDescs[st.label] || st.label;
var outPrev = (st.output || '').substring(0, 100).replace(/</g, '&lt;').replace(/\n/g, ' ');
var tip = desc + (outPrev ? ' — ' + outPrev : '');
var icon = st.status === 'done' ? '✓' : '◷';
if (bi > 0) badges += '<span style="color:#30363d;margin:0 1px">→</span>';
badges += '<span title="' + tip.replace(/"/g, '&quot;') + '" style="display:inline-block;background:' + bg + ';border:1px solid ' + color + ';border-radius:4px;padding:3px 8px;margin:2px;font-size:11px;color:' + color + ';cursor:help;white-space:nowrap">' + icon + ' ' + st.label.replace(/</g, '&lt;') + '</span>';
}
rows += '<div style="display:flex;align-items:center;gap:8px;margin:4px 0"><span style="min-width:70px;font-weight:600;font-size:12px;color:' + color + '">' + label + '</span><div style="display:flex;flex-wrap:wrap;align-items:center">' + badges + '</div></div>';
}
return '<div style="background:#0d1117;border:1px solid #30363d;border-radius:6px;padding:12px">' + rows + '</div>';
}
// Yksinkertainen pipeline (vanha: manageri → koodari → testaaja)