(() => { function parseSkill(text, node) { const source = String(text || '').trim(); const match = source.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/); const attributes = {}; const body = match ? match[2].trim() : source; const frontmatter = match ? match[1].split('\n') : []; for (const line of frontmatter) { const separatorIndex = line.indexOf(':'); if (separatorIndex === -1) { continue; } const key = line.slice(0, separatorIndex).trim(); const value = line.slice(separatorIndex + 1).trim(); if (key) { attributes[key] = value; } } if (!attributes.name || !attributes.description) { return null; } return { name: attributes.name, description: attributes.description, default: node.dataset.default === 'true', markdown: source, body, }; } const agentSkills = { skills: Object.create(null), reload() { this.skills = Object.create(null); for (const node of document.querySelectorAll('script[type="text/skill+markdown"]')) { const skill = parseSkill(node.textContent, node); if (skill) { this.skills[skill.name] = skill; } } return this.skills; }, list() { this.reload(); return Object.values(this.skills).map(({ name, description, default: isDefault }) => ({ name, description, default: isDefault, })); }, read(name) { this.reload(); return this.skills[name] || null; }, readDefault() { this.reload(); return Object.values(this.skills).filter((skill) => skill.default); }, }; window.agentSkills = agentSkills; agentSkills.reload(); })();