@runfusion/fusion 0.41.0 → 0.42.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 (83) hide show
  1. package/dist/bin.js +44240 -41922
  2. package/dist/client/.vite/manifest.json +72 -72
  3. package/dist/client/assets/AgentDetailView-C5Lb3fd3.js +18 -0
  4. package/dist/client/assets/AgentDetailView-DiWELtb1.css +1 -0
  5. package/dist/client/assets/{AgentPermissionPolicyEditor-VDXL4XQc.js → AgentPermissionPolicyEditor-DtRcvE6M.js} +2 -2
  6. package/dist/client/assets/{AgentsView-ChXccELt.js → AgentsView-BVW-NOYD.js} +3 -3
  7. package/dist/client/assets/ChatView-Dy-oIkrK.js +6 -0
  8. package/dist/client/assets/{DevServerView-DGOahw1o.js → DevServerView-DLsFSP4s.js} +1 -1
  9. package/dist/client/assets/{DirectoryPicker-DgqHlxyh.js → DirectoryPicker-_QawX-uL.js} +1 -1
  10. package/dist/client/assets/{DocumentsView-CbbZwzbH.js → DocumentsView-DierUJsj.js} +1 -1
  11. package/dist/client/assets/{EvalsView-BL_ue7fJ.js → EvalsView-B83lYKQl.js} +1 -1
  12. package/dist/client/assets/{ExperimentalAgentOnboardingModal-8H4XAu4O.js → ExperimentalAgentOnboardingModal-CTctYTPU.js} +1 -1
  13. package/dist/client/assets/{GoalsView-CO4FVL3E.js → GoalsView-CKn8i0i0.js} +1 -1
  14. package/dist/client/assets/{InsightsView-C5vLvWVE.js → InsightsView-EpRHCD8G.js} +1 -1
  15. package/dist/client/assets/{MemoryView-BL3W3yOv.js → MemoryView-Df_ocTc5.js} +2 -2
  16. package/dist/client/assets/NodesView-DF7xJ_3z.js +14 -0
  17. package/dist/client/assets/{PiExtensionsManager-HvSiVeDN.js → PiExtensionsManager-BOooOEDx.js} +2 -2
  18. package/dist/client/assets/{PluginManager-DIjrlhnU.js → PluginManager-CHrDAzK6.js} +1 -1
  19. package/dist/client/assets/{PullRequestView-C2jQX8xZ.js → PullRequestView-CJU21OZ6.js} +2 -2
  20. package/dist/client/assets/{ReliabilityView-DbqEwoRs.js → ReliabilityView-uHkW1Qeu.js} +1 -1
  21. package/dist/client/assets/{ResearchView-C1QghmLI.js → ResearchView-oZ2-vbjL.js} +1 -1
  22. package/dist/client/assets/{SecretsView-Y2MQ-9n5.js → SecretsView-BpkqSV_E.js} +1 -1
  23. package/dist/client/assets/SessionTerminal-D9IW4cDj.js +2 -0
  24. package/dist/client/assets/{SettingsModal-DabcZZ6S.js → SettingsModal-BmB5l2bA.js} +1 -1
  25. package/dist/client/assets/SettingsModal-C8gsAazm.js +31 -0
  26. package/dist/client/assets/{SetupWizardModal-Db-Rxinm.js → SetupWizardModal-BYLEU_7o.js} +1 -1
  27. package/dist/client/assets/{SkillsView-CIEY1-DE.js → SkillsView-8GgQ8Z_Z.js} +1 -1
  28. package/dist/client/assets/{StashRecoveryView-B6iDu5tI.js → StashRecoveryView-CT1t1Uf2.js} +1 -1
  29. package/dist/client/assets/{TodoView-B8IK_BPM.js → TodoView-BUj6ITAb.js} +2 -2
  30. package/dist/client/assets/WorkflowNodeEditor-CN7GPmvV.js +8 -0
  31. package/dist/client/assets/WorkflowNodeEditor-aPj8cv81.css +1 -0
  32. package/dist/client/assets/app-B2ZxMfJT.js +13 -0
  33. package/dist/client/assets/app-BffGU_HQ.js +13 -0
  34. package/dist/client/assets/app-C8AHhs5N.js +13 -0
  35. package/dist/client/assets/app-DCot4oXA.js +13 -0
  36. package/dist/client/assets/app-Ri9Te2Dv.js +13 -0
  37. package/dist/client/assets/app-sEkTyT-w.js +13 -0
  38. package/dist/client/assets/{dashboard-view-O5j3PSGY.js → dashboard-view-C3SsjXo1.js} +1621 -1621
  39. package/dist/client/assets/{dashboard-view-Dn4CztR6.js → dashboard-view-CrYwb0oQ.js} +1 -1
  40. package/dist/client/assets/dashboard-view-Du53JbmQ.css +1 -0
  41. package/dist/client/assets/{folder-open-C9XAaduE.js → folder-open-CREXTATY.js} +1 -1
  42. package/dist/client/assets/index-2kYpdJrx.js +793 -0
  43. package/dist/client/assets/index-CJUfvGdC.css +1 -0
  44. package/dist/client/assets/{upload-BRAEugYV.js → upload-BvLUlwaH.js} +1 -1
  45. package/dist/client/assets/{users-BlflbMZ3.js → users-CjhbU-sF.js} +1 -1
  46. package/dist/client/index.html +2 -2
  47. package/dist/client/version.json +1 -1
  48. package/dist/droid-cli/package.json +1 -1
  49. package/dist/extension.js +43622 -41519
  50. package/dist/pi-claude-cli/package.json +1 -1
  51. package/dist/plugins/fusion-plugin-acp-runtime/package.json +1 -1
  52. package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
  53. package/dist/plugins/fusion-plugin-compound-engineering/bundled.js +59 -8
  54. package/dist/plugins/fusion-plugin-compound-engineering/package.json +1 -1
  55. package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
  56. package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
  57. package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
  58. package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
  59. package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
  60. package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
  61. package/dist/plugins/fusion-plugin-reports/package.json +1 -1
  62. package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
  63. package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
  64. package/package.json +2 -1
  65. package/skill/fusion/references/extension-tools.md +3 -3
  66. package/skill/fusion/references/fusion-capabilities.md +2 -2
  67. package/dist/client/assets/AgentDetailView-CY-O6VkV.css +0 -1
  68. package/dist/client/assets/AgentDetailView-krC0B2O0.js +0 -18
  69. package/dist/client/assets/ChatView-Dz_xBKit.js +0 -6
  70. package/dist/client/assets/NodesView-DfBNNm9c.js +0 -14
  71. package/dist/client/assets/SessionTerminal-DaTXNT3A.js +0 -2
  72. package/dist/client/assets/SettingsModal-BAzm2kYd.js +0 -31
  73. package/dist/client/assets/WorkflowNodeEditor-DaPyvD_R.js +0 -8
  74. package/dist/client/assets/WorkflowNodeEditor-Po5uv_dN.css +0 -1
  75. package/dist/client/assets/app-CTRT_hQh.js +0 -13
  76. package/dist/client/assets/app-CVg6W-HU.js +0 -13
  77. package/dist/client/assets/app-CY3pQXOr.js +0 -13
  78. package/dist/client/assets/app-DNh04p5I.js +0 -13
  79. package/dist/client/assets/app-DhHgtB9j.js +0 -13
  80. package/dist/client/assets/app-NL_hPGDS.js +0 -13
  81. package/dist/client/assets/dashboard-view-BgiLoG1G.css +0 -1
  82. package/dist/client/assets/index-BHGM5W8a.css +0 -1
  83. package/dist/client/assets/index-CgfrecpF.js +0 -793
@@ -1,6 +0,0 @@
1
- import{r as s,b as zn,j as t,R as Hn}from"./vendor-react-D37HfzIf.js";import{c as On,a9 as Us,a7 as Bs,bf as Ks,bg as gs,aG as Lt,bh as Gs,ac as Vs,bi as cs,t as Un,bj as Bn,bk as ft,bl as Ws,bm as Kn,bn as It,w as Gn,bo as Vn,bp as Wn,bq as qn,br as Xn,bs as Yn,bt as Jn,aW as Qn,bu as Zn,bv as ea,s as ta,bw as sa,j as na,k as mn,bx as hn,by as aa,bz as ra,bA as oa,bB as fn,bC as ia,bD as ca,bE as la,p as da,bF as ua,bG as ma,u as ha,bH as fa,ah as gn,ai as pn,bI as ga,bJ as pa,S as ba,U as ls,P as pt,J as gt,aw as va,bK as qs,a as Pt,bL as Xs,bM as Ys,bN as Js,B as bt,ae as xa,af as ya,b4 as _t,bO as Qs,bP as wa,T as Ca,bQ as Sa,bR as ka,b1 as Na,au as Zs,m as ja,bS as en}from"./index-CgfrecpF.js";import{u as vt}from"./vendor-i18n-CV0mwX_-.js";import{SessionTerminal as tn}from"./SessionTerminal-DaTXNT3A.js";import"./vendor-reactflow-CRZcPCXF.js";import"./vendor-xterm-tcedd2Jt.js";import"./vendor-codemirror-jBKmHyH0.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 Ma=[["path",{d:"M5 3h14",key:"7usisc"}],["path",{d:"m18 13-6-6-6 6",key:"1kf1n9"}],["path",{d:"M12 7v14",key:"1akyts"}]],Ra=On("arrow-up-to-line",Ma),ds="kb-chat-active-session";function sn(n){const r=typeof n=="string"?n.trim():"",u=r.indexOf("/");return!r||u<=0||u>=r.length-1?{}:{modelProvider:r.slice(0,u),modelId:r.slice(u+1)}}function Aa(n){const r=n?.toolCalls;if(!Array.isArray(r))return;const u=r.map(o=>{if(!o||typeof o!="object")return null;const i=o,p=typeof i.toolName=="string"?i.toolName:"";if(!p)return null;const v=i.args;return{toolName:p,...v&&typeof v=="object"?{args:v}:{},isError:!!i.isError,result:i.result,status:"completed"}}).filter(o=>o!==null);return u.length>0?u:void 0}function Ea(n){const r=n?.fallback;if(!r||typeof r!="object")return;const u=r,o=typeof u.primaryModel=="string"?u.primaryModel:"",i=typeof u.fallbackModel=="string"?u.fallbackModel:"",p=u.triggerPoint;if(!(!o||!i||p!=="session-creation"&&p!=="prompt-time"))return{primaryModel:o,fallbackModel:i,triggerPoint:p}}function Ta(n){const r=n?.failureInfo;if(!r||typeof r!="object")return;const u=r,o=typeof u.summary=="string"?u.summary.trim():"";if(!o)return;const i=(()=>{const p=u.reference;if(!p||typeof p!="object")return;const v=p,g=typeof v.kind=="string"?v.kind.trim():"",k=typeof v.id=="string"?v.id.trim():"";if(!(!g||!k))return{kind:g,id:k,...typeof v.label=="string"&&v.label.trim()?{label:v.label.trim()}:{}}})();return{summary:o,...typeof u.errorClass=="string"&&u.errorClass.trim()?{errorClass:u.errorClass.trim()}:{},...typeof u.code=="string"&&u.code.trim()?{code:u.code.trim()}:{},...typeof u.detail=="string"&&u.detail.trim()?{detail:u.detail.trim()}:{},...i?{reference:i}:{}}}function nn(n,r){const u="Failed to get response";return typeof n=="string"?{summary:n.trim()||u}:{summary:typeof n.summary=="string"&&n.summary.trim()?n.summary.trim():u,...typeof n.errorClass=="string"&&n.errorClass.trim()?{errorClass:n.errorClass.trim()}:{},...typeof n.code=="string"&&n.code.trim()?{code:n.code.trim()}:{},...typeof n.detail=="string"&&n.detail.trim()?{detail:n.detail.trim()}:{},...n.reference?{reference:n.reference}:{}}}function us(n){return{id:n.id,sessionId:n.sessionId,role:n.role,content:n.content,thinkingOutput:n.thinkingOutput,toolCalls:Aa(n.metadata),fallbackInfo:Ea(n.metadata),failureInfo:Ta(n.metadata),attachments:n.attachments,createdAt:n.createdAt}}function Ia(n,r){const u=s.useCallback(l=>l?`${Us.CHAT_SESSIONS_PREFIX}${l}`:null,[]),o=s.useCallback((l,f)=>l&&f?`${Us.CHAT_MESSAGES_PREFIX}${l}:${f}`:null,[]),i=s.useCallback(l=>{const f=u(l);return f?Bs(f,{maxAgeMs:Ks})??[]:[]},[u]),[p,v]=s.useState(()=>i(n)),[g,k]=s.useState(null),[z,H]=s.useState(()=>i(n).length===0),[W,y]=s.useState([]),[O,_]=s.useState(!1),[M,R]=s.useState(!1),[q,N]=s.useState(""),[te,j]=s.useState(""),[ee,S]=s.useState([]),[ne,V]=s.useState(""),[X,ke]=s.useState(""),[ae,m]=s.useState(!1),{agentsMap:b}=gs(n),w=s.useRef(null),d=s.useRef(null),we=s.useRef(!1),J=s.useRef(""),P=s.useRef(null),Ce=s.useRef(p),$=s.useRef(g),je=s.useRef(W),Y=s.useRef(M);Ce.current=p,$.current=g,je.current=W,Y.current=M,s.useEffect(()=>{J.current=ne},[ne]);const Me=s.useRef(new Set),De=s.useRef(0),$e=s.useRef(n);$e.current!==n&&(Lt({view:"useChat",trigger:"project-context-change",projectId:n,replayAttempted:!1,detail:{previousProjectId:$e.current??null}}),$e.current=n,De.current++);const he=s.useCallback(async()=>{Ce.current.length===0&&H(!0);try{const f=[...(await Gs(n)).sessions].sort((A,G)=>new Date(G.updatedAt).getTime()-new Date(A.updatedAt).getTime());v(f);const x=u(n);x&&Vs(x,f,{maxBytes:5e5})}catch{const l=i(n);if(Ce.current.length===0&&l.length===0){const f=u(n);f&&cs(f)}}finally{H(!1)}},[u,n]);s.useEffect(()=>{const l=i(n);v(l),H(l.length===0)},[n,i]),s.useEffect(()=>{he()},[he,n]);const be=s.useRef(()=>{}),ve=s.useRef(!1);s.useEffect(()=>{ve.current=!1,d.current=null},[n]),s.useEffect(()=>{if(z||ve.current||$.current)return;const l=Un(ds,n);if(!l){ve.current=!0;return}const f=p.find(x=>x.id===l);if(f){ve.current=!0,be.current(l,f);return}ve.current=!0},[z,p,n]);const Fe=s.useCallback((l,f)=>{const x=o(l,f);return x?Bs(x,{maxAgeMs:Ks})??[]:[]},[o]),xt=s.useCallback(l=>{const f=Fe(n,l);return f.length>0?(y(f),_(!1),!0):(y([]),!1)},[n,Fe]),re=s.useCallback(async(l,f)=>{const x=typeof f?.offset=="number"&&f.offset>0||typeof f?.before=="string",A=o(n,l),G=x?[]:Fe(n,l),T=G.length>0;!x&&T?(y(G),_(!1)):_(!0);try{const U=await Bn(l,{limit:50,order:"desc",...f},n),B=U.messages.slice().reverse().map(us);x?$.current?.id===l&&(y(I=>[...B,...I]),m(U.messages.length>=50)):$.current?.id===l&&(y(B),m(U.messages.length>=50),A&&Vs(A,B,{maxBytes:5e5}))}catch{!x&&je.current.length===0&&T&&(y(G),_(!1))}finally{_(!1)}},[o,n,Fe]),Ge=s.useCallback(()=>{P.current?.(),P.current=null,J.current="",V(""),N(""),j(""),S([]),R(!1)},[]),Se=s.useCallback(()=>{ft($.current?.id),J.current="",V("")},[]),se=s.useCallback(()=>{const l=J.current.trim();l&&(ft($.current?.id),J.current="",V(""),Ve.current(l))},[]),oe=s.useCallback((l,f,x)=>{if(w.current||!l)return!0;we.current=!1,f&&(N(f.streamingText),j(f.streamingThinking),S(f.toolCalls)),R(!0);const{handlers:A}=Ws({sessionId:l,tempUserMessageId:"",setStreamingText:N,setStreamingThinking:j,setStreamingToolCalls:S,cancelStreamingFlushesRef:P,addToast:x?.silent?void 0:r,onFallbackSession:(T,U)=>{const B=sn(T.fallbackModel);v(I=>I.map(K=>K.id===U?{...K,...B}:K)),k(I=>I&&I.id===U?{...I,...B}:I)},onDone:()=>{N(""),j(""),S([]),R(!1),Y.current=!1,w.current=null,d.current=null,re(l),se()},onError:T=>{N(""),j(""),S([]),R(!1),Y.current=!1,w.current=null,d.current=null;const U=nn(T);x?.silent||r?.(U.summary,"error"),re(l),se()}});Lt({view:"useChat",trigger:"sse-open",projectId:n,replayAttempted:typeof f?.replayFromEventId=="number",replayFromEventId:f?.replayFromEventId??null,lastEventId:f?.replayFromEventId??null});const G=Kn(l,A,n,{...typeof f?.replayFromEventId=="number"?{lastEventId:f.replayFromEventId}:{}});return w.current=G,d.current={sessionId:l,replayFromEventId:typeof f?.replayFromEventId=="number"?f.replayFromEventId:null},!0},[r,re,n,se]),Le=s.useCallback((l,f)=>{const x=$.current?.id??null;if(l&&x===l&&!f)return;w.current&&(w.current.close(),w.current=null),d.current=null;const A=f??p.find(G=>G.id===l);k(A||null),l&&It(l,n).then(({session:G})=>{!G.isGenerating||!G.inFlightGeneration||k(T=>!T||T.id!==l?T:{...T,...G})}).catch(()=>{}),Ge(),m(!1),l?(xt(l),re(l)):y([]),A?.isGenerating&&oe(A.id,A.inFlightGeneration),l?Gn(ds,l,n):Vn(ds,n)},[oe,xt,p,re,n,Ge]);be.current=Le,s.useEffect(()=>{const l=g?.id;if(!l)return;const f=Wn(l);if(!f)return;J.current=f,V(f);let x=!1;return It(l,n).then(({session:A})=>{if(!(x||$.current?.id!==l||J.current.trim().length===0)){if(A.isGenerating){w.current||oe(l,A.inFlightGeneration);return}!Y.current&&!w.current&&se()}}).catch(()=>{}),()=>{x=!0}},[g?.id,oe,se,n]);const at=s.useCallback(async l=>{const f=$.current?.id,x=await qn(l,n);w.current&&(w.current.close(),w.current=null),d.current=null;const A={id:x.session.id,title:x.session.title,agentId:x.session.agentId,status:x.session.status,modelProvider:x.session.modelProvider,modelId:x.session.modelId,createdAt:x.session.createdAt,updatedAt:x.session.updatedAt};return v(G=>G.some(T=>T.id===A.id)?G:[A,...G]),ft(f),Ge(),Le(A.id,A),A},[n,Ge,Le]),zt=s.useCallback(async l=>{ft(l),await Xn(l,{status:"archived"},n),v(f=>f.filter(x=>x.id!==l)),g?.id===l&&(d.current=null,k(null),y([]))},[g,n]),_e=s.useCallback(async l=>{ft(l),g?.id===l&&w.current&&(w.current.close(),w.current=null),g?.id===l&&(d.current=null),await Yn(l,n);const f=o(n,l);f&&cs(f),v(x=>x.filter(A=>A.id!==l)),g?.id===l&&(k(null),y([]))},[g,o,n]),ze=s.useCallback(async()=>{if(!g||!ae)return;const l=je.current[0]?.createdAt;l&&await re(g.id,{before:l})},[g,ae,re]),rt=s.useCallback(()=>{g&&(we.current=!0,P.current?.(),P.current=null,w.current?.close(),w.current=null,d.current=null,Jn(g.id,n).catch(()=>{}),R(!1),Y.current=!1,N(""),j(""),S([]),se())},[g,n,se]),Ve=s.useRef(()=>{}),We=Qn(),He=s.useCallback(async l=>{try{await he();const f=await It(l,n);$.current?.id===l&&k(x=>!x||x.id!==l?x:{...x,...f.session}),f.session.isGenerating?(N(""),j(""),S([]),R(!0),Y.current=!0,oe(l,f.session.inFlightGeneration,{silent:!0})):(N(""),j(""),S([]),R(!1),Y.current=!1,await re(l))}catch{}},[oe,re,n,he]),Re=s.useCallback((l,f)=>{if(!g)return;if(Y.current){J.current=l,V(l),Zn(g.id,l);return}we.current=!1,w.current&&(w.current.close(),w.current=null),d.current=null;const x=`temp-${Date.now()}`,A={id:x,sessionId:g.id,role:"user",content:l,createdAt:new Date().toISOString()};y(T=>[...T,A]),N(""),j(""),S([]),R(!0);const{handlers:G}=Ws({sessionId:g.id,tempUserMessageId:x,setStreamingText:N,setStreamingThinking:j,setStreamingToolCalls:S,cancelStreamingFlushesRef:P,addToast:r,onFallbackSession:(T,U)=>{const B=sn(T.fallbackModel);v(I=>I.map(K=>K.id===U?{...K,...B}:K)),k(I=>I&&I.id===U?{...I,...B}:I)},onDone:({messageId:T,message:U,accumulated:B})=>{const I=U?{...us(U),...B.text.length>0?{content:B.text}:{}}:{id:T||`msg-${Date.now()}`,sessionId:g.id,role:"assistant",content:B.text,thinkingOutput:B.thinking,toolCalls:B.toolCalls.length>0?B.toolCalls:void 0,fallbackInfo:B.fallbackInfo,createdAt:new Date().toISOString()};Me.current.add(I.id),y(K=>[...K,I]),N(""),j(""),S([]),R(!1),Y.current=!1,w.current=null,d.current=null,setTimeout(()=>{Me.current.delete(I.id)},1e3),he(),se()},onError:(T,U)=>{const B=nn(T),I=typeof T=="string"?T:B.summary,K=sa(I);y(Q=>{const F=Q.filter(Z=>Z.id!==U);return K?F:[...F,{id:`error-${Date.now()}`,sessionId:g.id,role:"assistant",content:B.summary,failureInfo:B,createdAt:new Date().toISOString()}]}),N(""),j(""),S([]),R(!1),Y.current=!1,w.current=null,d.current=null,console.error("[useChat] Stream error:",T),K?(console.info("[useChat] Suppressed tab-suspension stream error:",T),g?.id&&(N(""),j(""),S([]),R(!0),Y.current=!0,He(g.id))):(r?.(B.summary,"error"),he()),we.current||se()}});w.current=ea(g.id,l,G,f,n)},[g,n,he,r,oe,He,se]);Ve.current=Re;const Oe=X?p.filter(l=>l.title?.toLowerCase().includes(X.toLowerCase())||l.agentId.toLowerCase().includes(X.toLowerCase())):p;return s.useEffect(()=>{if(!g?.id||g.isGenerating!==!0||w.current)return;const l=typeof g.inFlightGeneration?.replayFromEventId=="number"?g.inFlightGeneration.replayFromEventId:null,f=d.current;f?.sessionId===g.id&&f.replayFromEventId===l||oe(g.id,g.inFlightGeneration,{silent:!0})},[g?.id,g?.isGenerating,g?.inFlightGeneration,oe]),s.useEffect(()=>{if(!$.current?.isGenerating||(w.current||oe($.current.id,$.current.inFlightGeneration),!Y.current||w.current||!$.current))return;const l=setInterval(async()=>{if(!Y.current||w.current||!$.current){clearInterval(l);return}try{(await Gs(n)).sessions.find(A=>A.id===$.current?.id)?.isGenerating||(clearInterval(l),await re($.current.id),N(""),j(""),S([]),R(!1),Y.current=!1,se())}catch{}},3e3);return()=>clearInterval(l)},[oe,re,n,g,se]),s.useEffect(()=>We.onBecameVisible(()=>{const f=$.current;if(!f||w.current)return;const x=De.current;It(f.id,n).then(A=>{if(!(De.current!==x||w.current)){if(A.session.isGenerating){N(""),j(""),S([]),R(!0),Y.current=!0,oe(f.id,A.session.inFlightGeneration,{silent:!0});return}Y.current&&(N(""),j(""),S([]),R(!1),Y.current=!1,se(),re(f.id))}}).catch(()=>{})}),[oe,re,n,We,se]),s.useEffect(()=>{const l=De.current,f=n?`?projectId=${encodeURIComponent(n)}`:"",x=()=>De.current!==l,A=K=>{if(x())return;const Q=JSON.parse(K.data);v(F=>F.some(Z=>Z.id===Q.id)?F:[Q,...F])},G=K=>{if(x())return;const Q=JSON.parse(K.data);v(F=>[...F.map(le=>le.id===Q.id?Q:le)]),$.current?.id===Q.id&&(k(Q),Q.isGenerating&&!w.current&&oe(Q.id,Q.inFlightGeneration))},T=K=>{if(x())return;const{id:Q}=JSON.parse(K.data);v(Z=>Z.filter(le=>le.id!==Q));const F=o(n,Q);F&&cs(F),$.current?.id===Q&&(k(null),y([]))},U=K=>{if(x())return;const Q=JSON.parse(K.data),F=us(Q);if(!Me.current.has(F.id)){if($.current?.id===F.sessionId&&Y.current&&!w.current&&F.role==="assistant"){y(Z=>Z.some(le=>le.id===F.id)?Z:[...Z,F]),N(""),j(""),S([]),R(!1),Y.current=!1,se();return}$.current?.id===F.sessionId&&!Y.current&&y(Z=>{if(Z.some(le=>le.id===F.id))return Z;if(F.role==="user"){const le=Z.findIndex(fe=>fe.role==="user"&&fe.id.startsWith("temp-")&&fe.content.trim()===F.content.trim());if(le>=0){const fe=[...Z];return fe[le]=F,fe}}return[...Z,F]})}},B=K=>{if(x())return;const{id:Q}=JSON.parse(K.data);y(F=>F.filter(Z=>Z.id!==Q))};return ta(`/api/events${f}`,{events:{"chat:session:created":A,"chat:session:updated":G,"chat:session:deleted":T,"chat:message:added":U,"chat:message:deleted":B}})},[oe,o,n,se]),s.useEffect(()=>()=>{w.current&&(w.current.close(),w.current=null),d.current=null},[]),{sessions:p,activeSession:g,sessionsLoading:z,messages:W,messagesLoading:O,isStreaming:M,streamingText:q,streamingThinking:te,streamingToolCalls:ee,pendingMessage:ne,selectSession:Le,createSession:at,archiveSession:zt,deleteSession:_e,sendMessage:Re,stopStreaming:rt,clearPendingMessage:Se,loadMoreMessages:ze,hasMoreMessages:ae,searchQuery:X,setSearchQuery:ke,filteredSessions:Oe,refreshSessions:he,agentsMap:b}}function Pa(n,r=[],u){const o=n.trim().replace(/^#/,""),i=(v,g)=>u?u(v,g):g;if(!o)return{ok:!1,error:i("createRoom.nameRequired","Room name is required.")};if(/[A-Z]/.test(o))return{ok:!1,error:i("createRoom.lowercase","Use lowercase letters only.")};const p=o.toLowerCase();return p.length>80?{ok:!1,error:i("createRoom.maxLength","Room names can be at most 80 characters.")}:/^[a-z0-9_-]+$/.test(p)?/^[-_]|[-_]$/.test(p)?{ok:!1,error:i("createRoom.noEdgeChars","Room names cannot start or end with a hyphen or underscore.")}:r.some(v=>v.toLowerCase()===p)?{ok:!1,error:i("createRoom.duplicate","A room with this name already exists.")}:{ok:!0,name:p}:{ok:!1,error:i("createRoom.validChars","Use lowercase letters, numbers, hyphens, or underscores only.")}}function Da({isOpen:n,onClose:r,onCreate:u,projectId:o,existingRoomNames:i=[]}){const{t:p}=vt("app"),[v,g]=s.useState(""),[k,z]=s.useState([]),[H,W]=s.useState(""),[y,O]=s.useState([]),[_,M]=s.useState(!1),[R,q]=s.useState(null),[N,te]=s.useState(!1),j=s.useRef(null),ee=s.useRef(null);s.useEffect(()=>{n&&(ee.current=document.activeElement instanceof HTMLElement?document.activeElement:null,M(!0),q(null),na(void 0,o).then(m=>z(m)).catch(()=>{z([]),q(p("createRoom.failedLoadAgents","Failed to load agents."))}).finally(()=>M(!1)))},[n,o]),s.useEffect(()=>{if(!n){g(""),W(""),O([]),q(null),te(!1);return}const m=window.requestAnimationFrame(()=>j.current?.focus());return()=>window.cancelAnimationFrame(m)},[n]),s.useEffect(()=>{if(!n)return;const m=b=>{b.key==="Escape"&&r()};return document.addEventListener("keydown",m),()=>document.removeEventListener("keydown",m)},[n,r]),s.useEffect(()=>{n||ee.current?.focus()},[n]);const S=s.useMemo(()=>Pa(v,i,p),[v,i,p]),ne=s.useMemo(()=>{const m=H.trim().toLowerCase();return m?k.filter(b=>b.name.toLowerCase().includes(m)):k},[k,H]),V=s.useMemo(()=>k.filter(m=>y.includes(m.id)),[k,y]),X=S.ok&&y.length>0&&!N&&!_;if(!n)return null;const ke=m=>{N||O(b=>b.includes(m)?b.filter(w=>w!==m):[...b,m])},ae=async()=>{if(!S.ok){q(S.error);return}if(y.length===0){q(p("createRoom.selectMember","Select at least one member."));return}q(null),te(!0);try{await u({name:S.name,displayName:`#${S.name}`,memberAgentIds:y}),r()}catch(m){q(m instanceof Error?m.message:p("createRoom.failedCreate","Failed to create room."))}finally{te(!1)}};return zn.createPortal(t.jsx("div",{className:"modal-overlay open",onClick:m=>m.target===m.currentTarget&&r(),children:t.jsxs("div",{className:"modal modal-lg create-room-modal",role:"dialog","aria-modal":"true","aria-label":p("createRoom.title","Create room"),onClick:m=>m.stopPropagation(),children:[t.jsxs("div",{className:"modal-header",children:[t.jsx("h3",{children:p("createRoom.title","Create room")}),t.jsx("button",{type:"button",className:"modal-close","aria-label":p("actions.close","Close"),onClick:r,children:"×"})]}),t.jsxs("div",{className:"form-group create-room-modal-name-group",children:[t.jsx("label",{htmlFor:"create-room-name",children:p("createRoom.nameLabel","Room name")}),t.jsxs("div",{className:"create-room-modal-name-field",children:[t.jsx("span",{"aria-hidden":"true",className:"create-room-modal-name-hash",children:"#"}),t.jsx("input",{ref:j,id:"create-room-name",className:"input",value:v,disabled:N,onChange:m=>{const b=m.target.value.replace(/^#/,"").replace(/\s+/g,"-").toLowerCase();g(b)}})]}),!S.ok&&t.jsx("div",{className:"form-error",children:S.error})]}),t.jsxs("div",{className:"form-group",children:[t.jsx("label",{htmlFor:"create-room-member-search",children:p("createRoom.members","Members")}),t.jsx("input",{id:"create-room-member-search",className:"input",placeholder:p("createRoom.searchAgents","Search agents"),value:H,disabled:N,onChange:m=>W(m.target.value)})]}),V.length>0&&t.jsx("div",{className:"create-room-modal-selected","data-testid":"create-room-selected-chips",children:V.map(m=>t.jsxs("button",{type:"button",className:"btn btn-sm create-room-modal-chip",onClick:()=>ke(m.id),disabled:N,children:[m.name," ×"]},m.id))}),t.jsx("div",{className:"create-room-modal-member-list","data-testid":"create-room-member-list",children:_?t.jsx("div",{className:"create-room-modal-empty",children:p("createRoom.loadingAgents","Loading agents...")}):ne.length===0?t.jsx("div",{className:"create-room-modal-empty",children:k.length===0?p("createRoom.noAgents","No agents in this project yet."):p("createRoom.noMatch","No agents match your search.")}):ne.map(m=>{const b=y.includes(m.id);return t.jsxs("button",{type:"button",className:`create-room-modal-member-row${b?" create-room-modal-member-row--selected":""}`,onClick:()=>ke(m.id),disabled:N,children:[t.jsx(mn,{agent:m,size:20}),t.jsx("span",{children:m.name}),t.jsx("span",{className:"create-room-modal-member-role",children:m.role})]},m.id)})}),R&&t.jsx("div",{className:"form-group",children:t.jsx("div",{className:"form-error",children:R})}),t.jsxs("div",{className:"modal-actions",children:[t.jsx("button",{type:"button",className:"btn",onClick:r,disabled:N,children:p("actions.cancel","Cancel")}),t.jsx("button",{type:"button",className:"btn btn-primary",onClick:()=>void ae(),disabled:!X,children:N?p("createRoom.creating","Creating..."):p("createRoom.create","Create room")})]})]})}),document.body)}function $a({cliSessionId:n,tier:r,projectId:u,renderTranscript:o,renderComposer:i,queuedCount:p=0,terminalProps:v}){const{t:g}=vt("app"),k=r==="generic",[z,H]=s.useState(k?"terminal":"transcript");if(k)return t.jsx("div",{className:"cli-chat-surface cli-chat-surface--generic","data-tier":"generic",children:t.jsx(tn,{sessionId:n,projectId:u,...v})});const W=z==="terminal";return t.jsxs("div",{className:"cli-chat-surface","data-tier":r,"data-view":z,children:[t.jsxs("div",{className:"cli-chat-surface__toolbar",role:"tablist","aria-label":g("cliChat.viewToggleLabel","Chat view"),children:[t.jsxs("button",{type:"button",role:"tab","aria-selected":!W,className:`cli-chat-surface__tab${W?"":" is-active"}`,onClick:()=>H("transcript"),children:[t.jsx(hn,{size:14,"aria-hidden":"true"}),t.jsx("span",{children:g("cliChat.transcriptTab","Transcript")})]}),t.jsxs("button",{type:"button",role:"tab","aria-selected":W,className:`cli-chat-surface__tab${W?" is-active":""}`,onClick:()=>H("terminal"),children:[t.jsx(aa,{size:14,"aria-hidden":"true"}),t.jsx("span",{children:g("cliChat.terminalTab","Terminal")})]})]}),t.jsx("div",{className:"cli-chat-surface__body",children:W?t.jsx(tn,{sessionId:n,projectId:u,...v}):o()}),!W&&t.jsxs("div",{className:"cli-chat-surface__composer",children:[p>0&&t.jsx("div",{className:"cli-chat-surface__queued",role:"status","aria-live":"polite",children:g("cliChat.queued","{{count}} message queued — will send when the agent is ready",{count:p})}),i()]})]})}const bn=640,an="__SKIP__";let ms=!1;function Fa(n){return n>bn?"auto":"hidden"}function La(n){return Math.max(40,Math.min(n,bn))}function vn(n,r){const u=new Date(n),i=new Date().getTime()-u.getTime(),p=Math.floor(i/1e3),v=Math.floor(p/60),g=Math.floor(v/60),k=Math.floor(g/24);return p<60?r("chat.relativeTimeJustNow","just now"):v<60?r("chat.relativeTimeMinutes","{{count}}m ago",{count:v}):g<24?r("chat.relativeTimeHours","{{count}}h ago",{count:g}):k<7?r("chat.relativeTimeDays","{{count}}d ago",{count:k}):u.toLocaleDateString()}function rn(n,r){if(!n||!r)return null;const u=r.toLowerCase();if(u.includes("claude")){let i=r.replace(/^claude[- ]/i,"Claude ").replace(/sonnet[- ](\d+)[- ](\d+)/i,"Sonnet $1.$2").replace(/sonnet[- ](\d+)/i,"Sonnet $1").replace(/haiku[- ](\d+)/i,"Haiku $1").replace(/opus[- ](\d+)/i,"Opus $1").replace(/sonnet/i,"Sonnet").replace(/haiku/i,"Haiku").replace(/opus/i,"Opus").replace(/-/g," ").trim();return i=i.replace(/\s+/g," "),i.length>30?i.slice(0,30)+"…":i}if(u.includes("gpt")||u.includes("openai")){const i=r.replace(/^gpt-4-turbo$/i,"GPT-4 Turbo").replace(/^gpt-4o-mini$/i,"GPT-4o Mini").replace(/^gpt-4o$/i,"GPT-4o").replace(/^gpt-4$/i,"GPT-4").replace(/^gpt-o1-preview$/i,"GPT-o1 Preview").replace(/^gpt-o1-mini$/i,"GPT-o1 Mini").replace(/^gpt-o1$/i,"GPT-o1").replace(/^gpt/i,"GPT").trim();return i.length>30?i.slice(0,30)+"…":i}if(u.includes("gemini")){const i=r.replace(/^gemini[- ]/i,"Gemini ").replace(/pro[- ](\d+)[- ](\d+)/i,"Pro $1.$2").replace(/pro[- ](\d+)/i,"Pro $1").replace(/-/g," ").replace(/\s+/g," ").trim();return i.length>30?i.slice(0,30)+"…":i}const o=r.replace(/-/g," ").replace(/^\w/,i=>i.toUpperCase()).replace(/\s+/g," ").trim();return o.length>30?o.slice(0,30)+"…":o}function Ft(n,r){return n.length<=r?n:`${n.slice(0,r)}…`}function _a(n){if(!n)return null;const r=Object.entries(n);return r.length===0?null:r.map(([u,o])=>{const i=typeof o=="string"?o:(()=>{try{return JSON.stringify(o)}catch{return String(o)}})();return`${u}=${Ft(i,50)}`}).join(", ")}function za(n){if(n===void 0)return null;if(typeof n=="string")return Ft(n,200);try{return Ft(JSON.stringify(n),200)}catch{return Ft(String(n),200)}}function Ha(n){if(!n)return null;if(n.kind==="mailbox"||n.kind==="mailbox-message"){const r=typeof window>"u"?"/":window.location.pathname||"/",u=new URLSearchParams(typeof window>"u"?"":window.location.search);return u.set("view","mailbox"),u.set("mailbox-message",n.id),`${r}?${u.toString()}#message-${encodeURIComponent(n.id)}`}return null}function Oa(n,r){if(!n)return null;const u=n.label??`${n.kind} ${n.id}`,o=Ha(n),i=`chat-failure-reference-${n.kind}-${n.id}`.replace(/[^a-zA-Z0-9_-]+/g,"-").toLowerCase();return t.jsxs("div",{className:"chat-message-failure-reference",children:[t.jsx("span",{className:"chat-message-failure-reference-label",children:r("chat.failureReferenceLabel","Reference")}),t.jsx("span",{className:"chat-message-failure-reference-value",children:u}),o?t.jsx("a",{className:"btn btn-sm chat-message-failure-reference-link",href:o,children:r("chat.openMailboxMessage","Open mailbox message")}):t.jsxs("details",{className:"chat-message-failure-reference-details",children:[t.jsx("summary",{className:"btn btn-sm chat-message-failure-reference-link",children:r("chat.viewFailureDetails","View failure details")}),t.jsxs("dl",{className:"chat-message-failure-reference-meta",id:i,children:[t.jsxs("div",{children:[t.jsx("dt",{children:r("chat.failureReferenceKind","Kind")}),t.jsx("dd",{children:n.kind})]}),t.jsxs("div",{children:[t.jsx("dt",{children:r("chat.failureReferenceId","ID")}),t.jsx("dd",{children:n.id})]}),n.label&&t.jsxs("div",{children:[t.jsx("dt",{children:r("chat.failureReferenceMetaLabel","Label")}),t.jsx("dd",{children:n.label})]})]})]})]})}function xn(n,r){if(!n||n.length===0)return null;const u=(y,O)=>{const _=y.status==="running",M=y.status==="completed"&&y.isError,R=_a(y.args),q=za(y.result),N=_?R:q?`${r("chat.toolCallResultPrefix","result")}: ${q}`:R?`${r("chat.toolCallArgsPrefix","args")}: ${R}`:null,te=_?r("chat.toolCallStatusRunning","running"):M?r("chat.toolCallStatusError","error"):r("chat.toolCallStatusCompleted","completed");return t.jsxs("details",{className:`chat-tool-call${_?" chat-tool-call--running":""}${M?" chat-tool-call--error":""}`,open:_,children:[t.jsxs("summary",{children:[t.jsx("span",{className:"chat-tool-call-status-dot","aria-hidden":"true"}),t.jsx("span",{className:"chat-tool-call-name",title:y.toolName,children:y.toolName}),N&&t.jsx("span",{className:"chat-tool-call-preview",title:N,children:N}),t.jsx("span",{className:"chat-tool-call-status-text",children:te})]}),t.jsxs("div",{className:"chat-tool-call-content",children:[R&&t.jsxs("div",{className:"chat-tool-call-row",children:[t.jsx("span",{className:"chat-tool-call-label",children:r("chat.toolCallArgsPrefix","args")}),t.jsx("span",{className:"chat-tool-call-value",children:R})]}),q&&t.jsxs("div",{className:`chat-tool-call-row${M?" chat-tool-call-row--error":""}`,children:[t.jsx("span",{className:"chat-tool-call-label",children:r("chat.toolCallResultPrefix","result")}),t.jsx("span",{className:"chat-tool-call-value",children:q})]})]})]},`${y.toolName}-${O}`)},o="chat-tool-calls";if(n.length===1)return t.jsxs("div",{className:o,"data-testid":"chat-tool-calls",children:[t.jsxs("div",{className:"chat-tool-calls-header",children:[t.jsx(en,{size:12,"aria-hidden":"true"}),t.jsx("span",{children:r("chat.toolCallsHeader","Tool calls")})]}),u(n[0],0)]});const i=n.filter(y=>y.status==="running").length,p=n.filter(y=>y.status==="completed"&&y.isError).length,v=i>0,g=Array.from(new Set(n.map(y=>y.toolName))),k=g.slice(0,5),z=Math.max(0,g.length-k.length),H=z>0?`${k.join(", ")}, +${z} more`:k.join(", "),W=v?`(${i} ${r("chat.toolCallStatusRunning","running")})`:p>0?`(${p} ${p===1?r("chat.toolCallStatusError","error"):r("chat.toolCallStatusErrors","errors")})`:null;return t.jsx("div",{className:o,"data-testid":"chat-tool-calls",children:t.jsxs("details",{className:"chat-tool-calls-group","data-testid":"chat-tool-calls-group",open:v,children:[t.jsxs("summary",{className:"chat-tool-calls-group-summary",children:[t.jsx(en,{size:12,"aria-hidden":"true"}),t.jsx("span",{className:"chat-tool-calls-count",children:r("chat.toolCallsCount","{{count}} tool calls",{count:n.length})}),t.jsx("span",{className:"chat-tool-calls-names",title:H,children:H}),W&&t.jsx("span",{className:"chat-tool-calls-group-status",children:W})]}),n.map((y,O)=>u(y,O))]})})}const yn={p:({children:n,...r})=>t.jsx("p",{...r,children:Qs(n)}),li:({children:n,...r})=>t.jsx("li",{...r,children:Qs(n)}),pre:({children:n,...r})=>t.jsx("pre",{...r,className:"chat-markdown-pre",children:n}),code:({children:n,...r})=>{const u=typeof n=="string"?n:Hn.Children.toArray(n).join(""),o=_t(u);return o.length===1&&typeof o[0]=="string"?t.jsx("code",{...r,children:n}):t.jsx("code",{...r,children:o})},table:({children:n,...r})=>t.jsx("table",{...r,className:"chat-markdown-table",children:n})},nt="__fn_agent__",Ua=280,Dt=180,$t=500,on="fusion:chat-sidebar-width",hs="fusion:chat-scope",Ba="fusion:chat-draft:";function cn(n,r){return r?`${Ba}${n}:${r}`:null}function ln(n){if(!n)return"";try{return localStorage.getItem(n)??""}catch{return""}}const Ka=["image/png","image/jpeg","image/gif","image/webp","text/plain","application/json","text/yaml","text/markdown","text/csv","application/xml","text/x-log"];function dn(n){const r=/(^|[\s])\/([^\s]*)$/.exec(n);if(!r)return null;const u=r[1]??"",o=r[2]??"",i=r.index+u.length;return{filter:o,start:i,end:n.length}}function Ga(n,r){const u=n.slice(0,r),o=/(^|[\s\n])@([\w-]*)$/.exec(u);if(!o)return null;const i=o[2]??"",p=u.length-i.length-1;return{filter:i,start:p,end:r}}function Va(n){const r=n?.runtimeConfig;if(!r||typeof r!="object")return null;const u=Reflect.get(r,"modelProvider"),o=Reflect.get(r,"modelId");return typeof u!="string"||u.trim().length===0||typeof o!="string"||o.trim().length===0?null:{provider:u,modelId:o}}function un(n,r,u){if(n?.modelProvider&&n?.modelId)return{provider:n.modelProvider,modelId:n.modelId};const o=Va(r??void 0);return o||(u.provider&&u.modelId?{provider:u.provider,modelId:u.modelId}:null)}function Wa({projectId:n,defaultModel:r,onClose:u,onCreate:o}){const{t:i}=vt("app"),[p,v]=s.useState("agent"),{agents:g,loading:k}=gs(n),[z,H]=s.useState(""),{models:W,favoriteProviders:y,favoriteModels:O,loading:_,refresh:M}=fn(),R=r.provider&&r.modelId?`${r.provider}/${r.modelId}`:"",[q,N]=s.useState(R),[te,j]=s.useState(y),[ee,S]=s.useState(O);s.useEffect(()=>{j(y)},[y]),s.useEffect(()=>{S(O)},[O]),s.useEffect(()=>{R&&N(m=>m||R)},[R]);const ne=s.useCallback(async m=>{const b=te,d=b.includes(m)?b.filter(we=>we!==m):[m,...b];j(d);try{await Zs({favoriteProviders:d,favoriteModels:ee}),await M()}catch{j(b)}},[te,ee,M]),V=s.useCallback(async m=>{const b=ee,d=b.includes(m)?b.filter(we=>we!==m):[m,...b];S(d);try{await Zs({favoriteProviders:te,favoriteModels:d}),await M()}catch{S(b)}},[ee,te,M]),X=q||R,ke=m=>{if(m.preventDefault(),p==="agent"){if(!z)return;o({agentId:z});return}if(!X)return;const b=X.indexOf("/");if(b<=0)return;const w=X.slice(0,b),d=X.slice(b+1);o({agentId:nt,modelProvider:w,modelId:d})},ae=p==="agent"?!z:!X;return t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:u,role:"dialog","aria-modal":"true",children:t.jsxs("div",{className:"chat-new-dialog chat-view-dialog",onClick:m=>m.stopPropagation(),children:[t.jsx("h3",{children:i("chat.newChatTitle","New Chat")}),t.jsxs("div",{className:"chat-new-dialog-mode-toggle","data-testid":"chat-new-dialog-mode-toggle",children:[t.jsx("button",{type:"button",className:`chat-new-dialog-mode-btn${p==="agent"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-agent",onClick:()=>{v("agent")},children:i("chat.newChatModeAgent","Agent")}),t.jsx("button",{type:"button",className:`chat-new-dialog-mode-btn${p==="model"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-model",onClick:()=>{v("model"),H(""),N(m=>m||R)},children:i("chat.newChatModeModel","Model")})]}),t.jsxs("form",{onSubmit:ke,children:[p==="agent"&&t.jsxs("label",{className:"chat-new-dialog-model-label",children:[i("chat.newChatModeAgent","Agent"),k?t.jsx("div",{className:"chat-new-dialog-loading",children:i("chat.loadingAgents","Loading agents...")}):g.length===0?t.jsx("div",{className:"chat-new-dialog-empty",children:i("chat.noAgentsAvailable","No agents available")}):t.jsx("div",{className:"chat-new-dialog-agent-list",children:g.map(m=>t.jsxs("button",{type:"button",className:`chat-new-dialog-agent-item${z===m.id?" chat-new-dialog-agent-item--selected":""}`,onClick:()=>H(m.id),"data-testid":`agent-option-${m.id}`,children:[t.jsx(bt,{size:16}),t.jsx("span",{className:"chat-new-dialog-agent-name",children:m.name}),t.jsx("span",{className:"chat-new-dialog-agent-role",children:m.role})]},m.id))})]}),p==="model"&&t.jsx("div",{className:"chat-new-dialog-model-dropdown","data-testid":"chat-new-dialog-model-section",children:_?t.jsx("div",{className:"chat-new-dialog-loading",children:i("chat.loadingModels","Loading models...")}):t.jsx(ja,{models:W,value:q,onChange:N,label:i("chat.newChatModeModel","Model"),placeholder:i("chat.selectModel","Select a model"),favoriteProviders:te,onToggleFavorite:ne,favoriteModels:ee,onToggleModelFavorite:V})}),t.jsxs("div",{className:"chat-new-dialog-actions",children:[t.jsx("button",{type:"button",className:"btn btn-sm",onClick:u,children:i("chat.cancel","Cancel")}),t.jsx("button",{type:"submit",className:"btn btn-sm btn-primary",disabled:ae,children:i("chat.create","Create")})]})]})]})})}const fs=s.memo(function({message:r,forcePlain:u,agentName:o,hideAssistantIdentity:i,showAssistantModelTag:p,activeModelTag:v,activeModelProvider:g,activeSessionId:k,mentionAgentsByName:z,roomContext:H,copyAction:W,onScrollToTop:y}){const{t:O}=vt("app"),_=r.role==="assistant",M=_?r.failureInfo:void 0,R=_&&(!i||!!M),q=s.useMemo(()=>{if(_)return null;const j=r.content,ee=/@([\w-]+)/g,S=[];let ne=0,V=ee.exec(j);for(;V;){const[X,ke=""]=V,ae=V.index;ae>ne&&S.push(j.slice(ne,ae));const m=ke.replace(/_/g," ").toLowerCase(),b=z.get(m);if(b){const w=!!(H&&!H.memberIds.has(b.id)),d=w?O("chat.mentionNonMember","Not a member of {{roomName}}",{roomName:H?.roomName}):void 0;S.push(t.jsxs("span",{className:`chat-mention-chip${w?" chat-mention-chip--non-member":""}`,title:d,"aria-label":d,children:["@",b.name.replace(/\s+/g,"_")]},`${b.id}-${ae}`))}else S.push(X);ne=ae+X.length,V=ee.exec(j)}return ne<j.length&&S.push(j.slice(ne)),S.length===0?j:S},[_,r.content,z,H]),N=s.useMemo(()=>{const j=r.attachments;if(!j||j.length===0)return null;const ee=r.roomId?`/api/chat/rooms/${encodeURIComponent(r.roomId)}/attachments/`:k?`/api/chat/sessions/${encodeURIComponent(k)}/attachments/`:null;return ee?t.jsx("div",{className:"chat-message-attachments",children:j.map(S=>{const ne=S.mimeType.startsWith("image/"),V=S.id||S.filename,X=`${ee}${encodeURIComponent(S.filename)}`;return ne?t.jsx("a",{className:"chat-message-attachment-link","data-testid":"chat-message-attachment",href:X,target:"_blank",rel:"noopener noreferrer",children:t.jsx("img",{className:"chat-message-attachment",src:X,alt:S.originalName})},V):t.jsxs("a",{className:"chat-message-attachment-file","data-testid":"chat-message-attachment",href:X,target:"_blank",rel:"noopener noreferrer",children:[t.jsx(wa,{size:14}),t.jsx("span",{children:S.originalName})]},V)})}):null},[r.attachments,r.roomId,k]),te=s.useMemo(()=>_?M?t.jsxs("div",{className:"chat-message-content chat-message-content--failure",children:[t.jsxs("div",{className:"chat-message-failure-summary-row",children:[t.jsx("span",{className:"status-dot status-dot--error","aria-hidden":"true"}),t.jsx("span",{className:"chat-message-failure-label",children:O("chat.responseFailed","Response failed")})]}),t.jsx("div",{className:"chat-message-failure-summary",children:M.summary}),(M.errorClass||M.code)&&t.jsxs("div",{className:"chat-message-failure-badges",children:[M.errorClass&&t.jsx("span",{className:"chat-message-failure-badge",children:M.errorClass}),M.code&&t.jsx("span",{className:"chat-message-failure-badge",children:M.code})]}),(M.detail||M.reference)&&t.jsxs("details",{className:"chat-message-failure-details",children:[t.jsxs("summary",{children:[t.jsx(Ca,{size:14,"aria-hidden":"true"}),t.jsx("span",{children:O("chat.failureDetails","Failure details")})]}),M.detail&&t.jsx("pre",{className:"chat-message-failure-detail",children:_t(M.detail)}),Oa(M.reference,O)]})]}):u?t.jsx("div",{className:"chat-message-content chat-message-content--plain",children:r.content}):t.jsx("div",{className:"chat-message-content chat-message-content--markdown",children:t.jsx(gn,{remarkPlugins:[pn],components:yn,children:r.content})}):null,[M,u,_,r.content]);return t.jsxs("div",{className:`chat-message chat-message--${r.role}${M?" chat-message--failure":""}`,"data-testid":`chat-message-${r.id}`,"data-message-id":r.id,children:[R&&t.jsxs("div",{className:"chat-message-avatar",children:[g?t.jsx(pt,{provider:g,size:"sm"}):t.jsx(bt,{size:14}),t.jsx("span",{children:o}),p&&v&&t.jsx("span",{className:"chat-model-tag",children:v})]}),_?te:t.jsx("div",{className:"chat-message-content",children:q}),_&&!M&&(W||y)&&t.jsxs("div",{className:"chat-message-actions",children:[W,y&&t.jsx("button",{type:"button",className:"btn-icon chat-message-scroll-to-top-action","aria-label":O("chat.scrollMessageToTop","Scroll message to top"),"data-testid":`chat-message-scroll-to-top-${r.id}`,onClick:()=>y(r.id),children:t.jsx(Ra,{size:14})})]}),xn(r.toolCalls,O),r.thinkingOutput&&t.jsxs("details",{className:"chat-message-thinking",children:[t.jsx("summary",{children:O("chat.thinking","Thinking")}),t.jsx("pre",{className:"chat-message-thinking-content",children:_t(r.thinkingOutput)})]}),N,t.jsx("div",{className:"chat-message-time",children:vn(r.createdAt,O)})]})});function tr({projectId:n,addToast:r,experimentalFeatures:u}){const{t:o}=vt("app");s.useEffect(()=>(Lt({view:"ChatView",trigger:ms?"route-active":"remount",projectId:n,replayAttempted:!1}),ms=!1,()=>{ms=!0,Lt({view:"ChatView",trigger:"route-inactive",projectId:n,replayAttempted:!1})}),[n]);const{activeSession:i,sessionsLoading:p,messages:v,messagesLoading:g,isStreaming:k,streamingText:z,streamingThinking:H,streamingToolCalls:W,selectSession:y,createSession:O,archiveSession:_,deleteSession:M,sendMessage:R,stopStreaming:q,pendingMessage:N,clearPendingMessage:te,loadMoreMessages:j,hasMoreMessages:ee,searchQuery:S,setSearchQuery:ne,filteredSessions:V,agentsMap:X}=Ia(n,r),[ke,ae]=s.useState(!1),m=u?.chatRooms===!0,[b,w]=s.useState(()=>{try{if(localStorage.getItem(hs)==="rooms"&&m)return"rooms"}catch{}return"direct"}),d=ra(n,r),{isUnread:we,markRead:J}=oa(n),[P,Ce]=s.useState(()=>{const e=cn(b,b==="rooms"?d.activeRoom?.id:i?.id);return ln(e)}),[$,je]=s.useState(null),[Y,Me]=s.useState(null),[De,$e]=s.useState(null),[he,be]=s.useState(!0),[ve,Fe]=s.useState(Ua),[xt,re]=s.useState(!1),{agentsMap:Ge}=gs(n),Se=s.useMemo(()=>X.size>0?X:Ge,[Ge,X]),{defaultProvider:se,defaultModelId:oe}=fn(),Le=s.useMemo(()=>({provider:se,modelId:oe}),[oe,se]),{skills:at,loading:zt}=ia(n),[_e,ze]=s.useState(!1),[rt,Ve]=s.useState(""),[We,He]=s.useState(0),[Re,Oe]=s.useState(""),[l,f]=s.useState(!1),[x,A]=s.useState(0),[G,T]=s.useState(-1),[U,B]=s.useState(!1),[I,K]=s.useState([]),[Q,F]=s.useState(!1),[Z,le]=s.useState(!1),[fe,ps]=s.useState({}),[yt,Xe]=s.useState(!1),[wt,ot]=s.useState(!1),{pushNav:bs}=ca(),[,Ct]=s.useState(!1),[wn,Cn]=s.useState({top:0,left:0}),L=la({projectId:n}),Ht=s.useCallback(e=>{if(!e||!L.mentionActive)return;const a=e.getBoundingClientRect();Cn({top:a.top-260,left:a.left+8})},[L.mentionActive]),vs=s.useRef(null),xs=s.useRef(null),ys=s.useRef(null),ws=s.useRef(null),me=s.useRef(!1),St=s.useRef(null),Cs=s.useRef(null),Ue=s.useRef(null),kt=s.useRef(0),Ot=s.useRef(null),it=s.useRef(null),Ae=s.useRef(null),ge=s.useRef(null),Ut=s.useRef(null),Nt=s.useRef(!1),Ee=s.useRef(null),de=s.useRef(null),Ss=s.useRef(null),ks=s.useRef([]),Ye=s.useRef(0),ct=s.useRef(new Map),Bt=s.useRef(!1),Je=s.useRef(null),Ns=da(),E=Ns==="mobile",lt=Ns==="tablet";s.useEffect(()=>{i?.id&&J("direct",i.id,i.lastMessageAt??i.updatedAt)},[i?.id,i?.lastMessageAt,i?.updatedAt,J]),s.useEffect(()=>{d.activeRoom?.id&&J("room",d.activeRoom.id,d.activeRoom.updatedAt)},[d.activeRoom?.id,d.activeRoom?.updatedAt,J]),s.useEffect(()=>{if(!i?.id||v.length===0)return;const e=v[v.length-1];J("direct",i.id,e?.createdAt??i.lastMessageAt??i.updatedAt)},[i?.id,i?.lastMessageAt,i?.updatedAt,J,v]),s.useEffect(()=>{if(!d.activeRoom?.id||d.messages.length===0)return;const e=d.messages[d.messages.length-1];J("room",d.activeRoom.id,e?.createdAt??d.activeRoom.updatedAt)},[J,d.activeRoom?.id,d.activeRoom?.updatedAt,d.messages]),s.useEffect(()=>{try{const e=localStorage.getItem(on);if(!e)return;const a=Number.parseInt(e,10);if(Number.isNaN(a))return;const c=Math.max(Dt,Math.min($t,a));Fe(c)}catch{}},[]),s.useEffect(()=>{try{const e=localStorage.getItem(hs);if(e==="direct"){w("direct");return}e==="rooms"&&m&&w("rooms")}catch{}},[m]),s.useEffect(()=>{if(!m&&b==="rooms"){w("direct");return}try{localStorage.setItem(hs,b)}catch{}},[m,b]);const pe=cn(b,b==="rooms"?d.activeRoom?.id:i?.id),Kt=s.useRef(pe);s.useEffect(()=>{pe!==Kt.current&&(Kt.current=pe,Ce(ln(pe)))},[pe]),s.useEffect(()=>{if(!(!pe||Kt.current!==pe))try{if(P){localStorage.setItem(pe,P);return}localStorage.removeItem(pe)}catch{}},[pe,P]);const ie=m&&b==="rooms"&&!!d.activeRoom,{keyboardOverlap:js,keyboardOpen:Qe}=ua({enabled:(E||lt)&&(!!i||ie),allowNonMobileViewport:lt}),dt=lt&&Qe;s.useEffect(()=>{if(!lt){Je.current=null;return}if(Qe){be(e=>(Je.current===null&&(Je.current=e),e&&!1));return}if(Je.current!==null){const e=Je.current;Je.current=null,be(e)}},[lt,Qe]);const xe=s.useMemo(()=>{const e=rt.trim().toLowerCase();return(e?at.filter(c=>c.name.toLowerCase().includes(e)):at).slice(0,10)},[at,rt]),Ze=s.useMemo(()=>Array.from(Se.values()),[Se]),Te=s.useMemo(()=>!m||b!=="rooms"||!d.activeRoom?null:{roomId:d.activeRoom.id,roomName:d.activeRoom.name,memberIds:new Set(d.activeRoomMembers.map(e=>e.agentId))},[m,b,d.activeRoom,d.activeRoomMembers]),qe=s.useMemo(()=>{const e=Ze.filter(h=>ma(h.name,Re));if(!Te)return e;const a=e.filter(h=>Te.memberIds.has(h.id));if(Re.trim().length===0)return a;const c=e.filter(h=>!Te.memberIds.has(h.id));return[...a,...c]},[Ze,Re,Te]),Gt=s.useMemo(()=>{const e=new Map;for(const a of Ze)e.set(a.name.toLowerCase(),a);return e},[Ze]),Sn=s.useMemo(()=>xe.map(e=>e.id).join("\0"),[xe]);s.useEffect(()=>{He(0)},[Sn]),s.useEffect(()=>{A(0)},[Re,l]),s.useEffect(()=>()=>{Ae.current!==null&&window.clearTimeout(Ae.current)},[]),s.useEffect(()=>{const e=xs.current;if(!e||!ee||g)return;const a=new IntersectionObserver(c=>{c[0].isIntersecting&&j()},{threshold:.1});return a.observe(e),()=>a.disconnect()},[ee,g,j]);const et=s.useCallback(()=>ie?d.activeRoom?.id??null:i?.id??null,[ie,d.activeRoom?.id,i?.id]),Ms=s.useCallback((e,a)=>typeof CSS<"u"&&typeof CSS.escape=="function"?e.querySelector(`.chat-message[data-message-id="${CSS.escape(a)}"]`):e.querySelector(`.chat-message[data-message-id="${a.replace(/"/g,'\\"')}"]`),[]),jt=s.useCallback(()=>{const e=ge.current,a=et();if(!e||!a)return;const c=e.scrollTop,h=e.querySelectorAll(".chat-message[data-message-id]"),C=Array.from(h).find(ce=>ce.offsetTop+ce.offsetHeight>=c)??h[0]??null,D=C?.getAttribute("data-message-id")??null,ue=C?C.offsetTop-c:0;it.current={threadId:a,scrollTop:c,scrollHeight:e.scrollHeight,clientHeight:e.clientHeight,anchorMessageId:D,anchorOffset:ue,wasPinnedBefore:!me.current,capturedAtMs:typeof performance<"u"?performance.now():Date.now()}},[et]),Rs=s.useCallback(()=>{const e=ge.current;if(!e)return;const c=e.scrollTop+e.clientHeight>=e.scrollHeight-50;le(!c),me.current=!c,jt()},[jt]),Ie=s.useCallback((e,a)=>{if(!e.isConnected||!a?.force&&me.current)return;let c=0,h=0,C=-1;const D=6,ue=()=>{if(e.isConnected&&!(!a?.force&&me.current)){if(e.scrollTop=e.scrollHeight,e.scrollHeight===C?h+=1:(h=0,C=e.scrollHeight),c+=1,c>=D||h>=2){le(!1),me.current=!1;return}window.requestAnimationFrame(ue)}};ue()},[]),ut=ie?d.messages:v;s.useLayoutEffect(()=>{const e=ge.current,a=et(),c=it.current;if(!e||!a||!c||c.threadId!==a||c.wasPinnedBefore)return;const h=(typeof performance<"u"?performance.now():Date.now())-c.capturedAtMs,C=e.scrollHeight>e.clientHeight,D=h>3e3,ue=c.scrollTop<=0&&c.anchorOffset<=0&&C;if(!me.current||D||ue){it.current=null;return}let ce=c.scrollTop;if(c.anchorMessageId){const Pe=Ms(e,c.anchorMessageId);Pe?ce=Pe.offsetTop-c.anchorOffset:ce=c.scrollTop+(e.scrollHeight-c.scrollHeight)}else ce=c.scrollTop+(e.scrollHeight-c.scrollHeight);e.scrollTop=Math.max(0,ce),me.current=!0,le(!0),it.current=null},[ut,et,Ms]);const Vt=s.useCallback(e=>{},[ut.length,ie]),Ne=s.useCallback(e=>{Vt(e);const a=ge.current;a&&(it.current=null,me.current=!1,Ie(a))},[Ie,Vt]);s.useLayoutEffect(()=>{Ue.current!==null&&(window.clearTimeout(Ue.current),Ue.current=null);const e=ie?d.activeRoom?.id??null:i?.id??null;if(!e){St.current=null;return}const a={threadId:e,loaded:ie?!d.messagesLoading:!g,hasMessages:ie?d.messages.length>0:v.length>0},c=St.current,h=c?.threadId!==e,C=c?.threadId===e&&!c.loaded&&a.loaded,D=c?.threadId===e&&!c.hasMessages&&a.hasMessages;if(!(c===null||h||C||D))return;const ce=ge.current;if(ce)return Vt(h?"thread-change":C?"finished-loading":D?"first-messages":"mount"),Ie(ce,{force:!0}),ie||(Ue.current=window.setTimeout(()=>{if(Ue.current=null,me.current)return;const Pe=ge.current;Pe&&Ie(Pe)},250)),St.current=a,()=>{Ue.current!==null&&(window.clearTimeout(Ue.current),Ue.current=null)}},[ie,d.activeRoom?.id,d.messages.length,d.messagesLoading,i?.id,v.length,g,Ie]),s.useEffect(()=>{!k||me.current||Ne("streaming")},[k,z,H,Ne]),s.useEffect(()=>{const e=et();if(!e){kt.current=0,Ot.current=null;return}if(Ot.current!==e){Ot.current=e,kt.current=ut.length;return}const a=kt.current,c=ut.length,h=c>a,C=!me.current;kt.current=c,h&&C&&Ne("new-message")},[ut,et,Ne]),s.useEffect(()=>{js<=0||!ge.current||Ne("keyboard")},[js,Ne]),ha(E&&Qe),s.useLayoutEffect(()=>{if(!E||!i&&!ie||typeof window>"u")return;const e=Ut.current,a=window.visualViewport;if(!e||!a)return;const c=C=>{if(!(C instanceof HTMLElement))return!1;if(C.tagName==="TEXTAREA")return!0;if(C.tagName!=="INPUT")return!1;const D=C.type.toLowerCase();return["","text","search","email","url","tel","password","number"].includes(D)},h=()=>{if(Nt.current){e.classList.remove("chat-thread--keyboard-active");return}const C=Math.max(0,window.innerHeight-a.offsetTop-a.height),D=a.offsetTop||0;e.style.setProperty("--vv-height",`${a.height}px`),e.style.setProperty("--vv-offset-top",`${D}px`),e.style.setProperty("--keyboard-overlap",`${C}px`);const ue=(C>0||D>0)&&c(document.activeElement);e.classList.toggle("chat-thread--keyboard-active",ue)};return h(),a.addEventListener("resize",h),a.addEventListener("scroll",h),document.addEventListener("focusin",h),document.addEventListener("focusout",h),window.addEventListener("pageshow",h),document.addEventListener("visibilitychange",h),()=>{a.removeEventListener("resize",h),a.removeEventListener("scroll",h),document.removeEventListener("focusin",h),document.removeEventListener("focusout",h),window.removeEventListener("pageshow",h),document.removeEventListener("visibilitychange",h),e.classList.remove("chat-thread--keyboard-active")}},[i,E,ie]),s.useEffect(()=>{const e=()=>je(null);if($)return document.addEventListener("click",e),()=>document.removeEventListener("click",e)},[$]),s.useEffect(()=>{if(!E||!Qe)return;const e=a=>{a.target?.closest(".chat-messages")||a.preventDefault()};return document.addEventListener("touchmove",e,{passive:!1}),()=>{document.removeEventListener("touchmove",e)}},[E,Qe]),s.useEffect(()=>{if(!E||!i)return;const e=()=>{const a=de.current;a&&document.activeElement===a&&(a.blur(),window.setTimeout(()=>{a.focus({preventScroll:!0})},0))};return document.addEventListener("visibilitychange",e),window.addEventListener("pageshow",e),()=>{document.removeEventListener("visibilitychange",e),window.removeEventListener("pageshow",e)}},[E,i]),s.useEffect(()=>{const e=Cs.current;if(Cs.current=b,b==="rooms"&&!d.activeRoom){St.current=null;return}if(!(b==="direct"&&(e===null||e==="rooms"))&&!(b==="rooms"&&(e===null||e==="direct")))return;const h=ge.current;h&&(Ie(h,{force:!0}),me.current=!1,le(!1))},[b,d.activeRoom,Ie]),s.useEffect(()=>{if(!i&&!ie||ie&&!E)return;const e=()=>{const c=!me.current;jt(),c&&E&&ge.current&&Ne("visibility-restore")},a=()=>{document.visibilityState==="visible"&&e()};return document.addEventListener("visibilitychange",a),window.addEventListener("pageshow",e),()=>{document.removeEventListener("visibilitychange",a),window.removeEventListener("pageshow",e)}},[E,i,ie,jt,Ne]),s.useEffect(()=>{if(ie||typeof ResizeObserver>"u")return;const e=ge.current;if(!e)return;const a=new ResizeObserver(()=>{me.current||Ie(e)});return a.observe(e),()=>{a.disconnect()}},[ie,Ie,i?.id,b]),s.useEffect(()=>{ks.current=I},[I]),s.useEffect(()=>()=>{for(const e of ks.current)e.previewUrl&&URL.revokeObjectURL(e.previewUrl);for(const e of ct.current.values())window.clearTimeout(e);ct.current.clear()},[]);const Mt=s.useCallback(e=>{if(!e||e.length===0)return;const a=[];for(const c of Array.from(e)){if(!Ka.includes(c.type))continue;const h=c.type.startsWith("image/");a.push({file:c,previewUrl:h?URL.createObjectURL(c):""})}a.length>0&&K(c=>[...c,...a])},[]),kn=s.useCallback(e=>{K(a=>{const c=a[e];return c?.previewUrl&&URL.revokeObjectURL(c.previewUrl),a.filter((h,C)=>C!==e)})},[]),Nn=s.useCallback(e=>{const a=e.clipboardData?.files;if(!a||a.length===0)return;const c=Array.from(a).filter(h=>h.type.startsWith("image/"));c.length!==0&&Mt(c)},[Mt]),jn=s.useCallback(async e=>{try{await O(e),ae(!1),E&&be(!1)}catch{r(o("chat.failedToCreateSession","Failed to create chat session"),"error")}},[O,r,E]),ye=s.useCallback(e=>{const a=e??de.current;a&&(a.style.height="auto",a.style.height=`${La(a.scrollHeight)}px`,a.style.overflowY=Fa(a.scrollHeight))},[]),As=s.useCallback(e=>{de.current=e,e&&ye(e)},[ye]);s.useLayoutEffect(()=>{ye()},[b,P,i?.id,d.activeRoom?.id,ye]);const tt=s.useCallback(()=>{if(Ce(""),pe)try{localStorage.removeItem(pe)}catch{}ze(!1),Ve(""),f(!1),Oe(""),T(-1),K(e=>{for(const a of e)a.previewUrl&&URL.revokeObjectURL(a.previewUrl);return[]})},[pe]),Wt=s.useCallback(()=>{const e=P.trim(),a=I.map(c=>c.file);if(!(!e&&a.length===0||!i)){if(e==="/clear"||e==="/new"){tt(),te(),q(),O({agentId:i.agentId,modelProvider:i.modelProvider??void 0,modelId:i.modelId??void 0}).catch(()=>{r(o("chat.failedToClearConversation","Failed to clear conversation"),"error")});return}tt(),R(e,a)}},[P,I,i,tt,q,te,O,r,R]),qt=s.useCallback(async()=>{const e=P.trim();if(e){if(m&&b==="rooms"){if(!d.activeRoom)return;if(e==="/clear"||e==="/new"){tt();try{await d.clearRoom(d.activeRoom.id)}catch{r(o("chat.failedToClearRoomConversation","Failed to clear room conversation"),"error")}return}if(Bt.current)return;Bt.current=!0;const a=P;tt();try{await d.sendRoomMessage(e,{files:I.map(c=>c.file)})}catch(c){if(c instanceof fa){const C=c.message.trim()?c.message:o("chat.messageSentButReplyFailed","Message sent, but assistant reply failed");r(o("chat.messageSentButReplyFailedDetail","Message sent, but assistant reply failed: {{detail}}",{detail:C}),"error");return}Ce(a);const h=c instanceof Error&&c.message.trim()?c.message:o("chat.failedToSendRoomMessage","Failed to send room message");r(h,"error")}finally{Bt.current=!1}return}Wt()}},[P,I,m,b,d,d.clearRoom,tt,r,Wt]),Xt=s.useCallback(e=>{Ce(a=>{const c=dn(a);if(!c)return a;const h=`/skill:${e.name} `,C=a.slice(0,c.start)+h+a.slice(c.end);return window.requestAnimationFrame(()=>{de.current&&(ye(de.current),de.current.focus())}),C}),ze(!1),Ve(""),He(0)},[ye]),Rt=s.useCallback(e=>{const a=de.current;if(!a||G<0)return;const c=a.selectionStart??Ye.current,h=a.selectionEnd??c,C=Math.max(c,h),D=Math.min(G,C),ce=`${`@${e.name.replace(/\s+/g,"_")}`} `,Pe=P.slice(0,D)+ce+P.slice(C),st=D+ce.length;Ce(Pe),f(!1),Oe(""),A(0),T(-1),window.requestAnimationFrame(()=>{de.current&&(ye(de.current),de.current.focus(),de.current.setSelectionRange(st,st))})},[G,P,ye]),mt=s.useCallback((e,a)=>{const h=de.current?.selectionStart??Ye.current,C=P.lastIndexOf("#",h),D=C>=0?C+a.length:e.length;Ce(e),L.dismissMention(),Ct(!1),window.requestAnimationFrame(()=>{de.current&&(ye(de.current),de.current.focus(),de.current.setSelectionRange(D,D))})},[L,P,ye]),Es=s.useCallback(e=>{if(Ye.current=e.currentTarget.selectionStart??Ye.current,L.mentionActive&&L.combinedItems.length>0){if(L.handleKeyDown(e,P),e.key==="Enter"||e.key==="Tab"){const a=L.combinedItems[L.selectedIndex];a?.kind==="task"?mt(L.selectTask(a.task,P),`#${a.task.id}`):a?.kind==="file"&&mt(L.selectFile(a.file,P),`#${a.file.path}`)}return}if(l&&e.key==="ArrowDown"){e.preventDefault(),qe.length>0&&A(a=>(a+1)%qe.length);return}if(l&&e.key==="ArrowUp"){e.preventDefault(),qe.length>0&&A(a=>a===0?qe.length-1:a-1);return}if(l&&e.key==="Enter"){e.preventDefault();const a=qe[x]??qe[0];a&&Rt(a);return}if(l&&e.key==="Escape"){e.preventDefault(),f(!1),Oe(""),T(-1);return}if(_e&&e.key==="ArrowDown"){e.preventDefault(),xe.length>0&&He(a=>(a+1)%xe.length);return}if(_e&&e.key==="ArrowUp"){e.preventDefault(),xe.length>0&&He(a=>a===0?xe.length-1:a-1);return}if(_e&&(e.key==="Enter"||e.key==="Tab")&&xe.length>0){e.preventDefault();const a=xe[We]??xe[0];a&&Xt(a);return}if(_e&&e.key==="Escape"){e.preventDefault(),ze(!1);return}e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),qt())},[l,qe,x,Rt,_e,xe,We,Xt,qt,L,mt,P]),At=s.useCallback((e,a)=>{const c=Ga(e,a);if(c){f(!0),Oe(c.filter),T(c.start);return}f(!1),Oe(""),T(-1)},[]),Ts=s.useCallback(e=>{const a=e.target,c=a.value,h=a.selectionStart??c.length;ye(a),Ye.current=h,Ce(c);const C=dn(c);C?(ze(!0),Ve(C.filter)):(ze(!1),Ve("")),At(c,h),L.detectMention(c,h),Ct(L.mentionActive),L.mentionActive&&Ht(a)},[At,ye]),Et=s.useCallback(e=>{const a=e.currentTarget,c=a.selectionStart??a.value.length;Ye.current=c,At(a.value,c),L.detectMention(a.value,c),Ct(L.mentionActive),L.mentionActive&&Ht(a)},[At,L,Ht]),Is=s.useCallback(e=>{e.key!=="Escape"&&Et(e)},[Et]),Ps=s.useCallback(()=>{typeof window<"u"&&window.innerWidth<=768&&(Nt.current=!0,Ee.current!==null&&window.clearTimeout(Ee.current),Ee.current=window.setTimeout(()=>{Nt.current=!1,Ee.current=null},450)),Ae.current!==null&&window.clearTimeout(Ae.current),Ae.current=window.setTimeout(()=>{ze(!1),f(!1),Oe(""),T(-1),Ct(!1),L.dismissMention(),Ae.current=null},120)},[L]),Ds=s.useCallback(()=>{Nt.current=!1,Ee.current!==null&&(window.clearTimeout(Ee.current),Ee.current=null),Ae.current!==null&&(window.clearTimeout(Ae.current),Ae.current=null),typeof window<"u"&&window.innerWidth<=768&&queueMicrotask(()=>{(window.scrollY!==0||window.scrollX!==0)&&window.scrollTo(0,0)})},[]);s.useEffect(()=>()=>{Ee.current!==null&&window.clearTimeout(Ee.current)},[]);const Mn=s.useCallback(async e=>{je(null);try{await _(e),r(o("chat.conversationArchived","Conversation archived"),"success")}catch{r(o("chat.failedToArchiveConversation","Failed to archive conversation"),"error")}},[_,r]),Rn=s.useCallback(async e=>{Me(null),je(null);try{await M(e),r(o("chat.conversationDeleted","Conversation deleted"),"success")}catch{r(o("chat.failedToDeleteConversation","Failed to delete conversation"),"error")}},[M,r]),ht=s.useCallback(e=>{try{localStorage.setItem(on,String(e))}catch{}},[]),An=s.useCallback(e=>{if(E||dt)return;e.preventDefault(),e.stopPropagation();const a=e.currentTarget;typeof a.setPointerCapture=="function"&&a.setPointerCapture(e.pointerId);const c=e.clientX,h=ve;let C=h;document.body.style.userSelect="none";const D=ce=>{const Pe=ce.clientX-c,st=Math.max(Dt,Math.min($t,h+Pe));C=st,Fe(st),ht(st)},ue=ce=>{typeof a.releasePointerCapture=="function"&&a.releasePointerCapture(ce.pointerId),document.body.style.userSelect="",document.removeEventListener("pointermove",D),document.removeEventListener("pointerup",ue),ht(C)};document.addEventListener("pointermove",D),document.addEventListener("pointerup",ue)},[E,ht,ve,dt]),En=s.useCallback(e=>{if(E||dt||e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;e.preventDefault();const a=e.shiftKey?50:10,c=e.key==="ArrowLeft"?-a:a,h=Math.max(Dt,Math.min($t,ve+c));Fe(h),ht(h)},[E,ht,ve,dt]),$s=s.useCallback(e=>{const a=V.find(c=>c.id===e);J("direct",e,a?.lastMessageAt??a?.updatedAt),y(e),Xe(!1),E&&be(!1)},[V,E,J,y]),Yt=s.useCallback(()=>{y(""),be(!0),Xe(!1)},[y]),Jt=s.useCallback(()=>{d.selectRoom(null),be(!0),Xe(!1)},[d]),Tn=()=>t.jsxs("div",{className:"chat-empty-state",children:[t.jsx(hn,{size:48,strokeWidth:1.5}),t.jsx("h2",{children:o("chat.startNewConversation","Start a new conversation")}),t.jsxs("button",{className:"btn btn-primary",onClick:()=>ae(!0),children:[t.jsx(gt,{size:16}),o("chat.newChat","New Chat")]})]}),Qt=un(i,i?.agentId?Se.get(i.agentId)??null:null,Le),Be=rn(Qt?.provider,Qt?.modelId),Ke=Qt?.provider??null,Zt=!!(i||k||v.length>0),Tt=b==="rooms"?ie:!!i,Fs=s.useRef(Tt);s.useEffect(()=>{const e=Fs.current;Fs.current=Tt,E&&(e||!Tt||bs({type:"view",revert:b==="rooms"?Jt:Yt}))},[b,Yt,Jt,Tt,E,bs]);const es=i?.agentId===nt?Be??"Fusion":i?.title||Se.get(i?.agentId??"")?.name||i?.agentId||"Chat",Ls=!!(Be&&Be!==es),In=E&&b==="direct"&&!!i,ts=Se.get(i?.agentId??"")?.name||(i?.agentId===nt?Be??"Fusion":i?.agentId?.slice(0,30)??"Fusion"),ss=!1,ns=i?.agentId===nt,Pn=N.length>50?`${N.slice(0,50)}…`:N,Dn=s.useCallback(()=>{B(e=>!e)},[]);s.useEffect(()=>{if(!yt)return;const e=a=>{ys.current?.contains(a.target)||Xe(!1)};return document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[yt]),s.useEffect(()=>{if(!wt)return;const e=c=>{ws.current?.contains(c.target)||ot(!1)},a=c=>{c.key==="Escape"&&ot(!1)};return document.addEventListener("mousedown",e),document.addEventListener("keydown",a),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("keydown",a)}},[wt]),s.useEffect(()=>{(!E||b!=="direct"||he)&&Xe(!1)},[E,b,he]),s.useEffect(()=>{ot(!1)},[d.activeRoom?.id]);const as=s.useCallback((e,a)=>{const c=ct.current.get(e);c&&window.clearTimeout(c),ps(C=>({...C,[e]:a}));const h=window.setTimeout(()=>{ps(C=>{const{[e]:D,...ue}=C;return ue}),ct.current.delete(e)},2e3);ct.current.set(e,h)},[]),_s=s.useCallback(async(e,a)=>{try{if(!navigator.clipboard?.writeText)throw new Error("Clipboard API unavailable");await navigator.clipboard.writeText(a),as(e,"success")}catch{as(e,"error")}},[as]),$n=s.useCallback((e,a=!1)=>a?t.jsx("div",{className:"chat-message-content chat-message-content--plain",children:e}):t.jsx("div",{className:"chat-message-content chat-message-content--markdown",children:t.jsx(gn,{remarkPlugins:[pn],components:yn,children:e})}),[]),rs=i?.agentId===nt,os=s.useCallback((e,a,c)=>t.jsx("button",{type:"button",className:`btn-icon chat-message-copy-action${fe[e]==="success"?" chat-message-copy-action--success":""}${fe[e]==="error"?" chat-message-copy-action--error":""}`,"data-testid":c??`chat-copy-response-${e}`,"aria-label":fe[e]==="success"?o("chat.responseCopied","Response copied"):fe[e]==="error"?o("chat.copyFailed","Copy failed"):o("chat.copyResponse","Copy response"),onClick:()=>{_s(e,a)},children:fe[e]==="success"?t.jsx(ga,{size:14}):t.jsx(pa,{size:14})}),[fe,_s]),is=s.useCallback(e=>{const a=ge.current;if(!a)return;const c=`[data-testid="chat-message-${e}"]`,h=a.querySelector(c);if(!h)return;const C=h.getBoundingClientRect().top-a.getBoundingClientRect().top+a.scrollTop,D=typeof window<"u"&&window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;a.scrollTo({top:C,behavior:D?"auto":"smooth"})},[]),zs=i?.cliExecutorAdapterId??null,Fn=!!zs,Ln=zs==="generic"?"generic":"hybrid",_n=i?.cliSessionFile||i?.id||"",Hs=()=>t.jsxs("div",{className:"chat-messages",ref:ge,onScroll:Rs,children:[t.jsx("div",{ref:xs,className:"chat-load-more-sentinel",children:ee&&g&&t.jsx("div",{className:"chat-loading-older",children:o("chat.loadingOlderMessages","Loading older messages…")})}),k?t.jsxs(t.Fragment,{children:[v.map(e=>t.jsx(fs,{message:e,forcePlain:U,agentName:ts,hideAssistantIdentity:ns,showAssistantModelTag:ss,activeModelTag:Be,activeModelProvider:Ke,activeSessionId:i?.id??null,mentionAgentsByName:Gt,roomContext:null,copyAction:rs&&e.role==="assistant"?os(e.id,e.content):void 0,onScrollToTop:is},e.id)),t.jsxs("div",{className:"chat-message chat-message--assistant chat-message--streaming",children:[!ns&&t.jsxs("div",{className:"chat-message-avatar",children:[Ke?t.jsx(pt,{provider:Ke,size:"sm"}):t.jsx(bt,{size:14}),t.jsx("span",{children:ts}),ss]}),z?$n(z,U):t.jsx("div",{className:"chat-message-content chat-message-content--waiting",children:H?o("chat.thinkingStatus","Thinking…"):o("chat.connectingStatus","Connecting…")}),rs&&z&&os("__streaming__",z,"chat-copy-response-streaming"),xn(W,o),H&&t.jsxs("details",{className:"chat-message-thinking",children:[t.jsx("summary",{children:o("chat.thinking","Thinking")}),t.jsx("pre",{className:"chat-message-thinking-content",children:_t(H)})]}),t.jsxs("div",{className:"chat-typing-indicator",children:[t.jsx("span",{}),t.jsx("span",{}),t.jsx("span",{})]})]})]}):g?t.jsx("div",{className:"chat-empty-state",children:o("chat.loadingMessages","Loading messages...")}):v.length===0&&!i?Tn():v.length===0&&i?t.jsx("div",{className:"chat-empty-state",children:o("chat.noMessagesYet","No messages yet. Start the conversation!")}):t.jsx(t.Fragment,{children:v.map(e=>t.jsx(fs,{message:e,forcePlain:U,agentName:ts,hideAssistantIdentity:ns,showAssistantModelTag:ss,activeModelTag:Be,activeModelProvider:Ke,activeSessionId:i?.id??null,mentionAgentsByName:Gt,roomContext:null,copyAction:rs&&e.role==="assistant"?os(e.id,e.content):void 0,onScrollToTop:is},e.id))}),t.jsx("div",{ref:vs})]}),Os=()=>t.jsxs("div",{className:"chat-input-area",children:[t.jsx("input",{ref:Ss,type:"file",accept:"image/*,.txt,.json,.yaml,.yml,.log,.csv,.xml,.md",multiple:!0,style:{display:"none"},onChange:e=>{Mt(e.target.files),e.target.value=""}}),_e&&t.jsx("div",{className:"chat-skill-menu","data-testid":"chat-skill-menu",role:"listbox","aria-label":o("chat.skillSuggestions","Skill suggestions"),children:zt?t.jsx("div",{className:"chat-skill-menu-empty",children:o("chat.loadingSkills","Loading skills…")}):xe.length===0?t.jsx("div",{className:"chat-skill-menu-empty",children:rt?o("chat.noSkillsFound","No skills found"):o("chat.noSkillsAvailable","No skills available")}):xe.map((e,a)=>t.jsxs("button",{type:"button",role:"option","aria-selected":a===We,className:`chat-skill-menu-item${a===We?" chat-skill-menu-item--highlighted":""}`,onMouseDown:c=>c.preventDefault(),onMouseEnter:()=>He(a),onClick:()=>Xt(e),children:[t.jsx("span",{className:"chat-skill-menu-item-name",children:e.name}),t.jsx("span",{className:"chat-skill-menu-item-description",title:e.relativePath,children:e.relativePath})]},e.id))}),I.length>0&&t.jsx("div",{className:"chat-attachment-previews","data-testid":"chat-attachment-previews",children:I.map((e,a)=>t.jsxs("div",{className:"chat-attachment-preview","data-testid":`chat-attachment-preview-${a}`,children:[e.previewUrl?t.jsx("img",{src:e.previewUrl,alt:e.file.name}):t.jsx("span",{className:"chat-attachment-preview-name",children:e.file.name}),t.jsx("button",{type:"button",className:"chat-attachment-remove",onClick:()=>kn(a),"data-testid":`chat-attachment-remove-${a}`,"aria-label":`Remove ${e.file.name}`,children:"×"})]},e.previewUrl||`${e.file.name}-${a}`))}),t.jsxs("div",{className:"chat-input-row",children:[t.jsx("button",{type:"button",className:"btn-icon chat-attach-btn","data-testid":"chat-attach-btn","aria-label":o("chat.attachFiles","Attach files"),onClick:()=>Ss.current?.click(),children:t.jsx(Sa,{size:16})}),t.jsxs("div",{className:`chat-input-wrapper${Q?" chat-input-wrapper--dragover":""}`,onDragOver:e=>{e.preventDefault(),F(!0)},onDragLeave:()=>F(!1),onDrop:e=>{e.preventDefault(),F(!1),Mt(e.dataTransfer.files)},children:[t.jsx("textarea",{ref:As,className:"chat-input-textarea",placeholder:o("chat.typeMessage","Type a message..."),value:P,onChange:Ts,onKeyDown:Es,onKeyUp:Is,onClick:Et,onBlur:Ps,onFocus:Ds,onPaste:Nn,onTouchStart:e=>{typeof window>"u"||window.innerWidth>768||Xs()&&document.activeElement!==e.currentTarget&&(e.preventDefault(),e.currentTarget.focus({preventScroll:!0}))},rows:1,"data-testid":"chat-input"}),t.jsx(Ys,{agents:Ze,filter:Re,highlightedIndex:x,visible:l,onSelect:Rt,position:"below",roomMemberIds:Te?.memberIds,roomName:Te?.roomName}),t.jsx(ka,{visible:L.mentionActive&&!l,position:wn,tasks:L.tasks,files:L.files,selectedIndex:L.selectedIndex,onSelectTask:e=>{mt(L.selectTask(e,P),`#${e.id}`)},onSelectFile:e=>{mt(L.selectFile(e,P),`#${e.path}`)},loading:L.loading}),N&&t.jsxs("div",{className:"chat-pending-message","data-testid":"chat-pending-indicator",children:[t.jsx("span",{children:o("chat.queuedMessage","Queued: {{preview}}",{preview:Pn})}),t.jsx("button",{type:"button",className:"chat-pending-message-dismiss","aria-label":o("chat.dismissQueuedMessage","Dismiss queued message"),"data-testid":"chat-pending-dismiss",onClick:te,children:"×"})]})]}),k?t.jsx("button",{className:"chat-input-stop",onClick:q,"aria-label":o("chat.stopGeneration","Stop generation"),"data-testid":"chat-stop-btn",children:t.jsx(Na,{size:14})}):t.jsx("button",{type:"button",className:"chat-input-send",onPointerDown:e=>{e.pointerType&&e.pointerType!=="mouse"&&e.preventDefault()},onMouseDown:e=>{e.preventDefault()},onClick:()=>{Wt()},disabled:!P.trim()&&I.length===0,"data-testid":"chat-send-btn",style:{touchAction:"manipulation"},children:t.jsx(Js,{size:16})})]})]});return t.jsxs("div",{className:"chat-view",children:[t.jsxs("div",{className:`chat-sidebar${he?"":" chat-sidebar--hidden"}`,style:E?void 0:{width:`${ve}px`},children:[m&&t.jsxs("div",{className:"chat-sidebar-scope-toggle",role:"tablist","data-testid":"chat-sidebar-scope-toggle",children:[t.jsx("button",{type:"button",role:"tab",className:`chat-sidebar-scope-btn${b==="direct"?" chat-sidebar-scope-btn--active":""}`,"aria-selected":b==="direct","data-testid":"chat-sidebar-scope-direct",onClick:()=>w("direct"),children:o("chat.scopeDirect","Direct")}),t.jsx("button",{type:"button",role:"tab",className:`chat-sidebar-scope-btn${b==="rooms"?" chat-sidebar-scope-btn--active":""}`,"aria-selected":b==="rooms","data-testid":"chat-sidebar-scope-rooms",onClick:()=>w("rooms"),children:o("chat.scopeRooms","Rooms")})]}),!m||b==="direct"?t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"chat-sidebar-search-container",children:t.jsxs("div",{className:"chat-sidebar-search-wrapper",children:[t.jsx(ba,{size:14,className:"chat-sidebar-search-icon"}),t.jsx("input",{type:"text",className:"chat-sidebar-search",placeholder:o("chat.searchConversations","Search conversations..."),value:S,onChange:e=>ne(e.target.value),"data-testid":"chat-search-input"})]})}),t.jsx("div",{className:"chat-session-list chat-sidebar-list",children:p?t.jsx("div",{className:"chat-empty-state chat-empty-state--padded",children:o("chat.loadingConversations","Loading...")}):V.length===0?t.jsx("div",{className:"chat-empty-state chat-empty-state--padded",children:o("chat.noConversationsYet","No conversations yet")}):V.map(e=>{const a=i?.id===e.id,c=!a&&we("direct",e.id,e.lastMessageAt??e.updatedAt),h=un(e,Se.get(e.agentId)??null,Le),C=rn(h?.provider,h?.modelId)??"Fusion";return t.jsxs("div",{className:`chat-session-item${a?" chat-session-item--active":""}`,onClick:()=>$s(e.id),onContextMenu:D=>{D.preventDefault(),je({sessionId:e.id,x:D.clientX,y:D.clientY})},"data-testid":`chat-session-${e.id}`,children:[t.jsx("button",{className:"chat-session-delete-btn",onClick:D=>{D.stopPropagation(),Me(e.id)},"data-testid":"chat-session-delete-btn","aria-label":o("chat.deleteConversation","Delete conversation"),children:t.jsx(ls,{size:14})}),t.jsxs("div",{className:"chat-session-title",children:[e.title||o("chat.untitledSession","Untitled"),c?t.jsx("span",{className:"chat-unread-dot","data-testid":`chat-unread-dot-${e.id}`,"aria-label":o("chat.unreadMessages","Unread messages")}):null]}),t.jsx("div",{className:"chat-session-preview",children:e.lastMessagePreview||o("chat.noMessages","No messages")}),t.jsxs("div",{className:"chat-session-meta",children:[t.jsxs("span",{className:"chat-session-meta-model",children:[h?.provider?t.jsx(pt,{provider:h.provider,size:"sm"}):null,t.jsx("span",{children:Se.get(e.agentId)?.name||(e.agentId===nt?C:e.agentId.slice(0,30))})]}),t.jsx("span",{children:e.updatedAt?vn(e.updatedAt,o):""})]})]},e.id)})})]}):t.jsxs("div",{className:"chat-sidebar-rooms","data-testid":"chat-sidebar-rooms",children:[!E&&t.jsx("div",{className:"chat-sidebar-rooms-header","data-testid":"chat-sidebar-rooms-header",children:t.jsxs("button",{type:"button",className:"btn btn-sm btn-primary","data-testid":"chat-create-room-btn",onClick:()=>re(!0),children:[t.jsx(gt,{size:14}),o("chat.createRoom","Create room")]})}),d.rooms.length===0?t.jsx("div",{className:"chat-sidebar-rooms-empty","data-testid":"chat-sidebar-rooms-empty",children:o("chat.noRoomsYet","No rooms yet.")}):t.jsx("div",{className:"chat-session-list chat-sidebar-list",children:d.rooms.map(e=>{const a=d.activeRoom?.id===e.id,c=!a&&we("room",e.id,e.updatedAt);return t.jsxs("div",{role:"button",tabIndex:0,className:`chat-room-item${a?" chat-room-item--active":""}`,"data-testid":`chat-room-item-${e.slug}`,onClick:()=>{J("room",e.id,e.updatedAt),d.selectRoom(e.id),E&&be(!1)},onKeyDown:h=>{(h.key==="Enter"||h.key===" ")&&(h.preventDefault(),J("room",e.id,e.updatedAt),d.selectRoom(e.id),E&&be(!1))},children:[t.jsxs("span",{className:"chat-room-item-details",children:[t.jsxs("span",{className:"chat-room-item-name-row",children:[t.jsxs("span",{className:"chat-room-item-name",children:["#",e.name]}),c?t.jsx("span",{className:"chat-unread-dot","data-testid":`chat-unread-dot-${e.id}`,"aria-label":o("chat.unreadMessages","Unread messages")}):null]}),a?t.jsx("span",{className:"chat-room-item-meta",children:o("chat.roomMemberCount","{{count}} member",{count:d.activeRoomMembers.length,defaultValue_one:"{{count}} member",defaultValue_other:"{{count}} members"})}):null]}),t.jsx("button",{type:"button",className:"btn-icon chat-room-item-delete","data-testid":`chat-room-delete-${e.slug}`,"aria-label":o("chat.deleteRoom","Delete room {{name}}",{name:e.name}),onClick:h=>{h.stopPropagation(),$e(e.id)},children:t.jsx(ls,{size:14})})]},e.id)})})]}),b==="rooms"?E?t.jsx("div",{className:"chat-sidebar-footer",children:t.jsxs("button",{type:"button",className:"btn btn-sm btn-primary chat-sidebar-footer-btn","data-testid":"chat-create-room-btn",onClick:()=>re(!0),children:[t.jsx(gt,{size:14}),o("chat.createRoom","Create room")]})}):null:t.jsx("div",{className:"chat-sidebar-footer",children:t.jsxs("button",{className:"btn btn-sm btn-primary chat-sidebar-footer-btn",onClick:()=>ae(!0),"data-testid":"chat-new-btn",children:[t.jsx(gt,{size:14}),o("chat.newChat","New Chat")]})})]}),!E&&he&&!dt&&t.jsx("div",{className:"chat-sidebar-resize-handle",role:"separator","aria-orientation":"vertical","aria-valuemin":Dt,"aria-valuemax":$t,"aria-valuenow":ve,"aria-label":o("chat.resizeSidebar","Resize chat sidebar"),tabIndex:0,onPointerDown:An,onKeyDown:En}),$&&t.jsxs("div",{className:"chat-session-context-menu",style:{top:$.y,left:$.x},onClick:e=>e.stopPropagation(),children:[t.jsxs("button",{onClick:()=>Mn($.sessionId),"data-testid":"chat-context-archive",children:[t.jsx(va,{size:14}),o("chat.archive","Archive")]}),t.jsxs("button",{onClick:()=>{je(null),Me($.sessionId)},"data-testid":"chat-context-delete",children:[t.jsx(ls,{size:14}),o("chat.delete","Delete")]})]}),Y&&t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:()=>Me(null),children:t.jsxs("div",{className:"chat-new-dialog chat-view-dialog",onClick:e=>e.stopPropagation(),children:[t.jsx("h3",{children:o("chat.deleteConversationTitle","Delete Conversation?")}),t.jsx("p",{className:"chat-view-delete-dialog-copy",children:o("chat.deleteConversationBody","This action cannot be undone. All messages in this conversation will be permanently deleted.")}),t.jsxs("div",{className:"chat-new-dialog-actions",children:[t.jsx("button",{className:"btn btn-sm",onClick:()=>Me(null),children:o("chat.cancel","Cancel")}),t.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>void Rn(Y),children:o("chat.delete","Delete")})]})]})}),m&&De&&t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:()=>$e(null),children:t.jsxs("div",{className:"chat-new-dialog chat-view-dialog",onClick:e=>e.stopPropagation(),children:[t.jsx("h3",{children:o("chat.deleteRoomTitle","Delete Room?")}),t.jsx("p",{className:"chat-view-delete-dialog-copy",children:o("chat.deleteRoomBody","This action cannot be undone. This room and all its messages will be permanently deleted.")}),t.jsxs("div",{className:"chat-new-dialog-actions",children:[t.jsx("button",{className:"btn btn-sm",onClick:()=>$e(null),children:o("chat.cancel","Cancel")}),t.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>{(async()=>{try{await d.deleteRoom(De),$e(null)}catch{r(o("chat.failedToDeleteRoom","Failed to delete room"),"error")}})()},children:o("chat.delete","Delete")})]})]})}),m&&b==="rooms"?t.jsxs("div",{ref:Ut,className:"chat-thread",children:[d.activeRoom?t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"chat-room-thread-header",children:[E&&t.jsx("button",{className:"btn-icon",onClick:Jt,"data-testid":"chat-back-btn",children:t.jsx(qs,{size:16})}),t.jsxs("div",{className:"chat-room-switcher-menu",ref:ws,children:[t.jsxs("button",{type:"button",className:"chat-room-switcher-trigger","data-testid":"chat-room-switcher-trigger","aria-haspopup":"menu","aria-expanded":wt,onClick:()=>ot(e=>!e),children:[t.jsxs("span",{className:"chat-thread-header-title",children:["#",d.activeRoom.name]}),t.jsx(Pt,{size:16,"aria-hidden":"true"})]}),wt&&t.jsx("div",{role:"menu",className:"chat-room-switcher-dropdown","data-testid":"chat-room-switcher-dropdown",children:d.rooms.map(e=>t.jsxs("button",{type:"button",role:"menuitem",className:`chat-room-switcher-option${e.id===d.activeRoom?.id?" chat-room-switcher-option--active":""}`,"data-testid":`chat-room-switcher-option-${e.id}`,onClick:()=>{J("room",e.id,e.updatedAt),d.selectRoom(e.id),ot(!1)},children:["#",e.name]},e.id))})]}),t.jsx("div",{className:"chat-room-thread-members",children:d.activeRoomMembers.map(e=>t.jsx(mn,{agent:Se.get(e.agentId)??{id:e.agentId,name:e.agentId.slice(0,30)}},e.agentId))})]}),t.jsxs("div",{className:"chat-messages",ref:ge,onScroll:Rs,children:[d.messagesLoading?t.jsx("div",{className:"chat-empty-state",children:o("chat.loadingMessages","Loading messages...")}):d.messages.filter(e=>e.content.trim()!==an).length===0?t.jsx("div",{className:"chat-empty-state",children:o("chat.noMessagesYet","No messages yet. Start the conversation!")}):d.messages.filter(e=>e.content.trim()!==an).map(e=>{const a=e.senderAgentId?Se.get(e.senderAgentId)?.name??e.senderAgentId.slice(0,30):o("chat.you","You"),c={id:e.id,sessionId:e.roomId,role:e.role,content:e.content,thinkingOutput:e.thinkingOutput??void 0,toolCalls:void 0,fallbackInfo:void 0,attachments:e.attachments,createdAt:e.createdAt};return t.jsx(fs,{message:c,forcePlain:U,agentName:a,hideAssistantIdentity:!1,showAssistantModelTag:!1,activeModelTag:null,activeModelProvider:null,activeSessionId:d.activeRoom?.id??null,mentionAgentsByName:Gt,roomContext:Te,onScrollToTop:is},e.id)}),t.jsx("div",{ref:vs})]}),d.activeRoom&&Z&&t.jsxs("button",{type:"button",className:"btn btn-sm chat-jump-to-latest","data-testid":"chat-jump-to-latest",onClick:()=>Ne("fab-click"),children:[t.jsx(Pt,{size:14}),o("chat.latest","Latest")]})]}):t.jsx("div",{className:"chat-room-empty-pane","data-testid":"chat-rooms-empty-pane",children:o("chat.selectRoomOrCreate","Select a room or create one")}),d.activeRoom&&t.jsx("div",{className:"chat-input-area",children:t.jsxs("div",{className:"chat-input-row",children:[t.jsxs("div",{className:"chat-input-wrapper",children:[t.jsx("textarea",{ref:As,className:"chat-input-textarea",placeholder:o("chat.typeMessage","Type a message..."),value:P,onChange:Ts,onKeyDown:Es,onKeyUp:Is,onClick:Et,onBlur:Ps,onFocus:Ds,onTouchStart:e=>{typeof window>"u"||window.innerWidth>768||Xs()&&document.activeElement!==e.currentTarget&&(e.preventDefault(),e.currentTarget.focus({preventScroll:!0}))},rows:1,"data-testid":"chat-input"}),t.jsx(Ys,{agents:Ze,filter:Re,highlightedIndex:x,visible:l,onSelect:Rt,position:"below",roomMemberIds:Te?.memberIds,roomName:Te?.roomName})]}),t.jsx("button",{type:"button",className:"chat-input-send",onPointerDown:e=>{e.pointerType&&e.pointerType!=="mouse"&&e.preventDefault()},onMouseDown:e=>{e.preventDefault()},onClick:()=>{qt()},disabled:!P.trim(),"data-testid":"chat-send-btn",style:{touchAction:"manipulation"},children:t.jsx(Js,{size:16})})]})})]}):t.jsxs("div",{ref:Ut,className:"chat-thread",children:[(Zt||!E)&&t.jsxs("div",{className:"chat-thread-header",children:[E&&Zt&&t.jsx("button",{className:"btn-icon",onClick:Yt,"data-testid":"chat-back-btn",children:t.jsx(qs,{size:16})}),t.jsx("div",{className:"chat-thread-header-identity","data-testid":"chat-thread-header-identity",children:In?t.jsxs("div",{className:"chat-mobile-session-menu",ref:ys,children:[t.jsxs("button",{type:"button",className:"btn chat-mobile-session-trigger","data-testid":"chat-mobile-session-trigger","aria-haspopup":"menu","aria-expanded":yt,onClick:()=>Xe(e=>!e),children:[Ke?t.jsx(pt,{provider:Ke,size:"md"}):t.jsx(bt,{size:16}),t.jsx("span",{className:"chat-thread-header-title",children:es}),Ls&&t.jsx("span",{className:"chat-model-tag",children:Be}),t.jsx(Pt,{size:16,"aria-hidden":"true"})]}),yt&&t.jsx("div",{className:"chat-mobile-session-dropdown",role:"menu","data-testid":"chat-mobile-session-dropdown",children:V.map(e=>t.jsx("button",{type:"button",role:"menuitem",className:`chat-mobile-session-option${i?.id===e.id?" chat-mobile-session-option--active":""}`,"data-testid":`chat-mobile-session-option-${e.id}`,onClick:()=>$s(e.id),children:t.jsx("span",{className:"chat-mobile-session-option-title",children:e.title||o("chat.untitledSession","Untitled")})},e.id))})]}):t.jsxs(t.Fragment,{children:[Ke?t.jsx(pt,{provider:Ke,size:"md"}):t.jsx(bt,{size:16}),t.jsx("span",{className:"chat-thread-header-title",children:es}),Ls&&t.jsx("span",{className:"chat-model-tag",children:Be})]})}),Zt&&t.jsx("button",{type:"button",className:`chat-thread-header-render-toggle${U?" chat-thread-header-render-toggle--plain":""}`,"data-testid":"chat-thread-render-toggle","aria-label":U?o("chat.showRenderedMarkdown","Show all messages as rendered Markdown"):o("chat.showPlainText","Show all messages as plain text"),onClick:Dn,children:U?t.jsx(xa,{size:14}):t.jsx(ya,{size:14})}),!E&&t.jsxs("button",{className:"btn btn-sm btn-primary chat-thread-header-new-chat",onClick:()=>ae(!0),"data-testid":"chat-thread-new-chat-btn",children:[t.jsx(gt,{size:14}),o("chat.newChat","New Chat")]})]}),Fn?t.jsx($a,{cliSessionId:_n,tier:Ln,projectId:n,renderTranscript:Hs,renderComposer:()=>i?Os():null}):t.jsxs(t.Fragment,{children:[Hs(),Z&&t.jsxs("button",{type:"button",className:"btn btn-sm chat-jump-to-latest","data-testid":"chat-jump-to-latest",onClick:()=>Ne("fab-click"),children:[t.jsx(Pt,{size:14}),o("chat.latest","Latest")]}),i&&Os()]})]}),m&&t.jsx(Da,{isOpen:xt,onClose:()=>re(!1),projectId:n,existingRoomNames:d.rooms.map(e=>e.name),onCreate:async e=>{await d.createRoom({name:e.name,memberAgentIds:e.memberAgentIds}),b!=="rooms"&&w("rooms"),re(!1),E&&be(!1)}}),ke&&t.jsx(Wa,{projectId:n,defaultModel:Le,onClose:()=>ae(!1),onCreate:jn})]})}export{tr as ChatView,La as clampChatInputHeight,Fa as resolveChatInputOverflowY,un as resolveSessionProvider};
@@ -1,14 +0,0 @@
1
- import{r as s,j as e}from"./vendor-react-D37HfzIf.js";import{c as ze,aS as ds,aT as us,aU as ms,aV as hs,aW as Ke,aX as Ue,aY as Ie,aG as fe,aZ as ke,a_ as Oe,a$ as _e,b0 as Be,A as Te,ax as fs,Q as He,b1 as qe,b2 as gs,U as Ne,u as ps,R as Ce,a as we,J as ge,b3 as Ye,b4 as xs,b5 as vs,b6 as bs,b7 as Fe,X as he,ae as ys,af as js,b8 as Ve,F as ks,b9 as $e,ba as _s,bb as Ns,bc as Cs,bd as Ss,be as Ms,G as Ps}from"./index-CgfrecpF.js";import{u as ne}from"./vendor-i18n-CV0mwX_-.js";import{v as ws}from"./projectDetection-G3XuxD2X.js";import{U as Xe}from"./upload-BRAEugYV.js";import"./vendor-reactflow-CRZcPCXF.js";import"./vendor-xterm-tcedd2Jt.js";import"./vendor-codemirror-jBKmHyH0.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 Rs=[["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"}]],Es=ze("wifi-off",Rs);/**
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 Ls=[["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"}]],As=ze("wifi",Ls);function be(t){const{lastSyncAt:c,remoteReachable:a,diff:i}=t,r=i.global.length+i.project.length;return c===null?{syncState:"never-synced",lastSyncAt:c,diffCount:0}:a?r>0?{syncState:"diff",lastSyncAt:c,diffCount:r}:{syncState:"synced",lastSyncAt:c,diffCount:0}:{syncState:"error",lastSyncAt:c,diffCount:r}}function Se(t){if(t===null)return"Never synced";const c=new Date(t);if(Number.isNaN(c.getTime()))return"Never synced";const i=Date.now()-c.getTime(),r=Math.floor(i/1e3),m=Math.floor(r/60),o=Math.floor(m/60),g=Math.floor(o/24);return m<1?"Synced just now":m<60?`Synced ${m}m ago`:o<24?`Synced ${o}h ago`:`Synced ${g}d ago`}function Ds(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 Is=3e4;function Fs(){const{t}=ne("app"),[c,a]=s.useState({}),[i,r]=s.useState(!1),[m,o]=s.useState({}),[g,N]=s.useState(null),h=s.useRef(new Set),u=s.useRef(!1),C=s.useRef(null),S=s.useRef(null),f=s.useCallback(async(k,p)=>{try{const w=await ds(k);a(Q=>({...Q,[k]:w})),N(null)}catch(w){console.error(`Failed to fetch sync status for node ${k}:`,w),N(w instanceof Error?w.message:t("nodeSync.error.failedToFetchStatus","Failed to fetch sync status"))}},[t]),P=s.useCallback(async()=>{const k=Array.from(h.current);if(k.length===0)return;C.current&&C.current.abort(),C.current=new AbortController;const p=!u.current;p&&r(!0),N(null);try{const w=await Promise.allSettled(k.map(q=>f(q,p)));u.current=!0,w.filter(q=>q.status==="rejected").length>0&&N(t("nodeSync.error.someRequestsFailed","Some sync status requests failed"))}catch(w){if(w instanceof Error&&w.name==="AbortError")return;N(w instanceof Error?w.message:t("nodeSync.error.failedToFetchStatus","Failed to fetch sync status")),u.current=!0}finally{r(!1)}},[f,t]),j=s.useCallback(()=>{S.current&&clearInterval(S.current),S.current=setInterval(()=>{P()},Is)},[P]),b=s.useCallback(()=>{S.current&&(clearInterval(S.current),S.current=null)},[]);s.useEffect(()=>(P(),j(),()=>{b(),C.current&&C.current.abort()}),[P,j,b]);const l=s.useCallback(k=>{h.current.has(k)||(h.current.add(k),f(k,!u.current))},[f]),y=s.useCallback(k=>{h.current.delete(k),a(p=>{const w={...p};return delete w[k],w}),h.current.size===0&&b()},[b]),n=s.useCallback(async k=>{o(p=>({...p,[k]:!0})),N(null);try{const p=await us(k);return f(k,!1),!p.success&&p.error&&N(p.error),p}catch(p){const w=p instanceof Error?p.message:t("nodeSync.error.pushFailed","Push settings failed");throw N(w),p}finally{o(p=>{const w={...p};return delete w[k],w})}},[f,t]),M=s.useCallback(async k=>{o(p=>({...p,[k]:!0})),N(null);try{const p=await ms(k);return f(k,!1),!p.success&&p.error&&N(p.error),p}catch(p){const w=p instanceof Error?p.message:t("nodeSync.error.pullFailed","Pull settings failed");throw N(w),p}finally{o(p=>{const w={...p};return delete w[k],w})}},[f,t]),I=s.useCallback(async k=>{o(p=>({...p,[k]:!0})),N(null);try{return await hs(k)}catch(p){const w=p instanceof Error?p.message:t("nodeSync.error.authSyncFailed","Auth sync failed");throw N(w),p}finally{o(p=>{const w={...p};return delete w[k],w})}},[t]),O=s.useCallback(k=>c[k]?.authMatch,[c]),R=s.useCallback(k=>c[k]?.authDiff,[c]);return{syncStatusMap:c,loading:i,actionLoading:m,error:g,refresh:P,trackNode:l,untrackNode:y,pushSettings:n,pullSettings:M,syncAuth:I,getAuthSyncState:O,getAuthProviders:R}}const Vs=1e4,$s=1e3;function zs(){const{t}=ne("app"),[c,a]=s.useState([]),[i,r]=s.useState(!0),[m,o]=s.useState(null),g=s.useRef(null),N=s.useRef(0),h=s.useRef(c),u=Ke();s.useEffect(()=>{h.current=c},[c]);const C=s.useCallback(f=>h.current.length>0&&Ue(f,u.wasRecentlyHidden()),[u]),S=s.useCallback(async()=>{try{o(null);const f=await Ie();a(f.nodes)}catch(f){const P=f instanceof Error?f.message:t("mesh.failedToFetchMeshState","Failed to fetch mesh state");C(P)||o(P)}},[C,t]);return s.useEffect(()=>{let f=!1;async function P(){r(!0);try{const b=await Ie();f||(a(b.nodes),o(null))}catch(b){const l=b instanceof Error?b.message:t("mesh.failedToFetchMeshState","Failed to fetch mesh state");!f&&!C(l)&&o(l)}finally{f||r(!1)}}P();const j=()=>{if(document.visibilityState!=="visible")return;const b=Date.now(),l=b-N.current;if(l<$s){fe({view:"useMeshState",trigger:"visibility",projectId:void 0,replayAttempted:!1,reason:"debounce-skipped",detail:{timeSinceLastRefreshMs:l}});return}N.current=b,fe({view:"useMeshState",trigger:"visibility",projectId:void 0,replayAttempted:!1,reason:"debounced-refresh"}),S()};return document.addEventListener("visibilitychange",j),()=>{f=!0,document.removeEventListener("visibilitychange",j)}},[S,C,t]),s.useEffect(()=>{if(!i)return g.current=setInterval(()=>{S()},Vs),()=>{g.current&&(clearInterval(g.current),g.current=null)}},[i,S]),{meshState:c,loading:i,error:m,refresh:S}}function Ks(t){return{online:{label:t("nodes.status.online","Online"),color:"var(--color-success)",className:"node-card__status--online"},offline:{label:t("nodes.status.offline","Offline"),color:"var(--color-error)",className:"node-card__status--offline"},connecting:{label:t("nodes.status.connecting","Connecting"),color:"var(--color-warning)",className:"node-card__status--connecting"},error:{label:t("nodes.status.error","Error"),color:"var(--color-error)",className:"node-card__status--error"},creating:{label:t("nodes.status.creating","Creating"),color:"var(--color-warning)",className:"node-card__status--creating"},recreating:{label:t("nodes.status.recreating","Recreating"),color:"var(--color-warning)",className:"node-card__status--recreating"},deleting:{label:t("nodes.status.deleting","Deleting"),color:"var(--color-error)",className:"node-card__status--deleting"},running:{label:t("nodes.status.running","Running"),color:"var(--color-success)",className:"node-card__status--online"},stopped:{label:t("nodes.status.stopped","Stopped"),color:"var(--color-error)",className:"node-card__status--offline"},exited:{label:t("nodes.status.exited","Exited"),color:"var(--color-error)",className:"node-card__status--offline"}}}const Us={match:"var(--color-success)",differs:"var(--color-warning)","not-synced":"var(--text-muted)"};function Os(t,c,a){if(t==="match")return a?a("nodes.auth.match","Auth credentials match"):"Auth credentials match";if(t==="not-synced")return a?a("nodes.auth.notSynced","Auth not synced"):"Auth not synced";if(c&&Object.keys(c).length>0){const i=Object.entries(c).filter(([,r])=>r==="differs").map(([r])=>r);if(i.length>0)return a?a("nodes.auth.differProviders","Auth credentials differ: {{providers}}",{providers:i.join(", ")}):`Auth credentials differ: ${i.join(", ")}`}return a?a("nodes.auth.differ","Auth credentials differ"):"Auth credentials differ"}function Bs(t,c=42){return t.length<=c?t:`${t.slice(0,c-3)}...`}function Ts(t,c){const a=t.node,i=c.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!==c.isLoading)return!1;const r=t.managedDockerNode,m=c.managedDockerNode;if(!!r!=!!m||r&&m&&(r.id!==m.id||r.status!==m.status||r.imageTag!==m.imageTag||r.updatedAt!==m.updatedAt))return!1;const o=t.syncStatus,g=c.syncStatus;if(!(!o&&!g)){if(!o||!g)return!1;if(o.syncState!==g.syncState||o.lastSyncAt!==g.lastSyncAt||o.diffCount!==g.diffCount)return!1}if(t.authSyncState!==c.authSyncState)return!1;const N=t.authSyncProviders,h=c.authSyncProviders;if(N!==h){if(!N||!h)return!1;{const S=Object.keys(N),f=Object.keys(h);if(S.length!==f.length||S.some(P=>N[P]!==h[P]))return!1}}const u=ke(t.projects,a),C=ke(c.projects,i);return u===C}function Hs({node:t,projects:c,onHealthCheck:a,onEdit:i,onRemove:r,isLoading:m=!1,syncStatus:o,authSyncState:g,authSyncProviders:N,managedDockerNode:h}){const{t:u}=ne("app"),[C,S]=s.useState(!1),f=Ks(u),P=f[t.status]??f.offline,j=h?f[h.status]??f.error:null,b=h?.hostConfig.type==="remote"?u("nodes.dockerHost.remote","Remote: {{host}}",{host:h.hostConfig.host??"unknown"}):u("nodes.dockerHost.local","Local Docker"),l=s.useMemo(()=>ke(c,t),[c,t]),y=s.useCallback(()=>{i(t)},[i,t]),n=s.useCallback(R=>{R.stopPropagation(),a(t.id)},[a,t.id]),M=s.useCallback(R=>{R.stopPropagation(),i(t)},[i,t]),I=s.useCallback(R=>{if(R.stopPropagation(),!C){S(!0);return}r(t.id),S(!1)},[C,r,t.id]),O=s.useCallback(R=>{(R.key==="Enter"||R.key===" ")&&(R.preventDefault(),i(t))},[i,t]);return e.jsxs("article",{className:`node-card ${m?"node-card--loading":""}`,"data-node-id":t.id,role:"button",tabIndex:0,onClick:y,onKeyDown:O,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(Oe,{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"?u("nodes.type.local","Local"):u("nodes.type.remote","Remote")}),h&&e.jsxs("span",{className:"node-card__docker-badge",title:u("nodes.dockerBadge","Managed Docker node"),children:[e.jsx(_e,{size:12,"aria-hidden":!0}),u("nodes.dockerLabel","Docker")]}),e.jsxs("span",{className:`node-card__status ${P.className}`,style:{color:P.color},"data-status":t.status,children:[e.jsx("span",{className:"node-card__status-indicator",style:{backgroundColor:P.color},"aria-hidden":!0}),P.label]}),h&&j&&e.jsxs("span",{className:`node-card__status ${j.className}`,style:{color:j.color},"data-status":h.status,children:[e.jsx("span",{className:"node-card__status-indicator",style:{backgroundColor:j.color},"aria-hidden":!0}),j.label]}),t.type==="remote"&&g&&e.jsx("span",{className:`node-card__auth-indicator node-card__auth-indicator--${g}`,title:Os(g,N,u),"aria-label":u("nodes.authSync.label","Auth sync: {{status}}",{status:g==="match"?u("nodes.authSync.match","credentials match"):g==="differs"?u("nodes.authSync.differ","credentials differ"):u("nodes.authSync.notSynced","not synced")}),style:{color:Us[g]},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:Bs(t.url)}),h&&e.jsxs("div",{className:"node-card__docker-meta",children:[e.jsxs("span",{title:`${h.imageName}:${h.imageTag}`,children:[h.imageName,":",h.imageTag]}),e.jsx("span",{title:b,children:b})]}),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:u("nodes.metrics.projects","Projects")}),e.jsx("span",{className:"node-card__metric-value",children:l})]}),e.jsxs("div",{className:"node-card__metric",children:[e.jsx("span",{className:"node-card__metric-label",children:u("nodes.metrics.concurrency","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:Ds(o.syncState)},"aria-hidden":!0}),e.jsx("span",{className:"node-card__sync-time",children:Se(o.lastSyncAt)})]})]}),e.jsxs("footer",{className:"node-card__actions",children:[e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",onClick:n,disabled:m,"aria-label":u("nodes.actions.health.ariaLabel","Run node health check"),title:u("nodes.actions.health.title","Health Check"),children:[e.jsx(Te,{size:14}),e.jsx("span",{children:u("nodes.actions.health.label","Health")})]}),e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",onClick:M,disabled:m,"aria-label":u("nodes.actions.edit.ariaLabel","Edit node"),title:u("nodes.actions.edit.title","Edit"),children:[e.jsx(fs,{size:14}),e.jsx("span",{children:u("nodes.actions.edit.label","Edit")})]}),h&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",disabled:!0,"aria-label":u("nodes.actions.start.ariaLabel","Start node container"),title:u("nodes.actions.start.title","Available after FN-3113"),children:[e.jsx(He,{size:14}),e.jsx("span",{children:u("nodes.actions.start.label","Start")})]}),e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",disabled:!0,"aria-label":u("nodes.actions.stop.ariaLabel","Stop node container"),title:u("nodes.actions.stop.title","Available after FN-3113"),children:[e.jsx(qe,{size:14}),e.jsx("span",{children:u("nodes.actions.stop.label","Stop")})]}),e.jsxs("button",{className:"btn btn-sm node-card__action",type:"button",disabled:!0,"aria-label":u("nodes.actions.restart.ariaLabel","Restart node container"),title:u("nodes.actions.restart.title","Available after FN-3113"),children:[e.jsx(gs,{size:14}),e.jsx("span",{children:u("nodes.actions.restart.label","Restart")})]})]}),e.jsxs("button",{className:`btn btn-sm node-card__action node-card__action--remove ${C?"btn-danger is-armed":""}`,type:"button",onClick:I,disabled:m,"aria-label":C?u("nodes.actions.remove.ariaLabelConfirm","Confirm remove node"):u("nodes.actions.remove.ariaLabel","Remove node"),title:C?u("nodes.actions.remove.titleConfirm","Confirm remove"):u("nodes.actions.remove.title","Remove"),children:[e.jsx(Ne,{size:14}),e.jsx("span",{children:C?u("nodes.actions.remove.labelConfirm","Confirm"):u("nodes.actions.remove.label","Remove")})]})]})]})}const qs=s.memo(Hs,Ts),de={online:"var(--success, var(--color-success))",offline:"var(--text-dim)",connecting:"var(--color-warning)",error:"var(--color-error)"},me=28,Ys=12,Xs=300,Js=120;function Gs({nodes:t,className:c}){const{t:a}=ne("app"),i=s.useMemo(()=>t.find(u=>u.nodeType==="local")??t[0],[t]),r=s.useMemo(()=>t.filter(u=>u.nodeId!==i?.nodeId),[t,i?.nodeId]),m=s.useMemo(()=>Xs+Math.max(0,r.length-4)*20,[r.length]),o=m/2,g=m/2,N=s.useMemo(()=>{const u=new Map;if(i&&u.set(i.nodeId,{x:o,y:g,node:i}),r.length>0){const C=Math.min(Js,m/2-me-10),S=2*Math.PI/r.length,f=-Math.PI/2;r.forEach((P,j)=>{const b=f+j*S;u.set(P.nodeId,{node:P,x:o+C*Math.cos(b),y:g+C*Math.sin(b)})})}return u},[o,g,i,r,m]),h=s.useMemo(()=>{const u=new Set,C=[];for(const S of t){const f=N.get(S.nodeId);if(f)for(const P of S.knownPeers){const j=N.get(P.peerNodeId);if(!j)continue;const b=[S.nodeId,P.peerNodeId].sort().join("::");u.has(b)||(u.add(b),C.push({key:b,from:f,to:j}))}}return C},[N,t]);return t.length===0?e.jsx("div",{className:`mesh-topology mesh-topology--empty ${c??""}`,children:e.jsx("div",{className:"mesh-topology__empty-state",children:e.jsx("p",{children:a("mesh.noNodes","No nodes to display")})})}):e.jsxs("div",{className:`mesh-topology ${c??""}`,children:[e.jsxs("svg",{className:"mesh-topology__svg",viewBox:`0 0 ${m} ${m}`,preserveAspectRatio:"xMidYMid meet","aria-label":a("mesh.ariaLabel","Node mesh topology visualization"),children:[h.map(u=>e.jsx("line",{className:"mesh-topology__link mesh-topology__peer-line",x1:u.from.x,y1:u.from.y,x2:u.to.x,y2:u.to.y},u.key)),Array.from(N.values()).map(({node:u,x:C,y:S})=>e.jsxs("g",{className:"mesh-topology__node",transform:`translate(${C}, ${S})`,children:[e.jsx("circle",{className:"mesh-topology__node-circle",r:me,fill:de[u.status],"aria-label":`${u.nodeName} (${u.status})`}),e.jsx("text",{className:"mesh-topology__node-label",y:me+Ys,textAnchor:"middle",children:u.nodeName.length>12?`${u.nodeName.slice(0,10)}…`:u.nodeName}),e.jsxs("g",{className:"mesh-topology__node-type",transform:`translate(0 ${-me-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:u.nodeType==="local"?"L":"R"})]})]},u.nodeId))]}),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:de.online}}),e.jsx("span",{children:a("mesh.online","Online")})]}),e.jsxs("div",{className:"mesh-topology__legend-item",children:[e.jsx("span",{className:"mesh-topology__legend-dot",style:{background:de.offline}}),e.jsx("span",{children:a("mesh.offline","Offline")})]}),e.jsxs("div",{className:"mesh-topology__legend-item",children:[e.jsx("span",{className:"mesh-topology__legend-dot",style:{background:de.connecting}}),e.jsx("span",{children:a("mesh.connecting","Connecting")})]}),e.jsxs("div",{className:"mesh-topology__legend-item",children:[e.jsx("span",{className:"mesh-topology__legend-dot",style:{background:de.error}}),e.jsx("span",{children:a("mesh.error","Error")})]})]}),h.length===0&&e.jsx("p",{className:"mesh-topology__notice",children:a("mesh.noPeers","Peer-to-peer discovery data unavailable.")})]})}const Ws=s.memo(Gs),Me=1,Pe=10;function Zs(t,c){const a={projectMappings:{}};t.name.trim()||(a.name=c("nodes.nameRequired","Name is required")),t.type==="remote"&&!t.url?.trim()&&(a.url=c("nodes.urlRequired","URL is required for remote nodes")),(!Number.isFinite(t.maxConcurrent)||t.maxConcurrent<Me||t.maxConcurrent>Pe)&&(a.maxConcurrent=c("nodes.concurrencyRange","Concurrency must be between {{min}} and {{max}}",{min:Me,max:Pe}));for(const i of t.projectMappings){const r=ws(i.path);r.valid||(a.projectMappings[i.projectId]=r.error??c("nodes.pathInvalid","Path is invalid"))}return a}function Qs({isOpen:t,onClose:c,onSubmit:a,onDiscoverRemoteProjects:i,addToast:r,projects:m}){const{t:o}=ne("app");ps(t);const[g,N]=s.useState(""),[h,u]=s.useState("local"),[C,S]=s.useState(""),[f,P]=s.useState(""),[j,b]=s.useState(2),[l,y]=s.useState("auto-generate"),[n,M]=s.useState({}),[I,O]=s.useState({projectMappings:{}}),[R,k]=s.useState(!1),[p,w]=s.useState("idle"),[Q,q]=s.useState(null),[X,se]=s.useState([]),B=s.useCallback(()=>{N(""),u("local"),S(""),P(""),b(2),y("auto-generate"),M({}),O({projectMappings:{}}),k(!1),w("idle"),q(null),se([])},[]),J=s.useCallback(()=>{R||(B(),c())},[R,c,B]);s.useEffect(()=>{if(!t){B();return}const _=D=>{D.key==="Escape"&&(D.preventDefault(),J())};return document.addEventListener("keydown",_),()=>{document.removeEventListener("keydown",_)}},[J,t,B]);const Z=s.useMemo(()=>({name:g.trim(),type:h,url:h==="remote"&&C.trim()||void 0,apiKey:h==="remote"&&l==="provide"&&f||void 0,maxConcurrent:j,apiKeyMode:l,projectMappings:Object.entries(n).map(([_,D])=>({projectId:_,path:D.trim()}))}),[f,l,j,g,n,h,C]),ae=s.useCallback(async()=>{if(R||p==="loading")return;const _=C.trim();if(!_){O(D=>({...D,url:o("nodes.urlRequired","URL is required for remote nodes")}));return}w("loading"),q(null);try{const D=await i({url:_,apiKey:l==="provide"&&f.trim().length>0?f:void 0});se(D.projects),w("success"),M(F=>{if(Object.keys(F).length===0)return F;const U={...F};for(const oe of m){if(!(oe.id in U))continue;const re=D.projects.filter(te=>te.name===oe.name);re.length===1&&(U[oe.id]=re[0].path)}return U})}catch(D){w("error"),se([]),q(D instanceof Error?D.message:o("nodes.discoveryFailed","Failed to discover remote projects"))}},[f,l,p,R,i,m,o,C]);s.useEffect(()=>{if(h!=="remote"){w("idle"),q(null),se([]);return}w("idle"),q(null),se([])},[f,l,h,C]);const G=s.useCallback(async()=>{if(R)return;const _=Zs(Z,o);if(O(_),!(_.name||_.url||_.maxConcurrent||Object.keys(_.projectMappings).length>0)){if(Z.type==="remote"&&p!=="success"){q(o("nodes.discoverBeforeAdding","Discover remote projects before adding this node."));return}k(!0);try{await a(Z),r(o("nodes.registered",'Node "{{name}}" registered',{name:Z.name}),"success"),J()}catch(D){const F=D instanceof Error?D.message:o("nodes.registerFailed","Failed to register node");r(F,"error")}finally{k(!1)}}},[r,J,p,Z,R,a,o]),T=_=>{M(D=>{if(_.id in D){const{[_.id]:F,...U}=D;return U}if(h==="remote"&&p==="success"){const F=X.filter(U=>U.name===_.name);return F.length===1?{...D,[_.id]:F[0].path}:{...D,[_.id]:""}}return{...D,[_.id]:_.path}})},L=(_,D)=>{M(F=>({...F,[_]:D}))};return t?e.jsx("div",{className:"modal-overlay open",onClick:J,children:e.jsxs("div",{className:"modal modal-md add-node-modal",onClick:_=>_.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":o("nodes.addNode","Add Node"),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:o("nodes.addNode","Add Node")}),e.jsx("button",{className:"modal-close",onClick:J,disabled:R,"aria-label":o("nodes.closeNodeModal","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:o("nodes.description","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:o("nodes.name","Name")}),e.jsx("input",{className:"input",type:"text",value:g,onChange:_=>N(_.target.value),placeholder:o("nodes.namePlaceholder","Build Machine"),disabled:R,"aria-invalid":!!I.name,autoFocus:!0}),I.name&&e.jsx("span",{className:"form-error add-node-modal__error",children:I.name})]}),e.jsxs("div",{className:"add-node-modal__type-toggle",children:[e.jsx("button",{type:"button",className:`add-node-modal__type-btn ${h==="local"?"active":""}`,"data-type":"local",onClick:()=>u("local"),disabled:R,"aria-pressed":h==="local",children:o("nodes.local","Local")}),e.jsx("button",{type:"button",className:`add-node-modal__type-btn ${h==="remote"?"active":""}`,"data-type":"remote",onClick:()=>u("remote"),disabled:R,"aria-pressed":h==="remote",children:o("nodes.remote","Remote")})]}),h==="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:o("nodes.reachableUrl","Reachable URL / Hostname")}),e.jsx("input",{className:"input",type:"text",value:C,onChange:_=>S(_.target.value),placeholder:"https://node.example.com",disabled:R,"aria-invalid":!!I.url}),I.url&&e.jsx("span",{className:"form-error add-node-modal__error",children:I.url})]}),e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:o("nodes.apiKeyMode","API Key Mode")}),e.jsxs("select",{className:"select",value:l,onChange:_=>y(_.target.value),disabled:R,children:[e.jsx("option",{value:"auto-generate",children:o("nodes.autoGenerate","Auto-generate")}),e.jsx("option",{value:"provide",children:o("nodes.provideManually","Provide key manually")})]})]}),l==="provide"&&e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:o("nodes.apiKey","API Key")}),e.jsx("input",{className:"input",type:"password",value:f,onChange:_=>P(_.target.value),placeholder:o("nodes.apiKeyPlaceholder","Enter node API key"),disabled:R})]}),e.jsxs("div",{className:"add-node-modal__discovery-actions",children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>void ae(),disabled:R||p==="loading",children:p==="loading"?o("nodes.discovering","Discovering..."):o("nodes.discoverRemoteProjects","Discover Remote Projects")}),p==="success"&&e.jsx("span",{className:"add-node-modal__discovery-state","data-state":"success",children:X.length>0?o("nodes.discoveredCount","Discovered {{count}} remote project{{plural}}",{count:X.length,plural:X.length===1?"":"s"}):o("nodes.noProjectsDiscovered","No projects discovered on remote node.")}),p==="error"&&Q&&e.jsx("span",{className:"form-error add-node-modal__error",children:Q}),p==="idle"&&e.jsx("span",{className:"add-node-modal__hint",children:o("nodes.discoverBeforeAdding","Discover remote projects before adding this node.")})]}),p==="success"&&X.length>0&&e.jsx("div",{className:"add-node-modal__discovered-list","aria-label":"Discovered remote projects",children:X.map(_=>e.jsxs("div",{className:"card add-node-modal__discovered-card",children:[e.jsxs("div",{className:"add-node-modal__discovered-row",children:[e.jsx("strong",{children:_.name}),e.jsx("span",{className:"card-status-badge card-status-badge--in-review",children:_.status})]}),e.jsx("div",{className:"add-node-modal__hint",children:_.path})]},`${_.id}-${_.path}`))})]}),e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:o("nodes.maxConcurrent","Max Concurrent")}),e.jsx("input",{className:"input",type:"number",min:Me,max:Pe,value:j,onChange:_=>b(Number(_.target.value)),disabled:R,"aria-invalid":!!I.maxConcurrent}),e.jsx("span",{className:"add-node-modal__hint",children:o("nodes.maxConcurrentHint","Max simultaneous task agents (1–10)")}),I.maxConcurrent&&e.jsx("span",{className:"form-error add-node-modal__error",children:I.maxConcurrent})]}),e.jsxs("section",{className:"add-node-modal__projects","aria-label":"Project path mappings",children:[e.jsx("h4",{className:"add-node-modal__projects-title",children:o("nodes.attachProjects","Attach Existing Projects")}),e.jsx("p",{className:"add-node-modal__hint",children:o("nodes.attachProjectsHint","Select existing projects to run on this node and provide the node-specific absolute path for each one.")}),m.length===0?e.jsx("p",{className:"add-node-modal__hint",children:o("nodes.noProjects","No projects are currently registered.")}):e.jsx("div",{className:"add-node-modal__project-list",children:m.map(_=>{const D=_.id in n,F=I.projectMappings[_.id];return e.jsxs("div",{className:"card add-node-modal__project-card",children:[e.jsxs("label",{className:"checkbox-label add-node-modal__project-toggle",children:[e.jsx("input",{type:"checkbox",checked:D,onChange:()=>T(_),disabled:R}),e.jsx("span",{children:_.name})]}),D&&e.jsxs("label",{className:"add-node-modal__field",children:[e.jsx("span",{children:o("nodes.pathOnNode","Path on this node")}),h==="remote"&&p==="success"&&e.jsx("span",{className:"add-node-modal__hint",children:(()=>{const U=X.filter(oe=>oe.name===_.name);return U.length===1?o("nodes.pathDiscovered","Remote-authoritative path discovered: {{path}}",{path:U[0].path}):U.length>1?o("nodes.multipleMatches","Multiple remote projects matched this name. Enter the correct path manually."):o("nodes.noMatch","No exact remote name match. Enter this path manually.")})()}),e.jsx("input",{className:"input",type:"text",value:n[_.id]??"",onChange:U=>L(_.id,U.target.value),disabled:R,placeholder:"/absolute/path/to/project","aria-invalid":!!F}),F&&e.jsx("span",{className:"form-error add-node-modal__error",children:F})]})]},_.id)})})]})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{className:"btn btn-sm",onClick:J,disabled:R,children:o("common.cancel","Cancel")}),e.jsx("button",{className:"btn btn-primary btn-sm","data-testid":"add-node-submit",onClick:G,disabled:R,children:R?o("nodes.adding","Adding..."):o("nodes.addNode","Add Node")})]})]})}):null}function et(){const[t,c]=s.useState([]),[a,i]=s.useState(!1),[r,m]=s.useState(null),[o,g]=s.useState(!1),[N,h]=s.useState(null),[u,C]=s.useState(!1),S=s.useCallback(async()=>{i(!0),m(null);try{const j=await fetch("/api/docker/contexts");if(!j.ok)throw new Error(`Failed to load Docker contexts (${j.status})`);const b=await j.json();return c(b),b}catch(j){const b=j instanceof Error?j.message:String(j);throw m(b),j}finally{i(!1)}},[]),f=s.useCallback(async j=>{g(!0);try{const b=await fetch("/api/docker/test-connection",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({hostConfig:j})});if(!b.ok)throw new Error(`Failed to test Docker connection (${b.status})`);const l=await b.json();return h(l),l}finally{g(!1)}},[]),P=s.useCallback(async()=>{C(!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{C(!1)}},[]);return{contexts:t,isLoadingContexts:a,contextsError:r,loadContexts:S,isTestingConnection:o,lastTestResult:N,testConnection:f,isCheckingLocal:u,checkLocalDocker:P}}function st({value:t,onChange:c}){const{t:a}=ne("app"),[i,r]=s.useState(!!(t?.tlsCaPath||t?.tlsCertPath||t?.tlsKeyPath||t?.tlsVerify));s.useEffect(()=>{i||c({tlsVerify:void 0,tlsCaPath:void 0,tlsCertPath:void 0,tlsKeyPath:void 0})},[i,c]);const m=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:i,onChange:o=>r(o.target.checked)}),a("docker.useTls","Use TLS")]}),i&&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:a("docker.caPath","CA Certificate Path")}),e.jsx("input",{id:"docker-tls-ca-path",className:"input",value:m.tlsCaPath,onChange:o=>c({...m,tlsCaPath:o.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:a("docker.certPath","Client Certificate Path")}),e.jsx("input",{id:"docker-tls-cert-path",className:"input",value:m.tlsCertPath,onChange:o=>c({...m,tlsCertPath:o.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:a("docker.keyPath","Client Key Path")}),e.jsx("input",{id:"docker-tls-key-path",className:"input",value:m.tlsKeyPath,onChange:o=>c({...m,tlsKeyPath:o.target.value}),placeholder:"/etc/docker/key.pem"})]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:m.tlsVerify,onChange:o=>c({...m,tlsVerify:o.target.checked})}),a("docker.verifyTls","Verify TLS Certificate")]})]})]})}function tt({value:t,onChange:c,onError:a}){const{t:i}=ne("app"),r=t?.context?"context":t?.host?"host":"local",[m,o]=s.useState(r),[g,N]=s.useState(t?.context??""),[h,u]=s.useState(t?.host??""),[C,S]=s.useState(null),{contexts:f,isLoadingContexts:P,contextsError:j,loadContexts:b,testConnection:l,isTestingConnection:y,lastTestResult:n,checkLocalDocker:M,isCheckingLocal:I}=et(),O=s.useMemo(()=>({tlsVerify:t?.tlsVerify,tlsCaPath:t?.tlsCaPath,tlsCertPath:t?.tlsCertPath,tlsKeyPath:t?.tlsKeyPath}),[t]);s.useEffect(()=>{if(m==="local"){c({});return}if(m==="context"){b().catch(k=>a?.(k instanceof Error?k.message:String(k))),c(g?{context:g}:{});return}c({host:h,...O})},[m]);const R=s.useCallback(k=>{m==="host"&&c({host:h,...k})},[h,m,c]);return e.jsxs("div",{className:"docker-target-selector",children:[e.jsxs("div",{className:"docker-target-selector__modes",role:"group","aria-label":i("docker.targetMode","Docker target mode"),children:[e.jsx("button",{type:"button",className:`btn btn-sm ${m==="local"?"docker-target-selector__mode-active":""}`,onClick:()=>{o("local"),M().then(k=>{if(k.available){const p=k.version?` (${k.version})`:"";S(i("docker.available","Docker is available{{version}}",{version:p}))}else{const p=k.error?`: ${k.error}`:"";S(i("docker.notFound","Docker not found{{error}}",{error:p}))}}).catch(k=>{const p=k instanceof Error?k.message:String(k);S(i("docker.notFoundError","Docker not found: {{message}}",{message:p})),a?.(p)})},children:i("docker.local","Local Docker")}),e.jsx("button",{type:"button",className:`btn btn-sm ${m==="context"?"docker-target-selector__mode-active":""}`,onClick:()=>o("context"),children:i("docker.context","Docker Context")}),e.jsx("button",{type:"button",className:`btn btn-sm ${m==="host"?"docker-target-selector__mode-active":""}`,onClick:()=>o("host"),children:i("docker.remote","Remote Host")})]}),m==="local"&&C&&e.jsx("div",{className:"docker-target-selector__status",children:C}),m==="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:g,onChange:k=>{const p=k.target.value;N(p),c(p?{context:p}:{})},children:[e.jsx("option",{value:"",children:i("docker.selectContext","Select context")}),f.map(k=>e.jsxs("option",{value:k.name,children:[k.name,k.isCurrentContext?" (current)":"",k.dockerHost?` — ${k.dockerHost}`:""]},k.name))]}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon",onClick:()=>void b(),disabled:P,"aria-label":i("docker.refreshContexts","Refresh contexts"),children:e.jsx(Ce,{size:14})})]}),j&&e.jsx("div",{className:"docker-target-selector__error",children:j})]}),m==="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:i("docker.host","Docker Host")}),e.jsx("input",{id:"docker-target-selector-host",className:"input",placeholder:i("docker.hostPlaceholder","tcp://host:2376"),value:h,onChange:k=>{const p=k.target.value;u(p),c({host:p,...O})}})]}),e.jsx(st,{value:O,onChange:R})]}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>void l(m==="local"?void 0:m==="context"?{context:g}:{host:h,...O}),disabled:y||I,children:y?i("docker.testing","Testing..."):i("docker.testConnection","Test Connection")}),n&&e.jsx("div",{className:n.success?"docker-target-selector__success":"docker-target-selector__error",children:n.success?i("docker.connected","Connected{{version}}",{version:n.dockerVersion?` (Docker ${n.dockerVersion})`:""}):n.error??i("docker.connectionFailed","Connection failed")})]})}const ye="http://localhost:4040";function nt({isOpen:t,onClose:c,onSubmit:a,addToast:i}){const{t:r}=ne("app"),[m,o]=s.useState(""),[g,N]=s.useState({}),[h,u]=s.useState(ye),[C,S]=s.useState("auto"),[f,P]=s.useState(""),[j,b]=s.useState(!1),[l,y]=s.useState(!1),[n,M]=s.useState(!0),[I,O]=s.useState(4096),[R,k]=s.useState(2),[p,w]=s.useState(!1),[Q,q]=s.useState("runfusion/fusion"),[X,se]=s.useState("latest"),[B,J]=s.useState([]),[Z,ae]=s.useState([]),[G,T]=s.useState({}),[L,_]=s.useState(!1),D=s.useCallback(()=>{o(""),N({}),u(ye),S("auto"),P(""),b(!1),y(!1),M(!0),O(4096),k(2),w(!1),q("runfusion/fusion"),se("latest"),J([]),ae([]),T({}),_(!1)},[]),F=s.useCallback(()=>{L||(D(),c())},[c,D,L]);s.useEffect(()=>{if(!t){D();return}const x=K=>{K.key==="Escape"&&(K.preventDefault(),F())};return document.addEventListener("keydown",x),()=>document.removeEventListener("keydown",x)},[F,t,D]);const U=s.useMemo(()=>({nodeId:null,name:m.trim(),imageName:Q.trim()||"runfusion/fusion",imageTag:X.trim()||"latest",hostConfig:{context:g.context?.trim()||void 0,host:g.host?.trim()||void 0,tlsVerify:g.tlsVerify,tlsCaPath:g.tlsCaPath?.trim()||void 0,tlsCertPath:g.tlsCertPath?.trim()||void 0,tlsKeyPath:g.tlsKeyPath?.trim()||void 0},envVars:Object.fromEntries(B.map(x=>[x.key.trim(),x.value]).filter(([x])=>!!x)),volumeMounts:Z.map(x=>({hostPath:x.hostPath.trim(),containerPath:x.containerPath.trim(),mode:x.mode})).filter(x=>x.hostPath&&x.containerPath),resourceSizing:{memoryMB:I,cpus:R},extraClis:[j?"claude-cli":null,l?"droid-cli":null].filter(Boolean),persistentStorage:n,reachableUrl:h.trim()||null,apiKey:C==="manual"&&f.trim()||null}),[f,C,R,g,B,Q,X,j,l,I,Z,m,n,h]),oe=s.useCallback(()=>{J(x=>[...x,{key:"",value:""}])},[]),re=s.useCallback((x,K)=>{J(H=>H.map((Y,ie)=>ie===x?K:Y))},[]),te=s.useCallback(x=>{J(K=>K.filter((H,Y)=>Y!==x))},[]),ce=s.useCallback(()=>{ae(x=>[...x,{hostPath:"",containerPath:"",mode:"rw"}])},[]),A=s.useCallback((x,K)=>{ae(H=>H.map((Y,ie)=>ie===x?K:Y))},[]),V=s.useCallback(x=>{ae(K=>K.filter((H,Y)=>Y!==x))},[]),W=s.useCallback(async()=>{if(L)return;const x={};if((!U.name||U.name.length>64)&&(x.name=r("docker.errors.nameRequired","Name is required and must be 64 characters or fewer")),U.reachableUrl||(x.reachableUrl=r("docker.errors.urlRequired","URL is required")),I<512&&(x.memoryMB=r("docker.errors.memoryMinimum","Memory must be at least 512 MB")),R<.5&&(x.cpus=r("docker.errors.cpusMinimum","CPUs must be at least 0.5")),T(x),!(Object.keys(x).length>0)){_(!0);try{await a(U),F()}catch{}finally{_(!1)}}},[F,R,U,I,a,L,r]);return t?e.jsx("div",{className:"modal-overlay open",onClick:F,children:e.jsxs("div",{className:"modal docker-onboarding",role:"dialog","aria-modal":"true","aria-label":r("docker.ariaLabels.modal","Docker node onboarding"),onClick:x=>x.stopPropagation(),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:r("docker.titles.provisionNode","Provision Docker Node")}),e.jsx("button",{className:"modal-close",onClick:F,disabled:L,"aria-label":r("docker.ariaLabels.closeModal","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:r("docker.sections.requiredSettings","Required Settings")}),e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:r("docker.labels.nodeName","Node Name")}),e.jsx("input",{className:"input",value:m,onChange:x=>o(x.target.value),disabled:L,placeholder:r("docker.placeholders.nodeName","my-docker-node"),autoFocus:!0})]}),G.name&&e.jsx("div",{className:"form-error",children:G.name}),e.jsx(tt,{value:g,onChange:N}),e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:r("docker.labels.reachableUrl","Reachable URL")}),e.jsx("input",{className:"input",value:h,onChange:x=>u(x.target.value),disabled:L,placeholder:ye})]}),G.reachableUrl&&e.jsx("div",{className:"form-error",children:G.reachableUrl}),e.jsxs("div",{className:"docker-onboarding__radio-group",children:[e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"radio",checked:C==="auto",onChange:()=>S("auto"),disabled:L}),r("docker.options.autoGenerate","Auto-generate")]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"radio",checked:C==="manual",onChange:()=>S("manual"),disabled:L}),r("docker.options.provideManually","Provide manually")]})]}),C==="manual"&&e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:r("docker.labels.apiKey","API Key")}),e.jsx("input",{className:"input",type:"password",value:f,onChange:x=>P(x.target.value),disabled:L,placeholder:r("docker.placeholders.apiKey","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:j,onChange:x=>b(x.target.checked),disabled:L}),r("docker.options.claudeCli","Claude CLI")]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:l,onChange:x=>y(x.target.checked),disabled:L}),r("docker.options.droidCli","Droid CLI")]}),e.jsxs("label",{className:"checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:n,onChange:x=>M(x.target.checked),disabled:L}),r("docker.options.persistentStorage","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:r("docker.labels.memory","Memory (MB)")}),e.jsx("input",{className:"input",type:"number",min:512,value:I,onChange:x=>O(Number(x.target.value)),disabled:L})]}),e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:r("docker.labels.cpus","CPUs")}),e.jsx("input",{className:"input",type:"number",min:.5,step:.5,value:R,onChange:x=>k(Number(x.target.value)),disabled:L})]})]}),G.memoryMB&&e.jsx("div",{className:"form-error",children:G.memoryMB}),G.cpus&&e.jsx("div",{className:"form-error",children:G.cpus})]}),e.jsxs("section",{className:"docker-onboarding__section",children:[e.jsxs("button",{type:"button",className:`docker-onboarding__advanced-toggle ${p?"is-expanded":""}`,onClick:()=>w(x=>!x),disabled:L,children:[e.jsx("span",{children:r("docker.sections.advanced","Advanced")}),e.jsx(we,{})]}),e.jsx("div",{className:`docker-onboarding__advanced-content ${p?"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:r("docker.labels.image","Image")}),e.jsx("input",{className:"input",value:Q,onChange:x=>q(x.target.value),disabled:L,placeholder:r("docker.placeholders.image","runfusion/fusion")})]}),e.jsxs("label",{className:"docker-onboarding__field",children:[e.jsx("span",{children:r("docker.labels.tag","Tag")}),e.jsx("input",{className:"input",value:X,onChange:x=>se(x.target.value),disabled:L,placeholder:r("docker.placeholders.tag","latest")})]})]}),e.jsxs("div",{className:"docker-onboarding__kv-list",children:[e.jsx("h5",{children:r("docker.sections.environmentVariables","Environment Variables")}),B.map((x,K)=>e.jsxs("div",{className:"docker-onboarding__kv-row docker-onboarding__kv-row--env",children:[e.jsx("input",{className:"input",placeholder:r("docker.placeholders.envVarKey","KEY"),value:x.key,disabled:L,onChange:H=>re(K,{key:H.target.value,value:x.value})}),e.jsx("input",{className:"input",placeholder:r("docker.placeholders.envVarValue","Value"),value:x.value,disabled:L,onChange:H=>re(K,{key:x.key,value:H.target.value})}),e.jsx("button",{type:"button",className:"btn btn-icon","aria-label":r("docker.ariaLabels.removeVariable","Remove environment variable"),onClick:()=>te(K),disabled:L,children:e.jsx(Ne,{size:14})})]},`env-${K}`)),e.jsxs("button",{type:"button",className:"btn btn-sm docker-onboarding__kv-add",onClick:oe,disabled:L,children:[e.jsx(ge,{size:14}),r("docker.actions.addVariable","Add variable")]})]}),e.jsxs("div",{className:"docker-onboarding__kv-list",children:[e.jsx("h5",{children:r("docker.sections.volumeMounts","Volume Mounts")}),Z.map((x,K)=>e.jsxs("div",{className:"docker-onboarding__kv-row docker-onboarding__kv-row--mount",children:[e.jsx("input",{className:"input",placeholder:r("docker.placeholders.hostPath","Host path"),value:x.hostPath,disabled:L,onChange:H=>A(K,{hostPath:H.target.value,containerPath:x.containerPath,mode:x.mode})}),e.jsx("input",{className:"input",placeholder:r("docker.placeholders.containerPath","Container path"),value:x.containerPath,disabled:L,onChange:H=>A(K,{hostPath:x.hostPath,containerPath:H.target.value,mode:x.mode})}),e.jsxs("select",{className:"select",value:x.mode,disabled:L,onChange:H=>A(K,{hostPath:x.hostPath,containerPath:x.containerPath,mode:H.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":r("docker.ariaLabels.removeMount","Remove volume mount"),onClick:()=>V(K),disabled:L,children:e.jsx(Ne,{size:14})})]},`mount-${K}`)),e.jsxs("button",{type:"button",className:"btn btn-sm docker-onboarding__kv-add",onClick:ce,disabled:L,children:[e.jsx(ge,{size:14}),r("docker.actions.addMount","Add mount")]})]})]})})]})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("button",{className:"btn",onClick:F,disabled:L,children:r("docker.actions.cancel","Cancel")}),e.jsx("button",{className:"btn btn-primary",onClick:()=>void W(),disabled:L,children:L?r("docker.states.creating","Creating..."):r("docker.actions.createNode","Create Docker Node")})]})]})}):null}function at({nodeId:t,entries:c,loading:a=!1,singleNode:i=!1}){const{t:r}=ne("app"),[m,o]=s.useState(!1),[g,N]=s.useState("all"),[h,u]=s.useState("all"),C=s.useCallback(()=>{o(l=>!l)},[]),S=s.useMemo(()=>{const l=new Set;for(const y of c)l.add(y.nodeName);return Array.from(l).sort()},[c]),f=s.useMemo(()=>{let l=[...c];return g!=="all"&&(l=l.filter(y=>y.direction===g)),!i&&h!=="all"&&(l=l.filter(y=>y.nodeName===h)),l.sort((y,n)=>{const M=new Date(y.timestamp).getTime();return new Date(n.timestamp).getTime()-M}),l},[c,g,h,i]),P=s.useCallback(l=>new Date(l).toLocaleString(),[]),j=s.useCallback(l=>{switch(l){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""}},[]),b=s.useCallback(l=>{switch(l){case"success":return r("syncLog.resultSuccess","Success");case"conflict":return r("syncLog.resultConflict","Conflict");case"error":return r("syncLog.resultError","Error");default:return l}},[r]);return e.jsxs("div",{className:"settings-sync-log",children:[e.jsxs("button",{className:"settings-sync-log__header",type:"button",onClick:C,"aria-expanded":m,"data-testid":"settings-sync-log-header",children:[e.jsx(we,{size:16,className:`settings-sync-log__chevron ${m?"settings-sync-log__chevron--expanded":""}`}),e.jsx("span",{children:r("syncLog.entryCount",{count:c.length,defaultValue_one:"{{count}} entry",defaultValue_other:"{{count}} entries"})})]}),m&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"settings-sync-log__filters",children:[e.jsxs("label",{children:[r("syncLog.filterDirection","Direction:"),e.jsxs("select",{value:g,onChange:l=>N(l.target.value),children:[e.jsx("option",{value:"all",children:r("syncLog.filterAll","All")}),e.jsx("option",{value:"push",children:r("syncLog.filterPush","Push")}),e.jsx("option",{value:"pull",children:r("syncLog.filterPull","Pull")})]})]}),!i&&e.jsxs("label",{children:[r("syncLog.filterNode","Node:"),e.jsxs("select",{value:h,onChange:l=>u(l.target.value),children:[e.jsx("option",{value:"all",children:r("syncLog.filterAllNodes","All Nodes")}),S.map(l=>e.jsx("option",{value:l,children:l},l))]})]})]}),a&&c.length===0?e.jsx("div",{className:"settings-sync-log__empty",children:r("syncLog.loading","Loading...")}):f.length===0?e.jsx("div",{className:"settings-sync-log__empty",children:r("syncLog.noHistory","No sync history available")}):e.jsx("div",{className:"settings-sync-log__list",children:f.map(l=>e.jsxs("div",{className:"settings-sync-log__entry",children:[e.jsx("span",{className:"settings-sync-log__entry-timestamp",children:P(l.timestamp)}),e.jsx("span",{className:"settings-sync-log__entry-direction",children:l.direction==="push"?e.jsx(Xe,{size:14,"data-testid":"upload-icon"}):e.jsx(Ye,{size:14,"data-testid":"download-icon"})}),e.jsx("span",{className:`settings-sync-log__entry-result ${j(l.result)}`,children:b(l.result)}),!i&&e.jsx("span",{className:"settings-sync-log__entry-node",children:l.nodeName}),l.details&&e.jsx("span",{className:"settings-sync-log__entry-details",title:l.details,children:xs(l.details??"")})]},l.id))})]})]})}function ot(t,c){const a=typeof t=="string"?t:JSON.stringify(t,null,2),i=typeof c=="string"?c:JSON.stringify(c,null,2);if(a===i)return a;const r=a.split(`
12
- `),m=i.split(`
13
- `),o=[],g=Math.max(r.length,m.length);for(let N=0;N<g;N++){const h=r[N],u=m[N];h!==void 0&&h!==u&&o.push(`- ${h}`),u!==void 0&&u!==h&&o.push(`+ ${u}`),h!==void 0&&h===u&&o.push(` ${h}`)}return o.join(`
14
- `)}function rt({isOpen:t,onClose:c,onResolve:a,conflicts:i,localNodeName:r,remoteNodeName:m,addToast:o}){const{t:g}=ne("app"),[N,h]=s.useState({}),[u,C]=s.useState(!1);s.useEffect(()=>{const l={};for(const y of i)N[y.key]||(l[y.key]={resolution:"local"});Object.keys(l).length>0&&h(y=>({...y,...l}))},[i,N]),s.useEffect(()=>{if(!t)return;const l=y=>{y.key==="Escape"&&(y.preventDefault(),c())};return document.addEventListener("keydown",l),()=>document.removeEventListener("keydown",l)},[t,c]);const S=s.useCallback((l,y)=>{h(n=>{const M=n[l]??{};return y==="manual"?{...n,[l]:{resolution:"manual",manualValue:M.manualValue??JSON.stringify(i.find(I=>I.key===l)?.localValue??null,null,2)}}:{...n,[l]:{resolution:y}}})},[i]),f=s.useCallback((l,y)=>{h(n=>({...n,[l]:{...n[l],resolution:"manual",manualValue:y}}))},[]),P=s.useCallback(l=>{const y={};for(const n of i)y[n.key]={resolution:l};h(y)},[i]),j=s.useCallback(async()=>{C(!0);try{const l=i.map(y=>{const n=N[y.key]??{resolution:"local"};let M;switch(n.resolution){case"remote":M=y.remoteValue;break;case"manual":try{M=JSON.parse(n.manualValue??"null")}catch{M=n.manualValue??null}break;case"local":default:M=y.localValue;break}return{key:y.key,value:M}});await a(l),o(g("settings.resolvedSuccess","Settings conflicts resolved successfully"),"success"),c()}catch(l){const y=l instanceof Error?l.message:g("settings.resolveFailed","Failed to resolve conflicts");o(y,"error")}finally{C(!1)}},[o,i,c,a,N]),b=s.useMemo(()=>{const l={};for(const y of i)l[y.key]=ot(y.localValue,y.remoteValue);return l},[i]);return!t||i.length===0?null:e.jsx("div",{className:"modal-overlay open",onClick:c,children:e.jsxs("div",{className:"modal modal-lg settings-sync-conflict-modal",onClick:l=>l.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":g("settings.conflictModalTitle","Resolve Settings Conflicts"),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:g("settings.conflictModalTitle","Resolve Settings Conflicts")}),e.jsx("button",{className:"modal-close",onClick:c,"aria-label":g("settings.closeModal","Close conflict modal"),children:"×"})]}),e.jsxs("div",{className:"modal-body",children:[e.jsx("div",{className:"settings-sync-conflict-modal__conflict-list",children:i.map(l=>{const y=N[l.key]??{resolution:"local"},n=b[l.key];return e.jsxs("div",{className:"settings-sync-conflict-modal__conflict-item",children:[e.jsx("div",{className:"settings-sync-conflict-modal__key",children:l.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:r}),e.jsx("div",{className:"settings-sync-conflict-modal__diff-content",children:e.jsx("pre",{style:{margin:0,whiteSpace:"pre-wrap"},children:n})})]}),e.jsxs("div",{className:"settings-sync-conflict-modal__diff-side",children:[e.jsx("div",{className:"settings-sync-conflict-modal__diff-label",children:m}),e.jsx("div",{className:"settings-sync-conflict-modal__diff-content",children:e.jsx("pre",{style:{margin:0,whiteSpace:"pre-wrap"},children:n})})]})]}),e.jsxs("div",{className:"settings-sync-conflict-modal__resolution",children:[e.jsxs("label",{children:[e.jsx("input",{type:"radio",name:`resolution-${l.key}`,checked:y.resolution==="local",onChange:()=>S(l.key,"local")}),g("settings.keepLocal","Keep Local")]}),e.jsxs("label",{children:[e.jsx("input",{type:"radio",name:`resolution-${l.key}`,checked:y.resolution==="remote",onChange:()=>S(l.key,"remote")}),g("settings.keepRemote","Keep Remote")]}),e.jsxs("label",{children:[e.jsx("input",{type:"radio",name:`resolution-${l.key}`,checked:y.resolution==="manual",onChange:()=>S(l.key,"manual")}),g("settings.mergeManually","Merge Manually")]})]}),y.resolution==="manual"&&e.jsx("textarea",{className:"settings-sync-conflict-modal__manual-input",value:y.manualValue??"",onChange:M=>f(l.key,M.target.value),placeholder:g("settings.jsonPlaceholder","Enter JSON value...")})]},l.key)})}),e.jsxs("div",{className:"settings-sync-conflict-modal__bulk-actions",children:[e.jsx("button",{className:"btn btn-sm",onClick:()=>P("local"),type:"button",children:g("settings.resolveAllLocal","Resolve All: Keep Local")}),e.jsx("button",{className:"btn btn-sm",onClick:()=>P("remote"),type:"button",children:g("settings.resolveAllRemote","Resolve All: Keep Remote")})]})]}),e.jsxs("div",{className:"modal-actions settings-sync-conflict-modal__footer",children:[e.jsx("button",{className:"btn btn-sm",onClick:c,children:g("actions.cancel","Cancel")}),e.jsx("button",{className:"btn btn-primary btn-sm",onClick:j,disabled:u,children:u?g("settings.resolving","Resolving..."):g("actions.confirm","Confirm")})]})]})})}const Je=/(KEY|TOKEN|SECRET|PASSWORD)/i;function je(t){if(!t)return"—";const c=new Date(t);return Number.isNaN(c.getTime())?"—":c.toLocaleString()}function lt(t){if(!t)return"—";const c=new Date(t),a=Date.now();if(Number.isNaN(c.getTime())||c.getTime()>a)return"—";const i=Math.floor((a-c.getTime())/1e3);if(i<60)return`${i}s`;const r=Math.floor(i/60);if(r<60)return`${r}m`;const m=Math.floor(r/60);return m<24?`${m}h ${r%60}m`:`${Math.floor(m/24)}d ${m%24}h`}function ct(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 it(t){return t==="running"?"success":t==="creating"||t==="recreating"||t==="restarting"?"warning":"error"}function dt(t){return t?`${t.charAt(0).toUpperCase()}${t.slice(1)}`:"Unknown"}function ut(t){if(!t)return"—";try{const c=new URL(t);return c.port?c.port:c.protocol==="https:"?"443":c.protocol==="http:"?"80":"—"}catch{return"—"}}function mt(t,c){return Je.test(t)?"••••••••":c}function ht({isOpen:t,onClose:c,node:a,projects:i,onUpdate:r,onHealthCheck:m,addToast:o,syncStatus:g,onPushSettings:N,onPullSettings:h,onSyncAuth:u,syncHistory:C=[],onResolveConflicts:S,managedDockerNode:f,containerStatus:P,onFetchContainerStatus:j,onFetchLogs:b,onUpdateDockerConfig:l,onFetchDockerConfigDiff:y}){const{t:n}=ne("app"),M=s.useRef(!0),[I,O]=s.useState(!1),[R,k]=s.useState(""),[p,w]=s.useState(""),[Q,q]=s.useState(""),[X,se]=s.useState(2),[B,J]=s.useState(!1),[Z,ae]=s.useState(!1),[G,T]=s.useState(!1),[L,_]=s.useState(!1),[D,F]=s.useState(null),[U,oe]=s.useState(!1),[re]=s.useState([]),[te,ce]=s.useState(P),[A,V]=s.useState(!1),[W,x]=s.useState(!1),[K,H]=s.useState(""),[Y,ie]=s.useState(!1),[pe,Re]=s.useState(!1),[v,z]=s.useState(a?.dockerConfig??null),[Ee,Le]=s.useState({}),[ue,Ae]=s.useState(!1),[Ge,De]=s.useState(!1);s.useEffect(()=>(M.current=!0,()=>{M.current=!1}),[]),s.useEffect(()=>{ce(P)},[P]),s.useEffect(()=>{if(!a||!t){O(!1),x(!1),H("");return}k(a.name),w(a.url??""),q(a.apiKey??""),se(a.maxConcurrent),O(!1),z(a.dockerConfig??null),Re(!1),Le({})},[t,a]),s.useEffect(()=>{if(!t)return;const d=E=>{E.key==="Escape"&&(E.preventDefault(),c())};return document.addEventListener("keydown",d),()=>document.removeEventListener("keydown",d)},[t,c]);const xe=s.useMemo(()=>a?vs(i,a):[],[a,i]),We=s.useMemo(()=>f?f.hostConfig.type==="remote"?f.hostConfig.host??"—":n("nodes.localDocker","Local Docker"):"—",[f,n]),Ze=s.useMemo(()=>!f?.resourceSizing?.cpuLimit&&!f?.resourceSizing?.memoryLimit?n("nodes.dockerResourceDefault","Default"):`${f.resourceSizing?.cpuLimit??n("nodes.dockerDefaultCpu","Default CPU")} / ${f.resourceSizing?.memoryLimit??n("nodes.dockerDefaultMemory","Default memory")}`,[f,n]),Qe=s.useCallback(async()=>{if(a)try{if(await m(a.id),!M.current)return;o(n("nodes.healthCheckSuccess","Health check completed for {{name}}",{name:a.name}),"success")}catch(d){if(!M.current)return;const E=d instanceof Error?d.message:n("nodes.healthCheckFailed","Health check failed");o(E,"error")}},[o,a,m]),es=s.useCallback(async()=>{if(!(!a||!N)){F(null),ae(!0);try{if(await N(a.id),!M.current)return;o(n("nodes.pushSettingsSuccess","Settings pushed successfully"),"success")}catch(d){if(!M.current)return;const E=d instanceof Error?d.message:n("nodes.pushSettingsFailed","Push settings failed");F(E),o(E,"error")}finally{M.current&&ae(!1)}}},[o,a,N]),ss=s.useCallback(async()=>{if(!(!a||!h)){F(null),T(!0);try{if(await h(a.id),!M.current)return;o(n("nodes.pullSettingsSuccess","Settings pulled successfully"),"success")}catch(d){if(!M.current)return;const E=d instanceof Error?d.message:n("nodes.pullSettingsFailed","Pull settings failed");F(E),o(E,"error")}finally{M.current&&T(!1)}}},[o,a,h]),ts=s.useCallback(async()=>{if(!(!a||!u)){F(null),_(!0);try{if(await u(a.id),!M.current)return;o(n("nodes.syncAuthSuccess","Auth credentials synced successfully"),"success")}catch(d){if(!M.current)return;const E=d instanceof Error?d.message:n("nodes.syncAuthFailed","Auth sync failed");F(E),o(E,"error")}finally{M.current&&_(!1)}}},[o,a,u]),ns=s.useCallback(()=>{F(null)},[]),as=s.useCallback(async()=>{if(!(!f||!j)){V(!0);try{const d=await j(f.id);if(!M.current)return;ce(d)}catch(d){const E=d instanceof Error?d.message:n("nodes.fetchContainerStatusFailed","Failed to fetch container status");o(E,"error")}finally{M.current&&V(!1)}}},[o,f,j]),os=s.useCallback(async()=>{if(!(!f||!b)){x(!0),ie(!0);try{const d=await b(f.id);if(!M.current)return;H(d)}catch(d){if(!M.current)return;H("");const E=d instanceof Error?d.message:n("nodes.fetchContainerLogsFailed","Failed to fetch container logs");o(E,"error")}finally{M.current&&ie(!1)}}},[o,f,b]),rs=s.useCallback(async()=>{if(!a||B)return;const d=R.trim();if(!d){o(n("nodes.nameRequired","Name is required"),"error");return}if(a.type==="remote"&&!p.trim()){o(n("nodes.urlRequired","URL is required for remote nodes"),"error");return}if(!Number.isFinite(X)||X<1){o(n("nodes.concurrencyMin","Concurrency must be at least 1"),"error");return}J(!0);try{await r(a.id,{name:d,url:a.type==="remote"&&p.trim()||void 0,apiKey:a.type==="remote"&&Q||void 0,maxConcurrent:X}),o(n("nodes.updateSuccess","Updated {{name}}",{name:d}),"success"),O(!1)}catch(E){const ee=E instanceof Error?E.message:n("nodes.updateFailed","Failed to update node");o(ee,"error")}finally{J(!1)}},[o,Q,B,X,R,a,r,p]);s.useEffect(()=>{!a?.dockerConfig||!y||!t||y(a.id).then(d=>{M.current&&De(d.needsRecreate)}).catch(()=>{M.current&&De(!1)})},[t,a,y]);const ls=s.useCallback(async()=>{if(!(!a||!v||!l||ue)){Ae(!0);try{const d=await l(a.id,{image:v.image,volumeMounts:v.volumeMounts,environment:v.environment,resources:v.resources,host:v.host,extraClis:v.extraClis,persistence:v.persistence,containerName:v.containerName});if(!M.current)return;z(d),o(n("nodes.dockerConfigSaveSuccess","Docker config saved"),"success")}catch(d){if(!M.current)return;const E=d instanceof Error?d.message:n("nodes.dockerConfigSaveFailed","Failed to save Docker config");o(E,"error")}finally{M.current&&Ae(!1)}}},[o,v,ue,a,l]),cs=s.useCallback(()=>{a&&(k(a.name),w(a.url??""),q(a.apiKey??""),se(a.maxConcurrent),O(!1))},[a]);if(!t||!a)return null;const le=te?.status??f?.status,is=it(le);return e.jsxs("div",{className:"modal-overlay open",onClick:c,children:[e.jsxs("div",{className:"modal modal-lg node-detail-modal",onClick:d=>d.stopPropagation(),role:"dialog","aria-modal":"true","aria-label":n("nodes.modalAriaLabel","Node details for {{name}}",{name:a.name}),children:[e.jsxs("div",{className:"modal-header",children:[e.jsx("h3",{children:n("nodes.modalTitle","Node Details")}),e.jsx("button",{className:"modal-close",onClick:c,"aria-label":n("nodes.closeModalAriaLabel","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:n("nodes.sectionOverview","Overview")}),!I&&e.jsxs("button",{className:"btn btn-sm",onClick:()=>O(!0),children:[e.jsx(bs,{size:14}),n("nodes.editButton","Edit")]})]}),e.jsxs("div",{className:"node-detail-modal__grid",children:[e.jsxs("label",{className:"node-detail-modal__field",children:[e.jsx("span",{children:n("nodes.fieldName","Name")}),I?e.jsx("input",{className:"input",value:R,onChange:d=>k(d.target.value),disabled:B}):e.jsx("strong",{children:a.name})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:n("nodes.fieldType","Type")}),e.jsx("strong",{children:a.type==="local"?n("nodes.typeLocal","Local"):n("nodes.typeRemote","Remote")})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:n("nodes.fieldStatus","Status")}),e.jsx("strong",{children:a.status})]}),e.jsxs("label",{className:"node-detail-modal__field",children:[e.jsx("span",{children:n("nodes.fieldMaxConcurrent","Max Concurrent")}),I?e.jsx("input",{className:"input",type:"number",min:1,max:10,value:X,onChange:d=>se(Number(d.target.value)),disabled:B}):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:n("nodes.fieldUrl","URL")}),I?e.jsx("input",{className:"input",value:p,onChange:d=>w(d.target.value),disabled:B}):e.jsx("strong",{children:a.url??"—"})]}),e.jsxs("label",{className:"node-detail-modal__field node-detail-modal__field--full",children:[e.jsx("span",{children:n("nodes.fieldApiKey","API Key")}),I?e.jsx("input",{className:"input",type:"password",value:Q,onChange:d=>q(d.target.value),placeholder:n("nodes.apiKeyPlaceholder","Leave blank to keep unchanged"),disabled:B}):e.jsx("strong",{children:a.apiKey?"••••••••":n("nodes.apiKeyNotConfigured","Not configured")})]})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:n("nodes.fieldCreated","Created")}),e.jsx("strong",{children:je(a.createdAt)})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:n("nodes.fieldUpdated","Updated")}),e.jsx("strong",{children:je(a.updatedAt)})]})]}),I&&e.jsxs("div",{className:"node-detail-modal__edit-actions",children:[e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:rs,disabled:B,children:[e.jsx(Fe,{size:14}),B?n("nodes.saving","Saving..."):n("nodes.saveButton","Save")]}),e.jsxs("button",{className:"btn btn-sm",onClick:cs,disabled:B,children:[e.jsx(he,{size:14}),n("nodes.cancelButton","Cancel")]})]})]}),e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsxs("h4",{children:[a.type==="local"?n("nodes.sectionProjects","Projects"):n("nodes.sectionAssignedProjects","Assigned Projects")," (",xe.length,")"]}),xe.length===0?e.jsx("p",{className:"node-detail-modal__empty",children:a.type==="local"?n("nodes.noProjectsRunning","No projects are running on this node."):n("nodes.noProjectsAssigned","No projects are assigned to this node.")}):e.jsx("ul",{className:"node-detail-modal__project-list",children:xe.map(d=>e.jsxs("li",{className:"node-detail-modal__project-item",children:[e.jsx("span",{children:d.name}),e.jsx("code",{children:d.id})]},d.id))})]}),e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsx("h4",{children:n("nodes.sectionHealth","Health")}),e.jsxs("div",{className:"node-detail-modal__health-row",children:[e.jsxs("span",{children:[n("nodes.healthStatus","Status:")," ",e.jsx("strong",{children:a.status})]}),e.jsxs("span",{children:[n("nodes.healthLastCheck","Last check:")," ",e.jsx("strong",{children:je(a.updatedAt)})]})]})]}),v&&e.jsxs("section",{className:"node-detail-modal__section node-detail-modal__docker-config",children:[e.jsxs("button",{className:"btn btn-sm node-detail-modal__docker-toggle",onClick:()=>Re(d=>!d),"aria-expanded":pe,children:[e.jsx(we,{size:14,className:pe?"node-detail-modal__docker-toggle-icon--expanded":""}),n("nodes.dockerConfiguration","Docker Configuration")]}),pe&&e.jsxs("div",{className:"node-detail-modal__docker-config-content",children:[e.jsx("div",{className:"node-detail-modal__grid",children:e.jsxs("label",{className:"node-detail-modal__field node-detail-modal__field--full",children:[e.jsx("span",{children:n("nodes.dockerFieldImage","Image")}),e.jsx("input",{className:"input",value:v.image,onChange:d=>z({...v,image:d.target.value})})]})}),e.jsxs("details",{children:[e.jsx("summary",{children:n("nodes.dockerVolumeMounts","Volume Mounts")}),e.jsxs("div",{className:"node-detail-modal__docker-list",children:[v.volumeMounts.map((d,E)=>e.jsxs("div",{className:"node-detail-modal__docker-row",children:[e.jsx("input",{className:"input",value:d.hostPath,placeholder:n("nodes.dockerHostPath","Host path"),onChange:ee=>{const $=[...v.volumeMounts];$[E]={...$[E],hostPath:ee.target.value},z({...v,volumeMounts:$})}}),e.jsx("input",{className:"input",value:d.containerPath,placeholder:n("nodes.dockerContainerPath","Container path"),onChange:ee=>{const $=[...v.volumeMounts];$[E]={...$[E],containerPath:ee.target.value},z({...v,volumeMounts:$})}}),e.jsxs("select",{className:"input",value:d.mode??"rw",onChange:ee=>{const $=[...v.volumeMounts];$[E]={...$[E],mode:ee.target.value},z({...v,volumeMounts:$})},children:[e.jsx("option",{value:"rw",children:"rw"}),e.jsx("option",{value:"ro",children:"ro"})]}),e.jsxs("select",{className:"input",value:d.type??"volume",onChange:ee=>{const $=[...v.volumeMounts];$[E]={...$[E],type:ee.target.value},z({...v,volumeMounts:$})},children:[e.jsx("option",{value:"volume",children:"volume"}),e.jsx("option",{value:"bind",children:"bind"})]}),e.jsx("button",{className:"btn btn-sm",onClick:()=>z({...v,volumeMounts:v.volumeMounts.filter((ee,$)=>$!==E)}),children:n("nodes.removeButton","Remove")})]},`${d.hostPath}-${d.containerPath}-${E}`)),e.jsx("button",{className:"btn btn-sm",onClick:()=>z({...v,volumeMounts:[...v.volumeMounts,{hostPath:"",containerPath:"",mode:"rw",type:"volume"}]}),children:n("nodes.addMountButton","Add Mount")})]})]}),e.jsxs("details",{children:[e.jsx("summary",{children:n("nodes.dockerEnvVars","Environment Variables")}),e.jsxs("div",{className:"node-detail-modal__docker-list",children:[Object.entries(v.environment).map(([d,E])=>{const ee=Je.test(d)&&!Ee[d];return e.jsxs("div",{className:"node-detail-modal__docker-row",children:[e.jsx("input",{className:"input",value:d,onChange:$=>{const ve={...v.environment};delete ve[d],ve[$.target.value]=E,z({...v,environment:ve})}}),e.jsx("input",{className:"input",value:ee?"***":String(E),onChange:$=>z({...v,environment:{...v.environment,[d]:$.target.value}})}),e.jsx("button",{className:"btn btn-sm",onClick:()=>Le($=>({...$,[d]:!$[d]})),children:Ee[d]?e.jsx(ys,{size:14}):e.jsx(js,{size:14})}),e.jsx("button",{className:"btn btn-sm",onClick:()=>{const $={...v.environment};delete $[d],z({...v,environment:$})},children:n("nodes.removeButton","Remove")})]},d)}),e.jsx("button",{className:"btn btn-sm",onClick:()=>{const d=`NEW_VAR_${Object.keys(v.environment).length+1}`;z({...v,environment:{...v.environment,[d]:""}})},children:n("nodes.addVariableButton","Add Variable")})]})]}),e.jsxs("details",{children:[e.jsx("summary",{children:n("nodes.dockerResources","Resources")}),e.jsxs("div",{className:"node-detail-modal__docker-stack",children:[e.jsx("input",{className:"input",type:"number",placeholder:n("nodes.dockerMemoryBytes","Memory bytes (2 GB = 2147483648)"),value:v.resources?.memoryBytes??"",onChange:d=>z({...v,resources:{...v.resources,memoryBytes:d.target.value?Number(d.target.value):void 0}})}),e.jsx("input",{className:"input",type:"number",placeholder:n("nodes.dockerCpuCount","CPU count"),value:v.resources?.cpuCount??"",onChange:d=>z({...v,resources:{...v.resources,cpuCount:d.target.value?Number(d.target.value):void 0}})}),e.jsx("input",{className:"input",type:"number",placeholder:n("nodes.dockerPidsLimit","PIDs limit"),value:v.resources?.pidsLimit??"",onChange:d=>z({...v,resources:{...v.resources,pidsLimit:d.target.value?Number(d.target.value):void 0}})})]})]}),e.jsxs("details",{children:[e.jsx("summary",{children:n("nodes.dockerHostConfig","Host Config")}),e.jsxs("div",{className:"node-detail-modal__docker-stack",children:[e.jsx("input",{className:"input",placeholder:n("nodes.dockerContextName","Context name"),value:v.host?.contextName??"",onChange:d=>z({...v,host:{...v.host,contextName:d.target.value}})}),e.jsx("input",{className:"input",placeholder:n("nodes.dockerHostUrl","Docker host URL"),value:v.host?.dockerHost??"",onChange:d=>z({...v,host:{...v.host,dockerHost:d.target.value}})}),e.jsx("input",{className:"input",placeholder:n("nodes.dockerTlsCaCert","TLS CA cert path"),value:v.host?.tlsCaCert??"",onChange:d=>z({...v,host:{...v.host,tlsCaCert:d.target.value}})}),e.jsx("input",{className:"input",placeholder:n("nodes.dockerTlsCert","TLS cert path"),value:v.host?.tlsCert??"",onChange:d=>z({...v,host:{...v.host,tlsCert:d.target.value}})}),e.jsx("input",{className:"input",placeholder:n("nodes.dockerTlsKey","TLS key path"),value:v.host?.tlsKey??"",onChange:d=>z({...v,host:{...v.host,tlsKey:d.target.value}})}),e.jsxs("label",{className:"node-detail-modal__checkbox",children:[e.jsx("input",{type:"checkbox",checked:v.host?.tlsVerify??!0,onChange:d=>z({...v,host:{...v.host,tlsVerify:d.target.checked}})}),n("nodes.dockerTlsVerify","TLS verify")]})]})]}),e.jsxs("details",{children:[e.jsx("summary",{children:n("nodes.dockerExtraClis","Extra CLIs")}),e.jsxs("div",{className:"node-detail-modal__docker-list",children:[(v.extraClis??[]).map((d,E)=>e.jsxs("div",{className:"node-detail-modal__docker-row",children:[e.jsx("input",{className:"input",value:d,onChange:ee=>{const $=[...v.extraClis??[]];$[E]=ee.target.value,z({...v,extraClis:$})}}),e.jsx("button",{className:"btn btn-sm",onClick:()=>z({...v,extraClis:(v.extraClis??[]).filter((ee,$)=>$!==E)}),children:n("nodes.removeButton","Remove")})]},`${d}-${E}`)),e.jsx("button",{className:"btn btn-sm",onClick:()=>z({...v,extraClis:[...v.extraClis??[],""]}),children:n("nodes.addCliButton","Add CLI")})]})]}),e.jsxs("details",{children:[e.jsx("summary",{children:n("nodes.dockerPersistence","Persistence")}),e.jsxs("div",{className:"node-detail-modal__docker-stack",children:[e.jsx("input",{className:"input",placeholder:n("nodes.dockerVolumeName","Volume name"),value:v.persistence?.volumeName??"",onChange:d=>z({...v,persistence:{...v.persistence,volumeName:d.target.value}})}),e.jsxs("label",{className:"node-detail-modal__checkbox",children:[e.jsx("input",{type:"checkbox",checked:v.persistence?.retainOnDelete??!1,onChange:d=>z({...v,persistence:{...v.persistence,retainOnDelete:d.target.checked}})}),n("nodes.dockerRetainOnDelete","Retain on delete")]})]})]}),e.jsxs("div",{className:"node-detail-modal__docker-meta",children:[e.jsxs("span",{children:["Config v",v.configVersion," • Updated ",Se(v.lastUpdated??a.updatedAt)]}),Ge&&e.jsx("span",{className:"node-detail-modal__docker-recreate",children:n("nodes.dockerNeedsRecreate","Needs Recreate")})]}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:()=>void ls(),disabled:ue,children:[e.jsx(Fe,{size:14}),ue?n("nodes.saving","Saving..."):n("nodes.saveDockerConfig","Save Docker Config")]})]})]}),f&&e.jsxs("section",{className:"node-detail-modal__section docker-management",children:[e.jsx("h4",{children:n("nodes.sectionDockerManagement","Docker Management")}),e.jsxs("div",{className:"docker-management__status-card",children:[e.jsxs("div",{className:"docker-management__status-row",children:[e.jsx("span",{className:`docker-management__status-dot docker-management__status-dot--${is}`,"aria-hidden":!0}),e.jsx("strong",{children:le?dt(le):n("nodes.dockerStatusUnknown","Unknown")}),(le==="creating"||le==="recreating"||le==="restarting")&&e.jsx(Ve,{size:14,className:"spin","aria-hidden":!0})]}),e.jsxs("div",{className:"docker-management__status-meta",children:[le==="running"&&e.jsxs("span",{children:[n("nodes.dockerUptime","Uptime:")," ",lt(te?.startedAt)]}),le!=="running"&&te?.exitCode!==void 0&&e.jsxs("span",{children:[n("nodes.dockerExitCode","Exit code:")," ",te.exitCode]}),(te?.error||f.errorMessage)&&e.jsx("span",{children:te?.error??f.errorMessage})]}),e.jsx("button",{className:"btn btn-sm",onClick:()=>void as(),disabled:!j||A,children:A?n("nodes.refreshing","Refreshing..."):n("nodes.refreshStatus","Refresh Status")})]}),e.jsxs("div",{className:"node-detail-modal__grid docker-management__info-grid",children:[e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:n("nodes.dockerFieldImage","Image")}),e.jsx("strong",{children:e.jsxs("code",{children:[f.imageName,":",f.imageTag]})})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:n("nodes.dockerContainerId","Container ID")}),e.jsx("strong",{children:e.jsx("code",{children:f.containerId?f.containerId.slice(0,12):"—"})})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:n("nodes.dockerHost","Host")}),e.jsx("strong",{children:We})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:n("nodes.dockerPersistentStorage","Persistent Storage")}),e.jsx("strong",{children:f.persistentStorage?n("nodes.yes","Yes"):n("nodes.no","No")})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:n("nodes.dockerPort","Port")}),e.jsx("strong",{children:ut(f.reachableUrl)})]}),e.jsxs("div",{className:"node-detail-modal__field",children:[e.jsx("span",{children:n("nodes.dockerResourceSizing","Resource Sizing")}),e.jsx("strong",{children:Ze})]})]}),e.jsxs("div",{className:"docker-management__actions",children:[e.jsxs("button",{className:"btn btn-sm",disabled:!0,title:n("nodes.availableSoon","Available after FN-3113"),children:[e.jsx(He,{size:14}),n("nodes.startButton","Start")]}),e.jsxs("button",{className:"btn btn-sm",disabled:!0,title:n("nodes.availableSoon","Available after FN-3113"),children:[e.jsx(qe,{size:14}),n("nodes.stopButton","Stop")]}),e.jsxs("button",{className:"btn btn-sm",disabled:!0,title:n("nodes.availableSoon","Available after FN-3113"),children:[e.jsx(Ve,{size:14}),n("nodes.restartButton","Restart")]}),e.jsxs("button",{className:"btn btn-sm",onClick:()=>void os(),disabled:!b,children:[e.jsx(ks,{size:14}),n("nodes.viewLogsButton","View Logs")]})]}),W&&e.jsxs("div",{className:"docker-management__log-viewer",children:[e.jsxs("div",{className:"docker-management__log-viewer-header",children:[e.jsx("strong",{children:n("nodes.containerLogs","Container Logs")}),e.jsx("button",{className:"btn-icon",onClick:()=>x(!1),"aria-label":n("nodes.closeLogsAriaLabel","Close logs"),children:e.jsx(he,{size:14})})]}),Y?e.jsx("p",{children:n("nodes.fetchingLogs","Fetching logs...")}):e.jsx("pre",{children:K.trim()||n("nodes.noLogsAvailable","No logs available")})]}),e.jsxs("details",{children:[e.jsx("summary",{children:n("nodes.dockerEnvVars","Environment Variables")}),e.jsx("dl",{className:"docker-management__env-list",children:Object.entries(f.envVars).map(([d,E])=>e.jsxs("div",{children:[e.jsx("dt",{children:d}),e.jsx("dd",{children:mt(d,E)})]},d))})]}),e.jsxs("details",{children:[e.jsx("summary",{children:n("nodes.dockerVolumeMounts","Volume Mounts")}),e.jsx("ul",{className:"docker-management__mounts-list",children:f.volumeMounts.map(d=>e.jsxs("li",{children:[e.jsxs("span",{children:[d.hostPath," → ",d.containerPath]}),d.readOnly&&e.jsx("span",{className:"node-card__type-badge",children:n("nodes.readOnly","Read-only")})]},`${d.hostPath}:${d.containerPath}`))})]})]}),a.type==="remote"&&e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsx("h4",{children:n("nodes.sectionSettingsSync","Settings Sync")}),g&&e.jsxs("div",{className:"node-detail-modal__sync-status",children:[e.jsx("span",{className:`node-detail-modal__sync-dot ${ct(g.syncState)}`,"aria-hidden":!0}),e.jsxs("span",{children:[n("nodes.syncLastSync","Last sync:")," ",e.jsx("strong",{children:g.lastSyncAt?Se(g.lastSyncAt):n("nodes.syncNeverSynced","Never synced")})]}),g.diffCount>0&&e.jsxs("span",{className:"node-detail-modal__sync-diff",children:[n("nodes.syncDifferences","Differences:")," ",e.jsx("strong",{children:g.diffCount})]})]}),e.jsxs("div",{className:"node-detail-modal__sync-actions",children:[e.jsxs("button",{className:"btn btn-sm",onClick:es,disabled:Z||!N,children:[e.jsx(Xe,{size:14}),Z?n("nodes.pushing","Pushing..."):n("nodes.pushSettings","Push Settings")]}),e.jsxs("button",{className:"btn btn-sm",onClick:ss,disabled:G||!h,children:[e.jsx(Ye,{size:14}),G?n("nodes.pulling","Pulling..."):n("nodes.pullSettings","Pull Settings")]}),e.jsxs("button",{className:"btn btn-sm",onClick:ts,disabled:L||!u,children:[e.jsx(Be,{size:14}),L?n("nodes.syncing","Syncing..."):n("nodes.syncAuth","Sync Auth")]})]}),D&&e.jsxs("div",{className:"node-detail-modal__sync-error",children:[e.jsx("span",{children:D}),e.jsx("button",{className:"node-detail-modal__sync-error-dismiss",onClick:ns,"aria-label":n("nodes.dismissError","Dismiss error"),children:e.jsx(he,{size:14})})]})]}),a.type==="remote"&&e.jsxs("section",{className:"node-detail-modal__section",children:[e.jsx("h4",{children:n("nodes.sectionSyncHistory","Sync History")}),e.jsx(at,{nodeId:a.id,entries:C,singleNode:!0})]})]}),e.jsxs("div",{className:"modal-actions node-detail-modal__actions",children:[e.jsxs("button",{className:"btn btn-sm",onClick:Qe,children:[e.jsx(Te,{size:14}),n("nodes.healthCheckButton","Health Check")]}),e.jsx("button",{className:"btn btn-sm",onClick:c,children:n("nodes.closeButton","Close")})]})]}),a.type==="remote"&&e.jsx(rt,{isOpen:U,onClose:()=>oe(!1),onResolve:S??(async()=>{}),conflicts:re,localNodeName:n("nodes.localNodeName","Local"),remoteNodeName:a.name,addToast:o})]})}const ft=15e3,gt=1e3;function pt(){const[t,c]=s.useState([]),[a,i]=s.useState(!0),[r,m]=s.useState(null),o=s.useRef(null),g=s.useRef(0),N=s.useRef(t),h=Ke();s.useEffect(()=>{N.current=t},[t]);const u=s.useCallback(j=>N.current.length>0&&Ue(j,h.wasRecentlyHidden()),[h]),C=s.useCallback(async()=>{try{m(null);const j=await $e();c(j)}catch(j){const b=j instanceof Error?j.message:"Failed to fetch managed Docker nodes";u(b)||m(b)}},[u]);s.useEffect(()=>{let j=!1;async function b(){i(!0);try{const y=await $e();j||(c(y),m(null))}catch(y){const n=y instanceof Error?y.message:"Failed to fetch managed Docker nodes";!j&&!u(n)&&m(n)}finally{j||i(!1)}}b();const l=()=>{if(document.visibilityState!=="visible")return;const y=Date.now(),n=y-g.current;if(n<gt){fe({view:"useManagedDockerNodes",trigger:"visibility",projectId:void 0,replayAttempted:!1,reason:"debounce-skipped",detail:{timeSinceLastRefreshMs:n}});return}g.current=y,fe({view:"useManagedDockerNodes",trigger:"visibility",projectId:void 0,replayAttempted:!1,reason:"debounced-refresh"}),C()};return document.addEventListener("visibilitychange",l),()=>{j=!0,document.removeEventListener("visibilitychange",l)}},[C,u]),s.useEffect(()=>{if(!a)return o.current=setInterval(()=>{C()},ft),()=>{o.current&&(clearInterval(o.current),o.current=null)}},[a,C]);const S=s.useCallback(async j=>_s(j),[]),f=s.useCallback(async(j,b)=>(await Ns(j,b)).logs,[]),P=s.useCallback(async j=>{const b=await Cs(j),l={...b,nodeId:b.nodeId??void 0,containerId:b.containerId??void 0,status:b.status,hostConfig:{type:b.hostConfig.host||b.hostConfig.context?"remote":"local",host:b.hostConfig.host,context:b.hostConfig.context},reachableUrl:b.reachableUrl??void 0,volumeMounts:b.volumeMounts.map(y=>({hostPath:y.hostPath,containerPath:y.containerPath,readOnly:y.mode==="ro"?!0:void 0})),persistentStorage:b.persistentStorage,resourceSizing:{cpuLimit:b.resourceSizing.cpus!==void 0?String(b.resourceSizing.cpus):void 0,memoryLimit:b.resourceSizing.memoryMB!==void 0?`${b.resourceSizing.memoryMB}MB`:void 0},errorMessage:b.errorMessage??void 0};return c(y=>[...y,l]),l},[]);return{dockerNodes:t,loading:a,error:r,refresh:C,getContainerStatus:S,getLogs:f,create:P}}function Ct({addToast:t,onClose:c}){const{t:a}=ne("app"),{nodes:i,loading:r,error:m,refresh:o,register:g,update:N,unregister:h,healthCheck:u,patchDockerConfig:C,fetchDockerDiff:S,discoverRemoteProjects:f}=Ss(),{projects:P,refresh:j}=Ms(),{meshState:b,loading:l,error:y}=zs(),{syncStatusMap:n,pushSettings:M,pullSettings:I,syncAuth:O,trackNode:R,getAuthSyncState:k,getAuthProviders:p}=Fs(),{dockerNodes:w,loading:Q,refresh:q,getContainerStatus:X,getLogs:se,create:B}=pt(),[J,Z]=s.useState(!1),[ae,G]=s.useState(!1),[T,L]=s.useState(null);s.useEffect(()=>{const A=i.filter(V=>V.type==="remote");for(const V of A)R(V.id)},[i,R]),s.useEffect(()=>{if(!T)return;const A=i.find(V=>V.id===T.id)??null;L(A)},[i,T]);const _=s.useMemo(()=>{const A=i.length,V=i.filter(Y=>Y.status==="online").length,W=i.filter(Y=>Y.status==="offline"||Y.status==="error").length,x=i.filter(Y=>Y.type==="remote").length,K=i.filter(Y=>Y.type==="remote"&&n[Y.id]&&be(n[Y.id]).syncState==="synced").length,H=w.length;return{total:A,online:V,offline:W,remote:x,synced:K,docker:H}},[w.length,i,n]),D=s.useCallback(async A=>{await g(A),await j()},[j,g]),F=s.useCallback(async A=>{try{await B(A),t(a("nodes.dockerNodeCreated",'Docker node "{{name}}" created',{name:A.name}),"success"),G(!1)}catch(V){const W=V instanceof Error?V.message:a("nodes.failedCreateDocker","Failed to create Docker node");throw t(W,"error"),V}},[t,B,a]),U=s.useMemo(()=>{const A=new Map;for(const V of w)V.nodeId&&A.set(V.nodeId,V);return A},[w]),oe=s.useCallback(async()=>{try{await Promise.all([o(),q()])}catch{t(a("nodes.failedRefresh","Failed to refresh nodes"),"error")}},[t,o,q,a]),re=s.useCallback(async A=>{try{await u(A),t(a("nodes.healthCheckComplete","Node health check complete"),"success")}catch(V){const W=V instanceof Error?V.message:a("nodes.healthCheckFailed","Health check failed");t(W,"error")}},[t,u,a]),te=s.useCallback(async A=>{try{await h(A),t(a("nodes.removed","Node removed"),"success"),T?.id===A&&L(null)}catch(V){const W=V instanceof Error?V.message:a("nodes.failedRemove","Failed to remove node");t(W,"error")}},[t,T?.id,h,a]),ce=s.useCallback(async(A,V)=>{await N(A,V)},[N]);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(Oe,{size:20}),a("nodes.heading","Nodes")]}),e.jsx("span",{className:"nodes-view-count",children:a("nodes.registeredCount","{{count}} registered",{count:i.length})})]}),e.jsxs("div",{className:"nodes-view-actions",children:[e.jsx("button",{className:"btn-icon nodes-view-close",onClick:c,"aria-label":a("nodes.closeAriaLabel","Close nodes view"),children:e.jsx(he,{size:16})}),e.jsxs("button",{className:"btn btn-sm",onClick:()=>void oe(),disabled:r||Q,children:[e.jsx(Ce,{size:14,className:r?"spin":""}),a("nodes.refresh","Refresh")]}),e.jsxs("button",{className:"btn btn-sm",onClick:()=>Z(!0),children:[e.jsx(ge,{size:14}),a("nodes.addNode","Add Node")]}),e.jsxs("button",{className:"btn btn-sm",onClick:()=>G(!0),title:a("nodes.addDockerNodeTitle","Add a managed Docker node"),children:[e.jsx(_e,{size:14}),a("nodes.addDockerNode","Add 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:a("nodes.total","Total")}),e.jsx("strong",{children:_.total})]}),e.jsxs("div",{className:"nodes-view-stat nodes-view-stat--online","data-testid":"nodes-stat-online",children:[e.jsxs("span",{children:[e.jsx(As,{size:14})," ",a("nodes.online","Online")]}),e.jsx("strong",{children:_.online})]}),e.jsxs("div",{className:"nodes-view-stat nodes-view-stat--offline","data-testid":"nodes-stat-offline",children:[e.jsxs("span",{children:[e.jsx(Es,{size:14})," ",a("nodes.offline","Offline")]}),e.jsx("strong",{children:_.offline})]}),e.jsxs("div",{className:"nodes-view-stat","data-testid":"nodes-stat-remote",children:[e.jsxs("span",{children:[e.jsx(Ps,{size:14})," ",a("nodes.remote","Remote")]}),e.jsx("strong",{children:_.remote})]}),e.jsxs("div",{className:"nodes-view-stat nodes-view-stat--synced","data-testid":"nodes-stat-synced",children:[e.jsxs("span",{children:[e.jsx(Ce,{size:14})," ",a("nodes.synced","Synced")]}),e.jsx("strong",{children:_.synced})]}),e.jsxs("div",{className:"nodes-view-stat","data-testid":"nodes-stat-docker",children:[e.jsxs("span",{children:[e.jsx(_e,{size:14})," ",a("nodes.docker","Docker")]}),e.jsx("strong",{children:_.docker})]})]}),(m||y)&&e.jsx("div",{className:"nodes-view-error",children:m??y}),!l&&b.length>0&&e.jsxs("section",{className:"nodes-view-topology","aria-label":a("nodes.meshTopologyAriaLabel","Mesh Topology"),children:[e.jsx("h3",{className:"nodes-view-section-title",children:a("nodes.meshTopology","Mesh Topology")}),e.jsx(Ws,{nodes:b})]}),r?e.jsx("div",{className:"nodes-view-grid",children:Array.from({length:4}).map((A,V)=>e.jsx("div",{className:"node-card node-card--loading","aria-hidden":!0},V))}):i.length===0?e.jsxs("div",{className:"nodes-view-empty",children:[e.jsx("p",{children:a("nodes.noRegistered","No nodes are registered yet.")}),e.jsxs("button",{className:"btn btn-primary",onClick:()=>Z(!0),children:[e.jsx(ge,{size:14}),a("nodes.addFirstNode","Add First Node")]})]}):e.jsx("div",{className:"nodes-view-grid",children:i.map(A=>{const V=A.type==="remote"&&n[A.id]?be(n[A.id]):void 0;return e.jsx(qs,{node:A,projects:P,onHealthCheck:W=>{re(W)},onEdit:W=>L(W),onRemove:W=>{te(W)},isLoading:r,syncStatus:V,authSyncState:A.type==="remote"?k(A.id):void 0,authSyncProviders:A.type==="remote"?p(A.id):void 0,managedDockerNode:U.get(A.id)},A.id)})}),e.jsx(Qs,{isOpen:J,onClose:()=>Z(!1),onSubmit:D,onDiscoverRemoteProjects:f,addToast:t,projects:P}),e.jsx(nt,{isOpen:ae,onClose:()=>G(!1),onSubmit:F,addToast:t}),e.jsx(ht,{isOpen:T!==null,onClose:()=>L(null),node:T,projects:P,onUpdate:ce,onHealthCheck:re,addToast:t,syncStatus:T?.type==="remote"&&T&&n[T.id]?be(n[T.id]):void 0,onPushSettings:M,onPullSettings:I,onSyncAuth:O,managedDockerNode:T?U.get(T.id):void 0,onFetchContainerStatus:X,onFetchLogs:se,onUpdateDockerConfig:C,onFetchDockerConfigDiff:S})]})}export{Ct as NodesView};
@@ -1,2 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/vendor-xterm-tcedd2Jt.js","assets/vendor-react-D37HfzIf.js","assets/vendor-xterm-LZoznX6r.css","assets/addon-fit-B4jkcKk4.js","assets/addon-unicode11-Cdne2Sj4.js","assets/addon-webgl-CeCSULF1.js"])))=>i.map(i=>d[i]);
2
- import{bF as oe,cs as le,by as re,ax as ce,af as de,cG as ue,a0 as D,cR as me}from"./index-CgfrecpF.js";import{r as i,j as e}from"./vendor-react-D37HfzIf.js";import"./vendor-xterm-tcedd2Jt.js";import{u as pe}from"./vendor-i18n-CV0mwX_-.js";import"./vendor-reactflow-CRZcPCXF.js";import"./vendor-codemirror-jBKmHyH0.js";const be=32*1024,fe=100,Y="(max-width: 768px), (max-height: 480px)",ye="\x1B",he=" ",we="",_e="\x1B[A",ke="\x1B[B",Se="\x1B[C",xe="\x1B[D";function H(r){if(r.length!==1)return null;const n=r.toUpperCase().charCodeAt(0);return n>=64&&n<=95?String.fromCharCode(n&31):null}function ve(){const[r,l]=i.useState(()=>typeof window>"u"||typeof window.matchMedia!="function"?!1:window.matchMedia(Y).matches);return i.useEffect(()=>{if(typeof window>"u"||typeof window.matchMedia!="function")return;const n=window.matchMedia(Y),a=()=>l(n.matches);return a(),typeof n.addEventListener=="function"?(n.addEventListener("change",a),()=>n.removeEventListener("change",a)):(n.addListener(a),()=>n.removeListener(a))},[]),r}function Ce(r,l){if(typeof window>"u")return"";const a=`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/api/cli-sessions/ws?sessionId=${encodeURIComponent(r)}&ticket=${encodeURIComponent(l)}`;return me(a)}function Te(r){if(typeof window<"u"&&typeof window.atob=="function"){const l=window.atob(r),n=new Uint8Array(l.length);for(let a=0;a<l.length;a++)n[a]=l.charCodeAt(a);return new TextDecoder("utf-8").decode(n)}return Buffer.from(r,"base64").toString("utf8")}function Ae({sessionId:r,readOnly:l=!1,posture:n,mode:a="live",projectId:M,onConfirmAdvance:_,showConfirmAdvance:A=!1,onOpenAdapterSettings:L}){const{t:s}=pe("app"),v=i.useRef(null),P=i.useRef(null),I=i.useRef(null),w=i.useRef(null),[W,z]=i.useState(!1),[G,O]=i.useState(!1),[K,U]=i.useState(!1),k=ve(),{keyboardOpen:C,keyboardOverlap:Z}=oe({enabled:k}),q=i.useRef(null),[y,$]=i.useState(""),[S,T]=i.useState(!1),b=i.useCallback(t=>{if(!t)return;const c=w.current;c?.readyState===WebSocket.OPEN&&c.send(JSON.stringify({type:"input",data:t}))},[]),x=i.useCallback(t=>{if(S){const c=H(t);if(T(!1),c){b(c);return}}b(t)},[S,b]),o=i.useCallback(t=>{t.preventDefault()},[]),Q=i.useCallback(t=>{t?.preventDefault?.(),y&&b(y),b("\r"),$("")},[y,b]),X=i.useCallback(t=>{if(S&&t.length>y.length){const c=t.slice(y.length,y.length+1),h=H(c);if(T(!1),h){b(h);return}}$(t)},[S,y,b]);i.useEffect(()=>{A&&O(!1)},[A,r]),i.useEffect(()=>{if(!r||typeof window>"u")return;let t=!1,c=null,h=null,N=0;const V=(d,f)=>{const E=w.current;E?.readyState===WebSocket.OPEN&&E.send(JSON.stringify({type:"resize",cols:d,rows:f}))},ne=d=>{if(N+=d,N<be)return;const f=w.current;f?.readyState===WebSocket.OPEN&&f.send(JSON.stringify({type:"ack",bytes:N})),N=0};return(async()=>{let d;try{d=await ue(`/cli-sessions/${encodeURIComponent(r)}/attach-ticket`,{method:"POST",body:JSON.stringify(M?{projectId:M}:{})})}catch{return}if(t)return;const[{Terminal:f},{FitAddon:E},{Unicode11Addon:ie}]=await Promise.all([D(()=>import("./vendor-xterm-tcedd2Jt.js").then(p=>p.x),__vite__mapDeps([0,1,2])),D(()=>import("./addon-fit-B4jkcKk4.js").then(p=>p.a),__vite__mapDeps([3,1])),D(()=>import("./addon-unicode11-Cdne2Sj4.js").then(p=>p.a),__vite__mapDeps([4,1]))]);if(t||!v.current)return;const m=new f({convertEol:!1,cursorBlink:!l&&a==="live",disableStdin:l,scrollback:1e4,fontFamily:'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace',fontSize:13}),R=new E;m.loadAddon(R);const se=new ie;m.loadAddon(se),m.unicode.activeVersion="11",m.open(v.current),P.current=m,I.current=R;try{const{WebglAddon:p}=await D(async()=>{const{WebglAddon:u}=await import("./addon-webgl-CeCSULF1.js").then(j=>j.a);return{WebglAddon:u}},__vite__mapDeps([5,1]));if(!t){const u=new p;u.onContextLoss(()=>{try{u.dispose()}catch{}}),m.loadAddon(u)}}catch{}try{R.fit()}catch{}l||m.onData(p=>{const u=w.current;u?.readyState===WebSocket.OPEN&&u.send(JSON.stringify({type:"input",data:p}))}),c=new ResizeObserver(()=>{h&&clearTimeout(h),h=setTimeout(()=>{try{R.fit(),V(m.cols,m.rows)}catch{}},fe)}),c.observe(v.current);const B=new WebSocket(Ce(r,d.ticket));w.current=B,B.onopen=()=>{V(m.cols,m.rows)},B.onmessage=p=>{let u;try{u=JSON.parse(typeof p.data=="string"?p.data:"")}catch{return}switch(u.type){case"scrollback":case"data":{if(typeof u.data!="string")return;const j=Te(u.data),ae=j.length;m.write(j,()=>ne(ae));break}}}})(),()=>{t=!0,h&&clearTimeout(h),c&&c.disconnect();const d=w.current;if(d){d.onopen=null,d.onmessage=null,d.onclose=null,d.onerror=null;try{d.close()}catch{}w.current=null}const f=P.current;if(f){try{f.dispose()}catch{}P.current=null}I.current=null}},[r,l,a,M]);const F=i.useMemo(()=>a==="idle"?s("cliTerminal.replayIdle","Session idle"):a==="ended"?s("cliTerminal.replayEnded","Session ended"):null,[a,s]),ee=i.useCallback(async()=>{if(_){U(!0);try{await _("advance"),O(!0)}finally{U(!1)}}},[_]),te=i.useCallback(async()=>{_&&await _("not-yet"),O(!0)},[_]),g=!!n?.elevated,J=n?.elevatedFlags?.join(", ");return e.jsxs("div",{className:`cli-session-terminal${k?" cli-session-terminal--mobile":""}${k&&C?" cli-session-terminal--keyboard-open":""}`,"data-mode":a,"data-read-only":l,"data-mobile":k,"data-keyboard-open":k&&C,children:[e.jsxs("header",{className:"cli-session-terminal__header",children:[n&&e.jsxs("div",{className:"cli-session-terminal__posture-wrap",children:[e.jsxs("button",{type:"button",className:`cli-posture-chip${g?" cli-posture-chip--elevated":""}`,"data-elevated":g,"aria-expanded":W,onClick:()=>z(t=>!t),children:[g?e.jsx(le,{size:13,"aria-hidden":"true"}):e.jsx(re,{size:13,"aria-hidden":"true"}),e.jsx("span",{className:"cli-posture-chip__name",children:n.adapterName}),n.mode&&e.jsx("span",{className:"cli-posture-chip__mode",children:n.mode}),g&&J&&e.jsx("span",{className:"cli-posture-chip__flag",children:J})]}),W&&e.jsxs("div",{className:"cli-posture-tooltip",role:"tooltip",children:[e.jsx("p",{className:"cli-posture-tooltip__title",children:s("cliTerminal.postureResolved","Resolved posture")}),e.jsxs("ul",{className:"cli-posture-tooltip__list",children:[(n.resolved??[]).map((t,c)=>e.jsx("li",{children:t},c)),(n.resolved??[]).length===0&&e.jsx("li",{children:n.mode??s("cliTerminal.postureBaseline","Baseline")})]}),L&&e.jsxs("button",{type:"button",className:"cli-posture-tooltip__settings",onClick:()=>{z(!1),L()},children:[e.jsx(ce,{size:12,"aria-hidden":"true"}),s("cliTerminal.adapterSettings","Adapter settings")]})]})]}),l&&e.jsxs("span",{className:"cli-session-terminal__readonly-badge",children:[e.jsx(de,{size:12,"aria-hidden":"true"}),s("cliTerminal.readOnly","Read-only")]}),F&&e.jsx("span",{className:"cli-session-terminal__replay-badge","data-replay-mode":a,children:F})]}),e.jsx("div",{className:"cli-session-terminal__viewport",ref:v,"data-testid":"cli-terminal-viewport"}),A&&!G&&e.jsxs("div",{className:"cli-session-terminal__advance-strip",role:"region",children:[e.jsx("span",{className:"cli-session-terminal__advance-copy",children:s("cliTerminal.advancePrompt","This session looks idle — advance to review?")}),e.jsxs("div",{className:"cli-session-terminal__advance-actions",children:[e.jsx("button",{type:"button",className:"cli-session-terminal__advance-btn",disabled:K,onClick:ee,children:s("cliTerminal.advance","Advance")}),e.jsx("button",{type:"button",className:"cli-session-terminal__advance-btn cli-session-terminal__advance-btn--secondary",disabled:K,onClick:te,children:s("cliTerminal.notYet","Not yet")})]})]}),k&&!l&&e.jsxs("div",{className:`cli-session-terminal__mobile-bar${C?" cli-session-terminal__mobile-bar--keyboard-open":""}`,"data-testid":"cli-terminal-mobile-bar",style:C?{bottom:`${Z}px`}:void 0,children:[e.jsxs("div",{className:"cli-session-terminal__key-row","data-testid":"cli-terminal-key-bar",children:[e.jsx("button",{type:"button",className:`cli-terminal-key cli-terminal-key--ctrl${S?" cli-terminal-key--active":""}`,"data-testid":"cli-key-ctrl","aria-label":s("cliTerminal.mobileKeyCtrl","Sticky Ctrl modifier"),"aria-pressed":S,onPointerDown:o,onMouseDown:o,onClick:()=>T(t=>!t),children:"Ctrl"}),e.jsx("button",{type:"button",className:"cli-terminal-key","data-testid":"cli-key-esc","aria-label":s("cliTerminal.mobileKeyEsc","Send Escape"),onPointerDown:o,onMouseDown:o,onClick:()=>x(ye),children:"Esc"}),e.jsx("button",{type:"button",className:"cli-terminal-key","data-testid":"cli-key-tab","aria-label":s("cliTerminal.mobileKeyTab","Send Tab"),onPointerDown:o,onMouseDown:o,onClick:()=>x(he),children:"Tab"}),e.jsx("button",{type:"button",className:"cli-terminal-key cli-terminal-key--ctrlc","data-testid":"cli-key-ctrl-c","aria-label":s("cliTerminal.mobileKeyCtrlC","Send Ctrl-C"),onPointerDown:o,onMouseDown:o,onClick:()=>{T(!1),b(we)},children:"^C"}),e.jsx("button",{type:"button",className:"cli-terminal-key","data-testid":"cli-key-arrow-up","aria-label":s("cliTerminal.mobileKeyArrowUp","Cursor up"),onPointerDown:o,onMouseDown:o,onClick:()=>x(_e),children:"↑"}),e.jsx("button",{type:"button",className:"cli-terminal-key","data-testid":"cli-key-arrow-down","aria-label":s("cliTerminal.mobileKeyArrowDown","Cursor down"),onPointerDown:o,onMouseDown:o,onClick:()=>x(ke),children:"↓"}),e.jsx("button",{type:"button",className:"cli-terminal-key","data-testid":"cli-key-arrow-left","aria-label":s("cliTerminal.mobileKeyArrowLeft","Cursor left"),onPointerDown:o,onMouseDown:o,onClick:()=>x(xe),children:"←"}),e.jsx("button",{type:"button",className:"cli-terminal-key","data-testid":"cli-key-arrow-right","aria-label":s("cliTerminal.mobileKeyArrowRight","Cursor right"),onPointerDown:o,onMouseDown:o,onClick:()=>x(Se),children:"→"})]}),e.jsxs("form",{className:"cli-session-terminal__input-row",onSubmit:Q,children:[e.jsx("input",{ref:q,type:"text",className:"cli-session-terminal__mobile-input","data-testid":"cli-terminal-mobile-input",value:y,placeholder:s("cliTerminal.mobileInputPlaceholder","Type to send to the session…"),autoCapitalize:"off",autoCorrect:"off",autoComplete:"off",spellCheck:!1,onChange:t=>X(t.target.value)}),e.jsx("button",{type:"submit",className:"cli-session-terminal__mobile-send","data-testid":"cli-terminal-mobile-send","aria-label":s("cliTerminal.mobileSend","Send"),onPointerDown:o,onMouseDown:o,onClick:()=>Q(),children:s("cliTerminal.mobileSend","Send")})]})]})]})}export{Ae as SessionTerminal};