// AGENTFORGE-IA — Marketplace const Marketplace = ({ data, openAgent, openCategory, activeCategory, setActiveCategory }) => { const [q, setQ] = React.useState(''); const [sort, setSort] = React.useState('popular'); const cats = Array.isArray(data?.categories) ? data.categories : []; const agents = Array.isArray(data?.agents) ? data.agents : []; const resultsRef = React.useRef(null); const selectCategory = (id) => { setActiveCategory(id); setTimeout(() => { if (resultsRef.current) { resultsRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }, 60); }; // Contadores reales por categoría const catCounts = React.useMemo(() => { const counts = {}; agents.forEach(a => { counts[a.cat] = (counts[a.cat] || 0) + 1; }); return counts; }, [agents]); const featured = React.useMemo(() => { if (agents.length === 0) { return null; } return [...agents] .sort((a, b) => (Number(b.runs) || 0) - (Number(a.runs) || 0))[0] || null; }, [agents]); const filtered = agents.filter(a => { if (activeCategory && activeCategory !== 'all' && a.cat !== activeCategory) return false; const name = (a.name || '').toLowerCase(); const tagline = (a.tagline || '').toLowerCase(); if (q && !(name.includes(q.toLowerCase()) || tagline.includes(q.toLowerCase()))) return false; return true; }).sort((a,b) => sort === 'popular' ? (Number(b.runs) || 0) - (Number(a.runs) || 0) : sort === 'rating' ? (Number(b.rating) || 0) - (Number(a.rating) || 0) : (Number(b.runs) || 0) - (Number(a.runs) || 0)); const totalAgents = agents.length; const visibleCats = cats.filter(c => (catCounts[c.id] || 0) > 0); return (

Marketplace

explorar {totalAgents} agentes · {visibleCats.length} categorías
setQ(e.target.value)} /> ⌘K
Tendencias {['triaje de tickets','brief SEO','revisor de PRs','onboarding','investigación profunda','redlines de contratos'].map(t => ( ))}
Explorar por categoría · {totalAgents} agentes en {visibleCats.length} categorías
{visibleCats.map(c => ( ))}
Destacado esta semana
{featured ? (
openAgent(featured.id)}>
ELECCIÓN DEL EDITOR investigación

{featured.name || 'Agente destacado'}

{featured.tagline || 'Agente recomendado por actividad y adopción.'} Planificación multietapa, fuentes recursivas y citas trazables.

{(Math.max(0, Number(featured.runs) || 0)/1000).toFixed(0)} k ejecuciones {Number(featured.rating || 0).toString().replace('.', ',')} ({Number(featured.reviews) || 0}) {featured.author || 'Forge Labs'}
web.search
arxiv.fetch
memo.synth
Investigación Profunda
) : (

Sin agente destacado

Todavía no hay agentes suficientes para destacar uno en esta sección.

)}
{activeCategory && activeCategory !== 'all' ? cats.find(c=>c.id===activeCategory)?.name : 'Agentes destacados'} · {filtered.length} resultados {activeCategory && activeCategory !== 'all' && ( )}
{filtered.map(a => c.id === a.cat)} onOpen={() => openAgent(a.id)} />)}
); }; function AgentCard({ a, cat, onOpen }) { const tools = (Array.isArray(a.tools) ? a.tools : []).filter(t => !/slack|zendesk/i.test(String(t))); const runs = Number(a.runs) || 0; const rating = Number(a.rating) || 0; const reviews = Number(a.reviews) || 0; return (
{a.name} {a.verified && }
{a.author} · {cat?.name}
{String(a.price || '').toLowerCase().includes('gratis') ? 'De pago' : a.price}

{a.tagline}

{tools.slice(0,3).map(t => {t})} {tools.length > 3 && +{tools.length - 3}}
{runs > 999 ? (runs/1000).toFixed(0)+' k' : runs} {rating.toString().replace('.', ',')} {reviews}
); } window.Marketplace = Marketplace;