diff --git a/design-system.css b/design-system.css index e7274c9..7f976b7 100644 --- a/design-system.css +++ b/design-system.css @@ -1789,23 +1789,21 @@ html:has(body.agentrust-hub) { scroll-behavior: smooth; } .marketplace-callout h3 { margin:.3rem 0;font-size:1.25rem; }.marketplace-callout p { color:var(--muted);font-size:.9rem; } .marketplace-page { background:var(--at-paper); }.marketplace-page main { overflow:hidden; }.marketplace-page .site-header { position:relative;background:var(--at-paper); } .marketplace-page .site-header [aria-current="page"] { color:var(--at-red); }.marketplace-page .button { display:inline-flex;align-items:center;justify-content:center; } -.market-hero { position:relative;padding:clamp(4.5rem,9vw,8rem) 0;background:var(--at-ink);color:var(--at-paper); } -.market-hero::before { position:absolute;inset:0;background:radial-gradient(circle at 78% 45%,rgba(242,90,57,.2),transparent 24%),linear-gradient(115deg,transparent 66%,rgba(255,255,255,.03) 66%);content:"";pointer-events:none; } -.market-hero-grid { position:relative;display:grid;grid-template-columns:minmax(0,1.55fr) minmax(280px,.7fr);align-items:center;gap:clamp(3rem,8vw,8rem); } -.market-hero h1 { max-width:850px;margin:.8rem 0 1.4rem;color:#fff;font-family:var(--at-serif);font-size:clamp(3rem,7vw,6.4rem);font-weight:500;letter-spacing:-.055em;line-height:.94; } -.market-hero h1 em { color:var(--at-red);font-style:italic; }.market-intro { max-width:720px;color:rgba(255,255,255,.68);font-size:clamp(1rem,1.4vw,1.22rem);line-height:1.7; } -.market-hero-actions { display:flex;flex-wrap:wrap;gap:.8rem;margin-top:2rem; }.market-hero .button.secondary { border-color:rgba(255,255,255,.25);color:#fff; } -.market-signal { position:relative;padding:2rem;border:1px solid rgba(255,255,255,.14);border-radius:18px;background:rgba(255,255,255,.035);box-shadow:0 24px 70px rgba(0,0,0,.22); } -.signal-orbit { position:relative;height:175px;margin-bottom:1.8rem;border:1px solid rgba(255,255,255,.12);border-radius:50%; } -.signal-orbit::before,.signal-orbit::after { position:absolute;inset:23%;border:1px solid rgba(242,90,57,.3);border-radius:50%;content:""; }.signal-orbit::after { inset:46%;background:var(--at-red);border:0; } -.signal-orbit span { position:absolute;padding:.28rem .55rem;border:1px solid rgba(255,255,255,.16);border-radius:999px;background:var(--at-ink);color:rgba(255,255,255,.72);font-family:var(--at-mono);font-size:.6rem;letter-spacing:.08em; }.signal-orbit span:nth-child(1){top:8%;left:43%}.signal-orbit span:nth-child(2){right:3%;bottom:25%}.signal-orbit span:nth-child(3){bottom:8%;left:5%} -.market-signal p { display:flex;align-items:baseline;justify-content:space-between;margin:0;padding:.8rem 0;border-top:1px solid rgba(255,255,255,.1);color:rgba(255,255,255,.62);font-size:.78rem; }.market-signal p strong { color:#fff;font-family:var(--at-serif);font-size:1.7rem;font-weight:500; } +.market-hero { position:relative;padding:clamp(3.5rem,7vw,6rem) 0;border-top:1px solid var(--at-line);border-bottom:1px solid var(--at-line);background:linear-gradient(135deg,var(--at-paper) 0%,#f4f0e8 72%,#eee8dc 100%);color:var(--at-ink); } +.market-hero::before { position:absolute;top:0;right:10%;width:220px;height:4px;background:var(--at-red);content:""; } +.market-hero-grid { position:relative;display:grid;grid-template-columns:minmax(0,1.45fr) minmax(280px,.65fr);align-items:center;gap:clamp(2.5rem,7vw,7rem); } +.market-hero h1 { max-width:780px;margin:.8rem 0 1.25rem;color:var(--at-ink);font-family:var(--at-serif);font-size:clamp(2.8rem,5.6vw,5.2rem);font-weight:500;letter-spacing:-.05em;line-height:.98; } +.market-hero h1 em { color:var(--at-red);font-style:italic; }.market-intro { max-width:690px;color:var(--at-muted);font-size:clamp(1rem,1.3vw,1.16rem);line-height:1.7; } +.market-hero-actions { display:flex;flex-wrap:wrap;gap:.8rem;margin-top:1.8rem; }.market-hero .button.secondary { border-color:var(--at-line);color:var(--at-ink);background:rgba(255,255,255,.45); } +.market-signal { position:relative;padding:1.7rem;border:1px solid var(--at-line);border-radius:16px;background:rgba(255,255,255,.64);box-shadow:0 18px 50px rgba(19,19,19,.05); } +.market-signal p { display:flex;align-items:baseline;justify-content:space-between;gap:1.5rem;margin:0;padding:.8rem 0;border-bottom:1px solid var(--at-line);color:var(--at-muted);font-size:.76rem; }.market-signal p:first-child{padding-top:0}.market-signal p strong { color:var(--at-ink);font-family:var(--at-serif);font-size:1.65rem;font-weight:500; }.market-signal small{display:block;margin-top:1rem;color:var(--at-muted);font-size:.66rem;line-height:1.5}.market-signal small.catalog-warning{color:#8b5b20} .market-featured,.market-browser { padding:clamp(4rem,8vw,7rem) 0; }.market-featured { background:#f0ede6; }.market-section-heading { display:flex;align-items:flex-end;justify-content:space-between;gap:2rem;margin-bottom:2rem; } .market-section-heading h2,.market-submit h2 { margin-top:.45rem;font-family:var(--at-serif);font-size:clamp(2rem,4vw,3.5rem);font-weight:500;letter-spacing:-.035em;line-height:1.05; }.market-section-heading>a { color:var(--at-ink);font-size:.8rem;font-weight:700; } .featured-strip,.market-grid { display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1rem; }.market-card { display:flex;min-height:360px;flex-direction:column;justify-content:space-between;padding:1.4rem;border:1px solid var(--at-line);border-radius:16px;background:var(--at-white);transition:transform .2s,border-color .2s,box-shadow .2s; } .market-card:hover { transform:translateY(-3px);border-color:rgba(19,19,19,.35);box-shadow:0 16px 35px rgba(19,19,19,.07); }.market-card-featured { min-height:330px; } .market-card-top { display:flex;align-items:flex-start;justify-content:space-between;gap:1rem; }.market-mark { display:flex;width:50px;height:50px;align-items:center;justify-content:center;border-radius:13px;background:var(--at-ink);color:#fff;font-family:var(--at-mono);font-size:.82rem;font-weight:700;letter-spacing:-.02em; } .mark-frameworks{background:#5d3fd3}.mark-observability{background:#a43c78}.mark-security-policy{background:#173d34}.mark-identity-trust{background:#304b83}.mark-compliance{background:#7b4825}.mark-evidence-receipts{background:#604070} +.mark-agt-integrations{background:#315b78}.tier-project i{background:#4c7fa3} .market-tier { display:inline-flex;align-items:center;gap:.4rem;color:var(--at-muted);font-size:.65rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase; }.market-tier i { width:7px;height:7px;border-radius:50%;background:#3b9f78; } .market-vendor { margin-top:2rem;color:var(--at-muted);font-size:.69rem;font-weight:650;letter-spacing:.05em;text-transform:uppercase; }.market-card h3 { margin:.35rem 0 .65rem;font-family:var(--at-serif);font-size:1.5rem;font-weight:600;letter-spacing:-.025em; }.market-description { color:var(--at-muted);font-size:.88rem;line-height:1.6; } .market-card-foot { margin-top:1.5rem;padding-top:1rem;border-top:1px solid var(--at-line); }.market-tags { display:flex;flex-wrap:wrap;gap:.35rem;margin-bottom:1rem; }.market-tags span { padding:.25rem .5rem;border-radius:999px;background:var(--at-paper-2);color:var(--at-muted);font-family:var(--at-mono);font-size:.62rem; }.market-card-foot>a { display:flex;justify-content:space-between;color:var(--at-ink);font-size:.78rem;font-weight:750;text-decoration:none; }.market-card-foot>a:hover { color:var(--at-red); } @@ -1815,7 +1813,7 @@ html:has(body.agentrust-hub) { scroll-behavior: smooth; } .market-layout { display:grid;grid-template-columns:220px 1fr;align-items:start;gap:2.2rem; }.market-filters { position:sticky;top:1.5rem; }.filter-group { padding:0 0 1.4rem;margin-bottom:1.4rem;border-bottom:1px solid var(--at-line); }.filter-group>p { margin-bottom:.75rem;font-size:.7rem;font-weight:800;letter-spacing:.09em;text-transform:uppercase; }.filter-group label { display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:.55rem;padding:.45rem 0;color:var(--at-muted);font-size:.78rem;cursor:pointer; }.filter-group input { accent-color:var(--at-red); }.filter-group b { color:#999;font-size:.68rem;font-weight:500; }.clear-filters { padding:0;border:0;background:none;color:var(--at-red);font:inherit;font-size:.72rem;font-weight:750;cursor:pointer; }.neutrality-note { margin-top:2rem;padding:1rem;border-left:2px solid var(--at-line);color:var(--at-muted);font-size:.7rem;line-height:1.55; } .market-grid { grid-template-columns:repeat(2,minmax(0,1fr)); }.active-filters { display:flex;flex-wrap:wrap;gap:.45rem;margin-bottom:1rem; }.active-filters:empty { display:none; }.active-filters button { padding:.35rem .6rem;border:1px solid var(--at-line);border-radius:999px;background:var(--at-white);color:var(--at-muted);font-size:.68rem;cursor:pointer; } .market-empty { padding:5rem 2rem;border:1px dashed var(--at-line);border-radius:16px;text-align:center; }.market-empty span { color:var(--at-red);font-size:.68rem;font-weight:800;letter-spacing:.1em;text-transform:uppercase; }.market-empty h3 { margin:.7rem 0;font-family:var(--at-serif);font-size:2rem; }.market-empty p { margin-bottom:1.4rem;color:var(--at-muted); } -.market-submit { padding:clamp(4rem,8vw,7rem) 0;background:var(--at-red);color:#fff; }.market-submit .eyebrow { color:rgba(255,255,255,.7); }.submit-grid { display:grid;grid-template-columns:1fr 1fr;align-items:center;gap:clamp(2rem,8vw,7rem); }.market-submit p { max-width:580px;color:rgba(255,255,255,.78);line-height:1.7; }.market-submit .button { margin-top:1.5rem;background:var(--at-ink);color:#fff; } +.market-submit { padding:clamp(3.5rem,7vw,5.5rem) 0;border-top:1px solid var(--at-line);background:#ece7dd;color:var(--at-ink); }.market-submit .eyebrow { color:var(--at-red); }.submit-grid { display:grid;grid-template-columns:1fr 1fr;align-items:center;gap:clamp(2rem,8vw,7rem); }.market-submit p { max-width:580px;color:var(--at-muted);line-height:1.7; }.market-submit .button { margin-top:1.5rem;background:var(--at-ink);color:#fff; } .marketplace-page [hidden] { display:none!important; }.sr-only { position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0; } @media(max-width:860px){.marketplace-callout,.market-section-heading{align-items:flex-start;flex-direction:column}.market-hero-grid,.market-layout,.submit-grid{grid-template-columns:1fr}.market-signal{max-width:440px}.featured-strip,.market-grid{grid-template-columns:1fr}.market-filters{position:static;display:grid;grid-template-columns:1fr 1fr;gap:1rem}.neutrality-note{grid-column:1/-1;margin-top:0}.market-search-row{grid-template-columns:1fr}.market-sort{padding-left:0}.market-card{min-height:315px}} @media(max-width:560px){.market-hero h1 br{display:none}.market-filters{grid-template-columns:1fr}.neutrality-note{grid-column:auto}.market-search kbd{display:none}} diff --git a/index.html b/index.html index 090fee8..dda744b 100644 --- a/index.html +++ b/index.html @@ -194,7 +194,7 @@ ] } - + diff --git a/marketplace/index.html b/marketplace/index.html index 3963113..556aa72 100644 --- a/marketplace/index.html +++ b/marketplace/index.html @@ -8,20 +8,20 @@ - +
-

The open ecosystem, ready to build

Find your way into
verifiable AI.

Discover community-built plugins, adapters, enforcement tools, and evidence exporters that connect real agent stacks to TRACE, Confidential MCP, and Agent Manifest.

+

AgenTrust Marketplace

Build with the
verifiable AI ecosystem.

Find integrations across AgenTrust and the Microsoft Agent Governance Toolkit—from framework adapters to policy enforcement and portable trust evidence.

Explore the ecosystem

Find the right integration

15 integrations

-
+

Make the ecosystem bigger

Your integration belongs here.

Connect a framework, platform, policy engine, or governance product to the AgenTrust stack. The submission path is public, self-serve, and governed by the same rules for everyone.

List your integration ↗
- + diff --git a/marketplace/marketplace.js b/marketplace/marketplace.js index 8b99c6e..248f666 100644 --- a/marketplace/marketplace.js +++ b/marketplace/marketplace.js @@ -1,30 +1,65 @@ -(function(){'use strict'; -const base='https://github.com/agentrust-io/integrations/tree/main/'; -const items=[ -{name:'Claude Code',vendor:'agentrust-io',path:'claude-code',stack:['Agent Manifest','TRACE'],type:'Developer tools',mark:'CC',featured:1,description:'Emits a signed Agent Manifest and TRACE record per session, with composition-drift detection.'}, -{name:'agentrust-codex',vendor:'agentrust-io',path:'plugins/agentrust-codex',stack:['Agent Manifest','TRACE'],type:'Developer tools',mark:'CX',featured:2,description:'Fingerprints Codex agent configuration, detects workspace drift, and emits signed trust evidence.'}, -{name:'LangChain',vendor:'agentrust-io',path:'integrations/langchain',stack:['TRACE'],type:'Frameworks',mark:'LC',featured:3,description:'Emits a TRACE Trust Record from a LangChain run through a payload-safe callback handler.'}, -{name:'LlamaIndex',vendor:'agentrust-io',path:'integrations/llamaindex',stack:['TRACE'],type:'Frameworks',mark:'LI',featured:4,description:'Turns LlamaIndex instrumentation events into TRACE records using an explicit payload allow-list.'}, -{name:'OpenTelemetry GenAI',vendor:'agentrust-io',path:'integrations/otel-genai',stack:['TRACE'],type:'Observability',mark:'OT',featured:5,description:'Builds a TRACE Trust Record from OpenTelemetry GenAI spans as an unsigned telemetry import.'}, -{name:'Agent Sentinel',vendor:'a1k7',path:'integrations/sentinel',stack:['TRACE'],type:'Security & policy',mark:'AS',featured:6,description:'Detects delegation escalation, tool drift, identity drift, and policy avoidance across agent fleets.'}, -{name:'Agent Passport System',vendor:'aeoess',path:'integrations/aeoess-aps',stack:['TRACE'],type:'Identity & trust',mark:'AP',description:'Maps a verified, Ed25519-signed Agent Passport policy decision onto a TRACE Trust Record.'}, -{name:'Agentic SpendGuard',vendor:'SpendGuard',path:'integrations/spendguard',stack:['TRACE'],type:'Security & policy',mark:'$G',description:'Gates agent tool calls against reserved budget and creates a signed, hash-chained decision record.'}, -{name:'comply54',vendor:'comply54',path:'integrations/comply54',stack:['TRACE'],type:'Compliance',mark:'C5',description:'Maps African regulatory policy decisions from comply54 into signed TRACE evidence.'}, -{name:'DecisionAssure',vendor:'DecisionAssure',path:'integrations/decisionassure',stack:['TRACE'],type:'Security & policy',mark:'DA',description:'Converts a runtime governance trace into a third-party-asserted TRACE Trust Record.'}, -{name:'Nobulex',vendor:'Nobulex',path:'integrations/nobulex',stack:['TRACE'],type:'Evidence & receipts',mark:'NX',description:'Produces signed, canonical action receipts usable as external execution evidence in TRACE.'}, -{name:'ramen-ai cMCP Adapter',vendor:'ramen-ai',path:'integrations/ramen-ai-cmcp',stack:['cMCP','TRACE'],type:'Evidence & receipts',mark:'RA',description:'Verifies cMCP receipts and exports a natively signed, software-only TRACE Trust Record.'}, -{name:'SAGE AgenTrust Bridge',vendor:'SAGE',path:'integrations/sage-agenttrust',stack:['cMCP','TRACE'],type:'Security & policy',mark:'SG',description:'Verifies TRACE or cMCP runtime evidence before admitting memory to a SAGE consensus node.'}, -{name:'Shadow AI Discovery',vendor:'agentrust-io',path:'integrations/shadow-ai',stack:['cMCP','Agent Manifest'],type:'Identity & trust',mark:'SH',description:'Finds undeclared agents making MCP tool calls and creates discovery events for remediation.'}, -{name:'Scheduled Agents',vendor:'agentrust-io',path:'scheduled-agents',stack:['TRACE'],type:'Developer tools',mark:'SA',description:'Detects drift in unattended agent routines and emits a signed TRACE record for each run.'} -]; -const stacks=['TRACE','cMCP','Agent Manifest'],types=[...new Set(items.map(x=>x.type))].sort(),state={query:'',stacks:new Set(),types:new Set(),sort:'featured'},search=document.getElementById('market-search'),grid=document.getElementById('market-grid'),empty=document.getElementById('market-empty'); -const slug=v=>v.toLowerCase().replace(/[^a-z0-9]+/g,'-').replace(/(^-|-$)/g,''); -function esc(v){const n=document.createElement('span');n.textContent=v;return n.innerHTML} -function card(x,compact){const tags=x.stack.map(t=>`${esc(t)}`).join('');return `
${esc(x.mark)} Community

By ${esc(x.vendor)}

${esc(x.name)}

${esc(x.description)}

${tags}
View integration
`} -function addFilters(id,values,key){document.getElementById(id).innerHTML=values.map(v=>{const count=items.filter(x=>key==='stacks'?x.stack.includes(v):x.type===v).length,input=`${key}-${slug(v)}`;return ``}).join('')} -function render(){const words=state.query.toLowerCase().trim().split(/\s+/).filter(Boolean);let shown=items.filter(x=>{const hay=[x.name,x.vendor,x.type,x.description,...x.stack].join(' ').toLowerCase();return words.every(w=>hay.includes(w))&&(!state.stacks.size||[...state.stacks].every(s=>x.stack.includes(s)))&&(!state.types.size||state.types.has(x.type))});if(state.sort==='az')shown.sort((a,b)=>a.name.localeCompare(b.name));else if(state.sort==='za')shown.sort((a,b)=>b.name.localeCompare(a.name));else shown.sort((a,b)=>(a.featured||99)-(b.featured||99)||a.name.localeCompare(b.name));grid.innerHTML=shown.map(x=>card(x)).join('');grid.hidden=!shown.length;empty.hidden=!!shown.length;document.getElementById('result-count').textContent=shown.length;document.getElementById('result-label').textContent=shown.length===1?'integration':'integrations';const chips=[];if(state.query)chips.push(``);state.stacks.forEach(v=>chips.push(``));state.types.forEach(v=>chips.push(``));document.getElementById('active-filters').innerHTML=chips.join('');const p=new URLSearchParams;if(state.query)p.set('q',state.query);if(state.stacks.size)p.set('stack',[...state.stacks].join(','));if(state.types.size)p.set('type',[...state.types].join(','));if(state.sort!=='featured')p.set('sort',state.sort);history.replaceState(null,'',`${location.pathname}${p.size?'?'+p:''}${location.hash}`)} -function clear(){state.query='';state.stacks.clear();state.types.clear();state.sort='featured';search.value='';document.getElementById('market-sort').value='featured';document.querySelectorAll('[data-filter]').forEach(i=>i.checked=false);render()} -addFilters('stack-filters',stacks,'stacks');addFilters('type-filters',types,'types');document.getElementById('featured-list').innerHTML=items.filter(x=>x.featured&&x.featured<=3).map(x=>card(x,true)).join('');document.getElementById('hero-count').textContent=items.length; -const params=new URLSearchParams(location.search);state.query=params.get('q')||'';state.sort=['az','za'].includes(params.get('sort'))?params.get('sort'):'featured';(params.get('stack')||'').split(',').filter(v=>stacks.includes(v)).forEach(v=>state.stacks.add(v));(params.get('type')||'').split(',').filter(v=>types.includes(v)).forEach(v=>state.types.add(v));search.value=state.query;document.getElementById('market-sort').value=state.sort;document.querySelectorAll('[data-filter]').forEach(i=>i.checked=state[i.dataset.filter].has(i.value)); -search.addEventListener('input',()=>{state.query=search.value;render()});document.getElementById('market-sort').addEventListener('change',e=>{state.sort=e.target.value;render()});document.querySelectorAll('[data-filter]').forEach(i=>i.addEventListener('change',()=>{const set=state[i.dataset.filter];i.checked?set.add(i.value):set.delete(i.value);render()}));document.getElementById('active-filters').addEventListener('click',e=>{const b=e.target.closest('button');if(!b)return;if(b.dataset.clear==='query'){state.query='';search.value=''}else{state[b.dataset.clear].delete(b.dataset.value);const i=[...document.querySelectorAll('[data-filter]')].find(x=>x.value===b.dataset.value);if(i)i.checked=false}render()});document.getElementById('clear-filters').addEventListener('click',clear);document.getElementById('empty-clear').addEventListener('click',clear);document.addEventListener('keydown',e=>{if(e.key==='/'&&!/input|select|textarea/i.test(document.activeElement.tagName)){e.preventDefault();search.focus()}});render(); +(async function () { + 'use strict'; + const AGENTRUST_CATALOG = 'https://raw.githubusercontent.com/agentrust-io/integrations/main/marketplace/catalog.json'; + const AGT_DIRECTORY = 'https://api.github.com/repos/microsoft/agent-governance-toolkit/contents/agent-governance-python/agentmesh-integrations?ref=main'; + const AGT_NAMES = { + 'a2a-protocol': 'A2A Protocol', 'adk-agentmesh': 'Google ADK', 'agentmesh-avp': 'AgentMesh AVP', + 'audit-accountability-export': 'Audit Accountability Export', 'copilot-governance': 'Copilot Governance', + 'crewai-agentmesh': 'CrewAI', dify: 'Dify', 'flowise-agentmesh': 'Flowise', + 'haystack-agentmesh': 'Haystack', 'langchain-agentmesh': 'LangChain for AGT', + 'langflow-agentmesh': 'Langflow', 'langgraph-trust': 'LangGraph Trust', + 'llamaindex-agentmesh': 'LlamaIndex for AGT', 'mastra-agentmesh': 'Mastra', + 'mcp-receipt-governed': 'MCP Receipt Governance', 'mcp-trust-proxy': 'MCP Trust Proxy', + 'nostr-wot': 'Nostr Web of Trust', 'openai-agents-agentmesh': 'OpenAI Agents for AgentMesh', + 'openai-agents-trust': 'OpenAI Agents Trust', 'openshell-skill': 'OpenShell Skill', + 'pydantic-ai-governance': 'PydanticAI Governance', 'structural-authz-agentmesh': 'Structural Authorization' + }; + let items = []; + const state = { query: '', stacks: new Set(), types: new Set(), sort: 'featured' }; + const search = document.getElementById('market-search'), grid = document.getElementById('market-grid'), empty = document.getElementById('market-empty'), status = document.getElementById('catalog-status'); + const slug = (value) => value.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, ''); + const initials = (value) => value.split(/[^A-Za-z0-9]+/).filter(Boolean).slice(0, 2).map((word) => word[0]).join('').toUpperCase(); + function escape(value) { const node = document.createElement('span'); node.textContent = value; return node.innerHTML; } + async function fetchJson(url) { const controller = new AbortController(), timeout = setTimeout(() => controller.abort(), 8000); try { const response = await fetch(url, { headers: { Accept: 'application/json' }, signal: controller.signal }); if (!response.ok) throw new Error(`${url} returned ${response.status}`); return await response.json(); } finally { clearTimeout(timeout); } } + function normalizeAgenTrust(catalog) { + if (catalog.catalog_version !== 1 || !Array.isArray(catalog.integrations) || catalog.count !== catalog.integrations.length) throw new Error('unsupported AgenTrust catalog'); + return catalog.integrations.map((item) => ({ ...item, type: item.category, source: 'AgenTrust', sourceClass: 'community' })); + } + function normalizeAgt(directory) { + if (!Array.isArray(directory)) throw new Error('invalid AGT directory'); + return directory.filter((entry) => entry.type === 'dir' && entry.name !== 'template-agentmesh').map((entry) => { + const name = AGT_NAMES[entry.name] || entry.name.split('-').map((part) => part[0].toUpperCase() + part.slice(1)).join(' '); + return { name, package_name: entry.name, vendor: 'Microsoft', description: 'An AGT integration maintained in the Agent Governance Toolkit framework-adapter collection.', url: entry.html_url, repository: 'https://github.com/microsoft/agent-governance-toolkit', homepage: null, tier: 'project', stack: ['AGT'], type: 'AGT integrations', category: 'AGT integrations', mark: initials(name), featured: null, keywords: [entry.name, 'Agent Governance Toolkit', 'AgentMesh'], source: 'AGT', sourceClass: 'project' }; + }).sort((a, b) => a.name.localeCompare(b.name)); + } + function card(item, compact) { + const tags = item.stack.map((tag) => `${escape(tag)}`).join(''); + const tier = item.source === 'AGT' ? 'AGT project' : `${item.tier[0].toUpperCase()}${item.tier.slice(1)}`; + return `
${escape(item.mark)} ${escape(tier)}

By ${escape(item.vendor)}

${escape(item.name)}

${escape(item.description)}

${tags}
View integration
`; + } + function addFilters(target, values, key) { + document.getElementById(target).innerHTML = values.map((value) => { const count = items.filter((item) => key === 'stacks' ? item.stack.includes(value) : item.type === value).length, id = `${key}-${slug(value)}`; return ``; }).join(''); + } + function render() { + const words = state.query.toLowerCase().trim().split(/\s+/).filter(Boolean); + let visible = items.filter((item) => { const haystack = [item.name, item.package_name, item.vendor, item.type, item.description, ...(item.keywords || []), ...item.stack].join(' ').toLowerCase(); return words.every((word) => haystack.includes(word)) && (!state.stacks.size || [...state.stacks].every((stack) => item.stack.includes(stack))) && (!state.types.size || state.types.has(item.type)); }); + if (state.sort === 'az') visible.sort((a, b) => a.name.localeCompare(b.name)); else if (state.sort === 'za') visible.sort((a, b) => b.name.localeCompare(a.name)); else visible.sort((a, b) => (a.featured || 999) - (b.featured || 999) || a.name.localeCompare(b.name)); + grid.innerHTML = visible.map((item) => card(item, false)).join(''); grid.hidden = !visible.length; empty.hidden = Boolean(visible.length); + document.getElementById('result-count').textContent = visible.length; document.getElementById('result-label').textContent = visible.length === 1 ? 'integration' : 'integrations'; + const chips = []; if (state.query) chips.push(``); state.stacks.forEach((value) => chips.push(``)); state.types.forEach((value) => chips.push(``)); document.getElementById('active-filters').innerHTML = chips.join(''); + const params = new URLSearchParams(); if (state.query) params.set('q', state.query); if (state.stacks.size) params.set('stack', [...state.stacks].join(',')); if (state.types.size) params.set('type', [...state.types].join(',')); if (state.sort !== 'featured') params.set('sort', state.sort); history.replaceState(null, '', `${location.pathname}${params.size ? `?${params}` : ''}${location.hash}`); + } + function clearAll() { state.query = ''; state.stacks.clear(); state.types.clear(); state.sort = 'featured'; search.value = ''; document.getElementById('market-sort').value = 'featured'; document.querySelectorAll('[data-filter]').forEach((input) => { input.checked = false; }); render(); } + const [agentrustResult, agtResult] = await Promise.allSettled([fetchJson(AGENTRUST_CATALOG), fetchJson(AGT_DIRECTORY)]); + const warnings = []; let agentrustItems = [], agtItems = []; + if (agentrustResult.status === 'fulfilled') { try { agentrustItems = normalizeAgenTrust(agentrustResult.value); } catch (error) { warnings.push('AgenTrust catalog unavailable'); } } else warnings.push('AgenTrust catalog unavailable'); + if (agtResult.status === 'fulfilled') { try { agtItems = normalizeAgt(agtResult.value); } catch (error) { warnings.push('AGT catalog unavailable'); } } else warnings.push('AGT catalog unavailable'); + items = [...agentrustItems, ...agtItems]; document.getElementById('hero-count').textContent = items.length; document.getElementById('native-count').textContent = agentrustItems.length; document.getElementById('agt-count').textContent = agtItems.length; + status.textContent = warnings.length ? `${warnings.join(' · ')}. Showing the source that loaded successfully.` : 'Live inventory from the AgenTrust integrations and Microsoft Agent Governance Toolkit repositories.'; status.classList.toggle('catalog-warning', Boolean(warnings.length)); + const stacks = [...new Set(items.flatMap((item) => item.stack))].sort((a, b) => a.localeCompare(b)), types = [...new Set(items.map((item) => item.type))].sort((a, b) => a.localeCompare(b)); + addFilters('stack-filters', stacks, 'stacks'); addFilters('type-filters', types, 'types'); document.getElementById('featured-list').innerHTML = agentrustItems.filter((item) => item.featured && item.featured <= 3).map((item) => card(item, true)).join(''); + const params = new URLSearchParams(location.search); state.query = params.get('q') || ''; state.sort = ['az', 'za'].includes(params.get('sort')) ? params.get('sort') : 'featured'; (params.get('stack') || '').split(',').filter((value) => stacks.includes(value)).forEach((value) => state.stacks.add(value)); (params.get('type') || '').split(',').filter((value) => types.includes(value)).forEach((value) => state.types.add(value)); search.value = state.query; document.getElementById('market-sort').value = state.sort; document.querySelectorAll('[data-filter]').forEach((input) => { input.checked = state[input.dataset.filter].has(input.value); }); + search.addEventListener('input', () => { state.query = search.value; render(); }); document.getElementById('market-sort').addEventListener('change', (event) => { state.sort = event.target.value; render(); }); document.querySelectorAll('[data-filter]').forEach((input) => input.addEventListener('change', () => { const set = state[input.dataset.filter]; input.checked ? set.add(input.value) : set.delete(input.value); render(); })); + document.getElementById('active-filters').addEventListener('click', (event) => { const button = event.target.closest('button'); if (!button) return; if (button.dataset.clear === 'query') { state.query = ''; search.value = ''; } else { state[button.dataset.clear].delete(button.dataset.value); const input = [...document.querySelectorAll('[data-filter]')].find((candidate) => candidate.value === button.dataset.value); if (input) input.checked = false; } render(); }); + document.getElementById('clear-filters').addEventListener('click', clearAll); document.getElementById('empty-clear').addEventListener('click', clearAll); document.addEventListener('keydown', (event) => { if (event.key === '/' && !/input|select|textarea/i.test(document.activeElement.tagName)) { event.preventDefault(); search.focus(); } }); render(); }());