@apteva/apteva-linux-arm64 0.4.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/apteva +0 -0
  2. package/dist/ActivityPage.41nbye4r.js +3 -0
  3. package/dist/ActivityPage.41nbye4r.js.map +9 -0
  4. package/dist/ApiDocsPage.4smnt8m3.js +4 -0
  5. package/dist/ApiDocsPage.4smnt8m3.js.map +10 -0
  6. package/dist/App.0sbax9et.js +4 -0
  7. package/dist/App.0sbax9et.js.map +10 -0
  8. package/dist/App.0ws427h8.js +4 -0
  9. package/dist/App.0ws427h8.js.map +10 -0
  10. package/dist/App.6q6bar8b.js +4 -0
  11. package/dist/App.6q6bar8b.js.map +10 -0
  12. package/dist/App.80301vdb.js +4 -0
  13. package/dist/App.80301vdb.js.map +10 -0
  14. package/dist/App.af2wg84v.js +267 -0
  15. package/dist/App.af2wg84v.js.map +35 -0
  16. package/dist/App.ca1rz1ph.js +4 -0
  17. package/dist/App.ca1rz1ph.js.map +14 -0
  18. package/dist/App.ensa6z0r.js +4 -0
  19. package/dist/App.ensa6z0r.js.map +10 -0
  20. package/dist/App.f8g7tych.js +13 -0
  21. package/dist/App.f8g7tych.js.map +10 -0
  22. package/dist/App.mvtqv6qc.js +20 -0
  23. package/dist/App.mvtqv6qc.js.map +14 -0
  24. package/dist/App.ncgc9cxy.js +4 -0
  25. package/dist/App.ncgc9cxy.js.map +10 -0
  26. package/dist/App.p02f4ret.js +1 -0
  27. package/dist/App.p0fb1pds.js +4 -0
  28. package/dist/App.p0fb1pds.js.map +10 -0
  29. package/dist/App.pmaq48sj.js +4 -0
  30. package/dist/App.pmaq48sj.js.map +10 -0
  31. package/dist/App.yv87t9m5.js +4 -0
  32. package/dist/App.yv87t9m5.js.map +10 -0
  33. package/dist/App.zjmfm8p6.js +4 -0
  34. package/dist/App.zjmfm8p6.js.map +10 -0
  35. package/dist/ConnectionsPage.anb3rv9a.js +3 -0
  36. package/dist/ConnectionsPage.anb3rv9a.js.map +9 -0
  37. package/dist/McpPage.y396h6fy.js +3 -0
  38. package/dist/McpPage.y396h6fy.js.map +9 -0
  39. package/dist/SettingsPage.p1hc60gk.js +3 -0
  40. package/dist/SettingsPage.p1hc60gk.js.map +9 -0
  41. package/dist/SkillsPage.yj3xdsay.js +3 -0
  42. package/dist/SkillsPage.yj3xdsay.js.map +9 -0
  43. package/dist/TasksPage.sjv0khtv.js +3 -0
  44. package/dist/TasksPage.sjv0khtv.js.map +9 -0
  45. package/dist/TelemetryPage.2qm4w16r.js +3 -0
  46. package/dist/TelemetryPage.2qm4w16r.js.map +9 -0
  47. package/dist/TestsPage.zzs4qfj8.js +3 -0
  48. package/dist/TestsPage.zzs4qfj8.js.map +9 -0
  49. package/dist/apteva-kit.css +1 -0
  50. package/dist/icon.png +0 -0
  51. package/dist/index.html +16 -0
  52. package/dist/styles.css +1 -0
  53. package/index.js +1 -0
  54. package/package.json +10 -0
@@ -0,0 +1,4 @@
1
+ import{k as _0}from"./App.ensa6z0r.js";import{R as x}from"./App.p0fb1pds.js";import{S as O,V as X1,W as n,ca as g,fa as j}from"./App.mvtqv6qc.js";var $0=O(X1(),1);var D=O(X1(),1);var U=O(n(),1);function m0(){let{authFetch:R}=g(),{currentProjectId:H}=j(),[J,F]=D.useState([]),[Q,V]=D.useState([]),[W,T]=D.useState(!0);if(D.useEffect(()=>{(async()=>{T(!0);let y=H&&H!=="unassigned"?`?project_id=${H}`:"";try{let[I,a]=await Promise.all([R(`/api/subscriptions${y}`).catch(()=>null),R("/api/agents").catch(()=>null)]);if(I?.ok){let G=await I.json();F(G.subscriptions||[])}if(a?.ok){let G=await a.json();V(G.agents||[])}}catch(I){console.error("Failed to fetch overview data:",I)}T(!1)})()},[R,H]),W)return U.jsxDEV("div",{className:"text-center py-12 text-[#666]",children:"Loading..."},void 0,!1,void 0,this);let A=J.filter((Y)=>Y.enabled),S=J.filter((Y)=>!Y.enabled),l=new Map(Q.map((Y)=>[Y.id,Y]));return U.jsxDEV("div",{className:"space-y-6",children:[U.jsxDEV("div",{className:"grid grid-cols-3 gap-4",children:[U.jsxDEV(C1,{label:"Active",value:A.length},void 0,!1,void 0,this),U.jsxDEV(C1,{label:"Disabled",value:S.length},void 0,!1,void 0,this),U.jsxDEV(C1,{label:"Total",value:J.length},void 0,!1,void 0,this)]},void 0,!0,void 0,this),U.jsxDEV("section",{children:[U.jsxDEV("h3",{className:"text-sm font-medium text-[#888] mb-3",children:["Subscriptions (",J.length,")"]},void 0,!0,void 0,this),J.length===0?U.jsxDEV("div",{className:"bg-[#111] border border-[#1a1a1a] rounded-lg p-6 text-center text-[#666] text-sm",children:"No subscriptions yet. Go to the Triggers tab to create one."},void 0,!1,void 0,this):U.jsxDEV("div",{className:"space-y-2",children:J.map((Y)=>{let y=l.get(Y.agent_id);return U.jsxDEV("div",{className:"bg-[#111] border border-[#1a1a1a] rounded-lg p-3 flex items-center gap-3",children:[U.jsxDEV("div",{className:`w-2 h-2 rounded-full flex-shrink-0 ${Y.enabled?"bg-green-400":"bg-[#555]"}`},void 0,!1,void 0,this),U.jsxDEV("div",{className:"flex-1 min-w-0",children:[U.jsxDEV("div",{className:"text-sm font-medium truncate",children:Y.trigger_slug.replace(/_/g," ").replace(/-/g," ")},void 0,!1,void 0,this),U.jsxDEV("div",{className:"text-xs text-[#666]",children:Y.trigger_instance_id?`ID: ${Y.trigger_instance_id.slice(0,12)}...`:"All instances"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),U.jsxDEV("div",{className:"text-xs text-[#888] flex-shrink-0",children:[U.jsxDEV("span",{className:"text-[#555]",children:"→"},void 0,!1,void 0,this)," ",U.jsxDEV("span",{className:"text-[#f97316]",children:y?.name||"Unknown Agent"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),U.jsxDEV("span",{className:`text-xs px-2 py-0.5 rounded flex-shrink-0 ${Y.enabled?"bg-green-500/10 text-green-400":"bg-[#1a1a1a] text-[#555]"}`,children:Y.enabled?"active":"disabled"},void 0,!1,void 0,this)]},Y.id,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function C1({label:R,value:H,valueColor:J}){return U.jsxDEV("div",{className:"bg-[#111] border border-[#1a1a1a] rounded-lg p-4",children:[U.jsxDEV("div",{className:"text-xs text-[#666] mb-1",children:R},void 0,!1,void 0,this),U.jsxDEV("div",{className:`text-2xl font-bold ${J||"text-[#e0e0e0]"}`,children:H},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var $=O(X1(),1);var i=O(n(),1);function I0({message:R="Loading...",fullScreen:H=!1}){let J=i.jsxDEV("div",{className:"flex items-center gap-3 text-[#666]",children:[i.jsxDEV("svg",{className:"animate-spin h-5 w-5",viewBox:"0 0 24 24",children:[i.jsxDEV("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4",fill:"none"},void 0,!1,void 0,this),i.jsxDEV("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),i.jsxDEV("span",{children:R},void 0,!1,void 0,this)]},void 0,!0,void 0,this);if(H)return i.jsxDEV("div",{className:"min-h-screen bg-[#0a0a0a] text-[#e0e0e0] font-mono flex items-center justify-center",children:J},void 0,!1,void 0,this);return i.jsxDEV("div",{className:"flex items-center justify-center py-20",children:J},void 0,!1,void 0,this)}var m=O(n(),1);function v0(){let{authFetch:R}=g(),{currentProjectId:H}=j(),[J,F]=$.useState([]),[Q,V]=$.useState(""),[W,T]=$.useState([]),[A,S]=$.useState(!0),[l,Y]=$.useState([]),[y,I]=$.useState([]),[a,G]=$.useState(!1),[b,k]=$.useState(""),[o,F1]=$.useState(""),[R0,v1]=$.useState(!1),[B,_1]=$.useState(null),[f1,z0]=$.useState([]),[$1,I1]=$.useState(""),[Y1,R1]=$.useState(!1),[r,n1]=$.useState(""),[Z1,P1]=$.useState({}),[l1,G0]=$.useState(""),[H0,q1]=$.useState(!1),[p,J0]=$.useState([]),[K0,k1]=$.useState(!1),[A1,U0]=$.useState([]),[Q1,X0]=$.useState([]),[s,y1]=$.useState(""),[t,W1]=$.useState(""),[e,h1]=$.useState(""),[i1,T1]=$.useState(!1),[B1,z1]=$.useState({}),[S1,Y0]=$.useState(""),[a1,G1]=$.useState(!1),[M1,p1]=$.useState(""),[u1,H1]=$.useState(!1),[O1,x1]=$.useState(""),[Z0,J1]=$.useState(!1),[c,L1]=$.useState(""),[K1,b1]=$.useState(""),[V1,c1]=$.useState(!1),[h,q0]=$.useState([]),[d1,Z]=$.useState(null),X=H&&H!=="unassigned"?`?project_id=${H}`:"",E1=$.useCallback(async()=>{try{let N=await R(`/api/triggers/providers${X}`);if(N.ok){let _=((await N.json()).providers||[]).filter((f)=>f.connected);if(F(_),_.length>0)V((f)=>{if(!f||!_.find((K)=>K.id===f))return _[0].id;return f})}}catch(N){console.error("Failed to fetch providers:",N)}},[R]),u=$.useCallback(async()=>{S(!0);try{let N=`provider=${Q}`,v=X?"&":"?",_=X?`/api/triggers${X}&${N}`:`/api/triggers?${N}`,f=await R(_);if(f.ok){let K=await f.json();T(K.triggers||[])}}catch(N){console.error("Failed to fetch triggers:",N)}S(!1)},[R,X,Q]),N1=$.useCallback(async()=>{try{let N=await R(`/api/subscriptions${X}`);if(N.ok){let v=await N.json();Y(v.subscriptions||[])}}catch(N){console.error("Failed to fetch subscriptions:",N)}},[R,X]),D1=$.useCallback(async()=>{try{let N=await R(`/api/agents${X}`);if(N.ok){let v=await N.json();q0(v.agents||[])}}catch(N){}},[R,X]);$.useEffect(()=>{E1(),u(),N1(),D1()},[E1,u,N1,D1]);let Q0=async(N)=>{G(!0);try{let v=`/api/triggers/types?provider=${Q}`;if(N)v+=`&toolkit_slugs=${N}`;if(H&&H!=="unassigned")v+=`&project_id=${H}`;let _=await R(v);if(_.ok){let f=await _.json();I(f.types||[])}else{let f=await _.json();Z(f.error||"Failed to fetch trigger types")}}catch(v){Z("Failed to fetch trigger types")}G(!1)},W0=async()=>{try{let N=await R(`/api/integrations/${Q}/connected${X}`);if(N.ok){let v=await N.json();z0((v.accounts||[]).filter((_)=>_.status==="active"))}}catch(N){}},B0=(N)=>{_1(N),I1(""),n1(""),P1({}),G0(""),v1(!0),W0()},C=Q==="agentdojo",M0=async()=>{q1(!0),W1(""),y1(""),h1(""),z1({}),Y0("");let N=async()=>{if(p.length>0)return;k1(!0);try{let f="/api/triggers/types?provider=agentdojo";if(H&&H!=="unassigned")f+=`&project_id=${H}`;let L=await(await R(f)).json();J0(L.types||[])}catch(f){console.error("Failed to load trigger types:",f)}k1(!1)},v=async()=>{try{let f=`/api/integrations/agentdojo/connected${X}`,q=((await(await R(f)).json()).accounts||[]).filter((E)=>E.status==="active");U0(q)}catch(f){console.error("Failed to load connected accounts:",f)}},_=async()=>{if(Q1.length>0)return;try{let f=`/api/integrations/agentdojo/apps${X}`,L=await(await R(f)).json();X0((L.apps||[]).map((q)=>({id:q.id,name:q.name,slug:q.slug,logo:q.logo})))}catch(f){console.error("Failed to load apps:",f)}};await Promise.all([N(),v(),_()])},O0=async()=>{let N=p.find((_)=>_.slug===t),v=U1;if(!N||!e||!v)return;T1(!0),Z(null);try{let _=h.find((F0)=>F0.id===e),f="provider=agentdojo",K=X?`/api/triggers${X}&provider=agentdojo`:"/api/triggers?provider=agentdojo",L={callback_url:`${window.location.origin}/api/webhooks/agentdojo`,title:`${N.name} → ${_?.name||"Agent"}`,server:N.toolkit_slug,agent_id:e,...B1},q=await R(K,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({slug:N.slug,connectedAccountId:v.id,config:L})}),E=await q.json();if(!q.ok)Z(E.error||"Failed to create subscription");else q1(!1),u()}catch(_){Z(_.message||"Failed to create subscription")}T1(!1)},L0=async()=>{if(!B)return;if(C){if(!r||!m1)return;R1(!0),Z(null);try{let N=h.find((q)=>q.id===r),v=window.location.origin,_=`provider=${Q}`,f=X?`/api/triggers${X}&${_}`:`/api/triggers?${_}`,K=await R(f,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({slug:B.slug,connectedAccountId:m1.id,config:{callback_url:`${v}/api/webhooks/agentdojo`,title:`${B.name} → ${N?.name||"Agent"}`,server:B.toolkit_slug,agent_id:r,...Z1}})}),L=await K.json();if(!K.ok)Z(L.error||"Failed to create subscription");else v1(!1),_1(null),u()}catch(N){Z(N.message||"Failed to create subscription")}R1(!1);return}if(!$1)return;R1(!0),Z(null);try{let N=`provider=${Q}`,v=X?`/api/triggers${X}&${N}`:`/api/triggers?${N}`,_=await R(v,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({slug:B.slug,connectedAccountId:$1})}),f=await _.json();if(!_.ok)Z(f.error||"Failed to create trigger");else v1(!1),_1(null),u()}catch(N){Z(N.message||"Failed to create trigger")}R1(!1)},g1=async(N,v)=>{let _=v==="active"?"disable":"enable";try{let f=X?`&provider=${Q}`:`?provider=${Q}`,K=await R(`/api/triggers/${N}/${_}${X}${f}`,{method:"POST"});if(K.ok)u();else{let L=await K.json();Z(L.error||`Failed to ${_} trigger`)}}catch(f){Z(`Failed to ${_} trigger`)}},j1=async(N)=>{try{let v=X?`&provider=${Q}`:`?provider=${Q}`,_=await R(`/api/triggers/${N}${X}${v}`,{method:"DELETE"});if(_.ok)u();else{let f=await _.json();Z(f.error||"Failed to delete trigger")}}catch(v){Z("Failed to delete trigger")}},b0=async()=>{if(!c||!K1)return;let N=W.find((v)=>v.id===c);if(!N)return;c1(!0),Z(null);try{let v=await R("/api/subscriptions",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({trigger_slug:N.trigger_slug,trigger_instance_id:N.id,agent_id:K1,provider:Q,project_id:H&&H!=="unassigned"?H:null,public_url:window.location.origin})}),_=await v.json();if(!v.ok)Z(_.error||"Failed to create subscription");else J1(!1),L1(""),b1(""),N1()}catch(v){Z(v.message||"Failed to create subscription")}c1(!1)},w0=async(N)=>{let v=N.enabled?"disable":"enable";try{if((await R(`/api/subscriptions/${N.id}/${v}`,{method:"POST"})).ok)N1()}catch(_){Z(`Failed to ${v} subscription`)}},C0=async(N)=>{try{if((await R(`/api/subscriptions/${N}`,{method:"DELETE"})).ok)N1()}catch(v){Z("Failed to delete subscription")}},w1=y.filter((N)=>{if(!o)return!0;let v=o.toLowerCase();return N.name.toLowerCase().includes(v)||N.slug.toLowerCase().includes(v)||N.description.toLowerCase().includes(v)}),o1=(N,v)=>{if(!v||N.length===0)return null;let _=v.toLowerCase().replace(/[-_]/g," "),f=N.find((q)=>q.appId?.toLowerCase()===v.toLowerCase()||q.appName?.toLowerCase()===v.toLowerCase());if(f)return f;let K=N.find((q)=>q.appId?.toLowerCase().includes(_)||q.appName?.toLowerCase().replace(/[-_]/g," ").includes(_)||_.includes(q.appId?.toLowerCase()||"")||_.includes(q.appName?.toLowerCase().replace(/[-_]/g," ")||""));if(K)return K;let L=_.split(/\s+/);return N.find((q)=>{let E=(q.appName||"").toLowerCase().replace(/[-_]/g," ").split(/\s+/);return L[0]&&E[0]&&L[0]===E[0]})||null},M=p.find((N)=>N.slug===t),r1=M?o1(A1,M.toolkit_slug):null,U1=S1?A1.find((N)=>N.id===S1)||r1:r1,s1=B&&C?o1(f1,B.toolkit_slug):null,m1=l1?f1.find((N)=>N.id===l1)||s1:s1,t1=$.default.useMemo(()=>{let N=new Map;for(let _ of Q1)if(_.logo)N.set(_.slug,_.logo);let v=new Map;for(let _ of p){let f=v.get(_.toolkit_slug);if(f)f.count++;else{let K=N.get(_.toolkit_slug)||_.logo||null;v.set(_.toolkit_slug,{slug:_.toolkit_slug,name:_.toolkit_name,logo:K,count:1})}}return Array.from(v.values()).sort((_,f)=>_.name.localeCompare(f.name))},[p,Q1]),e1=s?p.filter((N)=>N.toolkit_slug===s):[],d=t1.find((N)=>N.slug===s),N0=new Map(h.map((N)=>[N.id,N]));if(J.length===0&&!A)return m.jsxDEV("div",{className:"bg-[#111] border border-[#1a1a1a] rounded-lg p-8 text-center",children:[m.jsxDEV("p",{className:"text-[#666]",children:"No trigger providers configured."},void 0,!1,void 0,this),m.jsxDEV("p",{className:"text-sm text-[#555] mt-1",children:"Add API keys for Composio or AgentDojo in Settings to enable triggers."},void 0,!1,void 0,this)]},void 0,!0,void 0,this);return m.jsxDEV("div",{className:"space-y-6",children:[d1&&m.jsxDEV("div",{className:"text-red-400 text-sm p-3 bg-red-500/10 border border-red-500/20 rounded-lg flex items-center justify-between",children:[m.jsxDEV("span",{children:d1},void 0,!1,void 0,this),m.jsxDEV("button",{onClick:()=>Z(null),className:"text-red-400 hover:text-red-300",children:"x"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J.length>1&&m.jsxDEV("div",{className:"flex items-center gap-2",children:[m.jsxDEV("span",{className:"text-xs text-[#666]",children:"Provider:"},void 0,!1,void 0,this),m.jsxDEV("div",{className:"flex gap-1 bg-[#111] border border-[#1a1a1a] rounded-lg p-0.5",children:J.map((N)=>m.jsxDEV("button",{onClick:()=>{V(N.id),I([]),k(""),F1("")},className:`px-3 py-1 rounded text-xs font-medium transition ${Q===N.id?"bg-[#1a1a1a] text-white":"text-[#666] hover:text-[#888]"}`,children:N.name},N.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),!C&&m.jsxDEV("section",{children:[m.jsxDEV("div",{className:"flex items-center justify-between mb-3",children:[m.jsxDEV("h3",{className:"text-sm font-medium text-[#888]",children:["Subscriptions (",l.length,")"]},void 0,!0,void 0,this),m.jsxDEV("button",{onClick:()=>J1(!0),className:"text-xs bg-[#1a1a1a] hover:bg-[#222] border border-[#333] hover:border-[#f97316] px-3 py-1.5 rounded transition",children:"+ Add Subscription"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),l.length===0?m.jsxDEV("div",{className:"bg-[#111] border border-[#1a1a1a] rounded-lg p-6 text-center text-[#666] text-sm",children:"No subscriptions yet. Add one to route trigger events to an agent."},void 0,!1,void 0,this):m.jsxDEV("div",{className:"space-y-2",children:l.map((N)=>{let v=N0.get(N.agent_id);return m.jsxDEV("div",{className:"bg-[#111] border border-[#1a1a1a] rounded-lg p-3 flex items-center gap-3",children:[m.jsxDEV("div",{className:`w-2 h-2 rounded-full flex-shrink-0 ${N.enabled?"bg-green-400":"bg-[#666]"}`},void 0,!1,void 0,this),m.jsxDEV("div",{className:"flex-1 min-w-0",children:[m.jsxDEV("div",{className:"text-sm font-medium truncate",children:[N.trigger_slug.replace(/_/g," "),m.jsxDEV("span",{className:"text-[#555] mx-1.5",children:"→"},void 0,!1,void 0,this),m.jsxDEV("span",{className:"text-[#f97316]",children:v?.name||"Unknown Agent"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m.jsxDEV("div",{className:"text-xs text-[#666]",children:N.trigger_instance_id?`Instance: ${N.trigger_instance_id.slice(0,12)}...`:"All instances"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m.jsxDEV("div",{className:"flex items-center gap-2 flex-shrink-0",children:[m.jsxDEV("button",{onClick:()=>w0(N),className:`text-xs px-3 py-1 rounded transition ${N.enabled?"bg-yellow-500/10 text-yellow-400 hover:bg-yellow-500/20":"bg-green-500/10 text-green-400 hover:bg-green-500/20"}`,children:N.enabled?"Disable":"Enable"},void 0,!1,void 0,this),m.jsxDEV("button",{onClick:()=>C0(N.id),className:"text-xs text-[#666] hover:text-red-400 transition px-2",children:"Delete"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},N.id,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this),!C&&m.jsxDEV("section",{children:[m.jsxDEV("h3",{className:"text-sm font-medium text-[#888] mb-3",children:["Trigger Instances (",W.length,")"]},void 0,!0,void 0,this),A?m.jsxDEV("div",{className:"text-center py-6 text-[#666] text-sm",children:"Loading triggers..."},void 0,!1,void 0,this):W.length===0?m.jsxDEV("div",{className:"bg-[#111] border border-[#1a1a1a] rounded-lg p-6 text-center text-[#666] text-sm",children:"No trigger instances. Browse trigger types below to create one."},void 0,!1,void 0,this):m.jsxDEV("div",{className:"space-y-2",children:W.map((N)=>m.jsxDEV("div",{className:"bg-[#111] border border-[#1a1a1a] rounded-lg p-3 flex items-center gap-3",children:[m.jsxDEV("div",{className:`w-2 h-2 rounded-full flex-shrink-0 ${N.status==="active"?"bg-green-400":"bg-[#666]"}`},void 0,!1,void 0,this),m.jsxDEV("div",{className:"flex-1 min-w-0",children:[m.jsxDEV("div",{className:"text-sm font-medium truncate",children:N.trigger_slug.replace(/_/g," ")},void 0,!1,void 0,this),m.jsxDEV("div",{className:"text-xs text-[#666]",children:["ID: ",N.id.slice(0,12),"... | Created: ",new Date(N.created_at).toLocaleDateString()]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),m.jsxDEV("div",{className:"flex items-center gap-2 flex-shrink-0",children:[m.jsxDEV("button",{onClick:()=>g1(N.id,N.status),className:`text-xs px-3 py-1 rounded transition ${N.status==="active"?"bg-yellow-500/10 text-yellow-400 hover:bg-yellow-500/20":"bg-green-500/10 text-green-400 hover:bg-green-500/20"}`,children:N.status==="active"?"Disable":"Enable"},void 0,!1,void 0,this),m.jsxDEV("button",{onClick:()=>j1(N.id),className:"text-xs text-[#666] hover:text-red-400 transition px-2",children:"Delete"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},N.id,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C&&m.jsxDEV("section",{children:[m.jsxDEV("div",{className:"flex items-center justify-between mb-3",children:[m.jsxDEV("h3",{className:"text-sm font-medium text-[#888]",children:["Active Subscriptions (",W.length,")"]},void 0,!0,void 0,this),m.jsxDEV("button",{onClick:M0,className:"text-xs bg-[#1a1a1a] hover:bg-[#222] border border-[#333] hover:border-[#f97316] px-3 py-1.5 rounded transition",children:"+ Add Subscription"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),A?m.jsxDEV("div",{className:"text-center py-6 text-[#666] text-sm",children:"Loading subscriptions..."},void 0,!1,void 0,this):W.length===0?m.jsxDEV("div",{className:"bg-[#111] border border-[#1a1a1a] rounded-lg p-6 text-center text-[#666] text-sm",children:"No active subscriptions. Browse trigger types below to create one."},void 0,!1,void 0,this):m.jsxDEV("div",{className:"space-y-2",children:W.map((N)=>{let v=l.find((f)=>f.trigger_instance_id===N.id),_=v?N0.get(v.agent_id):null;return m.jsxDEV("div",{className:"bg-[#111] border border-[#1a1a1a] rounded-lg p-3 flex items-center gap-3",children:[m.jsxDEV("div",{className:`w-2 h-2 rounded-full flex-shrink-0 ${N.status==="active"?"bg-green-400":"bg-[#666]"}`},void 0,!1,void 0,this),m.jsxDEV("div",{className:"flex-1 min-w-0",children:[m.jsxDEV("div",{className:"text-sm font-medium truncate",children:[N.config?.title||N.trigger_slug.replace(/_/g," "),_&&m.jsxDEV(m.Fragment,{children:[m.jsxDEV("span",{className:"text-[#555] mx-1.5",children:"→"},void 0,!1,void 0,this),m.jsxDEV("span",{className:"text-[#f97316]",children:_.name},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),m.jsxDEV("div",{className:"text-xs text-[#666]",children:[N.config?.server&&m.jsxDEV("span",{children:[String(N.config.server)," | "]},void 0,!0,void 0,this),"ID: ",String(N.id).slice(0,8)," | Created: ",new Date(N.created_at).toLocaleDateString()]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),m.jsxDEV("div",{className:"flex items-center gap-2 flex-shrink-0",children:[m.jsxDEV("button",{onClick:()=>g1(N.id,N.status),className:`text-xs px-3 py-1 rounded transition ${N.status==="active"?"bg-yellow-500/10 text-yellow-400 hover:bg-yellow-500/20":"bg-green-500/10 text-green-400 hover:bg-green-500/20"}`,children:N.status==="active"?"Disable":"Enable"},void 0,!1,void 0,this),m.jsxDEV("button",{onClick:()=>j1(N.id),className:"text-xs text-[#666] hover:text-red-400 transition px-2",children:"Delete"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},N.id,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m.jsxDEV("section",{children:[m.jsxDEV("h3",{className:"text-sm font-medium text-[#888] mb-3",children:"Browse Trigger Types"},void 0,!1,void 0,this),m.jsxDEV("div",{className:"flex gap-2 mb-3",children:[m.jsxDEV("input",{type:"text",value:b,onChange:(N)=>k(N.target.value),placeholder:"Toolkit filter (e.g. github, gmail, slack)",className:"flex-1 bg-[#111] border border-[#333] rounded px-3 py-2 text-sm focus:outline-none focus:border-[#f97316]"},void 0,!1,void 0,this),m.jsxDEV("button",{onClick:()=>Q0(b||void 0),disabled:a,className:"text-sm bg-[#1a1a1a] hover:bg-[#222] border border-[#333] hover:border-[#f97316] px-4 py-2 rounded transition disabled:opacity-50",children:a?"Loading...":"Browse"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),y.length>0&&m.jsxDEV(m.Fragment,{children:[m.jsxDEV("input",{type:"text",value:o,onChange:(N)=>F1(N.target.value),placeholder:"Search trigger types...",className:"w-full bg-[#111] border border-[#333] rounded px-3 py-2 text-sm mb-3 focus:outline-none focus:border-[#f97316]"},void 0,!1,void 0,this),m.jsxDEV("div",{className:"grid gap-3 sm:grid-cols-2 lg:grid-cols-3",children:w1.slice(0,30).map((N)=>m.jsxDEV("div",{className:"bg-[#111] border border-[#1a1a1a] hover:border-[#333] rounded-lg p-3 transition",children:[m.jsxDEV("div",{className:"flex items-start gap-3",children:[N.logo?m.jsxDEV("img",{src:N.logo,alt:N.toolkit_name,className:"w-8 h-8 rounded object-contain flex-shrink-0"},void 0,!1,void 0,this):m.jsxDEV("div",{className:"w-8 h-8 rounded bg-[#1a1a1a] flex items-center justify-center text-xs flex-shrink-0",children:N.toolkit_name?.[0]?.toUpperCase()||"?"},void 0,!1,void 0,this),m.jsxDEV("div",{className:"flex-1 min-w-0",children:[m.jsxDEV("div",{className:"text-sm font-medium truncate",children:N.name},void 0,!1,void 0,this),m.jsxDEV("div",{className:"text-xs text-[#666]",children:N.toolkit_name},void 0,!1,void 0,this),m.jsxDEV("div",{className:"text-xs text-[#555] mt-1 line-clamp-2",children:N.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),m.jsxDEV("button",{onClick:()=>B0(N),className:"w-full mt-3 text-xs bg-[#1a1a1a] hover:bg-[#222] border border-[#333] hover:border-[#f97316] px-3 py-1.5 rounded transition",children:C?"Subscribe":"Create Trigger"},void 0,!1,void 0,this)]},N.slug,!0,void 0,this))},void 0,!1,void 0,this),w1.length>30&&m.jsxDEV("p",{className:"text-xs text-[#555] mt-3 text-center",children:["Showing first 30 of ",w1.length," types. Use search to filter."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),R0&&B&&m.jsxDEV("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",children:m.jsxDEV("div",{className:"bg-[#111] border border-[#333] rounded-lg p-6 w-full max-w-md mx-4",children:[m.jsxDEV("h3",{className:"font-medium mb-1",children:C?"Create Subscription":"Create Trigger"},void 0,!1,void 0,this),m.jsxDEV("p",{className:"text-xs text-[#666] mb-4",children:[B.name,B.toolkit_name&&m.jsxDEV("span",{className:"text-[#555]",children:[" (",B.toolkit_name,")"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),m.jsxDEV("div",{className:"space-y-4",children:[!C&&m.jsxDEV("div",{children:[m.jsxDEV("label",{className:"block text-xs text-[#888] mb-1.5",children:"Connected Account"},void 0,!1,void 0,this),f1.length===0?m.jsxDEV("div",{className:"text-xs text-[#666] bg-[#0a0a0a] rounded p-3",children:"No connected accounts available. Connect an app first in the Integrations tab."},void 0,!1,void 0,this):m.jsxDEV(x,{value:$1,onChange:I1,placeholder:"Select account...",options:f1.map((N)=>({value:N.id,label:`${N.appName} (${N.id.slice(0,8)}...)`}))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),C&&m.jsxDEV("div",{children:[m.jsxDEV("label",{className:"block text-xs text-[#888] mb-1.5",children:"Route to Agent"},void 0,!1,void 0,this),h.length===0?m.jsxDEV("div",{className:"text-xs text-[#666] bg-[#0a0a0a] rounded p-3",children:"No agents available. Create an agent first."},void 0,!1,void 0,this):m.jsxDEV(x,{value:r,onChange:n1,placeholder:"Select agent...",options:h.map((N)=>({value:N.id,label:`${N.name} (${N.status})`}))},void 0,!1,void 0,this),m.jsxDEV("div",{className:"mt-3",children:[m.jsxDEV("label",{className:"block text-xs text-[#888] mb-1.5",children:"Connected Account"},void 0,!1,void 0,this),m1?m.jsxDEV("div",{className:"text-xs text-green-400 bg-green-500/10 border border-green-500/20 rounded p-3",children:["Connected: ",m1.appName]},void 0,!0,void 0,this):m.jsxDEV("div",{className:"text-xs text-yellow-400 bg-yellow-500/10 border border-yellow-500/20 rounded p-3",children:["No connected account for ",B?.toolkit_name||"this app",". Connect it first in the Integrations tab."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),B.config_schema&&Object.keys(B.config_schema.properties||{}).length>0&&m.jsxDEV("div",{className:"mt-3",children:[m.jsxDEV("label",{className:"block text-xs text-[#888] mb-1.5",children:"Configuration"},void 0,!1,void 0,this),m.jsxDEV("div",{className:"space-y-2",children:Object.entries(B.config_schema.properties||{}).map(([N,v])=>{let _=(B.config_schema.required||[]).includes(N);return m.jsxDEV("div",{children:[m.jsxDEV("label",{className:"block text-[11px] text-[#888] mb-1",children:[v.title||N,_&&m.jsxDEV("span",{className:"text-red-400 ml-0.5",children:"*"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m.jsxDEV("input",{type:"text",value:Z1[N]||"",onChange:(f)=>P1((K)=>({...K,[N]:f.target.value})),placeholder:v.description||`Enter ${v.title||N}...`,className:"w-full bg-[#0a0a0a] border border-[#333] rounded px-3 py-2 text-sm focus:outline-none focus:border-[#f97316]"},void 0,!1,void 0,this)]},N,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),m.jsxDEV("div",{className:"flex gap-2 mt-4",children:[m.jsxDEV("button",{onClick:()=>{v1(!1),_1(null)},className:"flex-1 text-sm bg-[#1a1a1a] hover:bg-[#222] border border-[#333] px-4 py-2 rounded transition",children:"Cancel"},void 0,!1,void 0,this),m.jsxDEV("button",{onClick:L0,disabled:C?!r||!m1||Y1||B?.config_schema&&(B.config_schema.required||[]).some((N)=>!Z1[N]?.trim()):!$1||Y1,className:"flex-1 text-sm bg-[#f97316] hover:bg-[#ea580c] text-white px-4 py-2 rounded transition disabled:opacity-50",children:Y1?"Creating...":C?"Subscribe":"Create"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),Z0&&m.jsxDEV("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",children:m.jsxDEV("div",{className:"bg-[#111] border border-[#333] rounded-lg p-6 w-full max-w-md mx-4",children:[m.jsxDEV("h3",{className:"font-medium mb-1",children:"Route Trigger to Agent"},void 0,!1,void 0,this),m.jsxDEV("p",{className:"text-xs text-[#666] mb-4",children:W.length===0?"No trigger instances yet. Create one first from the Browse section below.":"Select a trigger instance and the agent that should handle its events."},void 0,!1,void 0,this),W.length>0?m.jsxDEV(m.Fragment,{children:[m.jsxDEV("div",{className:"space-y-4",children:[m.jsxDEV("div",{children:[m.jsxDEV("label",{className:"block text-xs text-[#888] mb-1.5",children:"Trigger Instance"},void 0,!1,void 0,this),m.jsxDEV(x,{value:c,onChange:L1,placeholder:"Select trigger...",options:W.map((N)=>({value:N.id,label:`${N.trigger_slug.replace(/_/g," ")}`}))},void 0,!1,void 0,this),c&&m.jsxDEV("div",{className:"text-xs text-[#555] mt-1 font-mono",children:["ID: ",c.slice(0,16),"..."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),m.jsxDEV("div",{children:[m.jsxDEV("label",{className:"block text-xs text-[#888] mb-1.5",children:"Target Agent"},void 0,!1,void 0,this),m.jsxDEV(x,{value:K1,onChange:b1,placeholder:"Select agent...",options:h.map((N)=>({value:N.id,label:`${N.name} (${N.status})`}))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),m.jsxDEV("div",{className:"flex gap-2 mt-5",children:[m.jsxDEV("button",{onClick:()=>{J1(!1),L1(""),b1("")},className:"flex-1 text-sm bg-[#1a1a1a] hover:bg-[#222] border border-[#333] px-4 py-2 rounded transition",children:"Cancel"},void 0,!1,void 0,this),m.jsxDEV("button",{onClick:b0,disabled:!c||!K1||V1,className:"flex-1 text-sm bg-[#f97316] hover:bg-[#ea580c] text-white px-4 py-2 rounded transition disabled:opacity-50",children:V1?"Adding...":"Add"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this):m.jsxDEV("div",{className:"flex gap-2 mt-4",children:m.jsxDEV("button",{onClick:()=>J1(!1),className:"flex-1 text-sm bg-[#1a1a1a] hover:bg-[#222] border border-[#333] px-4 py-2 rounded transition",children:"Close"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),H0&&m.jsxDEV("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",children:m.jsxDEV("div",{className:"bg-[#111] border border-[#333] rounded-lg p-6 w-full max-w-lg mx-4",children:[m.jsxDEV("h3",{className:"font-medium mb-1",children:"Add Subscription"},void 0,!1,void 0,this),m.jsxDEV("p",{className:"text-xs text-[#666] mb-4",children:"Select an app and trigger, then route it to an agent."},void 0,!1,void 0,this),K0?m.jsxDEV("div",{className:"text-center py-8 text-[#666] text-sm",children:"Loading..."},void 0,!1,void 0,this):p.length===0?m.jsxDEV("div",{className:"text-center py-8 text-[#666] text-sm",children:"No triggers available. Connect an app first in the Integrations tab."},void 0,!1,void 0,this):m.jsxDEV("div",{className:"space-y-4",children:[m.jsxDEV("div",{children:[m.jsxDEV("label",{className:"block text-xs text-[#888] mb-1.5",children:"App"},void 0,!1,void 0,this),m.jsxDEV("div",{className:"relative",children:[m.jsxDEV("button",{onClick:()=>{G1(!a1),H1(!1),p1("")},className:"w-full flex items-center gap-2 bg-[#0a0a0a] border border-[#333] rounded px-3 py-2 text-sm text-left hover:border-[#555] transition",children:[d?m.jsxDEV(m.Fragment,{children:[d.logo?m.jsxDEV("img",{src:d.logo,alt:"",className:"w-5 h-5 rounded object-contain flex-shrink-0"},void 0,!1,void 0,this):m.jsxDEV("div",{className:"w-5 h-5 rounded bg-[#1a1a1a] flex items-center justify-center text-[10px] flex-shrink-0",children:d.name?.[0]?.toUpperCase()||"?"},void 0,!1,void 0,this),m.jsxDEV("span",{className:"flex-1 truncate",children:d.name},void 0,!1,void 0,this),m.jsxDEV("span",{className:"text-[10px] text-[#666]",children:[d.count," triggers"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this):m.jsxDEV("span",{className:"text-[#666] flex-1",children:"Select app..."},void 0,!1,void 0,this),m.jsxDEV("span",{className:"text-[#666] text-xs ml-1",children:"▾"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),a1&&m.jsxDEV(m.Fragment,{children:[m.jsxDEV("div",{className:"fixed inset-0 z-10",onClick:()=>G1(!1)},void 0,!1,void 0,this),m.jsxDEV("div",{className:"absolute left-0 right-0 top-full mt-1 bg-[#0a0a0a] border border-[#333] rounded-lg shadow-xl z-20 max-h-64 flex flex-col",children:[m.jsxDEV("div",{className:"p-2 border-b border-[#1a1a1a] flex-shrink-0",children:m.jsxDEV("input",{type:"text",value:M1,onChange:(N)=>p1(N.target.value),placeholder:"Search apps...",className:"w-full bg-[#111] border border-[#333] rounded px-2 py-1.5 text-sm focus:outline-none focus:border-[#f97316]",autoFocus:!0},void 0,!1,void 0,this)},void 0,!1,void 0,this),m.jsxDEV("div",{className:"overflow-y-auto flex-1",children:t1.filter((N)=>{if(!M1)return!0;let v=M1.toLowerCase();return N.name.toLowerCase().includes(v)||N.slug.toLowerCase().includes(v)}).map((N)=>m.jsxDEV("button",{onClick:()=>{y1(N.slug),W1(""),z1({}),G1(!1)},className:`w-full flex items-center gap-2 px-3 py-2 text-sm text-left transition hover:bg-[#1a1a1a] ${s===N.slug?"bg-[#1a1a1a] text-[#f97316]":""}`,children:[N.logo?m.jsxDEV("img",{src:N.logo,alt:"",className:"w-5 h-5 rounded object-contain flex-shrink-0"},void 0,!1,void 0,this):m.jsxDEV("div",{className:"w-5 h-5 rounded bg-[#1a1a1a] flex items-center justify-center text-[10px] flex-shrink-0",children:N.name?.[0]?.toUpperCase()||"?"},void 0,!1,void 0,this),m.jsxDEV("span",{className:"flex-1 truncate",children:N.name},void 0,!1,void 0,this),m.jsxDEV("span",{className:"text-[10px] text-[#666]",children:N.count},void 0,!1,void 0,this)]},N.slug,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),s&&m.jsxDEV("div",{children:[m.jsxDEV("label",{className:"block text-xs text-[#888] mb-1.5",children:"Trigger"},void 0,!1,void 0,this),m.jsxDEV("div",{className:"relative",children:[m.jsxDEV("button",{onClick:()=>{H1(!u1),G1(!1),x1("")},className:"w-full flex items-center gap-2 bg-[#0a0a0a] border border-[#333] rounded px-3 py-2 text-sm text-left hover:border-[#555] transition",children:[M?m.jsxDEV(m.Fragment,{children:[m.jsxDEV("span",{className:"flex-1 truncate",children:M.name},void 0,!1,void 0,this),m.jsxDEV("span",{className:`text-[10px] px-1.5 py-0.5 rounded flex-shrink-0 ${M.type==="webhook"?"bg-blue-500/10 text-blue-400":"bg-yellow-500/10 text-yellow-400"}`,children:M.type},void 0,!1,void 0,this)]},void 0,!0,void 0,this):m.jsxDEV("span",{className:"text-[#666] flex-1",children:"Select trigger..."},void 0,!1,void 0,this),m.jsxDEV("span",{className:"text-[#666] text-xs ml-1",children:"▾"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),u1&&m.jsxDEV(m.Fragment,{children:[m.jsxDEV("div",{className:"fixed inset-0 z-10",onClick:()=>H1(!1)},void 0,!1,void 0,this),m.jsxDEV("div",{className:"absolute left-0 right-0 top-full mt-1 bg-[#0a0a0a] border border-[#333] rounded-lg shadow-xl z-20 max-h-64 flex flex-col",children:[e1.length>3&&m.jsxDEV("div",{className:"p-2 border-b border-[#1a1a1a] flex-shrink-0",children:m.jsxDEV("input",{type:"text",value:O1,onChange:(N)=>x1(N.target.value),placeholder:"Search triggers...",className:"w-full bg-[#111] border border-[#333] rounded px-2 py-1.5 text-sm focus:outline-none focus:border-[#f97316]",autoFocus:!0},void 0,!1,void 0,this)},void 0,!1,void 0,this),m.jsxDEV("div",{className:"overflow-y-auto flex-1",children:e1.filter((N)=>{if(!O1)return!0;let v=O1.toLowerCase();return N.name.toLowerCase().includes(v)||N.slug.toLowerCase().includes(v)||N.description.toLowerCase().includes(v)}).map((N)=>m.jsxDEV("button",{onClick:()=>{W1(N.slug),z1({}),H1(!1)},className:`w-full flex items-center gap-2 px-3 py-2 text-sm text-left transition hover:bg-[#1a1a1a] ${t===N.slug?"bg-[#1a1a1a] text-[#f97316]":""}`,children:[m.jsxDEV("div",{className:"flex-1 min-w-0",children:[m.jsxDEV("div",{className:"truncate",children:N.name},void 0,!1,void 0,this),m.jsxDEV("div",{className:"text-[10px] text-[#666] truncate",children:N.description},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m.jsxDEV("span",{className:`text-[10px] px-1.5 py-0.5 rounded flex-shrink-0 ${N.type==="webhook"?"bg-blue-500/10 text-blue-400":"bg-yellow-500/10 text-yellow-400"}`,children:N.type},void 0,!1,void 0,this)]},N.slug,!0,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),t&&m.jsxDEV("div",{children:[m.jsxDEV("label",{className:"block text-xs text-[#888] mb-1.5",children:"Connected Account"},void 0,!1,void 0,this),U1?m.jsxDEV("div",{className:"text-xs text-green-400 bg-green-500/10 border border-green-500/20 rounded p-3",children:["Connected: ",U1.appName]},void 0,!0,void 0,this):m.jsxDEV("div",{className:"text-xs text-yellow-400 bg-yellow-500/10 border border-yellow-500/20 rounded p-3",children:["No connected account for ",M?.toolkit_name||"this app",". Connect it first in the Integrations tab."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),M&&M.config_schema&&Object.keys(M.config_schema.properties||{}).length>0&&m.jsxDEV("div",{children:[m.jsxDEV("label",{className:"block text-xs text-[#888] mb-1.5",children:"Configuration"},void 0,!1,void 0,this),m.jsxDEV("div",{className:"space-y-2",children:Object.entries(M.config_schema.properties||{}).map(([N,v])=>{let _=(M.config_schema.required||[]).includes(N);return m.jsxDEV("div",{children:[m.jsxDEV("label",{className:"block text-[11px] text-[#888] mb-1",children:[v.title||N,_&&m.jsxDEV("span",{className:"text-red-400 ml-0.5",children:"*"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m.jsxDEV("input",{type:"text",value:B1[N]||"",onChange:(f)=>z1((K)=>({...K,[N]:f.target.value})),placeholder:v.description||`Enter ${v.title||N}...`,className:"w-full bg-[#0a0a0a] border border-[#333] rounded px-3 py-2 text-sm focus:outline-none focus:border-[#f97316]"},void 0,!1,void 0,this)]},N,!0,void 0,this)})},void 0,!1,void 0,this)]},void 0,!0,void 0,this),m.jsxDEV("div",{children:[m.jsxDEV("label",{className:"block text-xs text-[#888] mb-1.5",children:"Target Agent"},void 0,!1,void 0,this),h.length===0?m.jsxDEV("div",{className:"text-xs text-[#666] bg-[#0a0a0a] rounded p-3",children:"No agents available. Create an agent first."},void 0,!1,void 0,this):m.jsxDEV(x,{value:e,onChange:h1,placeholder:"Select agent...",options:h.map((N)=>({value:N.id,label:`${N.name} (${N.status})`}))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),m.jsxDEV("div",{className:"flex gap-2 mt-5",children:[m.jsxDEV("button",{onClick:()=>q1(!1),className:"flex-1 text-sm bg-[#1a1a1a] hover:bg-[#222] border border-[#333] px-4 py-2 rounded transition",children:"Cancel"},void 0,!1,void 0,this),m.jsxDEV("button",{onClick:O0,disabled:!t||!e||!U1||i1||M?.config_schema&&(M.config_schema.required||[]).some((N)=>!B1[N]?.trim()),className:"flex-1 text-sm bg-[#f97316] hover:bg-[#ea580c] text-white px-4 py-2 rounded transition disabled:opacity-50",children:i1?"Creating...":"Subscribe"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var P=O(X1(),1);var z=O(n(),1);function f0(){let{authFetch:R}=g(),{currentProjectId:H}=j(),J=H&&H!=="unassigned"?H:null,F=J?`?project_id=${J}`:"",[Q,V]=P.useState([]),[W,T]=P.useState("");P.useEffect(()=>{R(`/api/triggers/providers${F}`).then((G)=>G.json()).then((G)=>{let b=(G.providers||[]).filter((k)=>k.connected);if(V(b),b.length>0&&!b.find((k)=>k.id===W))T(b[0].id)}).catch(()=>{})},[R]);let[A,S]=P.useState(null),[l,Y]=P.useState([]),[y,I]=P.useState(!1),a=P.useCallback(async(G)=>{S(G),I(!0);try{let b=`/api/triggers/types?provider=${W}&toolkit_slugs=${G}`;if(J)b+=`&project_id=${J}`;let k=await R(b);if(k.ok){let o=await k.json();Y(o.types||[])}}catch(b){console.error("Failed to fetch trigger types:",b)}I(!1)},[R,J,W]);return z.jsxDEV("div",{children:[z.jsxDEV("p",{className:"text-sm text-[#666] mb-4",children:"Connect external apps via OAuth or API Key. Connected apps can be used for triggers and MCP integrations."},void 0,!1,void 0,this),Q.length>1&&z.jsxDEV("div",{className:"flex items-center gap-2 mb-4",children:[z.jsxDEV("span",{className:"text-xs text-[#666]",children:"Provider:"},void 0,!1,void 0,this),z.jsxDEV("div",{className:"flex gap-1 bg-[#111] border border-[#1a1a1a] rounded-lg p-0.5",children:Q.map((G)=>z.jsxDEV("button",{onClick:()=>T(G.id),className:`px-3 py-1 rounded text-xs font-medium transition ${W===G.id?"bg-[#1a1a1a] text-white":"text-[#666] hover:text-[#888]"}`,children:G.name},G.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),Q.length===0?z.jsxDEV("div",{className:"bg-[#111] border border-[#1a1a1a] rounded-lg p-8 text-center",children:[z.jsxDEV("p",{className:"text-[#666]",children:"No integration providers configured."},void 0,!1,void 0,this),z.jsxDEV("p",{className:"text-sm text-[#555] mt-1",children:"Add API keys for Composio or AgentDojo in Settings."},void 0,!1,void 0,this)]},void 0,!0,void 0,this):z.jsxDEV(_0,{providerId:W,projectId:J,hideMcpConfig:!0,onBrowseTriggers:a},void 0,!1,void 0,this),A&&z.jsxDEV("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",children:z.jsxDEV("div",{className:"bg-[#111] border border-[#333] rounded-lg w-full max-w-2xl mx-4 max-h-[80vh] flex flex-col",children:[z.jsxDEV("div",{className:"p-4 border-b border-[#1a1a1a] flex items-center justify-between",children:[z.jsxDEV("div",{children:[z.jsxDEV("h3",{className:"font-medium",children:"Trigger Types"},void 0,!1,void 0,this),z.jsxDEV("p",{className:"text-xs text-[#666]",children:A},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z.jsxDEV("button",{onClick:()=>{S(null),Y([])},className:"text-[#666] hover:text-white transition text-lg px-2",children:"x"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),z.jsxDEV("div",{className:"flex-1 overflow-auto p-4",children:y?z.jsxDEV("div",{className:"text-center py-8 text-[#666]",children:"Loading trigger types..."},void 0,!1,void 0,this):l.length===0?z.jsxDEV("div",{className:"text-center py-8 text-[#666]",children:"No trigger types available for this app."},void 0,!1,void 0,this):z.jsxDEV("div",{className:"space-y-2",children:l.map((G)=>z.jsxDEV("div",{className:"bg-[#0a0a0a] border border-[#1a1a1a] rounded-lg p-3",children:z.jsxDEV("div",{className:"flex items-start gap-3",children:[G.logo?z.jsxDEV("img",{src:G.logo,alt:G.toolkit_name,className:"w-6 h-6 rounded object-contain flex-shrink-0 mt-0.5"},void 0,!1,void 0,this):z.jsxDEV("div",{className:"w-6 h-6 rounded bg-[#1a1a1a] flex items-center justify-center text-[10px] flex-shrink-0 mt-0.5",children:G.toolkit_name?.[0]?.toUpperCase()||"?"},void 0,!1,void 0,this),z.jsxDEV("div",{className:"flex-1 min-w-0",children:[z.jsxDEV("div",{className:"text-sm font-medium",children:G.name},void 0,!1,void 0,this),z.jsxDEV("div",{className:"text-xs text-[#666] mt-0.5",children:G.description},void 0,!1,void 0,this),z.jsxDEV("div",{className:"flex items-center gap-2 mt-1.5",children:[z.jsxDEV("span",{className:"text-[10px] bg-[#1a1a1a] text-[#555] px-1.5 py-0.5 rounded font-mono",children:G.slug},void 0,!1,void 0,this),z.jsxDEV("span",{className:`text-[10px] px-1.5 py-0.5 rounded ${G.type==="webhook"?"bg-blue-500/10 text-blue-400":"bg-yellow-500/10 text-yellow-400"}`,children:G.type},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},G.slug,!1,void 0,this))},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}var w=O(n(),1);function JN(){let[R,H]=$0.useState("overview");return w.jsxDEV("div",{className:"flex-1 overflow-auto p-6",children:w.jsxDEV("div",{className:"max-w-6xl",children:[w.jsxDEV("div",{className:"flex items-center justify-between mb-6",children:w.jsxDEV("div",{children:[w.jsxDEV("h1",{className:"text-2xl font-semibold mb-1",children:"Connections"},void 0,!1,void 0,this),w.jsxDEV("p",{className:"text-[#666]",children:"Manage external app connections, triggers, and webhooks."},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),w.jsxDEV("div",{className:"flex gap-1 mb-6 bg-[#111] border border-[#1a1a1a] rounded-lg p-1 w-fit",children:[{id:"overview",label:"Overview"},{id:"triggers",label:"Triggers"},{id:"integrations",label:"Integrations"}].map((F)=>w.jsxDEV("button",{onClick:()=>H(F.id),className:`px-4 py-2 rounded text-sm font-medium transition ${R===F.id?"bg-[#1a1a1a] text-white":"text-[#666] hover:text-[#888]"}`,children:F.label},F.id,!1,void 0,this))},void 0,!1,void 0,this),R==="overview"&&w.jsxDEV(m0,{},void 0,!1,void 0,this),R==="triggers"&&w.jsxDEV(v0,{},void 0,!1,void 0,this),R==="integrations"&&w.jsxDEV(f0,{},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)}
2
+ export{I0 as a,JN as b};
3
+
4
+ //# debugId=59BAB8E2425680DC64756E2164756E21
@@ -0,0 +1,14 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/web/components/connections/ConnectionsPage.tsx", "../src/web/components/connections/OverviewTab.tsx", "../src/web/components/connections/TriggersTab.tsx", "../src/web/components/common/LoadingSpinner.tsx", "../src/web/components/connections/IntegrationsTab.tsx"],
4
+ "sourcesContent": [
5
+ "import React, { useState } from \"react\";\nimport { OverviewTab } from \"./OverviewTab\";\nimport { TriggersTab } from \"./TriggersTab\";\nimport { IntegrationsTab } from \"./IntegrationsTab\";\n\ntype Tab = \"overview\" | \"triggers\" | \"integrations\";\n\nexport function ConnectionsPage() {\n const [activeTab, setActiveTab] = useState<Tab>(\"overview\");\n\n const tabs: { id: Tab; label: string }[] = [\n { id: \"overview\", label: \"Overview\" },\n { id: \"triggers\", label: \"Triggers\" },\n { id: \"integrations\", label: \"Integrations\" },\n ];\n\n return (\n <div className=\"flex-1 overflow-auto p-6\">\n <div className=\"max-w-6xl\">\n {/* Header */}\n <div className=\"flex items-center justify-between mb-6\">\n <div>\n <h1 className=\"text-2xl font-semibold mb-1\">Connections</h1>\n <p className=\"text-[#666]\">\n Manage external app connections, triggers, and webhooks.\n </p>\n </div>\n </div>\n\n {/* Tabs */}\n <div className=\"flex gap-1 mb-6 bg-[#111] border border-[#1a1a1a] rounded-lg p-1 w-fit\">\n {tabs.map(tab => (\n <button\n key={tab.id}\n onClick={() => setActiveTab(tab.id)}\n className={`px-4 py-2 rounded text-sm font-medium transition ${\n activeTab === tab.id\n ? \"bg-[#1a1a1a] text-white\"\n : \"text-[#666] hover:text-[#888]\"\n }`}\n >\n {tab.label}\n </button>\n ))}\n </div>\n\n {/* Tab Content */}\n {activeTab === \"overview\" && <OverviewTab />}\n {activeTab === \"triggers\" && <TriggersTab />}\n {activeTab === \"integrations\" && <IntegrationsTab />}\n </div>\n </div>\n );\n}\n",
6
+ "import React, { useState, useEffect } from \"react\";\nimport { useAuth, useProjects } from \"../../context\";\n\ninterface Subscription {\n id: string;\n trigger_slug: string;\n trigger_instance_id: string | null;\n agent_id: string;\n enabled: boolean;\n project_id: string | null;\n created_at: string;\n updated_at: string;\n}\n\ninterface Agent {\n id: string;\n name: string;\n status: string;\n}\n\nexport function OverviewTab() {\n const { authFetch } = useAuth();\n const { currentProjectId } = useProjects();\n\n const [subscriptions, setSubscriptions] = useState<Subscription[]>([]);\n const [agents, setAgents] = useState<Agent[]>([]);\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n const fetchAll = async () => {\n setLoading(true);\n const projectParam = currentProjectId && currentProjectId !== \"unassigned\" ? `?project_id=${currentProjectId}` : \"\";\n\n try {\n const [subsRes, agentsRes] = await Promise.all([\n authFetch(`/api/subscriptions${projectParam}`).catch(() => null),\n authFetch(`/api/agents`).catch(() => null),\n ]);\n\n if (subsRes?.ok) {\n const data = await subsRes.json();\n setSubscriptions(data.subscriptions || []);\n }\n if (agentsRes?.ok) {\n const data = await agentsRes.json();\n setAgents(data.agents || []);\n }\n } catch (e) {\n console.error(\"Failed to fetch overview data:\", e);\n }\n setLoading(false);\n };\n\n fetchAll();\n }, [authFetch, currentProjectId]);\n\n if (loading) {\n return <div className=\"text-center py-12 text-[#666]\">Loading...</div>;\n }\n\n const enabledSubs = subscriptions.filter(s => s.enabled);\n const disabledSubs = subscriptions.filter(s => !s.enabled);\n const agentMap = new Map(agents.map(a => [a.id, a]));\n\n return (\n <div className=\"space-y-6\">\n {/* Stats */}\n <div className=\"grid grid-cols-3 gap-4\">\n <StatCard label=\"Active\" value={enabledSubs.length} />\n <StatCard label=\"Disabled\" value={disabledSubs.length} />\n <StatCard label=\"Total\" value={subscriptions.length} />\n </div>\n\n {/* Subscriptions */}\n <section>\n <h3 className=\"text-sm font-medium text-[#888] mb-3\">Subscriptions ({subscriptions.length})</h3>\n {subscriptions.length === 0 ? (\n <div className=\"bg-[#111] border border-[#1a1a1a] rounded-lg p-6 text-center text-[#666] text-sm\">\n No subscriptions yet. Go to the Triggers tab to create one.\n </div>\n ) : (\n <div className=\"space-y-2\">\n {subscriptions.map(sub => {\n const agent = agentMap.get(sub.agent_id);\n return (\n <div key={sub.id} className=\"bg-[#111] border border-[#1a1a1a] rounded-lg p-3 flex items-center gap-3\">\n <div className={`w-2 h-2 rounded-full flex-shrink-0 ${sub.enabled ? \"bg-green-400\" : \"bg-[#555]\"}`} />\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium truncate\">\n {sub.trigger_slug.replace(/_/g, \" \").replace(/-/g, \" \")}\n </div>\n <div className=\"text-xs text-[#666]\">\n {sub.trigger_instance_id\n ? `ID: ${sub.trigger_instance_id.slice(0, 12)}...`\n : \"All instances\"\n }\n </div>\n </div>\n <div className=\"text-xs text-[#888] flex-shrink-0\">\n <span className=\"text-[#555]\">&rarr;</span>{\" \"}\n <span className=\"text-[#f97316]\">{agent?.name || \"Unknown Agent\"}</span>\n </div>\n <span className={`text-xs px-2 py-0.5 rounded flex-shrink-0 ${\n sub.enabled\n ? \"bg-green-500/10 text-green-400\"\n : \"bg-[#1a1a1a] text-[#555]\"\n }`}>\n {sub.enabled ? \"active\" : \"disabled\"}\n </span>\n </div>\n );\n })}\n </div>\n )}\n </section>\n </div>\n );\n}\n\nfunction StatCard({\n label,\n value,\n valueColor,\n}: {\n label: string;\n value: string | number;\n valueColor?: string;\n}) {\n return (\n <div className=\"bg-[#111] border border-[#1a1a1a] rounded-lg p-4\">\n <div className=\"text-xs text-[#666] mb-1\">{label}</div>\n <div className={`text-2xl font-bold ${valueColor || \"text-[#e0e0e0]\"}`}>\n {value}\n </div>\n </div>\n );\n}\n",
7
+ "import React, { useState, useEffect, useCallback } from \"react\";\nimport { useAuth, useProjects } from \"../../context\";\nimport { Select } from \"../common\";\n\ninterface TriggerType {\n slug: string;\n name: string;\n description: string;\n type: \"webhook\" | \"poll\";\n toolkit_slug: string;\n toolkit_name: string;\n logo: string | null;\n config_schema: Record<string, unknown>;\n payload_schema: Record<string, unknown>;\n}\n\ninterface TriggerInstance {\n id: string;\n trigger_slug: string;\n connected_account_id: string | null;\n status: \"active\" | \"disabled\";\n config: Record<string, unknown>;\n created_at: string;\n}\n\ninterface Subscription {\n id: string;\n trigger_slug: string;\n trigger_instance_id: string | null;\n agent_id: string;\n enabled: boolean;\n project_id: string | null;\n created_at: string;\n updated_at: string;\n}\n\ninterface ConnectedAccount {\n id: string;\n appId: string;\n appName: string;\n status: string;\n}\n\ninterface IntegrationApp {\n id: string;\n name: string;\n slug: string;\n logo: string | null;\n}\n\ninterface Agent {\n id: string;\n name: string;\n status: string;\n port: number | null;\n}\n\ninterface TriggerProviderInfo {\n id: string;\n name: string;\n connected: boolean;\n}\n\nexport function TriggersTab() {\n const { authFetch } = useAuth();\n const { currentProjectId } = useProjects();\n\n // Provider selection — only show configured providers\n const [providers, setProviders] = useState<TriggerProviderInfo[]>([]);\n const [selectedProvider, setSelectedProvider] = useState(\"\");\n\n // Trigger instances (from selected provider)\n const [triggers, setTriggers] = useState<TriggerInstance[]>([]);\n const [triggersLoading, setTriggersLoading] = useState(true);\n\n // Subscriptions (local routing)\n const [subscriptions, setSubscriptions] = useState<Subscription[]>([]);\n\n // Browse trigger types\n const [triggerTypes, setTriggerTypes] = useState<TriggerType[]>([]);\n const [typesLoading, setTypesLoading] = useState(false);\n const [toolkitFilter, setToolkitFilter] = useState(\"\");\n const [typeSearch, setTypeSearch] = useState(\"\");\n\n // Create trigger\n const [showCreate, setShowCreate] = useState(false);\n const [selectedType, setSelectedType] = useState<TriggerType | null>(null);\n const [connectedAccounts, setConnectedAccounts] = useState<ConnectedAccount[]>([]);\n const [selectedAccountId, setSelectedAccountId] = useState(\"\");\n const [creating, setCreating] = useState(false);\n const [createAgentId, setCreateAgentId] = useState(\"\"); // For AgentDojo direct subscription flow\n const [browseConfig, setBrowseConfig] = useState<Record<string, string>>({});\n const [browseSelectedAccountId, setBrowseSelectedAccountId] = useState(\"\");\n\n // AgentDojo add subscription modal\n const [showAddDojo, setShowAddDojo] = useState(false);\n const [dojoTriggerTypes, setDojoTriggerTypes] = useState<TriggerType[]>([]);\n const [dojoTypesLoading, setDojoTypesLoading] = useState(false);\n const [dojoAccounts, setDojoAccounts] = useState<ConnectedAccount[]>([]);\n const [dojoApps, setDojoApps] = useState<IntegrationApp[]>([]);\n const [dojoSelectedToolkit, setDojoSelectedToolkit] = useState(\"\");\n const [dojoSelectedType, setDojoSelectedType] = useState<string>(\"\");\n const [dojoAgentId, setDojoAgentId] = useState(\"\");\n const [dojoCreating, setDojoCreating] = useState(false);\n const [dojoConfig, setDojoConfig] = useState<Record<string, string>>({});\n const [dojoSelectedAccountId, setDojoSelectedAccountId] = useState(\"\");\n const [dojoAppDropdownOpen, setDojoAppDropdownOpen] = useState(false);\n const [dojoAppSearch, setDojoAppSearch] = useState(\"\");\n const [dojoTriggerDropdownOpen, setDojoTriggerDropdownOpen] = useState(false);\n const [dojoTriggerSearch, setDojoTriggerSearch] = useState(\"\");\n\n // Add subscription\n const [showAddSub, setShowAddSub] = useState(false);\n const [subTriggerId, setSubTriggerId] = useState(\"\");\n const [subAgentId, setSubAgentId] = useState(\"\");\n const [addingSub, setAddingSub] = useState(false);\n\n // Agents\n const [agents, setAgents] = useState<Agent[]>([]);\n\n const [error, setError] = useState<string | null>(null);\n\n const projectParam = currentProjectId && currentProjectId !== \"unassigned\" ? `?project_id=${currentProjectId}` : \"\";\n\n // Fetch available providers — only show ones with API keys configured\n const fetchProviders = useCallback(async () => {\n try {\n const res = await authFetch(`/api/triggers/providers${projectParam}`);\n if (res.ok) {\n const data = await res.json();\n const connected = (data.providers || []).filter((p: TriggerProviderInfo) => p.connected);\n setProviders(connected);\n // Auto-select first connected provider if none selected\n if (connected.length > 0) {\n setSelectedProvider(prev => {\n if (!prev || !connected.find((p: TriggerProviderInfo) => p.id === prev)) return connected[0].id;\n return prev;\n });\n }\n }\n } catch (e) {\n console.error(\"Failed to fetch providers:\", e);\n }\n }, [authFetch]);\n\n // Fetch active triggers\n const fetchTriggers = useCallback(async () => {\n setTriggersLoading(true);\n try {\n const providerParam = `provider=${selectedProvider}`;\n const sep = projectParam ? \"&\" : \"?\";\n const url = projectParam\n ? `/api/triggers${projectParam}&${providerParam}`\n : `/api/triggers?${providerParam}`;\n const res = await authFetch(url);\n if (res.ok) {\n const data = await res.json();\n setTriggers(data.triggers || []);\n }\n } catch (e) {\n console.error(\"Failed to fetch triggers:\", e);\n }\n setTriggersLoading(false);\n }, [authFetch, projectParam, selectedProvider]);\n\n // Fetch subscriptions\n const fetchSubscriptions = useCallback(async () => {\n try {\n const res = await authFetch(`/api/subscriptions${projectParam}`);\n if (res.ok) {\n const data = await res.json();\n setSubscriptions(data.subscriptions || []);\n }\n } catch (e) {\n console.error(\"Failed to fetch subscriptions:\", e);\n }\n }, [authFetch, projectParam]);\n\n // Fetch agents (project-scoped)\n const fetchAgents = useCallback(async () => {\n try {\n const res = await authFetch(`/api/agents${projectParam}`);\n if (res.ok) {\n const data = await res.json();\n setAgents(data.agents || []);\n }\n } catch (e) {\n // Ignore\n }\n }, [authFetch, projectParam]);\n\n useEffect(() => {\n fetchProviders();\n fetchTriggers();\n fetchSubscriptions();\n fetchAgents();\n }, [fetchProviders, fetchTriggers, fetchSubscriptions, fetchAgents]);\n\n // Browse trigger types\n const browseTriggerTypes = async (toolkit?: string) => {\n setTypesLoading(true);\n try {\n let url = `/api/triggers/types?provider=${selectedProvider}`;\n if (toolkit) url += `&toolkit_slugs=${toolkit}`;\n if (currentProjectId && currentProjectId !== \"unassigned\") url += `&project_id=${currentProjectId}`;\n const res = await authFetch(url);\n if (res.ok) {\n const data = await res.json();\n setTriggerTypes(data.types || []);\n } else {\n const data = await res.json();\n setError(data.error || \"Failed to fetch trigger types\");\n }\n } catch (e) {\n setError(\"Failed to fetch trigger types\");\n }\n setTypesLoading(false);\n };\n\n // Fetch connected accounts when creating\n const fetchConnectedAccounts = async () => {\n try {\n const res = await authFetch(`/api/integrations/${selectedProvider}/connected${projectParam}`);\n if (res.ok) {\n const data = await res.json();\n setConnectedAccounts((data.accounts || []).filter((a: ConnectedAccount) => a.status === \"active\"));\n }\n } catch (e) {\n // Ignore\n }\n };\n\n // Start create flow\n const startCreate = (triggerType: TriggerType) => {\n setSelectedType(triggerType);\n setSelectedAccountId(\"\");\n setCreateAgentId(\"\");\n setBrowseConfig({});\n setBrowseSelectedAccountId(\"\");\n setShowCreate(true);\n fetchConnectedAccounts();\n };\n\n const isAgentDojo = selectedProvider === \"agentdojo\";\n\n // Open AgentDojo add subscription modal — fetches from agentdojo provider (same as Integrations tab)\n const openAddDojoSub = async () => {\n setShowAddDojo(true);\n setDojoSelectedType(\"\");\n setDojoSelectedToolkit(\"\");\n setDojoAgentId(\"\");\n setDojoConfig({});\n setDojoSelectedAccountId(\"\");\n\n const loadTypes = async () => {\n if (dojoTriggerTypes.length > 0) return;\n setDojoTypesLoading(true);\n try {\n let url = `/api/triggers/types?provider=agentdojo`;\n if (currentProjectId && currentProjectId !== \"unassigned\") url += `&project_id=${currentProjectId}`;\n const res = await authFetch(url);\n const data = await res.json();\n setDojoTriggerTypes(data.types || []);\n } catch (e) {\n console.error(\"Failed to load trigger types:\", e);\n }\n setDojoTypesLoading(false);\n };\n\n const loadAccounts = async () => {\n try {\n const url = `/api/integrations/agentdojo/connected${projectParam}`;\n const res = await authFetch(url);\n const data = await res.json();\n const active = (data.accounts || []).filter((a: ConnectedAccount) => a.status === \"active\");\n setDojoAccounts(active);\n } catch (e) {\n console.error(\"Failed to load connected accounts:\", e);\n }\n };\n\n const loadApps = async () => {\n if (dojoApps.length > 0) return;\n try {\n const url = `/api/integrations/agentdojo/apps${projectParam}`;\n const res = await authFetch(url);\n const data = await res.json();\n setDojoApps((data.apps || []).map((a: any) => ({ id: a.id, name: a.name, slug: a.slug, logo: a.logo })));\n } catch (e) {\n console.error(\"Failed to load apps:\", e);\n }\n };\n\n await Promise.all([loadTypes(), loadAccounts(), loadApps()]);\n };\n\n // Create AgentDojo subscription from the add-subscription modal\n const handleAddDojoSub = async () => {\n const tt = dojoTriggerTypes.find(t => t.slug === dojoSelectedType);\n // Use derived dojoMatchedAccount (respects user dropdown selection + auto-match fallback)\n const matched = dojoMatchedAccount;\n if (!tt || !dojoAgentId || !matched) return;\n\n setDojoCreating(true);\n setError(null);\n try {\n const agent = agents.find(a => a.id === dojoAgentId);\n const providerParam = `provider=agentdojo`;\n const url = projectParam\n ? `/api/triggers${projectParam}&${providerParam}`\n : `/api/triggers?${providerParam}`;\n const configPayload = {\n callback_url: `${window.location.origin}/api/webhooks/agentdojo`,\n title: `${tt.name} → ${agent?.name || \"Agent\"}`,\n server: tt.toolkit_slug,\n agent_id: dojoAgentId,\n ...dojoConfig,\n };\n const res = await authFetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n slug: tt.slug,\n connectedAccountId: matched.id,\n config: configPayload,\n }),\n });\n const data = await res.json();\n if (!res.ok) {\n setError(data.error || \"Failed to create subscription\");\n } else {\n setShowAddDojo(false);\n fetchTriggers();\n }\n } catch (e: any) {\n setError(e.message || \"Failed to create subscription\");\n }\n setDojoCreating(false);\n };\n\n // Create trigger (Composio: trigger instance, AgentDojo: subscription + agent routing)\n const handleCreate = async () => {\n if (!selectedType) return;\n\n // AgentDojo: create remote subscription directly (callback_url points to apteva webhook handler)\n if (isAgentDojo) {\n if (!createAgentId || !browseMatchedAccount) return;\n setCreating(true);\n setError(null);\n try {\n const agent = agents.find(a => a.id === createAgentId);\n const instanceUrl = window.location.origin;\n const providerParam = `provider=${selectedProvider}`;\n const url = projectParam\n ? `/api/triggers${projectParam}&${providerParam}`\n : `/api/triggers?${providerParam}`;\n const res = await authFetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n slug: selectedType.slug,\n connectedAccountId: browseMatchedAccount.id,\n config: {\n callback_url: `${instanceUrl}/api/webhooks/agentdojo`,\n title: `${selectedType.name} → ${agent?.name || \"Agent\"}`,\n server: selectedType.toolkit_slug,\n agent_id: createAgentId,\n ...browseConfig, // Dynamic config fields (e.g. owner, repo)\n },\n }),\n });\n const data = await res.json();\n if (!res.ok) {\n setError(data.error || \"Failed to create subscription\");\n } else {\n setShowCreate(false);\n setSelectedType(null);\n fetchTriggers();\n }\n } catch (e: any) {\n setError(e.message || \"Failed to create subscription\");\n }\n setCreating(false);\n return;\n }\n\n // Composio: standard trigger instance creation\n if (!selectedAccountId) return;\n setCreating(true);\n setError(null);\n try {\n const providerParam = `provider=${selectedProvider}`;\n const url = projectParam\n ? `/api/triggers${projectParam}&${providerParam}`\n : `/api/triggers?${providerParam}`;\n const res = await authFetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n slug: selectedType.slug,\n connectedAccountId: selectedAccountId,\n }),\n });\n const data = await res.json();\n if (!res.ok) {\n setError(data.error || \"Failed to create trigger\");\n } else {\n setShowCreate(false);\n setSelectedType(null);\n fetchTriggers();\n }\n } catch (e: any) {\n setError(e.message || \"Failed to create trigger\");\n }\n setCreating(false);\n };\n\n // Enable/disable trigger\n const toggleTrigger = async (triggerId: string, currentStatus: string) => {\n const action = currentStatus === \"active\" ? \"disable\" : \"enable\";\n try {\n const providerQ = projectParam ? `&provider=${selectedProvider}` : `?provider=${selectedProvider}`;\n const res = await authFetch(`/api/triggers/${triggerId}/${action}${projectParam}${providerQ}`, {\n method: \"POST\",\n });\n if (res.ok) {\n fetchTriggers();\n } else {\n const data = await res.json();\n setError(data.error || `Failed to ${action} trigger`);\n }\n } catch (e) {\n setError(`Failed to ${action} trigger`);\n }\n };\n\n // Delete trigger\n const deleteTrigger = async (triggerId: string) => {\n try {\n const providerQ = projectParam ? `&provider=${selectedProvider}` : `?provider=${selectedProvider}`;\n const res = await authFetch(`/api/triggers/${triggerId}${projectParam}${providerQ}`, {\n method: \"DELETE\",\n });\n if (res.ok) {\n fetchTriggers();\n } else {\n const data = await res.json();\n setError(data.error || \"Failed to delete trigger\");\n }\n } catch (e) {\n setError(\"Failed to delete trigger\");\n }\n };\n\n // Add subscription — backend auto-creates webhook if needed\n const handleAddSubscription = async () => {\n if (!subTriggerId || !subAgentId) return;\n\n // Find the trigger instance to get its slug\n const trigger = triggers.find(t => t.id === subTriggerId);\n if (!trigger) return;\n\n setAddingSub(true);\n setError(null);\n try {\n const res = await authFetch(`/api/subscriptions`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n trigger_slug: trigger.trigger_slug,\n trigger_instance_id: trigger.id,\n agent_id: subAgentId,\n provider: selectedProvider,\n project_id: currentProjectId && currentProjectId !== \"unassigned\" ? currentProjectId : null,\n public_url: window.location.origin,\n }),\n });\n const data = await res.json();\n if (!res.ok) {\n setError(data.error || \"Failed to create subscription\");\n } else {\n setShowAddSub(false);\n setSubTriggerId(\"\");\n setSubAgentId(\"\");\n fetchSubscriptions();\n }\n } catch (e: any) {\n setError(e.message || \"Failed to create subscription\");\n }\n setAddingSub(false);\n };\n\n // Toggle subscription\n const toggleSubscription = async (sub: Subscription) => {\n const action = sub.enabled ? \"disable\" : \"enable\";\n try {\n const res = await authFetch(`/api/subscriptions/${sub.id}/${action}`, {\n method: \"POST\",\n });\n if (res.ok) fetchSubscriptions();\n } catch (e) {\n setError(`Failed to ${action} subscription`);\n }\n };\n\n // Delete subscription\n const deleteSubscription = async (id: string) => {\n try {\n const res = await authFetch(`/api/subscriptions/${id}`, {\n method: \"DELETE\",\n });\n if (res.ok) fetchSubscriptions();\n } catch (e) {\n setError(\"Failed to delete subscription\");\n }\n };\n\n // Filter trigger types by search\n const filteredTypes = triggerTypes.filter(t => {\n if (!typeSearch) return true;\n const s = typeSearch.toLowerCase();\n return t.name.toLowerCase().includes(s) || t.slug.toLowerCase().includes(s) || t.description.toLowerCase().includes(s);\n });\n\n // Best-effort match connected account from toolkit slug\n // A single credential can serve multiple toolkits (e.g. \"OmniKit Platform\" for \"OmniKit Messaging\")\n const matchAccount = (accounts: ConnectedAccount[], toolkitSlug: string): ConnectedAccount | null => {\n if (!toolkitSlug || accounts.length === 0) return null;\n const slug = toolkitSlug.toLowerCase().replace(/[-_]/g, \" \");\n // Exact match\n const exact = accounts.find(a =>\n a.appId?.toLowerCase() === toolkitSlug.toLowerCase() ||\n a.appName?.toLowerCase() === toolkitSlug.toLowerCase()\n );\n if (exact) return exact;\n // Contains match\n const contains = accounts.find(a =>\n a.appId?.toLowerCase().includes(slug) ||\n a.appName?.toLowerCase().replace(/[-_]/g, \" \").includes(slug) ||\n slug.includes(a.appId?.toLowerCase() || \"\") ||\n slug.includes(a.appName?.toLowerCase().replace(/[-_]/g, \" \") || \"\")\n );\n if (contains) return contains;\n // Prefix match — first word overlap (e.g. \"omnikit\" matches \"omnikit platform\" and \"omnikit messaging\")\n const slugWords = slug.split(/\\s+/);\n return accounts.find(a => {\n const nameWords = (a.appName || \"\").toLowerCase().replace(/[-_]/g, \" \").split(/\\s+/);\n return slugWords[0] && nameWords[0] && slugWords[0] === nameWords[0];\n }) || null;\n };\n\n // Derived: auto-matched or user-selected account for Add Subscription modal\n const dojoSelectedTriggerType = dojoTriggerTypes.find(t => t.slug === dojoSelectedType);\n const dojoAutoMatch = dojoSelectedTriggerType ? matchAccount(dojoAccounts, dojoSelectedTriggerType.toolkit_slug) : null;\n const dojoMatchedAccount = dojoSelectedAccountId\n ? dojoAccounts.find(a => a.id === dojoSelectedAccountId) || dojoAutoMatch\n : dojoAutoMatch;\n\n // Derived: auto-matched or user-selected account for Browse Subscribe modal\n const browseAutoMatch = selectedType && isAgentDojo ? matchAccount(connectedAccounts, selectedType.toolkit_slug) : null;\n const browseMatchedAccount = browseSelectedAccountId\n ? connectedAccounts.find(a => a.id === browseSelectedAccountId) || browseAutoMatch\n : browseAutoMatch;\n\n // Derived: group trigger types by toolkit, enriched with logos from apps list\n const dojoToolkits = React.useMemo(() => {\n const appLogos = new Map<string, string>();\n for (const app of dojoApps) {\n if (app.logo) appLogos.set(app.slug, app.logo);\n }\n const map = new Map<string, { slug: string; name: string; logo: string | null; count: number }>();\n for (const t of dojoTriggerTypes) {\n const existing = map.get(t.toolkit_slug);\n if (existing) {\n existing.count++;\n } else {\n const logo = appLogos.get(t.toolkit_slug) || t.logo || null;\n map.set(t.toolkit_slug, { slug: t.toolkit_slug, name: t.toolkit_name, logo, count: 1 });\n }\n }\n return Array.from(map.values()).sort((a, b) => a.name.localeCompare(b.name));\n }, [dojoTriggerTypes, dojoApps]);\n\n // Derived: triggers for the selected toolkit\n const dojoToolkitTriggers = dojoSelectedToolkit\n ? dojoTriggerTypes.filter(t => t.toolkit_slug === dojoSelectedToolkit)\n : [];\n\n // Derived: selected toolkit info (for logo in trigger dropdown)\n const dojoSelectedToolkitInfo = dojoToolkits.find(t => t.slug === dojoSelectedToolkit);\n\n // Agent map for quick lookups\n const agentMap = new Map(agents.map(a => [a.id, a]));\n\n if (providers.length === 0 && !triggersLoading) {\n return (\n <div className=\"bg-[#111] border border-[#1a1a1a] rounded-lg p-8 text-center\">\n <p className=\"text-[#666]\">No trigger providers configured.</p>\n <p className=\"text-sm text-[#555] mt-1\">Add API keys for Composio or AgentDojo in Settings to enable triggers.</p>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6\">\n {/* Error */}\n {error && (\n <div className=\"text-red-400 text-sm p-3 bg-red-500/10 border border-red-500/20 rounded-lg flex items-center justify-between\">\n <span>{error}</span>\n <button onClick={() => setError(null)} className=\"text-red-400 hover:text-red-300\">x</button>\n </div>\n )}\n\n {/* Provider Selector — only show if multiple configured */}\n {providers.length > 1 && (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-[#666]\">Provider:</span>\n <div className=\"flex gap-1 bg-[#111] border border-[#1a1a1a] rounded-lg p-0.5\">\n {providers.map(p => (\n <button\n key={p.id}\n onClick={() => {\n setSelectedProvider(p.id);\n setTriggerTypes([]);\n setToolkitFilter(\"\");\n setTypeSearch(\"\");\n }}\n className={`px-3 py-1 rounded text-xs font-medium transition ${\n selectedProvider === p.id\n ? \"bg-[#1a1a1a] text-white\"\n : \"text-[#666] hover:text-[#888]\"\n }`}\n >\n {p.name}\n </button>\n ))}\n </div>\n </div>\n )}\n\n {/* Subscriptions (trigger → agent routing) — hide entirely for AgentDojo (handled in Active Subscriptions) */}\n {!isAgentDojo && (\n <section>\n <div className=\"flex items-center justify-between mb-3\">\n <h3 className=\"text-sm font-medium text-[#888]\">\n Subscriptions ({subscriptions.length})\n </h3>\n <button\n onClick={() => setShowAddSub(true)}\n className=\"text-xs bg-[#1a1a1a] hover:bg-[#222] border border-[#333] hover:border-[#f97316] px-3 py-1.5 rounded transition\"\n >\n + Add Subscription\n </button>\n </div>\n\n {subscriptions.length === 0 ? (\n <div className=\"bg-[#111] border border-[#1a1a1a] rounded-lg p-6 text-center text-[#666] text-sm\">\n No subscriptions yet. Add one to route trigger events to an agent.\n </div>\n ) : (\n <div className=\"space-y-2\">\n {subscriptions.map(sub => {\n const agent = agentMap.get(sub.agent_id);\n return (\n <div key={sub.id} className=\"bg-[#111] border border-[#1a1a1a] rounded-lg p-3 flex items-center gap-3\">\n <div className={`w-2 h-2 rounded-full flex-shrink-0 ${sub.enabled ? \"bg-green-400\" : \"bg-[#666]\"}`} />\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium truncate\">\n {sub.trigger_slug.replace(/_/g, \" \")}\n <span className=\"text-[#555] mx-1.5\">&rarr;</span>\n <span className=\"text-[#f97316]\">{agent?.name || \"Unknown Agent\"}</span>\n </div>\n <div className=\"text-xs text-[#666]\">\n {sub.trigger_instance_id\n ? `Instance: ${sub.trigger_instance_id.slice(0, 12)}...`\n : \"All instances\"\n }\n </div>\n </div>\n <div className=\"flex items-center gap-2 flex-shrink-0\">\n <button\n onClick={() => toggleSubscription(sub)}\n className={`text-xs px-3 py-1 rounded transition ${\n sub.enabled\n ? \"bg-yellow-500/10 text-yellow-400 hover:bg-yellow-500/20\"\n : \"bg-green-500/10 text-green-400 hover:bg-green-500/20\"\n }`}\n >\n {sub.enabled ? \"Disable\" : \"Enable\"}\n </button>\n <button\n onClick={() => deleteSubscription(sub.id)}\n className=\"text-xs text-[#666] hover:text-red-400 transition px-2\"\n >\n Delete\n </button>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </section>\n )}\n\n {/* Trigger Instances — only show for providers that have them (not AgentDojo) */}\n {!isAgentDojo && (\n <section>\n <h3 className=\"text-sm font-medium text-[#888] mb-3\">\n Trigger Instances ({triggers.length})\n </h3>\n {triggersLoading ? (\n <div className=\"text-center py-6 text-[#666] text-sm\">Loading triggers...</div>\n ) : triggers.length === 0 ? (\n <div className=\"bg-[#111] border border-[#1a1a1a] rounded-lg p-6 text-center text-[#666] text-sm\">\n No trigger instances. Browse trigger types below to create one.\n </div>\n ) : (\n <div className=\"space-y-2\">\n {triggers.map(trigger => (\n <div key={trigger.id} className=\"bg-[#111] border border-[#1a1a1a] rounded-lg p-3 flex items-center gap-3\">\n <div className={`w-2 h-2 rounded-full flex-shrink-0 ${trigger.status === \"active\" ? \"bg-green-400\" : \"bg-[#666]\"}`} />\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium truncate\">\n {trigger.trigger_slug.replace(/_/g, \" \")}\n </div>\n <div className=\"text-xs text-[#666]\">\n ID: {trigger.id.slice(0, 12)}... | Created: {new Date(trigger.created_at).toLocaleDateString()}\n </div>\n </div>\n <div className=\"flex items-center gap-2 flex-shrink-0\">\n <button\n onClick={() => toggleTrigger(trigger.id, trigger.status)}\n className={`text-xs px-3 py-1 rounded transition ${\n trigger.status === \"active\"\n ? \"bg-yellow-500/10 text-yellow-400 hover:bg-yellow-500/20\"\n : \"bg-green-500/10 text-green-400 hover:bg-green-500/20\"\n }`}\n >\n {trigger.status === \"active\" ? \"Disable\" : \"Enable\"}\n </button>\n <button\n onClick={() => deleteTrigger(trigger.id)}\n className=\"text-xs text-[#666] hover:text-red-400 transition px-2\"\n >\n Delete\n </button>\n </div>\n </div>\n ))}\n </div>\n )}\n </section>\n )}\n\n {/* AgentDojo Active Subscriptions — shows remote subscriptions directly */}\n {isAgentDojo && (\n <section>\n <div className=\"flex items-center justify-between mb-3\">\n <h3 className=\"text-sm font-medium text-[#888]\">\n Active Subscriptions ({triggers.length})\n </h3>\n <button\n onClick={openAddDojoSub}\n className=\"text-xs bg-[#1a1a1a] hover:bg-[#222] border border-[#333] hover:border-[#f97316] px-3 py-1.5 rounded transition\"\n >\n + Add Subscription\n </button>\n </div>\n {triggersLoading ? (\n <div className=\"text-center py-6 text-[#666] text-sm\">Loading subscriptions...</div>\n ) : triggers.length === 0 ? (\n <div className=\"bg-[#111] border border-[#1a1a1a] rounded-lg p-6 text-center text-[#666] text-sm\">\n No active subscriptions. Browse trigger types below to create one.\n </div>\n ) : (\n <div className=\"space-y-2\">\n {triggers.map(trigger => {\n const localSub = subscriptions.find(s => s.trigger_instance_id === trigger.id);\n const agent = localSub ? agentMap.get(localSub.agent_id) : null;\n return (\n <div key={trigger.id} className=\"bg-[#111] border border-[#1a1a1a] rounded-lg p-3 flex items-center gap-3\">\n <div className={`w-2 h-2 rounded-full flex-shrink-0 ${trigger.status === \"active\" ? \"bg-green-400\" : \"bg-[#666]\"}`} />\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium truncate\">\n {(trigger.config?.title as string) || trigger.trigger_slug.replace(/_/g, \" \")}\n {agent && (\n <>\n <span className=\"text-[#555] mx-1.5\">&rarr;</span>\n <span className=\"text-[#f97316]\">{agent.name}</span>\n </>\n )}\n </div>\n <div className=\"text-xs text-[#666]\">\n {trigger.config?.server && <span>{String(trigger.config.server)} | </span>}\n ID: {String(trigger.id).slice(0, 8)} | Created: {new Date(trigger.created_at).toLocaleDateString()}\n </div>\n </div>\n <div className=\"flex items-center gap-2 flex-shrink-0\">\n <button\n onClick={() => toggleTrigger(trigger.id, trigger.status)}\n className={`text-xs px-3 py-1 rounded transition ${\n trigger.status === \"active\"\n ? \"bg-yellow-500/10 text-yellow-400 hover:bg-yellow-500/20\"\n : \"bg-green-500/10 text-green-400 hover:bg-green-500/20\"\n }`}\n >\n {trigger.status === \"active\" ? \"Disable\" : \"Enable\"}\n </button>\n <button\n onClick={() => deleteTrigger(trigger.id)}\n className=\"text-xs text-[#666] hover:text-red-400 transition px-2\"\n >\n Delete\n </button>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </section>\n )}\n\n {/* Browse Trigger Types */}\n <section>\n <h3 className=\"text-sm font-medium text-[#888] mb-3\">Browse Trigger Types</h3>\n <div className=\"flex gap-2 mb-3\">\n <input\n type=\"text\"\n value={toolkitFilter}\n onChange={(e) => setToolkitFilter(e.target.value)}\n placeholder=\"Toolkit filter (e.g. github, gmail, slack)\"\n className=\"flex-1 bg-[#111] border border-[#333] rounded px-3 py-2 text-sm focus:outline-none focus:border-[#f97316]\"\n />\n <button\n onClick={() => browseTriggerTypes(toolkitFilter || undefined)}\n disabled={typesLoading}\n className=\"text-sm bg-[#1a1a1a] hover:bg-[#222] border border-[#333] hover:border-[#f97316] px-4 py-2 rounded transition disabled:opacity-50\"\n >\n {typesLoading ? \"Loading...\" : \"Browse\"}\n </button>\n </div>\n\n {triggerTypes.length > 0 && (\n <>\n <input\n type=\"text\"\n value={typeSearch}\n onChange={(e) => setTypeSearch(e.target.value)}\n placeholder=\"Search trigger types...\"\n className=\"w-full bg-[#111] border border-[#333] rounded px-3 py-2 text-sm mb-3 focus:outline-none focus:border-[#f97316]\"\n />\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n {filteredTypes.slice(0, 30).map(tt => (\n <div key={tt.slug} className=\"bg-[#111] border border-[#1a1a1a] hover:border-[#333] rounded-lg p-3 transition\">\n <div className=\"flex items-start gap-3\">\n {tt.logo ? (\n <img src={tt.logo} alt={tt.toolkit_name} className=\"w-8 h-8 rounded object-contain flex-shrink-0\" />\n ) : (\n <div className=\"w-8 h-8 rounded bg-[#1a1a1a] flex items-center justify-center text-xs flex-shrink-0\">\n {tt.toolkit_name?.[0]?.toUpperCase() || \"?\"}\n </div>\n )}\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium truncate\">{tt.name}</div>\n <div className=\"text-xs text-[#666]\">{tt.toolkit_name}</div>\n <div className=\"text-xs text-[#555] mt-1 line-clamp-2\">{tt.description}</div>\n </div>\n </div>\n <button\n onClick={() => startCreate(tt)}\n className=\"w-full mt-3 text-xs bg-[#1a1a1a] hover:bg-[#222] border border-[#333] hover:border-[#f97316] px-3 py-1.5 rounded transition\"\n >\n {isAgentDojo ? \"Subscribe\" : \"Create Trigger\"}\n </button>\n </div>\n ))}\n </div>\n {filteredTypes.length > 30 && (\n <p className=\"text-xs text-[#555] mt-3 text-center\">\n Showing first 30 of {filteredTypes.length} types. Use search to filter.\n </p>\n )}\n </>\n )}\n </section>\n\n {/* Create Trigger Modal */}\n {showCreate && selectedType && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-[#111] border border-[#333] rounded-lg p-6 w-full max-w-md mx-4\">\n <h3 className=\"font-medium mb-1\">\n {isAgentDojo ? \"Create Subscription\" : \"Create Trigger\"}\n </h3>\n <p className=\"text-xs text-[#666] mb-4\">\n {selectedType.name}\n {selectedType.toolkit_name && <span className=\"text-[#555]\"> ({selectedType.toolkit_name})</span>}\n </p>\n\n <div className=\"space-y-4\">\n {/* Connected Account — only for Composio */}\n {!isAgentDojo && (\n <div>\n <label className=\"block text-xs text-[#888] mb-1.5\">Connected Account</label>\n {connectedAccounts.length === 0 ? (\n <div className=\"text-xs text-[#666] bg-[#0a0a0a] rounded p-3\">\n No connected accounts available. Connect an app first in the Integrations tab.\n </div>\n ) : (\n <Select\n value={selectedAccountId}\n onChange={setSelectedAccountId}\n placeholder=\"Select account...\"\n options={connectedAccounts.map(acc => ({\n value: acc.id,\n label: `${acc.appName} (${acc.id.slice(0, 8)}...)`,\n }))}\n />\n )}\n </div>\n )}\n\n {/* Agent selection — for AgentDojo direct subscription */}\n {isAgentDojo && (\n <div>\n <label className=\"block text-xs text-[#888] mb-1.5\">Route to Agent</label>\n {agents.length === 0 ? (\n <div className=\"text-xs text-[#666] bg-[#0a0a0a] rounded p-3\">\n No agents available. Create an agent first.\n </div>\n ) : (\n <Select\n value={createAgentId}\n onChange={setCreateAgentId}\n placeholder=\"Select agent...\"\n options={agents.map(agent => ({\n value: agent.id,\n label: `${agent.name} (${agent.status})`,\n }))}\n />\n )}\n\n {/* Connected account — auto-matched from toolkit */}\n <div className=\"mt-3\">\n <label className=\"block text-xs text-[#888] mb-1.5\">Connected Account</label>\n {browseMatchedAccount ? (\n <div className=\"text-xs text-green-400 bg-green-500/10 border border-green-500/20 rounded p-3\">\n Connected: {browseMatchedAccount.appName}\n </div>\n ) : (\n <div className=\"text-xs text-yellow-400 bg-yellow-500/10 border border-yellow-500/20 rounded p-3\">\n No connected account for {selectedType?.toolkit_name || \"this app\"}. Connect it first in the Integrations tab.\n </div>\n )}\n </div>\n\n {/* Dynamic config fields from config_schema */}\n {selectedType.config_schema && Object.keys((selectedType.config_schema as any).properties || {}).length > 0 && (\n <div className=\"mt-3\">\n <label className=\"block text-xs text-[#888] mb-1.5\">Configuration</label>\n <div className=\"space-y-2\">\n {Object.entries((selectedType.config_schema as any).properties || {}).map(([key, schema]: [string, any]) => {\n const required = ((selectedType.config_schema as any).required || []).includes(key);\n return (\n <div key={key}>\n <label className=\"block text-[11px] text-[#888] mb-1\">\n {schema.title || key}\n {required && <span className=\"text-red-400 ml-0.5\">*</span>}\n </label>\n <input\n type=\"text\"\n value={browseConfig[key] || \"\"}\n onChange={(e) => setBrowseConfig(prev => ({ ...prev, [key]: e.target.value }))}\n placeholder={schema.description || `Enter ${schema.title || key}...`}\n className=\"w-full bg-[#0a0a0a] border border-[#333] rounded px-3 py-2 text-sm focus:outline-none focus:border-[#f97316]\"\n />\n </div>\n );\n })}\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n\n <div className=\"flex gap-2 mt-4\">\n <button\n onClick={() => { setShowCreate(false); setSelectedType(null); }}\n className=\"flex-1 text-sm bg-[#1a1a1a] hover:bg-[#222] border border-[#333] px-4 py-2 rounded transition\"\n >\n Cancel\n </button>\n <button\n onClick={handleCreate}\n disabled={isAgentDojo ? (\n !createAgentId || !browseMatchedAccount || creating ||\n (selectedType?.config_schema && ((selectedType.config_schema as any).required || []).some((key: string) => !browseConfig[key]?.trim()))\n ) : (!selectedAccountId || creating)}\n className=\"flex-1 text-sm bg-[#f97316] hover:bg-[#ea580c] text-white px-4 py-2 rounded transition disabled:opacity-50\"\n >\n {creating ? \"Creating...\" : isAgentDojo ? \"Subscribe\" : \"Create\"}\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* Add Subscription Modal */}\n {showAddSub && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-[#111] border border-[#333] rounded-lg p-6 w-full max-w-md mx-4\">\n <h3 className=\"font-medium mb-1\">Route Trigger to Agent</h3>\n <p className=\"text-xs text-[#666] mb-4\">\n {triggers.length === 0\n ? \"No trigger instances yet. Create one first from the Browse section below.\"\n : \"Select a trigger instance and the agent that should handle its events.\"\n }\n </p>\n\n {triggers.length > 0 ? (\n <>\n <div className=\"space-y-4\">\n <div>\n <label className=\"block text-xs text-[#888] mb-1.5\">Trigger Instance</label>\n <Select\n value={subTriggerId}\n onChange={setSubTriggerId}\n placeholder=\"Select trigger...\"\n options={triggers.map(t => ({\n value: t.id,\n label: `${t.trigger_slug.replace(/_/g, \" \")}`,\n }))}\n />\n {subTriggerId && (\n <div className=\"text-xs text-[#555] mt-1 font-mono\">\n ID: {subTriggerId.slice(0, 16)}...\n </div>\n )}\n </div>\n\n <div>\n <label className=\"block text-xs text-[#888] mb-1.5\">Target Agent</label>\n <Select\n value={subAgentId}\n onChange={setSubAgentId}\n placeholder=\"Select agent...\"\n options={agents.map(agent => ({\n value: agent.id,\n label: `${agent.name} (${agent.status})`,\n }))}\n />\n </div>\n </div>\n\n <div className=\"flex gap-2 mt-5\">\n <button\n onClick={() => { setShowAddSub(false); setSubTriggerId(\"\"); setSubAgentId(\"\"); }}\n className=\"flex-1 text-sm bg-[#1a1a1a] hover:bg-[#222] border border-[#333] px-4 py-2 rounded transition\"\n >\n Cancel\n </button>\n <button\n onClick={handleAddSubscription}\n disabled={!subTriggerId || !subAgentId || addingSub}\n className=\"flex-1 text-sm bg-[#f97316] hover:bg-[#ea580c] text-white px-4 py-2 rounded transition disabled:opacity-50\"\n >\n {addingSub ? \"Adding...\" : \"Add\"}\n </button>\n </div>\n </>\n ) : (\n <div className=\"flex gap-2 mt-4\">\n <button\n onClick={() => setShowAddSub(false)}\n className=\"flex-1 text-sm bg-[#1a1a1a] hover:bg-[#222] border border-[#333] px-4 py-2 rounded transition\"\n >\n Close\n </button>\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* AgentDojo Add Subscription Modal */}\n {showAddDojo && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-[#111] border border-[#333] rounded-lg p-6 w-full max-w-lg mx-4\">\n <h3 className=\"font-medium mb-1\">Add Subscription</h3>\n <p className=\"text-xs text-[#666] mb-4\">\n Select an app and trigger, then route it to an agent.\n </p>\n\n {dojoTypesLoading ? (\n <div className=\"text-center py-8 text-[#666] text-sm\">Loading...</div>\n ) : dojoTriggerTypes.length === 0 ? (\n <div className=\"text-center py-8 text-[#666] text-sm\">\n No triggers available. Connect an app first in the Integrations tab.\n </div>\n ) : (\n <div className=\"space-y-4\">\n {/* App selector — custom dropdown with logos */}\n <div>\n <label className=\"block text-xs text-[#888] mb-1.5\">App</label>\n <div className=\"relative\">\n <button\n onClick={() => { setDojoAppDropdownOpen(!dojoAppDropdownOpen); setDojoTriggerDropdownOpen(false); setDojoAppSearch(\"\"); }}\n className=\"w-full flex items-center gap-2 bg-[#0a0a0a] border border-[#333] rounded px-3 py-2 text-sm text-left hover:border-[#555] transition\"\n >\n {dojoSelectedToolkitInfo ? (\n <>\n {dojoSelectedToolkitInfo.logo ? (\n <img src={dojoSelectedToolkitInfo.logo} alt=\"\" className=\"w-5 h-5 rounded object-contain flex-shrink-0\" />\n ) : (\n <div className=\"w-5 h-5 rounded bg-[#1a1a1a] flex items-center justify-center text-[10px] flex-shrink-0\">\n {dojoSelectedToolkitInfo.name?.[0]?.toUpperCase() || \"?\"}\n </div>\n )}\n <span className=\"flex-1 truncate\">{dojoSelectedToolkitInfo.name}</span>\n <span className=\"text-[10px] text-[#666]\">{dojoSelectedToolkitInfo.count} triggers</span>\n </>\n ) : (\n <span className=\"text-[#666] flex-1\">Select app...</span>\n )}\n <span className=\"text-[#666] text-xs ml-1\">&#9662;</span>\n </button>\n {dojoAppDropdownOpen && (\n <>\n <div className=\"fixed inset-0 z-10\" onClick={() => setDojoAppDropdownOpen(false)} />\n <div className=\"absolute left-0 right-0 top-full mt-1 bg-[#0a0a0a] border border-[#333] rounded-lg shadow-xl z-20 max-h-64 flex flex-col\">\n <div className=\"p-2 border-b border-[#1a1a1a] flex-shrink-0\">\n <input\n type=\"text\"\n value={dojoAppSearch}\n onChange={(e) => setDojoAppSearch(e.target.value)}\n placeholder=\"Search apps...\"\n className=\"w-full bg-[#111] border border-[#333] rounded px-2 py-1.5 text-sm focus:outline-none focus:border-[#f97316]\"\n autoFocus\n />\n </div>\n <div className=\"overflow-y-auto flex-1\">\n {dojoToolkits\n .filter(tk => {\n if (!dojoAppSearch) return true;\n const s = dojoAppSearch.toLowerCase();\n return tk.name.toLowerCase().includes(s) || tk.slug.toLowerCase().includes(s);\n })\n .map(tk => (\n <button\n key={tk.slug}\n onClick={() => {\n setDojoSelectedToolkit(tk.slug);\n setDojoSelectedType(\"\");\n setDojoConfig({});\n setDojoAppDropdownOpen(false);\n }}\n className={`w-full flex items-center gap-2 px-3 py-2 text-sm text-left transition hover:bg-[#1a1a1a] ${\n dojoSelectedToolkit === tk.slug ? \"bg-[#1a1a1a] text-[#f97316]\" : \"\"\n }`}\n >\n {tk.logo ? (\n <img src={tk.logo} alt=\"\" className=\"w-5 h-5 rounded object-contain flex-shrink-0\" />\n ) : (\n <div className=\"w-5 h-5 rounded bg-[#1a1a1a] flex items-center justify-center text-[10px] flex-shrink-0\">\n {tk.name?.[0]?.toUpperCase() || \"?\"}\n </div>\n )}\n <span className=\"flex-1 truncate\">{tk.name}</span>\n <span className=\"text-[10px] text-[#666]\">{tk.count}</span>\n </button>\n ))}\n </div>\n </div>\n </>\n )}\n </div>\n </div>\n\n {/* Trigger selector — only shown when app is selected */}\n {dojoSelectedToolkit && (\n <div>\n <label className=\"block text-xs text-[#888] mb-1.5\">Trigger</label>\n <div className=\"relative\">\n <button\n onClick={() => { setDojoTriggerDropdownOpen(!dojoTriggerDropdownOpen); setDojoAppDropdownOpen(false); setDojoTriggerSearch(\"\"); }}\n className=\"w-full flex items-center gap-2 bg-[#0a0a0a] border border-[#333] rounded px-3 py-2 text-sm text-left hover:border-[#555] transition\"\n >\n {dojoSelectedTriggerType ? (\n <>\n <span className=\"flex-1 truncate\">{dojoSelectedTriggerType.name}</span>\n <span className={`text-[10px] px-1.5 py-0.5 rounded flex-shrink-0 ${\n dojoSelectedTriggerType.type === \"webhook\" ? \"bg-blue-500/10 text-blue-400\" : \"bg-yellow-500/10 text-yellow-400\"\n }`}>\n {dojoSelectedTriggerType.type}\n </span>\n </>\n ) : (\n <span className=\"text-[#666] flex-1\">Select trigger...</span>\n )}\n <span className=\"text-[#666] text-xs ml-1\">&#9662;</span>\n </button>\n {dojoTriggerDropdownOpen && (\n <>\n <div className=\"fixed inset-0 z-10\" onClick={() => setDojoTriggerDropdownOpen(false)} />\n <div className=\"absolute left-0 right-0 top-full mt-1 bg-[#0a0a0a] border border-[#333] rounded-lg shadow-xl z-20 max-h-64 flex flex-col\">\n {dojoToolkitTriggers.length > 3 && (\n <div className=\"p-2 border-b border-[#1a1a1a] flex-shrink-0\">\n <input\n type=\"text\"\n value={dojoTriggerSearch}\n onChange={(e) => setDojoTriggerSearch(e.target.value)}\n placeholder=\"Search triggers...\"\n className=\"w-full bg-[#111] border border-[#333] rounded px-2 py-1.5 text-sm focus:outline-none focus:border-[#f97316]\"\n autoFocus\n />\n </div>\n )}\n <div className=\"overflow-y-auto flex-1\">\n {dojoToolkitTriggers\n .filter(t => {\n if (!dojoTriggerSearch) return true;\n const s = dojoTriggerSearch.toLowerCase();\n return t.name.toLowerCase().includes(s) || t.slug.toLowerCase().includes(s) || t.description.toLowerCase().includes(s);\n })\n .map(t => (\n <button\n key={t.slug}\n onClick={() => {\n setDojoSelectedType(t.slug);\n setDojoConfig({});\n setDojoTriggerDropdownOpen(false);\n }}\n className={`w-full flex items-center gap-2 px-3 py-2 text-sm text-left transition hover:bg-[#1a1a1a] ${\n dojoSelectedType === t.slug ? \"bg-[#1a1a1a] text-[#f97316]\" : \"\"\n }`}\n >\n <div className=\"flex-1 min-w-0\">\n <div className=\"truncate\">{t.name}</div>\n <div className=\"text-[10px] text-[#666] truncate\">{t.description}</div>\n </div>\n <span className={`text-[10px] px-1.5 py-0.5 rounded flex-shrink-0 ${\n t.type === \"webhook\" ? \"bg-blue-500/10 text-blue-400\" : \"bg-yellow-500/10 text-yellow-400\"\n }`}>\n {t.type}\n </span>\n </button>\n ))}\n </div>\n </div>\n </>\n )}\n </div>\n </div>\n )}\n\n {/* Connected account — auto-matched */}\n {dojoSelectedType && (\n <div>\n <label className=\"block text-xs text-[#888] mb-1.5\">Connected Account</label>\n {dojoMatchedAccount ? (\n <div className=\"text-xs text-green-400 bg-green-500/10 border border-green-500/20 rounded p-3\">\n Connected: {dojoMatchedAccount.appName}\n </div>\n ) : (\n <div className=\"text-xs text-yellow-400 bg-yellow-500/10 border border-yellow-500/20 rounded p-3\">\n No connected account for {dojoSelectedTriggerType?.toolkit_name || \"this app\"}. Connect it first in the Integrations tab.\n </div>\n )}\n </div>\n )}\n\n {/* Dynamic config fields from config_schema */}\n {dojoSelectedTriggerType && dojoSelectedTriggerType.config_schema && Object.keys(dojoSelectedTriggerType.config_schema.properties || {}).length > 0 && (\n <div>\n <label className=\"block text-xs text-[#888] mb-1.5\">Configuration</label>\n <div className=\"space-y-2\">\n {Object.entries((dojoSelectedTriggerType.config_schema as any).properties || {}).map(([key, schema]: [string, any]) => {\n const required = ((dojoSelectedTriggerType.config_schema as any).required || []).includes(key);\n return (\n <div key={key}>\n <label className=\"block text-[11px] text-[#888] mb-1\">\n {schema.title || key}\n {required && <span className=\"text-red-400 ml-0.5\">*</span>}\n </label>\n <input\n type=\"text\"\n value={dojoConfig[key] || \"\"}\n onChange={(e) => setDojoConfig(prev => ({ ...prev, [key]: e.target.value }))}\n placeholder={schema.description || `Enter ${schema.title || key}...`}\n className=\"w-full bg-[#0a0a0a] border border-[#333] rounded px-3 py-2 text-sm focus:outline-none focus:border-[#f97316]\"\n />\n </div>\n );\n })}\n </div>\n </div>\n )}\n\n {/* Agent selection */}\n <div>\n <label className=\"block text-xs text-[#888] mb-1.5\">Target Agent</label>\n {agents.length === 0 ? (\n <div className=\"text-xs text-[#666] bg-[#0a0a0a] rounded p-3\">\n No agents available. Create an agent first.\n </div>\n ) : (\n <Select\n value={dojoAgentId}\n onChange={setDojoAgentId}\n placeholder=\"Select agent...\"\n options={agents.map(agent => ({\n value: agent.id,\n label: `${agent.name} (${agent.status})`,\n }))}\n />\n )}\n </div>\n </div>\n )}\n\n <div className=\"flex gap-2 mt-5\">\n <button\n onClick={() => setShowAddDojo(false)}\n className=\"flex-1 text-sm bg-[#1a1a1a] hover:bg-[#222] border border-[#333] px-4 py-2 rounded transition\"\n >\n Cancel\n </button>\n <button\n onClick={handleAddDojoSub}\n disabled={!dojoSelectedType || !dojoAgentId || !dojoMatchedAccount || dojoCreating || (\n dojoSelectedTriggerType?.config_schema &&\n ((dojoSelectedTriggerType.config_schema as any).required || []).some((key: string) => !dojoConfig[key]?.trim())\n )}\n className=\"flex-1 text-sm bg-[#f97316] hover:bg-[#ea580c] text-white px-4 py-2 rounded transition disabled:opacity-50\"\n >\n {dojoCreating ? \"Creating...\" : \"Subscribe\"}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n}\n",
8
+ "import React from \"react\";\n\ninterface LoadingSpinnerProps {\n message?: string;\n fullScreen?: boolean;\n}\n\nexport function LoadingSpinner({ message = \"Loading...\", fullScreen = false }: LoadingSpinnerProps) {\n const content = (\n <div className=\"flex items-center gap-3 text-[#666]\">\n <svg className=\"animate-spin h-5 w-5\" viewBox=\"0 0 24 24\">\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n fill=\"none\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n <span>{message}</span>\n </div>\n );\n\n if (fullScreen) {\n return (\n <div className=\"min-h-screen bg-[#0a0a0a] text-[#e0e0e0] font-mono flex items-center justify-center\">\n {content}\n </div>\n );\n }\n\n return (\n <div className=\"flex items-center justify-center py-20\">\n {content}\n </div>\n );\n}\n",
9
+ "import React, { useState, useEffect, useCallback } from \"react\";\nimport { useAuth, useProjects } from \"../../context\";\nimport { IntegrationsPanel } from \"../mcp/IntegrationsPanel\";\n\ninterface TriggerType {\n slug: string;\n name: string;\n description: string;\n type: \"webhook\" | \"poll\";\n toolkit_slug: string;\n toolkit_name: string;\n logo: string | null;\n}\n\ninterface ProviderInfo {\n id: string;\n name: string;\n connected: boolean;\n}\n\nexport function IntegrationsTab() {\n const { authFetch } = useAuth();\n const { currentProjectId } = useProjects();\n\n const projectId = currentProjectId && currentProjectId !== \"unassigned\" ? currentProjectId : null;\n const projectParam = projectId ? `?project_id=${projectId}` : \"\";\n\n // Provider selection — only show configured providers\n const [providers, setProviders] = useState<ProviderInfo[]>([]);\n const [selectedProvider, setSelectedProvider] = useState(\"\");\n\n useEffect(() => {\n authFetch(`/api/triggers/providers${projectParam}`)\n .then(r => r.json())\n .then(data => {\n const connected = (data.providers || []).filter((p: ProviderInfo) => p.connected);\n setProviders(connected);\n if (connected.length > 0 && !connected.find((p: ProviderInfo) => p.id === selectedProvider)) {\n setSelectedProvider(connected[0].id);\n }\n })\n .catch(() => {});\n }, [authFetch]);\n\n // Trigger type browsing\n const [browsingToolkit, setBrowsingToolkit] = useState<string | null>(null);\n const [triggerTypes, setTriggerTypes] = useState<TriggerType[]>([]);\n const [typesLoading, setTypesLoading] = useState(false);\n\n const handleBrowseTriggers = useCallback(async (toolkitSlug: string) => {\n setBrowsingToolkit(toolkitSlug);\n setTypesLoading(true);\n try {\n let url = `/api/triggers/types?provider=${selectedProvider}&toolkit_slugs=${toolkitSlug}`;\n if (projectId) url += `&project_id=${projectId}`;\n const res = await authFetch(url);\n if (res.ok) {\n const data = await res.json();\n setTriggerTypes(data.types || []);\n }\n } catch (e) {\n console.error(\"Failed to fetch trigger types:\", e);\n }\n setTypesLoading(false);\n }, [authFetch, projectId, selectedProvider]);\n\n return (\n <div>\n <p className=\"text-sm text-[#666] mb-4\">\n Connect external apps via OAuth or API Key. Connected apps can be used for triggers and MCP integrations.\n </p>\n\n {/* Provider Selector — only show if multiple configured */}\n {providers.length > 1 && (\n <div className=\"flex items-center gap-2 mb-4\">\n <span className=\"text-xs text-[#666]\">Provider:</span>\n <div className=\"flex gap-1 bg-[#111] border border-[#1a1a1a] rounded-lg p-0.5\">\n {providers.map(p => (\n <button\n key={p.id}\n onClick={() => setSelectedProvider(p.id)}\n className={`px-3 py-1 rounded text-xs font-medium transition ${\n selectedProvider === p.id\n ? \"bg-[#1a1a1a] text-white\"\n : \"text-[#666] hover:text-[#888]\"\n }`}\n >\n {p.name}\n </button>\n ))}\n </div>\n </div>\n )}\n\n {providers.length === 0 ? (\n <div className=\"bg-[#111] border border-[#1a1a1a] rounded-lg p-8 text-center\">\n <p className=\"text-[#666]\">No integration providers configured.</p>\n <p className=\"text-sm text-[#555] mt-1\">Add API keys for Composio or AgentDojo in Settings.</p>\n </div>\n ) : (\n <IntegrationsPanel\n providerId={selectedProvider}\n projectId={projectId}\n hideMcpConfig\n onBrowseTriggers={handleBrowseTriggers}\n />\n )}\n\n {/* Trigger Types Panel */}\n {browsingToolkit && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-[#111] border border-[#333] rounded-lg w-full max-w-2xl mx-4 max-h-[80vh] flex flex-col\">\n <div className=\"p-4 border-b border-[#1a1a1a] flex items-center justify-between\">\n <div>\n <h3 className=\"font-medium\">Trigger Types</h3>\n <p className=\"text-xs text-[#666]\">{browsingToolkit}</p>\n </div>\n <button\n onClick={() => { setBrowsingToolkit(null); setTriggerTypes([]); }}\n className=\"text-[#666] hover:text-white transition text-lg px-2\"\n >\n x\n </button>\n </div>\n\n <div className=\"flex-1 overflow-auto p-4\">\n {typesLoading ? (\n <div className=\"text-center py-8 text-[#666]\">Loading trigger types...</div>\n ) : triggerTypes.length === 0 ? (\n <div className=\"text-center py-8 text-[#666]\">\n No trigger types available for this app.\n </div>\n ) : (\n <div className=\"space-y-2\">\n {triggerTypes.map(tt => (\n <div key={tt.slug} className=\"bg-[#0a0a0a] border border-[#1a1a1a] rounded-lg p-3\">\n <div className=\"flex items-start gap-3\">\n {tt.logo ? (\n <img src={tt.logo} alt={tt.toolkit_name} className=\"w-6 h-6 rounded object-contain flex-shrink-0 mt-0.5\" />\n ) : (\n <div className=\"w-6 h-6 rounded bg-[#1a1a1a] flex items-center justify-center text-[10px] flex-shrink-0 mt-0.5\">\n {tt.toolkit_name?.[0]?.toUpperCase() || \"?\"}\n </div>\n )}\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium\">{tt.name}</div>\n <div className=\"text-xs text-[#666] mt-0.5\">{tt.description}</div>\n <div className=\"flex items-center gap-2 mt-1.5\">\n <span className=\"text-[10px] bg-[#1a1a1a] text-[#555] px-1.5 py-0.5 rounded font-mono\">\n {tt.slug}\n </span>\n <span className={`text-[10px] px-1.5 py-0.5 rounded ${\n tt.type === \"webhook\" ? \"bg-blue-500/10 text-blue-400\" : \"bg-yellow-500/10 text-yellow-400\"\n }`}>\n {tt.type}\n </span>\n </div>\n </div>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n )}\n </div>\n );\n}\n"
10
+ ],
11
+ "mappings": "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",
12
+ "debugId": "59BAB8E2425680DC64756E2164756E21",
13
+ "names": []
14
+ }
@@ -0,0 +1,4 @@
1
+ import{S as d,V as _q,W as qq,ca as Hq}from"./App.mvtqv6qc.js";var U=d(_q(),1);var q=d(qq(),1);function i(J){return J.authSchemes.some((Q)=>Q.toUpperCase()==="API_KEY")}function Jq(J){return J.authSchemes.some((Q)=>Q.toUpperCase()==="OAUTH2")}function $q(J){return i(J)&&Jq(J)}function Rq({providerId:J="composio",projectId:Q,onConnectionComplete:k,onBrowseTriggers:F,hideMcpConfig:K}){let{authFetch:Y}=Hq(),[y,R]=U.useState([]),[L,P]=U.useState([]),[M,N]=U.useState(!0),[m,Qq]=U.useState(""),[A,B]=U.useState(null),[O,l]=U.useState(null),[r,X]=U.useState(null),[_,I]=U.useState(null),[$,b]=U.useState(null),[f,u]=U.useState(""),[w,V]=U.useState(null),[v,c]=U.useState(""),[s,g]=U.useState(!1),[n,x]=U.useState(null),[C,D]=U.useState(null),G=U.useCallback(async()=>{N(!0),X(null);let z=Q&&Q!=="unassigned"?`?project_id=${Q}`:"";try{let[H,W]=await Promise.all([Y(`/api/integrations/${J}/apps${z}`),Y(`/api/integrations/${J}/connected${z}`)]),Z=await H.json(),j=await W.json();R(Z.apps||[]),P(j.accounts||[])}catch(H){console.error("Failed to fetch integrations:",H),X("Failed to load integrations")}N(!1)},[Y,J,Q]);U.useEffect(()=>{G()},[G]),U.useEffect(()=>{if(new URLSearchParams(window.location.search).get("connected"))window.history.replaceState({},"",window.location.pathname),G(),k?.()},[G,k]),U.useEffect(()=>{if(!O?.connectionId)return;let z=Q&&Q!=="unassigned"?`?project_id=${Q}`:"",H=setInterval(async()=>{try{let Z=await(await Y(`/api/integrations/${J}/connection/${O.connectionId}${z}`)).json();if(Z.connection?.status==="active")l(null),B(null),G(),k?.();else if(Z.connection?.status==="failed")l(null),B(null),X(`Connection to ${O.appSlug} failed`)}catch(W){}},2000);return()=>clearInterval(H)},[O,Y,J,Q,G,k]);let h=async(z,H,W)=>{if($q(z)&&!H&&!W){I({app:z});return}if(i(z)&&!H&&!W){b({app:z}),u("");return}B(z.slug),X(null);try{let Z={appSlug:z.slug};if(H)Z.credentials={authScheme:"API_KEY",apiKey:H};let j=Q&&Q!=="unassigned"?`?project_id=${Q}`:"",p=await Y(`/api/integrations/${J}/connect${j}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(Z)}),T=await p.json();if(!p.ok){X(T.error||"Failed to initiate connection"),B(null),b(null);return}if(T.status==="active"||!T.redirectUrl){B(null),b(null),G(),k?.();return}if(T.redirectUrl){l({appSlug:z.slug,connectionId:T.connectionId});let e=window.open(T.redirectUrl,`connect-${z.slug}`,"width=600,height=700,left=200,top=100");if(!e||e.closed)window.location.href=T.redirectUrl}}catch(Z){X(`Failed to connect: ${Z}`),B(null),b(null)}},Uq=(z)=>{if(z.preventDefault(),!$||!f.trim())return;h($.app,f.trim())},Wq=async(z)=>{let H=Q&&Q!=="unassigned"?`?project_id=${Q}`:"";try{let W=await Y(`/api/integrations/${J}/connection/${z.id}${H}`,{method:"DELETE"});if(W.ok)G();else{let Z=await W.json();X(Z.error||"Failed to disconnect")}}catch(W){X(`Failed to disconnect: ${W}`)}},Xq=(z)=>{V({app:z}),c(`${z.name} MCP`),x(null)},Yq=async()=>{if(!w||!v.trim())return;g(!0),X(null);try{let z=Q&&Q!=="unassigned"?`?project_id=${Q}`:"",H=await Y(`/api/integrations/${J}/configs${z}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:v.replace(/[^a-zA-Z0-9\s-]/g,"").substring(0,30),toolkitSlug:w.app.slug})}),W=await H.json();if(!H.ok){X(W.error||"Failed to create MCP config"),g(!1);return}x(v),k?.()}catch(z){X(`Failed to create MCP config: ${z}`)}finally{g(!1)}},Zq=(z)=>{D({message:`Disconnect ${z.appName}?`,onConfirm:()=>{Wq(z),D(null)}})},a=(z)=>{return L.some((H)=>H.appId===z&&H.status==="active")},t=(z)=>{return L.find((H)=>H.appId===z&&H.status==="active")||L.find((H)=>H.appId===z)},o=y.filter((z)=>{if(!m)return!0;let H=m.toLowerCase();return z.name.toLowerCase().includes(H)||z.slug.toLowerCase().includes(H)||z.description?.toLowerCase().includes(H)||z.categories.some((W)=>W.toLowerCase().includes(H))}),E=o.filter((z)=>a(z.slug)),S=o.filter((z)=>!a(z.slug));if(M)return q.jsxDEV("div",{className:"text-center py-8 text-[#666]",children:"Loading apps..."},void 0,!1,void 0,this);return q.jsxDEV("div",{className:"space-y-6",children:[_&&q.jsxDEV("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",children:q.jsxDEV("div",{className:"bg-[#111] border border-[#333] rounded-lg p-6 w-full max-w-md mx-4",children:[q.jsxDEV("div",{className:"flex items-center gap-3 mb-4",children:[_.app.logo&&q.jsxDEV("img",{src:_.app.logo,alt:_.app.name,className:"w-10 h-10 object-contain"},void 0,!1,void 0,this),q.jsxDEV("div",{children:[q.jsxDEV("h3",{className:"font-medium",children:["Connect ",_.app.name]},void 0,!0,void 0,this),q.jsxDEV("p",{className:"text-xs text-[#666]",children:"Choose how to authenticate"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.jsxDEV("div",{className:"space-y-3",children:[q.jsxDEV("button",{onClick:()=>{I(null),b({app:_.app}),u("")},className:"w-full text-left p-3 bg-[#0a0a0a] hover:bg-[#1a1a1a] border border-[#333] hover:border-[#f97316] rounded-lg transition",children:[q.jsxDEV("div",{className:"font-medium text-sm",children:"API Key"},void 0,!1,void 0,this),q.jsxDEV("div",{className:"text-xs text-[#666] mt-0.5",children:["Enter your ",_.app.name," API key directly"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.jsxDEV("button",{onClick:()=>{I(null),h(_.app,void 0,!0)},className:"w-full text-left p-3 bg-[#0a0a0a] hover:bg-[#1a1a1a] border border-[#333] hover:border-[#f97316] rounded-lg transition",children:[q.jsxDEV("div",{className:"font-medium text-sm",children:"OAuth"},void 0,!1,void 0,this),q.jsxDEV("div",{className:"text-xs text-[#666] mt-0.5",children:["Sign in with your ",_.app.name," account"]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.jsxDEV("button",{onClick:()=>I(null),className:"w-full text-sm text-[#666] hover:text-white mt-4 py-2 transition",children:"Cancel"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),$&&q.jsxDEV("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",children:q.jsxDEV("div",{className:"bg-[#111] border border-[#333] rounded-lg p-6 w-full max-w-md mx-4",children:[q.jsxDEV("div",{className:"flex items-center gap-3 mb-4",children:[$.app.logo&&q.jsxDEV("img",{src:$.app.logo,alt:$.app.name,className:"w-10 h-10 object-contain"},void 0,!1,void 0,this),q.jsxDEV("div",{children:[q.jsxDEV("h3",{className:"font-medium",children:["Connect ",$.app.name]},void 0,!0,void 0,this),q.jsxDEV("p",{className:"text-xs text-[#666]",children:"Enter your API key to connect"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.jsxDEV("form",{onSubmit:Uq,children:[q.jsxDEV("input",{type:"password",value:f,onChange:(z)=>u(z.target.value),placeholder:"Enter API Key...",className:"w-full bg-[#0a0a0a] border border-[#333] rounded-lg px-4 py-2 mb-4 focus:outline-none focus:border-[#f97316]",autoFocus:!0},void 0,!1,void 0,this),q.jsxDEV("div",{className:"flex gap-2",children:[q.jsxDEV("button",{type:"button",onClick:()=>b(null),className:"flex-1 text-sm bg-[#1a1a1a] hover:bg-[#222] border border-[#333] px-4 py-2 rounded transition",children:"Cancel"},void 0,!1,void 0,this),q.jsxDEV("button",{type:"submit",disabled:!f.trim()||A===$.app.slug,className:"flex-1 text-sm bg-[#f97316] hover:bg-[#ea580c] text-white px-4 py-2 rounded transition disabled:opacity-50",children:A===$.app.slug?"Connecting...":"Connect"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),w&&q.jsxDEV("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",children:q.jsxDEV("div",{className:"bg-[#111] border border-[#333] rounded-lg p-6 w-full max-w-md mx-4",children:n?q.jsxDEV(q.Fragment,{children:[q.jsxDEV("div",{className:"text-center mb-4",children:[q.jsxDEV("div",{className:"w-12 h-12 bg-green-500/20 rounded-full flex items-center justify-center mx-auto mb-3",children:q.jsxDEV("span",{className:"text-green-400 text-2xl",children:"✓"},void 0,!1,void 0,this)},void 0,!1,void 0,this),q.jsxDEV("h3",{className:"font-medium text-lg",children:"MCP Config Created!"},void 0,!1,void 0,this),q.jsxDEV("p",{className:"text-sm text-[#888] mt-2",children:['"',n,'" has been created successfully.']},void 0,!0,void 0,this),q.jsxDEV("p",{className:"text-xs text-[#666] mt-2",children:"You can now add it to your agents from the MCP Configs tab."},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q.jsxDEV("button",{onClick:()=>{V(null),x(null)},className:"w-full text-sm bg-[#f97316] hover:bg-[#ea580c] text-white px-4 py-2 rounded transition",children:"Done"},void 0,!1,void 0,this)]},void 0,!0,void 0,this):q.jsxDEV(q.Fragment,{children:[q.jsxDEV("div",{className:"flex items-center gap-3 mb-4",children:[w.app.logo&&q.jsxDEV("img",{src:w.app.logo,alt:w.app.name,className:"w-10 h-10 object-contain"},void 0,!1,void 0,this),q.jsxDEV("div",{children:[q.jsxDEV("h3",{className:"font-medium",children:"Create MCP Config"},void 0,!1,void 0,this),q.jsxDEV("p",{className:"text-xs text-[#666]",children:["Create an MCP config for ",w.app.name]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.jsxDEV("form",{onSubmit:(z)=>{z.preventDefault(),Yq()},children:[q.jsxDEV("label",{className:"block text-xs text-[#888] mb-1",children:"Config Name"},void 0,!1,void 0,this),q.jsxDEV("input",{type:"text",value:v,onChange:(z)=>c(z.target.value),placeholder:"Enter config name...",className:"w-full bg-[#0a0a0a] border border-[#333] rounded-lg px-4 py-2 mb-4 focus:outline-none focus:border-[#f97316]",autoFocus:!0,maxLength:30},void 0,!1,void 0,this),q.jsxDEV("div",{className:"flex gap-2",children:[q.jsxDEV("button",{type:"button",onClick:()=>V(null),className:"flex-1 text-sm bg-[#1a1a1a] hover:bg-[#222] border border-[#333] px-4 py-2 rounded transition",children:"Cancel"},void 0,!1,void 0,this),q.jsxDEV("button",{type:"submit",disabled:!v.trim()||s,className:"flex-1 text-sm bg-[#f97316] hover:bg-[#ea580c] text-white px-4 py-2 rounded transition disabled:opacity-50",children:s?"Creating...":"Create Config"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this)},void 0,!1,void 0,this),C&&q.jsxDEV("div",{className:"fixed inset-0 bg-black/50 flex items-center justify-center z-50",children:q.jsxDEV("div",{className:"bg-[#111] border border-[#333] rounded-lg p-6 w-full max-w-sm mx-4",children:[q.jsxDEV("p",{className:"text-center mb-4",children:C.message},void 0,!1,void 0,this),q.jsxDEV("div",{className:"flex gap-2",children:[q.jsxDEV("button",{onClick:()=>D(null),className:"flex-1 text-sm bg-[#1a1a1a] hover:bg-[#222] border border-[#333] px-4 py-2 rounded transition",children:"Cancel"},void 0,!1,void 0,this),q.jsxDEV("button",{onClick:C.onConfirm,className:"flex-1 text-sm bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded transition",children:"Confirm"},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)},void 0,!1,void 0,this),r&&q.jsxDEV("div",{className:"text-red-400 text-sm p-3 bg-red-500/10 border border-red-500/20 rounded-lg flex items-center justify-between",children:[q.jsxDEV("span",{children:r},void 0,!1,void 0,this),q.jsxDEV("button",{onClick:()=>X(null),className:"text-red-400 hover:text-red-300",children:"×"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),O&&q.jsxDEV("div",{className:"text-yellow-400 text-sm p-3 bg-yellow-500/10 border border-yellow-500/20 rounded-lg flex items-center gap-2",children:[q.jsxDEV("span",{className:"animate-spin",children:"⟳"},void 0,!1,void 0,this),q.jsxDEV("span",{children:["Waiting for ",O.appSlug," authorization..."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.jsxDEV("div",{children:q.jsxDEV("input",{type:"text",value:m,onChange:(z)=>Qq(z.target.value),placeholder:"Search apps...",className:"w-full bg-[#111] border border-[#333] rounded-lg px-4 py-2 focus:outline-none focus:border-[#f97316]"},void 0,!1,void 0,this)},void 0,!1,void 0,this),E.length>0&&q.jsxDEV("div",{children:[q.jsxDEV("h3",{className:"text-sm font-medium text-[#888] mb-3",children:["Connected (",E.length,")"]},void 0,!0,void 0,this),q.jsxDEV("div",{className:"grid gap-3 sm:grid-cols-2 lg:grid-cols-3",children:E.map((z)=>q.jsxDEV(zq,{app:z,connection:t(z.slug),onConnect:()=>h(z),onDisconnect:()=>{let H=t(z.slug);if(H)Zq(H)},onCreateMcpConfig:K?void 0:()=>Xq(z),onBrowseTriggers:F?()=>F(z.slug):void 0,connecting:A===z.slug},z.id,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this),q.jsxDEV("div",{children:[q.jsxDEV("h3",{className:"text-sm font-medium text-[#888] mb-3",children:["Available Apps (",S.length,")"]},void 0,!0,void 0,this),S.length===0?q.jsxDEV("p",{className:"text-[#666] text-sm",children:m?"No apps match your search":"No apps available"},void 0,!1,void 0,this):q.jsxDEV("div",{className:"grid gap-3 sm:grid-cols-2 lg:grid-cols-3",children:S.slice(0,50).map((z)=>q.jsxDEV(zq,{app:z,onConnect:()=>h(z),connecting:A===z.slug},z.id,!1,void 0,this))},void 0,!1,void 0,this),S.length>50&&q.jsxDEV("p",{className:"text-xs text-[#555] mt-3 text-center",children:["Showing first 50 of ",S.length," apps. Use search to find more."]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this)}function zq({app:J,connection:Q,onConnect:k,onDisconnect:F,onCreateMcpConfig:K,onBrowseTriggers:Y,connecting:y}){let R=Q?.status==="active",L=i(J),P=Jq(J),M=L&&P;return q.jsxDEV("div",{className:`bg-[#111] border rounded-lg p-3 transition ${R?"border-green-500/30":"border-[#1a1a1a] hover:border-[#333]"}`,children:[q.jsxDEV("div",{className:"flex items-start gap-3",children:[q.jsxDEV("div",{className:"w-10 h-10 rounded bg-[#1a1a1a] flex items-center justify-center flex-shrink-0 overflow-hidden",children:J.logo?q.jsxDEV("img",{src:J.logo,alt:J.name,className:"w-8 h-8 object-contain",onError:(N)=>{N.target.style.display="none"}},void 0,!1,void 0,this):q.jsxDEV("span",{className:"text-lg",children:J.name[0]?.toUpperCase()},void 0,!1,void 0,this)},void 0,!1,void 0,this),q.jsxDEV("div",{className:"flex-1 min-w-0",children:[q.jsxDEV("div",{className:"flex items-center gap-2",children:[q.jsxDEV("h4",{className:"font-medium text-sm truncate",children:J.name},void 0,!1,void 0,this),R&&q.jsxDEV("span",{className:"text-xs text-green-400",children:"✓"},void 0,!1,void 0,this),!R&&L&&!P&&q.jsxDEV("span",{className:"text-[10px] bg-[#222] text-[#888] px-1.5 py-0.5 rounded",title:"Requires API Key",children:"API Key"},void 0,!1,void 0,this),!R&&M&&q.jsxDEV("span",{className:"text-[10px] bg-[#1a2a1a] text-[#6a6] px-1.5 py-0.5 rounded",title:"Supports API Key or OAuth",children:"API Key / OAuth"},void 0,!1,void 0,this)]},void 0,!0,void 0,this),J.description&&q.jsxDEV("p",{className:"text-xs text-[#666] line-clamp-2 mt-0.5",children:J.description},void 0,!1,void 0,this),J.categories.length>0&&q.jsxDEV("div",{className:"flex flex-wrap gap-1 mt-1",children:J.categories.slice(0,2).map((N)=>q.jsxDEV("span",{className:"text-[10px] bg-[#1a1a1a] text-[#555] px-1.5 py-0.5 rounded",children:N},N,!1,void 0,this))},void 0,!1,void 0,this)]},void 0,!0,void 0,this)]},void 0,!0,void 0,this),q.jsxDEV("div",{className:"mt-3 flex gap-2",children:R?q.jsxDEV(q.Fragment,{children:[K&&q.jsxDEV("button",{onClick:K,className:"flex-1 text-xs bg-[#1a2a1a] hover:bg-[#1a3a1a] border border-green-500/30 hover:border-green-500/50 text-green-400 px-3 py-1.5 rounded transition",children:"Create MCP Config"},void 0,!1,void 0,this),Y&&q.jsxDEV("button",{onClick:Y,className:"flex-1 text-xs bg-[#1a1a2a] hover:bg-[#1a1a3a] border border-blue-500/30 hover:border-blue-500/50 text-blue-400 px-3 py-1.5 rounded transition",children:"Browse Triggers"},void 0,!1,void 0,this),F&&q.jsxDEV("button",{onClick:F,className:"text-xs text-[#666] hover:text-red-400 transition px-2",title:"Disconnect",children:"×"},void 0,!1,void 0,this)]},void 0,!0,void 0,this):q.jsxDEV("button",{onClick:k,disabled:y,className:"w-full text-xs bg-[#1a1a1a] hover:bg-[#222] border border-[#333] hover:border-[#f97316] px-3 py-1.5 rounded transition disabled:opacity-50",children:y?"Connecting...":L&&!P?"Enter API Key":"Connect"},void 0,!1,void 0,this)},void 0,!1,void 0,this)]},void 0,!0,void 0,this)}
2
+ export{Rq as k};
3
+
4
+ //# debugId=879C1544186FFE2D64756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/web/components/mcp/IntegrationsPanel.tsx"],
4
+ "sourcesContent": [
5
+ "import React, { useState, useEffect, useCallback } from \"react\";\nimport { useAuth } from \"../../context\";\n\n// Types\ninterface IntegrationApp {\n id: string;\n name: string;\n slug: string;\n description: string | null;\n logo: string | null;\n categories: string[];\n authSchemes: string[];\n}\n\ninterface ConnectedAccount {\n id: string;\n appId: string;\n appName: string;\n status: \"active\" | \"pending\" | \"failed\" | \"expired\";\n createdAt: string;\n}\n\ninterface IntegrationProvider {\n id: string;\n name: string;\n connected: boolean;\n}\n\n// Check if app supports API_KEY auth\nfunction supportsApiKey(app: IntegrationApp): boolean {\n return app.authSchemes.some(s => s.toUpperCase() === \"API_KEY\");\n}\n\n// Check if app supports OAuth\nfunction supportsOAuth(app: IntegrationApp): boolean {\n return app.authSchemes.some(s => s.toUpperCase() === \"OAUTH2\");\n}\n\n// Check if app supports multiple auth methods\nfunction hasMultipleAuthMethods(app: IntegrationApp): boolean {\n return supportsApiKey(app) && supportsOAuth(app);\n}\n\n// Main component\nexport function IntegrationsPanel({\n providerId = \"composio\",\n projectId,\n onConnectionComplete,\n onBrowseTriggers,\n hideMcpConfig,\n}: {\n providerId?: string;\n projectId?: string | null;\n onConnectionComplete?: () => void;\n onBrowseTriggers?: (toolkitSlug: string) => void;\n hideMcpConfig?: boolean;\n}) {\n const { authFetch } = useAuth();\n const [apps, setApps] = useState<IntegrationApp[]>([]);\n const [connectedAccounts, setConnectedAccounts] = useState<ConnectedAccount[]>([]);\n const [loading, setLoading] = useState(true);\n const [search, setSearch] = useState(\"\");\n const [connecting, setConnecting] = useState<string | null>(null);\n const [pendingConnection, setPendingConnection] = useState<{\n appSlug: string;\n connectionId?: string;\n } | null>(null);\n const [error, setError] = useState<string | null>(null);\n // For auth method selection (when app supports both OAuth and API Key)\n const [authMethodModal, setAuthMethodModal] = useState<{ app: IntegrationApp } | null>(null);\n // For API Key modal\n const [apiKeyModal, setApiKeyModal] = useState<{ app: IntegrationApp } | null>(null);\n const [apiKeyInput, setApiKeyInput] = useState(\"\");\n // For MCP config creation modal\n const [mcpConfigModal, setMcpConfigModal] = useState<{ app: IntegrationApp } | null>(null);\n const [mcpConfigName, setMcpConfigName] = useState(\"\");\n const [mcpConfigCreating, setMcpConfigCreating] = useState(false);\n const [mcpConfigSuccess, setMcpConfigSuccess] = useState<string | null>(null);\n // For confirmation modal\n const [confirmModal, setConfirmModal] = useState<{\n message: string;\n onConfirm: () => void;\n } | null>(null);\n\n // Fetch apps and connected accounts\n const fetchData = useCallback(async () => {\n setLoading(true);\n setError(null);\n const projectParam = projectId && projectId !== \"unassigned\" ? `?project_id=${projectId}` : \"\";\n try {\n const [appsRes, connectedRes] = await Promise.all([\n authFetch(`/api/integrations/${providerId}/apps${projectParam}`),\n authFetch(`/api/integrations/${providerId}/connected${projectParam}`),\n ]);\n\n const appsData = await appsRes.json();\n const connectedData = await connectedRes.json();\n\n setApps(appsData.apps || []);\n setConnectedAccounts(connectedData.accounts || []);\n } catch (e) {\n console.error(\"Failed to fetch integrations:\", e);\n setError(\"Failed to load integrations\");\n }\n setLoading(false);\n }, [authFetch, providerId, projectId]);\n\n useEffect(() => {\n fetchData();\n }, [fetchData]);\n\n // Check for connection completion from URL params\n useEffect(() => {\n const params = new URLSearchParams(window.location.search);\n const connectedApp = params.get(\"connected\");\n if (connectedApp) {\n // Remove the query param\n window.history.replaceState({}, \"\", window.location.pathname);\n // Refresh to show new connection\n fetchData();\n onConnectionComplete?.();\n }\n }, [fetchData, onConnectionComplete]);\n\n // Poll for pending connection status\n useEffect(() => {\n if (!pendingConnection?.connectionId) return;\n const projectParam = projectId && projectId !== \"unassigned\" ? `?project_id=${projectId}` : \"\";\n\n const pollInterval = setInterval(async () => {\n try {\n const res = await authFetch(\n `/api/integrations/${providerId}/connection/${pendingConnection.connectionId}${projectParam}`\n );\n const data = await res.json();\n\n if (data.connection?.status === \"active\") {\n setPendingConnection(null);\n setConnecting(null);\n fetchData();\n onConnectionComplete?.();\n } else if (data.connection?.status === \"failed\") {\n setPendingConnection(null);\n setConnecting(null);\n setError(`Connection to ${pendingConnection.appSlug} failed`);\n }\n } catch (e) {\n // Keep polling\n }\n }, 2000);\n\n return () => clearInterval(pollInterval);\n }, [pendingConnection, authFetch, providerId, projectId, fetchData, onConnectionComplete]);\n\n // Initiate connection\n const connectApp = async (app: IntegrationApp, apiKey?: string, forceOAuth?: boolean) => {\n // If app supports multiple auth methods and user hasn't chosen, show choice\n if (hasMultipleAuthMethods(app) && !apiKey && !forceOAuth) {\n setAuthMethodModal({ app });\n return;\n }\n\n // If app supports API key (and user didn't choose OAuth), show API key modal\n if (supportsApiKey(app) && !apiKey && !forceOAuth) {\n setApiKeyModal({ app });\n setApiKeyInput(\"\");\n return;\n }\n\n setConnecting(app.slug);\n setError(null);\n\n try {\n // Build request body\n const body: any = { appSlug: app.slug };\n if (apiKey) {\n body.credentials = {\n authScheme: \"API_KEY\",\n apiKey,\n };\n }\n\n const projectParam = projectId && projectId !== \"unassigned\" ? `?project_id=${projectId}` : \"\";\n const res = await authFetch(`/api/integrations/${providerId}/connect${projectParam}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n const data = await res.json();\n\n if (!res.ok) {\n setError(data.error || \"Failed to initiate connection\");\n setConnecting(null);\n setApiKeyModal(null);\n return;\n }\n\n // API_KEY connections are immediately active (no redirect)\n if (data.status === \"active\" || !data.redirectUrl) {\n setConnecting(null);\n setApiKeyModal(null);\n fetchData();\n onConnectionComplete?.();\n return;\n }\n\n if (data.redirectUrl) {\n // Store pending connection for polling\n setPendingConnection({\n appSlug: app.slug,\n connectionId: data.connectionId,\n });\n\n // Open OAuth in popup\n const popup = window.open(\n data.redirectUrl,\n `connect-${app.slug}`,\n \"width=600,height=700,left=200,top=100\"\n );\n\n // If popup blocked, redirect instead\n if (!popup || popup.closed) {\n window.location.href = data.redirectUrl;\n }\n }\n } catch (e) {\n setError(`Failed to connect: ${e}`);\n setConnecting(null);\n setApiKeyModal(null);\n }\n };\n\n // Handle API key form submission\n const handleApiKeySubmit = (e: React.FormEvent) => {\n e.preventDefault();\n if (!apiKeyModal || !apiKeyInput.trim()) return;\n connectApp(apiKeyModal.app, apiKeyInput.trim());\n };\n\n // Disconnect (called after confirmation)\n const disconnectApp = async (account: ConnectedAccount) => {\n const projectParam = projectId && projectId !== \"unassigned\" ? `?project_id=${projectId}` : \"\";\n try {\n const res = await authFetch(\n `/api/integrations/${providerId}/connection/${account.id}${projectParam}`,\n { method: \"DELETE\" }\n );\n\n if (res.ok) {\n fetchData();\n } else {\n const data = await res.json();\n setError(data.error || \"Failed to disconnect\");\n }\n } catch (e) {\n setError(`Failed to disconnect: ${e}`);\n }\n };\n\n // Open MCP config creation modal\n const openMcpConfigModal = (app: IntegrationApp) => {\n setMcpConfigModal({ app });\n setMcpConfigName(`${app.name} MCP`);\n setMcpConfigSuccess(null);\n };\n\n // Create MCP config from connected app\n const createMcpConfig = async () => {\n if (!mcpConfigModal || !mcpConfigName.trim()) return;\n\n setMcpConfigCreating(true);\n setError(null);\n\n try {\n const projectParam = projectId && projectId !== \"unassigned\" ? `?project_id=${projectId}` : \"\";\n const res = await authFetch(`/api/integrations/${providerId}/configs${projectParam}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n name: mcpConfigName.replace(/[^a-zA-Z0-9\\s-]/g, \"\").substring(0, 30),\n toolkitSlug: mcpConfigModal.app.slug,\n }),\n });\n\n const data = await res.json();\n\n if (!res.ok) {\n setError(data.error || \"Failed to create MCP config\");\n setMcpConfigCreating(false);\n return;\n }\n\n setMcpConfigSuccess(mcpConfigName);\n onConnectionComplete?.();\n } catch (e) {\n setError(`Failed to create MCP config: ${e}`);\n } finally {\n setMcpConfigCreating(false);\n }\n };\n\n // Handle disconnect with confirmation modal\n const handleDisconnect = (account: ConnectedAccount) => {\n setConfirmModal({\n message: `Disconnect ${account.appName}?`,\n onConfirm: () => {\n disconnectApp(account);\n setConfirmModal(null);\n },\n });\n };\n\n // Check if app is connected\n const isConnected = (appSlug: string) => {\n return connectedAccounts.some(\n (a) => a.appId === appSlug && a.status === \"active\"\n );\n };\n\n // Get connection for app (prefer active account)\n const getConnection = (appSlug: string) => {\n return connectedAccounts.find((a) => a.appId === appSlug && a.status === \"active\")\n || connectedAccounts.find((a) => a.appId === appSlug);\n };\n\n // Filter apps\n const filteredApps = apps.filter((app) => {\n if (!search) return true;\n const s = search.toLowerCase();\n return (\n app.name.toLowerCase().includes(s) ||\n app.slug.toLowerCase().includes(s) ||\n app.description?.toLowerCase().includes(s) ||\n app.categories.some((c) => c.toLowerCase().includes(s))\n );\n });\n\n // Group by connected/not connected\n const connectedApps = filteredApps.filter((app) => isConnected(app.slug));\n const availableApps = filteredApps.filter((app) => !isConnected(app.slug));\n\n if (loading) {\n return <div className=\"text-center py-8 text-[#666]\">Loading apps...</div>;\n }\n\n return (\n <div className=\"space-y-6\">\n {/* Auth Method Choice Modal */}\n {authMethodModal && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-[#111] border border-[#333] rounded-lg p-6 w-full max-w-md mx-4\">\n <div className=\"flex items-center gap-3 mb-4\">\n {authMethodModal.app.logo && (\n <img\n src={authMethodModal.app.logo}\n alt={authMethodModal.app.name}\n className=\"w-10 h-10 object-contain\"\n />\n )}\n <div>\n <h3 className=\"font-medium\">Connect {authMethodModal.app.name}</h3>\n <p className=\"text-xs text-[#666]\">Choose how to authenticate</p>\n </div>\n </div>\n <div className=\"space-y-3\">\n <button\n onClick={() => {\n setAuthMethodModal(null);\n setApiKeyModal({ app: authMethodModal.app });\n setApiKeyInput(\"\");\n }}\n className=\"w-full text-left p-3 bg-[#0a0a0a] hover:bg-[#1a1a1a] border border-[#333] hover:border-[#f97316] rounded-lg transition\"\n >\n <div className=\"font-medium text-sm\">API Key</div>\n <div className=\"text-xs text-[#666] mt-0.5\">\n Enter your {authMethodModal.app.name} API key directly\n </div>\n </button>\n <button\n onClick={() => {\n setAuthMethodModal(null);\n connectApp(authMethodModal.app, undefined, true);\n }}\n className=\"w-full text-left p-3 bg-[#0a0a0a] hover:bg-[#1a1a1a] border border-[#333] hover:border-[#f97316] rounded-lg transition\"\n >\n <div className=\"font-medium text-sm\">OAuth</div>\n <div className=\"text-xs text-[#666] mt-0.5\">\n Sign in with your {authMethodModal.app.name} account\n </div>\n </button>\n </div>\n <button\n onClick={() => setAuthMethodModal(null)}\n className=\"w-full text-sm text-[#666] hover:text-white mt-4 py-2 transition\"\n >\n Cancel\n </button>\n </div>\n </div>\n )}\n\n {/* API Key Modal */}\n {apiKeyModal && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-[#111] border border-[#333] rounded-lg p-6 w-full max-w-md mx-4\">\n <div className=\"flex items-center gap-3 mb-4\">\n {apiKeyModal.app.logo && (\n <img\n src={apiKeyModal.app.logo}\n alt={apiKeyModal.app.name}\n className=\"w-10 h-10 object-contain\"\n />\n )}\n <div>\n <h3 className=\"font-medium\">Connect {apiKeyModal.app.name}</h3>\n <p className=\"text-xs text-[#666]\">Enter your API key to connect</p>\n </div>\n </div>\n <form onSubmit={handleApiKeySubmit}>\n <input\n type=\"password\"\n value={apiKeyInput}\n onChange={(e) => setApiKeyInput(e.target.value)}\n placeholder=\"Enter API Key...\"\n className=\"w-full bg-[#0a0a0a] border border-[#333] rounded-lg px-4 py-2 mb-4 focus:outline-none focus:border-[#f97316]\"\n autoFocus\n />\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n onClick={() => setApiKeyModal(null)}\n className=\"flex-1 text-sm bg-[#1a1a1a] hover:bg-[#222] border border-[#333] px-4 py-2 rounded transition\"\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n disabled={!apiKeyInput.trim() || connecting === apiKeyModal.app.slug}\n className=\"flex-1 text-sm bg-[#f97316] hover:bg-[#ea580c] text-white px-4 py-2 rounded transition disabled:opacity-50\"\n >\n {connecting === apiKeyModal.app.slug ? \"Connecting...\" : \"Connect\"}\n </button>\n </div>\n </form>\n </div>\n </div>\n )}\n\n {/* MCP Config Creation Modal */}\n {mcpConfigModal && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-[#111] border border-[#333] rounded-lg p-6 w-full max-w-md mx-4\">\n {mcpConfigSuccess ? (\n <>\n <div className=\"text-center mb-4\">\n <div className=\"w-12 h-12 bg-green-500/20 rounded-full flex items-center justify-center mx-auto mb-3\">\n <span className=\"text-green-400 text-2xl\">✓</span>\n </div>\n <h3 className=\"font-medium text-lg\">MCP Config Created!</h3>\n <p className=\"text-sm text-[#888] mt-2\">\n \"{mcpConfigSuccess}\" has been created successfully.\n </p>\n <p className=\"text-xs text-[#666] mt-2\">\n You can now add it to your agents from the MCP Configs tab.\n </p>\n </div>\n <button\n onClick={() => {\n setMcpConfigModal(null);\n setMcpConfigSuccess(null);\n }}\n className=\"w-full text-sm bg-[#f97316] hover:bg-[#ea580c] text-white px-4 py-2 rounded transition\"\n >\n Done\n </button>\n </>\n ) : (\n <>\n <div className=\"flex items-center gap-3 mb-4\">\n {mcpConfigModal.app.logo && (\n <img\n src={mcpConfigModal.app.logo}\n alt={mcpConfigModal.app.name}\n className=\"w-10 h-10 object-contain\"\n />\n )}\n <div>\n <h3 className=\"font-medium\">Create MCP Config</h3>\n <p className=\"text-xs text-[#666]\">\n Create an MCP config for {mcpConfigModal.app.name}\n </p>\n </div>\n </div>\n <form onSubmit={(e) => { e.preventDefault(); createMcpConfig(); }}>\n <label className=\"block text-xs text-[#888] mb-1\">Config Name</label>\n <input\n type=\"text\"\n value={mcpConfigName}\n onChange={(e) => setMcpConfigName(e.target.value)}\n placeholder=\"Enter config name...\"\n className=\"w-full bg-[#0a0a0a] border border-[#333] rounded-lg px-4 py-2 mb-4 focus:outline-none focus:border-[#f97316]\"\n autoFocus\n maxLength={30}\n />\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n onClick={() => setMcpConfigModal(null)}\n className=\"flex-1 text-sm bg-[#1a1a1a] hover:bg-[#222] border border-[#333] px-4 py-2 rounded transition\"\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n disabled={!mcpConfigName.trim() || mcpConfigCreating}\n className=\"flex-1 text-sm bg-[#f97316] hover:bg-[#ea580c] text-white px-4 py-2 rounded transition disabled:opacity-50\"\n >\n {mcpConfigCreating ? \"Creating...\" : \"Create Config\"}\n </button>\n </div>\n </form>\n </>\n )}\n </div>\n </div>\n )}\n\n {/* Confirmation Modal */}\n {confirmModal && (\n <div className=\"fixed inset-0 bg-black/50 flex items-center justify-center z-50\">\n <div className=\"bg-[#111] border border-[#333] rounded-lg p-6 w-full max-w-sm mx-4\">\n <p className=\"text-center mb-4\">{confirmModal.message}</p>\n <div className=\"flex gap-2\">\n <button\n onClick={() => setConfirmModal(null)}\n className=\"flex-1 text-sm bg-[#1a1a1a] hover:bg-[#222] border border-[#333] px-4 py-2 rounded transition\"\n >\n Cancel\n </button>\n <button\n onClick={confirmModal.onConfirm}\n className=\"flex-1 text-sm bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded transition\"\n >\n Confirm\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* Error */}\n {error && (\n <div className=\"text-red-400 text-sm p-3 bg-red-500/10 border border-red-500/20 rounded-lg flex items-center justify-between\">\n <span>{error}</span>\n <button onClick={() => setError(null)} className=\"text-red-400 hover:text-red-300\">\n ×\n </button>\n </div>\n )}\n\n {/* Pending connection notice */}\n {pendingConnection && (\n <div className=\"text-yellow-400 text-sm p-3 bg-yellow-500/10 border border-yellow-500/20 rounded-lg flex items-center gap-2\">\n <span className=\"animate-spin\">⟳</span>\n <span>Waiting for {pendingConnection.appSlug} authorization...</span>\n </div>\n )}\n\n {/* Search */}\n <div>\n <input\n type=\"text\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"Search apps...\"\n className=\"w-full bg-[#111] border border-[#333] rounded-lg px-4 py-2 focus:outline-none focus:border-[#f97316]\"\n />\n </div>\n\n {/* Connected Apps */}\n {connectedApps.length > 0 && (\n <div>\n <h3 className=\"text-sm font-medium text-[#888] mb-3\">\n Connected ({connectedApps.length})\n </h3>\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n {connectedApps.map((app) => (\n <AppCard\n key={app.id}\n app={app}\n connection={getConnection(app.slug)}\n onConnect={() => connectApp(app)}\n onDisconnect={() => {\n const conn = getConnection(app.slug);\n if (conn) handleDisconnect(conn);\n }}\n onCreateMcpConfig={hideMcpConfig ? undefined : () => openMcpConfigModal(app)}\n onBrowseTriggers={onBrowseTriggers ? () => onBrowseTriggers(app.slug) : undefined}\n connecting={connecting === app.slug}\n />\n ))}\n </div>\n </div>\n )}\n\n {/* Available Apps */}\n <div>\n <h3 className=\"text-sm font-medium text-[#888] mb-3\">\n Available Apps ({availableApps.length})\n </h3>\n {availableApps.length === 0 ? (\n <p className=\"text-[#666] text-sm\">\n {search ? \"No apps match your search\" : \"No apps available\"}\n </p>\n ) : (\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n {availableApps.slice(0, 50).map((app) => (\n <AppCard\n key={app.id}\n app={app}\n onConnect={() => connectApp(app)}\n connecting={connecting === app.slug}\n />\n ))}\n </div>\n )}\n {availableApps.length > 50 && (\n <p className=\"text-xs text-[#555] mt-3 text-center\">\n Showing first 50 of {availableApps.length} apps. Use search to find more.\n </p>\n )}\n </div>\n </div>\n );\n}\n\n// App card component\nfunction AppCard({\n app,\n connection,\n onConnect,\n onDisconnect,\n onCreateMcpConfig,\n onBrowseTriggers,\n connecting,\n}: {\n app: IntegrationApp;\n connection?: ConnectedAccount;\n onConnect: () => void;\n onDisconnect?: () => void;\n onCreateMcpConfig?: () => void;\n onBrowseTriggers?: () => void;\n connecting: boolean;\n}) {\n const isConnected = connection?.status === \"active\";\n const hasApiKey = supportsApiKey(app);\n const hasOAuth = supportsOAuth(app);\n const hasBothMethods = hasApiKey && hasOAuth;\n\n return (\n <div\n className={`bg-[#111] border rounded-lg p-3 transition ${\n isConnected ? \"border-green-500/30\" : \"border-[#1a1a1a] hover:border-[#333]\"\n }`}\n >\n <div className=\"flex items-start gap-3\">\n {/* Logo */}\n <div className=\"w-10 h-10 rounded bg-[#1a1a1a] flex items-center justify-center flex-shrink-0 overflow-hidden\">\n {app.logo ? (\n <img\n src={app.logo}\n alt={app.name}\n className=\"w-8 h-8 object-contain\"\n onError={(e) => {\n (e.target as HTMLImageElement).style.display = \"none\";\n }}\n />\n ) : (\n <span className=\"text-lg\">{app.name[0]?.toUpperCase()}</span>\n )}\n </div>\n\n {/* Info */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <h4 className=\"font-medium text-sm truncate\">{app.name}</h4>\n {isConnected && (\n <span className=\"text-xs text-green-400\">✓</span>\n )}\n {!isConnected && hasApiKey && !hasOAuth && (\n <span className=\"text-[10px] bg-[#222] text-[#888] px-1.5 py-0.5 rounded\" title=\"Requires API Key\">\n API Key\n </span>\n )}\n {!isConnected && hasBothMethods && (\n <span className=\"text-[10px] bg-[#1a2a1a] text-[#6a6] px-1.5 py-0.5 rounded\" title=\"Supports API Key or OAuth\">\n API Key / OAuth\n </span>\n )}\n </div>\n {app.description && (\n <p className=\"text-xs text-[#666] line-clamp-2 mt-0.5\">\n {app.description}\n </p>\n )}\n {app.categories.length > 0 && (\n <div className=\"flex flex-wrap gap-1 mt-1\">\n {app.categories.slice(0, 2).map((cat) => (\n <span\n key={cat}\n className=\"text-[10px] bg-[#1a1a1a] text-[#555] px-1.5 py-0.5 rounded\"\n >\n {cat}\n </span>\n ))}\n </div>\n )}\n </div>\n </div>\n\n {/* Actions */}\n <div className=\"mt-3 flex gap-2\">\n {isConnected ? (\n <>\n {onCreateMcpConfig && (\n <button\n onClick={onCreateMcpConfig}\n className=\"flex-1 text-xs bg-[#1a2a1a] hover:bg-[#1a3a1a] border border-green-500/30 hover:border-green-500/50 text-green-400 px-3 py-1.5 rounded transition\"\n >\n Create MCP Config\n </button>\n )}\n {onBrowseTriggers && (\n <button\n onClick={onBrowseTriggers}\n className=\"flex-1 text-xs bg-[#1a1a2a] hover:bg-[#1a1a3a] border border-blue-500/30 hover:border-blue-500/50 text-blue-400 px-3 py-1.5 rounded transition\"\n >\n Browse Triggers\n </button>\n )}\n {onDisconnect && (\n <button\n onClick={onDisconnect}\n className=\"text-xs text-[#666] hover:text-red-400 transition px-2\"\n title=\"Disconnect\"\n >\n ×\n </button>\n )}\n </>\n ) : (\n <button\n onClick={onConnect}\n disabled={connecting}\n className=\"w-full text-xs bg-[#1a1a1a] hover:bg-[#222] border border-[#333] hover:border-[#f97316] px-3 py-1.5 rounded transition disabled:opacity-50\"\n >\n {connecting ? \"Connecting...\" : (hasApiKey && !hasOAuth) ? \"Enter API Key\" : \"Connect\"}\n </button>\n )}\n </div>\n </div>\n );\n}\n\nexport default IntegrationsPanel;\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "879C1544186FFE2D64756E2164756E21",
9
+ "names": []
10
+ }