@runfusion/fusion 0.15.0 → 0.17.0

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 (75) hide show
  1. package/README.md +3 -19
  2. package/dist/bin.js +7005 -2992
  3. package/dist/client/assets/AgentDetailView-DGqT1oDt.js +18 -0
  4. package/dist/client/assets/AgentDetailView-yu8Xltqk.css +1 -0
  5. package/dist/client/assets/AgentsView-BmemrfrO.js +517 -0
  6. package/dist/client/assets/AgentsView-Bs03ptrd.css +1 -0
  7. package/dist/client/assets/ChatView-CZQUBFlV.js +1 -0
  8. package/dist/client/assets/{DevServerView-CV_PpbnZ.js → DevServerView-C3Q0XqDA.js} +1 -1
  9. package/dist/client/assets/{DirectoryPicker-DPfkGnj5.js → DirectoryPicker-BZWVA9ND.js} +1 -1
  10. package/dist/client/assets/{DocumentsView-CESb6RI7.js → DocumentsView-DO48ivSq.js} +1 -1
  11. package/dist/client/assets/InsightsView-CAngTfMf.js +11 -0
  12. package/dist/client/assets/MemoryView-B3rNcAOW.js +2 -0
  13. package/dist/client/assets/NodesView-BnV1LWa8.js +14 -0
  14. package/dist/client/assets/NodesView-DuAXX_0j.css +1 -0
  15. package/dist/client/assets/{PiExtensionsManager-C4fTzemh.js → PiExtensionsManager-C3_Lw4sa.js} +3 -3
  16. package/dist/client/assets/{PluginManager-C2-dExUL.js → PluginManager-Vv3nzrJ1.js} +1 -1
  17. package/dist/client/assets/ResearchView-BzCcDAS4.css +1 -0
  18. package/dist/client/assets/ResearchView-Dfdsuc21.js +1 -0
  19. package/dist/client/assets/RoadmapsView-BiIpE-b8.js +6 -0
  20. package/dist/client/assets/RoadmapsView-DdGlfuu-.css +1 -0
  21. package/dist/client/assets/SettingsModal-BN00HYJ2.js +31 -0
  22. package/dist/client/assets/{SettingsModal-BGnSAeqa.js → SettingsModal-CK4w8Ztb.js} +1 -1
  23. package/dist/client/assets/SettingsModal-Dq4a5KSX.css +1 -0
  24. package/dist/client/assets/{SetupWizardModal-C_d9clJp.js → SetupWizardModal-Dw6N4UvY.js} +1 -1
  25. package/dist/client/assets/{SkillsView-C096TB7i.js → SkillsView-C1196wgA.js} +1 -1
  26. package/dist/client/assets/{folder-open-CKivQd8c.js → folder-open-WVtgE4k3.js} +1 -1
  27. package/dist/client/assets/index-BIJgrHEn.css +1 -0
  28. package/dist/client/assets/index-Bv0TGzDH.js +682 -0
  29. package/dist/client/assets/{star-damu_EYz.js → star-MSImEC8V.js} +1 -1
  30. package/dist/client/assets/{upload-uH6CHlEw.js → upload-Dmvy3xXd.js} +1 -1
  31. package/dist/client/assets/{users-CUySbfji.js → users-CncYvHNf.js} +1 -1
  32. package/dist/client/index.html +2 -2
  33. package/dist/client/version.json +1 -1
  34. package/dist/extension.js +6220 -3829
  35. package/dist/pi-claude-cli/package.json +1 -1
  36. package/dist/pi-claude-cli/src/__tests__/process-manager.test.ts +11 -0
  37. package/dist/pi-claude-cli/src/__tests__/provider.test.ts +25 -0
  38. package/dist/plugins/fusion-plugin-dependency-graph/manifest.json +16 -0
  39. package/dist/plugins/fusion-plugin-dependency-graph/package.json +34 -0
  40. package/dist/plugins/fusion-plugin-dependency-graph/src/DependencyGraphView.css +132 -0
  41. package/dist/plugins/fusion-plugin-dependency-graph/src/DependencyGraphView.tsx +428 -0
  42. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/DependencyGraphView.test.tsx +261 -0
  43. package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/storage.test.ts +31 -0
  44. package/dist/plugins/fusion-plugin-dependency-graph/src/index.ts +25 -0
  45. package/dist/plugins/fusion-plugin-dependency-graph/src/storage.ts +23 -0
  46. package/package.json +8 -4
  47. package/skill/fusion/SKILL.md +5 -5
  48. package/skill/fusion/references/engine-tools.md +4 -4
  49. package/skill/fusion/references/extension-tools.md +3 -3
  50. package/skill/fusion/references/fusion-capabilities.md +1 -1
  51. package/skill/fusion/references/skill-patterns.md +1 -1
  52. package/skill/fusion/workflows/dashboard-cli.md +3 -3
  53. package/skill/fusion/workflows/task-management.md +1 -1
  54. package/dist/client/assets/AgentDetailView-B1zViykq.js +0 -18
  55. package/dist/client/assets/AgentDetailView-B5tq9ius.css +0 -1
  56. package/dist/client/assets/AgentsView-Bl9JH5C8.js +0 -522
  57. package/dist/client/assets/AgentsView-V5GhlBYu.css +0 -1
  58. package/dist/client/assets/ChatView-liNErE53.js +0 -1
  59. package/dist/client/assets/InsightsView-BKhvyEyQ.js +0 -11
  60. package/dist/client/assets/MemoryView-DB-l2miV.js +0 -2
  61. package/dist/client/assets/NodesView-DCoS6iYh.css +0 -1
  62. package/dist/client/assets/NodesView-DgTXO8mm.js +0 -14
  63. package/dist/client/assets/ResearchView-BzRdUzNq.css +0 -1
  64. package/dist/client/assets/ResearchView-CkVwRDVA.js +0 -1
  65. package/dist/client/assets/RoadmapsView-BOYnyMCh.css +0 -1
  66. package/dist/client/assets/RoadmapsView-Cu85_XrQ.js +0 -6
  67. package/dist/client/assets/SettingsModal-C0DokcId.js +0 -31
  68. package/dist/client/assets/SettingsModal-DcGFm6NR.css +0 -1
  69. package/dist/client/assets/SkillMultiselect-DDHJnrkn.css +0 -1
  70. package/dist/client/assets/SkillMultiselect-DwGWYZi6.js +0 -1
  71. package/dist/client/assets/TodoView-CUiAt2mR.js +0 -6
  72. package/dist/client/assets/TodoView-SeO9o7km.css +0 -1
  73. package/dist/client/assets/index-B4StE1qN.js +0 -662
  74. package/dist/client/assets/index-DYJk0WDc.css +0 -1
  75. package/dist/client/assets/list-checks-B3oufblU.js +0 -6
@@ -0,0 +1,14 @@
1
+ import{r as s,j as e}from"./vendor-react-K0fH_qHe.js";import{c as pe,aC as we,aD as Pe,aE as Me,aF as Ee,aG as ye,aH as be,A as je,aI as Re,V as Ae,aJ as De,aK as Le,Y as ie,R as de,a as Ne,M as ee,aL as _e,aM as $e,aN as Ke,X as ue,aO as xe,aP as ze,aQ as Ie,aR as Fe,G as Oe}from"./index-Bv0TGzDH.js";import{U as ve}from"./upload-Dmvy3xXd.js";import"./vendor-xterm-DzcZoU0P.js";/**
2
+ * @license lucide-react v1.7.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const Ve=[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}],["path",{d:"M5 12.859a10 10 0 0 1 5.17-2.69",key:"1dl1wf"}],["path",{d:"M19 12.859a10 10 0 0 0-2.007-1.523",key:"4k23kn"}],["path",{d:"M2 8.82a15 15 0 0 1 4.177-2.643",key:"1grhjp"}],["path",{d:"M22 8.82a15 15 0 0 0-11.288-3.764",key:"z3jwby"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]],Ue=pe("wifi-off",Ve);/**
7
+ * @license lucide-react v1.7.0 - ISC
8
+ *
9
+ * This source code is licensed under the ISC license.
10
+ * See the LICENSE file in the root directory of this source tree.
11
+ */const Be=[["path",{d:"M12 20h.01",key:"zekei9"}],["path",{d:"M2 8.82a15 15 0 0 1 20 0",key:"dnpr2z"}],["path",{d:"M5 12.859a10 10 0 0 1 14 0",key:"1x1e6c"}],["path",{d:"M8.5 16.429a5 5 0 0 1 7 0",key:"1bycff"}]],He=pe("wifi",Be);function re(t){const{lastSyncAt:l,remoteReachable:a,diff:i}=t,u=i.global.length+i.project.length;return l===null?{syncState:"never-synced",lastSyncAt:l,diffCount:0}:a?u>0?{syncState:"diff",lastSyncAt:l,diffCount:u}:{syncState:"synced",lastSyncAt:l,diffCount:0}:{syncState:"error",lastSyncAt:l,diffCount:u}}function ke(t){if(t===null)return"Never synced";const l=new Date(t);if(Number.isNaN(l.getTime()))return"Never synced";const i=Date.now()-l.getTime(),u=Math.floor(i/1e3),h=Math.floor(u/60),o=Math.floor(h/60),f=Math.floor(o/24);return h<1?"Synced just now":h<60?`Synced ${h}m ago`:o<24?`Synced ${o}h ago`:`Synced ${f}d ago`}function Te(t){switch(t){case"synced":return"var(--color-success)";case"pending":return"var(--color-warning)";case"diff":return"var(--color-warning)";case"error":return"var(--color-error)";case"never-synced":return"var(--text-muted)"}}const qe=3e4;function Je(){const[t,l]=s.useState({}),[a,i]=s.useState(!1),[u,h]=s.useState({}),[o,f]=s.useState(null),c=s.useRef(new Set),y=s.useRef(!1),p=s.useRef(null),N=s.useRef(null),C=s.useCallback(async(m,r)=>{try{const b=await we(m);l(z=>({...z,[m]:b})),f(null)}catch(b){console.error(`Failed to fetch sync status for node ${m}:`,b),f(b instanceof Error?b.message:"Failed to fetch sync status")}},[]),v=s.useCallback(async()=>{const m=Array.from(c.current);if(m.length===0)return;p.current&&p.current.abort(),p.current=new AbortController;const r=!y.current;r&&i(!0),f(null);try{const b=await Promise.allSettled(m.map(F=>C(F,r)));y.current=!0,b.filter(F=>F.status==="rejected").length>0&&f("Some sync status requests failed")}catch(b){if(b instanceof Error&&b.name==="AbortError")return;f(b instanceof Error?b.message:"Failed to fetch sync status"),y.current=!0}finally{i(!1)}},[C]),P=s.useCallback(()=>{N.current&&clearInterval(N.current),N.current=setInterval(()=>{v()},qe)},[v]),j=s.useCallback(()=>{N.current&&(clearInterval(N.current),N.current=null)},[]);s.useEffect(()=>(v(),P(),()=>{j(),p.current&&p.current.abort()}),[v,P,j]);const n=s.useCallback(m=>{c.current.has(m)||(c.current.add(m),C(m,!y.current))},[C]),x=s.useCallback(m=>{c.current.delete(m),l(r=>{const b={...r};return delete b[m],b}),c.current.size===0&&j()},[j]),g=s.useCallback(async m=>{h(r=>({...r,[m]:!0})),f(null);try{const r=await Pe(m);return C(m,!1),!r.success&&r.error&&f(r.error),r}catch(r){const b=r instanceof Error?r.message:"Push settings failed";throw f(b),r}finally{h(r=>{const b={...r};return delete b[m],b})}},[C]),M=s.useCallback(async m=>{h(r=>({...r,[m]:!0})),f(null);try{const r=await Me(m);return C(m,!1),!r.success&&r.error&&f(r.error),r}catch(r){const b=r instanceof Error?r.message:"Pull settings failed";throw f(b),r}finally{h(r=>{const b={...r};return delete b[m],b})}},[C]),R=s.useCallback(async m=>{h(r=>({...r,[m]:!0})),f(null);try{return await Ee(m)}catch(r){const b=r instanceof Error?r.message:"Auth sync failed";throw f(b),r}finally{h(r=>{const b={...r};return delete b[m],b})}},[]),E=s.useCallback(m=>t[m]?.authMatch,[t]),D=s.useCallback(m=>t[m]?.authDiff,[t]);return{syncStatusMap:t,loading:a,actionLoading:u,error:o,refresh:v,trackNode:n,untrackNode:x,pushSettings:g,pullSettings:M,syncAuth:R,getAuthSyncState:E,getAuthProviders:D}}function Xe(t,l){return l.type==="remote"?t.nodeId===l.id:t.nodeId===l.id||t.nodeId===void 0||t.nodeId===null}function Ce(t,l){return t.filter(a=>Xe(a,l))}function me(t,l){return Ce(t,l).length}const Ge={online:{label:"Online",color:"var(--color-success)",className:"node-card__status--online"},offline:{label:"Offline",color:"var(--color-error)",className:"node-card__status--offline"},connecting:{label:"Connecting",color:"var(--color-warning)",className:"node-card__status--connecting"},error:{label:"Error",color:"var(--color-error)",className:"node-card__status--error"}},Ye={match:"var(--color-success)",differs:"var(--color-warning)","not-synced":"var(--text-muted)"};function We(t,l){if(t==="match")return"Auth credentials match";if(t==="not-synced")return"Auth not synced";if(l&&Object.keys(l).length>0){const a=Object.entries(l).filter(([,i])=>i==="differs").map(([i])=>i);if(a.length>0)return`Auth credentials differ: ${a.join(", ")}`}return"Auth credentials differ"}function Qe(t,l=42){return t.length<=l?t:`${t.slice(0,l-3)}...`}function Ze(t,l){const a=t.node,i=l.node;if(a.id!==i.id||a.name!==i.name||a.type!==i.type||a.url!==i.url||a.status!==i.status||a.maxConcurrent!==i.maxConcurrent||a.updatedAt!==i.updatedAt||t.isLoading!==l.isLoading)return!1;const u=t.syncStatus,h=l.syncStatus;if(!(!u&&!h)){if(!u||!h)return!1;if(u.syncState!==h.syncState||u.lastSyncAt!==h.lastSyncAt||u.diffCount!==h.diffCount)return!1}if(t.authSyncState!==l.authSyncState)return!1;const o=t.authSyncProviders,f=l.authSyncProviders;if(o!==f){if(!o||!f)return!1;{const p=Object.keys(o),N=Object.keys(f);if(p.length!==N.length||p.some(C=>o[C]!==f[C]))return!1}}const c=me(t.projects,a),y=me(l.projects,i);return c===y}function es({node:t,projects:l,onHealthCheck:a,onEdit:i,onRemove:u,isLoading:h=!1,syncStatus:o,authSyncState:f,authSyncProviders:c}){const[y,p]=s.useState(!1),N=Ge[t.status],C=s.useMemo(()=>me(l,t),[l,t]),v=s.useCallback(()=>{i(t)},[i,t]),P=s.useCallback(g=>{g.stopPropagation(),a(t.id)},[a,t.id]),j=s.useCallback(g=>{g.stopPropagation(),i(t)},[i,t]),n=s.useCallback(g=>{if(g.stopPropagation(),!y){p(!0);return}u(t.id),p(!1)},[y,u,t.id]),x=s.useCallback(g=>{(g.key==="Enter"||g.key===" ")&&(g.preventDefault(),i(t))},[i,t]);return e.jsxs("article",{className:`node-card ${h?"node-card--loading":""}`,"data-node-id":t.id,role:"button",tabIndex:0,onClick:v,onKeyDown:x,children:[e.jsx("header",{className:"node-card__header",children:e.jsxs("div",{className:"node-card__title-wrap",children:[e.jsx("div",{className:"node-card__icon",children:e.jsx(ye,{size:18})}),e.jsxs("div",{children:[e.jsx("h3",{className:"node-card__name",title:t.name,children:t.name}),e.jsxs("div",{className:"node-card__meta-row",children:[e.jsx("span",{className:"node-card__type-badge",children:t.type==="local"?"Local":"Remote"}),e.jsxs("span",{className:`node-card__status ${N.className}`,style:{color:N.color},"data-status":t.status,children:[e.jsx("span",{className:"node-card__status-indicator",style:{backgroundColor:N.color},"aria-hidden":!0}),N.label]}),t.type==="remote"&&f&&e.jsx("span",{className:`node-card__auth-indicator node-card__auth-indicator--${f}`,title:We(f,c),"aria-label":`Auth sync: ${f==="match"?"credentials match":f==="differs"?"credentials differ":"not synced"}`,style:{color:Ye[f]},children:e.jsx(be,{size:14})})]})]})]})}),e.jsxs("div",{className:"node-card__body",children:[t.type==="remote"&&t.url&&e.jsx("div",{className:"node-card__url",title:t.url,children:Qe(t.url)}),e.jsxs("div",{className:"node-card__metrics",children:[e.jsxs("div",{className:"node-card__metric",children:[e.jsx("span",{className:"node-card__metric-label",children:"Projects"}),e.jsx("span",{className:"node-card__metric-value",children:C})]}),e.jsxs("div",{className:"node-card__metric",children:[e.jsx("span",{className:"node-card__metric-label",children:"Concurrency"}),e.jsx("span",{className:"node-card__metric-value",children:t.maxConcurrent})]})]}),t.type==="remote"&&o&&e.jsxs("div",{className:"node-card__sync","data-sync-state":o.syncState,"data-testid":"node-card-sync",children:[e.jsx("span",{className:"node-card__sync-dot",style:{backgroundColor:Te(o.syncState)},"aria-hidden":!0}),e.jsx("span",{className:"node-card__sync-time",children:ke(o.lastSyncAt)})]})]}),e.jsxs("footer",{className:"node-card__actions",children:[e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",onClick:P,disabled:h,"aria-label":"Run node health check",title:"Health Check",children:[e.jsx(je,{size:14}),e.jsx("span",{children:"Health"})]}),e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",onClick:j,disabled:h,"aria-label":"Edit node",title:"Edit",children:[e.jsx(Re,{size:14}),e.jsx("span",{children:"Edit"})]}),e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",onClick:j,disabled:h,"aria-label":"Start node container",title:"Start Container",children:[e.jsx(Ae,{size:14}),e.jsx("span",{children:"Start"})]}),e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",onClick:j,disabled:h,"aria-label":"Stop node container",title:"Stop Container",children:[e.jsx(De,{size:14}),e.jsx("span",{children:"Stop"})]}),e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",onClick:j,disabled:h,"aria-label":"Restart node container",title:"Restart Container",children:[e.jsx(Le,{size:14}),e.jsx("span",{children:"Restart"})]}),e.jsxs("button",{className:`btn btn-sm node-card__action node-card__action--remove ${y?"btn-danger is-armed":""}`,type:"button",onClick:n,disabled:h,"aria-label":y?"Confirm remove node":"Remove node",title:y?"Confirm remove":"Remove",children:[e.jsx(ie,{size:14}),e.jsx("span",{children:y?"Confirm":"Remove"})]})]})]})}const ss=s.memo(es,Ze),Y={online:"var(--success, var(--color-success))",offline:"var(--text-dim)",connecting:"var(--triage)",error:"var(--color-error)"},G=28,ge=12,ts=300,as=120;function ns({nodes:t,className:l}){const a=s.useMemo(()=>t.find(c=>c.type==="local")??t[0],[t]),i=s.useMemo(()=>t.filter(c=>c.type==="remote"),[t]),u=s.useMemo(()=>{const c=ts,y=Math.max(0,i.length-4)*20;return c+y},[i.length]),h=u/2,o=u/2,f=s.useMemo(()=>{if(i.length===0)return[];const c=Math.min(as,u/2-G-10),y=2*Math.PI/i.length,p=-Math.PI/2;return i.map((N,C)=>{const v=p+C*y;return{node:N,x:h+c*Math.cos(v),y:o+c*Math.sin(v)}})},[i,u,h,o]);return t.length===0?e.jsx("div",{className:`mesh-topology mesh-topology--empty ${l??""}`,children:e.jsx("div",{className:"mesh-topology__empty-state",children:e.jsx("p",{children:"No nodes to display"})})}):e.jsxs("div",{className:`mesh-topology ${l??""}`,children:[e.jsxs("svg",{className:"mesh-topology__svg",viewBox:`0 0 ${u} ${u}`,preserveAspectRatio:"xMidYMid meet","aria-label":"Node mesh topology visualization",children:[f.map(c=>e.jsx("line",{className:"mesh-topology__link",x1:h,y1:o,x2:c.x,y2:c.y},`link-${c.node.id}`)),a&&e.jsxs("g",{className:"mesh-topology__node",transform:`translate(${h}, ${o})`,children:[e.jsx("circle",{className:"mesh-topology__node-circle",r:G,fill:Y[a.status],"aria-label":`${a.name} (${a.status})`}),e.jsx("text",{className:"mesh-topology__node-label",y:G+ge,textAnchor:"middle",children:a.name.length>12?`${a.name.slice(0,10)}…`:a.name}),e.jsxs("g",{className:"mesh-topology__node-type",transform:`translate(0 ${-G-10})`,children:[e.jsx("circle",{className:"mesh-topology__node-type-badge",r:"8"}),e.jsx("text",{className:"mesh-topology__node-type-text",textAnchor:"middle",dominantBaseline:"middle",children:a.type==="local"?"L":"R"})]})]}),f.map(c=>e.jsxs("g",{className:"mesh-topology__node",transform:`translate(${c.x}, ${c.y})`,children:[e.jsx("circle",{className:"mesh-topology__node-circle",r:G,fill:Y[c.node.status],"aria-label":`${c.node.name} (${c.node.status})`}),e.jsx("text",{className:"mesh-topology__node-label",y:G+ge,textAnchor:"middle",children:c.node.name.length>12?`${c.node.name.slice(0,10)}…`:c.node.name}),e.jsxs("g",{className:"mesh-topology__node-type",transform:`translate(0 ${-G-10})`,children:[e.jsx("circle",{className:"mesh-topology__node-type-badge",r:"8"}),e.jsx("text",{className:"mesh-topology__node-type-text",textAnchor:"middle",dominantBaseline:"middle",children:c.node.type==="local"?"L":"R"})]})]},c.node.id))]}),e.jsxs("div",{className:"mesh-topology__legend",children:[e.jsxs("div",{className:"mesh-topology__legend-item",children:[e.jsx("span",{className:"mesh-topology__legend-dot",style:{background:Y.online}}),e.jsx("span",{children:"Online"})]}),e.jsxs("div",{className:"mesh-topology__legend-item",children:[e.jsx("span",{className:"mesh-topology__legend-dot",style:{background:Y.offline}}),e.jsx("span",{children:"Offline"})]}),e.jsxs("div",{className:"mesh-topology__legend-item",children:[e.jsx("span",{className:"mesh-topology__legend-dot",style:{background:Y.connecting}}),e.jsx("span",{children:"Connecting"})]}),e.jsxs("div",{className:"mesh-topology__legend-item",children:[e.jsx("span",{className:"mesh-topology__legend-dot",style:{background:Y.error}}),e.jsx("span",{children:"Error"})]})]}),e.jsx("p",{className:"mesh-topology__notice",children:"Peer-to-peer discovery data unavailable."})]})}const ls=s.memo(ns),he=1,fe=10;function rs(t){const l={};return t.name.trim()||(l.name="Name is required"),t.type==="remote"&&!t.url?.trim()&&(l.url="URL is required for remote nodes"),(!Number.isFinite(t.maxConcurrent)||t.maxConcurrent<he||t.maxConcurrent>fe)&&(l.maxConcurrent=`Concurrency must be between ${he} and ${fe}`),l}function os({isOpen:t,onClose:l,onSubmit:a,addToast:i}){const[u,h]=s.useState(""),[o,f]=s.useState("local"),[c,y]=s.useState(""),[p,N]=s.useState(""),[C,v]=s.useState(2),[P,j]=s.useState("auto-generate"),[n,x]=s.useState({}),[g,M]=s.useState(!1),R=s.useCallback(()=>{h(""),f("local"),y(""),N(""),v(2),j("auto-generate"),x({}),M(!1)},[]),E=s.useCallback(()=>{g||(R(),l())},[g,l,R]);s.useEffect(()=>{if(!t){R();return}const r=b=>{b.key==="Escape"&&(b.preventDefault(),E())};return document.addEventListener("keydown",r),()=>{document.removeEventListener("keydown",r)}},[E,t,R]);const D=s.useMemo(()=>({name:u.trim(),type:o,url:o==="remote"&&c.trim()||void 0,apiKey:o==="remote"&&P==="provide"&&p||void 0,maxConcurrent:C,apiKeyMode:P}),[p,P,C,u,o,c]),m=s.useCallback(async()=>{if(g)return;const r=rs(D);if(x(r),!(Object.keys(r).length>0)){M(!0);try{await a(D),i(`Node "${D.name}" registered`,"success"),E()}catch(b){const z=b instanceof Error?b.message:"Failed to register node";i(z,"error")}finally{M(!1)}}},[i,E,D,g,a]);return t?e.jsx("div",{className:"modal-overlay open",onClick:E,children:e.jsxs("div",{className:"modal modal-md add-node-modal",onClick:r=>r.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":"Add Node",children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:"Add Node"}),e.jsx("button",{className:"modal-close",onClick:E,disabled:g,"aria-label":"Close add node modal",children:"×"})]}),e.jsxs("div",{className:"modal-body add-node-modal__body",children:[e.jsx("p",{className:"add-node-modal__description",children:"Register an existing Fusion node by providing its connection details and concurrency settings."}),e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:"Name"}),e.jsx("input",{className:"input",type:"text",value:u,onChange:r=>h(r.target.value),placeholder:"Build Machine",disabled:g,"aria-invalid":!!n.name,autoFocus:!0}),n.name&&e.jsx("span",{className:"form-error add-node-modal__error",children:n.name})]}),e.jsxs("div",{className:"add-node-modal__type-toggle",children:[e.jsx("button",{type:"button",className:`add-node-modal__type-btn ${o==="local"?"active":""}`,"data-type":"local",onClick:()=>f("local"),disabled:g,"aria-pressed":o==="local",children:"Local"}),e.jsx("button",{type:"button",className:`add-node-modal__type-btn ${o==="remote"?"active":""}`,"data-type":"remote",onClick:()=>f("remote"),disabled:g,"aria-pressed":o==="remote",children:"Remote"})]}),o==="remote"&&e.jsxs("div",{className:"add-node-modal__remote-fields","data-testid":"remote-fields-container","data-visible":!0,children:[e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:"Reachable URL / Hostname"}),e.jsx("input",{className:"input",type:"text",value:c,onChange:r=>y(r.target.value),placeholder:"https://node.example.com",disabled:g,"aria-invalid":!!n.url}),n.url&&e.jsx("span",{className:"form-error add-node-modal__error",children:n.url})]}),e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:"API Key Mode"}),e.jsxs("select",{className:"select",value:P,onChange:r=>j(r.target.value),disabled:g,children:[e.jsx("option",{value:"auto-generate",children:"Auto-generate"}),e.jsx("option",{value:"provide",children:"Provide key manually"})]})]}),P==="provide"&&e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:"API Key"}),e.jsx("input",{className:"input",type:"password",value:p,onChange:r=>N(r.target.value),placeholder:"Enter node API key",disabled:g})]})]}),e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:"Max Concurrent"}),e.jsx("input",{className:"input",type:"number",min:he,max:fe,value:C,onChange:r=>v(Number(r.target.value)),disabled:g,"aria-invalid":!!n.maxConcurrent}),e.jsx("span",{className:"add-node-modal__hint",children:"Max simultaneous task agents (1–10)"}),n.maxConcurrent&&e.jsx("span",{className:"form-error add-node-modal__error",children:n.maxConcurrent})]})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{className:"btn btn-sm",onClick:E,disabled:g,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary btn-sm","data-testid":"add-node-submit",onClick:m,disabled:g,children:g?"Adding...":"Add Node"})]})]})}):null}function cs(){const[t,l]=s.useState([]),[a,i]=s.useState(!1),[u,h]=s.useState(null),[o,f]=s.useState(!1),[c,y]=s.useState(null),[p,N]=s.useState(!1),C=s.useCallback(async()=>{i(!0),h(null);try{const j=await fetch("/api/docker/contexts");if(!j.ok)throw new Error(`Failed to load Docker contexts (${j.status})`);const n=await j.json();return l(n),n}catch(j){const n=j instanceof Error?j.message:String(j);throw h(n),j}finally{i(!1)}},[]),v=s.useCallback(async j=>{f(!0);try{const n=await fetch("/api/docker/test-connection",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({hostConfig:j})});if(!n.ok)throw new Error(`Failed to test Docker connection (${n.status})`);const x=await n.json();return y(x),x}finally{f(!1)}},[]),P=s.useCallback(async()=>{N(!0);try{const j=await fetch("/api/docker/local-available");if(!j.ok)throw new Error(`Failed to check local Docker availability (${j.status})`);return await j.json()}finally{N(!1)}},[]);return{contexts:t,isLoadingContexts:a,contextsError:u,loadContexts:C,isTestingConnection:o,lastTestResult:c,testConnection:v,isCheckingLocal:p,checkLocalDocker:P}}function is({value:t,onChange:l}){const[a,i]=s.useState(!!(t?.tlsCaPath||t?.tlsCertPath||t?.tlsKeyPath||t?.tlsVerify));s.useEffect(()=>{a||l({tlsVerify:void 0,tlsCaPath:void 0,tlsCertPath:void 0,tlsKeyPath:void 0})},[a,l]);const u=s.useMemo(()=>({tlsVerify:t?.tlsVerify??!0,tlsCaPath:t?.tlsCaPath??"",tlsCertPath:t?.tlsCertPath??"",tlsKeyPath:t?.tlsKeyPath??""}),[t]);return e.jsxs("div",{className:"docker-tls-config",children:[e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:a,onChange:h=>i(h.target.checked)}),"Use TLS"]}),a&&e.jsxs("div",{className:"docker-tls-config__fields",children:[e.jsxs("div",{className:"docker-tls-config__field",children:[e.jsx("label",{htmlFor:"docker-tls-ca-path",children:"CA Certificate Path"}),e.jsx("input",{id:"docker-tls-ca-path",className:"input",value:u.tlsCaPath,onChange:h=>l({...u,tlsCaPath:h.target.value}),placeholder:"/etc/docker/ca.pem"})]}),e.jsxs("div",{className:"docker-tls-config__field",children:[e.jsx("label",{htmlFor:"docker-tls-cert-path",children:"Client Certificate Path"}),e.jsx("input",{id:"docker-tls-cert-path",className:"input",value:u.tlsCertPath,onChange:h=>l({...u,tlsCertPath:h.target.value}),placeholder:"/etc/docker/cert.pem"})]}),e.jsxs("div",{className:"docker-tls-config__field",children:[e.jsx("label",{htmlFor:"docker-tls-key-path",children:"Client Key Path"}),e.jsx("input",{id:"docker-tls-key-path",className:"input",value:u.tlsKeyPath,onChange:h=>l({...u,tlsKeyPath:h.target.value}),placeholder:"/etc/docker/key.pem"})]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:u.tlsVerify,onChange:h=>l({...u,tlsVerify:h.target.checked})}),"Verify TLS Certificate"]})]})]})}function ds({value:t,onChange:l,onError:a}){const i=t?.context?"context":t?.host?"host":"local",[u,h]=s.useState(i),[o,f]=s.useState(t?.context??""),[c,y]=s.useState(t?.host??""),[p,N]=s.useState(null),{contexts:C,isLoadingContexts:v,contextsError:P,loadContexts:j,testConnection:n,isTestingConnection:x,lastTestResult:g,checkLocalDocker:M,isCheckingLocal:R}=cs(),E=s.useMemo(()=>({tlsVerify:t?.tlsVerify,tlsCaPath:t?.tlsCaPath,tlsCertPath:t?.tlsCertPath,tlsKeyPath:t?.tlsKeyPath}),[t]);s.useEffect(()=>{if(u==="local"){l({});return}if(u==="context"){j().catch(m=>a?.(m instanceof Error?m.message:String(m))),l(o?{context:o}:{});return}l({host:c,...E})},[u]);const D=s.useCallback(m=>{u==="host"&&l({host:c,...m})},[c,u,l]);return e.jsxs("div",{className:"docker-target-selector",children:[e.jsxs("div",{className:"docker-target-selector__modes",role:"group","aria-label":"Docker target mode",children:[e.jsx("button",{type:"button",className:`btn btn-sm ${u==="local"?"docker-target-selector__mode-active":""}`,onClick:()=>{h("local"),M().then(m=>N(m.available?`Docker is available${m.version?` (${m.version})`:""}`:`Docker not found${m.error?`: ${m.error}`:""}`)).catch(m=>{const r=m instanceof Error?m.message:String(m);N(`Docker not found: ${r}`),a?.(r)})},children:"Local Docker"}),e.jsx("button",{type:"button",className:`btn btn-sm ${u==="context"?"docker-target-selector__mode-active":""}`,onClick:()=>h("context"),children:"Docker Context"}),e.jsx("button",{type:"button",className:`btn btn-sm ${u==="host"?"docker-target-selector__mode-active":""}`,onClick:()=>h("host"),children:"Remote Host"})]}),u==="local"&&p&&e.jsx("div",{className:"docker-target-selector__status",children:p}),u==="context"&&e.jsxs("div",{className:"docker-target-selector__panel",children:[e.jsxs("div",{className:"docker-target-selector__context-row",children:[e.jsxs("select",{className:"select",value:o,onChange:m=>{const r=m.target.value;f(r),l(r?{context:r}:{})},children:[e.jsx("option",{value:"",children:"Select context"}),C.map(m=>e.jsxs("option",{value:m.name,children:[m.name,m.isCurrentContext?" (current)":"",m.dockerHost?` — ${m.dockerHost}`:""]},m.name))]}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon",onClick:()=>void j(),disabled:v,"aria-label":"Refresh contexts",children:e.jsx(de,{size:14})})]}),P&&e.jsx("div",{className:"docker-target-selector__error",children:P})]}),u==="host"&&e.jsxs("div",{className:"docker-target-selector__panel",children:[e.jsxs("div",{className:"docker-target-selector__field",children:[e.jsx("label",{htmlFor:"docker-target-selector-host",children:"Docker Host"}),e.jsx("input",{id:"docker-target-selector-host",className:"input",placeholder:"tcp://host:2376",value:c,onChange:m=>{const r=m.target.value;y(r),l({host:r,...E})}})]}),e.jsx(is,{value:E,onChange:D})]}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>void n(u==="local"?void 0:u==="context"?{context:o}:{host:c,...E}),disabled:x||R,children:x?"Testing...":"Test Connection"}),g&&e.jsx("div",{className:g.success?"docker-target-selector__success":"docker-target-selector__error",children:g.success?`Connected${g.dockerVersion?` (Docker ${g.dockerVersion})`:""}`:g.error??"Connection failed"})]})}const oe="http://localhost:4040";function us({isOpen:t,onClose:l,onSubmit:a,addToast:i}){const[u,h]=s.useState(""),[o,f]=s.useState({}),[c,y]=s.useState(oe),[p,N]=s.useState("auto"),[C,v]=s.useState(""),[P,j]=s.useState(!1),[n,x]=s.useState(!1),[g,M]=s.useState(!0),[R,E]=s.useState(4096),[D,m]=s.useState(2),[r,b]=s.useState(!1),[z,F]=s.useState("runfusion/fusion"),[H,q]=s.useState("latest"),[O,V]=s.useState([]),[T,k]=s.useState([]),[S,K]=s.useState({}),[w,J]=s.useState(!1),L=s.useCallback(()=>{h(""),f({}),y(oe),N("auto"),v(""),j(!1),x(!1),M(!0),E(4096),m(2),b(!1),F("runfusion/fusion"),q("latest"),V([]),k([]),K({}),J(!1)},[]),U=s.useCallback(()=>{w||(L(),l())},[l,L,w]);s.useEffect(()=>{if(!t){L();return}const d=A=>{A.key==="Escape"&&(A.preventDefault(),U())};return document.addEventListener("keydown",d),()=>document.removeEventListener("keydown",d)},[U,t,L]);const X=s.useMemo(()=>({nodeId:null,name:u.trim(),imageName:z.trim()||"runfusion/fusion",imageTag:H.trim()||"latest",hostConfig:{context:o.context?.trim()||void 0,host:o.host?.trim()||void 0,tlsVerify:o.tlsVerify,tlsCaPath:o.tlsCaPath?.trim()||void 0,tlsCertPath:o.tlsCertPath?.trim()||void 0,tlsKeyPath:o.tlsKeyPath?.trim()||void 0},envVars:Object.fromEntries(O.map(d=>[d.key.trim(),d.value]).filter(([d])=>!!d)),volumeMounts:T.map(d=>({hostPath:d.hostPath.trim(),containerPath:d.containerPath.trim(),mode:d.mode})).filter(d=>d.hostPath&&d.containerPath),resourceSizing:{memoryMB:R,cpus:D},extraClis:[P?"claude-cli":null,n?"droid-cli":null].filter(Boolean),persistentStorage:g,reachableUrl:c.trim()||null,apiKey:p==="manual"&&C.trim()||null}),[C,p,D,o,O,z,H,P,n,R,T,u,g,c]),te=s.useCallback(()=>{V(d=>[...d,{key:"",value:""}])},[]),se=s.useCallback((d,A)=>{V($=>$.map((B,Z)=>Z===d?A:B))},[]),W=s.useCallback(d=>{V(A=>A.filter(($,B)=>B!==d))},[]),ae=s.useCallback(()=>{k(d=>[...d,{hostPath:"",containerPath:"",mode:"rw"}])},[]),Q=s.useCallback((d,A)=>{k($=>$.map((B,Z)=>Z===d?A:B))},[]),ne=s.useCallback(d=>{k(A=>A.filter(($,B)=>B!==d))},[]),le=s.useCallback(async()=>{if(w)return;const d={};if((!X.name||X.name.length>64)&&(d.name="Name is required and must be 64 characters or fewer"),X.reachableUrl||(d.reachableUrl="URL is required"),R<512&&(d.memoryMB="Memory must be at least 512 MB"),D<.5&&(d.cpus="CPUs must be at least 0.5"),K(d),!(Object.keys(d).length>0)){J(!0);try{await a(X),U()}catch{}finally{J(!1)}}},[U,D,X,R,a,w]);return t?e.jsx("div",{className:"modal-overlay open",onClick:U,children:e.jsxs("div",{className:"modal docker-onboarding",role:"dialog","aria-modal":"true","aria-label":"Docker node onboarding",onClick:d=>d.stopPropagation(),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:"Provision Docker Node"}),e.jsx("button",{className:"modal-close",onClick:U,disabled:w,"aria-label":"Close onboarding modal",children:"×"})]}),e.jsxs("div",{className:"modal-body docker-onboarding__body",children:[e.jsxs("section",{className:"docker-onboarding__section",children:[e.jsx("h4",{className:"docker-onboarding__section-title",children:"Required Settings"}),e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"Node Name"}),e.jsx("input",{className:"input",value:u,onChange:d=>h(d.target.value),disabled:w,placeholder:"my-docker-node",autoFocus:!0})]}),S.name&&e.jsx("div",{className:"form-error",children:S.name}),e.jsx(ds,{value:o,onChange:f}),e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"Reachable URL"}),e.jsx("input",{className:"input",value:c,onChange:d=>y(d.target.value),disabled:w,placeholder:oe})]}),S.reachableUrl&&e.jsx("div",{className:"form-error",children:S.reachableUrl}),e.jsxs("div",{className:"docker-onboarding__radio-group",children:[e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"radio",checked:p==="auto",onChange:()=>N("auto"),disabled:w}),"Auto-generate"]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"radio",checked:p==="manual",onChange:()=>N("manual"),disabled:w}),"Provide manually"]})]}),p==="manual"&&e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"API Key"}),e.jsx("input",{className:"input",type:"password",value:C,onChange:d=>v(d.target.value),disabled:w,placeholder:"Enter API key"})]}),e.jsxs("div",{className:"docker-onboarding__checkbox-group",children:[e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:P,onChange:d=>j(d.target.checked),disabled:w}),"Claude CLI"]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:n,onChange:d=>x(d.target.checked),disabled:w}),"Droid CLI"]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:g,onChange:d=>M(d.target.checked),disabled:w}),"Keep data across container recreations"]})]}),e.jsxs("div",{className:"docker-onboarding__inline-fields",children:[e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"Memory (MB)"}),e.jsx("input",{className:"input",type:"number",min:512,value:R,onChange:d=>E(Number(d.target.value)),disabled:w})]}),e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"CPUs"}),e.jsx("input",{className:"input",type:"number",min:.5,step:.5,value:D,onChange:d=>m(Number(d.target.value)),disabled:w})]})]}),S.memoryMB&&e.jsx("div",{className:"form-error",children:S.memoryMB}),S.cpus&&e.jsx("div",{className:"form-error",children:S.cpus})]}),e.jsxs("section",{className:"docker-onboarding__section",children:[e.jsxs("button",{type:"button",className:`docker-onboarding__advanced-toggle ${r?"is-expanded":""}`,onClick:()=>b(d=>!d),disabled:w,children:[e.jsx("span",{children:"Advanced"}),e.jsx(Ne,{})]}),e.jsx("div",{className:`docker-onboarding__advanced-content ${r?"is-expanded":""}`,children:e.jsxs("div",{children:[e.jsxs("div",{className:"docker-onboarding__inline-fields",children:[e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"Image"}),e.jsx("input",{className:"input",value:z,onChange:d=>F(d.target.value),disabled:w,placeholder:"runfusion/fusion"})]}),e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:"Tag"}),e.jsx("input",{className:"input",value:H,onChange:d=>q(d.target.value),disabled:w,placeholder:"latest"})]})]}),e.jsxs("div",{className:"docker-onboarding__kv-list",children:[e.jsx("h5",{children:"Environment Variables"}),O.map((d,A)=>e.jsxs("div",{className:"docker-onboarding__kv-row docker-onboarding__kv-row--env",children:[e.jsx("input",{className:"input",placeholder:"KEY",value:d.key,disabled:w,onChange:$=>se(A,{key:$.target.value,value:d.value})}),e.jsx("input",{className:"input",placeholder:"Value",value:d.value,disabled:w,onChange:$=>se(A,{key:d.key,value:$.target.value})}),e.jsx("button",{type:"button",className:"btn btn-icon","aria-label":"Remove environment variable",onClick:()=>W(A),disabled:w,children:e.jsx(ie,{size:14})})]},`env-${A}`)),e.jsxs("button",{type:"button",className:"btn btn-sm docker-onboarding__kv-add",onClick:te,disabled:w,children:[e.jsx(ee,{size:14}),"Add variable"]})]}),e.jsxs("div",{className:"docker-onboarding__kv-list",children:[e.jsx("h5",{children:"Volume Mounts"}),T.map((d,A)=>e.jsxs("div",{className:"docker-onboarding__kv-row docker-onboarding__kv-row--mount",children:[e.jsx("input",{className:"input",placeholder:"Host path",value:d.hostPath,disabled:w,onChange:$=>Q(A,{hostPath:$.target.value,containerPath:d.containerPath,mode:d.mode})}),e.jsx("input",{className:"input",placeholder:"Container path",value:d.containerPath,disabled:w,onChange:$=>Q(A,{hostPath:d.hostPath,containerPath:$.target.value,mode:d.mode})}),e.jsxs("select",{className:"select",value:d.mode,disabled:w,onChange:$=>Q(A,{hostPath:d.hostPath,containerPath:d.containerPath,mode:$.target.value==="ro"?"ro":"rw"}),children:[e.jsx("option",{value:"rw",children:"rw"}),e.jsx("option",{value:"ro",children:"ro"})]}),e.jsx("button",{type:"button",className:"btn btn-icon","aria-label":"Remove volume mount",onClick:()=>ne(A),disabled:w,children:e.jsx(ie,{size:14})})]},`mount-${A}`)),e.jsxs("button",{type:"button",className:"btn btn-sm docker-onboarding__kv-add",onClick:ae,disabled:w,children:[e.jsx(ee,{size:14}),"Add mount"]})]})]})})]})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{className:"btn",onClick:U,disabled:w,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary",onClick:()=>void le(),disabled:w,children:w?"Creating...":"Create Docker Node"})]})]})}):null}function ms({nodeId:t,entries:l,loading:a=!1,singleNode:i=!1}){const[u,h]=s.useState(!1),[o,f]=s.useState("all"),[c,y]=s.useState("all"),p=s.useCallback(()=>{h(n=>!n)},[]),N=s.useMemo(()=>{const n=new Set;for(const x of l)n.add(x.nodeName);return Array.from(n).sort()},[l]),C=s.useMemo(()=>{let n=[...l];return o!=="all"&&(n=n.filter(x=>x.direction===o)),!i&&c!=="all"&&(n=n.filter(x=>x.nodeName===c)),n.sort((x,g)=>{const M=new Date(x.timestamp).getTime();return new Date(g.timestamp).getTime()-M}),n},[l,o,c,i]),v=s.useCallback(n=>new Date(n).toLocaleString(),[]),P=s.useCallback(n=>{switch(n){case"success":return"settings-sync-log__badge--success";case"conflict":return"settings-sync-log__badge--conflict";case"error":return"settings-sync-log__badge--error";default:return""}},[]),j=s.useCallback(n=>{switch(n){case"success":return"Success";case"conflict":return"Conflict";case"error":return"Error";default:return n}},[]);return e.jsxs("div",{className:"settings-sync-log",children:[e.jsxs("button",{className:"settings-sync-log__header",type:"button",onClick:p,"aria-expanded":u,"data-testid":"settings-sync-log-header",children:[e.jsx(Ne,{size:16,className:`settings-sync-log__chevron ${u?"settings-sync-log__chevron--expanded":""}`}),e.jsxs("span",{children:[l.length," ",l.length===1?"entry":"entries"]})]}),u&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"settings-sync-log__filters",children:[e.jsxs("label",{children:["Direction:",e.jsxs("select",{value:o,onChange:n=>f(n.target.value),children:[e.jsx("option",{value:"all",children:"All"}),e.jsx("option",{value:"push",children:"Push"}),e.jsx("option",{value:"pull",children:"Pull"})]})]}),!i&&e.jsxs("label",{children:["Node:",e.jsxs("select",{value:c,onChange:n=>y(n.target.value),children:[e.jsx("option",{value:"all",children:"All Nodes"}),N.map(n=>e.jsx("option",{value:n,children:n},n))]})]})]}),a&&l.length===0?e.jsx("div",{className:"settings-sync-log__empty",children:"Loading..."}):C.length===0?e.jsx("div",{className:"settings-sync-log__empty",children:"No sync history available"}):e.jsx("div",{className:"settings-sync-log__list",children:C.map(n=>e.jsxs("div",{className:"settings-sync-log__entry",children:[e.jsx("span",{className:"settings-sync-log__entry-timestamp",children:v(n.timestamp)}),e.jsx("span",{className:"settings-sync-log__entry-direction",children:n.direction==="push"?e.jsx(ve,{size:14,"data-testid":"upload-icon"}):e.jsx(_e,{size:14,"data-testid":"download-icon"})}),e.jsx("span",{className:`settings-sync-log__entry-result ${P(n.result)}`,children:j(n.result)}),!i&&e.jsx("span",{className:"settings-sync-log__entry-node",children:n.nodeName}),n.details&&e.jsx("span",{className:"settings-sync-log__entry-details",title:n.details,children:n.details})]},n.id))})]})]})}function hs(t,l){const a=typeof t=="string"?t:JSON.stringify(t,null,2),i=typeof l=="string"?l:JSON.stringify(l,null,2);if(a===i)return a;const u=a.split(`
12
+ `),h=i.split(`
13
+ `),o=[],f=Math.max(u.length,h.length);for(let c=0;c<f;c++){const y=u[c],p=h[c];y!==void 0&&y!==p&&o.push(`- ${y}`),p!==void 0&&p!==y&&o.push(`+ ${p}`),y!==void 0&&y===p&&o.push(` ${y}`)}return o.join(`
14
+ `)}function fs({isOpen:t,onClose:l,onResolve:a,conflicts:i,localNodeName:u,remoteNodeName:h,addToast:o}){const[f,c]=s.useState({}),[y,p]=s.useState(!1);s.useEffect(()=>{const n={};for(const x of i)f[x.key]||(n[x.key]={resolution:"local"});Object.keys(n).length>0&&c(x=>({...x,...n}))},[i,f]),s.useEffect(()=>{if(!t)return;const n=x=>{x.key==="Escape"&&(x.preventDefault(),l())};return document.addEventListener("keydown",n),()=>document.removeEventListener("keydown",n)},[t,l]);const N=s.useCallback((n,x)=>{c(g=>{const M=g[n]??{};return x==="manual"?{...g,[n]:{resolution:"manual",manualValue:M.manualValue??JSON.stringify(i.find(R=>R.key===n)?.localValue??null,null,2)}}:{...g,[n]:{resolution:x}}})},[i]),C=s.useCallback((n,x)=>{c(g=>({...g,[n]:{...g[n],resolution:"manual",manualValue:x}}))},[]),v=s.useCallback(n=>{const x={};for(const g of i)x[g.key]={resolution:n};c(x)},[i]),P=s.useCallback(async()=>{p(!0);try{const n=i.map(x=>{const g=f[x.key]??{resolution:"local"};let M;switch(g.resolution){case"remote":M=x.remoteValue;break;case"manual":try{M=JSON.parse(g.manualValue??"null")}catch{M=g.manualValue??null}break;case"local":default:M=x.localValue;break}return{key:x.key,value:M}});await a(n),o("Settings conflicts resolved successfully","success"),l()}catch(n){const x=n instanceof Error?n.message:"Failed to resolve conflicts";o(x,"error")}finally{p(!1)}},[o,i,l,a,f]),j=s.useMemo(()=>{const n={};for(const x of i)n[x.key]=hs(x.localValue,x.remoteValue);return n},[i]);return!t||i.length===0?null:e.jsx("div",{className:"modal-overlay open",onClick:l,children:e.jsxs("div",{className:"modal modal-lg settings-sync-conflict-modal",onClick:n=>n.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":"Resolve Settings Conflicts",children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:"Resolve Settings Conflicts"}),e.jsx("button",{className:"modal-close",onClick:l,"aria-label":"Close conflict modal",children:"×"})]}),e.jsxs("div",{className:"modal-body",children:[e.jsx("div",{className:"settings-sync-conflict-modal__conflict-list",children:i.map(n=>{const x=f[n.key]??{resolution:"local"},g=j[n.key];return e.jsxs("div",{className:"settings-sync-conflict-modal__conflict-item",children:[e.jsx("div",{className:"settings-sync-conflict-modal__key",children:n.key}),e.jsxs("div",{className:"settings-sync-conflict-modal__diff-panel",children:[e.jsxs("div",{className:"settings-sync-conflict-modal__diff-side",children:[e.jsx("div",{className:"settings-sync-conflict-modal__diff-label",children:u}),e.jsx("div",{className:"settings-sync-conflict-modal__diff-content",children:e.jsx("pre",{style:{margin:0,whiteSpace:"pre-wrap"},children:g})})]}),e.jsxs("div",{className:"settings-sync-conflict-modal__diff-side",children:[e.jsx("div",{className:"settings-sync-conflict-modal__diff-label",children:h}),e.jsx("div",{className:"settings-sync-conflict-modal__diff-content",children:e.jsx("pre",{style:{margin:0,whiteSpace:"pre-wrap"},children:g})})]})]}),e.jsxs("div",{className:"settings-sync-conflict-modal__resolution",children:[e.jsxs("label",{children:[e.jsx("input",{type:"radio",name:`resolution-${n.key}`,checked:x.resolution==="local",onChange:()=>N(n.key,"local")}),"Keep Local"]}),e.jsxs("label",{children:[e.jsx("input",{type:"radio",name:`resolution-${n.key}`,checked:x.resolution==="remote",onChange:()=>N(n.key,"remote")}),"Keep Remote"]}),e.jsxs("label",{children:[e.jsx("input",{type:"radio",name:`resolution-${n.key}`,checked:x.resolution==="manual",onChange:()=>N(n.key,"manual")}),"Merge Manually"]})]}),x.resolution==="manual"&&e.jsx("textarea",{className:"settings-sync-conflict-modal__manual-input",value:x.manualValue??"",onChange:M=>C(n.key,M.target.value),placeholder:"Enter JSON value..."})]},n.key)})}),e.jsxs("div",{className:"settings-sync-conflict-modal__bulk-actions",children:[e.jsx("button",{className:"btn btn-sm",onClick:()=>v("local"),type:"button",children:"Resolve All: Keep Local"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>v("remote"),type:"button",children:"Resolve All: Keep Remote"})]})]}),e.jsxs("div",{className:"modal-actions settings-sync-conflict-modal__footer",children:[e.jsx("button",{className:"btn btn-sm",onClick:l,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary btn-sm",onClick:P,disabled:y,children:y?"Resolving...":"Confirm"})]})]})})}function ce(t){if(!t)return"—";const l=new Date(t);return Number.isNaN(l.getTime())?"—":l.toLocaleString()}function xs(t){switch(t){case"synced":return"node-detail-modal__sync-dot--synced";case"diff":return"node-detail-modal__sync-dot--diff";case"error":return"node-detail-modal__sync-dot--error";case"pending":return"node-detail-modal__sync-dot--pending";case"never-synced":default:return"node-detail-modal__sync-dot--never"}}function gs({isOpen:t,onClose:l,node:a,projects:i,onUpdate:u,onHealthCheck:h,addToast:o,syncStatus:f,onPushSettings:c,onPullSettings:y,onSyncAuth:p,syncHistory:N=[],onResolveConflicts:C}){const v=s.useRef(!0),[P,j]=s.useState(!1),[n,x]=s.useState(""),[g,M]=s.useState(""),[R,E]=s.useState(""),[D,m]=s.useState(2),[r,b]=s.useState(!1),[z,F]=s.useState(!1),[H,q]=s.useState(!1),[O,V]=s.useState(!1),[T,k]=s.useState(null),[S,K]=s.useState(!1),[w]=s.useState([]),[J,L]=s.useState("running"),[U,X]=s.useState("FUSION_LOG_LEVEL=info"),[te,se]=s.useState("/srv/fusion:/data:rw");s.useEffect(()=>(v.current=!0,()=>{v.current=!1}),[]),s.useEffect(()=>{if(!a||!t){j(!1);return}x(a.name),M(a.url??""),E(a.apiKey??""),m(a.maxConcurrent),j(!1)},[t,a]),s.useEffect(()=>{if(!t)return;const _=I=>{I.key==="Escape"&&(I.preventDefault(),l())};return document.addEventListener("keydown",_),()=>document.removeEventListener("keydown",_)},[t,l]);const W=s.useMemo(()=>a?Ce(i,a):[],[a,i]),ae=s.useMemo(()=>a?.capabilities?.includes("docker-managed")??!1,[a]),Q=s.useCallback(async()=>{if(a)try{if(await h(a.id),!v.current)return;o(`Health check completed for ${a.name}`,"success")}catch(_){if(!v.current)return;const I=_ instanceof Error?_.message:"Health check failed";o(I,"error")}},[o,a,h]),ne=s.useCallback(async()=>{if(!(!a||!c)){k(null),F(!0);try{if(await c(a.id),!v.current)return;o("Settings pushed successfully","success")}catch(_){if(!v.current)return;const I=_ instanceof Error?_.message:"Push settings failed";k(I),o(I,"error")}finally{v.current&&F(!1)}}},[o,a,c]),le=s.useCallback(async()=>{if(!(!a||!y)){k(null),q(!0);try{if(await y(a.id),!v.current)return;o("Settings pulled successfully","success")}catch(_){if(!v.current)return;const I=_ instanceof Error?_.message:"Pull settings failed";k(I),o(I,"error")}finally{v.current&&q(!1)}}},[o,a,y]),d=s.useCallback(async()=>{if(!(!a||!p)){k(null),V(!0);try{if(await p(a.id),!v.current)return;o("Auth credentials synced successfully","success")}catch(_){if(!v.current)return;const I=_ instanceof Error?_.message:"Auth sync failed";k(I),o(I,"error")}finally{v.current&&V(!1)}}},[o,a,p]),A=s.useCallback(()=>{k(null)},[]),$=s.useCallback(_=>{_==="start"&&L("running"),_==="stop"&&L("stopped"),_==="restart"&&L("running"),_==="recreate"&&L("recreating"),_==="upgrade"&&L("recreating"),o(`Docker action queued: ${_}`,"success")},[o]),B=s.useCallback(async()=>{if(!a||r)return;const _=n.trim();if(!_){o("Name is required","error");return}if(a.type==="remote"&&!g.trim()){o("URL is required for remote nodes","error");return}if(!Number.isFinite(D)||D<1){o("Concurrency must be at least 1","error");return}b(!0);try{await u(a.id,{name:_,url:a.type==="remote"&&g.trim()||void 0,apiKey:a.type==="remote"&&R||void 0,maxConcurrent:D}),o(`Updated ${_}`,"success"),j(!1)}catch(I){const Se=I instanceof Error?I.message:"Failed to update node";o(Se,"error")}finally{b(!1)}},[o,R,r,D,n,a,u,g]),Z=s.useCallback(()=>{a&&(x(a.name),M(a.url??""),E(a.apiKey??""),m(a.maxConcurrent),j(!1))},[a]);return!t||!a?null:e.jsxs("div",{className:"modal-overlay open",onClick:l,children:[e.jsxs("div",{className:"modal modal-lg node-detail-modal",onClick:_=>_.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":`Node details for ${a.name}`,children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:"Node Details"}),e.jsx("button",{className:"modal-close",onClick:l,"aria-label":"Close node detail modal",children:"×"})]}),e.jsxs("div",{className:"modal-body node-detail-modal__body",children:[e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsxs("div",{className:"node-detail-modal__section-header",children:[e.jsx("h4",{children:"Overview"}),!P&&e.jsxs("button",{className:"btn btn-sm",onClick:()=>j(!0),children:[e.jsx($e,{size:14}),"Edit"]})]}),e.jsxs("div",{className:"node-detail-modal__grid",children:[e.jsxs("label",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Name"}),P?e.jsx("input",{className:"input",value:n,onChange:_=>x(_.target.value),disabled:r}):e.jsx("strong",{children:a.name})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Type"}),e.jsx("strong",{children:a.type==="local"?"Local":"Remote"})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Status"}),e.jsx("strong",{children:a.status})]}),e.jsxs("label",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Max Concurrent"}),P?e.jsx("input",{className:"input",type:"number",min:1,max:10,value:D,onChange:_=>m(Number(_.target.value)),disabled:r}):e.jsx("strong",{children:a.maxConcurrent})]}),a.type==="remote"&&e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"node-detail-modal__field node-detail-modal__field--full",children:[e.jsx("span",{children:"URL"}),P?e.jsx("input",{className:"input",value:g,onChange:_=>M(_.target.value),disabled:r}):e.jsx("strong",{children:a.url??"—"})]}),e.jsxs("label",{className:"node-detail-modal__field node-detail-modal__field--full",children:[e.jsx("span",{children:"API Key"}),P?e.jsx("input",{className:"input",type:"password",value:R,onChange:_=>E(_.target.value),placeholder:"Leave blank to keep unchanged",disabled:r}):e.jsx("strong",{children:a.apiKey?"••••••••":"Not configured"})]})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Created"}),e.jsx("strong",{children:ce(a.createdAt)})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Updated"}),e.jsx("strong",{children:ce(a.updatedAt)})]})]}),P&&e.jsxs("div",{className:"node-detail-modal__edit-actions",children:[e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:B,disabled:r,children:[e.jsx(Ke,{size:14}),r?"Saving...":"Save"]}),e.jsxs("button",{className:"btn btn-sm",onClick:Z,disabled:r,children:[e.jsx(ue,{size:14}),"Cancel"]})]})]}),e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsxs("h4",{children:[a.type==="local"?"Projects":"Assigned Projects"," (",W.length,")"]}),W.length===0?e.jsx("p",{className:"node-detail-modal__empty",children:a.type==="local"?"No projects are running on this node.":"No projects are assigned to this node."}):e.jsx("ul",{className:"node-detail-modal__project-list",children:W.map(_=>e.jsxs("li",{className:"node-detail-modal__project-item",children:[e.jsx("span",{children:_.name}),e.jsx("code",{children:_.id})]},_.id))})]}),e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsx("h4",{children:"Health"}),e.jsxs("div",{className:"node-detail-modal__health-row",children:[e.jsxs("span",{children:["Status: ",e.jsx("strong",{children:a.status})]}),e.jsxs("span",{children:["Last check: ",e.jsx("strong",{children:ce(a.updatedAt)})]})]})]}),ae&&e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsx("h4",{children:"Docker Management"}),e.jsxs("div",{className:"node-detail-modal__health-row",children:[e.jsxs("span",{children:["Container: ",e.jsx("strong",{children:J})]}),e.jsxs("span",{children:["Image: ",e.jsx("strong",{children:"runfusion/fusion:latest"})]})]}),e.jsxs("div",{className:"node-detail-modal__sync-actions",children:[e.jsx("button",{className:"btn btn-sm",onClick:()=>$("start"),children:"Start"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>$("stop"),children:"Stop"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>$("restart"),children:"Restart"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>$("recreate"),children:"Recreate"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>$("upgrade"),children:"Upgrade Image"})]}),e.jsxs("div",{className:"node-detail-modal__docker-grid",children:[e.jsxs("label",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Environment Variables"}),e.jsx("textarea",{className:"input node-detail-modal__textarea",value:U,onChange:_=>X(_.target.value)})]}),e.jsxs("label",{className:"node-detail-modal__field",children:[e.jsx("span",{children:"Volume Mounts"}),e.jsx("textarea",{className:"input node-detail-modal__textarea",value:te,onChange:_=>se(_.target.value)})]})]}),e.jsxs("div",{className:"node-detail-modal__sync-actions",children:[e.jsx("button",{className:"btn btn-sm",onClick:()=>o("Container logs opened","success"),children:"View Logs"}),e.jsx("button",{className:"btn btn-sm",onClick:()=>o("Config changes saved","success"),children:"Save Config"}),e.jsx("button",{className:"btn btn-danger btn-sm",onClick:()=>o("Delete flow opened (retain/remove volumes)","warning"),children:"Delete Node…"})]})]}),a.type==="remote"&&e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsx("h4",{children:"Settings Sync"}),f&&e.jsxs("div",{className:"node-detail-modal__sync-status",children:[e.jsx("span",{className:`node-detail-modal__sync-dot ${xs(f.syncState)}`,"aria-hidden":!0}),e.jsxs("span",{children:["Last sync:"," ",e.jsx("strong",{children:f.lastSyncAt?ke(f.lastSyncAt):"Never synced"})]}),f.diffCount>0&&e.jsxs("span",{className:"node-detail-modal__sync-diff",children:["Differences: ",e.jsx("strong",{children:f.diffCount})]})]}),e.jsxs("div",{className:"node-detail-modal__sync-actions",children:[e.jsxs("button",{className:"btn btn-sm",onClick:ne,disabled:z||!c,children:[e.jsx(ve,{size:14}),z?"Pushing...":"Push Settings"]}),e.jsxs("button",{className:"btn btn-sm",onClick:le,disabled:H||!y,children:[e.jsx(_e,{size:14}),H?"Pulling...":"Pull Settings"]}),e.jsxs("button",{className:"btn btn-sm",onClick:d,disabled:O||!p,children:[e.jsx(be,{size:14}),O?"Syncing...":"Sync Auth"]})]}),T&&e.jsxs("div",{className:"node-detail-modal__sync-error",children:[e.jsx("span",{children:T}),e.jsx("button",{className:"node-detail-modal__sync-error-dismiss",onClick:A,"aria-label":"Dismiss error",children:e.jsx(ue,{size:14})})]})]}),a.type==="remote"&&e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsx("h4",{children:"Sync History"}),e.jsx(ms,{nodeId:a.id,entries:N,singleNode:!0})]})]}),e.jsxs("div",{className:"modal-actions node-detail-modal__actions",children:[e.jsxs("button",{className:"btn btn-sm",onClick:Q,children:[e.jsx(je,{size:14}),"Health Check"]}),e.jsx("button",{className:"btn btn-sm",onClick:l,children:"Close"})]})]}),a.type==="remote"&&e.jsx(fs,{isOpen:S,onClose:()=>K(!1),onResolve:C??(async()=>{}),conflicts:w,localNodeName:"Local",remoteNodeName:a.name,addToast:o})]})}function ps(){const[t,l]=s.useState([]),[a,i]=s.useState(!0),[u,h]=s.useState(null),o=s.useCallback(async()=>{try{h(null);const c=await xe();l(c)}catch(c){h(c instanceof Error?c.message:"Failed to fetch managed Docker nodes")}},[]);s.useEffect(()=>{let c=!1;async function y(){i(!0);try{const p=await xe();c||(l(p),h(null))}catch(p){c||h(p instanceof Error?p.message:"Failed to fetch managed Docker nodes")}finally{c||i(!1)}}return y(),()=>{c=!0}},[]);const f=s.useCallback(async c=>{const y=await ze(c);return l(p=>[...p,y]),y},[]);return{dockerNodes:t,loading:a,error:u,refresh:o,create:f}}function _s({addToast:t,onClose:l}){const{nodes:a,loading:i,error:u,refresh:h,register:o,update:f,unregister:c,healthCheck:y}=Ie(),{projects:p}=Fe(),{syncStatusMap:N,pushSettings:C,pullSettings:v,syncAuth:P,trackNode:j,getAuthSyncState:n,getAuthProviders:x}=Je(),{dockerNodes:g,create:M}=ps(),[R,E]=s.useState(!1),[D,m]=s.useState(!1),[r,b]=s.useState(null);s.useEffect(()=>{const k=a.filter(S=>S.type==="remote");for(const S of k)j(S.id)},[a,j]),s.useEffect(()=>{if(!r)return;const k=a.find(S=>S.id===r.id)??null;b(k)},[a,r]);const z=s.useMemo(()=>{const k=a.length,S=a.filter(L=>L.status==="online").length,K=a.filter(L=>L.status==="offline"||L.status==="error").length,w=a.filter(L=>L.type==="remote").length,J=a.filter(L=>L.type==="remote"&&N[L.id]&&re(N[L.id]).syncState==="synced").length;return{total:k,online:S,offline:K,remote:w,synced:J}},[a,N]),F=s.useCallback(async k=>{await o(k)},[o]),H=s.useCallback(async k=>{try{await M(k),t(`Docker node "${k.name}" created`,"success"),m(!1)}catch(S){const K=S instanceof Error?S.message:"Failed to create Docker node";throw t(K,"error"),S}},[t,M]),q=s.useCallback(async()=>{try{await h()}catch{t("Failed to refresh nodes","error")}},[t,h]),O=s.useCallback(async k=>{try{await y(k),t("Node health check complete","success")}catch(S){const K=S instanceof Error?S.message:"Health check failed";t(K,"error")}},[t,y]),V=s.useCallback(async k=>{try{await c(k),t("Node removed","success"),r?.id===k&&b(null)}catch(S){const K=S instanceof Error?S.message:"Failed to remove node";t(K,"error")}},[t,r?.id,c]),T=s.useCallback(async(k,S)=>{await f(k,S)},[f]);return e.jsxs("div",{className:"nodes-view","data-testid":"nodes-view",children:[e.jsxs("div",{className:"nodes-view-header",children:[e.jsxs("div",{className:"nodes-view-title",children:[e.jsxs("h2",{children:[e.jsx(ye,{size:20}),"Nodes"]}),e.jsxs("span",{className:"nodes-view-count",children:[a.length," registered"]})]}),e.jsxs("div",{className:"nodes-view-actions",children:[e.jsx("button",{className:"btn-icon nodes-view-close",onClick:l,"aria-label":"Close nodes view",children:e.jsx(ue,{size:16})}),e.jsxs("button",{className:"btn btn-sm",onClick:()=>void q(),disabled:i,children:[e.jsx(de,{size:14,className:i?"spin":""}),"Refresh"]}),e.jsxs("button",{className:"btn btn-sm",onClick:()=>E(!0),children:[e.jsx(ee,{size:14}),"Add Node"]}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:()=>m(!0),children:[e.jsx(ee,{size:14}),"Provision Docker Node"]})]})]}),e.jsxs("div",{className:"nodes-view-stats",children:[e.jsxs("div",{className:"nodes-view-stat","data-testid":"nodes-stat-total",children:[e.jsx("span",{children:"Total"}),e.jsx("strong",{children:z.total})]}),e.jsxs("div",{className:"nodes-view-stat nodes-view-stat--online","data-testid":"nodes-stat-online",children:[e.jsxs("span",{children:[e.jsx(He,{size:14})," Online"]}),e.jsx("strong",{children:z.online})]}),e.jsxs("div",{className:"nodes-view-stat nodes-view-stat--offline","data-testid":"nodes-stat-offline",children:[e.jsxs("span",{children:[e.jsx(Ue,{size:14})," Offline"]}),e.jsx("strong",{children:z.offline})]}),e.jsxs("div",{className:"nodes-view-stat","data-testid":"nodes-stat-remote",children:[e.jsxs("span",{children:[e.jsx(Oe,{size:14})," Remote"]}),e.jsx("strong",{children:z.remote})]}),e.jsxs("div",{className:"nodes-view-stat nodes-view-stat--synced","data-testid":"nodes-stat-synced",children:[e.jsxs("span",{children:[e.jsx(de,{size:14})," Synced"]}),e.jsx("strong",{children:z.synced})]})]}),u&&e.jsx("div",{className:"nodes-view-error",children:u}),e.jsxs("section",{className:"nodes-view-topology","aria-label":"Docker Nodes Summary",children:[e.jsx("h3",{className:"nodes-view-section-title",children:"Docker Nodes"}),e.jsxs("div",{className:"nodes-view-stat",children:[e.jsx("span",{children:"Managed Docker Nodes"}),e.jsx("strong",{children:g.length}),e.jsx("button",{className:"btn btn-sm",onClick:()=>m(!0),children:"Provision"})]})]}),!i&&a.length>0&&e.jsxs("section",{className:"nodes-view-topology","aria-label":"Mesh Topology",children:[e.jsx("h3",{className:"nodes-view-section-title",children:"Mesh Topology"}),e.jsx(ls,{nodes:a})]}),i?e.jsx("div",{className:"nodes-view-grid",children:Array.from({length:4}).map((k,S)=>e.jsx("div",{className:"node-card node-card--loading","aria-hidden":!0},S))}):a.length===0?e.jsxs("div",{className:"nodes-view-empty",children:[e.jsx("p",{children:"No nodes are registered yet."}),e.jsxs("button",{className:"btn btn-primary",onClick:()=>E(!0),children:[e.jsx(ee,{size:14}),"Add First Node"]})]}):e.jsx("div",{className:"nodes-view-grid",children:a.map(k=>{const S=k.type==="remote"&&N[k.id]?re(N[k.id]):void 0;return e.jsx(ss,{node:k,projects:p,onHealthCheck:K=>{O(K)},onEdit:K=>b(K),onRemove:K=>{V(K)},isLoading:i,syncStatus:S,authSyncState:k.type==="remote"?n(k.id):void 0,authSyncProviders:k.type==="remote"?x(k.id):void 0},k.id)})}),e.jsx(os,{isOpen:R,onClose:()=>E(!1),onSubmit:F,addToast:t}),e.jsx(us,{isOpen:D,onClose:()=>m(!1),onSubmit:H,addToast:t}),e.jsx(gs,{isOpen:r!==null,onClose:()=>b(null),node:r,projects:p,onUpdate:T,onHealthCheck:O,addToast:t,syncStatus:r?.type==="remote"&&r&&N[r.id]?re(N[r.id]):void 0,onPushSettings:C,onPullSettings:v,onSyncAuth:P})]})}export{_s as NodesView};
@@ -0,0 +1 @@
1
+ .nodes-management-overlay{display:flex;flex-direction:column;gap:var(--space-md);height:100%;overflow-y:auto;-webkit-overflow-scrolling:touch}.nodes-management-overlay__header{display:flex;justify-content:flex-end}.nodes-view{display:flex;flex-direction:column;gap:var(--space-md);padding:var(--space-sm) var(--space-md) var(--space-xl)}.nodes-view-header{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:var(--space-sm)}.nodes-view-title{display:flex;align-items:center;gap:var(--space-sm)}.nodes-view-title h2{margin:0;display:flex;align-items:center;gap:var(--space-sm)}.nodes-view-count{color:var(--text-muted);font-size:calc(var(--space-md) + var(--space-xs) / 4)}.nodes-view-actions{display:flex;gap:var(--space-sm)}.nodes-view-close{margin-left:auto}.nodes-view-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(calc(var(--space-xl) * 5.833),1fr));gap:var(--space-sm)}.nodes-view-stat{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:var(--space-sm) var(--space-md);display:flex;align-items:center;justify-content:space-between;gap:var(--space-sm)}.nodes-view-stat span{display:inline-flex;align-items:center;gap:var(--space-sm);color:var(--text-muted);font-size:calc(var(--space-sm) + var(--space-xs))}.nodes-view-stat strong{font-size:calc(var(--space-lg) + var(--space-xs) / 2)}.nodes-view-stat--online strong{color:var(--color-success)}.nodes-view-stat--offline strong{color:var(--color-error)}.nodes-view-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(calc(var(--space-lg) * 20),1fr));gap:var(--space-md)}.nodes-view-empty{padding:var(--space-xl);border:1px dashed var(--border);border-radius:var(--radius);text-align:center;color:var(--text-muted);display:flex;flex-direction:column;align-items:center;gap:var(--space-md)}.nodes-view-error{color:var(--color-error);font-size:calc(var(--space-md) + var(--space-xs) / 4)}.node-card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:var(--space-md);display:flex;flex-direction:column;gap:var(--space-md);cursor:pointer;transition:border-color var(--transition-fast),transform var(--transition-fast)}.node-card:hover{border-color:var(--accent);transform:translateY(calc(var(--space-xs) * -.25))}.node-card:focus-visible{outline:none;border-color:var(--todo);box-shadow:var(--focus-ring-strong)}.node-card--loading{min-height:calc(var(--space-xl) * 9.167);opacity:.55;pointer-events:none}.node-card__header{display:flex;align-items:center;justify-content:space-between}.node-card__title-wrap{display:flex;align-items:center;gap:var(--space-sm)}.node-card__icon{width:calc(var(--space-lg) * 2.125);height:calc(var(--space-lg) * 2.125);border-radius:var(--radius-sm);display:inline-flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--accent) 12%,transparent);color:var(--accent)}.node-card__name{margin:0;font-size:calc(var(--space-md) + var(--space-xs));line-height:1.25}.node-card__meta-row{margin-top:var(--space-xs);display:flex;align-items:center;gap:var(--space-xs)}.node-card__type-badge{border:1px solid var(--border);border-radius:var(--radius-pill);padding:var(--space-xs) var(--space-sm);font-size:calc(var(--space-sm) + var(--space-xs) * .75);color:var(--text-muted)}.node-card__status{display:inline-flex;align-items:center;gap:var(--space-xs);font-size:calc(var(--space-sm) + var(--space-xs) * .75);font-weight:600}.node-card__status-indicator{width:var(--space-sm);height:var(--space-sm);border-radius:50%}.node-card__status--online .node-card__status-indicator{background:var(--color-success)}.node-card__status--offline .node-card__status-indicator,.node-card__status--error .node-card__status-indicator{background:var(--color-error)}.node-card__status--connecting .node-card__status-indicator{background:var(--color-warning)}.node-card__auth-indicator{display:inline-flex;align-items:center;margin-left:var(--space-xs);vertical-align:middle}.node-card__url{font-family:var(--font-mono);font-size:calc(var(--space-sm) + var(--space-xs));color:var(--text-muted);word-break:break-all}.node-card__metrics{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-sm)}.node-card__metric{display:flex;flex-direction:column;gap:var(--space-xs)}.node-card__metric-label{color:var(--text-muted);font-size:calc(var(--space-sm) + var(--space-xs) * .75);text-transform:uppercase;letter-spacing:.03em}.node-card__metric-value{font-size:calc(var(--space-md) + var(--space-xs));font-weight:600}.node-card__sync{display:flex;align-items:center;gap:var(--space-xs);margin-top:var(--space-sm);font-size:calc(var(--space-sm) + var(--space-xs));color:var(--text-muted)}.node-card__sync-dot{width:var(--space-sm);height:var(--space-sm);border-radius:50%;flex-shrink:0}.node-card__sync-time{color:var(--text-muted)}.nodes-view-stat--synced strong{color:var(--color-success)}.node-card__actions{display:flex;gap:var(--space-xs);flex-wrap:wrap}.node-card__action{display:inline-flex;align-items:center;gap:var(--space-xs)}.node-card__action--remove{margin-left:auto}.node-card__action--remove:not(.btn-danger){color:var(--color-error);border-color:color-mix(in srgb,var(--color-error) 45%,var(--border))}.node-card__action--remove.is-armed{background:color-mix(in srgb,var(--color-error) 14%,transparent)}.mesh-topology{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-md);min-height:calc(var(--space-2xl) * 6.25);padding:var(--space-md);background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-md)}.mesh-topology__svg{width:100%;max-width:calc(var(--space-2xl) * 12.5);height:auto;aspect-ratio:1}.mesh-topology__node{transition:filter var(--transition-fast)}.mesh-topology__node:hover{filter:brightness(1.1)}.mesh-topology__node-circle{stroke:var(--border);stroke-width:calc(var(--space-xs) / 2);transition:fill var(--transition-fast)}.mesh-topology__node-label{font-size:calc(var(--space-sm) + var(--space-xs) * .75);fill:var(--text);font-weight:500}.mesh-topology__node-type-badge{fill:color-mix(in srgb,var(--surface) 75%,var(--bg));stroke:var(--border);stroke-width:calc(var(--space-xs) / 4)}.mesh-topology__node-type-text{font-size:calc(var(--space-sm) + var(--space-xs) / 2);font-weight:700;fill:var(--text-muted);text-transform:uppercase;letter-spacing:.03em}.mesh-topology__link{stroke:var(--border);stroke-width:calc((var(--space-xs) * 3) / 8);stroke-dasharray:var(--space-xs),var(--space-xs);opacity:.6}.mesh-topology__legend{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--space-md);font-size:calc(var(--space-sm) + var(--space-xs));color:var(--text-muted)}.mesh-topology__legend-item{display:flex;align-items:center;gap:var(--space-sm)}.mesh-topology__notice{margin:var(--space-md) 0 0;text-align:center;color:var(--text-dim);font-size:calc(var(--space-sm) + var(--space-xs))}.mesh-topology__legend-dot{width:calc(var(--space-sm) + var(--space-xs) / 2);height:calc(var(--space-sm) + var(--space-xs) / 2);border-radius:50%;border:1px solid var(--border)}.mesh-topology--empty{justify-content:center}.mesh-topology__empty-state{text-align:center;color:var(--text-muted);font-size:calc(var(--space-md) + var(--space-xs) / 2)}.connect-node-modal{width:min(calc(var(--space-lg) * 30),calc(100vw - (var(--space-lg) * 2)))}.connect-node-form{display:flex;flex-direction:column;gap:var(--space-md)}.connect-node-form .form-group{padding:0;margin-top:0}.connect-node-form .form-group:last-of-type{margin-bottom:0}.connect-node-field{display:flex;flex-direction:column;gap:var(--space-xs)}.connect-node-field__input{width:100%}.connect-node-field__input[aria-invalid=true]{border-color:var(--color-error);background:color-mix(in srgb,var(--color-error) 5%,var(--surface))}.connect-node-field__input[aria-invalid=true]:focus-visible{border-color:var(--color-error);box-shadow:var(--glow-danger)}.connect-node-url-preview{display:flex;align-items:center;gap:var(--space-sm);padding:var(--space-sm) var(--space-md);background:color-mix(in srgb,var(--surface) 50%,var(--bg));border-radius:var(--radius-sm);border-left:var(--space-xs) solid var(--accent);font-size:calc(var(--space-sm) + var(--space-xs))}.connect-node-url-preview-label{color:var(--text-muted)}.connect-node-url-preview code{font-family:var(--font-mono);color:var(--text);font-size:calc(var(--space-sm) + var(--space-xs))}.connect-node-actions{display:flex;justify-content:flex-end;gap:var(--space-sm);padding:var(--modal-padding);border-top:1px solid var(--border)}.nodes-view-topology{margin-bottom:var(--space-md)}.nodes-view-section-title{font-size:calc(var(--space-md) + var(--space-xs) * .5);font-weight:600;color:var(--text);margin:0 0 var(--space-sm)}.nodes-view .node-status-indicator{display:inline-flex;align-items:center;gap:var(--space-xs);font-size:calc(var(--space-sm) + var(--space-xs) * .625)}.nodes-view .node-status-indicator__label,.nodes-view .node-status-indicator--local{color:var(--text-muted)}.nodes-view .node-status-indicator--remote{color:var(--text)}.nodes-view .node-status-indicator__dot{width:var(--space-sm);height:var(--space-sm);border-radius:50%;position:relative;display:inline-block}.nodes-view .node-status-indicator__dot--online{background:var(--color-success);box-shadow:var(--glow-success)}.nodes-view .node-status-indicator__dot--offline,.nodes-view .node-status-indicator__dot--error{background:var(--color-error)}.nodes-view .node-status-indicator__dot--connecting{background:var(--color-warning);animation:pulse-warning 1.5s ease-in-out infinite}.nodes-view .node-status-indicator__spinner{position:absolute;inset:0;border:calc(var(--space-xs) / 2) solid transparent;border-top-color:currentColor;border-radius:50%;animation:spin 1s linear infinite}.nodes-view .node-status-indicator__name{font-weight:500}.nodes-view .node-status-indicator__details{font-size:calc(var(--space-sm) + var(--space-xs));color:var(--text-muted)}@keyframes pulse-warning{0%,to{opacity:1;box-shadow:var(--glow-warning)}50%{opacity:.6;box-shadow:var(--glow-warning)}}@media(max-width:768px){.nodes-view{padding-inline:var(--space-sm)}.nodes-view-grid,.node-card__metrics{grid-template-columns:1fr}.connect-node-modal{width:calc(100vw - (var(--space-md) * 2))}.connect-node-field__input{min-height:calc(var(--space-2xl) + var(--space-md))}.nodes-view-header{padding:var(--space-sm) var(--space-md);flex-wrap:wrap;gap:var(--space-sm)}.nodes-view-title h2{font-size:calc(var(--space-md) + var(--space-xs))}.nodes-view-title h2 svg{flex-shrink:0}.nodes-view-count{font-size:calc(var(--space-sm) + var(--space-xs))}.nodes-view-actions{flex-wrap:wrap;gap:var(--space-sm);width:100%;justify-content:flex-end}.nodes-view-close{min-height:calc(var(--space-xl) + var(--space-md));min-width:calc(var(--space-xl) + var(--space-md))}.nodes-view-actions .btn{min-height:calc(var(--space-xl) + var(--space-md))}.nodes-view-stats{grid-template-columns:repeat(2,1fr);gap:var(--space-sm)}.nodes-view-stat{padding:var(--space-xs) var(--space-sm)}.nodes-view-stat span{font-size:calc(var(--space-sm) + var(--space-xs) * .75)}.nodes-view-stat strong{font-size:calc(var(--space-md) + var(--space-xs) / 2)}.nodes-view-empty{padding:var(--space-xl) var(--space-md);text-align:center}.nodes-view-error{padding:var(--space-md);margin:var(--space-md) 0}.nodes-view-topology{padding:var(--space-sm) 0}.nodes-view-section-title{font-size:calc(var(--space-md) + var(--space-xs) / 4)}}.add-node-modal{width:min(calc(var(--space-lg) * 32.5),calc(100vw - (var(--space-lg) * 2)))}.add-node-modal__body{display:flex;flex-direction:column;gap:var(--space-md)}.add-node-modal__row{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-sm)}.add-node-modal__fieldset{border:1px solid var(--border);border-radius:var(--radius-sm);padding:var(--space-sm);display:flex;flex-direction:column;gap:var(--space-sm)}.add-node-modal__fieldset legend{color:var(--text-muted);font-size:calc(var(--space-sm) + var(--space-xs) * .625);padding:0 var(--space-xs)}.add-node-modal__storage-toggle{border:1px solid var(--border);border-radius:var(--radius-sm);padding:var(--space-sm)}.add-node-modal__advanced-btn{align-self:flex-start}.add-node-modal__advanced{border:1px dashed var(--border);border-radius:var(--radius-sm);padding:var(--space-sm);display:flex;flex-direction:column;gap:var(--space-sm)}.add-node-modal__textarea{min-height:calc(var(--space-2xl) * 2.25);resize:vertical;font-family:var(--font-mono)}.add-node-modal__description{font-size:calc(var(--space-sm) + var(--space-xs) * .625);color:var(--text-muted);margin-bottom:var(--space-sm);padding:0}.add-node-modal__field{display:flex;flex-direction:column;gap:var(--space-xs)}.add-node-modal__field>span{font-size:calc(var(--space-sm) + var(--space-xs) * .625);font-weight:600;color:var(--text-muted)}.add-node-modal__field .input{width:100%;padding:var(--space-sm) var(--space-md);font-size:calc(var(--space-md) + var(--space-xs) * .5)}.add-node-modal__field .input:focus-visible{border-color:var(--accent);box-shadow:var(--focus-ring-strong)}.add-node-modal__field .input[aria-invalid=true]{border-color:var(--color-error);background:color-mix(in srgb,var(--color-error) 5%,var(--surface))}.add-node-modal__field .input[aria-invalid=true]:focus{box-shadow:var(--glow-danger)}.add-node-modal__hint{font-size:calc(var(--space-sm) + var(--space-xs) * .375);color:var(--text-dim);margin-top:calc(var(--space-xs) / 2)}.add-node-modal__error{margin-top:calc(var(--space-xs) / 2)}.add-node-modal__type-toggle{display:flex;gap:0;border:1px solid var(--border);border-radius:var(--radius-md);overflow:hidden;background:var(--surface)}.add-node-modal__type-btn{flex:1;padding:calc(var(--space-sm) + var(--space-xs) / 2) var(--space-lg);border:none;background:transparent;color:var(--text-muted);font-size:calc(var(--space-sm) + var(--space-xs) * .625);font-weight:500;cursor:pointer;transition:background var(--transition-fast),color var(--transition-fast)}.add-node-modal__type-btn:hover:not(:disabled){background:color-mix(in srgb,var(--bg) 50%,var(--surface))}.add-node-modal__type-btn:focus-visible{outline:none;box-shadow:var(--focus-ring-strong);z-index:1}.add-node-modal__type-btn.active{background:var(--accent);color:var(--bg)}.add-node-modal__type-btn:disabled{opacity:.6;cursor:not-allowed}.add-node-modal__remote-fields{display:grid;gap:var(--space-sm)}@media(max-width:768px){.add-node-modal{width:calc(100vw - (var(--space-md) * 2))}.add-node-modal__type-toggle{width:100%}.add-node-modal__type-btn{flex:1;padding:var(--space-md) var(--space-lg)}.add-node-modal__field input{min-height:calc(var(--space-2xl) + var(--space-md));font-size:calc(var(--space-md) + var(--space-xs) * .5)}.add-node-modal__row{grid-template-columns:1fr}}.docker-tls-config{display:flex;flex-direction:column;gap:var(--space-md)}.docker-tls-config__fields{display:grid;gap:var(--space-md)}.docker-tls-config__field{display:flex;flex-direction:column;gap:var(--space-xs)}.docker-tls-config__field label{color:var(--text-muted)}@media(max-width:768px){.docker-tls-config .input{min-height:calc(var(--mobile-nav-height) - var(--space-sm))}}.docker-target-selector{display:flex;flex-direction:column;gap:var(--space-md)}.docker-target-selector__modes{display:flex;gap:var(--space-sm);flex-wrap:wrap}.docker-target-selector__mode-active{border-color:var(--todo);box-shadow:var(--focus-ring-strong)}.docker-target-selector__panel{display:grid;gap:var(--space-md)}.docker-target-selector__field{display:flex;flex-direction:column;gap:var(--space-xs)}.docker-target-selector__field label{color:var(--text-muted)}.docker-target-selector__context-row{display:grid;gap:var(--space-sm);grid-template-columns:minmax(0,1fr) auto;align-items:center}.docker-target-selector__status{color:var(--text-muted)}.docker-target-selector__success{color:var(--color-success)}.docker-target-selector__error{color:var(--color-error)}@media(max-width:768px){.docker-target-selector__modes .btn{min-height:calc(var(--mobile-nav-height) - var(--space-sm))}}.docker-onboarding{width:min(calc(var(--space-2xl) * 22.5),calc(100vw - (var(--space-lg) * 2)))}.docker-onboarding__body{display:flex;flex-direction:column;gap:var(--space-md)}.docker-onboarding__section{background:var(--card);border:1px solid var(--border);border-radius:var(--radius-md);padding:var(--space-md);display:flex;flex-direction:column;gap:var(--space-sm)}.docker-onboarding__section-title{margin:0;display:flex;align-items:center;gap:var(--space-sm);font-size:calc(var(--space-md) + var(--space-xs) / 2)}.docker-onboarding__field{display:flex;flex-direction:column;gap:var(--space-xs)}.docker-onboarding__inline-fields{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-sm)}.docker-onboarding__radio-group{display:flex;align-items:center;gap:var(--space-md);flex-wrap:wrap}.docker-onboarding__type-toggle{display:flex;border:1px solid var(--border);border-radius:var(--radius-sm);overflow:hidden}.docker-onboarding__type-btn{flex:1;border:none;background:var(--surface);color:var(--text);padding:var(--space-sm) var(--space-md);cursor:pointer;transition:background var(--transition-fast),color var(--transition-fast)}.docker-onboarding__type-btn+.docker-onboarding__type-btn{border-left:1px solid var(--border)}.docker-onboarding__type-btn.is-active{background:var(--todo);color:var(--bg)}.docker-onboarding__type-btn:focus-visible{outline:none;box-shadow:var(--focus-ring-strong);position:relative;z-index:1}.docker-onboarding__checkbox-group{display:flex;flex-direction:column;gap:var(--space-xs)}.docker-onboarding__kv-list{display:flex;flex-direction:column;gap:var(--space-sm)}.docker-onboarding__kv-list h5{margin:0;font-size:calc(var(--space-sm) + var(--space-xs))}.docker-onboarding__kv-row{display:grid;gap:var(--space-sm);align-items:center}.docker-onboarding__kv-row--env{grid-template-columns:minmax(0,1fr) minmax(0,1fr) auto}.docker-onboarding__kv-row--mount{grid-template-columns:minmax(0,1fr) minmax(0,1fr) auto auto}.docker-onboarding__kv-add{align-self:flex-start}.docker-onboarding__advanced-toggle{border:none;background:none;color:var(--text);padding:var(--space-xs);margin:calc(var(--space-xs) * -1);border-radius:var(--radius-sm);display:flex;align-items:center;justify-content:space-between;width:100%;cursor:pointer;font-size:calc(var(--space-md) + var(--space-xs) / 2);font-weight:600}.docker-onboarding__advanced-toggle:focus-visible{outline:none;box-shadow:var(--focus-ring-strong)}.docker-onboarding__advanced-toggle svg{transition:transform var(--transition-fast)}.docker-onboarding__advanced-toggle.is-expanded svg{transform:rotate(180deg)}.docker-onboarding__advanced-content{display:grid;grid-template-rows:0fr;transition:grid-template-rows var(--transition-fast)}.docker-onboarding__advanced-content>div{overflow:hidden;display:flex;flex-direction:column;gap:var(--space-sm)}.docker-onboarding__advanced-content.is-expanded{grid-template-rows:1fr}.docker-onboarding__tls-fields{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-sm)}.docker-onboarding__tls-fields .docker-onboarding__field:first-child{grid-column:1 / -1}@media(max-width:768px){.docker-onboarding{width:calc(100vw - (var(--space-md) * 2))}.docker-onboarding__inline-fields,.docker-onboarding__tls-fields,.docker-onboarding__kv-row{grid-template-columns:1fr}.docker-onboarding .input,.docker-onboarding .select,.docker-onboarding .btn{min-height:calc(var(--space-2xl) + var(--space-md))}.docker-onboarding__advanced-content{transition:none}}.settings-sync-log{display:flex;flex-direction:column;gap:var(--space-sm)}.settings-sync-log__header{display:flex;align-items:center;gap:var(--space-xs);cursor:pointer;padding:var(--space-xs) 0;border-radius:var(--radius-sm);border:none;background:transparent;color:var(--text);font:inherit;text-align:left;transition:background-color var(--transition-fast)}.settings-sync-log__header:hover{background:var(--surface-hover)}.settings-sync-log__header:focus-visible{outline:none;box-shadow:var(--focus-ring-strong);background:var(--surface-hover)}.settings-sync-log__chevron{transform:rotate(0);transition:transform var(--transition-fast)}.settings-sync-log__chevron--expanded{transform:rotate(180deg)}.settings-sync-log__filters{display:flex;gap:var(--space-sm);align-items:center;flex-wrap:wrap}.settings-sync-log__filters label{display:flex;align-items:center;gap:var(--space-xs);font-size:12px;color:var(--text-muted)}.settings-sync-log__filters select{font-size:12px;padding:4px 8px;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text)}.settings-sync-log__filters select:focus{outline:none;border-color:var(--todo);box-shadow:var(--focus-ring)}.settings-sync-log__list{display:flex;flex-direction:column}.settings-sync-log__entry{display:flex;align-items:center;gap:var(--space-sm);padding:var(--space-xs) 0;border-bottom:1px solid var(--border)}.settings-sync-log__entry:last-child{border-bottom:none}.settings-sync-log__entry-timestamp{font-size:12px;color:var(--text-muted);min-width:140px}.settings-sync-log__entry-direction{display:flex;align-items:center;color:var(--text-muted)}.settings-sync-log__entry-result{display:inline-flex;padding:2px 8px;border-radius:999px;font-size:11px;font-weight:500}.settings-sync-log__badge--success{background:color-mix(in srgb,var(--color-success, #2da44e) 14%,transparent);color:var(--color-success, #2da44e)}.settings-sync-log__badge--conflict{background:color-mix(in srgb,#d29922 14%,transparent);color:#d29922}.settings-sync-log__badge--error{background:color-mix(in srgb,var(--color-error, #cf222e) 14%,transparent);color:var(--color-error, #cf222e)}.settings-sync-log__entry-node{font-weight:500;font-size:12px}.settings-sync-log__entry-details{font-size:12px;color:var(--text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}.settings-sync-log__empty{text-align:center;color:var(--text-muted);padding:var(--space-md);font-size:13px}.node-badge{display:inline-flex;align-items:center;padding:2px 8px;border-radius:999px;background:color-mix(in srgb,var(--accent) 14%,transparent);border:1px solid color-mix(in srgb,var(--accent) 36%,transparent);color:var(--text-muted);font-size:11px;width:fit-content;margin-top:4px}@media(max-width:768px){.settings-sync-conflict-modal__diff-panel{grid-template-columns:1fr}}.settings-sync-conflict-modal{max-width:860px;width:min(860px,calc(100vw - 32px))}.settings-sync-conflict-modal__conflict-list{display:flex;flex-direction:column;gap:var(--space-md);max-height:min(50vh,400px);overflow-y:auto}.settings-sync-conflict-modal__conflict-item{border:1px solid var(--border);border-radius:var(--radius);padding:var(--space-md)}.settings-sync-conflict-modal__key{font-weight:600;font-family:monospace;margin-bottom:var(--space-sm)}.settings-sync-conflict-modal__diff-panel{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-sm);margin-bottom:var(--space-sm)}.settings-sync-conflict-modal__diff-side{border:1px solid var(--border);border-radius:var(--radius-sm);overflow:hidden}.settings-sync-conflict-modal__diff-label{font-size:calc(var(--space-sm) + var(--space-xs) * .75);color:var(--text-muted);padding:4px 8px;border-bottom:1px solid var(--border);background:var(--surface)}.settings-sync-conflict-modal__diff-content{padding:var(--space-xs) var(--space-sm);white-space:pre;font-family:monospace;font-size:12px;line-height:1.5;overflow-x:auto}.settings-sync-conflict-modal__resolution{display:flex;gap:var(--space-md);align-items:center}.settings-sync-conflict-modal__resolution label{display:flex;align-items:center;gap:var(--space-xs);cursor:pointer}.settings-sync-conflict-modal__resolution input[type=radio]{cursor:pointer}.settings-sync-conflict-modal__manual-input{width:100%;font-family:monospace;font-size:12px;min-height:80px;margin-top:var(--space-xs);padding:var(--space-sm);background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text);resize:vertical}.settings-sync-conflict-modal__manual-input:focus{outline:none;border-color:var(--todo);box-shadow:var(--focus-ring)}.settings-sync-conflict-modal__bulk-actions{display:flex;gap:var(--space-xs);padding-top:var(--space-sm);border-top:1px solid var(--border)}.settings-sync-conflict-modal__footer{display:flex;justify-content:flex-end;gap:var(--space-xs)}.node-detail-modal{max-width:calc(var(--space-lg) * 53.75);width:min(calc(var(--space-lg) * 53.75),calc(100vw - (var(--space-lg) * 2)))}.node-detail-modal__body{display:flex;flex-direction:column;gap:var(--space-md);max-height:min(72vh,calc(var(--space-lg) * 42.5));overflow-y:auto}.node-detail-modal__section{border:1px solid var(--border);border-radius:var(--radius-md);padding:var(--space-md)}.node-detail-modal__section h4{margin:0 0 var(--space-sm) 0}.node-detail-modal__section-header{display:flex;justify-content:space-between;align-items:center;gap:var(--space-sm);margin-bottom:var(--space-sm)}.node-detail-modal__grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-sm)}.node-detail-modal__field{display:flex;flex-direction:column;gap:var(--space-xs)}.node-detail-modal__field--full{grid-column:span 2}.node-detail-modal__field span{color:var(--text-muted);font-size:calc(var(--space-sm) + var(--space-xs))}.node-detail-modal__edit-actions{margin-top:var(--space-sm);display:flex;gap:var(--space-xs)}.node-detail-modal__project-list{margin:0;padding-left:var(--space-lg);display:flex;flex-direction:column;gap:var(--space-sm)}.node-detail-modal__project-item{display:flex;justify-content:space-between;align-items:center;gap:var(--space-sm)}.node-detail-modal__project-item code{color:var(--text-muted)}.node-detail-modal__empty{margin:0;color:var(--text-muted)}.node-detail-modal__health-row{display:flex;flex-wrap:wrap;gap:var(--space-md)}.node-detail-modal__actions{justify-content:space-between}.node-detail-modal__docker-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-sm);margin-top:var(--space-sm)}.node-detail-modal__textarea{min-height:calc(var(--space-2xl) * 2.25);resize:vertical;font-family:var(--font-mono)}.node-detail-modal__sync-status{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-sm);margin-bottom:var(--space-sm)}.node-detail-modal__sync-dot{width:calc(var(--space-sm) + var(--space-xs) / 2);height:calc(var(--space-sm) + var(--space-xs) / 2);border-radius:50%;flex-shrink:0}.node-detail-modal__sync-dot--synced{background:var(--color-success)}.node-detail-modal__sync-dot--diff,.node-detail-modal__sync-dot--pending{background:var(--color-warning)}.node-detail-modal__sync-dot--error{background:var(--color-error)}.node-detail-modal__sync-dot--never{background:var(--text-muted)}.node-detail-modal__sync-diff{color:var(--color-warning);font-size:calc(var(--space-sm) + var(--space-xs))}.node-detail-modal__sync-actions{display:flex;flex-wrap:wrap;gap:var(--space-sm);margin-top:var(--space-sm)}.node-detail-modal__sync-error{display:flex;align-items:center;justify-content:space-between;gap:var(--space-sm);margin-top:var(--space-sm);padding:var(--space-sm);background:color-mix(in srgb,var(--color-error) 10%,transparent);border:1px solid color-mix(in srgb,var(--color-error) 30%,transparent);border-radius:var(--radius-sm);color:var(--color-error);font-size:calc(var(--space-sm) + var(--space-xs))}.node-detail-modal__sync-error-dismiss{background:transparent;border:none;color:var(--color-error);cursor:pointer;padding:calc(var(--space-xs) / 2);display:flex;align-items:center;justify-content:center;border-radius:var(--radius-sm)}.node-detail-modal__sync-error-dismiss:hover{background:color-mix(in srgb,var(--color-error) 20%,transparent)}.node-detail-modal__sync-error-dismiss:focus-visible{outline:none;box-shadow:var(--focus-ring-strong);background:color-mix(in srgb,var(--color-error) 20%,transparent)}@media(max-width:768px){.node-detail-modal__grid,.node-detail-modal__docker-grid{grid-template-columns:1fr}.node-detail-modal__field--full{grid-column:span 1}}
@@ -1,11 +1,11 @@
1
- import{r as l,j as e}from"./vendor-react-K0fH_qHe.js";import{c as A,d_ as H,d$ as Q,e0 as Y,R as $,dS as y,J as Z,W as T,N as ee,V as se,cr as L,F as _,e1 as ae,e2 as te,e3 as D,X as ie}from"./index-B4StE1qN.js";import"./vendor-xterm-DzcZoU0P.js";/**
1
+ import{r as l,j as e}from"./vendor-react-K0fH_qHe.js";import{c as W,dW as H,dX as J,dY as Q,R as $,dO as y,M as V,a as T,b as ee,Y as se,cl as L,F as _,dZ as ae,d_ as te,d$ as D,X as ie}from"./index-Bv0TGzDH.js";import"./vendor-xterm-DzcZoU0P.js";/**
2
2
  * @license lucide-react v1.7.0 - ISC
3
3
  *
4
4
  * This source code is licensed under the ISC license.
5
5
  * See the LICENSE file in the root directory of this source tree.
6
- */const ne=[["path",{d:"M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z",key:"e79jfc"}],["circle",{cx:"13.5",cy:"6.5",r:".5",fill:"currentColor",key:"1okk4w"}],["circle",{cx:"17.5",cy:"10.5",r:".5",fill:"currentColor",key:"f64h9f"}],["circle",{cx:"6.5",cy:"12.5",r:".5",fill:"currentColor",key:"qy21gx"}],["circle",{cx:"8.5",cy:"7.5",r:".5",fill:"currentColor",key:"fotxhn"}]],M=A("palette",ne);/**
6
+ */const ne=[["path",{d:"M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z",key:"e79jfc"}],["circle",{cx:"13.5",cy:"6.5",r:".5",fill:"currentColor",key:"1okk4w"}],["circle",{cx:"17.5",cy:"10.5",r:".5",fill:"currentColor",key:"f64h9f"}],["circle",{cx:"6.5",cy:"12.5",r:".5",fill:"currentColor",key:"qy21gx"}],["circle",{cx:"8.5",cy:"7.5",r:".5",fill:"currentColor",key:"fotxhn"}]],M=W("palette",ne);/**
7
7
  * @license lucide-react v1.7.0 - ISC
8
8
  *
9
9
  * This source code is licensed under the ISC license.
10
10
  * See the LICENSE file in the root directory of this source tree.
11
- */const le=[["path",{d:"M15.39 4.39a1 1 0 0 0 1.68-.474 2.5 2.5 0 1 1 3.014 3.015 1 1 0 0 0-.474 1.68l1.683 1.682a2.414 2.414 0 0 1 0 3.414L19.61 15.39a1 1 0 0 1-1.68-.474 2.5 2.5 0 1 0-3.014 3.015 1 1 0 0 1 .474 1.68l-1.683 1.682a2.414 2.414 0 0 1-3.414 0L8.61 19.61a1 1 0 0 0-1.68.474 2.5 2.5 0 1 1-3.014-3.015 1 1 0 0 0 .474-1.68l-1.683-1.682a2.414 2.414 0 0 1 0-3.414L4.39 8.61a1 1 0 0 1 1.68.474 2.5 2.5 0 1 0 3.014-3.015 1 1 0 0 1-.474-1.68l1.683-1.682a2.414 2.414 0 0 1 3.414 0z",key:"w46dr5"}]],W=A("puzzle",le);function ce(t){return t.replace(/-/g,"-")}function re(t){return{"fusion-global":"Fusion Global","pi-global":"Pi Global","fusion-project":"Fusion Project","pi-project":"Pi Project",package:"Package"}[t]??t}function oe(t){return t.startsWith("npm:")?"npm":t.startsWith("git:")?"git":"local"}function de(t){return t.replace(/^(npm:|git:)/,"")}function he({addToast:t,projectId:x}){const[c,G]=l.useState(null),[f,P]=l.useState(!0),[N,S]=l.useState(!1),[E,w]=l.useState(!1),[h,F]=l.useState(""),[I,O]=l.useState(new Set),[p,q]=l.useState([]),[b,C]=l.useState(!0),[B,z]=l.useState(!1),r=l.useCallback(async()=>{try{P(!0);const s=await H();G(s)}catch(s){t(`Failed to load Pi settings: ${s instanceof Error?s.message:String(s)}`,"error")}finally{P(!1)}},[t]),m=l.useCallback(async()=>{try{C(!0);const s=await Q(x);q(s.extensions)}catch(s){t(`Failed to load extensions: ${s instanceof Error?s.message:String(s)}`,"error")}finally{C(!1)}},[t,x]),J=l.useCallback(async s=>{try{z(!0);const i=s.enabled?[...p.filter(a=>a.enabled&&a.id!==s.id).map(a=>a.id),s.id]:p.filter(a=>a.enabled&&a.id!==s.id).map(a=>a.id);await Y(i,x),await m(),t(s.enabled?"Extension disabled":"Extension enabled","success")}catch(i){t(`Failed to update extension: ${i instanceof Error?i.message:String(i)}`,"error")}finally{z(!1)}},[p,x,m,t]);l.useEffect(()=>{r()},[r]),l.useEffect(()=>{m()},[m]);const K=s=>{O(i=>{const a=new Set(i);return a.has(s)?a.delete(s):a.add(s),a})},R=async()=>{if(!h.trim()){t("Please enter a package source","error");return}try{S(!0),await ae(h.trim()),t("Package installed successfully","success"),F(""),await r()}catch(s){t(`Failed to install package: ${s instanceof Error?s.message:String(s)}`,"error")}finally{S(!1)}},U=async()=>{try{w(!0),await te(x),await Promise.all([r(),m()]),t("Fusion skill reinstalled successfully","success")}catch(s){t(`Failed to reinstall Fusion skill: ${s instanceof Error?s.message:String(s)}`,"error")}finally{w(!1)}},V=async s=>{if(!c)return;const i=c.packages.filter(a=>(typeof a=="string"?a:a.source)!==s);try{await D({packages:i}),t("Package removed","success"),await r()}catch(a){t(`Failed to remove package: ${a instanceof Error?a.message:String(a)}`,"error")}},X=async(s,i)=>{if(!c)return;const a=c[s].filter(n=>n!==i);try{await D({[s]:a}),t(`${s.slice(0,-1)} removed`,"success"),await r()}catch(n){t(`Failed to update settings: ${n instanceof Error?n.message:String(n)}`,"error")}},u=(s,i,a)=>!c||c[a].length===0?null:e.jsxs("div",{className:"pi-ext-section",children:[e.jsxs("div",{className:"pi-ext-section-header",children:[e.jsx(i,{size:14}),e.jsx("span",{children:s}),e.jsx("span",{className:"pi-ext-count",children:c[a].length})]}),e.jsx("div",{className:"pi-ext-resource-list",children:c[a].map((n,g)=>e.jsxs("span",{className:"pi-ext-resource-tag",children:[e.jsx("span",{className:"pi-ext-resource-path",children:n}),e.jsx("button",{className:"btn-icon touch-target pi-ext-resource-remove",onClick:()=>X(a,n),title:`Remove ${n}`,"aria-label":`Remove ${n}`,children:e.jsx(ie,{})})]},g))})]});return e.jsxs("div",{className:"pi-ext-manager",children:[e.jsxs("div",{className:"pi-ext-manager-header",children:[e.jsx("h4",{className:"pi-ext-manager-title",children:"Pi Extensions"}),e.jsx("div",{className:"pi-ext-manager-actions",children:e.jsx("button",{className:"btn-icon",onClick:r,title:"Refresh",disabled:f,children:e.jsx($,{size:16,className:f?"spin":""})})})]}),f?e.jsx("div",{className:"loading-state",children:"Loading Pi settings…"}):c?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"pi-ext-add-form",children:[e.jsxs("div",{className:"pi-ext-add-form-row",children:[e.jsx("input",{type:"text",className:"input",placeholder:"npm:pi-extension-name or git:https://github.com/...",value:h,onChange:s=>F(s.target.value),onKeyDown:s=>{s.key==="Enter"&&(s.preventDefault(),R())},disabled:N}),e.jsxs("button",{className:"btn btn-primary",onClick:R,disabled:N||!h.trim(),children:[e.jsx(Z,{size:14}),N?"Installing…":"Add"]})]}),e.jsx("div",{className:"pi-ext-add-form-row",children:e.jsx("button",{className:"btn",onClick:U,disabled:E,children:E?"Reinstalling Fusion…":"Reinstall Fusion skill"})})]}),c.packages.length>0?e.jsx("div",{className:"pi-ext-package-list",children:c.packages.map((s,i)=>{const a=typeof s=="string"?s:s.source,n=oe(a),g=de(a),j=typeof s=="object"&&s!==null,v=j&&(s.extensions?.length??0)>0||(s.skills?.length??0)>0||(s.prompts?.length??0)>0||(s.themes?.length??0)>0,k=I.has(i);return e.jsxs("div",{className:"pi-ext-package-card",children:[e.jsxs("div",{className:"pi-ext-package-header",children:[j&&v?e.jsx("button",{className:"pi-ext-expand-btn",onClick:()=>K(i),"aria-expanded":k,children:k?e.jsx(T,{size:14}):e.jsx(ee,{size:14})}):e.jsx("span",{className:"pi-ext-expand-placeholder"}),e.jsx("span",{className:`pi-ext-source-badge pi-ext-source-badge--${n}`,children:n}),e.jsx("span",{className:"pi-ext-package-source",children:g}),e.jsxs("div",{className:"pi-ext-package-actions",children:[j&&v&&e.jsxs("span",{className:"pi-ext-filter-hint",children:[s.extensions?.length??0," ext,"," ",s.skills?.length??0," skill,"," ",s.prompts?.length??0," prompt,"," ",s.themes?.length??0," theme"]}),e.jsx("button",{className:"btn-icon touch-target pi-ext-remove-btn",onClick:()=>V(a),title:"Remove package","aria-label":`Remove package ${g}`,children:e.jsx(se,{size:14})})]})]}),j&&v&&k&&e.jsxs("div",{className:"pi-ext-filter-list",children:[s.extensions?.length?e.jsxs("div",{className:"pi-ext-filter-section",children:[e.jsx(W,{size:12}),e.jsx("span",{className:"pi-ext-filter-label",children:"Extensions:"}),s.extensions.map((o,d)=>e.jsx("span",{className:"pi-ext-filter-tag",children:o},d))]}):null,s.skills?.length?e.jsxs("div",{className:"pi-ext-filter-section",children:[e.jsx(L,{size:12}),e.jsx("span",{className:"pi-ext-filter-label",children:"Skills:"}),s.skills.map((o,d)=>e.jsx("span",{className:"pi-ext-filter-tag",children:o},d))]}):null,s.prompts?.length?e.jsxs("div",{className:"pi-ext-filter-section",children:[e.jsx(_,{size:12}),e.jsx("span",{className:"pi-ext-filter-label",children:"Prompts:"}),s.prompts.map((o,d)=>e.jsx("span",{className:"pi-ext-filter-tag",children:o},d))]}):null,s.themes?.length?e.jsxs("div",{className:"pi-ext-filter-section",children:[e.jsx(M,{size:12}),e.jsx("span",{className:"pi-ext-filter-label",children:"Themes:"}),s.themes.map((o,d)=>e.jsx("span",{className:"pi-ext-filter-tag",children:o},d))]}):null]})]},i)})}):e.jsxs("div",{className:"empty-state",children:[e.jsx(y,{size:32,className:"text-muted"}),e.jsx("p",{children:"No packages configured."}),e.jsx("p",{className:"text-muted",children:"Add a package source above to get started."})]}),e.jsxs("div",{className:"pi-ext-top-level",children:[u("Extensions",W,"extensions"),u("Skills",L,"skills"),u("Prompts",_,"prompts"),u("Themes",M,"themes")]})]}):e.jsxs("div",{className:"empty-state",children:[e.jsx(y,{size:32,className:"text-muted"}),e.jsx("p",{children:"Failed to load Pi settings."})]}),e.jsxs("div",{className:"pi-ext-discovered-section",children:[e.jsxs("div",{className:"pi-ext-discovered-header",children:[e.jsx("h4",{children:"Discovered Extensions"}),e.jsx("button",{className:"btn-icon",onClick:m,disabled:b,title:"Refresh extensions",children:e.jsx($,{className:b?"spin":""})})]}),e.jsx("p",{className:"pi-ext-description",children:"Installed extensions resolved from packages and configured paths."}),b?e.jsx("div",{className:"loading-state",children:"Loading extensions…"}):p.length===0?e.jsxs("div",{className:"empty-state",children:[e.jsx(y,{size:32,className:"text-muted"}),e.jsx("p",{children:"No extensions discovered."})]}):e.jsx("div",{className:"pi-ext-list",children:p.map(s=>e.jsxs("div",{className:"pi-ext-item",children:[e.jsxs("div",{className:"pi-ext-item-content",children:[e.jsxs("div",{className:"pi-ext-info",children:[e.jsx("span",{className:"pi-ext-name",children:s.name}),e.jsx("span",{className:`pi-ext-source-badge pi-ext-source-badge--${ce(s.source)}`,children:re(s.source)})]}),e.jsx("span",{className:"pi-ext-path",children:s.path})]}),e.jsx("div",{className:"pi-ext-actions",children:e.jsxs("label",{className:"toggle-switch",children:[e.jsx("input",{type:"checkbox",checked:s.enabled,onChange:()=>void J(s),disabled:B,"aria-label":`Toggle ${s.name}`}),e.jsx("span",{className:"toggle-slider"})]})})]},s.id))})]})]})}export{he as PiExtensionsManager};
11
+ */const le=[["path",{d:"M15.39 4.39a1 1 0 0 0 1.68-.474 2.5 2.5 0 1 1 3.014 3.015 1 1 0 0 0-.474 1.68l1.683 1.682a2.414 2.414 0 0 1 0 3.414L19.61 15.39a1 1 0 0 1-1.68-.474 2.5 2.5 0 1 0-3.014 3.015 1 1 0 0 1 .474 1.68l-1.683 1.682a2.414 2.414 0 0 1-3.414 0L8.61 19.61a1 1 0 0 0-1.68.474 2.5 2.5 0 1 1-3.014-3.015 1 1 0 0 0 .474-1.68l-1.683-1.682a2.414 2.414 0 0 1 0-3.414L4.39 8.61a1 1 0 0 1 1.68.474 2.5 2.5 0 1 0 3.014-3.015 1 1 0 0 1-.474-1.68l1.683-1.682a2.414 2.414 0 0 1 3.414 0z",key:"w46dr5"}]],O=W("puzzle",le);function ce(t){return t.replace(/-/g,"-")}function re(t){return{"fusion-global":"Fusion Global","pi-global":"Pi Global","fusion-project":"Fusion Project","pi-project":"Pi Project",package:"Package"}[t]??t}function oe(t){return t.startsWith("npm:")?"npm":t.startsWith("git:")?"git":"local"}function de(t){return t.replace(/^(npm:|git:)/,"")}function he({addToast:t,projectId:x}){const[c,A]=l.useState(null),[f,P]=l.useState(!0),[N,S]=l.useState(!1),[E,w]=l.useState(!1),[h,F]=l.useState(""),[G,I]=l.useState(new Set),[p,X]=l.useState([]),[b,C]=l.useState(!0),[Y,z]=l.useState(!1),r=l.useCallback(async()=>{try{P(!0);const s=await H();A(s)}catch(s){t(`Failed to load Pi settings: ${s instanceof Error?s.message:String(s)}`,"error")}finally{P(!1)}},[t]),m=l.useCallback(async()=>{try{C(!0);const s=await J(x);X(s.extensions)}catch(s){t(`Failed to load extensions: ${s instanceof Error?s.message:String(s)}`,"error")}finally{C(!1)}},[t,x]),q=l.useCallback(async s=>{try{z(!0);const i=s.enabled?[...p.filter(a=>a.enabled&&a.id!==s.id).map(a=>a.id),s.id]:p.filter(a=>a.enabled&&a.id!==s.id).map(a=>a.id);await Q(i,x),await m(),t(s.enabled?"Extension disabled":"Extension enabled","success")}catch(i){t(`Failed to update extension: ${i instanceof Error?i.message:String(i)}`,"error")}finally{z(!1)}},[p,x,m,t]);l.useEffect(()=>{r()},[r]),l.useEffect(()=>{m()},[m]);const B=s=>{I(i=>{const a=new Set(i);return a.has(s)?a.delete(s):a.add(s),a})},R=async()=>{if(!h.trim()){t("Please enter a package source","error");return}try{S(!0),await ae(h.trim()),t("Package installed successfully","success"),F(""),await r()}catch(s){t(`Failed to install package: ${s instanceof Error?s.message:String(s)}`,"error")}finally{S(!1)}},K=async()=>{try{w(!0),await te(x),await Promise.all([r(),m()]),t("Fusion skill reinstalled successfully","success")}catch(s){t(`Failed to reinstall Fusion skill: ${s instanceof Error?s.message:String(s)}`,"error")}finally{w(!1)}},U=async s=>{if(!c)return;const i=c.packages.filter(a=>(typeof a=="string"?a:a.source)!==s);try{await D({packages:i}),t("Package removed","success"),await r()}catch(a){t(`Failed to remove package: ${a instanceof Error?a.message:String(a)}`,"error")}},Z=async(s,i)=>{if(!c)return;const a=c[s].filter(n=>n!==i);try{await D({[s]:a}),t(`${s.slice(0,-1)} removed`,"success"),await r()}catch(n){t(`Failed to update settings: ${n instanceof Error?n.message:String(n)}`,"error")}},u=(s,i,a)=>!c||c[a].length===0?null:e.jsxs("div",{className:"pi-ext-section",children:[e.jsxs("div",{className:"pi-ext-section-header",children:[e.jsx(i,{size:14}),e.jsx("span",{children:s}),e.jsx("span",{className:"pi-ext-count",children:c[a].length})]}),e.jsx("div",{className:"pi-ext-resource-list",children:c[a].map((n,g)=>e.jsxs("span",{className:"pi-ext-resource-tag",children:[e.jsx("span",{className:"pi-ext-resource-path",children:n}),e.jsx("button",{className:"btn-icon touch-target pi-ext-resource-remove",onClick:()=>Z(a,n),title:`Remove ${n}`,"aria-label":`Remove ${n}`,children:e.jsx(ie,{})})]},g))})]});return e.jsxs("div",{className:"pi-ext-manager",children:[e.jsxs("div",{className:"pi-ext-manager-header",children:[e.jsx("h4",{className:"pi-ext-manager-title",children:"Pi Extensions"}),e.jsx("div",{className:"pi-ext-manager-actions",children:e.jsx("button",{className:"btn-icon",onClick:r,title:"Refresh",disabled:f,children:e.jsx($,{size:16,className:f?"spin":""})})})]}),f?e.jsx("div",{className:"loading-state",children:"Loading Pi settings…"}):c?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"pi-ext-add-form",children:[e.jsxs("div",{className:"pi-ext-add-form-row",children:[e.jsx("input",{type:"text",className:"input",placeholder:"npm:pi-extension-name or git:https://github.com/...",value:h,onChange:s=>F(s.target.value),onKeyDown:s=>{s.key==="Enter"&&(s.preventDefault(),R())},disabled:N}),e.jsxs("button",{className:"btn btn-primary",onClick:R,disabled:N||!h.trim(),children:[e.jsx(V,{size:14}),N?"Installing…":"Add"]})]}),e.jsx("div",{className:"pi-ext-add-form-row",children:e.jsx("button",{className:"btn",onClick:K,disabled:E,children:E?"Reinstalling Fusion…":"Reinstall Fusion skill"})})]}),c.packages.length>0?e.jsx("div",{className:"pi-ext-package-list",children:c.packages.map((s,i)=>{const a=typeof s=="string"?s:s.source,n=oe(a),g=de(a),j=typeof s=="object"&&s!==null,v=j&&(s.extensions?.length??0)>0||(s.skills?.length??0)>0||(s.prompts?.length??0)>0||(s.themes?.length??0)>0,k=G.has(i);return e.jsxs("div",{className:"pi-ext-package-card",children:[e.jsxs("div",{className:"pi-ext-package-header",children:[j&&v?e.jsx("button",{className:"pi-ext-expand-btn",onClick:()=>B(i),"aria-expanded":k,children:k?e.jsx(T,{size:14}):e.jsx(ee,{size:14})}):e.jsx("span",{className:"pi-ext-expand-placeholder"}),e.jsx("span",{className:`pi-ext-source-badge pi-ext-source-badge--${n}`,children:n}),e.jsx("span",{className:"pi-ext-package-source",children:g}),e.jsxs("div",{className:"pi-ext-package-actions",children:[j&&v&&e.jsxs("span",{className:"pi-ext-filter-hint",children:[s.extensions?.length??0," ext,"," ",s.skills?.length??0," skill,"," ",s.prompts?.length??0," prompt,"," ",s.themes?.length??0," theme"]}),e.jsx("button",{className:"btn-icon touch-target pi-ext-remove-btn",onClick:()=>U(a),title:"Remove package","aria-label":`Remove package ${g}`,children:e.jsx(se,{size:14})})]})]}),j&&v&&k&&e.jsxs("div",{className:"pi-ext-filter-list",children:[s.extensions?.length?e.jsxs("div",{className:"pi-ext-filter-section",children:[e.jsx(O,{size:12}),e.jsx("span",{className:"pi-ext-filter-label",children:"Extensions:"}),s.extensions.map((o,d)=>e.jsx("span",{className:"pi-ext-filter-tag",children:o},d))]}):null,s.skills?.length?e.jsxs("div",{className:"pi-ext-filter-section",children:[e.jsx(L,{size:12}),e.jsx("span",{className:"pi-ext-filter-label",children:"Skills:"}),s.skills.map((o,d)=>e.jsx("span",{className:"pi-ext-filter-tag",children:o},d))]}):null,s.prompts?.length?e.jsxs("div",{className:"pi-ext-filter-section",children:[e.jsx(_,{size:12}),e.jsx("span",{className:"pi-ext-filter-label",children:"Prompts:"}),s.prompts.map((o,d)=>e.jsx("span",{className:"pi-ext-filter-tag",children:o},d))]}):null,s.themes?.length?e.jsxs("div",{className:"pi-ext-filter-section",children:[e.jsx(M,{size:12}),e.jsx("span",{className:"pi-ext-filter-label",children:"Themes:"}),s.themes.map((o,d)=>e.jsx("span",{className:"pi-ext-filter-tag",children:o},d))]}):null]})]},i)})}):e.jsxs("div",{className:"empty-state",children:[e.jsx(y,{size:32,className:"text-muted"}),e.jsx("p",{children:"No packages configured."}),e.jsx("p",{className:"text-muted",children:"Add a package source above to get started."})]}),e.jsxs("div",{className:"pi-ext-top-level",children:[u("Extensions",O,"extensions"),u("Skills",L,"skills"),u("Prompts",_,"prompts"),u("Themes",M,"themes")]})]}):e.jsxs("div",{className:"empty-state",children:[e.jsx(y,{size:32,className:"text-muted"}),e.jsx("p",{children:"Failed to load Pi settings."})]}),e.jsxs("div",{className:"pi-ext-discovered-section",children:[e.jsxs("div",{className:"pi-ext-discovered-header",children:[e.jsx("h4",{children:"Discovered Extensions"}),e.jsx("button",{className:"btn-icon",onClick:m,disabled:b,title:"Refresh extensions",children:e.jsx($,{className:b?"spin":""})})]}),e.jsx("p",{className:"pi-ext-description",children:"Installed extensions resolved from packages and configured paths."}),b?e.jsx("div",{className:"loading-state",children:"Loading extensions…"}):p.length===0?e.jsxs("div",{className:"empty-state",children:[e.jsx(y,{size:32,className:"text-muted"}),e.jsx("p",{children:"No extensions discovered."})]}):e.jsx("div",{className:"pi-ext-list",children:p.map(s=>e.jsxs("div",{className:"pi-ext-item",children:[e.jsxs("div",{className:"pi-ext-item-content",children:[e.jsxs("div",{className:"pi-ext-info",children:[e.jsx("span",{className:"pi-ext-name",children:s.name}),e.jsx("span",{className:`pi-ext-source-badge pi-ext-source-badge--${ce(s.source)}`,children:re(s.source)})]}),e.jsx("span",{className:"pi-ext-path",children:s.path})]}),e.jsx("div",{className:"pi-ext-actions",children:e.jsxs("label",{className:"toggle-switch",children:[e.jsx("input",{type:"checkbox",checked:s.enabled,onChange:()=>void q(s),disabled:Y,"aria-label":`Toggle ${s.name}`}),e.jsx("span",{className:"toggle-slider"})]})})]},s.id))})]})]})}export{he as PiExtensionsManager};
@@ -1 +1 @@
1
- import{r as o,j as s}from"./vendor-react-K0fH_qHe.js";import{w as T,dQ as ee,s as se,X as A,an as ne,J as O,dR as V,V as M,R as te,dS as ie,aF as ae,ch as le,dT as re,dU as ce,dV as de,dW as ue,dX as _,ce as oe}from"./index-B4StE1qN.js";import{D as me}from"./DirectoryPicker-DPfkGnj5.js";import"./vendor-xterm-DzcZoU0P.js";import"./folder-open-CKivQd8c.js";const ge=[{id:"fusion-plugin-agent-browser-runtime",name:"Agent Browser Runtime",path:"./plugins/fusion-plugin-agent-browser-runtime",experimental:!0},{id:"fusion-plugin-hermes-runtime",name:"Hermes Runtime",path:"./plugins/fusion-plugin-hermes-runtime",experimental:!0},{id:"fusion-plugin-paperclip-runtime",name:"Paperclip Runtime",path:"./plugins/fusion-plugin-paperclip-runtime"},{id:"fusion-plugin-openclaw-runtime",name:"OpenClaw Runtime",path:"./plugins/fusion-plugin-openclaw-runtime",experimental:!0}],N={started:"var(--color-success)",loaded:"var(--color-warning)",error:"var(--color-error)",stopped:"var(--color-muted)",installed:"var(--color-info)"};function fe({addToast:l,projectId:c}){const[x,b]=o.useState([]),[S,w]=o.useState(!0),[H,f]=o.useState(!1),[j,v]=o.useState(""),[C,P]=o.useState(!1),[h,R]=o.useState(null),[i,y]=o.useState(null),[a,p]=o.useState({}),[J,$]=o.useState(!1),[I,E]=o.useState(null),{confirm:X}=T(),m=o.useCallback(async()=>{try{w(!0);const e=await ee(c);b(e)}catch(e){l(`Failed to load plugins: ${e instanceof Error?e.message:String(e)}`,"error")}finally{w(!1)}},[c,l]);o.useEffect(()=>{m()},[m]);const G=o.useRef([]);G.current=x,o.useEffect(()=>{const e=c?`?projectId=${encodeURIComponent(c)}`:"",n=d=>{try{const t=JSON.parse(d.data);if(c&&t.projectId&&t.projectId!==c)return;switch(t.transition){case"installing":case"enabled":case"disabled":case"settings-updated":b(u=>{const g=u.findIndex(r=>r.id===t.pluginId);if(g>=0){const r=[...u];return r[g]={...r[g],enabled:t.enabled,state:t.state,settings:t.settings,error:t.error},r}else return m(),u});break;case"uninstalled":b(u=>u.filter(g=>g.id!==t.pluginId));break;case"error":b(u=>{const g=u.findIndex(r=>r.id===t.pluginId);if(g>=0){const r=[...u];return r[g]={...r[g],state:t.state,error:t.error},r}return u});break}}catch{}};return se(`/api/events${e}`,{events:{"plugin:lifecycle":n},onReconnect:()=>{m()}})},[c,m]);const z=async()=>{if(!j.trim()){l("Please enter a plugin path","error");return}try{P(!0),await _({path:j},c),l("Plugin installed successfully","success"),f(!1),v(""),await m()}catch(e){l(`Failed to install plugin: ${e instanceof Error?e.message:String(e)}`,"error")}finally{P(!1)}},K=async e=>{try{E(e.id),await _({path:e.path},c),l(`${e.name} installed successfully`,"success"),await m()}catch(n){l(`Failed to install ${e.name}: ${n instanceof Error?n.message:String(n)}`,"error")}finally{E(null)}},B=async e=>{try{await de(e.id,c),l(`${e.name} enabled`,"success"),await m()}catch(n){l(`Failed to enable plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},F=async e=>{try{await ce(e.id,c),l(`${e.name} disabled`,"success"),await m()}catch(n){l(`Failed to disable plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},U=async e=>{try{R(e.id),await re(e.id,c),l(`${e.name} reloaded`,"success"),await m()}catch(n){l(`Failed to reload plugin: ${n instanceof Error?n.message:String(n)}`,"error")}finally{R(null)}},L=async e=>{if(await X({title:"Uninstall Plugin",message:`Are you sure you want to uninstall "${e.name}"?`,danger:!0}))try{await ue(e.id,c),l(`${e.name} uninstalled`,"success"),await m(),y(null)}catch(d){l(`Failed to uninstall plugin: ${d instanceof Error?d.message:String(d)}`,"error")}},q=async e=>{y(e);try{$(!0);const n=await oe(e.id,c);p(n)}catch{p({})}finally{$(!1)}},Q=async()=>{if(i)try{await le(i.id,a,c),l("Settings saved","success")}catch(e){l(`Failed to save settings: ${e instanceof Error?e.message:String(e)}`,"error")}};if(i)return s.jsxs("div",{className:"plugin-manager-detail","data-testid":"plugin-manager-detail",children:[s.jsxs("div",{className:"plugin-manager-detail-header",children:[s.jsx("button",{className:"btn-icon",onClick:()=>y(null),"aria-label":"Back to plugin list",children:s.jsx(A,{size:16})}),s.jsxs("div",{className:"plugin-detail-title",children:[s.jsx("h4",{className:"plugin-detail-name",children:i.name}),s.jsx("span",{className:"plugin-state-badge",style:{color:N[i.state]||N.installed},children:i.state})]})]}),s.jsxs("div",{className:"plugin-detail-content",children:[s.jsxs("div",{className:"plugin-detail-card",children:[i.description&&s.jsx("p",{className:"plugin-description",children:i.description}),i.author&&s.jsxs("p",{className:"plugin-detail-meta-row",children:[s.jsx("span",{className:"text-muted",children:"Author:"}),i.author]}),i.homepage&&s.jsxs("p",{className:"plugin-detail-meta-row plugin-homepage",children:[s.jsx("span",{className:"text-muted",children:"Homepage:"}),s.jsxs("a",{href:i.homepage,target:"_blank",rel:"noopener noreferrer",children:[i.homepage,s.jsx(ne,{size:12})]})]}),s.jsxs("p",{className:"plugin-detail-meta-row",children:[s.jsx("span",{className:"text-muted",children:"Version:"}),i.version]})]}),s.jsxs("div",{className:"plugin-detail-card",children:[s.jsx("h5",{className:"plugin-detail-section-heading",children:"Settings"}),J?s.jsx("p",{className:"text-muted",children:"Loading..."}):i.settingsSchema&&Object.keys(i.settingsSchema).length>0?s.jsxs("div",{className:"plugin-settings-form",children:[Object.entries(i.settingsSchema).map(([e,n])=>{const d=`setting-${e}-help`;return s.jsxs("div",{className:"form-group",children:[s.jsxs("label",{htmlFor:`setting-${e}`,children:[n.label||e,n.required&&" *"]}),n.type==="string"&&!n.multiline&&s.jsx("input",{className:"input",type:"text",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),placeholder:n.description,"aria-describedby":n.description&&!n.required?d:void 0}),n.type==="string"&&n.multiline&&s.jsx("textarea",{className:"input",id:`setting-${e}`,rows:4,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),placeholder:n.description,"aria-describedby":n.description&&!n.required?d:void 0}),n.type==="password"&&s.jsx("input",{className:"input",type:"password",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),placeholder:n.description,"aria-describedby":n.description&&!n.required?d:void 0}),n.type==="number"&&s.jsx("input",{className:"input",type:"number",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:Number(t.target.value)}),"aria-describedby":n.description&&!n.required?d:void 0}),n.type==="boolean"&&s.jsxs("label",{className:"checkbox-label",children:[s.jsx("input",{type:"checkbox",checked:a[e]??!1,onChange:t=>p({...a,[e]:t.target.checked})}),n.description]}),n.type==="enum"&&s.jsxs("select",{className:"select",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),"aria-describedby":n.description&&!n.required?d:void 0,children:[s.jsx("option",{value:"",children:"Select..."}),n.enumValues?.map(t=>s.jsx("option",{value:t,children:t},t))]}),n.type==="array"&&s.jsxs("div",{className:"plugin-settings-array",children:[a[e]?.map((t,u)=>s.jsxs("div",{className:"plugin-settings-array-item",children:[s.jsx("input",{className:"input",type:n.itemType==="number"?"number":"text",value:t??"",onChange:g=>{const r=g.target.value,k=[...a[e]||[]];k[u]=n.itemType==="number"?Number(r):r,p({...a,[e]:k})}}),s.jsx("button",{className:"btn-icon",onClick:()=>{const r=[...a[e]||[]];r.splice(u,1),p({...a,[e]:r})},"aria-label":"Remove item",children:s.jsx(A,{size:14})})]},u)),s.jsxs("button",{className:"btn btn-secondary",onClick:()=>{const t=a[e]||[],u=n.itemType==="number"?0:"";p({...a,[e]:[...t,u]})},children:[s.jsx(O,{size:14})," Add Item"]})]}),n.description&&!n.required&&!n.multiline&&s.jsx("span",{id:d,className:"form-help",children:n.description})]},e)}),s.jsx("button",{className:"btn btn-primary",onClick:Q,children:"Save Settings"})]}):s.jsx("p",{className:"text-muted",children:"No configurable settings."})]}),s.jsxs("div",{className:"plugin-detail-actions",children:[i.state==="started"&&s.jsxs("button",{className:"btn btn-secondary",onClick:()=>U(i),disabled:h===i.id,children:[s.jsx(V,{size:14,className:h===i.id?"spin":""}),h===i.id?"Reloading...":"Reload"]}),i.enabled?s.jsx("button",{className:"btn btn-secondary",onClick:()=>F(i),children:"Disable"}):s.jsx("button",{className:"btn btn-primary",onClick:()=>B(i),children:"Enable"}),s.jsxs("button",{className:"btn btn-danger",onClick:()=>L(i),children:[s.jsx(M,{size:14})," Uninstall"]})]})]})]});const W=new Set(x.map(e=>e.id)),Y=new Map(x.map(e=>[e.id,e])),D=x,Z=()=>s.jsxs("section",{className:"plugin-bundled-runtime-section","aria-label":"Bundled Runtime Plugins",children:[s.jsxs("div",{className:"plugin-bundled-runtime-header",children:[s.jsx("h4",{className:"plugin-bundled-runtime-heading",children:"Bundled Runtime Plugins"}),s.jsx("p",{className:"plugin-bundled-runtime-description",children:"Install Fusion's bundled runtimes directly from this screen."})]}),s.jsx("div",{className:"plugin-bundled-runtime-list","aria-label":"Bundled runtime plugin recommendations",children:ge.map(e=>{const n=W.has(e.id);return s.jsxs("div",{className:"plugin-bundled-runtime-item",children:[s.jsxs("div",{className:"plugin-bundled-runtime-meta",children:[s.jsx("span",{className:"plugin-bundled-runtime-name",children:e.name}),e.experimental&&s.jsx("span",{className:"plugin-bundled-runtime-badge",children:"Experimental"}),s.jsx("span",{className:`plugin-bundled-runtime-status ${n?"plugin-bundled-runtime-status--installed":"plugin-bundled-runtime-status--available"}`,children:n?"Installed":"Not installed"})]}),s.jsx("button",{className:`btn ${n?"btn-secondary":"btn-primary"} btn-sm`,onClick:()=>{if(n){const d=Y.get(e.id);d&&q(d);return}K(e)},disabled:I===e.id,children:n?"Manage":I===e.id?"Installing...":`Install ${e.name}`})]},e.id)})})]});return s.jsxs("div",{className:"plugin-manager","data-testid":"plugin-manager",children:[s.jsxs("div",{className:"plugin-manager-header",children:[s.jsx("span",{className:"plugin-manager-header-title",children:"Installed Plugins"}),s.jsxs("div",{className:"plugin-manager-actions",children:[s.jsxs("button",{className:"btn btn-sm btn-ghost",onClick:m,title:"Refresh","aria-label":"Refresh plugin list",children:[s.jsx(te,{size:14,className:S?"spin":""}),"Refresh"]}),s.jsxs("button",{className:"btn btn-primary btn-sm",onClick:()=>f(!0),children:[s.jsx(O,{size:14})," Install"]})]})]}),H&&s.jsxs("div",{className:"plugin-install-form",children:[s.jsxs("p",{className:"plugin-install-hint",children:["Browse to a plugin package root (contains ",s.jsx("code",{children:"manifest.json"}),") or a built ",s.jsx("code",{children:"dist"})," directory."]}),s.jsx(me,{value:j,onChange:v,placeholder:"Absolute path to plugin directory or dist folder",onInputKeyDown:e=>{e.key==="Enter"&&(e.preventDefault(),z())}}),s.jsxs("div",{className:"plugin-install-actions",children:[s.jsx("button",{className:"btn btn-primary",onClick:z,disabled:C||!j.trim(),children:C?"Installing...":"Install Plugin"}),s.jsx("button",{className:"btn btn-secondary",onClick:()=>{f(!1),v("")},children:"Cancel"})]})]}),S?s.jsx("div",{className:"settings-empty-state",children:"Loading plugins..."}):s.jsxs(s.Fragment,{children:[D.length===0?s.jsxs("div",{className:"settings-empty-state",children:[s.jsx(ie,{size:32,className:"text-muted"}),s.jsx("p",{children:"No plugins installed."}),s.jsx("p",{className:"text-muted",children:"Install a plugin to get started, or use a bundled runtime below."})]}):s.jsx("div",{className:"plugin-list",children:D.map(e=>s.jsxs("div",{className:"plugin-item",children:[s.jsxs("div",{className:"plugin-info",children:[s.jsx("span",{className:"plugin-name",children:e.name}),s.jsxs("span",{className:"plugin-version text-muted",children:["v",e.version]}),s.jsx("span",{className:"plugin-state-badge",style:{color:N[e.state]||N.installed},children:e.state})]}),s.jsxs("div",{className:"plugin-actions",children:[e.state==="started"&&s.jsx("button",{className:"btn-icon",onClick:()=>U(e),disabled:h===e.id,title:"Reload",children:s.jsx(V,{size:14,className:h===e.id?"spin":""})}),s.jsxs("label",{className:"toggle-switch",children:[s.jsx("input",{type:"checkbox",checked:e.enabled,onChange:()=>e.enabled?F(e):B(e)}),s.jsx("span",{className:"toggle-slider"})]}),s.jsx("button",{className:"btn-icon",onClick:()=>q(e),title:"Settings",children:s.jsx(ae,{size:14})}),s.jsx("button",{className:"btn-icon",onClick:()=>L(e),title:"Uninstall",children:s.jsx(M,{size:14})})]})]},e.id))}),Z()]})]})}export{fe as PluginManager,N as STATE_COLORS};
1
+ import{r as o,j as s}from"./vendor-react-K0fH_qHe.js";import{y as T,dM as ee,s as se,X as O,ap as ne,M as A,dN as M,Y as _,R as te,dO as ie,aI as ae,cb as le,dP as re,dQ as ce,dR as de,dS as ue,dT as V,c8 as oe}from"./index-Bv0TGzDH.js";import{D as me}from"./DirectoryPicker-BZWVA9ND.js";import"./vendor-xterm-DzcZoU0P.js";import"./folder-open-WVtgE4k3.js";const ge=[{id:"fusion-plugin-agent-browser-runtime",name:"Agent Browser Runtime",path:"./plugins/fusion-plugin-agent-browser-runtime",experimental:!0},{id:"fusion-plugin-hermes-runtime",name:"Hermes Runtime",path:"./plugins/fusion-plugin-hermes-runtime",experimental:!0},{id:"fusion-plugin-paperclip-runtime",name:"Paperclip Runtime",path:"./plugins/fusion-plugin-paperclip-runtime"},{id:"fusion-plugin-openclaw-runtime",name:"OpenClaw Runtime",path:"./plugins/fusion-plugin-openclaw-runtime",experimental:!0}],N={started:"var(--color-success)",loaded:"var(--color-warning)",error:"var(--color-error)",stopped:"var(--color-muted)",installed:"var(--color-info)"};function fe({addToast:l,projectId:c}){const[x,b]=o.useState([]),[S,w]=o.useState(!0),[H,f]=o.useState(!1),[j,v]=o.useState(""),[C,P]=o.useState(!1),[h,R]=o.useState(null),[i,y]=o.useState(null),[a,p]=o.useState({}),[G,I]=o.useState(!1),[$,E]=o.useState(null),{confirm:J}=T(),m=o.useCallback(async()=>{try{w(!0);const e=await ee(c);b(e)}catch(e){l(`Failed to load plugins: ${e instanceof Error?e.message:String(e)}`,"error")}finally{w(!1)}},[c,l]);o.useEffect(()=>{m()},[m]);const K=o.useRef([]);K.current=x,o.useEffect(()=>{const e=c?`?projectId=${encodeURIComponent(c)}`:"",n=d=>{try{const t=JSON.parse(d.data);if(c&&t.projectId&&t.projectId!==c)return;switch(t.transition){case"installing":case"enabled":case"disabled":case"settings-updated":b(u=>{const g=u.findIndex(r=>r.id===t.pluginId);if(g>=0){const r=[...u];return r[g]={...r[g],enabled:t.enabled,state:t.state,settings:t.settings,error:t.error},r}else return m(),u});break;case"uninstalled":b(u=>u.filter(g=>g.id!==t.pluginId));break;case"error":b(u=>{const g=u.findIndex(r=>r.id===t.pluginId);if(g>=0){const r=[...u];return r[g]={...r[g],state:t.state,error:t.error},r}return u});break}}catch{}};return se(`/api/events${e}`,{events:{"plugin:lifecycle":n},onReconnect:()=>{m()}})},[c,m]);const z=async()=>{if(!j.trim()){l("Please enter a plugin path","error");return}try{P(!0),await V({path:j},c),l("Plugin installed successfully","success"),f(!1),v(""),await m()}catch(e){l(`Failed to install plugin: ${e instanceof Error?e.message:String(e)}`,"error")}finally{P(!1)}},Q=async e=>{try{E(e.id),await V({path:e.path},c),l(`${e.name} installed successfully`,"success"),await m()}catch(n){l(`Failed to install ${e.name}: ${n instanceof Error?n.message:String(n)}`,"error")}finally{E(null)}},B=async e=>{try{await de(e.id,c),l(`${e.name} enabled`,"success"),await m()}catch(n){l(`Failed to enable plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},F=async e=>{try{await ce(e.id,c),l(`${e.name} disabled`,"success"),await m()}catch(n){l(`Failed to disable plugin: ${n instanceof Error?n.message:String(n)}`,"error")}},L=async e=>{try{R(e.id),await re(e.id,c),l(`${e.name} reloaded`,"success"),await m()}catch(n){l(`Failed to reload plugin: ${n instanceof Error?n.message:String(n)}`,"error")}finally{R(null)}},U=async e=>{if(await J({title:"Uninstall Plugin",message:`Are you sure you want to uninstall "${e.name}"?`,danger:!0}))try{await ue(e.id,c),l(`${e.name} uninstalled`,"success"),await m(),y(null)}catch(d){l(`Failed to uninstall plugin: ${d instanceof Error?d.message:String(d)}`,"error")}},q=async e=>{y(e);try{I(!0);const n=await oe(e.id,c);p(n)}catch{p({})}finally{I(!1)}},X=async()=>{if(i)try{await le(i.id,a,c),l("Settings saved","success")}catch(e){l(`Failed to save settings: ${e instanceof Error?e.message:String(e)}`,"error")}};if(i)return s.jsxs("div",{className:"plugin-manager-detail","data-testid":"plugin-manager-detail",children:[s.jsxs("div",{className:"plugin-manager-detail-header",children:[s.jsx("button",{className:"btn-icon",onClick:()=>y(null),"aria-label":"Back to plugin list",children:s.jsx(O,{size:16})}),s.jsxs("div",{className:"plugin-detail-title",children:[s.jsx("h4",{className:"plugin-detail-name",children:i.name}),s.jsx("span",{className:"plugin-state-badge",style:{color:N[i.state]||N.installed},children:i.state})]})]}),s.jsxs("div",{className:"plugin-detail-content",children:[s.jsxs("div",{className:"plugin-detail-card",children:[i.description&&s.jsx("p",{className:"plugin-description",children:i.description}),i.author&&s.jsxs("p",{className:"plugin-detail-meta-row",children:[s.jsx("span",{className:"text-muted",children:"Author:"}),i.author]}),i.homepage&&s.jsxs("p",{className:"plugin-detail-meta-row plugin-homepage",children:[s.jsx("span",{className:"text-muted",children:"Homepage:"}),s.jsxs("a",{href:i.homepage,target:"_blank",rel:"noopener noreferrer",children:[i.homepage,s.jsx(ne,{size:12})]})]}),s.jsxs("p",{className:"plugin-detail-meta-row",children:[s.jsx("span",{className:"text-muted",children:"Version:"}),i.version]})]}),s.jsxs("div",{className:"plugin-detail-card",children:[s.jsx("h5",{className:"plugin-detail-section-heading",children:"Settings"}),G?s.jsx("p",{className:"text-muted",children:"Loading..."}):i.settingsSchema&&Object.keys(i.settingsSchema).length>0?s.jsxs("div",{className:"plugin-settings-form",children:[Object.entries(i.settingsSchema).map(([e,n])=>{const d=`setting-${e}-help`;return s.jsxs("div",{className:"form-group",children:[s.jsxs("label",{htmlFor:`setting-${e}`,children:[n.label||e,n.required&&" *"]}),n.type==="string"&&!n.multiline&&s.jsx("input",{className:"input",type:"text",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),placeholder:n.description,"aria-describedby":n.description&&!n.required?d:void 0}),n.type==="string"&&n.multiline&&s.jsx("textarea",{className:"input",id:`setting-${e}`,rows:4,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),placeholder:n.description,"aria-describedby":n.description&&!n.required?d:void 0}),n.type==="password"&&s.jsx("input",{className:"input",type:"password",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),placeholder:n.description,"aria-describedby":n.description&&!n.required?d:void 0}),n.type==="number"&&s.jsx("input",{className:"input",type:"number",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:Number(t.target.value)}),"aria-describedby":n.description&&!n.required?d:void 0}),n.type==="boolean"&&s.jsxs("label",{className:"checkbox-label",children:[s.jsx("input",{type:"checkbox",checked:a[e]??!1,onChange:t=>p({...a,[e]:t.target.checked})}),n.description]}),n.type==="enum"&&s.jsxs("select",{className:"select",id:`setting-${e}`,value:a[e]??"",onChange:t=>p({...a,[e]:t.target.value}),"aria-describedby":n.description&&!n.required?d:void 0,children:[s.jsx("option",{value:"",children:"Select..."}),n.enumValues?.map(t=>s.jsx("option",{value:t,children:t},t))]}),n.type==="array"&&s.jsxs("div",{className:"plugin-settings-array",children:[a[e]?.map((t,u)=>s.jsxs("div",{className:"plugin-settings-array-item",children:[s.jsx("input",{className:"input",type:n.itemType==="number"?"number":"text",value:t??"",onChange:g=>{const r=g.target.value,k=[...a[e]||[]];k[u]=n.itemType==="number"?Number(r):r,p({...a,[e]:k})}}),s.jsx("button",{className:"btn-icon",onClick:()=>{const r=[...a[e]||[]];r.splice(u,1),p({...a,[e]:r})},"aria-label":"Remove item",children:s.jsx(O,{size:14})})]},u)),s.jsxs("button",{className:"btn btn-secondary",onClick:()=>{const t=a[e]||[],u=n.itemType==="number"?0:"";p({...a,[e]:[...t,u]})},children:[s.jsx(A,{size:14})," Add Item"]})]}),n.description&&!n.required&&!n.multiline&&s.jsx("span",{id:d,className:"form-help",children:n.description})]},e)}),s.jsx("button",{className:"btn btn-primary",onClick:X,children:"Save Settings"})]}):s.jsx("p",{className:"text-muted",children:"No configurable settings."})]}),s.jsxs("div",{className:"plugin-detail-actions",children:[i.state==="started"&&s.jsxs("button",{className:"btn btn-secondary",onClick:()=>L(i),disabled:h===i.id,children:[s.jsx(M,{size:14,className:h===i.id?"spin":""}),h===i.id?"Reloading...":"Reload"]}),i.enabled?s.jsx("button",{className:"btn btn-secondary",onClick:()=>F(i),children:"Disable"}):s.jsx("button",{className:"btn btn-primary",onClick:()=>B(i),children:"Enable"}),s.jsxs("button",{className:"btn btn-danger",onClick:()=>U(i),children:[s.jsx(_,{size:14})," Uninstall"]})]})]})]});const Y=new Set(x.map(e=>e.id)),W=new Map(x.map(e=>[e.id,e])),D=x,Z=()=>s.jsxs("section",{className:"plugin-bundled-runtime-section","aria-label":"Bundled Runtime Plugins",children:[s.jsxs("div",{className:"plugin-bundled-runtime-header",children:[s.jsx("h4",{className:"plugin-bundled-runtime-heading",children:"Bundled Runtime Plugins"}),s.jsx("p",{className:"plugin-bundled-runtime-description",children:"Install Fusion's bundled runtimes directly from this screen."})]}),s.jsx("div",{className:"plugin-bundled-runtime-list","aria-label":"Bundled runtime plugin recommendations",children:ge.map(e=>{const n=Y.has(e.id);return s.jsxs("div",{className:"plugin-bundled-runtime-item",children:[s.jsxs("div",{className:"plugin-bundled-runtime-meta",children:[s.jsx("span",{className:"plugin-bundled-runtime-name",children:e.name}),e.experimental&&s.jsx("span",{className:"plugin-bundled-runtime-badge",children:"Experimental"}),s.jsx("span",{className:`plugin-bundled-runtime-status ${n?"plugin-bundled-runtime-status--installed":"plugin-bundled-runtime-status--available"}`,children:n?"Installed":"Not installed"})]}),s.jsx("button",{className:`btn ${n?"btn-secondary":"btn-primary"} btn-sm`,onClick:()=>{if(n){const d=W.get(e.id);d&&q(d);return}Q(e)},disabled:$===e.id,children:n?"Manage":$===e.id?"Installing...":`Install ${e.name}`})]},e.id)})})]});return s.jsxs("div",{className:"plugin-manager","data-testid":"plugin-manager",children:[s.jsxs("div",{className:"plugin-manager-header",children:[s.jsx("span",{className:"plugin-manager-header-title",children:"Installed Plugins"}),s.jsxs("div",{className:"plugin-manager-actions",children:[s.jsxs("button",{className:"btn btn-sm",onClick:m,title:"Refresh","aria-label":"Refresh plugin list",children:[s.jsx(te,{size:14,className:S?"spin":""}),"Refresh"]}),s.jsxs("button",{className:"btn btn-primary btn-sm",onClick:()=>f(!0),children:[s.jsx(A,{size:14})," Install"]})]})]}),H&&s.jsxs("div",{className:"plugin-install-form",children:[s.jsxs("p",{className:"plugin-install-hint",children:["Browse to a plugin package root (contains ",s.jsx("code",{children:"manifest.json"}),") or a built ",s.jsx("code",{children:"dist"})," directory."]}),s.jsx(me,{value:j,onChange:v,placeholder:"Absolute path to plugin directory or dist folder",onInputKeyDown:e=>{e.key==="Enter"&&(e.preventDefault(),z())}}),s.jsxs("div",{className:"plugin-install-actions",children:[s.jsx("button",{className:"btn btn-primary",onClick:z,disabled:C||!j.trim(),children:C?"Installing...":"Install Plugin"}),s.jsx("button",{className:"btn btn-secondary",onClick:()=>{f(!1),v("")},children:"Cancel"})]})]}),S?s.jsx("div",{className:"settings-empty-state",children:"Loading plugins..."}):s.jsxs(s.Fragment,{children:[D.length===0?s.jsxs("div",{className:"settings-empty-state",children:[s.jsx(ie,{size:32,className:"text-muted"}),s.jsx("p",{children:"No plugins installed."}),s.jsx("p",{className:"text-muted",children:"Install a plugin to get started, or use a bundled runtime below."})]}):s.jsx("div",{className:"plugin-list",children:D.map(e=>s.jsxs("div",{className:"plugin-item",children:[s.jsxs("div",{className:"plugin-info",children:[s.jsx("span",{className:"plugin-name",children:e.name}),s.jsxs("span",{className:"plugin-version text-muted",children:["v",e.version]}),s.jsx("span",{className:"plugin-state-badge",style:{color:N[e.state]||N.installed},children:e.state})]}),s.jsxs("div",{className:"plugin-actions",children:[e.state==="started"&&s.jsx("button",{className:"btn-icon",onClick:()=>L(e),disabled:h===e.id,title:"Reload",children:s.jsx(M,{size:14,className:h===e.id?"spin":""})}),s.jsxs("label",{className:"toggle-switch",children:[s.jsx("input",{type:"checkbox",checked:e.enabled,onChange:()=>e.enabled?F(e):B(e)}),s.jsx("span",{className:"toggle-slider"})]}),s.jsx("button",{className:"btn-icon",onClick:()=>q(e),title:"Settings",children:s.jsx(ae,{size:14})}),s.jsx("button",{className:"btn-icon",onClick:()=>U(e),title:"Uninstall",children:s.jsx(_,{size:14})})]})]},e.id))}),Z()]})]})}export{fe as PluginManager,N as STATE_COLORS};
@@ -0,0 +1 @@
1
+ .research-task-action-modal__body{display:flex;flex-direction:column;gap:var(--space-md)}.research-task-action-modal__preview{display:flex;flex-direction:column;gap:var(--space-xs);padding:var(--space-md)}.research-task-action-modal__preview p{margin:0}.research-task-action-modal__field{display:flex;flex-direction:column;gap:var(--space-xs);color:var(--text-muted);text-transform:uppercase}.research-task-action-modal__textarea{min-height:calc(var(--space-2xl) * 2);resize:vertical}@media(max-width:768px){.research-task-action-modal{width:min(100%,calc(100vw - (var(--space-md) * 2)))}.research-task-action-modal__body{gap:var(--space-lg)}.research-task-action-modal__preview{padding:var(--space-lg)}.research-task-action-modal .modal-actions{flex-direction:column;align-items:stretch;gap:var(--space-sm)}.research-task-action-modal .modal-actions .btn{min-height:calc(var(--space-lg) * 2 + var(--space-xs))}}.research-view{display:flex;flex-direction:column;gap:var(--space-md);height:100%;min-height:0;padding:var(--space-lg);padding-bottom:var(--space-lg)}.research-view__header{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--space-md)}.research-view__title{margin:0}.research-view__subtitle{margin:var(--space-xs) 0 0;color:var(--text-muted)}.research-view__layout{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,2fr);gap:var(--space-md);min-height:0;flex:1}.research-view__sidebar,.research-view__reader{padding:var(--space-md);display:flex;flex-direction:column;gap:var(--space-md);min-height:0}.research-view__form{display:flex;flex-direction:column;gap:var(--space-sm)}.research-view__form .form-group,.research-view__history-header.form-group,.research-view__actions .form-group{margin:0;padding:0}.research-view__textarea{min-height:calc(var(--space-2xl) * 3);resize:vertical}.research-view__providers{display:grid;gap:var(--space-xs)}.research-view__history-header{display:flex;flex-direction:column;align-items:stretch;gap:var(--space-xs)}.research-view__history-search-row{display:flex;align-items:center;gap:var(--space-xs)}.research-view__history-search-row .input{flex:1;min-width:0}.research-view__history{display:flex;flex-direction:column;gap:var(--space-xs);flex:1;min-height:0;overflow:auto}.research-view__history-item{text-align:left;padding:var(--space-sm);min-height:calc(var(--space-lg) * 2 + var(--space-xs));display:flex;flex-direction:column;justify-content:center;gap:var(--space-xs);cursor:pointer}.research-view__history-item--active{border-color:var(--todo);box-shadow:var(--focus-ring)}.research-view__status-row{display:flex;align-items:center;gap:var(--space-xs);text-transform:capitalize}.research-view__run-title,.research-view__run-query,.research-view__run-summary{margin:0}.research-view__run-query{color:var(--text-muted)}.research-view__actions{display:flex;flex-wrap:wrap;gap:var(--space-xs);margin-top:var(--space-sm)}.research-view__citations{margin:var(--space-sm) 0 0;padding-left:var(--space-lg);display:flex;flex-direction:column;gap:var(--space-xs)}.research-view__citations a{color:var(--text)}.research-view__error{color:var(--color-error)}.research-view__findings{display:flex;flex-direction:column;gap:var(--space-sm)}.research-view__finding{padding:var(--space-sm)}.research-view__finding h4,.research-view__finding p{margin:0}.research-view__finding-actions{margin-top:var(--space-sm)}.research-view__events{margin:var(--space-sm) 0 0;padding-left:var(--space-lg)}.research-view__stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-sm)}.research-view__stat-card{border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-sm);padding:var(--space-sm);background:var(--surface)}.research-view__stat-label{color:var(--text-muted);text-transform:uppercase}.research-view__stat-value{font-family:var(--font-mono)}.research-view__state--error{border-color:var(--color-error)}@media(max-width:768px){.research-view{padding:var(--space-md);padding-bottom:calc(var(--space-md) + var(--mobile-nav-height) + env(safe-area-inset-bottom,0px) + var(--standalone-bottom-gap))}.research-view__layout{grid-template-columns:minmax(0,1fr)}.research-view__header{flex-direction:column}.research-view__stats{grid-template-columns:minmax(0,1fr)}.research-view__history-item{min-height:calc(var(--space-lg) * 2 + var(--space-sm))}}
@@ -0,0 +1 @@
1
+ import{r as a,j as e}from"./vendor-react-K0fH_qHe.js";import{as as ie,at as ce,s as le,au as oe,av as de,aw as ue,ax as he,ay as me,az as ve,aA as be,D as xe,aB as fe,L as pe,S as je}from"./index-Bv0TGzDH.js";import"./vendor-xterm-DzcZoU0P.js";const F={webSearch:!0,pageFetch:!0,github:!1,localDocs:!0,llmSynthesis:!0};function W(d){const t=d?.researchGlobalDefaults,u=d?.researchSettings;return{enabled:u?.enabled??d?.researchEnabled??d?.researchGlobalEnabled??!0,searchProvider:u?.searchProvider??t?.searchProvider,synthesisProvider:u?.synthesisProvider??t?.synthesisProvider,synthesisModelId:u?.synthesisModelId??t?.synthesisModelId,enabledSources:{webSearch:u?.enabledSources?.webSearch??t?.enabledSources?.webSearch??F.webSearch,pageFetch:u?.enabledSources?.pageFetch??t?.enabledSources?.pageFetch??F.pageFetch,github:u?.enabledSources?.github??t?.enabledSources?.github??F.github,localDocs:u?.enabledSources?.localDocs??t?.enabledSources?.localDocs??F.localDocs,llmSynthesis:u?.enabledSources?.llmSynthesis??t?.enabledSources?.llmSynthesis??F.llmSynthesis},limits:{maxConcurrentRuns:u?.limits?.maxConcurrentRuns??d?.researchMaxConcurrentRuns??d?.researchGlobalMaxConcurrentRuns??3,maxSourcesPerRun:u?.limits?.maxSourcesPerRun??t?.maxSourcesPerRun??d?.researchMaxSourcesPerRun??d?.researchGlobalMaxSourcesPerRun??20,maxDurationMs:u?.limits?.maxDurationMs??d?.researchDefaultTimeout??d?.researchGlobalDefaultTimeout??3e5,requestTimeoutMs:u?.limits?.requestTimeoutMs??d?.researchFetchTimeoutMs??3e4},defaultExportFormat:t?.defaultExportFormat??"markdown"}}const ge=300,ye=4e3;function Se(d){const t=d?.projectId,[u,x]=a.useState([]),[m,r]=a.useState(null),[I,g]=a.useState(null),[f,S]=a.useState({available:!0}),[R,N]=a.useState(!0),[T,k]=a.useState(null),[y,C]=a.useState(""),_=a.useRef(0),E=a.useRef(0),M=a.useRef(t);a.useEffect(()=>{M.current!==t&&(M.current=t,E.current++)},[t]);const p=a.useCallback(async(c=y)=>{const l=++_.current,i=t;k(null);try{const n=await ie({q:c||void 0,limit:100},i);if(l!==_.current||i!==t)return;x(n.runs),S(n.availability),m&&!n.runs.some(b=>b.id===m)&&(r(null),g(null))}catch(n){if(l!==_.current||i!==t)return;k(n instanceof Error?n.message:"Failed to load research runs")}finally{l===_.current&&N(!1)}},[t,y,m]),j=a.useCallback(async c=>{const l=await ce(c,t);return g(l.run),S(l.availability),l.run},[t]);return a.useEffect(()=>{N(!0);const c=window.setTimeout(()=>{p(y)},ge);return()=>window.clearTimeout(c)},[p,y]),a.useEffect(()=>{if(!m){g(null);return}j(m)},[j,m]),a.useEffect(()=>{const c=E.current,l=()=>E.current!==c,i=t?`?projectId=${encodeURIComponent(t)}`:"";let n=!0;const b=()=>{!n||l()||(p(),m&&j(m))},A=le(`/api/events${i}`,{events:{"research:run:created":b,"research:run:updated":b,"research:run:completed":b,"research:run:failed":b,"research:run:cancelled":b},onReconnect:b}),q=window.setInterval(b,ye);return()=>{n=!1,A(),window.clearInterval(q)}},[t,p,m,j]),{runs:u,selectedRun:I,selectedRunId:m,setSelectedRunId:r,availability:f,loading:R,error:T,searchQuery:y,setSearchQuery:C,refresh:p,createRun:c=>ve(c,t),cancelRun:async c=>{const l=await me(c,t);return m===c&&g(l.run),await p(),l},retryRun:async c=>{const l=await he(c,t);return m===c&&g(l.run),await p(),l},exportRun:(c,l)=>ue(c,l,t),createTaskFromRun:(c,l,i,n,b,A)=>de(c,{title:l,findingId:i,description:n,priority:b,attachExport:A},t),attachRunToTask:(c,l,i,n)=>oe(c,{taskId:l,findingId:i,attachExport:n},t),statusCounts:u.reduce((c,l)=>(c[l.status]+=1,c),{queued:0,running:0,cancelling:0,retry_waiting:0,completed:0,failed:0,cancelled:0,timed_out:0,retry_exhausted:0})}}function _e({open:d,mode:t,run:u,finding:x,projectId:m,onClose:r,onConfirm:I}){const[g,f]=a.useState(!1),[S,R]=a.useState(""),[N,T]=a.useState(""),[k,y]=a.useState("normal"),[C,_]=a.useState(""),[E,M]=a.useState([]),[p,j]=a.useState(!1),[c,l]=a.useState(!1),i=a.useMemo(()=>{const n=(x.content??"").split(/(?<=[.!?])\s+/)[0]??"";return`${x.heading||"Research finding"} — ${n}`.trim()},[x.content,x.heading]);return a.useEffect(()=>{d&&(f(!1),R(`Research: ${x.heading||u.title}`),T(i),y("normal"),_(""),t==="enrich"&&(j(!0),be(50,0,m).then(n=>M(n.filter(b=>b.column!=="archived"))).finally(()=>j(!1))))},[d,t,m,x.heading,i,u.title]),d?e.jsx("div",{className:"modal-overlay open",role:"presentation",onClick:r,children:e.jsxs("div",{className:"modal modal-lg research-task-action-modal",role:"dialog","aria-modal":"true",onClick:n=>n.stopPropagation(),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:t==="create"?"Create task from finding":"Enrich existing task"}),e.jsx("button",{className:"modal-close",type:"button","aria-label":"Close",onClick:r,children:"×"})]}),e.jsxs("div",{className:"research-task-action-modal__body",children:[e.jsxs("div",{className:"card research-task-action-modal__preview",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"Run:"})," ",u.id]}),e.jsxs("p",{children:[e.jsx("strong",{children:"Finding:"})," ",x.id,x.heading?` — ${x.heading}`:""]}),e.jsx("p",{children:i||"No preview available."})]}),t==="create"?e.jsxs(e.Fragment,{children:[e.jsxs("label",{className:"research-task-action-modal__field",children:["Title",e.jsx("input",{className:"input",value:S,onChange:n=>R(n.target.value)})]}),e.jsxs("label",{className:"research-task-action-modal__field",children:["Description",e.jsx("textarea",{className:"input research-task-action-modal__textarea",value:N,onChange:n=>T(n.target.value)})]}),e.jsxs("label",{className:"research-task-action-modal__field",children:["Priority",e.jsxs("select",{className:"select",value:k,onChange:n=>y(n.target.value),children:[e.jsx("option",{value:"low",children:"Low"}),e.jsx("option",{value:"normal",children:"Normal"}),e.jsx("option",{value:"high",children:"High"}),e.jsx("option",{value:"urgent",children:"Urgent"})]})]})]}):e.jsxs("label",{className:"research-task-action-modal__field",children:["Target task",e.jsx("input",{className:"input",list:"research-task-action-task-list",value:C,placeholder:p?"Loading tasks…":"Enter task ID",onChange:n=>_(n.target.value)}),e.jsx("datalist",{id:"research-task-action-task-list",children:E.map(n=>e.jsx("option",{value:n.id,children:n.title},n.id))})]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:g,onChange:n=>f(n.target.checked)}),e.jsx("span",{children:"Attach markdown export artifact"})]})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{className:"btn",type:"button",onClick:r,children:"Cancel"}),e.jsx("button",{className:"btn btn-primary",type:"button",disabled:c||t==="enrich"&&!C,onClick:()=>{l(!0),I({taskId:t==="enrich"?C:void 0,title:t==="create"?S.trim():void 0,description:t==="create"?N.trim():void 0,priority:t==="create"?k:void 0,attachExport:g}).finally(()=>l(!1))},children:t==="create"?"Create Task":"Enrich Task"})]})]})}):null}const Re=["web-search","page-fetch","github","local-docs","llm-synthesis"],we={"web-search":"webSearch","page-fetch":"pageFetch",github:"github","local-docs":"localDocs","llm-synthesis":"llmSynthesis"},Ne={"web-search":"Web Search","page-fetch":"Page Fetch",github:"GitHub","local-docs":"Local Docs","llm-synthesis":"LLM Synthesis"};function Te({projectId:d,addToast:t,onOpenSettings:u,readinessVersion:x=0}){const{runs:m,selectedRun:r,selectedRunId:I,setSelectedRunId:g,availability:f,loading:S,error:R,searchQuery:N,setSearchQuery:T,createRun:k,cancelRun:y,retryRun:C,exportRun:_,createTaskFromRun:E,attachRunToTask:M,statusCounts:p,refresh:j}=Se({projectId:d}),[c,l]=a.useState(""),[i,n]=a.useState(()=>W(void 0)),[b,A]=a.useState([]),[q,Q]=a.useState(!1),[Y,X]=a.useState([]),[L,O]=a.useState(null),[P,$]=a.useState(null),B=f.supportedProviders??Re,U=s=>i.enabledSources[we[s]];a.useEffect(()=>{const s=B.filter(o=>U(o));X(o=>{const v=o.filter(h=>s.includes(h));return v.length>0?v:s})},[i.enabledSources,B]),a.useEffect(()=>{let s=!1;return Promise.all([xe(d),fe().catch(()=>({providers:[]}))]).then(([o,v])=>{s||(n(W(o)),A(v.providers.filter(h=>h.type==="api_key").map(h=>({id:h.id,authenticated:h.authenticated}))))}).catch(()=>{s||n(W(void 0))}),()=>{s=!0}},[d,x]);const re=a.useMemo(()=>r?r.status:"No run selected",[r]),ae=a.useMemo(()=>r?r.status==="queued"||r.status==="retry_waiting"?"status-dot status-dot--pending":r.status==="running"?"status-dot status-dot--connecting":r.status==="completed"?"status-dot status-dot--online":r.status==="failed"||r.status==="cancelled"?"status-dot status-dot--error":"status-dot":"status-dot",[r]),H=f.supportedExportFormats??["markdown","json","html"],V=i.searchProvider,Z=i.enabledSources.webSearch&&!V,ee=i.enabledSources.llmSynthesis&&(!i.synthesisProvider||!i.synthesisModelId),z=a.useMemo(()=>new Map(b.map(s=>[s.id,s.authenticated])),[b]),K=a.useMemo(()=>{const s=new Set;return i.enabledSources.webSearch&&V&&s.add(V),i.enabledSources.llmSynthesis&&i.synthesisProvider&&s.add(i.synthesisProvider),[...s].filter(o=>z.has(o))},[i.enabledSources.llmSynthesis,i.enabledSources.webSearch,i.synthesisProvider,V,z]).find(s=>z.get(s)!==!0),D=a.useMemo(()=>f.available?i.enabled?Z||ee?{reason:"Research defaults are incomplete.",details:"Select the required provider/model defaults in Research settings.",settingsSection:"research-global"}:K?{reason:`Missing API key for ${K}.`,details:"Add provider credentials in Authentication settings.",settingsSection:"authentication"}:null:{reason:"Research is disabled for this project.",details:"Enable project research settings to create runs.",settingsSection:"research-project"}:{reason:f.reason??"Research is unavailable for this project.",details:f.setupInstructions,settingsSection:"research-project"},[f.available,f.reason,f.setupInstructions,i.enabled,K,Z,ee]),G=async(s,o,v)=>{O(s);try{await o(),t?.(v,"success"),await j()}catch(h){t?.(h instanceof Error?h.message:"Action failed","error")}finally{O(null)}},J=async s=>{if(r){O(`export-${s}`);try{const o=await _(r.id,s),v=new Blob([o.content],{type:"text/plain;charset=utf-8"}),h=URL.createObjectURL(v),w=document.createElement("a");w.href=h,w.download=o.filename,document.body.appendChild(w),w.click(),w.remove(),URL.revokeObjectURL(h),t?.(`Exported ${o.filename}`,"success")}catch(o){t?.(o instanceof Error?o.message:"Export failed","error")}finally{O(null)}}},ne=async()=>{if(c.trim()){Q(!0);try{const s=Y.filter(v=>U(v));if(s.length===0){Q(!1),t?.("No enabled research sources are available for this project.","error");return}const o=await k({query:c.trim(),providers:s});g(o.run.id),l(""),t?.("Research run created","success"),await j()}catch(s){t?.(s instanceof Error?s.message:"Failed to create run","error")}finally{Q(!1)}}};return e.jsxs("section",{className:"research-view","aria-label":"Research view",children:[e.jsxs("header",{className:"research-view__header",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"research-view__title",children:"Research"}),e.jsx("p",{className:"research-view__subtitle",children:"Create and track research runs with cited findings."})]}),e.jsx("button",{className:"btn",type:"button",onClick:()=>void j(),children:"Refresh"})]}),D?e.jsxs("div",{className:"research-view__state research-view__state--error card","data-testid":"research-state-unavailable",children:[e.jsx("p",{children:D.reason}),D.details&&e.jsx("p",{children:D.details}),e.jsxs("p",{children:["Current defaults: provider ",i.searchProvider??"(not set)",", max sources ",i.limits.maxSourcesPerRun]}),e.jsxs("div",{className:"research-view__actions",children:[e.jsx("button",{className:"btn",type:"button",onClick:()=>void j(),children:"Refresh"}),e.jsx("button",{className:"btn btn-primary",type:"button",onClick:()=>u?.(D.settingsSection),children:"Open Settings"})]})]}):e.jsxs("div",{className:"research-view__layout",children:[e.jsxs("aside",{className:"research-view__sidebar card",children:[e.jsxs("div",{className:"research-view__form",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"research-query",children:"Query"}),e.jsx("textarea",{id:"research-query",className:"input research-view__textarea",value:c,onChange:s=>l(s.target.value)})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Providers"}),e.jsx("div",{className:"research-view__providers",children:B.map(s=>e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:Y.includes(s),disabled:!U(s),onChange:()=>{U(s)&&X(o=>o.includes(s)?o.filter(v=>v!==s):[...o,s])}}),e.jsx("span",{children:Ne[s]??s})]},s))})]}),e.jsxs("button",{className:"btn btn-primary",type:"button",disabled:!c.trim()||q,onClick:()=>void ne(),children:[q?e.jsx(pe,{className:"animate-spin",size:14}):null,"Create Run"]})]}),e.jsxs("div",{className:"research-view__history-header form-group",children:[e.jsx("label",{htmlFor:"research-run-search",children:"Search"}),e.jsxs("div",{className:"research-view__history-search-row",children:[e.jsx(je,{size:14}),e.jsx("input",{id:"research-run-search",className:"input",placeholder:"Search runs",value:N,onChange:s=>T(s.target.value)})]})]}),e.jsx("div",{className:"research-view__history","data-testid":"research-state-running",children:m.map(s=>e.jsxs("button",{type:"button",className:`research-view__history-item card${I===s.id?" research-view__history-item--active":""}`,onClick:()=>g(s.id),children:[e.jsx("span",{className:"card-id",children:s.id}),e.jsx("span",{children:s.title})]},s.id))})]}),e.jsxs("div",{className:"research-view__reader card",children:[S&&e.jsx("p",{"data-testid":"research-state-loading",children:"Loading research runs…"}),!S&&R&&e.jsx("p",{"data-testid":"research-state-error",children:R}),!S&&!R&&m.length===0&&e.jsx("p",{"data-testid":"research-state-empty",children:"No research runs yet"}),r&&e.jsxs("div",{children:[e.jsxs("div",{className:"research-view__status-row",children:[e.jsx("span",{className:ae}),e.jsx("strong",{children:re})]}),e.jsx("h3",{className:"research-view__run-title",children:r.title}),e.jsx("p",{className:"research-view__run-query",children:r.query}),e.jsx("p",{className:"research-view__run-summary","data-testid":"research-state-results",children:r.results?.summary??"No summary yet."}),e.jsxs("div",{className:"research-view__actions",children:[e.jsx("button",{className:"btn",type:"button",disabled:L==="cancel",onClick:()=>void G("cancel",()=>y(r.id),"Run cancelled"),children:"Cancel"}),e.jsx("button",{className:"btn",type:"button",disabled:L==="retry",onClick:()=>void G("retry",()=>C(r.id),"Run retried"),children:"Retry"}),H.includes("markdown")&&e.jsx("button",{className:"btn",type:"button",disabled:L==="export-markdown",onClick:()=>void J("markdown"),children:"Export MD"}),H.includes("json")&&e.jsx("button",{className:"btn",type:"button",disabled:L==="export-json",onClick:()=>void J("json"),children:"Export JSON"}),H.includes("html")&&e.jsx("button",{className:"btn",type:"button",disabled:L==="export-html",onClick:()=>void J("html"),children:"Export HTML"})]}),r.error&&e.jsx("p",{className:"research-view__error",children:r.error}),Array.isArray(r.results?.findings)&&r.results.findings.length>0&&e.jsx("div",{className:"research-view__findings",children:r.results.findings.map((s,o)=>{const h=s.id?.trim()||`finding-${o+1}`;return e.jsxs("article",{className:"research-view__finding card",children:[e.jsx("h4",{children:s.heading}),e.jsx("p",{children:s.content}),e.jsxs("div",{className:"research-view__actions research-view__finding-actions",children:[e.jsx("button",{className:"btn btn-primary btn-sm",type:"button",onClick:()=>$({mode:"create",findingId:h}),children:"Create Task"}),e.jsx("button",{className:"btn btn-sm",type:"button",onClick:()=>$({mode:"enrich",findingId:h}),children:"Enrich Task"})]})]},h)})}),Array.isArray(r.results?.citations)&&r.results.citations.length>0&&e.jsx("ul",{className:"research-view__citations",children:r.results.citations.map(s=>e.jsx("li",{children:e.jsx("a",{href:s,target:"_blank",rel:"noreferrer",children:s})},s))}),r.events.length>0&&e.jsxs("details",{children:[e.jsx("summary",{children:"Run history"}),e.jsx("ul",{className:"research-view__events",children:r.events.map(s=>e.jsx("li",{children:s.message},s.id))})]})]}),!r&&m.length>0&&e.jsx("p",{children:"Select a run to view details."}),e.jsxs("div",{className:"research-view__stats",children:[e.jsxs("div",{className:"research-view__stat-card",children:[e.jsx("div",{className:"research-view__stat-label",children:"Running"}),e.jsx("div",{className:"research-view__stat-value",children:p.running})]}),e.jsxs("div",{className:"research-view__stat-card",children:[e.jsx("div",{className:"research-view__stat-label",children:"Completed"}),e.jsx("div",{className:"research-view__stat-value",children:p.completed})]}),e.jsxs("div",{className:"research-view__stat-card",children:[e.jsx("div",{className:"research-view__stat-label",children:"Failed"}),e.jsx("div",{className:"research-view__stat-value",children:p.failed})]})]})]})]}),r&&P&&(()=>{const s=r.results?.findings?.findIndex((v,h)=>(v.id?.trim()||`finding-${h+1}`)===P.findingId)??-1,o=s>=0?r.results.findings[s]:null;return o?e.jsx(_e,{open:!0,mode:P.mode,run:r,finding:{id:P.findingId,heading:o.heading,content:o.content},projectId:d,onClose:()=>$(null),onConfirm:async({taskId:v,title:h,description:w,priority:se,attachExport:te})=>{P.mode==="create"?await G("create-task",()=>E(r.id,h,P.findingId,w,se,te),"Task created from research"):v&&await G("attach-task",()=>M(r.id,v,P.findingId,te),"Task enriched from research"),$(null)}}):null})()]})}export{Te as ResearchView};