/**
* Agent Index Search Widget
* Embed x402 endpoint search on any site
*
* Usage:
* <div id="agent-index-widget"></div>
* <script src="https://api.theagentindex.app/widget.js"></script>
* <script>AgentIndex.init({ container: '#agent-index-widget' })</script>
*/
(function() {
const API_BASE = 'https://api.theagentindex.app';
const styles = `
.ai-widget { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; max-width: 600px; }
.ai-widget * { box-sizing: border-box; }
.ai-search-box { display: flex; gap: 8px; margin-bottom: 16px; }
.ai-search-input { flex: 1; padding: 12px 16px; border: 1px solid #e0e0e0; border-radius: 8px; font-size: 14px; outline: none; }
.ai-search-input:focus { border-color: #64ffda; box-shadow: 0 0 0 2px rgba(100,255,218,0.2); }
.ai-search-btn { padding: 12px 20px; background: #0a0a0f; color: #64ffda; border: none; border-radius: 8px; cursor: pointer; font-weight: 600; }
.ai-search-btn:hover { background: #1a1a2f; }
.ai-results { display: flex; flex-direction: column; gap: 12px; }
.ai-result { padding: 16px; border: 1px solid #e0e0e0; border-radius: 8px; background: #fafafa; }
.ai-result:hover { border-color: #64ffda; }
.ai-result-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.ai-result-domain { font-weight: 600; color: #0a0a0f; }
.ai-result-tier { padding: 2px 8px; border-radius: 4px; font-size: 12px; font-weight: 600; }
.ai-tier-A { background: #d4edda; color: #155724; }
.ai-tier-B { background: #fff3cd; color: #856404; }
.ai-tier-C { background: #f8d7da; color: #721c24; }
.ai-result-desc { font-size: 14px; color: #666; margin-bottom: 8px; line-height: 1.4; }
.ai-result-meta { display: flex; gap: 16px; font-size: 12px; color: #888; }
.ai-result-price { color: #64ffda; font-weight: 600; }
.ai-powered { text-align: center; margin-top: 16px; font-size: 12px; color: #888; }
.ai-powered a { color: #64ffda; text-decoration: none; }
.ai-loading { text-align: center; padding: 20px; color: #888; }
.ai-empty { text-align: center; padding: 20px; color: #888; }
`;
window.AgentIndex = {
init: function(options = {}) {
const container = document.querySelector(options.container || '#agent-index-widget');
if (!container) return console.error('Agent Index: Container not found');
// Inject styles
const styleEl = document.createElement('style');
styleEl.textContent = styles;
document.head.appendChild(styleEl);
// Build widget HTML
container.innerHTML = \`
<div class="ai-widget">
<div class="ai-search-box">
<input type="text" class="ai-search-input" placeholder="Search x402 endpoints..." />
<button class="ai-search-btn">Search</button>
</div>
<div class="ai-results"></div>
<div class="ai-powered">Powered by <a href="https://theagentindex.app" target="_blank">Agent Index</a></div>
</div>
\`;
const input = container.querySelector('.ai-search-input');
const btn = container.querySelector('.ai-search-btn');
const results = container.querySelector('.ai-results');
const search = async () => {
const q = input.value.trim();
if (!q) return;
results.innerHTML = '<div class="ai-loading">Searching...</div>';
try {
const res = await fetch(\`\${API_BASE}/search?q=\${encodeURIComponent(q)}&limit=5\`);
const data = await res.json();
if (!data.results?.length) {
results.innerHTML = '<div class="ai-empty">No endpoints found</div>';
return;
}
results.innerHTML = data.results.map(r => \`
<div class="ai-result">
<div class="ai-result-header">
<span class="ai-result-domain">\${r.domain}</span>
<span class="ai-result-tier ai-tier-\${r.tier}">Tier \${r.tier}</span>
</div>
<div class="ai-result-desc">\${r.description?.slice(0,120) || 'No description'}...</div>
<div class="ai-result-meta">
<span class="ai-result-price">\$\${r.priceUsd?.toFixed(3) || '0.00'}/call</span>
<span>\${r.health}</span>
<span>\${r.category}</span>
</div>
</div>
\`).join('');
} catch (err) {
results.innerHTML = '<div class="ai-empty">Error searching. Try again.</div>';
}
};
btn.addEventListener('click', search);
input.addEventListener('keypress', e => e.key === 'Enter' && search());
// Initial search if query provided
if (options.query) {
input.value = options.query;
search();
}
}
};
})();