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 = '';
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 `
${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 = `| Skill | Score | Learnings | |
${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 `
| ${s.name.replace(/-/g, ' ')} |
${avg !== null ? `${(avg * 100).toFixed(0)}%` : 'โ'} |
${s.has_learnings ? 'โ' : 'โ'} |
|
`;
}).join('')}
`;
} 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 = `
${escapeHtml(skill.skill || 'No SKILL.md')}
${escapeHtml(skill.learnings || 'No learnings yet')}
${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
'}
${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;
const runBtn = document.querySelector('#modalContainer .btn-primary');
const resultArea = document.getElementById('skillResult');
if (runBtn) { runBtn.disabled = true; runBtn.textContent = 'โณ Running...'; }
if (resultArea) {
resultArea.style.display = 'block';
resultArea.innerHTML = '';
}
try {
const r = await api.runSkill(name, input, agent);
if (resultArea) {
const outputText = r.output || '(no output)';
resultArea.innerHTML = `
${escapeHtml(outputText)}
`;
}
if (runBtn) { runBtn.textContent = 'โ Done'; runBtn.disabled = false; }
} catch (err) {
if (resultArea) {
resultArea.innerHTML = `โ
Error
${escapeHtml(err.message)}
`;
}
if (runBtn) { runBtn.textContent = 'โถ Run'; runBtn.disabled = false; }
}
}