async function renderSkills() { const content = document.getElementById('pageContent'); content.innerHTML = `
`; try { const skills = await api.getSkills(); window._allSkills = skills; renderSkillGrid(skills); } catch (err) { document.getElementById('skillsContainer').innerHTML = `
โš 
${escapeHtml(err.message)}
`; } } function renderSkillGrid(skills) { const container = document.getElementById('skillsContainer'); if (!skills || skills.length === 0) { container.innerHTML = '
โšก
No skills installed
'; return; } container.innerHTML = `
${skills.map(s => { const lastScore = s.scores && s.scores.length > 0 ? s.scores[s.scores.length - 1] : null; const avg = lastScore && lastScore.criteria_scores ? (lastScore.criteria_scores.reduce((a, b) => a + b, 0) / lastScore.criteria_scores.length) : null; const icons = ['โšก', '๐Ÿ”ง', '๐Ÿ“', '๐Ÿ”', '๐Ÿ”„', '๐ŸŽฏ', '๐Ÿ“Š', '๐Ÿ› ', '๐Ÿ’ก', '๐Ÿงช', '๐Ÿ“‹', '๐Ÿ’พ', '๐Ÿ’ฐ', '๐Ÿ”„', '๐ŸŽจ']; const iconIdx = s.name.split('').reduce((a, c) => a + c.charCodeAt(0), 0) % icons.length; const icon = icons[iconIdx]; return `
${icon}
${s.name.replace(/-/g, ' ')}
${s.description ? s.description.slice(0, 120) + (s.description.length > 120 ? '...' : '') : 'No description'}
`; }).join('')}
`; } function switchSkillView(view) { document.querySelectorAll('#skillTabs .tab').forEach(t => t.classList.toggle('active', t.dataset.view === view)); if (view === 'list') { const skills = window._allSkills || []; document.getElementById('skillsContainer').innerHTML = `
${skills.map(s => { const lastScore = s.scores && s.scores.length > 0 ? s.scores[s.scores.length - 1] : null; const avg = lastScore && lastScore.criteria_scores ? (lastScore.criteria_scores.reduce((a, b) => a + b, 0) / lastScore.criteria_scores.length) : null; return ``; }).join('')}
SkillScoreLearnings
${s.name.replace(/-/g, ' ')} ${avg !== null ? `${(avg * 100).toFixed(0)}%` : 'โ€”'} ${s.has_learnings ? 'โœ“' : 'โ€”'}
`; } else { renderSkillGrid(window._allSkills || []); } } function filterSkills() { const q = document.getElementById('skillFilter').value.toLowerCase(); const skills = (window._allSkills || []).filter(s => s.name.toLowerCase().includes(q)); renderSkillGrid(skills); } async function showSkillDetail(name) { document.getElementById('skillsContainer').style.display = 'none'; document.getElementById('skillTabs').style.display = 'none'; document.getElementById('skillFilter').style.display = 'none'; const detail = document.getElementById('skillDetail'); detail.style.display = 'block'; detail.innerHTML = `
`; try { const skill = await api.getSkill(name); const scores = skill.score_history || []; const lastScore = scores.length > 0 ? scores[scores.length - 1] : null; const avg = lastScore && lastScore.criteria_scores ? (lastScore.criteria_scores.reduce((a, b) => a + b, 0) / lastScore.criteria_scores.length) : null; detail.innerHTML = `
๐Ÿ“„ SKILL.md
${escapeHtml(skill.skill || 'No SKILL.md')}
๐Ÿ“– Learnings
${escapeHtml(skill.learnings || 'No learnings yet')}
๐Ÿ“Š Performance
${scores.length > 0 ? `
${scores.slice(-10).map(s => `${((s.total_score || 0) * 100).toFixed(0)}%`).join('')}
Average: ${avg !== null ? (avg * 100).toFixed(0) : 'N/A'}% (${scores.length} runs)
` : '
No evaluation scores yet
'}
๐Ÿ“ Context Files
${skill.context && skill.context.length > 0 ? `
${skill.context.map(f => `${f}`).join('')}
` : '
No context files
'} ${skill.eval && skill.eval.criteria ? `
Eval Criteria:
${skill.eval.criteria.map(c => `${c}`).join('')}
` : ''}
`; } catch (err) { detail.innerHTML = `
โš 
Error
${escapeHtml(err.message)}
`; } } function backToSkills() { document.getElementById('skillsContainer').style.display = ''; document.getElementById('skillTabs').style.display = ''; document.getElementById('skillFilter').style.display = ''; document.getElementById('skillDetail').style.display = 'none'; } async function quickRunSkill(name) { const displayName = name.replace(/-/g, ' '); showModal(`Run: ${displayName}`, `
`, ` `); } async function executeSkillRun(name) { const input = document.getElementById('qrsInput').value; const agent = document.getElementById('qrsAgent').value; try { const r = await api.runSkill(name, input, agent); closeModal(); showToast(`"${name}" dispatched to ${r.agent} #${r.run_id}`, 'success'); } catch (err) { showToast(`Error: ${err.message}`, 'error'); } }